- Joined
- Jun 24, 2009
- Messages
- 1,408
I'm just wondering. Isn't there in JASS a func that increases an integer with 1? Just like the inc(i) in Pascal.
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
function inc takes integer i returns nothing
set i = i + 1
endfunction
Equilibrium Strike

Events


Unit - A unit Starts the effect of an ability

Conditions


(Ability being cast) Equal to Equilibrium Strike

Actions


-------- --- --------


-------- Setting the spell constants --------


-------- --- --------


Set ES_Caster = (Triggering unit)


Set ES_Target = (Target unit of ability being cast)


Set ES_Ability_Level = (Level of (Ability being cast) for ES_Caster)


Set ES_Owner = (Owner of ES_Caster)


-------- --- --------


-------- Setting the spell values --------


-------- --- --------


Set ES_Base_Damage = 60.00


Set ES_Level_Damage = 40.00


Set ES_Atribute_Factor = 0.30


Set ES_Atribute_Damage = (Agility of ES_Caster (Include bonuses))


Set ES_Caster_Life = ((Life of ES_Caster) / (Max life of ES_Caster))


Set ES_Target_Life = ((Life of ES_Target) / (Max life of ES_Target))


-------- --- --------


-------- Setting the dummy abilities --------


-------- --- --------


Set ES_Dummy_Ability_Slow = Equilibrium Strike(dummy slow)


Set ES_Dummy_Ability_Stun = Equilibrium Strike(dummy stun)


-------- --- --------


-------- Setting the spell values/locations for special effects --------


-------- --- --------


Set ES_Spell_Loc = (Position of ES_Target)


Set ES_Spell_Loc_2 = (Position of ES_Caster)


Set ES_Facing_Angle = (Angle from ES_Spell_Loc to ES_Spell_Loc_2)


Set ES_SFX_Offset = 200.00


Set ES_SFX_Angle = 50.00


Set ES_SFX_Duration = 1.00


Set ES_SFX_Loc = (ES_Spell_Loc_2 offset by ES_SFX_Offset towards (ES_Facing_Angle + ES_SFX_Angle) degrees)


Set ES_SFX_Loc_2 = (ES_Spell_Loc_2 offset by ES_SFX_Offset towards (ES_Facing_Angle - ES_SFX_Angle) degrees)


-------- --- --------


-------- Calculating the damage --------


-------- --- --------


Set ES_Damage_Calculation = (ES_Base_Damage + ((Real(ES_Ability_Level)) x ES_Level_Damage))


Set ES_Atribute_Damage_Calculation = ((Real(ES_Ability_Level)) x (ES_Atribute_Factor x (Real(ES_Atribute_Damage))))


-------- --- --------


Set ES_Total_Damage = (ES_Atribute_Damage_Calculation + ES_Damage_Calculation)


-------- --- --------


-------- Creating some nice special effects --------


-------- --- --------


Special Effect - Create a special effect attached to the weapon of ES_Caster using Abilities\Spells\Orc\Shockwave\ShockwaveMissile.mdl


Special Effect - Destroy (Last created special effect)


Special Effect - Create a special effect attached to the origin of ES_Target using Abilities\Spells\Other\Stampede\StampedeMissileDeath.mdl


Special Effect - Destroy (Last created special effect)


Special Effect - Create a special effect attached to the origin of ES_Target using Abilities\Spells\Orc\Disenchant\DisenchantSpecialArt.mdl


Special Effect - Destroy (Last created special effect)


-------- --- --------


-------- Starting a loop, which runs all the moving special effects --------


-------- --- --------


For each (Integer A) from 1 to 25, do (Actions)



Loop - Actions




-------- --- --------




-------- This loop runs two special effects at the same time, but by different angle, so don't get confused by two colums of almost same actions --------




-------- --- --------




-------- --- --------




-------- Calculating the values which are calculated trough every loop --------




-------- --- --------




Set ES_SFX_Value = ((Real((Integer A))) x 13.00)




Set ES_SFX_Value_1 = (100.00 - ((Real((Integer A))) x 2.50))




Set ES_SFX_Value_2 = ((Real((Integer A))) x 8.00)




Set ES_SFX_Value_3 = ((Real((Integer A))) x 3.00)




Set ES_SFX_Offset_Calculation = (ES_SFX_Offset - ES_SFX_Value)




-------- --- --------




-------- Getting a location for special effect --------




-------- --- --------




Set ES_SFX_Loc_3 = (ES_SFX_Loc offset by ES_SFX_Offset_Calculation towards (ES_Facing_Angle + ES_SFX_Angle) degrees)




-------- --- --------




-------- Creating the dummy as a special effect, setting its values experation timer/flying height/vertex coloring/ animation --------




-------- --- --------




Unit - Create 1 Dummy_SFX for ES_Owner at ES_SFX_Loc_3 facing ES_Facing_Angle degrees




Unit - Add a ES_SFX_Duration second Generic expiration timer to (Last created unit)




Unit - Order (Last created unit) to Move To ES_Spell_Loc




Animation - Change (Last created unit) flying height to ((Current flying height of (Last created unit)) - ES_SFX_Value_2) at 0.00




Animation - Play (Last created unit)'s birth animation




Animation - Change (Last created unit)'s size to (ES_SFX_Value_1%, ES_SFX_Value_1%, ES_SFX_Value_1%) of its original size




Animation - Change (Last created unit)'s vertex coloring to (100.00%, 100.00%, 100.00%) with ES_SFX_Value_3% transparency




-------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------




-------- --- --------




-------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------




-------- Getting a location for special effect --------




-------- --- --------




Set ES_SFX_Loc_4 = (ES_SFX_Loc_2 offset by ES_SFX_Offset_Calculation towards (ES_Facing_Angle - ES_SFX_Angle) degrees)




-------- --- --------




-------- Creating the dummy as a special effect, setting its values experation timer/flying height/vertex coloring/ animation --------




-------- --- --------




Unit - Create 1 Dummy_SFX for ES_Owner at ES_SFX_Loc_4 facing ES_Facing_Angle degrees




Unit - Add a ES_SFX_Duration second Generic expiration timer to (Last created unit)




Unit - Order (Last created unit) to Move To ES_Spell_Loc




Animation - Change (Last created unit) flying height to ((Current flying height of (Last created unit)) - ES_SFX_Value_2) at 0.00




Animation - Play (Last created unit)'s birth animation




Animation - Change (Last created unit)'s size to (ES_SFX_Value_1%, ES_SFX_Value_1%, ES_SFX_Value_1%) of its original size




Animation - Change (Last created unit)'s vertex coloring to (100.00%, 100.00%, 100.00%) with ES_SFX_Value_3% transparency




-------- --- --------




-------- Clearing the used locations / removing leaks --------




-------- --- --------




Custom script: call RemoveLocation(udg_ES_SFX_Loc_3)




Custom script: call RemoveLocation(udg_ES_SFX_Loc_4)


-------- --- --------


-------- Creating a nice floaring text that wil dispay the damage done, also setting its lifespan/color/velectory.. --------


-------- --- --------


Floating Text - Create floating text that reads ((String((Integer(ES_Total_Damage)))) + !) above ES_Target with Z offset 0.00, using font size 10.00, color (100.00%, 5.00%, 0.00%), and 0.00% transparency


Floating Text - Change (Last created floating text): Disable permanence


Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees


Floating Text - Change the fading age of (Last created floating text) to 0.75 seconds


Floating Text - Change the lifespan of (Last created floating text) to 2.00 seconds


-------- --- --------


