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

Set a variable, to another variable based off a Unit Indexer's given variable?

Status
Not open for further replies.
Level 5
Joined
Feb 13, 2019
Messages
128
So what I've done (this may be the issue, maybe I'm trying to cut a corner here where I need a hashtable?)

Is set variables as "stats" for units, using Bribe's Unit Indexer, as sort of a shortcut to an MUI system?


  • Hero Group
    • Events
      • Game - UnitIndexEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (UDexUnits[UDex] is A Hero) Equal to True
        • Then - Actions
          • Unit Group - Add (Triggering unit) to Hero_Group
          • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
            • Loop - Actions
              • Set VariableSet HeroAGI[UDex] = 3
              • Hero - Modify Agility of (Picked unit): Set to HeroAGI[UDex].
        • Else - Actions
          • Do nothing
What I'm aiming to do is recreate this trigger, with multiple Variables set to use for Hero Units, instead of the games built in "Hero Attributes", along with Damage Engine, to for example make it so units attacks will change in certain ways depending on the "Stats" we created, for instance this trigger will show a unit with "Higher Dexterity", (Hero Attribute Agility) "dodging" another

  • Combat
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • Set VariableSet AttackingUnit = DamageEventSource
      • Set VariableSet AttackedUnit = DamageEventTarget
      • Set VariableSet CombatDexSource = (Agility of AttackingUnit (Include bonuses))
      • Set VariableSet CombatTarget = (Agility of AttackedUnit (Include bonuses))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CombatDexSource Less than CombatTarget
        • Then - Actions
          • Set VariableSet DamageEventAmount = 0.00
        • Else - Actions
          • Do nothing

So where I have a bit of a brain fart is setting the "Attacking Unit" or "CombatDexSource" to the correct "HeroAGI[UDex]" we created.

So my thought process was to just convert it to custom text, and look inside the JASS to see if I could just tinker a bit and set this all up.

JASS:
function Trig_CDC_Func005C takes nothing returns boolean
    if ( not ( udg_CombatDexSource < udg_CombatTarget ) ) then
        return false
    endif
    return true
endfunction
function Trig_CDC_Actions takes nothing returns nothing
    set udg_AttackingUnit = udg_DamageEventSource
    set udg_DamageEventTarget = udg_AttackedUnit
    set udg_CombatDexSource = GetHeroStatBJ(bj_HEROSTAT_AGI, udg_AttackingUnit, true)
    set udg_CombatTarget = GetHeroStatBJ(bj_HEROSTAT_AGI, udg_AttackedUnit, true)
    if ( Trig_CDC_Func005C() ) then
        set udg_DamageEventAmount = 0.00
    else
        call DoNothing(  )
    endif
endfunction
//===========================================================================
function InitTrig_CDC takes nothing returns nothing
    set gg_trg_CDC = CreateTrigger(  )
    call TriggerRegisterVariableEvent( gg_trg_CDC, "udg_DamageEvent", EQUAL, 1.00 )
    call TriggerAddAction( gg_trg_CDC, function Trig_CDC_Actions )
endfunction


So this seems simple enough for a JASS newbie to understand, I just need to "Get" my custom variable instead of the "GetHeroStatBJ(bj_HEROSTAT_AGI, udg_AttackingUnit, true)" ?

I imagine that's actually quite simple and along the lines of like?

Get udg_UDexUnits[udg_UDex] ? But I'm not sure of the correct syntax and I'm currently on the JASS manual but I really wish there was a search function that would probably help me narrow this down :weekani:??
 
Level 9
Joined
Mar 26, 2017
Messages
376
Using a unit indexer is a fine alternative to hashtable.

I have looked through the code of Bribe's unit indexer, and looks like the system sets the Custom Value of an indexed unit to it's 'Udex' Id.

So you will be able to retrieve this Id value by getting that unit's custom value.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,496
It looks like you have the right idea but are not fully understanding how to use the system.

What's most important is to understand what Custom Value is and how these Unit Indexing systems take advantage of it.

