mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-29 19:03:25 -07:00
Swap to using logicmixin instead of prog_items (thanks Vi)
This commit is contained in:
@@ -11,6 +11,7 @@ from .er_scripts import create_er_regions
|
||||
from .er_data import portal_mapping
|
||||
from .options import (TunicOptions, EntranceRando, tunic_option_groups, tunic_option_presets, TunicPlandoConnections,
|
||||
LaurelsLocation, LogicRules, LaurelsZips, IceGrappling, LadderStorage)
|
||||
from .combat_logic import area_data, CombatState
|
||||
from worlds.AutoWorld import WebWorld, World
|
||||
from Options import PlandoConnection
|
||||
from decimal import Decimal, ROUND_HALF_UP
|
||||
@@ -127,6 +128,15 @@ class TunicWorld(World):
|
||||
def stage_generate_early(cls, multiworld: MultiWorld) -> None:
|
||||
tunic_worlds: Tuple[TunicWorld] = multiworld.get_game_worlds("TUNIC")
|
||||
for tunic in tunic_worlds:
|
||||
# setting up state combat logic stuff, see has_combat_reqs for its use
|
||||
# and this is magic so pycharm doesn't like it, unfortunately
|
||||
if tunic.options.combat_logic:
|
||||
multiworld.state.tunic_need_to_reset_combat_from_collect[tunic.player] = False
|
||||
multiworld.state.tunic_need_to_reset_combat_from_remove[tunic.player] = False
|
||||
multiworld.state.tunic_area_combat_state[tunic.player] = {}
|
||||
for area_name in area_data.keys():
|
||||
multiworld.state.tunic_area_combat_state[tunic.player][area_name] = CombatState.unchecked
|
||||
|
||||
# if it's one of the options, then it isn't a custom seed group
|
||||
if tunic.options.entrance_rando.value in EntranceRando.options.values():
|
||||
continue
|
||||
@@ -352,13 +362,13 @@ class TunicWorld(World):
|
||||
def collect(self, state: CollectionState, item: Item) -> bool:
|
||||
change = super().collect(state, item)
|
||||
if change and self.options.combat_logic and item.name in combat_items:
|
||||
state.prog_items[self.player]["need_to_reset_combat_state_from_collect"] = 1
|
||||
state.tunic_need_to_reset_combat_from_collect[self.player] = True
|
||||
return change
|
||||
|
||||
def remove(self, state: CollectionState, item: Item) -> bool:
|
||||
change = super().remove(state, item)
|
||||
if change and self.options.combat_logic and item.name in combat_items:
|
||||
state.prog_items[self.player]["need_to_reset_combat_state_from_remove"] = 1
|
||||
state.tunic_need_to_reset_combat_from_remove[self.player] = True
|
||||
return change
|
||||
|
||||
def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]) -> None:
|
||||
|
||||
@@ -2,6 +2,7 @@ from typing import Dict, List, NamedTuple, Tuple, Optional
|
||||
from enum import IntEnum
|
||||
from BaseClasses import CollectionState
|
||||
from .rules import has_sword, has_melee
|
||||
from worlds.AutoWorld import LogicMixin
|
||||
|
||||
|
||||
# the vanilla stats you are expected to have to get through an area, based on where they are in vanilla
|
||||
@@ -59,34 +60,23 @@ class CombatState(IntEnum):
|
||||
|
||||
def has_combat_reqs(area_name: str, state: CollectionState, player: int) -> bool:
|
||||
# we're caching whether you've met the combat reqs before if the state didn't change first
|
||||
player_state = state.prog_items[player]
|
||||
# if the combat state is stale, mark each area's combat state as stale
|
||||
if player_state["need_to_reset_combat_state_from_collect"]:
|
||||
player_state["need_to_reset_combat_state_from_collect"] = 0
|
||||
for name in boss_areas:
|
||||
if player_state["combat_reqs_met_for_" + name] == CombatState.failed:
|
||||
player_state["combat_reqs_met_for_" + name] = CombatState.unchecked
|
||||
for name in non_boss_areas:
|
||||
if player_state["combat_reqs_met_for_" + name] == CombatState.failed:
|
||||
player_state["combat_reqs_met_for_" + name] = CombatState.unchecked
|
||||
if player_state["combat_reqs_met_for_Gauntlet"] == CombatState.failed:
|
||||
player_state["combat_reqs_met_for_Gauntlet"] = CombatState.unchecked
|
||||
if state.tunic_need_to_reset_combat_from_collect[player]:
|
||||
state.tunic_need_to_reset_combat_from_collect[player] = 0
|
||||
for name in area_data.keys():
|
||||
if state.tunic_area_combat_state[player][name] == CombatState.failed:
|
||||
state.tunic_area_combat_state[player][name] = CombatState.unchecked
|
||||
|
||||
if player_state["need_to_reset_combat_state_from_remove"]:
|
||||
player_state["need_to_reset_combat_state_from_remove"] = 0
|
||||
for name in boss_areas:
|
||||
if player_state["combat_reqs_met_for_" + name] == CombatState.succeeded:
|
||||
player_state["combat_reqs_met_for_" + name] = CombatState.unchecked
|
||||
for name in non_boss_areas:
|
||||
if player_state["combat_reqs_met_for_" + name] == CombatState.succeeded:
|
||||
player_state["combat_reqs_met_for_" + name] = CombatState.unchecked
|
||||
if player_state["combat_reqs_met_for_Gauntlet"] == CombatState.succeeded:
|
||||
player_state["combat_reqs_met_for_Gauntlet"] = CombatState.unchecked
|
||||
if state.tunic_need_to_reset_combat_from_remove[player]:
|
||||
state.tunic_need_to_reset_combat_from_remove[player] = 0
|
||||
for name in area_data.keys():
|
||||
if state.tunic_area_combat_state[player][name] == CombatState.succeeded:
|
||||
state.tunic_area_combat_state[player][name] = CombatState.unchecked
|
||||
|
||||
if state.tunic_area_combat_state[player][area_name] > CombatState.unchecked:
|
||||
return state.tunic_area_combat_state[player][area_name] == CombatState.succeeded
|
||||
|
||||
met_combat_reqs = check_combat_reqs(area_name, state, player)
|
||||
if player_state["combat_reqs_met_for_" + area_name] > CombatState.unchecked:
|
||||
return met_combat_reqs
|
||||
|
||||
# loop through the lists and set the easier/harder area states accordingly
|
||||
if area_name in boss_areas:
|
||||
area_list = boss_areas
|
||||
@@ -95,30 +85,25 @@ def has_combat_reqs(area_name: str, state: CollectionState, player: int) -> bool
|
||||
else:
|
||||
area_list = [area_name]
|
||||
|
||||
if area_name in area_list:
|
||||
if met_combat_reqs:
|
||||
# set the state as true for each area until you get to the area we're looking at
|
||||
for name in area_list:
|
||||
player_state["combat_reqs_met_for_" + name] = CombatState.succeeded
|
||||
if name == area_name:
|
||||
break
|
||||
else:
|
||||
# set the state as false for the area we're looking at and each area after that
|
||||
reached_name = False
|
||||
for name in area_list:
|
||||
if name == area_name:
|
||||
reached_name = True
|
||||
if reached_name:
|
||||
player_state["combat_reqs_met_for_" + name] = CombatState.failed
|
||||
if met_combat_reqs:
|
||||
# set the state as true for each area until you get to the area we're looking at
|
||||
for name in area_list:
|
||||
state.tunic_area_combat_state[player][name] = CombatState.succeeded
|
||||
if name == area_name:
|
||||
break
|
||||
else:
|
||||
# set the state as false for the area we're looking at and each area after that
|
||||
reached_name = False
|
||||
for name in area_list:
|
||||
if name == area_name:
|
||||
reached_name = True
|
||||
if reached_name:
|
||||
state.tunic_area_combat_state[player][name] = CombatState.failed
|
||||
|
||||
return check_combat_reqs(area_name, state, player)
|
||||
return met_combat_reqs
|
||||
|
||||
|
||||
def check_combat_reqs(area_name: str, state: CollectionState, player: int, alt_data: Optional[AreaStats] = None) -> bool:
|
||||
# if our cache says we've already calced this, we don't need to go through these calculations again
|
||||
if state.prog_items[player]["combat_reqs_met_for_" + area_name] > CombatState.unchecked:
|
||||
return state.prog_items[player]["combat_reqs_met_for_" + area_name] > CombatState.failed
|
||||
|
||||
data = alt_data or area_data[area_name]
|
||||
extra_att_needed = 0
|
||||
extra_def_needed = 0
|
||||
@@ -413,3 +398,13 @@ def get_money_count(state: CollectionState, player: int) -> int:
|
||||
money += money_per_break
|
||||
money_per_break = min(512, money_per_break * 2)
|
||||
return money
|
||||
|
||||
|
||||
class TunicState(LogicMixin):
|
||||
# the per-player need to reset the combat state when collecting a combat item
|
||||
tunic_need_to_reset_combat_from_collect: Dict[int, bool] = {}
|
||||
# the per-player need to reset the combat state when removing a combat item
|
||||
tunic_need_to_reset_combat_from_remove: Dict[int, bool] = {}
|
||||
# the per-player, per-area state of combat checking -- unchecked, failed, or succeeded
|
||||
tunic_area_combat_state: Dict[int, Dict[str, int]] = {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user