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
+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;