def build_item_list(entity): entity['ai']['visible_items'] = {'weapon': [], 'container': [], 'ammo': [], 'bullet': [], 'corpse': []} return _active_solids = zones.get_active_solids(entity) for entity_id in entities.get_entity_group('items'): _item = entities.get_entity(entity_id) if not _item['stats']['type'] in entity['ai']['visible_items']: continue if _item['stats']['owner']: continue _distance = numbers.distance(movement.get_position(entity), movement.get_position(_item)) if _distance >= stats.get_vision(entity): continue for pos in shapes.line(movement.get_position(entity), movement.get_position(_item)): if pos in _active_solids: break else: entity['ai']['visible_items'][_item['stats']['type']].append(entity_id) entities.trigger_event(_item, 'seen', target_id=entity['_id'])
def hit(entity, projectile, damage_mod=1.0): _accuracy = random.uniform(.7, 1) _hit_map = [] for limb_name in entity['skeleton']['limbs']: _limb = entity['skeleton']['limbs'][limb_name] for i in range(int(round(_limb['health'] * _limb['accuracy']))): _hit_map.append(limb_name) _limb_name = random.choice(_hit_map) _limb = entity['skeleton']['limbs'][_limb_name] _damage = int( round((projectile['damage'] * _accuracy) * (numbers.clip( (1 - _limb['accuracy']), 0.25, .6) + .4))) _damage = int(round(_damage * damage_mod)) _limb['health'] -= _damage _x, _y = movement.get_position(entity) _x += int(round(random.uniform(-1, 1))) _y += int(round(random.uniform(-1, 1))) _mod = _limb['health'] / float(_limb['max_health']) #effects.explosion(_x, _y, 6) if not (_x, _y) in zones.get_active_solids(entity, ignore_calling_entity=True): #effects.blood(_x, _y) effects.blood_splatter( _x, _y, movement.get_direction(projectile) + random.randint(-5, 5)) entities.trigger_event(entity, 'animate', animation=['X', '@@'], repeat=4 * int(round((1 - _mod))), delay=20 * _mod) if _limb['health'] <= 0: if _limb['critical']: if projectile['owner'] in entities.ENTITIES: entities.trigger_event(entities.get_entity( projectile['owner']), 'log_kill', target_id=entity['_id']) entities.trigger_event(entity, 'killed_by', target_id=projectile['owner']) #entity['stats']['grave'] = {'':} entities.delete_entity(entity) else: if projectile['owner'] in entities.ENTITIES: entities.trigger_event(entities.get_entity(projectile['owner']), 'did_damage', target_id=entity['_id'], damage=_damage) entities.trigger_event(entity, 'damage', limb=_limb_name, damage=_damage)
def _smoke_shooter_push(entity): _x, _y = movement.get_position(entity) _direction = movement.get_direction(entity) _mod = random.randint(-35, 35) _alpha = flags.get_flag(entity, 'alpha') if _mod < 0: _mod = numbers.clip(_mod, -35, -20) else: _mod = numbers.clip(_mod, 20, 35) _direction += _mod _v_x, _v_y = numbers.velocity(_direction, random.uniform(.65, .85)) if not int(round(_x + _v_x)) == int(round(_x)) or not int(round(_y + _v_y)) == int(round(_y)): #smoke_cloud(_x + _v_x, _y + _v_y, random.randint(1, 2), start_alpha=_alpha, decay_amount=1.2) smoke(_x + _v_x, _y + _v_y, .75, start_amount=_alpha, decay_amount=random.uniform(3.0, 4.0)) _x += _v_x _y += _v_y if (int(round(_x)), int(round(_y))) in zones.get_active_solids({}, no_life=True): entities.delete_entity(entity) return entities.trigger_event(entity, 'set_direction', direction=_direction) entities.trigger_event(entity, 'set_position', x=_x, y=_y) entities.trigger_event(entity, 'set_flag', flag='alpha', value=_alpha - .05)
def check_for_collisions(entity): _x, _y = movement.get_position(entity) if _x < 0 or _x >= zones.get_active_size( )[0] - 1 or _y < 0 or _y >= zones.get_active_size()[1] - 1: entities.delete_entity(entity) return if (_x, _y) in zones.get_active_solids(entity): entities.trigger_event(entity, 'collision_with_solid') return for entity_id in entities.get_entity_group('life'): if entity_id == entity['owner']: continue if movement.get_position(entity) == movement.get_position_via_id( entity_id): entities.trigger_event(entity, 'collision_with_entity', target_id=entity_id) return
def can_see_position(entity, position): _solids = zones.get_active_solids(entity) if numbers.distance(movement.get_position(entity), position) > stats.get_vision(entity): return False for pos in shapes.line(movement.get_position(entity), position): if pos in _solids: return False return True
def check_next_position(entity): _x = int(round(entity['movement']['next_x'])) _y = int(round(entity['movement']['next_y'])) if (_x, _y) in zones.get_active_solids({}, no_life=True, ignore_calling_entity=True): entity['movement']['next_x'] = entity['movement']['x'] entity['movement']['next_y'] = entity['movement']['y'] entities.trigger_event(entity, 'collision_with_solid') return True return False
def handle_movement_order(x, y): global WALK_PATH, WALK_DEST if not is_squad_member_selected() or (x, y) in zones.get_active_solids({}, ignore_calling_entity=True): return False _entity = get_selected_squad_member() movement.walk_to_position(_entity, x, y, zones.get_active_astar_map(), zones.get_active_weight_map()) WALK_PATH = _entity['movement']['path']['positions'] WALK_DEST = _entity['movement']['path']['destination'] settings.set_tick_mode('normal') return True
def handle_mouse_movement(entity, x, y, vx, vy): if not DRAGGING_NODE: return if (vx, vy) in zones.get_active_solids(entity): return entities.trigger_event(DRAGGING_NODE['node'], 'set_position', x=vx, y=vy) entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 255)) DRAGGING_NODE['node']['x'] = vx DRAGGING_NODE['node']['y'] = vy DRAGGING_NODE['node']['path'] = [] redraw_path(entity) entities.trigger_event(entity, 'stop')
def find_melee_position(entity): _target = entity['ai']['nearest_target'] _x, _y = entity['ai']['life_memory'][_target]['last_seen_at'] _closest_pos = {'pos': None, 'distance': 0} _solids = zones.get_active_solids(entity, ignore_entities=[_target]) for x, y in [(_x-1, _y), (_x+1, _y), (_x, _y-1), (_x, _y+1), (_x-1, _y-1), (_x+1, _y-1), (_x-1, _y+1), (_x+1, _y+1)]: if (x, y) in _solids: continue _distance = numbers.distance(movement.get_position(entity), (x, y)) if not _closest_pos['pos'] or _distance < _closest_pos['distance']: _closest_pos['distance'] = _distance _closest_pos['pos'] = (x, y) movement.walk_to_position(entity, _closest_pos['pos'][0], _closest_pos['pos'][1], zones.get_active_astar_map(), zones.get_active_weight_map())
def handle_movement_order(x, y): global WALK_PATH, WALK_DEST if not is_squad_member_selected() or (x, y) in zones.get_active_solids( {}, ignore_calling_entity=True): return False _entity = get_selected_squad_member() movement.walk_to_position(_entity, x, y, zones.get_active_astar_map(), zones.get_active_weight_map()) WALK_PATH = _entity['movement']['path']['positions'] WALK_DEST = _entity['movement']['path']['destination'] settings.set_tick_mode('normal') return True
def handle_mouse_movement(x, y): global WALK_PATH, WALK_DEST if ui_menu.get_active_menu() or ui_menu.DELAY or not is_squad_member_selected(): return _x = x+camera.X _y = y+camera.Y if (_x, _y) in zones.get_active_solids({}, ignore_calling_entity=True, no_life=True): return _s_x, _s_y = movement.get_position(get_selected_squad_member()) if (_x, _y) == WALK_DEST or (_x, _y) == (_s_x, _s_y): return WALK_PATH = pathfinding.astar((_s_x, _s_y), (_x, _y), zones.get_active_astar_map(), zones.get_active_weight_map()) WALK_DEST = (_x, _y)
def explosion(x, y, size): _solids = zones.get_active_solids({}, no_life=True) for pos in shapes.circle_smooth(x, y, size + .1, 0.05): _c_mod = 1 - (numbers.float_distance((x, y), pos) / size) _c_mod_clip = numbers.clip(1 - numbers.float_distance((x, y), pos) / size, random.uniform(.3, .45), 1) if pos in _solids or set(shapes.line((x, y), (int(round(pos[0])), int(round(pos[1]))))) & _solids: continue smoke(pos[0], pos[1], _c_mod_clip) if random.uniform(0, 1) < numbers.clip(_c_mod, 0, .75) and not pos in _solids: fire(pos[0], pos[1], _c_mod) for i in range(random.randint(2 * size, 3*size)): smoke_shooter(x, y, random.randint(0, 359)) light(x, y, random.randint(7, 9), r=2.5, g=1.5, b=1.5) light(x, y, random.randint(13, 15), r=1.3, g=1.3, b=1.3)
def check_for_collisions(entity): _x, _y = movement.get_position(entity) if _x < 0 or _x >= zones.get_active_size()[0]-1 or _y < 0 or _y >= zones.get_active_size()[1]-1: entities.delete_entity(entity) return if (_x, _y) in zones.get_active_solids(entity): entities.trigger_event(entity, 'collision_with_solid') return for entity_id in entities.get_entity_group('life'): if entity_id == entity['owner']: continue if movement.get_position(entity) == movement.get_position_via_id(entity_id): entities.trigger_event(entity, 'collision_with_entity', target_id=entity_id) return
def find_melee_position(entity): _target = entity['ai']['nearest_target'] _x, _y = entity['ai']['life_memory'][_target]['last_seen_at'] _closest_pos = {'pos': None, 'distance': 0} _solids = zones.get_active_solids(entity, ignore_entities=[_target]) for x, y in [(_x - 1, _y), (_x + 1, _y), (_x, _y - 1), (_x, _y + 1), (_x - 1, _y - 1), (_x + 1, _y - 1), (_x - 1, _y + 1), (_x + 1, _y + 1)]: if (x, y) in _solids: continue _distance = numbers.distance(movement.get_position(entity), (x, y)) if not _closest_pos['pos'] or _distance < _closest_pos['distance']: _closest_pos['distance'] = _distance _closest_pos['pos'] = (x, y) movement.walk_to_position(entity, _closest_pos['pos'][0], _closest_pos['pos'][1], zones.get_active_astar_map(), zones.get_active_weight_map())
def handle_mouse_movement(x, y): global WALK_PATH, WALK_DEST if ui_menu.get_active_menu( ) or ui_menu.DELAY or not is_squad_member_selected(): return _x = x + camera.X _y = y + camera.Y if (_x, _y) in zones.get_active_solids({}, ignore_calling_entity=True, no_life=True): return _s_x, _s_y = movement.get_position(get_selected_squad_member()) if (_x, _y) == WALK_DEST or (_x, _y) == (_s_x, _s_y): return WALK_PATH = pathfinding.astar((_s_x, _s_y), (_x, _y), zones.get_active_astar_map(), zones.get_active_weight_map()) WALK_DEST = (_x, _y)
def _fire_movement(entity, x, y, **kwargs): _solids = zones.get_active_solids({}, no_life=True) if (x, y) in _solids: entities.delete_entity(entity)
def handle_mouse_pressed(entity, x, y, button): global DRAGGING_NODE, LAST_CLICKED_POS, SELECTING_TARGET_CALLBACK if ui_menu.get_active_menu() or ui_menu.DELAY: return if timers.has_timer_with_name(entity, 'passout'): return _x = x + camera.X _y = y + camera.Y if button == 1: if DRAGGING_NODE: DRAGGING_NODE = None elif not (_x, _y) in zones.get_active_solids(entity): if not DRAGGING_NODE: for entity_id in [ t for t in entity['ai']['visible_life'] if entity['ai']['life_memory'][t]['can_see'] ]: if entity['_id'] == entity_id: continue _entity = entities.get_entity(entity_id) _tx, _ty = movement.get_position(_entity) if (_x, _y) == (_tx, _ty): if SELECTING_TARGET_CALLBACK: SELECTING_TARGET_CALLBACK(entity, entity_id) SELECTING_TARGET_CALLBACK = None else: LAST_CLICKED_POS = (_x, _y) create_life_interact_menu(entity, entity_id) return else: for entity_id in entities.get_entity_group('contexts'): _entity = entities.get_entity(entity_id) if not _entity['callback']: continue if (_entity['tile']['x'], _entity['tile']['y']) == (_x, _y): _entity['callback'](x + 2, y - 3) return else: for entity_id in list(entity['ai']['targets'] - entity['ai']['visible_life']): _tx, _ty = entity['ai']['life_memory'][entity_id][ 'last_seen_at'] if (_tx, _ty - 2) == (_x, _y): ui_dialog.create( x + 2, y - 3, '%s - Last seen <time>' % entities.get_entity( entity_id)['stats']['name']) return else: for entity_id in entities.get_entity_group( 'items'): _item = entities.get_entity(entity_id) if _item['stats']['owner']: continue if (_x, _y) == movement.get_position(_item): create_item_menu(entity, _item, _x, _y) return create_walk_node(entity, _x, _y, clear=True) return for node in entity['node_grid']['nodes'].values(): if (_x, _y) == (node['node']['x'], node['node']['y']): DRAGGING_NODE = node entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 0)) break if (_x, _y) in node['node']['path']: if not (_x, _y) in node['node']['busy_pos']: LAST_CLICKED_POS = (_x, _y) create_action_menu(entity, LAST_CLICKED_POS[0], LAST_CLICKED_POS[1], on_path=True) else: LAST_CLICKED_POS = None return elif button == 2: if DRAGGING_NODE: entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 255)) DRAGGING_NODE = None else: for node in entity['node_grid']['nodes'].values(): if (_x, _y) == (node['node']['x'], node['node']['y']): entity['node_grid']['path'].remove(node['node']['_id']) entities.delete_entity(node['node']) redraw_path(entity) del entity['node_grid']['nodes'][node['node']['_id']] if not entity['node_grid']['nodes']: clear_path(entity) break else: create_walk_node(entity, _x, _y)
def handle_mouse_pressed(entity, x, y, button): global DRAGGING_NODE, LAST_CLICKED_POS, SELECTING_TARGET_CALLBACK if ui_menu.get_active_menu() or ui_menu.DELAY: return if timers.has_timer_with_name(entity, 'passout'): return _x = x+camera.X _y = y+camera.Y if button == 1: if DRAGGING_NODE: DRAGGING_NODE = None elif not (_x, _y) in zones.get_active_solids(entity): if not DRAGGING_NODE: for entity_id in [t for t in entity['ai']['visible_life'] if entity['ai']['life_memory'][t]['can_see']]: if entity['_id'] == entity_id: continue _entity = entities.get_entity(entity_id) _tx, _ty = movement.get_position(_entity) if (_x, _y) == (_tx, _ty): if SELECTING_TARGET_CALLBACK: SELECTING_TARGET_CALLBACK(entity, entity_id) SELECTING_TARGET_CALLBACK = None else: LAST_CLICKED_POS = (_x, _y) create_life_interact_menu(entity, entity_id) return else: for entity_id in entities.get_entity_group('contexts'): _entity = entities.get_entity(entity_id) if not _entity['callback']: continue if (_entity['tile']['x'], _entity['tile']['y']) == (_x, _y): _entity['callback'](x+2, y-3) return else: for entity_id in list(entity['ai']['targets'] - entity['ai']['visible_life']): _tx, _ty = entity['ai']['life_memory'][entity_id]['last_seen_at'] if (_tx, _ty-2) == (_x, _y): ui_dialog.create(x + 2, y - 3, '%s - Last seen <time>' % entities.get_entity(entity_id)['stats']['name']) return else: for entity_id in entities.get_entity_group('items'): _item = entities.get_entity(entity_id) if _item['stats']['owner']: continue if (_x, _y) == movement.get_position(_item): create_item_menu(entity, _item, _x, _y) return create_walk_node(entity, _x, _y, clear=True) return for node in entity['node_grid']['nodes'].values(): if (_x, _y) == (node['node']['x'], node['node']['y']): DRAGGING_NODE = node entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 0)) break if (_x, _y) in node['node']['path']: if not (_x, _y) in node['node']['busy_pos']: LAST_CLICKED_POS = (_x, _y) create_action_menu(entity, LAST_CLICKED_POS[0], LAST_CLICKED_POS[1], on_path=True) else: LAST_CLICKED_POS = None return elif button == 2: if DRAGGING_NODE: entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 255)) DRAGGING_NODE = None else: for node in entity['node_grid']['nodes'].values(): if (_x, _y) == (node['node']['x'], node['node']['y']): entity['node_grid']['path'].remove(node['node']['_id']) entities.delete_entity(node['node']) redraw_path(entity) del entity['node_grid']['nodes'][node['node']['_id']] if not entity['node_grid']['nodes']: clear_path(entity) break else: create_walk_node(entity, _x, _y)
def search_for_target(entity): _lost_targets = entity['ai']['targets_to_search'] _inside = zones.get_active_inside_positions() if not _lost_targets: print 'Trying to search with no lost targets' return _closest_target = {'distance': 0, 'target_id': None} for target_id in _lost_targets: _memory = entity['ai']['life_memory'][target_id] _distance = numbers.distance(movement.get_position(entity), _memory['last_seen_at']) if not _closest_target['target_id'] or _distance < _closest_target['distance']: _closest_target['target_id'] = target_id _closest_target['distance'] = _distance _target = entities.get_entity(_closest_target['target_id']) _solids = zones.get_active_solids(entity) if flags.has_flag(entity, 'search_nodes'): _search_for_target(entity, _target['_id']) return _x, _y = movement.get_position(entity) _tx, _ty = entity['ai']['life_memory'][_target['_id']]['last_seen_at'] _nodes_to_search = {} if entity['ai']['life_memory'][_target['_id']]['last_seen_velocity']: _vx, _vy = entity['ai']['life_memory'][_target['_id']]['last_seen_velocity'] _tx + _vx*6 _ty + _vy*6 entities.trigger_event(entity, 'set_flag', flag='search_nodes', value=_nodes_to_search) for node_x, node_y in zones.get_active_node_grid(): _distance = numbers.distance((_tx, _ty), (node_x, node_y)) if _distance >= 30: continue if not (node_x, node_y) in _inside: continue _continue = False for pos in shapes.line((_tx, _ty), (node_x, node_y)): if pos in _solids: _continue = True break if _continue: continue if _distance in _nodes_to_search: if not (node_x, node_y) in _nodes_to_search[_distance]: _nodes_to_search[_distance].append((node_x, node_y)) else: _nodes_to_search[_distance] = [(node_x, node_y)]
def build_life_list(entity): entity['ai']['visible_targets'] = [] _nearest_target = {'target_id': None, 'distance': 0} _solids = zones.get_active_solids(entity) _visible_life = set() _vision = stats.get_vision(entity) _visible_by_friendlies = [entities.get_entity(e)['ai']['visible_targets'] for e in entity['ai']['life_memory'] if not entity['ai']['life_memory'][e]['is_target'] and e in entities.ENTITIES] #Warning: Makes AI super smart _visible_by_friendlies = [item for sublist in _visible_by_friendlies for item in sublist] for entity_id in entities.get_entity_group('life'): if entity['_id'] == entity_id: continue _target = entities.get_entity(entity_id) if not entity_id in entity['ai']['life_memory']: life.create_life_memory(entity, entity_id) if not ai_factions.is_enemy(entity, entity_id): _visible = True else: if numbers.distance(movement.get_position(entity), movement.get_position(_target)) > _vision: if entity['ai']['life_memory'][entity_id]['can_see'] and ai_factions.is_enemy(entity, _target['_id']): entities.trigger_event(entity, 'target_lost', target_id=entity_id) if entity_id in _visible_by_friendlies: entity['ai']['life_memory'][entity_id]['in_los'] = False entity['ai']['life_memory'][entity_id]['can_see'] = True _visible = True else: entity['ai']['life_memory'][entity_id]['can_see'] = False entity['ai']['life_memory'][entity_id]['in_los'] = False if entity_id in entity['ai']['visible_life']: entity['ai']['visible_life'].remove(entity_id) _visible = False else: for pos in shapes.line(movement.get_position(entity), movement.get_position(_target)): if pos in _solids: if entity['ai']['life_memory'][entity_id]['can_see'] and ai_factions.is_enemy(entity, _target['_id']): entities.trigger_event(entity, 'target_lost', target_id=entity_id) if entity_id in _visible_by_friendlies: entity['ai']['life_memory'][entity_id]['in_los'] = False entity['ai']['life_memory'][entity_id]['can_see'] = True _visible = True else: entity['ai']['life_memory'][entity_id]['can_see'] = False entity['ai']['life_memory'][entity_id]['in_los'] = False if entity_id in entity['ai']['visible_life']: entity['ai']['visible_life'].remove(entity_id) _visible = False break else: entity['ai']['life_memory'][entity_id]['in_los'] = True _visible = True if not _visible and entity['ai']['life_memory'][entity_id]['seen_time'] > 0: _visible = True entity['ai']['life_memory'][entity_id]['in_los'] = False entity['ai']['life_memory'][entity_id]['can_see'] = True entity['ai']['life_memory'][entity_id]['seen_time'] -= 1 if entity_id in entity['ai']['visible_life']: entity['ai']['visible_life'].remove(entity_id) elif not _visible and entity_id in entity['ai']['visible_life']: entity['ai']['visible_life'].remove(entity_id) if _visible: _previous_last_seen_at = entity['ai']['life_memory'][entity_id]['last_seen_at'] _target_position = movement.get_position(_target)[:] entity['ai']['life_memory'][entity_id]['is_lost'] = False if entity['ai']['life_memory'][entity_id]['in_los']: if entity['ai']['life_memory'][entity_id]['seen_time'] < 30: entity['ai']['life_memory'][entity_id]['seen_time'] += 1 else: entity['ai']['life_memory'][entity_id]['seen_time'] -= 1 if entity['ai']['life_memory'][entity_id]['seen_time'] < 0 and entity_id in entity['ai']['visible_life']: entity['ai']['visible_life'].remove(entity_id) entity['ai']['life_memory'][entity_id]['in_los'] = False if movement.get_position(_target) == _previous_last_seen_at: _new_last_seen_at = _previous_last_seen_at else: _new_last_seen_at = _target_position _is_target = ai_factions.is_enemy(entity, _target['_id']) _profile = {'distance': numbers.distance(movement.get_position(entity), movement.get_position(_target)), 'is_target': _is_target, 'is_armed': items.get_items_in_holder(_target, 'weapon'), 'is_lost': False, 'can_see': True, 'last_seen_at': _new_last_seen_at, 'last_seen_velocity': None} if not entity_id in entity['ai']['visible_life']: entities.trigger_event(entity, 'new_target_spotted', target_id=entity_id) if entity['ai']['life_memory'][entity_id]['in_los']: entity['ai']['visible_life'].add(entity_id) if _is_target: ai_flow.register_combat(entity, entity_id) if _is_target: entity['ai']['targets'].add(entity_id) _distance = numbers.distance(movement.get_position(entity), movement.get_position_via_id(entity_id)) if not _nearest_target['target_id'] or _distance < _nearest_target['distance']: _nearest_target['distance'] = _distance _nearest_target['target_id'] = entity_id if entity['ai']['life_memory'][entity_id]['last_seen_at']: _last_seen_at = entity['ai']['life_memory'][entity_id]['last_seen_at'][:] _velocity = (_profile['last_seen_at'][0]-_last_seen_at[0], _profile['last_seen_at'][1]-_last_seen_at[1]) _profile['last_seen_velocity'] = _velocity else: _profile['last_seen_velocity'] = None if not entity['ai']['life_memory'][entity_id]['can_see'] and _is_target: _could_not_see_target_before = True else: _could_not_see_target_before = False entity['ai']['life_memory'][entity_id].update(_profile) if _could_not_see_target_before: entities.trigger_event(entity, 'target_found', target_id=entity_id) #TODO: What? #for t in entity['ai']['life_memory']: # if not 'is_lost' in entity['ai']['life_memory'][t]: # print entity['ai']['life_memory'][t] entity['ai']['visible_targets'] = list(entity['ai']['visible_life'] & entity['ai']['targets']) entity['ai']['targets_to_search'] = [t for t in entity['ai']['life_memory'].keys() if entity['ai']['life_memory'][t]['is_lost'] and not entity['ai']['life_memory'][t]['searched_for'] and t in entities.ENTITIES] if _nearest_target['target_id']: if not entity['ai']['nearest_target'] == _nearest_target['target_id']: entity['ai']['meta']['has_firing_position'] = True entity['ai']['nearest_target'] = _nearest_target['target_id'] elif entity['ai']['targets']: for target_id in list(entity['ai']['targets']): _target = entity['ai']['life_memory'][target_id] if not target_id in entities.ENTITIES or _target['is_lost']: entity['ai']['targets'].remove(target_id) continue _distance = numbers.distance(movement.get_position(entity), _target['last_seen_at']) if not _nearest_target['target_id'] or _distance < _nearest_target['distance']: _nearest_target['target_id'] = target_id _nearest_target['distance'] = _distance if not entity['ai']['nearest_target'] == _nearest_target['target_id']: entity['ai']['meta']['has_firing_position'] = True entity['ai']['nearest_target'] = _nearest_target['target_id']
def search_for_target(entity): _lost_targets = entity['ai']['targets_to_search'] _inside = zones.get_active_inside_positions() if not _lost_targets: print 'Trying to search with no lost targets' return _closest_target = {'distance': 0, 'target_id': None} for target_id in _lost_targets: _memory = entity['ai']['life_memory'][target_id] _distance = numbers.distance(movement.get_position(entity), _memory['last_seen_at']) if not _closest_target[ 'target_id'] or _distance < _closest_target['distance']: _closest_target['target_id'] = target_id _closest_target['distance'] = _distance _target = entities.get_entity(_closest_target['target_id']) _solids = zones.get_active_solids(entity) if flags.has_flag(entity, 'search_nodes'): _search_for_target(entity, _target['_id']) return _x, _y = movement.get_position(entity) _tx, _ty = entity['ai']['life_memory'][_target['_id']]['last_seen_at'] _nodes_to_search = {} if entity['ai']['life_memory'][_target['_id']]['last_seen_velocity']: _vx, _vy = entity['ai']['life_memory'][ _target['_id']]['last_seen_velocity'] _tx + _vx * 6 _ty + _vy * 6 entities.trigger_event(entity, 'set_flag', flag='search_nodes', value=_nodes_to_search) for node_x, node_y in zones.get_active_node_grid(): _distance = numbers.distance((_tx, _ty), (node_x, node_y)) if _distance >= 30: continue if not (node_x, node_y) in _inside: continue _continue = False for pos in shapes.line((_tx, _ty), (node_x, node_y)): if pos in _solids: _continue = True break if _continue: continue if _distance in _nodes_to_search: if not (node_x, node_y) in _nodes_to_search[_distance]: _nodes_to_search[_distance].append((node_x, node_y)) else: _nodes_to_search[_distance] = [(node_x, node_y)]