def get_accuracy(life, weapon_uid, limb=None): weapon = ITEMS[weapon_uid] _accuracy = weapon['accuracy'] _accuracy *= alife.stats.get_firearm_accuracy(life) if limb: _stability = lfe.get_limb_stability(life, limb) _accuracy *= _stability if 'player' in life: if _stability <= 0: gfx.message('Your %s is useless.' % limb, style='damage') return 0 elif _stability <= .25: gfx.message('Your %s is nearly useless!' % limb, style='damage') lfe.add_wound(life, limb, pain=2) elif _stability <= .55: gfx.message('You feel a sharp pain in your %s!' % limb, style='damage') lfe.add_wound(life, limb, pain=1) elif _stability <= .75: gfx.message('Your %s stings from the recoil.' % limb, style='damage') if life['stance'] == 'standing': _accuracy *= 0.7 elif life['stance'] == 'crouching': _accuracy *= 0.9 elif life['stance'] == 'crawling': _accuracy *= 1 return _accuracy
def get_accuracy(life, weapon_uid, limb=None): weapon = ITEMS[weapon_uid] _accuracy = 3 * weapon['accuracy'] _accuracy *= alife.stats.get_firearm_accuracy(life) if limb: _stability = lfe.get_limb_stability(life, limb) _accuracy *= _stability if 'player' in life: if _stability <= 0: gfx.message('Your %s is useless.' % limb, style='damage') return 0 elif _stability <= .25: gfx.message('Your %s is nearly useless!' % limb, style='damage') lfe.add_wound(life, limb, pain=2) elif _stability <= .55: gfx.message('You feel a sharp pain in your %s!' % limb, style='damage') lfe.add_wound(life, limb, pain=1) elif _stability <= .75: gfx.message('Your %s stings from the recoil.' % limb, style='damage') if life['stance'] == 'standing': _accuracy *= 0.7 elif life['stance'] == 'crouching': _accuracy *= 0.9 elif life['stance'] == 'crawling': _accuracy *= 1 return _accuracy
def help_player(situation): _player = LIFE[SETTINGS['controlling']] if not situation['armed']: _spawn_pos = spawns.get_spawn_point_around(_player['pos'], min_area=50, area=125) _group = spawns.generate_group('bandit', amount=1, spawn_chunks=[alife.chunks.get_chunk_key_at(_spawn_pos)]) lfe.add_wound(_group[0], random.choice(['head', 'stomach']), cut=4, pain=5) for i in range(8): events.sound('radio static', 'something', _spawn_pos, 130, 180*i) core.record_intervention(3)
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 execute_scheme(): if not WORLD_INFO['scheme']: return False _event = None for event in WORLD_INFO['scheme']: if event['time'] <= WORLD_INFO['ticks']: _event = event break if not _event: return False _situation = core.get_player_situation() _player = LIFE[SETTINGS['controlling']] if 'sound' in _event: alife.noise.create(_event['pos'], _event['volume'], _event['sound'][0], _event['sound'][1]) if 'radio' in _event and _situation['has_radio']: gfx.message('%s: %s' % (_event['radio'][0], _event['radio'][1]), style='radio') if 'glitch' in _event: gfx.glitch_text(_event['glitch'], change_text_only=_event['change']) if 'life' in _event: _life = spawns.generate_life(_event['life']['type'], position=_event['life']['position'])[0] if 'injuries' in _event['life']: for limb in _event['life']['injuries']: lfe.add_wound(_life, limb, **_event['life']['injuries'][limb]) if 'group' in _event: if 'stage' in _event: alife.groups.set_stage(LIFE[_event['member']], _event['group'], _event['stage']) if _event['stage'] == STAGE_RAIDING: alife.groups.raid(LIFE[_event['member']], _event['group'], _event['flags']['chunk_key']) WORLD_INFO['scheme'].remove(_event)
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 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 bullet_hit(life, bullet, limb): _owner = LIFE[bullet["shot_by"]] _actual_limb = lfe.get_limb(life, limb) _items_to_check = [] if "player" in _owner: if bullet["aim_at_limb"] == limb: _msg = ["The round hits"] elif not limb in life["body"]: return "The round misses entirely!" else: _msg = ["The round misses slightly"] _detailed = True elif "player" in life: _msg = ["The round hits"] else: _msg = ["%s hits %s's %s" % (items.get_name(bullet), life["name"][0], limb)] for item_uid in lfe.get_items_attached_to_limb(life, limb): _items_to_check.append({"item": item_uid, "visible": True}) _item = items.get_item_from_uid(item_uid) if "storing" in _item: for item_in_container_uid in _item["storing"]: _chance_of_hitting_item = _item["capacity"] / float(_item["max_capacity"]) if random.uniform(0, 1) < _chance_of_hitting_item: break _items_to_check.append({"item": item_in_container_uid, "visible": False}) for entry in _items_to_check: _item = items.get_item_from_uid(entry["item"]) _item_damage = get_puncture_value(bullet, _item, target_structure_name=_item["name"]) _item["thickness"] = numbers.clip(_item["thickness"] - _item_damage, 0, _item["max_thickness"]) if "material" in _item and not _item["material"] == "cloth": _speed_mod = _item_damage _can_stop = True bullet["speed"] *= _speed_mod bullet["velocity"][0] *= _speed_mod bullet["velocity"][1] *= _speed_mod else: _can_stop = False if not _item["thickness"]: _msg.append(", destroying the %s" % _item["name"]) if _item["type"] == "explosive": items.explode(_item) else: items.delete_item(_item) else: if bullet["speed"] <= 1 and _can_stop: _msg.append(", lodging itself in %s" % items.get_name(_item)) _ret_string = own_language(life, _msg) if _ret_string.endswith("!"): return _ret_string else: return _ret_string + "." else: if "material" in _item: if _item["material"] == "metal": _msg.append(", puncturing the %s" % _item["name"]) else: _msg.append(", ripping through the %s" % _item["name"]) _damage = get_puncture_value(bullet, _actual_limb, target_structure_name=limb) _actual_limb["thickness"] = numbers.clip(_actual_limb["thickness"] - _damage, 0, _actual_limb["max_thickness"]) _damage_mod = 1 - (_actual_limb["thickness"] / float(_actual_limb["max_thickness"])) if limb in life["body"]: _msg.append(", " + lfe.add_wound(life, limb, cut=_damage * _damage_mod, impact_velocity=bullet["velocity"])) _ret_string = own_language(life, _msg) if _ret_string.endswith("!"): return _ret_string else: return _ret_string + "."
def bite(life, target_id, limb): logging.debug("%s bit %s in the %s." % (" ".join(life["name"]), " ".join(LIFE[target_id]["name"]), limb)) target = LIFE[target_id] _msg = ["%s" % language.get_introduction(life)] _bite_strength = random.randint(1, 3) if numbers.distance(life["pos"], target["pos"]) > 1: _msg.append("bites the air") return " ".join(_msg) + "." _items_to_check = [] for _item in lfe.get_items_attached_to_limb(target, limb): _items_to_check.append({"item": _item, "visible": True}) _actual_item = items.get_item_from_uid(_item) if "storing" in _actual_item: for _item_in_container in _actual_item["storing"]: _items_to_check.append({"item": _item_in_container, "visible": False}) for entry in _items_to_check: _item = items.get_item_from_uid(entry["item"]) if not "thickness" in _item: logging.warning("Item '%s' has no set thickness. Guessing..." % _item["name"]) _item["thickness"] = _item["size"] / 2 _thickness = _item["thickness"] _item["thickness"] = numbers.clip(_item["thickness"] - _bite_strength, 0, 100) _bite_strength -= _thickness _tear = _item["thickness"] - _thickness _limb_in_context = False if _item["material"] == "cloth": if _thickness and not _item["thickness"]: _msg.append("rips through <own> %s" % _item["name"]) elif _tear <= -3: _msg.append("rips <own> %s" % _item["name"]) elif _tear <= -2: _msg.append("tears <own> %s" % _item["name"]) elif _tear <= -1: _msg.append("slightly tears <own> %s" % _item["name"]) if _bite_strength <= 0 and _item["thickness"]: _msg.append("is stopped by <own> %s" % _item["name"]) return " ".join(_msg) # if not lfe.limb_is_cut(target, limb): if _bite_strength == 1: _msg.append(", cutting <own> %s" % limb) elif _bite_strength == 2: _msg.append(", tearing <own> %s" % limb) elif _bite_strength == 3: _msg.append(", ripping open <own> %s" % limb) if _bite_strength: lfe.add_wound(target, limb, cut=_bite_strength) # TODO: How thick is skin? _bite_strength -= 1 # if not _bite_strength: # return ' '.join(_msg) _ret_string = own_language(target, _msg) return _ret_string + "."
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 bullet_hit(life, bullet, limb): _owner = LIFE[bullet['shot_by']] _actual_limb = lfe.get_limb(life, limb) if 'player' in _owner: if bullet['aim_at_limb'] == limb: _msg = ['The round hits'] elif not limb in life['body']: return 'The round misses entirely!' else: _msg = ['The round misses slightly'] _detailed = True else: _msg = ['%s shoots' % language.get_name(_owner)] _items_to_check = [] for item_uid in lfe.get_items_attached_to_limb(life, limb): _items_to_check.append({'item': item_uid, 'visible': True}) _item = items.get_item_from_uid(item_uid) if 'storing' in _item: for item_in_container_uid in _item['storing']: print '*' * 100 _chance_of_hitting_item = bullet['size']*(_item['capacity']/float(_item['max_capacity'])) print 'percent chance of hitting item:', 1-_chance_of_hitting_item if random.uniform(0, 1)<_chance_of_hitting_item: continue _items_to_check.append({'item': item_in_container_uid, 'visible': False}) for entry in _items_to_check: _item = items.get_item_from_uid(entry['item']) _item_damage = get_puncture_value(bullet, _item, target_structure_name=_item['name']) _item['thickness'] = numbers.clip(_item['thickness']-_item_damage, 0, _item['max_thickness']) _speed_mod = _item_damage bullet['speed'] *= _speed_mod bullet['velocity'][0] *= _speed_mod bullet['velocity'][1] *= _speed_mod if not _item['thickness']: _msg.append(', destroying the %s' % _item['name']) if _item['type'] == 'explosive': items.explode(_item) else: items.delete_item(_item) else: if bullet['speed']<=1: _msg.append(', lodging itself in %s' % items.get_name(_item)) _ret_string = own_language(life, _msg) if _ret_string.endswith('!'): return _ret_string else: return _ret_string+'.' else: if 'material' in _item: if _item['material'] == 'metal': _msg.append(', puncturing the %s' % _item['name']) else: _msg.append(', ripping through the %s' % _item['name']) _damage = get_puncture_value(bullet, _actual_limb, target_structure_name=limb) _actual_limb['thickness'] = numbers.clip(_actual_limb['thickness']-_damage, 0, _actual_limb['max_thickness']) _damage_mod = 1-(_actual_limb['thickness']/float(_actual_limb['max_thickness'])) if limb in life['body']: _msg.append(', '+lfe.add_wound(life, limb, cut=_damage*_damage_mod, impact_velocity=bullet['velocity'])) #return '%s punctures %s (%s)' % (bullet['name'], limb, get_puncture_value(bullet, _actual_limb, target_structure_name=limb)) _ret_string = own_language(life, _msg) if _ret_string.endswith('!'): return _ret_string else: return _ret_string+'.'
def bite(life, target_id, limb): logging.debug('%s bit %s in the %s.' % (' '.join(life['name']), ' '.join(LIFE[target_id]['name']), limb)) target = LIFE[target_id] _msg = ['%s' % language.get_introduction(life)] _bite_strength = random.randint(1, 3) if numbers.distance(life['pos'], target['pos'])>1: _msg.append('bites the air') return ' '.join(_msg)+'.' _items_to_check = [] for _item in lfe.get_items_attached_to_limb(target, limb): _items_to_check.append({'item': _item, 'visible': True}) _actual_item = items.get_item_from_uid(_item) if 'storing' in _actual_item: for _item_in_container in _actual_item['storing']: _items_to_check.append({'item': _item_in_container, 'visible': False}) for entry in _items_to_check: _item = items.get_item_from_uid(entry['item']) if not 'thickness' in _item: logging.warning('Item \'%s\' has no set thickness. Guessing...' % _item['name']) _item['thickness'] = _item['size']/2 _thickness = _item['thickness'] _item['thickness'] = numbers.clip(_item['thickness']-_bite_strength, 0, 100) _bite_strength -= _thickness _tear = _item['thickness']-_thickness _limb_in_context = False if _item['material'] == 'cloth': if _thickness and not _item['thickness']: _msg.append('rips through <own> %s' % _item['name']) elif _tear<=-3: _msg.append('rips <own> %s' % _item['name']) elif _tear<=-2: _msg.append('tears <own> %s' % _item['name']) elif _tear<=-1: _msg.append('slightly tears <own> %s' % _item['name']) if _bite_strength <= 0 and _item['thickness']: _msg.append('is stopped by <own> %s' % _item['name']) return ' '.join(_msg) #if not lfe.limb_is_cut(target, limb): if _bite_strength==1: _msg.append(', cutting <own> %s' % limb) elif _bite_strength==2: _msg.append(', tearing <own> %s' % limb) elif _bite_strength==3: _msg.append(', ripping open <own> %s' % limb) if _bite_strength: lfe.add_wound(target, limb, cut=_bite_strength) #TODO: How thick is skin? _bite_strength -= 1 #if not _bite_strength: # return ' '.join(_msg) _ret_string = own_language(target, _msg) return _ret_string+'.'
def bullet_hit(life, bullet, limb): _owner = LIFE[bullet['shot_by']] _actual_limb = lfe.get_limb(life, limb) _items_to_check = [] _msg = [] #if 'player' in _owner: # if bullet['aim_at_limb'] == limb: # _hit = True # _msg = ['The round hits'] # elif not limb in life['body']: # return 'The round misses entirely!' # else: # _msg = ['The round misses slightly'] # _detailed = True # #elif 'player' in life: # _msg = ['The round hits'] #else: # _msg = ['%s hits %s\'s %s' % (items.get_name(bullet), life['name'][0], limb)] for item_uid in lfe.get_items_attached_to_limb(life, limb): _items_to_check.append({'item': item_uid, 'visible': True}) _item = items.get_item_from_uid(item_uid) if 'storing' in _item: for item_in_container_uid in _item['storing']: _chance_of_hitting_item = _item['capacity']/float(_item['max_capacity']) if random.uniform(0, 1)<_chance_of_hitting_item: break _items_to_check.append({'item': item_in_container_uid, 'visible': False}) for entry in _items_to_check: _item = items.get_item_from_uid(entry['item']) _item_damage = get_puncture_value(bullet, _item, target_structure_name=_item['name']) _item['thickness'] = bad_numbers.clip(_item['thickness']-_item_damage, 0, _item['max_thickness']) if 'material' in _item and not _item['material'] == 'cloth': _speed_mod = _item_damage _can_stop = True bullet['speed'] *= _speed_mod bullet['velocity'][0] *= _speed_mod bullet['velocity'][1] *= _speed_mod else: _can_stop = False if not _item['thickness']: if _item['uid'] in lfe.get_all_visible_items(life): if 'player' in _owner: _msg.append('%s\'s %s is destroyed!' % (' '.join(life['name']), _item['name'])) if _item['type'] == 'explosive': items.explode(_item) else: items.delete_item(_item) #else: # if bullet['speed']<=1 and _can_stop: # #if 'player' in _owner: # # _msg.append(', lodging itself in %s' % items.get_name(_item)) # #_ret_string = own_language(life, _msg) # # if _ret_string.endswith('!'): # return _ret_string # else: # return _ret_string+'.' # #else: # # if 'material' in _item: # # if _item['material'] == 'metal': # # _msg.append(', puncturing the %s' % _item['name']) # # else: # # _msg.append(', ripping through the %s' % _item['name']) _damage = get_puncture_value(bullet, _actual_limb, target_structure_name=limb) _actual_limb['thickness'] = bad_numbers.clip(_actual_limb['thickness']-_damage, 0, _actual_limb['max_thickness']) if not _actual_limb['thickness']: lfe.sever_limb(life, limb, (0, 0, 0)) _damage_mod = 1-(_actual_limb['thickness']/float(_actual_limb['max_thickness'])) if limb in life['body']: _msg.append(lfe.add_wound(life, limb, cut=_damage*_damage_mod, impact_velocity=bullet['velocity'])) #_ret_string = own_language(life, _msg) return ' '.join(_msg)