Example #1
0
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)
Example #2
0
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)
Example #3
0
def conditions(life, alife_seen, alife_not_seen, targets_seen, targets_not_seen, source_map):
	RETURN_VALUE = STATE_UNCHANGED
	
	_mode = None
	if lfe.execute_raw(life, 'state', 'combat'):
		_mode = 'combat'
	
	if not _mode and lfe.execute_raw(life, 'state', 'hunt'):
		_mode = 'hunt'
	
	if not _mode:
		return False
	
	if not lfe.execute_raw(life, 'combat', 'ranged') and not lfe.execute_raw(life, 'combat', 'melee'):
		return False
	
	if not life['state'] == STATE:
		life['state_flags'] = {}
		stats.battle_cry(life)
		
		if gfx.position_is_in_frame(life['pos']) and SETTINGS['controlling']:
			_can_see = sight.can_see_position(life, LIFE[SETTINGS['controlling']]['pos'])
			
			if _can_see:
				_knows = brain.knows_alife_by_id(life, SETTINGS['controlling'])
				
				if _knows and judgement.can_trust(life, SETTINGS['controlling']):
					if lfe.ticker(life, 'enter_combat_message', 3, fire=True):
						logic.show_event('%s readies up.' % ' '.join(life['name']), life=life)
		
		RETURN_VALUE = STATE_CHANGE
	
	brain.flag(life, 'combat_mode', value=_mode)
	
	return RETURN_VALUE
Example #4
0
def tick(life, alife_seen, alife_not_seen, targets_seen, targets_not_seen, source_map):
	if lfe.ticker(life, 'call_for_help', 160, fire=True):
		_target = judgement.get_nearest_threat(life)
		_knows = brain.knows_alife_by_id(life, _target)
		if _target and judgement.get_nearest_trusted_target(life):
			if _knows:
				speech.announce(life, 'attacked_by_hostile', public=True, target_id=_target, last_seen_at=_knows['last_seen_at'])
			else:
				speech.announce(life, 'attacked_by_hostile', public=True, target_id=_target)
Example #5
0
def tick(life, alife_seen, alife_not_seen, targets_seen, targets_not_seen, source_map):
	if lfe.ticker(life, 'call_for_help', 160, fire=True):
		_target = judgement.get_nearest_threat(life)
		_knows = brain.knows_alife_by_id(life, _target)
		if _target and judgement.get_nearest_trusted_target(life):
			if _knows:
				speech.announce(life, 'attacked_by_hostile', public=True, target_id=_target, last_seen_at=_knows['last_seen_at'])
			else:
				speech.announce(life, 'attacked_by_hostile', public=True, target_id=_target)
Example #6
0
def judge_chunk_visually(life, chunk_id):
	if not chunk_id in life['known_chunks']:
		life['known_chunks'][chunk_id] = {'last_visited': -1,
			'last_seen': -1,
			'last_checked': -1,
			'discovered_at': WORLD_INFO['ticks'],
			'flags': {},
			'life': [],
			'score': 0}
	
	if lfe.ticker(life, 'judge_shelters', 5):
		if lfe.execute_raw(life, 'discover', 'remember_shelter'):
			judge_shelter(life, chunk_id)
Example #7
0
def judge_chunk_life(life, chunk_id):
	if lfe.ticker(life, 'judge_chunk_life_tick', 30):
		return False
	
	_score = 0
	for life_id in life['known_chunks'][chunk_id]['life']:
		_target = brain.knows_alife_by_id(life, life_id)
		_is_here = False
		_actually_here = False
		
		if not _target['last_seen_at'] or not chunks.position_is_in_chunk(_target['last_seen_at'], chunk_id) and not _target['life']['path']:
			continue
	
	return _score 
Example #8
0
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
Example #9
0
def judge_chunk_visually(life, chunk_id):
    if not chunk_id in life["known_chunks"]:
        life["known_chunks"][chunk_id] = {
            "last_visited": -1,
            "last_seen": -1,
            "last_checked": -1,
            "discovered_at": WORLD_INFO["ticks"],
            "flags": {},
            "life": [],
            "score": 0,
        }

    if lfe.ticker(life, "judge_shelters", 5):
        if lfe.execute_raw(life, "discover", "remember_shelter"):
            judge_shelter(life, chunk_id)
