The following is from a post I made inside the forum of a team making Torque game engine games when I was developing the code. This is only a very small portion of the code I developed.


I finally implemented all the features. I haven't tested it on a real server but it works right now for single player.

After

Code:

    if slot == RPG_SLOT_SECONDARY and "2H" in cursorItem.skill and not self.mob.skillLevels.get("Power Wield"):
                    self.player.sendGameText(RPG_MSG_GAME_DENIED,r'%s does not know how to <a:SkillPowerWield>power wield</a>.\n'%self.name)
                    return



add

Code:

               if cursorItem.itemProto.type != "":

                    from spell import SpellProto
                    protos = SpellProto.selectBy(type="Zombie Kit")   
                    CharacterSpell.clearTable()
                    newSlot = 0
                    for spellToLearnProto in protos: 
                        CharacterSpell(character=self,spellProto=spellToLearnProto,slot=newSlot,recast=0) 
                        newSlot += 1         
                    self.spellsDirty = True                                       
                    forceupdate = self.spells
                    # Send a sound and message to the Player.
                    self.player.mind.callRemote("playSound","sfx/Pencil_WriteOnPaper2.ogg")
                    #self.player.sendGameText(RPG_MSG_GAME_GOOD,r'%s learns <a:Spell%s>%s</a>.\n'%(self.name,GetTWikiName(spellToLearnProto.name),spellToLearnProto.name))                                   
                                       
                   
                    from mud.client.gui.macro import MACROMASTER
                    MACROMASTER.emptyMacros()
                    MACROMASTER.autoPopulate()



and replace the block of code after the comment "# Otherwise, the Player is removing an item from the slot."

Code:

    else:
            if previtem: 
                from spell import SpellProto             
                CharacterSpell.clearTable()
                self.spellsDirty = True       
                forceupdate = self.spells
               
                from mud.client.gui.macro import MACROMASTER
                MACROMASTER.emptyMacros()

                # Update player GUI to show the old item being removed.
                self.player.mind.callRemote("setItemSlot",self.id,None,slot)



Before def onMacroButtonClick(self, args): add:

Code:

    def emptyMacros(self):
        from playerSettings import PLAYERSETTINGS
        charIndex = PLAYERSETTINGS.charIndex
        visible = True
        page = 0
        slot = 0
        for page in range(0, 9):
            for slot in range(0, 9):

                # Check if there already is a macro present at the desired location.
                charMacros = self.macros.setdefault(charIndex,dict())
                oldMacro = charMacros.get((page,slot),None)
               
                # If an old macro exists we need first to clean up some stuff.
                if oldMacro:
                    # Remove the old macro from the dictionary of running macros.
                    try:
                        del self.runningMacros[charIndex][oldMacro]
                    except KeyError:
                        pass
                    # Remove the old macro from the set of recovering macros.
                    try:
                        self.recoveringMacros[charIndex].discard(oldMacro)
                    except KeyError:
                        pass
                    # Remove the old macro from the hotkey dictionary.
                    try:
                        hotkey = oldMacro.hotkey
                        if hotkey:
                            if hotkey[0] != 'F':
                                hotkey = '%i - %s'%(page,hotkey)
                            self.hotkeyDict[charIndex][hotkey].discard(oldMacro)
                    except KeyError:
                        pass
                    # Remove any connections the old macro has in the skill dictionary.
                    for skill in oldMacro.skills:
                        try:
                            self.skillDict[skill].discard(oldMacro)
                            if len(self.skillDict[skill]) == 0:
                                del self.skillDict[skill]
                        # KeyError occurs if the same macro uses the same skill more
                        #  than once and if it's the last macro using this skill.
                        except KeyError:
                            continue
                    # Remove any connections the old macro has in the spell dictionary.
                    for spell in oldMacro.spells:
                        try:
                            self.spellDict[spell].discard(oldMacro)
                            if len(self.spellDict[spell]) == 0:
                                del self.spellDict[spell]
                        # KeyError occurs if the same macro uses the same spell more
                        #  than once and if it's the last macro using this spell.
                        except KeyError:
                            continue
                    # Remove any connections the old macro has in the item dictionary.
          &nbsp;         for item in oldMacro.items:
                        try:
                            self.itemDict[item].discard(oldMacro)
                            if len(self.itemDict[item]) == 0:
                                del self.itemDict[item]
                        # KeyError occurs if the same macro uses the same item more
                        #  than once and if it's the last macro using this item.
                        except KeyError:
                            continue
                    # Remove macro from attack sets.
                    if oldMacro.hasAttack:
                        self.attackMacros[charIndex].discard(oldMacro)
                    if oldMacro.hasRangedAttack:
                        self.rangedAttackMacros[charIndex].discard(oldMacro)
                    # Add the macro slot back in to empty visible macro slots if needed.
                    if visible:
                        self.emptyVisibleSlots.setdefault(charIndex,set(range(10))).add(slot)
                    # And remove the old macro from the general collection of macros.
                    del charMacros[(page,slot)]

                    PLAYERSETTINGS.deleteMacro(charIndex,page,slot)
                    # If the button was visible, need to reset its appearance.
                    if visible:
                        control = TGEObject("MACROWND_MACRO%i_%i"%(charIndex,slot))
                        control.setText("")
                        control.setBitmap("")
                        control.hotKey = -1
                        control.pulseGreen = False
                        control.pulseRed = False
                        control.toggleLocked = True
                        control.setValue(0)
                        control.tooltip = "Macro Button (Press Ctrl + number to access more macro pages.  Double or Right Click to edit the macro.  Drag & Drop spells, items or skills to automatically create a macro.)"
    def autoPopulate(self):   
        from partyWnd import PARTYWND
        from playerSettings import PLAYERSETTINGS
        charIndex = PLAYERSETTINGS.charIndex
        charInfo = PARTYWND.charInfos[charIndex]
        macroSlot = 0
        from mud.world.spell import SpellProto       
        protos = SpellProto.selectBy(type="Zombie Kit")
        for spell in protos:
            # Create a new macro with the cursor content.
            newMacro = Macro(charIndex,0,macroSlot)           
            newMacroLines = list()           
            newMacro.name = spell.name
            newMacro.icon = spell.spellbookPic
            if newMacro.icon and not newMacro.icon.startswith('SPELLICON_'):
                    newMacro.icon = 'spellicons/%s'%newMacro.icon
            newMacro.description = spell.name
            basename = ' '.join([spell.name,RPG_ROMAN[charInfo.PLEVEL-1]])
            newMacroLines.append(MacroLine('/cast %s'%basename)) 
   
            # As the macro lines are now all prepared, insert them into the macro.
            newMacro.appendMacroLines(newMacroLines)
           
            # The new macro is now ready, so insert into macro master.
            self.insertMacro(charIndex,0,macroSlot,newMacro)
            macroSlot += 1



