Beispiel #1
0
def _walk_path(entity):
    if not entity['movement']['path']['positions']:
        return False

    if timers.has_timer_with_name(entity,
                                  'move') or timers.has_timer_with_name(
                                      entity, 'move', fuzzy=True):
        return False

    if entity['movement']['path']['refresh']:
        set_path(entity, [get_position(entity)])

    _next_pos = entity['movement']['path']['positions'].pop(0)
    _x, _y = get_position(entity)
    _d_x, _d_y = _next_pos[0] - _x, _next_pos[1] - _y

    if not _d_x in [-1, 0, 1] or not _d_y in [-1, 0, 1]:
        _clear_movement(entity)

        return

    if not entity['movement']['path']['positions']:
        entity['movement']['path']['destination'] = None

    push(entity, x=_d_x, y=_d_y, name='move', time=get_override_speed(entity))
Beispiel #2
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))
Beispiel #3
0
def update_group_status(entity):
    set_squad_meta(entity, 'is_squad_combat_ready', True)

    return

    _members_combat_ready = 0

    for member_id in entity['member_info']:
        _member = entities.get_entity(member_id)

        if _member['ai']['meta'][
                'has_needs'] and not _member['ai']['meta']['weapon_loaded']:
            continue

        if _member['ai']['meta']['is_injured'] or _member['ai']['meta'][
                'is_panicked']:
            continue

        if timers.has_timer_with_name(_member, 'passout'):
            continue

        _members_combat_ready += entity['member_info'][member_id]['armed']

    set_squad_meta(
        entity, 'is_squad_combat_ready',
        _members_combat_ready / float(len(entity['member_info'].keys())) >=
        .65)
    set_squad_meta(
        entity, 'is_squad_mobile_ready',
        _members_combat_ready / float(len(entity['member_info'].keys())) >=
        .65)
Beispiel #4
0
def get_and_hold_item(entity, item_id):
	_item = entities.get_entity(item_id)
	
	if timers.has_timer_with_name(entity, 'Getting %s' % _item['stats']['name'], fuzzy=True):
		return

	entities.trigger_event(entity,
		                   'create_timer',
		                   time=30,
		                   name='Getting %s' % _item['stats']['name'],
		                   exit_callback=lambda _: _get_and_hold_item(entity, item_id))
Beispiel #5
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))
Beispiel #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))
Beispiel #7
0
def handle_keyboard_input():
    global SELECTED_SQUAD_MEMBER, WALK_PATH, WALK_DEST

    #TODO: Check for multiple movement changes at this location
    if not is_squad_member_selected():
        return

    _entity = get_selected_squad_member()
    _x, _y = movement.get_position(_entity)

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

    if controls.get_input_char_pressed('z'):
        entities.trigger_event(_entity, 'set_motion', motion='crawl')
        settings.set_tick_mode('normal')

    elif controls.get_input_char_pressed('x'):
        entities.trigger_event(_entity, 'set_motion', motion='crouch')
        settings.set_tick_mode('normal')

    elif controls.get_input_char_pressed('c'):
        entities.trigger_event(_entity, 'set_motion', motion='stand')
        settings.set_tick_mode('normal')

    elif controls.get_input_char_pressed(' '):
        _entity['stats']['action_points'] = 0
        SELECTED_SQUAD_MEMBER = None
        WALK_DEST = None
        WALK_PATH = []
        _broken = False

        for squad_id in entities.get_entity_group('squads'):
            _squad = entities.get_entity(squad_id)

            if not _squad['faction'] == 'Rogues':
                continue

            for entity_id in _squad['members']:
                _entity = entities.get_entity(entity_id)

                if _entity['stats']['action_points'] > 0:
                    _broken = True
                    break

            if _broken:
                break

        else:
            settings.set_tick_mode('normal')
Beispiel #8
0
def handle_keyboard_input():
	global SELECTED_SQUAD_MEMBER, WALK_PATH, WALK_DEST
	
	#TODO: Check for multiple movement changes at this location
	if not is_squad_member_selected():
		return
	
	_entity = get_selected_squad_member()
	_x, _y = movement.get_position(_entity)
	
	if timers.has_timer_with_name(_entity, 'passout'):
		return
	
	if controls.get_input_char_pressed('z'):
		entities.trigger_event(_entity, 'set_motion', motion='crawl')
		settings.set_tick_mode('normal')
	
	elif controls.get_input_char_pressed('x'):
		entities.trigger_event(_entity, 'set_motion', motion='crouch')
		settings.set_tick_mode('normal')
	
	elif controls.get_input_char_pressed('c'):
		entities.trigger_event(_entity, 'set_motion', motion='stand')
		settings.set_tick_mode('normal')
	
	elif controls.get_input_char_pressed(' '):
		_entity['stats']['action_points'] = 0
		SELECTED_SQUAD_MEMBER = None
		WALK_DEST = None
		WALK_PATH = []
		_broken = False
		
		for squad_id in entities.get_entity_group('squads'):
			_squad = entities.get_entity(squad_id)
			
			if not _squad['faction'] == 'Rogues':
				continue
		
			for entity_id in _squad['members']:
				_entity = entities.get_entity(entity_id)
				
				if _entity['stats']['action_points'] > 0:
					_broken = True
					break
			
			if _broken:
				break
		
		else:
			settings.set_tick_mode('normal')
Beispiel #9
0
def get_and_hold_item(entity, item_id):
    _item = entities.get_entity(item_id)

    if timers.has_timer_with_name(entity,
                                  'Getting %s' % _item['stats']['name'],
                                  fuzzy=True):
        return

    entities.trigger_event(
        entity,
        'create_timer',
        time=30,
        name='Getting %s' % _item['stats']['name'],
        exit_callback=lambda _: _get_and_hold_item(entity, item_id))
Beispiel #10
0
def _walk_path(entity):
	if not entity['movement']['path']['positions']:
		return False

	if timers.has_timer_with_name(entity, 'move') or timers.has_timer_with_name(entity, 'move', fuzzy=True):
		return False
	
	if entity['movement']['path']['refresh']:
		set_path(entity, [get_position(entity)])

	_next_pos = entity['movement']['path']['positions'].pop(0)
	_x, _y = get_position(entity)
	_d_x, _d_y = _next_pos[0]-_x, _next_pos[1]-_y

	if not _d_x in [-1, 0, 1] or not _d_y in [-1, 0, 1]:
		_clear_movement(entity)

		return

	if not entity['movement']['path']['positions']:
		entity['movement']['path']['destination'] = None

	push(entity, x=_d_x, y=_d_y, name='move', time=get_override_speed(entity))
Beispiel #11
0
def handle_pain(entity, limb, damage):
    _pain = int(round(damage * .75))

    entity['stats']['pain'] += _pain

    if _pain > 65 and not timers.has_timer_with_name(entity, 'passout'):
        entities.trigger_event(entity, 'stop')
        entities.trigger_event(entity, 'clear_timers')
        entities.trigger_event(entity,
                               'create_timer',
                               time=(_pain - 65) * 6,
                               exit_callback=lambda e: entities.trigger_event(
                                   e, 'stop_animation'),
                               name='passout')
        entities.trigger_event(entity,
                               'animate',
                               animation=['s', '@@'],
                               repeat=-1)
Beispiel #12
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))
Beispiel #13
0
def update_group_status(entity):
	set_squad_meta(entity, 'is_squad_combat_ready', True)
	
	return
	
	_members_combat_ready = 0
	
	for member_id in entity['member_info']:
		_member = entities.get_entity(member_id)
		
		if _member['ai']['meta']['has_needs'] and not _member['ai']['meta']['weapon_loaded']:
			continue
		
		if _member['ai']['meta']['is_injured'] or _member['ai']['meta']['is_panicked']:
			continue
		
		if timers.has_timer_with_name(_member, 'passout'):
			continue
		
		_members_combat_ready += entity['member_info'][member_id]['armed']
	
	set_squad_meta(entity, 'is_squad_combat_ready', _members_combat_ready / float(len(entity['member_info'].keys())) >= .65)
	set_squad_meta(entity, 'is_squad_mobile_ready', _members_combat_ready / float(len(entity['member_info'].keys())) >= .65)
Beispiel #14
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']
Beispiel #15
0
def loop():
    global PLAYER_HAS_SHOOT_TIMER

    events.trigger_event('input')

    if not settings.TICK_MODE == 'strategy' and not (
        (ui_dialog.ACTIVE_DIALOG and ui_director.PAUSE) or ui_menu.ACTIVE_MENU
            or ui_director.PAUSE):
        _has_action = False

        _check_life = set()

        for squad_id in entities.get_entity_group('squads'):
            _squad = entities.get_entity(squad_id)

            if not _squad['faction'] == 'Rogues':
                continue

            for member_id in _squad['members']:
                _member = entities.get_entity(member_id)

                _check_life.add(member_id)
                _check_life.update([
                    i for i in _member['ai']['life_memory']
                    if _member['ai']['life_memory'][i]['can_see']
                    and i in entities.ENTITIES
                ])

        _check_life = list(_check_life)

        #_check_life =
        #_check_life.append(PLAYER['_id'])

        for entity_id in _check_life:
            if timers.has_timer_with_name(entities.get_entity(entity_id),
                                          'shoot'):
                _has_action = True

                break

        if _has_action:
            _ticks_per_tick = 1

        else:
            _ticks_per_tick = settings.PLAN_TICK_RATE

        for _ in range(_ticks_per_tick):
            if settings.TICK_MODE == 'strategy':
                break

            ai_flow.logic()
            events.trigger_event('logic')
            tick()
            free_tick()

    else:
        ai_flow.logic()
        free_tick()

    if pathfinding.wait_for_astar():
        pass

    if not handle_input():
        return False

    events.trigger_event('tick')
    events.trigger_event('camera')

    draw()

    return True
Beispiel #16
0
def tick():
	if settings.TURN_QUEUE:
		_squads = [settings.TURN_QUEUE[0]]
	
	else:
		_squads = entities.get_entity_group('squads')
		_found_able_player = False
		
		for squad_id in entities.get_entity_group('squads'):
			_squad = entities.get_entity(squad_id)
			_break = False
			
			if not _squad['faction'] == 'Rogues':
				continue
			
			for member_id in _squad['members']:
				_entity = entities.get_entity(member_id)
				
				if _entity['ai']['is_npc']:
					continue
				
				if timers.has_timer_with_name(_entity, 'shoot') or _entity['movement']['path']['positions'] or timers.has_timer_with_name(_entity, 'move'):
					_break = True
					
					break
				
				_found_able_player = True
			
			if _break:
				break
		
		else:
			if _found_able_player:
				settings.set_tick_mode('strategy')
	
	for squad_id in _squads:
		_squad = entities.get_entity(squad_id)
		_waiting = False
		
		#if not _squad['faction'] == 'Rogues':
		#	settings.set_tick_mode('normal')
		
		for entity_id in _squad['members']:
			_entity = entities.get_entity(entity_id)
			
			if not settings.TURN_QUEUE:
				_entity['stats']['action_points'] = _entity['stats']['action_points_max']
				
				if _entity['ai']['is_npc']:
					continue
			
			if _entity['stats']['action_points'] <= 0:
				continue
			
			_had_action = False
			
			if timers.has_timer_with_name(_entity, 'shoot') or _entity['movement']['path']['positions'] or timers.has_timer_with_name(_entity, 'move'):
				_had_action = True
			
			elif _entity['ai']['is_player']:
				_waiting = True
				
				continue
			
			entities.trigger_event(_entity, 'tick')
			
			if _had_action and not timers.has_timer_with_name(_entity, 'shoot') and not _entity['movement']['path']['positions'] and not timers.has_timer_with_name(_entity, 'move') and _entity['stats']['action_points'] > 0:
				if _entity['ai']['is_player'] and (ui_squad_control.is_squad_member_selected() and _entity == ui_squad_control.get_selected_squad_member()):
					settings.set_tick_mode('strategy')
					
					break
			
			if _entity['ai']['is_player'] and _entity['stats']['action_points'] <= 0:
				ui_squad_control.reset_selected_squad_member()
				settings.set_tick_mode('strategy')
			
			if not _entity['movement']['path']['positions'] and not timers.has_timer_with_name(_entity, 'shoot') and not timers.has_timer_with_name(_entity, 'move'):
				_entity['stats']['action_points'] -= constants.IDLE_COST
			
			if _entity['stats']['action_points'] <= 0:# and list(_squad['members']).index(entity_id)+1 == len(_squad['members']):
				entities.trigger_event(_squad, 'update_position_map')
			
			#print _entity['stats']['name'], _entity['stats']['action_points']
			
			break
		
		else:
			if _entity['ai']['is_player'] and not _waiting:
				settings.set_tick_mode('normal')
				print 'Normal...'
