• 🏆 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!

[JASS] How to extract the value of the field 'ista' for an item/item type ID

Status
Not open for further replies.
Level 25
Joined
Feb 2, 2006
Messages
1,690
Hi,
for my Unstack System I need to extract the value of the field:

JASS:
function ItemUnstackItemGetMaxStacks takes item whichItem returns integer
    // TODO 'ista' cannot be extracted.
    //return BlzGetItemIntegerField(whichItem, ConvertItemIntegerField('ista'))
    return 100
endfunction

However, it seems to return 0. Is it possible to extract this value or do I have to return them manually per item type?
 

Wrda

Spell Reviewer
Level 26
Joined
Nov 18, 2012
Messages
1,890
The field doesn't exist at all, as we've seen on your main thread, thus even attempting this has no fruitous result. From what I've seen of the 'ihpc' field, it only works if the item is on the ground, or if it is the main item that is stacked on, if it's the reverse, then it always returns 0.
E.g.: There's X and Y items on ground, both have 75 current hp. X is picked. You check X hp = 75 and Y's hp = 75. You pick up Y and it stacks on X. X hp = 75, Y = 0. This behavior seems to make sense, and I'd assume other fields behave like this too.
Returning to this field, the only ways i see this doable is either manually or some sort of trick with a loop and attempting stacking, to check if it's stackable and its max stacks, it's pretty lame though.
 
Level 25
Joined
Feb 2, 2006
Messages
1,690
Either that or with
JASS:
EVENT_PLAYER_UNIT_STACK_ITEM
and some trigger attempting to give the item to a dummy unit with two slots which already has it N times until the event is not triggered anymore.

edit:
I do know now how to solve it after updating my system Baradé's Item Unstack System 1.5

Here is a snippet:

JASS:
library MaxItemStacks initializer Init

globals
    // This dummy is created and hidden once. It requires an inventory with at least 2 slots.
    private constant integer DUMMY_UNIT_TYPE_MAX_CHECKS = 'Hpal'
    // Warcraft III has a limit of number of stacks for the field "Stats - Max Stacks".
    private constant integer MAX_STACKS_ALLOWED = 1000

    private unit stackItemDummy = null
    private integer stackCounter = 0
    private hashtable stackHashTable = InitHashtable()
endglobals

public function GetStackItemDummy takes nothing returns unit
    return stackItemDummy
endfunction

public function GetMaxStacksByItemTypeId takes integer itemTypeId returns integer
    local integer i = 0
    local item tmpItem = null

    if (HaveSavedInteger(stackHashTable, itemTypeId, 0)) then
        return LoadInteger(stackHashTable, itemTypeId, 0)
    endif
    set stackCounter = 1
    set tmpItem = CreateItem(itemTypeId, 0.0, 0.0)
    call SetItemCharges(tmpItem, 1)
    call UnitAddItem(stackItemDummy, tmpItem)
    set i = 1
    loop
        set tmpItem = CreateItem(itemTypeId, 0.0, 0.0)
        call SetItemCharges(tmpItem, 1)
        call UnitAddItem(stackItemDummy, tmpItem)
        exitwhen (stackCounter <= i)
        set i = i + 1
        exitwhen (i >= MAX_STACKS_ALLOWED)
    endloop
    if (UnitItemInSlot(stackItemDummy, 0) != null) then
        call RemoveItem(UnitItemInSlot(stackItemDummy, 0))
    endif
    if (UnitItemInSlot(stackItemDummy, 1) != null) then
        call RemoveItem(UnitItemInSlot(stackItemDummy, 1))
    endif
    call SaveInteger(stackHashTable, itemTypeId, 0, stackCounter)
    return stackCounter
endfunction

private function TriggerActionStack takes nothing returns nothing
    set stackCounter = stackCounter + 1
endfunction

private function Init takes nothing returns nothing
    set stackItemDummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_UNIT_TYPE_MAX_CHECKS, 0.0, 0.0, 0.0)
    call SetUnitInvulnerable(stackItemDummy, true)
    if (IsUnitType(stackItemDummy, UNIT_TYPE_HERO)) then
        call SuspendHeroXP(stackItemDummy, true)
    endif
    call SetUnitUseFood(stackItemDummy, false)
    call ShowUnit(stackItemDummy, false)
    call BlzSetUnitWeaponBooleanField(stackItemDummy, UNIT_WEAPON_BF_ATTACKS_ENABLED, 0, false)
    call BlzSetUnitWeaponBooleanField(stackItemDummy, UNIT_WEAPON_BF_ATTACKS_ENABLED, 1, false)
    call TriggerRegisterUnitEvent(stackItemTrigger, stackItemDummy, EVENT_UNIT_STACK_ITEM)
    call TriggerAddAction(stackItemTrigger, function TriggerActionStack)
endfunction

endlibrary

Function
JASS:
GetMaxStacksByItemTypeId
can be used to extract the 'ista' field from any item type. It caches the result into a hashtable.
Caching in the hashtable could be optional and is only done for better performance and since the field cannot be changed.
As you can see, the system creates a neutral passive Paladin dummy with a hero inventory who cannot attack or be killed or be seen or costs food or gains XP. Whenever you need to know the 'ista' value for an item type, it adds it n times to the Paladin until it is not stacked anymore. n is 1000 by default since this seems to be the limit of Warcraft III.

I am planning to move the code into such a separate library which then will be a dependency of my unstack system. Increasing the stack counter could also be done in a trigger condition which might be a bit faster (according to ConditionalTriggerExecute vs TriggerEvaluate).
 
Last edited:
Status
Not open for further replies.
Top