In spell.py in world just after

Code:

exclusionsInternal = MultipleJoin("SpellExclusion")



add

Code:

type = StringCol(default="")



in spells.py in genesis just for testing add the following contents:
Your player probably need to be of the class Bard for this to work.....

Code:

from genesis.dbdict import *
from mud.world.defines import *

durSecond = 6
durMinute = durSecond * 60
durHour = durMinute * 60

effect = DBEffectProto(name="Arcane Blast")
effect.addDamage(RPG_DMG_MAGICAL,100)
effect.resist = RPG_RESIST_MAGICAL

spell = DBSpellProto()
spell.name = "Arcane Blast"
spell.spellbookPic = "SPELLICON_1_25"
spell.particleTextureCasting = "staticring"
spell.particleCasting = "processesPending"
spell.sndCasting = "sfx/MagicSpell_CastingLoop1.ogg"
spell.particleTextureBegin = "staticring"
spell.particleBegin = "ChimneyFireEmitter"
spell.sndBegin = "sfx/DarkMagic_SpellImpact01.ogg"
spell.beginMsg = "$tgt is struck by an arcane blast."
spell.target = RPG_TARGET_OTHER
spell.duration = 0
spell.castRange = 20
spell.castTime = durSecond * 4
spell.recastTime = durSecond * 6
spell.harmful = True
spell.desc = "Damages a single target with a magical blast."
spell.skillname = "Evocation"
spell.addEffect("Arcane Blast")
spell.addClass("Bard", 1)
spell.type = "Zombie Kit"

effect = DBEffectProto(name="Arcane Storm")
effect.drainType = "health"
effect.drainTick = 20
effect.drainTickRate = durSecond * 6
effect.resist = RPG_RESIST_MAGICAL

spell = DBSpellProto()
spell.name = "Arcane Storm"
spell.spellbookPic = "SPELLICON_1_25"
spell.iconDst = "SPELLICON_1_25"
spell.particleTextureCasting = "staticring"
spell.particleCasting = "ChimneySmokeEmitter"
spell.sndCasting = "sfx/MagicSpell_CastingLoop1.ogg"
spell.particleTextureBegin = "staticring"
spell.particleBegin = "ChimneyFireEmitter"
spell.sndBegin = "sfx/DarkMagic_SpellImpact01.ogg"
spell.beginMsg = "$tgt is struck by an arcane storm."
spell.target = RPG_TARGET_OTHER
spell.duration = durMinute * 1
spell.castRange = 20
spell.castTime = durSecond * 4
spell.recastTime = durSecond * 6
spell.harmful = True
spell.aoeRange = 10
spell.desc = "Damages surrounding enemies by a magical storm."
spell.endMsg = "$tgt is no longer affected by the arcane storm."
spell.skillname = "Evocation"
spell.addEffect("Arcane Storm")
spell.addClass("Bard", 1)
spell.type = "Zombie Kit"

effect = DBEffectProto(name = "Summon Wolf Consort")
effect.summonPet = "Wolf Consort"

spell = DBSpellProto()
spell.name = "Summon Wolf Consort"
spell.spellbookPic = "SPELLICON_4_15"
spell.particleTextureCasting = "wingedc"
spell.particleCasting = "ChimneySmokeEmitter"
spell.sndCasting = "sfx/MagicSpell_CastingLoop1.ogg"
spell.particleTextureBegin = "wingedc"
spell.particleBegin = "ChimneyFireEmitter"
spell.sndBegin = "sfx/Skeleton_EmergeFromGround10.ogg"
spell.beginMsg = "$src has called upon a companion!"
spell.target = RPG_TARGET_SELF
spell.duration = 0
spell.castTime = durSecond * 10
spell.recastTime = durSecond * 5 * 60 # 5 minutes
spell.harmful = False
spell.desc = "Summons a wolf to help you."
spell.skillname = "Conjuration"
spell.addEffect("Summon Wolf Consort")
spell.addClass("Bard",1)
spell.type = "Zombie Kit"

effect = DBEffectProto(name = "Bard Levitation")
effect.addStat(RPG_EFFECT_STAGE_GLOBAL,"flying",1.0)

spell = DBSpellProto()
spell.name = "Sapre's Airy Melody"
spell.spellbookPic = "SPELLICON_4_3"
spell.iconDst = "SPELLICON_4_3"
spell.particleTextureCasting = "wingedc"
spell.particleCasting = "ChimneySmokeEmitter"
spell.sndCasting = "sfx/MagicSpell_CastingLoop1.ogg"
spell.particleTextureBegin = "wingedc"
spell.particleBegin = "ChimneyFireEmitter"
spell.sndBegin = "sfx/Pickup_Speed03.ogg"
spell.target = RPG_TARGET_PARTY
spell.duration = durMinute * 15 #15 minutes
spell.castTime = durSecond * 2
spell.harmful = False
spell.beginMsg = "$tgt dances on the air!"
spell.endMsg = "$tgt becomes heavier."
spell.desc = "Allows your party to levitate."
spell.skillname = "Singing"
spell.addEffect("Bard Levitation")
spell.addClass("Bard",1)
spell.type = "Zombie Kit"

###########################################################
effect = DBEffectProto(name = "Zombie Mask")
effect.addStat(RPG_EFFECT_STAGE_GLOBAL,"flying",1.0)

spell = DBSpellProto()
spell.name = "Zomebie Mask"
spell.spellbookPic = "SPELLICON_4_3"
spell.iconDst = "SPELLICON_4_3"
spell.particleTextureCasting = "wingedc"
spell.particleCasting = "ChimneySmokeEmitter"
spell.sndCasting = "sfx/MagicSpell_CastingLoop1.ogg"
spell.particleTextureBegin = "wingedc"
spell.particleBegin = "ChimneyFireEmitter"
spell.sndBegin = "sfx/Pickup_Speed03.ogg"
spell.target = RPG_TARGET_SELF
spell.duration = durMinute * 15 #15 minutes
spell.castTime = durSecond * 2
spell.harmful = False
spell.beginMsg = "$tgt is turned into a zombie!"
spell.endMsg = "$tgt turns back from a zombie."
spell.desc = "turns caster into a mock zombie; can blend with other zombies and not be attacked."
spell.skillname = "Singing"
spell.addEffect("Zombie Mask")
spell.addClass("Bard",1)
spell.type = "Zombie Kit"

effect = DBEffectProto(name = "Zombie Moan")
effect.addStat(RPG_EFFECT_STAGE_GLOBAL,"flying",1.0)

spell = DBSpellProto()
spell.name = "Zombie Moan"
spell.spellbookPic = "SPELLICON_4_4"
spell.iconDst = "SPELLICON_4_4"
spell.particleTextureCasting = "wingedc"
spell.particleCasting = "ChimneySmokeEmitter"
spell.sndCasting = "sfx/MagicSpell_CastingLoop1.ogg"
spell.particleTextureBegin = "wingedc"
spell.particleBegin = "ChimneyFireEmitter"
spell.sndBegin = "sfx/Pickup_Speed03.ogg"
spell.target = RPG_TARGET_PARTY
spell.duration = durMinute * 15 #15 minutes
spell.castTime = durSecond * 2
spell.harmful = False
spell.beginMsg = "$tgt is followed by all zombies in the area!"
spell.endMsg = "$tgt loose attention of all zombies in the area."
spell.desc = "makes zombies in area follow but not attack player is disguised; taunt if not disguised."
spell.skillname = "Singing"
spell.addEffect("Zombie Moan")
spell.addClass("Bard",1)
spell.type = "Zombie Kit"