Beispiel #1
0
    def __init__(self):
        """Set everything up."""
        self.enemy_rushes = {
            EnemyBuild.GeneralRush,
            EnemyBuild.Pool12,
            EnemyBuild.RoachRush,
            EnemyBuild.LingRush,
            EnemyBuild.CannonRush,
            EnemyBuild.EarlyMarines,
        }
        self.distribute = PlanDistributeWorkers()

        # basic build (17, 18, 17)
        base_build = SequentialList([
            Step(None, ZergUnit(UnitTypeId.DRONE, to_count=13)),
            Step(None, ZergUnit(UnitTypeId.OVERLORD, to_count=2)),
            Step(None, ZergUnit(UnitTypeId.DRONE, to_count=17)),
            Step(
                None,
                ActExpand(to_count=2,
                          priority=True,
                          consider_worker_production=False)),
            Step(None, ZergUnit(UnitTypeId.DRONE, to_count=18)),
            Step(RequiredMinerals(120), StepBuildGas(to_count=1)),
            Step(None, ActBuilding(UnitTypeId.SPAWNINGPOOL)),
            Step(None, ZergUnit(UnitTypeId.DRONE, to_count=20)),
            Step(UnitExists(UnitTypeId.SPAWNINGPOOL),
                 ZergUnit(UnitTypeId.ZERGLING, to_count=6)),
            Step(UnitExists(UnitTypeId.SPAWNINGPOOL),
                 ZergUnit(UnitTypeId.QUEEN, to_count=2)),
            Step(
                RequiredAll(
                    [UnitExists(UnitTypeId.SPAWNINGPOOL),
                     RequiredGas(100)]),
                ActTech(UpgradeId.ZERGLINGMOVEMENTSPEED),
            ),
            Step(UnitExists(UnitTypeId.SPAWNINGPOOL),
                 ZergUnit(UnitTypeId.ZERGLING, to_count=100)),
        ])

        build_together = BuildOrder([
            Step(None,
                 base_build,
                 skip=lambda k: k.ai.scout_manager.enemy_build in self.
                 enemy_rushes),
            Step(None,
                 RoachRushResponse(),
                 skip=lambda k: k.ai.scout_manager.enemy_build != EnemyBuild.
                 RoachRush),
        ])

        super().__init__(build_together, self.distribute, AutoOverLord(),
                         InjectLarva(), SpreadCreep())
Beispiel #2
0
 def __init__(self):
     """Build order steps to be combined."""
     self.done = False
     opening = SequentialList(
         [
             Step(None, ZergUnit(UnitTypeId.DRONE, to_count=13, only_once=True)),
             Step(None, ZergUnit(UnitTypeId.OVERLORD, to_count=2, only_once=True)),
             Step(None, ZergUnit(UnitTypeId.DRONE, to_count=17)),
             Step(None, ActExpand(2, priority=True, consider_worker_production=False)),
             Step(None, ZergUnit(UnitTypeId.DRONE, to_count=18, only_once=True)),
             Step(None, StepBuildGas(to_count=1)),
             Step(
                 UnitExists(
                     UnitTypeId.EXTRACTOR,
                     count=1,
                     include_pending=True,
                     include_not_ready=True,
                 ),
                 ActBuilding(UnitTypeId.SPAWNINGPOOL),
             ),
             Step(
                 UnitExists(
                     UnitTypeId.SPAWNINGPOOL,
                     count=1,
                     include_not_ready=True,
                     include_pending=True,
                 ),
                 ZergUnit(UnitTypeId.DRONE, to_count=20),
             ),
             Step(
                 UnitExists(UnitTypeId.SPAWNINGPOOL),
                 ZergUnit(UnitTypeId.ZERGLING, to_count=6),
             ),
             Step(
                 UnitExists(UnitTypeId.SPAWNINGPOOL),
                 ZergUnit(UnitTypeId.QUEEN, to_count=2),
             ),
             Step(None, ActExpand(3, priority=True, consider_worker_production=False)),
         ]
     )
     ling_speed = BuildOrder(
         [
             Step(
                 RequiredAll(
                     [UnitExists(UnitTypeId.SPAWNINGPOOL), RequiredGas(100)]
                 ),
                 ActTech(UpgradeId.ZERGLINGMOVEMENTSPEED, UnitTypeId.SPAWNINGPOOL),
             )
         ]
     )
     super().__init__([opening, ling_speed])
Beispiel #3
0
 async def create_plan(self) -> BuildOrder:
     flying_buildings = lambda k: self._bot.enemy_structures.flying.exists and self._bot.supply_used > 30
     in_case_of_air = [
         Step(flying_buildings, StepBuildGas(2)),
         ActUnit(UnitTypeId.DRONE, UnitTypeId.LARVA, 20),
         MorphLair(),
         ActUnit(UnitTypeId.DRONE, UnitTypeId.LARVA, 30),
         StepBuildGas(4),
         ActBuilding(UnitTypeId.SPIRE),
         ZergUnit(UnitTypeId.MUTALISK, 10, priority=True)
     ]
     return BuildOrder([
         SequentialList([
             ActBuilding(UnitTypeId.SPAWNINGPOOL, 1),
             ActUnit(UnitTypeId.DRONE, UnitTypeId.LARVA, 14),
             StepBuildGas(1),
             ActUnit(UnitTypeId.DRONE, UnitTypeId.LARVA, 14),
             ActUnit(UnitTypeId.OVERLORD, UnitTypeId.LARVA, 2),
             ActBuilding(UnitTypeId.ROACHWARREN, 1),
             ActUnit(UnitTypeId.DRONE, UnitTypeId.LARVA, 14),
             ActUnit(UnitTypeId.QUEEN, UnitTypeId.HATCHERY, 1),
             ActUnit(UnitTypeId.ROACH, UnitTypeId.LARVA, 100),
         ]), in_case_of_air,
         SequentialList([
             DistributeWorkers(),
             Step(None, SpeedMining(), lambda ai: ai.client.game_step > 5),
             PlanZoneDefense(),
             AutoOverLord(),
             InjectLarva(),
             PlanZoneGather(),
             Step(UnitExists(UnitTypeId.ROACH, 7), PlanZoneAttackAllIn(1)),
             PlanFinishEnemy(),
         ])
     ])
    def __init__(self):
        """Create plan for build order."""
        self.drones = ZergUnit(UnitTypeId.DRONE, to_count=0)
        self.lings = ZergUnit(UnitTypeId.ZERGLING, to_count=999)
        self.queens = ZergUnit(UnitTypeId.QUEEN, to_count=3)
        self.roaches = ZergUnit(UnitTypeId.ROACH, to_count=100, priority=True)
        self.ravagers = ZergUnit(UnitTypeId.RAVAGER, to_count=0)
        self.defense_spines = DefensiveBuilding(
            unit_type=UnitTypeId.SPINECRAWLER, position_type=DefensePosition.Entrance, to_base_index=1, to_count=3
        )
        self.gas = StepBuildGas(to_count=3)

        unit_building = BuildOrder(
            [
                Step(None, self.drones, skip_until=self.should_build_drones),
                Step(UnitExists(UnitTypeId.SPAWNINGPOOL), self.defense_spines),
                Step(
                    RequiredAll([UnitExists(UnitTypeId.ROACHWARREN), UnitExists(UnitTypeId.ROACH)]),
                    self.ravagers,
                    skip_until=self.should_build_ravagers,
                ),
                Step(UnitExists(UnitTypeId.ROACHWARREN), self.roaches),
                Step(
                    RequiredAll(
                        [
                            UnitExists(UnitTypeId.SPAWNINGPOOL),
                            UnitExists(
                                UnitTypeId.ROACHWARREN,
                                include_pending=True,
                                include_not_ready=True,
                                include_killed=True,
                            ),
                        ]
                    ),
                    self.lings,
                ),
                Step(UnitExists(UnitTypeId.SPAWNINGPOOL), self.queens),
                Step(UnitExists(UnitTypeId.SPAWNINGPOOL), self.lings),
            ]
        )

        buildings: BuildOrder = BuildOrder(
            [
                Step(None, ActBuilding(UnitTypeId.SPAWNINGPOOL, to_count=1)),
                Step(UnitExists(UnitTypeId.SPAWNINGPOOL), ActBuilding(UnitTypeId.ROACHWARREN, to_count=1)),
                Step(None, self.gas, skip_until=self.should_build_gas),
            ]
        )

        super().__init__(buildings, unit_building)
