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

Rocket Spheres V1.00

A JASS spell based around creating small (or large) automatically-adjusting Spheres made out of rockets (test show on a decent computer up to 900 projectiles can be placed in 3 spheres or 300 without lagging a computer, but I don't recommend doing that for general use)

Absolutely blasts everything to pieces with it's default settings, I wouldn't suggest casting too many level 3s at once but please do try to remember that these are demos and you can create lots of much smaller spheres without worrying too much about lag. Now before I draw out the intro too long, here's Rocket Spheres:


- Spheres made out of rockets, what more could you ask for?
- Spheres automatically adjust based on mass
- Accounts for terrain height
- Very fun
- Heavily documented
- Configuration galore
- Helpful importing files
- Uses a linked list
- Would probably look great on bosses
- Requires Dummy.mdl



Summons large masses of rockets around the caster that decimates the surrounding area dealing significant damage to all enemies caught within the blast.

Level 1 - Small Sphere of rockets, each rocket deals 40 damage
Level 2 - Medium Sphere of rockets, each rocket deals 50 damage
Level 3 - Large Sphere of rockets, each rocket deals 60 damage



JASS:
////////////////////////////////////////////////////////////////////
//                    ROCKET SPHERES V1.00                        //
//                                                                //
//  Author: Tank-Commander                                        //
//  Requires: Dummy.mdl                                           //
//  Purpose: Decimation ability                                   //
//                                                                //
//  Notes:                                                        //
//    -  Read the readme before you try modifying the config      //
//    -  Use the "Helpful files" to help you import the spell     //
//                                                                //
//  Credits:                                                      //
//    -  (Dummy.mdl) Vexorian                                     //
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
//  README:                                                       //
//    Before modifying this spell a few things need to be         //
//    understood and read, this is one of those things, while     //
//    most modification can be considered intuitive, it still     //
//    helps to read through these intstructions, as they will     //
//    inform you about how to configure this spell to your        //
//    desire.                                                     //
//----------------------------------------------------------------//
//  Timer Speed: The default for this is 0.03, it determines how  //
//  many times per second these triggers are ran, normally you    //
//  want to leave this at 0.03, but 0.04 and prehaps 0.05         //
//  would be good options if you computer lags a bit.             //
constant function RS_TimerSpeed takes nothing returns real  
    return 0.03                                                  
endfunction                                                      
//----------------------------------------------------------------//
//  Dummy Unit: This is the raw data of the dummy unit, to see    //
//  raw data in the object editor, press Ctrl + D, doing this     //
//  again will switch it back, if you want to change this dummy   //
//  unit, follow as displayed (use the first 4 characters in      //
//  the raw data and put them in ' markers)                       //
constant function RS_DummyUnit takes nothing returns integer
    return 'u000'
endfunction
//----------------------------------------------------------------//
//  Ability: This is done in the same manner as the Dummy unit    //
//  except that this time, you're doing it with ability raw       //
//  data, see the dummy unit if you do not know already how to    //
//  view raw data                                                 //
constant function RS_Ability takes nothing returns integer
    return 'A000'
endfunction
//----------------------------------------------------------------//
//  Gravity: This determines how quickly projectiles will be      //
//  pulled back down to earth, the standard is 4.905 (this is     //
//  half of earth gravity of 9.81) increase this to make          //
//  projectiles more tightly packed, or decrease it so they       //
//  spread further (having a high blast power AND gravity will    //
//  make projectile movement and landing faster)                  //
constant function RS_Gravity takes nothing returns real
    return 4.905
endfunction
//----------------------------------------------------------------//
//  Weapon Type: This alters what kind of weapon type is used by  //
//  the spell, those without knowledge of weapontypes don't       //
//  worry, you're not missing much, this spell doesn't really     //
//  use it, hence the default of null, but if you want to use     //
//  them, no reason to not.                                       //
constant function RS_WeaponType takes nothing returns weapontype
    return null
endfunction
//----------------------------------------------------------------//
//  Damage Type: These determine the damagetypes, changing this   //
//  will modify the damage multiplyers vs certain enemies         //
//  the standard is DAMAGE_TYPE_MAGIC, note that this spell       //
//  automatically discludes magic immunes, so changing this       //
//  damage type will not make them start taking damage            //
constant function RS_DamageType takes nothing returns damagetype
    return DAMAGE_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  Attack Type: This is very much so basically the same as       //
//  Damage Type, generally you'll want this to match with it      //
//  as such the default is ATTACK_TYPE_MAGIC, though Damagetype   //
//  is a key factor for determining bonuses rather than this      //
//  but unlike weapontype, you cannot have null as a setting      //
constant function RS_AttackType takes nothing returns attacktype
    return ATTACK_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  Rocket Model: Determines the model used to reprisent a rocket //
//  to change the model you simply go into the object editor      //
//  select a model, and then Copy and Paste the string path       //
//  of that model. Note: This will only work if you use           //
//  Dummy.mdl, hence why it is a required resource for this       //
constant function RS_RocketModel takes nothing returns string
    return "Abilities\\Weapons\\RocketMissile\\RocketMissile.mdl"
endfunction
//----------------------------------------------------------------//
//  Rocket Death Model: Same as the Rocket model in terms of      //
//  customising, this effect will be played when a rocket hits    //
//  the ground                                                    //
constant function RS_RocketDeathModel takes nothing returns string
    return "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
endfunction
//----------------------------------------------------------------//
//  Rocket Spawn Model: Same as the previous two, this effect     //
//  is played at the start of the spell on the ground underneath  //
//  the rocket spheres - as such: go for a tall one like the      //
//  level up effect                                               //
constant function RS_RocketSpawnModel takes nothing returns string
    return "Abilities\\Spells\\Other\\Levelup\\LevelupCaster.mdl"
endfunction
//----------------------------------------------------------------//
//  Rocket Scale: Determines the scale of the rocket models       //
//  note that it's a decimal percentage: 1.00 == 100% of the      //
//  standard model size, what you want to set this to depends     //
//  mostly on the rocket model that you are using default is      //
//  1.00                                                          //
constant function RS_RocketScale takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  Rocket Health Damage Base: Determines the base value of the   //
//  damage dealt by a single rocket, default is 30, note that     //
//  this damage is before applying weaknesses and resistances     //
//  of enemy units (and of course their armour) use this in       //
//  conjunction with the Health Damage per level to get the       //
//  desired damage                                                //
constant function RS_RocketHealthDamageBase takes nothing returns real
    return 30.00
endfunction
//----------------------------------------------------------------//
//  Rocket Health Damage Per Level: Determines the amount of      //
//  damage added on top of the base damage for every level of     //
//  spell to each rocket, default is 10                           //
constant function RS_RocketHealthDamagePerLevel takes nothing returns real
    return 10.00
endfunction
//----------------------------------------------------------------//
//  Rocket Mana Damage Base: This is the same as the health       //
//  damage base however, it is a true fixed value and ignores     //
//  armour, default is 0                                          //
constant function RS_RocketManaDamageBase takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  Rocket Mana Damager Per Level: Equally the same as Rocket     //
//  Health Damage Per Level but also true damage dealt to the     //
//  target's mana, default is 0                                   //
constant function RS_RocketManaDamagePerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  The area of effect of each rocket, this should be relative    //
//  to the size of your rockets, lest they look disproportional   //
//  to the area they are dealing damage in, 40 is directly        //
//  on top of a target, 90 is melee range of the area, roughly    //
//  default is 100                                                //
constant function RS_RocketAOE takes nothing returns real
    return 100.00
endfunction
//----------------------------------------------------------------//
//  Rocket Standard Mass: This determines how many degrees of     //
//  the sphere each rocket takes up default is 35, note that      //
//  this is also automatically relative to the sphere standard    //
//  mass, this is how many degrees a rocket takes up on a sphere  //
//  of the standard mass size, if the mass of the sphere is       //
//  more than this, then the rockets will take up less degrees    //
//  each on that larger sphere, to attempt to cover the same      //
//  area.                                                         //
constant function RS_RocketStandardMass takes nothing returns real
    return 35.00
endfunction
//----------------------------------------------------------------//
//  Sphere Standard Mass: Determines the default mass of a        //
//  which is used in tandem with the rocket standard mass to      //
//  give more control on the number of rockets used, based on     //
//  the size of the sphere. Note: you should never have the       //
//  rocket mass at 10 or so or below, as Warcraft can not create  //
//  enough entities at one time, to finish the sphere and it      //
//  will remain imcomplete                                        //
constant function RS_SphereStandardMass takes nothing returns real
    return 50.00
endfunction
//----------------------------------------------------------------//
//  Sphere Mass Base: Determines the mass of the sphere as a      //
//  base level, 40 is default, this equates to the radius of      //
//  sphere you will get with the rockets                          //
constant function RS_SphereMassBase takes nothing returns real
    return 40.00
endfunction
//----------------------------------------------------------------//
//  Sphere Mass Per Level: Added on to the Mass Base for every    //
//  level of the spell you have, 10 is default, this means at     //
//  level one you will have the base mass + this mass x 1         //
//  and so on                                                     //
constant function RS_SphereMassPerLevel takes nothing returns real
    return 10.00
endfunction
//----------------------------------------------------------------//
//  Sphere Top: you can use this to control what a "finished"     //
//  sphere looks like: 90 is default and creates the entire top   //
//  of a sphere, setting either to 0 will remove that half of the //
//  sphere, and the various settings between 0 and 90 will yeild  //
//  different results (do not set both to 0) 1 and - 1 will       //
//  create most of a sphere, but without the top centre and       //
//  bottom centre rockets                                         //
constant function RS_SphereTop takes nothing returns real
    return 90.00
endfunction
//----------------------------------------------------------------//
//  Sphere Bottom: It's the same as the Sphere Top, but           //
//  reflected onto the bottom half of the sphere                  //
constant function RS_SphereBottom takes nothing returns real
    return -90.00
endfunction
//----------------------------------------------------------------//
//  Sphere Count Base: Determines the number of spheres created   //
//  on activation of the spell, this is the base value which      //
//  will be applied regardless of level                           //
constant function RS_SphereCountBase takes nothing returns integer
    return 3
endfunction
//----------------------------------------------------------------//
//  Sphere Count Per Level: Determines how many spheres are       //
//  added on to the base value for every level of the spell you   //
//  have, default is 0                                            //
constant function RS_SphereCountPerLevel takes nothing returns integer
    return 0
endfunction
//----------------------------------------------------------------//
//  Sphere Spread Space Base: Base value for how far away from    //
//  the caster the spheres are created, higher is further away    //
//  lower is closer, default value is 200                         //
constant function RS_SphereSpreadSpaceBase takes nothing returns  real
    return 200.00
endfunction
//----------------------------------------------------------------//
//  Sphere Spread Space Per Level: Determines how far extra       //
//  further away (or closer) the spheres are to the caster        //
//  negative values will bring them closer each level, positive   //
//  away, but if the total value flips to negative, then they     //
//  will pass through the caster and start moving away again      //
constant function RS_SphereSpreadSpacePerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  Sphere Height Base: The Height of the spheres off the ground  //
//  as a base, higher value equates to more height, and vice      //
//  versa, 300 is the default value for this setting              //
constant function RS_SphereHeightBase takes nothing returns real
    return 300.00
endfunction
//----------------------------------------------------------------//
//  Sphere Height Per Level: is the same as the Sphere Height     //
//  and works in the same way as all other Per Level attributes   //
//  applied after base value for every level of the ability you   //
//  have.                                                         //
constant function RS_SphereHeightPerLevel takes nothing returns real
    return 0.00
endfunction
//----------------------------------------------------------------//
//  Blast Power Base: Determines the power of the rockets,        //
//  negative value is away from the centre, positive value is     //
//  toward it, default value is -20,000. you need large numbers   //
//  on this stat to make a difference, + or - 10,000 is a safe    //
//  minimum, else the projectiles will just fall to the gorund    //
constant function RS_BlastPowerBase takes nothing returns real
    return -20000.00
endfunction
//----------------------------------------------------------------//
//  Blast Power Per Level: Bonus applied for every level of the   //
//  ability your hero has, works in the same way as normal Blast  //
//  power and other per level factors, default value is -20,000   //
constant function RS_BlastPowerPerLevel takes nothing returns real
    return -20000.00
endfunction
//----------------------------------------------------------------//
//  Rocket Launch Delay Min: Determines after how many seconds    //
//  of creation, is the minimum before rockets start firing off   //
//  setting this to the same as the max will mean all rockets     //
//  launch off at the same time (though that will almost          //
//  certainly cause lag)                                          //
constant function RS_RocketLaunchDelayMin takes nothing returns real
    return 1.00
endfunction
//----------------------------------------------------------------//
//  Rocket Launch Delay Max: the counterpart to the minimum       //
//  Determines the maximum amount of time passed before all       //
//  rockets should have been launched, the closer these values    //
//  the more likely you'll have outliers which wait much longer   //
//  than the others (as most projectiles will launch at the       //
//  midway mark) Note: some projectiles may wait a bit extra      //
//  than this duration due to processing limitations, but all     //
//  projectiles will eventually finish their trajectory           //
constant function RS_RocketLaunchDelayMax takes nothing returns real
    return 8.00
endfunction
//----------------------------------------------------------------//
//  You have no reached the end of the readme, beyond this lies   //
//  the programming behind the spell itself, unless you're an     //
//  experienced programmer, it's not recommended to view and/or   //
//  try to understand the below text unless you really want to    //
////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
//  Reuses a location to get Z height of all locations associated with  //
//  the rockets                                                         //
//////////////////////////////////////////////////////////////////////////
function RS_GetZ takes real x, real y returns real

    //Gets the location Z of the selected location
    call MoveLocation(udg_RS_ZLoc, x, y)
    return GetLocationZ(udg_RS_ZLoc)
   
endfunction

//////////////////////////////////////////////////////////////////////////
//  Target filter, used to determine which targets can be used for      //
//  damage when a rocket crashes
//////////////////////////////////////////////////////////////////////////
function RS_TargetFilter takes unit u, player pl returns nothing

    //Checks if the unit can be used as a target
    if (IsUnitType(u, UNIT_TYPE_GROUND)) and (not IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) and (IsUnitEnemy(u, pl)) and (GetUnitTypeId(u) != RS_DummyUnit()) and (not IsUnitType(u, UNIT_TYPE_DEAD)) then
        call GroupAddUnit(udg_RS_TempGroup2, u)
    endif
endfunction

//////////////////////////////////////////////////////////////////////////
//  Controls the movement and activation of rockets, also deals damage  //
//  to targets when the rockets land                                    //
//////////////////////////////////////////////////////////////////////////
function RS_RocketSphereLoop takes nothing returns nothing

    //Sets up all the locals needed for this section
    local integer TempInt = 0
    local integer Node = 0
    local real x
    local real y
    local real z
    local unit u
    local player pl
   
    //Controls rocket movement
    loop
        set TempInt = TempInt + 1
        exitwhen TempInt > udg_RS_SpellCounter
        set Node = udg_RS_NextNode[Node]

        //Checks if the Rocket is ready to be fired
        if (udg_RS_ActivationTime[Node]  > 0) then
            set udg_RS_ActivationTime[Node] = udg_RS_ActivationTime[Node] - RS_TimerSpeed()
        else
            //Sets up moving the projectile
            set x = GetUnitX(udg_RS_Unit[Node]) + udg_RS_XVelocity[Node]
            set y = GetUnitY(udg_RS_Unit[Node]) + udg_RS_YVelocity[Node]
            set z = RS_GetZ(x, y)
            //Adjusts the Z height of the projectile and it's arc appearence
            set udg_RS_ZVelocity[Node] = udg_RS_ZVelocity[Node] - RS_Gravity()
            set udg_RS_CurrentZ[Node] = udg_RS_CurrentZ[Node] + udg_RS_ZVelocity[Node]
            call SetUnitFlyHeight(udg_RS_Unit[Node], udg_RS_CurrentZ[Node] - z, 0.00)
            call SetUnitAnimationByIndex(udg_RS_Unit[Node], (R2I(Atan2(udg_RS_ZVelocity[Node], SquareRoot((udg_RS_YVelocity[Node] * udg_RS_YVelocity[Node]) + (udg_RS_XVelocity[Node] * udg_RS_XVelocity[Node]))) * bj_RADTODEG + 0.5)) + 90)
           
            if (udg_RS_CurrentZ[Node] - z < 5.00) then
                //Destroys the effect
                call DestroyEffect(udg_RS_CurrentEffect[Node])
                call DestroyEffect(AddSpecialEffect(RS_RocketDeathModel(), x, y))
                //Sets up the correct player for this Node
                set pl = GetOwningPlayer(udg_RS_OriginalCaster[Node])
                //Select Units to damage
                call GroupEnumUnitsInRange(udg_RS_TempGroup, x, y, RS_RocketAOE(), null)              
               
                loop
                    //Scanning through
                    set u = FirstOfGroup(udg_RS_TempGroup)
                    exitwhen u == null
                    call RS_TargetFilter(u, pl)
                    call GroupRemoveUnit(udg_RS_TempGroup, u)
                   
                    //Select all the units which are to be damaged
                    if (IsUnitInGroup(u, udg_RS_TempGroup2)) then
                        //Dealing health and mana damage
                        call UnitDamageTarget(udg_RS_OriginalCaster[Node], u, udg_RS_HealthDamage[Node], true, false, RS_AttackType(), RS_DamageType(), RS_WeaponType())
                        call SetUnitState(u, UNIT_STATE_MANA, (GetUnitState(u,UNIT_STATE_MANA) - udg_RS_ManaDamage[Node]))
                        call GroupRemoveUnit(udg_RS_TempGroup2, u)
                    endif
                   
                endloop
                   
                //Removes the projectile
                call RemoveUnit(udg_RS_Unit[Node])

                if (udg_RS_LastNode == Node) then
                    set udg_RS_LastNode = udg_RS_PreviousNode[Node]
                endif
               
                //Recycles the node
                set udg_RS_RecycleNodes[udg_RS_RecycleableNodesNumber] = Node
                set udg_RS_RecycleableNodesNumber = udg_RS_RecycleableNodesNumber + 1
                set udg_RS_NextNode[udg_RS_PreviousNode[Node]] = udg_RS_NextNode[Node]
                set udg_RS_PreviousNode[udg_RS_NextNode[Node]] = udg_RS_PreviousNode[Node]
                set udg_RS_SpellCounter = udg_RS_SpellCounter - 1
                set TempInt = TempInt - 1

                //Destroys the timer when not in use
                if (udg_RS_SpellCounter == 0) then
                    call DestroyTimer(GetExpiredTimer())
                endif

            else
               
                //Makes sure the target location is within the map bounds
                if (x < udg_RS_MapMaxX) and (x > udg_RS_MapMinX) and (y < udg_RS_MapMaxY) and (y > udg_RS_MapMinY) then
                    call SetUnitX(udg_RS_Unit[Node], x)
                    call SetUnitY(udg_RS_Unit[Node], y)
                endif
               
            endif
           
        endif

    endloop
   
endfunction
   
   
//////////////////////////////////////////////////////////////////////////
//  Creates the Spheres, uses information passed to it to get the       //
//  correct mass, rocket number, rocket power, amongst other things     //
//////////////////////////////////////////////////////////////////////////
function RS_RocketSphereCreation takes real BlastPower, real RS_RocketMass, real RS_SphereMass, real RS_CrossSectionEnd, real HealthDamage, real ManaDamage, real z2, real x2, real y2, unit u returns nothing

    //Creates all the local variables needed for this section
    local real RS_Angle = 0
    local real RS_SecondaryAngle
    local real Distance
    local real x
    local real y
    local real z = 0
    local real dx
    local real dy
    local real TempReal
    local real TempTan
    local real TempTan2
    local integer Node
    local integer TempInt = R2I(360 / RS_RocketMass)
   
    //Creates a sphere of rockets
    loop
        //Dubplicates the cross-sections into a sphere shape
        set RS_Angle = RS_Angle + RS_RocketMass
        exitwhen RS_Angle > 360
        set RS_SecondaryAngle = RS_SphereTop()
       
        loop
            //Creates a single cross-section of the sphere
            set RS_SecondaryAngle = RS_SecondaryAngle - ((RS_SphereTop() - RS_SphereBottom()) / TempInt)
            exitwhen RS_SecondaryAngle < RS_CrossSectionEnd
            set Distance = Cos(RS_SecondaryAngle) * RS_SphereMass
            if (Distance < 0) then
                set Distance = Distance * -1
            endif

            set udg_RS_SpellCounter = udg_RS_SpellCounter + 1
            set x = x2 + Distance * Cos(RS_Angle * bj_DEGTORAD)
            set y = y2 + Distance * Sin(RS_Angle * bj_DEGTORAD)
            set z = Sin(RS_SecondaryAngle) * RS_SphereMass + z2
            //Checking for recycle Nodes
            if (udg_RS_RecycleableNodesNumber == 0) then
                set udg_RS_NodeNumber = udg_RS_NodeNumber + 1
                set Node = udg_RS_NodeNumber
            else
                set udg_RS_RecycleableNodesNumber = udg_RS_RecycleableNodesNumber - 1
                set Node = udg_RS_RecycleNodes[udg_RS_RecycleableNodesNumber]
            endif

            //Sets up this Node
            set udg_RS_NextNode[Node] = 0
            set udg_RS_NextNode[udg_RS_LastNode] = Node
            set udg_RS_PreviousNode[Node] = udg_RS_LastNode
            set udg_RS_LastNode = Node
            //Sets up data for this rocket
            set udg_RS_Unit[Node] =  CreateUnit(Player(14), RS_DummyUnit(), x, y, RS_Angle)
            set udg_RS_ActivationTime[Node] = GetRandomReal(RS_RocketLaunchDelayMin(), RS_RocketLaunchDelayMax())
            set udg_RS_OriginalCaster[Node] = u
            set udg_RS_HealthDamage[Node] = HealthDamage
            set udg_RS_ManaDamage[Node] = ManaDamage
           
            //Checks if it's the only rocket around
            if (udg_RS_SpellCounter == 1) then
                call TimerStart(CreateTimer(), RS_TimerSpeed(), true, function RS_RocketSphereLoop)
            endif
 
            //Sets up the trajectory
            set dx = x2 - x
            set dy = y2 - y
            set Distance = SquareRoot((dx * dx) + (dy * dy))
            set TempTan = Atan2(dy, dx)
            set TempTan2 = Atan2(z2 - z, Distance)
            set TempReal = (BlastPower / RS_SphereMass) * RS_TimerSpeed()
            set udg_RS_ZVelocity[Node] = TempReal * Sin(TempTan2)
            set udg_RS_XVelocity[Node] = TempReal * Cos(TempTan) * Cos(TempTan2)
            set udg_RS_YVelocity[Node] = TempReal * Sin(TempTan) * Cos(TempTan2)

            //Sets up aesthetics
            call SetUnitFlyHeight(udg_RS_Unit[Node], z, 0.00)
            set udg_RS_CurrentZ[Node] = RS_GetZ(x, y) + z
            set udg_RS_CurrentEffect[Node] = AddSpecialEffectTarget(RS_RocketModel(), udg_RS_Unit[Node], "origin")
            call SetUnitScale(udg_RS_Unit[Node], RS_RocketScale(), 0.00, 0.00)
            call SetUnitAnimationByIndex(udg_RS_Unit[Node], (R2I(Atan2(udg_RS_ZVelocity[Node], SquareRoot((udg_RS_YVelocity[Node] * udg_RS_YVelocity[Node]) + (udg_RS_XVelocity[Node] * udg_RS_XVelocity[Node]))) * bj_RADTODEG + 0.5)) + 90)
                   
        endloop
       
    endloop
   
endfunction

//////////////////////////////////////////////////////////////////////////
//  Starts up a new instance of the spell and calls the sphere          //
//  creation function, and passes all the necessary information         //
//////////////////////////////////////////////////////////////////////////

function RS_NewInstance takes nothing returns boolean

    //Creates all the local variables needed for this section
    local unit u
    local integer TempInt
    local integer TempInt2
    local real TempReal
    local real TempReal2
    local real x
    local real y
    local real x2
    local real y2
    local real z
    local real Angle = 0
    local real Index = 0
    local real RocketMass
    local real SphereMass
    local real BlastPower
    local real CrossSectionEnd
    local real HealthDamage
    local real ManaDamage
   
    //Checks if the right ability was casted
    if (GetSpellAbilityId() == RS_Ability()) then
        //Sets up basic information about the casting unit
        set u = GetTriggerUnit()
        set x = GetUnitX(u)
        set y = GetUnitY(u)
        set TempInt = GetUnitAbilityLevel(u, RS_Ability())
       
        //Sets up Sphere data
        set TempInt2 = RS_SphereCountBase() + (RS_SphereCountPerLevel() * TempInt)
        set TempReal = I2R(TempInt)
        set TempReal2 = RS_SphereSpreadSpaceBase() + (RS_SphereSpreadSpacePerLevel() * TempReal)
        set SphereMass = RS_SphereMassBase() + (RS_SphereMassPerLevel() * TempReal)
        set RocketMass = (RS_SphereStandardMass() / SphereMass) * RS_RocketStandardMass()
        set BlastPower = RS_BlastPowerBase() + (RS_BlastPowerPerLevel() * TempReal)
        set CrossSectionEnd = RS_SphereBottom()
        set HealthDamage = RS_RocketHealthDamageBase() + (RS_RocketHealthDamagePerLevel() * TempReal)
        set ManaDamage = RS_RocketManaDamageBase() + (RS_RocketManaDamagePerLevel() * TempReal)
       
        //Creates Spheres
        loop
            set Index = Index + 1
            exitwhen Index > TempInt2
            set Angle = Angle + (360.00 / TempInt2)
            set x2 = x + TempReal2 * Cos(Angle * bj_DEGTORAD)
            set y2 = y + TempReal2 * Sin(Angle * bj_DEGTORAD)
            set z = RS_SphereHeightBase() + (RS_SphereHeightPerLevel() * TempReal)
           
            call DestroyEffect(AddSpecialEffect(RS_RocketSpawnModel(), x2, y2))
            //Passes parameters to the Sphere creation function
            call RS_RocketSphereCreation(BlastPower, RocketMass, SphereMass, CrossSectionEnd, HealthDamage, ManaDamage, z, x2, y2, u)
           
        endloop
       
    endif
   
    set u = null
   
    return false
   
endfunction

//////////////////////////////////////////////////////////////////////////
//  Initialisation Function which sets up the trigger to run the        //
//  correct function at the correct time                                //
//////////////////////////////////////////////////////////////////////////
function InitTrig_Rocket_Spheres takes nothing returns nothing

    //Creates locals
    local trigger RS = CreateTrigger()
    local integer index = 0

    //Initialise the event for every player
    loop
        call TriggerRegisterPlayerUnitEvent(RS, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
   
    call TriggerAddCondition(RS, Condition(function RS_NewInstance))
   
    //Get all the map bounds so they can be used efficiently later
    set udg_RS_MapMaxX = GetRectMaxX(bj_mapInitialPlayableArea)
    set udg_RS_MapMinX = GetRectMinX(bj_mapInitialPlayableArea)
    set udg_RS_MapMaxY = GetRectMaxY(bj_mapInitialPlayableArea)
    set udg_RS_MapMinY = GetRectMinY(bj_mapInitialPlayableArea)
   
    //Initialise the Z-height finding location
    set udg_RS_ZLoc = Location(0,0)

    //Nulls variables
    set RS = null
   
endfunction

//////////////////////////////////////////////////////////////////////////
//  End of the spell                                                    //
//////////////////////////////////////////////////////////////////////////



  • Variable Creator
    • Events
    • Conditions
    • Actions
      • Set RS_ActivationTime[0] = 0.00
      • Set RS_CurrentEffect[0] = RS_CurrentEffect[0]
      • Set RS_CurrentZ[0] = 0.00
      • Set RS_HealthDamage[0] = 0.00
      • Set RS_LastNode = 0
      • Set RS_ManaDamage[0] = 0.00
      • Set RS_MapMaxX = 0.00
      • Set RS_MapMaxY = 0.00
      • Set RS_MapMinX = 0.00
      • Set RS_MapMinY = 0.00
      • Set RS_NextNode[0] = 0
      • Set RS_NodeNumber = 0
      • Set RS_OriginalCaster[0] = RS_OriginalCaster[0]
      • Set RS_PreviousNode[0] = 0
      • Set RS_RecycleNodes[0] = 0
      • Set RS_RecycleableNodesNumber = 0
      • Set RS_SpellCounter = 0
      • Set RS_TempGroup = RS_TempGroup
      • Set RS_TempGroup2 = RS_TempGroup2
      • Set RS_Unit[0] = RS_Unit[0]
      • Set RS_XVelocity[0] = 0.00
      • Set RS_YVelocity[0] = 0.00
      • Set RS_ZLoc = RS_ZLoc
      • Set RS_ZVelocity[0] = 0.00




172730-albums6263-picture73002.png



172730-albums6263-picture73001.png



172730-albums6263-picture73023.png



172730-albums6263-picture73024.png



172730-albums6263-picture73025.png




-=V1.00=-
- Initial Upload


Always on the lookout to improve my work, post suggestions on how to make it better and I'll see what I can do, Enjoy and give credits if you use this spell in your map.

Keywords:
Rocket, Sphere, Orb, Overkill, Too much spare time, Blinding, May cause Seizures, Bomb, Explosion, Random, Boss, Spell, Cannon.
Contents

Rocket Spheres (Map)

Reviews
Rocket Spheres V1.00 | Reviewed by Maker | 14th Sep 2013 APPROVED It is a creative spell and also looks very appealing. Fun to cast too [tr] The spell take a very heavy toll on FPS. I'd like to see you improve this...

Moderator

M

Moderator


Rocket Spheres V1.00 | Reviewed by Maker | 14th Sep 2013
APPROVED


126248-albums6177-picture66521.png


  • It is a creative spell and also looks very appealing. Fun to cast too
126248-albums6177-picture66523.png


  • The spell take a very heavy toll on FPS. I'd like to see you improve this aspect
  • GroupEnumUnitsInRange does not pick units with Locust,
    no need to filter them out
[tr]
 
It'll cause lag on ye olde computers, or if you just go over trigger-happy on creating many more rockets than reasonable (hence why the readme giving information on what's definitely too much, like giving rockets masses of 10 or lower since it'll try to create about 600 rockets at once if you do that, which warcraft 3 cannot do at a single time and then break it).
 
Level 13
Joined
Mar 29, 2012
Messages
530
Wow, another great spell to inspired to :D
+Rep

Going to review :)

Review

Minimize

Comment

Rating

  • You can use "call TriggerRegisterAnyUnitEventBJ(trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT)" to initialize the event for all players
  • Every instance have it's own timer! Perhaps it can be reduce :D, but since the spell work properly i think it's not too important :)
