Spellcasting system
by Lukas Joergensen · 04/07/2012 (12:17 pm) · 32 comments
Download code files
Hello, and welcome to my first resource! Please, help me in improving this resource if you find any errors, or badly explained parts you want clarified!
First off a quick list of features:
For the system to function properly, it needs the client to have a player. Because it uses the eyevector to calculate on where the spells should hit.
I will use the flamepillar spell as an example!
First create a new ScriptObject with the name of your spell:
Type defines what kind of spell it is (Projectil, summon, AoE, heal etc.)
Raytype defines what rayresult we want when using the CastAtScreenCenter method.
And add the new ScriptObject to the SimGroup 'spells'.
Then define a Cast function like this:
And then add the code for the spell:
Just copy everything from the folder into your own art folder. You don't have to override anything.
Please mind that the assets in the art folder is from the Torque Engine and as such is none of my property and even tho anything in this resource that i made is free those assets are not.
The decal is mine however you are free to use that as you please!
Then in art/datablocks/datablockExec.cs
Add this anywhere in the file:
Now step into the Client folder and copy:
After that just add the changes from default.bind_changes.cs to your own default.bind.cs
Now go into your init.cs file and add:
Now step into the Server folder and copy:
Then add the function in player_changes.cs with your player class.
Edit:
Almost forgot, to have spellanimations you need to add some animations to your model. If you like me use the stock Soldier model as your prototype model, add this in soldier_rigged.cs