-------- Creating a dummy that will Slow/Stun the target --------


-------- --- --------


Unit - Create 1 Dummy for ES_Owner at ES_Spell_Loc facing Default building facing degrees


Unit - Add a 0.75 second Generic expiration timer to (Last created unit)


Unit - Make (Last created unit) face ES_Target over 0.00 seconds


-------- --- --------


-------- This checks which life is higher target's or caster's --------


-------- --- --------


If (All Conditions are True) then do (Then Actions) else do (Else Actions)



If - Conditions




ES_Caster_Life Greater than or equal to ES_Target_Life



Then - Actions




-------- --- --------




-------- Now if caster's life is higher than target's then dummy is ordered to castslow --------




-------- --- --------




Unit - Add ES_Dummy_Ability_Slow to (Last created unit)




Unit - Set level of ES_Dummy_Ability_Slow for (Last created unit) to ES_Ability_Level




Unit - Order (Last created unit) to Human Sorceress - Slow ES_Target



Else - Actions




-------- --- --------




-------- But if caster's life is lower than target's than dummy is ordered to cast storm bolt (stun) --------




-------- --- --------




Unit - Add Equilibrium Strike(dummy stun) to (Last created unit)




Unit - Set level of ES_Dummy_Ability_Stun for (Last created unit) to ES_Ability_Level




Unit - Order (Last created unit) to Human Mountain King - Storm Bolt ES_Target


-------- --- --------


-------- Damaging the target --------


-------- --- --------


Unit - Cause ES_Caster to damage ES_Target, dealing ES_Total_Damage damage of attack type Spells and damage type Unknown


-------- --- --------


-------- Clearing the used locations / removing leaks --------


-------- --- --------


Custom script: call RemoveLocation(udg_ES_Spell_Loc)


Custom script: call RemoveLocation(udg_ES_Spell_Loc_2)


Custom script: call RemoveLocation(udg_ES_SFX_Loc)


Custom script: call RemoveLocation(udg_ES_SFX_Loc_2)
Even if the meteors are instant, the smoke behind them should go away a bit slower. I mean from the top effect to the ground effect it takes less than 0.2 seconds to go away. You should increase that interval, will look a bit better due to the impale dust effect. It's just my opinion though.
Well, there's nothing I can do with the smoke itself, but I guess I could increase the interval at which the meteors hit the ground to compensate.Yeah, the smoke should stay for a while longer.
That's how the actual spell is. Look at the video in this post (Starts at 0:30).The big flash is overpoweing and you can't see any actual meteors falling...
| Channels a soul orb to damage the first units in a line. If no enemy unit hit and the orb raches it's max distance, it disappears. The orb passes through magic immune units and buildings. |
Init

Events


Map initialization

Conditions

Actions


Visibility - Disable fog of war


Visibility - Disable black mask


Set SBMax = 2


-------- Configurables on each level --------


-------- Level 1 --------


Set Distance[1] = 1250.00


-------- Level 2 --------


Set Distance[2] = 1500.00


-------- Level 3 --------


Set Distance[3] = 1750.00
Soul Blast

Events


Unit - A unit Begins channeling an ability

Conditions


(Ability being cast) Equal to Soul Blast

Actions


If (All Conditions are True) then do (Then Actions) else do (Else Actions)



If - Conditions




SBHas[SBLastRecycled] Equal to True



Then - Actions




Set SBMax = (SBMax + 1)




Set SBLastRecycled = SBMax




Set SBIndex = SBLastRecycled




Set SBLastRecycled = SBRecycledList[SBLastRecycled]



Else - Actions




Set SBIndex = SBLastRecycled




Set SBLastRecycled = SBRecycledList[SBLastRecycled]


Set SBCaster[SBIndex] = (Triggering unit)


Set SBCasterPoint[SBIndex] = (Position of SBCaster[SBIndex])


Set SBTargetPoint[SBIndex] = (Target point of ability being cast)


Set SBDistance[SBIndex] = 50.00


Set SBLevel[SBIndex] = (Level of Soul Blast for SBCaster[SBIndex])


Set SBMaxDistance[SBIndex] = Distance[SBLevel[SBIndex]]


Set SBAngle[SBIndex] = (Angle from SBCasterPoint[SBIndex] to SBTargetPoint[SBIndex])


Set SBTempPoint = (SBCasterPoint[SBIndex] offset by 50.00 towards SBAngle[SBIndex] degrees)


Custom script: set udg_SBDummyGroup[udg_SBIndex] = CreateGroup()


Unit - Create 1 Missile Body 1 for (Triggering player) at SBCasterPoint[SBIndex] facing SBAngle[SBIndex] degrees


Unit Group - Add (Last created unit) to SBDummyGroup[SBIndex]


Animation - Change (Last created unit)'s animation speed to 5.00% of its original speed


Unit - Create 1 Missile Body 2 for (Triggering player) at SBCasterPoint[SBIndex] facing SBAngle[SBIndex] degrees


Unit Group - Add (Last created unit) to SBDummyGroup[SBIndex]


Unit - Create 1 Missile Head for (Triggering player) at SBTempPoint facing SBAngle[SBIndex] degrees


Unit Group - Add (Last created unit) to SBDummyGroup[SBIndex]


Custom script: set udg_SBChannelGroup[udg_SBIndex] = CreateGroup()


For each (Integer A) from 1 to 2, do (Actions)



Loop - Actions




Set SBScale[SBIndex] = (100.00 x (Real((Integer A))))




Unit - Create 1 Channel Effect for (Triggering player) at SBCasterPoint[SBIndex] facing SBAngle[SBIndex] degrees




Animation - Change (Picked unit)'s size to (SBScale[SBIndex]%, SBScale[SBIndex]%, SBScale[SBIndex]%) of its original size




Unit Group - Add (Last created unit) to SBChannelGroup[SBIndex]


Set SBHas[SBIndex] = True


Set SBCount = (SBCount + 1)


Set SBTimer[SBIndex] = 3.00


Set SBEffect[SBIndex] = False


Custom script: call RemoveLocation (udg_SBTempPoint)


If (All Conditions are True) then do (Then Actions) else do (Else Actions)



If - Conditions




(Soul Blast Loop <gen> is on) Equal to False



Then - Actions




Trigger - Turn on Soul Blast Loop <gen>




Trigger - Turn on Wave Effect <gen>



Else - Actions
Soul Blast Halt

Events


Unit - A unit Stops casting an ability


Unit - A unit Finishes casting an ability

Conditions


(Ability being cast) Equal to Soul Blast

Actions


For each (Integer A) from 0 to SBMax, do (Actions)



Loop - Actions




If (All Conditions are True) then do (Then Actions) else do (Else Actions)





If - Conditions






SBCaster[(Integer A)] Equal to (Triggering unit)





Then - Actions






If (All Conditions are True) then do (Then Actions) else do (Else Actions)







If - Conditions








SBTimer[(Integer A)] Greater than 0.00







Then - Actions








Unit Group - Pick every unit in SBDummyGroup[(Integer A)] and do (Unit - Kill (Picked unit))








Unit Group - Pick every unit in SBChannelGroup[(Integer A)] and do (Unit - Remove (Picked unit) from the game)








Custom script: call DestroyGroup (udg_SBChannelGroup[GetForLoopIndexA()])








Custom script: call DestroyGroup (udg_SBDummyGroup[GetForLoopIndexA()])








Set SBTimer[(Integer A)] = 0.00








Custom script: call RemoveLocation (udg_SBTargetPoint[GetForLoopIndexA()])








