Beispiel #1
0
def get_exposed_positions(life):
	_cover_exposed_at = brain.get_flag(life, 'cover_exposed_at')
	
	if _cover_exposed_at:
		return _cover_exposed_at
	
	return []
Beispiel #2
0
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)
Beispiel #3
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
Beispiel #4
0
def get_exposed_positions(life):
    _cover_exposed_at = brain.get_flag(life, 'cover_exposed_at')

    if _cover_exposed_at:
        return _cover_exposed_at

    return []
Beispiel #5
0
def is_tracking(life, target_id):
	_targets = brain.get_flag(life, 'tracking_targets')

	if not _targets:
		return False
	
	return target_id in _targets
Beispiel #6
0
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)
Beispiel #7
0
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
Beispiel #8
0
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
Beispiel #9
0
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
Beispiel #10
0
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
Beispiel #11
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
Beispiel #12
0
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)
Beispiel #13
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)
Beispiel #14
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)
Beispiel #15
0
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
Beispiel #16
0
def untrack_target(life, target_id):
	_tracking = brain.get_flag(life, 'tracking_targets')
	
	if target_id in _tracking:
		_tracking.remove(target_id)
Beispiel #17
0
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
Beispiel #18
0
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)
Beispiel #19
0
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
Beispiel #20
0
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
Beispiel #21
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
Beispiel #22
0
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,
    )
Beispiel #23
0
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
Beispiel #24
0
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)
Beispiel #25
0
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)
Beispiel #26
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
Beispiel #27
0
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)