Game Development Community

Mission Area Force Field & Particle Emitter

by Britton LaRoche · 01/25/2009 (8:12 pm) · 7 comments

I borrowed the bare essential idea from the Mission Area Force Field V2 Resource (Which is a Great Resource!) and implemented my own version in about 5 minutes with no C++ engine modifications.

Our first step is to create a visual effect to let the player know he or she hit the force field. An easy way to do this is to spawn a non moving projectile with its own particle emitter.

scripts and assets /server/scripts/projectileEmitter.cs
//-----------------------------------------------------------------------------
// Copyright (C) 2009 (your company name)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Projectile emitters
//
//  Easy way to spawn a particle emitter, by creating a 
//  projectile with no damage
//
// Script:  Original Author - Britton LaRoche 12/11/2003
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Particles
//

datablock ParticleData(effectParticle)
{
   textureName          = "~/data/shapes/particles/bubble";
   dragCoefficient     = 0.0;
   gravityCoefficient   = -0.1;
   inheritedVelFactor   = 0.0;
   lifetimeMS           = 1000;
   lifetimeVarianceMS   = 10;   // ...more or less
   useInvAlpha = true;
   spinRandomMin = -60.0;
   spinRandomMax = 60.0;

   colors[0]     = "0 0 0 0.0";
   sizes[0]      = 0.5;
   sizes[1]      = 3.5;
   sizes[2]      = 20.5;
   times[0]      = 0.0;
   times[1]      = 0.5;
   times[2]      = 1.0;

};



datablock ParticleData (smokeParticle : effectParticle)
{
   textureName = "~/data/shapes/particles/smoke";
};

datablock ParticleData (forceFieldParticle : effectParticle)
{
   textureName = "~/data/shapes/particles/bubble";
};

//-----------------------------------------------------------------------------
// Effects
//

datablock ParticleEmitterData(effectEmitter)
{
   ejectionPeriodMS = 150;
   periodVarianceMS = 0;

   ejectionVelocity = 0.0;
   velocityVariance = 0.0;

   thetaMin         = 0.0;
   thetaMax         = 0.0;

   particles = effectParticle;
};

datablock ParticleEmitterData(forceFieldEmitter : effectEmitter)
{
   particles = forceFieldParticle;
};

//-----------------------------------------------------------------------------
// Projectiles
//

datablock ProjectileData(effectProjectile)
{
   muzzleVelocity      = 0;
   velInheritFactor    = 0.0;
   particleEmitter     = effectEmitter;
   armingDelay         = 0;
   lifetime            = 1000;
   fadeDelay           = 0;
   bounceElasticity    = 0;
   bounceFriction      = 0;
   isBallistic         = false;
   gravityMod = 0;
};


datablock ProjectileData(forceFieldProjectile : effectProjectile)
{
	particleEmitter     = forceFieldEmitter;
};


function ShowProjectileEffect( %pos, %projectileEffect ){
        // Create the projectile particle emitter object
	// Randomly adjust the hieght of the effect
	%zrand = getRandom(3,8);
	%pos = setWord(%pos, 2, ( getWord(%pos, 2) + (%zrand/2) ) );

	//adjust the x an y pos too, by 50% of the bots index number
	%xrand = getRandom(0,2);
	%pos = setWord(%pos, 0, ( getWord(%pos, 0) + ( %xrand/2 ) ) );

	%yrand = getRandom(0,2);
	%pos = setWord(%pos, 1, ( getWord(%pos, 1) + ( %yrand/2 ) ) );

	
	%p = new (Projectile)() {
		dataBlock        = %projectileEffect;
		initialVelocity  = 0;
		initialPosition  = %pos;
	};
	MissionCleanup.add(%p);
}

Now that we have created this cool visual effect, we need to load the projectile emitters script in the game code.

scripts and assets /server/scripts/game.cs
function onServerCreated()
{
   // Server::GameType is sent to the master server.
   
   ...
   exec("./aiPlayer.cs");
   exec("./sgExamples.cs");
   
   exec("./projectileEmitters.cs");

In the game scripts and assets ... /server/scripts/player.cs
//-----------------------------------------------------------------------------

function Armor::onLeaveMissionArea(%this, %obj)
{
   // Inform the client
   %obj.client.onLeaveMissionArea();
   messageClient(%obj.client, 'default', 'A force field repelled you!');
   

   // Spawn a projectile particle emitter effect for visuals	
   ShowProjectileEffect(%obj.getPosition(), "forceFieldProjectile"); 
      
   // play a force field sound   
   %obj.PlayForceField();
   
   //Force the player backword
   %force = GlobalMissionArea.bounce;    
   %min_x = getWord(GlobalMissionArea.area, 0);
   %min_y = getWord(GlobalMissionArea.area, 1);
   %max_x = %min_x + getWord(GlobalMissionArea.area, 2);
   %max_y = %min_y + getWord(GlobalMissionArea.area, 3);
   %x = getWord(%obj.getPosition(), 0);
   %y = getWord(%obj.getPosition(), 1);
   %vx = 0;%vy = 0;%vz = 0;    
   if (%x<(%min_x+10)) %vx = %force;
   if (%y<(%min_y+10)) %vy = %force;
   if (%x>(%max_x-10)) %vx = -%force;
   if (%y>(%max_y-10)) %vy = -%force;
   %vec = %vx @ " " @ %vy @ " " @ %vz;
   %obj.setVelocity(%vec);
}


/// .... Play force field sound 
/// .... Replace with this with your new sound

function Player::PlayForceFieldSound( %this )
{
   %this.playAudio(0,PainCrySound);
}


For some reason the "MissionArea" tag in the mission files is now "GlobalMissionArea" in TGEA 1.8.0, so pop open your mission.mis (data/missions/stronghold.mis) file in a text editor and change your new MissionArea function to look like the following.

new MissionArea(GlobalMissionArea) {
      canSaveDynamicFields = "1";
      Enabled = "1";
      Area = "-150 -450 450 900";
      flightCeiling = "300";
      flightCeilingRange = "20";
         bounce = "50";
         locked = "true";
   };

The key here is two things:
new MissionArea(GlobalMissionArea)
bounce="50";

For earlier versions of TGE this will probably work
new MissionArea(MissionArea)

That is it. You can easily test this with the strong hold demo. The bounce sets the force at which you are repelled. Happy coding!


#1
01/26/2009 (7:48 am)
Very handy resource!
#2
01/28/2009 (3:33 am)
yep - agree with Todd. Thanks!
#3
01/31/2009 (10:29 pm)
Nice one! =)
#4
02/15/2009 (3:51 pm)
Anyone able to get this to work in TGEA 1.7.1? I actually saw errors on the console until I change MissionArea back to GlobalMissionArea in my mission.mis
#5
02/17/2009 (11:25 pm)
How can I make the player bounce back farther? I tried changing the bounce to 500, but I don't see any difference between 50 and 500 bounce when I run out of the mission area.
#6
02/21/2009 (8:40 am)
Just an update to my previous post. I was able to get this working in TGEA 1.7.1 using the Stronghold demo. Will retry adding it into my game. I must have done something wrong.

Thanks for this great and much easier to use resource.
#7
08/20/2011 (9:37 pm)
@David Bedford
You can try adding some to the z axis on %vz like %vz*2 or something to lift the player and cause them to launch up and back.