Beispiel #17
0
def handle_mouse_pressed(entity, x, y, button):
	global DRAGGING_NODE, LAST_CLICKED_POS, SELECTING_TARGET_CALLBACK
	
	if ui_menu.get_active_menu() or ui_menu.DELAY:
		return
	
	if timers.has_timer_with_name(entity, 'passout'):
		return
	
	_x = x+camera.X
	_y = y+camera.Y
	
	if button == 1:
		if DRAGGING_NODE:
			DRAGGING_NODE = None
		
		elif not (_x, _y) in zones.get_active_solids(entity):
			if not DRAGGING_NODE:
				for entity_id in [t for t in entity['ai']['visible_life'] if entity['ai']['life_memory'][t]['can_see']]:
					if entity['_id'] == entity_id:
						continue
					
					_entity = entities.get_entity(entity_id)
					_tx, _ty = movement.get_position(_entity)
					
					if (_x, _y) == (_tx, _ty):
						if SELECTING_TARGET_CALLBACK:
							SELECTING_TARGET_CALLBACK(entity, entity_id)
							SELECTING_TARGET_CALLBACK = None
						else:
							LAST_CLICKED_POS = (_x, _y)
					
							create_life_interact_menu(entity, entity_id)
						
						return
				
				else:
					for entity_id in entities.get_entity_group('contexts'):
						_entity = entities.get_entity(entity_id)
						
						if not _entity['callback']:
							continue
						
						if (_entity['tile']['x'], _entity['tile']['y']) == (_x, _y):
							_entity['callback'](x+2, y-3)
							
							return
					
					else:
						for entity_id in list(entity['ai']['targets'] - entity['ai']['visible_life']):
							_tx, _ty = entity['ai']['life_memory'][entity_id]['last_seen_at']
							
							if (_tx, _ty-2) == (_x, _y):
								ui_dialog.create(x + 2, y - 3, '%s - Last seen <time>' % entities.get_entity(entity_id)['stats']['name'])
								
								return
							
						else:
							for entity_id in entities.get_entity_group('items'):
								_item = entities.get_entity(entity_id)
								
								if _item['stats']['owner']:
									continue
								
								if (_x, _y) == movement.get_position(_item):
									create_item_menu(entity, _item, _x, _y)
									
									return
							
							create_walk_node(entity, _x, _y, clear=True)
							
							return
			
			for node in entity['node_grid']['nodes'].values():
				if (_x, _y) == (node['node']['x'], node['node']['y']):
					DRAGGING_NODE = node
					entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 0))
					
					break
				
				if (_x, _y) in node['node']['path']:
					if not (_x, _y) in node['node']['busy_pos']:
						LAST_CLICKED_POS = (_x, _y)
						
						create_action_menu(entity, LAST_CLICKED_POS[0], LAST_CLICKED_POS[1], on_path=True)
					
					else:
						LAST_CLICKED_POS = None
					
					return
	
	elif button == 2:
		if DRAGGING_NODE:
			entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 255))
			
			DRAGGING_NODE = None
		
		else:
			for node in entity['node_grid']['nodes'].values():
				if (_x, _y) == (node['node']['x'], node['node']['y']):
					entity['node_grid']['path'].remove(node['node']['_id'])
					entities.delete_entity(node['node'])
					redraw_path(entity)
					
					del entity['node_grid']['nodes'][node['node']['_id']]
					
					if not entity['node_grid']['nodes']:
						clear_path(entity)
					
					break
			else:
				create_walk_node(entity, _x, _y)
