Ejemplo n.º 1
0
def _bounce_one(a1, a2):
    # Bounces a1
    dir_angle = vectors.angle(a2.pos, a1.pos)

    vel_angle = vectors.angle(a1.velocity)

    # If they are head on then we want to swivel them a little
    if vectors.bound_angle(dir_angle[0] + 180) == vel_angle[0]:
        dir_angle[0] = vectors.bound_angle(dir_angle[0] + 40)

    # Keep trying distances further and further apart until they're
    # not going to be overlapping any more
    overlapping = True
    dist = vectors.total_velocity(a1.velocity)

    a2_rect = (a2.pos[0], a2.pos[1], a2.size[0], a2.size[1])

    while overlapping:
        new_pos = vectors.add_vectors(a1.pos,
                                      vectors.move_to_vector(dir_angle, dist))

        new_rect = (new_pos[0], new_pos[1], a1.size[0], a1.size[1])

        if not geometry.rect_collision(new_rect, a2_rect, True):
            overlapping = False

        dist += 1

    # Add a bit to be safe
    new_pos = vectors.add_vectors(
        a1.pos,
        vectors.move_to_vector(dir_angle,
                               dist + vectors.total_velocity(a1.velocity)))

    a1.pos = new_pos
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
def _bounce_one(a1, a2):
    # Bounces a1
    dir_angle = vectors.angle(a2.pos, a1.pos)
    
    vel_angle = vectors.angle(a1.velocity)
    
    # If they are head on then we want to swivel them a little
    if vectors.bound_angle(dir_angle[0]+180) == vel_angle[0]:
        dir_angle[0] = vectors.bound_angle(dir_angle[0] + 40)
    
    # Keep trying distances further and further apart until they're
    # not going to be overlapping any more
    overlapping = True
    dist = vectors.total_velocity(a1.velocity)
    
    a2_rect = (a2.pos[0], a2.pos[1], a2.size[0], a2.size[1])
    
    while overlapping:
        new_pos = vectors.add_vectors(a1.pos, vectors.move_to_vector(
            dir_angle, dist
        ))
        
        new_rect = (new_pos[0], new_pos[1], a1.size[0], a1.size[1])
        
        if not geometry.rect_collision(new_rect, a2_rect, True):
            overlapping = False
        
        dist += 1
    
    # Add a bit to be safe
    new_pos = vectors.add_vectors(a1.pos, vectors.move_to_vector(
        dir_angle, dist + vectors.total_velocity(a1.velocity)
    ))
    
    a1.pos = new_pos
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
 def get_offset_pos(self, use_effect_offset=False):
     """Gets the drawing position relative to the centre of their actor"""
     if use_effect_offset:
         base_offset = self.get_offset_pos()
         own_offset = vectors.move_to_vector(
             angle=vectors.add_vectors(self._effect_offset_angle,
                                       self.actor.facing),
             distance=self._effect_offset_distance)
         return vectors.add_vectors(base_offset, own_offset)
     else:
         return vectors.move_to_vector(angle=vectors.add_vectors(
             self._img_offset_angle, self.actor.facing),
                                       distance=self._img_offset_distance)
Ejemplo n.º 6
0
 def get_offset_pos(self, use_effect_offset=False):
     """Gets the drawing position relative to the centre of their actor"""
     if use_effect_offset:
         base_offset = self.get_offset_pos()
         own_offset = vectors.move_to_vector(
             angle = vectors.add_vectors(self._effect_offset_angle, self.actor.facing),
             distance = self._effect_offset_distance
         )
         return vectors.add_vectors(base_offset, own_offset)
     else:
         return vectors.move_to_vector(
             angle = vectors.add_vectors(self._img_offset_angle, self.actor.facing),
             distance = self._img_offset_distance
         )
Ejemplo n.º 7
0
 def generate_effect(self, target):
     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)
     
     the_effect = effects.Beam(
         origin=origin_pos,
         target=target.pos,
         colour=self.effect['colour'],
         duration=self.effect['duration'],
         degrade=self.effect.get("degrade", (0,0,0)),
     )
     self.actor.effects.append(the_effect)
Ejemplo n.º 8
0
    def generate_effect(self, target):
        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)

        the_effect = effects.Beam(
            origin=origin_pos,
            target=target.pos,
            colour=self.effect['colour'],
            duration=self.effect['duration'],
            degrade=self.effect.get("degrade", (0, 0, 0)),
        )
        self.actor.effects.append(the_effect)
Ejemplo n.º 9
0
 def update(self):
     self.pos = vectors.add_vectors(self.pos, self.velocity)
     
     # Set rect
     self.rect.topleft = (
         self.pos[0] - self.rect.width/2,
         self.pos[1] - self.rect.height/2
     )
Ejemplo n.º 10
0
    def get_rotated_offset(self, angle):
        if self.centre_offset == (0, 0):
            return 0, 0

        # Get the actual angle to use
        offset_angle = vectors.bound_angle(
            vectors.add_vectors(self.centre_offset[1], angle))

        return vectors.move_to_vector(offset_angle, self.centre_offset[0])
