mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
New feature: Covert ops
- you can disguise members of your team as civilians or soldiers and, if careful, avoid detection by the enemy. - For more info, see http://www.bears-pit.com/board/ubbthreads.php/topics/309312/New_feature_Covert_operations.html#Post309312 - GameDir revision >= 1529 is needed for this feature - fixed a bug that could cause inventory items to be treated like armed bombs - bloodcats can now be skinned git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5529 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -2142,6 +2142,12 @@ void LoadSkillTraitsExternalSettings()
|
||||
gSkillTraitValues.fSCPreventsBloodcatsAmbushes = iniReader.ReadBoolean("Scouting","PREVENTS_BLOODCATS_AMBUSHES", TRUE);
|
||||
gSkillTraitValues.fSCThrowMessageIfAmbushPrevented = iniReader.ReadBoolean("Scouting","SHOW_MESSAGE_IF_AMBUSH_PREVENTED", TRUE);
|
||||
|
||||
// Flugente: COVERT OPS
|
||||
gSkillTraitValues.sCOMeleeCTHBonus = iniReader.ReadInteger("Covert Ops","COVERT_MELEE_CTH_BONUS", 40, 0, 200);
|
||||
gSkillTraitValues.sCoMeleeInstakillBonus = iniReader.ReadInteger("Covert Ops","COVERT_MELEE_INSTAKILL_BONUS", 35, 0, 200);
|
||||
gSkillTraitValues.sCODisguiseAPReduction = iniReader.ReadInteger("Covert Ops","COVERT_DISGUISE_PERCENT_AP_REDUCTION", 20, 0, 100);
|
||||
gSkillTraitValues.sCOCloseDetectionRange = iniReader.ReadInteger("Covert Ops","COVERT_CLOSE_DETECTION_RANGE", 10, 0, 100);
|
||||
gSkillTraitValues.sCOCloseDetectionRangeSoldierCorpse = iniReader.ReadInteger("Covert Ops","COVERT_CLOSE_DETECTION_RANGE_SOLDIER_CORPSE", 5, 0, 100);
|
||||
}
|
||||
//DBrot: Grids
|
||||
void LoadModSettings(){
|
||||
@@ -2441,6 +2447,7 @@ void LoadGameAPBPConstants()
|
||||
APBPConstants[AP_EAT] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_EAT",80),80);
|
||||
APBPConstants[AP_CLEANINGKIT] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_CLEANINGKIT",80),80);
|
||||
APBPConstants[AP_INVENTORY_EXPLOSIVE_ACTIVATE] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_INVENTORY_EXPLOSIVE_ACTIVATE",20),20);
|
||||
APBPConstants[AP_DISGUISE] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_DISGUISE",80),80);
|
||||
|
||||
SetupMaxActionPointsAnimation();
|
||||
#undef ReadInteger
|
||||
|
||||
@@ -1418,6 +1418,13 @@ typedef struct
|
||||
BOOLEAN fSCPreventsBloodcatsAmbushes;
|
||||
BOOLEAN fSCThrowMessageIfAmbushPrevented;
|
||||
|
||||
// COVERT OPS
|
||||
INT16 sCOMeleeCTHBonus;
|
||||
INT16 sCoMeleeInstakillBonus;
|
||||
INT16 sCODisguiseAPReduction;
|
||||
INT16 sCOCloseDetectionRange;
|
||||
INT16 sCOCloseDetectionRangeSoldierCorpse;
|
||||
|
||||
} SKILL_TRAIT_VALUES;
|
||||
|
||||
// HEADROCK HAM 4: Constants used as coefficients by the various parts of the new CTH system.
|
||||
|
||||
@@ -201,6 +201,7 @@ AP_FORTIFICATION,
|
||||
AP_EAT,
|
||||
AP_CLEANINGKIT,
|
||||
AP_INVENTORY_EXPLOSIVE_ACTIVATE,
|
||||
AP_DISGUISE,
|
||||
TOTAL_APBP_VALUES
|
||||
};
|
||||
#endif
|
||||
|
||||
+12
-2
@@ -731,6 +731,17 @@ void GiveItemsToPC( UINT8 ubProfileId )
|
||||
GiveIMPRandomItems(pProfile, IMP_DOCTOR);
|
||||
}
|
||||
}
|
||||
if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, COVERT_NT))
|
||||
{
|
||||
if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, COVERT_NT))
|
||||
{
|
||||
GiveIMPRandomItems(pProfile,IMP_COVERT_EXP);
|
||||
}
|
||||
else
|
||||
{
|
||||
GiveIMPRandomItems(pProfile, IMP_COVERT);
|
||||
}
|
||||
}
|
||||
// MINOR TRAITS
|
||||
if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, AMBIDEXTROUS_NT))
|
||||
{
|
||||
@@ -771,8 +782,7 @@ void GiveItemsToPC( UINT8 ubProfileId )
|
||||
if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, SCOUTING_NT))
|
||||
{
|
||||
GiveIMPRandomItems(pProfile,IMP_SCOUTING);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#define IMP_SKILL_TRAIT__GREY_BOX_OFFSET_X 5
|
||||
#define IMP_SKILL_TRAIT__GREY_BOX_OFFSET_Y 7
|
||||
|
||||
#define NEWTRAIT_EXPERT_OFFSET 12 // Flugente: offset between normal and expert trait strings
|
||||
|
||||
//*******************************************************************
|
||||
//
|
||||
@@ -858,7 +859,7 @@ void IMPSkillTraitDisplaySkills()
|
||||
if( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
if ( gfSkillTraitQuestions[ uiCnt ] && gfSkillTraitQuestions2[ uiCnt ] && uiCnt != IMP_SKILL_TRAITS_NEW_MAJOR_NONE )
|
||||
DrawTextToScreen( gzIMPSkillTraitsTextNewMajor[ uiCnt+11 ], usPosX, usPosY, 0, IMP_SKILL_TRAIT__FONT, IMP_SKILL_TRAIT__COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
|
||||
DrawTextToScreen( gzIMPSkillTraitsTextNewMajor[ uiCnt+12 ], usPosX, usPosY, 0, IMP_SKILL_TRAIT__FONT, IMP_SKILL_TRAIT__COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
|
||||
else
|
||||
DrawTextToScreen( gzIMPSkillTraitsTextNewMajor[ uiCnt ], usPosX, usPosY, 0, IMP_SKILL_TRAIT__FONT, IMP_SKILL_TRAIT__COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
|
||||
}
|
||||
@@ -1075,6 +1076,10 @@ void AddSelectedSkillsToSkillsList()
|
||||
AddSkillToSkillList( DOCTOR_NT );
|
||||
break;
|
||||
|
||||
case IMP_SKILL_TRAITS_NEW_COVERT:
|
||||
AddSkillToSkillList( COVERT_NT );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1190,6 +1195,10 @@ void AddSelectedSkillsToSkillsList()
|
||||
AddSkillToSkillList( DOCTOR_NT );
|
||||
break;
|
||||
|
||||
case IMP_SKILL_TRAITS_NEW_COVERT:
|
||||
AddSkillToSkillList( COVERT_NT );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1560,6 +1569,13 @@ INT32 LeadershipRequiredDueToMajorSkills( void )
|
||||
else
|
||||
return (35);
|
||||
}
|
||||
else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_COVERT ])
|
||||
{
|
||||
if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_COVERT ])
|
||||
return (45);
|
||||
else
|
||||
return (30);
|
||||
}
|
||||
// Check the second skill trait
|
||||
else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_SQUADLEADER ])
|
||||
{
|
||||
@@ -1588,6 +1604,13 @@ INT32 WisdomRequiredDueToMajorSkills( void )
|
||||
else
|
||||
return (60);
|
||||
}
|
||||
else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_COVERT ])
|
||||
{
|
||||
if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_COVERT ])
|
||||
return (70);
|
||||
else
|
||||
return (65);
|
||||
}
|
||||
else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
|
||||
{
|
||||
if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
|
||||
@@ -2186,7 +2209,7 @@ void AssignSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLevel )
|
||||
}
|
||||
if( gSkillTraitValues.ubSLEffectiveLevelInRadius != 0 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[1], ( gSkillTraitValues.ubSLEffectiveLevelInRadius * (fExpertLevel ? 2 : 1)), (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[1], ( gSkillTraitValues.ubSLEffectiveLevelInRadius * (fExpertLevel ? 2 : 1)), (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + NEWTRAIT_EXPERT_OFFSET] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
if( gSkillTraitValues.ubSLEffectiveLevelAsStandby != 0 )
|
||||
@@ -2201,7 +2224,7 @@ void AssignSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLevel )
|
||||
}
|
||||
if( gSkillTraitValues.ubSLOverallSuppresionBonusPercent != 0 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[3], ( gSkillTraitValues.ubSLOverallSuppresionBonusPercent * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[3], ( gSkillTraitValues.ubSLOverallSuppresionBonusPercent * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + NEWTRAIT_EXPERT_OFFSET] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
if( gSkillTraitValues.ubSLMoraleGainBonus != 0 )
|
||||
@@ -2231,12 +2254,12 @@ void AssignSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLevel )
|
||||
|
||||
if( gSkillTraitValues.ubSLFearResistance != 0 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[9], ( gSkillTraitValues.ubSLFearResistance * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[9], ( gSkillTraitValues.ubSLFearResistance * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + NEWTRAIT_EXPERT_OFFSET] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
if( gSkillTraitValues.ubSLDeathMoralelossMultiplier != 0 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[10], (1 + ( gSkillTraitValues.ubSLDeathMoralelossMultiplier * (fExpertLevel ? 2 : 1))), (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[10], (1 + ( gSkillTraitValues.ubSLDeathMoralelossMultiplier * (fExpertLevel ? 2 : 1))), (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + NEWTRAIT_EXPERT_OFFSET] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
break;
|
||||
@@ -2281,17 +2304,17 @@ void AssignSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLevel )
|
||||
}
|
||||
if( gSkillTraitValues.ubTECtHControlledRobotBonus != 0 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[7], ( gSkillTraitValues.ubTECtHControlledRobotBonus * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[7], ( gSkillTraitValues.ubTECtHControlledRobotBonus * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + NEWTRAIT_EXPERT_OFFSET] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
if( gSkillTraitValues.ubTETraitsNumToRepairRobot == 2 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + NEWTRAIT_EXPERT_OFFSET] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
else if( gSkillTraitValues.ubTETraitsNumToRepairRobot == 1 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + NEWTRAIT_EXPERT_OFFSET] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
if( gSkillTraitValues.ubTERepairRobotPenaltyReduction != 0 && fExpertLevel)
|
||||
@@ -2353,6 +2376,35 @@ void AssignSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLevel )
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IMP_SKILL_TRAITS_NEW_COVERT:
|
||||
{
|
||||
swprintf( apStr, L"" );
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[0]);
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[1]);
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
if ( !fExpertLevel )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[2], gSkillTraitValues.sCOCloseDetectionRange);
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[3], gSkillTraitValues.sCOCloseDetectionRangeSoldierCorpse);
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[4], ( gSkillTraitValues.sCOMeleeCTHBonus * (fExpertLevel ? 2 : 1)), L"%");
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[5], ( gSkillTraitValues.sCoMeleeInstakillBonus * (fExpertLevel ? 2 : 1)), L"%");
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
INT16 apreduction = ( gSkillTraitValues.sCODisguiseAPReduction * (fExpertLevel ? 2 : 1));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[6], apreduction, L"%");
|
||||
wcscat( apStr, atStr );
|
||||
break;
|
||||
}
|
||||
case IMP_SKILL_TRAITS_NEW_MAJOR_NONE:
|
||||
{
|
||||
swprintf( apStr, gzIMPMajorTraitsHelpTextsNone[0] );
|
||||
|
||||
@@ -41,6 +41,7 @@ enum
|
||||
IMP_SKILL_TRAITS_NEW_SQUADLEADER,
|
||||
IMP_SKILL_TRAITS_NEW_TECHNICIAN,
|
||||
IMP_SKILL_TRAITS_NEW_DOCTOR,
|
||||
IMP_SKILL_TRAITS_NEW_COVERT,
|
||||
IMP_SKILL_TRAITS_NEW_MAJOR_NONE,
|
||||
IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS,
|
||||
};
|
||||
|
||||
@@ -4650,6 +4650,12 @@ void HandleIMPCharProfileResultsMessage( void)
|
||||
wcscpy(pString, MissingIMPSkillsDescriptions[10]);
|
||||
AddEmailRecordToList( pString );
|
||||
}
|
||||
// Covert ops
|
||||
if ( ProfileHasSkillTrait( iCurrentIMPSlot, COVERT_NT ) > 0 )
|
||||
{
|
||||
wcscpy(pString, MissingIMPSkillsDescriptions[11]);
|
||||
AddEmailRecordToList( pString );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+64
-13
@@ -1769,7 +1769,7 @@ void DisplayCharStats(INT32 iId, INT32 iSlot)
|
||||
{
|
||||
if ( ProfileHasSkillTrait( Menptr[iId].ubProfile, ubCnt ) == 2 )
|
||||
{
|
||||
ubTempSkillArray[bNumSkillTraits] = (ubCnt + 19);
|
||||
ubTempSkillArray[bNumSkillTraits] = (ubCnt + NEWTRAIT_MERCSKILL_EXPERTOFFSET);
|
||||
bNumSkillTraits++;
|
||||
}
|
||||
else if ( ProfileHasSkillTrait( Menptr[iId].ubProfile, ubCnt ) == 1 )
|
||||
@@ -1816,9 +1816,18 @@ void DisplayCharStats(INT32 iId, INT32 iSlot)
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( sString, L"%s", gzMercSkillTextNew[ ubTempSkillArray[ubCnt] ] );
|
||||
// Flugente: as the whole trait display is fubar, we have to to a special treatment here for new traits
|
||||
UINT8 display1 = ubTempSkillArray[ubCnt];
|
||||
if ( display1 > SCOUTING_NT + NEWTRAIT_MERCSKILL_EXPERTOFFSET )
|
||||
display1 -= NUM_MINOR_TRAITS;
|
||||
else if ( display1 >= AMBIDEXTROUS_NT && display1 <= SCOUTING_NT )
|
||||
display1++;
|
||||
else if ( display1 == NEWTRAIT_MERCSKILL_EXPERTOFFSET )
|
||||
display1 -= NUM_MINOR_TRAITS;
|
||||
|
||||
swprintf( sString, L"%s", gzMercSkillTextNew[ display1 ] );
|
||||
|
||||
if ( ubTempSkillArray[ubCnt] > 19 )
|
||||
if ( ubTempSkillArray[ubCnt] > NEWTRAIT_MERCSKILL_EXPERTOFFSET )
|
||||
{
|
||||
FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[19].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, FONT10ARIALBOLD, &sX, &sY);
|
||||
|
||||
@@ -1857,15 +1866,28 @@ void DisplayCharStats(INT32 iId, INT32 iSlot)
|
||||
MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
|
||||
MSYS_AddRegion( &gSkillTraitHelpTextRegion[ubCnt] );
|
||||
fAddedTraitRegion[ubCnt] = TRUE;
|
||||
// Assign the text
|
||||
AssignPersonnelSkillTraitHelpText( ((ubTempSkillArray[ubCnt] > 19) ? (ubTempSkillArray[ubCnt]-19) : ubTempSkillArray[ubCnt]), ((ubTempSkillArray[ubCnt] > 19) ? TRUE : FALSE), Menptr[iId].ubProfile, ubCnt );
|
||||
|
||||
// Assign the text
|
||||
UINT8 traitnr = ubTempSkillArray[ubCnt];
|
||||
UINT8 mlas = NEWTRAIT_MERCSKILL_EXPERTOFFSET;
|
||||
if ( traitnr > mlas )
|
||||
{
|
||||
traitnr = traitnr - mlas;
|
||||
}
|
||||
|
||||
// Flugente: as the whole trait display is fubar, we have to to a special treatment here for new traits
|
||||
UINT8 display2 = ubTempSkillArray[ubCnt];
|
||||
if ( display2 == NUM_MAJOR_TRAITS )
|
||||
display2 += NUM_MINOR_TRAITS;
|
||||
|
||||
AssignPersonnelSkillTraitHelpText( traitnr, ((ubTempSkillArray[ubCnt] > NEWTRAIT_MERCSKILL_EXPERTOFFSET) ? TRUE : FALSE), Menptr[iId].ubProfile, ubCnt );
|
||||
}
|
||||
}
|
||||
|
||||
// if we have more skills than we can display, show "more" and create a tooltip box with the rest of them
|
||||
if ( fDisplayMoreTraits )
|
||||
{
|
||||
swprintf( sString, L"%s", gzMercSkillTextNew[ 29 ]); // dispaly "More..."
|
||||
swprintf( sString, L"%s", gzMercSkillTextNew[ NEWTRAIT_MERCSKILL_OFFSET_ALL + 1 ]); // dispaly "More..."
|
||||
FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[19].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
|
||||
if( sX <= iMinimumX )
|
||||
{
|
||||
@@ -7444,7 +7466,7 @@ void AssignPersonnelSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLeve
|
||||
}
|
||||
if( gSkillTraitValues.ubSLEffectiveLevelInRadius != 0 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[1], ( gSkillTraitValues.ubSLEffectiveLevelInRadius * (fExpertLevel ? 2 : 1)), (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[1], ( gSkillTraitValues.ubSLEffectiveLevelInRadius * (fExpertLevel ? 2 : 1)), (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + NEWTRAIT_MERCSKILL_EXPERTOFFSET] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
if( gSkillTraitValues.ubSLEffectiveLevelAsStandby != 0 )
|
||||
@@ -7459,7 +7481,7 @@ void AssignPersonnelSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLeve
|
||||
}
|
||||
if( gSkillTraitValues.ubSLOverallSuppresionBonusPercent != 0 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[3], ( gSkillTraitValues.ubSLOverallSuppresionBonusPercent * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[3], ( gSkillTraitValues.ubSLOverallSuppresionBonusPercent * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + NEWTRAIT_MERCSKILL_EXPERTOFFSET] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
if( gSkillTraitValues.ubSLMoraleGainBonus != 0 )
|
||||
@@ -7489,12 +7511,12 @@ void AssignPersonnelSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLeve
|
||||
|
||||
if( gSkillTraitValues.ubSLFearResistance != 0 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[9], ( gSkillTraitValues.ubSLFearResistance * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[9], ( gSkillTraitValues.ubSLFearResistance * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + NEWTRAIT_MERCSKILL_EXPERTOFFSET] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
if( gSkillTraitValues.ubSLDeathMoralelossMultiplier != 0 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[10], (1 + ( gSkillTraitValues.ubSLDeathMoralelossMultiplier * (fExpertLevel ? 2 : 1))), (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[10], (1 + ( gSkillTraitValues.ubSLDeathMoralelossMultiplier * (fExpertLevel ? 2 : 1))), (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + NEWTRAIT_MERCSKILL_EXPERTOFFSET] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
break;
|
||||
@@ -7539,17 +7561,17 @@ void AssignPersonnelSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLeve
|
||||
}
|
||||
if( gSkillTraitValues.ubTECtHControlledRobotBonus != 0 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[7], ( gSkillTraitValues.ubTECtHControlledRobotBonus * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[7], ( gSkillTraitValues.ubTECtHControlledRobotBonus * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + NEWTRAIT_MERCSKILL_EXPERTOFFSET] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
if( gSkillTraitValues.ubTETraitsNumToRepairRobot == 2 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + NEWTRAIT_MERCSKILL_EXPERTOFFSET] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
else if( gSkillTraitValues.ubTETraitsNumToRepairRobot == 1 )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + NEWTRAIT_MERCSKILL_EXPERTOFFSET] : gzMercSkillTextNew[ubTraitNumber]));
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
if( gSkillTraitValues.ubTERepairRobotPenaltyReduction != 0 && fExpertLevel)
|
||||
@@ -7983,6 +8005,35 @@ void AssignPersonnelSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLeve
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COVERT_NT:
|
||||
{
|
||||
swprintf( apStr, L"" );
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[0]);
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[1]);
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
if ( !fExpertLevel )
|
||||
{
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[2], gSkillTraitValues.sCOCloseDetectionRange);
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[3], gSkillTraitValues.sCOCloseDetectionRangeSoldierCorpse);
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[4], ( gSkillTraitValues.sCOMeleeCTHBonus * (fExpertLevel ? 2 : 1)), L"%");
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[5], ( gSkillTraitValues.sCoMeleeInstakillBonus * (fExpertLevel ? 2 : 1)), L"%");
|
||||
wcscat( apStr, atStr );
|
||||
|
||||
INT16 apreduction = ( gSkillTraitValues.sCODisguiseAPReduction * (fExpertLevel ? 2 : 1));
|
||||
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[6], apreduction, L"%");
|
||||
wcscat( apStr, atStr );
|
||||
break;
|
||||
}
|
||||
case NO_SKILLTRAIT_NT:
|
||||
{
|
||||
swprintf( apStr, L"" );
|
||||
|
||||
+16
-16
@@ -5,17 +5,17 @@
|
||||
|
||||
// Message box flags
|
||||
#define MSG_BOX_FLAG_USE_CENTERING_RECT 0x0001 // Pass in a rect to center in
|
||||
#define MSG_BOX_FLAG_OK 0x0002 // Displays OK button
|
||||
#define MSG_BOX_FLAG_YESNO 0x0004 // Displays YES NO buttons
|
||||
#define MSG_BOX_FLAG_CANCEL 0x0008 // Displays YES NO buttons
|
||||
#define MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS 0x0010 // Displays four numbered buttons, 1-4
|
||||
#define MSG_BOX_FLAG_YESNOCONTRACT 0x0020 // yes no and contract buttons
|
||||
#define MSG_BOX_FLAG_OKCONTRACT 0x0040 // ok and contract buttons
|
||||
#define MSG_BOX_FLAG_YESNOLIE 0x0080 // ok and contract buttons
|
||||
#define MSG_BOX_FLAG_CONTINUESTOP 0x0100 // continue stop box
|
||||
#define MSG_BOX_FLAG_OKSKIP 0x0200 // Displays ok or skip (meanwhile) buttons
|
||||
#define MSG_BOX_FLAG_GENERICCONTRACT 0x0400 // displays contract buttoin + 2 user-defined text buttons
|
||||
#define MSG_BOX_FLAG_GENERIC 0x0800 // 2 user-defined text buttons
|
||||
#define MSG_BOX_FLAG_OK 0x0002 // Displays OK button
|
||||
#define MSG_BOX_FLAG_YESNO 0x0004 // Displays YES NO buttons
|
||||
#define MSG_BOX_FLAG_CANCEL 0x0008 // Displays YES NO buttons
|
||||
#define MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS 0x0010 // Displays four numbered buttons, 1-4
|
||||
#define MSG_BOX_FLAG_YESNOCONTRACT 0x0020 // yes no and contract buttons
|
||||
#define MSG_BOX_FLAG_OKCONTRACT 0x0040 // ok and contract buttons
|
||||
#define MSG_BOX_FLAG_YESNOLIE 0x0080 // ok and contract buttons
|
||||
#define MSG_BOX_FLAG_CONTINUESTOP 0x0100 // continue stop box
|
||||
#define MSG_BOX_FLAG_OKSKIP 0x0200 // Displays ok or skip (meanwhile) buttons
|
||||
#define MSG_BOX_FLAG_GENERICCONTRACT 0x0400 // displays contract buttoin + 2 user-defined text buttons
|
||||
#define MSG_BOX_FLAG_GENERIC 0x0800 // 2 user-defined text buttons
|
||||
// OJW - Adding text chatbox
|
||||
#define MSG_BOX_FLAG_INPUTBOX 0x1000 // has a text input field
|
||||
// Flugente - added boxes for simultaneous defuse/detonate mechanism
|
||||
@@ -23,11 +23,11 @@
|
||||
#define MSG_BOX_FLAG_SIXTEEN_NUMBERED_BUTTONS 0x4000 // Displays sixteen numbered buttons, 1-16, for setting up a tripwire network and choosing both a detonation and defusing frequency
|
||||
|
||||
// message box return codes
|
||||
#define MSG_BOX_RETURN_OK 1 // ENTER or on OK button
|
||||
#define MSG_BOX_RETURN_YES 2 // ENTER or YES button
|
||||
#define MSG_BOX_RETURN_NO 3 // ESC, Right Click or NO button
|
||||
#define MSG_BOX_RETURN_CONTRACT 4 // contract button
|
||||
#define MSG_BOX_RETURN_LIE 5 // LIE BUTTON
|
||||
#define MSG_BOX_RETURN_OK 1 // ENTER or on OK button
|
||||
#define MSG_BOX_RETURN_YES 2 // ENTER or YES button
|
||||
#define MSG_BOX_RETURN_NO 3 // ESC, Right Click or NO button
|
||||
#define MSG_BOX_RETURN_CONTRACT 4 // contract button
|
||||
#define MSG_BOX_RETURN_LIE 5 // LIE BUTTON
|
||||
|
||||
// message box style flags
|
||||
enum
|
||||
|
||||
@@ -45,8 +45,9 @@ typedef struct
|
||||
CHAR16 szCurDetailedUnexploredName[MAX_SECTOR_NAME_LENGTH];
|
||||
CHAR16 szCurExploredName[MAX_SECTOR_NAME_LENGTH];
|
||||
CHAR16 szCurDetailedExploredName[MAX_SECTOR_NAME_LENGTH];
|
||||
UINT8 sWaterType;
|
||||
UINT16 usNaturalDirt;
|
||||
UINT8 sWaterType; // Food System
|
||||
UINT16 usNaturalDirt; // Dirt System
|
||||
UINT8 usCurfewValue; // Covert Ops
|
||||
UINT32 currentDepth;
|
||||
UINT32 maxReadDepth;
|
||||
} SectorNameParseData;
|
||||
@@ -80,7 +81,12 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char **
|
||||
SectorExternalData[x][1].usNaturalDirt = 0;
|
||||
SectorExternalData[x][2].usNaturalDirt = 0;
|
||||
SectorExternalData[x][3].usNaturalDirt = 0;
|
||||
|
||||
|
||||
SectorExternalData[x][0].usCurfewValue = 0;
|
||||
SectorExternalData[x][1].usCurfewValue = 0;
|
||||
SectorExternalData[x][2].usCurfewValue = 0;
|
||||
SectorExternalData[x][3].usCurfewValue = 0;
|
||||
|
||||
if (Sector_Level == 0 )
|
||||
{
|
||||
gzSectorNames[x][0][0]=0;
|
||||
@@ -128,7 +134,8 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char **
|
||||
strcmp(name, "szExploredName") == 0 ||
|
||||
strcmp(name, "szDetailedExploredName") == 0 ||
|
||||
strcmp(name, "sWaterType") == 0 ||
|
||||
strcmp(name, "usNaturalDirt") == 0 ))
|
||||
strcmp(name, "usNaturalDirt") == 0 ||
|
||||
strcmp(name, "usCurfewValue") == 0 ))
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT;
|
||||
|
||||
@@ -180,16 +187,6 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
|
||||
wcscpy(gzSectorNames[ubSectorId][1], pData->szCurDetailedUnexploredName);
|
||||
wcscpy(gzSectorNames[ubSectorId][2], pData->szCurExploredName);
|
||||
wcscpy(gzSectorNames[ubSectorId][3], pData->szCurDetailedExploredName);
|
||||
|
||||
SectorExternalData[ubSectorId][0].usWaterType = pData->sWaterType;
|
||||
SectorExternalData[ubSectorId][1].usWaterType = pData->sWaterType;
|
||||
SectorExternalData[ubSectorId][2].usWaterType = pData->sWaterType;
|
||||
SectorExternalData[ubSectorId][3].usWaterType = pData->sWaterType;
|
||||
|
||||
SectorExternalData[ubSectorId][0].usNaturalDirt = pData->usNaturalDirt;
|
||||
SectorExternalData[ubSectorId][1].usNaturalDirt = pData->usNaturalDirt;
|
||||
SectorExternalData[ubSectorId][2].usNaturalDirt = pData->usNaturalDirt;
|
||||
SectorExternalData[ubSectorId][3].usNaturalDirt = pData->usNaturalDirt;
|
||||
}
|
||||
// moved to lua
|
||||
//else if (Sector_Level == 1 )
|
||||
@@ -221,17 +218,7 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
|
||||
wcscpy(gzSectorNames[ubSectorId][0], pData->szCurUnexploredName);
|
||||
wcscpy(gzSectorNames[ubSectorId][1], pData->szCurDetailedUnexploredName);
|
||||
wcscpy(gzSectorNames[ubSectorId][2], pData->szCurExploredName);
|
||||
wcscpy(gzSectorNames[ubSectorId][3], pData->szCurDetailedExploredName);
|
||||
|
||||
SectorExternalData[ubSectorId][0].usWaterType = pData->sWaterType;
|
||||
SectorExternalData[ubSectorId][1].usWaterType = pData->sWaterType;
|
||||
SectorExternalData[ubSectorId][2].usWaterType = pData->sWaterType;
|
||||
SectorExternalData[ubSectorId][3].usWaterType = pData->sWaterType;
|
||||
|
||||
SectorExternalData[ubSectorId][0].usNaturalDirt = pData->usNaturalDirt;
|
||||
SectorExternalData[ubSectorId][1].usNaturalDirt = pData->usNaturalDirt;
|
||||
SectorExternalData[ubSectorId][2].usNaturalDirt = pData->usNaturalDirt;
|
||||
SectorExternalData[ubSectorId][3].usNaturalDirt = pData->usNaturalDirt;
|
||||
wcscpy(gzSectorNames[ubSectorId][3], pData->szCurDetailedExploredName);
|
||||
}
|
||||
// moved to lua
|
||||
//else if (Sector_Level == 1 )
|
||||
@@ -256,6 +243,26 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
|
||||
// wcscpy(gzSectorUndergroundNames3[ubSectorId][3], pData->szCurDetailedExploredName);
|
||||
//}
|
||||
}
|
||||
|
||||
SectorExternalData[ubSectorId][0].usWaterType = pData->sWaterType;
|
||||
SectorExternalData[ubSectorId][1].usWaterType = pData->sWaterType;
|
||||
SectorExternalData[ubSectorId][2].usWaterType = pData->sWaterType;
|
||||
SectorExternalData[ubSectorId][3].usWaterType = pData->sWaterType;
|
||||
|
||||
SectorExternalData[ubSectorId][0].usNaturalDirt = pData->usNaturalDirt;
|
||||
SectorExternalData[ubSectorId][1].usNaturalDirt = pData->usNaturalDirt;
|
||||
SectorExternalData[ubSectorId][2].usNaturalDirt = pData->usNaturalDirt;
|
||||
SectorExternalData[ubSectorId][3].usNaturalDirt = pData->usNaturalDirt;
|
||||
|
||||
SectorExternalData[ubSectorId][0].usCurfewValue = pData->usCurfewValue;
|
||||
SectorExternalData[ubSectorId][1].usCurfewValue = pData->usCurfewValue;
|
||||
SectorExternalData[ubSectorId][2].usCurfewValue = pData->usCurfewValue;
|
||||
SectorExternalData[ubSectorId][3].usCurfewValue = pData->usCurfewValue;
|
||||
|
||||
// clean up values afterwards
|
||||
pData->sWaterType = 0;
|
||||
pData->usNaturalDirt = 100;
|
||||
pData->usCurfewValue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,6 +322,11 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usNaturalDirt = (UINT16) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usCurfewValue") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usCurfewValue = (UINT16) atoi(pData->szCharData);
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
|
||||
@@ -387,67 +387,65 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
|
||||
}
|
||||
|
||||
// Flugente: always do the following checks. Thereby, if the effect runs out, our stats will be back to normal
|
||||
// only do the checks for the player team, as soldiers do not have a gMercProfiles
|
||||
if ( pSoldier->bTeam == gbPlayerNum)
|
||||
//////////////// STRENGTH ////////////////
|
||||
pSoldier->bExtraStrength = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_STRENGTH ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_STRENGTH ];
|
||||
|
||||
//////////////// DEXTERITY ////////////////
|
||||
pSoldier->bExtraDexterity = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_DEXTERITY ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_DEXTERITY ];
|
||||
|
||||
//////////////// AGILITY ////////////////
|
||||
pSoldier->bExtraAgility = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_AGILITY ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_AGILITY ];
|
||||
|
||||
//////////////// WISDOM ////////////////
|
||||
pSoldier->bExtraWisdom = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_WISDOM ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_WISDOM ];
|
||||
|
||||
// if our sideeffect count is 1 (which should occur a while AFTER we took the drug), we suddenly become blind for a few turns...
|
||||
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_BLIND ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_BLIND ] == 1 )
|
||||
{
|
||||
//////////////// STRENGTH ////////////////
|
||||
pSoldier->bExtraStrength = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_STRENGTH ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_STRENGTH ];
|
||||
pSoldier->bBlindedCounter = 3;
|
||||
}
|
||||
|
||||
//////////////// DEXTERITY ////////////////
|
||||
pSoldier->bExtraDexterity = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_DEXTERITY ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_DEXTERITY ];
|
||||
// if our sideeffect count is 1 (which should occur a while AFTER we took the drug), we get a heart-attack and get knocked out...
|
||||
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_KNOCKOUT ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_KNOCKOUT ] == 1 )
|
||||
{
|
||||
// Keel over...
|
||||
DeductPoints( pSoldier, 0, 20000 );
|
||||
}
|
||||
|
||||
//////////////// AGILITY ////////////////
|
||||
pSoldier->bExtraAgility = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_AGILITY ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_AGILITY ];
|
||||
// if we have a life damaging effect, deduct life points
|
||||
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_LIFEDAMAGE ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_LIFEDAMAGE ] > 0 )
|
||||
{
|
||||
pSoldier->EVENT_SoldierGotHit( 0, 400, 0, pSoldier->ubDirection, 320, NOBODY , FIRE_WEAPON_NO_SPECIAL, pSoldier->bAimShotLocation, 0, -1 );
|
||||
|
||||
//////////////// WISDOM ////////////////
|
||||
pSoldier->bExtraWisdom = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_WISDOM ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_WISDOM ];
|
||||
|
||||
// if our sideeffect count is 1 (which should occur a while AFTER we took the drug), we suddenly become blind for a few turns...
|
||||
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_BLIND ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_BLIND ] == 1 )
|
||||
/*if ( pSoldier->stats.bLife > OKLIFE )
|
||||
{
|
||||
pSoldier->bBlindedCounter = 3;
|
||||
}
|
||||
|
||||
// if our sideeffect count is 1 (which should occur a while AFTER we took the drug), we get a heart-attack and get knocked out...
|
||||
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_KNOCKOUT ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_KNOCKOUT ] == 1 )
|
||||
{
|
||||
// Keel over...
|
||||
DeductPoints( pSoldier, 0, 20000 );
|
||||
}
|
||||
|
||||
// if we have a life damaging effect, deduct life points
|
||||
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_LIFEDAMAGE ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_LIFEDAMAGE ] > 0 )
|
||||
{
|
||||
if ( pSoldier->stats.bLife > OKLIFE )
|
||||
{
|
||||
INT8 lifepointdamage = pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_LIFEDAMAGE ];
|
||||
INT8 lifepointdamage = pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_LIFEDAMAGE ];
|
||||
|
||||
INT8 applieddamage = pSoldier->stats.bLife;
|
||||
INT8 applieddamage = pSoldier->stats.bLife;
|
||||
|
||||
pSoldier->stats.bLife = max(OKLIFE - 1, pSoldier->stats.bLife - lifepointdamage);
|
||||
pSoldier->stats.bLife = max(OKLIFE - 8, pSoldier->stats.bLife - lifepointdamage);
|
||||
|
||||
applieddamage -= pSoldier->stats.bLife;
|
||||
applieddamage -= pSoldier->stats.bLife;
|
||||
|
||||
pSoldier->iHealableInjury += (applieddamage * 100);
|
||||
}
|
||||
}
|
||||
pSoldier->iHealableInjury += (applieddamage * 100);
|
||||
}*/
|
||||
}
|
||||
|
||||
// if we took an antidote, reduce poisoning
|
||||
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_CUREPOISON ] > 0 )
|
||||
// if we took an antidote, reduce poisoning
|
||||
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_CUREPOISON ] > 0 )
|
||||
{
|
||||
if ( pSoldier->bPoisonSum > 0 )
|
||||
{
|
||||
if ( pSoldier->bPoisonSum > 0 )
|
||||
if ( pSoldier->bPoisonBleeding > 0 )
|
||||
{
|
||||
if ( pSoldier->bPoisonBleeding > 0 )
|
||||
{
|
||||
pSoldier->bPoisonBleeding--;
|
||||
}
|
||||
else if ( pSoldier->bPoisonLife > 0 )
|
||||
{
|
||||
pSoldier->bPoisonLife--;
|
||||
}
|
||||
|
||||
pSoldier->bPoisonSum--;
|
||||
pSoldier->bPoisonBleeding--;
|
||||
}
|
||||
else if ( pSoldier->bPoisonLife > 0 )
|
||||
{
|
||||
pSoldier->bPoisonLife--;
|
||||
}
|
||||
|
||||
pSoldier->bPoisonSum--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2318,6 +2318,13 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: add an icon if we are currently in disguise
|
||||
if ( MercPtrs[ pFace->ubSoldierID ]->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER) )
|
||||
{
|
||||
DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 22 );
|
||||
bNumRightIcons++;
|
||||
}
|
||||
|
||||
switch( pSoldier->bAssignment )
|
||||
{
|
||||
case DOCTOR:
|
||||
|
||||
@@ -101,6 +101,7 @@ static INT8 bTempFrequency;
|
||||
|
||||
void BombMessageBoxCallBack( UINT8 ubExitValue );
|
||||
void TacticalFunctionSelectionMessageBoxCallBack( UINT8 ubExitValue ); // Flugente: callback after deciding what tactical function to use
|
||||
void CorpseMessageBoxCallBack( UINT8 ubExitValue ); // Flugente: callback after deciding what to do with a corpse
|
||||
void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue );
|
||||
void SwitchMessageBoxCallBack( UINT8 ubExitValue );
|
||||
void BoobyTrapDialogueCallBack( void );
|
||||
@@ -133,6 +134,8 @@ void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo );
|
||||
void StartTacticalFunctionSelectionMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bLevel ); // added by Flugente
|
||||
void CleanWeapons();
|
||||
|
||||
void StartCorpseMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bLevel ); // added by Flugente
|
||||
|
||||
BOOLEAN HandleCheckForBadChangeToGetThrough( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pTargetSoldier, INT32 sTargetGridNo , INT8 bLevel )
|
||||
{
|
||||
BOOLEAN fBadChangeToGetThrough = FALSE;
|
||||
@@ -1647,6 +1650,11 @@ void HandleTacticalFunctionSelection( SOLDIERTYPE *pSoldier, INT32 sGridNo )
|
||||
}
|
||||
|
||||
|
||||
void HandleSoldierUseCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
{
|
||||
StartCorpseMessageBox( pSoldier, sGridNo, bLevel );
|
||||
}
|
||||
|
||||
void SoldierHandleDropItem( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
// LOOK IN PANDING DATA FOR ITEM TO DROP, AND LOCATION
|
||||
@@ -2441,6 +2449,12 @@ OBJECTTYPE* InternalAddItemToPool( INT32 *psGridNo, OBJECTTYPE *pObject, INT8 bV
|
||||
bRenderZHeightAboveLevel = 0;
|
||||
}
|
||||
|
||||
// Flugente: if this item is a corpse, don't add it to the world. Instead spawn a corpse in its position
|
||||
if ( HasItemFlag(pObject->usItem, CORPSE) && AddCorpseFromObject(pObject, *psGridNo, ubLevel ) )
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
//CHRISL: We need to make sure that item stacks follow the OldInv stacking limits
|
||||
// Copy the object we're working with the gTempObject so that we can use pObject later in this function
|
||||
OBJECTTYPE poolObject = OBJECTTYPE(*pObject);
|
||||
@@ -4418,6 +4432,19 @@ INT32 AdjustGridNoForItemPlacement( SOLDIERTYPE *pSoldier, INT32 sGridNo )
|
||||
return( sActionGridNo );
|
||||
}
|
||||
|
||||
// Flugente
|
||||
void StartCorpseMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
{
|
||||
gpTempSoldier = pSoldier;
|
||||
|
||||
// determine what is possible with this corpse
|
||||
BOOLEAN fDecapitate = TRUE;
|
||||
BOOLEAN fTakeClothes = TRUE;
|
||||
BOOLEAN fTakeCorpse = TRUE;
|
||||
|
||||
if ( fDecapitate && fTakeClothes )
|
||||
DoMessageBox( MSG_BOX_BASIC_SMALL_BUTTONS, TacticalStr[ CORPSE_SELECTION_STR ], GAME_SCREEN, MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS, CorpseMessageBoxCallBack, NULL );
|
||||
}
|
||||
|
||||
void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo )
|
||||
{
|
||||
@@ -4667,6 +4694,36 @@ void TacticalFunctionSelectionMessageBoxCallBack( UINT8 ubExitValue )
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: callback after deciding what to do with a corpse
|
||||
void CorpseMessageBoxCallBack( UINT8 ubExitValue )
|
||||
{
|
||||
if (gpTempSoldier)
|
||||
{
|
||||
INT32 nextGridNoinSight = gpTempSoldier->sGridNo;
|
||||
nextGridNoinSight = NewGridNo( nextGridNoinSight, DirectionInc( gpTempSoldier->ubDirection ) );
|
||||
|
||||
INT8 level = gpTempSoldier->bTargetLevel;
|
||||
|
||||
switch (ubExitValue)
|
||||
{
|
||||
case 1:
|
||||
DecapitateCorpse( gpTempSoldier, nextGridNoinSight, level );
|
||||
break;
|
||||
case 2:
|
||||
GutCorpse( gpTempSoldier, nextGridNoinSight, level );
|
||||
break;
|
||||
case 3:
|
||||
StripCorpse( gpTempSoldier, nextGridNoinSight, level );
|
||||
break;
|
||||
case 4:
|
||||
TakeCorpse( gpTempSoldier, nextGridNoinSight, level );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN HandItemWorks( SOLDIERTYPE *pSoldier, INT8 bSlot )
|
||||
{
|
||||
BOOLEAN fItemJustBroke = FALSE, fItemWorks = TRUE;
|
||||
|
||||
@@ -135,6 +135,8 @@ void HandleSoldierUseRemote( SOLDIERTYPE *pSoldier, INT32 sGridNo );
|
||||
|
||||
void HandleTacticalFunctionSelection( SOLDIERTYPE *pSoldier, INT32 sGridNo ); // Flugente: in tactical, open a selection box for different actions
|
||||
|
||||
void HandleSoldierUseCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel ); // Flugente: handle corpses
|
||||
|
||||
BOOLEAN ItemPoolOKForDisplay( ITEM_POOL *pItemPool, INT8 bZLevel );
|
||||
INT16 GetNumOkForDisplayItemsInPool( ITEM_POOL *pItemPool, INT8 bZLevel );
|
||||
|
||||
|
||||
@@ -2523,7 +2523,16 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
|
||||
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////// COVERT ITEM
|
||||
if ( HasItemFlag(gpItemDescObject->usItem, COVERT) )
|
||||
{
|
||||
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 31 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 31 ]);
|
||||
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
@@ -5532,7 +5541,14 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
|
||||
{
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 11, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////// COVERT ITEM
|
||||
if ( HasItemFlag(gpItemDescObject->usItem, COVERT) )
|
||||
{
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 30, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
|
||||
@@ -8938,8 +8954,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
// Print Values
|
||||
for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
|
||||
{
|
||||
if (UsingNewCTHSystem() == false && cnt2 > 0)
|
||||
break;
|
||||
// Flugente: no idea why we would want to skip this in OCTH, commenting this out
|
||||
//if (UsingNewCTHSystem() == false && cnt2 > 0)
|
||||
//break;
|
||||
SetFontForeground( 5 );
|
||||
sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
|
||||
sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
|
||||
|
||||
@@ -13148,11 +13148,11 @@ void BombInventoryMessageBoxCallBack( UINT8 ubExitValue )
|
||||
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( gpItemDescSoldier, DEMOLITIONS_NT ))
|
||||
{
|
||||
// increase trap level for Demolitions trait
|
||||
gpItemDescSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( max( 10, (8 + gSkillTraitValues.ubDEPlacedBombLevelBonus)), (( EffectiveExplosive( gpItemDescSoldier ) / 20) + (EffectiveExpLevel( gpItemDescSoldier ) / 3) + gSkillTraitValues.ubDEPlacedBombLevelBonus) );
|
||||
(*gpItemDescObject)[0]->data.bTrap = __min( max( 10, (8 + gSkillTraitValues.ubDEPlacedBombLevelBonus)), (( EffectiveExplosive( gpItemDescSoldier ) / 20) + (EffectiveExpLevel( gpItemDescSoldier ) / 3) + gSkillTraitValues.ubDEPlacedBombLevelBonus) );
|
||||
}
|
||||
else
|
||||
{
|
||||
gpItemDescSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( 10, ( EffectiveExplosive( gpItemDescSoldier ) / 20) + (EffectiveExpLevel( gpItemDescSoldier ) / 3) );
|
||||
(*gpItemDescObject)[0]->data.bTrap = __min( 10, ( EffectiveExplosive( gpItemDescSoldier ) / 20) + (EffectiveExpLevel( gpItemDescSoldier ) / 3) );
|
||||
}
|
||||
|
||||
// Flugente: We armed a bomb in our inventory. We will NOT add it to the item pool and the world bombs.
|
||||
@@ -13164,8 +13164,8 @@ void BombInventoryMessageBoxCallBack( UINT8 ubExitValue )
|
||||
// so we add 2 to all owner IDs passed through here and subtract 2 later
|
||||
//if (gpItemDescSoldier->inv[HANDPOS].MoveThisObjectTo(gTempObject, 1) == 0)
|
||||
{
|
||||
gTempObject[0]->data.misc.ubBombOwner = gpItemDescSoldier->ubID + 2;
|
||||
gTempObject[0]->data.ubDirection = gpItemDescSoldier->ubDirection; // Flugente: direction of bomb is direction of soldier
|
||||
(*gpItemDescObject)[0]->data.misc.ubBombOwner = gpItemDescSoldier->ubID + 2;
|
||||
(*gpItemDescObject)[0]->data.ubDirection = gpItemDescSoldier->ubDirection; // Flugente: direction of bomb is direction of soldier
|
||||
|
||||
//AddItemToPool( gsTempGridNo, &gTempObject, VISIBLE, gpItemDescSoldier->pathing.bLevel, WORLD_ITEM_ARMED_BOMB, 0 );
|
||||
}
|
||||
|
||||
@@ -3357,6 +3357,21 @@ void SMInvClickCamoCallback( MOUSE_REGION * pRegion, INT32 iReason )
|
||||
// Say OK acknowledge....
|
||||
gpSMCurrentMerc->DoMercBattleSound( BATTLE_SOUND_COOL1 );
|
||||
}
|
||||
else if ( ApplySpyKit( gpSMCurrentMerc, gpItemPointer ) )
|
||||
{
|
||||
// Dirty
|
||||
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||
|
||||
// Check if it's the same now!
|
||||
if ( gpItemPointer->exists() == false )
|
||||
{
|
||||
gbCompatibleApplyItem = FALSE;
|
||||
EndItemPointer( );
|
||||
}
|
||||
|
||||
// Say OK acknowledge....
|
||||
gpSMCurrentMerc->DoMercBattleSound( BATTLE_SOUND_COOL1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send message
|
||||
|
||||
+53
-6
@@ -734,13 +734,13 @@ extern OBJECTTYPE gTempObject;
|
||||
#define CAMO_REMOVAL 0x00000400 //1024 // item can be used to remove camo
|
||||
#define CLEANING_KIT 0x00000800 //2048 // weapon cleaning kit
|
||||
|
||||
/*#define ENEMY_NET_1_LVL_4 0x00001000 //4096
|
||||
#define ENEMY_NET_2_LVL_4 0x00002000 //8192
|
||||
#define ENEMY_NET_3_LVL_4 0x00004000 //16384
|
||||
#define ENEMY_NET_4_LVL_4 0x00008000 //32768
|
||||
#define CLOTHES_CIVILIAN 0x00001000 //4096 // with this item you can disguise as a civilian
|
||||
#define GAROTTE 0x00002000 //8192 // this item is a garotte
|
||||
#define COVERT 0x00004000 //16384 // if LBE, any gun inside will be covert. On a gun, it will covert in any LBE, even if the LBE does not have that tag itself
|
||||
#define CORPSE 0x00008000 //32768 // a dead body
|
||||
|
||||
#define PLAYER_NET_1_LVL_1 0x00010000 //65536
|
||||
#define PLAYER_NET_2_LVL_1 0x00020000 //131072
|
||||
#define SKIN_BLOODCAT 0x00010000 //65536 // retrieve this by skinning (=decapitating) a bloodcat
|
||||
/*#define PLAYER_NET_2_LVL_1 0x00020000 //131072
|
||||
#define PLAYER_NET_3_LVL_1 0x00040000 //262144
|
||||
#define PLAYER_NET_4_LVL_1 0x00080000 //524288
|
||||
|
||||
@@ -760,6 +760,49 @@ extern OBJECTTYPE gTempObject;
|
||||
#define PLAYER_NET_4_LVL_4 0x80000000 //2147483648*/
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// -------- added by Flugente: flags for objects --------
|
||||
// the numbering of these flags is important. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
|
||||
#define CORPSE_M_SMALL 0x00000001 //1
|
||||
#define CORPSE_M_BIG 0x00000002 //2
|
||||
#define CORPSE_F 0x00000004 //4
|
||||
#define CORPSE_NO_HEAD 0x00000008 //8
|
||||
|
||||
#define CORPSE_HAIR_BROWN 0x00000010 //16
|
||||
#define CORPSE_HAIR_BLACK 0x00000020 //32
|
||||
#define CORPSE_HAIR_WHITE 0x00000040 //64
|
||||
#define CORPSE_HAIR_BLOND 0x00000080 //128
|
||||
|
||||
#define CORPSE_HAIR_RED 0x00000100 //256
|
||||
#define CORPSE_SKIN_PINK 0x00000200 //512
|
||||
#define CORPSE_SKIN_TAN 0x00000400 //1024
|
||||
#define CORPSE_SKIN_DARK 0x00000800 //2048
|
||||
|
||||
#define CORPSE_SKIN_BLACK 0x00001000 //4096
|
||||
#define CORPSE_VEST_BROWN 0x00002000 //8192
|
||||
#define CORPSE_VEST_grey 0x00004000 //16384
|
||||
#define CORPSE_VEST_GREEN 0x00008000 //32768
|
||||
|
||||
#define CORPSE_VEST_JEAN 0x00010000 //65536
|
||||
#define CORPSE_VEST_RED 0x00020000 //131072
|
||||
#define CORPSE_VEST_BLUE 0x00040000 //262144
|
||||
#define CORPSE_VEST_YELLOW 0x00080000 //524288
|
||||
|
||||
#define CORPSE_VEST_WHITE 0x00100000 //1048576
|
||||
#define CORPSE_VEST_BLACK 0x00200000 //2097152
|
||||
#define CORPSE_VEST_GYELLOW 0x00400000 //4194304
|
||||
#define CORPSE_VEST_PURPLE 0x00800000 //8388608
|
||||
|
||||
#define CORPSE_PANTS_GREEN 0x01000000 //16777216
|
||||
#define CORPSE_PANTS_JEAN 0x02000000 //33554432
|
||||
#define CORPSE_PANTS_TAN 0x04000000 //67108864
|
||||
#define CORPSE_PANTS_BLACK 0x08000000 //134217728
|
||||
|
||||
#define CORPSE_PANTS_BLUE 0x10000000 //268435456
|
||||
#define CORPSE_PANTS_BEIGE 0x20000000 //536870912
|
||||
#define CORPSE_STRIPPED 0x40000000 //1073741824
|
||||
//#define unused 0x80000000 //2147483648*/
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// replaces candamage
|
||||
//#define ITEM_DAMAGEABLE 0x0001
|
||||
//// replaces canrepair
|
||||
@@ -1703,6 +1746,10 @@ enum
|
||||
IMP_TEACHING_EXP,
|
||||
IMP_LOCKPICKING_EXP,
|
||||
|
||||
// Flugente: added covert ops
|
||||
IMP_COVERT,
|
||||
IMP_COVERT_EXP,
|
||||
|
||||
MAX_IMP_ITEM_TYPES
|
||||
};
|
||||
|
||||
|
||||
@@ -9144,6 +9144,23 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
// Flugente: apply disguise
|
||||
BOOLEAN ApplySpyKit( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj)
|
||||
{
|
||||
if (pObj->exists() == false || !HasItemFlag(pObj->usItem, (CLOTHES_CIVILIAN)) )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
// we get the civilian disguise. AP costs will be checked and deducted here
|
||||
if ( !pSoldier->DisguiseAsCivilian() )
|
||||
return FALSE;
|
||||
|
||||
UseKitPoints( pObj, 100, pSoldier );
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
BOOLEAN ApplyCanteen( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAPs )
|
||||
{
|
||||
INT16 sPointsToUse;
|
||||
|
||||
@@ -196,6 +196,7 @@ 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 ApplySpyKit( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj); // Flugente: apply disguise
|
||||
|
||||
UINT32 ConvertProfileMoneyValueToObjectTypeMoneyValue( UINT8 ubStatus );
|
||||
UINT8 ConvertObjectTypeMoneyValueToProfileMoneyValue( UINT32 uiMoneyAmount );
|
||||
@@ -484,6 +485,7 @@ typedef struct
|
||||
{
|
||||
UINT8 usWaterType; // type of water source in this sector
|
||||
UINT16 usNaturalDirt; // extra dirt percentage when firing in this sector
|
||||
UINT8 usCurfewValue; // determines wether mercs disguising as civilian are automatically discovered (certain sectors are 'restricted' to civilians)
|
||||
} SECTOR_EXT_DATA;
|
||||
|
||||
// get dirt increase for object with attachments, fConsiderAmmo: with ammo
|
||||
|
||||
@@ -6104,11 +6104,11 @@ void EnterCombatMode( UINT8 ubStartingTeam )
|
||||
|
||||
if (!is_client || is_server) //hayden
|
||||
{
|
||||
StartPlayerTeamTurn( FALSE, TRUE );
|
||||
StartPlayerTeamTurn( FALSE, TRUE );
|
||||
if(is_client)send_EndTurn( ubStartingTeam ); //hayden
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
//ScreenMsg( FONT_YELLOW, MSG_CHAT, L"client skipped EnterCombatMode");
|
||||
if(is_client)startCombat(ubStartingTeam);//clients other than server meet and send request for combat for server
|
||||
}
|
||||
|
||||
+518
-31
@@ -275,8 +275,8 @@ BOOLEAN gbCorpseValidForDecapitation[ NUM_CORPSES ] =
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1, // Bloodcat - changed to 1 to allow gutting
|
||||
1, // Cow - changed to 1 to allow gutting
|
||||
1, // Bloodcat - changed to 1 to allow skinning (works like decapitating)
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@@ -495,6 +495,9 @@ INT32 AddRottingCorpse( ROTTING_CORPSE_DEFINITION *pCorpseDef )
|
||||
// Copy elements in
|
||||
memcpy( pCorpse, pCorpseDef, sizeof( ROTTING_CORPSE_DEFINITION ) );
|
||||
|
||||
if ( pCorpseDef->fHeadTaken )
|
||||
pCorpse->def.usFlags |= ROTTING_CORPSE_HEAD_TAKEN;
|
||||
|
||||
uiDirectionUseFlag = ANITILE_USE_DIRECTION_FOR_START_FRAME;
|
||||
|
||||
// If we are a soecial type...
|
||||
@@ -818,7 +821,7 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
|
||||
// Setup some values!
|
||||
memset( &Corpse, 0, sizeof( Corpse ) );
|
||||
Corpse.ubBodyType = pSoldier->ubBodyType;
|
||||
Corpse.sGridNo = pSoldier->sGridNo;
|
||||
Corpse.sGridNo = pSoldier->sGridNo;
|
||||
Corpse.dXPos = pSoldier->dXPos;
|
||||
Corpse.dYPos = pSoldier->dYPos;
|
||||
Corpse.bLevel = pSoldier->pathing.bLevel;
|
||||
@@ -895,6 +898,18 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
|
||||
Corpse.name[9] = '\0';
|
||||
#endif
|
||||
|
||||
// Flugente: mark if this was an army soldier ( we use this to steal his clothes later on )
|
||||
if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR )
|
||||
Corpse.usFlags |= ROTTING_CORPSE_FROM_ADMIN;
|
||||
else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY )
|
||||
Corpse.usFlags |= ROTTING_CORPSE_FROM_TROOP;
|
||||
else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE )
|
||||
Corpse.usFlags |= ROTTING_CORPSE_FROM_ELITE;
|
||||
|
||||
// if this soldier's uniform was damaged (gunfire, blade attacks, explosions) then don't allow to take the uniform. We can't stay hidden if we're covered in blood :-)
|
||||
if ( pSoldier->bSoldierFlagMask &SOLDIER_DAMAGED_UNIFORM )
|
||||
Corpse.usFlags |= ROTTING_CORPSE_CLOTHES_TAKEN;
|
||||
|
||||
// Determine corpse type!
|
||||
ubType = (UINT8)gubAnimSurfaceCorpseID[ pSoldier->ubBodyType][ pSoldier->usAnimState ];
|
||||
|
||||
@@ -1763,7 +1778,7 @@ INT32 FindNearestAvailableGridNoForCorpse( ROTTING_CORPSE_DEFINITION *pDef, INT8
|
||||
|
||||
BOOLEAN IsValidDecapitationCorpse( ROTTING_CORPSE *pCorpse )
|
||||
{
|
||||
if ( (pCorpse->def.usFlags & ROTTING_CORPSE_GUTTED) )
|
||||
if ( (pCorpse->def.usFlags & ROTTING_CORPSE_HEAD_TAKEN) )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
@@ -1797,14 +1812,12 @@ ROTTING_CORPSE *GetCorpseAtGridNo( INT32 sGridNo, INT8 bLevel )
|
||||
}
|
||||
|
||||
|
||||
void DecapitateCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
void DecapitateCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
{
|
||||
ROTTING_CORPSE *pCorpse;
|
||||
ROTTING_CORPSE_DEFINITION CorpseDef;
|
||||
UINT16 usHeadIndex = HEAD_1;
|
||||
static UINT16 usBloodCatMeatIndex = 1566;
|
||||
static UINT16 usCowMeatIndex = 1565;
|
||||
|
||||
static UINT16 usBloodCatSkinIndex = 232;
|
||||
|
||||
pCorpse = GetCorpseAtGridNo( sGridNo, bLevel );
|
||||
|
||||
@@ -1812,41 +1825,30 @@ void DecapitateCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ( IsValidDecapitationCorpse( pCorpse ) )
|
||||
{
|
||||
// Decapitate.....
|
||||
// Copy corpse definition...
|
||||
memcpy( &CorpseDef, &(pCorpse->def), sizeof( ROTTING_CORPSE_DEFINITION ) );
|
||||
|
||||
// Flugente: if the corpse is of a cow or a bloodcat, we don't take its head, we simply gut it and give meat instead of a head
|
||||
if ( CorpseDef.ubType == BLOODCAT_DEAD || CorpseDef.ubType == COW_DEAD )
|
||||
{
|
||||
pCorpse->def.usFlags |= (ROTTING_CORPSE_HEAD_TAKEN|ROTTING_CORPSE_GUTTED);
|
||||
|
||||
if ( CorpseDef.ubType == BLOODCAT_DEAD )
|
||||
{
|
||||
if ( HasItemFlag(usBloodCatMeatIndex, MEAT_BLOODCAT) || GetFirstItemWithFlag(&usBloodCatMeatIndex, MEAT_BLOODCAT) )
|
||||
usHeadIndex = usBloodCatMeatIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( HasItemFlag(usCowMeatIndex, COW_MEAT) || GetFirstItemWithFlag(&usCowMeatIndex, COW_MEAT) )
|
||||
usHeadIndex = usCowMeatIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add new one...
|
||||
CorpseDef.ubType = gDecapitatedCorpse[ CorpseDef.ubType ];
|
||||
|
||||
pCorpse->def.usFlags |= (ROTTING_CORPSE_HEAD_TAKEN|ROTTING_CORPSE_GUTTED);
|
||||
|
||||
|
||||
pCorpse->def.usFlags |= ROTTING_CORPSE_HEAD_TAKEN;
|
||||
CorpseDef.fHeadTaken = TRUE;
|
||||
|
||||
if ( CorpseDef.ubType != 0 )
|
||||
{
|
||||
// Remove old one...
|
||||
RemoveCorpse( pCorpse->iID );
|
||||
|
||||
AddRottingCorpse( &CorpseDef );
|
||||
INT32 iCorpseID = AddRottingCorpse( &CorpseDef );
|
||||
|
||||
if ( iCorpseID != -1 )
|
||||
{
|
||||
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_HEAD_TAKEN;
|
||||
}
|
||||
}
|
||||
|
||||
// Add head item.....
|
||||
@@ -1880,6 +1882,12 @@ void DecapitateCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
|
||||
}
|
||||
|
||||
if ( pCorpse->def.ubType == BLOODCAT_DEAD )
|
||||
{
|
||||
if ( HasItemFlag(usBloodCatSkinIndex, SKIN_BLOODCAT) || GetFirstItemWithFlag(&usBloodCatSkinIndex, SKIN_BLOODCAT) )
|
||||
usHeadIndex = usBloodCatSkinIndex;
|
||||
}
|
||||
|
||||
if ( usHeadIndex > 0 )
|
||||
{
|
||||
CreateItem( usHeadIndex, 100, &gTempObject );
|
||||
@@ -1889,7 +1897,404 @@ void DecapitateCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
NotifySoldiersToLookforItems( );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: can this corpse be gutted?
|
||||
BOOLEAN IsValidGutCorpse( ROTTING_CORPSE *pCorpse )
|
||||
{
|
||||
if ( pCorpse->def.ubType == ROTTING_STAGE2 || (pCorpse->def.usFlags & ROTTING_CORPSE_GUTTED) )
|
||||
return( FALSE );
|
||||
|
||||
return( pCorpse->def.ubType == BLOODCAT_DEAD || pCorpse->def.ubType == COW_DEAD );
|
||||
}
|
||||
|
||||
// Flugente: gut a corpse
|
||||
void GutCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
{
|
||||
ROTTING_CORPSE *pCorpse = GetCorpseAtGridNo( sGridNo, bLevel );
|
||||
|
||||
if ( pCorpse == NULL )
|
||||
return;
|
||||
|
||||
// can this thing be gutted?
|
||||
if ( IsValidGutCorpse( pCorpse ) )
|
||||
{
|
||||
// numbers for the meat acquired by gutting. These values respond to the standard GameDir values, if they have other values in the ini, no problem, we'll search for them
|
||||
static UINT16 usBloodCatMeatIndex = 1566;
|
||||
static UINT16 usCowMeatIndex = 1565;
|
||||
UINT16 meatindex = 0;
|
||||
|
||||
pCorpse->def.usFlags |= ROTTING_CORPSE_GUTTED;
|
||||
|
||||
if ( pCorpse->def.ubType == BLOODCAT_DEAD )
|
||||
{
|
||||
if ( HasItemFlag(usBloodCatMeatIndex, MEAT_BLOODCAT) || GetFirstItemWithFlag(&usBloodCatMeatIndex, MEAT_BLOODCAT) )
|
||||
meatindex = usBloodCatMeatIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( HasItemFlag(usCowMeatIndex, COW_MEAT) || GetFirstItemWithFlag(&usCowMeatIndex, COW_MEAT) )
|
||||
meatindex = usCowMeatIndex;
|
||||
}
|
||||
|
||||
if ( meatindex > 0 )
|
||||
{
|
||||
CreateItem( meatindex, 100, &gTempObject );
|
||||
AddItemToPool( sGridNo, &gTempObject, INVISIBLE, 0, 0, 0 );
|
||||
|
||||
// All teams lok for this...
|
||||
NotifySoldiersToLookforItems( );
|
||||
}
|
||||
}
|
||||
else
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Not possible, you sick, sick individual!" );
|
||||
}
|
||||
|
||||
// Flugente: can clothes be taken off of this corpse?
|
||||
BOOLEAN IsValidStripCorpse( ROTTING_CORPSE *pCorpse )
|
||||
{
|
||||
if ( pCorpse->def.ubType == ROTTING_STAGE2 || (pCorpse->def.usFlags & ROTTING_CORPSE_CLOTHES_TAKEN) )
|
||||
return( FALSE );
|
||||
|
||||
// is there a uniform we can take?
|
||||
if ( !(pCorpse->def.usFlags & (ROTTING_CORPSE_FROM_ADMIN|ROTTING_CORPSE_FROM_TROOP|ROTTING_CORPSE_FROM_ELITE)) )
|
||||
return( FALSE );
|
||||
|
||||
return( CorpseOkToDress(pCorpse, NULL) );
|
||||
}
|
||||
|
||||
|
||||
// Flugente: take the clothes off a corpse and wear them
|
||||
void StripCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
{
|
||||
ROTTING_CORPSE *pCorpse = GetCorpseAtGridNo( sGridNo, bLevel );
|
||||
|
||||
if ( pCorpse == NULL )
|
||||
return;
|
||||
|
||||
// can this thing be stripped?
|
||||
if ( IsValidStripCorpse( pCorpse ) )
|
||||
{
|
||||
// if this fits our body, try to wear it
|
||||
if ( CorpseOkToDress(pCorpse, pSoldier) && pSoldier->DisguiseAsSoldierFromCorpse( pCorpse->def.usFlags ) )
|
||||
{
|
||||
// we took the clothes, mark this
|
||||
pCorpse->def.usFlags |= ROTTING_CORPSE_CLOTHES_TAKEN;
|
||||
}
|
||||
}
|
||||
else
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"No clothes to take!" );
|
||||
}
|
||||
|
||||
// Flugente: can clothes be taken off of this corpse?
|
||||
BOOLEAN IsValidTakeCorpse( ROTTING_CORPSE *pCorpse )
|
||||
{
|
||||
if ( pCorpse->def.ubType >= BLOODCAT_DEAD || pCorpse->def.ubType == NO_CORPSE )
|
||||
return( FALSE );
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
// Flugente: take a corpse into your hand, thereby removing it from the field
|
||||
void TakeCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel )
|
||||
{
|
||||
ROTTING_CORPSE *pCorpse = GetCorpseAtGridNo( sGridNo, bLevel );
|
||||
|
||||
if ( pCorpse == NULL )
|
||||
return;
|
||||
|
||||
// can this corpse be picked up?
|
||||
if ( IsValidTakeCorpse( pCorpse ) )
|
||||
{
|
||||
// is there a 'corpse' item?
|
||||
UINT16 corpseitem = 0;
|
||||
if ( GetFirstItemWithFlag(&corpseitem, CORPSE) )
|
||||
{
|
||||
// we have to make sure this can be placed in our hands, as corpses can only be carried in hands.
|
||||
// At this point, we will have a knife in our first hand, so check if our second hand is free
|
||||
if ( !(pSoldier->inv[SECONDHANDPOS].exists()) )
|
||||
{
|
||||
CreateItem( corpseitem, 100, &gTempObject );
|
||||
|
||||
if(CanItemFitInPosition(pSoldier, &gTempObject, SECONDHANDPOS, FALSE))
|
||||
{
|
||||
// determine Body type
|
||||
if ( pCorpse->def.ubBodyType == BIGMALE || pCorpse->def.ubBodyType == STOCKYMALE || pCorpse->def.ubBodyType == FATCIV )
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_M_BIG;
|
||||
else if ( pCorpse->def.ubBodyType == REGFEMALE || pCorpse->def.ubBodyType == MINICIV || pCorpse->def.ubBodyType == DRESSCIV )
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_F;
|
||||
|
||||
if ( pCorpse->def.usFlags & ROTTING_CORPSE_HEAD_TAKEN )
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_NO_HEAD;
|
||||
|
||||
if ( pCorpse->def.usFlags & ROTTING_CORPSE_CLOTHES_TAKEN )
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_STRIPPED;
|
||||
|
||||
// now we have to get the correct flags for the object from the corpse, so that upon recreating the corpse, it looks the same
|
||||
UINT8 headpal = 0, skinpal = 0, vestpal = 0, pantspal = 0;
|
||||
GetPaletteRepIndexFromID(pCorpse->def.HeadPal, &headpal);
|
||||
GetPaletteRepIndexFromID(pCorpse->def.SkinPal, &skinpal);
|
||||
GetPaletteRepIndexFromID(pCorpse->def.VestPal, &vestpal);
|
||||
GetPaletteRepIndexFromID(pCorpse->def.PantsPal, &pantspal);
|
||||
|
||||
switch ( headpal )
|
||||
{
|
||||
case 0:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_HAIR_BLOND;
|
||||
break;
|
||||
case 1:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_HAIR_BROWN;
|
||||
break;
|
||||
case 2:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_HAIR_BLACK;
|
||||
break;
|
||||
case 3:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_HAIR_WHITE;
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_HAIR_RED;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( skinpal )
|
||||
{
|
||||
case 13:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_SKIN_PINK;
|
||||
break;
|
||||
case 14:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_SKIN_TAN;
|
||||
break;
|
||||
case 15:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_SKIN_DARK;
|
||||
break;
|
||||
case 16:
|
||||
default:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_SKIN_BLACK;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( vestpal )
|
||||
{
|
||||
case 17:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_BROWN;
|
||||
break;
|
||||
case 18:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_grey;
|
||||
break;
|
||||
case 19:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_GREEN;
|
||||
break;
|
||||
case 20:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_JEAN;
|
||||
break;
|
||||
case 21:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_RED;
|
||||
break;
|
||||
case 22:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_BLUE;
|
||||
break;
|
||||
case 23:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_YELLOW;
|
||||
break;
|
||||
case 24:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_WHITE;
|
||||
break;
|
||||
case 25:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_BLACK;
|
||||
break;
|
||||
case 26:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_GYELLOW;
|
||||
break;
|
||||
case 27:
|
||||
default:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_VEST_PURPLE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( pantspal )
|
||||
{
|
||||
case 7:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_PANTS_GREEN;
|
||||
break;
|
||||
case 8:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_PANTS_JEAN;
|
||||
break;
|
||||
case 9:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_PANTS_TAN;
|
||||
break;
|
||||
case 10:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_PANTS_BLACK;
|
||||
break;
|
||||
case 11:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_PANTS_BLUE;
|
||||
break;
|
||||
case 12:
|
||||
default:
|
||||
gTempObject[0]->data.sObjectFlag |= CORPSE_PANTS_BEIGE;
|
||||
break;
|
||||
}
|
||||
|
||||
gTempObject.MoveThisObjectTo(pSoldier->inv[SECONDHANDPOS], ALL_OBJECTS, pSoldier, SECONDHANDPOS);
|
||||
|
||||
if ( pCorpse->def.ubType != 0 )
|
||||
{
|
||||
// Remove corpse...
|
||||
RemoveCorpse( pCorpse->iID );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"No free hand to carry corpse!" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: create a corpse from an object and plce it in the world
|
||||
BOOLEAN AddCorpseFromObject(OBJECTTYPE* pObj, INT32 sGridNo, INT8 bLevel )
|
||||
{
|
||||
if ( !pObj || !HasItemFlag(pObj->usItem, CORPSE) )
|
||||
return FALSE;
|
||||
|
||||
ROTTING_CORPSE_DEFINITION Corpse;
|
||||
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_M_BIG )
|
||||
{
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_NO_HEAD )
|
||||
Corpse.ubType = MMERC_JFK;
|
||||
else
|
||||
Corpse.ubType = MMERC_BCK;
|
||||
|
||||
Corpse.ubBodyType = BIGMALE;
|
||||
}
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_F )
|
||||
{
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_NO_HEAD )
|
||||
Corpse.ubType = FMERC_JFK;
|
||||
else
|
||||
Corpse.ubType = FMERC_BCK;
|
||||
|
||||
Corpse.ubBodyType = REGFEMALE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_M_SMALL )
|
||||
Corpse.ubType = SMERC_JFK;
|
||||
else
|
||||
Corpse.ubType = SMERC_BCK;
|
||||
|
||||
Corpse.ubBodyType = REGMALE;
|
||||
}
|
||||
|
||||
Corpse.sGridNo = sGridNo;
|
||||
|
||||
Corpse.dXPos = CenterX(Corpse.sGridNo);
|
||||
Corpse.dYPos = CenterY(Corpse.sGridNo);
|
||||
|
||||
Corpse.sHeightAdjustment = 0;
|
||||
|
||||
// check the objects flagmask and set the corpse palette IDs accordingly
|
||||
|
||||
// Hair
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_HAIR_BROWN )
|
||||
SET_PALETTEREP_ID( Corpse.HeadPal, "BROWNHEAD" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_HAIR_BLACK )
|
||||
SET_PALETTEREP_ID( Corpse.HeadPal, "BLACKHEAD" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_HAIR_WHITE )
|
||||
SET_PALETTEREP_ID( Corpse.HeadPal, "WHITEHEAD" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_HAIR_BLOND )
|
||||
SET_PALETTEREP_ID( Corpse.HeadPal, "BLONDHEAD" );
|
||||
else
|
||||
SET_PALETTEREP_ID( Corpse.HeadPal, "REDHEAD" );
|
||||
|
||||
// Skin
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_SKIN_PINK )
|
||||
SET_PALETTEREP_ID( Corpse.SkinPal, "PINKSKIN" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_SKIN_TAN )
|
||||
SET_PALETTEREP_ID( Corpse.SkinPal, "TANSKIN" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_SKIN_DARK )
|
||||
SET_PALETTEREP_ID( Corpse.SkinPal, "DARKSKIN" );
|
||||
else
|
||||
SET_PALETTEREP_ID( Corpse.SkinPal, "BLACKSKIN" );
|
||||
|
||||
// Vest
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_BROWN )
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "BROWNVEST" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_grey )
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "greyVEST" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_GREEN )
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "GREENVEST" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_JEAN )
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "JEANVEST" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_RED )
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "REDVEST" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_BLUE )
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "BLUEVEST" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_YELLOW )
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "YELLOWVEST" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_WHITE )
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "WHITEVEST" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_BLACK )
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "BLACKSHIRT" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_GYELLOW )
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "GYELLOWSHIRT" );
|
||||
else
|
||||
SET_PALETTEREP_ID( Corpse.VestPal, "PURPLESHIRT" );
|
||||
|
||||
// Pants
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_GREEN )
|
||||
SET_PALETTEREP_ID( Corpse.PantsPal, "GREENPANTS" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_JEAN )
|
||||
SET_PALETTEREP_ID( Corpse.PantsPal, "JEANPANTS" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_TAN )
|
||||
SET_PALETTEREP_ID( Corpse.PantsPal, "TANPANTS" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_BLACK )
|
||||
SET_PALETTEREP_ID( Corpse.PantsPal, "BLACKPANTS" );
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_BLUE )
|
||||
SET_PALETTEREP_ID( Corpse.PantsPal, "BLUEPANTS" );
|
||||
else
|
||||
SET_PALETTEREP_ID( Corpse.PantsPal, "BEIGEPANTS" );
|
||||
|
||||
//SET_PALETTEREP_ID( Corpse.VestPal, gUniformColors[ UNIFORM_ENEMY_TROOP ].vest );
|
||||
//SET_PALETTEREP_ID( Corpse.PantsPal, gUniformColors[ UNIFORM_ENEMY_TROOP ].pants );
|
||||
|
||||
Corpse.ubDirection = NORTH;
|
||||
Corpse.uiTimeOfDeath = GetWorldTotalMin();
|
||||
|
||||
Corpse.usFlags = 0; // no flags here, at least not the new ones
|
||||
|
||||
Corpse.bLevel = bLevel;
|
||||
|
||||
Corpse.bVisible = 1;
|
||||
Corpse.bNumServicingCrows = 0;
|
||||
Corpse.ubProfile = NO_PROFILE;
|
||||
Corpse.fHeadTaken = FALSE;
|
||||
Corpse.ubAIWarningValue = 20;
|
||||
|
||||
INT32 iCorpseID = AddRottingCorpse( &Corpse );
|
||||
|
||||
if ( iCorpseID != -1 )
|
||||
{
|
||||
AllMercsOnTeamLookForCorpse(&( gRottingCorpse[ iCorpseID ] ), OUR_TEAM);
|
||||
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_NO_HEAD )
|
||||
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_HEAD_TAKEN;
|
||||
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_STRIPPED )
|
||||
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_CLOTHES_TAKEN;
|
||||
|
||||
// TODO: change this so it always fits, not dependant these colours
|
||||
if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_YELLOW && (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_GREEN )
|
||||
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_FROM_ADMIN;
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_RED && (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_GREEN )
|
||||
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_FROM_TROOP;
|
||||
else if ( (*pObj)[0]->data.sObjectFlag & CORPSE_VEST_BLACK && (*pObj)[0]->data.sObjectFlag & CORPSE_PANTS_BLACK )
|
||||
gRottingCorpse[ iCorpseID ].def.usFlags |= ROTTING_CORPSE_FROM_ELITE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -2552,3 +2957,85 @@ UINT8 GetNearestRottingCorpseAIWarning( INT32 sGridNo )
|
||||
return( canbezombie );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Flugente: can we take the clothes of this corpse?
|
||||
// calling this with NULL for soldier will give a general answer for any bodytype
|
||||
BOOLEAN CorpseOkToDress( ROTTING_CORPSE * pCorpse, SOLDIERTYPE* pSoldier )
|
||||
{
|
||||
if ( !pCorpse )
|
||||
return FALSE;
|
||||
|
||||
switch ( pCorpse->def.ubType )
|
||||
{
|
||||
case SMERC_JFK:
|
||||
case SMERC_BCK:
|
||||
case SMERC_FWD:
|
||||
case SMERC_DHD:
|
||||
case SMERC_PRN:
|
||||
case SMERC_WTR:
|
||||
case SMERC_FALL:
|
||||
case SMERC_FALLF:
|
||||
case M_DEAD1:
|
||||
case M_DEAD2:
|
||||
case H_DEAD1:
|
||||
case H_DEAD2:
|
||||
case S_DEAD1:
|
||||
case S_DEAD2:
|
||||
case C_DEAD1:
|
||||
case C_DEAD2:
|
||||
if ( pSoldier )
|
||||
{
|
||||
if ( pSoldier->ubBodyType == REGMALE )
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
|
||||
break;
|
||||
|
||||
case MMERC_JFK:
|
||||
case MMERC_BCK:
|
||||
case MMERC_FWD:
|
||||
case MMERC_DHD:
|
||||
case MMERC_PRN:
|
||||
case MMERC_WTR:
|
||||
case MMERC_FALL:
|
||||
case MMERC_FALLF:
|
||||
case FT_DEAD1:
|
||||
case FT_DEAD2:
|
||||
if ( pSoldier )
|
||||
{
|
||||
if ( pSoldier->ubBodyType == BIGMALE || pSoldier->ubBodyType == STOCKYMALE )
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
|
||||
break;
|
||||
|
||||
case FMERC_JFK:
|
||||
case FMERC_BCK:
|
||||
case FMERC_FWD:
|
||||
case FMERC_DHD:
|
||||
case FMERC_PRN:
|
||||
case FMERC_WTR:
|
||||
case FMERC_FALL:
|
||||
case FMERC_FALLF:
|
||||
case W_DEAD1:
|
||||
case W_DEAD2:
|
||||
if ( pSoldier )
|
||||
{
|
||||
if ( pSoldier->ubBodyType == REGFEMALE )
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -91,8 +91,12 @@ enum RottingCorpseDefines
|
||||
|
||||
// Flugente: corpses can now be gutted after they have been decapitated. Atm there is no corpse that can be both gutted and decapitated (to be done later)
|
||||
#define ROTTING_CORPSE_HEAD_TAKEN 0x00001000 // head has been taken off
|
||||
#define ROTTING_CORPSE_GUTTED 0x00001000 // corpse has been gutted
|
||||
#define ROTTING_CORPSE_GUTTED 0x00002000 // corpse has been gutted
|
||||
#define ROTTING_CORPSE_CLOTHES_TAKEN 0x00004000 // corpse is without clothes (atm not visually)
|
||||
|
||||
#define ROTTING_CORPSE_FROM_ADMIN 0x00010000 // corpse is from a admin (used to take his clothes)
|
||||
#define ROTTING_CORPSE_FROM_TROOP 0x00020000 // corpse is from a regular soldier (used to take his clothes)
|
||||
#define ROTTING_CORPSE_FROM_ELITE 0x00040000 // corpse is from a elite soldier (used to take his clothes)
|
||||
typedef struct
|
||||
{
|
||||
UINT8 ubType;
|
||||
@@ -199,6 +203,16 @@ ROTTING_CORPSE *GetCorpseAtGridNo( INT32 sGridNo , INT8 bLevel );
|
||||
BOOLEAN IsValidDecapitationCorpse( ROTTING_CORPSE *pCorpse );
|
||||
void DecapitateCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel );
|
||||
|
||||
// Flugente: actions for the covert opts trait
|
||||
BOOLEAN IsValidGutCorpse( ROTTING_CORPSE *pCorpse );
|
||||
void GutCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel );
|
||||
BOOLEAN IsValidStripCorpse( ROTTING_CORPSE *pCorpse );
|
||||
void StripCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel );
|
||||
BOOLEAN IsValidTakeCorpse( ROTTING_CORPSE *pCorpse );
|
||||
void TakeCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel );
|
||||
|
||||
BOOLEAN AddCorpseFromObject(OBJECTTYPE* pObj, INT32 sGridNo, INT8 bLevel );
|
||||
|
||||
void GetBloodFromCorpse( SOLDIERTYPE *pSoldier );
|
||||
|
||||
UINT16 GetCorpseStructIndex( ROTTING_CORPSE_DEFINITION *pCorpseDef, BOOLEAN fForImage );
|
||||
@@ -221,4 +235,7 @@ UINT8 GetNearestRottingCorpseAIWarning( INT32 sGridNo );
|
||||
BOOLEAN CorpseOkToSpawnZombie( ROTTING_CORPSE * pCorpse, UINT16* pAnimState );
|
||||
#endif
|
||||
|
||||
// Flugente: can we take the clothes of this corpse?
|
||||
BOOLEAN CorpseOkToDress( ROTTING_CORPSE * pCorpse, SOLDIERTYPE* pSoldier );
|
||||
|
||||
#endif
|
||||
@@ -2926,7 +2926,10 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
|
||||
case 752:
|
||||
|
||||
// Code: decapitate
|
||||
DecapitateCorpse( pSoldier, pSoldier->sTargetGridNo, pSoldier->bTargetLevel );
|
||||
//DecapitateCorpse( pSoldier, pSoldier->sTargetGridNo, pSoldier->bTargetLevel );
|
||||
|
||||
// Flugente: instead of jsut decapitating, we call a selection window where we can choose what to do with the corpse
|
||||
HandleSoldierUseCorpse( pSoldier, pSoldier->sTargetGridNo, pSoldier->bTargetLevel ); // Flugente: handle corpses
|
||||
break;
|
||||
|
||||
case 753:
|
||||
|
||||
@@ -6315,6 +6315,10 @@ void SoldierGotHitGunFire( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sD
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: if hit in legs or torso, blood will be on our uniform - this unifrom can't be used to disguise someone anymore
|
||||
if ( ubHitLocation == AIM_SHOT_TORSO || ubHitLocation == AIM_SHOT_LEGS )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_UNIFORM;
|
||||
|
||||
// IF HERE AND GUY IS DEAD, RETURN!
|
||||
if ( pSoldier->flags.uiStatusFlags & SOLDIER_DEAD )
|
||||
{
|
||||
@@ -6361,6 +6365,10 @@ void SoldierGotHitGunFire( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sD
|
||||
|
||||
void SoldierGotHitExplosion( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDamage, UINT16 bDirection, UINT16 sRange, UINT8 ubAttackerID, UINT8 ubSpecial, UINT8 ubHitLocation )
|
||||
{
|
||||
// Flugente: if hit in legs or torso, blood will be on our uniform - this unifrom can't be used to disguise someone anymore
|
||||
if ( ubHitLocation == AIM_SHOT_TORSO || ubHitLocation == AIM_SHOT_LEGS )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_UNIFORM;
|
||||
|
||||
INT32 sNewGridNo;
|
||||
|
||||
// IF HERE AND GUY IS DEAD, RETURN!
|
||||
@@ -6529,6 +6537,9 @@ void SoldierGotHitExplosion( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16
|
||||
|
||||
void SoldierGotHitBlade( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDamage, UINT16 bDirection, UINT16 sRange, UINT8 ubAttackerID, UINT8 ubSpecial, UINT8 ubHitLocation )
|
||||
{
|
||||
// Flugente: if hit in legs or torso, blood will be on our uniform - this unifrom can't be used to disguise someone anymore
|
||||
if ( ubHitLocation == AIM_SHOT_TORSO || ubHitLocation == AIM_SHOT_LEGS )
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_DAMAGED_UNIFORM;
|
||||
|
||||
// IF HERE AND GUY IS DEAD, RETURN!
|
||||
if ( pSoldier->flags.uiStatusFlags & SOLDIER_DEAD )
|
||||
@@ -11684,7 +11695,8 @@ void SOLDIERTYPE::EVENT_SoldierBeginBladeAttack( INT32 sGridNo, UINT8 ubDirectio
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( IsValidDecapitationCorpse( pCorpse ) )
|
||||
// Flugente: decapitation action now also performs gutting, stripping and taking corpses
|
||||
if ( IsValidDecapitationCorpse( pCorpse ) || IsValidGutCorpse( pCorpse ) || IsValidStripCorpse( pCorpse ) || IsValidTakeCorpse( pCorpse ) )
|
||||
{
|
||||
this->EVENT_InitNewSoldierAnim( DECAPITATE, 0 , FALSE );
|
||||
}
|
||||
@@ -14393,6 +14405,742 @@ void SOLDIERTYPE::CleanWeapon()
|
||||
}
|
||||
}
|
||||
|
||||
extern INT16 uiNIVSlotType[NUM_INV_SLOTS];
|
||||
|
||||
// do we look like a civilian?
|
||||
BOOLEAN SOLDIERTYPE::LooksLikeACivilian( void )
|
||||
{
|
||||
// if we have any camo: not covert
|
||||
if ( GetWornCamo(this) > 0 || GetWornUrbanCamo(this) > 0 || GetWornDesertCamo(this) > 0 || GetWornSnowCamo(this) > 0 )
|
||||
return FALSE;
|
||||
|
||||
if ( UsingNewInventorySystem() )
|
||||
{
|
||||
INT8 invsize = (INT8)this->inv.size();
|
||||
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ...
|
||||
{
|
||||
if ( this->inv[bLoop].exists() )
|
||||
{
|
||||
// if we have a back pack: not covert
|
||||
if ( bLoop == BPACKPOCKPOS )
|
||||
return FALSE;
|
||||
|
||||
// do not check the LBE itself (we already checked for camo above)
|
||||
if ( bLoop >= VESTPOCKPOS && bLoop <= CPACKPOCKPOS )
|
||||
continue;
|
||||
|
||||
BOOLEAN checkfurther = FALSE;
|
||||
// further checks it item is not covert. This means that a gun that has that tag will not be detectedif if its inside a pocket!
|
||||
if ( bLoop == HANDPOS || bLoop == SECONDHANDPOS || bLoop == GUNSLINGPOCKPOS || bLoop == HELMETPOS || bLoop == VESTPOS || bLoop == LEGPOS || bLoop == HEAD1POS || bLoop == HEAD2POS )
|
||||
checkfurther = TRUE;
|
||||
else if ( bLoop == KNIFEPOCKPOS && !HasItemFlag(this->inv[bLoop].usItem, COVERT) )
|
||||
checkfurther = TRUE;
|
||||
else if ( !HasItemFlag(this->inv[bLoop].usItem, COVERT) )
|
||||
{
|
||||
checkfurther = TRUE;
|
||||
|
||||
// item will be detected if someone looks - check for the LBE item that gave us this slot. If that one is covert, this item is also covert
|
||||
UINT8 checkslot = 0;
|
||||
switch (uiNIVSlotType[bLoop])
|
||||
{
|
||||
case 3:
|
||||
checkslot = VESTPOCKPOS;
|
||||
break;
|
||||
case 4:
|
||||
if ( bLoop == 23 || bLoop == 35 || bLoop == 36 || bLoop == 37 || bLoop == 38 )
|
||||
checkslot = LTHIGHPOCKPOS;
|
||||
else
|
||||
checkslot = RTHIGHPOCKPOS;
|
||||
break;
|
||||
case 5:
|
||||
checkslot = CPACKPOCKPOS;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// found a slot to check for LBE
|
||||
if ( checkslot > 0 )
|
||||
{
|
||||
// if LBE is covert
|
||||
if ( this->inv[checkslot].exists() && HasItemFlag(this->inv[checkslot].usItem, COVERT) )
|
||||
// pass for this item
|
||||
checkfurther = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( checkfurther )
|
||||
{
|
||||
// if that item is a gun, explosives, military armour or facewear, we're screwed
|
||||
if ( (Item[this->inv[bLoop].usItem].usItemClass & (IC_WEAPON|IC_GRENADE|IC_BOMB) ) ||
|
||||
( (Item[this->inv[bLoop].usItem].usItemClass & (IC_ARMOUR) ) && !Item[this->inv[bLoop].usItem].leatherjacket && Armour[ Item[this->inv[bLoop].usItem].ubClassIndex ].ubProtection > 10 ) ||
|
||||
( Item[this->inv[bLoop].usItem].nightvisionrangebonus > 0 || Item[this->inv[bLoop].usItem].hearingrangebonus > 0 )
|
||||
)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // old inventory system. No LBE here, nothing fancy
|
||||
{
|
||||
INT8 invsize = (INT8)this->inv.size();
|
||||
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ...
|
||||
{
|
||||
if ( this->inv[bLoop].exists() )
|
||||
{
|
||||
if ( !HasItemFlag(this->inv[bLoop].usItem, COVERT) )
|
||||
{
|
||||
// if that item is a gun, explosives, military armour or facewear, we're screwed
|
||||
if ( (Item[this->inv[bLoop].usItem].usItemClass & (IC_WEAPON|IC_GRENADE|IC_BOMB) ) ||
|
||||
( (Item[this->inv[bLoop].usItem].usItemClass & (IC_ARMOUR) ) && !Item[this->inv[bLoop].usItem].leatherjacket && Armour[ Item[this->inv[bLoop].usItem].ubClassIndex ].ubProtection > 10 ) ||
|
||||
( Item[this->inv[bLoop].usItem].nightvisionrangebonus > 0 || Item[this->inv[bLoop].usItem].hearingrangebonus > 0 )
|
||||
)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// do we look like a soldier?
|
||||
BOOLEAN SOLDIERTYPE::LooksLikeASoldier( void )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// is our equipment too good for a soldier?
|
||||
BOOLEAN SOLDIERTYPE::EquipmentTooGood( BOOLEAN fCloselook )
|
||||
{
|
||||
// check the guns in our hands an rifle sling
|
||||
// alert if we have more than 2, any of them has too much attachments or they are way too cool
|
||||
UINT8 numberofguns = 0;
|
||||
UINT8 ubCurrentProgress = CurrentPlayerProgressPercentage();
|
||||
UINT8 maxcoolnessallowed = 1 + ubCurrentProgress / 10;
|
||||
maxcoolnessallowed += 2; // TODO adjust for level and uniform
|
||||
UINT16 maxitemsize = 4;
|
||||
|
||||
if ( UsingNewInventorySystem() )
|
||||
{
|
||||
INT8 invsize = (INT8)this->inv.size();
|
||||
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ...
|
||||
{
|
||||
if ( this->inv[bLoop].exists() )
|
||||
{
|
||||
// if we have a back pack: not covert
|
||||
if ( bLoop == BPACKPOCKPOS )
|
||||
return FALSE;
|
||||
|
||||
// further checks it item is not covert. This means that a gun that has that tag will not be detectedif if its inside a pocket!
|
||||
if ( bLoop == HANDPOS || bLoop == SECONDHANDPOS || bLoop == GUNSLINGPOCKPOS || bLoop == HELMETPOS || bLoop == VESTPOS || bLoop == LEGPOS || bLoop == HEAD1POS || bLoop == HEAD2POS ||
|
||||
!HasItemFlag(this->inv[bLoop].usItem, COVERT) )
|
||||
{
|
||||
// item will be detected if someone looks - check for the LBE item that gave us this slot. If that one is covert, this item is also covert
|
||||
UINT8 checkslot = 0;
|
||||
switch (uiNIVSlotType[bLoop])
|
||||
{
|
||||
case 3:
|
||||
checkslot = VESTPOCKPOS;
|
||||
break;
|
||||
case 4:
|
||||
if ( bLoop == 23 || bLoop == 35 || bLoop == 36 || bLoop == 37 || bLoop == 38 )
|
||||
checkslot = LTHIGHPOCKPOS;
|
||||
else
|
||||
checkslot = RTHIGHPOCKPOS;
|
||||
break;
|
||||
case 5:
|
||||
checkslot = CPACKPOCKPOS;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// found a slot to check for LBE
|
||||
if ( checkslot > 0 )
|
||||
{
|
||||
// if LBE is covert
|
||||
if ( this->inv[checkslot].exists() && HasItemFlag(this->inv[checkslot].usItem, COVERT) )
|
||||
// pass for this item
|
||||
continue;
|
||||
}
|
||||
|
||||
// if that item is a gun, explosives, military armour or facewear, investigate further
|
||||
if ( (Item[this->inv[bLoop].usItem].usItemClass & (IC_GUN|IC_LAUNCHER|IC_ARMOUR|IC_FACE) ) )
|
||||
{
|
||||
if ( (Item[this->inv[bLoop].usItem].usItemClass & (IC_GUN|IC_LAUNCHER) ) )
|
||||
{
|
||||
++numberofguns;
|
||||
|
||||
if ( numberofguns > 2 )
|
||||
return TRUE;
|
||||
|
||||
OBJECTTYPE * pObj = &(this->inv[bLoop]); // ... get pointer for this item ...
|
||||
|
||||
if ( pObj != NULL )
|
||||
{
|
||||
for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ...
|
||||
{
|
||||
// loop over every item and its attachments
|
||||
if ( Item[pObj->usItem].ubCoolness > maxcoolnessallowed )
|
||||
return TRUE;
|
||||
|
||||
UINT8 numberofattachments = 0;
|
||||
// for every objects, we also have to check wether there are weapon attachments (eg. underbarrel grenade launchers), and cool them down too
|
||||
attachmentList::iterator iterend = (*pObj)[i]->attachments.end();
|
||||
for (attachmentList::iterator iter = (*pObj)[i]->attachments.begin(); iter != iterend; ++iter)
|
||||
{
|
||||
if ( iter->exists() )
|
||||
{
|
||||
// loop over every item and its attachments
|
||||
if ( Item[iter->usItem].ubCoolness > maxcoolnessallowed )
|
||||
return TRUE;
|
||||
|
||||
++numberofattachments;
|
||||
}
|
||||
}
|
||||
|
||||
// no ordinary soldier is allowed that many attachemnts > not covert
|
||||
if ( numberofattachments > gGameExternalOptions.iMaxEnemyAttachments )
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // old inventory system. No LBE here, nothing fancy
|
||||
{
|
||||
INT8 invsize = (INT8)this->inv.size();
|
||||
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ...
|
||||
{
|
||||
if ( this->inv[bLoop].exists() )
|
||||
{
|
||||
// if that item is a gun, explosives, military armour or facewear, investigate further
|
||||
if ( !HasItemFlag(this->inv[bLoop].usItem, COVERT) && (Item[this->inv[bLoop].usItem].usItemClass & (IC_GUN|IC_LAUNCHER|IC_ARMOUR|IC_FACE) ) )
|
||||
{
|
||||
if ( (Item[this->inv[bLoop].usItem].usItemClass & (IC_GUN|IC_LAUNCHER) ) )
|
||||
{
|
||||
++numberofguns;
|
||||
|
||||
if ( numberofguns > 2 )
|
||||
return TRUE;
|
||||
|
||||
OBJECTTYPE * pObj = &(this->inv[bLoop]); // ... get pointer for this item ...
|
||||
|
||||
if ( pObj != NULL )
|
||||
{
|
||||
for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ...
|
||||
{
|
||||
// loop over every item and its attachments
|
||||
if ( Item[pObj->usItem].ubCoolness > maxcoolnessallowed )
|
||||
return TRUE;
|
||||
|
||||
UINT8 numberofattachments = 0;
|
||||
// for every objects, we also have to check wether there are weapon attachments (eg. underbarrel grenade launchers), and cool them down too
|
||||
attachmentList::iterator iterend = (*pObj)[i]->attachments.end();
|
||||
for (attachmentList::iterator iter = (*pObj)[i]->attachments.begin(); iter != iterend; ++iter)
|
||||
{
|
||||
if ( iter->exists() )
|
||||
{
|
||||
// loop over every item and its attachments
|
||||
if ( Item[iter->usItem].ubCoolness > maxcoolnessallowed )
|
||||
return TRUE;
|
||||
|
||||
++numberofattachments;
|
||||
}
|
||||
}
|
||||
|
||||
// no ordinary soldier is allowed that many attachments > not covert
|
||||
if ( numberofattachments > gGameExternalOptions.iMaxEnemyAttachments )
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// are we in covert mode? we need to have the correct flag set, and not wear anything suspicious, or behave in a suspicious way
|
||||
BOOLEAN SOLDIERTYPE::SeemsLegit( UINT8 ubObserverID )
|
||||
{
|
||||
SOLDIERTYPE* pSoldier = MercPtrs[ubObserverID];
|
||||
|
||||
if ( !pSoldier )
|
||||
return TRUE;
|
||||
|
||||
// if we don't have the Flag: not covert
|
||||
// important: no messages up to this point. the function will get called a lot, up to this point there is nothing unusual
|
||||
if ( !(this->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER) ) )
|
||||
return FALSE;
|
||||
|
||||
// if we are in a suspicious stance: not covert
|
||||
if ( this->usAnimState == NINJA_SPINKICK ||
|
||||
this->usAnimState == NINJA_PUNCH ||
|
||||
this->usAnimState == NINJA_LOWKICK ||
|
||||
this->usAnimState == PUNCH_LOW ||
|
||||
this->usAnimState == DECAPITATE ||
|
||||
this->usAnimState == CROWBAR_ATTACK ||
|
||||
this->usAnimState == THROW_GRENADE_STANCE ||
|
||||
this->usAnimState == THROW_KNIFE_SP_BM ||
|
||||
this->usAnimState == DODGE_ONE ||
|
||||
this->usAnimState == SLICE ||
|
||||
this->usAnimState == STAB ||
|
||||
this->usAnimState == CROUCH_STAB ||
|
||||
this->usAnimState == PUNCH ||
|
||||
this->usAnimState == PUNCH_BREATH ||
|
||||
this->usAnimState == KICK_DOOR ||
|
||||
this->usAnimState == CUTTING_FENCE ||
|
||||
this->usAnimState == THROW_KNIFE ||
|
||||
this->usAnimState == PLANT_BOMB ||
|
||||
this->usAnimState == USE_REMOTE ||
|
||||
this->usAnimState == TAKE_BLOOD_FROM_CORPSE ||
|
||||
this->usAnimState == PICK_LOCK ||
|
||||
this->usAnimState == LOCKPICK_CROUCHED ||
|
||||
this->usAnimState == STEAL_ITEM_CROUCHED ||
|
||||
this->usAnimState == JUMPWINDOWS
|
||||
)
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s was seen performing suspicious activities!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN looklikeaciv = this->LooksLikeACivilian();
|
||||
|
||||
// if we are trying to dress like a civilian, but aren't sucessful: not covert
|
||||
if ( this->bSoldierFlagMask & SOLDIER_COVERT_CIV && !looklikeaciv)
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s does not look like a civilian!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN looklikeasoldier = this->LooksLikeASoldier();
|
||||
|
||||
// if we are trying to dress like a soldier, but aren't sucessful: not covert
|
||||
if ( this->bSoldierFlagMask & SOLDIER_COVERT_SOLDIER && !looklikeasoldier)
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s does not look like a soldier!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UINT8 covertlevel = NUM_SKILL_TRAITS( this, COVERT_NT ); // our level in covert operations
|
||||
INT32 distance = GetRangeFromGridNoDiff(this->sGridNo, pSoldier->sGridNo);
|
||||
|
||||
// if we are closer than this, our cover will always break if we do not have the skill
|
||||
// if we have the skill, our cover will blow if we dress up as a soldier, but not if we are dressed like a civilian
|
||||
INT32 discoverrange = gSkillTraitValues.sCOCloseDetectionRange;
|
||||
|
||||
if ( distance < discoverrange )
|
||||
{
|
||||
switch ( covertlevel )
|
||||
{
|
||||
case 2:
|
||||
// a covert ops expert can get as close as he wants, even dressed up as a soldier, without arousing suspicion
|
||||
// exceptions: we are discovered if we are close and bleeding, or if we are drunk while dressed as a soldier
|
||||
{
|
||||
// if we are openly bleeding: not covert
|
||||
if ( this->bBleeding > 0 )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s bleeding was discovered!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( this->bSoldierFlagMask & SOLDIER_COVERT_SOLDIER && GetDrunkLevel( this ) != SOBER )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s is drunk and doesn't look like a soldier!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// at lvl covert ops, we can be discovered if we are too close to the enemy and bleed or dressed up as a soldier
|
||||
// however, if we are dressed up as a civilian, we can get as close as we like, we won't be discovered
|
||||
{
|
||||
// if we are openly bleeding: not covert
|
||||
if ( this->bBleeding > 0 )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s bleeding was discovered!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( this->bSoldierFlagMask & SOLDIER_COVERT_SOLDIER )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"On closer inspection, %s's disguise does not hold!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
// without the covert ops skill, we can only dress up as civilians. We will be discovered if we get too close to the enemy
|
||||
if ( (this->bSoldierFlagMask & SOLDIER_COVERT_NPC_SPECIAL) == 0 )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"On closer inspection, %s's disguise does not hold!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( this->bSoldierFlagMask & SOLDIER_COVERT_CIV )
|
||||
{
|
||||
// civilians are suspicious if they are found in certain sectors. Especially at night
|
||||
// sector specific value:
|
||||
// 0 - civilians are always ok
|
||||
// 1 - civilians are suspicious at night
|
||||
// 2 - civilians are always suspicious
|
||||
|
||||
UINT8 sectordata = 0;
|
||||
UINT8 ubSectorId = SECTOR(gWorldSectorX, gWorldSectorY);
|
||||
if ( gbWorldSectorZ > 0 )
|
||||
// underground we are always suspicious
|
||||
sectordata = 2;
|
||||
else if ( ubSectorId >= 0 && ubSectorId < 256 )
|
||||
sectordata = SectorExternalData[ubSectorId][gbWorldSectorZ].usCurfewValue;
|
||||
|
||||
if ( sectordata > 1 )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s isn't supposed to be here!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
// is it night?
|
||||
else if ( sectordata == 1 && GetTimeOfDayAmbientLightLevel() < NORMAL_LIGHTLEVEL_DAY + 2 )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s isn't supposed to be here at this time!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// check wether we are around a fresh corpse - this will make us much more suspicious
|
||||
INT32 cnt;
|
||||
ROTTING_CORPSE * pCorpse;
|
||||
for ( cnt = 0; cnt < giNumRottingCorpse; ++cnt )
|
||||
{
|
||||
pCorpse = &(gRottingCorpse[ cnt ] );
|
||||
|
||||
if ( pCorpse && pCorpse->fActivated && pCorpse->def.ubAIWarningValue > 0 && PythSpacesAway( this->sGridNo, pCorpse->def.sGridNo ) <= 5 )
|
||||
{
|
||||
// a corpse was found near our position. If the soldier observing us can see it, he will be alarmed
|
||||
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pCorpse->def.sGridNo, pCorpse->def.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s was seen near a fresh corpse!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( this->bSoldierFlagMask & SOLDIER_COVERT_SOLDIER )
|
||||
{
|
||||
// if our equipment is too good, that is suspicious... not covert!
|
||||
if ( this->EquipmentTooGood( (distance < discoverrange) ) )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s equipment raises a few eyebrows!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// are we targeting a buddy of our observer?
|
||||
if ( this->ubTargetID && MercPtrs[this->ubTargetID] && MercPtrs[this->ubTargetID]->bTeam == pSoldier->bTeam )
|
||||
{
|
||||
// if we aiming at a soldier, others will notice our intent... not covert!
|
||||
if ( WeaponReady(this) )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s is seen targeting a soldier!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// even as a soldier, we will be caught around fresh corpses
|
||||
if (distance < gSkillTraitValues.sCOCloseDetectionRangeSoldierCorpse)
|
||||
{
|
||||
// check wether we are around a fresh corpse - this will make us much more suspicious
|
||||
// I deem this necessary, to avoid cheap exploits by nefarious players :-)
|
||||
INT32 cnt;
|
||||
ROTTING_CORPSE * pCorpse;
|
||||
for ( cnt = 0; cnt < giNumRottingCorpse; ++cnt )
|
||||
{
|
||||
pCorpse = &(gRottingCorpse[ cnt ] );
|
||||
|
||||
if ( pCorpse && pCorpse->fActivated && pCorpse->def.ubAIWarningValue > 0 && PythSpacesAway( this->sGridNo, pCorpse->def.sGridNo ) <= 5 )
|
||||
{
|
||||
// a corpse was found near our position. If the soldier observing us can see it, he will be alarmed
|
||||
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pCorpse->def.sGridNo, pCorpse->def.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s was seen near a fresh corpse!", this->name );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// do we recognize someone else as a combatant?
|
||||
BOOLEAN SOLDIERTYPE::RecognizeAsCombatant(UINT8 ubTargetID)
|
||||
{
|
||||
// this will only work with the new trait system
|
||||
if (!gGameOptions.fNewTraitSystem)
|
||||
return TRUE;
|
||||
|
||||
SOLDIERTYPE* pSoldier = MercPtrs[ubTargetID];
|
||||
|
||||
if ( !pSoldier )
|
||||
return TRUE;
|
||||
|
||||
// if neither of the 2 persons is covert, always return true
|
||||
if ( ( (pSoldier->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER)) == 0 ) && ( (this->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER)) == 0 ) )
|
||||
return TRUE;
|
||||
|
||||
// only members of the player team can ever be covert, sorry AI
|
||||
if ( pSoldier->bTeam != OUR_TEAM )
|
||||
return TRUE;
|
||||
|
||||
// neutral characters just dont care
|
||||
if ( this->aiData.bNeutral )
|
||||
return TRUE;
|
||||
|
||||
// check for for vehicles and creatures... weird things happen
|
||||
if ( IsVehicle(pSoldier) || pSoldier->bTeam == CREATURE_TEAM || this->bTeam == CREATURE_TEAM )
|
||||
return TRUE;
|
||||
|
||||
// checking someone from our team...
|
||||
if ( this->bTeam == pSoldier->bTeam )
|
||||
{
|
||||
// not in covert mode: we recognize him
|
||||
if ( (pSoldier->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER)) == 0 )
|
||||
return TRUE;
|
||||
else
|
||||
// we don't because we accept that he is covert (to not blow his cover)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// hack: if this is attacking us at this very moment by punching, do not recognize him...
|
||||
// this resolves the problem that we attack someone from behind and kill him instantly, but the game mechanic forces him to turn before
|
||||
// only allow this if we are not yet alerted (we are suprised, so we don't recognize him in the moment of the attack
|
||||
// also: only allow if he's next to us
|
||||
if ( this->aiData.bAlertStatus < STATUS_RED && pSoldier->ubTargetID == this->ubID )
|
||||
{
|
||||
INT32 nextGridNoinSight = NewGridNo( pSoldier->sGridNo, DirectionInc( pSoldier->ubDirection ) );
|
||||
if ( nextGridNoinSight == this->sGridNo && this->pathing.bLevel == pSoldier->pathing.bLevel )
|
||||
{
|
||||
if ( pSoldier->usAnimState == PUNCH )
|
||||
return FALSE;
|
||||
else if ( pSoldier->usAnimState == PUNCH_BREATH )
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// do we recognize this guy as an enemy?
|
||||
if ( !pSoldier->SeemsLegit(this->ubID) )
|
||||
{
|
||||
// aha, he/she's a spy! Blow cover
|
||||
if ( pSoldier->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER) )
|
||||
{
|
||||
pSoldier->LooseDisguise();
|
||||
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s has seen through %s disguise!", this->name, pSoldier->name );
|
||||
|
||||
// we have uncovered a spy! Get alerted, if we aren't already
|
||||
if ( this->aiData.bAlertStatus < STATUS_BLACK )
|
||||
this->aiData.bAlertStatus = STATUS_BLACK;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// dress up in our natural state
|
||||
void SOLDIERTYPE::LooseDisguise( void )
|
||||
{
|
||||
// show our true colours
|
||||
UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( this, this->usAnimState );
|
||||
|
||||
if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
|
||||
{
|
||||
UINT8 ubProfileIndex;
|
||||
MERCPROFILESTRUCT * pProfile;
|
||||
|
||||
ubProfileIndex = this->ubProfile;
|
||||
pProfile = &(gMercProfiles[ubProfileIndex]);
|
||||
|
||||
SET_PALETTEREP_ID ( this->VestPal, pProfile->VEST );
|
||||
SET_PALETTEREP_ID ( this->PantsPal, pProfile->PANTS );
|
||||
|
||||
// Use palette from HVOBJECT, then use substitution for pants, etc
|
||||
memcpy( this->p8BPPPalette, gAnimSurfaceDatabase[ usPaletteAnimSurface ].hVideoObject->pPaletteEntry, sizeof( this->p8BPPPalette ) * 256 );
|
||||
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->HeadPal );
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->VestPal );
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->PantsPal );
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->SkinPal );
|
||||
|
||||
this->CreateSoldierPalettes();
|
||||
}
|
||||
|
||||
// loose any covert flags
|
||||
// if we are disguised as a civilian, remove that flag, and give us back a civilian clothes item
|
||||
if ( this->bSoldierFlagMask & SOLDIER_COVERT_CIV )
|
||||
{
|
||||
this->bSoldierFlagMask &= ~SOLDIER_COVERT_CIV;
|
||||
|
||||
UINT16 civilianclothesitem = 0;
|
||||
if ( GetFirstItemWithFlag(&civilianclothesitem, CLOTHES_CIVILIAN) )
|
||||
{
|
||||
CreateItem( civilianclothesitem, 100, &gTempObject );
|
||||
|
||||
if ( !AutoPlaceObject( this, &gTempObject, FALSE ) )
|
||||
AddItemToPool( sGridNo, &gTempObject, 1, 0, 0, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
// if we are also disguised as a soldier, remove that flag
|
||||
if ( this->bSoldierFlagMask & SOLDIER_COVERT_SOLDIER )
|
||||
{
|
||||
this->bSoldierFlagMask &= ~SOLDIER_COVERT_SOLDIER;
|
||||
}
|
||||
}
|
||||
|
||||
// dress up like a civilian
|
||||
BOOLEAN SOLDIERTYPE::DisguiseAsCivilian( void )
|
||||
{
|
||||
// this will only work with the new trait system
|
||||
if (!gGameOptions.fNewTraitSystem)
|
||||
return FALSE;
|
||||
|
||||
UINT8 skilllevel = NUM_SKILL_TRAITS( this, COVERT_NT );
|
||||
|
||||
INT16 apcost = (APBPConstants[AP_DISGUISE] * ( gSkillTraitValues.sCODisguiseAPReduction * skilllevel))/100;
|
||||
if ( !EnoughPoints( this, apcost, 0, TRUE ) )
|
||||
return( FALSE );
|
||||
|
||||
this->bSoldierFlagMask |= SOLDIER_COVERT_CIV;
|
||||
|
||||
// wear an enemy uniform
|
||||
UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( this, this->usAnimState );
|
||||
|
||||
if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
|
||||
{
|
||||
// wear something random
|
||||
switch( Random( 7 ) )
|
||||
{
|
||||
case 0: SET_PALETTEREP_ID( this->VestPal, "WHITEVEST" ); break;
|
||||
case 1: SET_PALETTEREP_ID( this->VestPal, "BLACKSHIRT" ); break;
|
||||
case 2: SET_PALETTEREP_ID( this->VestPal, "PURPLESHIRT" ); break;
|
||||
case 3: SET_PALETTEREP_ID( this->VestPal, "BLUEVEST" ); break;
|
||||
case 4: SET_PALETTEREP_ID( this->VestPal, "BROWNVEST" ); break;
|
||||
case 5: SET_PALETTEREP_ID( this->VestPal, "JEANVEST" ); break;
|
||||
case 6: SET_PALETTEREP_ID( this->VestPal, "REDVEST" ); break;
|
||||
}
|
||||
|
||||
switch( Random( 3 ) )
|
||||
{
|
||||
case 0: SET_PALETTEREP_ID( this->PantsPal, "TANPANTS" ); break;
|
||||
case 1: SET_PALETTEREP_ID( this->PantsPal, "BEIGEPANTS" ); break;
|
||||
case 2: SET_PALETTEREP_ID( this->PantsPal, "GREENPANTS" ); break;
|
||||
}
|
||||
|
||||
// Use palette from HVOBJECT, then use substitution for pants, etc
|
||||
memcpy( this->p8BPPPalette, gAnimSurfaceDatabase[ usPaletteAnimSurface ].hVideoObject->pPaletteEntry, sizeof( this->p8BPPPalette ) * 256 );
|
||||
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->HeadPal );
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->VestPal );
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->PantsPal );
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->SkinPal );
|
||||
|
||||
this->CreateSoldierPalettes();
|
||||
}
|
||||
|
||||
// if we are also disguised as a soldier, remove that flag
|
||||
if ( this->bSoldierFlagMask & SOLDIER_COVERT_SOLDIER )
|
||||
{
|
||||
this->bSoldierFlagMask &= ~SOLDIER_COVERT_SOLDIER;
|
||||
}
|
||||
|
||||
DeductPoints( this, apcost, 0 );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// dress up like an enemy soldier
|
||||
BOOLEAN SOLDIERTYPE::DisguiseAsSoldierFromCorpse( UINT32 usFlag )
|
||||
{
|
||||
// this will only work with the new trait system
|
||||
if (!gGameOptions.fNewTraitSystem)
|
||||
return FALSE;
|
||||
|
||||
// action is only possible if we have the covert ops trait
|
||||
UINT8 skilllevel = NUM_SKILL_TRAITS( this, COVERT_NT );
|
||||
if ( skilllevel < 1)
|
||||
return FALSE;
|
||||
|
||||
INT16 apcost = (APBPConstants[AP_DISGUISE] * ( gSkillTraitValues.sCODisguiseAPReduction * skilllevel))/100;
|
||||
if ( !EnoughPoints( this, apcost, 0, TRUE ) )
|
||||
return( FALSE );
|
||||
|
||||
UINT8 uniformtype = 0;
|
||||
|
||||
if ( usFlag & ROTTING_CORPSE_FROM_ADMIN )
|
||||
uniformtype = UNIFORM_ENEMY_ADMIN;
|
||||
else if ( usFlag & ROTTING_CORPSE_FROM_TROOP )
|
||||
uniformtype = UNIFORM_ENEMY_TROOP;
|
||||
else if ( usFlag & ROTTING_CORPSE_FROM_ELITE )
|
||||
uniformtype = UNIFORM_ENEMY_ELITE;
|
||||
else
|
||||
// no uniform here, so nothing to wear
|
||||
return FALSE;
|
||||
|
||||
this->bSoldierFlagMask |= SOLDIER_COVERT_SOLDIER;
|
||||
|
||||
// wear an enemy uniform
|
||||
UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( this, this->usAnimState );
|
||||
|
||||
if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
|
||||
{
|
||||
SET_PALETTEREP_ID(this->VestPal, gUniformColors[ uniformtype ].vest );
|
||||
SET_PALETTEREP_ID(this->PantsPal, gUniformColors[ uniformtype ].pants );
|
||||
|
||||
// Use palette from HVOBJECT, then use substitution for pants, etc
|
||||
memcpy( this->p8BPPPalette, gAnimSurfaceDatabase[ usPaletteAnimSurface ].hVideoObject->pPaletteEntry, sizeof( this->p8BPPPalette ) * 256 );
|
||||
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->HeadPal );
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->VestPal );
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->PantsPal );
|
||||
SetPaletteReplacement( this->p8BPPPalette, this->SkinPal );
|
||||
|
||||
this->CreateSoldierPalettes();
|
||||
}
|
||||
|
||||
// if we are disguised as a civilian, remove that flag, and give us back a civilian clothes item
|
||||
if ( this->bSoldierFlagMask & SOLDIER_COVERT_CIV )
|
||||
{
|
||||
this->bSoldierFlagMask &= ~SOLDIER_COVERT_CIV;
|
||||
|
||||
UINT16 civilianclothesitem = 0;
|
||||
if ( GetFirstItemWithFlag(&civilianclothesitem, CLOTHES_CIVILIAN) )
|
||||
{
|
||||
CreateItem( civilianclothesitem, 100, &gTempObject );
|
||||
AddItemToPool( sGridNo, &gTempObject, 1, 0, 0, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
DeductPoints( this, apcost, 0 );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
INT8 bBandaged; //,savedOurTurn;
|
||||
@@ -16455,13 +17203,13 @@ BOOLEAN HAS_SKILL_TRAIT( SOLDIERTYPE * pSoldier, UINT8 uiSkillTraitNumber )
|
||||
{
|
||||
for ( INT8 bCnt = 0; bCnt < min(30,bMaxTraits); bCnt++ )
|
||||
{
|
||||
if ( uiSkillTraitNumber > 0 && uiSkillTraitNumber <= NUM_MAJOR_TRAITS )
|
||||
if ( uiSkillTraitNumber > 0 && (uiSkillTraitNumber <= NUM_MAJOR_TRAITS || uiSkillTraitNumber == COVERT_NT) )
|
||||
{
|
||||
if (pSoldier->stats.ubSkillTraits[ bCnt ] == uiSkillTraitNumber)
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
else if ( pSoldier->stats.ubSkillTraits[ bCnt ] > 0 && pSoldier->stats.ubSkillTraits[ bCnt ] <= NUM_MAJOR_TRAITS )
|
||||
else if ( pSoldier->stats.ubSkillTraits[ bCnt ] > 0 && (pSoldier->stats.ubSkillTraits[ bCnt ] <= NUM_MAJOR_TRAITS || pSoldier->stats.ubSkillTraits[ bCnt ] == COVERT_NT) )
|
||||
{
|
||||
bNumMajorTraitsCounted++;
|
||||
}
|
||||
@@ -16511,14 +17259,14 @@ INT8 NUM_SKILL_TRAITS( SOLDIERTYPE * pSoldier, UINT8 uiSkillTraitNumber )
|
||||
{
|
||||
for ( INT8 bCnt = 0; bCnt < min(30,bMaxTraits); bCnt++ )
|
||||
{
|
||||
if ( uiSkillTraitNumber > 0 && uiSkillTraitNumber <= NUM_MAJOR_TRAITS )
|
||||
if ( uiSkillTraitNumber > 0 && (uiSkillTraitNumber <= NUM_MAJOR_TRAITS || uiSkillTraitNumber == COVERT_NT) )
|
||||
{
|
||||
if ( pSoldier->stats.ubSkillTraits[ bCnt ] == uiSkillTraitNumber )
|
||||
{
|
||||
bNumberOfTraits++;
|
||||
bNumMajorTraitsCounted++;
|
||||
}
|
||||
else if ( pSoldier->stats.ubSkillTraits[ bCnt ] > 0 && pSoldier->stats.ubSkillTraits[ bCnt ] <= NUM_MAJOR_TRAITS )
|
||||
else if ( pSoldier->stats.ubSkillTraits[ bCnt ] > 0 && (pSoldier->stats.ubSkillTraits[ bCnt ] <= NUM_MAJOR_TRAITS || pSoldier->stats.ubSkillTraits[ bCnt ] == COVERT_NT ) )
|
||||
{
|
||||
bNumMajorTraitsCounted++;
|
||||
}
|
||||
@@ -16537,7 +17285,7 @@ INT8 NUM_SKILL_TRAITS( SOLDIERTYPE * pSoldier, UINT8 uiSkillTraitNumber )
|
||||
}
|
||||
}
|
||||
// cannot have more than one same minor trait
|
||||
if( uiSkillTraitNumber > NUM_MAJOR_TRAITS )
|
||||
if( uiSkillTraitNumber > NUM_MAJOR_TRAITS && uiSkillTraitNumber != COVERT_NT)
|
||||
return ( min(1, bNumberOfTraits) );
|
||||
else
|
||||
return ( min(2, bNumberOfTraits) );
|
||||
|
||||
@@ -345,12 +345,12 @@ enum
|
||||
// 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_NO_AP 0x00000002 //2 // Soldier has no APs this turn (fix for reinforcement bug)
|
||||
/*#define WH40K_BOLTER 0x00000004 //4
|
||||
#define WH40K_FLAMER 0x00000008 //8
|
||||
#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
|
||||
|
||||
#define WH40K_POWER_ARMOR 0x00000010 //16
|
||||
#define WH40K_POWER_PACK 0x00000020 //32
|
||||
#define WH40K_JUMPPACK 0x00000040 //64
|
||||
#define SOLDIER_DAMAGED_UNIFORM 0x00000010 //16 // Soldier's uniform is damged (and thus can't be taken off of his corpse)
|
||||
#define SOLDIER_COVERT_NPC_SPECIAL 0x00000020 //32 // Special flag for NPCs wehn recruited (used for covert stuff)
|
||||
/*#define WH40K_JUMPPACK 0x00000040 //64
|
||||
#define WH40K_DISPLACER 0x00000080 //128
|
||||
|
||||
#define WH40K_ROSARIUS 0x00000100 //256
|
||||
@@ -1456,6 +1456,34 @@ public:
|
||||
|
||||
// use any cleaning kits to clean weapons in inventory
|
||||
void CleanWeapon();
|
||||
|
||||
// Flugente: functions for the covert ops trait
|
||||
|
||||
// are we in covert mode? we need to have the correct flag set, and not wear anything suspicious, or behave in a suspicious way
|
||||
|
||||
// do we look like a civilian?
|
||||
BOOLEAN LooksLikeACivilian( void );
|
||||
|
||||
// do we look like a soldier?
|
||||
BOOLEAN LooksLikeASoldier( void );
|
||||
|
||||
// is our equipment too good for a soldier?
|
||||
BOOLEAN EquipmentTooGood( BOOLEAN fCloselook );
|
||||
|
||||
// does soldier ubObserverID recognize us as his enemy?
|
||||
BOOLEAN SeemsLegit( UINT8 ubObserverID );
|
||||
|
||||
// do we recognize someone else as a combatant?
|
||||
BOOLEAN RecognizeAsCombatant(UINT8 ubTargetID);
|
||||
|
||||
// loose disguise, dress up in our natural state
|
||||
void LooseDisguise( void );
|
||||
|
||||
// dress up like a civilian
|
||||
BOOLEAN DisguiseAsCivilian( void );
|
||||
|
||||
// dress up like an enemy soldier
|
||||
BOOLEAN DisguiseAsSoldierFromCorpse( UINT32 usFlag );
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // SOLDIERTYPE;
|
||||
|
||||
@@ -1701,6 +1701,16 @@ BOOLEAN RecruitRPC( UINT8 ubCharNum )
|
||||
GiveQuestRewardPoint( pSoldier->sSectorX, pSoldier->sSectorY, 6, MIGUEL );
|
||||
}
|
||||
|
||||
// Flugente: people recruited in Arulco are known to the enemy as civilians or even soldiers. So they will be covert whn recruiting them. Of course, this is not for the rebels...
|
||||
if ( ubCharNum == DEVIN || ubCharNum == HAMOUS || ubCharNum == SLAY || ubCharNum == VINCE || ubCharNum == MADDOG || ubCharNum == MICKY )
|
||||
{
|
||||
pNewSoldier->bSoldierFlagMask |= (SOLDIER_COVERT_CIV|SOLDIER_COVERT_NPC_SPECIAL);
|
||||
}
|
||||
else if ( ubCharNum == IGGY || ubCharNum == CONRAD )
|
||||
{
|
||||
pNewSoldier->bSoldierFlagMask |= (SOLDIER_COVERT_SOLDIER|SOLDIER_COVERT_NPC_SPECIAL);
|
||||
}
|
||||
|
||||
// handle town loyalty adjustment
|
||||
HandleTownLoyaltyForNPCRecruitment( pNewSoldier );
|
||||
|
||||
@@ -2650,14 +2660,14 @@ INT8 ProfileHasSkillTrait( INT32 ubProfileID, INT8 bSkillTrait )
|
||||
{
|
||||
for ( INT8 bCnt = 0; bCnt < gSkillTraitValues.ubMaxNumberOfTraits; bCnt++ )
|
||||
{
|
||||
if ( bSkillTrait > 0 && bSkillTrait <= NUM_MAJOR_TRAITS )
|
||||
if ( bSkillTrait > 0 && (bSkillTrait <= DOCTOR_NT || bSkillTrait == COVERT_NT ) )
|
||||
{
|
||||
if ( gMercProfiles[ubProfileID].bSkillTraits[ bCnt ] == bSkillTrait )
|
||||
{
|
||||
bNumTraits++;
|
||||
bNumMajorTraitsCounted++;
|
||||
}
|
||||
else if ( gMercProfiles[ubProfileID].bSkillTraits[ bCnt ] > 0 && gMercProfiles[ubProfileID].bSkillTraits[ bCnt ] <= NUM_MAJOR_TRAITS )
|
||||
else if ( gMercProfiles[ubProfileID].bSkillTraits[ bCnt ] > 0 && (gMercProfiles[ubProfileID].bSkillTraits[ bCnt ] <= DOCTOR_NT || gMercProfiles[ubProfileID].bSkillTraits[ bCnt ] <= COVERT_NT) )
|
||||
{
|
||||
bNumMajorTraitsCounted++;
|
||||
}
|
||||
@@ -2676,7 +2686,7 @@ INT8 ProfileHasSkillTrait( INT32 ubProfileID, INT8 bSkillTrait )
|
||||
}
|
||||
}
|
||||
// cannot have more than 1 rade of minor traits or 2 grades of a major traits
|
||||
if( bSkillTrait > NUM_MAJOR_TRAITS )
|
||||
if( bSkillTrait > DOCTOR_NT && bSkillTrait != COVERT_NT )
|
||||
return ( min(1, bNumTraits) );
|
||||
else
|
||||
return ( min(2, bNumTraits) );
|
||||
|
||||
@@ -238,7 +238,7 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier )
|
||||
CHAR16 pStrAux[50];
|
||||
swprintf( pStrAux, L"(%s)", gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[0]]);
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_1], pStrInfo, pStrAux );
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[1] + 19] );
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[1] + NEWTRAIT_MERCSKILL_EXPERTOFFSET] );
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_3], pStrInfo, gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[2]] );
|
||||
//swprintf( pStrInfo, L"%s\n", pStrInfo );
|
||||
}
|
||||
@@ -247,7 +247,7 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier )
|
||||
CHAR16 pStrAux[50];
|
||||
swprintf( pStrAux, L"(%s)", gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[1]]);
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_1], pStrInfo, pStrAux );
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[2] + 19] );
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[2] + NEWTRAIT_MERCSKILL_EXPERTOFFSET] );
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_3], pStrInfo, gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[0]] );
|
||||
}
|
||||
else if (( pSoldier->stats.ubSkillTraits[0] == pSoldier->stats.ubSkillTraits[2] ) && pSoldier->stats.ubSkillTraits[0] != 0 )
|
||||
@@ -255,7 +255,7 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier )
|
||||
CHAR16 pStrAux[50];
|
||||
swprintf( pStrAux, L"(%s)", gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[0]]);
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_1], pStrInfo, pStrAux );
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[2] + 19] );
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[2] + NEWTRAIT_MERCSKILL_EXPERTOFFSET] );
|
||||
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_3], pStrInfo, gzMercSkillTextNew[pSoldier->stats.ubSkillTraits[1]] );
|
||||
}
|
||||
else
|
||||
|
||||
@@ -4449,7 +4449,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
|
||||
/*// Flugente: spawn items while debugging
|
||||
if ( gusSelectedSoldier != NOBODY )
|
||||
{
|
||||
static UINT16 usitem = 1576;
|
||||
static UINT16 usitem = 142;
|
||||
static INT16 status = 100;
|
||||
static FLOAT temperature = 0.0;
|
||||
|
||||
|
||||
+65
-5
@@ -8960,8 +8960,21 @@ 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.
|
||||
// this is intended to work on darts, but it is possible on any ammo
|
||||
if ( AmmoTypes[ubAmmoType].ammoflag & AMMO_NEUROTOXIN )
|
||||
{
|
||||
pTarget->bSoldierFlagMask |= SOLDIER_DRUGGED;
|
||||
|
||||
if ( AmmoTypes[ubAmmoType].dart && sHitBy > 20 )
|
||||
// Add lifedamage effects
|
||||
pTarget->drugs.bFutureDrugEffect[ DRUG_TYPE_LIFEDAMAGE ] = min(pTarget->drugs.bFutureDrugEffect[ DRUG_TYPE_LIFEDAMAGE ] + 3, 127);
|
||||
pTarget->drugs.bDrugEffectRate[DRUG_TYPE_LIFEDAMAGE] = 1;
|
||||
pTarget->drugs.bDrugEffect[DRUG_TYPE_LIFEDAMAGE] = 0;
|
||||
pTarget->drugs.bDrugSideEffectRate[DRUG_TYPE_LIFEDAMAGE] = 0;
|
||||
pTarget->drugs.bDrugSideEffect[DRUG_TYPE_LIFEDAMAGE] = 127;
|
||||
pTarget->drugs.bTimesDrugUsedSinceSleep[ DRUG_TYPE_LIFEDAMAGE ]++;
|
||||
}
|
||||
else if ( AmmoTypes[ubAmmoType].dart && sHitBy > 20 )
|
||||
{
|
||||
if (pubSpecial)
|
||||
{
|
||||
@@ -9434,13 +9447,13 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
|
||||
INT32 iImpact, iFluke, iBonus;
|
||||
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary (think of bayonets)
|
||||
OBJECTTYPE* pObj = pSoldier->GetUsedWeapon( &(pSoldier->inv[HANDPOS]) );
|
||||
|
||||
if (fBladeAttack)
|
||||
{
|
||||
iImpact = ( EffectiveExpLevel( pSoldier ) / 2); // 0 to 4 for level
|
||||
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary (think of bayonets)
|
||||
OBJECTTYPE* pObj = pSoldier->GetUsedWeapon( &(pSoldier->inv[HANDPOS]) );
|
||||
|
||||
|
||||
iImpact += GetDamage(pObj);
|
||||
|
||||
iImpact += EffectiveStrength( pSoldier, FALSE ) / 20; // 0 to 5 for strength, adjusted by damage taken
|
||||
@@ -9677,6 +9690,34 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
iBonus += 10; // +10%
|
||||
}
|
||||
|
||||
// Flugente: if we are using a garotte, there is a chance that we score an instakill
|
||||
// our level in covert ops and wether the target is aware of us has a huge impact
|
||||
if ( pObj && HasItemFlag(pObj->usItem, GAROTTE) )
|
||||
{
|
||||
INT32 instakillchance = 0;
|
||||
INT32 resistchance = 20;
|
||||
|
||||
if ( !SoldierTo3DLocationLineOfSightTest( pSoldier, pTarget->sGridNo, pTarget->pathing.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
|
||||
instakillchance += 30;
|
||||
|
||||
UINT8 skilllevel = NUM_SKILL_TRAITS( pSoldier, COVERT_NT );
|
||||
instakillchance += skilllevel * gSkillTraitValues.sCoMeleeInstakillBonus;
|
||||
|
||||
if ( pTarget->aiData.bAlertStatus == STATUS_YELLOW )
|
||||
resistchance += 20;
|
||||
else if ( pTarget->aiData.bAlertStatus >= STATUS_RED )
|
||||
resistchance += 50;
|
||||
|
||||
if ( pTarget->bCollapsed )
|
||||
resistchance = 0;
|
||||
|
||||
// killchance gets lowered if garotte is in bad shape
|
||||
instakillchance *= ( (*pObj)[0]->data.objectStatus / 100 );
|
||||
|
||||
if ( Random(instakillchance) >= Random(resistchance) )
|
||||
iImpact += 500;
|
||||
}
|
||||
|
||||
// apply all bonuses
|
||||
iImpact = (iImpact * (100 + iBonus) + 50) / 100; // round it properly
|
||||
|
||||
@@ -9925,6 +9966,25 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
|
||||
{
|
||||
iAttRating += gSkillTraitValues.bCtHModifierHtHAttack; // Make HtH attacks a little more problematic for untrained mercs
|
||||
|
||||
// Flugente: if we are using a garotte, alter the attack rating on wether we are used in to this weapon, and wether our target can see us
|
||||
if ( HasItemFlag(usInHand, GAROTTE) )
|
||||
{
|
||||
// using a garotte is pretty hard, we get a malus as default value
|
||||
INT32 garottemodifier = -30;
|
||||
|
||||
UINT8 skilllevel = NUM_SKILL_TRAITS( pAttacker, COVERT_NT );
|
||||
garottemodifier += skilllevel * gSkillTraitValues.sCOMeleeCTHBonus;
|
||||
|
||||
if ( pDefender->bCollapsed )
|
||||
garottemodifier += 80;
|
||||
|
||||
// if this guy can see us, get a big malus!
|
||||
else if ( SoldierTo3DLocationLineOfSightTest( pAttacker, pDefender->sGridNo, pDefender->pathing.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
|
||||
garottemodifier -= 80;
|
||||
|
||||
iAttRating += garottemodifier;
|
||||
}
|
||||
|
||||
// bare hands - bonus for Martial arts
|
||||
if (!pAttacker->usAttackingWeapon && HAS_SKILL_TRAIT( pAttacker, MARTIAL_ARTS_NT ))
|
||||
{
|
||||
|
||||
+47
-1
@@ -172,6 +172,49 @@ enum
|
||||
AMMO_FLAME,
|
||||
};
|
||||
|
||||
// -------- added by Flugente: various ammo flags --------
|
||||
// flags used for various ammo properties (easier than adding 32 differently named variables). DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
|
||||
#define AMMO_NEUROTOXIN 0x00000001 //1 // this ammo adds the cyanide drug effect to its target, killing it in a few turns
|
||||
/*#define FULL_SANDBAG 0x00000002 //2
|
||||
#define SHOVEL 0x00000004 //4
|
||||
#define CONCERTINA 0x00000008 //8
|
||||
|
||||
#define WATER_DRUM 0x00000010 //16 // water drums allow to refill canteens in the sector they are in
|
||||
#define MEAT_BLOODCAT 0x00000020 //32 // retrieve this by gutting a bloodcat
|
||||
#define COW_MEAT 0x00000040 //64 // retrieve this by gutting a cow
|
||||
#define BELT_FED 0x00000080 //128 // item can be fed externally
|
||||
|
||||
#define AMMO_BELT 0x00000100 //256 // this item can be used to feed externally
|
||||
#define AMMO_BELT_VEST 0x00000200 //512 // this is a vest that can contain AMMO_BELT items in its medium slots
|
||||
#define COVERT_OPS_KIT 0x00000400 //1024 // this kit can restore the covert ops disguise
|
||||
#define RAG 0x00000800 //2048 // this item is a rag and can be used to remove camo
|
||||
|
||||
#define ENEMY_NET_1_LVL_4 0x00001000 //4096
|
||||
#define ENEMY_NET_2_LVL_4 0x00002000 //8192
|
||||
#define ENEMY_NET_3_LVL_4 0x00004000 //16384
|
||||
#define ENEMY_NET_4_LVL_4 0x00008000 //32768
|
||||
|
||||
#define PLAYER_NET_1_LVL_1 0x00010000 //65536
|
||||
#define PLAYER_NET_2_LVL_1 0x00020000 //131072
|
||||
#define PLAYER_NET_3_LVL_1 0x00040000 //262144
|
||||
#define PLAYER_NET_4_LVL_1 0x00080000 //524288
|
||||
|
||||
#define PLAYER_NET_1_LVL_2 0x00100000 //1048576
|
||||
#define PLAYER_NET_2_LVL_2 0x00200000 //2097152
|
||||
#define PLAYER_NET_3_LVL_2 0x00400000 //4194304
|
||||
#define PLAYER_NET_4_LVL_2 0x00800000 //8388608
|
||||
|
||||
#define PLAYER_NET_1_LVL_3 0x01000000 //16777216
|
||||
#define PLAYER_NET_2_LVL_3 0x02000000 //33554432
|
||||
#define PLAYER_NET_3_LVL_3 0x04000000 //67108864
|
||||
#define PLAYER_NET_4_LVL_3 0x08000000 //134217728
|
||||
|
||||
#define PLAYER_NET_1_LVL_4 0x10000000 //268435456
|
||||
#define PLAYER_NET_2_LVL_4 0x20000000 //536870912
|
||||
#define PLAYER_NET_3_LVL_4 0x40000000 //1073741824
|
||||
#define PLAYER_NET_4_LVL_4 0x80000000 //2147483648*/
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 uiIndex;
|
||||
@@ -216,10 +259,13 @@ typedef struct
|
||||
BOOLEAN tracerEffect;
|
||||
FLOAT temperatureModificator; // Flugente: modificator for weapon temperature
|
||||
INT16 poisonPercentage; // Flugente: modificator for weapon temperature
|
||||
FLOAT dirtModificator; // Flugente: modificator for weapon temperature
|
||||
FLOAT dirtModificator; // Flugente: modificator for dirt generation
|
||||
|
||||
//zilpin: pellet spread patterns externalized in XML
|
||||
INT32 spreadPattern;
|
||||
|
||||
// Flugente: item flag for various properties. Way easier than 32 boolean flags
|
||||
UINT32 ammoflag;
|
||||
|
||||
} AMMOTYPE;
|
||||
|
||||
|
||||
+39
-33
@@ -81,7 +81,8 @@ ammotypeStartElementHandle(void *userData, const XML_Char *name, const XML_Char
|
||||
strcmp(name, "monsterSpit") == 0 ||
|
||||
strcmp(name, "temperatureModificator") == 0 ||
|
||||
strcmp(name, "PoisonPercentage") == 0 ||
|
||||
strcmp(name, "dirtModificator") == 0 ))
|
||||
strcmp(name, "dirtModificator") == 0 ||
|
||||
strcmp(name, "ammoflag") == 0 ))
|
||||
{
|
||||
pData->curElement = ELEMENT_PROPERTY;
|
||||
|
||||
@@ -298,6 +299,11 @@ ammotypeEndElementHandle(void *userData, const XML_Char *name)
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curAmmoType.dirtModificator = (FLOAT) atof(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "ammoflag") == 0)
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curAmmoType.ammoflag = (UINT32) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
@@ -390,39 +396,39 @@ BOOLEAN WriteAmmoTypeStats()
|
||||
|
||||
FilePrintf(hFile,"\t<AMMOTYPE>\r\n");
|
||||
|
||||
FilePrintf(hFile,"\t\t<uiIndex>%d</uiIndex>\r\n", cnt );
|
||||
FilePrintf(hFile,"\t\t<fontColour>%d</fontColour>\r\n", AmmoTypes[cnt].fontColour );
|
||||
FilePrintf(hFile,"\t\t<grayed>%d</grayed>\r\n", AmmoTypes[cnt].grayed );
|
||||
FilePrintf(hFile,"\t\t<offNormal>%d</offNormal>\r\n", AmmoTypes[cnt].offNormal );
|
||||
FilePrintf(hFile,"\t\t<onNormal>%d</onNormal>\r\n", AmmoTypes[cnt].onNormal );
|
||||
FilePrintf(hFile,"\t\t<structureImpactReductionMultiplier>%d</structureImpactReductionMultiplier>\r\n", AmmoTypes[cnt].structureImpactReductionMultiplier );
|
||||
FilePrintf(hFile,"\t\t<structureImpactReductionDivisor>%d</structureImpactReductionDivisor>\r\n", AmmoTypes[cnt].structureImpactReductionDivisor );
|
||||
FilePrintf(hFile,"\t\t<armourImpactReductionMultiplier>%d</armourImpactReductionMultiplier>\r\n", AmmoTypes[cnt].armourImpactReductionMultiplier );
|
||||
FilePrintf(hFile,"\t\t<armourImpactReductionDivisor>%d</armourImpactReductionDivisor>\r\n", AmmoTypes[cnt].armourImpactReductionDivisor );
|
||||
FilePrintf(hFile,"\t\t<beforeArmourDamageMultiplier>%d</beforeArmourDamageMultiplier>\r\n", AmmoTypes[cnt].beforeArmourDamageMultiplier );
|
||||
FilePrintf(hFile,"\t\t<beforeArmourDamageDivisor>%d</beforeArmourDamageDivisor>\r\n", AmmoTypes[cnt].beforeArmourDamageDivisor );
|
||||
FilePrintf(hFile,"\t\t<afterArmourDamageMultiplier>%d</afterArmourDamageMultiplier>\r\n", AmmoTypes[cnt].afterArmourDamageMultiplier );
|
||||
FilePrintf(hFile,"\t\t<afterArmourDamageDivisor>%d</afterArmourDamageDivisor>\r\n", AmmoTypes[cnt].afterArmourDamageDivisor );
|
||||
FilePrintf(hFile,"\t\t<zeroMinimumDamage>%d</zeroMinimumDamage>\r\n", AmmoTypes[cnt].zeroMinimumDamage );
|
||||
FilePrintf(hFile,"\t\t<canGoThrough>%d</canGoThrough>\r\n", AmmoTypes[cnt].canGoThrough );
|
||||
FilePrintf(hFile,"\t\t<standardIssue>%d</standardIssue>\r\n", AmmoTypes[cnt].standardIssue );
|
||||
FilePrintf(hFile,"\t\t<numberOfBullets>%d</numberOfBullets>\r\n", AmmoTypes[cnt].numberOfBullets );
|
||||
FilePrintf(hFile,"\t\t<multipleBulletDamageMultiplier>%d</multipleBulletDamageMultiplier>\r\n", AmmoTypes[cnt].multipleBulletDamageMultiplier );
|
||||
FilePrintf(hFile,"\t\t<multipleBulletDamageDivisor>%d</multipleBulletDamageDivisor>\r\n", AmmoTypes[cnt].multipleBulletDamageDivisor );
|
||||
FilePrintf(hFile,"\t\t<highExplosive>%d</highExplosive>\r\n", AmmoTypes[cnt].highExplosive );
|
||||
FilePrintf(hFile,"\t\t<explosionSize>%d</explosionSize>\r\n", AmmoTypes[cnt].explosionSize );
|
||||
FilePrintf(hFile,"\t\t<antiTank>%d</antiTank>\r\n", AmmoTypes[cnt].antiTank );
|
||||
FilePrintf(hFile,"\t\t<dart>%d</dart>\r\n", AmmoTypes[cnt].dart );
|
||||
FilePrintf(hFile,"\t\t<knife>%d</knife>\r\n", AmmoTypes[cnt].knife );
|
||||
FilePrintf(hFile,"\t\t<monsterSpit>%d</monsterSpit>\r\n", AmmoTypes[cnt].monsterSpit );
|
||||
FilePrintf(hFile,"\t\t<acidic>%d</acidic>\r\n", AmmoTypes[cnt].acidic );
|
||||
FilePrintf(hFile,"\t\t<ignoreArmour>%d</ignoreArmour>\r\n", AmmoTypes[cnt].ignoreArmour );
|
||||
FilePrintf(hFile,"\t\t<lockBustingPower>%d</lockBustingPower>\r\n", AmmoTypes[cnt].lockBustingPower );
|
||||
FilePrintf(hFile,"\t\t<tracerEffect>%d</tracerEffect>\r\n", AmmoTypes[cnt].tracerEffect );
|
||||
FilePrintf(hFile,"\t\t<temperatureModificator>%4.2f</temperatureModificator>\r\n", AmmoTypes[cnt].temperatureModificator );
|
||||
FilePrintf(hFile,"\t\t<PoisonPercentage>%d</PoisonPercentage>\r\n", AmmoTypes[cnt].poisonPercentage );
|
||||
FilePrintf(hFile,"\t\t<uiIndex>%d</uiIndex>\r\n", cnt );
|
||||
FilePrintf(hFile,"\t\t<fontColour>%d</fontColour>\r\n", AmmoTypes[cnt].fontColour );
|
||||
FilePrintf(hFile,"\t\t<grayed>%d</grayed>\r\n", AmmoTypes[cnt].grayed );
|
||||
FilePrintf(hFile,"\t\t<offNormal>%d</offNormal>\r\n", AmmoTypes[cnt].offNormal );
|
||||
FilePrintf(hFile,"\t\t<onNormal>%d</onNormal>\r\n", AmmoTypes[cnt].onNormal );
|
||||
FilePrintf(hFile,"\t\t<structureImpactReductionMultiplier>%d</structureImpactReductionMultiplier>\r\n", AmmoTypes[cnt].structureImpactReductionMultiplier );
|
||||
FilePrintf(hFile,"\t\t<structureImpactReductionDivisor>%d</structureImpactReductionDivisor>\r\n", AmmoTypes[cnt].structureImpactReductionDivisor );
|
||||
FilePrintf(hFile,"\t\t<armourImpactReductionMultiplier>%d</armourImpactReductionMultiplier>\r\n", AmmoTypes[cnt].armourImpactReductionMultiplier );
|
||||
FilePrintf(hFile,"\t\t<armourImpactReductionDivisor>%d</armourImpactReductionDivisor>\r\n", AmmoTypes[cnt].armourImpactReductionDivisor );
|
||||
FilePrintf(hFile,"\t\t<beforeArmourDamageMultiplier>%d</beforeArmourDamageMultiplier>\r\n", AmmoTypes[cnt].beforeArmourDamageMultiplier );
|
||||
FilePrintf(hFile,"\t\t<beforeArmourDamageDivisor>%d</beforeArmourDamageDivisor>\r\n", AmmoTypes[cnt].beforeArmourDamageDivisor );
|
||||
FilePrintf(hFile,"\t\t<afterArmourDamageMultiplier>%d</afterArmourDamageMultiplier>\r\n", AmmoTypes[cnt].afterArmourDamageMultiplier );
|
||||
FilePrintf(hFile,"\t\t<afterArmourDamageDivisor>%d</afterArmourDamageDivisor>\r\n", AmmoTypes[cnt].afterArmourDamageDivisor );
|
||||
FilePrintf(hFile,"\t\t<zeroMinimumDamage>%d</zeroMinimumDamage>\r\n", AmmoTypes[cnt].zeroMinimumDamage );
|
||||
FilePrintf(hFile,"\t\t<canGoThrough>%d</canGoThrough>\r\n", AmmoTypes[cnt].canGoThrough );
|
||||
FilePrintf(hFile,"\t\t<standardIssue>%d</standardIssue>\r\n", AmmoTypes[cnt].standardIssue );
|
||||
FilePrintf(hFile,"\t\t<numberOfBullets>%d</numberOfBullets>\r\n", AmmoTypes[cnt].numberOfBullets );
|
||||
FilePrintf(hFile,"\t\t<multipleBulletDamageMultiplier>%d</multipleBulletDamageMultiplier>\r\n", AmmoTypes[cnt].multipleBulletDamageMultiplier );
|
||||
FilePrintf(hFile,"\t\t<multipleBulletDamageDivisor>%d</multipleBulletDamageDivisor>\r\n", AmmoTypes[cnt].multipleBulletDamageDivisor );
|
||||
FilePrintf(hFile,"\t\t<highExplosive>%d</highExplosive>\r\n", AmmoTypes[cnt].highExplosive );
|
||||
FilePrintf(hFile,"\t\t<explosionSize>%d</explosionSize>\r\n", AmmoTypes[cnt].explosionSize );
|
||||
FilePrintf(hFile,"\t\t<antiTank>%d</antiTank>\r\n", AmmoTypes[cnt].antiTank );
|
||||
FilePrintf(hFile,"\t\t<dart>%d</dart>\r\n", AmmoTypes[cnt].dart );
|
||||
FilePrintf(hFile,"\t\t<knife>%d</knife>\r\n", AmmoTypes[cnt].knife );
|
||||
FilePrintf(hFile,"\t\t<monsterSpit>%d</monsterSpit>\r\n", AmmoTypes[cnt].monsterSpit );
|
||||
FilePrintf(hFile,"\t\t<acidic>%d</acidic>\r\n", AmmoTypes[cnt].acidic );
|
||||
FilePrintf(hFile,"\t\t<ignoreArmour>%d</ignoreArmour>\r\n", AmmoTypes[cnt].ignoreArmour );
|
||||
FilePrintf(hFile,"\t\t<lockBustingPower>%d</lockBustingPower>\r\n", AmmoTypes[cnt].lockBustingPower );
|
||||
FilePrintf(hFile,"\t\t<tracerEffect>%d</tracerEffect>\r\n", AmmoTypes[cnt].tracerEffect );
|
||||
FilePrintf(hFile,"\t\t<temperatureModificator>%4.2f</temperatureModificator>\r\n", AmmoTypes[cnt].temperatureModificator );
|
||||
FilePrintf(hFile,"\t\t<PoisonPercentage>%d</PoisonPercentage>\r\n", AmmoTypes[cnt].poisonPercentage );
|
||||
FilePrintf(hFile,"\t\t<dirtModificator>%4.2f</dirtModificator>\r\n", AmmoTypes[cnt].dirtModificator );
|
||||
|
||||
FilePrintf(hFile,"\t\t<ammoflag>%d</ammoflag>\r\n", AmmoTypes[cnt].ammoflag );
|
||||
|
||||
FilePrintf(hFile,"\t</AMMOTYPE>\r\n");
|
||||
}
|
||||
|
||||
+47
-33
@@ -446,7 +446,7 @@ void ReevaluateBestSightingPosition( SOLDIERTYPE * pSoldier, INT8 bInterruptDuel
|
||||
{
|
||||
for ( ubLoop = 0; ubLoop < gubBestToMakeSightingSize; ubLoop++ )
|
||||
{
|
||||
if ( (gubBestToMakeSighting[ ubLoop ] == NOBODY) || (bInterruptDuelPts > MercPtrs[ gubBestToMakeSighting[ ubLoop ] ]->aiData.bInterruptDuelPts ) )
|
||||
if ( pSoldier->RecognizeAsCombatant(gubBestToMakeSighting[ ubLoop ]) && (gubBestToMakeSighting[ ubLoop ] == NOBODY) || (bInterruptDuelPts > MercPtrs[ gubBestToMakeSighting[ ubLoop ] ]->aiData.bInterruptDuelPts ) )
|
||||
{
|
||||
if ( gubBestToMakeSighting[ gubBestToMakeSightingSize - 1 ] != NOBODY )
|
||||
{
|
||||
@@ -509,36 +509,43 @@ void HandleBestSightingPositionInRealtime( void )
|
||||
if (gubBestToMakeSighting[ 1 ] == NOBODY)
|
||||
{ // The_Bob - real time sneaking code 01/06/09
|
||||
// if real time sneaking conditions are met...
|
||||
// this is now in the preferences window - SANDRO
|
||||
// this is now in the preferences window - SANDRO
|
||||
if (gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK] && MercPtrs[gubBestToMakeSighting[ 0 ]]->bTeam == OUR_TEAM && NobodyAlerted() )
|
||||
{
|
||||
// get rid of the item under cursor (we gotta react FAST)
|
||||
CancelItemPointer();
|
||||
// select (and center screen on) the merc who saw the enemy
|
||||
// HEADROCK HAM 3.6: A much-requested toggle.
|
||||
if (gusSelectedSoldier != (UINT16)MercPtrs[gubBestToMakeSighting[ 0 ]]->ubID &&
|
||||
!gGameExternalOptions.fNoAutoFocusChangeInRealtimeSneak)
|
||||
SelectSoldier (MercPtrs[gubBestToMakeSighting[ 0 ]]->ubID, false, true);
|
||||
// if not quiet, emit a message warning the player
|
||||
if (!gGameExternalOptions.fQuietRealTimeSneak)
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_RTM_ENEMIES_SPOOTED]);
|
||||
{
|
||||
// get rid of the item under cursor (we gotta react FAST)
|
||||
CancelItemPointer();
|
||||
// select (and center screen on) the merc who saw the enemy
|
||||
// HEADROCK HAM 3.6: A much-requested toggle.
|
||||
if (gusSelectedSoldier != (UINT16)MercPtrs[gubBestToMakeSighting[ 0 ]]->ubID &&
|
||||
!gGameExternalOptions.fNoAutoFocusChangeInRealtimeSneak)
|
||||
SelectSoldier (MercPtrs[gubBestToMakeSighting[ 0 ]]->ubID, false, true);
|
||||
// if not quiet, emit a message warning the player
|
||||
if (!gGameExternalOptions.fQuietRealTimeSneak)
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_RTM_ENEMIES_SPOOTED]);
|
||||
|
||||
return; // and do nothing
|
||||
}
|
||||
return; // and do nothing
|
||||
}
|
||||
else if ( MercPtrs[gubBestToMakeSighting[ 0 ]]->bTeam != OUR_TEAM && MercPtrs[gubBestToMakeSighting[ 0 ]]->aiData.bOppCnt > 0 )
|
||||
{
|
||||
// otherwise, simply award the turn to the team that saw the enemy first
|
||||
EnterCombatMode( MercPtrs[gubBestToMakeSighting[ 0 ]]->bTeam );
|
||||
}
|
||||
else
|
||||
// otherwise, simply award the turn to the team that saw the enemy first
|
||||
EnterCombatMode( MercPtrs[gubBestToMakeSighting[ 0 ]]->bTeam );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
// if 1st and 2nd on same team, or 1st and 3rd on same team, or there IS no 3rd, award turn to 1st
|
||||
if ( ( MercPtrs[gubBestToMakeSighting[ 0 ]]->bTeam == MercPtrs[gubBestToMakeSighting[ 1 ]]->bTeam ) ||
|
||||
if ( /*MercPtrs[gubBestToMakeSighting[ 0 ]]->aiData.bOppCnt > 0 &&*/ ( MercPtrs[gubBestToMakeSighting[ 0 ]]->bTeam == MercPtrs[gubBestToMakeSighting[ 1 ]]->bTeam ) ||
|
||||
( (gubBestToMakeSighting[ 2 ] == NOBODY) || ( MercPtrs[gubBestToMakeSighting[ 0 ]]->bTeam == MercPtrs[gubBestToMakeSighting[ 2 ]]->bTeam ) )
|
||||
)
|
||||
{
|
||||
EnterCombatMode( MercPtrs[gubBestToMakeSighting[ 0 ]]->bTeam );
|
||||
}
|
||||
else // give turn to 2nd best but interrupt to 1st
|
||||
else //if ( MercPtrs[gubBestToMakeSighting[ 1 ]]->aiData.bOppCnt > 0 ) // give turn to 2nd best but interrupt to 1st
|
||||
{
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Entering combat mode: turn for 2nd best, int for best" );
|
||||
|
||||
@@ -1766,7 +1773,7 @@ void HandleManNoLongerSeen( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOpponent, INT
|
||||
{
|
||||
// if neither side is neutral AND
|
||||
// if this soldier is an opponent (fights for different side)
|
||||
if (pSoldier->bActive && pOpponent->bActive && !CONSIDERED_NEUTRAL( pOpponent, pSoldier ) && !CONSIDERED_NEUTRAL( pSoldier, pOpponent ) && (pSoldier->bSide != pOpponent->bSide))
|
||||
if (pSoldier->bActive && pOpponent->bActive && !CONSIDERED_NEUTRAL( pOpponent, pSoldier ) && !CONSIDERED_NEUTRAL( pSoldier, pOpponent ) && (pSoldier->bSide != pOpponent->bSide) && pSoldier->RecognizeAsCombatant(pOpponent->ubID) )
|
||||
{
|
||||
RemoveOneOpponent(pSoldier);
|
||||
}
|
||||
@@ -2199,6 +2206,9 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
|
||||
return;
|
||||
}
|
||||
|
||||
// Flugente: update our sight concerning this guy, otherwise we could get way with open attacks because this does not get updated
|
||||
pSoldier->RecognizeAsCombatant(pOpponent->ubID);
|
||||
|
||||
// if we're seeing a guy we didn't see on our last chance to look for him
|
||||
if (pSoldier->aiData.bOppList[pOpponent->ubID] != SEEN_CURRENTLY)
|
||||
{
|
||||
@@ -2503,7 +2513,7 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
|
||||
|
||||
// if both of us are not neutral, AND
|
||||
// if this man is actually a true opponent (we're not on the same side)
|
||||
if (!CONSIDERED_NEUTRAL( pOpponent, pSoldier ) && !CONSIDERED_NEUTRAL( pSoldier, pOpponent ) && (pSoldier->bSide != pOpponent->bSide))
|
||||
if (!CONSIDERED_NEUTRAL( pOpponent, pSoldier ) && !CONSIDERED_NEUTRAL( pSoldier, pOpponent ) && (pSoldier->bSide != pOpponent->bSide) && pSoldier->RecognizeAsCombatant(pOpponent->ubID) )
|
||||
{
|
||||
AddOneOpponent(pSoldier);
|
||||
|
||||
@@ -3002,7 +3012,7 @@ IAN COMMENTED THIS OUT MAY 1997 - DO WE NEED THIS?
|
||||
if (pOpponent)
|
||||
{
|
||||
// check to see if OPPONENT considers US neutral
|
||||
if ( (pOpponent->aiData.bOppList[ubTarget] == SEEN_CURRENTLY) && !pOpponent->aiData.bNeutral && !CONSIDERED_NEUTRAL( pOpponent, pSoldier ) && (pSoldier->bSide != pOpponent->bSide) )
|
||||
if ( (pOpponent->aiData.bOppList[ubTarget] == SEEN_CURRENTLY) && !pOpponent->aiData.bNeutral && !CONSIDERED_NEUTRAL( pOpponent, pSoldier ) && (pSoldier->bSide != pOpponent->bSide) && pOpponent->RecognizeAsCombatant(pSoldier->ubID) )
|
||||
{
|
||||
RemoveOneOpponent(pOpponent);
|
||||
}
|
||||
@@ -3501,20 +3511,24 @@ void SaySeenQuote( SOLDIERTYPE *pSoldier, BOOLEAN fSeenCreature, BOOLEAN fVirgin
|
||||
}
|
||||
else
|
||||
{
|
||||
// Flugente: no quotes on seeing enemy when covert
|
||||
if ( (pSoldier->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER) ) == 0 )
|
||||
{
|
||||
#ifdef ENGLISH
|
||||
if ( Random( 100 ) < 30 )
|
||||
{
|
||||
pSoldier->DoMercBattleSound( BATTLE_SOUND_ENEMY );
|
||||
}
|
||||
else
|
||||
{
|
||||
TacticalCharacterDialogue( pSoldier, QUOTE_SEE_ENEMY );
|
||||
}
|
||||
if ( Random( 100 ) < 30 )
|
||||
{
|
||||
pSoldier->DoMercBattleSound( BATTLE_SOUND_ENEMY );
|
||||
}
|
||||
else
|
||||
{
|
||||
TacticalCharacterDialogue( pSoldier, QUOTE_SEE_ENEMY );
|
||||
}
|
||||
#else
|
||||
//ddd TacticalCharacterDialogue( pSoldier, QUOTE_SEE_ENEMY );
|
||||
if(Chance(gGameExternalOptions.iChanceSayAnnoyingPhrase) )
|
||||
TacticalCharacterDialogue( pSoldier, QUOTE_SEE_ENEMY );
|
||||
//ddd TacticalCharacterDialogue( pSoldier, QUOTE_SEE_ENEMY );
|
||||
if(Chance(gGameExternalOptions.iChanceSayAnnoyingPhrase) )
|
||||
TacticalCharacterDialogue( pSoldier, QUOTE_SEE_ENEMY );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6821,7 +6835,7 @@ void DecayIndividualOpplist(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
// they are NOT visible now!
|
||||
(*pPersOL)++;
|
||||
if (!CONSIDERED_NEUTRAL( pOpponent, pSoldier ) && !CONSIDERED_NEUTRAL( pSoldier, pOpponent ) && (pSoldier->bSide != pOpponent->bSide))
|
||||
if (!CONSIDERED_NEUTRAL( pOpponent, pSoldier ) && !CONSIDERED_NEUTRAL( pSoldier, pOpponent ) && (pSoldier->bSide != pOpponent->bSide) && pSoldier->RecognizeAsCombatant(pOpponent->ubID) )
|
||||
{
|
||||
RemoveOneOpponent(pSoldier);
|
||||
}
|
||||
@@ -7084,7 +7098,7 @@ void RecalculateOppCntsDueToBecomingNeutral( SOLDIERTYPE * pSoldier )
|
||||
pOpponent = MercSlots[uiLoop];
|
||||
|
||||
// for every active, living soldier on ANOTHER team
|
||||
if (pOpponent && pOpponent->stats.bLife && !pOpponent->aiData.bNeutral && (pOpponent->bTeam != pSoldier->bTeam) && !CONSIDERED_NEUTRAL( pSoldier, pOpponent ) && (pSoldier->bSide != pOpponent->bSide) )
|
||||
if (pOpponent && pOpponent->stats.bLife && !pOpponent->aiData.bNeutral && (pOpponent->bTeam != pSoldier->bTeam) && !CONSIDERED_NEUTRAL( pSoldier, pOpponent ) && (pSoldier->bSide != pOpponent->bSide) && pSoldier->RecognizeAsCombatant(pOpponent->ubID) )
|
||||
{
|
||||
if ( pOpponent->aiData.bOppList[pSoldier->ubID] == SEEN_CURRENTLY )
|
||||
{
|
||||
|
||||
@@ -157,12 +157,21 @@ typedef enum
|
||||
DEMOLITIONS_NT, // 17
|
||||
TEACHING_NT, // 18
|
||||
SCOUTING_NT, // 19
|
||||
|
||||
// Flugente: new traits have to go here, even if they are major traits, as otherwise the existing traits in profiles get mixed up
|
||||
COVERT_NT, // 20
|
||||
|
||||
NUM_SKILLTRAITS_NT
|
||||
} SkillTraitNew;
|
||||
|
||||
#define NUM_MAJOR_TRAITS 9
|
||||
#define NUM_MAJOR_TRAITS 10
|
||||
#define NUM_MINOR_TRAITS 10
|
||||
|
||||
// Flugente: I've had it with this hardcoding madness. Without this, adding or removing a new trait would crash anything related to a bubblehelp display of traits
|
||||
// always check every use of these enums and every use of the skill-strings if you add a new trait
|
||||
#define NEWTRAIT_MERCSKILL_EXPERTOFFSET NUM_MAJOR_TRAITS + NUM_MINOR_TRAITS
|
||||
#define NEWTRAIT_MERCSKILL_OFFSET_ALL NEWTRAIT_MERCSKILL_EXPERTOFFSET + NUM_MAJOR_TRAITS
|
||||
|
||||
// SANDRO - new set of character traits
|
||||
typedef enum
|
||||
{
|
||||
|
||||
@@ -189,6 +189,15 @@ INT32 MostImportantNoiseHeard( SOLDIERTYPE *pSoldier, INT32 *piRetValue, BOOLEAN
|
||||
if ( CONSIDERED_NEUTRAL( pSoldier, pTemp ) || (pSoldier->bSide == pTemp->bSide))
|
||||
continue; // next merc
|
||||
|
||||
// Flugente: chance to ignore the noise if the ceator is covert
|
||||
if ( pTemp->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER) )
|
||||
{
|
||||
// green AI state: always ignore
|
||||
// yellow AI state: 50% chance to ignore
|
||||
if ( pSoldier->aiData.bAlertStatus == STATUS_GREEN || (pSoldier->aiData.bAlertStatus == STATUS_GREEN && Random(2) < 1 ) )
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
pbPersOL = pSoldier->aiData.bOppList + pTemp->ubID;
|
||||
pbPublOL = gbPublicOpplist[pSoldier->bTeam] + pTemp->ubID;
|
||||
psLastLoc = gsLastKnownOppLoc[pSoldier->ubID] + pTemp->ubID;
|
||||
|
||||
+4
-2
@@ -640,8 +640,8 @@ extern STR16 szUDBGenAmmoStatsTooltipText[ 6 ]; // Flugente Overheating: 3
|
||||
extern STR16 szUDBGenAmmoStatsExplanationsTooltipText[ 6 ]; // Flugente Overheating: 3->4 poison: 4->5 dirt: 5->6
|
||||
extern STR16 szUDBGenExplosiveStatsTooltipText[ 22 ];
|
||||
extern STR16 szUDBGenExplosiveStatsExplanationsTooltipText[ 22 ];
|
||||
extern STR16 szUDBGenSecondaryStatsTooltipText[ 31 ]; // Flugente Food System: 26 -> 28 external feeding: 28->30 JMich_SkillsModifiers: 31 for Defusal kit
|
||||
extern STR16 szUDBGenSecondaryStatsExplanationsTooltipText[ 31 ]; // Flugente Food System: 26 -> 28 external feeding: 28->30 JMich_SkillsModifiers: 31 for Defusal kit
|
||||
extern STR16 szUDBGenSecondaryStatsTooltipText[ 32 ]; // Flugente Food System: 26 -> 28 external feeding: 28->30 JMich_SkillsModifiers: 31 for Defusal kit - covert item: 31->32
|
||||
extern STR16 szUDBGenSecondaryStatsExplanationsTooltipText[ 32 ]; // Flugente Food System: 26 -> 28 external feeding: 28->30 JMich_SkillsModifiers: 31 for Defusal kit - covert item: 31->32
|
||||
extern STR16 szUDBAdvStatsTooltipText[ 58 ]; // Flugente Overheating Weapons: 48->56 poison: 56->57 dirt: 57->58
|
||||
extern STR16 szUDBAdvStatsExplanationsTooltipText[ 58 ]; // Flugente Overheating Weapons: 48->56 poison: 56->57 dirt: 57->58
|
||||
extern STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[ 52 ]; // Flugente Overheating Weapons: 48->52
|
||||
@@ -819,6 +819,8 @@ enum
|
||||
MERC_VITAL_STATS_WITH_POISON_AND_FOOD_POPUPTEXT,
|
||||
|
||||
FUNCTION_SELECTION_STR,
|
||||
|
||||
CORPSE_SELECTION_STR,
|
||||
|
||||
TEXT_NUM_TACTICAL_STR
|
||||
};
|
||||
|
||||
@@ -7084,6 +7084,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
|
||||
L"|A|m|m|o |B|e|l|t",
|
||||
L"|A|m|m|o |V|e|s|t",
|
||||
L"|D|e|f|u|s|a|l |K|i|t", // TODO.Translate
|
||||
L"|C|o|v|e|r|t |I|t|e|m",
|
||||
};
|
||||
|
||||
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
@@ -7119,6 +7120,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
L"\n \nWith this ammo belt you can\nfeed someone else's MG.",
|
||||
L"\n \nYou can feed an MG with ammo\nbelts stored in this vest.",
|
||||
L"\n \nThis item improves your trap disarm chance by ", // TODO.Translate
|
||||
L"\n \nThis item and everything attached/inside\nit is hidden from curious eyes.",
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsTooltipText[]=
|
||||
|
||||
@@ -7075,6 +7075,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
|
||||
L"|A|m|m|o |B|e|l|t",
|
||||
L"|A|m|m|o |V|e|s|t",
|
||||
L"|D|e|f|u|s|a|l |K|i|t", // TODO.Translate
|
||||
L"|C|o|v|e|r|t |I|t|e|m",
|
||||
};
|
||||
|
||||
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
@@ -7110,6 +7111,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
L"\n \nWith this ammo belt you can\nfeed someone else's MG.",
|
||||
L"\n \nYou can feed an MG with ammo\nbelts stored in this vest.",
|
||||
L"\n \nThis item improves your trap disarm chance by ", // TODO.Translate
|
||||
L"\n \nThis item and everything attached/inside\nit is hidden from curious eyes.",
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsTooltipText[]=
|
||||
|
||||
+15
-6
@@ -2104,37 +2104,39 @@ STR16 gzMercSkillText[] =
|
||||
STR16 gzMercSkillTextNew[] =
|
||||
{
|
||||
// Major traits
|
||||
L"No Skill",
|
||||
L"No Skill", // 0
|
||||
L"Auto Weapons",
|
||||
L"Heavy Weapons",
|
||||
L"Marksman",
|
||||
L"Hunter",
|
||||
L"Gunslinger",
|
||||
L"Gunslinger", // 5
|
||||
L"Hand to Hand",
|
||||
L"Deputy",
|
||||
L"Technician",
|
||||
L"Paramedic",
|
||||
L"Covert Ops", // 10
|
||||
// Minor traits
|
||||
L"Ambidextrous",
|
||||
L"Melee",
|
||||
L"Throwing",
|
||||
L"Night Ops",
|
||||
L"Stealthy",
|
||||
L"Stealthy", // 15
|
||||
L"Athletics",
|
||||
L"Bodybuilding",
|
||||
L"Demolitions",
|
||||
L"Teaching",
|
||||
L"Scouting",
|
||||
L"Scouting", // 20
|
||||
// second names for major skills
|
||||
L"Machinegunner",
|
||||
L"Bombardier",
|
||||
L"Sniper",
|
||||
L"Ranger",
|
||||
L"Gunfighter",
|
||||
L"Gunfighter", // 25
|
||||
L"Martial Arts",
|
||||
L"Squadleader",
|
||||
L"Engineer",
|
||||
L"Doctor",
|
||||
L"Spy", // 30
|
||||
L"More...",
|
||||
};
|
||||
//////////////////////////////////////////////////////////
|
||||
@@ -2936,6 +2938,9 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
|
||||
// added by Flugente: selection of a function to call in tactical
|
||||
L"1 - Fill Canteens 2 - Clean Weapons 3,4 - Nothing",
|
||||
|
||||
// added by Flugente: decide what to do with the corpses
|
||||
L"1 - Decapitate 2 - Gut 3 - Take Clothes 4 - Take Body",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
@@ -6300,7 +6305,9 @@ STR16 MissingIMPSkillsDescriptions[] =
|
||||
// Demolitions
|
||||
L"Demolitions: Sowing grenades like seeds, planting bombs, watching the limbs flying.. This is what you live for! ± ",
|
||||
// Scouting
|
||||
L"Scouting: Nothing can escape your notice! ± ",
|
||||
L"Scouting: Nothing can escape your notice! ± ",
|
||||
// Covert ops
|
||||
L"Covert Operations: You make 007 look like an amateur! ± ",
|
||||
};
|
||||
|
||||
STR16 NewInvMessage[] =
|
||||
@@ -7067,6 +7074,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
|
||||
L"|A|m|m|o |B|e|l|t",
|
||||
L"|A|m|m|o |V|e|s|t",
|
||||
L"|D|e|f|u|s|a|l |K|i|t",
|
||||
L"|C|o|v|e|r|t |I|t|e|m",
|
||||
};
|
||||
|
||||
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
@@ -7102,6 +7110,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
L"\n \nWith this ammo belt you can\nfeed someone else's MG.",
|
||||
L"\n \nYou can feed an MG with ammo\nbelts stored in this vest.",
|
||||
L"\n \nThis item improves your trap disarm chance by ",
|
||||
L"\n \nThis item and everything attached/inside\nit is hidden from curious eyes.",
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsTooltipText[]=
|
||||
|
||||
@@ -7050,6 +7050,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
|
||||
L"|A|m|m|o |B|e|l|t",
|
||||
L"|A|m|m|o |V|e|s|t",
|
||||
L"|D|e|f|u|s|a|l |K|i|t", // TODO.Translate
|
||||
L"|C|o|v|e|r|t |I|t|e|m",
|
||||
};
|
||||
|
||||
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
@@ -7085,6 +7086,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
L"\n \nWith this ammo belt you can\nfeed someone else's MG.",
|
||||
L"\n \nYou can feed an MG with ammo\nbelts stored in this vest.",
|
||||
L"\n \nThis item improves your trap disarm chance by ", // TODO.Translate
|
||||
L"\n \nThis item and everything attached/inside\nit is hidden from curious eyes.",
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsTooltipText[]=
|
||||
|
||||
@@ -6894,6 +6894,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
|
||||
L"|M|u|n|i|t|i|o|n|s|g|u|r|t",
|
||||
L"|M|u|n|i|t|i|o|n|s|w|e|s|t|e",
|
||||
L"|D|e|f|u|s|a|l |K|i|t", // TODO.Translate
|
||||
L"|C|o|v|e|r|t |I|t|e|m",
|
||||
};
|
||||
|
||||
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
@@ -6929,6 +6930,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
L"\n \nEin externer Munitionsgurt für MGs.",
|
||||
L"\n \nIn diese Weste passen auch Munitionsgurte.",
|
||||
L"\n \nThis item improves your trap disarm chance by ", // TODO.Translate
|
||||
L"\n \nThis item and everything attached/inside\nit is hidden from curious eyes.",
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsTooltipText[]=
|
||||
|
||||
@@ -7062,6 +7062,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
|
||||
L"|A|m|m|o |B|e|l|t",
|
||||
L"|A|m|m|o |V|e|s|t",
|
||||
L"|D|e|f|u|s|a|l |K|i|t", // TODO.Translate
|
||||
L"|C|o|v|e|r|t |I|t|e|m",
|
||||
};
|
||||
|
||||
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
@@ -7097,6 +7098,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
L"\n \nWith this ammo belt you can\nfeed someone else's MG.",
|
||||
L"\n \nYou can feed an MG with ammo\nbelts stored in this vest.",
|
||||
L"\n \nThis item improves your trap disarm chance by ", // TODO.Translate
|
||||
L"\n \nThis item and everything attached/inside\nit is hidden from curious eyes.",
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsTooltipText[]=
|
||||
|
||||
@@ -58,6 +58,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"班副",// L"Deputy",
|
||||
L"技师",// L"Technician",
|
||||
L"救护员",// L"Paramedic",
|
||||
L"Covert Ops", // TODO.Translate
|
||||
|
||||
L"无",// L"None",
|
||||
L"I.M.P 主要特殊技能",// L"I.M.P. Major Traits",
|
||||
@@ -71,6 +72,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"班长",// L"Squadleader",
|
||||
L"工兵",// L"Engineer",
|
||||
L"军医",// L"Doctor",
|
||||
L"Spy", // TODO.Translate
|
||||
};
|
||||
|
||||
//added another set of skill texts for new minor traits
|
||||
@@ -241,6 +243,16 @@ STR16 gzIMPMajorTraitsHelpTextsDoctor[]=
|
||||
L"(这种效果最多叠加 %d 次)",// L" (max %d these bonuses per sector)",
|
||||
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsCovertOps[]= // TODO.Translate
|
||||
{
|
||||
L"Can disguise as a civilian or soldier to slip behind enemy lines.\n",
|
||||
L"Will be detected if performing suspicious actions, having\nsuspicious gear or being near fresh corpses.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to the enemy.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to a fresh corpse.\n",
|
||||
L"+%d%s CTH with covert melee weapons\n",
|
||||
L"+%d%s chance of instakill with covert melee weapons\n",
|
||||
L"Disguise AP cost lowered by %d%s.\n",
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsNone[]=
|
||||
{
|
||||
L"无奖励",// L"No bonuses",
|
||||
|
||||
@@ -58,6 +58,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Deputy",
|
||||
L"Technician",
|
||||
L"Paramedic",
|
||||
L"Covert Ops", // TODO.Translate
|
||||
|
||||
L"None",
|
||||
L"I.M.P. Major Traits",
|
||||
@@ -71,6 +72,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Squadleader",
|
||||
L"Engineer",
|
||||
L"Doctor",
|
||||
L"Spy", // TODO.Translate
|
||||
};
|
||||
|
||||
//added another set of skill texts for new minor traits
|
||||
@@ -240,6 +242,16 @@ STR16 gzIMPMajorTraitsHelpTextsDoctor[]=
|
||||
L" (max %d these bonuses per sector)",
|
||||
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsCovertOps[]= // TODO.Translate
|
||||
{
|
||||
L"Can disguise as a civilian or soldier to slip behind enemy lines.\n",
|
||||
L"Will be detected if performing suspicious actions, having\nsuspicious gear or being near fresh corpses.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to the enemy.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to a fresh corpse.\n",
|
||||
L"+%d%s CTH with covert melee weapons\n",
|
||||
L"+%d%s chance of instakill with covert melee weapons\n",
|
||||
L"Disguise AP cost lowered by %d%s.\n",
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsNone[]=
|
||||
{
|
||||
L"No bonuses",
|
||||
|
||||
@@ -17,6 +17,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsMartialArts[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
|
||||
|
||||
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
|
||||
|
||||
@@ -58,6 +58,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Deputy",
|
||||
L"Technician",
|
||||
L"Paramedic",
|
||||
L"Covert Ops",
|
||||
|
||||
L"None",
|
||||
L"I.M.P. Major Traits",
|
||||
@@ -71,6 +72,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Squadleader",
|
||||
L"Engineer",
|
||||
L"Doctor",
|
||||
L"Spy",
|
||||
};
|
||||
|
||||
//added another set of skill texts for new minor traits
|
||||
@@ -238,7 +240,16 @@ STR16 gzIMPMajorTraitsHelpTextsDoctor[]=
|
||||
L"+%d%s bandaging speed\n",
|
||||
L"+%d%s natural regeneration speed for all soldiers in the same sector", // MINTY - Changed "of" to "for"
|
||||
L" (max %d of these bonuses per sector stack)",
|
||||
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsCovertOps[]=
|
||||
{
|
||||
L"Can disguise as a civilian or soldier to slip behind enemy lines.\n",
|
||||
L"Will be detected if performing suspicious actions, having\nsuspicious gear or being near fresh corpses.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to the enemy.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to a fresh corpse.\n",
|
||||
L"+%d%s CTH with covert melee weapons\n",
|
||||
L"+%d%s chance of instakill with covert melee weapons\n",
|
||||
L"Disguise AP cost lowered by %d%s.\n",
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsNone[]=
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsMartialArts[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
|
||||
|
||||
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
|
||||
|
||||
@@ -58,6 +58,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Manager",
|
||||
L"Technicien",
|
||||
L"Médecin",
|
||||
L"Covert Ops", // TODO.Translate
|
||||
|
||||
L"Personne",
|
||||
L"I.M.P. Traits pincipaux",
|
||||
@@ -71,6 +72,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Commandant",
|
||||
L"Ingénieur",
|
||||
L"Chirurgien",
|
||||
L"Spy", // TODO.Translate
|
||||
};
|
||||
|
||||
//added another set of skill texts for new minor traits
|
||||
@@ -241,6 +243,16 @@ STR16 gzIMPMajorTraitsHelpTextsDoctor[]=
|
||||
L" (un maximum de %d bonus par secteur)",
|
||||
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsCovertOps[]= // TODO.Translate
|
||||
{
|
||||
L"Can disguise as a civilian or soldier to slip behind enemy lines.\n",
|
||||
L"Will be detected if performing suspicious actions, having\nsuspicious gear or being near fresh corpses.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to the enemy.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to a fresh corpse.\n",
|
||||
L"+%d%s CTH with covert melee weapons\n",
|
||||
L"+%d%s chance of instakill with covert melee weapons\n",
|
||||
L"Disguise AP cost lowered by %d%s.\n",
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsNone[]=
|
||||
{
|
||||
L"Pas de bonus",
|
||||
|
||||
@@ -17,6 +17,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsMartialArts[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
|
||||
|
||||
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
|
||||
|
||||
@@ -54,6 +54,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Gruppenführer", //GrpFhr und ZgFhr sind scheiße, aber mir fällt ohne Dienstgrade nüscht ein
|
||||
L"Mechaniker", //Option: Techniker
|
||||
L"Sanitäter", //Option: Rettungsassistent
|
||||
L"Covert Ops", // TODO.Translate
|
||||
|
||||
L"Nichts",
|
||||
L"B.S.E. Hauptfertigkeiten",
|
||||
@@ -68,6 +69,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Zugführer",
|
||||
L"Ingenieur",
|
||||
L"Arzt",
|
||||
L"Spy", // TODO.Translate
|
||||
};
|
||||
|
||||
//added another set of skill texts for new minor traits
|
||||
@@ -239,6 +241,16 @@ STR16 gzIMPMajorTraitsHelpTextsDoctor[]=
|
||||
L" (maximal %d Instanzen dieses Bonus pro Sektor)",
|
||||
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsCovertOps[]= // TODO.Translate
|
||||
{
|
||||
L"Can disguise as a civilian or soldier to slip behind enemy lines.\n",
|
||||
L"Will be detected if performing suspicious actions, having\nsuspicious gear or being near fresh corpses.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to the enemy.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to a fresh corpse.\n",
|
||||
L"+%d%s CTH with covert melee weapons\n",
|
||||
L"+%d%s chance of instakill with covert melee weapons\n",
|
||||
L"Disguise AP cost lowered by %d%s.\n",
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsNone[]=
|
||||
{
|
||||
L"Keine Boni",
|
||||
|
||||
@@ -17,6 +17,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsMartialArts[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
|
||||
|
||||
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
|
||||
|
||||
@@ -56,6 +56,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Deputy",
|
||||
L"Technician",
|
||||
L"Paramedic",
|
||||
L"Covert Ops", // TODO.Translate
|
||||
|
||||
L"None",
|
||||
L"I.M.P. Major Traits",
|
||||
@@ -69,6 +70,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Squadleader",
|
||||
L"Engineer",
|
||||
L"Doctor",
|
||||
L"Spy", // TODO.Translate
|
||||
};
|
||||
|
||||
//added another set of skill texts for new minor traits
|
||||
@@ -239,6 +241,16 @@ STR16 gzIMPMajorTraitsHelpTextsDoctor[]=
|
||||
L" (max %d these bonuses per sector)",
|
||||
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsCovertOps[]= // TODO.Translate
|
||||
{
|
||||
L"Can disguise as a civilian or soldier to slip behind enemy lines.\n",
|
||||
L"Will be detected if performing suspicious actions, having\nsuspicious gear or being near fresh corpses.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to the enemy.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to a fresh corpse.\n",
|
||||
L"+%d%s CTH with covert melee weapons\n",
|
||||
L"+%d%s chance of instakill with covert melee weapons\n",
|
||||
L"Disguise AP cost lowered by %d%s.\n",
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsNone[]=
|
||||
{
|
||||
L"No bonuses",
|
||||
|
||||
@@ -17,6 +17,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsMartialArts[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
|
||||
|
||||
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
|
||||
|
||||
@@ -58,6 +58,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Zastępca szeryfa",
|
||||
L"Technik",
|
||||
L"Paramedyk",
|
||||
L"Covert Ops", // TODO.Translate
|
||||
|
||||
L"None",
|
||||
L"Główne cechy I.M.P",
|
||||
@@ -71,6 +72,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Dowódca drużyny",
|
||||
L"Inżynier",
|
||||
L"Doktor",
|
||||
L"Spy", // TODO.Translate
|
||||
};
|
||||
|
||||
//added another set of skill texts for new minor traits
|
||||
@@ -241,6 +243,16 @@ STR16 gzIMPMajorTraitsHelpTextsDoctor[]=
|
||||
L" (max %d of these bonuses per sector stack)",
|
||||
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsCovertOps[]= // TODO.Translate
|
||||
{
|
||||
L"Can disguise as a civilian or soldier to slip behind enemy lines.\n",
|
||||
L"Will be detected if performing suspicious actions, having\nsuspicious gear or being near fresh corpses.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to the enemy.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to a fresh corpse.\n",
|
||||
L"+%d%s CTH with covert melee weapons\n",
|
||||
L"+%d%s chance of instakill with covert melee weapons\n",
|
||||
L"Disguise AP cost lowered by %d%s.\n",
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsNone[]=
|
||||
{
|
||||
L"No bonuses",
|
||||
|
||||
@@ -17,6 +17,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsMartialArts[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
|
||||
|
||||
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
|
||||
|
||||
@@ -57,6 +57,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Старшина", //Deputy
|
||||
L"Механик-электронщик", //Technician
|
||||
L"Санитар", //Paramedic
|
||||
L"Covert Ops", // TODO.Translate
|
||||
|
||||
L"Нет",
|
||||
L"I.M.P.: Основные навыки", //I.M.P. Major Traits
|
||||
@@ -70,6 +71,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Командир", //Squadleader
|
||||
L"Инженер", //Engineer
|
||||
L"Доктор", //Doctor
|
||||
L"Spy", // TODO.Translate
|
||||
};
|
||||
|
||||
//added another set of skill texts for new minor traits
|
||||
@@ -240,6 +242,16 @@ STR16 gzIMPMajorTraitsHelpTextsDoctor[]=
|
||||
L" (максимум %d бонуса на находящихся в секторе)",
|
||||
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsCovertOps[]= // TODO.Translate
|
||||
{
|
||||
L"Can disguise as a civilian or soldier to slip behind enemy lines.\n",
|
||||
L"Will be detected if performing suspicious actions, having\nsuspicious gear or being near fresh corpses.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to the enemy.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to a fresh corpse.\n",
|
||||
L"+%d%s CTH with covert melee weapons\n",
|
||||
L"+%d%s chance of instakill with covert melee weapons\n",
|
||||
L"Disguise AP cost lowered by %d%s.\n",
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsNone[]=
|
||||
{
|
||||
L"Нет преимуществ",
|
||||
|
||||
@@ -17,6 +17,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsMartialArts[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
|
||||
|
||||
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
|
||||
|
||||
@@ -59,6 +59,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Deputy",
|
||||
L"Technician",
|
||||
L"Paramedic",
|
||||
L"Covert Ops", // TODO.Translate
|
||||
|
||||
L"None",
|
||||
L"I.M.P. Major Traits",
|
||||
@@ -72,6 +73,7 @@ STR16 gzIMPSkillTraitsTextNewMajor[]=
|
||||
L"Squadleader",
|
||||
L"Engineer",
|
||||
L"Doctor",
|
||||
L"Spy", // TODO.Translate
|
||||
};
|
||||
|
||||
//added another set of skill texts for new minor traits
|
||||
@@ -242,6 +244,16 @@ STR16 gzIMPMajorTraitsHelpTextsDoctor[]=
|
||||
L" (max %d these bonuses per sector)",
|
||||
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsCovertOps[]= // TODO.Translate
|
||||
{
|
||||
L"Can disguise as a civilian or soldier to slip behind enemy lines.\n",
|
||||
L"Will be detected if performing suspicious actions, having\nsuspicious gear or being near fresh corpses.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to the enemy.\n",
|
||||
L"Will automatically be detected if disguised as a soldier and\ncloser than %d tiles to a fresh corpse.\n",
|
||||
L"+%d%s CTH with covert melee weapons\n",
|
||||
L"+%d%s chance of instakill with covert melee weapons\n",
|
||||
L"Disguise AP cost lowered by %d%s.\n",
|
||||
};
|
||||
STR16 gzIMPMajorTraitsHelpTextsNone[]=
|
||||
{
|
||||
L"No bonuses",
|
||||
|
||||
@@ -17,6 +17,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsMartialArts[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
|
||||
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
|
||||
|
||||
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
|
||||
|
||||
@@ -7074,6 +7074,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
|
||||
L"|A|m|m|o |B|e|l|t",
|
||||
L"|A|m|m|o |V|e|s|t",
|
||||
L"|D|e|f|u|s|a|l |K|i|t", // TODO.Translate
|
||||
L"|C|o|v|e|r|t |I|t|e|m",
|
||||
};
|
||||
|
||||
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
@@ -7109,6 +7110,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
L"\n \nWith this ammo belt you can\nfeed someone else's MG.",
|
||||
L"\n \nYou can feed an MG with ammo\nbelts stored in this vest.",
|
||||
L"\n \nThis item improves your trap disarm chance by ", // TODO.Translate
|
||||
L"\n \nThis item and everything attached/inside\nit is hidden from curious eyes.",
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsTooltipText[]=
|
||||
|
||||
@@ -7042,6 +7042,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
|
||||
L"|A|m|m|o |B|e|l|t",
|
||||
L"|A|m|m|o |V|e|s|t",
|
||||
L"|D|e|f|u|s|a|l |K|i|t", // TODO.Translate
|
||||
L"|C|o|v|e|r|t |I|t|e|m",
|
||||
};
|
||||
|
||||
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
@@ -7077,6 +7078,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
L"\n \nWith this ammo belt you can\nfeed someone else's MG.",
|
||||
L"\n \nYou can feed an MG with ammo\nbelts stored in this vest.",
|
||||
L"\n \nThis item improves your trap disarm chance by ", // TODO.Translate
|
||||
L"\n \nThis item and everything attached/inside\nit is hidden from curious eyes.",
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsTooltipText[]=
|
||||
|
||||
@@ -7079,6 +7079,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]=
|
||||
L"|A|m|m|o |B|e|l|t",
|
||||
L"|A|m|m|o |V|e|s|t",
|
||||
L"|D|e|f|u|s|a|l |K|i|t", // TODO.Translate
|
||||
L"|C|o|v|e|r|t |I|t|e|m",
|
||||
};
|
||||
|
||||
STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
@@ -7114,6 +7115,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]=
|
||||
L"\n \nWith this ammo belt you can\nfeed someone else's MG.",
|
||||
L"\n \nYou can feed an MG with ammo\nbelts stored in this vest.",
|
||||
L"\n \nThis item improves your trap disarm chance by ", // TODO.Translate
|
||||
L"\n \nThis item and everything attached/inside\nit is hidden from curious eyes.",
|
||||
};
|
||||
|
||||
STR16 szUDBAdvStatsTooltipText[]=
|
||||
|
||||
Reference in New Issue
Block a user