def register_with_squad(entity, squad_id): entity['ai']['squad'] = squad_id _squad = get_assigned_squad(entity) _squad['members'].add(entity['_id']) _squad['member_position_maps'][entity['_id']] = set() if not _squad['leader']: _squad['leader'] = entity['_id'] entity['ai']['meta']['is_squad_leader'] = _squad['leader'] == entity['_id'] entities.create_event(entity, 'squad_inform_raid') entities.register_event(_squad, 'meta_change', lambda e, **kwargs: entities.trigger_event(entity, 'set_meta', **kwargs)) #entities.register_event(entity, 'position_changed', lambda e, **kwargs: _squad['_id'] in entities.ENTITIES and entities.trigger_event(_squad, 'update_position_map', member_id=entity['_id'])) entities.register_event(entity, 'meta_change', lambda e, **kwargs: update_squad_member_snapshot(_squad, target_id=e['_id'])) entities.register_event(entity, 'meta_change', lambda e, **kwargs: update_group_status(_squad)) #TODO: Needs to be moved to a general area. Are squad members registering this? entities.register_event(entity, 'target_lost', ai_squad_logic.leader_handle_lost_target) entities.register_event(entity, 'target_lost', lambda e, **kwargs: update_combat_risk) entities.register_event(entity, 'target_found', lambda e, **kwargs: update_combat_risk) entities.register_event(entity, 'squad_inform_raid', ai_squad_logic.member_learn_raid) entities.register_event(entity, 'killed_by', lambda e, target_id, **kwargs: remove_member(_squad, entity['_id'])) entities.trigger_event(_squad, 'new_squad_member', target_id=entity['_id'])
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 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 _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 show_mission_details(entity, mission): entities.trigger_event(mission, 'get_briefing') _menu = ui_menu.create((constants.MAP_VIEW_WIDTH/2) - 10, (constants.MAP_VIEW_HEIGHT/2) - 10, title='Mission') ui_menu.add_selectable(_menu, 'Accept', lambda: accept_mission(entity, mission['_id'])) ui_menu.add_selectable(_menu, 'Decline', lambda: ui_dialog.delete(ui_dialog.ACTIVE_DIALOG))
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 create_action_menu(entity, x, y, on_path=False): _menu = ui_menu.create(ui_cursor.CURSOR['tile']['x']+2, ui_cursor.CURSOR['tile']['y']-1, title='Context') if items.get_items_in_holder(entity, 'weapon'): ui_menu.add_selectable(_menu, 'Shoot', lambda: select_target(x, y, on_path)) ui_menu.add_selectable(_menu, 'Reload', lambda: create_action_node(entity, x, y, 30, lambda: entities.trigger_event(entity, 'reload'), name='Reload', on_path=on_path)) ui_menu.add_selectable(_menu, 'Crouch', lambda: create_action_node(entity, x, y, 30, lambda: entities.trigger_event(entity, 'set_motion', motion='crouch'), name='Crouch', on_path=on_path)) ui_menu.add_selectable(_menu, 'Crawl', lambda: create_action_node(entity, x, y, 30, lambda: entities.trigger_event(entity, 'set_motion', motion='crawl'), name='Prone', on_path=on_path)) ui_menu.add_selectable(_menu, 'Stand', lambda: create_action_node(entity, x, y, 30, lambda: entities.trigger_event(entity, 'set_motion', motion='stand'), name='Stand', on_path=on_path))
def mutated_wild_dog(x, y, name): _entity = wild_dog(x, y, name) entities.trigger_event(_entity, 'set_char', char='D') entities.register_event(_entity, 'handle_corpse', _handle_mutated_wild_dog_corpse) return _entity
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 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 message(text, fore_color=(255, 255, 255), back_color=(10, 10, 10), time=-1, center=False, vert_center=False): global MESSAGES_ACTIVE _entity = entities.create_entity(group='ui_effects_freetick') if time == -1: _time = 30 * constants.SHOW_MESSAGES_FOR else: _time = time timers.register(_entity, use_system_event='draw') flags.register(_entity) entities.create_event(_entity, 'draw') entities.register_event(_entity, 'draw', _message_draw) entities.register_event(_entity, 'delete', _message_delete) entities.trigger_event(_entity, 'create_timer', time=_time, exit_callback=entities.delete_entity) entities.trigger_event(_entity, 'set_flag', flag='text', value=text) entities.trigger_event(_entity, 'set_flag', flag='index', value=MESSAGES_ACTIVE) entities.trigger_event(_entity, 'set_flag', flag='center', value=center) entities.trigger_event(_entity, 'set_flag', flag='vert_center', value=vert_center) MESSAGES_ACTIVE += 1 return _entity
def set_squad_meta(entity, meta, value): _old_value = entity['meta'][meta] if not value == _old_value: entities.trigger_event(entity, 'meta_change', meta=meta, value=value) entity['meta'][meta] = value
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 _create(x, y, name, char, weight, item_type, equip_to=None, fore_color=(255, 255, 255), kind=None): _entity = entities.create_entity(group='items') _entity['stats'] = {'name': name, 'display_name': name, 'type': item_type, 'weight': weight, 'owner': None, 'kind': kind, 'equip_to': equip_to, 'in_container': None} movement.register(_entity) flags.register(_entity) tile.register(_entity, surface='items', char=char, fore_color=fore_color) entities.create_event(_entity, 'collision_with_solid') entities.create_event(_entity, 'collision_with_entity') entities.create_event(_entity, 'get_interactions') entities.create_event(_entity, 'get_actions') entities.create_event(_entity, 'get_display_name') entities.create_event(_entity, 'seen') entities.register_event(_entity, 'get_display_name', get_display_name) entities.trigger_event(_entity, 'set_position', x=x, y=y) return _entity
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 member_handle_found_target(entity, target_id): for member_id in ai_squads.get_assigned_squad(entity)["members"]: if member_id == entity["_id"]: continue _member = entities.get_entity(member_id) entities.trigger_event(_member, "squad_inform_found_target", member_id=entity["_id"], target_id=target_id)
def _printer_move(entity): _x, _y = flags.get_flag(entity, 'text_pos') _move_direction = flags.get_flag(entity, 'move_direction') _vx, _vy = numbers.velocity(_move_direction, 1) _x += int(round(_vx)) _y += int(round(_vy)) entities.trigger_event(entity, 'set_flag', flag='text_pos', value=(_x, _y))
def set_respect(entity, respect): entity['stats']['respect'] = respect if respect <= 3: entities.trigger_event(entity, 'set_rank', rank='Newcomer') elif respect <= 10: entities.trigger_event(entity, 'set_rank', rank='Rookie')
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 recover(entity, time=15): #TODO: Placeholder #TODO: Show 'you stand back up' entities.trigger_event(entity, 'create_timer', time=time, exit_callback=lambda e: entities.trigger_event(e, 'recovering'), name='recovering')
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 clear_path(entity): for node_id in entity['node_grid']['path']: _last_node = entity['node_grid']['nodes'][node_id] entities.delete_entity(_last_node['node']) entities.trigger_event(entity, 'stop') entity['node_grid']['path'] = [] entity['node_grid']['nodes'] = {}
def add_respect(entity, target_id): _target = entities.get_entity(target_id) _respect = entity['stats']['respect'] _target_respect = _target['stats']['respect'] if _respect >= _target_respect: _target_respect *= 1 - numbers.clip((_respect - _target_respect) / 10.0, 0, 1) entities.trigger_event(entity, 'set_respect', respect = entity['stats']['respect'] + int(round(_target_respect)))
def find_cover(entity): _squad = entities.get_entity(ai_factions.FACTIONS[entity['ai']['faction']]['squads'][entity['ai']['squad']]) _cover_position = ai_squad_director.get_cover_position(_squad, entity['_id']) if not _cover_position or not numbers.distance(movement.get_position(entity), _cover_position): entities.trigger_event(entity, 'finish_turn') return movement.walk_to_position(entity, _cover_position[0], _cover_position[1], zones.get_active_astar_map(), zones.get_active_weight_map())
def member_handle_failed_target_search(entity, target_id): for member_id in ai_squads.get_assigned_squad(entity)["members"]: if member_id == entity["_id"]: continue _member = entities.get_entity(member_id) entities.trigger_event(_member, "squad_inform_failed_search", member_id=entity["_id"], target_id=target_id) entity["ai"]["life_memory"][target_id]["searched_for"] = True
def handle_start_of_turn(entity, squad_id): update_combat_risk(entity) update_group_status(entity) entities.trigger_event(entity, 'update_position_map') if entity['faction'] == 'Rogues': settings.set_tick_mode('strategy') else: settings.set_tick_mode('normal')
def push(entity, x, y, time=-1, name='move'): #TODO: Placeholder. See note in controls for player movement if time == -1: raise Exception('Outdated push (still using speed)') entities.trigger_event(entity, 'create_timer', time=time, exit_callback=lambda e: entities.trigger_event(e, 'push', x=x, y=y), name=name)
def logic(): #for faction in FACTIONS.values(): # for squad in faction['squads'].values(): # entities.trigger_event(squad, 'create') for faction in FACTIONS.values(): for squad_id in faction['squads'].values(): _squad = entities.get_entity(squad_id) entities.trigger_event(_squad, 'logic')
def _bullet_tick(entity): _direction = movement.get_direction(entity) entities.trigger_event(entity, 'push_tank', direction=_direction) _x, _y = movement.get_position(entity) _distance = numbers.distance((_x, _y), entity['start_position']) _starting_target_distance = numbers.distance(entity['start_position'], entity['end_position']) if _distance > _starting_target_distance + (12 - (entity['speed'] * 2)): entities.delete_entity(entity)
def get_and_hold_item(entity, item_id): _item = entities.get_entity(item_id) if timers.has_timer_with_name(entity, 'Getting %s' % _item['stats']['name'], fuzzy=True): return entities.trigger_event(entity, 'create_timer', time=30, name='Getting %s' % _item['stats']['name'], exit_callback=lambda _: _get_and_hold_item(entity, item_id))
def register(entity, health, speed, vision, class_name='Gunner', respect=1, accuracy=1.0, mobility=80, explosives=70, intelligence=90, action_points=100, smgs=50, rifles=50, pistols=50, name='Unknown', kind='unknown'): _stats = {'health': health, 'max_health': health, 'speed': speed, 'max_speed': speed, 'pain': 0, 'accuracy': accuracy, 'max_accuracy': accuracy, 'vision': vision, 'max_vision': vision, 'action_points': action_points, 'action_points_max': action_points, 'intelligence': intelligence, 'skill_points': int(round(100 * (intelligence/100.0))), 'mobility': mobility, 'max_mobility': mobility, 'class': class_name, 'smgs': smgs, 'rifles': rifles, 'pistols': pistols, 'explosives': explosives, 'name': name, 'kind': kind, 'last_engaged': None, 'respect': 0, 'rank': 'Unknown', 'last_rank': 'Unknown', 'kills': 0} entity['stats'] = _stats entities.create_event(entity, 'kill') entities.create_event(entity, 'killed_by') entities.create_event(entity, 'log_kill') entities.create_event(entity, 'heal') entities.create_event(entity, 'haste') entities.create_event(entity, 'slow') entities.create_event(entity, 'set_respect') entities.create_event(entity, 'set_rank') entities.create_event(entity, 'get_mobility') entities.create_event(entity, 'get_vision') entities.create_event(entity, 'get_accuracy') entities.register_event(entity, 'kill', kill) entities.register_event(entity, 'set_respect', set_respect) entities.register_event(entity, 'set_rank', set_rank) entities.register_event(entity, 'log_kill', add_respect) entities.register_event(entity, 'log_kill', log_kill) entities.register_event(entity, 'save', save) entities.trigger_event(entity, 'set_respect', respect=respect)
def member_learn_lost_target(entity, member_id, target_id): if not target_id in entity['ai']['visible_life']: entity['ai']['life_memory'][target_id]['is_lost'] = True entity['ai']['life_memory'][target_id]['searched_for'] = False return _sender = entities.get_entity(member_id) entities.trigger_event( _sender, 'update_target_memory', target_id=target_id, key='last_seen_at', value=entity['ai']['life_memory'][target_id]['last_seen_at'][:])
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 fade_in(): global NEED_FADE_IN NEED_FADE_IN = False entities.trigger_event(FADER, 'create_timer', time=7, repeat=FADE_TICKS, repeat_callback=lambda e: _fade_in(), exit_callback=lambda e: entities.trigger_event( e, 'create_timer', time=constants.FPS * SHOW_MESSAGE_TIME, callback=lambda ee: _draw_message()))
def _muzzle_flash_fade(entity): entity['alpha'] -= 0.07 _x, _y = movement.get_position(entity) _color = list(display.get_color_at('tiles', _x, _y)) _color[0] = numbers.interp_velocity(_color[0], (255, 255, 255), entity['alpha']) _color[1] = numbers.interp_velocity(_color[1], (255, 255, 255), entity['alpha']) for c in range(len(_color)): for i in range(len(_color)): _color[c][i] = int((round(_color[c][i]))) entities.trigger_event(entity, 'set_fore_color', color=_color[0]) entities.trigger_event(entity, 'set_back_color', color=_color[1])
def find_cover(entity): _squad = entities.get_entity(ai_factions.FACTIONS[entity['ai']['faction']] ['squads'][entity['ai']['squad']]) _cover_position = ai_squad_director.get_cover_position( _squad, entity['_id']) if not _cover_position or not numbers.distance( movement.get_position(entity), _cover_position): entities.trigger_event(entity, 'finish_turn') return movement.walk_to_position(entity, _cover_position[0], _cover_position[1], zones.get_active_astar_map(), zones.get_active_weight_map())
def complete_goal(entity, mission_id, goal_id): if entity['missions']['active'][mission_id]['goals'][goal_id]['complete']: return entity['missions']['active'][mission_id]['goals'][goal_id][ 'complete'] = True for goal_id in entity['missions']['active'][mission_id]['goals']: if not entity['missions']['active'][mission_id]['goals'][goal_id][ 'complete']: break else: entities.trigger_event(entity, 'complete_mission', mission_id=mission_id)
def register(entity, faction): if not faction in FACTIONS: raise Exception('Invalid faction: %s' % faction) #TODO: Move this to ai_squads at some point entities.register_event(entity, 'delete', cleanup) entity['ai']['faction'] = faction entity['ai']['squad'] = -1 FACTIONS[entity['ai']['faction']]['members'].add(entity['_id']) entities.trigger_event(FACTIONS[entity['ai']['faction']], 'add_member', member_id=entity['_id'])
def give_item(entity, target_id, item_match): _items = items.get_items_matching(entity, item_match) if not _items: entities.trigger_event(entity, 'receive_memory', member_id=entity['_id'], memory={}, message='You got the item yet?') return None entities.trigger_event(entity, 'give_item', item_id=_items[0], target_id=target_id)
def _counter_2d_tick(entity): for i in range(int(entity['passes'])): if entity['x']['current'] < entity['x']['max']-1: entity['callback'](entity['x']['current'], entity['y']['current']) if entity['y']['current'] < entity['y']['max']-1: entity['y']['current'] += 1 else: entity['y']['current'] = 0 entity['x']['current'] += 1 else: entity['callback'](entity['x']['current'], entity['y']['current']) entities.trigger_event(entity, 'finish') return entities.delete_entity(entity)
def delete(menu): global ACTIVE_MENU, DELAY entities.delete_entity(menu) if ACTIVE_MENU == menu: _menus = entities.get_entity_group('ui_menus') if _menus: ACTIVE_MENU = entities.get_entity(_menus[len(_menus) - 1]) entities.trigger_event(ACTIVE_MENU, 'reactivated') else: ACTIVE_MENU = None DELAY = 30
def register_combat(entity, target_id): _target = entities.get_entity(target_id) _squad_1 = ai_squads.get_assigned_squad(entity) _squad_2 = ai_squads.get_assigned_squad(_target)['_id'] FIGHTING_SQUADS.add(_squad_1['_id']) FIGHTING_SQUADS.add(_squad_2) if not settings.TURN_QUEUE: entities.trigger_event(FLOW, 'start_of_turn', squad_id=_squad_1['_id']) if not _squad_1['_id'] in settings.TURN_QUEUE: settings.TURN_QUEUE.append(_squad_1['_id']) if not _squad_2 in settings.TURN_QUEUE: settings.TURN_QUEUE.append(_squad_2)
def boot(): global CURSOR CURSOR = entities.create_entity(group='systems') tile.register(CURSOR, surface='ui') events.register_event('camera', logic) events.register_event('mouse_moved', handle_mouse_movement) events.register_event('mouse_pressed', handle_mouse_pressed) events.register_event('input', handle_keyboard_input) events.register_event('draw', lambda *args: entities.trigger_event(CURSOR, 'draw')) entities.trigger_event(CURSOR, 'set_position', x=constants.MAP_VIEW_WIDTH / 2, y=constants.MAP_VIEW_HEIGHT / 2)
def set_position(entity, x, y): _old_x = entity['movement']['x'] _old_y = entity['movement']['y'] entity['movement']['x'] = x entity['movement']['y'] = y entities.trigger_event(entity, 'set_position', x=int(round(x)), y=int(round(y)), _ban_events=[set_position]) entities.trigger_event(entity, 'position_changed', x=int(round(x)), y=int(round(y)), old_x=_old_x, old_y=_old_y)
def frag_grenade_explode(entity): _x, _y = movement.get_position(entity) _damage = entity['damage'] _size = 3 * int(round((_damage * .01))) effects.explosion(_x, _y, _size) for entity_id in entities.get_entity_group('life'): _entity = entities.get_entity(entity_id) _distance = numbers.distance((_x, _y), movement.get_position(_entity)) if _distance - 1 > _size or not life.can_see_position( _entity, (_x, _y)): continue entities.trigger_event(_entity, 'hit', projectile=entity, damage_mod=1 - ((_distance - 1) / float(_size)))
def _vapor_fade(entity): entity['alpha'] -= entity['fade_rate'] if entity['alpha'] <= 0: entities.delete_entity(entity) return _x, _y = movement.get_position(entity) _color = list(display.get_color_at('tiles', _x, _y)) _color[0] = numbers.interp_velocity(_color[0], (255, 255, 255), entity['alpha']) _color[1] = numbers.interp_velocity(_color[1], (255, 255, 255), entity['alpha']) for c in range(len(_color)): for i in range(len(_color)): _color[c][i] = int((round(_color[c][i]))) entities.trigger_event(entity, 'set_fore_color', color=_color[0]) entities.trigger_event(entity, 'set_back_color', color=_color[1])
def get_accuracy(entity, weapon_id): entity['stats']['accuracy'] = entity['stats']['max_accuracy'] _weapon = entities.get_entity(weapon_id) entities.trigger_event(entity, 'get_accuracy') _weapon_accuracy = flags.get_flag(_weapon, 'accuracy') if _weapon['stats']['kind'] == 'pistol': _weapon_accuracy *= 1 + (1 - (entity['stats']['pistols'] / 100.0)) elif _weapon['stats']['kind'] == 'rifle': _weapon_accuracy *= 1 + (1 - (entity['stats']['rifles'] / 100.0)) elif _weapon['stats']['kind'] == 'explosive': _weapon_accuracy *= 1 + (1 - (entity['stats']['explosives'] / 100.0)) else: raise Exception('Invalid gun type.') return int(round(_weapon_accuracy * entity['stats']['accuracy']))
def select_target(x, y, on_path): global SELECTING_TARGET_CALLBACK SELECTING_TARGET_CALLBACK = lambda entity, target: create_action_node( entity, x, y, 5, lambda: entities.trigger_event(entity, 'shoot', target_id=target), name='Shoot', on_path=on_path)
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 _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 _cleanup(entity): if entity['_id'] in ONLINE_ENTITIES: ONLINE_ENTITIES.remove(entity['_id']) elif entity['_id'] in OFFLINE_ENTITIES: OFFLINE_ENTITIES.remove(entity['_id']) _x, _y = movement.get_position(entity) if flags.has_flag(entity, 'fire_data'): _fire_data = flags.get_flag(entity, 'fire_data') _node = entities.get_entity( zones.get_active_node_grid()[_fire_data['node']]) entities.trigger_event(_node, 'set_flag', flag='owner', value=None) flags.delete_flag(entity, 'fire_data') _item_id = items.corpse(_x, _y, entity['tile']['char'], entity['_id'])['_id'] entities.trigger_event(entity, 'handle_corpse', corpse_id=_item_id)
def _push(entity, x, y): entity['movement']['next_x'] = entity['movement']['x'] + x entity['movement']['next_y'] = entity['movement']['y'] + y entities.trigger_event(entity, 'check_next_position') _nx = entity['movement']['next_x'] _ny = entity['movement']['next_y'] if entity['movement']['collisions']: _solids = [ get_position_via_id(p) for p in entities.get_entity_group('life') if not p == entity['_id'] ] if (_nx, _ny) in _solids: entity['movement']['path']['refresh'] = True return set_position(entity, _nx, _ny)
def smoke(x, y, amount, start_amount=0.0, decay_amount=1.0): _blood = _create(x, y) _x, _y = (int(round(x)), int(round(y))) _fore_color = random.choice([constants.BLACK_1, constants.BLACK_2, constants.BLACK_3]) _back_color = random.choice([constants.BLACK_1, constants.BLACK_2, constants.BLACK_3]) amount = numbers.clip(amount + random.uniform(-.1, .1), 0, 1) entities.trigger_event(_blood, 'set_char', char=' ') flags.register(_blood) flags.set_flag(_blood, 'alpha', value=start_amount) flags.set_flag(_blood, 'decay', value=decay_amount) flags.set_flag(_blood, 'alpha_mode', value=0) flags.set_flag(_blood, 'alpha_max', value=amount) flags.set_flag(_blood, 'fore_color', value=_fore_color) flags.set_flag(_blood, 'back_color', value=_back_color) _color = list(display.get_color_at('tiles', _x, _y)) _color[0] = numbers.interp_velocity(_color[0], _fore_color, amount) _color[1] = numbers.interp_velocity(_color[1], _back_color, amount) for c in range(len(_color)): for i in range(len(_color)): _color[c][i] = int((round(_color[c][i]))) entities.trigger_event(_blood, 'set_fore_color', color=_color[0]) entities.trigger_event(_blood, 'set_back_color', color=_color[1]) entities.register_event(_blood, 'tick', _tick_smoke) return _blood
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 _tick_fire(entity): _x, _y = movement.get_position(entity) _alpha = flags.get_flag(entity, 'alpha') _alpha += random.uniform(-.3, .3) _alpha = numbers.clip(_alpha, 0, 1) if not _alpha: #char(_x, _y, numbers.clip(flags.get_flag(entity, 'alpha_max') - random.uniform(.1, .2), 0, 1)) entities.delete_entity(entity) return #entities.trigger_event(entity, 'set_char', char=random.choice(['*', '&', '%'])) _color = list(display.get_color_at('tiles', _x, _y)) _color[0] = numbers.interp_velocity(_color[0], random.choice([constants.FIRE_1, constants.FIRE_2, constants.FIRE_3]), _alpha) _color[1] = numbers.interp_velocity(_color[1], random.choice([constants.FIRE_1, constants.FIRE_2, constants.FIRE_3]), _alpha) for c in range(len(_color)): for i in range(len(_color)): _color[c][i] = int((round(_color[c][i]))) entities.trigger_event(entity, 'set_fore_color', color=_color[0]) entities.trigger_event(entity, 'set_back_color', color=_color[1]) entities.trigger_event(entity, 'set_flag', flag='alpha', value=_alpha)
def _explosive_tick(entity): _direction = movement.get_direction(entity) entities.trigger_event(entity, 'push_tank', direction=_direction) _x, _y = movement.get_position(entity) _distance = numbers.distance((_x, _y), entity['end_position']) _starting_target_distance = numbers.distance(entity['start_position'], entity['end_position']) if _distance <= entity['accuracy'] * 2.5: entity['slow_down'] = True if entity['slow_down']: entity['speed'] = numbers.clip(entity['speed'] * 1.2, 0, 40) if entity['speed'] < 40: entities.trigger_event(entity, 'create_timer', time=int(round(entity['speed'])), name='movement', exit_callback=_explosive_tick) else: entities.trigger_event(entity, 'activate_explosive')
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 handle_pain(entity, limb, damage): _pain = int(round(damage * .75)) entity['stats']['pain'] += _pain if _pain > 65 and not timers.has_timer_with_name(entity, 'passout'): entities.trigger_event(entity, 'stop') entities.trigger_event(entity, 'clear_timers') entities.trigger_event(entity, 'create_timer', time=(_pain - 65) * 6, exit_callback=lambda e: entities.trigger_event( e, 'stop_animation'), name='passout') entities.trigger_event(entity, 'animate', animation=['s', '@@'], repeat=-1)
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 add_mission(entity, mission_id, make_active=True): _mission = entities.get_entity(mission_id) entity['missions'][('in' * (not make_active)) + 'active'][mission_id] = { 'goals': { k: { 'complete': False, 'cleanup_events': [] } for k in _mission['goals'] } } _mission['members'].append(entity['_id']) if make_active: entities.trigger_event(_mission, 'member_added', member_id=entity['_id']) logging.info('Adding entity %s to mission %s' % (entity['_id'], mission_id))