Example #10
0
def judge_chunk_life(life, chunk_id):
    if lfe.ticker(life, "judge_chunk_life_tick", 30):
        return False

    _score = 0
    for life_id in life["known_chunks"][chunk_id]["life"]:
        _target = brain.knows_alife_by_id(life, life_id)
        _is_here = False
        _actually_here = False

        if (
            not _target["last_seen_at"]
            or not chunks.position_is_in_chunk(_target["last_seen_at"], chunk_id)
            and not _target["life"]["path"]
        ):
            continue

    return _score
Example #11
0
def conditions(life, alife_seen, alife_not_seen, targets_seen,
               targets_not_seen, source_map):
    RETURN_VALUE = STATE_UNCHANGED

    _mode = None
    if lfe.execute_raw(life, 'state', 'combat'):
        _mode = 'combat'

    if not _mode and lfe.execute_raw(life, 'state', 'hunt'):
        _mode = 'hunt'

    if not _mode:
        return False

    if not lfe.execute_raw(life, 'combat', 'ranged') and not lfe.execute_raw(
            life, 'combat', 'melee'):
        return False

    if not life['state'] == STATE:
        life['state_flags'] = {}
        stats.battle_cry(life)

        if gfx.position_is_in_frame(life['pos']) and SETTINGS['controlling']:
            _can_see = sight.can_see_position(
                life, LIFE[SETTINGS['controlling']]['pos'])

            if _can_see:
                _knows = brain.knows_alife_by_id(life, SETTINGS['controlling'])

                if _knows and judgement.can_trust(life,
                                                  SETTINGS['controlling']):
                    if lfe.ticker(life, 'enter_combat_message', 3, fire=True):
                        logic.show_event('%s readies up.' %
                                         ' '.join(life['name']),
                                         life=life)

        RETURN_VALUE = STATE_CHANGE

    brain.flag(life, 'combat_mode', value=_mode)

    return RETURN_VALUE
Example #12
0
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,
    )
Example #13
0
def judge_chunk(life, chunk_id, visited=False, seen=False, checked=True, investigate=False):
    if lfe.ticker(life, "judge_tick", 30):
        return False

    chunk = maps.get_chunk(chunk_id)
    _score = 0

    if not chunk_id in life["known_chunks"]:
        life["known_chunks"][chunk_id] = {
            "last_visited": -1,
            "last_seen": -1,
            "last_checked": -1,
            "discovered_at": WORLD_INFO["ticks"],
            "flags": {},
            "life": [],
        }

    _camp = chunks.get_global_flag(chunk_id, "camp")
    if _camp and not _camp in life["known_camps"]:
        camps.discover_camp(life, _camp)

    _known_chunk = life["known_chunks"][chunk_id]

    if seen:
        _known_chunk["last_seen"] = WORLD_INFO["ticks"]

    if visited:
        _known_chunk["last_visited"] = WORLD_INFO["ticks"]
        _known_chunk["last_seen"] = WORLD_INFO["ticks"]

    if checked:
        _known_chunk["last_checked"] = WORLD_INFO["ticks"]

    _trusted = 0
    for _target in life["know"].values():
        if not _target["last_seen_at"]:
            continue

        _is_here = False
        _actually_here = False

        if chunks.position_is_in_chunk(_target["last_seen_at"], chunk_id) and not _target["life"]["path"]:
            _is_here = True
        elif (
            not _target["last_seen_time"]
            and _target["life"]["path"]
            and chunks.position_is_in_chunk(lfe.path_dest(_target["life"]), chunk_id)
        ):
            _is_here = True

        if chunks.position_is_in_chunk(_target["life"]["pos"], chunk_id):
            _actually_here = True

        if _is_here:
            if not _target["life"]["id"] in _known_chunk["life"]:
                _known_chunk["life"].append(_target["life"]["id"])

            if is_target_dangerous(life, _target["life"]["id"]):
                _score -= 10
            elif life["group"] and groups.is_leader(life, life["group"], _target["life"]["id"]):
                _trusted += _target["trust"]
        else:
            if _target["life"]["id"] in _known_chunk["life"]:
                _known_chunk["life"].remove(_target["life"]["id"])

    if investigate and not visited:
        chunks.flag(life, chunk_id, "investigate", True)
    elif visited and chunks.get_flag(life, chunk_id, "investigate"):
        chunks.unflag(life, chunk_id, "investigate")

    if chunks.get_flag(life, chunk_id, "investigate"):
        _score += 5

        # for camp in life['known_camps']:
        # 	if not chunk_id in camps.get_camp(camp)['reference']:
        # 		continue

        # if not life['camp'] == camp['id']:
        # 	continue

        # if stats.desires_shelter(life):
        # 	_score += judge_camp(life, life['camp'])

    if lfe.execute_raw(life, "discover", "remember_shelter"):
        judge_shelter(life, chunk_id)

        # if stats.desires_interaction(life):
        # 	_score += _trusted

    if seen:
        pass
        # TODO: Still a good idea... maybe use for shelter?
        # for item in chunk['items']:
        # 	_item = brain.remember_known_item(life, item)
        # 	if _item:
        # 		_score += _item['score']

    life["known_chunks"][chunk_id]["score"] = _score

    return _score
