• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Solved] strange hashtable problem

Status
Not open for further replies.
Level 9
Joined
Jul 10, 2011
Messages
562
hey all...

i nearly got my item restriction system to work as intended theres just one thing left....the hashtable saving the unit-types for the desired item level (item levels are my classes^^).

now there a problem occuring that is strange.

i use this line to save the unit-type in the hash :
  • Hashtabelle - Save (GetUnitTypeId(GroupPickRandomUnit(GetUnitsOfTypeIdAll('H02J')))) as 1 of 1 in (Last created hashtable)
all units are preplaced on the map and removed when map starts so the problem is not that there is a unit with the id H02J.
but somehow i can use this line afterwards to save the next unit type:
  • Hashtabelle - Save (GetUnitTypeId(GroupPickRandomUnit(GetUnitsOfTypeIdAll('H02O')))) as 2 of 1 in (Last created hashtable)
the first number is the number of the unit and im looping through them whenever an item is picked up. the second number is the item level.

so for the unit-type with the unit id H02J its working perfectly but the second unit type isnt registered somehow and i dont know whats the problem.

anyone has an idea?

greetz clapto
 
Level 9
Joined
Jul 10, 2011
Messages
562
i have each hero i use in my ORPG preplaced on my map and remove then when 0.00 game time is expired.

so and i save the unittypeID in a hash (or better try to) and i use (GroupPickRandomUnit(GetUnitsOfTypeIdAll('UNITRAWCODE'))) because its easier that way and there's just one unit of each type.

so and the problem is that no matter which way i try to save them (i also tried save the unittypeID as string and compared the strings with a I2S unittypeID of the unit picking up the item; also i tried to show the unittypeIDs ingame and wrote the unittypeID directly as string (as integer it wasnt possible because the number was too long), and so on) only the unittype saved as 1 of 1 works every other unittype is not recognized although the unittypeID is definitly saved (used a debug message).


and i wanna use the saved unittypeIDs to check whether the unittype of the unit picking up an item is allowed to pick up the item. because that i save the 'unittypeID as X of 'itemlevel' in Hash' and loop through them everytime a unit picks up an item. (X is just an increasing integer)


i hope you got it now. :D
 
Picking random units will not load properly, like purge said, save the unit type directly to the ID of the item itself rather than the random unit...
and i wanna use the saved unittypeIDs to check whether the unittype of the unit picking up an item is allowed to pick up the item...
the item means he cant pick up the same item?...
 
Level 9
Joined
Jul 10, 2011
Messages
562
that was just 1 solution i tried.

i also tried to save the unittypeID directly like :
  • Hashtabelle - Save 1211118154 as 1 of 1 in (Last created hashtable)
  • Hashtabelle - Save 1211118159 as 2 of 1 in (Last created hashtable)
  • Hashtabelle - Save 1211117637 as 3 of 1 in (Last created hashtable)
but it just works for the unittype saved in 1 of 1 too....:ogre_rage:

the item means he cant pick up the same item?...

yes and no^^
in the trigger running on picking up an item i check the item level (item levels are my classes ; they are saved as the 'of X' in the hash) i check whether the unit already has an item of the item levels (i have 8 different item levels for different 2 handed weapons, 5 item levels for different 1 handed weapons & 1 item level for shields), whether it already has something in the slot for this type of item and whether this unittype (class) is able/allowed to carry this type of weapon. if it is i put the item in the right slot and if anything is not as it should be (slot is filled, unittype isnt allowed to carry this weapon type) i drop the item again.


the system itself works perfectly. the problem is that its not possible somehow to save the unitypeIDs in the hash to be able to check whether the unittype is saved 'as "X" of "item level" in "Hash"' ... just the unittype saved as '1 of (item level) 1 in Hash' works....every other unit type (no matter if it was saved in the hash or not) just drops the item with the message 'You're not allowed to carry this weapon.' means the message appearing whenever a unittype that isnt saved in the hash (at least it should be just if its not in the hash)...the unittype are just not recognized and i dont understand why just '1 of 1 in Hash' is working and every other saved unitype not.
 
Use custom script call SaveInteger(table, missionKey, key, value) and set variable = LoadInteger(table, missionKey, key)

And save unit Id like this, even if there is or there isn't units on map, it doesn't mater.
  • Custom script: call SaveInteger( udg_HASH, 'UNITRAWCODE' , key, value)
so here is actual example:
  • Custom script: call SaveInteger( udg_Hash, 'hfoo' , 0, 10)
  • Custom script: call SaveInteger( udg_Hash, 'hfoo' , 1, 20)
  • Custom script: call SaveInteger( udg_Hash, 'hfoo' , 2, 30)
  • Custom script: call SaveInteger( udg_Hash, 'hkni' , 0, 5)
  • Custom script: call SaveInteger( udg_Hash, 'hkni' , 1, 10)
  • Custom script: call SaveInteger( udg_Hash, 'hkni' , 2, 15)
We saved some values into 1,2 and 3 as child of fathers: kfoo (footman Id) and hkni (knight id)

so for some item drop you can do it like this:
  • Here you go
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Killing unit)) Equal to Peasant
    • Actions
      • Custom script: set udg_Index = LoadInteger ( udg_Hash, GetUnitTypeId(GetTriggerUnit()), GetUnitLevel(GetKillingUnit()) )
      • If (Index Equal to 0) then do (Skip remaining actions) else do (Do nothing)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Index Equal to 1
        • Then - Actions
          • Item - Create Tome of Experience at (Center of (Playable map area))
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Index Equal to 2
            • Then - Actions
              • Item - Create Crown of Kings +5 at (Center of (Playable map area))
            • Else - Actions
              • Item - Create Wand of Illusion at (Center of (Playable map area))
 
Level 9
Joined
Jul 10, 2011
Messages
562
first of all thanks -Kobas- :D

then ive got a question...

if i understand it right you gave me an example to save integer values which can be called from unittypes....but i need it the other way round. i need to get the unittype by checking through integers.
i wanna do the following : whenever an item is picked up i loop through the part of the Hash so i need to save the following :
Hashtabelle - Save 'UnitType' as 'X' of 'item level' in 'hash'
(UnitType = Unittype able to carry this type of item ; X = integer value to differ the unit types in the hash ; item level = item levels are my classes so i set the item level 1 for 1 item class and so on)
and when an item is picked up i loop through all unit types saved in the item level (i saved the max value of X for item level as
Hashtabelle - Save 'MaxValue' as 0 of 'item level' in 'hash') and check whether the unit type is saved as one of the X values for the item level of the item picked up.


