1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. Rubbed the right way, the genie is out of its lamp! The 12th Concept Art Contest Results have been announced.
    Dismiss Notice
  5. Race against the odds and Reforge, Don't Refund. The 14th Techtree Contest has begun!
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Trigger Viewer

Advanced Equipment system.w3x
Variables
System
How To Import
How To Use
Equipment system
SaveLoad Plugin
Setup
Required
Linked List
RegisterPlayerUnitEvent
test map
init
Get SaveLoad Code
Use SaveLoad Code
Events
Kartenspezifischen eigenen Skript-Code unten eingeben. Dieser Text wird in das Karten-Skript nach der Deklaration der Variablen und vor jeglichem Auslöser-Code eingefügt.
//TESH.scrollpos=0
//TESH.alwaysfold=0
Name Type Is Array Initial Value
u unit No
//TESH.scrollpos=0
//TESH.alwaysfold=0

/*~~~~~~~How to Import/Update this system~~~~~~~*\

1. Delete (if existing) the old Equipment System trigger

2. Copy the new Equipment system Trigger into your map

~~~~~~~How to Set Up~~~~~~~

1. Copy all the abilities used by this system (here they are all under "human") or create your own ones
   they are one ability for opening the inventory, one for closing, one which makes items "clickable", and for each empty slot a ability

2. Create all your items which can be equipped and give them as ability ONLY  the  [clickable item]  ability

3. For each equipable item create a icon ability (best if you use "channel" as base ability)
    2 things to be careful with:

    Make sure that the item icon's Spell ID for each type of item is distinct
    i.e. Swords => acidbomb
          shields => bloodlust
    (be aware that the Cancel button has it's own Spell ID => absorb)


   Make sure that every item ability icon has the X and Y button coordinates matching with the Type of item it is

    i.e. Necklaces = 0,0 ; Helmets = 1,0 ; Gloves = 2,0
    Necklace of Power = 0,0
    Glory Necklace = 0,0
    Bloodlust Helmet = 1,0
    Green Cap = 1,0
    Gloves of the IronDwarf = 2,0

4. Create abilities for each equipable item. DONT use the same ability twice on items of different equipment classes!!
    Dont give those abilities to the items! They will be given to the equipping unit ingame by this system.
   
    I advise you to take abilities which have no icon because it would show up on the owner
    (of course this can be useful if an item should grant a active ability, for example!)
    if you need an icon ability which should be invisible (aura for example), create a spellbook, add that ability to it,
    disable the spellbook at map start and register the spellbook as an ability given by your item ;)

5. initialize your items and classes

6. make sure that all the adjustable variables in the setup part fit your map now

~~~~~~~Hints~~~~~~~
to show/hide the rawcode of anything in the object editor just press CTRL + D

to copy the systems abilities (open,close, empty offhand,...) you have to import all the BTN files importet in this map aswell!!




aaaaaand you are done :D

gl & hf
The_Witcher
*/
//TESH.scrollpos=93
//TESH.alwaysfold=0
\*                                                              */
/****************************************************************\
*                                                                *
*                                                                *
*                 Advanced Equipment System                      *
*                                                                *
*                                                                *
*                   by The_Witcher                               *
\****************************************************************/