Example #14
0
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
Example #15
0
def act(life):
	understand(life)
	
	if lfe.ticker(life, 'update_camps', UPDATE_CAMP_RATE):
		judgement.update_camps(life)
Example #16
0
def act(life):
    understand(life)

    if lfe.ticker(life, 'update_camps', UPDATE_CAMP_RATE):
        judgement.update_camps(life)
Example #17
0
def judge_chunk(life, chunk_id, visited=False, seen=False, checked=True, investigate=False):
	if lfe.ticker(life, 'judge_tick', 30):
		return False
	
	chunk = maps.get_chunk(chunk_id)
	_score = 0
	
	if not chunk_id in life['known_chunks']:
		life['known_chunks'][chunk_id] = {'last_visited': -1,
			'last_seen': -1,
			'last_checked': -1,
			'discovered_at': WORLD_INFO['ticks'],
			'flags': {},
			'life': []}
	
	_camp = chunks.get_global_flag(chunk_id, 'camp')
	if _camp and not _camp in life['known_camps']:
		camps.discover_camp(life, _camp)
	
	_known_chunk = life['known_chunks'][chunk_id]	
	
	if seen:
		_known_chunk['last_seen'] = WORLD_INFO['ticks']
	
	if visited:
		_known_chunk['last_visited'] = WORLD_INFO['ticks']
		_known_chunk['last_seen'] = WORLD_INFO['ticks']
	
	if checked:
		_known_chunk['last_checked'] = WORLD_INFO['ticks']
	
	_trusted = 0
	for _target in life['know'].values():
		if not _target['last_seen_at']:
			continue
		
		_is_here = False
		_actually_here = False
		
		if chunks.position_is_in_chunk(_target['last_seen_at'], chunk_id) and not _target['life']['path']:
			_is_here = True
		elif not _target['last_seen_time'] and _target['life']['path'] and chunks.position_is_in_chunk(lfe.path_dest(_target['life']), chunk_id):
			_is_here = True
		
		if chunks.position_is_in_chunk(_target['life']['pos'], chunk_id):
			_actually_here = True
			
		if _is_here:
			if not _target['life']['id'] in _known_chunk['life']:
				_known_chunk['life'].append(_target['life']['id'])
			
			if is_target_dangerous(life, _target['life']['id']):
				_score -= 10
			elif life['group'] and groups.is_leader(life, life['group'], _target['life']['id']):
				_trusted += _target['trust']
		else:
			if _target['life']['id'] in _known_chunk['life']:
				_known_chunk['life'].remove(_target['life']['id'])
	
	if investigate and not visited:
		chunks.flag(life, chunk_id, 'investigate', True)
	elif visited and chunks.get_flag(life, chunk_id, 'investigate'):
		chunks.unflag(life, chunk_id, 'investigate')
	
	if chunks.get_flag(life, chunk_id, 'investigate'):
		_score += 5
	
	#for camp in life['known_camps']:
	#	if not chunk_id in camps.get_camp(camp)['reference']:
	#		continue
		
		
		#if not life['camp'] == camp['id']:
		#	continue
	
		#if stats.desires_shelter(life):
		#	_score += judge_camp(life, life['camp'])
	
	if lfe.execute_raw(life, 'discover', 'remember_shelter'):
		judge_shelter(life, chunk_id)
	
	#if stats.desires_interaction(life):
	#	_score += _trusted
	
	if seen:
		pass
		#TODO: Still a good idea... maybe use for shelter?
		#for item in chunk['items']:
		#	_item = brain.remember_known_item(life, item)
		#	if _item:
		#		_score += _item['score']

	life['known_chunks'][chunk_id]['score'] = _score
	
	return _score
