diff --git a/Multiplayer/client.cpp b/Multiplayer/client.cpp index 168e8b59..3dee3ff1 100644 --- a/Multiplayer/client.cpp +++ b/Multiplayer/client.cpp @@ -3017,6 +3017,7 @@ void recieveGRENADE (RPCParameters *rpcParameters) pThrower->pThrowParams->uiActionData = gren->uiActionData; } + pThrower->usGrenadeItem = 0; HandleSoldierThrowItem( pThrower, gren->sTargetGridNo ); } } diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index ecf3a6a1..b6fe5cb5 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -2902,6 +2902,8 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile) this->usQuickItemId = 0; this->ubQuickItemSlot = 0; + this->usGrenadeItem = 0; + return TRUE; } diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp index aaf8c9ed..4f8a81e1 100644 --- a/Tactical/Interface Items.cpp +++ b/Tactical/Interface Items.cpp @@ -9557,6 +9557,7 @@ BOOLEAN HandleItemPointerClick( INT32 usMapPos ) CalculateLaunchItemParamsForThrow(gpItemPointerSoldier, sGridNo, gsInterfaceLevel, (INT16)(gsInterfaceLevel * 256 + sEndZ), gpItemPointer, 100, ubThrowActionCode, uiThrowActionData, gpItemPointer->usItem); // OK, goto throw animation + gpItemPointerSoldier->usGrenadeItem = 0; HandleSoldierThrowItem( gpItemPointerSoldier, usMapPos ); } } diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index f034c7f7..e8921556 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -1055,6 +1055,7 @@ SOLDIERTYPE& SOLDIERTYPE::operator=(const OLDSOLDIERTYPE_101& src) this->usQuickItemId = 0; this->ubQuickItemSlot = 0; + this->usGrenadeItem = 0; } return *this; } @@ -2980,6 +2981,85 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart // DO SOME CHECKS ON OUR NEW ANIMATION! ///////////////////////////////////////////////////////////////////// + if (usNewState == THROW_GRENADE_STANCE || usNewState == LOB_GRENADE_STANCE || usNewState == THROW_ITEM || usNewState == THROW_ITEM_CROUCHED) + { + UINT16 usItem = this->usGrenadeItem; + UINT8 ubVolume = Weapon[usItem].ubAttackVolume; + + // play grenade pin sound + if (usItem && Item[usItem].usItemClass == IC_GRENADE) + { + CHAR8 zFilename[512]; + sprintf(zFilename, ""); + + BOOLEAN fDelay = FALSE; + + if (usNewState == THROW_GRENADE_STANCE && gAnimControl[this->usAnimState].ubEndHeight == ANIM_STAND && this->ubBodyType < REGFEMALE) + { + fDelay = TRUE; + } + + // check if custom sound is set in Weapons.xml + if (Weapon[usItem].sSound) + { + PlayJA2Sample(Weapon[Item[usItem].ubClassIndex].sSound, RATE_11025, SoundVolume(MIDVOLUME, this->sGridNo), 1, SoundDir(this->sGridNo)); + } + else + { + if (Item[usItem].flare || + Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_SIGNAL_SMOKE || + Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_FLARE) + { + if (usItem == BREAK_LIGHT) + { + if (fDelay) + sprintf(zFilename, "sounds\\grenade\\grenade_breaklight_delay.ogg"); + else + sprintf(zFilename, "sounds\\grenade\\grenade_breaklight.ogg"); + } + else + { + if (fDelay) + sprintf(zFilename, "sounds\\grenade\\grenade_flare_delay.ogg"); + else + sprintf(zFilename, "sounds\\grenade\\grenade_flare.ogg"); + } + } + else if (Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL || + Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_STUN || + Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_FLASHBANG) + { + if (fDelay) + sprintf(zFilename, "sounds\\grenade\\grenade_pin_delay.ogg"); + else + sprintf(zFilename, "sounds\\grenade\\grenade_pin.ogg"); + } + else if (Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_SMOKE || + Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_TEARGAS || + Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_MUSTGAS || + Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_SMOKE) + { + if (fDelay) + sprintf(zFilename, "sounds\\grenade\\grenade_gas_delay.ogg"); + else + sprintf(zFilename, "sounds\\grenade\\grenade_gas.ogg"); + } + else if (Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_BURNABLEGAS) + { + if (fDelay) + sprintf(zFilename, "sounds\\grenade\\grenade_fire_delay.ogg"); + else + sprintf(zFilename, "sounds\\grenade\\grenade_fire.ogg"); + } + + if (strlen(zFilename) > 0 && FileExists(zFilename)) + { + PlayJA2SampleFromFile(zFilename, RATE_11025, SoundVolume(MIDVOLUME, this->sGridNo), 1, SoundDir(this->sGridNo)); + } + } + } + } + // If we are NOT loading a game, continue normally if ( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME) ) { diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 9ec27661..a356e094 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -1618,6 +1618,7 @@ public: UINT16 usQuickItemId; UINT8 ubQuickItemSlot; + UINT16 usGrenadeItem; public: // CREATION FUNCTIONS BOOLEAN DeleteSoldier( void ); diff --git a/Tactical/Soldier Create.cpp b/Tactical/Soldier Create.cpp index 0405caf8..bb499f33 100644 --- a/Tactical/Soldier Create.cpp +++ b/Tactical/Soldier Create.cpp @@ -2109,6 +2109,8 @@ void InitSoldierStruct( SOLDIERTYPE *pSoldier ) pSoldier->usQuickItemId = 0; pSoldier->ubQuickItemSlot = 0; + + pSoldier->usGrenadeItem = 0; } diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index 3fe93631..ef3c2ee2 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -3489,7 +3489,8 @@ BOOLEAN UseBlade( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo ) // anv: melee attack noise UINT16 usUBItem = pSoldier->GetUsedWeaponNumber( &pSoldier->inv[ pSoldier->ubAttackingHand ] ); UINT8 ubVolume = Weapon[ usUBItem ].ubAttackVolume; - MakeNoise( pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_UNKNOWN ); + // sevenfm: better make it NOISE_BULLET_IMPACT instead of NOISE_UNKNOWN so AI can associate it with enemy presence + MakeNoise(pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_BULLET_IMPACT); // possibly reduce monster smell if ( pSoldier->aiData.bMonsterSmell > 0 && Random( 5 ) == 0 ) @@ -4193,7 +4194,8 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea // anv: hth (inluding blunt weapons) attack noise UINT16 usUBItem = pSoldier->GetUsedWeaponNumber( &pSoldier->inv[ pSoldier->ubAttackingHand ] ); UINT8 ubVolume = Weapon[ usUBItem ].ubAttackVolume; - MakeNoise( pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_UNKNOWN ); + // sevenfm: better make it NOISE_BULLET_IMPACT instead of NOISE_UNKNOWN so AI can associate it with enemy presence + MakeNoise(pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_BULLET_IMPACT); // possibly reduce monster smell (gunpowder smell) if ( pSoldier->aiData.bMonsterSmell > 0 && Random( 5 ) == 0 ) @@ -4308,38 +4310,27 @@ BOOLEAN UseThrown( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo ) CalculateLaunchItemParamsForThrow( pSoldier, sTargetGridNo, pSoldier->bTargetLevel, (INT16)(pSoldier->bTargetLevel * 256 ), &(pSoldier->inv[ HANDPOS ] ), uiHitChance, THROW_ARM_ITEM, 0, pSoldier->inv[HANDPOS].usItem ); -#if 0//dnl ch72 180913 bad idea to charge APs before stance and turn really occurs, this was not here in v1.12 - //AXP 25.03.2007: Cleaned up throwing AP costs. Now only turning + stance change AP - // costs are deducted. Final throw cost is deducted on creating the grenade object - if ( (UINT8)GetDirectionFromGridNo( sTargetGridNo, pSoldier ) != pSoldier->ubDirection ) - sAPCost += (INT16)GetAPsToLook( pSoldier ); - sAPCost += GetAPsToChangeStance( pSoldier, ANIM_STAND ); + // anv: knife throw attack noise + UINT16 usItem = pSoldier->GetUsedWeaponNumber(&pSoldier->inv[pSoldier->ubAttackingHand]); + UINT8 ubVolume = Weapon[usItem].ubAttackVolume; + + pSoldier->usGrenadeItem = 0; + + // grenade pin sound + if (usItem && Item[usItem].usItemClass != IC_THROWING_KNIFE) + { + pSoldier->usGrenadeItem = usItem; + ubVolume = 10; + } + + if (ubVolume > 0) + { + // sevenfm: better make it NOISE_GRENADE_IMPACT instead of NOISE_UNKNOWN so AI can associate it with enemy presence + MakeNoise(pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_GRENADE_IMPACT); + } - HandleSoldierThrowItem( pSoldier, pSoldier->sTargetGridNo ); - DeductPoints( pSoldier, sAPCost, 0, AFTERSHOT_INTERRUPT ); - pSoldier->inv[ HANDPOS ].RemoveObjectsFromStack(1); -#else HandleSoldierThrowItem(pSoldier, pSoldier->sTargetGridNo); pSoldier->inv[HANDPOS].RemoveObjectsFromStack(1); -#endif - /* - // Madd: Next 2 lines added: Deduct points! - - sAPCost = CalcTotalAPsToAttack( pSoldier, sTargetGridNo, FALSE, pSoldier->aiData.bAimTime ); - // Kaiden: Deducting points too early, moving the line down - //DeductPoints( pSoldier, sAPCost, 0 ); - - // OK, goto throw animation - HandleSoldierThrowItem( pSoldier, pSoldier->sTargetGridNo ); - // Kaiden: Deducting points too early, moving the line down - DeductPoints( pSoldier, sAPCost, 0 ); - RemoveObjs( &(pSoldier->inv[ HANDPOS ] ), 1 ); - */ - - // anv: knife throw attack noise - UINT16 usUBItem = pSoldier->GetUsedWeaponNumber( &pSoldier->inv[ pSoldier->ubAttackingHand ] ); - UINT8 ubVolume = Weapon[ usUBItem ].ubAttackVolume; - MakeNoise( pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_UNKNOWN ); return( TRUE ); } @@ -4584,7 +4575,8 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo ) // anv: launcher attack noise UINT16 usUBItem = pSoldier->GetUsedWeaponNumber( &pSoldier->inv[ pSoldier->ubAttackingHand ] ); UINT8 ubVolume = Weapon[ usUBItem ].ubAttackVolume; - MakeNoise( pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_UNKNOWN ); + // sevenfm: better make it NOISE_GUNFIRE instead of NOISE_UNKNOWN so AI can associate it with enemy presence + MakeNoise(pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_GUNFIRE); return( TRUE ); }