Custom script: call RemoveLocation (udg_SBCasterPoint[GetForLoopIndexA()])








Set SBHas[(Integer A)] = False








Set SBRecycledList[(Integer A)] = SBLastRecycled








Set SBLastRecycled = (Integer A)








Set SBEffect[(Integer A)] = False








Set SBCount = (SBCount - 1)








If (All Conditions are True) then do (Then Actions) else do (Else Actions)









If - Conditions










SBCount Equal to 0









Then - Actions










Trigger - Turn off Wave Effect <gen>










Trigger - Turn off Soul Blast Loop <gen>









Else - Actions







Else - Actions





Else - Actions
Soul Blast Loop

Events


Time - Every 0.03 seconds of game time

Conditions

Actions


For each (Integer SBInteger) from 0 to SBMax, do (Actions)



Loop - Actions




If (All Conditions are True) then do (Then Actions) else do (Else Actions)





If - Conditions






SBHas[SBInteger] Equal to True





Then - Actions






If (All Conditions are True) then do (Then Actions) else do (Else Actions)







If - Conditions








SBTimer[SBInteger] Greater than 0.00







Then - Actions








Set SBTimer[SBInteger] = (SBTimer[SBInteger] - 0.03)








Set SBScale[SBInteger] = (SBScale[SBInteger] - 10.00)








Set r = SBScale[SBInteger]








Unit Group - Pick every unit in SBChannelGroup[SBInteger] and do (Actions)









Loop - Actions










If (All Conditions are True) then do (Then Actions) else do (Else Actions)











If - Conditions












r Less than 110.00











Then - Actions












Set r = 200.00











Else - Actions












Set r = (r - 100.00)










Animation - Change (Picked unit)'s size to (r%, r%, r%) of its original size







Else - Actions








If (All Conditions are True) then do (Then Actions) else do (Else Actions)









If - Conditions










(Number of units in SBChannelGroup[SBInteger]) Not equal to 0









Then - Actions










Unit Group - Pick every unit in SBChannelGroup[SBInteger] and do (Unit - Remove (Picked unit) from the game)









Else - Actions








Set SBEffect[SBInteger] = True








If (All Conditions are True) then do (Then Actions) else do (Else Actions)









If - Conditions










SBDistance[SBInteger] Less than SBMaxDistance[SBInteger]









Then - Actions










Set SBDistance[SBInteger] = (SBDistance[SBInteger] + 40.00)










Set SBTempPoint = (SBCasterPoint[SBInteger] offset by SBDistance[SBInteger] towards SBAngle[SBInteger] degrees)










Unit Group - Pick every unit in SBDummyGroup[SBInteger] and do (Actions)











Loop - Actions












If (All Conditions are True) then do (Then Actions) else do (Else Actions)













If - Conditions














(Unit-type of (Picked unit)) Equal to Missile Head













Then - Actions














Set SBTempPoint2 = (SBCasterPoint[SBInteger] offset by (SBDistance[SBInteger] + 40.00) towards SBAngle[SBInteger] degrees)














Unit - Move (Picked unit) instantly to SBTempPoint2














Custom script: call RemoveLocation (udg_SBTempPoint2)













Else - Actions














Unit - Move (Picked unit) instantly to SBTempPoint