Example #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)
Example #19
0
def setup(life):
	#TODO: Add these two values to an array called PANIC_STATES
	#if not alife_seen:
	#	return False
	#if brain.retrieve_from_memory(life, 'tension_spike') >= 10:
	#	lfe.say(life, '@n panics!', action=True)
	
	_potential_talking_targets = []
	for ai in life['seen']:
		if not stats.can_talk_to(life, ai):
			continue
		
		#print life['name'], LIFE[ai]['name'], judgement.get_tension_with(life, ai)
		
		if stats.has_attacked_self(life, ai):
			stats.react_to_attack(life, ai)
		elif 0<judgement.get_tension_with(life, ai)<=judgement.get_max_tension_with(life, ai):
			stats.react_to_tension(life, ai)
		else:
			#if not stats.desires_first_contact_with(life, ai) and not stats.desires_conversation_with(life, ai):
			#	continue
			if not stats.desires_conversation_with(life, ai):
				continue
	
			_potential_talking_targets.append(ai)
	
	if not _potential_talking_targets:
		if life['dialogs']:
			_dialog = life['dialogs'][0]
			dialog.process(life, _dialog)
		
		if not lfe.ticker(life, 'talk', 6):
			return False
	
	if lfe.get_all_inventory_items(life, matches=[{'type': 'radio'}]):
		for ai in life['know']:
			if ai in _potential_talking_targets:
				continue
			
			if not stats.can_talk_to(life, ai):
				continue
			
			_potential_talking_targets.append(ai)
	
	#TODO: Score these
	random.shuffle(_potential_talking_targets)
	
	for target in _potential_talking_targets:
		if life['dialogs']:
			break
		
		#if stats.desires_first_contact_with(life, target):
		#	memory.create_question(life, target, 'establish_relationship', ignore_if_said_in_last=-1)
		
		if memory.get_questions_for_target(life, target):
			_question = memory.ask_target_question(life, target)
			speech.start_dialog(life, target, _question['gist'], **_question['args'])
		elif memory.get_orders_for_target(life, target):
			speech.start_dialog(life, target, 'give_order')
		elif stats.wants_group_member(life, target):
			memory.create_question(life, target, 'recruit', ignore_if_said_in_last=-1, group_id=life['group'])
	
	if life['dialogs']:
		_dialog = life['dialogs'][0]
		dialog.process(life, _dialog)	
	
	if not judgement.is_safe(life) and lfe.ticker(life, 'call_for_help', 90, fire=True):
		_combat_targets = judgement.get_ready_combat_targets(life)
		
		if _combat_targets:
			if life['camp'] and camps.is_in_camp(life, lfe.get_current_camp(life)):
				_nearest_camp = camps.get_nearest_known_camp(life)
				raids.create_raid(_nearest_camp['id'], join=life['id'])
				raids.add_raiders(_nearest_camp['id'], _combat_targets)
				
				#TODO: Remove memory call
				speech.announce(life,
					'camp_raid',
					camp=_nearest_camp,
					raiders=_combat_targets)
			
			if life['group']:
				for target in _combat_targets:
					_last_seen_at = None
					_know = brain.knows_alife_by_id(life, target)
					
					if _know:
						_last_seen_at = _know['last_seen_at']
						
					groups.distribute(life, 'under_attack', attacker=target, last_seen_at=_last_seen_at)
		
		for target in judgement.get_ready_combat_targets(life):
			_last_seen_at = None
			_know = brain.knows_alife_by_id(life, target)
			
			if _know:
				_last_seen_at = _know['last_seen_at']

			speech.announce(life, 'attacked_by_hostile', trusted=True, target_id=target, last_seen_at=_last_seen_at)

	_visible_items = [life['know_items'][item] for item in life['know_items'] if not life['know_items'][item]['last_seen_time'] and not 'parent_id' in ITEMS[life['know_items'][item]['item']]]
	for ai in [life['know'][i] for i in life['know']]:
		if judgement.is_target_dangerous(life, ai['life']['id']):
			continue
		
		#if life['state'] == 'combat':
		#	break
		
		if ai['life']['state'] in ['hiding', 'hidden']:
			break
		
		if not stats.can_talk_to(life, ai['life']['id']):
			continue

		for item in _visible_items:
			#TODO: Check
			if brain.has_shared_item_with(life, ai['life'], item['item']):
				continue

			if not item['item'] in ITEMS:
				continue

			brain.share_item_with(life, ai['life'], item['item'])
			speech.communicate(life,
				'share_item_info',
				item=item['item'],
				matches=[ai['life']['id']])