/*                                                              *\
---------     Introduction     ---------

    what this is:
    - Equipment System
    - MUI
    - in vJass

    what this is not:
    - Inventory System
    - in GUI/normal Jass
    - exportable to GUI or normal Jass

    Content:
    1) How to register items
    2) How to use this system
    3) Additional functions
    4) Trigger Events
    5) To all vJassers out there

--------- 1)    How to register items    (1 ---------

    this system isn't that perfekt that it can do everything on its own ;D
    At first you have to initialize your classes.
    Do this by calling:
        call AdvancedEquipmentSystem_RegisterNewClass( icon,  class)
            "icon" is the icon ability that indicates an empty slot
            "class" is a simple integer that determines the class

    You also have to register all items you want to be equipable to this system.
    With the following function you can do that:

        call AdvancedEquipmentSystem_RegisterItem(itemid, abilities, icon, class, twohanded, animation)
            "itemid" is of course the rawcode of the item the rest is assigned to
            "icon" is the ability shown inside the Equipment when the item is equipped
            "class" is the slot the item jumps in (be sure to adjust the x/y coordinates inside the object editor according
                                                 to the coordinates of the "empty slot" icon ability of the same class)
            "twohanded" is a boolean (i think self explaining) !!works only for mainhand items!!          
            "animation" is a string which indicates the animation tag added when this item is equipped
                ATTENTION: offhand slot items animations always overwrite mainhand slot items animations
             
    until now your items have no effect when equipped...
    you can add countless abilities to one itemtype! (actually its limited to around 8000 abilities in total :D )
    to add one use:

         call AdvancedEquipmentSystem_AddItemAbility( integer itemid, integer abi )
            "itemid" is the rawcode of the item the rest is assigned to      
            "abi" is the rawcode of the ability the unit gets when it equips this item
             
    Example:

        globals
            integer AMULET_CLASS = 2
        endglobals
        ...
        call AdvancedEquipmentSystem_RegisterNewClass('A00A', AMULET_CLASS)
        ...
        call AdvancedEquipmentSystem_RegisterItem('I004', 'A008', AMULET_CLASS, false, "Alternate")
        call AdvancedEquipmentSystem_AddItemAbility('I004', 'A002')


--------- 2)    How to use this system    (2 ---------

    well its very simple to use:

    call InitEquipment ( owner )
      owner is the unit that gets the equipment
     
    and thats all^^ whenever this unit uses a registered item, it will get equipped


--------- 3)    Additional functions    (3 ---------

        function IsEquipmentClassEmpty takes unit u, integer class returns boolean

        function EquipItem takes unit u, item ite returns nothing

        function EquipItemById takes unit u, integer itemId returns nothing

        function UnequipItemById takes unit u, integer itemid returns nothing

        function UnequipItemByClass takes unit u, integer class returns nothing

        function GetEquippedItemTypeId takes unit u, integer class returns integer

        function ChangeEquipmentOwner takes unit u, unit newowner returns nothing

        function UnequipAll takes unit u returns nothing
       
        function EnableItemEquip takes integer itemId, integer unitType, boolean flag returns nothing

--------- 4)    Trigger Events    (4 ---------

        function RegisterItemEquipEvent takes code func returns nothing  
        function RegisterItemUnequipEvent takes code func returns nothing
        //use GetTriggeringItemId and GetEquippingUnit to get the involved units

--------- 5)    To all vJassers out there    (5 ---------
    well as we understand vJass we can do things much easier ^^

    the above mentioned functions are all simple wrappers for the included structs methods:
   
    struct Equipment
      methods
        create takes unit u returns Equipment  => creates a new Equipment for unit u
        destroy takes nothing returns nothing  => destroys an existing Equipment
        equip takes integer itemId returns nothing   => equips the given item
        unequip takes integer class returns nothing => unequips whatever is in the given class
       
        static method disable takes integer itemId, integer unitType, boolean flag returns nothing
            => disables a itemtype for a unit type so it can't equip it anymore
       
      members
        unit owner  => the equipment unit, use "set yourEquipment.owner = yourunit" to transfer the Equipment to another unit
        readonly EquipmentItem array Item  => the equipped EquipmentItem in a slot, specified by the array index

---------     Thanks to all who gave useful critism or tips for improvement     ---------

    The_Witcher

//TESH.scrollpos=0
//TESH.alwaysfold=0
library AdvancedEquipmentSystem requires LinkedListModule, RegisterPlayerUnitEvent

    // The_Witcher's Equipment System
    //
    // This is my easy to use equipment system, which adds an equipment screen to any unit you want.
    //  equipped items can give up abilities to the owner and can change the animations of him...
    //
    //
    //       To learn how to use this system please read the "How To Use" delivered in the demo map
    //
    //
    // Requirements:
    //    JASS knowledge
    //    LinkedList (http://www.hiveworkshop.com/forums/jass-resources-412/snippet-linkedlistmodule-206552/)
    //    RegisterPlayerUnitEvent (http://www.hiveworkshop.com/forums/jass-resources-412/snippet-registerplayerunitevent-203338/)
    //
    // have fun^^

    //**************************************************
    //********************SETUP PART********************
    //**************************************************

    globals
        // this is the rawcode of the unit which works as inventory
        public constant integer INVENTORY_DUMMY = 'h007'
     
        // this is the class you selected as mainhand class
        public constant integer MAINHAND_CLASS = 0
     
        // this is the class you selected as offhand class
        public constant integer OFFHAND_CLASS = 1
       
        // this is the amount of total classes you have
        public constant integer CLASSES = 9
     
        // this is the ability to close the inventory
        public constant integer EXIT_ABILITY = 'A00G'
     
        // this is the ability to open the inventory
        public constant integer OPEN_ABILITY = 'A003'
       
        // this is the ability which gives the dummy the same inventory as your hero has
        public constant integer INVENTORY_ABILITY = 'AInv'
     
        // this is the icon ability shown in the offhand slot when a twhoanded weapon is equipeed
        public constant integer TWOHAND_ABILITY = 'A00Z'
        public constant boolean SHOW_TWOHAND_ABILITY = true
     
        // this is the text shown when a unit is trying to equip an item which it isnt allowed to
        // example: " can't equip " becomes ingame something like   Soldier can't equip Giant Sword
        public constant string UNABLE_TO_EQUIP_STRING = " can't equip "
    endglobals

    //************************************************************
    //********************SETUP PART ENDS HERE********************
    //************************************************************
    //*****************Don't edit anything below******************
    //************************************************************

    globals
        private trigger OnEquip
        private trigger OnUnequip
        private integer TriggeringItem
        private unit EquippingUnit
        private hashtable table
    endglobals
   
    private struct AbilityList extends array
        integer abi
        implement LinkedList
       
        static method create takes nothing returns thistype
            return .createNode()
        endmethod
       
        method remove takes nothing returns nothing
            call .removeNode()
            call .deallocate()
        endmethod
       
        method add takes integer abi returns nothing
            local thistype new = .allocate()
            set new.abi = abi
            call .insertNode(new)
        endmethod
    endstruct


    // **** struct EquipmentItem ****
    private struct EquipmentItem extends array
        readonly integer id
        readonly integer class
        readonly AbilityList abilities
        readonly integer icon
        readonly boolean twohanded
        readonly string tag

        static method operator [] takes integer itemid returns EquipmentItem
            return itemid - 'I000' + CLASSES + 1
        endmethod
   
        static method create takes integer id, integer icon, integer class, boolean twohanded, string animation returns EquipmentItem
            local EquipmentItem this = id - 'I000' + CLASSES + 1
            if id - 'I000' >= 0 then
                call SaveBoolean(table, id - 'I000', 0, true)
            endif
            set .id = id
            set .class = class
            set .icon = icon
            if id >= CLASSES + 1 then
                set .abilities = AbilityList.create()
                if class == MAINHAND_CLASS then
                    set .twohanded = twohanded
                else
                    set .twohanded = false
                endif
                if (class == MAINHAND_CLASS or class == OFFHAND_CLASS) and id != 0 then
                    set .tag = animation
                else
                    set .tag = ""
                endif
            endif
            return this
        endmethod
       
        method addAbility takes integer abi returns nothing
            call .abilities.add( abi)
        endmethod
       
        method applyAbilities takes unit u, boolean add returns nothing
            local AbilityList node = .abilities.next
            loop
                exitwhen node.head
                if add then
                    call UnitAddAbility(u, node.abi)
                else
                    call UnitRemoveAbility(u, node.abi)
                endif
                set node = node.next
            endloop
        endmethod
    endstruct

    public function RegisterNewClass takes integer emptyicon, integer class returns nothing
        call EquipmentItem.create('I000' - CLASSES - 1 + class, emptyicon, class, false, "")
    endfunction

    // **** struct Equipment ****    
    struct Equipment
        private static EquipmentItem twohandIcon
   
        private unit u
        private unit dummy
        readonly string animtag = ""
        readonly EquipmentItem array Item [12]
   
        static method operator [] takes unit u returns Equipment
            return LoadInteger(table, GetHandleId(u), 0)
        endmethod
   
        method operator owner takes nothing returns unit
            return .u
        endmethod
   
        method operator owner= takes unit new returns nothing
            local integer i = 0
            loop
                exitwhen i >= CLASSES
                if .Item[i] != 0 then
                    call .Item[i].applyAbilities(.u, false)
                    call .Item[i].applyAbilities(new, true)
                endif
                set i = i + 1
            endloop
            call AddUnitAnimationProperties(.u, .animtag, false)
            call UnitRemoveAbility(.u, OPEN_ABILITY)
            call AddUnitAnimationProperties(new, .animtag, true)
            call UnitAddAbility(new, OPEN_ABILITY)
            set .u = new
            call SaveInteger(table, GetHandleId(.u), 0, this)
            call SaveInteger(table, GetHandleId(.dummy), 0, this)
        endmethod
       
        method syncInventories takes nothing returns nothing
            local integer i = 0
            loop
                exitwhen i >= 6
                call RemoveItem(UnitItemInSlot(.dummy, i))
                call UnitAddItemToSlotById(.dummy, GetItemTypeId(UnitItemInSlot(.u, i)), i)
                call SetItemDroppable(UnitItemInSlot(.dummy, i), false)
                set i = i + 1
            endloop
        endmethod
   
        private method refreshAnimation takes nothing returns nothing
            local string a = .Item[MAINHAND_CLASS].tag
            if .Item[OFFHAND_CLASS] != 0 and .Item[OFFHAND_CLASS] != twohandIcon then
                set a = .Item[OFFHAND_CLASS].tag
            endif
            call AddUnitAnimationProperties(.u, .animtag, false)
            call AddUnitAnimationProperties(.u, a, true)
            set .animtag = a
        endmethod
       
        method equipEmptyClass takes integer class returns nothing
            call UnitAddAbility(.dummy, EquipmentItem(class).icon)
            set .Item[class] = 0
        endmethod
       
        method equipTwohandIcon takes nothing returns nothing
            call UnitAddAbility(.dummy, twohandIcon.icon)
            set .Item[OFFHAND_CLASS] = twohandIcon
        endmethod
   
        method unequip takes integer class returns nothing
            local integer i = 0
            local EquipmentItem toRemove = .Item[class]
            if toRemove != 0 then
                if toRemove.twohanded then
                    call UnitRemoveAbility(.dummy, TWOHAND_ABILITY)
                    call .equipEmptyClass(OFFHAND_CLASS)
                endif
                call toRemove.applyAbilities(.u, false)
                call UnitAddItemById(.u, toRemove.id)
                set TriggeringItem = toRemove.id
                set EquippingUnit = .u
                call TriggerEvaluate(OnUnequip)
                call UnitRemoveAbility(.dummy, toRemove.icon)
            else
                call UnitRemoveAbility(.dummy, EquipmentItem(class).icon)
            endif
            set .Item[class] = 0
            call .refreshAnimation()
        endmethod
       
        method equip takes integer id returns nothing
            local EquipmentItem toEquip = EquipmentItem[id]
            local EquipmentItem mainEquip = .Item[MAINHAND_CLASS]
            // remove existing
            if mainEquip != 0 then
                if toEquip.twohanded or (mainEquip.twohanded and (toEquip.class == OFFHAND_CLASS or toEquip.class == MAINHAND_CLASS)) then
                    call .unequip(MAINHAND_CLASS)
                    call .unequip(OFFHAND_CLASS)
                    if toEquip.class == MAINHAND_CLASS and not toEquip.twohanded then
                        call .equipEmptyClass(OFFHAND_CLASS)
                    elseif toEquip.class == OFFHAND_CLASS then
                        call .equipEmptyClass(MAINHAND_CLASS)
                    endif
                endif
            endif
            call .unequip(toEquip.class)
            // new is twohanded ?
            if toEquip.twohanded then
                call .unequip(OFFHAND_CLASS)
                call .equipTwohandIcon()
                if not SHOW_TWOHAND_ABILITY then
                    call UnitRemoveAbility(.dummy, twohandIcon.icon)
                endif
            endif
            // equip new
            call toEquip.applyAbilities(.u, true)
            call UnitAddAbility(.dummy, toEquip.icon)
            set .Item[toEquip.class] = toEquip
            call .refreshAnimation()
            // fire trigger
            set EquippingUnit = .u
            set TriggeringItem = id
            call TriggerEvaluate(OnEquip)
        endmethod
       
        static method disable takes integer itemId, integer unitType, boolean flag returns nothing
            call SaveBoolean(table, itemId - 'I000', unitType, flag)
        endmethod
       
        private method onDestroy takes nothing returns nothing
            local integer i = 0
            call RemoveUnit(.dummy)
            loop
                exitwhen i > 12
                if .Item[i] != 0 then
                    call .Item[i].applyAbilities(.u, false)
                endif
                set i = i + 1
            endloop
            call AddUnitAnimationProperties(.u, .animtag, false)
            call UnitRemoveAbility(.u, OPEN_ABILITY)
        endmethod
   
        static method create takes unit u returns Equipment
            local Equipment this = Equipment[u]
            local integer i = 0
            local integer id = GetPlayerId(GetOwningPlayer(u))
            if this != 0 then
                call RemoveUnit(.dummy)
            else
                set this = Equipment.allocate()
                call SaveInteger(table, GetHandleId(u), 0, this)
            endif
            set .u = u
            set .dummy = CreateUnit(GetOwningPlayer(u), INVENTORY_DUMMY, GetUnitX(u), GetUnitY(u), 0)
            call SaveInteger(table, GetHandleId(.dummy), 0, this)
            call UnitAddAbility(.dummy, INVENTORY_ABILITY)
            call UnitAddAbility(.dummy, EXIT_ABILITY)
            call UnitAddAbility(.u, OPEN_ABILITY)
            loop
                exitwhen i >= CLASSES
                call .equipEmptyClass(i)
                set i = i + 1
            endloop
            return this
        endmethod
       

    // **** Other Stuff ****
        private static method Access takes nothing returns boolean
            local unit u = GetTriggerUnit()
            local Equipment inv = Equipment[u]
            local integer class
            local integer i = 0
            if GetSpellAbilityId() == EXIT_ABILITY then
                if GetLocalPlayer() == GetOwningPlayer(inv.u) then
                    call ClearSelection()
                    call SelectUnit(inv.u, true)
                endif
            elseif GetSpellAbilityId() == OPEN_ABILITY then
                call SetUnitX(inv.dummy, GetUnitX(inv.u))
                call SetUnitY(inv.dummy, GetUnitY(inv.u))
                if GetLocalPlayer() == GetOwningPlayer(inv.u) then
                    call ClearSelection()
                    call SelectUnit(inv.dummy, true)
                endif
                call inv.syncInventories()
            elseif GetUnitTypeId(u) == INVENTORY_DUMMY then
                loop
                    exitwhen i >= CLASSES
                    if inv.Item[i].icon == GetSpellAbilityId() then
                        set class = i
                        set i = CLASSES
                    endif
                    set i = i + 1
                endloop
                call inv.unequip(class)
                call inv.equipEmptyClass(class)
                call inv.syncInventories()
            endif
            set u = null
            return false
        endmethod

        private static method ItemEquip takes nothing returns boolean
            local unit u = GetTriggerUnit()
            local item ite = GetManipulatedItem()
            local integer i = 0
            local Equipment inv = Equipment[u]
            local EquipmentItem invIte = EquipmentItem[GetItemTypeId(ite)]
            if GetItemTypeId(ite) - 'I000' >= 0 then
                if LoadBoolean(table, GetItemTypeId(ite) - 'I000', 0) then
                    if invIte != 0 and inv != 0 then
                        if not LoadBoolean(table, GetItemTypeId(ite) - 'I000', GetUnitTypeId(inv.u)) then
                            if u == inv.u then
                                call inv.equip(GetItemTypeId(ite))
                                call RemoveItem(ite)
                                call inv.syncInventories()
                            elseif u == inv.dummy then
                                loop
                                    exitwhen i >= 6
                                    if invIte.id == GetItemTypeId(UnitItemInSlot(inv.u, i)) then
                                        call UnitUseItem(inv.u, UnitItemInSlot(inv.u, i))
                                        call RemoveItem(ite)
                                        set i = 7
                                    endif
                                    set i = i + 1
                                endloop
                            endif
                        else
                            call DisplayTextToPlayer(GetOwningPlayer(inv.u), 0, 0, GetUnitName(inv.u) + UNABLE_TO_EQUIP_STRING + GetItemName(ite))
                        endif
                    endif
                endif
            endif
            set u = null
            set ite = null
            return false
        endmethod
       
        private static method onInit takes nothing returns nothing
            set OnEquip = CreateTrigger()
            set OnUnequip = CreateTrigger()
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_USE_ITEM, function Equipment.ItemEquip)
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_CAST, function Equipment.Access)
            set .twohandIcon = EquipmentItem.create('I000' - 1, TWOHAND_ABILITY, 0, false, "")
            set table = InitHashtable()
        endmethod
       
        implement optional SaveLoadPlugin
   
    endstruct

    // **** Trigger Events ****
    function RegisterItemEquipEvent takes code func returns nothing
        call TriggerAddCondition(OnEquip, Filter(func))
    endfunction
   
    function RegisterItemUnequipEvent takes code func returns nothing
        call TriggerAddCondition(OnUnequip, Filter(func))
    endfunction
   
    function GetTriggeringItemId takes nothing returns integer
        return TriggeringItem
    endfunction
   
    function GetEquippingUnit takes nothing returns unit
        return EquippingUnit
    endfunction
   
   //wrappers
    function InitEquipment takes unit whichunit returns nothing
        call Equipment.create(whichunit)
    endfunction

    public function RegisterItem takes integer itemid, integer icon, integer class, boolean twohanded, string animation returns nothing
        call EquipmentItem.create(itemid, icon, class, twohanded, animation)
    endfunction
   
    public function AddItemAbility takes integer itemid, integer abi returns nothing
        call EquipmentItem[itemid].addAbility(abi)
    endfunction
   
    function EnableItemEquip takes integer itemId, integer unitType, boolean flag returns nothing
        call Equipment.disable(itemId, unitType, not flag)
    endfunction

    function IsEquipmentClassEmpty takes unit u, integer class returns boolean
        return Equipment[u].Item[class] == 0
    endfunction

    function EquipItem takes unit u, item ite returns nothing
        call Equipment[u].equip(GetItemTypeId(ite))
        call RemoveItem(ite)
    endfunction
    function EquipItemById takes unit u, integer itemId returns nothing
        call Equipment[u].equip(itemId)
    endfunction

    function UnequipItemById takes unit u, integer itemid returns nothing
        local integer class = EquipmentItem[itemid].class
        if Equipment[u].Item[class].id == itemid then
            call Equipment[u].unequip(EquipmentItem[itemid].class)
            call Equipment[u].equipEmptyClass(class)
        endif
    endfunction

    function UnequipItemByClass takes unit u, integer class returns nothing
        call Equipment[u].unequip(class)
        call Equipment[u].equipEmptyClass(class)
    endfunction

    function GetEquippedItemTypeId takes unit u, integer class returns integer
        return Equipment[u].Item[class].id
    endfunction

    function ChangeEquipmentOwner takes unit u, unit newowner returns nothing
        set Equipment[u].owner = newowner
    endfunction

    function UnequipAll takes unit u returns nothing
        local integer i = 1
        loop
            call Equipment[u].unequip(i)
            call Equipment[u].equipEmptyClass(i)
            exitwhen i >= CLASSES
            set i = i + 1
        endloop
    endfunction

endlibrary


//Code indented using The_Witcher's Script Language Aligner
//Download the newest version and report bugs at www.hiveworkshop.com
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
library SaveLoadPlugin
// create your custom save/load functions in here.
// if you don't need any simply delete this trigger

//  WARNING: this is only for experienced users!
//           the demo map save/load code is more an example
//           than a useful system (but it works, too)

    module SaveLoadPlugin
        method getLoadCode takes nothing returns string
            local integer i = 0
            local string s = ""
            loop
                set i = i + 1
                if .Item[i].id != 0 then
                    set s = s + I2S(.Item[i].id - 'I000')
                endif
                set s = s + "x"
                exitwhen i >= AdvancedEquipmentSystem_CLASSES
            endloop
            return s
        endmethod

        method useLoadCode takes string LoadCode returns nothing
            local integer i = 0
            local integer i2 = 0
            local integer i3 = 1
            local string s
            local string c = LoadCode
            loop
                set i = i + 1
                set i2 = 1
                loop
                    set s = SubString(c, 0, i2)
                    exitwhen SubString(s, StringLength(s) - 1, StringLength(s)) == "x"
                    set i2 = i2 + 1
                endloop
                set c = SubString(c, i2, 99999)
                set s = SubString(s, 0, StringLength(s) - 1)
                if s != "" then
                    call .equip('I000' + S2I(s))
                endif
                exitwhen i >= AdvancedEquipmentSystem_CLASSES or c == ""
            endloop
        endmethod
    endmodule

    function GetLoadCode takes unit u returns string
        return Equipment[u].getLoadCode()
    endfunction

    function UseLoadCode takes unit u, string LoadCode returns nothing
        call Equipment[u].useLoadCode( LoadCode)
    endfunction

endlibrary


//Code indented using The_Witcher's Script Language Aligner
//Download the newest version and report bugs at www.hiveworkshop.com
 
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope SetupAdvancedEquipmentSystem initializer Initialize

    globals
        integer AMULET_CLASS = 2
        integer ARMOR_CLASS = 3
        integer BOOTS_CLASS = 4
        integer GLOVES_CLASS = 5
        integer RING_CLASS = 6
        integer HELMET_CLASS = 7
        integer SPECIAL_CLASS = 8
    endglobals

    private function Initialize takes nothing returns nothing
        // here you have to give an icon ability for every empty slot
        // this is my setup for the testmap


        // WARNING: class 0 and 1 are taken as main and offhand slots! start with 2 for new indexes
        call AdvancedEquipmentSystem_RegisterNewClass('A00D', AdvancedEquipmentSystem_MAINHAND_CLASS)//Mainhand
        call AdvancedEquipmentSystem_RegisterNewClass('A00E', AdvancedEquipmentSystem_OFFHAND_CLASS)//Offhand
        call AdvancedEquipmentSystem_RegisterNewClass('A00A', AMULET_CLASS)//Amulet
        call AdvancedEquipmentSystem_RegisterNewClass('A007', ARMOR_CLASS)//Armor
        call AdvancedEquipmentSystem_RegisterNewClass('A00F', BOOTS_CLASS)//Boots
        call AdvancedEquipmentSystem_RegisterNewClass('A004', GLOVES_CLASS)//Gloves
        call AdvancedEquipmentSystem_RegisterNewClass('A00C', RING_CLASS)//Ring
        call AdvancedEquipmentSystem_RegisterNewClass('A00L', HELMET_CLASS)//Helmet
        call AdvancedEquipmentSystem_RegisterNewClass('A00M', SPECIAL_CLASS)//Special
       

    //in this part set up the items
    //you can do this anytime in your map (may cause bugs if not at initialization) by using
    //call AdvancedEquipmentSystem_RegisterItem(itemid, abilities, icon, class, twohanded, animation)
    // look into the HowToUse for further information
   
    //                                       itemid |  icon | class | twohanded? | animationtag
    //Silversword
        call AdvancedEquipmentSystem_RegisterItem('I004', 'A008', AdvancedEquipmentSystem_MAINHAND_CLASS, false, "Alternate")
        call AdvancedEquipmentSystem_AddItemAbility('I004', 'A002')
        call EnableItemEquip('I004','H001',false)
    //sacred stone        
        call AdvancedEquipmentSystem_RegisterItem('I000', 'A00K', SPECIAL_CLASS, false, "")
        call AdvancedEquipmentSystem_AddItemAbility('I000', 'A000')
        call AdvancedEquipmentSystem_AddItemAbility('I000', 'A00Y')
    //Slizer
        call AdvancedEquipmentSystem_RegisterItem('I005' , 'A00H', AdvancedEquipmentSystem_MAINHAND_CLASS, false, "Alternate")
        call AdvancedEquipmentSystem_AddItemAbility('I005', 'A005')
    //Razor
        call AdvancedEquipmentSystem_RegisterItem('I006', 'A00J', AdvancedEquipmentSystem_MAINHAND_CLASS, true, "Channel")
        call AdvancedEquipmentSystem_AddItemAbility('I006', 'A00I')
    //shield
        call AdvancedEquipmentSystem_RegisterItem('I001', 'A009', AdvancedEquipmentSystem_OFFHAND_CLASS, false, "defend")
        call AdvancedEquipmentSystem_AddItemAbility('I001', 'A006')
    //Amulet of darkness
        call AdvancedEquipmentSystem_RegisterItem('I00A', 'A00B', AMULET_CLASS, false, "")
        call AdvancedEquipmentSystem_AddItemAbility('I00A', 'A00S')
    //Golems Skin
        call AdvancedEquipmentSystem_RegisterItem('I003', 'A00N', ARMOR_CLASS, false, "")
        call AdvancedEquipmentSystem_AddItemAbility('I003', 'A00U')
    //Windwalkers
        call AdvancedEquipmentSystem_RegisterItem('I002', 'A00O', BOOTS_CLASS, false, "")
        call AdvancedEquipmentSystem_AddItemAbility('I002', 'A00X')
    //Stonefists
        call AdvancedEquipmentSystem_RegisterItem('I007', 'A00P', GLOVES_CLASS, false, "")
        call AdvancedEquipmentSystem_AddItemAbility('I007', 'A00W')
    //Arthuriel  
        call AdvancedEquipmentSystem_RegisterItem('I008', 'A00Q', RING_CLASS, false, "")
        call AdvancedEquipmentSystem_AddItemAbility('I008', 'A00T')
    //Mask of Horror      
        call AdvancedEquipmentSystem_RegisterItem('I009', 'A00R', HELMET_CLASS, false, "")
        call AdvancedEquipmentSystem_AddItemAbility('I009', 'A00V')
       
    endfunction

endscope


//Code indented using The_Witcher's Script Language Aligner
//Download the newest version and report bugs at www.hiveworkshop.com
 
//TESH.scrollpos=44
//TESH.alwaysfold=0
library LinkedListModule /* v2.2.0

    Easy implementation of linked lists into structs.

    ***********************************************************************
    *
    * module LinkedList
    *
    * - Implement at the top of your struct, must extend array
    *
    * thistype next
    * thistype prev
    * boolean head
    *
    * readonly static thistype base
    * - Precreated head, useful for non-dynamic lists.
    *
    * static method allocate takes nothing returns thistype
    * method deallocate takes nothing returns nothing
    *
    * static method createNode takes nothing returns thistype
    * - Allocates a new node pointing towards itself.
    * - These nodes are considered "heads" therefore it's head
    * - boolean member is set to true.
    * method insertNode takes thistype toInsert returns thistype
    * - Inserts the node into the list after 'this' node.
    * method removeNode takes nothing returns nothing
    * - Removes the node from the list.
    * method clearNode takes nothing returns nothing
    * - Deallocates all the instances within the node's range
    * method flushNode takes nothing returns nothing
    * - Clears and deallocates the node.
    *
    ********************************************************************* */

   
    module LinkedList
        //private static integer instanceCount = 0
        readonly static integer instanceCount = 0
       
        boolean head
        thistype next
        thistype prev
       
        static method operator base takes nothing returns thistype
            return 8190
        endmethod
       
        static method allocate takes nothing returns thistype
            local thistype this=thistype(0).prev
            if this == 0 then
                debug if instanceCount == 8190 then
                debug call BJDebugMsg("[LinkedList] Error: attempted to allocate too many instances.")
                debug return 0
                debug endif
                set instanceCount=instanceCount+1
                return instanceCount
            endif
            set thistype(0).prev=this.prev
            return this
        endmethod
       
        method deallocate takes nothing returns nothing
            set this.prev=thistype(0).prev
            set thistype(0).prev=this
            set this.head=false
        endmethod
               
        static method createNode takes nothing returns thistype
            local thistype this=allocate()
            set this.next=this
            set this.prev=this
            set this.head=true
            return this
        endmethod
       
        method clearNode takes nothing returns nothing
            if this != this.next then
                set this.next.prev=thistype(0).prev
                set thistype(0).prev=this.prev
                set this.next=this
                set this.prev=this
            endif
        endmethod
       
        method flushNode takes nothing returns nothing
            set this.next.prev=thistype(0).prev
            set thistype(0).prev=this
            set head=false
        endmethod
       
        method insertNode takes thistype toInsert returns nothing
            set this.prev.next=toInsert
            set toInsert.prev=this.prev
            set this.prev=toInsert
            set toInsert.next=this
        endmethod
       
        method removeNode takes nothing returns nothing
            set this.prev.next=this.next
            set this.next.prev=this.prev
        endmethod
       
        private static method onInit takes nothing returns nothing
            set thistype(8190).next=8190
            set thistype(8190).prev=8190
            set thistype(8190).head=true
        endmethod
       
        static if DEBUG_MODE then
            method print takes nothing returns nothing
                local string s=""
                local thistype exit=this
                set this=this.next
                loop
                    set s=s+I2S(this)
                    set this=this.next
                    exitwhen this == exit
                    set s=s+" - "
                endloop
                call BJDebugMsg("[ "+s+" ]")
            endmethod
        endif
       
    endmodule
   
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/**************************************************************
*
*   RegisterPlayerUnitEvent
*   v5.0.0.0
*   By Magtheridon96
*
*   I would like to give a special thanks to Bribe, azlier
*   and BBQ for improving this library. For modularity, it only
*   supports player unit events.
*
*   Functions passed to RegisterPlayerUnitEvent must
*   return false. They can return nothing as well. (Which is a Pro)
*
*   Warning:
*   --------
*
*       - Don't use TriggerSleepAction inside registered code.
*
*   API:
*   ----
*
*       - function RegisterPlayerUnitEvent
*           takes
*               playerunitevent whichEvent  :   The event you would like to register
*               code whichFunction          :   The code you would like to register
*           returns
*               nothing
*
*           - Registers code that will execute when an event fires.
*
*       - function RegisterPlayerUnitEventForPlayer
*           takes
*               playerunitevent whichEvent  :   The event you would like to register
*               code whichFunction          :   The code you would like to register
*               player whichPlayer          :   The player you would like to register the event for
*           returns
*               nothing
*
*           - Registers code that will execute when an event fires for a certain player.
*
**************************************************************/

library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
    globals
        private trigger array t
    endglobals
   
    function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
        local integer i = GetHandleId(p)
        local integer k = 15
        if t[i] == null then
            set t[i] = CreateTrigger()
            loop
                call TriggerRegisterPlayerUnitEvent(t[i], Player(k), p, null)
                exitwhen k == 0
                set k = k - 1
            endloop
        endif
        call TriggerAddCondition(t[i], Filter(c))
    endfunction
   
    function RegisterPlayerUnitEventForPlayer takes playerunitevent p, code c, player pl returns nothing
        local integer i = 260 + 16 * GetHandleId(p) + GetPlayerId(pl)
        if t[i] == null then
            set t[i] = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(t[i], pl, p, null)
        endif
        call TriggerAddCondition(t[i], Filter(c))
    endfunction
endlibrary
init
  Events
    Time - Elapsed game time is 0.00 seconds
  Conditions
  Actions
    Game - Set the time of day to 12
    Game - Turn the day/night cycle Off
    Visibility - Disable fog of war
    Visibility - Disable black mask
    Set VariableSet u = Creator of this System 0001 <gen>
    Custom script: call InitEquipment(udg_u)
    Game - Display to (All players) for 1000000000.00 seconds the text: |cffFF4231E|r|cffF34C37q|r|cffE7563Du|r|cffDB6043i|r|cffCF6A49p|r|cffC3744Fm|r|cffB77E55e|r|cffAB885Bn|r|cff9F9261t|r |cff87A66DS|r|cff7BB073y|r|cff6FBA79s|r|cff63C47Ft|r|cff57CE85e|r|cff4BD88Bm|r |cff3ACE9Ab|r|cff3AC299y|r |cff3AAA97T|r|cff3A9E96h|r|cff3A9295e|r|cff3A8694_|r|cff3A7A93W|r|cff3A6E92i|r|cff3A6291t|r|cff3A5690c|r|cff3A4A8Fh|r|cff3A3E8Ee|r|cff3A328Dr|r
    Game - Display to (All players) for 1000000000.00 seconds the text:
    Game - Display to (All players) for 1000000000.00 seconds the text: |cff08084AR|r|cff081255e|r|cff081C60q|r|cff08266Bu|r|cff083076e|r|cff083A81s|r|cff08448Ct|r|cff084E97e|r|cff0858A2d|r |cff086CB8b|r|cff0876C3y|r |cff088AD9d|r|cff089CDFr|r|cff089CD7a|r|cff089CCFk|r|cff089CC7e|r|cff089CBFn|r |cff089CAFk|r|cff089CA7o|r|cff089C9Fn|r|cff089C97i|r|cff089C8Fn|r|cff089C87g|r
    Game - Display to (All players) for 1000000000.00 seconds the text: |cffDE1919S|r|cffE0221Ah|r|cffE22B1Bi|r|cffE4341Ce|r|cffE63D1Dl|r|cffE8461Ed|r |cffEC5820m|r|cffEE6121o|r|cffF06A22d|r|cffF27323e|r|cffF47C24l|r |cffF99C25b|r|cffF6A023y|r |cffF0A81Fp|r|cffEDAC1De|r|cffEAB01Br|r|cffE7B419f|r|cffE4B817j|r|cffE1BC15e|r|cffDEC013r|r|cffDBC411t|r
    Game - Display to (All players) for 1000000000.00 seconds the text: |cff8C31A5V|r|cff84389Bi|r|cff7C3F91l|r|cff744687l|r|cff6C4D7Da|r|cff645473g|r|cff5C5B69e|r|cff54625Fr|r |cff44704Bm|r|cff3C7741o|r|cff347E37d|r|cff417645e|r|cff496F4Fl|r |cff596163b|r|cff615A6Dy|r |cff714C81.|r|cff79458BK|r|cff813E95C|r
    Game - Display to (All players) for 1000000000.00 seconds the text: |cff080842A|r|cff08144Dl|r|cff082058l|r |cff08386Eo|r|cff084479t|r|cff085084h|r|cff085C8Fe|r|cff08689Ar|r |cff0880B0m|r|cff088CBBo|r|cff0898C6d|r|cff08A4D1e|r|cff08B0DCl|r|cff08BCE7s|r |cff08BEE9b|r|cff08B2DEy|r |cff089AC8T|r|cff088EBDh|r|cff0882B2e|r|cff0876A7_|r|cff086A9CW|r|cff085E91i|r|cff085286t|r|cff08467Bc|r|cff083A70h|r|cff082E65e|r|cff08225Ar|r
    Game - Display to (All players) for 1000000000.00 seconds the text:
    Game - Display to (All players) for 1000000000.00 seconds the text: |cffFF3A3AV|r|cffEE443Ci|r|cffDD4E3Es|r|cffCC5840i|r|cffBB6242t|r |cff997646w|r|cff888048w|r|cff778A4Aw|r|cff66944C.|r|cff559E4Eh|r|cff44A850i|r|cff33B252v|r|cff22BC54e|r|cff2EB85Dw|r|cff41AD5Ao|r|cff54A257r|r|cff679754k|r|cff7A8C51s|r|cff8D814Eh|r|cffA0764Bo|r|cffB36B48p|r|cffC66045.|r|cffD95542c|
    Game - Display to (All players) for 1000000000.00 seconds the text:
    Game - Display to (All players) for 1000000000.00 seconds the text: |cff08216BT|r|cff08266Fo|r |cff083077g|r|cff08357Be|r|cff083A7Ft|r |cff084487y|r|cff08498Bo|r|cff084E8Fu|r|cff085393r|r |cff085D9Bc|r|cff08629Fu|r|cff0867A3r|r|cff086CA7r|r|cff0871ABe|r|cff0876AFn|r|cff087BB3t|r |cff0885BBs|r|cff088ABFa|r|cff088FC3v|r|cff0894C7e|r|cff0899CB/|r|cff1CA1D2l|r|cff269FCCo|r|cff309DC6a|r|cff3A9BC0d|r |cff4E97B4c|r|cff5895AEo|r|cff6293A8d|r|cff6C91A2e|r |cff808D96p|r|cff8A8B90r|r|cff94898Ae|r|cff9E8784s|r|cffA8857Es|r |cffBC8172e|r|cffC67F6Cs|r|cffD07D66c|r|cffDA7B60a|r|cffE4795Ap|r|cffEE7754e|r|cffF8754E.|r
    Game - Display to (All players) for 1000000000.00 seconds the text:
    Game - Display to (All players) for 1000000000.00 seconds the text: |cffC51919T|r|cffC01A19o|r |cffB61C19l|r|cffB11D19o|r|cffAC1E19a|r|cffA71F19d|r |cff9D2119a|r |cff932319f|r|cff8E2419u|r|cff892519l|r|cff842619l|r |cff7A2819e|r|cff752919q|r|cff702A19u|r|cff6B2B19i|r|cff662C19p|r|cff612D19p|r|cff5C2E19e|r|cff572F19d|r |cff4D3119w|r|cff483219a|r|cff433319r|r|cff3E3419r|r|cff393519i|r|cff343619o|r|cff2F3719r|r |cff253919w|r|cff203A19i|r|cff1B3B19t|r|cff163C19h|r |cff0A420Et|r|cff0B4211h|r|cff0C4214e|r |cff0E421Ai|r|cff0F421Dn|r|cff104220c|r|cff114223l|r|cff124226u|r|cff134229d|r|cff14422Ce|r|cff15422Fd|r |cff174235s|r|cff184238a|r|cff19423Bv|r|cff1A423Ee|r|cff1B4241/|r|cff1C4244l|r|cff1D4247o|r|cff1E424Aa|r|cff1F424Dd|r |cff214253s|r|cff224256y|r|cff234259s|r|cff24425Ct|r|cff25425Fe|r|cff264262m|r |cff284268t|r|cff29426By|r|cff2A426Ep|r|cff2B4271e|r|cff2C4274:|r
    Unit - Set life of u to 90.00%
Get SaveLoad Code
  Events
    Player - Player 1 (Red) skips a cinematic sequence
  Conditions
  Actions
    Custom script: call BJDebugMsg( GetLoadCode(udg_u) )
Use SaveLoad Code
  Events
    Player - Player 1 (Red) types a chat message containing (stringnoformat) as A substring
  Conditions
  Actions
    Custom script: call UnequipAll( udg_u )
    Custom script: call UseLoadCode(udg_u,GetEventPlayerChatString())
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope TestMapEvents initializer Init

    function OnEquip takes nothing returns boolean
        local item ite = CreateItem(GetTriggeringItemId(),0,0)
        call BJDebugMsg("|cffFF0202"+GetPlayerName(GetOwningPlayer(GetEquippingUnit()))+" |cff949596equipped |cffFFCC00"+GetItemName(ite)+" |cff949596on "+GetUnitName(GetEquippingUnit()))
        call RemoveItem(ite)
        set ite = null
        return false
    endfunction

    function OnUnequip takes nothing returns boolean
        local item ite = CreateItem(GetTriggeringItemId(),0,0)
        call BJDebugMsg("|cffFF0202"+GetPlayerName(GetOwningPlayer(GetEquippingUnit()))+" |cff949596unequipped |cffFFCC00"+GetItemName(ite)+" |cff949596from "+GetUnitName(GetEquippingUnit()))
        call RemoveItem(ite)
        set ite = null
        return false
    endfunction

    function Init takes nothing returns nothing
        call RegisterItemEquipEvent(function OnEquip)
        call RegisterItemUnequipEvent(function OnUnequip)
    endfunction

endscope