[Fixed]SingleShot Accurate, MultiShot Inaccurate
by CSMP · in Torque Game Engine · 09/11/2009 (4:16 am) · 14 replies
I've been thinking of how CoD incorporates its weapon system and I've noticed mostly that the first shot is deadly accurate however any following shot is not.
To further illustrate the demonstration if you tap the mouse for each shot you get a semi-auto type firing with accurate results, but if you hold down the mouse you get an automatic style recoil and unwanted spread with only the first shot being accurate.
I have the spread, but I'm trying to have the first shot almost perfectly accurate... heres some code in my weapon script I've been messing with with to no avail:
State-Script Code:
State Functions:
OK, now theres some strange results I'm getting here:
"onFireLooping" is never being called!?
"onFire" ALWAYS sees $AccuShot as being True????
I've even set $AccuShot = false via the console but it always calls the if(AccuShot=True) method... I've even gone further and removed the if(AccuShot=True) method and the if(AccuShot=False) method acts as if it were not even there!? (I've never even seen the "c4RPDImage::onFire AccuShot = False" echo, through all of my code variations!?)
Now I may be going about this all wrong, but since "onFireLooping" isnt being called and its the same way I called "onCeaseFire" and the onCeaseFire function is working, there must be something I dont know about the State-Machine System, as im not sure why the IF statement is not working in the "onFire" function either.
I've tried a variation of the above functions and variables and it seems like this should have been a "easy" mod but no deal, anyone else know what might be going on?
To further illustrate the demonstration if you tap the mouse for each shot you get a semi-auto type firing with accurate results, but if you hold down the mouse you get an automatic style recoil and unwanted spread with only the first shot being accurate.
I have the spread, but I'm trying to have the first shot almost perfectly accurate... heres some code in my weapon script I've been messing with with to no avail:
State-Script Code:
stateName[5] = "FireLoop"; stateScript[5] = "onFireLooping"; //ADDED:set $AccuShot = false here while firing.(NotWork) stateTransitionOnTriggerDown[5] = "Fire"; stateName[6] = "Fire"; stateSequence[6] = "Fire"; stateFire[6] = true; stateSequenceRandomFlash[6] = true; stateSpinThread[6] = FullSpeed; stateRecoil[6] = LightRecoil; stateAllowImageChange[6] = false; stateScript[6] = "onFire"; //Firing function called here.(IF does not work) stateEjectShell[6] = true; stateSound[6] = RPDFireSound; stateTimeoutValue[6] = 0.15; stateTransitionOnTimeout[6] = "FireLoop"; stateTransitionOnTriggerUp[6] = "Spindown"; stateTransitionOnNoAmmo[6] = "EmptySpindown"; stateEmitter[6] = "RPDFlashEmitter"; stateEmitterTime[6] = 0.10; stateName[7] = "Spindown"; stateSpinThread[7] = SpinDown; stateEmitter[7] = "RPDFireSmoke"; stateScript[7] = "onCeaseFire"; //ADDED:set $AccuShot = true after stopped firing.(works) stateEmitterTime[7] = 0.01; stateTimeoutValue[7] = 0.01; stateWaitForTimeout[7] = true; stateTransitionOnTimeout[7] = "Ready"; stateTransitionOnTriggerDown[7] = "Spinup";
State Functions:
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
// player stopped shooting, so give him another accurate shot
function RPDImage::onCeaseFire(%this, %obj, %slot)
{
$AccuShot = true;
echo("c4RPDImage::onCeaseFire Called!");
}
// player still shooting, so give him an inaccurate shot now
function RPDImage::onFireLooping(%this, %obj, %slot)
{
$AccuShot = false;
echo("c4RPDImage::onFireLooping Called!");
}
// check AccuShot and alter spread based on results...
function RPDImage::onFire(%this, %obj, %slot) //console: exec("common/scripts/server/weapons/RPD.cs");
{
// Decrease the weapons ammo on fire
%obj.decInventory(%this.ammo,1);
// Get the type of projectile we are gonna fire
%projectile = %this.projectile;
if ($AccuShot = false)
{
echo("c4RPDImage::onFire AccuShot = False");
if( VectorLen(%obj.getVelocity()) > 3 )
%SpeedSpread = (30.0 / 1000);
else if ( VectorLen(%obj.getVelocity()) > 0.9 )
%SpeedSpread = (15.0 / 1000);
else if ( VectorLen(%obj.getVelocity()) > 0.1 )
%SpeedSpread = (7.0 / 1000);
else
%SpeedSpread = (3.0 / 1000);
}
else
{
echo("c4RPDImage::onFire AccuShot = True");
if( VectorLen(%obj.getVelocity()) > 3 )
%SpeedSpread = (14.0 / 1000);
else if ( VectorLen(%obj.getVelocity()) > 0.9 )
%SpeedSpread = (7.0 / 1000);
else if ( VectorLen(%obj.getVelocity()) > 0.1 )
%SpeedSpread = (3.0 / 1000);
else
%SpeedSpread = (1.0 / 1000);
}
...
...
}OK, now theres some strange results I'm getting here:
"onFireLooping" is never being called!?
"onFire" ALWAYS sees $AccuShot as being True????
I've even set $AccuShot = false via the console but it always calls the if(AccuShot=True) method... I've even gone further and removed the if(AccuShot=True) method and the if(AccuShot=False) method acts as if it were not even there!? (I've never even seen the "c4RPDImage::onFire AccuShot = False" echo, through all of my code variations!?)
Now I may be going about this all wrong, but since "onFireLooping" isnt being called and its the same way I called "onCeaseFire" and the onCeaseFire function is working, there must be something I dont know about the State-Machine System, as im not sure why the IF statement is not working in the "onFire" function either.
I've tried a variation of the above functions and variables and it seems like this should have been a "easy" mod but no deal, anyone else know what might be going on?
#2
Thanks for the tip about the variable as well, I figured I'd have to replace it after it was working, but forgot about the extent of why it would need to be replaced.
I guess I'll try your %obj.property method and see if it works.
09/11/2009 (7:04 pm)
I was thinking about the lack of data in State5 as well, and actually tried the timeout theory but it didnt work.(good to know I was on point about that at least, lol)Thanks for the tip about the variable as well, I figured I'd have to replace it after it was working, but forgot about the extent of why it would need to be replaced.
I guess I'll try your %obj.property method and see if it works.
#3
09/12/2009 (4:59 pm)
Another option would be to inject slight random mouse movement after each shot fired.
#4
09/12/2009 (6:04 pm)
Like Daniel I would suggest swapping to %obj.property methods over using global variables. In your if statement you should use a comparison operand instead of the assignment operator, egif ($AccuShot == false)
#5
You'll first need to add this clientCMD to your client-side scripts, client.cs would be a good place
Everything else will be done in your weapons scripts. In the weaponImage datablock add this line:
09/12/2009 (6:16 pm)
Quote:Another option would be to inject slight random mouse movement after each shot fired.I was using this in the FPS Genre Kit (Torque 3D) for testing physical recoil (requiring the player to manually re-adjust aim after each shot), but it annoyed the crap out of me... and I've since moved it to the source, but here you might like this:
You'll first need to add this clientCMD to your client-side scripts, client.cs would be a good place
// ----------------------------------------------------------------------------
// Do some weapon recoil using camera/mouse adjustment.
// TODO: implement in C++ ...something
// like this resource: http://www.garagegames.com/community/resources/view/10241
// But keeping things basic here, scripted and network(able)ed
// Types of recoil are:
// - Light
// - Moderate
// - High - high is moderate, but with a more forceful push upwards.
// - Heavy
// - Extreme
// - Hit - to be used when player takes damage.
// ----------------------------------------------------------------------------
function clientCmdDoRecoil(%type)
{
switch$ (%type)
{
case "min":
$mvPitch += getrandom(-2, -3)/1000;
$mvYaw += getrandom(-2, 2)/1000;
case "Light":
$mvPitch += getrandom(-4, -6)/1000;
$mvYaw += getrandom(-4, 4)/1000;
case "Moderate":
$mvPitch += getrandom(-1, -2)/100;
$mvYaw += getrandom(-8,8)/1000;
case "High":
$mvPitch += getrandom(-3, -5)/100;
$mvYaw += getrandom(-8, 8)/1000;
case "Heavy":
$mvPitch += getrandom(-4, -6)/100;
$mvYaw += getrandom(-2, 2)/100;
case "Extreme":
$mvPitch += getrandom(-1, -2)/10;
$mvYaw += getrandom(-4, 4)/100;
case "Hit":
$mvPitch += getrandom(4, -4)/100;
$mvYaw += getrandom(-8, 8)/1000;
case "BumpRight":
$mvYaw += getrandom(1, 2)/33;
}
}Everything else will be done in your weapons scripts. In the weaponImage datablock add this line:
// scripted recoil system recoilType = "min";//"Moderate";And in your onFire() callback you'll need this:
// Do some recoil if this weapon has the required field: recoilType if (%this.recoilType !$= "") CommandToClient(%obj.client, 'DoRecoil', %this.recoilType);You'll want to add that somewhere after the vector calculations but before the return when the projectile is created.
#6
I have never been completely sure the differances of "=" and "==", and being used to VB I forgot about the "==", as with that simple change the IF statement now works as it should!
Looking at the functions, I have to admit I'm not sure how to assign a property to the %obj, I'm going to try and look around for a demonstration property value, but atm I have to check my moms Jeep's electrical system.
09/12/2009 (9:14 pm)
The weapon recoil system you've given is a very good effect, I think you were right about the manually adjusting getting annoying though.I have never been completely sure the differances of "=" and "==", and being used to VB I forgot about the "==", as with that simple change the IF statement now works as it should!
Looking at the functions, I have to admit I'm not sure how to assign a property to the %obj, I'm going to try and look around for a demonstration property value, but atm I have to check my moms Jeep's electrical system.
#7
to assign the property to %obj
09/12/2009 (10:15 pm)
you could replace$accuShot = true;with
%obj.accuShot = true;
to assign the property to %obj
#8
Everything works now, thanks for the help guys... this should all be common sense to me by now but I believe I wont be having those problems anymore. :)
And btw, the Jeeps electrical problem was a simple battery terminal Ground wire problem... lol, things are going good tonight!
09/12/2009 (10:48 pm)
LMAO, wow that was simple!Everything works now, thanks for the help guys... this should all be common sense to me by now but I believe I wont be having those problems anymore. :)
And btw, the Jeeps electrical problem was a simple battery terminal Ground wire problem... lol, things are going good tonight!
#9
I added the camera bounce c++ resource for a more realistic perception of the weapons firing as well.
09/13/2009 (7:12 pm)
@Michael, Ok, Well I checked out the c++ solution and I actually like your scripted functions better!(nice customization btw)I added the camera bounce c++ resource for a more realistic perception of the weapons firing as well.
#10
Code-side sounds more proper for recoil - in the aforementioned clientCmd script, wouldn't it be possible for a client to replace their DoRecoil with an empty function, and have recoilless weapons?
09/14/2009 (12:26 pm)
Michael - Arg! Didn't even notice the assignment '=' rather than comparison '==' :P.Code-side sounds more proper for recoil - in the aforementioned clientCmd script, wouldn't it be possible for a client to replace their DoRecoil with an empty function, and have recoilless weapons?
#11
Good point. Yeah, that's one hazard of doing things that way, but at the time that was really more of a test to show that it would work and had intended moving into code anyway.
09/14/2009 (1:52 pm)
@Daniel:Good point. Yeah, that's one hazard of doing things that way, but at the time that was really more of a test to show that it would work and had intended moving into code anyway.
#12
09/16/2009 (8:56 am)
Thanks for the feedback guys, noted on the insecurity of the scripted version!
#13
www.garagegames.com/community/resource/view/10243/3
09/16/2009 (11:41 am)
I remember that i use this c++ resource for this and works ok:www.garagegames.com/community/resource/view/10243/3
#14
09/16/2009 (10:01 pm)
@Javier, that resource only adds a camera bounce and no actual weapon recoil is involved, though it is closely related to the correct resource.
Torque Owner Daniel Buckmaster
T3D Steering Committee
Also, I wouldn't reccommend using a global variable. Think - firing scripts are called on the server, so $AccuFire is set on the server. If two players are using the weapon, they will use the same variable for projectile spread, which would be messed up. I'd suggest at least making accuFire a property of %obj, if you really want to use script-side variables.