Example #1
0
    async def on_unit_created(self, unit: Unit) -> None:
        """
        Add unit to dictionaries and determine what should happen to each spawned unit.

        Note: This function is called automatically.

        Args:
            unit (Unit): the unit created

        Returns:
            None
        """
        self.unit_dict[unit.tag] = unit.type_id

        # drone protocol (prioritize gas -> minerals)
        if unit.type_id in {UnitTypeId.DRONE}:
            for extractor in self.gas_buildings:
                if extractor.assigned_harvesters < 3:
                    self.do(unit.gather(extractor))
                    return
            for base in self.townhalls:
                if base.assigned_harvesters < 16:
                    self.do(
                        unit.gather(
                            self.mineral_field.closest_to(base.position)))
                    return

        # queen protocol (inject > creep > unassigned)
        if unit.type_id in {UnitTypeId.QUEEN}:
            if len(self.inject_queens) < min(len(self.townhalls), 3):
                self.inject_queens.add(unit.tag)
                return
            elif len(self.creep_queens) < 4:
                self.creep_queens.add(unit.tag)
                return
Example #2
0
    def go_mine(self, unit: Unit):
        self.knowledge.roles.clear_task(unit)

        if len(self.mineral_fields) > 0:
            # Go to mine in this zone
            mf = self.mineral_fields[0]
            self.ai.do(unit.gather(mf))
        elif self.ai.townhalls.exists and self.ai.mineral_field.exists:
            closest_base = self.ai.townhalls.closest_to(self.center_location)
            # Go to mine in some other base
            mf = self.ai.mineral_field.closest_to(closest_base)
            self.ai.do(unit.gather(mf))
Example #3
0
    def assign_to_work(self, worker: Unit, work: Unit):
        if worker.has_buff(BuffId.ORACLESTASISTRAPTARGET):
            return  # Worker is in stasis and cannot move

        self.roles.set_task(UnitTask.Gathering, worker)
        townhalls = self.ai.townhalls.ready

        if worker.is_carrying_resource and townhalls:
            closest = townhalls.closest_to(worker)
            self.do(worker(AbilityId.SMART, closest))
            self.do(worker.gather(work, queue=True))
        else:
            self.do(worker.gather(work))
Example #4
0
    def assign_probe(self, bot: sc2.BotAI, unit: Unit, prio_gas: bool):
        """
        Assigns the unit (PROBE) to either the closes gas or mineral patch depending
        on prio_gas
        """
        if prio_gas:
            if not self.assign_closest_gas(
                    bot, unit) and not self.assign_closest_mineral(bot, unit):
                closest_mineral = bot.mineral_field.closest_to(unit)
                bot.do(unit.gather(closest_mineral))

        else:
            if not self.assign_closest_mineral(
                    bot, unit) and not self.assign_closest_gas(bot, unit):
                closest_mineral = bot.mineral_field.closest_to(unit)
                bot.do(unit.gather(closest_mineral))
Example #5
0
    def assign_closest_gas(self, bot: sc2.BotAI, unit: Unit):
        gas_buildings = bot.gas_buildings.ready.sorted_by_distance_to(
            unit.position)

        for mining_place in gas_buildings:
            if mining_place.has_vespene and mining_place.surplus_harvesters < 0:
                bot.do(unit.gather(mining_place))
                return True
        return False
Example #6
0
 def assign_closest_mineral(self, bot: sc2.BotAI, unit: Unit) -> bool:
     """
     Assigns unit to the closest mineral field that is not utilized
     """
     bases = bot.townhalls.ready.sorted_by_distance_to(unit.position)
     for mining_place in bases:
         if mining_place.surplus_harvesters < 0:
             local_minerals = {
                 mineral for mineral \
                     in bot.mineral_field if mineral.distance_to(mining_place) <= 8
             }
             target_mineral = max(
                 local_minerals,
                 key=lambda mineral: mineral.mineral_contents,
                 default=None)
             bot.do(unit.gather(target_mineral))
             return True
     return False
Example #7
0
    async def build_gas(self, worker: Unit):
        if self.best_gas is not None and self.knowledge.can_afford(
                self.unit_type):
            target = self.best_gas

            if not self.set_worker(worker):
                return False

            self.builder_tag = worker.tag

            cmd = worker.build_gas(target, queue=self.has_build_order(worker))
            self.do(cmd)

            if self.ai.race == Race.Protoss:
                # Protoss only do something else after starting gas
                mf = self.ai.mineral_field.closest_to(worker)
                self.ai.do(worker.gather(mf, queue=True))

            self.print(f"Building {self.unit_type.name} to {target.position}")
        return False