Example #20
0
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
Example #21
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)
Example #22
0
def setup(life):
	#TODO: Add these two values to an array called PANIC_STATES
	#if not alife_seen:
	#	return False
	#if brain.retrieve_from_memory(life, 'tension_spike') >= 10:
	#	lfe.say(life, '@n panics!', action=True)
	_needs_help = stats.is_injured(life)
	
	_potential_talking_targets = []
	for ai in life['seen']:
		if not stats.can_talk_to(life, ai):
			continue
		
		_relationship_change = stats.wants_alignment_change(life, ai)
		
		#if 'player' in LIFE[ai]:
		#	print life['name'], LIFE[ai]['name'], judgement.get_tension_with(life, ai)>judgement.get_max_tension_with(life, ai), _relationship_change
		
		if stats.has_attacked_self(life, ai):
			stats.react_to_attack(life, ai)
		elif judgement.get_tension_with(life, ai)>judgement.get_max_tension_with(life, ai):
			stats.react_to_tension(life, ai)
		elif _needs_help:
			if stats.desires_help_from(life, ai):
				stats.ask_for_help(life, ai)
		elif _relationship_change:
			speech.change_alignment(life, ai, _relationship_change)
		else:
			if not stats.desires_conversation_with(life, ai):
				continue
	
			_potential_talking_targets.append(ai)
	
	if not _potential_talking_targets:
		if life['dialogs']:
			_dialog = life['dialogs'][0]
			dialog.process(life, _dialog)
		
		if not lfe.ticker(life, 'talk', 6):
			return False
	
	if lfe.get_all_inventory_items(life, matches=[{'type': 'radio'}]):
		for ai in life['know']:
			if ai in _potential_talking_targets:
				continue
			
			if not stats.can_talk_to(life, ai):
				continue
			
			_potential_talking_targets.append(ai)
	
	#TODO: Score these
	random.shuffle(_potential_talking_targets)
	
	for target in _potential_talking_targets:
		if life['dialogs']:
			break
		
		#if stats.desires_first_contact_with(life, target):
		#	memory.create_question(life, target, 'establish_relationship', ignore_if_said_in_last=-1)
		
		if memory.get_questions_for_target(life, target) and numbers.distance(life['pos'], LIFE[target]['pos'])<=25:
			_question = memory.ask_target_question(life, target)
			speech.start_dialog(life, target, _question['gist'], **_question['args'])
		elif memory.get_orders_for_target(life, target):
			speech.start_dialog(life, target, 'give_order')
		#elif stats.wants_group_member(life, target):
		#	memory.create_question(life, target, 'recruit', ignore_if_said_in_last=-1, group_id=life['group'])
	
	if life['dialogs']:
		_dialog = life['dialogs'][0]
		dialog.process(life, _dialog)
	
	if not judgement.is_safe(life) and lfe.ticker(life, 'call_for_help', 90, fire=True):
		_combat_targets = judgement.get_ready_combat_targets(life)
		
		if _combat_targets:
			if life['camp'] and camps.is_in_camp(life, lfe.get_current_camp(life)):
				_nearest_camp = camps.get_nearest_known_camp(life)
				raids.create_raid(_nearest_camp['id'], join=life['id'])
				raids.add_raiders(_nearest_camp['id'], _combat_targets)
				
				#TODO: Remove memory call
				speech.announce(life,
					'camp_raid',
					camp=_nearest_camp,
					raiders=_combat_targets)
			
			if life['group']:
				for target in _combat_targets:
					_last_seen_at = None
					_know = brain.knows_alife_by_id(life, target)
					
					if _know:
						_last_seen_at = _know['last_seen_at']
						
					groups.distribute(life, 'under_attack', attacker=target, last_seen_at=_last_seen_at)
		
		for target in judgement.get_ready_combat_targets(life):
			_last_seen_at = None
			_know = brain.knows_alife_by_id(life, target)
			
			if _know:
				_last_seen_at = _know['last_seen_at']

			speech.announce(life,
			                'attacked_by_hostile',
			                trusted=True,
			                target_id=target,
			                filter_if=lambda life_id: brain.knows_alife_by_id(life, life_id)['last_seen_time']<=30,
			                last_seen_at=_last_seen_at,
			                ignore_if_said_in_last=150)

	_visible_items = [life['know_items'][item] for item in life['know_items'] if not life['know_items'][item]['last_seen_time'] and not 'parent_id' in ITEMS[life['know_items'][item]['item']]]
	for ai in [life['know'][i] for i in life['know']]:
		if judgement.is_target_dangerous(life, ai['life']['id']):
			continue
		
		#if life['state'] == 'combat':
		#	break
		
		if ai['life']['state'] in ['hiding', 'hidden']:
			break
		
		if not stats.can_talk_to(life, ai['life']['id']):
			continue

		for item in _visible_items:
			#TODO: Check
			if brain.has_shared_item_with(life, ai['life'], item['item']):
				continue

			if not item['item'] in ITEMS:
				continue

			brain.share_item_with(life, ai['life'], item['item'])
			speech.communicate(life,
				'share_item_info',
				item=item['item'],
				matches=[ai['life']['id']])
