def check_chunks(self, force=False): if not force and WORLD_INFO['ticks']-self.last_checked<self.check_every: return False self.last_checked = WORLD_INFO['ticks'] for life in [l for l in LIFE.values() if l['online']]: _x_min = bad_numbers.clip(life['pos'][0]-MAP_WINDOW_SIZE[0], 0, MAP_SIZE[0]-1-MAP_WINDOW_SIZE[0]) _y_min = bad_numbers.clip(life['pos'][1]-MAP_WINDOW_SIZE[1], 0, MAP_SIZE[1]-1-MAP_WINDOW_SIZE[1]) _x_max = bad_numbers.clip(life['pos'][0]+MAP_WINDOW_SIZE[0], 0, MAP_SIZE[0]-1) _y_max = bad_numbers.clip(life['pos'][1]+MAP_WINDOW_SIZE[1], 0, MAP_SIZE[1]-1) _refresh = False for y in range(_y_min, _y_max, WORLD_INFO['chunk_size']): for x in range(_x_min, _x_max, WORLD_INFO['chunk_size']): maps.load_cluster_at_position_if_needed((x, y)) SETTINGS['loading'] = True if 'player' in life: _refresh = True if _refresh: gfx.refresh_view('map') SETTINGS['loading'] = False
def get_overwatch_hardship(no_mod=True): _stats = WORLD_INFO['overwatch'] _situation = get_player_situation() if not _situation: return 0 if no_mod: _mod = 1 else: if len(_situation['online_alife']) == len(_situation['trusted_online_alife']): _mod = _stats['last_updated']/float(WORLD_INFO['ticks']) else: _mod = bad_numbers.clip((_stats['last_updated']*1.5)/float(WORLD_INFO['ticks']), 0, 1.0) #TODO: Decay #_stats['loss_experienced'] *= _dec #_stats['danger_experienced'] *= _dec #_stats['injury'] *= _dec #_stats['human_encounters'] *= _dec _hardship = _stats['loss_experienced'] _hardship += _stats['danger_experienced'] _hardship += _stats['injury'] _hardship += _stats['human_encounters']*4 _hardship *= _mod return bad_numbers.clip(float(_hardship), 0.0, 10.0)
def create_search_map(life, pos, size): _map = numpy.ones((size, size)) _x_top_left = bad_numbers.clip(pos[0] - (size / 2), 0, MAP_SIZE[0]) _y_top_left = bad_numbers.clip(pos[1] - (size / 2), 0, MAP_SIZE[1]) for x in range(0, size): _x = _x_top_left + x if _x >= MAP_SIZE[0] - 1: continue for y in range(0, size): _y = _y_top_left + y if _y >= MAP_SIZE[1] - 1: continue if not is_solid((_x, _y, pos[2])) or is_solid( (_x, _y, pos[2] + 1)): _map[y, x] = 0 else: _map[y, x] = alife.judgement.judge_search_pos(life, (_x, _y)) return _map
def get_stealth_coverage(life): _coverage = 1.0 if life['stance'] == 'standing': _stealth_mod = 1.0 elif life['stance'] == 'crouching': _stealth_mod = 0.75 else: _stealth_mod = 0.55 _visible_chunk_keys = brain.get_flag(life, 'visible_chunks') if _visible_chunk_keys: _visible_chunks = len(_visible_chunk_keys) else: _visible_chunks = 100 _stealth_mod *= bad_numbers.clip(_visible_chunks / 100.0, 0, 1.0) for z in range(1, 6): if WORLD_INFO['map'][life['pos'][0]][life['pos'][1]][life['pos'][2] + z]: _coverage *= _stealth_mod return bad_numbers.clip(_coverage, 0.0, 1.0)
def generate_los(life, target, at, source_map, score_callback, invert=False, ignore_starting=False): _stime = time.time() _cover = {'pos': None, 'score': 9000} _x = bad_numbers.clip(at[0] - (SETTINGS['los'] / 2), 0, MAP_SIZE[0] - (SETTINGS['los'] / 2)) _y = bad_numbers.clip(at[1] - (SETTINGS['los'] / 2), 0, MAP_SIZE[1] - (SETTINGS['los'] / 2)) _top_left = (_x, _y, at[2]) target_los = render_fast_los.render_fast_los(at, SETTINGS['los'], source_map) for pos in render_los.draw_circle(life['pos'][0], life['pos'][1], 30): x = pos[0] - _top_left[0] y = pos[1] - _top_left[1] if pos[0] < 0 or pos[1] < 0 or pos[0] >= MAP_SIZE[0] or pos[ 1] >= MAP_SIZE[0]: continue if x < 0 or y < 0 or x >= target_los.shape[1] or y >= target_los.shape[ 0]: continue if life['pos'][0] - _top_left[0] >= target_los.shape[ 1] or life['pos'][1] - _top_left[1] >= target_los.shape[0]: continue if target_los[life['pos'][1] - _top_left[1], life['pos'][0] - _top_left[0]] == invert and not ignore_starting: _cover['pos'] = life['pos'][:] return False if source_map[pos[0]][pos[1]][at[2] + 1] or source_map[pos[0]][pos[1]][at[2] + 2]: continue if target_los[y, x] == invert: #TODO: Additional scores, like distance from target _score = score_callback(life, target, pos) if _score < _cover['score']: _cover['score'] = _score _cover['pos'] = list(pos) #print time.time()-_stime if not _cover['pos']: print 'Nowhere to hide', target['life']['name'], _top_left return False return _cover
def update_targets_around_noise(life, noise): _most_likely_target = {'target': None, 'last_seen_time': 0} if 'target' in noise and not life['id'] == noise['target']: _visiblity = bad_numbers.clip(sight.get_stealth_coverage(LIFE[noise['target']]), 0.0, 1.0) _visiblity = bad_numbers.clip(_visiblity+(bad_numbers.distance(life['pos'], LIFE[noise['target']]['pos']))/(sight.get_vision(life)/2), 0, 1.0) if _visiblity >= sight.get_visiblity_of_position(life, LIFE[noise['target']]['pos']): brain.meet_alife(life, LIFE[noise['target']]) life['know'][noise['target']]['escaped'] = 1 life['know'][noise['target']]['last_seen_at'] = noise['pos'][:] life['know'][noise['target']]['last_seen_time'] = 0 for target in life['know'].values(): if not target['escaped'] or not target['last_seen_at'] or target['dead']: continue if bad_numbers.distance(target['last_seen_at'], noise['pos']) > noise['volume']: continue if judgement.is_target_threat(life, target['life']['id']): if not _most_likely_target['target'] or target['last_seen_time'] < _most_likely_target['last_seen_time']: _most_likely_target['last_seen_time'] = target['last_seen_time'] _most_likely_target['target'] = target if _most_likely_target['target']: _most_likely_target['target']['escaped'] = 1 _most_likely_target['target']['last_seen_at'] = noise['pos'][:] _most_likely_target['target']['last_seen_time'] = 1 logging.debug('%s heard a noise, attributing it to %s.' % (' '.join(life['name']), ' '.join(_most_likely_target['target']['life']['name'])))
def draw_chunk_map(life=None, show_faction_ownership=False): _x_min = bad_numbers.clip(CAMERA_POS[0]/WORLD_INFO['chunk_size'], 0, MAP_SIZE[0]/WORLD_INFO['chunk_size']) _y_min = bad_numbers.clip(CAMERA_POS[1]/WORLD_INFO['chunk_size'], 0, MAP_SIZE[1]/WORLD_INFO['chunk_size']) _x_max = bad_numbers.clip(_x_min+WINDOW_SIZE[0], 0, MAP_SIZE[0]/WORLD_INFO['chunk_size']) _y_max = bad_numbers.clip(_y_min+WINDOW_SIZE[1], 0, MAP_SIZE[1]/WORLD_INFO['chunk_size']) _life_chunk_key = None if life: _life_chunk_key = lfe.get_current_chunk_id(life) for x in range(_x_min, _x_max): _d_x = x-(CAMERA_POS[0]/WORLD_INFO['chunk_size']) if 0>_d_x >= WINDOW_SIZE[0]: continue for y in range(_y_min, _y_max): _d_y = y-(CAMERA_POS[1]/WORLD_INFO['chunk_size']) _draw = True _fore_color = tcod.darker_gray _back_color = tcod.darkest_gray if 0>_d_y >= WINDOW_SIZE[1]: continue _chunk_key = '%s,%s' % (x*WORLD_INFO['chunk_size'], y*WORLD_INFO['chunk_size']) if life: if not _chunk_key in life['known_chunks']: _draw = False if _draw: _type = WORLD_INFO['chunk_map'][_chunk_key]['type'] _char = 'x' if _type in ['building', 'town']: _fore_color = tcod.light_gray _char = 'B' elif _type in ['outpost', 'factory']: _fore_color = tcod.desaturated_green _back_color = tcod.desaturated_han _char = 'M' elif _type == 'field': _fore_color = tcod.yellow elif _type == 'forest': _fore_color = tcod.dark_green elif _type in ['road', 'driveway']: _fore_color = tcod.white _back_color = tcod.black _char = '.' if _chunk_key == _life_chunk_key and time.time()%1>=.5: _fore_color = tcod.white _char = 'X' gfx.blit_char_to_view(_d_x, _d_y, _char, (_fore_color, _back_color), 'chunk_map') else: gfx.blit_char_to_view(_d_x, _d_y, 'x', (tcod.darker_gray, tcod.darkest_gray), 'chunk_map')
def fast_draw_map(): _CAM_X = bad_numbers.clip(CAMERA_POS[0], 0, MAP_SIZE[0] - MAP_WINDOW_SIZE[0]) _CAM_Y = bad_numbers.clip(CAMERA_POS[1], 0, MAP_SIZE[1] - MAP_WINDOW_SIZE[1]) tcod.console_blit(SETTINGS['map_slices'][2], _CAM_X, _CAM_Y, MAP_WINDOW_SIZE[0], MAP_WINDOW_SIZE[1], MAP_WINDOW, 0, 0)
def _generate_los(life, target, at, source_map, score_callback, invert=False, ignore_starting=False): #Step 1: Locate cover _cover = {'pos': None, 'score': 9000} #TODO: Unchecked Cython flag _x = bad_numbers.clip(at[0] - (MAP_WINDOW_SIZE[0] / 2), 0, MAP_SIZE[0]) _y = bad_numbers.clip(at[1] - (MAP_WINDOW_SIZE[1] / 2), 0, MAP_SIZE[1]) _top_left = (_x, _y, at[2]) target_los = render_los.render_los(source_map, at, top_left=_top_left, no_edge=False) for pos in render_los.draw_circle(life['pos'][0], life['pos'][1], 30): x = pos[0] - _top_left[0] y = pos[1] - _top_left[1] if pos[0] < 0 or pos[1] < 0 or pos[0] >= MAP_SIZE[0] or pos[ 1] >= MAP_SIZE[0]: continue if x < 0 or y < 0 or x >= target_los.shape[1] or y >= target_los.shape[ 0]: continue if life['pos'][0] - _top_left[0] >= target_los.shape[ 0] or life['pos'][1] - _top_left[1] >= target_los.shape[1]: continue if target_los[life['pos'][1] - _top_left[1], life['pos'][0] - _top_left[0]] == invert and not ignore_starting: _cover['pos'] = life['pos'][:] return False if source_map[pos[0]][pos[1]][at[2] + 1] or source_map[pos[0]][pos[1]][at[2] + 2]: continue if target_los[y, x] == invert: #TODO: Additional scores, like distance from target _score = score_callback(life, target['life'], pos) if _score < _cover['score']: _cover['score'] = _score _cover['pos'] = list(pos) if not _cover['pos']: print 'Nowhere to hide' return False return _cover
def draw_intro(): _stime = time.time() _title_time = time.time() _warning_time = None _warning_message = VERSION _sub_mod = 0 _sub_time = 0 _shadow = 50 _burn = 8.0 _char_alpha = {c: random.uniform(.15, .7) for c in SUB_LINE} #Why did I base this on time.time()? while time.time()-_stime<=5: _text = INTRO if time.time()-_stime<=1: _text = list(_text) random.shuffle(_text) _text = ''.join(_text) else: if not _sub_time: _sub_time = time.time() if 4.0>time.time()-_stime: _burn *= 1.005 elif time.time()-_stime>=4.0 and _burn>255: _burn = 255 _text = INTRO _mod = int(round(255*bad_numbers.clip(time.time()-_title_time, 0, 1))) console_set_default_foreground(0, Color(_mod, _mod, _mod)) console_print(0, (WINDOW_SIZE[0]/2)-len(_text)/2, (WINDOW_SIZE[1]/2)-2, _text) if time.time()-_stime>=1: if not _warning_time: _warning_time = time.time() _mod = int(round(255*bad_numbers.clip(time.time()-_warning_time, 0, 1))) console_set_default_foreground(0, Color(_mod/2, _mod/2, _mod/2)) console_print(0, 0, WINDOW_SIZE[1]-1, _warning_message) if time.time()-_stime>=1.2: _i = 0 for c in SUB_LINE: _c_mod = _char_alpha[c] _mod = bad_numbers.clip(time.time()-_warning_time, 0, 1) console_set_default_foreground(0, Color(int(round((200*_mod)*_c_mod)), 0, 0)) console_print(0, _i+(WINDOW_SIZE[0]/2)-len(SUB_LINE)/2, (WINDOW_SIZE[1]/2), c) _char_alpha[c] = bad_numbers.clip(_char_alpha[c]*1.015, 0, 1) _i += 1 console_flush() SETTINGS['running'] = 1
def is_confident(life): if 'player' in life: return False _friendly_confidence = judgement.get_ranged_combat_rating_of_target( life, life['id']) _threat_confidence = 0 for target_id in judgement.get_trusted(life, visible=False): _knows = brain.knows_alife_by_id(life, target_id) if _knows['dead'] or _knows['asleep']: continue if _knows['last_seen_time'] > 30: if brain.get_alife_flag(life, target_id, 'threat_score'): _recent_mod = 1 - ( bad_numbers.clip(_knows['last_seen_time'], 0, 300) / 300.0) _score = brain.get_alife_flag(life, target_id, 'threat_score') _friendly_confidence += _score * _recent_mod else: _friendly_confidence += 1 else: _score = judgement.get_ranged_combat_rating_of_target( life, target_id) brain.flag_alife(life, target_id, 'threat_score', value=_score) _friendly_confidence += _score for target_id in judgement.get_threats(life, ignore_escaped=False): _knows = brain.knows_alife_by_id(life, target_id) if _knows['dead'] or _knows['asleep']: continue if _knows['last_seen_time']: if brain.get_alife_flag(life, target_id, 'threat_score'): if _knows['last_seen_time'] > 50: _recent_mod = 1 - (bad_numbers.clip( _knows['last_seen_time'], 0, 600) / 600.0) else: _recent_mod = 1 _score = brain.get_alife_flag(life, target_id, 'threat_score') _threat_confidence += _score * _recent_mod else: _threat_confidence += 1 else: _score = judgement.get_ranged_combat_rating_of_target( life, target_id, inventory_check=False) brain.flag_alife(life, target_id, 'threat_score', value=_score) _threat_confidence += _score return _friendly_confidence - _threat_confidence >= -2
def move_camera(pos, scroll=False): _orig_pos = CAMERA_POS[:] CAMERA_POS[0] = bad_numbers.clip(pos[0]-(WINDOW_SIZE[0]/2),0,MAP_SIZE[0]-WINDOW_SIZE[0]) CAMERA_POS[1] = bad_numbers.clip(pos[1]-(WINDOW_SIZE[1]/2),0,MAP_SIZE[1]-WINDOW_SIZE[1]) CAMERA_POS[2] = pos[2] if not _orig_pos == CAMERA_POS: gfx.refresh_view('map') elif SETTINGS['controlling'] and not alife.brain.get_flag(LIFE[SETTINGS['controlling']], 'redraw') == pos: gfx.refresh_view('map')
def position_is_in_frame(pos): _view = get_active_view() if not _view: return False if pos[0] >= CAMERA_POS[0] and pos[0] < bad_numbers.clip(CAMERA_POS[0]+_view['view_size'][0]-1, 0, MAP_SIZE[0]) and \ pos[1] >= CAMERA_POS[1] and pos[1] < bad_numbers.clip(CAMERA_POS[1]+_view['view_size'][1]-1, 0, MAP_SIZE[1]): return True return False
def is_confident(life): if 'player' in life: return False _friendly_confidence = judgement.get_ranged_combat_rating_of_target(life, life['id']) _threat_confidence = 0 for target_id in judgement.get_trusted(life, visible=False): _knows = brain.knows_alife_by_id(life, target_id) if _knows['dead'] or _knows['asleep']: continue if _knows['last_seen_time']>30: if brain.get_alife_flag(life, target_id, 'threat_score'): _recent_mod = 1-(bad_numbers.clip(_knows['last_seen_time'], 0, 300)/300.0) _score = brain.get_alife_flag(life, target_id, 'threat_score') _friendly_confidence += _score*_recent_mod else: _friendly_confidence += 1 else: _score = judgement.get_ranged_combat_rating_of_target(life, target_id) brain.flag_alife(life, target_id, 'threat_score', value=_score) _friendly_confidence += _score for target_id in judgement.get_threats(life, ignore_escaped=False): _knows = brain.knows_alife_by_id(life, target_id) if _knows['dead'] or _knows['asleep']: continue if _knows['last_seen_time']: if brain.get_alife_flag(life, target_id, 'threat_score'): if _knows['last_seen_time']>50: _recent_mod = 1-(bad_numbers.clip(_knows['last_seen_time'], 0, 600)/600.0) else: _recent_mod = 1 _score = brain.get_alife_flag(life, target_id, 'threat_score') _threat_confidence += _score*_recent_mod else: _threat_confidence += 1 else: _score = judgement.get_ranged_combat_rating_of_target(life, target_id, inventory_check=False) brain.flag_alife(life, target_id, 'threat_score', value=_score) _threat_confidence += _score return _friendly_confidence-_threat_confidence>=-2
def reload_slices(): for _slice in WORLD_INFO['slices'].values(): #logging.debug('Loading slice: %s' % _slice['id']) _size = [_slice['bot_right'][0]-_slice['top_left'][0], _slice['bot_right'][1]-_slice['top_left'][1]] _size[0] = bad_numbers.clip(_size[0], 1, MAP_SIZE[0]) _size[1] = bad_numbers.clip(_size[1], 1, MAP_SIZE[1]) _slice['_map'] = zones.create_map_array(size=_size) for pos in _slice['map']: _xx = _slice['top_left'][0]+1 _yy = _slice['top_left'][1]+1 _slice['_map'][pos[0]-_xx][pos[1]-_yy] = 1
def get_engage_distance(life): _weapons = get_equipped_weapons(life) if _weapons: return bad_numbers.clip(int(round(ITEMS[_weapons[0]]['accuracy']*29)), 3, sight.get_vision(life)) else: return sight.get_vision(life)/2
def create_gib(life, icon, size, limb, velocity, color=(tcod.white, None)): _gib = {'name': 'gib', 'prefix': 'a', 'type': 'magazine', 'icon': icon, 'flags': ['BLOODY'], 'description': '%s\'s %s.' % (' '.join(life['name']), limb), 'size': '%sx1' % size, 'material': 'flesh', 'thickness': size, 'color': color} _i = items.get_item_from_uid(items.create_item('gib', position=life['pos'][:], item=_gib)) _i['velocity'] = [bad_numbers.clip(velocity[0], -3, 3), bad_numbers.clip(velocity[1], -3, 3), velocity[2]] logging.debug('Created gib.')
def draw_dijkstra(dijkstra,path=None): for _y in range(dijkstra['y_range'][0],dijkstra['y_range'][1]): y = _y-dijkstra['y_range'][0] for _x in range(dijkstra['x_range'][0],dijkstra['x_range'][1]): x = _x-dijkstra['x_range'][0] if not path: if (_x,_y) in dijkstra['ignore']: print '# ', continue #else: # print '.', _n = str(bad_numbers.clip(abs(int(dijkstra['map'][y,x])),0,41)) if len(_n)==1: print '%s ' % _n, else: print _n, else: #print path if (_x,_y,0) in path: print 'o', elif (_x,_y) in dijkstra['ignore']: print '#', else: print ' ', print
def draw_vapor(pos, vapor): gfx.tint_tile( pos[0], pos[1], vapor['color'], bad_numbers.clip( vapor['max_intensity'] * (1 - (vapor['age'] / float(vapor['age_max']))), 0, vapor['max_intensity']))
def broadcast(messages, event_time, glitch=False): _time = WORLD_INFO['ticks']+event_time _i = 0 for entry in messages: if 'source' in entry: _source = entry['source'] else: _source = '???' if glitch: if 'change_only' in entry: _change = entry['change_only'] else: _change = False _delay = (50*bad_numbers.clip(_i, 0, 1))+(len(entry['text'])*2)*_i WORLD_INFO['scheme'].append({'glitch': entry['text'], 'change': _change, 'time': _time+_delay}) else: WORLD_INFO['scheme'].append({'radio': [_source, entry['text']], 'time': _time}) _time += int(round(len(entry['text'])*1.25)) _i += 1
def generate_los(life, target, at, source_map, score_callback, invert=False, ignore_starting=False): _stime = time.time() _cover = {'pos': None,'score': 9000} _x = bad_numbers.clip(at[0]-(SETTINGS['los']/2),0,MAP_SIZE[0]-(SETTINGS['los']/2)) _y = bad_numbers.clip(at[1]-(SETTINGS['los']/2),0,MAP_SIZE[1]-(SETTINGS['los']/2)) _top_left = (_x,_y,at[2]) target_los = render_fast_los.render_fast_los(at, SETTINGS['los'], source_map) for pos in render_los.draw_circle(life['pos'][0],life['pos'][1],30): x = pos[0]-_top_left[0] y = pos[1]-_top_left[1] if pos[0]<0 or pos[1]<0 or pos[0]>=MAP_SIZE[0] or pos[1]>=MAP_SIZE[0]: continue if x<0 or y<0 or x>=target_los.shape[1] or y>=target_los.shape[0]: continue if life['pos'][0]-_top_left[0]>=target_los.shape[1] or life['pos'][1]-_top_left[1]>=target_los.shape[0]: continue if target_los[life['pos'][1]-_top_left[1],life['pos'][0]-_top_left[0]]==invert and not ignore_starting: _cover['pos'] = life['pos'][:] return False if source_map[pos[0]][pos[1]][at[2]+1] or source_map[pos[0]][pos[1]][at[2]+2]: continue if target_los[y,x] == invert: #TODO: Additional scores, like distance from target _score = score_callback(life, target, pos) if _score<_cover['score']: _cover['score'] = _score _cover['pos'] = list(pos) #print time.time()-_stime if not _cover['pos']: print 'Nowhere to hide', target['life']['name'], _top_left return False return _cover
def create_field(y_min=0): _territory_key = find_territory(y_min=y_min) _territory = WORLD_INFO['territories'][_territory_key] _territory['danger'] = random.choice(['burner']) _spawn_chunk_keys = [k for k in _territory['chunk_keys'] if WORLD_INFO['chunk_map'][k]['type'] == 'other'] _territory['flags']['create_amount'] = bad_numbers.clip(random.randint(3, 5), 0, len(_spawn_chunk_keys)) return _territory_key
def clear(*args): console_rect(0,0,0,WINDOW_SIZE[0],WINDOW_SIZE[1],True,flag=BKGND_DEFAULT) _c = random.choice([tcod.sepia, tcod.brass, tcod.gray]) for y in range(WINDOW_SIZE[1]): for x in range(WINDOW_SIZE[0]): if not time.time()%0.1: continue _mod = random.randint(0, 10) tcod.console_put_char_ex(0, x, y, chr(random.randint(0, 125)), tcod.Color(bad_numbers.clip(_c.r+_mod, 0, 255), bad_numbers.clip(_c.g+_mod, 0, 255), bad_numbers.clip(_c.b+_mod, 0, 255)), tcod.Color(_c.r+_mod, _c.g+_mod, _c.b+_mod)) console_flush()
def parse_raw_judgements(life, target_id): lfe.execute_raw(life, 'judge', 'trust', break_on_false=False, life_id=target_id) if lfe.execute_raw(life, 'judge', 'break_trust', life_id=target_id): brain.knows_alife_by_id(life, target_id)['trust'] = bad_numbers.clip(brain.knows_alife_by_id(life, target_id)['trust'], -1000, -1) return True return False
def get_current_weather(): _current_weather = WORLD_INFO['real_time_of_day'] / ( WORLD_INFO['length_of_day'] / len(WORLD_INFO['weather']['colors'])) _current_weather = bad_numbers.clip( _current_weather, 0, len(WORLD_INFO['weather']['colors']) - 1) return WORLD_INFO['weather']['colors'][_current_weather]
def draw_dialog(dialog_id): _dialog = get_dialog(dialog_id) _last_message = get_last_message(dialog_id) _x = bad_numbers.clip(MAP_WINDOW_SIZE[0]/2-len(_last_message['text'])/2, 3, 100) _y = 10 _line_of_sight = drawing.diag_line(LIFE[_dialog['started_by']]['pos'], LIFE[_dialog['target']]['pos']) locks.unlock('camera_free') if len(_line_of_sight)<=1: _center_pos = LIFE[_dialog['started_by']]['pos'] else: _center_pos = list(_line_of_sight[len(_line_of_sight)/2]) _center_pos.append(2) if SETTINGS['controlling'] == _dialog['started_by']: _target = _dialog['target'] else: _target = _dialog['started_by'] _target_portrait = lfe.draw_life_icon(LIFE[_target]) _lines = [] gfx.camera_track(_center_pos) gfx.blit_string(_x-2, _y-2, ' '.join(LIFE[_target]['name']), 'overlay', fore_color=_target_portrait[1]) gfx.blit_string(_x-2, _y, _target_portrait[0], 'overlay', fore_color=_target_portrait[1])#, back_color=tcod.darkest_gray) _text = _last_message['text'] _y_mod = 0 while _text: _x = MAP_WINDOW_SIZE[0]/2-len(_text[:MAP_WINDOW_SIZE[0]-4])/2 gfx.blit_string(_x, _y+_y_mod, _text[:MAP_WINDOW_SIZE[0]-4], 'overlay') _text = _text[MAP_WINDOW_SIZE[0]-4:] _y_mod += 1 for choice in _dialog['choices']: _text = choice['text'][choice['text'].index('\"')+1:choice['text'].index('\"')-1] if not _text.startswith('>'): _text = '> '+_text _n_x = MAP_WINDOW_SIZE[0]/2-len(_text)/2 if _n_x < _x: _x = _n_x for choice in _dialog['choices']: _text = choice['text'][choice['text'].index('\"')+1:choice['text'].index('\"')-1] if _dialog['cursor_index'] == _dialog['choices'].index(choice): _text = '> '+_text _lines.append(_text) for line in _lines: gfx.blit_string(_x, _y+3, line, 'overlay')#, back_color=tcod.darkest_gray) _y += 2
def reload_slices(): for _slice in WORLD_INFO['slices'].values(): #logging.debug('Loading slice: %s' % _slice['id']) _size = [ _slice['bot_right'][0] - _slice['top_left'][0], _slice['bot_right'][1] - _slice['top_left'][1] ] _size[0] = bad_numbers.clip(_size[0], 1, MAP_SIZE[0]) _size[1] = bad_numbers.clip(_size[1], 1, MAP_SIZE[1]) _slice['_map'] = zones.create_map_array(size=_size) for pos in _slice['map']: _xx = _slice['top_left'][0] + 1 _yy = _slice['top_left'][1] + 1 _slice['_map'][pos[0] - _xx][pos[1] - _yy] = 1
def get_engage_distance(life): _weapons = get_equipped_weapons(life) if _weapons: return bad_numbers.clip( int(round(ITEMS[_weapons[0]]['accuracy'] * 29)), 3, sight.get_vision(life)) else: return sight.get_vision(life) / 2
def create_effects(item, pos, real_z_pos, z_min): for _z in range(0, 2): _z_level = bad_numbers.clip( z_min - _z, 0, maputils.get_map_size(WORLD_INFO['map'])[2] - 1) if WORLD_INFO['map'][pos[0]][pos[1]][_z_level]: if int(round(real_z_pos)) - _z_level <= 2: if 'BLOODY' in item['flags']: if random.randint(0, 50) <= 35: effects.create_splatter('blood', [ pos[0] + random.randint(-2, 2), pos[1] + random.randint(-2, 2), _z_level ]) if 'SMOKING' in item['flags']: if random.randint(0, 50) <= 25: effects.create_smoke_streamer( [ pos[0] + random.randint(-item['size'], item['size']), pos[1] + random.randint(-item['size'], item['size']), _z_level ], item['size'] / 2, random.randint(item['size'] * 2, (item['size'] * 2) + 5)) if 'BURNING' in item['flags']: if random.randint(0, 50) <= 25: effects.create_smoke_cloud([ pos[0] + random.randint(-item['size'], item['size']), pos[1] + random.randint(-item['size'], item['size']), _z_level ], random.randint( item['size'], (item['size']) + 3), color=tcod.light_crimson) if 'max_speed' in item and is_moving(item): effects.create_vapor( item['pos'], 5, bad_numbers.clip(item['speed'] / 20, 0, 1))
def evaluate_overwatch_mood(): _stats = WORLD_INFO['overwatch'] _hardship = get_overwatch_hardship(no_mod=True) _success = get_overwatch_success() _hardship_rate = _hardship/10.0 _success_rate = _success/10.0 _activity = _stats['last_updated']/float(WORLD_INFO['ticks']) _difficulty = bad_numbers.clip(_hardship_rate-_success_rate, 0.0, 1.0) #print _activity, bad_numbers.clip(_success_rate, 0.3, 0.85) if _activity>bad_numbers.clip(_success_rate, 0.3, 0.85): _stats['mood'] = 'rest' elif _success_rate<.3: _stats['mood'] = 'help' elif _success_rate>_hardship_rate: _stats['mood'] = 'intrigue' else: _stats['mood'] = 'idle'
def _generate_los(life,target,at,source_map,score_callback,invert=False,ignore_starting=False): #Step 1: Locate cover _cover = {'pos': None,'score': 9000} #TODO: Unchecked Cython flag _x = bad_numbers.clip(at[0]-(MAP_WINDOW_SIZE[0]/2),0,MAP_SIZE[0]) _y = bad_numbers.clip(at[1]-(MAP_WINDOW_SIZE[1]/2),0,MAP_SIZE[1]) _top_left = (_x,_y,at[2]) target_los = render_los.render_los(source_map,at,top_left=_top_left,no_edge=False) for pos in render_los.draw_circle(life['pos'][0],life['pos'][1],30): x = pos[0]-_top_left[0] y = pos[1]-_top_left[1] if pos[0]<0 or pos[1]<0 or pos[0]>=MAP_SIZE[0] or pos[1]>=MAP_SIZE[0]: continue if x<0 or y<0 or x>=target_los.shape[1] or y>=target_los.shape[0]: continue if life['pos'][0]-_top_left[0]>=target_los.shape[0] or life['pos'][1]-_top_left[1]>=target_los.shape[1]: continue if target_los[life['pos'][1]-_top_left[1],life['pos'][0]-_top_left[0]]==invert and not ignore_starting: _cover['pos'] = life['pos'][:] return False if source_map[pos[0]][pos[1]][at[2]+1] or source_map[pos[0]][pos[1]][at[2]+2]: continue if target_los[y,x] == invert: #TODO: Additional scores, like distance from target _score = score_callback(life,target['life'],pos) if _score<_cover['score']: _cover['score'] = _score _cover['pos'] = list(pos) if not _cover['pos']: print 'Nowhere to hide' return False return _cover
def create_splatter(what, position, velocity=[0, 0], intensity=4): _intensity = bad_numbers.clip(random.random(), intensity*.05, intensity*.1) #if not _splatter: _splatter = {'pos': list(position[:]), 'what': what, 'color': tcod.Color(0, 0, 0), 'coef': _intensity} if velocity[0]>0: _splatter['pos'][0] += random.randint(0, bad_numbers.clip(int(round(velocity[0])), 0, 2)) elif velocity[0]<0: _splatter['pos'][0] -= random.randint(0, bad_numbers.clip(-int(round(velocity[0])), 0, 2)) if velocity[1]>0: _splatter['pos'][1] += random.randint(0, bad_numbers.clip(int(round(velocity[1])), 0, 2)) elif velocity[1]<0: _splatter['pos'][1] -= random.randint(0, bad_numbers.clip(-int(round(velocity[1])), 0, 2)) _has_splatter = has_splatter(tuple(_splatter['pos']), what=what) if _has_splatter: if what == 'blood': _has_splatter['color'].r = 150 else: _has_splatter['coef'] += 0.3 _has_splatter['coef'] = bad_numbers.clip(_has_splatter['coef'],0,1) return True _splatter['pos'] = tuple(_splatter['pos']) SPLATTERS.append(_splatter)
def create_gib(life, icon, size, limb, velocity, color=(tcod.white, None)): _gib = { 'name': 'gib', 'prefix': 'a', 'type': 'magazine', 'icon': icon, 'flags': ['BLOODY'], 'description': '%s\'s %s.' % (' '.join(life['name']), limb), 'size': '%sx1' % size, 'material': 'flesh', 'thickness': size, 'color': color } _i = items.get_item_from_uid( items.create_item('gib', position=life['pos'][:], item=_gib)) _i['velocity'] = [ bad_numbers.clip(velocity[0], -3, 3), bad_numbers.clip(velocity[1], -3, 3), velocity[2] ] logging.debug('Created gib.')
def get_tension_with(life, life_id): _target = brain.knows_alife_by_id(life, life_id) if _target['alignment'] in ['trust', 'feign_trust'] or not _target['last_seen_at']: return 0 if not _target['last_seen_time'] and _target['dead']: return 0 _distance = bad_numbers.clip(bad_numbers.distance(life['pos'], _target['last_seen_at']), 0, sight.get_vision(life)) _tension = get_ranged_combat_rating_of_target(life, life_id)/float(get_ranged_combat_rating_of_self(life)) return abs(((sight.get_vision(life)-_distance)/float(sight.get_vision(life)))*_tension)*(100-bad_numbers.clip(_target['last_seen_time'], 0, 100))/100.0
def get_vision(life): if not 'CAN_SEE' in life['life_flags']: return 0 #if 'player' in life: _fov_mod = 1 #else: # _fov_mod = bad_numbers.clip(1-(life['think_rate']/float(life['think_rate_max'])), 0.5, 1) _world_light = tcod.white-weather.get_lighting() _light_percentage = bad_numbers.clip(((_world_light.r+_world_light.g+_world_light.b)*.30)/200.0, 0, 1) return int(round((life['vision_max']*_light_percentage)*_fov_mod))
def get_overwatch_success(): _stats = WORLD_INFO['overwatch'] _situation = get_player_situation() if not _situation: return 0 #TODO: Check ammo _success = len(_situation['weapons']) _success += _stats['intervention'] #_success += len(_situation['equipped_gear']) return bad_numbers.clip(float(_success), 0.0, 10.0)
def create_effects(item, pos, real_z_pos, z_min): for _z in range(0, 2): _z_level = bad_numbers.clip(z_min-_z, 0, maputils.get_map_size(WORLD_INFO['map'])[2]-1) if WORLD_INFO['map'][pos[0]][pos[1]][_z_level]: if int(round(real_z_pos))-_z_level<=2: if 'BLOODY' in item['flags']: if random.randint(0,50)<=35: effects.create_splatter('blood', [pos[0]+random.randint(-2, 2), pos[1]+random.randint(-2, 2), _z_level]) if 'SMOKING' in item['flags']: if random.randint(0, 50)<=25: effects.create_smoke_streamer([pos[0]+random.randint(-item['size'], item['size']), pos[1]+random.randint(-item['size'], item['size']), _z_level], item['size']/2, random.randint(item['size']*2, (item['size']*2)+5)) if 'BURNING' in item['flags']: if random.randint(0, 50)<=25: effects.create_smoke_cloud([pos[0]+random.randint(-item['size'], item['size']), pos[1]+random.randint(-item['size'], item['size']), _z_level], random.randint(item['size'], (item['size'])+3), color=tcod.light_crimson) if 'max_speed' in item and is_moving(item): effects.create_vapor(item['pos'], 5, bad_numbers.clip(item['speed']/20, 0, 1))
def create_ash(pos): _color = random.randint(0, 25) _intensity = bad_numbers.clip(_color/float(25), .3, 1) _effect = {'type': 'ash', 'color': tcod.Color(_color, _color, _color), 'intensity': _intensity, 'pos': list(pos), 'callback': lambda x: 1==1, 'draw_callback': draw_ash, 'unregister_callback': lambda ash: unregister_effect(ash)} register_effect(_effect)
def get_stealth_coverage(life): _coverage = 1.0 if life['stance'] == 'standing': _stealth_mod = 1.0 elif life['stance'] == 'crouching': _stealth_mod = 0.75 else: _stealth_mod = 0.55 _visible_chunk_keys = brain.get_flag(life, 'visible_chunks') if _visible_chunk_keys: _visible_chunks = len(_visible_chunk_keys) else: _visible_chunks = 100 _stealth_mod *= bad_numbers.clip(_visible_chunks/100.0, 0, 1.0) for z in range(1, 6): if WORLD_INFO['map'][life['pos'][0]][life['pos'][1]][life['pos'][2]+z]: _coverage *= _stealth_mod return bad_numbers.clip(_coverage, 0.0, 1.0)
def get_vision(life): if not 'CAN_SEE' in life['life_flags']: return 0 #if 'player' in life: _fov_mod = 1 #else: # _fov_mod = bad_numbers.clip(1-(life['think_rate']/float(life['think_rate_max'])), 0.5, 1) _world_light = tcod.white - weather.get_lighting() _light_percentage = bad_numbers.clip( ((_world_light.r + _world_light.g + _world_light.b) * .30) / 200.0, 0, 1) return int(round((life['vision_max'] * _light_percentage) * _fov_mod))
def create_search_map(life, pos, size): _map = numpy.ones((size, size)) _x_top_left = bad_numbers.clip(pos[0]-(size/2), 0, MAP_SIZE[0]) _y_top_left = bad_numbers.clip(pos[1]-(size/2), 0, MAP_SIZE[1]) for x in range(0, size): _x = _x_top_left+x if _x >= MAP_SIZE[0]-1: continue for y in range(0, size): _y = _y_top_left+y if _y >= MAP_SIZE[1]-1: continue if not is_solid((_x, _y, pos[2])) or is_solid((_x, _y, pos[2]+1)): _map[y, x] = 0 else: _map[y, x] = alife.judgement.judge_search_pos(life, (_x, _y)) return _map
def create_ash(pos): _color = random.randint(0, 25) _intensity = bad_numbers.clip(_color / float(25), .3, 1) _effect = { 'type': 'ash', 'color': tcod.Color(_color, _color, _color), 'intensity': _intensity, 'pos': list(pos), 'callback': lambda x: 1 == 1, 'draw_callback': draw_ash, 'unregister_callback': lambda ash: unregister_effect(ash) } register_effect(_effect)
def generate_effects(size): _current_weather = WORLD_INFO['real_time_of_day']/(WORLD_INFO['length_of_day']/len(WORLD_INFO['weather']['colors'])) _current_weather = bad_numbers.clip(_current_weather, 0, len(WORLD_INFO['weather']['colors'])-1) if 'raining' in WORLD_INFO['weather']['colors'][_current_weather]['effects']: rain(size) if 'lightning' in WORLD_INFO['weather']['colors'][_current_weather]['effects'] and not random.randint(0, 200): RGB_LIGHT_BUFFER[0] -= 155 RGB_LIGHT_BUFFER[1] -= 155 RGB_LIGHT_BUFFER[2] -= 155 RGB_LIGHT_BUFFER[0] = RGB_LIGHT_BUFFER[0].clip(0, 255) RGB_LIGHT_BUFFER[1] = RGB_LIGHT_BUFFER[1].clip(0, 255) RGB_LIGHT_BUFFER[2] = RGB_LIGHT_BUFFER[2].clip(0, 255)
def _calculate_trust(life, target_id): _knows = brain.knows_alife_by_id(life, target_id) _hard_trust = 0 _soft_trust = 0 if life['group'] and groups.is_member(life, life['group'], target_id): _hard_trust += 1 for memory in lfe.get_memory(life, matches={'target': target_id, 'trust': '*'}): _soft_trust += memory['trust'] _total_trust = _hard_trust+_soft_trust if _hard_trust: _total_trust = bad_numbers.clip(_total_trust, _hard_trust, 10) return _total_trust
def draw_event(): _event = None for event in EVENTS: if not event['delay']: _event = event break if not _event: return False locks.unlock('camera_free') gfx.camera_track(_event['pos']) if len(event['text'])>=MAP_WINDOW_SIZE[0]-1: _lines = list(_event['text'].partition(',')) if not len(_lines[1]): _lines = list(_event['text'].partition('.')) if len(_lines[1]): _lines.pop(1) else: lines = ['????'] else: _lines = [_event['text']] for line in _lines: if len(line)>=MAP_WINDOW_SIZE[0]-1: _lines = ['The most annoying error.'] break _i = 0 for line in _lines: _half = len(line)/2 _x = bad_numbers.clip((MAP_WINDOW_SIZE[0]/2)-_half, 0, MAP_WINDOW_SIZE[0]-len(line)-1) gfx.blit_string(_x, 10+_i, line, 'overlay') _i += 1 return True
def create_fire(pos, intensity=1): intensity = bad_numbers.clip(intensity, 1, 8) if not tiles.get_raw_tile(tiles.get_tile(pos))['burnable']: return False if tiles.get_flag(tiles.get_tile(pos), 'burnt'): return False _effect = {'type': 'fire', 'color': tcod.Color(255, 69, 0), 'pos': list(pos), 'intensity': intensity, 'callback': calculate_fire, 'draw_callback': draw_fire, 'unregister_callback': delete_fire} register_effect(_effect)
def generate_effects(size): _current_weather = WORLD_INFO['real_time_of_day'] / ( WORLD_INFO['length_of_day'] / len(WORLD_INFO['weather']['colors'])) _current_weather = bad_numbers.clip( _current_weather, 0, len(WORLD_INFO['weather']['colors']) - 1) if 'raining' in WORLD_INFO['weather']['colors'][_current_weather][ 'effects']: rain(size) if 'lightning' in WORLD_INFO['weather']['colors'][_current_weather][ 'effects'] and not random.randint(0, 200): RGB_LIGHT_BUFFER[0] -= 155 RGB_LIGHT_BUFFER[1] -= 155 RGB_LIGHT_BUFFER[2] -= 155 RGB_LIGHT_BUFFER[0] = RGB_LIGHT_BUFFER[0].clip(0, 255) RGB_LIGHT_BUFFER[1] = RGB_LIGHT_BUFFER[1].clip(0, 255) RGB_LIGHT_BUFFER[2] = RGB_LIGHT_BUFFER[2].clip(0, 255)