diff --git a/worlds/sc2/item_descriptions.py b/worlds/sc2/item_descriptions.py index 7bd7f160e093..82e47ff0ac3e 100644 --- a/worlds/sc2/item_descriptions.py +++ b/worlds/sc2/item_descriptions.py @@ -744,6 +744,7 @@ def _ability_desc(unit_name_plural: str, ability_name: str, ability_description: item_names.MOTHERSHIP: "Ultimate Protoss vessel, Can use the Vortex and Mass Recall abilities. Cloaks nearby units and structures.", item_names.ARBITER: "Army support craft. Has the Stasis Field and Recall abilities. Cloaks nearby units.", item_names.ORACLE: "Flying caster. Can use the Revelation and Stasis Ward abilities.", + item_names.SKYLORD: "Capital ship. Builds and launches Interceptors that attack enemy targets. Can use Tactical Jump ability.", item_names.PROGRESSIVE_PROTOSS_GROUND_WEAPON: GENERIC_UPGRADE_TEMPLATE.format("damage", PROTOSS, "ground units"), item_names.PROGRESSIVE_PROTOSS_GROUND_ARMOR: GENERIC_UPGRADE_TEMPLATE.format("armor", PROTOSS, "ground units"), item_names.PROGRESSIVE_PROTOSS_SHIELDS: GENERIC_UPGRADE_TEMPLATE.format("shields", PROTOSS, "units"), @@ -792,8 +793,8 @@ def _ability_desc(unit_name_plural: str, ability_name: str, ability_description: item_names.ARBITER_SPACETIME_ANCHOR: "Arbiter Stasis Field lasts 50 seconds longer.", item_names.ARBITER_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.ARBITER), item_names.ARBITER_ENHANCED_CLOAK_FIELD: "Increases Arbiter Cloaking Field range.", - item_names.CARRIER_GRAVITON_CATAPULT: "Carriers can launch Interceptors more quickly.", - item_names.CARRIER_HULL_OF_PAST_GLORIES: "Carriers gain +2 armour.", + item_names.CARRIER_SKYLORD_GRAVITON_CATAPULT: "Carriers can launch Interceptors more quickly.", + item_names.CARRIER_SKYLORD_HULL_OF_PAST_GLORIES: "Carriers gain +2 armour.", item_names.VOID_RAY_DESTROYER_WARP_RAY_SCORCHER_FLUX_VANES: "Increases Void Ray and Destroyer movement speed.", item_names.DESTROYER_REFORGED_BLOODSHARD_CORE: "When fully charged, the Destroyer's Destruction Beam weapon does full damage to secondary targets.", item_names.WARP_PRISM_GRAVITIC_DRIVE: "Increases the movement speed of Warp Prisms.", diff --git a/worlds/sc2/item_groups.py b/worlds/sc2/item_groups.py index 912049a4e597..fb0d0417eb4d 100644 --- a/worlds/sc2/item_groups.py +++ b/worlds/sc2/item_groups.py @@ -533,7 +533,7 @@ def get_all_group_names(cls) -> typing.Set[str]: item_name_groups[ItemGroupNames.STARGATE_UNITS] = stargate_units = [ item_names.PHOENIX, item_names.MIRAGE, item_names.CORSAIR, item_names.VOID_RAY, item_names.DESTROYER, item_names.WARP_RAY, item_names.SCORCHER, - item_names.CARRIER, + item_names.CARRIER, item_names.SKYLORD, item_names.TEMPEST, item_names.SCOUT, item_names.MOTHERSHIP, item_names.ARBITER, item_names.ORACLE, ] @@ -554,7 +554,7 @@ def get_all_group_names(cls) -> typing.Set[str]: item_name_groups[ItemGroupNames.TAL_DARIM_UNITS] = [ item_names.SUPPLICANT, item_names.SLAYER, item_names.HAVOC, item_names.BLOOD_HUNTER, item_names.ASCENDANT, item_names.VANGUARD, item_names.WRATHWALKER, - item_names.DESTROYER, item_names.MOTHERSHIP, + item_names.DESTROYER, item_names.SKYLORD, item_names.MOTHERSHIP, ] item_name_groups[ItemGroupNames.PURIFIER_UNITS] = [ item_names.SENTINEL, item_names.ADEPT, item_names.INSTIGATOR, item_names.ENERGIZER, diff --git a/worlds/sc2/item_names.py b/worlds/sc2/item_names.py index 4eaf6e5e1015..3cf8cc57dd27 100644 --- a/worlds/sc2/item_names.py +++ b/worlds/sc2/item_names.py @@ -536,6 +536,7 @@ PHOENIX = "Phoenix" VOID_RAY = "Void Ray" CARRIER = "Carrier" +SKYLORD = "Skylord" OBSERVER = "Observer" CENTURION = "Centurion" SENTINEL = "Sentinel" @@ -626,8 +627,8 @@ ARBITER_SPACETIME_ANCHOR = "Spacetime Anchor (Arbiter)" ARBITER_RESOURCE_EFFICIENCY = "Resource Efficiency (Arbiter)" ARBITER_ENHANCED_CLOAK_FIELD = "Enhanced Cloak Field (Arbiter)" -CARRIER_GRAVITON_CATAPULT = "Graviton Catapult (Carrier)" -CARRIER_HULL_OF_PAST_GLORIES = "Hull of Past Glories (Carrier)" +CARRIER_SKYLORD_GRAVITON_CATAPULT = "Graviton Catapult (Carrier/Skylord)" +CARRIER_SKYLORD_HULL_OF_PAST_GLORIES = "Hull of Past Glories (Carrier/Skylord)" VOID_RAY_DESTROYER_WARP_RAY_SCORCHER_FLUX_VANES = "Flux Vanes (Void Ray/Destroyer/Warp Ray/Scorcher)" DESTROYER_REFORGED_BLOODSHARD_CORE = "Reforged Bloodshard Core (Destroyer)" WARP_PRISM_GRAVITIC_DRIVE = "Gravitic Drive (Warp Prism)" diff --git a/worlds/sc2/items.py b/worlds/sc2/items.py index 3e63ec6c3b4c..9cf13bb9e2bd 100644 --- a/worlds/sc2/items.py +++ b/worlds/sc2/items.py @@ -1578,6 +1578,9 @@ def get_full_item_list(): item_names.SCORCHER: ItemData(32 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 11, SC2Race.PROTOSS, classification=ItemClassification.progression, origin={"ext"}), + item_names.SKYLORD: + ItemData(33 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 12, SC2Race.PROTOSS, + classification=ItemClassification.progression, origin={"ext"}), # Protoss Upgrades item_names.PROGRESSIVE_PROTOSS_GROUND_WEAPON: ItemData(100 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, 0, SC2Race.PROTOSS, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, origin={"wol", "lotv"}), @@ -1631,12 +1634,10 @@ def get_full_item_list(): item_names.ARBITER_SPACETIME_ANCHOR: ItemData(330 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 0, SC2Race.PROTOSS, origin={"bw"}, parent_item=item_names.ARBITER), item_names.ARBITER_RESOURCE_EFFICIENCY: ItemData(331 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 1, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=item_names.ARBITER), item_names.ARBITER_ENHANCED_CLOAK_FIELD: ItemData(332 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 2, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=item_names.ARBITER), - item_names.CARRIER_GRAVITON_CATAPULT: - ItemData(333 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 3, SC2Race.PROTOSS, origin={"wol"}, - parent_item=item_names.CARRIER), - item_names.CARRIER_HULL_OF_PAST_GLORIES: - ItemData(334 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 4, SC2Race.PROTOSS, origin={"bw"}, - parent_item=item_names.CARRIER), + item_names.CARRIER_SKYLORD_GRAVITON_CATAPULT: + ItemData(333 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 3, SC2Race.PROTOSS, origin={"wol"}), + item_names.CARRIER_SKYLORD_HULL_OF_PAST_GLORIES: + ItemData(334 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 4, SC2Race.PROTOSS, origin={"bw"}), item_names.VOID_RAY_DESTROYER_WARP_RAY_SCORCHER_FLUX_VANES: ItemData(335 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 5, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"ext"}), diff --git a/worlds/sc2/pool_filter.py b/worlds/sc2/pool_filter.py index 4a76bf182179..5eecde28a67a 100644 --- a/worlds/sc2/pool_filter.py +++ b/worlds/sc2/pool_filter.py @@ -506,6 +506,9 @@ def attempt_removal(item: Item) -> bool: if not {item_names.VOID_RAY, item_names.DESTROYER, item_names.WARP_RAY, item_names.SCORCHER} & logical_inventory_set: inventory = [item for item in inventory if not item.name.endswith("(Void Ray/Destroyer/Warp Ray/Scorcher)")] unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Void Ray/Destroyer/Warp Ray/Scorcher)")] + if not {item_names.CARRIER, item_names.SKYLORD} & logical_inventory_set: + inventory = [item for item in inventory if not item.name.endswith("(Carrier/Skylord)")] + unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Carrier/Skylord)")] if not {item_names.IMMORTAL, item_names.ANNIHILATOR, item_names.STALWART} & logical_inventory_set: inventory = [item for item in inventory if not item.name.endswith("(Immortal/Annihilator/Stalwart)")] unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Immortal/Annihilator/Stalwart)")] diff --git a/worlds/sc2/rules.py b/worlds/sc2/rules.py index 2a22400baa0a..2ebfdcf74714 100644 --- a/worlds/sc2/rules.py +++ b/worlds/sc2/rules.py @@ -477,8 +477,10 @@ def protoss_common_unit(self, state: CollectionState) -> bool: def protoss_basic_anti_air(self, state: CollectionState) -> bool: return self.protoss_competent_anti_air(state) \ - or state.has_any({item_names.PHOENIX, item_names.MIRAGE, item_names.CORSAIR, item_names.CARRIER, item_names.SCOUT, - item_names.DARK_ARCHON, item_names.WRATHWALKER, item_names.MOTHERSHIP}, self.player) \ + or state.has_any({ + item_names.PHOENIX, item_names.MIRAGE, item_names.CORSAIR, item_names.CARRIER, item_names.SKYLORD, + item_names.SCOUT, item_names.DARK_ARCHON, item_names.WRATHWALKER, item_names.MOTHERSHIP + }, self.player) \ or state.has_all({item_names.WARP_PRISM, item_names.WARP_PRISM_PHASE_BLASTER}, self.player) \ or self.advanced_tactics and state.has_any( {item_names.HIGH_TEMPLAR, item_names.SIGNIFIER, item_names.ASCENDANT, item_names.DARK_TEMPLAR, @@ -492,14 +494,24 @@ def protoss_anti_armor_anti_air(self, state: CollectionState) -> bool: def protoss_anti_light_anti_air(self, state: CollectionState) -> bool: return self.protoss_competent_anti_air(state) \ - or state.has_any({item_names.PHOENIX, item_names.MIRAGE, item_names.CORSAIR, item_names.CARRIER}, self.player) + or state.has_any({ + item_names.PHOENIX, item_names.MIRAGE, item_names.CORSAIR, item_names.CARRIER, item_names.SKYLORD + }, self.player) def protoss_competent_anti_air(self, state: CollectionState) -> bool: - return state.has_any( - {item_names.STALKER, item_names.SLAYER, item_names.INSTIGATOR, item_names.DRAGOON, item_names.ADEPT, - item_names.VOID_RAY, item_names.DESTROYER, item_names.TEMPEST}, self.player) \ - or (state.has_any({item_names.PHOENIX, item_names.MIRAGE, item_names.CORSAIR, item_names.CARRIER}, self.player) - and state.has_any({item_names.SCOUT, item_names.WRATHWALKER}, self.player)) \ + return state.has_any({ + item_names.STALKER, item_names.SLAYER, item_names.INSTIGATOR, item_names.DRAGOON, item_names.ADEPT, + item_names.VOID_RAY, item_names.DESTROYER, item_names.TEMPEST + }, self.player) \ + or ( + state.has_any({ + item_names.PHOENIX, item_names.MIRAGE, item_names.CORSAIR, item_names.CARRIER, + item_names.SKYLORD + }, self.player) + and state.has_any({ + item_names.SCOUT, item_names.WRATHWALKER, item_names.SCORCHER, item_names.WARP_RAY + }, self.player) + ) \ or (self.advanced_tactics and state.has_any({item_names.IMMORTAL, item_names.ANNIHILATOR, item_names.STALWART}, self.player) and state.has(item_names.IMMORTAL_ANNIHILATOR_STALWART_ADVANCED_TARGETING_MECHANICS, self.player)) @@ -513,8 +525,8 @@ def protoss_has_blink(self, state: CollectionState) -> bool: def protoss_can_attack_behind_chasm(self, state: CollectionState) -> bool: return state.has_any({ - item_names.SCOUT, item_names.TEMPEST, item_names.CARRIER, item_names.VOID_RAY, item_names.DESTROYER, - item_names.WARP_RAY, item_names.SCORCHER, item_names.MOTHERSHIP + item_names.SCOUT, item_names.TEMPEST, item_names.CARRIER, item_names.SKYLORD, item_names.VOID_RAY, + item_names.DESTROYER, item_names.WARP_RAY, item_names.SCORCHER, item_names.MOTHERSHIP }, self.player) \ or self.protoss_has_blink(state) \ or (state.has(item_names.WARP_PRISM, self.player) @@ -524,8 +536,8 @@ def protoss_can_attack_behind_chasm(self, state: CollectionState) -> bool: def protoss_fleet(self, state: CollectionState) -> bool: return state.has_any({ - item_names.CARRIER, item_names.TEMPEST, item_names.VOID_RAY, item_names.DESTROYER, item_names.WARP_RAY, - item_names.SCORCHER + item_names.CARRIER, item_names.SKYLORD, item_names.TEMPEST, item_names.VOID_RAY, item_names.DESTROYER, + item_names.WARP_RAY, item_names.SCORCHER }, self.player) def templars_return_requirement(self, state: CollectionState) -> bool: @@ -566,8 +578,8 @@ def protoss_hybrid_counter(self, state: CollectionState) -> bool: Ground Hybrids """ return state.has_any( - {item_names.ANNIHILATOR, item_names.ASCENDANT, item_names.TEMPEST, item_names.CARRIER, item_names.VOID_RAY, - item_names.WRATHWALKER, item_names.VANGUARD}, self.player) \ + {item_names.ANNIHILATOR, item_names.ASCENDANT, item_names.TEMPEST, item_names.CARRIER, item_names.SKYLORD, + item_names.VOID_RAY, item_names.WARP_RAY, item_names.WRATHWALKER, item_names.VANGUARD}, self.player) \ or (state.has_any({item_names.IMMORTAL, item_names.STALWART}, self.player) or self.advanced_tactics) and state.has_any( {item_names.STALKER, item_names.DRAGOON, item_names.ADEPT, item_names.INSTIGATOR, item_names.SLAYER}, self.player) @@ -691,7 +703,7 @@ def amons_fall_requirement(self, state: CollectionState) -> bool: if self.take_over_ai_allies: return ( ( - state.has_any({item_names.BATTLECRUISER, item_names.CARRIER}, self.player) + state.has_any({item_names.BATTLECRUISER, item_names.CARRIER, item_names.SKYLORD}, self.player) ) or (state.has(item_names.ULTRALISK, self.player) and self.protoss_competent_anti_air(state)