SC2: Quality of Life Changes/Fixes to Prepare For Future Feature (#550)
This commit is contained in:
parent
cb9db5dff1
commit
bb15485965
|
@ -57,13 +57,13 @@ class StarcraftClientProcessor(ClientCommandProcessor):
|
|||
def _cmd_available(self) -> bool:
|
||||
"""Get what missions are currently available to play"""
|
||||
|
||||
request_available_missions(self.ctx.checked_locations, mission_req_table)
|
||||
request_available_missions(self.ctx.checked_locations, mission_req_table, self.ctx.ui)
|
||||
return True
|
||||
|
||||
def _cmd_unfinished(self) -> bool:
|
||||
"""Get what missions are currently available to play and have not had all locations checked"""
|
||||
|
||||
request_unfinished_missions(self.ctx.checked_locations, mission_req_table)
|
||||
request_unfinished_missions(self.ctx.checked_locations, mission_req_table, self.ctx.ui)
|
||||
return True
|
||||
|
||||
|
||||
|
@ -378,22 +378,23 @@ class MissionInfo(typing.NamedTuple):
|
|||
extra_locations: int
|
||||
required_world: list[int]
|
||||
number: int = 0 # number of worlds need beaten
|
||||
completion_critical: bool = False # missions needed to beat game
|
||||
or_requirements: bool = False # true if the requirements should be or-ed instead of and-ed
|
||||
|
||||
|
||||
mission_req_table = {
|
||||
"Liberation Day": MissionInfo(1, 7, []),
|
||||
"The Outlaws": MissionInfo(2, 2, [1]),
|
||||
"Zero Hour": MissionInfo(3, 4, [2]),
|
||||
"Liberation Day": MissionInfo(1, 7, [], completion_critical=True),
|
||||
"The Outlaws": MissionInfo(2, 2, [1], completion_critical=True),
|
||||
"Zero Hour": MissionInfo(3, 4, [2], completion_critical=True),
|
||||
"Evacuation": MissionInfo(4, 4, [3]),
|
||||
"Outbreak": MissionInfo(5, 3, [4]),
|
||||
"Safe Haven": MissionInfo(6, 1, [5], number=7),
|
||||
"Haven's Fall": MissionInfo(7, 1, [5], number=7),
|
||||
"Smash and Grab": MissionInfo(8, 5, [3]),
|
||||
"The Dig": MissionInfo(9, 4, [8], number=8),
|
||||
"The Moebius Factor": MissionInfo(10, 9, [9], number=11),
|
||||
"Supernova": MissionInfo(11, 5, [10], number=14),
|
||||
"Maw of the Void": MissionInfo(12, 6, [11]),
|
||||
"Smash and Grab": MissionInfo(8, 5, [3], completion_critical=True),
|
||||
"The Dig": MissionInfo(9, 4, [8], number=8, completion_critical=True),
|
||||
"The Moebius Factor": MissionInfo(10, 9, [9], number=11, completion_critical=True),
|
||||
"Supernova": MissionInfo(11, 5, [10], number=14, completion_critical=True),
|
||||
"Maw of the Void": MissionInfo(12, 6, [11], completion_critical=True),
|
||||
"Devil's Playground": MissionInfo(13, 3, [3], number=4),
|
||||
"Welcome to the Jungle": MissionInfo(14, 4, [13]),
|
||||
"Breakout": MissionInfo(15, 3, [14], number=8),
|
||||
|
@ -407,10 +408,10 @@ mission_req_table = {
|
|||
"A Sinister Turn": MissionInfo(23, 4, [22]),
|
||||
"Echoes of the Future": MissionInfo(24, 3, [23]),
|
||||
"In Utter Darkness": MissionInfo(25, 3, [24]),
|
||||
"Gates of Hell": MissionInfo(26, 2, [12]),
|
||||
"Belly of the Beast": MissionInfo(27, 4, [26]),
|
||||
"Shatter the Sky": MissionInfo(28, 5, [26]),
|
||||
"All-In": MissionInfo(29, -1, [27, 28], or_requirements=True)
|
||||
"Gates of Hell": MissionInfo(26, 2, [12], completion_critical=True),
|
||||
"Belly of the Beast": MissionInfo(27, 4, [26], completion_critical=True),
|
||||
"Shatter the Sky": MissionInfo(28, 5, [26], completion_critical=True),
|
||||
"All-In": MissionInfo(29, -1, [27, 28], completion_critical=True, or_requirements=True)
|
||||
}
|
||||
|
||||
lookup_id_to_mission: typing.Dict[int, str] = {
|
||||
|
@ -431,16 +432,21 @@ def calc_objectives_completed(mission, missions_info, locations_done):
|
|||
return -1
|
||||
|
||||
|
||||
def request_unfinished_missions(locations_done, location_table):
|
||||
def request_unfinished_missions(locations_done, location_table, ui):
|
||||
message = "Unfinished Missions: "
|
||||
|
||||
unfinished_missions = calc_unfinished_missions(locations_done, location_table)
|
||||
|
||||
message += ", ".join(f"{mission}[{location_table[mission].id}] "
|
||||
|
||||
message += ", ".join(f"{mark_critical(mission,location_table, ui)}[{location_table[mission].id}] "
|
||||
f"({unfinished_missions[mission]}/{location_table[mission].extra_locations})"
|
||||
for mission in unfinished_missions)
|
||||
|
||||
sc2_logger.info(message)
|
||||
if ui:
|
||||
ui.log_panels['All'].on_message_markup(message)
|
||||
ui.log_panels['Starcraft2'].on_message_markup(message)
|
||||
else:
|
||||
sc2_logger.info(message)
|
||||
|
||||
|
||||
def calc_unfinished_missions(locations_done, locations):
|
||||
|
@ -469,13 +475,28 @@ def is_mission_available(mission_id_to_check, locations_done, locations):
|
|||
return any(mission_id_to_check == locations[mission].id for mission in unfinished_missions)
|
||||
|
||||
|
||||
def request_available_missions(locations_done, location_table):
|
||||
def mark_critical(mission, location_table, ui):
|
||||
"""Checks if the mission is required for game completion and adds '*' to the name to mark that."""
|
||||
if location_table[mission].completion_critical:
|
||||
if ui:
|
||||
return "[color=AF99EF]" + mission + "[/color]"
|
||||
else:
|
||||
return "*" + mission + "*"
|
||||
else:
|
||||
return mission
|
||||
|
||||
|
||||
def request_available_missions(locations_done, location_table, ui):
|
||||
message = "Available Missions: "
|
||||
|
||||
missions = calc_available_missions(locations_done, location_table)
|
||||
message += ", ".join(f"{mission}[{location_table[mission].id}]" for mission in missions)
|
||||
message += ", ".join(f"{mark_critical(mission,location_table, ui)}[{location_table[mission].id}]" for mission in missions)
|
||||
|
||||
sc2_logger.info(message)
|
||||
if ui:
|
||||
ui.log_panels['All'].on_message_markup(message)
|
||||
ui.log_panels['Starcraft2'].on_message_markup(message)
|
||||
else:
|
||||
sc2_logger.info(message)
|
||||
|
||||
|
||||
def calc_available_missions(locations_done, locations):
|
||||
|
|
|
@ -116,7 +116,7 @@ item_table = {
|
|||
"Automated Refinery": ItemData(604 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 4),
|
||||
"Command Center Reactor": ItemData(605 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 5),
|
||||
"Raven": ItemData(606 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 6),
|
||||
"Science Vessel": ItemData(607 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 7),
|
||||
"Science Vessel": ItemData(607 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 7, progression=True),
|
||||
"Tech Reactor": ItemData(608 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 8),
|
||||
"Orbital Strike": ItemData(609 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 9),
|
||||
"Shrike Turret": ItemData(610 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 10),
|
||||
|
|
|
@ -5,6 +5,7 @@ from BaseClasses import Location
|
|||
|
||||
SC2WOL_LOC_ID_OFFSET = 1000
|
||||
|
||||
|
||||
class SC2WoLLocation(Location):
|
||||
game: str = "Starcraft2WoL"
|
||||
|
||||
|
@ -17,6 +18,7 @@ class LocationData(NamedTuple):
|
|||
|
||||
|
||||
def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[LocationData, ...]:
|
||||
# Note: rules which are ended with or True are rules identified as needed later when restricted units is an option
|
||||
location_table: List[LocationData] = [
|
||||
LocationData("Liberation Day", "Liberation Day: Victory", SC2WOL_LOC_ID_OFFSET + 100),
|
||||
LocationData("Liberation Day", "Liberation Day: First Statue", SC2WOL_LOC_ID_OFFSET + 101),
|
||||
|
@ -26,41 +28,84 @@ def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[L
|
|||
LocationData("Liberation Day", "Liberation Day: Fifth Statue", SC2WOL_LOC_ID_OFFSET + 105),
|
||||
LocationData("Liberation Day", "Liberation Day: Sixth Statue", SC2WOL_LOC_ID_OFFSET + 106),
|
||||
LocationData("Liberation Day", "Beat Liberation Day", None),
|
||||
LocationData("The Outlaws", "The Outlaws: Victory", SC2WOL_LOC_ID_OFFSET + 200),
|
||||
LocationData("The Outlaws", "The Outlaws: Rebel Base", SC2WOL_LOC_ID_OFFSET + 201),
|
||||
LocationData("The Outlaws", "Beat The Outlaws", None),
|
||||
LocationData("Zero Hour", "Zero Hour: Victory", SC2WOL_LOC_ID_OFFSET + 300),
|
||||
LocationData("The Outlaws", "The Outlaws: Victory", SC2WOL_LOC_ID_OFFSET + 200,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("The Outlaws", "The Outlaws: Rebel Base", SC2WOL_LOC_ID_OFFSET + 201,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("The Outlaws", "Beat The Outlaws", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Zero Hour", "Zero Hour: Victory", SC2WOL_LOC_ID_OFFSET + 300,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Zero Hour", "Zero Hour: First Group Rescued", SC2WOL_LOC_ID_OFFSET + 301),
|
||||
LocationData("Zero Hour", "Zero Hour: Second Group Rescued", SC2WOL_LOC_ID_OFFSET + 302),
|
||||
LocationData("Zero Hour", "Zero Hour: Third Group Rescued", SC2WOL_LOC_ID_OFFSET + 303),
|
||||
LocationData("Zero Hour", "Beat Zero Hour", None),
|
||||
LocationData("Evacuation", "Evacuation: Victory", SC2WOL_LOC_ID_OFFSET + 400),
|
||||
LocationData("Zero Hour", "Zero Hour: Second Group Rescued", SC2WOL_LOC_ID_OFFSET + 302,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Zero Hour", "Zero Hour: Third Group Rescued", SC2WOL_LOC_ID_OFFSET + 303,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Zero Hour", "Beat Zero Hour", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Evacuation", "Evacuation: Victory", SC2WOL_LOC_ID_OFFSET + 400,
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Evacuation", "Evacuation: First Chysalis", SC2WOL_LOC_ID_OFFSET + 401),
|
||||
LocationData("Evacuation", "Evacuation: Second Chysalis", SC2WOL_LOC_ID_OFFSET + 402),
|
||||
LocationData("Evacuation", "Evacuation: Third Chysalis", SC2WOL_LOC_ID_OFFSET + 403),
|
||||
LocationData("Evacuation", "Beat Evacuation", None),
|
||||
LocationData("Outbreak", "Outbreak: Victory", SC2WOL_LOC_ID_OFFSET + 500),
|
||||
LocationData("Outbreak", "Outbreak: Left Infestor", SC2WOL_LOC_ID_OFFSET + 501),
|
||||
LocationData("Outbreak", "Outbreak: Right Infestor", SC2WOL_LOC_ID_OFFSET + 502),
|
||||
LocationData("Outbreak", "Beat Outbreak", None),
|
||||
LocationData("Safe Haven", "Safe Haven: Victory", SC2WOL_LOC_ID_OFFSET + 600),
|
||||
LocationData("Safe Haven", "Beat Safe Haven", None),
|
||||
LocationData("Haven's Fall", "Haven's Fall: Victory", SC2WOL_LOC_ID_OFFSET + 700),
|
||||
LocationData("Haven's Fall", "Beat Haven's Fall", None),
|
||||
LocationData("Smash and Grab", "Smash and Grab: Victory", SC2WOL_LOC_ID_OFFSET + 800),
|
||||
LocationData("Evacuation", "Evacuation: Second Chysalis", SC2WOL_LOC_ID_OFFSET + 402,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Evacuation", "Evacuation: Third Chysalis", SC2WOL_LOC_ID_OFFSET + 403,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Evacuation", "Beat Evacuation", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Outbreak", "Outbreak: Victory", SC2WOL_LOC_ID_OFFSET + 500,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) or state.has("Reaper", player)),
|
||||
LocationData("Outbreak", "Outbreak: Left Infestor", SC2WOL_LOC_ID_OFFSET + 501,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) or state.has("Reaper", player)),
|
||||
LocationData("Outbreak", "Outbreak: Right Infestor", SC2WOL_LOC_ID_OFFSET + 502,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) or state.has("Reaper", player)),
|
||||
LocationData("Outbreak", "Beat Outbreak", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) or state.has("Reaper", player)),
|
||||
LocationData("Safe Haven", "Safe Haven: Victory", SC2WOL_LOC_ID_OFFSET + 600,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Safe Haven", "Beat Safe Haven", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Haven's Fall", "Haven's Fall: Victory", SC2WOL_LOC_ID_OFFSET + 700,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Haven's Fall", "Beat Haven's Fall", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Smash and Grab", "Smash and Grab: Victory", SC2WOL_LOC_ID_OFFSET + 800,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Smash and Grab", "Smash and Grab: First Relic", SC2WOL_LOC_ID_OFFSET + 801),
|
||||
LocationData("Smash and Grab", "Smash and Grab: Second Relic", SC2WOL_LOC_ID_OFFSET + 802),
|
||||
LocationData("Smash and Grab", "Smash and Grab: Third Relic", SC2WOL_LOC_ID_OFFSET + 803),
|
||||
LocationData("Smash and Grab", "Smash and Grab: Fourth Relic", SC2WOL_LOC_ID_OFFSET + 804),
|
||||
LocationData("Smash and Grab", "Beat Smash and Grab", None),
|
||||
LocationData("The Dig", "The Dig: Victory", SC2WOL_LOC_ID_OFFSET + 900),
|
||||
LocationData("The Dig", "The Dig: Left Relic", SC2WOL_LOC_ID_OFFSET + 901),
|
||||
LocationData("The Dig", "The Dig: Right Ground Relic", SC2WOL_LOC_ID_OFFSET + 902),
|
||||
LocationData("The Dig", "The Dig: Right Cliff Relic", SC2WOL_LOC_ID_OFFSET + 903),
|
||||
LocationData("The Dig", "Beat The Dig", None),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: 3rd Data Core", SC2WOL_LOC_ID_OFFSET + 1000),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: 1st Data Core ", SC2WOL_LOC_ID_OFFSET + 1001),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: 2nd Data Core", SC2WOL_LOC_ID_OFFSET + 1002),
|
||||
LocationData("Smash and Grab", "Smash and Grab: Third Relic", SC2WOL_LOC_ID_OFFSET + 803,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Smash and Grab", "Smash and Grab: Fourth Relic", SC2WOL_LOC_ID_OFFSET + 804,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_anti_air(world, player)),
|
||||
LocationData("Smash and Grab", "Beat Smash and Grab", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_anti_air(world, player)),
|
||||
LocationData("The Dig", "The Dig: Victory", SC2WOL_LOC_ID_OFFSET + 900,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_anti_air(world, player) and
|
||||
state._sc2wol_has_heavy_defense(world, player)),
|
||||
LocationData("The Dig", "The Dig: Left Relic", SC2WOL_LOC_ID_OFFSET + 901,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("The Dig", "The Dig: Right Ground Relic", SC2WOL_LOC_ID_OFFSET + 902,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("The Dig", "The Dig: Right Cliff Relic", SC2WOL_LOC_ID_OFFSET + 903,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("The Dig", "Beat The Dig", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_anti_air(world, player) and
|
||||
state._sc2wol_has_heavy_defense(world, player)),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: 3rd Data Core", SC2WOL_LOC_ID_OFFSET + 1000,
|
||||
lambda state: state._sc2wol_has_air(world, player)),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: 1st Data Core ", SC2WOL_LOC_ID_OFFSET + 1001,
|
||||
lambda state: state._sc2wol_has_air(world, player) or True),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: 2nd Data Core", SC2WOL_LOC_ID_OFFSET + 1002,
|
||||
lambda state: state._sc2wol_has_air(world, player)),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: South Rescue", SC2WOL_LOC_ID_OFFSET + 1003,
|
||||
lambda state: state._sc2wol_able_to_rescue(world, player) or True),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: Wall Rescue", SC2WOL_LOC_ID_OFFSET + 1004,
|
||||
|
@ -71,30 +116,58 @@ def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[L
|
|||
lambda state: state._sc2wol_able_to_rescue(world, player) or True),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: Alive Inside Rescue", SC2WOL_LOC_ID_OFFSET + 1007,
|
||||
lambda state: state._sc2wol_able_to_rescue(world, player) or True),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: Brutalisk", SC2WOL_LOC_ID_OFFSET + 1008),
|
||||
LocationData("The Moebius Factor", "Beat The Moebius Factor", None),
|
||||
LocationData("Supernova", "Supernova: Victory", SC2WOL_LOC_ID_OFFSET + 1100),
|
||||
LocationData("The Moebius Factor", "The Moebius Factor: Brutalisk", SC2WOL_LOC_ID_OFFSET + 1008,
|
||||
lambda state: state._sc2wol_has_air(world, player)),
|
||||
LocationData("The Moebius Factor", "Beat The Moebius Factor", None,
|
||||
lambda state: state._sc2wol_has_air(world, player)),
|
||||
LocationData("Supernova", "Supernova: Victory", SC2WOL_LOC_ID_OFFSET + 1100,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Supernova", "Supernova: West Relic", SC2WOL_LOC_ID_OFFSET + 1101),
|
||||
LocationData("Supernova", "Supernova: North Relic", SC2WOL_LOC_ID_OFFSET + 1102),
|
||||
LocationData("Supernova", "Supernova: South Relic", SC2WOL_LOC_ID_OFFSET + 1103),
|
||||
LocationData("Supernova", "Supernova: East Relic", SC2WOL_LOC_ID_OFFSET + 1104),
|
||||
LocationData("Supernova", "Beat Supernova", None),
|
||||
LocationData("Maw of the Void", "Maw of the Void: Xel'Naga Vault", SC2WOL_LOC_ID_OFFSET + 1200),
|
||||
LocationData("Supernova", "Supernova: North Relic", SC2WOL_LOC_ID_OFFSET + 1102,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Supernova", "Supernova: South Relic", SC2WOL_LOC_ID_OFFSET + 1103,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Supernova", "Supernova: East Relic", SC2WOL_LOC_ID_OFFSET + 1104,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Supernova", "Beat Supernova", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Maw of the Void", "Maw of the Void: Xel'Naga Vault", SC2WOL_LOC_ID_OFFSET + 1200,
|
||||
lambda state: state.has('Battlecruiser', player) or state.has('Science Vessel', player) and
|
||||
state._sc2wol_has_air(world, player)),
|
||||
LocationData("Maw of the Void", "Maw of the Void: Landing Zone Cleared", SC2WOL_LOC_ID_OFFSET + 1201),
|
||||
LocationData("Maw of the Void", "Maw of the Void: Expansion Prisoners", SC2WOL_LOC_ID_OFFSET + 1202),
|
||||
LocationData("Maw of the Void", "Maw of the Void: South Close Prisoners", SC2WOL_LOC_ID_OFFSET + 1203),
|
||||
LocationData("Maw of the Void", "Maw of the Void: South Far Prisoners", SC2WOL_LOC_ID_OFFSET + 1204),
|
||||
LocationData("Maw of the Void", "Maw of the Void: North Prisoners", SC2WOL_LOC_ID_OFFSET + 1205),
|
||||
LocationData("Maw of the Void", "Beat Maw of the Void", None),
|
||||
LocationData("Devil's Playground", "Devil's Playground: 8000 Minerals", SC2WOL_LOC_ID_OFFSET + 1300),
|
||||
LocationData("Maw of the Void", "Maw of the Void: South Close Prisoners", SC2WOL_LOC_ID_OFFSET + 1203,
|
||||
lambda state: state.has('Battlecruiser', player) or state.has('Science Vessel', player) and
|
||||
state._sc2wol_has_air(world, player)),
|
||||
LocationData("Maw of the Void", "Maw of the Void: South Far Prisoners", SC2WOL_LOC_ID_OFFSET + 1204,
|
||||
lambda state: state.has('Battlecruiser', player) or state.has('Science Vessel', player) and
|
||||
state._sc2wol_has_air(world, player)),
|
||||
LocationData("Maw of the Void", "Maw of the Void: North Prisoners", SC2WOL_LOC_ID_OFFSET + 1205,
|
||||
lambda state: state.has('Battlecruiser', player) or state.has('Science Vessel', player) and
|
||||
state._sc2wol_has_air(world, player)),
|
||||
LocationData("Maw of the Void", "Beat Maw of the Void", None,
|
||||
lambda state: state.has('Battlecruiser', player) or state.has('Science Vessel', player) and
|
||||
state._sc2wol_has_air(world, player)),
|
||||
LocationData("Devil's Playground", "Devil's Playground: 8000 Minerals", SC2WOL_LOC_ID_OFFSET + 1300,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) or state.has("Reaper", player)),
|
||||
LocationData("Devil's Playground", "Devil's Playground: Tosh's Miners", SC2WOL_LOC_ID_OFFSET + 1301),
|
||||
LocationData("Devil's Playground", "Devil's Playground: Brutalisk", SC2WOL_LOC_ID_OFFSET + 1302),
|
||||
LocationData("Devil's Playground", "Beat Devil's Playground", None),
|
||||
LocationData("Welcome to the Jungle", "Welcome to the Jungle: 7 Canisters", SC2WOL_LOC_ID_OFFSET + 1400),
|
||||
LocationData("Devil's Playground", "Devil's Playground: Brutalisk", SC2WOL_LOC_ID_OFFSET + 1302,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) or state.has("Reaper", player)),
|
||||
LocationData("Devil's Playground", "Beat Devil's Playground", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) or state.has("Reaper", player)),
|
||||
LocationData("Welcome to the Jungle", "Welcome to the Jungle: 7 Canisters", SC2WOL_LOC_ID_OFFSET + 1400,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Welcome to the Jungle", "Welcome to the Jungle: Close Relic", SC2WOL_LOC_ID_OFFSET + 1401),
|
||||
LocationData("Welcome to the Jungle", "Welcome to the Jungle: West Relic", SC2WOL_LOC_ID_OFFSET + 1402),
|
||||
LocationData("Welcome to the Jungle", "Welcome to the Jungle: North-East Relic", SC2WOL_LOC_ID_OFFSET + 1403),
|
||||
LocationData("Welcome to the Jungle", "Beat Welcome to the Jungle", None),
|
||||
LocationData("Welcome to the Jungle", "Welcome to the Jungle: West Relic", SC2WOL_LOC_ID_OFFSET + 1402,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Welcome to the Jungle", "Welcome to the Jungle: North-East Relic", SC2WOL_LOC_ID_OFFSET + 1403,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Welcome to the Jungle", "Beat Welcome to the Jungle", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player) and
|
||||
state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Breakout", "Breakout: Main Prison", SC2WOL_LOC_ID_OFFSET + 1500),
|
||||
LocationData("Breakout", "Breakout: Diamondback Prison", SC2WOL_LOC_ID_OFFSET + 1501),
|
||||
LocationData("Breakout", "Breakout: Siegetank Prison", SC2WOL_LOC_ID_OFFSET + 1502),
|
||||
|
@ -106,36 +179,51 @@ def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[L
|
|||
LocationData("Ghost of a Chance", "Ghost of a Chance: Second Island Spectres", SC2WOL_LOC_ID_OFFSET + 1604),
|
||||
LocationData("Ghost of a Chance", "Ghost of a Chance: Third Island Spectres", SC2WOL_LOC_ID_OFFSET + 1605),
|
||||
LocationData("Ghost of a Chance", "Beat Ghost of a Chance", None),
|
||||
LocationData("The Great Train Robbery", "The Great Train Robbery: 8 Trains", SC2WOL_LOC_ID_OFFSET + 1700, lambda state: state._sc2wol_has_train_killers(world, player)),
|
||||
LocationData("The Great Train Robbery", "The Great Train Robbery: 8 Trains", SC2WOL_LOC_ID_OFFSET + 1700,
|
||||
lambda state: state._sc2wol_has_train_killers(world, player)),
|
||||
LocationData("The Great Train Robbery", "The Great Train Robbery: North Defiler", SC2WOL_LOC_ID_OFFSET + 1701),
|
||||
LocationData("The Great Train Robbery", "The Great Train Robbery: Mid Defiler", SC2WOL_LOC_ID_OFFSET + 1702),
|
||||
LocationData("The Great Train Robbery", "The Great Train Robbery: South Defiler", SC2WOL_LOC_ID_OFFSET + 1703),
|
||||
LocationData("The Great Train Robbery", "Beat The Great Train Robbery", None,
|
||||
lambda state: state._sc2wol_has_train_killers(world, player)),
|
||||
LocationData("Cutthroat", "Cutthroat: Orlan's Planetary", SC2WOL_LOC_ID_OFFSET + 1800),
|
||||
LocationData("Cutthroat", "Cutthroat: Mira Han", SC2WOL_LOC_ID_OFFSET + 1801),
|
||||
LocationData("Cutthroat", "Cutthroat: North Relic", SC2WOL_LOC_ID_OFFSET + 1802),
|
||||
LocationData("Cutthroat", "Cutthroat: Orlan's Planetary", SC2WOL_LOC_ID_OFFSET + 1800,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Cutthroat", "Cutthroat: Mira Han", SC2WOL_LOC_ID_OFFSET + 1801,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Cutthroat", "Cutthroat: North Relic", SC2WOL_LOC_ID_OFFSET + 1802,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Cutthroat", "Cutthroat: Mid Relic", SC2WOL_LOC_ID_OFFSET + 1803),
|
||||
LocationData("Cutthroat", "Cutthroat: Southwest Relic", SC2WOL_LOC_ID_OFFSET + 1804),
|
||||
LocationData("Cutthroat", "Beat Cutthroat", None),
|
||||
LocationData("Cutthroat", "Cutthroat: Southwest Relic", SC2WOL_LOC_ID_OFFSET + 1804,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Cutthroat", "Beat Cutthroat", None,
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
LocationData("Engine of Destruction", "Engine of Destruction: Dominion Bases", SC2WOL_LOC_ID_OFFSET + 1900,
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Engine of Destruction", "Engine of Destruction: Odin", SC2WOL_LOC_ID_OFFSET + 1901),
|
||||
LocationData("Engine of Destruction", "Engine of Destruction: Loki", SC2WOL_LOC_ID_OFFSET + 1902,
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player) and
|
||||
state._sc2wol_has_common_unit(world, player) or state.has('Wraith', player)),
|
||||
LocationData("Engine of Destruction", "Engine of Destruction: Lab Devourer", SC2WOL_LOC_ID_OFFSET + 1903),
|
||||
LocationData("Engine of Destruction", "Engine of Destruction: North Devourer", SC2WOL_LOC_ID_OFFSET + 1904,
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player) and
|
||||
state._sc2wol_has_common_unit(world, player) or state.has('Wraith', player)),
|
||||
LocationData("Engine of Destruction", "Engine of Destruction: Southeast Devourer", SC2WOL_LOC_ID_OFFSET + 1905,
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player) and
|
||||
state._sc2wol_has_common_unit(world, player) or state.has('Wraith', player)),
|
||||
LocationData("Engine of Destruction", "Beat Engine of Destruction", None,
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player)),
|
||||
LocationData("Media Blitz", "Media Blitz: Full Upload", SC2WOL_LOC_ID_OFFSET + 2000),
|
||||
LocationData("Media Blitz", "Media Blitz: Tower 1", SC2WOL_LOC_ID_OFFSET + 2001),
|
||||
LocationData("Media Blitz", "Media Blitz: Tower 2", SC2WOL_LOC_ID_OFFSET + 2002),
|
||||
LocationData("Media Blitz", "Media Blitz: Tower 3", SC2WOL_LOC_ID_OFFSET + 2003),
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player) and
|
||||
state._sc2wol_has_common_unit(world, player) or state.has('Wraith', player)),
|
||||
LocationData("Media Blitz", "Media Blitz: Full Upload", SC2WOL_LOC_ID_OFFSET + 2000,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Media Blitz", "Media Blitz: Tower 1", SC2WOL_LOC_ID_OFFSET + 2001,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Media Blitz", "Media Blitz: Tower 2", SC2WOL_LOC_ID_OFFSET + 2002,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Media Blitz", "Media Blitz: Tower 3", SC2WOL_LOC_ID_OFFSET + 2003,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Media Blitz", "Media Blitz: Science Facility", SC2WOL_LOC_ID_OFFSET + 2004),
|
||||
LocationData("Media Blitz", "Beat Media Blitz", None),
|
||||
LocationData("Media Blitz", "Beat Media Blitz", None,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Piercing the Shroud", "Piercing the Shroud: Facility Escape", SC2WOL_LOC_ID_OFFSET + 2100),
|
||||
LocationData("Piercing the Shroud", "Piercing the Shroud: Holding Cell Relic", SC2WOL_LOC_ID_OFFSET + 2101),
|
||||
LocationData("Piercing the Shroud", "Piercing the Shroud: Brutalisk Relic", SC2WOL_LOC_ID_OFFSET + 2102),
|
||||
|
@ -156,31 +244,45 @@ def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[L
|
|||
lambda state: state._sc2wol_has_protoss_common_units(world, player)),
|
||||
LocationData("A Sinister Turn", "Beat A Sinister Turn", None,
|
||||
lambda state: state._sc2wol_has_protoss_medium_units(world, player)),
|
||||
LocationData("Echoes of the Future", "Echoes of the Future: Overmind", SC2WOL_LOC_ID_OFFSET + 2400),
|
||||
LocationData("Echoes of the Future", "Echoes of the Future: Overmind", SC2WOL_LOC_ID_OFFSET + 2400,
|
||||
lambda state: state._sc2wol_has_protoss_medium_units(world, player)),
|
||||
LocationData("Echoes of the Future", "Echoes of the Future: Close Obelisk", SC2WOL_LOC_ID_OFFSET + 2401),
|
||||
LocationData("Echoes of the Future", "Echoes of the Future: West Obelisk", SC2WOL_LOC_ID_OFFSET + 2402),
|
||||
LocationData("Echoes of the Future", "Beat Echoes of the Future", None),
|
||||
LocationData("In Utter Darkness", "In Utter Darkness: Kills", SC2WOL_LOC_ID_OFFSET + 2500),
|
||||
LocationData("In Utter Darkness", "In Utter Darkness: Protoss Archive", SC2WOL_LOC_ID_OFFSET + 2501),
|
||||
LocationData("Echoes of the Future", "Echoes of the Future: West Obelisk", SC2WOL_LOC_ID_OFFSET + 2402,
|
||||
lambda state: state._sc2wol_has_protoss_common_units(world, player)),
|
||||
LocationData("Echoes of the Future", "Beat Echoes of the Future", None,
|
||||
lambda state: state._sc2wol_has_protoss_medium_units(world, player)),
|
||||
LocationData("In Utter Darkness", "In Utter Darkness: Kills", SC2WOL_LOC_ID_OFFSET + 2500,
|
||||
lambda state: state._sc2wol_has_protoss_medium_units(world, player)),
|
||||
LocationData("In Utter Darkness", "In Utter Darkness: Protoss Archive", SC2WOL_LOC_ID_OFFSET + 2501,
|
||||
lambda state: state._sc2wol_has_protoss_medium_units(world, player)),
|
||||
LocationData("In Utter Darkness", "In Utter Darkness: Defeat", SC2WOL_LOC_ID_OFFSET + 2502),
|
||||
LocationData("In Utter Darkness", "Beat In Utter Darkness", None),
|
||||
LocationData("Gates of Hell", "Gates of Hell: Nydus Worms", SC2WOL_LOC_ID_OFFSET + 2600),
|
||||
LocationData("Gates of Hell", "Gates of Hell: Large Army", SC2WOL_LOC_ID_OFFSET + 2601),
|
||||
LocationData("In Utter Darkness", "Beat In Utter Darkness", None,
|
||||
lambda state: state._sc2wol_has_protoss_medium_units(world, player)),
|
||||
LocationData("Gates of Hell", "Gates of Hell: Nydus Worms", SC2WOL_LOC_ID_OFFSET + 2600,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Gates of Hell", "Gates of Hell: Large Army", SC2WOL_LOC_ID_OFFSET + 2601,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Gates of Hell", "Beat Gates of Hell", None),
|
||||
LocationData("Belly of the Beast", "Belly of the Beast: Extract", SC2WOL_LOC_ID_OFFSET + 2700),
|
||||
LocationData("Belly of the Beast", "Belly of the Beast: First Charge", SC2WOL_LOC_ID_OFFSET + 2701),
|
||||
LocationData("Belly of the Beast", "Belly of the Beast: Second Charge", SC2WOL_LOC_ID_OFFSET + 2702),
|
||||
LocationData("Belly of the Beast", "Belly of the Beast: Third Charge", SC2WOL_LOC_ID_OFFSET + 2703),
|
||||
LocationData("Belly of the Beast", "Beat Belly of the Beast", None),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Platform Destroyed", SC2WOL_LOC_ID_OFFSET + 2800),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Close Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2801),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Northwest Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2802),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Southeast Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2803),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Southwest Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2804),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Leviathan", SC2WOL_LOC_ID_OFFSET + 2805),
|
||||
LocationData("Shatter the Sky", "Beat Shatter the Sky", None),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Platform Destroyed", SC2WOL_LOC_ID_OFFSET + 2800,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Close Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2801,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Northwest Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2802,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Southeast Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2803,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Southwest Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2804,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Shatter the Sky", "Shatter the Sky: Leviathan", SC2WOL_LOC_ID_OFFSET + 2805,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("Shatter the Sky", "Beat Shatter the Sky", None,
|
||||
lambda state: state._sc2wol_has_competent_comp(world, player)),
|
||||
LocationData("All-In", "All-In: Victory", None)
|
||||
]
|
||||
|
||||
return tuple(location_table)
|
||||
|
||||
|
|
|
@ -12,9 +12,6 @@ class SC2WoLLogic(LogicMixin):
|
|||
def _sc2wol_has_air(self, world: MultiWorld, player: int) -> bool:
|
||||
return self.has_any({'Viking', 'Wraith', 'Medivac', 'Banshee', 'Hercules'}, player)
|
||||
|
||||
def _sc2wol_has_battlecruiser(self, world: MultiWorld, player: int) -> bool:
|
||||
return self.has('Battlecruiser', player)
|
||||
|
||||
def _sc2wol_has_air_anti_air(self, world: MultiWorld, player: int) -> bool:
|
||||
return self.has_any({'Viking', 'Wraith'}, player)
|
||||
|
||||
|
@ -29,6 +26,12 @@ class SC2WoLLogic(LogicMixin):
|
|||
self.has('Bunker', player) and self._sc2wol_has_bunker_unit(world, player)) and \
|
||||
self._sc2wol_has_anti_air(world, player)
|
||||
|
||||
def _sc2wol_has_competent_comp(self, world: MultiWorld, player: int) -> bool:
|
||||
return (self.has('Marine', player) or self.has('Marauder', player) and
|
||||
self._sc2wol_has_mobile_anti_air(world, player)) and self.has_any({'Medivac', 'Medic'}, player) or \
|
||||
self.has('Thor', player) or self.has("Banshee", player) and self._sc2wol_has_mobile_anti_air(world, player) or \
|
||||
self.has('Battlecruiser', player) and self._sc2wol_has_common_unit(world, player)
|
||||
|
||||
def _sc2wol_has_train_killers(self, world: MultiWorld, player: int) -> bool:
|
||||
return (self.has_any({'Siege Tank', 'Diamondback'}, player) or
|
||||
self.has_all({'Reaper', "G-4 Clusterbomb"}, player) or self.has_all({'Spectre', 'Psionic Lash'}, player))
|
||||
|
|
|
@ -48,54 +48,71 @@ def create_regions(world: MultiWorld, player: int, locations: Tuple[LocationData
|
|||
|
||||
connect(world, player, names, 'Menu', 'Liberation Day'),
|
||||
connect(world, player, names, 'Liberation Day', 'The Outlaws',
|
||||
lambda state: state._sc2wol_has_common_unit(world, player)),
|
||||
connect(world, player, names, 'The Outlaws', 'Zero Hour'),
|
||||
lambda state: state.has("Beat Liberation Day", player)),
|
||||
connect(world, player, names, 'The Outlaws', 'Zero Hour',
|
||||
lambda state: state.has("Beat The Outlaws", player)),
|
||||
connect(world, player, names, 'Zero Hour', 'Evacuation',
|
||||
lambda state: state._sc2wol_has_anti_air(world, player)),
|
||||
connect(world, player, names, 'Evacuation', 'Outbreak'),
|
||||
lambda state: state.has("Beat Zero Hour", player)),
|
||||
connect(world, player, names, 'Evacuation', 'Outbreak',
|
||||
lambda state: state.has("Beat Evacuation", player)),
|
||||
connect(world, player, names, "Outbreak", "Safe Haven",
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player) and
|
||||
state._sc2wol_cleared_missions(world, player, 7)),
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 7) and
|
||||
state.has("Beat Outbreak", player)),
|
||||
connect(world, player, names, "Outbreak", "Haven's Fall",
|
||||
lambda state: state._sc2wol_has_mobile_anti_air(world, player) and
|
||||
state._sc2wol_cleared_missions(world, player, 7)),
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 7) and
|
||||
state.has("Beat Outbreak", player)),
|
||||
connect(world, player, names, 'Zero Hour', 'Smash and Grab',
|
||||
lambda state: state._sc2wol_has_anti_air(world, player)),
|
||||
lambda state: state.has("Beat Zero Hour", player)),
|
||||
connect(world, player, names, 'Smash and Grab', 'The Dig',
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 8) and
|
||||
state._sc2wol_has_heavy_defense(world, player)),
|
||||
state.has("Beat Smash and Grab", player)),
|
||||
connect(world, player, names, 'The Dig', 'The Moebius Factor',
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 11) and
|
||||
state._sc2wol_has_air(world, player)),
|
||||
state.has("Beat The Dig", player)),
|
||||
connect(world, player, names, 'The Moebius Factor', 'Supernova',
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 14)),
|
||||
connect(world, player, names, 'Supernova', 'Maw of the Void'),
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 14) and
|
||||
state.has("Beat The Moebius Factor", player)),
|
||||
connect(world, player, names, 'Supernova', 'Maw of the Void',
|
||||
lambda state: state.has("Beat Supernova", player)),
|
||||
connect(world, player, names, 'Zero Hour', "Devil's Playground",
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 4)),
|
||||
connect(world, player, names, "Devil's Playground", 'Welcome to the Jungle'),
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 4) and
|
||||
state.has("Beat Zero Hour", player)),
|
||||
connect(world, player, names, "Devil's Playground", 'Welcome to the Jungle',
|
||||
lambda state: state.has("Beat Devil's Playground", player)),
|
||||
connect(world, player, names, "Welcome to the Jungle", 'Breakout',
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 8)),
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 8) and
|
||||
state.has("Beat Welcome to the Jungle", player)),
|
||||
connect(world, player, names, "Welcome to the Jungle", 'Ghost of a Chance',
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 8)),
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 8) and
|
||||
state.has("Beat Welcome to the Jungle", player)),
|
||||
connect(world, player, names, "Zero Hour", 'The Great Train Robbery',
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 6)),
|
||||
lambda state: state._sc2wol_cleared_missions(world, player, 6) and
|
||||
state.has("Beat Zero Hour", player)),
|
||||
connect(world, player, names, 'The Great Train Robbery', 'Cutthroat',
|
||||
lambda state: state.has("Beat The Great Train Robbery", player)),
|
||||
connect(world, player, names, 'Cutthroat', 'Engine of Destruction',
|
||||
lambda state: state.has("Beat The Great Train Robbery", player)),
|
||||
lambda state: state.has("Beat Cutthroat", player)),
|
||||
connect(world, player, names, 'Engine of Destruction', 'Media Blitz',
|
||||
lambda state: state.has("Beat Engine of Destruction", player)),
|
||||
connect(world, player, names, 'Media Blitz', 'Piercing the Shroud'),
|
||||
connect(world, player, names, 'The Dig', 'Whispers of Doom',),
|
||||
connect(world, player, names, 'Whispers of Doom', 'A Sinister Turn'),
|
||||
connect(world, player, names, 'Media Blitz', 'Piercing the Shroud',
|
||||
lambda state: state.has("Beat Media Blitz", player)),
|
||||
connect(world, player, names, 'The Dig', 'Whispers of Doom',
|
||||
lambda state: state.has("Beat The Dig", player)),
|
||||
connect(world, player, names, 'Whispers of Doom', 'A Sinister Turn',
|
||||
lambda state: state.has("Beat Whispers of Doom", player)),
|
||||
connect(world, player, names, 'A Sinister Turn', 'Echoes of the Future',
|
||||
lambda state: state.has("Beat A Sinister Turn", player)),
|
||||
connect(world, player, names, 'Echoes of the Future', 'In Utter Darkness'),
|
||||
connect(world, player, names, 'Maw of the Void', 'Gates of Hell'),
|
||||
connect(world, player, names, 'Gates of Hell', 'Belly of the Beast'),
|
||||
connect(world, player, names, 'Gates of Hell', 'Shatter the Sky'),
|
||||
connect(world, player, names, 'Echoes of the Future', 'In Utter Darkness',
|
||||
lambda state: state.has("Beat Echoes of the Future", player)),
|
||||
connect(world, player, names, 'Maw of the Void', 'Gates of Hell',
|
||||
lambda state: state.has("Beat Maw of the Void", player)),
|
||||
connect(world, player, names, 'Gates of Hell', 'Belly of the Beast',
|
||||
lambda state: state.has("Beat Gates of Hell", player)),
|
||||
connect(world, player, names, 'Gates of Hell', 'Shatter the Sky',
|
||||
lambda state: state.has("Beat Gates of Hell", player)),
|
||||
connect(world, player, names, 'Gates of Hell', 'All-In',
|
||||
lambda state: state.has('Beat Gates of Hell', player) or state.has('Beat Shatter the Sky', player))
|
||||
lambda state: state.has('Beat Gates of Hell', player) and (
|
||||
state.has('Beat Shatter the Sky', player) or state.has('Beat Belly of the Beast', player)))
|
||||
|
||||
|
||||
def throwIfAnyLocationIsNotAssignedToARegion(regions: List[Region], regionNames: Set[str]):
|
||||
|
@ -105,10 +122,12 @@ def throwIfAnyLocationIsNotAssignedToARegion(regions: List[Region], regionNames:
|
|||
existingRegions.add(region.name)
|
||||
|
||||
if (regionNames - existingRegions):
|
||||
raise Exception("Starcraft: the following regions are used in locations: {}, but no such region exists".format(regionNames - existingRegions))
|
||||
raise Exception("Starcraft: the following regions are used in locations: {}, but no such region exists".format(
|
||||
regionNames - existingRegions))
|
||||
|
||||
|
||||
def create_location(player: int, location_data: LocationData, region: Region, location_cache: List[Location]) -> Location:
|
||||
def create_location(player: int, location_data: LocationData, region: Region,
|
||||
location_cache: List[Location]) -> Location:
|
||||
location = Location(player, location_data.name, location_data.code, region)
|
||||
location.access_rule = location_data.rule
|
||||
|
||||
|
@ -121,7 +140,8 @@ def create_location(player: int, location_data: LocationData, region: Region, lo
|
|||
return location
|
||||
|
||||
|
||||
def create_region(world: MultiWorld, player: int, locations_per_region: Dict[str, List[LocationData]], location_cache: List[Location], name: str) -> Region:
|
||||
def create_region(world: MultiWorld, player: int, locations_per_region: Dict[str, List[LocationData]],
|
||||
location_cache: List[Location], name: str) -> Region:
|
||||
region = Region(name, RegionType.Generic, name, player)
|
||||
region.world = world
|
||||
|
||||
|
@ -133,7 +153,8 @@ def create_region(world: MultiWorld, player: int, locations_per_region: Dict[str
|
|||
return region
|
||||
|
||||
|
||||
def connect(world: MultiWorld, player: int, used_names: Dict[str, int], source: str, target: str, rule: Optional[Callable] = None):
|
||||
def connect(world: MultiWorld, player: int, used_names: Dict[str, int], source: str, target: str,
|
||||
rule: Optional[Callable] = None):
|
||||
sourceRegion = world.get_region(source, player)
|
||||
targetRegion = world.get_region(target, player)
|
||||
|
||||
|
@ -154,7 +175,7 @@ def connect(world: MultiWorld, player: int, used_names: Dict[str, int], source:
|
|||
|
||||
|
||||
def get_locations_per_region(locations: Tuple[LocationData, ...]) -> Dict[str, List[LocationData]]:
|
||||
per_region: Dict[str, List[LocationData]] = {}
|
||||
per_region: Dict[str, List[LocationData]] = {}
|
||||
|
||||
for location in locations:
|
||||
per_region.setdefault(location.region, []).append(location)
|
||||
|
|
Loading…
Reference in New Issue