EDIT: oh and if i save a unittype with a rawcode do i have to set 'custom_RAWCODE' or just the rawcode for selfmade units?

EDIT2: could you give me an example line for saving the value as i need it and load the value as i need it?
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
claptomanic, what do you exactly want to achieve? Seems like you want to have specific items for specific classes in an RPG, and prevent a Warrior from picking an Archer's Bow.
 
Level 9
Joined
Jul 10, 2011
Messages
562
that nearly what i want to achieve ^^

so...
i have several item classes just certain heroes can wear (8 different 2-handed weapon types, 5 different 1-handed weapon types and shields) so and i made a system to loop through the unit type (thats the part thats not working because the hash has this strange problem) saved for this certain item level (which defines the item classes ; for example 2-handed swords or 1-handed axes) to check whether this certain unittype is allowed to wear this item and then do some actions if or if not. to be specific each unittype has max 2 different item classes its able to wear.
so and everythings working perfectly beside the hash in which the classes are defined for the certain item levels.

thats it. but why do you ask?


p.s. in total i have 20 different item classes (define all item types like boots, rings, pots, and so on) and each is restricted to a certain slot and to certain unittypes. also when a 2-handed weapon is picked up successful a dummy item is added to fill the second hand (a certain slot).
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I ask because I sense you're not doing it the most efficient way.

I think yo should do something like this

JASS:
// Boots = 1
// Shields = 2
// 1Handed = 3
// 2Handed = 4
// Bow = 5

//           |Table| ItemID | ItemClass | Level | 2Handed 
call ItemData(Hash,  'i00k',      2,        15,    false) // Level 15 Shield
call ItemData(Hash,  'abcd',      4,        7,     true) // 2H Weapon level 7
call ItemData(Hash,  'efgh',      1,        1,     false) // Boots level 1
call ItemData(Hash,  'ijkl',      3,        4,     false) // 1H Weapon level 4
call ItemData(Hash,  'zzzZ',      5,        4,     true) // Bow level 5

I Hope you understand :)

