Example #1
0
def build_item_list(entity):
	entity['ai']['visible_items'] = {'weapon': [],
	                                 'container': [],
	                                 'ammo': [],
	                                 'bullet': [],
	                                 'corpse': []}
	
	return
	
	_active_solids = zones.get_active_solids(entity)
	
	for entity_id in entities.get_entity_group('items'):
		_item = entities.get_entity(entity_id)
		
		if not _item['stats']['type'] in entity['ai']['visible_items']:
			continue
		
		if _item['stats']['owner']:
			continue
		
		_distance = numbers.distance(movement.get_position(entity), movement.get_position(_item))
		
		if _distance >= stats.get_vision(entity):
			continue
		
		for pos in shapes.line(movement.get_position(entity), movement.get_position(_item)):
			if pos in _active_solids:
				break
		else:
			entity['ai']['visible_items'][_item['stats']['type']].append(entity_id)
			
			entities.trigger_event(_item, 'seen', target_id=entity['_id'])
Example #2
0
def hit(entity, projectile, damage_mod=1.0):
    _accuracy = random.uniform(.7, 1)
    _hit_map = []

    for limb_name in entity['skeleton']['limbs']:
        _limb = entity['skeleton']['limbs'][limb_name]

        for i in range(int(round(_limb['health'] * _limb['accuracy']))):
            _hit_map.append(limb_name)

    _limb_name = random.choice(_hit_map)
    _limb = entity['skeleton']['limbs'][_limb_name]
    _damage = int(
        round((projectile['damage'] * _accuracy) * (numbers.clip(
            (1 - _limb['accuracy']), 0.25, .6) + .4)))
    _damage = int(round(_damage * damage_mod))
    _limb['health'] -= _damage
    _x, _y = movement.get_position(entity)
    _x += int(round(random.uniform(-1, 1)))
    _y += int(round(random.uniform(-1, 1)))
    _mod = _limb['health'] / float(_limb['max_health'])

    #effects.explosion(_x, _y, 6)

    if not (_x, _y) in zones.get_active_solids(entity,
                                               ignore_calling_entity=True):
        #effects.blood(_x, _y)
        effects.blood_splatter(
            _x, _y,
            movement.get_direction(projectile) + random.randint(-5, 5))
        entities.trigger_event(entity,
                               'animate',
                               animation=['X', '@@'],
                               repeat=4 * int(round((1 - _mod))),
                               delay=20 * _mod)

    if _limb['health'] <= 0:
        if _limb['critical']:
            if projectile['owner'] in entities.ENTITIES:
                entities.trigger_event(entities.get_entity(
                    projectile['owner']),
                                       'log_kill',
                                       target_id=entity['_id'])
                entities.trigger_event(entity,
                                       'killed_by',
                                       target_id=projectile['owner'])

            #entity['stats']['grave'] = {'':}
            entities.delete_entity(entity)
    else:
        if projectile['owner'] in entities.ENTITIES:
            entities.trigger_event(entities.get_entity(projectile['owner']),
                                   'did_damage',
                                   target_id=entity['_id'],
                                   damage=_damage)

        entities.trigger_event(entity,
                               'damage',
                               limb=_limb_name,
                               damage=_damage)
Example #3
0
def _smoke_shooter_push(entity):
	_x, _y = movement.get_position(entity)
	_direction = movement.get_direction(entity)
	_mod = random.randint(-35, 35)
	_alpha = flags.get_flag(entity, 'alpha')
	
	if _mod < 0:
		_mod = numbers.clip(_mod, -35, -20)
	else:
		_mod = numbers.clip(_mod, 20, 35)
	
	_direction += _mod
	
	_v_x, _v_y = numbers.velocity(_direction, random.uniform(.65, .85))
	
	if not int(round(_x + _v_x)) == int(round(_x)) or not int(round(_y + _v_y)) == int(round(_y)):
		#smoke_cloud(_x + _v_x, _y + _v_y, random.randint(1, 2), start_alpha=_alpha, decay_amount=1.2)
		smoke(_x + _v_x, _y + _v_y, .75, start_amount=_alpha, decay_amount=random.uniform(3.0, 4.0))
	
	_x += _v_x
	_y += _v_y
	
	if (int(round(_x)), int(round(_y))) in zones.get_active_solids({}, no_life=True):
		entities.delete_entity(entity)
		
		return
	
	entities.trigger_event(entity, 'set_direction', direction=_direction)
	entities.trigger_event(entity, 'set_position', x=_x, y=_y)
	entities.trigger_event(entity, 'set_flag', flag='alpha', value=_alpha - .05)
Example #4
0
def check_for_collisions(entity):
    _x, _y = movement.get_position(entity)

    if _x < 0 or _x >= zones.get_active_size(
    )[0] - 1 or _y < 0 or _y >= zones.get_active_size()[1] - 1:
        entities.delete_entity(entity)

        return

    if (_x, _y) in zones.get_active_solids(entity):
        entities.trigger_event(entity, 'collision_with_solid')

        return

    for entity_id in entities.get_entity_group('life'):
        if entity_id == entity['owner']:
            continue

        if movement.get_position(entity) == movement.get_position_via_id(
                entity_id):
            entities.trigger_event(entity,
                                   'collision_with_entity',
                                   target_id=entity_id)

            return
Example #5
0
def can_see_position(entity, position):
	_solids = zones.get_active_solids(entity)
	
	if numbers.distance(movement.get_position(entity), position) > stats.get_vision(entity):
		return False
	
	for pos in shapes.line(movement.get_position(entity), position):
		if pos in _solids:
			return False
	
	return True
Example #6
0
def can_see_position(entity, position):
    _solids = zones.get_active_solids(entity)

    if numbers.distance(movement.get_position(entity),
                        position) > stats.get_vision(entity):
        return False

    for pos in shapes.line(movement.get_position(entity), position):
        if pos in _solids:
            return False

    return True
Example #7
0
def check_next_position(entity):
	_x = int(round(entity['movement']['next_x']))
	_y = int(round(entity['movement']['next_y']))
	
	if (_x, _y) in zones.get_active_solids({}, no_life=True, ignore_calling_entity=True):
		entity['movement']['next_x'] = entity['movement']['x']
		entity['movement']['next_y'] = entity['movement']['y']
		
		entities.trigger_event(entity, 'collision_with_solid')
		
		return True
	
	return False
Example #8
0
def check_next_position(entity):
    _x = int(round(entity['movement']['next_x']))
    _y = int(round(entity['movement']['next_y']))

    if (_x, _y) in zones.get_active_solids({},
                                           no_life=True,
                                           ignore_calling_entity=True):
        entity['movement']['next_x'] = entity['movement']['x']
        entity['movement']['next_y'] = entity['movement']['y']

        entities.trigger_event(entity, 'collision_with_solid')

        return True

    return False
Example #9
0
def handle_movement_order(x, y):
	global WALK_PATH, WALK_DEST
	
	if not is_squad_member_selected() or (x, y) in zones.get_active_solids({}, ignore_calling_entity=True):
		return False
	
	_entity = get_selected_squad_member()
	
	movement.walk_to_position(_entity, x, y, zones.get_active_astar_map(), zones.get_active_weight_map())
	
	WALK_PATH = _entity['movement']['path']['positions']
	WALK_DEST = _entity['movement']['path']['destination']
	
	settings.set_tick_mode('normal')
	
	return True
Example #10
0
def handle_mouse_movement(entity, x, y, vx, vy):
	if not DRAGGING_NODE:
		return
	
	if (vx, vy) in zones.get_active_solids(entity):
		return
	
	entities.trigger_event(DRAGGING_NODE['node'], 'set_position', x=vx, y=vy)
	entities.trigger_event(DRAGGING_NODE['node'], 'set_fore_color', color=(255, 255, 255))
	
	DRAGGING_NODE['node']['x'] = vx
	DRAGGING_NODE['node']['y'] = vy
	DRAGGING_NODE['node']['path'] = []
	
	redraw_path(entity)
	entities.trigger_event(entity, 'stop')
Example #11
0
def find_melee_position(entity):
	_target = entity['ai']['nearest_target']
	_x, _y = entity['ai']['life_memory'][_target]['last_seen_at']
	_closest_pos = {'pos': None, 'distance': 0}
	_solids = zones.get_active_solids(entity, ignore_entities=[_target])
	
	for x, y in [(_x-1, _y), (_x+1, _y), (_x, _y-1), (_x, _y+1), (_x-1, _y-1), (_x+1, _y-1), (_x-1, _y+1), (_x+1, _y+1)]:
		if (x, y) in _solids:
			continue
		
		_distance = numbers.distance(movement.get_position(entity), (x, y))
		
		if not _closest_pos['pos'] or _distance < _closest_pos['distance']:
			_closest_pos['distance'] = _distance
			_closest_pos['pos'] = (x, y)
	
	movement.walk_to_position(entity, _closest_pos['pos'][0], _closest_pos['pos'][1], zones.get_active_astar_map(), zones.get_active_weight_map())
Example #12
0
def handle_mouse_movement(entity, x, y, vx, vy):
    if not DRAGGING_NODE:
        return

    if (vx, vy) in zones.get_active_solids(entity):
        return

    entities.trigger_event(DRAGGING_NODE['node'], 'set_position', x=vx, y=vy)
    entities.trigger_event(DRAGGING_NODE['node'],
                           'set_fore_color',
                           color=(255, 255, 255))

    DRAGGING_NODE['node']['x'] = vx
    DRAGGING_NODE['node']['y'] = vy
    DRAGGING_NODE['node']['path'] = []

    redraw_path(entity)
    entities.trigger_event(entity, 'stop')
Example #13
0
def handle_movement_order(x, y):
    global WALK_PATH, WALK_DEST

    if not is_squad_member_selected() or (x, y) in zones.get_active_solids(
        {}, ignore_calling_entity=True):
        return False

    _entity = get_selected_squad_member()

    movement.walk_to_position(_entity, x, y, zones.get_active_astar_map(),
                              zones.get_active_weight_map())

    WALK_PATH = _entity['movement']['path']['positions']
    WALK_DEST = _entity['movement']['path']['destination']

    settings.set_tick_mode('normal')

    return True
Example #14
0
def handle_mouse_movement(x, y):
	global WALK_PATH, WALK_DEST
	
	if ui_menu.get_active_menu() or ui_menu.DELAY or not is_squad_member_selected():
		return
	
	_x = x+camera.X
	_y = y+camera.Y
	
	if (_x, _y) in zones.get_active_solids({}, ignore_calling_entity=True, no_life=True):
		return
	
	_s_x, _s_y = movement.get_position(get_selected_squad_member())
	
	if (_x, _y) == WALK_DEST or (_x, _y) == (_s_x, _s_y):
		return
	
	WALK_PATH = pathfinding.astar((_s_x, _s_y), (_x, _y), zones.get_active_astar_map(), zones.get_active_weight_map())
	WALK_DEST = (_x, _y)
Example #15
0
def explosion(x, y, size):
	_solids = zones.get_active_solids({}, no_life=True)
	
	for pos in shapes.circle_smooth(x, y, size + .1, 0.05):
		_c_mod = 1 - (numbers.float_distance((x, y), pos) / size)
		_c_mod_clip = numbers.clip(1 - numbers.float_distance((x, y), pos) / size, random.uniform(.3, .45), 1)
		
		if pos in _solids or set(shapes.line((x, y), (int(round(pos[0])), int(round(pos[1]))))) & _solids:
			continue
		
		smoke(pos[0], pos[1], _c_mod_clip)
		
		if random.uniform(0, 1) < numbers.clip(_c_mod, 0, .75) and not pos in _solids:
			fire(pos[0], pos[1], _c_mod)
	
	for i in range(random.randint(2 * size, 3*size)):
		smoke_shooter(x, y, random.randint(0, 359))
	
	light(x, y, random.randint(7, 9), r=2.5, g=1.5, b=1.5)
	light(x, y, random.randint(13, 15), r=1.3, g=1.3, b=1.3)
Example #16
0
def check_for_collisions(entity):
	_x, _y = movement.get_position(entity)
	
	if _x < 0 or _x >= zones.get_active_size()[0]-1 or _y < 0 or _y >= zones.get_active_size()[1]-1:
		entities.delete_entity(entity)
		
		return
	
	if (_x, _y) in zones.get_active_solids(entity):
		entities.trigger_event(entity, 'collision_with_solid')
		
		return
	
	for entity_id in entities.get_entity_group('life'):
		if entity_id == entity['owner']:
			continue
		
		if movement.get_position(entity) == movement.get_position_via_id(entity_id):
			entities.trigger_event(entity, 'collision_with_entity', target_id=entity_id)
			
			return
Example #17
0
def find_melee_position(entity):
    _target = entity['ai']['nearest_target']
    _x, _y = entity['ai']['life_memory'][_target]['last_seen_at']
    _closest_pos = {'pos': None, 'distance': 0}
    _solids = zones.get_active_solids(entity, ignore_entities=[_target])

    for x, y in [(_x - 1, _y), (_x + 1, _y), (_x, _y - 1), (_x, _y + 1),
                 (_x - 1, _y - 1), (_x + 1, _y - 1), (_x - 1, _y + 1),
                 (_x + 1, _y + 1)]:
        if (x, y) in _solids:
            continue

        _distance = numbers.distance(movement.get_position(entity), (x, y))

        if not _closest_pos['pos'] or _distance < _closest_pos['distance']:
            _closest_pos['distance'] = _distance
            _closest_pos['pos'] = (x, y)

    movement.walk_to_position(entity, _closest_pos['pos'][0],
                              _closest_pos['pos'][1],
                              zones.get_active_astar_map(),
                              zones.get_active_weight_map())
