def handle_member_killed(entity, member_id, target_id): _member = entities.get_entity(member_id) _target = entities.get_entity(target_id) _target_faction = _target['ai']['faction'] if _target_faction == _member['ai']['faction']: logging.info('Friendly fire resulted in death: %s' % _target_faction) return if not _target_faction in entity['enemies']: entity['relations'][_target_faction] = 0 entity['enemies'].append(_target_faction) logging.info('%s is now hostile to %s: Murder' % (_member['ai']['faction'], _target_faction)) if flags.has_flag(_target, 'is_player') and flags.get_flag(_target, 'is_player'): effects.message('%s now see you as hostile.' % _member['ai']['faction'])
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 handle_member_killed(entity, member_id, target_id): _member = entities.get_entity(member_id) _target = entities.get_entity(target_id) _target_faction = _target['ai']['faction'] if _target_faction == _member['ai']['faction']: logging.info('Friendly fire resulted in death: %s' % _target_faction) return if not _target_faction in entity['enemies']: entity['relations'][_target_faction] = 0 entity['enemies'].append(_target_faction) logging.info('%s is now hostile to %s: Murder' % (_member['ai']['faction'], _target_faction)) if flags.has_flag(_target, 'is_player') and flags.get_flag( _target, 'is_player'): effects.message('%s now see you as hostile.' % _member['ai']['faction'])
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 _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 search_for_target(entity): _lost_targets = entity['ai']['targets_to_search'] _inside = zones.get_active_inside_positions() if not _lost_targets: print 'Trying to search with no lost targets' return _closest_target = {'distance': 0, 'target_id': None} for target_id in _lost_targets: _memory = entity['ai']['life_memory'][target_id] _distance = numbers.distance(movement.get_position(entity), _memory['last_seen_at']) if not _closest_target['target_id'] or _distance < _closest_target['distance']: _closest_target['target_id'] = target_id _closest_target['distance'] = _distance _target = entities.get_entity(_closest_target['target_id']) _solids = zones.get_active_solids(entity) if flags.has_flag(entity, 'search_nodes'): _search_for_target(entity, _target['_id']) return _x, _y = movement.get_position(entity) _tx, _ty = entity['ai']['life_memory'][_target['_id']]['last_seen_at'] _nodes_to_search = {} if entity['ai']['life_memory'][_target['_id']]['last_seen_velocity']: _vx, _vy = entity['ai']['life_memory'][_target['_id']]['last_seen_velocity'] _tx + _vx*6 _ty + _vy*6 entities.trigger_event(entity, 'set_flag', flag='search_nodes', value=_nodes_to_search) for node_x, node_y in zones.get_active_node_grid(): _distance = numbers.distance((_tx, _ty), (node_x, node_y)) if _distance >= 30: continue if not (node_x, node_y) in _inside: continue _continue = False for pos in shapes.line((_tx, _ty), (node_x, node_y)): if pos in _solids: _continue = True break if _continue: continue if _distance in _nodes_to_search: if not (node_x, node_y) in _nodes_to_search[_distance]: _nodes_to_search[_distance].append((node_x, node_y)) else: _nodes_to_search[_distance] = [(node_x, node_y)]
def _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 _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 search_for_target(entity): _lost_targets = entity['ai']['targets_to_search'] _inside = zones.get_active_inside_positions() if not _lost_targets: print 'Trying to search with no lost targets' return _closest_target = {'distance': 0, 'target_id': None} for target_id in _lost_targets: _memory = entity['ai']['life_memory'][target_id] _distance = numbers.distance(movement.get_position(entity), _memory['last_seen_at']) if not _closest_target[ 'target_id'] or _distance < _closest_target['distance']: _closest_target['target_id'] = target_id _closest_target['distance'] = _distance _target = entities.get_entity(_closest_target['target_id']) _solids = zones.get_active_solids(entity) if flags.has_flag(entity, 'search_nodes'): _search_for_target(entity, _target['_id']) return _x, _y = movement.get_position(entity) _tx, _ty = entity['ai']['life_memory'][_target['_id']]['last_seen_at'] _nodes_to_search = {} if entity['ai']['life_memory'][_target['_id']]['last_seen_velocity']: _vx, _vy = entity['ai']['life_memory'][ _target['_id']]['last_seen_velocity'] _tx + _vx * 6 _ty + _vy * 6 entities.trigger_event(entity, 'set_flag', flag='search_nodes', value=_nodes_to_search) for node_x, node_y in zones.get_active_node_grid(): _distance = numbers.distance((_tx, _ty), (node_x, node_y)) if _distance >= 30: continue if not (node_x, node_y) in _inside: continue _continue = False for pos in shapes.line((_tx, _ty), (node_x, node_y)): if pos in _solids: _continue = True break if _continue: continue if _distance in _nodes_to_search: if not (node_x, node_y) in _nodes_to_search[_distance]: _nodes_to_search[_distance].append((node_x, node_y)) else: _nodes_to_search[_distance] = [(node_x, node_y)]