def member_learn_raid(entity, member_id, camp): _faction = ai_factions.FACTIONS[camp['owner']['faction']] _squad = entities.get_entity(_faction['squads'][camp['owner']['squad']]) if not _squad['leader']: return _camp_leader = entities.get_entity(_squad['leader']) #TODO: Don't do this if not _camp_leader['_id'] in entity['ai']['life_memory']: life.create_life_memory(entity, _camp_leader['_id']) entity['ai']['life_memory'][_camp_leader['_id']].update({ 'is_lost': True, 'searched_for': False, 'can_see': False, 'last_seen_at': movement.get_position(_camp_leader), 'last_seen_velocity': None })
def member_added(mission, member_id): _member = entities.get_entity(member_id) for goal_id in mission['goals']: _goal = entities.get_entity(goal_id) entities.trigger_event(_goal, 'member_added', member_id=member_id)
def _kill_npc_logic(goal): _target_id = goal['target_id'] _mission = entities.get_entity(goal['mission_id']) if not _target_id in entities.ENTITIES: print 'IF THIS IS A BOUNTY MISSION: MISSION INVALIDATED' #TODO: Loop through members - do any of them think this mission is active? Else, delete. #TOOD: We can't do that if the person who assigned the mission hasn't gotten then news the target is dead for member_id in _mission['members']: _member = entities.get_entity(member_id) if not goal['mission_id'] in _member['missions']['active']: continue _member_goal = _member['missions']['active'][_mission['_id']]['goals'][goal['_id']] if not _target_id in _member['ai']['life_memory']: continue _memory = _member['ai']['life_memory'][_target_id] if _memory['is_dead']: entities.trigger_event(_member, 'complete_goal', mission_id=goal['mission_id'], goal_id=goal['_id']) else: entities.trigger_event(_member, 'uncomplete_goal', mission_id=goal['mission_id'], goal_id=goal['_id'])
def add_member(entity, member_id): entities.register_event(entities.get_entity(member_id), 'killed_by', lambda e, target_id, **kwargs: handle_member_killed(entity, member_id, target_id)) entities.register_event(entities.get_entity(member_id), 'new_target_spotted', lambda e, target_id: handle_new_target(entity, target_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 create_position_map(squad): _coverage_positions = set() _known_targets = set() _known_squads = set() for member_id in squad['members']: _member = entities.get_entity(member_id) _x, _y = movement.get_position(_member) _sight = stats.get_vision(_member) if member_id in squad['member_position_maps']: _old_coverage_positions = squad['member_position_maps'][member_id].copy() else: _old_coverage_positions = set() _map_size = zones.get_active_size() squad['member_position_maps'][member_id] = set() squad['member_los_maps'][member_id] = tcod.map_new(_map_size[0], _map_size[1]) tcod.map_copy(zones.get_active_los_map(), squad['member_los_maps'][member_id]) _t = time.time() tcod.map_compute_fov(squad['member_los_maps'][member_id], _x, _y, radius=_sight, light_walls=False, algo=tcod.FOV_PERMISSIVE_2) for pos in shapes.circle(_x, _y, _sight): if pos[0] < 0 or pos[0] >= _map_size[0] or pos[1] < 0 or pos[1] >= _map_size[1]: continue if not tcod.map_is_in_fov(squad['member_los_maps'][member_id], pos[0], pos[1]): continue _coverage_positions.add(pos) squad['member_position_maps'][member_id].add(pos) #TODO: Do this elsewhere for target_id in _member['ai']['visible_targets']: if not target_id in entities.ENTITIES: continue _target = entities.get_entity(target_id) _known_squads.add((_target['ai']['faction'], _target['ai']['squad'])) #TODO: Is this right? _known_targets.update(_member['ai']['visible_targets']) _positions_to_remove = _old_coverage_positions - _coverage_positions squad['known_targets'].update(_known_targets) squad['known_squads'].update(_known_squads) squad['coverage_positions'].update(_coverage_positions) squad['coverage_positions'] = squad['coverage_positions'] - _positions_to_remove if squad['known_targets']: update_position_maps(squad) logging.debug('Updated local position map - requesting squad update') else: logging.debug('Updated local position map.')
def draw_mission_details(): for mission_id in PLAYER['missions']['active']: _mission = entities.get_entity(mission_id) _valid_goals = [g for g in _mission['goals']] _y_mod = constants.MAP_VIEW_HEIGHT - len(_valid_goals) - 1 display.write_string('ui', 1, _y_mod - 2, _mission['title'], fore_color=(200, 200, 200), back_color=(10, 10, 10)) for goal_id in _valid_goals: _goal = entities.get_entity(goal_id) entities.trigger_event(_goal, 'get_message', member_id=PLAYER['_id']) if not _goal['draw']: continue if PLAYER['missions']['active'][mission_id]['goals'][goal_id]['complete']: _fore_color = (200, 200, 200) _text = '+ %s' % _goal['message'] else: _fore_color = (255, 255, 255) _text = '- %s' % _goal['message'] display.write_string('ui', 1, _y_mod, _text, fore_color=_fore_color, back_color=(30, 30, 30)) _y_mod += 1
def draw_turn_bar(): if not ai_flow.is_flow_active(): return _squad = entities.get_entity(ai_flow.get_active_squad()) _current_action_points = sum([entities.get_entity(m)['stats']['action_points'] for m in _squad['members']]) _max_action_points = sum([entities.get_entity(m)['stats']['action_points_max'] for m in _squad['members']]) _mod = _current_action_points / float(_max_action_points) _filled_value = int(round(constants.MAP_VIEW_WIDTH * _mod)) if _squad['faction'] == 'Rogues': _message = 'Action points: %s' % _current_action_points _fore_color = (0, 200, 0) _back_color = (0, 50, 0) elif entities.get_entity(_squad['leader'])['ai']['faction'] in ai_factions.FACTIONS['Rogues']['enemies']: _message = 'Enemy' _fore_color = (200, 0, 0) _back_color = (50, 0, 0) else: _message = 'Friendly' _fore_color = (0, 200, 200) _back_color = (0, 50, 50) _n = len(_message) _string = _message + ('=' * (_filled_value-_n)) + (' ' * ((constants.MAP_VIEW_WIDTH-_filled_value-1))) display.write_string('nodes', 0, 0, _string[:constants.MAP_VIEW_WIDTH], fore_color=_fore_color, back_color=_back_color)
def shoot_weapon(entity, target_id): if timers.has_timer_with_name(entity, 'shoot'): return _weapon = items.get_items_in_holder(entity, 'weapon')[0] _ammo = flags.get_flag(entities.get_entity(_weapon), 'ammo') _rounds_per_shot = flags.get_flag(entities.get_entity(_weapon), 'rounds_per_shot') _pause_time = 15 if not _ammo: return entities.trigger_event( entity, 'create_timer', time=_pause_time, repeat=_rounds_per_shot, name='shoot', enter_callback=lambda _: entities.trigger_event(entity, 'animate', animation= ['\\', '|', '/', '-'], delay=_pause_time / 4), repeat_callback=lambda _: _shoot_weapon(entity, _weapon, target_id))
def tick(): global TIME for squad_id in entities.get_entity_group('squads'): _squad = entities.get_entity(squad_id) entities.trigger_event(_squad, 'logic') for x, y in MAP['grid'].keys(): _camp = MAP['grid'][x, y] if _camp['is_ownable'] and _camp['owned_by']: ai_factions.FACTIONS[_camp['owned_by']]['money'] += _camp['income'] for squad_id in entities.get_entity_group('squads'): _squad = entities.get_entity(squad_id) entities.trigger_event(_squad, 'tick') TIME += 0.01 if NEED_FADE_IN: fade_in() entities.trigger_event(FADER, 'tick')
def _reload_weapon(entity, weapon_id, ammo_id): _weapon = entities.get_entity(weapon_id) _ammo = entities.get_entity(ammo_id) _weapon_ammo = flags.get_flag(_weapon, 'ammo') _weapon_ammo_max = flags.get_flag(_weapon, 'ammo_max') _ammo_count = flags.get_flag(_ammo, 'ammo') if _weapon_ammo == _weapon_ammo_max: return _need_ammo = numbers.clip(_weapon_ammo_max - _weapon_ammo, 1, _ammo_count) _ammo_count -= _need_ammo entities.trigger_event(_weapon, 'set_flag', flag='ammo', value=_weapon_ammo + _need_ammo) if _ammo_count: entities.trigger_event(_ammo, 'set_flag', flag='ammo', value=_ammo_count) else: entities.delete_entity(_ammo)
def _kill_npc_logic(goal): _target_id = goal['target_id'] _mission = entities.get_entity(goal['mission_id']) if not _target_id in entities.ENTITIES: print 'IF THIS IS A BOUNTY MISSION: MISSION INVALIDATED' #TODO: Loop through members - do any of them think this mission is active? Else, delete. #TOOD: We can't do that if the person who assigned the mission hasn't gotten then news the target is dead for member_id in _mission['members']: _member = entities.get_entity(member_id) if not goal['mission_id'] in _member['missions']['active']: continue _member_goal = _member['missions']['active'][_mission['_id']]['goals'][ goal['_id']] if not _target_id in _member['ai']['life_memory']: continue _memory = _member['ai']['life_memory'][_target_id] if _memory['is_dead']: entities.trigger_event(_member, 'complete_goal', mission_id=goal['mission_id'], goal_id=goal['_id']) else: entities.trigger_event(_member, 'uncomplete_goal', mission_id=goal['mission_id'], goal_id=goal['_id'])
def handle_new_target(entity, target_id): if not _faction_is_enemy(entity, target_id): return _target = entities.get_entity(target_id) _target_faction = _target['ai']['faction'] _target_squad = entities.get_entity(FACTIONS[_target_faction]['squads'][_target['ai']['squad']]) if _target['ai']['squad'] in entity['faction_memory'][_target_faction]['squads']: _squad_memory = entity['faction_memory'][_target_faction]['squads'][_target['ai']['squad']] if not target_id in _squad_memory['members']: _squad_memory['members'].append(target_id) _squad_memory['task'] = _target_squad['task'] else: entity['faction_memory'][_target_faction]['squads'][_target['ai']['squad']] = {'members': [target_id], 'last_task': '', 'task': _target_squad['task']} _squad_memory = entity['faction_memory'][_target_faction]['squads'][_target['ai']['squad']] if not _squad_memory['task'] == _squad_memory['last_task']: if _squad_memory['task'] == 'raid': entities.trigger_event(entity, 'faction_raid_incoming', target_faction=_target_faction, target_squad=_target['ai']['squad']) _squad_memory['last_task'] = _target_squad['task']
def disown(entity): if not entity['stats']['owner']: return _owner = entities.get_entity(entity['stats']['owner']) _x, _y = movement.get_position(_owner) entities.trigger_event(entity, 'set_position', x=_x, y=_y) if entity['stats']['type'] == 'container': for item_id in entity['inventory']['containers'][entity['_id']]: _item = entities.get_entity(item_id) disown(_item) del entity['inventory']['containers'][entity['_id']] if entity['stats']['in_container']: _owner['inventory']['containers'][ entity['stats']['in_container']]['items'].remove(entity['_id']) _owner['inventory']['containers'][entity['stats']['in_container']][ 'weight'] -= entity['stats']['weight'] entity['stats']['in_container'] = None _owner['inventory']['items'].remove(entity['_id']) entity['stats']['owner'] = None
def disown(entity): if not entity['stats']['owner']: return _owner = entities.get_entity(entity['stats']['owner']) _x, _y = movement.get_position(_owner) entities.trigger_event(entity, 'set_position', x=_x, y=_y) if entity['stats']['type'] == 'container': for item_id in entity['inventory']['containers'][entity['_id']]: _item = entities.get_entity(item_id) disown(_item) del entity['inventory']['containers'][entity['_id']] if entity['stats']['in_container']: _owner['inventory']['containers'][entity['stats']['in_container']]['items'].remove(entity['_id']) _owner['inventory']['containers'][entity['stats']['in_container']]['weight'] -= entity['stats']['weight'] entity['stats']['in_container'] = None _owner['inventory']['items'].remove(entity['_id']) entity['stats']['owner'] = None
def add_goal_kill_npc(mission, target_id): #TODO: Register _target = entities.get_entity(target_id) create_goal( mission, 'locate', 'Locate %s' % _target['stats']['name'], _locate_npc_logic, _locate_npc_message, target_id=target_id, details=[{ 'intent': 'last_seen_at', 'message': 'Ask for location', 'callback': lambda member_id, life_id: ai_dialog.share_life_memory_location( entities.get_entity(life_id), member_id, target_id) }]) create_goal(mission, 'kill', 'Kill %s' % _target['stats']['name'], _kill_npc_logic, _kill_npc_message, draw=False, target_id=target_id)
def _locate_npc_message(goal, member_id): _target_id = goal['target_id'] _member = entities.get_entity(member_id) _mission = entities.get_entity(goal['mission_id']) if not _target_id in _member['ai']['life_memory'] or not _member['ai']['life_memory'][_target_id]['last_seen_at']: goal['message'] = 'Gather location info on target.' return if _member['ai']['life_memory'][_target_id]['is_dead']: goal['message'] = 'Confirmed: Target is dead.' entities.trigger_event(_member, 'complete_goal', mission_id=goal['mission_id'], goal_id=goal['_id']) elif _member['ai']['life_memory'][_target_id]['can_see']: goal['message'] = 'Target in line of sight.' entities.trigger_event(_member, 'complete_goal', mission_id=goal['mission_id'], goal_id=goal['_id']) elif _member['ai']['life_memory'][_target_id]['last_seen_at']: _direction = numbers.direction_to(movement.get_position(_member), _member['ai']['life_memory'][_target_id]['last_seen_at']) _distance = numbers.distance(movement.get_position(_member), _member['ai']['life_memory'][_target_id]['last_seen_at']) _real_direction = conversions.get_real_direction(_direction) _real_distance = conversions.get_real_distance(_distance) goal['message'] = 'Target last seen %s meters to the %s' % (_real_distance, _real_direction) _member['ai']['life_memory'][_target_id]['mission_related'] = True
def build_push_map(squad): for member_id in squad['members']: _member = entities.get_entity(member_id) _non_visible_targets = _member['ai']['targets'] - set(_member['ai']['visible_targets']) for target_id in _non_visible_targets: _target = entities.get_entity(target_id) _target_squad = entities.get_entity(ai_factions.FACTIONS[_target['ai']['faction']]['squads'][_target['ai']['squad']])
def get_mission_details(mission, menu, member_id, target_id): _target = entities.get_entity(target_id) for goal_id in mission['goals']: _goal = entities.get_entity(goal_id) for detail in _goal['details']: ui_menu.add_selectable(menu, detail['message'], lambda: detail['callback'](member_id, target_id))
def create_talk_menu(entity, target_id): _menu = ui_menu.create(LAST_CLICKED_POS[0]-camera.X+2, LAST_CLICKED_POS[1]-camera.Y-4, title='Talk') _target = entities.get_entity(target_id) for mission_id in _target['missions']['inactive']: _mission = entities.get_entity(mission_id) ui_menu.add_selectable(_menu, _mission['title'], lambda: show_mission_details(entity, _mission))
def _handle_return_item_item_given(goal, member_id, item_id, target_id): _mission = entities.get_entity(goal['mission_id']) _item_name = goal['item_name'] _member = entities.get_entity(member_id) _item_given = entities.get_entity(item_id) if _item_name == _item_given['stats']['name']: entities.trigger_event(_member, 'complete_goal', mission_id=goal['mission_id'], goal_id=goal['_id'])
def add_member(entity, member_id): entities.register_event( entities.get_entity(member_id), 'killed_by', lambda e, target_id, **kwargs: handle_member_killed( entity, member_id, target_id)) entities.register_event( entities.get_entity(member_id), 'new_target_spotted', lambda e, target_id: handle_new_target(entity, target_id))
def draw_life_memory(): _camera_x, _camera_y = camera.X, camera.Y _width = display.get_surface('life')['width'] _height = display.get_surface('life')['height'] _draw_life = set() _can_see_life = set() _last_seen_locations = {} for squad_id in entities.get_entity_group('squads'): _squad = entities.get_entity(squad_id) if not _squad['faction'] == 'Rogues': continue for member_id in _squad['members']: _member = entities.get_entity(member_id) _can_see_life.update([i for i in _member['ai']['life_memory'] if _member['ai']['life_memory'][i]['can_see'] and i in entities.ENTITIES]) _draw_life.update(_member['ai']['targets'] - _member['ai']['visible_life']) for memory_id in _member['ai']['life_memory'].keys(): if not member_id in _last_seen_locations and _member['ai']['life_memory'][memory_id]['last_seen_at']: _last_seen_locations[memory_id] = _member['ai']['life_memory'][memory_id]['last_seen_at'] _draw_life = list(_draw_life) for entity_id in _draw_life: if entity_id in _can_see_life or not entity_id in entities.ENTITIES: continue if not entity_id in _last_seen_locations: continue _entity = entities.get_entity(entity_id) _x, _y = _last_seen_locations[entity_id] _x -= _camera_x _y -= _camera_y if _x < 0 or _y < 0 or _x >= _width or _y >= _height: continue if time.time() % 1 >= .5: _char = _entity['tile']['char'] _fore_color = _entity['tile']['fore_color'] else: _char = '!' _fore_color = (255, 0, 0) _render_x = numbers.clip(_x - len(_char)/2, 0, _width - len(_char) - 1) _render_y = numbers.clip(_y, 0, _height) #if _x - len(_char)/2 < 0 or _x + len(_char)/2 >= _width: # continue if _render_y == _y: _render_y += 2 display.write_string('ui', _render_x, _render_y, _char, fore_color=_fore_color)
def get_mission_details(mission, menu, member_id, target_id): _target = entities.get_entity(target_id) for goal_id in mission['goals']: _goal = entities.get_entity(goal_id) for detail in _goal['details']: ui_menu.add_selectable( menu, detail['message'], lambda: detail['callback'] (member_id, target_id))
def build_push_map(squad): for member_id in squad['members']: _member = entities.get_entity(member_id) _non_visible_targets = _member['ai']['targets'] - set( _member['ai']['visible_targets']) for target_id in _non_visible_targets: _target = entities.get_entity(target_id) _target_squad = entities.get_entity(ai_factions.FACTIONS[ _target['ai']['faction']]['squads'][_target['ai']['squad']])
def create_talk_menu(entity, target_id): _menu = ui_menu.create(LAST_CLICKED_POS[0] - camera.X + 2, LAST_CLICKED_POS[1] - camera.Y - 4, title='Talk') _target = entities.get_entity(target_id) for mission_id in _target['missions']['inactive']: _mission = entities.get_entity(mission_id) ui_menu.add_selectable(_menu, _mission['title'], lambda: show_mission_details(entity, _mission))
def _return_item_message(goal, member_id): _item_name = goal['item_name'] _target_id = goal['target_id'] _member = entities.get_entity(member_id) _mission = entities.get_entity(goal['mission_id']) if not items.get_items_matching(_member, {'name': _item_name}): goal['draw'] = False else: goal['draw'] = True goal['message'] = 'Return the item.' #TODO: To who?
def get_list_of_free_containers(entity, item_id): _containers = [] _item = entities.get_entity(item_id) for container_id in entity['inventory']['containers']: _container = entities.get_entity(container_id) if _item['stats']['weight'] + _container['stats']['weight'] > _container['stats']['max_weight']: continue _containers.append(container_id) return _containers
def handle_keyboard_input(): global SELECTED_SQUAD_MEMBER, WALK_PATH, WALK_DEST #TODO: Check for multiple movement changes at this location if not is_squad_member_selected(): return _entity = get_selected_squad_member() _x, _y = movement.get_position(_entity) if timers.has_timer_with_name(_entity, 'passout'): return if controls.get_input_char_pressed('z'): entities.trigger_event(_entity, 'set_motion', motion='crawl') settings.set_tick_mode('normal') elif controls.get_input_char_pressed('x'): entities.trigger_event(_entity, 'set_motion', motion='crouch') settings.set_tick_mode('normal') elif controls.get_input_char_pressed('c'): entities.trigger_event(_entity, 'set_motion', motion='stand') settings.set_tick_mode('normal') elif controls.get_input_char_pressed(' '): _entity['stats']['action_points'] = 0 SELECTED_SQUAD_MEMBER = None WALK_DEST = None WALK_PATH = [] _broken = False 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']: _entity = entities.get_entity(entity_id) if _entity['stats']['action_points'] > 0: _broken = True break if _broken: break else: settings.set_tick_mode('normal')
def draw_long_range_life(): _camera_x, _camera_y = camera.X, camera.Y _width = display.get_surface('life')['width'] _height = display.get_surface('life')['height'] _draw_life_targets = set() if settings.OBSERVER_MODE: _draw_life = entities.get_entity_group('life') else: _draw_life = set() for squad_id in entities.get_entity_group('squads'): _squad = entities.get_entity(squad_id) if not _squad['faction'] == 'Rogues': continue for member_id in _squad['members']: _member = entities.get_entity(member_id) _draw_life.add(member_id) _draw_life.update([i for i in _member['ai']['life_memory'] if _member['ai']['life_memory'][i]['can_see'] and i in entities.ENTITIES]) _draw_life_targets.update([i for i in _member['ai']['life_memory'] if _member['ai']['life_memory'][i]['can_see'] and _member['ai']['life_memory'][i]['is_target'] and i in entities.ENTITIES]) _draw_life = list(_draw_life) for entity_id in _draw_life: _entity = entities.get_entity(entity_id) _x, _y = movement.get_position(_entity) _x -= _camera_x _y -= _camera_y if _x < 0 or _y < 0 or _x >= _width or _y >= _height: _x = numbers.clip(_x, 0, _width-1) _y = numbers.clip(_y, 0, _height-1) else: continue if time.time() % 1 >= .5: _char = 'X' else: _char = 'O' if entity_id in _draw_life_targets: _fore_color = (255, 0, 0) _back_color = (100, 0, 0) else: _fore_color = (255, 255, 255) _back_color = (100, 100, 100) display.write_string('ui', _x, _y, _char, fore_color=_fore_color, back_color=_back_color)
def get_list_of_free_containers(entity, item_id): _containers = [] _item = entities.get_entity(item_id) for container_id in entity['inventory']['containers']: _container = entities.get_entity(container_id) if _item['stats']['weight'] + _container['stats'][ 'weight'] > _container['stats']['max_weight']: continue _containers.append(container_id) return _containers
def logic(): for squad_id in entities.get_entity_group('squads'): _squad = entities.get_entity(squad_id) for entity_id in _squad['members']: _entity = entities.get_entity(entity_id) entities.trigger_event(_entity, 'logic') for squad_id in settings.TURN_QUEUE[:]: if not squad_id in entities.ENTITIES: settings.TURN_QUEUE.remove(squad_id) continue _squad = entities.get_entity(squad_id) for entity_id in _squad['members']: _entity = entities.get_entity(entity_id) if _entity['stats']['action_points'] > 0: break else: if _squad['_id'] in settings.TURN_QUEUE: _was_leader = False if not settings.TURN_QUEUE.index(_squad['_id']): entities.trigger_event(FLOW, 'end_of_turn', squad_id=_squad['_id']) _was_leader = True settings.TURN_QUEUE.remove(_squad['_id']) if len(settings.TURN_QUEUE): settings.TURN_QUEUE.append(_squad['_id']) if settings.TURN_QUEUE and _was_leader: entities.trigger_event(FLOW, 'start_of_turn', squad_id=settings.TURN_QUEUE[0]) for entity_id in _squad['members']: _entity = entities.get_entity(entity_id) _entity['stats']['action_points'] = _entity['stats'][ 'action_points_max']
def show_weapons(entity): global ACTIVE_MENU, REDRAW_TIMES _holder_menu = ui_menu.create(1, 1, title='Weapons', surface='ui_inventory', click_offset=(constants.MAP_VIEW_WIDTH-35, 0)) ACTIVE_MENU = _holder_menu REDRAW_TIMES = 3 _equipped_weapon = items.get_items_in_holder(entity, 'weapon') _weapons = [] if _equipped_weapon: _weapons.append(_equipped_weapon[0]) for item_id in items.get_items_matching(entity, {'type': 'weapon'}): if item_id in _weapons: continue _weapons.add(item_id) for item_id in _weapons: _item = entities.get_entity(item_id) entities.trigger_event(_item, 'get_display_name') if item_id in _equipped_weapon: _fg = (245, 245, 245) else: _fg = (230, 230, 230) ui_menu.add_selectable(_holder_menu, _item['stats']['display_name'], show_weapon_menu, fore_color=_fg, item_id=item_id)
def update_group_status(entity): set_squad_meta(entity, 'is_squad_combat_ready', True) return _members_combat_ready = 0 for member_id in entity['member_info']: _member = entities.get_entity(member_id) if _member['ai']['meta'][ 'has_needs'] and not _member['ai']['meta']['weapon_loaded']: continue if _member['ai']['meta']['is_injured'] or _member['ai']['meta'][ 'is_panicked']: continue if timers.has_timer_with_name(_member, 'passout'): continue _members_combat_ready += entity['member_info'][member_id]['armed'] set_squad_meta( entity, 'is_squad_combat_ready', _members_combat_ready / float(len(entity['member_info'].keys())) >= .65) set_squad_meta( entity, 'is_squad_mobile_ready', _members_combat_ready / float(len(entity['member_info'].keys())) >= .65)
def add_goal_get_item(mission, item_name, return_to_life_id): create_goal(mission, 'locate_item', 'Locate item: %s' % item_name, _locate_item_logic, _locate_item_message, item_name=item_name, details=[]) _goal = create_goal(mission, 'return_item', 'Return item: %s' % item_name, _return_item_logic, _return_item_message, draw=True, item_name=item_name, target_id=return_to_life_id, details=[{ 'intent': 'return_item', 'message': 'Return item', 'callback': lambda member_id, life_id: ai_dialog.give_item( entities.get_entity(member_id), life_id, {'name': 'Mutated Wild Dog Tail'}) }]) _event_id = entities.register_event(_goal, 'member_added', _handle_return_item_member_added)
def _handle_mutated_wild_dog_corpse(entity, corpse_id): _corpse = entities.get_entity(corpse_id) entities.register_event( _corpse, 'get_interactions', lambda e, menu, target_id: ui_menu.add_selectable( menu, 'Cut off tail', lambda: _handle_cut_tail(e, target_id)))
def create_noise(entity, text, volume, owner_can_hear=False, show_on_sight=False, direction=-1000, callback=None, context_callback=None): _x, _y = movement.get_position(entity) for entity_id in entities.get_entity_group('life'): if not owner_can_hear and entity['_id'] == entity_id: continue _target = entities.get_entity(entity_id) if entity['ai']['faction'] == _target['ai']['faction']: continue #TODO: Hearing stat _distance = numbers.distance(movement.get_position(entity), movement.get_position(_target)) _accuracy = 1 - numbers.clip(_distance / float(volume), 0, 1) entities.trigger_event(_target, 'heard_noise', x=_x, y=_y, text=text, direction=direction, show_on_sight=show_on_sight, accuracy=_accuracy, callback=callback, context_callback=context_callback)
def get_push_position(squad, member_id): _member = entities.get_entity(member_id) _best_vantage = {'position': None, 'score': 1000} _vision = stats.get_vision(_member) _engage_range = int(round(_vision * .75)) for pos in squad['position_map_scores']: _scores = squad['position_map_scores'][pos] _score = _scores['vantage'] + _scores['member_coverage'] if not _scores['targets'] or _score < 6 or _score > _engage_range: continue if _score < _best_vantage['score']: _best_vantage['score'] = _score _best_vantage['position'] = pos[:] if not _best_vantage['position']: _member['ai']['meta']['has_firing_position'] = False return _x, _y = movement.get_position(_member) for coverage_pos in shapes.circle(_best_vantage['position'][0], _best_vantage['position'][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'][_best_vantage['position']]['member_coverage'] += 20 return _best_vantage['position']
def select_squad_member(entity_id): global SELECTED_SQUAD_MEMBER SELECTED_SQUAD_MEMBER = entity_id entities.register_event(entities.get_entity(SELECTED_SQUAD_MEMBER), 'delete', reset_selected_squad_member)
def _corpse_seen(entity, target_id): _target = entities.get_entity(target_id) if not entity['owner_id'] in _target['ai']['life_memory']: life.create_life_memory(_target, entity['owner_id']) _target['ai']['life_memory'][entity['owner_id']]['is_dead'] = True
def handle_collisions(entity, x, y, old_x, old_y): _pos = (entity['collidable']['x'], entity['collidable']['y']) _collision = False if _pos[0] < 0 or _pos[1] < 0 or _pos[0] >= constants.LEVEL_WIDTH or _pos[1] >= constants.LEVEL_HEIGHT: entities.trigger_event(entity, 'set_position', x=old_x, y=old_y) return if _pos in COLLISION_MAP: _objects = COLLISION_MAP[_pos]-set([entity['_id']]) if _objects: for entity_id in _objects: if entity_id in entity['collidable']['ignore_entities']: continue _entity = entities.get_entity(entity_id) _continue = False for entity_group in _entity['collidable']['ignore_groups']: if entity_group in _entity['_groups']: _continue = True break if _continue: continue if not _collision and entity['collidable']['clipping']: entities.trigger_event(entity, 'set_position', x=old_x, y=old_y) _collision = True entities.trigger_event(entity, 'collision_with_entity', entity_id=entity_id)
def draw_item_labels(): _camera_x, _camera_y = camera.X, camera.Y _width = display.get_surface('life')['width'] _height = display.get_surface('life')['height'] if settings.OBSERVER_MODE: _draw_items = entities.get_entity_group('items') else: _draw_items = [item for _items in PLAYER['ai']['visible_items'].values() for item in _items] for entity_id in _draw_items: if not entity_id in entities.ENTITIES: continue _entity = entities.get_entity(entity_id) if _entity['stats']['owner']: continue _x, _y = movement.get_position(_entity) _x -= _camera_x _y -= _camera_y if _x < 0 or _y < 0 or _x >= _width or _y >= _height: continue _label = _entity['stats']['name'] _render_x = numbers.clip(_x - len(_label)/2, 0, _width - len(_label)) _render_y = numbers.clip(_y + 2, 0, _height) if _render_y == _y: _render_y -= 1 display.write_string('ui', _render_x, _render_y, _label)
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 _locate_item_message(goal, member_id): _item_name = goal['item_name'] _member = entities.get_entity(member_id) _mission = entities.get_entity(goal['mission_id']) #TODO: Check if item visible and show something different if not items.get_items_matching(_member, {'name': _item_name}): goal['message'] = 'Find item.' entities.trigger_event(_member, 'uncomplete_goal', mission_id=goal['mission_id'], goal_id=goal['_id']) else: goal['message'] = 'Item found.' entities.trigger_event(_member, 'complete_goal', mission_id=goal['mission_id'], goal_id=goal['_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 own_item(entity, item_id): _item = entities.get_entity(item_id) _item['stats']['owner'] = entity['_id'] if _item['stats']['type'] == 'container': entity['inventory']['containers'][item_id] = {'items': [], 'weight': 0, 'max_weight': _item['stats']['max_weight']} entity['inventory']['items'].append(item_id)
def draw_squad_info(squad_id): _text_y_mod = 0 _squad = entities.get_entity(squad_id) for member_id in _squad['members']: _member = entities.get_entity(member_id) _health_string = '[OK]' _weapon = items.get_items_in_holder(_member, 'weapon') if _weapon: _weapon_name = '<%s>' % entities.get_entity( _weapon[0])['stats']['name'] else: _weapon_name = '<None>' _class = _member['stats']['class'] display.write_string('ui_bar', 1, 1 + _text_y_mod, _member['stats']['name'], fore_color=(204, 200, 204)) display.write_string('ui_bar', 2 + len(_member['stats']['name']), 1 + _text_y_mod, _health_string, fore_color=(200, 200, 34)) display.write_string('ui_bar', 3 + len(_member['stats']['name']) + len(_health_string), 1 + _text_y_mod, _weapon_name, fore_color=(0, 200, 34)) display.write_string('ui_bar', 4 + len(_member['stats']['name']) + len(_health_string) + len(_weapon_name), 1 + _text_y_mod, _class, fore_color=(200, 50, 200), back_color=(50, 12, 50)) _text_y_mod += 1
def tick(): if entities.get_entity_group('bullets'): for i in range(4): for entity_id in entities.get_entity_group('bullets'): entities.trigger_event(entities.get_entity(entity_id), 'tick') else: ai_flow.tick() for entity_id in entities.get_entity_group('effects'): entities.trigger_event(entities.get_entity(entity_id), 'tick') for entity_id in entities.get_entity_group('ui_effects'): entities.trigger_event(entities.get_entity(entity_id), 'tick') ai_visuals.reset_moved_entities() post_tick()
def create_mission_menu(entity, target_id): _menu = ui_menu.create(LAST_CLICKED_POS[0]-camera.X+2, LAST_CLICKED_POS[1]-camera.Y-4, title='Inquire') for mission_id in entity['missions']['active']: _mission = entities.get_entity(mission_id) ui_menu.add_title(_menu, _mission['title']) entities.trigger_event(_mission, 'get_details', menu=_menu, member_id=entity['_id'], target_id=target_id)
def leader_handle_raid_camp(entity, camp): for member_id in ai_squads.get_assigned_squad(entity)['members']: _member = entities.get_entity(member_id) entities.trigger_event(_member, 'squad_inform_raid', member_id=entity['_id'], camp=camp)
def update_squad_member_snapshot(entity, target_id): _target = entities.get_entity(target_id) if 'has_weapon' in _target['ai']['meta']: _snapshot = {'armed': _target['ai']['meta']['has_weapon']} else: _snapshot = {} entity['member_info'].update({target_id: _snapshot})
def handle_keyboard_input(): if controls.get_input_char_pressed('\t'): if settings.TICK_MODE == 'strategy': if ui_panel.ACTIVE_MENU: ui_panel.close() else: ui_panel.show_inventory(entity) else: _x, _y = movement.get_position(entity) camera.set_pos(_x - constants.MAP_VIEW_WIDTH / 2, _y - constants.MAP_VIEW_HEIGHT / 2) if controls.get_input_char_pressed('O'): settings.toggle_show_node_grid() elif controls.get_input_char_pressed('o'): settings.toggle_observer_mode() if controls.get_input_char_pressed('d'): _mx, _my = ui_cursor.get_map_position() for entity_id in entities.get_entity_group('life'): _entity = entities.get_entity(entity_id) if not numbers.distance( (_mx, _my), movement.get_position(_entity)): _x, _y = ui_cursor.get_screen_position() _menu = ui_menu.create(_x, _y, title='Debug') ui_menu.add_selectable(_menu, 'Show Metas', lambda: _show_metas(_entity)) ui_menu.add_selectable( _menu, 'Kill', lambda: entities.trigger_event(_entity, 'kill')) ui_menu.add_selectable(_menu, 'Overwatch', lambda: ai_debugger.register(_entity)) break if controls.get_input_char_pressed('l'): _x, _y = ui_cursor.get_screen_position() _mx, _my = ui_cursor.get_map_position() _weight = zones.get_active_weight_map()[_my, _mx] _menu = ui_menu.create(_x, _y, title='Tile Info') ui_menu.add_selectable( _menu, 'Warp', lambda: entities.trigger_event( entity, 'set_position', x=_mx, y=_my)) ui_menu.add_selectable( _menu, 'Light', lambda: effects.light(_mx, _my, 15, r=random.uniform(1.0, 1.5), g=random.uniform(1.0, 1.5), light_map='static_lighting')) ui_menu.add_selectable(_menu, 'Weight: %s' % _weight, lambda: _)