- Joined
- Apr 24, 2012
- Messages
- 5,111
I created this spell:
and whenever i cast it, my fps drops so bad
curiously tho, this thing(i think it's a barracks model) always show whenever the fps drop:
My guess is that ZLibrary has something to do with it
JASS:
library GigaDrain/* 1.0 by Almia
*************************************************************************************
*
* Giga Drain
*
* Deals 100/200/300 damage to the target unit, per 0.125 seconds. The caster
* then absorbs the damage dealt, healing for 50/60/70 % of the damage dealt.
* The healing/damage is divided to the number of particles released.
*
*
*************************************************************************************
*
* */ requires /*
*
* */MissileRecycler /* hiveworkshop.com/forums/jass-resources-412/system-missilerecycler-206086/
* */UnitIndexerGUI /* hiveworkshop.com/forums/spells-569/gui-unit-indexer-1-2-0-2-a-197329/
* */Projection /* hiveworkshop.com/forums/2038279-post655.html
* */GetUnitCollision /* github.com/nestharus/JASS/blob/master/jass/Systems/GetUnitCollision/script.j
* */MapBounds /* hiveworkshop.com/forums/jass-resources-412/snippet-mapbounds-222870/
* */ZLibrary /* hiveworkshop.com/forums/jass-resources-412/snippet-zlibrary-237821/
* */SpellEffectEvent /* hiveworkshop.com/forums/jass-resources-412/snippet-spelleffectevent-187193/
*
*************************************************************************************
*
* Credits
*
* Nestharus - GUC
* Bribe - MissileRecycler, UnitIndexer, SpellEffectEvent
* D.O.G. - ZLibrary
* Adiktuz - MapBounds
*
*************************************************************************************/
globals
/*
* ability code
*/
private constant integer ABIL = 'giga'
/*
* Timeout iteration
*/
private constant real TIMEOUT = 0.03125
/*
* Damage values
*/
private constant real DAMAGE_BASE = 0
private constant real DAMAGE_PER_LEVEL = 100
/*
* attack type and damage type for damage
*/
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_CHAOS
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_UNIVERSAL
/*
* Heal potency (heal = damage*potency)
*/
private constant real HEAL_POTENCY_BASE = 0.4
private constant real HEAL_POTENCY_PER_LEVEL = 0.1
/*
* SFX applied to the unit when healed.
*/
private constant string ON_HEAL_EFFECT = ""
private constant string ON_HEAL_ATTACH = ""
/*
* SFX applied to the target when damaged.
*/
private constant string ON_DAMAGE_EFFECT = ""
private constant string ON_DAMAGE_ATTACH = ""
/*
* Release delay of particles
*/
private constant real PARTICLE_DELAY = 0.125
/*
* Model of particles
*/
private constant string PARTICLE_MODEL = "Abilities\\Spells\\Undead\\Possession\\PossessionTarget.mdl"
/*
* Total number of particles released
*/
private constant real PARTICLE_COUNT = 16
/*
* Bonus z applied to the unit(approximate height of the "chest"
*/
private constant real UNIT_Z_BONUS = 64
/*
* Time it takes for each particle to transform their appearances
*/
private constant real APPEARANCE_DURATION = 3.0
/*
* Particle sizes (newSize = random(start - variation, start + variation)
*/
private constant real START_SIZE = 1.5
private constant real START_SIZE_VARIATION = 0.5
private constant real END_SIZE = 0.25
private constant real END_SIZE_VARIATION = 0.125
private constant integer START_ALPHA = 255
private constant integer START_ALPHA_VARIATION = 0
private constant integer END_ALPHA = 255
private constant integer END_ALPHA_VARIATION = 0
private constant integer START_RED = 0
private constant integer START_RED_VARIATION = 0
private constant integer END_RED = 0
private constant integer END_RED_VARIATION = 0
private constant integer START_GREEN = 255
private constant integer START_GREEN_VARIATION = 0
private constant integer END_GREEN = 255
private constant integer END_GREEN_VARIATION = 0
private constant integer START_BLUE = 0
private constant integer START_BLUE_VARIATION = 0
private constant integer END_BLUE = 0
private constant integer END_BLUE_VARIATION = 0
/*
* Gravitational speed applied to each particles
* towards their target
*/
private constant real GRAVITY = 0.6129375//9.807//4.9035
/*
* Angles of particles when released.
*/
private constant real ANGLE_START = bj_PI/2
private constant real ANGLE_VARIATION = bj_PI
private constant real ANGLE_Z_START = bj_PI/2
private constant real ANGLE_Z_VARIATION = bj_PI
/*
* How fast the particles travel(also influenced by gravity)
*/
private constant real OUTWARD_SPEED = 250
private constant real OUTWARD_SPEED_VARIATION = 125
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_PER_LEVEL*lvl
endfunction
private function GetParticleDamage takes integer lvl returns real
return GetDamage(lvl)/PARTICLE_COUNT
endfunction
private function GetHealPotency takes integer lvl returns real
return HEAL_POTENCY_BASE + HEAL_POTENCY_PER_LEVEL*lvl
endfunction
private function GetParticleHeal takes real damage, integer lvl returns real
return (damage*GetHealPotency(lvl))/PARTICLE_COUNT
endfunction
private function GetVarianceReal takes real base, real variation returns real
if variation == 0 then
return base
endif
return GetRandomReal(base - variation, base + variation)
endfunction
private function GetVarianceInt takes integer base, integer variation returns integer
if variation == 0 then
return base
endif
return GetRandomInt(base - variation, base + variation)
endfunction
private function DamageTarget takes unit s, unit t, real amount returns nothing
call UnitDamageTarget(s, t, amount, false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
endfunction
private function HealTarget takes unit s, real amount returns nothing
call SetWidgetLife(s, GetWidgetLife(s) + amount)
endfunction
private function SetPitch takes unit u, real pitch returns nothing
local integer i = R2I(pitch * 57.2957795 + 90.5)
if (179 < i) then
set i = 179
elseif (0 > i) then
set i = 0
endif
call SetUnitAnimationByIndex(u, i)
endfunction
private function Linear takes real a, real b, real t returns real
return a + (b - a)*t
endfunction
private function LinearI takes integer a, integer b, real t returns integer
return R2I(Linear(I2R(a), I2R(b), t))
endfunction
private struct Particles
private unit u
private unit target
private real csize
private real speed
private real face
private real face3d
private real cdur
private real amount
private effect mdl
private real ss
private integer sa
private integer sr
private integer sg
private integer sb
private real es
private integer ea
private integer er
private integer eg
private integer eb
private static thistype array p
private static thistype array n
private static constant timer t = CreateTimer()
method destroy takes nothing returns nothing
call deallocate()
set n[p[this]] = n[this]
set p[n[this]] = p[this]
if n[0] == 0 then
call PauseTimer(t)
endif
call RecycleMissile(u)
call DestroyEffect(mdl)
set u = null
set target = null
set csize = 0
set speed = 0
set face = 0
set face3d = 0
set cdur = 0
set amount = 0
set mdl = null
set ss = 0
set sa = 0
set sr = 0
set sg = 0
set sb = 0
set es = 0
set ea = 0
set er = 0
set eg = 0
set eb = 0
endmethod
private static method pr takes nothing returns nothing
local thistype this = n[0]
local real angle2
local real angle3
local real px
local real py
local real pz
local real dx
local real dy
local real dz
local real nx
local real ny
local real nz
local real dist2d
local real dist3d
local real pct
loop
exitwhen 0 == this
/*
* Check if target is alive
*/
if UnitAlive(target) then
/*
* if true, initialize coordinates for both the target and the particle
*/
set px = GetUnitX(u)
set py = GetUnitY(u)
set pz = GetUnitZ(u)
set dx = GetUnitX(target)
set dy = GetUnitY(target)
set dz = GetUnitZ(target) + UNIT_Z_BONUS
/*
* Get the 2d and 3d distances
*/
set dist2d = GetMagnitude2D(dx - px, dy - py)
set dist3d = GetMagnitude3D(dx - px, dy - py, dz - pz)
/*
* Check if particle is within the spherical collision
*/
if dist3d <= csize then
/*
* If true, heal the target then destroy the particle
*/
call HealTarget(target, amount)
call DestroyEffect(AddSpecialEffectTarget(ON_HEAL_EFFECT, target, ON_HEAL_ATTACH))
call destroy()
else
/*
* if not, get the angle towards the target
*/
set angle2 = GetAngle2D(dx - px, dy - py)
set angle3 = GetAngle3D(dist2d, dz - pz)
/*
* Get the next coordinates for the unit(w/o gravity)
*/
set nx = px + speed*Cos(face)*Cos(face3d)
set ny = py + speed*Sin(face)*Cos(face3d)
set nz = pz + speed*Sin(face3d)
/*
* Apply gravity for the new coordinates
*/
set nx = nx + GRAVITY*Cos(angle2)*Cos(angle3)
set ny = ny + GRAVITY*Sin(angle2)*Cos(angle3)
set nz = nz + GRAVITY*Sin(angle3)
/*
* Apply new facing
*/
set face = GetAngle2D(nx - px, ny - py)
set face3d = GetAngle3D(GetMagnitude2D(nx - px, ny - py), nz - pz)
/*
* Move the particle to the coordinates, bounded.
*/
call SetUnitX(u, GetBoundedX(nx))
call SetUnitY(u, GetBoundedY(ny))
call SetUnitZ(u, nz)
/*
* Apply pitch and facing
*/
call SetUnitFacing(u, face*bj_RADTODEG)
call SetPitch(u, face3d)
/*
* Check if the appearance timer has not yet ended.
*/
if cdur < APPEARANCE_DURATION then
/*
* If true, get the percentage of the progress
*/
set cdur = cdur + TIMEOUT
set pct = cdur/APPEARANCE_DURATION
/*
* Apply linear calculation to get the new appearance values
*/
call SetUnitScale(u, Linear(ss, es, pct), 0, 0)
call SetUnitVertexColor(u, LinearI(sr, er, pct), LinearI(sg, eg, pct), LinearI(sb, eb, pct), LinearI(sa, ea, pct))
endif
endif
else
/*
* Destroy the particle
*/
call destroy()
endif
set this = n[this]
endloop
endmethod
static method create takes unit source, unit victim, integer level returns thistype
local thistype this = allocate()
/*
* Get the coordinates of the victim
*/
local real x = GetUnitX(victim)
local real y = GetUnitY(victim)
local real z = GetUnitZ(victim)
/*
* Get the damage
*/
local real damage = GetParticleDamage(level)
/*
* get the facing
*/
set face = GetVarianceReal(ANGLE_START, ANGLE_VARIATION)
set face3d = GetVarianceReal(ANGLE_Z_START, ANGLE_Z_VARIATION)
/*
* create the particles
*/
set u = GetRecycledMissile(x, y, z, face*bj_RADTODEG)
call SetPitch(u, face3d)
/*
* Add the model to it.
*/
set mdl = AddSpecialEffectTarget(PARTICLE_MODEL, u, "origin")
/*
* get the appearance values
*/
//! textmacro GD_APPEAR takes att, ATT
set s$att$ = GetVarianceInt(START_$ATT$, START_$ATT$_VARIATION)
set e$att$ = GetVarianceInt(END_$ATT$, END_$ATT$_VARIATION)
//! endtextmacro
//! runtextmacro GD_APPEAR("a", "ALPHA")
//! runtextmacro GD_APPEAR("r", "RED")
//! runtextmacro GD_APPEAR("g", "GREEN")
//! runtextmacro GD_APPEAR("b", "BLUE")
set ss = GetVarianceReal(START_SIZE, START_SIZE_VARIATION)
set es = GetVarianceReal(END_SIZE, END_SIZE_VARIATION)
/*
* Apply the appearances
*/
call SetUnitScale(u, ss, 0, 0)
call SetUnitVertexColor(u, sr, sg, sb, sa)
/*
* Get the speed of the particle
*/
set speed = GetVarianceReal(OUTWARD_SPEED, OUTWARD_SPEED_VARIATION)*TIMEOUT
/*
* Damage the target
*/
call DamageTarget(source, victim, damage)
/*
* Get the heal amount
*/
set amount = GetParticleHeal(damage, level)
/*
* get the target's collision size
*/
set target = source
set csize = GetUnitCollision(target)
set n[this] = 0
set p[this] = p[0]
set n[p[0]] = this
set p[0] = this
if p[this] == 0 then
call TimerStart(t, TIMEOUT, true, function thistype.pr)
endif
return this
endmethod
endstruct
private struct GigaDrain
private integer count
private real spawnDelay
private unit target
private unit source
private integer level
private static thistype array p
private static thistype array n
private static constant timer t = CreateTimer()
private method destroy takes nothing returns nothing
call deallocate()
set n[p[this]] = n[this]
set p[n[this]] = p[this]
if n[0] == 0 then
call PauseTimer(t)
endif
set spawnDelay = 0
set count = 0
set level = 0
set source = null
set target = null
endmethod
private static method pr takes nothing returns nothing
local thistype this = n[0]
loop
exitwhen 0 == this
if count < PARTICLE_COUNT and UnitAlive(target) and UnitAlive(source) then
if spawnDelay > 0 then
set spawnDelay = spawnDelay - TIMEOUT
else
set count = count + 1
set spawnDelay = PARTICLE_DELAY
call Particles.create(source, target, level)
endif
else
call destroy()
endif
set this = n[this]
endloop
endmethod
private static method onCast takes nothing returns boolean
local thistype this
local integer i = 0
local unit s = GetTriggerUnit()
local unit tg = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(s, ABIL)
if PARTICLE_DELAY < TIMEOUT then
loop
set i = i + 1
call Particles.create(s, tg, lvl)
exitwhen i == PARTICLE_COUNT
endloop
else
set this = allocate()
set spawnDelay = PARTICLE_DELAY
set source = s
set target = tg
set level = lvl
set count = 0
set n[this] = 0
set p[this] = p[0]
set n[p[0]] = this
set p[0] = this
if p[this] == 0 then
call TimerStart(t, TIMEOUT, true, function thistype.pr)
endif
endif
set s = null
set tg = null
return false
endmethod
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABIL, function thistype.onCast)
endmethod
endstruct
endlibrary
and whenever i cast it, my fps drops so bad
curiously tho, this thing(i think it's a barracks model) always show whenever the fps drop:
My guess is that ZLibrary has something to do with it