Пример #1
0
def create_action_menu(entity, x, y, on_path=False):
	_menu = ui_menu.create(ui_cursor.CURSOR['tile']['x']+2, ui_cursor.CURSOR['tile']['y']-1, title='Context')
	
	if items.get_items_in_holder(entity, 'weapon'):
		ui_menu.add_selectable(_menu, 'Shoot', lambda: select_target(x, y, on_path))
	
	ui_menu.add_selectable(_menu, 'Reload', lambda: create_action_node(entity,
	                                                                   x,
	                                                                   y,
	                                                                   30,
	                                                                   lambda: entities.trigger_event(entity, 'reload'),
	                                                                   name='Reload',
	                                                                   on_path=on_path))
	ui_menu.add_selectable(_menu, 'Crouch', lambda: create_action_node(entity,
	                                                                   x,
	                                                                   y,
	                                                                   30,
	                                                                   lambda: entities.trigger_event(entity, 'set_motion', motion='crouch'),
	                                                                   name='Crouch',
	                                                                   on_path=on_path))
	ui_menu.add_selectable(_menu, 'Crawl', lambda: create_action_node(entity,
	                                                                   x,
	                                                                   y,
	                                                                   30,
	                                                                   lambda: entities.trigger_event(entity, 'set_motion', motion='crawl'),
	                                                                   name='Prone',
	                                                                   on_path=on_path))
	ui_menu.add_selectable(_menu, 'Stand', lambda: create_action_node(entity,
	                                                                   x,
	                                                                   y,
	                                                                   30,
	                                                                   lambda: entities.trigger_event(entity, 'set_motion', motion='stand'),
	                                                                   name='Stand',
	                                                                   on_path=on_path))
Пример #2
0
def show_weapons(entity):
	global ACTIVE_MENU, REDRAW_TIMES

	_holder_menu = ui_menu.create(1, 1, title='Weapons', surface='ui_inventory', click_offset=(constants.MAP_VIEW_WIDTH-35, 0))
	ACTIVE_MENU = _holder_menu
	REDRAW_TIMES = 3

	_equipped_weapon = items.get_items_in_holder(entity, 'weapon')
	_weapons = []
	
	if _equipped_weapon:
		_weapons.append(_equipped_weapon[0])
	
	for item_id in items.get_items_matching(entity, {'type': 'weapon'}):
		if item_id in _weapons:
			continue
		
		_weapons.add(item_id)
	
	for item_id in _weapons:
		_item = entities.get_entity(item_id)
		
		entities.trigger_event(_item, 'get_display_name')
		
		if item_id in _equipped_weapon:
			_fg = (245, 245, 245)
		else:
			_fg = (230, 230, 230)

		ui_menu.add_selectable(_holder_menu,
		                       _item['stats']['display_name'],
		                       show_weapon_menu,
		                       fore_color=_fg,
		                       item_id=item_id)
Пример #3
0
def shoot_weapon(entity, target_id):
    if timers.has_timer_with_name(entity, 'shoot'):
        return

    _weapon = items.get_items_in_holder(entity, 'weapon')[0]
    _ammo = flags.get_flag(entities.get_entity(_weapon), 'ammo')
    _rounds_per_shot = flags.get_flag(entities.get_entity(_weapon),
                                      'rounds_per_shot')
    _pause_time = 15

    if not _ammo:
        return

    entities.trigger_event(
        entity,
        'create_timer',
        time=_pause_time,
        repeat=_rounds_per_shot,
        name='shoot',
        enter_callback=lambda _: entities.trigger_event(entity,
                                                        'animate',
                                                        animation=
                                                        ['\\', '|', '/', '-'],
                                                        delay=_pause_time / 4),
        repeat_callback=lambda _: _shoot_weapon(entity, _weapon, target_id))
Пример #4
0
def reload_weapon(entity):
	if timers.has_timer_with_name(entity, 'Reloading'):
		return

	_weapon = items.get_items_in_holder(entity, 'weapon')[0]
	_ammo = items.get_items_matching(entity, {'type': 'ammo'})[0]

	entities.trigger_event(entity,
		                   'create_timer',
		                   time=30,
		                   name='Reloading',
		                   exit_callback=lambda _: _reload_weapon(entity, _weapon, _ammo))
