Game Development Community

Ouch! Spellcasting hurts!

by Dreamer · in Torque Game Engine · 04/11/2005 (12:24 pm) · 18 replies

In server/scripts/commands.cs add the following
function ServerCmdCastSpell(%client,%spell){
	echo("Casting Spell!");
	if(%spell $="Bolt"){
		echo("Spell was Bolt!");
		%bolt = new (Projectile)() {
			dataBlock        = SpellProjectile;
			initialVelocity  = 100;
			initialPosition  = %client.Player.getTransform();
			sourceObject     = %client.Player;
			client           = %client;
		};
		MissionCleanup.add(%bolt);
		%client.Player.setEnergyLevel(%client.Player.getEnergyLevel() - %bolt.EnergyCost);
	}
	echo("Casting Complete!");
}

Now add the following file and exec it in your server/scripts/game.cs
server/scripts/DDSpell.cs
datablock ProjectileData(SpellProjectile)
{
   projectileShapeName = "~/data/shapes/crossbow/projectile.dts";
   directDamage        = 20;
   radiusDamage        = 20;
   damageRadius        = 1.5;
   EnergyCost	       = 10;
   explosion           = CrossbowExplosion;
   waterExplosion      = CrossbowWaterExplosion;

   particleEmitter     = CrossbowBoltEmitter;
   particleWaterEmitter= CrossbowBoltBubbleEmitter;

   splash              = CrossbowSplash;

   muzzleVelocity      = 100;
   velInheritFactor    = 0.3;

   armingDelay         = 0;
   lifetime            = 5000;
   fadeDelay           = 5000;
   bounceElasticity    = 0;
   bounceFriction      = 0;
   isBallistic         = false;
   gravityMod = 0.80;

   hasLight    = true;
   lightRadius = 4;
   lightColor  = "0.5 0.5 0.25";

   hasWaterLight     = true;
   waterLightColor   = "0 0.5 0.5";
};

function SpellProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
   // Apply damage to the object all shape base objects
   if (%col.getType() & $TypeMasks::ShapeBaseObjectType)
      %col.damage(%obj,%pos,%this.directDamage,"CrossbowBolt");

   // Radius damage is a support scripts defined in radiusDamage.cs
   // Push the contact point away from the contact surface slightly
   // along the contact normal to derive the explosion center. -dbs
   radiusDamage(%obj, VectorAdd(%pos, VectorScale(%normal, 0.01)),%this.damageRadius,%this.radiusDamage,"Radius",40);
}

Now add the following to client/scripts/default.bind.cs
moveMap.bind(keyboard,"c","CastSpell");

function CastSpell(){
	CommandToServer('CastSpell',"Bolt");
}

Now run your program and press the "C" button.

Ouch huh? Any idea on how I can get the projectile to not blow me to hell, I think starting it saw 5 or so units out in front of me will do that, but how the heck can I tell the engine to start the projectile out just a few units in front of me?

Thanx for the helps!

