SC2: Various bugfixes (#1267)

* SC2: Fixed nondeterminism resulting from early unit placement

* SC2: Renamed "world" arguments to "multiworld"

* SC2: Fixed All-In Ground including anti-air in defense score, fixed error in beats_protoss_deathball

* SC2: Fixed No Logic using logic on Beat events

* SC2: Fixed /unfinished command failing when All-In available
This commit is contained in:
Magnemania
2022-12-11 14:46:24 -05:00
committed by GitHub
parent e3f169b4c3
commit e71ea94fe5
9 changed files with 290 additions and 282 deletions

View File

@@ -48,8 +48,8 @@ class SC2WoLWorld(World):
victory_item: str
required_client_version = 0, 3, 6
def __init__(self, world: MultiWorld, player: int):
super(SC2WoLWorld, self).__init__(world, player)
def __init__(self, multiworld: MultiWorld, player: int):
super(SC2WoLWorld, self).__init__(multiworld, player)
self.location_cache = []
self.locked_locations = []
@@ -63,7 +63,7 @@ class SC2WoLWorld(World):
)
def generate_basic(self):
excluded_items = get_excluded_items(self, self.multiworld, self.player)
excluded_items = get_excluded_items(self.multiworld, self.player)
starter_items = assign_starter_items(self.multiworld, self.player, excluded_items, self.locked_locations)
@@ -74,7 +74,7 @@ class SC2WoLWorld(World):
self.multiworld.itempool += pool
def set_rules(self):
setup_events(self.multiworld, self.player, self.locked_locations, self.location_cache)
setup_events(self.player, self.locked_locations, self.location_cache)
self.multiworld.completion_condition[self.player] = lambda state: state.has(self.victory_item, self.player)
def get_filler_item_name(self) -> str:
@@ -95,7 +95,7 @@ class SC2WoLWorld(World):
return slot_data
def setup_events(world: MultiWorld, player: int, locked_locations: typing.List[str], location_cache: typing.List[Location]):
def setup_events(player: int, locked_locations: typing.List[str], location_cache: typing.List[Location]):
for location in location_cache:
if location.address is None:
item = Item(location.name, ItemClassification.progression, None, player)
@@ -105,39 +105,39 @@ def setup_events(world: MultiWorld, player: int, locked_locations: typing.List[s
location.place_locked_item(item)
def get_excluded_items(self: SC2WoLWorld, world: MultiWorld, player: int) -> Set[str]:
def get_excluded_items(multiworld: MultiWorld, player: int) -> Set[str]:
excluded_items: Set[str] = set()
if get_option_value(world, player, "upgrade_bonus") == 1:
if get_option_value(multiworld, player, "upgrade_bonus") == 1:
excluded_items.add("Ultra-Capacitors")
else:
excluded_items.add("Vanadium Plating")
if get_option_value(world, player, "bunker_upgrade") == 1:
if get_option_value(multiworld, player, "bunker_upgrade") == 1:
excluded_items.add("Shrike Turret")
else:
excluded_items.add("Fortified Bunker")
for item in world.precollected_items[player]:
for item in multiworld.precollected_items[player]:
excluded_items.add(item.name)
excluded_items_option = getattr(world, 'excluded_items', [])
excluded_items_option = getattr(multiworld, 'excluded_items', [])
excluded_items.update(excluded_items_option[player].value)
return excluded_items
def assign_starter_items(world: MultiWorld, player: int, excluded_items: Set[str], locked_locations: List[str]) -> List[Item]:
non_local_items = world.non_local_items[player].value
if get_option_value(world, player, "early_unit"):
local_basic_unit = tuple(item for item in get_basic_units(world, player) if item not in non_local_items and item not in excluded_items)
def assign_starter_items(multiworld: MultiWorld, player: int, excluded_items: Set[str], locked_locations: List[str]) -> List[Item]:
non_local_items = multiworld.non_local_items[player].value
if get_option_value(multiworld, player, "early_unit"):
local_basic_unit = sorted(item for item in get_basic_units(multiworld, player) if item not in non_local_items and item not in excluded_items)
if not local_basic_unit:
raise Exception("At least one basic unit must be local")
# The first world should also be the starting world
first_mission = list(world.worlds[player].mission_req_table)[0]
starting_mission_locations = get_starting_mission_locations(world, player)
first_mission = list(multiworld.worlds[player].mission_req_table)[0]
starting_mission_locations = get_starting_mission_locations(multiworld, player)
if first_mission in starting_mission_locations:
first_location = starting_mission_locations[first_mission]
elif first_mission == "In Utter Darkness":
@@ -145,28 +145,28 @@ def assign_starter_items(world: MultiWorld, player: int, excluded_items: Set[str
else:
first_location = first_mission + ": Victory"
return [assign_starter_item(world, player, excluded_items, locked_locations, first_location, local_basic_unit)]
return [assign_starter_item(multiworld, player, excluded_items, locked_locations, first_location, local_basic_unit)]
else:
return []
def assign_starter_item(world: MultiWorld, player: int, excluded_items: Set[str], locked_locations: List[str],
def assign_starter_item(multiworld: MultiWorld, player: int, excluded_items: Set[str], locked_locations: List[str],
location: str, item_list: Tuple[str, ...]) -> Item:
item_name = world.random.choice(item_list)
item_name = multiworld.random.choice(item_list)
excluded_items.add(item_name)
item = create_item_with_correct_settings(world, player, item_name)
item = create_item_with_correct_settings(player, item_name)
world.get_location(location, player).place_locked_item(item)
multiworld.get_location(location, player).place_locked_item(item)
locked_locations.append(location)
return item
def get_item_pool(world: MultiWorld, player: int, mission_req_table: Dict[str, MissionInfo],
def get_item_pool(multiworld: MultiWorld, player: int, mission_req_table: Dict[str, MissionInfo],
starter_items: List[str], excluded_items: Set[str], location_cache: List[Location]) -> List[Item]:
pool: List[Item] = []
@@ -174,18 +174,18 @@ def get_item_pool(world: MultiWorld, player: int, mission_req_table: Dict[str, M
locked_items = []
# YAML items
yaml_locked_items = get_option_set_value(world, player, 'locked_items')
yaml_locked_items = get_option_set_value(multiworld, player, 'locked_items')
for name, data in item_table.items():
if name not in excluded_items:
for _ in range(data.quantity):
item = create_item_with_correct_settings(world, player, name)
item = create_item_with_correct_settings(player, name)
if name in yaml_locked_items:
locked_items.append(item)
else:
pool.append(item)
existing_items = starter_items + [item for item in world.precollected_items[player]]
existing_items = starter_items + [item for item in multiworld.precollected_items[player]]
existing_names = [item.name for item in existing_items]
# Removing upgrades for excluded items
for item_name in excluded_items:
@@ -195,18 +195,18 @@ def get_item_pool(world: MultiWorld, player: int, mission_req_table: Dict[str, M
for invalid_upgrade in invalid_upgrades:
pool.remove(invalid_upgrade)
filtered_pool = filter_items(world, player, mission_req_table, location_cache, pool, existing_items, locked_items)
filtered_pool = filter_items(multiworld, player, mission_req_table, location_cache, pool, existing_items, locked_items)
return filtered_pool
def fill_item_pool_with_dummy_items(self: SC2WoLWorld, world: MultiWorld, player: int, locked_locations: List[str],
def fill_item_pool_with_dummy_items(self: SC2WoLWorld, multiworld: MultiWorld, player: int, locked_locations: List[str],
location_cache: List[Location], pool: List[Item]):
for _ in range(len(location_cache) - len(locked_locations) - len(pool)):
item = create_item_with_correct_settings(world, player, self.get_filler_item_name())
item = create_item_with_correct_settings(player, self.get_filler_item_name())
pool.append(item)
def create_item_with_correct_settings(world: MultiWorld, player: int, name: str) -> Item:
def create_item_with_correct_settings(player: int, name: str) -> Item:
data = item_table[name]
item = Item(name, data.classification, data.code, player)