Пример #5
0
def create_shoot_menu(entity, target_id):
	_tx, _ty = movement.get_position_via_id(target_id)
	_weapon = entities.get_entity(items.get_items_in_holder(entity, 'weapon')[0])
	_menu = ui_menu.create(_tx-camera.X+2, _ty-camera.Y-4, title='Shoot')
	_accuracy = stats.get_accuracy(entity, _weapon['_id'])
	_x, _y = movement.get_position(entity)
	_direction = numbers.direction_to((_x, _y), (_tx, _ty))
	_final_direction = _direction + (_accuracy * numbers.distance((_x, _y), (_tx, _ty)))
	_spray_accuracy = (100 * (_direction / float(_final_direction)))
	
	entities.trigger_event(_weapon, 'get_actions', menu=_menu)
	ui_menu.add_selectable(_menu, 'Spray (Acc: %.2d)' % _spray_accuracy, lambda: entities.trigger_event(entity, 'shoot', target_id=target_id) and settings.set_tick_mode('normal'))
	ui_menu.add_selectable(_menu, 'Snipe (Acc: %s)' % _accuracy, lambda: _)
Пример #6
0
def reload_weapon(entity):
    if timers.has_timer_with_name(entity, 'Reloading'):
        return

    _weapon = items.get_items_in_holder(entity, 'weapon')[0]
    _ammo = items.get_items_matching(entity, {'type': 'ammo'})[0]

    entities.trigger_event(
        entity,
        'create_timer',
        time=30,
        name='Reloading',
        exit_callback=lambda _: _reload_weapon(entity, _weapon, _ammo))
Пример #7
0
def create_action_menu(entity, x, y, on_path=False):
    _menu = ui_menu.create(ui_cursor.CURSOR['tile']['x'] + 2,
                           ui_cursor.CURSOR['tile']['y'] - 1,
                           title='Context')

    if items.get_items_in_holder(entity, 'weapon'):
        ui_menu.add_selectable(_menu, 'Shoot',
                               lambda: select_target(x, y, on_path))

    ui_menu.add_selectable(
        _menu, 'Reload',
        lambda: create_action_node(entity,
                                   x,
                                   y,
                                   30,
                                   lambda: entities.trigger_event(
                                       entity, 'reload'),
                                   name='Reload',
                                   on_path=on_path))
    ui_menu.add_selectable(
        _menu, 'Crouch',
        lambda: create_action_node(entity,
                                   x,
                                   y,
                                   30,
                                   lambda: entities.trigger_event(
                                       entity, 'set_motion', motion='crouch'),
                                   name='Crouch',
                                   on_path=on_path))
    ui_menu.add_selectable(
        _menu, 'Crawl',
        lambda: create_action_node(entity,
                                   x,
                                   y,
                                   30,
                                   lambda: entities.trigger_event(
                                       entity, 'set_motion', motion='crawl'),
                                   name='Prone',
                                   on_path=on_path))
    ui_menu.add_selectable(
        _menu, 'Stand',
        lambda: create_action_node(entity,
                                   x,
                                   y,
                                   30,
                                   lambda: entities.trigger_event(
                                       entity, 'set_motion', motion='stand'),
                                   name='Stand',
                                   on_path=on_path))
Пример #8
0
def create_life_interact_menu(entity, target_id):
	if not items.get_items_in_holder(entity, 'weapon'):
		return
	
	_target = entities.get_entity(target_id)
	_is_enemy = ai_factions.is_enemy(entity, target_id)
	_menu = ui_menu.create(ui_cursor.CURSOR['tile']['x']+2, ui_cursor.CURSOR['tile']['y']-4, title='Context')
	
	if not _is_enemy:
		if _target['missions']['inactive']:
			ui_menu.add_selectable(_menu, 'Talk', lambda: create_talk_menu(entity, target_id))
		
		ui_menu.add_selectable(_menu, 'Inquire', lambda: create_mission_menu(entity, target_id))
		ui_menu.add_selectable(_menu, 'Trade', lambda: create_mission_menu(entity, target_id))
	
	ui_menu.add_selectable(_menu, 'Shoot%s' % (' (Friendly fire)' * (not _is_enemy)), lambda: create_shoot_menu(entity, target_id))
