def _walk_path(entity): if not entity['movement']['path']['positions']: return False if timers.has_timer_with_name(entity, 'move') or timers.has_timer_with_name( entity, 'move', fuzzy=True): return False if entity['movement']['path']['refresh']: set_path(entity, [get_position(entity)]) _next_pos = entity['movement']['path']['positions'].pop(0) _x, _y = get_position(entity) _d_x, _d_y = _next_pos[0] - _x, _next_pos[1] - _y if not _d_x in [-1, 0, 1] or not _d_y in [-1, 0, 1]: _clear_movement(entity) return if not entity['movement']['path']['positions']: entity['movement']['path']['destination'] = None push(entity, x=_d_x, y=_d_y, name='move', time=get_override_speed(entity))
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 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 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 reload_weapon(entity): if timers.has_timer_with_name(entity, 'Reloading'): return _weapon = items.get_items_in_holder(entity, 'weapon')[0] _ammo = items.get_items_matching(entity, {'type': 'ammo'})[0] entities.trigger_event(entity, 'create_timer', time=30, name='Reloading', exit_callback=lambda _: _reload_weapon(entity, _weapon, _ammo))
def reload_weapon(entity): if timers.has_timer_with_name(entity, 'Reloading'): return _weapon = items.get_items_in_holder(entity, 'weapon')[0] _ammo = items.get_items_matching(entity, {'type': 'ammo'})[0] entities.trigger_event( entity, 'create_timer', time=30, name='Reloading', exit_callback=lambda _: _reload_weapon(entity, _weapon, _ammo))
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 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 _walk_path(entity): if not entity['movement']['path']['positions']: return False if timers.has_timer_with_name(entity, 'move') or timers.has_timer_with_name(entity, 'move', fuzzy=True): return False if entity['movement']['path']['refresh']: set_path(entity, [get_position(entity)]) _next_pos = entity['movement']['path']['positions'].pop(0) _x, _y = get_position(entity) _d_x, _d_y = _next_pos[0]-_x, _next_pos[1]-_y if not _d_x in [-1, 0, 1] or not _d_y in [-1, 0, 1]: _clear_movement(entity) return if not entity['movement']['path']['positions']: entity['movement']['path']['destination'] = None push(entity, x=_d_x, y=_d_y, name='move', time=get_override_speed(entity))
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 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 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 _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 loop(): global PLAYER_HAS_SHOOT_TIMER events.trigger_event('input') if not settings.TICK_MODE == 'strategy' and not ( (ui_dialog.ACTIVE_DIALOG and ui_director.PAUSE) or ui_menu.ACTIVE_MENU or ui_director.PAUSE): _has_action = False _check_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) _check_life.add(member_id) _check_life.update([ i for i in _member['ai']['life_memory'] if _member['ai']['life_memory'][i]['can_see'] and i in entities.ENTITIES ]) _check_life = list(_check_life) #_check_life = #_check_life.append(PLAYER['_id']) for entity_id in _check_life: if timers.has_timer_with_name(entities.get_entity(entity_id), 'shoot'): _has_action = True break if _has_action: _ticks_per_tick = 1 else: _ticks_per_tick = settings.PLAN_TICK_RATE for _ in range(_ticks_per_tick): if settings.TICK_MODE == 'strategy': break ai_flow.logic() events.trigger_event('logic') tick() free_tick() else: ai_flow.logic() free_tick() if pathfinding.wait_for_astar(): pass if not handle_input(): return False events.trigger_event('tick') events.trigger_event('camera') draw() return True
def tick(): if settings.TURN_QUEUE: _squads = [settings.TURN_QUEUE[0]] else: _squads = entities.get_entity_group('squads') _found_able_player = False for squad_id in entities.get_entity_group('squads'): _squad = entities.get_entity(squad_id) _break = False if not _squad['faction'] == 'Rogues': continue for member_id in _squad['members']: _entity = entities.get_entity(member_id) if _entity['ai']['is_npc']: continue if timers.has_timer_with_name(_entity, 'shoot') or _entity['movement']['path']['positions'] or timers.has_timer_with_name(_entity, 'move'): _break = True break _found_able_player = True if _break: break else: if _found_able_player: settings.set_tick_mode('strategy') for squad_id in _squads: _squad = entities.get_entity(squad_id) _waiting = False #if not _squad['faction'] == 'Rogues': # settings.set_tick_mode('normal') for entity_id in _squad['members']: _entity = entities.get_entity(entity_id) if not settings.TURN_QUEUE: _entity['stats']['action_points'] = _entity['stats']['action_points_max'] if _entity['ai']['is_npc']: continue if _entity['stats']['action_points'] <= 0: continue _had_action = False if timers.has_timer_with_name(_entity, 'shoot') or _entity['movement']['path']['positions'] or timers.has_timer_with_name(_entity, 'move'): _had_action = True elif _entity['ai']['is_player']: _waiting = True continue entities.trigger_event(_entity, 'tick') if _had_action and not timers.has_timer_with_name(_entity, 'shoot') and not _entity['movement']['path']['positions'] and not timers.has_timer_with_name(_entity, 'move') and _entity['stats']['action_points'] > 0: if _entity['ai']['is_player'] and (ui_squad_control.is_squad_member_selected() and _entity == ui_squad_control.get_selected_squad_member()): settings.set_tick_mode('strategy') break if _entity['ai']['is_player'] and _entity['stats']['action_points'] <= 0: ui_squad_control.reset_selected_squad_member() settings.set_tick_mode('strategy') if not _entity['movement']['path']['positions'] and not timers.has_timer_with_name(_entity, 'shoot') and not timers.has_timer_with_name(_entity, 'move'): _entity['stats']['action_points'] -= constants.IDLE_COST if _entity['stats']['action_points'] <= 0:# and list(_squad['members']).index(entity_id)+1 == len(_squad['members']): entities.trigger_event(_squad, 'update_position_map') #print _entity['stats']['name'], _entity['stats']['action_points'] break else: if _entity['ai']['is_player'] and not _waiting: settings.set_tick_mode('normal') print 'Normal...'
def handle_mouse_pressed(entity, x, y, button): global DRAGGING_NODE, LAST_CLICKED_POS, SELECTING_TARGET_CALLBACK if ui_menu.get_active_menu() or ui_menu.DELAY: return if timers.has_timer_with_name(entity, 'passout'): return _x = x+camera.X _y = y+camera.Y if button == 1: if DRAGGING_NODE: DRAGGING_NODE = None elif not (_x, _y) in zones.get_active_solids(entity): if not DRAGGING_NODE: for entity_id in [t for t in entity['ai']['visible_life'] if entity['ai']['life_memory'][t]['can_see']]: if entity['_id'] == entity_id: continue _entity = entities.get_entity(entity_id) _tx, _ty = movement.get_position(_entity) if (_x, _y) == (_tx, _ty): if SELECTING_TARGET_CALLBACK: SELECTING_TARGET_CALLBACK(entity, entity_id) SELECTING_TARGET_CALLBACK = None else: LAST_CLICKED_POS = (_x, _y) create_life_interact_menu(entity, entity_id) return else: for entity_id in entities.get_entity_group('contexts'): _entity = entities.get_entity(entity_id) if not _entity['callback']: continue if (_entity['tile']['x'], _entity['tile']['y']) == (_x, _y): _entity['callback'](x+2, y-3) return else: for entity_id in list(entity['ai']['targets'] - entity['ai']['visible_life']): _tx, _ty = entity['ai']['life_memory'][entity_id]['last_seen_at'] if (_tx, _ty-2) == (_x, _y): ui_dialog.create(x + 2, y - 3, '%s - Last seen <time>' % entities.get_entity(entity_id)['stats']['name']) return else: for entity_id in entities.get_entity_group('items'): _item = entities.get_entity(entity_id) if _item['stats']['owner']: continue if (_x, _y) == movement.get_position(_item): create_item_menu(entity, _item, _x, _y) return create_walk_node(entity, _x, _y, clear=True) return for node in entity['node_grid']['nodes'].values(): if (_x, _y) == (node['node']['x'], node['node']['y']): DRAGGING_NODE = node entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 0)) break if (_x, _y) in node['node']['path']: if not (_x, _y) in node['node']['busy_pos']: LAST_CLICKED_POS = (_x, _y) create_action_menu(entity, LAST_CLICKED_POS[0], LAST_CLICKED_POS[1], on_path=True) else: LAST_CLICKED_POS = None return elif button == 2: if DRAGGING_NODE: entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 255)) DRAGGING_NODE = None else: for node in entity['node_grid']['nodes'].values(): if (_x, _y) == (node['node']['x'], node['node']['y']): entity['node_grid']['path'].remove(node['node']['_id']) entities.delete_entity(node['node']) redraw_path(entity) del entity['node_grid']['nodes'][node['node']['_id']] if not entity['node_grid']['nodes']: clear_path(entity) break else: create_walk_node(entity, _x, _y)
def _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 _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 tick(): if settings.TURN_QUEUE: _squads = [settings.TURN_QUEUE[0]] else: _squads = entities.get_entity_group('squads') _found_able_player = False for squad_id in entities.get_entity_group('squads'): _squad = entities.get_entity(squad_id) _break = False if not _squad['faction'] == 'Rogues': continue for member_id in _squad['members']: _entity = entities.get_entity(member_id) if _entity['ai']['is_npc']: continue if timers.has_timer_with_name( _entity, 'shoot') or _entity['movement']['path'][ 'positions'] or timers.has_timer_with_name( _entity, 'move'): _break = True break _found_able_player = True if _break: break else: if _found_able_player: settings.set_tick_mode('strategy') for squad_id in _squads: _squad = entities.get_entity(squad_id) _waiting = False #if not _squad['faction'] == 'Rogues': # settings.set_tick_mode('normal') for entity_id in _squad['members']: _entity = entities.get_entity(entity_id) if not settings.TURN_QUEUE: _entity['stats']['action_points'] = _entity['stats'][ 'action_points_max'] if _entity['ai']['is_npc']: continue if _entity['stats']['action_points'] <= 0: continue _had_action = False if timers.has_timer_with_name( _entity, 'shoot') or _entity['movement']['path'][ 'positions'] or timers.has_timer_with_name( _entity, 'move'): _had_action = True elif _entity['ai']['is_player']: _waiting = True continue entities.trigger_event(_entity, 'tick') if _had_action and not timers.has_timer_with_name( _entity, 'shoot') and not _entity['movement']['path'][ 'positions'] and not timers.has_timer_with_name( _entity, 'move') and _entity['stats']['action_points'] > 0: if _entity['ai']['is_player'] and ( ui_squad_control.is_squad_member_selected() and _entity == ui_squad_control.get_selected_squad_member()): settings.set_tick_mode('strategy') break if _entity['ai'][ 'is_player'] and _entity['stats']['action_points'] <= 0: ui_squad_control.reset_selected_squad_member() settings.set_tick_mode('strategy') if not _entity['movement']['path'][ 'positions'] and not timers.has_timer_with_name( _entity, 'shoot') and not timers.has_timer_with_name( _entity, 'move'): _entity['stats']['action_points'] -= constants.IDLE_COST if _entity['stats'][ 'action_points'] <= 0: # and list(_squad['members']).index(entity_id)+1 == len(_squad['members']): entities.trigger_event(_squad, 'update_position_map') #print _entity['stats']['name'], _entity['stats']['action_points'] break else: if _entity['ai']['is_player'] and not _waiting: settings.set_tick_mode('normal') print 'Normal...'
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 loop(): global PLAYER_HAS_SHOOT_TIMER events.trigger_event('input') if not settings.TICK_MODE == 'strategy' and not ((ui_dialog.ACTIVE_DIALOG and ui_director.PAUSE) or ui_menu.ACTIVE_MENU or ui_director.PAUSE): _has_action = False _check_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) _check_life.add(member_id) _check_life.update([i for i in _member['ai']['life_memory'] if _member['ai']['life_memory'][i]['can_see'] and i in entities.ENTITIES]) _check_life = list(_check_life) #_check_life = #_check_life.append(PLAYER['_id']) for entity_id in _check_life: if timers.has_timer_with_name(entities.get_entity(entity_id), 'shoot'): _has_action = True break if _has_action: _ticks_per_tick = 1 else: _ticks_per_tick = settings.PLAN_TICK_RATE for _ in range(_ticks_per_tick): if settings.TICK_MODE == 'strategy': break ai_flow.logic() events.trigger_event('logic') tick() free_tick() else: ai_flow.logic() free_tick() if pathfinding.wait_for_astar(): pass if not handle_input(): return False events.trigger_event('tick') events.trigger_event('camera') draw() return True
def handle_mouse_pressed(entity, x, y, button): global DRAGGING_NODE, LAST_CLICKED_POS, SELECTING_TARGET_CALLBACK if ui_menu.get_active_menu() or ui_menu.DELAY: return if timers.has_timer_with_name(entity, 'passout'): return _x = x + camera.X _y = y + camera.Y if button == 1: if DRAGGING_NODE: DRAGGING_NODE = None elif not (_x, _y) in zones.get_active_solids(entity): if not DRAGGING_NODE: for entity_id in [ t for t in entity['ai']['visible_life'] if entity['ai']['life_memory'][t]['can_see'] ]: if entity['_id'] == entity_id: continue _entity = entities.get_entity(entity_id) _tx, _ty = movement.get_position(_entity) if (_x, _y) == (_tx, _ty): if SELECTING_TARGET_CALLBACK: SELECTING_TARGET_CALLBACK(entity, entity_id) SELECTING_TARGET_CALLBACK = None else: LAST_CLICKED_POS = (_x, _y) create_life_interact_menu(entity, entity_id) return else: for entity_id in entities.get_entity_group('contexts'): _entity = entities.get_entity(entity_id) if not _entity['callback']: continue if (_entity['tile']['x'], _entity['tile']['y']) == (_x, _y): _entity['callback'](x + 2, y - 3) return else: for entity_id in list(entity['ai']['targets'] - entity['ai']['visible_life']): _tx, _ty = entity['ai']['life_memory'][entity_id][ 'last_seen_at'] if (_tx, _ty - 2) == (_x, _y): ui_dialog.create( x + 2, y - 3, '%s - Last seen <time>' % entities.get_entity( entity_id)['stats']['name']) return else: for entity_id in entities.get_entity_group( 'items'): _item = entities.get_entity(entity_id) if _item['stats']['owner']: continue if (_x, _y) == movement.get_position(_item): create_item_menu(entity, _item, _x, _y) return create_walk_node(entity, _x, _y, clear=True) return for node in entity['node_grid']['nodes'].values(): if (_x, _y) == (node['node']['x'], node['node']['y']): DRAGGING_NODE = node entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 0)) break if (_x, _y) in node['node']['path']: if not (_x, _y) in node['node']['busy_pos']: LAST_CLICKED_POS = (_x, _y) create_action_menu(entity, LAST_CLICKED_POS[0], LAST_CLICKED_POS[1], on_path=True) else: LAST_CLICKED_POS = None return elif button == 2: if DRAGGING_NODE: entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 255)) DRAGGING_NODE = None else: for node in entity['node_grid']['nodes'].values(): if (_x, _y) == (node['node']['x'], node['node']['y']): entity['node_grid']['path'].remove(node['node']['_id']) entities.delete_entity(node['node']) redraw_path(entity) del entity['node_grid']['nodes'][node['node']['_id']] if not entity['node_grid']['nodes']: clear_path(entity) break else: create_walk_node(entity, _x, _y)