def delete_item(item): if item['uid'] in ITEMS and item['owner'] and item['uid'] in LIFE[item['owner']]['inventory']: life.remove_item_from_inventory(LIFE[item['owner']], item['uid']) logging.debug('Deleting references to item %s' % item['uid']) for _life in [LIFE[i] for i in LIFE]: if item['uid'] in _life['know_items']: alife.brain.offload_remembered_item(_life, item['uid']) alife.survival.remove_item_from_needs(_life, item['uid']) del _life['know_items'][item['uid']] _life['known_items_type_cache'][item['type']].remove(item['uid']) logging.debug('\tDeleted reference in life #%s' % _life['id']) timers.remove_by_owner(item) remove_from_chunk(item) if gfx.position_is_in_frame(item['pos']): gfx.refresh_view_position(item['pos'][0]-CAMERA_POS[0], item['pos'][1]-CAMERA_POS[1], 'map') cache.offload_item(item) if item['uid'] in ACTIVE_ITEMS: ACTIVE_ITEMS.remove(item['uid']) del ITEMS[item['uid']]
def delete_item(item): if item['uid'] in ITEMS and item['owner'] and item['uid'] in LIFE[ item['owner']]['inventory']: life.remove_item_from_inventory(LIFE[item['owner']], item['uid']) logging.debug('Deleting references to item %s' % item['uid']) for _life in [LIFE[i] for i in LIFE]: if item['uid'] in _life['know_items']: alife.brain.offload_remembered_item(_life, item['uid']) alife.survival.remove_item_from_needs(_life, item['uid']) del _life['know_items'][item['uid']] _life['known_items_type_cache'][item['type']].remove(item['uid']) logging.debug('\tDeleted reference in life #%s' % _life['id']) timers.remove_by_owner(item) remove_from_chunk(item) if gfx.position_is_in_frame(item['pos']): gfx.refresh_view_position(item['pos'][0] - CAMERA_POS[0], item['pos'][1] - CAMERA_POS[1], 'map') cache.offload_item(item) if item['uid'] in ACTIVE_ITEMS: ACTIVE_ITEMS.remove(item['uid']) del ITEMS[item['uid']]
def conditions(life, alife_seen, alife_not_seen, targets_seen, targets_not_seen, source_map): RETURN_VALUE = STATE_UNCHANGED _mode = None if lfe.execute_raw(life, 'state', 'combat'): _mode = 'combat' if not _mode and lfe.execute_raw(life, 'state', 'hunt'): _mode = 'hunt' if not _mode: return False if not lfe.execute_raw(life, 'combat', 'ranged') and not lfe.execute_raw(life, 'combat', 'melee'): return False if not life['state'] == STATE: life['state_flags'] = {} stats.battle_cry(life) if gfx.position_is_in_frame(life['pos']) and SETTINGS['controlling']: _can_see = sight.can_see_position(life, LIFE[SETTINGS['controlling']]['pos']) if _can_see: _knows = brain.knows_alife_by_id(life, SETTINGS['controlling']) if _knows and judgement.can_trust(life, SETTINGS['controlling']): if lfe.ticker(life, 'enter_combat_message', 3, fire=True): logic.show_event('%s readies up.' % ' '.join(life['name']), life=life) RETURN_VALUE = STATE_CHANGE brain.flag(life, 'combat_mode', value=_mode) return RETURN_VALUE
def create_smoke_cloud(pos, size, color=tcod.gray, age=0, factor_distance=False): if not gfx.position_is_in_frame(pos): return False for new_pos in render_los.draw_circle(pos[0], pos[1], size): if not gfx.position_is_in_frame(new_pos): continue maps.load_cluster_at_position_if_needed(new_pos) if not alife.sight._can_see_position(pos, new_pos, distance=False): continue _age_mod = 1 if factor_distance: _age_mod = 1-bad_numbers.clip(bad_numbers.distance(pos, new_pos)/float(size), 0.1, 1) create_smoke(new_pos, color=color, age=age*_age_mod)
def create_smoke_cloud(pos, size, color=tcod.gray, age=0, factor_distance=False): if not gfx.position_is_in_frame(pos): return False for new_pos in render_los.draw_circle(pos[0], pos[1], size): if not gfx.position_is_in_frame(new_pos): continue maps.load_cluster_at_position_if_needed(new_pos) if not alife.sight._can_see_position(pos, new_pos, distance=False): continue _age_mod = 1 if factor_distance: _age_mod = 1 - bad_numbers.clip( bad_numbers.distance(pos, new_pos) / float(size), 0.1, 1) create_smoke(new_pos, color=color, age=age * _age_mod)
def process_smoke(smoke): if smoke['disappear']: smoke['intensity'] -= smoke['decay'] else: if smoke['intensity'] < smoke['max_intensity']: smoke['intensity'] += smoke['grow'] else: smoke['disappear'] = True if smoke['intensity'] < 0 and smoke['disappear']: unregister_effect(smoke) return False if smoke['interp_wind']: smoke['velocity'] = numbers.lerp_velocity(smoke['velocity'], weather.get_wind_velocity(), 0.05) smoke['float_pos'][0] += smoke['velocity'][0] smoke['float_pos'][1] += smoke['velocity'][1] _in_frame = gfx.position_is_in_frame(smoke['pos']) _old_pos = smoke['pos'][:2] if _in_frame: gfx.refresh_view_position(smoke['pos'][0] - CAMERA_POS[0], smoke['pos'][1] - CAMERA_POS[1], 'map') EFFECT_MAP[smoke['pos'][0]][smoke['pos'][1]].remove(smoke['id']) smoke['pos'] = [ int(round(smoke['float_pos'][0])), int(round(smoke['float_pos'][1])) ] if _in_frame and not smoke['pos'] == _old_pos: gfx.refresh_view_position(smoke['pos'][0] - CAMERA_POS[0], smoke['pos'][1] - CAMERA_POS[1], 'map') if smoke['pos'][0] < 0 or smoke['pos'][1] < 0 or smoke['pos'][ 0] >= MAP_SIZE[0] - 1 or smoke['pos'][1] >= MAP_SIZE[1] - 1: unregister_effect(smoke, remove_from_effect_map=False) return False EFFECT_MAP[smoke['pos'][0]][smoke['pos'][1]].append(smoke['id'])
def conditions(life, alife_seen, alife_not_seen, targets_seen, targets_not_seen, source_map): RETURN_VALUE = STATE_UNCHANGED _mode = None if lfe.execute_raw(life, 'state', 'combat'): _mode = 'combat' if not _mode and lfe.execute_raw(life, 'state', 'hunt'): _mode = 'hunt' if not _mode: return False if not lfe.execute_raw(life, 'combat', 'ranged') and not lfe.execute_raw( life, 'combat', 'melee'): return False if not life['state'] == STATE: life['state_flags'] = {} stats.battle_cry(life) if gfx.position_is_in_frame(life['pos']) and SETTINGS['controlling']: _can_see = sight.can_see_position( life, LIFE[SETTINGS['controlling']]['pos']) if _can_see: _knows = brain.knows_alife_by_id(life, SETTINGS['controlling']) if _knows and judgement.can_trust(life, SETTINGS['controlling']): if lfe.ticker(life, 'enter_combat_message', 3, fire=True): logic.show_event('%s readies up.' % ' '.join(life['name']), life=life) RETURN_VALUE = STATE_CHANGE brain.flag(life, 'combat_mode', value=_mode) return RETURN_VALUE
def process_smoke(smoke): if smoke['disappear']: smoke['intensity'] -= smoke['decay'] else: if smoke['intensity'] < smoke['max_intensity']: smoke['intensity'] += smoke['grow'] else: smoke['disappear'] = True if smoke['intensity'] < 0 and smoke['disappear']: unregister_effect(smoke) return False if smoke['interp_wind']: smoke['velocity'] = numbers.lerp_velocity(smoke['velocity'], weather.get_wind_velocity(), 0.05) smoke['float_pos'][0] += smoke['velocity'][0] smoke['float_pos'][1] += smoke['velocity'][1] _in_frame = gfx.position_is_in_frame(smoke['pos']) _old_pos = smoke['pos'][:2] if _in_frame: gfx.refresh_view_position(smoke['pos'][0]-CAMERA_POS[0], smoke['pos'][1]-CAMERA_POS[1], 'map') EFFECT_MAP[smoke['pos'][0]][smoke['pos'][1]].remove(smoke['id']) smoke['pos'] = [int(round(smoke['float_pos'][0])), int(round(smoke['float_pos'][1]))] if _in_frame and not smoke['pos'] == _old_pos: gfx.refresh_view_position(smoke['pos'][0]-CAMERA_POS[0], smoke['pos'][1]-CAMERA_POS[1], 'map') if smoke['pos'][0]<0 or smoke['pos'][1]<0 or smoke['pos'][0]>=MAP_SIZE[0]-1 or smoke['pos'][1]>=MAP_SIZE[1]-1: unregister_effect(smoke, remove_from_effect_map=False) return False EFFECT_MAP[smoke['pos'][0]][smoke['pos'][1]].append(smoke['id'])
def clear_effect(effect): if gfx.position_is_in_frame(effect['pos']): gfx.refresh_view_position(effect['pos'][0] - CAMERA_POS[0], effect['pos'][1] - CAMERA_POS[1], 'map')
def tick_item(item): _z_max = bad_numbers.clip(item['pos'][2], 0, MAP_SIZE[2]-1) if item['type'] == 'bullet': _gravity = 0 else: _gravity = item['gravity'] if not is_moving(item): return False _x = item['pos'][0] _y = item['pos'][1] _break = False item['realpos'][0] += item['velocity'][0] item['realpos'][1] += item['velocity'][1] _line = drawing.diag_line(item['pos'], (int(round(item['realpos'][0])),int(round(item['realpos'][1])))) #Refresh even if we're not moving far enough to switch tiles if gfx.position_is_in_frame((_x, _y)): gfx.refresh_view_position(_x-CAMERA_POS[0], _y-CAMERA_POS[1], 'map') if not _line: item['velocity'][2] -= _gravity item['realpos'][2] = item['realpos'][2]+item['velocity'][2] item['pos'][2] = int(round(item['realpos'][2])) if maps.is_oob(item['pos']): delete_item(item) return False _z_min = bad_numbers.clip(int(round(item['realpos'][2])), 0, MAP_SIZE[2]-1) collision_with_solid(item, [int(round(item['realpos'][0])), int(round(item['realpos'][1])), _z_min]) for pos in _line: item['realpos'][2] += item['velocity'][2] if _gravity: item['velocity'][2] -= item['velocity'][2]*_gravity if 'drag' in item: _drag = item['drag'] else: _drag = item['gravity'] logging.warning('Improper use of gravity.') _min_x_vel, _min_y_vel, _max_x_vel, _max_y_vel = get_min_max_velocity(item) if abs(item['velocity'][0])<=1: item['velocity'][0] = 0.0 if abs(item['velocity'][1])<=1: item['velocity'][1] = 0.0 if not is_moving(item): if item['type'] == 'bullet': delete_item(item) return False item['velocity'][0] -= bad_numbers.clip(item['velocity'][0]*_drag, _min_x_vel, _max_x_vel) item['velocity'][1] -= bad_numbers.clip(item['velocity'][1]*_drag, _min_y_vel, _max_y_vel) item['speed'] -= bad_numbers.clip(item['speed']*_drag, 0, 100) if maps.is_oob((pos[0], pos[1], int(round(item['realpos'][2])))) or maps.is_oob(item['realpos']): delete_item(item) return False #TODO: Don't just stop the object collision_with_solid(item, (pos[0], pos[1], int(round(item['realpos'][2])))) tick_effects(item) #TODO: Don't do this here... maybe a callback or something if item['type'] == 'bullet': for _life in [LIFE[i] for i in LIFE]: if not _life['online']: continue if _life['id'] == item['shot_by'] or _life['dead']: continue if _life['pos'][0] == pos[0] and _life['pos'][1] == pos[1] and _life['pos'][2] == int(round(item['realpos'][2])): remove_from_chunk(item) item['pos'] = [pos[0],pos[1],_life['pos'][2]] add_to_chunk(item) life.damage_from_item(_life, item) if item['uid'] in ITEMS: delete_item(item) return False #if _break: # break #_z_min = bad_numbers.clip(int(round(item['realpos'][2])), 0, MAP_SIZE[2]-1) #if collision_with_solid(item, [pos[0], pos[1], _z_min]): # #_break = True # break #create_effects(item, pos, item['realpos'][2], _z_min) remove_from_chunk(item) if _break: item['pos'][0] = int(pos[0]) item['pos'][1] = int(pos[1]) item['pos'][2] = int(round(item['realpos'][2])) else: item['pos'][0] = int(round(item['realpos'][0])) item['pos'][1] = int(round(item['realpos'][1])) item['pos'][2] = int(round(item['realpos'][2])) add_to_chunk(item) _x = item['pos'][0] _y = item['pos'][1] if gfx.position_is_in_frame((_x, _y)): gfx.refresh_view_position(_x-CAMERA_POS[0], _y-CAMERA_POS[1], 'map') if maps.is_oob(item['pos']): delete_item(item) return False _min_x_vel, _min_y_vel, _max_x_vel, _max_y_vel = get_min_max_velocity(item) if abs(item['velocity'][0])<.35: item['velocity'][0] = 0.0 if abs(item['velocity'][1])<.35: item['velocity'][1] = 0.0 #TODO: This isn't gravity... if 'drag' in item: _drag = item['drag'] else: _drag = item['gravity'] logging.warning('Improper use of gravity.') item['velocity'][0] -= bad_numbers.clip(item['velocity'][0]*_drag, _min_x_vel, _max_x_vel) item['velocity'][1] -= bad_numbers.clip(item['velocity'][1]*_drag, _min_y_vel, _max_y_vel) item['speed'] -= bad_numbers.clip(item['speed']*_drag, 0, 100)
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 bad_numbers.distance( #TODO: Dirty hack for life_id in LIFE: _limbs = LIFE[life_id]['body'].keys() if not _limbs: continue _force = bad_numbers.clip((item['damage']['force']*2)-bad_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 = bad_numbers.direction_to(item['pos'], LIFE[life_id]['pos']) #TODO: Intelligent(?) limb groups? _distance = bad_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=bad_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 = bad_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 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 bad_numbers.distance( #TODO: Dirty hack for life_id in LIFE: _limbs = LIFE[life_id]['body'].keys() if not _limbs: continue _force = bad_numbers.clip( (item['damage']['force'] * 2) - bad_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 = bad_numbers.direction_to(item['pos'], LIFE[life_id]['pos']) #TODO: Intelligent(?) limb groups? _distance = bad_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=bad_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 = bad_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_item(item): if 'CAN_BURN' in item['flags'] and item['burning'] and item['owner']: life.burn(LIFE[item['owner']], item['burning']) if 'stored_in' in item or is_item_owned(item['uid']): return False _z_max = numbers.clip(item['pos'][2], 0, maputils.get_map_size(WORLD_INFO['map'])[2]-1) if item['velocity'][:2] == [0.0, 0.0] and WORLD_INFO['map'][item['pos'][0]][item['pos'][1]][_z_max]: return False _x = item['pos'][0] _y = item['pos'][1] #_view = gfx.get_view_by_name('map') #if 0<=_x<_view['draw_size'][0] and 0<=_y<_view['draw_size'][1]: if gfx.position_is_in_frame((_x, _y)): gfx.refresh_view_position(_x-CAMERA_POS[0], _y-CAMERA_POS[1], 'map') item['realpos'][0] += item['velocity'][0] item['realpos'][1] += item['velocity'][1] _break = False _line = drawing.diag_line(item['pos'],(int(round(item['realpos'][0])),int(round(item['realpos'][1])))) if not _line: item['velocity'][2] -= item['gravity'] item['realpos'][2] = item['realpos'][2]+item['velocity'][2] item['pos'][2] = int(round(item['realpos'][2])) if item['pos'][0]<0 or item['pos'][0]>=MAP_SIZE[0] or item['pos'][1]<0 or item['pos'][1]>=MAP_SIZE[1]: delete_item(item) return False _z_min = numbers.clip(int(round(item['realpos'][2])), 0, maputils.get_map_size(WORLD_INFO['map'])[2]-1) if collision_with_solid(item, [item['pos'][0], item['pos'][1], _z_min]): pos = item['pos'][:] _break = True create_effects(item, item['pos'], item['realpos'][2], _z_min) for pos in _line: item['realpos'][2] += item['velocity'][2] item['velocity'][2] -= item['velocity'][2]*item['gravity'] if 'drag' in item: _drag = item['drag'] else: _drag = item['gravity'] logging.warning('Improper use of gravity.') _min_x_vel, _min_y_vel, _max_x_vel, _max_y_vel = get_min_max_velocity(item) if 0<item['velocity'][0]<0.1 or -.1<item['velocity'][0]<0: item['velocity'][0] = 0 if 0<item['velocity'][1]<0.1 or -.1<item['velocity'][1]<0: item['velocity'][1] = 0 item['velocity'][0] -= numbers.clip(item['velocity'][0]*_drag, _min_x_vel, _max_x_vel) item['velocity'][1] -= numbers.clip(item['velocity'][1]*_drag, _min_y_vel, _max_y_vel) item['speed'] -= numbers.clip(item['speed']*_drag, 0, 100) if 0>pos[0] or pos[0]>=MAP_SIZE[0] or 0>pos[1] or pos[1]>=MAP_SIZE[1] or item['realpos'][2]<0 or item['realpos'][2]>=MAP_SIZE[2]-1: logging.warning('Item OOM: %s', item['uid']) delete_item(item) return False if collision_with_solid(item, [pos[0], pos[1], int(round(item['realpos'][2]))]): if item['type'] == 'bullet': effects.create_light(item['pos'], (255, 0, 0), 9, 0, fade=0.1) logging.debug('Item #%s hit a wall.' % item['uid']) return False if item['type'] == 'bullet': for _life in [LIFE[i] for i in LIFE]: if _life['id'] == item['shot_by'] or _life['dead']: continue if _life['pos'][0] == pos[0] and _life['pos'][1] == pos[1] and _life['pos'][2] == int(round(item['realpos'][2])): remove_from_chunk(item) item['pos'] = [pos[0],pos[1],_life['pos'][2]] add_to_chunk(item) life.damage_from_item(_life,item,60) if item['uid'] in ITEMS: delete_item(item) return False if _break: break #_z_max = numbers.clip(int(round(item['realpos'][2]))+1, 0, maputils.get_map_size(WORLD_INFO['map'])[2]-1) #if MAP[pos[0]][pos[1]][_z_max]: # item['velocity'][0] = 0 # item['velocity'][1] = 0 # item['velocity'][2] = 0 # item['pos'] = [pos[0],pos[1],item['pos'][2]-1] # # print 'LANDED',item['pos'] # _break = True # break _z_min = numbers.clip(int(round(item['realpos'][2])), 0, maputils.get_map_size(WORLD_INFO['map'])[2]-1) if collision_with_solid(item, [pos[0], pos[1], _z_min]): _break = True break create_effects(item, pos, item['realpos'][2], _z_min) remove_from_chunk(item) if _break: item['pos'][0] = int(pos[0]) item['pos'][1] = int(pos[1]) item['pos'][2] = int(round(item['realpos'][2])) else: item['pos'][0] = int(round(item['realpos'][0])) item['pos'][1] = int(round(item['realpos'][1])) item['pos'][2] = int(round(item['realpos'][2])) add_to_chunk(item) _x = item['pos'][0] _y = item['pos'][1] if gfx.position_is_in_frame((_x, _y)): gfx.refresh_view_position(_x-CAMERA_POS[0], _y-CAMERA_POS[1], 'map') if item['pos'][0] < 0 or item['pos'][0] > MAP_SIZE[0] \ or item['pos'][1] < 0 or item['pos'][1] > MAP_SIZE[1]: delete_item(item) return False #elif _break: # maps.refresh_chunk(life.get_current_chunk_id(item)) _min_x_vel, _min_y_vel, _max_x_vel, _max_y_vel = get_min_max_velocity(item) if 0<item['velocity'][0]<0.1 or -.1<item['velocity'][0]<0: item['velocity'][0] = 0 if 0<item['velocity'][1]<0.1 or -.1<item['velocity'][1]<0: item['velocity'][1] = 0 #TODO: This isn't gravity... if 'drag' in item: _drag = item['drag'] else: _drag = item['gravity'] logging.warning('Improper use of gravity.') item['velocity'][0] -= numbers.clip(item['velocity'][0]*_drag, _min_x_vel, _max_x_vel) item['velocity'][1] -= numbers.clip(item['velocity'][1]*_drag, _min_y_vel, _max_y_vel) item['speed'] -= numbers.clip(item['speed']*_drag, 0, 100)
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'] = bad_numbers.clip( life['recoil'] + (weapon['recoil'] * get_stance_recoil_mod(life)), 0.0, 1.0) _bullet_direction = bad_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 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 clear_effect(effect): if gfx.position_is_in_frame(effect['pos']): gfx.refresh_view_position(effect['pos'][0]-CAMERA_POS[0], effect['pos'][1]-CAMERA_POS[1], 'map')
def tick_item(item): _z_max = bad_numbers.clip(item['pos'][2], 0, MAP_SIZE[2] - 1) if item['type'] == 'bullet': _gravity = 0 else: _gravity = item['gravity'] if not is_moving(item): return False _x = item['pos'][0] _y = item['pos'][1] _break = False item['realpos'][0] += item['velocity'][0] item['realpos'][1] += item['velocity'][1] _line = drawing.diag_line( item['pos'], (int(round(item['realpos'][0])), int(round(item['realpos'][1])))) #Refresh even if we're not moving far enough to switch tiles if gfx.position_is_in_frame((_x, _y)): gfx.refresh_view_position(_x - CAMERA_POS[0], _y - CAMERA_POS[1], 'map') if not _line: item['velocity'][2] -= _gravity item['realpos'][2] = item['realpos'][2] + item['velocity'][2] item['pos'][2] = int(round(item['realpos'][2])) if maps.is_oob(item['pos']): delete_item(item) return False _z_min = bad_numbers.clip(int(round(item['realpos'][2])), 0, MAP_SIZE[2] - 1) collision_with_solid(item, [ int(round(item['realpos'][0])), int(round(item['realpos'][1])), _z_min ]) for pos in _line: item['realpos'][2] += item['velocity'][2] if _gravity: item['velocity'][2] -= item['velocity'][2] * _gravity if 'drag' in item: _drag = item['drag'] else: _drag = item['gravity'] logging.warning('Improper use of gravity.') _min_x_vel, _min_y_vel, _max_x_vel, _max_y_vel = get_min_max_velocity( item) if abs(item['velocity'][0]) <= 1: item['velocity'][0] = 0.0 if abs(item['velocity'][1]) <= 1: item['velocity'][1] = 0.0 if not is_moving(item): if item['type'] == 'bullet': delete_item(item) return False item['velocity'][0] -= bad_numbers.clip(item['velocity'][0] * _drag, _min_x_vel, _max_x_vel) item['velocity'][1] -= bad_numbers.clip(item['velocity'][1] * _drag, _min_y_vel, _max_y_vel) item['speed'] -= bad_numbers.clip(item['speed'] * _drag, 0, 100) if maps.is_oob((pos[0], pos[1], int(round( item['realpos'][2])))) or maps.is_oob(item['realpos']): delete_item(item) return False #TODO: Don't just stop the object collision_with_solid(item, (pos[0], pos[1], int(round(item['realpos'][2])))) tick_effects(item) #TODO: Don't do this here... maybe a callback or something if item['type'] == 'bullet': for _life in [LIFE[i] for i in LIFE]: if not _life['online']: continue if _life['id'] == item['shot_by'] or _life['dead']: continue if _life['pos'][0] == pos[0] and _life['pos'][ 1] == pos[1] and _life['pos'][2] == int( round(item['realpos'][2])): remove_from_chunk(item) item['pos'] = [pos[0], pos[1], _life['pos'][2]] add_to_chunk(item) life.damage_from_item(_life, item) if item['uid'] in ITEMS: delete_item(item) return False #if _break: # break #_z_min = bad_numbers.clip(int(round(item['realpos'][2])), 0, MAP_SIZE[2]-1) #if collision_with_solid(item, [pos[0], pos[1], _z_min]): # #_break = True # break #create_effects(item, pos, item['realpos'][2], _z_min) remove_from_chunk(item) if _break: item['pos'][0] = int(pos[0]) item['pos'][1] = int(pos[1]) item['pos'][2] = int(round(item['realpos'][2])) else: item['pos'][0] = int(round(item['realpos'][0])) item['pos'][1] = int(round(item['realpos'][1])) item['pos'][2] = int(round(item['realpos'][2])) add_to_chunk(item) _x = item['pos'][0] _y = item['pos'][1] if gfx.position_is_in_frame((_x, _y)): gfx.refresh_view_position(_x - CAMERA_POS[0], _y - CAMERA_POS[1], 'map') if maps.is_oob(item['pos']): delete_item(item) return False _min_x_vel, _min_y_vel, _max_x_vel, _max_y_vel = get_min_max_velocity(item) if abs(item['velocity'][0]) < .35: item['velocity'][0] = 0.0 if abs(item['velocity'][1]) < .35: item['velocity'][1] = 0.0 #TODO: This isn't gravity... if 'drag' in item: _drag = item['drag'] else: _drag = item['gravity'] logging.warning('Improper use of gravity.') item['velocity'][0] -= bad_numbers.clip(item['velocity'][0] * _drag, _min_x_vel, _max_x_vel) item['velocity'][1] -= bad_numbers.clip(item['velocity'][1] * _drag, _min_y_vel, _max_y_vel) item['speed'] -= bad_numbers.clip(item['speed'] * _drag, 0, 100)