# 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
|