• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Bounce Pushback Effect

Status
Not open for further replies.
Level 10
Joined
Aug 25, 2004
Messages
473
spend more then 3 hours making such trigger in GUI and all i could come up with was givind a unit an aura and if under the effect of the buff the unit will be randomly pushed to a side. But that would include that i have to check every 0.5 sec of the gametime if any of ALL units in playable map area has a sertain buff. And that could cause some lagg, even without memory leaks, when combined with other time triggers.
So i wonder if there anyone who could help me making such a trigger in JASS.
(the problem in gui is that it doesnt see custom variables in EVENT editor)
Should look something like this:
If a unit, classification mechanicle come in range 100 of an other organicle (not a building, not mechanicle) unit and the triggering unit speed current is higher than 200 then take that victem, take 20 damage, play death animation, make victem face the mech unit and Move the victem instantly of its position offset by 9.00 towards Facing itself - 180.00 degrees (move it few times to create a kickback effect)
So that is about it, it would realy mean world to me if someone helps
 
Level 5
Joined
May 22, 2006
Messages
150
I am on it.
The main function is already done. Pretty easy work.

What may take some more time, is to write my own function to get the point, to which your "victim" shall be pushed.
I have to get a location out of an angle, it's current location and a range...

My way only works for the first quarter of a two dimensional matrix yet...

c = angle between "victim" and "roller"
x1 = X-coordinate of "victim"
y1 = Y-coordinate of "victim"
x2 = X-coordinate of the new point
y2 = Y-coordinate of the new point
s = range between old and new location

x2 = (tan(c) + x1) * s
y2 = y1 (+ or -) square root(y1² + s² - ((tan(c) + x1) * s - x1)² - y1²)

... As it can easily be seen, something is wrong with y2 - there should not be two possiblities.
 
Level 5
Joined
May 22, 2006
Messages
150
Got it in another, much easier way:

xA = x-coordinate of the "roller"
yA = y-coordinate of the "roller"
xB = x-coordinate of the "victim"
yB = y-coordinate of the "victim"
s = range to push the "victim" back at once

x = s * (xB - xA) / square root((xA - xB)² + (yA - yB)²)
y = s * (yB - yA) / square root((xA - xB)² + (yA - yB)²)

Tomorrow the whole thing will be done.

Postscript:

Here is the "prototype". It is still untested.

Create a trigger, name it "Ueberfahrt", convert it into custom code.
Delete the first two lines of code and copy this onto their former place:

JASS:
function Trig_Ueberfahrt_Einheitenfilter takes nothing returns boolean
  return IsUnitType(GetFilterUnit(),UNIT_TYPE_GROUND) and IsUnitType(GetFilterUnit(),UNIT_TYPE_MECHANICAL)
endfunction

function Trig_Ueberfahrt_Zielsuche_Einheitenfilter takes nothing returns boolean
  return IsUnitType(GetFilterUnit(),UNIT_TYPE_GROUND) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_MECHANICAL) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)
endfunction

function Trig_Ueberfahrt_Zielsuche_Berechnung takes real xA,real yA,real xB,real yB,real strecke returns location
  local real x = strecke * (xB-xA) / SquareRoot((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB))
  local real y = strecke * (yB-yA) / SquareRoot((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB))
  return Location(x,y)
endfunction

function Trig_Ueberfahrt_Zielsuche takes nothing returns nothing
  local filterfunc infanterie = Filter(function Trig_Ueberfahrt_Zielsuche_Einheitenfilter)
  local group ziele = CreateGroup()
  local real zeit
  local timer ruhezeit = CreateTimer()
  local unit fahrzeug = GetTriggerUnit()
  local unit ziel
  loop
    set zeit = 0
    if GetUnitCurrentOrder(fahrzeug) != OrderId("stop") then
      call GroupEnumUnitsInRange(ziele,GetUnitX(fahrzeug),GetUnitY(fahrzeug),100,infanterie)
      loop
        set ziel = FirstOfGroup(ziele)
        call GroupRemoveUnit(ziele,ziel)
        call SetUnitExploded(ziel,true)
        call SetUnitState(ziel,UNIT_STATE_LIFE,RMaxBJ(0,GetUnitState(ziel,UNIT_STATE_LIFE) - 20))
        if GetUnitState(ziel,UNIT_STATE_LIFE) <= 0 then
          call KillUnit(ziel)
        endif
        call SetUnitFacing(ziel,bj_RADTODEG * Atan2(GetUnitY(ziel) - GetUnitY(fahrzeug),GetUnitX(ziel) - GetUnitX(fahrzeug)))
        call SetUnitAnimation(ziel,"Death")
        call TimerStart(ruhezeit,1,false,null)
        loop
          set zeit = zeit + 0.2
          call SetUnitPositionLoc(ziel,Trig_Ueberfahrt_Zielsuche_Berechnung(GetUnitX(fahrzeug),GetUnitY(fahrzeug),GetUnitX(ziel),GetUnitY(ziel),5))
          call TriggerSleepAction(0.01)
          exitwhen TimerGetRemaining(ruhezeit) <= 1 - zeit
        endloop
        call SetUnitAnimation(ziel,"Stand")
        call SetUnitExploded(ziel,false)
        exitwhen FirstOfGroup(ziele) == null
      endloop
    endif
    call TimerStart(ruhezeit,0.5,false,null)
    loop
      call TriggerSleepAction(0.01)
      exitwhen TimerGetRemaining(ruhezeit) <= 0
    endloop
    exitwhen GetUnitState(fahrzeug,UNIT_STATE_LIFE) <= 0
  endloop
  call DestroyFilter(infanterie)
  call DestroyGroup(ziele)
  call DestroyTimer(ruhezeit)
  set infanterie = null
  set ziele = null
  set ruhezeit = null
