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

Hashtables refuse to co-operate

Status
Not open for further replies.
Level 19
Joined
Aug 8, 2007
Messages
2,765
I dont know whats up, but whenever i do anything with hashtables they don't work. example

JASS:
library CustomDrop initializer init
    globals
        private hashtable Hash_t = InitHashtable()
        private location SendToItem = Location(0,0)
    endglobals
    
    private function OnDeath takes nothing returns nothing
        local unit u = GetDyingUnit()
        local integer unitId = GetUnitTypeId(u)
        local integer count = LoadInteger(Hash_t,unitId,0) // if the unit type was not registred for drop it will be equal to 0, else it will be > 0
        local real random
        local integer i
        local item drop
        
        loop // loop on all dropable item for unitID
        exitwhen count == 0 
            
            set i = 0
            loop // player loop
            exitwhen i == 11
                if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
                    set random = GetRandomReal(0,100)
                    if random < LoadReal(Hash_t,unitId,count) then
                        set drop = CreateItem(LoadInteger(Hash_t,unitId,count),GetUnitX(u),GetUnitY(u))
                        call SetItemVisible(drop,GetLocalPlayer()==Player(i))// the item will be visible only for Player(i)
                    endif
                endif
            set i = i+1
           endloop
     
        set count = count-1
        endloop
        set u = null
        set drop = null
    endfunction
    
    private function RegisterDrop takes integer unitId , integer itemId, real chanceToDrop returns nothing // chanceToDrop in percent
        local integer n = LoadInteger(Hash_t,unitId,0)
        /* integer : unitId ; 0 -> number of possible item drop for the unit type unitId
           integer : unitId ; x -> rawcode of the item to drop ; x > 0
           real : unitId ; x -> chance of the item x to drop
        */
        set n = n+1
        call SaveInteger(Hash_t,unitId,0,n)
        call SaveInteger(Hash_t,unitId,n,itemId)
        call SaveReal(Hash_t,unitId,n,chanceToDrop)
    endfunction
    private function onItemPickup takes nothing returns nothing
        local item it = GetOrderTargetItem()
        local unit u = GetTriggerUnit()
        local boolean b
        local integer i = 0
        local integer i2 = i2i.convert(GetItemTypeId(GetOrderTargetItem()))
 //       if i2 < 5 then
        call SetItemVisible(it, true)
        call print(I2S(i2))
  //      call RemoveItem(it)
 //       call print("Item " + R2S(GetHandleId(it)) + " With the name of " + GetItemName(it) + " was destroyed.")
 //       call UnitAddItemById(u, 'rat6')
 //       endif
 //       call SetItemPosition(i, GetItemX(i), GetItemY(i))
////        call TriggerSleepAction(0.01)
/* ///       call UnitAddItem(u , i)
        loop
            set b = UnitItemInSlot(u, i) == null
            exitwhen b == true
            set i = i + 1
            exitwhen i == 5
        endloop
        if b == true then
            call UnitAddItem(u, it)
        else
            set u = udg_Backpack[GetConvertedPlayerId(GetTriggerPlayer())]
            set i = 0
            loop
                set b = UnitItemInSlot(u, i) == null
                exitwhen b == true
                set i = i + 1
                exitwhen i == 6
            endloop
            if b == true then
                call UnitAddItem(u, it)
                call print("The item has been sent to your backpack")
            else
                call print("You do not have enough room for that item")
            endif
        endif
//            call TriggerSleepAction(0)
//            call IssueImmediateOrder(u, "stop")
//            call IssueInstantPointOrder(u, "move", GetUnitX(u), GetUnitY(u), null)
//            call print("Full Inventory")
//        elseif it != null then
//            call TriggerSleepAction(0)
//            call IssueImmediateOrder(u, "stop")
//            call SetUnitPositionLoc(u, GetUnitLoc(u))
 //           call SetItemVisible(it, true)
//            call UnitAddItem(u, it)
//        endif
            */
    endfunction

    private function init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        local trigger trig2 = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DEATH)
        call TriggerRegisterAnyUnitEventBJ(trig2, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER  )
        call TriggerAddAction(trig,function OnDeath)
        call TriggerAddAction(trig2, function onItemPickup)
        call RegisterDrop('n000','I000',99)
        
    endfunction
    
