def test_place_actor(self): vals = ( ([DummyActor(1000, 1000, 50, 50)], pygame.Rect(1000, 1000, 50, 50), pygame.Rect(900, 950, 50, 50)), ([ DummyActor(1000, 1000, 50, 50), DummyActor(900, 1000, 50, 50), ], pygame.Rect(1000, 1000, 50, 50), pygame.Rect(900, 1150, 50, 50)), ([ DummyActor(1879, 1879, 41, 50), DummyActor(1779, 1816, 41, 50), DummyActor(1679, 1716, 41, 50), DummyActor(1779, 1816, 41, 50), ], pygame.Rect(1700, 1800, 50, 50), pygame.Rect(1600, 1650, 50, 50)), ) for actor_list, new_rect, expected in vals: self.assertEqual(expected, ai_lib.place_actor(actor_list, new_rect, distance=100))
def test_place_actor(self): vals = ( ([DummyActor(1000, 1000, 50, 50)], pygame.Rect(1000, 1000, 50, 50), pygame.Rect(900, 950, 50, 50)), ([ DummyActor(1000, 1000, 50, 50), DummyActor(900, 1000, 50, 50), ], pygame.Rect(1000, 1000, 50, 50), pygame.Rect(900, 1150, 50, 50)), ([ DummyActor(1879, 1879, 41, 50), DummyActor(1779, 1816, 41, 50), DummyActor(1679, 1716, 41, 50), DummyActor(1779, 1816, 41, 50), ], pygame.Rect(1700, 1800, 50, 50), pygame.Rect(1600, 1650, 50, 50)), ) for actor_list, new_rect, expected in vals: self.assertEqual( expected, ai_lib.place_actor(actor_list, new_rect, distance=100))
def update(self): """The core function of the sim, this is where the 'magic happens'""" self.next_ai_update -= 1 if self.next_ai_update <= 0: self.update_ai_queues() self.next_ai_update = 30 # Update our network connection if self.connection == None: return self.connection.update() self.read_ai_queues() self.tick += 1 if self.tick + self.tick_jump not in self.orders: self.orders[self.tick + self.tick_jump] = [] if self.tick + self.tick_jump not in self.q_orders: self.q_orders[self.tick + self.tick_jump] = [] # Send and recieve orders with the server self.send_recieve_orders() # Run orders sent by the server self.issue_orders() # Update the AIs for t, a in self.autotargeters.items(): a.update() # Update the actors themselves to_remove = [] to_add = [] for aid, a in self.actors.items(): # 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, aid) 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))
def update(self): """The core function of the sim, this is where the 'magic happens'""" self.next_ai_update -= 1 if self.next_ai_update <= 0: self.update_ai_queues() self.next_ai_update = 30 # Update our network connection if self.connection == None: return self.connection.update() self.read_ai_queues() self.tick += 1 if self.tick + self.tick_jump not in self.orders: self.orders[self.tick + self.tick_jump] = [] if self.tick + self.tick_jump not in self.q_orders: self.q_orders[self.tick + self.tick_jump] = [] # Send and recieve orders with the server self.send_recieve_orders() # Run orders sent by the server self.issue_orders() # Update the AIs for t, a in self.autotargeters.items(): a.update() # Update the actors themselves to_remove = [] to_add = [] for aid, a in self.actors.items(): # 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, aid) 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))