def update_position_maps(squad): _t = time.time() _coverage_positions = squad['coverage_positions'] _known_targets = squad['known_targets'] _known_squads = squad['known_squads'] _known_targets_left_to_check = _known_targets.copy() _score_map = {pos: {'coverage': 0, 'vantage': 100, 'member_coverage': 0, 'danger': 0, 'targets': [], 'owned': False} for pos in _coverage_positions} for faction_name, squad_id in _known_squads: if not squad_id in ai_factions.FACTIONS[faction_name]['squads']: continue _squad = entities.get_entity(ai_factions.FACTIONS[faction_name]['squads'][squad_id]) _member_set = set(_squad['members']) _check_members = _known_targets_left_to_check & _member_set _known_targets_left_to_check = _known_targets_left_to_check - _member_set for target_id in list(_check_members): _target_position = movement.get_position_via_id(target_id) _closest_member = {'distance': 0, 'member_id': None} for member_id in squad['members']: _member_position = movement.get_position_via_id(member_id) _distance = numbers.clip(numbers.distance(_target_position, _member_position), 0, 60) if not _closest_member['member_id'] or _distance < _closest_member['distance']: _closest_member['distance'] = _distance _closest_member['member_id'] = member_id _target_coverage_map = _squad['member_position_maps'][target_id] _overlap_positions = _coverage_positions & _target_coverage_map _cover_positions = _coverage_positions - _target_coverage_map if not _closest_member['member_id']: logging.warning('Couldn\'t find closest member for target during squad positioning.') continue _closest_member_pos = movement.get_position_via_id(_closest_member['member_id']) for pos in _overlap_positions: _distance = numbers.distance(_closest_member_pos, pos) if _distance < _score_map[pos]['vantage']: _score_map[pos]['vantage'] = _distance #_score_map[pos]['danger'] = 60 - _distance _score_map[pos]['targets'].append(target_id) for pos in _cover_positions: _distance = numbers.distance(_closest_member_pos, pos) if _distance > _score_map[pos]['coverage']: _score_map[pos]['coverage'] = _distance _score_map[pos]['danger'] = 60 - _distance squad['position_map_scores'] = _score_map
def handle_fire_order(x, y): global WALK_PATH, WALK_DEST if not is_squad_member_selected(): return False _entity = get_selected_squad_member() 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 _x, _y = movement.get_position_via_id(entity_id) if (_x, _y) == (x, y): create_life_interact_menu(_entity, entity_id) WALK_PATH = None WALK_DEST = None return True return False
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 focus_on_entity(entity, target_id, show_line=False, pause=False): global HAS_FOCUS, PAUSE if HAS_FOCUS or '--no-fx' in sys.argv: return HAS_FOCUS = target_id PAUSE = pause _entity = ui_dialog.create(18, 7, 'Enemy spotted!') entities.register_event(_entity, 'delete', lambda e: lose_focus()) entities.trigger_event(DIRECTOR, 'create_timer', time=120, exit_callback=lambda e: ui_dialog.delete(_entity)) if show_line: for x, y in shapes.line(movement.get_position(entity), movement.get_position_via_id(target_id)): effects.vapor(x, y, group='effects_freetick', start_alpha=1.0, fade_rate=.01)
def handle_squad_member_select(x, y): for squad_id in entities.get_entity_group('squads'): _squad = entities.get_entity(squad_id) if not _squad['faction'] == 'Rogues': continue for entity_id in _squad['members']: if movement.get_position_via_id(entity_id) == (x, y): select_squad_member(entity_id) return True
def get_active_solids(entity, ignore_entities=[], ignore_calling_entity=False, no_life=False): if not ACTIVE_ZONE: raise Exception('No zone is active.') _solids = ZONES[ACTIVE_ZONE]['solids'].copy() if not no_life: if not ignore_calling_entity: ignore_entities.append(entity['_id']) _solids.update([movement.get_position_via_id(p) for p in entities.get_entity_group('life') if not p in ignore_entities]) return _solids
def create_shoot_menu(entity, target_id): _tx, _ty = movement.get_position_via_id(target_id) _weapon = entities.get_entity(items.get_items_in_holder(entity, 'weapon')[0]) _menu = ui_menu.create(_tx-camera.X+2, _ty-camera.Y-4, title='Shoot') _accuracy = stats.get_accuracy(entity, _weapon['_id']) _x, _y = movement.get_position(entity) _direction = numbers.direction_to((_x, _y), (_tx, _ty)) _final_direction = _direction + (_accuracy * numbers.distance((_x, _y), (_tx, _ty))) _spray_accuracy = (100 * (_direction / float(_final_direction))) entities.trigger_event(_weapon, 'get_actions', menu=_menu) ui_menu.add_selectable(_menu, 'Spray (Acc: %.2d)' % _spray_accuracy, lambda: entities.trigger_event(entity, 'shoot', target_id=target_id) and settings.set_tick_mode('normal')) ui_menu.add_selectable(_menu, 'Snipe (Acc: %s)' % _accuracy, lambda: _)
def draw_raid_info(squad_id, camp_id): _camp = world_strategy.MAP['grid'][camp_id] _squad = entities.get_entity(squad_id) _travel_distance = numbers.distance(movement.get_position_via_id(squad_id), camp_id) _highest_speed = 0 _cost = ai_squads.get_attack_cost(_squad, camp_id) for member_id in _squad['members']: _member = entities.get_entity(member_id) _speed = movement.get_move_cost(_member) if _speed > _highest_speed: _highest_speed = _speed _travel_time = _travel_distance * (_highest_speed * 80) _time_string = '%s hours %s minutes' % (_travel_time / 60, _travel_time - ((_travel_time / 60) * 60)) _info = 'Right Click Camp to Confirm Order, ESC to cancel' if time.time() % 1 >= .5: _info_color = (200, 0, 0) else: _info_color = (200, 80, 80) display.write_string('ui_bar', (constants.WINDOW_WIDTH / 2) - (len(_info) / 2), 0, _info, fore_color=_info_color) display.write_string('ui_bar', 1, 1, 'Raid Order', fore_color=(200, 50, 70)) flavor_print(1, 3, [('Risk: ', 'Low', constants.STATUS_GOOD), ('Cost: $ ', '%i' % _cost, constants.STATUS_GOOD), ('Supplies needed: ', '%i' % 12, constants.STATUS_OK), ('Travel time: ', _time_string, constants.STATUS_OK)]) flavor_print(35, 3, [('Test value: ', 'Low', constants.STATUS_GOOD)])
def create_shoot_menu(entity, target_id): _tx, _ty = movement.get_position_via_id(target_id) _weapon = entities.get_entity( items.get_items_in_holder(entity, 'weapon')[0]) _menu = ui_menu.create(_tx - camera.X + 2, _ty - camera.Y - 4, title='Shoot') _accuracy = stats.get_accuracy(entity, _weapon['_id']) _x, _y = movement.get_position(entity) _direction = numbers.direction_to((_x, _y), (_tx, _ty)) _final_direction = _direction + (_accuracy * numbers.distance((_x, _y), (_tx, _ty))) _spray_accuracy = (100 * (_direction / float(_final_direction))) entities.trigger_event(_weapon, 'get_actions', menu=_menu) ui_menu.add_selectable( _menu, 'Spray (Acc: %.2d)' % _spray_accuracy, lambda: entities.trigger_event(entity, 'shoot', target_id=target_id ) and settings.set_tick_mode('normal')) ui_menu.add_selectable(_menu, 'Snipe (Acc: %s)' % _accuracy, lambda: _)
def get_active_solids(entity, ignore_entities=[], ignore_calling_entity=False, no_life=False): if not ACTIVE_ZONE: raise Exception('No zone is active.') _solids = ZONES[ACTIVE_ZONE]['solids'].copy() if not no_life: if not ignore_calling_entity: ignore_entities.append(entity['_id']) _solids.update([ movement.get_position_via_id(p) for p in entities.get_entity_group('life') if not p in ignore_entities ]) return _solids
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 draw_raid_info(squad_id, camp_id): _camp = world_strategy.MAP["grid"][camp_id] _squad = entities.get_entity(squad_id) _travel_distance = numbers.distance(movement.get_position_via_id(squad_id), camp_id) _highest_speed = 0 _cost = ai_squads.get_attack_cost(_squad, camp_id) for member_id in _squad["members"]: _member = entities.get_entity(member_id) _speed = movement.get_move_cost(_member) if _speed > _highest_speed: _highest_speed = _speed _travel_time = _travel_distance * (_highest_speed * 80) _time_string = "%s hours %s minutes" % (_travel_time / 60, _travel_time - ((_travel_time / 60) * 60)) _info = "Right Click Camp to Confirm Order, ESC to cancel" if time.time() % 1 >= 0.5: _info_color = (200, 0, 0) else: _info_color = (200, 80, 80) display.write_string("ui_bar", (constants.WINDOW_WIDTH / 2) - (len(_info) / 2), 0, _info, fore_color=_info_color) display.write_string("ui_bar", 1, 1, "Raid Order", fore_color=(200, 50, 70)) flavor_print( 1, 3, [ ("Risk: ", "Low", constants.STATUS_GOOD), ("Cost: $ ", "%i" % _cost, constants.STATUS_GOOD), ("Supplies needed: ", "%i" % 12, constants.STATUS_OK), ("Travel time: ", _time_string, constants.STATUS_OK), ], ) flavor_print(35, 3, [("Test value: ", "Low", constants.STATUS_GOOD)])
def handle_fire_order(x, y): global WALK_PATH, WALK_DEST if not is_squad_member_selected(): return False _entity = get_selected_squad_member() 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 _x, _y = movement.get_position_via_id(entity_id) if (_x, _y) == (x, y): create_life_interact_menu(_entity, entity_id) WALK_PATH = None WALK_DEST = None return True return False
def get_active_life_positions(entity): return [ movement.get_position_via_id(p) for p in entities.get_entity_group('life') if not p == entity['_id'] ]
def update_position_maps(squad): _t = time.time() _coverage_positions = squad['coverage_positions'] _known_targets = squad['known_targets'] _known_squads = squad['known_squads'] _known_targets_left_to_check = _known_targets.copy() _score_map = { pos: { 'coverage': 0, 'vantage': 100, 'member_coverage': 0, 'danger': 0, 'targets': [], 'owned': False } for pos in _coverage_positions } for faction_name, squad_id in _known_squads: if not squad_id in ai_factions.FACTIONS[faction_name]['squads']: continue _squad = entities.get_entity( ai_factions.FACTIONS[faction_name]['squads'][squad_id]) _member_set = set(_squad['members']) _check_members = _known_targets_left_to_check & _member_set _known_targets_left_to_check = _known_targets_left_to_check - _member_set for target_id in list(_check_members): _target_position = movement.get_position_via_id(target_id) _closest_member = {'distance': 0, 'member_id': None} for member_id in squad['members']: _member_position = movement.get_position_via_id(member_id) _distance = numbers.clip( numbers.distance(_target_position, _member_position), 0, 60) if not _closest_member[ 'member_id'] or _distance < _closest_member['distance']: _closest_member['distance'] = _distance _closest_member['member_id'] = member_id _target_coverage_map = _squad['member_position_maps'][target_id] _overlap_positions = _coverage_positions & _target_coverage_map _cover_positions = _coverage_positions - _target_coverage_map if not _closest_member['member_id']: logging.warning( 'Couldn\'t find closest member for target during squad positioning.' ) continue _closest_member_pos = movement.get_position_via_id( _closest_member['member_id']) for pos in _overlap_positions: _distance = numbers.distance(_closest_member_pos, pos) if _distance < _score_map[pos]['vantage']: _score_map[pos]['vantage'] = _distance #_score_map[pos]['danger'] = 60 - _distance _score_map[pos]['targets'].append(target_id) for pos in _cover_positions: _distance = numbers.distance(_closest_member_pos, pos) if _distance > _score_map[pos]['coverage']: _score_map[pos]['coverage'] = _distance _score_map[pos]['danger'] = 60 - _distance squad['position_map_scores'] = _score_map
def handle_mouse_pressed(x, y, button): global SELECTED_SQUAD, SELECTED_CAMP, MAP_PATH _s1, _s2 = entities.get_entity_group('squads')[:2] _m_x, _m_y = x / constants.MAP_CELL_SPACE, y / constants.MAP_CELL_SPACE if button == 1: _camp = MAP['grid'][_m_x, _m_y] if _camp['owned_by'] == 'Rogues' and not SELECTED_CAMP: SELECTED_CAMP = (_m_x, _m_y) set_draw_mode('camp_info') elif not _camp['owned_by'] == 'Rogues': if SELECTED_SQUAD: if _camp['owned_by']: SELECTED_CAMP = (_m_x, _m_y) MAP_PATH = pathfinding.astar(movement.get_position_via_id(_s1), (_m_x, _m_y), MAP['astar_map'], MAP['astar_weight_map']) set_draw_mode('raid') elif _camp['is_ownable']: SELECTED_CAMP = (_m_x, _m_y) set_draw_mode('occupy') else: SELECTED_SQUAD = None SELECTED_CAMP = None set_draw_mode('news') #set_draw_mode('camp_info') else: for squad_id in entities.get_entity_group('squads'): if squad_id == SELECTED_SQUAD: continue _squad = entities.get_entity(squad_id) if not movement.get_position(_squad) == (_m_x, _m_y): continue if not _squad['faction'] == 'Rogues': continue SELECTED_SQUAD = squad_id SELECTED_CAMP = None set_draw_mode('squad_info') break elif button == 2: _camp = MAP['grid'][_m_x, _m_y] if not _camp['owned_by'] == 'Rogues': if SELECTED_SQUAD: if DRAW_MODE == 'raid': entities.trigger_event(entities.get_entity(SELECTED_SQUAD), 'raid', camp_id=(_m_x, _m_y)) SELECTED_SQUAD = None SELECTED_CAMP = None set_draw_mode('news')
def _animal_logic(entity): if timers.has_timer_with_name(entity, 'passout'): return ai_visuals.build_item_list(entity) ai_visuals.build_life_list(entity) _old_meta = entity['ai']['meta'].copy() entity['ai']['meta']['in_engagement'] = len(entity['ai']['targets']) > 0 entity['ai']['meta']['in_enemy_los'] = len([ t for t in entity['ai']['targets'] if entity['ai']['life_memory'][t]['in_los'] ]) > 0 if not entity['ai']['meta'] == _old_meta: entities.trigger_event(entity, 'meta_change') if entity['ai']['meta']['in_engagement']: _target = entity['ai']['nearest_target'] _target_distance = numbers.distance( movement.get_position_via_id(_target), movement.get_position(entity)) entity['ai']['meta']['is_target_near'] = _target_distance <= 25 if not entity['ai']['meta']['in_enemy_los'] and life.can_see_position( entity, entity['ai']['life_memory'][_target]['last_seen_at']): entity['ai']['meta']['has_lost_target'] = entity['ai']['meta'][ 'is_target_near'] elif entity['ai']['meta']['in_enemy_los']: if flags.has_flag(entity, 'search_nodes'): flags.delete_flag(entity, 'search_nodes') entity['ai']['meta']['is_in_melee_range'] = _target_distance == 1 else: entity['ai']['meta']['is_target_near'] = False entity['ai']['meta']['is_target_armed'] = len([ t for t in entity['ai']['targets'] if entity['ai']['life_memory'][t]['is_armed'] ]) > 0 #entity['ai']['meta']['is_panicked'] = skeleton.has_critical_injury(entity) entity['ai']['meta']['is_injured'] = skeleton.has_critical_injury(entity) entity['ai']['meta']['is_panicked'] = entity['ai']['meta']['is_injured'] if entity['ai']['is_player']: return _goap = _handle_goap(entity) if not _goap: entity['ai']['current_action'] = 'idle' return _plan = _goap[0] _plan['planner'].trigger_callback(entity, _plan['actions'][0]['name']) #print time.time() - _t if not entity['ai']['last_action'] == _plan['actions'][0]['name']: logging.debug('%s: %s -> %s' % (entity['_id'], entity['ai']['last_action'], _plan['actions'][0]['name'])) entity['ai']['last_action'] = _plan['actions'][0]['name'] entity['ai']['current_action'] = _plan['actions'][0]['name']
def _animal_logic(entity): if timers.has_timer_with_name(entity, "passout"): return ai_visuals.build_item_list(entity) ai_visuals.build_life_list(entity) _old_meta = entity["ai"]["meta"].copy() entity["ai"]["meta"]["in_engagement"] = len(entity["ai"]["targets"]) > 0 entity["ai"]["meta"]["in_enemy_los"] = ( len([t for t in entity["ai"]["targets"] if entity["ai"]["life_memory"][t]["in_los"]]) > 0 ) if not entity["ai"]["meta"] == _old_meta: entities.trigger_event(entity, "meta_change") if entity["ai"]["meta"]["in_engagement"]: _target = entity["ai"]["nearest_target"] _target_distance = numbers.distance(movement.get_position_via_id(_target), movement.get_position(entity)) entity["ai"]["meta"]["is_target_near"] = _target_distance <= 25 if not entity["ai"]["meta"]["in_enemy_los"] and life.can_see_position( entity, entity["ai"]["life_memory"][_target]["last_seen_at"] ): entity["ai"]["meta"]["has_lost_target"] = entity["ai"]["meta"]["is_target_near"] elif entity["ai"]["meta"]["in_enemy_los"]: if flags.has_flag(entity, "search_nodes"): flags.delete_flag(entity, "search_nodes") entity["ai"]["meta"]["is_in_melee_range"] = _target_distance == 1 else: entity["ai"]["meta"]["is_target_near"] = False entity["ai"]["meta"]["is_target_armed"] = ( len([t for t in entity["ai"]["targets"] if entity["ai"]["life_memory"][t]["is_armed"]]) > 0 ) # entity['ai']['meta']['is_panicked'] = skeleton.has_critical_injury(entity) entity["ai"]["meta"]["is_injured"] = skeleton.has_critical_injury(entity) entity["ai"]["meta"]["is_panicked"] = entity["ai"]["meta"]["is_injured"] if entity["ai"]["is_player"]: return _goap = _handle_goap(entity) if not _goap: entity["ai"]["current_action"] = "idle" return _plan = _goap[0] _plan["planner"].trigger_callback(entity, _plan["actions"][0]["name"]) # print time.time() - _t if not entity["ai"]["last_action"] == _plan["actions"][0]["name"]: logging.debug("%s: %s -> %s" % (entity["_id"], entity["ai"]["last_action"], _plan["actions"][0]["name"])) entity["ai"]["last_action"] = _plan["actions"][0]["name"] entity["ai"]["current_action"] = _plan["actions"][0]["name"]
def get_active_life_positions(entity): return [movement.get_position_via_id(p) for p in entities.get_entity_group('life') if not p == entity['_id']]
def get_vantage_point(squad, member_id): _member = entities.get_entity(member_id) _member_pos = movement.get_position(_member) _best_vantage = {'position': None, 'score': 1000} _engage_range = flags.get_flag(_member, 'engage_distance') _min_engage_range = flags.get_flag(_member, 'min_engage_distance') if _member['movement']['path']['destination']: if _member['movement']['path']['destination'] in squad['position_map_scores']: _scores = squad['position_map_scores'][_member['movement']['path']['destination']] _score = _scores['vantage']# + _scores['member_coverage'] _continue = False for target_id in squad['known_targets']: _last_known_position = _member['ai']['life_memory'][target_id]['last_seen_at'] _distance_to_target = numbers.distance(_member['movement']['path']['destination'], _last_known_position) if _distance_to_target < _min_engage_range: _continue = True break if not _continue and _scores['targets'] and _score >= _min_engage_range and _score <= _engage_range: return _member['movement']['path']['destination'] for pos in squad['position_map_scores']: _scores = squad['position_map_scores'][pos] _dist = numbers.distance(_member_pos, pos) _score = _scores['vantage'] + _dist _continue = False if not _scores['targets'] or _score - _dist < _min_engage_range or _score > _engage_range + _dist: continue for target_id in squad['known_targets']: _last_known_position = _member['ai']['life_memory'][target_id]['last_seen_at'] _distance_to_target = numbers.distance(pos, _last_known_position) if _distance_to_target < _min_engage_range: _continue = True break if _continue: continue if _score < _best_vantage['score']: _astar_distance = len(pathfinding.astar(_member_pos, pos, zones.get_active_astar_map(), zones.get_active_weight_map())) _best_vantage['score'] = _score + _scores['member_coverage'] + int(round((_astar_distance * .15))) _best_vantage['position'] = pos[:] if not _best_vantage['position']: _member['ai']['meta']['has_firing_position'] = False entities.trigger_event(_member, 'create_timer', time=60, exit_callback=_reset_fire_position) return _x, _y = movement.get_position(_member) _member_positions = set() for squad_member_id in squad['members']: if squad_member_id == member_id: continue _member_positions.add(movement.get_position_via_id(squad_member_id)) _v_p = _best_vantage['position'] _friendly_fire = False for pos in shapes.line((_x, _y), _best_vantage['position']): if pos in _member_positions: _friendly_fire = True break if _friendly_fire: for n_pos in [(_v_p[0]-1, _v_p[1]-1), (_v_p[0], _v_p[1]-1), (_v_p[0]+1, _v_p[1]-1), (_v_p[0]-1, _v_p[1]), (_v_p[0]+1, _v_p[1]), (_v_p[0]-1, _v_p[1]+1), (_v_p[0], _v_p[1]+1), (_v_p[0]+1, _v_p[1]+1)]: if not n_pos in squad['position_map_scores']: continue _break = False for nn_pos in shapes.line((_x, _y), n_pos): if nn_pos in _member_positions: _break = True break else: _v_p = n_pos break if _break: continue for coverage_pos in shapes.circle(_v_p[0], _v_p[1], 6): if not coverage_pos in squad['position_map_scores']: continue _c_dist = 15 * (1 - (numbers.distance(coverage_pos, (_x, _y)) / 6.0)) squad['position_map_scores'][coverage_pos]['member_coverage'] += _c_dist squad['position_map_scores'][_v_p]['member_coverage'] += 6 return _v_p
def get_vantage_point(squad, member_id): _member = entities.get_entity(member_id) _member_pos = movement.get_position(_member) _best_vantage = {'position': None, 'score': 1000} _engage_range = flags.get_flag(_member, 'engage_distance') _min_engage_range = flags.get_flag(_member, 'min_engage_distance') if _member['movement']['path']['destination']: if _member['movement']['path']['destination'] in squad[ 'position_map_scores']: _scores = squad['position_map_scores'][_member['movement']['path'] ['destination']] _score = _scores['vantage'] # + _scores['member_coverage'] _continue = False for target_id in squad['known_targets']: _last_known_position = _member['ai']['life_memory'][target_id][ 'last_seen_at'] _distance_to_target = numbers.distance( _member['movement']['path']['destination'], _last_known_position) if _distance_to_target < _min_engage_range: _continue = True break if not _continue and _scores[ 'targets'] and _score >= _min_engage_range and _score <= _engage_range: return _member['movement']['path']['destination'] for pos in squad['position_map_scores']: _scores = squad['position_map_scores'][pos] _dist = numbers.distance(_member_pos, pos) _score = _scores['vantage'] + _dist _continue = False if not _scores[ 'targets'] or _score - _dist < _min_engage_range or _score > _engage_range + _dist: continue for target_id in squad['known_targets']: _last_known_position = _member['ai']['life_memory'][target_id][ 'last_seen_at'] _distance_to_target = numbers.distance(pos, _last_known_position) if _distance_to_target < _min_engage_range: _continue = True break if _continue: continue if _score < _best_vantage['score']: _astar_distance = len( pathfinding.astar(_member_pos, pos, zones.get_active_astar_map(), zones.get_active_weight_map())) _best_vantage['score'] = _score + _scores['member_coverage'] + int( round((_astar_distance * .15))) _best_vantage['position'] = pos[:] if not _best_vantage['position']: _member['ai']['meta']['has_firing_position'] = False entities.trigger_event(_member, 'create_timer', time=60, exit_callback=_reset_fire_position) return _x, _y = movement.get_position(_member) _member_positions = set() for squad_member_id in squad['members']: if squad_member_id == member_id: continue _member_positions.add(movement.get_position_via_id(squad_member_id)) _v_p = _best_vantage['position'] _friendly_fire = False for pos in shapes.line((_x, _y), _best_vantage['position']): if pos in _member_positions: _friendly_fire = True break if _friendly_fire: for n_pos in [(_v_p[0] - 1, _v_p[1] - 1), (_v_p[0], _v_p[1] - 1), (_v_p[0] + 1, _v_p[1] - 1), (_v_p[0] - 1, _v_p[1]), (_v_p[0] + 1, _v_p[1]), (_v_p[0] - 1, _v_p[1] + 1), (_v_p[0], _v_p[1] + 1), (_v_p[0] + 1, _v_p[1] + 1)]: if not n_pos in squad['position_map_scores']: continue _break = False for nn_pos in shapes.line((_x, _y), n_pos): if nn_pos in _member_positions: _break = True break else: _v_p = n_pos break if _break: continue for coverage_pos in shapes.circle(_v_p[0], _v_p[1], 6): if not coverage_pos in squad['position_map_scores']: continue _c_dist = 15 * (1 - (numbers.distance(coverage_pos, (_x, _y)) / 6.0)) squad['position_map_scores'][coverage_pos][ 'member_coverage'] += _c_dist squad['position_map_scores'][_v_p]['member_coverage'] += 6 return _v_p
def _human_logic(entity): _t = time.time() ai_visuals.build_item_list(entity) ai_visuals.build_life_list(entity) if ai_flow.is_flow_active() and not ai_flow.can_act(entity): return if timers.has_timer_with_name(entity, 'passout'): return #if not ai_squads.is_active(ai_squads.get_assigned_squad(entity)) or entity['stats']['action_points'] <= 0: # return _old_meta = entity['ai']['meta'].copy() entity['ai']['meta']['sees_item_type_weapon'] = len( entity['ai']['visible_items']['weapon']) > 0 entity['ai']['meta']['sees_item_type_ammo'] = len( entity['ai']['visible_items']['ammo']) > 0 entity['ai']['meta']['sees_item_type_container'] = len( entity['ai']['visible_items']['container']) > 0 entity['ai']['meta']['has_weapon'] = len( items.get_items_in_holder(entity, 'weapon')) > 0 entity['ai']['meta']['has_ammo'] = len( items.get_items_matching(entity, {'type': 'ammo'})) > 0 entity['ai']['meta']['has_container'] = len( items.get_items_matching(entity, {'type': 'container'})) > 0 entity['ai']['meta']['weapon_loaded'] = len([ w for w in items.get_items_in_holder(entity, 'weapon') if entities.get_entity(w)['flags']['ammo']['value'] > 0 ]) > 0 entity['ai']['meta']['in_engagement'] = len([ t for t in entity['ai']['targets'] if not entity['ai']['life_memory'][t]['is_lost'] ]) > 0 entity['ai']['meta']['has_lost_target'] = len( entity['ai']['targets_to_search']) > 0 entity['ai']['meta']['in_enemy_los'] = len([ t for t in entity['ai']['targets'] if entity['ai']['life_memory'][t]['in_los'] ]) > 0 entity['ai']['meta']['has_needs'] = not entity['ai']['meta'][ 'has_weapon'] or not entity['ai']['meta'][ 'has_container'] or not entity['ai']['meta']['weapon_loaded'] entity['ai']['meta']['is_injured'] = skeleton.has_critical_injury(entity) if not entity['ai']['meta'] == _old_meta: entities.trigger_event(entity, 'meta_change') if entity['ai']['meta']['in_engagement']: _target = entity['ai']['nearest_target'] _target_distance = numbers.distance( movement.get_position_via_id(_target), movement.get_position(entity)) _engage_distance = stats.get_vision(entity) * .75 _weapon = entities.get_entity( items.get_items_in_holder(entity, 'weapon')[0]) _engage_distance = numbers.clip( _engage_distance - (flags.get_flag(_weapon, 'accuracy') * 3), 1, stats.get_vision(entity)) _min_engage_distance = 3 if _weapon['stats']['kind'] == 'explosive': _engage_distance /= 2 _min_engage_distance = 8 entities.trigger_event(entity, 'set_flag', flag='engage_distance', value=_engage_distance) entities.trigger_event(entity, 'set_flag', flag='min_engage_distance', value=_min_engage_distance) #NOTE: Mirror change in ai_logic! entity['ai']['meta'][ 'in_firing_range'] = _target_distance <= _engage_distance and _target_distance >= _min_engage_distance if entity['ai']['meta']['in_enemy_los']: if flags.has_flag(entity, 'search_nodes'): flags.delete_flag(entity, 'search_nodes') entity['ai']['meta']['is_in_melee_range'] = _target_distance == 1 else: entity['ai']['meta']['is_target_near'] = False entity['ai']['meta']['in_firing_range'] = False entity['ai']['meta']['is_target_armed'] = len([ t for t in entity['ai']['targets'] if entity['ai']['life_memory'][t]['is_armed'] ]) > 0 entity['ai']['meta']['is_panicked'] = ( not entity['ai']['meta']['weapon_loaded'] and entity['ai']['meta']['is_target_armed']) if entity['ai']['is_player']: return #TODO: Experimental! #if entity['ai']['meta'] == _old_meta: #print 'Something changed...' #return if timers.has_timer_with_name( entity, 'shoot' ) or entity['movement']['path']['positions'] or timers.has_timer_with_name( entity, 'move'): #print 'Clearing existing action...' return _goap = _handle_goap(entity) if not _goap: entity['ai']['current_action'] = 'idle' entities.trigger_event(entity, 'finish_turn') entities.trigger_event(entity, 'stop') #print #print entity['stats']['name'], 'no possible action' #print #for meta_name in entity['ai']['meta']: # print meta_name, '\t', entity['ai']['meta'][meta_name] return _plan = _goap[0] if not entity['ai']['last_action'] == _plan['actions'][0]['name']: if entity['_id'] in ai_debugger.WATCHING: logging.info('%s: %s -> %s' % (entity['_id'], entity['ai']['last_action'], _plan['actions'][0]['name'])) #TODO: Only do this if the action requires movement changes entities.trigger_event(entity, 'stop') entity['ai']['last_action'] = _plan['actions'][0]['name'] #print entity['stats']['name'], _plan['actions'][0]['name'] _plan['planner'].trigger_callback(entity, _plan['actions'][0]['name']) #print time.time() - _t entity['ai']['current_action'] = _plan['actions'][0]['name']
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 _human_logic(entity): _t = time.time() ai_visuals.build_item_list(entity) ai_visuals.build_life_list(entity) if ai_flow.is_flow_active() and not ai_flow.can_act(entity): return if timers.has_timer_with_name(entity, "passout"): return # if not ai_squads.is_active(ai_squads.get_assigned_squad(entity)) or entity['stats']['action_points'] <= 0: # return _old_meta = entity["ai"]["meta"].copy() entity["ai"]["meta"]["sees_item_type_weapon"] = len(entity["ai"]["visible_items"]["weapon"]) > 0 entity["ai"]["meta"]["sees_item_type_ammo"] = len(entity["ai"]["visible_items"]["ammo"]) > 0 entity["ai"]["meta"]["sees_item_type_container"] = len(entity["ai"]["visible_items"]["container"]) > 0 entity["ai"]["meta"]["has_weapon"] = len(items.get_items_in_holder(entity, "weapon")) > 0 entity["ai"]["meta"]["has_ammo"] = len(items.get_items_matching(entity, {"type": "ammo"})) > 0 entity["ai"]["meta"]["has_container"] = len(items.get_items_matching(entity, {"type": "container"})) > 0 entity["ai"]["meta"]["weapon_loaded"] = ( len( [ w for w in items.get_items_in_holder(entity, "weapon") if entities.get_entity(w)["flags"]["ammo"]["value"] > 0 ] ) > 0 ) entity["ai"]["meta"]["in_engagement"] = ( len([t for t in entity["ai"]["targets"] if not entity["ai"]["life_memory"][t]["is_lost"]]) > 0 ) entity["ai"]["meta"]["has_lost_target"] = len(entity["ai"]["targets_to_search"]) > 0 entity["ai"]["meta"]["in_enemy_los"] = ( len([t for t in entity["ai"]["targets"] if entity["ai"]["life_memory"][t]["in_los"]]) > 0 ) entity["ai"]["meta"]["has_needs"] = ( not entity["ai"]["meta"]["has_weapon"] or not entity["ai"]["meta"]["has_container"] or not entity["ai"]["meta"]["weapon_loaded"] ) entity["ai"]["meta"]["is_injured"] = skeleton.has_critical_injury(entity) if not entity["ai"]["meta"] == _old_meta: entities.trigger_event(entity, "meta_change") if entity["ai"]["meta"]["in_engagement"]: _target = entity["ai"]["nearest_target"] _target_distance = numbers.distance(movement.get_position_via_id(_target), movement.get_position(entity)) _engage_distance = stats.get_vision(entity) * 0.75 _weapon = entities.get_entity(items.get_items_in_holder(entity, "weapon")[0]) _engage_distance = numbers.clip( _engage_distance - (flags.get_flag(_weapon, "accuracy") * 3), 1, stats.get_vision(entity) ) _min_engage_distance = 3 if _weapon["stats"]["kind"] == "explosive": _engage_distance /= 2 _min_engage_distance = 8 entities.trigger_event(entity, "set_flag", flag="engage_distance", value=_engage_distance) entities.trigger_event(entity, "set_flag", flag="min_engage_distance", value=_min_engage_distance) # NOTE: Mirror change in ai_logic! entity["ai"]["meta"]["in_firing_range"] = ( _target_distance <= _engage_distance and _target_distance >= _min_engage_distance ) if entity["ai"]["meta"]["in_enemy_los"]: if flags.has_flag(entity, "search_nodes"): flags.delete_flag(entity, "search_nodes") entity["ai"]["meta"]["is_in_melee_range"] = _target_distance == 1 else: entity["ai"]["meta"]["is_target_near"] = False entity["ai"]["meta"]["in_firing_range"] = False entity["ai"]["meta"]["is_target_armed"] = ( len([t for t in entity["ai"]["targets"] if entity["ai"]["life_memory"][t]["is_armed"]]) > 0 ) entity["ai"]["meta"]["is_panicked"] = ( not entity["ai"]["meta"]["weapon_loaded"] and entity["ai"]["meta"]["is_target_armed"] ) if entity["ai"]["is_player"]: return # TODO: Experimental! # if entity['ai']['meta'] == _old_meta: # print 'Something changed...' # return if ( timers.has_timer_with_name(entity, "shoot") or entity["movement"]["path"]["positions"] or timers.has_timer_with_name(entity, "move") ): # print 'Clearing existing action...' return _goap = _handle_goap(entity) if not _goap: entity["ai"]["current_action"] = "idle" entities.trigger_event(entity, "finish_turn") entities.trigger_event(entity, "stop") # print # print entity['stats']['name'], 'no possible action' # print # for meta_name in entity['ai']['meta']: # print meta_name, '\t', entity['ai']['meta'][meta_name] return _plan = _goap[0] if not entity["ai"]["last_action"] == _plan["actions"][0]["name"]: if entity["_id"] in ai_debugger.WATCHING: logging.info("%s: %s -> %s" % (entity["_id"], entity["ai"]["last_action"], _plan["actions"][0]["name"])) # TODO: Only do this if the action requires movement changes entities.trigger_event(entity, "stop") entity["ai"]["last_action"] = _plan["actions"][0]["name"] # print entity['stats']['name'], _plan['actions'][0]['name'] _plan["planner"].trigger_callback(entity, _plan["actions"][0]["name"]) # print time.time() - _t entity["ai"]["current_action"] = _plan["actions"][0]["name"]
def handle_mouse_pressed(x, y, button): global SELECTED_SQUAD, SELECTED_CAMP, MAP_PATH _s1, _s2 = entities.get_entity_group('squads')[:2] _m_x, _m_y = x / constants.MAP_CELL_SPACE, y / constants.MAP_CELL_SPACE if button == 1: _camp = MAP['grid'][_m_x, _m_y] if _camp['owned_by'] == 'Rogues' and not SELECTED_CAMP: SELECTED_CAMP = (_m_x, _m_y) set_draw_mode('camp_info') elif not _camp['owned_by'] == 'Rogues': if SELECTED_SQUAD: if _camp['owned_by']: SELECTED_CAMP = (_m_x, _m_y) MAP_PATH = pathfinding.astar( movement.get_position_via_id(_s1), (_m_x, _m_y), MAP['astar_map'], MAP['astar_weight_map']) set_draw_mode('raid') elif _camp['is_ownable']: SELECTED_CAMP = (_m_x, _m_y) set_draw_mode('occupy') else: SELECTED_SQUAD = None SELECTED_CAMP = None set_draw_mode('news') #set_draw_mode('camp_info') else: for squad_id in entities.get_entity_group('squads'): if squad_id == SELECTED_SQUAD: continue _squad = entities.get_entity(squad_id) if not movement.get_position(_squad) == (_m_x, _m_y): continue if not _squad['faction'] == 'Rogues': continue SELECTED_SQUAD = squad_id SELECTED_CAMP = None set_draw_mode('squad_info') break elif button == 2: _camp = MAP['grid'][_m_x, _m_y] if not _camp['owned_by'] == 'Rogues': if SELECTED_SQUAD: if DRAW_MODE == 'raid': entities.trigger_event(entities.get_entity(SELECTED_SQUAD), 'raid', camp_id=(_m_x, _m_y)) SELECTED_SQUAD = None SELECTED_CAMP = None set_draw_mode('news')