def _spread(noise): for alife in LIFE.values(): if alife['dead']: continue if sight.can_see_position(alife, noise['pos']): continue _dist = numbers.distance(noise['pos'], alife['pos']) if _dist>noise['volume']: continue update_targets_around_noise(alife, noise) _direction_to = numbers.direction_to(alife['pos'], noise['pos']) _direction_string = language.get_real_direction(_direction_to) #TODO: Check walls between positions #TODO: Add memory if _dist >=noise['volume']/2: if 'player' in alife: gfx.message(random.choice(FAR_TEXT).replace('@t', noise['text'][1]).replace('@d', _direction_string)) else: if 'player' in alife: gfx.message(random.choice(FAR_TEXT).replace('@t', noise['text'][0]).replace('@d', _direction_string))
def tick_track(entity): #_target_id = find_target(entity) _target_id = entity['current_target'] if 'in_space' in entity and entity['in_space']: return False if entity['hp']<=0 or not _target_id in entities.ENTITIES: entity['current_target'] = None entities.unregister_event(entity, 'tick', tick_track) return False if not _target_id: entities.trigger_event(entity, 'accelerate', velocity=(0, 0)) return False _target = entities.get_entity(_target_id) _direction_to = numbers.direction_to(entity['position'], _target['position']) _degrees_to = abs(entity['direction']-_direction_to) if _degrees_to>=180: _direction_to += 360 _new_direction = numbers.interp(entity['direction'], _direction_to, entity['turn_rate']) _direction_difference = abs(entity['direction']-_new_direction) entity['direction'] = _new_direction entities.trigger_event(entity, 'thrust')
def create_cache_drop(pos, spawn_list): _player = LIFE[SETTINGS["controlling"]] _pos = spawns.get_spawn_point_around(pos, area=10) _direction = language.get_real_direction(numbers.direction_to(_player["pos"], _pos)) for container in spawn_list: if not container["rarity"] > random.uniform(0, 1.0): continue _c = items.create_item(container["item"], position=[_pos[0], _pos[1], 2]) for _inside_item in container["spawn_list"]: if _inside_item["rarity"] <= random.uniform(0, 1.0): continue _i = items.create_item(_inside_item["item"], position=[_pos[0], _pos[1], 2]) if not items.can_store_item_in(_i, _c): items.delete_item(_i) continue items.store_item_in(_i, _c) effects.create_smoker(_pos, 300, color=tcod.orange) gfx.message("You see something parachuting to the ground to the %s." % _direction, style="event")
def _spread(noise): for alife in LIFE.values(): if alife['dead']: continue _can_see = False if sight.can_see_position(alife, noise['pos']): _can_see = True _dist = numbers.distance(noise['pos'], alife['pos']) if _dist>noise['volume']: continue update_targets_around_noise(alife, noise) _direction_to = numbers.direction_to(alife['pos'], noise['pos']) _direction_string = language.get_real_direction(_direction_to) #TODO: Check walls between positions #TODO: Add memory if not _can_see or not noise['skip_on_visual']: if _dist >=noise['volume']/2: if 'player' in alife: gfx.message(random.choice(FAR_TEXT).replace('@t', noise['text'][1]).replace('@d', _direction_string), style='sound') else: if 'player' in alife: gfx.message(random.choice(FAR_TEXT).replace('@t', noise['text'][0]).replace('@d', _direction_string), style='sound')
def tick_track(entity): #_target_id = find_target(entity) _target_id = entity['current_target'] if 'in_space' in entity and entity['in_space']: return False if entity['hp'] <= 0 or not _target_id in entities.ENTITIES: entity['current_target'] = None entities.unregister_event(entity, 'tick', tick_track) return False if not _target_id: entities.trigger_event(entity, 'accelerate', velocity=(0, 0)) return False _target = entities.get_entity(_target_id) _direction_to = numbers.direction_to(entity['position'], _target['position']) _degrees_to = abs(entity['direction'] - _direction_to) if _degrees_to >= 180: _direction_to += 360 _new_direction = numbers.interp(entity['direction'], _direction_to, entity['turn_rate']) _direction_difference = abs(entity['direction'] - _new_direction) entity['direction'] = _new_direction entities.trigger_event(entity, 'thrust')
def create_cache_drop(pos, spawn_list): _player = LIFE[SETTINGS['controlling']] _pos = spawns.get_spawn_point_around(pos, area=10) _direction = language.get_real_direction( numbers.direction_to(_player['pos'], _pos)) for container in spawn_list: if not container['rarity'] > random.uniform(0, 1.0): continue _c = items.create_item(container['item'], position=[_pos[0], _pos[1], 2]) for _inside_item in container['spawn_list']: if _inside_item['rarity'] <= random.uniform(0, 1.0): continue _i = items.create_item(_inside_item['item'], position=[_pos[0], _pos[1], 2]) if not items.can_store_item_in(_i, _c): items.delete_item(_i) continue items.store_item_in(_i, _c) effects.create_smoker(_pos, 300, color=tcod.orange) gfx.message('You see something parachuting to the ground to the %s.' % _direction, style='event')
def path_along_reference(life, ref_type): _best_reference = _find_best_unknown_reference(life, ref_type)["reference"] if not _best_reference: print "NO BEST", ref_type return False _starting_chunk_key = find_nearest_key_in_reference(life, _best_reference) _chunk_path_keys = [] _directions = {} for neighbor_key in mapgen.get_neighbors_of_type(WORLD_INFO, _starting_chunk_key, ref_type, diagonal=True): if maps.get_chunk(neighbor_key) == lfe.get_current_chunk(life): continue _neighbor_pos = [int(val) + (WORLD_INFO["chunk_size"] / 2) for val in neighbor_key.split(",")] _cent = ( lfe.get_current_chunk(life)["pos"][0] + (WORLD_INFO["chunk_size"] / 2), lfe.get_current_chunk(life)["pos"][1] + (WORLD_INFO["chunk_size"] / 2), ) _neighbor_direction = numbers.direction_to(_cent, _neighbor_pos) _directions[_neighbor_direction] = {"key": neighbor_key, "score": 9999} _best_dir = {"dir": -1, "score": 0} for mod in range(-45, 361, 45): _new_dir = life["discover_direction"] + mod if _new_dir >= 360: _new_dir -= 360 if _new_dir in _directions: _score = 0 if _directions[_new_dir]["key"] in life["known_chunks"]: continue _score += (180 - (abs(_new_dir - life["discover_direction"]))) / 45 _score += life["discover_direction_history"].count(_new_dir) if _score >= _best_dir["score"]: if _score == _best_dir["score"]: _chunk = maps.get_chunk(_directions[_new_dir]["key"]) _best_dir["dir"] = _new_dir _best_dir["score"] = _score if _best_dir["dir"] == -1: return None # print _best_dir,_directions[_best_dir['dir']] life["discover_direction_history"].append(life["discover_direction"]) if len(life["discover_direction_history"]) >= 5: life["discover_direction_history"].pop(0) life["discover_direction"] = _best_dir["dir"] return _directions[_best_dir["dir"]]["key"]
def tick_energy_ship(entity): entity['shoot_direction'] = numbers.direction_to(entity['last_position'], entity['position']) if random.randint(0, 1): _displace = (random.uniform(-entity['velocity'][0], entity['velocity'][0]), random.uniform(-entity['velocity'][1], entity['velocity'][1])) _effect_direction = numbers.direction_to(entity['position'], (entity['position'][0]+(entity['velocity'][0]*6), entity['position'][1]+(entity['velocity'][1]*6))) _effect_direction += (abs(entity['shoot_direction']-_effect_direction)*numbers.clip(_effect_direction, -1, 1))*5 effects.create_particle(entity['position'][0]+_displace[0], entity['position'][1]+_displace[1], 'streamer.png', scale_rate=.75, speed=-entity['current_speed'], friction=0.1, direction=_effect_direction+random.randint(-5, 5), rotation=_effect_direction)
def tick_track(bullet): if bullet['target_id']: _target = entities.get_entity(bullet['target_id']) _current_direction = bullet['direction'] _direction_to = numbers.direction_to(bullet['position'], _target['position']) _degrees_to = _current_direction-_direction_to if (_degrees_to > 0 and abs(_degrees_to) <= 180) or (_degrees_to < 0 and abs(_degrees_to) > 180): bullet['direction'] -= 12 elif (_degrees_to > 0 and abs(_degrees_to) > 180) or (_degrees_to < 0 and abs(_degrees_to) <= 180): bullet['direction'] += 12 entities.trigger_event(bullet, 'thrust')
def path_along_reference(life, ref_type): _reference = WORLD_INFO['references'][WORLD_INFO['reference_map']['roads'][0]] _visible_chunks = alife.brain.get_flag(life, 'visible_chunks') _starting_chunk_key = alife.chunks.get_nearest_chunk_in_list(life['pos'], _reference, check_these_chunks_first=_visible_chunks) _chunk_path_keys = [] _directions = {} for neighbor_key in mapgen.get_neighbors_of_type(WORLD_INFO, _starting_chunk_key, ref_type, diagonal=True): if maps.get_chunk(neighbor_key) == lfe.get_current_chunk(life): continue _neighbor_pos = [int(val)+(WORLD_INFO['chunk_size']/2) for val in neighbor_key.split(',')] _cent = (lfe.get_current_chunk(life)['pos'][0]+(WORLD_INFO['chunk_size']/2), lfe.get_current_chunk(life)['pos'][1]+(WORLD_INFO['chunk_size']/2)) _neighbor_direction = numbers.direction_to(_cent, _neighbor_pos) _directions[_neighbor_direction] = {'key': neighbor_key, 'score': 9999} _best_dir = {'dir': -1, 'score': 0} for mod in range(-45, 361, 45): _new_dir = life['discover_direction']+mod if _new_dir>=360: _new_dir -= 360 if _new_dir in _directions: _score = 0 if _directions[_new_dir]['key'] in life['known_chunks']: continue _score += (180-(abs(_new_dir-life['discover_direction'])))/45 _score += life['discover_direction_history'].count(_new_dir) if _score>=_best_dir['score']: if _score==_best_dir['score']: _chunk = maps.get_chunk(_directions[_new_dir]['key']) _best_dir['dir'] = _new_dir _best_dir['score'] = _score if _best_dir['dir'] == -1: return None #print _best_dir,_directions[_best_dir['dir']] life['discover_direction_history'].append(life['discover_direction']) if len(life['discover_direction_history'])>=5: life['discover_direction_history'].pop(0) life['discover_direction'] = _best_dir['dir'] return _directions[_best_dir['dir']]['key']
def tick_guard(entity): if 'in_space' in entity and entity['in_space']: return False if entity['hp']<=0: entities.unregister_event(entity, 'tick', tick_guard) return False if not entity['current_target']: _target_id = find_target(entity, max_distance=350) if _target_id: entities.trigger_event(entity, 'set_direction', direction=numbers.direction_to(entity['position'], entities.get_entity(_target_id)['position'])) track_target(entity, _target_id)
def react_to_attack(life, target_id, stance): _target = LIFE[target_id] _attack = _target['moves'][stance] if life['stance'] <= _attack['effective_stance']: _force = life['stances'][life['stance']]-_attack['effective_stance'] else: _force = 0 if _force >= life['stances'][life['stance']]: lfe.push(life, numbers.direction_to(LIFE[target_id]['pos'], life['pos']), _attack['damage']['force']) force_stance(life, target_id, 'crawling') elif life['stances'][life['stance']]<=life['stances']['crouching']: force_stance(life, target_id, 'off-balance') lfe.add_wound(life, random.choice(life['body'].keys()), pain=_attack['damage']['force'])
def _gravity_well(entity): _moving_groups = [name for name in entities.GROUPS if not name in entity['_groups'] and not name in entities.IGNORE_ENTITY_GROUPS] for entity_id in entities.get_sprite_groups(_moving_groups): _entity = entities.get_entity(entity_id) if numbers.distance(entity['position'], _entity['position'])<entity['min_distance']: _entity['in_space'] = False continue if entity['kill_engines']: _entity['in_space'] = True _velocity = numbers.velocity(numbers.direction_to(_entity['position'], entity['position']), entity['strength']) entities.trigger_event(_entity, 'push', velocity=_velocity)
def react_to_attack(life, target_id, stance): _target = LIFE[target_id] _attack = _target['moves'][stance] if life['stance'] <= _attack['effective_stance']: _force = life['stances'][life['stance']] - _attack['effective_stance'] else: _force = 0 if _force >= life['stances'][life['stance']]: lfe.push(life, numbers.direction_to(LIFE[target_id]['pos'], life['pos']), _attack['damage']['force']) force_stance(life, target_id, 'crawling') elif life['stances'][life['stance']] <= life['stances']['crouching']: force_stance(life, target_id, 'off-balance') lfe.add_wound(life, random.choice(life['body'].keys()), pain=_attack['damage']['force'])
def tick_guard(entity): if 'in_space' in entity and entity['in_space']: return False if entity['hp'] <= 0: entities.unregister_event(entity, 'tick', tick_guard) return False if not entity['current_target']: _target_id = find_target(entity, max_distance=350) if _target_id: entities.trigger_event( entity, 'set_direction', direction=numbers.direction_to( entity['position'], entities.get_entity(_target_id)['position'])) track_target(entity, _target_id)
def hurt_player(situation): _player = LIFE[SETTINGS['controlling']] if situation['group']: if situation['armed']: _bandit_group_leader = get_group_leader_with_motive('crime', online=True) _military_group_leader = get_group_leader_with_motive('military', online=False) if not _military_group_leader: _military_group_leader = spawns.generate_group('soldier', amount=3, spawn_chunks=[spawns.get_spawn_in_ref('outposts', chunk_key=True)])[0] if not _bandit_group_leader: _chunk_key = alife.chunks.get_chunk_key_at(spawns.get_spawn_point_around(_military_group_leader['pos'], area=150, min_area=100)) _bandit_group_leader = spawns.generate_group('bandit', amount=5, spawn_chunks=[_chunk_key])[0] _bandit_group_location = lfe.get_current_chunk_id(_bandit_group_leader) _military_group_location = lfe.get_current_chunk_id(_military_group_leader) order_group(_bandit_group_leader, _bandit_group_leader['group'], STAGE_RAIDING, 500, chunk_key=_military_group_location) alife.groups.discover_group(_bandit_group_leader, _military_group_leader['group']) alife.groups.declare_group_hostile(_bandit_group_leader, _bandit_group_leader['group'], _military_group_leader['group']) _real_direction = language.get_real_direction(numbers.direction_to((MAP_SIZE[0]/2, MAP_SIZE[1]/2), alife.chunks.get_chunk(_military_group_location)['pos'])) _messages = [{'text': 'Attention all neutral and bandit squads.'}, {'text': 'We finally got solid contact on military in the %s compound.' % _real_direction}, {'text': 'We\'re located near coords %s and heading out soon.' % (', '.join(_bandit_group_location.split(',')))}] events.broadcast(_messages, 40) core.record_encounter(len(alife.groups.get_group(_military_group_leader, _military_group_leader['group'])['members'])) _player_group_leader = LIFE[alife.groups.get_leader(_player, situation['group'])] for friendly_member in alife.groups.get_group(_player_group_leader, situation['group'])['members']: for hostile_member in alife.groups.get_group(_military_group_leader, _military_group_leader['group'])['members']: _target = alife.brain.meet_alife(LIFE[friendly_member], LIFE[hostile_member]) _target['last_seen_time'] = 1 _target['escaped'] = 1 _target['last_seen_at'] = LIFE[hostile_member]['pos'][:] alife.stats.establish_hostile(LIFE[friendly_member], hostile_member) for hostile_member in alife.groups.get_group(_military_group_leader, _military_group_leader['group'])['members']: for friendly_member in alife.groups.get_group(_player_group_leader, situation['group'])['members']: _target = alife.brain.meet_alife(LIFE[hostile_member], LIFE[friendly_member]) _target['last_seen_time'] = 1 _target['escaped'] = 1 _target['last_seen_at'] = LIFE[friendly_member]['pos'][:] alife.stats.establish_hostile(LIFE[hostile_member], friendly_member) return True elif situation['armed']: _town_chunk_keys = [] for ref in WORLD_INFO['refs']['towns']: _town_chunk_keys.extend(ref) _nearest_town_chunk_key = alife.chunks.get_nearest_chunk_in_list(_player['pos'], _town_chunk_keys) _town_chunk = alife.chunks.get_chunk(_nearest_town_chunk_key) _distance_to_nearst_town = numbers.distance(_player['pos'], _town_chunk['pos']) _spawn_distance = 15*WORLD_INFO['chunk_size'] if len(situation['online_alife']) == len(situation['trusted_online_alife']): if _distance_to_nearst_town<=50: _group_spawn_velocity = numbers.velocity(numbers.direction_to(_player['pos'], _town_chunk['pos']), _spawn_distance+(50-numbers.clip(_distance_to_nearst_town, 0, 50))) _group_spawn_pos = [int(round(_player['pos'][0]+_group_spawn_velocity[0])), int(round(_player['pos'][1]+_group_spawn_velocity[1]))] _group_spawn_pos[0] = numbers.clip(_group_spawn_pos[0], 0, MAP_SIZE[0]) _group_spawn_pos[1] = numbers.clip(_group_spawn_pos[1], 0, MAP_SIZE[1]) _group_spawn_chunk_key = alife.chunks.get_chunk_key_at(spawns.get_spawn_point_around(_group_spawn_pos, area=30)) _alife = spawns.generate_group('bandit', amount=2, spawn_chunks=[_group_spawn_chunk_key]) for ai in _alife: alife.brain.meet_alife(ai, _player) alife.stats.establish_hostile(ai, _player['id']) core.record_encounter(2, life_ids=[i['id'] for i in _alife]) if random.randint(0, 1) or 1: _spawn_chunk_key = spawns.get_spawn_point_around(_group_spawn_pos, area=90, min_area=60, chunk_key=True) _other_group = spawns.generate_group('loner', amount=1, spawn_chunks=[_spawn_chunk_key]) for ai in _other_group: for ai2 in _alife: _target = alife.brain.meet_alife(ai, ai2) _target['last_seen_time'] = 1 _target['escaped'] = 1 _target['last_seen_at'] = ai2['pos'][:] alife.stats.establish_hostile(ai, ai2['id']) for ai2 in _alife: for ai in _other_group: _target = alife.brain.meet_alife(ai2, ai) _target['last_seen_time'] = 1 _target['escaped'] = 1 _target['last_seen_at'] = ai['pos'][:] alife.stats.establish_hostile(ai2, ai['id']) _messages = [{'text': 'I\'m pinned down in the village!'}, {'text': 'Anyone nearby?'}] events.broadcast(_messages, 0) return True elif 1==2: _spawn_chunk_key = spawns.get_spawn_point_around(_player['pos'], min_area=125, area=200, chunk_key=True) _group = spawns.generate_group('loner', amount=1, spawn_chunks=[_spawn_chunk_key]) core.record_encounter(1, life_ids=[l['id'] for l in _group]) for ai in _group: events.attract_tracked_alife_to(spawns.get_spawn_point_around(_player['pos'], min_area=10, area=100)) return False
def explode(item): if not item['type'] == 'explosive': return False logging.debug('The %s (item %s) explodes!' % (item['name'], item['uid'])) #TODO: Don't breathe this! item['pos'] = get_pos(item['uid']) if item['damage']['force']: effects.create_explosion(item['pos'], item['damage']['force']) if SETTINGS['controlling'] and alife.sight.can_see_position(LIFE[SETTINGS['controlling']], item['pos']): gfx.message('%s explodes!' % get_name(item)) logic.show_event('%s explodes!' % get_name(item), item=item, delay=0) #elif numbers.distance( #TODO: Dirty hack for life_id in LIFE: _limbs = LIFE[life_id]['body'].keys() if not _limbs: continue _force = numbers.clip((item['damage']['force']*2)-numbers.distance(LIFE[life_id]['pos'], item['pos']), 0, 100) if not _force: continue _known_item = alife.brain.remembers_item(LIFE[life_id], item) _direction = numbers.direction_to(item['pos'], LIFE[life_id]['pos']) #TODO: Intelligent(?) limb groups? _distance = numbers.distance(LIFE[life_id]['pos'], item['pos'])/2 for i in range(_force-_distance): _limb = random.choice(_limbs) for _attached_limb in life.get_all_attached_limbs(LIFE[life_id], _limb): if _attached_limb in _limbs: _limbs.remove(_attached_limb) #_limb = random.choice(LIFE[life_id]['body'].keys()) if _known_item and _known_item['last_seen_time'] < 100 and _known_item['last_owned_by']: life.memory(LIFE[life_id], 'blown_up_by', target=_known_item['last_owned_by']) #for _limb in _limbs: life.add_wound(LIFE[life_id], _limb, force_velocity=numbers.velocity(_direction, _force*2)) if not _limbs: break life.push(LIFE[life_id], _direction, _force) if 'player' in LIFE[life_id]: life.say(LIFE[life_id], '@n are thrown by the explosion!', action=True) else: life.say(LIFE[life_id], '@n is thrown by the explosion!', action=True) if 'fire' in item['damage']: _circle = drawing.draw_circle(item['pos'], item['radius']) _zone = zones.get_zone_at_coords(item['pos']) if _zone: for pos in zones.dijkstra_map(item['pos'], [item['pos']], [_zone], return_score_in_range=[0, item['damage']['fire']]): if not pos in _circle: continue if not maps.position_is_in_map(pos): continue for life_id in LIFE_MAP[pos[0]][pos[1]]: for _visible_item in [get_item_from_uid(i) for i in life.get_all_visible_items(LIFE[life_id])]: if not 'CAN_BURN' in _visible_item['flags']: continue burn(_visible_item, item['damage']['fire']) if not random.randint(0, 4): effects.create_fire((pos[0], pos[1], item['pos'][2]), intensity=item['damage']['fire']/2) _dist = numbers.distance(item['pos'], pos)/2 if not random.randint(0, _dist) or not _dist: effects.create_ash(pos) if gfx.position_is_in_frame(pos): _render_pos = gfx.get_render_position(pos) gfx.refresh_view_position(_render_pos[0], _render_pos[1], 'map') #if item['uid'] in ITEMS and ITEMS[item['uid']]['owner'] and item['uid'] in LIFE[ITEMS[item['uid']]['owner']]['inventory']: delete_item(item)
def create_eyemine(x=0, y=0, max_explode_velocity=40): _entity = create(x=x, y=y, group='hazards', sprite_name='eyemine_body.png', speed=35, acceleration=0.1, max_velocity=35) _entity['max_explode_velocity'] = max_explode_velocity effects.create_image(_entity['position'][0], _entity['position'][1], 'eyemine_subbody.png', parent_entity=_entity, rotate_by=3, background=True) effects.create_image(_entity['position'][0], _entity['position'][1], 'eyemine_eye1.png', parent_entity=_entity, background=False) effects.create_image(_entity['position'][0], _entity['position'][1], 'eyemine_eye2.png', parent_entity=_entity, rotate_with_parent=True, background=False) entities.register_event(_entity, 'tick', tick_eyemine) entities.register_event(_entity, 'hit', lambda _entity, target_id, **kwargs: target_id in entities.ENTITIES and entities.trigger_event(_entity, 'set_direction', direction=numbers.direction_to(_entity['position'], entities.get_entity(target_id)['position']))) entities.register_event(_entity, 'hit', lambda _entity, target_id, **kwargs: ai.track_target(_entity, target_id)) entities.register_event(_entity, 'hit_edge', lambda entity: entities.trigger_event(entity, 'kill')) ai.guard(_entity) return _entity
def explode(item): if not item['type'] == 'explosive': return False logging.debug('The %s (item %s) explodes!' % (item['name'], item['uid'])) #TODO: Don't breathe this! item['pos'] = get_pos(item['uid']) alife.noise.create(item['pos'], item['damage']['force']*100, 'an explosion', 'a low rumble') if item['damage']['force']: effects.create_light(item['pos'], (255, 69, 0), item['damage']['force']*6, 1, fade=3) effects.create_smoke_cloud(item['pos'], item['damage']['force']*6, age=.8, factor_distance=True) for i in range(random.randint(1, 3)): effects.create_smoke_streamer(item['pos'], 3+random.randint(0, 2), (item['damage']['force']*2)+random.randint(3, 6), color=tcod.color_lerp(tcod.gray, tcod.crimson, random.uniform(0.1, 0.3))) if SETTINGS['controlling'] and alife.sight.can_see_position(LIFE[SETTINGS['controlling']], item['pos']): gfx.message('%s explodes!' % get_name(item)) logic.show_event('%s explodes!' % get_name(item), item=item, delay=0) #elif numbers.distance( #TODO: Dirty hack for life_id in LIFE: _limbs = LIFE[life_id]['body'].keys() if not _limbs: continue _force = numbers.clip((item['damage']['force']*2)-numbers.distance(LIFE[life_id]['pos'], item['pos']), 0, 100) if not _force: continue _known_item = alife.brain.remembers_item(LIFE[life_id], item) _direction = numbers.direction_to(item['pos'], LIFE[life_id]['pos']) #TODO: Intelligent(?) limb groups? _distance = numbers.distance(LIFE[life_id]['pos'], item['pos'])/2 for i in range(_force-_distance): _limb = random.choice(_limbs) for _attached_limb in life.get_all_attached_limbs(LIFE[life_id], _limb): if _attached_limb in _limbs: _limbs.remove(_attached_limb) #_limb = random.choice(LIFE[life_id]['body'].keys()) #ex: memory(life, 'shot at by (missed)', target=item['owner'], danger=3, trust=-10) if _known_item and _known_item['last_seen_time'] < 100 and _known_item['last_owned_by']: life.memory(LIFE[life_id], 'blown_up_by', target=_known_item['last_owned_by'], trust=-10, danger=3) #for _limb in _limbs: life.add_wound(LIFE[life_id], _limb, force_velocity=numbers.velocity(_direction, _force*2)) if not _limbs: break life.push(LIFE[life_id], _direction, _force) if 'player' in LIFE[life_id]: life.say(LIFE[life_id], '@n are thrown by the explosion!', action=True) else: life.say(LIFE[life_id], '@n is thrown by the explosion!', action=True) if 'fire' in item['damage']: _circle = drawing.draw_circle(item['pos'], item['radius']) _zone = zones.get_zone_at_coords(item['pos']) if _zone: for pos in zones.dijkstra_map(item['pos'], [item['pos']], [_zone], return_score_in_range=[0, item['damage']['fire']]): if not pos in _circle: continue if not maps.position_is_in_map(pos): continue for life_id in LIFE_MAP[pos[0]][pos[1]]: for _visible_item in [get_item_from_uid(i) for i in life.get_all_visible_items(LIFE[life_id])]: if not 'CAN_BURN' in _visible_item['flags']: continue burn(_visible_item, item['damage']['fire']) if not random.randint(0, 4): effects.create_fire((pos[0], pos[1], item['pos'][2]), intensity=item['damage']['fire']/2) _dist = numbers.distance(item['pos'], pos)/2 if not random.randint(0, _dist) or not _dist: effects.create_ash(pos) if gfx.position_is_in_frame(pos): _render_pos = gfx.get_render_position(pos) gfx.refresh_view_position(_render_pos[0], _render_pos[1], 'map') #if item['uid'] in ITEMS and ITEMS[item['uid']]['owner'] and item['uid'] in LIFE[ITEMS[item['uid']]['owner']]['inventory']: delete_item(item)
def tick_turret(entity): _target_id = ai.find_target(entity, max_distance=1600) if _target_id: entity['shoot_direction'] = numbers.direction_to(entity['position'], entities.get_entity(_target_id)['position']) entities.trigger_event(entity, 'shoot')
def fire(life, target, limb=None): #TODO: Don't breathe this! weapon = get_weapon_to_fire(life) if not weapon: return False _aim_with_limb = None for hand in life['hands']: if weapon['uid'] in lfe.get_limb(life, hand)['holding']: _aim_with_limb = hand _ooa = False _feed_uid = get_feed(weapon) if not _feed_uid: if 'player' in life: gfx.message('The weapon is unloaded.') _ooa = True return False _feed = items.get_item_from_uid(_feed_uid) if not _feed or (_feed and not _feed['rounds']): if 'player' in life: gfx.message('*Click* (You are out of ammo.)') _ooa = True return False _bullet_deviation = (1 - weapon['accuracy']) + life['recoil'] _deviation_mod = SETTINGS['aim_difficulty'] * (1 - ( (life['stats']['firearms'] / 10.0) * SETTINGS['firearms_skill_mod'])) _direction_deviation = (_bullet_deviation * SETTINGS['aim_difficulty']) * _deviation_mod life['recoil'] = numbers.clip( life['recoil'] + (weapon['recoil'] * get_stance_recoil_mod(life)), 0.0, 1.0) _bullet_direction = numbers.direction_to(life['pos'], target) + ( random.uniform(-_direction_deviation, _direction_deviation)) alife.noise.create(life['pos'], 120, '%s fire' % weapon['name'], 'something discharge', target=life['id']) #TODO: Clean this up... _bullet = items.get_item_from_uid(_feed['rounds'].pop()) _bullet['pos'] = life['pos'][:] _bullet['start_pos'] = life['pos'][:] _bullet['owner'] = None _bullet['shot_by'] = life['id'] _bullet['aim_at_limb'] = limb items.add_to_chunk(_bullet) if gfx.position_is_in_frame(life['pos']) or 'player' in life: effects.create_light(life['pos'], tcod.yellow, 7, 1, fade=3.2) effects.create_light(_bullet['pos'], tcod.yellow, 7, .9, fade=.65, follow_item=_bullet['uid']) effects.create_smoke_cloud(life['pos'], 3, color=tcod.light_gray) effects.create_smoke(life['pos'], color=tcod.yellow) _bullet['accuracy'] = int( round(get_accuracy(life, weapon['uid'], limb=_aim_with_limb))) print 'ACCURACY', _bullet['accuracy'] del _bullet['parent'] items.move(_bullet, _bullet_direction, _bullet['max_speed']) _bullet['start_velocity'] = _bullet['velocity'][:] items.tick_item(_bullet) for _life in [LIFE[i] for i in LIFE]: if _life['pos'][0] == target[0] and _life['pos'][1] == target[1]: life['aim_at'] = _life['id'] break if len(lfe.find_action(life, matches=[{'action': 'shoot'}])) == 1: life['firing'] = None
def spawn_enemies(): global TRANSITION_PAUSE, CHANGE_WAVE_FIRE, CHANGE_WAVE, ANNOUNCE, WAVE _i = random.choice([0, 1, 2, 3]) if WAVE == 3: TRANSITION_PAUSE = 30*30 CHANGE_WAVE = True CHANGE_WAVE_FIRE = False return False if LEVEL == 2: return False if _i == 1: _xrange = random.choice([(100, worlds.get_size()[0]*.25), (worlds.get_size()[0]*.25, worlds.get_size()[0]*.5), (worlds.get_size()[0]*.5, worlds.get_size()[0]*.75), (worlds.get_size()[0]*.75, worlds.get_size()[0]-100)]) _y = 100 elif _i == 2: _x = worlds.get_size()[0]-100 _y = random.choice([(100, worlds.get_size()[1]*.25), (worlds.get_size()[1]*.25, worlds.get_size()[1]*.5), (worlds.get_size()[1]*.5, worlds.get_size()[1]*.75), (worlds.get_size()[1]*.75, worlds.get_size()[1]-100)]) elif _i == 3: _x = 100 _y = random.randint(100, worlds.get_size()[1]-100) else: _x = random.randint(100, worlds.get_size()[0]-100) _y = worlds.get_size()[1]-100 _missile_turrets = int(round(10*((WAVE+1)/5.0))) _gun_turrets = int(round(10*(WAVE/5.0))) _fleas = int(round(5*(WAVE/5.0))) for i in range(_fleas): if _i == 1: _x = random.randint(100, worlds.get_size()[0]-100) _y = 100 elif _i == 2: _x = worlds.get_size()[0]-100 _y = random.randint(100, worlds.get_size()[1]-100) elif _i == 3: _x = 100 _y = random.randint(100, worlds.get_size()[1]-100) else: _x = random.randint(100, worlds.get_size()[0]-100) _y = worlds.get_size()[1]-100 _entity = ships.create_flea(x=_x, y=_y, hazard=True) _move_direction = numbers.direction_to((_x, _y,), (worlds.get_size()[0]/2, worlds.get_size()[1]/2)) entities.trigger_event(_entity, 'push', velocity=numbers.velocity(_move_direction, 20)) for i in range(_gun_turrets): if _i == 1: _x = random.randint(200, worlds.get_size()[0]-200) _y = 200 elif _i == 2: _x = worlds.get_size()[0]-200 _y = random.randint(200, worlds.get_size()[1]-200) elif _i == 3: _x = 200 _y = random.randint(200, worlds.get_size()[1]-200) else: _x = random.randint(200, worlds.get_size()[0]-200) _y = worlds.get_size()[1]-200 _entity = ships.create_gun_turret(x=_x, y=_y) _move_direction = numbers.direction_to((_x, _y,), (worlds.get_size()[0]/2, worlds.get_size()[1]/2)) entities.trigger_event(_entity, 'push', velocity=numbers.velocity(_move_direction, 20)) for i in range(_missile_turrets): if _i == 1: _x = random.randint(100, worlds.get_size()[0]-100) _y = 100 elif _i == 2: _x = worlds.get_size()[0]-100 _y = random.randint(100, worlds.get_size()[1]-100) elif _i == 3: _x = 100 _y = random.randint(100, worlds.get_size()[1]-100) else: _x = random.randint(100, worlds.get_size()[0]-100) _y = worlds.get_size()[1]-100 _entity = ships.create_missile_turret(x=_x, y=_y) _move_direction = numbers.direction_to((_x, _y,), (worlds.get_size()[0]/2, worlds.get_size()[1]/2)) entities.trigger_event(_entity, 'push', velocity=numbers.velocity(_move_direction, 20)) WAVE += 1 ANNOUNCE = True
def fire(life, target, limb=None): #TODO: Don't breathe this! weapon = get_weapon_to_fire(life) if not weapon: return False _aim_with_limb = None for hand in life['hands']: if weapon['uid'] in lfe.get_limb(life, hand)['holding']: _aim_with_limb = hand _ooa = False _feed_uid = get_feed(weapon) if not _feed_uid: if 'player' in life: gfx.message('The weapon is unloaded.') _ooa = True return False _feed = items.get_item_from_uid(_feed_uid) if not _feed or (_feed and not _feed['rounds']): if 'player' in life: gfx.message('*Click* (You are out of ammo.)') _ooa = True return False direction = numbers.direction_to(life['pos'],target)+(random.uniform(-life['recoil'], life['recoil'])) alife.noise.create(life['pos'], 120, '%s fire' % weapon['name'], 'something discharge') #TODO: Clean this up... _bullet = items.get_item_from_uid(_feed['rounds'].pop()) _bullet['pos'] = life['pos'][:] _bullet['start_pos'] = life['pos'][:] _bullet['owner'] = None _bullet['shot_by'] = life['id'] _bullet['aim_at_limb'] = limb life['recoil'] += _bullet['recoil']*(weapon['recoil']*get_stance_recoil_mod(life)) items.add_to_chunk(_bullet) if gfx.position_is_in_frame(life['pos']): effects.create_light(life['pos'], tcod.yellow, 7, 1, fade=3.5) effects.create_light(_bullet['pos'], tcod.yellow, 7, 1, fade=0.65, follow_item=_bullet['uid']) effects.create_smoke_cloud(life['pos'], 3, color=tcod.light_gray) effects.create_smoke(life['pos'], color=tcod.yellow) _bullet['accuracy'] = int(round(get_accuracy(life, weapon['uid'], limb=_aim_with_limb))) del _bullet['parent'] items.move(_bullet, direction, _bullet['max_speed']) _bullet['start_velocity'] = _bullet['velocity'][:] items.tick_item(_bullet) for _life in [LIFE[i] for i in LIFE]: if _life['pos'][0] == target[0] and _life['pos'][1] == target[1]: life['aim_at'] = _life['id'] break if len(lfe.find_action(life, matches=[{'action': 'shoot'}])) == 1: life['firing'] = None
def score(entity, target_id, amount=0, text=''): display.print_text(0, 10+(len(display.LABELS)*15), '%s (<b>+%s</b>)' % (text, amount), color=(0, 240, 0, 255), show_for=1.5) if target_id in entities.ENTITIES and abs(entity['shoot_direction']-numbers.direction_to(entity['position'], entities.get_entity(target_id)['position']))<45: display.print_text(0, 10+(len(display.LABELS)*15), 'FRENZY!!!', color=(0, 240, 0, 255), show_for=1.5)
def form_scheme(force=False): if (WORLD_INFO['scheme'] or (WORLD_INFO['ticks']-WORLD_INFO['last_scheme_time'])<200) and not force or not SETTINGS['controlling']: return False _overwatch_mood = WORLD_INFO['overwatch']['mood'] core.handle_tracked_alife() if _overwatch_mood == 'rest': return False _player_situation = core.get_player_situation() if _overwatch_mood == 'hurt': if hurt_player(_player_situation): WORLD_INFO['last_scheme_time'] = WORLD_INFO['ticks'] return True elif _overwatch_mood == 'intrigue': if intrigue_player(_player_situation): WORLD_INFO['last_scheme_time'] = WORLD_INFO['ticks'] return True elif _overwatch_mood == 'help': if help_player(_player_situation): WORLD_INFO['last_scheme_time'] = WORLD_INFO['ticks'] return True #if _player_situation['armed']: _i = random.randint(0, 3)+10 if _i == 1: _military_group_leader = get_group_leader_with_motive('military') _bandit_group_leader = get_group_leader_with_motive('crime', online=False) #TODO: Actual bandit camp location if _military_group_leader and _bandit_group_leader: _bandit_group_location = lfe.get_current_chunk_id(LIFE[_bandit_group_leader]) order_group(LIFE[_military_group_leader], LIFE[_military_group_leader]['group'], STAGE_RAIDING, 30, chunk_key=_bandit_group_location) alife.groups.discover_group(LIFE[_military_group_leader], LIFE[_bandit_group_leader]['group']) alife.groups.declare_group_hostile(LIFE[_military_group_leader], LIFE[_military_group_leader]['group'], LIFE[_bandit_group_leader]['group']) elif _i == 2: _spawn_pos = spawns.get_spawn_in_ref('farms') _real_direction = language.get_real_direction(numbers.direction_to((MAP_SIZE[0]/2, MAP_SIZE[1]/2), _spawn_pos)) spawn_life('loner', _spawn_pos, 35, injuries={'llowerleg': {'cut': 1}}) _messages = [{'text': 'Hello? Can anyone hear me?'}, {'text': 'Bandits robbed me and left me to bleed out...'}, {'text': 'I\'m by a farm to the %s.' % _real_direction}, {'text': 'They might still be around. Please hurry!'}] events.broadcast(_messages, 40) elif 1 == 1: _bandit_group_leader = core.get_group_leader_with_motive('crime', online=True) _military_group_leader = core.get_group_leader_with_motive('military', online=False) if _military_group_leader and _bandit_group_leader: _bandit_group_location = lfe.get_current_chunk_id(LIFE[_bandit_group_leader]) _military_group_location = lfe.get_current_chunk_id(LIFE[_military_group_leader]) order_group(LIFE[_bandit_group_leader], LIFE[_bandit_group_leader]['group'], STAGE_RAIDING, 500, chunk_key=_military_group_location) alife.groups.discover_group(LIFE[_bandit_group_leader], LIFE[_military_group_leader]['group']) alife.groups.declare_group_hostile(LIFE[_bandit_group_leader], LIFE[_bandit_group_leader]['group'], LIFE[_military_group_leader]['group']) _real_direction = language.get_real_direction(numbers.direction_to((MAP_SIZE[0]/2, MAP_SIZE[1]/2), alife.chunks.get_chunk(_military_group_location)['pos'])) _messages = [{'text': 'Attention all neutral and bandit squads.'}, {'text': 'We finally got solid contact on military in the %s compound.' % _real_direction}, {'text': 'We\'re located near coords %s and heading out soon.' % (', '.join(_bandit_group_location.split(',')))}] events.broadcast(_messages, 40)