This is my first resource so i might be missing something or have explained something poorly, again just comment on this resource if you want something fixed or shined a bit up! I will remain active on this resource!
Hello, and welcome to my first resource! Please, help me in improving this resource if you find any errors, or badly explained parts you want clarified!
First off a quick list of features:
- AoE spell indicator
- 2 sample spells Fireball and Pillar of Flame
- Simple pipeline for adding new spells
- Support for spellanimations
For the system to function properly, it needs the client to have a player. Because it uses the eyevector to calculate on where the spells should hit.
How to add a new spell:
First create a new file give it any name and place it in the Scripts/Server/Spells folder.I will use the flamepillar spell as an example!
First create a new ScriptObject with the name of your spell:
new ScriptObject( Flamepillar ){
superClass = Spell;
type = "AOE";
raytype = "point";
};
spells.add(Flamepillar);Always set superClass to Spell.Type defines what kind of spell it is (Projectil, summon, AoE, heal etc.)
Raytype defines what rayresult we want when using the CastAtScreenCenter method.
And add the new ScriptObject to the SimGroup 'spells'.
Then define a Cast function like this:
function Flamepillar::Cast(%this, %pos, %trans, %path, %team, %client)
{
// First if we miss any of the needed variables, message the error to the console
// and return with an error.
if(%pos $= ""){
error("No pos on Rogue::Cast");
return false;
}
if(%trans $= ""){
error("No trans on Rogue::Cast");
return false;
}
}And then add the code for the spell:
function Flamepillar::Cast(%this, %pos, %trans, %path, %team, %client)
{
// First if we miss any of the needed variables, message the error to the console
// and return with an error.
if(%pos $= ""){
error("No pos on Rogue::Cast");
return false;
}
if(%trans $= ""){
error("No trans on Rogue::Cast");
return false;
}
// Instantiate the ParticleEmitterNode which shows the almighty Pillar of Flame
%flame = new ParticleEmitterNode(){
position = %pos;
rotation = "1 0 0 0";
scale = "1 1 1 1";
dataBlock = broadNode;
emitter = broadEmitter;
velocity = 1;
};
// Dish out some damage when the Pillar of Flame is spawned
radiusDamage(%col, %pos, 2.5, 20, "Projectile", 0);
// Tell the client to lock for 2000 ms and cast spellanimation 1
commandToClient(%client, 'BeginCast', 2000, 1);
// Return with the instantiated object
return %flame;
}Then to fire the spell we will just use this:commandToServer('CastSpell', "Flamepillar");Or if we want it to have a spellIndicator:spellIndicator("Flamepillar");Installation
First download the code files (link at top).Just copy everything from the folder into your own art folder. You don't have to override anything.
Please mind that the assets in the art folder is from the Torque Engine and as such is none of my property and even tho anything in this resource that i made is free those assets are not.
The decal is mine however you are free to use that as you please!
Then in art/datablocks/datablockExec.cs
Add this anywhere in the file:
exec("./../effects/effects.cs");
exec("./../decals/indicatorDecal.cs");Now step into the Client folder and copy:
- movement.cs
- raycasts.cs
- scriptExec.cs
- spellindicator.cs
- (If you don't already have one) commands.cs
After that just add the changes from default.bind_changes.cs to your own default.bind.cs
Now go into your init.cs file and add:
exec("./scriptExec.cs");under Client scripts.Now step into the Server folder and copy:
- spell.cs
- spells
- utility
Then add the function in player_changes.cs with your player class.
Edit:
Almost forgot, to have spellanimations you need to add some animations to your model. If you like me use the stock Soldier model as your prototype model, add this in soldier_rigged.cs
%this.addSequence( "./Anims/PlayerAnim_Lurker_Celebrate_01.dae Celebrate_01", "spell_1", 0, -1); %this.addSequence( "./Anims/PlayerAnim_Lurker_Head.dae Head", "spell_2", 0, -1);In the onLoad function right after all the other addSequence calls.
Screenshots:
Pillar of Flame and spell animations:

Fireball

Spell indicator

This is my first resource so i might be missing something or have explained something poorly, again just comment on this resource if you want something fixed or shined a bit up! I will remain active on this resource!
About the author
IPS Bundle available at: https://www.winterleafentertainment.com/Products/IPS.aspx
#2
04/07/2012 (2:48 pm)
Well thank you very much! I hope it helps some newcomers at Torque with some of the things that i personally have had a lot of trouble with :)
#3
04/08/2012 (9:19 pm)
Nice. One thing you might like to do is put the call to spells.add in Spell::onAdd, like so:function Spell::onAdd(%this)
{
spells.add(%this);
...
}That way, the user only needs to declare the spell object, and it automatically gets added for them.
#4
04/10/2012 (12:39 am)
That is so strangely simple and yet super effective! I will integrate it in the code when i get some time to do it ;)
#5
04/20/2012 (8:53 am)
Nice work Lukas. Like the use of the buttons too ;)
#6
04/20/2012 (1:26 pm)
Thought you'd be able to recognize those buttons S2P :D
#7
Just a note. I had to add the key bindings to config.cs and set up different keys. I ended up using altTrigger + mouse button1 instead of mouseFire since I use mouseFire for melee strike.
Thanks again for sharing this :)
05/03/2012 (9:33 pm)
Great resource!Just a note. I had to add the key bindings to config.cs and set up different keys. I ended up using altTrigger + mouse button1 instead of mouseFire since I use mouseFire for melee strike.
Thanks again for sharing this :)
#8
Oh yeah, that config.cs is some autogenerated file. I think it is generated because it saves the keybinds when the user customizes them.
You can actually just delete the config.cs and the file will be reverted to the default settings (the ones in default.binds.cs) :)
05/04/2012 (1:40 am)
@RobOh yeah, that config.cs is some autogenerated file. I think it is generated because it saves the keybinds when the user customizes them.
You can actually just delete the config.cs and the file will be reverted to the default settings (the ones in default.binds.cs) :)
#9
07/19/2013 (10:55 am)
How can you make it where when you cast a spell it drains the players energy and a setting to change how much energy is cost for a spell? Also is there a way to change the Flame Pillar to use a keybind instead of using the mouse. Example: You press 1 to active the spell indicator and then press 1 again to cast the spell for the Flame pillar.
#10
@Stephen just move this code:
To drain energy use the getEnergyLevel and setEnergyLevel methods:
*WARNING* The rest of this is just links to other resources and products.
Also you should have a look at this: IPS Bundle Pre-release
It includes a much better SpellSystemm, and a great particle system for FX.
Or if you really want to avoid spending any money you should look at this resource. It shows you how to use Charlie Pattersons Twillex resource to animate particle emitters to create some basic spell effects.
And if you want to optimize the SpellDecals a bit you can implement this resource
Lastly this resource is the prototype version of the IPS Pro. The code is crude and the implementation is bad but it works, and give you an idea of what you will get with the IPS Bundle.
07/19/2013 (11:15 am)
Wow people still read my resources!@Stephen just move this code:
if(%val && $nextSpell !$= "")
{
commandToServer('CastSpell', $nextSpell);
$nextSpell = "";
decalManagerRemoveDecal( $SpellDecal );
$SpellDecal = "";
}From the mouseFire function to the function that fires the spell. Then first time you press the button, $nextSpell will be "" and therefore it will just spawn the decal, next time it will fire the spell. Example:moveMap.bindCmd(keyboard, "1", "ClientCastSpell(\"Flamepillar");\");
function ClientCastSpell(%spell)
{
if($nextSpell !$= "")
{
commandToServer('CastSpell', $nextSpell);
$nextSpell = "";
decalManagerRemoveDecal( $SpellDecal );
$SpellDecal = "";
}
else
spellIndicator(%spell);
}To drain energy use the getEnergyLevel and setEnergyLevel methods:
%player.setEnergyLevel(%player.getEnergyLevel() - 50);
*WARNING* The rest of this is just links to other resources and products.
Also you should have a look at this: IPS Bundle Pre-release
It includes a much better SpellSystemm, and a great particle system for FX.
Or if you really want to avoid spending any money you should look at this resource. It shows you how to use Charlie Pattersons Twillex resource to animate particle emitters to create some basic spell effects.
And if you want to optimize the SpellDecals a bit you can implement this resource
Lastly this resource is the prototype version of the IPS Pro. The code is crude and the implementation is bad but it works, and give you an idea of what you will get with the IPS Bundle.
#11
07/19/2013 (12:05 pm)
Where to put the energy drain at?
#12
07/19/2013 (12:08 pm)
Ah sorry I made a syntax error, did you remember to escape the quotes?moveMap.bindCmd(keyboard, "1", "ClientCastSpell(\"Flamepillar\");");
#13
07/19/2013 (12:11 pm)
Put the energy drain when you want to drain the energy, a good place would be to place it in the Cast function of the spell.
#14
Where should the energy drain be places at? I would like to have the cost of energy different for each spell.
07/19/2013 (12:11 pm)
I forgot to delete the "config.cs". Torsion caught that bug with the keybind. I got the Flame pillar working now but I noticed that you can still shoot as your character is playing the cast animation.Where should the energy drain be places at? I would like to have the cost of energy different for each spell.
#15
07/19/2013 (12:18 pm)
Okay so I got the spell to use the energy but I can still cast the spell at 0 energy.
#16
To prevent shooting just set a boolean "$canShoot = false;". and test for that boolean in the MouseFire function.
07/19/2013 (12:18 pm)
You could do something like this:new ScriptObject( Flamepillar ){
superClass = Spell;
type = "AOE";
raytype = "point";
cost = 20;
};
function Flamepillar::Cast(%this, %pos, %trans, %path, %team, %client)
{
// First if we miss any of the needed variables, message the error to the console
// and return with an error.
if(%pos $= ""){
error("No pos on Rogue::Cast");
return false;
}
if(%trans $= ""){
error("No trans on Rogue::Cast");
return false;
}
%player = %client.getControlObject();
%player.setEnergyLevel(%player.getEnergyLevel() %this.cost);
}To prevent shooting just set a boolean "$canShoot = false;". and test for that boolean in the MouseFire function.
#17
07/19/2013 (12:20 pm)
Just make an if clause:function Flamepillar::Cast(%this, %pos, %trans, %path, %team, %client)
{
// First if we miss any of the needed variables, message the error to the console
// and return with an error.
if(%pos $= ""){
error("No pos on Rogue::Cast");
return false;
}
if(%trans $= ""){
error("No trans on Rogue::Cast");
return false;
}
%player = %client.getControlObject();
if(%player.getEnergyLevel() >= %this.cost)
%player.setEnergyLevel(%player.getEnergyLevel() - %this.cost);
else{
error("Not enough energy!");
return false;
}
}
#18
07/19/2013 (12:30 pm)
Okay the cost of the spell is working great now but I'm not sure how to fix the shooting while casting the spell.
#19
07/19/2013 (12:40 pm)
I have tested this all in multiplayer and the only thing that I can see that has a problem is the decal doesn't show up for the client only server can see the decal. The client gets this error, "decalManagerAddDecal - Invalid Decal DataBlock".
#20
Did you fix the shooting then?
07/19/2013 (12:56 pm)
Hmm thats weird, try echoing the datablock id and see what it tries to add client-side.Did you fix the shooting then?

Torque Owner Robert Fritzen
Phantom Games Development
Nice work!