endlibrary

used to work but now does nothing

  • UnitIndex
    • Events
      • Game - UnitIndexEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • Custom script: local unit u = udg_UDexUnits[udg_UDex]
      • Custom script: call SaveReal(udg_CreepTable, udg_UDex, 1, GetUnitX(u))
      • Custom script: call SaveReal(udg_CreepTable, udg_UDex, 2, GetUnitY(u))
      • Custom script: call SaveReal(udg_CreepTable, udg_UDex, 3, GetUnitFacing(u))
      • Custom script: set u = null
  • Respawn
    • Events
      • Unit - A unit owned by Neutral Hostile Dies
    • Conditions
    • Actions
      • Custom script: local unit u = GetDyingUnit()
      • Custom script: local integer id = GetUnitTypeId(u)
      • Custom script: local integer lv = GetHeroLevel(u)
      • Custom script: local integer cv = GetUnitUserData(u)
      • Custom script: local real x = LoadReal(udg_CreepTable, cv, 1)
      • Custom script: local real y = LoadReal(udg_CreepTable, cv, 2)
      • Custom script: local real ang = LoadReal(udg_CreepTable, cv, 3)
      • Custom script: call RemoveUnit( u )
      • Custom script: set u = CreateUnit(GetTriggerPlayer(),id,x,y,ang)
      • Custom script: if lv > 1 then
      • Custom script: call SetHeroLevel(u,lv,false)
      • Custom script: endif
      • Custom script: set u = null
doesnt do anything. (yes, the hashtable is initialized i just didnt put the initialization trigger inside of it
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
/sry for double post but its to add information/

Here, im not asking for a thorough search of the maps scripts but just overview it and see if i mess up hashtables anywhere o_O
 

Attachments

  • Rebirth RPG Alpha.w3x
    5.3 MB · Views: 51
Level 16
Joined
Mar 3, 2006
Messages
1,564
That's really hard I don't know where to start, could you specify what is the problem.

I really don't know what I am looking at even after you attach the map.

<<< EDIT >>>

I noticed something:

JASS:
struct i2i
    private @static@ hashtable Hash = InitHashtable()

    // ...

endstruct

as a starter try making this non-static.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
hmm.. i thought it was because of the hashtable overflow DSG mentioned but

call print(I2S(GetHandleId(InitHashtable()))) returns a valid handle identification tag. Am i just using hashtables incorrectly?
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
I looked at the map but this is way too big to look at every trigger and library you are using so if you point out more specific to the problem you are experiencing. That should narrow the search on the problem.

every hashtable now is returning null values, even though their handle ids are correct and they used to work previously
 
Level 16
Joined
Mar 3, 2006
Messages
1,564
every hashtable now is returning null values, even though their handle ids are correct and they used to work previously

So not only the hashtable in the example you posted is not working; its the entire hashtables in the map. :eekani:

I am not an expert actually to tell you, but you are using lots of external libraries could it be the problem. IDK for sure.

Ok. try to remember when the hashtables were working and remember what did you add when they began to return null. I know it is not much but at least lets find the root of the problem.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
So not only the hashtable in the example you posted is not working; its the entire hashtables in the map. :eekani:

I am not an expert actually to tell you, but you are using lots of external libraries could it be the problem. IDK for sure.

Ok. try to remember when the hashtables were working and remember what did you add when they began to return null. I know it is not much but at least lets find the root of the problem.

idk i was toying with the item systeem and i went to test and no items dropped, i cant remember what changes i made between when the item system worked and when it didnt. its not an issue with the item system but rather something else.

Anyway, it IS a problem with a script somewhere in the map. I removed all of the scripts in the map besides the respawn trigger and the respawn trigger worked.

e/ wait... do i not have unit indexer in the map...
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
If you never flush hashtables, a quick way to see how many hashtables you are using :

JASS:
library DisplayHashtablesCount initializer init

    globals
        private integer I = 0
    endglobals

    function CountHashtables takes nothing return hashtable
        set I = I+1
        return null
    endfunction

    hook InitHashtable CountHashtables

    private function init takes nothing returns nothing        
        call TriggerSleepAction(5)
        call BJDebugMsg("number of hashtables == "+I2S(I))
    endfunction

endlibrary
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
@TrollBrain

on all instances of InitHashtable()

Undeclared Function h__InitHashtable (hashtable CustomDrop___Hash_t = h__InitHashtable())
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Oh well, i suppose hooks don't work with global definitions, it tries to use the custom function (the hook) while it's not a native function, then it fails on compilation.

Anyway if you don't use InitHashtables inside loops (that would be a terrible idea), you can just count the number of "InitHashtable" with any text editor, looking the map script.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Oh well, i suppose hooks don't work with global definitions, it tries to use the custom function (the hook) while it's not a native function, then it fails on compilation.

Anyway if you don't use InitHashtables inside loops (that would be a terrible idea), you can just count the number of "InitHashtable" with any text editor, looking the map script.

its like around 10. the only instance where a function creates a hashtable on function call not initialization is my equipment trigger which ive been using long past when ive had these errors
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Never create an hashtable if it's "dynamic".
But you don't seem to reach the limit anyway.

The script i've seen should work if the trigger fire. (as DSG said make sure you're not reaching the limit op on map initialization by displaying messages when triggers fire)
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
I tested the map and it seems that the inventory is not working as well, has you disabled it or it has something to do with the hashtables problem ?

