Ejemplo n.º 1
0
def focus_on_entity(entity, target_id, show_line=False, pause=False):
    global HAS_FOCUS, PAUSE

    if HAS_FOCUS or '--no-fx' in sys.argv:
        return

    HAS_FOCUS = target_id
    PAUSE = pause

    _entity = ui_dialog.create(18, 7, 'Enemy spotted!')

    entities.register_event(_entity, 'delete', lambda e: lose_focus())
    entities.trigger_event(DIRECTOR,
                           'create_timer',
                           time=120,
                           exit_callback=lambda e: ui_dialog.delete(_entity))

    if show_line:
        for x, y in shapes.line(movement.get_position(entity),
                                movement.get_position_via_id(target_id)):
            effects.vapor(x,
                          y,
                          group='effects_freetick',
                          start_alpha=1.0,
                          fade_rate=.01)
Ejemplo n.º 2
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'])
Ejemplo n.º 3
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
Ejemplo n.º 4
0
def draw_raid_path(path):
    _start_pos = path[0]

    for pos in path[1:]:
        _r_pos_1 = _start_pos[0] * constants.MAP_CELL_SPACE, _start_pos[1] * constants.MAP_CELL_SPACE
        _r_pos_2 = pos[0] * constants.MAP_CELL_SPACE, pos[1] * constants.MAP_CELL_SPACE
        _line = shapes.line(_r_pos_1, _r_pos_2)

        for x, y in _line[: len(_line) - 1]:
            display.write_char("map_path", x + constants.MAP_CELL_SPACE / 2, y + constants.MAP_CELL_SPACE / 2, chr(176))

        _start_pos = pos[:]
Ejemplo n.º 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
Ejemplo n.º 6
0
def draw_raid_path(path):
    _start_pos = path[0]

    for pos in path[1:]:
        _r_pos_1 = _start_pos[0] * constants.MAP_CELL_SPACE, _start_pos[
            1] * constants.MAP_CELL_SPACE
        _r_pos_2 = pos[0] * constants.MAP_CELL_SPACE, pos[
            1] * constants.MAP_CELL_SPACE
        _line = shapes.line(_r_pos_1, _r_pos_2)

        for x, y in _line[:len(_line) - 1]:
            display.write_char('map_path', x + constants.MAP_CELL_SPACE / 2,
                               y + constants.MAP_CELL_SPACE / 2, chr(176))

        _start_pos = pos[:]
Ejemplo n.º 7
0
def focus_on_entity(entity, target_id, show_line=False, pause=False):
	global HAS_FOCUS, PAUSE
	
	if HAS_FOCUS or '--no-fx' in sys.argv:
		return
	
	HAS_FOCUS = target_id
	PAUSE = pause
	
	_entity = ui_dialog.create(18, 7, 'Enemy spotted!')
	
	entities.register_event(_entity, 'delete', lambda e: lose_focus())
	entities.trigger_event(DIRECTOR, 'create_timer', time=120, exit_callback=lambda e: ui_dialog.delete(_entity))
	
	if show_line:
		for x, y in shapes.line(movement.get_position(entity), movement.get_position_via_id(target_id)):
			effects.vapor(x, y, group='effects_freetick', start_alpha=1.0, fade_rate=.01)
Ejemplo n.º 8
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)
Ejemplo n.º 9
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']
Ejemplo n.º 10
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)]
Ejemplo n.º 11
0
def get_vantage_point(squad, member_id):
	_member = entities.get_entity(member_id)
	_member_pos = movement.get_position(_member)
	_best_vantage = {'position': None, 'score': 1000}
	_engage_range = flags.get_flag(_member, 'engage_distance')
	_min_engage_range = flags.get_flag(_member, 'min_engage_distance')
	
	if _member['movement']['path']['destination']:
		if _member['movement']['path']['destination'] in squad['position_map_scores']:
			_scores = squad['position_map_scores'][_member['movement']['path']['destination']]
			_score = _scores['vantage']# + _scores['member_coverage']
			_continue = False
			
			for target_id in squad['known_targets']:
				_last_known_position = _member['ai']['life_memory'][target_id]['last_seen_at']
				_distance_to_target = numbers.distance(_member['movement']['path']['destination'], _last_known_position)
				
				if _distance_to_target < _min_engage_range:
					_continue = True
					
					break
			
			if not _continue and _scores['targets'] and _score >= _min_engage_range and _score <= _engage_range:
				return _member['movement']['path']['destination']
	
	for pos in squad['position_map_scores']:
		_scores = squad['position_map_scores'][pos]
		_dist = numbers.distance(_member_pos, pos)
		_score = _scores['vantage'] + _dist
		_continue = False
		
		if not _scores['targets'] or _score - _dist < _min_engage_range or _score > _engage_range + _dist:
			continue
		
		for target_id in squad['known_targets']:
			_last_known_position = _member['ai']['life_memory'][target_id]['last_seen_at']
			_distance_to_target = numbers.distance(pos, _last_known_position)
			
			if _distance_to_target < _min_engage_range:
				_continue = True
				
				break
			
		if _continue:
			continue

		if _score < _best_vantage['score']:
			_astar_distance = len(pathfinding.astar(_member_pos, pos, zones.get_active_astar_map(), zones.get_active_weight_map()))
			_best_vantage['score'] = _score + _scores['member_coverage'] + int(round((_astar_distance * .15)))
			_best_vantage['position'] = pos[:]
	
	if not _best_vantage['position']:
		_member['ai']['meta']['has_firing_position'] = False
		
		entities.trigger_event(_member, 'create_timer', time=60, exit_callback=_reset_fire_position)
		
		return
	
	_x, _y = movement.get_position(_member)
	_member_positions = set()
	
	for squad_member_id in squad['members']:
		if squad_member_id == member_id:
			continue
		
		_member_positions.add(movement.get_position_via_id(squad_member_id))
	
	_v_p = _best_vantage['position']
	_friendly_fire = False
	
	for pos in shapes.line((_x, _y), _best_vantage['position']):
		if pos in _member_positions:
			_friendly_fire = True
			
			break

	if _friendly_fire:
		for n_pos in [(_v_p[0]-1, _v_p[1]-1), (_v_p[0], _v_p[1]-1), (_v_p[0]+1, _v_p[1]-1), (_v_p[0]-1, _v_p[1]), (_v_p[0]+1, _v_p[1]), (_v_p[0]-1, _v_p[1]+1), (_v_p[0], _v_p[1]+1), (_v_p[0]+1, _v_p[1]+1)]:
			if not n_pos in squad['position_map_scores']:
				continue
			
			_break = False
			for nn_pos in shapes.line((_x, _y), n_pos):
				if nn_pos in _member_positions:
					_break = True
					
					break
			else:
				_v_p = n_pos
				
				break
			
			if _break:
				continue
	
	for coverage_pos in shapes.circle(_v_p[0], _v_p[1], 6):
		if not coverage_pos in squad['position_map_scores']:
			continue
		
		_c_dist = 15 * (1 - (numbers.distance(coverage_pos, (_x, _y)) / 6.0))
		
		squad['position_map_scores'][coverage_pos]['member_coverage'] += _c_dist
	
	squad['position_map_scores'][_v_p]['member_coverage'] += 6
	
	return _v_p
