def __init__(self, orders: List[Union[ActBase, List[ActBase]]]): """ Build order package that replaces normal build order for Zerg with one that builds mutalisks to destroy terran flying buildings. Add any PlanDistributeWorkers acts with orders """ cover_list = SequentialList([ PlanDistributeWorkers(), AutoOverLord(), Step(None, ZergUnit(UnitTypeId.DRONE, 20), skip=Supply(198)), StepBuildGas(4, None), MorphLair(), ActBuilding(UnitTypeId.SPIRE, 1), Step( None, DefensiveBuilding(UnitTypeId.SPORECRAWLER, DefensePosition.BehindMineralLineCenter), skip_until=Supply(199), ), Step( None, DefensiveBuilding(UnitTypeId.SPINECRAWLER, DefensePosition.Entrance), skip_until=Supply(199), ), ZergUnit(UnitTypeId.MUTALISK, 10), ]) new_build_order = [ Step(None, cover_list, skip_until=self.should_build_mutalisks), Step(None, BuildOrder(orders), skip=self.should_build_mutalisks), ] super().__init__(new_build_order)
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)
def __init__(self): """Build order steps to be combined.""" opening = SequentialList( Step(None, ActBuilding(UnitTypeId.SPAWNINGPOOL)), Step(None, ZergUnit(UnitTypeId.DRONE, to_count=14)), Step(RequiredSupply(14), ZergUnit(UnitTypeId.OVERLORD, to_count=2, only_once=True)), Step(RequiredUnitReady(UnitTypeId.SPAWNINGPOOL, 1), ZergUnit(UnitTypeId.ZERGLING, 6, only_once=True)), ZergExpand(2), Step(RequiredUnitReady(UnitTypeId.SPAWNINGPOOL), ZergUnit(UnitTypeId.ZERGLING, to_count=12, only_once=True)), ) super().__init__([opening])
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(), ]) ])
async def start(self, knowledge: "Knowledge"): await super().start(knowledge) if self.type_id in {UnitTypeId.PROBE, UnitTypeId.SCV}: self.act = Workers(self.to_count) elif self.type_id in ALL_GAS: self.act = BuildGas(self.to_count) elif self.type_id in buildings_5x5: self.act = Expand(self.to_count, priority=self.priority, consider_worker_production=False) elif self.type_id in BUILDING_IDS: self.act = GridBuilding(self.type_id, self.to_count, priority=self.priority, consider_worker_production=False) else: if self.ai.race == Race.Protoss: self.act = ProtossUnit(self.type_id, self.to_count, priority=self.priority, only_once=True) elif self.ai.race == Race.Terran: self.act = TerranUnit(self.type_id, self.to_count, priority=self.priority, only_once=True) else: self.act = ZergUnit(self.type_id, self.to_count, priority=self.priority, only_once=True) await self.act.start(knowledge)
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) ] limit_gas = Any( [Gas(100), TechReady(UpgradeId.ZERGLINGMOVEMENTSPEED, 0.001)]) return BuildOrder([ SequentialList([ ActUnit(UnitTypeId.DRONE, UnitTypeId.LARVA, 14), Expand(2), StepBuildGas(1), ActBuilding(UnitTypeId.SPAWNINGPOOL, 1), ActUnit(UnitTypeId.OVERLORD, UnitTypeId.LARVA, 2), Step(None, Tech(UpgradeId.ZERGLINGMOVEMENTSPEED, UnitTypeId.SPAWNINGPOOL), skip_until=Gas(100)), ActUnit(UnitTypeId.QUEEN, UnitTypeId.HATCHERY, 1), ActUnit(UnitTypeId.ZERGLING, UnitTypeId.LARVA, 30), ActBuilding(UnitTypeId.BANELINGNEST, 1), BuildOrder([ Step(None, ActUnit(UnitTypeId.ZERGLING, UnitTypeId.LARVA, 200), skip=RequireCustom(lambda k: self._bot.vespene > 25 or flying_buildings)), Step(None, ActUnit(UnitTypeId.BANELING, UnitTypeId.ZERGLING, 200), skip=RequireCustom(flying_buildings)), ]) ]), SequentialList([ Step(None, DistributeWorkers(), skip=limit_gas), Step(limit_gas, DistributeWorkers(1, 1), skip=RequireCustom(flying_buildings)), Step(RequireCustom(flying_buildings), DistributeWorkers()), ]), in_case_of_air, SequentialList([ Step(None, SpeedMining(), lambda ai: ai.client.game_step > 5), PlanZoneDefense(), AutoOverLord(), InjectLarva(), PlanZoneGather(), Step(TechReady(UpgradeId.ZERGLINGMOVEMENTSPEED), PlanZoneAttackAllIn(10)), PlanFinishEnemy(), ]) ])
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())
def __init__(self, unit_type: UnitTypeId, amount: int): super().__init__() self.micro = MicroRules() self.micro.load_default_methods() self.micro.unit_micros[UnitTypeId.ZERGLING] = SuicideLingMicro() self.started = False self.ended = False self.unit_type = unit_type self.amount = amount self.lair_tech = MorphLair() self.network = ActBuilding(UnitTypeId.NYDUSNETWORK, to_count=1) self.zerg_build = ZergUnit(unit_type) self.tags: List[int] = []
def __init__(self): """Build order steps to be combined.""" 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)), Step(None, ZergUnit(UnitTypeId.DRONE, to_count=18, only_once=True)), Step(None, StepBuildGas(to_count=1)), Step( RequiredUnitExists( UnitTypeId.EXTRACTOR, count=1, include_pending=True, include_not_ready=True, ), ActBuilding(UnitTypeId.SPAWNINGPOOL), ), Step( RequiredUnitExists( UnitTypeId.SPAWNINGPOOL, count=1, include_not_ready=True, include_pending=True, ), ZergUnit(UnitTypeId.DRONE, to_count=21), ), Step( RequiredUnitExists(UnitTypeId.SPAWNINGPOOL), ZergUnit(UnitTypeId.ZERGLING, to_count=6), ), Step( RequiredUnitExists(UnitTypeId.SPAWNINGPOOL), ZergUnit(UnitTypeId.QUEEN, to_count=2), ), Step(None, ActExpand(3)), ]) ling_speed = BuildOrder([ Step( RequiredAll([ RequiredUnitExists(UnitTypeId.SPAWNINGPOOL), RequiredGas(100) ]), ActTech(UpgradeId.ZERGLINGMOVEMENTSPEED, UnitTypeId.SPAWNINGPOOL), ) ]) super().__init__([opening, ling_speed])
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()])
def __init__(self, amount: int): super().__init__() # custom micro to make sure lings just attack self.micro = MicroRules() self.micro.load_default_methods() self.micro.generic_micro = NoMicro() self.started = False self.ended = False self.amount = amount self.lair_tech = MorphLair() self.network = ActBuilding(UnitTypeId.NYDUSNETWORK, to_count=1) self.zerg_build = ZergUnit(UnitTypeId.ZERGLING) self.nydus_spot: Point2 = Point2((0, 0))
def __init__(self): """Build order steps to be combined.""" extractor_trick = SequentialList([ Step( RequiredSupply(14), StepBuildGas(1), skip=RequiredUnitExists(UnitTypeId.EXTRACTOR, include_killed=True, include_pending=True), ), Step( RequiredUnitExists( UnitTypeId.EXTRACTOR, 1, include_pending=True, include_not_ready=True, ), ZergUnit(UnitTypeId.DRONE, to_count=14), ), # SequentialList will take care of making sure the drone was made Step( RequiredUnitExists(UnitTypeId.EXTRACTOR), CancelBuilding(UnitTypeId.EXTRACTOR, to_count=0), skip=RequiredUnitExists( UnitTypeId.EXTRACTOR, 1, include_killed=True, include_not_ready=False, ), ), ]) opening = SequentialList([ Step(None, ZergUnit(UnitTypeId.DRONE, to_count=14)), Step( RequiredSupply(14), extractor_trick, skip=RequiredUnitExists( UnitTypeId.EXTRACTOR, 1, include_killed=True, include_not_ready=False, ), ), ActExpand(2, priority=True, consider_worker_production=False), Step( RequiredAll([RequiredSupply(14), RequiredMinerals(130)]), StepBuildGas(1), ), Step(None, ZergUnit(UnitTypeId.DRONE, to_count=14)), Step(RequiredSupply(14), ActBuilding(UnitTypeId.SPAWNINGPOOL)), Step( RequiredAll([ RequiredUnitExists(UnitTypeId.HATCHERY), RequiredUnitExists(UnitTypeId.SPAWNINGPOOL) ]), ZergUnit(UnitTypeId.QUEEN, 2), ), # spam lings Step(RequiredUnitExists(UnitTypeId.SPAWNINGPOOL), ZergUnit(UnitTypeId.ZERGLING, 999)), ]) ling_speed = BuildOrder([ Step( RequiredAll([ RequiredUnitExists(UnitTypeId.SPAWNINGPOOL), RequiredGas(100) ]), ActTech(UpgradeId.ZERGLINGMOVEMENTSPEED, UnitTypeId.SPAWNINGPOOL), ) ]) worker_distribution = SequentialList([ Step( RequiredSupply(15), PlanDistributeWorkers(), skip=RequiredUnitExists( UnitTypeId.HATCHERY, 2, include_killed=True, ), ), Step( RequiredUnitExists(UnitTypeId.EXTRACTOR), PlanDistributeWorkers(min_gas=3), skip=RequiredAny([ RequiredTechReady(UpgradeId.ZERGLINGMOVEMENTSPEED, percentage=0.01), RequiredGas(96) ]), ), Step( RequiredAny([ RequiredTechReady(UpgradeId.ZERGLINGMOVEMENTSPEED, percentage=0.01), RequiredGas(96) ]), PlanDistributeWorkers(max_gas=0), ), ]) overlords = BuildOrder([ Step( None, AutoOverLord(), skip_until=RequiredUnitExists(UnitTypeId.SPAWNINGPOOL), ) ]) super().__init__([opening, ling_speed, worker_distribution, overlords])
def __init__(self, *args: ScoutBaseAction): self.zerg_build = ZergUnit(UnitTypeId.OVERLORD) super().__init__(UnitTypeId.OVERLORD, 1, *args)
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, ] )
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()])