Author Topic: Weapon reloading  (Read 3125 times)

I looked through the forums for some help on reloading, but I couldn't find an answer to my question. This is what I want my weapon to do:

-Starts with 60 rounds of ammo
-Each time it fires(animation already made, called 'Fire'), ammo is reduced by 1
-When there is no ammo left, the reloading animation(already made, called 'beltReplace') plays and the weapon will not fire for 3 seconds.
-After 3.25 seconds, the ammo is restored back to 60 and the weapon can fire.

Note that I did not incorporate the beltReplace animation inside the server.cs already. What would I add to the script to make all of this happen?
I think it deals with animation sequences, but I don't know exactly how. And does it have to check every time before the weapon is fired, if there is enough ammo?
« Last Edit: September 12, 2012, 05:18:55 PM by hammereditor² »

You must have the Support_AmmoGuns.cs inside the .zip with the weapon.

First, you have to add 2 lines to the item datablock.
Code: [Select]
   maxAmmo = 60;
   canReload = 1;
maxAmmo: Sets the maximum amount of ammo for the gun.
canReload: Can you reload? 1:Yes, 0:No.

Next you need to change up the weapon's states. (note this is for automatic weapons)
Code: [Select]
stateName[0]    = "Activate";
  stateTimeoutValue[0]   = 0.3;
  stateWaitForTimeout[0]   = true;
  stateTransitionOnTimeout[0]  = "LoadCheckA";
  stateSound[0]    = weaponSwitchSound;
 
  stateName[1]                     = "Ready";
  stateTransitionOnTriggerDown[1]  = "Fire";
  stateAllowImageChange[1]         = true;
  stateTimeoutValue[1]   = 0.01;
  stateTransitionOnNoAmmo[1]  = "Reload";

  stateName[2]                     = "Fire";
  stateTransitionOnTimeout[2]      = "FireLoadCheckA";
  stateTimeoutValue[2]             = 0.06;
  stateFire[2]                     = true;
  stateAllowImageChange[2]         = false;
  stateSequence[2]   = "Fire"; //Fire animation
  stateScript[2]    = "onFire";
  stateWaitForTimeout[2]   = true;
  stateEmitter[2]    = (Flash Emitter);
  stateEmitterTime[2]   = 0.06;
  stateEmitterNode[2]   = "muzzleNode";
  stateSound[2]    = (Fire Sound);
  stateEjectShell[2] = true;
 
        stateName[3]                                = "LoadCheckA";
        stateScript[3]                                = "onLoadCheck";
        stateTimeoutValue[3]                        = 0.01;
        stateTransitionOnTimeout[3]                = "LoadCheckB";
       
        stateName[4]                                = "LoadCheckB";
        stateTransitionOnAmmo[4]                = "Ready";
        stateTransitionOnNoAmmo[4]                = "Reload";

        stateName[5]                                = "Reload";
        stateTimeoutValue[5]                        = 1.4;
stateSequence[5]   = "beltReplace"; //Reload animation
        stateScript[5]                                = "onReloaded";
        stateTransitionOnTimeout[5]                = "Wait";
        stateWaitForTimeout[5]                        = true;
        stateSound[5]                                = (reload sound);

//this is kinda useless but should still be  in here       
        stateName[6]                                = "Wait";
        stateTimeoutValue[6]                        = 0.0;
        stateTransitionOnTimeout[6]                = "Ready";
       
        stateName[7]                                = "FireLoadCheckA";
        stateScript[7]                                = "onLoadCheck";
        stateTimeoutValue[7]                        = 0.03;
        stateTransitionOnTimeout[7]                = "FireLoadCheckB";
       
        stateName[8]                                = "FireLoadCheckB";
        stateTransitionOnAmmo[8]                = "Smoke";
        stateTransitionOnNoAmmo[8]                = "ReloadSmoke";
       
        stateName[9]                                 = "Smoke";
        stateEmitter[9]                        = (Smoke Emitter);
        stateEmitterTime[9]                        = 0.3;
        stateEmitterNode[9]                        = "muzzleNode";
        stateTimeoutValue[9]                        = 0.2;
        stateTransitionOnTimeout[9]                = "Ready";
        stateTransitionOnTriggerDown[9]        = "Fire";
       
        stateName[10]                                 = "ReloadSmoke";
        stateEmitter[10]                        = (Smoke Emitter);
        stateEmitterTime[10]                        = 0.3;
        stateEmitterNode[10]                        = "muzzleNode";
        stateTimeoutValue[10]                        = 0.2;
        stateTransitionOnTimeout[10]                = "Reload";
