• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Zephyr Contest #14 - Unique Summoning

Status
Not open for further replies.
Level 9
Joined
Oct 14, 2013
Messages
238
And why tell this now? You couldn't tell me this earlier?

I'm not an originality inspector here, I just checked your entry and gave my honest opinion. If it's your idea, well, it's OK then. But I thought maybe you need to know about it before you can modify it. Just trying to help here and no offense intended.
 
Level 33
Joined
Apr 24, 2012
Messages
5,113
Contestants should not review other's work, that gives them advantage :)

as for Raynor's ship and Flux's Spell, it's up to the eye of the judges

For me, the spell's originality is not a bit unique ( I have seen so many spells/scenes of that spell from many games) but how the spell is made that what makes it unique (come on, just look at that awesome range indicator)
 
Level 9
Joined
Oct 14, 2013
Messages
238
Contestants should not review other's work
I did not review his entry. But I find leaving other contestants in the dark, in order to increase one's own chance of winning is a bit unfair. And also notifying others of the existing pitfalls, increases the quality of the contest. I'd like to compete against the best, not slip through by the mistakes that others make (Of course, if there are any mistakes, at all)
 
Level 4
Joined
Apr 28, 2016
Messages
33
You need to reconfigure the names of your variables; look at the other entries to find out.

And by the way I don't think there is a need for Aghanim mode in this contest. Aghanim is only for DotA, and if it changes your spell's nature I think it is counted as 2 versions of your spell, which I think, completely from a personal viewpoint, will have negative score for you.

So, what must i'm going to do? Editing my map and my entries, is that allowed in this contest? :/
 

Kyrbi0

Arena Moderator
Level 45
Joined
Jul 29, 2008
Messages
9,492
Contestants should not review other's work, that gives them advantage :)
There's a difference between "reviewing" and "commenting", though. If the point is to discourage discussion between Contestants, well then, why even bother with a Contest thread, or WIP posts or anything? All of that is to get people talking, communicating, sharing, and exciting one another with the thrill of a good competition.

Some of my favorite Contests have been ones where the entrants weren't afraid/felt free to offer comments, tips, pointers, etc to the other entrants; in fact, they were sharing whole sections of code & discussing the pros/cons of various design elements. It was a real positive, collaborative environment, and extra-fun for it.

The actual nitty-gritty design & implementation, of course, must come from the individual, but there's no harm in talking & sharing & helping; no one likes to lose because of (the equivalent of) a spelling error, right?

^See?

That's what I meant of giving advantage.
He's... confused & asking a question? Don't get it.
 

Kyrbi0

Arena Moderator
Level 45
Joined
Jul 29, 2008
Messages
9,492
While it may seem nice to offer tips and tricks it's stupid since your helping an opponent.
I'm sorry you feel that way, man. I dream of a better world; one where cooperation is better than competition. I may not always live that to the max, but I believe we are all enriched when both we & our "opponents" are at our best. Who wants to win against a cripple (figuratively speaking)?
 
Level 14
Joined
Jul 1, 2008
Messages
1,314
I'm sorry you feel that way, man. I dream of a better world; one where cooperation is better than competition. I may not always live that to the max, but I believe we are all enriched when both we & our "opponents" are at our best. Who wants to win against a cripple (figuratively speaking)?

I support your way of thinking by 100%! Feels like "Fremantle" spirit - good ol' home :D

I thought, I was not allowed to comment other people's spells.

Anyway, if you help someone, this does not matter much in this kind of contest, since you got to be creative and hope, that the judges love your idea more than others. I dont think you will lose only because of minor coding, if your idea is pretty neat. And anyway so what? Its better to create something awesome!
I know this is OT, but I want to add, that this is the reason why I think that protecting maps is not helpful for anybody.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
Seems silly to me.
That's like saying "I want to lose so I'll give them a handicap" (Or, "I am much better than them, they need all the help they can get to stand a chance.")

Saying that it looks nice, or the concept is interesting etc is fine. But offering code advise.. nope nope.
Not until the results are in anyway.

I am all for helping, I do that a lot. But not in a contest.
 
Level 14
Joined
Jul 1, 2008
Messages
1,314
I am all for helping, I do that a lot. But not in a contest.

Nobody would doubt that, I guess :)

Saying that it looks nice, or the concept is interesting etc is fine. But offering code advise.. nope nope.

Makes sense too, but giving the same tools to everybody makes it more interesting, I think. Lets say for example, someone is not able to figure out how to calculate a jumping motion, then I would rather help him finding the formula rather than leaving him and knowing he will lose a 100% just because he can't do the math. Maybe he would have created a hell of a jump if I helped him. Not saying how exactly he should do, I think just providing the basic stuff would be fair ... Like that you would still win most probably, but the other contestant would have a chance to develop something at least ..
Depends on the type of contest and what you are helping with, of course. If the contest was about finding the best jumping motion, it would be rather pointless, I agree. But still, the other one would lose in this case because of copying your stuff, so ...
 
Level 22
Joined
Aug 27, 2013
Messages
3,973
This is a contest and contest is all about competition. If one is not ready for a competition then he shouldn't join. Why does one want to participate in a contest? Because he wants a challenge. To overcome a challenge he must know his own ability whether he could do that or not. That is the reason why a preparation is needed. Prepare everything you need to defeat the other contestants before the contest started. Once it has started, you may only rely on the ability you've prepared. If it's not good enough, you'll lose. That's just how competitions are.

Anyways, I'm going to post my entry real soon!
 
Level 22
Joined
Aug 27, 2013
Messages
3,973
Entry - Hellfire Orb

HELLFIRE ORB
232216-albums6711-picture108891.png

232216-albums6711-picture108892.png

Details

GIFs

Preview



