Mercs can now have multiple disabilities at the same time.

The new fSpecialFlagContractDisability tag for diseases adds a disability every time we are infected with the disease, it is used for PTSD.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8826 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2020-06-20 15:47:43 +00:00
parent 7899cc1f1e
commit d33bc9123c
18 changed files with 147 additions and 36 deletions
+2 -2
View File
@@ -55,8 +55,8 @@
#endif
CHAR8 czVersionNumber[16] = { "Build 20.06.01" }; //YY.MM.DD
CHAR8 czVersionNumber[16] = { "Build 20.06.20" }; //YY.MM.DD
CHAR16 zTrackingNumber[16] = { L"Z" };
CHAR16 zRevisionNumber[16] = { L"Revision 8815" };
CHAR16 zRevisionNumber[16] = { L"Revision 8826" };
// SAVE_GAME_VERSION is defined in header, change it there
+2 -1
View File
@@ -22,6 +22,7 @@ extern CHAR16 zRevisionNumber[16];
// Keeps track of the saved game version. Increment the saved game version whenever
// you will invalidate the saved game file
#define DISABILITYFLAGMASK 181 // Flugente: disabilities get a flagmask
#define PROFILETYPE_STORED 180 // Flugente: the type of each profile is stored in the savegame
#define CORPSE_DISPOSAL 179 // Flugente: corpses can be removed by assignment
#define RAID_EVENTS 178 // Flugente: added bloodcat/zombie/bandit raids
@@ -100,7 +101,7 @@ extern CHAR16 zRevisionNumber[16];
#define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes
#define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system
#define SAVE_GAME_VERSION PROFILETYPE_STORED
#define SAVE_GAME_VERSION DISABILITYFLAGMASK
//#define RUSSIANGOLD
#ifdef __cplusplus
+64 -22
View File
@@ -40,6 +40,7 @@
#include "Interface.h" // added by Flugente
#include "IMP Background.h" // added by Flugente for AssignBackgroundHelpText()
#include "NPC.h" // added by Flugente for GetEffectiveApproachValue(...)
#include "Drugs And Alcohol.h" // added by Flugente for DoesMercHaveDisability(...)
// WDS - make number of mercenaries, etc. be configurable
@@ -447,6 +448,7 @@ BOOLEAN fAddedTraitRegion[13] = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALS
void AssignPersonnelCharacterTraitHelpText( UINT8 ubCharacterNumber );
void AssignPersonnelDisabilityHelpText( UINT8 ubDisabilityNumber );
void AssignPersonnelMultipleDisabilityHelpText( SOLDIERTYPE* pSoldier );
void AssignPersonnelKillsHelpText( INT32 ubProfile );
void AssignPersonnelAssistsHelpText( INT32 ubProfile );
void AssignPersonnelHitPercentageHelpText( INT32 ubProfile );
@@ -1774,30 +1776,49 @@ void DisplayCharStats( INT32 iId, INT32 iSlot )
case 18:
// Disability
mprintf( (INT16)(pPersonnelScreenPoints[25].x + (iSlot*TEXT_BOX_WIDTH)), (pPersonnelScreenPoints[25].y + 10), pPersonnelRecordsHelpTexts[44] ); //L"Disability:"
swprintf( sString, gzIMPDisabilityTraitText[gMercProfiles[Menptr[iId].ubProfile].bDisability] );
FindFontRightCoordinates( (INT16)(pPersonnelScreenPoints[25].x + (iSlot*TEXT_BOX_WIDTH)), 0, TEXT_BOX_WIDTH - 20, 0, sString, PERS_FONT, &sX, &sY );
mprintf( sX, (pPersonnelScreenPoints[25].y + 10), sString );
//GetVideoObject(&hHandle, guiQMark);
//BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[25].x + 148), ( pPersonnelScreenPoints[25].y ), VO_BLT_SRCTRANSPARENCY,NULL );
// Add specific region for fast help window
if ( fAddedTraitRegion[6] )
{
MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[6] );
UINT8 loc = 25;
UINT8 regionnr = 6;
mprintf( (INT16)( pPersonnelScreenPoints[loc].x + ( iSlot*TEXT_BOX_WIDTH ) ), ( pPersonnelScreenPoints[loc].y + 10 ), pPersonnelRecordsHelpTexts[44] ); //L"Disability:"
int numdisabilities = 0;
UINT8 disabilityfound = 0;
for ( UINT8 i = NO_DISABILITY + 1; i < NUM_DISABILITIES; ++i )
{
if ( DoesMercHaveDisability( pSoldier, i ) )
{
disabilityfound = i;
++numdisabilities;
}
}
if ( numdisabilities <= 1 )
swprintf( sString, gzIMPDisabilityTraitText[disabilityfound] );
else
swprintf( sString, L"%s, ...", gzIMPDisabilityTraitText[disabilityfound] );
FindFontRightCoordinates( (INT16)( pPersonnelScreenPoints[loc].x + ( iSlot*TEXT_BOX_WIDTH ) ), 0, TEXT_BOX_WIDTH - 20, 0, sString, PERS_FONT, &sX, &sY );
mprintf( sX, ( pPersonnelScreenPoints[loc].y + 10 ), sString );
// Add specific region for fast help window
if ( fAddedTraitRegion[regionnr] )
{
MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[regionnr] );
}
MSYS_DefineRegion( &gSkillTraitHelpTextRegion[regionnr], ( sX - 3 ), (UINT16)( pPersonnelScreenPoints[loc].y + 10 ),
( sX + StringPixLength( sString, PERS_FONT ) + 3 ), (UINT16)( pPersonnelScreenPoints[loc].y + 17 ), MSYS_PRIORITY_HIGH,
MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
MSYS_AddRegion( &gSkillTraitHelpTextRegion[regionnr] );
fAddedTraitRegion[regionnr] = TRUE;
// Assign the text
if ( numdisabilities <= 1 )
AssignPersonnelDisabilityHelpText( gMercProfiles[Menptr[iId].ubProfile].bDisability );
else
AssignPersonnelMultipleDisabilityHelpText( pSoldier );
}
MSYS_DefineRegion( &gSkillTraitHelpTextRegion[6], (sX - 3), (UINT16)(pPersonnelScreenPoints[25].y + 10),
(sX + StringPixLength( sString, PERS_FONT ) + 3), (UINT16)(pPersonnelScreenPoints[25].y + 17), MSYS_PRIORITY_HIGH,
MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
//MSYS_DefineRegion( &gSkillTraitHelpTextRegion[6], (UINT16)( pPersonnelScreenPoints[25].x + 147 ), (UINT16)( pPersonnelScreenPoints[25].y - 1),
// (UINT16)( pPersonnelScreenPoints[25].x + 166 ), (UINT16)(pPersonnelScreenPoints[25].y + 10), MSYS_PRIORITY_HIGH,
// MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
MSYS_AddRegion( &gSkillTraitHelpTextRegion[6] );
fAddedTraitRegion[6] = TRUE;
// Assign the text
AssignPersonnelDisabilityHelpText( gMercProfiles[Menptr[iId].ubProfile].bDisability );
break;
/////////////////////////////////////////////////////////////////////////
@@ -8569,6 +8590,27 @@ void AssignPersonnelDisabilityHelpText( UINT8 ubDisabilityNumber )
SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[6], MSYS_NO_CALLBACK );
}
void AssignPersonnelMultipleDisabilityHelpText( SOLDIERTYPE* pSoldier )
{
CHAR16 apStr[1000];
int numdisabilities = 0;
UINT8 disabilityfound = 0;
swprintf( apStr, L"" );
for ( UINT8 i = NO_DISABILITY + 1; i < NUM_DISABILITIES; ++i )
{
if ( DoesMercHaveDisability( pSoldier, i ) )
{
swprintf( apStr, L"%s%s\n", apStr, gzIMPDisabilityTraitText[i] );
swprintf( apStr, L"%s%s\n\n", apStr, gzIMPDisabilitiesHelpTexts[i] );
}
}
// Set region help text
SetRegionFastHelpText( &( gSkillTraitHelpTextRegion[6] ), apStr );
SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[6], MSYS_NO_CALLBACK );
}
void AssignPersonnelKillsHelpText( INT32 ubProfile )
{
CHAR16 apStr[ 1000 ];
+12
View File
@@ -2457,6 +2457,18 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
buffer++;
}
if ( guiCurrentSaveGameVersion >= DISABILITYFLAGMASK )
{
numBytesRead = ReadFieldByField( hFile, &this->usDisabilityFlagMask, sizeof( usDisabilityFlagMask ), sizeof( UINT32 ), numBytesRead );
}
else
{
this->usDisabilityFlagMask = 0;
for ( int i = 0; i < sizeof( usDisabilityFlagMask ); ++i )
buffer++;
}
/*if ( guiCurrentSaveGameVersion >= FOOD_CHANGES )
{
numBytesRead = ReadFieldByField(hFile, &this->bFoodLevel, sizeof(bFoodLevel), sizeof(INT32), numBytesRead);
+1
View File
@@ -70,6 +70,7 @@ enum
#define DISEASE_PROPERTY_DISGUSTING 0x00000010 // other merc's will be disgusted by anyone with this disease if broken out
#define DISEASE_PROPERTY_PTSD_BUNS 0x00000020 // if Buns has this disease, she can change personality
#define DISEASE_PROPERTY_ADD_DISABILITY 0x00000040 // whenever we contract this disease, we gain a new disability
#define CORPSEREMOVALPOINTSPERCORPSE 1.0f // number of corpse removal points required to, you guessed it, remove a corpse
#define DISEASE_PER_ROTTINGCORPSE 100.0f // if a corpse is removed by rotting, add this many disease points to the sector
+3
View File
@@ -328,6 +328,9 @@ BOOLEAN DoesMercHaveDisability( SOLDIERTYPE *pSoldier, UINT8 aVal )
if ( pSoldier->newdrugs.drugdisability == aVal )
return TRUE;
if ( pSoldier->usDisabilityFlagMask & ( 1 << aVal ) )
return TRUE;
}
return FALSE;
+35 -3
View File
@@ -1130,6 +1130,7 @@ void SOLDIERTYPE::initialize( )
this->iLastArmourProtection = 0;
this->usQuickItemId = 0;
this->ubQuickItemSlot = 0;
this->usDisabilityFlagMask = 0;
}
bool SOLDIERTYPE::exists( )
@@ -19227,10 +19228,28 @@ void SOLDIERTYPE::Infect( UINT8 aDisease )
return;
// we are getting infected. Raise our disease points, but not over the level of an infection
if ( aDisease < NUM_DISEASES && this->sDiseasePoints[aDisease] < Disease[aDisease].sInfectionPtsInitial )
if ( aDisease < NUM_DISEASES && this->sDiseasePoints[aDisease] <= Disease[aDisease].sInfectionPtsInitial )
{
this->sDiseasePoints[aDisease] = min( this->sDiseasePoints[aDisease] + Disease[aDisease].sInfectionPtsInitial, Disease[aDisease].sInfectionPtsInitial );
// possibly add a new disability
if ( Disease[aDisease].usDiseaseProperties & DISEASE_PROPERTY_ADD_DISABILITY )
{
// take a random disability we don't yet have and give it to us
std::vector<UINT8> disabilitieswedonthaveset;
for ( UINT8 i = NO_DISABILITY + 1; i < min( 31, NUM_DISABILITIES ); ++i )
{
if ( !DoesMercHaveDisability( this, i ) )
disabilitieswedonthaveset.push_back(i);
}
if ( !disabilitieswedonthaveset.empty() )
{
UINT8 newdisability = disabilitieswedonthaveset[Random( disabilitieswedonthaveset.size() )];
this->AddDisability( newdisability );
}
}
if ( this->sDiseasePoints[aDisease] > Disease[aDisease].sInfectionPtsOutbreak )
{
this->sDiseaseFlag[aDisease] |= SOLDIERDISEASE_OUTBREAK;
@@ -19295,6 +19314,11 @@ void SOLDIERTYPE::AnnounceDisease( UINT8 aDisease )
gMercProfiles[this->ubProfile].records.usTimesInfected += 1;
}
void SOLDIERTYPE::AddDisability( UINT8 aDisability )
{
this->usDisabilityFlagMask |= ( 1 << aDisability );
}
// do we have any disease? fDiagnosedOnly: check for wether we know of this infection fHealableOnly: check wether it can be healed
BOOLEAN SOLDIERTYPE::HasDisease( BOOLEAN fDiagnosedOnly, BOOLEAN fHealableOnly, BOOLEAN fSymbolOnly )
{
@@ -19368,7 +19392,8 @@ void SOLDIERTYPE::PrintDiseaseDesc( CHAR16* apStr, BOOLEAN fFullDesc )
fShowExactPoints = TRUE;
CHAR16 atStr[500];
swprintf( atStr, L"" );
swprintf( atStr, L"\n \n" );
wcscat( apStr, atStr );
for ( int i = 0; i < NUM_DISEASES; ++i )
{
@@ -19479,6 +19504,12 @@ void SOLDIERTYPE::PrintDiseaseDesc( CHAR16* apStr, BOOLEAN fFullDesc )
swprintf( atStr, szDiseaseText[TEXT_DISEASE_PTSD_BUNS_SPECIAL] );
wcscat( apStr, atStr );
}
if ( Disease[i].usDiseaseProperties & DISEASE_PROPERTY_ADD_DISABILITY )
{
swprintf( atStr, szDiseaseText[TEXT_DISEASE_ADD_DISABILITY] );
wcscat( apStr, atStr );
}
}
}
else if ( fShowExactPoints && this->sDiseasePoints[i] > 0 )
@@ -19600,7 +19631,8 @@ void SOLDIERTYPE::PrintSleepDesc( CHAR16* apStr )
return;
CHAR16 atStr[100];
swprintf( atStr, L"" );
swprintf( atStr, L"\n \n" );
wcscat( apStr, atStr );
swprintf( atStr, gpStrategicString[STR_BREATH_REGEN_SLEEP], this->GetSleepBreathRegeneration( ) );
wcscat( apStr, atStr );
+3
View File
@@ -1579,6 +1579,8 @@ public:
UINT32 usIndividualMilitiaID; // Flugente: if this is a militia, this is the ID of the militia data
// Flugente: store disabilities as a flagmask, so we can have multiple ones
UINT32 usDisabilityFlagMask;
#ifdef JA2UB
//ja25
@@ -1958,6 +1960,7 @@ public:
void Infect( UINT8 aDisease );
void AddDiseasePoints( UINT8 aDisease, INT32 aVal );
void AnnounceDisease( UINT8 aDisease );
void AddDisability( UINT8 aDisability );
// do we have any disease?
// fDiagnosedOnly: check for wether we know of this infection
+8
View File
@@ -83,6 +83,7 @@ diseaseStartElementHandle( void *userData, const XML_Char *name, const XML_Char
strcmp( name, "fHideSymbol" ) == 0 ||
strcmp( name, "fDisgusting" ) == 0 ||
strcmp( name, "fSpecialFlagPTSDBuns" ) == 0 ||
strcmp( name, "fSpecialFlagContractDisability" ) == 0 ||
strcmp( name, "sEffStatAGI" ) == 0 ||
strcmp( name, "sEffStatDEX" ) == 0 ||
strcmp( name, "sEffStatSTR" ) == 0 ||
@@ -309,6 +310,12 @@ diseaseEndElementHandle( void *userData, const XML_Char *name )
if ( atol( pData->szCharData ) )
pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_PTSD_BUNS;
}
else if ( strcmp( name, "fSpecialFlagContractDisability" ) == 0 )
{
pData->curElement = ELEMENT;
if ( atol( pData->szCharData ) )
pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_ADD_DISABILITY;
}
else if ( strcmp( name, "sEffStatAGI" ) == 0 )
{
pData->curElement = ELEMENT;
@@ -488,6 +495,7 @@ BOOLEAN WriteDiseaseStats( )
FilePrintf( hFile, "\t\t<fHideSymbol>%d</fHideSymbol>\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_HIDESYMBOL) ? 1 : 0 );
FilePrintf( hFile, "\t\t<fDisgusting>%d</fDisgusting>\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_DISGUSTING) ? 1 : 0 );
FilePrintf( hFile, "\t\t<fSpecialFlagPTSDBuns>%d</fSpecialFlagPTSDBuns>\r\n", ( Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_PTSD_BUNS ) ? 1 : 0 );
FilePrintf( hFile, "\t\t<fSpecialFlagContractDisability>%d</fSpecialFlagContractDisability>\r\n", ( Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_ADD_DISABILITY ) ? 1 : 0 );
FilePrintf( hFile, "\t\t<sEffStatAGI>%d</sEffStatAGI>\r\n", Disease[cnt].sEffStat[INFST_AGI] );
FilePrintf( hFile, "\t\t<sEffStatDEX>%d</sEffStatDEX>\r\n", Disease[cnt].sEffStat[INFST_DEX] );
FilePrintf( hFile, "\t\t<sEffStatSTR>%d</sEffStatSTR>\r\n", Disease[cnt].sEffStat[INFST_STR] );
+1
View File
@@ -2983,6 +2983,7 @@ enum
TEXT_DISEASE_PTSD_BUNS_SPECIAL,
TEXT_DISEASE_CONTAMINATION_FOUND,
TEXT_DISEASE_ADD_DISABILITY,
};
enum
+2 -1
View File
@@ -11111,7 +11111,8 @@ STR16 szDiseaseText[] =
L"\n\n%s (未诊断的) - %d / %d\n", //L"\n\n%s (undiagnosed) - %d / %d\n",
L"高度的痛苦会导致人格分裂\n", //L"High amount of distress can cause a personality split\n",
L"在%s'库存中发现污染物品。", //L"Contaminated items found in %s' inventory.",
L"在%s'库存中发现污染物品。\n", //L"Contaminated items found in %s' inventory.\n",
L"Whenever we get this, a new disability is added.\n", // TODO.Translate
};
STR16 szSpyText[] =
+2 -1
View File
@@ -11127,7 +11127,8 @@ STR16 szDiseaseText[] =
L"\n\n%s (undiagnosed) - %d / %d\n", // TODO.Translate
L"High amount of distress can cause a personality split\n", // TODO.Translate
L"Contaminated items found in %s' inventory.",
L"Contaminated items found in %s' inventory.\n",
L"Whenever we get this, a new disability is added.\n", // TODO.Translate
};
STR16 szSpyText[] =
+2 -1
View File
@@ -11125,7 +11125,8 @@ STR16 szDiseaseText[] =
L"\n\n%s (undiagnosed) - %d / %d\n",
L"High amount of distress can cause a personality split\n",
L"Contaminated items found in %s' inventory.",
L"Contaminated items found in %s' inventory.\n",
L"Whenever we get this, a new disability is added.\n",
};
STR16 szSpyText[] =
+2 -1
View File
@@ -11109,7 +11109,8 @@ STR16 szDiseaseText[] =
L"\n\n%s (undiagnosed) - %d / %d\n", // TODO.Translate
L"High amount of distress can cause a personality split\n", // TODO.Translate
L"Contaminated items found in %s' inventory.",
L"Contaminated items found in %s' inventory.\n",
L"Whenever we get this, a new disability is added.\n", // TODO.Translate
};
STR16 szSpyText[] =
+2 -1
View File
@@ -10939,7 +10939,8 @@ STR16 szDiseaseText[] =
L"\n\n%s (undiagnosed) - %d / %d\n", // TODO.Translate
L"High amount of distress can cause a personality split\n", // TODO.Translate
L"Contaminated items found in %s' inventory.",
L"Contaminated items found in %s' inventory.\n",
L"Whenever we get this, a new disability is added.\n", // TODO.Translate
};
STR16 szSpyText[] =
+2 -1
View File
@@ -11118,7 +11118,8 @@ STR16 szDiseaseText[] =
L"\n\n%s (undiagnosed) - %d / %d\n", // TODO.Translate
L"High amount of distress can cause a personality split\n", // TODO.Translate
L"Contaminated items found in %s' inventory.",
L"Contaminated items found in %s' inventory.\n",
L"Whenever we get this, a new disability is added.\n", // TODO.Translate
};
STR16 szSpyText[] =
+2 -1
View File
@@ -11131,7 +11131,8 @@ STR16 szDiseaseText[] =
L"\n\n%s (undiagnosed) - %d / %d\n", // TODO.Translate
L"High amount of distress can cause a personality split\n", // TODO.Translate
L"Contaminated items found in %s' inventory.",
L"Contaminated items found in %s' inventory.\n",
L"Whenever we get this, a new disability is added.\n", // TODO.Translate
};
STR16 szSpyText[] =
+2 -1
View File
@@ -11111,7 +11111,8 @@ STR16 szDiseaseText[] =
L"\n\n%s (недиагностирована) - %d / %d\n",
L"High amount of distress can cause a personality split\n", // TODO.Translate
L"Contaminated items found in %s' inventory.",
L"Contaminated items found in %s' inventory.\n",
L"Whenever we get this, a new disability is added.\n", // TODO.Translate
};
STR16 szSpyText[] =