scope ExpandingSphere
//============================================||
//----------------------------Spell made by D1000---------------------------||
//-----Please give Credits if you use it in your (Or anyone else) map----||
//-------------------------------Version 1.4b----------------------------------||
//-------------------------------------------------------------------------------||
//--Requires: JassHelper, TimerUtils and xe (basic,fx,preload,damage)-||
//------Credits to Vexorian for: JassHelper, TimerUtils and xe------------||
//============================================||
//============================================||
//------------------------------------Import------------------------------------||
//1) Copy the folders "Spell" and "Systems" to your map.----------------||
//2) Import the Dummy-model used in this map in your map -----------||
//3) Follow the import-instructions of xebasic -----------------------------||
//4) Create a dummy-spell and set "AbilityID" in this trigger to its ID ---||
//5) Give credits to Vexorian and me (D1000) -----------------------------||
//6) Have fun :-) --------------------------------------------------------------||
//============================================||
globals
//Things you can change
/*Different*/
private constant integer AbilityID = 'A000' //ID of the dummy Spell
private constant real Interval = XE_ANIMATION_PERIOD //The loop-Interval
private constant real Height = 60 //How high above the ground the spell takes place
private constant integer MaxInstances = 8190 //Maximum number of instances of the Spelldata-Struct. Each usage of the spell needs 17 of them, so you can cast the spell with "MaxInstances = 8190" 8190/17 ~ 481 times at once.
/*Lightnings*/
private constant string LightningType = "DRAB" //Which lightning effect should be used.
private constant real Length = 90 //The Length of each lightning
private constant real LengthAdd = 0 //The Length increase each level
private constant real SpinSpeed = 0.11 //Spin movement per "Interval" (in Radians)
private constant real SpinSpeedAdd = 0 //Everytime the same...
//Color of the lightnings
private constant real LightningColorR = 1 //Red
private constant real LightningColorG = 1 //Green
private constant real LightningColorB = 1 //Blue
private constant real LightningColorA = 1 //Alpha
/*The ball*/
private constant string BallModel = "Abilities\\Spells\\Other\\Parasite\\ParasiteMissile.mdl" //The model of the lightning ball
private constant real StartScale = 0.2 //The scale the ball has to begin of the spell
private constant real StartScaleAdd = 0 //The scale-increase each level
private constant real GrowScale = 0.09 //How much the dummy-unit grows each "Interval"
private constant real GrowScaleAdd = 0 //The groth increase each level
private constant real MaxScale = 18 //When the dummy reaches this size, it will explode
private constant real MaxScaleAdd = 0 //Guess what
//Color of the ball
private constant integer BallColorR = 255 //Red
private constant integer BallColorG = 255 //Green
private constant integer BallColorB = 255 //Blue
private constant integer BallColorA = 255 //Alpha
/*The effect at the end*/
private constant string EndEffect = "Objects\\Spawnmodels\\Undead\\UDeathMedium\\UDeath.mdl" //The model of the explosion at the end
private constant real EndScale = 1.6 //The scale of the effect
private constant real EndScaleAdd = 0
private constant real EndZ = 100 //The flying-Height of the effect
private constant real EndZAdd = 0 //....
private constant real EndTimeAfter = 1 //Time after the EndEffect until the DummyUnit gets destroyed.
private constant real EndTimeAfterAdd = 0
//Color of the EndEffect
private constant integer EndColorR = 255 //Red
private constant integer EndColorG = 255 //Green
private constant integer EndColorB = 255 //Blue
private constant integer EndColorA = 255 //Alpha
/*Damage*/
private constant real Range = 240 //The range of the damage
private constant real RangeAdd = 0
private constant real Damage = 200 //Damage to each target
private constant real DamageAdd = 100 // self-explanatory
//Here you can alter the damage type and similar things (uses xedamage)
//! textmacro ExpandingSphereDamageSettings
set .dtype = DAMAGE_TYPE_MAGIC
set .atype = ATTACK_TYPE_HERO
//the wepon-type is per default "WEAPON_TYPE_WHOKNOWS"
set .damageTrees = true
set .damageNeutral = false
//Damage enemies and not harming allies is default
//You can find the xe-readmes in the "Systems"-Folder
//You can also define other "onInit" actions in this textmacro, if you need them
//! endtextmacro
endglobals
/*Advanced Settings*/
//The following textmacros are called in different parts of the spell.
//You can define locals in them, if you want.
//You can access the struct members by using d.StructMember
//! textmacro ExpandingSphereStart
//This textmacro is called when the spell starts.
debug call BJDebugMsg("|cffFFCC00"+GetUnitName(.caster)+"|r starts to cast 'Expanding Sphere'")
//! endtextmacro
//! textmacro ExpandingSpherePeriodic
//This textmacro is called every "Interval" seconds, while the spell takes place
debug call BJDebugMsg("Periodic event of 'Expanding Sphere' (casted by |cffFFCC00"+GetUnitName(.caster)+"|r)")
//! endtextmacro
//! textmacro ExpandingSphereEnd
//This textmacro is called when the spell ends
debug call BJDebugMsg("|cffFFCC00"+GetUnitName(.caster)+"|r finished casting 'Expanding Sphere'")
//! endtextmacro
private struct ES[MaxInstances]
//If you want, you can declare additional struct-members here
//=========================================================\\
/* Don´t touch anything below! */
//=========================================================\\
real array x[17]
real array y[17]
real array z[17]
unit caster
lightning array l[16]
integer level
real scale
real radians = 0
real array dist[16]
delegate xefx ball
static delegate xedamage dmg
static location loc = Location(0,0) //Used to get the Z value of the target point
static method create takes unit caster, real x, real y returns ES
local ES this = ES.allocate()
set .caster = caster
set .level = GetUnitAbilityLevel(caster,AbilityID)-1
set .scale = StartScale+StartScaleAdd*.level
set .x[16] = x
set .y[16] = y
set .ball = xefx.create(x,y,0)
//Sets the color of the ball
set .fxpath = BallModel
set .red = EndColorR
set .green = EndColorG
set .blue = EndColorB
set .alpha = EndColorA
set .dist[0] = -(Length + LengthAdd*.level)/2
set .x[0] = x + .dist[0]
set .y[0] = y
return this
endmethod
static method EndSpell takes nothing returns nothing
local ES this = GetTimerData(GetExpiredTimer())
//! runtextmacro ExpandingSphereEnd()
call ReleaseTimer(GetExpiredTimer())
//Destroys the ball
call .ball.destroy()
//Destroys the spell-struct
call .destroy()
endmethod
static method Loop takes nothing returns nothing
//Local declaration
local timer t = GetExpiredTimer()
local ES this = GetTimerData(t)
local integer i = 1
local xefx EndSFX
//! runtextmacro ExpandingSpherePeriodic()
//Lets the dummy grow^^
set .ball.scale = .scale
set .scale = .scale + GrowScale+GrowScaleAdd*.level
if .scale >= MaxScale + MaxScaleAdd*.level then // When the max scale is reached, destroy the shapes and so on...
call PauseTimer(t) //Only pauses the timer becauses it is still needed
//The explosion
set EndSFX = xefx.create(.x[16],.y[16],0)
set EndSFX.fxpath = EndEffect
set EndSFX.z = EndZ+EndZAdd*.level
set EndSFX.scale = EndScale+EndScaleAdd*.level
//Sets the color of the effect
set EndSFX.red = EndColorR
set EndSFX.green = EndColorG
set EndSFX.blue = EndColorB
set EndSFX.alpha = EndColorA
set i = 0
loop //Destroys the shapes
call DestroyLightning(.l[i])
set i = i + 1
exitwhen i == 16
endloop
if Damage+DamageAdd*.level > 0 then //Only triggers if the damage is > 0
call .damageAOE(.caster,.x[16],.y[16],Range+RangeAdd*.level,Damage+DamageAdd*.level)
endif
call TimerStart(t,EndTimeAfter+EndTimeAfterAdd*.level,false,function ES.EndSpell)
return //Skips the rest of the trigger
endif
set .x[0] = .x[16]+ .dist[0]*Sin(.radians)
set .y[0] = .y[16]+ .dist[0]*Cos(.radians)
loop // Moves the lightnings
if i <= 7 then
set .x[i] = .x[16]+ .dist[i]*Sin(.radians)
set .y[i] = .y[16]+ .dist[i]*Cos(.radians)
call MoveLightningEx(.l[i-1],true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
elseif i == 8 then
set .y[i] = .y[16]+ .dist[i]*Sin(.radians)
set .z[i] = .z[16]+ .dist[i]*Cos(.radians)
call MoveLightningEx(.l[i-1],true,.x[0],.y[0],.z[0],.x[i-1],.y[i-1],.z[i-1])
else
set .y[i] = .y[16]+ .dist[i]*Sin(.radians)
set .z[i] = .z[16]+ .dist[i]*Cos(.radians)
call MoveLightningEx(.l[i-1],true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
endif
set i = i + 1
exitwhen i >= 16
endloop
call MoveLightningEx(.l[15],true,.x[8],.y[8],.z[8],.x[15],.y[15],.z[15])
set .radians = .radians + SpinSpeed+SpinSpeedAdd*.level
endmethod
static method StartSpell takes nothing returns nothing
// Local declaration
local ES this = ES.create(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
local timer t = NewTimer()
local integer i = 1
//! runtextmacro ExpandingSphereStart()
call MoveLocation(.loc,.x[16],.y[16])
set .z[16] = GetLocationZ(.loc)
call SetTimerData(t,this) //Attaches the struct to the timer
set .z[0] = .z[16] + Height
set .ball.z = (Length + LengthAdd*.level)/2 + SquareRoot(((Length + LengthAdd*.level)*(Length + LengthAdd*.level))/2) + Height // Sets the Height of the ball
set .z[16] = .z[16]+.ball.z
//Creates the lightnings (there are 16 of them)
loop
if i <= 7 then
set .x[i] = .x[i-1] + (Length+LengthAdd*.level)*Cos(bj_PI/4*(i-1))
set .y[i] = .y[16]
set .z[i] = .z[i-1] + (Length+LengthAdd*.level)*Sin(bj_PI/4*(i-1))
set .l[i-1] = AddLightningEx(LightningType,true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
set .dist[i] = .x[i]-.x[16]
elseif i == 8 then
set .x[i] = .x[16] - (Length + LengthAdd*.level)/2
set .y[i] = .y[16] - (Length + LengthAdd*.level)/2 - SquareRoot(((Length + LengthAdd*.level)*(Length + LengthAdd*.level))/2)
set .z[i] = .z[16]
set .l[i-1] = AddLightningEx(LightningType,true,.x[0],.y[0],.z[0],.x[i-1],.y[i-1],.z[i-1])
set .dist[i] = .y[i]-.y[16]
else
set .x[i] = .x[i-1] + (Length+LengthAdd*.level)*Cos(bj_PI/4*(i-1))
set .y[i] = .y[i-1] + (Length+LengthAdd*.level)*Sin(bj_PI/4*(i-1))
set .z[i] = .z[8]
set .l[i-1] = AddLightningEx(LightningType,true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
set .dist[i] = .y[i]-.y[16]
endif
call SetLightningColor(.l[i-1],LightningColorR,LightningColorG,LightningColorB,LightningColorA)
set i = i + 1
exitwhen i >= 16
endloop
set .l[15] = AddLightningEx(LightningType,true,.x[15],.y[15],.z[15],.x[8],.y[8],.z[8])
call SetLightningColor(.l[15],LightningColorR,LightningColorG,LightningColorB,LightningColorA)
call TimerStart(t,Interval,true,function ES.Loop) //Starts the loop
endmethod
static method onInit takes nothing returns nothing
local trigger tr = CreateTrigger()
call XE_PreloadAbility(AbilityID)
call TriggerRegisterAnyUnitEventBJ(tr,EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition(tr,Condition(function ES.IsSpell))
call TriggerAddAction(tr,function ES.StartSpell)
set tr = null
set .dmg = xedamage.create()
//! runtextmacro ExpandingSphereDamageSettings()
endmethod
static method IsSpell takes nothing returns boolean
return GetSpellAbilityId() == AbilityID
endmethod
endstruct
endscope