System Track Unit Movement System

uberfoop

~=Admiral Stukov=~
Reaction score
177
Uh oh, I'm not safe? :eek:
If you use them without checking for stuff recycling like Gtam is doing, very much so. Normally, not THAT much, though hashtables, being hashtables, are presumably not entirely watertight.





Anyway...

This demonstration of system break may be a little overelaborate, because I was trying to twist the map's arm to force it to recycle the id of the first unit I created to a specific unit, but anyway, here's another system break:
JASS:

scope THISBREAKSGTAMSSYSTEM initializer SHAMWOW
globals
    unit EL_MAN
    unit THE_OTHER_MAN
    unit UN_MAN
endglobals

function DISP takes nothing returns nothing
    call BJDebugMsg(R2S(GetUnitMovingDistance(UN_MAN)))
endfunction

function LOLWUT takes nothing returns nothing
    set UN_MAN = CreateUnit(Player(0),'hfoo',0,0,0)
    call RemoveUnit(THE_OTHER_MAN)
    call TrackUnitMovement(UN_MAN)
    call TimerStart(CreateTimer(),1,true,function DISP)
endfunction

function LOLCATS takes nothing returns nothing
    set THE_OTHER_MAN = CreateUnit(Player(0),'hfoo',0,0,0)
    call TimerStart(CreateTimer(),1,false,function LOLWUT)
    call TrackUnitMovement(THE_OTHER_MAN)
endfunction

function SLAPCHOP takes nothing returns nothing
    call RemoveUnit(EL_MAN)
    call TimerStart(CreateTimer(),15,false,function LOLCATS)
    set EL_MAN=null
endfunction

function SHAMWOW takes nothing returns nothing
    set EL_MAN = CreateUnit(Player(0),'hfoo',0,0,0)
    call IssuePointOrder(EL_MAN,"move",0,1000)
    call TimerStart(CreateTimer(),5,false,function SLAPCHOP)
    call TrackUnitMovement(EL_MAN)
endfunction
endscope



Anyway, once again:



¡USE AIDS STRUCTS!
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
damit. But way aids structs and not normal structs that can be destroyed manualy?
 

Azlier

Old World Ghost
Reaction score
461
I'm pretty sure the AIDS_onDestroy method is called when the unit is removed from the game somehow. I don't use AIDS, so I don't know.
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
yea but with aids i cant call destroy struct bla bla and so when i want to remove a unit from the system there will still be struct for him that i dont want but normal structs i can call destroy struct.
 

T.s.e

Wish I was old and a little sentimental
Reaction score
133
[ljass] call TriggerRegisterTimerEventPeriodic( TrackMovement, PeriodicMovementCheck )[/ljass]
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
facepalmhy2.gif
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
how is that a face palm??????? It works and thats a variable thats set in the globals block.
 

Azlier

Old World Ghost
Reaction score
461
Because it's total failure. You should have just used a timer.
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
oh i see now whats the diffrence?? They both get the job done.
 

Jesus4Lyf

Good Idea™
Reaction score
397
yea but with aids i cant call destroy struct bla bla and so when i want to remove a unit from the system there will still be struct for him that i dont want but normal structs i can call destroy struct.
AIDS structs are automatically created and destroyed. They never are leaked - they can't be (unless you abuse locks, different point).

Read the documentation. You seem capable of understanding them... I think you might like it.

Here's an example of how to attach a bunch of reals to a unit, having them always start at 0 for every unit:
JASS:
struct MyData extends array
    //! runtextmacro AIDS()
    real a
    real b
    
    real xWhenUnitSpawned
    real yWhenUnitSpawned
    
    private method AIDS_onCreate takes nothing returns nothing
        set this.a=0
        set this.b=0
        
        set this.xWhenUnitSpawned=GetUnitX(this.unit) // "this.unit" comes for free with AIDS structs.
        set this.yWhenUnitSpawned=GetUnitY(this.unit) // It is always the unit the struct was created for.
    endmethod
endstruct

AIDS structs are automatically created for every unit when the unit enters the map, and destroyed when they leave.
So AIDS_onCreate is called when they enter, and AIDS_onDestroy when they leave.

This actually is extremely efficient.
It actually does not allocate structs. It uses the unit id as the struct id.

Anyway, I'd say just use AIDS_onCreate to reset your data, and treat it like a random way to store a bunch of values for a unit elsewise.

To access the values, use:
JASS:
local MyData d=MyData[someUnit]
set d.a=d.a+someValue

