mirror of
https://github.com/1dot13/source.git
synced 2026-09-02 14:36:06 +02:00
New feature: Diseaes affect your mercenaries. They can be contracted in varíous ways and have varying effects.
For more info, see http://www.ja-galaxy-forum.com/ubbthreads.php/topics/334918#Post334918 Requires GameDir >= r2099. Does not break savegame compatibility. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7384 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+11
-10
@@ -7,16 +7,17 @@
|
||||
#include "tile animation.h"
|
||||
|
||||
|
||||
#define BULLET_FLAG_CREATURE_SPIT 0x0001
|
||||
#define BULLET_FLAG_KNIFE 0x0002
|
||||
#define BULLET_FLAG_MISSILE 0x0004
|
||||
#define BULLET_FLAG_SMALL_MISSILE 0x0008
|
||||
#define BULLET_STOPPED 0x0010
|
||||
#define BULLET_FLAG_TANK_CANNON 0x0020
|
||||
#define BULLET_FLAG_BUCKSHOT 0x0040
|
||||
#define BULLET_FLAG_FLAME 0x0080
|
||||
#define BULLET_FLAG_TRACER 0x0100
|
||||
#define BULLET_FLAG_ANTIMATERIEL 0x0200 // Flugente: bullet can destroy structures
|
||||
#define BULLET_FLAG_CREATURE_SPIT 0x0001
|
||||
#define BULLET_FLAG_KNIFE 0x0002
|
||||
#define BULLET_FLAG_MISSILE 0x0004
|
||||
#define BULLET_FLAG_SMALL_MISSILE 0x0008
|
||||
#define BULLET_STOPPED 0x0010
|
||||
#define BULLET_FLAG_TANK_CANNON 0x0020
|
||||
#define BULLET_FLAG_BUCKSHOT 0x0040
|
||||
#define BULLET_FLAG_FLAME 0x0080
|
||||
#define BULLET_FLAG_TRACER 0x0100
|
||||
#define BULLET_FLAG_ANTIMATERIEL 0x0200 // Flugente: bullet can destroy structures
|
||||
#define BULLET_FLAG_INFECTED 0x0400 // Flugente: bullet is infected
|
||||
|
||||
//afp-start calculate line points between two point
|
||||
#define BULLET_TRACER_MAX_LENGTH 60
|
||||
|
||||
@@ -1269,11 +1269,9 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTar
|
||||
CHAR16 gzTauntQuote[ 320 ];
|
||||
UINT16 iApplicableTaunts = 0;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: zombies don't talk
|
||||
if ( pCiv->IsZombie() )
|
||||
return;
|
||||
#endif
|
||||
|
||||
// gCivQuoteData.bActive is checked in ShowTauntPopupBox() instead, taunt can be shown in log though!
|
||||
// if we have a different quote on, return, this one is not important
|
||||
@@ -1720,9 +1718,7 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTar
|
||||
if( zTaunt[ i ].uiFlags2 & TAUNT_T_ZOMBIE )
|
||||
{
|
||||
// anv: moved ifdef - if zombies are off, we want to skip any taunts with TAUNT_T_ZOMBIE flag
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if( pTarget->IsZombie() == FALSE )
|
||||
#endif
|
||||
if( !pTarget->IsZombie() )
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,727 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Flugente (bears-pit.com)
|
||||
*/
|
||||
|
||||
#include "Disease.h"
|
||||
|
||||
#include "Overhead.h"
|
||||
#include "random.h"
|
||||
#include "Assignments.h"
|
||||
#include "message.h"
|
||||
#include "Soldier Profile.h"
|
||||
#include "Map Screen Interface Map.h"
|
||||
#include "Queen Command.h"
|
||||
#include "Quests.h"
|
||||
#include "finances.h"
|
||||
#include "Game Clock.h"
|
||||
#include "LaptopSave.h"
|
||||
#include "strategic.h"
|
||||
#include "DynamicDialogue.h"
|
||||
|
||||
//GLOBALS
|
||||
DISEASE Disease[NUM_DISEASES];
|
||||
|
||||
extern SECTOR_EXT_DATA SectorExternalData[256][4];
|
||||
|
||||
// if disease in a sector is high enough, there is a chance that neighbouring sectors can be affected too
|
||||
#define DISEASE_STRATEGIC_ADJACENTINFECTION 0.3
|
||||
|
||||
#define MAPROWS (MAP_WORLD_X - 2)
|
||||
#define MAPCOLS (MAP_WORLD_Y - 2)
|
||||
|
||||
// percentage of population that has at least some medical skill
|
||||
FLOAT GetCivPopulationDoctorRate( ) { return 0.1f; }
|
||||
|
||||
// percentage of army population that has at least some medical skill
|
||||
FLOAT GetMilitaryPopulationDoctorRate( ) { return 0.34f; }
|
||||
|
||||
// healing points of a population doctor
|
||||
FLOAT GetPopulationDoctorPoints( ) { return 20; }
|
||||
|
||||
// if this fraction of a sector's population is infected, outbreak is declared regardless of infection severity
|
||||
// Otherwise infection would be untreatable at this point
|
||||
FLOAT GetSectorDiseaseOverFlowThreshold( )
|
||||
{
|
||||
/* disease in a sector is automatically revealed if the mean severity breaches the outbreak threshold
|
||||
* however, we add a second condition: if a high enough percentage of the population is infected, disease is also revealed
|
||||
* the reason is that otherwise the AI might have no chance at all to combat an outbreak
|
||||
* It thus follows that
|
||||
* population * percentage of doctors * healing points per doctor == population * disease overflow threshold * infection gain per hour
|
||||
* which leads to
|
||||
* disease overflow threshold = percentage of doctors * healing points per doctor / infection gain per hour
|
||||
*/
|
||||
if ( Disease[0].sInfectionPtsGainPerHour > 0 )
|
||||
return GetCivPopulationDoctorRate( ) * GetPopulationDoctorPoints( ) / (FLOAT)Disease[0].sInfectionPtsGainPerHour;
|
||||
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
void HandleDisease()
|
||||
{
|
||||
if ( !gGameExternalOptions.fDisease )
|
||||
return;
|
||||
|
||||
SOLDIERTYPE *pSoldier = NULL;
|
||||
UINT32 uiCnt = 0;
|
||||
|
||||
// increase existing diseases
|
||||
for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, ++pSoldier )
|
||||
{
|
||||
if ( pSoldier->bActive )
|
||||
{
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
{
|
||||
if ( pSoldier->sDiseasePoints[i] > 0 )
|
||||
{
|
||||
// add disease points - some diseases can reverse on certain states
|
||||
if ( pSoldier->sDiseaseFlag[i] & SOLDIERDISEASE_REVERSEAL )
|
||||
pSoldier->AddDiseasePoints( i, -Disease[i].sInfectionPtsGainPerHour );
|
||||
else
|
||||
pSoldier->AddDiseasePoints( i, Disease[i].sInfectionPtsGainPerHour );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// chance for infection due to proximity to other mercs
|
||||
for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, ++pSoldier )
|
||||
{
|
||||
if ( pSoldier->bActive && pSoldier->stats.bLife > 0 )
|
||||
{
|
||||
// loop over all other soldiers and determine the chance that they will infect us
|
||||
SOLDIERTYPE *pTeamSoldier = NULL;
|
||||
UINT32 uiCnt2 = 0;
|
||||
|
||||
// chance for infection due to proximity to other mercs
|
||||
for ( uiCnt2 = 0, pTeamSoldier = MercPtrs[uiCnt2]; uiCnt2 <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt2, ++pTeamSoldier )
|
||||
{
|
||||
if ( pTeamSoldier->bActive && pTeamSoldier != pSoldier
|
||||
&& pTeamSoldier->sSectorX == pSoldier->sSectorX && pTeamSoldier->sSectorY == pSoldier->sSectorY && pTeamSoldier->bSectorZ == pSoldier->bSectorZ
|
||||
&& pTeamSoldier->stats.bLife > 0 )
|
||||
{
|
||||
// infection chance gets modified depending on assignments
|
||||
FLOAT modifier = 1.0f;
|
||||
|
||||
// if both are in the same squad, chance is increased
|
||||
if ( pTeamSoldier->bAssignment == pSoldier->bAssignment && pSoldier->bAssignment < ON_DUTY )
|
||||
modifier = 1.5;
|
||||
// doctor-patient relations increase chance even more
|
||||
else if ( (pTeamSoldier->bAssignment == DOCTOR || pTeamSoldier->bAssignment == PATIENT) && (pSoldier->bAssignment == DOCTOR || pSoldier->bAssignment == PATIENT) )
|
||||
modifier = 4;
|
||||
|
||||
// we might get a disease from this...
|
||||
HandlePossibleInfection( pSoldier, pTeamSoldier, INFECTION_TYPE_CONTACT_HUMAN, modifier );
|
||||
}
|
||||
}
|
||||
|
||||
// we can also be infected by the population
|
||||
if ( gGameExternalOptions.fDiseaseStrategic )
|
||||
{
|
||||
UINT16 population = GetSectorPopulation( pSoldier->sSectorX, pSoldier->sSectorY );
|
||||
|
||||
if ( population )
|
||||
{
|
||||
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
|
||||
UINT32 usChance = Disease[0].usInfectionChance[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 )
|
||||
{
|
||||
if ( Chance( usChance ) )
|
||||
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 )
|
||||
{
|
||||
if ( Chance( Disease[0].usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN] ) )
|
||||
{
|
||||
FLOAT infectedseverity = (FLOAT)Disease[0].sInfectionPtsInitial / (FLOAT)Disease[0].sInfectionPtsFull;
|
||||
|
||||
pSectorInfo->fInfectionSeverity = (pSectorInfo->fInfectionSeverity * pSectorInfo->usInfected + infectedseverity * 1) / (pSectorInfo->usInfected + 1);
|
||||
++pSectorInfo->usInfected;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we are infected, this might disgust other people
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
{
|
||||
if ( (Disease[i].usDiseaseProperties & DISEASE_PROPERTY_DISGUSTING) && (pSoldier->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED) )
|
||||
{
|
||||
HandleDynamicOpinionChange( pSoldier, OPINIONEVENT_DISEASE_DISGUSTING, TRUE, TRUE );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// chance for infection due sector
|
||||
for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, ++pSoldier )
|
||||
{
|
||||
if ( pSoldier->bActive )
|
||||
{
|
||||
UINT8 ubSector = (UINT8)SECTOR( pSoldier->sSectorX, pSoldier->sSectorY );
|
||||
UINT8 ubTraverseType = SectorInfo[ubSector].ubTraversability[pSoldier->ubDirection];
|
||||
|
||||
switch ( ubTraverseType )
|
||||
{
|
||||
case TROPICS_SAM_SITE:
|
||||
case TROPICS:
|
||||
case TROPICS_ROAD:
|
||||
{
|
||||
HandlePossibleInfection( pSoldier, NULL, INFECTION_TYPE_TROPICS );
|
||||
}
|
||||
break;
|
||||
case SWAMP:
|
||||
case SWAMP_ROAD:
|
||||
{
|
||||
HandlePossibleInfection( pSoldier, NULL, INFECTION_TYPE_SWAMP );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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:
|
||||
{
|
||||
UINT32 usChance = Disease[0].usInfectionChance[INFECTION_TYPE_TROPICS];
|
||||
for ( UINT16 i = 0; i < lefttoinfect; ++i )
|
||||
{
|
||||
if ( Chance( usChance) )
|
||||
++newinfected;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SWAMP:
|
||||
case SWAMP_ROAD:
|
||||
{
|
||||
UINT32 usChance = Disease[0].usInfectionChance[INFECTION_TYPE_SWAMP];
|
||||
for ( UINT16 i = 0; i < lefttoinfect; ++i )
|
||||
{
|
||||
if ( Chance( usChance ) )
|
||||
++newinfected;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( lefttoinfect - newinfected > 1 && pSectorInfo->usInfected )
|
||||
{
|
||||
// infection is also possible by human contact
|
||||
UINT32 usChance = Disease[0].usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN];
|
||||
UINT16 max = sqrt( min( lefttoinfect - newinfected, pSectorInfo->usInfected ) );
|
||||
for ( UINT16 i = 0; i < max; ++i )
|
||||
{
|
||||
if ( Chance( usChance ) )
|
||||
++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( min( lefttoinfect, pSectorInfo->usInfected + newinfected ) ) * 0.5f;
|
||||
|
||||
FLOAT chance_sex = Disease[0].usInfectionChance[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].usInfectionChance[INFECTION_TYPE_CONTACT_CORPSE] * populationpercentage;
|
||||
|
||||
if ( Chance( chance_sex ) )
|
||||
++newinfected;
|
||||
|
||||
if ( Chance( chance_corpse ) )
|
||||
++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].usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN]) / (FLOAT)(100 * population);
|
||||
|
||||
if ( Chance( 100 * percentage ) )
|
||||
++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 += NumEnemiesInSector( sX, sY ) * 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)
|
||||
void HandlePossibleInfection( SOLDIERTYPE *pSoldier, SOLDIERTYPE* pOtherSoldier, UINT8 aInfectionType, FLOAT aModifier, BOOLEAN fStrategicOnly )
|
||||
{
|
||||
// only for living mercs with a profile with a valid infection method
|
||||
if ( !pSoldier || pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || pSoldier->ubProfile == NO_PROFILE || aInfectionType >= INFECTION_TYPE_MAX )
|
||||
return;
|
||||
|
||||
int max = fStrategicOnly ? 1 : NUM_DISEASES;
|
||||
for ( int i = 0; i < max; ++i )
|
||||
{
|
||||
// do not infect us if we are already infected
|
||||
if ( !(Disease[i].usDiseaseProperties & DISEASE_PROPERTY_CANREINFECT) && pSoldier->sDiseasePoints[i] > 0 )
|
||||
continue;
|
||||
|
||||
// chance of infection by insects
|
||||
UINT32 usChance = Disease[i].usInfectionChance[aInfectionType];
|
||||
|
||||
// alter chance by modifier and disease resistance
|
||||
usChance = usChance * aModifier * ( 100 - pSoldier->GetDiseaseResistance( ) ) / 100;
|
||||
|
||||
if ( aInfectionType == INFECTION_TYPE_TROPICS || aInfectionType == INFECTION_TYPE_SWAMP )
|
||||
{
|
||||
// if we are afraid of insects, we will be more careful around them - lower chance to be infected
|
||||
if ( gMercProfiles[pSoldier->ubProfile].bDisability == FEAR_OF_INSECTS )
|
||||
usChance *= 0.7f;
|
||||
}
|
||||
else if ( aInfectionType == INFECTION_TYPE_CONTACT_HUMAN )
|
||||
{
|
||||
// if we check a specific soldier, he must have the disease himself
|
||||
if ( pOtherSoldier && pOtherSoldier->sDiseasePoints[i] <= 0 )
|
||||
usChance = 0;
|
||||
|
||||
// if we wear face or hand protection, lower chance of infection
|
||||
usChance *= (1.0f - pSoldier->GetDiseaseContactProtection( ));
|
||||
}
|
||||
else if ( aInfectionType == INFECTION_TYPE_CONTACT_CORPSE )
|
||||
{
|
||||
// if we wear face or hand protection, lower chance of infection
|
||||
usChance *= (1.0f - pSoldier->GetDiseaseContactProtection( ));
|
||||
}
|
||||
|
||||
if ( Chance( usChance ) )
|
||||
{
|
||||
// infect us
|
||||
pSoldier->Infect( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return number of adjacent sector or -1 if there is none
|
||||
INT16 GetAdjacentSector( UINT8 sector, UINT8 spdir )
|
||||
{
|
||||
switch ( spdir )
|
||||
{
|
||||
case SP_UP:
|
||||
if ( SECTORY( sector ) > 0 )
|
||||
return sector - MAPCOLS;
|
||||
break;
|
||||
|
||||
case SP_LEFT:
|
||||
if ( SECTORX( sector ) > 0 )
|
||||
return sector - 1;
|
||||
break;
|
||||
|
||||
case SP_RIGHT:
|
||||
if ( SECTORX( sector ) < MAPCOLS )
|
||||
return sector + 1;
|
||||
break;
|
||||
|
||||
case SP_DOWN:
|
||||
if ( SECTORY( sector ) < MAPCOLS )
|
||||
return sector + MAPCOLS;
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// get a sector population (not the tactical one - we use an xml estimation + troops present)
|
||||
UINT16 GetSectorPopulation( INT16 sX, INT16 sY, BOOLEAN fWithMilitary )
|
||||
{
|
||||
UINT8 sector = SECTOR( sX, sY );
|
||||
|
||||
UINT16 population = SectorExternalData[sector][0].usCivilianPopulation;
|
||||
|
||||
if ( fWithMilitary )
|
||||
{
|
||||
// add number of enemies...
|
||||
UINT16 sNumberOfEnemies = NumEnemiesInSector( sX, sY );
|
||||
population += sNumberOfEnemies;
|
||||
}
|
||||
|
||||
return population;
|
||||
}
|
||||
|
||||
// colour for a sector on the map
|
||||
INT32 GetMapColour( INT16 sX, INT16 sY, UINT8 mode )
|
||||
{
|
||||
UINT8 sector = SECTOR( sX, sY );
|
||||
|
||||
switch ( mode )
|
||||
{
|
||||
case MAPMODE_DISEASE:
|
||||
{
|
||||
UINT16 population = GetSectorPopulation( sX, sY );
|
||||
|
||||
if ( population )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return MAP_SHADE_DK_GREY;
|
||||
}
|
||||
|
||||
// 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 )
|
||||
(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 )
|
||||
{
|
||||
gubFact[FACT_DISEASE_WHODATA_ACCESS] = TRUE;
|
||||
|
||||
AddTransactionToPlayersBook( WHO_SUBSCRIPTION, 0, GetWorldTotalMin( ), (-1) * (INT32)gGameExternalOptions.sDiseaseWHOSubscriptionCost );
|
||||
}
|
||||
else
|
||||
{
|
||||
gubFact[FACT_DISEASE_WHODATA_ACCESS] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// heal sector population, return number of points used
|
||||
UINT32 HealSectorPopulation( INT16 sX, INT16 sY, UINT32 uHealpts )
|
||||
{
|
||||
// how many points are needed to cure all disease?
|
||||
UINT8 sector = SECTOR( sX, sY );
|
||||
|
||||
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
|
||||
|
||||
if ( !pSectorInfo )
|
||||
return 0;
|
||||
|
||||
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 )
|
||||
{
|
||||
uHealpts -= ptsneededforcure;
|
||||
--pSectorInfo->usInfected;
|
||||
}
|
||||
|
||||
// if there are still points let, but we cannot cure someone, at least lower their disease
|
||||
if ( pSectorInfo->usInfected && uHealpts > 0 && Disease[0].sInfectionPtsFull )
|
||||
{
|
||||
UINT32 totaldiseasepoints = pSectorInfo->usInfected * ptsneededforcure;
|
||||
totaldiseasepoints = max( 0, totaldiseasepoints - uHealpts );
|
||||
|
||||
pSectorInfo->fInfectionSeverity = (FLOAT)totaldiseasepoints / (FLOAT)(pSectorInfo->usInfected * Disease[0].sInfectionPtsFull);
|
||||
}
|
||||
|
||||
// if there are no more infected, or infection is at 0, remove all traces of disease
|
||||
if ( !pSectorInfo->usInfected || !pSectorInfo->fInfectionSeverity )
|
||||
{
|
||||
pSectorInfo->usInfected = 0;
|
||||
pSectorInfo->fInfectionSeverity = 0;
|
||||
pSectorInfo->usInfectionFlag &= ~(SECTORDISEASE_OUTBREAK | SECTORDISEASE_DIAGNOSED_WHO | SECTORDISEASE_DIAGNOSED_PLAYER);
|
||||
}
|
||||
|
||||
ptsused -= uHealpts;
|
||||
|
||||
return ptsused;
|
||||
}
|
||||
|
||||
// Flugente: get workforce effectiveness with regards to strategic disease
|
||||
FLOAT GetWorkforceEffectivenessWithDisease( INT8 bTownId, UINT8 usTeam )
|
||||
{
|
||||
if ( !gGameExternalOptions.fDisease || !gGameExternalOptions.fDiseaseStrategic )
|
||||
return 1.0f;
|
||||
|
||||
FLOAT val = 0.0f;
|
||||
UINT8 sectors = 0;
|
||||
|
||||
for ( UINT8 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
|
||||
{
|
||||
for ( UINT8 sY = 1; sY < MAP_WORLD_X - 1; ++sY )
|
||||
{
|
||||
UINT16 strategicsector = CALCULATE_STRATEGIC_INDEX( sX, sY );
|
||||
|
||||
if ( StrategicMap[strategicsector].bNameId == bTownId )
|
||||
{
|
||||
// if we check for the player team, we look for sectors free of the enemy
|
||||
if ( OUR_TEAM == usTeam && StrategicMap[strategicsector].fEnemyControlled )
|
||||
continue;
|
||||
else if ( ENEMY_TEAM == usTeam && !StrategicMap[strategicsector].fEnemyControlled )
|
||||
continue;
|
||||
|
||||
UINT8 sector = SECTOR( sX, sY );
|
||||
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
|
||||
|
||||
if ( !pSectorInfo )
|
||||
continue;
|
||||
|
||||
UINT16 population = GetSectorPopulation( sX, sY, FALSE );
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
++sectors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( sectors )
|
||||
val /= sectors;
|
||||
|
||||
return val;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
#ifndef __DISEASE_H
|
||||
#define __DISEASE_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @author Flugente (bears-pit.com)
|
||||
*/
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
// number of different diseases. Altering this will alter the size of INT32 sDiseasePoints[NUM_DISEASES]; in SOLDIERTYPE
|
||||
#define NUM_DISEASES 20
|
||||
|
||||
#include "Soldier Control.h"
|
||||
|
||||
// infection types - how can we be infected
|
||||
enum
|
||||
{
|
||||
// infection depending on sector type
|
||||
INFECTION_TYPE_SWAMP = 0,
|
||||
INFECTION_TYPE_TROPICS,
|
||||
|
||||
// infection by having sex
|
||||
INFECTION_TYPE_SEX,
|
||||
|
||||
// infection by contact with lifeforms
|
||||
INFECTION_TYPE_CONTACT_HUMAN, // infection by human interaction
|
||||
INFECTION_TYPE_CONTACT_CORPSE, // infection by interacting with corpses
|
||||
|
||||
// infections when taking damage
|
||||
INFECTION_TYPE_WOUND_ANIMAL, // wounded by an animal (bloodcat)
|
||||
INFECTION_TYPE_WOUND_OPEN, // we have a new non-bandaged wound
|
||||
INFECTION_TYPE_WOUND_GUNSHOT, // we were wounded by gunshot
|
||||
|
||||
// wound caused statloss
|
||||
INFECTION_TYPE_WOUND_AGI,
|
||||
INFECTION_TYPE_WOUND_DEX,
|
||||
INFECTION_TYPE_WOUND_STR,
|
||||
INFECTION_TYPE_WOUND_WIS,
|
||||
|
||||
INFECTION_TYPE_TRAUMATIC, // certain events traumatized us
|
||||
|
||||
// infection by bad foodstuff
|
||||
INFECTION_TYPE_BADFOOD,
|
||||
INFECTION_TYPE_BADWATER,
|
||||
|
||||
INFECTION_TYPE_MAX
|
||||
};
|
||||
|
||||
// stats that can be affected
|
||||
enum
|
||||
{
|
||||
INFST_AGI = 0,
|
||||
INFST_DEX,
|
||||
INFST_STR,
|
||||
INFST_WIS,
|
||||
INFST_EXP,
|
||||
|
||||
INFST_MAX
|
||||
};
|
||||
|
||||
// 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
|
||||
#define DISEASE_PROPERTY_CANBECURED 0x00000001 // this disease can be healed by doctoring
|
||||
#define DISEASE_PROPERTY_REVERSEONFULL 0x00000002 // once sInfectionPtsFull are reached, the infection reverses - negative sInfectionPtsGainPerHour is used
|
||||
#define DISEASE_PROPERTY_CANREINFECT 0x00000004 // infection can be reapplied if already infected
|
||||
#define DISEASE_PROPERTY_HIDESYMBOL 0x00000008 // do not show a symbol for this disease on the merc's face, even if diagnosed
|
||||
|
||||
#define DISEASE_PROPERTY_DISGUSTING 0x00000010 // other merc's will be disgusted by anyone with this disease if broken out
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 uiIndex;
|
||||
CHAR16 szName[80]; // name of disease, used for display
|
||||
CHAR16 szFatName[80]; // name of disease, used for display
|
||||
CHAR16 szDescription[256]; // a short description of the disease. Observe and learn, kids!
|
||||
|
||||
// diseases are measured in disease points
|
||||
INT32 sInfectionPtsInitial; // number of points gained on infection
|
||||
INT32 sInfectionPtsOutbreak; // at this many points, the disease breaks out - effects start and one can see it
|
||||
INT32 sInfectionPtsFull; // the nominal point of a full-blown infection. Effects are scaled towards this
|
||||
INT32 sInfectionPtsGainPerHour; // extra points gained every hour if infected
|
||||
|
||||
// infection chances and behaviour
|
||||
UINT8 usInfectionChance[INFECTION_TYPE_MAX]; // percentage chance of being infected this way if conditions are fulfilled
|
||||
UINT32 usDiseaseProperties; // properties of the disease
|
||||
|
||||
// effects of disease (effect at sInfectionPtsFull points), scaled
|
||||
INT8 sEffStat[INFST_MAX]; // stat effectivity is altered
|
||||
INT8 sEffAP; // alter APs
|
||||
UINT8 usMaxBreath; // max Breath is lowered by this percentage
|
||||
INT8 sEffCarryStrength; // carrying strength
|
||||
INT16 sLifeRegenHundreds; // alter hourly life regen by these hundreds
|
||||
INT8 sNeedToSleep; // +/- need to sleep
|
||||
INT16 sDrinkModifier; // +/- % water consumption
|
||||
INT16 sFoodModifier; // +/- % water consumption
|
||||
} DISEASE;
|
||||
|
||||
//GLOBALS
|
||||
extern DISEASE Disease[NUM_DISEASES];
|
||||
|
||||
void HandleDisease();
|
||||
|
||||
// handle possible infection of type aInfectionType to pSoldier. Possible related to pOtherSoldier (can be NULL !)
|
||||
// chance gets modified by aModifier (contextual modifier)
|
||||
// if fStrategicOnly == TRUE, then we only handle disease 0
|
||||
void HandlePossibleInfection( SOLDIERTYPE *pSoldier, SOLDIERTYPE* pOtherSoldier, UINT8 aInfectionType, FLOAT aModifier = 1.0f, BOOLEAN fStrategicOnly = FALSE );
|
||||
|
||||
////////////// STRATEGIC DISEASE //////////////////////////
|
||||
|
||||
enum
|
||||
{
|
||||
MAPMODE_OFF = 0,
|
||||
MAPMODE_DISEASE,
|
||||
|
||||
MAPMODE_MAX,
|
||||
};
|
||||
|
||||
// directions for adjacent sectors
|
||||
enum {
|
||||
SP_UP,
|
||||
SP_LEFT,
|
||||
SP_RIGHT,
|
||||
SP_DOWN,
|
||||
|
||||
SP_DIR_MAX,
|
||||
};
|
||||
|
||||
// return number of adjacent sector or -1 if there is none
|
||||
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 );
|
||||
|
||||
// colour for a sector on the map
|
||||
INT32 GetMapColour( INT16 sX, INT16 sY, UINT8 mode );
|
||||
|
||||
// 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
|
||||
UINT32 HealSectorPopulation( INT16 sX, INT16 sY, UINT32 uHealpts );
|
||||
|
||||
// Flugente: get workforce effectiveness with regards to strategic disease
|
||||
FLOAT GetWorkforceEffectivenessWithDisease( INT8 bTownId, UINT8 usTeam );
|
||||
|
||||
// if this fraction of a sector's population is infected, outbreak is declared regardless of infection severity
|
||||
// Otherwise infection would be untreatable at this point
|
||||
FLOAT GetSectorDiseaseOverFlowThreshold();
|
||||
|
||||
#endif //__DISEASE_H
|
||||
@@ -177,6 +177,14 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
|
||||
// SANDRO - merc records - stat damaged
|
||||
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
|
||||
}
|
||||
|
||||
// Flugente: if this can cure a disease, do so
|
||||
if ( Drug[i].ubDiseaseCure > 0 )
|
||||
{
|
||||
// we cure exactly enough to cure an outbreak
|
||||
// Drug[i].ubDiseaseCure - 1 - the xml value is simply one higher than the disease type, otherwise we couldn't identify disease 0
|
||||
pSoldier->AddDiseasePoints( Drug[i].ubDiseaseCure - 1, -Disease[Drug[i].ubDiseaseCure - 1].sInfectionPtsOutbreak );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __DRUGS_AND_ALCOHOL_H
|
||||
#define __DRUGS_AND_ALCOHOL_H
|
||||
|
||||
#include "soldier control.h"
|
||||
#include "Soldier Control.h"
|
||||
|
||||
#define SOBER 0
|
||||
#define FEELING_GOOD 1
|
||||
@@ -84,6 +84,8 @@ typedef struct
|
||||
UINT8 ubDrugSideEffect;
|
||||
UINT8 ubDrugSideEffectRate;
|
||||
UINT8 ubMoralBacklash;
|
||||
|
||||
UINT8 ubDiseaseCure; // this is a cure for disease x - 1. It will cure Disease[x].sInfectionPtsOutbreak points of disease.
|
||||
} DRUGTYPE;
|
||||
|
||||
//GLOBALS
|
||||
|
||||
@@ -1243,11 +1243,14 @@ void AddOpinionEvent( UINT8 usProfileA, UINT8 usProfileB, UINT8 usEvent, BOOLEAN
|
||||
case OPINIONEVENT_AGAINST_US: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] |= OPINIONFLAG_STAGE1_AGAINST_US; break;
|
||||
case OPINIONEVENT_FOR_US: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] |= OPINIONFLAG_STAGE1_FOR_US; break;
|
||||
case OPINIONEVENT_AGAINST_ENEMY: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] |= OPINIONFLAG_STAGE1_AGAINST_ENEMY; break;
|
||||
|
||||
case OPINIONEVENT_FOR_ENEMY: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_FOR_ENEMY; break;
|
||||
case OPINIONEVENT_SOLVECONFLICT_REASON_GOOD: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_SOLVECONFLICT_REASON_GOOD; break;
|
||||
case OPINIONEVENT_SOLVECONFLICT_REASON_BAD: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_SOLVECONFLICT_REASON_BAD; break;
|
||||
case OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_GOOD:gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_SOLVECONFLICT_AGGRESSIVE_GOOD; break;
|
||||
case OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_BAD: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_SOLVECONFLICT_AGGRESSIVE_BAD; break;
|
||||
case OPINIONEVENT_DISEASE_DISGUSTING: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_DISEASE_DISGUSTING; break;
|
||||
case OPINIONEVENT_DISEASE_TREATMENT: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_DISEASE_TREATMENT; break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
@@ -1322,88 +1325,6 @@ INT8 GetDynamicOpinionDay( UINT8 usProfileA, UINT8 usProfileB, UINT8 usDay )
|
||||
opinion += gDynamicOpinionEvent[event].sOpinionModifier;
|
||||
}
|
||||
|
||||
/*if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_FRIENDLYFIRE << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_FRIENDLYFIRE].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_SNITCHSOLDMEOUT << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_SNITCHSOLDMEOUT].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_INTERFERENCE << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_SNITCHINTERFERENCE].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_FRIENDSWITHHATED << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_FRIENDSWITHHATED].sOpinionModifier;
|
||||
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_CONTRACTEXTENSION << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_CONTRACTEXTENSION].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_ORDEREDRETREAT << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_ORDEREDRETREAT].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_CIVKILLER << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_CIVKILLER].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_SLOWSUSDOWN << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_SLOWSUSDOWN].sOpinionModifier;
|
||||
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_NOSHARINGFOOD << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_NOSHARINGFOOD].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_ANNOYINGDISABILITY << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_ANNOYINGDISABILITY].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_ADDICT << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_ADDICT].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_THIEF << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_THIEF].sOpinionModifier;
|
||||
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_WORSTCOMMANDEREVER << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_WORSTCOMMANDEREVER].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_RICHGUY << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_RICHGUY].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_BETTERGEAR << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_BETTERGEAR].sOpinionModifier;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_YOUMOUNTEDAGUNONMYBREASTS << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_YOUMOUNTEDAGUNONMYBREASTS].sOpinionModifier;
|
||||
|
||||
|
||||
|
||||
|
||||
case OPINIONEVENT_BANDAGED:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_BANDAGED << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_DRINKBUDDIES_GOOD:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_DRINKBUDDIES_GOOD << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_DRINKBUDDIES_SUPER:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_DRINKBUDDIES_SUPER << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_DRINKBUDDIES_BAD:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_DRINKBUDDIES_BAD << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_DRINKBUDDIES_WORSE:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_DRINKBUDDIES_WORSE << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_AGAINST_US:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_AGAINST_US << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_FOR_US:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_FOR_US << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_AGAINST_ENEMY:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_AGAINST_ENEMY << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_FOR_ENEMY:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_FOR_ENEMY << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_SOLVECONFLICT_REASON_GOOD:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_SOLVECONFLICT_REASON_GOOD << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_SOLVECONFLICT_REASON_BAD:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_SOLVECONFLICT_REASON_BAD << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_GOOD:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_SOLVECONFLICT_AGGRESSIVE_GOOD << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_BAD:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_SOLVECONFLICT_AGGRESSIVE_BAD << usDay ) ++numflags;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// event opinion is number of times this happened times opinion modifer
|
||||
opinion = numflags * gDynamicOpinionEvent[usEvent].sOpinionModifier;*/
|
||||
|
||||
// cut it down to INT8
|
||||
return (INT8)opinion;
|
||||
}
|
||||
@@ -1626,6 +1547,20 @@ INT8 GetDynamicOpinion( UINT8 usProfileA, UINT8 usProfileB, UINT8 usEvent )
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE4_SOLVECONFLICT_AGGRESSIVE_BAD ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_DISEASE_DISGUSTING:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_DISEASE_DISGUSTING ) ++numflags;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE2_DISEASE_DISGUSTING ) ++numflags;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE3_DISEASE_DISGUSTING ) ++numflags;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE4_DISEASE_DISGUSTING ) ++numflags;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_DISEASE_TREATMENT:
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_DISEASE_TREATMENT ) ++numflags;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE2_DISEASE_TREATMENT ) ++numflags;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE3_DISEASE_TREATMENT ) ++numflags;
|
||||
if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE4_DISEASE_TREATMENT ) ++numflags;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2005,14 +1940,14 @@ void HandleDynamicOpinionChange( SOLDIERTYPE* pSoldier, UINT8 usEvent, BOOLEAN f
|
||||
switch ( usEvent )
|
||||
{
|
||||
case OPINIONEVENT_CONTRACTEXTENSION:
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_ORDEREDRETREAT:
|
||||
case OPINIONEVENT_CIVKILLER:
|
||||
case OPINIONEVENT_ANNOYINGDISABILITY:
|
||||
case OPINIONEVENT_ADDICT:
|
||||
case OPINIONEVENT_THIEF:
|
||||
case OPINIONEVENT_WORSTCOMMANDEREVER:
|
||||
case OPINIONEVENT_DISEASE_DISGUSTING:
|
||||
case OPINIONEVENT_DISEASE_TREATMENT:
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_SLOWSUSDOWN:
|
||||
@@ -2046,12 +1981,6 @@ void HandleDynamicOpinionChange( SOLDIERTYPE* pSoldier, UINT8 usEvent, BOOLEAN f
|
||||
highestcoolness = HighestInventoryCoolness( pSoldier );
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_DRINKBUDDIES_GOOD:
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_DRINKBUDDIES_BAD:
|
||||
break;
|
||||
|
||||
default:
|
||||
// either unknown event, or event is handled elsewhere - exit
|
||||
return;
|
||||
@@ -2163,6 +2092,15 @@ void HandleDynamicOpinionChange( SOLDIERTYPE* pSoldier, UINT8 usEvent, BOOLEAN f
|
||||
case OPINIONEVENT_DRINKBUDDIES_BAD:
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_DISEASE_DISGUSTING:
|
||||
// not if the other guy is a doctor, is currently used as a doctor, or has disease themself
|
||||
if ( pTeamSoldier->bAssignment == DOCTOR || pTeamSoldier->bAssignment == DISEASE_DOCTOR_SECTOR || HAS_SKILL_TRAIT( pTeamSoldier, DOCTOR_NT ) || pTeamSoldier->HasDisease(TRUE, FALSE, FALSE) )
|
||||
continue;
|
||||
break;
|
||||
|
||||
case OPINIONEVENT_DISEASE_TREATMENT:
|
||||
break;
|
||||
|
||||
default:
|
||||
// either unknown event, or event is handled elsewhere - exit
|
||||
return;
|
||||
|
||||
@@ -54,6 +54,8 @@ enum
|
||||
OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_GOOD, // other guy attempted to solve the conflict agressively, and we thought that was good
|
||||
|
||||
OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_BAD, // other guy attempted to solve the conflict agressively, and we thought that was bad
|
||||
OPINIONEVENT_DISEASE_DISGUSTING, // we have a disease, which others might find disgusting
|
||||
OPINIONEVENT_DISEASE_TREATMENT, // someone treated our diseases
|
||||
|
||||
OPINIONEVENT_MAX
|
||||
};
|
||||
@@ -223,17 +225,17 @@ extern DynamicOpinionEvent gDynamicOpinionEvent[OPINIONEVENT_MAX];
|
||||
#define OPINIONFLAG_STAGE3_SOLVECONFLICT_AGGRESSIVE_BAD 0x00040000 //262144
|
||||
#define OPINIONFLAG_STAGE4_SOLVECONFLICT_AGGRESSIVE_BAD 0x00080000 //524288
|
||||
|
||||
/*#define OPINIONFLAG_STAGE1_AGAINST_US 0x00100000 //1048576 // was against us in dialogue
|
||||
#define OPINIONFLAG_STAGE2_AGAINST_US 0x00200000 //2097152
|
||||
#define OPINIONFLAG_STAGE3_AGAINST_US 0x00400000 //4194304
|
||||
#define OPINIONFLAG_STAGE4_AGAINST_US 0x00800000 //8388608
|
||||
#define OPINIONFLAG_STAGE1_DISEASE_DISGUSTING 0x00100000 //1048576 // is diseased, which we find disgusting
|
||||
#define OPINIONFLAG_STAGE2_DISEASE_DISGUSTING 0x00200000 //2097152
|
||||
#define OPINIONFLAG_STAGE3_DISEASE_DISGUSTING 0x00400000 //4194304
|
||||
#define OPINIONFLAG_STAGE4_DISEASE_DISGUSTING 0x00800000 //8388608
|
||||
|
||||
#define OPINIONFLAG_STAGE1_FOR_US 0x01000000 //16777216 // other guy was for us in dialogue
|
||||
#define OPINIONFLAG_STAGE2_FOR_US 0x02000000 //33554432
|
||||
#define OPINIONFLAG_STAGE3_FOR_US 0x04000000 //67108864
|
||||
#define OPINIONFLAG_STAGE4_FOR_US 0x08000000 //134217728
|
||||
#define OPINIONFLAG_STAGE1_DISEASE_TREATMENT 0x01000000 //16777216 // treated our disease, which we like
|
||||
#define OPINIONFLAG_STAGE2_DISEASE_TREATMENT 0x02000000 //33554432
|
||||
#define OPINIONFLAG_STAGE3_DISEASE_TREATMENT 0x04000000 //67108864
|
||||
#define OPINIONFLAG_STAGE4_DISEASE_TREATMENT 0x08000000 //134217728
|
||||
|
||||
#define OPINIONFLAG_STAGE1_AGAINST_ENEMY 0x10000000 //268435456 // was against our dialogue enemy in dialogue
|
||||
/*#define OPINIONFLAG_STAGE1_AGAINST_ENEMY 0x10000000 //268435456 // was against our dialogue enemy in dialogue
|
||||
#define OPINIONFLAG_STAGE2_AGAINST_ENEMY 0x20000000 //536870912
|
||||
#define OPINIONFLAG_STAGE3_AGAINST_ENEMY 0x40000000 //1073741824
|
||||
#define OPINIONFLAG_STAGE4_AGAINST_ENEMY 0x80000000 //2147483648*/
|
||||
|
||||
@@ -2237,6 +2237,13 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: disease
|
||||
if ( MercPtrs[pFace->ubSoldierID]->HasDisease(TRUE, FALSE, TRUE) )
|
||||
{
|
||||
DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 28 );
|
||||
bNumRightIcons++;
|
||||
}
|
||||
|
||||
switch( pSoldier->bAssignment )
|
||||
{
|
||||
case DOCTOR:
|
||||
@@ -2361,6 +2368,31 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
|
||||
sIconIndex_Assignment = 16;
|
||||
fDoIcon_Assignment = TRUE;
|
||||
break;
|
||||
|
||||
case DISEASE_DIAGNOSE:
|
||||
{
|
||||
sIconIndex_Assignment = 29;
|
||||
fDoIcon_Assignment = TRUE;
|
||||
// determine our skill at detecting disease
|
||||
sPtsAvailable = pSoldier->stats.bMedical / 2 + NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) * 15;
|
||||
sPtsAvailable = (sPtsAvailable * (100 + pSoldier->GetBackgroundValue( BG_PERC_DISEASE_DIAGNOSE ))) / 100;
|
||||
|
||||
fShowNumber = TRUE;
|
||||
fShowMaximum = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case DISEASE_DOCTOR_SECTOR:
|
||||
sIconIndex_Assignment = 1;
|
||||
fDoIcon_Assignment = TRUE;
|
||||
sPtsAvailable = CalculateHealingPointsForDoctor( MercPtrs[pFace->ubSoldierID], &usMaximumPts, FALSE );
|
||||
fShowNumber = TRUE;
|
||||
fShowMaximum = TRUE;
|
||||
|
||||
// divide both amounts by 10 to make the displayed numbers a little more user-palatable (smaller)
|
||||
sPtsAvailable = (sPtsAvailable + 5) / 10;
|
||||
usMaximumPts = (usMaximumPts + 5) / 10;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check for being serviced...
|
||||
|
||||
+22
-2
@@ -178,6 +178,10 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, B
|
||||
poisonadd = min(poisonadd, gGameExternalOptions.usFoodMaxPoisoning),
|
||||
|
||||
pSoldier->AddPoison(poisonadd);
|
||||
|
||||
// we might get a disease from this...
|
||||
FLOAT modifier = 1.0f - 2 * foodcondition;
|
||||
HandlePossibleInfection( pSoldier, NULL, type == AP_EAT ? INFECTION_TYPE_BADFOOD : INFECTION_TYPE_BADWATER, modifier );
|
||||
}
|
||||
|
||||
FLOAT conditionmodifier = 0.5f * (1.0f + sqrt(foodcondition));
|
||||
@@ -236,6 +240,13 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, B
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szFoodTextStr[STR_FOOD_ATE], pSoldier->GetName(), Item[pObject->usItem].szItemName );
|
||||
else
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szFoodTextStr[STR_FOOD_DRANK], pSoldier->GetName(), Item[pObject->usItem].szItemName );
|
||||
|
||||
// Flugente: if this guy has the disease, infect object
|
||||
if ( pSoldier->sDiseasePoints[0] > 0 )
|
||||
(*pObject)[0]->data.sObjectFlag |= INFECTED;
|
||||
// if object is infected, infect the victim
|
||||
else if ( (*pObject)[0]->data.sObjectFlag & INFECTED )
|
||||
pSoldier->Infect( 0 );
|
||||
|
||||
// now remove a portion of the food item (or the whole item altogether)
|
||||
UINT16 ptsconsumed = UseKitPoints( pObject, Food[foodtype].ubPortionSize, pSoldier );
|
||||
@@ -372,8 +383,17 @@ void HourlyFoodSituationUpdate( SOLDIERTYPE *pSoldier )
|
||||
|
||||
FLOAT temperaturemodifier = (FLOAT)(3 + sectortemperaturemod)/3;
|
||||
|
||||
FLOAT specialfoodmodifier = (100.0 + pSoldier->GetBackgroundValue(BG_PERC_FOOD) ) / 100.0;
|
||||
FLOAT specialdrinkmodifier = (100.0 + pSoldier->GetBackgroundValue(BG_PERC_WATER)) / 100.0;
|
||||
FLOAT specialfoodmodifier = 100.0 + pSoldier->GetBackgroundValue(BG_PERC_FOOD);
|
||||
FLOAT specialdrinkmodifier = 100.0 + pSoldier->GetBackgroundValue(BG_PERC_WATER);
|
||||
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
{
|
||||
specialfoodmodifier += Disease[i].sFoodModifier * pSoldier->GetDiseaseMagnitude( i );
|
||||
specialdrinkmodifier += Disease[i].sDrinkModifier * pSoldier->GetDiseaseMagnitude( i );
|
||||
}
|
||||
|
||||
specialfoodmodifier /= 100.0;
|
||||
specialdrinkmodifier /= 100.0;
|
||||
|
||||
// due to digestion, reduce our food and drink levels
|
||||
pSoldier->bFoodLevel = max(pSoldier->bFoodLevel - (INT32) (specialfoodmodifier * activitymodifier * gGameExternalOptions.usFoodDigestionHourlyBaseFood), FOOD_MIN);
|
||||
|
||||
@@ -5247,6 +5247,15 @@ void CorpseMessageBoxCallBack( UINT8 ubExitValue )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we might get a disease from this...
|
||||
// if the corpse is already rotting, chance of infection is greatly increased
|
||||
FLOAT modifier = 1.0f;
|
||||
ROTTING_CORPSE *pCorpse = GetCorpseAtGridNo( nextGridNoinSight, level );
|
||||
if ( pCorpse->def.ubType == ROTTING_STAGE2 )
|
||||
modifier = 5.0f;
|
||||
|
||||
HandlePossibleInfection( gpTempSoldier, NULL, INFECTION_TYPE_CONTACT_CORPSE, modifier );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2680,6 +2680,25 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
|
||||
cnt++;
|
||||
}
|
||||
|
||||
//////////////////// DISEASE
|
||||
if ( gGameExternalOptions.fDisease )
|
||||
{
|
||||
if ( HasItemFlag( gpItemDescObject->usItem, DISEASEPROTECTION_FACE ) )
|
||||
{
|
||||
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[38], szUDBGenSecondaryStatsExplanationsTooltipText[38] );
|
||||
SetRegionFastHelpText( &(gUDBFasthelpRegions[iFirstDataRegion + cnt]), pStr );
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] );
|
||||
cnt++;
|
||||
}
|
||||
else if ( HasItemFlag( gpItemDescObject->usItem, DISEASEPROTECTION_HAND ) )
|
||||
{
|
||||
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[39], szUDBGenSecondaryStatsExplanationsTooltipText[39] );
|
||||
SetRegionFastHelpText( &(gUDBFasthelpRegions[iFirstDataRegion + cnt]), pStr );
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] );
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
@@ -6252,6 +6271,7 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////// DEFUSAL KIT
|
||||
//JMich_SkillsModifiers: Still needs a picture, currently using the wirecutters.
|
||||
if ( ( Item[gpItemDescObject->usItem].DisarmModifier > 0 && !fComparisonMode ) ||
|
||||
@@ -6308,6 +6328,23 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 35, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
cnt++;
|
||||
}
|
||||
|
||||
//////////////////// DISEASE
|
||||
if ( gGameExternalOptions.fDisease )
|
||||
{
|
||||
if ( (HasItemFlag( gpItemDescObject->usItem, DISEASEPROTECTION_FACE ) && !fComparisonMode) ||
|
||||
(fComparisonMode && HasItemFlag( gpComparedItemDescObject->usItem, DISEASEPROTECTION_FACE )) )
|
||||
{
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 37, gItemDescGenSecondaryRegions[cnt].sLeft + sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
++cnt;
|
||||
}
|
||||
else if ( (HasItemFlag( gpItemDescObject->usItem, DISEASEPROTECTION_HAND ) && !fComparisonMode) ||
|
||||
(fComparisonMode && HasItemFlag( gpComparedItemDescObject->usItem, DISEASEPROTECTION_HAND )) )
|
||||
{
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 37, 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 )
|
||||
|
||||
@@ -2998,6 +2998,16 @@ void RenderSMPanel( BOOLEAN *pfDirty )
|
||||
swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_POPUPTEXT ], gpSMCurrentMerc->stats.bLife, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bBreath, gpSMCurrentMerc->bBreathMax, pMoraleStr );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
CHAR16 atStr[500];
|
||||
swprintf( atStr, L"" );
|
||||
|
||||
gpSMCurrentMerc->PrintDiseaseDesc( atStr );
|
||||
|
||||
wcscat( pStr, atStr );
|
||||
}
|
||||
|
||||
SetRegionFastHelpText( &(gSM_SELMERCBarsRegion), pStr );
|
||||
|
||||
// Buggler: skills/traits tooltip on merc portrait
|
||||
@@ -5688,6 +5698,16 @@ void RenderTEAMPanel( BOOLEAN fDirty )
|
||||
swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_POPUPTEXT ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax, pSoldier->bBreath, pSoldier->bBreathMax, pMoraleStr );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
CHAR16 atStr[500];
|
||||
swprintf( atStr, L"" );
|
||||
|
||||
pSoldier->PrintDiseaseDesc( atStr );
|
||||
|
||||
wcscat( pStr, atStr );
|
||||
}
|
||||
|
||||
SetRegionFastHelpText( &(gTEAM_BarsRegions[ cnt ]), pStr );
|
||||
|
||||
// Buggler: skills/traits tooltip on merc portrait
|
||||
|
||||
@@ -2311,7 +2311,6 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
||||
//-----------------
|
||||
if ( pSoldier->bInSector && pSoldier->ubProfile == NO_PROFILE )
|
||||
{
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( pSoldier->IsZombie() )
|
||||
{
|
||||
swprintf(NameStr, pSoldier->name);
|
||||
@@ -2324,9 +2323,7 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
||||
gprintfdirty( sX, sY, NameStr );
|
||||
mprintf( sX, sY, NameStr );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ( pSoldier->bTeam == ENEMY_TEAM )
|
||||
else if ( pSoldier->bTeam == ENEMY_TEAM )
|
||||
{
|
||||
// Flugente: soldier profiles
|
||||
if ( gGameExternalOptions.fSoldierProfiles_Enemy && pSoldier->usSoldierProfile )
|
||||
|
||||
@@ -152,6 +152,7 @@ enum {
|
||||
BG_RESI_SUPPRESSION,
|
||||
BG_RESI_PHYSICAL,
|
||||
BG_RESI_ALCOHOL,
|
||||
BG_RESI_DISEASE,
|
||||
|
||||
// various
|
||||
BG_PERC_INTERROGATION,
|
||||
@@ -173,7 +174,7 @@ enum {
|
||||
BG_PERC_CTH_MAX,
|
||||
BG_PERC_HEARING_NIGHT,
|
||||
BG_PERC_HEARING_DAY,
|
||||
BG_TRAP_DISARM,
|
||||
BG_PERC_DISARM,
|
||||
|
||||
// approaches
|
||||
BG_PERC_APPROACH_FRIENDLY,
|
||||
@@ -186,6 +187,8 @@ enum {
|
||||
BG_PERC_CTH_CREATURE,
|
||||
BG_PERC_INSURANCE,
|
||||
BG_PERC_SPOTTER,
|
||||
BG_PERC_DISEASE_DIAGNOSE,
|
||||
BG_PERC_DISEASE_TREAT,
|
||||
|
||||
BG_DISLIKEBG, // dislike any other background that has the negative of this value set
|
||||
|
||||
|
||||
@@ -765,10 +765,10 @@ extern OBJECTTYPE gTempObject;
|
||||
#define SIGNAL_SHELL 0x04000000 //67108864 // this is a signal shell that precedes artillery barrages
|
||||
#define POWER_PACK 0x08000000 //134217728 // item continously powers an item it is attached to
|
||||
|
||||
/*#define SPOTTERITEM 0x10000000 //268435456 // binocular
|
||||
#define PLAYER_NET_2_LVL_4 0x20000000 //536870912
|
||||
#define PLAYER_NET_3_LVL_4 0x40000000 //1073741824
|
||||
#define PLAYER_NET_4_LVL_4 0x80000000 //2147483648*/
|
||||
#define SPOTTERITEM 0x10000000 //268435456 // binocular
|
||||
#define DISEASEPROTECTION_FACE 0x20000000 //536870912 // this item protects us from getting diseases by human contact if worn in a face slot
|
||||
#define DISEASEPROTECTION_HAND 0x40000000 //1073741824 // this item protects us from getting diseases by human contact if kept in inventory
|
||||
/*#define PLAYER_NET_4_LVL_4 0x80000000 //2147483648*/
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// -------- added by Flugente: flags for objects --------
|
||||
@@ -813,11 +813,13 @@ extern OBJECTTYPE gTempObject;
|
||||
#define CORPSE_NO_VEST 0x40000000 //1073741824 // corpse has no vest item (it has been either taken or been destroyed)
|
||||
#define CORPSE_NO_PANTS 0x80000000 //2147483648 // corpse has no pants item/for tripwire activation (gets set and unset when activating tripwire)
|
||||
|
||||
#define TRIPWIRE_ACTIVATED 0x0000000100000000 // 4294967296
|
||||
#define TAKEN_BY_MILITIA 0x0000000200000000 // 8589934592
|
||||
#define TRIPWIRE_ACTIVATED 0x0000000100000000 // 4294967296
|
||||
#define TAKEN_BY_MILITIA 0x0000000200000000 // 8589934592 // this item was picked up by militia
|
||||
#define TAKEN_BY_MILITIA_TABOO_GREEN 0x0000000400000000 // 17179869184 // this item is taboo for green militia (have to reset flag for world item upon dropping it)
|
||||
#define TAKEN_BY_MILITIA_TABOO_BLUE 0x0000000800000000 // 34359738368 // this item is taboo for blue militia (have to reset flag for world item upon dropping it)
|
||||
|
||||
#define INFECTED 0x0000001000000000 // // this item is infected with disease 0, getting damaged by this will infect you
|
||||
|
||||
// Flugente TODO 2012-09-17: next time we break savegame compatibility, extend the flagmasks from UINT32 to UINT64. I didn't do it this time (see double-used flag above), as we try to minimise those breaks. But it is needed.
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
|
||||
+6
-1
@@ -3153,7 +3153,12 @@ UINT32 CalculateCarriedWeight( SOLDIERTYPE * pSoldier )
|
||||
ubStrengthForCarrying = (ubStrengthForCarrying * (100 + gSkillTraitValues.ubBBCarryWeightBonus) / 100); // plus one third
|
||||
}
|
||||
|
||||
ubStrengthForCarrying = (ubStrengthForCarrying * (100 + pSoldier->GetBackgroundValue(BG_PERC_CARRYSTRENGTH)) / 100);
|
||||
// Flugente: diseases can affect stat effectivity
|
||||
INT16 diseaseeffect = 0;
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
diseaseeffect += Disease[i].sEffCarryStrength * pSoldier->GetDiseaseMagnitude( i );
|
||||
|
||||
ubStrengthForCarrying = (ubStrengthForCarrying * (100 + diseaseeffect + pSoldier->GetBackgroundValue( BG_PERC_CARRYSTRENGTH )) / 100);
|
||||
|
||||
// for now, assume soldiers can carry 1/2 their strength in KGs without penalty.
|
||||
// instead of multiplying by 100 for percent, and then dividing by 10 to account
|
||||
|
||||
@@ -509,6 +509,8 @@ typedef struct
|
||||
INT8 sRadioScanModifier; // modifies the scan range of the radio scan assignment in this sector
|
||||
UINT16 usPrisonRoomNumber[MAX_PRISON_ROOMS]; // room numbers of prisons
|
||||
|
||||
UINT16 usCivilianPopulation; // total amount of civilians that are supposed to be in this sector. This does not have to be the number of civilians in tactical
|
||||
|
||||
} SECTOR_EXT_DATA;
|
||||
|
||||
// get dirt increase for object with attachments, fConsiderAmmo: with ammo
|
||||
|
||||
@@ -2585,9 +2585,20 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend
|
||||
AddItemToPool(pTarget->sGridNo, &gTempObject, -1, pTarget->pathing.bLevel, 0, 0);
|
||||
// Make team look for items
|
||||
NotifySoldiersToLookforItems();
|
||||
|
||||
// Flugente: if this guy has the disease, or the blade was already infected, the new one will be too
|
||||
if ( pTarget->sDiseasePoints[0] > 0 || pBullet->usFlags & BULLET_FLAG_INFECTED )
|
||||
(*&gTempObject)[0]->data.sObjectFlag |= INFECTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateItem(usItem, usItemStatus, &pTarget->inv[bSlot]);
|
||||
|
||||
// Flugente: if this guy has the disease, or the blade was already infected, the new one will be too
|
||||
if ( pTarget->sDiseasePoints[0] > 0 || pBullet->usFlags & BULLET_FLAG_INFECTED )
|
||||
pTarget->inv[bSlot][0]->data.sObjectFlag |= INFECTED;
|
||||
}
|
||||
|
||||
ubAmmoType = AMMO_KNIFE;
|
||||
}
|
||||
else if (pBullet->fFragment)
|
||||
@@ -2600,6 +2611,13 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend
|
||||
ubAmmoType = pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType;
|
||||
}
|
||||
|
||||
// Flugente: if bullet is infected, give us disease (this is intended for throwing knifes)
|
||||
if ( pBullet->usFlags & BULLET_FLAG_INFECTED )
|
||||
{
|
||||
// infect us with the first disease
|
||||
pTarget->Infect( 0 );
|
||||
}
|
||||
|
||||
// HEADROCK HAM 5.1: This is an utter hack, but it may be necessary. This soldier is hit by a fragment,
|
||||
// so he needs to have his animations be interruptible. This takes care of soldiers hitting themselves
|
||||
// with their own fragments.
|
||||
@@ -4503,6 +4521,10 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
|
||||
if ( AmmoTypes[(*pObjAttHand)[0]->data.gun.ubGunAmmoType].ammoflag & AMMO_ANTIMATERIEL )
|
||||
usBulletFlags |= BULLET_FLAG_ANTIMATERIEL;
|
||||
|
||||
// Flugente: if object is infected, missile is too (intended for throwing knifes)
|
||||
if ( (*pObjAttHand)[0]->data.sObjectFlag & INFECTED )
|
||||
usBulletFlags |= BULLET_FLAG_INFECTED;
|
||||
|
||||
ubImpact =(UINT8) GetDamage(&pFirer->inv[pFirer->ubAttackingHand]);
|
||||
//zilpin: Begin new code block for spread patterns, number of projectiles, impact adjustment, etc.
|
||||
{
|
||||
@@ -4987,6 +5009,10 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
|
||||
if ( AmmoTypes[ pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType ].ammoflag & AMMO_ANTIMATERIEL )
|
||||
usBulletFlags |= BULLET_FLAG_ANTIMATERIEL;
|
||||
|
||||
// Flugente: if object is infected, missile is too (intended for throwing knifes)
|
||||
if ( (*pObjAttHand)[0]->data.sObjectFlag & INFECTED )
|
||||
usBulletFlags |= BULLET_FLAG_INFECTED;
|
||||
|
||||
ubImpact =(UINT8) GetDamage(pObjAttHand);
|
||||
//zilpin: pellet spread patterns externalized in XML
|
||||
/* zilpin: The section below, including line comments, is the original adjustment made to multiple projectile stats.
|
||||
|
||||
@@ -145,6 +145,9 @@ DynamicOpinionEvent gDynamicOpinionEvent[OPINIONEVENT_MAX] =
|
||||
{OPINIONEVENT_SOLVECONFLICT_REASON_BAD, -2, TRUE, FALSE, TRUE, FALSE},
|
||||
{OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_GOOD, 3, TRUE, FALSE, TRUE, FALSE},
|
||||
{OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_BAD, -3, TRUE, FALSE, TRUE, FALSE},
|
||||
{OPINIONEVENT_DISEASE_DISGUSTING, -3, TRUE, FALSE, TRUE, FALSE},
|
||||
{OPINIONEVENT_DISEASE_TREATMENT, 1, TRUE, FALSE, TRUE, FALSE},
|
||||
|
||||
};
|
||||
|
||||
BOOLEAN gfSomeoneSaidMoraleQuote = FALSE;
|
||||
@@ -1023,6 +1026,9 @@ void HandleMoraleEvent( SOLDIERTYPE *pSoldier, INT8 bMoraleEvent, INT16 sMapX, I
|
||||
break;
|
||||
}
|
||||
|
||||
// Flugente: if the situation is really, REALLY bad, we can get traumatized
|
||||
if ( pSoldier && pSoldier->aiData.bMorale < 15 )
|
||||
HandlePossibleInfection( pSoldier, NULL, INFECTION_TYPE_TRAUMATIC );
|
||||
|
||||
// some morale events also impact the player's reputation with the mercs back home
|
||||
switch( bMoraleEvent )
|
||||
|
||||
@@ -8316,16 +8316,14 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Loop through every character.
|
||||
for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
|
||||
for (uiLoop = 0; uiLoop < guiNumMercSlots; ++uiLoop )
|
||||
{
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("HandleSuppressionFire: loop = %d, numslots = %d ",uiLoop, guiNumMercSlots));
|
||||
pSoldier = MercSlots[uiLoop];
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: zombies do not receive any suppression at all!
|
||||
if ( pSoldier != NULL && pSoldier->IsZombie() )
|
||||
continue;
|
||||
#endif
|
||||
|
||||
// Has this character received any Suppression Points since the last attack?
|
||||
// HEADROCK: Suppression Points accumulate by bullets flying near the character. It includes
|
||||
@@ -9949,11 +9947,11 @@ BOOLEAN HostileZombiesPresent( )
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
for ( iLoop = gTacticalStatus.Team[ CREATURE_TEAM ].bFirstID; iLoop <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; iLoop++ )
|
||||
for ( iLoop = gTacticalStatus.Team[ CREATURE_TEAM ].bFirstID; iLoop <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; ++iLoop )
|
||||
{
|
||||
pSoldier = MercPtrs[ iLoop ];
|
||||
|
||||
if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->stats.bLife > 0 && pSoldier->IsZombie() )
|
||||
if ( pSoldier && pSoldier->bActive && pSoldier->bInSector && pSoldier->stats.bLife > 0 && pSoldier->IsZombie( ) )
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
+33
-10
@@ -50,7 +50,12 @@ INT16 EffectiveStrength( SOLDIERTYPE *pSoldier, BOOLEAN fTrainer )
|
||||
iEffStrength = 0;
|
||||
}
|
||||
|
||||
iEffStrength = (iEffStrength * (100 + pSoldier->GetBackgroundValue(BG_STRENGTH))) / 100;
|
||||
// Flugente: diseases can affect stat effectivity
|
||||
INT16 diseaseeffect = 0;
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
diseaseeffect += Disease[i].sEffStat[INFST_STR] * pSoldier->GetDiseaseMagnitude( i );
|
||||
|
||||
iEffStrength = (iEffStrength * (100 + diseaseeffect + pSoldier->GetBackgroundValue( BG_STRENGTH ))) / 100;
|
||||
|
||||
// ATE: Make sure at least 2...
|
||||
iEffStrength = __max( iEffStrength, 2 );
|
||||
@@ -69,7 +74,12 @@ INT16 EffectiveWisdom( SOLDIERTYPE * pSoldier)
|
||||
|
||||
iEffWisdom = EffectStatForBeingDrunk( pSoldier, iEffWisdom );
|
||||
|
||||
iEffWisdom = (iEffWisdom * (100 + pSoldier->GetBackgroundValue(BG_WISDOM))) / 100;
|
||||
// Flugente: diseases can affect stat effectivity
|
||||
INT16 diseaseeffect = 0;
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
diseaseeffect += Disease[i].sEffStat[INFST_WIS] * pSoldier->GetDiseaseMagnitude( i );
|
||||
|
||||
iEffWisdom = (iEffWisdom * (100 + diseaseeffect + pSoldier->GetBackgroundValue( BG_WISDOM ))) / 100;
|
||||
|
||||
return( (INT16) iEffWisdom );
|
||||
}
|
||||
@@ -90,7 +100,12 @@ INT16 EffectiveAgility( SOLDIERTYPE * pSoldier, BOOLEAN fTrainer )
|
||||
iEffAgility = (iEffAgility * 100) / pSoldier->sWeightCarriedAtTurnStart;
|
||||
}
|
||||
|
||||
iEffAgility = (iEffAgility * (100 + pSoldier->GetBackgroundValue(BG_AGILITY))) / 100;
|
||||
// Flugente: diseases can affect stat effectivity
|
||||
INT16 diseaseeffect = 0;
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
diseaseeffect += Disease[i].sEffStat[INFST_AGI] * pSoldier->GetDiseaseMagnitude( i );
|
||||
|
||||
iEffAgility = (iEffAgility * (100 + diseaseeffect + pSoldier->GetBackgroundValue( BG_AGILITY ))) / 100;
|
||||
|
||||
return( (INT16) iEffAgility );
|
||||
}
|
||||
@@ -196,7 +211,12 @@ INT8 EffectiveExpLevel( SOLDIERTYPE * pSoldier )
|
||||
}
|
||||
}
|
||||
|
||||
iEffExpLevel += pSoldier->bExtraExpLevel;
|
||||
// Flugente: diseases can affect stat effectivity
|
||||
INT16 diseaseeffect = 0;
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
diseaseeffect += Disease[i].sEffStat[INFST_EXP] * pSoldier->GetDiseaseMagnitude( i );
|
||||
|
||||
iEffExpLevel += diseaseeffect + pSoldier->bExtraExpLevel;
|
||||
|
||||
if (iEffExpLevel > 10)
|
||||
{
|
||||
@@ -208,10 +228,8 @@ INT8 EffectiveExpLevel( SOLDIERTYPE * pSoldier )
|
||||
// can't go below 1
|
||||
return( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return( (INT8) iEffExpLevel );
|
||||
}
|
||||
|
||||
return( (INT8) iEffExpLevel );
|
||||
}
|
||||
|
||||
INT8 EffectiveMarksmanship( SOLDIERTYPE * pSoldier )
|
||||
@@ -238,7 +256,12 @@ INT16 EffectiveDexterity( SOLDIERTYPE * pSoldier, BOOLEAN fTrainer )
|
||||
|
||||
iEffDexterity = EffectStatForBeingDrunk( pSoldier, iEffDexterity );
|
||||
|
||||
iEffDexterity = (iEffDexterity * (100 + pSoldier->GetBackgroundValue(BG_DEXTERITY))) / 100;
|
||||
// Flugente: diseases can affect stat effectivity
|
||||
INT16 diseaseeffect = 0;
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
diseaseeffect += Disease[i].sEffStat[INFST_DEX] * pSoldier->GetDiseaseMagnitude( i );
|
||||
|
||||
iEffDexterity = (iEffDexterity * (100 + diseaseeffect + pSoldier->GetBackgroundValue( BG_DEXTERITY ))) / 100;
|
||||
|
||||
return( (INT16) iEffDexterity );
|
||||
}
|
||||
@@ -458,7 +481,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
|
||||
iSkill += EffectiveExpLevel( pSoldier ) * 10;
|
||||
|
||||
// Flugente: backgrounds
|
||||
iSkill += pSoldier->GetBackgroundValue(BG_TRAP_DISARM);
|
||||
iSkill += pSoldier->GetBackgroundValue( BG_PERC_DISARM );
|
||||
|
||||
iSkill = iSkill / 10; // bring the value down to a percentage
|
||||
//JMich_SkillModifiers: Adding a Disarm Trap bonus
|
||||
|
||||
@@ -4006,6 +4006,9 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse )
|
||||
// Flugente: campaign stats
|
||||
gCurrentIncident.AddStat( pSoldier, CAMPAIGNHISTORY_TYPE_KILL );
|
||||
|
||||
// Flugente: disease
|
||||
HandleDeathDiseaseImplications( pSoldier );
|
||||
|
||||
if ( TurnSoldierIntoCorpse( pSoldier, TRUE, TRUE ) )
|
||||
{
|
||||
*pfMadeCorpse = TRUE;
|
||||
|
||||
+316
-19
@@ -5807,10 +5807,24 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1
|
||||
ubReason = TAKE_DAMAGE_BLADE;
|
||||
|
||||
// Flugente: check wether we can make this blade bloody
|
||||
if ( ubAttackerID != NOBODY && MercPtrs[ubAttackerID]->inv[HANDPOS].exists( ) && Item[MercPtrs[ubAttackerID]->inv[HANDPOS].usItem].bloodieditem > 0 )
|
||||
if ( ubAttackerID != NOBODY && MercPtrs[ubAttackerID]->inv[HANDPOS].exists( ) )
|
||||
{
|
||||
// magic happens
|
||||
MercPtrs[ubAttackerID]->inv[HANDPOS].usItem = Item[MercPtrs[ubAttackerID]->inv[HANDPOS].usItem].bloodieditem;
|
||||
if ( Item[MercPtrs[ubAttackerID]->inv[HANDPOS].usItem].bloodieditem > 0 )
|
||||
{
|
||||
// magic happens
|
||||
MercPtrs[ubAttackerID]->inv[HANDPOS].usItem = Item[MercPtrs[ubAttackerID]->inv[HANDPOS].usItem].bloodieditem;
|
||||
}
|
||||
|
||||
// Flugente: if the blade is infected, infect the victim
|
||||
if ( *&(MercPtrs[ubAttackerID]->inv[HANDPOS])[0]->data.sObjectFlag & INFECTED )
|
||||
{
|
||||
// infect us with the first disease
|
||||
this->Infect( 0 );
|
||||
}
|
||||
|
||||
// if this guy has the disease, infect the blade
|
||||
if ( this->sDiseasePoints[0] > 0 )
|
||||
*&(MercPtrs[ubAttackerID]->inv[HANDPOS])[0]->data.sObjectFlag |= INFECTED;
|
||||
}
|
||||
}
|
||||
else if ( Item[usWeaponIndex].usItemClass & IC_PUNCH )
|
||||
@@ -9984,11 +9998,7 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo
|
||||
// ATE: Put some logic in here to allow enemies to die quicker.....
|
||||
// Are we an enemy?
|
||||
// zombies don't die suddenly, as they regenerate health by bloodloss and poison. You have to make sure they die!
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( this->bSide != gbPlayerNum && !this->aiData.bNeutral && this->ubProfile == NO_PROFILE && !this->IsZombie( ) )
|
||||
#else
|
||||
if ( this->bSide != gbPlayerNum && !this->aiData.bNeutral && this->ubProfile == NO_PROFILE )
|
||||
#endif
|
||||
{
|
||||
// ATE: Give them a chance to fall down...
|
||||
if ( this->stats.bLife > 0 && this->stats.bLife < (OKLIFE - 1) )
|
||||
@@ -10051,6 +10061,26 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo
|
||||
if ( sLifeDeduct > 0 )
|
||||
this->usSoldierFlagMask |= SOLDIER_FRESHWOUND;
|
||||
|
||||
// Flugente we might get a disease from this...
|
||||
if ( gGameExternalOptions.fDisease )
|
||||
{
|
||||
if ( ubAttacker != NOBODY && MercPtrs[ubAttacker] && CREATURE_OR_BLOODCAT( MercPtrs[ubAttacker] ) )
|
||||
HandlePossibleInfection( this, MercPtrs[ubAttacker], INFECTION_TYPE_WOUND_ANIMAL );
|
||||
|
||||
if ( sLifeDeduct > 0 && ubReason == TAKE_DAMAGE_GUNFIRE )
|
||||
HandlePossibleInfection( this, NULL, INFECTION_TYPE_WOUND_GUNSHOT );
|
||||
else if ( sLifeDeduct > 0 && ( ubReason == TAKE_DAMAGE_BLADE || ubReason == TAKE_DAMAGE_HANDTOHAND
|
||||
|| ubReason == TAKE_DAMAGE_EXPLOSION || ubReason == TAKE_DAMAGE_STRUCTURE_EXPLOSION || ubReason == TAKE_DAMAGE_TENTACLES ) )
|
||||
{
|
||||
FLOAT modifier = 0.5f + sLifeDeduct/100;
|
||||
HandlePossibleInfection( this, NULL, INFECTION_TYPE_WOUND_OPEN, modifier );
|
||||
}
|
||||
|
||||
// possibly get traumatized if we're hit really bad
|
||||
if ( this->stats.bLife < OKLIFE )
|
||||
HandlePossibleInfection( this, NULL, INFECTION_TYPE_TRAUMATIC );
|
||||
}
|
||||
|
||||
// Calculate damage to our items if from an explosion!
|
||||
if ( ubReason == TAKE_DAMAGE_EXPLOSION || ubReason == TAKE_DAMAGE_STRUCTURE_EXPLOSION )
|
||||
{
|
||||
@@ -12297,13 +12327,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio
|
||||
#ifdef JA2UB
|
||||
if ( fMartialArtist && !Item[usItem].crowbar && this->ubBodyType == REGMALE )
|
||||
#else
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE && !IsZombie( ) ) // SANDRO - added check for body type
|
||||
#else
|
||||
if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE ) // SANDRO - added check for body type
|
||||
#endif
|
||||
|
||||
#endif
|
||||
{
|
||||
// Are we in attack mode yet?
|
||||
@@ -14649,12 +14673,14 @@ INT16 SOLDIERTYPE::GetSoldierCriticalDamageBonus( void )
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
BOOLEAN SOLDIERTYPE::IsZombie( void )
|
||||
{
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
return(ubSoldierClass == SOLDIER_CLASS_ZOMBIE);
|
||||
}
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
INT16 SOLDIERTYPE::GetPoisonResistance( void )
|
||||
{
|
||||
@@ -14690,11 +14716,9 @@ INT16 SOLDIERTYPE::GetPoisonDamagePercentage( void )
|
||||
// Flugente: this percentage has to be between 0% and 100%
|
||||
INT16 val = 0;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// zombies poison damage percentage is externalised
|
||||
if ( IsZombie( ) )
|
||||
val += gGameExternalOptions.sZombiePoisonDamagePercentage;
|
||||
#endif
|
||||
|
||||
if ( this->usAttackingWeapon )
|
||||
{
|
||||
@@ -15873,11 +15897,9 @@ BOOLEAN SOLDIERTYPE::RecognizeAsCombatant( UINT8 ubTargetID )
|
||||
if ( !pSoldier )
|
||||
return TRUE;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// zombies don't care about disguises
|
||||
if ( IsZombie( ) )
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
// not in covert mode: we recognize him
|
||||
if ( (pSoldier->usSoldierFlagMask & (SOLDIER_COVERT_CIV | SOLDIER_COVERT_SOLDIER)) == 0 )
|
||||
@@ -17297,6 +17319,13 @@ INT16 SOLDIERTYPE::GetAPBonus( )
|
||||
if ( this->pathing.bLevel )
|
||||
bonus += this->GetBackgroundValue( BG_HEIGHT );
|
||||
|
||||
// diseases can affect stat effectivity
|
||||
INT16 diseaseeffect = 0;
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
diseaseeffect += Disease[i].sEffAP * this->GetDiseaseMagnitude( i );
|
||||
|
||||
bonus += diseaseeffect;
|
||||
|
||||
return bonus;
|
||||
}
|
||||
|
||||
@@ -18663,6 +18692,274 @@ void SOLDIERTYPE::DeleteBoxingFlag( )
|
||||
flags.uiStatusFlags &= (~SOLDIER_BOXER);
|
||||
}
|
||||
|
||||
// Flugente: disease
|
||||
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 )
|
||||
{
|
||||
this->sDiseaseFlag[aDisease] |= SOLDIERDISEASE_OUTBREAK;
|
||||
|
||||
this->AnnounceDisease( aDisease );
|
||||
}
|
||||
|
||||
// remove later on, for testing only
|
||||
if ( 1 )
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s was infected with %s", gMercProfiles[this->ubProfile].zNickname, Disease[aDisease].szName );
|
||||
}
|
||||
}
|
||||
|
||||
void SOLDIERTYPE::AddDiseasePoints( UINT8 aDisease, INT32 aVal )
|
||||
{
|
||||
if ( aDisease < NUM_DISEASES )
|
||||
{
|
||||
this->sDiseasePoints[aDisease] = min( Disease[aDisease].sInfectionPtsFull, max( this->sDiseasePoints[aDisease] + aVal, -Disease[aDisease].sInfectionPtsOutbreak ) );
|
||||
|
||||
// if the disease 'breaks out', make it known
|
||||
if ( this->sDiseasePoints[aDisease] > Disease[aDisease].sInfectionPtsOutbreak )
|
||||
{
|
||||
this->sDiseaseFlag[aDisease] |= SOLDIERDISEASE_OUTBREAK;
|
||||
|
||||
if ( !(this->sDiseaseFlag[aDisease] & SOLDIERDISEASE_DIAGNOSED) )
|
||||
this->AnnounceDisease( aDisease );
|
||||
}
|
||||
|
||||
// once disease is fullblown, some diseases reverse themself
|
||||
if ( (Disease[aDisease].usDiseaseProperties & DISEASE_PROPERTY_REVERSEONFULL) && this->sDiseasePoints[aDisease] >= Disease[aDisease].sInfectionPtsFull )
|
||||
{
|
||||
this->sDiseaseFlag[aDisease] |= SOLDIERDISEASE_REVERSEAL;
|
||||
}
|
||||
|
||||
// if disease is cured, remove traces of it
|
||||
if ( this->sDiseasePoints[aDisease] <= 0 )
|
||||
{
|
||||
this->sDiseaseFlag[aDisease] &= ~(SOLDIERDISEASE_DIAGNOSED | SOLDIERDISEASE_OUTBREAK);
|
||||
|
||||
if ( this->bTeam == gbPlayerNum )
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szDiseaseText[TEXT_DISEASE_CURED], this->GetName( ), Disease[aDisease].szName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SOLDIERTYPE::AnnounceDisease( UINT8 aDisease )
|
||||
{
|
||||
this->sDiseaseFlag[aDisease] |= SOLDIERDISEASE_DIAGNOSED;
|
||||
|
||||
if ( this->bTeam == gbPlayerNum )
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szDiseaseText[TEXT_DISEASE_DIAGNOSE_GENERAL], this->GetName( ), Disease[aDisease].szName );
|
||||
}
|
||||
|
||||
// do we have any disease? fDiagnosedOnly: check for wether we know of this infection fHealableOnly: check wether it can be healed
|
||||
BOOLEAN SOLDIERTYPE::HasDisease( BOOLEAN fDiagnosedOnly, BOOLEAN fHealableOnly, BOOLEAN fSymbolOnly )
|
||||
{
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
{
|
||||
// disease is relevant if we are infected and are not looking for symbols only while the disease has no symbol
|
||||
if ( this->sDiseasePoints[i] > 0 && !(fSymbolOnly && (Disease[i].usDiseaseProperties & DISEASE_PROPERTY_HIDESYMBOL)) )
|
||||
{
|
||||
// only if we don't check for diagnosis, or we already know of this
|
||||
if ( !fDiagnosedOnly || (this->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED) )
|
||||
{
|
||||
// only if we don't check for cure, or this can be cured
|
||||
if ( !fHealableOnly || (Disease[i].usDiseaseProperties & DISEASE_PROPERTY_CANBECURED) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// get the magnitude os a disease we might have, used to determine wether there are any effects
|
||||
FLOAT SOLDIERTYPE::GetDiseaseMagnitude( UINT8 aDisease )
|
||||
{
|
||||
// diseases only have effects once they have broken out (otherwise stuff happens without the player having any clue as to why)
|
||||
if ( aDisease < NUM_DISEASES && this->sDiseasePoints[aDisease] > 0 && (this->sDiseaseFlag[aDisease] & SOLDIERDISEASE_OUTBREAK) )
|
||||
{
|
||||
return ((FLOAT)this->sDiseasePoints[aDisease] / (FLOAT)Disease[aDisease].sInfectionPtsFull);
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void SOLDIERTYPE::PrintDiseaseDesc( CHAR16* apStr, BOOLEAN fFullDesc )
|
||||
{
|
||||
// only for living mercs with a profile with a valid infection method
|
||||
if ( this->flags.uiStatusFlags & SOLDIER_VEHICLE || this->ubProfile == NO_PROFILE )
|
||||
return;
|
||||
|
||||
CHAR16 atStr[500];
|
||||
swprintf( atStr, L"" );
|
||||
|
||||
for ( int i = 0; i < NUM_DISEASES; ++i )
|
||||
{
|
||||
if ( this->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED )
|
||||
{
|
||||
swprintf( atStr, L"\n\n%s\n", Disease[i].szFatName );
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
// if we give a full description, also print out the effects at the moment
|
||||
if ( fFullDesc )
|
||||
{
|
||||
swprintf( atStr, L"%s\n", Disease[i].szDescription );
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
FLOAT magnitude = GetDiseaseMagnitude(i);
|
||||
|
||||
for ( int j = 0; j < INFST_MAX; ++j )
|
||||
{
|
||||
INT8 val = Disease[i].sEffStat[j] * magnitude;
|
||||
|
||||
if ( val )
|
||||
{
|
||||
swprintf( atStr, szDiseaseText[j], val > 0 ? L"+" : L"", val );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
INT8 val = Disease[i].sEffAP * magnitude;
|
||||
|
||||
if ( val )
|
||||
{
|
||||
swprintf( atStr, szDiseaseText[TEXT_DISEASE_AP], val > 0 ? L"+" : L"", val );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
UINT8 val = Disease[i].usMaxBreath * magnitude;
|
||||
|
||||
if ( val )
|
||||
{
|
||||
swprintf( atStr, szDiseaseText[TEXT_DISEASE_MAXBREATH], L"-", val );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
INT8 val = Disease[i].sEffCarryStrength * magnitude;
|
||||
|
||||
if ( val )
|
||||
{
|
||||
swprintf( atStr, szDiseaseText[TEXT_DISEASE_CARRYSTRENGTH], val > 0 ? L"+" : L"", val );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
FLOAT val = (FLOAT)(Disease[i].sLifeRegenHundreds) * magnitude / 100;
|
||||
|
||||
if ( val )
|
||||
{
|
||||
swprintf( atStr, szDiseaseText[TEXT_DISEASE_LIFEREGENHUNDREDS], val > 0 ? L"+" : L"", val );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
INT8 val = Disease[i].sNeedToSleep * magnitude;
|
||||
|
||||
if ( val )
|
||||
{
|
||||
swprintf( atStr, szDiseaseText[TEXT_DISEASE_NEEDTOSLEEP], val > 0 ? L"+" : L"", val );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
INT16 val = Disease[i].sDrinkModifier * magnitude;
|
||||
|
||||
if ( val )
|
||||
{
|
||||
swprintf( atStr, szDiseaseText[TEXT_DISEASE_DRINK], val > 0 ? L"+" : L"", val );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
INT16 val = Disease[i].sFoodModifier * magnitude;
|
||||
|
||||
if ( val )
|
||||
{
|
||||
swprintf( atStr, szDiseaseText[TEXT_DISEASE_FOOD], val > 0 ? L"+" : L"", val );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get percentage protection from infections via contact
|
||||
FLOAT SOLDIERTYPE::GetDiseaseContactProtection( )
|
||||
{
|
||||
FLOAT val = 0.0f;
|
||||
|
||||
// if we wear special equipment, lower our chances of being infected
|
||||
FLOAT bestfacegear = 0.0f;
|
||||
FLOAT bestprotectivegear = 0.0f;
|
||||
INT8 invsize = (INT8)inv.size( ); // remember inventorysize, so we don't call size() repeatedly
|
||||
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop )
|
||||
{
|
||||
if ( inv[bLoop].exists( ) )
|
||||
{
|
||||
OBJECTTYPE* pObj = &(inv[bLoop]);
|
||||
|
||||
if ( pObj && (*pObj)[0]->data.objectStatus >= USABLE )
|
||||
{
|
||||
if ( (bLoop == HEAD1POS || bLoop == HEAD2POS) )
|
||||
{
|
||||
if ( HasItemFlag( pObj->usItem, DISEASEPROTECTION_FACE ) )
|
||||
{
|
||||
bestfacegear = max( bestfacegear, (FLOAT)((*pObj)[0]->data.objectStatus / 100) );
|
||||
}
|
||||
}
|
||||
else if ( HasItemFlag( pObj->usItem, DISEASEPROTECTION_HAND ) )
|
||||
{
|
||||
bestprotectivegear = max( bestprotectivegear, (FLOAT)((*pObj)[0]->data.objectStatus / 100) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// up to 100% protection if face and hand protection is worn
|
||||
val += (bestfacegear + bestprotectivegear) / 2;
|
||||
|
||||
// not higher than 100%
|
||||
return min( val, 1.0f );
|
||||
}
|
||||
|
||||
INT16 SOLDIERTYPE::GetDiseaseResistance()
|
||||
{
|
||||
// Flugente: resistance can per definition only be between -100 and 100 (at least that's my definition)
|
||||
INT16 val = 0;
|
||||
|
||||
val += this->GetBackgroundValue( BG_RESI_DISEASE );
|
||||
|
||||
val = max( -100, val );
|
||||
val = min( 100, val );
|
||||
|
||||
return(val);
|
||||
}
|
||||
|
||||
|
||||
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include "GameSettings.h" // added by Flugente
|
||||
#include "Disease.h" // added by Flugente
|
||||
|
||||
#define PTR_CIVILIAN (pSoldier->bTeam == CIV_TEAM)
|
||||
#define PTR_CROUCHED (gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_CROUCH)
|
||||
@@ -409,6 +410,15 @@ enum
|
||||
#define SOLDIER_INTERROGATE_ALL 0x000000F8 // all interrogation flags
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// -------- added by Flugente: disease property flags --------
|
||||
// easier than adding 32 differently named variables. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
|
||||
// these flags describe how a disease has affected us so far
|
||||
#define SOLDIERDISEASE_DIAGNOSED 0x00000001 //1 // it is now known that we have this disease - either a doctor diagnosed it, or it broke out an we are currently suffering
|
||||
#define SOLDIERDISEASE_OUTBREAK 0x00000002 //2 // disease has broken out - we suffer the effects now. Without this flag, it is active but does not do any damage to us
|
||||
#define SOLDIERDISEASE_REVERSEAL 0x00000004 //4 // disease is reversing - every hour we receive negative points. This is used to simulate a disease healing itself
|
||||
|
||||
|
||||
|
||||
// -------- added by Flugente: background property flags --------
|
||||
// easier than adding 32 differently named variables. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
|
||||
// a merc's background info reveals data about his previous life, like former regiments. These backgrounds add small abilities/disabilities. Nothing substantial, just small bits do
|
||||
@@ -1469,6 +1479,10 @@ public:
|
||||
UINT8 usAISkillUse; // this variable allows the AI to remember which skill it wants to use
|
||||
UINT16 usSkillCounter[SOLDIER_COUNTER_MAX]; // counters used for various skill/trait/taint effects
|
||||
UINT32 usSkillCooldown[SOLDIER_COOLDOWN_MAX]; // cooldown used for various skill/trait/taint effects
|
||||
|
||||
// Flugente: diseases
|
||||
INT16 sDiseasePoints[NUM_DISEASES]; // we store the state of our diseases here
|
||||
UINT8 sDiseaseFlag[NUM_DISEASES]; // we need to store some special flags for every disease
|
||||
|
||||
// Flugente: Decrease this filler by 1 for each new UINT8 / BOOLEAN variable, so we can maintain savegame compatibility!!
|
||||
// Note that we also have to account for padding, so you might need to substract more than just the size of the new variables
|
||||
@@ -1691,10 +1705,8 @@ public:
|
||||
|
||||
INT16 GetSoldierCriticalDamageBonus( void ); // Flugente: determines critical damage bonus depending on class, skill, etc.
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: Zombies
|
||||
BOOLEAN IsZombie( void );
|
||||
#endif
|
||||
|
||||
// Flugente: poison system
|
||||
// These functions might one day be modified by traits etc. We'll keep that in these functions and not clutter the rest of the code
|
||||
@@ -1849,6 +1861,21 @@ public:
|
||||
// Flugente: boxing fix: this shall be the only location where the boxing flag gets removed (easier debugging)
|
||||
void DeleteBoxingFlag();
|
||||
|
||||
// Flugente: disease
|
||||
void Infect( UINT8 aDisease );
|
||||
void AddDiseasePoints( UINT8 aDisease, INT32 aVal );
|
||||
void AnnounceDisease( UINT8 aDisease );
|
||||
|
||||
// do we have any disease?
|
||||
// fDiagnosedOnly: check for wether we know of this infection
|
||||
// fHealableOnly: check wether it can be healed
|
||||
// fSymbolOnly: only show if symbol should be shown
|
||||
BOOLEAN HasDisease(BOOLEAN fDiagnosedOnly, BOOLEAN fHealableOnly, BOOLEAN fSymbolOnly = FALSE);
|
||||
FLOAT GetDiseaseMagnitude( UINT8 aDisease ); // get the magnitude os a disease we might have, used to determine wether there are any effects
|
||||
void PrintDiseaseDesc( CHAR16* apStr, BOOLEAN fFullDesc = FALSE );
|
||||
FLOAT GetDiseaseContactProtection(); // get percentage protection from infections via contact
|
||||
INT16 GetDiseaseResistance();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // SOLDIERTYPE;
|
||||
|
||||
+85
-37
@@ -581,33 +581,34 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
|
||||
tbTeam=pCreateStruct->bTeam;
|
||||
tfPP=pCreateStruct->fPlayerPlan; //used as temp indicator of struct sent from the server //hayden.
|
||||
|
||||
if(is_networked) {
|
||||
if(is_networked && (pCreateStruct->fOnRoof==1))
|
||||
if(is_networked)
|
||||
{
|
||||
ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping roof merc");
|
||||
return NULL;
|
||||
}
|
||||
if(is_networked && (pCreateStruct->fOnRoof==1))
|
||||
{
|
||||
ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping roof merc");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(is_client && !is_server && (tbTeam >0 && tbTeam < 5) && tfPP==0)
|
||||
{
|
||||
return NULL; // pure client to not spawn AI unless from server, Hayden.
|
||||
//gTacticalStatus.Team[ tbTeam ].bTeamActive=0;
|
||||
}
|
||||
//if(is_server && tbTeam>0 && tbTeam<5)
|
||||
if(is_server && tbTeam>0 && tbTeam<5)
|
||||
{
|
||||
send_AI(pCreateStruct,pubID);
|
||||
}
|
||||
if(is_client && !is_server && tfPP==1)
|
||||
{
|
||||
pCreateStruct->fPlayerPlan = 0;
|
||||
}
|
||||
if(is_client && !is_server && (tbTeam >0 && tbTeam < 5) && tfPP==0)
|
||||
{
|
||||
return NULL; // pure client to not spawn AI unless from server, Hayden.
|
||||
//gTacticalStatus.Team[ tbTeam ].bTeamActive=0;
|
||||
}
|
||||
//if(is_server && tbTeam>0 && tbTeam<5)
|
||||
if(is_server && tbTeam>0 && tbTeam<5)
|
||||
{
|
||||
send_AI(pCreateStruct,pubID);
|
||||
}
|
||||
if(is_client && !is_server && tfPP==1)
|
||||
{
|
||||
pCreateStruct->fPlayerPlan = 0;
|
||||
}
|
||||
|
||||
if(is_networked && (pCreateStruct->bBodyType==23 || pCreateStruct->bBodyType==24))
|
||||
{
|
||||
ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping tank");
|
||||
return NULL;
|
||||
}
|
||||
if(is_networked && (pCreateStruct->bBodyType==23 || pCreateStruct->bBodyType==24))
|
||||
{
|
||||
ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping tank");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//hayden
|
||||
@@ -785,19 +786,68 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
|
||||
}
|
||||
|
||||
Soldier.bActionPoints = Soldier.CalcActionPoints( );
|
||||
Soldier.bInitialActionPoints = Soldier.bActionPoints;
|
||||
Soldier.bSide = gTacticalStatus.Team[ Soldier.bTeam ].bSide;
|
||||
Soldier.bActive = TRUE;
|
||||
Soldier.sSectorX = pCreateStruct->sSectorX;
|
||||
Soldier.sSectorY = pCreateStruct->sSectorY;
|
||||
Soldier.bSectorZ = pCreateStruct->bSectorZ;
|
||||
Soldier.ubInsertionDirection = pCreateStruct->ubDirection;
|
||||
Soldier.pathing.bDesiredDirection = pCreateStruct->ubDirection;
|
||||
Soldier.aiData.bDominantDir = pCreateStruct->ubDirection;
|
||||
Soldier.bInitialActionPoints = Soldier.bActionPoints;
|
||||
Soldier.bSide = gTacticalStatus.Team[ Soldier.bTeam ].bSide;
|
||||
Soldier.bActive = TRUE;
|
||||
Soldier.sSectorX = pCreateStruct->sSectorX;
|
||||
Soldier.sSectorY = pCreateStruct->sSectorY;
|
||||
Soldier.bSectorZ = pCreateStruct->bSectorZ;
|
||||
Soldier.ubInsertionDirection = pCreateStruct->ubDirection;
|
||||
Soldier.pathing.bDesiredDirection = pCreateStruct->ubDirection;
|
||||
Soldier.aiData.bDominantDir = pCreateStruct->ubDirection;
|
||||
Soldier.ubDirection = pCreateStruct->ubDirection;
|
||||
|
||||
Soldier.sInsertionGridNo = pCreateStruct->sInsertionGridNo;
|
||||
Soldier.bOldLife = Soldier.stats.bLifeMax;
|
||||
Soldier.sInsertionGridNo = pCreateStruct->sInsertionGridNo;
|
||||
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 && Soldier.ubSoldierClass != SOLDIER_CLASS_TANK )
|
||||
{
|
||||
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 ( population )
|
||||
{
|
||||
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
|
||||
|
||||
if ( pSectorInfo && pSectorInfo->usInfected )
|
||||
{
|
||||
UINT16 chanceofinfection = 100 * (FLOAT)(pSectorInfo->usInfected) / (FLOAT)(population);
|
||||
|
||||
if ( Chance( chanceofinfection ) )
|
||||
{
|
||||
INT32 diseaseamount = Disease[0].sInfectionPtsFull * pSectorInfo->fInfectionSeverity;
|
||||
Soldier.AddDiseasePoints( 0, diseaseamount );
|
||||
|
||||
// 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 );
|
||||
|
||||
UINT16 diseasemaxbreathreduction = Disease[0].usMaxBreath * magnitude;
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If a civvy, set neutral
|
||||
if ( Soldier.bTeam == CIV_TEAM )
|
||||
@@ -1923,12 +1973,10 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
|
||||
{
|
||||
swprintf( pSoldier->name, gzLateLocalizedString[ 36 ] );
|
||||
}
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
else if ( pSoldier->IsZombie() )
|
||||
{
|
||||
swprintf( pSoldier->name, TacticalStr[ ZOMBIE_TEAM_MERC_NAME ] );
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
swprintf( pSoldier->name, TacticalStr[ CREATURE_TEAM_MERC_NAME ] ); break;
|
||||
|
||||
@@ -394,6 +394,10 @@
|
||||
RelativePath=".\Dialogue Control.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Disease.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DisplayCover.h"
|
||||
>
|
||||
@@ -744,6 +748,10 @@
|
||||
RelativePath=".\Dialogue Control.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Disease.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DisplayCover.cpp"
|
||||
>
|
||||
@@ -1068,6 +1076,10 @@
|
||||
RelativePath=".\XML_CompatibleFaceItems.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_Disease.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_Drugs.cpp"
|
||||
>
|
||||
|
||||
@@ -398,6 +398,10 @@
|
||||
RelativePath="Dialogue Control.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Disease.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="DisplayCover.h"
|
||||
>
|
||||
@@ -746,6 +750,10 @@
|
||||
RelativePath="Dialogue Control.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Disease.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="DisplayCover.cpp"
|
||||
>
|
||||
@@ -1070,6 +1078,10 @@
|
||||
RelativePath="XML_CompatibleFaceItems.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_Disease.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_Drugs.cpp"
|
||||
>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<ClInclude Include="Campaign.h" />
|
||||
<ClInclude Include="Civ Quotes.h" />
|
||||
<ClInclude Include="Dialogue Control.h" />
|
||||
<ClInclude Include="Disease.h" />
|
||||
<ClInclude Include="DisplayCover.h" />
|
||||
<ClInclude Include="Drugs And Alcohol.h" />
|
||||
<ClInclude Include="DynamicDialogue.h" />
|
||||
@@ -124,6 +125,7 @@
|
||||
<ClCompile Include="Campaign.cpp" />
|
||||
<ClCompile Include="Civ Quotes.cpp" />
|
||||
<ClCompile Include="Dialogue Control.cpp" />
|
||||
<ClCompile Include="Disease.cpp" />
|
||||
<ClCompile Include="DisplayCover.cpp" />
|
||||
<ClCompile Include="Drugs And Alcohol.cpp" />
|
||||
<ClCompile Include="DynamicDialogue.cpp" />
|
||||
@@ -204,6 +206,7 @@
|
||||
<ClCompile Include="XML_Clothes.cpp" />
|
||||
<ClCompile Include="XML_ComboMergeInfo.cpp" />
|
||||
<ClCompile Include="XML_CompatibleFaceItems.cpp" />
|
||||
<ClCompile Include="XML_Disease.cpp" />
|
||||
<ClCompile Include="XML_Drugs.cpp" />
|
||||
<ClCompile Include="XML_EnemyAmmoDrops.cpp" />
|
||||
<ClCompile Include="XML_EnemyArmourDrops.cpp" />
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
<ClInclude Include="Dialogue Control.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Disease.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DisplayCover.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -308,6 +311,9 @@
|
||||
<ClCompile Include="Dialogue Control.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Disease.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DisplayCover.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -625,6 +631,9 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="XML_ItemAdjustments.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="XML_Disease.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="XML_Drugs.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<ClInclude Include="Campaign.h" />
|
||||
<ClInclude Include="Civ Quotes.h" />
|
||||
<ClInclude Include="Dialogue Control.h" />
|
||||
<ClInclude Include="Disease.h" />
|
||||
<ClInclude Include="DisplayCover.h" />
|
||||
<ClInclude Include="Drugs And Alcohol.h" />
|
||||
<ClInclude Include="DynamicDialogue.h" />
|
||||
@@ -125,6 +126,7 @@
|
||||
<ClCompile Include="Campaign.cpp" />
|
||||
<ClCompile Include="Civ Quotes.cpp" />
|
||||
<ClCompile Include="Dialogue Control.cpp" />
|
||||
<ClCompile Include="Disease.cpp" />
|
||||
<ClCompile Include="DisplayCover.cpp" />
|
||||
<ClCompile Include="Drugs And Alcohol.cpp" />
|
||||
<ClCompile Include="DynamicDialogue.cpp" />
|
||||
@@ -205,6 +207,7 @@
|
||||
<ClCompile Include="XML_Clothes.cpp" />
|
||||
<ClCompile Include="XML_ComboMergeInfo.cpp" />
|
||||
<ClCompile Include="XML_CompatibleFaceItems.cpp" />
|
||||
<ClCompile Include="XML_Disease.cpp" />
|
||||
<ClCompile Include="XML_Drugs.cpp" />
|
||||
<ClCompile Include="XML_EnemyAmmoDrops.cpp" />
|
||||
<ClCompile Include="XML_EnemyArmourDrops.cpp" />
|
||||
|
||||
@@ -273,6 +273,9 @@
|
||||
<ClInclude Include="DynamicDialogue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Disease.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Air Raid.cpp">
|
||||
@@ -680,5 +683,11 @@
|
||||
<ClCompile Include="DynamicDialogue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Disease.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="XML_Disease.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+12
-4
@@ -9442,7 +9442,6 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
|
||||
INT8 bStatLoss = 0;
|
||||
UINT8 ubAmmoType;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( pTarget->IsZombie() )
|
||||
{
|
||||
// if bullet does not hits anything other than the head, it doesn't do any damage
|
||||
@@ -9458,7 +9457,6 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
|
||||
pTarget->usSoldierFlagMask &= ~SOLDIER_HEADSHOT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// NOTE: reduction of bullet impact due to range and obstacles is handled
|
||||
// in MoveBullet.
|
||||
@@ -9843,6 +9841,9 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
|
||||
gMercProfiles[ pTarget->ubProfile ].bWisdom = pTarget->stats.bWisdom;
|
||||
}
|
||||
|
||||
// Flugente: disease
|
||||
HandlePossibleInfection( pTarget, pFirer, INFECTION_TYPE_WOUND_WIS );
|
||||
|
||||
if (pTarget->name[0] && pTarget->bVisible == TRUE)
|
||||
{
|
||||
// make stat RED for a while...
|
||||
@@ -9935,6 +9936,9 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
|
||||
gMercProfiles[ pTarget->ubProfile ].bDexterity = pTarget->stats.bDexterity;
|
||||
}
|
||||
|
||||
// Flugente: disease
|
||||
HandlePossibleInfection( pTarget, pFirer, INFECTION_TYPE_WOUND_DEX );
|
||||
|
||||
if (pTarget->name[0] && pTarget->bVisible == TRUE)
|
||||
{
|
||||
// make stat RED for a while...
|
||||
@@ -9969,6 +9973,9 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
|
||||
gMercProfiles[ pTarget->ubProfile ].bStrength = pTarget->stats.bStrength;
|
||||
}
|
||||
|
||||
// Flugente: disease
|
||||
HandlePossibleInfection( pTarget, pFirer, INFECTION_TYPE_WOUND_STR );
|
||||
|
||||
if (pTarget->name[0] && pTarget->bVisible == TRUE)
|
||||
{
|
||||
// make stat RED for a while...
|
||||
@@ -10004,6 +10011,9 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
|
||||
gMercProfiles[ pTarget->ubProfile ].bAgility = pTarget->stats.bAgility;
|
||||
}
|
||||
|
||||
// Flugente: disease
|
||||
HandlePossibleInfection( pTarget, pFirer, INFECTION_TYPE_WOUND_AGI );
|
||||
|
||||
if (pTarget->name[0] && pTarget->bVisible == TRUE)
|
||||
{
|
||||
// make stat RED for a while...
|
||||
@@ -10330,7 +10340,6 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
BOOLEAN autoresolve = IsAutoResolveActive();
|
||||
iImpact = max( 1, (INT32)(iImpact * (100 - pTarget->GetDamageResistance(autoresolve, FALSE)) / 100 ) );
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: if the target is a zombie, any melee attack, regardless of hit location, will set the headshot flag. Thus any zombie killed in melee will stay dead (if you play with that option)
|
||||
if ( pTarget->IsZombie() )
|
||||
{
|
||||
@@ -10340,7 +10349,6 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
pTarget->usSoldierFlagMask |= SOLDIER_HEADSHOT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return( iImpact );
|
||||
}
|
||||
|
||||
@@ -238,6 +238,7 @@ typedef PARSE_STAGE;
|
||||
#define SQUADNAMEFILENAME "SquadNames.xml"
|
||||
#define BACKGROUNDSFILENAME "Backgrounds.xml"
|
||||
#define CAMPAIGNSTATSEVENTSFILENAME "CampaignStatsEvents.xml"
|
||||
#define DISEASEFILENAME "Disease.xml"
|
||||
|
||||
#define TAUNTSFOLDERNAME "EnemyTaunts\\"
|
||||
#define TAUNTSFILENAME "EnemyTaunts.xml"
|
||||
@@ -308,6 +309,10 @@ extern BOOLEAN WriteDrugsStats();
|
||||
extern BOOLEAN ReadInFoodStats(STR fileName);
|
||||
extern BOOLEAN WriteFoodStats();
|
||||
|
||||
// Flugente: disease
|
||||
extern BOOLEAN ReadInDiseaseStats( STR fileName );
|
||||
extern BOOLEAN WriteDiseaseStats( );
|
||||
|
||||
// Flugente: merchants
|
||||
extern BOOLEAN ReadInMerchantStats(STR fileName);
|
||||
extern BOOLEAN WriteMerchantStats();
|
||||
|
||||
@@ -97,6 +97,7 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha
|
||||
strcmp(name, "resistance_suppression") == 0 ||
|
||||
strcmp(name, "resistance_physical") == 0 ||
|
||||
strcmp(name, "resistance_alcohol") == 0 ||
|
||||
strcmp(name, "resistance_disease" ) == 0 ||
|
||||
strcmp(name, "interrogation") == 0 ||
|
||||
strcmp(name, "prisonguard") == 0 ||
|
||||
strcmp(name, "betterprices_guns") == 0 ||
|
||||
@@ -125,6 +126,8 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha
|
||||
strcmp(name, "cth_vs_creatures") == 0 ||
|
||||
strcmp(name, "insurance") == 0 ||
|
||||
strcmp(name, "spotter") == 0 ||
|
||||
strcmp(name, "disease_diagnose" ) == 0 ||
|
||||
strcmp(name, "disease_treatment" ) == 0 ||
|
||||
strcmp(name, "dislikebackground" ) == 0 ||
|
||||
strcmp(name, "druguse") == 0 ||
|
||||
strcmp(name, "xenophobic") == 0 ||
|
||||
@@ -380,6 +383,11 @@ backgroundEndElementHandle(void *userData, const XML_Char *name)
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curBackground.value[BG_RESI_ALCOHOL] = min(XML_BACKGROUND_RESI_MAX, max(-XML_BACKGROUND_RESI_MAX, (INT8) atol(pData->szCharData) ));
|
||||
}
|
||||
else if ( strcmp( name, "resistance_disease" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curBackground.value[BG_RESI_DISEASE] = min( XML_BACKGROUND_RESI_MAX, max( -XML_BACKGROUND_RESI_MAX, (INT8)atol( pData->szCharData ) ) );
|
||||
}
|
||||
else if(strcmp(name, "interrogation") == 0)
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
@@ -478,7 +486,7 @@ backgroundEndElementHandle(void *userData, const XML_Char *name)
|
||||
else if(strcmp(name, "disarm_trap") == 0)
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curBackground.value[BG_TRAP_DISARM] = min(50, max(-50, (INT16) atol(pData->szCharData) ));
|
||||
pData->curBackground.value[BG_PERC_DISARM] = min( 50, max( -50, (INT16)atol( pData->szCharData ) ) );
|
||||
}
|
||||
else if(strcmp(name, "approach_friendly") == 0)
|
||||
{
|
||||
@@ -520,6 +528,16 @@ backgroundEndElementHandle(void *userData, const XML_Char *name)
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curBackground.value[BG_PERC_SPOTTER] = min(30, max(-30, (INT16) atol(pData->szCharData) ));
|
||||
}
|
||||
else if ( strcmp( name, "disease_diagnose" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curBackground.value[BG_PERC_DISEASE_DIAGNOSE] = min( 50, max( -50, (INT16)atol( pData->szCharData ) ) );
|
||||
}
|
||||
else if ( strcmp( name, "disease_treatment" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curBackground.value[BG_PERC_DISEASE_TREAT] = min( 50, max( -50, (INT16)atol( pData->szCharData ) ) );
|
||||
}
|
||||
else if ( strcmp( name, "dislikebackground" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
|
||||
@@ -0,0 +1,479 @@
|
||||
#ifdef PRECOMPILEDHEADERS
|
||||
#include "Tactical All.h"
|
||||
#else
|
||||
#include "sgp.h"
|
||||
#include "overhead.h"
|
||||
#include "Disease.h"
|
||||
#include "Debug Control.h"
|
||||
#include "expat.h"
|
||||
#include "XML.h"
|
||||
#endif
|
||||
|
||||
struct
|
||||
{
|
||||
PARSE_STAGE curElement;
|
||||
|
||||
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH + 1];
|
||||
DISEASE curItem;
|
||||
DISEASE * curArray;
|
||||
UINT32 maxArraySize;
|
||||
|
||||
UINT32 currentDepth;
|
||||
UINT32 maxReadDepth;
|
||||
}
|
||||
typedef parseData;
|
||||
|
||||
static void XMLCALL
|
||||
diseaseStartElementHandle( void *userData, const XML_Char *name, const XML_Char **atts )
|
||||
{
|
||||
parseData * pData = (parseData *)userData;
|
||||
|
||||
if ( pData->currentDepth <= pData->maxReadDepth ) //are we reading this element?
|
||||
{
|
||||
if ( strcmp( name, "DISEASESLIST" ) == 0 && pData->curElement == ELEMENT_NONE )
|
||||
{
|
||||
pData->curElement = ELEMENT_LIST;
|
||||
|
||||
memset( pData->curArray, 0, sizeof(DISEASE)*pData->maxArraySize );
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
else if ( strcmp( name, "DISEASE" ) == 0 && pData->curElement == ELEMENT_LIST )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
|
||||
memset( &pData->curItem, 0, sizeof(DISEASE) );
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
else if ( pData->curElement == ELEMENT &&
|
||||
(strcmp( name, "uiIndex" ) == 0 ||
|
||||
strcmp( name, "szName" ) == 0 ||
|
||||
strcmp( name, "szFatName" ) == 0 ||
|
||||
strcmp( name, "szDescription" ) == 0 ||
|
||||
strcmp( name, "sInfectionPtsInitial" ) == 0 ||
|
||||
strcmp( name, "sInfectionPtsOutbreak" ) == 0 ||
|
||||
strcmp( name, "sInfectionPtsFull" ) == 0 ||
|
||||
strcmp( name, "sInfectionPtsGainPerHour" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_SWAMP" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_TROPICS" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_SEX" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_CONTACT_HUMAN" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_CONTACT_CORPSE" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_WOUND_ANIMAL" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_WOUND_OPEN" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_WOUND_GUNSHOT" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_WOUND_AGI" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_WOUND_DEX" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_WOUND_STR" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_WOUND_WIS" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_WOUND_TRAUMATIC" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_BADFOOD" ) == 0 ||
|
||||
strcmp( name, "usInfectionChance_BADWATER" ) == 0 ||
|
||||
strcmp( name, "fCanBeCured" ) == 0 ||
|
||||
strcmp( name, "fReverseOnFull" ) == 0 ||
|
||||
strcmp( name, "fCanReInfect" ) == 0 ||
|
||||
strcmp( name, "fHideSymbol" ) == 0 ||
|
||||
strcmp( name, "fDisgusting" ) == 0 ||
|
||||
strcmp( name, "sEffStatAGI" ) == 0 ||
|
||||
strcmp( name, "sEffStatDEX" ) == 0 ||
|
||||
strcmp( name, "sEffStatSTR" ) == 0 ||
|
||||
strcmp( name, "sEffStatWIS" ) == 0 ||
|
||||
strcmp( name, "sEffStatEXP" ) == 0 ||
|
||||
strcmp( name, "sEffAP" ) == 0 ||
|
||||
strcmp( name, "usMaxBreath" ) == 0 ||
|
||||
strcmp( name, "sEffCarryStrength" ) == 0 ||
|
||||
strcmp( name, "sLifeRegenHundreds" ) == 0 ||
|
||||
strcmp( name, "sNeedToSleep" ) == 0 ||
|
||||
strcmp( name, "sDrinkModifier" ) == 0 ||
|
||||
strcmp( name, "sFoodModifier" ) == 0) )
|
||||
{
|
||||
pData->curElement = ELEMENT_PROPERTY;
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
pData->szCharData[0] = '\0';
|
||||
}
|
||||
|
||||
pData->currentDepth++;
|
||||
|
||||
}
|
||||
|
||||
static void XMLCALL
|
||||
diseaseCharacterDataHandle( void *userData, const XML_Char *str, int len )
|
||||
{
|
||||
parseData * pData = (parseData *)userData;
|
||||
|
||||
if ( (pData->currentDepth <= pData->maxReadDepth) &&
|
||||
(strlen( pData->szCharData ) < MAX_CHAR_DATA_LENGTH)
|
||||
){
|
||||
strncat( pData->szCharData, str, __min( (unsigned int)len, MAX_CHAR_DATA_LENGTH - strlen( pData->szCharData ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
diseaseEndElementHandle( void *userData, const XML_Char *name )
|
||||
{
|
||||
parseData * pData = (parseData *)userData;
|
||||
|
||||
if ( pData->currentDepth <= pData->maxReadDepth ) //we're at the end of an element that we've been reading
|
||||
{
|
||||
if ( strcmp( name, "DISEASESLIST" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT_NONE;
|
||||
}
|
||||
else if ( strcmp( name, "DISEASE" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT_LIST;
|
||||
|
||||
// we do NOT want to read the first entry -> move stuff by 1
|
||||
if ( pData->curItem.uiIndex < pData->maxArraySize )
|
||||
{
|
||||
pData->curArray[pData->curItem.uiIndex] = pData->curItem; //write the food into the table
|
||||
}
|
||||
}
|
||||
else if ( strcmp( name, "uiIndex" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.uiIndex = (UINT16)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "szName" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
|
||||
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curItem.szName, sizeof(pData->curItem.szName) / sizeof(pData->curItem.szName[0]) );
|
||||
pData->curItem.szName[sizeof(pData->curItem.szName) / sizeof(pData->curItem.szName[0]) - 1] = '\0';
|
||||
}
|
||||
else if ( strcmp( name, "szFatName" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
|
||||
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curItem.szFatName, sizeof(pData->curItem.szFatName) / sizeof(pData->curItem.szFatName[0]) );
|
||||
pData->curItem.szFatName[sizeof(pData->curItem.szFatName) / sizeof(pData->curItem.szFatName[0]) - 1] = '\0';
|
||||
}
|
||||
else if ( strcmp( name, "szDescription" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
|
||||
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curItem.szDescription, sizeof(pData->curItem.szDescription) / sizeof(pData->curItem.szDescription[0]) );
|
||||
pData->curItem.szDescription[sizeof(pData->curItem.szDescription) / sizeof(pData->curItem.szDescription[0]) - 1] = '\0';
|
||||
}
|
||||
else if ( strcmp( name, "sInfectionPtsInitial" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sInfectionPtsInitial = (INT32)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sInfectionPtsOutbreak" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sInfectionPtsOutbreak = (INT32)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sInfectionPtsFull" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sInfectionPtsFull = (INT32)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sInfectionPtsGainPerHour" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sInfectionPtsGainPerHour = (INT32)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_SWAMP" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_SWAMP] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_TROPICS" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_TROPICS] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_SEX" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_SEX] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_CONTACT_HUMAN" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_CONTACT_CORPSE" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_CONTACT_CORPSE] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_WOUND_ANIMAL" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_ANIMAL] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_WOUND_OPEN" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_OPEN] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_WOUND_GUNSHOT" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_GUNSHOT] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_WOUND_AGI" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_AGI] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_WOUND_DEX" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_DEX] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_WOUND_STR" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_STR] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_WOUND_WIS" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_WIS] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_WOUND_TRAUMATIC" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_TRAUMATIC] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_BADFOOD" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_BADFOOD] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usInfectionChance_BADWATER" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usInfectionChance[INFECTION_TYPE_BADWATER] = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "fCanBeCured" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
if ( atol( pData->szCharData ) )
|
||||
pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_CANBECURED;
|
||||
}
|
||||
else if ( strcmp( name, "fReverseOnFull" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
if ( atol( pData->szCharData ) )
|
||||
pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_REVERSEONFULL;
|
||||
}
|
||||
else if ( strcmp( name, "fCanReInfect" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
if ( atol( pData->szCharData ) )
|
||||
pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_CANREINFECT;
|
||||
}
|
||||
else if ( strcmp( name, "fHideSymbol" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
if ( atol( pData->szCharData ) )
|
||||
pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_HIDESYMBOL;
|
||||
}
|
||||
else if ( strcmp( name, "fDisgusting" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
if ( atol( pData->szCharData ) )
|
||||
pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_DISGUSTING;
|
||||
}
|
||||
else if ( strcmp( name, "sEffStatAGI" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sEffStat[INFST_AGI] = (INT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sEffStatDEX" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sEffStat[INFST_DEX] = (INT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sEffStatSTR" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sEffStat[INFST_STR] = (INT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sEffStatWIS" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sEffStat[INFST_WIS] = (INT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sEffStatEXP" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sEffStat[INFST_EXP] = (INT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sEffAP" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sEffAP = (INT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "usMaxBreath" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.usMaxBreath = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sEffCarryStrength" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sEffCarryStrength = (INT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sLifeRegenHundreds" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sLifeRegenHundreds = (INT16)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sNeedToSleep" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sNeedToSleep = (INT8)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sDrinkModifier" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sDrinkModifier = (INT16)atol( pData->szCharData );
|
||||
}
|
||||
else if ( strcmp( name, "sFoodModifier" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.sFoodModifier = (INT16)atol( pData->szCharData );
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
|
||||
pData->currentDepth--;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN ReadInDiseaseStats( STR fileName )
|
||||
{
|
||||
HWFILE hFile;
|
||||
UINT32 uiBytesRead;
|
||||
UINT32 uiFSize;
|
||||
CHAR8 * lpcBuffer;
|
||||
XML_Parser parser = XML_ParserCreate( NULL );
|
||||
|
||||
parseData pData;
|
||||
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Loading Disease.xml" );
|
||||
|
||||
// Open foods file
|
||||
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
|
||||
if ( !hFile )
|
||||
return(FALSE);
|
||||
|
||||
uiFSize = FileGetSize( hFile );
|
||||
lpcBuffer = (CHAR8 *)MemAlloc( uiFSize + 1 );
|
||||
|
||||
//Read in block
|
||||
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
|
||||
{
|
||||
MemFree( lpcBuffer );
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
lpcBuffer[uiFSize] = 0; //add a null terminator
|
||||
|
||||
FileClose( hFile );
|
||||
|
||||
XML_SetElementHandler( parser, diseaseStartElementHandle, diseaseEndElementHandle );
|
||||
XML_SetCharacterDataHandler( parser, diseaseCharacterDataHandle );
|
||||
|
||||
memset( &pData, 0, sizeof(pData) );
|
||||
pData.curArray = Disease;
|
||||
pData.maxArraySize = NUM_DISEASES;
|
||||
|
||||
XML_SetUserData( parser, &pData );
|
||||
|
||||
if ( !XML_Parse( parser, lpcBuffer, uiFSize, TRUE ) )
|
||||
{
|
||||
CHAR8 errorBuf[511];
|
||||
|
||||
sprintf( errorBuf, "XML Parser Error in Disease.xml: %s at line %d", XML_ErrorString( XML_GetErrorCode( parser ) ), XML_GetCurrentLineNumber( parser ) );
|
||||
LiveMessage( errorBuf );
|
||||
|
||||
MemFree( lpcBuffer );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MemFree( lpcBuffer );
|
||||
|
||||
XML_ParserFree( parser );
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
BOOLEAN WriteDiseaseStats( )
|
||||
{
|
||||
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"writefoodsstats");
|
||||
HWFILE hFile;
|
||||
|
||||
//Debug code; make sure that what we got from the file is the same as what's there
|
||||
// Open a new file
|
||||
hFile = FileOpen( "TABLEDATA\\Disease out.xml", FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
|
||||
if ( !hFile )
|
||||
return(FALSE);
|
||||
|
||||
{
|
||||
FilePrintf( hFile, "<DISEASESLIST>\r\n" );
|
||||
for ( UINT32 cnt = 0; cnt < NUM_DISEASES; ++cnt )
|
||||
{
|
||||
FilePrintf( hFile, "\t<DISEASE>\r\n" );
|
||||
|
||||
FilePrintf( hFile, "\t\t<uiIndex>%d</uiIndex>\r\n", cnt );
|
||||
FilePrintf( hFile, "\t\t<szName>%s</szName>\r\n", Disease[cnt].szName );
|
||||
FilePrintf( hFile, "\t\t<szFatName>%s</szFatName>\r\n", Disease[cnt].szFatName );
|
||||
FilePrintf( hFile, "\t\t<szDescription>%s</szDescription>\r\n", Disease[cnt].szDescription );
|
||||
FilePrintf( hFile, "\t\t<sInfectionPtsInitial>%d</sInfectionPtsInitial>\r\n", Disease[cnt].sInfectionPtsInitial );
|
||||
FilePrintf( hFile, "\t\t<sInfectionPtsOutbreak>%d</sInfectionPtsOutbreak>\r\n", Disease[cnt].sInfectionPtsOutbreak );
|
||||
FilePrintf( hFile, "\t\t<sInfectionPtsFull>%d</sInfectionPtsFull>\r\n", Disease[cnt].sInfectionPtsFull );
|
||||
FilePrintf( hFile, "\t\t<sInfectionPtsGainPerHour>%d</sInfectionPtsGainPerHour>\r\n", Disease[cnt].sInfectionPtsGainPerHour );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_SWAMP>%d</usInfectionChance_SWAMP>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_SWAMP] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_TROPICS>%d</usInfectionChance_TROPICS>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_TROPICS] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_SEX>%d</usInfectionChance_SEX>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_SEX] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_CONTACT_HUMAN>%d</usInfectionChance_CONTACT_HUMAN>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_CONTACT_CORPSE>%d</usInfectionChance_CONTACT_CORPSE>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_CONTACT_CORPSE] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_WOUND_ANIMAL>%d</usInfectionChance_WOUND_ANIMAL>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_ANIMAL] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_WOUND_OPEN>%d</usInfectionChance_WOUND_OPEN>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_OPEN] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_WOUND_GUNSHOT>%d</usInfectionChance_WOUND_GUNSHOT>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_GUNSHOT] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_WOUND_AGI>%d</usInfectionChance_WOUND_AGI>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_AGI] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_WOUND_DEX>%d</usInfectionChance_WOUND_DEX>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_DEX] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_WOUND_STR>%d</usInfectionChance_WOUND_STR>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_STR] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_WOUND_WIS>%d</usInfectionChance_WOUND_WIS>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_WIS] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_TRAUMATIC>%d</usInfectionChance_TRAUMATIC>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_TRAUMATIC] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_BADFOOD>%d</usInfectionChance_BADFOOD>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_BADFOOD] );
|
||||
FilePrintf( hFile, "\t\t<usInfectionChance_BADWATER>%d</usInfectionChance_BADWATER>\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_BADWATER] );
|
||||
FilePrintf( hFile, "\t\t<fCanBeCured>%d</fCanBeCured>\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_CANBECURED) ? 1 : 0 );
|
||||
FilePrintf( hFile, "\t\t<fReverseOnFull>%d</fReverseOnFull>\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_REVERSEONFULL) ? 1 : 0 );
|
||||
FilePrintf( hFile, "\t\t<fCanReInfect>%d</fCanReInfect>\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_CANREINFECT) ? 1 : 0 );
|
||||
FilePrintf( hFile, "\t\t<fHideSymbol>%d</fHideSymbol>\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_HIDESYMBOL) ? 1 : 0 );
|
||||
FilePrintf( hFile, "\t\t<fDisgusting>%d</fDisgusting>\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_DISGUSTING) ? 1 : 0 );
|
||||
FilePrintf( hFile, "\t\t<sEffStatAGI>%d</sEffStatAGI>\r\n", Disease[cnt].sEffStat[INFST_AGI] );
|
||||
FilePrintf( hFile, "\t\t<sEffStatDEX>%d</sEffStatDEX>\r\n", Disease[cnt].sEffStat[INFST_DEX] );
|
||||
FilePrintf( hFile, "\t\t<sEffStatSTR>%d</sEffStatSTR>\r\n", Disease[cnt].sEffStat[INFST_STR] );
|
||||
FilePrintf( hFile, "\t\t<sEffStatWIS>%d</sEffStatWIS>\r\n", Disease[cnt].sEffStat[INFST_WIS] );
|
||||
FilePrintf( hFile, "\t\t<sEffStatEXP>%d</sEffStatEXP>\r\n", Disease[cnt].sEffStat[INFST_EXP] );
|
||||
FilePrintf( hFile, "\t\t<sEffAP>%d</sEffAP>\r\n", Disease[cnt].sEffAP );
|
||||
FilePrintf( hFile, "\t\t<usMaxBreath>%d</usMaxBreath>\r\n", Disease[cnt].usMaxBreath );
|
||||
FilePrintf( hFile, "\t\t<sEffCarryStrength>%d</sEffCarryStrength>\r\n", Disease[cnt].sEffCarryStrength );
|
||||
FilePrintf( hFile, "\t\t<sLifeRegenHundreds>%d</sLifeRegenHundreds>\r\n", Disease[cnt].sLifeRegenHundreds );
|
||||
FilePrintf( hFile, "\t\t<sNeedToSleep>%d</sNeedToSleep>\r\n", Disease[cnt].sNeedToSleep );
|
||||
FilePrintf( hFile, "\t\t<sDrinkModifier>%d</sDrinkModifier>\r\n", Disease[cnt].sDrinkModifier );
|
||||
FilePrintf( hFile, "\t\t<sFoodModifier>%d</sFoodModifier>\r\n", Disease[cnt].sFoodModifier );
|
||||
|
||||
FilePrintf( hFile, "\t</DISEASE>\r\n" );
|
||||
}
|
||||
FilePrintf( hFile, "</DISEASESLIST>\r\n" );
|
||||
}
|
||||
FileClose( hFile );
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
@@ -54,7 +54,9 @@ drugsStartElementHandle(void *userData, const XML_Char *name, const XML_Char **a
|
||||
strcmp(name, "ubDrugEffect") == 0 ||
|
||||
strcmp(name, "ubDrugSideEffect") == 0 ||
|
||||
strcmp(name, "ubDrugSideEffectRate") == 0 ||
|
||||
strcmp(name, "ubMoralBacklash") ))
|
||||
strcmp(name, "ubMoralBacklash" ) == 0 ||
|
||||
strcmp(name, "ubMoralBacklash" ) == 0 ||
|
||||
strcmp(name, "ubDiseaseCure" ) == 0 ))
|
||||
{
|
||||
pData->curElement = ELEMENT_PROPERTY;
|
||||
|
||||
@@ -142,6 +144,11 @@ drugsEndElementHandle(void *userData, const XML_Char *name)
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curDrugs.ubMoralBacklash = (UINT8) atol(pData->szCharData);
|
||||
}
|
||||
else if ( strcmp( name, "ubDiseaseCure" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curDrugs.ubDiseaseCure = (UINT8)atol( pData->szCharData );
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
@@ -241,6 +248,7 @@ BOOLEAN WriteDrugsStats()
|
||||
FilePrintf(hFile,"\t\t<ubDrugSideEffect>%d</ubDrugSideEffect>\r\n", Drug[cnt].ubDrugSideEffect );
|
||||
FilePrintf(hFile,"\t\t<ubDrugSideEffectRate>%d</ubDrugSideEffectRate>\r\n", Drug[cnt].ubDrugSideEffectRate );
|
||||
FilePrintf(hFile,"\t\t<ubMoralBacklash>%d</ubMoralBacklash>\r\n", Drug[cnt].ubMoralBacklash );
|
||||
FilePrintf(hFile,"\t\t<ubDiseaseCure>%d</ubDiseaseCure>\r\n", Drug[cnt].ubDiseaseCure );
|
||||
|
||||
FilePrintf(hFile,"\t</DRUG>\r\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user