Пример #9
0
def draw_squad_info(squad_id):
    _text_y_mod = 0
    _squad = entities.get_entity(squad_id)

    for member_id in _squad['members']:
        _member = entities.get_entity(member_id)
        _health_string = '[OK]'
        _weapon = items.get_items_in_holder(_member, 'weapon')

        if _weapon:
            _weapon_name = '<%s>' % entities.get_entity(
                _weapon[0])['stats']['name']

        else:
            _weapon_name = '<None>'

        _class = _member['stats']['class']

        display.write_string('ui_bar',
                             1,
                             1 + _text_y_mod,
                             _member['stats']['name'],
                             fore_color=(204, 200, 204))

        display.write_string('ui_bar',
                             2 + len(_member['stats']['name']),
                             1 + _text_y_mod,
                             _health_string,
                             fore_color=(200, 200, 34))

        display.write_string('ui_bar',
                             3 + len(_member['stats']['name']) +
                             len(_health_string),
                             1 + _text_y_mod,
                             _weapon_name,
                             fore_color=(0, 200, 34))

        display.write_string('ui_bar',
                             4 + len(_member['stats']['name']) +
                             len(_health_string) + len(_weapon_name),
                             1 + _text_y_mod,
                             _class,
                             fore_color=(200, 50, 200),
                             back_color=(50, 12, 50))

        _text_y_mod += 1
Пример #10
0
def shoot_weapon(entity, target_id):
	if timers.has_timer_with_name(entity, 'shoot'):
		return

	_weapon = items.get_items_in_holder(entity, 'weapon')[0]
	_ammo = flags.get_flag(entities.get_entity(_weapon), 'ammo')
	_rounds_per_shot = flags.get_flag(entities.get_entity(_weapon), 'rounds_per_shot')
	_pause_time = 15

	if not _ammo:
		return

	entities.trigger_event(entity,
		                   'create_timer',
		                   time=_pause_time,
	                       repeat=_rounds_per_shot,
		                   name='shoot',
	                       enter_callback=lambda _: entities.trigger_event(entity, 'animate', animation=['\\', '|', '/', '-'], delay=_pause_time/4),
		                   repeat_callback=lambda _: _shoot_weapon(entity, _weapon, target_id))
Пример #11
0
def create_shoot_menu(entity, target_id):
    _tx, _ty = movement.get_position_via_id(target_id)
    _weapon = entities.get_entity(
        items.get_items_in_holder(entity, 'weapon')[0])
    _menu = ui_menu.create(_tx - camera.X + 2,
                           _ty - camera.Y - 4,
                           title='Shoot')
    _accuracy = stats.get_accuracy(entity, _weapon['_id'])
    _x, _y = movement.get_position(entity)
    _direction = numbers.direction_to((_x, _y), (_tx, _ty))
    _final_direction = _direction + (_accuracy * numbers.distance((_x, _y),
                                                                  (_tx, _ty)))
    _spray_accuracy = (100 * (_direction / float(_final_direction)))

    entities.trigger_event(_weapon, 'get_actions', menu=_menu)
    ui_menu.add_selectable(
        _menu, 'Spray (Acc: %.2d)' % _spray_accuracy,
        lambda: entities.trigger_event(entity, 'shoot', target_id=target_id
                                       ) and settings.set_tick_mode('normal'))
    ui_menu.add_selectable(_menu, 'Snipe (Acc: %s)' % _accuracy, lambda: _)
Пример #12
0
def draw_squad_info(squad_id):
    _text_y_mod = 0
    _squad = entities.get_entity(squad_id)

    for member_id in _squad["members"]:
        _member = entities.get_entity(member_id)
        _health_string = "[OK]"
        _weapon = items.get_items_in_holder(_member, "weapon")

        if _weapon:
            _weapon_name = "<%s>" % entities.get_entity(_weapon[0])["stats"]["name"]

        else:
            _weapon_name = "<None>"

        _class = _member["stats"]["class"]

        display.write_string("ui_bar", 1, 1 + _text_y_mod, _member["stats"]["name"], fore_color=(204, 200, 204))

        display.write_string(
            "ui_bar", 2 + len(_member["stats"]["name"]), 1 + _text_y_mod, _health_string, fore_color=(200, 200, 34)
        )

        display.write_string(
            "ui_bar",
            3 + len(_member["stats"]["name"]) + len(_health_string),
            1 + _text_y_mod,
            _weapon_name,
            fore_color=(0, 200, 34),
        )

        display.write_string(
            "ui_bar",
            4 + len(_member["stats"]["name"]) + len(_health_string) + len(_weapon_name),
            1 + _text_y_mod,
            _class,
            fore_color=(200, 50, 200),
            back_color=(50, 12, 50),
        )

        _text_y_mod += 1
