Author Topic: Projectile animations and sticking them in walls  (Read 3146 times)

So i'm working on one of my new weapons for my medieval weapon pack and can't figure out the following:

- The throwing axe has custom flying animations called "Activate" and "Maintain", This makes the axe rotate while it's flying.
- When the throwing axe hits a wall it should stick into it like an arrow projectile, facing the direction of the surface it hit.

But whenever I throw it on onto something it keep playing the turning animation instead of holding still or facing the direction of the surface it's stuck into.

Code: [Select]
//ThrowingAxeAxe.cs
datablock AudioProfile(ThrowingAxeBrickSound)
{
filename    = "./throwingaxeHit.wav";
description = AudioClosest3d;
preload = true;
};
datablock AudioProfile(AxeDrawSound)
{
filename    = "./throwingaxeDraw.wav";
description = AudioClosest3d;
preload = true;
};
     
datablock ParticleData(AxethrownExplosionParticle)
{
dragCoefficient      = 5;
gravityCoefficient   = 0.1;
inheritedVelFactor   = 0.2;
constantAcceleration = 0.0;
lifetimeMS           = 500;
lifetimeVarianceMS   = 300;
textureName          = "base/data/particles/chunk";
spinSpeed = 10.0;
spinRandomMin = -50.0;
spinRandomMax = 50.0;
colors[0]     = "0.9 0.9 0.6 0.9";
colors[1]     = "0.9 0.5 0.6 0.0";
sizes[0]      = 0.25;
sizes[1]      = 0.0;
};
     
datablock ParticleEmitterData(AxethrownExplosionEmitter)
{
   ejectionPeriodMS = 1;
   periodVarianceMS = 0;
   ejectionVelocity = 5;
   velocityVariance = 0.0;
   ejectionOffset   = 0.0;
   thetaMin         = 80;
   thetaMax         = 80;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "AxethrownExplosionParticle";

   useEmitterColors = true;
   uiName = "Throwing Axe Explosion";
};
 
datablock ExplosionData(AxethrownExplosion)
{
   //explosionShape = "";

   lifeTimeMS = 150;

   particleEmitter = AxethrownExplosionEmitter;
   particleDensity = 10;
   particleRadius = 0.2;

   emitter[0] = "";

   faceViewer     = true;
   explosionScale = "1 1 1";

   shakeCamera = false;
   camShakeFreq = "10.0 11.0 10.0";
   camShakeAmp = "1.0 1.0 1.0";
   camShakeDuration = 0.5;
   camShakeRadius = 10.0;

   // Dynamic light
   lightStartRadius = 0;
   lightEndRadius = 0;
   lightStartColor = "0 0 0";
   lightEndColor = "0 0 0";
};
 
datablock ParticleData(ThrowingAxeExplosionParticle)
{
   dragCoefficient      = 2;
   gravityCoefficient   = 1.0;
   inheritedVelFactor   = 0.2;
   constantAcceleration = 0.0;
   spinRandomMin = -90;
   spinRandomMax = 90;
   lifetimeMS           = 500;
   lifetimeVarianceMS   = 300;
   textureName          = "base/data/particles/chunk";
   colors[0]     = "0.7 0.7 0.9 0.9";
   colors[1]     = "0.9 0.9 0.9 0.0";
   sizes[0]      = 0.5;
   sizes[1]      = 0.25;
};

datablock ParticleEmitterData(ThrowingAxeExplosionEmitter)
{
   ejectionPeriodMS = 7;
   periodVarianceMS = 0;
   ejectionVelocity = 8;
   velocityVariance = 1.0;
   ejectionOffset   = 0.0;
   thetaMin         = 0;
   thetaMax         = 60;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "ThrowingAxeExplosionParticle";

   uiName = "Throwing Axe Hit";
};

datablock ExplosionData(ThrowingAxeExplosion)
{
   //explosionShape = "";
   lifeTimeMS = 500;

   particleEmitter = ThrowingAxeExplosionEmitter;
   particleDensity = 10;
   particleRadius = 0.2;

   faceViewer     = true;
   explosionScale = "1 1 1";

   shakeCamera = true;
   camShakeFreq = "20.0 22.0 20.0";
   camShakeAmp = "1.0 1.0 1.0";
   camShakeDuration = 0.5;
   camShakeRadius = 10.0;

   // Dynamic light
   lightStartRadius = 3;
   lightEndRadius = 0;
   lightStartColor = "00.0 0.2 0.6";
   lightEndColor = "0 0 0";
};

