def use(self, item_entity, **kwargs): results = [] item_component = item_entity.item if item_component.use_funtion is None: equipment_component = item_entity.equipment if equipment_component: results.append({"equip": item_entity}) else: results.append({ "message": Message("The {} cannot be used".format(item_entity), libtcod.yellow) }) else: if item_component.targeting and not (kwargs.get("target_x") or kwargs.get("target_y")): results.append({"targeting": item_entity}) else: kwargs = {**item_component.function_kwargs, **kwargs} item_use_results = item_component.use_funtion( self.owner, **kwargs) for item_use_result in item_use_results: if item_use_result.get("consumed"): self.remove_item(item_entity) results.extend(item_use_results) return results
def cast_lightning(*args, **kwargs): caster = args[0] entities = kwargs.get("entities") fov_map = kwargs.get("fov_map") damage = kwargs.get("damage") maximum_range = kwargs.get("maximum_range") results = [] target = None closest_distance = maximum_range + 1 for entity in entities: if entity.playable and entity != caster and libtcod.map_is_in_fov( fov_map, entity.x, entity.y): distance = caster.distance_to(entity) if distance < closest_distance: targer = entity closest_distance = distance if targer: results.append({ "consumed": True, "target": targer, "message": Message( "A ligthning bolt strikes the {} with a loud thunder! The damage is {}" .format(targer.name, damage), libtcod.orange) }) return results
def cast_confuse(*args, **kwargs): entities = kwargs.get("entities") fov_map = kwargs.get("fov_map") target_x = kwargs.get("target_x") target_y = kwargs.get("target_y") results = [] if not libtcod.map_is_in_fov(fov_map, target_x, target_y): results.append({ "consumed": False, "message": Message("You cannot target a tile outside your field of view.", libtcod.yellow) }) return results for entity in entities: if entity.x == target_x and entity.y == target_y and entity.ai: confused_ai = CofusedMonster(entity.ai, 10) confused_ai.owner = entity entity.ai = confused_ai results.append({ "consumed": True, "message": Message( "The eyes of the {} look vacant, as he stars to stuble around!" .format(entity.name), libtcod.light_green) }) break else: results.append({ "consumed": False, "message": Message("There is no targetable enemy at the location", libtcod.yellow) }) return results
def add_item(self, item): results = [] if len(self.items) >= self.capacity: results.append({ "item_added": None, "message": Message("You cannot carry any more, your inventory is full!", libtcod.yellow) }) else: results.append({ "item_added": item, "message": Message("You pick up the {}!".format(item.name), libtcod.blue) }) self.items.append(item) return results
def cast_fireball(*args, **kwargs): entities = kwargs.get("entities") fov_map = kwargs.get("fov_map") damage = kwargs.get("damage") radius = kwargs.get("radius") target_x = kwargs.get("target_x") target_y = kwargs.get("target_y") results = [] if not fov_map.fov[target_y, target_x]: results.append({ "consumed": False, "message": Message("You cannot target a tile outside your field of view.", libtcod.yellow) }) return results results.append({ "consumed": True, "message": Message( "The fireball explodes, burning everything within {} tiles!". format(radius), libtcod.orange) }) for entity in entities: if entity.distance(target_x, target_y) <= radius and entity.playable: results.append({ "message": Message( "The {} gets burned for {} hit points.".format( entity.name, damage), libtcod.orange) }) results.extend(entity.playable.take_damage(damage)) return results
def kill_monster(monster): death_message = Message("{} is dead!".format(monster.name.capitalize()), libtcod.orange) monster.color = libtcod.dark_red monster.blocks = False monster.playable = None monster.ai = None monster.name = "remains of " + monster.name monster.render_order = RenderOrder.CORPSE monster.image_name = 'dead' return death_message
def heal(*args, **kwargs): entity = args[0] amount = kwargs.get("amount") results = [] if entity.playable.hp == entity.playable.max_hp: results.append({ "consumed": False, "message": Message("You are already at full health", libtcod.yellow) }) else: entity.playable.heal(amount) results.append({ "consumed": True, "message": Message("You wounds start to feel better!", libtcod.green) }) return results
def drop_item(self, item): results = [] if self.owner.equipment.main_hand == item or self.owner.equipment.off_hand == item: results.extend(self.owener.equipment.toggle_equip(item)) item.x = self.owner.x item.y = self.owner.y self.remove_item(item) results.append({ "item_dropped": item, "message": Message("You dropped the {}".format(item.name), libtcod.white) }) return results
def take_turn(self, targer, fov_map, game_map, entities): results = [] if self.number_of_turns > 0: random_x = self.owner.x + randint(0, 2) - 1 random_y = self.owner.y + randint(0, 2) - 1 if random_x != self.owner.x and random_y != self.owner.y: self.owner.move_towards(random_x, random_y, game_map, entities) self.number_of_turns -= 1 else: self.owner.ai = self.previus_ai results.append({ "message": Message("The {} is no longer confuse".format(self.owner.name), libtcod.red) }) return results
def attack(self, target): results = [] if self.owner.equipment.main_hand != None: m_weapon: Weapon = self.owner.equipment.main_hand.weapon atk_bonus = self.get_atk_bonus(m_weapon) roll = randint(1, 20) results.append({ "message": Message("{} attack roll {}+{} vs {} AC of {}.".format( self.owner.name, atk_bonus, roll, target.playable.armor_class, target.name)) }) if atk_bonus + roll >= target.playable.armor_class: damage = 0 for i in range(0, m_weapon.dmg_quantity): d_roll = randint(1, m_weapon.weapon_dmg) modifier = self.get_modifier_bonus(m_weapon) damage += d_roll + modifier if damage > 0: results.append({ "message": Message( "{} attacks {} for {} hit points.".format( self.owner.name.capitalize(), target.name, damage), WHITE) }) results.extend(target.playable.take_damage(damage)) else: results.append({ "message": Message( "{} attacks {} but does no damage.".format( self.owner.name.capitalize(), target.name), WHITE) }) else: results.append({ "message": Message( "{} attacks {} but does no damage.".format( self.owner.name.capitalize(), target.name), WHITE) }) if self.owner.equipment.off_hand != None: o_weapon: Weapon = self.owner.equipment.off_hand.weapon atk_bonus = self.get_atk_bonus(o_weapon) roll = randint(1, 20) results.append({ "message": Message("{} attack roll {}+{} vs {} AC of {}.".format( self.owner.name, atk_bonus, roll, target.playable.armor_class, target.name)) }) if atk_bonus + roll >= target.playable.armor_class: damage = 0 for i in range(0, m_weapon.dmg_quantity): d_roll = randint(1, m_weapon.weapon_dmg) ''' TODO DULA WILDING 3 types ;/ ''' #modifier = sefl.get_modifier_bonus(m_weapon) modifier = 0 damage += d_roll + modifier if damage > 0: results.append({ "message": Message( "{} attacks {} for {} hit points.".format( self.owner.name.capitalize(), target.name, damage), WHITE) }) results.extend(target.playable.take_damage(damage)) else: results.append({ "message": Message( "{} attacks {} but does no damage.".format( self.owner.name.capitalize(), target.name), WHITE) }) else: results.append({ "message": Message( "{} attacks {} but does no damage.".format( self.owner.name.capitalize(), target.name), WHITE) }) if self.owner.equipment.main_hand == None and self.owner.equipment.off_hand == None: atk_bonus = self.owner.ability.modifaier_strenght roll = randint(1, 20) results.append({ "message": Message("{} attack roll {}+{} vs {} AC of {}.".format( self.owner.name, atk_bonus, roll, target.playable.armor_class, target.name)) }) if atk_bonus + roll >= target.playable.armor_class: ''' Instead of using a weapon to make a melee weapon attack, you can use an unarmed strike: a punch, kick, head--butt, or similar forceful blow (none of which count as weapons). On a hit, an unarmed strike deals bludgeoning damage equal to 1 + your Strength modifier. You are proficient with your unarmed strikes. ''' damage = 1 + max(self.owner.ability.modifaier_strenght, 0) if damage > 0: results.append({ "message": Message( "{} attacks {} for {} hit points.".format( self.owner.name.capitalize(), target.name, damage), WHITE) }) results.extend(target.playable.take_damage(damage)) else: results.append({ "message": Message( "{} attacks {} but does no damage.".format( self.owner.name.capitalize(), target.name), WHITE) }) else: results.append({ "message": Message( "{} attacks {} but does no damage.".format( self.owner.name.capitalize(), target.name), WHITE) }) return results
def kill_player(player): player.color = libtcod.dark_red return Message("You died!", libtcod.red), GameState.PLAYER_DEAD