cr4xzZz
Also known as azwraith_ftL.
- Reaction score
- 51
I've made a JASS version of Flare's Frozen Orb ability for my map. I think that this could be optimized a lot more but I'm not sure. Uses ABC and TT for trigger and timer attaching.
Frozen orb is a Diablo II spell.
Don't worry, it works fine, I just wanna know if it can be optimized more
Frozen orb is a Diablo II spell.
JASS:
scope FrozenOrb
globals
// ability raw code
private constant integer ABILITY_RAW = 039;A000039;
// missile frozen orb unit
private constant integer MISSILE_RAW = 039;h001039;
// shards unit
private constant integer BOLT_RAW = 039;h002039;
// dummy caster
private constant integer DUMMY = 039;h000039;
// frost nova raw
private constant integer FROST_NOVA = 039;A002039;
// buff frost
private constant integer BUFF_RAW = 039;Bfro039;
// max travel distance for the orb
private constant real MAX_DIST = 1050.
// travel speed
private constant real SPEED = 425.
// radius of effect of the orb
private constant real M_RADIUS = 225.
// radius of effect of the shards
private constant real S_RADIUS = 100.
endglobals
private struct Data
unit missile
integer ticks
real dx
real dy
trigger trig = CreateTrigger()
method onDestroy takes nothing returns nothing
call RemoveUnit(.missile)
call ClearTriggerStructA(.trig)
call DestroyTrigger(.trig)
endmethod
endstruct
private struct Shard
unit shard
trigger trig = CreateTrigger()
method onDestroy takes nothing returns nothing
call RemoveUnit(.shard)
call ClearTriggerStructA(.trig)
call DestroyTrigger(.trig)
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABILITY_RAW
endfunction
private function Move takes nothing returns boolean
local Data d = TT_GetData()
local real x = GetUnitX(d.missile)
local real y = GetUnitY(d.missile)
local real dx = x + d.dx
local real dy = y + d.dy
call SetUnitPosition(d.missile, dx, dy)
set d.ticks = d.ticks - 1
if d.ticks <= 0 then
call d.destroy()
return true
endif
return false
endfunction
private function Damage takes nothing returns boolean
local Data d = GetTriggerStructA(GetTriggeringTrigger())
local unit pick = GetTriggerUnit()
local unit dummy
if IsUnitEnemy(pick, GetOwningPlayer(d.missile)) and GetWidgetLife(pick) > 0.405 and IsUnitType(pick, UNIT_TYPE_STRUCTURE) == false then
if GetUnitAbilityLevel(pick, BUFF_RAW) > 0 then
else
set dummy = CreateUnit(GetOwningPlayer(d.missile), DUMMY, 0., 0., 0.)
call UnitAddAbility(dummy, FROST_NOVA)
call IssueTargetOrder(dummy, "frostnova", pick)
call UnitApplyTimedLife(dummy, 039;BTLF039;, 2.)
endif
call UnitDamageTarget(d.missile, pick, 10., false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
endif
set dummy = null
set pick = null
return false
endfunction
private function RemoveShard takes nothing returns boolean
local Shard i = TT_GetData()
if GetWidgetLife(i.shard) < 0.405 then
call i.destroy()
return true
endif
return false
endfunction
private function ShardDmg takes nothing returns boolean
local Shard i = GetTriggerStructA(GetTriggeringTrigger())
local unit pick = GetTriggerUnit()
local unit dummy
if IsUnitEnemy(pick, GetOwningPlayer(i.shard)) and GetWidgetLife(pick) > 0.405 and IsUnitType(pick, UNIT_TYPE_STRUCTURE) == false then
if GetUnitAbilityLevel(pick, BUFF_RAW) > 0 then
else
set dummy = CreateUnit(GetOwningPlayer(i.shard), DUMMY, 0., 0., 0.)
call UnitAddAbility(dummy, FROST_NOVA)
call IssueTargetOrder(dummy, "frostnova", pick)
call UnitApplyTimedLife(dummy, 039;BTLF039;, 2.)
endif
call UnitDamageTarget(i.shard, pick, 10., false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
endif
set dummy = null
set pick = null
return false
endfunction
private function Shards takes nothing returns boolean
local Data d = TT_GetData()
local Shard i = Shard.create()
local real x
local real y
local unit shard
local location loc
local location move
if GetWidgetLife(d.missile) > 0.405 then
set x = GetUnitX(d.missile)
set y = GetUnitY(d.missile)
set i.shard = CreateUnit(GetOwningPlayer(d.missile), BOLT_RAW, x, y, GetRandomReal(1, 360))
set loc = GetUnitLoc(i.shard)
set x = GetLocationX(loc) + 850. * Cos(GetUnitFacing(i.shard) * bj_DEGTORAD)
set y = GetLocationY(loc) + 850. * Sin(GetUnitFacing(i.shard) * bj_DEGTORAD)
set move = Location(x, y)
call IssuePointOrderLoc(i.shard, "move", move)
call RemoveLocation(move)
call RemoveLocation(loc)
call TriggerRegisterUnitInRange(i.trig, i.shard, S_RADIUS, null)
call TriggerAddCondition(i.trig, Condition(function ShardDmg))
call SetTriggerStructA(i.trig, i)
call TT_Start(function RemoveShard, i)
call UnitApplyTimedLife(i.shard, 039;BTLF039;, GetRandomReal(0.4, 1.2))
else
return true
endif
set shard = null
set loc = null
set move = null
return false
endfunction
private function Actions takes nothing returns nothing
local unit cast = GetTriggerUnit()
local location targ = GetSpellTargetLoc()
local real x = GetUnitX(cast)
local real y = GetUnitY(cast)
local real dx = GetLocationX(targ) - x
local real dy = GetLocationY(targ) - y
local real distance = RMinBJ(MAX_DIST, SquareRoot(dx * dx + dy * dy))
local real angle = Atan2(dy, dx)
local Data d = Data.create()
set d.missile = CreateUnit(GetOwningPlayer(cast), MISSILE_RAW, x, y, GetUnitFacing(cast))
set d.ticks = R2I(distance / (SPEED * TT_PERIOD))
set d.dx = (SPEED * TT_PERIOD) * Cos(angle)
set d.dy = (SPEED * TT_PERIOD) * Sin(angle)
call RemoveLocation(targ)
call TT_Start(function Move, d)
call TT_Start(function Shards, d)
call TriggerRegisterUnitInRange(d.trig, d.missile, M_RADIUS, null)
call TriggerAddCondition(d.trig, Condition(function Damage))
call SetTriggerStructA(d.trig, d)
set cast = null
set targ = null
endfunction
function InitTrig_FrozenOrb takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function Conditions))
call TriggerAddAction(t, function Actions)
endfunction
endscope
Don't worry, it works fine, I just wanna know if it can be optimized more