Example #23
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)
Example #24
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,
    )
Example #25
0
def order_to_loot(life, group_id, add_leader=False):
    #TODO: We should really consider moving the needs portion of this code outside of this function
    #Because this function really only does something on the first run, rendering it into just another
    #announce loop...

    _group = get_group(life, group_id)

    _requirements = [
        action.make_small_script(function='has_number_of_items_matching',
                                 args={
                                     'matching': [{
                                         'type': 'drink'
                                     }],
                                     'amount': 1
                                 })
    ]

    _j = jobs.create_job(life,
                         'Loot for group %s.' % life['group'],
                         gist='loot_for_group',
                         description='Collect loot for group.',
                         group=life['group'],
                         requirements=_requirements)

    if _j:
        for member in _group['members']:
            if member == _group['leader'] and not add_leader:
                continue

            survival.add_needed_item(LIFE[member], {'type': 'drink'},
                                     amount=1,
                                     pass_if=_requirements,
                                     satisfy_if=action.make_small_script(
                                         function='group_needs_resources',
                                         args={'group_id': group_id}),
                                     satisfy_callback=action.make_small_script(
                                         return_function='pass'))

        jobs.add_task(_j,
                      '0',
                      'bring_back_loot',
                      action.make_small_script(function='find_target',
                                               kwargs={
                                                   'target': _group['leader'],
                                                   'distance': 5,
                                                   'follow': False
                                               }),
                      player_action=action.make_small_script(
                          function='can_see_target',
                          kwargs={'target_id': _group['leader']}),
                      description='Drop the item off at the camp',
                      delete_on_finish=False)

        jobs.add_task(
            _j,
            '1',
            'flag_item',
            action.make_small_script(function='flag_item_matching',
                                     kwargs={
                                         'matching': {
                                             'type': 'drink'
                                         },
                                         'flag': 'ignore'
                                     }),
            player_action=action.make_small_script(function='always'),
            description='Ignore this',
            delete_on_finish=False)

        jobs.add_task(_j,
                      '2',
                      'drop_item',
                      action.make_small_script(
                          function='drop_item_matching',
                          kwargs={'matching': {
                              'type': 'drink'
                          }}),
                      player_action=action.make_small_script(function='never'),
                      description='Drop the item off at the camp',
                      delete_on_finish=False)

        flag(group_id, 'loot', _j)

    if lfe.ticker(life, 'resource_announce', 10):
        _job_id = get_flag(group_id, 'loot')

        announce(
            life,
            life['group'],
            'job',
            'We need more resources.',
            job_id=_job_id,
            order=True,
            filter_if=[action.make_small_script(function='has_needs_to_meet')])
Example #26
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
Example #27
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
Example #28
0
def order_to_loot(life, group_id, add_leader=False):
	#TODO: We should really consider moving the needs portion of this code outside of this function
	#Because this function really only does something on the first run, rendering it into just another
	#announce loop...
	
	_group = get_group(life, group_id)
	
	_requirements = [action.make_small_script(function='has_number_of_items_matching',
	                                          args={'matching': [{'type': 'drink'}], 'amount': 1})]
	
	_j = jobs.create_job(life, 'Loot for group %s.' % life['group'],
	                     gist='loot_for_group',
	                     description='Collect loot for group.',
	                     group=life['group'],
	                     requirements=_requirements)
	
	if _j:
		for member in _group['members']:
			if member == _group['leader'] and not add_leader:
				continue
			
			survival.add_needed_item(LIFE[member],
				                    {'type': 'drink'},
				                    amount=1,
			                         pass_if=_requirements,
				                    satisfy_if=action.make_small_script(function='group_needs_resources',
				                                                        args={'group_id': group_id}),
				                    satisfy_callback=action.make_small_script(return_function='pass'))
		
		jobs.add_task(_j, '0', 'bring_back_loot',
		              action.make_small_script(function='find_target',
		                                       kwargs={'target': _group['leader'],
		                                               'distance': 5,
		                                               'follow': False}),
		              player_action=action.make_small_script(function='can_see_target',
		                                                     kwargs={'target_id': _group['leader']}),
		              description='Drop the item off at the camp',
		              delete_on_finish=False)
		
		jobs.add_task(_j, '1', 'flag_item',
		              action.make_small_script(function='flag_item_matching',
		                                       kwargs={'matching': {'type': 'drink'},
		                                               'flag': 'ignore'}),
		              player_action=action.make_small_script(function='always'),
		              description='Ignore this',
		              delete_on_finish=False)
		
		jobs.add_task(_j, '2', 'drop_item',
		              action.make_small_script(function='drop_item_matching',
		                                       kwargs={'matching': {'type': 'drink'}}),
		              player_action=action.make_small_script(function='never'),
		              description='Drop the item off at the camp',
		              delete_on_finish=False)
		
		flag(group_id, 'loot', _j)
	
	if lfe.ticker(life, 'resource_announce', 10):
		_job_id = get_flag(group_id, 'loot')
		
		announce(life, life['group'],
			     'job',
			     'We need more resources.',
			     job_id=_job_id,
		          order=True,
			     filter_if=[action.make_small_script(function='has_needs_to_meet')])
Example #29
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)