Пример #13
0
def show_weapons(entity):
    global ACTIVE_MENU, REDRAW_TIMES

    _holder_menu = ui_menu.create(1,
                                  1,
                                  title='Weapons',
                                  surface='ui_inventory',
                                  click_offset=(constants.MAP_VIEW_WIDTH - 35,
                                                0))
    ACTIVE_MENU = _holder_menu
    REDRAW_TIMES = 3

    _equipped_weapon = items.get_items_in_holder(entity, 'weapon')
    _weapons = []

    if _equipped_weapon:
        _weapons.append(_equipped_weapon[0])

    for item_id in items.get_items_matching(entity, {'type': 'weapon'}):
        if item_id in _weapons:
            continue

        _weapons.add(item_id)

    for item_id in _weapons:
        _item = entities.get_entity(item_id)

        entities.trigger_event(_item, 'get_display_name')

        if item_id in _equipped_weapon:
            _fg = (245, 245, 245)
        else:
            _fg = (230, 230, 230)

        ui_menu.add_selectable(_holder_menu,
                               _item['stats']['display_name'],
                               show_weapon_menu,
                               fore_color=_fg,
                               item_id=item_id)
Пример #14
0
def create_life_interact_menu(entity, target_id):
    if not items.get_items_in_holder(entity, 'weapon'):
        return

    _target = entities.get_entity(target_id)
    _is_enemy = ai_factions.is_enemy(entity, target_id)
    _menu = ui_menu.create(ui_cursor.CURSOR['tile']['x'] + 2,
                           ui_cursor.CURSOR['tile']['y'] - 4,
                           title='Context')

    if not _is_enemy:
        if _target['missions']['inactive']:
            ui_menu.add_selectable(_menu, 'Talk',
                                   lambda: create_talk_menu(entity, target_id))

        ui_menu.add_selectable(_menu, 'Inquire',
                               lambda: create_mission_menu(entity, target_id))
        ui_menu.add_selectable(_menu, 'Trade',
                               lambda: create_mission_menu(entity, target_id))

    ui_menu.add_selectable(_menu,
                           'Shoot%s' % (' (Friendly fire)' * (not _is_enemy)),
                           lambda: create_shoot_menu(entity, target_id))