Beispiel #18
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"]
Beispiel #19
0
def _animal_logic(entity):
    if timers.has_timer_with_name(entity, "passout"):
        return

    ai_visuals.build_item_list(entity)
    ai_visuals.build_life_list(entity)

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

    entity["ai"]["meta"]["in_engagement"] = len(entity["ai"]["targets"]) > 0
    entity["ai"]["meta"]["in_enemy_los"] = (
        len([t for t in entity["ai"]["targets"] if entity["ai"]["life_memory"][t]["in_los"]]) > 0
    )

    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))

        entity["ai"]["meta"]["is_target_near"] = _target_distance <= 25

        if not entity["ai"]["meta"]["in_enemy_los"] and life.can_see_position(
            entity, entity["ai"]["life_memory"][_target]["last_seen_at"]
        ):
            entity["ai"]["meta"]["has_lost_target"] = entity["ai"]["meta"]["is_target_near"]

        elif 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"]["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'] = skeleton.has_critical_injury(entity)
    entity["ai"]["meta"]["is_injured"] = skeleton.has_critical_injury(entity)
    entity["ai"]["meta"]["is_panicked"] = entity["ai"]["meta"]["is_injured"]

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

    _goap = _handle_goap(entity)

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

        return

    _plan = _goap[0]
    _plan["planner"].trigger_callback(entity, _plan["actions"][0]["name"])
    # print time.time() - _t

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

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

    entity["ai"]["current_action"] = _plan["actions"][0]["name"]
Beispiel #20
0
def tick():
    if settings.TURN_QUEUE:
        _squads = [settings.TURN_QUEUE[0]]

    else:
        _squads = entities.get_entity_group('squads')
        _found_able_player = False

        for squad_id in entities.get_entity_group('squads'):
            _squad = entities.get_entity(squad_id)
            _break = False

            if not _squad['faction'] == 'Rogues':
                continue

            for member_id in _squad['members']:
                _entity = entities.get_entity(member_id)

                if _entity['ai']['is_npc']:
                    continue

                if timers.has_timer_with_name(
                        _entity, 'shoot') or _entity['movement']['path'][
                            'positions'] or timers.has_timer_with_name(
                                _entity, 'move'):
                    _break = True

                    break

                _found_able_player = True

            if _break:
                break

        else:
            if _found_able_player:
                settings.set_tick_mode('strategy')

    for squad_id in _squads:
        _squad = entities.get_entity(squad_id)
        _waiting = False

        #if not _squad['faction'] == 'Rogues':
        #	settings.set_tick_mode('normal')

        for entity_id in _squad['members']:
            _entity = entities.get_entity(entity_id)

            if not settings.TURN_QUEUE:
                _entity['stats']['action_points'] = _entity['stats'][
                    'action_points_max']

                if _entity['ai']['is_npc']:
                    continue

            if _entity['stats']['action_points'] <= 0:
                continue

            _had_action = False

            if timers.has_timer_with_name(
                    _entity, 'shoot') or _entity['movement']['path'][
                        'positions'] or timers.has_timer_with_name(
                            _entity, 'move'):
                _had_action = True

            elif _entity['ai']['is_player']:
                _waiting = True

                continue

            entities.trigger_event(_entity, 'tick')

            if _had_action and not timers.has_timer_with_name(
                    _entity, 'shoot') and not _entity['movement']['path'][
                        'positions'] and not timers.has_timer_with_name(
                            _entity,
                            'move') and _entity['stats']['action_points'] > 0:
                if _entity['ai']['is_player'] and (
                        ui_squad_control.is_squad_member_selected() and _entity
                        == ui_squad_control.get_selected_squad_member()):
                    settings.set_tick_mode('strategy')

                    break

            if _entity['ai'][
                    'is_player'] and _entity['stats']['action_points'] <= 0:
                ui_squad_control.reset_selected_squad_member()
                settings.set_tick_mode('strategy')

            if not _entity['movement']['path'][
                    'positions'] and not timers.has_timer_with_name(
                        _entity, 'shoot') and not timers.has_timer_with_name(
                            _entity, 'move'):
                _entity['stats']['action_points'] -= constants.IDLE_COST

            if _entity['stats'][
                    'action_points'] <= 0:  # and list(_squad['members']).index(entity_id)+1 == len(_squad['members']):
                entities.trigger_event(_squad, 'update_position_map')

            #print _entity['stats']['name'], _entity['stats']['action_points']

            break

        else:
            if _entity['ai']['is_player'] and not _waiting:
                settings.set_tick_mode('normal')
                print 'Normal...'