Ejemplo n.º 11
0
 def generate_effect(self, target):
     colour = [self.effect['colour'][i] + random.random() * self.effect['variation'][i] for i in range(3)]
     
     the_effect = effects.Beam(
         origin=vectors.add_vectors(self.actor.pos, self.effect_offset),
         target=target.pos,
         colour=effects.bound_colour(colour),
         duration=self.required_charge-1,
     )
     self.actor.effects.append(the_effect)
Ejemplo n.º 12
0
    def test_add_vectors(self):
        vals = (
            ([0, 0, 0], [1, 1, 1], [1, 1, 1]),
            ([2, 2, 2], [1, 1, 1], [3, 3, 3]),
            ([0, 0, 0], [0, 0, 0], [0, 0, 0]),
            ([3, 5, 7], [0, 5, 0], [3, 10, 7]),
        )

        for a, b, expected in vals:
            self.assertEqual(vectors.add_vectors(a, b), expected)
Ejemplo n.º 13
0
 def test_add_vectors(self):
     vals = (
         ([0,0,0], [1,1,1], [1,1,1]),
         ([2,2,2], [1,1,1], [3,3,3]),
         ([0,0,0], [0,0,0], [0,0,0]),
         ([3,5,7], [0,5,0], [3,10,7]),
     )
     
     for a, b, expected in vals:
         self.assertEqual(vectors.add_vectors(a, b), expected)
Ejemplo n.º 14
0
 def get_rotated_offset(self, angle):
     if self.centre_offset == (0, 0):
         return 0, 0
     
     # Get the actual angle to use
     offset_angle = vectors.bound_angle(
         vectors.add_vectors(self.centre_offset[1], angle)
     )
     
     return vectors.move_to_vector(offset_angle, self.centre_offset[0])
Ejemplo n.º 15
0
def _bounce_both(a1, a2):
    # These are the angles directly away from each other
    angle1 = vectors.angle(a2.pos, a1.pos)
    angle2 = vectors.angle(a1.pos, a2.pos)

    vel_angle1 = vectors.angle(a1.velocity)
    vel_angle2 = vectors.angle(a2.velocity)

    # If they are head on then we want to swivel them a little
    if vel_angle1[0] == angle2[0] and vel_angle2[0] == angle1[0]:
        angle1[0] = vectors.bound_angle(angle1[0] + 20)
        angle2[0] = vectors.bound_angle(angle2[0] + 20)

    # Keep trying distances further and further apart until they're
    # not going to be overlapping any more
    overlapping = True
    dist_multiplier = 0.1

    while overlapping:
        dist_multiplier += 0.1

        new_pos1 = vectors.add_vectors(
            a1.pos,
            vectors.move_to_vector(angle1,
                                   max(a1.size) * dist_multiplier))

        new_pos2 = vectors.add_vectors(
            a2.pos,
            vectors.move_to_vector(angle2,
                                   max(a2.size) * dist_multiplier))

        new_rect1 = (new_pos1[0], new_pos1[1], a1.size[0], a1.size[1])
        new_rect2 = (new_pos2[0], new_pos2[1], a2.size[0], a2.size[1])

        if not geometry.rect_collision(new_rect1, new_rect2):
            overlapping = False

    a1.pos = new_pos1
    a2.pos = new_pos2
Ejemplo n.º 16
0
    def generate_effect(self, target):
        colour = [
            self.effect['colour'][i] +
            random.random() * self.effect['variation'][i] for i in range(3)
        ]

        the_effect = effects.Beam(
            origin=vectors.add_vectors(self.actor.pos, self.effect_offset),
            target=target.pos,
            colour=effects.bound_colour(colour),
            duration=self.required_charge - 1,
        )
        self.actor.effects.append(the_effect)
Ejemplo n.º 17
0
def _bounce_both(a1, a2):
    # These are the angles directly away from each other
    angle1 = vectors.angle(a2.pos, a1.pos)
    angle2 = vectors.angle(a1.pos, a2.pos)
    
    vel_angle1 = vectors.angle(a1.velocity)
    vel_angle2 = vectors.angle(a2.velocity)
    
    # If they are head on then we want to swivel them a little
    if vel_angle1[0] == angle2[0] and vel_angle2[0] == angle1[0]:
        angle1[0] = vectors.bound_angle(angle1[0] + 20)
        angle2[0] = vectors.bound_angle(angle2[0] + 20)
    
    # Keep trying distances further and further apart until they're
    # not going to be overlapping any more
    overlapping = True
    dist_multiplier = 0.1
    
    while overlapping:
        dist_multiplier += 0.1
        
        new_pos1 = vectors.add_vectors(a1.pos, vectors.move_to_vector(
            angle1, max(a1.size) * dist_multiplier
        ))
        
        new_pos2 = vectors.add_vectors(a2.pos, vectors.move_to_vector(
            angle2, max(a2.size) * dist_multiplier
        ))
        
        new_rect1 = (new_pos1[0], new_pos1[1], a1.size[0], a1.size[1])
        new_rect2 = (new_pos2[0], new_pos2[1], a2.size[0], a2.size[1])
        
        if not geometry.rect_collision(new_rect1, new_rect2):
            overlapping = False
    
    a1.pos = new_pos1
    a2.pos = new_pos2