Approved
I just can say that. Cuz you are more experienced than me... :D
[TD]

Rating

[/TD]
 
[*]You can use "call TriggerRegisterAnyUnitEventBJ(trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT)" to initialize the event for all players
[*]Every instance have it's own timer! Perhaps it can be reduce :D, but since the spell work properly i think it's not too important :)

Look at the function TriggerRegisterAnyUnitEventBJ, it gives you what I have in the code: I CnP'd it out of there as to cut out the function call - I.e. one less line of code executed

it all runs using one timer, each rocket has it's own artifical wait, and that's intrinsically linked to how the rockets work, to alter that would be to alter the functionality of the spell. Doesn't increase processing any more so than using one artifical wait repeadely and then finding rockets to launch.
 
My computer can't handle skyrim on anything higher than lowest: without getting lag from the spell, prehaps your computer is lacking in some other aspect (or mine is particularly good with graphical settings themselves if you subtract shadow calculation and such)? eitherway you can just lower it and it's fine so no problems there.

and while I would make the projectiles aim at units directly, 300+ homing rockets would/could cause a lot of extra processing - they fire straight out specifically to lighten the load (as data per rocket would also increase, which obviously, adds up quickly with a lot of rockets) but certainly I agree with you that it would be probably a lot cooler (though much harder to balance)
 
Top