What do you mean by that, I disabled the init equipment triggers in one of the tests I did, idr if that's the version I uploaded. Anyway, disconsider the inventory
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
I give up.

so do i. (not really)

i disabled all the triggers besides those needed to respawn and it didnt work. i switched time elapsed = 0 to melee init and it worked. i re-enabled all the triggers and it stopped working again and now the melee initialization trigger doesnt work.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Well, the error is really easy to catch (and sorry but stupid as well), you just don't have the item 'I000', i've tried with 'I005', seems to work.
Also it spams errors on init about TableArray, but it could be related to the preplaced units i've added to check if the custom drop worked.
Use the debug mode of jasshelper to get rid of them.

I've not checked the other scripts coz after such errors i've lost all motivation.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
hurr. but i still think i have an issue with hashtables.

1) If i try to init a hashtable on a main map initialization trigger, the rest of the map initialization trigger will NOT run. if i remove it, it initializes fine.


JASS:
UnitIndex
    Events
        Game - UnitIndexEvent becomes Equal to 1.00
    Conditions
    Actions
        Custom script:   local unit u = udg_UDexUnits[udg_UDex]
        Custom script:   if udg_CreepTableBool == false then
        Custom script:   call SaveReal(udg_CreepTable, 99999, 99999, 59438)
        Custom script:   if LoadReal(udg_CreepTable, 99999, 99999) != 59438 then
        Custom script:   call print("No Hashtable")
        Custom script:   set udg_CreepTable = InitHashtable()
        Custom script:   set udg_CreepTableBool = true
        Custom script:   endif
        Custom script:   endif
        Custom script:   call SaveReal(udg_CreepTable, udg_UDex, 1, GetUnitX(u))
        Custom script:    call SaveReal(udg_CreepTable, udg_UDex, 2, GetUnitY(u))
        Custom script:   call SaveReal(udg_CreepTable, udg_UDex, 3, GetUnitFacing(u))
        Custom script:   set u = null

This never prints "No Hashtable" (yes i have unit indexer in the map)
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
JASS:
call SaveReal(udg_CreepTable, 99999, 99999, 59438)
before
JASS:
set udg_CreepTable = InitHashtable()

And if udg_CreepTable is not a GUI variable editor it has probably no value at this point, in jass use a not initialized value crash the thread, that's why you don't see the message.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
JASS:
call SaveReal(udg_CreepTable, 99999, 99999, 59438)
before
JASS:
set udg_CreepTable = InitHashtable()

And if udg_CreepTable is not a GUI variable editor it has probably no value at this point, in jass use a not initialized value crash the thread, that's why you don't see the message.

if i init the hashtable when its already initialized will it wipe previous data?
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
No, it will create an other hashtable and you will lost the reference of the previous one if it's not saved somewhere else (in an other variable).
Just like any handle in fact.

For example :

JASS:
    private function init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        local trigger trig2 = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DEATH)
        call TriggerRegisterAnyUnitEventBJ(trig2, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER  )
        call TriggerAddAction(trig,function OnDeath)
        call TriggerAddAction(trig2, function onItemPickup)
        call RegisterDrop('n000','I000',99)
        
    endfunction

->

JASS:
    private function init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DEATH)
        call TriggerAddAction(trig,function OnDeath)
        set trig = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER  )
        call TriggerAddAction(trig, function onItemPickup)
        call RegisterDrop('n000','I000',99)
        set trig = null
        
    endfunction

You don't need two triggers variables here, because you don't need to keep the reference of created trigger once you're done with it.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
No, it will create an other hashtable and you will lost the reference of the previous one if it's not saved somewhere else (in an other variable).
Just like any handle in fact.

For example :

JASS:
    private function init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        local trigger trig2 = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DEATH)
        call TriggerRegisterAnyUnitEventBJ(trig2, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER  )
        call TriggerAddAction(trig,function OnDeath)
        call TriggerAddAction(trig2, function onItemPickup)
        call RegisterDrop('n000','I000',99)
        
    endfunction

->

JASS:
    private function init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DEATH)
        call TriggerAddAction(trig,function OnDeath)
        set trig = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER  )
        call TriggerAddAction(trig, function onItemPickup)
        call RegisterDrop('n000','I000',99)
        set trig = null
        
    endfunction

You don't need two triggers variables here, because you don't need to keep the reference of created trigger once you're done with it.

still cant get this to work

  • UnitIndex
    • Events
      • Game - UnitIndexEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • Custom script: local unit u = udg_UDexUnits[udg_UDex]
      • Custom script: call print("Debug1")
      • Custom script: if udg_CreepTableBool == false then
      • Custom script: set udg_CreepTable = InitHashtable()
      • Custom script: set udg_CreepTableBool = true
      • Custom script: endif
      • Custom script: call SaveReal(udg_CreepTable, udg_UDex, 1, GetUnitX(u))
      • Custom script: call SaveReal(udg_CreepTable, udg_UDex, 2, GetUnitY(u))
      • Custom script: call SaveReal(udg_CreepTable, udg_UDex, 3, GetUnitFacing(u))
      • Custom script: set u = null
doesnt print Debug1 at map init.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
i think its an issue with unit indexer. i put a debug behind and in front of set UnitIndexEvent = 1.00 and none fired. Any ideas?

e/ dafuq. map initialization is bugging

  • Untitled Trigger 005
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: call print("If this doesnt work, im going to kill a small baby")
nada.

but if i convert it to JASS and put the call inside of the init trig, it works
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
What is "Game - UnitIndexEvent becomes Equal to 1.00", it isn't map initialization at least.

So, it seems you crash the thread somewhere in the init trig GUI triggers, disable all other GUI triggers and then check if this one is working.

Also try to use a scope initializer (create a trigger at the bottom for that) anc check if it fire, just in case the crash is inside vJass initializers (i don't remember the order of GUI/(v)Jass initializers in the main function, but i suppose GUI triggers are handled after after all vJass ones).
Make sure you don't use any unitialized variable, or recursive inits.
 
Last edited:
Level 19
Joined
Aug 8, 2007
Messages
2,765
The crash is in between running init trig and erunning map map int trigger cuz as I said I can convert to custom and it'll work. I'll look at it when Im on comp
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Can mark this as solved

JASS:
function Leave takes nothing returns nothing
    call print(GetPlayerName(GetTriggerPlayer()) + " Has left the game.")
endfunction

//===========================================================================
function InitTrig_Leave takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 0
    loop
        exitwhen i == 12
        call TriggerRegisterPlayerEvent(t, Player(i), EVENT_PLAYER_LEAVE)
    endloop
    call TriggerAddAction( t, function Leave )
endfunction

Woops :)
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Note that with vJass initializers and Cohadar's jasshelper that shouldn't disable all the other triggers init, since each vJass initializer use ExecuteFunc (or at very least library and scope ones), and then a new thread is open for each initializer.

And wait, you didn't had a game crash ?!
Because last time i tried to use Player() with an argument outside the bounds, wc3 crashed.

EDIT : Nevermind, the only player used here is Player(0), and then a valid one.
 
Last edited:
Status
Not open for further replies.
Top