endfunction

Finally, delete everything between these lines:
JASS:
function InitTrig_Ueberfahrt takes nothing returns nothing
JASS:
endfunction
Then, copy this into this space:

JASS:
  set gg_trg_Ueberfahrt = CreateTrigger()
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(0),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(1),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(2),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(3),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(4),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(5),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(6),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(7),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(8),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(9),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(10),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(11),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
//neutral players - let them out for an advantage of speed
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(12),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(13),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(14),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(15),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
  call TriggerAddAction(gg_trg_Ueberfahrt,function Trig_Ueberfahrt_Zielsuche)

I am sorry for the german names, but I am just a little short on time.
If appropriated, I will change that next day.

... And if an error occurs, do not hesitate to tell me.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
JASS:
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(0),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(1),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(2),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(3),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(4),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(5),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(6),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(7),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(8),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(9),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(10),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(11),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
//neutral players - let them out for an advantage of speed
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(12),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(13),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(14),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(15),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)

replace all that code with
JASS:
call TriggerRegisterAnyUnitEventBJ( gg_trg_Ueberfahrt, EVENT_PLAYER_UNIT_TRAIN_FINISH )

though, if you hate BJs, even though this one is good, this is the best solution ( assuming u need fahrzeug use this one )

JASS:
local integer i = 0
loop
    exitwhen i == 16
    call TriggerRegisterPlayerUnitEvent(gg_trg_Ueberfahrt,Player(i),EVENT_PLAYER_UNIT_TRAIN_FINISH,fahrzeug)
    set i = i + 1
endloop
 
Level 5
Joined
May 22, 2006
Messages
150
However you want it. ^^
It is just a question of being formal.

Okay, some little faults have been cleared.
This code is tested and works.

JASS:
function Trig_DriveOver_Unitfilter takes nothing returns boolean
  return IsUnitType(GetFilterUnit(),UNIT_TYPE_GROUND) and IsUnitType(GetFilterUnit(),UNIT_TYPE_MECHANICAL)
endfunction

function Trig_DriveOver_SearchForTarget_Unitfilter takes nothing returns boolean
  return IsUnitType(GetFilterUnit(),UNIT_TYPE_GROUND) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_MECHANICAL) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)
endfunction

function Trig_DriveOver_SearchForTarget takes unit fahrzeug returns nothing
  local filterfunc infantry = Filter(function Trig_DriveOver_SearchForTarget_Unitfilter)
  local group targets = CreateGroup()
  local timer sleepingTime = CreateTimer()
  local real xV
  local real yV
  local real xT
  local real yT
  local unit vessel = GetTriggerUnit()
  local unit target
  loop
    if GetUnitCurrentOrder(vessel) != OrderId("stop") then
      call GroupEnumUnitsInRange(targets,GetUnitX(vessel),GetUnitY(vessel),150,infantry)
      loop
        set ziel = FirstOfGroup(targets)
        exitwhen ziel == null
        call GroupRemoveUnit(targets,target)
        call SetUnitExploded(target,true)
        call SetUnitState(target,UNIT_STATE_LIFE,RMaxBJ(0,GetUnitState(target,UNIT_STATE_LIFE) - 20))
        if GetUnitState(target,UNIT_STATE_LIFE) <= 0 then
          call KillUnit(target)
        endif
        set xV = GetUnitX(vessel)
        set yV = GetUnitY(vessel)
        call SetUnitFacing(target,bj_RADTODEG * Atan2(GetUnitY(target) - yV,GetUnitX(target) - xV))
        call SetUnitAnimation(target,"Death")
        call TimerStart(sleepingTime,2,false,null)
        loop
          set xT = GetUnitX(target)
          set yT = GetUnitY(target)
          call SetUnitPosition(ziel,xT + 7.5 * (xT - xV) / SquareRoot((xV - xT) * (xV - xT) + (yV - yT) * (yV - yT)),yT + 7.5 * (yT - yV) / SquareRoot((xV - xT) * (xV - xT) + (yV - yT) * (yV - yT)))
          call TriggerSleepAction(0.01)
          exitwhen TimerGetRemaining(sleepingTime) <= 0
        endloop
        call SetUnitAnimation(target,"Stand")
        call SetUnitExploded(target,false)
        exitwhen FirstOfGroup(targets) == null
      endloop
      set target = null
    endif
    call TimerStart(sleepingTime,0.5,false,null)
    loop
      call TriggerSleepAction(0.01)
      exitwhen TimerGetRemaining(sleepingTime) <= 0
    endloop
    exitwhen GetUnitState(vessel,UNIT_STATE_LIFE) <= 0
  endloop
  call DestroyFilter(infantry)
  call DestroyGroup(targets)
  call DestroyTimer(sleepingTime)
  set infantry = null
  set targets = null
  set sleepingTime = null
endfunction

JASS:
  local filterfunc vessel = Filter(function Trig_DriveOver_Unitfilter)
 set gg_trg_DriveOver = CreateTrigger() 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(0),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel)
  call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(1),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(2),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(3),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(4),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(5),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(6),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(7),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(8),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(9),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(10),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(11),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
//neutral players - let them out for an advantage of speed 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(12),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(13),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(14),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(15),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel) 
call TriggerAddAction(gg_trg_DriveOver,function Trig_DriveOver_SearchForTarget)
  set vessel = null

OR

JASS:
  local integer counter = 0
  local filterfunc vessel = Filter(function Trig_DriveOver_Unitfilter)
  set gg_trg_DriveOver = CreateTrigger()
  loop
    call TriggerRegisterPlayerUnitEvent(gg_trg_DriveOver,Player(counter),EVENT_PLAYER_UNIT_TRAIN_FINISH,vessel)
    set counter = counter + 1
    exitwhen counter >= 16
  endloop
  call TriggerAddAction(gg_trg_DriveOver,function Trig_DriveOver_SearchForTarget)
  set vessel = null

Preparation for usage remains the same - only your trigger should now be named "DriveOver" for identification purposes.
 
Level 5
Joined
May 22, 2006
Messages
150
Indeed. That was annoying and I became tired of thinking about working around.
So I used this way.

... And there is something else about "ForGroup", which is as serious:
It does not wait until the code is done for each group member.
So, the calling function's execution goes on, while the "ForGroup"-function is not finished.

Mostly, that does not cause problems, but sometimes...
I found such a case, while writing an automatical mating/breeding-script.

postscript:
Argh! UnMi, you were a little too fast in answering. ^^

... And by the way, there is still something wrong.
Just because I altered my code while testing, as I did not want to produce the unit before.

This
JASS:
local unit vessel = GetTriggerUnit()
has to be replaced with this
JASS:
local unit vessel = GetTrainedUnit()

The variable to get is vessel.
Sure, I could get it via "GetTrainedUnit()".
But what if two or three times the if-structure is skipped and while these 0.15 seconds passed another unit has been produced?
 
Level 5
Joined
Feb 16, 2006
Messages
151
Well, yes, but normally you won't need any other values expect for the unit itself while group looping.
The point is to use ForGroup as much as possible, but if you need a lot extern variables, you will have to stick to group looping.
 
Level 5
Joined
May 22, 2006
Messages
150
We are not in GUI, the unit is saved in the local variable and won't be changed unless you change it.
And as we are not in GUI, will this local - this LOCAL variable be aviable in the called function?
No.

Ether I would have to use a global or the game cache to carry it's value over.
The global forbids the whole thing to be multiinstanceable, the cache...

Well, I would have to write an algorithm, which creates a unique key for each time the function is called and the creation,
storage and recycling of used keys would obviously take any speed bonus, I won by avoiding the iteration.
 
Level 5
Joined
May 22, 2006
Messages
150
I am sure, we can accept, that nether the one nor the other way is ideal. ^^
But vexorian wrote something about a "location stack", which may be a nice alternative...
Unfortunally I have no idea, how it works. ^^

I wrote my own stack structures in Java, but in Jass, I thought, it is impossible to define own objects...
And the functions he used were never seen by me before.
 
Level 5
Joined
May 22, 2006
Messages
150
Oh, well... Hard to explain as Jass is no object-based language...

An "object" is any kind of virtual instance of a definition...
Of course, this explanation tells you nothing. ^^

Let me show some examples:
In "common.j", there are "types" listed in the first few lines.
Take the type "filterfunc".
When calling the function "Filter(code)", this function creates an object.
The filter exists virtually and is handled as you would do with... A net or something similar in Reality.
This special created object has it's own place in memory - that is, why you have to destroy it after usage.

... Now, the filter is an object of type "filterfunc".
This type defines everything to do with an instance of it - you cannot insert a unit into a function, which requires a filter as argument.

Now, in a language, which is not just some cheap script language for a programm, you may define your very own custom type.
Own name, own signature (name + parameters), own attributes...
In an object-based language like Java own functions, which are called by the object rather than on an object as it happens in Jass.

... Just I worry to be not able to explain it properly.
In my mother tongue itself, I am still pretty bad in making somebody understand, what I mean. ^^

However, what I wanted to say is that I have no idea, how this "location stack" may be realized.
 
Level 5
Joined
May 22, 2006
Messages
150
Is one of you two registered to WC3Campaigns?
This one may simply ask Vexorian about how it works...
Or at least, how the function bodies of "GetLocationX_Unit" and "GetLocation_Loc()" look like - then we may figure it out ourselves (or even use it without knowing, how it works ^^).
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
here is the code, i just looked it up, and basically you are attaching data to the coords of the location. They run about 6.5 times faster, but can only store 2 values, so the "Stack" part comes from the fact you use the Y-Coord of a loc to store another loc, and so on, and so on :lol:

anyways, credits to vex for the script, and that B thing was some function he wrote to show how they work. ( i am soooo tempted to replace all my cache stuff with these if i work out how to pass them between funcs :p )

JASS:
function CS_i2r takes integer i returns real
    return i
    return 0.
endfunction

function CS_h2r takes handle h returns real
    return h
    return 0.
endfunction

function Stack_First takes location l returns location
    return GetLocationX(l)
    return null
endfunction

function Stack_Next takes location l returns location
    return GetLocationY(l)
    return null
endfunction


function Stack_Empty takes location s returns boolean
    set udg_csloc=Stack_First(s)
    return udg_csloc==null
endfunction

function Stack_Push takes location s, real i returns nothing
 local location F=Stack_First(s)
    if (F==null) then
        set F=Location(i,CS_h2r(null))
    else
        set F=Location(i,CS_h2r(F))
    endif
    call MoveLocation(s,CS_h2r(F),0)
 set F=null
endfunction

function Stack_Pop takes location s returns real
 local location F=Stack_First(s)
 local location q
 local real i
    if (F==null) then
        return 0
    endif
    set i=GetLocationX(F)
    set q=Stack_Next(F)
    call RemoveLocation(F)
    call MoveLocation(s,CS_h2r(q),0)
 set F=null
 set q=null
 return i
endfunction

function NewStack takes nothing returns location
   return Location(CS_h2r(null),0)
endfunction

function Stack_Destroy takes location s returns nothing
 local location t=Stack_First(s)
 local location q
 
   loop
       exitwhen (t==null)
       set q=t
       set t=Stack_Next(t)
       call RemoveLocation(q)
   endloop
   call RemoveLocation(s)
 set t=null
 set q=null
endfunction

function B takes nothing returns nothing
 local location s=NewStack()
 local integer n=100
 local integer i=0
 local real x

    loop
        exitwhen i>=n
        call Stack_Push(s,3.3)
        set i=i+1
    endloop
 set i=0
    loop
        exitwhen Stack_Empty(s)
        call Stack_Pop(s)
        set i=i+1
    endloop
    call Stack_Destroy(s)
    if (i>=n) then
        set udg_log=udg_log+1
    endif
 set s=null
endfunction
 
Level 5
Joined
May 22, 2006
Messages
150
Hell, that is mad - mad and brilliant!

Mad it is, as the whole thing bases on a formal mistake done by Blizzard coders,
brilliant it is, as it should work (and seems to have worked)!
 
Level 5
Joined
May 9, 2006
Messages
162
I had somewhere a function that adds to all units having an aura antimagic ability. With no leaks and rather fast. I'll rework it, and show there.
 
Level 5
Joined
May 9, 2006
Messages
162
User data is very useful in some in-fly situations. For example, you need to store to a dummy target unit of ability (to buff it, fe).
 
Level 5
Joined
May 22, 2006
Messages
150
Oh? I cannot see a game cache in the whole script...
Of course, that must not mean anything.
Being blind is kind of hobby of mine, while looking over code. ^^

postscript:

@PurplePoot:
Check out these values:
-2147483648 as minimum,
2147483647 as maximum.
 
Level 5
Joined
May 22, 2006
Messages
150
... A "stack"'s definition includes, that more than one value can be stored.
In fact, it bases on this. To be sure, as long as there are not two or more values stored, the structure is no stack but "has a potential to grow into a stack".

Or did you mean the "UnitUserData"?
 
Status
Not open for further replies.
Top