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.
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      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