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