Example #1
0
 def can_use(self, target=None, **kwargs):
     if not super(RepairAbility, self).can_use(target, **kwargs):
         return False
     
     if vectors.distance(self.actor.pos, target.pos) > self.max_range:
         return False
     
     if self.min_range > 0:
         if vectors.distance(self.actor.pos, target.pos) < self.min_range:
             return False
     
     if self.actor.team != target.team:
         return False
     
     # Is the ally still under construction?
     if target.completion < 100:
         return False
     
     # Is the ally hurt?
     if target.hp >= target.max_hp:
         return False
     
     # Finally, can we afford it?
     cost = teams.multiply_cost(target._part_repair_cost, self.repair_rate)
     if not self.actor.team_obj.can_afford(cost):
         return False
     
     return True
Example #2
0
 def explode(self, actors):
     for a in actors:
         if vectors.distance(self.pos, a.pos) <= self.blast_radius:
             actor_lib.apply_damage(a, dissipate(
                 self.damage, vectors.distance(self.pos, a.pos),
                 self.blast_radius, self.dissipation_func)
             )
     return self.generate_effect()
Example #3
0
 def __init__(self, actor, ability_data={}):
     super(Ability, self).__init__()
     self.actor = actor
     self.facing = [0,0]
     
     self.set_stats(ability_data)
     self.charge = self.required_charge
     
     self._effect_offset_distance = vectors.distance(self.effect_offset)
     self._effect_offset_angle = vectors.angle(self.effect_offset)
     
     self._img_offset_distance = vectors.distance(self.image_offset)
     self._img_offset_angle = vectors.angle(self.image_offset)
Example #4
0
 def can_use(self, target=None, **kwargs):
     if not super(WeaponAbility, self).can_use(target, **kwargs):
         return False
     
     if vectors.distance(self.actor.pos, target.pos) > self.max_range:
         return False
     
     if self.min_range > 0:
         if vectors.distance(self.actor.pos, target.pos) < self.min_range:
             return False
     
     if self.actor.team == target.team:
         return False
     
     return True
Example #5
0
 def generate_bullet(self, target):
     # Set correct origin
     offset_angle = vectors.bound_angle(
         vectors.add_vectors(self._effect_offset_angle, self.facing)
     )
     
     origin_pos = vectors.add_vectors(self.get_offset_pos(use_effect_offset=True), self.actor.pos)
     
     # Get actual velocity we'll be using
     if type(target) == list or type(target) == tuple:
         direction = vectors.angle(origin_pos, target)
         target_pos = target
     else:
         direction = vectors.angle(origin_pos, target.pos)
         target_pos = target.pos
     
     velocity = vectors.move_to_vector(direction, self.bullet['velocity'])
     velocity[2] = math_lib.calc_trajectory(0.1, vectors.distance(origin_pos, target_pos), self.bullet['velocity'])
     
     the_bullet = bullets.Shell(
         pos=origin_pos,
         velocity=velocity,
         image = self.bullet['image'],
         size = self.bullet['size'],
         blast_radius = self.bullet['blast_radius'],
         damage = self.bullet['damage'],
         dissipation_func = self.bullet.get('dissipation_func', "linear"),
     )
     self.actor.bullets.append(the_bullet)
Example #6
0
 def update_actor(self, the_actor):
     the_actor.enemy_targets = []
     
     for a in self.enemy_actors:
         dist = vectors.distance(a.pos, the_actor.pos)
         
         if dist <= the_actor.max_attack_range:
             the_actor.enemy_targets.append(a)
Example #7
0
    def _accelerate_ai(self, target):
        dist = vectors.distance(self.pos, target)

        if dist > self.max_velocity:
            self.velocity = vectors.move_to_vector(self.pos.angle(target),
                                                   self.max_velocity)
        else:
            self.velocity = vectors.move_to_vector(self.pos.angle(target),
                                                   dist)