Beispiel #5
0
 def __init__(self):
     """Create the build order."""
     opener = SequentialList(
         Step(
             RequiredUnitReady(UnitTypeId.SPAWNINGPOOL),
             NatSpines(4),
             skip=RequiredUnitReady(UnitTypeId.SPINECRAWLER, count=4),
             skip_until=lambda k: k.build_detector.rush_detected,
         ), Step(None, ZergUnit(UnitTypeId.DRONE, to_count=13)),
         Step(None, ZergUnit(UnitTypeId.OVERLORD, to_count=2)),
         Step(None, ZergUnit(UnitTypeId.DRONE, to_count=17)),
         Step(None,
              ActExpand(2, priority=True,
                        consider_worker_production=False)),
         Step(
             UnitExists(UnitTypeId.HATCHERY,
                        count=2,
                        include_pending=True,
                        include_not_ready=True),
             ZergUnit(UnitTypeId.DRONE, to_count=18),
         ), Step(None, ActBuilding(UnitTypeId.SPAWNINGPOOL)),
         Step(None, ZergUnit(UnitTypeId.DRONE, to_count=20)),
         StepBuildGas(1),
         Step(RequiredUnitReady(UnitTypeId.SPAWNINGPOOL),
              ZergUnit(UnitTypeId.QUEEN, 2)),
         Step(RequiredUnitReady(UnitTypeId.SPAWNINGPOOL),
              ZergUnit(UnitTypeId.ZERGLING, 6)),
         Step(None, ZergUnit(UnitTypeId.OVERLORD, to_count=3)),
         BuildOrder([
             Step(RequiredGas(100), MorphLair()),
             Step(
                 None,
                 ZergUnit(UnitTypeId.DRONE),
                 skip=UnitExists(UnitTypeId.LAIR,
                                 include_pending=True,
                                 include_not_ready=True),
             ),
         ])
         # end of build hard order, switch to reactive play
     )
     super().__init__([opener, AutoOverLord()])
 async def create_plan(self) -> BuildOrder:
     finish_rush = Any([Gas(150), UnitExists(UnitTypeId.PLANETARYFORTRESS)])
     return BuildOrder([
         SequentialList([
             BuildPosition(UnitTypeId.COMMANDCENTER,
                           self._bot.knowledge.zone_manager.enemy_natural.
                           center_location,
                           exact=True,
                           only_once=True),
             StepBuildGas(2),
             ActBuilding(UnitTypeId.ENGINEERINGBAY),
             ActUnit(UnitTypeId.SCV, UnitTypeId.COMMANDCENTER, 17),
             MorphProxyPlanetary(),
             GridBuilding(UnitTypeId.SUPPLYDEPOT, 1),
             BuildOrder([
                 ActUnit(UnitTypeId.SCV, UnitTypeId.COMMANDCENTER, 38),
                 ActUnit(UnitTypeId.SCV, UnitTypeId.PLANETARYFORTRESS, 38),
                 GridBuilding(UnitTypeId.BARRACKS, 4),
                 BuildAddon(UnitTypeId.BARRACKSTECHLAB, UnitTypeId.BARRACKS,
                            2),
                 BuildAddon(UnitTypeId.BARRACKSREACTOR, UnitTypeId.BARRACKS,
                            2),
                 Tech(UpgradeId.STIMPACK, UnitTypeId.BARRACKSTECHLAB),
                 Tech(UpgradeId.TERRANINFANTRYWEAPONSLEVEL1,
                      UnitTypeId.ENGINEERINGBAY),
                 AutoDepot(),
                 ActUnit(UnitTypeId.MARAUDER, UnitTypeId.BARRACKS, 50),
                 ActUnit(UnitTypeId.MARINE, UnitTypeId.BARRACKS, 100),
                 GridBuilding(UnitTypeId.BARRACKS, 6),
                 BuildAddon(UnitTypeId.BARRACKSREACTOR, UnitTypeId.BARRACKS,
                            4),
             ]),
         ]),
         SequentialList([
             Step(None, DistributeWorkers(min_gas=6), skip=finish_rush),
             Step(finish_rush, DistributeWorkers(max_gas=4)),
         ]),
         SequentialList([
             Step(None, SpeedMining(), lambda ai: ai.client.game_step > 5),
             PlanCancelBuilding(),
             LowerDepots(),
             PlanZoneDefense(),
             ManTheBunkers(),
             Repair(),
             ContinueBuilding(),
             PlanZoneGatherTerran(),
             Step(TechReady(UpgradeId.TERRANINFANTRYWEAPONSLEVEL1),
                  PlanZoneAttack(20)),
             PlanFinishEnemy(),
         ])
     ])