Triggers:
  • HO Config
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- =========================================== --------
      • -------- Input your ability here --------
      • -------- =========================================== --------
      • Set HO_Abil_ID = Hellfire Orb
      • -------- =========================================== --------
      • -------- Input the dummy for your Tree Destroyer here --------
      • -------- =========================================== --------
      • Set HO_TDType = TreeDestroyer
      • -------- =========================================== --------
      • -------- Input your dummies here --------
      • -------- =========================================== --------
      • Set HO_DummyType[1] = Dummy1
      • Set HO_DummyType[2] = Dummy2
      • Set HO_DummyType[3] = Dummy3
      • Set HO_DummyType[4] = Dummy4
      • -------- =========================================== --------
      • -------- Input your minions here --------
      • -------- =========================================== --------
      • Set HO_Minion[1] = Hellfire Minion (Level 1)
      • Set HO_Minion[2] = Hellfire Minion (Level 2)
      • Set HO_Minion[3] = Hellfire Minion (Level 3)
      • -------- =========================================== --------
      • -------- Input the number of your minions here --------
      • -------- =========================================== --------
      • Set HO_Number[1] = 3
      • Set HO_Number[2] = 4
      • Set HO_Number[3] = 5
      • -------- =========================================== --------
      • -------- Input your minion duration here --------
      • -------- =========================================== --------
      • Set HO_MDur[1] = 20.00
      • Set HO_MDur[2] = 20.00
      • Set HO_MDur[3] = 20.00
      • -------- =========================================== --------
      • -------- Input the effects which will be used later --------
      • -------- =========================================== --------
      • Set HO_Effect[1] = FireNova2.mdl
      • Set HO_Effect[2] = Abilities\Spells\Other\Doom\DoomDeath.mdl
      • -------- =========================================== --------
      • -------- Input the line damage when Hellfire orb missile is firstly fired --------
      • -------- =========================================== --------
      • Set HO_Damage[1] = 50.00
      • Set HO_Damage[2] = 75.00
      • Set HO_Damage[3] = 100.00
      • -------- =========================================== --------
      • -------- Input the range for how far the orb missile will travel --------
      • -------- =========================================== --------
      • Set HO_Range[1] = 700.00
      • Set HO_Range[2] = 700.00
      • Set HO_Range[3] = 700.00
      • -------- =========================================== --------
      • -------- Input the speed for the orb missile --------
      • -------- =========================================== --------
      • Set HO_Speed[1] = 30.00
      • Set HO_Speed[2] = 30.00
      • Set HO_Speed[3] = 30.00
      • -------- =========================================== --------
      • -------- Input the area of effect for the orb missile --------
      • -------- =========================================== --------
      • Set HO_AoE[1] = 150.00
      • Set HO_AoE[2] = 150.00
      • Set HO_AoE[3] = 150.00
      • -------- =========================================== --------
      • -------- Input the minimum range for where the hellfire minions will be summoned --------
      • -------- =========================================== --------
      • Set HO_MinR[1] = 150.00
      • Set HO_MinR[2] = 150.00
      • Set HO_MinR[3] = 150.00
      • -------- =========================================== --------
      • -------- Input the maximum range for where the hellfire minions will be summoned --------
      • -------- =========================================== --------
      • Set HO_MaxR[1] = 500.00
      • Set HO_MaxR[2] = 500.00
      • Set HO_MaxR[3] = 500.00
      • -------- =========================================== --------
      • -------- Input the speed for the missile to summon the minion --------
      • -------- =========================================== --------
      • Set HO_Speed2[1] = 25.00
      • Set HO_Speed2[2] = 25.00
      • Set HO_Speed2[3] = 25.00
      • -------- =========================================== --------
      • -------- Input the number of your second missile here (Dummy 4 in this case) --------
      • -------- =========================================== --------
      • Set HO_Number2[1] = 3
      • Set HO_Number2[2] = 3
      • Set HO_Number2[3] = 3
      • -------- =========================================== --------
      • -------- Input the speed for the final missile --------
      • -------- =========================================== --------
      • Set HO_Speed3[1] = 15.00
      • Set HO_Speed3[2] = 15.00
      • Set HO_Speed3[3] = 15.00
      • -------- =========================================== --------
      • -------- Input the max distance for the final missile to travel --------
      • -------- =========================================== --------
      • Set HO_MaxDist[1] = 1000.00
      • Set HO_MaxDist[2] = 1000.00
      • Set HO_MaxDist[3] = 1000.00
      • -------- =========================================== --------
      • -------- Input the final damage when explosion occurs --------
      • -------- =========================================== --------
      • Set HO_Damage2[1] = 200.00
      • Set HO_Damage2[2] = 400.00
      • Set HO_Damage2[3] = 600.00
      • -------- =========================================== --------
      • -------- Input the area of effect for the final explosion --------
      • -------- =========================================== --------
      • Set HO_AoE2[1] = 500.00
      • Set HO_AoE2[2] = 500.00
      • Set HO_AoE2[3] = 500.00
      • -------- =========================================== --------
      • -------- True = Destroy any tree near the spell. False = Doesn't destroy any tree. --------
      • -------- =========================================== --------
      • Set HO_DestroyTree = True
      • -------- =========================================== --------
      • -------- OFF LIMITS - DO NOT CHANGE ANYTHING BELOW --------
      • -------- =========================================== --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • HO_DestroyTree Equal to True
        • Then - Actions
          • Set Point[1] = (Center of (Playable map area))
          • Unit - Create 1 HO_TDType for Neutral Passive at Point[1] facing Default building facing degrees
          • Set HO_TD = (Last created unit)
          • Unit - Hide HO_TD
          • Unit - Make HO_TD Invulnerable
          • Custom script: call RemoveLocation(udg_Point[1])
        • Else - Actions
  • HO Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to HO_Abil_ID
    • Actions
      • -------- =========================================== --------
      • -------- Store the necessary values --------
      • -------- =========================================== --------
      • Set HO_Max_Index = (HO_Max_Index + 1)
      • Set HO_Caster[HO_Max_Index] = (Triggering unit)
      • Set HO_Level[HO_Max_Index] = (Level of HO_Abil_ID for HO_Caster[HO_Max_Index])
      • Set HO_ReachedDistance[HO_Max_Index] = 0.00
      • Set HO_ReachedDistance2[HO_Max_Index] = 0.00
      • Set HO_ReachedDistance3[HO_Max_Index] = 0.00
      • Set HO_TargetPoint[HO_Max_Index] = 0.00
      • Set HO_Counter[HO_Max_Index] = 0.00
      • Set HO_Counter2[HO_Max_Index] = 0
      • -------- =========================================== --------
      • -------- Store the locations --------
      • -------- =========================================== --------
      • Set Point[1] = (Position of HO_Caster[HO_Max_Index])
      • Set Point[2] = (Target point of ability being cast)
      • -------- =========================================== --------
      • -------- Store the angle between locations --------
      • -------- =========================================== --------
      • Set HO_Angle[HO_Max_Index] = (Angle from Point[1] to Point[2])
      • -------- =========================================== --------
      • -------- Create the missile dummy --------
      • -------- =========================================== --------
      • Unit - Create 1 HO_DummyType[1] for (Owner of HO_Caster[HO_Max_Index]) at Point[1] facing HO_Angle[HO_Max_Index] degrees
      • -------- =========================================== --------
      • -------- Store the dummy into a variable --------
      • -------- =========================================== --------
      • Set HO_Dummy1[HO_Max_Index] = (Last created unit)
      • -------- =========================================== --------
      • -------- Create a group to separate the already damaged foes later on --------
      • -------- =========================================== --------
      • Custom script: if udg_HO_DU[udg_HO_Max_Index] == null then
      • Custom script: set udg_HO_DU[udg_HO_Max_Index] = CreateGroup()
      • Custom script: endif
      • -------- =========================================== --------
      • -------- Create groups for the dummies --------
      • -------- =========================================== --------
      • Custom script: if udg_HO_DumGroup[udg_HO_Max_Index] == null then
      • Custom script: set udg_HO_DumGroup[udg_HO_Max_Index] = CreateGroup()
      • Custom script: endif
      • Custom script: if udg_HO_DumGroup2[udg_HO_Max_Index] == null then
      • Custom script: set udg_HO_DumGroup2[udg_HO_Max_Index] = CreateGroup()
      • Custom script: endif
      • -------- =========================================== --------
      • -------- Set the stage for the spell --------
      • -------- =========================================== --------
      • Set HO_Stage[HO_Max_Index] = 1
      • -------- =========================================== --------
      • -------- Start the spell --------
      • -------- =========================================== --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • HO_Max_Index Equal to 1
        • Then - Actions
          • Trigger - Turn on HO Loop <gen>
        • Else - Actions
      • -------- =========================================== --------
      • -------- Clean up some location leaks --------
      • -------- =========================================== --------
      • Custom script: call RemoveLocation(udg_Point[1])
      • Custom script: call RemoveLocation(udg_Point[2])
  • HO Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer HO_Cur_Index) from 1 to HO_Max_Index, do (Actions)
        • Loop - Actions
          • -------- =========================================== --------
          • -------- The first stage of the spell --------
          • -------- =========================================== --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • HO_Stage[HO_Cur_Index] Equal to 1
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • HO_ReachedDistance[HO_Cur_Index] Greater than or equal to HO_Range[HO_Level[HO_Cur_Index]]
                • Then - Actions
                  • -------- =========================================== --------
                  • -------- When the orb missile has travelled to the location --------
                  • -------- Create the real orb and destroy the missile orb --------
                  • -------- =========================================== --------
                  • Set Point[1] = (Position of HO_Dummy1[HO_Cur_Index])
                  • Unit - Create 1 HO_DummyType[2] for (Owner of HO_Caster[HO_Cur_Index]) at Point[1] facing Default building facing degrees
                  • Set HO_Dummy2[HO_Cur_Index] = (Last created unit)
                  • Unit - Create 1 HO_DummyType[3] for (Owner of HO_Caster[HO_Cur_Index]) at Point[1] facing Default building facing degrees
                  • Set HO_Dummy3[HO_Cur_Index] = (Last created unit)
                  • Unit - Kill HO_Dummy1[HO_Cur_Index]
                  • -------- =========================================== --------
                  • -------- Destroy Trees --------
                  • -------- =========================================== --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • HO_DestroyTree Equal to True
                    • Then - Actions
                      • Destructible - Pick every destructible within HO_AoE2[HO_Level[HO_Cur_Index]] of Point[1] and do (Actions)
                        • Loop - Actions
                          • Set TempDest = (Picked destructible)
                          • Unit - Order HO_TD to Harvest TempDest
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Current order of HO_TD) Equal to (Order(harvest))
                            • Then - Actions
                              • Destructible - Kill TempDest
                            • Else - Actions
                          • Unit - Order HO_TD to Stop
                    • Else - Actions
                  • -------- =========================================== --------
                  • -------- Create an effect for the impact --------
                  • -------- =========================================== --------
                  • Special Effect - Create a special effect at Point[1] using HO_Effect[1]
                  • Special Effect - Destroy (Last created special effect)
                  • Unit Group - Remove all units from HO_DU[HO_Cur_Index]
                  • -------- =========================================== --------
                  • -------- Continue to the second stage --------
                  • -------- =========================================== --------
                  • Set HO_Stage[HO_Cur_Index] = 2
                  • -------- =========================================== --------
                  • -------- Clean up the leak --------
                  • -------- =========================================== --------
                  • Custom script: call RemoveLocation(udg_Point[1])
                • Else - Actions
                  • -------- =========================================== --------
                  • -------- Store the required locations --------
                  • -------- =========================================== --------
                  • Set Point[1] = (Position of HO_Dummy1[HO_Cur_Index])
                  • Set Point[2] = (Point[1] offset by HO_Speed[HO_Level[HO_Cur_Index]] towards HO_Angle[HO_Cur_Index] degrees)
                  • -------- =========================================== --------
                  • -------- Move the dummy --------
                  • -------- =========================================== --------
                  • Custom script: call SetUnitX(udg_HO_Dummy1[udg_HO_Cur_Index], GetLocationX(udg_Point[2]))
                  • Custom script: call SetUnitY(udg_HO_Dummy1[udg_HO_Cur_Index], GetLocationY(udg_Point[2]))
                  • -------- =========================================== --------
                  • -------- A counter to check when to stop the orb and start the second stage --------
                  • -------- =========================================== --------
                  • Set HO_ReachedDistance[HO_Cur_Index] = (HO_ReachedDistance[HO_Cur_Index] + HO_Speed[HO_Level[HO_Cur_Index]])
                  • -------- =========================================== --------
                  • -------- Damage every nearby enemy unit --------
                  • -------- =========================================== --------
                  • Custom script: set bj_wantDestroyGroup = true
                  • Unit Group - Pick every unit in (Units within HO_AoE[HO_Level[HO_Cur_Index]] of Point[1]) and do (Actions)
                    • Loop - Actions
                      • Set TempUnit = (Picked unit)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (TempUnit belongs to an enemy of (Owner of HO_Caster[HO_Cur_Index])) Equal to True
                          • (TempUnit is alive) Equal to True
                          • (TempUnit is in HO_DU[HO_Cur_Index]) Equal to False
                          • (TempUnit is A structure) Equal to False
                        • Then - Actions
                          • Unit - Cause HO_Caster[HO_Cur_Index] to damage TempUnit, dealing HO_Damage[HO_Level[HO_Cur_Index]] damage of attack type Spells and damage type Normal
                          • -------- =========================================== --------
                          • -------- Add them to HO_DU, so they won't take the damage multiple times --------
                          • -------- =========================================== --------
                          • Unit Group - Add TempUnit to HO_DU[HO_Cur_Index]
                        • Else - Actions
                  • -------- =========================================== --------
                  • -------- Clean up the leaks --------
                  • -------- =========================================== --------
                  • Custom script: call RemoveLocation(udg_Point[1])
                  • Custom script: call RemoveLocation(udg_Point[2])
            • Else - Actions
              • -------- =========================================== --------
              • -------- The second stage of the spell --------
              • -------- =========================================== --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • HO_Stage[HO_Cur_Index] Equal to 2
                • Then - Actions
                  • -------- =========================================== --------
                  • -------- Set up the counter --------
                  • -------- =========================================== --------
                  • Set HO_Counter[HO_Cur_Index] = (HO_Counter[HO_Cur_Index] + 0.03)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • HO_Counter[HO_Cur_Index] Greater than or equal to 1.00
                    • Then - Actions
                      • -------- =========================================== --------
                      • -------- Create a missile which will summon the hellfire minion --------
                      • -------- =========================================== --------
                      • Set HO_TargetPoint[HO_Cur_Index] = (Random real number between HO_MinR[HO_Level[HO_Cur_Index]] and HO_MaxR[HO_Level[HO_Cur_Index]])
                      • Set Point[1] = (Position of HO_Dummy2[HO_Cur_Index])
                      • Set Point[2] = (Point[1] offset by HO_TargetPoint[HO_Cur_Index] towards (Random angle) degrees)
                      • Set HO_Angle2[HO_Cur_Index] = (Angle from Point[1] to Point[2])
                      • Unit - Create 1 HO_DummyType[1] for (Owner of HO_Caster[HO_Cur_Index]) at Point[1] facing HO_Angle2[HO_Cur_Index] degrees
                      • Set HO_Dummy4[HO_Cur_Index] = (Last created unit)
                      • -------- =========================================== --------
                      • -------- Continue to the third stage --------
                      • -------- =========================================== --------
                      • Set HO_Stage[HO_Cur_Index] = 3
                      • -------- =========================================== --------
                      • -------- Clean up the leaks --------
                      • -------- =========================================== --------
                      • Custom script: call RemoveLocation(udg_Point[1])
                      • Custom script: call RemoveLocation(udg_Point[2])
                    • Else - Actions
                • Else - Actions
                  • -------- =========================================== --------
                  • -------- The third stage of the spell --------
                  • -------- =========================================== --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • HO_Stage[HO_Cur_Index] Equal to 3
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • HO_ReachedDistance2[HO_Cur_Index] Greater than or equal to HO_TargetPoint[HO_Cur_Index]
                        • Then - Actions
                          • -------- =========================================== --------
                          • -------- When the missile has travelled to the location --------
                          • -------- Create the minion and destroy the missile --------
                          • -------- =========================================== --------
                          • Set Point[1] = (Position of HO_Dummy4[HO_Cur_Index])
                          • Unit - Create 1 HO_Minion[HO_Level[HO_Cur_Index]] for (Owner of HO_Caster[HO_Cur_Index]) at Point[1] facing (Random angle) degrees
                          • Set TempUnit = (Last created unit)
                          • Unit - Add a HO_MDur[HO_Level[HO_Cur_Index]] second Generic expiration timer to TempUnit
                          • Unit - Kill HO_Dummy4[HO_Cur_Index]
                          • -------- =========================================== --------
                          • -------- Destroy Trees --------
                          • -------- =========================================== --------
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • HO_DestroyTree Equal to True
                            • Then - Actions
                              • Destructible - Pick every destructible within HO_AoE[HO_Level[HO_Cur_Index]] of Point[1] and do (Actions)
                                • Loop - Actions
                                  • Set TempDest = (Picked destructible)
                                  • Unit - Order HO_TD to Harvest TempDest
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • (Current order of HO_TD) Equal to (Order(harvest))
                                    • Then - Actions
                                      • Destructible - Kill TempDest
                                    • Else - Actions
                                  • Unit - Order HO_TD to Stop
                            • Else - Actions
                          • -------- =========================================== --------
                          • -------- Create an effect for the impact --------
                          • -------- =========================================== --------
                          • Special Effect - Create a special effect at Point[1] using HO_Effect[2]
                          • Special Effect - Destroy (Last created special effect)
                          • -------- =========================================== --------
                          • -------- Reset the counter --------
                          • -------- =========================================== --------
                          • Set HO_Counter[HO_Cur_Index] = 0.00
                          • -------- =========================================== --------
                          • -------- Count the number of the summoned minions --------
                          • -------- =========================================== --------
                          • Set HO_Counter2[HO_Cur_Index] = (HO_Counter2[HO_Cur_Index] + 1)
                          • -------- =========================================== --------
                          • -------- Reset --------
                          • -------- =========================================== --------
                          • Set HO_ReachedDistance2[HO_Cur_Index] = 0.00
                          • Set HO_TargetPoint[HO_Cur_Index] = 0.00
                          • Set HO_Angle2[HO_Cur_Index] = 0.00
                          • -------- =========================================== --------
                          • -------- If it hasn't reached the maximum number, return to the second stage. If it has, move on to the next stage --------
                          • -------- =========================================== --------
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • HO_Counter2[HO_Cur_Index] Equal to HO_Number[HO_Level[HO_Cur_Index]]
                            • Then - Actions
                              • -------- =========================================== --------
                              • -------- Create the dummies around the hellfire orb --------
                              • -------- =========================================== --------
                              • For each (Integer HO_INT[HO_Cur_Index]) from 1 to HO_Number2[HO_Level[HO_Cur_Index]], do (Actions)
                                • Loop - Actions
                                  • -------- =========================================== --------
                                  • -------- Set up the locations --------
                                  • -------- =========================================== --------
                                  • Set Point[1] = (Position of HO_Dummy2[HO_Cur_Index])
                                  • Set Point[2] = (Point[1] offset by 50.00 towards ((Real(HO_INT[HO_Cur_Index])) x (360.00 / (Real(HO_Number2[HO_Level[HO_Cur_Index]])))) degrees)
                                  • -------- =========================================== --------
                                  • -------- Create the dummies and add them into a group so we can keep their track --------
                                  • -------- =========================================== --------
                                  • Unit - Create 1 HO_DummyType[4] for (Owner of HO_Caster[HO_Cur_Index]) at Point[2] facing (Angle from Point[1] to Point[2]) degrees
                                  • Set HO_Dummy5[HO_Cur_Index] = (Last created unit)
                                  • Unit Group - Add HO_Dummy5[HO_Cur_Index] to HO_DumGroup[HO_Cur_Index]
                                  • Unit - Add a (((HO_MaxDist[HO_Level[HO_Cur_Index]] x 2.00) / HO_Speed3[HO_Level[HO_Cur_Index]]) / 100.00) second Generic expiration timer to HO_Dummy5[HO_Cur_Index]
                                  • -------- =========================================== --------
                                  • -------- Clean up the leaks --------
                                  • -------- =========================================== --------
                                  • Custom script: call RemoveLocation(udg_Point[1])
                                  • Custom script: call RemoveLocation(udg_Point[2])
                              • -------- =========================================== --------
                              • -------- Continue to the fourth stage --------
                              • -------- =========================================== --------
                              • Set HO_Stage[HO_Cur_Index] = 4
                            • Else - Actions
                              • -------- =========================================== --------
                              • -------- Return to the second stage --------
                              • -------- =========================================== --------
                              • Set HO_Stage[HO_Cur_Index] = 2
                          • -------- =========================================== --------
                          • -------- Clean up the leak --------
                          • -------- =========================================== --------
                          • Custom script: call RemoveLocation(udg_Point[1])
                        • Else - Actions
                          • -------- =========================================== --------
                          • -------- Store the required locations --------
                          • -------- =========================================== --------
                          • Set Point[1] = (Position of HO_Dummy4[HO_Cur_Index])
                          • Set Point[2] = (Point[1] offset by HO_Speed2[HO_Level[HO_Cur_Index]] towards HO_Angle2[HO_Cur_Index] degrees)
                          • -------- =========================================== --------
                          • -------- Move the dummy --------
                          • -------- =========================================== --------
                          • Custom script: call SetUnitX(udg_HO_Dummy4[udg_HO_Cur_Index], GetLocationX(udg_Point[2]))
                          • Custom script: call SetUnitY(udg_HO_Dummy4[udg_HO_Cur_Index], GetLocationY(udg_Point[2]))
                          • -------- =========================================== --------
                          • -------- A counter to check when to stop the missile, destroy it and summon the minion --------
                          • -------- =========================================== --------
                          • Set HO_ReachedDistance2[HO_Cur_Index] = (HO_ReachedDistance2[HO_Cur_Index] + HO_Speed2[HO_Level[HO_Cur_Index]])
                          • -------- =========================================== --------
                          • -------- Clean up the leaks --------
                          • -------- =========================================== --------
                          • Custom script: call RemoveLocation(udg_Point[1])
                          • Custom script: call RemoveLocation(udg_Point[2])
                    • Else - Actions
                      • -------- =========================================== --------
                      • -------- The fourth stage of the spell --------
                      • -------- =========================================== --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • HO_Stage[HO_Cur_Index] Equal to 4
                        • Then - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (HO_DumGroup[HO_Cur_Index] is empty) Equal to False
                            • Then - Actions
                              • Unit Group - Pick every unit in HO_DumGroup[HO_Cur_Index] and do (Actions)
                                • Loop - Actions
                                  • Set HO_Dummy5[HO_Cur_Index] = (Picked unit)
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • HO_ReachedDistance3[HO_Cur_Index] Greater than or equal to HO_MaxDist[HO_Level[HO_Cur_Index]]
                                    • Then - Actions
                                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                        • If - Conditions
                                          • (HO_Dummy5[HO_Cur_Index] is dead) Equal to True
                                        • Then - Actions
                                          • -------- =========================================== --------
                                          • -------- Store the required location --------
                                          • -------- =========================================== --------
                                          • Set Point[1] = (Position of HO_Dummy2[HO_Cur_Index])
                                          • -------- =========================================== --------
                                          • -------- Damage every nearby enemy unit --------
                                          • -------- =========================================== --------
                                          • Custom script: set bj_wantDestroyGroup = true
                                          • Unit Group - Pick every unit in (Units within HO_AoE2[HO_Level[HO_Cur_Index]] of Point[1]) and do (Actions)
                                            • Loop - Actions
                                              • Set TempUnit = (Picked unit)
                                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                                • If - Conditions
                                                  • (TempUnit belongs to an enemy of (Owner of HO_Caster[HO_Cur_Index])) Equal to True
                                                  • (TempUnit is alive) Equal to True
                                                  • (TempUnit is A structure) Equal to False
                                                  • (TempUnit is in HO_DU[HO_Cur_Index]) Equal to False
                                                • Then - Actions
                                                  • Unit - Cause HO_Caster[HO_Cur_Index] to damage TempUnit, dealing HO_Damage2[HO_Level[HO_Cur_Index]] damage of attack type Spells and damage type Normal
                                                  • -------- =========================================== --------
                                                  • -------- Add them to HO_DU, so they won't take the damage multiple times --------
                                                  • -------- =========================================== --------
                                                  • Unit Group - Add TempUnit to HO_DU[HO_Cur_Index]
                                                • Else - Actions
                                          • -------- =========================================== --------
                                          • -------- Destroy Trees --------
                                          • -------- =========================================== --------
                                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                            • If - Conditions
                                              • HO_DestroyTree Equal to True
                                            • Then - Actions
                                              • Destructible - Pick every destructible within HO_AoE2[HO_Level[HO_Cur_Index]] of Point[1] and do (Actions)
                                                • Loop - Actions
                                                  • Set TempDest = (Picked destructible)
                                                  • Unit - Order HO_TD to Harvest TempDest
                                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                                    • If - Conditions
                                                      • (Current order of HO_TD) Equal to (Order(harvest))
                                                    • Then - Actions
                                                      • Destructible - Kill TempDest
                                                    • Else - Actions
                                                  • Unit - Order HO_TD to Stop
                                            • Else - Actions
                                          • -------- =========================================== --------
                                          • -------- Create some special effects --------
                                          • -------- =========================================== --------
                                          • Special Effect - Create a special effect at Point[1] using HO_Effect[1]
                                          • Special Effect - Destroy (Last created special effect)
                                          • Unit - Create 1 Dummy5 for (Owner of HO_Caster[HO_Cur_Index]) at Point[1] facing Default building facing degrees
                                          • Set TempUnit = (Last created unit)
                                          • Unit - Kill TempUnit
                                          • -------- =========================================== --------
                                          • -------- Destroy the orb and its effects --------
                                          • -------- =========================================== --------
                                          • Unit - Kill HO_Dummy2[HO_Cur_Index]
                                          • Unit - Kill HO_Dummy3[HO_Cur_Index]
                                          • Unit Group - Pick every unit in HO_DumGroup2[HO_Cur_Index] and do (Actions)
                                            • Loop - Actions
                                              • Set TempUnit = (Picked unit)
                                              • Unit - Kill TempUnit
                                          • -------- =========================================== --------
                                          • -------- Continue to the final stage --------
                                          • -------- =========================================== --------
                                          • Set HO_Stage[HO_Cur_Index] = 5
                                          • -------- =========================================== --------
                                          • -------- Clean up the leak --------
                                          • -------- =========================================== --------
                                          • Custom script: call RemoveLocation(udg_Point[1])
                                        • Else - Actions
                                          • -------- =========================================== --------
                                          • -------- Store the required locations --------
                                          • -------- =========================================== --------
                                          • Set Point[1] = (Position of HO_Dummy5[HO_Cur_Index])
                                          • Set Point[2] = (Position of HO_Dummy2[HO_Cur_Index])
                                          • Set Point[3] = (Point[2] offset by ((Distance between Point[1] and Point[2]) - HO_Speed3[HO_Level[HO_Cur_Index]]) towards ((Angle from Point[2] to Point[1]) + 5.00) degrees)
                                          • -------- =========================================== --------
                                          • -------- Move the dummy --------
                                          • -------- =========================================== --------
                                          • Custom script: call SetUnitX(udg_HO_Dummy5[udg_HO_Cur_Index], GetLocationX(udg_Point[3]))
                                          • Custom script: call SetUnitY(udg_HO_Dummy5[udg_HO_Cur_Index], GetLocationY(udg_Point[3]))
                                          • -------- =========================================== --------
                                          • -------- Create more dummies as special effects --------
                                          • -------- =========================================== --------
                                          • Unit - Create 1 HO_DummyType[4] for (Owner of HO_Caster[HO_Cur_Index]) at Point[1] facing (Facing of HO_Dummy5[HO_Cur_Index]) degrees
                                          • Set TempUnit = (Last created unit)
                                          • Unit Group - Add TempUnit to HO_DumGroup2[HO_Cur_Index]
                                          • -------- =========================================== --------
                                          • -------- Clean up the leaks --------
                                          • -------- =========================================== --------
                                          • Custom script: call RemoveLocation(udg_Point[1])
                                          • Custom script: call RemoveLocation(udg_Point[2])
                                          • Custom script: call RemoveLocation(udg_Point[3])
                                    • Else - Actions
                                      • -------- =========================================== --------
                                      • -------- Store the required locations --------
                                      • -------- =========================================== --------
                                      • Set Point[1] = (Position of HO_Dummy5[HO_Cur_Index])
                                      • Set Point[2] = (Point[1] offset by HO_Speed3[HO_Level[HO_Cur_Index]] towards (Facing of HO_Dummy5[HO_Cur_Index]) degrees)
                                      • -------- =========================================== --------
                                      • -------- Move the dummy --------
                                      • -------- =========================================== --------
                                      • Custom script: call SetUnitX(udg_HO_Dummy5[udg_HO_Cur_Index], GetLocationX(udg_Point[2]))
                                      • Custom script: call SetUnitY(udg_HO_Dummy5[udg_HO_Cur_Index], GetLocationY(udg_Point[2]))
                                      • -------- =========================================== --------
                                      • -------- Create more dummies as special effects --------
                                      • -------- =========================================== --------
                                      • Unit - Create 1 HO_DummyType[4] for (Owner of HO_Caster[HO_Cur_Index]) at Point[1] facing (Facing of HO_Dummy5[HO_Cur_Index]) degrees
                                      • Set TempUnit = (Last created unit)
                                      • Unit Group - Add TempUnit to HO_DumGroup2[HO_Cur_Index]
                                      • -------- =========================================== --------
                                      • -------- A counter to check when to continue to the next step --------
                                      • -------- =========================================== --------
                                      • Set HO_ReachedDistance3[HO_Cur_Index] = (HO_ReachedDistance3[HO_Cur_Index] + 15.00)
                                      • -------- =========================================== --------
                                      • -------- Clean up the leaks --------
                                      • -------- =========================================== --------
                                      • Custom script: call RemoveLocation(udg_Point[1])
                                      • Custom script: call RemoveLocation(udg_Point[2])
                            • Else - Actions
                        • Else - Actions
                          • -------- =========================================== --------
                          • -------- The final stage of the spell --------
                          • -------- =========================================== --------
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • HO_Stage[HO_Cur_Index] Equal to 5
                            • Then - Actions
                              • -------- =========================================== --------
                              • -------- De-Index --------
                              • -------- =========================================== --------
                              • Custom script: call DestroyGroup(udg_HO_DU[udg_HO_Cur_Index])
                              • Set HO_DU[HO_Cur_Index] = HO_DU[HO_Max_Index]
                              • Custom script: set udg_HO_DU[udg_HO_Max_Index] = null
                              • Custom script: call DestroyGroup(udg_HO_DumGroup[udg_HO_Cur_Index])
                              • Set HO_DumGroup[HO_Cur_Index] = HO_DumGroup[HO_Max_Index]
                              • Custom script: set udg_HO_DumGroup[udg_HO_Max_Index] = null
                              • Custom script: call DestroyGroup(udg_HO_DumGroup2[udg_HO_Cur_Index])
                              • Set HO_DumGroup2[HO_Cur_Index] = HO_DumGroup2[HO_Max_Index]
                              • Custom script: set udg_HO_DumGroup2[udg_HO_Max_Index] = null
                              • Set HO_Angle[HO_Cur_Index] = HO_Angle[HO_Max_Index]
                              • Set HO_Angle2[HO_Cur_Index] = HO_Angle2[HO_Max_Index]
                              • Set HO_Caster[HO_Cur_Index] = HO_Caster[HO_Max_Index]
                              • Set HO_Caster[HO_Max_Index] = No unit
                              • Set HO_Dummy1[HO_Cur_Index] = HO_Dummy1[HO_Max_Index]
                              • Set HO_Dummy1[HO_Max_Index] = No unit
                              • Set HO_Dummy2[HO_Cur_Index] = HO_Dummy2[HO_Max_Index]
                              • Set HO_Dummy2[HO_Max_Index] = No unit
                              • Set HO_Dummy3[HO_Cur_Index] = HO_Dummy3[HO_Max_Index]
                              • Set HO_Dummy3[HO_Max_Index] = No unit
                              • Set HO_Dummy4[HO_Cur_Index] = HO_Dummy4[HO_Max_Index]
                              • Set HO_Dummy4[HO_Max_Index] = No unit
                              • Set HO_Dummy5[HO_Cur_Index] = HO_Dummy5[HO_Max_Index]
                              • Set HO_Dummy5[HO_Max_Index] = No unit
                              • Set HO_ReachedDistance[HO_Cur_Index] = HO_ReachedDistance[HO_Max_Index]
                              • Set HO_ReachedDistance2[HO_Cur_Index] = HO_ReachedDistance2[HO_Max_Index]
                              • Set HO_ReachedDistance3[HO_Cur_Index] = HO_ReachedDistance3[HO_Max_Index]
                              • Set HO_INT[HO_Cur_Index] = HO_INT[HO_Max_Index]
                              • Set HO_Stage[HO_Cur_Index] = HO_Stage[HO_Max_Index]
                              • Set HO_Stage[HO_Max_Index] = 0
                              • Set HO_TargetPoint[HO_Cur_Index] = HO_TargetPoint[HO_Max_Index]
                              • Set HO_Level[HO_Cur_Index] = HO_Level[HO_Max_Index]
                              • Set HO_Counter[HO_Cur_Index] = HO_Counter[HO_Max_Index]
                              • Set HO_Counter2[HO_Cur_Index] = HO_Counter2[HO_Max_Index]
                              • Set HO_Cur_Index = (HO_Cur_Index - 1)
                              • Set HO_Max_Index = (HO_Max_Index - 1)
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • HO_Max_Index Equal to 0
                                • Then - Actions
                                  • Trigger - Turn off (This trigger)
                                • Else - Actions
                            • Else - Actions

Credits:
Frankster
JetFangInferno

WIP:
WIP 1
WIP 2


WIP 1

WIP 2

myDibuD.gif
6hdxcfD.gif


Orb

Orb2

Final

Final2

Explosion

232216-albums6711-picture108898.png
232216-albums6711-picture108897.png
232216-albums6711-picture108896.png
232216-albums6711-picture108895.png
232216-albums6711-picture108894.png

How to Import:
Go to World Editor => file => Preferences => Check the "Automatically create unknown Variable while pasting trigger" => ok
then copy all triggers inside the Hellfire Category into your map. Copy the dummies and the ability itself into your map as well.
 

Attachments

  • Rheiko - Hellfire Orb.w3x
    110.2 KB · Views: 84
Last edited:
Level 14
Joined
Jul 1, 2008
Messages
1,314
I would like to enter this contest as well with a WIP of the spell "Chicken Rage".

Tooltipp

151951-albums8916-picture108910.jpg



Comments

This spell can be combined with another spell, that lets you type in a message, that the target player has to type in order to summon the chicken slayer. This unit instantly kills all chickens and throws them at the casting player, dealing explosive damage. I am not sure about that combination thing yet.
well, it is work in progress :)

Picutres

Sry for the ugly WIP pictures, I do not have much time atm.
151951-albums8916-picture108909.jpg
"]

Credits

Models will be credited in the maps Quest Log and via a message on the screen.
 
Last edited:
Level 9
Joined
Oct 14, 2013
Messages
238
This is a contest and contest is all about competition. If one is not ready for a competition then he shouldn't join. Why does one want to participate in a contest? Because he wants a challenge. To overcome a challenge he must know his own ability whether he could do that or not. That is the reason why a preparation is needed. Prepare everything you need to defeat the other contestants before the contest started. Once it has started, you may only rely on the ability you've prepared. If it's not good enough, you'll lose. That's just how competitions are.

Anyways, I'm going to post my entry real soon!

Your comment reminds me of the times when I used to play DotA and saw people who would feast upon the noobs to prove that they are skilled players and chat shit about everyone and when faced with pro opponents you could see how they would fail and start crying.

If you compete against the best you need to raise your game, too. Otherwise you can simply rely on the weak and never improve your skills. That's what contests are about. Everyone wins even if they lose the contest.
 
Level 17
Joined
Sep 8, 2007
Messages
994
Your comment reminds me of the times when I used to play DotA and saw people who would feast upon the noobs to prove that they are skilled players and chat shit about everyone and when faced with pro opponents you could see how they would fail and start crying.

If you compete against the best you need to raise your game, too. Otherwise you can simply rely on the weak and never improve your skills. That's what contests are about. Everyone wins even if they lose the contest.

#Word.
Totally agree. The experience is worth more than winning the contest, IMO.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
It's not that much of an experience really. I could understand that argument if you went to the world cup in football or something because it's completely different and it brings much more than just matches.

But a contest in the hive.. it's exactly like uploading something to the spell section.
You code something on your own and you upload it, and get it graded.
The only difference is the competitive aspect. (due prizes)
 
Level 4
Joined
Jun 23, 2013
Messages
23
Hey there.

I hope it's not too late but I'd like to join the contest. For now, I'll state my rough idea:

A Druid spell summoning either a treant like unit or animal spirits. I'll try to post a first WIP as soon as possible.
 
Level 22
Joined
Aug 27, 2013
Messages
3,973
Your comment reminds me of the times when I used to play DotA and saw people who would feast upon the noobs to prove that they are skilled players and chat shit about everyone and when faced with pro opponents you could see how they would fail and start crying.

If you compete against the best you need to raise your game, too. Otherwise you can simply rely on the weak and never improve your skills. That's what contests are about. Everyone wins even if they lose the contest.
Except that this isn't DotA and I doubt there are noobs in DotA tournament. This is a contest, not a game for practicing. Even DotA players practiced a lot of times against AI and other players until they feel they can compete in tournament.

#Word.
Totally agree. The experience is worth more than winning the contest, IMO.
Indeed, that's the reason I also joined. But what is the good of contest if you don't have a competitive aspect? The main goal of course is to win and the experience to get there is what worth.
 
Level 17
Joined
Sep 8, 2007
Messages
994
Indeed, that's the reason I also joined. But what is the good of contest if you don't have a competitive aspect? The main goal of course is to win and the experience to get there is what worth.

I didn't mean to say that you shouldn't have a competitive aspect, you totally should.
What I meant is that the experience of participating in a contest and creating a new spell is worth more than the 5 rep points for participating (in case you don't score higher), as you will learn more by creating a new spell, seeing where there's room for improvement and getting skilled people's reactions.
 
Level 9
Joined
Oct 14, 2013
Messages
238
Except that this isn't DotA and I doubt there are noobs in DotA tournament. This is a contest, not a game for practicing. Even DotA players practiced a lot of times against AI and other players until they feel they can compete in tournament.

You missed the whole point!

I didn't compare DotA (especially tournaments) to this contest. I compared the behavior of average players in ordinary DotA games who prey on the weak to the attitudes found here to take advantage of others' weaknesses.

Let me tell you something: If you think that letting others know a major mistake in their work, will affect your winning odds, you probably lack enough confidence on your own skills/ideas and you need to reassess them, or as a hero once said "time to man up" :) Dare to face the betters of you.
 
Level 11
Joined
Dec 19, 2012
Messages
411
Final Entry - Elemental Chaos

Elemental Chaos[tr]
Spell Icon
224529-albums8862-picture108936.jpg
[tr]
Spell Description
224529-albums8862-picture108935.jpg
[tr]

Close

Spell Codes

ScreenShoots

Summons Spells Details

Change Log


Main code :
Elemental Chaos
JASS:
library ElementalChaos initializer Init /* version 1.0.1
*======================================Elemental Chaos by DD_LegionTN======================================================*
*
*	Spell Description :
*		An unstable sphere is generated for 3/2.5/2 seconds using the elemental power of the caster.
*
*		The unstabilized sphere will emits out 3/4/5 packs of energy around the sphere, 
*		which will explode and creating 1~2/1~3/2~3 missiles.
*		Once the missile landed on the ground, 10/20/30 damage within 50/80/110 AoE is dealt to nearby enemy units
*		as well as summons an unstable elemental unit with 10/12/14 seconds life time.
*
*		The unstable elemental unit will get reabsorb back to the sphere once it life time is expired.
*		Maximum reabsorb 6/8/10 units. Maximum absorb range is 1000.
*
*		The sphere will slowly lands on the ground after all summons expired,
*		dealing 100/200/300 damage within 500/600/700 AoE to nearby enermy units
*		and summons a stabilized elemental unit with life time 30/40/50 seconds.
*		The summons hit points is dependent on the amount of the unstable elemental unit reabsorbed.
*
*==========================================================================================================================*
*
*	Requirement :
*		*/requires /*
*			- Elemental Chaos requires no nessasary library
*
*
*		*/optional DummyRecycler /*
*			- Performance gain, recommended
*
*		*/optional SpellEffectEvent /*
*			- Minor performance gain, recommended
*
*		*/optional Table /*
*			- Not nessasary needed, in case people have Table present in their map
*			  so that there would not be generated an extra hashtable
*
*		*/optional ZLibrary /*
*			- Not nessasary needed, in case people have ZLibrary present in their map
*			  so that no unnessasary location handle and function are generated 
*==========================================================================================================================*
*	Import Instruction :
*		1. Copy abilities into your map :
*			a) Required - Elemental Chaos (A000)
*			b) Optional - dummy unit (e000) if you don't have dummy unit in your map (using vexorian's dummy unit)
*						  The dummy unit MUST have locust and crow form abilties (Aloc and Amrf)
*			c) Optional - Energy Absorbption (A004, A005, A006) and Regeneration (A001, A002, A003) if you want the
*						  passive regeneration of the SECOND_SUMMON
*			d) Optional - Energy Loss (A00A, A00B, A00C) and Degeneration (A007, A008, A009) if you want the
*						  passive degeneration of the FIRST_SUMMON
*			e) Optional - Energy Explode (A00D) if you want the active skill of the FIRST_SUMMON
*
*		2. Copy units into your map :
*			a) Optional - Unstabilized Element (h001, h002, h003) into your map (or create new units and use your own)
*			b) Optional - Stabilized Element (h004, h005, h006) into your map (or create new units and use your own)
*
*		3. Copy spell scripts into your map :
*			a) Required - Elemental Chaos
*			b) Optional - Only copy Energy Explosion if you want the active skill of the FIRST_SUMMON
*
*		4. Copy libraries into your map :
*			a) Optional - DummyRecycler
*			b) Optional - SpellEffectEvent (Requires RegisterPlayerUnitEvent)
*			c) Optional - Table
*			d) Optional - ZLibrary
*
*		5. Modify the copied abilities data to suit your need
*
*		6. Modify the copied units data to suit your need
*
*		7. Configures the spell of Elemental Chaos
*
*		8. Configures the spell of Energy Explosion (if you did copy)
*
*==========================================================================================================================*
*	API :
*		Yes, there is 1 API available in this spell, it only used for defining whether FIRST_SUMMON is enable to get
*		reabsorbed back to the sphere once it expired (remember to configure the function EC_AbsorbFilter)
*		Use this API to create custom ablities for summons if needed (Add abilities via function SummonAddAbilities)
*		
*		struct ECData
*			static method absorbable takes unit u, boolean b returns nothing
*				unit u 		- the summon unit (ONLY for FIRST_SUMMON type)
*				boolean b	- true for enable reabsorb, false for disable reabsorb
*/

//================================================================================
//============================Configurable Part===================================
//================================================================================
	static if not LIBRARY_DummyRecycler then
	
	globals
		//Only need to set dummy unit id only if there is no DummyRecycler present
		//Dummy unit id
		private constant integer				DUMMY_UNIT_ID							= 'e000'
	endglobals
	
	endif
	
	
	globals
		/*
			GENERAL Configuration
		*/
		
		//The id of the spell
		private	constant integer				SPELL_ID 								= 'A000'
		
		//Interval time between energy packs to release the next energy pack
		private constant real					SPHERE_PACK_RELEASE_INTERVAL			= 1.
		
		//Timer updating time constant
		private constant real		 			TIMER_TIMEOUT							= 0.03125
		
		//How long does the dummy unit get removed so that the attached effect could be fully played
		private constant real					DUMMY_DEATH_TIME						= 2.
		
		//The attachement path of the effect on the dummy units
		private	constant string					ATTACHMENT_PATH							= "origin"
		
		//Attack type of the damage
		private constant attacktype				ATTACK_TYPE								= ATTACK_TYPE_NORMAL
		
		//Damage type of the damage
		private constant damagetype				DAMAGE_TYPE								= DAMAGE_TYPE_NORMAL
		
		//Weapon type of the damage
		private constant weapontype				WEAPON_TYPE								= WEAPON_TYPE_WHOKNOWS
		
		//Gravitational force determines how strong the verticle force that pulling the missile to the ground
		private constant real					GRAVITATIONAL_FORCE						= 150.
		
		/*
			SPHERE Configuration (the generating sphere at start)
		*/
		
		//Sphere effect model path
		private constant string					SPHERE_EFFECT_PATH						= "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
		
		//Color adjustment - red color component of sphere
		private	constant integer				SPHERE_COLOR_RED						= 70
		
		//Color adjustment - green color component of sphere
		private	constant integer				SPHERE_COLOR_GREEN						= 200
		
		//Color adjustment - blue color component of sphere
		private constant integer				SPHERE_COLOR_BLUE						= 255
		
		//Transparency adjustment - transparency of sphere
		private	constant integer				SPHERE_TRANSPARENCY						= 255
		
		//Initial scale of the sphere before generating start
		private	constant real					SPHERE_INITIAL_SCALE					= 0.
		
		/*
				PARTICLE_EFFECT Configuration (those little particles moving toward the sphere)
		*/
		
		//Sphere particle effect stop spawn timing before sphere fully generated
		private constant real					PARTICLE_EFFECT_STOP_TIMING				= 1.
		
		//Sphere particle maximum scale
		private constant real					PARTICLE_EFFECT_MAX_SCALE				= 2.5
		
		//Sphere particle minimum scale
		private constant real					PARTICLE_EFFECT_MIN_SCALE				= 1.0
		
		//Sphere particle maximum distance from sphere
		private constant real					PARTICLE_EFFECT_MAX_DIST				= 250.
		
		//Sphere particle minimum distance from sphere
		private constant real					PARTICLE_EFFECT_MIN_DIST				= 150.
		
		//Sphere particle maximum height distance from shpere
		private constant real					PARTICLE_EFFECT_MAX_HEIGHT				= 200.
		
		//Sphere particle minimum height distance from sphere
		private constant real					PARTICLE_EFFECT_MIN_HEIGHT				= 100.
		
		//Sphere particle maximum speed moving toward sphere (horizontal)
		//(verticle) speed is dependent on the (horizontal) speed and height (distance) between particle and sphere
		private constant real					PARTICLE_EFFECT_MAX_SPEED				= 32.
		
		//Sphere particle minimum speed moving toward sphere (horizontal)
		private constant real					PARTICLE_EFFECT_MIN_SPEED				= 16.
		
		//The distance between sphere and sphere particle must within PARTICLE_EFFECT_END_DIST for the sphere effect to remove
		private constant real 					PARTICLE_EFFECT_END_DIST				= 25.

		//Color adjustment - red color component of sphere particle
		private constant integer				PARTICLE_EFFECT_COLOR_RED				= 255
		
		//Color adjustment - green color component of sphere particle
		private constant integer				PARTICLE_EFFECT_COLOR_GREEN				= 255
		
		//Color adjustment - blue color component of sphere particle
		private constant integer				PARTICLE_EFFECT_COLOR_BLUE				= 255
		
		//Transparency adjustment - transparency of sphere particle
		private constant integer				PARTICLE_EFFECT_TRANSPARENCY			= 255
		
		//Sphere particle effect model path
		private constant string					PARTICLE_EFFECT_PATH					= "war3mapImported\\Stars_lightning_.MDX"
		
		/*
				ENERGY_PACK Configuraration (The sphere/orb effect moves away from the sphere)
		*/
		
		//Minimum distance to traval from sphere
		private constant real 					ENERGY_PACK_MIN_DIST					= 150.
		
		//Maximum distance to traval from sphere
		private constant real					ENERGY_PACK_MAX_DIST					= 250.

		//Minimum height to travel from sphere
		private constant real					ENERGY_PACK_MIN_HEIGHT					= 100.
		
		//Maximum height to travel from sphere
		private constant real					ENERGY_PACK_MAX_HEIGHT					= 200.
		
		//Minimum speed when travelling
		private constant real					ENERGY_PACK_MIN_SPEED					= 2.
		
		//Maximum speed when travelling
		private constant real					ENERGY_PACK_MAX_SPEED					= 4.
		
		//Minimum scale for the effect (unit)
		private constant real					ENERGY_PACK_MIN_SCALE					= .5
		
		//Maximum scale for the effect (unit)
		private constant real					ENERGY_PACK_MAX_SCALE					= 1.
		
		//Color adjustment - red color component of sphere energy pack
		private constant integer				ENERGY_PACK_COLOR_RED					= 70
		
		//Color adjustment - green color component of sphere energy pack
		private constant integer				ENERGY_PACK_COLOR_GREEN					= 200
		
		//Color adjustment - blue color component of sphere energy pack
		private constant integer				ENERGY_PACK_COLOR_BLUE					= 255
		
		//Transparency adjustment - transparency of sphere energy pack
		private constant integer				ENERGY_PACK_TRANSPARENCY				= 255
		
		//Sphere energy pack effect path
		private constant string					ENERGY_PACK_EFFECT_PATH					= "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
		
		//minimum time before energy pack would explode
		//NOTE : If the energy pack reaches it destination before reaching the minimum time, it will still explode regardless 
		//		 ENERGY_PACK_EXPLODE_MIN_TIME
		private constant real					ENERGY_PACK_EXPLODE_MIN_TIME			= 3.5
		
		//maximum time for energy to explode
		private constant real					ENERGY_PACK_EXPLODE_MAX_TIME			= 4.0
		
		//Scale of the explode effect (unit)
		private constant real					ENERGY_PACK_EXPLODE_SCALE				= 0.5
		
		//Color adjustment - red color component of sphere energy pack explode effect
		private constant integer				ENERGY_PACK_EXPLODE_COLOR_RED			= 50
		
		//Color adjustment - green color component of sphere energy pack explode effect
		private constant integer				ENERGY_PACK_EXPLODE_COLOR_GREEN			= 50
		
		//Color adjustment - blue color component of sphere energy pack explode effect
		private constant integer				ENERGY_PACK_EXPLODE_COLOR_BLUE			= 255
		
		//Transparency adjustment - transparency of sphere energy pack explode effect
		private constant integer				ENERGY_PACK_EXPLODE_TRANSPARENCY		= 255
		
		//exploe effect of the energy pack
		private constant string					ENERGY_PACK_EXPLODE_PATH				= "Units\\NightElf\\Wisp\\WispExplode.mdl"
		
		/*
				MISSILE Configuration (missiles that released out when energy pack exploded)
		*/
		
		//The minimum distance for the missile to tarvel along z-axis when missile just created
		private constant real					MISSILE_MIN_HEIGHT						= 50.
		
		//The maximum distance for the missile to tarvel along z-axis when missile just created
		private constant real					MISSILE_MAX_HEIGHT						= 150.
		
		//Scaling of the effect (unit)
		private constant real					MISSILE_SCALE							= 1.
		
		//Color adjustment - red color component of missile
		private constant integer				MISSILE_COLOR_RED						= 255
		
		//Color adjustment - green color component of missile
		private constant integer				MISSILE_COLOR_GREEN						= 255
		
		//Color adjustment - blue color component of missile
		private constant integer				MISSILE_COLOR_BLUE						= 255
		
		//Transparency adjustment - transparency of missile
		private constant integer				MISSILE_TRANSPARENCY					= 255
		
		//Missile effect attached to the unit
		private constant string					MISSILE_EFFECT_PATH						= "Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl"
		
		//Scaling of the effect (unit) after landed
		private constant real					MISSILE_LANDED_SCALE					= 1.
		
		//Color adjustment - red color component of missile after landed
		private constant integer				MISSILE_LANDED_COLOR_RED				= 255
		
		//Color adjustment - green color component of missile after landed
		private constant integer				MISSILE_LANDED_COLOR_GREEN				= 255
		
		//Color adjustment - blue color component of missile after landed
		private constant integer				MISSILE_LANDED_COLOR_BLUE				= 255
		
		//Transparency adjustment - transparency of missile after landed
		private constant integer				MISSILE_LANDED_TRANSPARENCY				= 255
		
		//Missile effect attach to the unit after landed ground
		private constant string					MISSILE_LANDED_EFFECT_PATH				= "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl"
		
		/*
				ORB_ROTATION Configuration 
				PART 1 : summons that get re-absorb back(moving toward) to the sphere when expired
				PART 2 : the effect where the orbs rotating the sphere
		*/
		
		//PART 1 Configuration :
		
		//The missile effect attach to the unit when expired summon moving toward the sphere
		private constant string					ORB_REABSORB_EFFECT_MISSILE				= "war3mapImported\\Stars_lightning_.MDX"
		
		//Speed of the dummy moving toward the sphere vertically (per TIMER_TIMEOUT)
		private constant real					ORB_REABSORB_SPEED						= 5.
		
		//The scale of the unit(effect/missile) when moving toward the sphere
		private constant real					ORB_REABSORB_SCALE_MISSILE				= 1.
		
		//Color adjustment - red color component of the unit
		private constant integer				ORB_REABSORB_COLOR_RED_MISSILE			= 255
		
		//Color adjustment - green color component of the unit
		private constant integer				ORB_REABSORB_COLOR_GREEN_MISSILE		= 255
		
		//Color adjustment - blue color component of the unit
		private constant integer				ORB_REABSORB_COLOR_BLUE_MISSILE			= 255
		
		//Transparency adjustment - transparency of the unit
		private constant integer				ORB_REABSORB_TRANSPARENCY_MISSILE		= 255
		
		//The explode effect attach to the shpere when expired summons reach the sphere
		private constant string					ORB_REABSORB_EFFECT_EXPLODE				= "war3mapImported\\IceNova.mdx"
		
		//The scale of the unit(effect/missile) when moving toward the sphere
		private constant real					ORB_REABSORB_SCALE_EXPLODE				= 1.
		
		//Color adjustment - red color component of the unit
		private constant integer				ORB_REABSORB_COLOR_RED_EXPLODE			= 255
		
		//Color adjustment - green color component of the unit
		private constant integer				ORB_REABSORB_COLOR_GREEN_EXPLODE		= 255
		
		//Color adjustment - blue color component of the unit
		private constant integer				ORB_REABSORB_COLOR_BLUE_EXPLODE			= 255
		
		//Transparency adjustment - transparency of the unit
		private constant integer				ORB_REABSORB_TRANSPARENCY_EXPLODE		= 0
		
		//PART 2 Configuration :
		
		//The effect path for the sphere rotating
		private constant string					ORB_ROTATING_EFFECT_PATH				= "war3mapImported\\Stars_lightning_.MDX"
		
		//The scale of the unit(effect/missile) when rotating the sphere
		private constant real					ORB_ROTATING_SCALE						= 1.
		
		//The angle increasement when rotating the sphere (radian per TIMER_TIMEOUT)
		//larger value means faster rotation
		//lower value means slower rotation
		
		//The angle increasement of the orbs in the first shell
		private constant real					ORB_ROTATING_ANGLE_INCREASEMENT_FIRST	= bj_PI/16
		
		//The angle increasement of the orbs in the second shell
		private constant real					ORB_ROTATING_ANGLE_INCREASEMENT_SECOND	= bj_PI/32
		
		//The angle increasement of the orbs in the third shell
		private constant real					ORB_ROTATING_ANGLE_INCREASEMENT_THIRD	= bj_PI/64
		
		//The constant distance between the orbs and the sphere (horizontal)
		private constant real					ORB_ROTATING_DISTANCE					= 150.
		
		//The constant distance increasement for the path of the orbs if exceed the maximum amount of orbs in the path
		private constant real					ORB_ROTATING_DISTANCE_INCREASEMENT		= 75.
		
		//The maximum amount of orbs able to hold in first shell
		private constant integer				ORB_ROTATING_MAX_FIRST_SHELL			= 2
		
		//same as ORB_ROTATING_MAX_FIRST_SHELL, just for second shell
		private constant integer				ORB_ROTATING_MAX_SECOND_SHELL			= 4
		
		//same as ORB_ROTATING_MAX_FIRST_SHELL, just for third shell
		private constant integer				ORB_ROTATING_MAX_THIRD_SHELL			= 8
		
		//Color adjustment - red color component of the unit
		private constant integer				ORB_ROTATING_COLOR_RED					= 255
		
		//Color adjustment - green color component of the unit
		private constant integer				ORB_ROTATING_COLOR_GREEN				= 255
		
		//Color adjustment - blue color component of the unit
		private constant integer				ORB_ROTATING_COLOR_BLUE					= 255
		
		//Transparency adjustment - transparency of the unit
		private constant integer				ORB_RORATING_TRANSPARENCY				= 255
		
		/*
		
				SPHERE_LANDING_PHASE Configuration (when the sphere is landing)
		
		*/
		//the z-axis landing speed of the sphere (per TIMER_TIMEOUT)
		private constant real					SPHERE_LANDING_SPEED					= 4.
		
		/*
		
				SPHERE_LANDED Configuration (when the sphere landed to the ground)
		
		*/
		
		//the scale of the sphere after landed (for effect scale)
		private constant real					SPHERE_LANDED_SCALE						= 2.0
		
		//Color adjustment - red color component of the sphere
		private constant integer				SPHERE_LANDED_COLOR_RED					= 255
		
		//Color adjustment - green color component of the sphere
		private constant integer				SPHERE_LANDED_COLOR_GREEN				= 255
		
		//Color adjustment - blue color component of the sphere
		private constant integer				SPHERE_LANDED_COLOR_BLUE				= 255
		
		//Transparency adjustment - transparency of the sphere
		private constant integer				SPHERE_LANDED_TRANSPARENCY				= 255
		
		//Sfx when the sphere landed the ground
		private constant string					SPHERE_LANDED_SFX						= "war3mapImported\\AquaSpikeVersion2.mdx"
		
 		/*
				Level Data Configuration (data values will be affected according to spell lv)
				
				All of them are configurable at function Init
		*/
		
		//Sphere height 
		private			 real		 array		SPHERE_HEIGHT
		
		//Sphere maximum scale 
		private			 real		 array		SPHERE_MAX_SCALE
		
		//Sphere generates time 
		private			 real		 array		SPHERE_GENERATE_TIME
		
		//Sphere awaiting time after whole summons killed/absorbed all expired summons before entering landing phase
		private			 real		 array		SPHERE_AWAITING_LANDING_TIME
		
		//Sphere energy pack release amount 
		private			 integer	 array		SPHERE_RELEASE_PACK_MAX
		
		//Spere maximum absorb count of expired summons
		private			 integer	 array		SPHERE_ABSORB_COUNT_MAX
		
		//Sphere maximum distance that able to absorb the expired summons
		private			 real		 array		SPHERE_ABSORB_MAX_DIST
		
		//Sphere missile minimum spawn 
		private			 integer	 array		ENERGY_PACK_MIN_MISSILE
		
		//Sphere missile maximum spawn 
		private			 integer	 array		ENERGY_PACK_MAX_MISSILE
		
		//Sphere missile minimum travelling distance from shpere 
		private			 real		 array		MISSILE_MIN_DIST
		
		//Sphere missile maximum travelling distance from sphere 
		private			 real		 array		MISSILE_MAX_DIST
		
		//The damage deal to enemy after missile landed on the ground 
		private			 real		 array		FIRST_DAMAGE
		
		//The AoE of the FIRST_DAMAGE 
		private			 real		 array		FIRST_DAMAGE_AOE
		
		//Sphere summons unit type after missile landed on the ground 
		private			 integer	 array		FIRST_SUMMON
		
		//FIRST_SUMMON time life 
		private			 real		 array		FIRST_SUMMON_TIME_LIFE
		
		//The damage deal to enemy after sphere landed on thr ground
		private			 real		 array		SECOND_DAMAGE
		
		//The AoE of the SECOND_DAMAGE
		private			 real		 array		SECOND_DAMAGE_AOE
		
		//Sphere summons unit type after sphere landed on the ground 
		private			 integer	 array		SECOND_SUMMON
		
		//SECOND_SUMMON time life 
		private			 real		 array		SECOND_SUMMON_TIME_LIFE
	endglobals
	
	
	private function Init takes nothing returns nothing
		//[1] indicates Lv1, [2] indicates Lv2 and [3] indicates Lv3
		//Arrays are used instead of globals for preventing overwhelming globals as well as unnessasary coding.
		
		//Setting sphere height
		set SPHERE_HEIGHT[1] = 300.
		set SPHERE_HEIGHT[2] = 300.
		set SPHERE_HEIGHT[3] = 300.
		
		//Setting sphere maximum scale
		set SPHERE_MAX_SCALE[1] = 1.5
		set SPHERE_MAX_SCALE[2] = 1.7
		set SPHERE_MAX_SCALE[3] = 1.9
		
		//Setting sphere generates time
		set SPHERE_GENERATE_TIME[1] = 3.0
		set SPHERE_GENERATE_TIME[2] = 2.5
		set SPHERE_GENERATE_TIME[3] = 2.0
		
		//Setting the time to wait before sphere landing after absorbed all expired summons
		set SPHERE_AWAITING_LANDING_TIME[1] = 5.
		set SPHERE_AWAITING_LANDING_TIME[2] = 4.
		set SPHERE_AWAITING_LANDING_TIME[3] = 3.
		
		//The amount of energy pack would be released from the sphere
		set SPHERE_RELEASE_PACK_MAX[1] = 3
		set SPHERE_RELEASE_PACK_MAX[2] = 4
		set SPHERE_RELEASE_PACK_MAX[3] = 5
		
		//Maximum number of expired summons able to reabsorb back to the sphere
		set SPHERE_ABSORB_COUNT_MAX[1] = 6
		set SPHERE_ABSORB_COUNT_MAX[2] = 8
		set SPHERE_ABSORB_COUNT_MAX[3] = 10
		
		//
		set SPHERE_ABSORB_MAX_DIST[1] = 1000.
		set SPHERE_ABSORB_MAX_DIST[2] = 1000.
		set SPHERE_ABSORB_MAX_DIST[3] = 1000.
		
		//Minimum missle could be spawn after energy pack explode
		set ENERGY_PACK_MIN_MISSILE[1] = 1
		set ENERGY_PACK_MIN_MISSILE[2] = 1
		set ENERGY_PACK_MIN_MISSILE[3] = 2
		
		//Maximum missile could be spawn after energy pack explode
		set ENERGY_PACK_MAX_MISSILE[1] = 2
		set ENERGY_PACK_MAX_MISSILE[2] = 3
		set ENERGY_PACK_MAX_MISSILE[3] = 3
		
		//Minimum travel distance from shpere (horizontal)
		set MISSILE_MIN_DIST[1] = 100.
		set MISSILE_MIN_DIST[2] = 100.
		set MISSILE_MIN_DIST[3] = 100.
		
		//Maximum travel distance from sphere (horizontal)
		set MISSILE_MAX_DIST[1] = 250.
		set MISSILE_MAX_DIST[2] = 250.
		set MISSILE_MAX_DIST[3] = 250.
		
		//Setting the damage amount after the missile landed the ground
		set FIRST_DAMAGE[1] = 10.
		set FIRST_DAMAGE[2] = 20.
		set FIRST_DAMAGE[3] = 30.
		
		//Setting the AoE of the FIRST_DAMAGE
		set FIRST_DAMAGE_AOE[1] = 80.
		set FIRST_DAMAGE_AOE[2] = 110.
		set FIRST_DAMAGE_AOE[3] = 140.
		
		//Setting the unit-id of the first summons type after missile landed

		set FIRST_SUMMON[1] = 'h001'
		set FIRST_SUMMON[2] = 'h002'
		set FIRST_SUMMON[3] = 'h003'
		
		//Apply the time life for the FIRST_SUMMON unit type
		set FIRST_SUMMON_TIME_LIFE[1] = 10.
		set FIRST_SUMMON_TIME_LIFE[2] = 12.
		set FIRST_SUMMON_TIME_LIFE[3] = 14.
		
		//Setting the damage amount after the sphere landed the ground
		set SECOND_DAMAGE[1] = 100.
		set SECOND_DAMAGE[2] = 200.
		set SECOND_DAMAGE[3] = 300.
		
		//Setting the AoE of the SECOND_DAMAGE
		set SECOND_DAMAGE_AOE[1] = 500.
		set SECOND_DAMAGE_AOE[2] = 600.
		set SECOND_DAMAGE_AOE[3] = 700.
		
		//Setting the unit-id of the second summons type after sphere landed on the ground
		//Using : Water Elemental (war3 default unit)
		set SECOND_SUMMON[1] = 'h004'
		set SECOND_SUMMON[2] = 'h005'
		set SECOND_SUMMON[3] = 'h006'
		
		//Apply the time life for the SECOND_SUMMON unit type
		set SECOND_SUMMON_TIME_LIFE[1] = 30.
		set SECOND_SUMMON_TIME_LIFE[2] = 40.
		set SECOND_SUMMON_TIME_LIFE[3] = 50.
	endfunction
	
	private keyword OrbRotation
	
	//Dynamic array is used for OrbRotation struct
	//The size of the RotatingOrb should be same as SPHERE_ABSORB_COUNT_MAX[3]
	type RotatingOrb extends OrbRotation array[10]
	
	
	native UnitAlive takes unit id returns boolean
	
	//Unit filter before damaging
	//p = owner of casting unit
	//u = unit to filter
	private function EC_UnitFilter takes player p, unit u returns boolean
		return IsUnitEnemy(u, p) and UnitAlive(u)
	endfunction
	
	//Unit filter before reabsorb back to the sphere
	//Default set to :
	//1. expired will be reabsorbed back to the sphere
	//2. it is defined as absorbable
	//
	//Note : It is hardcoded that only FIRST_SUMMON unit type is reabsorbable by the sphere
	private function EC_AbsorbFilter takes unit killedUnit, unit killingUnit, integer spellLv, boolean absorbable returns boolean
		return killingUnit == null and absorbable
	endfunction
	
	//Add abilities to summon units, if any is defined
	//uId is the unit id of the summon unit
	private function SummonAddAbilities takes unit u, integer uId, integer spellLv returns nothing
		if uId == FIRST_SUMMON[spellLv] then
			//Add Energy Release to FIRST_SUMMON type unit
			call UnitAddAbility(u, 'A00D')
			call SetUnitAbilityLevel(u, 'A00D', spellLv)
		elseif uId == SECOND_SUMMON[spellLv] then
			//I have no idea what ability to create for SECOND_SUMMON type unit, add your own if you want to
		endif
	endfunction