When a hero acquires an item, you can check on the ItemID
1. The Item Class (Bow, Boots, Shield, etc)
2. The Item Level Requirement (If there's any)
3. If the item is one handed or two handed

You can use the same method to store as many requirements or classifications your items have, and compare all that with the hero data.
 
Level 9
Joined
Jul 10, 2011
Messages
562
that looks intresting O.O

but that causes me to ask several questions/mentions :

1. why is your way more efficient? because i need to save several unittypes for certain itemlevels and nothing else Oo (everything like 2-handed or not and so on is already saved in the system itself) in your way i have to set about 100 (or even more) saves with several of 81 unittypes repeating in several item classes (means i have write (at least if its possible) 12-15 unittypes in your data save for about 100 items -> 1500 rawcodes! and beside that i also have to write all the items. and beside that i dont even know how to set several unittypes for each item. because each item level has certain unittypes who are able to wear this type of item and in your way i save things like level requirement (not existing in my map) 2-handed or not (item levels 1-8 are 2 handed) but not the unittypes for each itemlevel. i hope you get what mean.

2. even if your way were the most effient (and at the moement i doubt it) i would have to write 1600 rawcodes (at least) instead of writing down 12-15 rawcodes for 20 itemlevels -> 300 rawcodes. thats one-fifth of the rawcodes i would have to write down in your way.

3. even though i thank everybody here for helping in my eyes the version of -Kobas- seems the most fitting for me at least if its possible to change it the way i mentioned (calling the unittype from integers and not integers from unittypes).

i hope you know what i mean and youre not angry about my post. ;D

if anybody could tell me how to change -Kobas- way to the one i need and how to call it then i would be very happy.

clapto
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I think you're thinking this too much. You talk as it's something really complicated, when it isn't :) I'm not mad about your post, and there's no need for those 1500 raw codes and stuff...

If you save an item as a Bow, and Bows are identified with a #5, and you don't want your warrior to have a bow (any bow), you save a #5 in the warrior id, then you campare, if both numbers match, drop the item. Hows this translated to 1500 lines of coding?

If you have 100 items, and 15 heroes, you just need 115 lines of coding to store all the item classes heroes are available to use, 100 for item configuration, and 15 for hero configuration.

So far, what's exactly what you want? You don't want your Mage to be walking around with an Archer's Bow? It's just that? Is there something else to be aware of, besides an item-type not being allowed to be picked by a certain unit-type?

How many heroes do you have? How many items do you have?
 
Level 9
Joined
Jul 10, 2011
Messages
562
If you have 100 items, and 15 heroes, you just need 115 lines of coding to store all the item classes heroes are available to use, 100 for item configuration, and 15 for hero configuration.

could you make an example line for a hero config? i dont get it.

Is there something else to be aware of, besides an item-type not being allowed to be picked by a certain unit-type?

yes there is another restriction. beside the restriction that just certain heroes are able to wear certain item types (defined through levels) theres also a slot restriction means each item is just wearable if the required slot/s is/are free.

How many heroes do you have? How many items do you have?

i have 81 heroes and will have about 400 items (maybe more).
 
Level 25
Joined
Jun 5, 2008
Messages
2,573
Or you know... use a simple integer array.

Each hero has an integer array, example warrior:

{1,2,3, 6, 9}

1 - armor
2 - boots
3 - helmet
6 - sword
9 - shield

number of available equipment for warrior: 5

Bow type is #4 so when you pickup a bow type you go through all 5 integers for warrior, if 4 isn't inside it (and it isn't) you drop the item.

Quite simple.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Item Config

You can configure the Item classes with any index you want. This is just an example with 5 Item Classes, just identifying the Item-Class with an index in the Hash. All of these saved on slot 0 of the ItemType Id. This list would have all your 400 items, manually indexed based on it's item type. You can use the Item data in the Object Editor, but if you want to edit several items in the future, you would have to modify several of them, and editing the data in this list is a lot easier than doing it in the OE. It's up to you. I would use the same Hash to store the item class and item slot requirement.
JASS:
// Boots = 1
// Shields = 2
// Axes = 3
// Swords = 4
// Bow = 5

//              |Table| ItemID | ItemClass
// Shield of Fire
call SaveInteger(Hash,  'i00k',      2) // Shield
// Sword of Ice
call SaveInteger(Hash,  'abcd',      4) // Sword
// Boots of Flash
call SaveInteger(Hash,  'efgh',      1) // Boots
// Wood Axe
call SaveInteger(Hash,  'ijkl',      3) // Axe
// Ancient's Bow.
call SaveInteger(Hash,  'zzzZ',      5) // Bow

Hero Config

There's a "dumb" way for this, which is the one I like the most xD. You would just do this 81 times, once per hero, and each line with the Hash, UnitTypeID, and the 22 item classes booleans (1/0)

JASS:
// 0 means "Useable" - 1 Means "NotUseable"
// Boots = 1
// Shields = 2
// Axes = 3
// Swords = 4
// Bow = 5
//           Table HeroTypeID Boots Shields Axes Swords Bow
call HeroData(Hash,  'hook',    0,     0,     1,   0,    0)

So, if Axes are represented with a "3", and Mages CANT use an Axe, You save a "1" (as Not-Usable) as 3 of MageUnitTypeId in Hashtable.

When the unit acquires an item, you check the slot 0 of the manipulated Item Id
JASS:
Set ItemClass = LoadInteger(Hash, 0, GetItemTypeId(GetManipulatedItem())
// If the item is an Axe, then "ItemClass = 3"

If LoadInteger(Hash, ItemClass, GetUnitTypeID(GetTriggerUnit()) = 1 then
    // Display Message: "This Hero isn't allowed to carry this item class"
else
    If -Required Item Slot is available- then
        // Equip the item
    else
        // Display message: "Slot is already occupied"
    endif
endif

<< EDIT >>

What Kingz suggested works, but you would require 81 arrays (one for each Hero Unit Type) and 10+ integer variables to know the available amount of item classes for each Unit-Type, and loop through 22 indexes everytime an item is acquired, which is more resource-consuming, and basically, requires the same work and time it would require to do it with the Hashtable.
 
Level 25
Joined
Jun 5, 2008
Messages
2,573
Or the better solution:

Let's say you have, what, 50 item types?
Then the following example works with 162 heroes max.

JASS:
globals
 private constant integer WEAPON_CODE = 0
 private constant integer ARMOR_CODE = 1
 // setup everything here
endglobals

struct hero
 integer   unitId
 boolean array equipableId[50]

 method add takes integer i returns nothing
     set .equipableId[i] = true
 endmethod

 method save takes nothing returns nothing
   call SaveInteger(Hashtable, .unitId, 0)
 endmethod

 static method operator [] takes integer i returns thistype
     local thistype this = LoadInteger(Hashtable, i, 0)
    return this
 endmethod
endstruct


private function setupHeroes takes nothing returns nothing
 local hero a = hero.create()
 set a.unitId = 'h000'
 call a.add(ARMOR_CODE)
 call a.add(WEAPON_CODE)
 call a.add(HELM_CODE)
 call a.add(SHIELD_CODE)
 call a.save()

 // a new hero
 set a =  'h001'
 call a.add(ARMOR_CODE)
 // etc, etc, as much as you want.
endfunction

private function acquiresItem takes nothing returns nothing
 local integer id = GetUnitTypeId(GetTriggerUnit())
 local integer itemId = GetItemTypeId(GetManipulatedItem())
 local hero h = hero[id]
 if h.equipableId[itemId]  then
   // hero can equip/hold item
 else
  // hero can't hold/equip item
 endif
endfunction

This is much faster than all those hashtable calls.
 
Level 9
Joined
Jul 10, 2011
Messages
562
okay ill give it a try later Spartipilo...if youre really nice you would complete the trigger (to make it much easier for me) for the a unit acquires an item with:

item slot check (and moving the item to the desired slot), 2-handed weapon check (and adding a dummy unit to slot X), messages if the item isnt allowed to be worn or the slot is filled and the dropping itself. also please add a line setting the custom value to 0 (i use it for ownership) if the item is dropped.


would be really really really nice if you would do that because my jass knowledge is small^^ sadly...

+rep and credit would be given for sure....and for sure a big big 'thank you' xD
 
Level 25
Joined
Jun 5, 2008
Messages
2,573
I think it's faster to use 81 arrays than all those hashtable calls again.
(might be a pain to generate tho, 81 variables)
I mean, hashtable uses resources again, it's not like that data is hanging in the air.

Indexing is 4x faster than hashtables and you don't need to loop through arrays you use the direct way of accessing data.

You use the:

array[id] == true

If yes, the hero can equip the item which has the id as it's type.
Like for example:

if equipable[BOW_ID] == true then the hero can equip all bows, if it's false he can't.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I'm taking a look at Kingz last suggestion. My trigger implies a custom function which actually calls 22 SaveInteger function per hero (81 x 23 = 1782) + 2 SaveInteger for each item (400 x 3 = 1200). That would increase the loading time. After that, the trigger itself to detect the picked item, the item class, and slot, is pretty easy and fast.

I'd like to know how his suggestion works, since I don't know vJASS.

@Kingz, clapto is talking about 81 Heroes and 400 Item-Types, of 22 different classes, with restricted slot usage. How wold your system be for that?
 
Level 9
Joined
Jul 10, 2011
Messages
562
i think both ways would be a pain to do because i have 20 item classes and 81 heroes^^ so in the array way it would be 1620 booleans to set...O.O

in the hash i would have about 400 item configs and 81 hero configs and thats a sum of 481 sets...so (im a lazy one ^^) i would choose the hash way because its less to write xD
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
The strong part I see in Kingz system is that it saves only the items that are useable, while my system requires saving all of them.
 
Level 9
Joined
Jul 10, 2011
Messages
562
there are 2 thing leading me to the hash version :

1. as far as i understand both hash is much less to write
2. i dont really understand the code of Kingz version ^^
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Wait a bit... He's probably working on it. I'm also breaking my head with the desk to find a way to optimize mine....

Ok... I found it. To optimize my way you have to do it Manually. Instead of saving 0 for all the items you can use. Just save "1" in the item slots you know the hero can't use. Using the custom function is "prettier" but by far slower.

JASS:
// Warrior can't use Bow (5) and Staves (12)
call SaveInteger(Hash, 5, 'asdf', 1)
call SaveInteger(Hash, 12, 'asdf', 1)

// Mage can't use Shields (2) and Axes (19)
call SaveInteger(Hash, 2, 'asdf', 1)
call SaveInteger(Hash, 19, 'asdf', 1)

// and so on...
 
Level 25
Joined
Jun 5, 2008
Messages
2,573
Hmmh this could be aproached differently, with item pools and making it fully vjass.

But as that would require quite a bit of knowledge of vjass for the user to use, i guess using hashtables is okay.

Still the number of calls is dramatic, it can be lowered down to 481 at map initialization and that is pushing it.

edit:

JASS:
globals
     private constant integer ITEM_CLASS_COUNT = 22 // claws, sword, 2h sword, armor, etc...
endglobals

struct hashArray
 integer array data[ITEM_CLASS_COUNT ]
endstruct

Save hashArray to the unitId's via hashtable and use it later.
No 22 save integer calls, just setting 22 arrays per unitId and saving 1 integer per hero.
You can have up to 8190/ITEM_CLASS_COUNT heroe types with this way, more if you make the struct larger than 8190.
 
Level 9
Joined
Jul 10, 2011
Messages
562
now im confused... :vw_wtf:

so could one of you (and i dont care whether hash or array, vjass, jass, zinc or whatever) please make me a an example of saving the item classes wearable for specific unittypes and an example for a unit acquires an item with everything i mentioned above with a small tutorial.

this here :
item slot check (and moving the item to the desired slot), 2-handed weapon check (and adding a dummy unit to slot X), messages if the item isnt allowed to be worn or the slot is filled and the dropping itself. also please add a line setting the custom value to 0 (i use it for ownership) if the item is dropped.

i really dont get anything you two are writing here anymore. sorry.... 'shame on me'
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Create both list On event "Elapsed Gametime is 1.00 second" and add a "Wait 1 second" action every 50 items/units. That would lag the first 20 seconds of the game, but will reduce a lot the loading time.

Don't worry clapto, I'll do it in a while for you. I was just giving a bit more time for us to think of a better way.
 
This should be really easy to understand and use.
It's the most beautiful way to show everything in huge table from where you can edit all settings for your hero class, but problem is that it's huge and it's save even values that are there by default...

If function breaks because of 2 many arguments then split it into 2 >.>

JASS:
library ItemLib initializer Init
    
    globals
        private hashtable hash = InitHashtable()
        private trigger   trig = CreateTrigger()
    endglobals
    
    function CheckItem takes nothing returns nothing
        if LoadBoolean(hash, GetUnitTypeId(GetTriggerUnit()), GetItemLevel(GetManipulatedItem())) then
            call BJDebugMsg("Item Loaded!")
            return
        endif
        call UnitRemoveItem(GetTriggerUnit(), GetManipulatedItem())
        call BJDebugMsg("Can't carry this item!")
    endfunction
    
    function RegisterItem takes integer hero_id, boolean flag1, boolean flag2, boolean flag3, boolean flag4, boolean flag5, boolean flag6, boolean flag7, boolean flag8, boolean flag9, boolean flag10, boolean flag11, boolean flag12, boolean flag13, boolean flag14, boolean flag15, boolean flag16, boolean flag17, boolean flag18, boolean flag19, boolean flag20 returns nothing
        call SaveBoolean( hash, hero_id, 1 , flag1  )
        call SaveBoolean( hash, hero_id, 2 , flag2  )
        call SaveBoolean( hash, hero_id, 3 , flag3  )
        call SaveBoolean( hash, hero_id, 4 , flag4  )
        call SaveBoolean( hash, hero_id, 5 , flag5  )
        call SaveBoolean( hash, hero_id, 6 , flag6  )
        call SaveBoolean( hash, hero_id, 7 , flag7  )
        call SaveBoolean( hash, hero_id, 8 , flag8  )
        call SaveBoolean( hash, hero_id, 9 , flag9  )
        call SaveBoolean( hash, hero_id, 10, flag10 )
        call SaveBoolean( hash, hero_id, 11, flag11  )
        call SaveBoolean( hash, hero_id, 12, flag12  )
        call SaveBoolean( hash, hero_id, 13, flag13  )
        call SaveBoolean( hash, hero_id, 14, flag14  )
        call SaveBoolean( hash, hero_id, 15, flag15  )
        call SaveBoolean( hash, hero_id, 16, flag16  )
        call SaveBoolean( hash, hero_id, 17, flag17  )
        call SaveBoolean( hash, hero_id, 18, flag18  )
        call SaveBoolean( hash, hero_id, 19, flag19  )
        call SaveBoolean( hash, hero_id, 20, flag20 )
    endfunction
    
    function Init takes nothing returns nothing
        /*   Example  HeroRawCode lvl1 , lvl2 , lvl3 , lvl4 , lvl5 , lvl6 , lvl7 , lvl8 , lvl9 , lvl10, lvl11, lvl12, lvl13, lvl14, lvl15, lvl16, lvl17, lvl18, lvl19, lvl20,*/
        call RegisterItem('Hpal', false, false, false, false, true , true , true , true , true , true , false, false, false, false, true , true , true , true , true , true )
        call RegisterItem('Hamg', true , true , true , true , false, false, false, false, false, false, true , true , true , true , false, false, false, false, false, false)
        
        call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
        call TriggerAddAction(trig, function CheckItem )
    endfunction

endlibrary
 

Attachments

  • testtt.w3x
    17.7 KB · Views: 24
Level 9
Joined
Jul 10, 2011
Messages
562
okay it seems that each of you 3 have a differrent way to do what i need. that okay and i would say normal.

but could you guys PLEASE find the best (efficient, easy to understand or at least with a understandable with a short tutorial & if possible laggless and not so much to write) way to do it and then give me an example which is either self explaining or with a short tutorial.

its really very hard to get what you guys are arguing about for someone who is just triggering and trying to make a good map^^

would be great if you guys would manage that ^^
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
My Final Suggestion:

Use this to set the data of all your Items and Heroes
JASS:
function Trig_Hero_and_Item_List_Actions takes nothing returns nothing

set udg_Hash = InitHashtable()

//                   | Table | ItemID | 000 | ItemClass |
    call SaveInteger(udg_Hash, 'aaaa',   0,       1) // Item 1
    call SaveInteger(udg_Hash, 'bbbb',   0,       2) // Item 2
    call SaveInteger(udg_Hash, 'cccc',   0,       3) // Item 3
    call SaveInteger(udg_Hash, 'dddd',   0,       4) // Item 4
    call SaveInteger(udg_Hash, 'eeee',   0,       5) // Item 5
    call SaveInteger(udg_Hash, 'ffff',   0,       6) // Item 6
    call SaveInteger(udg_Hash, 'gggg',   0,       7) // Item 7
    call SaveInteger(udg_Hash, 'hhhh',   0,       8) // Item 8
    call SaveInteger(udg_Hash, 'iiii',   0,       9) // Item 9
    call SaveInteger(udg_Hash, 'iiii',   0,      10) // Item 10
    call TriggerSleepAction(0.25) // Add one of these every 10 actions.
    // and so on...

//                  | Table | Hero ID | 000 | Forbidden Item Class |
// Hero 1           
    call SaveInteger(udg_Hash, 'jjjj',   0,           1)
    call SaveInteger(udg_Hash, 'jjjj',   0,           1)
// Hero 2
    call SaveInteger(udg_Hash, 'kkkk',   0,           1)
    call SaveInteger(udg_Hash, 'kkkk',   0,           1)
// Hero 3
    call SaveInteger(udg_Hash, 'llll',   0,           1)
    call SaveInteger(udg_Hash, 'llll',   0,           1)
    
    // and so on...

endfunction

//===========================================================================
function InitTrig_Hero_and_Item_List takes nothing returns nothing
    set gg_trg_Hero_and_Item_List = CreateTrigger(  )
    call TriggerRegisterTimerEvent( gg_trg_Hero_and_Item_List, 1.00, false )
    call TriggerAddAction( gg_trg_Hero_and_Item_List, function Trig_Hero_and_Item_List_Actions )
endfunction

This is to check if the Item can be used, and if the slot is empty. Match the required slot with the Item Level
JASS:
function Item_Acquire_Actions takes nothing returns nothing

    local unit u = GetTriggerUnit()
    local item i = (GetManipulatedItem())
    local integer lvl = GetItemLevel(i)
    local integer ItemClass = LoadInteger(udg_Hash, GetItemTypeId(i), 0)

    if LoadInteger(udg_Hash, ItemClass, GetUnitTypeId(u)) == 1 then // Checks if the Acquired Item is Useable by the Unit
    // Drops the item and Displays Message
        call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "This Hero isn't allowed to carry this item class")
        call UnitRemoveItem(u, i)
        call SetItemUserData(i, 0 )
    elseif UnitItemInSlot(u, lvl-1) == null then // Checks if the Item Slot is Empty
        call  IssueTargetOrderById(u, 852001+lvl, i) // Moves the Item to the correct Slot
    else
    // Drops the item and Displays Message
        call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "Slot is already occupied")
        call UnitRemoveItem(u, i)
        call SetItemUserData(i, 0 )
    endif

    set u = null
    set i = null
    
endfunction

//===========================================================================
function InitTrig_Item_Acquire takes nothing returns nothing
    set gg_trg_Item_Acquire = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Item_Acquire, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( gg_trg_Item_Acquire, function Item_Acquire_Actions )
endfunction
 
Level 25
Joined
Jun 5, 2008
Messages
2,573
Here is the vjass library for setting up data and all the shizazle:

JASS:
library customLib initializer onInit

globals
 private constant integer ITEM_CLASS_COUNT = 22
 private hashtable Data = InitHashtable()
endglobals

private struct hashArray
  integer array data[ITEM_CLASS_COUNT]

  static method operator [] takes integer id returns thistype
    return LoadInteger(Data, id, 0)
  endmethod

  method operator []= takes integer i, integer val returns nothing
   set .data[i]=val
  endmethod

  method save takes integer unitId returns nothing
   call SaveInteger(Data, unitId, 0, this)
  endmethod
endstruct

private struct ItemHandler

 static method operator [] takes integer itemId returns integer
  return LoadInteger(Data, itemId, 0)
 endmethod

 static method operator []= takes integer itemId, integer class returns nothing
   call SaveInteger(Data, itemId, 0, class)
 endmethod
endstruct

private function runCheck takes nothing returns boolean
 local integer uId = GetUnitTypeId(GetTriggerUnit())
 local integer iId = GetItemTypeId(GetManipulatedItem())
 local hashArray a = hashArray[uId]
 if a.data[ItemHandler[iId]] == 0 then
    call UnitRemoveItem(GetTriggerUnit(), GetManipulatedItem())
 endif
 return false
endfunction

private function onInit takes nothing returns nothing
 local hashArray a
 local trigger t = CreateTrigger()
 set a = hashArray.create()  // call this every time before you setup the hero
 set a[2] = 1       // sets which class is useable by the hero
 set a[13] = 1
 call a.save('hpal')  // use id of your hero here

// rinse and repeat
 set a = hashArray.create()
 set a[4] = 1 // can use item class 4
 set a[20] = 1 // can use item class 5
 set a[21] = 1 // etc...
 call a.save('h000')  // use id of your hero here

// etc, for all your 81 heroes...
// now for items:

// you can use constants or pure numbers
// example 1 - heavy armor, 13 - greatsword

 set ItemHandler['I000'] = 1   // item of type I000 is heavy armor class
 set ItemHandler['I002'] = 13 // item of type I002 is greatsword class
// do for all your items...
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddCondition(t , function runCheck)
endfunction

endlibrary

Working on the pickup trigger.
Done, working for all the weapon classes, if you need to check for multiple class items and prevention of multiple weapons/armors/2h weapons then i need to add more stuff to it.
 
Level 9
Joined
Jul 10, 2011
Messages
562
My Final Suggestion:

Use this to set the data of all your Items and Heroes
JASS:
function Trig_Hero_and_Item_List_Actions takes nothing returns nothing

set udg_Hash = InitHashtable()

//                   | Table | ItemID | 000 | ItemClass |
    call SaveInteger(udg_Hash, 'aaaa',   0,       1) // Item 1
    call SaveInteger(udg_Hash, 'bbbb',   0,       2) // Item 2
    call SaveInteger(udg_Hash, 'cccc',   0,       3) // Item 3
    call SaveInteger(udg_Hash, 'dddd',   0,       4) // Item 4
    call SaveInteger(udg_Hash, 'eeee',   0,       5) // Item 5
    call SaveInteger(udg_Hash, 'ffff',   0,       6) // Item 6
    call SaveInteger(udg_Hash, 'gggg',   0,       7) // Item 7
    call SaveInteger(udg_Hash, 'hhhh',   0,       8) // Item 8
    call SaveInteger(udg_Hash, 'iiii',   0,       9) // Item 9
    call SaveInteger(udg_Hash, 'iiii',   0,      10) // Item 10
    call TriggerSleepAction(0.25) // Add one of these every 10 actions.
    // and so on...

//                  | Table | Hero ID | 000 | Forbidden Item Class |
// Hero 1           
    call SaveInteger(udg_Hash, 'jjjj',   0,           1)
    call SaveInteger(udg_Hash, 'jjjj',   0,           1)
// Hero 2
    call SaveInteger(udg_Hash, 'kkkk',   0,           1)
    call SaveInteger(udg_Hash, 'kkkk',   0,           1)
// Hero 3
    call SaveInteger(udg_Hash, 'llll',   0,           1)
    call SaveInteger(udg_Hash, 'llll',   0,           1)
    
    // and so on...

endfunction

//===========================================================================
function InitTrig_Hero_and_Item_List takes nothing returns nothing
    set gg_trg_Hero_and_Item_List = CreateTrigger(  )
    call TriggerRegisterTimerEvent( gg_trg_Hero_and_Item_List, 1.00, false )
    call TriggerAddAction( gg_trg_Hero_and_Item_List, function Trig_Hero_and_Item_List_Actions )
endfunction

This is to check if the Item can be used, and if the slot is empty. Match the required slot with the Item Level
JASS:
function Item_Acquire_Actions takes nothing returns nothing

    local unit u = GetTriggerUnit()
    local item i = (GetManipulatedItem())
    local integer lvl = GetItemLevel(i)
    local integer ItemClass = LoadInteger(udg_Hash, GetItemTypeId(i), 0)

    if LoadInteger(udg_Hash, ItemClass, GetUnitTypeId(u)) == 1 then // Checks if the Acquired Item is Useable by the Unit
    // Drops the item and Displays Message
        call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "This Hero isn't allowed to carry this item class")
        call UnitRemoveItem(u, i)
        call SetItemUserData(i, 0 )
    elseif UnitItemInSlot(u, lvl-1) == null then // Checks if the Item Slot is Empty
        call  IssueTargetOrderById(u, 852001+lvl, i) // Moves the Item to the correct Slot
    else
    // Drops the item and Displays Message
        call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "Slot is already occupied")
        call UnitRemoveItem(u, i)
        call SetItemUserData(i, 0 )
    endif

    set u = null
    set i = null
    
