System Unique Unit Custom Value

wewso

New Member
Reaction score
11
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 :p

VVV The map may help you VVV
 

Attachments

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

GoGo-Boy

You can change this now in User CP
Reaction score
40
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!!).
 

wewso

New Member
Reaction score
11
@ 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!
Reaction score
662
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
Reaction score
11
@ 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.
 
Reaction score
333
@ 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!
Reaction score
662
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
Reaction score
50
Or you can use the new extended arrays in vJass to push your array limit to 65526 :p
 

wewso

New Member
Reaction score
11
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
Reaction score
40
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
Reaction score
152
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
Reaction score
1
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
Reaction score
803
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

Your Friendly Neighborhood Admin
Reaction score
1,494
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
Reaction score
152
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
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top