def get_exposed_positions(life): _cover_exposed_at = brain.get_flag(life, 'cover_exposed_at') if _cover_exposed_at: return _cover_exposed_at return []
def get_stealth_coverage(life): _coverage = 1.0 if life['stance'] == 'standing': _stealth_mod = 1.0 elif life['stance'] == 'crouching': _stealth_mod = 0.75 else: _stealth_mod = 0.55 _visible_chunk_keys = brain.get_flag(life, 'visible_chunks') if _visible_chunk_keys: _visible_chunks = len(_visible_chunk_keys) else: _visible_chunks = 100 _stealth_mod *= bad_numbers.clip(_visible_chunks / 100.0, 0, 1.0) for z in range(1, 6): if WORLD_INFO['map'][life['pos'][0]][life['pos'][1]][life['pos'][2] + z]: _coverage *= _stealth_mod return bad_numbers.clip(_coverage, 0.0, 1.0)
def tick(life): if not lfe.execute_raw(life, 'discover', 'discover_type'): _lost_method = lfe.execute_raw(life, 'discover', 'when_lost') if _lost_method: if not life['path'] or not brain.retrieve_from_memory( life, 'discovery_lock'): if not 'scanned_chunks' in life['state_flags']: life['state_flags']['scanned_chunks'] = [] sight.scan_surroundings( life, _chunks=brain.get_flag(life, 'visible_chunks'), ignore_chunks=life['state_flags']['scanned_chunks']) _explore_chunk = chunks.find_best_chunk( life, ignore_starting=True, ignore_time=True, lost_method=_lost_method, only_recent=True) brain.store_in_memory(life, 'discovery_lock', True) brain.store_in_memory(life, 'explore_chunk', _explore_chunk) if not _explore_chunk: brain.flag(life, 'lost') return False survival.explore_known_chunks(life) else: return False
def is_tracking(life, target_id): _targets = brain.get_flag(life, 'tracking_targets') if not _targets: return False return target_id in _targets
def track_target(life, target_id): _tracking = brain.get_flag(life, 'tracking_targets') if not _tracking: brain.flag(life, 'tracking_targets', [target_id]) return None _tracking.append(target_id)
def desires_job(life): #TODO: We recalculate this, but the answer is always the same. _wont = brain.get_flag(life, 'wont_work') if life['job'] or _wont: if _wont: _wont = brain.flag(life, 'wont_work', value=_wont - 1) return False if not life['stats']['lone_wolf']: return True brain.flag(life, 'wont_work', value=1000) return False
def desires_job(life): #TODO: We recalculate this, but the answer is always the same. _wont = brain.get_flag(life, 'wont_work') if life['job'] or _wont: if _wont: _wont = brain.flag(life, 'wont_work', value=_wont-1) return False if not life['stats']['lone_wolf']: return True brain.flag(life, 'wont_work', value=1000) return False
def judge_item(life, item_uid): _item = ITEMS[item_uid] _score = 0 if brain.get_flag(life, "no_weapon") or not combat.has_ready_weapon(life): if _item["type"] == "gun": if combat.weapon_is_working(life, item_uid): _score += _item["accuracy"] else: _score += _item["accuracy"] / 2 if _item["type"] in ["magazine", "clip"]: _score += 1 return _score
def judge_item(life, item_uid, initial=False): _item = ITEMS[item_uid] _score = 0 if brain.get_flag(life, 'no_weapon') or item_uid in combat.get_equipped_weapons(life): if _item['type'] == 'gun': if combat.weapon_is_working(life, item_uid): _score += _item['accuracy'] else: _score += _item['accuracy']*.5 if _item['type'] in ['magazine', 'clip']: _score += 1 if not initial: brain.get_remembered_item(life, item_uid)['score'] = _score return _score
def tick(life): if not lfe.execute_raw(life, 'discover', 'discover_type'): _lost_method = lfe.execute_raw(life, 'discover', 'when_lost') if _lost_method: if not life['path'] or not brain.retrieve_from_memory(life, 'discovery_lock'): if not 'scanned_chunks' in life['state_flags']: life['state_flags']['scanned_chunks'] = [] sight.scan_surroundings(life, _chunks=brain.get_flag(life, 'visible_chunks'), ignore_chunks=life['state_flags']['scanned_chunks']) _explore_chunk = chunks.find_best_chunk(life, ignore_starting=True, ignore_time=True, lost_method=_lost_method, only_recent=True) brain.store_in_memory(life, 'discovery_lock', True) brain.store_in_memory(life, 'explore_chunk', _explore_chunk) if not _explore_chunk: brain.flag(life, 'lost') return False survival.explore_known_chunks(life) else: return False
def get_stealth_coverage(life): _coverage = 1.0 if life['stance'] == 'standing': _stealth_mod = 1.0 elif life['stance'] == 'crouching': _stealth_mod = 0.75 else: _stealth_mod = 0.55 _visible_chunk_keys = brain.get_flag(life, 'visible_chunks') if _visible_chunk_keys: _visible_chunks = len(_visible_chunk_keys) else: _visible_chunks = 100 _stealth_mod *= bad_numbers.clip(_visible_chunks/100.0, 0, 1.0) for z in range(1, 6): if WORLD_INFO['map'][life['pos'][0]][life['pos'][1]][life['pos'][2]+z]: _coverage *= _stealth_mod return bad_numbers.clip(_coverage, 0.0, 1.0)
def generate_needs(life): if not lfe.ticker(life, 'generate_needs', 90, fire=True): return False if stats.desires_weapon(life): brain.flag(life, 'no_weapon') else: brain.unflag(life, 'no_weapon') if combat.get_weapons(life): for weapon in combat.get_weapons(life): _weapon_uid = weapon['uid'] #for _flag in ['ammo', 'feed']: if len(combat.get_all_ammo_for_weapon(life, _weapon_uid)) >= 5: _flag_name = '%s_needs_ammo' % _weapon_uid _need = brain.get_flag(life, _flag_name) if _need: delete_needed_item(life, _need) brain.unflag(life, _flag_name) if combat.get_feeds_for_weapon(life, _weapon_uid): _flag_name = '%s_needs_feed' % _weapon_uid _need = brain.get_flag(life, _flag_name) if _need: delete_needed_item(life, _need) brain.unflag(life, _flag_name) if not combat.has_potentially_usable_weapon( life) and not combat.has_ready_weapon(life): #_weapon_with_feed = None #for weapon in combat.get_weapons(life): # if weapons.get_feed(weapon): # _weapon_with_feed = weapon['uid'] # break #if _weapon_with_feed: # _weapon_uid = weapon['uid'] # _flag_name = '%s_needs_ammo' % _weapon_uid # _n = add_needed_item(life, # {'type': 'bullet', 'owner': None, 'ammotype': weapon['ammotype']}, # satisfy_if=action.make_small_script(function='get_flag', # args={'flag': _flag_name}), # satisfy_callback=action.make_small_script(return_function='pick_up_and_hold_item')) # # brain.flag(life, _flag_name, value=_n) for weapon in combat.get_weapons(life): _weapon_uid = weapon['uid'] _flag_name = '%s_needs_feed' % _weapon_uid if combat.have_feed_and_ammo_for_weapon(life, _weapon_uid): continue #print 'feeds?', combat.get_feeds_for_weapon(life, _weapon_uid), [ITEMS[i]['name'] for i in lfe.get_held_items(life)] if not combat.get_feeds_for_weapon( life, _weapon_uid) and not brain.get_flag( life, _flag_name): _n = add_needed_item( life, { 'type': weapon['feed'], 'owner': None, 'ammotype': weapon['ammotype'] }, satisfy_if=action.make_small_script( function='get_flag', args={'flag': _flag_name}), satisfy_callback=action.make_small_script( return_function='pick_up_and_hold_item')) brain.flag(life, _flag_name, value=_n) _flag_name = '%s_needs_ammo' % _weapon_uid if len(combat.get_all_ammo_for_weapon( life, _weapon_uid)) < 5 and not brain.get_flag( life, _flag_name): _n = add_needed_item( life, { 'type': 'bullet', 'owner': None, 'ammotype': weapon['ammotype'] }, satisfy_if=action.make_small_script( function='get_flag', args={'flag': _flag_name}), satisfy_callback=action.make_small_script( return_function='pick_up_and_hold_item')) brain.flag(life, _flag_name, value=_n)
def generate_needs(life): if not lfe.ticker(life, "generate_needs", 90, fire=True): return False if stats.desires_weapon(life): brain.flag(life, "no_weapon") else: brain.unflag(life, "no_weapon") if combat.get_weapons(life): for weapon in combat.get_weapons(life): _weapon_uid = weapon["uid"] # for _flag in ['ammo', 'feed']: if len(combat.get_all_ammo_for_weapon(life, _weapon_uid)) >= 5: _flag_name = "%s_needs_ammo" % _weapon_uid _need = brain.get_flag(life, _flag_name) if _need: delete_needed_item(life, _need) brain.unflag(life, _flag_name) if combat.get_feeds_for_weapon(life, _weapon_uid): _flag_name = "%s_needs_feed" % _weapon_uid _need = brain.get_flag(life, _flag_name) if _need: delete_needed_item(life, _need) brain.unflag(life, _flag_name) if not combat.has_potentially_usable_weapon(life) and not combat.has_ready_weapon(life): # _weapon_with_feed = None # for weapon in combat.get_weapons(life): # if weapons.get_feed(weapon): # _weapon_with_feed = weapon['uid'] # break # if _weapon_with_feed: # _weapon_uid = weapon['uid'] # _flag_name = '%s_needs_ammo' % _weapon_uid # _n = add_needed_item(life, # {'type': 'bullet', 'owner': None, 'ammotype': weapon['ammotype']}, # satisfy_if=action.make_small_script(function='get_flag', # args={'flag': _flag_name}), # satisfy_callback=action.make_small_script(return_function='pick_up_and_hold_item')) # # brain.flag(life, _flag_name, value=_n) for weapon in combat.get_weapons(life): _weapon_uid = weapon["uid"] _flag_name = "%s_needs_feed" % _weapon_uid if combat.have_feed_and_ammo_for_weapon(life, _weapon_uid): continue # print 'feeds?', combat.get_feeds_for_weapon(life, _weapon_uid), [ITEMS[i]['name'] for i in lfe.get_held_items(life)] if not combat.get_feeds_for_weapon(life, _weapon_uid) and not brain.get_flag(life, _flag_name): _n = add_needed_item( life, {"type": weapon["feed"], "owner": None, "ammotype": weapon["ammotype"]}, satisfy_if=action.make_small_script(function="get_flag", args={"flag": _flag_name}), satisfy_callback=action.make_small_script(return_function="pick_up_and_hold_item"), ) brain.flag(life, _flag_name, value=_n) _flag_name = "%s_needs_ammo" % _weapon_uid if len(combat.get_all_ammo_for_weapon(life, _weapon_uid)) < 5 and not brain.get_flag(life, _flag_name): _n = add_needed_item( life, {"type": "bullet", "owner": None, "ammotype": weapon["ammotype"]}, satisfy_if=action.make_small_script(function="get_flag", args={"flag": _flag_name}), satisfy_callback=action.make_small_script(return_function="pick_up_and_hold_item"), ) brain.flag(life, _flag_name, value=_n)
def manage_combat(life, group_id): if has_flag(life, group_id, 'confident'): _was_confident = get_flag(life, group_id, 'confident') if _was_confident == stats.is_confident(life) and not lfe.ticker( life, 'decision_wait', 16): return False flag(life, group_id, 'confident', stats.is_confident(life)) _existing_friendlies = get_flag(life, group_id, 'friendlies') _existing_targets = get_flag(life, group_id, 'targets') _last_focal_point = get_flag(life, group_id, 'last_focal_point') if not _existing_friendlies: _existing_friendlies = {} if not _existing_targets: _existing_targets = {} for life_id in get_group(life, group_id)['members']: if not life_id in _existing_friendlies: _existing_friendlies[life_id] = {'updated': -900} flag(life, group_id, 'friendlies', _existing_friendlies) _checked_targets = [] for target_id in judgement.get_threats(life): if target_id in _existing_targets: _existing_targets[target_id]['time'] = 0 else: _existing_targets[target_id] = { 'time': 0, 'pos': brain.knows_alife_by_id(life, target_id)['last_seen_at'][:] } _checked_targets.append(target_id) _enemy_focal_pos = None for target_id in _existing_targets: if not _enemy_focal_pos: _enemy_focal_pos = _existing_targets[target_id]['pos'][:] else: _enemy_focal_pos = bad_numbers.lerp_velocity( _enemy_focal_pos, _existing_targets[target_id]['pos'], 0.5) if target_id in _checked_targets: continue _existing_targets[target_id]['time'] += 1 if _existing_targets[target_id]['time'] > 100: del _existing_targets[target_id] continue _hostile_chunks = get_flag(life, group_id, 'hostile_chunks') _previous_visible_chunks = brain.get_flag(life, 'group_combat_vis_chunks') if _previous_visible_chunks and _previous_visible_chunks[ 'from_pos'] == life['pos']: _visible_chunks = _previous_visible_chunks['visible_chunks'] else: _visible_chunks = chunks.get_visible_chunks_from( life['pos'], life['vision_max'] * .75) brain.flag(life, 'group_combat_vis_chunks', value={ 'from_pos': life['pos'][:], 'visible_chunks': _visible_chunks }) if _enemy_focal_pos: lfe.clear_ticker(life, 'group_command_reset') if not _last_focal_point or bad_numbers.distance( _enemy_focal_pos, _last_focal_point) > 30: _hostile_chunks = chunks.get_visible_chunks_from( (int(round(_enemy_focal_pos[0])), int(round(_enemy_focal_pos[1])), 2), life['vision_max'] * 1.5) flag(life, group_id, 'hostile_chunks', _hostile_chunks) flag(life, group_id, 'visible_chunks', _visible_chunks) flag(life, group_id, 'last_focal_point', _enemy_focal_pos) else: _ticker = lfe.ticker(life, 'group_command_reset', 48) if get_stage(life, group_id) == STAGE_ATTACKING: if _ticker: set_stage(life, group_id, STAGE_FORMING) flag(life, group_id, 'friendlies', None) flag(life, group_id, 'strategy', None) else: manage_strategy(life, group_id) return False if not get_stage(life, group_id) == STAGE_ATTACKING: speech.announce_combat_to_group(life, group_id) set_stage(life, group_id, STAGE_ATTACKING) if not lfe.ticker(life, 'group_command_rate', 3): return False _orig_visible_chunks = _visible_chunks[:] #TODO: Check distance to threat for hostile_chunk_key in _hostile_chunks: if hostile_chunk_key in _visible_chunks: _visible_chunks.remove(hostile_chunk_key) #TODO: Additional stages: PLANNING, EXECUTING if _visible_chunks and stats.is_confident(life): for target_id in order_spread_out( life, group_id, _visible_chunks, filter_by=lambda life_id: WORLD_INFO[ 'ticks'] - _existing_friendlies[life_id]['updated'] > 100): _existing_friendlies[target_id]['updated'] = WORLD_INFO['ticks'] else: _distant_chunk = {'distance': -1, 'chunk_key': None} _unchecked_members = get_group(life, group_id)['members'][:] for chunk_key in _orig_visible_chunks: _distance = bad_numbers.distance( (int(round( _enemy_focal_pos[0])), int(round(_enemy_focal_pos[1]))), chunks.get_chunk(chunk_key)['pos']) _distance *= bad_numbers.clip( bad_numbers.distance(life['pos'], _enemy_focal_pos), 1, 35) / 35.0 if chunk_key in _visible_chunks: _distance *= 2 for member_id in _unchecked_members: if life['id'] == member_id: continue _target = brain.knows_alife_by_id(life, member_id) if _target['last_seen_time'] <= 25 and chunks.get_chunk_key_at( _target['last_seen_at']) == chunk_key: _distance *= (2.5 * (1 - (bad_numbers.clip( _target['last_seen_time'], 0, 25) / 25.0))) if _distance > _distant_chunk['distance']: _distant_chunk['distance'] = _distance _distant_chunk['chunk_key'] = chunk_key if _distant_chunk['chunk_key']: for target_id in order_move_to( life, group_id, _distant_chunk['chunk_key'], filter_by=lambda life_id: WORLD_INFO['ticks'] - _existing_friendlies[life_id]['updated'] > 100): _existing_friendlies[target_id]['updated'] = WORLD_INFO[ 'ticks'] return False
def untrack_target(life, target_id): _tracking = brain.get_flag(life, 'tracking_targets') if target_id in _tracking: _tracking.remove(target_id)
def search_for_target(life, target_id): #TODO: Variable size instead of hardcoded _know = brain.knows_alife_by_id(life, target_id) _size = 30 _timer = brain.get_flag(life, 'search_time') _chunk_path = alife.brain.get_flag(life, 'chunk_path') if _chunk_path: travel_to_position(life, _chunk_path['end'], force=True) return False if _timer > 0: brain.flag(life, 'search_time', _timer - 1) return False if brain.alife_has_flag(life, target_id, 'search_map'): _search_map = brain.get_alife_flag(life, target_id, 'search_map') else: _search_map = maps.create_search_map(life, _know['last_seen_at'], _size) brain.flag_alife(life, target_id, 'search_map', value=_search_map) lfe.walk_to(life, _know['last_seen_at']) brain.flag(life, 'search_time', 12) return False _lowest = {'score': -1, 'pos': None} _x_top_left = bad_numbers.clip(_know['last_seen_at'][0] - (_size / 2), 0, MAP_SIZE[0]) _y_top_left = bad_numbers.clip(_know['last_seen_at'][1] - (_size / 2), 0, MAP_SIZE[1]) for x in range(0, _size): _x = _x_top_left + x if _x >= MAP_SIZE[0] - 1: continue for y in range(0, _size): _y = _y_top_left + y if _y >= MAP_SIZE[1] - 1: continue if not _search_map[y, x]: continue if sight.can_see_position(life, (_x, _y, _know['last_seen_at'][2]), get_path=True) or not lfe.can_walk_to( life, (_x, _y, _know['last_seen_at'][2])): _search_map[y, x] = 0 if _search_map[y, x] > 0 and ( not _lowest['pos'] or _search_map[y, x] < _lowest['score']): _lowest['score'] = _search_map[y, x] _lowest['pos'] = (_x, _y, x, y) if _lowest['pos']: x, y, _x, _y = _lowest['pos'] if travel_to_position(life, (x, y, _know['last_seen_at'][2]), stop_on_sight=False): _search_map[_y, _x] = 0 brain.flag( life, 'search_time', bad_numbers.clip( bad_numbers.distance(life['pos'], (x, y)) * .75, 5, 16)) else: _know['escaped'] = 2
def hide(life, targets): _target_positions = [] _avoid_positions = [] _zones = [zones.get_zone_at_coords(life['pos'])] if lfe.find_action(life, [{ 'action': 'dijkstra_move', 'reason': 'escaping' }]): if not lfe.ticker(life, 'escaping', 6): return False #What can the targets see? for target_id in targets: _target = brain.knows_alife_by_id(life, target_id) _zone = zones.get_zone_at_coords(_target['last_seen_at']) if not _zone in _zones: _zones.append(_zone) fov.fov(_target['last_seen_at'], sight.get_vision(_target['life']), callback=lambda pos: _avoid_positions.append(pos)) #What can we see? _can_see_positions = [] fov.fov(life['pos'], sight.get_vision(life), callback=lambda pos: _can_see_positions.append(pos)) #If there are no visible targets, we could be running away from a position we were attacked from _cover_exposed_at = brain.get_flag(life, 'cover_exposed_at') if _cover_exposed_at: _avoid_exposed_cover_positions = set() for pos in _cover_exposed_at[:]: if tuple(pos[:2]) in _can_see_positions: _cover_exposed_at.remove(pos) continue fov.fov( pos, int(round(sight.get_vision(life) * .25)), callback=lambda pos: _avoid_exposed_cover_positions.add(pos)) for pos in _avoid_exposed_cover_positions: if not pos in _avoid_positions: _avoid_positions.append(pos) else: print 'Something went wrong' return False #Overlay the two, finding positions we can see but the target can't for pos in _can_see_positions[:]: if pos in _avoid_positions: _can_see_positions.remove(pos) continue #Get rid of positions that are too close for target_id in targets: _target = brain.knows_alife_by_id(life, target_id) if bad_numbers.distance(_target['last_seen_at'], pos) < 4: _can_see_positions.remove(pos) break #Now scan for cover to prevent hiding in the open for pos in _can_see_positions[:]: if chunks.get_chunk(chunks.get_chunk_key_at(pos))['max_z'] == 2: _can_see_positions.remove(pos) if not _can_see_positions: if life['pos'] in _cover_exposed_at: _cover_exposed_at.remove(life['pos']) return False if lfe.find_action(life, [{ 'action': 'dijkstra_move', 'goals': _can_see_positions[:] }]): return True lfe.stop(life) lfe.add_action( life, { 'action': 'dijkstra_move', 'rolldown': True, 'zones': _zones, 'goals': _can_see_positions[:], 'reason': 'escaping' }, 200)
def search_for_target(life, target_id): # TODO: Variable size instead of hardcoded _know = brain.knows_alife_by_id(life, target_id) _size = 30 _timer = brain.get_flag(life, "search_time") _chunk_path = alife.brain.get_flag(life, "chunk_path") if _chunk_path: travel_to_position(life, _chunk_path["end"], force=True) return False if _timer > 0: brain.flag(life, "search_time", _timer - 1) return False if brain.alife_has_flag(life, target_id, "search_map"): _search_map = brain.get_alife_flag(life, target_id, "search_map") else: _search_map = maps.create_search_map(life, _know["last_seen_at"], _size) brain.flag_alife(life, target_id, "search_map", value=_search_map) lfe.walk_to(life, _know["last_seen_at"]) brain.flag(life, "search_time", 12) return False _lowest = {"score": -1, "pos": None} _x_top_left = numbers.clip(_know["last_seen_at"][0] - (_size / 2), 0, MAP_SIZE[0]) _y_top_left = numbers.clip(_know["last_seen_at"][1] - (_size / 2), 0, MAP_SIZE[1]) for x in range(0, _size): _x = _x_top_left + x if _x >= MAP_SIZE[0] - 1: continue for y in range(0, _size): _y = _y_top_left + y if _y >= MAP_SIZE[1] - 1: continue if not _search_map[y, x]: continue if sight.can_see_position(life, (_x, _y, _know["last_seen_at"][2]), get_path=True) or not lfe.can_walk_to( life, (_x, _y, _know["last_seen_at"][2]) ): _search_map[y, x] = 0 if _search_map[y, x] > 0 and (not _lowest["pos"] or _search_map[y, x] < _lowest["score"]): _lowest["score"] = _search_map[y, x] _lowest["pos"] = (_x, _y, x, y) if _lowest["pos"]: x, y, _x, _y = _lowest["pos"] if travel_to_position(life, (x, y, _know["last_seen_at"][2]), stop_on_sight=False): _search_map[_y, _x] = 0 brain.flag(life, "search_time", numbers.clip(numbers.distance(life["pos"], (x, y)) * 0.75, 5, 16)) else: _know["escaped"] = 2
def manage_combat(life, group_id): if has_flag(life, group_id, 'confident'): _was_confident = get_flag(life, group_id, 'confident') if _was_confident == stats.is_confident(life) and not lfe.ticker(life, 'decision_wait', 16): return False flag(life, group_id, 'confident', stats.is_confident(life)) _existing_friendlies = get_flag(life, group_id, 'friendlies') _existing_targets = get_flag(life, group_id, 'targets') _last_focal_point = get_flag(life, group_id, 'last_focal_point') if not _existing_friendlies: _existing_friendlies = {} if not _existing_targets: _existing_targets = {} for life_id in get_group(life, group_id)['members']: if not life_id in _existing_friendlies: _existing_friendlies[life_id] = {'updated': -900} flag(life, group_id, 'friendlies', _existing_friendlies) _checked_targets = [] for target_id in judgement.get_threats(life): if target_id in _existing_targets: _existing_targets[target_id]['time'] = 0 else: _existing_targets[target_id] = {'time': 0, 'pos': brain.knows_alife_by_id(life, target_id)['last_seen_at'][:]} _checked_targets.append(target_id) _enemy_focal_pos = None for target_id in _existing_targets: if not _enemy_focal_pos: _enemy_focal_pos = _existing_targets[target_id]['pos'][:] else: _enemy_focal_pos = bad_numbers.lerp_velocity(_enemy_focal_pos, _existing_targets[target_id]['pos'], 0.5) if target_id in _checked_targets: continue _existing_targets[target_id]['time'] += 1 if _existing_targets[target_id]['time']>100: del _existing_targets[target_id] continue _hostile_chunks = get_flag(life, group_id, 'hostile_chunks') _previous_visible_chunks = brain.get_flag(life, 'group_combat_vis_chunks') if _previous_visible_chunks and _previous_visible_chunks['from_pos'] == life['pos']: _visible_chunks = _previous_visible_chunks['visible_chunks'] else: _visible_chunks = chunks.get_visible_chunks_from(life['pos'], life['vision_max']*.75) brain.flag(life, 'group_combat_vis_chunks', value={'from_pos': life['pos'][:], 'visible_chunks': _visible_chunks}) if _enemy_focal_pos: lfe.clear_ticker(life, 'group_command_reset') if not _last_focal_point or bad_numbers.distance(_enemy_focal_pos, _last_focal_point)>30: _hostile_chunks = chunks.get_visible_chunks_from((int(round(_enemy_focal_pos[0])), int(round(_enemy_focal_pos[1])), 2), life['vision_max']*1.5) flag(life, group_id, 'hostile_chunks', _hostile_chunks) flag(life, group_id, 'visible_chunks', _visible_chunks) flag(life, group_id, 'last_focal_point', _enemy_focal_pos) else: _ticker = lfe.ticker(life, 'group_command_reset', 48) if get_stage(life, group_id) == STAGE_ATTACKING: if _ticker: set_stage(life, group_id, STAGE_FORMING) flag(life, group_id, 'friendlies', None) flag(life, group_id, 'strategy', None) else: manage_strategy(life, group_id) return False if not get_stage(life, group_id) == STAGE_ATTACKING: speech.announce_combat_to_group(life, group_id) set_stage(life, group_id, STAGE_ATTACKING) if not lfe.ticker(life, 'group_command_rate', 3): return False _orig_visible_chunks = _visible_chunks[:] #TODO: Check distance to threat for hostile_chunk_key in _hostile_chunks: if hostile_chunk_key in _visible_chunks: _visible_chunks.remove(hostile_chunk_key) #TODO: Additional stages: PLANNING, EXECUTING if _visible_chunks and stats.is_confident(life): for target_id in order_spread_out(life, group_id, _visible_chunks, filter_by=lambda life_id: WORLD_INFO['ticks']-_existing_friendlies[life_id]['updated']>100): _existing_friendlies[target_id]['updated'] = WORLD_INFO['ticks'] else: _distant_chunk = {'distance': -1, 'chunk_key': None} _unchecked_members = get_group(life, group_id)['members'][:] for chunk_key in _orig_visible_chunks: _distance = bad_numbers.distance((int(round(_enemy_focal_pos[0])), int(round(_enemy_focal_pos[1]))), chunks.get_chunk(chunk_key)['pos']) _distance *= bad_numbers.clip(bad_numbers.distance(life['pos'], _enemy_focal_pos), 1, 35)/35.0 if chunk_key in _visible_chunks: _distance *= 2 for member_id in _unchecked_members: if life['id'] == member_id: continue _target = brain.knows_alife_by_id(life, member_id) if _target['last_seen_time'] <= 25 and chunks.get_chunk_key_at(_target['last_seen_at']) == chunk_key: _distance *= (2.5*(1-(bad_numbers.clip(_target['last_seen_time'], 0, 25)/25.0))) if _distance>_distant_chunk['distance']: _distant_chunk['distance'] = _distance _distant_chunk['chunk_key'] = chunk_key if _distant_chunk['chunk_key']: for target_id in order_move_to(life, group_id, _distant_chunk['chunk_key'], filter_by=lambda life_id: WORLD_INFO['ticks']-_existing_friendlies[life_id]['updated']>100): _existing_friendlies[target_id]['updated'] = WORLD_INFO['ticks'] return False
def look(life): if not 'CAN_SEE' in life['life_flags']: return False for target_id in life['know']: if life['know'][target_id]['last_seen_time']: life['know'][target_id]['last_seen_time'] += 1 life['know'][target_id]['time_visible'] = 0 else: life['know'][target_id]['time_visible'] += 1 if 'player' in life: if life['path'] or not brain.get_flag(life, 'visible_chunks'): if SETTINGS['smp']: _visible_chunks = post_scan_surroundings(life) else: _visible_chunks = scan_surroundings(life, judge=False, get_chunks=True, ignore_chunks=0) _chunks = [maps.get_chunk(c) for c in _visible_chunks] brain.flag(life, 'visible_chunks', value=_visible_chunks) elif 'player' in life: _visible_chunks = brain.get_flag(life, 'visible_chunks') _chunks = [maps.get_chunk(c) for c in _visible_chunks] else: #This is for optimizing. Be careful if you mess with this... _nearby_alife = {} for alife in LIFE.values(): if alife['id'] == life['id']: continue if bad_numbers.distance( life['pos'], alife['pos']) <= get_vision(life) and can_see_position( life, alife['pos']): _nearby_alife[alife['id']] = { 'pos': alife['pos'][:], 'stance': alife['stance'] } _last_nearby_alife = brain.get_flag(life, '_nearby_alife') if not _last_nearby_alife == _nearby_alife: brain.flag(life, '_nearby_alife', value=_nearby_alife) else: for target_id in life['seen']: if life['know'][target_id]['last_seen_time']: life['know'][target_id]['last_seen_time'] = 0 return False _chunks = [ maps.get_chunk(c) for c in brain.get_flag(life, 'visible_chunks') ] life['seen'] = [] life['seen_items'] = [] for item_uid in life['know_items']: life['know_items'][item_uid]['last_seen_time'] += 1 for target_id in life['know']: life['know'][target_id]['last_seen_time'] += 1 if life['know'][target_id]['last_seen_time'] >= 10 and not life[ 'know'][target_id]['escaped']: life['know'][target_id]['escaped'] = 1 if not 'player' in life: quick_look(life) return False for chunk in _chunks: judgement.judge_chunk_visually( life, '%s,%s' % (chunk['pos'][0], chunk['pos'][1])) judgement.judge_chunk_life( life, '%s,%s' % (chunk['pos'][0], chunk['pos'][1])) for ai in [LIFE[i] for i in chunk['life']]: if ai['id'] == life['id']: continue if not is_in_fov(life, ai['pos']): if ai['id'] in life['know']: life['know'][ai['id']]['time_visible'] = 0 continue if not ai['id'] in life['know']: brain.meet_alife(life, ai) _visibility = get_visiblity_of_position(life, ai['pos']) _stealth_coverage = get_stealth_coverage(ai) if _visibility < 1 - _stealth_coverage: continue life['seen'].append(ai['id']) if life['think_rate'] == life['think_rate_max']: lfe.create_and_update_self_snapshot(LIFE[ai['id']]) judgement.judge_life(life, ai['id']) if ai['dead']: if 'player' in life and not life['know'][ ai['id']]['dead'] and life['know'][ ai['id']]['last_seen_time'] > 25: logic.show_event('You discover the body of %s.' % ' '.join(ai['name']), life=ai) if life['know'][ai['id']]['group']: groups.remove_member(life, life['know'][ai['id']]['group'], ai['id']) life['know'][ai['id']]['group'] = None core.record_loss(1) life['know'][ai['id']]['dead'] = True elif ai['asleep']: life['know'][ai['id']]['asleep'] = True elif not ai['asleep']: life['know'][ai['id']]['asleep'] = False life['know'][ai['id']]['last_seen_time'] = 0 life['know'][ai['id']]['last_seen_at'] = ai['pos'][:] life['know'][ai['id']]['escaped'] = False life['know'][ai['id']]['state'] = ai['state'] life['know'][ai['id']]['state_tier'] = ai['state_tier'] if brain.alife_has_flag(life, ai['id'], 'search_map'): brain.unflag_alife(life, ai['id'], 'search_map') _chunk_id = lfe.get_current_chunk_id(ai) judgement.judge_chunk(life, _chunk_id, seen=True) for item in [ITEMS[i] for i in chunk['items'] if i in ITEMS]: if not is_in_fov(life, item['pos']): continue if not item['uid'] in life['know_items']: brain.remember_item(life, item) if items.is_item_owned(item['uid']): #TODO: This doesn't work because we are specifically checking chunks if item['owner'] and lfe.item_is_equipped( LIFE[item['owner']], item['uid']): life['know_items'][item['uid']]['last_seen_at'] = LIFE[ item['owner']]['pos'] life['know_items'][ item['uid']]['last_owned_by'] = item['owner'] life['know_items'][item['uid']]['last_seen_time'] = 0 continue life['seen_items'].append(item['uid']) life['know_items'][item['uid']]['last_seen_at'] = item['pos'][:] life['know_items'][item['uid']]['last_seen_time'] = 0 life['know_items'][item['uid']]['last_owned_by'] = None life['know_items'][item['uid']]['score'] = judgement.judge_item( life, item['uid']) life['know_items'][item['uid']]['lost'] = False
def hide(life, targets): _target_positions = [] _avoid_positions = [] _zones = [zones.get_zone_at_coords(life["pos"])] if lfe.find_action(life, [{"action": "dijkstra_move", "reason": "escaping"}]): if not lfe.ticker(life, "escaping", 6): return False # What can the targets see? for target_id in targets: _target = brain.knows_alife_by_id(life, target_id) _zone = zones.get_zone_at_coords(_target["last_seen_at"]) if not _zone in _zones: _zones.append(_zone) fov.fov( _target["last_seen_at"], sight.get_vision(_target["life"]), callback=lambda pos: _avoid_positions.append(pos), ) # What can we see? _can_see_positions = [] fov.fov(life["pos"], sight.get_vision(life), callback=lambda pos: _can_see_positions.append(pos)) # If there are no visible targets, we could be running away from a position we were attacked from _cover_exposed_at = brain.get_flag(life, "cover_exposed_at") if _cover_exposed_at: _avoid_exposed_cover_positions = set() for pos in _cover_exposed_at[:]: if tuple(pos[:2]) in _can_see_positions: _cover_exposed_at.remove(pos) continue fov.fov( pos, int(round(sight.get_vision(life) * 0.25)), callback=lambda pos: _avoid_exposed_cover_positions.add(pos), ) for pos in _avoid_exposed_cover_positions: if not pos in _avoid_positions: _avoid_positions.append(pos) else: print "Something went wrong" return False # Overlay the two, finding positions we can see but the target can't for pos in _can_see_positions[:]: if pos in _avoid_positions: _can_see_positions.remove(pos) continue # Get rid of positions that are too close for target_id in targets: _target = brain.knows_alife_by_id(life, target_id) if numbers.distance(_target["last_seen_at"], pos) < 4: _can_see_positions.remove(pos) break # Now scan for cover to prevent hiding in the open for pos in _can_see_positions[:]: if chunks.get_chunk(chunks.get_chunk_key_at(pos))["max_z"] == 2: _can_see_positions.remove(pos) if not _can_see_positions: if life["pos"] in _cover_exposed_at: _cover_exposed_at.remove(life["pos"]) return False if lfe.find_action(life, [{"action": "dijkstra_move", "goals": _can_see_positions[:]}]): return True lfe.stop(life) lfe.add_action( life, { "action": "dijkstra_move", "rolldown": True, "zones": _zones, "goals": _can_see_positions[:], "reason": "escaping", }, 200, )
def search_for_target(life, target_id): #TODO: Variable size instead of hardcoded _know = brain.knows_alife_by_id(life, target_id) _size = 30 _timer = brain.get_flag(life, 'search_time') _chunk_path = alife.brain.get_flag(life, 'chunk_path') if _chunk_path: travel_to_position(life, _chunk_path['end'], force=True) return False if _timer>0: brain.flag(life, 'search_time', _timer-1) return False if brain.alife_has_flag(life, target_id, 'search_map'): _search_map = brain.get_alife_flag(life, target_id, 'search_map') else: _search_map = maps.create_search_map(life, _know['last_seen_at'], _size) brain.flag_alife(life, target_id, 'search_map', value=_search_map) lfe.walk_to(life, _know['last_seen_at']) brain.flag(life, 'search_time', 12) return False _lowest = {'score': -1, 'pos': None} _x_top_left = bad_numbers.clip(_know['last_seen_at'][0]-(_size/2), 0, MAP_SIZE[0]) _y_top_left = bad_numbers.clip(_know['last_seen_at'][1]-(_size/2), 0, MAP_SIZE[1]) for x in range(0, _size): _x = _x_top_left+x if _x >= MAP_SIZE[0]-1: continue for y in range(0, _size): _y = _y_top_left+y if _y >= MAP_SIZE[1]-1: continue if not _search_map[y, x]: continue if sight.can_see_position(life, (_x, _y, _know['last_seen_at'][2]), get_path=True) or not lfe.can_walk_to(life, (_x, _y, _know['last_seen_at'][2])): _search_map[y, x] = 0 if _search_map[y, x]>0 and (not _lowest['pos'] or _search_map[y, x] < _lowest['score']): _lowest['score'] = _search_map[y, x] _lowest['pos'] = (_x, _y, x, y) if _lowest['pos']: x, y, _x, _y = _lowest['pos'] if travel_to_position(life, (x, y, _know['last_seen_at'][2]), stop_on_sight=False): _search_map[_y, _x] = 0 brain.flag(life, 'search_time', bad_numbers.clip(bad_numbers.distance(life['pos'], (x, y))*.75, 5, 16)) else: _know['escaped'] = 2
def setup_look(life): if not 'CAN_SEE' in life['life_flags']: return False if life['path'] or not brain.get_flag(life, 'visible_chunks'): scan_surroundings(life, judge=False, get_chunks=True, ignore_chunks=0)
def look(life): if not 'CAN_SEE' in life['life_flags']: return False for target_id in life['know']: if life['know'][target_id]['last_seen_time']: life['know'][target_id]['last_seen_time'] += 1 life['know'][target_id]['time_visible'] = 0 else: life['know'][target_id]['time_visible'] += 1 if 'player' in life: if life['path'] or not brain.get_flag(life, 'visible_chunks'): if SETTINGS['smp']: _visible_chunks = post_scan_surroundings(life) else: _visible_chunks = scan_surroundings(life, judge=False, get_chunks=True, ignore_chunks=0) _chunks = [maps.get_chunk(c) for c in _visible_chunks] brain.flag(life, 'visible_chunks', value=_visible_chunks) elif 'player' in life: _visible_chunks = brain.get_flag(life, 'visible_chunks') _chunks = [maps.get_chunk(c) for c in _visible_chunks] else: #This is for optimizing. Be careful if you mess with this... _nearby_alife = {} for alife in LIFE.values(): if alife['id'] == life['id']: continue if bad_numbers.distance(life['pos'], alife['pos'])<=get_vision(life) and can_see_position(life, alife['pos']): _nearby_alife[alife['id']] = {'pos': alife['pos'][:], 'stance': alife['stance']} _last_nearby_alife = brain.get_flag(life, '_nearby_alife') if not _last_nearby_alife == _nearby_alife: brain.flag(life, '_nearby_alife', value=_nearby_alife) else: for target_id in life['seen']: if life['know'][target_id]['last_seen_time']: life['know'][target_id]['last_seen_time'] = 0 return False _chunks = [maps.get_chunk(c) for c in brain.get_flag(life, 'visible_chunks')] life['seen'] = [] life['seen_items'] = [] for item_uid in life['know_items']: life['know_items'][item_uid]['last_seen_time'] += 1 for target_id in life['know']: life['know'][target_id]['last_seen_time'] += 1 if life['know'][target_id]['last_seen_time']>=10 and not life['know'][target_id]['escaped']: life['know'][target_id]['escaped'] = 1 if not 'player' in life: quick_look(life) return False for chunk in _chunks: judgement.judge_chunk_visually(life, '%s,%s' % (chunk['pos'][0], chunk['pos'][1])) judgement.judge_chunk_life(life, '%s,%s' % (chunk['pos'][0], chunk['pos'][1])) for ai in [LIFE[i] for i in chunk['life']]: if ai['id'] == life['id']: continue if not is_in_fov(life, ai['pos']): if ai['id'] in life['know']: life['know'][ai['id']]['time_visible'] = 0 continue if not ai['id'] in life['know']: brain.meet_alife(life, ai) _visibility = get_visiblity_of_position(life, ai['pos']) _stealth_coverage = get_stealth_coverage(ai) if _visibility < 1-_stealth_coverage: continue life['seen'].append(ai['id']) if life['think_rate'] == life['think_rate_max']: lfe.create_and_update_self_snapshot(LIFE[ai['id']]) judgement.judge_life(life, ai['id']) if ai['dead']: if 'player' in life and not life['know'][ai['id']]['dead'] and life['know'][ai['id']]['last_seen_time']>25: logic.show_event('You discover the body of %s.' % ' '.join(ai['name']), life=ai) if life['know'][ai['id']]['group']: groups.remove_member(life, life['know'][ai['id']]['group'], ai['id']) life['know'][ai['id']]['group'] = None core.record_loss(1) life['know'][ai['id']]['dead'] = True elif ai['asleep']: life['know'][ai['id']]['asleep'] = True elif not ai['asleep']: life['know'][ai['id']]['asleep'] = False life['know'][ai['id']]['last_seen_time'] = 0 life['know'][ai['id']]['last_seen_at'] = ai['pos'][:] life['know'][ai['id']]['escaped'] = False life['know'][ai['id']]['state'] = ai['state'] life['know'][ai['id']]['state_tier'] = ai['state_tier'] if brain.alife_has_flag(life, ai['id'], 'search_map'): brain.unflag_alife(life, ai['id'], 'search_map') _chunk_id = lfe.get_current_chunk_id(ai) judgement.judge_chunk(life, _chunk_id, seen=True) for item in [ITEMS[i] for i in chunk['items'] if i in ITEMS]: if not is_in_fov(life, item['pos']): continue if not item['uid'] in life['know_items']: brain.remember_item(life, item) if items.is_item_owned(item['uid']): #TODO: This doesn't work because we are specifically checking chunks if item['owner'] and lfe.item_is_equipped(LIFE[item['owner']], item['uid']): life['know_items'][item['uid']]['last_seen_at'] = LIFE[item['owner']]['pos'] life['know_items'][item['uid']]['last_owned_by'] = item['owner'] life['know_items'][item['uid']]['last_seen_time'] = 0 continue life['seen_items'].append(item['uid']) life['know_items'][item['uid']]['last_seen_at'] = item['pos'][:] life['know_items'][item['uid']]['last_seen_time'] = 0 life['know_items'][item['uid']]['last_owned_by'] = None life['know_items'][item['uid']]['score'] = judgement.judge_item(life, item['uid']) life['know_items'][item['uid']]['lost'] = False
def escape(life, targets): _target_positions = [] _avoid_positions = [] _zones = [zones.get_zone_at_coords(life['pos'])] if lfe.find_action(life, [{'action': 'dijkstra_move', 'reason': 'escaping'}]): if not lfe.ticker(life, 'escaping', 4): return False #What can the targets see? for target_id in targets: _target = brain.knows_alife_by_id(life, target_id) _zone = zones.get_zone_at_coords(_target['last_seen_at']) if not _zone in _zones: _zones.append(_zone) fov.fov(_target['last_seen_at'], sight.get_vision(_target['life']), callback=lambda pos: _avoid_positions.append(pos)) #What can we see? _can_see_positions = [] fov.fov(life['pos'], sight.get_vision(life), callback=lambda pos: _can_see_positions.append(pos)) #If there are no visible targets, we could be running away from a position we were attacked from _cover_exposed_at = brain.get_flag(life, 'cover_exposed_at') if _cover_exposed_at: _avoid_exposed_cover_positions = set() for pos in _cover_exposed_at[:]: if tuple(pos[:2]) in _can_see_positions: print 'ok!!!'*20 _cover_exposed_at.remove(pos) continue fov.fov(pos, int(round(sight.get_vision(life)*.25)), callback=lambda pos: _avoid_exposed_cover_positions.add(pos)) for pos in _avoid_exposed_cover_positions: if not pos in _avoid_positions: _avoid_positions.append(pos) #Overlay the two, finding positions we can see but the target can't for pos in _can_see_positions[:]: if pos in _avoid_positions: _can_see_positions.remove(pos) continue #Get rid of positions that are too close for target_id in targets: _target = brain.knows_alife_by_id(life, target_id) #TODO: Unhardcode 15 if numbers.distance(_target['last_seen_at'], pos)<10: _can_see_positions.remove(pos) break #Now scan for cover to prevent hiding in the open for pos in _can_see_positions[:]: if chunks.get_chunk(chunks.get_chunk_key_at(pos))['max_z'] == 2: _can_see_positions.remove(pos) #for target_id in targets: #_target = brain.knows_alife_by_id(life, target_id) #_target_positions.append(_target['last_seen_at'][:]) #_zone = zones.get_zone_at_coords(_target['last_seen_at']) #if not _zone in _zones: # _zones.append(_zone) #for chunk_key in chunks.get_visible_chunks_from(_target['last_seen_at'], sight.get_vision(_target['life'])): # if chunk_key in _visible_target_chunks: # continue # _visible_target_chunks.append(chunk_key) #for friendly_id in life['seen']: # _chunk_key = lfe.get_current_chunk_id(LIFE[friendly_id]) # # if not _chunk_key in _visible_target_chunks: # _visible_target_chunks.append(_chunk_key) #if not _target_positions: # return False #TODO: #combat: For lower limit in return_score_in_range, use range of weapon #_cover = zones.dijkstra_map(life['pos'], # _avoid_positions, # _zones, # avoid_chunks=[], # return_score_in_range=[1, 5]) # sight.get_vision(life) #_cover = [(c[0], c[1], life['pos'][2]) for c in _cover] #if not _cover: # return False #_zones = [zones.get_zone_at_coords(life['pos'])] #for _pos in _cover: # _zone = zones.get_zone_at_coords(_pos) # if not _zone in _zones: # _zones.append(_zone) if not _can_see_positions: return False if lfe.find_action(life, [{'action': 'dijkstra_move', 'goals': _can_see_positions[:]}]): return True lfe.stop(life) lfe.add_action(life, {'action': 'dijkstra_move', 'rolldown': True, 'zones': _zones, 'goals': _can_see_positions[:], 'reason': 'escaping'}, 999)