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
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.
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:
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:
function InitTrig_Ueberfahrt takes nothing returns nothing
endfunction
Then, copy this into this space:
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.
though, if you hate BJs, even though this one is good, this is the best solution ( assuming u need fahrzeug use this one )
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
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
local unit vessel = GetTriggerUnit()
has to be replaced with this
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?
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.
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.