datablock DecalData(Axestab)
{
textureName = "add-ons/Weapon_throwing_Axe/CI_Axestab.png";
};
 
//Stab Projectile
AddDamageType("Axestab",   '<bitmap:add-ons/Weapon_Throwing_Axe/CI_Axestab> %1',    '%2 <bitmap:add-ons/Weapon_Throwing_Axe/CI_Axestab> %1',0.75,1);
datablock ProjectileData(ThrowingAxeStabProjectile)
{
shapeFile = "base/data/shapes/empty.dts";
directDamage        = 20;
directDamageType  = $DamageType::Axestab;
radiusDamageType  = $DamageType::Axestab;

brickExplosionRadius = 0;
brickExplosionImpact = true;
brickExplosionForce = 0;
brickExplosionMaxVolume = 1;
brickExplosionMaxVolumeFloating = 2;
explosion           = ThrowingAxeExplosion;

muzzleVelocity      = 50;
velInheritFactor    = 1;

armingDelay         = 0;
lifetime            = 75;
fadeDelay           = 70;
bounceElasticity    = 0;
bounceFriction      = 0;
isBallistic         = true;
gravityMod = 0.50;

hasLight    = false;
lightRadius = 3.0;
lightColor  = "1 0 0";

uiName = "Throwing Axe Stab";
};
 
datablock ParticleData(ThrowingAxeTrailParticle)
{
dragCoefficient         = 3.0;
windCoefficient         = 0.0;
gravityCoefficient      = 0.0;
inheritedVelFactor      = 0.0;
constantAcceleration    = 0.0;
lifetimeMS              = 600;
lifetimeVarianceMS      = 0;
spinSpeed               = 10.0;
spinRandomMin           = -50.0;
spinRandomMax           = 50.0;
useInvAlpha             = true;
animateTexture          = false;
//framesPerSec          = 1;

textureName             = "base/data/particles/ring";
//animTexName           = " ";

// Interpolation variables
colors[0]       = "0.75 0.75 0.75 0.3";
colors[1]       = "0.75 0.75 0.75 0.2";
colors[2]       = "1 1 1 0.0";
sizes[0]        = 0.15;
sizes[1]        = 0.35;
sizes[2]        = 0.05;
times[0]        = 0.0;
times[1]        = 0.1;
times[2]        = 1.0;
};
 
datablock ParticleEmitterData(ThrowingAxeTrailEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;

ejectionVelocity = 0; //0.25;
velocityVariance = 0; //0.10;

ejectionOffset = 0;

thetaMin         = 0.0;
thetaMax         = 90.0; 

particles = AxeTrailParticle;

useEmitterColors = true;
uiName = "Throwing Axe Trail";
};

datablock DecalData(Axethrow)
{
textureName = "add-ons/Weapon_throwing_Axe/CI_Axethrow.png";
};

//Thrown projectile
AddDamageType("Axethrow",   '<bitmap:add-ons/Weapon_Throwing_Axe/CI_Axethrow> %1',    '%2 <bitmap:add-ons/Weapon_Throwing_Axe/CI_Axethrow> %1',0.75,1);
datablock ProjectileData(ThrowingAxeThrowProjectile)
{
   projectileShapeName = "./ThrowingAxeProjectile.dts";
   directDamage        = 70;
   directDamageType  = $DamageType::Axethrow;
   radiusDamageType  = $DamageType::Axethrow;
   particleEmitter       = ThrowingAxeTrailEmitter;
   stickExplosion        = AxethrownExplosion;
   bloodExplosion        = AxethrownExplosion;
   explosion             =  ThrowingAxeExplosion;
   explodeOnPlayerImpact = true;
   explodeOnDeath        = true; 
 
   armingDelay         = 6000;
   lifetime            = 6000;
   fadeDelay           = 6000;
 
   isBallistic         = true;
   bounceAngle         = 180; //stick almost all the time
   minStickVelocity    = 10;
   bounceElasticity    = 0;
   bounceFriction      = 1; 
   gravityMod = 0.35;
   doColorShift = false;
   colorShiftColor = "0.471 0.471 0.471 1.000";
 
 
   hasLight    = false;
   lightRadius = 3.0;
   lightColor  = "0 0 1";
 
   muzzleVelocity      = 75;
   velInheritFactor    = 1;
   lightColor  = "0 0 0.5";
 
   uiName = "Throwing Axe Throw";
};
 
 
 
 
 
 
//////////
// item //
//////////
datablock ItemData(ThrowingAxeItem)
{
category = "Weapon";  // Mission editor category
className = "Weapon"; // For inventory system

// Basic Item Properties
shapeFile = "./ThrowingAxe.dts";
mass = 1;
density = 0.2;
elasticity = 0.2;
friction = 0.6;
emap = true;

//gui stuff
uiName = "Throwing Axe";
iconName = "./icon_ThrowingAxe";
doColorShift = false;
colorShiftColor = "0.471 0.471 0.471 1.000";

// Dynamic properties defined by the scripts
image = ThrowingAxeImage;
canDrop = true;
};

