New Feature: Drug System Overhaul. The drug system has been completely overhauled.

Requires GameDir >= r2257.

For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=msg&goto=341541&#msg_341541

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7896 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2015-06-28 17:47:25 +00:00
parent ceea35b0e9
commit 4d9140da57
61 changed files with 1667 additions and 871 deletions
-2
View File
@@ -3543,8 +3543,6 @@ void LoadMoraleSettings()
gMoraleSettings.bModifiers[MORALE_MOD_MAX] = iniReader.ReadInteger("Morale Modifiers Settings","MORALE_MOD_MAX", -1, 0, 100);
gMoraleSettings.sDrugAndAlcoholModifiers[DRUG_EFFECT_MORALE_MOD] = iniReader.ReadInteger("Morale Modifiers Settings","DRUG_EFFECT_MORALE_MOD", 150, 0, 10000);
gMoraleSettings.sDrugAndAlcoholModifiers[ALCOHOL_EFFECT_MORALE_MOD] = iniReader.ReadInteger("Morale Modifiers Settings","ALCOHOL_EFFECT_MORALE_MOD", 160, 0, 10000);
gMoraleSettings.bModifiers[PHOBIC_LIMIT] = iniReader.ReadInteger("Morale Modifiers Settings","PHOBIC_LIMIT", 20, 0, 100);
gMoraleSettings.bModifiers[MORALE_MODIFIER_SOCIABLE_ONE_MERC_NEARBY] = iniReader.ReadInteger("Morale Modifiers Settings","MORALE_MODIFIER_SOCIABLE_ONE_MERC_NEARBY", -2, -100, 100);
-1
View File
@@ -1510,7 +1510,6 @@ typedef struct
UINT8 ubHoursBetweenStrategicDelay;
INT8 bValues[64];
INT8 bModifiers[32];
INT16 sDrugAndAlcoholModifiers[2];
} MORALE_SETTINGS;
typedef struct
+9 -9
View File
@@ -15,9 +15,9 @@
#ifdef JA2EDITOR
#ifdef JA2UB
CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.7889 (Development Build)" };
CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.7896 (Development Build)" };
#else
CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.7889 (Development Build)" };
CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.7896 (Development Build)" };
#endif
// ------------------------------
@@ -27,11 +27,11 @@
//DEBUG BUILD VERSION
#ifdef JA2UB
CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.7889 (Development Build)" };
CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.7896 (Development Build)" };
#elif defined (JA113DEMO)
CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.7889 (Development Build)" };
CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.7896 (Development Build)" };
#else
CHAR16 zVersionLabel[256] = { L"Debug: v1.13.7889 (Development Build)" };
CHAR16 zVersionLabel[256] = { L"Debug: v1.13.7896 (Development Build)" };
#endif
#elif defined CRIPPLED_VERSION
@@ -46,16 +46,16 @@
//RELEASE BUILD VERSION
#ifdef JA2UB
CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.7889 (Development Build)" };
CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.7896 (Development Build)" };
#elif defined (JA113DEMO)
CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.7889 (Development Build)" };
CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.7896 (Development Build)" };
#else
CHAR16 zVersionLabel[256] = { L"Release v1.13.7889 (Development Build)" };
CHAR16 zVersionLabel[256] = { L"Release v1.13.7896 (Development Build)" };
#endif
#endif
CHAR8 czVersionNumber[16] = { "Build 15.06.13" }; //YY.MM.DD
CHAR8 czVersionNumber[16] = { "Build 15.06.28" }; //YY.MM.DD
CHAR16 zTrackingNumber[16] = { L"Z" };
// SAVE_GAME_VERSION is defined in header, change it there
+2 -1
View File
@@ -21,6 +21,7 @@ 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 DRUG_SYSTEM_REDONE 163 // Flugente: reworked the drug system
#define MILITIA_PATH_PLOTTING 162 // Flugente: the player can plot militia paths in strategic, similar to player or helicopter travel
#define STRATEGIC_TEAM_GROUPS 161 // Flugente: a change to the GROUP-structure allows any team to have strategic movement groups
#define PMC_WEBSITE 160 // Flugente: a new PMC allows us to hire trained militia
@@ -81,7 +82,7 @@ extern CHAR16 zTrackingNumber[16];
#define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes
#define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system
#define SAVE_GAME_VERSION MILITIA_PATH_PLOTTING
#define SAVE_GAME_VERSION DRUG_SYSTEM_REDONE
//#define RUSSIANGOLD
#ifdef __cplusplus
+18 -3
View File
@@ -492,23 +492,38 @@ void AssignBackgroundHelpText( UINT16 ubNumber, MOUSE_REGION* pMouseregion )
}
}
UINT8 strused = 0;
for ( UINT8 i = 0; i < BG_MAX; ++i)
{
if ( BG_DISLIKEBG == i && zBackground[ubNumber].value[i] )
{
swprintf( atStr, szBackgroundText_Value[i] );
swprintf( atStr, szBackgroundText_Value[strused] );
wcscat( apStr, atStr );
}
else if ( BG_TRACKER_ABILITY == i && zBackground[ubNumber].value[i] )
{
swprintf( atStr, szBackgroundText_Value[i], (UINT16)((gSkillTraitValues.usSVTrackerMaxRange * zBackground[ubNumber].value[i]) / 100) );
swprintf( atStr, szBackgroundText_Value[strused], (UINT16)((gSkillTraitValues.usSVTrackerMaxRange * zBackground[ubNumber].value[i]) / 100) );
wcscat( apStr, atStr );
}
else if ( BG_SMOKERTYPE == i )
{
if ( zBackground[ubNumber].value[i] == 1 )
swprintf( atStr, szBackgroundText_Value[strused] );
else
swprintf( atStr, szBackgroundText_Value[strused + 1] );
wcscat( apStr, atStr );
// smoke has 2 texts, so extra increase of counter is needed
++strused;
}
else if ( zBackground[ ubNumber ].value[i] )
{
swprintf(atStr, szBackgroundText_Value[ i ], zBackground[ ubNumber ].value[i] > 0 ? L"+" : L"", zBackground[ ubNumber ].value[i] );
swprintf( atStr, szBackgroundText_Value[strused], zBackground[ubNumber].value[i] > 0 ? L"+" : L"", zBackground[ubNumber].value[i] );
wcscat( apStr, atStr );
}
++strused;
}
}
else
+21
View File
@@ -826,6 +826,27 @@ BOOLEAN DisplayMercData( UINT8 usProfileA, UINT8 usProfileB )
usPosY += DisplayWrappedString( usPosX + MCA_SIDEOFFSET + MCA_NUMBEROFFSET, usPosY, LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X, 2, CAMPHIS_FONT_MED, (val > 0) ? FONT_MCOLOR_LTGREEN : (val < 0) ? FONT_MCOLOR_LTRED : MERCOMP_FONT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, 0 );
}
// smoker
INT16 smokerA = GetBackgroundValue( usProfileA, BG_SMOKERTYPE );
INT16 smokerB = GetBackgroundValue( usProfileB, BG_SMOKERTYPE );
if ( smokerA && smokerB )
{
if ( smokerA != smokerB )
val = -2;
else
val = 1;
swprintf( sText, smokerA == 1 ? szBackgroundText_Value[BG_SMOKERTYPE] : szBackgroundText_Value[BG_SMOKERTYPE + 1] );
DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X, 2, CAMPHIS_FONT_MED, MERCOMP_FONT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, 0 );
swprintf( sText, L"%d", val );
DisplayWrappedString( usPosX + MCA_NUMBEROFFSET, usPosY, LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X, 2, CAMPHIS_FONT_MED, (val > 0) ? FONT_MCOLOR_LTGREEN : (val < 0) ? FONT_MCOLOR_LTRED : MERCOMP_FONT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, 0 );
swprintf( sText, smokerB == 1 ? szBackgroundText_Value[BG_SMOKERTYPE] : szBackgroundText_Value[BG_SMOKERTYPE + 1] );
DisplayWrappedString( usPosX + MCA_SIDEOFFSET, usPosY, LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X, 2, CAMPHIS_FONT_MED, MERCOMP_FONT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, 0 );
swprintf( sText, L"%d", val );
usPosY += DisplayWrappedString( usPosX + MCA_SIDEOFFSET + MCA_NUMBEROFFSET, usPosY, LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X, 2, CAMPHIS_FONT_MED, (val > 0) ? FONT_MCOLOR_LTGREEN : (val < 0) ? FONT_MCOLOR_LTRED : MERCOMP_FONT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, 0 );
}
// after this, the lines are no longer synchronous - we just list each property on its own side
usPosY2 = usPosY;
+63 -7
View File
@@ -1554,9 +1554,34 @@ BOOLEAN MERCPROFILESTRUCT::Load(HWFILE hFile, bool forceLoadOldVersion, bool for
{
if ( guiCurrentSaveGameVersion >= DYNAMIC_DIALOGUE )
{
if ( !FileRead( hFile, &this->usDynamicOpinionFlagmask, sizeof(usDynamicOpinionFlagmask), &uiNumBytesRead ) )
if ( guiCurrentSaveGameVersion >= DRUG_SYSTEM_REDONE )
{
return(FALSE);
if ( !FileRead( hFile, &this->usDynamicOpinionFlagmask, sizeof(usDynamicOpinionFlagmask), &uiNumBytesRead ) )
{
return(FALSE);
}
}
else
{
UINT32 tmp[NUM_PROFILES][5];
if ( !FileRead( hFile, &tmp, sizeof(tmp), &uiNumBytesRead ) )
{
return(FALSE);
}
for ( UINT16 profile = 0; profile < NUM_PROFILES; ++profile )
{
UINT8 i = 0;
for ( i = 0; i < 5; ++i )
{
this->usDynamicOpinionFlagmask[profile][i] = tmp[profile][i];
}
for ( ; i < OPINION_FLAGMASKS_NUMBER; ++i )
{
this->usDynamicOpinionFlagmask[profile][i] = tmp[profile][i];
}
}
}
if ( !FileRead( hFile, &this->sDynamicOpinionLongTerm, sizeof(sDynamicOpinionLongTerm), &uiNumBytesRead ) )
@@ -1566,7 +1591,7 @@ BOOLEAN MERCPROFILESTRUCT::Load(HWFILE hFile, bool forceLoadOldVersion, bool for
}
else
{
UINT32 tmp[NUM_PROFILES][3];
UINT32 tmp[NUM_PROFILES][3];
if ( !FileRead( hFile, &tmp, sizeof(tmp), &uiNumBytesRead ) )
{
return(FALSE);
@@ -1574,7 +1599,13 @@ BOOLEAN MERCPROFILESTRUCT::Load(HWFILE hFile, bool forceLoadOldVersion, bool for
for ( UINT16 profile = 0; profile < NUM_PROFILES; ++profile )
{
for ( UINT8 i = 0; i < 3; ++i )
UINT8 i = 0;
for ( i = 0; i < 3; ++i )
{
this->usDynamicOpinionFlagmask[profile][i] = tmp[profile][i];
}
for ( ; i < OPINION_FLAGMASKS_NUMBER; ++i )
{
this->usDynamicOpinionFlagmask[profile][i] = tmp[profile][i];
}
@@ -1724,10 +1755,13 @@ BOOLEAN SOLDIERTYPE::Save(HWFILE hFile)
{
return(FALSE);
}
if ( !FileWrite( hFile, &this->drugs, sizeof(STRUCT_Drugs), &uiNumBytesWritten ) )
// Flugente: changed drug structure
if ( !FileWrite( hFile, &this->newdrugs, sizeof(DRUGS), &uiNumBytesWritten ) )
{
return(FALSE);
}
if ( !FileWrite( hFile, &this->stats, sizeof(STRUCT_Statistics), &uiNumBytesWritten ) )
{
return(FALSE);
@@ -2610,10 +2644,32 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
{
return(FALSE);
}
if ( !FileRead( hFile, &this->drugs, sizeof(STRUCT_Drugs), &uiNumBytesRead ) )
if ( guiCurrentSaveGameVersion < DRUG_SYSTEM_REDONE )
{
return(FALSE);
// read old drugs with a dummy structure of the old structs size (192)
UINT8 tmp[192];
if ( !FileRead( hFile, &tmp, sizeof(tmp), &uiNumBytesRead ) )
{
return(FALSE);
}
/*if ( !FileRead( hFile, &this->drugs, sizeof(STRUCT_Drugs), &uiNumBytesRead ) )
{
return(FALSE);
}*/
// clear new drugs
memset( &this->newdrugs, 0, sizeof(DRUGS) );
}
else
{
if ( !FileRead( hFile, &this->newdrugs, sizeof(DRUGS), &uiNumBytesRead ) )
{
return(FALSE);
}
}
//Load STRUCT_Statistics
numBytesRead = 0;
buffer = 0;
+31 -19
View File
@@ -70,6 +70,7 @@
#include "Disease.h" // added by Flugente
#include "Queen Command.h" // added by Flugente
#include "PMC.h" // added by Flugente
#include "Drugs And Alcohol.h" // added by Flugente for DoesMercHaveDisability( ... )
#endif
#include <vector>
#include <queue>
@@ -2738,14 +2739,15 @@ UINT16 CalculateHealingPointsForDoctor(SOLDIERTYPE *pDoctor, UINT16 *pusMaxPts,
usHealPts += usHealPts * gSkillTraitValues.usDODoctorAssignmentBonus * NUM_SKILL_TRAITS( pDoctor, DOCTOR_NT ) / 100;
*pusMaxPts += *pusMaxPts * gSkillTraitValues.usDODoctorAssignmentBonus * NUM_SKILL_TRAITS( pDoctor, DOCTOR_NT ) / 100;
}
// penalty for aggressive people
if ( gMercProfiles[ pDoctor->ubProfile ].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
if ( DoesMercHavePersonality( pDoctor, CHAR_TRAIT_AGGRESSIVE ) )
{
usHealPts -= usHealPts / 10;
*pusMaxPts -= *pusMaxPts / 10;
}
// bonus for phlegmatic people
else if ( gMercProfiles[ pDoctor->ubProfile ].bCharacterTrait == CHAR_TRAIT_PHLEGMATIC )
else if ( DoesMercHavePersonality( pDoctor, CHAR_TRAIT_PHLEGMATIC ) )
{
usHealPts += usHealPts / 20;
*pusMaxPts += *pusMaxPts / 20;
@@ -2831,14 +2833,15 @@ UINT8 CalculateRepairPointsForRepairman(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts
usRepairPts += usRepairPts * gSkillTraitValues.usTERepairSpeedBonus * (NUM_SKILL_TRAITS( pSoldier, TECHNICIAN_NT )) / 100;
*pusMaxPts += *pusMaxPts * gSkillTraitValues.usTERepairSpeedBonus * (NUM_SKILL_TRAITS( pSoldier, TECHNICIAN_NT )) / 100;
}
// Penalty for aggressive people
if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_AGGRESSIVE ) )
{
usRepairPts -= usRepairPts / 10; // -10%
*pusMaxPts -= *pusMaxPts / 10;
}
// Bonus for phlegmatic people
else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_PHLEGMATIC )
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_PHLEGMATIC ) )
{
usRepairPts += usRepairPts / 20; // +5%
*pusMaxPts += *pusMaxPts / 20;
@@ -3015,10 +3018,11 @@ UINT32 CalculateSnitchGuardValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts )
usValue += 25 * NUM_SKILL_TRAITS( pSoldier, STEALTHY_OT );
}
if( gMercProfiles[ pSoldier->ubProfile ].bDisability == DEAF )
if ( DoesMercHaveDisability( pSoldier, DEAF ) )
{
usValue = usValue/2;
}
// adjust for fatigue
ReducePointsForFatigue( pSoldier, &usValue );
@@ -3136,7 +3140,7 @@ UINT32 CalculateSnitchInterrogationValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPt
if ( gGameOptions.fNewTraitSystem )
{
if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_ASSERTIVE )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_ASSERTIVE ) )
friendlyvalue += 30;
}
@@ -5092,8 +5096,9 @@ void FatigueCharacter( SOLDIERTYPE *pSoldier )
{
bMaxBreathLoss = (bMaxBreathLoss * (100 - gSkillTraitValues.ubSVBreathForTravellingReduction * NUM_SKILL_TRAITS( pSoldier, SURVIVAL_NT )) / 100);
}
// primitive people get exhausted slower
if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_PRIMITIVE )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_PRIMITIVE ) )
{
switch ( pSoldier->bAssignment )
{
@@ -5121,8 +5126,8 @@ void FatigueCharacter( SOLDIERTYPE *pSoldier )
break;
}
}
// Picifist actually gain morale, when on peaceful assignments
else if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_PACIFIST )
// Pacifists actually gain morale, when on peaceful assignments
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_PACIFIST ) )
{
switch ( pSoldier->bAssignment )
{
@@ -5537,9 +5542,12 @@ void HandleDiseaseDiagnosis()
for ( int i = 0; i < NUM_DISEASES; ++i )
{
// if teammember has disease, but this is not yet known
if ( pTeamSoldier->sDiseasePoints[i] > 0 && !(pTeamSoldier->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED) )
if ( pTeamSoldier->sDiseasePoints[i] > 0 && !(pTeamSoldier->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED) && Disease[i].sInfectionPtsOutbreak > 0 )
{
if ( Chance( skill ) )
// whether an infection is diagnosed also depends on how high it is compared to an outbreak
FLOAT infectedfraction = ((FLOAT)pTeamSoldier->sDiseasePoints[i] / (FLOAT)Disease[i].sInfectionPtsOutbreak);
if ( infectedfraction > 0.0f && Chance((UINT32)(100 * infectedfraction)) && Chance( skill ) )
{
// doctor discovered a disease - make it known
pTeamSoldier->AnnounceDisease( i );
@@ -5763,7 +5771,7 @@ void HandleGatheringInformationBySoldier( SOLDIERTYPE* pSoldier )
FLOAT fBaseChance = ( EffectiveLeadership(pSoldier) + EffectiveWisdom(pSoldier) + EffectiveExpLevel(pSoldier) * 10 ) / 3000.0f;
if( gMercProfiles[ pSoldier->ubProfile ].bDisability == DEAF )
if ( DoesMercHaveDisability( pSoldier, DEAF ) )
{
fBaseChance /= 2.0;
}
@@ -6146,16 +6154,18 @@ INT16 GetSoldierTrainingPts( SOLDIERTYPE *pSoldier, INT8 bTrainStat, UINT16 *pus
bTrainingBonus += gSkillTraitValues.ubTGBonusOnPractising;
//sTrainingPts += (sTrainingPts * gSkillTraitValues.ubTGBonusOnPractising / 100);
}
// bonus for practising for intellectuals
if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_INTELLECTUAL )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_INTELLECTUAL ) )
{
// +10%
*pusMaxPts += (*pusMaxPts / 10);
bTrainingBonus += 10;
//sTrainingPts += (sTrainingPts / 10);
}
// bonus for practising for intellectuals
if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_AGGRESSIVE ) )
{
switch (bTrainStat)
{
@@ -6268,16 +6278,18 @@ INT16 GetSoldierStudentPts( SOLDIERTYPE *pSoldier, INT8 bTrainStat, UINT16 *pusM
bTrainingBonus += gSkillTraitValues.ubTGBonusOnPractising;
//sTrainingPts += (sTrainingPts * gSkillTraitValues.ubTGBonusOnPractising / 100);
}
// bonus for practising for intellectuals
if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_INTELLECTUAL )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_INTELLECTUAL ) )
{
// +10%
*pusMaxPts += (*pusMaxPts / 10);
bTrainingBonus += 10;
//sTrainingPts += (sTrainingPts / 10);
}
// bonus for practising for intellectuals
if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_AGGRESSIVE ) )
{
switch (bTrainStat)
{
@@ -7388,17 +7400,17 @@ INT16 GetTownTrainPtsForCharacter( SOLDIERTYPE *pTrainer, UINT16 *pusMaxPts )
sTrainingBonus += gSkillTraitValues.ubTGBonusToTrainMilitia;
}
// +10% for Assertive people
if ( gMercProfiles[pTrainer->ubProfile].bCharacterTrait == CHAR_TRAIT_ASSERTIVE )
if ( DoesMercHavePersonality( pTrainer, CHAR_TRAIT_ASSERTIVE ) )
{
sTrainingBonus += 10;
}
// -5% for Aggressive people
else if ( gMercProfiles[pTrainer->ubProfile].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
else if ( DoesMercHavePersonality( pTrainer, CHAR_TRAIT_AGGRESSIVE ) )
{
sTrainingBonus -= 5;
}
// +5% for Phlegmatic people
else if ( gMercProfiles[pTrainer->ubProfile].bCharacterTrait == CHAR_TRAIT_PHLEGMATIC )
else if ( DoesMercHavePersonality( pTrainer, CHAR_TRAIT_PHLEGMATIC ) )
{
sTrainingBonus += 5;
}
+7 -3
View File
@@ -1840,9 +1840,13 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
}
// Add effects
pSoldier->AddDrugValues( DRUG_TYPE_ALCOHOL, Drug[DRUG_TYPE_ALCOHOL].ubDrugEffect, Drug[DRUG_TYPE_ALCOHOL].ubDrugTravelRate, Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect );
CreateItem( ALCOHOL, Item[ALCOHOL].usPortionSize, &gTempObject );
ApplyConsumable( pSoldier, &gTempObject, TRUE, FALSE );
// ATE: Make guy collapse from heart attack if too much stuff taken....
//pSoldier->AddDrugValues( DRUG_TYPE_ALCOHOL, Drug[DRUG_TYPE_ALCOHOL].ubDrugEffect, Drug[DRUG_TYPE_ALCOHOL].ubDrugTravelRate, Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect );
/*// ATE: Make guy collapse from heart attack if too much stuff taken....
if ( pSoldier->drugs.bDrugSideEffectRate[ DRUG_TYPE_ALCOHOL ] > ( Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect * 3 ) )
{
if ( pSoldier->ubProfile == LARRY_NORMAL )
@@ -1938,7 +1942,7 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
}*/
break;
case RISK_LOYALTY_LOCAL:
Result *= GAIN_PTS_PER_LOYALTY_PT; // Transform points into actual loyalty.
+38 -19
View File
@@ -20,6 +20,7 @@
#include "Strategic AI.h"
#include "Tactical Save.h" // added by Flugente
#include "DynamicDialogue.h" // added by Flugente for HandleDynamicOpinions()
#include "Drugs And Alcohol.h" // added by Flugente for HourlyDrugUpdate()
#endif
#include "Luaglobal.h"
@@ -41,6 +42,7 @@
void HourlyQuestUpdate();
void HourlyLarryUpdate();
void HourlySmokerUpdate();
void HourlyStealUpdate(); // Flugente: certain characters might steal equipment (backgrounds)
void HourlySnitchUpdate(); // anv: decreasing cooldown after exposition
@@ -60,8 +62,6 @@ void HourlyHelicopterRepair();
void HourlyGatheringInformation();
void UpdateRegenCounters( void );
void HandleMinuteUpdate()
{
}
@@ -117,6 +117,8 @@ CHAR16 zString[128];
HourlyLarryUpdate();
HourlySmokerUpdate( );
HourlyStealUpdate();
HourlySnitchUpdate();
@@ -139,10 +141,7 @@ CHAR16 zString[128];
HourlyHelicopterRepair();
#endif
if ( GetWorldHour() % 6 == 0 ) // 4 times a day
{ UpdateRegenCounters();
}
HourlyDrugUpdate();
// WANNE: This check should avoid the resaving of a loaded auto-save game, when entering tactical
BOOLEAN doAutoSave = TRUE;
@@ -255,19 +254,6 @@ CHAR16 zString[128];
}
}
void UpdateRegenCounters( void )
{
UINT8 ubID;
for ( ubID = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; ubID <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubID++ )
{
if ( MercPtrs[ ubID ]->bRegenBoostersUsedToday > 0 )
{
MercPtrs[ ubID ]->bRegenBoostersUsedToday--;
}
}
}
void HandleQuarterHourUpdate()
{
//if the game hasnt even started yet ( we havent arrived in the sector ) dont process this
@@ -528,6 +514,39 @@ void HourlyLarryUpdate()
}
}
}
#include "Interface.h"
// Flugente: mercs that are smokers occasionally consume smokes if they have some in their inventory
void HourlySmokerUpdate( )
{
SOLDIERTYPE * pSoldier = NULL;
OBJECTTYPE* pObj = NULL;
for ( UINT32 cnt = gTacticalStatus.Team[OUR_TEAM].bFirstID; cnt <= gTacticalStatus.Team[OUR_TEAM].bLastID; ++cnt )
{
pSoldier = MercPtrs[cnt];
if ( pSoldier && pSoldier->bActive && !pSoldier->flags.fMercAsleep )
{
// if we are a smoker, there is a chance that we will look fo cigarettes in our inventory, and consume them if we find any
if ( Chance(33) && pSoldier->GetBackgroundValue( BG_SMOKERTYPE ) == 1 )
{
INT8 invsize = (INT8)pSoldier->inv.size( ); // remember inventorysize, so we don't call size() repeatedly
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop ) // ... for all items in our inventory ...
{
if ( pSoldier->inv[bLoop].exists( ) && Item[pSoldier->inv[bLoop].usItem].cigarette )
{
pObj = &(pSoldier->inv[bLoop]);
if ( ApplyConsumable( pSoldier, pObj, FALSE, FALSE ) )
{
break;
}
}
}
}
}
}
}
// anv: decrease exposed snitch cooldown (for simplified exposition handling)
void HourlySnitchUpdate()
+27 -59
View File
@@ -2351,7 +2351,7 @@ void DrawCharStats( INT16 sCharNum )
SetFontBackground(FONT_BLACK);
// strength
swprintf( sString, L"%d", pSoldier->stats.bStrength);
swprintf( sString, L"%d", pSoldier->stats.bStrength + pSoldier->bExtraStrength );
// SANDRO - if damaged stat we could regain, show in red until repaired
if ( ( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_STRENGTH] > 0 )) || (gGameOptions.fFoodSystem && pSoldier->usStarveDamageStrength > 0) )
@@ -2369,6 +2369,10 @@ void DrawCharStats( INT16 sCharNum )
SetFontForeground( FONT_RED );
}
}
else if ( pSoldier->bExtraStrength )
{
SetRGBFontForeground( 250, 5, 250 );
}
else
{
SetFontForeground(CHAR_TEXT_FONT_COLOR);
@@ -2379,7 +2383,7 @@ void DrawCharStats( INT16 sCharNum )
DrawString(sString,usX, STR_Y,CHAR_FONT );
// dexterity
swprintf( sString, L"%d", pSoldier->stats.bDexterity );
swprintf( sString, L"%d", pSoldier->stats.bDexterity + pSoldier->bExtraDexterity );
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_DEXTERITY] > 0 ))
@@ -2397,6 +2401,10 @@ void DrawCharStats( INT16 sCharNum )
SetFontForeground( FONT_RED );
}
}
else if ( pSoldier->bExtraDexterity )
{
SetRGBFontForeground( 250, 5, 250 );
}
else
{
SetFontForeground(CHAR_TEXT_FONT_COLOR);
@@ -2407,7 +2415,7 @@ void DrawCharStats( INT16 sCharNum )
DrawString(sString,usX, DEX_Y,CHAR_FONT );
// agility
swprintf( sString, L"%d", pSoldier->stats.bAgility );
swprintf( sString, L"%d", pSoldier->stats.bAgility + pSoldier->bExtraAgility );
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_AGILITY] > 0 ))
@@ -2425,6 +2433,10 @@ void DrawCharStats( INT16 sCharNum )
SetFontForeground( FONT_RED );
}
}
else if ( pSoldier->bExtraAgility )
{
SetRGBFontForeground( 250, 5, 250 );
}
else
{
SetFontForeground(CHAR_TEXT_FONT_COLOR);
@@ -2435,7 +2447,7 @@ void DrawCharStats( INT16 sCharNum )
DrawString(sString,usX, AGL_Y,CHAR_FONT );
// wisdom
swprintf( sString, L"%d", pSoldier->stats.bWisdom );
swprintf( sString, L"%d", pSoldier->stats.bWisdom + pSoldier->bExtraWisdom );
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_WISDOM] > 0 ))
@@ -2453,6 +2465,10 @@ void DrawCharStats( INT16 sCharNum )
SetFontForeground( FONT_RED );
}
}
else if ( pSoldier->bExtraWisdom )
{
SetRGBFontForeground( 250, 5, 250 );
}
else
{
SetFontForeground(CHAR_TEXT_FONT_COLOR);
@@ -2491,7 +2507,7 @@ void DrawCharStats( INT16 sCharNum )
DrawString(sString,usX, LDR_Y,CHAR_FONT );
// experience level
swprintf( sString, L"%d", pSoldier->stats.bExpLevel );
swprintf( sString, L"%d", pSoldier->stats.bExpLevel + pSoldier->bExtraExpLevel );
if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeLevelTime)&&( pSoldier->timeChanges.uiChangeLevelTime != 0 ) )
{
@@ -2504,6 +2520,10 @@ void DrawCharStats( INT16 sCharNum )
SetFontForeground( FONT_RED );
}
}
else if ( pSoldier->bExtraExpLevel )
{
SetRGBFontForeground( 250, 5, 250 );
}
else
{
SetFontForeground(CHAR_TEXT_FONT_COLOR);
@@ -9535,50 +9555,12 @@ void MAPInvClickCamoCallback( MOUSE_REGION *pRegion, INT32 iReason )
if ( gpItemPointer && pSoldier )
{
BOOLEAN fGoodAPs = FALSE;
BOOLEAN fDoSound = FALSE;
// We are doing this ourselve, continue
if ( pSoldier->stats.bLife >= CONSCIOUSNESS )
{
// Try to apply camo....
if ( ApplyCammo( pSoldier, gpItemPointer, &fGoodAPs ) )
if ( ApplyConsumable( pSoldier, gpItemPointer, FALSE, TRUE ) )
{
if ( fGoodAPs )
{
fDoSound = TRUE;
// WANNE: We should only delete the face, if there was a camo we applied.
// This should fix the bug and crashes with missing faces
if ( gGameExternalOptions.fShowCamouflageFaces )
{
// Flugente: refresh face regardless of result of SetCamoFace(), otherwise applying a rag will not clean the picture
SetCamoFace( pSoldier );
DeleteSoldierFace( pSoldier );// remove face
gpItemPointerSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
}
}
}
else if ( !gGameOptions.fFoodSystem && ApplyCanteen( pSoldier, gpItemPointer, &fGoodAPs, TRUE ) )
{
;
}
else if ( ApplyElixir( pSoldier, gpItemPointer, &fGoodAPs ) )
{
fDoSound = TRUE;
}
else if ( ApplyDrugs( pSoldier, gpItemPointer ) )
{
fGoodAPs = TRUE;
fDoSound = TRUE;
}
else if ( gGameOptions.fFoodSystem && ApplyFood( pSoldier, gpItemPointer, FALSE, FALSE ) )
{
fGoodAPs = TRUE;
}
else if ( ApplyClothes( pSoldier, gpItemPointer ) )
{
fGoodAPs = TRUE;
UpdateMercBodyRegionHelpText( );
}
else
{
@@ -9595,20 +9577,6 @@ void MAPInvClickCamoCallback( MOUSE_REGION *pRegion, INT32 iReason )
//EndItemPointer( );
MAPEndItemPointer( );
}
if ( fGoodAPs )
{
// Dirty
fInterfacePanelDirty = DIRTYLEVEL2;
UpdateMercBodyRegionHelpText( );
}
if ( fDoSound )
{
// Say OK acknowledge....
pSoldier->DoMercBattleSound( BATTLE_SOUND_COOL1 );
}
}
}
}
+1 -1
View File
@@ -1013,7 +1013,7 @@ UINT32 GetArmsDealerItemTypeFromItemNumber( UINT16 usItem )
break;
case IC_MISC:
{
if ( Item [usItem].alcohol )
if ( Item [usItem].alcohol > 0.0f )
return( ARMS_DEALER_ALCOHOL );
else if ( Item [usItem].electronic )
return( ARMS_DEALER_ELECTRONICS );
+2 -5
View File
@@ -183,8 +183,7 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
if (usNumChances == 0)
return;
usSubpointsPerPoint = SubpointsPerPoint(ubStat, pProfile->bExpLevel);
usSubpointsPerLevel = SubpointsPerPoint(EXPERAMT, pProfile->bExpLevel);
@@ -262,15 +261,13 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
// training always affected by wisdom
fAffectedByWisdom = TRUE;
}
// stats/skills of 0 can NEVER be improved!
if ( bCurrentRating < 0 )
{
return;
}
// loop once for each chance to improve
for (uiCnt = 0; uiCnt < usNumChances; uiCnt++)
{
+2 -1
View File
@@ -19,6 +19,7 @@
#include "strategic.h"
#include "DynamicDialogue.h"
#include <math.h>
#include "Drugs And Alcohol.h" // for DoesMercHaveDisability( ... )
//GLOBALS
DISEASE Disease[NUM_DISEASES];
@@ -422,7 +423,7 @@ void HandlePossibleInfection( SOLDIERTYPE *pSoldier, SOLDIERTYPE* pOtherSoldier,
if ( aInfectionType == INFECTION_TYPE_TROPICS || aInfectionType == INFECTION_TYPE_SWAMP )
{
// if we are afraid of insects, we will be more careful around them - lower chance to be infected
if ( gMercProfiles[pSoldier->ubProfile].bDisability == FEAR_OF_INSECTS )
if ( DoesMercHaveDisability( pSoldier, FEAR_OF_INSECTS ) )
dChance *= 0.7f;
}
else if ( aInfectionType == INFECTION_TYPE_CONTACT_HUMAN )
+1
View File
@@ -98,6 +98,7 @@ typedef struct
INT8 sNeedToSleep; // +/- need to sleep
INT16 sDrinkModifier; // +/- % water consumption
INT16 sFoodModifier; // +/- % water consumption
FLOAT moralemodifier; // a modifier to total morale
} DISEASE;
//GLOBALS
+341 -63
View File
@@ -23,6 +23,301 @@
class OBJECTTYPE;
class SOLDIERTYPE;
BOOLEAN ApplyDrugs_New( SOLDIERTYPE *pSoldier, UINT16 usItem, UINT16 uStatusUsed )
{
// If not a drug, return
if ( !Item[usItem].drugtype || !uStatusUsed || !pSoldier )
return(FALSE);
UINT32 drugused = Item[usItem].drugtype;
// we might not use up the entire item, so reduce effects accordingly
FLOAT effectivepercentage = uStatusUsed / 100.0;
// if this alcohol, alcohol resistance can lower the effects
if ( Item[usItem].alcohol > 0.0f )
{
effectivepercentage = effectivepercentage * ((100.0 - pSoldier->GetBackgroundValue( BG_RESI_ALCOHOL )) / 100.0);
FLOAT weight = pSoldier->GetBodyWeight( );
// the alcohol amounts in the xml are intended for a person with weight 80. We thus have to alter the effective value
if ( weight > 0.0f )
{
effectivepercentage *= 80.0f / weight;
}
}
// we now add drug, disease, personality and disability effects
// every effect has a chance of happening (not entering a chance, so 0, always results in a effect for xml editing simplicity reasons)
// add effects
std::vector<DRUG_EFFECT> vec_drug = NewDrug[drugused].drug_effects;
std::vector<DRUG_EFFECT>::iterator drug_effects_itend = vec_drug.end( );
for ( std::vector<DRUG_EFFECT>::iterator drug_effects_it = vec_drug.begin( ); drug_effects_it != drug_effects_itend; ++drug_effects_it )
{
if ( !(*drug_effects_it).chance || Chance( (*drug_effects_it).chance ) )
{
// if we are already under influence of this effect, merge them, otherwise just add effect
if ( pSoldier->newdrugs.duration[(*drug_effects_it).effect] )
{
INT32 effectsum_existing = pSoldier->newdrugs.duration[(*drug_effects_it).effect] * pSoldier->newdrugs.size[(*drug_effects_it).effect];
INT32 effectsum_new = (*drug_effects_it).duration * (*drug_effects_it).size;
INT32 effectsum_total = effectsum_existing + effectsum_new * effectivepercentage;
UINT16 newduration = (pSoldier->newdrugs.duration[(*drug_effects_it).effect] + (*drug_effects_it).duration) / 2;
if ( newduration )
{
INT32 newsize = effectsum_total / newduration;
pSoldier->newdrugs.duration[(*drug_effects_it).effect] = newduration;
pSoldier->newdrugs.size[(*drug_effects_it).effect] = newsize;
}
}
else
{
pSoldier->newdrugs.duration[(*drug_effects_it).effect] = (*drug_effects_it).duration;
pSoldier->newdrugs.size[(*drug_effects_it).effect] = (*drug_effects_it).size * effectivepercentage;
}
}
}
// add diseases
std::vector<DISEASE_EFFECT> vec_disease = NewDrug[drugused].disease_effects;
std::vector<DISEASE_EFFECT>::iterator disease_effects_itend = vec_disease.end( );
for ( std::vector<DISEASE_EFFECT>::iterator disease_effects_it = vec_disease.begin( ); disease_effects_it != disease_effects_itend; ++disease_effects_it )
{
if ( !(*disease_effects_it).chance || Chance( (*disease_effects_it).chance ) )
{
pSoldier->AddDiseasePoints( (*disease_effects_it).disease, (*disease_effects_it).size * effectivepercentage );
}
}
// add disability
std::vector<DISABILITY_EFFECT> vec_disability = NewDrug[drugused].disability_effects;
std::vector<DISABILITY_EFFECT>::iterator disability_effects_itend = vec_disability.end( );
for ( std::vector<DISABILITY_EFFECT>::iterator disability_effects_it = vec_disability.begin( ); disability_effects_it != disability_effects_itend; ++disability_effects_it )
{
if ( !(*disability_effects_it).chance || Chance( (*disability_effects_it).chance ) )
{
if ( pSoldier->newdrugs.drugdisability == (*disability_effects_it).disability )
{
pSoldier->newdrugs.drugdisability_duration += (*disability_effects_it).duration * effectivepercentage;
}
else
{
pSoldier->newdrugs.drugdisability = (*disability_effects_it).disability;
pSoldier->newdrugs.drugdisability_duration = (*disability_effects_it).duration * effectivepercentage;
}
}
}
// add personality
std::vector<PERSONALITY_EFFECT> vec_personality = NewDrug[drugused].personality_effects;
std::vector<PERSONALITY_EFFECT>::iterator personality_effects_itend = vec_personality.end( );
for ( std::vector<PERSONALITY_EFFECT>::iterator personality_effects_it = vec_personality.begin( ); personality_effects_it != personality_effects_itend; ++personality_effects_it )
{
if ( !(*personality_effects_it).chance || Chance( (*personality_effects_it).chance ) )
{
if ( pSoldier->newdrugs.drugpersonality == (*personality_effects_it).personality )
{
pSoldier->newdrugs.drugpersonality_duration += (*personality_effects_it).duration * effectivepercentage;
}
else
{
pSoldier->newdrugs.drugpersonality = (*personality_effects_it).personality;
pSoldier->newdrugs.drugpersonality_duration = (*personality_effects_it).duration * effectivepercentage;
}
}
}
// do switch for Larry!!
if ( pSoldier->ubProfile == LARRY_NORMAL )
{
pSoldier = SwapLarrysProfiles( pSoldier );
}
else if ( pSoldier->ubProfile == LARRY_DRUNK )
{
gMercProfiles[LARRY_DRUNK].bNPCData = 0;
}
if ( NewDrug[drugused].opinionevent )
{
HandleDynamicOpinionChange( pSoldier, OPINIONEVENT_ADDICT, TRUE, TRUE );
}
if ( Item[usItem].alcohol > 0.0f )
{
FLOAT weight = pSoldier->GetBodyWeight( );
// the alcohol amounts in the xml are intended for a person with weight 80. We thus have to alter the effective value
if ( weight > 0.0f )
{
// added promille = alcohol added (g) / (weight of person (kg) * 0.7)
FLOAT addedpromille = (Item[usItem].alcohol * effectivepercentage) / (weight * 0.7);
pSoldier->newdrugs.drinkstaken += addedpromille;
}
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_DRANK_SOME], pSoldier->GetName( ), ShortItemNames[usItem] );
HandleDynamicOpinionTeamDrinking( pSoldier );
}
else
{
// set flag: we are on non-alcoholic drugs
pSoldier->usSoldierFlagMask |= SOLDIER_DRUGGED;
if ( gMercProfiles[pSoldier->ubProfile].ubNumTimesDrugUseInLifetime != 255 )
{
gMercProfiles[pSoldier->ubProfile].ubNumTimesDrugUseInLifetime++;
}
if ( Item[usItem].cigarette )
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_MERC_TOOK_CIGARETTE], pSoldier->GetName( ), ShortItemNames[usItem] );
}
else
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_MERC_TOOK_DRUG], pSoldier->GetName( ) );
}
}
// Dirty panel
fInterfacePanelDirty = DIRTYLEVEL2;
return TRUE;
}
void HandleEndTurnDrugAdjustments_New( SOLDIERTYPE *pSoldier )
{
// some effects are handled here
if ( pSoldier->newdrugs.size[DRUG_EFFECT_HP] )
{
// increase life
pSoldier->stats.bLife = __min( pSoldier->stats.bLife + pSoldier->newdrugs.size[DRUG_EFFECT_HP], pSoldier->stats.bLifeMax );
//SANDRO - Insta-healable injury reduction
if ( pSoldier->newdrugs.size[DRUG_EFFECT_HP] > 0 )
{
pSoldier->iHealableInjury = max( 0, (pSoldier->iHealableInjury - (100 * pSoldier->newdrugs.size[DRUG_EFFECT_HP])) );
}
if ( pSoldier->stats.bLife == pSoldier->stats.bLifeMax )
{
pSoldier->bBleeding = 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->bExtraStrength += pSoldier->newdrugs.size[DRUG_EFFECT_STR];
pSoldier->bExtraDexterity += pSoldier->newdrugs.size[DRUG_EFFECT_DEX];
pSoldier->bExtraAgility += pSoldier->newdrugs.size[DRUG_EFFECT_AGI];
pSoldier->bExtraWisdom += pSoldier->newdrugs.size[DRUG_EFFECT_WIS];
BOOLEAN fStillDrugged = FALSE;
// as time progresses, effects wear off
for ( UINT8 i = 0; i < DRUG_EFFECT_MAX; ++i )
{
pSoldier->newdrugs.duration[i] = max( 0, pSoldier->newdrugs.duration[i] - 1 );
if ( !pSoldier->newdrugs.duration[i] )
pSoldier->newdrugs.size[i] = 0;
else
fStillDrugged = TRUE;
}
pSoldier->newdrugs.drugpersonality_duration = max( 0, pSoldier->newdrugs.drugpersonality_duration - 1 );
if ( !pSoldier->newdrugs.drugpersonality_duration )
pSoldier->newdrugs.drugpersonality = 0;
else
fStillDrugged = TRUE;
pSoldier->newdrugs.drugdisability_duration = max( 0, pSoldier->newdrugs.drugdisability_duration - 1 );
if ( !pSoldier->newdrugs.drugdisability_duration )
pSoldier->newdrugs.drugdisability = 0;
else
fStillDrugged = TRUE;
if ( !fStillDrugged )
{
pSoldier->usSoldierFlagMask &= ~SOLDIER_DRUGGED;
fInterfacePanelDirty = DIRTYLEVEL1;
}
}
INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier )
{
if ( pSoldier->usSoldierFlagMask2 & SOLDIER_HUNGOVER )
{
return HUNGOVER;
}
if ( pSoldier->newdrugs.drinkstaken <= 0.01 )
{
return SOBER;
}
else if ( pSoldier->newdrugs.drinkstaken <= 0.7 )
{
return FEELING_GOOD;
}
else if ( pSoldier->newdrugs.drinkstaken <= 2.0 )
{
return BORDERLINE;
}
return DRUNK;
}
// does a merc have a disability/personality, or is he under drugs that simulate this?
BOOLEAN DoesMercHaveDisability( SOLDIERTYPE *pSoldier, UINT8 aVal )
{
if ( pSoldier->ubProfile != NO_PROFILE )
{
if ( gMercProfiles[pSoldier->ubProfile].bDisability == aVal )
return TRUE;
if ( pSoldier->newdrugs.drugdisability == aVal )
return TRUE;
}
return FALSE;
}
BOOLEAN DoesMercHavePersonality( SOLDIERTYPE *pSoldier, UINT8 aVal )
{
// personalities are new trait system only!
if ( !gGameOptions.fNewTraitSystem )
return FALSE;
if ( pSoldier->ubProfile != NO_PROFILE )
{
if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == aVal )
return TRUE;
if ( pSoldier->newdrugs.drugpersonality == aVal )
return TRUE;
}
return FALSE;
}
//-------------------------------------------------------
/*UINT8 ubDrugTravelRate[] = { 4, 2 };
UINT8 ubDrugWearoffRate[] = { 2, 2 };
@@ -43,7 +338,7 @@ INT32 giDrunkModifier[] =
#define HANGOVER_BP_REDUCE 200
BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
/*BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
{
UINT32 ubDrugType;
INT8 bRegenPointsGained;
@@ -262,9 +557,9 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
ApplyFood( pSoldier, pObject, TRUE, TRUE );
return( TRUE );
}
}*/
void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
/*void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
{
INT32 cnt, cnt2;
INT32 iNumLoops;
@@ -508,72 +803,36 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
// if all drug effects have ended, delete flag
if ( !MercUnderTheInfluence(pSoldier) )
pSoldier->usSoldierFlagMask &= ~SOLDIER_DRUGGED;
}
}*/
void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *pubPoints )
{
INT8 bDrunkLevel;
INT16 sPoints = (*pubPoints);
// Are we in a side effect or good effect?
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
sPoints += pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ];
}
else if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
sPoints -= pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ];
if ( sPoints < APBPConstants[AP_MINIMUM] )
{
sPoints = APBPConstants[AP_MINIMUM];
}
}
*pubPoints += pSoldier->newdrugs.size[DRUG_EFFECT_AP];
bDrunkLevel = GetDrunkLevel( pSoldier );
if ( bDrunkLevel == HUNGOVER )
if ( GetDrunkLevel( pSoldier ) == HUNGOVER )
{
// Reduce....
sPoints -= HANGOVER_AP_REDUCE;
*pubPoints -= HANGOVER_AP_REDUCE;
if ( sPoints < APBPConstants[AP_MINIMUM] )
if ( *pubPoints < APBPConstants[AP_MINIMUM] )
{
sPoints = APBPConstants[AP_MINIMUM];
*pubPoints = APBPConstants[AP_MINIMUM];
}
}
(*pubPoints) = sPoints;
}
void HandleBPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *psPointReduction )
{
INT8 bDrunkLevel;
// Are we in a side effect or good effect?
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
(*psPointReduction) -= ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] * APBPConstants[BP_RATIO_RED_PTS_TO_NORMAL] );
}
else if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
(*psPointReduction) += ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] * APBPConstants[BP_RATIO_RED_PTS_TO_NORMAL] );
}
bDrunkLevel = GetDrunkLevel( pSoldier );
if ( bDrunkLevel == HUNGOVER )
*psPointReduction -= pSoldier->newdrugs.size[DRUG_EFFECT_BP];
if ( GetDrunkLevel( pSoldier ) == HUNGOVER )
{
// Reduce....
(*psPointReduction) += HANGOVER_BP_REDUCE;
}
}
void HandleDamageResistanceEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT32 *psPointReduction )
/*void HandleDamageResistanceEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT32 *psPointReduction )
{
// Are we in a side effect or good effect?
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_RESISTANCE ] )
@@ -586,9 +845,9 @@ void HandleDamageResistanceEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT32 *psPoi
// Adjust!
(*psPointReduction) -= pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_RESISTANCE ];
}
}
}*/
INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier )
/*INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier )
{
INT8 bNumDrinks;
@@ -618,14 +877,14 @@ INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier )
{
return( DRUNK );
}
}
}*/
INT32 EffectStatForBeingDrunk( SOLDIERTYPE *pSoldier, INT32 iStat )
{
return( ( iStat * giDrunkModifier[ GetDrunkLevel( pSoldier ) ] / 100 ) );
}
BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier )
/*BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier )
{
for (UINT8 cnt = DRUG_TYPE_ADRENALINE; cnt < DRUG_TYPE_MAX; ++cnt)
{
@@ -634,9 +893,20 @@ BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier )
}
return( FALSE );
}*/
BOOLEAN MercDruggedOrDrunk( SOLDIERTYPE *pSoldier )
{
if ( pSoldier->newdrugs.drinkstaken )
return TRUE;
if ( pSoldier->usSoldierFlagMask & SOLDIER_DRUGGED )
return TRUE;
return FALSE;
}
BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier, UINT8 aDrugType )
/*BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier, UINT8 aDrugType )
{
// in case of wrong inout, stay safe
if ( aDrugType >= DRUG_TYPE_MAX )
@@ -653,18 +923,26 @@ BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier, UINT8 aDrugType )
return( TRUE );
return( FALSE );
}
}*/
BOOLEAN MercDruggedButNotDrunk( SOLDIERTYPE *pSoldier )
BOOLEAN MercDrugged( SOLDIERTYPE *pSoldier )
{
for (UINT8 cnt = DRUG_TYPE_ADRENALINE; cnt < DRUG_TYPE_MAX; ++cnt)
return (pSoldier->usSoldierFlagMask & SOLDIER_DRUGGED);
}
void HourlyDrugUpdate( )
{
for ( UINT16 ubID = gTacticalStatus.Team[OUR_TEAM].bFirstID; ubID <= gTacticalStatus.Team[OUR_TEAM].bLastID; ++ubID )
{
if ( cnt == DRUG_TYPE_ALCOHOL )
continue;
// every hour, we lower our alcohol counter
if ( MercPtrs[ubID]->newdrugs.drinkstaken > 0.0f )
{
MercPtrs[ubID]->newdrugs.drinkstaken = max( 0.0, MercPtrs[ubID]->newdrugs.drinkstaken - 0.15f );
if ( MercUnderTheInfluence(pSoldier, cnt) )
return TRUE;
if ( MercPtrs[ubID]->newdrugs.drinkstaken <= 0.0f )
{
MercPtrs[ubID]->usSoldierFlagMask2 &= ~SOLDIER_HUNGOVER;
}
}
}
return( FALSE );
}
+100 -16
View File
@@ -3,18 +3,99 @@
#include "Soldier Control.h"
#define SOBER 0
class DRUG_EFFECT
{
/*bool operator==(const DRUG_EFFECT& other)
{
return ( effect == other.effect &&
duration == other.duration &&
size == other.size &&
chance == other.chance);
}
bool operator!=(const DRUG_EFFECT& other)
{
return !(*this == other);
}*/
public:
UINT8 effect;
UINT16 duration;
INT16 size;
UINT8 chance;
};
typedef struct
{
UINT8 disease;
INT32 size;
UINT8 chance;
} DISEASE_EFFECT;
typedef struct
{
UINT8 disability;
UINT16 duration;
UINT8 chance;
} DISABILITY_EFFECT;
typedef struct
{
UINT8 personality;
UINT16 duration;
UINT8 chance;
} PERSONALITY_EFFECT;
typedef struct
{
UINT8 uiIndex;
CHAR16 szName[80]; // name, used for display
BOOLEAN opinionevent;
std::vector<DRUG_EFFECT> drug_effects;
std::vector<DISEASE_EFFECT> disease_effects;
std::vector<DISABILITY_EFFECT> disability_effects;
std::vector<PERSONALITY_EFFECT> personality_effects;
} DRUG;
//GLOBALS
#define NEW_DRUGS_MAX 100
extern DRUG NewDrug[NEW_DRUGS_MAX];
enum {
SOBER = 0,
FEELING_GOOD,
BORDERLINE,
DRUNK,
HUNGOVER,
};
BOOLEAN ApplyDrugs_New( SOLDIERTYPE *pSoldier, UINT16 usItem, UINT16 uStatusUsed );
void HandleEndTurnDrugAdjustments_New( SOLDIERTYPE *pSoldier );
INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier );
// does a merc have a disability/personality, or is he under drugs that simulate this?
BOOLEAN DoesMercHaveDisability( SOLDIERTYPE *pSoldier, UINT8 aVal );
BOOLEAN DoesMercHavePersonality( SOLDIERTYPE *pSoldier, UINT8 aVal );
//----------------------------------------------------------------------------------------
/*#define SOBER 0
#define FEELING_GOOD 1
#define BORDERLINE 2
#define DRUNK 3
#define HUNGOVER 4
#define HUNGOVER 4 */
#define REGEN_POINTS_PER_BOOSTER 4
#define LIFE_GAIN_PER_REGEN_POINT 10
//#define REGEN_POINTS_PER_BOOSTER 4
//#define LIFE_GAIN_PER_REGEN_POINT 10
extern UINT8 gbPlayerNum;
//extern UINT8 gbPlayerNum;
enum {
/*enum {
DRUG_TYPE_ADRENALINE = 0,
DRUG_TYPE_ALCOHOL,
DRUG_TYPE_REGENERATION,
@@ -73,9 +154,9 @@ enum {
#define DRUG_MISC_15 0x10000000 //268435456
#define DRUG_MISC_16 0x20000000 //536870912
#define DRUG_MISC_17 0x40000000 //1073741824
#define DRUG_MISC_18 0x80000000 //2147483648
#define DRUG_MISC_18 0x80000000 //2147483648*/
typedef struct
/*typedef struct
{
UINT8 ubType; // type of drug: bit field
UINT8 ubDrugTravelRate;
@@ -89,19 +170,22 @@ typedef struct
} DRUGTYPE;
//GLOBALS
extern DRUGTYPE Drug[DRUG_TYPE_MAX];
extern DRUGTYPE Drug[DRUG_TYPE_MAX];*/
BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject );
//BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject );
void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier );
//void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier );
void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *pubPoints );
void HandleBPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *psPoints );
void HandleDamageResistanceEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT32 *psPoints );
//void HandleDamageResistanceEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT32 *psPoints );
INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier );
//INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier );
INT32 EffectStatForBeingDrunk( SOLDIERTYPE *pSoldier, INT32 iStat );
BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier );
BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier, UINT8 aDrugType );
BOOLEAN MercDruggedButNotDrunk( SOLDIERTYPE *pSoldier );
//BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier );
BOOLEAN MercDruggedOrDrunk( SOLDIERTYPE *pSoldier );
//BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier, UINT8 aDrugType );
BOOLEAN MercDrugged( SOLDIERTYPE *pSoldier );
void HourlyDrugUpdate();
#endif
+23 -13
View File
@@ -198,6 +198,17 @@ INT8 SoldierRelation( SOLDIERTYPE* pSoldierA, SOLDIERTYPE* pSoldierB )
bOpinion -= 2;
}
// smoker
INT16 smokerA = pSoldierA->GetBackgroundValue( BG_SMOKERTYPE );
INT16 smokerB = pSoldierB->GetBackgroundValue( BG_SMOKERTYPE );
if ( smokerA && smokerB )
{
if ( smokerA != smokerB )
bOpinion -= 2;
else
bOpinion += 1;
}
if ( pSoldierA->HasBackgroundFlag( BACKGROUND_XENOPHOBIC ) && pSoldierB->ubProfile != NO_PROFILE && gMercProfiles[pSoldierA->ubProfile].usBackground != gMercProfiles[pSoldierB->ubProfile].usBackground )
bOpinion -= gGameExternalOptions.sMoraleModXenophobicBackGround;
@@ -1818,7 +1829,7 @@ void HandleDynamicOpinionRetreat( )
void HandleDynamicOpinionTeamDrinking( SOLDIERTYPE* pSoldier )
{
// need to be drunk for this
if ( !pSoldier || pSoldier->ubProfile == NO_PROFILE || !MercUnderTheInfluence( pSoldier, DRUG_TYPE_ALCOHOL ) )
if ( !pSoldier || pSoldier->ubProfile == NO_PROFILE || !pSoldier->newdrugs.drinkstaken <= 0.0 )
return;
SOLDIERTYPE* pTeamSoldier = NULL;
@@ -1829,7 +1840,7 @@ void HandleDynamicOpinionTeamDrinking( SOLDIERTYPE* pSoldier )
// everybody other merc in the same sector can get updated if they are drugged too
if ( pTeamSoldier->bActive && pTeamSoldier->ubProfile != NO_PROFILE && pTeamSoldier->ubProfile != pSoldier->ubProfile &&
pTeamSoldier->sSectorX == pSoldier->sSectorX && pTeamSoldier->sSectorY == pSoldier->sSectorY && pTeamSoldier->bSectorZ == pSoldier->bSectorZ &&
MercUnderTheInfluence( pTeamSoldier, DRUG_TYPE_ALCOHOL ) &&
pTeamSoldier->newdrugs.drinkstaken > 0.0 &&
!(pTeamSoldier->bAssignment == IN_TRANSIT ||
pTeamSoldier->bAssignment == ASSIGNMENT_DEAD) )
{
@@ -2252,12 +2263,12 @@ void HandleDynamicOpinionChange( SOLDIERTYPE* pSoldier, UINT8 usEvent, BOOLEAN f
case OPINIONEVENT_BRUTAL_BAD:
// if we are a good guy or a pacifist, then we dislike excessive violence
if ( gMercProfiles[pTeamSoldier->ubProfile].ubMiscFlags3 & PROFILE_MISC_FLAG3_GOODGUY ||
gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_PACIFIST )
DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_PACIFIST ) )
usEventUsed = OPINIONEVENT_BRUTAL_BAD;
// if we are malicious, agressive or a psycho, then we like it
else if ( gMercProfiles[pTeamSoldier->ubProfile].bDisability == PSYCHO || MercUnderTheInfluence( pTeamSoldier, DRUG_TYPE_PSYCHO ) ||
gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE ||
gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_MALICIOUS )
else if ( DoesMercHaveDisability( pTeamSoldier, PSYCHO ) ||
DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_AGGRESSIVE ) ||
DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_MALICIOUS ) )
usEventUsed = OPINIONEVENT_BRUTAL_GOOD;
else
continue;
@@ -2272,7 +2283,7 @@ void HandleDynamicOpinionChange( SOLDIERTYPE* pSoldier, UINT8 usEvent, BOOLEAN f
if ( pTeamSoldier->ubTargetID == pSoldier->ubTargetID && pTeamSoldier->sTargetGridNo == pSoldier->sTargetGridNo )
{
// are we ambitious enough to care about kill counts?
if ( gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_ASSERTIVE || gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_SHOWOFF )
if ( DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_ASSERTIVE ) || DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_SHOWOFF ) )
{
// did we have enough AP to claim we were about to finish them?
if ( !EnoughPoints( pTeamSoldier, 60, 0, FALSE ) )
@@ -2291,16 +2302,15 @@ void HandleDynamicOpinionChange( SOLDIERTYPE* pSoldier, UINT8 usEvent, BOOLEAN f
case OPINIONEVENT_BATTLE_TOOK_PRISONER:
// we only care if we prefer the enemy to be taken alive
if ( !(gMercProfiles[pTeamSoldier->ubProfile].ubMiscFlags3 & PROFILE_MISC_FLAG3_GOODGUY ||
gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_INTELLECTUAL ||
gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_PACIFIST) )
continue;
DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_INTELLECTUAL ) ||
DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_PACIFIST ) ) )
continue;
break;
case OPINIONEVENT_CIV_ATTACKER:
// psychos or malicious characters dont care
if ( gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_MALICIOUS ||
gMercProfiles[pTeamSoldier->ubProfile].bDisability == PSYCHO ||
MercUnderTheInfluence( pTeamSoldier, DRUG_TYPE_PSYCHO ) )
if ( DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_MALICIOUS ) ||
DoesMercHaveDisability( pTeamSoldier, PSYCHO ) )
continue;
break;
+2 -2
View File
@@ -2149,8 +2149,8 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
bNumRightIcons++;
}
// Flugente: add drug symbol if drugged (without alcohol 'drug')
if ( MercDruggedButNotDrunk( MercPtrs[ pFace->ubSoldierID ] ) )
// Flugente: add drug symbol if drugged (without alcohol)
if ( MercDrugged( MercPtrs[pFace->ubSoldierID] ) )
{
DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 7 );
bNumRightIcons++;
+71 -60
View File
@@ -100,7 +100,64 @@ void AddFoodpoints( INT32& arCurrentFood, INT32 aVal )
arCurrentFood = max(arCurrentFood, FOOD_MIN);
}
BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, BOOLEAN fForceFromDrugs )
BOOLEAN DoesSoldierRefuseToEat( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj )
{
if ( gGameOptions.fFoodSystem )
{
// static variables to remember the last food someone was forced to eat
static UINT8 lasteater = 0;
static UINT16 lastitem = 0;
UINT32 foodtype = Item[pObj->usItem].foodtype;
if ( !foodtype )
return FALSE;
// check if we are willing to eat this: if we're filled, the merc refuses
if ( ((Food[foodtype].bFoodPoints > 0 && pSoldier->bFoodLevel > FoodMoraleMods[FOOD_MERC_REFUSAL].bThreshold) || Food[foodtype].bFoodPoints <= 0) &&
((Food[foodtype].bDrinkPoints > 0 && pSoldier->bDrinkLevel > FoodMoraleMods[FOOD_MERC_REFUSAL].bThreshold) || Food[foodtype].bDrinkPoints <= 0) )
{
// Say quote!
TacticalCharacterDialogue( pSoldier, QUOTE_PRE_NOT_SMART );
return TRUE;
}
// we have to determine wether the food is rotten, that might influence its condition and poison us
FLOAT foodcondition = (*pObj)[0]->data.bTemperature / OVERHEATING_MAX_TEMPERATURE;
// food in bad condition is harmful!
if ( foodcondition < FOOD_BAD_THRESHOLD )
{
// if we can choose to reject a food and haven't yet done so with this type of bad food, do so. Works only once
if ( (lasteater != pSoldier->ubID || lastitem != pObj->usItem) )
{
lasteater = pSoldier->ubID;
lastitem = pObj->usItem;
// notification
// do we eat or drink this stuff?
UINT8 type = AP_EAT;
if ( Food[foodtype].bDrinkPoints > Food[foodtype].bFoodPoints )
type = AP_DRINK;
if ( type == AP_EAT )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szFoodTextStr[STR_FOOD_DONOTWANT_EAT], pSoldier->GetName( ), Item[pObj->usItem].szItemName );
else
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szFoodTextStr[STR_FOOD_DONOTWANT_DRINK], pSoldier->GetName( ), Item[pObj->usItem].szItemName );
// Say quote!
TacticalCharacterDialogue( pSoldier, QUOTE_PRE_NOT_SMART );
return TRUE;
}
}
}
return FALSE;
}
BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, UINT16 usPointsToUse )
{
// static variables to remember the last food someone was forced to eat
static UINT8 lasteater = 0;
@@ -128,46 +185,13 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, B
UINT8 type = AP_EAT;
if ( Food[foodtype].bDrinkPoints > Food[foodtype].bFoodPoints )
type = AP_DRINK;
// return if we don't have enough APs
if ( !fForceFromDrugs && !EnoughPoints( pSoldier, APBPConstants[type], 0, TRUE ) )
{
return( FALSE );
}
// check if we are willing to eat this: if we're filled, the merc refuses
if ( !fForceFromDrugs && ( ( Food[foodtype].bFoodPoints > 0 && pSoldier->bFoodLevel > FoodMoraleMods[FOOD_MERC_REFUSAL].bThreshold ) || Food[foodtype].bFoodPoints <= 0 ) && ( ( Food[foodtype].bDrinkPoints > 0 && pSoldier->bDrinkLevel > FoodMoraleMods[FOOD_MERC_REFUSAL].bThreshold ) || Food[foodtype].bDrinkPoints <= 0 ) )
{
// Say quote!
TacticalCharacterDialogue( pSoldier, 61 );
return( FALSE);
}
// we have to determine wether the food is rotten, that might influence its condition and poison us
FLOAT foodcondition = (*pObject)[0]->data.bTemperature / OVERHEATING_MAX_TEMPERATURE;
// food in bad condition is harmful!
if ( !fForceFromDrugs && foodcondition < FOOD_BAD_THRESHOLD )
{
// if we can choose to reject a food and haven't yet done so with this type of bad food, do so. Works only once
if ( !fForce && ( lasteater != pSoldier->ubID || lastitem != pObject->usItem) )
{
lasteater = pSoldier->ubID;
lastitem = pObject->usItem;
// notification
if ( type == AP_EAT )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szFoodTextStr[STR_FOOD_DONOTWANT_EAT], pSoldier->GetName(), Item[pObject->usItem].szItemName );
else
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szFoodTextStr[STR_FOOD_DONOTWANT_DRINK], pSoldier->GetName(), Item[pObject->usItem].szItemName );
// Say quote!
TacticalCharacterDialogue( pSoldier, 61 );
return( FALSE);
}
if ( foodcondition < FOOD_BAD_THRESHOLD )
{
// determine the max nutritional value
INT32 maxpts = max(Food[foodtype].bFoodPoints, Food[foodtype].bDrinkPoints);
@@ -178,7 +202,7 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, B
FLOAT conditionmodifier = 0.5f * (1.0f + sqrt(foodcondition));
FLOAT percentualsize = min(Food[foodtype].ubPortionSize, (*pObject)[0]->data.objectStatus) / 100.0f;
FLOAT percentualsize = usPointsToUse / 100.0f;
INT32 foodpts = (INT32) (Food[foodtype].bFoodPoints * percentualsize * conditionmodifier );
INT32 drinkpts = (INT32) (Food[foodtype].bDrinkPoints * percentualsize * conditionmodifier );
@@ -240,17 +264,14 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, B
else if ( (*pObject)[0]->data.sObjectFlag & INFECTED && gGameExternalOptions.fDiseaseContaminatesItems )
pSoldier->Infect( 0 );
// now remove a portion of the food item (or the whole item altogether)
UINT16 ptsconsumed = UseKitPoints( pObject, Food[foodtype].ubPortionSize, pSoldier );
INT32 sBPAdjustment = 0;
// if the food is more of a drink, we also restore breath points
if ( Food[foodtype].bDrinkPoints > Food[foodtype].bFoodPoints )
{
sBPAdjustment = 2 * ptsconsumed * -(100 - pSoldier->bBreath);
sBPAdjustment = 2 * usPointsToUse * -(100 - pSoldier->bBreath);
}
DeductPoints( pSoldier, APBPConstants[type], sBPAdjustment );
DeductPoints( pSoldier, 0, sBPAdjustment );
// let it be known that we are eating
if ( pSoldier->bTeam == gbPlayerNum && gGameExternalOptions.fFoodEatingSounds )
@@ -370,7 +391,7 @@ void HourlyFoodSituationUpdate( SOLDIERTYPE *pSoldier )
INT8 sectortemperaturemod = SectorTemperature( 0, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
// if we are heat intolerant, increase modifier
if ( sectortemperaturemod > 0 && (gMercProfiles[ pSoldier->ubProfile ].bDisability == HEAT_INTOLERANT || MercUnderTheInfluence(pSoldier, DRUG_TYPE_HEATINTOLERANT) ) )
if ( sectortemperaturemod > 0 && DoesMercHaveDisability( pSoldier, HEAT_INTOLERANT ) )
++sectortemperaturemod;
FLOAT temperaturemodifier = (FLOAT)(3 + sectortemperaturemod)/3;
@@ -648,7 +669,7 @@ void EatFromInventory( SOLDIERTYPE *pSoldier, BOOLEAN fcanteensonly )
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ...
{
// ... if Item exists and is food ...
if (pSoldier->inv[bLoop].exists() == true && Item[pSoldier->inv[bLoop].usItem].foodtype > 0 )
if ( pSoldier->inv[bLoop].exists() && Item[pSoldier->inv[bLoop].usItem].foodtype )
{
OBJECTTYPE * pObj = &(pSoldier->inv[bLoop]); // ... get pointer for this item ...
@@ -680,14 +701,9 @@ void EatFromInventory( SOLDIERTYPE *pSoldier, BOOLEAN fcanteensonly )
// if we're thirsty or hungry, and this is nutritious, consume it
if ( ( pSoldier->bDrinkLevel < FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold && Food[foodtype].bDrinkPoints > 0 ) || ( pSoldier->bFoodLevel < FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold && Food[foodtype].bFoodPoints > 0 ) )
{
while ( (*pObj)[0]->data.objectStatus > 1 )
// cannot reject to eat this, we chose to eat this ourself!
while ( (*pObj)[0]->data.objectStatus > 1 && ApplyConsumable( pSoldier, pObj, TRUE, FALSE ) )
{
// if food is also a drug, ApplyDrugs will also call ApplyFood
if ( Item[pObj->usItem].drugtype > 0 )
ApplyDrugs( pSoldier, pObj );
else
ApplyFood( pSoldier, pObj, TRUE, FALSE ); // cannot reject to eat this, we chose to eat this ourself!
// if we're full, finish
if ( pSoldier->bFoodLevel > FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold && pSoldier->bDrinkLevel > FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold )
return;
@@ -701,7 +717,7 @@ void EatFromInventory( SOLDIERTYPE *pSoldier, BOOLEAN fcanteensonly )
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ...
{
// ... if Item exists and is food ...
if (pSoldier->inv[bLoop].exists() == true && Item[pSoldier->inv[bLoop].usItem].foodtype > 0 )
if ( pSoldier->inv[bLoop].exists() && Item[pSoldier->inv[bLoop].usItem].foodtype )
{
OBJECTTYPE * pObj = &(pSoldier->inv[bLoop]); // ... get pointer for this item ...
@@ -719,14 +735,9 @@ void EatFromInventory( SOLDIERTYPE *pSoldier, BOOLEAN fcanteensonly )
// if we're thirsty or hungry, and this is nutritious, consume it
if ( ( pSoldier->bDrinkLevel < FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold && Food[foodtype].bDrinkPoints > 0 ) || ( pSoldier->bFoodLevel < FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold && Food[foodtype].bFoodPoints > 0 ) )
{
while ( (*pObj)[0]->data.objectStatus > 1 )
// cannot reject to eat this, we chose to eat this ourself!
while ( (*pObj)[0]->data.objectStatus > 1 && ApplyConsumable( pSoldier, pObj, TRUE, FALSE ) )
{
// if food is also a drug, ApplyDrugs will also call ApplyFood
if ( Item[pObj->usItem].drugtype > 0 )
ApplyDrugs( pSoldier, pObj );
else
ApplyFood( pSoldier, pObj, TRUE, FALSE ); // cannot reject to eat this, we chose to eat this ourself!
// if we're full, finish
if ( ( pSoldier->bFoodLevel > FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold || Food[foodtype].bFoodPoints == 0 ) && ( pSoldier->bDrinkLevel > FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold|| Food[foodtype].bDrinkPoints == 0 ) )
return;
+3 -2
View File
@@ -52,7 +52,6 @@ typedef struct
CHAR16 szName[80]; // name of this food
INT32 bFoodPoints; // points that will be added to our drink level
INT32 bDrinkPoints; // points that will be added to our drink level
UINT16 ubPortionSize; // how much is 'eaten' as a portion (percentage)
FLOAT usDecayRate; // rate at which food decays
} FOODTYPE;
@@ -76,9 +75,11 @@ typedef enum
WATER_POISONOUS // there is water, but it is poisoned (swamps and polluted sectors)
} FoodSectorWaterSupply;
BOOLEAN DoesSoldierRefuseToEat( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj );
// eat a food object. if fForce = FALSE, the soldier can reject to eat this once
// if fForceFromDrugs = TRUE, we HAVE to eat this, because we already got the effects from the ApplyDrugs-function (item is both drug and food)
BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, BOOLEAN fForceFromDrugs );
BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, UINT16 usPointsToUse );
void GetFoodSituation( SOLDIERTYPE *pSoldier, UINT8* pFoodSituation, UINT8* pWaterSituation );
void FoodMaxMoraleModifiy( SOLDIERTYPE *pSoldier, UINT8* pubMaxMorale );
+2 -2
View File
@@ -474,7 +474,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
{
// Flugente: drugs can temporarily cause a merc to go psycho
if ( (pSoldier->ubProfile != NO_PROFILE) && ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) )
if ( DoesMercHaveDisability( pSoldier, PSYCHO ) )
{
// psychos might possibly switch to burst if they can
// Changed by ADB, rev 1513
@@ -549,7 +549,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
// SANDRO - changed Random to PreRandom to avoid save-load mania
// Flugente: drugs can temporarily cause a merc to go psycho
if((pSoldier->ubProfile != NO_PROFILE) && ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) && PreRandom(100) < 20)
if ( DoesMercHaveDisability( pSoldier, PSYCHO ) && PreRandom( 100 ) < 20 )
{
chanceToMisfire = diceSides;
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 26 ], pSoldier->GetName() );
+8 -8
View File
@@ -2571,7 +2571,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// ALCOHOL
if (Item[ gpItemDescObject->usItem ].alcohol)
if ( Item[gpItemDescObject->usItem].alcohol > 0.0f )
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 22 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 22 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -4090,7 +4090,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
cnt++;
}
////////////////////// PORTION SIZE
if ( Food[foodtype].ubPortionSize != 0 )
if ( Item[gpItemDescObject->usItem].usPortionSize != 0 )
{
if (cnt >= sFirstLine && cnt < sLastLine)
{
@@ -5769,8 +5769,8 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject )
}
cnt++;
}
if ( ( Food[Item[gpItemDescObject->usItem].foodtype].ubPortionSize > 0 ) ||
( fComparisonMode && Food[Item[gpComparedItemDescObject->usItem].foodtype].ubPortionSize > 0 ) )
if ( (Item[gpItemDescObject->usItem].usPortionSize > 0) ||
(fComparisonMode && Item[gpComparedItemDescObject->usItem].usPortionSize > 0) )
{
//////////////////// PORTION SIZE
if (cnt >= sFirstLine && cnt < sLastLine)
@@ -6129,8 +6129,8 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
}
//////////////////// ALCOHOL
if ( ( Item[ gpItemDescObject->usItem ].alcohol ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].alcohol ) )
if ( (Item[gpItemDescObject->usItem].alcohol > 0.0f) ||
(fComparisonMode && Item[gpComparedItemDescObject->usItem].alcohol > 0.0f) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 22, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
@@ -14057,10 +14057,10 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
cnt++;
}
////////////////////////// PORTION SIZE
iModifier[0] = Food[fFoodtype].ubPortionSize;
iModifier[0] = Item[gpItemDescObject->usItem].usPortionSize;
if( fComparisonMode )
{
iComparedModifier[0] = Food[fComparedFoodtype].ubPortionSize;
iComparedModifier[0] = Item[gpItemDescObject->usItem].usPortionSize;
iModifier[0] = iComparedModifier[0] - iModifier[0];
}
sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+1 -1
View File
@@ -2810,7 +2810,7 @@ BOOLEAN CompatibleItemForApplyingOnMerc( OBJECTTYPE *pTestObject )
// ATE: Would be nice to have flag here to check for these types....
if ( Item[usItem].camouflagekit || usItem == ADRENALINE_BOOSTER || usItem == REGEN_BOOSTER ||
usItem == SYRINGE_3 || usItem == SYRINGE_4 || usItem == SYRINGE_5 ||
Item[usItem].alcohol || Item[usItem].canteen || usItem == JAR_ELIXIR || (usItem == 1022 && gGameExternalOptions.fCamoRemoving) ) // Added rag usable on self - SANDRO
Item[usItem].alcohol > 0.0f || Item[usItem].canteen || usItem == JAR_ELIXIR || (usItem == 1022 && gGameExternalOptions.fCamoRemoving) ) // Added rag usable on self - SANDRO
{
return( TRUE );
}
+8 -58
View File
@@ -2766,19 +2766,19 @@ void RenderSMPanel( BOOLEAN *pfDirty )
mprintf( SM_CAMMO_PERCENT_X, SM_CAMMO_PERCENT_Y, L"%%" );
#endif
UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeAgilityTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & AGIL_INCREASE? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_AGILITY] > 0 )) ? TRUE : FALSE), MercUnderTheInfluence(gpSMCurrentMerc, DRUG_TYPE_AGILITY)); // SANDRO
UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeAgilityTime, (BOOLEAN)(gpSMCurrentMerc->usValueGoneUp & AGIL_INCREASE ? TRUE : FALSE), (BOOLEAN)((gGameOptions.fNewTraitSystem && (gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_AGILITY] > 0)) ? TRUE : FALSE), gpSMCurrentMerc->bExtraAgility != 0 ); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bAgility + gpSMCurrentMerc->bExtraAgility );
FindFontRightCoordinates(SM_AGI_X, SM_AGI_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeDexterityTime,( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & DEX_INCREASE? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_DEXTERITY] > 0 )) ? TRUE : FALSE), MercUnderTheInfluence(gpSMCurrentMerc, DRUG_TYPE_DEXTERITY)); // SANDRO
UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeDexterityTime, (BOOLEAN)(gpSMCurrentMerc->usValueGoneUp & DEX_INCREASE ? TRUE : FALSE), (BOOLEAN)((gGameOptions.fNewTraitSystem && (gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_DEXTERITY] > 0)) ? TRUE : FALSE), gpSMCurrentMerc->bExtraDexterity != 0 ); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bDexterity + gpSMCurrentMerc->bExtraDexterity );
FindFontRightCoordinates(SM_DEX_X, SM_DEX_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeStrengthTime, ( BOOLEAN )( gpSMCurrentMerc->usValueGoneUp & STRENGTH_INCREASE?TRUE: FALSE ), ( BOOLEAN ) ( (( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_STRENGTH] > 0 )) || (gGameOptions.fFoodSystem && gpSMCurrentMerc->usStarveDamageStrength > 0) ) ? TRUE : FALSE), MercUnderTheInfluence(gpSMCurrentMerc, DRUG_TYPE_STRENGTH)); // SANDRO
UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeStrengthTime, (BOOLEAN)(gpSMCurrentMerc->usValueGoneUp & STRENGTH_INCREASE ? TRUE : FALSE), (BOOLEAN)(((gGameOptions.fNewTraitSystem && (gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_STRENGTH] > 0)) || (gGameOptions.fFoodSystem && gpSMCurrentMerc->usStarveDamageStrength > 0)) ? TRUE : FALSE), gpSMCurrentMerc->bExtraStrength != 0 ); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bStrength + gpSMCurrentMerc->bExtraStrength );
FindFontRightCoordinates(SM_STR_X, SM_STR_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
@@ -2790,7 +2790,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
FindFontRightCoordinates(SM_CHAR_X, SM_CHAR_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeWisdomTime,( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & WIS_INCREASE? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_WISDOM] > 0 )) ? TRUE : FALSE), MercUnderTheInfluence(gpSMCurrentMerc, DRUG_TYPE_WISDOM)); // SANDRO
UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeWisdomTime, (BOOLEAN)(gpSMCurrentMerc->usValueGoneUp & WIS_INCREASE ? TRUE : FALSE), (BOOLEAN)((gGameOptions.fNewTraitSystem && (gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_WISDOM] > 0)) ? TRUE : FALSE), gpSMCurrentMerc->bExtraWisdom != 0 ); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bWisdom + gpSMCurrentMerc->bExtraWisdom );
FindFontRightCoordinates(SM_WIS_X, SM_WIS_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
@@ -3093,7 +3093,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
}
else
{
if ( MercUnderTheInfluence( gpSMCurrentMerc ) )
if ( MercDruggedOrDrunk( gpSMCurrentMerc ) )
{
SetFontBackground( FONT_MCOLOR_BLACK );
//SetFontForeground( FONT_MCOLOR_LTBLUE );
@@ -3316,50 +3316,12 @@ void SMInvClickCamoCallback( MOUSE_REGION * pRegion, INT32 iReason )
// If we do not have an item in hand, start moving it
if ( gpItemPointer )
{
BOOLEAN fGoodAPs = FALSE;
BOOLEAN fDoSound = FALSE;
// We are doing this ourselve, continue
if ( gpSMCurrentMerc->stats.bLife >= CONSCIOUSNESS )
{
// Try to apply camo....
if ( ApplyCammo( gpSMCurrentMerc, gpItemPointer, &fGoodAPs ) )
if ( ApplyConsumable( gpSMCurrentMerc, gpItemPointer, FALSE, TRUE ) )
{
if ( fGoodAPs )
{
fDoSound = TRUE;
// WANNE: We should only delete the face, if there was a camo we applied.
// This should fix the bug and crashes with missing faces
if (gGameExternalOptions.fShowCamouflageFaces )
{
// Flugente: refresh face regardless of result of SetCamoFace(), otherwise applying a rag will not clean the picture
SetCamoFace( gpSMCurrentMerc );
DeleteSoldierFace( gpSMCurrentMerc );// remove face
gpSMCurrentMerc->iFaceIndex = InitSoldierFace( gpSMCurrentMerc );// create new face
}
}
}
else if ( !gGameOptions.fFoodSystem && ApplyCanteen( gpSMCurrentMerc, gpItemPointer, &fGoodAPs, TRUE ) )
{
;
}
else if ( ApplyElixir( gpSMCurrentMerc, gpItemPointer, &fGoodAPs ) )
{
fDoSound = TRUE;
}
else if ( ApplyDrugs( gpSMCurrentMerc, gpItemPointer ) )
{
fGoodAPs = TRUE;
fDoSound = TRUE;
}
else if ( gGameOptions.fFoodSystem && ApplyFood( gpSMCurrentMerc, gpItemPointer, FALSE, FALSE ) )
{
fGoodAPs = TRUE;
}
else if ( ApplyClothes( gpSMCurrentMerc, gpItemPointer ) )
{
fGoodAPs = TRUE;
}
else
{
@@ -3375,18 +3337,6 @@ void SMInvClickCamoCallback( MOUSE_REGION * pRegion, INT32 iReason )
gbCompatibleApplyItem = FALSE;
EndItemPointer( );
}
if ( fGoodAPs )
{
// Dirty
fInterfacePanelDirty = DIRTYLEVEL2;
}
if ( fDoSound )
{
// Say OK acknowledge....
gpSMCurrentMerc->DoMercBattleSound( BATTLE_SOUND_COOL1 );
}
}
}
}
@@ -5688,7 +5638,7 @@ void RenderTEAMPanel( BOOLEAN fDirty )
}
else
{
if ( MercUnderTheInfluence( pSoldier ) )
if ( MercDruggedOrDrunk( pSoldier ) )
{
SetFontBackground( FONT_MCOLOR_BLACK );
//SetFontForeground( FONT_MCOLOR_LTBLUE );
@@ -7085,7 +7035,7 @@ void CleanUpStack( OBJECTTYPE * pObj, OBJECTTYPE * pCursorObj )
{
INT16 bMaxPoints;
if ( !(Item[ pObj->usItem ].usItemClass & IC_AMMO || Item[ pObj->usItem ].usItemClass & IC_KIT || Item[ pObj->usItem ].usItemClass & IC_MEDKIT || Item[pObj->usItem].canteen || Item[pObj->usItem].gascan || Item[pObj->usItem].alcohol ) )
if ( !(Item[pObj->usItem].usItemClass & IC_AMMO || Item[pObj->usItem].usItemClass & IC_KIT || Item[pObj->usItem].usItemClass & IC_MEDKIT || Item[pObj->usItem].canteen || Item[pObj->usItem].gascan || Item[pObj->usItem].alcohol > 0.0f) )
{
return;
}
+3 -2
View File
@@ -191,8 +191,9 @@ enum {
BG_PERC_DISEASE_TREAT,
BG_TRACKER_ABILITY,
BG_AMBUSH_RADIUS,
BG_DISLIKEBG, // dislike any other background that has the negative of this value set
BG_SMOKERTYPE, // 0: doesnt care about smoking 1: will consume cigarettes, dislikes non-smokers 2: will refuse to smoke, dislikes smokers
BG_MAX,
};
@@ -204,7 +205,7 @@ typedef struct
CHAR16 szShortName[20]; // abbreviated name for laptop display
CHAR16 szDescription[256]; // description of background, should explain the abilities
UINT64 uiFlags; // this flagmask defines what speial properties this background has (on/off behaviour)
UINT64 uiFlags; // this flagmask defines what special properties this background has (on/off behaviour)
INT16 value[BG_MAX]; // property values
} BACKGROUND_VALUES;
+4 -1
View File
@@ -1047,7 +1047,7 @@ typedef struct
BOOLEAN camouflagekit;
BOOLEAN locksmithkit;
BOOLEAN mine;
BOOLEAN alcohol;
FLOAT alcohol;
BOOLEAN hardware;
BOOLEAN medical;
BOOLEAN gascan;
@@ -1170,6 +1170,9 @@ typedef struct
INT16 sBackpackWeightModifier; //modifier to weight calculation to climb.
BOOLEAN fAllowClimbing; //does item allow climbing while wearing it
BOOLEAN cigarette; // Flugenete: this item can be smoked
UINT8 usPortionSize; // Flugente: for consumables: how much of this item is consumed at once
} INVTYPE;
+113 -179
View File
@@ -1253,7 +1253,9 @@ std::map<UINT8,popupDef> LBEPocketPopup;
// { /* Knife Pocket */ 5, 0, 1, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }
//};
DRUGTYPE Drug[DRUG_TYPE_MAX];
//DRUGTYPE Drug[DRUG_TYPE_MAX];
DRUG NewDrug[NEW_DRUGS_MAX];
FOODTYPE Food[FOOD_TYPE_MAX];
@@ -9363,57 +9365,37 @@ void WaterDamage( SOLDIERTYPE *pSoldier )
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
}
BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAPs, BOOLEAN fUseAPs )
BOOLEAN ApplyCamo( SOLDIERTYPE * pSoldier, UINT16 usItem, UINT16& usrPointsToUse )
{
// Added - SANDRO
INT8 bPointsToUse;
UINT16 usTotalKitPoints;
UINT16 iRemainingCamoAfterRemoving;
(*pfGoodAPs) = TRUE;
if (pObj->exists() == false)
return( FALSE );
INT8 bPointsToUse;
UINT16 iRemainingCamoAfterRemoving;
//////////////////////////////////////////////////////////////////////////////
// added possibility to remove all camo by using a rag on self - SANDRO
if ( HasItemFlag(pObj->usItem, CAMO_REMOVAL) && gGameExternalOptions.fCamoRemoving)
if ( HasItemFlag( usItem, CAMO_REMOVAL ) && gGameExternalOptions.fCamoRemoving )
{
if ( fUseAPs && !EnoughPoints( pSoldier, (APBPConstants[AP_CAMOFLAGE]/2), 0, TRUE ) )
{
(*pfGoodAPs) = FALSE;
return( TRUE );
}
// 100 should be enough. The third value "0" means we will remove all types of camo
ReduceCamoFromSoldier( pSoldier, 100, 0 );
// damage the rag :) - actually you would need to flag it damagable in the items.XML
DamageItem( pObj, 22, FALSE );
if ( fUseAPs )
DeductPoints( pSoldier, (APBPConstants[AP_CAMOFLAGE] / 2), 0 );
usrPointsToUse = min( 22, usrPointsToUse );
// Reload palettes....
if ( pSoldier->bInSector )
{
pSoldier->CreateSoldierPalettes( );
}
return( TRUE );
}
else if ( !Item[pObj->usItem].camouflagekit )
else if ( !Item[usItem].camouflagekit )
{
return( FALSE );
}
//////////////////////////////////////////////////////////////////////////////
if ( fUseAPs && !EnoughPoints( pSoldier, APBPConstants[AP_CAMOFLAGE], 0, TRUE ) )
{
(*pfGoodAPs) = FALSE;
return( TRUE );
}
usTotalKitPoints = TotalPoints( pObj );
if (usTotalKitPoints == 0)
if ( usrPointsToUse == 0 )
{
// HUH???
return( FALSE );
@@ -9426,26 +9408,25 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP
if (gGameExternalOptions.fCamoRemoving)
{
int totalCamo = pSoldier->bCamo + pSoldier->urbanCamo + pSoldier->desertCamo + pSoldier->snowCamo;
// First, check if we have an item with major JUNGLE camobonus
if ( (Item[pObj->usItem].camobonus > Item[pObj->usItem].urbanCamobonus) &&
(Item[pObj->usItem].camobonus > Item[pObj->usItem].desertCamobonus) &&
(Item[pObj->usItem].camobonus > Item[pObj->usItem].snowCamobonus) )
if ( (Item[usItem].camobonus > Item[usItem].urbanCamobonus) &&
(Item[usItem].camobonus > Item[usItem].desertCamobonus) &&
(Item[usItem].camobonus > Item[usItem].snowCamobonus) )
{
if ( pSoldier->bCamo >= gGameExternalOptions.bCamoKitArea || Item[pObj->usItem].camobonus == 0 )
if ( pSoldier->bCamo >= gGameExternalOptions.bCamoKitArea || Item[usItem].camobonus == 0 )
return( FALSE );
// determine how much we can add
bPointsToUse = __max( 0, ( gGameExternalOptions.bCamoKitArea - pSoldier->bCamo ) );
// check how much of the kit we need for that
bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[pObj->usItem].camobonus / 100.0 ) );
bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[usItem].camobonus / 100.0 ) );
// limit to what we have in the kit
bPointsToUse = __min( bPointsToUse, usTotalKitPoints );
bPointsToUse = __min( bPointsToUse, usrPointsToUse );
// determine how much we will add
int iJungleCamoAdded = (int)(Item[pObj->usItem].camobonus * bPointsToUse / 100 );
int iJungleCamoAdded = (int)(Item[usItem].camobonus * bPointsToUse / 100 );
// if we have already too much different camo on ourselves, reduce some or all
if ( (totalCamo + iJungleCamoAdded) > gGameExternalOptions.bCamoKitArea )
@@ -9471,26 +9452,27 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP
{
pSoldier->bCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->bCamo + iJungleCamoAdded );
}
// update with amount that we really used
bPointsToUse = ( (FLOAT)iJungleCamoAdded / ( (FLOAT)Item[pObj->usItem].camobonus / 100.0 ) );
bPointsToUse = ( (FLOAT)iJungleCamoAdded / ( (FLOAT)Item[usItem].camobonus / 100.0 ) );
}
// Second, check if we have an item with major URBAN camobonus
else if ( (Item[pObj->usItem].urbanCamobonus > Item[pObj->usItem].camobonus) &&
(Item[pObj->usItem].urbanCamobonus > Item[pObj->usItem].desertCamobonus) &&
(Item[pObj->usItem].urbanCamobonus > Item[pObj->usItem].snowCamobonus) )
else if ( (Item[usItem].urbanCamobonus > Item[usItem].camobonus) &&
(Item[usItem].urbanCamobonus > Item[usItem].desertCamobonus) &&
(Item[usItem].urbanCamobonus > Item[usItem].snowCamobonus) )
{
if ( pSoldier->urbanCamo >= gGameExternalOptions.bCamoKitArea || Item[pObj->usItem].urbanCamobonus == 0 )
if ( pSoldier->urbanCamo >= gGameExternalOptions.bCamoKitArea || Item[usItem].urbanCamobonus == 0 )
return( FALSE );
// determine how much we can add
bPointsToUse = __max( 0, ( gGameExternalOptions.bCamoKitArea - pSoldier->urbanCamo ) );
// check how much of the kit we need for that
bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[pObj->usItem].urbanCamobonus / 100.0 ) );
bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[usItem].urbanCamobonus / 100.0 ) );
// limit to what we have in the kit
bPointsToUse = __min( bPointsToUse, usTotalKitPoints );
bPointsToUse = __min( bPointsToUse, usrPointsToUse );
// determine how much we will add
int iUrbanCamoAdded = (int)(Item[pObj->usItem].urbanCamobonus * bPointsToUse / 100 );
int iUrbanCamoAdded = (int)(Item[usItem].urbanCamobonus * bPointsToUse / 100 );
// if we have already too much different camo on ourselves, reduce some or all
if ( (totalCamo + iUrbanCamoAdded) > gGameExternalOptions.bCamoKitArea )
@@ -9517,25 +9499,25 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP
pSoldier->urbanCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->urbanCamo + iUrbanCamoAdded );
}
// update with amount that we really used
bPointsToUse = ( (FLOAT)iUrbanCamoAdded / ( (FLOAT)Item[pObj->usItem].urbanCamobonus / 100.0 ) );
bPointsToUse = ( (FLOAT)iUrbanCamoAdded / ( (FLOAT)Item[usItem].urbanCamobonus / 100.0 ) );
}
// Third, check if we have an item with major DESERT camobonus
else if ( (Item[pObj->usItem].desertCamobonus > Item[pObj->usItem].camobonus) &&
(Item[pObj->usItem].desertCamobonus > Item[pObj->usItem].urbanCamobonus) &&
(Item[pObj->usItem].desertCamobonus > Item[pObj->usItem].snowCamobonus) )
else if ( (Item[usItem].desertCamobonus > Item[usItem].camobonus) &&
(Item[usItem].desertCamobonus > Item[usItem].urbanCamobonus) &&
(Item[usItem].desertCamobonus > Item[usItem].snowCamobonus) )
{
if ( pSoldier->desertCamo >= gGameExternalOptions.bCamoKitArea || Item[pObj->usItem].desertCamobonus == 0 )
if ( pSoldier->desertCamo >= gGameExternalOptions.bCamoKitArea || Item[usItem].desertCamobonus == 0 )
return( FALSE );
// determine how much we can add
bPointsToUse = __max( 0, ( gGameExternalOptions.bCamoKitArea - pSoldier->desertCamo ) );
// check how much of the kit we need for that
bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[pObj->usItem].desertCamobonus / 100.0 ) );
bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[usItem].desertCamobonus / 100.0 ) );
// limit to what we have in the kit
bPointsToUse = __min( bPointsToUse, usTotalKitPoints );
bPointsToUse = __min( bPointsToUse, usrPointsToUse );
// determine how much we will add
int iDesertCamoAdded = (int)(Item[pObj->usItem].desertCamobonus * bPointsToUse / 100 );
int iDesertCamoAdded = (int)(Item[usItem].desertCamobonus * bPointsToUse / 100 );
// if we have already too much different camo on ourselves, reduce some or all
if ( (totalCamo + iDesertCamoAdded) > gGameExternalOptions.bCamoKitArea )
@@ -9562,25 +9544,25 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP
pSoldier->desertCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->desertCamo + iDesertCamoAdded );
}
// update with amount that we really used
bPointsToUse = ( (FLOAT)iDesertCamoAdded / ( (FLOAT)Item[pObj->usItem].desertCamobonus / 100.0 ) );
bPointsToUse = ( (FLOAT)iDesertCamoAdded / ( (FLOAT)Item[usItem].desertCamobonus / 100.0 ) );
}
// Fourth, check if we have an item with major SNOW camobonus
else if ( (Item[pObj->usItem].snowCamobonus > Item[pObj->usItem].camobonus) &&
(Item[pObj->usItem].snowCamobonus > Item[pObj->usItem].urbanCamobonus) &&
(Item[pObj->usItem].snowCamobonus > Item[pObj->usItem].desertCamobonus) )
else if ( (Item[usItem].snowCamobonus > Item[usItem].camobonus) &&
(Item[usItem].snowCamobonus > Item[usItem].urbanCamobonus) &&
(Item[usItem].snowCamobonus > Item[usItem].desertCamobonus) )
{
if ( pSoldier->snowCamo >= gGameExternalOptions.bCamoKitArea || Item[pObj->usItem].snowCamobonus == 0 )
if ( pSoldier->snowCamo >= gGameExternalOptions.bCamoKitArea || Item[usItem].snowCamobonus == 0 )
return( FALSE );
// determine how much we can add
bPointsToUse = __max( 0, ( gGameExternalOptions.bCamoKitArea - pSoldier->snowCamo ) );
// check how much of the kit we need for that
bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[pObj->usItem].snowCamobonus / 100.0 ) );
bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[usItem].snowCamobonus / 100.0 ) );
// limit to what we have in the kit
bPointsToUse = __min( bPointsToUse, usTotalKitPoints );
bPointsToUse = __min( bPointsToUse, usrPointsToUse );
// determine how much we will add
int iSnowCamoAdded = (int)(Item[pObj->usItem].snowCamobonus * bPointsToUse / 100 );
int iSnowCamoAdded = (int)(Item[usItem].snowCamobonus * bPointsToUse / 100 );
// if we have already too much different camo on ourselves, reduce some or all
if ( (totalCamo + iSnowCamoAdded) > gGameExternalOptions.bCamoKitArea )
@@ -9607,7 +9589,7 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP
pSoldier->snowCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->snowCamo + iSnowCamoAdded );
}
// update with amount that we really used
bPointsToUse = ( (FLOAT)iSnowCamoAdded / ( (FLOAT)Item[pObj->usItem].snowCamobonus / 100.0 ) );
bPointsToUse = ( (FLOAT)iSnowCamoAdded / ( (FLOAT)Item[usItem].snowCamobonus / 100.0 ) );
}
else // the item has no major camo, return
return( FALSE );
@@ -9627,13 +9609,13 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP
}
bPointsToUse = (gGameExternalOptions.bCamoKitArea - iKitCamo);
bPointsToUse = __min( bPointsToUse, usTotalKitPoints );
bPointsToUse = __min( bPointsToUse, usrPointsToUse );
//figure out proportions of each to be applied, one item can theoretically have more than one camouflage type this way
int urban = (int)(Item[pObj->usItem].urbanCamobonus * bPointsToUse / 100 );
int jungle = (int)(Item[pObj->usItem].camobonus * bPointsToUse / 100 );
int desert = (int)(Item[pObj->usItem].desertCamobonus * bPointsToUse / 100 );
int snow = (int)(Item[pObj->usItem].snowCamobonus * bPointsToUse / 100 );
int urban = (int)(Item[usItem].urbanCamobonus * bPointsToUse / 100 );
int jungle = (int)(Item[usItem].camobonus * bPointsToUse / 100 );
int desert = (int)(Item[usItem].desertCamobonus * bPointsToUse / 100 );
int snow = (int)(Item[usItem].snowCamobonus * bPointsToUse / 100 );
pSoldier->bCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->bCamo + jungle );
pSoldier->urbanCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->urbanCamo + urban );
@@ -9641,10 +9623,7 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP
pSoldier->snowCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->snowCamo + snow );
}
UseKitPoints( pObj, bPointsToUse, pSoldier );
if ( fUseAPs )
DeductPoints( pSoldier, APBPConstants[AP_CAMOFLAGE], 0 );
usrPointsToUse = bPointsToUse;
// Reload palettes....
if ( pSoldier->bInSector )
@@ -9655,8 +9634,62 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP
return( TRUE );
}
BOOLEAN ApplyCanteen( SOLDIERTYPE * pSoldier, UINT16 usItem, UINT16 usPointsToUse )
{
if ( !Item[usItem].canteen )
{
return(FALSE);
}
if ( usPointsToUse == 0 )
{
// HUH???
return(FALSE);
}
if ( pSoldier->bTeam == gbPlayerNum )
{
if ( gMercProfiles[pSoldier->ubProfile].bSex == MALE )
{
PlayJA2Sample( DRINK_CANTEEN_MALE, RATE_11025, MIDVOLUME, 1, MIDDLEPAN );
}
else
{
PlayJA2Sample( DRINK_CANTEEN_FEMALE, RATE_11025, MIDVOLUME, 1, MIDDLEPAN );
}
}
// CJC Feb 9. Canteens don't seem effective enough, so doubled return from them
DeductPoints( pSoldier, 0, (INT16)(2 * usPointsToUse * -(100 - pSoldier->bBreath)) );
return(TRUE);
}
#define MAX_HUMAN_CREATURE_SMELL (NORMAL_HUMAN_SMELL_STRENGTH - 1)
BOOLEAN ApplyElixir( SOLDIERTYPE * pSoldier, UINT16 usItem, UINT16& usrPointsToUse )
{
if ( usItem != JAR_ELIXIR )
{
return(FALSE);
}
if ( usrPointsToUse == 0 )
{
// HUH???
return(FALSE);
}
INT16 sPointsToUse = (MAX_HUMAN_CREATURE_SMELL - pSoldier->aiData.bMonsterSmell) * 2;
usrPointsToUse = __min( sPointsToUse, usrPointsToUse );
pSoldier->aiData.bMonsterSmell += sPointsToUse / 2;
return(TRUE);
}
// Flugente: apply clothes, and eventually disguise
BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN fUseAPs )
BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, UINT16 usItem, UINT16 usPointsToUse )
{
// this will only work with the new trait system
if (!gGameOptions.fNewTraitSystem)
@@ -9665,20 +9698,13 @@ BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN fUseAPs
return FALSE;
}
if ( !pSoldier || pObj->exists() == false )
if ( !pSoldier )
return( FALSE );
UINT8 skilllevel = NUM_SKILL_TRAITS( pSoldier, COVERT_NT );
INT16 apcost = (APBPConstants[AP_DISGUISE] * ( 100 - gSkillTraitValues.sCODisguiseAPReduction * skilllevel))/100;
if ( fUseAPs && !EnoughPoints( pSoldier, apcost, 0, TRUE ) )
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NOT_ENOUGH_APS] );
return( FALSE );
}
// determine clothes type
UINT32 clothestype = Item[pObj->usItem].clothestype;
UINT32 clothestype = Item[usItem].clothestype;
// if not a clothes item, nothing to see here
if ( clothestype == 0 || clothestype > CLOTHES_MAX )
@@ -9760,11 +9786,6 @@ BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN fUseAPs
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->SkinPal );
pSoldier->CreateSoldierPalettes();
UseKitPoints( pObj, 100, pSoldier );
if ( fUseAPs )
DeductPoints( pSoldier, apcost, 0 );
}
if ( pSoldier->usSoldierFlagMask & SOLDIER_NEW_VEST && pSoldier->usSoldierFlagMask & SOLDIER_NEW_PANTS )
@@ -9810,93 +9831,6 @@ BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN fUseAPs
return( TRUE );
}
BOOLEAN ApplyCanteen( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAPs, BOOLEAN fUseAPs )
{
INT16 sPointsToUse;
UINT16 usTotalKitPoints;
(*pfGoodAPs) = TRUE;
if (!Item[pObj->usItem].canteen || pObj->exists() == false)
{
return( FALSE );
}
usTotalKitPoints = TotalPoints( pObj );
if (usTotalKitPoints == 0)
{
// HUH???
return( FALSE );
}
if ( fUseAPs && !EnoughPoints( pSoldier, APBPConstants[AP_DRINK], 0, TRUE ) )
{
(*pfGoodAPs) = FALSE;
return( TRUE );
}
if ( pSoldier->bTeam == gbPlayerNum )
{
if ( gMercProfiles[ pSoldier->ubProfile ].bSex == MALE )
{
PlayJA2Sample( DRINK_CANTEEN_MALE, RATE_11025, MIDVOLUME, 1, MIDDLEPAN );
}
else
{
PlayJA2Sample( DRINK_CANTEEN_FEMALE, RATE_11025, MIDVOLUME, 1, MIDDLEPAN );
}
}
sPointsToUse = __min( 20, usTotalKitPoints );
// CJC Feb 9. Canteens don't seem effective enough, so doubled return from them
if ( fUseAPs )
DeductPoints( pSoldier, APBPConstants[AP_DRINK], (INT16) (2 * sPointsToUse * -(100 - pSoldier->bBreath) ) );
UseKitPoints( pObj, sPointsToUse, pSoldier );
return( TRUE );
}
#define MAX_HUMAN_CREATURE_SMELL (NORMAL_HUMAN_SMELL_STRENGTH - 1)
BOOLEAN ApplyElixir( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAPs )
{
INT16 sPointsToUse;
UINT16 usTotalKitPoints;
(*pfGoodAPs) = TRUE;
if (pObj->usItem != JAR_ELIXIR || pObj->exists() == false)
{
return( FALSE );
}
usTotalKitPoints = TotalPoints( pObj );
if (usTotalKitPoints == 0)
{
// HUH???
return( FALSE );
}
if (!EnoughPoints( pSoldier, APBPConstants[AP_CAMOFLAGE], 0, TRUE ) )
{
(*pfGoodAPs) = FALSE;
return( TRUE );
}
DeductPoints( pSoldier, APBPConstants[AP_CAMOFLAGE], 0 );
sPointsToUse = ( MAX_HUMAN_CREATURE_SMELL - pSoldier->aiData.bMonsterSmell ) * 2;
sPointsToUse = __min( sPointsToUse, usTotalKitPoints );
UseKitPoints( pObj, sPointsToUse, pSoldier );
pSoldier->aiData.bMonsterSmell += sPointsToUse / 2;
return( TRUE );
}
UINT32 ConvertProfileMoneyValueToObjectTypeMoneyValue( UINT8 ubStatus )
{
return( ubStatus * 50 );
@@ -11564,7 +11498,7 @@ INT16 GetTotalVisionRangeBonus( SOLDIERTYPE * pSoldier, UINT8 bLightLevel )
bonus += GetDayVisionRangeBonus(pSoldier, bLightLevel);
}
// Flugente: drugs can alter our sight
/*// Flugente: drugs can alter our sight
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_VISION ] )
{
bonus += 10;
@@ -11572,7 +11506,7 @@ INT16 GetTotalVisionRangeBonus( SOLDIERTYPE * pSoldier, UINT8 bLightLevel )
else if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_VISION ] )
{
bonus -= 10;
}
}*/
// Flugente: add sight range bonus due to disabilities, traits etc. (not equipment)
bonus += pSoldier->GetSightRangeBonus();
@@ -11713,11 +11647,11 @@ UINT8 GetPercentTunnelVision( SOLDIERTYPE * pSoldier )
}
}
// Flugente: drugs can alter our vision
/*// Flugente: drugs can alter our vision
if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_TUNNELVISION ] )
{
bonus = __min(100, bonus + 25);
}
} */
if ( !PTR_OURTEAM ) // Madd: adjust tunnel vision by difficulty level
bonus /= gGameOptions.ubDifficultyLevel;
+4 -5
View File
@@ -196,8 +196,10 @@ void WaterDamage( SOLDIERTYPE *pSoldier );
INT8 FindObj( SOLDIERTYPE * pSoldier, UINT16 usItem, INT8 bLower = 0, INT8 bUpper = NUM_INV_SLOTS );
BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAPs, BOOLEAN fUseAPs = TRUE );
BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN fUseAPs = TRUE ); // Flugente: apply clothes, and eventually disguise
BOOLEAN ApplyCamo( SOLDIERTYPE * pSoldier, UINT16 usItem, UINT16& usrPointsToUse );
BOOLEAN ApplyCanteen( SOLDIERTYPE * pSoldier, UINT16 usItem, UINT16 usPointsToUse );
BOOLEAN ApplyElixir( SOLDIERTYPE * pSoldier, UINT16 usItem, UINT16& usrPointsToUse );
BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, UINT16 usItem, UINT16 usPointsToUse ); // Flugente: apply clothes, and eventually disguise
UINT32 ConvertProfileMoneyValueToObjectTypeMoneyValue( UINT8 ubStatus );
UINT8 ConvertObjectTypeMoneyValueToProfileMoneyValue( UINT32 uiMoneyAmount );
@@ -212,9 +214,6 @@ UINT16 FindReplacementMagazineIfNecessary( UINT16 usOldGun, UINT16 usOldAmmo, UI
BOOLEAN DamageItemOnGround( OBJECTTYPE * pObject, INT32 sGridNo, INT8 bLevel, INT32 iDamage, UINT8 ubOwner );
BOOLEAN ApplyCanteen( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAPs, BOOLEAN fUseAPs = TRUE );
BOOLEAN ApplyElixir( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAPs );
BOOLEAN CompatibleFaceItem( UINT16 usItem1, UINT16 usItem2 );
UINT32 MoneySlotLimit( INT8 bSlot );
+35 -39
View File
@@ -165,23 +165,23 @@ BOOLEAN IsShowOffNearBy( SOLDIERTYPE * pSoldier ); // Added by SANDRO
INT8 GetMoraleModifier( SOLDIERTYPE * pSoldier )
{
INT8 morale = 0;
if (pSoldier->flags.uiStatusFlags & SOLDIER_PC)
{
if (pSoldier->aiData.bMorale > 50)
{
// give +1 at 55, +3 at 65, up to +5 at 95 and above
return( (pSoldier->aiData.bMorale - 45) / 10 );
morale = (pSoldier->aiData.bMorale - 45) / 10;
}
else
{
// give penalties down to -20 at 0 (-2 at 45, -4 by 40...)
return( (pSoldier->aiData.bMorale - 50) * 2 / 5 );
morale = (pSoldier->aiData.bMorale - 50) * 2 / 5;
}
}
else
{
INT8 morale = 0;
// use AI morale
switch( pSoldier->aiData.bAIMorale )
{
@@ -196,12 +196,12 @@ INT8 GetMoraleModifier( SOLDIERTYPE * pSoldier )
default:
morale = 0;
}
// Flugente: morale modifiers
morale = max(morale, morale * pSoldier->GetMoraleModifier());
return morale;
}
// Flugente: morale modifiers
morale = max( morale, morale * pSoldier->GetMoraleModifier( ) );
return morale;
}
void DecayTacticalMorale( SOLDIERTYPE * pSoldier )
@@ -259,19 +259,8 @@ void DecayTacticalMoraleModifiers( void )
{
continue;
}
// Flugente: drugs can temporarily cause a merc get a new disability
// therefore we change this routine
BOOLEAN isClaustrophobic = gMercProfiles[ pSoldier->ubProfile ].bDisability == CLAUSTROPHOBIC ? TRUE : FALSE;
BOOLEAN isNervous = gMercProfiles[ pSoldier->ubProfile ].bDisability == NERVOUS ? TRUE : FALSE;
if ( MercUnderTheInfluence(pSoldier, DRUG_TYPE_CLAUSTROPHOBIC) )
isClaustrophobic = TRUE;
if ( MercUnderTheInfluence(pSoldier, DRUG_TYPE_NERVOUS) )
isNervous = TRUE;
if ( isClaustrophobic )
if ( DoesMercHaveDisability( pSoldier, CLAUSTROPHOBIC ) )
{
if ( pSoldier->bSectorZ > 0 )
{
@@ -283,7 +272,7 @@ void DecayTacticalMoraleModifiers( void )
}
}
if ( isNervous )
if ( DoesMercHaveDisability( pSoldier, NERVOUS ) )
{
if ( pSoldier->aiData.bMorale < 50 )
{
@@ -396,9 +385,8 @@ void RefreshSoldierMorale( SOLDIERTYPE * pSoldier )
//iActualMorale = DEFAULT_MORALE + (INT32) pSoldier->aiData.bTeamMoraleMod + (INT32) pSoldier->aiData.bTacticalMoraleMod + (INT32) pSoldier->aiData.bStrategicMoraleMod + (INT32) (CurrentPlayerProgressPercentage() / 5);
iActualMorale = gMoraleSettings.ubDefaultMorale + (INT32) pSoldier->aiData.bTeamMoraleMod + (INT32) pSoldier->aiData.bTacticalMoraleMod + (INT32) pSoldier->aiData.bStrategicMoraleMod + (INT32) (CurrentPlayerProgressPercentage() / 5);
// ATE: Modify morale based on drugs....
iActualMorale += ( ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] * gMoraleSettings.sDrugAndAlcoholModifiers[DRUG_EFFECT_MORALE_MOD] ) / 100 );
iActualMorale += ( ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ALCOHOL ] * gMoraleSettings.sDrugAndAlcoholModifiers[ALCOHOL_EFFECT_MORALE_MOD] ) / 100 );
// Flugente: drug system has been redone
iActualMorale += pSoldier->newdrugs.size[DRUG_EFFECT_MORALE];
iActualMorale = __min( 100, iActualMorale );
iActualMorale = __max( 0, iActualMorale );
@@ -593,13 +581,14 @@ void UpdateSoldierMorale( SOLDIERTYPE * pSoldier, INT8 bMoraleEvent )
break;
}
}
// Check for character traits
if ( pProfile->bCharacterTrait == CHAR_TRAIT_OPTIMIST )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_OPTIMIST ) )
{
bMoraleMod += gMoraleSettings.bModifiers[MORALE_MODIFIER_OPTIMIST];//1;
}
// Fearless character does not suffer morale loss for these so much
else if( pProfile->bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_DAUNTLESS ) )
{
switch ( bMoraleEvent )
{
@@ -774,7 +763,7 @@ void HandleMoraleEvent( SOLDIERTYPE *pSoldier, INT8 bMoraleEvent, INT16 sMapX, I
HandleMoraleEventForSoldier( pTeamSoldier, MORALE_BATTLE_WON );
}
// SANDRO - Assertive people don't care about actions of others
else if ( !gGameOptions.fNewTraitSystem || gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait != CHAR_TRAIT_ASSERTIVE )
else if ( !gGameOptions.fNewTraitSystem || !DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_ASSERTIVE ) )
{
HandleMoraleEventForSoldier( pTeamSoldier, MORALE_HEARD_BATTLE_WON );
}
@@ -799,10 +788,11 @@ void HandleMoraleEvent( SOLDIERTYPE *pSoldier, INT8 bMoraleEvent, INT16 sMapX, I
if ( !HAS_SKILL_TRAIT( pTeamSoldier, COVERT_NT ) || ( (pTeamSoldier->usSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER)) == 0) )
{
// SANDRO - no penalty for pacifists to run away
if ( gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait != CHAR_TRAIT_PACIFIST )
if ( DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_PACIFIST ) )
HandleMoraleEventForSoldier( pTeamSoldier, MORALE_RAN_AWAY );
// Double morale drop for aggressive people
if ( gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
if ( DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_AGGRESSIVE ) )
HandleMoraleEventForSoldier( pTeamSoldier, MORALE_RAN_AWAY );
}
}
@@ -825,7 +815,7 @@ void HandleMoraleEvent( SOLDIERTYPE *pSoldier, INT8 bMoraleEvent, INT16 sMapX, I
}
}
// SANDRO - Assertive people don't care about actions of others
else if ( !gGameOptions.fNewTraitSystem || gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait != CHAR_TRAIT_ASSERTIVE )
else if ( !gGameOptions.fNewTraitSystem || !DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_ASSERTIVE ) )
{
HandleMoraleEventForSoldier( pTeamSoldier, MORALE_HEARD_BATTLE_LOST );
}
@@ -854,7 +844,7 @@ void HandleMoraleEvent( SOLDIERTYPE *pSoldier, INT8 bMoraleEvent, INT16 sMapX, I
if ( gGameOptions.fNewTraitSystem && bMoraleEvent != MORALE_DEIDRANNA_KILLED)
{
if ( !SOLDIER_IN_SECTOR( pTeamSoldier, sMapX, sMapY, bMapZ ) && ( gMoraleSettings.bValues[bMoraleEvent] > 0 ) && //( gbMoraleEvent[bMoraleEvent].bChange > 0 ) &&
gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_ASSERTIVE )
DoesMercHavePersonality( pTeamSoldier, CHAR_TRAIT_ASSERTIVE ) )
{
// No morale gain for assertive people from actions of others
}
@@ -1270,11 +1260,13 @@ void HourlyMoraleUpdate( void )
{
bTeamMoraleModChange = 0;
}
// SANDRO - morale is going down faster if not fighting for malicious characters
if ( gGameOptions.fNewTraitSystem && pProfile->bCharacterTrait == CHAR_TRAIT_MALICIOUS )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_MALICIOUS ) )
{
bTeamMoraleModChange += gMoraleSettings.bModifiers[MORALE_MODIFIER_MALICIOUS_HOURLY_DECAY];//-= 1;
}
pSoldier->aiData.bTeamMoraleMod += bTeamMoraleModChange;
pSoldier->aiData.bTeamMoraleMod = __min( pSoldier->aiData.bTeamMoraleMod, gMoraleSettings.bModifiers[MORALE_MOD_MAX] );
pSoldier->aiData.bTeamMoraleMod = __max( pSoldier->aiData.bTeamMoraleMod, -gMoraleSettings.bModifiers[MORALE_MOD_MAX] );
@@ -1567,18 +1559,22 @@ void RememberSnitchableEvent( UINT8 ubTargetProfile, UINT8 ubSecondaryTargetProf
SoldierRelation( pSoldier, pSnitch )*gSkillTraitValues.fSNTMercOpinionAboutSnitchBonusModifier +
SoldierRelation( pSnitch, pSoldier )*gSkillTraitValues.fSNTSnitchOpinionAboutMercBonusModifier +
gMercProfiles[ubSnitchProfile].bLeadership*gSkillTraitValues.fSNTSnitchLeadershipBonusModifer);
if ( pSoldier->bAssignment == pSnitch->bAssignment )
{
sSnitchingChance += gSkillTraitValues.bSNTSameAssignmentBonus;
}
if ( gMercProfiles[pSnitch->ubProfile].bCharacterTrait == CHAR_TRAIT_SOCIABLE )
if ( DoesMercHavePersonality( pSnitch, CHAR_TRAIT_SOCIABLE ) )
{
sSnitchingChance += gSkillTraitValues.bSNTSociableMercBonus;
}
if ( gMercProfiles[pSnitch->ubProfile].bCharacterTrait == CHAR_TRAIT_LONER )
if ( DoesMercHavePersonality( pSnitch, CHAR_TRAIT_LONER ) )
{
sSnitchingChance += gSkillTraitValues.bSNTLonerMercBonus;
}
if ( ubEventType == SNITCH_HATED_PERSON )
{
if ( gSkillTraitValues.bSNTMercOpinionAboutMercTreshold != HATED_OPINION )
@@ -1588,7 +1584,7 @@ void RememberSnitchableEvent( UINT8 ubTargetProfile, UINT8 ubSecondaryTargetProf
(FLOAT)(gSkillTraitValues.bSNTMercOpinionAboutMercTreshold - HATED_OPINION)));
}
}
if ( gMercProfiles[pSnitch->ubProfile].bDisability == DEAF )
if ( DoesMercHaveDisability( pSnitch, DEAF ) )
{
sSnitchingChance /= 2;
}
@@ -1686,13 +1682,13 @@ BOOLEAN IsShowOffNearBy( SOLDIERTYPE * pSoldier )
}
// Are we from our team an dalive?
if ( pTeammate->bTeam == pSoldier->bTeam && pTeammate->stats.bLife >= OKLIFE &&
gMercProfiles[ pTeammate->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF && PythSpacesAway( pSoldier->sGridNo, pTeammate->sGridNo ) <= 15)
DoesMercHavePersonality( pTeammate, CHAR_TRAIT_SHOWOFF ) && PythSpacesAway( pSoldier->sGridNo, pTeammate->sGridNo ) <= 15 )
{
if ( (pSoldier->ubBodyType <= STOCKYMALE && pTeammate->ubBodyType <= STOCKYMALE) ||
(pSoldier->ubBodyType == REGFEMALE && pTeammate->ubBodyType == REGFEMALE) )
{
// phlegmatic character can ignore one
if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_PHLEGMATIC && !fOneException)
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_PHLEGMATIC ) && !fOneException )
{
fOneException = TRUE;
}
+17 -31
View File
@@ -2463,7 +2463,7 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE
else
// ATE; First check for profile
// Forgetful guy might forget his path
if ( (pSoldier->bTeam == gbPlayerNum) && ( pSoldier->ubProfile != NO_PROFILE ) && gMercProfiles[pSoldier->ubProfile].bDisability == FORGETFUL )
if ( (pSoldier->bTeam == gbPlayerNum) && DoesMercHaveDisability( pSoldier, FORGETFUL ) )
{
if ( pSoldier->ubNumTilesMovesSinceLastForget < 255 )
{
@@ -3233,33 +3233,17 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF
// possibly say personality quote
if ( (pSoldier->bTeam == gbPlayerNum) && (pSoldier->ubProfile != NO_PROFILE && pSoldier->ubWhatKindOfMercAmI != MERC_TYPE__PLAYER_CHARACTER) && !( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_PERSONALITY) )
{
switch ( gMercProfiles[ pSoldier->ubProfile ].bDisability )
{
case PSYCHO:
if ( Random( 50 ) == 0 )
{
TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT );
pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY;
if ( DoesMercHaveDisability( pSoldier, PSYCHO ) )
{
if ( Random( 50 ) == 0 )
{
TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT );
pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY;
// Flugente: dynamic opinions
HandleDynamicOpinionChange( pSoldier, OPINIONEVENT_ANNOYINGDISABILITY, TRUE, TRUE );
}
break;
default:
// Flugente: drugs can temporarily cause a merc to go psycho
if ( MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) )
{
if ( Random( 50 ) == 0 )
{
TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT );
pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY;
// Flugente: dynamic opinions
HandleDynamicOpinionChange( pSoldier, OPINIONEVENT_ANNOYINGDISABILITY, TRUE, TRUE );
}
}
break;
}
// Flugente: dynamic opinions
HandleDynamicOpinionChange( pSoldier, OPINIONEVENT_ANNOYINGDISABILITY, TRUE, TRUE );
}
}
}
UpdateForContOverPortrait( pSoldier, TRUE );
@@ -8230,9 +8214,9 @@ INT8 CalcSuppressionTolerance( SOLDIERTYPE * pSoldier )
// SANDRO - check for character traits
if ( gGameOptions.fNewTraitSystem )
{
if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_INTELLECTUAL )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_INTELLECTUAL ) )
bTolerance += -2;
else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_DAUNTLESS ) )
bTolerance += 2;
}
else
@@ -10897,12 +10881,13 @@ INT8 CalcEffectiveShockLevel( SOLDIERTYPE * pSoldier )
{
bShockForCower = (INT8)((bShockForCower * (100 - gSkillTraitValues.ubSLFearResistance * NUM_SKILL_TRAITS( pSoldier, SQUADLEADER_NT )) /100) + 0.5);
}
// Check for character traits
if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_INTELLECTUAL )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_INTELLECTUAL ) )
{
bShockForCower = (INT8)((bShockForCower * 23 / 20 ) + 0.5); // +15% as shock
}
else if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_DAUNTLESS ) )
{
bShockForCower = (INT8)((bShockForCower * 17 / 20 ) + 0.5); // -15% as shock
}
@@ -10910,6 +10895,7 @@ INT8 CalcEffectiveShockLevel( SOLDIERTYPE * pSoldier )
// Flugente: personal fear resistance
bShockForCower = (INT8)((bShockForCower * (100 - pSoldier->GetFearResistanceBonus()) / 100 ) + 0.5);
}
return bShockForCower;
}
+8 -6
View File
@@ -1185,14 +1185,15 @@ INT32 AdjustBreathPts( SOLDIERTYPE * pSoldier , INT32 iBPCost )
{
sBreathFactor += 100;
}
// SANDRO - Less breath consumption for Primitive chars
if ( gGameOptions.fNewTraitSystem && gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_PRIMITIVE )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_PRIMITIVE ) )
{
sBreathFactor -= 15; // -15% breath consumption
}
// if a non-swimmer type is thrashing around in deep water
if ( (pSoldier->ubProfile != NO_PROFILE ) && (gMercProfiles[ pSoldier->ubProfile ].bDisability == NONSWIMMER) )
// if a non-swimmer type is thrashing around in deep water
if ( DoesMercHaveDisability( pSoldier, NONSWIMMER ) )
{
if ( pSoldier->usAnimState == DEEP_WATER_TRED || pSoldier->usAnimState == DEEP_WATER_SWIM)
{
@@ -1258,11 +1259,12 @@ void UnusedAPsToBreath( SOLDIERTYPE * pSoldier )
// Adjust for on drugs
HandleBPEffectDueToDrugs( pSoldier, &sBreathChange );
if ( sBreathChange > 0 )
// Flugente: why would we forbid losing breath in realtime?
/*if ( sBreathChange > 0 )
{
sBreathChange = 0;
}
else
}*/
if ( sBreathChange < 0 )
{
// We have a gain, now limit this depending on what we were doing...
// OK for RT, look at how many tiles we have moved, our last move anim
+9 -9
View File
@@ -199,12 +199,12 @@ INT8 EffectiveExpLevel( SOLDIERTYPE * pSoldier )
if (pSoldier->ubProfile != NO_PROFILE)
{
// Flugente: drugs can temporarily cause a merc to be claustrophobic
if ( ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == CLAUSTROPHOBIC) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_CLAUSTROPHOBIC) ) && pSoldier->bActive && pSoldier->bInSector && gbWorldSectorZ > 0)
if ( DoesMercHaveDisability( pSoldier, CLAUSTROPHOBIC ) && pSoldier->bActive && pSoldier->bInSector && gbWorldSectorZ > 0 )
{
// claustrophobic!
iEffExpLevel -= 2;
}
else if ( ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_FEAROFINSECTS) )&& MercIsInTropicalSector( pSoldier ) )
else if ( DoesMercHaveDisability( pSoldier, FEAR_OF_INSECTS ) && MercIsInTropicalSector( pSoldier ) )
{
// SANDRO - fear of insects, and we are in tropical sector
iEffExpLevel -= 1;
@@ -674,7 +674,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
iChance -= 15;
}
// also added a small penalty for fear of insects in tropical sectors
else if ( ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_FEAROFINSECTS) ) && MercIsInTropicalSector( pSoldier ))
else if ( DoesMercHaveDisability( pSoldier, FEAR_OF_INSECTS ) && MercIsInTropicalSector( pSoldier ) )
{
// fear of insects, and we are in tropical sector
iChance -= 5;
@@ -682,7 +682,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
// character traits influence
// Sociable - better performance in groups
if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_SOCIABLE ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SOCIABLE );
if ( bNumMercs > 2 )
@@ -691,7 +691,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
iChance += 2;
}
// Loner - better performance when alone
else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER )
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_LONER ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_LONER );
if ( bNumMercs == 0 )
@@ -700,7 +700,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
iChance += 2;
}
// Aggressive - penalty for actions needing patience
else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_AGGRESSIVE ) )
{
switch ( bReason )
{
@@ -717,7 +717,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
}
}
// Phlegmatic - bonus for actions needing patience
else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_PHLEGMATIC )
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_PHLEGMATIC ) )
{
switch ( bReason )
{
@@ -734,7 +734,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
}
}
// Show-off - better performance if some babes around to impress
else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF )
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_SHOWOFF ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SHOWOFF );
if ( bNumMercs > 1 )
@@ -934,7 +934,7 @@ INT16 CalcTrapDetectLevel( SOLDIERTYPE * pSoldier, BOOLEAN fExamining )
bDetectLevel += (INT8) PreRandom(bDetectLevel / 3 + 2);
}
// SANDRO - optimists just don't even think about the traps, randomly ignoring this all
else if ( gGameOptions.fNewTraitSystem && gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_OPTIMIST )
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_OPTIMIST ) )
{
if ( Chance(50) )
bDetectLevel = 1;
+4 -8
View File
@@ -1875,16 +1875,12 @@ BOOLEAN IsMercOnTeamAndInOmertaAlreadyAndAlive(UINT8 ubMercID)
// GetSoldierIDFromMercID() Gets the Soldier ID from the Merc Profile ID, else returns -1
INT16 GetSoldierIDFromMercID(UINT8 ubMercID)
{
UINT16 cnt;
UINT8 ubLastTeamID;
SOLDIERTYPE *pTeamSoldier;
SOLDIERTYPE *pTeamSoldier = NULL;
cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
ubLastTeamID = gTacticalStatus.Team[ OUR_TEAM ].bLastID;
UINT16 cnt = gTacticalStatus.Team[OUR_TEAM].bFirstID;
// look for all mercs on the same team,
for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= ubLastTeamID; ++cnt, pTeamSoldier++)
for ( pTeamSoldier = MercPtrs[cnt]; cnt <= gTacticalStatus.Team[OUR_TEAM].bLastID; ++cnt, ++pTeamSoldier )
{
if ( pTeamSoldier->ubProfile == ubMercID )
{
@@ -1893,7 +1889,7 @@ INT16 GetSoldierIDFromMercID(UINT8 ubMercID)
}
}
return( -1 );
return -1 ;
}
+1 -1
View File
@@ -1829,7 +1829,7 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
// enemy on sight, don't pretend we don't see him!
if ( pSoldier->ubProfile != NO_PROFILE )
{
if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait != CHAR_TRAIT_SHOWOFF && Random( 10 ) < 9 )
if ( Random( 10 ) < 9 && !DoesMercHavePersonality( pSoldier, CHAR_TRAIT_SHOWOFF ) )
{
continue;
}
+265 -105
View File
@@ -636,7 +636,7 @@ SOLDIERTYPE& SOLDIERTYPE::operator=(const OLDSOLDIERTYPE_101& src)
flags.ConvertFrom_101_To_102( src );
timeChanges.ConvertFrom_101_To_102( src );
timeCounters.ConvertFrom_101_To_102( src );
drugs.ConvertFrom_101_To_102( src );
//drugs.ConvertFrom_101_To_102( src );
stats.ConvertFrom_101_To_102( src );
pathing.ConvertFrom_101_To_102( src );
inv = src.inv;
@@ -1105,7 +1105,8 @@ void SOLDIERTYPE::initialize( )
memset( &flags, 0, sizeof(STRUCT_Flags) );
memset( &timeChanges, 0, sizeof(STRUCT_TimeChanges) );
memset( &timeCounters, 0, sizeof(STRUCT_TimeCounters) );
memset( &drugs, 0, sizeof(STRUCT_Drugs) );
//memset( &drugs, 0, sizeof(STRUCT_Drugs) );
memset( &newdrugs, 0, sizeof(DRUGS) );
memset( &stats, 0, sizeof(STRUCT_Statistics) );
memset( &pathing, 0, sizeof(STRUCT_Pathing) );
}
@@ -2033,23 +2034,23 @@ INT16 SOLDIERTYPE::CalcActionPoints( void )
if ( this->ubProfile != NO_PROFILE )
{
// Flugente: drugs can temporarily cause a merc to be claustrophobic
if ( ((gMercProfiles[this->ubProfile].bDisability == CLAUSTROPHOBIC) || MercUnderTheInfluence( this, DRUG_TYPE_CLAUSTROPHOBIC )) && (gbWorldSectorZ > 0) )
if ( DoesMercHaveDisability( this, CLAUSTROPHOBIC ) && gbWorldSectorZ > 0 )
{
ubPoints = (ubPoints * APBPConstants[AP_CLAUSTROPHOBE]) / 10;
}
else if ( ((gMercProfiles[this->ubProfile].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence( this, DRUG_TYPE_FEAROFINSECTS )) && (MercSeesCreature( this )) )
else if ( DoesMercHaveDisability( this, FEAR_OF_INSECTS ) && MercSeesCreature( this ) )
{
ubPoints = (ubPoints * APBPConstants[AP_AFRAID_OF_INSECTS]) / 10;
}
else if ( ((gMercProfiles[this->ubProfile].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence( this, DRUG_TYPE_FEAROFINSECTS )) && (MercIsInTropicalSector( this )) )
else if ( DoesMercHaveDisability( this, HEAT_INTOLERANT ) && MercIsInTropicalSector( this ) )
{
ubPoints = (ubPoints * 9) / 10;
}
}
// Adjusat APs due to drugs...
// Adjust APs due to drugs...
HandleAPEffectDueToDrugs( this, &ubPoints );
//Madd
// if ( this->bTeam != CIV_TEAM && this->bTeam != gbPlayerNum && gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
// ubPoints += 5; // everything and everyone moves a little faster against you on insane...
@@ -2153,7 +2154,7 @@ void SOLDIERTYPE::CalcNewActionPoints( void )
this->bActionPoints = APBPConstants[AP_MIN_LIMIT];
// Don't max out if we are drugged....
if ( !MercUnderTheInfluence( this, DRUG_TYPE_ADRENALINE ) && !MercUnderTheInfluence( this, DRUG_TYPE_AGILITY ) )
if ( !this->newdrugs.size[DRUG_EFFECT_AP] && !this->newdrugs.size[DRUG_EFFECT_AGI] )
{
///////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - following code messed a bit
@@ -7600,7 +7601,7 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
// ATE: Add decay effect sfor drugs...
//if ( fFromRealTime ) //&& iRealTimeCounter % 300 )
{
HandleEndTurnDrugAdjustments( this );
HandleEndTurnDrugAdjustments_New( this );
}
// ATE: Don't bleed if in AUTO BANDAGE!
@@ -7760,26 +7761,7 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
if ( (this->bTeam == gbPlayerNum) && (this->ubProfile != NO_PROFILE) )
{
// Flugente: drugs can temporarily cause a merc get a new disability
// therefore we change this routine
BOOLEAN isHeatIntolerant = gMercProfiles[this->ubProfile].bDisability == HEAT_INTOLERANT ? TRUE : FALSE;
BOOLEAN isFearOfInsects = gMercProfiles[this->ubProfile].bDisability == FEAR_OF_INSECTS ? TRUE : FALSE;
BOOLEAN isClaustrophobic = gMercProfiles[this->ubProfile].bDisability == CLAUSTROPHOBIC ? TRUE : FALSE;
BOOLEAN isNervous = gMercProfiles[this->ubProfile].bDisability == NERVOUS ? TRUE : FALSE;
if ( MercUnderTheInfluence( this, DRUG_TYPE_HEATINTOLERANT ) )
isHeatIntolerant = TRUE;
if ( MercUnderTheInfluence( this, DRUG_TYPE_FEAROFINSECTS ) )
isFearOfInsects = TRUE;
if ( MercUnderTheInfluence( this, DRUG_TYPE_CLAUSTROPHOBIC ) )
isClaustrophobic = TRUE;
if ( MercUnderTheInfluence( this, DRUG_TYPE_NERVOUS ) )
isNervous = TRUE;
if ( isHeatIntolerant )
if ( DoesMercHaveDisability( this, HEAT_INTOLERANT ) )
{
if ( MercIsHot( this ) )
{
@@ -7795,7 +7777,7 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
}
}
if ( isFearOfInsects )
if ( DoesMercHaveDisability( this, FEAR_OF_INSECTS ) )
{
if ( MercSeesCreature( this ) )
{
@@ -7811,7 +7793,7 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
}
}
if ( isClaustrophobic )
if ( DoesMercHaveDisability( this, CLAUSTROPHOBIC ) )
{
if ( gbWorldSectorZ > 0 && Random( 6 - gbWorldSectorZ ) == 0 )
{
@@ -7828,7 +7810,7 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
}
}
if ( isNervous )
if ( DoesMercHaveDisability( this, NERVOUS ) )
{
if ( DistanceToClosestFriend( this ) > NERVOUS_RADIUS )
{
@@ -8857,7 +8839,7 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier
// If a moving animation and w/re on drugs, increase speed....
if ( gAnimControl[pSoldier->usAnimState].uiFlags & ANIM_MOVING )
{
if ( MercUnderTheInfluence( pSoldier, DRUG_TYPE_ADRENALINE ) )
if ( pSoldier->newdrugs.size[DRUG_EFFECT_AP] )
{
pSoldier->sAniDelay = pSoldier->sAniDelay / 2;
}
@@ -12070,8 +12052,10 @@ void SOLDIERTYPE::EVENT_SoldierBeginBladeAttack( INT32 sGridNo, UINT8 ubDirectio
if ( ubTargetID != NOBODY && ((MercPtrs[ubTargetID]->stats.bLife < OKLIFE && MercPtrs[ubTargetID]->stats.bLife > 0) || (MercPtrs[ubTargetID]->bBreath < OKBREATH && MercPtrs[ubTargetID]->bCollapsed)) )
{
this->aiData.uiPendingActionData4 = ubTargetID;
// add regen bonus
this->bRegenerationCounter++;
this->newdrugs.size[DRUG_EFFECT_HP] += 10;
this->EVENT_InitNewSoldierAnim( MONSTER_BEGIN_EATTING_FLESH, 0, FALSE );
}
else
@@ -12547,7 +12531,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginKnifeThrowAttack( INT32 sGridNo, UINT8 ubDir
DebugAttackBusy( String( "Begin knife throwing attack: ATB %d\n", gTacticalStatus.ubAttackBusyCount ) );
// SANDRO - new animation for throwing for big mercs by PasHancock
if ( this->ubBodyType == BIGMALE && ((this->ubProfile != NO_PROFILE && gMercProfiles[this->ubProfile].bCharacterTrait == CHAR_TRAIT_SHOWOFF) || (HAS_SKILL_TRAIT( this, THROWING_NT ) && gGameOptions.fNewTraitSystem) || (HAS_SKILL_TRAIT( this, THROWING_OT ) && !gGameOptions.fNewTraitSystem)) )
if ( this->ubBodyType == BIGMALE && (DoesMercHavePersonality( this, CHAR_TRAIT_SHOWOFF ) || (HAS_SKILL_TRAIT( this, THROWING_NT ) && gGameOptions.fNewTraitSystem) || (HAS_SKILL_TRAIT( this, THROWING_OT ) && !gGameOptions.fNewTraitSystem)))
{
this->EVENT_InitNewSoldierAnim( THROW_KNIFE_SP_BM, 0, FALSE );
}
@@ -14568,7 +14552,7 @@ INT32 SOLDIERTYPE::GetDamageResistance( BOOLEAN fAutoResolve, BOOLEAN fCalcBreat
////////////////////////////////////////////////////////////////////////////////////
// Flugente: drugs can now have an effect on damage resistance
HandleDamageResistanceEffectDueToDrugs( this, &resistance );
resistance += this->newdrugs.size[DRUG_EFFECT_PHYS_RES];
resistance += this->GetBackgroundValue( BG_RESI_PHYSICAL );
@@ -14590,7 +14574,7 @@ INT8 SOLDIERTYPE::GetHearingBonus( )
bonus += GetHearingRangeBonus( this ); // pSoldier->inv[bSlot][0]->data.objectStatus / 20 + 1;
}
if ( gMercProfiles[this->ubProfile].bDisability == DEAF )
if ( DoesMercHaveDisability( this, DEAF ) )
bonus -= 5;
if ( NightTime( ) )
@@ -14608,7 +14592,7 @@ INT16 SOLDIERTYPE::GetSightRangeBonus( )
{
INT16 bonus = 0;
if ( gMercProfiles[this->ubProfile].bDisability == SHORTSIGHTED )
if ( DoesMercHaveDisability( this, SHORTSIGHTED ) )
bonus -= 10;
return bonus;
@@ -16795,7 +16779,7 @@ INT8 SOLDIERTYPE::GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubT
if ( this->ubProfile != NO_PROFILE )
{
// Sociable - better performance in groups
if ( gMercProfiles[this->ubProfile].bCharacterTrait == CHAR_TRAIT_SOCIABLE )
if ( DoesMercHavePersonality( this, CHAR_TRAIT_SOCIABLE ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( this->ubProfile, CHAR_TRAIT_SOCIABLE );
if ( bNumMercs > 2 )
@@ -16804,7 +16788,7 @@ INT8 SOLDIERTYPE::GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubT
modifier += 2;
}
// Loner - better performance when alone
else if ( gMercProfiles[this->ubProfile].bCharacterTrait == CHAR_TRAIT_LONER )
else if ( DoesMercHavePersonality( this, CHAR_TRAIT_LONER ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( this->ubProfile, CHAR_TRAIT_LONER );
if ( bNumMercs == 0 )
@@ -16813,13 +16797,13 @@ INT8 SOLDIERTYPE::GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubT
modifier += 2;
}
// Aggressive - bonus on bursts/autofire
else if ( gMercProfiles[this->ubProfile].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
else if ( DoesMercHavePersonality( this, CHAR_TRAIT_AGGRESSIVE ) )
{
if ( (this->bDoBurst || this->bDoAutofire) && !ubAimTime )
modifier += 10;
}
// Show-off - better performance if some babes around to impress
else if ( gMercProfiles[this->ubProfile].bCharacterTrait == CHAR_TRAIT_SHOWOFF )
else if ( DoesMercHavePersonality( this, CHAR_TRAIT_SHOWOFF ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( this->ubProfile, CHAR_TRAIT_SHOWOFF );
if ( bNumMercs > 1 )
@@ -16837,15 +16821,16 @@ INT8 SOLDIERTYPE::GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubT
}
// Small penalty for fear of insects in tropical sectors
// Flugente: drugs can temporarily cause a merc get a new disability
else if ( ((gMercProfiles[this->ubProfile].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence( this, DRUG_TYPE_FEAROFINSECTS )) && MercIsInTropicalSector( this ) )
else if ( DoesMercHaveDisability( this, FEAR_OF_INSECTS ) && MercIsInTropicalSector( this ) )
{
// fear of insects, and we are in tropical sector
modifier -= 5;
}
}
}
// Dauntless - penalty for not taking proper cover
if ( ubTargetProfile != NOBODY )
if ( ubTargetProfile != NO_PROFILE )
{
if ( gMercProfiles[ubTargetProfile].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
modifier += 5;
@@ -16854,7 +16839,7 @@ INT8 SOLDIERTYPE::GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubT
else
{
// this rather unlogical bonus for psychotic characters applies only with old traits
if ( this->ubProfile != NO_PROFILE && gMercProfiles[this->ubProfile].bDisability == PSYCHO || MercUnderTheInfluence( this, DRUG_TYPE_PSYCHO ) )
if ( DoesMercHaveDisability( this, PSYCHO ) )
{
modifier += AIM_BONUS_PSYCHO;
}
@@ -16863,14 +16848,14 @@ INT8 SOLDIERTYPE::GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubT
return modifier;
}
void SOLDIERTYPE::AddDrugValues( UINT8 uDrugType, UINT8 usEffect, UINT8 usTravelRate, UINT8 usSideEffect )
/*void SOLDIERTYPE::AddDrugValues( UINT8 uDrugType, UINT8 usEffect, UINT8 usTravelRate, UINT8 usSideEffect )
{
// in case of wrong inout, stay safe
if ( uDrugType >= DRUG_TYPE_MAX )
return;
// Flugente: backgrounds
if ( this->ubProfile != NOBODY && uDrugType == DRUG_TYPE_ALCOHOL )
if ( uDrugType == DRUG_TYPE_ALCOHOL )
{
usEffect = usEffect * ((100 - this->GetBackgroundValue( BG_RESI_ALCOHOL )) / 100);
usSideEffect = usSideEffect * ((100 - this->GetBackgroundValue( BG_RESI_ALCOHOL )) / 100);
@@ -16896,7 +16881,7 @@ void SOLDIERTYPE::AddDrugValues( UINT8 uDrugType, UINT8 usEffect, UINT8 usTravel
// set flag: we are on drugs
this->usSoldierFlagMask |= SOLDIER_DRUGGED;
}
}*/
void SOLDIERTYPE::HandleFlashLights( )
{
@@ -17222,11 +17207,23 @@ FLOAT SOLDIERTYPE::GetMoraleModifier( )
FLOAT mod = 1.0f;
UINT8 officertype = OFFICER_NONE;
if ( HighestEnemyOfficersInSector( officertype ) )
if ( bTeam == ENEMY_TEAM && HighestEnemyOfficersInSector( officertype ) )
{
mod += gGameExternalOptions.dEnemyOfficerMoraleModifier * officertype;
}
// Flugente: disease
if ( gGameExternalOptions.fDisease )
{
FLOAT diseaseeffect = 1.0f;
for ( int i = 0; i < NUM_DISEASES; ++i )
{
diseaseeffect *= 1.0f - (1.0f - Disease[i].moralemodifier) * this->GetDiseaseMagnitude( i );
}
mod *= diseaseeffect;
}
return mod;
}
@@ -17234,11 +17231,11 @@ INT16 SOLDIERTYPE::GetInterruptModifier( UINT8 usDistance )
{
INT16 bonus = 0;
// drugs can alter our perception
/*// drugs can alter our perception
if ( this->drugs.bDrugEffect[DRUG_TYPE_PERCEPTION] )
bonus += 2;
else if ( this->drugs.bDrugSideEffect[DRUG_TYPE_PERCEPTION] )
bonus -= 2;
bonus -= 2;*/
// if we are listening on our radio, our mind will be somewhere else... we will be less focused
if ( this->IsRadioListening( ) )
@@ -19008,6 +19005,46 @@ INT8 SOLDIERTYPE::GetSleepBreathRegeneration( )
return bMaxBreathRegain;
}
// Flugente: assumed character weight (without any items)
FLOAT SOLDIERTYPE::GetBodyWeight()
{
switch ( this->ubBodyType )
{
case REGMALE:
case MANCIV:
return 85.0f;
break;
case BIGMALE:
case STOCKYMALE:
return 110.0f;
break;
case REGFEMALE:
return 75.0f;
break;
case FATCIV:
return 100.0f;
break;
case MINICIV:
case DRESSCIV:
return 60.0f;
break;
case HATKIDCIV:
case KIDCIV:
return 40.0f;
break;
case CRIPPLECIV:
return 75.0f;
break;
}
return 80.0f;
}
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
{
@@ -20039,45 +20076,7 @@ void SOLDIERTYPE::EVENT_SoldierApplyItemToPerson( INT32 sGridNo, UINT8 ubDirecti
if ( success )
{
if ( Item[usItem].canteen )
{
if ( !gGameOptions.fFoodSystem )
{
BOOLEAN tmp = FALSE;
success = ApplyCanteen( pSoldier, pObj, &tmp, FALSE );
}
else
{
success = ApplyFood( pSoldier, pObj, TRUE, TRUE );
}
}
else if ( Item[usItem].drugtype )
{
// applying drugs also handles food items
success = ApplyDrugs( pSoldier, pObj );
}
else if ( Item[usItem].camouflagekit )
{
BOOLEAN tmp = FALSE;
success = ApplyCammo( pSoldier, pObj, &tmp, FALSE );
if ( success )
{
// WANNE: We should only delete the face, if there was a camo we applied.
// This should fix the bug and crashes with missing faces
if ( gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
// Flugente: refresh face regardless of result of SetCamoFace(), otherwise applying a rag will not clean the picture
SetCamoFace( pSoldier );
DeleteSoldierFace( pSoldier );// remove face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
}
// Dirty
fInterfacePanelDirty = DIRTYLEVEL2;
}
}
else if ( Item[usItem].gasmask )
if ( Item[usItem].gasmask )
{
// put this item into a (at best empty) faceslot if no gasmask is been worn
INT8 bSlot = FindGasMask( pSoldier );
@@ -20100,17 +20099,14 @@ void SOLDIERTYPE::EVENT_SoldierApplyItemToPerson( INT32 sGridNo, UINT8 ubDirecti
}
}
}
else if ( Item[usItem].clothestype )
{
ApplyClothes( pSoldier, pObj, FALSE );
// Dirty
fInterfacePanelDirty = DIRTYLEVEL2;
}
else if ( Item[ usItem ].usItemClass == IC_BOMB )
else if ( Item[usItem].usItemClass == IC_BOMB )
{
success = AutoPlaceObject( pSoldier, pObj, FALSE );
}
else if ( ApplyConsumable( pSoldier, pObj, TRUE, TRUE ) )
{
success = TRUE;
}
}
DeductPoints( this, GetAPsToApplyItem( this, sGridNo ), APBPConstants[BP_APPLYITEM], AFTERACTION_INTERRUPT );
@@ -21856,27 +21852,30 @@ BOOLEAN ResolvePendingInterrupt( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType )
iInjuryPenalty = (200 * (pInterrupter->stats.bLifeMax - pInterrupter->stats.bLife + ((pInterrupter->stats.bLifeMax - pInterrupter->stats.bLife - pInterrupter->bBleeding) / 2))) / (pInterrupter->stats.bLifeMax);
uiReactionTime = (uiReactionTime * (100 + iInjuryPenalty * (100 - (3 * EffectiveExpLevel( pInterrupter ))) / 100) / 100);
}
// adjust by breath down
if ( pSoldier->bBreath < 100 )
{
// +1% per 2 points of breath down
uiReactionTime = (uiReactionTime * (100 + ((100 - pSoldier->bBreath) / 2)) / 100);
}
// adjust for getting aid, being in gas or being in shock
if ( pInterrupter->flags.uiStatusFlags & SOLDIER_GASSED )
uiReactionTime = (uiReactionTime * (100 + AIM_PENALTY_GASSED) / 100);
if ( pInterrupter->ubServiceCount > 0 )
uiReactionTime = (uiReactionTime * (100 + AIM_PENALTY_GETTINGAID) / 100);
if ( pInterrupter->aiData.bShock )
uiReactionTime = (uiReactionTime * (100 + (pInterrupter->aiData.bShock * 20)) / 100); // this is severe, 20% per point
// Phlegmatic characters has slightly longer reaction time
if ( pSoldier->ubProfile != NO_PROFILE )
// Phlegmatic characters has slightly longer reaction time
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_PHLEGMATIC ) )
{
if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_PHLEGMATIC )
{
uiReactionTime = ((uiReactionTime * 110) / 100);
}
uiReactionTime = ((uiReactionTime * 110) / 100);
}
// finally divide back by 10 to get the needed result (round properly)
uiReactionTime = ((uiReactionTime + 5) / 10);
@@ -22869,7 +22868,7 @@ void HandleVolunteerRecruitment( SOLDIERTYPE* pRecruiter, SOLDIERTYPE* pTarget )
FLOAT leadershipfactor = EffectiveLeadership( pRecruiter ) / 100.0;
// bonus for assertive characters
if ( gMercProfiles[pRecruiter->ubProfile].bCharacterTrait == CHAR_TRAIT_ASSERTIVE )
if ( DoesMercHavePersonality( pRecruiter, CHAR_TRAIT_ASSERTIVE ) )
leadershipfactor *= 1.05;
FLOAT recruitmodifier = (100 + pRecruiter->GetBackgroundValue( BG_PERC_APPROACH_RECRUIT )) / 100.0;
@@ -22892,3 +22891,164 @@ void HandleVolunteerRecruitment( SOLDIERTYPE* pRecruiter, SOLDIERTYPE* pTarget )
}
}
}
// Flugente: apply a consumable item on a soldier. Returns true if item was successfully interacted with
BOOLEAN ApplyConsumable( SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, BOOLEAN fForce, BOOLEAN fUseAPs )
{
if ( !pSoldier || !pObj )
return FALSE;
// if it's not a kit or a misc item, we cannot consume it
if ( !(Item[pObj->usItem].usItemClass & (IC_KIT | IC_MISC)) )
return FALSE;
BOOLEAN fDoSound = FALSE;
// use portionsize, if none was entered, use full item
UINT8 portionsize = Item[pObj->usItem].usPortionSize;
if ( !portionsize )
portionsize = 100;
// how much of this item do we use up
UINT16 statusused = min( portionsize, (*pObj)[0]->data.objectStatus );
if ( !statusused )
return FALSE;
// if we check for APs, do so - if we don't have enough, stop
if ( fUseAPs )
{
// an object can be consumed in several ways (like food that is also a drug), but each consumption might have a different AP cost.
// as it would be very odd if an effect does not happen because the corresponding AP cost could not be met, we analyze the item first and determine the AP cost.
// We then either apply everything or nothing
UINT16 apcost = 0;
if ( HasItemFlag( pObj->usItem, CAMO_REMOVAL ) && gGameExternalOptions.fCamoRemoving )
{
apcost = max( apcost, (APBPConstants[AP_CAMOFLAGE] / 2) );
}
if ( Item[pObj->usItem].camouflagekit )
{
apcost = max( apcost, APBPConstants[AP_CAMOFLAGE] );
}
if ( Item[pObj->usItem].canteen )
{
apcost = max( apcost, APBPConstants[AP_DRINK] );
}
if ( pObj->usItem == JAR_ELIXIR )
{
apcost = max( apcost, APBPConstants[AP_CAMOFLAGE] );
}
if ( Item[pObj->usItem].clothestype )
{
INT16 disguise_apcost = (APBPConstants[AP_DISGUISE] * (100 - gSkillTraitValues.sCODisguiseAPReduction * NUM_SKILL_TRAITS( pSoldier, COVERT_NT ))) / 100;
apcost = max( apcost, disguise_apcost );
}
if ( Item[pObj->usItem].drugtype )
{
apcost = max( apcost, APBPConstants[AP_DRINK] );
}
if ( Item[pObj->usItem].foodtype )
{
// do we eat or drink this stuff?
UINT8 apcost_type = AP_EAT;
if ( Food[Item[pObj->usItem].foodtype].bDrinkPoints > Food[Item[pObj->usItem].foodtype].bFoodPoints )
apcost_type = AP_DRINK;
apcost = max( apcost, APBPConstants[apcost_type] );
}
if ( !fForce && !EnoughPoints( pSoldier, apcost, 0, TRUE ) )
{
return FALSE;
}
}
// under certain conditions, a merc can but simply does not want to consume an item, and can refuse if not forced to.
if ( !fForce )
{
if ( DoesSoldierRefuseToEat( pSoldier, pObj ) )
{
return FALSE;
}
// some mercs will refuse to smoke
if ( Item[pObj->usItem].cigarette && pSoldier->GetBackgroundValue( BG_SMOKERTYPE ) == 2 )
{
// merc gets slightly pissed by the player even suggesting this
TacticalCharacterDialogue( pSoldier, QUOTE_PRE_NOT_SMART );
pSoldier->aiData.bMorale = max( 0, pSoldier->aiData.bMorale - 1 );
return FALSE;
}
}
// Try to apply camo....
// this returns true if camo can be applied, but APs were only used, and the action happened, if *pfGoodAPs is TRUE
if ( ApplyCamo( pSoldier, pObj->usItem, statusused ) )
{
fDoSound = TRUE;
// WANNE: We should only delete the face, if there was a camo we applied.
// This should fix the bug and crashes with missing faces
if ( gGameExternalOptions.fShowCamouflageFaces )
{
// Flugente: refresh face regardless of result of SetCamoFace(), otherwise applying a rag will not clean the picture
SetCamoFace( pSoldier );
DeleteSoldierFace( pSoldier );// remove face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
}
}
if ( ApplyCanteen( pSoldier, pObj->usItem, statusused ) )
{
fDoSound = FALSE;
}
if ( ApplyElixir( pSoldier, pObj->usItem, statusused ) )
{
fDoSound = TRUE;
}
if ( ApplyClothes( pSoldier, pObj->usItem, statusused ) )
{
}
if ( ApplyFood( pSoldier, pObj, statusused ) )
{
fDoSound = FALSE;
}
if ( ApplyDrugs_New( pSoldier, pObj->usItem, statusused ) )
{
// no sound on consuming cigarettes, as that is very annoying
if ( !Item[pObj->usItem].cigarette )
{
fDoSound = TRUE;
}
}
// use up object
UseKitPoints( pObj, statusused, pSoldier );
if ( fUseAPs )
{
// Dirty
fInterfacePanelDirty = DIRTYLEVEL2;
}
if ( fDoSound )
{
// Say OK acknowledge....
pSoldier->DoMercBattleSound( BATTLE_SOUND_COOL1 );
}
return TRUE;
}
+42 -5
View File
@@ -355,7 +355,7 @@ enum
// -------- added by Flugente: various flags for soldiers --------
// easier than adding 32 differently named variables. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
#define SOLDIER_DRUGGED 0x00000001 //1 // Soldier is on drugs
#define SOLDIER_DRUGGED 0x00000001 //1 // Soldier is on (non-alcoholic) drugs
#define SOLDIER_NO_AP 0x00000002 //2 // Soldier has no APs this turn (fix for reinforcement bug)
#define SOLDIER_COVERT_CIV 0x00000004 //4 // Soldier is currently disguised as a civilian
#define SOLDIER_COVERT_SOLDIER 0x00000008 //8 // Soldier is currently disguised as an enemy soldier
@@ -409,6 +409,7 @@ enum
#define SOLDIER_INTERROGATE_CIVILIAN 0x00000100 //256 // interrogate civilian
#define SOLDIER_POTENTIAL_VOLUNTEER 0x00000200 //512 // this civilian _might_ join us as a volunteer if conditions are right
#define SOLDIER_HUNGOVER 0x00000400 //1024 // we drank alcohol recently, and are now hungover
#define SOLDIER_INTERROGATE_ALL 0x000001F8 // all interrogation flags
// ----------------------------------------------------------------
@@ -911,6 +912,36 @@ public:
INT8 bTimesDrugUsedSinceSleep[DRUG_TYPE_MAX];
};
// Flugente: everything drug-related has been redone
enum {
DRUG_EFFECT_HP = 0,
DRUG_EFFECT_BP,
DRUG_EFFECT_AP,
DRUG_EFFECT_MORALE,
DRUG_EFFECT_PHYS_RES,
DRUG_EFFECT_STR,
DRUG_EFFECT_AGI,
DRUG_EFFECT_DEX,
DRUG_EFFECT_WIS,
DRUG_EFFECT_MAX = 20,
};
struct DRUGS
{
UINT16 duration[DRUG_EFFECT_MAX];
INT16 size[DRUG_EFFECT_MAX];
UINT8 drugpersonality;
UINT16 drugpersonality_duration;
UINT8 drugdisability;
UINT16 drugdisability_duration;
FLOAT drinkstaken; // number of alcoholic drinks we habe in our system, lowered by 1 every hour
};
class STRUCT_TimeCounters//last edited at version 102
{
public:
@@ -1361,8 +1392,8 @@ public:
INT8 bGoodContPath;
UINT8 ubPendingActionInterrupted;
INT8 bNoiseLevel;
INT8 bRegenerationCounter;
INT8 bRegenBoostersUsedToday;
INT8 bRegenerationCounter; // Flugente: not used anymore!
INT8 bRegenBoostersUsedToday; // Flugente: not used anymore!
INT8 bNumPelletsHitBy;
INT32 sSkillCheckGridNo;
UINT8 ubLastEnemyCycledID;
@@ -1520,7 +1551,8 @@ public:
STRUCT_Flags flags;
STRUCT_TimeChanges timeChanges;
STRUCT_TimeCounters timeCounters;
STRUCT_Drugs drugs;
//STRUCT_Drugs drugs; // Flugente: drug values are now in newdrugs
DRUGS newdrugs;
STRUCT_Statistics stats;
STRUCT_Pathing pathing;
@@ -1788,7 +1820,7 @@ public:
INT8 GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubTargetProfile );
void AddDrugValues(UINT8 uDrugType, UINT8 usEffect, UINT8 usTravelRate, UINT8 usSideEffect );
//void AddDrugValues(UINT8 uDrugType, UINT8 usEffect, UINT8 usTravelRate, UINT8 usSideEffect );
void HandleFlashLights();
UINT8 GetBestEquippedFlashLightRange();
@@ -1876,6 +1908,8 @@ public:
// Flugente: hourly breath regen calculation
INT8 GetSleepBreathRegeneration();
// Flugente: assumed character weight (without any items)
FLOAT GetBodyWeight();
//////////////////////////////////////////////////////////////////////////////
}; // SOLDIERTYPE;
@@ -2728,6 +2762,9 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
// Flugente: decide whether pRecruiter can successfully recruit pTarget to be a volunteer
void HandleVolunteerRecruitment( SOLDIERTYPE* pRecruiter, SOLDIERTYPE* pTarget );
// Flugente: apply a consumable item on a soldier. Returns true if item was successfully interacted with
BOOLEAN ApplyConsumable( SOLDIERTYPE* pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, BOOLEAN fUseAPs );
#endif
+2 -6
View File
@@ -3471,16 +3471,12 @@ void CreateAssassin(UINT8 disguisetype)
if ( vestfound )
{
CreateItem( vestitem, 100, &gTempObject );
ApplyClothes(pSoldier, &gTempObject, FALSE);
ApplyClothes( pSoldier, vestitem, 100 );
}
if ( pantsfound )
{
CreateItem( pantsitem, 100, &gTempObject );
ApplyClothes(pSoldier, &gTempObject, FALSE);
ApplyClothes( pSoldier, vestitem, 100 );
}
// Dirty
+10 -10
View File
@@ -2297,7 +2297,7 @@ BOOLEAN MercIsHot( SOLDIERTYPE * pSoldier )
{
// SANDRO - added argument
// Flugente: drugs can temporarily cause a merc to be heat intolerant
if ( pSoldier->ubProfile != NO_PROFILE && (gMercProfiles[ pSoldier->ubProfile ].bDisability == HEAT_INTOLERANT || MercUnderTheInfluence(pSoldier, DRUG_TYPE_HEATINTOLERANT) ) && !pSoldier->MercInWater())
if ( !pSoldier->MercInWater( ) && DoesMercHaveDisability( pSoldier, HEAT_INTOLERANT ) )
{
if ((pSoldier->bSectorZ > 0) || (guiEnvWeather & ( WEATHER_FORECAST_SHOWERS | WEATHER_FORECAST_THUNDERSHOWERS )))
{
@@ -2859,18 +2859,18 @@ INT8 CheckMercsNearForCharTraits( UINT8 ubProfileID, INT8 bCharTraitID )
{
// Sociable - we are OK with everyone except those wicked malicious guys
case CHAR_TRAIT_SOCIABLE:
if( gMercProfiles[ pTeammate->ubProfile ].bCharacterTrait != CHAR_TRAIT_MALICIOUS )
bNumber++;
if ( !DoesMercHavePersonality( pTeammate, CHAR_TRAIT_MALICIOUS ) )
++bNumber;
break;
// Loner can tolerate one other loner around
case CHAR_TRAIT_LONER:
if ( gMercProfiles[ pTeammate->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER && !fOnlyOneException )
if ( !fOnlyOneException && DoesMercHavePersonality( pTeammate, CHAR_TRAIT_LONER ) )
{
fOnlyOneException = TRUE;
}
else
{
bNumber++;
++bNumber;
}
break;
// Show-off, depends on gender and appearance of others
@@ -2885,9 +2885,9 @@ INT8 CheckMercsNearForCharTraits( UINT8 ubProfileID, INT8 bCharTraitID )
bNumber += 2;
// However remove one if ugly one
else if ( gMercProfiles[ pTeammate->ubProfile ].bAppearance == APPEARANCE_UGLY )
bNumber--;
--bNumber;
else
bNumber++;
++bNumber;
}
}
// If we are female
@@ -2900,14 +2900,14 @@ INT8 CheckMercsNearForCharTraits( UINT8 ubProfileID, INT8 bCharTraitID )
bNumber += 2;
// However remove one if ugly one
else if ( gMercProfiles[ pTeammate->ubProfile ].bAppearance == APPEARANCE_UGLY )
bNumber--;
--bNumber;
else
bNumber++;
++bNumber;
}
}
break;
default:
bNumber++;
++bNumber;
break;
}
}
+2 -1
View File
@@ -1914,8 +1914,9 @@ INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN f
iPoints += gSkillTraitValues.ubNOIterruptsBonusInDark;
}
}
// Phlegmatics get a small penalty to interrupts
if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_PHLEGMATIC )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_PHLEGMATIC ) )
{
iPoints -= 1;
}
+4
View File
@@ -1575,6 +1575,10 @@ void CheatCreateItem( )
{
INT16 status = 100;
FLOAT temperature = 0.0;
if ( Item[usitem].foodtype )
temperature = OVERHEATING_MAX_TEMPERATURE;
// Flugente: spawn items while debugging
OBJECTTYPE newobj;
CreateItem( usitem, status, &newobj );
+40 -29
View File
@@ -6075,14 +6075,12 @@ else
//Give 60% the normal stomp modifier as the aim mod
iAimModifier += (FLOAT)iTraitModifier * 0.6f;
}
//else
//{
// Flugente: drugs can temporarily cause a merc to go psycho
if ( pSoldier->ubProfile != NO_PROFILE && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) )
{
iAimModifier += gGameCTHConstants.AIM_PSYCHO;
}
//}
// Flugente: drugs can temporarily cause a merc to go psycho
if ( DoesMercHaveDisability( pSoldier, PSYCHO ) )
{
iAimModifier += gGameCTHConstants.AIM_PSYCHO;
}
//////////////////////////////////////////
// Gun Handling modifiers
@@ -7201,12 +7199,9 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// HEADROCK HAM B2.6: Externalized the value
iPenalty = __min( (UINT16)((float)pTarget->bTilesMoved * (float)gGameExternalOptions.iMovementEffectOnAiming), gGameExternalOptions.usMaxCTHPenaltyForMovingTarget );
///////////////////////////////////////////////////////////////////////////////////
// SANDRO - fearless characters do not even take their head down no matter what
if ( gGameOptions.fNewTraitSystem && pTarget->ubProfile != NO_PROFILE )
{
if ( gMercProfiles[ pTarget->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
iPenalty -= (iPenalty * 2 / 3); // two thirds only
}
// SANDRO - fearless characters do not even take their head down no matter what
if ( DoesMercHavePersonality( pTarget, CHAR_TRAIT_DAUNTLESS ) )
iPenalty -= (iPenalty * 2 / 3); // two thirds only
///////////////////////////////////////////////////////////////////////////////////
iChance -= iPenalty;
@@ -9496,11 +9491,14 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
INT32 sOrigGridNo = 0;
BOOLEAN fFragment = FALSE;
INT32 iTotalArmourProtection=0;
UINT16 ammoitem = NOTHING;
if (pBullet == NULL && pFirer )
{
usAttackingWeapon = pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType;
sOrigGridNo = pFirer->sGridNo;
ammoitem = pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.usGunAmmoItem;
}
else
{
@@ -9543,6 +9541,8 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
// Flugente: check for underbarrel weapons and use that object if necessary
OBJECTTYPE* pObj = pFirer->GetUsedWeapon( &pFirer->inv[pFirer->ubAttackingHand] );
ubAmmoType = (*pObj)[0]->data.gun.ubGunAmmoType;
ammoitem = (*pObj)[0]->data.gun.usGunAmmoItem;
}
else
{
@@ -9637,21 +9637,31 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
if ( iImpact > 0 && !TANK( pTarget ) )
{
// Flugente: ammo can now add the lifedamage drug effect. This will kill the target in a few turns.
// Flugente: any bullet can have drug effects it set so in the magazine item
if ( ammoitem != NOTHING )
{
ApplyDrugs_New( pTarget, ammoitem, 100 );
}
/*// Flugente: ammo can now add the lifedamage drug effect. This will kill the target in a few turns.
// this is intended to work on darts, but it is possible on any ammo
if ( AmmoTypes[ubAmmoType].ammoflag & AMMO_NEUROTOXIN )
{
pTarget->usSoldierFlagMask |= SOLDIER_DRUGGED;
ApplyDrugs_New( pTarget, ammoitem, 100 );
// Add lifedamage effects
pTarget->AddDrugValues( DRUG_TYPE_LIFEDAMAGE, Drug[DRUG_TYPE_LIFEDAMAGE].ubDrugEffect, Drug[DRUG_TYPE_LIFEDAMAGE].ubDrugTravelRate, Drug[DRUG_TYPE_LIFEDAMAGE].ubDrugSideEffect );
}
else if ( AmmoTypes[ubAmmoType].dart && sHitBy > 20 )
else */
if ( AmmoTypes[ubAmmoType].dart && sHitBy > 20 )
{
if (pubSpecial)
{
*pubSpecial = FIRE_WEAPON_SLEEP_DART_SPECIAL;
}
return( iImpact );
}
@@ -9866,14 +9876,15 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
}
BOOLEAN fMaliciousHit = FALSE;
// SANDRO - Malicious characters inflict stat loss more often
if ( gGameOptions.fNewTraitSystem && pFirer && pFirer->ubProfile != NO_PROFILE && !fFragment)
if ( pFirer && !fFragment)
{
if ( gMercProfiles[ pFirer->ubProfile ].bCharacterTrait == CHAR_TRAIT_MALICIOUS )
if ( DoesMercHavePersonality( pFirer, CHAR_TRAIT_MALICIOUS ) )
{
uiCritChance += 8;
fMaliciousHit = TRUE;
}
}
// SANDRO - with new traits, the chance for stat loss is higher as we are now able to repair it
if ((PreRandom( uiCritChance ) + 1) > (UINT8)(gGameOptions.fNewTraitSystem ? gSkillTraitValues.ubDamageNeededToLoseStats : CRITICAL_HIT_THRESHOLD))
{
@@ -10374,7 +10385,7 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
}
// bonus damage for aggressive characters
if ( gGameOptions.fNewTraitSystem && gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_AGGRESSIVE ) )
{
iBonus += 10; // +10%
}
@@ -10622,7 +10633,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
// psycho bonus - only with old traits - SANDRO
// Flugente: drugs can temporarily cause a merc to go psycho
if ( !( gGameOptions.fNewTraitSystem ) && pAttacker->ubProfile != NO_PROFILE && (gMercProfiles[ pAttacker->ubProfile ].bDisability == PSYCHO || MercUnderTheInfluence(pAttacker, DRUG_TYPE_PSYCHO) ) )
if ( !(gGameOptions.fNewTraitSystem) && DoesMercHaveDisability( pAttacker, PSYCHO ) )
{
iAttRating += AIM_BONUS_PSYCHO;
}
@@ -10767,7 +10778,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
if ( gGameOptions.fNewTraitSystem && pAttacker->ubProfile != NO_PROFILE )
{
// Sociable - better performance in groups
if ( gMercProfiles[ pAttacker->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE )
if ( DoesMercHavePersonality( pAttacker, CHAR_TRAIT_SOCIABLE ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( pAttacker->ubProfile, CHAR_TRAIT_SOCIABLE );
if ( bNumMercs > 2 )
@@ -10776,7 +10787,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
iAttRating += 2;
}
// Loner - better performance when alone
else if ( gMercProfiles[ pAttacker->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER )
else if ( DoesMercHavePersonality( pAttacker, CHAR_TRAIT_LONER ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( pAttacker->ubProfile, CHAR_TRAIT_LONER );
if ( bNumMercs == 0 )
@@ -10785,7 +10796,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
iAttRating += 2;
}
// Show-off - better performance if some babes around to impress
else if ( gMercProfiles[ pAttacker->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF )
else if ( DoesMercHavePersonality( pAttacker, CHAR_TRAIT_SHOWOFF ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( pAttacker->ubProfile, CHAR_TRAIT_SHOWOFF );
if ( bNumMercs > 1 )
@@ -11028,7 +11039,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
if ( gGameOptions.fNewTraitSystem && pDefender->ubProfile != NO_PROFILE )
{
// Sociable - better performance in groups
if ( gMercProfiles[ pDefender->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE )
if ( DoesMercHavePersonality( pDefender, CHAR_TRAIT_SOCIABLE ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( pDefender->ubProfile, CHAR_TRAIT_SOCIABLE );
if ( bNumMercs > 2 )
@@ -11037,7 +11048,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
iDefRating += 2;
}
// Loner - better performance when alone
else if ( gMercProfiles[ pDefender->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER )
else if ( DoesMercHavePersonality( pDefender, CHAR_TRAIT_LONER ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( pDefender->ubProfile, CHAR_TRAIT_LONER );
if ( bNumMercs == 0 )
@@ -11046,7 +11057,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
iDefRating += 2;
}
// Show-off - better performance if some babes around to impress
else if ( gMercProfiles[ pDefender->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF )
else if ( DoesMercHavePersonality( pDefender, CHAR_TRAIT_SHOWOFF ) )
{
INT8 bNumMercs = CheckMercsNearForCharTraits( pDefender->ubProfile, CHAR_TRAIT_SHOWOFF );
if ( bNumMercs > 1 )
@@ -11054,7 +11065,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
else if ( bNumMercs > 0 )
iDefRating += 2;
}
else if ( gMercProfiles[ pDefender->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
else if ( DoesMercHavePersonality( pDefender, CHAR_TRAIT_DAUNTLESS ) )
{
iDefRating -= 5;
}
@@ -12330,7 +12341,7 @@ void EstimateBulletsLeft( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj )
// Is this Soldier a psycho?
// Flugente: drugs can temporarily cause a merc to go psycho
if ( pSoldier->ubProfile != NO_PROFILE && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) )
if ( DoesMercHaveDisability( pSoldier, PSYCHO ) )
{
fPsycho = TRUE;
}
@@ -13058,7 +13069,7 @@ FLOAT CalcNewChanceToHitAimEffectBonus(SOLDIERTYPE *pSoldier)
}
// Flugente: drugs can temporarily cause a merc to go psycho
if ( pSoldier->ubProfile != NO_PROFILE && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) )
if ( DoesMercHaveDisability( pSoldier, PSYCHO ) )
{
fAimModifier += gGameCTHConstants.AIM_PSYCHO;
}
+10 -1
View File
@@ -35,7 +35,16 @@ enum
MERCHANT_CASH_DAILY,
MERCHANT_COOLNESS,
MERCHANT_FLAGS,
MERCHANT_REORDER
MERCHANT_REORDER,
ELEMENT_DRUG_EFFECT,
ELEMENT_DRUG_EFFECT_PROPERTY,
ELEMENT_DISEASE_EFFECT,
ELEMENT_DISEASE_EFFECT_PROPERTY,
ELEMENT_DISABILITY_EFFECT,
ELEMENT_DISABILITY_EFFECT_PROPERTY,
ELEMENT_PERSONALITY_EFFECT,
ELEMENT_PERSONALITY_EFFECT_PROPERTY
}
typedef PARSE_STAGE;
+6
View File
@@ -130,6 +130,7 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha
strcmp(name, "tracker_ability" ) == 0 ||
strcmp(name, "ambush_radius" ) == 0 ||
strcmp(name, "dislikebackground" ) == 0 ||
strcmp(name, "smoker" ) == 0 ||
strcmp(name, "druguse") == 0 ||
strcmp(name, "xenophobic") == 0 ||
strcmp(name, "corruptionspread") == 0 ||
@@ -549,6 +550,11 @@ backgroundEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curBackground.value[BG_DISLIKEBG] = (INT16)atol( pData->szCharData );
}
else if ( strcmp( name, "smoker" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curBackground.value[BG_SMOKERTYPE] = min( 2, max( 0, (INT16)atol( pData->szCharData ) ) );
}
else if(strcmp(name, "druguse") == 0)
{
pData->curElement = ELEMENT;
+11 -1
View File
@@ -44,6 +44,9 @@ diseaseStartElementHandle( void *userData, const XML_Char *name, const XML_Char
memset( &pData->curItem, 0, sizeof(DISEASE) );
// default value
pData->curItem.moralemodifier = 1.0f;
pData->maxReadDepth++; //we are not skipping this element
}
else if ( pData->curElement == ELEMENT &&
@@ -86,7 +89,8 @@ diseaseStartElementHandle( void *userData, const XML_Char *name, const XML_Char
strcmp( name, "sLifeRegenHundreds" ) == 0 ||
strcmp( name, "sNeedToSleep" ) == 0 ||
strcmp( name, "sDrinkModifier" ) == 0 ||
strcmp( name, "sFoodModifier" ) == 0) )
strcmp( name, "sFoodModifier" ) == 0 ||
strcmp( name, "moralemodifier" ) == 0 ) )
{
pData->curElement = ELEMENT_PROPERTY;
@@ -345,6 +349,11 @@ diseaseEndElementHandle( void *userData, const XML_Char *name )
pData->curElement = ELEMENT;
pData->curItem.sFoodModifier = (INT16)atol( pData->szCharData );
}
else if ( strcmp( name, "moralemodifier" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curItem.moralemodifier = (FLOAT)atof( pData->szCharData );
}
pData->maxReadDepth--;
}
@@ -468,6 +477,7 @@ BOOLEAN WriteDiseaseStats( )
FilePrintf( hFile, "\t\t<sNeedToSleep>%d</sNeedToSleep>\r\n", Disease[cnt].sNeedToSleep );
FilePrintf( hFile, "\t\t<sDrinkModifier>%d</sDrinkModifier>\r\n", Disease[cnt].sDrinkModifier );
FilePrintf( hFile, "\t\t<sFoodModifier>%d</sFoodModifier>\r\n", Disease[cnt].sFoodModifier );
FilePrintf( hFile, "\t\t<moralemodifier>%3.2f</moralemodifier>\r\n", Disease[cnt].moralemodifier );
FilePrintf( hFile, "\t</DISEASE>\r\n" );
}
+230 -54
View File
@@ -14,12 +14,17 @@ struct
PARSE_STAGE curElement;
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
DRUGTYPE curDrugs;
DRUGTYPE * curArray;
UINT32 maxArraySize;
DRUG curDrugs;
DRUG * curArray;
UINT32 maxArraySize;
UINT32 currentDepth;
UINT32 maxReadDepth;
UINT32 currentDepth;
UINT32 maxReadDepth;
DRUG_EFFECT drug_effects;
DISEASE_EFFECT disease_effects;
DISABILITY_EFFECT disability_effects;
PERSONALITY_EFFECT personality_effects;
}
typedef drugsParseData;
@@ -34,7 +39,7 @@ drugsStartElementHandle(void *userData, const XML_Char *name, const XML_Char **a
{
pData->curElement = ELEMENT_LIST;
memset(pData->curArray,0,sizeof(DRUGTYPE)*pData->maxArraySize);
memset(pData->curArray,0,sizeof(DRUG)*pData->maxArraySize);
pData->maxReadDepth++; //we are not skipping this element
}
@@ -42,27 +47,106 @@ drugsStartElementHandle(void *userData, const XML_Char *name, const XML_Char **a
{
pData->curElement = ELEMENT;
memset(&pData->curDrugs,0,sizeof(DRUGTYPE));
memset( &pData->curDrugs, 0, sizeof(DRUG) );
pData->maxReadDepth++; //we are not skipping this element
}
else if(pData->curElement == ELEMENT &&
(strcmp(name, "ubType") == 0 ||
strcmp(name, "name") == 0 ||
strcmp(name, "ubDrugTravelRate") == 0 ||
strcmp(name, "ubDrugWearoffRate") == 0 ||
strcmp(name, "ubDrugEffect") == 0 ||
strcmp(name, "ubDrugSideEffect") == 0 ||
strcmp(name, "ubDrugSideEffectRate") == 0 ||
strcmp(name, "ubMoralBacklash" ) == 0 ||
strcmp(name, "ubMoralBacklash" ) == 0 ||
strcmp(name, "ubDiseaseCure" ) == 0 ))
(strcmp(name, "uiIndex") == 0 ||
strcmp(name, "szName") == 0 ||
strcmp(name, "opinionevent" ) == 0 ))
{
pData->curElement = ELEMENT_PROPERTY;
pData->maxReadDepth++; //we are not skipping this element
}
else if ( pData->curElement == ELEMENT &&
(strcmp( name, "DRUG_EFFECT" ) == 0) )
{
pData->curElement = ELEMENT_DRUG_EFFECT;
// start of a new element: set default values
pData->drug_effects.effect = 0;
pData->drug_effects.duration = 0;
pData->drug_effects.size = 0;
pData->drug_effects.chance = 100;
pData->maxReadDepth++;
}
else if ( pData->curElement == ELEMENT &&
(strcmp( name, "DISEASE_EFFECT" ) == 0) )
{
pData->curElement = ELEMENT_DISEASE_EFFECT;
// start of a new element: set default values
pData->disease_effects.disease = 0;
pData->disease_effects.size = 0;
pData->disease_effects.chance = 100;
pData->maxReadDepth++;
}
else if ( pData->curElement == ELEMENT &&
(strcmp( name, "DISABILITY_EFFECT" ) == 0) )
{
pData->curElement = ELEMENT_DISABILITY_EFFECT;
// start of a new element: set default values
pData->disability_effects.disability = 0;
pData->disability_effects.duration = 0;
pData->disability_effects.chance = 100;
pData->maxReadDepth++;
}
else if ( pData->curElement == ELEMENT &&
(strcmp( name, "PERSONALITY_EFFECT" ) == 0) )
{
pData->curElement = ELEMENT_PERSONALITY_EFFECT;
// start of a new element: set default values
pData->personality_effects.personality = 0;
pData->personality_effects.duration = 0;
pData->personality_effects.chance = 100;
pData->maxReadDepth++;
}
else if ( pData->curElement == ELEMENT_DRUG_EFFECT &&
(strcmp( name, "effect" ) == 0 ||
strcmp( name, "duration" ) == 0 ||
strcmp( name, "size" ) == 0 ||
strcmp( name, "chance" ) == 0 ) )
{
pData->curElement = ELEMENT_DRUG_EFFECT_PROPERTY;
pData->maxReadDepth++; //we are not skipping this element
}
else if ( pData->curElement == ELEMENT_DISEASE_EFFECT &&
(strcmp( name, "disease" ) == 0 ||
strcmp( name, "size" ) == 0 ||
strcmp( name, "chance" ) == 0) )
{
pData->curElement = ELEMENT_DISEASE_EFFECT_PROPERTY;
pData->maxReadDepth++; //we are not skipping this element
}
else if ( pData->curElement == ELEMENT_DISABILITY_EFFECT &&
(strcmp( name, "disability" ) == 0 ||
strcmp( name, "duration" ) == 0 ||
strcmp( name, "chance" ) == 0) )
{
pData->curElement = ELEMENT_DISABILITY_EFFECT_PROPERTY;
pData->maxReadDepth++; //we are not skipping this element
}
else if ( pData->curElement == ELEMENT_PERSONALITY_EFFECT &&
(strcmp( name, "personality" ) == 0 ||
strcmp( name, "duration" ) == 0 ||
strcmp( name, "chance" ) == 0) )
{
pData->curElement = ELEMENT_PERSONALITY_EFFECT_PROPERTY;
pData->maxReadDepth++; //we are not skipping this element
}
pData->szCharData[0] = '\0';
}
@@ -98,56 +182,127 @@ drugsEndElementHandle(void *userData, const XML_Char *name)
{
pData->curElement = ELEMENT_LIST;
// we do NOT want to read the first entry -> move stuff by 1
if(pData->curDrugs.ubType < pData->maxArraySize + 1 && pData->curDrugs.ubType > 0) // do not write the first item into our array
{
pData->curArray[pData->curDrugs.ubType - 1] = pData->curDrugs; //write the drugs into the table
}
pData->curArray[pData->curDrugs.uiIndex] = pData->curDrugs; //write the drugs into the table
}
else if(strcmp(name, "ubType") == 0)
else if(strcmp(name, "uiIndex") == 0)
{
pData->curElement = ELEMENT;
pData->curDrugs.ubType = (UINT8) atol(pData->szCharData);
pData->curDrugs.uiIndex = (UINT8)atol( pData->szCharData );
}
else if(strcmp(name, "name") == 0)
else if(strcmp(name, "szName") == 0)
{
pData->curElement = ELEMENT;
// not needed, but its there for informational purposes
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curDrugs.szName, sizeof(pData->curDrugs.szName) / sizeof(pData->curDrugs.szName[0]) );
pData->curDrugs.szName[sizeof(pData->curDrugs.szName) / sizeof(pData->curDrugs.szName[0]) - 1] = '\0';
}
else if(strcmp(name, "ubDrugTravelRate") == 0)
else if(strcmp(name, "opinionevent") == 0)
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDrugTravelRate = (UINT8) atol(pData->szCharData);
pData->curDrugs.opinionevent = (BOOLEAN)atol( pData->szCharData );
}
else if(strcmp(name, "ubDrugWearoffRate") == 0)
// Close opened Tags.
else if ( strcmp( name, "DRUG_EFFECT" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDrugWearoffRate = (UINT8) atol(pData->szCharData);
pData->curDrugs.drug_effects.push_back( pData->drug_effects );
}
else if(strcmp(name, "ubDrugEffect") == 0)
else if ( strcmp( name, "DISEASE_EFFECT" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDrugEffect = (UINT8) atol(pData->szCharData);
pData->curDrugs.disease_effects.push_back( pData->disease_effects );
}
else if(strcmp(name, "ubDrugSideEffect") == 0)
else if ( strcmp( name, "DISABILITY_EFFECT" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDrugSideEffect = (UINT8) atol(pData->szCharData);
pData->curDrugs.disability_effects.push_back( pData->disability_effects );
}
else if(strcmp(name, "ubDrugSideEffectRate") == 0)
else if ( strcmp( name, "PERSONALITY_EFFECT" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDrugSideEffectRate = (UINT8) atol(pData->szCharData);
pData->curDrugs.personality_effects.push_back( pData->personality_effects );
}
else if(strcmp(name, "ubMoralBacklash") == 0)
else if ( pData->curElement == ELEMENT_DRUG_EFFECT_PROPERTY )
{
pData->curElement = ELEMENT;
pData->curDrugs.ubMoralBacklash = (UINT8) atol(pData->szCharData);
if ( strcmp( name, "effect" ) == 0 )
{
pData->drug_effects.effect = (UINT8)atol( pData->szCharData );
}
else if ( strcmp( name, "duration" ) == 0 )
{
pData->drug_effects.duration = (UINT16)atol( pData->szCharData );
}
else if ( strcmp( name, "size" ) == 0 )
{
pData->drug_effects.size = (INT16)atol( pData->szCharData );
}
else if ( strcmp( name, "chance" ) == 0 )
{
pData->drug_effects.chance = (UINT8)atol( pData->szCharData );
}
pData->curElement = ELEMENT_DRUG_EFFECT;
}
else if ( strcmp( name, "ubDiseaseCure" ) == 0 )
else if ( pData->curElement == ELEMENT_DISEASE_EFFECT_PROPERTY )
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDiseaseCure = (UINT8)atol( pData->szCharData );
if ( strcmp( name, "disease" ) == 0 )
{
pData->disease_effects.disease = (UINT8)atol( pData->szCharData );
}
else if ( strcmp( name, "size" ) == 0 )
{
pData->disease_effects.size = (INT32)atol( pData->szCharData );
}
else if ( strcmp( name, "chance" ) == 0 )
{
pData->disease_effects.chance = (UINT8)atol( pData->szCharData );
}
pData->curElement = ELEMENT_DISEASE_EFFECT;
}
else if ( pData->curElement == ELEMENT_DISABILITY_EFFECT_PROPERTY )
{
if ( strcmp( name, "disability" ) == 0 )
{
pData->disability_effects.disability = (UINT8)atol( pData->szCharData );
}
else if ( strcmp( name, "duration" ) == 0 )
{
pData->disability_effects.duration = (UINT16)atol( pData->szCharData );
}
else if ( strcmp( name, "chance" ) == 0 )
{
pData->disability_effects.chance = (UINT8)atol( pData->szCharData );
}
pData->curElement = ELEMENT_DISABILITY_EFFECT;
}
else if ( pData->curElement == ELEMENT_PERSONALITY_EFFECT_PROPERTY )
{
if ( strcmp( name, "personality" ) == 0 )
{
pData->personality_effects.personality = (UINT8)atol( pData->szCharData );
}
else if ( strcmp( name, "duration" ) == 0 )
{
pData->personality_effects.duration = (UINT16)atol( pData->szCharData );
}
else if ( strcmp( name, "chance" ) == 0 )
{
pData->personality_effects.chance = (UINT8)atol( pData->szCharData );
}
pData->curElement = ELEMENT_PERSONALITY_EFFECT;
}
pData->maxReadDepth--;
@@ -196,8 +351,8 @@ BOOLEAN ReadInDrugsStats(STR fileName)
memset(&pData,0,sizeof(pData));
pData.curArray = Drug;
pData.maxArraySize = DRUG_TYPE_MAX;
pData.curArray = NewDrug;
pData.maxArraySize = NEW_DRUGS_MAX;
XML_SetUserData(parser, &pData);
@@ -234,21 +389,42 @@ BOOLEAN WriteDrugsStats()
return( FALSE );
{
UINT32 cnt;
FilePrintf(hFile,"<DRUGSLIST>\r\n");
for(cnt = 0;cnt < DRUG_TYPE_MAX;cnt++)
for ( UINT32 cnt = 0; cnt < NEW_DRUGS_MAX; ++cnt )
{
FilePrintf(hFile,"\t<DRUG>\r\n");
FilePrintf(hFile,"\t\t<ubType>%d</ubType>\r\n", cnt );
FilePrintf(hFile,"\t\t<ubDrugTravelRate>%d</ubDrugTravelRate>\r\n", Drug[cnt].ubDrugTravelRate );
FilePrintf(hFile,"\t\t<ubDrugWearoffRate>%d</ubDrugWearoffRate>\r\n", Drug[cnt].ubDrugWearoffRate );
FilePrintf(hFile,"\t\t<ubDrugEffect>%d</ubDrugEffect>\r\n", Drug[cnt].ubDrugEffect );
FilePrintf(hFile,"\t\t<ubDrugSideEffect>%d</ubDrugSideEffect>\r\n", Drug[cnt].ubDrugSideEffect );
FilePrintf(hFile,"\t\t<ubDrugSideEffectRate>%d</ubDrugSideEffectRate>\r\n", Drug[cnt].ubDrugSideEffectRate );
FilePrintf(hFile,"\t\t<ubMoralBacklash>%d</ubMoralBacklash>\r\n", Drug[cnt].ubMoralBacklash );
FilePrintf(hFile,"\t\t<ubDiseaseCure>%d</ubDiseaseCure>\r\n", Drug[cnt].ubDiseaseCure );
FilePrintf(hFile,"\t\t<uiIndex>%d</uiIndex>\r\n", cnt );
FilePrintf(hFile,"\t\t<opinionevent>%d</opinionevent>\r\n", NewDrug[cnt].opinionevent );
for ( std::vector<DRUG_EFFECT>::iterator it = NewDrug[cnt].drug_effects.begin( ); it != NewDrug[cnt].drug_effects.end( ); ++it )
{
FilePrintf( hFile, "\t\t<effect>%d</effect>\r\n", (*it).effect );
FilePrintf( hFile, "\t\t<duration>%d</duration>\r\n", (*it).duration );
FilePrintf( hFile, "\t\t<size>%d</size>\r\n", (*it).size );
FilePrintf( hFile, "\t\t<chance>%d</chance>\r\n", (*it).chance );
}
for ( std::vector<DISEASE_EFFECT>::iterator it = NewDrug[cnt].disease_effects.begin( ); it != NewDrug[cnt].disease_effects.end( ); ++it )
{
FilePrintf( hFile, "\t\t<disease>%d</disease>\r\n", (*it).disease );
FilePrintf( hFile, "\t\t<size>%d</size>\r\n", (*it).size );
FilePrintf( hFile, "\t\t<chance>%d</chance>\r\n", (*it).chance );
}
for ( std::vector<DISABILITY_EFFECT>::iterator it = NewDrug[cnt].disability_effects.begin( ); it != NewDrug[cnt].disability_effects.end( ); ++it )
{
FilePrintf( hFile, "\t\t<disability>%d</disability>\r\n", (*it).disability );
FilePrintf( hFile, "\t\t<duration>%d</duration>\r\n", (*it).duration );
FilePrintf( hFile, "\t\t<chance>%d</chance>\r\n", (*it).chance );
}
for ( std::vector<PERSONALITY_EFFECT>::iterator it = NewDrug[cnt].personality_effects.begin( ); it != NewDrug[cnt].personality_effects.end( ); ++it )
{
FilePrintf( hFile, "\t\t<personality>%d</personality>\r\n", (*it).personality );
FilePrintf( hFile, "\t\t<duration>%d</duration>\r\n", (*it).duration );
FilePrintf( hFile, "\t\t<chance>%d</chance>\r\n", (*it).chance );
}
FilePrintf(hFile,"\t</DRUG>\r\n");
}
-7
View File
@@ -51,7 +51,6 @@ foodStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
strcmp(name, "szName") == 0 ||
strcmp(name, "bFoodPoints") == 0 ||
strcmp(name, "bDrinkPoints") == 0 ||
strcmp(name, "ubPortionSize") == 0 ||
strcmp(name, "usDecayRate") == 0 ))
{
pData->curElement = ELEMENT_PROPERTY;
@@ -120,11 +119,6 @@ foodEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curFood.bDrinkPoints = (INT32) atol(pData->szCharData);
}
else if(strcmp(name, "ubPortionSize") == 0)
{
pData->curElement = ELEMENT;
pData->curFood.ubPortionSize = (UINT16) atol(pData->szCharData);
}
else if(strcmp(name, "usDecayRate") == 0)
{
pData->curElement = ELEMENT;
@@ -225,7 +219,6 @@ BOOLEAN WriteFoodStats()
FilePrintf(hFile,"\t\t<uiIndex>%d</uiIndex>\r\n", cnt );
FilePrintf(hFile,"\t\t<bFoodPoints>%d</bFoodPoints>\r\n", Food[cnt].bFoodPoints );
FilePrintf(hFile,"\t\t<bDrinkPoints>%d</bDrinkPoints>\r\n", Food[cnt].bDrinkPoints );
FilePrintf(hFile,"\t\t<ubPortionSize>%d</ubPortionSize>\r\n", Food[cnt].ubPortionSize );
FilePrintf(hFile,"\t\t<usDecayRate>%4.2f</usDecayRate>\r\n", Food[cnt].usDecayRate );
FilePrintf(hFile,"\t</FOOD>\r\n");
+5 -4
View File
@@ -4120,7 +4120,7 @@ void DebugSoldierPage1( )
gprintf( 350, LINE_HEIGHT * ubLine, L"%d", pSoldier->stats.bMedical);
ubLine++;
SetFontShade(LARGEFONT1, FONT_SHADE_GREEN);
/*SetFontShade(LARGEFONT1, FONT_SHADE_GREEN);
gprintf( 200, LINE_HEIGHT * ubLine, L"Drug Effects:");
SetFontShade(LARGEFONT1, FONT_SHADE_NEUTRAL);
gprintf( 400, LINE_HEIGHT * ubLine, L"%d", pSoldier->drugs.bDrugEffect[0] );
@@ -4142,7 +4142,7 @@ void DebugSoldierPage1( )
gprintf( 200, LINE_HEIGHT * ubLine, L"Hangover Side Effects:");
SetFontShade(LARGEFONT1, FONT_SHADE_NEUTRAL);
gprintf( 400, LINE_HEIGHT * ubLine, L"%d", pSoldier->drugs.bDrugSideEffect[1] );
ubLine++;
ubLine++;*/
SetFontShade(LARGEFONT1, FONT_SHADE_GREEN);
gprintf( 200, LINE_HEIGHT * ubLine, L"AI has Keys:");
@@ -5428,11 +5428,12 @@ UINT8 MovementNoise( SOLDIERTYPE *pSoldier )
iStealthSkill -= 20; // 20% penalty
}
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
// Flugente: deleting this
/*if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
{
// minus 3 percent per bonus AP from adrenaline
iStealthSkill -= 3 * pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ];
}
}*/
/*
// if sneaker is too eager and impatient to "do it right"
+1 -1
View File
@@ -309,7 +309,7 @@ typedef enum
} RacistLevels;
// Flugente: dynamic opinons: number of profile flagmasks
#define OPINION_FLAGMASKS_NUMBER 5
#define OPINION_FLAGMASKS_NUMBER 6
//////////////////////////////////////////////////////////////////////
+10 -5
View File
@@ -54,6 +54,7 @@
#include "BriefingRoom_Data.h"
#include "Map Screen Helicopter.h"
#include "Drugs And Alcohol.h" // added by Flugente for DoesMercHavePersonality( ... )
#ifdef JA2UB
#include "Ja25_Tactical.h"
@@ -872,7 +873,7 @@ INT32 CalcThreateningEffectiveness( UINT8 ubMerc )
}
// SANDRO - bonus for threatening for assertive people
if ( gGameOptions.fNewTraitSystem && gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_ASSERTIVE )
if ( gGameOptions.fNewTraitSystem && DoesMercHavePersonality( pSoldier, CHAR_TRAIT_ASSERTIVE ) )
{
iDeadliness += 50;
}
@@ -899,10 +900,14 @@ UINT8 CalcDesireToTalk( UINT8 ubNPC, UINT8 ubMerc, INT8 bApproach )
// SANDRO - bonus for communication with people for assertive people
if ( gGameOptions.fNewTraitSystem && bApproach != APPROACH_THREATEN)
{
if ( pMercProfile->bCharacterTrait == CHAR_TRAIT_ASSERTIVE )
iPersonalVal += 50;
else if ( pMercProfile->bCharacterTrait == CHAR_TRAIT_MALICIOUS )
iPersonalVal -= 50;
INT16 id = GetSoldierIDFromMercID( ubMerc );
if ( id > -1 )
{
if ( DoesMercHavePersonality( MercPtrs[id], CHAR_TRAIT_ASSERTIVE ) )
iPersonalVal += 50;
else if ( DoesMercHavePersonality( MercPtrs[id], CHAR_TRAIT_MALICIOUS ) )
iPersonalVal -= 50;
}
}
// ARM: NOTE - for towns which don't use loyalty (San Mona, Estoni, Tixa, Orta )
+1 -1
View File
@@ -5561,7 +5561,7 @@ BOOLEAN HandleAttachedExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, IN
IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, GAS_EXPLOSION, bLevel, DIRECTION_IRRELEVANT , NULL );
fAttFound = TRUE;
}
if(Item[iter->usItem].alcohol)
if ( Item[iter->usItem].alcohol > 0.0f )
{
IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, MOLOTOV_EXPLOSION, bLevel, DIRECTION_IRRELEVANT , NULL );
fAttFound = TRUE;
+1
View File
@@ -489,6 +489,7 @@ enum
MSG_MERC_CASTS_LIGHT_OFF,
MSG_SQUAD_ACTIVE_STRING,
MSG_MERC_TOOK_CIGARETTE,
TEXT_NUM_MSG,
};
+24 -5
View File
@@ -85,13 +85,16 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
if ( !localizedTextOnly )
memset(&pData->curItem,0,sizeof(INVTYPE));
// Flugente: default value
pData->curItem.usPortionSize = 100;
// HEADROCK HAM 4: With the new stance-based variables, it is necessary to set vars to have an impossible
// value. That way when they are later recorded in the item structs, a parent->child inheritence can occur
// for children that do not have data put into them from XML.
// -10000 has been selected to pose as "no value". Modders should never even reduce the value of any of
// these tags below -100 anyway, and although it's not the best solution that's the only one I came up with.
for (INT8 X = 0; X < 3; X++)
for (INT8 X = 0; X < 3; ++X)
{
pData->curItem.flatbasemodifier[X] = -10000;
pData->curItem.percentbasemodifier[X] = -10000;
@@ -283,6 +286,8 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
strcmp(name, "usSpotting") == 0 ||
strcmp(name, "sBackpackWeightModifier") == 0 ||
strcmp(name, "fAllowClimbing") == 0 ||
strcmp(name, "cigarette" ) == 0 ||
strcmp(name, "usPortionSize" ) == 0 ||
strcmp(name, "diseaseprotectionface" ) == 0 ||
strcmp(name, "diseaseprotectionhand" ) == 0))
{
@@ -941,7 +946,9 @@ itemEndElementHandle(void *userData, const XML_Char *name)
else if(strcmp(name, "Alcohol") == 0)
{
pData->curElement = ELEMENT;
pData->curItem.alcohol = (BOOLEAN) atol(pData->szCharData);
pData->curItem.alcohol = (FLOAT) atof(pData->szCharData);
pData->curItem.alcohol = max( 0.0f, pData->curItem.alcohol );
}
else if(strcmp(name, "Hardware") == 0)
{
@@ -1453,6 +1460,16 @@ itemEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curItem.fAllowClimbing = (BOOLEAN)atol(pData->szCharData);
}
else if ( strcmp( name, "cigarette" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curItem.cigarette = (BOOLEAN)atol( pData->szCharData );
}
else if ( strcmp( name, "usPortionSize" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curItem.usPortionSize = (UINT8)atol( pData->szCharData );
}
// Flugente: simple tags in the xml get translated into flags
else if ( strcmp( name, "diseaseprotectionface" ) == 0 )
{
@@ -1986,7 +2003,7 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile,"\t\t<GasMask>%d</GasMask>\r\n", Item[cnt].gasmask );
FilePrintf(hFile,"\t\t<Alcohol>%d</Alcohol>\r\n", Item[cnt].alcohol );
FilePrintf(hFile,"\t\t<Alcohol>%3.2f</Alcohol>\r\n", Item[cnt].alcohol );
FilePrintf(hFile,"\t\t<Hardware>%d</Hardware>\r\n", Item[cnt].hardware );
FilePrintf(hFile,"\t\t<Medical>%d</Medical>\r\n", Item[cnt].medical );
FilePrintf(hFile,"\t\t<CamouflageKit>%d</CamouflageKit>\r\n", Item[cnt].camouflagekit );
@@ -2095,8 +2112,10 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile,"\t\t<buddyitem>%d</buddyitem>\r\n", Item[cnt].usBuddyItem );
FilePrintf(hFile,"\t\t<SleepModifier>%d</SleepModifier>\r\n", Item[cnt].ubSleepModifier );
FilePrintf(hFile,"\t\t<usSpotting>%d</usSpotting>\r\n", Item[cnt].usSpotting );
FilePrintf(hFile, "\t\t<sBackpackWeightModifier>%d</sBackpackWeightModifier>\r\n", Item[cnt].sBackpackWeightModifier);
FilePrintf(hFile, "\t\t<fAllowClimbing>%d</fAllowClimbing>\r\n", Item[cnt].fAllowClimbing);
FilePrintf(hFile,"\t\t<sBackpackWeightModifier>%d</sBackpackWeightModifier>\r\n", Item[cnt].sBackpackWeightModifier);
FilePrintf(hFile,"\t\t<fAllowClimbing>%d</fAllowClimbing>\r\n", Item[cnt].fAllowClimbing);
FilePrintf(hFile, "\t\t<cigarette>%d</cigarette>\r\n", Item[cnt].cigarette );
FilePrintf(hFile,"\t\t<usPortionSize>%d</usPortionSize>\r\n", Item[cnt].usPortionSize );
if ( Item[cnt].usItemFlag & DISEASEPROTECTION_1 )
FilePrintf( hFile, "\t\t<diseaseprotectionface>%d</diseaseprotectionface>\r\n", 1 );
+3
View File
@@ -6207,6 +6207,7 @@ STR16 pMessageStrings[] =
L"虚拟佣兵光照开启",
L"虚拟佣兵光照关闭",
L"Squad %s active.", //TODO.Translate
L"%s smoked %s.",
};
@@ -8278,6 +8279,8 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% initial distance to enemy in ambush\n",
L" dislikes some other backgrounds", // TODO.Translate
L"Smoker",
L"Nonsmoker",
};
STR16 szBackgroundTitleText[] =
+3
View File
@@ -6215,6 +6215,7 @@ STR16 pMessageStrings[] =
L"Artificial Merc Light ON", // TODO.Translate
L"Artificial Merc Light OFF",
L"Squad %s active.", //TODO.Translate
L"%s smoked %s.",
};
@@ -8291,6 +8292,8 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% initial distance to enemy in ambush\n",
L" dislikes some other backgrounds", // TODO.Translate
L"Smoker",
L"Nonsmoker",
};
STR16 szBackgroundTitleText[] = // TODO.Translate
+3
View File
@@ -6206,6 +6206,7 @@ STR16 pMessageStrings[] =
L"Artificial Merc Light ON",
L"Artificial Merc Light OFF",
L"Squad %s active.",
L"%s smoked %s.",
};
@@ -8276,6 +8277,8 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% initial distance to enemy in ambush\n",
L" dislikes some other backgrounds",
L"Smoker",
L"Nonsmoker",
};
STR16 szBackgroundTitleText[] =
+3
View File
@@ -6217,6 +6217,7 @@ STR16 pMessageStrings[] =
L"Éclairage du mercenaire activé",
L"Éclairage du mercenaire désactivé",
L"Squad %s active.", //TODO.Translate
L"%s smoked %s.",
};
@@ -8277,6 +8278,8 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% initial distance to enemy in ambush\n",
L" dislikes some other backgrounds", // TODO.Translate
L"Smoker",
L"Nonsmoker",
};
STR16 szBackgroundTitleText[] =
+3
View File
@@ -6052,6 +6052,7 @@ STR16 pMessageStrings[] =
L"Artificial Merc Light ON", // TODO.Translate
L"Artificial Merc Light OFF",
L"Squad %s active.", //TODO.Translate
L"%s smoked %s.",
};
CHAR16 ItemPickupHelpPopup[][40] =
@@ -8108,6 +8109,8 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% initial distance to enemy in ambush\n",
L" dislikes some other backgrounds", // TODO.Translate
L"Smoker",
L"Nonsmoker",
};
STR16 szBackgroundTitleText[] = // TODO.Translate
+3
View File
@@ -6203,6 +6203,7 @@ STR16 pMessageStrings[] =
L"Artificial Merc Light ON", // TODO.Translate
L"Artificial Merc Light OFF",
L"Squad %s active.", //TODO.Translate
L"%s smoked %s.",
};
@@ -8286,6 +8287,8 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% initial distance to enemy in ambush\n",
L" dislikes some other backgrounds", // TODO.Translate
L"Smoker",
L"Nonsmoker",
};
STR16 szBackgroundTitleText[] = // TODO.Translate
+3
View File
@@ -6221,6 +6221,7 @@ STR16 pMessageStrings[] =
L"Artificial Merc Light ON", // TODO.Translate
L"Artificial Merc Light OFF",
L"Squad %s active.", //TODO.Translate
L"%s smoked %s.",
};
@@ -8303,6 +8304,8 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% initial distance to enemy in ambush\n",
L" dislikes some other backgrounds", // TODO.Translate
L"Smoker",
L"Nonsmoker",
};
STR16 szBackgroundTitleText[] = // TODO.Translate
+3
View File
@@ -6203,6 +6203,7 @@ STR16 pMessageStrings[] =
L"Подсветка наемника включена",
L"Подсветка наемника отключена",
L"Squad %s active.", //TODO.Translate
L"%s smoked %s.",
};
@@ -8275,6 +8276,8 @@ STR16 szBackgroundText_Value[]=
L" %s%d%% initial distance to enemy in ambush\n",
L" dislikes some other backgrounds", // TODO.Translate
L"Smoker",
L"Nonsmoker",
};
STR16 szBackgroundTitleText[] =