• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

MUI Advanced Equipment System (+Save/Load +Event)

This is my Advanced Equipment System

It is based on the same idea like many others: click on an item and it gets equipped, click on it in the equipment screen to unequip it.

It is advanced because it has many special options available!
Prevent unit types from equipping certain items.
Items may change animations.
Save/load code integration
and many more...

For explaination of the included functions check the documentations included in the map

Features:
  • decide whether a weapon is one or twohanded
  • give a unit a special animation tag, depending on the equiped item
  • an offhand tag will overwrite all mainhand tags (a shield will always cause defend animation)
  • functions for forcing equip/unequip
  • functions for getting information
  • functions for prohibiting a unit from equipping an item (for example for race-only items)
  • Save/load code generator included
  • Register Events to your triggers, firing on item equip and unequip
  • items can give countless abilities



my system is MUI, so every unit can have its own equipment, and easy to customize.
full documentation included.

New improved "How to import" and "How to Use" included, too!!

YOU NEED JNGP AND JASS KNOWLEDGE TO GET THIS WORKING! WITHOUT JNGP AND JASS KNOWLEDGE IT IS IMPOSSIBLE!

I importet some files!!!
the icons and models don't violate any rules, because they are necessary to show what this system can do!! credits ingame.

comment and if you like it maybe +rep^^
give credits when used

have fun

IMPORTANT:
For all who ask me to make the system in a spellbook:
That would be much more work for the users of this system and highly inefficient!!
I will not change that so don't ask me to do that anymore!




UPDATE v.1.5:
I read vercas suggestions and improved my scripting.
Adding an item is now much more simple^^
thx to vercas for his review

UPDATE v.2.0:
Tige_R found a bug, reseting the shield animation when another item got unequipped
fixed that!!

UPDATE v.3.0: BIG thx to teldrassil who found a huge bug which was settled in all my systems!!! i managed to fix it and updated ALL my newer systems!!!

UPDATE v.4.0: now there is no need anymore that the equipable items are of one itemclass! added system code to the description here

UPDATE v.5.0: it's possible now, to make items give up to 3 abilities when equipped instead of 1 in the previous versions...

UPDATE v.6.0: The bug fixed in v.2.0 was still there... now its really gone AND the script is 1.24 compatible

UPDATE v.6.5: added a new function (IsEquipmentClassEmpty) to check whether a specific unit has something from class x equipped
more information in the code

UPDATE v.7.0: added a new function (GetEquipItemID) to get an items rawcode which is equipped
more information in the code

UPDATE v.8.0: added 3 new functions (GetEquipItemIndex, EquipItemByIndex and EquipItemByID) to get an items index which is equipped (not the same as rawcode) and to equip a item by this index, which helps with the usage of Save/Load Systems
the last function makes you able to equip an item by its rawcode.
more information in the code

UPDATE v.9.0: again 2 new functions for prohibiting a unit from equipping an item or allowing it again for it(EnableItemEquipByID and EnableItemEquipByIndex) and a new function for getting the index of an item (not of its rawcode) --> GetItemIndex
Also much better performance because of the use of hastables!

UPDATE v.10.0: all O(n) searches are now replaced by hashtables!! also there is a new function (TransferEquipment) to move the equipment from unit a to unit b

UPDATE v.11.0: made the item registeration useable outside the library, improved documentation

Update v.12.0: created a how to import and structured the code a little more. also improved the empty-slot-icons

Update v.13.0: New code for equipping items and a new workaround for twohanded items

Update v.14.0: Reworked the beginning of the code, changed variable names, and removed a last rest of german i left in the testmap...


NEW versions:
Update v.2.0: At first I'd like to thank you for your great support!!
As so many of you love it I decided to refresh this a little!
Well i got a lot more experience since i first uploaded this and decided to remake the code... now takes advantage of much more efficient struct usage, doesn't need any hashtable anymore, runs smoother, more ways to work with (if you understand vJass), and many more new things...
Whole new documentation and new methods to work with!
Of course I kept the old names for most of the functions to make it easier for you to apply the new update!
SO: Have fun :D