////////////////
//weapon image//
////////////////
datablock ShapeBaseImageData(ThrowingAxeImage)
{
// Basic Item properties
shapeFile = "./ThrowingAxe.dts";
emap = true;

// Specify mount point & offset for 3rd person, and eye offset
// for first person rendering.
mountPoint = 0;
offset = "0 0 0";

// When firing from a point offset from the eye, muzzle correction
// will adjust the muzzle vector to point to the eye LOS point.
// Since this weapon doesn't actually fire from the muzzle point,
// we need to turn this off. 
correctMuzzleVector = false;

eyeOffset = "0 0 0";

// Add the WeaponImage namespace as a parent, WeaponImage namespace
// provides some hooks into the inventory system.
className = "WeaponImage";

// Projectile && Ammo.
item = ThrowingAxeItem;
ammo = " ";
projectile = ThrowingAxeStabProjectile;
projectileType = Projectile;

//melee particles shoot from eye node for consistancy
melee = true;
doRetraction = false;
//raise your arm up or not
armReady = true;

//casing = " ";
doColorShift = false;
colorShiftColor = "0.471 0.471 0.471 1.000";
 
   // Images have a state system which controls how the animations
   // are run, which sounds are played, script callbacks, etc. This
   // state system is downloaded to the client so that clients can
   // predict state changes and animate accordingly.  The following
   // system supports basic ready->fire->reload transitions as
   // well as a no-ammo->dryfire idle state.
 
   // Initial start up state
stateName[0]                     = "Activate";
stateTimeoutValue[0]             = 0.5;
stateTransitionOnTimeout[0]      = "Ready";
stateSound[0]                    = AxeDrawSound;

stateName[1]                     = "Ready";
stateTransitionOnTriggerDown[1]  = "PreFire";
stateAllowImageChange[1]         = true;

stateName[2]                    = "PreFire";
stateScript[2]                  = "onPreFire";
stateAllowImageChange[2]        = false;
stateTimeoutValue[2]            = 0.1;
stateTransitionOnTimeout[2]     = "Fire";

stateName[3]                    = "Fire";
stateTransitionOnTimeout[3]     = "CheckFire";
stateTimeoutValue[3]            = 0.2;
stateFire[3]                    = true;
stateAllowImageChange[3]        = false;
stateSequence[3]                = "Fire";
stateScript[3]                  = "onFire";
stateWaitForTimeout[3]          = true;


stateName[4]                    = "CheckFire";
stateTransitionOnTriggerUp[4]   = "StopFire";
stateTransitionOnTriggerDown[4] = "Fire";

   
stateName[5]                    = "StopFire";
stateTransitionOnTimeout[5]     = "Ready";
stateTimeoutValue[5]            = 0.2;
stateAllowImageChange[5]        = false;
stateWaitForTimeout[5]          = true;
stateSequence[5]                = "StopFire";
stateScript[5]                  = "onStopFire";
};
 
function ThrowingAxeImage::onPreFire(%this, %obj, %slot)
{
%obj.playthread(2, armattack);
}
 
function ThrowingAxeImage::onStopFire(%this, %obj, %slot)
{     
%obj.playthread(2, root);
}
 