So at it's core all the system does is Set each unit's Custom Value to a new unused value. This value is stored as an Integer and saved to the unit using the Action: Set unit custom value. Blizzard has provided us with the Getters/Setters for custom value, so it's not something unique to the system (although the system uses it in a unique way).

Since no two units share the same custom value then this value becomes like an ID for our units. And since this value is an Integer it can be used as the [Index] in our variable Arrays. This makes it possible to Set variable that are specific to each individual unit. All you have to do is use their custom value as the Index in that variable's array which I show in an example down below.

Also, speaking on some variables that Bribe's Unit Indexer uses. UDexUnits is a Unit Array variable that is used to keep track of the indexed units. UDex is an Integer that's used to keep track of the most recent custom value that was used by the system. These variables are really only needed when you use UnitIndexEvent, however UDexUnits can come in handy in some other cases.

Long story short, you don't necessarily need to use any of the variables provided by the Unit Indexing system. The system has already assigned a unique custom value to each of your units, all you need to do is Get this value to make use of it:
  • Set Variable SpellPower[Custom value of some unit] = 100
Here's a working example of your Damage trigger:
  • Actions:
  • Set Variable S_CV = Custom value of DamageEventSource
  • Set Variable T_CV = Custom value of DamageEventTarget
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • HeroAGI[S_CV] Less than HeroAGI[T_CV]
    • Then - Actions
      • Set Variable DamageEventAmount = 0.00
    • Else - Actions
Remember, as long as you have access to a Unit, you have access to it's Custom Value as well, and as long as you have access to it's Custom Value, you have access to ALL of your Variable Arrays that take advantage of Unit Indexing.

And you would use this line to get the unit's custom value in Jass:
vJASS:
GetUnitUserData(whichUnit)

//And an example of using it:
local integer cv = GetUnitUserData(someUnit)
set udg_HeroAGI[cv] = udg_HeroAGI[cv] + 1


Also, your first trigger has some mistakes. UDex is always equal to the most recent indexed unit's Custom Value, and you reference it multiple times for different units as if you're expecting it to change.

This is how you'd define the HeroAGI for your picked units:
  • Set Variable P_CV = Custom value of Picked unit
  • Set Variable HeroAGI[P_CV] = 3
  • Hero - Modify Agility of (Picked unit): Set to HeroAGI[P_CV]
Also, I'm not sure if Triggering Unit works with the Unit Indexer Event. You probably want to change that to UDexUnits[UDex].
  • Events:
  • Game - UnitIndexEvent becomes Equal to 1.00
  • Actions:
  • Unit Group - Add UDexUnits[UDex] to Hero_Group
Note that S_CV, T_CV, and P_CV are Integer variables. They're efficient shortcuts for keeping track of your unit(s) Custom Values throughout the trigger but they are NOT required. If you use them just be careful that you handle them properly. You don't want to accidentally set their values to something else mid-trigger, which can happen if you re-use the same variables throughout all of your triggers, especially in cases when one trigger causes another trigger to fire.

HASHTABLES:
As pr has said, Hashtables will work as well. A nice thing about a Hashtable is that it makes it easier to define a unit's base stats since you can store this information into the Hashtable using the Unit's Id as the Key. Then when a unit enters the map you can plug it's Unit Id into the hashtable and get access to this stored information and apply it directly to your unit. I attached an example map of this.
 

Attachments

  • Stat Hashtable Example 1.w3m
    17.8 KB · Views: 86
Last edited:
Level 5
Joined
Feb 13, 2019
Messages
128
It looks like you have the right idea but are not fully understanding how to use the system.

What's most important to understand is how Custom Value works. So at it's core all the system does is Set each unit's Custom Value to a new unused value. This value is stored as an Integer and saved to the unit using the Action: Set unit custom value. Blizzard has provided us with the Getters/Setters for custom value, so it's not something unique to the system (although the system uses it in a unique way).