Update v.2.1: Added Save/Load system, fixed the unequip function, added unequipAll function

Update v.2.2: Added Events and updated the "how to use"

UPDATE v.2.3: Thanks to creativeRPG for finding a very bad bug! i fixed it and suggest everyone to only use the new code!! the one from 2.2 may not work and freeze your game!

Update v.2.4: creativeRPG found more deadly bugs: you could equip items with all units you wanted to the unit owning the inventory and when equipping a one handed weapon while a two handed weapon was equipped the "offhand slot not available" button didn't vanish... fixed now! redownload is necessary!!!!!

Update v.2.5: aaaand again creativeRPG found a bug when you have too many items in your map the index gets too high for the system and it stops working

Update v.3.0: I chagned the whole code for equipping and unequipping and improved the ability handling:
its possible to get up to 50 abilitites from each item
added disbtns for my icons

Update v.3.1: Fixed bugs with syncing the inventories causing mass item creation on the map, made items in the dummys inventory undropable

Update v.4.0: Reduced Abilities per item to 20, fixed a bug for multiplayer usage preventing a second player from using the system, fixed an animation bug where the shield animation didn't disappear

Update v.5.0: New code cause the old one was buggy as hell :D works like a charm now

Update v.5.1: Fixed a bug regarding set Equipment[].owner=

Update v.5.2: Fixed a bug causing standard items to unequip registered equipment



JASS:
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

Keywords:
equipment, equip, system, item, hero, unit, bonus, stat, vjass, jngp, mui, mpi, animation, ability, save, load, hashtable, code, Event, events
Contents

Advanced Equipment System (Map)

Reviews
20:01, 26th Oct 2009 TriggerHappy187: Approved because of so many minimod approvals and high ratings. I also couldn't see anything wrong inside the code.
Me wants interface onEquip and onUnequip methods as I don't want the item to use abilities and no I don't want to work it out with dummy abilities.

(or maybe I can do this on my own, if I can have your permission to edit this for my own map? :D)


NEW UPDATE

added events for equip and unequip and releated functions;)

just look at the new events section in the test map to get a example usage
 
Level 5
Joined
May 25, 2009
Messages
103
Hello all,

i have worked so much with this system, you cant imagine ^^ - but only with gui and maaany dummy-abilities. I created set items and much more than 10 different versions of my heros by attack/defense.

But now i decided to rework all of this to get the new version - with save&load and with many of the new easier possibilites.

But is this system now only for one Hero?! (in the test-map there is also only one hero left :-S )
Since now i had simply to call InitEquipment(udg_u) and call InitEquipment(udg_u2)
But now it seems there is only one Equip-Dummy on the map, that one of the last Init.
What did i do wrong - eg. what have i to change?

Perhaps ists really easy, but it seems i have to ask... :)

Edit:
Oh
"my system is MPI for now (MUI is a bit unnecessary) and easy to customize.
full documentation included."

thats bad, i have a 2 Player Map that could also be played by single player - every trigger is build on this possibility.
Do i have any method to solve this?

plz help in time, cause i want my map as a xmas gift :)
 
Last edited:
Hello all,

i have worked so much with this system, you cant imagine ^^ - but only with gui and maaany dummy-abilities. I created set items and much more than 10 different
[...]
Do i have any method to solve this?

plz help in time, cause i want my map as a xmas gift :)

Hey :)
I made my system MPI cause I thought this might be more usefull and require a shorter code...
I would have to change much of the code to make it MUI, loosing efficiency...

So maybe if there are more people demanding this but not for now! sorry!
 
Level 5
Joined
May 25, 2009
Messages
103
Hi,
thank you for your early answer.

So i have to decide, but its quite easy.
Cause my map should be a 2-Player map in first case i will take the new one and add "Cheat"-triggers to copy all equipped abilities to the second hero for singleplayer - not really good, but i will see. I could differentiate by items.
I am already worked into the new system, and its really much easier than before, but i am proud of having all these oportunites in difficult nestlings of triggers, dummyspells/units before you wrote them in jass ^^