endfunction

//===========================================================================
function InitTrig_Item_Acquire takes nothing returns nothing
    set gg_trg_Item_Acquire = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Item_Acquire, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( gg_trg_Item_Acquire, function Item_Acquire_Actions )
endfunction

Spartipilo your way is much better for me to read and understand so ill use yours. thanks to Kingz and -Kobas- anyway. you 3 get +rep anyway :D

to Spartipilo....could you add something? i need to add a dummy item filling slot 2 (the top right one...in jass is it slot 1 afaik) when a 2 handed weapon is successfully picked up. the item rawcode is 'I001'. 2-handed weapons are all item classes from 1 to 8.


and some little questions. what the 0's stand for in the first trigger (just for my understanding^^)? and when i set several items as forbidden is have to copy this line
JASS:
call SaveInteger(udg_Hash, 'jjjj',   0,           1)
and set the last integer to the number of the forbidden class or? and they arent overwritten if i just change the last integer or? and UnitRemoveItem is a drop order? because i just know the to custom text converted line and there it is UnitRemoveItemSwapped.


EDIT: sorry Spartipilo you cant get rep at the moment....ill give it to you later (at least if i dont forget it....hopefully i dont^^)
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Kingz, now, I would REALLY like to know how your idea works. I don't like my method either, but it's the most I've been hable to achieve. Please, explain a bit of that vJass so I can improve this for clapto.