This should work, I haven't tested it tho. You will need to fill in for the emitters and sounds. don't include the "(" or ")".

Now you need to make some code that subtracts from your ammo.
Code: [Select]
function (Weapon)Image::onFire(%this,%obj,%slot)
{
        %obj.toolAmmo[%obj.currTool]--;
}

Next you need to make a piece of code that sets the amount of ammo after reloading.

Code: [Select]
function (Weapon)Image::onReloaded(%this,%obj,%slot)
{
        %obj.toolAmmo[%obj.currTool] = %this.item.maxAmmo;
        %obj.setImageAmmo(%slot,1);
}



Your weapon should now have reloading. If you have any questions feel free to ask.

Thanks for this. I'll use it soon.

You must have the Support_AmmoGuns.cs inside the .zip with the weapon.
Now this is why my weapon wasn't working for days!

I have only one last problem: The reloading animation.
When the ammo is 0, it goes back to 60. I did this on purpose so that the ammo would not go into teh negatives. But I want the animation to play when teh ammo is 0, then it goes to 60, and the weapon can fire.
Can somebody please look through the attached file and find out what I am doing wrong? I have Support_AmmoGuns. cs running witht he add-on and I am sure of it.
Also, the reloading animation is called drumReplace, when I exported it in Milkshape. I am sure of its name. Do I have to rename it to 'Reload'?


« Last Edit: September 18, 2012, 06:29:35 PM by hammereditor² »

Are you exporting the animations as .dsq? You are not supposed to do that.

I don't know what this is, but it shouldn't be there.
Code: [Select]
    if (%obj.toolAmmo[%obj.currTool] == -1)
    {
        %obj.toolAmmo[%obj.currTool] = 60;
    }
The script always does this already, and this might be causing the animation problem.
« Last Edit: September 18, 2012, 09:19:13 PM by Aware »

Are you exporting the animations as .dsq? You are not supposed to do that.

I don't know what this is, but it shouldn't be there.
Code: [Select]
    if (%obj.toolAmmo[%obj.currTool] == -1)
    {
        %obj.toolAmmo[%obj.currTool] = 60;
    }
The script always does this already, and this might be causing the animation problem.
There are no .dsq files.
Yes, I put that in there for testing purposes but I will remove it.

Is there any way you can just declare the sequence, and play it, without resorting to all this confusing Support_AmmoGuns.cs stuff?

Code: [Select]
        stateName[5]                                = "Reload";
        stateTimeoutValue[5]                        = 1.4;
stateSequence[5]   = "beltReplace"; //Reload animation
        stateScript[5]                                = "onReloaded";
        stateTransitionOnTimeout[5]                = "Wait";
        stateWaitForTimeout[5]                        = true;
        stateSound[5]                                = (reload sound);

The sequence you want to do is already called here with stateSequence[5]   = "beltReplace"; . The animation may be playing to fast so change the stateTimeoutValue to something greater.

Code: [Select]
        stateName[5]                                = "Reload";
        stateTimeoutValue[5]                        = 1.4;
stateSequence[5]   = "beltReplace"; //Reload animation
        stateScript[5]                                = "onReloaded";
        stateTransitionOnTimeout[5]                = "Wait";
        stateWaitForTimeout[5]                        = true;
        stateSound[5]                                = (reload sound);

The sequence you want to do is already called here with stateSequence[5]   = "beltReplace"; . The animation may be playing to fast so change the stateTimeoutValue to something greater.
The animation takes 3 seconds to play at 30 FPS, which is the framerate which I exported it at in Milkshape. The firing animation works perfectly, but the reloading one does not.
The weapon now starts out with 60 rounds, and when it is 0, no animation plays. The ammo keeps going on to the negatives?
I changed the timeout value from 1.4 to 4, which is once second longer than the animation, but it still doesn't work.
« Last Edit: September 19, 2012, 08:12:55 AM by hammereditor² »

If, for example,
Code: [Select]
%obj.playThread(4, drumReplace);doesn't play the reloading animation, then what does it do?

