burst fire view kickback fix, accuracy kickback time proper, compiles

This commit is contained in:
Christopher Dawalt 2021-10-02 22:01:09 -04:00
parent 94aee91bf0
commit 497393eea6
4 changed files with 113 additions and 47 deletions

View File

@ -31,6 +31,7 @@ enum PLAYER_STATE{
#define ATTR_CHANGED_ARY(ary, i) (ary ##_net[i] != ary[i]) #define ATTR_CHANGED_ARY(ary, i) (ary ##_net[i] != ary[i])
#define PREDICTED_ARY_INT(ary, size) int ary[size]; int ary ##_net[size] #define PREDICTED_ARY_INT(ary, size) int ary[size]; int ary ##_net[size]
#define PREDICTED_ARY_FLOAT(ary, size) float ary[size]; float ary ##_net[size]
#define ROLL_BACK_ARY(ary, i) ary[i] = ary ##_net[i] #define ROLL_BACK_ARY(ary, i) ary[i] = ary ##_net[i]
#define SAVE_STATE_ARY(ary, i) ary ##_net[i] = ary[i] #define SAVE_STATE_ARY(ary, i) ary ##_net[i] = ary[i]
@ -339,10 +340,19 @@ class player:base_player
// Shared, but don't network! I think? // Shared, but don't network! I think?
int aryNextBurstShotTime_softLength; // apparently we do need to do this, at least network somewhat.
float aryNextBurstShotTime[5]; // Unsure how much, maybe the 'aryNextBurstShotTime' every single frame
int aryNextBurstShotTime_listenIndex; // is a bit overkill, should only need to be set at the start of a burst-fire.
// So no need for networking as the client/server should set those to the same
// values independently, but no idea of the prediction-rollbacks on clientside
// would complicate that, maybe still do the SAVE/ROLL_BACK stuff?
// aryNextBurstShotTime_listenIndex depends on the time and updates a lot,
// that one most likely has to stay networked and predicted.
PREDICTED_INT(aryNextBurstShotTime_softLength);
PREDICTED_ARY_FLOAT(aryNextBurstShotTime, 5);
PREDICTED_INT(aryNextBurstShotTime_listenIndex);
PREDICTED_ARY_INT(ary_ammoTotal, AMMO_ID::LAST_ID);
//shotgun stuff //shotgun stuff
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -384,21 +394,22 @@ class player:base_player
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// -1 = nothing special, holding grenade normally. Pressing primary/secondary // 0 = nothing special, holding grenade normally. Pressing primary/secondary
// starts the next phase. // starts the next phase.
// 0 = pull-pin animation, and stays this way until the animation finishes and // 1 = pull-pin animation, and stays this way until the animation finishes and
// neither input is held down. Then the next phase starts. // neither input is held down. Then the next phase starts.
// 1 = throw or throw-slide anim picked, based on primary or secondary being // 2 = throw or throw-slide anim picked, based on primary or secondary being
// pressed the most recently. Jumps to phase 2. // pressed the most recently. Jumps to phase 2.
// 2 = throw/slide anim playing. Grenade spawns very soon. After the anim // 3 = throw/slide anim playing. Grenade spawns very soon. After the anim
// finishes, decide whether to bring another grenade up (has ammo), other- // finishes, decide whether to bring another grenade up (has ammo), other-
// wise, discard the weapon and pick another. // wise, discard the weapon and pick another.
PREDICTED_INT(grenadeFireIndex); PREDICTED_INT(grenadeFireIndex);
// at what time do I throw the grenade after starting the throw/toss anim? // at what time do I throw the grenade after starting the throw/toss anim?
float grenadeSpawnTime; //TAGGG - should these be predicted too? Unsure. Possibly not.
float grenadeHeldDuration; PREDICTED_FLOAT(grenadeSpawnTime);
PREDICTED_FLOAT(grenadeHeldDuration);
// Same for this, but it has been for a while
PREDICTED_FLOAT(bGrenadeToss); //set to FALSE if it's a typical throw instead. PREDICTED_FLOAT(bGrenadeToss); //set to FALSE if it's a typical throw instead.
@ -472,7 +483,7 @@ class player:base_player
// to. Sounds like a lot of extra work for a single ammo counter per type of ammo which // to. Sounds like a lot of extra work for a single ammo counter per type of ammo which
// is all this is. // is all this is.
//int ary_ammoTotal[AMMO_ID::LAST_ID]; //int ary_ammoTotal[AMMO_ID::LAST_ID];
PREDICTED_ARY_INT(ary_ammoTotal,AMMO_ID::LAST_ID); PREDICTED_ARY_INT(ary_ammoTotal, AMMO_ID::LAST_ID);
// Provided for quick reference. How many slots does the current loadout take? // Provided for quick reference. How many slots does the current loadout take?
// There is a record of how much money has been spent, similar to config, but that isn't // There is a record of how much money has been spent, similar to config, but that isn't

View File

@ -236,7 +236,10 @@ player::ReceiveEntity(float new, float fl)
nextAkimboAttackPreference = readbyte(); nextAkimboAttackPreference = readbyte();
akimboDualFireToleranceTime = readfloat(); akimboDualFireToleranceTime = readfloat();
grenadeFireIndex = readbyte() - 1;
grenadeFireIndex = readbyte();
grenadeHeldDuration = readfloat();
grenadeSpawnTime = readfloat();
bGrenadeToss = readbyte(); bGrenadeToss = readbyte();
@ -276,6 +279,12 @@ player::ReceiveEntity(float new, float fl)
fKarateStamina = readfloat(); fKarateStamina = readfloat();
aryNextBurstShotTime_softLength = readbyte();
for(i = 0; i < aryNextBurstShotTime_softLength; i++){
aryNextBurstShotTime[i] = readfloat();
}
aryNextBurstShotTime_listenIndex = readbyte() - 1;
shotgunReloadIndex = readbyte(); shotgunReloadIndex = readbyte();
shotgunAddAmmoTime = readfloat(); shotgunAddAmmoTime = readfloat();
shotgunAddAmmoSoundTime = readfloat(); shotgunAddAmmoSoundTime = readfloat();
@ -381,6 +390,7 @@ so we can roll them back later.
void void
player::PredictPreFrame(void) player::PredictPreFrame(void)
{ {
int i;
//printfline("---PREDICT PRE FRAME"); //printfline("---PREDICT PRE FRAME");
@ -407,7 +417,10 @@ player::PredictPreFrame(void)
SAVE_STATE(iZoomLevel); SAVE_STATE(iZoomLevel);
SAVE_STATE(nextAkimboAttackPreference); SAVE_STATE(nextAkimboAttackPreference);
SAVE_STATE(akimboDualFireToleranceTime); SAVE_STATE(akimboDualFireToleranceTime);
SAVE_STATE(grenadeFireIndex); SAVE_STATE(grenadeFireIndex);
SAVE_STATE(grenadeHeldDuration);
SAVE_STATE(grenadeSpawnTime);
SAVE_STATE(bGrenadeToss); SAVE_STATE(bGrenadeToss);
@ -428,6 +441,12 @@ player::PredictPreFrame(void)
SAVE_STATE(fKarateStamina); SAVE_STATE(fKarateStamina);
SAVE_STATE(aryNextBurstShotTime_softLength);
for(i = 0; i < aryNextBurstShotTime_softLength; i++){
SAVE_STATE_ARY(ary_ammoTotal, i);
}
SAVE_STATE(aryNextBurstShotTime_listenIndex);
SAVE_STATE(shotgunReloadIndex); SAVE_STATE(shotgunReloadIndex);
@ -436,7 +455,7 @@ player::PredictPreFrame(void)
SAVE_STATE(ary_myWeapons_softMax); SAVE_STATE(ary_myWeapons_softMax);
for(int i = 0; i < ary_myWeapons_softMax; i++){ for(i = 0; i < ary_myWeapons_softMax; i++){
SAVE_STATE(ary_myWeapons[i].weaponID); SAVE_STATE(ary_myWeapons[i].weaponID);
SAVE_STATE(ary_myWeapons[i].weaponTypeID); SAVE_STATE(ary_myWeapons[i].weaponTypeID);
SAVE_STATE(ary_myWeapons[i].iBitsUpgrade); SAVE_STATE(ary_myWeapons[i].iBitsUpgrade);
@ -455,7 +474,7 @@ player::PredictPreFrame(void)
//UNNECESSARY. This array is of fixed length, so known at all times. //UNNECESSARY. This array is of fixed length, so known at all times.
//WriteByte(MSG_ENTITY, ary_ammoTotal_softMax); //WriteByte(MSG_ENTITY, ary_ammoTotal_softMax);
for(int i = 0; i < AMMO_ID::LAST_ID; i++){ for(i = 0; i < AMMO_ID::LAST_ID; i++){
// See serverside equivalent, too much info was lost from some pools being over 255 // See serverside equivalent, too much info was lost from some pools being over 255
// (well I guess that's all there is to it) // (well I guess that's all there is to it)
SAVE_STATE_ARY(ary_ammoTotal, i); SAVE_STATE_ARY(ary_ammoTotal, i);
@ -482,6 +501,7 @@ Where we roll back our values to the ones last sent/verified by the server.
void void
player::PredictPostFrame(void) player::PredictPostFrame(void)
{ {
int i;
//printfline("---PREDICT POST FRAME"); //printfline("---PREDICT POST FRAME");
sendevent("ViewOffsetR", "fff", vViewAngleOffsetTotalChange[0], vViewAngleOffsetTotalChange[1], vViewAngleOffsetTotalChange[2]); sendevent("ViewOffsetR", "fff", vViewAngleOffsetTotalChange[0], vViewAngleOffsetTotalChange[1], vViewAngleOffsetTotalChange[2]);
@ -513,7 +533,10 @@ player::PredictPostFrame(void)
ROLL_BACK(nextAkimboAttackPreference); ROLL_BACK(nextAkimboAttackPreference);
ROLL_BACK(akimboDualFireToleranceTime); ROLL_BACK(akimboDualFireToleranceTime);
ROLL_BACK(grenadeFireIndex); ROLL_BACK(grenadeFireIndex);
ROLL_BACK(grenadeHeldDuration);
ROLL_BACK(grenadeSpawnTime);
ROLL_BACK(bGrenadeToss); ROLL_BACK(bGrenadeToss);
//flKarateBlockCooldown //flKarateBlockCooldown
@ -532,15 +555,21 @@ player::PredictPostFrame(void)
ROLL_BACK(fUncrouchBlockDelay); ROLL_BACK(fUncrouchBlockDelay);
ROLL_BACK(fKarateStamina); ROLL_BACK(fKarateStamina);
ROLL_BACK(aryNextBurstShotTime_softLength);
for(i = 0; i < aryNextBurstShotTime_softLength; i++){
ROLL_BACK_ARY(ary_ammoTotal, i);
}
ROLL_BACK(aryNextBurstShotTime_listenIndex);
ROLL_BACK(shotgunReloadIndex); ROLL_BACK(shotgunReloadIndex);
ROLL_BACK(shotgunAddAmmoTime); ROLL_BACK(shotgunAddAmmoTime);
ROLL_BACK(shotgunAddAmmoSoundTime); ROLL_BACK(shotgunAddAmmoSoundTime);
ROLL_BACK(ary_myWeapons_softMax); ROLL_BACK(ary_myWeapons_softMax);
for(int i = 0; i < ary_myWeapons_softMax; i++){ for(i = 0; i < ary_myWeapons_softMax; i++){
ROLL_BACK(ary_myWeapons[i].weaponID); ROLL_BACK(ary_myWeapons[i].weaponID);
ROLL_BACK(ary_myWeapons[i].weaponTypeID); ROLL_BACK(ary_myWeapons[i].weaponTypeID);
ROLL_BACK(ary_myWeapons[i].iBitsUpgrade); ROLL_BACK(ary_myWeapons[i].iBitsUpgrade);
@ -559,7 +588,7 @@ player::PredictPostFrame(void)
// UNNECESSARY. This array is of fixed length, so known at all times. // UNNECESSARY. This array is of fixed length, so known at all times.
//WriteByte(MSG_ENTITY, ary_ammoTotal_softMax); //WriteByte(MSG_ENTITY, ary_ammoTotal_softMax);
for(int i = 0; i < AMMO_ID::LAST_ID; i++){ for(i = 0; i < AMMO_ID::LAST_ID; i++){
// See serverside equivalent, too much info was lost from some pools being over 255 // See serverside equivalent, too much info was lost from some pools being over 255
// (well I guess that's all there is to it) // (well I guess that's all there is to it)
ROLL_BACK_ARY(ary_ammoTotal, i); ROLL_BACK_ARY(ary_ammoTotal, i);
@ -659,7 +688,10 @@ player::EvaluateEntity(void)
SAVE_STATE(iZoomLevel); SAVE_STATE(iZoomLevel);
SAVE_STATE(nextAkimboAttackPreference); SAVE_STATE(nextAkimboAttackPreference);
SAVE_STATE(akimboDualFireToleranceTime); SAVE_STATE(akimboDualFireToleranceTime);
SAVE_STATE(grenadeFireIndex); SAVE_STATE(grenadeFireIndex);
SAVE_STATE(grenadeHeldDuration);
SAVE_STATE(grenadeSpawnTime);
SAVE_STATE(bGrenadeToss); SAVE_STATE(bGrenadeToss);
//flKarateBlockCooldown //flKarateBlockCooldown
@ -679,6 +711,13 @@ player::EvaluateEntity(void)
SAVE_STATE(fKarateStamina); SAVE_STATE(fKarateStamina);
SAVE_STATE(aryNextBurstShotTime_softLength);
for(i = 0; i < aryNextBurstShotTime_softLength; i++){
SAVE_STATE_ARY(ary_ammoTotal, i);
}
SAVE_STATE(aryNextBurstShotTime_listenIndex);
SAVE_STATE(shotgunReloadIndex); SAVE_STATE(shotgunReloadIndex);
SAVE_STATE(shotgunAddAmmoTime); SAVE_STATE(shotgunAddAmmoTime);
@ -789,7 +828,10 @@ player::SendEntity(entity ePEnt, float fChanged)
} }
WriteByte(MSG_ENTITY, nextAkimboAttackPreference); WriteByte(MSG_ENTITY, nextAkimboAttackPreference);
WriteFloat(MSG_ENTITY, akimboDualFireToleranceTime); WriteFloat(MSG_ENTITY, akimboDualFireToleranceTime);
WriteByte(MSG_ENTITY, grenadeFireIndex + 1);
WriteByte(MSG_ENTITY, grenadeFireIndex);
WriteFloat(MSG_ENTITY, grenadeHeldDuration);
WriteFloat(MSG_ENTITY, grenadeSpawnTime);
WriteByte(MSG_ENTITY, bGrenadeToss); WriteByte(MSG_ENTITY, bGrenadeToss);
WriteByte(MSG_ENTITY, armor ); WriteByte(MSG_ENTITY, armor );
@ -813,6 +855,12 @@ player::SendEntity(entity ePEnt, float fChanged)
WriteFloat(MSG_ENTITY, fKarateStamina); WriteFloat(MSG_ENTITY, fKarateStamina);
WriteByte(MSG_ENTITY, aryNextBurstShotTime_softLength);
for(i = 0; i < aryNextBurstShotTime_softLength; i++){
WriteFloat(MSG_ENTITY, aryNextBurstShotTime[i]);
}
WriteByte(MSG_ENTITY, aryNextBurstShotTime_listenIndex + 1);
WriteByte(MSG_ENTITY, shotgunReloadIndex ); WriteByte(MSG_ENTITY, shotgunReloadIndex );
WriteFloat(MSG_ENTITY, shotgunAddAmmoTime ); WriteFloat(MSG_ENTITY, shotgunAddAmmoTime );
@ -1013,7 +1061,7 @@ player::reset(BOOL resetInventory){
shotgunAddAmmoSoundTime = -1; shotgunAddAmmoSoundTime = -1;
//Grenade stuff //Grenade stuff
grenadeFireIndex = -1; grenadeFireIndex = 0;
grenadeHeldDuration = -1; grenadeHeldDuration = -1;
grenadeSpawnTime = -1; grenadeSpawnTime = -1;
bGrenadeToss = FALSE; bGrenadeToss = FALSE;
@ -1152,7 +1200,7 @@ player::updateTimers(void){
if(fAccuracyKickbackStartCooldown <= 0){ if(fAccuracyKickbackStartCooldown <= 0){
// begin reducing // begin reducing
//fAccuracyKickback -= frametime * 0.1; //fAccuracyKickback -= frametime * 0.1;
fAccuracyKickback = max(0, fAccuracyKickback - input_timelength); fAccuracyKickback = max(0, fAccuracyKickback - input_timelength * 0.1);
if(fAccuracyKickback <= 0){ if(fAccuracyKickback <= 0){
// stop! // stop!
@ -1211,9 +1259,10 @@ player::updateTimers(void){
// test? main one // test? main one
#ifndef CLIENT #ifndef CLIENT
GET_MY_VIEW_ANGLES = GET_MY_VIEW_ANGLES + finalChange; GET_MY_VIEW_ANGLES = GET_MY_VIEW_ANGLES + finalChange;
#else
// (this might be pointless?) // (this might be pointless?)
this.vViewAngleOffsetTotalChangeAlt += finalChange; this.vViewAngleOffsetTotalChangeAlt += finalChange;
#else
#endif #endif

View File

@ -307,6 +307,10 @@ weapon_base_onAttack(player pl, weapondata_basic_t* basePRef, weapondynamic_t ar
// For firing once the left or right has been picked for firing, does not matter which as this has // For firing once the left or right has been picked for firing, does not matter which as this has
// no effect on the weapon stats. Also applies kickback for firing once. // no effect on the weapon stats. Also applies kickback for firing once.
// TODO: restore random-ness of kickback, going left/right angle-wise and
// varrying the intensity, 65% to 100%, as shown commented out below.
// Need shared randoms for that to work, input_sequence is not relayed
// to the server on processing an input it seems.
void void
weapon_base_onAttack_individual(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount){ weapon_base_onAttack_individual(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount){
@ -391,12 +395,15 @@ weapon_base_onAttack_individual(player pl, weapondata_basic_t* basePRef, weapond
finalAng = ( 90 - (angleRange/2) + randoAngFactor*( angleRange ) ) * (M_PI/180); finalAng = ( 90 - (angleRange/2) + randoAngFactor*( angleRange ) ) * (M_PI/180);
pl.addViewAngleOffset(finalAng, finalAmount); pl.addViewAngleOffset(finalAng, finalAmount);
// TODO - be better shared later? // separate accuracy-kickback that spaces the crosshairs out and causes the weapon-spread
// Syncing view kickback would need the random-ness to be handled between server/client, // to be higher to discourage firing too much, even beyon the view-kickback that forces
// maybe seeded randoms? I forget. // the camera up. I don't think it has any random component, determined by weapon
// Properly predicted shotgun firing would be a good demonstration of that too, // stats only.
// so what happens instantly (client sees) and what actually happened (server sees; everyone // Also this is going off what makes sense with the as-is game stats, 0.1 is the
// else sees) line up. // highest accuracy kickback allowed and it slows down at a rate of 10% real-time.
// When reached, the 0.1 cap takes 1 second of not-firing to be completely reset.
// fAccuracyKickbackStartCooldown is still real-time, so 0.14 seconds, and the reduction
// starts happening after it runs out.
pl.fAccuracyKickbackStartCooldown = 0.14; pl.fAccuracyKickbackStartCooldown = 0.14;
pl.fAccuracyKickback += baseRef.firestats.fAccuracyKickback; pl.fAccuracyKickback += baseRef.firestats.fAccuracyKickback;
if(pl.fAccuracyKickback >= 0.1){ if(pl.fAccuracyKickback >= 0.1){

View File

@ -38,7 +38,7 @@ void weapon_m61grenade_onThink(player pl, weapondynamic_t arg_thisWeapon){
// If using to keep track of what animation to play (like HL having different throw anims for // If using to keep track of what animation to play (like HL having different throw anims for
// range), that should be networked so that this gives an accurate viewmodel. // range), that should be networked so that this gives an accurate viewmodel.
// ALTHOUGH, this applies to the time of picking a throw anim, not spawning the grenade. // ALTHOUGH, this applies to the time of picking a throw anim, not spawning the grenade.
if(pl.grenadeSpawnTime != -1 && pl.grenadeFireIndex > 0){ if(pl.grenadeSpawnTime != -1 && pl.grenadeFireIndex > 1){
pl.grenadeHeldDuration = min(pl.grenadeHeldDuration + input_timelength, 3); pl.grenadeHeldDuration = min(pl.grenadeHeldDuration + input_timelength, 3);
if(pl.w_attack_next <= pl.grenadeSpawnTime){ if(pl.w_attack_next <= pl.grenadeSpawnTime){
@ -71,44 +71,43 @@ void weapon_m61grenade_onThink(player pl, weapondynamic_t arg_thisWeapon){
printfline("!!! w_attack_next FINISHED WITH GRENFIREIN: %i", pl.grenadeFireIndex); printfline("!!! w_attack_next FINISHED WITH GRENFIREIN: %i", pl.grenadeFireIndex);
prevChoice = pl.grenadeFireIndex; prevChoice = pl.grenadeFireIndex;
} }
if(pl.grenadeFireIndex > 0){ if(pl.grenadeFireIndex > 1){
printfline("pl.grenadeFireIndex resolved: %i", pl.grenadeFireIndex); printfline("pl.grenadeFireIndex resolved: %i", pl.grenadeFireIndex);
} }
*/ */
if(pl.grenadeFireIndex == 0){ if(pl.grenadeFireIndex == 1){
// pin pull animation is finished, ready to throw when the input is not held down. // pin pull animation is finished, ready to throw when the input is not held down.
pl.grenadeHeldDuration = min(pl.grenadeHeldDuration + input_timelength, 3); pl.grenadeHeldDuration = min(pl.grenadeHeldDuration + input_timelength, 3);
if(!(input_buttons & INPUT_BUTTON0) && !(input_buttons & INPUT_BUTTON3)){ if(!(input_buttons & INPUT_BUTTON0) && !(input_buttons & INPUT_BUTTON3)){
// neither input held down? Move on // neither input held down? Move on
//printfline("!!! RELEASE"); //printfline("!!! RELEASE");
pl.grenadeFireIndex = 1; pl.grenadeFireIndex = 2;
} }
} }
// should this be joined by else or no? // should this be joined by else or no?
if(pl.grenadeFireIndex == 1){ if(pl.grenadeFireIndex == 2){
// Release detected, do the throw anim + spawn the grenade soon // Release detected, do the throw anim + spawn the grenade soon
if(!pl.bGrenadeToss){ if(!pl.bGrenadeToss){
TS_Weapons_ViewAnimation(weaponseq_m61grenade::throw, 11.0f/30.0f); TS_Weapons_ViewAnimation(weaponseq_m61grenade::throw, 11.0f/30.0f);
}else{ }else{
TS_Weapons_ViewAnimation(weaponseq_m61grenade::throw_slide, 11.0f/30.0f); TS_Weapons_ViewAnimation(weaponseq_m61grenade::throw_slide, 11.0f/30.0f);
} }
pl.grenadeFireIndex = 2; pl.grenadeFireIndex = 3;
// re-use shotgunAddAmmoTime instead, make the var more genericly named maybe??? // re-use shotgunAddAmmoTime instead, make the var more genericly named maybe???
//pl.grenadeSpawnTime = time + 4.0f/30.0f;
weapon_base_setWholeAttackDelay(pl, (11.0f/30.0f) * 1); weapon_base_setWholeAttackDelay(pl, (11.0f/30.0f) * 1);
pl.grenadeSpawnTime = pl.w_attack_next - 4.0f/30.0f; pl.grenadeSpawnTime = pl.w_attack_next - 4.0f/30.0f;
}else if(pl.grenadeFireIndex == 2){
}else if(pl.grenadeFireIndex == 3){
// Throw anim is over, decide whether to deploy another grenade or remove the // Throw anim is over, decide whether to deploy another grenade or remove the
// weapon if out of grenades. // weapon if out of grenades.
//printfline("Remove grenade? Count:%i", arg_thisWeapon.iCount); //printfline("Remove grenade? Count:%i", arg_thisWeapon.iCount);
if(arg_thisWeapon.iCount > 0){ if(arg_thisWeapon.iCount > 0){
TS_Weapons_ViewAnimation(weaponseq_m61grenade::draw, 31.0f / 40.0f ); TS_Weapons_ViewAnimation(weaponseq_m61grenade::draw, 31.0f / 40.0f );
printfline("I set grenadeFireIndex to -1, B!"); printfline("I set grenadeFireIndex to 0, B!");
pl.grenadeFireIndex = -1; pl.grenadeFireIndex = 0;
weapon_base_setWholeAttackDelay(pl, (31.0f/40.0f)); weapon_base_setWholeAttackDelay(pl, (31.0f/40.0f));
}else{ }else{
@ -122,8 +121,8 @@ void weapon_m61grenade_onThink(player pl, weapondynamic_t arg_thisWeapon){
//printfline("removeWeaponFromInventory POST cur weapo: %i", pl.inventoryEquippedIndex); //printfline("removeWeaponFromInventory POST cur weapo: %i", pl.inventoryEquippedIndex);
printfline("I set grenadeFireIndex to -1, C!"); printfline("I set grenadeFireIndex to 0, C!");
pl.grenadeFireIndex = -1; // paranoia? pl.grenadeFireIndex = 0; // paranoia?
return; return;
} }
@ -183,8 +182,8 @@ void weapon_grenade_onInputPress(player pl, weapondynamic_t arg_thisWeapon, int
// Initiating a throw is only do-able when the attack delay is up, and a fresh key press. // Initiating a throw is only do-able when the attack delay is up, and a fresh key press.
// Don't allow to interrupt the deploy anim. // Don't allow to interrupt the deploy anim.
if(pl.w_attack_next <= 0 && (INPUT_PRIMARY_TAP_CHECK(pl) || INPUT_SECONDARY_TAP_CHECK(pl))){ if(pl.w_attack_next <= 0 && (INPUT_PRIMARY_TAP_CHECK(pl) || INPUT_SECONDARY_TAP_CHECK(pl))){
if(pl.grenadeFireIndex == -1){ if(pl.grenadeFireIndex == 0){
pl.grenadeFireIndex = 0; pl.grenadeFireIndex = 1;
printfline("WHAT THE heckin heck IS THIS %.2f", time); printfline("WHAT THE heckin heck IS THIS %.2f", time);
pl.grenadeSpawnTime = -1; // not yet! pl.grenadeSpawnTime = -1; // not yet!
pl.grenadeHeldDuration = 0; pl.grenadeHeldDuration = 0;
@ -194,7 +193,7 @@ void weapon_grenade_onInputPress(player pl, weapondynamic_t arg_thisWeapon, int
} }
// Once already started, this can affect being a normal throw or slide-throw. // Once already started, this can affect being a normal throw or slide-throw.
if(pl.grenadeFireIndex == 0){ if(pl.grenadeFireIndex == 1){
if(attackTypeUsed & BITS_AKIMBOCHOICE_LEFT){ if(attackTypeUsed & BITS_AKIMBOCHOICE_LEFT){
pl.bGrenadeToss = FALSE; //throw, this was primary. pl.bGrenadeToss = FALSE; //throw, this was primary.
}else if(attackTypeUsed & BITS_AKIMBOCHOICE_RIGHT){ }else if(attackTypeUsed & BITS_AKIMBOCHOICE_RIGHT){
@ -221,12 +220,12 @@ void weapon_grenade_onInputRelease(player pl, weapondynamic_t arg_thisWeapon){
// (except above, checks a bit differently for spawning the grenade) // (except above, checks a bit differently for spawning the grenade)
return; return;
} }
if(pl.grenadeFireIndex == 0){ if(pl.grenadeFireIndex == 1){
// pin pull animation is finished, ready to throw when the input is not held down. // pin pull animation is finished, ready to throw when the input is not held down.
if(!(input_buttons & INPUT_BUTTON0) && !(input_buttons & INPUT_BUTTON3)){ if(!(input_buttons & INPUT_BUTTON0) && !(input_buttons & INPUT_BUTTON3)){
// primary not held down? Move on then // primary not held down? Move on then
//printfline("!!! RELEASE DETECT"); //printfline("!!! RELEASE DETECT");
pl.grenadeFireIndex = 1; pl.grenadeFireIndex = 2;
} }
} }
} }
@ -277,8 +276,8 @@ w_m61grenade_draw(void)
player pl = (player)self; player pl = (player)self;
weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex]; weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex];
printfline("I set grenadeFireIndex to -1, A!"); printfline("I set grenadeFireIndex to 0, A!");
pl.grenadeFireIndex = -1; pl.grenadeFireIndex = 0;
pl.grenadeSpawnTime = -1; pl.grenadeSpawnTime = -1;
pl.grenadeHeldDuration = 0; pl.grenadeHeldDuration = 0;