How to tell if a unit is already in a struct instance?

NeuroToxin

New Member
Reaction score
46
As the title says, I want to know how to tell if a unit is already associated with another struct instance of the same type.
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
You will need to somehow associate that struct with the unit, eg. by saving its integer in a hashtable at the unit's handle ID, or in an array at the unit's custom value (if using a unit indexer like AIDS). Then, you can see if a struct is attached to the unit because there will be a value. (Don't forget to clear it/set to 0 when destroying the struct!)

Alternately, the struct itself could be made to extend array, and using a unit indexer, the struct can be made to have the same index as the unit, so there will always only be 1 instance per unit because you designed it that way. :)
 

Bo-Bo

New Member
Reaction score
8
Store the structs in an array, then do something like this:

JASS:
static method isUnitInArray takes unit u returns boolean
  local thistype this
  local integer i = 0
  local boolean check = false
  
  loop
    exitwhen (check or (i >= STRUCT_COUNT))

    set this = STRUCT_ARRAY<i>
    if (.u == u) then
      set check = true
    endif
    
    set i = i + 1
  endloop

  return check
endmethod</i>

".u" being of course a member of your struct.

That's the way I do it, but of course there are tons of better ways.
And I'd be glad to learn them. =)
 

NeuroToxin

New Member
Reaction score
46
What im trying to do, is get it so every dummy unit is associated with its caster. EX. When a unit dies, I have a passive that is going to send it to the unit, then make it circle around the unit. However, when I want to select a random unit frmo there, I cannot do (units owned by (triggering unit)) Therefore, I need to find a way to associate the dummy units with a certain unit. I am fully against hashtables as they confuse me.
 

tooltiperror

Super Moderator
Reaction score
231
Hash tables are about as complicated as you let them be.

It's a 2D array. You can throw in some extra function calls and fancy handle magic, but a hash table is simply a special array.
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
What im trying to do, is get it so every dummy unit is associated with its caster.
I'd add the dummies to a unit group member of a struct attached to the caster...or, in semi-GUI language, a unit group array keyed to the custom value of the caster as assigned by a unit indexing system.
 

chobibo

Level 1 Crypt Lord
Reaction score
48
Use a unit indexing system, since all units have a unique Id assigned to it, structs instances would be assinged to a uniqe unit id as well.

consider the following example:
JASS:

function sample takes nothing returns boolean
    local integer id=GetUnitIndex(X)
    local structA A=A(id)
    local structB B=B(id)
endfunction

when you create a structA or structB's instance, both of them will use the same id, hence we may say that structA and structB's instance is attached to unit X.
Of course, implementation of the said script would be different, or should be added to the structs create method.
 

luorax

Invasion in Duskwood
Reaction score
67
Use Vexorian's Table. Then do something like this: (Handwritten!)

JASS:
struct ABC
    
    unit Owner
    
    private static HandleTable table

    static method create takes unit u returns thistype
        local thistype this = 0
        
        if thistype.table.exists(u) then
            return thistype(thistype.table<u>)
        endif

        set this = thistype.allocate()
        set this.Owner = u
        set thistype.table[this.Owner] = this
        return this
    endmethod

    method destroy takes nothing returns nothing
        call thistype.table.flush(this.Owner)
        set this.Owner = null
        call this.deallocate()
    endmethod

    static method getInstance takes unit u returns thistype
        return thistype(thistype.table<u>)
    endmethod

    private static method onInit takes nothing returns nothing
        set thistype.table = HandleTable.create()
    endmethod

endstruct</u></u>
 

Romek

Super Moderator
Reaction score
964
You could make a static group in the struct. When a unit becomes associated with an instance, add the unit to the group. When the object is destroyed, remove the unit from the group.
Then simply use [ljass]IsUnitInGroup[/ljass]. If you're using an sort of unit indexing system, it'd probably be a safer bet to use that to attach the boolean instead.

Don't loop through every instance of the struct. There are far better ways of accomplishing what you want.
 

Sevion

The DIY Ninja
Reaction score
413
As Romek says, don't loop through every instance of the struct... That's very, very inefficient. As bad as it can get.

You guys are making this as complicated as you can, aren't you? D:

JASS:
struct myStruct
    // ... blah blah blah ...

    public static hashtable hash
    public unit whichUnit

    public static method has takes unit whichUnit returns boolean
        return (LoadInteger(thistype.hash, GetHandleId(whichUnit), 0) != 0 or not HaveSavedInteger(thistype.hash, GetHandleId(whichUnit), 0))
    endmethod

    public static method create takes unit whichUnit returns thistype
        local thistype this
        
        if (LoadInteger(thistype.hash, GetHandleId(whichUnit), 0) != 0 or not HaveSavedInteger(thistype.hash, GetHandleId(whichUnit), 0)) then // Second part may not be necessary. I don&#039;t remember
            set thistype.whichUnit = whichUnit
            call SaveInteger(thistype.hash, GetHandleId(whichUnit), 0, this)
        else
            debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;Warning: Unit already identified with an instance!&quot;)
            return 0
        endif
        // ... blah blah blah ...
        return this
    endmethod

    private method onDestroy takes nothing returns nothing
        call RemoveInteger(thistype.hash, GetHandleId(this.whichUnit), 0)
        set this.whichUnit = null
    endmethod

    private static method onInit takes nothing returns nothing
        set thistype.hash = InitHashtable()
    endmethod
endstruct

function trololol takes unit whichUnit returns nothing
    local myStruct lolol

    if ( not myStruct.has(whichUnit) ) then
        set lolol = myStruct.create(whichUnit)
    endif

    // ... blah blah blah ...
endfunction
 

chobibo

Level 1 Crypt Lord
Reaction score
48
You guys are making this as complicated as you can, aren't you?
You're doing the same too.

First of all, the linear search is bad lol.

The group check is simple to implement, but you'll need 1 group handle per struct or per spell with the same properties. The algorithm for checking the units inside the group is hidden, but I believe it's efficient enough.

The Hashtable, while also simple to implement, suffers from the same problem (1 hash table per struct or spell, as suggested by your code). Vexorian's Table on the other hand does not, since it uses a single hashtable.

A unit indexing system could handle multiple structs, it could even replace the struct initializer if done properly. But its not without a disadvantage, implementation is a pain in the ass.

All of these solutions have strongpoints and disadvantages, so it really depends to NeuroToxin's map, if the solution would conflict or not in his project.

The problem at hand is also not as simple as you think it is.

No offence man! :D Just trying to give an opinion.
 

Sevion

The DIY Ninja
Reaction score
413
I think you're misunderstanding my code.

The 1 hashtable per struct/spell is for handling collisions o_O'

(I.E. two different structs instanced to the same unit would overwrite each other unless you had two hashtables OR, read below)

And there'd be a way to make it 1 global hashtable. Simply instead of saving the data at 0, save it at a key for each struct.

I simply don't like Table. However nice it probably is, I don't like it. Never had to use it.
 

chobibo

Level 1 Crypt Lord
Reaction score
48
I did understand, I just wanted to point out the way you are trying to do it. Whenever you want to attach a struct to a unit, you'd need to use 1 hashtable, and we all know wc3 engine suck at handling large amount of handles. Like you said, it's possible to just use a single hashtable for it, but of course it depends on the one putting the scripts in the map to handle those public handles, and that makes the said solution unportable, but possible. :D

I also haven't used hashtables, we'll because I never do anything, just some random scripts lol.
 

Sevion

The DIY Ninja
Reaction score
413
Truthfully, I would rather handle the hashtable myself than have an indexing system or other do it. There's less overhead when I do it.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1

      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