//================================================================================
//==========================End Configurable Part=================================
//================================================================================





//================================================================================
//===========================Non-Configurable Part================================
//================================================================================
	globals
		private constant real				TWO_PI							= 2*bj_PI
		
		//Sphere's phases
		private	constant integer			SPHERE_GENERATING_PHASE 		= 0
		
		private constant integer			SPHERE_RELEASING_PHASE 			= 1
		
		private constant integer			SPHERE_AWAITING_PHASE			= 2
		
		private constant integer			SPHERE_LANDING_PHASE			= 3
		
		//A constant used by SphereMissile struct for increasing verticle velocity every TIMER_TIMEOUT
		private constant real				MISSILE_CONSTANT			= GRAVITATIONAL_FORCE*TIMER_TIMEOUT*TIMER_TIMEOUT
		
		//Orb Rotating's phases
		private constant integer			ORB_ROTATION_REABSORB_PHASE		= 0
		
		private constant integer			ORB_ROTATION_ROTATING_PHASE		= 1
		
		//Orb rotating constant, used for average angle calculation for each shell
		private constant integer			SECOND_MAX						= ORB_ROTATING_MAX_FIRST_SHELL+ORB_ROTATING_MAX_SECOND_SHELL
		
		private constant integer			THIRD_MAX						= SECOND_MAX+ORB_ROTATING_MAX_THIRD_SHELL
		
		
		private			 trigger			diedTrigger
	endglobals
	
	//Summons need to store the struct instance of ElementalChaos so that
	//the spell able to verify which summons belong to which instance
	static if LIBRARY_Table then
	/**/
	/**/globals
	/**/	private			 Table				 tb
	/**/endglobals
	/**/
	else
	/**/
	/**/globals
	/**/	private			 hashtable			 hash
	/**/endglobals
	/**/
	endif
	
	//A location handle is generated so that when orb rotating the shpere that is not on flat ground,
	//the height of orbs would still be parallel to the sphere
	static if not LIBRARY_ZLibrary then
	/**/
	/**/globals
	/**/	private			 location			 l							= Location(0, 0)
	/**/endglobals
	/**/
	endif
	
	private function DistanceBetweenCoordinates takes real x1, real y1, real x2, real y2 returns real
		local real dx = x2-x1
		local real dy = y2-y1
		return SquareRoot(dx*dx + dy*dy)
	endfunction
	
	static if not LIBRARY_ZLibrary then
	/**/
	/**/private function GetPointZ takes real x, real y returns real
	/**/	call MoveLocation(l, x, y)
	/**/	return GetLocationZ(l)
	/**/endfunction
	/**/
	endif
	
	private keyword ElementalChaos
//================================================================================
//=========================End Non-Configurable Part==============================
//================================================================================
	
	
	//----------------------------------------------------------------------
	//----------------------------------------------------------------------
	//A linked list created by myself
	module LinkedList
		static method create takes nothing returns thistype
			local thistype this = instanceCount + 1
			set instanceCount = this
			
			if thistype(0).next == 0 then
				set thistype(0).next = this
				set lastNode = this
			else
				set lastNode.next = this
				set this.prev = lastNode
				
				set lastNode = this
			endif
			
			set this.next = 0
			set thistype(0).prev = this
			
			return this
		endmethod
		
		method destroy takes nothing returns nothing
			set this.prev.next = this.next
			set this.next.prev = this.prev
			
			if this.next == 0 and this.prev == 0 then
				set instanceCount = 0
				
				//call instanceClear if exists
				static if thistype.instanceClear.exists then
					call thistype.instanceClear()
				endif
			elseif lastNode == this then
				set lastNode = this.prev
			endif
			
		endmethod
	endmodule
	//----------------------------------------------------------------------
	//----------------------------------------------------------------------
	
	
	//A struct that is made for the summon's custom spell accessment
	//Able to define whether FIRST_SUMMON is able to reabsorb, or not.
	struct ECData extends array		
		static method absorbable takes unit u, boolean b returns nothing
			static if LIBRARY_Table then
				set tb.boolean[GetHandleId(u)] = b
			else
				call SaveBoolean(hash, GetHandleId(u), 0, b)
			endif
		endmethod
	endstruct
	
	private struct OrbRotation extends array
		//===========Orb Rotation Globals=================
					static	timer				timerOR					= CreateTimer()					
		
							unit				dummy
							
							effect				e
							
							integer				phase
							integer				shell
							
							real				finalHeight
							real				height
							real				speedv
							real				x
							real				y
							real				angle
							real				destinationX
							real				destinationY
							
							ElementalChaos		ec
		//================================================
		
		//============Linked List Globals=================
		
		//spell's instance count
		private 	static  thistype 	instanceCount = 0
		
		//last allocated instance
		private 	static	thistype 	lastNode
		
		private 			thistype	next
		private 			thistype	prev
		//================================================
		
		private static method instanceClear takes nothing returns nothing
			call PauseTimer(timerOR)
		endmethod
		
		implement LinkedList
		
		static method onPeriodic takes nothing returns nothing
			local thistype this = thistype(0).next
			local integer i
			local real averageAngle
			local unit u
			
			loop
				exitwhen this == 0
				
				if this.phase == ORB_ROTATION_REABSORB_PHASE then
					set this.angle = Atan2(this.destinationY-this.y, this.destinationX-this.x)
					
					//move the unit toward the sphere (horizontally)
					set this.x = this.x + ORB_REABSORB_SPEED * Cos(this.angle)
					set this.y = this.y + ORB_REABSORB_SPEED * Sin(this.angle)
					
					call SetUnitX(this.dummy, this.x)
					call SetUnitY(this.dummy, this.y)
					
					//Set unit facing toward the sphere
					call SetUnitFacing(this.dummy, this.angle*bj_RADTODEG)
					
					//move the unit toward the sphere (vertically)
					set this.height = this.height + this.speedv
					
					call SetUnitFlyHeight(this.dummy, this.height, 0.)
					
					if this.finalHeight - this.height <= 0 then
						set this.phase = ORB_ROTATION_ROTATING_PHASE
						
						set ec.c = ec.c + 1
						set ec.order[ec.c] = this
						
						//Increase the number of "orb" rotating the sphere by one
						set ec.rotatingCount = ec.rotatingCount + 1
						
						//This part will be the explode effect of the orb after it get absorbed
						static if LIBRARY_DummyRecycler then
							set u = GetRecycledDummyAnyAngle(this.destinationX, this.destinationY, this.finalHeight)
							call DummyAddRecycleTimer(u, DUMMY_DEATH_TIME)
						else
							set u = CreateUnit(ec.owner, DUMMY_UNIT_ID, this.destinationX, this.destinationY, this.finalHeight)
							call UnitApplyTimedLife(u, 'BTLF', DUMMY_DEATH_TIME)
						endif
						
						//set unit scale and color
						call SetUnitScale(u, ORB_REABSORB_SCALE_EXPLODE, ORB_REABSORB_SCALE_EXPLODE, ORB_REABSORB_SCALE_EXPLODE)
						
						call SetUnitVertexColor(u, ORB_REABSORB_COLOR_RED_EXPLODE, ORB_REABSORB_COLOR_GREEN_EXPLODE, ORB_REABSORB_COLOR_BLUE_EXPLODE, ORB_REABSORB_TRANSPARENCY_EXPLODE)
						
						call DestroyEffect(AddSpecialEffectTarget(ORB_REABSORB_EFFECT_EXPLODE, u, ATTACHMENT_PATH))
						
						//repeating same thing : set unit scale and color
						call SetUnitScale(this.dummy, ORB_ROTATING_SCALE, ORB_ROTATING_SCALE, ORB_ROTATING_SCALE)
						call SetUnitVertexColor(this.dummy, ORB_ROTATING_COLOR_RED, ORB_ROTATING_COLOR_GREEN, ORB_ROTATING_COLOR_BLUE, ORB_RORATING_TRANSPARENCY)
						
						//destroy the effect and attach the new effect for sphere rotation
						call DestroyEffect(this.e)
						set this.e = AddSpecialEffectTarget(ORB_ROTATING_EFFECT_PATH, this.dummy, ATTACHMENT_PATH)
						
						//averagely set the angle according to the number of "orb" rotating in the shell respectively
						if ec.rotatingCount <= ORB_ROTATING_MAX_FIRST_SHELL then
							set this.shell = 1
							set i = 1
							set averageAngle = TWO_PI/ec.rotatingCount
							
							loop
								set ec.order[i].angle = i*averageAngle
								set i = i + 1
								exitwhen ec.order[i] == 0
							endloop
						elseif ec.rotatingCount <= SECOND_MAX then
							set this.shell = 2
							set i = 1 + ORB_ROTATING_MAX_FIRST_SHELL
							set averageAngle = TWO_PI/(ec.rotatingCount-ORB_ROTATING_MAX_FIRST_SHELL)
							
							loop
								set ec.order[i].angle = (i-ORB_ROTATING_MAX_FIRST_SHELL)*averageAngle
								set i = i + 1
								exitwhen ec.order[i] == 0
							endloop
						elseif ec.rotatingCount <= THIRD_MAX then
							set this.shell = 3
							set i = 1 + SECOND_MAX
							set averageAngle = TWO_PI/(ec.rotatingCount-SECOND_MAX)
							
							loop
								set ec.order[i].angle = (i-SECOND_MAX)*averageAngle
								set i = i + 1
								exitwhen ec.order[i] == 0
							endloop
						endif
					endif
				elseif this.phase == ORB_ROTATION_ROTATING_PHASE then
					//increase the angle according to the shell position
					if this.shell == 1 then
						set this.angle = this.angle + ORB_ROTATING_ANGLE_INCREASEMENT_FIRST
					elseif this.shell == 2 then
						set this.angle = this.angle + ORB_ROTATING_ANGLE_INCREASEMENT_SECOND
					else
						set this.angle = this.angle + ORB_ROTATING_ANGLE_INCREASEMENT_THIRD
					endif
					
					set this.x = this.destinationX + (ORB_ROTATING_DISTANCE + (this.shell-1)*ORB_ROTATING_DISTANCE_INCREASEMENT) * Cos(this.angle)
					set this.y = this.destinationY + (ORB_ROTATING_DISTANCE + (this.shell-1)*ORB_ROTATING_DISTANCE_INCREASEMENT) * Sin(this.angle)
					
					call SetUnitX(this.dummy, this.x)
					call SetUnitY(this.dummy, this.y)
					
					//height is vertically parallel to sphere's height
					static if LIBRARY_ZLibrary then
						call SetUnitFlyHeight(this.dummy, ec.terrainZ - GetSurfaceZ(this.x, this.y) + ec.sphereHeight, 0.)
					else
						call SetUnitFlyHeight(this.dummy, ec.terrainZ - GetPointZ(this.x, this.y) + ec.sphereHeight, 0.)
					endif
				endif
				
				set this = this.next
			endloop
		endmethod
		
		//destroy the orbs that rotating the sphere
		static method destroyOrbs takes ElementalChaos ec returns nothing
			local integer i = 1
			local thistype this
			
			loop
				set this = ec.order[i]
				
				static if LIBRARY_DummyRecycler then
					call RecycleDummy(this.dummy)
				else
					call RemoveUnit(this.dummy)
				endif
				
				call DestroyEffect(this.e)
				
				set this.dummy 	= null
				set this.e		= null
				
				call this.destroy()
				
				set ec.order[i] = 0
				
				//exitwhen when no more orbs rotating the sphere (haven't reach max orbs rotating the sphere)
				//exitwhen when destroyed orbs that rotating the sphere == maximum number of orb rotating the sphere
				exitwhen ec.order[i+1] == 0 or i == ec.order.size
				set i = i + 1
			endloop
		endmethod
	endstruct
	
	private struct SphereMissile extends array
		//==========Sphere Side Effect Globals============
					static  timer			timerSM				= CreateTimer()
		private		static	group			g					= CreateGroup()
					
							player			owner			//Owner of the missile
							
							unit			dummy
							
							effect			e
							
							integer			spellLv
							
							real			x
							real			y
							real			speedX			//speed value travelling along x-axis
							real			speedY			//speed value travelling along y-axis
							real			speedv
							real			height
							
							ElementalChaos	ec
		//================================================
		
		//============Linked List Globals=================
		
		//spell's instance count
		private 	static  thistype 	instanceCount = 0
		
		//last allocated instance
		private 	static	thistype 	lastNode
		
		private 			thistype	next
		private 			thistype	prev
		//================================================
		
		private static method instanceClear takes nothing returns nothing
			call PauseTimer(timerSM)
		endmethod
		
		implement LinkedList
		
		static method onPeriodic takes nothing returns nothing
			local thistype this = thistype(0).next
			local unit u		= null
			
			loop
				exitwhen this == 0
				
				//Move the unit horizontally
				set this.x = this.x + this.speedX
				set this.y = this.y + this.speedY
				call SetUnitX(this.dummy, this.x)
				call SetUnitY(this.dummy, this.y)
				
				//Move the unit vertically
				//v = u + at
				//u = this.speedv , a = -GRAVITATIONAL_FORCE, t = TIMER_TIMEOUT
				set this.speedv = this.speedv + MISSILE_CONSTANT
				set this.height = this.height - this.speedv
				
				call SetUnitFlyHeight(this.dummy, this.height, 0.)
				
				//Check if missile reached ground
				if this.height <= 0 then
					//Destroy missile effect
					call DestroyEffect(this.e)
					
					//Damage the units caught in it
					call GroupEnumUnitsInRange(g, this.x, this.y, FIRST_DAMAGE_AOE[this.spellLv], null)
					
					loop
						set u = FirstOfGroup(g)
						exitwhen u == null
						
						if EC_UnitFilter(this.owner, u) then
							call UnitDamageTarget(this.dummy, u, FIRST_DAMAGE[this.spellLv], true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
						endif
						
						call GroupRemoveUnit(g, u)
					endloop
					
					//Spawn the summons out
					set u = CreateUnit(this.owner, FIRST_SUMMON[this.spellLv], this.x, this.y, GetRandomReal(0, 360))
					
					//Add the summons to unit group
					call GroupAddUnit(ElementalChaos.unitGroup, u)
					
					//Store the ElementalChaos instance to the summon unit
					call ec.storeInstance(u)
					
					//Set the boolean of absorbable to true
					call ECData.absorbable(u, true)
					
					//Add the ability to the unit, if any is defined
					call SummonAddAbilities(u, GetUnitTypeId(u), this.spellLv)
					
					//Apply time life (Summons)
					call UnitApplyTimedLife(u, 'BTLF', FIRST_SUMMON_TIME_LIFE[this.spellLv])
					
					//Modify unit scale (dummy)
					call SetUnitScale(this.dummy, MISSILE_LANDED_SCALE, MISSILE_LANDED_SCALE, MISSILE_LANDED_SCALE)
					
					//Modify unit color (dummy)
					call SetUnitVertexColor(this.dummy, MISSILE_LANDED_COLOR_RED, MISSILE_LANDED_COLOR_GREEN, MISSILE_LANDED_COLOR_BLUE, MISSILE_LANDED_TRANSPARENCY)
					
					//Add landed effect
					call DestroyEffect(AddSpecialEffectTarget(MISSILE_LANDED_EFFECT_PATH, this.dummy, ATTACHMENT_PATH))
					
					//Apply time life (dummy)
					static if LIBRARY_DummyRecycler then
						call DummyAddRecycleTimer(this.dummy, DUMMY_DEATH_TIME)
					else
						call UnitApplyTimedLife(this.dummy, 'BTLF', DUMMY_DEATH_TIME)
					endif
					
					call this.destroy()
					
					set this.owner = null
					set this.dummy = null
					set this.e	   = null
				endif
				
				set this = this.next
			endloop
		endmethod
	endstruct
	
	
	
	
	
	private struct SphereEnergyPack extends array
		//==========Sphere Side Effect Globals============
					static	timer			timerSEP			= CreateTimer()
		
							player			owner
							
							unit			dummy
							
							effect			e 					//effect attached to dummy
							
							integer			missileCount		//Number of missile spawn after energy pack explode
							integer			spellLv
							
							real			x 					//y coordinate of energy pack
							real			y 					//x coordinate of energy pack
							real			height 				//height of energy pack from sphere
							real			speedh 				//speed horizontal (constant)
							real			speedv 				//speed verticle (non-constant)
							real			remainingTime 		//time taken for energy pack explode
							
							real			destinationX		//energy's pack destination x-coordinate
							real			destinationY		//energy's pack destination y-coordinate
							real			destinationDistance //distance between energy pack and destination of energy pack
							
							ElementalChaos	ec
		//================================================
	
		//============Linked List Globals=================
		
		//spell's instance count
		private 	static  thistype 	instanceCount = 0
		
		//last allocated instance
		private 	static	thistype 	lastNode
		
		private 			thistype	next
		private 			thistype	prev
		//================================================
		
		private static method instanceClear takes nothing returns nothing
			call PauseTimer(timerSEP)
		endmethod
		
		implement LinkedList
		
		static method onPeriodic takes nothing returns nothing
			local SphereMissile sm
			
			local thistype  	this  = thistype(0).next
			local integer		i
			local real			angle
			local real			r
			local real			time
			
			loop
				exitwhen this == 0
				
				set angle = Atan2(this.destinationY-GetUnitY(this.dummy), this.destinationX-GetUnitX(this.dummy))
				
				//move the energy pack towards destinationX/Y (horizontally)
				set this.destinationDistance = this.destinationDistance - this.speedh
				set this.x = this.x + this.speedh * Cos(angle)
				set this.y = this.y + this.speedh * Sin(angle)
				call SetUnitX(this.dummy, this.x)
				call SetUnitY(this.dummy, this.y)
				
				//move the energy pack towards destiantionHeight (vertically)
				set this.height = this.height + this.speedv
				call SetUnitFlyHeight(this.dummy, this.height, 0.)
				
				//Decrease the explode time by TIMER_TIMEOUT seconds
				set this.remainingTime = this.remainingTime - TIMER_TIMEOUT
				
				//Check if energy pack reaches its destination OR remainingTime <= 0
				if this.destinationDistance <= 0 or this.remainingTime <= 0 then
					//destroy the energy pack effect
					call DestroyEffect(this.e)
					
					//change the unit (effect) color
					call SetUnitVertexColor(this.dummy, ENERGY_PACK_EXPLODE_COLOR_RED, ENERGY_PACK_EXPLODE_COLOR_GREEN, ENERGY_PACK_EXPLODE_COLOR_BLUE, ENERGY_PACK_EXPLODE_TRANSPARENCY)
					
					//change the unit scale
					call SetUnitScale(this.dummy, ENERGY_PACK_EXPLODE_SCALE, ENERGY_PACK_EXPLODE_SCALE, ENERGY_PACK_EXPLODE_SCALE)
					
					//add the explode effect to the dummy
					call DestroyEffect(AddSpecialEffectTarget(ENERGY_PACK_EXPLODE_PATH, this.dummy, ATTACHMENT_PATH))
					
					//add life time to the dummy
					static if LIBRARY_DummyRecycler then
						//call DummyAddRecycleTimer(this.dummy, DUMMY_DEATH_TIME)
					else
						call UnitApplyTimedLife(this.dummy, 'BTLF', DUMMY_DEATH_TIME)
					endif
				
					set i = 0
					loop
						set i = i + 1
						
						//Create a new missile
						set sm = SphereMissile.create()
						
						//Setting up missile requires data
						set sm.height		 = GetRandomReal(MISSILE_MIN_HEIGHT, MISSILE_MAX_HEIGHT)
						set sm.spellLv		 = this.spellLv
						set sm.owner		 = this.owner
						set sm.ec			 = this.ec
						set sm.x			 = this.x
						set sm.y			 = this.y
						
						static if LIBRARY_DummyRecycler then
							set sm.dummy		 = GetRecycledDummyAnyAngle(this.x, this.y, this.height)
						else
							set sm.dummy		 = CreateUnit(this.owner, DUMMY_UNIT_ID, this.x, this.y, 0.)
							
							call SetUnitFlyHeight(sm.dummy, this.height, 0.)
						endif
						
						//Kinemtic formula is used : v*v = u*u + 2as
						//Check if height is positive
						if sm.height > 0 then
							//Rearrange : u = SquareRoot(v*v - 2as)
							//a = -GRAVITATIONAL_FORCE (against gravitational force), v = 0
							//So : u = -1 * SquareRoot(2*GRAVITATIONAL_FORCE*s)
							set sm.speedv = -1 * SquareRoot(2*GRAVITATIONAL_FORCE*sm.height)
						else
							//a = GRAVITATIONAL_FORCE, u = 0
							set sm.speedv = 0.
						endif
						
						//Set the height to the height where it should be
						set sm.height		 = this.height + sm.height
						//To obtain the total time taken for the motion, t1 = upward motion (if present), t2 = downward motion
						//Calculation are in unit : PER SECOND
						//For t1 : use v = u + at
						//v = 0, u = sm.speedv, a = -GRAVITATIONAL_FORCE, t1 = ?
						//So : t1 = -u/a
						//For t2 : use s = ut + (1/2)at*t
						//s = sm.height (total height), u = 0, a = GRAVITATIONAL_FORCE, t2 = ?
						//So : t2 = SquareRoot(2s/a)
						//	   t2 = SquareRoot((2*sm.height)/GRAVITATIONAL_FORCE)
						set time			 = (-sm.speedv/GRAVITATIONAL_FORCE) + SquareRoot((2*sm.height)/GRAVITATIONAL_FORCE)
						//Covert sm.speedv's unit from PER SECOND to PER TIMER_TIMEOUT
						set sm.speedv		 = sm.speedv * TIMER_TIMEOUT
						//let r = distance
						//speedh = r/time
						//Cos(angle) = constant, Sin(angle) = constant
						//so : (r/time) * Cos/Sin(angle) unit : PER SECOND
						//Convert PER SECOND to PER TIMER_TIMEOUT :
						// (r/time) * Cos/Sin(angle) * TIMER_TIMEOUT
						set r				 = GetRandomReal(MISSILE_MIN_DIST[this.spellLv], MISSILE_MAX_DIST[this.spellLv])
						set angle			 = GetRandomReal(-bj_PI, bj_PI)
						set sm.speedX		 = (r/time) * Cos(angle) * TIMER_TIMEOUT
						set sm.speedY		 = (r/time) * Sin(angle) * TIMER_TIMEOUT
						
						//Setting up dummy's data
						call SetUnitScale(sm.dummy, MISSILE_SCALE, MISSILE_SCALE, MISSILE_SCALE)
						
						call SetUnitVertexColor(sm.dummy, MISSILE_COLOR_RED, MISSILE_COLOR_GREEN, MISSILE_COLOR_BLUE, MISSILE_TRANSPARENCY)
						
						set sm.e			 = AddSpecialEffectTarget(MISSILE_EFFECT_PATH, sm.dummy, ATTACHMENT_PATH)
						
						if sm == 1 then
							call TimerStart(SphereMissile.timerSM, TIMER_TIMEOUT, true, function SphereMissile.onPeriodic)
						endif
						
						exitwhen i == this.missileCount //exitwhen created missile == number of missile gonna be fired
					endloop
					
					call this.destroy()
					
					set this.owner = null
					set this.dummy = null
					set this.e	   = null
				endif
				
				set this = this.next
			endloop
		endmethod
	endstruct
	
	
	
	
	
	private struct SphereParticleEffect extends array
		//==========Sphere Side Effect Globals============
					static	timer		timerSPE			= CreateTimer()
		
							unit		dummy
							
							effect		e					 	//effect attached to dummy
							
							real		x 						//y coordinate of particle
							real		y 						//x coordinate of particle
							real		distance 				//distance between sphere and particle
							real		height					//height between sphere and particle
							real		speedh 					//speed horizontal (constant)
							real		speedv 					//speed verticle (constant)
							
							real		destinationHeight 		//sphere height
							real		destinationX			//sphere x coordinate
							real		destinationY 			//sphere y coordinate
		//================================================
		
		//============Linked List Globals=================
		
		//spell's instance count
		private 	static  thistype 	instanceCount = 0
		
		//last allocated instance
		private 	static	thistype 	lastNode
		
		private 			thistype	next
		private 			thistype	prev
		//================================================
		
		private static method instanceClear takes nothing returns nothing
			call PauseTimer(timerSPE)
		endmethod
		
		implement LinkedList
		
		static method onPeriodic takes nothing returns nothing
			local thistype  this  = thistype(0).next
			local real 		angle
			local real 		x2
			
			loop
				exitwhen this == 0
				
				if this.distance >= PARTICLE_EFFECT_END_DIST then
					set this.distance = this.distance - this.speedh
					
					set x2 = GetUnitX(this.dummy)-this.destinationX
					set angle = Atan2(GetUnitY(this.dummy)-this.destinationY, x2)
					
					//move the particle toward sphere (verticle)
					set this.height = this.height - this.speedv
					call SetUnitFlyHeight(this.dummy, this.destinationHeight + this.height * Cos(Atan2(this.destinationHeight-this.height,x2)), 0.)
					
					//move the particle toward sphere (horizontal)
					set this.x = this.x - this.speedh * Cos(angle)
					set this.y = this.y - this.speedh * Sin(angle)
					
					call SetUnitX(this.dummy, this.x)
					call SetUnitY(this.dummy, this.y)
					
				else
					call DestroyEffect(this.e)
					
					static if LIBRARY_DummyRecycler then
						call RecycleDummy(this.dummy)
					else
						call RemoveUnit(this.dummy)
					endif
					
					call this.destroy()
					
					set this.e = null
					set this.dummy = null
				endif
				set this = this.next
			endloop
		endmethod
	endstruct
	
	
	
	
	
	private struct ElementalChaos extends array
		//============Elemental Chaos Globals=============
		private		static	timer		timerEC					= CreateTimer() //Elemental Chaos Timer
		
		private				unit		triggerUnit
		private				unit		sphere
		
		private				effect		sphereEffect
		
		public		static	group		unitGroup				= CreateGroup() //Group used for storing FIRST_SUMMON units
		private		static	group		g						= CreateGroup()	//Group used for enum unit in range, and damage them
		
		public				player		owner
		
		private				integer		spellLv
		private				integer		phase					//spell phase
		private				integer		releasedPack			//amount of energy pack released from sphere
		private				integer		summonsDiedCount		//number of expired/killed summons
		private				integer		summonsSpawnCount		//Total number of summons spawned
		private				integer		absorbCount				//number of expired summons reabsorb to the sphere
		private				integer		maximumAbsorbCount		//maximum number of expired summons able to reabsorb to the sphere
		public				integer		rotatingCount			//the number of "orb" rotating the sphere
		public				integer		c
		
		private				real		targetX					//spell target X
		private				real		targetY					//spell target Y
		private				real		duration				//duration that used for calculate the time between a phase to another phase
		private				real		sphereScale
		private				real		sphereScaleConst		//sphere scale increasement constant every TIMER_TIMEOUT seconds
		private				real		packReleaseTimePassed	//energy pack release interval, increases every TIMER_TIMEOUT seconds
		
		private				real		sphereGenerateTime
		public				real		sphereHeight
		public				real		terrainZ				//The height of the terrain at the sphere point
		
		public				RotatingOrb	order					//The order of the orbs that rotating around the sphere
		//================================================
		
		//============Linked List Globals=================
		
		//spell's instance count
		private 	static  thistype 	instanceCount = 0
		
		//last allocated instance
		private 	static	thistype 	lastNode
		
		private 			thistype	next
		private 			thistype	prev
		//================================================
		//instanceClear will be called if no more instance is running
		private static method instanceClear takes nothing returns nothing
			call PauseTimer(timerEC)
			call DisableTrigger(diedTrigger)
		endmethod
		
		implement LinkedList
		
		//Store the instance to a summon unit
		method storeInstance takes unit u returns nothing
			static if LIBRARY_Table then
				set tb.integer[GetHandleId(u)] = this
			else
				call SaveInteger(hash, GetHandleId(u), 0, this)
			endif
		endmethod
		
		//Retrieve the instance from a summon unit
		static method retrieveInstance takes unit u returns ElementalChaos
			static if LIBRARY_Table then
				return tb.integer[GetHandleId(u)]
			else
				return LoadInteger(hash, GetHandleId(u), 0)
			endif
		endmethod
		
		private static method onDied takes nothing returns boolean
			local unit u = GetTriggerUnit()
			local thistype this
			local OrbRotation ort
			local boolean b
			
			if IsUnitInGroup(u, thistype.unitGroup) then
				call GroupRemoveUnit(thistype.unitGroup, u)
				
				set this = retrieveInstance(u)
				
				//increase the died count by one
				set this.summonsDiedCount = this.summonsDiedCount + 1
				
				//Check if the died summons unit is within the range of the sphere
				if DistanceBetweenCoordinates(GetUnitX(u), GetUnitY(u), this.targetX, this.targetY) <= SPHERE_ABSORB_MAX_DIST[this.spellLv] then
					//load the stored boolean (absorbable) from the summon unit
					static if LIBRARY_Table then
						set b = tb.boolean[GetHandleId(u)]
					else
						set b = LoadBoolean(hash, GetHandleId(u), 0)
					endif
					
					//Filter if unit could be reabsorb back to the sphere
					if EC_AbsorbFilter(u, GetKillingUnit(), this.spellLv, b) then
						//if summons absorb count < maximum summons absorb count
						if this.absorbCount < this.maximumAbsorbCount then
							set this.absorbCount = this.absorbCount + 1
							
							set ort = OrbRotation.create()
							
							//Setting up the data
							set ort.ec						= this
							set ort.finalHeight				= this.sphereHeight
							set ort.x						= GetUnitX(u)
							set ort.y						= GetUnitY(u)
							set ort.destinationX			= this.targetX
							set ort.destinationY			= this.targetY
							//SquareRoot((this.targetX-ort.x)*(this.targetX-ort.x) + (this.targetY-ort.y)*(this.targetY-ort.y)) : distance between dummy unit position and sphere position
							//distance/SPHERE_REABSORB_SPEED = time taken
							//speedv = final height/time
							set ort.speedv					= this.sphereHeight/(SquareRoot((this.targetX-ort.x)*(this.targetX-ort.x) + (this.targetY-ort.y)*(this.targetY-ort.y))/ORB_REABSORB_SPEED)
							set ort.phase					= ORB_ROTATION_REABSORB_PHASE
							set ort.height					= 0.
							
							static if LIBRARY_DummyRecycler then
								set ort.dummy				= GetRecycledDummy(ort.x, ort.y, 0., Atan2(ort.y-this.targetY, ort.x-this.targetX)*bj_RADTODEG)
							else
								set ort.dummy				= CreateUnit(this.owner, DUMMY_UNIT_ID, ort.x, ort.y, Atan2(ort.y-this.targetY, ort.x-this.targetX)*bj_RADTODEG)
							endif
							
							set ort.e						= AddSpecialEffectTarget(ORB_REABSORB_EFFECT_MISSILE, ort.dummy, ATTACHMENT_PATH)
							
							call SetUnitVertexColor(ort.dummy, ORB_REABSORB_COLOR_RED_MISSILE, ORB_REABSORB_COLOR_GREEN_MISSILE, ORB_REABSORB_COLOR_BLUE_MISSILE, ORB_REABSORB_TRANSPARENCY_MISSILE)
							
							call SetUnitScale(ort.dummy, ORB_REABSORB_SCALE_MISSILE, ORB_REABSORB_SCALE_MISSILE, ORB_REABSORB_SCALE_MISSILE)
							
							if ort == 1 then
								call TimerStart(ort.timerOR, TIMER_TIMEOUT, true, function OrbRotation.onPeriodic)
							endif
						endif
					endif
				endif
				
				static if LIBRARY_Table then
					call tb.remove(GetHandleId(u))
				else
					call FlushChildHashtable(hash, GetHandleId(u))
				endif
			endif
			
			set u = null
			return false
		endmethod
		
		private static method onPeriodic takes nothing returns nothing
			local SphereParticleEffect  particleEffect
			local SphereEnergyPack		energyPack
			
			local thistype  this = thistype(0).next
			local unit		u	 = null
			local real		rand
			local real		angle
			
			loop
				exitwhen this == 0
				
				//phase 0 indicates sphere generating phase
				if this.phase == SPHERE_GENERATING_PHASE then
					set this.duration = this.duration + TIMER_TIMEOUT
					//=================================================================================
					//Generate Effect of the sphere (the effect shows when sphere is generating)
					//=================================================================================
					//if (sphere generate time - passed spell timing) >= PARTICLE_EFFECT_STOP_TIMING
					if (this.sphereGenerateTime-this.duration) >= PARTICLE_EFFECT_STOP_TIMING then
						set particleEffect = SphereParticleEffect.create()
						
						//Setting up particle data
						set particleEffect.destinationHeight	= this.sphereHeight
						set particleEffect.destinationX			= this.targetX
						set particleEffect.destinationY			= this.targetY
						set particleEffect.distance				= GetRandomReal(PARTICLE_EFFECT_MIN_DIST, PARTICLE_EFFECT_MAX_DIST)
						set particleEffect.height				= GetRandomReal(PARTICLE_EFFECT_MIN_HEIGHT, PARTICLE_EFFECT_MAX_HEIGHT)
						set particleEffect.speedh				= GetRandomReal(PARTICLE_EFFECT_MIN_SPEED, PARTICLE_EFFECT_MAX_SPEED)
						//speedv = height / time
						//time = ditance / speedh
						set particleEffect.speedv				= particleEffect.height/(particleEffect.distance/particleEffect.speedh)
						set particleEffect.x					= this.targetX + particleEffect.distance * Cos(GetRandomReal(-bj_PI, bj_PI))
						set particleEffect.y					= this.targetY + particleEffect.distance * Sin(GetRandomReal(-bj_PI, bj_PI))
						set angle 								= Atan2(particleEffect.y-this.targetY, particleEffect.x-this.targetX) * bj_RADTODEG
						
						static if LIBRARY_DummyRecycler then
							set particleEffect.dummy			= GetRecycledDummy(particleEffect.x, particleEffect.y, particleEffect.height, angle)
						else
							set particleEffect.dummy			= CreateUnit(this.owner, DUMMY_UNIT_ID, particleEffect.x, particleEffect.y, angle)
						
							//set unit height
							call SetUnitFlyHeight(particleEffect.dummy, this.sphereHeight + particleEffect.height, 0)
						endif
						
						set particleEffect.e					= AddSpecialEffectTarget(PARTICLE_EFFECT_PATH, particleEffect.dummy, ATTACHMENT_PATH)
						
						//Set unit scale randomly
						set rand = GetRandomReal(PARTICLE_EFFECT_MIN_SCALE, PARTICLE_EFFECT_MAX_SCALE)
						call SetUnitScale(particleEffect.dummy, rand, rand, rand)
						
						
						//rendomly obtain a number so that height can be appear lower or higher thn the sphere
						if GetRandomInt(0, 1) == 1 then
							set particleEffect.height = particleEffect.height * -1
						endif
						
						//adjust the color compoennt of the unit
						call SetUnitVertexColor(particleEffect.dummy, PARTICLE_EFFECT_COLOR_RED, PARTICLE_EFFECT_COLOR_GREEN, PARTICLE_EFFECT_COLOR_BLUE, PARTICLE_EFFECT_TRANSPARENCY)
						
						if particleEffect == 1 then
							call TimerStart(SphereParticleEffect.timerSPE, TIMER_TIMEOUT, true, function SphereParticleEffect.onPeriodic)
						endif
						
						//Setting sphere scale, reason it is inside this block is to prevent sphere increasing scale when no more particle effects
						//are generated.
						set this.sphereScale = this.sphereScale + this.sphereScaleConst
						call SetUnitScale(this.sphere, this.sphereScale, this.sphereScale, this.sphereScale)
					endif
					//=================================================================================
					//===========================End Sphere Generate Effect============================
					//=================================================================================
					
					//Check if the spell duration >= sphere generate time
					if this.duration >= this.sphereGenerateTime then
						//Sphere generate phase ends, switch spell phase to 1
						set this.phase = SPHERE_RELEASING_PHASE
					endif
				elseif this.phase == SPHERE_RELEASING_PHASE then
					//If released energy pack count < SPHERE_RELEASE_PACK_MAX[spellLv]
					if this.releasedPack < SPHERE_RELEASE_PACK_MAX[this.spellLv] then
					/************************************************************************************************************/
					/**/if this.packReleaseTimePassed >= SPHERE_PACK_RELEASE_INTERVAL then
					/**/	set this.packReleaseTimePassed  = 0.
					/**/	set this.releasedPack			= this.releasedPack + 1
					/**/
					/**/	set energyPack = SphereEnergyPack.create()
					/**/	
					/**/	//Setting up energy pack data
					/**/	set energyPack.destinationDistance	 = GetRandomReal(ENERGY_PACK_MIN_DIST, ENERGY_PACK_MAX_DIST) //final distance between sphere and energy pack
					/**/	set energyPack.speedh 				 = GetRandomReal(ENERGY_PACK_MIN_SPEED, ENERGY_PACK_MAX_SPEED)
					/**/	//Height/time
					/**/	set energyPack.speedv				 = GetRandomReal(ENERGY_PACK_MIN_HEIGHT, ENERGY_PACK_MAX_HEIGHT)/*
																   *//(energyPack.destinationDistance/energyPack.speedh) //formula same as particleEffect
					/**/	set energyPack.remainingTime		 = GetRandomReal(ENERGY_PACK_EXPLODE_MIN_TIME, ENERGY_PACK_EXPLODE_MAX_TIME)
					/**/	set energyPack.missileCount			 = GetRandomInt(ENERGY_PACK_MIN_MISSILE[this.spellLv], ENERGY_PACK_MAX_MISSILE[this.spellLv])
					/**/	set	this.summonsSpawnCount			 = this.summonsSpawnCount + energyPack.missileCount //increase the spawn count
					/**/	set energyPack.spellLv				 = this.spellLv
					/**/	set energyPack.x 					 = this.targetX
					/**/	set energyPack.y 					 = this.targetY
					/**/	set energyPack.height 				 = this.sphereHeight
					/**/	set energyPack.owner				 = this.owner
					/**/	set energyPack.ec					 = this
					/**/	
					/**/	//create a unit to obtain the destinationX and destinationY
					/**/	set rand							 = GetRandomReal(-bj_PI, bj_PI)
					/**/	set angle							 = rand*bj_RADTODEG
					/**/
					/**/	static if LIBRARY_DummyRecycler then
					/**/		set energyPack.dummy			 = GetRecycledDummy(this.targetX, this.targetY, this.sphereHeight, angle)
					/**/	else
					/**/		set energyPack.dummy			 = CreateUnit(this.owner, DUMMY_UNIT_ID, this.targetX, this.targetY, angle)
					/**/
					/**/		//set unit height
					/**/		call SetUnitFlyHeight(energyPack.dummy, this.sphereHeight, 0.)
					/**/	endif
					/**/
					/**/	set energyPack.destinationX			 = this.targetX + energyPack.destinationDistance * Cos(rand)
					/**/	set energyPack.destinationY			 = this.targetY + energyPack.destinationDistance * Sin(rand)
					/**/	set energyPack.e					 = AddSpecialEffectTarget(ENERGY_PACK_EFFECT_PATH, energyPack.dummy, ATTACHMENT_PATH)
					/**/
					/**/	//Set unit scale
					/**/	set rand = GetRandomReal(ENERGY_PACK_MIN_SCALE, ENERGY_PACK_MAX_SCALE)
					/**/	call SetUnitScale(energyPack.dummy, rand, rand, rand)
					/**/
					/**/	//set unit color	
					/**/	call SetUnitVertexColor(energyPack.dummy, ENERGY_PACK_COLOR_RED, ENERGY_PACK_COLOR_GREEN, ENERGY_PACK_COLOR_BLUE, ENERGY_PACK_TRANSPARENCY)
					/**/
					/**/
					/**/	if energyPack == 1 then
					/**/		call TimerStart(SphereEnergyPack.timerSEP, TIMER_TIMEOUT, true, function SphereEnergyPack.onPeriodic)
					/**/	endif
					/**/else
					/**/	//increase the time passed by TIMER_TIMEOUT seconds
					/**/	set this.packReleaseTimePassed = this.packReleaseTimePassed + TIMER_TIMEOUT
					/**/endif
					/************************************************************************************************************/
					else
						set this.phase = SPHERE_AWAITING_PHASE
					endif
				elseif this.phase == SPHERE_AWAITING_PHASE then
					//Ensure all summons expired, as well as all absorbed summons are rotating the sphere
					
					if this.absorbCount == this.rotatingCount and this.summonsDiedCount == this.summonsSpawnCount then
						set this.phase = SPHERE_LANDING_PHASE
						set this.duration = SPHERE_AWAITING_LANDING_TIME[this.spellLv]
					endif
				elseif this.phase == SPHERE_LANDING_PHASE then
					//wait for a certain time before the sphere starts to land down
					if this.duration > 0 then
						set this.duration = this.duration - TIMER_TIMEOUT
					else
						//decrease the sphere height periodically
						set this.sphereHeight = this.sphereHeight - SPHERE_LANDING_SPEED
						call SetUnitFlyHeight(this.sphere, this.sphereHeight, 0.)
					
						//if sphere height landed on the ground
						if this.sphereHeight <= 0 then
							//destroy the orbs rotating the sphere
							call OrbRotation.destroyOrbs(this)
							
							//destroy the sphere's effect
							call DestroyEffect(this.sphereEffect)
							
							//change the sphere scale, color for the sfx of the sphere landing on the ground
							call SetUnitScale(this.sphere, SPHERE_LANDED_SCALE, SPHERE_LANDED_SCALE, SPHERE_LANDED_SCALE)
							call SetUnitVertexColor(this.sphere, SPHERE_LANDED_COLOR_RED, SPHERE_LANDED_COLOR_GREEN, SPHERE_LANDED_COLOR_BLUE, SPHERE_LANDED_TRANSPARENCY)
							
							
							//attach the effect to the sphere
							call AddSpecialEffectTarget(SPHERE_LANDED_SFX, this.sphere, ATTACHMENT_PATH)
							
							//add the expire time for the sphere
							static if LIBRARY_DummyRecycler then
								call DummyAddRecycleTimer(this.sphere, DUMMY_DEATH_TIME)
							else
								call UnitApplyTimedLife(this.sphere, 'BTLF', DUMMY_DEATH_TIME)
							endif
							
							//damage nearby enemy units
							call GroupEnumUnitsInRange(g, this.targetX, this.targetY, SECOND_DAMAGE_AOE[this.spellLv], null)
							
							loop
								set u = FirstOfGroup(g)
								exitwhen u == null
								
								if EC_UnitFilter(this.owner, u) then
									call UnitDamageTarget(this.triggerUnit, u, SECOND_DAMAGE[this.spellLv], true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
								endif
								
								call GroupRemoveUnit(g, u)
							endloop
					
							//if there is no rotating orb, SECOND_SUMMON unit will not get summoned.
							if this.absorbCount > 0 then
								//summons the SECOND_SUMMON unit
								set u = CreateUnit(this.owner, SECOND_SUMMON[this.spellLv], this.targetX, this.targetY, 0.)
								
								//apply this time life to SECOND_SUMMON unit
								call UnitApplyTimedLife(u, 'BTLF', SECOND_SUMMON_TIME_LIFE[this.spellLv])
								
								//set the life of the SECOND_SUMMON unit based on the number of reabsorbed units
								call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE)*this.absorbCount/this.maximumAbsorbCount)
								
								//Add ability to SECOND_SUMMON unit
								call SummonAddAbilities(u, GetUnitTypeId(u), this.spellLv)
								
								set u = null
							endif
							
							//spell ends, destroy the instance
							call this.destroy()
							
							//destroy the dynamic array instance
							call this.order.destroy()
							
							//nulling variables
							set this.triggerUnit 	= null
							set this.sphere		 	= null
							set this.sphereEffect	= null
							set this.owner			= null
						endif
					endif
				endif
				
				set this = this.next
			endloop
			
		endmethod
		
		private static method onCast takes nothing returns nothing
			local thistype this = thistype.create()
			set this.order = RotatingOrb.create()
							
			//Storing data
			set this.triggerUnit				= GetTriggerUnit()
			set this.owner						= GetOwningPlayer(this.triggerUnit)
			set this.targetX					= GetSpellTargetX()
			set this.targetY					= GetSpellTargetY()
			set this.spellLv					= GetUnitAbilityLevel(this.triggerUnit, SPELL_ID)
			set this.phase						= SPHERE_GENERATING_PHASE
			set this.sphereGenerateTime			= SPHERE_GENERATE_TIME[this.spellLv]
			set this.sphereHeight				= SPHERE_HEIGHT[this.spellLv]
			set this.sphereScale				= SPHERE_INITIAL_SCALE
			set this.maximumAbsorbCount			= SPHERE_ABSORB_COUNT_MAX[this.spellLv]
												//sphereScaleConst is dependent on SPHERE_MAX_SCALE, SPHERE_GENERATE_TIME, TIMER_TIMEOUT and SHPERE_PARTICLE_STOP_TIMING
												//(this.sphereGenerateTime-PARTICLE_EFFECT_STOP_TIMING) : as sphere stop increase scale if no more particle is generating
												// divide by TIMER_TIMEOUT : to obtain the overall running times
												// SPHERE_MAX_SCALE[this.spellLv] : obtain the maximum scale of the sphere
												// maximum scale / running times : so that a constant is obtained for scale increasement every TIMER_TIMEOUT
			set this.sphereScaleConst 			= SPHERE_MAX_SCALE[this.spellLv]/((this.sphereGenerateTime-PARTICLE_EFFECT_STOP_TIMING)/TIMER_TIMEOUT)
			set this.duration					= 0.
			set this.packReleaseTimePassed		= 0.
			set this.releasedPack				= 0
			set this.summonsDiedCount			= 0
			set this.summonsSpawnCount			= 0
			set this.absorbCount				= 0
			set this.rotatingCount				= 0
			set this.c							= 0
				
			static if LIBRARY_DummyRecycler then
				set this.sphere 				= GetRecycledDummyAnyAngle(this.targetX, this.targetY, this.sphereHeight)
			else
				set this.sphere					= CreateUnit(this.owner, DUMMY_UNIT_ID, this.targetX, this.targetY, 0.)
				
				//Set the unit height
				call SetUnitFlyHeight(this.sphere, this.sphereHeight, 0.)
			endif
			
			//Store the Z height of the terrain at the sphere point
			static if LIBRARY_ZLibrary then
				set this.terrainZ = GetSurfaceZ(this.targetX, this.targetY)
			else
				set this.terrainZ = GetPointZ(this.targetX, this.targetY)
			endif
				
			//Setting the sphere to initial scale value
			call SetUnitScale(this.sphere, SPHERE_INITIAL_SCALE, SPHERE_INITIAL_SCALE, SPHERE_INITIAL_SCALE)
				
			//Setting the sphere color
			call SetUnitVertexColor(this.sphere, SPHERE_COLOR_RED, SPHERE_COLOR_GREEN, SPHERE_COLOR_BLUE, SPHERE_TRANSPARENCY)
				
			//Add the sphere effect to the unit
			set this.sphereEffect = AddSpecialEffectTarget(SPHERE_EFFECT_PATH, this.sphere, ATTACHMENT_PATH)
				
			if this == 1 then
				call TimerStart(timerEC, TIMER_TIMEOUT, true, function thistype.onPeriodic)
				call EnableTrigger(diedTrigger)
			endif
		endmethod
		
		static if not LIBRARY_SpellEffectEvent then
			private static method onCondition takes nothing returns boolean
				if GetSpellAbilityId() == SPELL_ID then
					call thistype.onCast()
				endif
				return false
			endmethod
		endif
		
		private static method onInit takes nothing returns nothing
			static if not LIBRARY_SpellEffectEvent then
				local trigger t = CreateTrigger()
				call TriggerAddCondition(t, Condition(function thistype.onCondition))
				call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
				set t = null
			else
				call RegisterSpellEffectEvent(SPELL_ID, function thistype.onCast)
			endif
			
			static if LIBRARY_Table then
				set tb = Table.create()
			endif
			
			set diedTrigger = CreateTrigger()
			call TriggerAddCondition(diedTrigger, Condition(function thistype.onDied))
			call TriggerRegisterAnyUnitEventBJ(diedTrigger, EVENT_PLAYER_UNIT_DEATH)
			call DisableTrigger(diedTrigger)
		endmethod
	endstruct