But thanks to have this so easy now, so i could go on very fast despite the wasted reworking time.

Best regards
 
Hi,
thank you for your early answer.

So i have to decide, but its quite easy.
Cause my map should be a 2-Player map in first case i will take the new one and add "Cheat"-triggers to copy all equipped abilities to the second hero for singleplayer - not really good, but i will see. I could differentiate by items.
I am already worked into the new system, and its really much easier than before, but i am proud of having all these oportunites in difficult nestlings of triggers, dummyspells/units before you wrote them in jass ^^

But thanks to have this so easy now, so i could go on very fast despite the wasted reworking time.

Best regards

you make the second hero still owned by the other player but share its control to the other player that is playing in SP to easily solve your MPI problem...
 
Level 5
Joined
May 25, 2009
Messages
103
Hey!
Really thanks!
This way i use already *lol* for shared control with some pets....
Sometimes we simply need a little help ^^

thx

€dit: But than it would also be player 1 who klicks on the item on the shared Hero. I will test it, but i sadly think, that this wont work.


€dit2: I got a problem!

I cant handle "ChangeEquipmentOwner" :-S
Every trigger i have that in stops and makes nothing.

Here is my Test-Trigger:
Test
Ereignisse
Unit - XY <gen> takes damage {or something like this}
Bedingungen
Aktionen
Custom script: call ChangeEquipmentOwner(Player(0), GetTriggerUnit() )

{or this:}

Custom script: call ChangeEquipmentOwner(Player(0), udg_u2 )

and nothing happens, also if there are more actions below this - they also dont happen

What did i do wrong?

thx :-S

--> it doesnt work in your test-map either

Could nobody say me, what i did wrong or how it works, or is there really a bug? :-(
 
Last edited:
Level 8
Joined
Oct 11, 2009
Messages
40
Killer system. But a few suggestions...

1) Include DISBTNs of the empty slot icons.
2) Why not give the inventory dummy an inventory of its own that mimics the hero's inventory? So when you're in equipment view, you can equip/unequip items without having to go back and forth between views.
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
Killer system. But a few suggestions...

1) Include DISBTNs of the empty slot icons.
2) Why not give the inventory dummy an inventory of its own that mimics the hero's inventory? So when you're in equipment view, you can equip/unequip items without having to go back and forth between views.

1. Is kinda easy to just export :p

2. That would require an insane amount of dummy items. Or you use the normal dummy items but I get your point, it's not bad at all.
 
Level 1
Joined
May 26, 2007
Messages
4
I imagine this won't work with Warcraft Version 1.24 because the JNPG doesn't seem to work with a version beyond 1.21? Correct?
 
Level 1
Joined
May 26, 2007
Messages
4
I imagine this won't work with Warcraft Version 1.24 because the JNPG doesn't seem to work with a version beyond 1.21? Correct?

Yeah I did that. Hmm perhaps it is Window's 7 maybe? I am not really a noob to any of this and I am sure I did everything correctly. I had already granted permission and everything but the program itself just doesn't start up even if running it as an Admin
 
Yeah I did that. Hmm perhaps it is Window's 7 maybe? I am not really a noob to any of this and I am sure I did everything correctly. I had already granted permission and everything but the program itself just doesn't start up even if running it as an Admin

then maybe its a w7 prob... because it works fine for me and for everyone else using wc3 1.24e...
 