Beispiel #21
0
def _animal_logic(entity):
    if timers.has_timer_with_name(entity, 'passout'):
        return

    ai_visuals.build_item_list(entity)
    ai_visuals.build_life_list(entity)

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

    entity['ai']['meta']['in_engagement'] = len(entity['ai']['targets']) > 0
    entity['ai']['meta']['in_enemy_los'] = len([
        t for t in entity['ai']['targets']
        if entity['ai']['life_memory'][t]['in_los']
    ]) > 0

    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))

        entity['ai']['meta']['is_target_near'] = _target_distance <= 25

        if not entity['ai']['meta']['in_enemy_los'] and life.can_see_position(
                entity, entity['ai']['life_memory'][_target]['last_seen_at']):
            entity['ai']['meta']['has_lost_target'] = entity['ai']['meta'][
                'is_target_near']

        elif 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']['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'] = skeleton.has_critical_injury(entity)
    entity['ai']['meta']['is_injured'] = skeleton.has_critical_injury(entity)
    entity['ai']['meta']['is_panicked'] = entity['ai']['meta']['is_injured']

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

    _goap = _handle_goap(entity)

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

        return

    _plan = _goap[0]
    _plan['planner'].trigger_callback(entity, _plan['actions'][0]['name'])
    #print time.time() - _t

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

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

    entity['ai']['current_action'] = _plan['actions'][0]['name']
Beispiel #22
0
def loop():
	global PLAYER_HAS_SHOOT_TIMER
	
	events.trigger_event('input')

	if not settings.TICK_MODE == 'strategy' and not ((ui_dialog.ACTIVE_DIALOG and ui_director.PAUSE) or ui_menu.ACTIVE_MENU or ui_director.PAUSE):
		_has_action = False
		
		_check_life = set()
		
		for squad_id in entities.get_entity_group('squads'):
			_squad = entities.get_entity(squad_id)
			
			if not _squad['faction'] == 'Rogues':
				continue
			
			for member_id in _squad['members']:
				_member = entities.get_entity(member_id)
				
				_check_life.add(member_id)
				_check_life.update([i for i in _member['ai']['life_memory'] if _member['ai']['life_memory'][i]['can_see'] and i in entities.ENTITIES])

		_check_life = list(_check_life)
		
		#_check_life = 
		#_check_life.append(PLAYER['_id'])
		
		for entity_id in _check_life:
			if timers.has_timer_with_name(entities.get_entity(entity_id), 'shoot'):
				_has_action = True
				
				break
		
		if _has_action:
			_ticks_per_tick = 1
		
		else:
			_ticks_per_tick = settings.PLAN_TICK_RATE
		
		for _ in range(_ticks_per_tick):
			if settings.TICK_MODE == 'strategy':
				break
			
			ai_flow.logic()
			events.trigger_event('logic')
			tick()
			free_tick()
	
	else:
		ai_flow.logic()
		free_tick()

	if pathfinding.wait_for_astar():
		pass

	if not handle_input():
		return False

	events.trigger_event('tick')	
	events.trigger_event('camera')
	
	draw()

	return True
