mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
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:
@@ -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 );
|
||||
|
||||
@@ -1330,6 +1330,7 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOLEAN fTauntCensoredMode;
|
||||
BOOLEAN fTauntShowPopupBox;
|
||||
BOOLEAN fTauntShowInLog;
|
||||
BOOLEAN fTauntMakeNoise;
|
||||
|
||||
+71
-37
@@ -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 );
|
||||
|
||||
@@ -267,6 +267,7 @@ typedef struct
|
||||
{
|
||||
UINT16 uiIndex;
|
||||
CHAR16 szText[320];
|
||||
CHAR16 szCensoredText[320];
|
||||
UINT64 uiFlags;
|
||||
UINT64 uiFlags2;
|
||||
INT16 value[TAUNT_MAX];
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user