Hashtables, And Passing Data to them.

NeuroToxin

New Member
Reaction score
46
Very Well.

I am currently doing a spell called Maledict, otherwise known as the spell from the Witch Doctor in Dota, because I've always loved this spell. Basically it does damage per second, and that damage multiplies for every 250 - 200 - 150 - 100 damage taken. Now, the thing I want to do.

I have some sort of fetish for Timers at the moment, and hashtables, as hashtables recently became usable to me in JASS and vJASS, I know they were usable before, but there was no colored syntax for them. The problem for me, maybe it's because I'm incredibly tired and the solution is right there. But, instead of a separate trigger for damage detection, I'm simply adding the targeted unit to another trigger in the same trigger (Inception much?). Which handles all damage taken events in that trigger. How would I retrieve a specific instance of a hashtable, which is set on using the data of a timer, to set an integer for the damage dealt to a higher amount? For dealing multiplied damage. The solution is probably right in front of me, but I'm tired. So, thanks for reading this wall of text.

Thanks, Neuro.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Not necessary.
You can use AIDS and Damage to do that.
Make a linked list of struct and attach to targets. (If you want to make the unit able to get multiple instances of Maledict :p )
When damage dealt, add the damage to the struct. :)
 

Ayanami

칼리
Reaction score
288
As mentioned above, you could just use AIDS. If you really want to use Hashtable, add a damage event (I think you're currently doing this already) to another trigger. Then save the instance of your struct in the hashtable, using the trigger's (containing the damage event) handle as the parent key. Then, you can retrieve the struct instance by:

JASS:
private function DamageTrigger takes nothing returns nothing
     local thistype this = LoadInteger(MyHash, GetHandleId(GetTriggeringTrigger()), 0)
endfunction


Something like that.
 

tooltiperror

Super Moderator
Reaction score
231
Handle Ids go way above 8191, Glenphir, such practice is evil and should be avoided at all costs
 

NeuroToxin

New Member
Reaction score
46
So it seems my best bet would be to use both a struct AND a hashtable.

My original thing to do, was just saving the hashtable in the timer, then I realized that I can't do that along with the damage. Therefore, I'll go with a struct.
 

emjlr3

Change can be a good thing
Reaction score
395
this might help a bit
JASS:
globals
    hashtable ht=InitHashtable()
endglobals

struct data
    trigger t
    unit caster
    unit target
    
    method destroy
        // flush the stored data, otherwise it will leak
        call FlushChildHashtable(ht,GetHandleId(.t))
        // destroy the dynamic trigger, otherwise it will leak
        // there is no risk in doing this since we are using trigger conditions which cannot have waits
        call DestroyTrigger(.t)
        call .deallocate()
    endmethod
endstruct

function onDamage
    // retrieve the integer stored to the trigger under marker 0
    // remember we stored our struct under marker 0, so the "integer" will actually be our struct
    local data d=LoadInteger(ht,GetHandleId(GetTriggeringTrigger()),0)

    if GetTriggerEventId()==EVENT_UNIT_DAMAGED then
        // the damage event will fire even on 0.0 damage
        if GetEventDamage()>.01 then
            call DisableTrigger(d.t)
            // do effects
            // we must manipulate the trigger like this otherwise it will fire again on damage and create an infinite loop
            call EnableTrigger(d.t)
        endif
    else // timer event has fired
        call d.destroy()
    endif
    return false
endfunction
function onCast
    local data d=data.allocate()
    
    // new trigger for a new instance of the spell
    set d.t=CreateTrigger()
    set d.caster=GetTriggerUnit()
    set d.target=GetSpellTargetUnit()
    
    call TriggerRegisterUnitEvent(d.t,d.target,EVENT_UNIT_DAMAGED)
    call TriggerAddCondition(d.t,Condition(function onDamage))
    // incase we want to stop after a duration
    call TriggerRegisterTimerEvent(d.t,5.,false)
    // store the struct to the trigger, 0 is the marker, so we can retrieve this later
    // structs can also be used as integers!
    // if we wanted to store a second integer, we would need to use another marker, so we can tell the stored data apart
    call SaveInteger(ht,GetHandleId(d.t,),0,d)
    // in Maledict, you will need to register each unit effected to the trigger
endfunction


alternatively, using a damage detection system and unit attachment system would streamline this effort, storing cast instances to the effected unit and going from there
 

NeuroToxin

New Member
Reaction score
46
Ah, Thanks, I figured something like that, just didn't have a prime example. I owe you credits for two things now. The test map which I stole from you, (The demo map in the resources) And now this. Thanks Emjlr
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top