Beispiel #23
0
def handle_mouse_pressed(entity, x, y, button):
    global DRAGGING_NODE, LAST_CLICKED_POS, SELECTING_TARGET_CALLBACK

    if ui_menu.get_active_menu() or ui_menu.DELAY:
        return

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

    _x = x + camera.X
    _y = y + camera.Y

    if button == 1:
        if DRAGGING_NODE:
            DRAGGING_NODE = None

        elif not (_x, _y) in zones.get_active_solids(entity):
            if not DRAGGING_NODE:
                for entity_id in [
                        t for t in entity['ai']['visible_life']
                        if entity['ai']['life_memory'][t]['can_see']
                ]:
                    if entity['_id'] == entity_id:
                        continue

                    _entity = entities.get_entity(entity_id)
                    _tx, _ty = movement.get_position(_entity)

                    if (_x, _y) == (_tx, _ty):
                        if SELECTING_TARGET_CALLBACK:
                            SELECTING_TARGET_CALLBACK(entity, entity_id)
                            SELECTING_TARGET_CALLBACK = None
                        else:
                            LAST_CLICKED_POS = (_x, _y)

                            create_life_interact_menu(entity, entity_id)

                        return

                else:
                    for entity_id in entities.get_entity_group('contexts'):
                        _entity = entities.get_entity(entity_id)

                        if not _entity['callback']:
                            continue

                        if (_entity['tile']['x'],
                                _entity['tile']['y']) == (_x, _y):
                            _entity['callback'](x + 2, y - 3)

                            return

                    else:
                        for entity_id in list(entity['ai']['targets'] -
                                              entity['ai']['visible_life']):
                            _tx, _ty = entity['ai']['life_memory'][entity_id][
                                'last_seen_at']

                            if (_tx, _ty - 2) == (_x, _y):
                                ui_dialog.create(
                                    x + 2, y - 3, '%s - Last seen <time>' %
                                    entities.get_entity(
                                        entity_id)['stats']['name'])

                                return

                        else:
                            for entity_id in entities.get_entity_group(
                                    'items'):
                                _item = entities.get_entity(entity_id)

                                if _item['stats']['owner']:
                                    continue

                                if (_x, _y) == movement.get_position(_item):
                                    create_item_menu(entity, _item, _x, _y)

                                    return

                            create_walk_node(entity, _x, _y, clear=True)

                            return

            for node in entity['node_grid']['nodes'].values():
                if (_x, _y) == (node['node']['x'], node['node']['y']):
                    DRAGGING_NODE = node
                    entities.trigger_event(DRAGGING_NODE['node'],
                                           'set_fore_color',
                                           color=(255, 255, 0))

                    break

                if (_x, _y) in node['node']['path']:
                    if not (_x, _y) in node['node']['busy_pos']:
                        LAST_CLICKED_POS = (_x, _y)

                        create_action_menu(entity,
                                           LAST_CLICKED_POS[0],
                                           LAST_CLICKED_POS[1],
                                           on_path=True)

                    else:
                        LAST_CLICKED_POS = None

                    return

    elif button == 2:
        if DRAGGING_NODE:
            entities.trigger_event(DRAGGING_NODE['node'],
                                   'set_fore_color',
                                   color=(255, 255, 255))

            DRAGGING_NODE = None

        else:
            for node in entity['node_grid']['nodes'].values():
                if (_x, _y) == (node['node']['x'], node['node']['y']):
                    entity['node_grid']['path'].remove(node['node']['_id'])
                    entities.delete_entity(node['node'])
                    redraw_path(entity)

                    del entity['node_grid']['nodes'][node['node']['_id']]

                    if not entity['node_grid']['nodes']:
                        clear_path(entity)

                    break
            else:
                create_walk_node(entity, _x, _y)