Moderator
M
Moderator
Rocket Spheres V1.00 | Reviewed by Maker | 14th Sep 2013 | ||||
APPROVED | ||||
|
////////////////////////////////////////////////////////////////////
// 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 //
//////////////////////////////////////////////////////////////////////////