| 01-04-2007, 01:46 PM | #1 |
Spell: Ice Path Creates a path of Ice, gradually from caster towards target spell location, damaging units and freezing those that get caught. I had it working fine at first. But then I noticed the path only went as far as the spell was cast. So I tried fiddling with it to always continue on to its maximum distance. This works fine: JASS:
local unit c = GetTriggerUnit()
local location l = GetSpellTargetLoc()
local real x1 = GetUnitX(c)
local real y1 = GetUnitY(c)
local real x2 = GetLocationX(l)
local real y2 = GetLocationY(l)
local integer lvl = GetUnitAbilityLevel(c, Ice_Wave_AbilId())
local real angle = AngleBetweenPoints(Location(x2, y2), Location(x1, y1))
local real distance = DistanceBetweenPoints(Location(x1, y1), Location(x2, y2))
This does NOT work JASS:
local unit c = GetTriggerUnit()
local location f = GetSpellTargetLoc()
local real x1 = GetUnitX(c)
local real y1 = GetUnitY(c)
local real a1 = GetLocationX(f)
local real b1 = GetLocationY(f)
local integer lvl = GetUnitAbilityLevel(c, Ice_Wave_AbilId())
local real distance = Ice_Wave_Distance(lvl)
local real angle = AngleBetweenPoints(Location(a1, b1), Location(x1, y1))
local location l = PolarProjectionBJ(Location(x1, y1), distance, angle)
local real x2 = GetLocationX(l)
local real y2 = GetLocationY(l)
Here is the entire spell just incase. JASS:
//####################################################################################\\
// Spell Name: Ice Wave \\
// Spell Auth: Fulla \\
//####################################################################################\\
//################################################################\\
// \\
// Configuration Section \\
// \\
//################################################################\\
constant function Ice_Wave_AbilId takes nothing returns integer
return 'A088'
endfunction
constant function Ice_Wave_DummySlowAbilId takes nothing returns integer
return 'S001'
endfunction
constant function Ice_Wave_DummyDmgAbilId takes nothing returns integer
return 'A06J'
endfunction
constant function Ice_Wave_DummyUnitId takes nothing returns integer
return 'u001'
endfunction
constant function Ice_Wave_Distance takes integer lvl returns real
if (lvl != 5) then
return (lvl * 150) + 700.
endif
return 1600.
endfunction
//################################################################\\
// \\
// Spell Section \\
// \\
//################################################################\\
function Trig_Ice_Wave_Conditions takes nothing returns boolean
return GetSpellAbilityId() == Ice_Wave_AbilId()
endfunction
function Ice_Wave_Movement takes nothing returns nothing
local timer t = GetExpiredTimer()
local string s = GetAttachmentTable(t)
local unit d
local unit c = GetTableUnit(s,"Caster")
local real x1 = GetTableReal(s,"X1")
local real y1 = GetTableReal(s,"Y1")
local real x2 = GetTableReal(s,"X2")
local real y2 = GetTableReal(s,"Y2")
local integer lvl = GetTableInt(s,"Level")
local real angle = GetTableReal(s,"Angle")
local real distance = GetTableReal(s,"Distance")
if (distance >= 50.) then
set distance = distance -50.
else
set distance = 0
endif
set x1 = x2+distance*Cos(angle*bj_DEGTORAD)
set y1 = y2+distance*Sin(angle*bj_DEGTORAD)
set d = CreateUnit(GetOwningPlayer(c), Ice_Wave_DummyUnitId(), x1, y1, bj_UNIT_FACING)
call SetUnitX(d, x1)
call SetUnitY(d, y1)
call SetUnitAbilityLevel(d, Ice_Wave_DummyDmgAbilId(), lvl)
call UnitApplyTimedLife(d, 'BTLF', 1.)
if distance == 0 then
call PauseTimer(t)
call DestroyTimer(t)
endif
call SetTableObject(s,"Caster",c)
call SetTableReal(s,"X1",x1)
call SetTableReal(s,"Y1",y1)
call SetTableReal(s,"X2",x2)
call SetTableReal(s,"Y2",y2)
call SetTableReal(s,"Distance",distance)
endfunction
function Trig_Ice_Wave_Actions takes nothing returns nothing
local timer t = CreateTimer()
local string s = GetAttachmentTable(t)
local unit c = GetTriggerUnit()
local location f = GetSpellTargetLoc()
local real x1 = GetUnitX(c)
local real y1 = GetUnitY(c)
local real a1 = GetLocationX(f)
local real b1 = GetLocationY(f)
local integer lvl = GetUnitAbilityLevel(c, Ice_Wave_AbilId())
local real distance = Ice_Wave_Distance(lvl)
local real angle = AngleBetweenPoints(Location(a1, b1), Location(x1, y1))
local location l = PolarProjectionBJ(Location(x1, y1), distance, angle)
local real x2 = GetLocationX(l)
local real y2 = GetLocationY(l)
call SetTableObject(s,"Caster",c)
call SetTableReal(s,"X1",x1)
call SetTableReal(s,"Y1",y1)
call SetTableReal(s,"X2",x2)
call SetTableReal(s,"Y2",y2)
call SetTableInt(s,"Level",lvl)
call SetTableReal(s,"Angle",angle)
call SetTableReal(s,"Distance",distance)
call TimerStart(t,0.05,true,function Ice_Wave_Movement)
endfunction
//===========================================================================
function InitTrig_Ice_Wave takes nothing returns nothing
set gg_trg_Ice_Wave = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Ice_Wave, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Ice_Wave, Condition( function Trig_Ice_Wave_Conditions ) )
call TriggerAddAction( gg_trg_Ice_Wave, function Trig_Ice_Wave_Actions )
endfunction
thx for anyhelp. |
| 01-04-2007, 03:02 PM | #2 |
(I'll add more and more to this post) JASS:constant function Ice_Wave_Distance takes integer lvl returns real if (lvl != 5) then return (lvl * 150) + 700. endif return 1600. endfunction constant functions only returns the same value all the time. that function shouldnt be a constant. JASS:function Ice_Wave_Movement takes nothing returns nothing ... if distance == 0 then call PauseTimer(t) call DestroyTimer(t) endif call SetTableObject(s,"Caster",c) call SetTableReal(s,"X1",x1) call SetTableReal(s,"Y1",y1) call SetTableReal(s,"X2",x2) call SetTableReal(s,"Y2",y2) call SetTableReal(s,"Distance",distance) endfunction dont store anything on the timers id after you've destroyed it, set those store lines before the if statement or if you dont want to compute it when it isn't needed (on the last run), put it in the else actions to that if statement. set all your local handles to null at the end of the function (or when you're done with them) Storing the x2 and y2 real when you haven't even made any changes on them is useless. infact, you dont need those at all since you already have the startloc and the angle of the spell. Storing the distance is also useless since you can get it inside the timer callback instead. ehum, right, now i see why you store the distance. do save it. JASS:... if (distance >= 50.) then set distance = distance -50. else set distance = 0 endif ... if distance == 0 then call PauseTimer(t) call DestroyTimer(t) endif ... change to: JASS:... if distance >= 50. then set distance = distance -50. endif ... if distance <= 0 then call PauseTimer(t) call DestroyTimer(t) endif ... Anyways, to your real problem (if those things didnt solve it) what happens? how doesnt it work? is all units spawned at the targetpoint? is all units spawned in the middle? etc etc |
| 01-04-2007, 05:09 PM | #4 | |
well, thats becouse thats how you do it. you get the angle between the target point and the caster point.' the distance is postitive, which means it will start outside and walk inwards. to change this the easy way, you can calculate the polarprojectile without the x2 and y2: set x = x + 50. * Cos(angle*bj_DEGTORAD) set y = y + 50. * Sin(angle*bj_DEGTORAD) and then restore them. if you do it like that, then you can remove the x2 and y2 since they have no purpose anymore. you still use the dist = dist - 50 to know when to break the loop. constant functions will always return the same value as it did when first run. thats why you should make it a regular function. if you don't feel like doing it yourself, here's a rewritten version. partly optimized. i haven't checked it for any kind of error.
|
| 01-04-2007, 10:52 PM | #5 |
Constant functions do not always return the same thing they captured at first run. If it was that way the whole JESP standard wouldn't work. I wouldn't recommend posting things that are totally untrue. |
| 01-04-2007, 10:57 PM | #6 |
thx oNdizZ Works perfectly now. |
| 01-05-2007, 11:07 AM | #7 | |
Quote:
noted. |
