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