Beispiel #7
0
 def __init__(self):
     """Research basic unit upgrades with Overlord Speed and Burrow."""
     upgrades = BuildOrder([
         # ranged upgrades
         SequentialList(
             Step(
                 RequiredUnitReady(UnitTypeId.EVOLUTIONCHAMBER),
                 ActTech(UpgradeId.ZERGMISSILEWEAPONSLEVEL1,
                         UnitTypeId.EVOLUTIONCHAMBER),
             ),
             Step(
                 RequiredAll([
                     RequiredUnitReady(UnitTypeId.EVOLUTIONCHAMBER),
                     RequiredTechReady(UpgradeId.ZERGMISSILEWEAPONSLEVEL1),
                     UnitExists(UnitTypeId.LAIR),
                 ]),
                 ActTech(UpgradeId.ZERGMISSILEWEAPONSLEVEL2,
                         UnitTypeId.EVOLUTIONCHAMBER),
             ),
             Step(
                 RequiredAll([
                     RequiredUnitReady(UnitTypeId.EVOLUTIONCHAMBER),
                     RequiredTechReady(UpgradeId.ZERGMISSILEWEAPONSLEVEL2),
                     UnitExists(UnitTypeId.HIVE),
                 ]),
                 ActTech(UpgradeId.ZERGMISSILEWEAPONSLEVEL3,
                         UnitTypeId.EVOLUTIONCHAMBER),
             ),
         ),
         # ground carapace upgrades
         SequentialList(
             Step(
                 RequiredUnitReady(UnitTypeId.EVOLUTIONCHAMBER),
                 ActTech(UpgradeId.ZERGGROUNDARMORSLEVEL1,
                         UnitTypeId.EVOLUTIONCHAMBER),
             ),
             Step(
                 RequiredAll([
                     RequiredUnitReady(UnitTypeId.EVOLUTIONCHAMBER),
                     RequiredTechReady(UpgradeId.ZERGGROUNDARMORSLEVEL1),
                     UnitExists(UnitTypeId.LAIR),
                 ]),
                 ActTech(UpgradeId.ZERGGROUNDARMORSLEVEL2,
                         UnitTypeId.EVOLUTIONCHAMBER),
             ),
             Step(
                 RequiredAll([
                     RequiredUnitReady(UnitTypeId.EVOLUTIONCHAMBER),
                     RequiredTechReady(UpgradeId.ZERGGROUNDARMORSLEVEL2),
                     UnitExists(UnitTypeId.HIVE),
                 ]),
                 ActTech(UpgradeId.ZERGGROUNDARMORSLEVEL3,
                         UnitTypeId.EVOLUTIONCHAMBER),
             ),
         ),
         # melee upgrades
         SequentialList(
             Step(
                 RequiredUnitReady(UnitTypeId.EVOLUTIONCHAMBER),
                 ActTech(UpgradeId.ZERGMELEEWEAPONSLEVEL1,
                         UnitTypeId.EVOLUTIONCHAMBER),
             ),
             Step(
                 RequiredAll([
                     RequiredUnitReady(UnitTypeId.EVOLUTIONCHAMBER),
                     RequiredTechReady(UpgradeId.ZERGMELEEWEAPONSLEVEL1),
                     UnitExists(UnitTypeId.LAIR),
                 ]),
                 ActTech(UpgradeId.ZERGMELEEWEAPONSLEVEL2,
                         UnitTypeId.EVOLUTIONCHAMBER),
             ),
             Step(
                 RequiredAll([
                     RequiredUnitReady(UnitTypeId.EVOLUTIONCHAMBER),
                     RequiredTechReady(UpgradeId.ZERGMELEEWEAPONSLEVEL2),
                     UnitExists(UnitTypeId.HIVE),
                 ]),
                 ActTech(UpgradeId.ZERGMELEEWEAPONSLEVEL3,
                         UnitTypeId.EVOLUTIONCHAMBER),
             ),
         ),
         # overlord speed then burrow
         SequentialList(
             Step(UnitExists(UnitTypeId.QUEEN, 2),
                  ActTech(UpgradeId.OVERLORDSPEED, UnitTypeId.HATCHERY)),
             Step(UnitExists(UnitTypeId.LAIR),
                  ActTech(UpgradeId.BURROW, UnitTypeId.LAIR)),
         ),
         Step(
             RequiredAll([
                 UnitExists(UnitTypeId.INFESTATIONPIT),
                 RequiredUnitReady(UnitTypeId.LAIR),
                 RequiredTechReady(UpgradeId.ZERGMISSILEWEAPONSLEVEL2),
             ]),
             MorphHive(),
         ),
     ])
     super().__init__([upgrades])
