""" Coders Guild:  A minimal example of a Guild written in Jython.

This guild only has two abilities:

    * it gives you a special command, "write-code", that
      just issues you a congratulatory message.

    * it gives you Guild XP for slaying monsters with a Pen.

Author:  Steve Yegge, June 18th, 2003
Copyright 2003, Cabochon.
"""

from wyvern.lib import Kernel, Command
from wyvern.lib.properties import GuildSkills, JythonBean

class coders_guild(GuildSkills, JythonBean):

    # Function:  getJavaClass
    #
    # JythonBean implementation.  This is required for all Wyvern
    # bean properties implemented in Jython.  Guilds are bean props,
    # so they need this method.
    #
    # All you have to do is return the fully-qualified name of the
    # class you're extending.  This is one of the shortcomings of
    # Jython - it's not smart enough to tell Wyvern what class it's
    # extending, so we have to tell Wyvern ourselves.

    def getJavaClass(self):
        return 'wyvern.lib.properties.GuildSkills'


    # This nested class implements a simple Command, which just
    # issues you a message whe you enter the command.  It's just
    # for demonstration purposes - in a real guild, you'd provide
    # the guild member with much more interesting and complex
    # abilities (and penalties!)

    class code_command(Command):

        def knowsCommand(self, cmd):
            return cmd == 'write-code'

        def createEvent(self, initial):
            return initial

        def execute(self, event):
            member = event.getAgent()
            member.message('You are now officially a Jython coder!')
            return 1


    # Function:  startup
    #
    # Sets guild abilities for the player.  Called when player
    # first joins the guild, and every time the player logs in.
    #
    # We want to provide some sort of unique guild skill in this
    # example, but it can't be a lot of code, or it'll obscure
    # the rest of the work you have to do in order to create a
    # guild.  So our guild just gives you one extra ability:
    # a new command that you can type, 'write-code', that issues
    # you a message when you enter the command.

    def startup(self):

        # get the player we're operating on
        player = self.getAgent()
        if not player:
            return

        # Create and remember a new code_command object that
        # will handle the command for us.  We could have had
        # coders_guild implement the Command interface itself,
        # but this way illustrates that you can have helper
        # classes for your guild.  The helper classes can be
        # in Java or Jython, and can be in this file or in
        # a separate file.

        self.cmd = self.code_command()

        # register the Command with the player
        player.registerCommand('write-code', self.cmd)


    # Function:  shutdown
    #
    # Removes any guild abilities from the player.  Called when
    # the player logs out, or quits the guild.

    def shutdown(self):
        player=self.getAgent()
        if not player:  return
        player.unregisterCommand('write-code', self.cmd)


    # Function:  getGuildName
    #
    # Returns the official name for the guild, minus 'Guild'.
    # Examples, 'Paladins', 'Mages', 'Axemans', 'Archers'.

    def getGuildName(self):
        return 'Coders'

    # Function:  getGuildShortName
    #
    # Returns the short name for the guild, such as 'mage', 'paladin',
    # or 'archer'.  Used for constructing the 'tell' and 'who' commands,
    # e.g. 'guildwho', 'magetell', and various other things.

    def getGuildShortName(self):
        return 'coder'


    # Function:  getGuildPluralName
    #
    # Returns the short, plural name for the guild, such as 'Paladins'
    # or 'Axemen', used in phrases like 'There are 20 Axemen online.'.

    def getGuildPluralName(self):
        return 'Coders'


    # Function:  getGuildTitle
    #
    # Returns the generic guild title to show in the high-score list,
    # such as 'Mage' or 'Paladin'. Stored in a property on the guild
    # member called 'guild-name'.

    def getGuildTitle(self):
        return 'Coder'


    # Function:  getGuildTag
    #
    # Returns the tag-property saying which guild this person is in,
    # such as 'paladin-guild' or 'mages-guild'.  Used by guild-only
    # armor, and anything else needing to check if you're in a
    # specific guild.  It's not printed to the player, so it can be
    # pretty much anything you want, but it's usually guildname + '-guild'.

    def getGuildTag(self):
        return 'coders-guild'


    # Function:  getTitle
    #
    # Returns the Guild Title to use for the player.  Most guilds
    # have different titles depending on what guild-level you're
    # at, so we'll demonstrate how to do that.  Some guilds also
    # have different titles for male and female members.  We don't
    # do that here, but it's not difficult to add it in - you just
    # have two title-lists, and choose the right one to use based
    # on the player's gender.

    def getTitle(self, player):

        # we'll use the default XP chart from our superclass
        xp = self.getGuildXP()
        level = self.getGuildLevel ( xp )

        if level < 1: level = 1
        if level > 10: level = 10

        # levels range from 1 to 10, so our titles will range from
        # the low-end to the high-end of computer knowledge.

        titles = ["AOL User",
                  "Computer Illiterate",
                  "Computer Novice",
                  "Power User",
                  "Neophyte Coder",
                  "Developer",
                  "Software Engineer",
                  "Master Hacker",
                  "Lazy, Impatient, Hubris-ful",
                  "Emacs Guru"]

        return titles[level-1]


    # Function:  getWhoCommand
    #
    # Returns the name of the command to use for guild-who.

    def getWhoCommand(self):
        return 'coderwho'


    # Function:  getTellCommand
    #
    # Returns the name of the command to use for guild-tell.

    def getTellCommand(self):
        return 'codertell'


    # Function:  awardXP
    #
    # Return:  1 if we awarded guild XP to the player

    def awardXP(self, event):

        # per the docs above, check if the event is null
        if not event:
            return 0

        # get passed group member
        player = event.getProperty('member')
        if not player:
            return 0

        # make sure group member is in the Coders Guild
        if not player.hasProperty(self.getGuildTag()):
            return 0

        # get the player who actually killed the monster
        slayer = event.getAgent()

        # The DamageEvent only shows the weapon used by the slayer,
        # not the group member.  So we'll do it this way:
        #
        # - if the player killed the monster, award xp if Attack
        #   in the event is a pen.
        #
        # - if not, award xp if player is wielding a range weapon
        #
        # Players may notice that you can get guild XP for killing
        # a monster by wielding a sword just before the monster
        # dies (but only if someone else kills it), but I figure
        # this is will happen pretty darn rarely.

        if player is slayer:

            # get the weapon used to kill the monster
            weapon = event.getProperty('weapon')

            # check if weapon's archetype is correct
            if Kernel.isInstance(weapon, 'wiz/rhialto/misc/pen'):

                # it's a pen.  We'll award guild XP 1 for 1.
                self.adjustGuildXP(event.getIntProperty('xp'))
                return 1

            # not wielding a pen, so they lose.
            else:
                return 0

        # player was part of the group, but didn't kill the monster
        else:

            attacks = player.getProperty('@attacks')
            if not attacks:
                return 0

            for attack in attacks:
                if Kernel.isInstance(attack, 'wiz/rhialto/misc/pen'):

                    # the player was wielding a pen, so assume they
                    # were being good citizens, and award the XP.

                    self.adjustGuildXP(event.getIntProperty('xp'))
                    return 1

            # didn't find any Pens in the @attacks list => no xp award
            return 0