Example #8
0
 def test_distance(self):
     vals = (
         # 3D
         ([0,0,0], 0),
         ([1,1,1], 1.73),
         ([3,4,0], 5),
         ([3,0,4], 5),
     )
     
     for the_point, expected in vals:
         self.assertAlmostEqual(vectors.distance(the_point), expected, places=2)
Example #9
0
    def inspect_bases(self):
        # First find out which buildings we are missing
        for base_name, base_data in self.bases.items():
            base_area = (
                base_data['location'][0] - base_data['size'][0],
                base_data['location'][1] - base_data['size'][1],
                base_data['location'][0] + base_data['size'][0],
                base_data['location'][1] + base_data['size'][1],
            )

            buildings_needed = set(base_data['buildings'])

            # Reset this now
            base_data['current_buildings'] = []

            # Get all buildings within this base
            found_buildings = {}
            total_needed = {}
            for b in buildings_needed:
                found_buildings[b] = 0
                total_needed[b] = 0

            for b in base_data['buildings']:
                total_needed[b] += 1

            # Loop through all actors and see what we've got
            for i, a in self.own_actors.items():
                if actor_lib.is_inside(a, base_area):
                    if a.actor_type in buildings_needed:
                        found_buildings[a.actor_type] += 1

                        if a.completion >= 100:
                            base_data['current_buildings'].append(a.oid)

            # Now also loop through all the buildings_in_progress
            # Use a range loop so we can update the list as we go
            for i in range(
                    len(base_data['buildings_in_progress']) - 1, -1, -1):
                b, ttl = base_data['buildings_in_progress'][i]

                if ttl <= 0:
                    del (base_data['buildings_in_progress'][i])
                    continue

                base_data['buildings_in_progress'][i][1] -= 1

                if b in found_buildings:
                    found_buildings[b] += 1

            # Now find out what we are missing
            missing = {}
            for b in buildings_needed:
                m = total_needed[b] - found_buildings[b]
                if m > 0:
                    missing[b] = m

            # None missing? We can stop looking around now
            if missing == {}:
                continue

            # Now find out which builders we can use
            # Narrow down our list of builders so we don't later iterate over
            # non-builders more than once
            builders = []
            builders_used = []
            for aid, a in self.own_actors.items():
                if self.actor_types[a.actor_type]['can_construct']:
                    if a.current_order[0] == "stop":
                        builders.append(a)

            # Now we work out which buildings we can build and who is closest to it
            for building_type, amount in missing.items():
                for i in range(amount):
                    target_pos = base_data['location']

                    closest_builder = None, 9999999
                    for b in builders:
                        if b in builders_used: continue
                        if actor_lib.can_build(
                                builder_type=self.actor_types[b.actor_type],
                                item_type=self.actor_types[building_type],
                                build_lists=self.build_lists,
                        ):
                            # If they are closest we want them to go build it
                            dist = vectors.distance(target_pos, b.pos)

                            if dist < closest_builder[1]:
                                closest_builder = b, dist

                    # Now remove them from the pool and issue the build order
                    if closest_builder[0] != None:
                        builders_used.append(closest_builder[0])
                        self.issue_orders(closest_builder[0].oid,
                                          cmd="build",
                                          pos=target_pos,
                                          target=building_type)

                        base_data['buildings_in_progress'].append(
                            [building_type, buildings_in_progress_ttl])
Example #10
0
    def inspect_bases(self):
        # First find out which buildings we are missing
        for base_name, base_data in self.bases.items():
            base_area = (
                base_data["location"][0] - base_data["size"][0],
                base_data["location"][1] - base_data["size"][1],
                base_data["location"][0] + base_data["size"][0],
                base_data["location"][1] + base_data["size"][1],
            )

            buildings_needed = set(base_data["buildings"])

            # Reset this now
            base_data["current_buildings"] = []

            # Get all buildings within this base
            found_buildings = {}
            total_needed = {}
            for b in buildings_needed:
                found_buildings[b] = 0
                total_needed[b] = 0

            for b in base_data["buildings"]:
                total_needed[b] += 1

            # Loop through all actors and see what we've got
            for i, a in self.own_actors.items():
                if actor_lib.is_inside(a, base_area):
                    if a.actor_type in buildings_needed:
                        found_buildings[a.actor_type] += 1

                        if a.completion >= 100:
                            base_data["current_buildings"].append(a.oid)

            # Now also loop through all the buildings_in_progress
            # Use a range loop so we can update the list as we go
            for i in range(len(base_data["buildings_in_progress"]) - 1, -1, -1):
                b, ttl = base_data["buildings_in_progress"][i]

                if ttl <= 0:
                    del (base_data["buildings_in_progress"][i])
                    continue

                base_data["buildings_in_progress"][i][1] -= 1

                if b in found_buildings:
                    found_buildings[b] += 1

            # Now find out what we are missing
            missing = {}
            for b in buildings_needed:
                m = total_needed[b] - found_buildings[b]
                if m > 0:
                    missing[b] = m

            # None missing? We can stop looking around now
            if missing == {}:
                continue

            # Now find out which builders we can use
            # Narrow down our list of builders so we don't later iterate over
            # non-builders more than once
            builders = []
            builders_used = []
            for aid, a in self.own_actors.items():
                if self.actor_types[a.actor_type]["can_construct"]:
                    if a.current_order[0] == "stop":
                        builders.append(a)

            # Now we work out which buildings we can build and who is closest to it
            for building_type, amount in missing.items():
                for i in range(amount):
                    target_pos = base_data["location"]

                    closest_builder = None, 9999999
                    for b in builders:
                        if b in builders_used:
                            continue
                        if actor_lib.can_build(
                            builder_type=self.actor_types[b.actor_type],
                            item_type=self.actor_types[building_type],
                            build_lists=self.build_lists,
                        ):
                            # If they are closest we want them to go build it
                            dist = vectors.distance(target_pos, b.pos)

                            if dist < closest_builder[1]:
                                closest_builder = b, dist

                    # Now remove them from the pool and issue the build order
                    if closest_builder[0] != None:
                        builders_used.append(closest_builder[0])
                        self.issue_orders(closest_builder[0].oid, cmd="build", pos=target_pos, target=building_type)

                        base_data["buildings_in_progress"].append([building_type, buildings_in_progress_ttl])
Example #11
0
    def run_ai(self):
        if self.micro_orders == []:
            cmd, pos, target = self.current_order
        else:
            cmd, pos, target = self.micro_orders[0]

        self._passive_ai()
        self._attack_ai()
        self._help_ai()

        if cmd == "stop" or cmd == "hold position":
            self.velocity = vectors.V(0, 0, 0)

            if target == 0:
                self.next_order()

        elif cmd == "move":
            self._move_ai(pos)

            if vectors.distance(self.pos, pos) <= self.velocity.magnitude():
                self.pos = vectors.V(pos)
                self.velocity = vectors.V(0, 0, 0)
                self.next_order()

        elif cmd == "attack":
            target = self.get_first_target()

            # If we have a target, lets move closer to it
            if target != None:
                # First, are we within optimum range of our target?
                # If not then we need to get closer
                target_distance = vectors.distance(self.pos, target.pos)
                if target_distance > self.optimum_attack_range:
                    attack_pos = vectors.get_midpoint(
                        self.pos, target.pos, self.optimum_attack_range)
                    self._move_ai(attack_pos)
                else:
                    # If we are close enough then we can slow down
                    self._decelerate_ai()

        elif cmd == "aid":
            if target == None:
                target = self.get_first_ally()

            # If we have a target, lets move closer to it
            if target != None:
                dist = vectors.distance(self.pos, target.pos)

                if dist > self.optimum_heal_range:
                    target_pos = vectors.get_midpoint(self.pos, target.pos,
                                                      self.optimum_heal_range)
                    self._move_ai(target_pos)
                else:
                    self._decelerate_ai()

        else:
            raise Exception("No handler for cmd %s (pos: %s, target: %s)" %
                            (cmd, pos, target))

        # Do we have something to build?
        if self.build_queue != []:
            pass