package ThrowingAxePackage
{
function ThrowingAxeStabProjectile::onCollision(%this, %obj, %col, %fade, %pos, %normal, %client)
{
%currSlot = %obj.currTool;
%client = %obj.sourceObject.client;
 
if(isObject(%col.client.minigame))
{
if(%obj.client.minigame $= %col.client.minigame)
{
if(%col.getClassName() $= "Player")
{
if($ThrowingAxeStabLimit==1)
{
%obj.sourceObject.tool[%currSlot] = 0;
%obj.sourceObject.weaponCount--;
messageClient(%obj.client,'MsgItemPickup',"",%currSlot,0);
serverCmdUnUseTool(%obj.client);
}
 
serverPlay3D(ThrowingAxeBrickSound, %pos);
return Parent::onCollision(%this, %obj, %col, %fade, %pos, %normal, %client);
}

}
 
if((%col.getType() && $TypeMasks::FxBrickObjectType))
{
serverPlay3D(ThrowingAxeBrickSound, %pos);
return Parent::onCollision(%this, %obj, %col, %fade, %pos, %normal, %client);
}
 
else
{
return Parent::onCollision(%this, %obj, %col, %fade, %pos, %normal, %client);
}     
}
 
function ThrowingAxeThrowProjectile::onCollision(%this, %obj, %col, %fade, %pos, %normal, %client)
{

if((%col.getType() & $TypeMasks::PlayerObjectType) && isObject(%col.client))
{
serverPlay3D(ThrowingAxeBrickSound, %pos);
return Parent::onCollision(%this, %obj, %col, %fade, %pos, %normal, %client);   
}
   
if((%col.getType() && $TypeMasks::FxBrickObjectType))
{
serverPlay3D(ThrowingAxeBrickSound, %pos);
return Parent::onCollision(%this, %obj, %col, %fade, %pos, %normal, %client); 
}
 
else
{
return Parent::onCollision(%this, %obj, %col, %fade, %pos, %normal, %client); 
}                     
}
 
 
function Armor::onTrigger(%this, %player, %slot, %val)
{
if(%player.getMountedImage(0) $= ThrowingAxeImage.getID() && %slot $= 4 && %val)
{
%currSlot = %player.currTool;
%player.tool[%currSlot] = 0;
%player.weaponCount--;
messageClient(%player.client,'MsgItemPickup','',%currSlot,0);
serverCmdUnUseTool(%player.client);
 
%projectile = ThrowingAxeThrowProjectile;
%vector = %player.getMuzzleVector(0);
%objectVelocity = %player.getVelocity();
%vector1 = VectorScale(%vector, %projectile.muzzleVelocity);
%vector2 = VectorScale(%objectVelocity, %projectile.velInheritFactor);
%velocity = VectorAdd(%vector1,%vector2);
%p = new Projectile()
{
dataBlock = %projectile;
initialVelocity = %velocity;
initialPosition = %player.getMuzzlePoint(0);
sourceObject = %player;
sourceSlot = 0;
client = %player.client;
};
serverPlay3D(ThrowingAxeSwingSound,%player.getPosition());
%player.playthread("3","Activate");
MissionCleanup.add(%p);
return %p;
}
Parent::onTrigger(%this, %player, %slot, %val);
}
};
activatePackage(ThrowingAxePackage);

Help would be much appreciated!



why are you here I you can't code...
Because this is "Coding Help" not "Coding Discussion."

You need to learn how to explain things a little better, JakeBlade. With that being said, this:

But whenever I throw it on onto something it keep playing the turning animation instead of holding still or facing the direction of the surface it's stuck into.

Is because you never tell it to stop rotating. I'll give you a hint, the code should be written in one of the functions that are inside of ThrowingAxePackage.

I'll make a video once I get home, I shall credit the ones who help me with this issue once I release my entire weaponspack.

I'm not sure you can really give the command to stop the animation to a projectile. What you can do is swap it out with a new projectile that doesn't animate immediately spawned in the wall.

I'm not sure you can really give the command to stop the animation to a projectile. What you can do is swap it out with a new projectile that doesn't animate immediately spawned in the wall.

That might be a good idea, could you help me with this?
I could send you the models that would be needed.

I'll give you a hint, the code should be written in one of the functions that are inside of ThrowingAxePackage.

Wait you can animate projectiles??!
I never knew this

Try using %projectile.playthread(SLOT_ID, "root");

Try using %projectile.playthread(SLOT_ID, "root");

Please be more precise, should I replace %player.playthread("3","Activate"); with %projectile.playthread(SLOT_ID, "root");   ?

Try using %projectile.playthread(SLOT_ID, "root");
No good. There is no projectile::playThread method.

Wait you can animate projectiles??!
I never knew this
Look at the default rocket launcher. Slow it down with the timescale if you need to.

That might be a good idea, could you help me with this?
I could send you the models that would be needed.
I'm not very good at coding for other people, because I only code when I feel like it, and that leads to long hiatuses on projects, which only makes me feel bad when it's for someone else.

Do what jetz said earlier, when the animating projectile collides with something.