- Joined
- Jan 11, 2009
- Messages
- 3,414
I could use some help optimizing a trigger i just made, it is a kind of grenade spell which works roughly like this:
*A unit "squad" is ordered to throw grenades. This sets a boolean flag called "ThrowGrenade" to true and sets the real variable "GrenadeDistance" to the distance between the units and the target.
*A trigger calls the fllowing script to throw the grenades:
"L" is a struct that controls information about the group and their "leader" etc. This has to do with other systems in the map.
The following script is the process itself; it is a linked chain of functions that trigger eachother through timers (using Timerutils). It works this way because i have to synchronize attack animations, flight time, etc.
In the first step, the animation starts and the first timer is started. By the time this finishes, the anim has reached the point where the grenade is to be spawned as a projectile, which is where the second function fires. It spawns a dummy that casts a dummy spell (with projectile art) towards a polar point in front of the unit. The next timer starts with the interval required until the grenade lands.
Finally, when the last timer expires, it spawns a grenade unit at the target point. This unit will have timed life and explode upon death.
This is the code that fires when the grenade explodes:
The knockback struct type is part of a knockback library made by kricz. YOu may find it in the spells section if you want to take a closer look.
The problem is that i'm experiencing some pretty heavy lag when this fires, especially when the grenades themselves spawn, and i want some advice on how i can make this script faster, or if there's something causing near-infinite loops (like for instance when the grenades tries to knockback eachother, which was an issue until i added a condition for it).
Also, i'm having trouble making the projectile art show. I tried giving the ability to a regular unit, and ifor some reason the projectile art does not show. I am basing my ability on "channel" (a generic neutral hostile ability).
+2 rep to whoever manages to help me somehow.
Thanks in advance.
*A unit "squad" is ordered to throw grenades. This sets a boolean flag called "ThrowGrenade" to true and sets the real variable "GrenadeDistance" to the distance between the units and the target.
*A trigger calls the fllowing script to throw the grenades:
JASS:
call ForGroup(L.units, function GrenadeInterval)
set L.ThrowGrenade = false
"L" is a struct that controls information about the group and their "leader" etc. This has to do with other systems in the map.
The following script is the process itself; it is a linked chain of functions that trigger eachother through timers (using Timerutils). It works this way because i have to synchronize attack animations, flight time, etc.
In the first step, the animation starts and the first timer is started. By the time this finishes, the anim has reached the point where the grenade is to be spawned as a projectile, which is where the second function fires. It spawns a dummy that casts a dummy spell (with projectile art) towards a polar point in front of the unit. The next timer starts with the interval required until the grenade lands.
Finally, when the last timer expires, it spawns a grenade unit at the target point. This unit will have timed life and explode upon death.
JASS:
function GrenadeSpawn takes nothing returns nothing
local location l = LoadLocationHandle(LineHash, 0, GetHandleId(GetExpiredTimer()) )
call CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), 'h00P', GetLocationX(l), GetLocationY(l), 0.)
call RemoveLocation(l)
call RemoveSavedHandle(LineHash, 0, GetHandleId(GetExpiredTimer()))
call ReleaseTimer(GetExpiredTimer())
set l = null
endfunction
function GrenadesFly takes nothing returns nothing
local unit u = LoadUnitHandle(LineHash, 0, GetHandleId(GetExpiredTimer()) )
local unit dummy = CreateUnit(GetOwningPlayer(u), 'h00G', GetUnitX(u), GetUnitY(u), GetUnitFacing(u))
local Line L = Lines[GetUnitUserData(u)]
local timer t = GetExpiredTimer()
local real X = GetUnitX(u) +GetRandomReal(-5, 5) + L.GrenadeDistance * Cos(GetUnitFacing(L.controller) * bj_DEGTORAD)
local real Y = GetUnitY(u) +GetRandomReal(-5, 5) + L.GrenadeDistance * Sin(GetUnitFacing(L.controller) * bj_DEGTORAD)
local unit target = CreateUnit(GetOwningPlayer(u), 'h00G', X, Y, GetUnitFacing(u))
call UnitAddAbility(dummy, 'A002')
call IssueTargetOrderById( dummy, OrderId("acidbomb"), target)
call UnitApplyTimedLife(dummy, 'BTLF', 5.00)
call UnitApplyTimedLife(target, 'BTLF', 5.00)
call RemoveSavedHandle(LineHash, 0, GetHandleId(GetExpiredTimer()))
call SaveLocationHandle(LineHash, 0, GetHandleId(t), Location(X, Y))
call TimerStart(t, L.GrenadeDistance/700, false, function GrenadeSpawn)
set u = null
set t = null
set dummy = null
endfunction
function ThrowGrenades takes nothing returns nothing
local unit u = LoadUnitHandle(LineHash, 0, GetHandleId(GetExpiredTimer()) )
local Line L = Lines[GetUnitUserData(u)]
local timer t = GetExpiredTimer()
call SetUnitFacing(u, GetUnitFacing(L.controller))
call SetUnitAnimation(u, "spell throw")
call QueueUnitAnimation(u, "stand")
call TimerStart(t, 2., false, function GrenadesFly)
set t = null
set u = null
endfunction
function GrenadeInterval takes nothing returns nothing
local Line L = Lines[GetUnitUserData(GetEnumUnit())]
local timer t = NewTimer()
call SaveUnitHandle(LineHash, 0, GetHandleId(t), GetEnumUnit())
call TimerStart(t, GetRandomReal(0.1, 1.0), false, function ThrowGrenades)
set t = null
endfunction
This is the code that fires when the grenade explodes:
JASS:
function Trig_Grenade_Damage_Conditions takes nothing returns boolean
if ( not ( GetUnitTypeId(GetTriggerUnit()) == 'h00P' ) ) then
return false
endif
return true
endfunction
function HeroFilter takes nothing returns boolean
if (IsUnitType(GetEnumUnit(), UNIT_TYPE_HERO) == true) then
return false
endif
if (GetUnitTypeId(GetEnumUnit()) == 'h00P') then
return false
endif
return true
endfunction
function Trig_Grenade_Damage_Actions takes nothing returns nothing
local group g = CreateGroup()
local unit temp
local real ang
local real dmg
local Knockback K
call GroupEnumUnitsInRange(g, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 200., Filter(function HeroFilter))
loop
set temp = FirstOfGroup(g)
set dmg = GetRandomReal(5., 9.)
if (GetUnitState(temp, UNIT_STATE_LIFE) < dmg) then
if (GetUnitState(temp, UNIT_STATE_LIFE) > 0.5) then
set ang = bj_RADTODEG * Atan2(GetUnitY(GetTriggerUnit()) - GetUnitY(temp), GetUnitX(GetTriggerUnit()) - GetUnitX(temp))
call SetUnitFacing(temp, ang)
call SetUnitAnimation(temp, "spell slam")
set K = Knockback.create(GetTriggerUnit(), temp, GetRandomReal(100., 250.), GetRandomReal(1, 2), ang-180, KbType)
endif
endif
call SetUnitState(temp, UNIT_STATE_LIFE, GetUnitState(temp, UNIT_STATE_LIFE)-dmg)
call GroupRemoveUnit(g, temp)
exitwhen temp == null
endloop
//Cleanup variables
call RemoveUnit(GetTriggerUnit())
call DestroyGroup(g)
set g = null
endfunction
//===========================================================================
function InitTrig_Grenade_Damage takes nothing returns nothing
set gg_trg_Grenade_Damage = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Grenade_Damage, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( gg_trg_Grenade_Damage, Condition( function Trig_Grenade_Damage_Conditions ) )
call TriggerAddAction( gg_trg_Grenade_Damage, function Trig_Grenade_Damage_Actions )
endfunction
The knockback struct type is part of a knockback library made by kricz. YOu may find it in the spells section if you want to take a closer look.
The problem is that i'm experiencing some pretty heavy lag when this fires, especially when the grenades themselves spawn, and i want some advice on how i can make this script faster, or if there's something causing near-infinite loops (like for instance when the grenades tries to knockback eachother, which was an issue until i added a condition for it).
Also, i'm having trouble making the projectile art show. I tried giving the ability to a regular unit, and ifor some reason the projectile art does not show. I am basing my ability on "channel" (a generic neutral hostile ability).
+2 rep to whoever manages to help me somehow.
Thanks in advance.
Last edited: