From c78558cba865e211654da81ffafef31b7488d912 Mon Sep 17 00:00:00 2001 From: Ziktofel Date: Sat, 30 Nov 2024 19:11:23 +0100 Subject: [PATCH] Add Unsealing the Past race swaps --- worlds/sc2/item/item_tables.py | 6 +-- worlds/sc2/locations.py | 78 ++++++++++++++++++++++++++++++++++ worlds/sc2/mission_tables.py | 5 ++- worlds/sc2/rules.py | 52 +++++++++++++++++++++++ 4 files changed, 136 insertions(+), 5 deletions(-) diff --git a/worlds/sc2/item/item_tables.py b/worlds/sc2/item/item_tables.py index b901db6ec030..b51381829712 100644 --- a/worlds/sc2/item/item_tables.py +++ b/worlds/sc2/item/item_tables.py @@ -474,7 +474,7 @@ def get_full_item_list(): important_for_filtering=True), item_names.SIEGE_TANK_SMART_SERVOS: ItemData(270 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 5, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=item_names.SIEGE_TANK), + classification=ItemClassification.progression, parent_item=item_names.SIEGE_TANK), item_names.SIEGE_TANK_GRADUATING_RANGE: ItemData(271 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 6, SC2Race.TERRAN, classification=ItemClassification.progression, parent_item=item_names.SIEGE_TANK), @@ -813,7 +813,7 @@ def get_full_item_list(): classification=ItemClassification.filler, parent_item=item_names.CYCLONE), item_names.LIBERATOR_SMART_SERVOS: ItemData(384 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 3, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=item_names.LIBERATOR), + classification=ItemClassification.progression, parent_item=item_names.LIBERATOR), item_names.LIBERATOR_RESOURCE_EFFICIENCY: ItemData(385 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 4, SC2Race.TERRAN, classification=ItemClassification.filler, parent_item=item_names.LIBERATOR), @@ -843,7 +843,7 @@ def get_full_item_list(): parent_item=item_names.BATTLECRUISER), item_names.BATTLECRUISER_COVERT_OPS_ENGINES: ItemData(394 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 12, SC2Race.TERRAN, - parent_item=item_names.BATTLECRUISER), + classification=ItemClassification.progression, parent_item=item_names.BATTLECRUISER), item_names.PLANETARY_FORTRESS_ORBITAL_MODULE: ItemData(395 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 1, SC2Race.TERRAN, parent_item=item_names.PLANETARY_FORTRESS), diff --git a/worlds/sc2/locations.py b/worlds/sc2/locations.py index 8f0102e69a68..231e399040e8 100644 --- a/worlds/sc2/locations.py +++ b/worlds/sc2/locations.py @@ -5182,6 +5182,84 @@ def get_locations(world: Optional['SC2World']) -> Tuple[LocationData, ...]: make_location_data(SC2Mission.HARBINGER_OF_OBLIVION_Z.mission_name, "North Xel'Naga Vessel", SC2_RACESWAP_LOC_ID_OFFSET + 12608, LocationType.VANILLA, logic.zerg_harbinger_of_oblivion_requirement ), + make_location_data(SC2Mission.UNSEALING_THE_PAST_T.mission_name, "Victory", SC2_RACESWAP_LOC_ID_OFFSET + 12700, LocationType.VICTORY, + logic.terran_unsealing_the_past_requirement + ), + make_location_data(SC2Mission.UNSEALING_THE_PAST_T.mission_name, "Zerg Cleared", SC2_RACESWAP_LOC_ID_OFFSET + 12701, LocationType.EXTRA), + make_location_data(SC2Mission.UNSEALING_THE_PAST_T.mission_name, "First Stasis Lock", SC2_RACESWAP_LOC_ID_OFFSET + 12702, LocationType.EXTRA, + lambda state: ( + logic.advanced_tactics + or logic.terran_unsealing_the_past_requirement + )), + make_location_data(SC2Mission.UNSEALING_THE_PAST_T.mission_name, "Second Stasis Lock", SC2_RACESWAP_LOC_ID_OFFSET + 12703, LocationType.EXTRA, + logic.terran_unsealing_the_past_requirement + ), + make_location_data(SC2Mission.UNSEALING_THE_PAST_T.mission_name, "Third Stasis Lock", SC2_RACESWAP_LOC_ID_OFFSET + 12704, LocationType.EXTRA, + logic.terran_unsealing_the_past_requirement + ), + make_location_data(SC2Mission.UNSEALING_THE_PAST_T.mission_name, "Fourth Stasis Lock", SC2_RACESWAP_LOC_ID_OFFSET + 12705, LocationType.EXTRA, + logic.terran_unsealing_the_past_requirement + ), + make_location_data(SC2Mission.UNSEALING_THE_PAST_T.mission_name, "South Power Core", SC2_RACESWAP_LOC_ID_OFFSET + 12706, LocationType.VANILLA, + lambda state: ( + logic.terran_unsealing_the_past_requirement(state) + and ( + adv_tactics + or logic.terran_air(state) + or state.has_all({item_names.GOLIATH, item_names.GOLIATH_JUMP_JETS}, player) + ) + )), + make_location_data(SC2Mission.UNSEALING_THE_PAST_T.mission_name, "East Power Core", SC2_RACESWAP_LOC_ID_OFFSET + 12707, LocationType.VANILLA, + lambda state: ( + logic.terran_unsealing_the_past_requirement(state) + and ( + adv_tactics + or logic.terran_air(state) + or state.has_all({item_names.GOLIATH, item_names.GOLIATH_JUMP_JETS}, player) + ) + )), + make_location_data(SC2Mission.UNSEALING_THE_PAST_Z.mission_name, "Victory", SC2_RACESWAP_LOC_ID_OFFSET + 12800, LocationType.VICTORY, + logic.zerg_unsealing_the_past_requirement + ), + make_location_data(SC2Mission.UNSEALING_THE_PAST_Z.mission_name, "Zerg Cleared", SC2_RACESWAP_LOC_ID_OFFSET + 12801, LocationType.EXTRA), + make_location_data(SC2Mission.UNSEALING_THE_PAST_Z.mission_name, "First Stasis Lock", SC2_RACESWAP_LOC_ID_OFFSET + 12802, LocationType.EXTRA, + lambda state: ( + logic.advanced_tactics + or logic.zerg_unsealing_the_past_requirement + )), + make_location_data(SC2Mission.UNSEALING_THE_PAST_Z.mission_name, "Second Stasis Lock", SC2_RACESWAP_LOC_ID_OFFSET + 12803, LocationType.EXTRA, + logic.zerg_unsealing_the_past_requirement + ), + make_location_data(SC2Mission.UNSEALING_THE_PAST_Z.mission_name, "Third Stasis Lock", SC2_RACESWAP_LOC_ID_OFFSET + 12804, LocationType.EXTRA, + logic.zerg_unsealing_the_past_requirement + ), + make_location_data(SC2Mission.UNSEALING_THE_PAST_Z.mission_name, "Fourth Stasis Lock", SC2_RACESWAP_LOC_ID_OFFSET + 12805, LocationType.EXTRA, + logic.zerg_unsealing_the_past_requirement + ), + make_location_data(SC2Mission.UNSEALING_THE_PAST_Z.mission_name, "South Power Core", SC2_RACESWAP_LOC_ID_OFFSET + 12806, LocationType.VANILLA, + lambda state: ( + logic.zerg_unsealing_the_past_requirement(state) + and ( + adv_tactics + or ( + state.has(item_names.MUTALISK, player) + or logic.morph_brood_lord(state) + or logic.morph_guardian(state) + ) + ) + )), + make_location_data(SC2Mission.UNSEALING_THE_PAST_Z.mission_name, "East Power Core", SC2_RACESWAP_LOC_ID_OFFSET + 12807, LocationType.VANILLA, + lambda state: ( + logic.zerg_unsealing_the_past_requirement(state) + and ( + adv_tactics + or ( + state.has(item_names.MUTALISK, player) + or logic.morph_brood_lord(state) + or logic.morph_guardian(state) + ) + ) + )), ] beat_events = [] diff --git a/worlds/sc2/mission_tables.py b/worlds/sc2/mission_tables.py index 1a7b7bc4d0df..bfe2f863d7fc 100644 --- a/worlds/sc2/mission_tables.py +++ b/worlds/sc2/mission_tables.py @@ -171,7 +171,7 @@ def __init__(self, mission_id: int, name: str, campaign: SC2Campaign, area: str, TEMPLE_OF_UNIFICATION = 61, "Temple of Unification (Protoss)", SC2Campaign.LOTV, "Ulnar", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_temple_of_unification", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsTP|MissionFlag.HasRaceSwap THE_INFINITE_CYCLE = 62, "The Infinite Cycle", SC2Campaign.LOTV, "Ulnar", SC2Race.ANY, MissionPools.HARD, "ap_the_infinite_cycle", MissionFlag.Protoss|MissionFlag.Kerrigan|MissionFlag.NoBuild|MissionFlag.VsTP HARBINGER_OF_OBLIVION = 63, "Harbinger of Oblivion (Protoss)", SC2Campaign.LOTV, "Ulnar", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_harbinger_of_oblivion", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.Countdown|MissionFlag.VsTP|MissionFlag.AiZergAlly|MissionFlag.HasRaceSwap - UNSEALING_THE_PAST = 64, "Unsealing the Past", SC2Campaign.LOTV, "Purifier", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_unsealing_the_past", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.AutoScroller|MissionFlag.VsZerg + UNSEALING_THE_PAST = 64, "Unsealing the Past (Protoss)", SC2Campaign.LOTV, "Purifier", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_unsealing_the_past", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.AutoScroller|MissionFlag.VsZerg|MissionFlag.HasRaceSwap PURIFICATION = 65, "Purification", SC2Campaign.LOTV, "Purifier", SC2Race.PROTOSS, MissionPools.HARD, "ap_purification", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsZerg STEPS_OF_THE_RITE = 66, "Steps of the Rite", SC2Campaign.LOTV, "Tal'darim", SC2Race.PROTOSS, MissionPools.HARD, "ap_steps_of_the_rite", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsProtoss RAK_SHIR = 67, "Rak'Shir", SC2Campaign.LOTV, "Tal'darim", SC2Race.PROTOSS, MissionPools.HARD, "ap_rak_shir", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsProtoss @@ -305,7 +305,8 @@ def __init__(self, mission_id: int, name: str, campaign: SC2Campaign, area: str, # 206/207 - The Infinite Cycle HARBINGER_OF_OBLIVION_T = 208, "Harbinger of Oblivion (Terran)", SC2Campaign.LOTV, "Ulnar", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_harbinger_of_oblivion", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsTP|MissionFlag.AiZergAlly|MissionFlag.RaceSwap HARBINGER_OF_OBLIVION_Z = 209, "Harbinger of Oblivion (Zerg)", SC2Campaign.LOTV, "Ulnar", SC2Race.ZERG, MissionPools.HARD, "ap_harbinger_of_oblivion", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsTP|MissionFlag.AiZergAlly|MissionFlag.RaceSwap - # 210/211 - Unsealing the Past + UNSEALING_THE_PAST_T = 210, "Unsealing the Past (Terran)", SC2Campaign.LOTV, "Purifier", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_unsealing_the_past", MissionFlag.Terran|MissionFlag.AutoScroller|MissionFlag.VsZerg|MissionFlag.RaceSwap + UNSEALING_THE_PAST_Z = 211, "Unsealing the Past (Zerg)", SC2Campaign.LOTV, "Purifier", SC2Race.ZERG, MissionPools.MEDIUM, "ap_unsealing_the_past", MissionFlag.Zerg|MissionFlag.AutoScroller|MissionFlag.VsZerg|MissionFlag.RaceSwap # 212/213 - Purification # 214/215 - Steps of the Rite # 216/217 - Rak'Shir diff --git a/worlds/sc2/rules.py b/worlds/sc2/rules.py index ca097527d1e6..a6efc9f9a03f 100644 --- a/worlds/sc2/rules.py +++ b/worlds/sc2/rules.py @@ -1726,6 +1726,58 @@ def zerg_harbinger_of_oblivion_requirement(self, state: CollectionState) -> bool ) ) + def terran_unsealing_the_past_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_competent_anti_air(state) + and self.terran_competent_comp(state) + and ( + state.has_all({item_names.SIEGE_TANK, item_names.SIEGE_TANK_JUMP_JETS}, self.player) + or state.has_all({item_names.VIKING, item_names.VIKING_SHREDDER_ROUNDS}, self.player) + or state.has(item_names.BANSHEE, self.player) + or state.has_all({item_names.BATTLECRUISER, item_names.BATTLECRUISER_ATX_LASER_BATTERY, + item_names.BATTLECRUISER_COVERT_OPS_ENGINES}, self.player) + or ( + self.advanced_tactics + and ( + state.has_all({item_names.SIEGE_TANK, item_names.SIEGE_TANK_SMART_SERVOS}, + self.player) + or ( + state.has_all({item_names.LIBERATOR, item_names.LIBERATOR_SMART_SERVOS}, + self.player) + and ( + state.has_all( + {item_names.HELLION, item_names.HELLION_HELLBAT_ASPECT}, + self.player) + or state.has(item_names.FIREBAT, self.player) + ) + and self.terran_bio_heal(state) + ) + ) + ) + ) + ) + + def zerg_unsealing_the_past_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_comp(state) + and self.zerg_competent_anti_air(state) + and ( + self.morph_brood_lord(state) + or self.zerg_big_monsters(state) + or state.has_all({item_names.MUTALISK, item_names.MUTALISK_SEVERING_GLAIVE, item_names.MUTALISK_VICIOUS_GLAIVE}, self.player) + or ( + self.advanced_tactics + and ( + self.morph_igniter(state) + or ( + self.morph_lurker(state) + and state.has(item_names.LURKER_SEISMIC_SPINES, self.player) + ) + ) + ) + ) + ) + def protoss_competent_comp(self, state: CollectionState) -> bool: return ( self.protoss_common_unit(state)