Updated Enemy Taunts (by anv)

- fixed crash due to same enemy taunting several times in a row (e.g. after being hit by a burst)
- prevent enemy from taunting again, before his previous taunt is finished
- taunt .xmls should be kept in subdirectory TableData\EnemyTaunts\ to avoid mess in TableData\
- added <szCensoredText>, if TAUNT_CENSORED_MODE set to TRUE and <szCensoredText> defined, it will be displayed instead of <szText>

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6659 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2013-11-28 08:23:03 +00:00
parent e6e8cd75fd
commit 4b7258f8b3
6 changed files with 85 additions and 38 deletions
+1
View File
@@ -3206,6 +3206,7 @@ void LoadCTHConstants()
void LoadTauntsSettings()
{
CIniReader iniReader(TAUNTS_SETTINGS_FILE);
gTauntsSettings.fTauntCensoredMode = iniReader.ReadBoolean("Taunts Settings","TAUNT_CENSORED_MODE", FALSE );
gTauntsSettings.fTauntShowPopupBox = iniReader.ReadBoolean("Taunts Settings","TAUNT_SHOW_POPUP_BOX", TRUE );
gTauntsSettings.fTauntShowInLog = iniReader.ReadBoolean("Taunts Settings","TAUNT_SHOW_IN_LOG", TRUE );
gTauntsSettings.fTauntMakeNoise = iniReader.ReadBoolean("Taunts Settings","TAUNT_MAKE_NOISE", TRUE );
+1
View File
@@ -1330,6 +1330,7 @@ typedef struct
typedef struct
{
BOOLEAN fTauntCensoredMode;
BOOLEAN fTauntShowPopupBox;
BOOLEAN fTauntShowInLog;
BOOLEAN fTauntMakeNoise;
+71 -37
View File
@@ -45,6 +45,8 @@
#define HIGH_TOWN_LOYALTY 80
#define CIV_QUOTE_HINT 99
#define MAX_APPLICABLE_TAUNTS 512
extern void CaptureTimerCallback( void );
BOOLEAN gfSurrendered = FALSE;
@@ -137,6 +139,11 @@ CHAR16 gzCivQuote[ 320 ];
UINT16 gusCivQuoteBoxWidth;
UINT16 gusCivQuoteBoxHeight;
// anv: store times, when enemy taunt will be finished (so they won't taunt 50 times / second)
UINT32 uiTauntFinishTimes[ TOTAL_SOLDIERS ];
TAUNT_VALUES zApplicableTaunts[NUM_TAUNT];
//--------------------------------------------------------------
void CopyNumEntriesIntoQuoteStruct( ) // Not used
{
@@ -1029,11 +1036,15 @@ BOOLEAN SaveCivQuotesToSaveGameFile( HWFILE hFile )
return( TRUE );
}
// anv: used now
//is allowed remove. Not used and remove from SaveLoadGame.cpp.
BOOLEAN LoadCivQuotesFromLoadGameFile( HWFILE hFile )
{
UINT32 uiNumBytesRead;
// anv: reset uiTauntFinishTimes after game is loaded (so enemies can taunt after guiBaseJA2Clock is decreased)
memset( &uiTauntFinishTimes, 0, sizeof( uiTauntFinishTimes ) );
FileRead( hFile, &gCivQuotes, sizeof( gCivQuotes ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( gCivQuotes ) )
{
@@ -1062,6 +1073,12 @@ void PossiblyStartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTY
{
return;
}
// is enemy blocked from taunting at the moment?
if( uiTauntFinishTimes[pCiv->ubID] > GetJA2Clock() )
{
return;
}
// check if generated person
if ( !(IS_MERC_BODY_TYPE( pCiv )) || !(pCiv->ubProfile == NO_PROFILE) )
{
@@ -1079,7 +1096,7 @@ void PossiblyStartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTY
return;
}
// only enemies that are able to speak at the moment can taunt
if ( pCiv->stats.bLife < OKLIFE || pCiv->bCollapsed )
if ( pCiv->stats.bLife < OKLIFE || pCiv->bBreathCollapsed )
{
return;
}
@@ -1248,13 +1265,9 @@ void PossiblyStartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTY
// SANDRO - soldier taunts
void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTarget )
{
UINT16 iTauntNumber;
CHAR16 sTauntText[320];
CHAR16 sTauntText[ 320 ];
CHAR16 gzTauntQuote[ 320 ];
TAUNT_VALUES zApplicableTaunts[1024];
UINT16 iApplicableTaunts = 0;
BOOLEAN fApplicableAttitude[6];
#ifdef ENABLE_ZOMBIES
// Flugente: zombies don't talk
@@ -1262,11 +1275,12 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTar
return;
#endif
// 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;
}
//if ( gCivQuoteData.bActive )
//{
// return;
//}
// anv: check all taunts, and remember those applicable
for(UINT16 i=0; i<num_found_taunt; i++)
@@ -1876,44 +1890,58 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTar
}
// everything ok, current taunt is applicable, remember it
zApplicableTaunts[iApplicableTaunts] = zTaunt[i];
iApplicableTaunts++;
iApplicableTaunts++;
if(iApplicableTaunts >= MAX_APPLICABLE_TAUNTS)
continue;
}
// are there any applicable taunts?
if( iApplicableTaunts > 0 )
{
// use random one
swprintf( sTauntText, zApplicableTaunts[ Random(iApplicableTaunts) ].szText );
// use censored version if setting is set
UINT16 iChosenTaunt = Random(iApplicableTaunts);
if( gTauntsSettings.fTauntCensoredMode == TRUE && zApplicableTaunts[ iChosenTaunt ].szCensoredText[0] != 0 )
{
swprintf( sTauntText, zApplicableTaunts[ iChosenTaunt ].szCensoredText );
}
else
{
swprintf( sTauntText, zApplicableTaunts[ iChosenTaunt ].szText );
}
#ifdef TAIWANESE
swprintf( gzTauntQuote, L"%s", sTauntText );
#else
swprintf( gzTauntQuote, L"\"%s\"", sTauntText );
#endif
// block this enemy from taunting for a time being
uiTauntFinishTimes[pCiv->ubID] = 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 );
else
{
if(gTauntsSettings.fTauntShowPopupBox == TRUE)
{
if( gbPublicOpplist[gbPlayerNum][pCiv->ubID] == SEEN_CURRENTLY || gTauntsSettings.fTauntAlwaysShowPopupBox == TRUE )
{
ShowTauntPopupBox( pCiv, gzTauntQuote );
}
}
if(gTauntsSettings.fTauntShowInLog == TRUE)
{
if( gbPublicOpplist[gbPlayerNum][pCiv->ubID] == SEEN_CURRENTLY || gTauntsSettings.fTauntAlwaysShowInLog == TRUE )
{
ScreenMsg( FONT_GRAY2, MSG_INTERFACE, L"%s: %s", pCiv->GetName(), gzTauntQuote );
}
}
}
}
else
{
return;
}
#ifdef TAIWANESE
swprintf( gzTauntQuote, L"%s", sTauntText );
#else
swprintf( gzTauntQuote, L"\"%s\"", sTauntText );
#endif
if( gTauntsSettings.fTauntMakeNoise == TRUE )
MakeNoise( pCiv->ubID, pCiv->sGridNo, pCiv->pathing.bLevel, pCiv->bOverTerrainType, gTauntsSettings.sVolume, NOISE_VOICE, gzTauntQuote );
else
{
if(gTauntsSettings.fTauntShowPopupBox == TRUE)
{
if( gbPublicOpplist[gbPlayerNum][pCiv->ubID] == SEEN_CURRENTLY || gTauntsSettings.fTauntAlwaysShowPopupBox == TRUE )
{
ShowTauntPopupBox( pCiv, gzTauntQuote );
}
}
if(gTauntsSettings.fTauntShowInLog == TRUE)
{
if( gbPublicOpplist[gbPlayerNum][pCiv->ubID] == SEEN_CURRENTLY || gTauntsSettings.fTauntAlwaysShowInLog == TRUE )
{
ScreenMsg( FONT_GRAY2, MSG_INTERFACE, L"%s: %s", pCiv->GetName(), gzTauntQuote );
}
}
}
}
void ShowTauntPopupBox( SOLDIERTYPE *pCiv, STR16 gzTauntQuote )
@@ -1922,6 +1950,12 @@ void ShowTauntPopupBox( SOLDIERTYPE *pCiv, STR16 gzTauntQuote )
INT16 sScreenX, sScreenY;
VIDEO_OVERLAY_DESC VideoOverlayDesc;
// stop if other civ quote is already being shown
if( gCivQuoteData.bActive == TRUE )
{
return;
}
// Determine location...
// Get location of civ on screen.....
GetSoldierScreenPos( pCiv, &sScreenX, &sScreenY );
+1
View File
@@ -267,6 +267,7 @@ typedef struct
{
UINT16 uiIndex;
CHAR16 szText[320];
CHAR16 szCensoredText[320];
UINT64 uiFlags;
UINT64 uiFlags2;
INT16 value[TAUNT_MAX];
+1 -1
View File
@@ -238,7 +238,7 @@ typedef PARSE_STAGE;
#define SQUADNAMEFILENAME "SquadNames.xml"
#define BACKGROUNDSFILENAME "Backgrounds.xml"
#define TAUNTSFILENAME "EnemyTaunts.xml"
#define TAUNTSFILENAMEBEGINNING "EnemyTaunts"
#define TAUNTSFILENAMEBEGINNING "EnemyTaunts\\EnemyTaunts"
#define TAUNTSFILENAMEENDING ".xml"
#define ENEMY_ADMIN_PROFILE_FILENAME "Profiles\\SoldierProfileEnemyAdmin.xml"
+10
View File
@@ -55,6 +55,7 @@ tauntStartElementHandle(void *userData, const XML_Char *name, const XML_Char **a
else if(pData->curElement == ELEMENT &&
(strcmp(name, "uiIndex") == 0 ||
strcmp(name, "szText") == 0 ||
strcmp(name, "szCensoredText") == 0 ||
strcmp(name, "aggressive") == 0 ||
strcmp(name, "defensive") == 0 ||
@@ -233,6 +234,8 @@ tauntEndElementHandle(void *userData, const XML_Char *name)
{
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curArray[pData->curTaunt.uiIndex].szText, sizeof(pData->curTaunt.szText)/sizeof(pData->curTaunt.szText[0]) );
pData->curArray[pData->curTaunt.uiIndex].szText[sizeof(pData->curTaunt.szText)/sizeof(pData->curTaunt.szText[0]) - 1] = '\0';
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curArray[pData->curTaunt.uiIndex].szCensoredText, sizeof(pData->curTaunt.szCensoredText)/sizeof(pData->curTaunt.szCensoredText[0]) );
pData->curArray[pData->curTaunt.uiIndex].szCensoredText[sizeof(pData->curTaunt.szCensoredText)/sizeof(pData->curTaunt.szCensoredText[0]) - 1] = '\0';
}
else
{
@@ -297,6 +300,13 @@ tauntEndElementHandle(void *userData, const XML_Char *name)
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curTaunt.szText, sizeof(pData->curTaunt.szText)/sizeof(pData->curTaunt.szText[0]) );
pData->curTaunt.szText[sizeof(pData->curTaunt.szText)/sizeof(pData->curTaunt.szText[0]) - 1] = '\0';
}
else if(strcmp(name, "szCensoredText") == 0 )
{
pData->curElement = ELEMENT;
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curTaunt.szCensoredText, sizeof(pData->curTaunt.szCensoredText)/sizeof(pData->curTaunt.szCensoredText[0]) );
pData->curTaunt.szCensoredText[sizeof(pData->curTaunt.szCensoredText)/sizeof(pData->curTaunt.szCensoredText[0]) - 1] = '\0';
}
else if(strcmp(name, "aggressive") == 0)
{
pData->curElement = ELEMENT;