Beispiel #8
0
    def __init__(self):
        """Create the build order."""
        self.drone = ZergUnit(UnitTypeId.DRONE, to_count=0)
        self.queen = ZergUnit(UnitTypeId.QUEEN, to_count=3, priority=True)
        self.zergling = ZergUnit(UnitTypeId.ZERGLING, to_count=0)
        self.roach = ZergUnit(UnitTypeId.ROACH, to_count=0)
        self.ravager = MorphRavager(target_count=0)
        self.swarmhost = ZergUnit(UnitTypeId.SWARMHOSTMP, to_count=0)
        ling_scout = BuildOrder([Step(RequiredTime(4 * 60), LingScout(2, ScoutLocation.scout_enemy3()))])
        run_by = Step(
            RequiredTime(4 * 60), RunBy(UnitTypeId.ZERGLING, 8, 1)
        )
        units = BuildOrder(
            [
                Step(None, self.drone),
                Step(UnitExists(UnitTypeId.SPAWNINGPOOL), self.queen),
                Step(UnitExists(UnitTypeId.INFESTATIONPIT), self.swarmhost),
                Step(UnitExists(UnitTypeId.ROACHWARREN), self.roach),
                Step(UnitExists(UnitTypeId.ROACH), self.ravager),
                Step(UnitExists(UnitTypeId.SPAWNINGPOOL), self.zergling),
            ]
        )
        self.gas = StepBuildGas(to_count=0)
        tech_buildings = BuildOrder(
            Step(
                UnitExists(UnitTypeId.DRONE, 30),
                BuildOrder(
                    [
                        Step(None, ActBuilding(UnitTypeId.ROACHWARREN)),
                        Step(None, MorphLair()),
                        Step(
                            RequiredAll(
                                [
                                    UnitExists(UnitTypeId.LAIR),
                                    UnitExists(UnitTypeId.EVOLUTIONCHAMBER),
                                    UnitExists(UnitTypeId.HATCHERY, 3),
                                ]
                            ),
                            ActBuilding(UnitTypeId.INFESTATIONPIT),
                        ),
                        Step(None, ActBuilding(UnitTypeId.EVOLUTIONCHAMBER)),
                        Step(UnitExists(UnitTypeId.HATCHERY, 4), ActBuilding(UnitTypeId.EVOLUTIONCHAMBER, 2)),
                    ]
                ),
            )
        )
        bases = BuildOrder(
            [
                Step(None, ActExpand(to_count=3, priority=True, consider_worker_production=False)),
                Step(UnitExists(UnitTypeId.DRONE, 60), ActExpand(4, priority=True, consider_worker_production=False)),
            ]
        )

        nat_spines = Step(
            UnitExists(UnitTypeId.SPAWNINGPOOL),
            NatSpines(4),
            skip=UnitExists(UnitTypeId.SPINECRAWLER, count=4),
            skip_until=lambda k: k.build_detector.rush_detected,
        )
        super().__init__(
            [
                nat_spines,
                units,
                tech_buildings,
                self.gas,
                bases,
                MassExpand(),
                AutoOverLord(),
                StandardUpgrades(),
                # ling_scout,
                run_by,
            ]
        )