#1
04/11/2005 (12:27 pm)
This is nice, should post as resource.
#2
04/11/2005 (12:30 pm)
I would except casting causes the player to die :(

As for resources it looks like GG is being a little slow in approving the things, I have several tuts up right now that make use of TGE and some small mods to produce all kinds of neat things, like a Server Side Melee, Inventory and even a fishing tradeskill, I put them up a week or so ago and they still haven't been approved. Oddly enough the last one I put up about changing the default.dso directory in Linux IS up :(
#3
04/11/2005 (12:31 pm)
Change the initialPosition to something else than the player position?
#4
04/11/2005 (12:35 pm)
I understand, but what I'm asking is HOW to do that, my hope is to get it looking like the thing comes from the players hand or belly, but I'm not finding how to do math on the players current position.
#5
04/11/2005 (12:36 pm)
There is something like 'raycast' that gives you a vector to the a line of sight - hold on a sec.

[edit] the answer is somewhere in here. I think you need getEyeVector() to get a safe offset to the players position.
#6
04/11/2005 (1:24 pm)
Well... This almost works!
function ServerCmdCastSpell(%client,%spell){
	%Player = %client.Player;
	echo("Casting Spell!");
	if(%spell $="Bolt"){
		
		echo("Spell was Bolt!");
		%distance = 0.1;
		%eye = %player.getEyeVector();
   		%vec = vectorScale(%eye, %distance);
   		%startPoint = %Player.getTransform();
   		%LaunchPoint = VectorAdd(%startPoint,%vec);
		
		%bolt = new (Projectile)() {
			dataBlock        = SpellProjectile;
			initialVelocity  = 100;
			initialPosition  = %LaunchPoint;
			sourceObject     = %Player;
			client           = %client;
		};
		MissionCleanup.add(%bolt);
		%client.Player.setEnergyLevel(%client.Player.getEnergyLevel() - %bolt.EnergyCost);
	}
	echo("Casting Complete!");
}
Only problem is the trajectory is static, doesn't matter which way the player is facing the bolt always hits the same area. I think I may need a vector from the camera instead. :(
#8
04/11/2005 (2:01 pm)
Same result, just a static trajectory, no matter what the projectile is always firing in the same general direction, regardless of the direction my player is facing.
#9
04/11/2005 (2:12 pm)
Ahh but this works nicely and fits with my original game plan anyways (you need to have completed the object selection tutorial for this to work)

function ServerCmdCastSpell(%client,%spell){
	%Player = %client.Player;
	echo("Casting Spell!");
	if(%spell $="Bolt"){
		
		echo("Spell was Bolt!");
		%targetObject = %client.getSelectedObject();
		
				
		%bolt = new (Projectile)() {
			dataBlock        = SpellProjectile;
			initialVelocity  = 10;
			initialPosition  = %targetObject.getTransform();
			sourceObject     = %Player;
			client           = %client;
		};
		MissionCleanup.add(%bolt);
		%client.Player.setEnergyLevel(%client.Player.getEnergyLevel() - %bolt.EnergyCost);
	}
	echo("Casting Complete!");
}
#10
04/11/2005 (10:52 pm)
initialPosition  = %targetObject.getTransform();

so the bolt just manifests on top of the target, doesnt move from source to target?
#11
04/12/2005 (8:35 am)
@Ed Yes, it's a magical bolt of yummy goodness. Sometime soon I will try to make it actually start at the player and travel to the target, but for now think of it as a magic grenade spell.

Oddly enough I was wrong about my way of deducting energy for the spell so that part needs to be fixed and has been in the tutorial, now if they will ever approve my tuts :)

*Update* Cool my tutorials finally got up today! Yeah!
#12
10/02/2005 (7:49 am)
I was having a similar problem, in that I wanted to have a projectile launch from a specific point which was not attached to the player object. I was not using a gun so getting the muzzlepoint was out. My projectile was always shooting along the same axis no matter what I did.... that is until I looked at all of the values that were being set by the crossbow example for the projectile. The key to getting the projectile to go where you want it to is to properly set the initialVelocity parameter. In the code snippet above the initialVelocity is set to 10. This is setting just one value of the 3 word vector. A proper initialVelocity looks something like this: "-97.1623 -21.89 -8.96175".

You can get the values for the for the initialVelocity by doing something like this:
%hardEyeVector = "-0.937088 0.0664537 0.342708"; //%client.player.getEyeVector();
   %objectVelocity = "0 -3 0"; //%obj.getVelocity();
   %hardVelocity = 40;
   %velInheritFactor = 0.3;
   %projectileVelocity = VectorAdd(
      VectorScale(%hardEyeVector, %hardVelocity),
      VectorScale(%objectVelocity, %velInheritFactor));   
   // Create the projectile object   

   %p = new (Projectile)() {
      dataBlock        = TheProjectile;
      initialVelocity  = %projectileVelocity; //"-97.1623 -21.89 -8.96175";//%muzzleVelocity;
      initialPosition  = "499.875 322.92 220.936";
      sourceObject     = %player;
      //sourceSlot       = %slot;
      client           = %client;
   };
   MissionCleanup.add(%p);

I hope this helps.
#13
10/09/2005 (4:21 pm)
%bolt.setCollisionTimeout(%client.player);

add that to your projectile code I believe it makes it so that the bolt doesn't collide with the player. your problem is most likely that since you spawn the projectile at the center of the player it hits him as it goes out. another solution is to spawn it at his eye vector.

initialPosition = %client.player.getEyeVector();

I'm a little late but it can always help someone else and collision timeout is a usefull little function.
#14
11/04/2005 (11:04 am)
Set "armingDelay" to something > 0. This sets a time in milliseconds before the projectile will become active. Depending on the speed of the projectile, 100-200 ms would allow it to clear the player before arming.
#15
11/04/2005 (11:20 am)
Wow, I had no idea this thread was still going after all this time ;)
Thanks for the suggestions folks.
#16
11/11/2005 (12:57 am)
Is there any way to cast spell with mouse down with cursor on...??
#17
11/11/2005 (2:37 am)
The object selection code does a raycast to determine what object the cursor is over, no reason you couldn't modify it to fire a spell at whatever point you click on instead. Try looking for Dreamer's RPG tutorials
#18
11/17/2005 (10:34 pm)
Could i make the cursor as the source to target?