# 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__()
|