Since no two units share the same custom value then this value becomes like an ID for our units. And since this value is an Integer it can be used as the [Index] in our variable Arrays. This makes it possible to assign a value to a variable that's specific to any given unit. All you have to do is use their custom value as the Index in that variable's array which I show in an example down below.

Also, speaking on some variables that the system uses. UDexUnits is a Unit Array variable that is used to keep track of the indexed units. UDex is used to keep track of the most recent custom value that was used by the system. These variables are really only needed when you use UnitIndexEvent, however UDexUnits can come in handy in some other cases.

What I'm trying to say is that you don't necessarily need to use any of the variables provided by the Unit Indexing system. The system has already assigned a unique custom value to each of your units, all you need to do is Get this value to make use of it:
  • Set Variable SpellPower[Custom value of some unit] = 100
Here's a working example of your Damage trigger:
  • Actions:
  • Set Variable S_CV = Custom value of DamageEventSource
  • Set Variable T_CV = Custom value of DamageEventTarget
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • HeroAGI[S_CV] Less than HeroAGI[T_CV]
    • Then - Actions
      • Set Variable DamageEventAmount = 0.00
    • Else - Actions
Remember, as long as you have access to a Unit, you have access to it's Custom Value as well, and as long as you have access to it's Custom Value, you have access to ALL of your Variable Arrays that take advantage of Unit Indexing.

And you would use this line to get the unit's custom value in Jass:
vJASS:
GetUnitUserData(whichUnit)

//And an example of using it:
local integer cv = GetUnitUserData(someUnit)
set udg_HeroAGI[cv] = udg_HeroAGI[cv] + 1


Also, your first trigger has some mistakes. UDex is always equal to the most recent indexed unit's Custom Value, and you reference it multiple times for different units as if you're expecting it to change.

This is how you'd define the HeroAGI for your picked units:
  • Set Variable P_CV = Custom value of Picked unit
  • Set Variable HeroAGI[P_CV] = 3
  • Hero - Modify Agility of (Picked unit): Set to HeroAGI[P_CV]
Also, does Triggering Unit even work with the Unit Indexer Event? You probably want to change that to UDexUnits[UDex].
  • Events:
  • Game - UnitIndexEvent becomes Equal to 1.00
  • Actions:
  • Unit Group - Add UDexUnits[UDex] to Hero_Group
Note that S_CV, T_CV, and P_CV are Integer variables. They're efficient shortcuts for keeping track of your unit(s) Custom Values throughout the trigger but they are NOT required. If you use them just be careful that you handle them properly. You don't want to accidentally set their values to something else mid-trigger, which can happen if you re-use the same variables throughout all of your triggers, especially in cases when one trigger causes another trigger to fire.

HASHTABLES:
As pr has said, Hashtables will work as well. A nice thing about a Hashtable is that it makes it easier to define a unit's base stats since you can store this information into the Hashtable using the Unit's Id as the Key. Then when a unit enters the map you can plug it's Unit Id into the hashtable and get access to this stored information and apply it directly to your unit. I attached an example map of this.


I'm sorry for the late reply, but thank you so much, I really appreciate the help, and having an example to dissect really helped me with trying to understand Hashtables, I can't thank you enough.



I just haven't had a lot of free time lately, but I feel like I'm making some progress and am going to sit down and go over this top to bottom within the next few days, but I truly appreciate the assistance!! :week::week::week:
 
Last edited:
Level 5
Joined
Feb 13, 2019
Messages
128
LMAOOOO I'm so stupid, I couldn't figure out how this possibly was wrong

  • Hero - Modify Strength of (Triggering unit): Set to (Load 1 of (Key (Triggering unit).) from Stat_Hashtable.).
it's because

  • Unit - A unit enters (Playable map area)
My units were preplaced and not entering and I assumed preplaced units "entered" the map upon loading, so yeah I actually do understand my Handles, I was losing my mind I was like "I know I'm doing this correctly?!?!" I reread tutorials like 5 times, etc. Hahahah oops! :week:
 
Status
Not open for further replies.
Top