# SystemUnique Unit Custom Value

#### wewso

##### New Member
Unique Custom Value System

Explanation:
So, I have been having problems lately with some of the spells in my Hero Arena. Most of them work with triggers and so I had to make them MUI (Multi-Unit-Instanceability) which means that they should work propperly on more than one unit at the same time. Then I came up with the idea of giving each unit a unique custom value which can be used in varaible arrays to store information about the unit.

First I made a trigger that gives each unit custom value, equal to the order it was created. I worked a little bit on the system and I came to the conclusion that it wont work that way since there may be enormous amounts of units created, but very little of them are left alive. I would have had a unit with custom value 2 and a unit with 457 and all the units that had custom values between 2 and 457 dead and their values - unused. To fix this I made the trigger to set the custom value of the unit to the lowest positive number that is not used by another unit.

Example:

1. I train a Footman and he is the first unit in the map. The lowest unused positive number is 1 so the footy gets Custom Value 1
2. Then I train another footman, who is the second trained unit in the map. Analogicaly he gets Custom Value 2
3. Now I take Footman 2 and kill Footman 1 with him.
4. Then I train another Footman, that is the third trained unit in the map. However he doesnt get Custom Value 3 because the lowest unused number is 1 (Footman 1 died a while ago) His Custom Value is set to 1.

Here are the triggers:

You need only 1 varaible "Loop" - a non-array integer

Main trigger for new units:
Code:
``````New Unit Custom Value
Events
Unit - A unit enters (Entire map)
Conditions
(Custom value of (Triggering unit)) Equal to 0
Actions
Set Loop = 0
For each (Integer A) from 1 to 8192, do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Then - Actions
Unit Group - Pick every unit in (Units in (Entire map)) and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Custom value of (Picked unit)) Equal to (Integer A)
Then - Actions
Set Loop = (Loop + 1)
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Loop Equal to 0
Then - Actions
Unit - Set the custom value of (Triggering unit) to (Integer A)
Skip remaining actions
Else - Actions
Else - Actions``````

Trigger for pre-placed units:
Code:
``````Prepalced Unit Custom Value
Events
Map initialization
Conditions
Actions
Set Loop = 0
Unit Group - Pick every unit in (Units in (Entire map)) and do (Actions)
Loop - Actions
Set Loop = (Loop + 1)
Unit - Set the custom value of (Picked unit) to Loop``````

NOTE 1: Units still exist even after they are killed. They can be manipulated until their corpses dissappear. My system wont consider a Custom Value number free until the unit it was used by is remover from the game or its corpse dissappears. I did this to avoid bugs with reviving Heroes or Animate Dead spell.

NOTE 2: The system can handle no more that 8192 units at a time. You can change this restriction but remember that the maximum Array size is 8192 and you wont be able to store the unit data in the varaible. However strongly reccomend you not to use that many units in your map :shades:.

++Rep if you liked it

#### Attachments

• Custom Value System.w3x
17.5 KB · Views: 299

#### GoGo-Boy

##### You can change this now in User CP
Code:
`````` For each (Integer A) from [COLOR="Purple"]1 to 8192,[/COLOR] do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)[COLOR="Red"]
If - Conditions
Loop Equal to 0[/COLOR]
Then - Actions
Unit Group - [COLOR="Purple"]Pick every unit in (Units in (Entire map))[/COLOR] and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
[COLOR="Red"]    If - Conditions
(Custom value of (Picked unit)) Equal to [/COLOR](Integer A)
Then - Actions
Set Loop = (Loop + 1)
Else - Actions``````

Hell each time a unit enters the map there will be 8192 * (Units in playable map area) loop actions??? That is insane I think. Let's say you got 100 units... the game/CPU performs 819200 times conditions (some are really useless or not? It's so hard too look at GUI code but checking whether loop = 0 when you set it to 0 before?? And afterwards it won't be 0 anyway or?) and some set-actions.

Just use Cohadars PUI system. Made in JASS??? Yep, but still easy to implant and even easy to use in GUI (just one custom script line!!).

#### AceHart

> all the units that had custom values between 2 and 457 dead and their values - unused

What is the problem with that?

#### TheDamien

##### _
This is an inefficient method, a stack based allocator would be a wiser choice.

#### wewso

##### New Member
@ AceHart

Ok then Ill give another example:

I have played a massive strategy map for an hour and I have trained a total of 8192 units. Currently only 356 of then are alive, but the new units I train will still get a custom value above 8192 and wont be able to be included in varaibles with arrays. Thats why I need to fill up the space between 1 and 8192 and not go above 8192.

_______

@ GoGo-Boy
Hell each time a unit enters the map there will be 8192 * (Units in playable map area) loop actions??? That is insane I think. Let's say you got 100 units... the game/CPU performs 819200 times conditions (some are really useless or not? It's so hard too look at GUI code but checking whether loop = 0 when you set it to 0 before?? And afterwards it won't be 0 anyway or?) and some set-actions.

I did this only to make the code with least varaibles as possible. Work that way too:

Code:
``````    Actions
Set Loop = 0
Set Units_Trained = Units_Trained + 1
For each (Integer A) from 1 to Units_Trained, do (Actions)``````

_______

@ TheDamien
Can you explain what a "stack based allocator" is?

#### Flare

##### Stops copies me!
from my understanding of your first code, it will run the integer loop, and give every unit within (Units in playable map area) a custom value of Integer A, THEN move onto the next integer. So (if I'm correct) every unit will have the exact same custom value of 8192 (since the integer loop ends at 8192).

Couldn't you just use uareanoob's GUI MUI system? Or read my GUI MUI tutorial, incase you ever need another use for unit's custom value (such as keeping track of each units kills, deaths and so on). Or, as Gogo-Boy suggested, learn to use Cohadar's PUI

#### wewso

##### New Member
@ Flare
from my understanding of your first code, it will run the integer loop, and give every unit within (Units in playable map area) a custom value of Integer A, THEN move onto the next integer. So (if I'm correct) every unit will have the exact same custom value of 8192 (since the integer loop ends at 8192).

No, with the unit pick function it checks if that number has been used by any unit and if not it sets the Custom Value of the entering unit to it.
_________

@ GoGo-Boy

You r right I dont need the Loop check condition

I ll just use
Code:
``Skip remaining actions``
When the Custom Value is ready.

#### TheDamien

##### _
@ TheDamien
Can you explain what a "stack based allocator" is?

A stack is a sort of data structure. The basic idea is you can add and remove things from the top of the stack only. A very minimal stack based allocator would have a function for retrieving and removing a value from the top of the stack (or generating a unique value if the stack is empty) and a function for adding a value to the top of the stack.

#### Flare

##### Stops copies me!
Also, does (Units in (Entire Map)) leak (or does it work like All Players)? If so, you might want to clean it up. 8192 leaks in an instant would be pretty bad :S

Here's what I use whenever I need to add a custom value to all units. Whether it helps you in anyway, I don't really know. Only flaw would be that it would overlap if unit 1 was still in the game when unit 8193 (i.e. the unit after highest custom value number has been used, so it's back to 1 again).

Code:
``````Damage detection init 1
Events
Map initialization
Conditions
Actions
Set TempGroupA = (Units in (Playable map area))
Unit Group - Pick every unit in TempGroupA and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
INTEGER Less than or equal to 8192
Then - Actions
Set INTEGER = (INTEGER + 1)
Else - Actions
Set INTEGER = 1
Unit - Set the custom value of (Picked unit) to INTEGER

-----------------------------------------------

Damage detection init 2
Events
Unit - A unit enters (Playable map area)
Conditions
Actions
Unit Group - Add (Triggering unit) to TempGroupB
Unit Group - Remove all units of TempGroupA from TempGroupB
Unit Group - Pick every unit in TempGroupB and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
INTEGER Less than or equal to 8192
Then - Actions
Set INTEGER = (INTEGER + 1)
Else - Actions
Set INTEGER = 1
Unit - Set the custom value of (Picked unit) to INTEGER
Unit Group - Add (Picked unit) to TempGroupA
Unit Group - Remove (Picked unit) from TempGroupB``````

#### Gwypaas

##### hook DoNothing MakeGUIUsersCrash
Or you can use the new extended arrays in vJass to push your array limit to 65526

#### wewso

##### New Member
Well you could still have more than 65526 units created in your map if you are playing a massive Strategy for a very long time.
Such maps are very rare but the mere idea of having limits doesnt suit me.:shades:

#### GoGo-Boy

##### You can change this now in User CP
There will most likely never be a map where you get more then 65000 units.
Dummies might become a problem.. but simple unit type conditions do it.

#### U are a noob

##### Mega Super Ultra Cool Member
This is another good method. Although already thought of. I did the same thing but I was preparing mine for the instances where it gets too 8912 that one player wouldn't have an excessive amount of units over another player.

#### Burningicce9

##### Cool Member
Why not just use PUI by cohadar? It does what you are trying to do, but covers things like units being removed, and works perfectly.

You just do Custom Script: GetUnitIndex(unit) to get a units "unique custom value"

#### vypur85

##### Hibernate
Code:
``````New Unit Custom Value
Events
Unit - A unit enters (Entire map)
Conditions
(Custom value of (Triggering unit)) Equal to 0
Actions
Set Loop = 0
For each (Integer A) from 1 to 8192, do (Actions)
Loop - Actions
[B]                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions[/B]
[I]<Here>[/I]
Then - Actions
Unit Group - Pick every unit in (Units in (Entire map)) and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Custom value of (Picked unit)) Equal to (Integer A)
Then - Actions
Set Loop = (Loop + 1)
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Loop Equal to 0
Then - Actions
Unit - Set the custom value of (Triggering unit) to (Integer A)
Skip remaining actions
Else - Actions
Else - Actions``````

How come the condition is not used? (Did you update it and forgot to use it?)

And how are you going to reference the custom value for a particular unit? For example, if player 1 and player 2 both have Footman. One with custom value of 23 and the other is 463. So, how do you reference which Footman is for Player 1 while the other is for Player 2?

#### AceHart

FWIW:

Code:
``````Index Init
Events
Map initialization
Conditions
Actions
Set UnitIndex_Top = 0
Set UnitIndex_Check = 0
Set UnitGroup = (Units in (Playable map area))
Unit Group - Pick every unit in UnitGroup and do (Actions)
Loop - Actions
Set UnitIndex_Top = (UnitIndex_Top + 1)
Set UnitIndex_Units[UnitIndex_Top] = (Picked unit)
Set UnitIndex_Index[UnitIndex_Top] = UnitIndex_Top
Unit - Set the custom value of (Picked unit) to UnitIndex_Top
Set UnitIndex_Max = UnitIndex_Top
Custom script:   call DestroyGroup( udg_UnitGroup )``````
Code:
``````Index Update
Events
Unit - A unit enters (Playable map area)
Conditions
(Custom value of (Triggering unit)) Equal to 0
Actions
Set UnitIndex_Top = (UnitIndex_Top + 1)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
UnitIndex_Top Greater than UnitIndex_Max
Then - Actions
Set UnitIndex_Max = UnitIndex_Top
Set UnitIndex_Index[UnitIndex_Max] = UnitIndex_Max
Else - Actions
Set UnitIndex_Units[UnitIndex_Top] = (Triggering unit)
Unit - Set the custom value of (Triggering unit) to UnitIndex_Index[UnitIndex_Top]``````
Code:
``````Index Clean
Events
Time - Every 0.20 seconds of game time
Conditions
UnitIndex_Top Greater than 0
Actions
Set UnitIndex_Check = (UnitIndex_Check + 1)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
UnitIndex_Check Greater than UnitIndex_Top
Then - Actions
Set UnitIndex_Check = 0
Skip remaining actions
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Unit-type of UnitIndex_Units[UnitIndex_Check]) Not equal to No unit-type
Then - Actions
Skip remaining actions
Else - Actions
Set UnitIndex_Units[UnitIndex_Check] = UnitIndex_Units[UnitIndex_Top]
Set TempInteger = UnitIndex_Index[UnitIndex_Check]
Set UnitIndex_Index[UnitIndex_Check] = UnitIndex_Index[UnitIndex_Top]
Set UnitIndex_Index[UnitIndex_Top] = TempInteger
Set UnitIndex_Top = (UnitIndex_Top - 1)``````

Variables used:
UnitIndex_Top, integer
UnitIndex_Max, integer
UnitIndex_Check, integer
UnitIndex_Index, integer array
UnitIndex_Units, unit array
UnitGroup, unit group
TempInteger, integer

Note:
Those triggers are only verified correct, not actually tested.

#### U are a noob

##### Mega Super Ultra Cool Member
Hell each time a unit enters the map there will be 8192 * (Units in playable map area) loop actions??? That is insane I think. Let's say you got 100 units... the game/CPU performs 819200 times conditions (some are really useless or not? It's so hard too look at GUI code but checking whether loop = 0 when you set it to 0 before?? And afterwards it won't be 0 anyway or?) and some set-actions.

Wrong. There is only one instance that there will ever be 8192 conditions. Remember the "skip remaining actions".

This system works perfect. Only problem is every time you want to remove a units custom value you have to set it to 0. Thats one more action you need to set on dummy units.

General chit-chat
Help Users
• Blackveiled:
I wouldn't know, I'm in Joliet, Illinois right now working. I left Houston area about 2 weeks ago lol
• Blackveiled:
Not permanently of course, just a temporary job.
+1
• jonas:
• jonas:
@Blackveiled you know another word for permanent? temporary
+1
• Varine:
Briefly, he'll only be there for the interim. Like a stopgap of sorts, he'll be back home in short time
Hurray! Tom has reappeared!
• The Helper:
Happy Thursday!
• Blackveiled:
Yep. Just another fun night at work.
• Varine:
Broke the nozzle on my 3d printer and I don't have another heater block. So... I guess I'm fucked on that this weekend
• The Helper:
that sucks i bet they are expensive
• Varine:
Not really
• Varine:
The entire hot end is like 20 dollars, I just can't get anymore until next week
• Varine:
I ordered like five blocks for 15 dollars. They're just little aluminum blocks with holes drilled into them
• Varine:
They are pretty much disposable. I have shitty nozzles though, and I don't think these were designed for how hot I've run them
• Varine:
I tried to extract it but the thing is pretty stuck. Idk what else I can use this for
• Varine:
I'll throw it into my scrap stuff box, I'm sure can be used for something
• Varine:
I have spare parts for like, everything BUT that block lol. Oh well, I'll print this shit next week I guess. Hopefully it fits
• Varine:
I see that, despite your insistence to the contrary, we are becoming a recipe website
• Varine:
Which is unique I guess.
• The Helper:
Actually I was just playing with having some kind of mention of the food forum and recipes on the main page to test and see if it would engage some of those people to post something. It is just weird to get so much traffic and no engagement
• The Helper:
So what it really is me trying to implement some kind of better site navigation not change the whole theme of the site