mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- New feature: zombies can now spawn from corpses, if you specify that option in the preferences screen (by Flugente)
o if set to off, no zombies will spawn. This can also be changed in mid-game o for more information on how this works and how to set it up, see http://www.bears-pit.com/board/ubbthreads.php/topics/295746/Zombies_WH40K_and_more.html#Post295746 o with the tag <PoisonPercentage>, you can now poison guns or ammo. This is the percentage of damage dealt that will be poisonous (see zombie thread for an explanation) o The zombie option can only be enabled in a single player game o AI fix: to prevent the endless clock problem, the AI now ends the turn if the same actor calls the decision routine over 100 times in a single turn. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5313 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -792,6 +792,10 @@ void ChangeBaseSoldierStats( SOLDIERTYPE *pSoldier )
|
||||
pSoldier->bBleeding = 0;
|
||||
pSoldier->bBreath = 100;
|
||||
|
||||
pSoldier->bPoisonSum = 0;
|
||||
pSoldier->bPoisonLife = 0;
|
||||
pSoldier->bPoisonBleeding = 0;
|
||||
|
||||
pSoldier->stats.bMarksmanship = (UINT8)(sBaseStat[sCurBaseDiff] + (UINT16)(Random(BASE_STAT_DEVIATION * 2)-BASE_STAT_DEVIATION));
|
||||
pSoldier->stats.bMedical = (UINT8)(sBaseStat[sCurBaseDiff] + (UINT16)(Random(BASE_STAT_DEVIATION * 2)-BASE_STAT_DEVIATION));
|
||||
pSoldier->stats.bMechanical = (UINT8)(sBaseStat[sCurBaseDiff] + (UINT16)(Random(BASE_STAT_DEVIATION * 2)-BASE_STAT_DEVIATION));
|
||||
|
||||
+20
-10
@@ -241,7 +241,7 @@ BOOLEAN LoadGameSettings()
|
||||
if (!IsHiSpeedClockMode())
|
||||
gGameSettings.fOptions[TOPTION_AUTO_FAST_FORWARD_MODE] = FALSE;
|
||||
|
||||
//gGameOptions.fWeaponOverheating = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_WEAPON_OVERHEATING" , FALSE ); // Flugente FTW 1: Weapon Overheating
|
||||
gGameSettings.fOptions[TOPTION_ZOMBIES] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ZOMBIES" , FALSE );
|
||||
|
||||
gGameSettings.fOptions[NUM_ALL_GAME_OPTIONS] = iniReader.ReadBoolean("JA2 Game Settings","NUM_ALL_GAME_OPTIONS" , FALSE );
|
||||
|
||||
@@ -341,8 +341,6 @@ BOOLEAN SaveGameSettings()
|
||||
settings << "; UINT8 fOptions[ NUM_ALL_GAME_OPTIONS ]; // Toggle Options (Speech, Subtitles, Show Tree Tops, etc.. )" << endl;
|
||||
settings << "; UINT32 uiMeanwhileScenesSeenFlags; // Bit Vector describing seen 'mean whiles..'" << endl;
|
||||
settings << "; BOOLEAN fHideHelpInAllScreens; // Controls Help \"do not show help again\" checkbox" << endl;
|
||||
//settings << "; UINT8 ubSizeOfDisplayCover; // The number of grids the player designates thru [Delete + ( = or - )]" << endl;
|
||||
//settings << "; UINT8 ubSizeOfLOS; // The number of grids the player designates thru [End + ( = or - )]" << endl;
|
||||
settings << "; } GAME_SETTINGS" << endl;
|
||||
settings << ";" << endl;
|
||||
settings << ";******************************************************************************************************************************" << endl;
|
||||
@@ -355,8 +353,6 @@ BOOLEAN SaveGameSettings()
|
||||
settings << "ubSpeechVolume = " << (int)gGameSettings.ubSpeechVolume << endl;
|
||||
settings << "uiMeanwhileScenesSeenFlags = " << gGameSettings.uiMeanwhileScenesSeenFlags << endl;
|
||||
settings << "fHideHelpInAllScreens = " << (gGameSettings.fHideHelpInAllScreens ? "TRUE" : "FALSE" ) << endl;
|
||||
//settings << "ubSizeOfDisplayCover = " << (int)gGameSettings.ubSizeOfDisplayCover << endl;
|
||||
//settings << "ubSizeOfLOS = " << (int)gGameSettings.ubSizeOfLOS << endl;
|
||||
settings << "TOPTION_SPEECH = " << (gGameSettings.fOptions[TOPTION_SPEECH] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_MUTE_CONFIRMATIONS = " << (gGameSettings.fOptions[TOPTION_MUTE_CONFIRMATIONS] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_SUBTITLES = " << (gGameSettings.fOptions[TOPTION_SUBTITLES] ? "TRUE" : "FALSE" ) << endl;
|
||||
@@ -391,20 +387,18 @@ BOOLEAN SaveGameSettings()
|
||||
settings << "TOPTION_ALLOW_SOLDIER_TOOLTIPS = " << (gGameSettings.fOptions[TOPTION_ALLOW_SOLDIER_TOOLTIPS] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_USE_AUTO_SAVE = " << (gGameSettings.fOptions[TOPTION_USE_AUTO_SAVE] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_SILENT_SKYRIDER = " << (gGameSettings.fOptions[TOPTION_SILENT_SKYRIDER] ? "TRUE" : "FALSE" ) << endl;
|
||||
//settings << "TOPTION_LOW_CPU_USAGE = " << (gGameSettings.fOptions[TOPTION_LOW_CPU_USAGE] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_ENHANCED_DESC_BOX = " << (gGameSettings.fOptions[TOPTION_ENHANCED_DESC_BOX] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_TOGGLE_TURN_MODE = " << (gGameSettings.fOptions[TOPTION_TOGGLE_TURN_MODE] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_STAT_PROGRESS_BARS = " << (gGameSettings.fOptions[TOPTION_STAT_PROGRESS_BARS] ? "TRUE" : "FALSE" ) << endl; // HEADROCK HAM 3.6: Progress Bars
|
||||
settings << "TOPTION_ALT_MAP_COLOR = " << (gGameSettings.fOptions[TOPTION_ALT_MAP_COLOR] ? "TRUE" : "FALSE" ) << endl; // HEADROCK HAM 4: Alt Map Colors
|
||||
settings << "TOPTION_ALTERNATE_BULLET_GRAPHICS = " << (gGameSettings.fOptions[TOPTION_ALTERNATE_BULLET_GRAPHICS] ? "TRUE" : "FALSE" ) << endl;
|
||||
//settings << "TOPTION_USE_NCTH = " << (gGameSettings.fOptions[TOPTION_USE_NCTH] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_SHOW_MERC_RANKS = " << (gGameSettings.fOptions[TOPTION_SHOW_MERC_RANKS] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_SHOW_TACTICAL_FACE_GEAR = " << (gGameSettings.fOptions[TOPTION_SHOW_TACTICAL_FACE_GEAR] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_SHOW_TACTICAL_FACE_ICONS = " << (gGameSettings.fOptions[TOPTION_SHOW_TACTICAL_FACE_ICONS] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_DISABLE_CURSOR_SWAP = " << (gGameSettings.fOptions[TOPTION_DISABLE_CURSOR_SWAP] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_QUIET_TRAINING = " << (gGameSettings.fOptions[TOPTION_QUIET_TRAINING] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_AUTO_FAST_FORWARD_MODE = " << (gGameSettings.fOptions[TOPTION_AUTO_FAST_FORWARD_MODE] ? "TRUE" : "FALSE" ) << endl;
|
||||
//settings << "TOPTION_WEAPON_OVERHEATING = " << (gGameOptions.fWeaponOverheating ? "TRUE" : "FALSE" ) << endl; // Flugente FTW 1: Weapon Overheating
|
||||
settings << "TOPTION_ZOMBIES = " << (gGameSettings.fOptions[TOPTION_ZOMBIES] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_CHEAT_MODE_OPTIONS_HEADER = " << (gGameSettings.fOptions[TOPTION_CHEAT_MODE_OPTIONS_HEADER] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_FORCE_BOBBY_RAY_SHIPMENTS = " << (gGameSettings.fOptions[TOPTION_FORCE_BOBBY_RAY_SHIPMENTS] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_CHEAT_MODE_OPTIONS_END = " << (gGameSettings.fOptions[TOPTION_CHEAT_MODE_OPTIONS_END] ? "TRUE" : "FALSE" ) << endl;
|
||||
@@ -530,9 +524,8 @@ void InitGameSettings()
|
||||
gGameSettings.fOptions[ TOPTION_DISABLE_CURSOR_SWAP ] = FALSE;
|
||||
gGameSettings.fOptions[ TOPTION_QUIET_TRAINING ] = FALSE;
|
||||
gGameSettings.fOptions[ TOPTION_AUTO_FAST_FORWARD_MODE ] = FALSE;
|
||||
gGameSettings.fOptions[ TOPTION_ZOMBIES ] = FALSE; // Flugente Zombies 1.0
|
||||
|
||||
// Flugente FTW 1: Weapon Overheating
|
||||
//gGameSettings.fOptions[ TOPTION_WEAPON_OVERHEATING ] = TRUE;
|
||||
|
||||
// arynn: Cheat/Debug Menu
|
||||
gGameSettings.fOptions[ TOPTION_CHEAT_MODE_OPTIONS_HEADER ] = FALSE;
|
||||
@@ -547,6 +540,8 @@ void InitGameSettings()
|
||||
gGameSettings.fOptions[ TOPTION_RENDER_MOUSE_REGIONS ] = FALSE; // an example of a DEBUG build option
|
||||
gGameSettings.fOptions[ TOPTION_DEBUG_MODE_OPTIONS_END ] = FALSE; // an example options screen options divider (pure text)
|
||||
|
||||
|
||||
|
||||
// enum control options (not real options but included here for the sake of complete control of values)
|
||||
|
||||
//gGameSettings.ubSizeOfDisplayCover = 16;
|
||||
@@ -1331,6 +1326,21 @@ void LoadGameExternalOptions()
|
||||
gGameExternalOptions.iCooldownModificatorLonelyBarrel = iniReader.ReadFloat ("Tactical Weapon Overheating Settings","OVERHEATING_COOLDOWN_MODIFICATOR_LONELYBARREL", 1.15f, 1.0f, 10.0f);
|
||||
gGameExternalOptions.fSetZeroUponNewSector = iniReader.ReadBoolean("Tactical Weapon Overheating Settings","OVERHEATING_SET_ZERO_UPON_NEW_SECTOR",TRUE);
|
||||
|
||||
//################# Tactical Zombie Settings ##################
|
||||
gGameExternalOptions.sZombieRiseBehaviour = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_RISE_BEHAVIOUR", 0, 0, 3);
|
||||
gGameExternalOptions.fZombieSpawnWaves = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_SPAWN_WAVES", FALSE);
|
||||
gGameExternalOptions.sZombieRiseWaveFrequency = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_RISE_WAVE_FREQUENCY", 30, 0, 100);
|
||||
gGameExternalOptions.fZombieCanClimb = iniReader.ReadBoolean("Tactical Zombie Settings", "ZOMBIE_CAN_CLIMB", TRUE);
|
||||
gGameExternalOptions.fZombieExplodingCivs = iniReader.ReadBoolean("Tactical Zombie Settings", "ZOMBIE_EXPLODING_CIVS", FALSE);
|
||||
gGameExternalOptions.sEnemyZombieDamageResistance = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_DAMAGE_RESISTANCE", 0, -50, 95);
|
||||
gGameExternalOptions.fZombieOnlyHeadshotsWork = iniReader.ReadBoolean("Tactical Zombie Settings", "ZOMBIE_ONLY_HEADSHOTS_WORK", FALSE);
|
||||
gGameExternalOptions.sZombieDifficultyLevel = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_DIFFICULTY_LEVEL", 2, 1, 4);
|
||||
|
||||
//################# Tactical Poison Settings ##################
|
||||
gGameExternalOptions.ubPoisonBaseMedicalSkillToCure = iniReader.ReadInteger("Tactical Poison Settings", "POISON_BASE_MEDICAL_SKILL_TO_CURE", 50, 1, 100);
|
||||
gGameExternalOptions.sZombiePoisonDamagePercentage = iniReader.ReadInteger("Tactical Poison Settings", "ZOMBIE_POISON_DAMAGE_PERCENTAGE", 50, 0, 100);
|
||||
gGameExternalOptions.sPoisonInfectionDamageMultiplier = iniReader.ReadFloat("Tactical Poison Settings", "POISON_INFECTION_DAMAGE_MULTIPLIER", 4.0, 1.0, 10.0);
|
||||
|
||||
//################# Strategic Gamestart Settings ##################
|
||||
|
||||
//Lalien: Game starting time
|
||||
|
||||
+17
-4
@@ -89,9 +89,7 @@ enum
|
||||
TOPTION_DISABLE_CURSOR_SWAP, // Disable cursor swapping every second between talk and quick exchange
|
||||
TOPTION_QUIET_TRAINING, //Madd: mercs don't say gained experience quote while training
|
||||
TOPTION_AUTO_FAST_FORWARD_MODE, // automatically fast forward through AI turns
|
||||
|
||||
// Flugente FTW 1: Weapon Overheating
|
||||
//TOPTION_WEAPON_OVERHEATING, // allow Overheating of weapons
|
||||
TOPTION_ZOMBIES, // Flugente Zombies 1.0: allow zombies
|
||||
|
||||
// arynn: Debug/Cheat
|
||||
TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
@@ -107,7 +105,7 @@ enum
|
||||
TOPTION_RETAIN_DEBUG_OPTIONS_IN_RELEASE, // allow debug options that were set in debug.exe to continue in a rel.exe (debugging release can be beneficial)
|
||||
TOPTION_DEBUG_MODE_RENDER_OPTIONS_GROUP, // an example option that will show/hide other options
|
||||
TOPTION_RENDER_MOUSE_REGIONS, // an example of a DEBUG build option
|
||||
TOPTION_DEBUG_MODE_OPTIONS_END, // an example options screen options divider (pure text)
|
||||
TOPTION_DEBUG_MODE_OPTIONS_END, // an example options screen options divider (pure text)
|
||||
|
||||
// this is THE LAST option that exists (intended for debugging the options screen, doesnt do anything, except exist)
|
||||
TOPTION_LAST_OPTION,
|
||||
@@ -365,6 +363,21 @@ typedef struct
|
||||
//Video settings
|
||||
BOOLEAN gfVSync;
|
||||
|
||||
// Flugente: zombie settings
|
||||
INT8 sZombieRiseBehaviour;
|
||||
BOOLEAN fZombieSpawnWaves;
|
||||
INT8 sZombieRiseWaveFrequency;
|
||||
BOOLEAN fZombieCanClimb;
|
||||
BOOLEAN fZombieExplodingCivs;
|
||||
INT8 sEnemyZombieDamageResistance;
|
||||
BOOLEAN fZombieOnlyHeadshotsWork;
|
||||
INT8 sZombieDifficultyLevel;
|
||||
|
||||
// Flugente: poison settings
|
||||
INT32 ubPoisonBaseMedicalSkillToCure;
|
||||
INT16 sZombiePoisonDamagePercentage;
|
||||
FLOAT sPoisonInfectionDamageMultiplier;
|
||||
|
||||
//Animation settings
|
||||
FLOAT giPlayerTurnSpeedUpFactor;
|
||||
FLOAT giEnemyTurnSpeedUpFactor;
|
||||
|
||||
+2
-1
@@ -20,8 +20,9 @@ extern CHAR16 zTrackingNumber[16];
|
||||
//
|
||||
// Keeps track of the saved game version. Increment the saved game version whenever
|
||||
// you will invalidate the saved game file
|
||||
#define SAVE_GAME_VERSION 131 //125 //124 //114 //113 //112 //111 //110 //109 //108 //107 //106 //105 //104 //103 //102 //101 //100 // 99
|
||||
#define SAVE_GAME_VERSION 132 //131 //125 //124 //114 //113 //112 //111 //110 //109 //108 //107 //106 //105 //104 //103 //102 //101 //100 // 99
|
||||
|
||||
#define ZOMBIE_CHANGES 132 // Included some changes for Zombies
|
||||
#define JA25_UB_INTEGRATION 131 // Before this, the JA25 Unfinished Business code was not integrated (see "Builddefines.h" JA2UB)
|
||||
#define IMPROVED_INTERRUPT_SYSTEM 130
|
||||
#define ENCYCLOPEDIA_SAVEGAME_CHANGE 129 // Added encyclopedia
|
||||
|
||||
+10
-2
@@ -4959,7 +4959,7 @@ void DisplayDepartedCharStats(INT32 iId, INT32 iSlot, INT32 iState)
|
||||
case 14:
|
||||
// kills
|
||||
mprintf((INT16)(pPersonnelScreenPoints[20].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[20].y - 12),pPersonnelScreenStrings[PRSNL_TXT_KILLS]);
|
||||
swprintf(sString, L"%d",(gMercProfiles[iId].records.usKillsElites + gMercProfiles[iId].records.usKillsRegulars + gMercProfiles[iId].records.usKillsAdmins + gMercProfiles[iId].records.usKillsHostiles + gMercProfiles[iId].records.usKillsCreatures + gMercProfiles[iId].records.usKillsTanks + gMercProfiles[iId].records.usKillsOthers));
|
||||
swprintf(sString, L"%d",(gMercProfiles[iId].records.usKillsElites + gMercProfiles[iId].records.usKillsRegulars + gMercProfiles[iId].records.usKillsAdmins + gMercProfiles[iId].records.usKillsHostiles + gMercProfiles[iId].records.usKillsCreatures + gMercProfiles[iId].records.usKillsZombies + gMercProfiles[iId].records.usKillsTanks + gMercProfiles[iId].records.usKillsOthers));
|
||||
FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[20].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
|
||||
mprintf(sX,(pPersonnelScreenPoints[20].y - 12),sString);
|
||||
|
||||
@@ -6824,7 +6824,7 @@ DEF:3/19/99:
|
||||
case 14:
|
||||
// kills
|
||||
mprintf((INT16)(pPersonnelScreenPoints[20].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[20].y - 12),pPersonnelScreenStrings[PRSNL_TXT_KILLS]);
|
||||
swprintf(sString, L"%d",(gMercProfiles[Menptr[iId].ubProfile].records.usKillsElites + gMercProfiles[Menptr[iId].ubProfile].records.usKillsRegulars + gMercProfiles[Menptr[iId].ubProfile].records.usKillsAdmins + gMercProfiles[Menptr[iId].ubProfile].records.usKillsHostiles + gMercProfiles[Menptr[iId].ubProfile].records.usKillsCreatures + gMercProfiles[Menptr[iId].ubProfile].records.usKillsTanks + gMercProfiles[Menptr[iId].ubProfile].records.usKillsOthers));
|
||||
swprintf(sString, L"%d",(gMercProfiles[Menptr[iId].ubProfile].records.usKillsElites + gMercProfiles[Menptr[iId].ubProfile].records.usKillsRegulars + gMercProfiles[Menptr[iId].ubProfile].records.usKillsAdmins + gMercProfiles[Menptr[iId].ubProfile].records.usKillsHostiles + gMercProfiles[Menptr[iId].ubProfile].records.usKillsCreatures + gMercProfiles[Menptr[iId].ubProfile].records.usKillsZombies + gMercProfiles[Menptr[iId].ubProfile].records.usKillsTanks + gMercProfiles[Menptr[iId].ubProfile].records.usKillsOthers));
|
||||
FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[20].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
|
||||
mprintf(sX,(pPersonnelScreenPoints[20].y - 12),sString);
|
||||
|
||||
@@ -8235,6 +8235,14 @@ void AssignPersonnelKillsHelpText( INT32 IMercId )
|
||||
swprintf(atStr, pPersonnelRecordsHelpTexts[ 6 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsOthers );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
if (gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
{
|
||||
if (gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsZombies > 0 || fShowRecordsIfZero)
|
||||
{
|
||||
swprintf(atStr, pPersonnelRecordsHelpTexts[ 46 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsZombies );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
}
|
||||
|
||||
// Set region help text
|
||||
SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[7]), apStr );
|
||||
|
||||
@@ -3570,7 +3570,7 @@ void recieveEXPLOSIONDAMAGE (RPCParameters *rpcParameters)
|
||||
|
||||
// can use DishOutGasDamage() as it is dependant on the local state of the gas cloud which is not always in sync
|
||||
// but we have the definite results of damage on a merc, so :
|
||||
pSoldier->SoldierTakeDamage( ANIM_STAND, exp->sWoundAmt, exp->sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( ANIM_STAND, exp->sWoundAmt, 0, exp->sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE );
|
||||
}
|
||||
else if (exp->ubDamageFunc == 2)
|
||||
{
|
||||
@@ -4405,7 +4405,7 @@ void recieveDISCONNECT(RPCParameters* rpcParameters)
|
||||
if ( !pTeamSoldier->aiData.bNeutral && (pTeamSoldier->bTeam == iNetbTeam ) )
|
||||
{
|
||||
// KIll......
|
||||
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 100, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
|
||||
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 0, 100, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1972,6 +1972,12 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
|
||||
numBytesRead = ReadFieldByField(hFile, &this->wornSnowCamo, sizeof(wornSnowCamo), sizeof(INT8), numBytesRead);
|
||||
numBytesRead = ReadFieldByField(hFile, &this->sFacilityTypeOperated, sizeof(sFacilityTypeOperated), sizeof(INT16), numBytesRead);
|
||||
numBytesRead = ReadFieldByField(hFile, &this->bScopeMode, sizeof(bScopeMode), sizeof(INT8), numBytesRead);
|
||||
numBytesRead = ReadFieldByField(hFile, &this->bPoisonBleeding, sizeof(bPoisonBleeding), sizeof(INT8), numBytesRead);
|
||||
numBytesRead = ReadFieldByField(hFile, &this->bPoisonLife, sizeof(bPoisonLife), sizeof(INT8), numBytesRead);
|
||||
numBytesRead = ReadFieldByField(hFile, &this->bPoisonSum, sizeof(bPoisonSum), sizeof(INT8), numBytesRead);
|
||||
numBytesRead = ReadFieldByField(hFile, &this->bPoisonResistance, sizeof(bPoisonResistance), sizeof(INT16), numBytesRead);
|
||||
numBytesRead = ReadFieldByField(hFile, &this->bPoisonAbsorption, sizeof(bPoisonAbsorption), sizeof(INT16), numBytesRead);
|
||||
|
||||
#ifdef JA2UB
|
||||
numBytesRead = ReadFieldByField(hFile, &this->fIgnoreGetupFromCollapseCheck, sizeof(fIgnoreGetupFromCollapseCheck), sizeof(BOOLEAN), numBytesRead);
|
||||
numBytesRead = ReadFieldByField(hFile, &this->GetupFromJA25StartCounter, sizeof(GetupFromJA25StartCounter), sizeof(TIMECOUNTER), numBytesRead);
|
||||
@@ -2181,6 +2187,9 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
|
||||
buffer = 28;
|
||||
}
|
||||
numBytesRead += buffer;
|
||||
|
||||
INT32 sizestruct = sizeof(STRUCT_Statistics);
|
||||
|
||||
if(numBytesRead != sizeof(STRUCT_Statistics))
|
||||
return(FALSE);
|
||||
// if ( !FileRead( hFile, &this->stats, sizeof(STRUCT_Statistics), &uiNumBytesRead ) )
|
||||
|
||||
+219
-17
@@ -571,6 +571,8 @@ static BOOLEAN IsGunJammed(const OBJECTTYPE* pObj);
|
||||
/// Collect items that need repairing and add them to the repair queue
|
||||
static void CollectRepairableItems(const SOLDIERTYPE* pSoldier, RepairQueue& itemsToFix);
|
||||
|
||||
extern BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse );
|
||||
|
||||
void InitSectorsWithSoldiersList( void )
|
||||
{
|
||||
// init list of sectors
|
||||
@@ -1121,6 +1123,11 @@ BOOLEAN CanCharacterPatient( SOLDIERTYPE *pSoldier )
|
||||
if ( pSoldier->ubCriticalStatDamage[i] > 0 )
|
||||
return ( TRUE );
|
||||
}
|
||||
|
||||
// Flugente: check if poisoned
|
||||
if ( pSoldier->bPoisonSum > 0 )
|
||||
return( TRUE );
|
||||
|
||||
// if we don't have damaged stat, look if we need healing
|
||||
if ( pSoldier->stats.bLife == pSoldier->stats.bLifeMax )
|
||||
return( FALSE );
|
||||
@@ -2669,8 +2676,8 @@ void UpdatePatientsWhoAreDoneHealing( void )
|
||||
// active soldier?
|
||||
if( pTeamSoldier->bActive )
|
||||
{
|
||||
// patient who doesn't need healing
|
||||
if( ( pTeamSoldier->bAssignment == PATIENT ) &&( pTeamSoldier->stats.bLife == pTeamSoldier->stats.bLifeMax ) )
|
||||
// patient who doesn't need healing or curing
|
||||
if( ( pTeamSoldier->bAssignment == PATIENT ) &&( pTeamSoldier->stats.bLife == pTeamSoldier->stats.bLifeMax ) && ( pTeamSoldier->bPoisonSum == 0 ) )
|
||||
{
|
||||
// SANDRO - added check if we can help to heal lost stats to this one
|
||||
for (UINT8 cnt = 0; cnt < NUM_DAMAGABLE_STATS; cnt++)
|
||||
@@ -2937,8 +2944,21 @@ BOOLEAN CanSoldierBeHealedByDoctor( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pDoctor,
|
||||
// if we have no damaged stat and don't need healing
|
||||
if (!fHealDamagedStat && (pSoldier->stats.bLife == pSoldier->stats.bLifeMax) )
|
||||
{
|
||||
// cannot be healed
|
||||
return( FALSE );
|
||||
// if we are poisoned
|
||||
if ( pSoldier->bPoisonSum )
|
||||
{
|
||||
// if using the new trait system, Doctor skill is needed
|
||||
if ( gGameOptions.fNewTraitSystem && ( NUM_SKILL_TRAITS( pDoctor, DOCTOR_NT ) == 0 ) )
|
||||
{
|
||||
// we may have the medical stats, but we lack the skills!
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
else // if we are not poisoned
|
||||
{
|
||||
// cannot be healed
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
return( TRUE );
|
||||
@@ -2954,6 +2974,12 @@ UINT8 GetMinHealingSkillNeeded( SOLDIERTYPE *pPatient )
|
||||
// less than ok life, return skill needed
|
||||
return( gGameExternalOptions.ubBaseMedicalSkillToDealWithEmergency + ( gGameExternalOptions.ubMultiplierForDifferenceInLifeValueForEmergency * ( OKLIFE - pPatient->stats.bLife ) ) );
|
||||
}
|
||||
// if at full life, only poison needs to be removed
|
||||
else if ( pPatient->stats.bLife == pPatient->stats.bLifeMax && pPatient->bPoisonSum > 0 )
|
||||
{
|
||||
// skill to remove poison needed
|
||||
return( gGameExternalOptions.ubPoisonBaseMedicalSkillToCure );
|
||||
}
|
||||
else
|
||||
{
|
||||
// only need some skill
|
||||
@@ -2967,16 +2993,19 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHundr
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - this whole procedure was heavily changed
|
||||
////////////////////////////////////////////////////
|
||||
UINT16 usHealingPtsLeft;
|
||||
UINT16 usHealingPtsLeft = 0;
|
||||
UINT16 usTotalHundredthsUsed = 0;
|
||||
INT16 sPointsToUse = 0;
|
||||
INT8 bPointsHealed = 0;
|
||||
INT8 bMedFactor;
|
||||
INT8 bMedFactor = 1; // basic medical factor
|
||||
BOOLEAN fWillRepiarStats = FALSE;
|
||||
BOOLEAN fWillHealLife = TRUE;
|
||||
BOOLEAN fWillHealLife = TRUE;
|
||||
UINT16 usTotalMedPoints = 0;
|
||||
UINT16 ubReturnDamagedStatRate = 0;
|
||||
|
||||
// usPointsLeftToCurePoison will measure how much Hundreths will be left to cure poison
|
||||
INT16 usPointsLeftToCurePoison = usHundredthsHealed;
|
||||
|
||||
// Look how much life do we need to heal
|
||||
sPointsToUse = ( pPatient->stats.bLifeMax - pPatient->stats.bLife );
|
||||
if ( sPointsToUse <= 0 )
|
||||
@@ -3008,7 +3037,6 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHundr
|
||||
sPointsToUse = ( INT8 )usHealingPtsLeft;
|
||||
}
|
||||
|
||||
bMedFactor = 1; // basic medical factor
|
||||
// if we will heal life and stats at the same time, increases the medical cost
|
||||
if (fWillRepiarStats && fWillHealLife)
|
||||
{
|
||||
@@ -3071,6 +3099,10 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHundr
|
||||
}
|
||||
}
|
||||
|
||||
// we have to remember what will be left over to cure poison
|
||||
//usPointsLeftToCurePoison = min(usHundredthsHealed, usPointsLeftToCurePoison - usTotalHundredthsUsed);
|
||||
//usPointsLeftToCurePoison = max(usPointsLeftToCurePoison, 0); // do not go below zero
|
||||
|
||||
// if we are actually here to heal life
|
||||
if ( fWillHealLife )
|
||||
{
|
||||
@@ -3084,6 +3116,16 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHundr
|
||||
pPatient->sFractLife %= 100;
|
||||
|
||||
pPatient->stats.bLife = min( pPatient->stats.bLifeMax, (pPatient->stats.bLife + bPointsHealed));
|
||||
|
||||
// potentially increase bPoisonLife: as life points are healed, unhealed poinson points become healed poison points
|
||||
if ( pPatient->bPoisonSum > 0 )
|
||||
{
|
||||
// check if there are unhealed poison points
|
||||
if ( pPatient->bPoisonLife < pPatient->bPoisonSum )
|
||||
{
|
||||
pPatient->bPoisonLife = min( pPatient->bPoisonSum, (pPatient->bPoisonLife + bPointsHealed));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (((pPatient->sFractLife / gGameExternalOptions.ubPointCostPerHealthBelowOkLife) >= 100) && (pPatient->stats.bLife < OKLIFE))
|
||||
{
|
||||
@@ -3091,6 +3133,16 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHundr
|
||||
pPatient->sFractLife %= 100;
|
||||
|
||||
pPatient->stats.bLife = min( pPatient->stats.bLifeMax, (pPatient->stats.bLife + bPointsHealed));
|
||||
|
||||
// potentially increase bPoisonLife: as life points are healed, unhealed poinson points become healed poison points
|
||||
if ( pPatient->bPoisonSum > 0 )
|
||||
{
|
||||
// check if there are unhealed poison points
|
||||
if ( pPatient->bPoisonLife < pPatient->bPoisonSum )
|
||||
{
|
||||
pPatient->bPoisonLife = min( pPatient->bPoisonSum, (pPatient->bPoisonLife + bPointsHealed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// when being healed normally, reduce insta-healable HPs value
|
||||
@@ -3113,6 +3165,65 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHundr
|
||||
}
|
||||
}
|
||||
|
||||
// As curing poison happens only when there is no more life to heal ortats to repair, we don't have to edit the above function - we simply cure afterwards
|
||||
// Look how much poison needs to be cured. Conversion of fresh life points to poison points has already taken place
|
||||
if ( pPatient->bPoisonSum > 0 || pPatient->sFractLife < 0 )
|
||||
{
|
||||
if ( fWillHealLife || fWillRepiarStats )
|
||||
usPointsLeftToCurePoison = max(0, usPointsLeftToCurePoison - usHundredthsHealed);
|
||||
|
||||
if ( usPointsLeftToCurePoison > 0 )
|
||||
{
|
||||
INT8 usPoisontoCure = pPatient->bPoisonSum;
|
||||
|
||||
if ( (INT8) (usPointsLeftToCurePoison/100) < usPoisontoCure )
|
||||
usPoisontoCure = (INT8) (usPointsLeftToCurePoison/100);
|
||||
|
||||
// calculate how much total points we have in all medical bags
|
||||
UINT16 usTotalMedPointsLeft = TotalMedicalKitPoints(pDoctor);
|
||||
|
||||
if ( usTotalMedPointsLeft > 0 )
|
||||
{
|
||||
UINT16 usTotalHundredthsUsedToCurePoison = 0;
|
||||
// if having enough, no problem
|
||||
if (usTotalMedPointsLeft >= (usPoisontoCure * bMedFactor))
|
||||
{
|
||||
usTotalHundredthsUsedToCurePoison = usPoisontoCure * 100;
|
||||
usTotalMedPointsLeft = (usPoisontoCure * bMedFactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// only heal what we have
|
||||
usTotalHundredthsUsedToCurePoison = (usTotalMedPointsLeft * 100 / bMedFactor) ;
|
||||
}
|
||||
|
||||
pPatient->sFractLife += usTotalHundredthsUsedToCurePoison;
|
||||
|
||||
// modify usHundredthsHealed?
|
||||
//usHundredthsHealed += usTotalHundredthsUsedToCurePoison;
|
||||
|
||||
if (pPatient->sFractLife >= 100)
|
||||
{
|
||||
// convert fractions into full points
|
||||
INT8 bPoisonPointsHealed = (pPatient->sFractLife / 100);
|
||||
pPatient->sFractLife %= 100;
|
||||
|
||||
pPatient->bPoisonSum = max( 0, (pPatient->bPoisonSum - bPoisonPointsHealed));
|
||||
pPatient->bPoisonLife = max( 0, (pPatient->bPoisonLife - bPoisonPointsHealed));
|
||||
}
|
||||
|
||||
// Finally use all kit points (we are sure, we have that much)
|
||||
if (UseTotalMedicalKitPoints( pDoctor, usTotalMedPointsLeft ) == FALSE )
|
||||
{
|
||||
// throw message if this went wrong for feedback on debugging
|
||||
#ifdef JA2TESTVERSION
|
||||
ScreenMsg( FONT_MCOLOR_RED, MSG_TESTVERSION, L"Warning! UseTotalKitPOints returned false, not all points were probably used." );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ( usHundredthsHealed );
|
||||
}
|
||||
|
||||
@@ -3176,13 +3287,23 @@ void HealHospitalPatient( SOLDIERTYPE *pPatient, UINT16 usHealingPtsLeft )
|
||||
// if he needs more than we have, reduce to that
|
||||
if( bPointsToUse > usHealingPtsLeft )
|
||||
{
|
||||
bPointsToUse = ( INT8 )usHealingPtsLeft;
|
||||
bPointsToUse = ( INT8 )usHealingPtsLeft;
|
||||
}
|
||||
|
||||
usHealingPtsLeft -= bPointsToUse;
|
||||
|
||||
// heal person the amount / POINT_COST_PER_HEALTH_BELOW_OKLIFE
|
||||
pPatient->stats.bLife += ( bPointsToUse / gGameExternalOptions.ubPointCostPerHealthBelowOkLife );
|
||||
|
||||
// potentially increase bPoisonLife: as life points are healed, unhealed poinson points become healed poison points
|
||||
if ( pPatient->bPoisonSum > 0 )
|
||||
{
|
||||
// check if there are unhealed poison points
|
||||
if ( pPatient->bPoisonLife < pPatient->bPoisonSum )
|
||||
{
|
||||
pPatient->bPoisonLife = min( pPatient->bPoisonSum, (pPatient->bPoisonLife + ( bPointsToUse / gGameExternalOptions.ubPointCostPerHealthBelowOkLife ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
// SANDRO - doctor trait - when being healed normally, reduce insta-healable HPs value
|
||||
if ( gGameOptions.fNewTraitSystem && pPatient->iHealableInjury > 0 )
|
||||
@@ -3209,6 +3330,16 @@ void HealHospitalPatient( SOLDIERTYPE *pPatient, UINT16 usHealingPtsLeft )
|
||||
|
||||
// heal person the amount
|
||||
pPatient->stats.bLife += bPointsToUse;
|
||||
|
||||
// potentially increase bPoisonLife: as life points are healed, unhealed poinson points become healed poison points
|
||||
if ( pPatient->bPoisonSum > 0 )
|
||||
{
|
||||
// check if there are unhealed poison points
|
||||
if ( pPatient->bPoisonLife < pPatient->bPoisonSum )
|
||||
{
|
||||
pPatient->bPoisonLife = min( pPatient->bPoisonSum, (pPatient->bPoisonLife + bPointsToUse) );
|
||||
}
|
||||
}
|
||||
|
||||
// SANDRO - doctor trait - when being healed normally, reduce insta-healable HPs value
|
||||
if ( gGameOptions.fNewTraitSystem && pPatient->iHealableInjury > 0 )
|
||||
@@ -3219,8 +3350,21 @@ void HealHospitalPatient( SOLDIERTYPE *pPatient, UINT16 usHealingPtsLeft )
|
||||
}
|
||||
}
|
||||
|
||||
// if this patient is fully healed
|
||||
if ( pPatient->stats.bLife == pPatient->stats.bLifeMax )
|
||||
// are here still points left to cure poison?
|
||||
if ( usHealingPtsLeft > 0 )
|
||||
{
|
||||
UINT16 usPoisonToCure = pPatient->bPoisonSum;
|
||||
|
||||
if ( usPoisonToCure > usHealingPtsLeft )
|
||||
usPoisonToCure = usHealingPtsLeft;
|
||||
|
||||
usHealingPtsLeft -= usPoisonToCure;
|
||||
|
||||
pPatient->bPoisonSum = max( 0, (pPatient->bPoisonSum - usPoisonToCure));
|
||||
}
|
||||
|
||||
// if this patient is fully healed and cured
|
||||
if ( pPatient->stats.bLife == pPatient->stats.bLifeMax && pPatient->bPoisonSum == 0 )
|
||||
{
|
||||
AssignmentDone( pPatient, TRUE, TRUE );
|
||||
}
|
||||
@@ -4550,7 +4694,7 @@ INT16 GetBonusTrainingPtsDueToInstructor( SOLDIERTYPE *pInstructor, SOLDIERTYPE
|
||||
switch( bTrainStat )
|
||||
{
|
||||
case( STRENGTH ):
|
||||
bTrainerEffSkill = EffectiveStrength ( pInstructor );
|
||||
bTrainerEffSkill = (INT8)EffectiveStrength ( pInstructor );
|
||||
bTrainerNatSkill = pInstructor->stats.bStrength;
|
||||
break;
|
||||
case( DEXTERITY ):
|
||||
@@ -5428,6 +5572,7 @@ void HandleNaturalHealing( void )
|
||||
void HandleHealingByNaturalCauses( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
UINT32 uiPercentHealth = 0;
|
||||
UINT32 uiPercentPoison = 0;
|
||||
INT8 bActivityLevelDivisor = 0;
|
||||
UINT16 usFacilityModifier = 100;
|
||||
UINT8 ubAssignmentType = 0;
|
||||
@@ -5446,7 +5591,7 @@ void HandleHealingByNaturalCauses( SOLDIERTYPE *pSoldier )
|
||||
}
|
||||
|
||||
// lost any pts?
|
||||
if( pSoldier->stats.bLife == pSoldier->stats.bLifeMax )
|
||||
if( pSoldier->stats.bLife == pSoldier->stats.bLifeMax && pSoldier->bPoisonLife == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -5498,6 +5643,9 @@ void HandleHealingByNaturalCauses( SOLDIERTYPE *pSoldier )
|
||||
// what percentage of health is he down to
|
||||
uiPercentHealth = ( pSoldier->stats.bLife * 100 ) / pSoldier->stats.bLifeMax;
|
||||
|
||||
// how much is he poisoned?
|
||||
uiPercentPoison = ( pSoldier->bPoisonSum * 100 ) / pSoldier->stats.bLifeMax;
|
||||
|
||||
// SANDRO - experimental - increase health regenariton of soldiers when doctors are around
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
@@ -5539,6 +5687,11 @@ void HandleHealingByNaturalCauses( SOLDIERTYPE *pSoldier )
|
||||
pSoldier->sFractLife += ( INT16 ) ((( uiPercentHealth / bActivityLevelDivisor ) * usFacilityModifier) / 100 );
|
||||
}
|
||||
|
||||
// Flugente: reduce gained life because of poison
|
||||
// poison resistance reduces poison damage
|
||||
// a high activity level (stress) increases poisoning
|
||||
pSoldier->sFractLife -= ( INT16 ) ( (uiPercentPoison * (100 - pSoldier->GetPoisonResistance())/100) * gGameExternalOptions.sPoisonInfectionDamageMultiplier * ((99 + bActivityLevelDivisor)/100) );
|
||||
|
||||
// now update the real life values
|
||||
UpDateSoldierLife( pSoldier );
|
||||
|
||||
@@ -5549,12 +5702,45 @@ void HandleHealingByNaturalCauses( SOLDIERTYPE *pSoldier )
|
||||
void UpDateSoldierLife( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
// update soldier life, make sure we don't go out of bounds
|
||||
pSoldier->stats.bLife += pSoldier->sFractLife / 100;
|
||||
INT8 sAddedLife = pSoldier->sFractLife/100;
|
||||
|
||||
// if sAddedLife, it must be poison damage
|
||||
if ( sAddedLife < 0 )
|
||||
{
|
||||
// it is hereby possible to heal yourself through poison, if you have high absorption ( > 100%)
|
||||
INT8 sPoisonAbsorped = - (INT8) ( sAddedLife * (pSoldier->GetPoisonAbsorption()/100) );
|
||||
|
||||
sAddedLife += sPoisonAbsorped;
|
||||
|
||||
// if we're not fully poisoned, we are now poisoned a bit more, even if we won life thanks to absorption
|
||||
if ( pSoldier->bPoisonSum < pSoldier->stats.bLifeMax )
|
||||
{
|
||||
pSoldier->bPoisonSum += abs(sAddedLife);
|
||||
}
|
||||
}
|
||||
|
||||
INT8 oldlife = pSoldier->stats.bLife;
|
||||
pSoldier->stats.bLife += sAddedLife;
|
||||
|
||||
// if we fall below OKLIFE (can only be because of poison), we start bleeding again...
|
||||
if ( pSoldier->stats.bLife < OKLIFE && oldlife >= OKLIFE && sAddedLife < 0 )
|
||||
{
|
||||
/*pSoldier->stats.bLife = 0;
|
||||
BOOLEAN fMadeCorpse;
|
||||
HandleSoldierDeath( pSoldier, &fMadeCorpse );*/
|
||||
|
||||
pSoldier->bBleeding = pSoldier->stats.bLifeMax - pSoldier->stats.bLife;
|
||||
pSoldier->bPoisonBleeding = pSoldier->bPoisonSum - pSoldier->bPoisonLife;
|
||||
|
||||
/*pSoldier->bPoisonSum = 0;
|
||||
pSoldier->bPoisonLife = 0;
|
||||
pSoldier->bPoisonBleeding = 0;*/
|
||||
}
|
||||
|
||||
// SANDRO - when being healed normally, reduce insta-healable HPs value
|
||||
if ( gGameOptions.fNewTraitSystem && pSoldier->iHealableInjury > 0 )
|
||||
{
|
||||
pSoldier->iHealableInjury -= pSoldier->sFractLife;
|
||||
pSoldier->iHealableInjury -= sAddedLife * 100;
|
||||
|
||||
if (pSoldier->iHealableInjury < 0)
|
||||
pSoldier->iHealableInjury = 0;
|
||||
@@ -5568,7 +5754,11 @@ void UpDateSoldierLife( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
// reduce
|
||||
pSoldier->stats.bLife = pSoldier->stats.bLifeMax;
|
||||
pSoldier->sFractLife = 0;
|
||||
|
||||
// only set sFractLife to be 0 if > 0, saving possible poison damage
|
||||
if ( pSoldier->sFractLife > 0 )
|
||||
pSoldier->sFractLife = 0;
|
||||
|
||||
pSoldier->iHealableInjury = 0; // check added by SANDRO
|
||||
}
|
||||
return;
|
||||
@@ -8107,7 +8297,9 @@ void BeginRemoveMercFromContract( SOLDIERTYPE *pSoldier )
|
||||
|
||||
// WANNE: Nothing to do here, when we want to dismiss the robot
|
||||
BOOLEAN fAmIaRobot = AM_A_ROBOT( pSoldier );
|
||||
if (!fAmIaRobot)
|
||||
|
||||
// Flugente: If merc is unconscious, just fire him anyway (if talking stuff is called, this leads to a geme lock)
|
||||
if (!fAmIaRobot && pSoldier->stats.bLife > CONSCIOUSNESS )
|
||||
{
|
||||
if( ( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC ) || ( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__NPC ) )
|
||||
{
|
||||
@@ -10938,6 +11130,7 @@ void SetSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment, INT32 iParam
|
||||
|
||||
pSoldier->bOldAssignment = pSoldier->bAssignment;
|
||||
pSoldier->bBleeding = 0;
|
||||
pSoldier->bPoisonBleeding = 0;
|
||||
|
||||
// set dirty flag
|
||||
fTeamPanelDirty = TRUE;
|
||||
@@ -12219,6 +12412,7 @@ void BandageBleedingDyingPatientsBeingTreated( )
|
||||
|
||||
// stop bleeding automatically
|
||||
pSoldier->bBleeding = 0;
|
||||
pSoldier->bPoisonBleeding = 0;
|
||||
|
||||
if ( pSoldier->stats.bLife < OKLIFE )
|
||||
{
|
||||
@@ -12227,7 +12421,14 @@ void BandageBleedingDyingPatientsBeingTreated( )
|
||||
{
|
||||
pSoldier->iHealableInjury -= ((OKLIFE - pSoldier->stats.bLife) * 100);
|
||||
}
|
||||
|
||||
// convert poison points to poison life points
|
||||
INT8 oldlife = pSoldier->stats.bLife;
|
||||
|
||||
pSoldier->stats.bLife = OKLIFE;
|
||||
|
||||
INT8 lifegained = OKLIFE - oldlife;
|
||||
pSoldier->bPoisonLife = min(pSoldier->bPoisonSum, pSoldier->bPoisonLife + lifegained);
|
||||
}
|
||||
}
|
||||
else // assigned to DOCTOR/PATIENT
|
||||
@@ -16417,3 +16618,4 @@ void HaveMercSayWhyHeWontLeave( SOLDIERTYPE *pSoldier )
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -729,6 +729,9 @@ void RefreshMerc( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
pSoldier->stats.bLife = pSoldier->stats.bLifeMax;
|
||||
pSoldier->bBleeding = 0;
|
||||
pSoldier->bPoisonSum = 0;
|
||||
pSoldier->bPoisonLife = 0;
|
||||
pSoldier->bPoisonBleeding = 0;
|
||||
pSoldier->iHealableInjury = 0; // added by SANDRO
|
||||
pSoldier->bBreath = pSoldier->bBreathMax = 100;
|
||||
pSoldier->sBreathRed = 0;
|
||||
@@ -1189,14 +1192,43 @@ void RenderSoldierCellBars( SOLDIERCELL *pCell )
|
||||
iStartY = pCell->yp + 29 - 25*pCell->pSoldier->stats.bLifeMax/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+37, iStartY, pCell->xp+38, pCell->yp+29, Get16BPPColor( FROMRGB( 107, 107, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+38, iStartY, pCell->xp+39, pCell->yp+29, Get16BPPColor( FROMRGB( 222, 181, 115 ) ) );
|
||||
|
||||
// poisoned bleeding in purple
|
||||
if ( pCell->pSoldier->bPoisonBleeding )
|
||||
{
|
||||
iStartY = pCell->yp + 29 - 25*(pCell->pSoldier->stats.bLifeMax - pCell->pSoldier->bBleeding + pCell->pSoldier->bPoisonBleeding)/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+37, iStartY, pCell->xp+38, pCell->yp+29, Get16BPPColor( FROMRGB( 107, 57, 107 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+38, iStartY, pCell->xp+39, pCell->yp+29, Get16BPPColor( FROMRGB( 222, 115, 181 ) ) );
|
||||
}
|
||||
|
||||
//pink one for bandaged.
|
||||
iStartY += 25*pCell->pSoldier->bBleeding/100;
|
||||
iStartY = pCell->yp + 29 - 25*(pCell->pSoldier->stats.bLifeMax - pCell->pSoldier->bBleeding)/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+37, iStartY, pCell->xp+38, pCell->yp+29, Get16BPPColor( FROMRGB( 156, 57, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+38, iStartY, pCell->xp+39, pCell->yp+29, Get16BPPColor( FROMRGB( 222, 132, 132 ) ) );
|
||||
|
||||
// get amount of poisoned bandage
|
||||
INT8 bPoisonBandage = pCell->pSoldier->bPoisonSum - pCell->pSoldier->bPoisonBleeding - pCell->pSoldier->bPoisonLife;
|
||||
if ( bPoisonBandage )
|
||||
{
|
||||
// poisoned bandage in bright green
|
||||
iStartY = pCell->yp + 29 - 25*(pCell->pSoldier->stats.bLife + bPoisonBandage)/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+37, iStartY, pCell->xp+38, pCell->yp+29, Get16BPPColor( FROMRGB( 57, 156, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+38, iStartY, pCell->xp+39, pCell->yp+29, Get16BPPColor( FROMRGB( 132, 222, 132 ) ) );
|
||||
}
|
||||
|
||||
//red one for actual health
|
||||
iStartY = pCell->yp + 29 - 25*pCell->pSoldier->stats.bLife/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+37, iStartY, pCell->xp+38, pCell->yp+29, Get16BPPColor( FROMRGB( 107, 8, 8 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+38, iStartY, pCell->xp+39, pCell->yp+29, Get16BPPColor( FROMRGB( 206, 0, 0 ) ) );
|
||||
|
||||
// poisoned life
|
||||
if ( pCell->pSoldier->bPoisonLife )
|
||||
{
|
||||
iStartY = pCell->yp + 29 - 25*pCell->pSoldier->bPoisonLife/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+37, iStartY, pCell->xp+38, pCell->yp+29, Get16BPPColor( FROMRGB( 8, 107, 8 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+38, iStartY, pCell->xp+39, pCell->yp+29, Get16BPPColor( FROMRGB( 0, 206, 0 ) ) );
|
||||
}
|
||||
|
||||
//BREATH BAR
|
||||
iStartY = pCell->yp + 29 - 25*pCell->pSoldier->bBreathMax/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, pCell->xp+41, iStartY, pCell->xp+42, pCell->yp+29, Get16BPPColor( FROMRGB( 8, 8, 132 ) ) );
|
||||
@@ -1519,6 +1551,11 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
|
||||
pVictim->stats.bLife = OKLIFE;
|
||||
// reduce bleeding by the same number of life points healed up
|
||||
pVictim->bBleeding -= bBelowOKlife;
|
||||
|
||||
// Flugente: increase bPoisonLife, decrease bPoisonBleeding
|
||||
pVictim->bPoisonLife = min(pVictim->bPoisonSum, pVictim->bPoisonLife + bBelowOKlife);
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - bBelowOKlife);
|
||||
|
||||
// use up appropriate # of actual healing points
|
||||
bPtsLeft -= (2 * bBelowOKlife);
|
||||
}
|
||||
@@ -1533,12 +1570,20 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
|
||||
}
|
||||
pVictim->stats.bLife += ( bPtsLeft / 2);
|
||||
pVictim->bBleeding -= ( bPtsLeft / 2);
|
||||
|
||||
// Flugente: increase bPoisonLife, decrease bPoisonBleeding
|
||||
pVictim->bPoisonLife = min(pVictim->bPoisonSum, pVictim->bPoisonLife + ( bPtsLeft / 2));
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - ( bPtsLeft / 2));
|
||||
|
||||
bPtsLeft = bPtsLeft % 2; // if ptsLeft was odd, ptsLeft = 1
|
||||
}
|
||||
|
||||
// this should never happen any more, but make sure bleeding not negative
|
||||
if (pVictim->bBleeding < 0)
|
||||
{
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
|
||||
// if this healing brought the patient out of the worst of it, cancel dying
|
||||
if (pVictim->stats.bLife >= OKLIFE )
|
||||
@@ -1612,22 +1657,27 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
|
||||
if ((pVictim->stats.bLife + (iLifeReturned / 100)) <= pVictim->stats.bLifeMax)
|
||||
{
|
||||
pVictim->stats.bLife += (iLifeReturned/100);
|
||||
pVictim->bPoisonLife = min(pVictim->bPoisonSum, pVictim->bPoisonLife + (iLifeReturned/100));
|
||||
if (pVictim->bBleeding >= (iLifeReturned/100))
|
||||
{
|
||||
pVictim->bBleeding -= (iLifeReturned/100);
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - (iLifeReturned/100));
|
||||
uiMedcost += (iLifeReturned / 200); // add medkit points cost for unbandaged part
|
||||
}
|
||||
else
|
||||
{
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
uiMedcost += max( 0, (((iLifeReturned/100) - pVictim->bBleeding) / 2)); // add medkit points cost for unbandaged part
|
||||
}
|
||||
}
|
||||
else // this shouldn't even happen, but we still want to have it here for sure
|
||||
{
|
||||
pVictim->stats.bLife = pVictim->stats.bLifeMax;
|
||||
pVictim->bPoisonLife = pVictim->bPoisonSum;
|
||||
pVictim->iHealableInjury = 0;
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
// Reduce max breath based on life returned
|
||||
if ( (pVictim->bBreathMax - (((iLifeReturned/100) * gSkillTraitValues.usDOSurgeryMaxBreathLoss )/ 100)) <= BREATHMAX_ABSOLUTE_MINIMUM )
|
||||
@@ -1654,10 +1704,12 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
|
||||
{
|
||||
bPtsLeft -= pVictim->bBleeding;
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
else // bandage what we can
|
||||
{
|
||||
pVictim->bBleeding -= bPtsLeft;
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - bPtsLeft);
|
||||
bPtsLeft = 0;
|
||||
}
|
||||
}
|
||||
@@ -4541,13 +4593,16 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
|
||||
case SOLDIER_CLASS_CREATURE :
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsCreatures++;
|
||||
break;
|
||||
case SOLDIER_CLASS_ZOMBIE :
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsZombies++;
|
||||
break;
|
||||
default :
|
||||
if ( CREATURE_OR_BLOODCAT( pTarget->pSoldier ) )
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsCreatures++;
|
||||
else if ( TANK( pTarget->pSoldier ) ) // we hardly can kill a tank in autoresolve, but well.. who knows..
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsTanks++;
|
||||
else if ( pTarget->pSoldier->bTeam == CIV_TEAM && !pTarget->pSoldier->aiData.bNeutral && pTarget->pSoldier->bSide != gbPlayerNum )
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsHostiles++;
|
||||
else if ( TANK( pTarget->pSoldier ) ) // we hardly can kill a tank in autoresolve, but well.. who knows..
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsTanks++;
|
||||
else if ( pTarget->pSoldier->bTeam == CIV_TEAM && !pTarget->pSoldier->aiData.bNeutral && pTarget->pSoldier->bSide != gbPlayerNum )
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsHostiles++;
|
||||
else
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsOthers++;
|
||||
break;
|
||||
@@ -4729,6 +4784,9 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
|
||||
case SOLDIER_CLASS_CREATURE :
|
||||
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsCreatures++;
|
||||
break;
|
||||
case SOLDIER_CLASS_ZOMBIE :
|
||||
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsZombies++;
|
||||
break;
|
||||
default :
|
||||
if ( CREATURE_OR_BLOODCAT( pTarget->pSoldier ) )
|
||||
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsCreatures++;
|
||||
|
||||
@@ -1722,7 +1722,7 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
|
||||
if (Result < 0)
|
||||
{
|
||||
// Soldier is suffering direct unbandaged injury.
|
||||
pSoldier->SoldierTakeDamage( 0, abs(Result), abs(Result), TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, FALSE );
|
||||
pSoldier->SoldierTakeDamage( 0, abs(Result), 0, abs(Result), TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, FALSE );
|
||||
fBadResult = TRUE;
|
||||
|
||||
// SANDRO - add to merc records - facility accidents counter
|
||||
|
||||
@@ -1972,10 +1972,23 @@ void UpdateCharRegionHelpText( void )
|
||||
{
|
||||
// person (health/energy/morale)
|
||||
GetMoraleString( pSoldier, pMoraleStr );
|
||||
swprintf( sString, L"%s: %d/%d, %s: %d/%d, %s: %s",
|
||||
pMapScreenStatusStrings[ 0 ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax,
|
||||
pMapScreenStatusStrings[ 1 ], pSoldier->bBreath, pSoldier->bBreathMax,
|
||||
pMapScreenStatusStrings[ 2 ], pMoraleStr );
|
||||
|
||||
if ( pSoldier->bPoisonSum )
|
||||
{
|
||||
INT8 bPoisonBandaged = pSoldier->bPoisonSum - pSoldier->bPoisonBleeding - pSoldier->bPoisonLife;
|
||||
swprintf( sString, L"%s: %d/%d, %s: %d/%d/%d - %d, %s: %d/%d, %s: %s",
|
||||
pMapScreenStatusStrings[ 0 ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax,
|
||||
pMapScreenStatusStrings[ 5 ], pSoldier->bPoisonBleeding, bPoisonBandaged, pSoldier->bPoisonLife, pSoldier->bPoisonSum,
|
||||
pMapScreenStatusStrings[ 1 ], pSoldier->bBreath, pSoldier->bBreathMax,
|
||||
pMapScreenStatusStrings[ 2 ], pMoraleStr );
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( sString, L"%s: %d/%d, %s: %d/%d, %s: %s",
|
||||
pMapScreenStatusStrings[ 0 ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax,
|
||||
pMapScreenStatusStrings[ 1 ], pSoldier->bBreath, pSoldier->bBreathMax,
|
||||
pMapScreenStatusStrings[ 2 ], pMoraleStr );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -5358,16 +5371,42 @@ void RenderSoldierSmallFaceForUpdatePanel( INT32 iIndex, INT32 iX, INT32 iY )
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+36, iStartY, iX+37, iY+29, Get16BPPColor( FROMRGB( 107, 107, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+37, iStartY, iX+38, iY+29, Get16BPPColor( FROMRGB( 222, 181, 115 ) ) );
|
||||
|
||||
if ( pSoldier->bPoisonBleeding )
|
||||
{
|
||||
// poisoned bleeding in purple
|
||||
iStartY = iY + 29 - 27*(pSoldier->stats.bLifeMax - pSoldier->bBleeding + pSoldier->bPoisonBleeding)/100;
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+36, iStartY, iX+37, iY+29, Get16BPPColor( FROMRGB( 107, 57, 107 ) ) );
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+37, iStartY, iX+38, iY+29, Get16BPPColor( FROMRGB( 222, 115, 181 ) ) );
|
||||
}
|
||||
|
||||
//pink one for bandaged.
|
||||
iStartY += 27*pSoldier->bBleeding/100;
|
||||
iStartY = iY + 29 - 27*(pSoldier->stats.bLifeMax - pSoldier->bBleeding)/100;
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+36, iStartY, iX+37, iY+29, Get16BPPColor( FROMRGB( 156, 57, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+37, iStartY, iX+38, iY+29, Get16BPPColor( FROMRGB( 222, 132, 132 ) ) );
|
||||
|
||||
// get amount of poisoned bandage
|
||||
INT8 bPoisonBandage = pSoldier->bPoisonSum - pSoldier->bPoisonBleeding - pSoldier->bPoisonLife;
|
||||
if ( bPoisonBandage )
|
||||
{
|
||||
// poisoned bandage in bright green
|
||||
iStartY = iY + 29 - 27*(pSoldier->stats.bLife + bPoisonBandage)/100;
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+36, iStartY, iX+37, iY+29, Get16BPPColor( FROMRGB( 57, 156, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+37, iStartY, iX+38, iY+29, Get16BPPColor( FROMRGB( 132, 222, 132 ) ) );
|
||||
}
|
||||
|
||||
//red one for actual health
|
||||
iStartY = iY + 29 - 27*pSoldier->stats.bLife/100;
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+36, iStartY, iX+37, iY+29, Get16BPPColor( FROMRGB( 107, 8, 8 ) ) );
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+37, iStartY, iX+38, iY+29, Get16BPPColor( FROMRGB( 206, 0, 0 ) ) );
|
||||
|
||||
// poisoned life
|
||||
if ( pSoldier->bPoisonLife )
|
||||
{
|
||||
iStartY = iY + 29 - 27*pSoldier->bPoisonLife/100;
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+36, iStartY, iX+37, iY+29, Get16BPPColor( FROMRGB( 8, 107, 8 ) ) );
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+37, iStartY, iX+38, iY+29, Get16BPPColor( FROMRGB( 0, 206, 0 ) ) );
|
||||
}
|
||||
|
||||
//BREATH BAR
|
||||
iStartY = iY + 29 - 27*pSoldier->bBreathMax/100;
|
||||
ColorFillVideoSurfaceArea( guiSAVEBUFFER, iX+39, iStartY, iX+40, iY+29, Get16BPPColor( FROMRGB( 8, 8, 132 ) ) );
|
||||
|
||||
@@ -496,6 +496,10 @@ BOOLEAN WillMercRenew( SOLDIERTYPE *pSoldier, BOOLEAN fSayQuote )
|
||||
if( pSoldier->ubWhatKindOfMercAmI != MERC_TYPE__AIM_MERC )
|
||||
return( FALSE );
|
||||
|
||||
// Flugente: an unconscious merc can't say 'yes' to a contract renewal
|
||||
if ( pSoldier->stats.bLife < CONSCIOUSNESS )
|
||||
return( FALSE );
|
||||
|
||||
// does the merc have another contract already lined up?
|
||||
if( pSoldier->flags.fSignedAnotherContract )
|
||||
{
|
||||
|
||||
@@ -2174,6 +2174,7 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
|
||||
|
||||
//Bandaging him would prevent him from dying (due to low HP)
|
||||
pSoldier->bBleeding = 0;
|
||||
pSoldier->bPoisonBleeding = 0;
|
||||
|
||||
// wake him up
|
||||
if ( pSoldier->flags.fMercAsleep )
|
||||
@@ -2183,6 +2184,7 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
|
||||
}
|
||||
|
||||
//Set his life to 50% + or - 10 HP.
|
||||
INT8 oldlife = pSoldier->stats.bLife;
|
||||
pSoldier->stats.bLife = pSoldier->stats.bLifeMax / 2;
|
||||
if ( pSoldier->stats.bLife <= 35 )
|
||||
{
|
||||
@@ -2192,6 +2194,14 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
pSoldier->stats.bLife += (INT8)(10 - Random( 21 ) );
|
||||
}
|
||||
|
||||
// adjust poison points
|
||||
INT8 lifechanged = oldlife - pSoldier->stats.bLife;
|
||||
if ( lifechanged < 0 )
|
||||
pSoldier->bPoisonLife -= lifechanged;
|
||||
else if ( lifechanged > 0)
|
||||
pSoldier->bPoisonLife = max(pSoldier->bPoisonSum, pSoldier->bPoisonLife + lifechanged);
|
||||
|
||||
// SANDRO - make the lost life insta-healable
|
||||
pSoldier->iHealableInjury = ((pSoldier->stats.bLifeMax - pSoldier->stats.bLife) * 100);
|
||||
|
||||
|
||||
@@ -1305,16 +1305,42 @@ BOOLEAN RenderSoldierSmallFaceForAutoBandagePanel( INT32 iIndex, INT16 sCurrentX
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+36, iStartY, sCurrentXPosition+37, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 107, 107, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+37, iStartY, sCurrentXPosition+38, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 222, 181, 115 ) ) );
|
||||
|
||||
// poisoned bleeding in purple
|
||||
if ( pSoldier->bPoisonBleeding )
|
||||
{
|
||||
iStartY = sCurrentYPosition + 29 - 27*(pSoldier->stats.bLifeMax - pSoldier->bBleeding + pSoldier->bPoisonBleeding)/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+36, iStartY, sCurrentXPosition+37, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 107, 57, 107 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+37, iStartY, sCurrentXPosition+38, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 222, 115, 181 ) ) );
|
||||
}
|
||||
|
||||
//pink one for bandaged.
|
||||
iStartY += 27*pSoldier->bBleeding/100;
|
||||
iStartY = sCurrentYPosition + 29 - 27*(pSoldier->stats.bLifeMax - pSoldier->bBleeding)/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+36, iStartY, sCurrentXPosition+37, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 156, 57, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+37, iStartY, sCurrentXPosition+38, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 222, 132, 132 ) ) );
|
||||
|
||||
// get amount of poisoned bandage
|
||||
INT8 bPoisonBandage = pSoldier->bPoisonSum - pSoldier->bPoisonBleeding - pSoldier->bPoisonLife;
|
||||
if ( bPoisonBandage )
|
||||
{
|
||||
// poisoned bandage in bright green
|
||||
iStartY = sCurrentYPosition + 29 - 27*(pSoldier->stats.bLife + bPoisonBandage)/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+36, iStartY, sCurrentXPosition+37, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 57, 156, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+37, iStartY, sCurrentXPosition+38, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 132, 222, 132 ) ) );
|
||||
}
|
||||
|
||||
//red one for actual health
|
||||
iStartY = sCurrentYPosition + 29 - 27*pSoldier->stats.bLife/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+36, iStartY, sCurrentXPosition+37, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 107, 8, 8 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+37, iStartY, sCurrentXPosition+38, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 206, 0, 0 ) ) );
|
||||
|
||||
// poisoned life
|
||||
if ( pSoldier->bPoisonLife )
|
||||
{
|
||||
iStartY = sCurrentYPosition + 29 - 27*pSoldier->bPoisonLife/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+36, iStartY, sCurrentXPosition+37, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 8, 107, 8 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+37, iStartY, sCurrentXPosition+38, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 0, 206, 0 ) ) );
|
||||
}
|
||||
|
||||
//BREATH BAR
|
||||
iStartY = sCurrentYPosition + 29 - 27*pSoldier->bBreathMax/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, sCurrentXPosition+39, iStartY, sCurrentXPosition+40, sCurrentYPosition+29, Get16BPPColor( FROMRGB( 8, 8, 132 ) ) );
|
||||
|
||||
@@ -1035,6 +1035,10 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, INT8 iTauntType )
|
||||
VIDEO_OVERLAY_DESC VideoOverlayDesc;
|
||||
CHAR16 gzTauntQuote[ 320 ];
|
||||
|
||||
// Flugente: zombies don't talk
|
||||
if ( pCiv->IsZombie() )
|
||||
return;
|
||||
|
||||
// if we have a different quote on, return, this one is not important
|
||||
if ( gCivQuoteData.bActive )
|
||||
{
|
||||
|
||||
@@ -334,8 +334,9 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
|
||||
// bBandaged = BANDAGED( pSoldier );
|
||||
|
||||
// increase life
|
||||
pSoldier->bPoisonLife = max(pSoldier->bPoisonSum, pSoldier->bPoisonLife + pSoldier->stats.bLife - __min( pSoldier->stats.bLife + LIFE_GAIN_PER_REGEN_POINT, pSoldier->stats.bLifeMax ) );
|
||||
pSoldier->stats.bLife = __min( pSoldier->stats.bLife + LIFE_GAIN_PER_REGEN_POINT, pSoldier->stats.bLifeMax );
|
||||
|
||||
|
||||
//SANDRO - Insta-healable injury reduction
|
||||
if( pSoldier->iHealableInjury > 0 )
|
||||
{
|
||||
@@ -345,12 +346,14 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
|
||||
if ( pSoldier->stats.bLife == pSoldier->stats.bLifeMax )
|
||||
{
|
||||
pSoldier->bBleeding = 0;
|
||||
pSoldier->bPoisonBleeding = 0;
|
||||
pSoldier->iHealableInjury = 0;
|
||||
}
|
||||
else if ( pSoldier->bBleeding + pSoldier->stats.bLife > pSoldier->stats.bLifeMax )
|
||||
{
|
||||
// got to reduce amount of bleeding
|
||||
pSoldier->bBleeding = (pSoldier->stats.bLifeMax - pSoldier->stats.bLife);
|
||||
pSoldier->bPoisonBleeding = min(pSoldier->bPoisonBleeding, (pSoldier->stats.bLifeMax - pSoldier->stats.bLife));
|
||||
}
|
||||
|
||||
// decrement counter
|
||||
|
||||
@@ -4575,7 +4575,7 @@ void SetOffBoobyTrapInMapScreen( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
|
||||
}
|
||||
|
||||
// injure the inventory character
|
||||
pSoldier->SoldierTakeDamage( 0, ubPtsDmg, ubPtsDmg, TAKE_DAMAGE_EXPLOSION, NOBODY, NOWHERE, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( 0, ubPtsDmg, 0, ubPtsDmg, TAKE_DAMAGE_EXPLOSION, NOBODY, NOWHERE, 0, TRUE );
|
||||
|
||||
// play the sound
|
||||
PlayJA2Sample( EXPLOSION_1, RATE_11025, BTNVOLUME, 1, MIDDLEPAN );
|
||||
|
||||
@@ -760,13 +760,23 @@ void RenderTopmostTacticalInterface( )
|
||||
SetFontForeground( FONT_MCOLOR_WHITE );
|
||||
|
||||
bool showDamage = true;
|
||||
if (gGameExternalOptions.ubEnemyHitCount > 0 && pSoldier->bTeam == ENEMY_TEAM || pSoldier->bTeam == CREATURE_TEAM)
|
||||
if (gGameExternalOptions.ubEnemyHitCount > 0 && ( pSoldier->bTeam == ENEMY_TEAM || pSoldier->bTeam == CREATURE_TEAM) )
|
||||
showDamage = false;
|
||||
|
||||
if (showDamage)
|
||||
{
|
||||
gprintfdirty( sDamageX, sDamageY, L"-%d", pSoldier->sDamage );
|
||||
mprintf( sDamageX, sDamageY, L"-%d", pSoldier->sDamage );
|
||||
{
|
||||
if ( pSoldier->sDamage >= 0 )
|
||||
{
|
||||
gprintfdirty( sDamageX, sDamageY, L"-%d", pSoldier->sDamage );
|
||||
mprintf( sDamageX, sDamageY, L"-%d", pSoldier->sDamage );
|
||||
}
|
||||
else // Flugente: it is possible that someone might regain negative damage as zombies can regenerate health through bleeding
|
||||
{
|
||||
SetFontForeground( FONT_MCOLOR_LTGREEN );
|
||||
gprintfdirty( sDamageX, sDamageY, L"+%d", -pSoldier->sDamage );
|
||||
mprintf( sDamageX, sDamageY, L"+%d", -pSoldier->sDamage );
|
||||
SetFontForeground( FONT_MCOLOR_WHITE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2268,6 +2268,7 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
|
||||
DeleteTalkingMenu();
|
||||
SetSoldierNeutral( pSoldier );
|
||||
pSoldier->bBleeding = 0; // make sure he doesn't bleed now...
|
||||
pSoldier->bPoisonBleeding = 0;
|
||||
RecalculateOppCntsDueToBecomingNeutral( pSoldier );
|
||||
if ( gTacticalStatus.uiFlags & INCOMBAT )
|
||||
{
|
||||
@@ -4445,6 +4446,9 @@ UINT32 CalcPatientMedicalCost( SOLDIERTYPE * pSoldier )
|
||||
uiCost += ( 25 * ( OKLIFE - pSoldier->stats.bLife ) );
|
||||
}
|
||||
|
||||
// charge additional $13 for every poison point that has to be cured
|
||||
uiCost += 13 * pSoldier->bPoisonSum;
|
||||
|
||||
// also charge $2 for each point of bleeding that must be stopped
|
||||
if ( pSoldier->bBleeding > 0 )
|
||||
{
|
||||
|
||||
+164
-236
@@ -95,6 +95,8 @@ UINT32 guiItemInfoArmorIcon;
|
||||
UINT32 guiItemInfoSecondaryIcon;
|
||||
// HEADROCK HAM 4: This replaces "Misc" icons.
|
||||
UINT32 guiItemInfoAdvancedIcon;
|
||||
// Flugente: added icons for WH40K
|
||||
UINT32 guiItemInfoWH40KIcon;
|
||||
|
||||
// HEADROCK HAM 4: New tooltip regions for UDB replace the old regions.
|
||||
#define NUM_UDB_FASTHELP_REGIONS 102
|
||||
@@ -1376,6 +1378,10 @@ BOOLEAN InternalInitEnhancedDescBox()
|
||||
strcpy( VObjectDesc.ImageFile, "INTERFACE\\ItemInfoAdvancedIcons.STI" );
|
||||
CHECKF( AddVideoObject( &VObjectDesc, &guiItemInfoAdvancedIcon ) );
|
||||
|
||||
// Flugente: added icons for WH40K
|
||||
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
|
||||
strcpy( VObjectDesc.ImageFile, "INTERFACE\\ItemInfoWH40KIcons.STI" );
|
||||
CHECKF( AddVideoObject( &VObjectDesc, &guiItemInfoWH40KIcon ) );
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
@@ -1879,7 +1885,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
|
||||
CHAR16 pStr[1000];
|
||||
|
||||
///////////////// PRIMARY DATA - ICONS
|
||||
for (cnt = 0; cnt < 4; cnt++)
|
||||
for (cnt = 0; cnt < 5; cnt++)
|
||||
{
|
||||
MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
|
||||
(INT16)(gItemDescGenRegions[cnt][0].sLeft),
|
||||
@@ -1919,6 +1925,14 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 3 ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] ) // Flugente Zombies
|
||||
{
|
||||
//////////////////// POISON PERCENTAGE
|
||||
{
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 4 ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3850,6 +3864,51 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente Zombies
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
{
|
||||
if(!cnt) cnt += 2;
|
||||
|
||||
if (cnt >= sFirstLine && cnt < sLastLine)
|
||||
{
|
||||
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), gzUDBGenIndexTooltipText[ 0 ] );
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
|
||||
|
||||
iRegionsCreated++;
|
||||
|
||||
for (cnt2 = 1; cnt2 < 4; cnt2++)
|
||||
{
|
||||
MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
|
||||
(INT16)(gItemDescAdvIndexRegions[cnt-sFirstLine][cnt2].sLeft),
|
||||
(INT16)(gItemDescAdvIndexRegions[cnt-sFirstLine][cnt2].sTop),
|
||||
(INT16)(gItemDescAdvIndexRegions[cnt-sFirstLine][cnt2].sRight),
|
||||
(INT16)(gItemDescAdvIndexRegions[cnt-sFirstLine][cnt2].sBottom),
|
||||
MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
|
||||
|
||||
MSYS_AddRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) + cnt2]);
|
||||
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) + cnt2]), gzUDBGenIndexTooltipText[ cnt2 ] );
|
||||
SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) + cnt2]), HelpTextDoneCallback );
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) + cnt2] );
|
||||
|
||||
iRegionsCreated++;
|
||||
}
|
||||
}
|
||||
++cnt;
|
||||
|
||||
///////////////////// poison percentage
|
||||
// only draw if item is poisoned in any way
|
||||
if ( Item[gpItemDescObject->usItem].bPoisonPercentage != 0 || (Item[gpItemDescObject->usItem].usItemClass == IC_GUN && AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].poisonPercentage != 0 ) )
|
||||
{
|
||||
if (cnt >= sFirstLine && cnt < sLastLine)
|
||||
{
|
||||
swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 56 ], szUDBAdvStatsExplanationsTooltipText[ 56 ]);
|
||||
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
gubDescBoxTotalAdvLines = (UINT8)cnt;
|
||||
}
|
||||
@@ -3866,6 +3925,7 @@ void DeleteEnhancedDescBox( UINT32 guiCurrentItemDescriptionScreen )
|
||||
// HEADROCK HAM 4: Delete new icons
|
||||
DeleteVideoObjectFromIndex( guiItemInfoSecondaryIcon );
|
||||
DeleteVideoObjectFromIndex( guiItemInfoAdvancedIcon );
|
||||
DeleteVideoObjectFromIndex( guiItemInfoWH40KIcon );
|
||||
|
||||
if ( UsingEDBSystem() > 0 )
|
||||
{
|
||||
@@ -4244,6 +4304,13 @@ void DrawAmmoStats( OBJECTTYPE * gpItemDescObject )
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 16, gItemDescGenRegions[3][0].sLeft+sOffsetX, gItemDescGenRegions[3][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
}
|
||||
}
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] ) // Flugente Zombies
|
||||
{
|
||||
//////////////// POISON PERCENTAGE
|
||||
{
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWH40KIcon, 6, gItemDescGenRegions[4][0].sLeft+sOffsetX, gItemDescGenRegions[4][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
DrawSecondaryStats( gpItemDescObject );
|
||||
}
|
||||
@@ -5130,6 +5197,25 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente Zombies
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
{
|
||||
if(!cnt) cnt += 2;
|
||||
|
||||
++cnt; // for the new index-line
|
||||
|
||||
///////////////////// poison percentage
|
||||
// only draw if item is poisoned in any way
|
||||
if ( Item[gpItemDescObject->usItem].bPoisonPercentage != 0 || (Item[gpItemDescObject->usItem].usItemClass == IC_GUN && AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].poisonPercentage != 0 ) )
|
||||
{
|
||||
if (cnt >= sFirstLine && cnt < sLastLine)
|
||||
{
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWH40KIcon, 6, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawMiscStats( OBJECTTYPE * gpItemDescObject )
|
||||
@@ -7246,7 +7332,6 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
|
||||
}
|
||||
if (gubDescBoxPage == 2)
|
||||
{
|
||||
@@ -7511,6 +7596,59 @@ void DrawAmmoValues( OBJECTTYPE * gpItemDescObject, int shotsLeft )
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] ) // Flugente Zombies
|
||||
{
|
||||
///////////////////// POISON PERCENTAGE
|
||||
// Set line to draw into
|
||||
ubNumLine = 4;
|
||||
// Set Y coordinates
|
||||
sTop = gItemDescGenRegions[ubNumLine][1].sTop;
|
||||
sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
|
||||
|
||||
// base modificator
|
||||
INT16 basevalue = AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].poisonPercentage;
|
||||
INT16 modificator = 0; // Does not exist (yet?)
|
||||
INT16 finalvalue = basevalue - modificator;
|
||||
|
||||
// Print base value
|
||||
SetFontForeground( 5 );
|
||||
sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
|
||||
sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
|
||||
swprintf( pStr, L"%d", basevalue );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
mprintf( usX, usY, pStr );
|
||||
|
||||
// modifier
|
||||
SetFontForeground( 5 );
|
||||
if ( modificator > 0 )
|
||||
{
|
||||
SetFontForeground( ITEMDESC_FONTPOSITIVE );
|
||||
swprintf( pStr, L"%d", modificator );
|
||||
}
|
||||
else if ( modificator < 0 )
|
||||
{
|
||||
SetFontForeground( ITEMDESC_FONTNEGATIVE );
|
||||
swprintf( pStr, L"%d", modificator );
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pStr, L"--" );
|
||||
}
|
||||
|
||||
sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
|
||||
sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
mprintf( usX, usY, pStr );
|
||||
|
||||
// Print final value
|
||||
SetFontForeground( FONT_MCOLOR_WHITE );
|
||||
sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
|
||||
sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
|
||||
swprintf( pStr, L"%d", finalvalue );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
}
|
||||
else if (gubDescBoxPage == 2)
|
||||
{
|
||||
@@ -10660,47 +10798,6 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
|
||||
///////////////////// MAX COUNTER FORCE
|
||||
iFloatModifier[0] = CalcCounterForceMax( gpItemDescSoldier, gpItemDescObject, ANIM_STAND );
|
||||
iFloatModifier[1] = CalcCounterForceMax( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH );
|
||||
iFloatModifier[2] = CalcCounterForceMax( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE );
|
||||
if ((iFloatModifier[0] != 0 || iFloatModifier[1] != 0 || iFloatModifier[2] != 0) && UsingNewCTHSystem() == true && Item[gpItemDescObject->usItem].usItemClass == IC_GUN )
|
||||
{
|
||||
if (cnt >= sFirstLine && cnt < sLastLine)
|
||||
{
|
||||
// Set Y coordinates
|
||||
sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
|
||||
sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
|
||||
|
||||
// Print Values
|
||||
for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
|
||||
{
|
||||
SetFontForeground( 5 );
|
||||
sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
|
||||
sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
|
||||
if (iFloatModifier[cnt2] > 0)
|
||||
{
|
||||
SetFontForeground( ITEMDESC_FONTPOSITIVE );
|
||||
swprintf( pStr, L"%3.1f", iFloatModifier[cnt2] );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
}
|
||||
else if (iFloatModifier[cnt2] < 0)
|
||||
{
|
||||
SetFontForeground( ITEMDESC_FONTNEGATIVE );
|
||||
swprintf( pStr, L"%3.1f", iFloatModifier[cnt2] );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pStr, L"--" );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
}
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
|
||||
// HEADROCK HAM 5: Counter-Force Frequency has been removed from the game in favour of a more realistic system.
|
||||
/*
|
||||
@@ -10783,7 +10880,7 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
|
||||
sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
|
||||
|
||||
iFloatModifier[0] = Weapon[ Item[gpItemDescObject->usItem].ubClassIndex].usOverheatingSingleShotTemperature;
|
||||
iFloatModifier[0] = Weapon[ gpItemDescObject->usItem ].usOverheatingSingleShotTemperature;
|
||||
|
||||
iFloatModifier[1] = GetSingleShotTemperature( gpItemDescObject ) - iFloatModifier[0];
|
||||
iFloatModifier[2] = GetSingleShotTemperature( gpItemDescObject );
|
||||
@@ -10890,7 +10987,7 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
|
||||
sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
|
||||
|
||||
iFloatModifier[0] = Weapon[ Item[gpItemDescObject->usItem].ubClassIndex].usOverheatingJamThreshold;
|
||||
iFloatModifier[0] = Weapon[ gpItemDescObject->usItem ].usOverheatingJamThreshold;
|
||||
iFloatModifier[1] = GetOverheatJamThreshold(gpItemDescObject) - iFloatModifier[0];
|
||||
iFloatModifier[2] = GetOverheatJamThreshold(gpItemDescObject);
|
||||
|
||||
@@ -10943,7 +11040,7 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
|
||||
sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
|
||||
|
||||
iFloatModifier[0] = Weapon[ Item[gpItemDescObject->usItem].ubClassIndex].usOverheatingDamageThreshold;
|
||||
iFloatModifier[0] = Weapon[ gpItemDescObject->usItem ].usOverheatingDamageThreshold;
|
||||
iFloatModifier[1] = GetOverheatDamageThreshold(gpItemDescObject) - iFloatModifier[0];
|
||||
iFloatModifier[2] = GetOverheatDamageThreshold(gpItemDescObject);
|
||||
|
||||
@@ -11070,11 +11167,14 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente Zombies
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
{
|
||||
///////////////////////////////////////////////////// INDEXES
|
||||
if(!cnt) cnt += 2;
|
||||
|
||||
// various overheating modificators
|
||||
if ( ( Item[gpItemDescObject->usItem].overheatTemperatureModificator != 0.0 ) || ( Item[gpItemDescObject->usItem].overheatCooldownModificator != 0.0 ) || ( Item[gpItemDescObject->usItem].overheatJamThresholdModificator != 0.0 ) || ( Item[gpItemDescObject->usItem].overheatDamageThresholdModificator != 0.0 ) )
|
||||
{
|
||||
///////////////////////////////////////////////////// INDEXES
|
||||
if (cnt >= sFirstLine && cnt < sLastLine)
|
||||
{
|
||||
SetFontForeground( FONT_MCOLOR_WHITE );
|
||||
@@ -11099,31 +11199,32 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
}
|
||||
++cnt;
|
||||
|
||||
///////////////////// TEMPERATURE MODIFICATOR
|
||||
iFloatModifier[0] = Item[gpItemDescObject->usItem].overheatTemperatureModificator;
|
||||
iFloatModifier[1] = 0.0; // doesn't exist (yet?)
|
||||
iFloatModifier[2] = iFloatModifier[0];
|
||||
///////////////////// poison percentage
|
||||
iModifier[0] = Item[gpItemDescObject->usItem].bPoisonPercentage;
|
||||
|
||||
if ( iFloatModifier[0] != 0 )
|
||||
UINT8 ammotype = (*gpItemDescObject)[0]->data.gun.ubGunAmmoType; // ... get type of ammunition used ...
|
||||
|
||||
iModifier[1] = AmmoTypes[ammotype].poisonPercentage;
|
||||
iModifier[2] = iModifier[0] + iModifier[1];
|
||||
|
||||
// only draw if item is poisoned in any way
|
||||
if ( iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0 )
|
||||
{
|
||||
if (cnt >= sFirstLine && cnt < sLastLine)
|
||||
{
|
||||
// Set Y coordinates
|
||||
sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
|
||||
sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
|
||||
|
||||
|
||||
// Print Values
|
||||
for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
|
||||
{
|
||||
SetFontForeground( 5 );
|
||||
SetRGBFontForeground( 0, 255, 0 );
|
||||
sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
|
||||
sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
|
||||
if (iFloatModifier[cnt2] > 0)
|
||||
if (iModifier[cnt2] > 0)
|
||||
{
|
||||
if ( cnt2 == 1 )
|
||||
SetFontForeground( ITEMDESC_FONTNEGATIVE );
|
||||
|
||||
swprintf( pStr, L"%4.2f", iFloatModifier[cnt2] );
|
||||
swprintf( pStr, L"%d", iModifier[cnt2] );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
#ifdef CHINESE
|
||||
wcscat( pStr, ChineseSpecString1 );
|
||||
@@ -11133,10 +11234,7 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
}
|
||||
else if (iFloatModifier[cnt2] < 0)
|
||||
{
|
||||
if ( cnt2 == 1 )
|
||||
SetFontForeground( ITEMDESC_FONTPOSITIVE );
|
||||
|
||||
swprintf( pStr, L"%4.2f", iFloatModifier[cnt2] );
|
||||
swprintf( pStr, L"%d", iModifier[cnt2] );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
#ifdef CHINESE
|
||||
wcscat( pStr, ChineseSpecString1 );
|
||||
@@ -11154,176 +11252,6 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
|
||||
///////////////////// COOLDOWN FACTOR MODIFICATOR
|
||||
iFloatModifier[0] = Item[gpItemDescObject->usItem].overheatCooldownModificator;
|
||||
iFloatModifier[1] = 0.0; // doesn't exist (yet?)
|
||||
iFloatModifier[2] = iFloatModifier[0];
|
||||
|
||||
if ( iFloatModifier[0] != 0 )
|
||||
{
|
||||
if (cnt >= sFirstLine && cnt < sLastLine)
|
||||
{
|
||||
// Set Y coordinates
|
||||
sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
|
||||
sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
|
||||
|
||||
// Print Values
|
||||
for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
|
||||
{
|
||||
SetFontForeground( 5 );
|
||||
sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
|
||||
sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
|
||||
if (iFloatModifier[cnt2] > 0)
|
||||
{
|
||||
if ( cnt2 == 1 )
|
||||
SetFontForeground( ITEMDESC_FONTPOSITIVE );
|
||||
|
||||
swprintf( pStr, L"%4.2f", iFloatModifier[cnt2] );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
#ifdef CHINESE
|
||||
wcscat( pStr, ChineseSpecString1 );
|
||||
#else
|
||||
wcscat( pStr, L"%" );
|
||||
#endif
|
||||
}
|
||||
else if (iFloatModifier[cnt2] < 0)
|
||||
{
|
||||
if ( cnt2 == 1 )
|
||||
SetFontForeground( ITEMDESC_FONTNEGATIVE );
|
||||
|
||||
swprintf( pStr, L"%4.2f", iFloatModifier[cnt2] );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
#ifdef CHINESE
|
||||
wcscat( pStr, ChineseSpecString1 );
|
||||
#else
|
||||
wcscat( pStr, L"%" );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pStr, L"--" );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
}
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
|
||||
///////////////////// JAM THRESHOLD FACTOR MODIFICATOR
|
||||
iFloatModifier[0] = Item[gpItemDescObject->usItem].overheatJamThresholdModificator;
|
||||
iFloatModifier[1] = 0.0; // doesn't exist (yet?)
|
||||
iFloatModifier[2] = iFloatModifier[0];
|
||||
|
||||
if ( iFloatModifier[0] != 0 )
|
||||
{
|
||||
if (cnt >= sFirstLine && cnt < sLastLine)
|
||||
{
|
||||
// Set Y coordinates
|
||||
sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
|
||||
sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
|
||||
|
||||
// Print Values
|
||||
for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
|
||||
{
|
||||
SetFontForeground( 5 );
|
||||
sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
|
||||
sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
|
||||
if (iFloatModifier[cnt2] > 0)
|
||||
{
|
||||
if ( cnt2 == 1 )
|
||||
SetFontForeground( ITEMDESC_FONTNEGATIVE );
|
||||
|
||||
swprintf( pStr, L"%4.2f", iFloatModifier[cnt2] );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
#ifdef CHINESE
|
||||
wcscat( pStr, ChineseSpecString1 );
|
||||
#else
|
||||
wcscat( pStr, L"%" );
|
||||
#endif
|
||||
}
|
||||
else if (iFloatModifier[cnt2] < 0)
|
||||
{
|
||||
if ( cnt2 == 1 )
|
||||
SetFontForeground( ITEMDESC_FONTPOSITIVE );
|
||||
|
||||
swprintf( pStr, L"%4.2f", iFloatModifier[cnt2] );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
#ifdef CHINESE
|
||||
wcscat( pStr, ChineseSpecString1 );
|
||||
#else
|
||||
wcscat( pStr, L"%" );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pStr, L"--" );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
}
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
|
||||
///////////////////// DAMAGE THRESHOLD MODIFICATOR
|
||||
iFloatModifier[0] = Item[gpItemDescObject->usItem].overheatDamageThresholdModificator;
|
||||
iFloatModifier[1] = 0.0; // doesn't exist (yet?)
|
||||
iFloatModifier[2] = iFloatModifier[0];
|
||||
|
||||
if ( iFloatModifier[0] != 0 )
|
||||
{
|
||||
if (cnt >= sFirstLine && cnt < sLastLine)
|
||||
{
|
||||
// Set Y coordinates
|
||||
sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
|
||||
sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
|
||||
|
||||
// Print Values
|
||||
for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
|
||||
{
|
||||
SetFontForeground( 5 );
|
||||
sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
|
||||
sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
|
||||
if (iFloatModifier[cnt2] > 0)
|
||||
{
|
||||
if ( cnt2 == 1 )
|
||||
SetFontForeground( ITEMDESC_FONTNEGATIVE );
|
||||
|
||||
swprintf( pStr, L"%4.2f", iFloatModifier[cnt2] );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
#ifdef CHINESE
|
||||
wcscat( pStr, ChineseSpecString1 );
|
||||
#else
|
||||
wcscat( pStr, L"%" );
|
||||
#endif
|
||||
}
|
||||
else if (iFloatModifier[cnt2] < 0)
|
||||
{
|
||||
if ( cnt2 == 1 )
|
||||
SetFontForeground( ITEMDESC_FONTPOSITIVE );
|
||||
|
||||
swprintf( pStr, L"%4.2f", iFloatModifier[cnt2] );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
#ifdef CHINESE
|
||||
wcscat( pStr, ChineseSpecString1 );
|
||||
#else
|
||||
wcscat( pStr, L"%" );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pStr, L"--" );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
}
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2928,8 +2928,17 @@ void RenderSMPanel( BOOLEAN *pfDirty )
|
||||
else
|
||||
{
|
||||
GetMoraleString( gpSMCurrentMerc, pMoraleStr );
|
||||
swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_POPUPTEXT ], gpSMCurrentMerc->stats.bLife, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bBreath, gpSMCurrentMerc->bBreathMax, pMoraleStr );
|
||||
// Flugente: added a display for poison, only show text if actualy poisoned
|
||||
if ( gpSMCurrentMerc->bPoisonSum > 0 )
|
||||
{
|
||||
swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_WITH_POISON_POPUPTEXT ], gpSMCurrentMerc->stats.bLife, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bPoisonSum, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bBreath, gpSMCurrentMerc->bBreathMax, pMoraleStr );
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_POPUPTEXT ], gpSMCurrentMerc->stats.bLife, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bBreath, gpSMCurrentMerc->bBreathMax, pMoraleStr );
|
||||
}
|
||||
SetRegionFastHelpText( &(gSM_SELMERCBarsRegion), pStr );
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -5442,16 +5451,25 @@ void RenderTEAMPanel( BOOLEAN fDirty )
|
||||
}
|
||||
else
|
||||
{
|
||||
GetMoraleString( pSoldier, pMoraleStr );
|
||||
swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_POPUPTEXT ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax, pSoldier->bBreath, pSoldier->bBreathMax, pMoraleStr );
|
||||
SetRegionFastHelpText( &(gTEAM_BarsRegions[ cnt ]), pStr );
|
||||
GetMoraleString( pSoldier, pMoraleStr );
|
||||
|
||||
// Flugente: added a display for poison, only show text if actually poisoned
|
||||
if ( pSoldier->bPoisonSum > 0 )
|
||||
{
|
||||
swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_WITH_POISON_POPUPTEXT ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax, pSoldier->bPoisonSum, pSoldier->stats.bLifeMax, pSoldier->bBreath, pSoldier->bBreathMax, pMoraleStr );
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_POPUPTEXT ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax, pSoldier->bBreath, pSoldier->bBreathMax, pMoraleStr );
|
||||
}
|
||||
SetRegionFastHelpText( &(gTEAM_BarsRegions[ cnt ]), pStr );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRegionFastHelpText( &(gTEAM_BarsRegions[ cnt ]), L"" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRegionFastHelpText( &(gTEAM_BarsRegions[ cnt ]), L"" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !( pSoldier->flags.uiStatusFlags & SOLDIER_DEAD ) )
|
||||
{
|
||||
|
||||
@@ -24,22 +24,30 @@
|
||||
#endif
|
||||
|
||||
#define LIFE_BAR_SHADOW FROMRGB( 108, 12, 12 )
|
||||
#define LIFE_BAR FROMRGB( 200, 0, 0 )
|
||||
#define LIFE_BAR FROMRGB( 200, 0, 0 )
|
||||
#define BANDAGE_BAR_SHADOW FROMRGB( 156, 60, 60 )
|
||||
#define BANDAGE_BAR FROMRGB( 222, 132, 132 )
|
||||
#define BANDAGE_BAR FROMRGB( 222, 132, 132 )
|
||||
#define BLEEDING_BAR_SHADOW FROMRGB( 128, 128, 60 )
|
||||
#define BLEEDING_BAR FROMRGB( 240, 240, 20 )
|
||||
#define CURR_BREATH_BAR_SHADOW FROMRGB( 8, 12, 118 ) // the MAX max breatth, always at 100%
|
||||
#define CURR_BREATH_BAR FROMRGB( 8, 12, 160 )
|
||||
#define CURR_MAX_BREATH FROMRGB( 0, 0, 0 ) // the current max breath, black
|
||||
#define CURR_MAX_BREATH_SHADOW FROMRGB( 0, 0, 0 )
|
||||
#define MORALE_BAR_SHADOW FROMRGB( 8, 112, 12 )
|
||||
#define MORALE_BAR FROMRGB( 8, 180, 12 )
|
||||
#define BREATH_BAR_SHADOW FROMRGB( 60, 108, 108 ) // the lt blue current breath
|
||||
#define BREATH_BAR FROMRGB( 113, 178, 218 )
|
||||
#define BLEEDING_BAR FROMRGB( 240, 240, 20 )
|
||||
|
||||
#define POISON_LIFE_BAR_SHADOW FROMRGB( 12, 108, 12 )
|
||||
#define POISON_LIFE_BAR FROMRGB( 0, 200, 0 )
|
||||
#define POISON_BANDAGE_BAR_SHADOW FROMRGB( 80, 186, 80 )
|
||||
#define POISON_BANDAGE_BAR FROMRGB( 152, 252, 152 )
|
||||
#define POISON_BLEEDING_BAR_SHADOW FROMRGB( 128, 60, 128 )
|
||||
#define POISON_BLEEDING_BAR FROMRGB( 240, 20, 240 )
|
||||
|
||||
#define CURR_BREATH_BAR_SHADOW FROMRGB( 8, 12, 118 ) // the MAX max breatth, always at 100%
|
||||
#define CURR_BREATH_BAR FROMRGB( 8, 12, 160 )
|
||||
#define CURR_MAX_BREATH FROMRGB( 0, 0, 0 ) // the current max breath, black
|
||||
#define CURR_MAX_BREATH_SHADOW FROMRGB( 0, 0, 0 )
|
||||
#define MORALE_BAR_SHADOW FROMRGB( 8, 112, 12 )
|
||||
#define MORALE_BAR FROMRGB( 8, 180, 12 )
|
||||
#define BREATH_BAR_SHADOW FROMRGB( 60, 108, 108 ) // the lt blue current breath
|
||||
#define BREATH_BAR FROMRGB( 113, 178, 218 )
|
||||
#define BREATH_BAR_SHAD_BACK FROMRGB( 1,1,1 )
|
||||
#define FACE_WIDTH 48
|
||||
#define FACE_HEIGHT 43
|
||||
#define FACE_WIDTH 48
|
||||
#define FACE_HEIGHT 43
|
||||
|
||||
|
||||
// backgrounds for breath max background
|
||||
@@ -162,12 +170,15 @@ void DrawLifeUIBarEx( SOLDIERTYPE *pSoldier, INT16 sXPos, INT16 sYPos, INT16 sWi
|
||||
pDestBuf = LockVideoSurface( uiBuffer, &uiDestPitchBYTES );
|
||||
SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT );
|
||||
|
||||
|
||||
dStart = sYPos;
|
||||
dEnd = 0;
|
||||
|
||||
// FIRST DO MAX LIFE
|
||||
dPercentage = (FLOAT)pSoldier->stats.bLife / (FLOAT)100;
|
||||
FLOAT dstart1 = dStart - dEnd;
|
||||
dStart = (FLOAT)( dStart - dEnd );
|
||||
dEnd = dPercentage * sHeight;
|
||||
dStart = sYPos;
|
||||
|
||||
|
||||
usLineColor = Get16BPPColor( LIFE_BAR_SHADOW );
|
||||
RectangleDraw( TRUE, sXPos, (INT32)dStart, sXPos, (INT32)( dStart - dEnd ) , usLineColor, pDestBuf );
|
||||
|
||||
@@ -177,15 +188,33 @@ void DrawLifeUIBarEx( SOLDIERTYPE *pSoldier, INT16 sXPos, INT16 sYPos, INT16 sWi
|
||||
usLineColor = Get16BPPColor( LIFE_BAR_SHADOW );
|
||||
RectangleDraw( TRUE, sXPos+ 2, (INT32)dStart, sXPos + 2, (INT32)( dStart - dEnd ), usLineColor, pDestBuf );
|
||||
|
||||
// NOW DO BANDAGE
|
||||
// poisoned life first
|
||||
if ( pSoldier->bPoisonLife )
|
||||
{
|
||||
dPercentage = (FLOAT)pSoldier->bPoisonLife / (FLOAT)100;
|
||||
FLOAT dpoisonStart = (FLOAT)( dstart1 );
|
||||
FLOAT dpoisonEnd = dPercentage * sHeight;
|
||||
|
||||
usLineColor = Get16BPPColor( POISON_LIFE_BAR_SHADOW );
|
||||
RectangleDraw( TRUE, sXPos, (INT32)dpoisonStart, sXPos, (INT32)( dpoisonStart - dpoisonEnd ) , usLineColor, pDestBuf );
|
||||
|
||||
usLineColor = Get16BPPColor( POISON_LIFE_BAR );
|
||||
RectangleDraw( TRUE, sXPos+ 1, (INT32)dpoisonStart, sXPos + 1, (INT32)( dpoisonStart - dpoisonEnd ), usLineColor, pDestBuf );
|
||||
|
||||
usLineColor = Get16BPPColor( POISON_LIFE_BAR_SHADOW );
|
||||
RectangleDraw( TRUE, sXPos+ 2, (INT32)dpoisonStart, sXPos + 2, (INT32)( dpoisonStart - dpoisonEnd ), usLineColor, pDestBuf );
|
||||
}
|
||||
|
||||
// NOW DO BANDAGE
|
||||
|
||||
// Calculate bandage
|
||||
FLOAT dstart2 = dStart - dEnd;
|
||||
bBandage = pSoldier->stats.bLifeMax - pSoldier->stats.bLife - pSoldier->bBleeding;
|
||||
|
||||
if ( bBandage )
|
||||
{
|
||||
dPercentage = (FLOAT)bBandage / (FLOAT)100;
|
||||
dStart = (FLOAT)( sYPos - dEnd );
|
||||
dStart = (FLOAT)( dStart - dEnd );
|
||||
dEnd = ( dPercentage * sHeight );
|
||||
|
||||
usLineColor = Get16BPPColor( BANDAGE_BAR_SHADOW );
|
||||
@@ -198,7 +227,26 @@ void DrawLifeUIBarEx( SOLDIERTYPE *pSoldier, INT16 sXPos, INT16 sYPos, INT16 sWi
|
||||
RectangleDraw( TRUE, sXPos+ 2, (INT32)dStart, sXPos + 2, (INT32)( dStart - dEnd ), usLineColor, pDestBuf );
|
||||
}
|
||||
|
||||
// get amount of poisoned bandage
|
||||
INT8 bPoisonBandage = pSoldier->bPoisonSum - pSoldier->bPoisonBleeding - pSoldier->bPoisonLife;
|
||||
if ( bPoisonBandage )
|
||||
{
|
||||
dPercentage = (FLOAT)bPoisonBandage / (FLOAT)100;
|
||||
FLOAT dpoisonStart = (FLOAT)( dstart2 );
|
||||
FLOAT dpoisonEnd = dPercentage * sHeight;
|
||||
|
||||
usLineColor = Get16BPPColor( POISON_BANDAGE_BAR_SHADOW );
|
||||
RectangleDraw( TRUE, sXPos, (INT32)dpoisonStart, sXPos, (INT32)( dpoisonStart - dpoisonEnd ) , usLineColor, pDestBuf );
|
||||
|
||||
usLineColor = Get16BPPColor( POISON_BANDAGE_BAR );
|
||||
RectangleDraw( TRUE, sXPos+ 1, (INT32)dpoisonStart, sXPos + 1, (INT32)( dpoisonStart - dpoisonEnd ), usLineColor, pDestBuf );
|
||||
|
||||
usLineColor = Get16BPPColor( POISON_BANDAGE_BAR_SHADOW );
|
||||
RectangleDraw( TRUE, sXPos+ 2, (INT32)dpoisonStart, sXPos + 2, (INT32)( dpoisonStart - dpoisonEnd ), usLineColor, pDestBuf );
|
||||
}
|
||||
|
||||
// NOW DO BLEEDING
|
||||
FLOAT dstart3 = dStart - dEnd;
|
||||
if ( pSoldier->bBleeding )
|
||||
{
|
||||
dPercentage = (FLOAT)pSoldier->bBleeding / (FLOAT)100;
|
||||
@@ -215,6 +263,23 @@ void DrawLifeUIBarEx( SOLDIERTYPE *pSoldier, INT16 sXPos, INT16 sYPos, INT16 sWi
|
||||
RectangleDraw( TRUE, sXPos+ 2, (INT32)dStart, sXPos + 2, (INT32)( dStart - dEnd ), usLineColor, pDestBuf );
|
||||
}
|
||||
|
||||
// poisoned bleeding
|
||||
if ( pSoldier->bPoisonBleeding )
|
||||
{
|
||||
dPercentage = (FLOAT)pSoldier->bPoisonBleeding / (FLOAT)100;
|
||||
FLOAT dpoisonStart = (FLOAT)( dstart3 );
|
||||
FLOAT dpoisonEnd = dPercentage * sHeight;
|
||||
|
||||
usLineColor = Get16BPPColor( POISON_BLEEDING_BAR_SHADOW );
|
||||
RectangleDraw( TRUE, sXPos, (INT32)dpoisonStart, sXPos, (INT32)( dpoisonStart - dpoisonEnd ) , usLineColor, pDestBuf );
|
||||
|
||||
usLineColor = Get16BPPColor( POISON_BLEEDING_BAR );
|
||||
RectangleDraw( TRUE, sXPos+ 1, (INT32)dpoisonStart, sXPos + 1, (INT32)( dpoisonStart - dpoisonEnd ), usLineColor, pDestBuf );
|
||||
|
||||
usLineColor = Get16BPPColor( POISON_BLEEDING_BAR_SHADOW );
|
||||
RectangleDraw( TRUE, sXPos+ 2, (INT32)dpoisonStart, sXPos + 2, (INT32)( dpoisonStart - dpoisonEnd ), usLineColor, pDestBuf );
|
||||
}
|
||||
|
||||
UnLockVideoSurface( uiBuffer );
|
||||
|
||||
}
|
||||
|
||||
@@ -2210,6 +2210,21 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( pSoldier->IsZombie() )
|
||||
{
|
||||
swprintf(NameStr, pSoldier->name);
|
||||
|
||||
// Display name
|
||||
SetFont( TINYFONT1 );
|
||||
SetFontBackground( FONT_MCOLOR_BLACK );
|
||||
SetFontForeground( FONT_MCOLOR_WHITE );
|
||||
|
||||
//legion2
|
||||
FindFontCenterCoordinates( sXPos, (INT16)( sYPos -10 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
|
||||
gprintfdirty( sX, sY, NameStr );
|
||||
mprintf( sX, sY, NameStr );
|
||||
}
|
||||
//------------
|
||||
}
|
||||
}
|
||||
@@ -3162,6 +3177,7 @@ void DrawBarsInUIBox( SOLDIERTYPE *pSoldier , INT16 sXPos, INT16 sYPos, INT16 sW
|
||||
UINT8 *pDestBuf;
|
||||
UINT16 usLineColor;
|
||||
INT8 bBandage;
|
||||
INT8 bPoisonBandage;
|
||||
|
||||
// Draw breath points
|
||||
|
||||
@@ -3174,6 +3190,8 @@ void DrawBarsInUIBox( SOLDIERTYPE *pSoldier , INT16 sXPos, INT16 sYPos, INT16 sW
|
||||
// get amt bandaged
|
||||
bBandage = pSoldier->stats.bLifeMax - pSoldier->stats.bLife - pSoldier->bBleeding;
|
||||
|
||||
// get amount of poisoned bandage
|
||||
bPoisonBandage = pSoldier->bPoisonSum - pSoldier->bPoisonBleeding - pSoldier->bPoisonLife;
|
||||
|
||||
|
||||
// NOW DO BLEEDING
|
||||
@@ -3194,6 +3212,23 @@ void DrawBarsInUIBox( SOLDIERTYPE *pSoldier , INT16 sXPos, INT16 sYPos, INT16 sW
|
||||
}
|
||||
}
|
||||
|
||||
// poisoned bleeding
|
||||
if ( pSoldier->bPoisonBleeding )
|
||||
{
|
||||
dPercentage = (FLOAT)( pSoldier->stats.bLifeMax - pSoldier->bBleeding + pSoldier->bPoisonBleeding )/ (FLOAT)100;
|
||||
dWidth = dPercentage * sWidth;
|
||||
if(gbPixelDepth==16)
|
||||
{
|
||||
usLineColor = Get16BPPColor( FROMRGB( 240, 20, 240 ) );
|
||||
RectangleDraw( TRUE, sXPos + 3, sYPos + 1, (INT32)( sXPos + dWidth + 3 ), sYPos + 1, usLineColor, pDestBuf );
|
||||
}
|
||||
else if(gbPixelDepth==8)
|
||||
{
|
||||
// DB Need to change this to a color from the 8-bit standard palette
|
||||
usLineColor = COLOR_GREEN;
|
||||
RectangleDraw8( TRUE, sXPos + 3, sYPos + 1, (INT32)( sXPos + dWidth + 3 ), sYPos + 1, usLineColor, pDestBuf );
|
||||
}
|
||||
}
|
||||
|
||||
if( bBandage )
|
||||
{
|
||||
@@ -3212,6 +3247,23 @@ void DrawBarsInUIBox( SOLDIERTYPE *pSoldier , INT16 sXPos, INT16 sYPos, INT16 sW
|
||||
}
|
||||
}
|
||||
|
||||
// poisoned bandage
|
||||
if ( bPoisonBandage )
|
||||
{
|
||||
dPercentage = (FLOAT)( pSoldier->stats.bLife + bPoisonBandage )/ (FLOAT)100;
|
||||
dWidth = dPercentage * sWidth;
|
||||
if(gbPixelDepth==16)
|
||||
{
|
||||
usLineColor = Get16BPPColor( FROMRGB( 132, 222, 132 ) );
|
||||
RectangleDraw( TRUE, sXPos + 3, sYPos + 1, (INT32)( sXPos + dWidth + 3 ), sYPos + 1, usLineColor, pDestBuf );
|
||||
}
|
||||
else if(gbPixelDepth==8)
|
||||
{
|
||||
// DB Need to change this to a color from the 8-bit standard palette
|
||||
usLineColor = COLOR_GREEN;
|
||||
RectangleDraw8( TRUE, sXPos + 3, sYPos + 1, (INT32)( sXPos + dWidth + 3 ), sYPos + 1, usLineColor, pDestBuf );
|
||||
}
|
||||
}
|
||||
|
||||
dPercentage = (FLOAT)pSoldier->stats.bLife / (FLOAT)100;
|
||||
dWidth = dPercentage * sWidth;
|
||||
@@ -3227,6 +3279,23 @@ void DrawBarsInUIBox( SOLDIERTYPE *pSoldier , INT16 sXPos, INT16 sYPos, INT16 sW
|
||||
RectangleDraw8( TRUE, sXPos + 3, sYPos + 1, (INT32)( sXPos + dWidth + 3 ), sYPos + 1, usLineColor, pDestBuf );
|
||||
}
|
||||
|
||||
// poisoned life
|
||||
if ( pSoldier->bPoisonLife )
|
||||
{
|
||||
dPercentage = (FLOAT)( pSoldier->bPoisonLife )/ (FLOAT)100;
|
||||
dWidth = dPercentage * sWidth;
|
||||
if(gbPixelDepth==16)
|
||||
{
|
||||
usLineColor = Get16BPPColor( FROMRGB( 0, 200, 0 ) );
|
||||
RectangleDraw( TRUE, sXPos + 3, sYPos + 1, (INT32)( sXPos + dWidth + 3 ), sYPos + 1, usLineColor, pDestBuf );
|
||||
}
|
||||
else if(gbPixelDepth==8)
|
||||
{
|
||||
// DB Need to change this to a color from the 8-bit standard palette
|
||||
usLineColor = COLOR_GREEN;
|
||||
RectangleDraw8( TRUE, sXPos + 3, sYPos + 1, (INT32)( sXPos + dWidth + 3 ), sYPos + 1, usLineColor, pDestBuf );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dPercentage = (FLOAT)( pSoldier->bBreathMax ) / (FLOAT)100;
|
||||
|
||||
@@ -846,6 +846,10 @@ void GenerateRandomEquipment( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass, INT8
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
// zombies get no items at all...
|
||||
break;
|
||||
}
|
||||
|
||||
for ( i = 0; i < pp->Inv.size(); i++ )
|
||||
@@ -1052,6 +1056,8 @@ void ChooseWeaponForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bWeaponC
|
||||
bStatus += (INT8)(HighestPlayerProgressPercentage() / 10);
|
||||
bStatus = (INT8)min( 100, bStatus );
|
||||
break;
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
bStatus = (INT8)(1); // if a zombie gets anything, it'll be broken
|
||||
default:
|
||||
bStatus = (INT8)(50 + Random( 51 ) );
|
||||
break;
|
||||
@@ -2105,6 +2111,7 @@ void ChooseFaceGearForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp )
|
||||
break;
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_GREEN_MILITIA:
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,6 +219,9 @@ typedef enum
|
||||
#define GS_CARTRIDGE_IN_CHAMBER 0x01
|
||||
#define GS_WEAPON_BEING_RELOADED 0x02
|
||||
|
||||
// Flugente: define for maximum temperature
|
||||
#define OVERHEATING_MAX_TEMPERATURE 60000.0
|
||||
|
||||
//forward declaration
|
||||
class OBJECTTYPE;
|
||||
class SOLDIERTYPE;
|
||||
@@ -956,6 +959,9 @@ typedef struct
|
||||
|
||||
BOOLEAN blockironsight; // if a gun or any attachment have this property, the iron sight won't be usable (if there is at least one other usable sight)
|
||||
|
||||
// Flugente poison system
|
||||
INT16 bPoisonPercentage;
|
||||
|
||||
} INVTYPE;
|
||||
|
||||
// CHRISL: Added new structures to handle LBE gear and the two new XML files that will be needed to deal
|
||||
|
||||
+51
-8
@@ -3042,7 +3042,7 @@ UINT32 CalculateCarriedWeight( SOLDIERTYPE * pSoldier )
|
||||
UINT32 uiTotalWeight = 0;
|
||||
UINT32 uiPercent;
|
||||
UINT8 ubLoop;
|
||||
UINT8 ubStrengthForCarrying;
|
||||
UINT16 ubStrengthForCarrying;
|
||||
|
||||
//Pulmu: Changes for dynamic ammo weight
|
||||
for( ubLoop = 0; ubLoop < pSoldier->inv.size(); ubLoop++)
|
||||
@@ -7418,7 +7418,7 @@ BOOLEAN CreateGun( UINT16 usItem, INT16 bStatus, OBJECTTYPE * pObj )
|
||||
pStackedObject->data.ubImprintID = NO_PROFILE;
|
||||
|
||||
// Flugente FTW 1: temperature on creation is 0
|
||||
pStackedObject->data.bTemperature = 0.0;
|
||||
pStackedObject->data.bTemperature = 0.0f;
|
||||
|
||||
if (Weapon[ usItem ].ubWeaponClass == MONSTERCLASS)
|
||||
{
|
||||
@@ -7533,6 +7533,7 @@ BOOLEAN CreateItem( UINT16 usItem, INT16 bStatus, OBJECTTYPE * pObj )
|
||||
{
|
||||
(*pObj)[0]->data.objectStatus = bStatus;
|
||||
}
|
||||
|
||||
//ADB ubWeight has been removed, see comments in OBJECTTYPE
|
||||
//pObj->ubWeight = CalculateObjectWeight( pObj );
|
||||
fRet = TRUE;
|
||||
@@ -9189,6 +9190,41 @@ void ActivateXRayDevice( SOLDIERTYPE * pSoldier )
|
||||
pSoldier->uiXRayActivatedTime = GetWorldTotalSeconds();
|
||||
}
|
||||
|
||||
void TurnOnXRayEffects( SOLDIERTYPE * pSoldier )
|
||||
{
|
||||
SOLDIERTYPE * pSoldier2;
|
||||
UINT32 uiSlot;
|
||||
|
||||
// first, scan through all mercs and turn off xrayed flag for anyone
|
||||
// previously xrayed by this guy
|
||||
for ( uiSlot = 0; uiSlot < guiNumMercSlots; ++uiSlot )
|
||||
{
|
||||
pSoldier2 = MercSlots[ uiSlot ];
|
||||
if ( pSoldier2 )
|
||||
{
|
||||
if ( (pSoldier2->ubMiscSoldierFlags & SOLDIER_MISC_XRAYED) && (pSoldier2->aiData.ubXRayedBy == pSoldier->ubID) )
|
||||
{
|
||||
pSoldier2->ubMiscSoldierFlags &= (~SOLDIER_MISC_XRAYED);
|
||||
pSoldier2->aiData.ubXRayedBy = NOBODY;
|
||||
}
|
||||
}
|
||||
}
|
||||
// now turn on xray for anyone within range
|
||||
for ( uiSlot = 0; uiSlot < guiNumMercSlots; ++uiSlot )
|
||||
{
|
||||
pSoldier2 = MercSlots[ uiSlot ];
|
||||
if ( pSoldier2 )
|
||||
{
|
||||
if ( pSoldier2->bTeam != pSoldier->bTeam && PythSpacesAway( pSoldier->sGridNo, pSoldier2->sGridNo ) < XRAY_RANGE )
|
||||
{
|
||||
pSoldier2->ubMiscSoldierFlags |= SOLDIER_MISC_XRAYED;
|
||||
pSoldier2->aiData.ubXRayedBy = pSoldier->ubID;
|
||||
}
|
||||
}
|
||||
}
|
||||
pSoldier->uiXRayActivatedTime = GetWorldTotalSeconds();
|
||||
}
|
||||
|
||||
void TurnOffXRayEffects( SOLDIERTYPE * pSoldier )
|
||||
{
|
||||
SOLDIERTYPE * pSoldier2;
|
||||
@@ -9453,13 +9489,17 @@ INT16 GetGearAPBonus( SOLDIERTYPE * pSoldier )
|
||||
{
|
||||
INT16 bonus=0;
|
||||
|
||||
for (int j = HELMETPOS; j <= HEAD2POS; j++)
|
||||
for (int j = HELMETPOS; j <= HEAD2POS; ++j)
|
||||
{
|
||||
if (pSoldier->inv[j].exists() == true) {
|
||||
bonus += Item[pSoldier->inv[j].usItem].APBonus;
|
||||
if (pSoldier->inv[j].exists() == true)
|
||||
{
|
||||
OBJECTTYPE* pObj = &pSoldier->inv[j];
|
||||
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
|
||||
if(iter->exists()){
|
||||
|
||||
attachmentList::iterator iterend = (*pObj)[0]->attachments.begin();
|
||||
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter)
|
||||
{
|
||||
if(iter->exists())
|
||||
{
|
||||
bonus += Item[iter->usItem].APBonus;
|
||||
}
|
||||
}
|
||||
@@ -11020,7 +11060,9 @@ BOOLEAN HasThermalOptics( SOLDIERTYPE * pSoldier )
|
||||
if (!IsWeapon(pSoldier->inv[i].usItem) || (IsWeapon(pSoldier->inv[i].usItem) && usingGunScope == true) )
|
||||
{
|
||||
if (Item[pSoldier->inv[i].usItem].thermaloptics)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13414,6 +13456,8 @@ BOOLEAN HasAttachmentOfClass( OBJECTTYPE * pObj, UINT32 aFlag )
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
|
||||
extern void HandleSight(SOLDIERTYPE *pSoldier, UINT8 ubSightFlags);
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HEADROCK HAM 5: Item Transformation.
|
||||
// Item Transformation is a new way to interact with items. Where Merges combine two items into one, a Transformation
|
||||
@@ -13816,4 +13860,3 @@ UINT64 GetAvailableAttachmentPoint (OBJECTTYPE * pObject, UINT8 subObject)
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -225,6 +225,7 @@ void CheckEquipmentForFragileItemDamage( SOLDIERTYPE *pSoldier, INT32 iDamage );
|
||||
#define XRAY_TIME 5
|
||||
|
||||
extern void ActivateXRayDevice( SOLDIERTYPE * pSoldier );
|
||||
extern void TurnOnXRayEffects( SOLDIERTYPE * pSoldier );
|
||||
extern void TurnOffXRayEffects( SOLDIERTYPE * pSoldier );
|
||||
OBJECTTYPE* FindLaunchableAttachment( OBJECTTYPE * pObj, UINT16 usWeapon );
|
||||
UINT16 FindLegalGrenade(UINT16 usItem);
|
||||
@@ -448,7 +449,7 @@ BOOLEAN UseTotalMedicalKitPoints( SOLDIERTYPE * pSoldier, UINT16 usPointsToConsu
|
||||
FLOAT GetItemCooldownFactor( OBJECTTYPE * pObj );
|
||||
void GetScopeLists( OBJECTTYPE * pObj, std::map<INT8, OBJECTTYPE*>& arScopeMap );
|
||||
|
||||
// check if item belongs to a specific attachemnt class
|
||||
// check if item belongs to a specific attachment class
|
||||
BOOLEAN IsAttachmentClass( UINT16 usItem, UINT32 aFlag );
|
||||
BOOLEAN HasAttachmentOfClass( OBJECTTYPE * pObj, UINT32 aFlag );
|
||||
|
||||
@@ -459,6 +460,3 @@ bool IsAttachmentPointAvailable( UINT64 point, UINT32 attachmentID, BOOLEAN only
|
||||
UINT64 GetAvailableAttachmentPoint ( OBJECTTYPE * pObject, UINT8 subObject );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -702,7 +702,7 @@ void HandleDoorTrap( SOLDIERTYPE * pSoldier, DOOR * pDoor )
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Trap gone off %d", gTacticalStatus.ubAttackBusyCount) );
|
||||
DebugAttackBusy( "!!!!!!! Trap gone off\n" );
|
||||
|
||||
pSoldier->SoldierTakeDamage( 0, (UINT16) (10 + PreRandom( 10 )), (UINT16) ((3 + PreRandom( 3 ) * 1000)), TAKE_DAMAGE_ELECTRICITY, NOBODY, pDoor->sGridNo, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( 0, (UINT16) (10 + PreRandom( 10 )), 0, (UINT16) ((3 + PreRandom( 3 ) * 1000)), TAKE_DAMAGE_ELECTRICITY, NOBODY, pDoor->sGridNo, 0, TRUE );
|
||||
break;
|
||||
|
||||
case SUPER_ELECTRIC:
|
||||
@@ -717,7 +717,7 @@ void HandleDoorTrap( SOLDIERTYPE * pSoldier, DOOR * pDoor )
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Trap gone off %d", gTacticalStatus.ubAttackBusyCount) );
|
||||
DebugAttackBusy( "!!!!!!! Trap gone off\n" );
|
||||
|
||||
pSoldier->SoldierTakeDamage( 0, (UINT16) (20 + PreRandom( 20 )), (UINT16) ((6 + PreRandom( 6 ) * 1000)), TAKE_DAMAGE_ELECTRICITY, NOBODY, pDoor->sGridNo, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( 0, (UINT16) (20 + PreRandom( 20 )), 0, (UINT16) ((6 + PreRandom( 6 ) * 1000)), TAKE_DAMAGE_ELECTRICITY, NOBODY, pDoor->sGridNo, 0, TRUE );
|
||||
break;
|
||||
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "WorldDat.h"
|
||||
// HEADROCK HAM 3.6: This must be included, for testing whether Bloodcats and Enemies can see one another.
|
||||
#include "Campaign Types.h"
|
||||
#include "soldier tile.h" // added by Flugente
|
||||
|
||||
//forward declarations of common classes to eliminate includes
|
||||
class OBJECTTYPE;
|
||||
|
||||
@@ -109,20 +109,6 @@ extern SOLDIERTYPE *pTMilitiaSoldier;
|
||||
extern BOOLEAN SoldierCanAffordNewStance( SOLDIERTYPE *pSoldier, UINT8 ubDesiredStance );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ResetMilitia()
|
||||
{
|
||||
UINT8 ubNumGreen = 0;
|
||||
@@ -2370,5 +2356,3 @@ void MilitiaControlMenuBtnCallBack( MOUSE_REGION * pRegion, INT32 iReason )
|
||||
// return;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
+9
-1
@@ -88,6 +88,8 @@ MoraleEvent gbMoraleEvent[NUM_MORALE_EVENTS] =
|
||||
{ TACTICAL_MORALE_EVENT, -1}, // MORALE_PSYCHO_UNABLE_TO_PSYCHO,
|
||||
{ STRATEGIC_MORALE_EVENT, +1}, // MORALE_PACIFIST_GAIN_NONCOMBAT,
|
||||
{ TACTICAL_MORALE_EVENT, +1}, // MORALE_MALICIOUS_HIT,
|
||||
// added by SANDRO
|
||||
{ TACTICAL_MORALE_EVENT, -1}, //MORALE_KHORNATE_RANGED_COMBAT,
|
||||
};
|
||||
|
||||
BOOLEAN gfSomeoneSaidMoraleQuote = FALSE;
|
||||
@@ -523,7 +525,7 @@ void UpdateSoldierMorale( SOLDIERTYPE * pSoldier, INT8 bMoraleEvent )
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( bMoraleMod != MORALE_PSYCHO_UNABLE_TO_PSYCHO)
|
||||
else if ( bMoraleMod != MORALE_PSYCHO_UNABLE_TO_PSYCHO && bMoraleMod != MORALE_KHORNATE_RANGED_COMBAT)
|
||||
{
|
||||
switch( pProfile->bAttitude )
|
||||
{
|
||||
@@ -909,6 +911,12 @@ void HandleMoraleEvent( SOLDIERTYPE *pSoldier, INT8 bMoraleEvent, INT16 sMapX, I
|
||||
HandleMoraleEventForSoldier( pSoldier, bMoraleEvent );
|
||||
break;
|
||||
|
||||
// added by Flugente
|
||||
case MORALE_KHORNATE_RANGED_COMBAT:
|
||||
Assert( pSoldier );
|
||||
HandleMoraleEventForSoldier( pSoldier, bMoraleEvent );
|
||||
break;
|
||||
|
||||
default:
|
||||
// debug message
|
||||
ScreenMsg( MSG_FONT_RED, MSG_BETAVERSION, L"Invalid morale event type = %d. AM/CC-1", bMoraleEvent );
|
||||
|
||||
@@ -49,6 +49,9 @@ typedef enum
|
||||
MORALE_PSYCHO_UNABLE_TO_PSYCHO,
|
||||
MORALE_PACIFIST_GAIN_NONCOMBAT,
|
||||
MORALE_MALICIOUS_HIT,
|
||||
|
||||
// added by Flugente
|
||||
MORALE_KHORNATE_RANGED_COMBAT,
|
||||
NUM_MORALE_EVENTS
|
||||
} MoraleEventNames;
|
||||
|
||||
|
||||
+30
-4
@@ -6975,10 +6975,12 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
|
||||
if (pTeamSoldier->iHealableInjury < 0)
|
||||
pTeamSoldier->iHealableInjury = 0;
|
||||
|
||||
pTeamSoldier->bPoisonLife = min(pTeamSoldier->bPoisonSum, pTeamSoldier->bPoisonLife + OKLIFE - pTeamSoldier->stats.bLife);
|
||||
pTeamSoldier->stats.bLife = OKLIFE;
|
||||
}
|
||||
|
||||
pTeamSoldier->bBleeding = 0; // let's think, the autobandage was done for the militia too
|
||||
pTeamSoldier->bPoisonBleeding = 0;
|
||||
}
|
||||
}
|
||||
gTacticalStatus.Team[ MILITIA_TEAM ].bAwareOfOpposition = FALSE;
|
||||
@@ -7255,6 +7257,26 @@ UINT8 NumEnemyInSector( )
|
||||
|
||||
}
|
||||
|
||||
UINT8 NumZombiesInSector( )
|
||||
{
|
||||
SOLDIERTYPE *pTeamSoldier;
|
||||
INT32 cnt = 0;
|
||||
UINT8 ubNumZombies = 0;
|
||||
|
||||
for ( pTeamSoldier = Menptr, cnt = 0; cnt < TOTAL_SOLDIERS; ++pTeamSoldier, ++cnt )
|
||||
{
|
||||
if ( pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->stats.bLife > 0 )
|
||||
{
|
||||
if ( pTeamSoldier->IsZombie() )
|
||||
{
|
||||
++ubNumZombies;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return( ubNumZombies );
|
||||
}
|
||||
|
||||
UINT8 NumEnemyInSectorExceptCreatures()
|
||||
{
|
||||
SOLDIERTYPE *pTeamSoldier;
|
||||
@@ -7582,13 +7604,13 @@ BOOLEAN KillIncompacitatedEnemyInSector( )
|
||||
// KIll......
|
||||
// SANDRO - if the soldier is bleeding out, consider this damage as done by the last attacker
|
||||
if ( pTeamSoldier->ubAttackerID != NOBODY )
|
||||
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 100, TAKE_DAMAGE_BLOODLOSS, pTeamSoldier->ubAttackerID, NOWHERE, 0, TRUE );
|
||||
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 0, 100, TAKE_DAMAGE_BLOODLOSS, pTeamSoldier->ubAttackerID, NOWHERE, 0, TRUE );
|
||||
else if ( pTeamSoldier->ubPreviousAttackerID != NOBODY )
|
||||
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 100, TAKE_DAMAGE_BLOODLOSS, pTeamSoldier->ubPreviousAttackerID, NOWHERE, 0, TRUE );
|
||||
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 0, 100, TAKE_DAMAGE_BLOODLOSS, pTeamSoldier->ubPreviousAttackerID, NOWHERE, 0, TRUE );
|
||||
else if ( pTeamSoldier->ubNextToPreviousAttackerID != NOBODY )
|
||||
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 100, TAKE_DAMAGE_BLOODLOSS, pTeamSoldier->ubNextToPreviousAttackerID, NOWHERE, 0, TRUE );
|
||||
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 0, 100, TAKE_DAMAGE_BLOODLOSS, pTeamSoldier->ubNextToPreviousAttackerID, NOWHERE, 0, TRUE );
|
||||
else
|
||||
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 100, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
|
||||
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 0, 100, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
|
||||
|
||||
fReturnVal = TRUE;
|
||||
}
|
||||
@@ -7767,6 +7789,10 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("HandleSuppressionFire: loop = %d, numslots = %d ",uiLoop, guiNumMercSlots));
|
||||
pSoldier = MercSlots[uiLoop];
|
||||
|
||||
// Flugente: zombies do not receive any suppression at all!
|
||||
if ( pSoldier != NULL && pSoldier->IsZombie() )
|
||||
continue;
|
||||
|
||||
// Has this character received any Suppression Points since the last attack?
|
||||
// HEADROCK: Suppression Points accumulate by bullets flying near the character. It includes
|
||||
// friendly fire at a certain distance. As of HAM 3.2, it also happens with nearby explosions.
|
||||
|
||||
@@ -393,4 +393,7 @@ BOOLEAN WillAirRaidBeStopped( INT16 sSectorX, INT16 sSectorY );
|
||||
|
||||
// HEADROCK HAM 3.5: Externalized for First Arrival enemy check
|
||||
extern UINT8 NumEnemyInSector();
|
||||
|
||||
// Flugente
|
||||
extern UINT8 NumZombiesInSector();
|
||||
#endif
|
||||
@@ -43,6 +43,9 @@
|
||||
#include "strategic.h"
|
||||
#include "qarray.h"
|
||||
#include "Interface.h"
|
||||
|
||||
#include "Campaign Types.h"
|
||||
//#include "Queen Command.h"
|
||||
#endif
|
||||
|
||||
#include "Animation Control.h"
|
||||
@@ -580,6 +583,10 @@ INT32 AddRottingCorpse( ROTTING_CORPSE_DEFINITION *pCorpseDef )
|
||||
pCorpse->pAniTile->uiUserData = iIndex;
|
||||
pCorpse->iID = iIndex;
|
||||
|
||||
// copy name of corpse definition...
|
||||
memcpy( &(pCorpse->name), &(pCorpseDef->name), sizeof(CHAR16) * 10 );
|
||||
pCorpse->name[9] = '\0';
|
||||
|
||||
pCorpse->fActivated = TRUE;
|
||||
|
||||
if ( Random( 100 ) > 50 )
|
||||
@@ -853,6 +860,36 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
|
||||
Corpse.usFlags |= ROTTING_CORPSE_USE_SNOW_CAMO_PALETTE;
|
||||
}
|
||||
|
||||
// Flugente Zombies: Determine if a zombie can rise from this corpse
|
||||
switch ( gGameExternalOptions.sZombieRiseBehaviour )
|
||||
{
|
||||
case 3:
|
||||
// a zombie might rise again
|
||||
if ( pSoldier->IsZombie() && Random( 2 ) > 0 )
|
||||
Corpse.usFlags |= ROTTING_CORPSE_NEVER_RISE_AGAIN;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// death tosses a coin...
|
||||
if ( Random( 2 ) > 0 )
|
||||
Corpse.usFlags |= ROTTING_CORPSE_NEVER_RISE_AGAIN;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// no flag, the dead shall rise for eternity!
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
// a killed zombie won't rise again
|
||||
if ( pSoldier->IsZombie() )
|
||||
Corpse.usFlags |= ROTTING_CORPSE_NEVER_RISE_AGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
// Flugente: copy name of soldier...
|
||||
memcpy( &(Corpse.name), &(pSoldier->name), sizeof(CHAR16) * 10 );
|
||||
Corpse.name[9] = '\0';
|
||||
|
||||
// Determine corpse type!
|
||||
ubType = (UINT8)gubAnimSurfaceCorpseID[ pSoldier->ubBodyType][ pSoldier->usAnimState ];
|
||||
@@ -2046,3 +2083,364 @@ UINT8 GetNearestRottingCorpseAIWarning( INT32 sGridNo )
|
||||
|
||||
return( ubHighestWarning );
|
||||
}
|
||||
|
||||
// Flugente Zombies: resurrect zombies
|
||||
void RaiseZombies( void )
|
||||
{
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
{
|
||||
// if gGameExternalOptions.fZombieSpawnWaves is true, zombies will spawn from all corpses (while there is still room for more), creating a wave of zombies. with lots of bodies lying around, this can be a lot.
|
||||
// if GameExternalOptions.fZombieSpawnWaves is false, each zombie can spawn randomly, you will get zombies on msot turns, but they won't spawn a whole horde at once
|
||||
if ( ( gGameExternalOptions.fZombieSpawnWaves && (INT8) ( Random( 100 ) ) > 100 - gGameExternalOptions.sZombieRiseWaveFrequency ) || !gGameExternalOptions.fZombieSpawnWaves )
|
||||
{
|
||||
ROTTING_CORPSE * pCorpse;
|
||||
BOOLEAN zombieshaverisen = FALSE;
|
||||
|
||||
SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
|
||||
|
||||
for ( INT32 cnt = giNumRottingCorpse - 1; cnt >= 0; --cnt )
|
||||
{
|
||||
if ( pSector->ubNumCreatures < gGameExternalOptions.ubGameMaximumNumberOfCreatures ) // ... if there is still room for more zombies (zombies count as creatures until a separate ZOMBIE_TEAM is implemented)...
|
||||
{
|
||||
pCorpse = &(gRottingCorpse[ cnt ] );
|
||||
|
||||
// if zombies should spawn individually, roll for every corpse individually
|
||||
if ( gGameExternalOptions.fZombieSpawnWaves || ( !gGameExternalOptions.fZombieSpawnWaves && (INT8) ( Random( 100 ) ) > 100 - gGameExternalOptions.sZombieRiseWaveFrequency ) )
|
||||
{
|
||||
if ( pCorpse->fActivated && pCorpse->def.fHeadTaken == FALSE ) // ... if corpse is active, and still has a head ...
|
||||
{
|
||||
if ( !(pCorpse->def.usFlags & ROTTING_CORPSE_NEVER_RISE_AGAIN) ) // ... if corpse is already that of a zombie, don't create zombie again ...
|
||||
{
|
||||
if ( !TileIsOutOfBounds(pCorpse->def.sGridNo) ) // ... if corpse is on existing coordinates ...
|
||||
{
|
||||
if ( WhoIsThere2( pCorpse->def.sGridNo, pCorpse->def.bLevel ) == NOBODY ) // ... if nobody else is on that position ...
|
||||
{
|
||||
UINT16 recanimstate = STANDING;
|
||||
|
||||
if ( CorpseOkToSpawnZombie( pCorpse, &recanimstate ) ) // ... a zombie can be created from this corpse, in the corresponding animstate ...
|
||||
{
|
||||
zombieshaverisen = TRUE;
|
||||
CreateZombiefromCorpse( pCorpse, recanimstate );
|
||||
|
||||
//++pSector->ubNumZombies;
|
||||
//++pSector->ubZombiesInBattle;
|
||||
|
||||
RemoveCorpse( cnt );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there is no more room, we can skip this
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( zombieshaverisen )
|
||||
{
|
||||
#ifdef JA2TESTVERSION
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"A wave of zombies is created");
|
||||
#endif
|
||||
// Play sound
|
||||
PlayJA2SampleFromFile( "Sounds\\zombie1.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente Zombies 1.0: create a zombie from a corpse
|
||||
void CreateZombiefromCorpse( ROTTING_CORPSE * pCorpse, UINT16 usAnimState )
|
||||
{
|
||||
SOLDIERCREATE_STRUCT MercCreateStruct;
|
||||
|
||||
MercCreateStruct.ubProfile = NO_PROFILE;
|
||||
MercCreateStruct.bTeam = CREATURE_TEAM; // should be ZOMBIE_TEAM, once that is properly implemented
|
||||
MercCreateStruct.sInsertionGridNo = pCorpse->def.sGridNo;
|
||||
MercCreateStruct.sSectorX = gWorldSectorX;
|
||||
MercCreateStruct.sSectorY = gWorldSectorY;
|
||||
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
||||
MercCreateStruct.bBodyType = pCorpse->def.ubBodyType;
|
||||
MercCreateStruct.ubDirection = pCorpse->def.ubDirection;
|
||||
MercCreateStruct.fOnRoof = pCorpse->def.bLevel > 0 ? TRUE : FALSE;
|
||||
|
||||
// add important stats according to difficulty level
|
||||
// bLife is actually lower than bLifeMax. Because zombies have poison absorption, they can and will heal themselves over time, thereby gaining more life if they are not put down fast
|
||||
switch( gGameExternalOptions.sZombieDifficultyLevel )
|
||||
{
|
||||
case 4:
|
||||
MercCreateStruct.bLifeMax = (INT8)( 70 + Random( 30 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(10 + Random(15));
|
||||
MercCreateStruct.bAgility = (INT8)( 50 + Random( 10 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 60 + Random( 15 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 80 + Random( 20 ) );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
MercCreateStruct.bLifeMax = (INT8)( 60 + Random( 20 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(10 + Random(10));
|
||||
MercCreateStruct.bAgility = (INT8)( 40 + Random( 10 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 45 + Random( 10 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 60 + Random( 20 ) );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
MercCreateStruct.bLifeMax = (INT8)( 45 + Random( 15 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(5 + Random(10));
|
||||
MercCreateStruct.bAgility = (INT8)( 30 + Random( 5 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 30 + Random( 10 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 45 + Random( 20 ) );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
default:
|
||||
MercCreateStruct.bLifeMax = (INT8)( 35 + Random( 10 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(5 + Random(5));
|
||||
MercCreateStruct.bAgility = (INT8)( 15 + Random( 5 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 15 + Random( 5 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 30 + Random( 20 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
// FIX: something's wrong with the FATCIV-bodytype when dying... this is to ensure they die absolutely fast
|
||||
//if ( MercCreateStruct.bBodyType == FATCIV )
|
||||
//MercCreateStruct.bLifeMax = OKLIFE;
|
||||
|
||||
MercCreateStruct.bExpLevel = 1;
|
||||
MercCreateStruct.bMarksmanship = 1;
|
||||
MercCreateStruct.bMedical = 1;
|
||||
MercCreateStruct.bMechanical = 1;
|
||||
MercCreateStruct.bExplosive = 1;
|
||||
MercCreateStruct.bLeadership = 1;
|
||||
MercCreateStruct.bWisdom = 1;
|
||||
MercCreateStruct.bMorale = 90;
|
||||
MercCreateStruct.bAIMorale = MORALE_FEARLESS;
|
||||
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.HeadPal, pCorpse->def.HeadPal );
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.PantsPal, pCorpse->def.PantsPal );
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.VestPal, pCorpse->def.VestPal );
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.SkinPal, pCorpse->def.SkinPal );
|
||||
|
||||
MercCreateStruct.fVisible = TRUE;
|
||||
|
||||
// do not generate a new palette, thereby using the old palette of the corpse
|
||||
MercCreateStruct.fNoGenNewPalette = TRUE;
|
||||
|
||||
INT8 iNewIndex;
|
||||
if ( TacticalCreateSoldier( &MercCreateStruct, (UINT8 *)&iNewIndex ) )
|
||||
{
|
||||
/* certain values have to be set afterwards - the alternative to edit each and every function that gets called from TacticalCreateSoldier() subsequently and
|
||||
* make an exception for zombies every time...
|
||||
*/
|
||||
SOLDIERTYPE* pNewSoldier = MercPtrs[ (UINT8)iNewIndex ];
|
||||
|
||||
pNewSoldier->bActionPoints = 60;
|
||||
pNewSoldier->bInitialActionPoints = 60;
|
||||
pNewSoldier->sBreathRed = 0;
|
||||
|
||||
pNewSoldier->ubInsertionDirection = pCorpse->def.ubDirection;
|
||||
|
||||
//pNewSoldier->sHeightAdjustment = pCorpse->def.sHeightAdjustment;
|
||||
pNewSoldier->sDesiredHeight = 3;
|
||||
|
||||
pNewSoldier->ubDesiredHeight = 3; // this forces pNewSoldier to rise up to crouching position
|
||||
|
||||
pNewSoldier->ubSoldierClass = SOLDIER_CLASS_ZOMBIE;
|
||||
pNewSoldier->aiData.bOrders = SEEKENEMY;
|
||||
pNewSoldier->aiData.bAttitude = AGGRESSIVE;
|
||||
|
||||
////////////// stuff for poisoning ///////////////////////////////////
|
||||
// this is important - by declaring the gap between bLife and bLifeMax as bBleeding, the zombies will bleed (even more if they are damaged)
|
||||
// all their lifepoints are also poisoned. Thereby all bleeding damage will be poisoned bleeding damage
|
||||
// as they have bPoisonAbsorption of at least 200%, they will absorp this poison damage
|
||||
// This leads to them GAINING life through bleeding
|
||||
// They can thereby regain their health in battle (although not very fast)
|
||||
pNewSoldier->bBleeding = pNewSoldier->stats.bLifeMax - pNewSoldier->stats.bLife;
|
||||
|
||||
pNewSoldier->bPoisonSum = pNewSoldier->stats.bLifeMax;
|
||||
pNewSoldier->bPoisonLife = pNewSoldier->stats.bLife;
|
||||
pNewSoldier->bPoisonBleeding = pNewSoldier->bPoisonSum - pNewSoldier->bPoisonLife;
|
||||
// zombies get 200% poison absorption, but no resistance to it, as it would reduce their healing
|
||||
pNewSoldier->bPoisonResistance = 0;
|
||||
pNewSoldier->bPoisonAbsorption = 200 + Random(100);
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
memcpy( &(pNewSoldier->name), &(pCorpse->name), sizeof(CHAR16) * 10 );
|
||||
pNewSoldier->name[9] = '\0';
|
||||
|
||||
// add skills according to difficulty level
|
||||
switch( gGameExternalOptions.sZombieDifficultyLevel )
|
||||
{
|
||||
case 4:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = ATHLETICS_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = HANDTOHAND_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = MARTIALARTS_OT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = ATHLETICS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = NO_SKILLTRAIT_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = HANDTOHAND_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_OT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = NO_SKILLTRAIT_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = NO_SKILLTRAIT_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_OT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
default:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = NO_SKILLTRAIT_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = NO_SKILLTRAIT_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = NO_SKILLTRAIT_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_OT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
AddSoldierToSectorNoCalculateDirectionUseAnimation( iNewIndex, usAnimState, 0 );
|
||||
|
||||
// If this corpse has camo, use palette from hvobject
|
||||
if ( pCorpse->def.ubType == ROTTING_STAGE2 )
|
||||
{
|
||||
memcpy( pNewSoldier->p8BPPPalette, gpTileCache[ pCorpse->iCachedTileID ].pImagery->vo->pPaletteEntry, sizeof( pCorpse->p8BPPPalette ) * 256 );
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->bCamo = 60;
|
||||
pNewSoldier->wornCamo = 60;
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_URBAN_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->urbanCamo = 60;
|
||||
pNewSoldier->wornUrbanCamo = 60;
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_DESERT_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->desertCamo = 60;
|
||||
pNewSoldier->wornDesertCamo = 60;
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_SNOW_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->snowCamo = 60;
|
||||
pNewSoldier->wornSnowCamo = 60;
|
||||
}
|
||||
|
||||
// Reload palettes....
|
||||
if ( pNewSoldier->bInSector )
|
||||
{
|
||||
pNewSoldier->CreateSoldierPalettes( );
|
||||
}
|
||||
|
||||
// Set a pending animation to change stance first...
|
||||
//SendChangeSoldierStanceEvent( pNewSoldier, ANIM_CROUCH );
|
||||
|
||||
|
||||
// Change to standing,unless we can getup with an animation
|
||||
pNewSoldier->EVENT_InitNewSoldierAnim( STANDING, 0, TRUE );
|
||||
pNewSoldier->BeginSoldierGetup( );
|
||||
|
||||
// So we can see them!
|
||||
AllTeamsLookForAll(ALLOW_INTERRUPTS);
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente Zombies: returns true if a zombie can be raised from this corpse, and returns the correct pAnimState for the new zombie
|
||||
BOOLEAN CorpseOkToSpawnZombie( ROTTING_CORPSE * pCorpse, UINT16* pAnimState )
|
||||
{
|
||||
BOOLEAN canbezombie = FALSE;
|
||||
*pAnimState = FALLBACKHIT_STOP;
|
||||
|
||||
switch ( pCorpse->def.ubType )
|
||||
{
|
||||
case SMERC_BCK:
|
||||
case SMERC_DHD:
|
||||
case SMERC_FALL:
|
||||
case MMERC_BCK:
|
||||
case MMERC_DHD:
|
||||
case MMERC_FALL:
|
||||
case FMERC_BCK:
|
||||
case FMERC_DHD:
|
||||
case FMERC_FALL:
|
||||
case ROTTING_STAGE2:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = FALLBACKHIT_STOP;
|
||||
break;
|
||||
|
||||
case SMERC_FWD:
|
||||
case SMERC_PRN:
|
||||
case SMERC_FALLF:
|
||||
case MMERC_FWD:
|
||||
case MMERC_PRN:
|
||||
case MMERC_FALLF:
|
||||
case FMERC_FWD:
|
||||
case FMERC_PRN:
|
||||
case FMERC_FALLF:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = FALLFORWARD_HITDEATH_STOP;
|
||||
break;
|
||||
|
||||
case M_DEAD1:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = GENERIC_HIT_DEATH;
|
||||
break;
|
||||
|
||||
case M_DEAD2:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = CIV_DIE2;
|
||||
|
||||
case H_DEAD1:
|
||||
case K_DEAD1:
|
||||
case FT_DEAD1:
|
||||
case S_DEAD1:
|
||||
case W_DEAD1:
|
||||
case C_DEAD1:
|
||||
case H_DEAD2:
|
||||
case K_DEAD2:
|
||||
case FT_DEAD2:
|
||||
case S_DEAD2:
|
||||
case W_DEAD2:
|
||||
case C_DEAD2:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = STANDING;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
return( canbezombie );
|
||||
}
|
||||
|
||||
+38
-21
@@ -26,14 +26,14 @@ enum RottingCorpseDefines
|
||||
MMERC_FALL,
|
||||
MMERC_FALLF,
|
||||
|
||||
FMERC_JFK,
|
||||
FMERC_BCK,
|
||||
FMERC_FWD,
|
||||
FMERC_JFK, // head has exploded
|
||||
FMERC_BCK, // body lying backward
|
||||
FMERC_FWD, // body lying forward
|
||||
FMERC_DHD,
|
||||
FMERC_PRN,
|
||||
FMERC_WTR,
|
||||
FMERC_FALL,
|
||||
FMERC_FALLF,
|
||||
FMERC_PRN, // body lying on the belly while looking forward, one leg to the side
|
||||
FMERC_WTR, // body lying in water
|
||||
FMERC_FALL, // body lying backward, fallen from roof
|
||||
FMERC_FALLF, // body lying forward, fallen from roof
|
||||
|
||||
// CIVS
|
||||
M_DEAD1,
|
||||
@@ -73,17 +73,19 @@ enum RottingCorpseDefines
|
||||
|
||||
|
||||
|
||||
#define ROTTING_CORPSE_FIND_SWEETSPOT_FROM_GRIDNO 0x001 //Find the closest spot to the given gridno
|
||||
#define ROTTING_CORPSE_FIND_SWEETSPOT_FROM_GRIDNO 0x001 //Find the closest spot to the given gridno
|
||||
#define ROTTING_CORPSE_USE_NORTH_ENTRY_POINT 0x002 //Find the spot closest to the north entry grid
|
||||
#define ROTTING_CORPSE_USE_SOUTH_ENTRY_POINT 0x004 //Find the spot closest to the south entry grid
|
||||
#define ROTTING_CORPSE_USE_EAST_ENTRY_POINT 0x008 //Find the spot closest to the east entry grid
|
||||
#define ROTTING_CORPSE_USE_WEST_ENTRY_POINT 0x010 //Find the spot closest to the west entry grid
|
||||
#define ROTTING_CORPSE_USE_CAMO_PALETTE 0x020 //We use cammo palette here....
|
||||
#define ROTTING_CORPSE_VEHICLE 0x040 //Vehicle Corpse
|
||||
#define ROTTING_CORPSE_USE_STEALTH_PALETTE 0x080 //We use stealth palette here....
|
||||
#define ROTTING_CORPSE_USE_URBAN_CAMO_PALETTE 0x100 //We use urban palette here....
|
||||
#define ROTTING_CORPSE_USE_DESERT_CAMO_PALETTE 0x200 //We use desert palette here....
|
||||
#define ROTTING_CORPSE_USE_SNOW_CAMO_PALETTE 0x400 //We use snow palette here....
|
||||
#define ROTTING_CORPSE_VEHICLE 0x040 //Vehicle Corpse
|
||||
#define ROTTING_CORPSE_USE_STEALTH_PALETTE 0x080 //We use stealth palette here....
|
||||
#define ROTTING_CORPSE_USE_URBAN_CAMO_PALETTE 0x100 //We use urban palette here....
|
||||
#define ROTTING_CORPSE_USE_DESERT_CAMO_PALETTE 0x200 //We use desert palette here....
|
||||
#define ROTTING_CORPSE_USE_SNOW_CAMO_PALETTE 0x400 //We use snow palette here....
|
||||
#define ROTTING_CORPSE_NEVER_RISE_AGAIN 0x800 //a zombie cannot be created from this corpse (if not set, it'll eventually rise again )
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -94,26 +96,29 @@ typedef struct
|
||||
FLOAT dYPos;
|
||||
INT16 sHeightAdjustment;
|
||||
|
||||
PaletteRepID HeadPal; // Palette reps
|
||||
PaletteRepID PantsPal;
|
||||
PaletteRepID VestPal;
|
||||
PaletteRepID SkinPal;
|
||||
PaletteRepID HeadPal; // Palette reps
|
||||
PaletteRepID PantsPal;
|
||||
PaletteRepID VestPal;
|
||||
PaletteRepID SkinPal;
|
||||
|
||||
UINT8 ubDirection;
|
||||
UINT32 uiTimeOfDeath;
|
||||
UINT32 uiTimeOfDeath;
|
||||
|
||||
UINT16 usFlags;
|
||||
UINT16 usFlags;
|
||||
|
||||
INT8 bLevel;
|
||||
|
||||
INT8 bVisible;
|
||||
INT8 bNumServicingCrows;
|
||||
UINT8 ubProfile;
|
||||
BOOLEAN fHeadTaken;
|
||||
UINT8 ubAIWarningValue;
|
||||
BOOLEAN fHeadTaken;
|
||||
UINT8 ubAIWarningValue;
|
||||
|
||||
UINT8 ubFiller[ 12 ];
|
||||
|
||||
// Flugente: added name so we can display individual name if corpse gets resurrected...
|
||||
CHAR16 name[ 10 ];
|
||||
|
||||
} ROTTING_CORPSE_DEFINITION;
|
||||
|
||||
|
||||
@@ -135,6 +140,9 @@ typedef struct
|
||||
BOOLEAN fAttractCrowsOnlyWhenOnScreen;
|
||||
INT32 iID;
|
||||
|
||||
// Flugente: added name so we can display individual name if corpse gets resurrected...
|
||||
CHAR16 name[ 10 ];
|
||||
|
||||
} ROTTING_CORPSE;
|
||||
|
||||
|
||||
@@ -192,4 +200,13 @@ INT32 GetGridNoOfCorpseGivenProfileID( UINT8 ubProfileID );
|
||||
void DecayRottingCorpseAIWarnings( void );
|
||||
UINT8 GetNearestRottingCorpseAIWarning( INT32 sGridNo );
|
||||
|
||||
// Flugente: Raise zombies
|
||||
void RaiseZombies( void );
|
||||
|
||||
// Flugente: create a zombie from a corpse
|
||||
void CreateZombiefromCorpse( ROTTING_CORPSE * pCorpse, UINT16 usAnimState );
|
||||
|
||||
// Flugente: returns true if a zombie can be raised from this corpse, and returns the correct pAnimState for the new zombie
|
||||
BOOLEAN CorpseOkToSpawnZombie( ROTTING_CORPSE * pCorpse, UINT16* pAnimState );
|
||||
|
||||
#endif
|
||||
+14
-6
@@ -18,7 +18,7 @@
|
||||
#include "Soldier Control.h"
|
||||
#endif
|
||||
|
||||
INT8 EffectiveStrength( SOLDIERTYPE * pSoldier )
|
||||
INT8 EffectiveStrength( SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
INT8 bBandaged;
|
||||
INT32 iEffStrength;
|
||||
@@ -29,9 +29,9 @@ INT8 EffectiveStrength( SOLDIERTYPE * pSoldier )
|
||||
bBandaged = pSoldier->stats.bLifeMax - pSoldier->stats.bLife - pSoldier->bBleeding;
|
||||
|
||||
if (pSoldier->stats.bStrength > 0)
|
||||
{
|
||||
iEffStrength = pSoldier->stats.bStrength / 2;
|
||||
iEffStrength += (pSoldier->stats.bStrength / 2) * (pSoldier->stats.bLife + bBandaged / 2) / (pSoldier->stats.bLifeMax);
|
||||
{
|
||||
iEffStrength = ( pSoldier->stats.bStrength )/ 2;
|
||||
iEffStrength += ( (pSoldier->stats.bStrength ) / 2) * (pSoldier->stats.bLife + bBandaged / 2) / (pSoldier->stats.bLifeMax);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -164,7 +164,7 @@ INT8 EffectiveExpLevel( SOLDIERTYPE * pSoldier )
|
||||
iEffExpLevel -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (iEffExpLevel > 10)
|
||||
{
|
||||
// can't go over 10 - SANDRO
|
||||
@@ -476,7 +476,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
|
||||
case OPEN_WITH_CROWBAR:
|
||||
// Add for crowbar...
|
||||
iSkill = EffectiveStrength( pSoldier ) + 20;
|
||||
fForceDamnSound = TRUE;
|
||||
fForceDamnSound = TRUE;
|
||||
break;
|
||||
|
||||
case SMASH_DOOR_CHECK:
|
||||
@@ -546,6 +546,14 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
|
||||
iSkill /= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ATTACH_POWER_PACK: // added by Flugente
|
||||
// technicians can attach it, other people can'
|
||||
if ( HAS_SKILL_TRAIT( pSoldier, TECHNICIAN_NT ))
|
||||
iSkill = 100;
|
||||
else
|
||||
iSkill = 0;
|
||||
|
||||
break;
|
||||
default:
|
||||
iSkill = 0;
|
||||
|
||||
@@ -41,6 +41,7 @@ enum SkillChecks
|
||||
ATTACHING_SPECIAL_ITEM_CHECK,
|
||||
ATTACHING_SPECIAL_ELECTRONIC_ITEM_CHECK,
|
||||
DISARM_ELECTRONIC_TRAP_CHECK,
|
||||
ATTACH_POWER_PACK, // Flugente: attach a power pack to power armor
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -3485,6 +3485,9 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse )
|
||||
case SOLDIER_CLASS_CREATURE :
|
||||
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsCreatures++;
|
||||
break;
|
||||
case SOLDIER_CLASS_ZOMBIE :
|
||||
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsZombies++;
|
||||
break;
|
||||
default :
|
||||
if ( CREATURE_OR_BLOODCAT( pSoldier ) )
|
||||
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsCreatures++;
|
||||
|
||||
+427
-138
@@ -110,6 +110,8 @@
|
||||
|
||||
#include "Dialogue Control.h"
|
||||
|
||||
#include "IMP Skill Trait.h" // added by Flugente
|
||||
|
||||
//forward declarations of common classes to eliminate includes
|
||||
class OBJECTTYPE;
|
||||
class SOLDIERTYPE;
|
||||
@@ -135,6 +137,10 @@ extern INT16 DirIncrementer[8];
|
||||
#define MIN_SUBSEQUENT_SNDS_DELAY 2000
|
||||
#include "connect.h"
|
||||
|
||||
extern void TeleportSelectedSoldier( void );
|
||||
extern BOOLEAN AddSoldierToSectorNoCalculateDirectionUseAnimation( UINT8 ubID, UINT16 usAnimState, UINT16 usAnimCode );
|
||||
|
||||
|
||||
// Enumerate extended directions
|
||||
enum
|
||||
{
|
||||
@@ -996,6 +1002,12 @@ SOLDIERTYPE& SOLDIERTYPE::operator=(const OLDSOLDIERTYPE_101& src)
|
||||
this->wornSnowCamo = src.wornSnowCamo;
|
||||
|
||||
this->bScopeMode = USE_BEST_SCOPE;
|
||||
|
||||
this->bPoisonBleeding = 0;
|
||||
this->bPoisonLife = 0;
|
||||
this->bPoisonSum = 0;
|
||||
this->bPoisonResistance = 0;
|
||||
this->bPoisonAbsorption = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -1337,6 +1349,7 @@ MERCPROFILESTRUCT& MERCPROFILESTRUCT::operator=(const OLD_MERCPROFILESTRUCT_101&
|
||||
this->records.usKillsAdmins = (src.usKills/4);
|
||||
this->records.usKillsHostiles = 0;
|
||||
this->records.usKillsCreatures = 0;
|
||||
this->records.usKillsZombies = 0;
|
||||
this->records.usKillsTanks = 0;
|
||||
this->records.usKillsOthers = 0;
|
||||
this->records.usAssistsMercs = (src.usAssists*3/4);
|
||||
@@ -1476,7 +1489,7 @@ MERCPROFILESTRUCT& MERCPROFILESTRUCT::operator=(const OLD_MERCPROFILESTRUCT_101&
|
||||
|
||||
this->iMercMercContractLength = src.iMercMercContractLength;//Used for MERC mercs, specifies how many days the merc has gone since last page
|
||||
|
||||
this->uiTotalCostToDate = src.uiTotalCostToDate;// The total amount of money that has been paid to the merc for their salary
|
||||
this->uiTotalCostToDate = src.uiTotalCostToDate;// The total amount of money that has been paid to the merc for their salary
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -1669,7 +1682,7 @@ void HandleSystemNewAISituation( SOLDIERTYPE *pSoldier, BOOLEAN fResetABC );
|
||||
UINT16 *CreateEnemyGlow16BPPPalette( SGPPaletteEntry *pPalette, UINT32 rscale, UINT32 gscale, BOOLEAN fAdjustGreen );
|
||||
UINT16 *CreateEnemyGreyGlow16BPPPalette( SGPPaletteEntry *pPalette, UINT32 rscale, UINT32 gscale, BOOLEAN fAdjustGreen );
|
||||
|
||||
void SoldierBleed( SOLDIERTYPE *pSoldier, BOOLEAN fBandagedBleed );
|
||||
void SoldierBleed( SOLDIERTYPE *pSoldier, BOOLEAN fBandagedBleed, BOOLEAN fAllowPoisoning );
|
||||
INT32 CheckBleeding( SOLDIERTYPE *pSoldier );
|
||||
|
||||
void EVENT_InternalSetSoldierDesiredDirection( SOLDIERTYPE *pSoldier, UINT8 ubNewDirection, BOOLEAN fInitalMove, UINT16 usAnimState );
|
||||
@@ -5409,7 +5422,7 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1
|
||||
HandleMoraleEvent( this, MORALE_TOOK_LOTS_OF_DAMAGE, this->sSectorX, this->sSectorY, this->bSectorZ );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SWITCH IN TYPE OF WEAPON
|
||||
if ( ubSpecial == FIRE_WEAPON_TOSSED_OBJECT_SPECIAL )
|
||||
{
|
||||
@@ -5652,12 +5665,14 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1
|
||||
// OK, If we are a vehicle.... damage vehicle...( people inside... )
|
||||
if ( this->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
{
|
||||
this->SoldierTakeDamage( ANIM_CROUCH, sDamage, sBreathLoss, ubReason, this->ubAttackerID, NOWHERE, FALSE, TRUE );
|
||||
this->SoldierTakeDamage( ANIM_CROUCH, sDamage, 0, sBreathLoss, ubReason, this->ubAttackerID, NOWHERE, FALSE, TRUE );
|
||||
return;
|
||||
}
|
||||
|
||||
INT16 poisondamage = (INT16) ( sDamage * MercPtrs[ubAttackerID]->GetPoisonDamagePercentage() / 100 );
|
||||
|
||||
// DEDUCT LIFE
|
||||
ubCombinedLoss = this->SoldierTakeDamage( ANIM_CROUCH, sDamage, sBreathLoss, ubReason, this->ubAttackerID, NOWHERE, FALSE, TRUE );
|
||||
ubCombinedLoss = this->SoldierTakeDamage( ANIM_CROUCH, sDamage, poisondamage, sBreathLoss, ubReason, this->ubAttackerID, NOWHERE, FALSE, TRUE );
|
||||
|
||||
// ATE: OK, Let's check our ASSIGNMENT state,
|
||||
// If anything other than on a squad or guard, make them guard....
|
||||
@@ -7053,10 +7068,6 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
|
||||
{
|
||||
HandleEndTurnDrugAdjustments( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleEndTurnDrugAdjustments( this );
|
||||
}
|
||||
|
||||
// ATE: Don't bleed if in AUTO BANDAGE!
|
||||
if ( !gTacticalStatus.fAutoBandageMode )
|
||||
@@ -8657,7 +8668,16 @@ void SOLDIERTYPE::BeginSoldierClimbUpRoof( void )
|
||||
|
||||
this->ubPendingDirection = bNewDirection;
|
||||
//this->usPendingAnimation = CLIMBUPROOF;
|
||||
this->EVENT_InitNewSoldierAnim( CLIMBUPROOF, 0 , FALSE );
|
||||
|
||||
// Flugente: In case an animation is missing (zombies with bodytype of civilians), we TELEPORT instead
|
||||
if ( IsAnimationValidForBodyType( this, CLIMBUPROOF ) == FALSE )
|
||||
{
|
||||
SetSoldierHeight( 50.0 );
|
||||
TeleportSoldier( this, this->sTempNewGridNo, TRUE );
|
||||
EndAIGuysTurn( this);
|
||||
}
|
||||
else
|
||||
this->EVENT_InitNewSoldierAnim( CLIMBUPROOF, 0 , FALSE );
|
||||
|
||||
this->InternalReceivingSoldierCancelServices( FALSE );
|
||||
this->InternalGivingSoldierCancelServices( FALSE );
|
||||
@@ -8810,7 +8830,7 @@ void SOLDIERTYPE::BeginSoldierClimbWallUp( void )
|
||||
UINT32 SleepDartSuccumbChance( SOLDIERTYPE * pSoldier )
|
||||
{
|
||||
UINT32 uiChance;
|
||||
INT8 bEffectiveStrength;
|
||||
INT16 bEffectiveStrength;
|
||||
|
||||
// figure out base chance of succumbing,
|
||||
bEffectiveStrength = EffectiveStrength( pSoldier );
|
||||
@@ -9006,12 +9026,12 @@ void HandleTakeDamageDeath( SOLDIERTYPE *pSoldier, UINT8 bOldLife, UINT8 ubReaso
|
||||
}
|
||||
|
||||
|
||||
UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBreathLoss, UINT8 ubReason, UINT8 ubAttacker, INT32 sSourceGrid, INT16 sSubsequent, BOOLEAN fShowDamage )
|
||||
UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPoisonAdd, INT16 sBreathLoss, UINT8 ubReason, UINT8 ubAttacker, INT32 sSourceGrid, INT16 sSubsequent, BOOLEAN fShowDamage )
|
||||
{
|
||||
#ifdef JA2BETAVERSION
|
||||
if (is_networked) {
|
||||
CHAR tmpMPDbgString[512];
|
||||
sprintf(tmpMPDbgString,"SoldierTakeDamage ( bHeight : %i , sLifeDeduct : %i , sBreathLoss : %i , ubReason : %i , ubAttacker : %i , sSourceGrid : %i , sSubsequent : %i , fShowDamage : %i )\n", bHeight , sLifeDeduct , sBreathLoss , ubReason , ubAttacker , sSourceGrid , sSubsequent , fShowDamage );
|
||||
sprintf(tmpMPDbgString,"SoldierTakeDamage ( bHeight : %i , sLifeDeduct : %i , sPoisonAdd : %i , sBreathLoss : %i , ubReason : %i , ubAttacker : %i , sSourceGrid : %i , sSubsequent : %i , fShowDamage : %i )\n", bHeight , sLifeDeduct , sPoisonAdd, sBreathLoss , ubReason , ubAttacker , sSourceGrid , sSubsequent , fShowDamage );
|
||||
MPDebugMsg(tmpMPDbgString);
|
||||
}
|
||||
#endif
|
||||
@@ -9025,6 +9045,11 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
|
||||
|
||||
this->ubLastDamageReason = ubReason;
|
||||
|
||||
// check: poison damage cannot be higher than damage
|
||||
sPoisonAdd = min(sPoisonAdd, sLifeDeduct);
|
||||
|
||||
// reduce poison damage by poison resistance
|
||||
sPoisonAdd = (INT16)(sPoisonAdd * (100 - this->GetPoisonResistance())/100);
|
||||
|
||||
// CJC Jan 21 99: add check to see if we are hurting an enemy in an enemy-controlled
|
||||
// sector; if so, this is a sign of player activity
|
||||
@@ -9059,6 +9084,11 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
|
||||
// Deduct life!, Show damage if we want!
|
||||
bOldLife = this->stats.bLife;
|
||||
|
||||
// we need this to relation to decide how to redistribute poison points
|
||||
FLOAT dpoisonliferelation = 1.0;
|
||||
if ( bOldLife > 0 )
|
||||
dpoisonliferelation = (FLOAT)(this->bPoisonLife / bOldLife);
|
||||
|
||||
// OK, If we are a vehicle.... damage vehicle...( people inside... )
|
||||
if ( this->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
{
|
||||
@@ -9182,11 +9212,41 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
|
||||
if (sLifeDeduct > this->stats.bLife)
|
||||
{
|
||||
this->stats.bLife = 0;
|
||||
|
||||
this->bPoisonSum = 0;
|
||||
this->bPoisonLife = 0;
|
||||
this->bPoisonBleeding = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we might have poison absorption
|
||||
INT16 sLifeGainAbsorption = (INT16) ((sPoisonAdd * this->GetPoisonAbsorption())/100);
|
||||
|
||||
// life reduction gets reduced itself by life gained through absorption
|
||||
sLifeDeduct -= sLifeGainAbsorption;
|
||||
|
||||
// poison points however get increased by absorped life points (poison was absorbed, not resisted)
|
||||
INT16 poisongained = sPoisonAdd + sLifeGainAbsorption;
|
||||
|
||||
// Decrease Health
|
||||
this->stats.bLife -= sLifeDeduct;
|
||||
|
||||
// life may increase by poison absorption, so make sure it doesn't rise too much
|
||||
this->stats.bLife = min(this->stats.bLife, this->stats.bLifeMax);
|
||||
|
||||
// increase poisoning
|
||||
this->bPoisonSum = min(this->stats.bLifeMax, this->bPoisonSum + poisongained);
|
||||
|
||||
// increase poison life if we gained life through absorption
|
||||
if ( sLifeGainAbsorption > 0 )
|
||||
this->bPoisonLife = min(this->bPoisonSum, this->bPoisonLife + sLifeGainAbsorption);
|
||||
|
||||
// if no life was lost, also add sPoisonAdd to bPoisonLife
|
||||
if ( sLifeDeduct <= 0 )
|
||||
this->bPoisonLife = min(this->bPoisonSum, this->bPoisonLife + sPoisonAdd);
|
||||
else
|
||||
// we reduce bPoisonLife according to old percentage of poison life to life
|
||||
this->bPoisonLife -= (INT8) (dpoisonliferelation * sLifeDeduct);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -9211,7 +9271,8 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
|
||||
|
||||
// ATE: Put some logic in here to allow enemies to die quicker.....
|
||||
// Are we an enemy?
|
||||
if ( this->bSide != gbPlayerNum && !this->aiData.bNeutral && this->ubProfile == NO_PROFILE )
|
||||
// zombies don't die suddenly, as they regenerate health by bloodloss and poison. You have to make sure they die!
|
||||
if ( this->bSide != gbPlayerNum && !this->aiData.bNeutral && this->ubProfile == NO_PROFILE && !this->IsZombie() )
|
||||
{
|
||||
// ATE: Give them a chance to fall down...
|
||||
if ( this->stats.bLife > 0 && this->stats.bLife < ( OKLIFE - 1 ) )
|
||||
@@ -9219,11 +9280,15 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
|
||||
// Are we taking damage from bleeding?
|
||||
if ( ubReason == TAKE_DAMAGE_BLOODLOSS )
|
||||
{
|
||||
// Fifty-fifty chance to die now!
|
||||
// Fifty-fifty chance to die now!
|
||||
if ( Random( 3 ) == 0 || gTacticalStatus.Team[ this->bTeam ].bMenInSector == 1 )
|
||||
{
|
||||
// Kill!
|
||||
this->stats.bLife = 0;
|
||||
|
||||
this->bPoisonSum = 0;
|
||||
this->bPoisonLife = 0;
|
||||
this->bPoisonBleeding = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -9233,10 +9298,20 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
|
||||
{
|
||||
// Kill!
|
||||
this->stats.bLife = 0;
|
||||
|
||||
this->bPoisonSum = 0;
|
||||
this->bPoisonLife = 0;
|
||||
this->bPoisonBleeding = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( this->IsZombie() && this->stats.bLife > 0 && this->stats.bLife < OKLIFE )
|
||||
{
|
||||
// a zombie doesn't automatically die, so he would normally stand up again after being hit.
|
||||
// We don't want that, because he is dying, so we manually skip that animation
|
||||
this->usPendingAnimation = NO_PENDING_ANIMATION;
|
||||
}
|
||||
|
||||
if ( fShowDamage )
|
||||
{
|
||||
@@ -9247,6 +9322,10 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
|
||||
if ( this->stats.bLife < 0 )
|
||||
{
|
||||
this->stats.bLife = 0;
|
||||
|
||||
this->bPoisonSum = 0;
|
||||
this->bPoisonLife = 0;
|
||||
this->bPoisonBleeding = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -9267,11 +9346,29 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
|
||||
{
|
||||
// HTH does 1 pt bleeding per hit
|
||||
this->bBleeding = this->bBleeding + 1;
|
||||
|
||||
// add poison point according to poison/life relation
|
||||
this->bPoisonBleeding += (INT8) (dpoisonliferelation );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->bBleeding = this->stats.bLifeMax - ( this->stats.bLife + bBandage );
|
||||
// if we would actually bleed _less_ after applying the damage received (poison absorption), we reduce bleeding only if the new bBandage would be zero
|
||||
// by this, we can continue bleeding, and eventually bleeding
|
||||
// the normal behaviour is unchanged, as this case can't happen without poison absorption
|
||||
if ( sLifeDeduct < 0 )
|
||||
{
|
||||
INT8 oldBleeding = this->bBleeding;
|
||||
this->bBleeding = min(this->bBleeding, this->stats.bLifeMax - this->stats.bLife );
|
||||
this->bPoisonBleeding = max(0, this->bPoisonBleeding - (oldBleeding - this->bBleeding));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->bBleeding = this->stats.bLifeMax - ( this->stats.bLife + bBandage );
|
||||
|
||||
// we increase bPoisonLife according to old percentage of poison life to life
|
||||
this->bPoisonBleeding += (INT8) (dpoisonliferelation * sLifeDeduct);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10089,7 +10186,7 @@ BOOLEAN SOLDIERTYPE::CheckSoldierHitRoof( void )
|
||||
//this->EVENT_InitNewSoldierAnim( FALLFORWARD_ROOF, 0 , FALSE );
|
||||
|
||||
// Deduct hitpoints/breath for falling!
|
||||
this->SoldierTakeDamage( ANIM_CROUCH, 100, 5000, TAKE_DAMAGE_FALLROOF, NOBODY, NOWHERE, 0, TRUE );
|
||||
this->SoldierTakeDamage( ANIM_CROUCH, 100, 0, 5000, TAKE_DAMAGE_FALLROOF, NOBODY, NOWHERE, 0, TRUE );
|
||||
|
||||
fReturnVal = TRUE;
|
||||
|
||||
@@ -10104,7 +10201,7 @@ BOOLEAN SOLDIERTYPE::CheckSoldierHitRoof( void )
|
||||
this->usPendingAnimation = FALLOFF;
|
||||
|
||||
// Deduct hitpoints/breath for falling!
|
||||
this->SoldierTakeDamage( ANIM_CROUCH, 100, 5000, TAKE_DAMAGE_FALLROOF, NOBODY, NOWHERE, 0, TRUE );
|
||||
this->SoldierTakeDamage( ANIM_CROUCH, 100, 0, 5000, TAKE_DAMAGE_FALLROOF, NOBODY, NOWHERE, 0, TRUE );
|
||||
|
||||
fReturnVal = TRUE;
|
||||
}
|
||||
@@ -10139,15 +10236,21 @@ void SOLDIERTYPE::BeginSoldierClimbDownRoof( void )
|
||||
SetUIBusy( this->ubID );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
this->sTempNewGridNo = NewGridNo( this->sGridNo, (UINT16)DirectionInc(bNewDirection ) );
|
||||
|
||||
bNewDirection = gTwoCDirection[ bNewDirection ];
|
||||
|
||||
this->ubPendingDirection = bNewDirection;
|
||||
this->EVENT_InitNewSoldierAnim( JUMPDOWNWALL, 0 , FALSE );
|
||||
|
||||
// Flugente: In case an animation is missing (zombies with bodytype of civilians), we TELEPORT instead
|
||||
if ( IsAnimationValidForBodyType( this, JUMPDOWNWALL ) == FALSE )
|
||||
{
|
||||
SetSoldierHeight( 0.0 );
|
||||
TeleportSoldier( this, this->sTempNewGridNo, TRUE );
|
||||
EndAIGuysTurn( this);
|
||||
}
|
||||
else
|
||||
this->EVENT_InitNewSoldierAnim( JUMPDOWNWALL, 0 , FALSE );
|
||||
|
||||
this->InternalReceivingSoldierCancelServices( FALSE );
|
||||
this->InternalGivingSoldierCancelServices( FALSE );
|
||||
@@ -10952,6 +11055,9 @@ void SOLDIERTYPE::ReviveSoldier( void )
|
||||
|
||||
this->stats.bLife = this->stats.bLifeMax;
|
||||
this->bBleeding = 0;
|
||||
this->bPoisonBleeding = 0;
|
||||
this->bPoisonLife = 0;
|
||||
this->bPoisonSum = 0;
|
||||
this->iHealableInjury = 0; // added by SANDRO
|
||||
this->ubDesiredHeight = ANIM_STAND;
|
||||
|
||||
@@ -11376,7 +11482,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio
|
||||
#if (defined JA2UB || defined JA113NODEMO)
|
||||
if ( fMartialArtist && !Item[usItem].crowbar && this->ubBodyType == REGMALE)
|
||||
#else
|
||||
if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE ) // SANDRO - added check for body type
|
||||
if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE && !IsZombie() ) // SANDRO - added check for body type
|
||||
#endif
|
||||
{
|
||||
// Are we in attack mode yet?
|
||||
@@ -11391,66 +11497,136 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look at stance of target
|
||||
switch( gAnimControl[ pTSoldier->usAnimState ].ubEndHeight )
|
||||
// Flugente: civilians can be zombies too, but they do not have a 'punch' animation. Simple fix: They 'attack' without animation...
|
||||
// CHECK IF WE CAN DO THIS ANIMATION!
|
||||
if ( this->IsZombie() && IsAnimationValidForBodyType( this, PUNCH ) == FALSE )
|
||||
{
|
||||
case ANIM_STAND:
|
||||
case ANIM_CROUCH:
|
||||
|
||||
if ( !Item[usItem].crowbar )
|
||||
if ( gGameExternalOptions.fZombieExplodingCivs )
|
||||
{
|
||||
this->EVENT_InitNewSoldierAnim( PUNCH, 0 , FALSE );
|
||||
// Solution 1: zombie explodes, killing himself and eventually also killing his target
|
||||
// Lower hitpoints, to ensure we will die in explosion (otherwise there might be multiple explosions or zombies not dying correctly...)
|
||||
if ( stats.bLife > 2 )
|
||||
stats.bLife = 2;
|
||||
// Explosion of a Jar of RDX Crystals
|
||||
IgniteExplosion( this->ubID, this->sX, this->sY, (INT16) (gpWorldLevelData[this->sGridNo].sHeight), this->sGridNo, 136, this->pathing.bLevel );
|
||||
}
|
||||
else
|
||||
{
|
||||
this->EVENT_InitNewSoldierAnim( CROWBAR_ATTACK, 0 , FALSE );
|
||||
}
|
||||
|
||||
// CHECK IF HE CAN SEE US, IF SO CHANGE DIR
|
||||
if ( pTSoldier->aiData.bOppList[ this->ubID ] == 0 && pTSoldier->bTeam != this->bTeam )
|
||||
{
|
||||
// Get direction to target
|
||||
// IF WE ARE AN ANIMAL, CAR, MONSTER, DONT'T TURN
|
||||
if ( !( pTSoldier->flags.uiStatusFlags & ( SOLDIER_MONSTER | SOLDIER_ANIMAL | SOLDIER_VEHICLE ) ) )
|
||||
// Solution 2: Crude simulation of a 'melee' attack (this is a rig-up, a better solution needs to be found).
|
||||
// do we 'hit'?
|
||||
if ( Random(100) > 30 )
|
||||
{
|
||||
// OK, stop merc....
|
||||
pTSoldier->EVENT_StopMerc( pTSoldier->sGridNo, pTSoldier->ubDirection );
|
||||
// Play sound
|
||||
PlayJA2SampleFromFile( "Sounds\\zombie_swish1.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
|
||||
|
||||
if ( pTSoldier->bTeam != gbPlayerNum )
|
||||
INT8 oldlife = pTSoldier->stats.bLife;
|
||||
|
||||
INT16 damage = (INT16)(5 + Random(20));
|
||||
if ( pTSoldier->stats.bLife - damage < 0 )
|
||||
damage = oldlife;
|
||||
|
||||
// We've got a problem if we kill someone outright ithout him collapsing properly...
|
||||
// FIX: We'll adjust our damage, so if we'd kill someone without collapsing first, we lower our damage, to let him collapse
|
||||
// After all, this whole thing's a rig up, so there shouldn't be a problem with that
|
||||
if ( oldlife >= OKLIFE && oldlife <= damage )
|
||||
damage -= (INT16)((5 + Random(5)));
|
||||
|
||||
INT16 breathdamage = (INT16)(500 + Random(1500));
|
||||
if ( pTSoldier->bBreath - breathdamage < 0 )
|
||||
breathdamage = pTSoldier->bBreath;
|
||||
|
||||
INT16 poisondamage = (INT16) ( sDamage * this->GetPoisonDamagePercentage() / 100 );
|
||||
|
||||
// zombies do ~50% poison damage
|
||||
pTSoldier->SoldierTakeDamage( 0, damage, poisondamage, breathdamage, TAKE_DAMAGE_HANDTOHAND, this->ubID, pTSoldier->sGridNo, 0, TRUE );
|
||||
|
||||
if ( pTSoldier->stats.bLife == 0 )
|
||||
{
|
||||
CancelAIAction( pTSoldier, TRUE );
|
||||
// FINISH HIM!
|
||||
HandleTakeDamageDeath( pTSoldier, oldlife, TAKE_DAMAGE_BLOODLOSS );
|
||||
}
|
||||
else if ( pTSoldier->stats.bLife < OKLIFE && !pTSoldier->bCollapsed )
|
||||
{
|
||||
// let the target collapse...
|
||||
SoldierCollapse(pTSoldier);
|
||||
}
|
||||
|
||||
ubTDirection = (UINT8)GetDirectionFromGridNo( this->sGridNo, pTSoldier );
|
||||
SendSoldierSetDesiredDirectionEvent( pTSoldier, ubTDirection );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIM_PRONE:
|
||||
|
||||
// CHECK OUR STANCE
|
||||
// ATE: Added this for CIV body types 'cause of elliot
|
||||
if ( !IS_MERC_BODY_TYPE( this ) )
|
||||
{
|
||||
this->EVENT_InitNewSoldierAnim( PUNCH, 0 , FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( gAnimControl[ this->usAnimState ].ubEndHeight != ANIM_CROUCH )
|
||||
{
|
||||
// SET DESIRED STANCE AND SET PENDING ANIMATION
|
||||
SendChangeSoldierStanceEvent( this, ANIM_CROUCH );
|
||||
this->usPendingAnimation = PUNCH_LOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
// USE crouched one
|
||||
// NEED TO CHANGE STANCE IF NOT CROUCHD!
|
||||
this->EVENT_InitNewSoldierAnim( PUNCH_LOW, 0 , FALSE );
|
||||
// Play sound
|
||||
PlayJA2SampleFromFile( "Sounds\\zombie_swish2.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
|
||||
}
|
||||
|
||||
// zombie is done doing harm...
|
||||
EndAIGuysTurn( this);
|
||||
}
|
||||
|
||||
// ensure that we are running on our way to the next enemy
|
||||
this->EVENT_InitNewSoldierAnim( RUNNING, 0 , FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look at stance of target
|
||||
switch( gAnimControl[ pTSoldier->usAnimState ].ubEndHeight )
|
||||
{
|
||||
case ANIM_STAND:
|
||||
case ANIM_CROUCH:
|
||||
|
||||
if ( !Item[usItem].crowbar )
|
||||
{
|
||||
this->EVENT_InitNewSoldierAnim( PUNCH, 0 , FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
this->EVENT_InitNewSoldierAnim( CROWBAR_ATTACK, 0 , FALSE );
|
||||
}
|
||||
|
||||
// CHECK IF HE CAN SEE US, IF SO CHANGE DIR
|
||||
if ( pTSoldier->aiData.bOppList[ this->ubID ] == 0 && pTSoldier->bTeam != this->bTeam )
|
||||
{
|
||||
// Get direction to target
|
||||
// IF WE ARE AN ANIMAL, CAR, MONSTER, DONT'T TURN
|
||||
if ( !( pTSoldier->flags.uiStatusFlags & ( SOLDIER_MONSTER | SOLDIER_ANIMAL | SOLDIER_VEHICLE ) ) )
|
||||
{
|
||||
// OK, stop merc....
|
||||
pTSoldier->EVENT_StopMerc( pTSoldier->sGridNo, pTSoldier->ubDirection );
|
||||
|
||||
if ( pTSoldier->bTeam != gbPlayerNum )
|
||||
{
|
||||
CancelAIAction( pTSoldier, TRUE );
|
||||
}
|
||||
|
||||
ubTDirection = (UINT8)GetDirectionFromGridNo( this->sGridNo, pTSoldier );
|
||||
SendSoldierSetDesiredDirectionEvent( pTSoldier, ubTDirection );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIM_PRONE:
|
||||
|
||||
// CHECK OUR STANCE
|
||||
// ATE: Added this for CIV body types 'cause of elliot
|
||||
if ( !IS_MERC_BODY_TYPE( this ) )
|
||||
{
|
||||
this->EVENT_InitNewSoldierAnim( PUNCH, 0 , FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( gAnimControl[ this->usAnimState ].ubEndHeight != ANIM_CROUCH )
|
||||
{
|
||||
// SET DESIRED STANCE AND SET PENDING ANIMATION
|
||||
SendChangeSoldierStanceEvent( this, ANIM_CROUCH );
|
||||
this->usPendingAnimation = PUNCH_LOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
// USE crouched one
|
||||
// NEED TO CHANGE STANCE IF NOT CROUCHD!
|
||||
this->EVENT_InitNewSoldierAnim( PUNCH_LOW, 0 , FALSE );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11682,7 +11858,7 @@ void SOLDIERTYPE::EVENT_SoldierEnterVehicle( INT32 sGridNo, UINT8 ubDirection )
|
||||
UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT16 sStatus )
|
||||
{
|
||||
UINT32 uiDressSkill, uiPossible, uiActual, uiMedcost, uiDeficiency, uiAvailAPs, uiUsedAPs;
|
||||
UINT8 ubBelowOKlife, ubPtsLeft = 0;
|
||||
UINT8 ubBelowOKlife = 0, ubPtsLeft = 0;
|
||||
BOOLEAN fRanOut = FALSE;
|
||||
BOOLEAN fOnSurgery = FALSE;
|
||||
INT8 bInitialBleeding;
|
||||
@@ -11860,6 +12036,10 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
|
||||
|
||||
// use up appropriate # of actual healing points
|
||||
ubPtsLeft -= (2 * ubBelowOKlife);
|
||||
|
||||
// raise bPoisonLife, reduce bPoisonBleeding
|
||||
pVictim->bPoisonLife = min(pVictim->bPoisonLife + ubBelowOKlife, pVictim->bPoisonSum);
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - ubBelowOKlife);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -11875,12 +12055,17 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
|
||||
pVictim->bBleeding -= ( ubPtsLeft / 2);
|
||||
|
||||
ubPtsLeft = ubPtsLeft % 2; // if ptsLeft was odd, ptsLeft = 1
|
||||
|
||||
// raise bPoisonLife, reduce bPoisonBleeding
|
||||
pVictim->bPoisonLife = min(pVictim->bPoisonLife + ( ubPtsLeft / 2), pVictim->bPoisonSum);
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - ( ubPtsLeft / 2));
|
||||
}
|
||||
|
||||
// this should never happen any more, but make sure bleeding not negative
|
||||
if (pVictim->bBleeding < 0)
|
||||
{
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
|
||||
// if this healing brought the patient out of the worst of it, cancel dying
|
||||
@@ -11970,11 +12155,13 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
|
||||
if (pVictim->bBleeding >= (usLifeReturned/100))
|
||||
{
|
||||
pVictim->bBleeding -= (usLifeReturned/100);
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - (usLifeReturned/100) );
|
||||
uiMedcost += (usLifeReturned / 200); // add medkit points cost for unbandaged part
|
||||
}
|
||||
else
|
||||
{
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
uiMedcost += max( 0, (((usLifeReturned/100) - pVictim->bBleeding) / 2)); // add medkit points cost for unbandaged part
|
||||
}
|
||||
}
|
||||
@@ -11983,6 +12170,7 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
|
||||
pVictim->stats.bLife = pVictim->stats.bLifeMax;
|
||||
pVictim->iHealableInjury = 0;
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
// Reduce max breath based on life returned
|
||||
if ( (pVictim->bBreathMax - (((usLifeReturned/100) * gSkillTraitValues.usDOSurgeryMaxBreathLoss )/ 100)) <= BREATHMAX_ABSOLUTE_MINIMUM )
|
||||
@@ -12010,10 +12198,12 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
|
||||
{
|
||||
ubPtsLeft -= pVictim->bBleeding;
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
else // bandage what we can
|
||||
{
|
||||
pVictim->bBleeding -= ubPtsLeft;
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - ubPtsLeft);
|
||||
ubPtsLeft = 0;
|
||||
}
|
||||
|
||||
@@ -13189,6 +13379,8 @@ INT32 SOLDIERTYPE::GetDamageResistance(BOOLEAN fAutoResolve, BOOLEAN fCalcBreath
|
||||
resistance += gGameExternalOptions.sEnemyRegularDamageResistance;
|
||||
else if (this->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
|
||||
resistance += gGameExternalOptions.sEnemyEliteDamageResistance;
|
||||
else if (IsZombie())
|
||||
resistance += gGameExternalOptions.sEnemyZombieDamageResistance;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -13236,6 +13428,74 @@ INT32 SOLDIERTYPE::GetDamageResistance(BOOLEAN fAutoResolve, BOOLEAN fCalcBreath
|
||||
return( resistance );
|
||||
}
|
||||
|
||||
INT16 SOLDIERTYPE::GetSoldierCriticalDamageBonus( void )
|
||||
{
|
||||
INT16 val = 0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
BOOLEAN SOLDIERTYPE::IsZombie( void )
|
||||
{
|
||||
return( ubSoldierClass == SOLDIER_CLASS_ZOMBIE );
|
||||
}
|
||||
|
||||
INT16 SOLDIERTYPE::GetPoisonResistance( void )
|
||||
{
|
||||
// Flugente: resistance can per definition only be between -100 and 100 (at least that's my definition)
|
||||
INT16 val = bPoisonResistance;
|
||||
|
||||
// without WH40K, there are no modifiers
|
||||
|
||||
val = max(-100, val);
|
||||
val = min(100, val);
|
||||
|
||||
return( val );
|
||||
}
|
||||
|
||||
INT16 SOLDIERTYPE::GetPoisonAbsorption( void )
|
||||
{
|
||||
// Flugente: absorption can per definition only be >= 0 (at least that's my definition)
|
||||
INT16 val = bPoisonAbsorption;
|
||||
|
||||
val = max(0, val);
|
||||
|
||||
return( val );
|
||||
}
|
||||
|
||||
|
||||
INT16 SOLDIERTYPE::GetPoisonDamagePercentage( void )
|
||||
{
|
||||
// Flugente: this percentage has to be between 0% and 100%
|
||||
INT16 val = 0;
|
||||
|
||||
// zombies poison damage percentage is externalised
|
||||
if ( IsZombie() )
|
||||
val += gGameExternalOptions.sZombiePoisonDamagePercentage;
|
||||
|
||||
if ( this->usAttackingWeapon )
|
||||
{
|
||||
val += Item[this->usAttackingWeapon].bPoisonPercentage;
|
||||
|
||||
if ( Item[this->usAttackingWeapon].usItemClass == IC_GUN )
|
||||
{
|
||||
// check for modificators (attachments, poisoned ammunition)
|
||||
// check for poisoned ammunition
|
||||
UINT8 ammotype = this->inv[ this->ubAttackingHand ][0]->data.gun.ubGunAmmoType;
|
||||
val += AmmoTypes[ammotype].poisonPercentage;
|
||||
|
||||
// check for attachments with a bonus to poison (currently, none exist)
|
||||
}
|
||||
}
|
||||
|
||||
val = max(0, val);
|
||||
val = min(100, val);
|
||||
|
||||
return( val );
|
||||
}
|
||||
|
||||
|
||||
|
||||
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
INT8 bBandaged; //,savedOurTurn;
|
||||
@@ -13244,94 +13504,116 @@ INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
|
||||
if ( pSoldier->stats.bLife != 0 )
|
||||
{
|
||||
// if merc is hurt beyond the minimum required to bleed, or he's dying
|
||||
if ( ( pSoldier->bBleeding > MIN_BLEEDING_THRESHOLD) || pSoldier->stats.bLife < OKLIFE )
|
||||
// Flugente: also allow bleeding if we would regenerate health through it, which happens when we have enough absorption and are poisoned enough (only guaranteed if fully poisoned)
|
||||
if ( ( ( pSoldier->bBleeding > MIN_BLEEDING_THRESHOLD) || pSoldier->stats.bLife < OKLIFE ) || ( pSoldier->bPoisonSum == pSoldier->stats.bLifeMax && pSoldier->GetPoisonAbsorption() >= 200 ) )
|
||||
{
|
||||
// if he's NOT in the process of being bandaged or DOCTORed
|
||||
if ( ( pSoldier->ubServiceCount == 0 ) && ( AnyDoctorWhoCanHealThisPatient( pSoldier, HEALABLE_EVER ) == NULL ) )
|
||||
{
|
||||
// may drop blood whether or not any bleeding takes place this turn
|
||||
if ( pSoldier->bTilesMoved < 1 )
|
||||
{
|
||||
iBlood = ( ( pSoldier->bBleeding - MIN_BLEEDING_THRESHOLD ) / BLOODDIVISOR ); // + pSoldier->dying;
|
||||
if ( iBlood > MAXBLOODQUANTITY )
|
||||
{
|
||||
iBlood = MAXBLOODQUANTITY;
|
||||
}
|
||||
}
|
||||
{
|
||||
iBlood = ( ( pSoldier->bBleeding - MIN_BLEEDING_THRESHOLD ) / BLOODDIVISOR ); // + pSoldier->dying;
|
||||
if ( iBlood > MAXBLOODQUANTITY )
|
||||
{
|
||||
iBlood = MAXBLOODQUANTITY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iBlood = NOBLOOD;
|
||||
}
|
||||
{
|
||||
iBlood = NOBLOOD;
|
||||
}
|
||||
|
||||
// Are we in a different mode?
|
||||
if ( !(gTacticalStatus.uiFlags & TURNBASED ) || !(gTacticalStatus.uiFlags & INCOMBAT ) )
|
||||
{
|
||||
pSoldier->dNextBleed -= (FLOAT)RT_NEXT_BLEED_MODIFIER;
|
||||
}
|
||||
{
|
||||
pSoldier->dNextBleed -= (FLOAT)RT_NEXT_BLEED_MODIFIER;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do a single step descrease
|
||||
pSoldier->dNextBleed--;
|
||||
}
|
||||
{
|
||||
// Do a single step descrease
|
||||
pSoldier->dNextBleed--;
|
||||
}
|
||||
|
||||
// if it's time to lose some blood
|
||||
if ( pSoldier->dNextBleed <= 0)
|
||||
{
|
||||
// first, calculate if soldier is bandaged
|
||||
bBandaged = pSoldier->stats.bLifeMax - pSoldier->bBleeding - pSoldier->stats.bLife;
|
||||
{
|
||||
// first, calculate if soldier is bandaged
|
||||
bBandaged = pSoldier->stats.bLifeMax - pSoldier->bBleeding - pSoldier->stats.bLife;
|
||||
|
||||
// as long as he's bandaged and not "dying"
|
||||
if ( bBandaged && pSoldier->stats.bLife >= OKLIFE )
|
||||
{
|
||||
// just bleeding through existing bandages
|
||||
pSoldier->bBleeding++;
|
||||
|
||||
SoldierBleed( pSoldier, TRUE );
|
||||
}
|
||||
else // soldier is either not bandaged at all or is dying
|
||||
{
|
||||
if ( pSoldier->stats.bLife < OKLIFE ) // if he's dying
|
||||
// as long as he's bandaged and not "dying"
|
||||
if ( bBandaged && pSoldier->stats.bLife >= OKLIFE )
|
||||
{
|
||||
// if he's conscious, and he hasn't already, say his "dying quote"
|
||||
if ( ( pSoldier->stats.bLife >= CONSCIOUSNESS ) && !pSoldier->flags.fDyingComment )
|
||||
// just bleeding through existing bandages
|
||||
pSoldier->bBleeding++;
|
||||
|
||||
SoldierBleed( pSoldier, TRUE, TRUE );
|
||||
}
|
||||
else // soldier is either not bandaged at all or is dying
|
||||
{
|
||||
if ( pSoldier->stats.bLife < OKLIFE ) // if he's dying
|
||||
{
|
||||
TacticalCharacterDialogue( pSoldier, QUOTE_SERIOUSLY_WOUNDED );
|
||||
// if he's conscious, and he hasn't already, say his "dying quote"
|
||||
if ( ( pSoldier->stats.bLife >= CONSCIOUSNESS ) && !pSoldier->flags.fDyingComment )
|
||||
{
|
||||
TacticalCharacterDialogue( pSoldier, QUOTE_SERIOUSLY_WOUNDED );
|
||||
|
||||
pSoldier->flags.fDyingComment = TRUE;
|
||||
}
|
||||
pSoldier->flags.fDyingComment = TRUE;
|
||||
}
|
||||
|
||||
// can't permit lifemax to ever bleed beneath OKLIFE, or that
|
||||
// soldier might as well be dead!
|
||||
if (pSoldier->stats.bLifeMax >= OKLIFE)
|
||||
{
|
||||
// bleeding while "dying" costs a PERMANENT point of life each time!
|
||||
pSoldier->stats.bLifeMax--;
|
||||
pSoldier->bBleeding--;
|
||||
if ( pSoldier->iHealableInjury >= 100) // added check for insta-healable injury - SANDRO
|
||||
pSoldier->iHealableInjury -= 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
// can't permit lifemax to ever bleed beneath OKLIFE, or that
|
||||
// soldier might as well be dead!
|
||||
if (pSoldier->stats.bLifeMax >= OKLIFE)
|
||||
{
|
||||
// Flugente: reduce PERMANENT points of life only if through 'normal' bleeding, not by poisoning
|
||||
// problem is that this function applies every bleeding cycle, while loosing points through natural restoration (too much poison in body) only happens every hour.
|
||||
// so one might lose 1pt of life through poisoning at 8:00, and then lose 30 points of life PERMANTENLY in the following hour without dying
|
||||
// We bypass this by only allowing PERMANTENT lifeloss if really bleeding
|
||||
if ( pSoldier->bBleeding )
|
||||
{
|
||||
// bleeding while "dying" costs a PERMANENT point of life each time!
|
||||
pSoldier->stats.bLifeMax--;
|
||||
pSoldier->bBleeding = max(0, pSoldier->bBleeding - 1);
|
||||
|
||||
// either way, a point of life (health) is lost because of bleeding
|
||||
// This will also update the life bar
|
||||
// the lost point might be poisoned
|
||||
pSoldier->bPoisonSum = max(0, pSoldier->bPoisonSum - 1);
|
||||
|
||||
SoldierBleed( pSoldier, FALSE );
|
||||
// also adjust poisoned bleeding
|
||||
pSoldier->bPoisonBleeding = max(0, pSoldier->bPoisonBleeding - 1);
|
||||
|
||||
if ( pSoldier->iHealableInjury >= 100) // added check for insta-healable injury - SANDRO
|
||||
pSoldier->iHealableInjury -= 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// either way, a point of life (health) is lost because of bleeding
|
||||
// Flugente: not true anymore! We might be fully bandaged, not bleeding, but still receive poison damage that will lower our life. So check if we're bleeding!
|
||||
if ( pSoldier->bBleeding )
|
||||
{
|
||||
// This will also update the life bar
|
||||
SoldierBleed( pSoldier, FALSE, TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
// just to update everything, like going unconscious or dying
|
||||
pSoldier->SoldierTakeDamage( ANIM_CROUCH, 0, 0, 0, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
|
||||
}
|
||||
|
||||
|
||||
// if he's not dying (which includes him saying the dying quote just
|
||||
// now), and he hasn't warned us that he's bleeding yet, he does so
|
||||
// Also, not if they are being bandaged....
|
||||
if ( ( pSoldier->stats.bLife >= OKLIFE ) && !pSoldier->flags.fDyingComment && !pSoldier->flags.fWarnedAboutBleeding && !gTacticalStatus.fAutoBandageMode && pSoldier->ubServiceCount == 0 )
|
||||
{
|
||||
// if he's not dying (which includes him saying the dying quote just
|
||||
// now), and he hasn't warned us that he's bleeding yet, he does so
|
||||
// Also, not if they are being bandaged....
|
||||
if ( ( pSoldier->stats.bLife >= OKLIFE ) && !pSoldier->flags.fDyingComment && !pSoldier->flags.fWarnedAboutBleeding && !gTacticalStatus.fAutoBandageMode && pSoldier->ubServiceCount == 0 )
|
||||
{
|
||||
TacticalCharacterDialogue( pSoldier, QUOTE_STARTING_TO_BLEED );
|
||||
|
||||
// "starting to bleed" quote
|
||||
pSoldier->flags.fWarnedAboutBleeding = TRUE;
|
||||
}
|
||||
|
||||
pSoldier->dNextBleed = CalcSoldierNextBleed( pSoldier );
|
||||
}
|
||||
|
||||
pSoldier->dNextBleed = CalcSoldierNextBleed( pSoldier );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13340,10 +13622,8 @@ INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
|
||||
}
|
||||
|
||||
|
||||
void SoldierBleed( SOLDIERTYPE *pSoldier, BOOLEAN fBandagedBleed )
|
||||
void SoldierBleed( SOLDIERTYPE *pSoldier, BOOLEAN fBandagedBleed, BOOLEAN fAllowPoisoning )
|
||||
{
|
||||
INT8 bOldLife;
|
||||
|
||||
// OK, here make some stuff happen for bleeding
|
||||
// A banaged bleed does not show damage taken , just through existing bandages
|
||||
|
||||
@@ -13360,21 +13640,30 @@ void SoldierBleed( SOLDIERTYPE *pSoldier, BOOLEAN fBandagedBleed )
|
||||
SetInfoChar( pSoldier->ubID );
|
||||
}
|
||||
}
|
||||
|
||||
// if poisoning is allowed, if we are poisoned and we can be sure that we are really bleeding (safety reasons), there is a chance that the poisoning spreads
|
||||
// this simply means that the new Bleeding point will also be a poisoned bleeding point
|
||||
INT16 poisondamage = 0;
|
||||
if ( fAllowPoisoning && pSoldier->bPoisonSum > 0 && pSoldier->bBleeding )
|
||||
{
|
||||
INT8 bleedingpercentagepoison = (INT8) (100 * pSoldier->bPoisonSum / pSoldier->stats.bLifeMax);
|
||||
|
||||
bOldLife = pSoldier->stats.bLife;
|
||||
if ( (INT8) Random(100) < bleedingpercentagepoison )
|
||||
poisondamage = 1;
|
||||
}
|
||||
|
||||
// If we are already dead, don't show damage!
|
||||
if ( !fBandagedBleed )
|
||||
{
|
||||
// SANDRO - if the soldier is bleeding out, consider this damage as done by the last attacker
|
||||
if ( pSoldier->ubAttackerID != NOBODY )
|
||||
pSoldier->SoldierTakeDamage( ANIM_CROUCH, 1, 100, TAKE_DAMAGE_BLOODLOSS, pSoldier->ubAttackerID, NOWHERE, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( ANIM_CROUCH, 1, poisondamage, 100, TAKE_DAMAGE_BLOODLOSS, pSoldier->ubAttackerID, NOWHERE, 0, TRUE );
|
||||
else if ( pSoldier->ubPreviousAttackerID != NOBODY )
|
||||
pSoldier->SoldierTakeDamage( ANIM_CROUCH, 1, 100, TAKE_DAMAGE_BLOODLOSS, pSoldier->ubPreviousAttackerID, NOWHERE, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( ANIM_CROUCH, 1, poisondamage, 100, TAKE_DAMAGE_BLOODLOSS, pSoldier->ubPreviousAttackerID, NOWHERE, 0, TRUE );
|
||||
else if ( pSoldier->ubNextToPreviousAttackerID != NOBODY )
|
||||
pSoldier->SoldierTakeDamage( ANIM_CROUCH, 1, 100, TAKE_DAMAGE_BLOODLOSS, pSoldier->ubNextToPreviousAttackerID, NOWHERE, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( ANIM_CROUCH, 1, poisondamage, 100, TAKE_DAMAGE_BLOODLOSS, pSoldier->ubNextToPreviousAttackerID, NOWHERE, 0, TRUE );
|
||||
else
|
||||
pSoldier->SoldierTakeDamage( ANIM_CROUCH, 1, 100, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( ANIM_CROUCH, 1, poisondamage, 100, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -309,6 +309,7 @@ enum
|
||||
SOLDIER_CLASS_ELITE_MILITIA,
|
||||
SOLDIER_CLASS_CREATURE,
|
||||
SOLDIER_CLASS_MINER,
|
||||
SOLDIER_CLASS_ZOMBIE,
|
||||
};
|
||||
|
||||
#define SOLDIER_CLASS_ENEMY( bSoldierClass ) ( ( bSoldierClass >= SOLDIER_CLASS_ADMINISTRATOR ) && ( bSoldierClass <= SOLDIER_CLASS_ARMY ) )
|
||||
@@ -1143,6 +1144,21 @@ public:
|
||||
// I don't know if this is a good idea at all...
|
||||
//INT16 filler;
|
||||
|
||||
// Flugente: Is this the correct position?
|
||||
INT8 bScopeMode;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Flugente Zombies: Added variables for the poison system
|
||||
INT8 bPoisonBleeding; // The number of bleeding points that are also poison points
|
||||
//INT8 bPoisonBandaged; // The number of bandaged lifepoints that are also poison points
|
||||
INT8 bPoisonLife; // The number of Lifepoints that are also poison points
|
||||
INT8 bPoisonSum; // The sum of poison points;
|
||||
|
||||
INT16 bPoisonResistance; // poison resistance reduces the amount of poison damage received. It is applied before poison absorption
|
||||
INT16 bPoisonAbsorption; // for x points of poison damage received, you gain x * (bPoisonAbsorption / 100) poison life points
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifdef JA2UB
|
||||
//ja25
|
||||
BOOLEAN fIgnoreGetupFromCollapseCheck;
|
||||
@@ -1151,10 +1167,7 @@ public:
|
||||
|
||||
UINT8 ubPercentDamageInflictedByTeam[NUM_ASSIST_SLOTS]; //The percent of damage inflicted by the player team. Each element corresponds to the Soldier ID. Each element contains the percent damage inflicted by that merc
|
||||
#endif
|
||||
|
||||
// Flugente: Is this the correct position?
|
||||
INT8 bScopeMode;
|
||||
|
||||
|
||||
char endOfPOD; // marker for end of POD (plain old data)
|
||||
|
||||
// Note: Place all non-POD items at the end (after endOfPOD)
|
||||
@@ -1229,7 +1242,8 @@ public:
|
||||
void ChangeSoldierStance( UINT8 ubDesiredStance );
|
||||
void StopSoldier( void );
|
||||
void ReviveSoldier( void );
|
||||
UINT8 SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBreathDeduct, UINT8 ubReason, UINT8 ubAttacker, INT32 sSourceGrid, INT16 sSubsequent, BOOLEAN fShowDamage );
|
||||
// Flugente: added poison damage, which should be smaller or equal than sLifeDeduct
|
||||
UINT8 SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPoisonAdd, INT16 sBreathDeduct, UINT8 ubReason, UINT8 ubAttacker, INT32 sSourceGrid, INT16 sSubsequent, BOOLEAN fShowDamage );
|
||||
|
||||
|
||||
// Palette functions for soldiers
|
||||
@@ -1330,6 +1344,19 @@ public:
|
||||
// returns damage resistance in percent
|
||||
INT32 GetDamageResistance( BOOLEAN fAutoResolve = FALSE, BOOLEAN fCalcBreathLoss = FALSE);
|
||||
|
||||
INT16 GetSoldierCriticalDamageBonus( void ); // Flugente: determines critical damage bonus depending on class, skill, etc.
|
||||
|
||||
// Flugente: Zombies
|
||||
BOOLEAN IsZombie( void );
|
||||
|
||||
// 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
|
||||
INT16 GetPoisonResistance( void );
|
||||
INT16 GetPoisonAbsorption( void );
|
||||
// returns the poison percentage of the damage we will be doing with the weapon currently in our hand
|
||||
INT16 GetPoisonDamagePercentage( void );
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // SOLDIERTYPE;
|
||||
|
||||
#define SIZEOF_SOLDIERTYPE_POD offsetof( SOLDIERTYPE, endOfPOD )
|
||||
|
||||
@@ -341,6 +341,7 @@ SOLDIERCREATE_STRUCT::SOLDIERCREATE_STRUCT() {
|
||||
SOLDIERCREATE_STRUCT::SOLDIERCREATE_STRUCT(const SOLDIERCREATE_STRUCT& src) {
|
||||
memcpy(this, &src, SIZEOF_SOLDIERCREATE_STRUCT_POD);
|
||||
this->Inv = src.Inv;
|
||||
this->fNoGenNewPalette = src.fNoGenNewPalette;
|
||||
}
|
||||
|
||||
// Assignment operator
|
||||
@@ -349,6 +350,7 @@ SOLDIERCREATE_STRUCT& SOLDIERCREATE_STRUCT::operator=(const SOLDIERCREATE_STRUCT
|
||||
if (this != &src) {
|
||||
memcpy(this, &src, SIZEOF_SOLDIERCREATE_STRUCT_POD);
|
||||
this->Inv = src.Inv;
|
||||
this->fNoGenNewPalette = src.fNoGenNewPalette;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -1727,6 +1729,10 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
|
||||
{
|
||||
swprintf( pSoldier->name, gzLateLocalizedString[ 36 ] );
|
||||
}
|
||||
else if ( pSoldier->IsZombie() )
|
||||
{
|
||||
swprintf( pSoldier->name, TacticalStr[ ZOMBIE_TEAM_MERC_NAME ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pSoldier->name, TacticalStr[ CREATURE_TEAM_MERC_NAME ] ); break;
|
||||
@@ -1735,7 +1741,8 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
|
||||
}
|
||||
|
||||
//Generate colors for soldier based on the body type.
|
||||
GeneratePaletteForSoldier( pSoldier, pCreateStruct->ubSoldierClass );
|
||||
if ( !pCreateStruct->fNoGenNewPalette )
|
||||
GeneratePaletteForSoldier( pSoldier, pCreateStruct->ubSoldierClass );
|
||||
|
||||
// Copy item info over
|
||||
pSoldier->inv = pCreateStruct->Inv;
|
||||
@@ -2170,6 +2177,7 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
switch( ubSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
pp->bExpLevel = (INT8) 2 + bExpLevelModifier;
|
||||
break;
|
||||
case SOLDIER_CLASS_ARMY:
|
||||
@@ -2287,7 +2295,7 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
//If it is a detailed placement, don't do this yet, as detailed placements may have their
|
||||
//own equipment.
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CreateDetailedPlacementGivenBasicPlacementInfo: generate random equipment"));
|
||||
if( !bp->fDetailedPlacement && ubSoldierClass != SOLDIER_CLASS_NONE && ubSoldierClass != SOLDIER_CLASS_CREATURE && ubSoldierClass != SOLDIER_CLASS_MINER )
|
||||
if( !bp->fDetailedPlacement && ubSoldierClass != SOLDIER_CLASS_NONE && ubSoldierClass != SOLDIER_CLASS_CREATURE && ubSoldierClass != SOLDIER_CLASS_MINER && ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
GenerateRandomEquipment( pp, ubSoldierClass, bp->bRelativeEquipmentLevel);
|
||||
|
||||
DecideToAssignSniperOrders(pp);
|
||||
@@ -2455,7 +2463,7 @@ void CreateDetailedPlacementGivenStaticDetailedPlacementAndBasicPlacementInfo(
|
||||
//{
|
||||
// ReplaceExtendedGuns( pp, bp->ubSoldierClass );
|
||||
//}
|
||||
if( bp->ubSoldierClass != SOLDIER_CLASS_NONE && bp->ubSoldierClass != SOLDIER_CLASS_CREATURE && bp->ubSoldierClass != SOLDIER_CLASS_MINER )
|
||||
if( bp->ubSoldierClass != SOLDIER_CLASS_NONE && bp->ubSoldierClass != SOLDIER_CLASS_CREATURE && bp->ubSoldierClass != SOLDIER_CLASS_MINER && bp->ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
{
|
||||
GenerateRandomEquipment( pp, bp->ubSoldierClass, bp->bRelativeEquipmentLevel);
|
||||
DecideToAssignSniperOrders(pp);
|
||||
@@ -2650,7 +2658,7 @@ SOLDIERTYPE* ReserveTacticalSoldierForAutoresolve( UINT8 ubSoldierClass )
|
||||
//returns the pointer to that soldier. This is used when copying the exact status of
|
||||
//all remaining enemy troops (or creatures) to finish the battle in autoresolve. To
|
||||
//signify that the troop has already been reserved, we simply set their gridno to NOWHERE.
|
||||
if( ubSoldierClass != SOLDIER_CLASS_CREATURE )
|
||||
if( ubSoldierClass != SOLDIER_CLASS_CREATURE && ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
{ //use the enemy team
|
||||
iStart = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
|
||||
iEnd = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID;
|
||||
@@ -2660,7 +2668,7 @@ SOLDIERTYPE* ReserveTacticalSoldierForAutoresolve( UINT8 ubSoldierClass )
|
||||
iStart = gTacticalStatus.Team[ CREATURE_TEAM ].bFirstID;
|
||||
iEnd = gTacticalStatus.Team[ CREATURE_TEAM ].bLastID;
|
||||
}
|
||||
for( i = iStart; i <= iEnd; i++ )
|
||||
for( i = iStart; i <= iEnd; ++i )
|
||||
{
|
||||
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->bInSector && MercPtrs[ i ]->stats.bLife && !TileIsOutOfBounds(MercPtrs[ i ]->sGridNo))
|
||||
{
|
||||
@@ -2792,6 +2800,40 @@ SOLDIERTYPE* TacticalCreateEliteEnemy()
|
||||
return( pSoldier );
|
||||
}
|
||||
|
||||
//USED BY STRATEGIC AI and AUTORESOLVE
|
||||
SOLDIERTYPE* TacticalCreateZombie()
|
||||
{
|
||||
BASIC_SOLDIERCREATE_STRUCT bp;
|
||||
SOLDIERCREATE_STRUCT pp;
|
||||
UINT8 ubID;
|
||||
SOLDIERTYPE * pSoldier;
|
||||
|
||||
if( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI )
|
||||
{
|
||||
pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_ZOMBIE );
|
||||
if( pSoldier ) return pSoldier;
|
||||
}
|
||||
|
||||
memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) );
|
||||
RandomizeRelativeLevel( &( bp.bRelativeAttributeLevel ), SOLDIER_CLASS_ZOMBIE );
|
||||
RandomizeRelativeLevel( &( bp.bRelativeEquipmentLevel ), SOLDIER_CLASS_ZOMBIE );
|
||||
bp.bTeam = CREATURE_TEAM;//ZOMBIE_TEAM;
|
||||
bp.bOrders = SEEKENEMY;
|
||||
bp.bAttitude = AGGRESSIVE;
|
||||
bp.bBodyType = -1;
|
||||
bp.ubSoldierClass = SOLDIER_CLASS_ZOMBIE;
|
||||
CreateDetailedPlacementGivenBasicPlacementInfo( &pp, &bp );
|
||||
pSoldier = TacticalCreateSoldier( &pp, &ubID );
|
||||
if ( pSoldier )
|
||||
{
|
||||
// send soldier to centre of map, roughly
|
||||
pSoldier->aiData.sNoiseGridno = (CENTRAL_GRIDNO + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) * WORLD_COLS);
|
||||
pSoldier->aiData.ubNoiseVolume = MAX_MISC_NOISE_DURATION;
|
||||
}
|
||||
|
||||
return( pSoldier );
|
||||
}
|
||||
|
||||
SOLDIERTYPE* ReserveTacticalMilitiaSoldierForAutoresolve( UINT8 ubSoldierClass )
|
||||
{
|
||||
INT32 i, iStart, iEnd;
|
||||
@@ -4195,6 +4237,8 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 10 + ubProgress/4; // 10-35% chance
|
||||
else if( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
iChance = ubProgress/4; // 0-25% chance
|
||||
else if (ubSolClass == SOLDIER_CLASS_ZOMBIE )
|
||||
iChance = 100; // 100% chance
|
||||
|
||||
if( foundHtH ) // if found brass knuckless, increase the chance (doesn't happen often)
|
||||
iChance += 35;
|
||||
@@ -4238,6 +4282,8 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 25 + ubProgress*2/5; // 25-65% chance
|
||||
else if( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
iChance = 10 + ubProgress*2/5; // 10-50% chance
|
||||
else if (ubSolClass == SOLDIER_CLASS_ZOMBIE )
|
||||
iChance = 100; // 100% chance
|
||||
|
||||
// modify the chance by preset ini setting
|
||||
if( gGameExternalOptions.bAssignedTraitsRarity != 0 )
|
||||
|
||||
@@ -305,6 +305,9 @@ public:
|
||||
INT8 bUseGivenVehicleID;
|
||||
BOOLEAN fHasKeys;
|
||||
|
||||
// Flugente: do not generate new palette for soldier (for soldiers that are created from existing soldiers/corpses, like doppelgangers and zombies)
|
||||
BOOLEAN fNoGenNewPalette;
|
||||
|
||||
//
|
||||
// New and OO stuff goes after here. Above this point any changes will goof up reading from files.
|
||||
//
|
||||
@@ -420,6 +423,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
|
||||
SOLDIERTYPE* TacticalCreateAdministrator();
|
||||
SOLDIERTYPE* TacticalCreateEliteEnemy();
|
||||
SOLDIERTYPE* TacticalCreateArmyTroop();
|
||||
SOLDIERTYPE* TacticalCreateZombie(); // Flugente Zombies
|
||||
SOLDIERTYPE* TacticalCreateMilitia( UINT8 ubMilitiaClass );
|
||||
SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType );
|
||||
|
||||
|
||||
@@ -2106,6 +2106,7 @@ SOLDIERTYPE * SwapLarrysProfiles( SOLDIERTYPE * pSoldier )
|
||||
pNewProfile->records.usKillsRegulars = gMercProfiles[ ubSrcProfile ].records.usKillsRegulars;
|
||||
pNewProfile->records.usKillsAdmins = gMercProfiles[ ubSrcProfile ].records.usKillsAdmins;
|
||||
pNewProfile->records.usKillsCreatures = gMercProfiles[ ubSrcProfile ].records.usKillsCreatures;
|
||||
pNewProfile->records.usKillsZombies = gMercProfiles[ ubSrcProfile ].records.usKillsZombies;
|
||||
pNewProfile->records.usKillsTanks = gMercProfiles[ ubSrcProfile ].records.usKillsTanks;
|
||||
pNewProfile->records.usKillsOthers = gMercProfiles[ ubSrcProfile ].records.usKillsOthers;
|
||||
pNewProfile->records.usAssistsMercs = gMercProfiles[ ubSrcProfile ].records.usAssistsMercs;
|
||||
|
||||
@@ -273,6 +273,11 @@ void HandleTacticalEndTurn( )
|
||||
|
||||
// Flugente FTW 1: Cool down all items not in a soldier's inventory
|
||||
CoolDownWorldItems( FALSE );
|
||||
// Flugente: raise zombies if in gamescreen and option set
|
||||
if ( guiCurrentScreen == GAME_SCREEN )
|
||||
{
|
||||
RaiseZombies();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -120,6 +120,9 @@
|
||||
#include "connect.h"
|
||||
#include "fresh_header.h"
|
||||
|
||||
|
||||
#include "IMP Skill Trait.h" // added by Flugente
|
||||
|
||||
//forward declarations of common classes to eliminate includes
|
||||
class OBJECTTYPE;
|
||||
class SOLDIERTYPE;
|
||||
@@ -4316,6 +4319,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
|
||||
// Get life back
|
||||
pSoldier->stats.bLife = pSoldier->stats.bLifeMax;
|
||||
pSoldier->bBleeding = 0;
|
||||
pSoldier->bPoisonBleeding = 0;
|
||||
// SANDRO - erase insta-healable injury
|
||||
pSoldier->iHealableInjury = 0;
|
||||
|
||||
|
||||
@@ -1330,7 +1330,7 @@ BOOLEAN InjurePersonInVehicle( INT32 iId, SOLDIERTYPE *pSoldier, UINT8 ubPointsO
|
||||
}
|
||||
|
||||
// otherwise hurt them
|
||||
pSoldier->SoldierTakeDamage( 0, ubPointsOfDmg, ubPointsOfDmg, TAKE_DAMAGE_GUNFIRE, NOBODY, NOWHERE, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( 0, ubPointsOfDmg, 0, ubPointsOfDmg, TAKE_DAMAGE_GUNFIRE, NOBODY, NOWHERE, 0, TRUE );
|
||||
|
||||
pSoldier->HandleSoldierTakeDamageFeedback( );
|
||||
|
||||
@@ -1359,7 +1359,7 @@ BOOLEAN KillPersonInVehicle( INT32 iId, SOLDIERTYPE *pSoldier )
|
||||
}
|
||||
|
||||
// otherwise hurt them
|
||||
pSoldier->SoldierTakeDamage( 0, 100, 100, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( 0, 100, 0, 100, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
+64
-13
@@ -334,9 +334,6 @@ bool gbForceWeaponNotReady = false;
|
||||
bool gbForceWeaponReady = false;
|
||||
|
||||
|
||||
// Flugente: define for maximum temperature
|
||||
#define OVERHEATING_MAX_TEMPERATURE 60000.0
|
||||
|
||||
enum
|
||||
{
|
||||
WEAPON_ELEMENT_NONE = 0,
|
||||
@@ -1328,6 +1325,22 @@ BOOLEAN OKFireWeapon( SOLDIERTYPE *pSoldier )
|
||||
}
|
||||
|
||||
|
||||
// Flugente FTW 1: Get percentage: temperature/damagethreshold
|
||||
FLOAT GetGunOverheatDamagePercentage( FLOAT usTemperature, UINT16 usIndx )
|
||||
{
|
||||
FLOAT damagethreshold = Weapon[Item[ usIndx ].ubClassIndex].usOverheatingDamageThreshold;
|
||||
|
||||
return usTemperature/ damagethreshold ;
|
||||
}
|
||||
|
||||
// Flugente FTW 1: Get percentage: temperature/jamthreshold
|
||||
FLOAT GetGunOverheatJamPercentage( FLOAT usTemperature, UINT16 usIndx )
|
||||
{
|
||||
FLOAT jamthreshold = Weapon[Item[ usIndx ].ubClassIndex].usOverheatingJamThreshold;
|
||||
|
||||
return usTemperature/ jamthreshold ;
|
||||
}
|
||||
|
||||
BOOLEAN FireWeapon( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
|
||||
{
|
||||
// ignore passed in target gridno for now
|
||||
@@ -5187,6 +5200,7 @@ UINT32 CalcNewChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
|
||||
|
||||
// AGILITY OR EXPERIENCE
|
||||
FLOAT iTempPenalty = (FLOAT)__max((pTarget->stats.bExpLevel*10), pTarget->stats.bAgility);
|
||||
|
||||
iBaseModifier += (iTempPenalty * gGameCTHConstants.BASE_AGILE_TARGET) / 100;
|
||||
}
|
||||
|
||||
@@ -6235,19 +6249,19 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
|
||||
if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE )
|
||||
{
|
||||
// 13% penalty per tile closer than min range
|
||||
iChance -= 13 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE );
|
||||
iChance -= (INT32)(13 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE ));
|
||||
}
|
||||
else
|
||||
{
|
||||
// at anything other than point-blank range
|
||||
if (iRange > POINT_BLANK_RANGE + 10 * (AIM_PENALTY_TARGET_CROUCHED / 3) )
|
||||
{
|
||||
iChance -= AIM_PENALTY_TARGET_CROUCHED;
|
||||
iChance -= (INT32)(AIM_PENALTY_TARGET_CROUCHED);
|
||||
}
|
||||
else if (iRange > POINT_BLANK_RANGE)
|
||||
{
|
||||
// at close range give same bonus as prone, up to maximum of AIM_PENALTY_TARGET_CROUCHED
|
||||
iChance -= 3 * ((iRange - POINT_BLANK_RANGE) / CELL_X_SIZE); // penalty -3%/tile
|
||||
iChance -= (INT32)(3 * ((iRange - POINT_BLANK_RANGE) / CELL_X_SIZE)); // penalty -3%/tile
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -6255,7 +6269,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
|
||||
if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE )
|
||||
{
|
||||
// 25% penalty per tile closer than min range
|
||||
iChance -= 25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE );
|
||||
iChance -= (INT32)(25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE ) * iPenalty);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6286,7 +6300,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
|
||||
// e.g. 30% to aim at head at range 1, only 10% at range 3
|
||||
// or 20% to aim at torso at range 1, no penalty at range 3
|
||||
// NB torso aim position is 2, so (5-aimpos) is 3, for legs it's 2, for head 4
|
||||
iChance -= (5 - ubAdjAimPos - iRange / CELL_X_SIZE) * 10;
|
||||
iChance -= (INT32)((5 - ubAdjAimPos - iRange / CELL_X_SIZE) * 10 * iPenalty);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -8421,7 +8435,7 @@ INT32 CalcBodyImpactReduction( UINT8 ubAmmoType, UINT8 ubHitLocation )
|
||||
return( iReduction );
|
||||
}
|
||||
|
||||
INT32 ArmourProtection( SOLDIERTYPE * pTarget, UINT16 ubArmourType, INT16 * pbStatus, INT32 iImpact, UINT8 ubAmmoType, BOOLEAN *plateHit )
|
||||
INT32 ArmourProtection( SOLDIERTYPE * pTarget, UINT16 ubArmourType, INT16 * pbStatus, INT32 iImpact, UINT8 ubAmmoType, BOOLEAN *plateHit)
|
||||
{
|
||||
INT32 iProtection, iAppliedProtection, iFailure, iCoverage;
|
||||
|
||||
@@ -8498,7 +8512,7 @@ INT32 ArmourProtection( SOLDIERTYPE * pTarget, UINT16 ubArmourType, INT16 * pbSt
|
||||
else if ( AmmoTypes[ubAmmoType].ignoreArmour )
|
||||
{
|
||||
// knives and darts damage armour but are not stopped by kevlar
|
||||
if (Armour[ ubArmourType ].ubArmourClass == ARMOURCLASS_VEST || Armour[ ubArmourType ].ubArmourClass == ARMOURCLASS_LEGGINGS)
|
||||
if ( Armour[ ubArmourType ].ubArmourClass == ARMOURCLASS_VEST || Armour[ ubArmourType ].ubArmourClass == ARMOURCLASS_LEGGINGS )
|
||||
{
|
||||
iProtection = 0;
|
||||
}
|
||||
@@ -8624,6 +8638,13 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
|
||||
INT8 bStatLoss = 0;
|
||||
UINT8 ubAmmoType;
|
||||
|
||||
if ( pTarget->IsZombie() && gGameExternalOptions.fZombieOnlyHeadshotsWork )
|
||||
{
|
||||
// if bullet does not hits anything other than the head, it doesn't do any damage
|
||||
if ( ubHitLocation != AIM_SHOT_HEAD )
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: reduction of bullet impact due to range and obstacles is handled
|
||||
// in MoveBullet.
|
||||
|
||||
@@ -8769,7 +8790,7 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
|
||||
|
||||
|
||||
AdjustImpactByHitLocation( iImpact, ubHitLocation, &iImpact, &iImpactForCrits );
|
||||
|
||||
|
||||
switch( ubHitLocation )
|
||||
{
|
||||
case AIM_SHOT_HEAD:
|
||||
@@ -9346,7 +9367,22 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
if (pTarget->aiData.bOppList[ pSoldier->ubID ] == NOT_HEARD_OR_SEEN && !CREATURE_OR_BLOODCAT( pTarget ) )
|
||||
{
|
||||
iImpact = (INT32)((iImpact * 140 / 100) + 0.5); // 30% incresed damage on suprising attacks
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: power armour reduces damage taken
|
||||
INT8 iSlot = VESTPOS;
|
||||
switch( pSoldier->bAimShotLocation )
|
||||
{
|
||||
case AIM_SHOT_HEAD:
|
||||
iSlot = HELMETPOS;
|
||||
break;
|
||||
case AIM_SHOT_LEGS:
|
||||
iSlot = LEGPOS;
|
||||
break;
|
||||
default:
|
||||
iSlot = VESTPOS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// DAMAGE BONUS TO KNIFE ATTACK WITH MELEE SKILL
|
||||
@@ -9369,6 +9405,21 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
iImpact = (INT32)(iImpact * 125 / 100); // 40% incresed damage to lying characters
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: power armour reduces damage taken
|
||||
INT8 iSlot = VESTPOS;
|
||||
switch( pSoldier->bAimShotLocation )
|
||||
{
|
||||
case AIM_SHOT_HEAD:
|
||||
iSlot = HELMETPOS;
|
||||
break;
|
||||
case AIM_SHOT_LEGS:
|
||||
iSlot = LEGPOS;
|
||||
break;
|
||||
default:
|
||||
iSlot = VESTPOS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// bonus damage for aggressive characters
|
||||
@@ -9501,7 +9552,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
|
||||
// We need to be agile and dexterous
|
||||
iAttRating = ( 2 * EffectiveDexterity( pAttacker ) + // coordination, accuracy *
|
||||
2 * EffectiveAgility( pAttacker ) + // speed & reflexes
|
||||
pAttacker->stats.bStrength + // physical strength
|
||||
pAttacker->stats.bStrength + // physical strength
|
||||
(10 * EffectiveExpLevel( pAttacker ) ) ); // experience, knowledge
|
||||
}
|
||||
else
|
||||
|
||||
@@ -211,6 +211,7 @@ typedef struct
|
||||
INT16 lockBustingPower;
|
||||
BOOLEAN tracerEffect;
|
||||
FLOAT temperatureModificator; // Flugente FTW 1.1: modificator for weapon temperature
|
||||
INT16 poisonPercentage; // Flugente FTW 1.1: modificator for weapon temperature
|
||||
|
||||
//zilpin: pellet spread patterns externalized in XML
|
||||
INT32 spreadPattern;
|
||||
@@ -428,6 +429,8 @@ extern void GetTargetWorldPositions( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo,
|
||||
|
||||
extern BOOLEAN OKFireWeapon( SOLDIERTYPE *pSoldier );
|
||||
extern BOOLEAN CheckForGunJam( SOLDIERTYPE * pSoldier );
|
||||
extern FLOAT GetGunOverheatDamagePercentage( FLOAT usTemperature, UINT16 usIndx ); // Flugente FTW 1: Get percentage: temperature/damagethreshold
|
||||
extern FLOAT GetGunOverheatJamPercentage( FLOAT usTemperature, UINT16 usIndx ); // Flugente FTW 1: Get percentage: temperature/jamthreshold
|
||||
|
||||
extern INT32 CalcMaxTossRange( SOLDIERTYPE * pSoldier, UINT16 usItem, BOOLEAN fArmed );
|
||||
extern UINT32 CalcThrownChanceToHit(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos );
|
||||
|
||||
@@ -844,7 +844,7 @@ void CoolDownWorldItems( BOOLEAN fSetZero )
|
||||
{
|
||||
for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ...
|
||||
{
|
||||
FLOAT newguntemperature = 0.0;
|
||||
FLOAT newguntemperature = 0.0f;
|
||||
|
||||
if ( !fSetZero && gGameExternalOptions.fSetZeroUponNewSector )
|
||||
{
|
||||
@@ -855,7 +855,7 @@ void CoolDownWorldItems( BOOLEAN fSetZero )
|
||||
if ( Item[gWorldItems[ uiCount ].object.usItem].barrel == TRUE ) // ... a barrel lying around cools down a bit faster ...
|
||||
cooldownfactor *= gGameExternalOptions.iCooldownModificatorLonelyBarrel;
|
||||
|
||||
newguntemperature = max(0.0, guntemperature - cooldownfactor); // ... calculate new temperature ...
|
||||
newguntemperature = max(0.0f, guntemperature - cooldownfactor); // ... calculate new temperature ...
|
||||
}
|
||||
|
||||
(*pObj)[i]->data.bTemperature = newguntemperature; // ... set new temperature
|
||||
@@ -869,7 +869,7 @@ void CoolDownWorldItems( BOOLEAN fSetZero )
|
||||
{
|
||||
if ( iter->exists() && Item[ iter->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
|
||||
{
|
||||
FLOAT newtemperature = 0.0;
|
||||
FLOAT newtemperature = 0.0f;
|
||||
|
||||
if ( !fSetZero && gGameExternalOptions.fSetZeroUponNewSector )
|
||||
{
|
||||
@@ -877,7 +877,7 @@ void CoolDownWorldItems( BOOLEAN fSetZero )
|
||||
|
||||
FLOAT cooldownfactor = GetItemCooldownFactor( &(*iter) ); // ... get cooldown factor ...
|
||||
|
||||
newtemperature = max(0.0, temperature - cooldownfactor); // ... calculate new temperature ...
|
||||
newtemperature = max(0.0f, temperature - cooldownfactor); // ... calculate new temperature ...
|
||||
}
|
||||
|
||||
(*iter)[i]->data.bTemperature = newtemperature; // ... set new temperature
|
||||
|
||||
@@ -79,7 +79,8 @@ ammotypeStartElementHandle(void *userData, const XML_Char *name, const XML_Char
|
||||
strcmp(name, "acidic") == 0 ||
|
||||
strcmp(name, "tracerEffect") == 0 ||
|
||||
strcmp(name, "monsterSpit") == 0 ||
|
||||
strcmp(name, "temperatureModificator") == 0 ))
|
||||
strcmp(name, "temperatureModificator") == 0 ||
|
||||
strcmp(name, "PoisonPercentage") == 0 ))
|
||||
{
|
||||
pData->curElement = ELEMENT_PROPERTY;
|
||||
|
||||
@@ -282,6 +283,15 @@ ammotypeEndElementHandle(void *userData, const XML_Char *name)
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curAmmoType.temperatureModificator = (FLOAT) atof(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "PoisonPercentage") == 0)
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curAmmoType.poisonPercentage = (INT16) atol(pData->szCharData);
|
||||
|
||||
// check: poisonPercentage must be between 0 and 100, fit bad values
|
||||
pData->curAmmoType.poisonPercentage = max(0, pData->curAmmoType.poisonPercentage);
|
||||
pData->curAmmoType.poisonPercentage = min(100, pData->curAmmoType.poisonPercentage);
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
@@ -404,6 +414,7 @@ BOOLEAN WriteAmmoTypeStats()
|
||||
FilePrintf(hFile,"\t\t<lockBustingPower>%d</lockBustingPower>\r\n", AmmoTypes[cnt].lockBustingPower );
|
||||
FilePrintf(hFile,"\t\t<tracerEffect>%d</tracerEffect>\r\n", AmmoTypes[cnt].tracerEffect );
|
||||
FilePrintf(hFile,"\t\t<temperatureModificator>%4.2f</temperatureModificator>\r\n", AmmoTypes[cnt].temperatureModificator );
|
||||
FilePrintf(hFile,"\t\t<PoisonPercentage>%d</PoisonPercentage>\r\n", AmmoTypes[cnt].poisonPercentage );
|
||||
|
||||
|
||||
FilePrintf(hFile,"\t</AMMOTYPE>\r\n");
|
||||
|
||||
@@ -4764,6 +4764,7 @@ void DebugSoldierPage4( )
|
||||
case SOLDIER_CLASS_REG_MILITIA: gprintf( 320, LINE_HEIGHT * ubLine, L"(Reg Militia)" ); break;
|
||||
case SOLDIER_CLASS_ELITE_MILITIA: gprintf( 320, LINE_HEIGHT * ubLine, L"(Elite Militia)" ); break;
|
||||
case SOLDIER_CLASS_MINER: gprintf( 320, LINE_HEIGHT * ubLine, L"(Miner)" ); break;
|
||||
case SOLDIER_CLASS_ZOMBIE: gprintf( 320, LINE_HEIGHT * ubLine, L"(Zombie)" ); break;
|
||||
default: break; //don't care (don't write anything)
|
||||
}
|
||||
ubLine++;
|
||||
|
||||
@@ -262,6 +262,7 @@ public:
|
||||
UINT16 usKillsAdmins;
|
||||
UINT16 usKillsHostiles;
|
||||
UINT16 usKillsCreatures;
|
||||
UINT16 usKillsZombies;
|
||||
UINT16 usKillsTanks;
|
||||
UINT16 usKillsOthers;
|
||||
|
||||
|
||||
@@ -171,6 +171,14 @@ INT32 ClosestSeenOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLeve
|
||||
void CreatureCall( SOLDIERTYPE * pCaller );
|
||||
INT8 CreatureDecideAction( SOLDIERTYPE * pCreature );
|
||||
void CreatureDecideAlertStatus( SOLDIERTYPE *pCreature );
|
||||
|
||||
// Flugente: Zombie AI
|
||||
INT8 ZombieDecideAction( SOLDIERTYPE * pZombie );
|
||||
void ZombieDecideAlertStatus( SOLDIERTYPE *pZombie );
|
||||
|
||||
// a variant of ClosestSeenOpponent(...), that allows zombies
|
||||
INT32 ClosestSeenOpponentforZombie(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel);
|
||||
|
||||
INT8 CrowDecideAction( SOLDIERTYPE * pSoldier );
|
||||
void DecideAlertStatus( SOLDIERTYPE *pSoldier );
|
||||
INT8 DecideAutoBandage( SOLDIERTYPE * pSoldier );
|
||||
|
||||
+31
-1
@@ -1616,7 +1616,32 @@ fprintf(NetDebugFile,"\tNPC %d, dtctLvl %d, marking mine at gridno %d, gridCost
|
||||
|
||||
void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
// added by Flugente: static pointers, used to break out of an endless circles (currently only used for zombie AI)
|
||||
static SOLDIERTYPE* pLastDecisionSoldier = NULL;
|
||||
static INT16 lastdecisioncount = 0;
|
||||
|
||||
// simple solution to prevent an endless clock: remember the last soldier that decided an action. If its the same one, increase the counter.
|
||||
// if counter is high enough, end this guy's turn
|
||||
if ( pSoldier == pLastDecisionSoldier )
|
||||
{
|
||||
// we will only end our turn this way if this function was called over 100 times with same soldier without ending a turn.
|
||||
// so many actions in a single turn smell of an endless clock.
|
||||
// If we end a turn normally, the counter will be set back to 0, so this wont be a problem if you have a single soldier left for multiple turns
|
||||
if ( lastdecisioncount >= 100 )
|
||||
{
|
||||
// zombie is done doing harm...
|
||||
EndAIGuysTurn( pSoldier);
|
||||
lastdecisioncount = 0;
|
||||
return ;
|
||||
}
|
||||
else
|
||||
++lastdecisioncount;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLastDecisionSoldier = pSoldier;
|
||||
lastdecisioncount = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
if (Status.gamePaused)
|
||||
@@ -1905,7 +1930,11 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
if (!(gTacticalStatus.uiFlags & ENGAGED_IN_CONV))
|
||||
{
|
||||
if (CREATURE_OR_BLOODCAT( pSoldier ))
|
||||
if ( pSoldier->IsZombie() )
|
||||
{
|
||||
pSoldier->aiData.bAction = ZombieDecideAction(pSoldier);
|
||||
}
|
||||
else if (CREATURE_OR_BLOODCAT( pSoldier ))
|
||||
{
|
||||
pSoldier->aiData.bAction = CreatureDecideAction( pSoldier );
|
||||
}
|
||||
@@ -1971,6 +2000,7 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
// turn based... abort this guy's turn
|
||||
EndAIGuysTurn( pSoldier );
|
||||
lastdecisioncount = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1295,6 +1295,100 @@ INT32 ClosestSeenOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLeve
|
||||
}
|
||||
|
||||
|
||||
// special variant with a minor twist for the zombie AI
|
||||
INT32 ClosestSeenOpponentforZombie(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel)
|
||||
{
|
||||
INT32 sGridNo, sClosestOpponent = NOWHERE;
|
||||
UINT32 uiLoop;
|
||||
INT32 iRange, iClosestRange = 1500;
|
||||
INT8 *pbPersOL;
|
||||
INT8 bLevel, bClosestLevel;
|
||||
SOLDIERTYPE * pOpp;
|
||||
|
||||
bClosestLevel = -1;
|
||||
|
||||
// look through this man's personal & public opplists for opponents known
|
||||
for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
|
||||
{
|
||||
pOpp = MercSlots[ uiLoop ];
|
||||
|
||||
// if this merc is inactive, at base, on assignment, or dead
|
||||
if (!pOpp)
|
||||
{
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
// if this merc is neutral/on same side, he's not an opponent
|
||||
if ( CONSIDERED_NEUTRAL( pSoldier, pOpp ) || (pSoldier->bSide == pOpp->bSide))
|
||||
{
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
// Special stuff for Carmen the bounty hunter
|
||||
if (pSoldier->aiData.bAttitude == ATTACKSLAYONLY && pOpp->ubProfile != 64)
|
||||
{
|
||||
continue; // next opponent
|
||||
}
|
||||
|
||||
pbPersOL = pSoldier->aiData.bOppList + pOpp->ubID;
|
||||
|
||||
// if this opponent is not seen personally
|
||||
if (*pbPersOL != SEEN_CURRENTLY)
|
||||
{
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
// since we're dealing with seen people, use exact gridnos
|
||||
sGridNo = pOpp->sGridNo;
|
||||
bLevel = pOpp->pathing.bLevel;
|
||||
|
||||
// if we are standing at that gridno(!, obviously our info is old...)
|
||||
if (sGridNo == pSoldier->sGridNo)
|
||||
{
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
// special: allow zombies to also find opponents on a roof
|
||||
// otherwise they have will never decide to climb a roof while they are seeing an enemy
|
||||
// this function is used only for turning towards closest opponent or changing stance
|
||||
// as such, if they AI is in a building,
|
||||
// we should ignore people who are on the roof of the same building as the AI
|
||||
if ( !pSoldier->IsZombie() && (bLevel != pSoldier->pathing.bLevel) && SameBuilding( pSoldier->sGridNo, sGridNo ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// I hope this will be good enough; otherwise we need a fractional/world-units-based 2D distance function
|
||||
//sRange = PythSpacesAway( pSoldier->sGridNo, sGridNo);
|
||||
iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo );
|
||||
|
||||
if (iRange < iClosestRange)
|
||||
{
|
||||
iClosestRange = iRange;
|
||||
sClosestOpponent = sGridNo;
|
||||
bClosestLevel = bLevel;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUGDECISIONS
|
||||
if (!TileIsOutOfBounds(sClosestOpponent))
|
||||
{
|
||||
AINumMessage("CLOSEST OPPONENT is at gridno ",sClosestOpponent);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (psGridNo)
|
||||
{
|
||||
*psGridNo = sClosestOpponent;
|
||||
}
|
||||
if (pbLevel)
|
||||
{
|
||||
*pbLevel = bClosestLevel;
|
||||
}
|
||||
return( sClosestOpponent );
|
||||
}
|
||||
|
||||
|
||||
INT32 ClosestPC( SOLDIERTYPE *pSoldier, INT32 * psDistance )
|
||||
{
|
||||
// used by NPCs... find the closest PC
|
||||
@@ -2487,6 +2581,10 @@ UINT8 SoldierDifficultyLevel( SOLDIERTYPE * pSoldier )
|
||||
bDifficulty = 4;
|
||||
break;
|
||||
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
bDifficulty = bDifficultyBase;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (pSoldier->bTeam == CREATURE_TEAM)
|
||||
{
|
||||
|
||||
@@ -1757,3 +1757,4 @@ INT8 CrowDecideAction( SOLDIERTYPE * pSoldier )
|
||||
return( AI_ACTION_NONE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,10 @@ INT8 RTPlayerDecideAction( SOLDIERTYPE * pSoldier )
|
||||
{
|
||||
bAction = DecideAutoBandage( pSoldier );
|
||||
}
|
||||
else if ( pSoldier->IsZombie() )
|
||||
{
|
||||
bAction = ZombieDecideAction( pSoldier );
|
||||
}
|
||||
else
|
||||
{
|
||||
bAction = DecideAction( pSoldier );
|
||||
@@ -47,6 +51,10 @@ INT8 RTDecideAction(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
return( CreatureDecideAction( pSoldier ) );
|
||||
}
|
||||
else if ( pSoldier->IsZombie() )
|
||||
{
|
||||
return( ZombieDecideAction( pSoldier ) );
|
||||
}
|
||||
else if (pSoldier->ubBodyType == CROW)
|
||||
{
|
||||
return( CrowDecideAction( pSoldier ) );
|
||||
|
||||
@@ -1577,21 +1577,10 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT32 sBombGridNo
|
||||
// Bodybuilding damage resistance
|
||||
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, BODYBUILDING_NT ) )
|
||||
sNewWoundAmt = max( 1, (INT16)(sNewWoundAmt * (100 - gSkillTraitValues.ubBBDamageResistance) / 100));
|
||||
|
||||
// Damage resistance for Militia
|
||||
if (pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.bGreenMilitiaDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.bGreenMilitiaDamageResistance) /100);
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.bRegularMilitiaDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.bRegularMilitiaDamageResistance) /100);
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.bVeteranMilitiaDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.bVeteranMilitiaDamageResistance) /100);
|
||||
// bonus for enemy too
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.sEnemyAdminDamageResistance) /100);
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.sEnemyRegularDamageResistance) /100);
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.sEnemyEliteDamageResistance) /100);
|
||||
|
||||
// Flugente: moved the damage calculation into a separate function
|
||||
if ( pSoldier->GetDamageResistance(FALSE, FALSE) > 0 )
|
||||
sNewWoundAmt -= ((sNewWoundAmt * pSoldier->GetDamageResistance(FALSE, FALSE)) /100);
|
||||
|
||||
// we can loose stats due to being hit by the blast
|
||||
else if ( gGameOptions.fNewTraitSystem && Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL &&
|
||||
@@ -1790,41 +1779,12 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT32 sBombGridNo
|
||||
sNewWoundAmt = max(1, sNewWoundAmt);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - option to make special NPCs stronger - damage resistance
|
||||
if (gGameExternalOptions.usSpecialNPCStronger > 0)
|
||||
{
|
||||
switch( pSoldier->ubProfile )
|
||||
{
|
||||
case CARMEN:
|
||||
case QUEEN:
|
||||
case JOE:
|
||||
case ANNIE:
|
||||
case CHRIS:
|
||||
case KINGPIN:
|
||||
case TIFFANY:
|
||||
case T_REX:
|
||||
case DRUGGIST:
|
||||
case GENERAL:
|
||||
case JACK:
|
||||
case OLAF:
|
||||
case RAY:
|
||||
case OLGA:
|
||||
case TYRONE:
|
||||
case MIKE:
|
||||
sNewWoundAmt -= (sNewWoundAmt * gGameExternalOptions.usSpecialNPCStronger / 200);
|
||||
sNewWoundAmt = max( 1, sNewWoundAmt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SANDRO - new merc records - times wounded (blasted by explosion)
|
||||
if ( ( sNewWoundAmt > 1 || sBreathAmt > 1000 ) && pSoldier->ubProfile != NO_PROFILE )
|
||||
gMercProfiles[ pSoldier->ubProfile ].records.usTimesWoundedBlasted++;
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
// Lesh: flashbang does affect on soldier or not - check it
|
||||
if ( (Item[usItem].usItemClass & IC_EXPLOSV) && fFlashbang )
|
||||
{
|
||||
@@ -1918,7 +1878,8 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN
|
||||
{
|
||||
if ( pExplosive->ubType == EXPLOSV_TEARGAS )
|
||||
{
|
||||
if ( AM_A_ROBOT( pSoldier ) )
|
||||
// zombies and robots are unaffected by tear gas
|
||||
if ( AM_A_ROBOT( pSoldier ) || pSoldier->IsZombie() )
|
||||
{
|
||||
return( fRecompileMovementCosts );
|
||||
}
|
||||
@@ -1932,7 +1893,8 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN
|
||||
}
|
||||
else if ( pExplosive->ubType == EXPLOSV_MUSTGAS )
|
||||
{
|
||||
if ( AM_A_ROBOT( pSoldier ) )
|
||||
// zombies and robots are unaffected by mustard gas
|
||||
if ( AM_A_ROBOT( pSoldier ) || pSoldier->IsZombie() )
|
||||
{
|
||||
return( fRecompileMovementCosts );
|
||||
}
|
||||
@@ -2030,9 +1992,8 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN
|
||||
case EXPLOSV_TEARGAS:
|
||||
pSoldier->flags.fHitByGasFlags |= HIT_BY_TEARGAS;
|
||||
break;
|
||||
case EXPLOSV_MUSTGAS:
|
||||
case EXPLOSV_MUSTGAS:
|
||||
pSoldier->flags.fHitByGasFlags |= HIT_BY_MUSTARDGAS;
|
||||
break;
|
||||
case EXPLOSV_BURNABLEGAS:
|
||||
pSoldier->flags.fHitByGasFlags |= HIT_BY_BURNABLEGAS;
|
||||
break;
|
||||
@@ -2046,7 +2007,7 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN
|
||||
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"ExpControl pSoldier->flags.fHitByGasFlags: %d", pSoldier->flags.fHitByGasFlags );
|
||||
|
||||
// a gas effect, take damage directly...
|
||||
pSoldier->SoldierTakeDamage( ANIM_STAND, sWoundAmt, sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( ANIM_STAND, sWoundAmt, 0, sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE );
|
||||
|
||||
if (is_networked && is_client)
|
||||
{
|
||||
@@ -2480,7 +2441,7 @@ BOOLEAN ExpAffect( INT32 sBombGridNo, INT32 sGridNo, UINT32 uiDist, UINT16 usIte
|
||||
break;
|
||||
}
|
||||
// a gas effect, take damage directly...
|
||||
pSoldier->SoldierTakeDamage( ANIM_STAND, sWoundAmt, sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE );
|
||||
pSoldier->SoldierTakeDamage( ANIM_STAND, sWoundAmt, 0, sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE );
|
||||
if ( pSoldier->stats.bLife >= CONSCIOUSNESS )
|
||||
{
|
||||
pSoldier->DoMercBattleSound( (INT8)( BATTLE_SOUND_HIT1 + Random( 2 ) ) );
|
||||
|
||||
@@ -683,14 +683,43 @@ void RenderTacticalPlacementGUI()
|
||||
iStartY = yp + 29 - 27*pSoldier->stats.bLifeMax/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+36, iStartY, xp+37, yp+29, Get16BPPColor( FROMRGB( 107, 107, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+37, iStartY, xp+38, yp+29, Get16BPPColor( FROMRGB( 222, 181, 115 ) ) );
|
||||
|
||||
// poisoned bleeding in purple
|
||||
if ( pSoldier->bPoisonBleeding )
|
||||
{
|
||||
iStartY = yp + 29 - 27*(pSoldier->stats.bLifeMax - pSoldier->bBleeding + pSoldier->bPoisonBleeding)/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+36, iStartY, xp+37, yp+29, Get16BPPColor( FROMRGB( 107, 57, 107 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+37, iStartY, xp+38, yp+29, Get16BPPColor( FROMRGB( 222, 115, 181 ) ) );
|
||||
}
|
||||
|
||||
//pink one for bandaged.
|
||||
iStartY += 27*pSoldier->bBleeding/100;
|
||||
iStartY = yp + 29 - 27*(pSoldier->stats.bLifeMax - pSoldier->bBleeding)/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+36, iStartY, xp+37, yp+29, Get16BPPColor( FROMRGB( 156, 57, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+37, iStartY, xp+38, yp+29, Get16BPPColor( FROMRGB( 222, 132, 132 ) ) );
|
||||
|
||||
// get amount of poisoned bandage
|
||||
INT8 bPoisonBandage = pSoldier->bPoisonSum - pSoldier->bPoisonBleeding - pSoldier->bPoisonLife;
|
||||
if ( bPoisonBandage )
|
||||
{
|
||||
// poisoned bandage in bright green
|
||||
iStartY = yp + 29 - 27*(pSoldier->stats.bLife + bPoisonBandage)/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+36, iStartY, xp+37, yp+29, Get16BPPColor( FROMRGB( 57, 156, 57 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+37, iStartY, xp+38, yp+29, Get16BPPColor( FROMRGB( 132, 222, 132 ) ) );
|
||||
}
|
||||
|
||||
//red one for actual health
|
||||
iStartY = yp + 29 - 27*pSoldier->stats.bLife/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+36, iStartY, xp+37, yp+29, Get16BPPColor( FROMRGB( 107, 8, 8 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+37, iStartY, xp+38, yp+29, Get16BPPColor( FROMRGB( 206, 0, 0 ) ) );
|
||||
|
||||
// poisoned life
|
||||
if ( pSoldier->bPoisonLife )
|
||||
{
|
||||
iStartY = yp + 29 - 27*pSoldier->bPoisonLife/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+36, iStartY, xp+37, yp+29, Get16BPPColor( FROMRGB( 8, 107, 8 ) ) );
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+37, iStartY, xp+38, yp+29, Get16BPPColor( FROMRGB( 0, 206, 0 ) ) );
|
||||
}
|
||||
|
||||
//BREATH BAR
|
||||
iStartY = yp + 29 - 27*pSoldier->bBreathMax/100;
|
||||
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+39, iStartY, xp+40, yp+29, Get16BPPColor( FROMRGB( 8, 8, 132 ) ) );
|
||||
|
||||
+7
-4
@@ -632,14 +632,14 @@ extern STR16 szUDBGenWeaponsStatsTooltipText[ 23 ];
|
||||
extern STR16 szUDBGenWeaponsStatsExplanationsTooltipText[ 23 ];
|
||||
extern STR16 szUDBGenArmorStatsTooltipText[ 3 ];
|
||||
extern STR16 szUDBGenArmorStatsExplanationsTooltipText[ 3 ];
|
||||
extern STR16 szUDBGenAmmoStatsTooltipText[ 4 ]; // Flugente Overheating Weapons: 3->4
|
||||
extern STR16 szUDBGenAmmoStatsExplanationsTooltipText[ 4 ];
|
||||
extern STR16 szUDBGenAmmoStatsTooltipText[ 5 ]; // Flugente Overheating: 3->4 poison: 4->5
|
||||
extern STR16 szUDBGenAmmoStatsExplanationsTooltipText[ 5 ]; // Flugente Overheating: 3->4 poison: 4->5
|
||||
extern STR16 szUDBGenExplosiveStatsTooltipText[ 22 ];
|
||||
extern STR16 szUDBGenExplosiveStatsExplanationsTooltipText[ 22 ];
|
||||
extern STR16 szUDBGenSecondaryStatsTooltipText[ 26 ];
|
||||
extern STR16 szUDBGenSecondaryStatsExplanationsTooltipText[ 26 ];
|
||||
extern STR16 szUDBAdvStatsTooltipText[ 56 ]; // Flugente Overheating Weapons: 48->56
|
||||
extern STR16 szUDBAdvStatsExplanationsTooltipText[ 56 ]; // Flugente Overheating Weapons: 48->56
|
||||
extern STR16 szUDBAdvStatsTooltipText[ 57 ]; // Flugente Overheating Weapons: 48->56 poison: 56->57
|
||||
extern STR16 szUDBAdvStatsExplanationsTooltipText[ 57 ]; // Flugente Overheating Weapons: 48->56 poison: 56->57
|
||||
extern STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[ 52 ]; // Flugente Overheating Weapons: 48->52
|
||||
|
||||
// Headrock: End Externs
|
||||
@@ -752,6 +752,7 @@ enum
|
||||
CREATURE_TEAM_MERC_NAME,
|
||||
MILITIA_TEAM_MERC_NAME,
|
||||
CIV_TEAM_MERC_NAME,
|
||||
ZOMBIE_TEAM_MERC_NAME,
|
||||
|
||||
//The text for the 'exiting sector' gui
|
||||
EXIT_GUI_TITLE_STR,
|
||||
@@ -808,6 +809,8 @@ enum
|
||||
CHOOSE_REMOTE_DETONATE_AND_REMOTE_DEFUSE_FREQUENCY_STR,
|
||||
CHOOSE_DETONATE_AND_REMOTE_DEFUSE_FREQUENCY_STR,
|
||||
CHOOSE_TRIPWIRE_NETWORK,
|
||||
|
||||
MERC_VITAL_STATS_WITH_POISON_POPUPTEXT,
|
||||
|
||||
TEXT_NUM_TACTICAL_STR
|
||||
};
|
||||
|
||||
@@ -265,6 +265,8 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
|
||||
strcmp(name, "Directional") == 0 ||
|
||||
strcmp(name, "DrugType") == 0 ||
|
||||
strcmp(name, "BlockIronSight") == 0 ||
|
||||
// Flugente: poison system
|
||||
strcmp(name, "PoisonPercentage") == 0 ||
|
||||
|
||||
strcmp(name, "fFlags") == 0 ))
|
||||
{
|
||||
@@ -1331,6 +1333,12 @@ itemEndElementHandle(void *userData, const XML_Char *name)
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.blockironsight = (BOOLEAN) atol(pData->szCharData);
|
||||
}
|
||||
// Flugente poison system
|
||||
else if(strcmp(name, "PoisonPercentage") == 0)
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curItem.bPoisonPercentage = (INT16) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
|
||||
pData->maxReadDepth--;
|
||||
@@ -1947,6 +1955,9 @@ BOOLEAN WriteItemStats()
|
||||
|
||||
FilePrintf(hFile,"\t\t<BlockIronSight>%d</BlockIronSight>\r\n", Item[cnt].blockironsight );
|
||||
|
||||
// Flugente poison system
|
||||
FilePrintf(hFile,"\t\t<PoisonPercentage>%d</PoisonPercentage>\r\n", Item[cnt].bPoisonPercentage );
|
||||
|
||||
FilePrintf(hFile,"\t</ITEM>\r\n");
|
||||
}
|
||||
FilePrintf(hFile,"</ITEMLIST>\r\n");
|
||||
|
||||
+14
-1
@@ -2070,6 +2070,8 @@ STR16 pPersonnelRecordsHelpTexts[] =
|
||||
L"弱点:",
|
||||
|
||||
L"态度:", // WANNE: For old traits display instead of "Character:"!
|
||||
|
||||
L"Zombies: %d\n", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -2865,6 +2867,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"异形",
|
||||
L"民兵",
|
||||
L"平民",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"离开分区",
|
||||
L"确定",
|
||||
L"取消",
|
||||
@@ -2920,6 +2923,9 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Set detonation frequency (1 - 4) and defusing frequency (A - D):",
|
||||
L"Set detonation time in turns (1 - 4) and defusing frequency (A - D):",
|
||||
L"Select tripwire hierarchy (1 - 4) and network (A - D):",
|
||||
|
||||
// added by Flugente to display health and poisoning // TODO.Translate
|
||||
L"Health: %d/%d\n Poison: %d/%d\nEnergy: %d/%d\nMorale: %s",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
@@ -3473,6 +3479,7 @@ STR16 pMapScreenStatusStrings[] =
|
||||
L"士气",
|
||||
L"状态", // the condition of the current vehicle (its "health")
|
||||
L"油量", // the fuel level of the current vehicle (its "energy")
|
||||
L"Posion", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -5102,8 +5109,9 @@ STR16 zOptionsToggleText[] =
|
||||
L"显示脸部装备图",
|
||||
L"显示脸部装备图标",
|
||||
L"禁止光标切换", // Disable Cursor Swap
|
||||
L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate
|
||||
L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate
|
||||
L"自动加速敌军回合", // Automatic fast forward through AI turns
|
||||
L"Allow Zombies", // TODO.Translate
|
||||
//L"武器过热",
|
||||
L"--作弊模式选项--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"强制 Bobby Ray 送货", // force all pending Bobby Ray shipments
|
||||
@@ -5213,6 +5221,7 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"打开时,在交换位置和其它动作时光标不切换。键入 |x 可以快速切换。",
|
||||
L"When ON, mercs will not report progress during training.", //TODO.Translate
|
||||
L"打开时,敌军回合将被大幅加速。",
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
//L"打开时,武器连续射击时温度逐渐升高引起过热。",
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"强制 Bobby Ray 出货",
|
||||
@@ -6924,6 +6933,7 @@ STR16 szUDBGenAmmoStatsTooltipText[]=
|
||||
L"|翻|搅|力|(|开|花|弹|)",
|
||||
L"|爆|炸|力|(|炸|子|儿|)",
|
||||
L"|过|热|修|正",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
@@ -6932,6 +6942,7 @@ STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
L"\n \n该值决定子弹打穿护甲击中身体时的伤害力\n加成。\n \n该值大于1时,子弹在穿过护甲后会增加伤害。\n \n当该值小于1时,子弹穿过护甲后会减少伤害。\n \n该数值越高越好。",
|
||||
L"\n \n该值是子弹在击中目标前已经造成的潜在伤害的倍率。\n \n大于1的数值可以增加伤害,\n反之则减少伤害。\n \n该数值越高越好。",
|
||||
L"\n \n子弹温度系数。\n \n该数值越低越好。",
|
||||
L"\n \nDetermines what percentage of a\nbullet's damage will be poisonous.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenExplosiveStatsTooltipText[]=
|
||||
@@ -7108,6 +7119,7 @@ STR16 szUDBAdvStatsTooltipText[]=
|
||||
L"|冷|却|参|数",
|
||||
L"|卡|壳|阈|值",
|
||||
L"|损|坏|阈|值",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
// Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular.
|
||||
@@ -7169,6 +7181,7 @@ STR16 szUDBAdvStatsExplanationsTooltipText[]=
|
||||
L"\n \n武器的冷却系数数增加了(百分比)。\n \n该数值越高越好。",
|
||||
L"\n \n武器的卡壳阈值增加了(百分比)。\n \n该数值越高越好。",
|
||||
L"\n \n武器的损坏阈值增加了(百分比)。\n \n该数值越高越好。",
|
||||
L"\n \nThis is the percentage of damage dealt\nby this item that will be poisonous.\n\nUsefulness depends on wether enemy\nhas poison resistance or absorption.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[]=
|
||||
|
||||
@@ -2066,6 +2066,8 @@ STR16 pPersonnelRecordsHelpTexts[] =
|
||||
L"Weakness:",
|
||||
|
||||
L"Attitudes:", // WANNE: For old traits display instead of "Character:"!
|
||||
|
||||
L"Zombies: %d\n", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -2862,6 +2864,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"CREPITUS", // L"CREPITUS",
|
||||
L"MILITIE", // L"MILITIA",
|
||||
L"BURGER", // L"CIVILIAN",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"Verlaten Sector", // L"Exiting Sector",
|
||||
L"OK",
|
||||
L"Stoppen", // L"Cancel",
|
||||
@@ -2917,6 +2920,9 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Set detonation frequency (1 - 4) and defusing frequency (A - D):",
|
||||
L"Set detonation time in turns (1 - 4) and defusing frequency (A - D):",
|
||||
L"Select tripwire hierarchy (1 - 4) and network (A - D):",
|
||||
|
||||
// added by Flugente to display health and poisoning // TODO.Translate
|
||||
L"Health: %d/%d\n Poison: %d/%d\nEnergy: %d/%d\nMorale: %s",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
@@ -3469,6 +3475,7 @@ STR16 pMapScreenStatusStrings[] =
|
||||
L"Moraal",
|
||||
L"Conditie", // the condition of the current vehicle (its "health")
|
||||
L"Brandstof", // the fuel level of the current vehicle (its "energy")
|
||||
L"Posion", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -5103,6 +5110,7 @@ STR16 zOptionsToggleText[] =
|
||||
L"Uit te schakelen Cursor Swap", // Disable Cursor Swap
|
||||
L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
L"Allow Zombies", // TODO.Translate
|
||||
//L"Weapons Overheating", // TODO.Translate
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments
|
||||
@@ -5212,6 +5220,7 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"Wanneer ingeschakeld, zal de cursor niet te schakelen tussen uitwisseling positie en andere acties. Druk op |x om snelle uitwisseling te starten.",
|
||||
L"When ON, mercs will not report progress during training.", //TODO.Translate
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
//L"When ON, weapons can be overheated when firing.", // TODO.Translate
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Force all pending Bobby Ray shipments",
|
||||
@@ -6919,6 +6928,7 @@ STR16 szUDBGenAmmoStatsTooltipText[]=
|
||||
L"|B|u|l|l|e|t |T|u|m|b|l|e",
|
||||
L"|P|r|e|-|I|m|p|a|c|t |E|x|p|l|o|s|i|o|n",
|
||||
L"|T|e|m|p|e|r|a|t|u|r|e |M|o|d|i|f|i|c|a|t|i|o|n", // TODO.Translate
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
@@ -6927,6 +6937,7 @@ STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
L"\n \nDetermines a proportional increase of damage\npotential once the bullet gets through the\ntarget's armor and hits the bodypart behind it.\n \nWhen above 1.0, the bullet's damage\nincreases after penetrating the armor.\n \nWhen below 1.0, the bullet's damage\npotential decreases after passing through armor.\n \nHigher is better.",
|
||||
L"\n \nA multiplier to the bullet's damage potential\nthat is applied immediately before hitting the\ntarget.\n \nValues above 1.0 indicate an increase in damage,\nvalues below 1.0 indicate a decrease.\n \nHigher is better.",
|
||||
L"\n \nAdditional heat generated by this ammunition.\n \nLower is better.", // TODO.Translate
|
||||
L"\n \nDetermines what percentage of a\nbullet's damage will be poisonous.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenExplosiveStatsTooltipText[]=
|
||||
@@ -7103,6 +7114,7 @@ STR16 szUDBAdvStatsTooltipText[]=
|
||||
L"|C|o|o|l|d|o|w|n |M|o|d|i|f|i|e|r",
|
||||
L"|J|a|m |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|D|a|m|a|g|e |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
// Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular.
|
||||
@@ -7164,6 +7176,7 @@ STR16 szUDBAdvStatsExplanationsTooltipText[]=
|
||||
L"\n \nA gun's cooldown factor is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's jam threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's damage threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nThis is the percentage of damage dealt\nby this item that will be poisonous.\n\nUsefulness depends on wether enemy\nhas poison resistance or absorption.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[]=
|
||||
|
||||
+15
-3
@@ -2070,6 +2070,8 @@ STR16 pPersonnelRecordsHelpTexts[] =
|
||||
L"Weakness:",
|
||||
|
||||
L"Attitudes:", // WANNE: For old traits display instead of "Character:"!
|
||||
|
||||
L"Zombies: %d\n", // Flugente Zombies
|
||||
};
|
||||
|
||||
|
||||
@@ -2865,6 +2867,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"CREPITUS",
|
||||
L"MILITIA",
|
||||
L"CIVILIAN",
|
||||
L"ZOMBIE",
|
||||
L"Exiting Sector",
|
||||
L"OK",
|
||||
L"Cancel",
|
||||
@@ -2920,6 +2923,9 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Set detonation frequency (1 - 4) and defusing frequency (A - D):",
|
||||
L"Set detonation time in turns (1 - 4) and defusing frequency (A - D):",
|
||||
L"Select tripwire hierarchy (1 - 4) and network (A - D):",
|
||||
|
||||
// added by Flugente to display health and poisoning
|
||||
L"Health: %d/%d\n Poison: %d/%d\nEnergy: %d/%d\nMorale: %s",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
@@ -3471,6 +3477,7 @@ STR16 pMapScreenStatusStrings[] =
|
||||
L"Morale",
|
||||
L"Condition", // the condition of the current vehicle (its "health")
|
||||
L"Fuel", // the fuel level of the current vehicle (its "energy")
|
||||
L"Poison", // for display of poisoning
|
||||
};
|
||||
|
||||
|
||||
@@ -5102,6 +5109,7 @@ STR16 zOptionsToggleText[] =
|
||||
L"Disable Cursor Swap", // Disable Cursor Swap
|
||||
L"Quiet Training", // Madd: mercs don't say quotes while training
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
//L"Weapons Overheating", // TODO.Translate
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments
|
||||
@@ -5113,7 +5121,7 @@ STR16 zOptionsToggleText[] =
|
||||
L"Debug Options in other builds", // allow debugging in release or mapeditor
|
||||
L"DEBUG Render Option group", // an example option that will show/hide other options
|
||||
L"Render Mouse Regions", // an example of a DEBUG build option
|
||||
L"-----------------", // an example options screen options divider (pure text)
|
||||
L"-----------------", // an example options screen options divider (pure text)
|
||||
|
||||
// this is THE LAST option that exists (debug the options screen, doesnt do anything, except exist)
|
||||
L"THE_LAST_OPTION",
|
||||
@@ -5211,6 +5219,7 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, the cursor will not toggle between exchange position and other actions. Press |x to initiate quick exchange.",
|
||||
L"When ON, mercs will not report progress during training.",
|
||||
L"When ON, AI turns will be much faster.",
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies
|
||||
//L"When ON, weapons can be overheated when firing.", // TODO.Translate
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Force all pending Bobby Ray shipments",
|
||||
@@ -5222,8 +5231,7 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"Allows debug options in release or mapeditor builds", // allow debugging in release or mapeditor
|
||||
L"Toggle to display debugging render options", // an example option that will show/hide other options
|
||||
L"Attempts to display slash-rects around mouse regions", // an example of a DEBUG build option
|
||||
L"(text not rendered)TOPTION_DEBUG_MODE_OPTIONS_END", // an example options screen options divider (pure text)
|
||||
|
||||
L"(text not rendered)TOPTION_DEBUG_MODE_OPTIONS_END", // an example options screen options divider (pure text)
|
||||
|
||||
// this is THE LAST option that exists (debug the options screen, doesnt do anything, except exist)
|
||||
L"TOPTION_LAST_OPTION",
|
||||
@@ -6911,6 +6919,7 @@ STR16 szUDBGenAmmoStatsTooltipText[]=
|
||||
L"|B|u|l|l|e|t |T|u|m|b|l|e",
|
||||
L"|P|r|e|-|I|m|p|a|c|t |E|x|p|l|o|s|i|o|n",
|
||||
L"|T|e|m|p|e|r|a|t|u|r|e |M|o|d|i|f|i|c|a|t|i|o|n",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e",
|
||||
};
|
||||
|
||||
STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
@@ -6919,6 +6928,7 @@ STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
L"\n \nDetermines a proportional increase of damage\npotential once the bullet gets through the\ntarget's armor and hits the bodypart behind it.\n \nWhen above 1.0, the bullet's damage\nincreases after penetrating the armor.\n \nWhen below 1.0, the bullet's damage\npotential decreases after passing through armor.\n \nHigher is better.",
|
||||
L"\n \nA multiplier to the bullet's damage potential\nthat is applied immediately before hitting the\ntarget.\n \nValues above 1.0 indicate an increase in damage,\nvalues below 1.0 indicate a decrease.\n \nHigher is better.",
|
||||
L"\n \nAdditional heat generated by this ammunition.\n \nLower is better.",
|
||||
L"\n \nDetermines what percentage of a\nbullet's damage will be poisonous.",
|
||||
};
|
||||
|
||||
STR16 szUDBGenExplosiveStatsTooltipText[]=
|
||||
@@ -7096,6 +7106,7 @@ STR16 szUDBAdvStatsTooltipText[]=
|
||||
L"|C|o|o|l|d|o|w|n |M|o|d|i|f|i|e|r",
|
||||
L"|J|a|m |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|D|a|m|a|g|e |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e",
|
||||
};
|
||||
|
||||
// Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular.
|
||||
@@ -7157,6 +7168,7 @@ STR16 szUDBAdvStatsExplanationsTooltipText[]=
|
||||
L"\n \nA gun's cooldown factor is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's jam threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's damage threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nThis is the percentage of damage dealt\nby this item that will be poisonous.\n\nUsefulness depends on wether enemy\nhas poison resistance or absorption.",
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[]=
|
||||
|
||||
@@ -2069,6 +2069,8 @@ STR16 pPersonnelRecordsHelpTexts[] =
|
||||
L"Faiblesse :",
|
||||
|
||||
L"Attitudes :", // WANNE: For old traits display instead of "Character:"!
|
||||
|
||||
L"Zombies: %d\n", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -2864,6 +2866,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"CREPITUS",
|
||||
L"Milice",
|
||||
L"CIVIL",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"Quitter Secteur",
|
||||
L"OK",
|
||||
L"Annuler",
|
||||
@@ -2919,6 +2922,9 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Set detonation frequency (1 - 4) and defusing frequency (A - D):",
|
||||
L"Set detonation time in turns (1 - 4) and defusing frequency (A - D):",
|
||||
L"Select tripwire hierarchy (1 - 4) and network (A - D):",
|
||||
|
||||
// added by Flugente to display health and poisoning // TODO.Translate
|
||||
L"Health: %d/%d\n Poison: %d/%d\nEnergy: %d/%d\nMorale: %s",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
@@ -3473,6 +3479,7 @@ STR16 pMapScreenStatusStrings[] =
|
||||
L"Moral",
|
||||
L"Etat", // the condition of the current vehicle (its "Santé")
|
||||
L"Carburant", // the fuel level of the current vehicle (its "energy")
|
||||
L"Posion", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -5093,6 +5100,7 @@ STR16 zOptionsToggleText[] =
|
||||
L"Désactiver échange curseur", // Disable Cursor Swap
|
||||
L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
//L"Weapons Overheating", // TODO.Translate
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Forcer envois Bobby Ray", // force all pending Bobby Ray shipments
|
||||
@@ -5202,6 +5210,7 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"Si activé, le curseur ne basculera pas entre changer de position et une autre action. Appuyez sur |x pour initier un échange rapide.",
|
||||
L"When ON, mercs will not report progress during training.",
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
//L"When ON, weapons can be overheated when firing.", // TODO.Translate
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Forcer tous les envois en attente de Bobby Ray",
|
||||
@@ -6894,6 +6903,7 @@ STR16 szUDBGenAmmoStatsTooltipText[]=
|
||||
L"|C|u|l|b|u|t|e |d|e |b|a|l|l|e",
|
||||
L"|P|r|e|-|I|m|p|a|c|t |E|x|p|l|o|s|i|o|n",
|
||||
L"|T|e|m|p|e|r|a|t|u|r|e |M|o|d|i|f|i|c|a|t|i|o|n", // TODO.Translate
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
@@ -6902,6 +6912,7 @@ STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
L"\n \nDétermine le potentiel de la balle à faire des dégâts\nsur le corps après avoir traversée l'armure.\n \nAvec une valeur supérieure à 1.0, la balle fera de lourds dégâts\naprès pénétration\nAvec une valeur inférieure à 1.0, la balle fera des dégâts moindre\naprès pénétration.\n \nValeur élevée recommandée.",
|
||||
L"\n \nMultiplicateur de potentiel de dégâts juste avant\nl'impact de la balle.\n \nAvec une valeur supérieure à 1.0, la balle fera de lourds dégâts\nUne valeur inférieure à 1.0 fera des dégâts moindre.\n \nValeur élevée recommandée.",
|
||||
L"\n \nAdditional heat generated by this ammunition.\n \nLower is better.", // TODO.Translate
|
||||
L"\n \nDetermines what percentage of a\nbullet's damage will be poisonous.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenExplosiveStatsTooltipText[]=
|
||||
@@ -7078,6 +7089,7 @@ STR16 szUDBAdvStatsTooltipText[]=
|
||||
L"|C|o|o|l|d|o|w|n |M|o|d|i|f|i|e|r",
|
||||
L"|J|a|m |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|D|a|m|a|g|e |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
// Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular.
|
||||
@@ -7139,6 +7151,7 @@ STR16 szUDBAdvStatsExplanationsTooltipText[]=
|
||||
L"\n \nA gun's cooldown factor is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's jam threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's damage threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nThis is the percentage of damage dealt\nby this item that will be poisonous.\n\nUsefulness depends on wether enemy\nhas poison resistance or absorption.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[]=
|
||||
|
||||
@@ -2080,6 +2080,8 @@ STR16 pPersonnelRecordsHelpTexts[] =
|
||||
L"Schwächen:",
|
||||
|
||||
L"Persönlichkeit:", // WANNE: For old traits display instead of "Character:"!
|
||||
|
||||
L"Zombies: %d\n", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -2866,6 +2868,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"MONSTER",
|
||||
L"MILIZ",
|
||||
L"ZIVILIST",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"Sektor verlassen",
|
||||
L"OK",
|
||||
L"Abbruch",
|
||||
@@ -2923,6 +2926,9 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Detonations-Frequenz (1 - 4) und die Entschärfungs-Frequenz (A - D):",
|
||||
L"Detonations-Zeit (in Züge) (1 - 4) und die Entschärfungs-Frequenz (A - D):",
|
||||
L"Stolperdraht-Hierarchie (1 - 4) und das Netzwerk (A - D):",
|
||||
|
||||
// added by Flugente to display health and poisoning // TODO.Translate
|
||||
L"Health: %d/%d\n Poison: %d/%d\nEnergy: %d/%d\nMorale: %s",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
@@ -3440,6 +3446,7 @@ STR16 pMapScreenStatusStrings[] =
|
||||
L"Moral",
|
||||
L"Zustand", // the condition of the current vehicle (its "health")
|
||||
L"Tank", // the fuel level of the current vehicle (its "energy")
|
||||
L"Posion", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 pMapScreenPrevNextCharButtonHelpText[] =
|
||||
@@ -4951,6 +4958,7 @@ STR16 zOptionsToggleText[] =
|
||||
L"Cursor-Wechsel deaktivieren", // Disable Cursor Swap
|
||||
L"Stummes Trainieren", // Madd: mercs don't say quotes while training
|
||||
L"Autom. schnelle Gegner-Züge", // Automatic fast forward through AI turns
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
//L"Waffen können überhitzen",
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Erzwinge BR Lieferung", // force all pending Bobby Ray shipments
|
||||
@@ -6739,6 +6747,7 @@ STR16 szUDBGenAmmoStatsTooltipText[]=
|
||||
L"|K|u|g|e|l|s|t|u|r|z",
|
||||
L"|E|x|p|l|o|s|i|o|n |v|o|r |E|i|n|s|c|h|l|a|g",
|
||||
L"|T|e|m|p|e|r|a|t|u|r |M|o|d|i|f|i|k|a|t|o|r",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
@@ -6747,6 +6756,7 @@ STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
L"\n \nBestimmt eine verhältnismäßige Zunahme des Schadenspotentials,\nsobald die Kugel die Rüstung des Ziels\ndurchbricht und den Körper dahinter trifft.\n \nWerte über 1.0 erhöhen, Werte unter 1.0 reduzieren das Schadenspotential\nder durchbrochenen Kugel.\n \nHöher ist besser.",
|
||||
L"\n \nEin Multiplikator zum Schadenspotential der Kugel,\nder vor dem Treffen des Zieles angewandt wird.\n \nWerte über 1.0 erhöhen, Werte unter 1.0 reduzieren den Schaden.\n \nHöher ist besser.",
|
||||
L"\n \nProzentuale zusätzliche Hitze\ndurch diese Munitionsart.\n \nNiedriger ist besser.",
|
||||
L"\n \nDetermines what percentage of a\nbullet's damage will be poisonous.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenExplosiveStatsTooltipText[]=
|
||||
@@ -6923,6 +6933,7 @@ STR16 szUDBAdvStatsTooltipText[]=
|
||||
L"|M|o|d|i|f|i|k|a|t|o|r|-|A|b|k|ü|h|l|f|a|k|t|o|r",
|
||||
L"|M|o|d|i|f|i|k|a|t|o|r|-|L|a|d|e|h|e|m|m|u|n|g|s|s|c|h|r|a|n|k|e",
|
||||
L"|M|o|d|i|f|i|k|a|t|o|r|-|H|i|t|z|e|s|c|h|a|d|e|n|s|s|c|h|r|a|n|k|e",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
// Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular.
|
||||
@@ -6984,6 +6995,7 @@ STR16 szUDBAdvStatsExplanationsTooltipText[]=
|
||||
L"\n \nAbkühlung wird um diesen Prozentsatz erhöht.\n \nHöher ist besser.",
|
||||
L"\n \nLadehemmungsschranke wird um diesen Prozentsatz erhöht.\n \nHöher ist besser.",
|
||||
L"\n \nHitzeschadensschranke wird um diesen Prozentsatz erhöht.\n \nHöher is besser.",
|
||||
L"\n \nThis is the percentage of damage dealt\nby this item that will be poisonous.\n\nUsefulness depends on wether enemy\nhas poison resistance or absorption.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[]=
|
||||
|
||||
@@ -2062,6 +2062,8 @@ STR16 pPersonnelRecordsHelpTexts[] =
|
||||
L"Weakness:",
|
||||
|
||||
L"Attitudes:", // WANNE: For old traits display instead of "Character:"!
|
||||
|
||||
L"Zombies: %d\n", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -2857,6 +2859,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"CREPITUS",
|
||||
L"ESERCITO",
|
||||
L"CIVILE",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"Settore di uscita",
|
||||
L"OK",
|
||||
L"Annulla",
|
||||
@@ -2912,6 +2915,9 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Set detonation frequency (1 - 4) and defusing frequency (A - D):",
|
||||
L"Set detonation time in turns (1 - 4) and defusing frequency (A - D):",
|
||||
L"Select tripwire hierarchy (1 - 4) and network (A - D):",
|
||||
|
||||
// added by Flugente to display health and poisoning // TODO.Translate
|
||||
L"Health: %d/%d\n Poison: %d/%d\nEnergy: %d/%d\nMorale: %s",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
@@ -3464,6 +3470,7 @@ STR16 pMapScreenStatusStrings[] =
|
||||
L"Morale",
|
||||
L"Condizione", // the condition of the current vehicle (its "health")
|
||||
L"Carburante", // the fuel level of the current vehicle (its "energy")
|
||||
L"Posion", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -5088,6 +5095,7 @@ STR16 zOptionsToggleText[] =
|
||||
L"Disabilita Swap Cursore", // Disable Cursor Swap
|
||||
L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
//L"Weapons Overheating", // TODO.Translate
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments
|
||||
@@ -5197,6 +5205,7 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"Se attivato, il cursore non si alternerà tra la posizione di scambio e altre azioni. Premere |x per avviare lo scambio rapido.",
|
||||
L"When ON, mercs will not report progress during training.",
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
//L"When ON, weapons can be overheated when firing.", // TODO.Translate
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Force all pending Bobby Ray shipments",
|
||||
@@ -6907,6 +6916,7 @@ STR16 szUDBGenAmmoStatsTooltipText[]=
|
||||
L"|B|u|l|l|e|t |T|u|m|b|l|e",
|
||||
L"|P|r|e|-|I|m|p|a|c|t |E|x|p|l|o|s|i|o|n",
|
||||
L"|T|e|m|p|e|r|a|t|u|r|e |M|o|d|i|f|i|c|a|t|i|o|n", // TODO.Translate
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
@@ -6915,6 +6925,7 @@ STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
L"\n \nDetermines a proportional increase of damage\npotential once the bullet gets through the\ntarget's armor and hits the bodypart behind it.\n \nWhen above 1.0, the bullet's damage\nincreases after penetrating the armor.\n \nWhen below 1.0, the bullet's damage\npotential decreases after passing through armor.\n \nHigher is better.",
|
||||
L"\n \nA multiplier to the bullet's damage potential\nthat is applied immediately before hitting the\ntarget.\n \nValues above 1.0 indicate an increase in damage,\nvalues below 1.0 indicate a decrease.\n \nHigher is better.",
|
||||
L"\n \nAdditional heat generated by this ammunition.\n \nLower is better.", // TODO.Translate
|
||||
L"\n \nDetermines what percentage of a\nbullet's damage will be poisonous.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenExplosiveStatsTooltipText[]=
|
||||
@@ -7091,6 +7102,7 @@ STR16 szUDBAdvStatsTooltipText[]=
|
||||
L"|C|o|o|l|d|o|w|n |M|o|d|i|f|i|e|r",
|
||||
L"|J|a|m |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|D|a|m|a|g|e |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
// Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular.
|
||||
@@ -7152,6 +7164,7 @@ STR16 szUDBAdvStatsExplanationsTooltipText[]=
|
||||
L"\n \nA gun's cooldown factor is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's jam threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's damage threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nThis is the percentage of damage dealt\nby this item that will be poisonous.\n\nUsefulness depends on wether enemy\nhas poison resistance or absorption.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[]=
|
||||
|
||||
@@ -2077,6 +2077,8 @@ STR16 pPersonnelRecordsHelpTexts[] =
|
||||
L"NiepełnosprawnoŚć:",
|
||||
|
||||
L"Attitudes:", // WANNE: For old traits display instead of "Character:"!
|
||||
|
||||
L"Zombies: %d\n", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -2872,6 +2874,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"STWÓR",
|
||||
L"SAMOOBRONA",
|
||||
L"CYWIL",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"WyjŚcie z sektora",
|
||||
L"OK",
|
||||
L"Anuluj",
|
||||
@@ -2927,6 +2930,9 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Set detonation frequency (1 - 4) and defusing frequency (A - D):",
|
||||
L"Set detonation time in turns (1 - 4) and defusing frequency (A - D):",
|
||||
L"Select tripwire hierarchy (1 - 4) and network (A - D):",
|
||||
|
||||
// added by Flugente to display health and poisoning // TODO.Translate
|
||||
L"Health: %d/%d\n Poison: %d/%d\nEnergy: %d/%d\nMorale: %s",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
@@ -3480,6 +3486,7 @@ STR16 pMapScreenStatusStrings[] =
|
||||
L"Morale",
|
||||
L"Stan", // the condition of the current vehicle (its "health")
|
||||
L"Paliwo", // the fuel level of the current vehicle (its "energy")
|
||||
L"Posion", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -5100,6 +5107,7 @@ STR16 zOptionsToggleText[] =
|
||||
L"Disable Cursor Swap", // Disable Cursor Swap // TODO.Translate
|
||||
L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
//L"Weapons Overheating", // TODO.Translate
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments
|
||||
@@ -5209,6 +5217,7 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, the cursor will not toggle between exchange position and other actions. Press |x to initiate quick exchange.", // TODO.Translate
|
||||
L"When ON, mercs will not report progress during training.",
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
//L"When ON, weapons can be overheated when firing.", // TODO.Translate
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"WymuŚ wszystkie oczekiwane dostawy od Bobby Ray's.",
|
||||
@@ -6917,6 +6926,7 @@ STR16 szUDBGenAmmoStatsTooltipText[]=
|
||||
L"|B|u|l|l|e|t |T|u|m|b|l|e",
|
||||
L"|P|r|e|-|I|m|p|a|c|t |E|x|p|l|o|s|i|o|n",
|
||||
L"|T|e|m|p|e|r|a|t|u|r|e |M|o|d|i|f|i|c|a|t|i|o|n", // TODO.Translate
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
@@ -6925,6 +6935,7 @@ STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
L"\n \nDetermines a proportional increase of damage\npotential once the bullet gets through the\ntarget's armor and hits the bodypart behind it.\n \nWhen above 1.0, the bullet's damage\nincreases after penetrating the armor.\n \nWhen below 1.0, the bullet's damage\npotential decreases after passing through armor.\n \nHigher is better.",
|
||||
L"\n \nA multiplier to the bullet's damage potential\nthat is applied immediately before hitting the\ntarget.\n \nValues above 1.0 indicate an increase in damage,\nvalues below 1.0 indicate a decrease.\n \nHigher is better.",
|
||||
L"\n \nAdditional heat generated by this ammunition.\n \nLower is better.", // TODO.Translate
|
||||
L"\n \nDetermines what percentage of a\nbullet's damage will be poisonous.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenExplosiveStatsTooltipText[]=
|
||||
@@ -7101,6 +7112,7 @@ STR16 szUDBAdvStatsTooltipText[]=
|
||||
L"|C|o|o|l|d|o|w|n |M|o|d|i|f|i|e|r",
|
||||
L"|J|a|m |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|D|a|m|a|g|e |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
// Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular.
|
||||
@@ -7162,6 +7174,7 @@ STR16 szUDBAdvStatsExplanationsTooltipText[]=
|
||||
L"\n \nA gun's cooldown factor is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's jam threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's damage threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nThis is the percentage of damage dealt\nby this item that will be poisonous.\n\nUsefulness depends on wether enemy\nhas poison resistance or absorption.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[]=
|
||||
|
||||
@@ -2070,6 +2070,8 @@ STR16 pPersonnelRecordsHelpTexts[] =
|
||||
L"Недостаток:",
|
||||
|
||||
L"По жизни:", //Attitudes For old traits display instead of "Character:"!
|
||||
|
||||
L"Zombies: %d\n", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -2865,6 +2867,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"РЕПТИОН",
|
||||
L"ОПОЛЧЕНЕЦ",
|
||||
L"ЖИТЕЛЬ",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"Выход из сектора",
|
||||
L"ДА",
|
||||
L"ОТМЕНА",
|
||||
@@ -2920,6 +2923,9 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Set detonation frequency (1 - 4) and defusing frequency (A - D):",
|
||||
L"Set detonation time in turns (1 - 4) and defusing frequency (A - D):",
|
||||
L"Select tripwire hierarchy (1 - 4) and network (A - D):",
|
||||
|
||||
// added by Flugente to display health and poisoning // TODO.Translate
|
||||
L"Health: %d/%d\n Poison: %d/%d\nEnergy: %d/%d\nMorale: %s",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
@@ -3473,6 +3479,7 @@ STR16 pMapScreenStatusStrings[] =
|
||||
L"Боевой дух",
|
||||
L"Состояние", // the condition of the current vehicle (its "health")
|
||||
L"Бензин", // the fuel level of the current vehicle (its "energy")
|
||||
L"Posion", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -5083,6 +5090,7 @@ STR16 zOptionsToggleText[] =
|
||||
L"Disable Cursor Swap", // Disable Cursor Swap // TODO.Translate
|
||||
L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
//L"Weapons Overheating", // TODO.Translate
|
||||
L"--Читерские настройки--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Ускорить доставку Бобби Рэя", // force all pending Bobby Ray shipments
|
||||
@@ -5192,6 +5200,7 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, the cursor will not toggle between exchange position and other actions. Press |x to initiate quick exchange.", // TODO.Translate
|
||||
L"When ON, mercs will not report progress during training.",
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
//L"When ON, weapons can be overheated when firing.", // TODO.Translate
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Выберите этот пункт чтобы груз Бобби Рэя прибыл немедленно.",
|
||||
@@ -6885,6 +6894,7 @@ STR16 szUDBGenAmmoStatsTooltipText[]=
|
||||
L"|П|а|д|е|н|и|е |п|а|т|р|о|н|ы",
|
||||
L"|П|р|е|д|в|а|р|и|т|е|л|ь|н|о|е |в|л|и|я|н|и|е |в|з|р|ы|в|а",
|
||||
L"|T|e|m|p|e|r|a|t|u|r|e |M|o|d|i|f|i|c|a|t|i|o|n", // TODO.Translate
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
@@ -6893,6 +6903,7 @@ STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
L"\n \nDetermines a proportional increase of damage\npotential once the bullet gets through the\ntarget's armor and hits the bodypart behind it.\n \nWhen above 1.0, the bullet's damage\nincreases after penetrating the armor.\n \nWhen below 1.0, the bullet's damage\npotential decreases after passing through armor.\n \nHigher is better.",
|
||||
L"\n \nA multiplier to the bullet's damage potential\nthat is applied immediately before hitting the\ntarget.\n \nValues above 1.0 indicate an increase in damage,\nvalues below 1.0 indicate a decrease.\n \nHigher is better.",
|
||||
L"\n \nAdditional heat generated by this ammunition.\n \nLower is better.", // TODO.Translate
|
||||
L"\n \nDetermines what percentage of a\nbullet's damage will be poisonous.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenExplosiveStatsTooltipText[]=
|
||||
@@ -7069,6 +7080,7 @@ STR16 szUDBAdvStatsTooltipText[]=
|
||||
L"|C|o|o|l|d|o|w|n |M|o|d|i|f|i|e|r",
|
||||
L"|J|a|m |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|D|a|m|a|g|e |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
// Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular.
|
||||
@@ -7130,6 +7142,7 @@ STR16 szUDBAdvStatsExplanationsTooltipText[]=
|
||||
L"\n \nA gun's cooldown factor is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's jam threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's damage threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nThis is the percentage of damage dealt\nby this item that will be poisonous.\n\nUsefulness depends on wether enemy\nhas poison resistance or absorption.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[]=
|
||||
|
||||
@@ -2070,6 +2070,8 @@ STR16 pPersonnelRecordsHelpTexts[] =
|
||||
L"Weakness:",
|
||||
|
||||
L"Attitudes:", // WANNE: For old traits display instead of "Character:"!
|
||||
|
||||
L"Zombies: %d\n", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -2866,6 +2868,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"CREPITUS",
|
||||
L"MILITIA",
|
||||
L"CIVILIAN",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"Exiting Sector",
|
||||
L"OK",
|
||||
L"Cancel",
|
||||
@@ -2921,6 +2924,9 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Set detonation frequency (1 - 4) and defusing frequency (A - D):",
|
||||
L"Set detonation time in turns (1 - 4) and defusing frequency (A - D):",
|
||||
L"Select tripwire hierarchy (1 - 4) and network (A - D):",
|
||||
|
||||
// added by Flugente to display health and poisoning // TODO.Translate
|
||||
L"Health: %d/%d\n Poison: %d/%d\nEnergy: %d/%d\nMorale: %s",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
@@ -3474,6 +3480,7 @@ STR16 pMapScreenStatusStrings[] =
|
||||
L"Morale",
|
||||
L"Condition", // the condition of the current vehicle (its "health")
|
||||
L"Fuel", // the fuel level of the current vehicle (its "energy")
|
||||
L"Posion", // TODO.Translate
|
||||
};
|
||||
|
||||
|
||||
@@ -5104,6 +5111,7 @@ STR16 zOptionsToggleText[] =
|
||||
L"Disable Cursor Swap", // Disable Cursor Swap
|
||||
L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
//L"Weapons Overheating", // TODO.Translate
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments
|
||||
@@ -5213,6 +5221,7 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, the cursor will not toggle between exchange position and other actions. Press |x to initiate quick exchange.",
|
||||
L"When ON, mercs will not report progress during training.",
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
//L"When ON, weapons can be overheated when firing.", // TODO.Translate
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Force all pending Bobby Ray shipments",
|
||||
@@ -6922,6 +6931,7 @@ STR16 szUDBGenAmmoStatsTooltipText[]=
|
||||
L"|B|u|l|l|e|t |T|u|m|b|l|e",
|
||||
L"|P|r|e|-|I|m|p|a|c|t |E|x|p|l|o|s|i|o|n",
|
||||
L"|T|e|m|p|e|r|a|t|u|r|e |M|o|d|i|f|i|c|a|t|i|o|n", // TODO.Translate
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
@@ -6930,6 +6940,7 @@ STR16 szUDBGenAmmoStatsExplanationsTooltipText[]=
|
||||
L"\n \nDetermines a proportional increase of damage\npotential once the bullet gets through the\ntarget's armor and hits the bodypart behind it.\n \nWhen above 1.0, the bullet's damage\nincreases after penetrating the armor.\n \nWhen below 1.0, the bullet's damage\npotential decreases after passing through armor.\n \nHigher is better.",
|
||||
L"\n \nA multiplier to the bullet's damage potential\nthat is applied immediately before hitting the\ntarget.\n \nValues above 1.0 indicate an increase in damage,\nvalues below 1.0 indicate a decrease.\n \nHigher is better.",
|
||||
L"\n \nAdditional heat generated by this ammunition.\n \nLower is better.", // TODO.Translate
|
||||
L"\n \nDetermines what percentage of a\nbullet's damage will be poisonous.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBGenExplosiveStatsTooltipText[]=
|
||||
@@ -7106,6 +7117,7 @@ STR16 szUDBAdvStatsTooltipText[]=
|
||||
L"|C|o|o|l|d|o|w|n |M|o|d|i|f|i|e|r",
|
||||
L"|J|a|m |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|D|a|m|a|g|e |T|h|r|e|s|h|o|l|d |M|o|d|i|f|i|e|r",
|
||||
L"|P|o|i|s|o|n |P|e|r|c|e|n|t|a|g|e", // TODO.Translate
|
||||
};
|
||||
|
||||
// Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular.
|
||||
@@ -7167,6 +7179,7 @@ STR16 szUDBAdvStatsExplanationsTooltipText[]=
|
||||
L"\n \nA gun's cooldown factor is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's jam threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nA gun's damage threshold is\nincreased by this percentage.\n \nHigher is better.",
|
||||
L"\n \nThis is the percentage of damage dealt\nby this item that will be poisonous.\n\nUsefulness depends on wether enemy\nhas poison resistance or absorption.", // TODO.Translate
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[]=
|
||||
|
||||
Reference in New Issue
Block a user