# Copyright (c) 1997 Cabochon Technologies, Inc. All rights reserved. """ Magically enchants a weapon. Author: rhialto, fenixdown """ from wyvern.lib import Range, Kernel, Weapon, Monster from wyvern.lib.classes.magic import Spell from wyvern.lib.predicates import ClassPredicate """ This class desperately needs to be made a subclass of enchant_armor. Not sure how to do that yet. -Rhialto """ class enchant_weapon(Spell): def start(self): target = self.get_target() if target is None or not self.enchantable(target): return if Range.percent() < self.get_destroy_chance(target): self.blow_up_weapon(self.agent, target) return self.modify_weapon(target, target.toString()) def modify_weapon(self, target, desc): if self.isCursed(): self.do_cursed_effects(target, desc) return # increment enchantment counter target.adjustIntProperty("wc-magic", 1) target.adjustIntProperty("to-hit", 1) target.adjustIntProperty("enchantment", 1) self.set_enchant_info(target) self.increase_value(target) self.upgrade_curse_level(target, desc) def get_target(self): target = self.findTargetObject() # no target specified => operate on first weapon in inv if target is None: target = self.find_first_weapon(self.agent) if target is None: self.tellCaster("Cast enchant weapon on what?") return target def set_enchant_info(self, target): target.setProperty("enchanted-by", self.agent.name) target.setProperty("enchanted-on", Kernel.getDate()) def upgrade_curse_level(self, target, desc): # remove curse. damned goes to cursed. if target.hasProperty("damned"): target.removeProperty("damned") target.addProperty("cursed") elif target.hasProperty("cursed"): target.removeProperty("cursed") # if scroll was blessed, bless the item elif self.isBlessed(): target.addProperty("blessed") target.invalidateText() self.tellCaster("Your " + desc + " glows blue for a moment.") def increase_value(self, target): # this is actually pretty close to how much people # have to pay to enchant them to the corresponding level if not target.hasProperty("groupable"): if target.value <= 0: target.setIntProperty("value", 0) else: value = target.getIntProperty('value') target.setIntProperty("value", value * 2) def do_cursed_effects(self, target, desc): # decrement enchantment counter and curse the item target.adjustIntProperty("wc-magic", -1) target.adjustIntProperty("to-hit", -1) target.adjustIntProperty("enchantment", -1) target.curse() self.tellCaster("Your %s glows with a black aura." % desc) self.reduce_value(target) def reduce_value(self, target): # don't adjust value for missiles - it's kinda gross # (numbers like 730275418) if not target.hasProperty("groupable"): if target.value <= 0: target.setIntProperty("value", 0) else: target.setIntProperty("value", target.value / 2) def enchantable(self, target): """Checks if this is an enchantable weapon. If not, issues a message to the caster and returns false. If it's enchantable, it returns true. """ if target is None: return 0 if (target.hasProperty("unique") or target.hasProperty("no-enchant") or not isinstance(target, Weapon )): self.tellCaster(`target` + " is not an enchantable weapon.") return 0 if target.quantity > 1: self.tellCaster("You can only enchant one at a time.") return 0 return 1 def get_destroy_chance(self, target): # chance the thing will blow depends on enchantment level enchant = target.getIntProperty("enchantment") chance = enchant * 20 if self.isBlessed(): chance = enchant * 15; # take into account earth and spirit chance -= self.getLevel(self.EARTH_AND_SPIRIT) return chance def find_first_weapon(self, agent): """Locates first weapon the agent is carrying.""" p = ClassPredicate(Weapon) return agent.inventory.find(p) def blow_up_weapon(self, agent, weapon): msg = self.get_destroy_message(weapon) self.tellCaster(msg) # this takes care of removing from ground or inv weapon.destroy(); if not isinstance(agent, Monster): return # hurt the user too self.setIntProperty("wc-magic", 10) self.damageMonster(self.agent, self) def get_destroy_message(self, weapon): name = weapon.toString() return ("Your " + name + " glows with a blinding white light!\n" + "Your " + name + " explodes!") def consumeReagents(self, agent): """Finds and consumes the required reagent(s). We have special reagent needs, so we do it manually. Returns true if the had the right reagents. """ if self.getMagicItem() is not None: return 1 if agent is None or agent.inventory is None: return 0 return self.find_reagent(agent) def find_reagent(self, agent): for i in agent.inventory.objects(): if self.is_usable_reagent(i): self.adjust_quantity_in_inventory(i, agent) return 1 # didn't find it return 0 def is_usable_reagent(self, obj): return (obj.value >= 1000 and Kernel.isInstance(obj, self.get_reagent_type())) def adjust_quantity_in_inventory(self, obj, agent): if obj.quantity > 1: obj.quantity = obj.quantity - 1 else: agent.inventory.remove(obj) def get_reagent_type(self): """Returns the type of gem to use as a reagent. Return: the archetype path """ return "objects/treasure/diamond" def canDamageSelf(self, caster, spell): return 1 |