Beispiel #9
0
    def __init__(self):
        self.drone = ZergUnit(UnitTypeId.DRONE)
        self.queen = ZergUnit(UnitTypeId.QUEEN, to_count=3)
        self.zergling = ZergUnit(UnitTypeId.ZERGLING)
        self.baneling = ZergUnit(UnitTypeId.BANELING)
        self.ultra = ZergUnit(UnitTypeId.ULTRALISK, to_count=15)
        self.corruptor = ZergUnit(UnitTypeId.CORRUPTOR, to_count=40)
        self.mutalisk = ZergUnit(UnitTypeId.MUTALISK)
        self.overseer = ZergUnit(UnitTypeId.OVERSEER, to_count=3)

        build_units = BuildOrder(
            [
                Step(None, self.drone),
                Step(UnitExists(UnitTypeId.SPAWNINGPOOL), self.queen),
                Step(UnitExists(UnitTypeId.ULTRALISKCAVERN), self.ultra, skip_until=self.should_build_ultras),
                Step(UnitExists(UnitTypeId.SPIRE), self.corruptor, skip_until=self.should_build_air),
                Step(UnitExists(UnitTypeId.SPIRE), self.mutalisk, skip_until=self.should_build_air),
                Step(UnitExists(UnitTypeId.BANELINGNEST), self.baneling),
                Step(UnitExists(UnitTypeId.SPAWNINGPOOL), self.zergling),
                Step(
                    UnitExists(UnitTypeId.LAIR),
                    self.overseer,
                    skip_until=lambda k: k.enemy_units_manager.enemy_cloak_trigger,
                ),
            ]
        )

        tech_buildings = BuildOrder(
            Step(None, Expand(3, priority=True, consider_worker_production=False), skip_until=self.take_third),
            Step(None, StepBuildGas(to_count=2)),
            Step(UnitExists(UnitTypeId.LAIR), StepBuildGas(4)),
            Step(None, ActBuilding(UnitTypeId.SPAWNINGPOOL)),
            Step(UnitExists(UnitTypeId.SPAWNINGPOOL), ActBuilding(UnitTypeId.BANELINGNEST)),
            Step(UnitExists(UnitTypeId.BANELINGNEST), MorphLair()),
            Step(
                All([UnitExists(UnitTypeId.DRONE, 60), UnitExists(UnitTypeId.LAIR)]),
                ActBuilding(UnitTypeId.INFESTATIONPIT),
            ),
            Step(UnitExists(UnitTypeId.INFESTATIONPIT), StepBuildGas(6)),
            Step(UnitExists(UnitTypeId.LAIR), ActBuilding(UnitTypeId.EVOLUTIONCHAMBER, to_count=2)),
            Step(All([UnitExists(UnitTypeId.LAIR), UnitExists(UnitTypeId.INFESTATIONPIT)]), MorphHive()),
            Step(UnitExists(UnitTypeId.HIVE), ActBuilding(UnitTypeId.ULTRALISKCAVERN)),
            Step(UnitExists(UnitTypeId.LAIR), ActBuilding(UnitTypeId.SPIRE), skip_until=self.should_build_air),
            Step(UnitExists(UnitTypeId.HIVE), StepBuildGas(8))
        )

        upgrades = BuildOrder(
            Step(
                All([UnitExists(UnitTypeId.BANELINGNEST), UnitExists(UnitTypeId.LAIR)]),
                Tech(UpgradeId.CENTRIFICALHOOKS),
            ),
            SequentialList(
                Step(None, Tech(UpgradeId.ZERGMELEEWEAPONSLEVEL1)),
                Step(UnitExists(UnitTypeId.LAIR), Tech(UpgradeId.ZERGMELEEWEAPONSLEVEL2)),
                Step(UnitExists(UnitTypeId.HIVE), Tech(UpgradeId.ZERGMELEEWEAPONSLEVEL3)),
            ),
            SequentialList(
                Step(
                    UnitExists(UnitTypeId.EVOLUTIONCHAMBER, 2, include_not_ready=False, include_pending=False),
                    Tech(UpgradeId.ZERGGROUNDARMORSLEVEL1),
                ),
                Step(UnitExists(UnitTypeId.LAIR), Tech(UpgradeId.ZERGGROUNDARMORSLEVEL2)),
                Step(UnitExists(UnitTypeId.HIVE), Tech(UpgradeId.ZERGGROUNDARMORSLEVEL3)),
            ),
            Step(UnitExists(UnitTypeId.SPAWNINGPOOL), Tech(UpgradeId.ZERGLINGMOVEMENTSPEED)),
            Step(
                All([UnitExists(UnitTypeId.SPAWNINGPOOL), UnitExists(UnitTypeId.HIVE)]),
                Tech(UpgradeId.ZERGLINGATTACKSPEED),
            ),
            SequentialList(
                Step(UnitExists(UnitTypeId.ULTRALISKCAVERN), Tech(UpgradeId.CHITINOUSPLATING)),
                Step(UnitExists(UnitTypeId.ULTRALISKCAVERN), Tech(UpgradeId.ANABOLICSYNTHESIS)),
            ),
            SequentialList(
                Step(UnitExists(UnitTypeId.SPIRE), Tech(UpgradeId.ZERGFLYERWEAPONSLEVEL1)),
                Step(UnitExists(UnitTypeId.SPIRE), Tech(UpgradeId.ZERGFLYERWEAPONSLEVEL2)),
                Step(
                    All(
                        [
                            UnitExists(UnitTypeId.SPIRE),
                            UnitExists(UnitTypeId.HIVE),
                        ]
                    ),
                    Tech(UpgradeId.ZERGFLYERWEAPONSLEVEL3),
                ),
                Step(UnitExists(UnitTypeId.SPIRE), Tech(UpgradeId.ZERGFLYERARMORSLEVEL1)),
                Step(UnitExists(UnitTypeId.SPIRE), Tech(UpgradeId.ZERGFLYERARMORSLEVEL2)),
                Step(
                    All(
                        [
                            UnitExists(UnitTypeId.SPIRE),
                            UnitExists(UnitTypeId.HIVE),
                        ]
                    ),
                    Tech(UpgradeId.ZERGFLYERARMORSLEVEL3),
                ),
            ),
            Step(TechReady(UpgradeId.CENTRIFICALHOOKS), Tech(UpgradeId.OVERLORDSPEED)),
        )

        super().__init__([PaulAutoOverLord(), upgrades, tech_buildings, build_units, MassExpand()])