Ejemplo n.º 18
0
 def logic_cycle(self):
     """The core function of the sim, this is where the 'magic happens'"""
     if int(time.time()) != self.cycle_count[1]:
         self.cycle_count = [0, int(time.time())]
     
     self.next_ai_update -= 1
     if self.next_ai_update <= 0:
         self.update_ai_queues()
         self.next_ai_update = 30
     
     self.read_ai_queues()
     
     self.tick += 1
     
     self.orders[self.tick + self.tick_jump] = []
     self.q_orders[self.tick + self.tick_jump] = []
     self.issue_orders()
     
     # This will warn us if the sim is lagging behind how fast it's meant to be
     time_over = time.time() - self.next_cycle
     if time_over > 0.25:
         print("Logic lag of %ss" % time_over)
     
     # Update the AIs
     for t, a in self.autotargeters.items():
         a.update()
     
     # Update the actors themselves
     to_remove = []
     to_add = []
     for i, a in enumerate(self.actors):
         # First we need to check to see if it's got a build order
         # it'd have one because the AI can't directly tell us
         # to build something and instantly be told what the building
         # item is, thus we place it here and automatically tell
         # the actor to go build it
         if a.current_order[0] == "build" and a.completion >= 100:
             cmd, pos, type_name = a.current_order
             
             # Should this be done via a build queue instead?
             if self.actor_types[a.actor_type]['uses_build_queue']:
                 a.build_queue.append(type_name)
                 
             else:
                 a_type = self.actor_types[type_name]
         
                 new_rect = pygame.Rect(pos[0], pos[1], a_type['size'][0], a_type['size'][1])
                 building_rect = ai_lib.place_actor(self.actors, new_rect, [50, 100, 200], self.battlefield['size'])
                 
                 if building_rect != None:
                     posx = building_rect.left + building_rect.width/2
                     posy = building_rect.top + building_rect.height/2
             
                     to_add.append((a, {
                         "type": type_name,
                         "pos":  [posx, posy, 0],
                         "team": a.team,
                         "order_queue": list(a.rally_orders),
                     }))
             
             a.next_order()
         
         a.update()
         
         # Is the actor trying to place a new unit?
         # We only check as often as we check for collisions, this gives a cycle
         # for an already started actor to be given a position as it defaults to 0,0
         # and this has an impact on it's rect
         if self._collision_inverval_count < 2:
             if a.build_queue != [] and a.completion >= 100:
                 a_type = self.actor_types[a.build_queue[0]]
                 
                 new_rect_pos = vectors.add_vectors(a.pos, a.build_offset)
                 new_rect = pygame.Rect(new_rect_pos[0], new_rect_pos[1], a_type['size'][0], a_type['size'][1])
             
                 if not sim_lib.test_possible_collision(self.actors, new_rect):
                     to_add.append((a, {
                         "type": a.build_queue[0],
                         "pos":  new_rect_pos,
                         "team": a.team,
                         "order_queue": list(a.rally_orders),
                     }))
                     self.signal_menu_rebuild = True
                     del(a.build_queue[0])
         
         if a.hp <= 0: to_remove.insert(0, i)
     for i in to_remove: del(self.actors[i])
     for builder, new_actor in to_add:
         new_target = self.place_actor(new_actor)
         builder.issue_command("aid", target=new_target)
     
     # Bullets too
     to_delete = []
     for i, b in enumerate(self.bullets):
         b.update()
         
         if b.dead:
             new_effect = b.explode(self.actors)
             if new_effect != None:
                 self.effects.append(new_effect)
             to_delete.insert(0, i)
     for i in to_delete:
         del(self.bullets[i])
     
     # And lastly effects
     to_delete = []
     for i, e in enumerate(self.effects):
         e.update()
         if e.dead:
             to_delete.insert(0, i)
             continue
     
     # Delete any uneeded effects
     for i in to_delete:
         del(self.effects[i])
     
     # Check for collisions
     self._collision_inverval_count -= 1
     
     if self._collision_inverval_count < 1:
         self._collision_inverval_count = self._collision_interval
         collisions = sim_lib.get_collisions(self.actors)
         
         # We now have a list of all the collisions
         for obj1, obj2 in collisions:
             # We order them based on aid, this way we always deal with the same
             # actor in the same way and the order the collison was found is
             # irrelevant
             actor_lib.handle_pathing_collision(min(obj1, obj2), max(obj1, obj2))
     
     # Set next cycle time
     self.next_cycle = time.time() + self._cycle_delay
     self.cycle_count[0] += 1