Level 2
Joined
Apr 26, 2010
Messages
14
Help me please :( . Let say I have 2 item of class boot. I equip once then click the other boot, it perfect toggle equip but... the ItemUnequip Event does'nt fire correctly :( .
 
Level 2
Joined
Apr 26, 2010
Messages
14
uhm... on the item equip event, i add 5 streng to the equiped unit and remove that 5 streng on the item unequip event.... so if the unequip event does'nt fire correctly then this unit's streng rise 5 every time i toogle equip between 2 boot... srr for listening my bad english :(
 
Level 2
Joined
Apr 26, 2010
Messages
14
JASS:
scope TestEquip initializer init
//====================
//Setup
//====================
globals
    //Common config:
    private constant integer ITEM_ID = 'I000'
    private constant integer ICON_ID = 'A00K'
    private constant integer ITEM_CLASS_ID = 3
    private constant boolean ENABLE = true
    
    //equip condition
    private constant integer LV_REQUIRE = 0
    private constant integer STR_REQUIRE = 0
    private constant integer AGI_REQUIRE = 0
    private constant integer INT_REQUIRE = 0
    private constant string NOTICE = "Can't equip, you do not meet the require!"
    
    //bonus:
    private constant integer ABI_1 = 0
    private constant integer ABI_2 = 0
    private constant integer ABI_3 = 0
    private constant integer BONUS_ARMOR = 5
    
    //for weapon only:
    private constant boolean TWO_HAND = false 
endglobals


//====================
//End Setup
//====================

private function equipCon takes nothing returns boolean
    local unit e = GetEquippingUnit()
    
    return GetHeroLevel(e) >= LV_REQUIRE and GetHeroStr(e,false) >= STR_REQUIRE and GetHeroAgi(e,false) >= AGI_REQUIRE and GetHeroInt(e,false) >= INT_REQUIRE
endfunction

private function onEquip takes nothing returns nothing
    local unit e = GetEquippingUnit()
    
    if equipCon() then
        //--------------------------------
        //Bonus add here:
        //*I use the Status sytem by j4ly
        //--------------------------------
        call Status[e].modArmorBonus(BONUS_ARMOR)
        //--------------------------------
    else
        call UnequipItemByClass(GetOwningPlayer(e),ITEM_CLASS_ID)
        call BJDebugMsg(NOTICE)
    endif
endfunction

private function onUnequip takes nothing returns nothing
    local unit e = GetEquippingUnit()
    
    //--------------------------------
    //And remove here
    //--------------------------------
    call Status[e].modArmorBonus(-BONUS_ARMOR)
    //------------------------------
    
endfunction

private function con takes nothing returns boolean
    return GetTriggeringItemId() == ITEM_ID
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local trigger t2 = CreateTrigger()
    
    call TriggerRegisterItemEquipEvent(t)
    call TriggerAddCondition(t,Condition(function con))
    call TriggerAddAction(t,function onEquip)
    
    call TriggerRegisterItemUnequipEvent(t2)
    call TriggerAddCondition(t2,Condition(function con))
    call TriggerAddAction(t2,function onUnequip)
    
    if ENABLE then
        //                                       itemid  | abi 1 | abi2 | abi3 | icon  | class       | twohanded? | animationtag
        call AdvancedEquipmentSystem_RegisterItem(ITEM_ID,  ABI_1, ABI_2, ABI_1,ICON_ID,ITEM_CLASS_ID,    TWO_HAND,           "")
    endif
    
    call InitEquipment (gg_unit_H000_0001)
endfunction

endscope
 
on first check... it only bugs if I click the boots with no effect, while I'm equipped with the other boots which has the + armor...

I think this is because when an item is unequiped due to the equipping of another, the unequip method and event doesn't run... so you better tell him about this...

@The_Witcher - currently the unequip event can cause bugs since it is not fired when an item is unequiped due to equipping another item (it is only fired when the item is unequiped manually or when the item is a two-hand weapon)... so please fix that... (this is just on first look so there might be some other error, and this might not be the real cause) ^_^
 
Level 2
Joined
Apr 26, 2010
Messages
14
yes, this is the (only) big problem. I think the unequip event doesn't fire in that case... so this system need fix ?
 
Level 2
Joined
Apr 26, 2010
Messages
14
on first check... it only bugs if I click the boots with no effect, while I'm equipped with the other boots which has the + armor...

this is because when an item is unequiped due to the equipping of another, the unequip method and event doesn't run... I could fix this myself but this is The_Witcher's system so I would not edit it without his consent, so you better tell him about this...

@The_Witcher - currently the unequip event can cause bugs since it is not fired when an item is unequiped due to equipping another item (it is only fired when the item is unequiped manually or when the item is a two-hand weapon)... so please fix that... ^_^

I'm not sure about the return of The_Witcher in this topic. Can you pm me the fix-yourself code? Please, i need it 4 my project
 
yes, since its a problem with the AES code, we should just wait for The_Witcher to see this and fix it... or you can PM him about this...

edit: please don't double post... use edit button...

Sorry but I refuse to edit it and send it to you. If this was a prob of a code specific to ur map, I would but since the problem is about the system itself, its better if The_Witcher fixes this himself so that the resource would get updated and so that other users of this system won't get the same error...
 
Big update

New update for my System!

DISBTNs are included now

The dummys inventory now syncs with the owners so you can equip even in the inventory view

every item registered to the system can now give up to 50 (!) abilities

fixed the issues with the events

please PM me for bug reporting! I read all my PMs but reading all comments is a bit too much ;)
 
wow, 50 abilties... that's insane... ^_^

testing...

EDIT: looked at the code, and wow, it could even support more than 50 abilities... (who would add 50 to an item anyway?)

this is pure EPICNESS.

who would use more than 50 abilities on a single item :D
actually i would be able to increase up to 8192 abilities for each item :p

but the higher the value, the more inefficient can get this system!
 
Level 7
Joined
Nov 4, 2006
Messages
153
There are some bugs that I found:

1) If you click items on the main hero fast enough, then duplicates will be created at the dummy's location.
To see this yourself: grab two of the same shield and continuously equip the one in the first slot quickly.

