Help improving this Spell

Zwiebelchen

You can change this now in User CP.
Reaction score
60
Hmm, this is a spell that creates a cross-shaped special effect below the feet of the caster pointing towards the selected target destination.

The spell lags heavily everytime the dummys are created and destroyed.

I know that I could make it more efficient using a struct instead of all those hashtable slots, but I think that is not the problem here. Anyone has an idea what could be the problem?

PS: The spell lags even if there is no unit in range, so it's not the damage function that causes the lag.
Also, the spell doesn't lag in singleplayer or Bnet-games without other players.

JASS:
library Crucify uses Damage, ZTS


globals
    private integer system_dummyId1 = 'h00V'
    private integer system_spellId = 'A042'
    private string system_orderId = "unloadall"
    private constant group targetGroup = CreateGroup()
    private player tplayer = null
endglobals
private function DamageTarget takes unit caster, unit target returns nothing
    local real dmg = (I2R(StatSpellpower[caster])) * 1.5 * (GetRandomReal(0.8, 1.2))
    if IsUnitType(target, UNIT_TYPE_UNDEAD) then
        set dmg = dmg*2
    endif
    call UnitDamageTargetEx(caster, target, dmg, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
    call ZTS_ModifyThreat(caster, target, dmg*0.5, true)
endfunction
private function GroupFilter takes nothing returns boolean
    return (GetUnitTypeId(GetFilterUnit())!=system_dummyId1) and IsUnitEnemy(GetFilterUnit(), tplayer)
endfunction
//-----------------------------------------------------------------------------
private function RotMatrixX takes real x, real y, real angle returns real
    return x*Cos(angle)-y*Sin(angle)
endfunction
private function RotMatrixY takes real x, real y, real angle returns real
    return x*Sin(angle)+y*Cos(angle)
endfunction

private function Tick takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer parentKey = GetHandleId(t)
    local integer state = LoadInteger(TimerHash, parentKey, 2)
    local integer drawMax
    local integer i = 6
    local real angle = LoadReal(TimerHash, parentKey, 5)
    local unit caster = LoadUnitHandle(TimerHash, parentKey, 0)
    local unit tempUnit
    local real tempUnitX
    local real tempUnitY
    local real length
    local real width
    local real casterX = LoadReal(TimerHash, parentKey, 3)
    local real casterY = LoadReal(TimerHash, parentKey, 4)
    local boolean channeling = false
    
    call RecalcStats(caster)
    if (OrderId2String(GetUnitCurrentOrder(caster))==system_orderId) then
        set channeling = true
    endif
    if(channeling) then
        call SaveInteger(TimerHash, parentKey, 2, state+1)
        if(state==0) then
            set drawMax = 135
            set length = 300
            set width = 50
        elseif(state==1) then
            set drawMax = 111
            set length = 250
            set width = 50
        elseif(state==2) then
            set drawMax = 87
            set length = 200
            set width = 50
        elseif(state==3) then
            set drawMax = 63
            set length = 150
            set width = 50
        endif
        
        loop
            exitwhen i>=drawMax
            call KillUnit(CreateUnit(GetOwningPlayer(caster), system_dummyId1, LoadReal(TimerHash, parentKey, i),LoadReal(TimerHash, parentKey, i+1), 0.0))
            set i=i+2
        endloop
        set tplayer = GetOwningPlayer(caster)
        call GroupEnumUnitsInRange(targetGroup, casterX, casterY, 300, Condition(function GroupFilter))
        set tempUnit=FirstOfGroup(targetGroup)
        set tplayer = null
        loop
            exitwhen tempUnit==null
            set tempUnitX = RotMatrixX(GetUnitX(tempUnit)-casterX, GetUnitY(tempUnit)-casterY, angle*(-1))
            set tempUnitY = RotMatrixY(GetUnitX(tempUnit)-casterX, GetUnitY(tempUnit)-casterY, angle*(-1))
            if((((-1)*width<=tempUnitX)and(tempUnitX<=width)and((-1)*length<=tempUnitY)and(tempUnitY<=length)) or (((-1)*width<=tempUnitY)and(tempUnitY<=width)and((-1)*length<=tempUnitX)and(tempUnitX<=length))) then
                call DamageTarget(caster, tempUnit)
            endif
            call GroupRemoveUnit(targetGroup, tempUnit)
            set tempUnit=FirstOfGroup(targetGroup)
        endloop
    
        if(state==0) then
            call TimerStart(t, 0.7, false, function Tick)
        elseif(state==1) then
            call TimerStart(t, 0.7, false, function Tick)
        elseif(state==2) then
            call TimerStart(t, 0.7, false, function Tick)
        else
            call FlushChildHashtable(TimerHash, parentKey)
            call DestroyTimer(t)
        endif
    else
        call FlushChildHashtable(TimerHash, parentKey)
        call DestroyTimer(t)
    endif
    set t=null
    set caster = null
    set tempUnit = null
endfunction

function Crucify takes unit caster, unit target returns nothing
    local timer t = CreateTimer()
    local integer parentKey = GetHandleId(t)
    local real targetX = GetUnitX(target)
    local real targetY = GetUnitY(target)
    local real casterX = GetUnitX(caster)
    local real casterY = GetUnitY(caster)
    local real angle = Atan2(targetY-casterY,targetX-casterX)
    local integer i
    local integer childKey = 0

    call SaveUnitHandle(TimerHash, parentKey, 0, caster)
    call SaveUnitHandle(TimerHash, parentKey, 1, target)
    call SaveInteger(TimerHash, parentKey, 2, 0)
    call SaveReal(TimerHash, parentKey, 3, casterX)
    call SaveReal(TimerHash, parentKey, 4, casterY)
    call SaveReal(TimerHash, parentKey, 5, angle)
    //middle:
    call SaveReal(TimerHash, parentKey, 6, casterX)
    call SaveReal(TimerHash, parentKey, 7, casterY)
    call SaveReal(TimerHash, parentKey, 8, casterX+RotMatrixX(25,25,angle))
    call SaveReal(TimerHash, parentKey, 9, casterY+RotMatrixY(25,25,angle))
    call SaveReal(TimerHash, parentKey, 10, casterX+RotMatrixX(25,-25,angle))
    call SaveReal(TimerHash, parentKey, 11, casterY+RotMatrixY(25,-25,angle))
    call SaveReal(TimerHash, parentKey, 12, casterX+RotMatrixX(-25,25,angle))
    call SaveReal(TimerHash, parentKey, 13, casterY+RotMatrixY(-25,25,angle))
    call SaveReal(TimerHash, parentKey, 14, casterX+RotMatrixX(-25,-25,angle))
    call SaveReal(TimerHash, parentKey, 15, casterY+RotMatrixY(-25,-25,angle))
    set childKey=16
    //row1:
    set i=0
    loop
        exitwhen i==4
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(50,0,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(50,0,angle+i*bj_PI/2))
        set childKey=childKey+1
        set i=i+1
    endloop //childkey == 23
    //row2:
    set i=0
    loop
        exitwhen i==4
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(75,25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(75,25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(75,-25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(75,-25,angle+i*bj_PI/2))
        set childKey=childKey+1
        set i=i+1
    endloop //childkey == 39
    //row3:
    set i=0
    loop
        exitwhen i==4
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(100,0,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(100,0,angle+i*bj_PI/2))
        set childKey=childKey+1
        set i=i+1
    endloop //childkey == 47
    //row4:
    set i=0
    loop
        exitwhen i==4
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(125,25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(125,25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(125,-25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(125,-25,angle+i*bj_PI/2))
        set childKey=childKey+1
        set i=i+1
    endloop //childkey == 63
    //row5:
    set i=0
    loop
        exitwhen i==4
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(150,0,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(150,0,angle+i*bj_PI/2))
        set childKey=childKey+1
        set i=i+1
    endloop //childkey == 71
    //row6:
    set i=0
    loop
        exitwhen i==4
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(175,25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(175,25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(175,-25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(175,-25,angle+i*bj_PI/2))
        set childKey=childKey+1
        set i=i+1
    endloop //childkey == 87
    //row7:
    set i=0
    loop
        exitwhen i==4
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(200,0,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(200,0,angle+i*bj_PI/2))
        set childKey=childKey+1
        set i=i+1
    endloop //childkey == 95
    //row8:
    set i=0
    loop
        exitwhen i==4
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(225,25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(225,25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(225,-25,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(225,-25,angle+i*bj_PI/2))
        set childKey=childKey+1
        set i=i+1
    endloop //childkey == 111
    //row9:
    set i=0
    loop
        exitwhen i==4
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(250,0,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(250,0,angle+i*bj_PI/2))
        set childKey=childKey+1
        set i=i+1
    endloop //childkey == 119
    //row10:
    set i=0
    loop
        exitwhen i==4
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(250,40,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(250,40,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(250,-40,angle+i*bj_PI/2))
        set childKey=childKey+1
        call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(250,-40,angle+i*bj_PI/2))
        set childKey=childKey+1
        set i=i+1
    endloop //childkey == 135
    call TimerStart(t, 0.0, false, function Tick)
    set t = null
endfunction

endlibrary
 

Laiev

Hey Listen!!
Reaction score
188
don't get why you can't use just one loop for every i = i + 1

is the same thing every loop :s
 

Zwiebelchen

You can change this now in User CP.
Reaction score
60
JASS:
        loop
            exitwhen i>=drawMax
            call KillUnit(CreateUnit(GetOwningPlayer(caster), system_dummyId1, LoadReal(TimerHash, parentKey, i),LoadReal(TimerHash, parentKey, i+1), 0.0))
            set i=i+2
        endloop


Lol!

67 times CreateUnit, GetOwningPlayer, LoadReal, LoadReal, i+1.
And where's the problem? o_O

I agree that GetOwningPlayer(caster) should be a variable to improve performance, but I don't see how I should avoid the unit creation and the checking of the spawn coordinates?
don't get why you can't use just one loop for every i = i + 1

is the same thing every loop :s
No it's not. The coordinates are always different.
 

Zwiebelchen

You can change this now in User CP.
Reaction score
60
Use DestroyEffect(AddSpecialEffect... instead?
Unit creation is taxing.
I can't, as the special effects do not allow Z coordinates (at least I haven't found out how). The problem with this spell is, that only units can have a certain flyHeight.
 

SanKakU

Member
Reaction score
21
Hmm, this is a spell that creates a cross-shaped special effect below the feet of the caster pointing towards the selected target destination.

The spell lags heavily everytime the dummys are created and destroyed.

I know that I could make it more efficient using a struct instead of all those hashtable slots, but I think that is not the problem here. Anyone has an idea what could be the problem?

PS: The spell lags even if there is no unit in range, so it's not the damage function that causes the lag.
Also, the spell doesn't lag in singleplayer or Bnet-games without other players.

library Crucify uses Damage, ZTS


globals
private integer system_dummyId1 = 'h00V'
private integer system_spellId = 'A042'
private string system_orderId = "unloadall"
private constant group targetGroup = CreateGroup()
private player tplayer = null
endglobals
private function DamageTarget takes unit caster, unit target returns nothing
local real dmg = (I2R(StatSpellpower[caster])) * 1.5 * (GetRandomReal(0.8, 1.2))
if IsUnitType(target, UNIT_TYPE_UNDEAD) then
set dmg = dmg*2
endif
call UnitDamageTargetEx(caster, target, dmg, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
call ZTS_ModifyThreat(caster, target, dmg*0.5, true)
endfunction
private function GroupFilter takes nothing returns boolean
return (GetUnitTypeId(GetFilterUnit())!=system_dummyId1) and IsUnitEnemy(GetFilterUnit(), tplayer)
endfunction
//-----------------------------------------------------------------------------
private function RotMatrixX takes real x, real y, real angle returns real
return x*Cos(angle)-y*Sin(angle)
endfunction
private function RotMatrixY takes real x, real y, real angle returns real
return x*Sin(angle)+y*Cos(angle)
endfunction

private function Tick takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer parentKey = GetHandleId(t)
local integer state = LoadInteger(TimerHash, parentKey, 2)
local integer drawMax
local integer i = 6
local real angle = LoadReal(TimerHash, parentKey, 5)
local unit caster = LoadUnitHandle(TimerHash, parentKey, 0)
local unit tempUnit
local real tempUnitX
local real tempUnitY
local real length
local real width
local real casterX = LoadReal(TimerHash, parentKey, 3)
local real casterY = LoadReal(TimerHash, parentKey, 4)
local boolean channeling = false

call RecalcStats(caster)
if (OrderId2String(GetUnitCurrentOrder(caster))==system_orderId) then
set channeling = true
endif
if(channeling) then
call SaveInteger(TimerHash, parentKey, 2, state+1)
if(state==0) then
set drawMax = 135
set length = 300
set width = 50
elseif(state==1) then
set drawMax = 111
set length = 250
set width = 50
elseif(state==2) then
set drawMax = 87
set length = 200
set width = 50
elseif(state==3) then
set drawMax = 63
set length = 150
set width = 50
endif

loop
exitwhen i>=drawMax
call KillUnit(CreateUnit(GetOwningPlayer(caster), system_dummyId1, LoadReal(TimerHash, parentKey, i),LoadReal(TimerHash, parentKey, i+1), 0.0))
set i=i+2
endloop
set tplayer = GetOwningPlayer(caster)
call GroupEnumUnitsInRange(targetGroup, casterX, casterY, 300, Condition(function GroupFilter))
set tempUnit=FirstOfGroup(targetGroup)
set tplayer = null
loop
exitwhen tempUnit==null
set tempUnitX = RotMatrixX(GetUnitX(tempUnit)-casterX, GetUnitY(tempUnit)-casterY, angle*(-1))
set tempUnitY = RotMatrixY(GetUnitX(tempUnit)-casterX, GetUnitY(tempUnit)-casterY, angle*(-1))
if((((-1)*width<=tempUnitX)and(tempUnitX<=width)and((-1)*length<=tempUnitY)and(tempUnitY<=length)) or (((-1)*width<=tempUnitY)and(tempUnitY<=width)and((-1)*length<=tempUnitX)and(tempUnitX<=length))) then
call DamageTarget(caster, tempUnit)
endif
call GroupRemoveUnit(targetGroup, tempUnit)
set tempUnit=FirstOfGroup(targetGroup)
endloop

if(state==0) then
call TimerStart(t, 0.7, false, function Tick)
elseif(state==1) then
call TimerStart(t, 0.7, false, function Tick)
elseif(state==2) then
call TimerStart(t, 0.7, false, function Tick)
else
call FlushChildHashtable(TimerHash, parentKey)
call DestroyTimer(t)
endif
else
call FlushChildHashtable(TimerHash, parentKey)
call DestroyTimer(t)
endif
set t=null
set caster = null
set tempUnit = null
endfunction

function Crucify takes unit caster, unit target returns nothing
local timer t = CreateTimer()
local integer parentKey = GetHandleId(t)
local real targetX = GetUnitX(target)
local real targetY = GetUnitY(target)
local real casterX = GetUnitX(caster)
local real casterY = GetUnitY(caster)
local real angle = Atan2(targetY-casterY,targetX-casterX)
local integer i
local integer childKey = 0

call SaveUnitHandle(TimerHash, parentKey, 0, caster)
call SaveUnitHandle(TimerHash, parentKey, 1, target)
call SaveInteger(TimerHash, parentKey, 2, 0)
call SaveReal(TimerHash, parentKey, 3, casterX)
call SaveReal(TimerHash, parentKey, 4, casterY)
call SaveReal(TimerHash, parentKey, 5, angle)
//middle:
call SaveReal(TimerHash, parentKey, 6, casterX)
call SaveReal(TimerHash, parentKey, 7, casterY)
call SaveReal(TimerHash, parentKey, 8, casterX+RotMatrixX(25,25,angle))
call SaveReal(TimerHash, parentKey, 9, casterY+RotMatrixY(25,25,angle))
call SaveReal(TimerHash, parentKey, 10, casterX+RotMatrixX(25,-25,angle))
call SaveReal(TimerHash, parentKey, 11, casterY+RotMatrixY(25,-25,angle))
call SaveReal(TimerHash, parentKey, 12, casterX+RotMatrixX(-25,25,angle))
call SaveReal(TimerHash, parentKey, 13, casterY+RotMatrixY(-25,25,angle))
call SaveReal(TimerHash, parentKey, 14, casterX+RotMatrixX(-25,-25,angle))
call SaveReal(TimerHash, parentKey, 15, casterY+RotMatrixY(-25,-25,angle))
set childKey=16
//row1:
set i=0
loop
exitwhen i==4
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(50,0,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(50,0,angle+i*bj_PI/2))
set childKey=childKey+1
set i=i+1
endloop //childkey == 23
//row2:
set i=0
loop
exitwhen i==4
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(75,25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(75,25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(75,-25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(75,-25,angle+i*bj_PI/2))
set childKey=childKey+1
set i=i+1
endloop //childkey == 39
//row3:
set i=0
loop
exitwhen i==4
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(100,0,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(100,0,angle+i*bj_PI/2))
set childKey=childKey+1
set i=i+1
endloop //childkey == 47
//row4:
set i=0
loop
exitwhen i==4
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(125,25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(125,25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(125,-25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(125,-25,angle+i*bj_PI/2))
set childKey=childKey+1
set i=i+1
endloop //childkey == 63
//row5:
set i=0
loop
exitwhen i==4
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(150,0,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(150,0,angle+i*bj_PI/2))
set childKey=childKey+1
set i=i+1
endloop //childkey == 71
//row6:
set i=0
loop
exitwhen i==4
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(175,25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(175,25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(175,-25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(175,-25,angle+i*bj_PI/2))
set childKey=childKey+1
set i=i+1
endloop //childkey == 87
//row7:
set i=0
loop
exitwhen i==4
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(200,0,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(200,0,angle+i*bj_PI/2))
set childKey=childKey+1
set i=i+1
endloop //childkey == 95
//row8:
set i=0
loop
exitwhen i==4
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(225,25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(225,25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(225,-25,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(225,-25,angle+i*bj_PI/2))
set childKey=childKey+1
set i=i+1
endloop //childkey == 111
//row9:
set i=0
loop
exitwhen i==4
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(250,0,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(250,0,angle+i*bj_PI/2))
set childKey=childKey+1
set i=i+1
endloop //childkey == 119
//row10:
set i=0
loop
exitwhen i==4
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(250,40,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(250,40,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterX+RotMatrixX(250,-40,angle+i*bj_PI/2))
set childKey=childKey+1
call SaveReal(TimerHash, parentKey, childKey, casterY+RotMatrixY(250,-40,angle+i*bj_PI/2))
set childKey=childKey+1
set i=i+1
endloop //childkey == 135
call TimerStart(t, 0.0, false, function Tick)
set t = null
endfunction

endlibrary
i just wanted to see it without the silly jass scrolly box.

hmm...the description of what the spell does is kindof hard to understand...
i think i sortof know what you're doing...
I would like to see the Damage and ZTS libraries...and want to know what models you're using for the dummies.

is your spell not kindof like this one?


scope SearingLight initializer I
//! textmacro searinglight takes reala, realb
set u = CreateUnit(p, SpiritWalker_SearingLightBeam, ux + 400.00 * Cos($reala$ * bj_DEGTORAD), uy + 400.00 * Sin($reala$ * bj_DEGTORAD), $realb$)
call UnitApplyTimedLife(u, 'BTLF', 3.0)
//! endtextmacro
private function fa takes nothing returns boolean
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local real ux = GetUnitX(u)
local real uy = GetUnitY(u)
//! runtextmacro searinglight("45.00","270.00")
//! runtextmacro searinglight("45.00","180.00")
//! runtextmacro searinglight("45.00","225.00")
//! runtextmacro searinglight("135.00","270.00")
//! runtextmacro searinglight("135.00","0.00")
//! runtextmacro searinglight("135.00","315.00")
//! runtextmacro searinglight("225.00","90.00")
//! runtextmacro searinglight("225.00","0.00")
//! runtextmacro searinglight("225.00","45.00")
//! runtextmacro searinglight("315.00","90.00")
//! runtextmacro searinglight("315.00","180.00")
//! runtextmacro searinglight("315.00","135.00")
set u = null
return false
endfunction
public function I takes nothing returns nothing
call GT_AddStartsEffectAction(function fa,SpiritWalker_SearingLight)
call XE_PreloadAbility(SpiritWalker_SearingLight)
endfunction
endscope

this spell is not a cross effect...and i have no idea what color you want it to be(it's bright like healing wave or shockwave)...but it does draw a box and an ex...if you modify it, you might be able to come up with something like what you need for your spell...and i don't think it lags...

oh and...you should probably use textmacro

yeah this spell doesn't use timers...so it's an instant effect, basically...if you need the timers then your spell is more complicated than your description implies...either you need to be more descriptive or you have some useless stuff in your trigger.
 

Weep

Godspeed to the sound of the pounding
Reaction score
400

After testing this method intensively, I must recommend against it. It seems to build up lag that never goes away, which does not occur with the create/remove destructable lines omitted. :thdown:

[edit] But it's negligible unless run thousands of times.
 

Zwiebelchen

You can change this now in User CP.
Reaction score
60
I would like to see the Damage and ZTS libraries...and want to know what models you're using for the dummies.
The damage and ZTS libraries are fine. Its not the damage part that is lagging the spell, as it also lags with no units affected at all.

is your spell not kindof like this one?

this spell is not a cross effect...and i have no idea what color you want it to be(it's bright like healing wave or shockwave)...but it does draw a box and an ex...if you modify it, you might be able to come up with something like what you need for your spell...and i don't think it lags...
It does exactly the same as I do. Having fixed coordinates and applying a transformation matrix to them.

oh and...you should probably use textmacro
This has no effect on runtime. Textmacros just save lines of code, as Textmacros get replaced when compiling.

yeah this spell doesn't use timers...so it's an instant effect, basically...if you need the timers then your spell is more complicated than your description implies...either you need to be more descriptive or you have some useless stuff in your trigger.
Its a channeled spell. It has 4 pulses, creating a shrinking cross.

The model I used for the dummies is the one of the Divine Shield of the Paladin.
 

SanKakU

Member
Reaction score
21
Its a channeled spell. It has 4 pulses, creating a shrinking cross.
oh...in that case...check this out...

not sure how similiar it is to your spell...but it does use pulses and the rings get smaller

whoever made this spell made it on a water elemental...
and they didn't put their name in comments anywhere.
JASS:

constant function HR_Ring_Interval takes nothing returns real
    return 0.35      //The raw code of the ability &quot;Hydro Rings&quot;
endfunction

constant function HR_Damage_Base takes nothing returns real
    return 30.0      //The base damage for the spell
endfunction

constant function HR_AoE takes nothing returns real
    return 200.0      //The AoE of each explosion
endfunction

constant function HR_Ring1_Explosion_Offset takes nothing returns real
    return 350.0      //The explosion offset in the 1st ring
endfunction

constant function HR_Ring2_Explosion_Offset takes nothing returns real
    return 250.0      //The explosion offset in the 2nd ring
endfunction

constant function HR_Ring3_Explosion_Offset takes nothing returns real
    return 150.0      //The explosion offset in the 3rd ring
endfunction

constant function HR_Ring1_Explosion_Count takes nothing returns integer
    return 10         //The amount of water explosions in the 1st ring
endfunction

constant function HR_Ring2_Explosion_Count takes nothing returns integer
    return 8          //The amount of water explosions in the 2nd ring
endfunction 

constant function HR_Ring3_Explosion_Count takes nothing returns integer
    return 6          //The amount of water explosions in the 3rd ring
endfunction

constant function HR_Ability_ID takes nothing returns integer
    return &#039;A08D&#039;     //The raw code of the ability &quot;Hydro Rings&quot;
endfunction

constant function HR_Dummy_Unit_ID takes nothing returns integer
    return &#039;h01D&#039;     //The raw code of the unit &quot;Hydro Rings Dummy&quot;
endfunction

function HR_Filter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) and GetWidgetLife(GetFilterUnit()) &gt; 0.405
endfunction

function HR_Actions takes nothing returns nothing    
    local unit u = GetTriggerUnit()
    local location l = GetSpellTargetLoc()
    local real dmg = GetUnitAbilityLevel(u, HR_Ability_ID()) * HR_Damage_Base()
    local integer i = 0
    local group g = CreateGroup()
    local boolexpr b = Condition(function HR_Filter)
    local unit p
    local location ll
   
    loop
        exitwhen i &gt; HR_Ring1_Explosion_Count()    
        set ll = PolarProjectionBJ(l, HR_Ring1_Explosion_Offset(), 360.00/HR_Ring1_Explosion_Count() * i)
        call CreateUnitAtLoc(GetOwningPlayer(u), HR_Dummy_Unit_ID(), ll, 0)
        call GroupEnumUnitsInRangeOfLoc(g, ll, HR_AoE(), b)
        loop
            set p = FirstOfGroup(g)
            exitwhen p == null
            call GroupRemoveUnit(g, p)
            call UnitDamageTarget(u, p, dmg, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
        endloop
        call RemoveLocation(ll)
        set i = i + 1
    endloop

    call PolledWait(HR_Ring_Interval())    
    set i = 0 

    loop
        exitwhen i &gt; HR_Ring2_Explosion_Count()    
        set ll = PolarProjectionBJ(l, HR_Ring2_Explosion_Offset(), 360.00/HR_Ring2_Explosion_Count() * i)
        call CreateUnitAtLoc(GetOwningPlayer(u), HR_Dummy_Unit_ID(), ll, 0)
        call GroupEnumUnitsInRangeOfLoc(g, ll, HR_AoE(), b)
        loop
            set p = FirstOfGroup(g)
            exitwhen p == null
            call GroupRemoveUnit(g, p)
            call UnitDamageTarget(u, p, dmg, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
        endloop
        call RemoveLocation(ll)
        set i = i + 1
    endloop  
 
    call PolledWait(HR_Ring_Interval())    
    set i = 0 
    
    loop
        exitwhen i &gt; HR_Ring3_Explosion_Count()    
        set ll = PolarProjectionBJ(l, HR_Ring3_Explosion_Offset(), 360.00/HR_Ring3_Explosion_Count() * i)
        call CreateUnitAtLoc(GetOwningPlayer(u), HR_Dummy_Unit_ID(), ll, 0)
        call GroupEnumUnitsInRangeOfLoc(g, ll, HR_AoE(), b)
        loop
            set p = FirstOfGroup(g)
            exitwhen p == null
            call GroupRemoveUnit(g, p)
            call UnitDamageTarget(u, p, dmg, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
        endloop
        call RemoveLocation(ll)
        set i = i + 1
    endloop 

    call RemoveLocation(l)
    call DestroyGroup(g)
    call DestroyBoolExpr(b)

    set u = null
    set l = null
    set ll = null
    set g = null
    set b = null
endfunction

function HR_Cond takes nothing returns boolean
    return GetSpellAbilityId() == HR_Ability_ID()    
endfunction

function InitTrig_Hydro_Rings takes nothing returns nothing
    set gg_trg_Hydro_Rings = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Hydro_Rings, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Hydro_Rings, Condition(function HR_Cond))
    call TriggerAddAction(gg_trg_Hydro_Rings, function HR_Actions)
endfunction
 

Zwiebelchen

You can change this now in User CP.
Reaction score
60
This is not really more effective considering that this spell is circular shape and circular is always easy to do as it doesnt require real polar projection and pre-form coordinates.

You miss the point of this thread.
 

Laiev

Hey Listen!!
Reaction score
188
use global variable instead function, more readable and fast <i think> :nuts:
 

SanKakU

Member
Reaction score
21
it's not my spell...
and it has pulses in it. you said you're using pulses...so i just showed you a spell with pulses. if the spell is junk, fine...just say that. i'm just trying to compare what you were doing with what some other spellmaker guy was doing.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Errr ... this thread is about improving my spell, not his one, though his one is awfully triggered, I agree.
For the performance improvement, use struct.
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
You know using a custom model instead of 25 dummy units is probably the best solution.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top