@clapto: 0 is the slot were we save the data, so it remains like that for all the items. And yess, you have to copy that line and replace that last number with the item-class you want to block for that hero.

Yes, UnitRemoveItem is the native function UnitRemoveItemSwapped uses to drop the items. There's no need to use 2nd function to call the 1rst one, when we can do it directly.

I tough the 2handed thing was already done. I remember you saying that before... You would have to check if any of both slots are occupied. I don't want to do it right now. Maybe tomorrow :)
 
Level 9
Joined
Jul 10, 2011
Messages
562
I tough the 2handed thing was already done. I remember you saying that before... You would have to check if any of both slots are occupied. I don't want to do it right now. Maybe tomorrow :)

would be great if you could add that^^ and yes i already did it in my system the problem is that i now replace my system with yours and i have to set the slot with the item level instead of setting the item level for the class so my trigger for 2handed weapons wont work anymore and so i have to ask you to add it ^^
 
Level 25
Joined
Jun 5, 2008
Messages
2,573
Okay so the basic principle is:
Instead of saving 22 integers you save an integer array which is masked through an index.

Since structs can be saved as integers (index of the struct) you can save it only and thus save up to 21 SaveInteger() calls every single time.

Now a single hero would have an array of certain size bound to it.
By default all integers are 0 so we only set the wanted classes to 1 which he can use.

On pickup we load the struct, and access the array of that unitId, if it's 1 we can use the item, if it isn't we can't.

About the items:
Item class is directly bound to item type id, so when you use ItemHandler['I000'] = 0, you set all items with id I000 to class 0.

About seting up the hero:
Only the onInit trigger is used for it, what you do is create a new array:
JASS:
set a = hashArray.create()

Then add to id all the item classes you want:
JASS:
set a.data[0] = 1 // can use item class 0
set a.data[3] = 1 // can use item class 3

And on the end save it with unit type id:
JASS:
call a.save('h000')
where h000 is a type ID of the hero.

When you acquire the item ItemHandler['I001'] will load the class from the hashtable had for item type I001 and return it as a integer.
And hashArray['u002'] will load the array binded to the unid id u002 and set it to a hashArray variable.
For example:
JASS:
b = hashArray['h000']
if b.data[0] == 1 then
 call BJDebugMsg("Unit can wear items of class 0.")
endif

So when picking up an item, you get the item type id:
JASS:
local integer iId = GetItemTypeId(GetManipulatedItem()

Get it's class with ItemHandler[iId].
For the unit you setup a new hashArray variable and load it with the help of unit type id:
JASS:
 local integer uId = GetUnitTypeId(GetTriggerUnit())
 local hashArray a = hashArray[uId]

Now all you need to do is check if a.data[class] == 1 where class is gotten with ItemHandler[iId] directly from the hashtable.
This requires 2 hashtable calls per pickup event, but if you were to check for multiple items or have a more advanced check you would already have all 22 values binded to the unit saving you time by not having to call the LoadInteger() function.

Hope this explains how my library would work.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
It probably does, but i don't understand :$

How's this works? b = hashArray['h000']

Wouldn't 'h000' be greater than 8192 and therefore, not work?

Could you post an example with some (4) item classes, some (4) item types and some (2) heroes?
 
Level 25
Joined
Jun 5, 2008
Messages
2,573
Ah but you see, i implemented a custom operator:

JASS:
  static method operator [] takes integer id returns thistype
    return LoadInteger(Data, id, 0)
  endmethod

So when you compile the vjass into jass:

JASS:
b = hashArray['h000']  // this will become:

b = LoadInteger(Data, 'h000', 0) // this, and the above is much more easy to read and write

It's a vjass thingy, really usefull :D
 
Level 9
Joined
Jul 10, 2011
Messages
562
Spartipilo please dont forget to add the dummy item add on picking up a 2 handed weapon so i can continue/finish that part of my map ^^
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
You could do it. 2Handed items are from 1 to 8. Detect if ItemClass is less than or equal to 8 and add your dummy item. Detect when the item is dropped and remove the dummy item.
 
Level 9
Joined
Jul 10, 2011
Messages
562
okay i just made these 2 small triggers to do what i want and implemented your triggers but now i get 2 errors :

undeclared variable gg_trg_Hero_and_Item_List
undeclared variable gg_trg_Item_Acquire


what i have to do to solve? never had problem with trigger "variables" not declared...
 
Level 9
Joined
Jul 10, 2011
Messages
562
the problem was that easy Oo wow thanks xD


EDIT: tested your system now and there seems to be a sense problem. whenever you pick up an item for slot 1 and slot 1 is free the item will be put in slot 1 when picked up. Afterwards the system checks whether slot 1 is free but the picked up item is in there. so it drops the item and the message 'the slot is already occupied' appears. so its impossible to pick up item for slot 1. and the same will happen is for example slot 1 & 2 are filled and you pick up an item for slot 3. i hope you get what i mean. could you fix that problem?
 
Last edited:
Level 20
Joined
Jul 14, 2011
Messages
3,213
Ooohh... Sorry, it's my first time working with Empty Slots and triggered inventory item movement.

I Guess that, when the item is moved inside the inventory with this trigger, it's actually acquired again, so, the trigger runs again with the item in the occupied slot, which trigger the dropping of the item.

The only solution I can think of is turning off the trigger before moving the item, and turning on again after it.

JASS:
...
    elseif UnitItemInSlot(u, lvl-1) == null then // Checks if the Item Slot is Empty    
        call DisableTrigger(gg_trg_Item_Acquire)
        call  IssueTargetOrderById(u, 852001+lvl, i) // Moves the Item to the correct Slot    
        call EnableTrigger(gg_trg_Item_Acquire )
    else
...
 
Level 9
Joined
Jul 10, 2011
Messages
562
no thats not the problem ^^moving is not recognized as acquiring...

the problem is that (i make an example) :

lets say you have a hero with an empty inventory. so this hero picks up an item for slot 1. so the picked item is in slot 1 because of picking up. now the problem comes. the trigger checks whether in slot 1 is an item and oh wonder oh wonder there is one...the picked up one. so because of this little thing the trigger recognizes that the slot is filled (although it is the item you picked up) and drops the item.

in my system i had the same problem an my solution was when a unit acquires an item saving the item-type in a variable removing the item that was picked up and then do the checks and afterwards if everything is fine and the item would be successfully picked up i created an item of the saved type in the desired slot and if for example the slot is occupied or the hero-type isnt allowed to carry the item i created an item of the saved type at the position of the hero and displayed the error message.

could you change the code to do what i wrote?
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I added the comparison or UnitItemInSlot(u, lvl-1) == (GetManipulatedItem()) to check if the item carried in the desired slot is the same item that was acquired. The trigger moves the item to the same slot it's, but it's better than using another comparison to "do nothing".

You just have to add this

JASS:
//...
    local item i2 = UnitItemInSlot(u, lvl-1)
//...
    elseif i2 == null or  i2 == i then // Checks if the Item Slot is Empty or the Item in the slot is the desired item.
//...
    set i2 = null

JASS:
function Item_Acquire_Actions takes nothing returns nothing

    local unit u = GetTriggerUnit()
    local item i = (GetManipulatedItem())
    local integer lvl = GetItemLevel(i)
    local integer ItemClass = LoadInteger(udg_Hash, GetItemTypeId(i), 0)
    local item i2 = UnitItemInSlot(u, lvl-1)

    
    if LoadInteger(udg_Hash, ItemClass, GetUnitTypeId(u)) == 1 then // Checks if the Acquired Item is Useable by the Unit
    // Drops the item and Displays Message
        call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "This Hero isn't allowed to carry this item class")
        call UnitRemoveItem(u, i)
        call SetItemUserData(i, 0 )
    elseif i2 == null or  i2 == i then // Checks if the Item Slot is Empty or the Item in the slot is the desired item.
        call  IssueTargetOrderById(u, 852001+lvl, i) // Moves the Item to the correct Slot
    else
    // Drops the item and Displays Message
        call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "Slot is already occupied")
        call UnitRemoveItem(u, i)
        call SetItemUserData(i, 0 )
    endif

    set u = null
    set i = null
    set i2 = null
    
endfunction
 
Level 9
Joined
Jul 10, 2011
Messages
562
now it gets strange...

before you changed the trigger dropped the item everytime.
now after the change it never drops it Oo

any ideas?


here are my test triggers:
JASS:
function Trig_Hero_and_Item_List_Actions takes nothing returns nothing

set udg_ItemRestrictionTable = InitHashtable()

//                             | Table |      ItemID | 000 | ItemClass |
    call SaveInteger(udg_ItemRestrictionTable, 'ofro',   0,       1) // Item 1
    call TriggerSleepAction(0.25) // Add one of these every 10 actions.
    // and so on...

//                  | Table |                  Hero ID | 000 | Forbidden Item Class |
// Hero 1
    call SaveInteger(udg_ItemRestrictionTable, 'H02Q',   0,             1)
    call SaveInteger(udg_ItemRestrictionTable, 'H00F',   0,             1)
    
    // and so on...

endfunction

//===========================================================================
function InitTrig_Hero_and_Item_List takes nothing returns nothing
    set gg_trg_Hero_and_Item_List = CreateTrigger(  )
    call TriggerRegisterTimerEvent( gg_trg_Hero_and_Item_List, 1.00, false )
    call TriggerAddAction( gg_trg_Hero_and_Item_List, function Trig_Hero_and_Item_List_Actions )
endfunction

JASS:
function Item_Acquire_Actions takes nothing returns nothing

    local unit u = GetTriggerUnit()
    local item i = (GetManipulatedItem())
    local integer lvl = GetItemLevel(i)
    local integer ItemClass = LoadInteger(udg_ItemRestrictionTable, GetItemTypeId(i), 0)
    local item i2 = UnitItemInSlot(u, lvl-1)

    
    if LoadInteger(udg_ItemRestrictionTable, ItemClass, GetUnitTypeId(u)) == 1 then // Checks if the Acquired Item is Useable by the Unit
    // Drops the item and Displays Message
        call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "You can't carry this item.")
        call UnitRemoveItem(u, i)
        call SetItemUserData(i, 0 )
    elseif i2 == null or  i2 == i then // Checks if the Item Slot is Empty or the Item in the slot is the desired item.
        call  IssueTargetOrderById(u, 852001+lvl, i) // Moves the Item to the correct Slot
    else
    // Drops the item and Displays Message
        call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "Needed slot is already occupied.")
        call UnitRemoveItem(u, i)
        call SetItemUserData(i, 0 )
    endif

    set u = null
    set i = null
    set i2 = null
    
endfunction

//===========================================================================
function InitTrig_Item_Acquire takes nothing returns nothing
    set gg_trg_Item_Acquire = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Item_Acquire, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( gg_trg_Item_Acquire, function Item_Acquire_Actions )
endfunction


EDIT:
also ive got a small question because i just dont understand...

i save items like this :
JASS:
call SaveInteger(udg_ItemRestrictionTable, 'ofro',   0,       1)

and forbidden item classes like this :
JASS:
call SaveInteger(udg_ItemRestrictionTable, 'H02Q',   0,             1)

but when you check it you do this :
JASS:
if LoadInteger(udg_ItemRestrictionTable, ItemClass, GetUnitTypeId(u)) == 1 then

and i just dont get where the 1 should come from because i save a 0 under the unittypeID and the item class...and there is no 1 Oo i hope you get what i dont understand^^
 
Last edited:
Level 20
Joined
Jul 14, 2011
Messages
3,213
<< EDIT >> I forgot to ask. What message was displaying before when the item was always dropped, that the slot was occupied, or that the unit couldn't hold that item?

WTF have I done? I don't even understand what I did. I remember my initial idea, but this doesn't seem like it. It's all messed up :$

One tip. Computers works harder to write more. I mean "udg_ItemRestrictionTable" is larger than "udg_IRT", specially when we're going to write it hundreds of times. You can copy the base example of "How to imput Data" in the Header of the trigger (The comment box over the script) to guide yourself, so you can delete the comments and everything else withing the code (which also takes space). I would suggest trying to use variables and stuff with short names. Even the blank spaces takes space, so, this call SaveBoolean(udg_ItemRestrictionTable, 'H02Q', #, true) should be this call SaveBoolean(udg_ItemRestrictionTable, 'H02Q', #, true).

What you have to do here, is, in the Unit part, where there's a # type the item class that can't be used. If the hero can't use Item Classes 2, 5, 8, create 3 actions with the UnitType, and true at the end, but replace the # with the 2, 5, 8.

JASS:
function Trig_Hero_and_Item_List_Actions takes nothing returns nothing

set udg_ItemRestrictionTable = InitHashtable()


/************************** ITEMS **************************/

// Slot 0 of ItemTypeId holds the Item-Classes (Helm, Boot, etc.) as a number

//                             | Table |      ItemID | 000 | ItemClass |
    call SaveInteger(udg_ItemRestrictionTable, 'ofro',   0,       1) // Item 1
    call TriggerSleepAction(0.25) // Add one of these every 10 actions.
    // and so on...



    
    
/************************** UNITS **************************/
    
// Slot (ItemClass) of UnitTypeId holds a (true) if that ItemClass can't be used by that UnitType
    
//                  | Table |                  HeroID | ItemClass | Can't be used |
// Hero 1
    call SaveBoolean(udg_ItemRestrictionTable, 'H02Q',      #,          true)
    call SaveBoolean(udg_ItemRestrictionTable, 'H00F',      #,          true)
    
    // and so on...

endfunction

//===========================================================================
function InitTrig_Hero_and_Item_List takes nothing returns nothing
    set gg_trg_Hero_and_Item_List = CreateTrigger(  )
    call TriggerRegisterTimerEvent( gg_trg_Hero_and_Item_List, 1.00, false )
    call TriggerAddAction( gg_trg_Hero_and_Item_List, function Trig_Hero_and_Item_List_Actions )
endfunction


<< I'm Working on the other trigger. I'll update this post >>

<< EDIT >> Damn it. I don't know how to check if the acquired item is supposed to be in the slot that already occupies to prevent droping it.

<< EDIT >> This is the 2nd trigger. I'm sorry, but I wasn't able to know if the Item in the occupied slot is supposed to be there to prevent dropping =/ You may create another thread to ask other a way to know that.

JASS:
function Item_Acquire_Actions takes nothing returns nothing

    local unit u = GetTriggerUnit()
    local integer uID = GetUnitTypeId(u)
    local item i = (GetManipulatedItem())
    local integer iID = GetItemTypeId(i)
    local integer lvl = GetItemLevel(i)
    local integer ItemClass = LoadInteger(udg_ItemRestrictionTable, iID, 0)
    local boolean nouse  = LoadBoolean(udg_ItemRestrictionTable, uID, ItemClass)
    local item i2 = UnitItemInSlot(u, lvl-1)

    if nouse == true then // Checks if the ItemClass of the Acquired Item is Useable by the Unit
    // Drops the item and Displays Message
        call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "You can't carry this item.")
        call UnitRemoveItem(u, i)
        call SetItemUserData(i, 0 )
    elseif i2 == null then // Checks if the ItemSlot (based on ItemLevel) is Empty
        call  IssueTargetOrderById(u, 852001+lvl, i) // Moves the Item to the correct Slot
    else
    // Drops the item and Displays Message
        call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "Needed slot is already occupied.")
        call UnitRemoveItem(u, i)
        call SetItemUserData(i, 0 )
    endif
    
    set u = null
    set i = null
    set i2 = null
    
endfunction
 
Last edited:
Status
Not open for further replies.
Top