Set SBTempGroup = (Units within 100.00 of SBTempPoint matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is Magic Immune) Equal to False) and ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of (Owner of SBCa










If (All Conditions are True) then do (Then Actions) else do (Else Actions)











If - Conditions












(SBTempGroup is empty) Equal to True











Then - Actions











Else - Actions












Custom script: call RemoveLocation (udg_SBTargetPoint[udg_SBInteger])












Custom script: call RemoveLocation (udg_SBCasterPoint[udg_SBInteger])












Custom script: set bj_wantDestroyGroup = true












Unit Group - Pick every unit in SBDummyGroup[SBInteger] and do (Unit - Kill (Picked unit))












Unit Group - Pick every unit in SBChannelGroup[SBInteger] and do (Unit - Remove (Picked unit) from the game)












Custom script: call DestroyGroup (udg_SBDummyGroup[udg_SBInteger])












Custom script: call DestroyGroup (udg_SBChannelGroup[udg_SBInteger])












Set SBEffect[SBIndex] = False












Unit Group - Pick every unit in (Units within 250.00 of SBTempPoint matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is Magic Immune) Equal to False) and ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of (Owner of SBCa and do (Actions)













Loop - Actions














Unit - Cause SBCaster[SBInteger] to damage (Picked unit), dealing (100.00 x (Real(SBLevel[SBInteger]))) damage of attack type Spells and damage type Magic












Unit - Create 1 Blast Effect for (Owner of SBCaster[SBInteger]) at SBTempPoint facing Default building facing degrees












Unit - Add a 0.10 second Generic expiration timer to (Last created unit)












Set SBHas[SBInteger] = False












Set SBCount = (SBCount - 1)












Set SBRecycledList[SBInteger] = SBLastRecycled












Set SBLastRecycled = SBInteger












If (All Conditions are True) then do (Then Actions) else do (Else Actions)













If - Conditions














SBCount Equal to 0













Then - Actions














Trigger - Turn off (This trigger)














Trigger - Turn off Wave Effect <gen>













Else - Actions










Custom script: call DestroyGroup (udg_SBTempGroup)










Custom script: call RemoveLocation (udg_SBTempPoint)









Else - Actions










Set SBHas[SBInteger] = False










Custom script: set bj_wantDestroyGroup = true










Set SBEffect[SBIndex] = False










Unit Group - Pick every unit in SBDummyGroup[SBInteger] and do (Unit - Kill (Picked unit))










Unit Group - Pick every unit in SBChannelGroup[SBInteger] and do (Unit - Remove (Picked unit) from the game)










Custom script: call DestroyGroup (udg_SBDummyGroup[udg_SBInteger])










Custom script: call DestroyGroup (udg_SBChannelGroup[udg_SBInteger])










Custom script: call RemoveLocation (udg_SBTargetPoint[udg_SBInteger])










Custom script: call RemoveLocation (udg_SBCasterPoint[udg_SBInteger])










Set SBCount = (SBCount - 1)










Set SBRecycledList[SBInteger] = SBLastRecycled










Set SBLastRecycled = SBInteger










If (All Conditions are True) then do (Then Actions) else do (Else Actions)











If - Conditions












SBCount Equal to 0











Then - Actions












Trigger - Turn off (This trigger)












Trigger - Turn off Wave Effect <gen>











Else - Actions





Else - Actions
Wave Effect

Events


Time - Every 0.05 seconds of game time

Conditions

Actions


For each (Integer B) from 0 to SBMax, do (Actions)



Loop - Actions




If (All Conditions are True) then do (Then Actions) else do (Else Actions)





If - Conditions






SBHas[(Integer B)] Equal to True





Then - Actions






If (All Conditions are True) then do (Then Actions) else do (Else Actions)







If - Conditions








SBEffect[(Integer B)] Equal to True







Then - Actions








Unit Group - Pick every unit in SBDummyGroup[(Integer B)] and do (Actions)









Loop - Actions










If (All Conditions are True) then do (Then Actions) else do (Else Actions)











If - Conditions












((Picked unit) is alive) Equal to True












(Unit-type of (Picked unit)) Equal to Missile Head











Then - Actions












Set SBTempPoint = (Position of (Picked unit))












Unit - Create 1 Wave Effect for (Owner of (Picked unit)) at SBTempPoint facing (Facing of (Picked unit)) degrees












Animation - Change (Last created unit)'s animation speed to 150.00% of its original speed












Unit - Add a 1.00 second Generic expiration timer to (Last created unit)












Custom script: call RemoveLocation (udg_SBTempPoint)











Else - Actions







Else - Actions








Unit - Create 1 Blast Effect for (Owner of SBCaster[(Integer B)]) at SBCasterPoint[(Integer B)] facing Default building facing degrees








Unit - Add a 0.10 second Generic expiration timer to (Last created unit)








Animation - Change (Last created unit)'s animation speed to 200.00% of its original speed





Else - Actions
Omg, i afraid that i will lose, here we have a good contestant!
Introduction
The Spells & Systems Contest is more of a fun code learning environment than a contest, due to its low requirements, its short time limit, and its small prize. Each spell must adhere to the theme listed below, and to win, it should be executed well and take the main judging points into consideration.
You had it right. If the value of:
Caster Health / Caster Health Max
Is less than the value of:
Target Health / Target Health Max
Then the caster has less health (in percentage) than the target.
So, if the caster has 500/1000 then the percentage is 50%, or 0.5. If the target has 200/300, then the percentage is 66.6%, or 0.666. Since 0.5 < 0.666, the caster would have less percentage than the target.
Got any ideas how to make it more balanced, by not just using flat life?
Got any ideas how to make it more balanced, by not just using flat life?
Berb said:Does anybody own Age of Mythology? There aren't any particularly good videos of the effect it has; from what I can tell it deals damage to enemies in an area and sucks them into the wind if they die as a result.
What happens when two tornadoes come in contact with each other? What happens to the units that are being blown around by the tornado? What happens to air units (if there are air units) when they are affected by the tornado?
TRD*TDR, that looks really good now; where did you get the light flashing effect from?
"Abilities\\Weapons\\RocketMissile\\RocketMissile.mdl" and it's scaled to 16 times its own size. call DestroyEffect(AddSpecialEffectTarget(<derp>)) (Target because it's attached to a dummy unit so I could scale it).Okey, I'll implement that tomorrow. Not sure if I'll find fitting "godpower music" though without importing anything.Okay, TRD, I got the exact stuff now.
Meteor Storm does not damage allies and your own units; It does, however, knock them off flying, albeit more lightly than enemy units.
Meteor Storm also has cool 'godpower music' playing while it's being cast.![]()
library TornadoObject requires SafetyQueue, TimerUtils, Group
struct tornadoobject
//******************
//* Tornado Object
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//*
//*
//* ########################################################################################################
//* Config:
//* @ TORNADO_ID - the unit ID of the tornado visual unit.
//*
//* @ TORNADO_VISUAL_COUNT - the amount of tornado visuals created upon construction.
//* @ TORNADO_DEBRIS_COUNT - the amount of tornado debris visuals created upon construction.
//*
//* @ DAMAGE_FREQUENCY - the frequency enemies are damaged within the 'outerRadius'.
//* @ MOTION_UPDATE_FREQUENCY - the frequency at which motion is updated amongst tornado objects.
//*
//* @ TORNADO_OFFSET_LIMIT - the tornado visuals will be offset by a maximum of this value.
//* @ TORNADO_SCALE_MINIMUM - the smallest scale-size a tornado may have.
//* @ TORNADO_SCALE_MAXIMUM - the largest scale-size a tornado may have.
//*
//* @ DAMAGE_PER_SECOND - the damage dealt to enemies within a second.
//* ----
public static constant integer TORNADO_ID = 'hsor'
public static constant integer TORNADO_VISUAL_COUNT = 3
public static constant integer TORNADO_DEBRIS_COUNT = 4
public static constant real DAMAGE_FREQUENCY = 0.1
public static constant real MOTION_UPDATE_FREQUENCY = 0.033
public static constant real TORNADO_OFFSET_LIMIT = 30.00
public static constant real TORNADO_SCALE_MINIMUM = 1.4
public static constant real TORNADO_SCALE_MAXIMUM = 1.7
public static real array DAMAGE_PER_SECOND
//*
//*
//* ########################################################################################################
//*
//*
//* Members:
//*
//* ----
private unit originCaster = null
private player casterPlayer = null
private integer level
private unit array visualDummy [thistype.TORNADO_VISUAL_COUNT]
private tornadodebris array debrisDummy [thistype.TORNADO_DEBRIS_COUNT]
private extgroup effectGroup
private real x
private real y
private real outerRadius
private real innerRadius
private timer damageTimer = null
private timer motionTimer = null
//*
//*
//* Method: onDestroyGroupEnum ()
//* Iterates through the group 'effectGroup' to reset some of the states that may have been altered
//* during the spell such as invulnerability and pause-state.
//*
//* Uses the 'enumTempObject' member defined below to carry data to another function.
//* ----
private static method onDestroyGroupEnum takes nothing returns nothing
local unit en = GetEnumUnit()
call SetUnitFlyHeight(en, 0, 20000)
call SetUnitTimeScale(en, 1)
call PauseUnitSafe(en, false)
call SetUnitInvulnerableSafe(en, false)
call UnitDamageTarget(enumTempObject.originCaster, en, GetWidgetLife(en)*2, false, false, /*
*/ ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
set en = null
endmethod
//*
//*
//* Destructor:
//*
//* ----
method onDestroy takes nothing returns nothing
local integer i = 0
loop // destroy tornado visuals
exitwhen i == TORNADO_VISUAL_COUNT
call KillUnit(visualDummy[i])
set i = i + 1
endloop
set i = 0
loop // destroy tornado debris visuals
exitwhen i == TORNADO_DEBRIS_COUNT
call debrisDummy[i].destroy()
set i = i + 1
endloop
set enumTempObject = this
call ForGroup(effectGroup.g, function thistype.onDestroyGroupEnum)
call effectGroup.destroy()
call ReleaseTimer(damageTimer)
call ReleaseTimer(motionTimer)
endmethod
//*
//*
//* Method: createTornadoVisual ()
//* Creates a tornado unit for visual effect at an offset location to the given coordinates.
//* ----
private static real tempDist
private static real tempAngl
private static real tempX
private static real tempY
private static unit tempReturn
static method createTornadoVisual takes real x, real y, real scale returns unit
set tempDist = GetRandomReal(0, TORNADO_OFFSET_LIMIT)
set tempAngl = GetRandomReal(0, 2*bj_PI)
set tempX = x + tempDist * Cos(tempAngl)
set tempY = y + tempDist * Sin(tempAngl)
set tempReturn = CreateUnit(Player(12), TORNADO_ID, tempX, tempY, GetRandomReal(0, 360))
call SetUnitX(tempReturn, tempX)
call SetUnitY(tempReturn, tempY)
call SetUnitScale(tempReturn, scale, scale, scale)
call SetUnitTimeScale(tempReturn, 0.4)
call extunit[tempReturn].applyFader(255, 255, 200, 0, 255, 5.0)
return tempReturn
endmethod
//*
//*
//* Constructor:
//* Creates a tornado-object given coordinates and values for inner/outer radius, respectively.
//* ----
static method create takes unit caster, integer lvl, real x, real y, real radius1, real radius2 returns thistype
local thistype t = allocate()
local integer i
set t.x = x
set t.y = y
set t.originCaster = caster
set t.casterPlayer = GetOwningPlayer(caster)
set t.level = lvl
set t.effectGroup = extgroup.create()
if radius1 > radius2 then
set t.innerRadius = radius2
set t.outerRadius = radius1
else
set t.innerRadius = radius1
set t.outerRadius = radius2
endif
set i = 0
loop
exitwhen i == TORNADO_VISUAL_COUNT
set t.visualDummy[i] = createTornadoVisual(x, y, /*
*/ GetRandomReal(TORNADO_SCALE_MINIMUM, TORNADO_SCALE_MAXIMUM))
set i = i + 1
endloop
set t.damageTimer = NewTimer()
call SetTimerData(t.damageTimer, t)
call TimerStart(t.damageTimer, DAMAGE_FREQUENCY, true, function thistype.onDamageInterval)
set t.motionTimer = NewTimer()
call SetTimerData(t.motionTimer, t)
call TimerStart(t.motionTimer, MOTION_UPDATE_FREQUENCY, true, function thistype.onMotionInterval)
return t
endmethod
//*
//*
//* Method: onMotionIterate ()
//* Iterates through the group's contents and updates. There are a lot of execution trees here,
//* so to clarify what this is doing...
//*
//* "onMotionInterval" is executed after the tornado has been created on a periodic interval. The
//* timer "motionTimer" is responsible for this. On each execution of "onMotionInterval", the
//* members of the group "effectGroup" are iterated through.
//* ----
private static method onMotionIterate takes nothing returns nothing
local unit en = GetEnumUnit()
local real newX
local real newY
local real angl = Atan2(enumTempObject.y - GetUnitY(en), enumTempObject.x - GetUnitX(en))
local real rnd = GetRandomReal(-bj_PI/16, bj_PI/16)
if IsUnitInRangeXY(en, enumTempObject.x, enumTempObject.y, enumTempObject.innerRadius) then
set newX = GetUnitX(en) + 11 * Cos(angl+bj_PI/2+rnd)
set newY = GetUnitY(en) + 11 * Sin(angl+bj_PI/2+rnd)
call SetUnitFlyHeight(en, GetUnitFlyHeight(en)+1, 0)
else
set newX = GetUnitX(en) + 10 * Cos(angl)
set newY = GetUnitY(en) + 10 * Sin(angl)
set newX = newX + 11 * Cos(angl+bj_PI/2)
set newY = newY + 11 * Sin(angl+bj_PI/2)
endif
call SetUnitX(en, newX)
call SetUnitY(en, newY)
set en = null
endmethod
//*
//*
//* Method: onMotionInterval ()
//* This method uses the 'enumTempObject' which is defined below under 'onDamageInterval ()'.
//* ----
private static method onMotionInterval takes nothing returns nothing
set enumTempObject = GetTimerData(GetExpiredTimer())
call ForGroup(enumTempObject.effectGroup.g, function thistype.onMotionIterate)
endmethod
//*
//*
//* Method: onDamageFilter ()
//* This will damage nearby enemies to the tornado. The interval method is defined below which is
//* executed on a periodic basis, though similar to "onMotionInterval" it simply allocates the
//* iterative work-load to this method.
//* ----
private static method onDamageFilter takes nothing returns boolean
local boolean isValid = true
local unit filt = GetFilterUnit()
local thistype temp = enumTempObject
if not IsUnitInGroup(filt, temp.effectGroup.g) then
if not IsUnitEnemy(filt, temp.casterPlayer) or /*
*/ IsUnitType(filt, UNIT_TYPE_MAGIC_IMMUNE) then
set isValid = false
endif
if isValid then
if (DAMAGE_PER_SECOND[temp.level] * DAMAGE_FREQUENCY) >= GetWidgetLife(filt) then
if not (GetWidgetLife(filt) < 0.405) then
call SetUnitInvulnerableSafe(filt, true)
call PauseUnitSafe(filt, true)
call SelectUnit(filt, false)
call SetUnitTimeScale(filt, 6)
call UnitAddAbility(filt, 'Amrf')
call UnitRemoveAbility(filt, 'Amrf')
call GroupAddUnit(temp.effectGroup.g, filt)
endif
else
call UnitDamageTarget(temp.originCaster, filt, /*
*/ DAMAGE_PER_SECOND[temp.level] * DAMAGE_FREQUENCY, /*
*/ false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
endif
endif
endif
set filt = null
return false
endmethod
//*
//*
//* Method: onDamageInterval ()
//* On each damage interval nearby enemies are enumerated and dealt damage.
//* ----
private static group enumGroup = CreateGroup()
private static boolexpr enumFilter = null
private static thistype enumTempObject
private static method onDamageInterval takes nothing returns nothing
set enumTempObject = GetTimerData(GetExpiredTimer())
call GroupEnumUnitsInRange(enumGroup, enumTempObject.x, enumTempObject.y, /*
*/ enumTempObject.outerRadius, enumFilter)
endmethod
//*
//*
//* Initialization:
//*
//* ----
private static method onInit takes nothing returns nothing
set enumFilter = Filter(function thistype.onDamageFilter)
set DAMAGE_PER_SECOND[0] = 250.00
set DAMAGE_PER_SECOND[1] = 350.00
endmethod
//*
//*
//**********************************************************************************************************
endstruct
endlibrary
scope Tornado
struct tornado extends spell
//******************
//* Tornado
//* ¯¯¯¯¯¯¯
//* The spell-effect should be found in the "onSpellEffect" method.
//*
//*
//* ########################################################################################################
//* Config
//* @ ABIL_ID - the raw-code ability ID for the spell.
//* @ DURATION - the duration that the tornado will last until destruction.
//* ----
public static constant integer ABIL_ID = 'A000'
public static constant real DURATION = 25.00
//*
//*
//* ########################################################################################################
//*
//*
//* Method: onSpellExpire ()
//* Executes after the spell has been cast and the duration has expired. This will simply destroy
//* the tornado object which was created on spell effect.
//* ----
private static method onSpellExpire takes nothing returns nothing
call tornadoobject(GetTimerData(GetExpiredTimer())).destroy()
call ReleaseTimer(GetExpiredTimer())
endmethod
//*
//*
//* Method: onSpellEffect ()
//* Executes spell actions. User-interfaced method.
//* ----
method onSpellEffect takes nothing returns nothing
local timer t = NewTimer()
local tornadoobject obj = tornadoobject.create(GetTriggerUnit(), /*
*/ GetUnitAbilityLevel(GetTriggerUnit(), ABIL_ID), GetSpellTargetX(), GetSpellTargetY(), 80, 800)
call SetTimerData(t, obj)
call TimerStart(t, DURATION, false, function thistype.onSpellExpire)
set t = null
endmethod
//*
//*
//* Initialization:
//* Initialize 'tornado' spell struct.
//* ----
private static method onInit takes nothing returns nothing
call thistype.create(ABIL_ID)
endmethod
//*
//*
//**********************************************************************************************************
endstruct
endscope
library Unit requires AutoIndex, /*
*/ optional UnitTargetModule, /*
*/ optional UnitDamageModule, /*
*/ optional UnitFaderModule
struct extunit extends extunitinterface
//******************
//* Extended Unit
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯
//* The extended unit struct is implemented with AutoIndex because it is truly one of the easiest to
//* interface with for casual purposes, or at least to my standards.
//*
//* Modules can be implemented (as they are below) that add functionality in terms of API methods and
//* interface methods which make the unit struct very easy to work with.
//*
//*
//* Optional Modules:
//* @ UnitDamageModule - provides registration of unit structs in a damage-detection engine.
//* @ UnitTargetModule - provides an API for gathering unit targeting information.
//* @ UnitFaderModule - provides an API for fading a unit in alpha color.
//* ----
implement optional UnitDamageModule
implement optional UnitTargetModule
implement optional UnitFaderModule
//*
//*
//* Implemented Modules:
//* @ AutoCreate - provides automatic creation of 'extunit' structs for new units.
//* @ AutoDestroy - provides automatic recycling of 'extunit' structs when the
//* associated unit is removed from the game.
//* ----
implement AutoCreate
implement AutoDestroy
//*
//*
//**********************************************************************************************************
endstruct
endlibrary
library UnitFader
module UnitFaderModule
//******************
//* Unit Fader Module
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* Provides an API to the 'extunit' struct to fade a unit from a set starting alpha to a set final alpha. The
//* unit-fader comes with a method to determine whether or not a unit is being faded, but additional calls to
//* the unit-fader will simply over-ride each other.
//*
//*
//* Timer Members:
//* Variable members associated with the timed updates of the fader.
//* ----
private static timer fadeTimer = CreateTimer()
private static constant real fadeTimeout = 0.1
//*
//*
//* Stack Members:
//* Variable members that maintain a stack of units that are being told to fade.
//* ----
private static thistype array fadeStack
private static integer fadeStackSize = 0
private integer fadeStackIndex
private boolean fadeStackIn = false
//*
//*
//* Fade Data Members:
//* Data associated with the fade components and coloring components of the unit.
//* ----
private integer fadeVertexRed
private integer fadeVertexBlue
private integer fadeVertexGreen
private integer fadeVertexAlpha
private integer fadeVertexAlphaStep
private integer fadeVertexAlphaFinal
private real fadeTimeLeft
//*
//*
//* Method: removeFader ()
//* Removes the unit-fader from the stack. By the time 'removeFader()' is called the unit's final
//* alpha should be the same value given upon application.
//* ----
method removeFader takes nothing returns nothing
set fadeStackSize = fadeStackSize - 1
set fadeStack[fadeStackIndex] = fadeStack[fadeStackSize]
set fadeStack[fadeStackIndex].fadeStackIndex = fadeStackIndex
if fadeStackSize == 0 then
call PauseTimer(fadeTimer)
endif
endmethod
//*
//* Method: fadeRefresh ()
//* Updates the stack with appropriate fade levels.
//* ----
private static method fadeRefresh takes nothing returns nothing
local integer i = fadeStackSize - 1
local thistype d
loop
exitwhen i < 0
set d = fadeStack[i]
if d != 0 then
set d.fadeTimeLeft = d.fadeTimeLeft - fadeTimeout
if d.fadeTimeLeft <= 0.00 then
set d.fadeVertexAlpha = d.fadeVertexAlphaFinal
call SetUnitVertexColor(d.me, d.fadeVertexRed, d.fadeVertexGreen, /*
*/ d.fadeVertexBlue, d.fadeVertexAlpha)
// The unit-fader is complete and can be removed from the stack.
call d.removeFader()
else
set d.fadeVertexAlpha = R2I(d.fadeVertexAlpha + d.fadeVertexAlphaStep * fadeTimeout)
call SetUnitVertexColor(d.me, d.fadeVertexRed, d.fadeVertexGreen, /*
*/ d.fadeVertexBlue, d.fadeVertexAlpha)
endif
endif
set i = i - 1
endloop
endmethod
//*
//*
//* Method: applyFader ()
//* Applies the fader to a unit, adding the unit object to the stack so it can be updated.
//* ----
method applyFader takes integer red, integer grn, integer blu, /*
*/ integer alpha1, integer alpha2, real duration returns nothing
if fadeStackSize == 0 then
// The fade-stack is empty.
call TimerStart(fadeTimer, fadeTimeout, true, function thistype.fadeRefresh)
endif
if not fadeStackIn then
set fadeStack[fadeStackSize] = this
set fadeStackIndex = fadeStackSize
set fadeStackSize = fadeStackSize + 1
endif
call SetUnitVertexColor(me, red, grn, blu, alpha1)
set fadeVertexRed = red
set fadeVertexBlue = blu
set fadeVertexGreen = grn
set fadeVertexAlpha = alpha1
set fadeVertexAlphaStep = R2I((alpha2 - alpha1) / duration)
set fadeVertexAlphaFinal = alpha2
set fadeTimeLeft = duration
endmethod
//*
//*
//*
//**********************************************************************************************************
endmodule
endlibrary
library Spell requires SpellInterface, SpellSetupModule
struct spell extends spellinterface
//******************
//* Spell
//* ¯¯¯¯¯
//* Allows a fairly convenient interface for referencing spell-related data. Once a spell has been
//* created it is given an ID. This ID can be used to reference the spell struct.
//*
//* When you are comfortable to customize your spell, simply extend the 'spell' struct and define your
//* own actions for "onSpellEffect", or one of the other interface events.
//*
//* Each spell event must have the parameters for the caster of the spell, a target of some type, and
//* the level of the spell when it was cast. The target types are:
//* - Unit Target
//* - Point Target
//* - No Target
//*
//* If "0" is given as the target then it will know there is no target. If an object of type
//* "spelltargetunit" is given then it is a unit-target (target will have .targetUnit() method) or
//* if "spelltargetarea" is given then it is a point-target.
//*
//*
//* Spell Members:
//* @ id - the raw-code or integer ID of the spell.
//* ----
public integer id
//*
//*
//* System Members:
//* @ table - the hash table used to cross-reference spells and spell IDs.
//* ----
private static hashtable table = InitHashtable()
//*
//*
//* Operators:
//* These are used to make interfacing with the spell struct a little more convenient.
//* ----
static method operator [] takes integer id returns thistype
if HaveSavedInteger(table, id, 0) then
return LoadInteger(table, id, 0)
endif
return 0
endmethod
//*
//* Method: verify ()
//* Verifies whether or not a specific integer ID is already being used by a spell. The integer-ID
//* of the spell should be able to transform to the spell struct that stores it.
//* ----
private static method verify takes integer id returns boolean
return not HaveSavedInteger(table, id, 0)
endmethod
//*
//*
//* Method: register ()
//* Registers a spell ID to the spell struct system so that the ID cannot be shared. This also
//* allows the reference of spell structs directly from the spell IDs.
//* ----
private static method register takes integer id, thistype sp returns nothing
call SaveInteger(table, id, 0, sp)
endmethod
//*
//*
//* Destructor:
//* Destroys a spell struct, unregistering its ID.
//* ----
method onDestroy takes nothing returns nothing
call RemoveSavedInteger(table, id, 0)
endmethod
//*
//* Constructor:
//* Creates a spell struct with an ID. The spell is cross-referenced with the spell ID and can
//* be obtained from the spell ID with the syntax "spell[ ID ]". Spells may not share IDs.
//* ----
static method create takes integer id returns thistype
local thistype sp = 0
if verify(id) then
set sp = allocate()
set sp.id = id
call register(id, sp)
endif
return sp
endmethod
//*
//*
//* Implemented Modules:
//* @ SpellSetupModule - provides a setup for the spell struct that registers events to several
//* triggers so that they can be extended to the user interface.
//* ----
implement SpellSetupModule
//*
//*
//**********************************************************************************************************
endstruct
endlibrary
library Group
struct extgroup
public group g
method onDestroy takes nothing returns nothing
call GroupClear(g)
endmethod
static method create takes nothing returns thistype
local thistype s = allocate()
if (s.g == null) then
set s.g = CreateGroup()
endif
return s
endmethod
endstruct
endlibrary
Okey, I'll implement that tomorrow. Not sure if I'll find fitting "godpower music" though without importing anything.
Well,the guy should post the link himself,it will be much more neat ^^If anyone needs a video of his spell, let me know.
TEEHEE
-Berz- said:Now good luck guys and girls and may the best "copy pasta" spell wins x)
what recording prog are you using?Yeah sure. I'll edit this post with the videos.
Uploading . . .
Uploaded.
what recording prog are you using?
Purgatory Constant

Events(On)


Time - Elapsed game time is 0.01 seconds

Conditions

Actions


Set PgFHUp = 80.00


Set PgLateralSpeed = 5.00


Set PgSpiralAngle = 20.00


Set PgSizeCylinder = 150.00


Set PgSizeExplosion = 300.00


Set PgSpeed = 0.10


Set PgSpell = Purgatory
Purgatory Init(On)

Events


Unit - A unit Starts the effect of an ability

Conditions


(Ability being cast) Equal to Purgatory

Actions


If (All Conditions are True) then do (Then Actions) else do (Else Actions)



If - Conditions




PgB Equal to 0



Then - Actions




Trigger - Turn on Purgatory Periodic <gen>



Else - Actions


Set PgB = (PgB + 1)


Set PgA = (PgA + 1)


Set PgCaster[PgA] = (Triggering unit)


Set PgLevel = (Level of PgSpell for PgCaster[PgA])


Set PgIntDmgPart = ((1.00 + (2.00 x (Real(PgLevel)))) x (Real((Intelligence of PgCaster[PgA] (Include bonuses)))))


Set PgBonusDmgPart = (50.00 x (Real(PgLevel)))


Set PgDamage[PgA] = (PgIntDmgPart + PgBonusDmgPart)


Set PgTargetPoint[PgA] = (Target point of ability being cast)


Set PgOwner[PgA] = (Owner of PgCaster[PgA])


Set PgMaxAOE[PgA] = (200.00 + (100.00 x (Real(PgLevel))))


Set PgCurrentAOE[PgA] = 100.00


Set PgAngleLeft1 = 360.00


Set PgAngleRight1 = 0.00


Set PgAngleLeft2 = 450.00


Set PgAngleRight2 = 90.00


Set PgAngleLeft3 = 540.00


Set PgAngleRight3 = 180.00


Set PgAngleLeft4 = 630.00


Set PgAngleRight4 = 270.00


Set PgFlyingHeight = 0.00


For each (Integer A) from 1 to 10, do (Actions)



Loop - Actions




-------- ------------------------------------------------------------------------------------------------------------------------------------------------------------ --------




Set PgSpiralPointL1 = (PgTargetPoint[PgA] offset by PgCurrentAOE[PgA] towards PgAngleLeft1 degrees)




Set PgSpiralPointL2 = (PgTargetPoint[PgA] offset by PgCurrentAOE[PgA] towards PgAngleLeft2 degrees)




Set PgSpiralPointL3 = (PgTargetPoint[PgA] offset by PgCurrentAOE[PgA] towards PgAngleLeft3 degrees)




Set PgSpiralPointL4 = (PgTargetPoint[PgA] offset by PgCurrentAOE[PgA] towards PgAngleLeft4 degrees)




-------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --------




Unit - Create 1 PurgDummy[Cylindre] for PgOwner[PgA] at PgSpiralPointL1 facing 0.00 degrees




Set PgCylinderDummy[PgA] = (Last created unit)




Unit - Set the custom value of PgCylinderDummy[PgA] to (Integer(PgAngleLeft1))




Animation - Change PgCylinderDummy[PgA]'s size to (PgSizeCylinder%, PgSizeCylinder%, (2.00 x PgSizeCylinder)%) of its original size




Animation - Change PgCylinderDummy[PgA] flying height to PgFlyingHeight at 0.00




Unit Group - Add PgCylinderDummy[PgA] to PgDummyGroup[PgA]




-------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --------




Unit - Create 1 PurgDummy[Cylindre] for PgOwner[PgA] at PgSpiralPointL2 facing 0.00 degrees




Set PgCylinderDummy[PgA] = (Last created unit)




Unit - Set the custom value of PgCylinderDummy[PgA] to (Integer(PgAngleLeft2))




Animation - Change PgCylinderDummy[PgA]'s size to (PgSizeCylinder%, PgSizeCylinder%, (2.00 x PgSizeCylinder)%) of its original size




Animation - Change PgCylinderDummy[PgA] flying height to PgFlyingHeight at 0.00




Unit Group - Add PgCylinderDummy[PgA] to PgDummyGroup[PgA]




-------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --------




Unit - Create 1 PurgDummy[Cylindre] for PgOwner[PgA] at PgSpiralPointL3 facing 0.00 degrees




Set PgCylinderDummy[PgA] = (Last created unit)




Unit - Set the custom value of PgCylinderDummy[PgA] to (Integer(PgAngleLeft3))




Animation - Change PgCylinderDummy[PgA]'s size to (PgSizeCylinder%, PgSizeCylinder%, (2.00 x PgSizeCylinder)%) of its original size




Animation - Change PgCylinderDummy[PgA] flying height to PgFlyingHeight at 0.00




Unit Group - Add PgCylinderDummy[PgA] to PgDummyGroup[PgA]




-------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --------




Unit - Create 1 PurgDummy[Cylindre] for PgOwner[PgA] at PgSpiralPointL4 facing 0.00 degrees




Set PgCylinderDummy[PgA] = (Last created unit)




Unit - Set the custom value of PgCylinderDummy[PgA] to (Integer(PgAngleLeft4))




Animation - Change PgCylinderDummy[PgA]'s size to (PgSizeCylinder%, PgSizeCylinder%, (2.00 x PgSizeCylinder)%) of its original size




Animation - Change PgCylinderDummy[PgA] flying height to PgFlyingHeight at 0.00




Unit Group - Add PgCylinderDummy[PgA] to PgDummyGroup[PgA]




Set PgAngleLeft1 = (PgAngleLeft1 - PgSpiralAngle)




Set PgAngleLeft2 = (PgAngleLeft2 - PgSpiralAngle)




Set PgAngleLeft3 = (PgAngleLeft3 - PgSpiralAngle)




Set PgAngleLeft4 = (PgAngleLeft4 - PgSpiralAngle)




-------- ------------------------------------------------------------------------------------------------------------------------------------------------------------ --------




Set PgSpiralPointR1 = (PgTargetPoint[PgA] offset by PgCurrentAOE[PgA] towards PgAngleRight1 degrees)




Set PgSpiralPointR2 = (PgTargetPoint[PgA] offset by PgCurrentAOE[PgA] towards PgAngleRight2 degrees)




Set PgSpiralPointR3 = (PgTargetPoint[PgA] offset by PgCurrentAOE[PgA] towards PgAngleRight3 degrees)




Set PgSpiralPointR4 = (PgTargetPoint[PgA] offset by PgCurrentAOE[PgA] towards PgAngleRight4 degrees)




-------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --------




Unit - Create 1 PurgDummy[Cylindre] for PgOwner[PgA] at PgSpiralPointR1 facing 0.00 degrees




Set PgCylinderDummy[PgA] = (Last created unit)




Unit - Set the custom value of PgCylinderDummy[PgA] to (Integer(PgAngleRight1))




Animation - Change PgCylinderDummy[PgA]'s size to (PgSizeCylinder%, PgSizeCylinder%, (2.00 x PgSizeCylinder)%) of its original size




Animation - Change PgCylinderDummy[PgA] flying height to PgFlyingHeight at 0.00




Unit Group - Add PgCylinderDummy[PgA] to PgDummyGroup[PgA]




-------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --------




Unit - Create 1 PurgDummy[Cylindre] for PgOwner[PgA] at PgSpiralPointR2 facing 0.00 degrees




Set PgCylinderDummy[PgA] = (Last created unit)




Unit - Set the custom value of PgCylinderDummy[PgA] to (Integer(PgAngleRight2))




Animation - Change PgCylinderDummy[PgA]'s size to (PgSizeCylinder%, PgSizeCylinder%, (2.00 x PgSizeCylinder)%) of its original size




Animation - Change PgCylinderDummy[PgA] flying height to PgFlyingHeight at 0.00




Unit Group - Add PgCylinderDummy[PgA] to PgDummyGroup[PgA]




-------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --------




Unit - Create 1 PurgDummy[Cylindre] for PgOwner[PgA] at PgSpiralPointR3 facing 0.00 degrees




Set PgCylinderDummy[PgA] = (Last created unit)




Unit - Set the custom value of PgCylinderDummy[PgA] to (Integer(PgAngleRight3))




Animation - Change PgCylinderDummy[PgA]'s size to (PgSizeCylinder%, PgSizeCylinder%, (2.00 x PgSizeCylinder)%) of its original size




Animation - Change PgCylinderDummy[PgA] flying height to PgFlyingHeight at 0.00




Unit Group - Add PgCylinderDummy[PgA] to PgDummyGroup[PgA]




-------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --------




Unit - Create 1 PurgDummy[Cylindre] for PgOwner[PgA] at PgSpiralPointR4 facing 0.00 degrees




Set PgCylinderDummy[PgA] = (Last created unit)




Unit - Set the custom value of PgCylinderDummy[PgA] to (Integer(PgAngleRight4))




Animation - Change PgCylinderDummy[PgA]'s size to (PgSizeCylinder%, PgSizeCylinder%, (2.00 x PgSizeCylinder)%) of its original size




Animation - Change PgCylinderDummy[PgA] flying height to PgFlyingHeight at 0.00




Unit Group - Add PgCylinderDummy[PgA] to PgDummyGroup[PgA]




Set PgAngleRight1 = (PgAngleRight1 + PgSpiralAngle)




Set PgAngleRight2 = (PgAngleRight2 + PgSpiralAngle)




Set PgAngleRight3 = (PgAngleRight3 + PgSpiralAngle)




Set PgAngleRight4 = (PgAngleRight4 + PgSpiralAngle)




-------- ------------------------------------------------------------------------------------------------------------------------------------------------------------ --------




Set PgFlyingHeight = (PgFlyingHeight + PgFHUp)




Custom script: call RemoveLocation(udg_PgSpiralPointL1)




Custom script: call RemoveLocation(udg_PgSpiralPointL2)




Custom script: call RemoveLocation(udg_PgSpiralPointL3)




Custom script: call RemoveLocation(udg_PgSpiralPointL4)




Custom script: call RemoveLocation(udg_PgSpiralPointR1)




Custom script: call RemoveLocation(udg_PgSpiralPointR2)




Custom script: call RemoveLocation(udg_PgSpiralPointR3)




Custom script: call RemoveLocation(udg_PgSpiralPointR4)
Purgatory Periodic(Off)

Events


Time - Every 0.04 seconds of game time

Conditions

Actions


For each (Integer Pg) from 1 to PgA, do (Actions)



Loop - Actions




Unit Group - Pick every unit in PgDummyGroup[Pg] and do (Actions)





Loop - Actions






Set PgCylinderDummy[Pg] = (Picked unit)






Set PgMovingAngle[Pg] = ((Real((Custom value of PgCylinderDummy[Pg]))) + PgLateralSpeed)






Set PgMovePoint[Pg] = (PgTargetPoint[Pg] offset by PgCurrentAOE[Pg] towards PgMovingAngle[Pg] degrees)






Unit - Move PgCylinderDummy[Pg] instantly to PgMovePoint[Pg]






Set PgCurrentAOE[Pg] = (PgCurrentAOE[Pg] + PgSpeed)






Unit - Set the custom value of PgCylinderDummy[Pg] to (Integer(PgMovingAngle[Pg]))






Custom script: call RemoveLocation(udg_PgMovePoint[udg_Pg])






If (All Conditions are True) then do (Then Actions) else do (Else Actions)







If - Conditions








PgCurrentAOE[Pg] Greater than or equal to PgMaxAOE[Pg]







Then - Actions








Unit Group - Add all units of PgDummyGroup[Pg] to PgDummyGroup2[Pg]








Custom script: call DestroyGroup(udg_PgDummyGroup[udg_Pg])







Else - Actions




Unit Group - Pick every unit in PgDummyGroup2[Pg] and do (Actions)





Loop - Actions






Set PgCylinderDummy[Pg] = (Picked unit)






Set PgMovingAngle[Pg] = ((Real((Custom value of PgCylinderDummy[Pg]))) + PgLateralSpeed)






Set PgMovePoint[Pg] = (PgTargetPoint[Pg] offset by PgCurrentAOE[Pg] towards PgMovingAngle[Pg] degrees)






Unit - Move PgCylinderDummy[Pg] instantly to PgMovePoint[Pg]






Set PgCurrentAOE[Pg] = (PgCurrentAOE[Pg] - PgSpeed)






Unit - Set the custom value of PgCylinderDummy[Pg] to (Integer(PgMovingAngle[Pg]))






Custom script: call RemoveLocation(udg_PgMovePoint[udg_Pg])






If (All Conditions are True) then do (Then Actions) else do (Else Actions)







If - Conditions








PgCurrentAOE[Pg] Less than or equal to 50.00







Then - Actions








Unit - Kill PgCylinderDummy[Pg]








Unit - Create 1 PurgDummy[Final Explosion] for PgOwner[Pg] at PgTargetPoint[Pg] facing 0.00 degrees








Set PgExplosionDummy[Pg] = (Last created unit)








Set PgExplosionPoint[Pg] = (Position of PgExplosionDummy[Pg])








Unit - Add a 2.00 second Generic expiration timer to PgExplosionDummy[Pg]








Animation - Change PgExplosionDummy[Pg]'s size to (PgSizeExplosion%, PgSizeExplosion%, (2.00 x PgSizeExplosion)%) of its original size








Set PgTargetGroup = (Units within PgMaxAOE[Pg] of PgExplosionPoint[Pg])








Unit Group - Pick every unit in PgTargetGroup and do (Actions)









Loop - Actions










Set PgTarget = (Picked unit)










If (All Conditions are True) then do (Then Actions) else do (Else Actions)











If - Conditions












(PgTarget is A structure) Equal to False












(PgTarget is Magic Immune) Equal to False












(PgTarget belongs to an enemy of PgOwner[Pg]) Equal to True











Then - Actions












Unit - Cause PgCaster[Pg] to damage PgTarget, dealing PgDamage[Pg] damage of attack type Spells and damage type Normal











Else - Actions








Custom script: call RemoveLocation(udg_PgExplosionPoint[udg_Pg])








Custom script: call DestroyGroup(udg_PgTargetGroup)








Custom script: call RemoveLocation(udg_PgTargetPoint[udg_Pg])








Unit Group - Remove PgCylinderDummy[Pg] from PgDummyGroup2[Pg]








Set PgB = (PgB - 1)








If (All Conditions are True) then do (Then Actions) else do (Else Actions)









If - Conditions










PgB Equal to 0










(PgDummyGroup[Pg] is empty) Equal to True










(PgDummyGroup2[Pg] is empty) Equal to True









Then - Actions










Set PgA = 0










Trigger - Turn off Purgatory Periodic <gen>









Else - Actions







Else - Actions