2) When the dummy is selected, you can right click an item and left click the dummy's portrait to drop the item at its location. Do this two or three times. After that, equip/unequip any items. Duplicates of items are created on the group every time.

3) Moving items in the dummy's inventory doesn't change the item's position for the hero.

PS: Are there more models that have lots of animations such as the one in the demo? :)
 
Last edited:
Level 2
Joined
Apr 26, 2010
Messages
14
That's fucking perfeck. From 3 abi to more than 50 :) thank you the witcher. You help my life easier. But i see some one find some bug. Can you fix all?
-------------------------------------
I have to create 1 trigger that remove item dropped from dummy unit inventory now to prevent items duplicating :D. But I belive The_Witcher will fix it soon :)
 
Last edited:
There are some bugs that I found:

1) If you click items on the main hero fast enough, then duplicates will be created at the dummy's location.
To see this yourself: grab two of the same shield and continuously equip the one in the first slot quickly.

2) When the dummy is selected, you can right click an item and left click the dummy's portrait to drop the item at its location. Do this two or three times. After that, equip/unequip any items. Duplicates of items are created on the group every time.

3) Moving items in the dummy's inventory doesn't change the item's position for the hero.

PS: Are there more models that have lots of animations such as the one in the demo? :)

thanks! fixed all yiour issues except (3)

Update v.3.1: Fixed bugs with syncing the inventories causing mass item creation on the map, made items in the dummys inventory undropable
 
Level 15
Joined
Sep 27, 2009
Messages
669
I read all in "How to Use" but didn't found :grin:
Ok here it is, can you tell me what is that what i need to do?

JASS:
what this is:
- Equipment System
- MPI
- in vJass

what this not is:
- Inventory System
- in GUI/normal Jass
- exportable to GUI or normal Jass
- MUI(coming soon)

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

this system isnt that perfekt that it can do everything on its own ;D
with the following function you can register items to the system:

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
     
Example:
  call AdvancedEquipmentSystem_RegisterItem('I004', 'A008', 1, false, "Alternate")
  registers item 'I004' to the system.
  the item gets equipped in slot 1 and is not twohanded
  as long as the unit has this item equipped it will play its "Alternate" animations

  
until now your items have no effect when equipped... 
you can add up to 50 abilities to one itemtype!
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:
  call AdvancedEquipmentSystem_AddItemAbility('I004', 'A002')
  a unit will get the ability 'A002' when equipping an item of type 'I004'


--------- 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 ---------

EnableItemEquip takes player p, integer id, boolean flag returns nothing
  with this function, you can disable/enable the equipping of a special item
  
  Example:
    call EnableEquipment(Player(0), 'I001', false)
    => Player 1 cant equip the item 'I001' anymore, until it gets enabled again
    

    
