Example #1
0
def _explosive_tick(entity):
    _direction = movement.get_direction(entity)

    entities.trigger_event(entity, 'push_tank', direction=_direction)

    _x, _y = movement.get_position(entity)
    _distance = numbers.distance((_x, _y), entity['end_position'])
    _starting_target_distance = numbers.distance(entity['start_position'],
                                                 entity['end_position'])

    if _distance <= entity['accuracy'] * 2.5:
        entity['slow_down'] = True

    if entity['slow_down']:
        entity['speed'] = numbers.clip(entity['speed'] * 1.2, 0, 40)

    if entity['speed'] < 40:
        entities.trigger_event(entity,
                               'create_timer',
                               time=int(round(entity['speed'])),
                               name='movement',
                               exit_callback=_explosive_tick)

    else:
        entities.trigger_event(entity, 'activate_explosive')
Example #2
0
def walk_to_position(entity, x, y, astar_map, weight_map, avoid=[], smp=-1):
    _start_position = get_position(entity)
    _target_position = (x, y)

    if _start_position == _target_position:
        return False

    if smp == True or (smp == -1
                       and numbers.distance(_start_position, _target_position)
                       > settings.SMP_MIN_PATH_DISTANCE):
        smp = settings.ALLOW_SMP

    if entity['movement']['path']['destination']:
        if not numbers.distance(entity['movement']['path']['destination'],
                                _target_position):
            return False

    if smp == True:
        pathfinding.astar_mp(_start_position,
                             _target_position,
                             astar_map,
                             weight_map,
                             lambda path: set_path(entity, path),
                             avoid=avoid)
    else:
        entity['movement']['path']['positions'] = pathfinding.astar(
            get_position(entity),
            _target_position,
            astar_map,
            weight_map,
            avoid=avoid)
        entity['movement']['path']['destination'] = _target_position
        entity['movement']['path']['refresh'] = False

    return True
Example #3
0
def update_position_maps(squad):
	_t = time.time()
	
	_coverage_positions = squad['coverage_positions']
	_known_targets = squad['known_targets']
	_known_squads = squad['known_squads']
	_known_targets_left_to_check = _known_targets.copy()
	_score_map = {pos: {'coverage': 0, 'vantage': 100, 'member_coverage': 0, 'danger': 0, 'targets': [], 'owned': False} for pos in _coverage_positions}
	
	for faction_name, squad_id in _known_squads:
		if not squad_id in ai_factions.FACTIONS[faction_name]['squads']:
			continue
		
		_squad = entities.get_entity(ai_factions.FACTIONS[faction_name]['squads'][squad_id])
		_member_set = set(_squad['members'])
		_check_members = _known_targets_left_to_check & _member_set
		_known_targets_left_to_check = _known_targets_left_to_check - _member_set
		
		for target_id in list(_check_members):
			_target_position = movement.get_position_via_id(target_id)
			_closest_member = {'distance': 0, 'member_id': None}
			
			for member_id in squad['members']:
				_member_position = movement.get_position_via_id(member_id)
				_distance = numbers.clip(numbers.distance(_target_position, _member_position), 0, 60)
				
				if not _closest_member['member_id'] or _distance < _closest_member['distance']:
					_closest_member['distance'] = _distance
					_closest_member['member_id'] = member_id
			
			_target_coverage_map = _squad['member_position_maps'][target_id]
			_overlap_positions = _coverage_positions & _target_coverage_map
			_cover_positions = _coverage_positions - _target_coverage_map
			
			if not _closest_member['member_id']:
				logging.warning('Couldn\'t find closest member for target during squad positioning.')
				
				continue
			
			_closest_member_pos = movement.get_position_via_id(_closest_member['member_id'])
			
			for pos in _overlap_positions:
				_distance = numbers.distance(_closest_member_pos, pos)
				
				if _distance < _score_map[pos]['vantage']:
					_score_map[pos]['vantage'] = _distance
				
				#_score_map[pos]['danger'] = 60 - _distance
				_score_map[pos]['targets'].append(target_id)
			
			for pos in _cover_positions:
				_distance = numbers.distance(_closest_member_pos, pos)
								
				if _distance > _score_map[pos]['coverage']:
					_score_map[pos]['coverage'] = _distance
				
				_score_map[pos]['danger'] = 60 - _distance
	
	squad['position_map_scores'] = _score_map
Example #4
0
def _bullet_tick(entity):
	_direction = movement.get_direction(entity)
	
	entities.trigger_event(entity, 'push_tank', direction=_direction)
	
	_x, _y = movement.get_position(entity)
	_distance = numbers.distance((_x, _y), entity['start_position'])
	_starting_target_distance = numbers.distance(entity['start_position'], entity['end_position'])
	
	if _distance > _starting_target_distance + (12 - (entity['speed'] * 2)):
		entities.delete_entity(entity)
Example #5
0
def _bullet_tick(entity):
    _direction = movement.get_direction(entity)

    entities.trigger_event(entity, 'push_tank', direction=_direction)

    _x, _y = movement.get_position(entity)
    _distance = numbers.distance((_x, _y), entity['start_position'])
    _starting_target_distance = numbers.distance(entity['start_position'],
                                                 entity['end_position'])

    if _distance > _starting_target_distance + (12 - (entity['speed'] * 2)):
        entities.delete_entity(entity)
Example #6
0
def logic(entity):
	_last_pos = None
	_stop_here = False
	
	for node_id in entity['node_grid']['path'][:]:
		_node = entity['node_grid']['nodes'][node_id]
		
		if not (_node['node']['x'], _node['node']['y']) == movement.get_position(entity):
			if _stop_here and not (_node['node']['x'], _node['node']['y']) == _last_pos:
				break
		
		_distance = numbers.distance((_node['node']['x'], _node['node']['y']), movement.get_position(entity))
		
		if _node['call_on_touch'] and _distance:
			continue
		
		elif not _distance:
			entity['node_grid']['path'].remove(node_id)
			del entity['node_grid']['nodes'][node_id]
			
			entities.delete_entity_via_id(node_id)
		
		_node['callback']()		
		
		if not _node['passive']:
			_stop_here = True
			_last_pos = (_node['node']['x'], _node['node']['y'])
Example #7
0
def _search_for_target(entity, target_id):
    _nodes = flags.get_flag(entity, 'search_nodes')

    if not _nodes:
        flags.delete_flag(entity, 'search_nodes')

        entities.trigger_event(entity,
                               'target_search_failed',
                               target_id=target_id)

        return

    _node_list = _nodes.keys()
    _node_list.sort()
    _node_x, _node_y = _nodes[_node_list[0]][0]
    _distance = numbers.distance(movement.get_position(entity),
                                 (_node_x, _node_y))

    if _distance <= 15 and life.can_see_position(entity, (_node_x, _node_y)):
        _nodes[_node_list[0]].remove((_node_x, _node_y))

        if not _nodes[_node_list[0]]:
            del _nodes[_node_list[0]]
    else:
        movement.walk_to_position(entity, _node_x, _node_y,
                                  zones.get_active_astar_map(),
                                  zones.get_active_weight_map())
