Rheiko
Spell Reviewer
- Joined
- Aug 27, 2013
- Messages
- 4,122
I'm working on a spell that fires a projectile that travels for X distance at target location's angle, if it hits an obstacle on its way (cliff and units), it should be reflected with the correct angle.
I've been following this tutorial so far (Deflection Angle) although I don't get the angle of reflection correctly still for cliffs.
Also, I'm pretty bad at math.
This is the code:
It's not finished yet as I want to deal with the angle of reflection first before the other things. But if there's any feedback regarding the code aside from the main problem, greatly appreciated, as this is my first project using plain jass. Thanks in advance.
Edit: Forgot to mention, I'm using purgeandfire's walkability system to do pathing check.
I've been following this tutorial so far (Deflection Angle) although I don't get the angle of reflection correctly still for cliffs.
Also, I'm pretty bad at math.
This is the code:
JASS:
function GetDeflectionAngle takes real mx, real my, real tx, real ty, real mface returns real
return 2 * Atan2(ty - my, tx - mx) + bj_PI - mface
endfunction
function FLRE_Loop takes nothing returns nothing
//Locals
local integer Node = 0
local integer order
local real x
local real x2
local real y
local real y2
local real Angle
local real Angle2
local real tempCos
local real tempSin
loop
set Node = udg_FLRE_NextNode[Node]
exitwhen Node == 0
set order = GetUnitCurrentOrder(udg_FLRE_Caster[Node])
if (order == OrderId(FLRE_OrderId())) then
if (udg_FLRE_Interval[Node] < FLRE_DurationBase(udg_FLRE_Level[Node])) then
set udg_FLRE_Counter[Node] = udg_FLRE_Counter[Node] + FLRE_TimerSpeed()
if (udg_FLRE_Counter[Node] >= 1) then
set x = GetUnitX(udg_FLRE_Dummy[Node])
set y = GetUnitY(udg_FLRE_Dummy[Node])
set udg_FLRE_Interval[Node] = udg_FLRE_Interval[Node] + 1
set udg_FLRE_Counter[Node] = 0.00
set udg_FLRE_CurrentSize[Node] = udg_FLRE_CurrentSize[Node] + 0.1
call SetUnitScale( udg_FLRE_Dummy[Node], udg_FLRE_CurrentSize[Node], udg_FLRE_CurrentSize[Node], udg_FLRE_CurrentSize[Node] )
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl", x, y))
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl", x, y))
set udg_FLRE_BounceDmg[Node] = udg_FLRE_BounceDmg[Node] + FLRE_OnHitDamageBase(udg_FLRE_Level[Node])
endif
endif
else
set x = GetUnitX(udg_FLRE_Dummy[Node])
set y = GetUnitY(udg_FLRE_Dummy[Node])
if (udg_FLRE_ReachedDistance[Node] < udg_FLRE_MaxDistance[Node]) then
set x2 = x + udg_FLRE_CurrentSpeed[Node] * Cos(udg_FLRE_CurrentAngle[Node])
set y2 = y + udg_FLRE_CurrentSpeed[Node] * Sin(udg_FLRE_CurrentAngle[Node])
set udg_CP_Point = Location(x2, y2)
call TriggerExecute( gg_trg_Check_Walkability )
if not (udg_CP_PointIsWalkable) then
set udg_FLRE_ReachedDistance[Node] = udg_FLRE_ReachedDistance[Node] + udg_FLRE_CurrentSpeed[Node]
set udg_FLRE_CurrentAngle[Node] = GetDeflectionAngle(y2, y, x2, x, (udg_FLRE_CurrentAngle[Node]))
set x2 = x + udg_FLRE_CurrentSpeed[Node] * Cos(udg_FLRE_CurrentAngle[Node])
set y2 = y + udg_FLRE_CurrentSpeed[Node] * Sin(udg_FLRE_CurrentAngle[Node])
call BJDebugMsg("Found unpathable!")
call BJDebugMsg("NewAngle: " + R2S(udg_FLRE_CurrentAngle[Node] * bj_RADTODEG))
endif
// Move the projectile
call SetUnitX(udg_FLRE_Dummy[Node], x2)
call SetUnitY(udg_FLRE_Dummy[Node], y2)
set udg_FLRE_ReachedDistance[Node] = udg_FLRE_ReachedDistance[Node] + udg_FLRE_CurrentSpeed[Node]
call RemoveLocation(udg_CP_Point)
else
call KillUnit(udg_FLRE_Dummy[Node])
endif
endif
endloop
endfunction
function FLRE_Start takes nothing returns boolean
local integer SpellId = GetSpellAbilityId()
local integer Node
local real x1
local real x2
local real x3
local real y1
local real y2
local real y3
if ( SpellId == FLRE_AbilityId() ) then
// Set up Node
if (udg_FLRE_RecycledSize == 0) then
set udg_FLRE_MaxIndex = udg_FLRE_MaxIndex + 1
set Node = udg_FLRE_MaxIndex
else
set udg_FLRE_RecycledSize = udg_FLRE_RecycledSize - 1
set Node = udg_FLRE_RecycledStack[udg_FLRE_RecycledSize]
endif
set udg_FLRE_NextNode[Node] = 0
set udg_FLRE_NextNode[udg_FLRE_PrevNode[0]] = Node
set udg_FLRE_PrevNode[Node] = udg_FLRE_PrevNode[0]
set udg_FLRE_PrevNode[0] = Node
// Set up Ability Data
set udg_FLRE_Caster[Node] = GetTriggerUnit()
set x1 = GetUnitX(udg_FLRE_Caster[Node])
set y1 = GetUnitY(udg_FLRE_Caster[Node])
set x2 = GetSpellTargetX()
set y2 = GetSpellTargetY()
set udg_FLRE_CurrentAngle[Node] = Atan2((y2-y1), (x2-x1))
set udg_FLRE_Owner[Node] = GetTriggerPlayer()
set udg_FLRE_Level[Node] = GetUnitAbilityLevel(udg_FLRE_Caster[Node], FLRE_AbilityId())
set udg_FLRE_Duration[Node] = FLRE_DurationBase(udg_FLRE_Level[Node])
set udg_FLRE_MissileAoe[Node] = FLRE_MissileAoeBase(udg_FLRE_Level[Node])
set udg_FLRE_FinalAoe[Node] = FLRE_FinalAoeBase(udg_FLRE_Level[Node])
set udg_FLRE_MaxDistance[Node] = FLRE_MaxDistanceBase(udg_FLRE_Level[Node])
set udg_FLRE_Speed[Node] = FLRE_SpeedBase(udg_FLRE_Level[Node])
set udg_FLRE_SpeedFactor[Node] = FLRE_SpeedFactorBase(udg_FLRE_Level[Node])
set udg_FLRE_MaxBounce[Node] = FLRE_MaxBounceBase(udg_FLRE_Level[Node])
set udg_FLRE_BounceDmg[Node] = FLRE_InitialDamage(udg_FLRE_Level[Node])
set udg_FLRE_Bounce[Node] = 0
set udg_FLRE_Interval[Node] = 0
set udg_FLRE_ReachedDistance[Node] = 0.
set udg_FLRE_Counter[Node] = 0.00
set udg_FLRE_CurrentSize[Node] = 1.
set udg_FLRE_CurrentSpeed[Node] = udg_FLRE_Speed[Node] * FLRE_TimerSpeed()
call BJDebugMsg("CurrentAngle: " + R2S(udg_FLRE_CurrentAngle[Node] * bj_RADTODEG))
// Create dummy unit as projectile
set x3 = x1 + FLRE_InitDistance() * Cos(udg_FLRE_CurrentAngle[Node])
set y3 = y1 + FLRE_InitDistance() * Sin(udg_FLRE_CurrentAngle[Node])
set udg_FLRE_Dummy[Node] = CreateUnit(udg_FLRE_Owner[Node], FLRE_DummyUnit(), x3, y3, udg_FLRE_CurrentAngle[Node] * bj_RADTODEG)
call SetUnitScale( udg_FLRE_Dummy[Node], udg_FLRE_CurrentSize[Node], udg_FLRE_CurrentSize[Node], udg_FLRE_CurrentSize[Node] )
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl", x3, y3))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl", x3, y3))
// Start timer if this is the only instance
if (udg_FLRE_PrevNode[Node] == 0) then
call TimerStart(udg_FLRE_Timer, FLRE_TimerSpeed(), true, function FLRE_Loop)
endif
endif
return false
endfunction
function Trig_Flame_Rebound_Actions takes nothing returns nothing
endfunction
//===========================================================================
function InitTrig_Flame_Rebound takes nothing returns nothing
local trigger FLRE_Trigger = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( FLRE_Trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( FLRE_Trigger, Condition( function FLRE_Start ) )
set udg_FLRE_DummyCaster = CreateUnit(FLRE_DummyOwner(), FLRE_DummyCaster(), 0., 0., 0.)
call UnitAddAbility(udg_FLRE_DummyCaster, FLRE_DummyAbility())
call ShowUnit(udg_FLRE_DummyCaster, false)
endfunction
It's not finished yet as I want to deal with the angle of reflection first before the other things. But if there's any feedback regarding the code aside from the main problem, greatly appreciated, as this is my first project using plain jass. Thanks in advance.
Edit: Forgot to mention, I'm using purgeandfire's walkability system to do pathing check.
Attachments
Last edited: