- Joined
- Nov 22, 2006

- Messages
- 1,260

I don't usually ask this much, but I've been working on a spell that creates lightning orbs around the caster that rotate, if they hit a unit, they knockback it. I want someone to look at my code (this is maybe a bit complicated) Here's what doesn't work: I want the orbs to accelerate when rotating, so when they reach LightningOrbs_MaxSpeed they explode (lifespan of a lightning orb is LightningOrbs_Duration), but they don't accelerate, they don't rotate at all. Everything else works, they knockback a unit if they hit it etc.

There's the problem about the angle, it doesn't change, but when the caster moves, lightning orbs move with him, so SetUnitX/SetUnitY works, the angle just won't change......

Knockback is a function I made, it works, don't worry about that. Frequency function is in my map header and it goes like this:

Thanks in advance, I'll give +rep to the one who solves the problem, because only the experienced ones can follow the code (at least I have a hard time following it)

There's the problem about the angle, it doesn't change, but when the caster moves, lightning orbs move with him, so SetUnitX/SetUnitY works, the angle just won't change......

JASS:

```
constant function LightningOrbs_SpellId takes nothing returns integer
return 'A000'
endfunction
constant function LightningOrbs_OrbId takes nothing returns integer
return 'h000'
endfunction
constant function LightningOrbs_OrbCount takes integer level returns integer
return 4 + 2 * level
endfunction
constant function LightningOrbs_Duration takes nothing returns real
return 20.0
endfunction
constant function LightningOrbs_KnockbackDist takes real level returns real
return 200.0 + 100.0 * level
endfunction
constant function LightningOrbs_Damage takes real level returns real
return 50.0 + 50.0 * level
endfunction
constant function LightningOrbs_Distance takes nothing returns real
return 300.0
endfunction
constant function LightningOrbs_Height takes nothing returns real
return 100.0
endfunction
constant function LightningOrbs_OrbCollision takes nothing returns real
return 70.0
endfunction
constant function LightningOrbs_MaxSpeed takes nothing returns real
return 15.0
endfunction
constant function LightningOrbs_CastSFX takes nothing returns string
return "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"
endfunction
constant function LightningOrbs_LightningSFX takes nothing returns string
return "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
endfunction
//===========================================================================
function LightningOrbs_OrbHit takes nothing returns nothing
local trigger t = GetTriggeringTrigger()
local unit c = GetTriggerUnit()
local unit u = GetHandleUnit(t, "u")
local real x1 = GetUnitX(c)
local real y1 = GetUnitY(c)
local real x2 = GetUnitX(u)
local real y2 = GetUnitY(u)
local integer lvl = GetHandleInt(t, "lvl")
local real dmg = LightningOrbs_Damage(I2R(lvl))
local real d = LightningOrbs_KnockbackDist(I2R(lvl))
local real a = Atan2(y1 - y2, x1 - x2)
local player p = GetOwningPlayer(u)
call UnitDamageTarget(u, c, dmg, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
call KillUnit(u)
call Knockback(c, d, a, 1, 0, null, LightningOrbs_LightningSFX())
call DestroyTrigger(t)
set t = null
set c = null
set u = null
set p = null
endfunction
//===========================================================================
function Trig_Lightning_Orbs_Conditions takes nothing returns boolean
return GetSpellAbilityId() == LightningOrbs_SpellId()
endfunction
function LightningOrbs_TimerDestroy takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer n = GetHandleInt(t, "n")
local integer i = 1
local trigger array trig
loop
exitwhen i > n
set trig[i] = GetHandleTrigger(t, "trig" + I2S(i))
call DestroyTrigger(trig[i])
set trig[i] = null
endloop
call FlushHandleLocals(t)
call DestroyTimer(t)
set t = null
endfunction
function LightningOrbs_Rotate takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit c = GetHandleUnit(t, "c")
local group g = GetHandleGroup(t, "g")
local integer i = GetHandleInt(t, "i")
local group g2 = CreateGroup()
local real x = GetUnitX(c)
local real y = GetUnitY(c)
local integer q = R2I(LightningOrbs_Duration()/Frequency())
local real a = 10 * bj_DEGTORAD
local real a1
local unit u
local real x1
local real y1
call GroupAddGroup(g, g2)
loop
set u = FirstOfGroup(g2)
exitwhen u == null
call GroupRemoveUnit(g2, u)
set a1 = GetHandleReal(u, "a") + a
set x1 = x + LightningOrbs_Distance() * Cos(a1)
set y1 = y + LightningOrbs_Distance() * Sin(a1)
call SetUnitX(u, x1)
call SetUnitY(u, y1)
call SetHandleReal(u, "a", a1)
endloop
if i >= q then
call FlushHandleLocals(t)
call DestroyTimer(t)
else
call SetHandleInt(t, "i", i + 1)
endif
call DestroyGroup(g2)
set t = null
set c = null
set g = null
set g2 = null
endfunction
function Trig_Lightning_Orbs_Actions takes nothing returns nothing
local unit c = GetTriggerUnit()
local unit u
local real x = GetUnitX(c)
local real y = GetUnitY(c)
local real x1
local real y1
local integer lvl = GetUnitAbilityLevel(c, LightningOrbs_SpellId())
local integer n = LightningOrbs_OrbCount(lvl)
local integer i = 1
local real a = (360/I2R(n)) * bj_DEGTORAD
local player p = GetOwningPlayer(c)
local trigger array trig
local timer t = CreateTimer()
local timer v = CreateTimer()
local group g = CreateGroup()
call SetHandleInt(t, "n", n)
loop
exitwhen i > n
set trig[i] = CreateTrigger()
set x1 = x + LightningOrbs_Distance() * Cos(a*i)
set y1 = y + LightningOrbs_Distance() * Sin(a*i)
set u = CreateUnit(p, LightningOrbs_OrbId(), x1, y1, 0)
call GroupAddUnit(g, u)
call SetHandleReal(u, "a", a*i)
call SetUnitFlyHeight(u, LightningOrbs_Height(), 0)
call UnitApplyTimedLife(u, 'BTLF', LightningOrbs_Duration())
call SetHandleHandle(trig[i], "u", u)
call SetHandleInt(trig[i], "lvl", lvl)
call TriggerRegisterUnitInRange(trig[i], u, LightningOrbs_OrbCollision(), null)
call TriggerAddAction(trig[i], function LightningOrbs_OrbHit)
call SetHandleHandle(t, "trig" + I2S(i), trig[i])
set trig[i] = null
set i = i + 1
endloop
call TimerStart(t, LightningOrbs_Duration(), false, function LightningOrbs_TimerDestroy)
call SetHandleHandle(v, "g", g)
call SetHandleHandle(v, "c", c)
call TimerStart(v, Frequency(), true, function LightningOrbs_Rotate)
set t = null
set c = null
set u = null
set p = null
endfunction
//===========================================================================
function InitTrig_Lightning_Orbs takes nothing returns nothing
local integer i = 0
set gg_trg_Lightning_Orbs = CreateTrigger( )
loop
call TriggerRegisterPlayerUnitEvent(gg_trg_Lightning_Orbs, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition( gg_trg_Lightning_Orbs, Condition( function Trig_Lightning_Orbs_Conditions ) )
call TriggerAddAction( gg_trg_Lightning_Orbs, function Trig_Lightning_Orbs_Actions )
endfunction
```

Knockback is a function I made, it works, don't worry about that. Frequency function is in my map header and it goes like this:

JASS:

```
constant function Frequency takes nothing returns real
return 0.035
endfunction
```

Thanks in advance, I'll give +rep to the one who solves the problem, because only the experienced ones can follow the code (at least I have a hard time following it)

Last edited: