From 74443ca8a9563e81c3ebbda36f311b50fd4e8a22 Mon Sep 17 00:00:00 2001 From: Sevenfm Date: Fri, 7 Feb 2020 10:13:16 +0000 Subject: [PATCH] New option TAUNT_VOICE (FALSE by default): if true, will play sound file instead of showing text. New option TAUNT_VOICE_SHOW_INFO (FALSE by default): if true, will show debug info when playing voice taunt. Restored JA2TESTVERSION for SpreadPatternLog.txt Allow taunts from militia when using voice taunts. Don't show noise text messages from militia (if on our side). Fixed incorrect OKLIFE check in CheckStatusNearbyFriendlies(). git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8743 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 3 + GameSettings.h | 2 + Tactical/Civ Quotes.cpp | 307 ++++++++++++++++++++++++++++++++++++++-- Tactical/Civ Quotes.h | 3 + Tactical/LOS.cpp | 4 +- Tactical/Overhead.cpp | 2 +- Tactical/Weapons.cpp | 18 ++- Tactical/opplist.cpp | 71 ++++++---- 8 files changed, 370 insertions(+), 40 deletions(-) diff --git a/GameSettings.cpp b/GameSettings.cpp index afc10eb5..0fe21fd9 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -3500,6 +3500,9 @@ void LoadTauntsSettings() gTauntsSettings.fTauntShowInLogIfHeard = iniReader.ReadBoolean("Taunts Settings","TAUNT_SHOW_IN_LOG_IF_HEARD", TRUE ); gTauntsSettings.fTauntAlwaysShowPopupBox = iniReader.ReadBoolean("Taunts Settings","TAUNT_ALWAYS_SHOW_POPUP_BOX", FALSE ); gTauntsSettings.fTauntAlwaysShowInLog = iniReader.ReadBoolean("Taunts Settings","TAUNT_ALWAYS_SHOW_IN_LOG", FALSE ); + gTauntsSettings.fTauntVoice = iniReader.ReadBoolean("Taunts Settings", "TAUNT_VOICE", FALSE); + gTauntsSettings.fTauntVoiceShowInfo = iniReader.ReadBoolean("Taunts Settings", "TAUNT_VOICE_SHOW_INFO", FALSE); + gTauntsSettings.sVolume = iniReader.ReadInteger("Taunts Settings","TAUNT_VOLUME",30, 0, 65535 ); gTauntsSettings.sModDelay = iniReader.ReadInteger("Taunts Settings","TAUNT_MOD_DELAY",100, -32767, 32767 ); gTauntsSettings.sMinDelay = iniReader.ReadInteger("Taunts Settings","TAUNT_MIN_DELAY",500, 0, 65535 ); diff --git a/GameSettings.h b/GameSettings.h index 3ebfdaa1..9dac15af 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -1560,6 +1560,8 @@ typedef struct BOOLEAN fTauntShowInLogIfHeard; BOOLEAN fTauntAlwaysShowPopupBox; BOOLEAN fTauntAlwaysShowInLog; + BOOLEAN fTauntVoice; + BOOLEAN fTauntVoiceShowInfo; UINT16 sVolume; INT16 sModDelay; UINT16 sMinDelay; diff --git a/Tactical/Civ Quotes.cpp b/Tactical/Civ Quotes.cpp index c3e1272b..649524aa 100644 --- a/Tactical/Civ Quotes.cpp +++ b/Tactical/Civ Quotes.cpp @@ -39,6 +39,7 @@ #include "Soldier Profile.h" #include "Campaign.h" #include "opplist.h" +#include "Sound Control.h" // sevenfm: voice taunts #define DIALOGUE_DEFAULT_WIDTH 200 #define EXTREAMLY_LOW_TOWN_LOYALTY 20 @@ -1151,7 +1152,6 @@ void PossiblyStartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, UINT32 ui // is enemy blocked from taunting at the moment? if( uiTauntFinishTimes[pCiv->ubID] > GetJA2Clock() ) { - return; } // check if generated person @@ -1160,10 +1160,18 @@ void PossiblyStartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, UINT32 ui return; } // only enemies and militia taunt - if ( pCiv->bTeam != ENEMY_TEAM && pCiv->bTeam != MILITIA_TEAM ) + // sevenfm: allow voice taunts for hostile civilians with group + if (pCiv->bTeam != ENEMY_TEAM && + pCiv->bTeam != MILITIA_TEAM && + !(pCiv->bTeam == CIV_TEAM && pCiv->ubCivilianGroup != NON_CIV_GROUP && !pCiv->aiData.bNeutral && gTauntsSettings.fTauntVoice)) { return; } + /*if ( pCiv->bTeam != ENEMY_TEAM && pCiv->bTeam != MILITIA_TEAM ) + { + return; + }*/ + // only visible enemies taunt (unless set otherwise) if ( ( pCiv->bVisible == -1 ) && ( gTauntsSettings.fTauntOnlyVisibleEnemies == TRUE ) ) { @@ -1346,12 +1354,15 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTar if ( pCiv->IsZombie() ) return; - // gCivQuoteData.bActive is checked in ShowTauntPopupBox() instead, taunt can be shown in log though! - // if we have a different quote on, return, this one is not important - //if ( gCivQuoteData.bActive ) - //{ - // return; - //} + // sevenfm: play audio taunt if possible + if (gTauntsSettings.fTauntVoice) + { + // try to play voice taunt, use noise if gTauntsSettings.fTauntMakeNoise is TRUE + PlayVoiceTaunt(pCiv, iTauntType, pTarget); + // block this enemy from taunting for a time being + uiTauntFinishTimes[pCiv->ubID] = GetJA2Clock() + min(gTauntsSettings.sMaxDelay, max(gTauntsSettings.sMinDelay, FindDelayForString(L"You're the disease and I'm the cure!") + gTauntsSettings.sModDelay)); + return; + } // anv: check all taunts, and remember those applicable for(UINT16 i=0; iubID] = GetJA2Clock() + min( gTauntsSettings.sMaxDelay , max( gTauntsSettings.sMinDelay, FindDelayForString( gzTauntQuote ) + gTauntsSettings.sModDelay ) ); if( gTauntsSettings.fTauntMakeNoise == TRUE ) - MakeNoise( pCiv->ubID, pCiv->sGridNo, pCiv->pathing.bLevel, pCiv->bOverTerrainType, gTauntsSettings.sVolume, NOISE_VOICE, gzTauntQuote ); + MakeNoise( pCiv->ubID, pCiv->sGridNo, pCiv->pathing.bLevel, pCiv->bOverTerrainType, (UINT8)gTauntsSettings.sVolume, NOISE_VOICE, gzTauntQuote ); else { if(gTauntsSettings.fTauntShowPopupBox == TRUE) @@ -2099,3 +2110,281 @@ BOOLEAN CivQuoteActive() { return gCivQuoteData.bActive; } + +STR VoiceTauntFileName[] = +{ + "FIRE_GUN", + "FIRE_LAUNCHER", + "ATTACK_BLADE", + "ATTACK_HTH", + + "THROW_KNIFE", + "THROW_GRENADE", + + "OUT_OF_AMMO", + "RELOAD", + + "STEAL", + + // AI routines + "CHARGE_BLADE", + "CHARGE_HTH", + "RUN_AWAY", + "SEEK_NOISE", + "ALERT", + "SUSPICIOUS", + "NOTICED_UNSEEN", + "SAY_HI", + "INFORM_ABOUT", + + // got_hit_xxx + "GOT_HIT", + "GOT_HIT_GUNFIRE", + "GOT_HIT_BLADE", + "GOT_HIT_HTH", + "GOT_HIT_FALLROOF", + "GOT_HIT_BLOODLOSS", + "GOT_HIT_EXPLOSION", + "GOT_HIT_GAS", + "GOT_HIT_TENTACLES", + "GOT_HIT_STRUCTURE_EXPLOSION", + "GOT_HIT_OBJECT", + "GOT_HIT_THROWING_KNIFE", + + "GOT_DEAFENED", + "GOT_BLINDED", + + "GOT_ROBBED", + + // got_missed_xxx + "GOT_MISSED", + "GOT_MISSED_GUNFIRE", + "GOT_MISSED_BLADE", + "GOT_MISSED_HTH", + "GOT_MISSED_THROWING_KNIFE", + + // hit_xxx + "HIT", + "HIT_GUNFIRE", + "HIT_BLADE", + "HIT_HTH", + "HIT_EXPLOSION", + "HIT_THROWING_KNIFE", + + // kill_xxx + "KILL", + "KILL_GUNFIRE", + "KILL_BLADE", + "KILL_HTH", + "KILL_THROWING_KNIFE", + "HEAD_POP", + + // miss_xxx + "MISS", + "MISS_GUNFIRE", + "TAUNT_MISS_BLADE", + "MISS_HTH", + "MISS_THROWING_KNIFE", + + // ripostes to merc quotes + "RIPOSTE" +}; + +// sevenfm: voice taunts +BOOLEAN PlayVoiceTaunt(SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTarget) +{ + CHAR8 filename[1024]; + CHAR8 filenameExtra[1024]; + CHAR16 noise[1024]; + CHAR8 buf[1024]; + INT32 iRandomTaunt = 0; + UINT8 ubExtraTaunts = 0; + + CHECKF(pCiv); + + if (!gTauntsSettings.fTauntVoice) + { + return FALSE; + } + + // show some information about taunts + if (gTauntsSettings.fTauntVoiceShowInfo) + ScreenMsg(FONT_MCOLOR_LTGREEN, MSG_INTERFACE, L"Soldier [%d] TauntType %d", pCiv->ubID, iTauntType); + + // cannot taunt when dead or collapsed + if (pCiv->stats.bLife < OKLIFE || pCiv->bCollapsed || pCiv->bBreathCollapsed) + { + if (gTauntsSettings.fTauntVoiceShowInfo) + ScreenMsg(FONT_MCOLOR_LTGREEN, MSG_INTERFACE, L"Bad soldier state (dying or collapsed)"); + + return FALSE; + } + + if (iTauntType < TAUNT_FIRE_GUN || iTauntType > TAUNT_RIPOSTE) + { + if (gTauntsSettings.fTauntVoiceShowInfo) + ScreenMsg(FONT_MCOLOR_LTGREEN, MSG_INTERFACE, L"Bad taunt"); + + return FALSE; + } + + strcpy(filename, "VoiceTaunts"); + + // prepare team + if (pCiv->bTeam == ENEMY_TEAM) + { + strcat(filename, "\\Army\\"); + } + else if (pCiv->bTeam == MILITIA_TEAM) + { + strcat(filename, "\\Militia\\"); + } + else if (pCiv->bTeam == CIV_TEAM && pCiv->ubCivilianGroup != NON_CIV_GROUP) + { + sprintf(buf, "\\Civgroup%02d\\", pCiv->ubCivilianGroup); + strcat(filename, buf); + } + else + { + if (gTauntsSettings.fTauntVoiceShowInfo) + ScreenMsg(FONT_MCOLOR_LTGREEN, MSG_INTERFACE, L"Bad soldier team"); + + return FALSE; + } + + // prepare gender + if (pCiv->ubBodyType <= STOCKYMALE) + { + strcat(filename, "Male\\"); + } + else if (pCiv->ubBodyType == REGFEMALE) + { + strcat(filename, "Female\\"); + } + else + { + if (gTauntsSettings.fTauntVoiceShowInfo) + ScreenMsg(FONT_MCOLOR_LTGREEN, MSG_INTERFACE, L"Incorrect bodytype"); + + return FALSE; + } + + // count possible voices + UINT8 ubVoiceCount; + for (ubVoiceCount = 1; ubVoiceCount <= 100; ubVoiceCount++) + { + sprintf(buf, "%s%02d", filename, ubVoiceCount); + strcat(buf, "\\alert.ogg"); + + // check that folder exists + if (!FileExists(buf)) + { + if (gTauntsSettings.fTauntVoiceShowInfo) + { + mbstowcs(noise, buf, strlen(buf) + 1); + ScreenMsg(FONT_GREEN, MSG_INTERFACE, noise); + } + + break; + } + } + // find last good number + ubVoiceCount--; + + if (ubVoiceCount < 1) + { + if (gTauntsSettings.fTauntVoiceShowInfo) + ScreenMsg(FONT_MCOLOR_LTGREEN, MSG_INTERFACE, L"Could not find any voice folder"); + + return FALSE; + } + + if (gTauntsSettings.fTauntVoiceShowInfo) + ScreenMsg(FONT_MCOLOR_LTGREEN, MSG_INTERFACE, L"found %d voices", ubVoiceCount); + + // prepare voice folder name + sprintf(buf, "%02d", 1 + pCiv->ubID % ubVoiceCount); + strcat(filename, buf); + strcat(filename, "\\"); + + // prepare base taunt filename + strcat(filename, VoiceTauntFileName[iTauntType]); + + // count possible extra filenames + ubExtraTaunts = 0; + for (UINT8 ubCheck = 1; ubCheck <= 10; ubCheck++) + { + // check extra taunt file + strcpy(filenameExtra, filename); + sprintf(buf, " %d", ubExtraTaunts); + strcat(filenameExtra, buf); + strcat(filenameExtra, ".ogg"); + if (!FileExists(filenameExtra)) + { + break; + } + ubExtraTaunts = ubCheck; + } + + // possibly use extra taunt + iRandomTaunt = Random(ubExtraTaunts + 1); + if (iRandomTaunt > 0) + { + sprintf(buf, " %d", iRandomTaunt); + strcat(filename, buf); + } + + strcat(filename, ".ogg"); + + // log taunt file names + if (gTauntsSettings.fTauntVoiceShowInfo) + { + FILE *OutFile; + if ((OutFile = fopen("VoiceTauntLog.txt", "a+t")) != NULL) + { + fprintf(OutFile, "Soldier [%d] TauntType %d %s\n", + pCiv->ubID, + iTauntType, + filename); + fclose(OutFile); + } + + // show some information about taunts + mbstowcs(noise, filename, strlen(filename) + 1); + ScreenMsg(FONT_GREEN, MSG_INTERFACE, noise); + } + + // check that taunt file exists + if (!FileExists(filename)) + { + if (gTauntsSettings.fTauntVoiceShowInfo) + { + mbstowcs(noise, filename, strlen(filename) + 1); + ScreenMsg(FONT_GREEN, MSG_INTERFACE, noise); + ScreenMsg(FONT_MCOLOR_LTRED, MSG_INTERFACE, L"Taunt: no file %s", noise); + } + + return FALSE; + } + + if (gTauntsSettings.fTauntMakeNoise == TRUE) + { + // convert char to char16 + mbstowcs(noise, filename, strlen(filename) + 1); + // use filename as taunt text, play sound later + MakeNoise(pCiv->ubID, pCiv->sGridNo, pCiv->pathing.bLevel, pCiv->bOverTerrainType, (UINT8)gTauntsSettings.sVolume, NOISE_VOICE, noise); + } + else + { + // play voice taunt + if (PlayJA2SampleFromFile(filename, RATE_11025, SoundVolume(HIGHVOLUME, pCiv->sGridNo), 1, SoundDir(pCiv->sGridNo)) == SOUND_ERROR) + { + if (gTauntsSettings.fTauntVoiceShowInfo) + ScreenMsg(FONT_MCOLOR_LTRED, MSG_INTERFACE, L"Failed to play taunt"); + + return FALSE; + } + } + + return TRUE; +} \ No newline at end of file diff --git a/Tactical/Civ Quotes.h b/Tactical/Civ Quotes.h index d950b9be..0c466651 100644 --- a/Tactical/Civ Quotes.h +++ b/Tactical/Civ Quotes.h @@ -158,6 +158,9 @@ void PossiblyStartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, UINT32 ui void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTarget = NULL ); //enemy taunts - SANDRO // anv: added pTarget argument void ShowTauntPopupBox( SOLDIERTYPE *pCiv, STR16 gzTauntQuote ); +// sevenfm: voice taunts +BOOLEAN PlayVoiceTaunt(SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTarget); + void InitCivQuoteSystem( ); void StartCivQuote( SOLDIERTYPE *pCiv ); diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index 42c88ded..003b3d89 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -4949,7 +4949,7 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, ddVerticAngle += ddAdjustedVerticAngle; //Logging for debugging - //#ifdef JA2TESTVERSION + #ifdef JA2TESTVERSION if(!fFake) { FILE *OutFile; @@ -4968,7 +4968,7 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, fclose(OutFile); } } - //#endif + #endif } //Just calculate the increments the bullet will use, not any of the to-hit adjustments, because we already did. diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 15f6a61d..c834a025 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -10342,7 +10342,7 @@ INT8 CheckStatusNearbyFriendlies( SOLDIERTYPE *pSoldier ) } } // Incapacitated or heavily suppressed friends will not be good for our tolerance! - else if ( (pLeader->aiData.bShock > pSoldier->aiData.bShock || pLeader->stats.bLife <= OKLIFE) ) + else if ( (pLeader->aiData.bShock > pSoldier->aiData.bShock || pLeader->stats.bLife < OKLIFE) ) { usEffectiveRangeToLeader = PythSpacesAway( pSoldier->sGridNo, pLeader->sGridNo ); // If they are no more than 5 tiles away, diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index ef3c2ee2..4ef71697 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -5320,14 +5320,28 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT16 bWeaponStatus, UIN { if( Item[ pBullet->pFirer->usAttackingWeapon ].usItemClass & IC_GUN ) { - if( MercPtrs[ pBullet->pFirer->ubOppNum ]->aiData.bOppList[ pBullet->pFirer->ubID ] == SEEN_CURRENTLY ) - PossiblyStartEnemyTaunt( MercPtrs[ pBullet->pFirer->ubOppNum ], TAUNT_GOT_MISSED_GUNFIRE, pBullet->pFirer->ubID ); + if (gTauntsSettings.fTauntVoice) + { + // say taunt only to inform others + if (gbPublicOpplist[MercPtrs[pBullet->pFirer->ubOppNum]->bTeam][pBullet->pFirer->ubID] != SEEN_CURRENTLY && + gbPublicOpplist[MercPtrs[pBullet->pFirer->ubOppNum]->bTeam][pBullet->pFirer->ubID] != SEEN_THIS_TURN && + gTacticalStatus.Team[MercPtrs[pBullet->pFirer->ubOppNum]->bTeam].bMenInSector > 1) + { + PossiblyStartEnemyTaunt(MercPtrs[pBullet->pFirer->ubOppNum], TAUNT_GOT_MISSED_GUNFIRE, pBullet->pFirer->ubID); + } + } + else if (MercPtrs[pBullet->pFirer->ubOppNum]->aiData.bOppList[pBullet->pFirer->ubID] == SEEN_CURRENTLY) + { + PossiblyStartEnemyTaunt(MercPtrs[pBullet->pFirer->ubOppNum], TAUNT_GOT_MISSED_GUNFIRE, pBullet->pFirer->ubID); + } + PossiblyStartEnemyTaunt( pBullet->pFirer, TAUNT_MISS_GUNFIRE, pBullet->pFirer->ubOppNum ); } else if( Item[ pBullet->pFirer->usAttackingWeapon ].usItemClass & IC_THROWING_KNIFE ) { if( MercPtrs[ pBullet->pFirer->ubOppNum ]->aiData.bOppList[ pBullet->pFirer->ubID ] == SEEN_CURRENTLY ) PossiblyStartEnemyTaunt( MercPtrs[ pBullet->pFirer->ubOppNum ], TAUNT_GOT_MISSED_THROWING_KNIFE, pBullet->pFirer->ubID ); + PossiblyStartEnemyTaunt( pBullet->pFirer, TAUNT_MISS_THROWING_KNIFE, pBullet->pFirer->ubOppNum ); } } diff --git a/Tactical/opplist.cpp b/Tactical/opplist.cpp index a7436893..0568357b 100644 --- a/Tactical/opplist.cpp +++ b/Tactical/opplist.cpp @@ -6007,7 +6007,9 @@ void ProcessNoise(UINT8 ubNoiseMaker, INT32 sGridNo, INT8 bLevel, UINT8 ubTerrTy break; case MILITIA_TEAM: // if the noisemaker is militia and still on our side, ignore noise if we're listening - if ( pSoldier->bTeam == OUR_TEAM && MercPtrs[ ubNoiseMaker ]->bSide == 0 ) + // sevenfm: allow taunts from militia + if (pSoldier->bTeam == OUR_TEAM && MercPtrs[ubNoiseMaker]->bSide == 0 && (ubNoiseType != NOISE_VOICE || !gTauntsSettings.fTauntVoice)) + //if ( pSoldier->bTeam == OUR_TEAM && MercPtrs[ ubNoiseMaker ]->bSide == 0 ) { continue; } @@ -6740,43 +6742,66 @@ void TellPlayerAboutNoise( SOLDIERTYPE *pSoldier, UINT8 ubNoiseMaker, INT32 sGri } // anv: special treatment of NOISE_VOICE - also display taunt message - if( ubNoiseType == NOISE_VOICE ) + if (ubNoiseType == NOISE_VOICE && ubNoiseMaker != NOBODY) { // information about direction etc. only displayed if we don't see noise maker - if( gbPublicOpplist[gbPlayerNum][ubNoiseMaker] != SEEN_CURRENTLY && pSoldier->aiData.bOppList[ubNoiseMaker] != SEEN_CURRENTLY ) + // sevenfm: don't show noise messages from militia (if on our side) + if (gbPublicOpplist[gbPlayerNum][ubNoiseMaker] != SEEN_CURRENTLY && pSoldier->aiData.bOppList[ubNoiseMaker] != SEEN_CURRENTLY && + !(MercPtrs[ubNoiseMaker]->bTeam == MILITIA_TEAM && MercPtrs[ubNoiseMaker]->bSide == 0)) + //if( gbPublicOpplist[gbPlayerNum][ubNoiseMaker] != SEEN_CURRENTLY && pSoldier->aiData.bOppList[ubNoiseMaker] != SEEN_CURRENTLY ) { - if( bLevel == pSoldier->pathing.bLevel && ubNoiseType == NOISE_VOICE ) + if (bLevel == pSoldier->pathing.bLevel) { - ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, pNewNoiseStr[ubNoiseType], pSoldier->name, pNoiseVolStr[ubVolumeIndex], pDirectionStr[ubNoiseDir] ); + ScreenMsg(MSG_FONT_YELLOW, MSG_INTERFACE, pNewNoiseStr[ubNoiseType], pSoldier->name, pNoiseVolStr[ubVolumeIndex], pDirectionStr[ubNoiseDir]); } - else if ( bLevel > pSoldier->pathing.bLevel ) + else if (bLevel > pSoldier->pathing.bLevel) { // from above! - ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, pNewNoiseStr[ubNoiseType], pSoldier->name, pNoiseVolStr[ubVolumeIndex], gzLateLocalizedString[6] ); + ScreenMsg(MSG_FONT_YELLOW, MSG_INTERFACE, pNewNoiseStr[ubNoiseType], pSoldier->name, pNoiseVolStr[ubVolumeIndex], gzLateLocalizedString[6]); } else { // from below! - ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, pNewNoiseStr[ubNoiseType], pSoldier->name, pNoiseVolStr[ubVolumeIndex], gzLateLocalizedString[7] ); + ScreenMsg(MSG_FONT_YELLOW, MSG_INTERFACE, pNewNoiseStr[ubNoiseType], pSoldier->name, pNoiseVolStr[ubVolumeIndex], gzLateLocalizedString[7]); } } + if( ubVolumeIndex > 0 ) // definite noise - we're able to recognize words { - // do we know who said that? - if( gbPublicOpplist[gbPlayerNum][ubNoiseMaker] == SEEN_CURRENTLY || pSoldier->aiData.bOppList[ubNoiseMaker] == SEEN_CURRENTLY ) + CHAR8 filename[1024]; + + if (gTauntsSettings.fTauntVoiceShowInfo) + ScreenMsg(FONT_ORANGE, MSG_INTERFACE, zNoiseMessage); + + // convert wchar to char + wcstombs(filename, zNoiseMessage, wcslen(zNoiseMessage) + 1); + // sevenfm: play voice taunt (check that noise string is a filename) + if (gTauntsSettings.fTauntVoice && + strlen(filename) != 0 && + strstr(filename, "VoiceTaunts\\") != NULL) { - if( gTauntsSettings.fTauntShowPopupBox == TRUE ) - ShowTauntPopupBox( MercPtrs[ubNoiseMaker], zNoiseMessage ); - if( gTauntsSettings.fTauntShowInLog == TRUE ) - ScreenMsg( FONT_GRAY2, MSG_INTERFACE, L"%s: %s", MercPtrs[ubNoiseMaker]->GetName(), zNoiseMessage ); + UINT32 playResult = PlayJA2SampleFromFile(filename, RATE_11025, SoundVolume(HIGHVOLUME, pSoldier->sGridNo), 1, SoundDir(pSoldier->sGridNo)); + if (playResult == SOUND_ERROR && gTauntsSettings.fTauntVoiceShowInfo) + ScreenMsg(FONT_MCOLOR_LTRED, MSG_INTERFACE, L"Noise: Failed to play taunt"); } else { - if( gTauntsSettings.fTauntShowPopupBox == TRUE && gTauntsSettings.fTauntShowPopupBoxIfHeard == TRUE ) - ShowTauntPopupBox( MercPtrs[ubNoiseMaker], zNoiseMessage ); - if( gTauntsSettings.fTauntShowInLog == TRUE && gTauntsSettings.fTauntShowInLogIfHeard == TRUE ) - ScreenMsg( FONT_GRAY2, MSG_INTERFACE, L"%s: %s", pTauntUnknownVoice[0], zNoiseMessage ); - } + // do we know who said that? + if (gbPublicOpplist[gbPlayerNum][ubNoiseMaker] == SEEN_CURRENTLY || pSoldier->aiData.bOppList[ubNoiseMaker] == SEEN_CURRENTLY) + { + if (gTauntsSettings.fTauntShowPopupBox == TRUE) + ShowTauntPopupBox(MercPtrs[ubNoiseMaker], zNoiseMessage); + if (gTauntsSettings.fTauntShowInLog == TRUE) + ScreenMsg(FONT_GRAY2, MSG_INTERFACE, L"%s: %s", MercPtrs[ubNoiseMaker]->GetName(), zNoiseMessage); + } + else + { + if (gTauntsSettings.fTauntShowPopupBox == TRUE && gTauntsSettings.fTauntShowPopupBoxIfHeard == TRUE) + ShowTauntPopupBox(MercPtrs[ubNoiseMaker], zNoiseMessage); + if (gTauntsSettings.fTauntShowInLog == TRUE && gTauntsSettings.fTauntShowInLogIfHeard == TRUE) + ScreenMsg(FONT_GRAY2, MSG_INTERFACE, L"%s: %s", pTauntUnknownVoice[0], zNoiseMessage); + } + } } } else if ( bLevel == pSoldier->pathing.bLevel || ubNoiseType == NOISE_EXPLOSION || ubNoiseType == NOISE_SCREAM || ubNoiseType == NOISE_ROCK_IMPACT || ubNoiseType == NOISE_GRENADE_IMPACT ) @@ -6817,20 +6842,14 @@ void TellPlayerAboutNoise( SOLDIERTYPE *pSoldier, UINT8 ubNoiseMaker, INT32 sGri //DIGICRAB: Loud Sound Locator - //show a locator for very loud noises if we are in PLATINUM mode and have an extended ear - //Madd: if(gGameOptions.ubGameStyle == STYLE_PLATINUM && ubVolumeIndex >= 2) + //show a locator for very loud noises if we have an extended ear if(ubVolumeIndex >= 2) { -// INT8 bSlot; - - //bSlot = FindObj( pSoldier, EXTENDEDEAR ); - //if ( bSlot == HEAD1POS || bSlot == HEAD2POS) if ( FindHearingAid(pSoldier) ) BeginMultiPurposeLocator(sGridNo, bLevel, (INT8)((gTacticalStatus.uiFlags & TURNBASED) && ( gTacticalStatus.uiFlags & INCOMBAT ))); } // flag soldier as having reported noise in a particular direction - } void VerifyAndDecayOpplist(SOLDIERTYPE *pSoldier)