# Copyright (c) 1997-2003 Cabochon Technologies, Inc. All rights reserved. """Stops monsters from attacking. Author: Rhialto """ from wyvern.lib import Monster, Direction, HookCallback, Search from wyvern.lib.classes.magic import Spell from wyvern.lib.predicates import NameMatchPredicate, ThisObjectPredicate class pacify(Spell, HookCallback): def start(self): agent = self.getAgent() if not agent: return if not agent.getMap(): return # see if target specified by name name = self.getTargetName() if name is not None: p = NameMatchPredicate(name) self.target = Search.findNeighbor(agent, p) if self.target is None: agent.message(name + ' is not here.') return # find an attacker to pacify else: self.target = self.findAttacker(agent) if self.target is None: # message? return if self.target.hasProperty("golem") or \ self.target.hasProperty("undead"): agent.message('You cannot pacify that.') return self.target.removeProperty("@hunt") if agent.getProperty("@hunt") == self.target: agent.removeProperty("@hunt") self.target.stop() self.target.setProperty("ai-temper", "neutral") self.target.removeProperty("hates") self.target.start() # need to stifle the automatic attack-backs agent.addHook(self, "killPreHook") agent.addHook(self, "attackPreHook") self.target.addHook(self, "killPreHook") self.target.addHook(self, "attackPreHook") # this spell is a bit fragile - just stopping the next # attack on each side doesn't always do it. self.count = 3 self.notified = 0 # only tell player they stopped once # look for an adjacent monster to pacify def findAttacker(self, agent): mon = agent.getProperty("@hunt") p = ThisObjectPredicate(mon) return Search.findNeighbor(agent, p) # hook the attack/kill events and veto them def hookEvent(self, hookName, event): attacker = event.getAgent() defender = event.getTarget() # only stop caster from attacking that monster if attacker == self.getAgent(): if defender == self.target: if self.notified == 0: event.veto('You stop attacking ' + str(defender) + '.') self.notified = 1 else: event.veto(None) # stop monster from attacking anybody if attacker == self.target: event.veto('You feel friendly towards ' + str(defender) + '.') # stop N attacks to make sure combat ceases self.count = self.count - 1 if self.count <= 0: attacker.removeHook(self, "killPreHook") attacker.removeHook(self, "attackPreHook") defender.removeHook(self, "killPreHook") defender.removeHook(self, "attackPreHook") attacker.removeProperty("@hunt") defender.removeProperty("@hunt") def __repr__(self): return 'pacify spell' def toString(self): return self.__repr__() |