• 🏆 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!

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...

Moderator

M

Moderator

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.
 
Level 9
Joined
Aug 2, 2008
Messages
219
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
 
Level 4
Joined
Jun 22, 2008
Messages
49
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^^
 
Level 6
Joined
Jun 15, 2008
Messages
175
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 :)
 
Level 4
Joined
Jun 22, 2008
Messages
49
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?^^
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
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
 
Level 4
Joined
Jun 22, 2008
Messages
49
Level 2
Joined
Mar 3, 2009
Messages
10
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
 
Level 4
Joined
Jun 22, 2008
Messages
49
: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
 
Level 19
Joined
Apr 25, 2006
Messages
1,309
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.
 
Level 4
Joined
Jun 22, 2008
Messages
49
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
 
Level 19
Joined
Apr 25, 2006
Messages
1,309
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. Just need to know a way that will let me cast the spell through a trigger.
 
Level 4
Joined
Jun 22, 2008
Messages
49
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)
 
Level 19
Joined
Apr 25, 2006
Messages
1,309
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.
 
Level 4
Joined
Jun 22, 2008
Messages
49
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:
Top