endlibrary
Summon's spell code :
Energy Explosion
JASS:
scope EnergyExplosion initializer Init
/*
*==========================================================================================================================*
	Sub spell from Elemental Chaos : FIRST_SUMMON active spell
*==========================================================================================================================*
	Spell Description :
	
		Unstabilized element unit maximize its disordered energy inside his body, causes an AoE explosion, 
		dealing moderate damage to nearby enemy units. Unit will be died and will not get reabsorbed back by the sphere.

		Level 1 - (Remaining Life/4) damage, 200 AoE
		
		Level 2 - (Remaining Life/4) damage, 250 AoE
		
		Level 3 - (Remaining Life/4) damage, 300 AoE

*==========================================================================================================================*

*/

	//================================================================================
	//============================Configurable Part===================================
	//================================================================================
	static if not LIBRARY_DummyRecycler then
	
	globals
		//Only need to set dummy unit id only if there is no DummyRecycler present
		//Dummy unit id
		private constant integer			DUMMY_UNIT_ID		= 'e000'
	endglobals
	
	endif

	globals
		private constant integer			SPELL_ID			= 'A00D'
		
		private constant string				ATTACHMENT_PATH 	= "origin"
		
		private constant real				DUMMY_DEATH_TIME	= 2.
		
		private constant damagetype			DAMAGE_TYPE			= DAMAGE_TYPE_NORMAL
		
		private constant attacktype			ATTACK_TYPE			= ATTACK_TYPE_NORMAL
		
		private constant weapontype			WEAPON_TYPE			= WEAPON_TYPE_WHOKNOWS
		
		private constant string				EXPLODE_SFX 		= "war3mapImported\\WaterBlast.mdx"
		
		private constant real				SFX_SCALE			= 1.5
		
		private constant integer			SFX_COLOR_RED		= 255
		
		private constant integer			SFX_COLOR_GREEN		= 255
		
		private constant integer			SFX_COLOR_BLUE		= 255
		
		private constant integer			SFX_TRANSPARENCY	= 255
		
		
		//Configure DAMAGE_AOE inside function Init
		private			 real		array	DAMAGE_AOE
		
		//Don't touch this, a permanent group for enum unit in range
		private			 group				g					= CreateGroup()
	endglobals
	
	//Init the damage AoE of the spell
	private function Init takes nothing returns nothing
		set DAMAGE_AOE[1] = 200
		set DAMAGE_AOE[2] = 250
		set DAMAGE_AOE[3] = 300
	endfunction
	
	//Filter of unit for damaging
	private function UnitFilter takes player p, unit u returns boolean
		return IsUnitEnemy(u, p) and UnitAlive(u)
	endfunction
	
	//Damage of the spell, i'm not using spellLv, you may change it as spellLv based
	private function Damage takes unit u, integer spellLv returns real
		return GetUnitState(u, UNIT_STATE_LIFE)/4.
	endfunction
	
	//================================================================================
	//==========================End Configurable Part=================================
	//================================================================================

	struct EnergyExplosion extends array
		private static method onCast takes nothing returns nothing
			local unit u = null
			local unit triggerUnit = GetTriggerUnit()
				
			local player p = GetOwningPlayer(triggerUnit)
				
			local integer i = GetUnitAbilityLevel(triggerUnit, SPELL_ID)
				
			local real x = GetUnitX(triggerUnit)
			local real y = GetUnitY(triggerUnit)
			
			call GroupEnumUnitsInRange(g, x, y, DAMAGE_AOE[i], null)
				
			loop
				set u = FirstOfGroup(g)
				exitwhen u == null
					
				if UnitFilter(p, u) then
					call UnitDamageTarget(triggerUnit, u, Damage(triggerUnit, i), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)	
				endif
					
				call GroupRemoveUnit(g, u)
			endloop
				
			static if LIBRARY_DummyRecycler then
				set u = GetRecycledDummyAnyAngle(x, y, 0.)
				call DummyAddRecycleTimer(u, DUMMY_DEATH_TIME)
			else
				set u = CreateUnit(p, DUMMY_UNIT_ID, x, y, 0.)
				call UnitApplyTimedLife(u, 'BTLF', DUMMY_DEATH_TIME)
			endif
				
			call SetUnitVertexColor(u, SFX_COLOR_RED, SFX_COLOR_GREEN, SFX_COLOR_BLUE, SFX_TRANSPARENCY)
			call SetUnitScale(u, SFX_SCALE, SFX_SCALE, SFX_SCALE)
			call DestroyEffect(AddSpecialEffectTarget(EXPLODE_SFX, u, ATTACHMENT_PATH))
					
			//Disable reabsorb for this unit
			call ECData.absorbable(triggerUnit, false)
			
			call KillUnit(triggerUnit)
				
			set triggerUnit = null
			set p = null
		endmethod
		
		static if not LIBRARY_SpellEffectEvent then
			private static method onCondition takes nothing returns boolean
				if GetSpellAbilityId() == SPELL_ID then
					call thistype.onCast()
				endif
				return false
			endmethod
		endif
		
		private static method onInit takes nothing returns nothing
			static if not LIBRARY_SpellEffectEvent then
				local trigger t = CreateTrigger()
				call TriggerAddCondition(t, Condition(function thistype.onCondition))
				call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
			else
				call RegisterSpellEffectEvent(SPELL_ID, function thistype.onCast)
			endif
		endmethod
	endstruct
	
endscope

Generating Sphere

Releasing Energy Pack

Energy Pack Explode

Energy Missile Landed Ground

Summons Expired

Reabsorption of summons

Fully Reabsorbed

Sphere Landed Ground

224529-albums8862-picture108949.jpg
224529-albums8862-picture108948.jpg
224529-albums8862-picture108939.jpg
224529-albums8862-picture108940.jpg
224529-albums8862-picture108941.jpg
224529-albums8862-picture108942.jpg
224529-albums8862-picture108943.jpg
224529-albums8862-picture108944.jpg

First Summon Spells

Second Summon Spell

Spell Name
Energy Loss
Spell Icon
224529-albums8862-picture108945.jpg
Spell Description
The elemental unit is constantly losing the energy from his body, resulting in loss of hit points over time.

Decreases hit point regeneration by 5/7/9 hit points per second.

Spell Name
Energy Explosion
Spell Icon
224529-albums8862-picture108946.jpg
Spell Description

Unstabilized element unit maximize its disordered energy inside his body, causes an AoE explosion, dealing moderate damage to nearby enemy units. Unit will be died and will not get reabsorbed back by the sphere.

Level 1 - (Remaining Life/4) damage, 200 AoE

Level 2 - (Remaining Life/4) damage, 250 AoE

Level 3 - (Remaining Life/4) damage, 300 AoE
Spell Name
Energy Absorption
Spell Icon
224529-albums8862-picture108947.jpg
Spell Description
The elemental unit is constantly absorbing the energy around him, replacing his lost energy.

Increases hit point regeneration by 5/10/15 hit points per second.
v1.0.1
  • Removed FIRST_SUMMON[spellLv] == GetUnitTypeId(killedUnit) from function EC_AbsorbFilter
v1.0.0
  • Initial upload
[tr]Credits
vJASS Systems

DummyRecycler - Flux

RegisterPlayerUnitEvent - Magtheridon96

SpellEffectEvent - Bribe

Table - Bribe

ZLibrary - D.O.G
Models

dummy unit - Vexorian

AnimateDeathTarget - JetFangInferno

Water Blast - JesusHipster

Stars_Lightning - Haistrah

blue thunder clap - DCrimson
Icons

BTNOrbOfWater - Mc !

BTNskill1 - Blizzard Entertainment

BTNWisp - Andreitch

BTNArcaneBlast - KelThuzad
Tool

Button Manager - Shadow Daemon
[tr][TD]
 

Attachments

  • DD_LegionTN - Elemental Chaos.w3x
    167.8 KB · Views: 132
Last edited:
Level 11
Joined
Dec 19, 2012
Messages
411
I believe after the contest deadline is over, and after the contest thread is closed (no more modification), you may upload to the spell section. But I personally suggest to upload the spell after the contest is completely over (so that you could receive some feedback from the judges and people) and do the final modification before upload it to spell section.
 
I'm not really aware of a clear rule towards this question, at this moment.
It's maybe not a perfect solution, and could be set clear for future spell contests right at the begining, but I personaly would prefer you to upload the spell after results are public.

Also BPower locked (or wanted to lock ?) uploaded entries, so we follow this at the moment, I would say.

It was great if there was an option to upload a submission in our section, marked as an "contest entry".
The thread should be insantly locked, when submitted, but be unlocked when the contest is over.
This way we would not have any problems with pre-reviews, but also can ensure to have all entries in our spell data base.
 
Level 22
Joined
Aug 27, 2013
Messages
3,973
It was great if there was an option to upload a submission in our section, marked as an "contest entry".
The thread should be insantly locked, when submitted, but be unlocked when the contest is over.
This way we would not have any problems with pre-reviews, but also can ensure to have all entries in our spell data base.
But then the submission will sink in the spell database until someone bump the thread.
 
Level 14
Joined
Jul 1, 2008
Messages
1,314
Final Entry: Chicken Rage

Hey guys, this is my final entry.

Allthough I did not have the time to polish this, but I wanted to upload it anyway, because I had a lot of fun making this:

Description


151951-albums8916-picture109051.jpg

151951-albums8916-picture109049.jpg

151951-albums8916-picture109050.jpg
Screenshots

151951-albums8916-picture109047.jpg

151951-albums8916-picture109048.jpg

Credits

Note: I learned heaps on www.wc3c.net, inWarcraft.de and here, but for example I cannot find the original credits for the function SIM_ERROR in my map, which might be Vexorian from www.wc3c.net. So If you recognize a snippet by yourself, please tell me. In this case, I am very sorry not to credit you!
Credits for non-blizzard ressources, all from (www.hiveworkshop.com)
- Ancient Explosion Model: WILL THE ALMIGHTY
- yellow chicken model: maxor_gan
- yellow chicken button: maxor_gan
- talk button: KelThuzad
- dummy.mdx: Vexorian (actual link of the mdx file unknown, but I think, Vexorian created it)
Comments

I like to wish good luck to everyone, that entered this contest and thank a lot the judges and people from the hive, that organize these contests!
 
Last edited:
Level 37
Joined
Jul 22, 2015
Messages
3,485

[GUI] Ice Anomaly



Description

Calls an orb from the skies. When the orb lands, it will knockback all nearby units. After a few seconds, the orb will become
attackable for a set duration where any damage taken will be reduced to one. Enemy units that die near the orb while it is
still alive will charge the orb, eventually resetting its duration, turning the orb invulnerable, and allowing the caster to move
and use its ability.​


Previews



attachment.php

attachment.php

attachment.php

attachment.php

attachment.php

attachment.php



Requirements