Пример #15
0
def build_life_list(entity):
	entity['ai']['visible_targets'] = []
	_nearest_target = {'target_id': None, 'distance': 0}
	_solids = zones.get_active_solids(entity)
	_visible_life = set()
	_vision = stats.get_vision(entity)
	_visible_by_friendlies = [entities.get_entity(e)['ai']['visible_targets'] for e in entity['ai']['life_memory'] if not entity['ai']['life_memory'][e]['is_target'] and e in entities.ENTITIES]
	
	#Warning: Makes AI super smart
	_visible_by_friendlies = [item for sublist in _visible_by_friendlies for item in sublist]
	
	for entity_id in entities.get_entity_group('life'):
		if entity['_id'] == entity_id:
			continue
		
		_target = entities.get_entity(entity_id)
		
		if not entity_id in entity['ai']['life_memory']:
			life.create_life_memory(entity, entity_id)
		
		if not ai_factions.is_enemy(entity, entity_id):
			_visible = True
		
		else:
			if numbers.distance(movement.get_position(entity), movement.get_position(_target)) > _vision:
				if entity['ai']['life_memory'][entity_id]['can_see'] and ai_factions.is_enemy(entity, _target['_id']):
					entities.trigger_event(entity, 'target_lost', target_id=entity_id)
				
				if entity_id in _visible_by_friendlies:
					entity['ai']['life_memory'][entity_id]['in_los'] = False
					entity['ai']['life_memory'][entity_id]['can_see'] = True
					
					_visible = True
				else:
					entity['ai']['life_memory'][entity_id]['can_see'] = False
					entity['ai']['life_memory'][entity_id]['in_los'] = False
					
					if entity_id in entity['ai']['visible_life']:
						entity['ai']['visible_life'].remove(entity_id)
					
					_visible = False
				
			else:
				for pos in shapes.line(movement.get_position(entity), movement.get_position(_target)):
					if pos in _solids:
						if entity['ai']['life_memory'][entity_id]['can_see'] and ai_factions.is_enemy(entity, _target['_id']):
							entities.trigger_event(entity, 'target_lost', target_id=entity_id)
						
						if entity_id in _visible_by_friendlies:
							entity['ai']['life_memory'][entity_id]['in_los'] = False
							entity['ai']['life_memory'][entity_id]['can_see'] = True
							
							_visible = True
						
						else:
							entity['ai']['life_memory'][entity_id]['can_see'] = False
							entity['ai']['life_memory'][entity_id]['in_los'] = False
							
							if entity_id in entity['ai']['visible_life']:
								entity['ai']['visible_life'].remove(entity_id)
							
							_visible = False
						
						break
				else:
					entity['ai']['life_memory'][entity_id]['in_los'] = True
					_visible = True
		
		if not _visible and entity['ai']['life_memory'][entity_id]['seen_time'] > 0:
			_visible = True
			
			entity['ai']['life_memory'][entity_id]['in_los'] = False
			entity['ai']['life_memory'][entity_id]['can_see'] = True
			
			entity['ai']['life_memory'][entity_id]['seen_time'] -= 1
			
			if entity_id in entity['ai']['visible_life']:
				entity['ai']['visible_life'].remove(entity_id)
		
		elif not _visible and entity_id in entity['ai']['visible_life']:
			entity['ai']['visible_life'].remove(entity_id)
		
		if _visible:
			_previous_last_seen_at = entity['ai']['life_memory'][entity_id]['last_seen_at']
			_target_position = movement.get_position(_target)[:]
			
			entity['ai']['life_memory'][entity_id]['is_lost'] = False
			
			if entity['ai']['life_memory'][entity_id]['in_los']:
				if entity['ai']['life_memory'][entity_id]['seen_time'] < 30:
					entity['ai']['life_memory'][entity_id]['seen_time'] += 1
			
			else:
				entity['ai']['life_memory'][entity_id]['seen_time'] -= 1
				
				if entity['ai']['life_memory'][entity_id]['seen_time'] < 0 and entity_id in entity['ai']['visible_life']:
					entity['ai']['visible_life'].remove(entity_id)
					entity['ai']['life_memory'][entity_id]['in_los'] = False
			
			if movement.get_position(_target) == _previous_last_seen_at:
				_new_last_seen_at = _previous_last_seen_at
			
			else:
				_new_last_seen_at = _target_position
			
			_is_target = ai_factions.is_enemy(entity, _target['_id'])
			_profile = {'distance': numbers.distance(movement.get_position(entity), movement.get_position(_target)),
				        'is_target': _is_target,
				        'is_armed': items.get_items_in_holder(_target, 'weapon'),
			            'is_lost': False,
			            'can_see': True,
			            'last_seen_at': _new_last_seen_at,
			            'last_seen_velocity': None}
			
			if not entity_id in entity['ai']['visible_life']:
				entities.trigger_event(entity, 'new_target_spotted', target_id=entity_id)
			
			if entity['ai']['life_memory'][entity_id]['in_los']:
				entity['ai']['visible_life'].add(entity_id)
				
				if _is_target:
					ai_flow.register_combat(entity, entity_id)
			
			if _is_target:
				entity['ai']['targets'].add(entity_id)
				
				_distance = numbers.distance(movement.get_position(entity), movement.get_position_via_id(entity_id))
				
				if not _nearest_target['target_id'] or _distance < _nearest_target['distance']:
					_nearest_target['distance'] = _distance
					_nearest_target['target_id'] = entity_id
			
			if entity['ai']['life_memory'][entity_id]['last_seen_at']:
				_last_seen_at = entity['ai']['life_memory'][entity_id]['last_seen_at'][:]
				_velocity = (_profile['last_seen_at'][0]-_last_seen_at[0], _profile['last_seen_at'][1]-_last_seen_at[1])
				
				_profile['last_seen_velocity'] = _velocity
			else:
				_profile['last_seen_velocity'] = None
			
			if not entity['ai']['life_memory'][entity_id]['can_see'] and _is_target:
				_could_not_see_target_before = True
			else:
				_could_not_see_target_before = False
			
			entity['ai']['life_memory'][entity_id].update(_profile)
			
			if _could_not_see_target_before:
				entities.trigger_event(entity, 'target_found', target_id=entity_id)
	
	#TODO: What?
	#for t in entity['ai']['life_memory']:
	#	if not 'is_lost' in entity['ai']['life_memory'][t]:
	#		print entity['ai']['life_memory'][t]
	
	entity['ai']['visible_targets'] = list(entity['ai']['visible_life'] & entity['ai']['targets'])
	entity['ai']['targets_to_search'] = [t for t in entity['ai']['life_memory'].keys() if entity['ai']['life_memory'][t]['is_lost'] and not entity['ai']['life_memory'][t]['searched_for'] and t in entities.ENTITIES]
	
	if _nearest_target['target_id']:
		if not entity['ai']['nearest_target'] == _nearest_target['target_id']:
			entity['ai']['meta']['has_firing_position'] = True
		
		entity['ai']['nearest_target'] = _nearest_target['target_id']
	
	elif entity['ai']['targets']:
		for target_id in list(entity['ai']['targets']):
			_target = entity['ai']['life_memory'][target_id]
			
			if not target_id in entities.ENTITIES or _target['is_lost']:
				entity['ai']['targets'].remove(target_id)
				
				continue
			
			_distance = numbers.distance(movement.get_position(entity), _target['last_seen_at'])
			
			if not _nearest_target['target_id'] or _distance < _nearest_target['distance']:
				_nearest_target['target_id'] = target_id
				_nearest_target['distance'] = _distance
		
		if not entity['ai']['nearest_target'] == _nearest_target['target_id']:
			entity['ai']['meta']['has_firing_position'] = True
		
		entity['ai']['nearest_target'] = _nearest_target['target_id']
Пример #16
0
def _human_logic(entity):
    _t = time.time()
    ai_visuals.build_item_list(entity)
    ai_visuals.build_life_list(entity)

    if ai_flow.is_flow_active() and not ai_flow.can_act(entity):
        return

    if timers.has_timer_with_name(entity, 'passout'):
        return

    #if not ai_squads.is_active(ai_squads.get_assigned_squad(entity)) or entity['stats']['action_points'] <= 0:
    #	return

    _old_meta = entity['ai']['meta'].copy()

    entity['ai']['meta']['sees_item_type_weapon'] = len(
        entity['ai']['visible_items']['weapon']) > 0
    entity['ai']['meta']['sees_item_type_ammo'] = len(
        entity['ai']['visible_items']['ammo']) > 0
    entity['ai']['meta']['sees_item_type_container'] = len(
        entity['ai']['visible_items']['container']) > 0
    entity['ai']['meta']['has_weapon'] = len(
        items.get_items_in_holder(entity, 'weapon')) > 0
    entity['ai']['meta']['has_ammo'] = len(
        items.get_items_matching(entity, {'type': 'ammo'})) > 0
    entity['ai']['meta']['has_container'] = len(
        items.get_items_matching(entity, {'type': 'container'})) > 0
    entity['ai']['meta']['weapon_loaded'] = len([
        w for w in items.get_items_in_holder(entity, 'weapon')
        if entities.get_entity(w)['flags']['ammo']['value'] > 0
    ]) > 0
    entity['ai']['meta']['in_engagement'] = len([
        t for t in entity['ai']['targets']
        if not entity['ai']['life_memory'][t]['is_lost']
    ]) > 0
    entity['ai']['meta']['has_lost_target'] = len(
        entity['ai']['targets_to_search']) > 0
    entity['ai']['meta']['in_enemy_los'] = len([
        t for t in entity['ai']['targets']
        if entity['ai']['life_memory'][t]['in_los']
    ]) > 0
    entity['ai']['meta']['has_needs'] = not entity['ai']['meta'][
        'has_weapon'] or not entity['ai']['meta'][
            'has_container'] or not entity['ai']['meta']['weapon_loaded']
    entity['ai']['meta']['is_injured'] = skeleton.has_critical_injury(entity)

    if not entity['ai']['meta'] == _old_meta:
        entities.trigger_event(entity, 'meta_change')

    if entity['ai']['meta']['in_engagement']:
        _target = entity['ai']['nearest_target']
        _target_distance = numbers.distance(
            movement.get_position_via_id(_target),
            movement.get_position(entity))
        _engage_distance = stats.get_vision(entity) * .75
        _weapon = entities.get_entity(
            items.get_items_in_holder(entity, 'weapon')[0])
        _engage_distance = numbers.clip(
            _engage_distance - (flags.get_flag(_weapon, 'accuracy') * 3), 1,
            stats.get_vision(entity))
        _min_engage_distance = 3

        if _weapon['stats']['kind'] == 'explosive':
            _engage_distance /= 2
            _min_engage_distance = 8

        entities.trigger_event(entity,
                               'set_flag',
                               flag='engage_distance',
                               value=_engage_distance)
        entities.trigger_event(entity,
                               'set_flag',
                               flag='min_engage_distance',
                               value=_min_engage_distance)

        #NOTE: Mirror change in ai_logic!
        entity['ai']['meta'][
            'in_firing_range'] = _target_distance <= _engage_distance and _target_distance >= _min_engage_distance

        if entity['ai']['meta']['in_enemy_los']:
            if flags.has_flag(entity, 'search_nodes'):
                flags.delete_flag(entity, 'search_nodes')

            entity['ai']['meta']['is_in_melee_range'] = _target_distance == 1

    else:
        entity['ai']['meta']['is_target_near'] = False
        entity['ai']['meta']['in_firing_range'] = False

    entity['ai']['meta']['is_target_armed'] = len([
        t for t in entity['ai']['targets']
        if entity['ai']['life_memory'][t]['is_armed']
    ]) > 0
    entity['ai']['meta']['is_panicked'] = (
        not entity['ai']['meta']['weapon_loaded']
        and entity['ai']['meta']['is_target_armed'])

    if entity['ai']['is_player']:
        return

    #TODO: Experimental!
    #if entity['ai']['meta'] == _old_meta:
    #print 'Something changed...'

    #return

    if timers.has_timer_with_name(
            entity, 'shoot'
    ) or entity['movement']['path']['positions'] or timers.has_timer_with_name(
            entity, 'move'):
        #print 'Clearing existing action...'
        return

    _goap = _handle_goap(entity)

    if not _goap:
        entity['ai']['current_action'] = 'idle'

        entities.trigger_event(entity, 'finish_turn')
        entities.trigger_event(entity, 'stop')

        #print
        #print entity['stats']['name'], 'no possible action'
        #print

        #for meta_name in entity['ai']['meta']:
        #	print meta_name, '\t', entity['ai']['meta'][meta_name]

        return

    _plan = _goap[0]

    if not entity['ai']['last_action'] == _plan['actions'][0]['name']:
        if entity['_id'] in ai_debugger.WATCHING:
            logging.info('%s: %s -> %s' %
                         (entity['_id'], entity['ai']['last_action'],
                          _plan['actions'][0]['name']))

        #TODO: Only do this if the action requires movement changes
        entities.trigger_event(entity, 'stop')

        entity['ai']['last_action'] = _plan['actions'][0]['name']

    #print entity['stats']['name'], _plan['actions'][0]['name']

    _plan['planner'].trigger_callback(entity, _plan['actions'][0]['name'])

    #print time.time() - _t

    entity['ai']['current_action'] = _plan['actions'][0]['name']
