def manage_hands(life): for item in [lfe.get_inventory_item(life, item) for item in lfe.get_held_items(life)]: judgement.judge_item(life, item["uid"]) _known_item = brain.get_remembered_item(life, item["uid"]) if _known_item["score"]: # judgement.get_score_of_highest_scoring_item(life): continue _equip_action = {"action": "equipitem", "item": item["uid"]} if len(lfe.find_action(life, matches=[_equip_action])): return True if lfe.can_wear_item(life, item["uid"]): lfe.add_action(life, _equip_action, 401, delay=lfe.get_item_access_time(life, item["uid"])) return True _storage = lfe.can_put_item_in_storage(life, item["uid"]) if not "CAN_WEAR" in item["flags"] and _storage: _store_action = {"action": "storeitem", "item": item["uid"], "container": _storage} if len(lfe.find_action(life, matches=[_store_action])): continue lfe.add_action(life, _store_action, 401, delay=lfe.get_item_access_time(life, item["uid"])) return True return False
def manage_inventory(life): if manage_hands(life): return False for weapon_uid in combat.get_equipped_weapons(life): if not combat.weapon_is_working(life, weapon_uid): if combat.weapon_is_in_preferred_working_condition(life, weapon_uid): if not len(lfe.find_action(life,matches=[{'action': 'refillammo'}])): combat.reload_weapon(life, weapon_uid) return True _item_to_wear = {'score': 0, 'item_uid': None} _item_to_equip = {'score': 0, 'item_uid': None} for item in [lfe.get_inventory_item(life, item) for item in lfe.get_all_unequipped_items(life)]: judgement.judge_item(life, item['uid']) _known_item = brain.get_remembered_item(life, item['uid']) if _known_item['score']: if lfe.can_wear_item(life, item['uid']): if _known_item['score'] > _item_to_wear['score']: _item_to_wear['score'] = _known_item['score'] _item_to_wear['item_uid'] = item['uid'] else: if rawparse.raw_has_section(life, 'items') and rawparse.raw_section_has_identifier(life, 'items', item['type']): _action = lfe.execute_raw(life, 'items', item['type']) if item['type'] == 'gun' and lfe.get_all_equipped_items(life, matches=[{'type': 'gun'}]): continue if _action == 'equip': if _known_item['score'] > _item_to_equip['score']: _item_to_equip['score'] = _known_item['score'] _item_to_equip['item_uid'] = item['uid'] _item = None if _item_to_wear['score'] > _item_to_equip['score']: _item = _item_to_wear['item_uid'] elif _item_to_equip['item_uid']: _item = _item_to_equip['item_uid'] if _item: _equip_action = {'action': 'equipitem', 'item': _item} if len(lfe.find_action(life, matches=[_equip_action])): return False lfe.add_action(life, _equip_action, 401, delay=lfe.get_item_access_time(life, _item)) return False return True
def position_to_attack(life, target): if lfe.find_action(life, [{'action': 'dijkstra_move', 'reason': 'positioning for attack'}]): if not lfe.ticker(life, 'attack_position', 4): return False _target_positions, _zones = combat.get_target_positions_and_zones(life, [target]) _nearest_target_score = zones.dijkstra_map(life['pos'], _target_positions, _zones, return_score=True) #TODO: Short or long-range weapon? #if _nearest_target_score >= sight.get_vision(life)/2: if not sight.can_see_position(life, brain.knows_alife_by_id(life, target)['last_seen_at'], block_check=True, strict=True) or sight.view_blocked_by_life(life, _target_positions[0], allow=[target]): print life['name'], 'changing position for combat...', life['name'], LIFE[target]['name'] _avoid_positions = [] for life_id in life['seen']: if life_id == target or life['id'] == life_id: continue if alife.judgement.can_trust(life, life_id): _avoid_positions.append(lfe.path_dest(LIFE[life_id])) else: _avoid_positions.append(brain.knows_alife_by_id(life, life_id)['last_seen_at']) _cover = _target_positions _zones = [] for pos in _cover: _zone = zones.get_zone_at_coords(pos) if not _zone in _zones: _zones.append(_zone) if not lfe.find_action(life, [{'action': 'dijkstra_move', 'orig_goals': _cover[:], 'avoid_positions': _avoid_positions}]): lfe.stop(life) lfe.add_action(life, {'action': 'dijkstra_move', 'rolldown': True, 'goals': _cover[:], 'orig_goals': _cover[:], 'avoid_positions': _avoid_positions, 'reason': 'positioning for attack'}, 999) return False else: return False elif life['path']: lfe.stop(life) return True
def manage_hands(life): for item in [ lfe.get_inventory_item(life, item) for item in lfe.get_held_items(life) ]: judgement.judge_item(life, item['uid']) _known_item = brain.get_remembered_item(life, item['uid']) for weapon in combat.get_equipped_weapons(life): if item['type'] == ITEMS[weapon]['feed'] and len( item['rounds']) >= 5: combat.load_feed(life, weapon, item['uid']) return True if _known_item[ 'score']: #judgement.get_score_of_highest_scoring_item(life): continue _equip_action = {'action': 'equipitem', 'item': item['uid']} if len(lfe.find_action(life, matches=[_equip_action])): return True if lfe.can_wear_item(life, item['uid']): lfe.add_action(life, _equip_action, 401, delay=lfe.get_item_access_time(life, item['uid'])) return True _storage = lfe.can_put_item_in_storage(life, item['uid']) if not 'CAN_WEAR' in item['flags'] and _storage: _store_action = { 'action': 'storeitem', 'item': item['uid'], 'container': _storage } if len(lfe.find_action(life, matches=[_store_action])): continue lfe.add_action(life, _store_action, 401, delay=lfe.get_item_access_time(life, item['uid'])) return True return False
def escape(life, targets): _avoid_positions = [] _zones = [zones.get_zone_at_coords(life['pos'])] if lfe.find_action(life, [{ 'action': 'dijkstra_move', 'reason': 'escape' }]): if lfe.ticker(life, 'escape_refresh', 4): lfe.stop(life) else: return False 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) _avoid_positions.append(_target['last_seen_at']) lfe.add_action( life, { 'action': 'dijkstra_move', 'rolldown': False, 'zones': _zones, 'goals': _avoid_positions, 'reason': 'escape' }, 100)
def escape(life, targets): _avoid_positions = [] _zones = [zones.get_zone_at_coords(life['pos'])] if lfe.find_action(life, [{'action': 'dijkstra_move', 'reason': 'escape'}]): if lfe.ticker(life, 'escape_refresh', 4): lfe.stop(life) else: return False 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) _avoid_positions.append(_target['last_seen_at']) lfe.add_action(life, {'action': 'dijkstra_move', 'rolldown': False, 'zones': _zones, 'goals': _avoid_positions, 'reason': 'escape'}, 100)
def understand(life): if SETTINGS['controlling']: _dist_to_player = numbers.distance(life['pos'], LIFE[SETTINGS['controlling']]['pos']) if _dist_to_player < 100: if life['think_rate_max']>=30: if _dist_to_player < 75: life['think_rate_max'] = 1 life['online'] = True logging.debug('[Agent] %s brought online (Reason: Near viewer)' % ' '.join(life['name'])) else: life['think_rate_max'] = 1 else: if _dist_to_player >= OFFLINE_ALIFE_DISTANCE and life['online']: life['online'] = False logging.debug('[Agent] %s went offline (Reason: Away from viewer)' % ' '.join(life['name'])) elif life['think_rate_max']<30: if _dist_to_player < OFFLINE_ALIFE_DISTANCE: life['online'] = True logging.debug('[Agent] %s went passive (Reason: Away from viewer)' % ' '.join(life['name'])) life['think_rate_max'] = numbers.clip(15*(((_dist_to_player-100)+30)/30), 30, 60) else: life['think_rate_max'] = 5 if not life['online'] or life['asleep']: return False if len(life['actions'])-len(lfe.find_action(life, matches=[{'action': 'move'}, {'action': 'dijkstra_move'}]))>0: lfe.clear_actions(life) life['path'] = [] return False if life['think_rate']>0: life['think_rate'] -= 1 return False for module in CONSTANT_MODULES: module.setup(life) life['think_rate'] = life['think_rate_max'] #if life['name'][0].startswith('Tim'): # _goal, _tier, _plan = planner.get_next_goal(life, debug='attack') #else: _goal, _tier, _plan = planner.get_next_goal(life) if _goal: lfe.change_goal(life, _goal, _tier, _plan) else: lfe.change_goal(life, 'idle', TIER_RELAXED, []) #logging.error('%s has no possible goal.' % ' '.join(life['name'])) return False planner.think(life)
def collect_nearby_wanted_items(life, only_visible=True, matches={'type': 'gun'}): _highest = {'item': None, 'score': -100000} _nearby = sight.find_known_items(life, matches=matches, only_visible=only_visible) for item in _nearby: _item = brain.get_remembered_item(life, item) _score = _item['score'] _score -= bad_numbers.distance(life['pos'], ITEMS[item]['pos']) if not _highest['item'] or _score > _highest['score']: _highest['score'] = _score _highest['item'] = ITEMS[item] if not _highest['item']: return True _empty_hand = lfe.get_open_hands(life) if not _empty_hand: print 'No open hands, managing....' for item_uid in lfe.get_held_items(life): _container = lfe.can_put_item_in_storage(life, item_uid) lfe.add_action(life, { 'action': 'storeitem', 'item': item_uid, 'container': _container }, 200, delay=lfe.get_item_access_time(life, item_uid)) return False if life['pos'] == _highest['item']['pos']: lfe.clear_actions(life) for action in lfe.find_action(life, matches=[{ 'action': 'pickupholditem' }]): #print 'I was picking up something else...',_highest['item']['name'] return False lfe.add_action(life, { 'action': 'pickupholditem', 'item': _highest['item']['uid'], 'hand': random.choice(_empty_hand) }, 200, delay=lfe.get_item_access_time(life, _highest['item']['uid'])) lfe.lock_item(life, _highest['item']['uid']) else: lfe.walk_to(life, _highest['item']['pos']) return False
def _refill_feed(life, feed): if not lfe.is_holding(life, feed['uid']) and not lfe.can_hold_item(life): logging.warning('No hands free to load ammo!') return False if not lfe.get_held_items(life, matches=[{'id': feed['uid']}]) and lfe.item_is_stored(life, feed['uid']) and not lfe.find_action(life, matches=[{'action': 'removeandholditem'}]): lfe.add_action(life,{'action': 'removeandholditem', 'item': feed['uid']}, 200, delay=0) return False #TODO: No check for ammo type. _loading_rounds = len(lfe.find_action(life,matches=[{'action': 'refillammo'}])) if _loading_rounds >= len(lfe.get_all_inventory_items(life,matches=[{'type': 'bullet', 'ammotype': feed['ammotype']}])): #TODO: What? if not _loading_rounds: return True return False if len(lfe.find_action(life,matches=[{'action': 'refillammo'}])): return False _rounds = len(feed['rounds']) if _rounds>=feed['maxrounds']: print 'Full?' return True _ammo_count = len(lfe.get_all_inventory_items(life,matches=[{'type': 'bullet', 'ammotype': feed['ammotype']}])) _ammo_count += len(feed['rounds']) _rounds_to_load = numbers.clip(_ammo_count,0,feed['maxrounds']) for ammo in lfe.get_all_inventory_items(life,matches=[{'type': 'bullet', 'ammotype': feed['ammotype']}])[:_rounds_to_load]: lfe.add_action(life,{'action': 'refillammo', 'ammo': feed, 'round': ammo}, 200, delay=3) _rounds += 1 return False
def _refill_feed(life, feed): if not lfe.is_holding(life, feed['uid']) and not lfe.can_hold_item(life): logging.warning('No hands free to load ammo!') return False if not lfe.get_held_items(life, matches=[{'id': feed['uid']}]) and lfe.item_is_stored(life, feed['uid']) and not lfe.find_action(life, matches=[{'action': 'removeandholditem'}]): lfe.add_action(life,{'action': 'removeandholditem', 'item': feed['uid']}, 200, delay=0) return False #TODO: No check for ammo type. _loading_rounds = len(lfe.find_action(life, matches=[{'action': 'refillammo'}])) _bullets_in_inventory = len(lfe.get_all_inventory_items(life, matches=[{'type': 'bullet', 'ammotype': feed['ammotype']}])) if _loading_rounds:# >= _bullets_in_inventory: return False if len(lfe.find_action(life,matches=[{'action': 'refillammo'}])): return False _rounds = len(feed['rounds']) if _rounds>=feed['maxrounds'] or (not _bullets_in_inventory and _rounds): print 'Full?' return True _ammo_count = len(lfe.get_all_inventory_items(life,matches=[{'type': 'bullet', 'ammotype': feed['ammotype']}])) _ammo_count += len(feed['rounds']) _rounds_to_load = numbers.clip(_ammo_count,0,feed['maxrounds']) for ammo in lfe.get_all_inventory_items(life,matches=[{'type': 'bullet', 'ammotype': feed['ammotype']}])[:_rounds_to_load]: lfe.add_action(life,{'action': 'refillammo', 'ammo': feed, 'round': ammo}, 200, delay=3) _rounds += 1 return False
def load_feed(life, weapon_uid, feed_uid): _load_action = {'action': 'reload', 'weapon': ITEMS[weapon_uid], 'ammo': ITEMS[feed_uid]} if lfe.find_action(life, matches=[_load_action]): return False lfe.add_action(life, _load_action, 200, delay=0) return True
def guard_camp(life): _delay = random.randint(25, jobs.get_job_detail(life['job'], 'pause')) if not life['path'] and not lfe.find_action(life, matches=[{'action': 'move'}]): _chunk = WORLD_INFO['chunk_map'][references.find_least_populated_key_in_reference(life, CAMPS[life['camp']]['reference'])] lfe.add_action(life,{'action': 'move', 'to': random.choice(_chunk['ground'])}, 200, delay=_delay) return False
def manage_hands(life): for item in [lfe.get_inventory_item(life, item) for item in lfe.get_held_items(life)]: judgement.judge_item(life, item['uid']) _known_item = brain.get_remembered_item(life, item['uid']) for weapon in combat.get_equipped_weapons(life): if item['type'] == ITEMS[weapon]['feed'] and len(item['rounds'])>=5: combat.load_feed(life, weapon, item['uid']) return True if _known_item['score']:#judgement.get_score_of_highest_scoring_item(life): continue _equip_action = {'action': 'equipitem', 'item': item['uid']} if len(lfe.find_action(life, matches=[_equip_action])): return True if lfe.can_wear_item(life, item['uid']): lfe.add_action(life, _equip_action, 401, delay=lfe.get_item_access_time(life, item['uid'])) return True _storage = lfe.can_put_item_in_storage(life, item['uid']) if not 'CAN_WEAR' in item['flags'] and _storage: _store_action = {'action': 'storeitem', 'item': item['uid'], 'container': _storage} if len(lfe.find_action(life, matches=[_store_action])): continue lfe.add_action(life,_store_action, 401, delay=lfe.get_item_access_time(life, item['uid'])) return True return False
def search_for_target(life, target_id): #TODO: Variable size instead of hardcoded _know = brain.knows_alife_by_id(life, target_id) _size = 30 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.stop(life) lfe.walk_to(life, _know['last_seen_at'][:2]) if life['path'] or lfe.find_action(life, matches=[{'action': 'move'}]): 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)): _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=True): _search_map[_y, _x] = 0 else: _know['escaped'] = 2
def manage_inventory(life): if manage_hands(life): return False for weapon_uid in combat.get_equipped_weapons(life): if not combat.weapon_is_working(life, weapon_uid): if combat.weapon_is_in_preferred_working_condition(life, weapon_uid): combat.reload_weapon(life, weapon_uid) return True _item_to_wear = {"score": 0, "item_uid": None} _item_to_equip = {"score": 0, "item_uid": None} for item in [lfe.get_inventory_item(life, item) for item in lfe.get_all_unequipped_items(life)]: judgement.judge_item(life, item["uid"]) _known_item = brain.get_remembered_item(life, item["uid"]) if _known_item["score"]: if lfe.can_wear_item(life, item["uid"]): if _known_item["score"] > _item_to_wear["score"]: _item_to_wear["score"] = _known_item["score"] _item_to_wear["item_uid"] = item["uid"] else: if rawparse.raw_has_section(life, "items") and rawparse.raw_section_has_identifier( life, "items", item["type"] ): _action = lfe.execute_raw(life, "items", item["type"]) if _action == "equip": if _known_item["score"] > _item_to_equip["score"]: _item_to_equip["score"] = _known_item["score"] _item_to_equip["item_uid"] = item["uid"] _item = None if _item_to_wear["score"] > _item_to_equip["score"]: _item = _item_to_wear["item_uid"] elif _item_to_equip["item_uid"]: _item = _item_to_equip["item_uid"] if _item: _equip_action = {"action": "equipitem", "item": _item} if len(lfe.find_action(life, matches=[_equip_action])): return False lfe.add_action(life, _equip_action, 401, delay=lfe.get_item_access_time(life, _item)) return True return False
def collect_nearby_wanted_items(life, only_visible=True, matches={"type": "gun"}): _highest = {"item": None, "score": -100000} _nearby = sight.find_known_items(life, matches=matches, only_visible=only_visible) for item in _nearby: _item = brain.get_remembered_item(life, item) _score = _item["score"] _score -= numbers.distance(life["pos"], ITEMS[item]["pos"]) if not _highest["item"] or _score > _highest["score"]: _highest["score"] = _score _highest["item"] = ITEMS[item] if not _highest["item"]: return True _empty_hand = lfe.get_open_hands(life) if not _empty_hand: print "No open hands, managing...." for item_uid in lfe.get_held_items(life): _container = lfe.can_put_item_in_storage(life, item_uid) lfe.add_action( life, {"action": "storeitem", "item": item_uid, "container": _container}, 200, delay=lfe.get_item_access_time(life, item_uid), ) return False if life["pos"] == _highest["item"]["pos"]: lfe.clear_actions(life) for action in lfe.find_action(life, matches=[{"action": "pickupholditem"}]): # print 'I was picking up something else...',_highest['item']['name'] return False lfe.add_action( life, {"action": "pickupholditem", "item": _highest["item"]["uid"], "hand": random.choice(_empty_hand)}, 200, delay=lfe.get_item_access_time(life, _highest["item"]["uid"]), ) lfe.lock_item(life, _highest["item"]["uid"]) else: lfe.walk_to(life, _highest["item"]["pos"]) return False
def collect_nearby_wanted_items(life, only_visible=True, matches={'type': 'gun'}): _highest = {'item': None,'score': -100000} _nearby = sight.find_known_items(life, matches=matches, only_visible=only_visible) for item in _nearby: _item = brain.get_remembered_item(life, item) _score = _item['score'] _score -= numbers.distance(life['pos'], ITEMS[item]['pos']) if not _highest['item'] or _score > _highest['score']: _highest['score'] = _score _highest['item'] = ITEMS[item] if not _highest['item']: return True _empty_hand = lfe.get_open_hands(life) if not _empty_hand: print 'No open hands, managing....' for item_uid in lfe.get_held_items(life): _container = lfe.can_put_item_in_storage(life, item_uid) lfe.add_action(life, {'action': 'storeitem', 'item': item_uid, 'container': _container}, 200, delay=lfe.get_item_access_time(life, item_uid)) return False if life['pos'] == _highest['item']['pos']: lfe.clear_actions(life) for action in lfe.find_action(life, matches=[{'action': 'pickupholditem'}]): #print 'I was picking up something else...',_highest['item']['name'] return False lfe.add_action(life,{'action': 'pickupholditem', 'item': _highest['item']['uid'], 'hand': random.choice(_empty_hand)}, 200, delay=lfe.get_item_access_time(life, _highest['item']['uid'])) lfe.lock_item(life, _highest['item']['uid']) else: lfe.clear_actions(life) lfe.add_action(life,{'action': 'move','to': _highest['item']['pos'][:2]},200) return False
def guard_camp(life): _delay = random.randint(25, jobs.get_job_detail(life['job'], 'pause')) if not life['path'] and not lfe.find_action(life, matches=[{ 'action': 'move' }]): _chunk = WORLD_INFO['chunk_map'][ references.find_least_populated_key_in_reference( life, CAMPS[life['camp']]['reference'])] lfe.add_action(life, { 'action': 'move', 'to': random.choice(_chunk['ground']) }, 200, delay=_delay) return False
def ranged_combat(life, targets): _target = get_closest_target(life, targets) if not _target: for target_id in targets: if brain.knows_alife_by_id(life, target_id)['escaped']: continue brain.knows_alife_by_id(life, target_id)['escaped'] = 1 logging.error('No target for ranged combat.') return False if not life['path'] or not numbers.distance(lfe.path_dest(life), _target['last_seen_at']) == 0: movement.position_to_attack(life, _target['life']['id']) if sight.can_see_position(life, _target['last_seen_at'], block_check=True, strict=True) and not sight.view_blocked_by_life(life, _target['last_seen_at'], allow=[_target['life']['id']]): if sight.can_see_position(life, _target['life']['pos']): if not len(lfe.find_action(life, matches=[{'action': 'shoot'}])): for i in range(weapons.get_rounds_to_fire(weapons.get_weapon_to_fire(life))): lfe.add_action(life,{'action': 'shoot', 'target': _target['last_seen_at'], 'target_id': _target['life']['id'], 'limb': 'chest'}, 5000, delay=int(round(life['recoil']-stats.get_recoil_recovery_rate(life)))) else: lfe.memory(life,'lost sight of %s' % (' '.join(_target['life']['name'])), target=_target['life']['id']) _target['escaped'] = 1 for send_to in judgement.get_trusted(life): speech.communicate(life, 'target_missing', target=_target['life']['id'], matches=[send_to]) else: print life['name'], 'waiting...' return False
def escape(life, targets): _avoid_positions = [] _zones = [zones.get_zone_at_coords(life["pos"])] if lfe.find_action(life, [{"action": "dijkstra_move", "reason": "escape"}]): if lfe.ticker(life, "escape_refresh", 4): lfe.stop(life) else: return False 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) _avoid_positions.append(_target["last_seen_at"]) lfe.add_action( life, {"action": "dijkstra_move", "rolldown": False, "zones": _zones, "goals": _avoid_positions, "reason": "escape"}, 100, )
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 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)
def ranged_combat(life, targets): _target = brain.knows_alife_by_id(life, get_closest_target(life, targets)) #if not _target: # for target_id in targets: # if brain.knows_alife_by_id(life, target_id)['escaped']: # continue # # brain.knows_alife_by_id(life, target_id)['escaped'] = 1 # # logging.error('No target for ranged combat.') # # return False _engage_distance = get_engage_distance(life) _path_dest = lfe.path_dest(life) if not _path_dest: _path_dest = life['pos'][:] _target_distance = bad_numbers.distance(life['pos'], _target['last_seen_at']) #Get us near the target #if _target['last_seen_at']: movement.position_to_attack(life, _target['life']['id'], _engage_distance) if sight.can_see_position(life, _target['last_seen_at']): if _target_distance <= _engage_distance: if sight.can_see_position(life, _target['life']['pos']): if not sight.view_blocked_by_life(life, _target['life']['pos'], allow=[_target['life']['id']]): lfe.clear_actions(life) if not len(lfe.find_action(life, matches=[{'action': 'shoot'}])) and _target['time_visible']>2: for i in range(weapons.get_rounds_to_fire(weapons.get_weapon_to_fire(life))): lfe.add_action(life, {'action': 'shoot', 'target': _target['last_seen_at'], 'target_id': _target['life']['id'], 'limb': 'chest'}, 300, delay=int(round(life['recoil']-stats.get_recoil_recovery_rate(life)))) else: _friendly_positions, _friendly_zones = get_target_positions_and_zones(life, judgement.get_trusted(life)) _friendly_zones.append(zones.get_zone_at_coords(life['pos'])) _friendly_positions.append(life['pos'][:]) if not lfe.find_action(life, [{'action': 'dijkstra_move', 'orig_goals': [_target['life']['pos'][:]], 'avoid_positions': _friendly_positions}]): lfe.add_action(life, {'action': 'dijkstra_move', 'rolldown': True, 'zones': _friendly_zones, 'goals': [_target['life']['pos'][:]], 'orig_goals': [_target['life']['pos'][:]], 'avoid_positions': _friendly_positions, 'reason': 'combat_position'}, 100) else: lfe.memory(life,'lost sight of %s' % (' '.join(_target['life']['name'])), target=_target['life']['id']) _target['escaped'] = 1 for send_to in judgement.get_trusted(life): speech.communicate(life, 'target_missing', target=_target['life']['id'], matches=[send_to]) #else: #print life['name'] #_friendly_positions, _friendly_zones = get_target_positions_and_zones(life, judgement.get_trusted(life)) #_friendly_zones.append(zones.get_zone_at_coords(life['pos'])) #_friendly_positions.append(life['pos'][:]) #if not lfe.find_action(life, [{'action': 'dijkstra_move', 'orig_goals': [_target['life']['pos'][:]], 'avoid_positions': _friendly_positions}]): # lfe.add_action(life, {'action': 'dijkstra_move', # 'rolldown': True, # 'zones': _friendly_zones, # 'goals': [_target['life']['pos'][:]], # 'orig_goals': [_target['life']['pos'][:]], # 'avoid_positions': _friendly_positions, # 'reason': 'combat_position'}, # 100) # # print '2' else: return False
def ranged_combat(life, targets): _target = brain.knows_alife_by_id(life, get_closest_target(life, targets)) #if not _target: # for target_id in targets: # if brain.knows_alife_by_id(life, target_id)['escaped']: # continue # # brain.knows_alife_by_id(life, target_id)['escaped'] = 1 # # logging.error('No target for ranged combat.') # # return False _engage_distance = get_engage_distance(life) _path_dest = lfe.path_dest(life) if not _path_dest: _path_dest = life['pos'][:] _target_distance = bad_numbers.distance(life['pos'], _target['last_seen_at']) #Get us near the target #if _target['last_seen_at']: movement.position_to_attack(life, _target['life']['id'], _engage_distance) if sight.can_see_position(life, _target['last_seen_at']): if _target_distance <= _engage_distance: if sight.can_see_position(life, _target['life']['pos']): if not sight.view_blocked_by_life( life, _target['life']['pos'], allow=[_target['life']['id']]): lfe.clear_actions(life) if not len( lfe.find_action( life, matches=[{ 'action': 'shoot' }])) and _target['time_visible'] > 2: for i in range( weapons.get_rounds_to_fire( weapons.get_weapon_to_fire(life))): lfe.add_action( life, { 'action': 'shoot', 'target': _target['last_seen_at'], 'target_id': _target['life']['id'], 'limb': 'chest' }, 300, delay=int( round( life['recoil'] - stats.get_recoil_recovery_rate(life)))) else: _friendly_positions, _friendly_zones = get_target_positions_and_zones( life, judgement.get_trusted(life)) _friendly_zones.append( zones.get_zone_at_coords(life['pos'])) _friendly_positions.append(life['pos'][:]) if not lfe.find_action( life, [{ 'action': 'dijkstra_move', 'orig_goals': [_target['life']['pos'][:]], 'avoid_positions': _friendly_positions }]): lfe.add_action( life, { 'action': 'dijkstra_move', 'rolldown': True, 'zones': _friendly_zones, 'goals': [_target['life']['pos'][:]], 'orig_goals': [_target['life']['pos'][:]], 'avoid_positions': _friendly_positions, 'reason': 'combat_position' }, 100) else: lfe.memory(life, 'lost sight of %s' % (' '.join(_target['life']['name'])), target=_target['life']['id']) _target['escaped'] = 1 for send_to in judgement.get_trusted(life): speech.communicate(life, 'target_missing', target=_target['life']['id'], matches=[send_to]) #else: #print life['name'] #_friendly_positions, _friendly_zones = get_target_positions_and_zones(life, judgement.get_trusted(life)) #_friendly_zones.append(zones.get_zone_at_coords(life['pos'])) #_friendly_positions.append(life['pos'][:]) #if not lfe.find_action(life, [{'action': 'dijkstra_move', 'orig_goals': [_target['life']['pos'][:]], 'avoid_positions': _friendly_positions}]): # lfe.add_action(life, {'action': 'dijkstra_move', # 'rolldown': True, # 'zones': _friendly_zones, # 'goals': [_target['life']['pos'][:]], # 'orig_goals': [_target['life']['pos'][:]], # 'avoid_positions': _friendly_positions, # 'reason': 'combat_position'}, # 100) # # print '2' else: return False
def understand(life): if SETTINGS['controlling']: _dist_to_player = numbers.distance( life['pos'], LIFE[SETTINGS['controlling']]['pos']) if _dist_to_player < 100: if life['think_rate_max'] >= 30: if _dist_to_player < 75: life['think_rate_max'] = 1 life['online'] = True logging.debug( '[Agent] %s brought online (Reason: Near viewer)' % ' '.join(life['name'])) else: life['think_rate_max'] = 1 else: if _dist_to_player >= OFFLINE_ALIFE_DISTANCE and life['online']: life['online'] = False logging.debug( '[Agent] %s went offline (Reason: Away from viewer)' % ' '.join(life['name'])) elif life['think_rate_max'] < 30: if _dist_to_player < OFFLINE_ALIFE_DISTANCE: life['online'] = True logging.debug( '[Agent] %s went passive (Reason: Away from viewer)' % ' '.join(life['name'])) life['think_rate_max'] = numbers.clip( 15 * (((_dist_to_player - 100) + 30) / 30), 30, 60) else: life['think_rate_max'] = 5 if not life['online'] or life['asleep']: return False if len(life['actions']) - len( lfe.find_action(life, matches=[{ 'action': 'move' }, { 'action': 'dijkstra_move' }])) > 0: lfe.clear_actions(life) life['path'] = [] return False if life['think_rate'] > 0: life['think_rate'] -= 1 return False for module in CONSTANT_MODULES: module.setup(life) life['think_rate'] = life['think_rate_max'] #if life['name'][0].startswith('Tim'): # _goal, _tier, _plan = planner.get_next_goal(life, debug='attack') #else: _goal, _tier, _plan = planner.get_next_goal(life) if _goal: lfe.change_goal(life, _goal, _tier, _plan) else: lfe.change_goal(life, 'idle', TIER_RELAXED, []) #logging.error('%s has no possible goal.' % ' '.join(life['name'])) return False planner.think(life)
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 position_to_attack(life, target, engage_distance): if lfe.find_action(life, [{ 'action': 'dijkstra_move', 'reason': 'positioning for attack' }]): if not lfe.ticker(life, 'attack_position', 4): return False _target_positions, _zones = combat.get_target_positions_and_zones( life, [target]) _can_see = alife.sight.can_see_position(life, _target_positions[0], get_path=True) _distance = bad_numbers.distance(life['pos'], _target_positions[0]) if _can_see and len(_can_see) < engage_distance * .85: if life['path']: lfe.stop(life) elif _distance < engage_distance * .9: _avoid_positions = set() _target_area = set() for life_id in alife.judgement.get_trusted(life, visible=False, only_recent=True): fov.fov(LIFE[life_id]['pos'], int(round(sight.get_vision(life) * .25)), callback=lambda pos: _avoid_positions.add(pos)) fov.fov(_target_positions[0], int(round(sight.get_vision(life) * .15)), callback=lambda pos: _target_area.add(pos)) _min_view_distance = int(round(sight.get_vision(life) * .25)) _max_view_distance = int(round(sight.get_vision(life) * .5)) _attack_positions = set( zones.dijkstra_map( life['pos'], _target_positions, _zones, rolldown=True, return_score_in_range=[_min_view_distance, _max_view_distance])) _attack_positions = _attack_positions - _target_area if not _attack_positions: return False if not lfe.find_action(life, [{ 'action': 'dijkstra_move', 'orig_goals': list(_attack_positions), 'avoid_positions': list(_avoid_positions) }]): lfe.stop(life) lfe.add_action( life, { 'action': 'dijkstra_move', 'rolldown': True, 'goals': [ list(p) for p in random.sample(_attack_positions, len(_attack_positions) / 2) ], 'orig_goals': list(_attack_positions), 'avoid_positions': list(_avoid_positions), 'reason': 'positioning for attack' }, 999) return False else: _can_see_positions = set() _target_area = set() _avoid_positions = set() fov.fov(life['pos'], int(round(sight.get_vision(life) * .75)), callback=lambda pos: _can_see_positions.add(pos)) fov.fov(_target_positions[0], int(round(sight.get_vision(life) * .75)), callback=lambda pos: _target_area.add(pos)) for life_id in alife.judgement.get_trusted(life, visible=False, only_recent=True): _path_dest = lfe.path_dest(LIFE[life_id]) if not _path_dest: continue if len(_path_dest) == 2: _path_dest = list(_path_dest[:]) _path_dest.append(LIFE[life_id]['pos'][2]) fov.fov(_path_dest, 5, callback=lambda pos: _avoid_positions.add(pos)) _avoid_positions = list(_avoid_positions) _sneak_positions = _can_see_positions - _target_area _move_positions = zones.dijkstra_map(LIFE[target]['pos'], list(_sneak_positions), _zones, rolldown=True) if not _move_positions: travel_to_position(life, list(_target_positions[0])) return False if not lfe.find_action(life, [{ 'action': 'dijkstra_move', 'orig_goals': _move_positions, 'avoid_positions': _avoid_positions }]): lfe.stop(life) lfe.add_action( life, { 'action': 'dijkstra_move', 'rolldown': True, 'goals': [list(p) for p in _move_positions], 'orig_goals': _move_positions, 'avoid_positions': _avoid_positions, 'reason': 'positioning for attack' }, 999) return False return True
def fire(life, target, limb=None): #TODO: Don't breathe this! weapon = get_weapon_to_fire(life) if not weapon: return False _aim_with_limb = None for hand in life['hands']: if weapon['uid'] in lfe.get_limb(life, hand)['holding']: _aim_with_limb = hand _ooa = False _feed_uid = get_feed(weapon) if not _feed_uid: if 'player' in life: gfx.message('The weapon is unloaded.') _ooa = True return False _feed = items.get_item_from_uid(_feed_uid) if not _feed or (_feed and not _feed['rounds']): if 'player' in life: gfx.message('*Click* (You are out of ammo.)') _ooa = True return False _bullet_deviation = (1 - weapon['accuracy']) + life['recoil'] _deviation_mod = SETTINGS['aim_difficulty'] * (1 - ( (life['stats']['firearms'] / 10.0) * SETTINGS['firearms_skill_mod'])) _direction_deviation = (_bullet_deviation * SETTINGS['aim_difficulty']) * _deviation_mod life['recoil'] = bad_numbers.clip( life['recoil'] + (weapon['recoil'] * get_stance_recoil_mod(life)), 0.0, 1.0) _bullet_direction = bad_numbers.direction_to(life['pos'], target) + ( random.uniform(-_direction_deviation, _direction_deviation)) alife.noise.create(life['pos'], 120, '%s fire' % weapon['name'], 'something discharge', target=life['id']) #TODO: Clean this up... _bullet = items.get_item_from_uid(_feed['rounds'].pop()) _bullet['pos'] = life['pos'][:] _bullet['start_pos'] = life['pos'][:] _bullet['owner'] = None _bullet['shot_by'] = life['id'] _bullet['aim_at_limb'] = limb items.add_to_chunk(_bullet) if gfx.position_is_in_frame(life['pos']) or 'player' in life: effects.create_light(life['pos'], tcod.yellow, 7, 1, fade=3.2) effects.create_light(_bullet['pos'], tcod.yellow, 7, .9, fade=.65, follow_item=_bullet['uid']) effects.create_smoke_cloud(life['pos'], 3, color=tcod.light_gray) effects.create_smoke(life['pos'], color=tcod.yellow) _bullet['accuracy'] = int( round(get_accuracy(life, weapon['uid'], limb=_aim_with_limb))) print 'ACCURACY', _bullet['accuracy'] del _bullet['parent'] items.move(_bullet, _bullet_direction, _bullet['max_speed']) _bullet['start_velocity'] = _bullet['velocity'][:] items.tick_item(_bullet) for _life in [LIFE[i] for i in LIFE]: if _life['pos'][0] == target[0] and _life['pos'][1] == target[1]: life['aim_at'] = _life['id'] break if len(lfe.find_action(life, matches=[{'action': 'shoot'}])) == 1: life['firing'] = None
def manage_inventory(life): if manage_hands(life): return False for weapon_uid in combat.get_equipped_weapons(life): if not combat.weapon_is_working(life, weapon_uid): if combat.weapon_is_in_preferred_working_condition( life, weapon_uid): if not len( lfe.find_action(life, matches=[{ 'action': 'refillammo' }])): combat.reload_weapon(life, weapon_uid) return True _item_to_wear = {'score': 0, 'item_uid': None} _item_to_equip = {'score': 0, 'item_uid': None} for item in [ lfe.get_inventory_item(life, item) for item in lfe.get_all_unequipped_items(life) ]: judgement.judge_item(life, item['uid']) _known_item = brain.get_remembered_item(life, item['uid']) if _known_item['score']: if lfe.can_wear_item(life, item['uid']): if _known_item['score'] > _item_to_wear['score']: _item_to_wear['score'] = _known_item['score'] _item_to_wear['item_uid'] = item['uid'] else: if rawparse.raw_has_section( life, 'items') and rawparse.raw_section_has_identifier( life, 'items', item['type']): _action = lfe.execute_raw(life, 'items', item['type']) if item['type'] == 'gun' and lfe.get_all_equipped_items( life, matches=[{ 'type': 'gun' }]): continue if _action == 'equip': if _known_item['score'] > _item_to_equip['score']: _item_to_equip['score'] = _known_item['score'] _item_to_equip['item_uid'] = item['uid'] _item = None if _item_to_wear['score'] > _item_to_equip['score']: _item = _item_to_wear['item_uid'] elif _item_to_equip['item_uid']: _item = _item_to_equip['item_uid'] if _item: _equip_action = {'action': 'equipitem', 'item': _item} if len(lfe.find_action(life, matches=[_equip_action])): return False lfe.add_action(life, _equip_action, 401, delay=lfe.get_item_access_time(life, _item)) return False return True
def fire(life, target, limb=None): #TODO: Don't breathe this! weapon = get_weapon_to_fire(life) if not weapon: return False _aim_with_limb = None for hand in life['hands']: if weapon['uid'] in lfe.get_limb(life, hand)['holding']: _aim_with_limb = hand _ooa = False _feed_uid = get_feed(weapon) if not _feed_uid: if 'player' in life: gfx.message('The weapon is unloaded.') _ooa = True return False _feed = items.get_item_from_uid(_feed_uid) if not _feed or (_feed and not _feed['rounds']): if 'player' in life: gfx.message('*Click* (You are out of ammo.)') _ooa = True return False direction = numbers.direction_to(life['pos'],target)+(random.uniform(-life['recoil'], life['recoil'])) alife.noise.create(life['pos'], 120, '%s fire' % weapon['name'], 'something discharge') #TODO: Clean this up... _bullet = items.get_item_from_uid(_feed['rounds'].pop()) _bullet['pos'] = life['pos'][:] _bullet['start_pos'] = life['pos'][:] _bullet['owner'] = None _bullet['shot_by'] = life['id'] _bullet['aim_at_limb'] = limb life['recoil'] += _bullet['recoil']*(weapon['recoil']*get_stance_recoil_mod(life)) items.add_to_chunk(_bullet) if gfx.position_is_in_frame(life['pos']): effects.create_light(life['pos'], tcod.yellow, 7, 1, fade=3.5) effects.create_light(_bullet['pos'], tcod.yellow, 7, 1, fade=0.65, follow_item=_bullet['uid']) effects.create_smoke_cloud(life['pos'], 3, color=tcod.light_gray) effects.create_smoke(life['pos'], color=tcod.yellow) _bullet['accuracy'] = int(round(get_accuracy(life, weapon['uid'], limb=_aim_with_limb))) del _bullet['parent'] items.move(_bullet, direction, _bullet['max_speed']) _bullet['start_velocity'] = _bullet['velocity'][:] items.tick_item(_bullet) for _life in [LIFE[i] for i in LIFE]: if _life['pos'][0] == target[0] and _life['pos'][1] == target[1]: life['aim_at'] = _life['id'] break if len(lfe.find_action(life, matches=[{'action': 'shoot'}])) == 1: life['firing'] = None
def position_to_attack(life, target, engage_distance): if lfe.find_action(life, [{"action": "dijkstra_move", "reason": "positioning for attack"}]): if not lfe.ticker(life, "attack_position", 4): return False _target_positions, _zones = combat.get_target_positions_and_zones(life, [target]) _can_see = alife.sight.can_see_position(life, _target_positions[0], get_path=True) _distance = numbers.distance(life["pos"], _target_positions[0]) if _can_see and len(_can_see) < engage_distance * 0.85: if life["path"]: lfe.stop(life) elif _distance < engage_distance * 0.9: _avoid_positions = set() _target_area = set() for life_id in alife.judgement.get_trusted(life, visible=False, only_recent=True): fov.fov( LIFE[life_id]["pos"], int(round(sight.get_vision(life) * 0.25)), callback=lambda pos: _avoid_positions.add(pos), ) fov.fov( _target_positions[0], int(round(sight.get_vision(life) * 0.15)), callback=lambda pos: _target_area.add(pos) ) _min_view_distance = int(round(sight.get_vision(life) * 0.25)) _max_view_distance = int(round(sight.get_vision(life) * 0.5)) _attack_positions = set( zones.dijkstra_map( life["pos"], _target_positions, _zones, rolldown=True, return_score_in_range=[_min_view_distance, _max_view_distance], ) ) _attack_positions = _attack_positions - _target_area if not _attack_positions: return False if not lfe.find_action( life, [ { "action": "dijkstra_move", "orig_goals": list(_attack_positions), "avoid_positions": list(_avoid_positions), } ], ): lfe.stop(life) lfe.add_action( life, { "action": "dijkstra_move", "rolldown": True, "goals": [list(p) for p in random.sample(_attack_positions, len(_attack_positions) / 2)], "orig_goals": list(_attack_positions), "avoid_positions": list(_avoid_positions), "reason": "positioning for attack", }, 999, ) return False else: _can_see_positions = set() _target_area = set() _avoid_positions = set() fov.fov( life["pos"], int(round(sight.get_vision(life) * 0.75)), callback=lambda pos: _can_see_positions.add(pos) ) fov.fov( _target_positions[0], int(round(sight.get_vision(life) * 0.75)), callback=lambda pos: _target_area.add(pos) ) for life_id in alife.judgement.get_trusted(life, visible=False, only_recent=True): _path_dest = lfe.path_dest(LIFE[life_id]) if not _path_dest: continue if len(_path_dest) == 2: _path_dest = list(_path_dest[:]) _path_dest.append(LIFE[life_id]["pos"][2]) fov.fov(_path_dest, 5, callback=lambda pos: _avoid_positions.add(pos)) _avoid_positions = list(_avoid_positions) _sneak_positions = _can_see_positions - _target_area _move_positions = zones.dijkstra_map(LIFE[target]["pos"], list(_sneak_positions), _zones, rolldown=True) if not _move_positions: travel_to_position(life, list(_target_positions[0])) return False if not lfe.find_action( life, [{"action": "dijkstra_move", "orig_goals": _move_positions, "avoid_positions": _avoid_positions}] ): lfe.stop(life) lfe.add_action( life, { "action": "dijkstra_move", "rolldown": True, "goals": [list(p) for p in _move_positions], "orig_goals": _move_positions, "avoid_positions": _avoid_positions, "reason": "positioning for attack", }, 999, ) return False return True