So I did this:
Code: [Select]
datablock ShapeBaseImageData(RPKImage : GunImage)
{
   shapeFile  = "./RPK.dts";
   projectile = RPKProjectile;

   doColorShift    = RPKItem.doColorShift;
   colorShiftColor = RPKItem.colorShiftColor;

   stateName[0]    = "Activate";
  stateTimeoutValue[0]   = 0.3;
  stateWaitForTimeout[0]   = true;
  stateTransitionOnTimeout[0]  = "LoadCheckA";
  stateSound[0]    = weaponSwitchSound;
 
  stateName[1]                     = "Ready";
  stateTransitionOnTriggerDown[1]  = "Fire";
  stateAllowImageChange[1]         = true;
  stateTimeoutValue[1]   = 0.01;
  stateTransitionOnNoAmmo[1]  = "Reload";

  stateName[2]                     = "Fire";
  stateTransitionOnTimeout[2]      = "FireLoadCheckA";
  stateTimeoutValue[2]             = 0.06;
  stateFire[2]                     = true;
  stateAllowImageChange[2]         = false;
  stateSequence[2]   = "Fire"; //Fire animation
  stateScript[2]    = "onFire";
  stateWaitForTimeout[2]   = true;
  stateEmitter[2]    = gunFlashEmitter;
  stateEmitterTime[2]   = 0.06;
  stateEmitterNode[2]   = "muzzleNode";
  stateSound[2]    = RPKFireSound;
  stateEjectShell[2] = true;
 
        stateName[3]                                = "LoadCheckA";
        stateScript[3]                                = "onLoadCheck";
        stateTimeoutValue[3]                        = 0.01;
        stateTransitionOnTimeout[3]                = "LoadCheckB";
       
        stateName[4]                                = "LoadCheckB";
        stateTransitionOnAmmo[4]                = "Ready";
        stateTransitionOnNoAmmo[4]                = "Reload";

        stateName[5]                                = "Reload";
        stateTimeoutValue[5]                        = 3.5;
    stateSequence[5]                             = "drumReplace"; //Reload animation
        stateScript[5]                                = "onReloaded";
        stateTransitionOnTimeout[5]                = "Wait";
        stateWaitForTimeout[5]                        = true;
        stateSound[5]                                = RPKReloadSound;

//this is kinda useless but should still be  in here       
        stateName[6]                                = "Wait";
        stateTimeoutValue[6]                        = 0.0;
        stateTransitionOnTimeout[6]                = "Ready";
       
        stateName[7]                                = "FireLoadCheckA";
        stateScript[7]                                = "onLoadCheck";
        stateTimeoutValue[7]                        = 0.03;
        stateTransitionOnTimeout[7]                = "FireLoadCheckB";
       
        stateName[8]                                = "FireLoadCheckB";
        stateTransitionOnAmmo[8]                = "Smoke";
        stateTransitionOnNoAmmo[8]                = "ReloadSmoke";
       
        stateName[9]                                 = "Smoke";
        stateEmitter[9]                        = gunSmokeEmitter;
        stateEmitterTime[9]                        = 0.3;
        stateEmitterNode[9]                        = "muzzleNode";
        stateTimeoutValue[9]                        = 0.2;
        stateTransitionOnTimeout[9]                = "Ready";
        stateTransitionOnTriggerDown[9]        = "Fire";
       
        stateName[10]                                 = "ReloadSmoke";
        stateEmitter[10]                        = gunSmokeEmitter;
        stateEmitterTime[10]                        = 0.3;
        stateEmitterNode[10]                        = "muzzleNode";
        stateTimeoutValue[10]                        = 0.2;
        stateTransitionOnTimeout[10]                = "Reload";

   
};

And it still doesn't work.
I'm a beginner to sequences, so what do I do to fix this?
Does stateSequence[number] tell which animation (as exported in Milkshape) to play when the state is activated?
If it does, then I have no idea what I'm screwing up.

Do animations have to be exported with a certain framerate? Maybe that is what's causing this problem.

And what does %obj.playThread([number], [idk this arg]); do, and what does its arguments do?
« Last Edit: September 19, 2012, 03:17:48 PM by hammereditor² »

try using this. also double check to make sure the reloading animation sequence is named right, I set it to drumReplace.

The problem was you didn't have the item = RPKItem; included in the script.


%obj.playThread makes the player model play an animation, not a weapon.

%obj.playThread(2, shiftLeft); would cause the player to do the player animation play like when you move a brick left.

%obj.playThread(2, spearReady); would make the player do the spear charge animation.

try using this. also double check to make sure the reloading animation sequence is named right, I set it to drumReplace.

The problem was you didn't have the item = RPKItem; included in the script.


%obj.playThread makes the player model play an animation, not a weapon.

%obj.playThread(2, shiftLeft); would cause the player to do the player animation play like when you move a brick left.

%obj.playThread(2, spearReady); would make the player do the spear charge animation.
Gosh, thank you so much for this!
And you even posted the corrected .cs file!
Looks like playThread only plays playertype animations, though.

Thank you so much, it works!!!Yes!!!!After days of frustration!!!!!