• 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.
  • 💡 We're thrilled to announce that our upcoming texturing contest is in the works, and we're eager to hear your suggestions! Please take this opportunity to share your ideas in this theme discussion thread for the Texturing Contest #34!
  • 🏆 Hive's 7th HD Modeling Contest: Icecrown Creature is now open! The frozen wastes of Icecrown are home to some of Azeroth’s most terrifying and resilient creatures. For this contest, your challenge is to design and model a HD 3D monster that embodies the cold, undead, and sinister essence of Icecrown! 📅 Submissions close on April 13, 2025. Don't miss this opportunity to let your creativity shine! Enter now and show us your frozen masterpiece! 🔗 Click here to enter!

Hashtable and Damage Blocking Ability Help Needed

Status
Not open for further replies.
Level 5
Joined
Feb 8, 2015
Messages
93
Hello Hive!

I'm in need of some help for a Shield Spell that I'm triggering. The spell is called "Cragskin" (you'll see that in variable names) and it targets an ally, giving them a buff. Based off of Frost Armor.

The spell is supposed to reduce the damage of the next 3 incoming attacks/damage sources by a percentage. So when the buff is on, the trigger should count to 3 (using Bribe's Damage Detection Engine) and reduce those attacks by for instance 45%, then the buff should be removed after 3 attacks.

Problem here is that the hashtable I use to save the Hits-Taken for each affected unit always returns 0, can anyone here spot the problem?

  • Cragskin Activate
    • Events
      • Unit - A unit owned by Player 1 (Red) Starts the effect of an ability
      • Unit - A unit owned by Player 2 (Blue) Starts the effect of an ability
      • Unit - A unit owned by Player 3 (Teal) Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Cragskin
    • Actions
      • Set Cragskin_r = (0.25 + (0.15 x (Real((Level of (Ability being cast) for (Triggering unit))))))
      • Set Cragskin_Counteri = 3
      • Hashtable - Save (Real(Cragskin_Counteri)) as (Key HitsCounter) of (Key (Target unit of ability being cast)) in Cragskin_hash
  • Cragskin HitTaken
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • (DamageEventTarget has buff Cragskin ) Equal to True
    • Actions
      • Game - Display to (All players) the text: Run
      • Set Cragskin_Tempu1 = DamageEventTarget
      • Unit Group - Pick every unit in (Units in (Playable map area) matching ((Matching unit) Equal to Cragskin_Tempu1)) and do (Actions)
        • Loop - Actions
          • Set Cragskin_Tempu2 = (Picked unit)
          • Set Cragskin_Counteri = (Load (Key HitsCounter) of (Key (Picked unit)) from Cragskin_hash)
          • Game - Display to (All players) the text: (String(Cragskin_Counteri))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Cragskin_Counteri Greater than or equal to 1
            • Then - Actions
              • Set DamageEventAmount = (DamageEventAmount - (DamageEventAmount x Cragskin_r))
              • Hashtable - Save (Real((Cragskin_Counteri - 1))) as (Key HitsCounter) of (Key (Picked unit)) in Cragskin_hash
            • Else - Actions
              • Unit - Remove Cragskin buff from Cragskin_Tempu2
thanks in advance.
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
First of all... why don't you use a generic starts the effect of an ability event?

Secondly... why group all units in the map and check if they are a specific unit?
You already have that unit so no need to loop through all of em.

For the problem... I think that a hashtable does not return an integer if you did LoadReal().
Try LoadInteger() instead.
 
Level 5
Joined
Feb 8, 2015
Messages
93
Secondly... why group all units in the map and check if they are a specific unit?
You already have that unit so no need to loop through all of em.

I did it to be capable of using the "handle: Picked unit" in the hashtable, is there a way to work around this handle method?

And also, the hashtables concerning the integer all use save/load integer () now, but they still don't work.
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
Key of (DamageEventTarget) not working?

Make 2 actions "Game - Display text" and let them show the key you are using, check if they are the same. (One on spellcast and the other on take damage.)

Also where does HitsCounter come from?

I suppose that that could just be an integer instead of a key.
 
Level 5
Joined
Feb 8, 2015
Messages
93
I tried what you suggested (assuming that I understood the suggestion properly), and it seems that the integer is set correctly (to 3) on spell cast, but immediatly goes to 0 when damage is taken. Here are the triggers as of now:



  • Cragskin Activate
    • Events
      • Unit - A unit owned by Player 1 (Red) Starts the effect of an ability
      • Unit - A unit owned by Player 2 (Blue) Starts the effect of an ability
      • Unit - A unit owned by Player 3 (Teal) Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Cragskin
    • Actions
      • Set Cragskin_r = (0.25 + (0.15 x (Real((Level of (Ability being cast) for (Triggering unit))))))
      • Set Cragskin_Counteri = 3
      • Hashtable - Save Cragskin_Counteri as 1 of (Key (Target point of ability being cast)) in Cragskin_hash
      • Game - Display to (All players) the text: ((Load (Key (Target unit of ability being cast)) of 1 from (Last created hashtable)) + (String(Cragskin_Counteri)))
  • Cragskin HitTaken
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • (DamageEventTarget has buff Cragskin ) Equal to True
    • Actions
      • Game - Display to (All players) the text: Run noUg
      • Set Cragskin_Counteri = (Load 1 of (Key (Target unit of ability being cast)) from Cragskin_hash)
      • Set Cragskin_Tempu2 = DamageEventTarget
      • Game - Display to (All players) the text: ((Load (Key (Target unit of ability being cast)) of 1 from (Last created hashtable)) + (String(Cragskin_Counteri)))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Cragskin_Counteri Greater than or equal to 1
        • Then - Actions
          • Set DamageEventAmount = (DamageEventAmount - (DamageEventAmount x Cragskin_r))
          • Hashtable - Save (Cragskin_Counteri - 1) as 1 of (Key (Target unit of ability being cast)) in Cragskin_hash
        • Else - Actions
          • Unit - Remove Cragskin buff from Cragskin_Tempu2
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
Well... you could use my Effect Over Time System to make the effect.
However it is not yet finished and will take up to a week to be finished.

If you can wait until then you have a perfect working one.
It has an in-built hashtable that grants easy control over the data.
You will also have some nice features about buffs.

But again, I cannot see what the problem is in your trigger.
So someone else should help you or you have to wait a week.
If so I can make this spell for you. It is not that hard.
 
Level 20
Joined
Jul 14, 2011
Messages
877
In that one you pick every unit that is equal to DamageEventTarget. Just use DamageEventTarget. Also makes sure HitsCounter stays the same, so you load the correct value.

E: Cragskin_Counteri is getting changed everytime the second trigger triggers, so if multiple units cast it there will surely be a problem. You can replace this:
  • Set Cragskin_Tempu2 = DamageEventTarget
with: local unit udg_Cragskin_Tempu2 = udg_DamageEventTarget

@Wietlol GUI hashtables arent in JNGP. If you have a trigger with them, it will work correctly but you cant actualy create those actions.
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
In that one you pick every unit that is equal to DamageEventTarget. Just use DamageEventTarget. Also makes sure HitsCounter stays the same, so you load the correct value.

E: Cragskin_Counteri is getting changed everytime the second trigger triggers, so if multiple units cast it there will surely be a problem. You can replace this:
  • Set Cragskin_Tempu2 = DamageEventTarget
with: local unit udg_Cragskin_Tempu2 = udg_DamageEventTarget
That is not entirely true because he sets that value to the value from the hashtable.

However you can use this instead:
  • Set TempUnit = DamageEventTarget
  • Custom script: set udg_TempInteger = LoadInteger(udg_Cragskin_hash, GetHandleId(udg_TempUnit), 1)
  • Set Cragskin_Counteri = TempInteger
You require 2 variables "TempUnit : unit" and "TempInteger : integer".
That code is the best way to do it... you can indeed just use one custom script:
  • Custom script: set udg_Cragskin_Counteri = LoadInteger(udg_Cragskin_hash, GetHandleId(udg_DamageEventTarget), 1)
But that can only be used in that trigger.
If you have other problems, the first one can also be applied to other triggers.

@Wietlol GUI hashtables arent in JNGP. If you have a trigger with them, it will work correctly but you cant actualy create those actions.
So lame -_-
However as I said before I never use GUI.
So I guess that I don't really have to care :D
 
Level 5
Joined
Feb 8, 2015
Messages
93
I followed your advice Wietl, and the trigger now looks like this

  • Cragskin HitTaken
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • (DamageEventTarget has buff Cragskin ) Equal to True
    • Actions
      • Game - Display to (All players) the text: Run noUg
      • Set Cragskin_Tempu2 = DamageEventTarget
      • Custom script: set udg_TempInteger = LoadInteger(udg_Cragskin_hash, GetHandleId(udg_Cragskin_Tempu2), 1)
      • Set Cragskin_Counteri = TempInteger
      • Game - Display to (All players) the text: ((Load (Key (Target unit of ability being cast)) of 1 from Cragskin_hash) + (String(Cragskin_Counteri)))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Cragskin_Counteri Greater than or equal to 1
        • Then - Actions
          • Set DamageEventAmount = (DamageEventAmount - (DamageEventAmount x Cragskin_r))
          • Hashtable - Save (Cragskin_Counteri - 1) as 1 of (Key (Target unit of ability being cast)) in Cragskin_hash
        • Else - Actions
          • Unit - Remove Cragskin buff from Cragskin_Tempu2


But it still doesn't work, the buff is immediatly removed and no damage is negated.
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
  • Hashtable - Save (Cragskin_Counteri - 1) as 1 of (Key (Target unit of ability being cast)) in Cragskin_hash
Use Cragskin_Tempu2 + custom script again (Cragskin_Tempu2 should be TempUnit to reduce your amount of global variables)

  • Game - Display to (All players) the text: ((Load (Key (Target unit of ability being cast)) of 1 from Cragskin_hash) + (String(Cragskin_Counteri)))
Try to put the Cragskin_Counteri in it instead and see if the data is stored properly... Because it is not. Otherwise the damage would be reduced.
 
Level 5
Joined
Feb 8, 2015
Messages
93
  • Hashtable - Save (Cragskin_Counteri - 1) as 1 of (Key (Target unit of ability being cast)) in Cragskin_hash
Use Cragskin_Tempu2 + custom script again (Cragskin_Tempu2 should be TempUnit to reduce your amount of global variables)

  • Game - Display to (All players) the text: ((Load (Key (Target unit of ability being cast)) of 1 from Cragskin_hash) + (String(Cragskin_Counteri)))
Try to put the Cragskin_Counteri in it instead and see if the data is stored properly... Because it is not. Otherwise the damage would be reduced.


Sorry I do not quite understand, where are each of these supposed to go? Which lines in my trigger should be changed?
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
Those are both from the trigger you posted -_-
At the bottom you save again but then on "Target unit of ability being cast".
That should be that custom script again.

The display message should use the exact same reference as what you use... which is Cragskin_Counteri rather than loading from the hashtable again. (not for performance but to avoid mistakes)
Also try to diplay the name of the targeted unit and the number of the stacks.
 
Level 20
Joined
Jul 14, 2011
Messages
877
  • Set Cragskin_Tempu2 = DamageEventTarget
  • Custom script: set udg_TempInteger = LoadInteger(udg_Cragskin_hash, GetHandleId(udg_Cragskin_Tempu2), 1)
  • Set Cragskin_Counteri = TempInteger
->
  • Custom script: set udg_Cragskin_Counteri = LoadInteger(udg_Cragskin_hash, GetHandleId(udg_DamageEventTarget), 1)
Also:
  • Hashtable - Save (Cragskin_Counteri - 1) as 1 of (Key (Target unit of ability being cast)) in Cragskin_hash
->
  • Hashtable - Save (Cragskin_Counteri - 1) as 1 of (Key (DamageEventTarget)) in Cragskin_hash
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
You cannot use variables inside the key method of hashtables.

Also:
  • Set TempUnit = DamageEventTarget
  • Custom script: set udg_TempInteger = LoadInteger(udg_Cragskin_hash, GetHandleId(udg_TempUnit), 1)
  • Set Cragskin_Counteri = TempInteger
You require 2 variables "TempUnit : unit" and "TempInteger : integer".
That code is the best way to do it... you can indeed just use one custom script:
  • Custom script: set udg_Cragskin_Counteri = LoadInteger(udg_Cragskin_hash, GetHandleId(udg_DamageEventTarget), 1)
But that can only be used in that trigger.
If you have other problems, the first one can also be applied to other triggers.
 
Status
Not open for further replies.
Top