Example #18
0
def handle_mouse_movement(x, y):
    global WALK_PATH, WALK_DEST

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

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

    if (_x, _y) in zones.get_active_solids({},
                                           ignore_calling_entity=True,
                                           no_life=True):
        return

    _s_x, _s_y = movement.get_position(get_selected_squad_member())

    if (_x, _y) == WALK_DEST or (_x, _y) == (_s_x, _s_y):
        return

    WALK_PATH = pathfinding.astar((_s_x, _s_y), (_x, _y),
                                  zones.get_active_astar_map(),
                                  zones.get_active_weight_map())
    WALK_DEST = (_x, _y)
Example #19
0
def _fire_movement(entity, x, y, **kwargs):
	_solids = zones.get_active_solids({}, no_life=True)
	
	if (x, y) in _solids:
		entities.delete_entity(entity)
Example #20
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)
Example #21
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)
Example #22
0
def search_for_target(entity):
	_lost_targets = entity['ai']['targets_to_search']
	_inside = zones.get_active_inside_positions()
	
	if not _lost_targets:
		print 'Trying to search with no lost targets'
		
		return
	
	_closest_target = {'distance': 0, 'target_id': None}
	
	for target_id in _lost_targets:
		_memory = entity['ai']['life_memory'][target_id]
		_distance = numbers.distance(movement.get_position(entity), _memory['last_seen_at'])
		
		if not _closest_target['target_id'] or _distance < _closest_target['distance']:
			_closest_target['target_id'] = target_id
			_closest_target['distance'] = _distance
	
	_target = entities.get_entity(_closest_target['target_id'])
	_solids = zones.get_active_solids(entity)
	
	if flags.has_flag(entity, 'search_nodes'):
		_search_for_target(entity, _target['_id'])
		
		return
	
	_x, _y = movement.get_position(entity)
	_tx, _ty = entity['ai']['life_memory'][_target['_id']]['last_seen_at']
	_nodes_to_search = {}
	
	if entity['ai']['life_memory'][_target['_id']]['last_seen_velocity']:
		_vx, _vy = entity['ai']['life_memory'][_target['_id']]['last_seen_velocity']
		_tx + _vx*6
		_ty + _vy*6
	
	entities.trigger_event(entity, 'set_flag', flag='search_nodes', value=_nodes_to_search)
	
	for node_x, node_y in zones.get_active_node_grid():
		_distance = numbers.distance((_tx, _ty), (node_x, node_y))
		
		if _distance >= 30:
			continue
		
		if not (node_x, node_y) in _inside:
			continue
		
		_continue = False
		
		for pos in shapes.line((_tx, _ty), (node_x, node_y)):
			if pos in _solids:
				_continue = True
				
				break
		
		if _continue:
			continue
		
		if _distance in _nodes_to_search:
			if not (node_x, node_y) in _nodes_to_search[_distance]:
				_nodes_to_search[_distance].append((node_x, node_y))
		else:
			_nodes_to_search[_distance] = [(node_x, node_y)]
Example #23
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']
Example #24
0
def search_for_target(entity):
    _lost_targets = entity['ai']['targets_to_search']
    _inside = zones.get_active_inside_positions()

    if not _lost_targets:
        print 'Trying to search with no lost targets'

        return

    _closest_target = {'distance': 0, 'target_id': None}

    for target_id in _lost_targets:
        _memory = entity['ai']['life_memory'][target_id]
        _distance = numbers.distance(movement.get_position(entity),
                                     _memory['last_seen_at'])

        if not _closest_target[
                'target_id'] or _distance < _closest_target['distance']:
            _closest_target['target_id'] = target_id
            _closest_target['distance'] = _distance

    _target = entities.get_entity(_closest_target['target_id'])
    _solids = zones.get_active_solids(entity)

    if flags.has_flag(entity, 'search_nodes'):
        _search_for_target(entity, _target['_id'])

        return

    _x, _y = movement.get_position(entity)
    _tx, _ty = entity['ai']['life_memory'][_target['_id']]['last_seen_at']
    _nodes_to_search = {}

    if entity['ai']['life_memory'][_target['_id']]['last_seen_velocity']:
        _vx, _vy = entity['ai']['life_memory'][
            _target['_id']]['last_seen_velocity']
        _tx + _vx * 6
        _ty + _vy * 6

    entities.trigger_event(entity,
                           'set_flag',
                           flag='search_nodes',
                           value=_nodes_to_search)

    for node_x, node_y in zones.get_active_node_grid():
        _distance = numbers.distance((_tx, _ty), (node_x, node_y))

        if _distance >= 30:
            continue

        if not (node_x, node_y) in _inside:
            continue

        _continue = False

        for pos in shapes.line((_tx, _ty), (node_x, node_y)):
            if pos in _solids:
                _continue = True

                break

        if _continue:
            continue

        if _distance in _nodes_to_search:
            if not (node_x, node_y) in _nodes_to_search[_distance]:
                _nodes_to_search[_distance].append((node_x, node_y))
        else:
            _nodes_to_search[_distance] = [(node_x, node_y)]