Пример #17
0
def _human_logic(entity):
    _t = time.time()
    ai_visuals.build_item_list(entity)
    ai_visuals.build_life_list(entity)

    if ai_flow.is_flow_active() and not ai_flow.can_act(entity):
        return

    if timers.has_timer_with_name(entity, "passout"):
        return

        # if not ai_squads.is_active(ai_squads.get_assigned_squad(entity)) or entity['stats']['action_points'] <= 0:
        # 	return

    _old_meta = entity["ai"]["meta"].copy()

    entity["ai"]["meta"]["sees_item_type_weapon"] = len(entity["ai"]["visible_items"]["weapon"]) > 0
    entity["ai"]["meta"]["sees_item_type_ammo"] = len(entity["ai"]["visible_items"]["ammo"]) > 0
    entity["ai"]["meta"]["sees_item_type_container"] = len(entity["ai"]["visible_items"]["container"]) > 0
    entity["ai"]["meta"]["has_weapon"] = len(items.get_items_in_holder(entity, "weapon")) > 0
    entity["ai"]["meta"]["has_ammo"] = len(items.get_items_matching(entity, {"type": "ammo"})) > 0
    entity["ai"]["meta"]["has_container"] = len(items.get_items_matching(entity, {"type": "container"})) > 0
    entity["ai"]["meta"]["weapon_loaded"] = (
        len(
            [
                w
                for w in items.get_items_in_holder(entity, "weapon")
                if entities.get_entity(w)["flags"]["ammo"]["value"] > 0
            ]
        )
        > 0
    )
    entity["ai"]["meta"]["in_engagement"] = (
        len([t for t in entity["ai"]["targets"] if not entity["ai"]["life_memory"][t]["is_lost"]]) > 0
    )
    entity["ai"]["meta"]["has_lost_target"] = len(entity["ai"]["targets_to_search"]) > 0
    entity["ai"]["meta"]["in_enemy_los"] = (
        len([t for t in entity["ai"]["targets"] if entity["ai"]["life_memory"][t]["in_los"]]) > 0
    )
    entity["ai"]["meta"]["has_needs"] = (
        not entity["ai"]["meta"]["has_weapon"]
        or not entity["ai"]["meta"]["has_container"]
        or not entity["ai"]["meta"]["weapon_loaded"]
    )
    entity["ai"]["meta"]["is_injured"] = skeleton.has_critical_injury(entity)

    if not entity["ai"]["meta"] == _old_meta:
        entities.trigger_event(entity, "meta_change")

    if entity["ai"]["meta"]["in_engagement"]:
        _target = entity["ai"]["nearest_target"]
        _target_distance = numbers.distance(movement.get_position_via_id(_target), movement.get_position(entity))
        _engage_distance = stats.get_vision(entity) * 0.75
        _weapon = entities.get_entity(items.get_items_in_holder(entity, "weapon")[0])
        _engage_distance = numbers.clip(
            _engage_distance - (flags.get_flag(_weapon, "accuracy") * 3), 1, stats.get_vision(entity)
        )
        _min_engage_distance = 3

        if _weapon["stats"]["kind"] == "explosive":
            _engage_distance /= 2
            _min_engage_distance = 8

        entities.trigger_event(entity, "set_flag", flag="engage_distance", value=_engage_distance)
        entities.trigger_event(entity, "set_flag", flag="min_engage_distance", value=_min_engage_distance)

        # NOTE: Mirror change in ai_logic!
        entity["ai"]["meta"]["in_firing_range"] = (
            _target_distance <= _engage_distance and _target_distance >= _min_engage_distance
        )

        if entity["ai"]["meta"]["in_enemy_los"]:
            if flags.has_flag(entity, "search_nodes"):
                flags.delete_flag(entity, "search_nodes")

            entity["ai"]["meta"]["is_in_melee_range"] = _target_distance == 1

    else:
        entity["ai"]["meta"]["is_target_near"] = False
        entity["ai"]["meta"]["in_firing_range"] = False

    entity["ai"]["meta"]["is_target_armed"] = (
        len([t for t in entity["ai"]["targets"] if entity["ai"]["life_memory"][t]["is_armed"]]) > 0
    )
    entity["ai"]["meta"]["is_panicked"] = (
        not entity["ai"]["meta"]["weapon_loaded"] and entity["ai"]["meta"]["is_target_armed"]
    )

    if entity["ai"]["is_player"]:
        return

        # TODO: Experimental!
        # if entity['ai']['meta'] == _old_meta:
        # print 'Something changed...'

        # return

    if (
        timers.has_timer_with_name(entity, "shoot")
        or entity["movement"]["path"]["positions"]
        or timers.has_timer_with_name(entity, "move")
    ):
        # print 'Clearing existing action...'
        return

    _goap = _handle_goap(entity)

    if not _goap:
        entity["ai"]["current_action"] = "idle"

        entities.trigger_event(entity, "finish_turn")
        entities.trigger_event(entity, "stop")

        # print
        # print entity['stats']['name'], 'no possible action'
        # print

        # for meta_name in entity['ai']['meta']:
        # 	print meta_name, '\t', entity['ai']['meta'][meta_name]

        return

    _plan = _goap[0]

    if not entity["ai"]["last_action"] == _plan["actions"][0]["name"]:
        if entity["_id"] in ai_debugger.WATCHING:
            logging.info("%s: %s -> %s" % (entity["_id"], entity["ai"]["last_action"], _plan["actions"][0]["name"]))

            # TODO: Only do this if the action requires movement changes
        entities.trigger_event(entity, "stop")

        entity["ai"]["last_action"] = _plan["actions"][0]["name"]

        # print entity['stats']['name'], _plan['actions'][0]['name']

    _plan["planner"].trigger_callback(entity, _plan["actions"][0]["name"])

    # print time.time() - _t

    entity["ai"]["current_action"] = _plan["actions"][0]["name"]