New feature: we have to bury corpses, or their rot causes diseases in sectors

Requires GameDir >= r2436.

Fopr more info, see http://thepit.ja-galaxy-forum.com/index.php?t=tree&th=23828&goto=354321&#msg_354321

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8591 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2018-08-12 12:42:38 +00:00
parent b7c74ee398
commit a59b75b0be
39 changed files with 713 additions and 644 deletions
+2 -2
View File
@@ -1731,8 +1731,8 @@ void LoadGameExternalOptions()
gGameExternalOptions.fZombieOnlyHeadShotsPermanentlyKill = iniReader.ReadBoolean("Tactical Zombie Settings", "ZOMBIE_ONLY_HEADSHOTS_PERMANENTLY_KILL", TRUE);
//################# Corpse Settings ##################
gGameExternalOptions.usCorpseDelayUntilRotting = iniReader.ReadInteger( "Corpse Settings", "CORPSE_DELAY_UNTIL_ROTTING", NUM_SEC_IN_DAY / 60, 720, 7 * NUM_SEC_IN_DAY / 60 );
gGameExternalOptions.usCorpseDelayUntilDoneRotting = iniReader.ReadInteger( "Corpse Settings", "CORPSE_DELAY_UNTIL_DONE_ROTTING", 3 * NUM_SEC_IN_DAY / 60, NUM_SEC_IN_DAY / 60, 14 * NUM_SEC_IN_DAY / 60 );
gGameExternalOptions.usCorpseDelayUntilRotting = iniReader.ReadInteger( "Corpse Settings", "CORPSE_DELAY_UNTIL_ROTTING", NUM_SEC_IN_DAY / 60, 0, 7 * NUM_SEC_IN_DAY / 60 );
gGameExternalOptions.usCorpseDelayUntilDoneRotting = iniReader.ReadInteger( "Corpse Settings", "CORPSE_DELAY_UNTIL_DONE_ROTTING", 3 * NUM_SEC_IN_DAY / 60, 0, 14 * NUM_SEC_IN_DAY / 60 );
//################# Tactical Fortification Settings ##################
gGameExternalOptions.fFortificationAllowInHostileSector = iniReader.ReadBoolean("Tactical Fortification Settings", "FORTIFICATION_ALLOW_IN_HOSTILE_SECTOR", FALSE);
+2 -2
View File
@@ -55,8 +55,8 @@
#endif
CHAR8 czVersionNumber[16] = { "Build 18.07.25" }; //YY.MM.DD
CHAR8 czVersionNumber[16] = { "Build 18.08.12" }; //YY.MM.DD
CHAR16 zTrackingNumber[16] = { L"Z" };
CHAR16 zRevisionNumber[16] = { L"Revision 8588" };
CHAR16 zRevisionNumber[16] = { L"Revision 8591" };
// 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 CORPSE_DISPOSAL 179 // Flugente: corpses can be removed by assignment
#define RAID_EVENTS 178 // Flugente: added bloodcat/zombie/bandit raids
#define INDIVIDUAL_MILITIA_EXP_FLOAT 177 // Flugente: changed the way we store individual militia experience
#define CHAT_TO_DISTRACT 176 // Flugente: internal variable allows us to distract enemies by engrossing them in conversation
@@ -98,7 +99,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 RAID_EVENTS
#define SAVE_GAME_VERSION CORPSE_DISPOSAL
//#define RUSSIANGOLD
#ifdef __cplusplus
+267 -41
View File
@@ -145,6 +145,7 @@ enum{
enum {
DISEASE_MENU_DIAGNOSE,
DISEASE_MENU_SECTOR_TREATMENT,
DISEASE_MENU_BURIAL,
DISEASE_MENU_CANCEL,
};
@@ -491,7 +492,7 @@ void HandleRadioScanInSector( INT16 sMapX, INT16 sMapY, INT8 bZ );
// Flugente: disease
void HandleDiseaseDiagnosis();
void HandleDiseaseSectorTreatment( );
void HandleStrategicDiseaseAndBurial( );
// Flugente: fortification
void HandleFortification();
@@ -1002,7 +1003,7 @@ BOOLEAN CanCharacterTreatSectorDisease( SOLDIERTYPE *pSoldier )
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
// we can only treat disease if we have data on it - either our team diagnosed it, or the WHO did and we have access to their data
if ( pSectorInfo && ((pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) || (gubFact[FACT_DISEASE_WHODATA_ACCESS] && pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_WHO)) )
if ( pSectorInfo && ((pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) || gubFact[FACT_DISEASE_WHODATA_ACCESS] ) )
return TRUE;
// all criteria fit, can doctor
@@ -1055,6 +1056,27 @@ BOOLEAN CanCharacterSpyAssignment( SOLDIERTYPE *pSoldier )
return TRUE;
}
BOOLEAN CanCharacterBurial( SOLDIERTYPE *pSoldier )
{
if ( !gGameExternalOptions.fDisease || !gGameExternalOptions.fDiseaseStrategic )
return FALSE;
AssertNotNIL( pSoldier );
if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) )
return( FALSE );
if ( pSoldier->bSectorZ )
return FALSE;
SECTORINFO *pSectorInfo = &( SectorInfo[SECTOR( pSoldier->sSectorX, pSoldier->sSectorY )] );
if ( !pSectorInfo || (!( pSectorInfo->uiFlags & SF_ROTTING_CORPSE_TEMP_FILE_EXISTS ) && !pSectorInfo->usNumCorpses ) )
return FALSE;
return TRUE;
}
BOOLEAN IsAnythingAroundForSoldierToRepair( SOLDIERTYPE * pSoldier )
{
AssertNotNIL(pSoldier);
@@ -2895,7 +2917,7 @@ void UpdateAssignments()
// Flugente: disease
HandleDisease();
HandleDiseaseDiagnosis(); // this must come after HandleDisease() so we discover fresh infections
HandleDiseaseSectorTreatment();
HandleStrategicDiseaseAndBurial();
// Flugente: PMC recruits new personnel
HourlyUpdatePMC();
@@ -6228,8 +6250,8 @@ void HandleDiseaseDiagnosis()
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
if ( pSectorInfo && pSectorInfo->usInfected &&
!((pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) || (gubFact[FACT_DISEASE_WHODATA_ACCESS] && pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_WHO)) &&
if ( pSectorInfo && pSectorInfo->fDiseasePoints &&
!(pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) &&
Chance( skill ) )
{
pSectorInfo->usInfectionFlag |= SECTORDISEASE_DIAGNOSED_PLAYER;
@@ -6242,57 +6264,236 @@ void HandleDiseaseDiagnosis()
}
}
extern BOOLEAN SaveRottingCorpsesToTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, std::vector<ROTTING_CORPSE_DEFINITION> aCorpseDefVector );
// handle treating the population (NOT our mercs) against diseases
// our mercs are healed via the regular doctoring procedure
void HandleDiseaseSectorTreatment()
void HandleStrategicDiseaseAndBurial()
{
// requires dieases, duh
if ( !gGameExternalOptions.fDisease || !gGameExternalOptions.fDiseaseStrategic )
return;
// every merc on diagnosis examines every other merc in this sector for diseases that are currently now known
// depending on his skills how far an infection has gotten, the infection will be made public, giving us more time to cure it
UINT32 currenttime = GetWorldTotalMin();
// turn corpses into disease once they are old enough
for ( INT16 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
{
for ( INT16 sY = 1; sY < MAP_WORLD_X - 1; ++sY )
{
SECTORINFO *pSectorInfo = &( SectorInfo[SECTOR( sX, sY )] );
if ( pSectorInfo )
{
if ( ( pSectorInfo->uiFlags & SF_ROTTING_CORPSE_TEMP_FILE_EXISTS ) || pSectorInfo->usNumCorpses )
{
// determine corpse removal points of all mercs on assignment here
FLOAT corpseremovalpoints = pSectorInfo->dBurial_UnappliedProgress;
SOLDIERTYPE *pSoldier = NULL;
UINT32 uiCnt = 0;
for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, ++pSoldier )
{
if ( pSoldier->bActive && pSoldier->bAssignment == BURIAL && !pSoldier->flags.fMercAsleep &&
pSoldier->sSectorX == sX && pSoldier->sSectorY == sY && !pSoldier->bSectorZ && EnoughTimeOnAssignment( pSoldier ) )
{
corpseremovalpoints += pSoldier->GetBurialPoints( NULL );
}
}
INT32 corpsesremoved_burial = 0;
INT32 corpsesremoved_rot = 0;
// open corpse table, check them for age, remove those ones old enough and add disease and a loyalty penalty
if ( sX == gWorldSectorX && sY == gWorldSectorY )
{
INT32 corpsesleft = 0;
for ( INT32 iCount = 0; iCount < giNumRottingCorpse; ++iCount )
{
if ( ( gRottingCorpse[iCount].fActivated ) )
{
if ( corpseremovalpoints >= CORPSEREMOVALPOINTSPERCORPSE )
{
corpseremovalpoints -= CORPSEREMOVALPOINTSPERCORPSE;
RemoveCorpse( iCount );
++corpsesremoved_burial;
}
else if ( ( ( currenttime - gRottingCorpse[iCount].def.uiTimeOfDeath ) > gGameExternalOptions.usCorpseDelayUntilDoneRotting ) )
{
// add disease
pSectorInfo->fDiseasePoints = min( DISEASE_MAX_SECTOR, pSectorInfo->fDiseasePoints + DISEASE_PER_ROTTINGCORPSE );
RemoveCorpse( iCount );
++corpsesremoved_rot;
}
else
{
++corpsesleft;
}
}
}
pSectorInfo->usNumCorpses = corpsesleft;
}
else
{
HWFILE hFile;
UINT32 uiNumBytesRead = 0;
CHAR8 zMapName[128];
UINT32 uiNumberOfCorpses = 0;
ROTTING_CORPSE_DEFINITION def;
std::vector<ROTTING_CORPSE_DEFINITION> corpsedefvector;
GetMapTempFileName( SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, zMapName, sX, sY, 0 );
//Check to see if the file exists
if ( FileExists( zMapName ) )
{
//Open the file for reading
hFile = FileOpen( zMapName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
if ( hFile != 0 )
{
// Load the number of Rotting corpses
FileRead( hFile, &uiNumberOfCorpses, sizeof( UINT32 ), &uiNumBytesRead );
if ( uiNumBytesRead != sizeof( UINT32 ) )
{
// Error Writing size of array to disk
FileClose( hFile );
}
else
{
// we loop over all corpses and remove some of them, either by rotting or assignment
// if we chang anything, we save the now reduced array
for ( UINT32 cnt = 0; cnt < uiNumberOfCorpses; ++cnt )
{
// Load the Rotting corpses info
FileRead( hFile, &def, sizeof( ROTTING_CORPSE_DEFINITION ), &uiNumBytesRead );
if ( uiNumBytesRead != sizeof( ROTTING_CORPSE_DEFINITION ) )
{
//Error Writing size of array to disk
continue;
}
if ( corpseremovalpoints >= CORPSEREMOVALPOINTSPERCORPSE )
{
corpseremovalpoints -= CORPSEREMOVALPOINTSPERCORPSE;
++corpsesremoved_burial;
}
else if ( ( ( currenttime - def.uiTimeOfDeath ) > gGameExternalOptions.usCorpseDelayUntilDoneRotting ) )
{
// add disease
pSectorInfo->fDiseasePoints = min( DISEASE_MAX_SECTOR, pSectorInfo->fDiseasePoints + DISEASE_PER_ROTTINGCORPSE);
++corpsesremoved_rot;
}
else
{
corpsedefvector.push_back( def );
}
}
FileClose( hFile );
pSectorInfo->usNumCorpses = corpsedefvector.size();
// now save the corpses under the same filename
if ( corpsesremoved_burial + corpsesremoved_rot )
SaveRottingCorpsesToTempCorpseFile( sX, sY, 0, corpsedefvector );
}
}
}
}
// the population doesn't like it when their neighbourhood suffers from disease
if ( corpsesremoved_rot )
{
INT8 bTownId = GetTownIdForSector( sX, sY );
// if NOT in a town
if ( bTownId != BLANK_SECTOR )
{
UINT32 uiLoyaltyChange = corpsesremoved_rot * LOYALTY_PENALTY_ROTTED_CORPSE;
DecrementTownLoyalty( bTownId, uiLoyaltyChange );
}
}
// if we removed corpses, award experience to the undertakers
if ( corpsesremoved_burial )
{
for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, ++pSoldier )
{
if ( pSoldier->bActive && pSoldier->bAssignment == BURIAL && !pSoldier->flags.fMercAsleep &&
pSoldier->sSectorX == sX && pSoldier->sSectorY == sY && !pSoldier->bSectorZ && EnoughTimeOnAssignment( pSoldier ) )
{
StatChange( pSoldier, STRAMT, 8, FALSE );
}
}
}
// store unapplied assignment progress
pSectorInfo->dBurial_UnappliedProgress = max( 0.0f, corpseremovalpoints );
}
// disease from corpses decays over time
// if this the hospital sector, the amount of doctoring is increased to marvellous levels
if ( sX == gModSettings.ubHospitalSectorX && sY == gModSettings.ubHospitalSectorY )
pSectorInfo->fDiseasePoints = max( 0.0f, min( pSectorInfo->fDiseasePoints * 0.9f, pSectorInfo->fDiseasePoints - 10.0f ) );
else
pSectorInfo->fDiseasePoints = max( 0.0f, min( pSectorInfo->fDiseasePoints * 0.98f, pSectorInfo->fDiseasePoints - 2.0f ) );
}
}
}
// mercs remove strategic disease
SOLDIERTYPE *pSoldier = NULL;
UINT32 uiCnt = 0;
for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, pSoldier++ )
for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, ++pSoldier )
{
if ( pSoldier->bActive && pSoldier->bAssignment == DISEASE_DOCTOR_SECTOR && CanCharacterTreatSectorDisease( pSoldier ) && !pSoldier->flags.fMercAsleep && EnoughTimeOnAssignment( pSoldier ) )
if ( pSoldier->bActive && pSoldier->bAssignment == DISEASE_DOCTOR_SECTOR && !pSoldier->bSectorZ &&
!pSoldier->flags.fMercAsleep && EnoughTimeOnAssignment( pSoldier ) && CanCharacterTreatSectorDisease( pSoldier ) )
{
MakeSureMedKitIsInHand( pSoldier );
// get available healing pts
UINT16 max = 0;
UINT16 ptsavailable = CalculateHealingPointsForDoctor( pSoldier, &max, TRUE );
ptsavailable = (ptsavailable * (100 + pSoldier->GetBackgroundValue( BG_PERC_DISEASE_TREAT ))) / 100;
// calculate how much total points we have in all medical bags
UINT16 usTotalMedPoints = TotalMedicalKitPoints( pSoldier );
// doctoring points are limited by medical supplies
ptsavailable = min( ptsavailable, usTotalMedPoints * 100 );
// if we are doctoring in a sector, then we know for sure that there is disease here
SECTORINFO *pSectorInfo = &(SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ]);
SECTORINFO *pSectorInfo = &( SectorInfo[SECTOR( pSoldier->sSectorX, pSoldier->sSectorY )] );
if ( pSectorInfo && pSectorInfo->usInfected )
if ( pSectorInfo && pSectorInfo->fDiseasePoints )
{
pSectorInfo->usInfectionFlag |= SECTORDISEASE_DIAGNOSED_PLAYER;
UINT32 ptsused = HealSectorPopulation( pSoldier->sSectorX, pSoldier->sSectorY, ptsavailable );
// Finaly use all kit points (we are sure, we have that much)
if ( !UseTotalMedicalKitPoints( pSoldier, ptsused / 100 ) )
{
// throw message if this went wrong for feedback on debugging
#ifdef JA2TESTVERSION
ScreenMsg( FONT_MCOLOR_RED, MSG_TESTVERSION, L"Warning! UseTotalKitPOints returned false, not all points were probably used." );
#endif
}
MakeSureMedKitIsInHand( pSoldier );
// increment skills based on healing pts used
StatChange( pSoldier, MEDICALAMT, (UINT16)(ptsused / 100), FALSE );
StatChange( pSoldier, DEXTAMT, (UINT16)(ptsused / 100), FALSE );
StatChange( pSoldier, WISDOMAMT, (UINT16)(ptsused / 100), FALSE );
// get available healing pts
UINT16 max = 0;
UINT16 ptsavailable = CalculateHealingPointsForDoctor( pSoldier, &max, TRUE );
ptsavailable = ( ptsavailable * ( 100 + pSoldier->GetBackgroundValue( BG_PERC_DISEASE_TREAT ) ) ) / 100;
// calculate how much total points we have in all medical bags
UINT16 usTotalMedPoints = TotalMedicalKitPoints( pSoldier );
// doctoring points are limited by medical supplies
ptsavailable = min( ptsavailable, usTotalMedPoints * 100 );
UINT32 ptsused = HealSectorPopulation( pSoldier->sSectorX, pSoldier->sSectorY, ptsavailable );
// Finaly use all kit points (we are sure, we have that much)
if ( !UseTotalMedicalKitPoints( pSoldier, ptsused / 100 ) )
{
// throw message if this went wrong for feedback on debugging
#ifdef JA2TESTVERSION
ScreenMsg( FONT_MCOLOR_RED, MSG_TESTVERSION, L"Warning! UseTotalMedicalKitPoints returned false, not all points were probably used." );
#endif
}
// increment skills based on healing pts used
StatChange( pSoldier, MEDICALAMT, 3, FALSE );
StatChange( pSoldier, DEXTAMT, 1, FALSE );
StatChange( pSoldier, WISDOMAMT, 1, FALSE );
}
}
}
}
@@ -17572,6 +17773,10 @@ void ReEvaluateEveryonesNothingToDo( BOOLEAN aDoExtensiveCheck )
fNothingToDo = !CanCharacterDrillMilitia( pSoldier );
break;
case BURIAL:
fNothingToDo = !CanCharacterBurial( pSoldier );
break;
case VEHICLE:
default: // squads
fNothingToDo = FALSE;
@@ -17909,6 +18114,15 @@ void SetAssignmentForList( INT8 bAssignment, INT8 bParam )
}
break;
case BURIAL:
if ( CanCharacterBurial( pSoldier ) )
{
pSoldier->bOldAssignment = pSoldier->bAssignment;
SetSoldierAssignment( pSoldier, bAssignment, bParam, 0, 0 );
fItWorked = TRUE;
}
break;
case( SQUAD_1 ):
case( SQUAD_2 ):
case( SQUAD_3 ):
@@ -21645,6 +21859,7 @@ BOOLEAN DisplayDiseaseMenu( SOLDIERTYPE *pSoldier )
AddMonoString( (UINT32 *)&hStringHandle, szDiseaseText[TEXT_DISEASE_DIAGNOSIS] );
AddMonoString( (UINT32 *)&hStringHandle, szDiseaseText[TEXT_DISEASE_TREATMENT] );
AddMonoString( (UINT32 *)&hStringHandle, szDiseaseText[TEXT_DISEASE_BURIAL] );
// cancel
AddMonoString( (UINT32 *)&hStringHandle, szDiseaseText[TEXT_DISEASE_CANCEL] );
@@ -21672,6 +21887,7 @@ void HandleShadingOfLinesForDiseaseMenu( void )
return;
}
UnShadeStringInBox( ghDiseaseBox, iCount++ );
UnShadeStringInBox( ghDiseaseBox, iCount++ );
UnShadeStringInBox( ghDiseaseBox, iCount++ );
@@ -21740,7 +21956,15 @@ void CreateDestroyMouseRegionForDiseaseMenu( void )
MSYS_SetRegionUserData( &gDisease[iCount], 0, iCount );
MSYS_SetRegionUserData( &gDisease[iCount], 1, iCount );
++iCount;
// burial assignment
MSYS_DefineRegion( &gDisease[iCount], (INT16)( iBoxXPosition ), (INT16)( iBoxYPosition + GetTopMarginSize( ghAssignmentBox ) + (iFontHeight)* iCount ), (INT16)( iBoxXPosition + iBoxWidth ), (INT16)( iBoxYPosition + GetTopMarginSize( ghAssignmentBox ) + ( iFontHeight )* ( iCount + 1 ) ), MSYS_PRIORITY_HIGHEST - 4,
MSYS_NO_CURSOR, DiseaseMenuMvtCallback, DiseaseMenuBtnCallback );
MSYS_SetRegionUserData( &gDisease[iCount], 0, iCount );
MSYS_SetRegionUserData( &gDisease[iCount], 1, iCount );
++iCount;
// cancel
MSYS_DefineRegion( &gDisease[iCount], (INT16)(iBoxXPosition), (INT16)(iBoxYPosition + GetTopMarginSize( ghAssignmentBox ) + (iFontHeight)* iCount), (INT16)(iBoxXPosition + iBoxWidth), (INT16)(iBoxYPosition + GetTopMarginSize( ghAssignmentBox ) + (iFontHeight)* (iCount + 1)), MSYS_PRIORITY_HIGHEST - 4,
MSYS_NO_CURSOR, DiseaseMenuMvtCallback, DiseaseMenuBtnCallback );
@@ -21801,6 +22025,8 @@ void DiseaseMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason )
INT8 newassignment = DISEASE_DIAGNOSE;
if ( iWhat == DISEASE_MENU_SECTOR_TREATMENT )
newassignment = DISEASE_DOCTOR_SECTOR;
else if ( iWhat == DISEASE_MENU_BURIAL )
newassignment = BURIAL;
if ( pSoldier->bAssignment != newassignment )
{
+3
View File
@@ -96,6 +96,7 @@ enum
GATHERINTEL, // gathers information while disguised in enemy territory
DOCTOR_MILITIA, // heal militia
DRILL_MILITIA, // train existing militia (does not create new ones)
BURIAL, // merc removes corpses in this sector
NUM_ASSIGNMENTS,
};
@@ -187,6 +188,8 @@ BOOLEAN CanCharacterFortify( SOLDIERTYPE *pSoldier );
BOOLEAN CanCharacterSpyAssignment( SOLDIERTYPE *pSoldier );
BOOLEAN CanCharacterBurial( SOLDIERTYPE *pSoldier );
// can this character be assigned as a repairman?
BOOLEAN CanCharacterRepair( SOLDIERTYPE *pCharacter );
+2 -8
View File
@@ -4799,10 +4799,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
{
AddRaidPersonnel( -( pTarget->pSoldier->ubBodyType == BLOODCAT ), -( pTarget->pSoldier->ubSoldierClass == SOLDIER_CLASS_ZOMBIE ), -( pTarget->pSoldier->ubSoldierClass == SOLDIER_CLASS_BANDIT ) );
}
// Flugente: disease
HandleDeathDiseaseImplications( pTarget->pSoldier );
if( pAttacker->uiFlags & CELL_MERC )
{ //Player killed the enemy soldier -- update his stats as well as any assisters.
/////////////////////////////////////////////////////////////////////////////////////
@@ -5028,10 +5025,7 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
{
AddRaidPersonnel( -( pTarget->pSoldier->ubBodyType == BLOODCAT ), -( pTarget->pSoldier->ubSoldierClass == SOLDIER_CLASS_ZOMBIE ), -( pTarget->pSoldier->ubSoldierClass == SOLDIER_CLASS_BANDIT ) );
}
// Flugente: disease
HandleDeathDiseaseImplications( pTarget->pSoldier );
//soldier has been killed
if( pTarget->pAttacker[ index ]->uiFlags & CELL_PLAYER )
{ //Player killed the enemy soldier -- update his stats as well as any assisters.
+7 -4
View File
@@ -518,9 +518,9 @@ typedef struct SECTORINFO
UINT8 ubTanksInBattle;
// Flugente: disease
UINT16 usInfected; // how many people (civilians + enemy + militia) are infected in this sector? Does NOT count our mercs
FLOAT fInfectionSeverity; // mean infection rate of those infected (percentage)
UINT8 usDiseaseDoctoringDelay; // AI doctoring in this sector is delayed due to player interference
UINT16 usNumCorpses; // number of corpses in this sector
FLOAT fDiseasePoints; // disease points
UINT8 bFiller4;
UINT8 usInfectionFlag;
// Flugente: fortification
@@ -537,7 +537,10 @@ typedef struct SECTORINFO
// Flugente: localized weather
UINT32 usWeather;
INT8 bPadding[ 16 ];
// Flugente: burial assignment
FLOAT dBurial_UnappliedProgress; // progress done via assignment work. This way no work gets lost
INT8 bPadding[ 12 ];
}SECTORINFO;
+51 -65
View File
@@ -705,46 +705,43 @@ void HandleShowingOfEnemiesWithMilitiaOn( void )
// aType = 2: intel
INT32 GetMapColour( INT16 sX, INT16 sY, UINT8 aType )
{
UINT8 sector = SECTOR( sX, sY );
if ( aType == 0 )
{
UINT16 population = GetSectorPopulation( sX, sY );
{
SECTORINFO *pSectorInfo = &( SectorInfo[sector] );
if ( population )
// display sector information only if we know about infection there
if ( pSectorInfo && ( ( pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER ) || gubFact[FACT_DISEASE_WHODATA_ACCESS] ) )
{
UINT8 sector = SECTOR( sX, sY );
FLOAT diseaseratio = pSectorInfo->fDiseasePoints / DISEASE_MAX_SECTOR;
SECTORINFO *pSectorInfo = &( SectorInfo[sector] );
// display sector information only if we know about infection there
if ( pSectorInfo && ( ( pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER ) || ( gubFact[FACT_DISEASE_WHODATA_ACCESS] && pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_WHO ) ) )
{
FLOAT infectedpercentage = (FLOAT)pSectorInfo->usInfected / (FLOAT)( population );
if ( infectedpercentage < 0.2f )
return MAP_SHADE_DK_GREEN;
else if ( infectedpercentage < 0.3f )
return MAP_SHADE_MD_GREEN;
else if ( infectedpercentage < 0.4f )
return MAP_SHADE_LT_GREEN;
else if ( infectedpercentage < 0.5f )
return MAP_SHADE_DK_YELLOW;
else if ( infectedpercentage < 0.6f )
return MAP_SHADE_MD_YELLOW;
else if ( infectedpercentage < 0.7f )
return MAP_SHADE_LT_YELLOW;
else if ( infectedpercentage < 0.8f )
return MAP_SHADE_DK_RED;
else if ( infectedpercentage < 0.9f )
return MAP_SHADE_MD_RED;
else
return MAP_SHADE_LT_RED;
}
if ( pSectorInfo->fDiseasePoints < 0.1f )
return MAP_SHADE_BLACK;
else if ( diseaseratio < 0.05f )
return MAP_SHADE_DK_GREEN;
else if ( diseaseratio < 0.1f )
return MAP_SHADE_MD_GREEN;
else if ( diseaseratio < 0.2f )
return MAP_SHADE_LT_GREEN;
else if ( diseaseratio < 0.3f )
return MAP_SHADE_DK_YELLOW;
else if ( diseaseratio < 0.4f )
return MAP_SHADE_MD_YELLOW;
else if ( diseaseratio < 0.5f )
return MAP_SHADE_LT_YELLOW;
else if ( diseaseratio < 0.65f )
return MAP_SHADE_ORANGE;
else if ( diseaseratio < 0.8f )
return MAP_SHADE_DK_RED;
else if ( diseaseratio < 0.9f )
return MAP_SHADE_MD_RED;
else
return MAP_SHADE_LT_RED;
}
}
else if ( aType == 1 )
{
UINT8 sector = SECTOR( sX, sY );
SECTORINFO *pSectorInfo = &( SectorInfo[sector] );
// display sector information only if we know about infection there
@@ -773,8 +770,6 @@ INT32 GetMapColour( INT16 sX, INT16 sY, UINT8 aType )
}
else if ( aType == 2 )
{
UINT8 sector = SECTOR( sX, sY );
return gMapIntelData[sector].mapcolour;
}
@@ -7248,7 +7243,6 @@ void ShowDiseaseOnMap()
}
SetFont(MapItemsFont);
SetFontForeground(FONT_MCOLOR_LTGREEN);
SetFontBackground(FONT_MCOLOR_BLACK);
// run through sectors
@@ -7260,42 +7254,34 @@ void ShowDiseaseOnMap()
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
if ( pSectorInfo && ((pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) || (gubFact[FACT_DISEASE_WHODATA_ACCESS] && pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_WHO)) )
if ( pSectorInfo && ((pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) || gubFact[FACT_DISEASE_WHODATA_ACCESS] ) )
{
// hide this information, as it might allow the player to deduct enemy positions and numbers
/*{
UINT16 population = GetSectorPopulation( sMapX, sMapY );
if ( population )
{
sXCorner = (INT16)(MAP_VIEW_START_X + (sMapX * MAP_GRID_X));
sYCorner = (INT16)(MAP_VIEW_START_Y + (sMapY * MAP_GRID_Y));
SetFontForeground( FONT_MCOLOR_WHITE );
if ( pSectorInfo->usInfectionFlag & SECTORDISEASE_OUTBREAK )
swprintf( sString, L"%d/%d", pSectorInfo->usInfected, population );
else
swprintf( sString, L"%d", population );
FindFontCenterCoordinates( sXCorner, sYCorner, MAP_GRID_X, MAP_GRID_Y, sString, MapItemsFont, &usXPos, &usYPos );
mprintf( usXPos, usYPos, sString );
}
}*/
sXCorner = (INT16)( MAP_VIEW_START_X + ( sMapX * MAP_GRID_X ) );
sYCorner = (INT16)( MAP_VIEW_START_Y + ( sMapY * MAP_GRID_Y ) );
if ( pSectorInfo->usNumCorpses > 0 )
{
if ( pSectorInfo->fInfectionSeverity > 0 )
{
sXCorner = (INT16)(MAP_VIEW_START_X + (sMapX * MAP_GRID_X));
sYCorner = (INT16)(MAP_VIEW_START_Y + (sMapY * MAP_GRID_Y));
SetFontForeground( FONT_MCOLOR_WHITE );
SetFontForeground( FONT_MCOLOR_WHITE );
swprintf( sString, L"%4.1f%%", 100 * pSectorInfo->fInfectionSeverity );
swprintf( sString, L"%d", pSectorInfo->usNumCorpses );
FindFontCenterCoordinates( sXCorner, sYCorner, MAP_GRID_X, MAP_GRID_Y, sString, MapItemsFont, &usXPos, &usYPos );
FindFontCenterCoordinates( sXCorner, sYCorner, MAP_GRID_X, MAP_GRID_Y, sString, MapItemsFont, &usXPos, &usYPos );
mprintf( usXPos, usYPos, sString );
}
mprintf( usXPos, usYPos, sString );
}
if ( pSectorInfo->fDiseasePoints > 0 )
{
SetFontForeground( FONT_MCOLOR_LTGREEN );
// as the healing displayed is always divided by 10 (see in face display), we do the same thinh here to not confuse the player
swprintf( sString, L"%6.1f", pSectorInfo->fDiseasePoints / 10.0f );
sYCorner += GetFontHeight( MapItemsFont );
FindFontCenterCoordinates( sXCorner, sYCorner, MAP_GRID_X, MAP_GRID_Y, sString, MapItemsFont, &usXPos, &usYPos );
mprintf( usXPos, usYPos, sString );
}
}
}
+11 -1
View File
@@ -365,7 +365,17 @@ void HandleHourlyMilitiaHealing( )
{
if ( !((*it).flagmask & MILITIAFLAG_DEAD) )
{
(*it).healthratio = min( 100.0f, (*it).healthratio + gGameExternalOptions.dIndividualMilitiaHourlyHealthPercentageGain );
FLOAT healingmodifier = 1.0f;
if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic )
{
SECTORINFO *pSectorInfo = &( SectorInfo[(*it).sector] );
if ( pSectorInfo && pSectorInfo->fDiseasePoints )
healingmodifier -= 2.5f * pSectorInfo->fDiseasePoints / DISEASE_MAX_SECTOR;
}
(*it).healthratio = min( 100.0f, (*it).healthratio + healingmodifier * gGameExternalOptions.dIndividualMilitiaHourlyHealthPercentageGain );
}
}
+2 -11
View File
@@ -277,9 +277,6 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
// Flugente: update individual militia data
ApplyTacticalLifeRatioToMilitia( );
// Flugente: disease
PopulationMove( sMapX, sMapY, sTMapX, sTMapY, elites + regulars + greens );
// Erase ALL militia from both locations.
StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
@@ -321,10 +318,7 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
// Flugente: update individual militia data
ApplyTacticalLifeRatioToMilitia( );
// Flugente: disease
PopulationMove( sMapX, sMapY, sTMapX, sTMapY, elites + regulars + greens );
// Remove half team from source sector
StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, bGreensDestTeam );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, bRegularsDestTeam );
@@ -414,10 +408,7 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
// Flugente: update individual militia data
ApplyTacticalLifeRatioToMilitia( );
// Flugente: disease
PopulationMove( sMapX, sMapY, sTMapX, sTMapY, elites + regulars + greens );
// Erase ALL militia from both locations.
StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
+21
View File
@@ -2131,6 +2131,24 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
ChooseMapEdgepoints( &MapEdgepointInfo, ubStrategicInsertionCode, ubTotalSoldiers );
#endif
extern INT16 gsStrategicDiseaseOriginSector;
// Flugente: we need to set the sector of origin to determine from which sector to take the disease ratio that affects health
gsStrategicDiseaseOriginSector = -1;
if ( !gbWorldSectorZ )
{
switch ( ubStrategicInsertionCode )
{
case INSERTION_CODE_NORTH: gsStrategicDiseaseOriginSector = SECTOR( gWorldSectorX, gWorldSectorY - 1 ); break;
case INSERTION_CODE_EAST: gsStrategicDiseaseOriginSector = SECTOR( gWorldSectorX + 1, gWorldSectorY ); break;
case INSERTION_CODE_SOUTH: gsStrategicDiseaseOriginSector = SECTOR( gWorldSectorX, gWorldSectorY + 1 ); break;
case INSERTION_CODE_WEST: gsStrategicDiseaseOriginSector = SECTOR( gWorldSectorX - 1, gWorldSectorY ); break;
default:
break;
}
}
ubCurrSlot = 0;
while( ubTotalSoldiers )
{
@@ -2265,6 +2283,9 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
gCurrentIncident.usIncidentFlags |= INCIDENT_REINFORCEMENTS_ENEMY;
}
}
// set this back so it doesn't affect others
gsStrategicDiseaseOriginSector = -1;
#ifdef JA2UB
gsGridNoForMapEdgePointInfo = -1;
-3
View File
@@ -226,9 +226,6 @@ UINT8 DoReinforcementAsPendingNonPlayer( INT16 sMapX, INT16 sMapY, UINT8 usTeam
{
while ( (pGroup = GetNonPlayerGroupInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), usTeam )) != NULL )
{
// Flugente: disease
PopulationMove( pGroup->ubSectorX, pGroup->ubSectorY, sMapX, sMapY, pGroup->ubGroupSize );
pGroup->ubPrevX = pGroup->ubSectorX;
pGroup->ubPrevY = pGroup->ubSectorY;
+1 -7
View File
@@ -1932,13 +1932,7 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe
return;
}
// Flugente: disease
if ( pGroup->usGroupTeam != OUR_TEAM )
{
PopulationMove( pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubNextX, pGroup->ubNextY, pGroup->ubGroupSize );
}
//Update the position of the group
pGroup->ubPrevX = pGroup->ubSectorX;
pGroup->ubPrevY = pGroup->ubSectorY;
+3
View File
@@ -47,6 +47,9 @@
//Madd:
#define LOYALTY_PENALTY_INACTIVE 0 // (10 * GAIN_PTS_PER_LOYALTY_PT)
// Flugente: a rotting corpse is so decayed that it disappeared (we're the ones making all those corpses, the last we could do is clean up afterwards)
#define LOYALTY_PENALTY_ROTTED_CORPSE (1 * GAIN_PTS_PER_LOYALTY_PT)
typedef enum
{
// There are only for distance-adjusted global loyalty effects. Others go into list above instead!
+8
View File
@@ -5593,6 +5593,14 @@ BOOLEAN LoadStrategicInfoFromSavedFile( HWFILE hFile )
SectorInfo[sectorID].usWorkers = SectorExternalData[sectorID][0].maxworkers * gGameExternalOptions.dInitialWorkerRate;
SectorInfo[sectorID].ubWorkerTrainingHundredths = 0;
}
if ( guiCurrentSaveGameVersion < CORPSE_DISPOSAL )
{
SectorInfo[sectorID].usNumCorpses = 0; // this will get updated on the next full hour anyway
SectorInfo[sectorID].fDiseasePoints = 0.0f;
SectorInfo[sectorID].usInfectionFlag &= ~3;
SectorInfo[sectorID].dBurial_UnappliedProgress = 0.0f;
}
}
// uiSize = sizeof( SECTORINFO ) * 256;
+25 -352
View File
@@ -124,54 +124,14 @@ void HandleDisease()
}
}
// we can also be infected by the population
// we can also be infected by the disease left from corpses
if ( gGameExternalOptions.fDiseaseStrategic )
{
UINT16 population = GetSectorPopulation( pSoldier->sSectorX, pSoldier->sSectorY );
SECTORINFO *pSectorInfo = &( SectorInfo[SECTOR( pSoldier->sSectorX, pSoldier->sSectorY )] );
if ( population )
if ( pSectorInfo && pSectorInfo->fDiseasePoints )
{
UINT8 sector = SECTOR( pSoldier->sSectorX, pSoldier->sSectorY );
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
if ( pSectorInfo )
{
// if there are infected people, we might get an infection (disease 0 only)
if ( pSectorInfo->usInfected )
{
// infection is also possible by human contact
FLOAT dChance = Disease[0].dInfectionChance[INFECTION_TYPE_CONTACT_HUMAN];
// if disease is known, mercs will avoid the infected, lowering the chance of them being infected
UINT16 max = min(20, pSectorInfo->usInfected);
if ( (pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) || (gubFact[FACT_DISEASE_WHODATA_ACCESS] && pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_WHO) )
max /= 4;
for ( UINT16 i = 0; i < max; ++i )
{
// chances can be smaller than 1%, so we use a trick here by altering our 'chance function'. This allows to have much smaller chances, as for diseases, 1% can be way too high.
if ( Random( 10000 ) < dChance * 100 )
HandlePossibleInfection( pSoldier, NULL, INFECTION_TYPE_CONTACT_HUMAN, 1.0f, TRUE );
}
}
// if we are infected, WE might infect other people
if ( pSoldier->sDiseasePoints[0] > 0 )
{
if ( pSectorInfo->usInfected < population )
{
// chances can be smaller than 1%, so we use a trick here by altering our 'chance function'. This allows to have much smaller chances, as for diseases, 1% can be way too high.
if ( Random( 10000 ) < Disease[0].dInfectionChance[INFECTION_TYPE_CONTACT_HUMAN] * 100 )
{
FLOAT infectedseverity = (FLOAT)Disease[0].sInfectionPtsInitial / (FLOAT)Disease[0].sInfectionPtsFull;
pSectorInfo->fInfectionSeverity = (pSectorInfo->fInfectionSeverity * pSectorInfo->usInfected + infectedseverity * 1) / (pSectorInfo->usInfected + 1);
++pSectorInfo->usInfected;
}
}
}
}
HandlePossibleInfection( pSoldier, NULL, INFECTION_TYPE_CONTACT_CORPSE, ( pSectorInfo->fDiseasePoints / DISEASE_MAX_SECTOR ) );
}
}
@@ -217,191 +177,6 @@ void HandleDisease()
}
}
}
// now to handle strategic disease
if ( !gGameExternalOptions.fDiseaseStrategic )
return;
for ( UINT8 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
{
for ( UINT8 sY = 1; sY < MAP_WORLD_X - 1; ++sY )
{
UINT8 sector = SECTOR( sX, sY );
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
if ( !pSectorInfo )
continue;
// first, existing infections get worse
if ( pSectorInfo->fInfectionSeverity > 0 )
{
pSectorInfo->fInfectionSeverity = min( 1.0f, pSectorInfo->fInfectionSeverity + ( FLOAT )(Disease[0].sInfectionPtsGainPerHour) / (FLOAT)(Disease[0].sInfectionPtsFull) );
}
UINT16 population = GetSectorPopulation( sX, sY );
if ( population )
{
// how many people are already infected?
if ( pSectorInfo->usInfected < population )
{
UINT16 lefttoinfect = population - pSectorInfo->usInfected;
UINT16 newinfected = 0;
// population might get infected if this a swamp or tropical sector
switch ( SectorInfo[sector].ubTraversability[THROUGH_STRATEGIC_MOVE] )
{
case TROPICS_SAM_SITE:
case TROPICS:
case TROPICS_ROAD:
{
FLOAT dChance = Disease[0].dInfectionChance[INFECTION_TYPE_TROPICS];
for ( UINT16 i = 0; i < lefttoinfect; ++i )
{
// chances can be smaller than 1%, so we use a trick here by altering our 'chance function'. This allows to have much smaller chances, as for diseases, 1% can be way too high.
if ( Random( 10000 ) < dChance * 100 )
++newinfected;
}
}
break;
case SWAMP:
case SWAMP_ROAD:
{
FLOAT dChance = Disease[0].dInfectionChance[INFECTION_TYPE_SWAMP];
for ( UINT16 i = 0; i < lefttoinfect; ++i )
{
// chances can be smaller than 1%, so we use a trick here by altering our 'chance function'. This allows to have much smaller chances, as for diseases, 1% can be way too high.
if ( Random( 10000 ) < dChance * 100 )
++newinfected;
}
}
break;
default:
break;
}
if ( lefttoinfect - newinfected > 1 && pSectorInfo->usInfected )
{
// infection is also possible by human contact
FLOAT dChance = Disease[0].dInfectionChance[INFECTION_TYPE_CONTACT_HUMAN];
UINT16 max = sqrt( (FLOAT) min( lefttoinfect - newinfected, pSectorInfo->usInfected ) );
for ( UINT16 i = 0; i < max; ++i )
{
// chances can be smaller than 1%, so we use a trick here by altering our 'chance function'. This allows to have much smaller chances, as for diseases, 1% can be way too high.
if ( Random( 10000 ) < dChance * 100 )
++newinfected;
}
}
if ( lefttoinfect - newinfected > 0 )
{
// there is also the chance to be infected by bad food, sex, contact with animals etc.
// For now, we assume this to be very rare events, so just add a small chance to be infected this way
FLOAT populationpercentage = (FLOAT)(lefttoinfect - newinfected) / (FLOAT)(population);
FLOAT basechance = sqrt( (FLOAT) min( lefttoinfect, pSectorInfo->usInfected + newinfected ) ) * 0.5f;
FLOAT chance_sex = Disease[0].dInfectionChance[INFECTION_TYPE_SEX] * basechance * populationpercentage;
FLOAT chance_corpse = 0;
// if there was a fight here in the last 48 hours, then corpses will still be here - increase chance of infection
if ( pSectorInfo->uiTimeLastPlayerLiberated && pSectorInfo->uiTimeLastPlayerLiberated + (48 * 3600) > GetWorldTotalSeconds( ) )
chance_corpse = Disease[0].dInfectionChance[INFECTION_TYPE_CONTACT_CORPSE] * populationpercentage;
// chances can be smaller than 1%, so we use a trick here by altering our 'chance function'. This allows to have much smaller chances, as for diseases, 1% can be way too high.
if ( Random( 10000 ) < chance_sex * 100 )
++newinfected;
if ( Random( 10000 ) < chance_corpse * 100 )
++newinfected;
}
if ( lefttoinfect - newinfected > 0 )
{
// adjacent sectors can infect us too
for ( UINT8 dir = 0; dir < SP_DIR_MAX; ++dir )
{
INT16 othersector = GetAdjacentSector( sector, dir );
if ( othersector > -1 )
{
UINT16 population_other = GetSectorPopulation( SECTORX( othersector ), SECTORY( othersector ) );
SECTORINFO *pSectorInfo_Other = &(SectorInfo[othersector]);
if ( pSectorInfo_Other && pSectorInfo_Other->usInfected && population_other )
{
FLOAT infectedothersector = (FLOAT)pSectorInfo_Other->usInfected / (FLOAT)(population_other);
if ( infectedothersector > DISEASE_STRATEGIC_ADJACENTINFECTION )
{
FLOAT percentage = (FLOAT)((lefttoinfect - newinfected) * Disease[0].dInfectionChance[INFECTION_TYPE_CONTACT_HUMAN]) / (FLOAT)(100 * population);
// chances can be smaller than 1%, so we use a trick here by altering ou 'chance function'. This allows to have much smaller chances, as for diseases, 1% can be way too high.
if ( Random( 10000 ) < percentage * 100 * 100 )
++newinfected;
}
}
}
}
}
if ( pSectorInfo->usInfected + newinfected > 0 && Disease[0].sInfectionPtsFull )
{
FLOAT infectedseverity = (FLOAT)Disease[0].sInfectionPtsInitial / (FLOAT)Disease[0].sInfectionPtsFull;
pSectorInfo->fInfectionSeverity = (pSectorInfo->fInfectionSeverity * pSectorInfo->usInfected + infectedseverity * newinfected) / (pSectorInfo->usInfected + newinfected);
pSectorInfo->usInfected += newinfected;
pSectorInfo->usInfected = min( pSectorInfo->usInfected , population);
}
}
// if infection is high enough, disease officially breaks out
FLOAT infectedpercentage = (FLOAT)pSectorInfo->usInfected / (FLOAT)(population);
if ( infectedpercentage >= GetSectorDiseaseOverFlowThreshold() || pSectorInfo->fInfectionSeverity > ((FLOAT)Disease[0].sInfectionPtsOutbreak / (FLOAT)Disease[0].sInfectionPtsFull) )
{
pSectorInfo->usInfectionFlag |= (SECTORDISEASE_OUTBREAK | SECTORDISEASE_DIAGNOSED_WHO);
}
// if disease is known and doctoring isn't inhibited, use doctoring to remove disease
// doctors (civilian and military) can fight the disease
if ( (pSectorInfo->usInfectionFlag & (SECTORDISEASE_DIAGNOSED_WHO | SECTORDISEASE_DIAGNOSED_PLAYER)) && !pSectorInfo->usDiseaseDoctoringDelay)
{
// the country doesn't have many doctors...
UINT32 doctors = GetSectorPopulation( sX, sY, FALSE ) * GetCivPopulationDoctorRate();
// if this the hospital sector, the amount of doctoring is increased to marvellous levels
if ( sX == gModSettings.ubHospitalSectorX && sY == gModSettings.ubHospitalSectorY )
{
doctors += 200;
}
// the bulk of doctoring will come from the military
doctors += NumNonPlayerTeamMembersInSector( sX, sY, ENEMY_TEAM ) * GetMilitaryPopulationDoctorRate( );
UINT32 doctorpower = doctors * GetPopulationDoctorPoints( );
// if the disease escalates, increase doctor power!
if ( infectedpercentage > GetSectorDiseaseOverFlowThreshold( ) + 0.1f )
doctorpower += doctors * 0.3f * GetPopulationDoctorPoints();
HealSectorPopulation( sX, sY, doctorpower );
}
}
else
{
// if nobody is there, be sure to set infection data to 0
pSectorInfo->usInfected = 0;
pSectorInfo->usInfectionFlag = 0;
pSectorInfo->fInfectionSeverity = 0;
pSectorInfo->usDiseaseDoctoringDelay = 0;
}
// in any case, one hour has passed, update possible doctor replacements
pSectorInfo->usDiseaseDoctoringDelay = max( 0, pSectorInfo->usDiseaseDoctoringDelay - 1);
}
}
}
// chance gets modified by aModifier (contextual modifier)
@@ -503,95 +278,6 @@ UINT16 GetSectorPopulation( INT16 sX, INT16 sY, BOOLEAN fWithMilitary )
return population;
}
// handle infection redistribution if people move from A to B (set sXB and sYB to negative values to simply remove infected people in A)
void PopulationMove( INT16 sXA, INT16 sYA, INT16 sXB, INT16 sYB, UINT16 usAmount )
{
// we have to handle the impact on a sector's disease if people other than mercs move from A to B
if ( !gGameExternalOptions.fDiseaseStrategic )
return;
UINT8 sectorA = SECTOR( sXA, sYA );
SECTORINFO *pSectorInfoA = &(SectorInfo[sectorA]);
UINT16 populationA = GetSectorPopulation( sXA, sYA );
if ( populationA )
{
// how many people are already infected?
if ( pSectorInfoA )
{
FLOAT infectionrateA = (FLOAT)(pSectorInfoA->usInfected) / (FLOAT)(populationA);
UINT16 movinginfected = usAmount * infectionrateA;
// we have to add the infection of movinginfected new infected with an infection level of pSectorInfoA->usInfectionSeverity
if ( movinginfected )
{
// it is possible that there is no other sector
if ( sXB > -1 && sYB > -1 )
{
UINT8 sectorB = SECTOR( sXB, sYB );
SECTORINFO *pSectorInfoB = &(SectorInfo[sectorB]);
if ( pSectorInfoB )
{
// new infection severity is the mean of old and new infected times their infection ratios
pSectorInfoB->fInfectionSeverity = (pSectorInfoB->fInfectionSeverity * pSectorInfoB->usInfected + pSectorInfoA->fInfectionSeverity * movinginfected) / (pSectorInfoB->usInfected + movinginfected);
pSectorInfoB->usInfected += movinginfected;
// disease moves before population moves, so we have to add those too
UINT16 populationB = GetSectorPopulation( sXB, sYB ) + movinginfected;
FLOAT infectedpercentage = 0;
if ( populationB )
infectedpercentage = (FLOAT)pSectorInfoB->usInfected / (FLOAT)(populationB);
if ( infectedpercentage >= GetSectorDiseaseOverFlowThreshold() || pSectorInfoB->fInfectionSeverity > ((FLOAT)Disease[0].sInfectionPtsOutbreak / (FLOAT)Disease[0].sInfectionPtsFull) )
pSectorInfoB->usInfectionFlag |= (SECTORDISEASE_OUTBREAK | SECTORDISEASE_DIAGNOSED_WHO);
}
}
// reduce the amount of infected in sector A
pSectorInfoA->usInfected -= movinginfected;
// if no infected remain, clean up data
if ( !pSectorInfoA->usInfected )
{
pSectorInfoA->fInfectionSeverity = 0;
pSectorInfoA->usInfectionFlag &= ~(SECTORDISEASE_OUTBREAK | SECTORDISEASE_DIAGNOSED_WHO | SECTORDISEASE_DIAGNOSED_PLAYER);
}
}
}
}
}
void HandleDeathDiseaseImplications( SOLDIERTYPE *pSoldier )
{
if ( !gGameExternalOptions.fDisease || !gGameExternalOptions.fDiseaseStrategic || !pSoldier )
return;
UINT8 sector = SECTOR( pSoldier->sSectorX, pSoldier->sSectorY );
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
if ( pSectorInfo )
{
// if the deceased was infected and not a merc, reduce sector number of infected
if ( pSoldier->sDiseasePoints[0] && pSoldier->bTeam != OUR_TEAM )
{
pSectorInfo->usInfected = max( 0, pSectorInfo->usInfected - 1 );
}
// if this guy was a medic, then medical personnel was killed - it will take a while before he will be replaced
if ( HAS_SKILL_TRAIT( pSoldier, DOCTOR_NT ) )
{
pSectorInfo->usDiseaseDoctoringDelay = min( 255, pSectorInfo->usDiseaseDoctoringDelay + 12 );
}
}
}
void HandleDiseaseDailyRefresh()
{
if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && gubFact[FACT_DISEASE_WHODATA_SUBSCRIBED] && LaptopSaveInfo.iCurrentBalance > gGameExternalOptions.sDiseaseWHOSubscriptionCost )
@@ -619,31 +305,21 @@ UINT32 HealSectorPopulation( INT16 sX, INT16 sY, UINT32 uHealpts )
UINT32 ptsused = uHealpts;
// the amount of points needed to cure a single patient
UINT32 ptsneededforcure = pSectorInfo->fInfectionSeverity * Disease[0].sInfectionPtsFull;
// if possible, cure people (we prioritise on this, as we want to lower the number os possible infection sources)
while ( pSectorInfo->usInfected && uHealpts >= ptsneededforcure )
if ( uHealpts >= pSectorInfo->fDiseasePoints )
{
uHealpts -= ptsneededforcure;
--pSectorInfo->usInfected;
uHealpts -= pSectorInfo->fDiseasePoints;
pSectorInfo->fDiseasePoints = 0;
}
// if there are still points let, but we cannot cure someone, at least lower their disease
if ( pSectorInfo->usInfected && uHealpts > 0 && Disease[0].sInfectionPtsFull )
else
{
UINT32 totaldiseasepoints = pSectorInfo->usInfected * ptsneededforcure;
totaldiseasepoints = max( 0, totaldiseasepoints - uHealpts );
pSectorInfo->fInfectionSeverity = (FLOAT)totaldiseasepoints / (FLOAT)(pSectorInfo->usInfected * Disease[0].sInfectionPtsFull);
pSectorInfo->fDiseasePoints -= uHealpts;
uHealpts = 0;
}
// if there are no more infected, or infection is at 0, remove all traces of disease
if ( !pSectorInfo->usInfected || !pSectorInfo->fInfectionSeverity )
if ( pSectorInfo->fDiseasePoints <= 0 )
{
pSectorInfo->usInfected = 0;
pSectorInfo->fInfectionSeverity = 0;
pSectorInfo->usInfectionFlag &= ~(SECTORDISEASE_OUTBREAK | SECTORDISEASE_DIAGNOSED_WHO | SECTORDISEASE_DIAGNOSED_PLAYER);
pSectorInfo->usInfectionFlag &= ~(SECTORDISEASE_DIAGNOSED_PLAYER);
}
ptsused -= uHealpts;
@@ -658,7 +334,8 @@ FLOAT GetWorkforceEffectivenessWithDisease( INT8 bTownId, UINT8 usTeam )
return 1.0f;
FLOAT val = 0.0f;
UINT8 sectors = 0;
UINT16 population_healthy = 0;
UINT16 population_total = 0;
for ( UINT8 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
{
@@ -675,33 +352,29 @@ FLOAT GetWorkforceEffectivenessWithDisease( INT8 bTownId, UINT8 usTeam )
continue;
UINT8 sector = SECTOR( sX, sY );
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
SECTORINFO *pSector = &(SectorInfo[sector]);
if ( !pSectorInfo )
if ( !pSector )
continue;
UINT16 population = GetSectorPopulation( sX, sY, FALSE );
// at least 1 to be safe
UINT16 population = max(1, GetSectorPopulation( sX, sY, FALSE ) );
population_total += population;
// only civilian population is relevant here
if ( population )
{
// workforce effectivity in a sector is population minus cumulated effectivity loss of all infected, divided by entire population
val += (population - min( pSectorInfo->usInfected, population ) * pSectorInfo->fInfectionSeverity ) / population;
}
// if no population is here, then there is no part of te population that is not working, so retrun 1.0 here :-)
// this is basically a fix for players using this feature who have faulty xmls with population 0
else
{
val += 1.0f;
// workforce effectivity is linearly dependent on disease
population = max( 0, ( ( DISEASE_MAX_SECTOR - pSector->fDiseasePoints) / DISEASE_MAX_SECTOR ) * population );
}
++sectors;
population_healthy += population;
}
}
}
if ( sectors )
val /= sectors;
val = (FLOAT)(population_healthy) / (FLOAT)(population_total);
return val;
}
+4 -7
View File
@@ -60,8 +60,6 @@ enum
};
// disase flags for a sector
#define SECTORDISEASE_OUTBREAK 0x01 //1 // disease has officially broken out here - it can now be seen on the map, and the AI will try to remove it
#define SECTORDISEASE_DIAGNOSED_WHO 0x02 //2 // disease has been diagnosed by the WHO. This information can only be seen if the player has a contract with the WHO
#define SECTORDISEASE_DIAGNOSED_PLAYER 0x04 //4 // disease has been diagnosed by the player
// properties of diseases
@@ -73,6 +71,10 @@ 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 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
#define DISEASE_MAX_SECTOR 10000.0f // max disease points in a sector
typedef struct
{
UINT8 uiIndex;
@@ -138,11 +140,6 @@ INT16 GetAdjacentSector( UINT8 sector, UINT8 spdir );
// get a sector population (not the tactical one - we use an xml estimation + troops present)
UINT16 GetSectorPopulation( INT16 sX, INT16 sY, BOOLEAN fWithMilitary = TRUE );
// handle infection redistribution if people move from A to B (set sXB and sYB to negative values to simply remove infected people in A)
void PopulationMove( INT16 sXA, INT16 sYA, INT16 sXB, INT16 sYB, UINT16 usAmount );
void HandleDeathDiseaseImplications( SOLDIERTYPE *pSoldier );
void HandleDiseaseDailyRefresh();
// heal sector population, return number of points used
+8
View File
@@ -2491,7 +2491,15 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
usTextWidth = StringPixLength( sString, FONT10ARIAL ) - 10;
}
break;
case BURIAL:
sIconIndex_Assignment = 35;
fDoIcon_Assignment = TRUE;
fShowCustomText = TRUE;
bPtsAvailable = MercPtrs[pFace->ubSoldierID]->GetBurialPoints( &usMaximumPts );
swprintf( sString, L"%3.1f/%d", bPtsAvailable, usMaximumPts );
break;
}
+17
View File
@@ -2729,6 +2729,15 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] );
++cnt;
}
//////////////////// BURIAL MODIFIER
if ( Item[gpItemDescObject->usItem].usBurialModifier )
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[42], szUDBGenSecondaryStatsExplanationsTooltipText[42] );
SetRegionFastHelpText( &( gUDBFasthelpRegions[iFirstDataRegion + cnt] ), pStr );
MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] );
++cnt;
}
}
//////////////////////////////////////////////////////
@@ -6273,6 +6282,14 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 39, gItemDescGenSecondaryRegions[cnt].sLeft + sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// BURIAL MODIFIER
if ( ( Item[gpItemDescObject->usItem].usBurialModifier && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usBurialModifier ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 40, gItemDescGenSecondaryRegions[cnt].sLeft + sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
}
void DrawPropertyValueInColour( INT16 iValue, UINT8 ubNumLine, UINT8 ubNumRegion, BOOLEAN fComparisonMode, BOOLEAN fModifier, BOOLEAN fHigherBetter, UINT16 uiOverwriteColour = 0, BOOLEAN fPercentSign = FALSE )
+1
View File
@@ -201,6 +201,7 @@ enum {
BG_CROUCHEDDEFENSE, // lowers enemy cth if they fire at us while we are crouched against cover in the direction the shots come from
BG_FORTIFY_ASSIGNMENT, // modifies effectivity of 'FORTIFICATION' assignment
BG_HACKERSKILL, // hacking skill from 0 to 100, > 0 means hacking is possible
BG_BURIAL_ASSIGNMENT, // modifies effectivity of 'BURIAL' assignment
BG_MAX,
};
+4 -1
View File
@@ -1146,6 +1146,9 @@ typedef struct
// Flugente: a modifier to hacking
UINT8 usHackingModifier;
// Flugente: a modifier for burial effectiveness
UINT8 usBurialModifier;
// Flugente: advanced repair/dirt system
UINT8 usDamageChance; // chance that damage to the status will also damage the repair threshold
FLOAT dirtIncreaseFactor; // one shot causes this much dirt on a gun
@@ -1172,7 +1175,7 @@ typedef struct
// silversurfer: item provides breath regeneration bonus while resting
UINT8 ubSleepModifier;
// Flugente: spoting effectiveness
// Flugente: spotting effectiveness
INT16 usSpotting;
//JMich.BackpackClimb
+36 -7
View File
@@ -49,6 +49,7 @@
#include "Vehicles.h" // added by silversurfer
#include "ai.h" // added by Flugente
#include "PreBattle Interface.h" // added by Flugente
#include "Strategic Town Loyalty.h" // added by Flugente
#endif
#include "Animation Control.h"
@@ -677,6 +678,15 @@ INT32 AddRottingCorpse( ROTTING_CORPSE_DEFINITION *pCorpseDef )
}
}
// Flugente: update number of corpses in this sector
if ( !gbWorldSectorZ )
{
SECTORINFO *pSectorInfo = &( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )] );
if ( pSectorInfo )
pSectorInfo->usNumCorpses = giNumRottingCorpse;
}
// OK, we're done!
return( iIndex );
}
@@ -1614,7 +1624,7 @@ void VaporizeCorpse( INT32 sGridNo, INT8 asLevel, UINT16 usStructureID )
{
// Add explosion
memset( &AniParams, 0, sizeof( ANITILE_PARAMS ) );
AniParams.sGridNo = sBaseGridNo;
AniParams.sGridNo = sBaseGridNo;
// Check if on roof or not...
if ( pCorpse->def.bLevel == 0 )
@@ -1622,12 +1632,12 @@ void VaporizeCorpse( INT32 sGridNo, INT8 asLevel, UINT16 usStructureID )
else
AniParams.ubLevelID = ANI_ONROOF_LEVEL;
AniParams.sDelay = (INT16)( 80 );
AniParams.sStartFrame = 0;
AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD;
AniParams.sX = CenterX( sBaseGridNo );
AniParams.sY = CenterY( sBaseGridNo );
AniParams.sZ = (INT16)pCorpse->def.sHeightAdjustment;
AniParams.sDelay = (INT16)( 80 );
AniParams.sStartFrame = 0;
AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD;
AniParams.sX = CenterX( sBaseGridNo );
AniParams.sY = CenterY( sBaseGridNo );
AniParams.sZ = (INT16)pCorpse->def.sHeightAdjustment;
strcpy( AniParams.zCachedFile, "TILECACHE\\GEN_BLOW.STI" );
CreateAnimationTile( &AniParams );
@@ -1636,6 +1646,25 @@ void VaporizeCorpse( INT32 sGridNo, INT8 asLevel, UINT16 usStructureID )
RemoveCorpse( pCorpse->iID );
SetRenderFlags( RENDER_FLAG_FULL );
// add disease
if ( !gbWorldSectorZ )
{
SECTORINFO *pSectorInfo = &( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )] );
if ( pSectorInfo )
pSectorInfo->fDiseasePoints = min( DISEASE_MAX_SECTOR, pSectorInfo->fDiseasePoints + DISEASE_PER_ROTTINGCORPSE );
// the population doesn't like it when we blow chunks of people all over the place
INT8 bTownId = GetTownIdForSector( gWorldSectorX, gWorldSectorY );
// if NOT in a town
if ( bTownId != BLANK_SECTOR )
{
UINT32 uiLoyaltyChange = LOYALTY_PENALTY_ROTTED_CORPSE;
DecrementTownLoyalty( bTownId, uiLoyaltyChange );
}
}
if ( pCorpse->def.bLevel == 0 )
{
// Set some blood......
+1 -4
View File
@@ -4081,10 +4081,7 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse )
UpdateMilitia(militia);
}
// Flugente: disease
HandleDeathDiseaseImplications( pSoldier );
if ( TurnSoldierIntoCorpse( pSoldier, TRUE, TRUE ) )
{
*pfMadeCorpse = TRUE;
+65 -16
View File
@@ -18834,17 +18834,6 @@ void SOLDIERTYPE::Infect( UINT8 aDisease )
// 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 this guy is not of our team, note that a new infected person is in the sector
if ( this->bTeam != gbPlayerNum && aDisease == 0 && this->sDiseasePoints[0] <= 0 )
{
UINT8 sector = SECTOR( this->sSectorX, this->sSectorY );
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
if ( pSectorInfo )
++pSectorInfo->usInfected;
}
this->sDiseasePoints[aDisease] = min( this->sDiseasePoints[aDisease] + Disease[aDisease].sInfectionPtsInitial, Disease[aDisease].sInfectionPtsInitial );
if ( this->sDiseasePoints[aDisease] > Disease[aDisease].sInfectionPtsOutbreak )
@@ -19274,6 +19263,70 @@ INT16 SOLDIERTYPE::GetDiseaseResistance( )
return(val);
}
FLOAT SOLDIERTYPE::GetBurialPoints( UINT16* apCorpses )
{
if ( this->stats.bLife < OKLIFE || this->bSectorZ || ( this->usSoldierFlagMask & SOLDIER_POW ) )
return 0.0f;
if ( apCorpses )
{
SECTORINFO *pSectorInfo = &( SectorInfo[SECTOR( this->sSectorX, this->sSectorY )] );
if ( pSectorInfo )
*apCorpses = pSectorInfo->usNumCorpses;
}
// if not on correct assignment, no gain
if ( this->bAssignment != BURIAL )
return 0.0f;
UINT32 val = 4 * EffectiveStrength( this, FALSE );
ReducePointsForFatigue( this, &val );
// personality/disability modifiers
FLOAT persmodifier = 1.0f;
if ( DoesMercHaveDisability( this, HEAT_INTOLERANT ) ) persmodifier -= 0.01f;
if ( DoesMercHaveDisability( this, FEAR_OF_INSECTS ) ) persmodifier -= 0.03f;
// background modifier
persmodifier += ( this->GetBackgroundValue( BG_BURIAL_ASSIGNMENT ) ) / 100.0f;
// equipment modifier
FLOAT bestequipmentmodifier = 1.0f;
OBJECTTYPE* pObj = NULL;
INT8 invsize = (INT8)inv.size(); // remember inventorysize, so we don't call size() repeatedly
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop ) // ... for all items in our inventory ...
{
// ... if Item exists and is canteen (that can have drink points) ...
if ( inv[bLoop].exists() == true && Item[inv[bLoop].usItem].usBurialModifier )
{
OBJECTTYPE * pObj = &( this->inv[bLoop] ); // ... get pointer for this item ...
if ( pObj != NULL ) // ... if pointer is not obviously useless ...
{
for ( INT16 i = 0; i < pObj->ubNumberOfObjects; ++i )
{
FLOAT modifier = 1.0f + ( Item[inv[bLoop].usItem].usBurialModifier * ( *pObj )[i]->data.objectStatus ) / 10000.0f;
if ( modifier > bestequipmentmodifier )
bestequipmentmodifier = modifier;
}
}
}
}
FLOAT totalvalue = val * persmodifier * bestequipmentmodifier * 0.01f;
// A most awesome merc in Meduna palace, disguised as a soldier, would have a value of 1.15 * 4.63 * 2 = 10.649 at this point.
// This would be the place where we modify our intel gain rate.
return totalvalue;
}
// Flugente: hourly breath regen calculation
INT8 SOLDIERTYPE::GetSleepBreathRegeneration( )
{
@@ -19558,16 +19611,13 @@ UINT16 SOLDIERTYPE::GetInteractiveActionSkill( INT32 sGridNo, UINT8 usLevel, UIN
return 0;
FLOAT bestmodifier = 1.0f;
UINT8 bestequipmentbonus = 0;
OBJECTTYPE* pObj = NULL;
INT8 invsize = (INT8)inv.size( ); // remember inventorysize, so we don't call size() repeatedly
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop ) // ... for all items in our inventory ...
{
// ... if Item exists and is canteen (that can have drink points) ...
if ( inv[bLoop].exists( ) == true && Item[inv[bLoop].usItem].usHackingModifier )
{
OBJECTTYPE * pObj = &(this->inv[bLoop]); // ... get pointer for this item ...
@@ -19584,7 +19634,6 @@ UINT16 SOLDIERTYPE::GetInteractiveActionSkill( INT32 sGridNo, UINT8 usLevel, UIN
}
}
}
return (UINT16)(skill * bestmodifier);
}
+1
View File
@@ -1941,6 +1941,7 @@ public:
void PrintSleepDesc( CHAR16* apStr );
FLOAT GetDiseaseContactProtection(); // get percentage protection from infections via contact
INT16 GetDiseaseResistance();
FLOAT GetBurialPoints( UINT16* apCorpses );
// Flugente: hourly breath regen calculation
INT8 GetSleepBreathRegeneration();
+25 -29
View File
@@ -568,6 +568,12 @@ void DecideToAssignSniperOrders( SOLDIERCREATE_STRUCT * pp )
}
}
// Flugente: disease in a sector affects the health of any NPC spawning there.
// This causes an issue if someone enters a sector from an adjacent sector - they should be affected by their point of origin, not the current sector
// For this reason, we add a little helper variable that stores such a sector.
INT16 gsStrategicDiseaseOriginSector = -1;
SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *pubID )
{
SOLDIERTYPE Soldier;
@@ -810,50 +816,40 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
Soldier.bOldLife = Soldier.stats.bLifeMax;
// Flugente: disease can affect a soldier's health
if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && Soldier.bTeam != OUR_TEAM && Soldier.bTeam != CREATURE_TEAM && !ARMED_VEHICLE((&Soldier)) )
// not for us, and not for individual militia (their health is affected by their hourly healing instead)
if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && Soldier.bTeam != OUR_TEAM && Soldier.bTeam != CREATURE_TEAM && !ARMED_VEHICLE((&Soldier)) &&
!( Soldier.bTeam == MILITIA_TEAM && gGameExternalOptions.fIndividualMilitia && gGameExternalOptions.fIndividualMilitia_ManageHealth ) )
{
UINT8 sector = SECTOR( Soldier.sSectorX, Soldier.sSectorY );
UINT16 population = GetSectorPopulation( Soldier.sSectorX, Soldier.sSectorY );
// if this is autoresolve, we have to get the sector in a different way..
if ( guiCurrentScreen == AUTORESOLVE_SCREEN )
{
sector = GetAutoResolveSectorID( );
population = GetSectorPopulation( SECTORX( sector ), SECTORY( sector ) );
}
if ( gsStrategicDiseaseOriginSector > 0 )
sector = (UINT8)gsStrategicDiseaseOriginSector;
if ( population )
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
if ( pSectorInfo )
{
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
INT32 diseaseamount = (Disease[0].sInfectionPtsFull * pSectorInfo->fDiseasePoints) / DISEASE_MAX_SECTOR;
Soldier.AddDiseasePoints( 0, diseaseamount );
if ( pSectorInfo && pSectorInfo->usInfected )
// if disease has broken out, lower life points
if ( Soldier.sDiseaseFlag[0] & SOLDIERDISEASE_OUTBREAK )
{
UINT16 chanceofinfection = 100 * (FLOAT)(pSectorInfo->usInfected) / (FLOAT)(population);
// we only alter breath and life points here, stats effectivity will be handled automatically
FLOAT magnitude = Soldier.GetDiseaseMagnitude( 0 );
if ( Chance( chanceofinfection ) )
{
INT32 diseaseamount = Disease[0].sInfectionPtsFull * pSectorInfo->fInfectionSeverity;
Soldier.AddDiseasePoints( 0, diseaseamount );
UINT16 diseasemaxbreathreduction = Disease[0].usMaxBreath * magnitude;
// if disease has broken out, lower life points
if ( Soldier.sDiseaseFlag[0] & SOLDIERDISEASE_OUTBREAK )
{
// we only alter breath and life points here, stats effectivity will be handled automatically
FLOAT magnitude = Soldier.GetDiseaseMagnitude( 0 );
Soldier.bBreathMax = min( Soldier.bBreathMax, 100 - diseasemaxbreathreduction );
Soldier.bBreath = min( Soldier.bBreath, Soldier.bBreathMax );
UINT16 diseasemaxbreathreduction = Disease[0].usMaxBreath * magnitude;
INT8 lifereduction = (6 * Disease[0].sLifeRegenHundreds) * (magnitude / 100.0f);
Soldier.bBreathMax = min( Soldier.bBreathMax, 100 - diseasemaxbreathreduction );
Soldier.bBreath = min( Soldier.bBreath, Soldier.bBreathMax );
INT8 lifereduction = (6 * Disease[0].sLifeRegenHundreds) * (magnitude / 100);
Soldier.stats.bLifeMax = max( OKLIFE, Soldier.stats.bLifeMax + lifereduction );
Soldier.stats.bLifeMax = min( 100, Soldier.stats.bLifeMax );
Soldier.stats.bLife = min( Soldier.stats.bLife, Soldier.stats.bLifeMax );
}
}
Soldier.stats.bLife = max( OKLIFE, min(100, Soldier.stats.bLife + lifereduction) );
}
}
}
+37 -54
View File
@@ -108,7 +108,7 @@ BOOLEAN RetrieveTempFileFromSavedGame( HWFILE hFile, UINT32 uiType, INT16 sMapX,
BOOLEAN AddTempFileToSavedGame( HWFILE hFile, UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ );
BOOLEAN SaveRottingCorpsesToTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
BOOLEAN SaveRottingCorpsesToTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, std::vector<ROTTING_CORPSE_DEFINITION> aCorpseDefVector );
BOOLEAN LoadRottingCorpsesFromTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
void LoadNPCInformationFromProfileStruct();
@@ -1021,8 +1021,17 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( )
return( FALSE );
}
std::vector<ROTTING_CORPSE_DEFINITION> corpsedefvector;
//Determine how many rotting corpses there are
for ( INT32 iCount = 0; iCount < giNumRottingCorpse; ++iCount )
{
if ( gRottingCorpse[iCount].fActivated )
corpsedefvector.push_back( gRottingCorpse[iCount].def );
}
//Save the rotting corpse array to the temp rotting corpse file
if( !SaveRottingCorpsesToTempCorpseFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
if( !SaveRottingCorpsesToTempCorpseFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, corpsedefvector ) )
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in SaveRottingCorpsesToTempCorpseFile()" ) );
EnableModifiedFileSetCache(cacheResetValue);
@@ -1706,27 +1715,22 @@ BOOLEAN InitTacticalSave( BOOLEAN fCreateTempDir )
}
BOOLEAN SaveRottingCorpsesToTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
BOOLEAN SaveRottingCorpsesToTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, std::vector<ROTTING_CORPSE_DEFINITION> aCorpseDefVector )
{
HWFILE hFile;
UINT32 uiNumBytesWritten=0;
// CHAR8 zTempName[ 128 ];
CHAR8 zMapName[ 128 ];
UINT32 uiNumberOfCorpses=0;
INT32 iCount;
CHAR8 zMapName[ 128 ];
// if we have no corpses at all, we have nothing to write - erase the 'corpse file exists flag', the next time we add a corpse, a new file will be created
if ( aCorpseDefVector.empty() )
{
ReSetSectorFlag( sMapX, sMapY, bMapZ, SF_ROTTING_CORPSE_TEMP_FILE_EXISTS );
/*
//Convert the current sector location into a file name
GetMapFileName( sMapX,sMapY, bMapZ, zTempName, FALSE );
//add the 'r' for 'Rotting Corpses' to the front of the map name
sprintf( zMapName, "%s\\r_%s", MAPS_DIR, zTempName);
*/
return TRUE;
}
GetMapTempFileName( SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );
//Open the file for writing, Create it if it doesnt exist
hFile = FileOpen( zMapName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
if( hFile == 0 )
@@ -1734,16 +1738,9 @@ BOOLEAN SaveRottingCorpsesToTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ
//Error opening map modification file
return( FALSE );
}
//Determine how many rotting corpses there are
for(iCount=0; iCount < giNumRottingCorpse; iCount++)
{
if( gRottingCorpse[iCount].fActivated == TRUE )
uiNumberOfCorpses++;
}
UINT32 uiNumberOfCorpses = aCorpseDefVector.size();
//Save the number of the Rotting Corpses array table
FileWrite( hFile, &uiNumberOfCorpses, sizeof( UINT32 ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( UINT32 ) )
@@ -1754,31 +1751,26 @@ BOOLEAN SaveRottingCorpsesToTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ
}
//Loop through all the carcases in the array and save the active ones
for(iCount=0; iCount < giNumRottingCorpse; iCount++)
for( std::vector<ROTTING_CORPSE_DEFINITION>::iterator it = aCorpseDefVector.begin(); it != aCorpseDefVector.end(); ++it )
{
if( gRottingCorpse[iCount].fActivated == TRUE )
//Save the RottingCorpse info array
FileWrite( hFile, &(*it), sizeof( ROTTING_CORPSE_DEFINITION ), &uiNumBytesWritten );
if ( uiNumBytesWritten != sizeof( ROTTING_CORPSE_DEFINITION ) )
{
//Save the RottingCorpse info array
FileWrite( hFile, &gRottingCorpse[iCount].def, sizeof( ROTTING_CORPSE_DEFINITION ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( ROTTING_CORPSE_DEFINITION ) )
{
//Error Writing size of array to disk
FileClose( hFile );
return( FALSE );
}
//Error Writing size of array to disk
FileClose( hFile );
return( FALSE );
}
}
FileClose( hFile );
// Set the flag indicating that there is a rotting corpse Temp File
// SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags |= SF_ROTTING_CORPSE_TEMP_FILE_EXISTS;
SetSectorFlag( sMapX, sMapY, bMapZ, SF_ROTTING_CORPSE_TEMP_FILE_EXISTS );
return( TRUE );
}
BOOLEAN DeleteTempItemMapFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
UINT8 bSectorId = 0;
@@ -1813,26 +1805,18 @@ BOOLEAN LoadRottingCorpsesFromTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMa
{
HWFILE hFile;
UINT32 uiNumBytesRead=0;
// CHAR8 zTempName[ 128 ];
CHAR8 zMapName[ 128 ];
UINT32 uiNumberOfCorpses=0;
UINT32 cnt;
ROTTING_CORPSE_DEFINITION def;
BOOLEAN fDontAddCorpse = FALSE;
INT8 bTownId;
BOOLEAN fDontAddCorpse = FALSE;
INT8 bTownId;
//Delete the existing rotting corpse array
RemoveCorpses( );
/*
//Convert the current sector location into a file name
GetMapFileName( sMapX,sMapY, bMapZ, zTempName, FALSE );
sprintf( zMapName, "%s\\r_%s", MAPS_DIR, zTempName);
*/
GetMapTempFileName( SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );
//Check to see if the file exists
if( !FileExists( zMapName ) )
{
@@ -1864,7 +1848,7 @@ BOOLEAN LoadRottingCorpsesFromTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMa
// Get town ID for use later....
bTownId = GetTownIdForSector( gWorldSectorX, gWorldSectorY );
for( cnt=0; cnt<uiNumberOfCorpses; cnt++ )
for( cnt=0; cnt<uiNumberOfCorpses; ++cnt )
{
fDontAddCorpse = FALSE;
@@ -1876,8 +1860,7 @@ BOOLEAN LoadRottingCorpsesFromTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMa
FileClose( hFile );
return( FALSE );
}
//Check the flags to see if we have to find a gridno to place the rotting corpses at
if( def.usFlags & ROTTING_CORPSE_FIND_SWEETSPOT_FROM_GRIDNO )
{
+29 -21
View File
@@ -3367,19 +3367,23 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
//Get the gridno the cursor is at
GetMouseMapPos( &usGridNo );
//if there is a selected soldier, and the cursor location is valid
if( gusSelectedSoldier != NOBODY && !TileIsOutOfBounds(usGridNo))
// if the cursor location is valid
if ( !TileIsOutOfBounds(usGridNo) )
{
//if the cursor is over someone
if( gfUIFullTargetFound )
// if there is a selected soldier
if ( gusSelectedSoldier != NOBODY )
{
//Display the range to the target
DisplayRangeToTarget( MercPtrs[ gusSelectedSoldier ], MercPtrs[ gusUIFullTargetID ]->sGridNo );
}
else
{
//Display the range to the target
DisplayRangeToTarget( MercPtrs[ gusSelectedSoldier ], usGridNo );
//if the cursor is over someone
if ( gfUIFullTargetFound )
{
//Display the range to the target
DisplayRangeToTarget( MercPtrs[gusSelectedSoldier], MercPtrs[gusUIFullTargetID]->sGridNo );
}
else
{
//Display the range to the target
DisplayRangeToTarget( MercPtrs[gusSelectedSoldier], usGridNo );
}
}
CHAR16 zOutputString[512];
@@ -3389,7 +3393,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
// Flugente: print out structure tileset
if ( gGameExternalOptions.fPrintStructureTileset )
{
STRUCTURE * pStruct = FindStructure( usGridNo, (STRUCTURE_GENERIC) );
STRUCTURE * pStruct = FindStructure( usGridNo, ( STRUCTURE_TYPE_DEFINED ) );
if ( pStruct )
{
// if this is a multi-tile structure, be sure to use the base gridno
@@ -3420,16 +3424,20 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
}
}
}
extern BOOLEAN InARoom( INT32 sGridNo, UINT16 *pusRoomNo );
UINT16 usRoom;
if ( InARoom( usGridNo, &usRoom ) )
{
swprintf( zOutputString, L"Room number: %d", usRoom );
ScreenMsg( FONT_MCOLOR_LTGREEN, MSG_INTERFACE, zOutputString );
}
}
extern BOOLEAN InARoom( INT32 sGridNo, UINT16 *pusRoomNo );
UINT16 usRoom;
if ( InARoom( usGridNo, &usRoom ) )
{
swprintf( zOutputString, L"Room number: %d", usRoom );
ScreenMsg( FONT_MCOLOR_LTGREEN, MSG_INTERFACE, zOutputString );
}
// display height
swprintf( zOutputString, L"Floor height: %d", gpWorldLevelData[usGridNo].sHeight );
ScreenMsg( FONT_MCOLOR_LTGREEN, MSG_INTERFACE, zOutputString );
}
}
break;
+6
View File
@@ -138,6 +138,7 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha
strcmp(name, "croucheddefense" ) == 0 ||
strcmp(name, "fortify_assignment" ) == 0 ||
strcmp(name, "hackerskill" ) == 0 ||
strcmp(name, "burial_assignment" ) == 0 ||
strcmp(name, "druguse") == 0 ||
strcmp(name, "xenophobic") == 0 ||
strcmp(name, "corruptionspread") == 0 ||
@@ -597,6 +598,11 @@ backgroundEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curBackground.value[BG_HACKERSKILL] = min( 100, max( 0, (INT16)atol( pData->szCharData ) ) );
}
else if ( strcmp( name, "burial_assignment" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curBackground.value[BG_BURIAL_ASSIGNMENT] = min( 1000, max( -50, (INT16)atol( pData->szCharData ) ) );
}
else if(strcmp(name, "druguse") == 0)
{
pData->curElement = ELEMENT;
+1
View File
@@ -2960,6 +2960,7 @@ enum
// menu entries
TEXT_DISEASE_DIAGNOSIS,
TEXT_DISEASE_TREATMENT,
TEXT_DISEASE_BURIAL,
TEXT_DISEASE_CANCEL,
// (undiagnosed)
+7
View File
@@ -276,6 +276,7 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
strcmp(name, "DisarmModifier") == 0 ||
strcmp(name, "RepairModifier") == 0 ||
strcmp(name, "usHackingModifier" ) == 0 ||
strcmp(name, "usBurialModifier" ) == 0 ||
strcmp(name, "usActionItemFlag") == 0 ||
strcmp(name, "clothestype") == 0 ||
@@ -1404,6 +1405,11 @@ itemEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curItem.usHackingModifier = min(100, (UINT8)atol( pData->szCharData ) );
}
else if ( strcmp( name, "usBurialModifier" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curItem.usBurialModifier = min( 100, (UINT8)atol( pData->szCharData ) );
}
else if(strcmp(name, "DamageChance") == 0)
{
pData->curElement = ELEMENT;
@@ -2125,6 +2131,7 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile, "\t\t<DisarmModifier>%d</DisarmModifier>\r\n", Item[cnt].DisarmModifier );
FilePrintf(hFile, "\t\t<RepairModifier>%d</RepairModifier>\r\n", Item[cnt].RepairModifier );
FilePrintf(hFile, "\t\t<usHackingModifier>%d</usHackingModifier>\r\n", Item[cnt].usHackingModifier );
FilePrintf(hFile, "\t\t<usBurialModifier>%d</usBurialModifier>\r\n", Item[cnt].usBurialModifier );
FilePrintf(hFile,"\t\t<DamageChance>%d</DamageChance>\r\n", Item[cnt].usDamageChance );
FilePrintf(hFile,"\t\t<DirtIncreaseFactor>%4.2f</DirtIncreaseFactor>\r\n", Item[cnt].dirtIncreaseFactor );
+8 -1
View File
@@ -2475,6 +2475,7 @@ STR16 pAssignmentStrings[] =
L"GetIntel",
L"DoctorM.",
L"DMilitia",
L"Burial",
};
@@ -2582,6 +2583,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -2648,6 +2650,7 @@ STR16 pLongAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -6248,7 +6251,7 @@ STR16 zMarksMapScreenText[] =
L"地图概况",//"Map Overview", // 24
// Flugente: disease texts describing what a map view does //文本描述疾病查看地图并做翻译。
L"这个视图会展示出哪个地区爆发了瘟疫,这个数字表明,平均每个人的感染程度,颜色表示它的范围。 灰色=无病。 绿色到红色=不断升级的感染程度。", //L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.",
L"This view shows how many rotting corpses are in a sector. The white number are corpses, the green number is accumulated disease, the sector colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of disease.", // TODO.Translate
// Flugente: weather texts describing what a map view does
L"这个视图显示了目前的天气。没有颜色=晴天。青色为雨天。蓝色为雷暴。橙色为沙尘暴。白色为下雪",//L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.",
@@ -8444,6 +8447,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
L"|感|染|防|护", //L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39
L"|护|盾", //L"|S|h|i|e|l|d",
L"|C|a|m|e|r|a", // TODO.Translate
L"|B|u|r|i|a|l |M|o|d|i|f|i|e|r",
};
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
@@ -8490,6 +8494,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
L"\n \n如果保存在物品栏\n降低\n传染给其他人的几率。", //L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.",
L"\n \n拿在手里,就可以抵挡前方的伤害。", //L"\n \nIf equipped in a hand, this will block incoming damage.",
L"\n \nYou can take photos with this.", // TODO.Translate
L"\n \nThis item makes you more effective at burying corpses.",
};
STR16 szUDBAdvStatsTooltipText[]=
@@ -9063,6 +9068,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% 如果在蹲下状态,视野方向发现敌人,即可瞄准\n", //L" %s%d%% enemy CTH if crouched against thick cover in their direction\n",
L" %s%d%% 建设速度\n",//L" %s%d%% building speed\n",
L"黑客技能: %s%d ",//L" hacking skill: %s%d ",
L" %s%d%% burial speed\n", // TODO.Translate
};
STR16 szBackgroundTitleText[] =
@@ -10996,6 +11002,7 @@ STR16 szDiseaseText[] =
L"诊断", // L"Diagnosis",
L"治疗", //L"Treatment",
L"Burial", // TODO.Translate
L"取消", //L"Cancel", 
L"\n\n%s (未诊断的) - %d / %d\n", //L"\n\n%s (undiagnosed) - %d / %d\n",
+8 -1
View File
@@ -2474,6 +2474,7 @@ STR16 pAssignmentStrings[] =
L"GetIntel",
L"DoctorM.",
L"DMilitia",
L"Burial",
};
@@ -2581,6 +2582,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -2647,6 +2649,7 @@ STR16 pLongAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -6256,7 +6259,7 @@ STR16 zMarksMapScreenText[] =
L"Map Overview", // 24
// Flugente: disease texts describing what a map view does TODO.Translate
L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.",
L"This view shows how many rotting corpses are in a sector. The white number are corpses, the green number is accumulated disease, the sector colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of disease.", // TODO.Translate
// Flugente: weather texts describing what a map view does
L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate
@@ -8461,6 +8464,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39
L"|S|h|i|e|l|d", // TODO.Translate
L"|C|a|m|e|r|a", // TODO.Translate
L"|B|u|r|i|a|l |M|o|d|i|f|i|e|r",
};
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
@@ -8507,6 +8511,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.",
L"\n \nIf equipped in a hand, this will block incoming damage.", // TODO.Translate
L"\n \nYou can take photos with this.", // TODO.Translate
L"\n \nThis item makes you more effective at burying corpses.",
};
STR16 szUDBAdvStatsTooltipText[]=
@@ -9083,6 +9088,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% enemy CTH if crouched against thick cover in their direction\n",
L" %s%d%% building speed\n",
L" hacking skill: %s%d ", // TODO.Translate
L" %s%d%% burial speed\n", // TODO.Translate
};
STR16 szBackgroundTitleText[] = // TODO.Translate
@@ -11014,6 +11020,7 @@ STR16 szDiseaseText[] =
L"Diagnosis",
L"Treatment",
L"Burial", // TODO.Translate
L"Cancel",
L"\n\n%s (undiagnosed) - %d / %d\n", // TODO.Translate
+8 -1
View File
@@ -2475,6 +2475,7 @@ STR16 pAssignmentStrings[] =
L"GetIntel",
L"DoctorM.",
L"DMilitia",
L"Burial",
};
@@ -2582,6 +2583,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -2648,6 +2650,7 @@ STR16 pLongAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -6249,7 +6252,7 @@ STR16 zMarksMapScreenText[] =
L"Map Overview", // 24
// Flugente: disease texts describing what a map view does
L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.",
L"This view shows how many rotting corpses are in a sector. The white number are corpses, the green number is accumulated disease, the sector colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of disease.",
// Flugente: weather texts describing what a map view does
L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.",
@@ -8445,6 +8448,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39
L"|S|h|i|e|l|d",
L"|C|a|m|e|r|a",
L"|B|u|r|i|a|l |M|o|d|i|f|i|e|r",
};
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
@@ -8491,6 +8495,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.",
L"\n \nIf equipped in a hand, this will block incoming damage.",
L"\n \nYou can take photos with this.",
L"\n \nThis item makes you more effective at burying corpses.",
};
STR16 szUDBAdvStatsTooltipText[]=
@@ -9064,6 +9069,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% enemy CTH if crouched against thick cover in their direction\n",
L" %s%d%% building speed\n",
L" hacking skill: %s%d ",
L" %s%d%% burial speed\n",
};
STR16 szBackgroundTitleText[] =
@@ -10998,6 +11004,7 @@ STR16 szDiseaseText[] =
L"Diagnosis",
L"Treatment",
L"Burial",
L"Cancel",
L"\n\n%s (undiagnosed) - %d / %d\n",
+8 -1
View File
@@ -2483,6 +2483,7 @@ STR16 pAssignmentStrings[] =
L"GetIntel",
L"DoctorM.",
L"DMilitia",
L"Burial",
};
@@ -2590,6 +2591,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -2656,6 +2658,7 @@ STR16 pLongAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -6261,7 +6264,7 @@ STR16 zMarksMapScreenText[] =
L"Écran carte", // 24
// Flugente: disease texts describing what a map view does TODO.Translate
L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.",
L"This view shows how many rotting corpses are in a sector. The white number are corpses, the green number is accumulated disease, the sector colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of disease.", // TODO.Translate
// Flugente: weather texts describing what a map view does
L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate
@@ -8448,6 +8451,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39
L"|S|h|i|e|l|d", // TODO.Translate
L"|C|a|m|e|r|a", // TODO.Translate
L"|B|u|r|i|a|l |M|o|d|i|f|i|e|r",
};
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
@@ -8494,6 +8498,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.",
L"\n \nIf equipped in a hand, this will block incoming damage.", // TODO.Translate
L"\n \nYou can take photos with this.", // TODO.Translate
L"\n \nThis item makes you more effective at burying corpses.",
};
STR16 szUDBAdvStatsTooltipText[]=
@@ -9065,6 +9070,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% enemy CTH if crouched against thick cover in their direction\n",
L" %s%d%% building speed\n",
L" hacking skill: %s%d ", // TODO.Translate
L" %s%d%% burial speed\n", // TODO.Translate
};
STR16 szBackgroundTitleText[] =
@@ -10996,6 +11002,7 @@ STR16 szDiseaseText[] =
L"Diagnosis",
L"Treatment",
L"Burial", // TODO.Translate
L"Cancel",
L"\n\n%s (undiagnosed) - %d / %d\n", // TODO.Translate
+8 -1
View File
@@ -2488,6 +2488,7 @@ STR16 pAssignmentStrings[] =
L"GetIntel",
L"DoctorM.",
L"DMilitia",
L"Burial",
};
STR16 pMilitiaString[] =
@@ -2591,6 +2592,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
// refer to above for comments
@@ -2655,6 +2657,7 @@ STR16 pLongAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
// the contract options
@@ -6101,7 +6104,7 @@ STR16 zMarksMapScreenText[] =
L"Kartenübersicht", // 24
// Flugente: disease texts describing what a map view does TODO.Translate
L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.",
L"This view shows how many rotting corpses are in a sector. The white number are corpses, the green number is accumulated disease, the sector colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of disease.", // TODO.Translate
// Flugente: weather texts describing what a map view does
L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate
@@ -8277,6 +8280,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39
L"|S|h|i|e|l|d", // TODO.Translate
L"|C|a|m|e|r|a", // TODO.Translate
L"|B|u|r|i|a|l |M|o|d|i|f|i|e|r",
};
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
@@ -8323,6 +8327,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.",
L"\n \nIf equipped in a hand, this will block incoming damage.", // TODO.Translate
L"\n \nYou can take photos with this.", // TODO.Translate
L"\n \nThis item makes you more effective at burying corpses.",
};
STR16 szUDBAdvStatsTooltipText[]=
@@ -8895,6 +8900,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% enemy CTH if crouched against thick cover in their direction\n",
L" %s%d%% building speed\n",
L" hacking skill: %s%d ", // TODO.Translate
L" %s%d%% burial speed\n", // TODO.Translate
};
STR16 szBackgroundTitleText[] = // TODO.Translate
@@ -10826,6 +10832,7 @@ STR16 szDiseaseText[] =
L"Diagnosis",
L"Treatment",
L"Burial", // TODO.Translate
L"Cancel",
L"\n\n%s (undiagnosed) - %d / %d\n", // TODO.Translate
+8 -1
View File
@@ -2469,6 +2469,7 @@ STR16 pAssignmentStrings[] =
L"GetIntel",
L"DoctorM.",
L"DMilitia",
L"Burial",
};
@@ -2576,6 +2577,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -2642,6 +2644,7 @@ STR16 pLongAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -6239,7 +6242,7 @@ STR16 zMarksMapScreenText[] =
L"Il contratto del mercenario non è assicurato",
// Flugente: disease texts describing what a map view does TODO.Translate
L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.",
L"This view shows how many rotting corpses are in a sector. The white number are corpses, the green number is accumulated disease, the sector colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of disease.", // TODO.Translate
// Flugente: weather texts describing what a map view does
L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate
@@ -8451,6 +8454,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39
L"|S|h|i|e|l|d", // TODO.Translate
L"|C|a|m|e|r|a", // TODO.Translate
L"|B|u|r|i|a|l |M|o|d|i|f|i|e|r",
};
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
@@ -8497,6 +8501,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.",
L"\n \nIf equipped in a hand, this will block incoming damage.", // TODO.Translate
L"\n \nYou can take photos with this.", // TODO.Translate
L"\n \nThis item makes you more effective at burying corpses.",
};
STR16 szUDBAdvStatsTooltipText[]=
@@ -9074,6 +9079,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% enemy CTH if crouched against thick cover in their direction\n",
L" %s%d%% building speed\n",
L" hacking skill: %s%d ", // TODO.Translate
L" %s%d%% burial speed\n", // TODO.Translate
};
STR16 szBackgroundTitleText[] = // TODO.Translate
@@ -11005,6 +11011,7 @@ STR16 szDiseaseText[] =
L"Diagnosis",
L"Treatment",
L"Burial", // TODO.Translate
L"Cancel",
L"\n\n%s (undiagnosed) - %d / %d\n", // TODO.Translate
+8 -1
View File
@@ -2481,6 +2481,7 @@ STR16 pAssignmentStrings[] =
L"GetIntel",
L"DoctorM.",
L"DMilitia",
L"Burial",
};
@@ -2588,6 +2589,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -2654,6 +2656,7 @@ STR16 pLongAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -6257,7 +6260,7 @@ STR16 zMarksMapScreenText[] =
L"Mapa", // 24
// Flugente: disease texts describing what a map view does TODO.Translate
L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.",
L"This view shows how many rotting corpses are in a sector. The white number are corpses, the green number is accumulated disease, the sector colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of disease.", // TODO.Translate
// Flugente: weather texts describing what a map view does
L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate
@@ -8463,6 +8466,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39
L"|S|h|i|e|l|d", // TODO.Translate
L"|C|a|m|e|r|a", // TODO.Translate
L"|B|u|r|i|a|l |M|o|d|i|f|i|e|r",
};
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
@@ -8509,6 +8513,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.",
L"\n \nIf equipped in a hand, this will block incoming damage.", // TODO.Translate
L"\n \nYou can take photos with this.", // TODO.Translate
L"\n \nThis item makes you more effective at burying corpses.",
};
STR16 szUDBAdvStatsTooltipText[]=
@@ -9087,6 +9092,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% enemy CTH if crouched against thick cover in their direction\n",
L" %s%d%% building speed\n",
L" hacking skill: %s%d ", // TODO.Translate
L" %s%d%% burial speed\n", // TODO.Translate
};
STR16 szBackgroundTitleText[] = // TODO.Translate
@@ -11018,6 +11024,7 @@ STR16 szDiseaseText[] =
L"Diagnosis",
L"Treatment",
L"Burial", // TODO.Translate
L"Cancel",
L"\n\n%s (undiagnosed) - %d / %d\n", // TODO.Translate
+8 -1
View File
@@ -2475,6 +2475,7 @@ STR16 pAssignmentStrings[] =
L"GetIntel",
L"DoctorM.",
L"DMilitia",
L"Burial",
};
@@ -2582,6 +2583,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -2648,6 +2650,7 @@ STR16 pLongAssignmentStrings[] =
L"Get intel while disguised",
L"Doctor wounded militia",
L"Drill existing militia",
L"Bury corpses",
};
@@ -6249,7 +6252,7 @@ STR16 zMarksMapScreenText[] =
L"Стратегическая карта",
// Flugente: disease texts describing what a map view does
L"Здесь показаны вспышки заболеваний по секторам. Число указывает средний показатель инфекции на человека, цвет - насколько широко распространена инфекция. СЕРЫЙ= нет информации о заболеваемости. ЗЕЛЁНЫЙ - КРАСНЫЙ = уровень роста заболеваемости.",
L"This view shows how many rotting corpses are in a sector. The white number are corpses, the green number is accumulated disease, the sector colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of disease.", // TODO.Translate
// Flugente: weather texts describing what a map view does
L"Здесь паказана актуальная погода. Без цвета=солнечно, зеленый=дождь, Синий=Гроза, Оранжевый=песчаная буря, Белый=снег.",
@@ -8445,6 +8448,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
L"|И|н|ф|е|к|ц|и|о|н|н|а|я |з|а|щ|и|т|а", // 39
L"|S|h|i|e|l|d", // TODO.Translate
L"|C|a|m|e|r|a", // TODO.Translate
L"|B|u|r|i|a|l |M|o|d|i|f|i|e|r",
};
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
@@ -8491,6 +8495,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
L"\n \nЕсли хранить в своём кармане,\nпонижается шанс заражения\n от других людей.",
L"\n \nIf equipped in a hand, this will block incoming damage.", // TODO.Translate
L"\n \nYou can take photos with this.", // TODO.Translate
L"\n \nThis item makes you more effective at burying corpses.",
};
STR16 szUDBAdvStatsTooltipText[]=
@@ -9064,6 +9069,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% enemy CTH if crouched against thick cover in their direction\n",
L" %s%d%% кровотечение\n",
L" Взлом: %s%d ",
L" %s%d%% burial speed\n", // TODO.Translate
};
STR16 szBackgroundTitleText[] =
@@ -10998,6 +11004,7 @@ STR16 szDiseaseText[] =
L"Обследование",
L"Лечение населения",
L"Burial", // TODO.Translate
L"Отмена",
L"\n\n%s (недиагностирована) - %d / %d\n",