Example #8
0
def get_push_position(squad, member_id):
	_member = entities.get_entity(member_id)
	_best_vantage = {'position': None, 'score': 1000}
	_vision = stats.get_vision(_member)
	_engage_range = int(round(_vision * .75))
	
	for pos in squad['position_map_scores']:
		_scores = squad['position_map_scores'][pos]
		_score = _scores['vantage'] + _scores['member_coverage']
		
		if not _scores['targets'] or _score < 6 or _score > _engage_range:
			continue

		if _score < _best_vantage['score']:
			_best_vantage['score'] = _score
			_best_vantage['position'] = pos[:]
	
	if not _best_vantage['position']:
		_member['ai']['meta']['has_firing_position'] = False
		
		return
	
	_x, _y = movement.get_position(_member)
	
	for coverage_pos in shapes.circle(_best_vantage['position'][0], _best_vantage['position'][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'][_best_vantage['position']]['member_coverage'] += 20
	
	return _best_vantage['position']
Example #9
0
def create_noise(entity,
                 text,
                 volume,
                 owner_can_hear=False,
                 show_on_sight=False,
                 direction=-1000,
                 callback=None,
                 context_callback=None):
    _x, _y = movement.get_position(entity)

    for entity_id in entities.get_entity_group('life'):
        if not owner_can_hear and entity['_id'] == entity_id:
            continue

        _target = entities.get_entity(entity_id)

        if entity['ai']['faction'] == _target['ai']['faction']:
            continue

        #TODO: Hearing stat
        _distance = numbers.distance(movement.get_position(entity),
                                     movement.get_position(_target))
        _accuracy = 1 - numbers.clip(_distance / float(volume), 0, 1)

        entities.trigger_event(_target,
                               'heard_noise',
                               x=_x,
                               y=_y,
                               text=text,
                               direction=direction,
                               show_on_sight=show_on_sight,
                               accuracy=_accuracy,
                               callback=callback,
                               context_callback=context_callback)
Example #10
0
def logic(entity):
    _last_pos = None
    _stop_here = False

    for node_id in entity['node_grid']['path'][:]:
        _node = entity['node_grid']['nodes'][node_id]

        if not (_node['node']['x'],
                _node['node']['y']) == movement.get_position(entity):
            if _stop_here and not (_node['node']['x'],
                                   _node['node']['y']) == _last_pos:
                break

        _distance = numbers.distance((_node['node']['x'], _node['node']['y']),
                                     movement.get_position(entity))

        if _node['call_on_touch'] and _distance:
            continue

        elif not _distance:
            entity['node_grid']['path'].remove(node_id)
            del entity['node_grid']['nodes'][node_id]

            entities.delete_entity_via_id(node_id)

        _node['callback']()

        if not _node['passive']:
            _stop_here = True
            _last_pos = (_node['node']['x'], _node['node']['y'])
Example #11
0
def explosive(entity, x, y, tx, ty, speed, accuracy, damage):
    _entity = _create(x, y, 'Explosive', '.', 0, 'bullet')
    _entity['owner'] = entity['_id']
    _entity['start_position'] = (x, y)
    _entity['end_position'] = (tx, ty)
    _entity['speed'] = speed
    _entity['damage'] = damage
    _toss_distance = numbers.distance(_entity['start_position'],
                                      _entity['end_position'])
    _entity['accuracy'] = numbers.clip(
        random.randint(int(round(accuracy * .25)), accuracy), 0,
        100) - (accuracy * (1 - (_toss_distance / 20.0)))
    _entity['slow_down'] = False
    _direction_mod = random.uniform(-accuracy, accuracy) * 2

    entities.create_event(_entity, 'explode')
    entities.create_event(_entity, 'activate_explosive')
    entities.register_event(_entity, 'explode', frag_grenade_explode)
    entities.register_event(_entity, 'explode', entities.delete_entity)
    entities.register_event(
        _entity, 'activate_explosive', lambda e: entities.trigger_event(
            e,
            'create_timer',
            time=90,
            exit_callback=lambda ee: entities.trigger_event(ee, 'explode')))
    entities.register_event(_entity, 'check_next_position',
                            check_next_position)

    entities.add_entity_to_group(_entity, 'bullets')
    timers.register(_entity)

    entities.trigger_event(_entity,
                           'set_direction',
                           direction=numbers.direction_to(
                               (x, y), (tx, ty)) + _direction_mod)
    entities.trigger_event(_entity,
                           'create_timer',
                           time=speed,
                           enter_callback=_explosive_tick,
                           name='movement')
    entities.register_event(_entity, 'position_changed',
                            lambda e, **kwargs: check_for_collisions(e))

    if not '--no-fx' in sys.argv:
        entities.register_event(
            _entity, 'position_changed',
            lambda e, x, y, **kwargs: _bullet_effects(e, x, y))

    entities.register_event(
        _entity, 'collision_with_entity',
        lambda e, **kwargs: entities.trigger_event(e, 'activate_explosive'))
    entities.register_event(_entity, 'collision_with_entity',
                            lambda e, **kwargs: _explosive_stop_dumb_hack(e))
    entities.register_event(_entity, 'collision_with_solid',
                            lambda e: timers.stop_timer(e, 'movement'))
    entities.register_event(_entity, 'collision_with_solid',
                            _explosive_stop_dumb_hack)
    entities.register_event(
        _entity, 'collision_with_solid',
        lambda e: entities.trigger_event(e, 'activate_explosive'))
Example #12
0
def _locate_npc_message(goal, member_id):
	_target_id = goal['target_id']
	_member = entities.get_entity(member_id)
	_mission = entities.get_entity(goal['mission_id'])
		
	if not _target_id in _member['ai']['life_memory'] or not _member['ai']['life_memory'][_target_id]['last_seen_at']:
		goal['message'] = 'Gather location info on target.'
		
		return
	
	if _member['ai']['life_memory'][_target_id]['is_dead']:
		goal['message'] = 'Confirmed: Target is dead.'
		
		entities.trigger_event(_member, 'complete_goal', mission_id=goal['mission_id'], goal_id=goal['_id'])
	
	elif _member['ai']['life_memory'][_target_id]['can_see']:
		goal['message'] = 'Target in line of sight.'
		
		entities.trigger_event(_member, 'complete_goal', mission_id=goal['mission_id'], goal_id=goal['_id'])
	
	elif _member['ai']['life_memory'][_target_id]['last_seen_at']:
		_direction = numbers.direction_to(movement.get_position(_member), _member['ai']['life_memory'][_target_id]['last_seen_at'])
		_distance = numbers.distance(movement.get_position(_member), _member['ai']['life_memory'][_target_id]['last_seen_at'])
		_real_direction = conversions.get_real_direction(_direction)
		_real_distance = conversions.get_real_distance(_distance)
		
		goal['message'] = 'Target last seen %s meters to the %s' % (_real_distance, _real_direction)
	
	_member['ai']['life_memory'][_target_id]['mission_related'] = True
Example #13
0
def create_noise(entity, text, volume, owner_can_hear=False, show_on_sight=False, direction=-1000, callback=None, context_callback=None):
	_x, _y = movement.get_position(entity)
	
	for entity_id in entities.get_entity_group('life'):
		if not owner_can_hear and entity['_id'] == entity_id:
			continue
		
		_target = entities.get_entity(entity_id)
		
		if entity['ai']['faction'] == _target['ai']['faction']:
			continue
		
		#TODO: Hearing stat
		_distance = numbers.distance(movement.get_position(entity), movement.get_position(_target))
		_accuracy = 1 - numbers.clip(_distance / float(volume), 0, 1)
		
		entities.trigger_event(_target,
		                       'heard_noise',
		                       x=_x,
		                       y=_y,
		                       text=text,
		                       direction=direction,
		                       show_on_sight=show_on_sight,
		                       accuracy=_accuracy,
		                       callback=callback,
		                       context_callback=context_callback)
Example #14
0
def explosive(entity, x, y, tx, ty, speed, accuracy, damage):
	_entity = _create(x, y, 'Explosive', '.', 0, 'bullet')
	_entity['owner'] = entity['_id']
	_entity['start_position'] = (x, y)
	_entity['end_position'] = (tx, ty)
	_entity['speed'] = speed
	_entity['damage'] = damage
	_toss_distance = numbers.distance(_entity['start_position'], _entity['end_position'])
	_entity['accuracy'] = numbers.clip(random.randint(int(round(accuracy * .25)), accuracy), 0, 100) - (accuracy * (1 - (_toss_distance / 20.0)))
	_entity['slow_down'] = False
	_direction_mod = random.uniform(-accuracy, accuracy) * 2
	
	entities.create_event(_entity, 'explode')
	entities.create_event(_entity, 'activate_explosive')
	entities.register_event(_entity, 'explode', frag_grenade_explode)
	entities.register_event(_entity, 'explode', entities.delete_entity)
	entities.register_event(_entity, 'activate_explosive', lambda e: entities.trigger_event(e, 'create_timer', time=90, exit_callback=lambda ee: entities.trigger_event(ee, 'explode')))
	entities.register_event(_entity, 'check_next_position', check_next_position)
	
	entities.add_entity_to_group(_entity, 'bullets')
	timers.register(_entity)
	
	entities.trigger_event(_entity, 'set_direction', direction=numbers.direction_to((x, y), (tx, ty)) + _direction_mod)
	entities.trigger_event(_entity, 'create_timer', time=speed, enter_callback=_explosive_tick, name='movement')
	entities.register_event(_entity, 'position_changed', lambda e, **kwargs: check_for_collisions(e))
	
	if not '--no-fx' in sys.argv:
		entities.register_event(_entity, 'position_changed', lambda e, x, y, **kwargs: _bullet_effects(e, x, y))
	
	entities.register_event(_entity, 'collision_with_entity', lambda e, **kwargs: entities.trigger_event(e, 'activate_explosive'))
	entities.register_event(_entity, 'collision_with_entity', lambda e, **kwargs: _explosive_stop_dumb_hack(e))
	entities.register_event(_entity, 'collision_with_solid', lambda e: timers.stop_timer(e, 'movement'))
	entities.register_event(_entity, 'collision_with_solid', _explosive_stop_dumb_hack)
	entities.register_event(_entity, 'collision_with_solid', lambda e: entities.trigger_event(e, 'activate_explosive'))
Example #15
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 #16
0
def create_bases(ownable_plots):
	_width = constants.STRAT_MAP_WIDTH/constants.MAP_CELL_SPACE
	_height = constants.STRAT_MAP_HEIGHT/constants.MAP_CELL_SPACE
	_bases = []
	
	for i in range(6):
		while 1:
			_new_base_pos = random.choice(ownable_plots)
			_min_distance = 0
			
			for base_pos in _bases:
				_distance = numbers.distance(_new_base_pos, base_pos)
				
				if _distance <= 2:
					break
				
				_min_distance = _distance
			
			else:
				if _min_distance >= 7:
					continue
				
				_bases.append(_new_base_pos)
				ownable_plots.remove(_new_base_pos)
				
				break
	
	for b_x, b_y in _bases:
		world_strategy.MAP['grid'][b_x, b_y]['is_ownable'] = True
Example #17
0
def add_plot_pole(x, y, radius, solids, cell_split=3.0, debug=False):
	global NODE_SET_ID

	_node_set = set()
	_min_x = 999999999
	_max_x = 0
	_min_y = 999999999
	_max_y = 0

	for node_pos in list(UNCLAIMED_NODES):
		if numbers.distance((x, y), node_pos) > radius:
			continue
		
		if node_pos[0] < _min_x:
			_min_x = node_pos[0]
		
		if node_pos[0] > _max_x:
			_max_x = node_pos[0]
		
		if node_pos[1] < _min_y:
			_min_y = node_pos[1]
		
		if node_pos[1] > _max_y:
			_max_y = node_pos[1]

		_node_set.add(node_pos)
	
	_map = numpy.ones(((_max_y-_min_y)+1, (_max_x-_min_x)+1))
	
	for _x, _y in solids:
		if _x >= _max_x or _x <= _min_x or _y >= _max_y or _y <= _min_y:
			continue
		
		_map[int(round((_y-_min_y))), int(round((_x-_min_x)))] = -2

	NODE_SETS[NODE_SET_ID] = {'owner': None,
	                          'nodes': _node_set,
	                          'center': (x, y),
	                          'astar_map': _map,
	                          'min_x': _min_x,
	                          'min_y': _min_y,
	                          'cell_split': float(cell_split),
	                          'weight_map': numpy.ones(((_max_y-_min_y)+1, (_max_x-_min_x)+1), dtype=numpy.int16)}
	NODE_SET_ID += 1
	
	if debug:
		for y in range(_max_y-_min_y):
			for x in range(_max_x-_min_x):
				_val = int(round(_map[y, x]))
				
				if _val == -2:
					print '#',
				elif _val == 1:
					print '.',
			
			print

	return NODE_SET_ID-1
Example #18
0
def handle_keyboard_input():
    if controls.get_input_char_pressed('\t'):
        if settings.TICK_MODE == 'strategy':
            if ui_panel.ACTIVE_MENU:
                ui_panel.close()
            else:
                ui_panel.show_inventory(entity)

        else:
            _x, _y = movement.get_position(entity)

            camera.set_pos(_x - constants.MAP_VIEW_WIDTH / 2,
                           _y - constants.MAP_VIEW_HEIGHT / 2)

    if controls.get_input_char_pressed('O'):
        settings.toggle_show_node_grid()

    elif controls.get_input_char_pressed('o'):
        settings.toggle_observer_mode()

    if controls.get_input_char_pressed('d'):
        _mx, _my = ui_cursor.get_map_position()

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

            if not numbers.distance(
                (_mx, _my), movement.get_position(_entity)):
                _x, _y = ui_cursor.get_screen_position()
                _menu = ui_menu.create(_x, _y, title='Debug')
                ui_menu.add_selectable(_menu, 'Show Metas',
                                       lambda: _show_metas(_entity))
                ui_menu.add_selectable(
                    _menu, 'Kill',
                    lambda: entities.trigger_event(_entity, 'kill'))
                ui_menu.add_selectable(_menu, 'Overwatch',
                                       lambda: ai_debugger.register(_entity))

                break

    if controls.get_input_char_pressed('l'):
        _x, _y = ui_cursor.get_screen_position()
        _mx, _my = ui_cursor.get_map_position()
        _weight = zones.get_active_weight_map()[_my, _mx]
        _menu = ui_menu.create(_x, _y, title='Tile Info')

        ui_menu.add_selectable(
            _menu, 'Warp', lambda: entities.trigger_event(
                entity, 'set_position', x=_mx, y=_my))
        ui_menu.add_selectable(
            _menu, 'Light', lambda: effects.light(_mx,
                                                  _my,
                                                  15,
                                                  r=random.uniform(1.0, 1.5),
                                                  g=random.uniform(1.0, 1.5),
                                                  light_map='static_lighting'))
        ui_menu.add_selectable(_menu, 'Weight: %s' % _weight, lambda: _)
Example #19
0
def _bullet_effects(entity, x, y):
	_distance = numbers.distance((x, y), entity['start_position'])
	_target_distance = numbers.distance((x, y), entity['end_position']) + numbers.clip(10 - _distance, 0, 10) 
	_x, _y = movement.get_position(entity)
	_mod = (0.6 - (_distance / 35.0)) + random.uniform(-.1, .1)
	_alpha = numbers.clip(_mod, 0, 1)
	_crash_dist = 60 - (entity['speed'] * 2)
	
	if _alpha > 0:
		effects.vapor(x, y, start_alpha=_alpha)
	
	if _target_distance < 30:
		_size = int(round(2 * (1 - (1 * numbers.clip(numbers.clip(_target_distance, 0, 100)/60.0, 0, 1))))) + random.randint(1, 2)
		
		if _distance > _crash_dist:
			_size = int(round(_size * (_crash_dist/float(_distance))))
		
		if _size > 1:
			effects.light(_x, _y, _size, r=1.3, g=1.3, b=1.3)
Example #20
0
def find_cover(entity):
	_squad = entities.get_entity(ai_factions.FACTIONS[entity['ai']['faction']]['squads'][entity['ai']['squad']])
	_cover_position = ai_squad_director.get_cover_position(_squad, entity['_id'])
	
	if not _cover_position or not numbers.distance(movement.get_position(entity), _cover_position):
		entities.trigger_event(entity, 'finish_turn')
	
		return
	
	movement.walk_to_position(entity, _cover_position[0], _cover_position[1], zones.get_active_astar_map(), zones.get_active_weight_map())
Example #21
0
def _explosive_tick(entity):
	_direction = movement.get_direction(entity)
	
	entities.trigger_event(entity, 'push_tank', direction=_direction)
	
	_x, _y = movement.get_position(entity)
	_distance = numbers.distance((_x, _y), entity['end_position'])
	_starting_target_distance = numbers.distance(entity['start_position'], entity['end_position'])
	
	if _distance <= entity['accuracy'] * 2.5:
		entity['slow_down'] = True
	
	if entity['slow_down']:
		entity['speed'] = numbers.clip(entity['speed'] * 1.2, 0, 40)	
	
	if entity['speed'] < 40:
		entities.trigger_event(entity, 'create_timer', time=int(round(entity['speed'])), name='movement', exit_callback=_explosive_tick)
	
	else:
		entities.trigger_event(entity, 'activate_explosive')
Example #22
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 #23
0
def get_cover_position(squad, member_id):
    _member = entities.get_entity(member_id)
    _best_coverage = {'position': None, 'score': 0}
    _inside = zones.get_active_inside_positions()

    if _member['movement']['path']['destination']:
        _hide_pos = _member['movement']['path']['destination']

    else:
        _hide_pos = movement.get_position(_member)

    if _hide_pos in squad['position_map_scores']:
        _scores = squad['position_map_scores'][_hide_pos]
        _score = _scores['coverage'] + _scores['member_coverage']

        if not _scores['targets'] and _score > 0:
            return _hide_pos

    for pos in squad['position_map_scores']:
        _scores = squad['position_map_scores'][pos]
        #TODO: Add or subtract here? Subtraction will make some NPCs run away from teammates
        _score = _scores['coverage'] + _scores['member_coverage']

        if not pos in _inside:
            continue

        if _scores['targets'] or _score <= 0:
            continue

        if _score > _best_coverage['score']:
            _best_coverage['score'] = _score
            _best_coverage['position'] = pos[:]

    if not _best_coverage['position']:
        #print 'no good coverage position'
        return

    _x, _y = movement.get_position(_member)

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

        _c_dist = 10 * (1 - (numbers.distance(coverage_pos, (_x, _y)) / 3.0))

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

    squad['position_map_scores'][
        _best_coverage['position']]['member_coverage'] += 15

    return _best_coverage['position']
Example #24
0
def get_nearest_entity_in_list(entity, entity_list):
	_nearest_entity = {'entity': None, 'distance': 0}
	
	for entity_id in entity_list:
		_entity = entities.get_entity(entity_id)
		_distance = numbers.distance(movement.get_position(entity), movement.get_position(_entity))
		
		if not _nearest_entity['entity'] or _distance < _nearest_entity['distance']:
			_nearest_entity['entity'] = _entity
			_nearest_entity['distance'] = _distance
	
	return _nearest_entity['entity']
Example #25
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 #26
0
def create_shoot_menu(entity, target_id):
	_tx, _ty = movement.get_position_via_id(target_id)
	_weapon = entities.get_entity(items.get_items_in_holder(entity, 'weapon')[0])
	_menu = ui_menu.create(_tx-camera.X+2, _ty-camera.Y-4, title='Shoot')
	_accuracy = stats.get_accuracy(entity, _weapon['_id'])
	_x, _y = movement.get_position(entity)
	_direction = numbers.direction_to((_x, _y), (_tx, _ty))
	_final_direction = _direction + (_accuracy * numbers.distance((_x, _y), (_tx, _ty)))
	_spray_accuracy = (100 * (_direction / float(_final_direction)))
	
	entities.trigger_event(_weapon, 'get_actions', menu=_menu)
	ui_menu.add_selectable(_menu, 'Spray (Acc: %.2d)' % _spray_accuracy, lambda: entities.trigger_event(entity, 'shoot', target_id=target_id) and settings.set_tick_mode('normal'))
	ui_menu.add_selectable(_menu, 'Snipe (Acc: %s)' % _accuracy, lambda: _)
Example #27
0
def _bullet_effects(entity, x, y):
    _distance = numbers.distance((x, y), entity['start_position'])
    _target_distance = numbers.distance(
        (x, y), entity['end_position']) + numbers.clip(10 - _distance, 0, 10)
    _x, _y = movement.get_position(entity)
    _mod = (0.6 - (_distance / 35.0)) + random.uniform(-.1, .1)
    _alpha = numbers.clip(_mod, 0, 1)
    _crash_dist = 60 - (entity['speed'] * 2)

    if _alpha > 0:
        effects.vapor(x, y, start_alpha=_alpha)

    if _target_distance < 30:
        _size = int(
            round(2 * (1 - (1 * numbers.clip(
                numbers.clip(_target_distance, 0, 100) / 60.0, 0, 1))))
        ) + random.randint(1, 2)

        if _distance > _crash_dist:
            _size = int(round(_size * (_crash_dist / float(_distance))))

        if _size > 1:
            effects.light(_x, _y, _size, r=1.3, g=1.3, b=1.3)
Example #28
0
def get_cover_position(squad, member_id):
	_member = entities.get_entity(member_id)
	_best_coverage = {'position': None, 'score': 0}
	_inside = zones.get_active_inside_positions()
	
	if _member['movement']['path']['destination']:
		_hide_pos = _member['movement']['path']['destination']
	
	else:
		_hide_pos = movement.get_position(_member)
	
	if _hide_pos in squad['position_map_scores']:
		_scores = squad['position_map_scores'][_hide_pos]
		_score = _scores['coverage'] + _scores['member_coverage']
		
		if not _scores['targets'] and _score > 0:
			return _hide_pos
	
	for pos in squad['position_map_scores']:
		_scores = squad['position_map_scores'][pos]
		#TODO: Add or subtract here? Subtraction will make some NPCs run away from teammates
		_score = _scores['coverage'] + _scores['member_coverage']
		
		if not pos in _inside:
			continue
		
		if _scores['targets'] or _score <= 0:
			continue

		if _score > _best_coverage['score']:
			_best_coverage['score'] = _score
			_best_coverage['position'] = pos[:]
	
	if not _best_coverage['position']:
		#print 'no good coverage position'
		return
	
	_x, _y = movement.get_position(_member)
	
	for coverage_pos in shapes.circle(_best_coverage['position'][0], _best_coverage['position'][1], 6):
		if not coverage_pos in squad['position_map_scores']:
			continue
		
		_c_dist = 10 * (1 - (numbers.distance(coverage_pos, (_x, _y)) / 3.0))
		
		squad['position_map_scores'][coverage_pos]['member_coverage'] += _c_dist
	
	squad['position_map_scores'][_best_coverage['position']]['member_coverage'] += 15
	
	return _best_coverage['position']
Example #29
0
def get_nearest_entity_in_list(entity, entity_list):
    _nearest_entity = {'entity': None, 'distance': 0}

    for entity_id in entity_list:
        _entity = entities.get_entity(entity_id)
        _distance = numbers.distance(movement.get_position(entity),
                                     movement.get_position(_entity))

        if not _nearest_entity[
                'entity'] or _distance < _nearest_entity['distance']:
            _nearest_entity['entity'] = _entity
            _nearest_entity['distance'] = _distance

    return _nearest_entity['entity']
Example #30
0
def walk_to_position(entity, x, y, astar_map, weight_map, avoid=[], smp=-1):
	_start_position = get_position(entity)
	_target_position = (x, y)
	
	if _start_position == _target_position:
		return False
	
	if smp == True or (smp == -1 and numbers.distance(_start_position, _target_position) > settings.SMP_MIN_PATH_DISTANCE):
		smp = settings.ALLOW_SMP
	
	if entity['movement']['path']['destination']:
		if not numbers.distance(entity['movement']['path']['destination'], _target_position):
			return False
	
	if smp == True:
		pathfinding.astar_mp(_start_position, _target_position, astar_map, weight_map,
		                     lambda path: set_path(entity, path), avoid=avoid)
	else:
		entity['movement']['path']['positions'] = pathfinding.astar(get_position(entity), _target_position, astar_map, weight_map, avoid=avoid)
		entity['movement']['path']['destination'] = _target_position
		entity['movement']['path']['refresh'] = False
	
	return True
Example #31
0
def generate_shadow_map(width, height, solids, trees, inside):
    global SHADOWS

    SHADOWS = display.create_shader(width, height)
    SHADOWS[0] += 1
    SHADOWS[1] += 1
    SHADOWS[2] += 1

    _taken = set()

    for x, y in solids:
        if (x, y) in trees:
            continue

        for y1 in range(-3, 4):
            for x1 in range(-3, 4):
                if (x + x1,
                        y + y1) in solids or (x + x1, y + y1) in inside or (
                            x + x1, y + y1
                        ) in _taken or x + x1 >= width or y + y1 >= height:
                    continue

                _shadow = numbers.clip(
                    numbers.distance((x, y),
                                     (x + x1, y + y1)) / 5.0, .25, .6) + .25

                if _shadow < SHADOWS[0][y + y1][x + x1]:
                    SHADOWS[0][y + y1][x + x1] = _shadow
                    SHADOWS[1][y + y1][x + x1] = _shadow
                    SHADOWS[2][y + y1][x + x1] = _shadow

    _taken = set()

    for _x, _y in trees.keys():
        _tree_size = float(trees[_x, _y])

        for x, y in shapes.circle(_x, _y, int(_tree_size)):
            if (x, y) in solids or x >= width or y >= height or x < 0 or y < 0:
                continue

            _distance = numbers.float_distance((x, y), (_x, _y)) * 1.25
            _shadow = numbers.clip(1 - ((_distance / _tree_size) + .25), .1,
                                   .9)

            SHADOWS[0][y][x] = numbers.clip(SHADOWS[0][y][x] - _shadow, .45, 1)
            SHADOWS[1][y][x] = numbers.clip(SHADOWS[1][y][x] - _shadow, .45, 1)
            SHADOWS[2][y][x] = numbers.clip(SHADOWS[2][y][x] - _shadow, .45, 1)

    return SHADOWS
Example #32
0
def find_cover(entity):
    _squad = entities.get_entity(ai_factions.FACTIONS[entity['ai']['faction']]
                                 ['squads'][entity['ai']['squad']])
    _cover_position = ai_squad_director.get_cover_position(
        _squad, entity['_id'])

    if not _cover_position or not numbers.distance(
            movement.get_position(entity), _cover_position):
        entities.trigger_event(entity, 'finish_turn')

        return

    movement.walk_to_position(entity, _cover_position[0], _cover_position[1],
                              zones.get_active_astar_map(),
                              zones.get_active_weight_map())
Example #33
0
def frag_grenade_explode(entity):
	_x, _y = movement.get_position(entity)
	_damage = entity['damage']
	_size = 3 * int(round((_damage * .01)))
	
	effects.explosion(_x, _y, _size)
	
	for entity_id in entities.get_entity_group('life'):
		_entity = entities.get_entity(entity_id)
		_distance = numbers.distance((_x, _y), movement.get_position(_entity))
		
		if _distance - 1 > _size or not life.can_see_position(_entity, (_x, _y)):
			continue
		
		entities.trigger_event(_entity, 'hit', projectile=entity, damage_mod=1 - ((_distance - 1) / float(_size)))
Example #34
0
def _get_item(entity, item_id, hold=False, weight=None):
	_item = entities.get_entity(item_id)
	_x, _y = movement.get_position(_item)
	_distance = numbers.distance(movement.get_position(entity), (_x, _y))
	
	if weight:
		ai.set_meta_weight(entity, weight, 10*numbers.clip(_distance/30.0, 0, 1))
	
	if _distance:
		movement.walk_to_position(entity, _x, _y, zones.get_active_astar_map(), zones.get_active_weight_map(), smp=True)
	
	else:
		if hold:
			life.get_and_hold_item(entity, item_id)
		else:
			life.get_and_store_item(entity, item_id)
Example #35
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 #36
0
def draw_raid_info(squad_id, camp_id):
    _camp = world_strategy.MAP['grid'][camp_id]
    _squad = entities.get_entity(squad_id)
    _travel_distance = numbers.distance(movement.get_position_via_id(squad_id),
                                        camp_id)
    _highest_speed = 0
    _cost = ai_squads.get_attack_cost(_squad, camp_id)

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

        if _speed > _highest_speed:
            _highest_speed = _speed

    _travel_time = _travel_distance * (_highest_speed * 80)
    _time_string = '%s hours %s minutes' % (_travel_time / 60, _travel_time -
                                            ((_travel_time / 60) * 60))
    _info = 'Right Click Camp to Confirm Order, ESC to cancel'

    if time.time() % 1 >= .5:
        _info_color = (200, 0, 0)

    else:
        _info_color = (200, 80, 80)

    display.write_string('ui_bar',
                         (constants.WINDOW_WIDTH / 2) - (len(_info) / 2),
                         0,
                         _info,
                         fore_color=_info_color)

    display.write_string('ui_bar',
                         1,
                         1,
                         'Raid Order',
                         fore_color=(200, 50, 70))

    flavor_print(1, 3, [('Risk: ', 'Low', constants.STATUS_GOOD),
                        ('Cost: $ ', '%i' % _cost, constants.STATUS_GOOD),
                        ('Supplies needed: ', '%i' % 12, constants.STATUS_OK),
                        ('Travel time: ', _time_string, constants.STATUS_OK)])

    flavor_print(35, 3, [('Test value: ', 'Low', constants.STATUS_GOOD)])
Example #37
0
def generate_shadow_map(width, height, solids, trees, inside):
	global SHADOWS
	
	SHADOWS = display.create_shader(width, height)
	SHADOWS[0] += 1
	SHADOWS[1] += 1
	SHADOWS[2] += 1
	
	_taken = set()
	
	for x, y in solids:
		if (x, y) in trees:
			continue
		
		for y1 in range(-3, 4):
			for x1 in range(-3, 4):
				if (x+x1, y+y1) in solids or (x+x1, y+y1) in inside or (x+x1, y+y1) in _taken or x+x1 >= width or y+y1 >= height:
					continue
				
				_shadow = numbers.clip(numbers.distance((x, y), (x+x1, y+y1))/5.0, .25, .6) + .25
			
				if _shadow < SHADOWS[0][y+y1][x+x1]:
					SHADOWS[0][y+y1][x+x1] = _shadow
					SHADOWS[1][y+y1][x+x1] = _shadow
					SHADOWS[2][y+y1][x+x1] = _shadow
	
	_taken = set()
	
	for _x, _y in trees.keys():
		_tree_size = float(trees[_x, _y])
		
		for x, y in shapes.circle(_x, _y, int(_tree_size)):
			if (x, y) in solids or x >= width or y >= height or x < 0 or y <0:
				continue
			
			_distance = numbers.float_distance((x, y), (_x, _y))*1.25
			_shadow = numbers.clip(1 - ((_distance / _tree_size) + .25), .1, .9)
			
			SHADOWS[0][y][x] = numbers.clip(SHADOWS[0][y][x]-_shadow, .45, 1)
			SHADOWS[1][y][x] = numbers.clip(SHADOWS[1][y][x]-_shadow, .45, 1)
			SHADOWS[2][y][x] = numbers.clip(SHADOWS[2][y][x]-_shadow, .45, 1)
	
	return SHADOWS
Example #38
0
def frag_grenade_explode(entity):
    _x, _y = movement.get_position(entity)
    _damage = entity['damage']
    _size = 3 * int(round((_damage * .01)))

    effects.explosion(_x, _y, _size)

    for entity_id in entities.get_entity_group('life'):
        _entity = entities.get_entity(entity_id)
        _distance = numbers.distance((_x, _y), movement.get_position(_entity))

        if _distance - 1 > _size or not life.can_see_position(
                _entity, (_x, _y)):
            continue

        entities.trigger_event(_entity,
                               'hit',
                               projectile=entity,
                               damage_mod=1 - ((_distance - 1) / float(_size)))
Example #39
0
def handle_keyboard_input():
	if controls.get_input_char_pressed('\t'):
		if settings.TICK_MODE == 'strategy':
			if ui_panel.ACTIVE_MENU:
				ui_panel.close()
			else:
				ui_panel.show_inventory(entity)
		
		else:
			_x, _y = movement.get_position(entity)
			
			camera.set_pos(_x - constants.MAP_VIEW_WIDTH/2, _y - constants.MAP_VIEW_HEIGHT/2)
	
	if controls.get_input_char_pressed('O'):
		settings.toggle_show_node_grid()
	
	elif controls.get_input_char_pressed('o'):
		settings.toggle_observer_mode()
	
	if controls.get_input_char_pressed('d'):
		_mx, _my = ui_cursor.get_map_position()
		
		for entity_id in entities.get_entity_group('life'):
			_entity = entities.get_entity(entity_id)
			
			if not numbers.distance((_mx, _my), movement.get_position(_entity)):
				_x, _y = ui_cursor.get_screen_position()
				_menu = ui_menu.create(_x, _y, title='Debug')
				ui_menu.add_selectable(_menu, 'Show Metas', lambda: _show_metas(_entity))
				ui_menu.add_selectable(_menu, 'Kill', lambda: entities.trigger_event(_entity, 'kill'))
				ui_menu.add_selectable(_menu, 'Overwatch', lambda: ai_debugger.register(_entity))
				
				break
	
	if controls.get_input_char_pressed('l'):
		_x, _y = ui_cursor.get_screen_position()
		_mx, _my = ui_cursor.get_map_position()
		_weight = zones.get_active_weight_map()[_my, _mx]
		_menu = ui_menu.create(_x, _y, title='Tile Info')
		
		ui_menu.add_selectable(_menu, 'Warp', lambda: entities.trigger_event(entity, 'set_position', x=_mx, y=_my))
		ui_menu.add_selectable(_menu, 'Light', lambda: effects.light(_mx, _my, 15, r=random.uniform(1.0, 1.5), g=random.uniform(1.0, 1.5), light_map='static_lighting'))
		ui_menu.add_selectable(_menu, 'Weight: %s' % _weight, lambda: _)
Example #40
0
def create_shoot_menu(entity, target_id):
    _tx, _ty = movement.get_position_via_id(target_id)
    _weapon = entities.get_entity(
        items.get_items_in_holder(entity, 'weapon')[0])
    _menu = ui_menu.create(_tx - camera.X + 2,
                           _ty - camera.Y - 4,
                           title='Shoot')
    _accuracy = stats.get_accuracy(entity, _weapon['_id'])
    _x, _y = movement.get_position(entity)
    _direction = numbers.direction_to((_x, _y), (_tx, _ty))
    _final_direction = _direction + (_accuracy * numbers.distance((_x, _y),
                                                                  (_tx, _ty)))
    _spray_accuracy = (100 * (_direction / float(_final_direction)))

    entities.trigger_event(_weapon, 'get_actions', menu=_menu)
    ui_menu.add_selectable(
        _menu, 'Spray (Acc: %.2d)' % _spray_accuracy,
        lambda: entities.trigger_event(entity, 'shoot', target_id=target_id
                                       ) and settings.set_tick_mode('normal'))
    ui_menu.add_selectable(_menu, 'Snipe (Acc: %s)' % _accuracy, lambda: _)
Example #41
0
def _locate_npc_message(goal, member_id):
    _target_id = goal['target_id']
    _member = entities.get_entity(member_id)
    _mission = entities.get_entity(goal['mission_id'])

    if not _target_id in _member['ai']['life_memory'] or not _member['ai'][
            'life_memory'][_target_id]['last_seen_at']:
        goal['message'] = 'Gather location info on target.'

        return

    if _member['ai']['life_memory'][_target_id]['is_dead']:
        goal['message'] = 'Confirmed: Target is dead.'

        entities.trigger_event(_member,
                               'complete_goal',
                               mission_id=goal['mission_id'],
                               goal_id=goal['_id'])

    elif _member['ai']['life_memory'][_target_id]['can_see']:
        goal['message'] = 'Target in line of sight.'

        entities.trigger_event(_member,
                               'complete_goal',
                               mission_id=goal['mission_id'],
                               goal_id=goal['_id'])

    elif _member['ai']['life_memory'][_target_id]['last_seen_at']:
        _direction = numbers.direction_to(
            movement.get_position(_member),
            _member['ai']['life_memory'][_target_id]['last_seen_at'])
        _distance = numbers.distance(
            movement.get_position(_member),
            _member['ai']['life_memory'][_target_id]['last_seen_at'])
        _real_direction = conversions.get_real_direction(_direction)
        _real_distance = conversions.get_real_distance(_distance)

        goal['message'] = 'Target last seen %s meters to the %s' % (
            _real_distance, _real_direction)

    _member['ai']['life_memory'][_target_id]['mission_related'] = True
Example #42
0
def draw_raid_info(squad_id, camp_id):
    _camp = world_strategy.MAP["grid"][camp_id]
    _squad = entities.get_entity(squad_id)
    _travel_distance = numbers.distance(movement.get_position_via_id(squad_id), camp_id)
    _highest_speed = 0
    _cost = ai_squads.get_attack_cost(_squad, camp_id)

    for member_id in _squad["members"]:
        _member = entities.get_entity(member_id)
        _speed = movement.get_move_cost(_member)

        if _speed > _highest_speed:
            _highest_speed = _speed

    _travel_time = _travel_distance * (_highest_speed * 80)
    _time_string = "%s hours %s minutes" % (_travel_time / 60, _travel_time - ((_travel_time / 60) * 60))
    _info = "Right Click Camp to Confirm Order, ESC to cancel"

    if time.time() % 1 >= 0.5:
        _info_color = (200, 0, 0)

    else:
        _info_color = (200, 80, 80)

    display.write_string("ui_bar", (constants.WINDOW_WIDTH / 2) - (len(_info) / 2), 0, _info, fore_color=_info_color)

    display.write_string("ui_bar", 1, 1, "Raid Order", fore_color=(200, 50, 70))

    flavor_print(
        1,
        3,
        [
            ("Risk: ", "Low", constants.STATUS_GOOD),
            ("Cost: $ ", "%i" % _cost, constants.STATUS_GOOD),
            ("Supplies needed: ", "%i" % 12, constants.STATUS_OK),
            ("Travel time: ", _time_string, constants.STATUS_OK),
        ],
    )

    flavor_print(35, 3, [("Test value: ", "Low", constants.STATUS_GOOD)])
Example #43
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 #44
0
def _search_for_target(entity, target_id):
	_nodes = flags.get_flag(entity, 'search_nodes')
	
	if not _nodes:
		flags.delete_flag(entity, 'search_nodes')
		
		entities.trigger_event(entity, 'target_search_failed', target_id=target_id)
		
		return
	
	_node_list = _nodes.keys()
	_node_list.sort()	
	_node_x, _node_y = _nodes[_node_list[0]][0]
	_distance = numbers.distance(movement.get_position(entity), (_node_x, _node_y))
	
	if _distance <= 15 and life.can_see_position(entity, (_node_x, _node_y)):
		_nodes[_node_list[0]].remove((_node_x, _node_y))
		
		if not _nodes[_node_list[0]]:
			del _nodes[_node_list[0]]
	else:
		movement.walk_to_position(entity, _node_x, _node_y, zones.get_active_astar_map(), zones.get_active_weight_map())
Example #45
0
def _get_item(entity, item_id, hold=False, weight=None):
    _item = entities.get_entity(item_id)
    _x, _y = movement.get_position(_item)
    _distance = numbers.distance(movement.get_position(entity), (_x, _y))

    if weight:
        ai.set_meta_weight(entity, weight,
                           10 * numbers.clip(_distance / 30.0, 0, 1))

    if _distance:
        movement.walk_to_position(entity,
                                  _x,
                                  _y,
                                  zones.get_active_astar_map(),
                                  zones.get_active_weight_map(),
                                  smp=True)

    else:
        if hold:
            life.get_and_hold_item(entity, item_id)
        else:
            life.get_and_store_item(entity, item_id)
Example #46
0
def get_push_position(squad, member_id):
    _member = entities.get_entity(member_id)
    _best_vantage = {'position': None, 'score': 1000}
    _vision = stats.get_vision(_member)
    _engage_range = int(round(_vision * .75))

    for pos in squad['position_map_scores']:
        _scores = squad['position_map_scores'][pos]
        _score = _scores['vantage'] + _scores['member_coverage']

        if not _scores['targets'] or _score < 6 or _score > _engage_range:
            continue

        if _score < _best_vantage['score']:
            _best_vantage['score'] = _score
            _best_vantage['position'] = pos[:]

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

        return

    _x, _y = movement.get_position(_member)

    for coverage_pos in shapes.circle(_best_vantage['position'][0],
                                      _best_vantage['position'][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'][
        _best_vantage['position']]['member_coverage'] += 20

    return _best_vantage['position']
Example #47
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 #48
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
Example #49
0
def update_position_maps(squad):
    _t = time.time()

    _coverage_positions = squad['coverage_positions']
    _known_targets = squad['known_targets']
    _known_squads = squad['known_squads']
    _known_targets_left_to_check = _known_targets.copy()
    _score_map = {
        pos: {
            'coverage': 0,
            'vantage': 100,
            'member_coverage': 0,
            'danger': 0,
            'targets': [],
            'owned': False
        }
        for pos in _coverage_positions
    }

    for faction_name, squad_id in _known_squads:
        if not squad_id in ai_factions.FACTIONS[faction_name]['squads']:
            continue

        _squad = entities.get_entity(
            ai_factions.FACTIONS[faction_name]['squads'][squad_id])
        _member_set = set(_squad['members'])
        _check_members = _known_targets_left_to_check & _member_set
        _known_targets_left_to_check = _known_targets_left_to_check - _member_set

        for target_id in list(_check_members):
            _target_position = movement.get_position_via_id(target_id)
            _closest_member = {'distance': 0, 'member_id': None}

            for member_id in squad['members']:
                _member_position = movement.get_position_via_id(member_id)
                _distance = numbers.clip(
                    numbers.distance(_target_position, _member_position), 0,
                    60)

                if not _closest_member[
                        'member_id'] or _distance < _closest_member['distance']:
                    _closest_member['distance'] = _distance
                    _closest_member['member_id'] = member_id

            _target_coverage_map = _squad['member_position_maps'][target_id]
            _overlap_positions = _coverage_positions & _target_coverage_map
            _cover_positions = _coverage_positions - _target_coverage_map

            if not _closest_member['member_id']:
                logging.warning(
                    'Couldn\'t find closest member for target during squad positioning.'
                )

                continue

            _closest_member_pos = movement.get_position_via_id(
                _closest_member['member_id'])

            for pos in _overlap_positions:
                _distance = numbers.distance(_closest_member_pos, pos)

                if _distance < _score_map[pos]['vantage']:
                    _score_map[pos]['vantage'] = _distance

                #_score_map[pos]['danger'] = 60 - _distance
                _score_map[pos]['targets'].append(target_id)

            for pos in _cover_positions:
                _distance = numbers.distance(_closest_member_pos, pos)

                if _distance > _score_map[pos]['coverage']:
                    _score_map[pos]['coverage'] = _distance

                _score_map[pos]['danger'] = 60 - _distance

    squad['position_map_scores'] = _score_map
Example #50
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
Example #51
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"]
Example #52
0
def generate(width, height):
    _weight_map, _tile_map, _solids, _node_grid = mapgen.create_map(
        width, height)
    _zoom = .95
    _noise = tcod.noise_new(3)
    _low_grass = 25
    _fsl = {}
    _building_space = set()
    _walls = set()
    _possible_trees = set()
    _river_start_x = random.randint(int(round(width * .35)),
                                    int(round(width * .65)))
    _river_start_y = 0  #random.randint(int(round(height * .15)), int(round(height * .85)))
    _x = _river_start_x
    _y = _river_start_y
    _px, _py = _river_start_x, _river_start_y
    _river_direction = 270
    _turn_rate = random.randint(-1, 1)
    _river_tiles = set()
    _river_size = random.randint(7, 10)
    _ground_tiles = set()
    _possible_camps = set()

    while 1:
        for i in range(4, 10):
            for __x, __y in shapes.circle(_x, _y, _river_size):
                if __x < 0 or __y < 0 or __x >= width or __y >= height or (
                        __x, __y) in _solids:
                    continue

                _river_tiles.add((__x, __y))
                _tile = tiles.swamp_water(__x, __y)
                _tile_map[__y][__x] = _tile
                _weight_map[__y][__x] = _tile['w']

            _river_direction += _turn_rate
            _xv, _yv = numbers.velocity(_river_direction, 1)
            _px += _xv
            _py += _yv
            _x = int(round(_px))
            _y = int(round(_py))

            if _x < 0 or _y < 0 or _x >= width or _y >= height or (
                    _x, _y) in _solids:
                break

        if _x < 0 or _y < 0 or _x >= width or _y >= height:
            break

        _turn_rate = random.uniform(-2.5, 2.5)
        _river_size = numbers.clip(_river_size + random.randint(-1, 1), 7, 10)

    for y in range(height):
        for x in range(width):
            if (x, y) in _river_tiles:
                continue

            _tile = tiles.grass(x, y)
            _tile_map[y][x] = _tile
            _weight_map[y][x] = _tile['w']

            _ground_tiles.add((x, y))

    tcod.noise_set_type(_noise, tcod.NOISE_WAVELET)

    for y in range(height):
        for x in range(width):
            if (x, y) in _river_tiles:
                continue

            _noise_values = [(_zoom * x / (constants.MAP_VIEW_WIDTH)),
                             (_zoom * y / (constants.MAP_VIEW_HEIGHT))]
            _noise_value = 100 * tcod.noise_get_turbulence(
                _noise, _noise_values, tcod.NOISE_WAVELET)

            if _low_grass <= _noise_value <= 100:
                _tile = tiles.tall_grass(x, y)

                if _noise_value >= 40:
                    if not x < width * .15 and not x > width * .85 and not y < height * .15 and not y > height * .85:
                        _possible_camps.add((x, y))

                if random.uniform(0, 1) > .5:
                    _possible_trees.add((x, y))

            elif _noise_value >= _low_grass - 10 and 10 * random.uniform(
                    0, 1) > _low_grass - _noise_value:
                _tile = tiles.grass(x, y)

            else:
                _tile = tiles.rock(x, y)
                _solids.add((x, y))

            _tile_map[y][x] = _tile
            _weight_map[y][x] = _tile['w']

    _trees = {}
    _tree_plots = _possible_trees - _solids - _river_tiles
    _used_trees = random.sample(
        _tree_plots,
        numbers.clip(int(round((width * height) * .002)), 0, len(_tree_plots)))

    for x, y in _used_trees:
        _size = random.randint(1, 3)

        for _x, _y in shapes.circle(x, y, _size):
            if _x < 0 or _y < 0 or _x >= width or _y >= height or (
                    _x, _y) in _solids:
                break

            _tile = tiles.tree(_x, _y)
            _weight_map[_y][_x] = _tile['w']
            _tile_map[_y][_x] = _tile
            _trees[_x, _y] = random.uniform(2, 3.5) * _size

            _solids.add((_x, _y))

    _ground_tiles = _ground_tiles - _solids
    _plot_pole_x, _plot_pole_y = width / 2, height / 2
    _bushes = random.sample(
        _ground_tiles,
        numbers.clip(int(round((width * height) * .0003)), 0,
                     len(_ground_tiles)))
    _camps = set()

    while len(_possible_camps):
        _camp_1 = random.choice(list(_possible_camps))
        _possible_camps.remove(_camp_1)
        _camps.add(_camp_1)

        for camp_2 in _possible_camps.copy():
            _dist = numbers.distance(_camp_1, camp_2)

            if _dist <= 250:
                _possible_camps.remove(camp_2)

    for x, y in _bushes:
        _walker_x = x
        _walker_y = y
        _last_dir = -2, -2

        for i in range(random.randint(10, 15)):
            _tile = tiles.tree(_walker_x, _walker_y)
            _weight_map[_walker_y][_walker_x] = _tile['w']
            _tile_map[_walker_y][_walker_x] = _tile

            _dir = random.randint(-1, 1), random.randint(-1, 1)
            _n_x = _walker_x + _dir[0]
            _n_y = _walker_y + _dir[1]

            if _n_x < 0 or _n_y < 0 or _n_x >= width or _n_y >= height or (
                    _n_x, _n_y) in _solids:
                break

            _last_dir = _dir[0] * -1, _dir[0] * -1
            _walker_x = _n_x
            _walker_y = _n_y

    _camp_info = {}

    for c_x, c_y in _camps:
        _building_walls = random.sample(['north', 'south', 'east', 'west'],
                                        random.randint(2, 3))
        _broken_walls = random.sample(
            _building_walls,
            numbers.clip(random.randint(0, 3), 0, len(_building_walls)))
        _camp = {'center': (c_x, c_y)}
        _camp_ground = []

        for y in range(-10, 10 + 1):
            for x in range(-10, 10 + 1):
                _x = x + c_x
                _y = y + c_y

                if (_x, _y) in _solids or (_x, _y) in _river_tiles:
                    continue

                if (x == -10 and 'west' in _building_walls) or (
                        y == -10 and 'north' in _building_walls) or (
                            x == 10 and 'east' in _building_walls) or (
                                y == 10 and 'south' in _building_walls):
                    if x == -10 and 'west' in _building_walls and 'west' in _broken_walls and random.uniform(
                            0, 1) > .75:
                        continue

                    if x == 10 and 'east' in _building_walls and 'east' in _broken_walls and random.uniform(
                            0, 1) > .75:
                        continue

                    if y == -10 and 'north' in _building_walls and 'north' in _broken_walls and random.uniform(
                            0, 1) > .75:
                        continue

                    if y == 10 and 'south' in _building_walls and 'south' in _broken_walls and random.uniform(
                            0, 1) > .75:
                        continue

                    _tile = tiles.wooden_fence(_x, _y)
                    _weight_map[_y][_x] = _tile['w']
                    _tile_map[_y][_x] = _tile
                    _solids.add((_x, _y))

                elif (x > -10 and x <= 10) and (y > -10 and y <= 10):
                    _camp_ground.append((_x, _y))

        _camp['ground'] = _camp_ground[:]
        _camp_info[c_x, c_y] = _camp

    mapgen.build_node_grid(_node_grid, _solids)

    for c_x, c_y in _camps:
        mapgen.add_plot_pole(c_x, c_y, 40, _solids)

    _fsl = {
        'Terrorists': {
            'bases': 1,
            'squads': 0,
            'trader': False,
            'type': life.human_runner
        }
    }
    #        #'Militia': {'bases': 0, 'squads': 1, 'trader': False, 'type': life.human_bandit},
    #        'Wild Dogs': {'bases': 0, 'squads': 1, 'trader': False, 'type': life.wild_dog}}

    return width, height, _node_grid, mapgen.NODE_SETS.copy(
    ), _weight_map, _tile_map, _solids, _fsl, _trees, _building_space - _walls
Example #53
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"]
Example #54
0
File: ai.py Project: penny64/r3-tdw
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']
Example #55
0
def get_attack_cost(entity, camp_id):
	return numbers.distance(movement.get_position(entity), camp_id) * 125
Example #56
0
def generate(width, height):
	_weight_map, _tile_map, _solids, _node_grid = mapgen.create_map(width, height)
	_zoom = .95
	_noise = tcod.noise_new(3)
	_low_grass = 25
	_fsl = {}
	_building_space = set()
	_walls = set()
	_possible_trees = set()
	_river_start_x = random.randint(int(round(width * .35)), int(round(width * .65)))
	_river_start_y = 0#random.randint(int(round(height * .15)), int(round(height * .85)))
	_x = _river_start_x
	_y = _river_start_y
	_px, _py = _river_start_x, _river_start_y
	_river_direction = 270
	_turn_rate = random.randint(-1, 1)
	_river_tiles = set()
	_river_size = random.randint(7, 10)
	_ground_tiles = set()
	_possible_camps = set()
	
	while 1:
		for i in range(4, 10):
			for __x, __y in shapes.circle(_x, _y, _river_size):
				if __x < 0 or __y < 0 or __x >= width or __y >= height or (__x, __y) in _solids:
					continue
				
				_river_tiles.add((__x, __y))
				_tile = tiles.swamp_water(__x, __y)
				_tile_map[__y][__x] = _tile
				_weight_map[__y][__x] = _tile['w']
			
			_river_direction += _turn_rate
			_xv, _yv = numbers.velocity(_river_direction, 1)
			_px += _xv
			_py += _yv
			_x = int(round(_px))
			_y = int(round(_py))
			
			if _x < 0 or _y < 0 or _x >= width or _y >= height or (_x, _y) in _solids:
				break
		
		if _x < 0 or _y < 0 or _x >= width or _y >= height:
			break
		
		_turn_rate = random.uniform(-2.5, 2.5)
		_river_size = numbers.clip(_river_size + random.randint(-1, 1), 7, 10)
	
	for y in range(height):
		for x in range(width):
			if (x, y) in _river_tiles:
				continue
			
			_tile = tiles.grass(x, y)
			_tile_map[y][x] = _tile
			_weight_map[y][x] = _tile['w']
			
			_ground_tiles.add((x, y))
	
	tcod.noise_set_type(_noise, tcod.NOISE_WAVELET)
	
	for y in range(height):
		for x in range(width):
			if (x, y) in _river_tiles:
				continue
			
			_noise_values = [(_zoom * x / (constants.MAP_VIEW_WIDTH)),
					         (_zoom * y / (constants.MAP_VIEW_HEIGHT))]
			_noise_value = 100 * tcod.noise_get_turbulence(_noise, _noise_values, tcod.NOISE_WAVELET)
			
			if _low_grass <= _noise_value <= 100:
				_tile = tiles.tall_grass(x, y)
				
				if _noise_value >= 40:
					if not x < width * .15 and not x > width * .85 and not y < height * .15 and not y > height * .85:
						_possible_camps.add((x, y))
				
				if random.uniform(0, 1) > .5:
					_possible_trees.add((x, y))
			
			elif _noise_value >= _low_grass - 10 and 10 * random.uniform(0, 1) > _low_grass-_noise_value:
				_tile = tiles.grass(x, y)
			
			else:
				_tile = tiles.rock(x, y)
				_solids.add((x, y))
			
			_tile_map[y][x] = _tile
			_weight_map[y][x] = _tile['w']
	
	_trees = {}
	_tree_plots = _possible_trees - _solids - _river_tiles
	_used_trees = random.sample(_tree_plots, numbers.clip(int(round((width * height) * .002)), 0, len(_tree_plots)))
	
	for x, y in _used_trees:
		_size = random.randint(1, 3)
		
		for _x, _y in shapes.circle(x, y, _size):
			if _x < 0 or _y < 0 or _x >= width or _y >= height or (_x, _y) in _solids:
				break
			
			_tile = tiles.tree(_x, _y)
			_weight_map[_y][_x] = _tile['w']
			_tile_map[_y][_x] = _tile
			_trees[_x, _y] = random.uniform(2, 3.5) * _size
			
			_solids.add((_x, _y))
	
	_ground_tiles = _ground_tiles - _solids
	_plot_pole_x, _plot_pole_y = width/2, height/2
	_bushes = random.sample(_ground_tiles, numbers.clip(int(round((width * height) * .0003)), 0, len(_ground_tiles)))
	_camps = set()
	
	while len(_possible_camps):
		_camp_1 = random.choice(list(_possible_camps))
		_possible_camps.remove(_camp_1)
		_camps.add(_camp_1)
		
		for camp_2 in _possible_camps.copy():
			_dist = numbers.distance(_camp_1, camp_2)
			
			if _dist <= 250:
				_possible_camps.remove(camp_2)
	
	for x, y in _bushes:
		_walker_x = x
		_walker_y = y
		_last_dir = -2, -2
		
		for i in range(random.randint(10, 15)):
			_tile = tiles.tree(_walker_x, _walker_y)
			_weight_map[_walker_y][_walker_x] = _tile['w']
			_tile_map[_walker_y][_walker_x] =_tile
			
			_dir = random.randint(-1, 1), random.randint(-1, 1)
			_n_x = _walker_x + _dir[0]
			_n_y = _walker_y + _dir[1]

			if _n_x < 0 or _n_y < 0 or _n_x >= width or _n_y >= height or (_n_x, _n_y) in _solids:
				break
			
			_last_dir = _dir[0] * -1, _dir[0] * -1
			_walker_x = _n_x
			_walker_y = _n_y
	
	_camp_info = {}
	
	for c_x, c_y in _camps:
		_building_walls = random.sample(['north', 'south', 'east', 'west'], random.randint(2, 3))
		_broken_walls = random.sample(_building_walls, numbers.clip(random.randint(0, 3), 0, len(_building_walls)))
		_camp = {'center': (c_x, c_y)}
		_camp_ground = []
		
		for y in range(-10, 10+1):
			for x in range(-10, 10+1):
				_x = x + c_x
				_y = y + c_y
				
				if (_x, _y) in _solids or (_x, _y) in _river_tiles:
					continue
				
				if (x == -10 and 'west' in _building_walls) or (y == -10 and 'north' in _building_walls) or (x == 10 and 'east' in _building_walls) or (y == 10 and 'south' in _building_walls):
					if x == -10 and 'west' in _building_walls and 'west' in _broken_walls and random.uniform(0, 1) > .75:
						continue
					
					if x == 10 and 'east' in _building_walls and 'east' in _broken_walls and random.uniform(0, 1) > .75:
						continue
					
					if y == -10 and 'north' in _building_walls and 'north' in _broken_walls and random.uniform(0, 1) > .75:
						continue
					
					if y == 10 and 'south' in _building_walls and 'south' in _broken_walls and random.uniform(0, 1) > .75:
						continue
					
					_tile = tiles.wooden_fence(_x, _y)
					_weight_map[_y][_x] = _tile['w']
					_tile_map[_y][_x] = _tile
					_solids.add((_x, _y))
				
				elif (x > -10 and x <= 10) and (y > -10 and y <= 10):
					_camp_ground.append((_x, _y))
		
		_camp['ground'] = _camp_ground[:]
		_camp_info[c_x, c_y] = _camp
	
	mapgen.build_node_grid(_node_grid, _solids)
	
	for c_x, c_y in _camps:
		mapgen.add_plot_pole(c_x, c_y, 40, _solids)
	
	_fsl = {'Terrorists': {'bases': 1, 'squads': 0, 'trader': False, 'type': life.human_runner}}
	#        #'Militia': {'bases': 0, 'squads': 1, 'trader': False, 'type': life.human_bandit},
	#        'Wild Dogs': {'bases': 0, 'squads': 1, 'trader': False, 'type': life.wild_dog}}
	
	return width, height, _node_grid, mapgen.NODE_SETS.copy(), _weight_map, _tile_map, _solids, _fsl, _trees, _building_space - _walls
Example #57
0
def add_plot_pole(x, y, radius, solids, cell_split=3.0, debug=False):
    global NODE_SET_ID

    _node_set = set()
    _min_x = 999999999
    _max_x = 0
    _min_y = 999999999
    _max_y = 0

    for node_pos in list(UNCLAIMED_NODES):
        if numbers.distance((x, y), node_pos) > radius:
            continue

        if node_pos[0] < _min_x:
            _min_x = node_pos[0]

        if node_pos[0] > _max_x:
            _max_x = node_pos[0]

        if node_pos[1] < _min_y:
            _min_y = node_pos[1]

        if node_pos[1] > _max_y:
            _max_y = node_pos[1]

        _node_set.add(node_pos)

    _map = numpy.ones(((_max_y - _min_y) + 1, (_max_x - _min_x) + 1))

    for _x, _y in solids:
        if _x >= _max_x or _x <= _min_x or _y >= _max_y or _y <= _min_y:
            continue

        _map[int(round((_y - _min_y))), int(round((_x - _min_x)))] = -2

    NODE_SETS[NODE_SET_ID] = {
        'owner':
        None,
        'nodes':
        _node_set,
        'center': (x, y),
        'astar_map':
        _map,
        'min_x':
        _min_x,
        'min_y':
        _min_y,
        'cell_split':
        float(cell_split),
        'weight_map':
        numpy.ones(((_max_y - _min_y) + 1, (_max_x - _min_x) + 1),
                   dtype=numpy.int16)
    }
    NODE_SET_ID += 1

    if debug:
        for y in range(_max_y - _min_y):
            for x in range(_max_x - _min_x):
                _val = int(round(_map[y, x]))

                if _val == -2:
                    print '#',
                elif _val == 1:
                    print '.',

            print

    return NODE_SET_ID - 1
Example #58
0
File: ai.py Project: penny64/r3-tdw
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']
Example #59
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)]