Ejemplo n.º 12
0
def get_vantage_point(squad, member_id):
    _member = entities.get_entity(member_id)
    _member_pos = movement.get_position(_member)
    _best_vantage = {'position': None, 'score': 1000}
    _engage_range = flags.get_flag(_member, 'engage_distance')
    _min_engage_range = flags.get_flag(_member, 'min_engage_distance')

    if _member['movement']['path']['destination']:
        if _member['movement']['path']['destination'] in squad[
                'position_map_scores']:
            _scores = squad['position_map_scores'][_member['movement']['path']
                                                   ['destination']]
            _score = _scores['vantage']  # + _scores['member_coverage']
            _continue = False

            for target_id in squad['known_targets']:
                _last_known_position = _member['ai']['life_memory'][target_id][
                    'last_seen_at']
                _distance_to_target = numbers.distance(
                    _member['movement']['path']['destination'],
                    _last_known_position)

                if _distance_to_target < _min_engage_range:
                    _continue = True

                    break

            if not _continue and _scores[
                    'targets'] and _score >= _min_engage_range and _score <= _engage_range:
                return _member['movement']['path']['destination']

    for pos in squad['position_map_scores']:
        _scores = squad['position_map_scores'][pos]
        _dist = numbers.distance(_member_pos, pos)
        _score = _scores['vantage'] + _dist
        _continue = False

        if not _scores[
                'targets'] or _score - _dist < _min_engage_range or _score > _engage_range + _dist:
            continue

        for target_id in squad['known_targets']:
            _last_known_position = _member['ai']['life_memory'][target_id][
                'last_seen_at']
            _distance_to_target = numbers.distance(pos, _last_known_position)

            if _distance_to_target < _min_engage_range:
                _continue = True

                break

        if _continue:
            continue

        if _score < _best_vantage['score']:
            _astar_distance = len(
                pathfinding.astar(_member_pos, pos,
                                  zones.get_active_astar_map(),
                                  zones.get_active_weight_map()))
            _best_vantage['score'] = _score + _scores['member_coverage'] + int(
                round((_astar_distance * .15)))
            _best_vantage['position'] = pos[:]

    if not _best_vantage['position']:
        _member['ai']['meta']['has_firing_position'] = False

        entities.trigger_event(_member,
                               'create_timer',
                               time=60,
                               exit_callback=_reset_fire_position)

        return

    _x, _y = movement.get_position(_member)
    _member_positions = set()

    for squad_member_id in squad['members']:
        if squad_member_id == member_id:
            continue

        _member_positions.add(movement.get_position_via_id(squad_member_id))

    _v_p = _best_vantage['position']
    _friendly_fire = False

    for pos in shapes.line((_x, _y), _best_vantage['position']):
        if pos in _member_positions:
            _friendly_fire = True

            break

    if _friendly_fire:
        for n_pos in [(_v_p[0] - 1, _v_p[1] - 1), (_v_p[0], _v_p[1] - 1),
                      (_v_p[0] + 1, _v_p[1] - 1), (_v_p[0] - 1, _v_p[1]),
                      (_v_p[0] + 1, _v_p[1]), (_v_p[0] - 1, _v_p[1] + 1),
                      (_v_p[0], _v_p[1] + 1), (_v_p[0] + 1, _v_p[1] + 1)]:
            if not n_pos in squad['position_map_scores']:
                continue

            _break = False
            for nn_pos in shapes.line((_x, _y), n_pos):
                if nn_pos in _member_positions:
                    _break = True

                    break
            else:
                _v_p = n_pos

                break

            if _break:
                continue

    for coverage_pos in shapes.circle(_v_p[0], _v_p[1], 6):
        if not coverage_pos in squad['position_map_scores']:
            continue

        _c_dist = 15 * (1 - (numbers.distance(coverage_pos, (_x, _y)) / 6.0))

        squad['position_map_scores'][coverage_pos][
            'member_coverage'] += _c_dist

    squad['position_map_scores'][_v_p]['member_coverage'] += 6

    return _v_p
Ejemplo n.º 13
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)]