• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

Expanding Sphere 1.4b

This is my first spell I upload on HiveWorkshop (Not my first spell at all^^)
It won the "Spell Making Session #15" on Wc3c.net (Link)

D1000_ExpandingSphere_Tooltip.png


Requires:
  • JNGP
  • TimerUtils
  • xe

Credits to Vexorian for TimerUtils, JassHelper and xe

Please give proper credits to me and Vexorian if you use this spell in your map.

JASS:
scope ExpandingSphere

//============================================||
//----------------------------Spell made by D1000---------------------------||
//-----Please give Credits if you use it in your (Or anyone else) map----||
//-------------------------------Version 1.4b----------------------------------||
//-------------------------------------------------------------------------------||
//--Requires: JassHelper, TimerUtils and xe (basic,fx,preload,damage)-||
//------Credits to Vexorian for: JassHelper, TimerUtils and xe------------||
//============================================||

//============================================||
//------------------------------------Import------------------------------------||
//1) Copy the folders "Spell" and "Systems" to your map.----------------||
//2) Import the Dummy-model used in this map in your map -----------||
//3) Follow the import-instructions of xebasic -----------------------------||
//4) Create a dummy-spell and set "AbilityID" in this trigger to its ID ---||
//5) Give credits to Vexorian and me (D1000) -----------------------------||
//6) Have fun :-) --------------------------------------------------------------||
//============================================||

    globals
        //Things you can change
        
        /*Different*/
        private constant integer AbilityID = 'A000' //ID of the dummy Spell
        private constant real Interval = XE_ANIMATION_PERIOD //The loop-Interval
        private constant real Height = 60 //How high above the ground the spell takes place
        private constant integer MaxInstances = 8190 //Maximum number of instances of the Spelldata-Struct. Each usage of the spell needs 17 of them, so you can cast the spell with "MaxInstances = 8190" 8190/17 ~ 481 times at once.

        
        /*Lightnings*/
        private constant string LightningType = "DRAB" //Which lightning effect should be used.
        private constant real Length = 90 //The Length of each lightning
        private constant real LengthAdd = 0 //The Length increase each level
        private constant real SpinSpeed = 0.11 //Spin movement per "Interval" (in Radians)
        private constant real SpinSpeedAdd = 0 //Everytime the same...
                    //Color of the lightnings 
        private constant real LightningColorR = 1 //Red
        private constant real LightningColorG = 1 //Green
        private constant real LightningColorB = 1 //Blue
        private constant real LightningColorA = 1 //Alpha
        
        
        /*The ball*/
        private constant string BallModel = "Abilities\\Spells\\Other\\Parasite\\ParasiteMissile.mdl" //The model of the lightning ball
        private constant real StartScale = 0.2 //The scale the ball has to begin of the spell
        private constant real StartScaleAdd = 0 //The scale-increase each level
        private constant real GrowScale = 0.09 //How much the dummy-unit grows each "Interval"
        private constant real GrowScaleAdd = 0 //The groth increase each level
        private constant real MaxScale = 18 //When the dummy reaches this size, it will explode
        private constant real MaxScaleAdd = 0 //Guess what
                    //Color of the ball
        private constant integer BallColorR = 255 //Red
        private constant integer BallColorG = 255 //Green
        private constant integer BallColorB = 255 //Blue
        private constant integer BallColorA = 255 //Alpha
        
        
        /*The effect at the end*/
        private constant string EndEffect = "Objects\\Spawnmodels\\Undead\\UDeathMedium\\UDeath.mdl" //The model of the explosion at the end
        private constant real EndScale = 1.6 //The scale of the effect
        private constant real EndScaleAdd = 0
        private constant real EndZ = 100 //The flying-Height of the effect
        private constant real EndZAdd = 0 //....
        private constant real EndTimeAfter = 1 //Time after the EndEffect until the DummyUnit gets destroyed.
        private constant real EndTimeAfterAdd = 0
                    //Color of the EndEffect
        private constant integer EndColorR = 255 //Red
        private constant integer EndColorG = 255 //Green
        private constant integer EndColorB = 255 //Blue
        private constant integer EndColorA = 255 //Alpha
        
        
        /*Damage*/
        private constant real Range = 240 //The range of the damage
        private constant real RangeAdd = 0
        private constant real Damage = 200 //Damage to each target
        private constant real DamageAdd = 100 // self-explanatory 
        //Here you can alter the damage type and similar things (uses xedamage)
        //! textmacro ExpandingSphereDamageSettings
            set .dtype  = DAMAGE_TYPE_MAGIC
            set .atype  = ATTACK_TYPE_HERO
            //the wepon-type is per default "WEAPON_TYPE_WHOKNOWS"
            set .damageTrees = true
            set .damageNeutral = false
            //Damage enemies and not harming allies is default
            //You can find the xe-readmes in the "Systems"-Folder
            
            //You can also define other "onInit" actions in this textmacro, if you need them
        //! endtextmacro
        
        endglobals
        
        /*Advanced Settings*/
        //The following textmacros are called in different parts of the spell.
        //You can define locals in them, if you want.
        //You can access the struct members by using d.StructMember
            //! textmacro ExpandingSphereStart
                //This textmacro is called when the spell starts.
                debug call BJDebugMsg("|cffFFCC00"+GetUnitName(.caster)+"|r starts to cast 'Expanding Sphere'")
            //! endtextmacro
        
            //! textmacro ExpandingSpherePeriodic
                //This textmacro is called every "Interval" seconds, while the spell takes place
                debug call BJDebugMsg("Periodic event of 'Expanding Sphere' (casted by |cffFFCC00"+GetUnitName(.caster)+"|r)")
            //! endtextmacro
        
            //! textmacro ExpandingSphereEnd
                //This textmacro is called when the spell ends
                debug call BJDebugMsg("|cffFFCC00"+GetUnitName(.caster)+"|r finished casting 'Expanding Sphere'")
            //! endtextmacro
            
    private struct ES[MaxInstances]
        //If you want, you can declare additional struct-members here
//=========================================================\\
/*                                        Don´t touch anything below!                                              */
//=========================================================\\    
        real array x[17]
        real array y[17]
        real array z[17]
        unit caster
        lightning array l[16]
        integer level
        real scale
        real radians = 0
        real array dist[16]
        
        delegate xefx ball
        
        static delegate xedamage dmg
        static location loc = Location(0,0) //Used to get the Z value of the target point
        
        static method create takes unit caster, real x, real y returns ES
            local ES this = ES.allocate()
            set .caster = caster
            
            set .level = GetUnitAbilityLevel(caster,AbilityID)-1
            set .scale = StartScale+StartScaleAdd*.level
            
            set .x[16] = x
            set .y[16] = y
            set .ball = xefx.create(x,y,0)
                //Sets the color of the ball
            set .fxpath = BallModel
            set .red = EndColorR
            set .green = EndColorG
            set .blue = EndColorB
            set .alpha = EndColorA
                
        
            set .dist[0] = -(Length + LengthAdd*.level)/2
            set .x[0] = x + .dist[0]
            set .y[0] = y
            return this
        endmethod
        
        static method EndSpell takes nothing returns nothing
            local ES this = GetTimerData(GetExpiredTimer())
            //! runtextmacro ExpandingSphereEnd()
        
            call ReleaseTimer(GetExpiredTimer())
        
            //Destroys the ball
            call .ball.destroy()
        
            //Destroys the spell-struct
            call .destroy()
        endmethod
    
        static method Loop takes nothing returns nothing
            //Local declaration
            local timer t = GetExpiredTimer()
            local ES this = GetTimerData(t)
            local integer i = 1
            local xefx EndSFX
            //! runtextmacro ExpandingSpherePeriodic()
        
            //Lets the dummy grow^^
            set .ball.scale = .scale
            set .scale = .scale + GrowScale+GrowScaleAdd*.level
        
            if .scale >= MaxScale + MaxScaleAdd*.level then // When the max scale is reached, destroy the shapes and so on...
                call PauseTimer(t) //Only pauses the timer becauses it is still needed
            
                //The explosion
                set EndSFX = xefx.create(.x[16],.y[16],0)
                set EndSFX.fxpath = EndEffect
                set EndSFX.z = EndZ+EndZAdd*.level
                set EndSFX.scale = EndScale+EndScaleAdd*.level
                //Sets the color of the effect
                set EndSFX.red = EndColorR
                    set EndSFX.green = EndColorG
                set EndSFX.blue = EndColorB
                set EndSFX.alpha = EndColorA
            
                set i = 0
                loop //Destroys the shapes
                    call DestroyLightning(.l[i])
                    set i = i + 1
                    exitwhen i == 16
                endloop
            
                if Damage+DamageAdd*.level > 0 then //Only triggers if the damage is > 0
                    call .damageAOE(.caster,.x[16],.y[16],Range+RangeAdd*.level,Damage+DamageAdd*.level)
                endif

                call TimerStart(t,EndTimeAfter+EndTimeAfterAdd*.level,false,function ES.EndSpell)
                return //Skips the rest of the trigger
            endif
        
        
            set .x[0] = .x[16]+ .dist[0]*Sin(.radians)
            set .y[0] = .y[16]+ .dist[0]*Cos(.radians)
        
            loop // Moves the lightnings
                if i <= 7 then
                    set .x[i] = .x[16]+ .dist[i]*Sin(.radians)
                    set .y[i] = .y[16]+ .dist[i]*Cos(.radians)
                    call MoveLightningEx(.l[i-1],true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
                elseif i == 8 then
                    set .y[i] = .y[16]+ .dist[i]*Sin(.radians)
                    set .z[i] = .z[16]+ .dist[i]*Cos(.radians)
                    call MoveLightningEx(.l[i-1],true,.x[0],.y[0],.z[0],.x[i-1],.y[i-1],.z[i-1])
                else
                    set .y[i] = .y[16]+ .dist[i]*Sin(.radians)
                    set .z[i] = .z[16]+ .dist[i]*Cos(.radians)
                    call MoveLightningEx(.l[i-1],true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
                endif
            
                set i = i + 1      
                exitwhen i >= 16
            endloop
            call MoveLightningEx(.l[15],true,.x[8],.y[8],.z[8],.x[15],.y[15],.z[15])
        
            set .radians = .radians + SpinSpeed+SpinSpeedAdd*.level
        endmethod
    
        static method StartSpell takes nothing returns nothing
            // Local declaration
            local ES this = ES.create(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
            local timer t = NewTimer()
            local integer i = 1
            //! runtextmacro ExpandingSphereStart()
        
            call MoveLocation(.loc,.x[16],.y[16])
            set .z[16] = GetLocationZ(.loc)
        
            call SetTimerData(t,this) //Attaches the struct to the timer
        
            set .z[0] = .z[16] + Height
        
            set .ball.z = (Length + LengthAdd*.level)/2 + SquareRoot(((Length + LengthAdd*.level)*(Length + LengthAdd*.level))/2) + Height // Sets the Height of the ball
        
            set .z[16] = .z[16]+.ball.z
            //Creates the lightnings (there are 16 of them)
            loop
                if i <= 7 then
                    set .x[i] = .x[i-1] + (Length+LengthAdd*.level)*Cos(bj_PI/4*(i-1))
                    set .y[i] = .y[16]
                    set .z[i] = .z[i-1] + (Length+LengthAdd*.level)*Sin(bj_PI/4*(i-1))
                    set .l[i-1] = AddLightningEx(LightningType,true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
                    set .dist[i] = .x[i]-.x[16]
                elseif i == 8 then
                    set .x[i] = .x[16] - (Length + LengthAdd*.level)/2
                    set .y[i] = .y[16] - (Length + LengthAdd*.level)/2 - SquareRoot(((Length + LengthAdd*.level)*(Length + LengthAdd*.level))/2)
                    set .z[i] = .z[16]
                    set .l[i-1] = AddLightningEx(LightningType,true,.x[0],.y[0],.z[0],.x[i-1],.y[i-1],.z[i-1])
                    set .dist[i] = .y[i]-.y[16]
                else
                    set .x[i] = .x[i-1] + (Length+LengthAdd*.level)*Cos(bj_PI/4*(i-1))
                    set .y[i] = .y[i-1] + (Length+LengthAdd*.level)*Sin(bj_PI/4*(i-1))
                    set .z[i] = .z[8]
                    set .l[i-1] = AddLightningEx(LightningType,true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
                    set .dist[i] = .y[i]-.y[16]
                endif
            
                call SetLightningColor(.l[i-1],LightningColorR,LightningColorG,LightningColorB,LightningColorA)
            
                set i = i + 1
                exitwhen i >= 16
            endloop
        
            set .l[15] = AddLightningEx(LightningType,true,.x[15],.y[15],.z[15],.x[8],.y[8],.z[8])
            call SetLightningColor(.l[15],LightningColorR,LightningColorG,LightningColorB,LightningColorA)
                
            call TimerStart(t,Interval,true,function ES.Loop) //Starts the loop
        endmethod
    
        static method onInit takes nothing returns nothing
            local trigger tr = CreateTrigger()
        
            call XE_PreloadAbility(AbilityID)
        
            call TriggerRegisterAnyUnitEventBJ(tr,EVENT_PLAYER_UNIT_SPELL_EFFECT )
            call TriggerAddCondition(tr,Condition(function ES.IsSpell))
            call TriggerAddAction(tr,function ES.StartSpell)
        
            set tr = null
            set .dmg = xedamage.create()
            //! runtextmacro ExpandingSphereDamageSettings()
        endmethod
    
        static method IsSpell takes nothing returns boolean
            return GetSpellAbilityId() == AbilityID
        endmethod
    endstruct
endscope


• v. 1.4b:
-Fixed a very small bug

• v. 1.4:
-Fixed what Purple said (Except the clipping-thing, I don´t really know how)
-Moved the hole spell into the struct
-Now using delegates
-Made the spell a bit smaller and faster

• v. 1.3:
-Added posibility to define your own actions on Spellstart/-end/Periodic and to declare your own struct-members
-Now using a create-method

• v. 1.2:
-Fixed a bug whith the height of the ball, when you used the spell on cliffs

• v. 1.1:
-Improved the triggering and changed the look a bit (like it was originally planned)
-Uploaded it on HiveWorkshop and Wc3c

• v. 1.0:
-Made the Spell and submitted it to the "Spell Making Session #15" on wc3c.net


Keywords:
Expanding, Sphere, D1000, Explosion, 3D, Lightning, Circle, Growing, green, grow, expand, ring, rotate
Contents

Expanding Sphere 1.4 (Map)

Reviews
12:33, 3rd Sep 2009 PurplePoot: The visuals looked pretty good, other than the obvious flaw that the sphere clipped when too large--I suggest you tweak the model so that the lighting isn't so much larger than the actual core to fix this problem...
12:33, 3rd Sep 2009
PurplePoot: The visuals looked pretty good, other than the obvious flaw that the sphere clipped when too large--I suggest you tweak the model so that the lighting isn't so much larger than the actual core to fix this problem.

As for the code:

  • GetTriggerUnit() tends to be a little nicer and more standard than the million clones (such as GetSpellAbilityUnit()), although this isn't that big of a deal.

  • It's "length", not "lenght" (just for cleanliness of the user-modified constants).

  • You don't need to null timers from TimerUtils.

  • Can't say I have much other to complain about--the code was mostly math.

Approved (4/5), although I'd appreciate it if you fixed the clipping issue mentioned above.
 
Wow i have to say it has an impressive eyecandy!
Code looks fine, has a lot of configureable constants. It also has documentation and in-code comments. One thing i´d like to see is that it may does more than just dealing damage, for example makes all enemies inside the target area banished or something but a really nice job anyway !

~TNT
 
Wow i have to say it has an impressive eyecandy!
Code looks fine, has a lot of configureable constants. It also has documentation and in-code comments. One thing i´d like to see is that it may does more than just dealing damage, for example makes all enemies inside the target area banished or something but a really nice job anyway !

~TNT
I´ll think about it, thanks

You now, that I like this spell^^
And the new code is much better than the old one XD
+Rep und vote for approve!

Thanks^^
 
You want more comments eh? Too bad there's alot of passive downloaders on the hive, on the other part it makes your submitted content more known.
I like the spells very much. To have done all of this in just the object editor is amazing :)
 
I like the spells very much.
SpellS?
To have done all of this in just the object editor is amazing :)
I used the Trigger-Editor
1) It is not allowed to submit spells which don´t use the trigger editor
2) It would be impossible to do this in the object-editor

Could it be, that you mixed up this spell with this one?^^
 
Hahaha :P well first of all, if a spell is well done, nah comments aren't usually necessary you know...

Plus, it's Jass and there only few Jass reviewers around... I mean not all that know Jass tend to review other spells you knw...

I'm being bit lazy lately so I'm not getting anytime to check this :s

Hopefully soon :P

EDIT:
You geometry freak! :P
 
hehehe nc spell

well it looks really cool and the code was well done.....except i haven't have the time to test it yet lol :P...but im pretty sure its fine....since most of the comments came out great...^^:thumbs_up::thumbs_up::thumbs_up::thumbs_up::thumbs_up: 5/5
 
:eek: O M G
This spell is

SUPER!!!
5/5 +rep
Thanks^^
I dont know nothing about JASS and what it is...
but stuff like this I will not do even after 30 years
It´s not that difficult^^
Meaby spell need be a bit faster but it is very small thing
You can modify nearly everything in the spell in the globals. Also the Spin-Speed and the growth of the Ball
 
v 1.1 is bugged: Try casting the spell on different hights and the ball won't be inside the sphere. =/ I would also like to see the option to allow allied units get damaged as well. Also what order do I need to give a computer AI unit so that it will cast the ability? Other than this the effect looks really nice.
 
v 1.1 is bugged: Try casting the spell on different hights and the ball won't be inside the sphere. =/
I´ll try to fix this
I would also like to see the option to allow allied units get damaged as well.
Here:
JASS:
        //Here you can alter the damage type and similar things (uses xedamage)
        //! textmacro DamageSettings
            set dmg.dtype = DAMAGE_TYPE_MAGIC
            set dmg.atype = ATTACK_TYPE_HERO
            //the wepon-type is per default "WEAPON_TYPE_WHOKNOWS"
            set dmg.damageTrees = true
            set dmg.damageNeutral = false
            //Damage enemies and not harming allies is default
            //You can find the xe-readmes in the "Systems"-Folder
        //! endtextmacro


Also what order do I need to give a computer AI unit so that it will cast the ability? Other than this the effect looks really nice.
I´ve no idea
 
You mean change set dmg.damageNeutral = false? I think I set it to true but still I think I couldn't kill my own unit.
There is a simmilar option for allied units, just read the xe-damage Readme
Just need to know a way that will let me cast the spell through a trigger.
Just let a unit cast your dummy-spell, like you would let it cast any other spells. (Yes, I know that my english is horrible)
 
Just let a unit cast your dummy-spell, like you would let it cast any other spells. (Yes, I know that my english is horrible)
I don't know how to make it cast this spell that is in the map. I tried replacing the spell ability id with another spell but when I casted it the sphere never came.
EDIT: Oh I tried another spell and it worked. Must have been something wrong with the spell I first tried.
 
It´s not a bug, it´s a feature
The damage is dealt by the caster and if there is no caster, how should it deal damage^^

/€: It is also a rule for spell-submission on hive, that the right units gets credits for damage/kills.

/€²: New ver.: 1.3
 
Last edited:
Back
Top