No create/destroy required. Think of it like the unit is the struct. :)
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
Okay ill see what i can come up with i just dont really understand all the struct functions but ill try.
Well Okay i cans see what im doing wrong here??
JASS:
library TUMS initializer Init requires AIDS
    
    struct TUMS extends array
        //! runtextmacro AIDS()
        
        real ox
        real oy
        real nx
        real ny
        real Distance
        
        method AIDS_onCreate takes nothing returns nothing
            set this.ox = 0.
            set this.oy = 0.
            set this.nx = 0.
            set this.ny = 0.
            set this.Distance = 0.
        endmethod
        
        method AIDS_onDestroy takes nothing returns nothing
        endmethod
    endstruct
        
    globals
        private constant real PeriodicMovementCheck = .03125
        private real x
        private real y
        private real Squareroot
        private unit P
        private timer Ti
        private group TrackUnits = CreateGroup()
    endglobals

    function TrackUnitMovement takes unit whichUnit returns nothing
        if IsUnitInGroup( whichUnit, TrackUnits) == false then
            call GroupAddUnit( TrackUnits, whichUnit)
        endif
    endfunction

    function StopTrackingUnit takes unit whichUnit returns nothing
        if IsUnitInGroup( whichUnit, TrackUnits) == true then
            call GroupRemoveUnit( TrackUnits, whichUnit)
        endif
    endfunction
   
    function IsUnitMoving takes unit whichUnit returns boolean
        local TUMS d = TUMS[whichUnit]
        local real dx = d.nx - d.ox
        local real dy = d.ny - d.oy
        if SquareRoot(dx * dx + dy * dy) > 0 then
            return true
        else
            return false
        endif
    endfunction
    
    function GetUnitMovingAngle takes unit whichUnit returns real
        local TUMS d = TUMS[whichUnit]
        return 57.2958 * (Atan2(d.ny - d.oy, d.nx - d.ox))
    endfunction
    
    function GetUnitMovingDistance takes unit whichUnit returns real
        local TUMS d = TUMS[whichUnit]
        return d.Distance
    endfunction
    
    function ResetUnitDistance takes unit whichUnit returns nothing
        local TUMS d = TUMS[whichUnit]
        set d.Distance = 0
    endfunction
    
    private function TUMS_Group takes nothing returns nothing
        local TUMS d = TUMS[GetEnumUnit()]
        local real dx
        local real dy
        set P = GetEnumUnit()
        set x = GetUnitX(P)
        set y = GetUnitY(P)
        set dx = x - d.nx
        set dy = y - d.ny
        set Squareroot = SquareRoot(dx * dx + dy * dy)
        if IsUnitType (P, UNIT_TYPE_DEAD) == false then
            if Squareroot <= 35 then
                set d.Distance = d.Distance + Squareroot
            endif
            set d.ox = d.nx
            set d.oy = d.ny
            set d.nx = x
            set d.ny = y
        else
            call StopTrackingUnit(P)
        endif
    endfunction
    
    private function TUMS_Actions takes nothing returns nothing
        call ForGroup( TrackUnits, function TUMS_Group )
    endfunction
    
    private function Init takes nothing returns nothing
        call TimerStart( Ti, PeriodicMovementCheck, true, function TUMS_Actions)
    endfunction
endlibrary
 

Jesus4Lyf

Good Idea™
Reaction score
397
Yes.
JASS:
    private function Init takes nothing returns nothing
        call TimerStart( Ti, PeriodicMovementCheck, true, function TUMS_Actions)
    endfunction

Thread termination for using uninitialised global [LJASS]Ti[/LJASS].
Rofl.

See
JASS:
private timer Ti

Missing [LJASS]=CreateTimer()[/LJASS].
But really, you should just do:
JASS:
call TimerStart( CreateTimer() /* Nice, ey? */, PeriodicMovementCheck, true, function TUMS_Actions)

:)

Keep up the good work.

PS.
JASS:
        method AIDS_onDestroy takes nothing returns nothing
        endmethod

Completely optional. If it is empty, you may exclude it. :)

PPS. Actually, this whole thing would be brilliant as an AIDS/T32 struct. I'll leave that for now though, getting it working is the first thing. :thup:
AIDS/T32 structs compile to unit indexes being used as nodes for a linked list, and the fastest iteration script ever being added to a timer as a single condition. Then, instead of add/remove from group, you can use TUMS[unit].startPeriodic(), and when I finally get T32X out, TUMS[unit].stopPeriodic(). :)

Probably best to wait for T32X module before doing that, though (if you'd like to).
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
thnks i always forget about the createtimer and inithashtables or creategroup the i try to find the error in the functions not global block.
 

Jesus4Lyf

Good Idea™
Reaction score
397
JASS:
    function GetUnitMovingDistance takes unit whichUnit returns real
        local TUMS d = TUMS[whichUnit]
        return d.Distance
    endfunction
    
    function ResetUnitDistance takes unit whichUnit returns nothing
        local TUMS d = TUMS[whichUnit]
        set d.Distance = 0
    endfunction

-->
JASS:
    function GetUnitMovingDistance takes unit whichUnit returns real
        return TUMS[whichUnit].Distance
    endfunction
    
    function ResetUnitDistance takes unit whichUnit returns nothing
        set TUMS[whichUnit].Distance = 0
    endfunction

And [LJASS]IsUnitInGroup[/LJASS] does not need to be compared to true.
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
oh okay ill do that but im writing exams in two weeks time so i can maby fix that today but i think i will have to learn so i wouldnt be able to fix and release it. Only after 4 weeks when the exams are finished.
 

Jesus4Lyf

Good Idea™
Reaction score
397
By the way, same comment as here, these trackers would be really cool if there were multiple instances per unit possible with a nice struct interface.

For something that creates instances with a user-controlled lifetime, I can't imagine a more appropriate interface than a struct. :)

I'd approve it.
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
as i said my exams are here and i had computees yesterday in school to update the stuff but unfortunally the next update has to wait for the exams to finish. Is it okay if they(track movement and damage counter) stay here in T&R.
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
btw why do you want them to be multi instance per unit? If he moves he moves and if he doesnt he doesnt and the units distance can only be so far not two diffrent distances.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      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