Triggers



  • IA Config
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- CONFIG START --------
      • Set IA_Ability = Ice Anomaly
      • Set IA_Order_ID = channel
      • -------- --------
      • -------- Orb Configurables --------
      • Set IA_OrbUnit = Ice Anomaly
      • Set IA_OrbSize = 1.00
      • Set IA_SFXOrb = war3mapImported\OrbIceX.mdl
      • Set IA_SFXOrb_AP = origin
      • Set IA_SFXTail = Abilities\Weapons\ZigguratFrostMissile\ZigguratFrostMissile.mdl
      • Set IA_SFXTail_AP = overhead
      • Set IA_SFXOrbDeath = war3mapImported\FrostSplosion.mdl
      • Set IA_SFXOrbDeath_AP = origin
      • -------- --------
      • -------- Spawn Configurables --------
      • Set IA_SpawnDistance = 800.00
      • Set IA_SpawnHeight = 1500.00
      • Set IA_FallTime = 1.50
      • Set IA_SFXLanding = Abilities\Weapons\FrostWyrmMissile\FrostWyrmMissile.mdl
      • -------- --------
      • -------- Landing Knockback Configurables --------
      • Set IA_KB_AoE = 200.00
      • Set IA_KB_AoEPerLevel = 0.00
      • -------- ^ 200 + (0 * AbilityLevel) = 200 AoE at all levels --------
      • -------- NOTE: Make sure AoE is the same value as the one defined in the object editor ability --------
      • Set IA_KB_Time = 1.00
      • Set IA_KB_TimePerLevel = 0.00
      • -------- ^ 1 + (0 * AbilityLevel) = 1 second at all levels --------
      • Set IA_KB_Distance = 100.00
      • Set IA_KB_DistancePerLevel = 0.00
      • -------- ^ 100 + (0 * AbilityLevel) = 100 units at all levels --------
      • Set IA_KB_MaxHeight = 100.00
      • -------- ^ because it would be weird if flying units were knocked back? xD --------
      • Set IA_KB_SFX = Abilities\Weapons\AncientProtectorMissile\AncientProtectorMissile.mdl
      • -------- --------
      • -------- Levitate Phase Configurables --------
      • Set IA_Delay = 2.00
      • Set IA_LevitateTime = 1.50
      • Set IA_OrbLevitateHeight = 250.00
      • -------- --------
      • -------- Search Phase Configurables --------
      • Set IA_OrbHP = 8
      • Set IA_OrbHPPerLevel = 2
      • -------- ^ 8 + (2 * AbilityLevel) = 10 HP at level 1 --------
      • -------- NOTE: Orb will take ONE damage from all sources --------
      • Set IA_SearchAoE = 900.00
      • Set IA_SearchAoEPerLevel = 0.00
      • -------- ^ 900 + (0 * AbilityLevel) = 900 AoE at all levels --------
      • Set IA_SearchStartIndicator = Abilities\Weapons\DragonHawkMissile\DragonHawkMissile.mdl
      • Set IA_SearchStartIndicator_AP = origin
      • -------- --------
      • -------- Fragment Configurables --------
      • Set IA_SFXFragment = Abilities\Weapons\SpiritOfVengeanceMissile\SpiritOfVengeanceMissile.mdl
      • Set IA_SFXFragment_AP = chest
      • Set IA_Frag_Speed = 8.00
      • -------- ^ Distance moved per iteration --------
      • Set IA_Frag_HeightOffset = 25.00
      • -------- ^ How high from the origin of the Orb should the frags land --------
      • Set IA_ArcPercentage = 30.00
      • -------- ^ What percentage of the distance will be the max height of parabola --------
      • Set IA_SFXFrag_Red = 0.00
      • Set IA_SFXFrag_Green = 0.00
      • Set IA_SFXFrag_Blue = 0.00
      • -------- --------
      • -------- Move Phase Configurables --------
      • Set IA_MoveStartIndicator = Abilities\Spells\Orc\LightningBolt\LightningBoltMissile.mdl
      • Set IA_MoveStartIndicator_AP = origin
      • -------- --------
      • -------- Mechanics --------
      • Set IA_OrbDuration = 12.00
      • Set IA_OrbDurationPerLevel = 4.00
      • -------- ^ 12 + (4 * AbilityLevel) = 16 seconds at level 1 --------
      • Set IA_RequiredKills = 5
      • Set IA_RequiredKillsPerLevel = -1
      • -------- ^ 5 + (-1 * AbilityLevel) = 4 kills required at level 1 --------
      • -------- --------
      • -------- Other --------
      • Set IA_ErrorMsg = Target point is not pathable.
      • Set IA_AttackType = Spells
      • Set IA_DamageType = Normal
      • -------- CONFIG END --------
      • -------- --------
      • Set IA_PeriodicTimer = (1.00 / 32.00)
      • Trigger - Add to IA Loop <gen> the event (Time - Every IA_PeriodicTimer seconds of game time)
      • Trigger - Add to IA Frag Loop <gen> the event (Time - Every IA_PeriodicTimer seconds of game time)
      • Set IA_OrbSize = (IA_OrbSize x 100.00)
      • Set IA_FallRate_XY = (IA_SpawnDistance / (IA_FallTime / IA_PeriodicTimer))
      • Set IA_FallRate_Z = (IA_SpawnHeight / (IA_FallTime / IA_PeriodicTimer))
      • Set IA_LevitateRate = (IA_OrbLevitateHeight / (IA_LevitateTime / IA_PeriodicTimer))
      • Set IA_ArcPercentage = (IA_ArcPercentage / 100.00)
      • Set IA_ZLoc = (Center of (Playable map area))
      • Unit - Create 1 IA_OrbUnit for Neutral Passive at IA_ZLoc facing Default building facing degrees
      • Set IA_TempUnit = (Last created unit)
      • Unit - Remove IA_TempUnit from the game
  • IA Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to IA_Ability
    • Actions
      • Set IA_SpellCount = (IA_SpellCount + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IA_SpellCount Equal to 1
        • Then - Actions
          • Trigger - Turn on IA Loop <gen>
        • Else - Actions
          • -------- IA Loop is already on; do nothing --------
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IA_RecycledSize Equal to 0
        • Then - Actions
          • Set IA_MaxIndex = (IA_MaxIndex + 1)
          • Set IA_Spell_ID = IA_MaxIndex
        • Else - Actions
          • Set IA_RecycledSize = (IA_RecycledSize - 1)
          • Set IA_Spell_ID = IA_RecycledStack[IA_RecycledSize]
      • Set IA_NodeNext[IA_Spell_ID] = 0
      • Set IA_NodeNext[IA_NodePrev[0]] = IA_Spell_ID
      • Set IA_NodePrev[IA_Spell_ID] = IA_NodePrev[0]
      • Set IA_NodePrev[0] = IA_Spell_ID
      • -------- --------
      • Set IA_Caster[IA_Spell_ID] = (Triggering unit)
      • Set IA_Owner[IA_Spell_ID] = (Triggering player)
      • Set IA_AbilityLvl[IA_Spell_ID] = (Level of IA_Ability for IA_Caster[IA_Spell_ID])
      • Set IA_Counter[IA_Spell_ID] = 0.00
      • Set IA_CounterKills[IA_Spell_ID] = 0
      • Set IA_DistanceTraveled[IA_Spell_ID] = 0.00
      • Set IA_CurrentHeight[IA_Spell_ID] = IA_SpawnHeight
      • Set IA_Phase[IA_Spell_ID] = 0
      • -------- --------
      • Set IA_TempReal = (Real(IA_AbilityLvl[IA_Spell_ID]))
      • Set IA_Duration[IA_Spell_ID] = (IA_OrbDuration + (IA_OrbDurationPerLevel x IA_TempReal))
      • Set IA_SearchRange[IA_Spell_ID] = (IA_SearchAoE + (IA_SearchAoEPerLevel x IA_TempReal))
      • Set IA_KillGoal[IA_Spell_ID] = (IA_RequiredKills + (IA_RequiredKillsPerLevel x IA_AbilityLvl[IA_Spell_ID]))
      • Set IA_DistanceKB[IA_Spell_ID] = (IA_KB_Distance + (IA_KB_DistancePerLevel x IA_TempReal))
      • Set IA_RangeKB[IA_Spell_ID] = (IA_KB_AoE + (IA_KB_AoEPerLevel x IA_TempReal))
      • Set IA_TimeKB[IA_Spell_ID] = (IA_KB_Time + (IA_KB_TimePerLevel x IA_TempReal))
      • -------- --------
      • Set IA_CurrentLoc = (Position of IA_Caster[IA_Spell_ID])
      • Set IA_TempLoc = (Target point of ability being cast)
      • Set IA_TempReal = (Angle from IA_CurrentLoc to IA_TempLoc)
      • Set IA_EffectLoc = (IA_TempLoc offset by IA_SpawnDistance towards IA_TempReal degrees)
      • -------- --------
      • Set IA_TempReal = (IA_TempReal + 180.00)
      • Unit - Create 1 IA_OrbUnit for IA_Owner[IA_Spell_ID] at IA_EffectLoc facing IA_TempReal degrees
      • Set IA_Orb[IA_Spell_ID] = (Last created unit)
      • -------- using SetUnit native so that unit can properly start from out of map regions --------
      • Custom script: call SetUnitX(udg_IA_Orb[udg_IA_Spell_ID], GetLocationX(udg_IA_EffectLoc))
      • Custom script: call SetUnitY(udg_IA_Orb[udg_IA_Spell_ID], GetLocationY(udg_IA_EffectLoc))
      • Custom script: if UnitAddAbility(udg_IA_Orb[udg_IA_Spell_ID], 'Amrf') then
      • Custom script: call UnitRemoveAbility(udg_IA_Orb[udg_IA_Spell_ID], 'Amrf')
      • Custom script: endif
      • Custom script: call CSS_AddBonus(udg_IA_Orb[udg_IA_Spell_ID], udg_IA_OrbHP + (udg_IA_OrbHPPerLevel*udg_IA_TempInt) - 1, 8)
      • Unit - Make IA_Orb[IA_Spell_ID] Invulnerable
      • -------- pausing unit so that it cannot be moved until PHASE 3 --------
      • Unit - Pause IA_Orb[IA_Spell_ID]
      • Unit - Turn collision for IA_Orb[IA_Spell_ID] Off
      • -------- --------
      • Set IA_Cos[IA_Spell_ID] = (Cos(IA_TempReal))
      • Set IA_Sin[IA_Spell_ID] = (Sin(IA_TempReal))
      • -------- --------
      • Animation - Change IA_Orb[IA_Spell_ID]'s size to (IA_OrbSize%, 100.00%, 100.00%) of its original size
      • Special Effect - Create a special effect attached to the IA_SFXTail_AP of IA_Orb[IA_Spell_ID] using IA_SFXTail
      • Set IA_TailSFX[IA_Spell_ID] = (Last created special effect)
      • -------- --------
      • Custom script: call RemoveLocation(udg_IA_TempLoc)
      • Custom script: call RemoveLocation(udg_IA_EffectLoc)
      • Custom script: call RemoveLocation(udg_IA_CurrentLoc)
  • IA Cancel
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Level of IA_Ability for (Triggering unit)) Greater than 0
      • (Issued order) Equal to (Order(IA_Order_ID))
    • Actions
      • Set CP_Point = (Target point of issued order)
      • Trigger - Run Check Walkability <gen> (ignoring conditions)
      • -------- checking to make sure that the target point is walkable; if not, do not start a new spell instance --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CP_PointIsWalkable Equal to False
        • Then - Actions
          • Set IA_TempUnit = (Triggering unit)
          • -------- --------
          • Unit - Pause IA_TempUnit
          • Unit - Order IA_TempUnit to Stop
          • Unit - Unpause IA_TempUnit
          • Custom script: call SimError(GetTriggerPlayer(), udg_IA_ErrorMsg)
        • Else - Actions
          • -------- target point is walkable; do not interrupt --------
      • Custom script: call RemoveLocation(udg_CP_Point)
  • IA Loop
    • Events
    • Conditions
    • Actions
      • Custom script: local real x
      • Custom script: local real y
      • -------- --------
      • Set IA_Spell_ID = 0
      • For each (Integer IA_LoopInt) from 1 to IA_SpellCount, do (Actions)
        • Loop - Actions
          • Set IA_Spell_ID = IA_NodeNext[IA_Spell_ID]
          • -------- --------
          • -------- --------
          • -------- PHASE 0 = falling animation --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • IA_Phase[IA_Spell_ID] Equal to 0
            • Then - Actions
              • -------- xy adjustment --------
              • Custom script: set x = GetUnitX(udg_IA_Orb[udg_IA_Spell_ID]) + udg_IA_FallRate_XY * udg_IA_Cos[udg_IA_Spell_ID]
              • Custom script: set y = GetUnitY(udg_IA_Orb[udg_IA_Spell_ID]) + udg_IA_FallRate_XY * udg_IA_Sin[udg_IA_Spell_ID]
              • Set IA_DistanceTraveled[IA_Spell_ID] = (IA_DistanceTraveled[IA_Spell_ID] + IA_FallRate_XY)
              • -------- z adjustment --------
              • Set IA_CurrentHeight[IA_Spell_ID] = (IA_CurrentHeight[IA_Spell_ID] - IA_FallRate_Z)
              • -------- apply adjustment --------
              • Custom script: call SetUnitX(udg_IA_Orb[udg_IA_Spell_ID], x)
              • Custom script: call SetUnitY(udg_IA_Orb[udg_IA_Spell_ID], y)
              • Animation - Change IA_Orb[IA_Spell_ID] flying height to IA_CurrentHeight[IA_Spell_ID] at 0.00
              • -------- checking if the orb has reached its target location --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • IA_DistanceTraveled[IA_Spell_ID] Greater than or equal to IA_SpawnDistance
                • Then - Actions
                  • Set IA_OrbLoc[IA_Spell_ID] = (Position of IA_Orb[IA_Spell_ID])
                  • Special Effect - Create a special effect at IA_OrbLoc[IA_Spell_ID] using IA_SFXLanding
                  • Special Effect - Destroy (Last created special effect)
                  • Special Effect - Destroy IA_TailSFX[IA_Spell_ID]
                  • -------- --------
                  • -------- knocking back enemy units within landing radius --------
                  • Custom script: set bj_wantDestroyGroup = true
                  • Unit Group - Pick every unit in (Units within IA_RangeKB[IA_Spell_ID] of IA_OrbLoc[IA_Spell_ID]) and do (Actions)
                    • Loop - Actions
                      • Set IA_TempUnit = (Picked unit)
                      • Set IA_TempReal = (Current flying height of IA_TempUnit)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (IA_TempUnit is A structure) Equal to False
                          • (IA_TempUnit is Magic Immune) Equal to False
                          • (IA_TempUnit is alive) Equal to True
                          • IA_TempReal Less than or equal to IA_KB_MaxHeight
                          • (Unit-type of IA_TempUnit) Not equal to IA_OrbUnit
                        • Then - Actions
                          • Set Knockback2DUnit = IA_TempUnit
                          • Set IA_TempLoc = (Position of Knockback2DUnit)
                          • Set Knockback2DAngle = (Angle from IA_OrbLoc[IA_Spell_ID] to IA_TempLoc)
                          • Set Knockback2DDistance = IA_DistanceKB[IA_Spell_ID]
                          • Set Knockback2DTime = IA_TimeKB[IA_Spell_ID]
                          • Set Knockback2DLoopFX = IA_KB_SFX
                          • Trigger - Run Knockback 2D <gen> (checking conditions)
                          • -------- --------
                          • Custom script: call RemoveLocation(udg_IA_TempLoc)
                        • Else - Actions
                          • -------- TempUnit did not pass filters; do not knockback --------
                  • -------- --------
                  • -------- starting PHASE 1 --------
                  • Set IA_Phase[IA_Spell_ID] = 1
                • Else - Actions
                  • -------- orb has not reached target location; continue to move --------
            • Else - Actions
              • -------- --------
              • -------- --------
              • -------- PHASE 1 = levitating animation --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • IA_Phase[IA_Spell_ID] Equal to 1
                • Then - Actions
                  • -------- checking if we should continue to increment delay timer --------
                  • -------- or if it is time to levitate the orb --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • IA_Counter[IA_Spell_ID] Greater than or equal to IA_Delay
                    • Then - Actions
                      • -------- z adjustment --------
                      • Set IA_CurrentHeight[IA_Spell_ID] = (IA_CurrentHeight[IA_Spell_ID] + IA_LevitateRate)
                      • -------- apply adjustment --------
                      • Animation - Change IA_Orb[IA_Spell_ID] flying height to IA_CurrentHeight[IA_Spell_ID] at 0.00
                      • -------- if the orb has reached projected height, start next PHASE --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • IA_CurrentHeight[IA_Spell_ID] Greater than or equal to IA_OrbLevitateHeight
                        • Then - Actions
                          • Set IA_Counter[IA_Spell_ID] = 0.00
                          • -------- if required kills is > 0, start PHASE 2 --------
                          • -------- if required kills is <= 0, start PHASE 3 --------
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • IA_KillGoal[IA_Spell_ID] Greater than 0
                            • Then - Actions
                              • Set IA_Phase[IA_Spell_ID] = 2
                              • Special Effect - Create a special effect attached to the IA_SearchStartIndicator_AP of IA_Orb[IA_Spell_ID] using IA_SearchStartIndicator
                              • Special Effect - Destroy (Last created special effect)
                              • Unit - Make IA_Orb[IA_Spell_ID] Vulnerable
                              • -------- --------
                              • Set IA_Phase2_Count = (IA_Phase2_Count + 1)
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • IA_Phase2_Count Equal to 1
                                • Then - Actions
                                  • Trigger - Turn on IA Search <gen>
                                  • Trigger - Turn on IA Damage <gen>
                                • Else - Actions
                                  • -------- IA Search & Damage is already on; do nothing --------
                            • Else - Actions
                              • Set IA_Phase[IA_Spell_ID] = 3
                              • Special Effect - Create a special effect attached to the IA_MoveStartIndicator_AP of IA_Orb[IA_Spell_ID] using IA_MoveStartIndicator
                              • Special Effect - Destroy (Last created special effect)
                              • Unit - Add a IA_Duration[IA_Spell_ID] second Generic expiration timer to IA_Orb[IA_Spell_ID]
                              • Unit - Make IA_Orb[IA_Spell_ID] Invulnerable
                              • Unit - Unpause IA_Orb[IA_Spell_ID]
                              • Unit - Set level of PB_Ability for IA_Orb[IA_Spell_ID] to IA_AbilityLvl[IA_Spell_ID]
                        • Else - Actions
                          • -------- orb has not reached projected height; do not start PHASE 2 --------
                    • Else - Actions
                      • Set IA_Counter[IA_Spell_ID] = (IA_Counter[IA_Spell_ID] + IA_PeriodicTimer)
                • Else - Actions
                  • -------- --------
                  • -------- --------
                  • -------- PHASE 2 = searching for enemy units that die near the orb; PHASE 3 will start if KillsRequired is reached --------
                  • -------- orb has X seconds to start PHASE 3; the Counter will reset if PHASE 3 begins --------
                  • Set IA_Counter[IA_Spell_ID] = (IA_Counter[IA_Spell_ID] + IA_PeriodicTimer)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Or - Any (Conditions) are true
                        • Conditions
                          • (IA_Orb[IA_Spell_ID] is dead) Equal to True
                          • IA_Counter[IA_Spell_ID] Greater than or equal to IA_Duration[IA_Spell_ID]
                    • Then - Actions
                      • Special Effect - Create a special effect attached to the IA_SFXOrbDeath_AP of IA_Orb[IA_Spell_ID] using IA_SFXOrbDeath
                      • Special Effect - Destroy (Last created special effect)
                      • Custom script: call RemoveLocation(udg_IA_OrbLoc[udg_IA_Spell_ID])
                      • -------- checking if the orb died in PHASE 2 or 3 --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (IA_Orb[IA_Spell_ID] is dead) Equal to True
                        • Then - Actions
                          • -------- orb died during phase 2 --------
                          • Set IA_Phase2_Count = (IA_Phase2_Count - 1)
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • IA_Phase2_Count Equal to 0
                            • Then - Actions
                              • Trigger - Turn off IA Search <gen>
                              • Trigger - Turn off IA Damage <gen>
                            • Else - Actions
                              • -------- there are still Orbs in Phase 2 --------
                        • Else - Actions
                          • -------- orb made it to phase 3 --------
                      • -------- --------
                      • Set IA_RecycledStack[IA_RecycledSize] = IA_Spell_ID
                      • Set IA_RecycledSize = (IA_RecycledSize + 1)
                      • Set IA_NodeNext[IA_NodePrev[IA_Spell_ID]] = IA_NodeNext[IA_Spell_ID]
                      • Set IA_NodePrev[IA_NodeNext[IA_Spell_ID]] = IA_NodePrev[IA_Spell_ID]
                      • -------- --------
                      • Set IA_SpellCount = (IA_SpellCount - 1)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • IA_SpellCount Equal to 0
                        • Then - Actions
                          • Trigger - Turn off IA Loop <gen>
                        • Else - Actions
                          • -------- there is still a spell instance running; do not turn loop off --------
                    • Else - Actions
                      • -------- --------
                      • -------- --------
                      • -------- PHASE 3: Orb can now be moved by player --------
  • IA Search
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • Set IA_TempUnit = (Triggering unit)
      • Set IA_TempLoc = (Position of IA_TempUnit)
      • -------- --------
      • Set IA_FindNode = 0
      • For each (Integer IA_TempInt) from 1 to IA_SpellCount, do (Actions)
        • Loop - Actions
          • Set IA_FindNode = IA_NodeNext[IA_FindNode]
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (IA_TempUnit belongs to an enemy of IA_Owner[IA_FindNode]) Equal to True
              • IA_Phase[IA_FindNode] Equal to 2
            • Then - Actions
              • -------- if TempUnit is within range of an orb in Phase 2, create a fragment --------
              • Set IA_TempReal = (Distance between IA_TempLoc and IA_OrbLoc[IA_FindNode])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • IA_TempReal Less than or equal to IA_SearchRange[IA_FindNode]
                • Then - Actions
                  • Trigger - Run IA Frag Create <gen> (ignoring conditions)
                • Else - Actions
                  • -------- TempUnit is not within the search radius of the the orb; do not create fragment --------
            • Else - Actions
              • -------- TempUnit is not an enemy or the orb is not in search phase yet --------
      • Custom script: call RemoveLocation(udg_IA_TempLoc)
  • IA Damage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventTarget) Equal to IA_OrbUnit
    • Actions
      • -------- forcing any damage taken by the orb to 1 --------
      • Set DamageEventAmount = 1.00
  • IA Frag Create
    • Events
    • Conditions
    • Actions
      • Custom script: local real x = GetUnitX(udg_IA_TempUnit)
      • Custom script: local real y = GetUnitY(udg_IA_TempUnit)
      • -------- --------
      • Set IA_Frag_Count = (IA_Frag_Count + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IA_Frag_Count Equal to 1
        • Then - Actions
          • Trigger - Turn on IA Frag Loop <gen>
        • Else - Actions
          • -------- IA Frag Loop is already on; do nothing --------
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IA_Frag_RecycledSize Equal to 0
        • Then - Actions
          • Set IA_Frag_MaxIndex = (IA_Frag_MaxIndex + 1)
          • Set IA_Frag_ID = IA_Frag_MaxIndex
        • Else - Actions
          • Set IA_Frag_RecycledSize = (IA_Frag_RecycledSize - 1)
          • Set IA_Frag_ID = IA_Frag_RecycledStack[IA_Frag_RecycledSize]
      • Set IA_Frag_NodeNext[IA_Frag_ID] = 0
      • Set IA_Frag_NodeNext[IA_Frag_NodePrev[0]] = IA_Frag_ID
      • Set IA_Frag_NodePrev[IA_Frag_ID] = IA_Frag_NodePrev[0]
      • Set IA_Frag_NodePrev[0] = IA_Frag_ID
      • -------- --------
      • Set IA_Frag_Height = (Current flying height of IA_TempUnit)
      • Custom script: set udg_IA_Frag[udg_IA_Frag_ID] = GetRecycledDummyAnyAngle(x, y, udg_IA_Frag_Height)
      • Animation - Change IA_Frag[IA_Frag_ID]'s vertex coloring to (IA_SFXFrag_Red%, IA_SFXFrag_Green%, IA_SFXFrag_Blue%) with 0.00% transparency
      • Special Effect - Create a special effect attached to the IA_SFXFragment_AP of IA_Frag[IA_Frag_ID] using IA_SFXFragment
      • Set IA_FragSFX[IA_Frag_ID] = (Last created special effect)
      • -------- --------
      • Set IA_Frag_TotalDistance[IA_Frag_ID] = IA_TempReal
      • Set IA_TempReal = (Angle from IA_TempLoc to IA_OrbLoc[IA_FindNode])
      • Set IA_Frag_Cos[IA_Frag_ID] = (Cos(IA_TempReal))
      • Set IA_Frag_Sin[IA_Frag_ID] = (Sin(IA_TempReal))
      • Set IA_Frag_Node[IA_Frag_ID] = IA_FindNode
      • Set IA_Frag_DistanceTraveled[IA_Frag_ID] = 0.00
      • Set IA_Frag_MaxHeight[IA_Frag_ID] = (IA_Frag_TotalDistance[IA_Frag_ID] x IA_ArcPercentage)
      • -------- --------
      • Custom script: call MoveLocation(udg_IA_ZLoc, x, y)
      • Custom script: set udg_IA_Frag_StartHeight[udg_IA_Frag_ID] = GetLocationZ(udg_IA_ZLoc) + udg_IA_Frag_Height
      • Custom script: set udg_IA_Frag_EndHeight[udg_IA_Frag_ID] = GetLocationZ(udg_IA_OrbLoc[udg_IA_FindNode]) + udg_IA_OrbLevitateHeight + udg_IA_Frag_HeightOffset
  • IA Frag Loop
    • Events
    • Conditions
    • Actions
      • Custom script: local real adjustZ
      • Custom script: local real aimZ
      • Custom script: local real originZ
      • Custom script: local real totalD
      • Custom script: local real d
      • Custom script: local real x
      • Custom script: local real y
      • -------- --------
      • Set IA_Frag_ID = 0
      • For each (Integer IA_Frag_LoopInt) from 1 to IA_Frag_Count, do (Actions)
        • Loop - Actions
          • Set IA_Frag_ID = IA_Frag_NodeNext[IA_Frag_ID]
          • -------- --------
          • -------- checking if fragment reached its target orb or if its orb died --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (IA_Orb[IA_Frag_Node[IA_Frag_ID]] is dead) Equal to True
                  • IA_Phase[IA_Frag_Node[IA_Frag_ID]] Not equal to 2
                  • IA_Frag_DistanceTraveled[IA_Frag_ID] Greater than or equal to IA_Frag_TotalDistance[IA_Frag_ID]
            • Then - Actions
              • Special Effect - Destroy IA_FragSFX[IA_Frag_ID]
              • Custom script: call DummyAddRecycleTimer(udg_IA_Frag[udg_IA_Frag_ID], 0.5)
              • -------- if the orb did not die, add to kill counter --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (IA_Orb[IA_Frag_Node[IA_Frag_ID]] is alive) Equal to True
                • Then - Actions
                  • -------- caching the proper instance to properly credit CounterKills --------
                  • Set IA_Node = IA_Frag_Node[IA_Frag_ID]
                  • Set IA_CounterKills[IA_Node] = (IA_CounterKills[IA_Node] + 1)
                  • -------- if the orb has reached KillGoal, unpause and start phase 3 --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • IA_CounterKills[IA_Node] Equal to IA_KillGoal[IA_Node]
                    • Then - Actions
                      • Special Effect - Create a special effect attached to the IA_MoveStartIndicator_AP of IA_Orb[IA_Node] using IA_MoveStartIndicator
                      • Special Effect - Destroy (Last created special effect)
                      • Unit - Add a IA_Duration[IA_Node] second Generic expiration timer to IA_Orb[IA_Node]
                      • Unit - Make IA_Orb[IA_Node] Invulnerable
                      • Unit - Unpause IA_Orb[IA_Node]
                      • Unit - Set level of PB_Ability for IA_Orb[IA_Node] to IA_AbilityLvl[IA_Node]
                      • Set IA_Phase[IA_Node] = 3
                      • Set IA_Counter[IA_Node] = 0.00
                      • -------- --------
                      • Set IA_Phase2_Count = (IA_Phase2_Count - 1)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • IA_Phase2_Count Equal to 0
                        • Then - Actions
                          • Trigger - Turn off IA Search <gen>
                          • Trigger - Turn off IA Damage <gen>
                        • Else - Actions
                          • -------- there are still orbs in the searching phase --------
                    • Else - Actions
                      • -------- orb has not reached KillGoal; do not start phase 3 --------
                • Else - Actions
                  • -------- orb is dead; do not increment CounterKills --------
              • -------- --------
              • Set IA_Frag_RecycledStack[IA_Frag_RecycledSize] = IA_Frag_ID
              • Set IA_Frag_RecycledSize = (IA_Frag_RecycledSize + 1)
              • Set IA_Frag_NodeNext[IA_Frag_NodePrev[IA_Frag_ID]] = IA_Frag_NodeNext[IA_Frag_ID]
              • Set IA_Frag_NodePrev[IA_Frag_NodeNext[IA_Frag_ID]] = IA_Frag_NodePrev[IA_Frag_ID]
              • -------- --------
              • Set IA_Frag_Count = (IA_Frag_Count - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • IA_Frag_Count Equal to 0
                • Then - Actions
                  • Trigger - Turn off IA Frag Loop <gen>
                • Else - Actions
                  • -------- there are still frags trying to reach their orb; do not turn loop off --------
            • Else - Actions
              • -------- xy adjustment --------
              • Custom script: set x = GetUnitX(udg_IA_Frag[udg_IA_Frag_ID]) + udg_IA_Frag_Speed * udg_IA_Frag_Cos[udg_IA_Frag_ID]
              • Custom script: set y = GetUnitY(udg_IA_Frag[udg_IA_Frag_ID]) + udg_IA_Frag_Speed * udg_IA_Frag_Sin[udg_IA_Frag_ID]
              • Set IA_Frag_DistanceTraveled[IA_Frag_ID] = (IA_Frag_DistanceTraveled[IA_Frag_ID] + IA_Frag_Speed)
              • -------- z adjustment --------
              • Custom script: set totalD = udg_IA_Frag_TotalDistance[udg_IA_Frag_ID]
              • Custom script: set d = udg_IA_Frag_DistanceTraveled[udg_IA_Frag_ID]
              • Custom script: set originZ = udg_IA_Frag_StartHeight[udg_IA_Frag_ID]
              • Custom script: set aimZ = udg_IA_Frag_EndHeight[udg_IA_Frag_ID]
              • Custom script: call MoveLocation(udg_IA_ZLoc, x, y)
              • Custom script: set adjustZ = originZ - GetLocationZ(udg_IA_ZLoc)
              • Custom script: set udg_IA_Frag_Height = adjustZ + 4 * udg_IA_Frag_MaxHeight[udg_IA_Frag_ID] * d * (totalD-d) / (totalD*totalD) + d * (aimZ-originZ) / totalD
              • -------- apply adjustment --------
              • Custom script: call SetUnitX(udg_IA_Frag[udg_IA_Frag_ID], x)
              • Custom script: call SetUnitY(udg_IA_Frag[udg_IA_Frag_ID], y)
              • Animation - Change IA_Frag[IA_Frag_ID] flying height to IA_Frag_Height at 0.00



  • PB Config
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- --------
      • -------- CONFIG START --------
      • Set PB_Ability = Pleisto-Beam
      • -------- --------
      • -------- Lightning Configurables --------
      • Set PB_LightningType = Drain Mana
      • Set PB_Red = 1.00
      • Set PB_Green = 1.00
      • Set PB_Blue = 1.00
      • -------- ^ keep color values between 0.00 - 1.00 --------
      • Set PB_SFXEndPoint = war3mapImported\IceIncenerateBuff.mdl
      • Set PB_SFXEndPoint_AP = origin
      • Set PB_HeightOffset = 100.00
      • -------- --------
      • -------- Mechanics --------
      • Set PB_BeamDamage = 5.00
      • Set PB_BeamDamagePerLevel = 5.00
      • -------- ^ 5 + (5 * AbilityLevel) = 10 damage PER second at level 1 --------
      • Set PB_BeamDamage_MaxHeight = 100.00
      • -------- ^ because it would be weird if flying units were taking damage? xD --------
      • Set PB_BreakRange = 600.00
      • Set PB_BreakRangePerLevel = 100.00
      • -------- ^ 600 + (100 * AbilityLevel) = 700 units at level 1 --------
      • -------- NOTE: Make sure BreakRange is BIGGER than the cast range of the ability --------
      • Set PB_BeamAoE = 150.00
      • Set PB_BeamAoEPerLevel = 0.00
      • -------- ^ 150 + (0 * AbilityLevel) = 150 AoE all levels --------
      • -------- NOTE: Make sure AoE is the same value as the one defined in the object editor ability --------
      • -------- --------
      • -------- Other --------
      • Set PB_AttackType = Spells
      • Set PB_DamageType = Normal
      • -------- CONFIG END --------
      • -------- --------
      • Set PB_PeriodicTimer = (1.00 / 32.00)
      • Trigger - Add to PB Loop <gen> the event (Time - Every PB_PeriodicTimer seconds of game time)
      • Set PB_ZLoc = (Center of (Playable map area))
  • PB Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to PB_Ability
    • Actions
      • Custom script: local real casterX
      • Custom script: local real casterY
      • Custom script: local real casterZ
      • -------- --------
      • Set PB_SpellCount = (PB_SpellCount + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • PB_SpellCount Equal to 1
        • Then - Actions
          • Trigger - Turn on PB Loop <gen>
        • Else - Actions
          • -------- PB Loop is already on; do nothing --------
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • PB_RecycledSize Equal to 0
        • Then - Actions
          • Set PB_MaxIndex = (PB_MaxIndex + 1)
          • Set PB_Spell_ID = PB_MaxIndex
        • Else - Actions
          • Set PB_RecycledSize = (PB_RecycledSize - 1)
          • Set PB_Spell_ID = PB_RecycledStack[PB_RecycledSize]
      • Set PB_NodeNext[PB_Spell_ID] = 0
      • Set PB_NodeNext[PB_NodePrev[0]] = PB_Spell_ID
      • Set PB_NodePrev[PB_Spell_ID] = PB_NodePrev[0]
      • Set PB_NodePrev[0] = PB_Spell_ID
      • -------- --------
      • Set PB_Caster[PB_Spell_ID] = (Triggering unit)
      • Set PB_Owner[PB_Spell_ID] = (Triggering player)
      • Set PB_TempReal = (Real((Level of PB_Ability for PB_Caster[PB_Spell_ID])))
      • Set PB_Damage[PB_Spell_ID] = ((PB_BeamDamage + (PB_BeamDamagePerLevel x PB_TempReal)) x PB_PeriodicTimer)
      • Set PB_BeamRange[PB_Spell_ID] = (PB_BeamAoE + (PB_BeamAoEPerLevel x PB_TempReal))
      • Set PB_BreakRadius[PB_Spell_ID] = (PB_BreakRange + (PB_BreakRangePerLevel x PB_TempReal))
      • -------- --------
      • Custom script: set casterX = GetUnitX(udg_PB_Caster[udg_PB_Spell_ID])
      • Custom script: set casterY = GetUnitY(udg_PB_Caster[udg_PB_Spell_ID])
      • Custom script: call MoveLocation(udg_PB_ZLoc, casterX, casterY)
      • Custom script: set casterZ = GetUnitFlyHeight(udg_PB_Caster[udg_PB_Spell_ID]) + udg_PB_HeightOffset + GetLocationZ(udg_PB_ZLoc)
      • -------- --------
      • Set PB_TargetLoc[PB_Spell_ID] = (Target point of ability being cast)
      • Custom script: set udg_PB_TargetX[udg_PB_Spell_ID] = GetSpellTargetX()
      • Custom script: set udg_PB_TargetY[udg_PB_Spell_ID] = GetSpellTargetY()
      • Custom script: call MoveLocation(udg_PB_ZLoc, udg_PB_TargetX[udg_PB_Spell_ID], udg_PB_TargetY[udg_PB_Spell_ID])
      • Custom script: set udg_PB_TargetZ[udg_PB_Spell_ID] = GetLocationZ(udg_PB_ZLoc)
      • -------- --------
      • Custom script: set udg_PB_L[udg_PB_Spell_ID] = AddLightningEx(udg_PB_LightningType, true, udg_PB_TargetX[udg_PB_Spell_ID], udg_PB_TargetY[udg_PB_Spell_ID], udg_PB_TargetZ[udg_PB_Spell_ID], casterX, casterY, casterZ)
      • Lightning - Change color of PB_L[PB_Spell_ID] to (PB_Red PB_Green PB_Blue) with 1.00 alpha
      • -------- --------
      • Custom script: set udg_PB_DummySFX[udg_PB_Spell_ID] = GetRecycledDummyAnyAngle(udg_PB_TargetX[udg_PB_Spell_ID], udg_PB_TargetY[udg_PB_Spell_ID], 0)
      • Special Effect - Create a special effect attached to the PB_SFXEndPoint_AP of PB_DummySFX[PB_Spell_ID] using PB_SFXEndPoint
      • Set PB_GroundSFX[PB_Spell_ID] = (Last created special effect)
  • PB Loop
    • Events
    • Conditions
    • Actions
      • Custom script: local real casterX
      • Custom script: local real casterY
      • Custom script: local real casterZ
      • -------- --------
      • Set PB_Spell_ID = 0
      • For each (Integer PB_LoopInt) from 1 to PB_SpellCount, do (Actions)
        • Loop - Actions
          • Set PB_Spell_ID = PB_NodeNext[PB_Spell_ID]
          • -------- --------
          • -------- xy adjustment --------
          • Custom script: set casterX = GetUnitX(udg_PB_Caster[udg_PB_Spell_ID])
          • Custom script: set casterY = GetUnitY(udg_PB_Caster[udg_PB_Spell_ID])
          • Custom script: call MoveLocation(udg_PB_ZLoc, casterX, casterY)
          • -------- checking if the caster died or if it moved too far; if so, destroy lightning effect --------
          • Set PB_TempReal = (Distance between PB_ZLoc and PB_TargetLoc[PB_Spell_ID])
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (PB_Caster[PB_Spell_ID] is dead) Equal to True
                  • PB_TempReal Greater than or equal to PB_BreakRadius[PB_Spell_ID]
            • Then - Actions
              • Lightning - Destroy PB_L[PB_Spell_ID]
              • Special Effect - Destroy PB_GroundSFX[PB_Spell_ID]
              • Custom script: call RemoveLocation(udg_PB_TargetLoc[udg_PB_Spell_ID])
              • Custom script: call DummyAddRecycleTimer(udg_PB_DummySFX[udg_PB_Spell_ID], 1)
              • -------- --------
              • Set PB_RecycledStack[PB_RecycledSize] = PB_Spell_ID
              • Set PB_RecycledSize = (PB_RecycledSize + 1)
              • Set PB_NodeNext[PB_NodePrev[PB_Spell_ID]] = PB_NodeNext[PB_Spell_ID]
              • Set PB_NodePrev[PB_NodeNext[PB_Spell_ID]] = PB_NodePrev[PB_Spell_ID]
              • -------- --------
              • Set PB_SpellCount = (PB_SpellCount - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • PB_SpellCount Equal to 0
                • Then - Actions
                  • Trigger - Turn off PB Loop <gen>
                • Else - Actions
                  • -------- there are still lightning effects that need to remain active; do not turn loop off --------
            • Else - Actions
              • -------- z lightning adjustment --------
              • -------- storing casterZ so that MoveLightningEx() doesn't crash the map from the custom script being too long --------
              • Custom script: set casterZ = GetUnitFlyHeight(udg_PB_Caster[udg_PB_Spell_ID]) + udg_PB_HeightOffset + GetLocationZ(udg_PB_ZLoc)
              • -------- apply adjustment --------
              • Custom script: call MoveLightningEx(udg_PB_L[udg_PB_Spell_ID], true, udg_PB_TargetX[udg_PB_Spell_ID], udg_PB_TargetY[udg_PB_Spell_ID], udg_PB_TargetZ[udg_PB_Spell_ID], casterX, casterY, casterZ)
              • -------- --------
              • -------- dealing damage to units within the target point --------
              • Custom script: set bj_wantDestroyGroup = true
              • Unit Group - Pick every unit in (Units within PB_BeamRange[PB_Spell_ID] of PB_TargetLoc[PB_Spell_ID]) and do (Actions)
                • Loop - Actions
                  • Set PB_TempUnit = (Picked unit)
                  • Set PB_TempReal = (Current flying height of PB_TempUnit)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (PB_TempUnit is Magic Immune) Equal to False
                      • (PB_TempUnit is alive) Equal to True
                      • (PB_TempUnit belongs to an enemy of PB_Owner[PB_Spell_ID]) Equal to True
                      • PB_TempReal Less than or equal to PB_BeamDamage_MaxHeight
                    • Then - Actions
                      • Unit - Cause PB_Caster[PB_Spell_ID] to damage PB_TempUnit, dealing PB_Damage[PB_Spell_ID] damage of attack type PB_AttackType and damage type PB_DamageType
                    • Else - Actions
                      • -------- TempUnit did not pass filters; do not deal damage --------


Credits



Bribe
- GUI Damage Engine, Knockback, & Unit Indexer

Direfury
- FrostSplosion.mdx

Doomlord
- Custom Stat System

Flux
- DummyRecycler

General Frank
- OrbIceX.mdx

ILH
- DrainManaLightning.blp

PurgeandFire
- Check Walkability

s4nji
- IceIncenerateBuff.mdx

Vexorian
- dummy.mdx and SimError
 

Attachments

  • P0+1.gif
    P0+1.gif
    3.2 MB · Views: 610
  • P2.gif
    P2.gif
    2.5 MB · Views: 595
  • P2End.gif
    P2End.gif
    4 MB · Views: 550
  • P3Start.gif
    P3Start.gif
    2.3 MB · Views: 545
  • P3.gif
    P3.gif
    4.5 MB · Views: 552
  • P3End.gif
    P3End.gif
    3.5 MB · Views: 519
  • KILLCIDE + Ice Anomaly.w3x
    139.1 KB · Views: 92
Last edited:
Level 4
Joined
Jun 23, 2013
Messages
23
Unfortunately, I won't be able to finish my entry. Too bad, this type of contest is one of the few I can participate in the first place. Maybe next time. And good luck to the contestants! :)
 
Level 14
Joined
Jul 1, 2008
Messages
1,314
(Technically, since I don't mod/work on the Sabbath, I only have until the end of today,) but it's pretty simple so I'm fairly certain I still can.

The simplicity of it is why I will lose. ;P

Hey Kyrbi0,

don't worry too much. :) I will not win either most probably, because my time was shorter than I thought, but I finished it anyway just for fun.

"Mothers love" sounds interesting, I think you should give it a try and see how far you go. good luck and have fun :)
 

Kyrbi0

Arena Moderator
Level 45
Joined
Jul 29, 2008
Messages
9,492
FINAL - ZEPHYR 14 - KYRBI0 - Mother's Love

Lololol. Well, can't work on it anymore, so here it is.

I'm pretty much gunning for last place here, and I hope (Anitarf especially) you will forgive me; the trigger leaks, the tooltips are probably screwy, the map is unfinished, and there's an unconscionable bug with my methods I could not decipher. Regardless, it 'works' (for some definitions of "work"), and it's more important to me at this point to just put something in.

Boy am I rusty. I had forgotten just how hard it is, modding... And how big of a gap between "works on paper" and "works in practice". (It kills me to think, this ability was supposed to be merely 1 of 4 such abilities on a custom Hero, for a custom faction, for the latest Techtree Contest... Boy did I sink myself in deep there.)
 

Attachments

  • [Zephyr14] - v1.0 (Kyrbi0).w3x
    22.1 KB · Views: 96
Just so nobody is under any illusions - generally contests run on GMT time (current time is 20:12 GMT) the contest closes at 00:00 GMT which is a bit under 4 hours. Since we don't really have an applied moderator at the moment I suggest everybody work under that assumption and also assume it's strictly enforced (i.e. request an extension if you need a bit more time to complete your entry though there's no guarantee of it being granted) though obviously I'm no authority on the matter.
 
Status
Not open for further replies.
Top