The_Kingpin
Member (Who are you and why should I care?)
- Reaction score
- 41
Static Shield - Follows JESP Standard
Surrounds a targeted friendly unit with balls of static electricity. If the target it attacked, a ball will fly off and damage the attacker.
Info:
- My second spell.
- In vJass, requires Jass NewGen Pack v4b or newer.
- MUI (Now)
- Leakless
- BJ-Free
Code:
Download: View attachment Spell-StaticShield.w3x
Credits to Tinki3 for the test map template.
Constructive criticism and comments are welcome.
Surrounds a targeted friendly unit with balls of static electricity. If the target it attacked, a ball will fly off and damage the attacker.
Info:
- My second spell.
- In vJass, requires Jass NewGen Pack v4b or newer.
- MUI (Now)
- Leakless
- BJ-Free
Code:
JASS:
library StaticShield
//Configuration Section
//Edit the following varibles as needed.
globals
//Spell Data
//This is the raw code of the ability.
private integer Ability = 039;A000039;
//This is the raw code of the dummy.
private integer Dummy = 039;u001039;
//This is how long the effect will last before it dispels.
private real Duration = 58
//This is the attack type when damaging the target.
private attacktype AttackType = ATTACK_TYPE_MAGIC
//This is the damage type when damaging the target.
private damagetype DamageType = DAMAGE_TYPE_LIGHTNING
//Other Data
//This is how often the movement triggers.
private real Interval = 0.03
//This is how many degrees the balls will move in one second.
private real Degrees = 180
//This is the distance the balls will be from the unit.
private real Offset = 100
//This is how close the balls need to be to an attacker before the attacker is damaged.
private real Radius = 60
//This is how fast the balls will travel when moving toward a target.
private real Speed = 800
endglobals
//Level Settings
//
//To add more levels, add another line like this:
//set Level[<LEVEL>] = <AMOUNT>
private function Balls takes integer lvl returns integer
local integer array Level
set Level[lvl]=1
//Balls per level.
set Level[1] = 1
set Level[2] = 2
set Level[3] = 3
return Level[lvl]
endfunction
private function Damage takes integer lvl returns real
local real array Level
set Level[lvl] = 50
//Damage per level (per ball).
set Level[1] = 75
set Level[2] = 80
set Level[3] = 90
return Level[lvl]
endfunction
//End of configuration settings.
//DO NOT edit anything below this unless
//you are absolutely sure of what you are doing!
//
//
//
//
//
globals
private integer array Database1
private integer array Database2
private integer array Database3
private integer array Database4
endglobals
private function H2I takes handle h returns integer
return h
return 0
endfunction
private function Store takes handle h, integer s returns nothing
local integer id = H2I(h)-0x100000
if id <= 8190 then
set Database1[id]=s
elseif id <= 16380 then
set Database2[id-8190]=s
elseif id <= 24570 then
set Database3[id-16380]=s
elseif id <= 32760 then
set Database4[id-24570]=s
else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,20,"|cffff0000Static Shield storage limit reached at "+I2S(id)+".|r")
endif
endfunction
private function Recall takes handle h returns integer
local integer id = H2I(h)-0x100000
if id <= 8190 then
return Database1[id]
elseif id <= 16380 then
return Database2[id-8190]
elseif id <= 24570 then
return Database3[id-16380]
elseif id <= 32760 then
return Database4[id-24570]
endif
return 0
endfunction
private keyword Projectile
private keyword Orbit
private keyword Unit
private struct Projectile
unit Unit
unit Target
real Damage
trigger Trigger = CreateTrigger()
timer Timer = CreateTimer()
static method Movement takes nothing returns boolean
local Projectile this = Projectile(Recall(GetTriggeringTrigger()))
local real cx = GetUnitX(this.Unit)
local real cy = GetUnitY(this.Unit)
local real tx = GetUnitX(this.Target)
local real ty = GetUnitY(this.Target)
local real a = Atan2(ty-cy,tx-cx)
call SetUnitX(this.Unit,cx+(Speed*Interval)*Cos(a))
call SetUnitY(this.Unit,cy+(Speed*Interval)*Sin(a))
if SquareRoot((tx-cx)*(tx-cx)+(ty-cy)*(ty-cy)) <= Radius then
call UnitDamageTarget(this.Unit,this.Target,this.Damage,true,true,AttackType,DamageType,WEAPON_TYPE_WHOKNOWS)
call KillUnit(this.Unit)
call this.destroy()
endif
return false
endmethod
method onDestroy takes nothing returns nothing
call PauseTimer(this.Timer)
call DestroyTimer(this.Timer)
call DestroyTrigger(this.Trigger)
endmethod
static method create takes unit u, unit t, real damage returns Projectile
local Projectile this = Projectile.allocate()
set this.Unit = u
set this.Target = t
set this.Damage = damage
call TriggerRegisterTimerExpireEvent(this.Trigger,this.Timer)
call TriggerAddCondition(this.Trigger,Condition(function Projectile.Movement))
call Store(this.Trigger,this)
call TimerStart(this.Timer,Interval,true,null)
return this
endmethod
endstruct
private struct Orbit
unit Unit
Unit Center
real Degrees
trigger Trigger = CreateTrigger()
static method Movement takes nothing returns boolean
local Orbit this = Orbit(Recall(GetTriggeringTrigger()))
set this.Degrees = this.Degrees+Degrees*Interval
call SetUnitX(this.Unit,GetUnitX(this.Center.Unit)+Offset*Cos(this.Degrees*(3.14159/180)))
call SetUnitY(this.Unit,GetUnitY(this.Center.Unit)+Offset*Sin(this.Degrees*(3.14159/180)))
return false
endmethod
method onDestroy takes nothing returns nothing
call DestroyTrigger(this.Trigger)
endmethod
static method create takes Unit s, real Angle returns Orbit
local Orbit this = Orbit.allocate()
set this.Center = s
set this.Unit = CreateUnit(GetOwningPlayer(this.Center.Unit),Dummy,GetUnitX(this.Center.Unit),GetUnitY(this.Center.Unit),0)
call GroupAddUnit(this.Center.Balls,this.Unit)
call Store(this.Unit,this)
set this.Degrees = Angle
call TriggerRegisterTimerExpireEvent(this.Trigger,this.Center.Timer)
call TriggerAddCondition(this.Trigger,Condition(function Orbit.Movement))
call Store(this.Trigger,this)
return this
endmethod
endstruct
private struct Unit
unit Unit
group Balls = CreateGroup()
integer BallCount
integer Level
timer Timer = CreateTimer()
trigger Trigger = CreateTrigger()
trigger Exit = CreateTrigger()
static method OnAttack takes nothing returns boolean
local Unit this = Unit(Recall(GetTriggeringTrigger()))
local unit u = FirstOfGroup(this.Balls)
if IsUnitEnemy(this.Unit,GetOwningPlayer(GetAttacker())) then
call GroupRemoveUnit(this.Balls,u)
call Orbit(Recall(u)).destroy()
call Projectile.create(u,GetAttacker(),Damage(this.Level))
set this.BallCount = this.BallCount - 1
if this.BallCount <= 0 then
call this.destroy()
endif
endif
set u=null
return false
endmethod
static method ExitF takes nothing returns boolean
local Unit this = Unit(Recall(GetTriggeringTrigger()))
call this.destroy()
return false
endmethod
method onDestroy takes nothing returns nothing
local unit f
call Store(this.Unit,0)
loop
set f = FirstOfGroup(this.Balls)
exitwhen f == null
call Orbit(Recall(f)).destroy()
call KillUnit(f)
call GroupRemoveUnit(this.Balls,f)
endloop
call DestroyGroup(this.Balls)
call PauseTimer(this.Timer)
call DestroyTimer(this.Timer)
call DestroyTrigger(this.Trigger)
call DestroyTrigger(this.Exit)
endmethod
static method create takes unit u, integer l returns Unit
local Unit this = Unit.allocate()
local Orbit o
local integer i = 0
local integer a = 0
local integer balls = Balls(l)
set this.Unit=u
set this.Level=l
set this.BallCount = balls
loop
exitwhen i >= balls
set o = Orbit.create(this,a)
set a = a+360/balls
set i=i+1
endloop
call TimerStart(this.Timer,Interval,true,null)
call TriggerRegisterUnitEvent(this.Trigger,this.Unit,EVENT_UNIT_ATTACKED)
call TriggerAddCondition(this.Trigger,Condition(function Unit.OnAttack))
call Store(this.Trigger,this)
call TriggerRegisterTimerEvent(this.Exit,Duration,false)
call TriggerRegisterUnitEvent(this.Exit,this.Unit,EVENT_UNIT_DEATH)
call TriggerAddCondition(this.Exit,Condition(function Unit.ExitF))
call Store(this.Exit,this)
return this
endmethod
endstruct
function Trig_Static_Shield_Conditions takes nothing returns boolean
return GetSpellAbilityId() == Ability
endfunction
function Trig_Static_Shield_Actions takes nothing returns nothing
local unit u = GetSpellTargetUnit()
local Unit U = Recall(u)
if U != 0 then
call U.destroy()
endif
set U = Unit.create(u,GetUnitAbilityLevel(GetTriggerUnit(),Ability))
call Store(u,U)
set u = null
endfunction
//===========================================================================
function InitTrig_Static_Shield takes nothing returns nothing
set gg_trg_Static_Shield = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Static_Shield, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Static_Shield, Condition( function Trig_Static_Shield_Conditions ) )
call TriggerAddAction( gg_trg_Static_Shield, function Trig_Static_Shield_Actions )
endfunction
endlibrary
Download: View attachment Spell-StaticShield.w3x
Credits to Tinki3 for the test map template.
Constructive criticism and comments are welcome.