IsEquipmentClassEmpty takes player p, integer class returns boolean
  sometimes you amybe want to know whether a unit has something equipped in class xy...
  
  Example:
    If IsEquipmentClassEmpty(Player(0),2) then
       ...
    endif
    => only if the unit owned by Player 1 which has the Equipment has nothing equipped in slot 2
        the if then else block releases his actions


EquipItem takes player p, item ite returns nothing
  to force equipping of a special item use this function
  
  Example:
    call EquipItem( Player(0),GetManipulatedItem() )
    => the unit owned by Player 1 which has the Equipment equips the manipulated item
    
    
function UnequipItemById takes player p, integer itemid returns nothing
function UnequipItemByClass takes player p, integer class returns nothing
  two functions which do the same but with different parameters:
  player p is always the owner of the unit with the destination equipment
  first function uses itemid... it is the rawcode of the item which gets unequipped (system searches the class)
  second function uses class... it is the number of the class of which the equipped item gets unequipped
  
  Examples:
    call UnequipItemById(Player(0),'I002') => if equipped, item of type 'I002' is unequipped now
    call UnequipItemByClass(Player(0),2) => item equipped in class 2 is unequipepd now



GetEquippedItemTypeId takes player p, integer class returns integer
  this function returns the rawcode of the item equipped in the given class
  
  Example:
    If GetEquippedItemTypeId(Player(0),1) == 'I005' then
      ...
    endif
    => only if the unit owned by Player 1 which has the Equipment, has a item of type 'I005'
        in slot 1, the if then else block releases his actions
        (useful for: if unit blaa has equipped sword xy then...)
        

ChangeEquipmentOwner takes  player p, unit newOwner returns nothing
  if you have to transfer the Equipment to another unit use this function
  
  Example:
    call ChangeEquipmentOwner(Player(0), GetTriggerUnit() )
    => the triggering unit gets the Equipment the unit of Player 1 has at the moment
    
--------- 4)    Save/Load Codes    (4 ---------
I added functions for getting and applying save and load codes to this system
  
    function SaveEquipment takes player p returns string
      this function returns the current load code from the equipment of player p
      
    function LoadEquipment takes player p, string LoadCode returns nothing
      this function loads a given code "LoadCode" into player ps equipment

--------- 5)    Trigger Events    (5 ---------
you can register events to triggers which fire when a item is equipped or unequipped

    function TriggerRegisterItemEquipEvent takes trigger t returns nothing
    
    and
    
    function TriggerRegisterItemUnequipEvent takes trigger t returns nothing
    
    are pretty self explaining...
    
    use GetTriggeringItemId and GetEquippingUnit to get the involved units

--------- 6)    To all vJassers out there    (6 ---------
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 EquipmentItem
  methods
    create takes integer id, integer abi1,integer abi2,integer abi3, integer icon, integer class, boolean twohanded, string animation returns EquipmentItem
       => same as AdvancedEquipmentSystem_RegisterItem
  members
    readonly integer id     => the item rawcode
    readonly integer class  => the assigned class
    readonly integer abi1   => the first ability this item adds
    readonly integer abi2   => the second ability this item adds
    readonly integer abi3   => the third ability this item adds
    readonly integer icon   => the icon ability added to the dummy
    readonly boolean twohanded  => whether the item is twohanded or not (always false for non mainhand items)
    readonly string  tag    => the animation tag added when the unit equips this (always "" for non main- and offhand items)
    
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 item ite returns nothing   => equips a special item
    unequip takes integer class returns nothing => unequips whatever is in the given class
  members
    readonly unit dummy  => the equipment dummy unit
    readonly boolean array enabled  => boolean whether this unit can equip item xy (inside the array is the items rawcode)
    readonly EquipmentItem array Item  => the equipped EquipmentItem in the slot given as array
             unit owner => self explaining... use set yourequipment.owner = yourunit to transfer the Equipment to another unit



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

The_Witcher
 
Top