New feature: radio operator trait allows calling in artillery, requesting reinforcements, scanning for enemies and a few other skills.

Also includes mechansim for easy implementation of new skills.

For more info see http://www.bears-pit.com/board/ubbthreads.php/topics/327348.html#Post327348

Requires GameDir >= r1848.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6547 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2013-10-30 23:05:37 +00:00
parent bef4e7b52b
commit f17829fac9
80 changed files with 4722 additions and 243 deletions
+17
View File
@@ -2349,6 +2349,18 @@ void LoadSkillTraitsExternalSettings()
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);
gSkillTraitValues.fCOElitesDetectNextTile = iniReader.ReadBoolean("Covert Ops","COVERT_ELITES_DETECT_NEXTTILE", TRUE);
// Flugente: RADIO OPERATOR
gSkillTraitValues.bVOArtillerySectorFrequency = iniReader.ReadInteger("Radio Operator","RADIO_OPERATOR_ARTILLERY_SECTOR_FREQUENCY", 120, 20, 1440);
gSkillTraitValues.usVOMortarCountDivisor = iniReader.ReadInteger("Radio Operator","RADIO_OPERATOR_MORTAR_COUNT_DIVISOR", 6, 5, 20);
gSkillTraitValues.usVOMortarShellDivisor = iniReader.ReadInteger("Radio Operator","RADIO_OPERATOR_MORTAR_SHELL_DIVISOR", 30, 2, 100);
gSkillTraitValues.usVOMortarPointsAdmin = iniReader.ReadInteger("Radio Operator","RADIO_OPERATOR_MORTAR_POINTS_ADMIN", 10, 0, 100);
gSkillTraitValues.usVOMortarPointsTroop = iniReader.ReadInteger("Radio Operator","RADIO_OPERATOR_MORTAR_POINTS_TROOP", 15, 0, 100);
gSkillTraitValues.usVOMortarPointsElite = iniReader.ReadInteger("Radio Operator","RADIO_OPERATOR_MORTAR_POINTS_ELITE", 25, 0, 100);
gSkillTraitValues.usVOMortarRadius = iniReader.ReadInteger("Radio Operator","RADIO_OPERATOR_MORTAR_RADIUS", 10, 5, 100);
gSkillTraitValues.usVOMortarSignalShellRadius = iniReader.ReadInteger("Radio Operator","RADIO_OPERATOR_MORTAR_SIGNAL_SHELL_RADIUS", 2, 2, 100);
gSkillTraitValues.sVOScanAssignmentBaseRange = iniReader.ReadInteger("Radio Operator","RADIO_OPERATOR_ASSIGNMENT_SCAN_BASE_RANGE", 5, 0, 20);
gSkillTraitValues.sVOListeningHearingBonus = iniReader.ReadInteger("Radio Operator","RADIO_OPERATOR_LISTENING_HEARING_BONUS", 20, 0, 100);
}
//DBrot: Grids
void LoadModSettings(){
@@ -2724,6 +2736,11 @@ void LoadItemSettings()
gItemSettings.fDamageHealthMoveModifierExplosive = iniReader.ReadFloat ("Explosives Settings","DAMAGE_HEALTH_MOVE_EXPLOSIVE_MODIFIER", 0.1f, 0.0f, 1.0f);
gItemSettings.fDamageBreathMoveModifierExplosive = iniReader.ReadFloat ("Explosives Settings","DAMAGE_BREATH_MOVE_EXPLOSIVE_MODIFIER", 0.1f, 0.0f, 1.0f);
// ------------ ENERGY MODIFIERS -----------------
gItemSettings.energy_cost_radioset_activate = iniReader.ReadFloat ("Energy Settings","ENERGY_COST_RADIOSET_ACTIVATE", 100.00f, 1.00f, 1000.0f);
gItemSettings.energy_cost_radioset_jam = iniReader.ReadFloat ("Energy Settings","ENERGY_COST_RADIOSET_JAM", 10.00f, 1.00f, 1000.0f);
gItemSettings.energy_cost_radioset_scan = iniReader.ReadFloat ("Energy Settings","ENERGY_COST_RADIOSET_SCAN", 3.00f, 1.00f, 1000.0f);
gItemSettings.energy_cost_radioset_scan_assignment = iniReader.ReadFloat ("Energy Settings","ENERGY_COST_RADIOSET_SCAN_ASSIGNMENT", 3000.00f, 1.00f, 30000.0f);
}
INT16 DynamicAdjustAPConstants(INT16 iniReadValue, INT16 iniDefaultValue, BOOLEAN reverse)
+19
View File
@@ -1575,6 +1575,18 @@ typedef struct
INT16 sCOCloseDetectionRangeSoldierCorpse;
BOOLEAN fCOElitesDetectNextTile;
// RADIO OPERATOR
INT16 bVOArtillerySectorFrequency; // ability to call an a artillery strike from a sector every '_' minutes. Only applies if ordered from enemy/militia
UINT8 usVOMortarCountDivisor;
UINT8 usVOMortarShellDivisor;
UINT8 usVOMortarPointsAdmin;
UINT8 usVOMortarPointsTroop;
UINT8 usVOMortarPointsElite;
UINT8 usVOMortarRadius;
UINT8 usVOMortarSignalShellRadius;
INT8 sVOScanAssignmentBaseRange;
INT8 sVOListeningHearingBonus;
} SKILL_TRAIT_VALUES;
// HEADROCK HAM 4: Constants used as coefficients by the various parts of the new CTH system.
@@ -1949,6 +1961,13 @@ typedef struct
FLOAT fDamageHealthMoveModifierExplosive; // applies when character moves through gas cloud without a gas mask
FLOAT fDamageBreathMoveModifierExplosive; // applies when character moves through gas cloud without a gas mask
// ------------ ENERGY MODIFIERS -----------------
// Flugente: energy consumption settings (energy-consumption of attached non-vanilla batteries)
FLOAT energy_cost_radioset_activate;
FLOAT energy_cost_radioset_jam;
FLOAT energy_cost_radioset_scan;
FLOAT energy_cost_radioset_scan_assignment;
}ITEM_SETTINGS;
extern MOD_SETTINGS gModSettings;
+2 -1
View File
@@ -21,6 +21,7 @@ extern CHAR16 zTrackingNumber[16];
// Keeps track of the saved game version. Increment the saved game version whenever
// you will invalidate the saved game file
#define TRAIT_RADIO_OPERATOR 147 // Flugente: new trait radio operator
#define BACKGROUNDS_FIX_UINT8 146 // Flugente: had to change usBackground-vars from UINT8 to UINT16
#define BACKGROUNDS 145 // Flugente: background feature
#define NO_VEHICLE_SAVE 144 // Flugente: vehicle data isn't saved anymore, as it has long been externalised
@@ -65,7 +66,7 @@ extern CHAR16 zTrackingNumber[16];
#define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes
#define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system
#define SAVE_GAME_VERSION BACKGROUNDS_FIX_UINT8
#define SAVE_GAME_VERSION TRAIT_RADIO_OPERATOR
//#define RUSSIANGOLD
#ifdef __cplusplus
+5 -1
View File
@@ -778,7 +778,11 @@ void GiveItemsToPC( UINT8 ubProfileId )
if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, SCOUTING_NT))
{
GiveIMPRandomItems(pProfile,IMP_SCOUTING);
}
}
if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, RADIO_OPERATOR_NT))
{
GiveIMPRandomItems(pProfile,IMP_RADIO_OPERATOR);
}
}
else
{
+32 -8
View File
@@ -45,7 +45,7 @@
#define IMP_MINOR_TRAIT__SPACE_BTN_BUTTONS ( 38 + 5 )
#define IMP_MINOR_TRAIT__TRAITS_TO_START_RIGHT_COL 4
#define IMP_MINOR_TRAIT__TRAITS_TO_START_RIGHT_COL 5
#define IMP_MINOR_TRAIT__NONE_BTN_LOC_X ( LAPTOP_SCREEN_UL_X + 136 )
#define IMP_MINOR_TRAIT__NONE_BTN_LOC_Y ( LAPTOP_SCREEN_WEB_UL_Y + 306 )
@@ -78,7 +78,7 @@ INT32 giIMPMinorTraitAnswerButtonImage[ IMP_SKILL_TRAITS_NEW_NUMBER_MINOR_SKILLS
INT32 giIMPMinorlTraitFinsihButton;
INT32 giIMPMinorlTraitFinsihButtonImage;
INT8 gbLastSelectedMinorTrait[ 10 ];
INT8 gbLastSelectedMinorTrait[ NUM_MINOR_TRAITS ];
//image handle
UINT32 guiIMT_GreyGoldBox;
@@ -191,7 +191,7 @@ void EnterIMPMinorTrait( void )
}
//reset last selected trait
memset( gbLastSelectedMinorTrait, -1, 10 );
memset( gbLastSelectedMinorTrait, -1, NUM_MINOR_TRAITS );
}
@@ -512,14 +512,17 @@ void BtnIMPMinorTraitFinishCallback(GUI_BUTTON *btn,INT32 reason)
{
iCurrentImpPage = IMP_MAIN_PAGE;
if( CameBackToMinorTraitPageButNotFinished() )
fButtonPendingFlag = TRUE;
/*i´f( CameBackToMinorTraitPageButNotFinished() )
{
}
else
{
//We are finished on this page
iCurrentProfileMode = IMP__ATTRIBUTES;
}
}*/
}
}
}
@@ -652,6 +655,10 @@ void AddSelectedMinorTraitsToSkillsList()
case IMP_SKILL_TRAITS_NEW_SCOUTING:
AddSkillToSkillList( SCOUTING_NT );
break;
case IMP_SKILL_TRAITS_NEW_RADIO_OPERATOR:
AddSkillToSkillList( RADIO_OPERATOR_NT );
break;
default:
break;
@@ -668,7 +675,7 @@ void HandleLastSelectedMinorTrait( INT8 bNewTrait )
if (bNewTrait == -1)
{
// we only want to delete the last selected trait from list
for( iCnt=9; iCnt>=0; iCnt-- )
for( iCnt=NUM_MINOR_TRAITS-1; iCnt>=0; iCnt-- )
{
if ( gbLastSelectedMinorTrait[ iCnt ] > 0 )
{
@@ -680,7 +687,7 @@ void HandleLastSelectedMinorTrait( INT8 bNewTrait )
}
else
{
for( iCnt=0; iCnt<9; iCnt++ )
for( iCnt=0; iCnt<NUM_MINOR_TRAITS-1; iCnt++ )
{
gbLastSelectedMinorTrait[ (iCnt + 1) ] = gbLastSelectedMinorTrait[ iCnt ];
}
@@ -768,7 +775,7 @@ INT8 GetLastSelectedMinorTrait( void )
{
INT16 iCnt;
for( iCnt=9; iCnt>=0; iCnt-- )
for( iCnt=NUM_MINOR_TRAITS-1; iCnt>=0; iCnt-- )
{
if ( gbLastSelectedMinorTrait[ iCnt ] > 0 )
{
@@ -1432,6 +1439,23 @@ void AssignMinorTraitHelpText( UINT8 ubNumber )
}
break;
}
case IMP_SKILL_TRAITS_NEW_RADIO_OPERATOR:
{
swprintf( apStr, L"" );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[0]);
wcscat( apStr, atStr );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[1]);
wcscat( apStr, atStr );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[2]);
wcscat( apStr, atStr );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[3]);
wcscat( apStr, atStr );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[4]);
wcscat( apStr, atStr );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[5]);
wcscat( apStr, atStr );
break;
}
case IMP_SKILL_TRAITS_NEW_MINOR_NONE:
{
swprintf( apStr, gzIMPMinorTraitsHelpTextsNone[0] );
+1
View File
@@ -21,6 +21,7 @@ enum
IMP_SKILL_TRAITS_NEW_DEMOLITIONS,
IMP_SKILL_TRAITS_NEW_TEACHING,
IMP_SKILL_TRAITS_NEW_SCOUTING,
IMP_SKILL_TRAITS_NEW_RADIO_OPERATOR, // added by Flugente
//////
IMP_SKILL_TRAITS_NEW_MINOR_NONE,
IMP_SKILL_TRAITS_NEW_NUMBER_MINOR_SKILLS,
+6
View File
@@ -4699,6 +4699,12 @@ void HandleIMPCharProfileResultsMessage( void)
wcscpy(pString, MissingIMPSkillsDescriptions[11]);
AddEmailRecordToList( pString );
}
// Radio Operator
if ( ProfileHasSkillTrait( iCurrentIMPSlot, RADIO_OPERATOR_NT ) > 0 )
{
wcscpy(pString, MissingIMPSkillsDescriptions[15]);
AddEmailRecordToList( pString );
}
}
else
{
+21 -1
View File
@@ -8084,7 +8084,27 @@ void AssignPersonnelSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLeve
swprintf( atStr, gzIMPMajorTraitsHelpTextsCovertOps[6], apreduction, L"%");
wcscat( apStr, atStr );
break;
}
}
// Flugente: Radio Operator
case RADIO_OPERATOR_NT:
{
swprintf( apStr, L"" );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[0]);
wcscat( apStr, atStr );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[1]);
wcscat( apStr, atStr );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[2]);
wcscat( apStr, atStr );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[3]);
wcscat( apStr, atStr );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[4]);
wcscat( apStr, atStr );
swprintf( atStr, gzIMPMajorTraitsHelpTextsRadioOperator[5]);
wcscat( apStr, atStr );
break;
}
case NO_SKILLTRAIT_NT:
{
swprintf( apStr, L"" );
+167 -4
View File
@@ -2054,8 +2054,148 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
numBytesRead = ReadFieldByField(hFile, &this->bExtraWisdom, sizeof(bExtraWisdom), sizeof(INT16), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->bExtraExpLevel, sizeof(bExtraExpLevel), sizeof(INT8), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->bSoldierFlagMask, sizeof(bSoldierFlagMask), sizeof(INT32), numBytesRead);
if ( guiCurrentSaveGameVersion >= FOOD_CHANGES )
{
numBytesRead = ReadFieldByField(hFile, &this->bFoodLevel, sizeof(bFoodLevel), sizeof(INT32), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->bDrinkLevel, sizeof(bDrinkLevel), sizeof(INT32), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->usStarveDamageHealth, sizeof(usStarveDamageHealth), sizeof(UINT8), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->usStarveDamageHealth, sizeof(usStarveDamageStrength), sizeof(UINT8), numBytesRead);
}
else
{
this->bFoodLevel = 0;
this->bDrinkLevel = 0;
this->usStarveDamageHealth = 0;
this->usStarveDamageHealth = 0;
for(int i = 0; i < sizeof(bFoodLevel); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
for(int i = 0; i < sizeof(bDrinkLevel); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
for(int i = 0; i < sizeof(usStarveDamageHealth); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
for(int i = 0; i < sizeof(usStarveDamageStrength); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
}
if ( guiCurrentSaveGameVersion >= MULTITURN_ACTIONS )
{
numBytesRead = ReadFieldByField(hFile, &this->bOverTurnAPS, sizeof(bOverTurnAPS), sizeof(INT16), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->sMTActionGridNo, sizeof(sMTActionGridNo), sizeof(INT32), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->usMultiTurnAction, sizeof(usMultiTurnAction), sizeof(UINT8), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->bAIIndex, sizeof(bAIIndex), sizeof(INT16), numBytesRead);
}
else
{
this->bOverTurnAPS = 0;
this->sMTActionGridNo = 0;
this->usMultiTurnAction = 0;
this->bAIIndex = 0;
for(int i = 0; i < sizeof(bOverTurnAPS); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
for(int i = 0; i < sizeof(sMTActionGridNo); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
for(int i = 0; i < sizeof(usMultiTurnAction); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
for(int i = 0; i < sizeof(bAIIndex); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
}
if ( guiCurrentSaveGameVersion >= SOLDIER_PROFILES )
{
numBytesRead = ReadFieldByField(hFile, &this->usSoldierProfile, sizeof(usSoldierProfile), sizeof(UINT16), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->usItemMoveSectorID, sizeof(usItemMoveSectorID), sizeof(UINT8), numBytesRead);
}
else
{
this->usSoldierProfile = 0;
this->usItemMoveSectorID = 0;
for(int i = 0; i < sizeof(usSoldierProfile); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
for(int i = 0; i < sizeof(usItemMoveSectorID); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
}
if ( guiCurrentSaveGameVersion >= TRAIT_RADIO_OPERATOR )
{
numBytesRead = ReadFieldByField(hFile, &this->usAISkillUse, sizeof(usAISkillUse), sizeof(UINT8), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->usSkillCounter, sizeof(usSkillCounter), sizeof(UINT16), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->usSkillCooldown, sizeof(usSkillCooldown), sizeof(UINT32), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead);
}
else
{
this->usAISkillUse = 0;
for(UINT8 i = 0; i < SOLDIER_COUNTER_MAX; ++i)
this->usSkillCounter[i] = 0;
for(UINT8 i = 0; i < SOLDIER_COOLDOWN_MAX; ++i)
this->usSkillCooldown[i] = 0;
// Flugente: okay, this part will be a bit weird, so bear with me
// ubFiller had length 7 before this revision - we still need to read those. We have to do that, otherwise the next read functions will read the filler
UINT8 blarg[7];
numBytesRead = ReadFieldByField(hFile, &blarg, 7, sizeof(UINT8), numBytesRead);
// usAISkillUse forms one block with usSoldierProfile and usItemMoveSectorID and thus does not need additional padding
buffer += 3;
for(int i = 0; i < sizeof(usAISkillUse); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
for(int i = 0; i < sizeof(usSkillCounter)-6; ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
for(int i = 0; i < sizeof(usSkillCooldown); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
for(int i = 0; i < sizeof(ubFiller); ++i)
buffer++;
while((buffer%4) > 0)
buffer++;
// we now have to substract the 7 bytes we read from the old ubFiller, but have to account for usAISkillUse
buffer -= 6;
}
/*if ( guiCurrentSaveGameVersion >= FOOD_CHANGES )
{
numBytesRead = ReadFieldByField(hFile, &this->bFoodLevel, sizeof(bFoodLevel), sizeof(INT32), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->bDrinkLevel, sizeof(bDrinkLevel), sizeof(INT32), numBytesRead);
@@ -2073,8 +2213,31 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
{
numBytesRead = ReadFieldByField(hFile, &this->usSoldierProfile, sizeof(usSoldierProfile), sizeof(UINT16), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->usItemMoveSectorID, sizeof(usItemMoveSectorID), sizeof(UINT8), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead);
if ( guiCurrentSaveGameVersion >= SOLDIER_PROFILES )
{
numBytesRead = ReadFieldByField(hFile, &this->usSkillCounter, sizeof(usSkillCounter), sizeof(UINT16), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->usSkillCooldown, sizeof(usSkillCooldown), sizeof(UINT32), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->usAISkillUse, sizeof(usAISkillUse), sizeof(UINT8), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead);
}
else
{
for(UINT8 i = 0; i < SOLDIER_COUNTER_MAX; ++i)
this->usSkillCounter[i] = 0;
for(UINT8 i = 0; i < SOLDIER_COOLDOWN_MAX; ++i)
this->usSkillCooldown[i] = 0;
this->usAISkillUse = 0;
// as we added new variables, fillersize was reduced, here we account for that. We have to also read the existing fillers that now do not exist anymore
const UINT8 tmp = sizeof(usSkillCounter) + sizeof(usSkillCooldown) + sizeof(usAISkillUse);
UINT8 blarg[tmp];
numBytesRead = ReadFieldByField(hFile, &blarg, tmp, sizeof(UINT8), numBytesRead);
numBytesRead = ReadFieldByField(hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead);
}
}
else
{
@@ -2164,7 +2327,7 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
buffer++;
while((buffer%4) > 0)
buffer++;
}
}*/
#ifdef JA2UB
numBytesRead = ReadFieldByField(hFile, &this->fIgnoreGetupFromCollapseCheck, sizeof(fIgnoreGetupFromCollapseCheck), sizeof(BOOLEAN), numBytesRead);
+245 -1
View File
@@ -64,6 +64,7 @@
#include "Morale.h"
#include "Food.h"
#include "Tactical Save.h" // added by Flugente
#include "Campaign Types.h" // added by Flugente
#endif
#include <vector>
#include <queue>
@@ -91,6 +92,9 @@ class SOLDIERTYPE;
#include "ub_config.h"
#endif
// Flugente: external sector data
extern SECTOR_EXT_DATA SectorExternalData[256][4];
// various reason an assignment can be aborted before completion
enum{
NO_MORE_MED_KITS = 40,
@@ -427,6 +431,12 @@ void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ );
// Flugente: assigned mercs can move equipemnt in city sectors
void HandleEquipmentMove( INT16 sMapX, INT16 sMapY, INT8 bZ );
// Flugente: handle radio scanning assignments
void HandleRadioScanInSector( INT16 sMapX, INT16 sMapY, INT8 bZ );
// reset scan flags in all sectors
void ClearSectorScanResults();
// is the character between secotrs in mvt
BOOLEAN CharacterIsBetweenSectors( SOLDIERTYPE *pSoldier );
@@ -2249,6 +2259,9 @@ void UpdateAssignments()
// HEADROCK HAM 3.6: See what effect, if any, our Facility Staffers have on global variables.
UpdateGlobalVariablesFromFacilities();
// reset scan flags in all sectors
ClearSectorScanResults();
// run through sectors and handle each type in sector
for(sX = 0 ; sX < MAP_WORLD_X; sX++ )
{
@@ -2272,6 +2285,9 @@ void UpdateAssignments()
// handle any training
HandleTrainingInSector( sX, sY, bZ );
// handle training of character in sector
HandleRadioScanInSector( sX, sY, bZ );
// handle processing of prisoners
HandlePrisonerProcessingInSector( sX, sY, bZ );
@@ -4872,6 +4888,152 @@ void HandleTrainingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
}
// handle radio scanning assignments
void HandleRadioScanInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
{
SOLDIERTYPE *pSoldier = NULL;
UINT32 uiCnt=0;
UINT8 numberofradiooperators = 0;
// no underground scanning
if (bZ != 0)
return;
// if sector not under our control, has enemies in it, or is currently in combat mode
if (!SectorOursAndPeaceful( sMapX, sMapY, bZ ))
return;
// we will count the number of radio operators in this sector that have scanned successfully this hour. The higher this number, the higher the chance to detect enemy patrols!
// search team for radio operators in this sector that performed this assignemnt successfully
for ( uiCnt = 0, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= gTacticalStatus.Team[ MercPtrs[0]->bTeam ].bLastID; uiCnt++, pSoldier++)
{
if( pSoldier->bActive && ( pSoldier->sSectorX == sMapX ) && ( pSoldier->sSectorY == sMapY ) && ( pSoldier->bSectorZ == bZ) )
{
if( ( pSoldier->bAssignment == RADIO_SCAN ) && ( EnoughTimeOnAssignment( pSoldier ) ) && ( pSoldier->flags.fMercAsleep == FALSE ) )
{
++numberofradiooperators;
// use up radio energy
pSoldier->DepleteActiveRadioSetEnergy(FALSE, TRUE);
}
}
}
if ( !numberofradiooperators )
return;
INT8 range = gSkillTraitValues.sVOScanAssignmentBaseRange;
UINT8 ubSectorId = SECTOR(sMapX, sMapY);
if ( ubSectorId >= 0 && ubSectorId < 256 )
range += SectorExternalData[ubSectorId][0].sRadioScanModifier;
if ( range < 1 )
return;
UINT8 normalgroupsize = 0;
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
normalgroupsize = gGameExternalOptions.ubMinEnemyGroupSizeNovice;
break;
case DIF_LEVEL_MEDIUM:
normalgroupsize = gGameExternalOptions.ubMinEnemyGroupSizeExperienced;
break;
case DIF_LEVEL_HARD:
normalgroupsize = gGameExternalOptions.ubMinEnemyGroupSizeExpert;
break;
case DIF_LEVEL_INSANE:
default:
normalgroupsize = gGameExternalOptions.ubMinEnemyGroupSizeInsane;
break;
}
normalgroupsize *= 2;
FLOAT detect_basechance = 1.0f - pow(0.5f, numberofradiooperators);
FLOAT detect_rangefactor = .0f;
FLOAT detect_sizefactor = .0f;
FLOAT detect_chance = .0f;
FLOAT scandirectionmalus = .2f;
FLOAT scanexactnumbermalus = .3f;
UINT8 patrolsize = 0;
// run through sectors and handle each type in sector
for(INT16 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
{
for(INT16 sY = 1; sY < MAP_WORLD_X - 1; ++sY )
{
// is this sector within range?
FLOAT euklid_dist = (sX - sMapX)*(sX - sMapX) + (sY - sMapY)*(sY - sMapY);
detect_rangefactor = euklid_dist / (range*range);
//detect_rangefactor *= detect_rangefactor;
if ( detect_rangefactor > 1.0f )
continue;
detect_rangefactor = 1.01f - detect_rangefactor;
patrolsize = NumEnemiesInSector( sX, sY );
// no or single enemies -> skip this
if ( patrolsize < 2 )
continue;
detect_sizefactor = sqrt((FLOAT)(patrolsize) / (FLOAT)(normalgroupsize));
detect_chance = detect_basechance * detect_rangefactor * detect_sizefactor;
UINT32 scanresult = Random(100);
if ( scanresult < 100 * detect_chance )
{
// enemy patrol detected
SectorInfo[ SECTOR( sX, sY ) ].uiFlags |= SF_ASSIGN_NOTICED_ENEMIES_HERE;
if ( scanresult < 100 * (detect_chance - scanexactnumbermalus) )
{
// our scan was very good, we even got the exact enemy numbers
SectorInfo[ SECTOR( sX, sY ) ].uiFlags |= SF_ASSIGN_NOTICED_ENEMIES_KNOW_NUMBER;
}
// we roll again to decide wether we know the direction this patrol is moving in
scanresult = Random(100);
if ( scanresult < 100 * (detect_chance - scandirectionmalus) )
{
// we were succesful in deducting the direction they are moving in
SectorInfo[ SECTOR( sX, sY ) ].uiFlags |= SF_ASSIGN_NOTICED_ENEMIES_KNOW_DIRECTION;
}
}
}
}
// award experience to all radio operators
for ( uiCnt = 0, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= gTacticalStatus.Team[ MercPtrs[0]->bTeam ].bLastID; uiCnt++, pSoldier++)
{
if( pSoldier->bActive && ( pSoldier->sSectorX == sMapX ) && ( pSoldier->sSectorY == sMapY ) && ( pSoldier->bSectorZ == bZ) )
{
if( ( pSoldier->bAssignment == RADIO_SCAN ) && ( EnoughTimeOnAssignment( pSoldier ) ) && ( pSoldier->flags.fMercAsleep == FALSE ) )
{
StatChange( pSoldier, WISDOMAMT, 5, TRUE );
StatChange( pSoldier, EXPERAMT, 3, TRUE );
}
}
}
}
// reset scan flags in all sectors
void ClearSectorScanResults()
{
for(INT16 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
{
for(INT16 sY = 1; sY < MAP_WORLD_X - 1; ++sY )
{
SectorInfo[ SECTOR( sX, sY ) ].uiFlags &= ~(SF_ASSIGN_NOTICED_ENEMIES_HERE|SF_ASSIGN_NOTICED_ENEMIES_KNOW_NUMBER);
}
}
}
int TownTrainerQsortCompare(const void *pArg1, const void *pArg2)
{
if (((TOWN_TRAINER_TYPE *)pArg1)->sTrainingPts > ((TOWN_TRAINER_TYPE *)pArg2)->sTrainingPts)
@@ -7799,6 +7961,17 @@ void HandleShadingOfLinesForAssignmentMenus( void )
}
}
// radio scan
if( pSoldier->CanUseRadio() )
{
// unshade line
UnShadeStringInBox( ghAssignmentBox, ASSIGN_MENU_RADIO_SCAN );
}
else
{
// shade line
ShadeStringInBox( ghAssignmentBox, ASSIGN_MENU_RADIO_SCAN );
}
// patient
if( CanCharacterPatient( pSoldier ) )
@@ -10267,7 +10440,42 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason )
DoScreenIndependantMessageBox( sString , MSG_BOX_FLAG_OK, NULL );
}
break;
break;
case( ASSIGN_MENU_RADIO_SCAN ):
if( pSoldier->CanUseRadio() )
{
// stop showing menu
fShowAssignmentMenu = FALSE;
giAssignHighLine = -1;
pSoldier->bOldAssignment = pSoldier->bAssignment;
if( ( pSoldier->bAssignment != RADIO_SCAN ) )
{
SetTimeOfAssignmentChangeForMerc( pSoldier );
}
// remove from squad
if( pSoldier->bOldAssignment == VEHICLE )
{
TakeSoldierOutOfVehicle( pSoldier );
}
RemoveCharacterFromSquads( pSoldier );
ChangeSoldiersAssignment( pSoldier, RADIO_SCAN );
AssignMercToAMovementGroup( pSoldier );
MakeSoldiersTacticalAnimationReflectAssignment( pSoldier );
// set dirty flag
fTeamPanelDirty = TRUE;
fMapScreenBottomDirty = TRUE;
// set assignment for group
SetAssignmentForList( ( INT8 ) RADIO_SCAN, 0 );
}
break;
case( ASSIGN_MENU_TRAIN ):
if( CanCharacterPractise( pSoldier ) )
{
@@ -12498,6 +12706,30 @@ void SetSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment, INT32 iParam
}
break;
case( RADIO_SCAN ):
if( pSoldier->CanUseRadio() )
{
pSoldier->bOldAssignment = pSoldier->bAssignment;
// remove from squad
RemoveCharacterFromSquads( pSoldier );
// remove from any vehicle
if( pSoldier->bOldAssignment == VEHICLE )
{
TakeSoldierOutOfVehicle( pSoldier );
}
if ( pSoldier->bAssignment != RADIO_SCAN )
{
SetTimeOfAssignmentChangeForMerc( pSoldier );
}
ChangeSoldiersAssignment( pSoldier, RADIO_SCAN );
AssignMercToAMovementGroup( pSoldier );
}
break;
case( FACILITY_INTERROGATE_PRISONERS ):
if( pSoldier->CanProcessPrisoners() )
{
@@ -13598,6 +13830,10 @@ void ReEvaluateEveryonesNothingToDo()
fNothingToDo = !CanCharacterRepair( pSoldier ) || HasCharacterFinishedRepairing( pSoldier );
break;
case RADIO_SCAN:
fNothingToDo = !pSoldier->CanUseRadio();
break;
case FACILITY_INTERROGATE_PRISONERS:
fNothingToDo = !pSoldier->CanProcessPrisoners();
break;
@@ -13778,6 +14014,14 @@ void SetAssignmentForList( INT8 bAssignment, INT8 bParam )
}
}
break;
case ( RADIO_SCAN ):
if ( pSoldier->CanUseRadio() )
{
pSoldier->bOldAssignment = pSoldier->bAssignment;
SetSoldierAssignment( pSoldier, RADIO_SCAN, bParam, 0,0 );
fItWorked = TRUE;
}
break;
case( TRAIN_SELF ):
if( CanCharacterTrainStat( pSoldier, bParam , TRUE, FALSE ) )
{
+1
View File
@@ -56,6 +56,7 @@ enum
VEHICLE,
IN_TRANSIT,
REPAIR,
RADIO_SCAN, // added by Flugente
TRAIN_SELF,
TRAIN_TOWN,
TRAIN_MOBILE, // HEADROCK HAM 3.6: Training mobile militia.
+3 -1
View File
@@ -491,8 +491,10 @@ typedef struct SECTORINFO
UINT8 uiNumberOfPrisonersOfWar[PRISONER_MAX];
UINT8 uiInterrogationHundredsLeft;
UINT32 uiTimeAIArtillerywasOrdered; // Flugente: updated every time an artillery strike is ordered from the militia
INT8 bPadding[ 36 ];
INT8 bPadding[ 29 ];
}SECTORINFO;
+1
View File
@@ -125,6 +125,7 @@ enum {
ASSIGN_MENU_PATIENT,
ASSIGN_MENU_VEHICLE,
ASSIGN_MENU_REPAIR,
ASSIGN_MENU_RADIO_SCAN, // added by Flugente
ASSIGN_MENU_TRAIN,
ASSIGN_MENU_MOVE_ITEMS, // added by Flugente
ASSIGN_MENU_FACILITY, // HEAROCK HAM 3.6: Facility List menu
+100
View File
@@ -33,6 +33,7 @@
#include "MilitiaSquads.h"
#include "Reinforcement.h"
#include "Inventory Choosing.h" // added by Flugente for MoveOneMilitiaEquipmentSet() and MoveMilitiaEquipment()
#include "message.h" // added by Flugente for ScreenMsg()
// Debug defines
@@ -1813,6 +1814,105 @@ void DoMilitiaHelpFromAdjacentSectors( INT16 sMapX, INT16 sMapY )
gfStrategicMilitiaChangesMade = FALSE;
}
// Flugente: order sNumber reinforcements from src sector to target sector
BOOLEAN CallMilitiaReinforcements( INT16 sTargetMapX, INT16 sTargetMapY, INT16 sSrcMapX, INT16 sSrcMapY, UINT16 sNumber )
{
UINT8 uiNumGreen = 0, uiNumReg = 0, uiNumElite = 0;
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sTargetMapX, sTargetMapY ) ] );
guiDirNumber = 0;
UINT8 insertioncode = INSERTION_CODE_CENTER;
UINT8 movetype = THROUGH_STRATEGIC_MOVE;
// determine from which direction militia should enter (and exit if this isn't possible)
if ( sTargetMapX == sSrcMapX + 1 && sTargetMapY == sSrcMapY )
{
insertioncode = INSERTION_CODE_WEST;
movetype = EAST_STRATEGIC_MOVE;
}
else if ( sTargetMapX == sSrcMapX - 1 && sTargetMapY == sSrcMapY )
{
insertioncode = INSERTION_CODE_EAST;
movetype = WEST_STRATEGIC_MOVE;
}
else if ( sTargetMapX == sSrcMapX && sTargetMapY == sSrcMapY + 1 )
{
insertioncode = INSERTION_CODE_NORTH;
movetype = SOUTH_STRATEGIC_MOVE;
}
else if ( sTargetMapX == sSrcMapX && sTargetMapY == sSrcMapY - 1 )
{
insertioncode = INSERTION_CODE_SOUTH;
movetype = NORTH_STRATEGIC_MOVE;
}
else
{
// no proper direction here... get out
return FALSE;
}
// test wether travel from src to target is possible ( we cannot open the src map information, we'll rely on the xml data instead
if( SectorInfo[ SECTOR(sSrcMapX,sSrcMapY) ].ubTraversability[ movetype ] == GROUNDBARRIER || SectorInfo[ SECTOR(sSrcMapX,sSrcMapY) ].ubTraversability[ movetype ] == EDGEOFWORLD )
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Militia cannot traverse to this sector due to the terrain." );
return FALSE;
}
guiDirNumber = 0;
ZeroMemory( gpAttackDirs, sizeof( gpAttackDirs ) );
gpAttackDirs[ guiDirNumber ][0] = uiNumGreen = pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA];
gpAttackDirs[ guiDirNumber ][1] = uiNumReg = pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA];
gpAttackDirs[ guiDirNumber ][2] = uiNumElite = pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA];
gpAttackDirs[ guiDirNumber ][3] = INSERTION_CODE_CENTER;
guiDirNumber = insertioncode + 1;
UINT16 sMilitiaMoved = 0;
while ( sMilitiaMoved < sNumber && CountMilitia(pSectorInfo ) < gGameExternalOptions.iMaxMilitiaPerSector && MoveOneBestMilitiaMan( sSrcMapX, sSrcMapY, sTargetMapX, sTargetMapY ) )
{
++sMilitiaMoved;
gpAttackDirs[ guiDirNumber ][0] += pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA] - uiNumGreen;
gpAttackDirs[ guiDirNumber ][1] += pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA] - uiNumReg;
gpAttackDirs[ guiDirNumber ][2] += pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA] - uiNumElite;
gpAttackDirs[ guiDirNumber ][3] = insertioncode;
uiNumGreen = pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA];
uiNumReg = pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA];
uiNumElite = pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA];
}
guiDirNumber = 5;
if ( !sMilitiaMoved )
return FALSE;
// we need to se this falg. If it wasn't set prior to this, we remove it again afterwards, otherwise all militia will join us if we are in combat
BOOLEAN wantreinforcements = (gTacticalStatus.uiFlags & WANT_MILITIA_REINFORCEMENTS);
gTacticalStatus.uiFlags |= WANT_MILITIA_REINFORCEMENTS;
if (is_networked)
{
if (gfStrategicMilitiaChangesMade)
{
RemoveMilitiaFromTactical();
if(is_server && gMilitiaEnabled == 1)
PrepareMilitiaForTactical(FALSE);
}
}
else
PrepareMilitiaForTactical(FALSE);
if ( !wantreinforcements )
gTacticalStatus.uiFlags &= ~WANT_MILITIA_REINFORCEMENTS;
gfStrategicMilitiaChangesMade = FALSE;
return TRUE;
}
void MSCallBack( UINT8 ubResult )
{
if( ubResult == MSG_BOX_RETURN_YES )
+15
View File
@@ -48,6 +48,7 @@ typedef struct
UINT8 sWaterType; // Food System
UINT16 usNaturalDirt; // Dirt System
UINT8 usCurfewValue; // Covert Ops
INT8 sRadioScanModifier; // Radio Operator
UINT16 usPrisonRoomNumber[MAX_PRISON_ROOMS]; // Prisoner System
UINT32 currentDepth;
UINT32 maxReadDepth;
@@ -145,6 +146,7 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char **
strcmp(name, "sWaterType") == 0 ||
strcmp(name, "usNaturalDirt") == 0 ||
strcmp(name, "usCurfewValue") == 0 ||
strcmp(name, "sRadioScanModifier") == 0 ||
strcmp(name, "usPrisonRoomNumber00") == 0 ||
strcmp(name, "usPrisonRoomNumber01") == 0 ||
strcmp(name, "usPrisonRoomNumber02") == 0 ||
@@ -284,6 +286,13 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
SectorExternalData[ubSectorId][2].usCurfewValue = pData->usCurfewValue;
SectorExternalData[ubSectorId][3].usCurfewValue = pData->usCurfewValue;
INT8 radioscanmod = max(-3, pData->sRadioScanModifier);
radioscanmod = min(3, pData->sRadioScanModifier);
SectorExternalData[ubSectorId][0].sRadioScanModifier = pData->sRadioScanModifier;
SectorExternalData[ubSectorId][1].sRadioScanModifier = pData->sRadioScanModifier;
SectorExternalData[ubSectorId][2].sRadioScanModifier = pData->sRadioScanModifier;
SectorExternalData[ubSectorId][3].sRadioScanModifier = pData->sRadioScanModifier;
for(UINT8 i = 0; i <MAX_PRISON_ROOMS; ++i)
{
SectorExternalData[ubSectorId][0].usPrisonRoomNumber[i] = pData->usPrisonRoomNumber[i];
@@ -294,6 +303,7 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
pData->sWaterType = 0;
pData->usNaturalDirt = 100;
pData->usCurfewValue = 0;
pData->sRadioScanModifier = 0;
}
}
@@ -358,6 +368,11 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
pData->usCurfewValue = (UINT8) atoi(pData->szCharData);
}
else if(strcmp(name, "sRadioScanModifier") == 0)
{
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
pData->sRadioScanModifier = (INT8) atoi(pData->szCharData);
}
else if(strcmp(name, "usPrisonRoomNumber00") == 0)
{
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
+288 -20
View File
@@ -67,6 +67,15 @@ enum MINES_VALUES
MAX_MINES
};
// Flugente: trait display
enum TRAIT_VALUES
{
TRAIT_ALL = MAX_MINES + 1,
TRAIT_1,
TRAIT_2,
MAX_TRAIT
};
struct CoverCell
{
@@ -75,8 +84,9 @@ struct CoverCell
BOOLEAN fInverseColor;
INT8 bMines;
INT8 bTrait;
CoverCell() : sGridNo(NOWHERE), bCover(INVALID_COVER), fInverseColor(FALSE), bMines(MINES_ALL) {}
CoverCell() : sGridNo(NOWHERE), bCover(INVALID_COVER), fInverseColor(FALSE), bMines(MINES_ALL), bTrait(TRAIT_ALL) {}
};
@@ -111,6 +121,13 @@ enum MINES_DRAW_MODE {
MINES_DRAW_MAX
};
// Flugente: trait draw mode
enum TRAIT_DRAW_MODE {
TRAIT_DRAW_OFF,
TRAIT_DRAW_RANGE,
TRAIT_DRAW_MAX
};
//****** Local Variables *********************************************
@@ -124,6 +141,8 @@ COVER_DRAW_MODE gubDrawMode = COVER_DRAW_OFF;
MINES_DRAW_MODE gubDrawModeMine = MINES_DRAW_OFF; // Flugente: mines display
TRAIT_DRAW_MODE gubDrawModeTrait = TRAIT_DRAW_OFF; // Flugente: mines display
//******* Local Function Prototypes ***********************************
@@ -138,7 +157,7 @@ void AddCoverObjectsToViewArea();
void RemoveCoverObjectsFromViewArea();
void RemoveMinesObjectsFromViewArea(); // added by Flugente, has to be declared here
void RemoveTraitObjectsFromViewArea();
void CalculateCover();
void CalculateCoverForSoldier( SOLDIERTYPE* pForSoldier, const INT32& sTargetGridNo, const BOOLEAN& fRoof, INT8& bCover );
@@ -746,11 +765,6 @@ void ToggleHostileTrapsView()
void ToggleTrapNetworkView()
{
SwitchMinesDrawModeForNetworks();
/*if (gubDrawModeMine == MINES_DRAW_PLAYERTEAM_NETWORKS) {
SwitchMineViewOff();
} else {
SwitchToTrapNetworkView();
}*/
}
void SwitchMinesDrawModeForNetworks()
@@ -797,19 +811,6 @@ void SwitchMinesDrawModeForNetworks()
DisplayMines(TRUE);
break;
}
/*switch(gubDrawModeMine)
{
case MINES_DRAW_OFF:
SwitchToTrapNetworkView();
break;
case MINES_DRAW_PLAYERTEAM_NETWORKS:
SwitchToHostileTrapsView();
break;
default:
SwitchMineViewOff();
break;
}*/
}
///END key binding functions
@@ -1254,3 +1255,270 @@ void DetermineMineDisplayInTile( INT32 sGridNo, INT8 bLevel, INT8& bMines, BOOLE
}
}
// ----------------------------- trait range display after this ----------------------------------------
// added by Flugente
//******* Local Function Prototypes ***********************************
TileDefines GetTileTraitIndex( const INT8& bTrait );
void AddTraitObjectsToViewArea();
void CalculateTraitRange();
BOOLEAN TraitTileHasAdjTile( const INT32& ubX, const INT32& ubY, const INT32& ubZ );
UINT32 usDisplayTrait = NO_SKILLTRAIT_NT;
INT32 sTraitgridNo = NOWHERE;
///BEGIN key binding functions
void ToggleTraitRangeView(BOOLEAN fOn)
{
if ( fOn )
{
gubDrawModeTrait = TRAIT_DRAW_RANGE;
gubDrawMode = COVER_DRAW_OFF;
gubDrawModeMine = MINES_DRAW_OFF;
}
else
{
gubDrawModeTrait = TRAIT_DRAW_OFF;
SetTraitToDisplay( NO_SKILLTRAIT_NT );
SetGridNoForTraitDisplay( NOWHERE );
}
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Display trait ranges");
DisplayTraitRange(TRUE);
}
void SetTraitToDisplay( UINT32 aTrait )
{
usDisplayTrait = aTrait;
}
void SetGridNoForTraitDisplay( INT32 sGridNo )
{
sTraitgridNo = sGridNo;
}
void DisplayTraitRange( const BOOLEAN& forceUpdate )
{
if ( gGameExternalOptions.ubCoverDisplayUpdateWait == -1 )
{
return;
}
if ( forceUpdate || ( !gfScrollPending && !gfScrollInertia && GetTickCount() > guiMinesNextUpdateTime ) )
{
CalculateTraitRange();
guiMinesNextUpdateTime = GetTickCount() + gGameExternalOptions.ubCoverDisplayUpdateWait;
}
}
void CalculateTraitRange()
{
INT32 ubX, ubY, ubZ;
SOLDIERTYPE* pSoldier;
RemoveTraitObjectsFromViewArea();
if ( gubDrawModeTrait == TRAIT_DRAW_OFF )
return;
if( gusSelectedSoldier == NOBODY || !GetSoldier( &pSoldier, gusSelectedSoldier ) )
return;
UINT16 range1 = 0;
UINT16 range2 = 0;
switch ( usDisplayTrait )
{
case RADIO_OPERATOR_NT:
{
// we 'mark' the map position with which we called the menu, so that the player sees where he is targetting
}
break;
default:
return;
}
//remove other displays
if( gubDrawModeMine != MINES_DRAW_OFF )
RemoveMinesObjectsFromViewArea();
if ( gubDrawMode != COVER_DRAW_OFF )
RemoveCoverObjectsFromViewArea();
const INT32& sSelectedSoldierGridNo = MercPtrs[ gusSelectedSoldier ]->sGridNo;
INT16 usTmp;
GetScreenXYWorldCell( gsVIEWPORT_START_X, gsVIEWPORT_START_Y, &gsMineMinCellX, &usTmp );
GetScreenXYWorldCell( gsVIEWPORT_END_X, gsVIEWPORT_END_Y, &gsMineMaxCellX, &usTmp );
GetScreenXYWorldCell( gsVIEWPORT_END_X, gsVIEWPORT_START_Y, &usTmp, &gsMineMinCellY );
GetScreenXYWorldCell( gsVIEWPORT_START_X, gsVIEWPORT_END_Y, &usTmp, &gsMineMaxCellY );
for ( ubX=gsMineMinCellX; ubX<=gsMineMaxCellX; ++ubX )
{
for ( ubY=gsMineMinCellY; ubY<=gsMineMaxCellY; ++ubY )
{
for ( ubZ=0; ubZ<COVER_Z_CELLS; ++ubZ )
{
INT32& sGridNo = gCoverViewArea[ ubX ][ ubY ][ ubZ ].sGridNo;
GetGridNoForViewPort( ubX, ubY, sGridNo );
if( !GridNoOnScreenAndAround( sGridNo, 2 ) )
{
continue;
}
if ( !NewOKDestination( pSoldier, sGridNo, false, (INT8) ubZ ) )
{
continue;
}
// do not show stuff on roofs if ground is shown
if ( ubZ == I_ROOF_LEVEL && !IsTheRoofVisible( sGridNo ) )
{
continue;
}
// do not show stuff on ground if roof is shown
if ( ubZ == I_GROUND_LEVEL && IsTheRoofVisible( sGridNo ) )
{
continue;
}
if ( range1 && PythSpacesAway(sSelectedSoldierGridNo, sGridNo) == range1 )
gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait = TRAIT_1;
else if ( range2 && PythSpacesAway(sSelectedSoldierGridNo, sGridNo) == range2 )
gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait = TRAIT_2;
// mark the gridno we are targetting
else if ( PythSpacesAway(sTraitgridNo, sGridNo) == 1 )
gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait = TRAIT_1;
else
gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait = MAX_TRAIT;
}
}
}
AddTraitObjectsToViewArea();
}
void AddTraitObjectsToViewArea()
{
if (gsMineMaxCellY == -1)
{
return;
}
INT32 ubX, ubY, ubZ;
BOOLEAN fChanged = FALSE;
for ( ubX=gsMineMinCellX; ubX<=gsMineMaxCellX; ++ubX )
{
for ( ubY=gsMineMinCellY; ubY<=gsMineMaxCellY; ++ubY )
{
for ( ubZ=0; ubZ<COVER_Z_CELLS; ++ubZ )
{
INT32& sGridNo = gCoverViewArea[ ubX ][ ubY ][ ubZ ].sGridNo;
INT8& bTrait = gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait;
if ( bTrait != -1 && ( bTrait == TRAIT_1 || bTrait == TRAIT_2 ) )
{
TileDefines tile = GetTileTraitIndex( bTrait );
AddCoverObjectToWorld( sGridNo, tile, (BOOLEAN) ubZ );
fChanged = TRUE;
}
}
}
}
// Re-render the scene!
if ( fChanged )
{
SetRenderFlags( RENDER_FLAG_FULL );
}
}
TileDefines GetTileTraitIndex( const INT8& bTrait )
{
switch(bTrait)
{
case TRAIT_1:
return SPECIALTILE_COVER_5; // green
case TRAIT_2:
return SPECIALTILE_COVER_2; // orange
case TRAIT_ALL:
return SPECIALTILE_COVER_3; // yellow
case MAX_TRAIT:
default:
return SPECIALTILE_COVER_1; // red
}
}
BOOLEAN TraitTileHasAdjTile( const INT32& ubX, const INT32& ubY, const INT32& ubZ )
{
INT32 ubTX, ubTY;
for ( ubTX = ubX-1; ubTX <= ubX+1; ++ubTX )
{
if ( ubTX < 0 || ubTX > WORLD_COLS )
{
continue;
}
for ( ubTY = ubY-1; ubTY <= ubY+1; ++ubTY )
{
if ( ubTY < 0 || ubTY > WORLD_ROWS )
{
continue;
}
INT8& bTrait = gCoverViewArea[ ubTX ][ ubTY ][ ubZ ].bTrait;
if ( bTrait == TRAIT_1 || bTrait == TRAIT_2 )
{
return TRUE;
}
}
}
return FALSE;
}
void RemoveTraitObjectsFromViewArea()
{
if (gsMineMaxCellY == -1)
{
return;
}
INT32 ubX, ubY, ubZ;
BOOLEAN fChanged = FALSE;
for ( ubX=gsMineMinCellX; ubX<=gsMineMaxCellX; ++ubX )
{
for ( ubY=gsMineMinCellY; ubY<=gsMineMaxCellY; ++ubY )
{
for ( ubZ=0; ubZ<COVER_Z_CELLS; ++ubZ )
{
INT32& sGridNo = gCoverViewArea[ ubX ][ ubY ][ ubZ ].sGridNo;
INT8& bTrait = gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait;
if ( bTrait != -1 || TraitTileHasAdjTile( ubX, ubY, ubZ ))
{
TileDefines tile = GetTileTraitIndex( bTrait );
RemoveCoverObjectFromWorld( sGridNo, tile, (BOOLEAN) ubZ );
bTrait = -1;
fChanged = TRUE;
}
}
}
}
// Re-render the scene!
if ( fChanged )
{
SetRenderFlags( RENDER_FLAG_FULL );
}
}
+7
View File
@@ -50,5 +50,12 @@ void ToggleHostileTrapsView();
void SwitchMinesDrawModeForNetworks();
// ----------------------------- trait range display after this ----------------------------------------
// added by Flugente: display of ranges and areas of effects for traits
void DisplayTraitRange(const BOOLEAN& forceUpdate = FALSE);
void ToggleTraitRangeView(BOOLEAN fOn = TRUE);
void SetTraitToDisplay( UINT32 aTrait );
void SetGridNoForTraitDisplay( INT32 sGridNo );
#endif
+20
View File
@@ -2196,6 +2196,21 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
bNumRightIcons++;
}
// Flugente: icons for radio operator actions (not the assignment)
if ( MercPtrs[ pFace->ubSoldierID ]->bAssignment != RADIO_SCAN )
{
if ( MercPtrs[ pFace->ubSoldierID ]->bSoldierFlagMask & (SOLDIER_RADIO_OPERATOR_SCANNING|SOLDIER_RADIO_OPERATOR_LISTENING) )
{
DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 19 );
bNumRightIcons++;
}
else if ( MercPtrs[ pFace->ubSoldierID ]->bSoldierFlagMask & SOLDIER_RADIO_OPERATOR_JAMMING )
{
DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 20 );
bNumRightIcons++;
}
}
switch( pSoldier->bAssignment )
{
case DOCTOR:
@@ -2270,6 +2285,11 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
break;
case RADIO_SCAN:
sIconIndex_Assignment = 19;
fDoIcon_Assignment = TRUE;
break;
case MOVE_EQUIPMENT:
{
sIconIndex_Assignment = 15;
+81
View File
@@ -3946,6 +3946,23 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
}
}
// Flugente: display energy level of power packs
if ( HasItemFlag(pObject->usItem, POWER_PACK) )
{
if ( OVERHEATING_MAX_TEMPERATURE > 0 )
{
FLOAT energylevel = (*pObject)[0]->data.bTemperature / (FLOAT)OVERHEATING_MAX_TEMPERATURE;
UINT32 red = (UINT32) ( 255 * ( 1.0 - max(0, 2*energylevel - 1.0) ) );
UINT32 green = (UINT32) ( 255 * ( min(1.0, 2*energylevel) ) );
UINT32 blue = 0;
UINT16 colour = Get16BPPColor( FROMRGB( red, green, blue ) );
DrawItemUIBarEx( pObject, DRAW_ITEM_TEMPERATURE, sX, sY + sHeight-1, ITEMDESC_ITEM_STATUS_WIDTH, sHeight-1, colour, colour, TRUE, guiSAVEBUFFER);
}
}
// display symbol if we are leaning our weapon on something
// display only if eapon resting is allowed, display is allowed, item is a gun/launcher, we are a person, we hold the gun in our hand, and we are resting the gun
if ( gGameExternalOptions.fWeaponResting && gGameExternalOptions.fDisplayWeaponRestingIndicator && pItem->usItemClass & (IC_GUN | IC_LAUNCHER) && pSoldier && &(pSoldier->inv[pSoldier->ubAttackingHand]) == pObject && pSoldier->IsWeaponMounted() )
@@ -6771,6 +6788,22 @@ void RenderItemDescriptionBox( )
DrawItemUIBarEx( &(*iter), DRAW_ITEM_TEMPERATURE, sCenX+4, sCenY, ITEM_BAR_WIDTH, ITEM_BAR_HEIGHT, colour, colour, TRUE, guiSAVEBUFFER );
}
// Flugente: display energy level of power packs
else if ( HasItemFlag(iter->usItem, POWER_PACK) )
{
if ( OVERHEATING_MAX_TEMPERATURE > 0 )
{
FLOAT energylevel = (*iter)[0]->data.bTemperature / (FLOAT)OVERHEATING_MAX_TEMPERATURE;
UINT32 red = (UINT32) ( 255 * ( 1.0 - max(0, 2*energylevel - 1.0) ) );
UINT32 green = (UINT32) ( 255 * ( min(1.0, 2*energylevel) ) );
UINT32 blue = 0;
UINT16 colour = Get16BPPColor( FROMRGB( red, green, blue ) );
DrawItemUIBarEx( &(*iter), DRAW_ITEM_TEMPERATURE, sCenX+4, sCenY, ITEM_BAR_WIDTH, ITEM_BAR_HEIGHT, colour, colour, TRUE, guiSAVEBUFFER );
}
}
}
}
@@ -7017,6 +7050,54 @@ void RenderItemDescriptionBox( )
mprintf( usX, usY, pStr );
}
}
else if ( HasItemFlag(gpItemDescObject->usItem, POWER_PACK) )
{
if ( OVERHEATING_MAX_TEMPERATURE > 0 )
{
FLOAT energylevel = (*gpItemDescObject)[0]->data.bTemperature / (FLOAT)OVERHEATING_MAX_TEMPERATURE;
UINT32 red = (UINT32) ( 255 * ( 1.0 - max(0, 2*energylevel - 1.0) ) );
UINT32 green = (UINT32) ( 255 * ( min(1.0, 2*energylevel) ) );
UINT32 blue = 0;
UINT8 stringNum = 5;
if ( energylevel > 0.8f )
stringNum = 1;
else if ( energylevel > 0.6f )
stringNum = 2;
else if ( energylevel > 0.4f )
stringNum = 3;
else if ( energylevel > 0.2f )
stringNum = 4;
// UDB system displays a string with colored condition text.
int regionindex = 7;
SetFontForeground( ForegroundColor );
swprintf( pStr, L"%s", gPowerPackDesc[STR_POWERPACK_BEGIN] ); // "Temperature is "
mprintf( gItemDescTextRegions[regionindex].sLeft, gItemDescTextRegions[regionindex].sTop, pStr );
// Record length
INT16 indent = StringPixLength( gPowerPackDesc[STR_POWERPACK_BEGIN], ITEMDESC_FONT );
swprintf( pStr, L"%s", gPowerPackDesc[stringNum] );
SetRGBFontForeground( red, green, blue );
mprintf( gItemDescTextRegions[regionindex].sLeft+indent+2, gItemDescTextRegions[regionindex].sTop, pStr );
// Record length
indent += StringPixLength( gPowerPackDesc[stringNum], ITEMDESC_FONT );
SetFontForeground( ForegroundColor );
swprintf( pStr, L"%s", gPowerPackDesc[STR_POWERPACK_END] ); // "."
mprintf( gItemDescTextRegions[regionindex].sLeft + indent + 2, gItemDescTextRegions[regionindex].sTop, pStr );
// to get the text to the left side...
swprintf( pStr, L"");
FindFontRightCoordinates( gItemDescTextRegions[regionindex].sLeft, gItemDescTextRegions[regionindex].sTop, gItemDescTextRegions[regionindex].sRight - gItemDescTextRegions[regionindex].sLeft ,gItemDescTextRegions[regionindex].sBottom - gItemDescTextRegions[regionindex].sTop ,pStr, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY, pStr );
}
}
// UDB system displays a string with colored condition text.
SetFontForeground( ForegroundColor );
+7
View File
@@ -508,6 +508,13 @@ void DrawItemUIBarEx( OBJECTTYPE *pObject, UINT8 ubStatus, INT16 sXPos, INT16 sY
{
sValue = 100;
}
else if ( HasItemFlag(pObject->usItem, POWER_PACK) )
{
if ( OVERHEATING_MAX_TEMPERATURE > 0 )
{
sValue = (INT16) ( 100 * (*pObject)[0]->data.bTemperature / (FLOAT)OVERHEATING_MAX_TEMPERATURE );
}
}
else
{
sValue = (INT16) (100 * GetGunOverheatJamPercentage( pObject) );
+12 -7
View File
@@ -714,10 +714,10 @@ extern OBJECTTYPE gTempObject;
#define TRIPWIRE_NETWORK_LVL_3 0x00400000 //4194304
#define TRIPWIRE_NETWORK_LVL_4 0x00800000 //8388608
/*#define TRIPWIRE_NETWORK_LVL_1 0x01000000 //16777216
#define TRIPWIRE_NETWORK_LVL_2 0x02000000 //33554432
#define TRIPWIRE_NETWORK_LVL_3 0x04000000 //67108864
#define TRIPWIRE_NETWORK_LVL_4 0x08000000 //134217728
#define ARTILLERY_STRIKE_COUNT_1 0x01000000 //16777216
#define ARTILLERY_STRIKE_COUNT_2 0x02000000 //33554432
#define ARTILLERY_STRIKE_COUNT_4 0x04000000 //67108864
/*#define TRIPWIRE_NETWORK_LVL_4 0x08000000 //134217728
#define PLAYER_NET_1_LVL_4 0x10000000 //268435456
#define PLAYER_NET_2_LVL_4 0x20000000 //536870912
@@ -725,6 +725,8 @@ extern OBJECTTYPE gTempObject;
#define PLAYER_NET_4_LVL_4 0x80000000 //2147483648*/
// ----------------------------------------------------------------
#define ANY_ARTILLERY_FLAG (ARTILLERY_STRIKE_COUNT_1|ARTILLERY_STRIKE_COUNT_2|ARTILLERY_STRIKE_COUNT_4)
// -------- added by Flugente: various item flags --------
// flags used for various item properties (easier than adding 32 differently named variables). DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
// note that these should not be used to determine what kind of an attachment an item is, that is determined by attachmentclass and the AC_xxx flags above
@@ -759,9 +761,9 @@ extern OBJECTTYPE gTempObject;
#define SCUBA_FINS 0x00800000 //8388608 // this item speed up swimming, but slows walking and running
#define TRIPWIREROLL 0x01000000 //16777216 // this item is a tripwire roll
/*#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 RADIO_SET 0x02000000 //33554432 // item can be used to radio militia/squads in other sectors
#define SIGNAL_SHELL 0x04000000 //67108864 // this is a signal shell that precedes artillery barrages
#define POWER_PACK 0x08000000 //134217728 // item continously powers an item it is attached to
#define PLAYER_NET_1_LVL_4 0x10000000 //268435456
#define PLAYER_NET_2_LVL_4 0x20000000 //536870912
@@ -1856,6 +1858,9 @@ enum
IMP_COVERT,
IMP_COVERT_EXP,
// Flugente: added radio operator
IMP_RADIO_OPERATOR,
MAX_IMP_ITEM_TYPES
};
+6
View File
@@ -7822,6 +7822,12 @@ BOOLEAN CreateItem( UINT16 usItem, INT16 bStatus, OBJECTTYPE * pObj )
(*pObj)[0]->data.bTemperature = OVERHEATING_MAX_TEMPERATURE;
}
// Flugente: certain items get the maximum temperature when they are created
if ( HasItemFlag(usItem, POWER_PACK) )
{
(*pObj)[0]->data.bTemperature = (FLOAT)(OVERHEATING_MAX_TEMPERATURE);
}
//ADB ubWeight has been removed, see comments in OBJECTTYPE
//pObj->ubWeight = CalculateObjectWeight( pObj );
fRet = TRUE;
+1
View File
@@ -494,6 +494,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)
INT8 sRadioScanModifier; // modifies the scan range of the radio scan assignment in this sector
UINT16 usPrisonRoomNumber[MAX_PRISON_ROOMS]; // room numbers of prisons
} SECTOR_EXT_DATA;
+7 -2
View File
@@ -1009,7 +1009,8 @@ void HandleShadingOfLinesForMilitiaControlMenu( void )
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
{
// Check LOS!
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->pathing.bLevel, 3, TRUE, CALC_FROM_ALL_DIRS ) )
// Flugente: active radio sets allows us to give individual orders even without a line of sight
if ( pSoldier->CanUseRadio() || SoldierTo3DLocationLineOfSightTest( pSoldier, pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->pathing.bLevel, 3, TRUE, CALC_FROM_ALL_DIRS ) )
{
UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ATTACK );
UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_HOLD );
@@ -1069,7 +1070,11 @@ BOOLEAN CheckIfRadioIsEquipped( void )
//pSoldier = GetSelectedAssignSoldier( FALSE ); //do not use
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
{
{
// Flugente: active radio sets also count as radio
if ( pSoldier->CanUseRadio() )
return TRUE;
//bSlot = FindObj( pSoldier, EXTENDEDEAR );
bSlot = FindHearingAid(pSoldier);
//ScreenMsg( FONT_WHITE, MSG_INTERFACE, L"Position: %d", bSlot );
+677
View File
@@ -0,0 +1,677 @@
/**
* @file
* @author Flugente (bears-pit.com)
*/
#include "SkillMenu.h"
#include "Soldier Profile Type.h"
#include "Overhead.h"
#include "Text.h"
#include "Isometric Utils.h"
#include "DisplayCover.h"
#include "worldman.h"
UINT16 usTraitMenuPosX = 0;
UINT16 usTraitMenuPosY = 0;
INT32 sTraitsMenuTargetGridNo = NOWHERE;
void Hide( void )
{
// set off display of trait range/target gridno
ToggleTraitRangeView(FALSE);
// Dirty!
fMapPanelDirty = TRUE;
}
// Turns an option off by always returning FALSE
BOOLEAN Popup_OptionOff( void ) { return FALSE; }
void
SkillMenuItem::SetupPopup(CHAR* name)
{
// create a popup
gPopup = new POPUP(name);
// add a callback that lets the keyboard handler know we're done (and ready to pop up again)
gPopup->setCallback(POPUP_CALLBACK_HIDE, new popupCallbackFunction<void, void>( &Hide ) );
}
// Different SkillItem classes. We need wrappers for each one, as we cannot pass a pointer to a member function (we need a concrete object)
/////////////////////////////// Trait Selection ////////////////////////////////////////////
TraitSelection gTraitSelection;
//void Wrapper_Function_TraitSelection( UINT32 aVal) { gTraitSelection.Functions(aVal); }
void Wrapper_Setup_TraitSelection( UINT32 aVal) { gTraitSelection.Setup(aVal); }
void Wrapper_Cancel_TraitSelection( UINT32 aVal ) { gTraitSelection.Cancel(); }
/////////////////////////////// Trait Selection ////////////////////////////////////////////
/////////////////////////////// Skill Selection ////////////////////////////////////////////
SkillSelection gSkillSelection;
void Wrapper_Function_SkillSelection( UINT32 aVal) { gSkillSelection.Functions(aVal); }
void Wrapper_Setup_SkillSelection( UINT32 aVal) { gSkillSelection.Setup(aVal); }
void Wrapper_Cancel_SkillSelection( UINT32 aVal ) { gSkillSelection.Cancel(); }
/////////////////////////////// Skill Selection ////////////////////////////////////////////
/////////////////////////////// Artillery Sector Selection ////////////////////////////////////////////
ArtillerySector gArtillerySector;
//void Wrapper_Function_ArtillerySector( UINT32 aVal) { gArtillerySector.Functions(aVal); }
void Wrapper_Setup_ArtillerySector( UINT32 aVal) { gArtillerySector.Setup(aVal); }
void Wrapper_Cancel_ArtillerySector( UINT32 aVal ) { gArtillerySector.Cancel(); }
/////////////////////////////// Artillery Sector Selection ////////////////////////////////////////////
/////////////////////////////// Artillery Team Selection ////////////////////////////////////////////
ArtilleryTeam gArtilleryTeam;
void Wrapper_Function_ArtilleryTeam( UINT32 aVal) { gArtilleryTeam.Functions(aVal); }
void Wrapper_Setup_ArtilleryTeam( UINT32 aVal) { gArtilleryTeam.Setup(aVal); }
void Wrapper_Cancel_ArtilleryTeam( UINT32 aVal ) { gArtilleryTeam.Cancel(); }
/////////////////////////////// Artillery Team Selection ////////////////////////////////////////////
/////////////////////////////// Reinforcement Sector Selection ////////////////////////////////////////////
ReinforcementSector gReinforcementSector;
//void Wrapper_Function_ReinforcementSector( UINT32 aVal) { gReinforcementSector.Functions(aVal); }
void Wrapper_Setup_ReinforcementSector( UINT32 aVal) { gReinforcementSector.Setup(aVal); }
void Wrapper_Cancel_ReinforcementSector( UINT32 aVal ) { gReinforcementSector.Cancel(); }
/////////////////////////////// Reinforcement Sector Selection ////////////////////////////////////////////
/////////////////////////////// Reinforcement Number Selection ////////////////////////////////////////////
ReinforcementNumber gReinforcementNumber;
void Wrapper_Function_ReinforcementNumber( UINT32 aVal) { gReinforcementNumber.Functions(aVal); }
void Wrapper_Setup_ReinforcementNumber( UINT32 aVal) { gReinforcementNumber.Setup(aVal); }
void Wrapper_Cancel_ReinforcementNumber( UINT32 aVal ) { gReinforcementNumber.Cancel(); }
/////////////////////////////// Reinforcement Number Selection ////////////////////////////////////////////
/////////////////////////////// Soldier Target Selection ////////////////////////////////////////////
SoldierSelection gSoldierSelection;
void Wrapper_Function_SoldierSelection( UINT32 aVal) { gSoldierSelection.Functions(aVal); }
void Wrapper_Setup_SoldierSelection( UINT32 aVal) { gSoldierSelection.Setup(aVal); }
void Wrapper_Cancel_SoldierSelection( UINT32 aVal ) { gSoldierSelection.Cancel(); }
/////////////////////////////// Soldier Target Selection ////////////////////////////////////////////
/////////////////////////////// Trait Selection ////////////////////////////////////////////
void
TraitSelection::Setup( UINT32 aVal )
{
Destroy();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL )
return;
SetupPopup("TraitSelection");
POPUP_OPTION *pOption;
CHAR16 pStr[300];
// create entries for the sub-menus for each trait
const UINT8 num = 1;
UINT8 traitarray[num];
traitarray[0] = RADIO_OPERATOR_NT;
for ( int i = 0; i < num; ++i)
{
swprintf( pStr, gzMercSkillTextNew[traitarray[i]] );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Setup_SkillSelection, traitarray[i] ) );
// if we cannot perform this skill, grey it out
if ( !HAS_SKILL_TRAIT(pSoldier, traitarray[i]) )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
}
// cancel option
swprintf( pStr, L"Cancel" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_TraitSelection, 0 ) );
GetPopup()->addOption( *pOption );
// grab soldier's x,y screen position
INT16 sX, sY;
GetSoldierScreenPos( pSoldier, &sX, &sY );
if( sX < 0 ) sX = 0;
if( sY < 0 ) sY = 0;
usTraitMenuPosX = sX + 30;
usTraitMenuPosY = sY;
if ( ( usTraitMenuPosX + 400 ) > SCREEN_WIDTH )
usTraitMenuPosX = SCREEN_WIDTH - 400;
if ( ( usTraitMenuPosY + 130 ) > SCREEN_HEIGHT )
usTraitMenuPosY = SCREEN_HEIGHT - 190;
SetPos(usTraitMenuPosX, usTraitMenuPosY);
}
/////////////////////////////// Trait Selection ////////////////////////////////////////////
/////////////////////////////// Skill Selection ////////////////////////////////////////////
void
SkillSelection::Setup( UINT32 aVal )
{
Destroy();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL )
return;
if ( HAS_SKILL_TRAIT(pSoldier, aVal) )
{
SetupPopup("SkillSelection");
POPUP_OPTION *pOption;
CHAR16 pStr[300];
SetTraitToDisplay(aVal);
SetGridNoForTraitDisplay(sTraitsMenuTargetGridNo);
// this switch isn't really necessary. But dividing the skills into menus for each trait gives a better overview, and looks way better than a huge list
switch ( aVal )
{
case RADIO_OPERATOR_NT:
{
for(UINT32 uiCounter = SKILLS_RADIO_FIRST; uiCounter <= SKILLS_RADIO_LAST; ++uiCounter)
{
swprintf( pStr, pTraitSkillsMenuStrings[uiCounter] );
if ( uiCounter == SKILLS_RADIO_ARTILLERY)
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Setup_ArtillerySector, uiCounter ) );
else if ( uiCounter == SKILLS_RADIO_CALLREINFORCEMENTS)
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Setup_ReinforcementSector, uiCounter ) );
else
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Function_SkillSelection, uiCounter ) );
// if we cannot perform this skill, grey it out
if ( !(pSoldier->CanUseSkill(uiCounter, TRUE)) )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
}
}
break;
default:
break;
}
// certain traits have skills whose effects depend on wether eomeone is near to us (squadleader, commissar). We therefore display our radius of effect while this display is open
ToggleTraitRangeView(TRUE);
// cancel option
swprintf( pStr, L"Cancel" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_SkillSelection, 0 ) );
GetPopup()->addOption( *pOption );
}
// same y, different x
SetPos(gTraitSelection.GetMaxPosX(), usTraitMenuPosY);
if ( HAS_SKILL_TRAIT(pSoldier, aVal) )
{
UINT8 cnt = 0;
switch ( aVal )
{
case RADIO_OPERATOR_NT:
{
for(UINT32 uiCounter = SKILLS_RADIO_FIRST; uiCounter <= SKILLS_RADIO_LAST; ++uiCounter)
{
SetRegionFastHelpText( &(GetPopup()->MenuRegion[cnt++]), pSoldier->PrintSkillDesc(uiCounter) );
}
}
break;
}
}
}
void
SkillSelection::Functions( UINT32 aVal )
{
Cancel();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL )
return;
UINT8 ubID = WhoIsThere2(sTraitsMenuTargetGridNo, 0 );
pSoldier->UseSkill(aVal, sTraitsMenuTargetGridNo, ubID);
Cancel();
gTraitSelection.Cancel();
}
/////////////////////////////// Skill Selection ////////////////////////////////////////////
/////////////////////////////// Artillery Sector Selection ////////////////////////////////////////////
void
ArtillerySector::Setup( UINT32 aVal )
{
Destroy();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL )
return;
if ( pSoldier->CanUseSkill(SKILLS_RADIO_ARTILLERY) )
{
SetupPopup("ArtillerySector");
POPUP_OPTION *pOption;
CHAR16 pStr[300];
// check wether we can call artillery from the 4 adjacent sectors
for (UINT8 i = 0; i < 4; ++i)
{
INT16 loopX = pSoldier->sSectorX;
INT16 loopY = pSoldier->sSectorY;
if ( i == 0 ) ++loopY;
else if ( i == 1 ) ++loopX;
else if ( i == 2 ) --loopY;
else if ( i == 3 ) --loopX;
if ( loopX < 1 || loopX >= MAP_WORLD_X - 1 || loopY < 1 || loopY >= MAP_WORLD_Y - 1 )
continue;
UINT32 sectornr = (UINT32)SECTOR( loopX, loopY );
swprintf( pStr, L"%c%d", loopY + 'A' - 1, loopX );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Setup_ArtilleryTeam, sectornr ) );
// grey out if no artillery can be called from this sector
if ( !IsValidArtilleryOrderSector( loopX, loopY, pSoldier->bSectorZ, pSoldier->bTeam ) && !IsValidArtilleryOrderSector( loopX, loopY, pSoldier->bSectorZ, MILITIA_TEAM ) )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
}
// cancel option
swprintf( pStr, L"Cancel" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_ArtillerySector, 0 ) );
GetPopup()->addOption( *pOption );
}
// same y, different x
SetPos(gSkillSelection.GetMaxPosX(), usTraitMenuPosY);
}
/////////////////////////////// Artillery Sector Selection ////////////////////////////////////////////
/////////////////////////////// Artillery Team Selection ////////////////////////////////////////////
void
ArtilleryTeam::Setup( UINT32 aVal )
{
Destroy();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL )
return;
if ( pSoldier->CanUseSkill(SKILLS_RADIO_ARTILLERY) && pSoldier->bSectorZ == 0)
{
usSector = aVal;
SetupPopup("ArtilleryTeam");
POPUP_OPTION *pOption;
CHAR16 pStr[300];
// determine sector coordinates
INT16 sSectorX = SECTORX(usSector);
INT16 sSectorY = SECTORY(usSector);
// order artillery from militia
swprintf( pStr, L"Militia" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ArtilleryTeam, MILITIA_TEAM ) );
// grey out if no ArtilleryTeam can be called from this sector
if ( !IsValidArtilleryOrderSector( sSectorX, sSectorY, pSoldier->bSectorZ, MILITIA_TEAM ) )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
// order artillery from our mercs
swprintf( pStr, L"Other Squads" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, INT8>( &Wrapper_Function_ArtilleryTeam, pSoldier->bTeam ) );
// grey out if no ArtilleryTeam can be called from this sector
if ( !IsValidArtilleryOrderSector( sSectorX, sSectorY, pSoldier->bSectorZ, pSoldier->bTeam ) )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
// cancel option
swprintf( pStr, L"Cancel" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_ArtilleryTeam, 0 ) );
GetPopup()->addOption( *pOption );
}
// same y, different x
SetPos(gArtillerySector.GetMaxPosX(), usTraitMenuPosY);
}
void
ArtilleryTeam::Functions( UINT32 aVal )
{
Cancel();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL || !pSoldier->CanUseSkill(SKILLS_RADIO_ARTILLERY) )
return;
pSoldier->OrderArtilleryStrike(usSector, sTraitsMenuTargetGridNo, (UINT8)(aVal));
Cancel();
gArtillerySector.Cancel();
gSkillSelection.Cancel();
gTraitSelection.Cancel();
}
/////////////////////////////// Artillery Team Selection ////////////////////////////////////////////
/////////////////////////////// Reinforcement Sector Selection ////////////////////////////////////////////
extern UINT8 CountAllMilitiaInSector(INT16 sMapX, INT16 sMapY);
void
ReinforcementSector::Setup( UINT32 aVal )
{
Destroy();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL )
return;
if ( pSoldier->CanUseSkill(aVal) )
{
SetupPopup("Reinforcements sector");
POPUP_OPTION *pOption;
CHAR16 pStr[300];
// check wether we can call artillery from the 4 adjacent sectors
for (UINT8 i = 0; i < 4; ++i)
{
INT16 loopX = pSoldier->sSectorX;
INT16 loopY = pSoldier->sSectorY;
if ( i == 0 ) ++loopY;
else if ( i == 1 ) ++loopX;
else if ( i == 2 ) --loopY;
else if ( i == 3 ) --loopX;
if ( loopX < 1 || loopX >= MAP_WORLD_X - 1 || loopY < 1 || loopY >= MAP_WORLD_Y - 1 )
continue;
UINT32 sectornr = (UINT32)SECTOR( loopX, loopY );
swprintf( pStr, L"%c%d", loopY + 'A' - 1, loopX );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Setup_ReinforcementNumber, sectornr ) );
// grey out if no reinforcements can be called from this sector
if( !CountAllMilitiaInSector( loopX, loopY ) )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
}
// cancel option
swprintf( pStr, L"Cancel" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Cancel_ReinforcementSector, 0 ) );
GetPopup()->addOption( *pOption );
}
// same y, different x
SetPos(gSkillSelection.GetMaxPosX(), usTraitMenuPosY);
}
/////////////////////////////// Reinforcement Sector Selection ////////////////////////////////////////////
/////////////////////////////// Reinforcement Number Selection ////////////////////////////////////////////
void
ReinforcementNumber::Setup( UINT32 aVal )
{
Destroy();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL )
return;
if ( pSoldier->CanUseSkill(SKILLS_RADIO_CALLREINFORCEMENTS) )
{
usSector = aVal;
SetupPopup("Reinforcements number submenu");
POPUP_OPTION *pOption;
CHAR16 pStr[300];
UINT8 numberofmilitia = CountAllMilitiaInSector( SECTORX(usSector), SECTORY(usSector) );
// 5 militia option
swprintf( pStr, L"5 Militia" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, 5 ) );
if ( numberofmilitia < 5 )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
// 10 militia option
swprintf( pStr, L"10 Militia" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, 10 ) );
if ( numberofmilitia < 10 )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
// 15 militia option
swprintf( pStr, L"15 Militia" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, 15 ) );
if ( numberofmilitia < 15 )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
// 20 militia option
swprintf( pStr, L"20 Militia" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, 20 ) );
if ( numberofmilitia < 20 )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
// all militia option
swprintf( pStr, L"All Militia" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, numberofmilitia ) );
GetPopup()->addOption( *pOption );
// cancel option
swprintf( pStr, L"Cancel" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Cancel_ReinforcementNumber, 0 ) );
GetPopup()->addOption( *pOption );
}
// same y, different x
SetPos(gReinforcementSector.GetMaxPosX(), usTraitMenuPosY);
}
void
ReinforcementNumber::Functions( UINT32 aVal )
{
Cancel();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL || !pSoldier->CanUseSkill(SKILLS_RADIO_CALLREINFORCEMENTS) )
return;
pSoldier->RadioCallReinforcements(usSector, aVal);
Cancel();
gReinforcementSector.Cancel();
gSkillSelection.Cancel();
gTraitSelection.Cancel();
}
/////////////////////////////// Reinforcement Number Selection ////////////////////////////////////////////
/////////////////////////////// Soldier Target Selection ////////////////////////////////////////////
void
SoldierSelection::Setup( UINT32 aVal )
{
Destroy();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL )
return;
if ( pSoldier->CanUseSkill(aVal) )
{
usSkill = aVal;
SetupPopup("SoldierSelection");
POPUP_OPTION *pOption;
CHAR16 pStr[300];
// pretty simple: we find every soldier in a radius around the target position and add him to the list
// loop through all soldiers around
for ( UINT32 cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID ; cnt <= gTacticalStatus.Team[ CIV_TEAM ].bLastID ; ++cnt )
{
INT32 iRange = GetRangeInCellCoordsFromGridNoDiff( sTraitsMenuTargetGridNo, MercPtrs[ cnt ]->sGridNo );
if ( iRange < 100 )
{
if ( cnt != pSoldier->ubID )
{
swprintf( pStr, L"%s", MercPtrs[ cnt ]->GetName() );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT8>( &Wrapper_Function_SoldierSelection, cnt ) );
// grey out if no artillery can be called from this sector
if ( 0 )
{
// Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
}
GetPopup()->addOption( *pOption );
}
}
}
// cancel option
swprintf( pStr, L"Cancel" );
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_SoldierSelection, 0 ) );
GetPopup()->addOption( *pOption );
}
// same y, different x
SetPos(gSkillSelection.GetMaxPosX(), usTraitMenuPosY);
}
void
SoldierSelection::Functions( UINT32 aVal )
{
Cancel();
SOLDIERTYPE * pSoldier = NULL;
GetSoldier( &pSoldier, gusSelectedSoldier );
if ( pSoldier == NULL )
return;
pSoldier->UseSkill(usSkill, sTraitsMenuTargetGridNo, aVal);
Cancel();
gSkillSelection.Cancel();
gTraitSelection.Cancel();
}
/////////////////////////////// Soldier Target Selection ////////////////////////////////////////////
/**
* Flugente: traits menu popup box
* This will create other boxes when needed
*/
void TraitsMenu( INT32 usMapPos )
{
sTraitsMenuTargetGridNo = usMapPos;
gTraitSelection.Setup(0);
}
+165
View File
@@ -0,0 +1,165 @@
#ifndef _SKILL_MENU_
#define _SKILL_MENU_
/**
* @file
* @author Flugente (bears-pit.com)
*/
#include "popup_class.h"
/**
* @brief A basic class for popup menus
* Use this to create mensu calling other menus, each having various sub-options
* I tried to make this as orderly as possible. It's ugly, but much more clean than the first solution, which was a hardcoded mess.
* You will, however, still need wrapper functions (we use callbacks on member functions), see Implementation.
*/
class SkillMenuItem
{
public:
SkillMenuItem() :
fInitialized(FALSE), usPosX(0), gPopup(NULL)
{
}
virtual void Cancel()
{
// Hide the Filter Menu pop-up.
if (gPopup != NULL && fInitialized )
{
gPopup->hide();
}
}
virtual void Destroy()
{
// If we already have a popup, destroy it first. This ensures we get a fresh menu each time.
if ( fInitialized )
{
delete(gPopup);
gPopup = NULL;
fInitialized = FALSE;
}
}
UINT16 GetMaxPosX()
{
if ( gPopup )
return (usPosX + gPopup->getBoxDimensions().iRight);
return usPosX;
}
virtual void SetPos(UINT16 usX, UINT16 usY)
{
// same y, different x
usPosX = usX;
gPopup->setPosition( usPosX, usY );
fInitialized = TRUE;
gPopup->show();
}
void SetupPopup(CHAR* name);
POPUP* GetPopup()
{
return gPopup;
}
virtual void Setup( UINT32 aVal ) {}
virtual void Functions( UINT32 aVal ) {}
private:
BOOLEAN fInitialized;
UINT16 usPosX;
POPUP* gPopup;
};
// select a trait
class TraitSelection : public SkillMenuItem
{
public:
TraitSelection() {}
void Setup( UINT32 aVal );
};
// select a skill
class SkillSelection : public SkillMenuItem
{
public:
SkillSelection() : usSector(0) {}
void Setup( UINT32 aVal );
void Functions( UINT32 aVal );
private:
UINT32 usSector;
};
// select sector to call artillery from
class ArtillerySector : public SkillMenuItem
{
public:
ArtillerySector() {}
void Setup( UINT32 aVal );
};
// select team we request artillery from
class ArtilleryTeam : public SkillMenuItem
{
public:
ArtilleryTeam() : usSector(0) {}
void Setup( UINT32 aVal );
void Functions( UINT32 aVal );
private:
UINT32 usSector;
};
// select the sector we call reinforcements from
class ReinforcementSector : public SkillMenuItem
{
public:
ReinforcementSector() {}
void Setup( UINT32 aVal );
};
// select the number of milita that should reinforce
class ReinforcementNumber : public SkillMenuItem
{
public:
ReinforcementNumber() : usSector(0) {}
void Setup( UINT32 aVal );
void Functions( UINT32 aVal );
private:
UINT32 usSector;
};
// select an individual soldier as target of a skill
class SoldierSelection : public SkillMenuItem
{
public:
SoldierSelection() : usSkill(0) {}
void Setup( UINT32 aVal );
void Functions( UINT32 aVal );
private:
UINT32 usSkill;
};
/**
* Flugente: traits menu popup box
* This will create other boxes when needed
*/
void TraitsMenu( INT32 usMapPos );
#endif
File diff suppressed because it is too large Load Diff
+98 -26
View File
@@ -353,34 +353,34 @@ enum
// -------- added by Flugente: various flags for soldiers --------
// easier than adding 32 differently named variables. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
#define SOLDIER_DRUGGED 0x00000001 //1 // Soldier is on drugs
#define SOLDIER_NO_AP 0x00000002 //2 // Soldier has no APs this turn (fix for reinforcement bug)
#define SOLDIER_COVERT_CIV 0x00000004 //4 // Soldier is currently disguised as a civilian
#define SOLDIER_COVERT_SOLDIER 0x00000008 //8 // Soldier is currently disguised as an enemy soldier
#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 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 SOLDIER_DAMAGED_VEST 0x00000010 //16 // Soldier's vest is damaged (and thus can't be taken off)
#define SOLDIER_COVERT_NPC_SPECIAL 0x00000020 //32 // Special flag for NPCs when recruited (used for covert stuff)
#define SOLDIER_NEW_VEST 0x00000040 //64 // Soldier is wearing new vest. if having both vest and pants, he can disguise
#define SOLDIER_NEW_PANTS 0x00000080 //128 // Soldier is wearing new pants
#define SOLDIER_DAMAGED_VEST 0x00000010 //16 // Soldier's vest is damaged (and thus can't be taken off)
#define SOLDIER_COVERT_NPC_SPECIAL 0x00000020 //32 // Special flag for NPCs when recruited (used for covert stuff)
#define SOLDIER_NEW_VEST 0x00000040 //64 // Soldier is wearing new vest. if having both vest and pants, he can disguise
#define SOLDIER_NEW_PANTS 0x00000080 //128 // Soldier is wearing new pants
#define SOLDIER_DAMAGED_PANTS 0x00000100 //256 // Soldier's vest is damaged (and thus can't be taken off)
#define SOLDIER_HEADSHOT 0x00000200 //512 // last hit received was a headshot (attack to the head, so knifes/punches also work)
#define SOLDIER_POW 0x00000400 //1024 // we are a prisoner of war
#define SOLDIER_ASSASSIN 0x00000800 //2048 // we are an enemy assassin, and thus we will behave very different from normal enemies
#define SOLDIER_DAMAGED_PANTS 0x00000100 //256 // Soldier's vest is damaged (and thus can't be taken off)
#define SOLDIER_HEADSHOT 0x00000200 //512 // last hit received was a headshot (attack to the head, so knifes/punches also work)
#define SOLDIER_POW 0x00000400 //1024 // we are a prisoner of war
#define SOLDIER_ASSASSIN 0x00000800 //2048 // we are an enemy assassin, and thus we will behave very different from normal enemies
#define SOLDIER_POW_PRISON 0x00001000 //4096 // this guy is a prisoner of war in a prison sector. SOLDIER_POW refers to people we capture, this refers to people we hold captive
#define SOLDIER_EQUIPMENT_DROPPED 0x00002000 //8192 // under certain circumstances, militia can be ordered to drop their gear twice. Thus we set a marker to avoid that.
#define SOLDIER_ACCESSTEAMMEMBER 0x00004000 //16384 // this merc is accessing another team member'S inventory (via abusing the stealing mechanic)
#define SOLDIER_REDOFLASHLIGHT 0x00008000 //32768 // this flag signifies that we somehow interacted with the items in our hands. Thus we have to possible redo lighting from flashlights
#define SOLDIER_POW_PRISON 0x00001000 //4096 // this guy is a prisoner of war in a prison sector. SOLDIER_POW refers to people we capture, this refers to people we hold captive
#define SOLDIER_EQUIPMENT_DROPPED 0x00002000 //8192 // under certain circumstances, militia can be ordered to drop their gear twice. Thus we set a marker to avoid that.
#define SOLDIER_ACCESSTEAMMEMBER 0x00004000 //16384 // this merc is accessing another team member'S inventory (via abusing the stealing mechanic)
#define SOLDIER_REDOFLASHLIGHT 0x00008000 //32768 // this flag signifies that we somehow interacted with the items in our hands. Thus we have to possible redo lighting from flashlights
#define SOLDIER_LIGHT_OWNER 0x00010000 //65536 // we 'own' at least one light source (via flashlights)
#define SOLDIER_AIRDROP_BONUS 0x00020000 //131072 // backgrounds: special AP bonus during the first turn of an airdrop
#define SOLDIER_ASSAULT_BONUS 0x00040000 //262144 // backgrounds: our first turn in an assault
/*#define PLAYER_NET_4_LVL_1 0x00080000 //524288
#define SOLDIER_LIGHT_OWNER 0x00010000 //65536 // we 'own' at least one light source (via flashlights)
#define SOLDIER_AIRDROP_BONUS 0x00020000 //131072 // backgrounds: special AP bonus during the first turn of an airdrop
#define SOLDIER_ASSAULT_BONUS 0x00040000 //262144 // backgrounds: our first turn in an assault
#define SOLDIER_RADIO_OPERATOR_LISTENING 0x00080000 //524288 // radio operator is listening with his set
#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 SOLDIER_RADIO_OPERATOR_JAMMING 0x00100000 //1048576 // radio operator is jamming frequencies
#define SOLDIER_RADIO_OPERATOR_SCANNING 0x00200000 //2097152 // radio operator is scanning for jammers
/*#define PLAYER_NET_3_LVL_2 0x00400000 //4194304
#define PLAYER_NET_4_LVL_2 0x00800000 //8388608
#define PLAYER_NET_1_LVL_3 0x01000000 //16777216
@@ -423,6 +423,36 @@ enum
NUM_MTA,
};
//Flugente skills from traits and other sources
enum{
// psyker skills
SKILLS_FIRST = 0,
// radio operator
SKILLS_RADIO_FIRST = SKILLS_FIRST,
SKILLS_RADIO_ARTILLERY = SKILLS_RADIO_FIRST,
SKILLS_RADIO_JAM,
SKILLS_RADIO_SCAN_FOR_JAM,
SKILLS_RADIO_LISTEN,
SKILLS_RADIO_CALLREINFORCEMENTS,
SKILLS_RADIO_TURNOFF,
SKILLS_RADIO_LAST = SKILLS_RADIO_TURNOFF,
SKILLS_MAX,
};
// Flugente: certain skills/traits/taints add effects that require a counter, here are enums for these
enum {
SOLDIER_COUNTER_RADIO_ARTILLERY, // there is actually no need for an artillery timer, but we use one to forbid the same AI guy ordering multiple strikes at once
SOLDIER_COUNTER_MAX = 20, // enough space for fillers
};
// Flugente: certain skills/traits/taints require a cooldown timer
enum {
SOLDIER_COOLDOWN_MAX = 20, // enough space for fillers
};
// enum of uniform pieces
typedef struct
{
@@ -1297,12 +1327,17 @@ public:
UINT16 usSoldierProfile; // Flugente: allow linking to a xml-based profile specifiying name, visuals, traits etc.
// Flugente: sector ID for move items assignemnt
// Flugente: sector ID for move items assignment
UINT8 usItemMoveSectorID;
// Flugente: skill stuff
UINT8 usAISkillUse; // this variable allows the AI to remember which skill it wants to use
UINT16 usSkillCounter[SOLDIER_COUNTER_MAX]; // counters used for various skill/trait/taint effects
UINT32 usSkillCooldown[SOLDIER_COOLDOWN_MAX]; // cooldown used for various skill/trait/taint effects
// Flugente: Decrease this filler by 1 for each new UINT8 / BOOLEAN variable, so we can maintain savegame compatibility!!
// Note that we also have to account for padding, so you might need to substract more than just the size of the new variables
UINT8 ubFiller[7];
UINT8 ubFiller[20];
#ifdef JA2UB
//ja25
@@ -1610,6 +1645,38 @@ public:
void SoldierPropertyUpkeep(); // update functions for various properties (updating counters, resetting flags etc.)
// Flugente: functions for skill usage
// traits can allow use of certain skills
// check if Soldier can use the spell skillwise, with fAPCheck = TRUE also check current APs
BOOLEAN CanUseSkill( INT8 iSkill, BOOLEAN fAPCheck = TRUE );
// use a skill. For safety reasons, this calls CanUseSkill again (it is possible to switch the soldier while the menu is open)
BOOLEAN UseSkill( UINT8 iSkill, INT32 usMapPos, UINT8 ID );
// is the AI allowed to use a skill? we have to check how much breath and life using this skill would cost, as otherwise the AI might commit suicide by casting
BOOLEAN IsAIAllowedtoUseSkill( INT8 iSkill );
// print a small description of the skill if we can use it, or its requirements if we cannot
STR16 PrintSkillDesc( INT8 iSkill);
// Flugente: functions for the radio operator trait
BOOLEAN CanUseRadio(); // can we use radio, if we even have one?
BOOLEAN UseRadio(); // simply drain the batteries
BOOLEAN HasMortar();
BOOLEAN GetSlotOfSignalShellIfMortar(UINT8* pbLoop); // if we have a mortar and a fitting signal shell, return the inventory slot it is in
BOOLEAN CanAnyArtilleryStrikeBeOrdered(UINT32* pSectorID); // can any artillery strikes be ordered by this guy's team from the neighbouring sectors?
BOOLEAN OrderArtilleryStrike( UINT32 usSectorNr, INT32 sTargetGridNo, UINT8 bTeam );
BOOLEAN IsJamming(); // are we currently jamming communication frequencies?
BOOLEAN JamCommunications();
BOOLEAN IsScanning();
BOOLEAN ScanForJam();
BOOLEAN IsRadioListening();
BOOLEAN RadioListen();
BOOLEAN RadioCallReinforcements( UINT32 usSector, UINT16 sNumber );
BOOLEAN SwitchOffRadio();
void RadioFail(); // display and error sound used either when the radio set fails or the sector is jammed - the player knows of the error, but cannot be sure of the cause
void DepleteActiveRadioSetEnergy(BOOLEAN fActivation = FALSE, BOOLEAN fAssignment = FALSE);
//////////////////////////////////////////////////////////////////////////////
}; // SOLDIERTYPE;
@@ -1737,7 +1804,12 @@ BOOLEAN ResolvePendingInterrupt( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType )
BOOLEAN AIDecideHipOrShoulderStance( SOLDIERTYPE * pSoldier, INT32 iGridNo );
BOOLEAN DecideAltAnimForBigMerc( SOLDIERTYPE * pSoldier );
BOOLEAN TwoStagedTrait( UINT8 uiSkillTraitNumber ); // Flugente: determine if this (new) trait has two stages
// added by Flugente
BOOLEAN TwoStagedTrait( UINT8 uiSkillTraitNumber ); // determine if this (new) trait has two stages
BOOLEAN GetRadioOperatorSignal(UINT8 usOwner, INT32* psTargetGridNo); // retrieve the gridno of a radio operator who (or whose team) ordered an artillery strike
BOOLEAN IsValidArtilleryOrderSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 bTeam ); // can an artillery strike be ordered FROM this sector
BOOLEAN SectorJammed();
BOOLEAN PlayerTeamIsScanning();
//typedef struct
class OLDSOLDIERTYPE_101
+28
View File
@@ -4630,6 +4630,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
BOOLEAN foundThrowing = FALSE;
BOOLEAN foundHtH = FALSE;
BOOLEAN foundMelee = FALSE;
BOOLEAN fRadioSetFound = FALSE;
// FIRST FIND OUT THE COMPOSITION OF OUR GEAR
for (bLoop = 0; bLoop < (INT8) pSoldier->inv.size(); bLoop++)
@@ -4653,6 +4654,8 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
else if (Item[pCreateStruct->Inv[bLoop].usItem].usItemClass == 128 && // 128 is an identifier of blunt melee weapons
Item[pCreateStruct->Inv[bLoop].usItem].uiIndex != 0 )
foundMelee = TRUE;
else if ( HasItemFlag(pCreateStruct->Inv[bLoop].usItem, RADIO_SET) )
fRadioSetFound = TRUE;
}
}
@@ -5191,6 +5194,31 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
}
}
}
// Flugente: new traits
if ( gGameOptions.fNewTraitSystem && (!ATraitAssigned || !BTraitAssigned || !CTraitAssigned ) )
{
// if we have a radio set, give us the corresponding trait so we can use it...
if ( fRadioSetFound )
{
if ( !ATraitAssigned )
{
pSoldier->stats.ubSkillTraits[0] = RADIO_OPERATOR_NT;
ATraitAssigned = TRUE;
}
else if ( !BTraitAssigned )
{
pSoldier->stats.ubSkillTraits[1] = RADIO_OPERATOR_NT;
BTraitAssigned = TRUE;
}
else if ( ubSolClass == SOLDIER_CLASS_ELITE || ubSolClass == SOLDIER_CLASS_ELITE_MILITIA )
{
pSoldier->stats.ubSkillTraits[2] = RADIO_OPERATOR_NT;
CTraitAssigned = TRUE;
return( TRUE ); // We no longer need to continue from here
}
}
}
}
// RETURN TRUE IF ALL TRAITS ASSIGNED OTHERWISE FALSE
if (( !gGameOptions.fNewTraitSystem && ATraitAssigned && BTraitAssigned ) || ( gGameOptions.fNewTraitSystem && ATraitAssigned && BTraitAssigned && CTraitAssigned ) )
+8
View File
@@ -578,6 +578,10 @@
RelativePath=".\SkillCheck.h"
>
</File>
<File
RelativePath=".\SkillMenu.h"
>
</File>
<File
RelativePath=".\Soldier Add.h"
>
@@ -904,6 +908,10 @@
RelativePath=".\SkillCheck.cpp"
>
</File>
<File
RelativePath=".\SkillMenu.cpp"
>
</File>
<File
RelativePath=".\Soldier Add.cpp"
>
+8
View File
@@ -582,6 +582,10 @@
RelativePath="SkillCheck.h"
>
</File>
<File
RelativePath="SkillMenu.h"
>
</File>
<File
RelativePath="Soldier Add.h"
>
@@ -906,6 +910,10 @@
RelativePath="SkillCheck.cpp"
>
</File>
<File
RelativePath="SkillMenu.cpp"
>
</File>
<File
RelativePath="Soldier Add.cpp"
>
+2
View File
@@ -83,6 +83,7 @@
<ClInclude Include="ShopKeeper Interface.h" />
<ClInclude Include="ShopKeeper Quotes.h" />
<ClInclude Include="SkillCheck.h" />
<ClInclude Include="SkillMenu.h" />
<ClInclude Include="Soldier Add.h" />
<ClInclude Include="Soldier Ani.h" />
<ClInclude Include="Soldier Control.h" />
@@ -165,6 +166,7 @@
<ClCompile Include="Rotting Corpses.cpp" />
<ClCompile Include="ShopKeeper Interface.cpp" />
<ClCompile Include="SkillCheck.cpp" />
<ClCompile Include="SkillMenu.cpp" />
<ClCompile Include="Soldier Add.cpp" />
<ClCompile Include="Soldier Ani.cpp" />
<ClCompile Include="Soldier Control.cpp" />
+6
View File
@@ -264,6 +264,9 @@
<ClInclude Include="Food.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SkillMenu.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Air Raid.cpp">
@@ -647,5 +650,8 @@
<ClCompile Include="XML_Background.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SkillMenu.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+11 -2
View File
@@ -114,7 +114,8 @@
#include "fresh_header.h"
#include "IMP Skill Trait.h" // added by Flugente
#include "IMP Skill Trait.h" // added by Flugente
#include "SkillMenu.h" // added by Flugente
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
@@ -2495,7 +2496,15 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
break;
case '$':
ChangeCurrentSquad( 13 );
{
// Flugente: trait skill selection menu. Yes, screw squad 13
INT32 usMapPos;
if ( GetMouseMapPos( &usMapPos ) )
{
TraitsMenu(usMapPos);
}
}
//ChangeCurrentSquad( 13 );
break;
case '%':
+81
View File
@@ -13019,4 +13019,85 @@ FLOAT CalcNewChanceToHitAimTraitBonus(SOLDIERTYPE *pSoldier, FLOAT fAimCap, FLOA
}
return fAimChance;
}
extern BOOLEAN IsRoofPresentAtGridNo( INT32 sGridNo );
// Flugente: fire item from A to B (intended for mortarshells and launchable grenades)
BOOLEAN ArtilleryStrike( UINT16 usItem, UINT32 usStartingGridNo, UINT32 usTargetMapPos )
{
FLOAT dForce, dDegrees;
INT16 sDestX, sDestY, sSrcX, sSrcY;
vector_3 vForce, vDirNormal;
INT16 sStartZ = ( 1 * 256 ) + 50;
INT16 sEndZ = 0;
// radius is way smaller for signal shells, otherwise the inaccuraccy would increase too much
INT8 bRadius = gSkillTraitValues.usVOMortarRadius;
if ( HasItemFlag(usItem, SIGNAL_SHELL) )
bRadius = gSkillTraitValues.usVOMortarSignalShellRadius;
INT32 sTargetGridNo = GetArtilleryTargetGridNo( usTargetMapPos, bRadius );
if ( TileIsOutOfBounds(sTargetGridNo) )
return FALSE;
UINT8 ubLevel = 0;
if ( IsRoofPresentAtGridNo( sTargetGridNo ) )
ubLevel = 1;
// create shell
OBJECTTYPE shellobj;
CreateItem( usItem, 100, &shellobj );
// Get basic launch params...
if ( !GetArtilleryLaunchParams(usStartingGridNo, sTargetGridNo, sStartZ, sEndZ, usItem, &shellobj, &dForce, &dDegrees) )
return FALSE;
// Get XY from gridno
ConvertGridNoToCenterCellXY( sTargetGridNo, &sDestX, &sDestY );
ConvertGridNoToCenterCellXY( usStartingGridNo, &sSrcX, &sSrcY );
// OK, get direction normal
vDirNormal.x = (float)(sDestX - sSrcX);
vDirNormal.y = (float)(sDestY - sSrcY);
vDirNormal.z = 0;
// NOmralize
vDirNormal = VGetNormal( &vDirNormal );
// From degrees, calculate Z portion of normal
vDirNormal.z = (float)sin( dDegrees );
// Do force....
vForce.x = dForce * vDirNormal.x;
vForce.y = dForce * vDirNormal.y;
vForce.z = dForce * vDirNormal.z;
float dX = (float)sSrcX;
float dY = (float)sSrcY;
float dZ = (float)sStartZ;
float dForceX = vForce.x;
float dForceY = vForce.y;
float dForceZ = vForce.z;
if ( Weapon[ usItem ].sSound != NO_WEAPON_SOUND )
{
PlayJA2Sample( Weapon[ usItem ].sSound, RATE_11025, SoundVolume( HIGHVOLUME, usStartingGridNo ), 1, SoundDir( usStartingGridNo ) );
}
INT32 iID = CreatePhysicalObject( &shellobj, -1, dX, dY, dZ, dForceX, dForceY, dForceZ, 0, THROW_ARM_ITEM, 0, FALSE );
// OJW - 20091002 - Explosives
/*if (is_networked && is_client)
{
if (pSoldier->bTeam == 0 || (pSoldier->bTeam == 1 && is_server))
{
send_grenade( &shellobj , dLifeSpan,dX, dY, dZ, dForceX, dForceY, dForceZ, sTargetGridNo, pSoldier->ubID, ubActionCode, uiActionData, iID , false);
}
}*/
//REAL_OBJECT* pObject = &( ObjectSlots[ iID ] );
return TRUE;
}
+3
View File
@@ -283,6 +283,7 @@ enum
EXPLOSV_CREATUREGAS,
EXPLOSV_BURNABLEGAS,
EXPLOSV_FLASHBANG,
EXPLOSV_SIGNAL_SMOKE,
};
#define AMMO_DAMAGE_ADJUSTMENT_BUCKSHOT( x ) (x / 4)
@@ -539,4 +540,6 @@ FLOAT GetOverheatJamThreshold( OBJECTTYPE *pObj );
FLOAT GetOverheatDamageThresholdModifier( OBJECTTYPE *pObj );
FLOAT GetOverheatDamageThreshold( OBJECTTYPE *pObj );
BOOLEAN ArtilleryStrike( UINT16 usItem, UINT32 usStartingGridNo, UINT32 usTargetMapPos );
#endif
+3
View File
@@ -136,6 +136,9 @@ explosiveEndElementHandle(void *userData, const XML_Char *name)
{
pData->curElement = ELEMENT;
pData->curExplosive.ubRadius = (UINT8) atol(pData->szCharData);
// Flugente: variable is UINT16, but is always used as UINT8, so better keep it in line
pData->curExplosive.ubRadius = max( 0, min(255, pData->curExplosive.ubRadius));
}
else if(strcmp(name, "ubVolume") == 0)
{
+4 -3
View File
@@ -161,19 +161,20 @@ typedef enum
// 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
RADIO_OPERATOR_NT, //21 // a minor trait
NUM_SKILLTRAITS_NT
} SkillTraitNew;
#define NUM_MAJOR_TRAITS 10
#define NUM_MINOR_TRAITS 10
#define NUM_MINOR_TRAITS 11
#define NUM_ORIGINAL_MAJOR_TRAITS 9
// 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
#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
+21
View File
@@ -298,3 +298,24 @@ FLOAT AICalcRecoilForShot( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon, UINT8 ubS
// HEADROCK HAM 4: Calculate average recoil offset for a shot.
FLOAT AICalcRecoilForShot( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon, UINT8 ubShotNum);
// Flugente AI functions
typedef BOOLEAN (*SOLDIER_CONDITION)( SOLDIERTYPE *pSoldier );
// determine a gridno that would allow us to hit as many enemies as possible given an effect with radius aRadius tiles
// return true if sufficent gridno is found
// pGridNo will be the GridNo
// aRadius is the area effect radius to use
// uCheckFriends: 0 - do not consider friends at all 1 - consider with negative weight else: ignore any location that might also hit friends
// sucess only if at a rating of at least aMinRating can be achieved
// any enemy soldiers not fulfilling cond will be excluded from this calculation
// if an enemy soldier fulfils taboo, make sure to not hit him at all!
BOOLEAN GetBestAoEGridNo(SOLDIERTYPE *pSoldier, INT32* pGridNo, INT16 aRadius, UINT8 uCheckFriends, UINT8 aMinRating, SOLDIER_CONDITION cond, SOLDIER_CONDITION taboo);
// Get the ID of the farthest opponent we can see, with an optional minimum range
// puID - ID of the farthest opponent pSoldier can see
// sRange - only return true and give an idea if opponent found is further away than this
BOOLEAN GetFarthestOpponent(SOLDIERTYPE *pSoldier, UINT8* puID, INT16 sRange);
// are there more allies than friends in adjacent sectors?
BOOLEAN MoreFriendsThanEnemiesinNearbysectors(UINT8 ausTeam, INT16 aX, INT16 aY, INT8 aZ);
+13
View File
@@ -2286,6 +2286,15 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
}
break;
case AI_ACTION_USE_SKILL:
{
UINT8 ubID = WhoIsThere2( pSoldier->aiData.usActionData, 0 );
pSoldier->UseSkill(pSoldier->usAISkillUse, pSoldier->aiData.usActionData, ubID);
ActionDone( pSoldier );
}
break;
default:
#ifdef BETAVERSION
NumMessage("ExecuteAction - Illegal action type = ",pSoldier->aiData.bAction);
@@ -2365,6 +2374,10 @@ void ATTACKTYPE::InitAttackType(ATTACKTYPE *pAttack)//dnl ch69 140913
void HandleInitialRedAlert( INT8 bTeam, UINT8 ubCommunicate)
{
// Flugente radio operator: if the sector is jammed, no radio communication possible
if ( SectorJammed() )
return;
/*
if (ubCommunicate)
{
+5 -2
View File
@@ -589,6 +589,10 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
bMinPointsNeeded = APBPConstants[AP_HANDCUFF];
break;
case AI_ACTION_USE_SKILL:
bMinPointsNeeded = 10; // TODO
break;
default:
#ifdef BETAVERSION
//NumMessage("AffordableAction - Illegal action type = ",pSoldier->aiData.bAction);
@@ -1909,9 +1913,8 @@ BOOLEAN InWaterGasOrSmoke( SOLDIERTYPE *pSoldier, INT32 sGridNo )
BOOLEAN InGasOrSmoke( SOLDIERTYPE *pSoldier, INT32 sGridNo )
{
// smoke
if (gpWorldLevelData[sGridNo].ubExtFlags[ pSoldier->pathing.bLevel ] & MAPELEMENT_EXT_SMOKE)
if (gpWorldLevelData[sGridNo].ubExtFlags[ pSoldier->pathing.bLevel ] & (MAPELEMENT_EXT_SMOKE|MAPELEMENT_EXT_SIGNAL_SMOKE) )
return TRUE;
return InGas(pSoldier,sGridNo);
+284
View File
@@ -24,6 +24,9 @@
#include "message.h"
#include "Vehicles.h"
#include "Soldier Functions.h"//dnl ch69 140913
#include "Reinforcement.h" // added by Flugente
#include "Town Militia.h" // added by Flugente
#include "Queen Command.h" // added by Flugente
#endif
extern INT16 DirIncrementer[8];
@@ -3191,3 +3194,284 @@ UINT8 UnderFire::Chance(INT8 bTeam)
}
return(cth);
}
// Flugente AI functions
// determine a gridno that would allow us to hit as many enemies as possible given an effect with radius aRadius tiles
// return true if sufficent gridno is found
// pGridNo will be the GridNo
// aRadius is the area effect radius to use
// uCheckFriends: 0 - do not consider friends at all 1 - consider with negative weight else: ignore any location that might also hit friends
// sucess only if at a rating of at least aMinRating can be achieved
// any enemy soldiers not fulfilling cond will be excluded from this calculation
// if an enemy soldier fulfils taboo, make sure to not hit him at all!
BOOLEAN GetBestAoEGridNo(SOLDIERTYPE *pSoldier, INT32* pGridNo, INT16 aRadius, UINT8 uCheckFriends, UINT8 aMinRating, SOLDIER_CONDITION cond, SOLDIER_CONDITION taboo)
{
UINT8 ubLoop, ubLoop2;
INT32 sGridNo, sFriendTile[MAXMERCS], sOpponentTile[MAXMERCS], sTabooTile[MAXMERCS];
UINT8 ubFriendCnt = 0,ubOpponentCnt = 0, ubTabooCnt = 0, ubOpponentID[MAXMERCS];
INT32 bMaxLeft,bMaxRight,bMaxUp,bMaxDown, i, j;
INT8 bPersOL, bPublOL;
SOLDIERTYPE *pFriend;
static INT16 sExcludeTile[100]; // This array is for storing tiles that we have
UINT8 ubNumExcludedTiles = 0; // already considered, to prevent duplication of effort
INT32 lowestX = 999999;
INT32 highestX = 0;
INT32 lowestY = 999999;
INT32 highestY = 0;
// make lists of enemies and friends
for (ubLoop = 0; ubLoop < guiNumMercSlots; ++ubLoop)
{
pFriend = MercSlots[ubLoop];
if ( !pFriend || !pFriend->bActive || !pFriend->bInSector )
continue;
if (pFriend->stats.bLife == 0)
continue;
// dying or captured friends are 'helpless' anyway, we are willing to sacrifice them :-)
if ( uCheckFriends && pSoldier->bSide == pFriend->bSide && pFriend->stats.bLife > OKLIFE && !(pFriend->bSoldierFlagMask & SOLDIER_POW) )
{
// active friend, remember where he is so that we DON'T blow him up!
// this includes US, since we don't want to blow OURSELVES up either
sFriendTile[ubFriendCnt] = pFriend->sGridNo;
ubFriendCnt++;
}
else
{
// if an enemy fulfills taboo, we will remember his tile and be careful not to ever hit it!
if ( taboo(pFriend) )
{
sTabooTile[ubTabooCnt] = pFriend->sGridNo;
++ubTabooCnt;
continue;
}
// Special stuff for Carmen the bounty hunter
if (pSoldier->aiData.bAttitude == ATTACKSLAYONLY && pFriend->ubProfile != 64)
continue;
// check wether this guy fulfills the target condition
if ( !cond(pFriend) )
continue;
bPersOL = pSoldier->aiData.bOppList[pFriend->ubID];
bPublOL = gbPublicOpplist[pSoldier->bTeam][pFriend->ubID];
if ( bPersOL == SEEN_CURRENTLY || bPublOL == SEEN_CURRENTLY )
{
// active KNOWN opponent, remember where he is so that we DO blow him up!
sOpponentTile[ubOpponentCnt] = pFriend->sGridNo;
}
else if ( bPersOL == SEEN_LAST_TURN || bPersOL == HEARD_LAST_TURN )
{
// cheat; only allow throw if person is REALLY within 2 tiles of where last seen
if ( SpacesAway( pFriend->sGridNo, gsLastKnownOppLoc[ pSoldier->ubID ][ pFriend->ubID ] ) < 3 )
{
sOpponentTile[ubOpponentCnt] = gsLastKnownOppLoc[ pSoldier->ubID ][ pFriend->ubID ];
}
}
else
{
continue;
}
// also remember who he is (which soldier #)
ubOpponentID[ubOpponentCnt] = pFriend->ubID;
// update lowest and highest x and y values
lowestX = min(lowestX, sOpponentTile[ubOpponentCnt] % MAXCOL );
highestX = max(highestX, sOpponentTile[ubOpponentCnt] % MAXCOL );
lowestY = min(lowestY, sOpponentTile[ubOpponentCnt] / MAXCOL );
highestY = max(highestY, sOpponentTile[ubOpponentCnt] / MAXCOL );
ubOpponentCnt++;
}
}
// no/not enough enemies found -> no area effect location advisable
if ( !ubOpponentCnt || ubOpponentCnt < aMinRating )
return FALSE;
BOOLEAN fGridNoFound = FALSE;
INT32 bestGridNo = -1;
INT8 bestGridNoCnt = aMinRating;
INT32 currentSoldierGridNo = -1;
INT8 enemiesnear = 0;
INT8 friendsnear = 0;
// look at the squares near each known opponent and try to find the one
// place where a tossed projectile would do the most harm to the opponents
// while avoiding one's friends
for (ubLoop = 0; ubLoop < ubOpponentCnt; ++ubLoop)
{
currentSoldierGridNo = sOpponentTile[ubLoop];
// determine maximum horizontal limits
bMaxLeft = max(currentSoldierGridNo % MAXCOL - aRadius, lowestX);
bMaxRight = min(currentSoldierGridNo % MAXCOL + aRadius, highestX);
// determine maximum vertical limits
bMaxDown = max(currentSoldierGridNo / MAXCOL - aRadius, lowestY);
bMaxUp = min(currentSoldierGridNo / MAXCOL + aRadius, highestY);
// evaluate every tile for its opponent-damaging potential
for (i = bMaxLeft; i <= bMaxRight; ++i)
{
for (j = bMaxDown; j <= bMaxUp; ++j)
{
// calculate the next potential gridno near this opponent
sGridNo = i + (MAXCOL * j);
// this shouldn't ever happen
if ((sGridNo < 0) || (sGridNo >= GRIDSIZE))
continue;
if ( PythSpacesAway( currentSoldierGridNo, sGridNo ) > aRadius )
continue;
// if this tile is taboo, don't even think about targetting it!
for (ubLoop2 = 0; ubLoop2 < ubTabooCnt; ++ubLoop2)
{
if (sTabooTile[ubLoop2] == sGridNo)
continue;
}
// Check to see if we have considered this tile before:
for (ubLoop2 = 0; ubLoop2 < ubNumExcludedTiles; ++ubLoop2)
{
if (sExcludeTile[ubLoop2] == sGridNo)
continue;
}
// add this tile to the list of alreay checked tiles
if ( ubNumExcludedTiles < 100 )
{
sExcludeTile[ubNumExcludedTiles] = sGridNo;
++ubNumExcludedTiles;
}
// loop over all enemies and friends to determine how many are in range
enemiesnear = 0;
friendsnear = 0;
// check whether there are any friends near this gridno
for (ubLoop2 = 0; ubLoop2 < ubFriendCnt; ++ubLoop2)
{
if ( PythSpacesAway(sFriendTile[ubLoop2], sGridNo) <= aRadius )
++friendsnear;
}
// ignore this location if friends are found and we want to absolutely ignore friendly fire
if ( friendsnear && uCheckFriends > 1 )
continue;
// check whether there are any enemies near this gridno
for (ubLoop2 = 0; ubLoop2 < ubOpponentCnt; ++ubLoop2)
{
if ( PythSpacesAway(sOpponentTile[ubLoop2], sGridNo) <= aRadius )
{
++enemiesnear;
}
}
if ( enemiesnear - friendsnear >= bestGridNoCnt )
{
bestGridNoCnt = enemiesnear - friendsnear;
bestGridNo = sGridNo;
fGridNoFound = TRUE;
}
}
}
}
*pGridNo = bestGridNo;
return fGridNoFound;
}
// Get the ID of the farthest opponent we can see, with an optional minimum range
// puID - ID of the farthest opponent pSoldier can see
// sRange - only return an true and give an idea if opponent found is further away than this
BOOLEAN GetFarthestOpponent(SOLDIERTYPE *pSoldier, UINT8* puID, INT16 sRange)
{
INT32 sGridNo;
UINT32 uiLoop;
INT32 iRange = 0;;
INT8 *pbPersOL;
SOLDIERTYPE * pOpp;
BOOLEAN found = FALSE;
*puID = NOBODY;
// look through this man's personal & public opplists for opponents known
for (uiLoop = 0; uiLoop < guiNumMercSlots; ++uiLoop)
{
pOpp = MercSlots[ uiLoop ];
// if this merc is inactive, at base, on assignment, or dead
if (!pOpp)
{
continue; // next merc
}
// if this merc is neutral/on same side, he's not an opponent
if ( CONSIDERED_NEUTRAL( pSoldier, pOpp ) || (pSoldier->bSide == pOpp->bSide))
{
continue; // next merc
}
// Special stuff for Carmen the bounty hunter
if (pSoldier->aiData.bAttitude == ATTACKSLAYONLY && pOpp->ubProfile != 64)
{
continue; // next opponent
}
pbPersOL = pSoldier->aiData.bOppList + pOpp->ubID;
// if this opponent is not seen personally
if (*pbPersOL != SEEN_CURRENTLY)
{
continue; // next merc
}
// since we're dealing with seen people, use exact gridnos
sGridNo = pOpp->sGridNo;
// if we are standing at that gridno(!, obviously our info is old...)
if (sGridNo == pSoldier->sGridNo)
{
continue; // next merc
}
// I hope this will be good enough; otherwise we need a fractional/world-units-based 2D distance function
//sRange = PythSpacesAway( pSoldier->sGridNo, sGridNo);
iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo );
if (iRange > sRange)
{
sRange = iRange;
*puID = uiLoop;
found = TRUE;
}
}
return( found );
}
// are there more allies than friends in adjacent sectors?
BOOLEAN MoreFriendsThanEnemiesinNearbysectors(UINT8 ausTeam, INT16 aX, INT16 aY, INT8 aZ)
{
UINT16 enemyteam = NumEnemiesInFiveSectors(aX, aY) - NumEnemiesInAnySector(aX, aY, aZ);
UINT16 militiateam = CountAllMilitiaInFiveSectors(aX, aY) - CountAllMilitiaInSector(aX, aY);
if ( ausTeam == ENEMY_TEAM )
return (enemyteam > militiateam);
return (militiateam > enemyteam);
}
+99
View File
@@ -2609,6 +2609,43 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
return(AI_ACTION_NONE);
}
}
// Flugente: trait skills
// if we are a radio operator
if ( HAS_SKILL_TRAIT( pSoldier, RADIO_OPERATOR_NT ) > 0 && pSoldier->CanUseSkill(SKILLS_RADIO_ARTILLERY, TRUE) )
{
UINT32 tmp;
INT32 skilltargetgridno = 0;
// call reinforcements if we haven't yet done so
if ( !gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition && MoreFriendsThanEnemiesinNearbysectors(pSoldier->bTeam, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ) )
{
// if frequencies are jammed...
if ( SectorJammed() )
{
// if we are jamming, turn it off, otherwise, bad luck...
if ( pSoldier->IsJamming() )
{
pSoldier->usAISkillUse = SKILLS_RADIO_TURNOFF;
pSoldier->aiData.usActionData = skilltargetgridno;
return(AI_ACTION_USE_SKILL);
}
}
// frequencies are clear, lets call for help
else
{
// raise alarm!
return( AI_ACTION_RED_ALERT );
}
}
// if we can't call in artillery, jam frequencies, so that the palyer can't use radio skills
else if ( !pSoldier->IsJamming() && !pSoldier->CanAnyArtilleryStrikeBeOrdered(&tmp) )
{
pSoldier->usAISkillUse = SKILLS_RADIO_JAM;
pSoldier->aiData.usActionData = skilltargetgridno;
return(AI_ACTION_USE_SKILL);
}
}
}
//RELOADING
@@ -3990,6 +4027,10 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
return(AI_ACTION_NONE);
}
// Flugente: dummies if we do not want to check for any conditions or taboos
BOOLEAN SoldierCondTrue(SOLDIERTYPE *pSoldier) { return TRUE; }
BOOLEAN SoldierCondFalse(SOLDIERTYPE *pSoldier) { return FALSE; }
INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
{
INT32 iCoverPercentBetter, iOffense, iDefense, iChance;
@@ -4363,6 +4404,64 @@ INT16 ubMinAPCost;
}
}
// Flugente: trait skills
// if we are a radio operator
if ( HAS_SKILL_TRAIT( pSoldier, RADIO_OPERATOR_NT ) > 0 && pSoldier->CanUseSkill(SKILLS_RADIO_ARTILLERY, TRUE) )
{
// check: would it be possible to call in artillery from neighbouring sectors?
UINT32 tmp;
INT32 skilltargetgridno = 0;
// can we call in artillery?
if ( pSoldier->CanAnyArtilleryStrikeBeOrdered(&tmp) )
{
// if frequencies are jammed...
if ( SectorJammed() )
{
// if we are jamming, turn it off, otherwise, bad luck...
if ( pSoldier->IsJamming() )
{
pSoldier->usAISkillUse = SKILLS_RADIO_TURNOFF;
pSoldier->aiData.usActionData = skilltargetgridno;
return(AI_ACTION_USE_SKILL);
}
}
// frequencies are clear, order a strike
else if ( GetBestAoEGridNo(pSoldier, &skilltargetgridno, max(1, gSkillTraitValues.usVOMortarRadius - 2), 1, 2, SoldierCondTrue, SoldierCondFalse) )
{
pSoldier->usAISkillUse = SKILLS_RADIO_ARTILLERY;
pSoldier->aiData.usActionData = skilltargetgridno;
return(AI_ACTION_USE_SKILL);
}
}
// no access to artillery... we can still call reinforcements if we haven't yet done so
else if ( !gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition && MoreFriendsThanEnemiesinNearbysectors(pSoldier->bTeam, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ) )
{
// if frequencies are jammed...
if ( SectorJammed() )
{
// if we are jamming, turn it off, otherwise, bad luck...
if ( pSoldier->IsJamming() )
{
pSoldier->usAISkillUse = SKILLS_RADIO_TURNOFF;
pSoldier->aiData.usActionData = skilltargetgridno;
return(AI_ACTION_USE_SKILL);
}
}
// frequencies are clear, lets call for help
else
{
// raise alarm!
return( AI_ACTION_RED_ALERT );
}
}
// if we can't call in artillery or reinforcements, then nobody else from our team can. So we better jam communications, so that the player cannot use these skills either
else if ( !pSoldier->IsJamming() )
{
pSoldier->usAISkillUse = SKILLS_RADIO_JAM;
pSoldier->aiData.usActionData = skilltargetgridno;
return(AI_ACTION_USE_SKILL);
}
}
BestShot.ubPossible = FALSE; // by default, assume Shooting isn't possible
BestThrow.ubPossible = FALSE; // by default, assume Throwing isn't possible
+1
View File
@@ -103,6 +103,7 @@ typedef enum
AI_ACTION_JUMP_WINDOW, // added by Flugente: jump through a window
AI_ACTION_FREE_PRISONER, // added by Flugente: free a prisoner
AI_ACTION_USE_SKILL, // added by Flugente: perform a skill, which one is stored in usAISkillUse
} ActionType;
+50
View File
@@ -374,6 +374,9 @@ void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32
// HEADROCK HAM 5: Deactivated until the release of HAM 5.1.
FireFragments( MercPtrs[ubOwner], sX, sY, sZ, usItem, ubDirection );
}
// Flugente: Items can have secondary explosions
HandleBuddyExplosions(ubOwner, sX, sY, sZ, sGridNo, usItem, fLocate, bLevel, ubDirection );
}
@@ -2225,6 +2228,13 @@ BOOLEAN ExpAffect( INT32 sBombGridNo, INT32 sGridNo, UINT32 uiDist, UINT16 usIte
bSmokeEffectType = CREATURE_SMOKE_EFFECT;
fBlastEffect = FALSE;
break;
case EXPLOSV_SIGNAL_SMOKE:
fSmokeEffect = TRUE;
bSmokeEffectType = SIGNAL_SMOKE_EFFECT;
fBlastEffect = FALSE;
break;
}
}
@@ -2872,6 +2882,7 @@ void SpreadEffect( INT32 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner,
case EXPLOSV_TEARGAS:
case EXPLOSV_SMOKE:
case EXPLOSV_CREATUREGAS:
case EXPLOSV_SIGNAL_SMOKE:
fSmokeEffect = TRUE;
break;
@@ -3993,6 +4004,25 @@ void HandleExplosionQueue( void )
// now add a tripwire item to the floor, simulating that activating tripwire deactivates it
AddItemToPool( sGridNo, &newtripwireObject, 1, ubLevel, 0, -1 );
}
else if ( (*pObj)[0]->data.ubWireNetworkFlag & ANY_ARTILLERY_FLAG )
{
UINT8 cnt = 0;
if ( (*pObj)[0]->data.ubWireNetworkFlag & ARTILLERY_STRIKE_COUNT_1 ) cnt += 1;
if ( (*pObj)[0]->data.ubWireNetworkFlag & ARTILLERY_STRIKE_COUNT_2 ) cnt += 2;
if ( (*pObj)[0]->data.ubWireNetworkFlag & ARTILLERY_STRIKE_COUNT_4 ) cnt += 4;
// determine gridno to attack - smoke signal required. Otherwise, it is assumed the radio operator ordered the bombing of his OWN position
// if we cannot even find a radio operator, all bets are off - target a random gridno
INT32 sTargetGridNo = -1;
if ( GetRandomSignalSmokeGridNo(&sTargetGridNo) || GetRadioOperatorSignal((*pObj)[0]->data.misc.ubBombOwner, &sTargetGridNo) || (sTargetGridNo = RandomGridNo()) )
{
for ( UINT8 i = 0; i < cnt; ++i)
ArtilleryStrike(pObj->usItem, sGridNo, sTargetGridNo);
}
// not needed anymore
RemoveItemFromPool( sGridNo, gWorldBombs[ uiWorldBombIndex ].iItemIndex, ubLevel );
}
else
{
gfExplosionQueueMayHaveChangedSight = TRUE;
@@ -5376,3 +5406,23 @@ void HandleSeeingPowerGenFan( UINT32 sGridNo )
}
}
#endif
void HandleBuddyExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection )
{
// Flugente: Items can have secondary explosions
if ( Item[usItem].usBuddyItem )
{
if ( Item[Item[usItem].usBuddyItem].flare )
{
if( !sZ || !FindBuilding(sGridNo) )
{
// Add a light effect...
NewLightEffect( sGridNo, (UINT8)Explosive[Item[Item[usItem].usBuddyItem].ubClassIndex].ubDuration , (UINT8)Explosive[Item[Item[usItem].usBuddyItem].ubClassIndex].ubStartRadius );
}
}
else if ( Item[Item[usItem].usBuddyItem ].usItemClass & (IC_GRENADE|IC_BOMB) )
{
IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, Item[usItem].usBuddyItem, bLevel, ubDirection );
}
}
}
+4
View File
@@ -159,4 +159,8 @@ extern void HandleSwitchToOpenFortifiedDoor( UINT32 sGridNo );
extern void HandleSeeingPowerGenFan( UINT32 sGridNo );
extern void HandleSeeingFortifiedDoor( UINT32 sGridNo );//Ja25 UB
#endif
// Flugente: handle secondary explosive effects
void HandleBuddyExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection );
#endif
+156 -91
View File
@@ -126,6 +126,10 @@ INT8 FromWorldFlagsToSmokeType( UINT16 ubWorldFlags )
{
return( BURNABLEGAS_SMOKE_EFFECT );
}
else if ( ubWorldFlags & MAPELEMENT_EXT_SIGNAL_SMOKE )
{
return( SIGNAL_SMOKE_EFFECT );
}
else
{
return( NO_SMOKE_EFFECT );
@@ -157,10 +161,15 @@ UINT16 FromSmokeTypeToWorldFlags( INT8 bType )
return( MAPELEMENT_EXT_BURNABLEGAS );
break;
case CREATURE_SMOKE_EFFECT:
case CREATURE_SMOKE_EFFECT:
return( MAPELEMENT_EXT_CREATUREGAS );
break;
return( MAPELEMENT_EXT_CREATUREGAS );
break;
case SIGNAL_SMOKE_EFFECT:
return( MAPELEMENT_EXT_SIGNAL_SMOKE );
break;
default:
@@ -250,7 +259,8 @@ INT32 NewSmokeEffect( INT32 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubOwner,
//ubStartRadius = 1;
//break;
case EXPLOSV_CREATUREGAS:
case EXPLOSV_CREATUREGAS:
bSmokeEffectType = CREATURE_SMOKE_EFFECT;
break;
@@ -259,11 +269,14 @@ INT32 NewSmokeEffect( INT32 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubOwner,
//bSmokeEffectType = CREATURE_SMOKE_EFFECT;
//ubDuration = 2;
//ubStartRadius = 0;
break;
//break;
case EXPLOSV_SIGNAL_SMOKE:
bSmokeEffectType = SIGNAL_SMOKE_EFFECT;
break;
}
pSmoke->ubDuration = (UINT8)Explosive[ Item[ usItem ].ubClassIndex ].ubDuration;
pSmoke->ubRadius = (UINT8)Explosive[ Item[ usItem ].ubClassIndex ].ubStartRadius;
pSmoke->bAge = 0;
@@ -372,99 +385,117 @@ void AddSmokeEffectToTile( INT32 iSmokeEffectID, INT8 bType, INT32 sGridNo, INT8
{
case NORMAL_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smkechze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalsmke.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\SMOKE.STI" );
}
}
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smkechze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalsmke.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\SMOKE.STI" );
}
}
break;
case TEARGAS_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\tearchze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smaltear.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\TEARGAS.STI" );
}
}
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\tearchze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smaltear.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\TEARGAS.STI" );
}
}
break;
case MUSTARDGAS_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\mustchze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalmust.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\MUSTARD2.STI" );
}
}
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\mustchze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalmust.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\MUSTARD2.STI" );
}
}
break;
case BURNABLEGAS_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\FLAMCHZE.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalflam.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\FLAMETH2.STI" );
}
}
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\FLAMCHZE.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalflam.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\FLAMETH2.STI" );
}
}
break;
case CREATURE_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
}
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
}
break;
case SIGNAL_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\signal_gas.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\signal_gas.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\signal_gas.STI" );
}
}
break;
}
// Create tile...
@@ -944,18 +975,52 @@ void UpdateSmokeEffectGraphics( )
//if the smoke is active
if( gSmokeEffectData[ uiCnt ].fAllocated )
{
if ( gSmokeEffectData[uiCnt].bFlags & SMOKE_EFFECT_ON_ROOF )
{
bLevel = 1;
}
else
{
bLevel = 0;
}
if ( gSmokeEffectData[uiCnt].bFlags & SMOKE_EFFECT_ON_ROOF )
{
bLevel = 1;
}
else
{
bLevel = 0;
}
SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, ERASE_SPREAD_EFFECT, bLevel, uiCnt );
SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, TRUE, bLevel, uiCnt );
}
}
}
}
BOOL GetRandomSignalSmokeGridNo(INT32* psGridNo)
{
UINT32 uiCnt;
//SMOKEEFFECT *pSmoke;
//INT8 bLevel;
INT32 smokearray[50];
for (UINT8 i = 0; i < 50; ++i)
smokearray[i] = -1;
UINT8 cnt = 0;
//loop through and save the number of smoke effects
for( uiCnt=0; uiCnt < guiNumSmokeEffects; uiCnt++)
{
if ( gSmokeEffectData[ uiCnt ].fAllocated && gSmokeEffectData[ uiCnt ].bType == SIGNAL_SMOKE_EFFECT )
{
smokearray[cnt++] = uiCnt;
if ( cnt >= 50 )
break;
}
}
if ( !cnt )
return FALSE;
UINT8 target = Random(cnt);
(*psGridNo) = gSmokeEffectData[ smokearray[target] ].sGridNo;
return TRUE;
}
+3
View File
@@ -11,6 +11,7 @@ enum
MUSTARDGAS_SMOKE_EFFECT,
CREATURE_SMOKE_EFFECT,
BURNABLEGAS_SMOKE_EFFECT,
SIGNAL_SMOKE_EFFECT, // added by Flugente for artillery
};
#define SMOKE_EFFECT_INDOORS 0x01
@@ -68,5 +69,7 @@ void ResetSmokeEffects();
void UpdateSmokeEffectGraphics( );
// Flugente: get the gridno and blevel of a random smoke signal, if one exists
BOOL GetRandomSignalSmokeGridNo(INT32* psGridNo);
#endif
+1 -1
View File
@@ -573,7 +573,7 @@ void UpdateAniTiles( )
// if ( ubExpType == EXPLOSV_TEARGAS || ubExpType == EXPLOSV_MUSTGAS ||
// ubExpType == EXPLOSV_SMOKE )
if ( ubExpType == EXPLOSV_TEARGAS || ubExpType == EXPLOSV_MUSTGAS ||
ubExpType == EXPLOSV_SMOKE || ubExpType == EXPLOSV_BURNABLEGAS )
ubExpType == EXPLOSV_SMOKE || ubExpType == EXPLOSV_BURNABLEGAS || ubExpType == EXPLOSV_SIGNAL_SMOKE )
{
// Do sound....
// PlayJA2Sample( AIR_ESCAPING_1, RATE_11025, SoundVolume( HIGHVOLUME, pNode->sGridNo ), 1, SoundDir( pNode->sGridNo ) );
+30 -15
View File
@@ -1307,13 +1307,24 @@ void RenderOverheadOverlays()
{ //loop through all soldiers.
end = MAX_NUM_SOLDIERS;
}
if(is_networked)end = MAX_NUM_SOLDIERS;
if(is_networked)
end = MAX_NUM_SOLDIERS;
SGPRect HostileArea = {0,0,0,0};
// Flugente: is one of the player's mercs scanning for jam signals while someone is actually jamming signals?
BOOLEAN showjammers = FALSE;
if ( PlayerTeamIsScanning() && SectorJammed() )
showjammers = TRUE;
UINT16 jamcolour = Get16BPPColor( FROMRGB( 36, 219, 151 ) );
BOOLEAN marklastenemy = FALSE;
if ( gGameSettings.fOptions[TOPTION_SHOW_LAST_ENEMY] && gGameExternalOptions.ubMarkerMode && gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector <= gGameExternalOptions.ubSoldiersLeft )
marklastenemy = TRUE;
for( i = 0; i < end; i++ )
for( i = 0; i < end; ++i )
{
//First, check to see if the soldier exists and is in the sector.
pSoldier = MercPtrs[ i ];
@@ -1325,14 +1336,16 @@ void RenderOverheadOverlays()
continue;
//DBrot: mark his general area as hostile
if(!gfEditMode && gGameSettings.fOptions[TOPTION_SHOW_LAST_ENEMY] /*&& gfUseBiggerOverview */&& gGameExternalOptions.ubMarkerMode && gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector <= gGameExternalOptions.ubSoldiersLeft){
if(pSoldier->bTeam == ENEMY_TEAM){
// Flugente: also do that if the we scanned a jamming person
if(!gfEditMode && (showjammers || marklastenemy ) )
{
if ( ( marklastenemy && pSoldier->bTeam == ENEMY_TEAM ) || ( showjammers && pSoldier->IsJamming() ) )
{
UINT8 ubGridSquareX, ubGridSquareY;
ubGridSquareX = sX / (gusGridFrameX / gubGridDivisor); //( pSoldier->sGridNo / WORLD_COLS ) / ( WORLD_COLS / ubResolutionTable[gGameExternalOptions.ubGridResolution]);
ubGridSquareY = sY / (gusGridFrameY / gubGridDivisor); //( pSoldier->sGridNo - ( ( pSoldier->sGridNo / WORLD_COLS ) * WORLD_COLS ) ) / ( WORLD_COLS / ubResolutionTable[gGameExternalOptions.ubGridResolution]);
HostileArea.iLeft = iOffsetHorizontal + (((gusGridFrameX / gubGridDivisor) * ubGridSquareX));
HostileArea.iTop = iOffsetVertical + (((gusGridFrameY / gubGridDivisor) * ubGridSquareY));
HostileArea.iRight = iOffsetHorizontal + (((gusGridFrameX / gubGridDivisor) * (ubGridSquareX + 1)));
@@ -1340,9 +1353,14 @@ void RenderOverheadOverlays()
if(gGameExternalOptions.ubMarkerMode == SHARPBORDER)
RectangleDraw(TRUE, HostileArea.iLeft, HostileArea.iTop, HostileArea.iRight, HostileArea.iBottom, 255, pDestBuf);
if(gGameExternalOptions.ubMarkerMode == HATCHED){
RectangleDraw(TRUE, HostileArea.iLeft, HostileArea.iTop, HostileArea.iRight, HostileArea.iBottom, 0xF000, pDestBuf);
Blt16BPPBufferLooseHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &HostileArea, 0xF000 );
if(gGameExternalOptions.ubMarkerMode == HATCHED)
{
UINT16 colour = 0xF000;
if ( showjammers && pSoldier->IsJamming() )
colour = jamcolour;
RectangleDraw(TRUE, HostileArea.iLeft, HostileArea.iTop, HostileArea.iRight, HostileArea.iBottom, colour, pDestBuf);
Blt16BPPBufferLooseHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &HostileArea, colour );
}
}
}
@@ -1352,10 +1370,7 @@ void RenderOverheadOverlays()
sX += 2;
sY -= 5;
//sScreenY -= 7; //height of doll
if( !gfTacticalPlacementGUIActive && pSoldier->bLastRenderVisibleValue == -1 && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) )
{
+35
View File
@@ -2867,3 +2867,38 @@ INT32 RandomGridFromRadius( INT32 sSweetGridNo, INT8 ubMinRadius, INT8 ubMaxRadi
return( sGridNo );
}
UINT32 GetArtilleryTargetGridNo( UINT32 sTargetGridNo, INT8 bRadius )
{
return RandomGridFromRadius( sTargetGridNo, 1, bRadius );
}
BOOLEAN GetArtilleryLaunchParams( UINT32 sStartingGridNo, UINT32 sTargetGridNo, INT16 sStartZ, INT16 sEndZ, UINT16 usLauncher, OBJECTTYPE* pObj, FLOAT* pdForce, FLOAT* pdDegrees)
{
FLOAT dMagForce, dMaxForce, dMinForce;
FLOAT dDegrees = OUTDOORS_START_ANGLE;
INT16 sMinRange = MIN_MORTAR_RANGE;
sStartZ = 256;
// Find force for basic
INT32 sFinalGridNo = 0;
FindBestForceForTrajectory( sStartingGridNo, sTargetGridNo, sStartZ, sEndZ, dDegrees, pObj, &sFinalGridNo, &dMagForce );
INT32 uiMaxRange = GetModifiedGunRange(usLauncher) / CELL_X_SIZE;
dMaxForce = CalculateForceFromRange( NULL, (INT16) uiMaxRange, (FLOAT)( PI/4 ) );
if ( dMagForce > dMaxForce )
dMagForce = dMaxForce;
dMinForce = CalculateForceFromRange( NULL, (INT16)( sMinRange / 10 ), (FLOAT)( PI / 4 ) );
if ( dMagForce < dMinForce )
dMagForce = dMinForce;
(*pdForce) = dMagForce;
(*pdDegrees) = dDegrees;
return TRUE;
}
+5
View File
@@ -181,5 +181,10 @@ BOOLEAN SavePhysicsTableToSaveGameFile( HWFILE hFile );
BOOLEAN LoadPhysicsTableFromSavedGameFile( HWFILE hFile );
// Flugente: artillery functions
INT32 RandomGridFromRadius( INT32 sSweetGridNo, INT8 ubMinRadius, INT8 ubMaxRadius );
UINT32 GetArtilleryTargetGridNo( UINT32 sTargetGridNo, INT8 bRadius );
BOOLEAN GetArtilleryLaunchParams( UINT32 sStartingGridNo, UINT32 sTargetGridNo, INT16 sStartZ, INT16 sEndZ, UINT16 usLauncher, OBJECTTYPE* pObj, FLOAT* pdForce, FLOAT* pdDegrees);
#endif
+2 -1
View File
@@ -134,12 +134,13 @@ class SOLDIERTYPE;
#define MAPELEMENT_EXT_CREATUREGAS 0x0080 //0x80
#define MAPELEMENT_EXT_BURNABLEGAS 0x0100 //0x100
#define MAPELEMENT_EXT_CLIMBPOINT 0x0200 //0x200
#define MAPELEMENT_EXT_SIGNAL_SMOKE 0x0400 //0x400 // added by Flugente
#define FIRST_LEVEL 0
#define SECOND_LEVEL 1
//#define ANY_SMOKE_EFFECT ( MAPELEMENT_EXT_CREATUREGAS | MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS )
#define ANY_SMOKE_EFFECT ( MAPELEMENT_EXT_CREATUREGAS | MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS | MAPELEMENT_EXT_BURNABLEGAS )
#define ANY_SMOKE_EFFECT ( MAPELEMENT_EXT_CREATUREGAS | MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS | MAPELEMENT_EXT_BURNABLEGAS | MAPELEMENT_EXT_SIGNAL_SMOKE )
// WDS - Clean up inventory handling
+32
View File
@@ -145,6 +145,9 @@ extern CHAR16 WeaponType[MAXITEMS][30];
extern CHAR16 Message[][STRING_LENGTH];
extern CHAR16 TeamTurnString[][STRING_LENGTH];
extern STR16 pMilitiaControlMenuStrings[]; //lal
extern STR16 pTraitSkillsMenuStrings[]; //Flugente
extern STR16 pTraitSkillsMenuDescStrings[]; //Flugente
extern STR16 pTraitSkillsDenialStrings[]; //Flugente
//extern STR16 pTalkToAllMenuStrings[];
extern STR16 pAssignMenuStrings[];
extern STR16 pTrainingStrings[];
@@ -704,6 +707,21 @@ enum
extern STR16 szCovertTextStr[];
enum
{
STR_POWERPACK_BEGIN,
STR_POWERPACK_FULL,
STR_POWERPACK_GOOD,
STR_POWERPACK_HALF,
STR_POWERPACK_LOW,
STR_POWERPACK_EMPTY,
STR_POWERPACK_END,
TEXT_POWERPACK_STR
};
extern STR16 gPowerPackDesc[];
enum
{
STR_CORPSE_NO_HEAD_ITEM,
@@ -2415,6 +2433,20 @@ extern STR16 szCareLevelText[];
extern STR16 szRacistText[];
extern STR16 szSexistText[];
enum
{
TEXT_SKILL_DENIAL_REQ,
TEXT_SKILL_DENIAL_X_AP,
TEXT_SKILL_DENIAL_X_TXT,
TEXT_SKILL_DENIAL_X_TXT_ORHIGHER,
TEXT_SKILL_DENIAL_X_TXT_ORHIGHER_OR,
TEXT_SKILL_DENIAL_X_MINUTES,
TEXT_SKILL_DENIAL_NOMORTAR,
TEXT_SKILL_DENIAL_ITSCOMPLICATED,
TEXT_SKILL_DENIAL_NODEMON,
TEXT_SKILL_DENIAL_MAX,
};
// Enumeration support
typedef struct Str8EnumLookupType {
+69 -9
View File
@@ -1646,6 +1646,7 @@ STR16 pAssignmentStrings[] =
L"交通工具", // in a vehicle
L"在途中",// in transit - abbreviated form
L"修理", // repairing
L"Radio Scan", // scanning for nearby patrols // TODO.Translate
L"锻炼", // training themselves
L"民兵", // training a town to revolt
L"游击队", //L"M.Militia", //training moving militia units //ham3.6
@@ -1734,6 +1735,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"交通工具",
L"在途中",
L"修理",
L"Radio Scan", // radio scan // TODO.Translate
L"锻炼",
L"训练民兵",
L"训练游击队",
@@ -1782,6 +1784,7 @@ STR16 pLongAssignmentStrings[] =
L"交通工具",
L"在途中",
L"修理",
L"Radio Scan", // radio scan // TODO.Translate
L"练习",
L"训练民兵",
L"训练游击队", //L"Train Mobiles",
@@ -1909,8 +1912,9 @@ STR16 pAssignMenuStrings[] =
L"编队",
L"医生",
L"病人",
L"交通工具",
L"交通工具",
L"修理",
L"Radio Scan", // Flugente: the merc is scanning for patrols in neighbouring sectors
L"训练",
L"搬运物品", // move items // TODO.Translate
L"设施", // L"Facility", // the merc is using/staffing a facility //ham3.6
@@ -1939,6 +1943,43 @@ STR16 pMilitiaControlMenuStrings[] =
L"取消", // cancel this menu
};
//Flugente
STR16 pTraitSkillsMenuStrings[] = // TODO.Translate
{
// radio operator
L"Artillery Strike",
L"Jam communications",
L"Scan frequencies",
L"Eavesdrop",
L"Call reinforcements",
L"Switch off radio set",
};
//Flugente: short description of the above skills for the skill selection menu
STR16 pTraitSkillsMenuDescStrings[] =
{
// radio operator
L"Order an artillery strike from sector...",
L"Fill all radio frequencies with white noise, making communications impossible.",
L"Scan for jamming signals.",
L"Use your radio equipment to continously listen for enemy movement",
L"Call in reinforcements from neighbouring sectors.",
L"Turn off radio set to save batteries.",
};
STR16 pTraitSkillsDenialStrings[] =
{
L"Requires:\n",
L" - %d AP\n",
L" - %s\n",
L" - %s or higher\n",
L" - %s or higher or\n",
L" - %d minutes to be ready\n",
L" - mortar positions in neighbouring sectors\n",
L" - %s |o|r %s |a|n|d %s or %s or higher\n"
L" - posession by a demon",
};
//STR16 pTalkToAllMenuStrings[] =
//{
// L"Attack", // set militia to aggresive
@@ -2143,36 +2184,41 @@ STR16 gzMercSkillTextNew[] =
L"近战",
L"投掷",
L"夜战",
L"潜行", // 15
L"潜行", // 14
L"运动员",
L"健身",
L"爆破",
L"教学",
L"侦察", // 20
L"侦察", // 19
// covert ops is a major trait that was added later
L"特工", // L"Covert Ops",
// new minor traits
L"Radio Operator", // 21
// second names for major skills
L"机枪手",
L"掷弹兵",
L"狙击手",
L"游骑兵",
L"枪斗术", // 25
L"游骑兵", // 25
L"枪斗术",
L"武术家",
L"班长",
L"工兵",
L"军医",
// placeholders for minor traits
L"Placeholder", // 30
L"Placeholder", // 31
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 35
L"Placeholder", // 36
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 39
L"间谍", // 30
L"Placeholder", // 40
L"间谍", // 41
L"Placeholder", // for radio operator (minor trait)
L"更多...",
};
//////////////////////////////////////////////////////////
@@ -6356,6 +6402,8 @@ STR16 MissingIMPSkillsDescriptions[] =
L"侦查:没有什么东西你觉察不到! ± ",
// Covert ops
L"特工: 你让詹姆斯邦德甘拜下风! ± ", // L"Covert Operations: You make 007 look like an amateur! ± ",
// Radio Operator
L"Radio Operator: Your usage of communication devices broaden your team's tactical and strategic skills. ± ", // TOO.Translate
};
STR16 NewInvMessage[] =
@@ -7843,6 +7891,18 @@ STR16 szSexistText[]=
L"a Gentleman",
};
// Flugente: power pack texts
STR16 gPowerPackDesc[] =
{
L"Batteries are ",
L"full",
L"good",
L"at half",
L"low",
L"depleted",
L"."
};
// WANNE: Some Chinese specific strings that needs to be in unicode!
STR16 ChineseSpecString1 = L"%"; //defined in _ChineseText.cpp as this file is already unicode
STR16 ChineseSpecString2 = L"*%3d%%%"; //defined in _ChineseText.cpp as this file is already unicode
+66 -7
View File
@@ -1642,6 +1642,7 @@ STR16 pAssignmentStrings[] =
L"Voertuig", // in a vehicle
L"Onderweg", // in transit - abbreviated form
L"Repareer", // repairing
L"Radio Scan", // scanning for nearby patrols // TODO.Translate
L"Oefenen", // training themselves
L"Militie", // training a town to revolt
L"M.Militia", //training moving militia units // TODO.Translate
@@ -1730,6 +1731,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Voertuig", // in a vehicle
L"Onderweg", // in transit - abbreviated form
L"Repareer", // repairing
L"Radio Scan", // radio scan // TODO.Translate
L"Oefenen", // training themselves
L"Militie", // training a town to revolt
L"Training Mobile Militia", // TODO.Translate
@@ -1778,6 +1780,7 @@ STR16 pLongAssignmentStrings[] =
L"Voertuig", // in a vehicle
L"Onderweg", // in transit - abbreviated form
L"Repareer", // repairing
L"Radio Scan", // radio scan // TODO.Translate
L"Oefenen", // training themselves
L"Militie", // training a town to revolt
L"Train Mobiles", // TODO.Translate
@@ -1907,6 +1910,7 @@ STR16 pAssignMenuStrings[] =
L"Patient", // the merc is receiving medical attention
L"Vehicle", // the merc is in a vehicle
L"Repair", // the merc is repairing items
L"Radio Scan", // Flugente: the merc is scanning for patrols in neighbouring sectors
L"Train", // the merc is training
L"Move Item", // move items // TODO.Translate
L"Facility", // the merc is using/staffing a facility // TODO.Translate
@@ -1935,6 +1939,44 @@ STR16 pMilitiaControlMenuStrings[] =
L"Cancel", // cancel this menu
};
//Flugente
STR16 pTraitSkillsMenuStrings[] = // TODO.Translate
{
// radio operator
L"Artillery Strike",
L"Jam communications",
L"Scan frequencies",
L"Eavesdrop",
L"Call reinforcements",
L"Switch off radio set",
};
//Flugente: short description of the above skills for the skill selection menu
STR16 pTraitSkillsMenuDescStrings[] =
{
// radio operator
L"Order an artillery strike from sector...",
L"Fill all radio frequencies with white noise, making communications impossible.",
L"Scan for jamming signals.",
L"Use your radio equipment to continously listen for enemy movement",
L"Call in reinforcements from neighbouring sectors.",
L"Turn off radio set to save batteries.",
};
STR16 pTraitSkillsDenialStrings[] =
{
L"Requires:\n",
L" - %d AP\n",
L" - %s\n",
L" - %s or higher\n",
L" - %s or higher or\n",
L" - %d minutes to be ready\n",
L" - mortar positions in neighbouring sectors\n",
L" - %s |o|r %s |a|n|d %s or %s or higher\n"
L" - posession by a demon",
};
//STR16 pTalkToAllMenuStrings[] =
//{
// L"Attack", // set militia to aggresive
@@ -2147,28 +2189,31 @@ STR16 gzMercSkillTextNew[] =
L"Scouting", // 19
// covert ops is a major trait that was added later
L"Covert Ops", // 20
// new minor traits
L"Radio Operator", // 21
// second names for major skills
L"Machinegunner", // 21
L"Machinegunner", // 22
L"Bombardier",
L"Sniper",
L"Ranger",
L"Gunfighter", // 25
L"Gunfighter", // 26
L"Martial Arts",
L"Squadleader",
L"Engineer",
L"Doctor", // 20
L"Doctor", // 30
// placeholders for minor traits
L"Placeholder", // 30
L"Placeholder", // 31
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 35
L"Placeholder", // 36
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 39
L"Spy", // 40
L"Placeholder", // 40
L"Spy", // 41
L"Placeholder", // for radio operator (minor trait)
L"More...",
};
//////////////////////////////////////////////////////////
@@ -6364,6 +6409,8 @@ STR16 MissingIMPSkillsDescriptions[] =
L"Scouting: Nothing can escape your notice! ± ",
// Covert ops
L"Covert Operations: You make 007 look like an amateur! ± ", // TODO.Translate
// Radio Operator
L"Radio Operator: Your usage of communication devices broaden your team's tactical and strategic skills. ± ", // TOO.Translate
};
STR16 NewInvMessage[] =
@@ -7860,4 +7907,16 @@ STR16 szSexistText[]=
L"a Gentleman",
};
// Flugente: power pack texts
STR16 gPowerPackDesc[] =
{
L"Batteries are ",
L"full",
L"good",
L"at half",
L"low",
L"depleted",
L"."
};
#endif //DUTCH
+68 -8
View File
@@ -1646,6 +1646,7 @@ STR16 pAssignmentStrings[] =
L"Vehicle", // in a vehicle
L"In Trans", // in transit - abbreviated form
L"Repair", // repairing
L"Radio Scan", // scanning for nearby patrols
L"Practice", // training themselves
L"Militia", // training a town to revolt
L"M.Militia", //training moving militia units
@@ -1655,7 +1656,7 @@ STR16 pAssignmentStrings[] =
L"Staff", // operating a strategic facility
L"Eat", // eating at a facility (cantina etc.)
L"Rest", // Resting at a facility
L"Prison", // Flugente: interrogate prisoners
L"Prison", // interrogate prisoners
L"Dead", // dead
L"Incap.", // abbreviation for incapacitated
L"POW", // Prisoner of war - captured
@@ -1734,6 +1735,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Vehicle",
L"In Transit",
L"Repair",
L"Radio Scan",
L"Practice",
L"Training Militia",
L"Training Mobile Militia", // Missing
@@ -1782,6 +1784,7 @@ STR16 pLongAssignmentStrings[] =
L"Vehicle",
L"In Transit",
L"Repair",
L"Radio Scan",
L"Practice",
L"Train Militia",
L"Train Mobiles", // Missing
@@ -1911,6 +1914,7 @@ STR16 pAssignMenuStrings[] =
L"Patient", // the merc is receiving medical attention
L"Vehicle", // the merc is in a vehicle
L"Repair", // the merc is repairing items
L"Radio Scan", // Flugente: the merc is scanning for patrols in neighbouring sectors
L"Train", // the merc is training
L"Move Item", // move items
L"Facility", // the merc is using/staffing a facility
@@ -1939,6 +1943,43 @@ STR16 pMilitiaControlMenuStrings[] =
L"Cancel", // cancel this menu
};
//Flugente
STR16 pTraitSkillsMenuStrings[] =
{
// radio operator
L"Artillery Strike",
L"Jam communications",
L"Scan frequencies",
L"Eavesdrop",
L"Call reinforcements",
L"Switch off radio set",
};
//Flugente: short description of the above skills for the skill selection menu
STR16 pTraitSkillsMenuDescStrings[] =
{
// radio operator
L"Order an artillery strike from sector...",
L"Fill all radio frequencies with white noise, making communications impossible.",
L"Scan for jamming signals.",
L"Use your radio equipment to continously listen for enemy movement",
L"Call in reinforcements from neighbouring sectors.",
L"Turn off radio set to save batteries.",
};
STR16 pTraitSkillsDenialStrings[] =
{
L"Requires:\n",
L" - %d AP\n",
L" - %s\n",
L" - %s or higher\n",
L" - %s or higher or\n",
L" - %d minutes to be ready\n",
L" - mortar positions in neighbouring sectors\n",
L" - %s |o|r %s |a|n|d %s or %s or higher\n"
L" - posession by a demon",
};
//STR16 pTalkToAllMenuStrings[] =
//{
// L"Attack", // set militia to aggresive
@@ -2151,28 +2192,33 @@ STR16 gzMercSkillTextNew[] =
L"Scouting", // 19
// covert ops is a major trait that was added later
L"Covert Ops", // 20
// new minor traits
L"Radio Operator", // 21
// second names for major skills
L"Machinegunner", // 21
L"Machinegunner", // 22
L"Bombardier",
L"Sniper",
L"Ranger",
L"Gunfighter", // 25
L"Gunfighter", // 26
L"Martial Arts",
L"Squadleader",
L"Engineer",
L"Doctor", // 20
L"Doctor", // 30
// placeholders for minor traits
L"Placeholder", // 30
L"Placeholder", // 31
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 35
L"Placeholder", // 36
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 39
L"Spy", // 40
L"Placeholder", // 40
L"Spy", // 41
L"Placeholder", // for radio operator (minor trait)
L"More...",
};
//////////////////////////////////////////////////////////
@@ -6356,6 +6402,8 @@ STR16 MissingIMPSkillsDescriptions[] =
L"Scouting: Nothing can escape your notice! ± ",
// Covert ops
L"Covert Operations: You make 007 look like an amateur! ± ",
// Radio Operator
L"Radio Operator: Your usage of communication devices broaden your team's tactical and strategic skills. ± ",
};
STR16 NewInvMessage[] =
@@ -7844,4 +7892,16 @@ STR16 szSexistText[]=
L"a Gentleman",
};
// Flugente: power pack texts
STR16 gPowerPackDesc[] =
{
L"Batteries are ",
L"full",
L"good",
L"at half",
L"low",
L"depleted",
L"."
};
#endif //ENGLISH
+64 -5
View File
@@ -1650,6 +1650,7 @@ STR16 pAssignmentStrings[] =
L"Transport", // in a vehicle
L"Transit", // in transit - abbreviated form
L"Réparation", // repairing
L"Radio Scan", // scanning for nearby patrols // TODO.Translate
L"Formation", // training themselves
L"Milice", // training a town to revolt
L"Milice M.", //training moving militia units
@@ -1737,6 +1738,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Transport",
L"Transit",
L"Réparation",
L"Radio Scan", // radio scan // TODO.Translate
L"Formation",
L"Milice",
L"Forme la milice mobile",//!!! Too long ? -> It is OK
@@ -1785,6 +1787,7 @@ STR16 pLongAssignmentStrings[] =
L"Transport",
L"Transit",
L"Réparation",
L"Radio Scan", // radio scan // TODO.Translate
L"Formation",
L"Milice",
L"Milice mobile",
@@ -1914,6 +1917,7 @@ STR16 pAssignMenuStrings[] =
L"Patient(e)", // the merc is receiving medical attention
L"Transport", // the merc is in a vehicle
L"Réparation", // the merc is repairing items
L"Radio Scan", // Flugente: the merc is scanning for patrols in neighbouring sectors
L"Formation", // the merc is training
L"Move Item", // move items // TODO.Translate
L"Construction", // the merc is using/staffing a facility
@@ -1942,6 +1946,43 @@ STR16 pMilitiaControlMenuStrings[] =
L"Annuler", // cancel this menu
};
//Flugente
STR16 pTraitSkillsMenuStrings[] = // TODO.Translate
{
// radio operator
L"Artillery Strike",
L"Jam communications",
L"Scan frequencies",
L"Eavesdrop",
L"Call reinforcements",
L"Switch off radio set",
};
//Flugente: short description of the above skills for the skill selection menu
STR16 pTraitSkillsMenuDescStrings[] =
{
// radio operator
L"Order an artillery strike from sector...",
L"Fill all radio frequencies with white noise, making communications impossible.",
L"Scan for jamming signals.",
L"Use your radio equipment to continously listen for enemy movement",
L"Call in reinforcements from neighbouring sectors.",
L"Turn off radio set to save batteries.",
};
STR16 pTraitSkillsDenialStrings[] =
{
L"Requires:\n",
L" - %d AP\n",
L" - %s\n",
L" - %s or higher\n",
L" - %s or higher or\n",
L" - %d minutes to be ready\n",
L" - mortar positions in neighbouring sectors\n",
L" - %s |o|r %s |a|n|d %s or %s or higher\n"
L" - posession by a demon",
};
//STR16 pTalkToAllMenuStrings[] =
//{
// L"Attaquez", // set militia to aggresive
@@ -2154,7 +2195,10 @@ STR16 gzMercSkillTextNew[] =
L"Instructeur",
L"Reconnaissance",
// covert ops is a major trait that was added later
L"Espionnage", // 10 // TODO.Translate !!! "Infiltrateur" ? Char limit ?
L"Espionnage", // 20 // TODO.Translate !!! "Infiltrateur" ? Char limit ?
// new minor traits
L"Radio Operator", // 21
// second names for major skills
L"Mitrailleur",
L"Bombardier",
@@ -2166,17 +2210,18 @@ STR16 gzMercSkillTextNew[] =
L"Ingénieur",
L"Chirurgien",
// placeholders for minor traits
L"Placeholder", // 30
L"Placeholder", // 31
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 35
L"Placeholder", // 36
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 39
L"Espion", // 30
L"Placeholder", // 40
L"Espion", // 41
L"Placeholder", // for radio operator (minor trait)
L"Plus...",
};
//////////////////////////////////////////////////////////
@@ -6356,6 +6401,8 @@ STR16 MissingIMPSkillsDescriptions[] =
L"Reconnaissance : Rien n'échappe à votre vigilance ! ± ",
// Covert ops
L"Déguisement : Vous ferez passer 007 pour un amateur ! ± ", // TODO.Translate
// Radio Operator
L"Radio Operator: Your usage of communication devices broaden your team's tactical and strategic skills. ± ", // TOO.Translate
};
STR16 NewInvMessage[] =
@@ -7845,4 +7892,16 @@ STR16 szSexistText[]=
L"a Gentleman",
};
// Flugente: power pack texts
STR16 gPowerPackDesc[] =
{
L"Batteries are ",
L"full",
L"good",
L"at half",
L"low",
L"depleted",
L"."
};
#endif //FRENCH
+63 -4
View File
@@ -1655,6 +1655,7 @@ STR16 pAssignmentStrings[] =
L"Fahrzeug", // in a vehicle
L"Transit", // in transit - abbreviated form
L"Repar.", // repairing
L"Radio Scan", // scanning for nearby patrols // TODO.Translate
L"Üben", // training themselves
L"Miliz", // training a town to revolt
L"M.Miliz", //training moving militia units
@@ -1739,6 +1740,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Fahrzeug",
L"Transit",
L"Reparieren",
L"Radio Scan", // radio scan // TODO.Translate
L"Üben",
L"Miliz",
L"Trainiere Mobile Miliz",
@@ -1785,6 +1787,7 @@ STR16 pLongAssignmentStrings[] =
L"Fahrzeug",
L"Transit",
L"Reparieren",
L"Radio Scan", // radio scan // TODO.Translate
L"Üben",
L"Miliz",
L"Trainiere Mobile",
@@ -1910,6 +1913,7 @@ STR16 pAssignMenuStrings[] =
L"Patient", // the merc is receiving medical attention
L"Fahrzeug", // the merc is in a vehicle
L"Repar.", // the merc is repairing items
L"Radio Scan", // Flugente: the merc is scanning for patrols in neighbouring sectors
L"Training", // the merc is training
L"Umzug", // move items
L"Betrieb", // the merc is using/staffing a facility
@@ -1938,6 +1942,44 @@ STR16 pMilitiaControlMenuStrings[] =
L"Abbrechen", // cancel this menu
};
//Flugente
STR16 pTraitSkillsMenuStrings[] = // TODO.Translate
{
// radio operator
L"Artillery Strike",
L"Jam communications",
L"Scan frequencies",
L"Eavesdrop",
L"Call reinforcements",
L"Switch off radio set",
};
//Flugente: short description of the above skills for the skill selection menu
STR16 pTraitSkillsMenuDescStrings[] =
{
// radio operator
L"Order an artillery strike from sector...",
L"Fill all radio frequencies with white noise, making communications impossible.",
L"Scan for jamming signals.",
L"Use your radio equipment to continously listen for enemy movement",
L"Call in reinforcements from neighbouring sectors.",
L"Turn off radio set to save batteries.",
};
STR16 pTraitSkillsDenialStrings[] =
{
L"Requires:\n",
L" - %d AP\n",
L" - %s\n",
L" - %s or higher\n",
L" - %s or higher or\n",
L" - %d minutes to be ready\n",
L" - mortar positions in neighbouring sectors\n",
L" - %s |o|r %s |a|n|d %s or %s or higher\n"
L" - posession by a demon",
};
//STR16 pTalkToAllMenuStrings[] =
//{
// L"Attack", // set militia to aggresive
@@ -2162,6 +2204,8 @@ STR16 gzMercSkillTextNew[] =
L"Aufklärer",
// covert ops is a major trait that was added later
L"Geheimagent",
// new minor traits
L"Funker", // 21
// second names for major skills
L"MG-Veteran",
L"Artillerist",
@@ -2173,17 +2217,18 @@ STR16 gzMercSkillTextNew[] =
L"Ingenieur",
L"Arzt",
// placeholders for minor traits
L"Placeholder", // 30
L"Placeholder", // 31
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 35
L"Placeholder", // 36
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 39
L"Spion", // 30
L"Placeholder", // 40
L"Spion", // 41
L"Placeholder", // for radio operator (minor trait)
L"Mehr...",
};
@@ -6181,6 +6226,8 @@ STR16 MissingIMPSkillsDescriptions[] =
L"Aufklärer: Sie sind über die Maßen aufmerksam, haben ein sehr reges Auge und einen nimmermüden Geist. ± ",
// Covert ops
L"Geheimagent: Neben Ihnen schaut 007 wie der reinste Amateur aus! ± ",
// Radio Operator
L"Radio Operator: Your usage of communication devices broaden your team's tactical and strategic skills. ± ", // TOO.Translate
};
STR16 NewInvMessage[] =
@@ -7669,4 +7716,16 @@ STR16 szSexistText[]=
L"a Gentleman",
};
// Flugente: power pack texts
STR16 gPowerPackDesc[] =
{
L"Batteries are ",
L"full",
L"good",
L"at half",
L"low",
L"depleted",
L"."
};
#endif //GERMAN
+66 -7
View File
@@ -1638,6 +1638,7 @@ STR16 pAssignmentStrings[] =
L"Veicolo", // in a vehicle
L"Transito", // in transit - abbreviated form
L"Riparare", // repairing
L"Radio Scan", // scanning for nearby patrols // TODO.Translate
L"Esercit.", // training themselves
L"Esercit.", // training a town to revolt
L"M.Militia", //training moving militia units // TODO.Translate
@@ -1726,6 +1727,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"veicolo",
L"In transito",
L"Riparare",
L"Radio Scan", // radio scan // TODO.Translate
L"Esercitarsi",
L"Allenamento Esercito",
L"Training Mobile Militia", // TODO.Translate
@@ -1774,6 +1776,7 @@ STR16 pLongAssignmentStrings[] =
L"Veicolo",
L"In transito",
L"Ripara",
L"Radio Scan", // radio scan // TODO.Translate
L"Esercitarsi",
L"Allenatore esercito",
L"Train Mobiles", // TODO.Translate
@@ -1903,6 +1906,7 @@ STR16 pAssignMenuStrings[] =
L"Paziente", // the merc is receiving medical attention
L"Veicolo", // the merc is in a vehicle
L"Ripara", // the merc is repairing items
L"Radio Scan", // Flugente: the merc is scanning for patrols in neighbouring sectors
L"Si esercita", // the merc is training
L"Move Item", // move items // TODO.Translate
L"Facility", // the merc is using/staffing a facility // TODO.Translate
@@ -1931,6 +1935,44 @@ STR16 pMilitiaControlMenuStrings[] =
L"Cancel", // cancel this menu
};
//Flugente
STR16 pTraitSkillsMenuStrings[] = // TODO.Translate
{
// radio operator
L"Artillery Strike",
L"Jam communications",
L"Scan frequencies",
L"Eavesdrop",
L"Call reinforcements",
L"Switch off radio set",
};
//Flugente: short description of the above skills for the skill selection menu
STR16 pTraitSkillsMenuDescStrings[] =
{
// radio operator
L"Order an artillery strike from sector...",
L"Fill all radio frequencies with white noise, making communications impossible.",
L"Scan for jamming signals.",
L"Use your radio equipment to continously listen for enemy movement",
L"Call in reinforcements from neighbouring sectors.",
L"Turn off radio set to save batteries.",
};
STR16 pTraitSkillsDenialStrings[] =
{
L"Requires:\n",
L" - %d AP\n",
L" - %s\n",
L" - %s or higher\n",
L" - %s or higher or\n",
L" - %d minutes to be ready\n",
L" - mortar positions in neighbouring sectors\n",
L" - %s |o|r %s |a|n|d %s or %s or higher\n"
L" - posession by a demon",
};
//STR16 pTalkToAllMenuStrings[] =
//{
// L"Attack", // set militia to aggresive
@@ -2143,28 +2185,31 @@ STR16 gzMercSkillTextNew[] =
L"Scouting", // 19
// covert ops is a major trait that was added later
L"Covert Ops", // 20
// new minor traits
L"Radio Operator", // 21
// second names for major skills
L"Machinegunner", // 21
L"Machinegunner", // 22
L"Bombardier",
L"Sniper",
L"Ranger",
L"Gunfighter", // 25
L"Gunfighter", // 26
L"Martial Arts",
L"Squadleader",
L"Engineer",
L"Doctor", // 20
L"Doctor", // 30
// placeholders for minor traits
L"Placeholder", // 30
L"Placeholder", // 31
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 35
L"Placeholder", // 36
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 39
L"Spy", // 40
L"Placeholder", // 40
L"Spy", // 41
L"Placeholder", // for radio operator (minor trait)
L"More...",
};
//////////////////////////////////////////////////////////
@@ -6351,6 +6396,8 @@ STR16 MissingIMPSkillsDescriptions[] =
L"Scouting: Nothing can escape your notice! ± ",
// Covert ops
L"Covert Operations: You make 007 look like an amateur! ± ", // TODO.Translate
// Radio Operator
L"Radio Operator: Your usage of communication devices broaden your team's tactical and strategic skills. ± ", // TOO.Translate
};
STR16 NewInvMessage[] =
@@ -7847,4 +7894,16 @@ STR16 szSexistText[]=
L"a Gentleman",
};
// Flugente: power pack texts
STR16 gPowerPackDesc[] =
{
L"Batteries are ",
L"full",
L"good",
L"at half",
L"low",
L"depleted",
L"."
};
#endif //ITALIAN
+12
View File
@@ -88,6 +88,7 @@ STR16 gzIMPSkillTraitsTextNewMinor[]=
L"爆破",// L"Demolitions",
L"教学",// L"Teaching",
L"侦察",// L"Scouting",
L"Radio Operator",
L"",// L"None",
L"I.M.P 副技能",// L"I.M.P. Minor Traits",
@@ -255,6 +256,17 @@ STR16 gzIMPMajorTraitsHelpTextsCovertOps[]=
L"伪装状态下使用近战武器攻击时,秒杀几率增加 +%d%s\n",//L"+%d%s chance of instakill with covert melee weapons\n",
L"伪装动作消耗的AP降低 %d%s\n",//L"Disguise AP cost lowered by %d%s.\n",
};
STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]= // TODO.Translate
{
L"Can use communications equipment\n",
L"Can call in artillery strikes from allies in neighbouring sectors.\n",
L"Via Frequency Scan assignment, enemy patrols can be located.\n",
L"Communications can be jammed sector-wide.\n",
L"If communications are jammed, a operator can scan for the jamming device.\n",
L"Can call in militia reinforcements from neighbouring sectors.\n",
};
STR16 gzIMPMajorTraitsHelpTextsNone[]=
{
L"无奖励",// L"No bonuses",
+11
View File
@@ -88,6 +88,7 @@ STR16 gzIMPSkillTraitsTextNewMinor[]=
L"Demolitions",
L"Teaching",
L"Scouting",
L"Radio Operator",
L"None",
L"I.M.P. Minor Traits",
@@ -257,6 +258,16 @@ STR16 gzIMPMajorTraitsHelpTextsCovertOps[]=
L"Disguise AP cost lowered by %d%s.\n",
};
STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]= // TODO.Translate
{
L"Can use communications equipment\n",
L"Can call in artillery strikes from allies in neighbouring sectors.\n",
L"Via Frequency Scan assignment, enemy patrols can be located.\n",
L"Communications can be jammed sector-wide.\n",
L"If communications are jammed, a operator can scan for the jamming device.\n",
L"Can call in militia reinforcements from neighbouring sectors.\n",
};
STR16 gzIMPMajorTraitsHelpTextsNone[]=
{
L"No bonuses",
+1
View File
@@ -18,6 +18,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
+11
View File
@@ -88,6 +88,7 @@ STR16 gzIMPSkillTraitsTextNewMinor[]=
L"Demolitions",
L"Teaching",
L"Scouting",
L"Radio Operator",
L"None",
L"I.M.P. Minor Traits",
@@ -257,6 +258,16 @@ STR16 gzIMPMajorTraitsHelpTextsCovertOps[]=
L"Disguise AP cost lowered by %d%s.\n",
};
STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]=
{
L"Can use communications equipment\n",
L"Can call in artillery strikes from allies in neighbouring sectors.\n",
L"Via Frequency Scan assignment, enemy patrols can be located.\n",
L"Communications can be jammed sector-wide.\n",
L"If communications are jammed, a operator can scan for the jamming device.\n",
L"Can call in militia reinforcements from neighbouring sectors.\n",
};
STR16 gzIMPMajorTraitsHelpTextsNone[]=
{
L"No bonuses",
+1
View File
@@ -18,6 +18,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
+12
View File
@@ -88,6 +88,7 @@ STR16 gzIMPSkillTraitsTextNewMinor[]=
L"Sabotage",
L"Instructeur",
L"Reconnaissance",
L"Radio Operator",
L"Personne",
L"Traits mineurs IMP",
@@ -256,6 +257,17 @@ STR16 gzIMPMajorTraitsHelpTextsCovertOps[]= // TODO.Translate
L"+%d%s chance of instakill with covert melee weapons\n",
L"Disguise AP cost lowered by %d%s.\n",
};
STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]= // TODO.Translate
{
L"Can use communications equipment\n",
L"Can call in artillery strikes from allies in neighbouring sectors.\n",
L"Via Frequency Scan assignment, enemy patrols can be located.\n",
L"Communications can be jammed sector-wide.\n",
L"If communications are jammed, a operator can scan for the jamming device.\n",
L"Can call in militia reinforcements from neighbouring sectors.\n",
};
STR16 gzIMPMajorTraitsHelpTextsNone[]=
{
L"Pas de bonus",
+1
View File
@@ -18,6 +18,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
+12
View File
@@ -85,6 +85,7 @@ STR16 gzIMPSkillTraitsTextNewMinor[]=
L"Sprengmeister", // alt. "Kampfmittel"
L"Ausbilder", // alt. "Lehren"
L"Aufklärer", // alt. "Spähen"
L"Radio Operator",
L"Keine",
L"B.S.E. Nebenfertigkeiten",
@@ -253,6 +254,17 @@ STR16 gzIMPMajorTraitsHelpTextsCovertOps[]=
L"+%d%s Trefferwahrscheinlichkeit für sofortigen Totschlag mit Covert-Ops Nahkampfwaffen\n",
L"Verringerte AP Kosten für verdeckte Operationen durch %d%s.\n",
};
STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]= // TODO.Translate
{
L"Can use communications equipment\n",
L"Can call in artillery strikes from allies in neighbouring sectors.\n",
L"Via Frequency Scan assignment, enemy patrols can be located.\n",
L"Communications can be jammed sector-wide.\n",
L"If communications are jammed, a operator can scan for the jamming device.\n",
L"Can call in militia reinforcements from neighbouring sectors.\n",
};
STR16 gzIMPMajorTraitsHelpTextsNone[]=
{
L"Keine Boni",
+1
View File
@@ -18,6 +18,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
+11
View File
@@ -86,6 +86,7 @@ STR16 gzIMPSkillTraitsTextNewMinor[]=
L"Demolitions",
L"Teaching",
L"Scouting",
L"Radio Operator",
L"None",
L"I.M.P. Minor Traits",
@@ -255,6 +256,16 @@ STR16 gzIMPMajorTraitsHelpTextsCovertOps[]=
L"Disguise AP cost lowered by %d%s.\n",
};
STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]= // TODO.Translate
{
L"Can use communications equipment\n",
L"Can call in artillery strikes from allies in neighbouring sectors.\n",
L"Via Frequency Scan assignment, enemy patrols can be located.\n",
L"Communications can be jammed sector-wide.\n",
L"If communications are jammed, a operator can scan for the jamming device.\n",
L"Can call in militia reinforcements from neighbouring sectors.\n",
};
STR16 gzIMPMajorTraitsHelpTextsNone[]=
{
L"No bonuses",
+1
View File
@@ -18,6 +18,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
+11
View File
@@ -88,6 +88,7 @@ STR16 gzIMPSkillTraitsTextNewMinor[]=
L"£adunki wybuchowe",
L"Nauczanie",
L"Zwiad",
L"Radio Operator",
L"Brak",
L"Pomniejsze cechy I.M.P",
@@ -257,6 +258,16 @@ STR16 gzIMPMajorTraitsHelpTextsCovertOps[]=
L"Disguise AP cost lowered by %d%s.\n",
};
STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]= // TODO.Translate
{
L"Can use communications equipment\n",
L"Can call in artillery strikes from allies in neighbouring sectors.\n",
L"Via Frequency Scan assignment, enemy patrols can be located.\n",
L"Communications can be jammed sector-wide.\n",
L"If communications are jammed, a operator can scan for the jamming device.\n",
L"Can call in militia reinforcements from neighbouring sectors.\n",
};
STR16 gzIMPMajorTraitsHelpTextsNone[]=
{
L"No bonuses",
+1
View File
@@ -18,6 +18,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
+12
View File
@@ -88,6 +88,7 @@ STR16 gzIMPSkillTraitsTextNewMinor[]=
L"Подрывник", //Demolitions
L"Инструктор", //Teaching
L"Разведчик", //Scouting
L"Radio Operator",
L"Нет",
L"I.M.P.: Дополнительные навыки", //I.M.P. Minor Traits
@@ -254,6 +255,17 @@ STR16 gzIMPMajorTraitsHelpTextsCovertOps[]=
L"+%d%s к шансу на смертельный удар скрытным оружием ближнего боя.\n",
L"ОД на переодевание снижено на %d%s.\n",
};
STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]= // TODO.Translate
{
L"Can use communications equipment\n",
L"Can call in artillery strikes from allies in neighbouring sectors.\n",
L"Via Frequency Scan assignment, enemy patrols can be located.\n",
L"Communications can be jammed sector-wide.\n",
L"If communications are jammed, a operator can scan for the jamming device.\n",
L"Can call in militia reinforcements from neighbouring sectors.\n",
};
STR16 gzIMPMajorTraitsHelpTextsNone[]=
{
L"Нет преимуществ",
+1
View File
@@ -18,6 +18,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
+11
View File
@@ -89,6 +89,7 @@ STR16 gzIMPSkillTraitsTextNewMinor[]=
L"Demolitions",
L"Teaching",
L"Scouting",
L"Radio Operator",
L"None",
L"I.M.P. Minor Traits",
@@ -258,6 +259,16 @@ STR16 gzIMPMajorTraitsHelpTextsCovertOps[]=
L"Disguise AP cost lowered by %d%s.\n",
};
STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]= // TODO.Translate
{
L"Can use communications equipment\n",
L"Can call in artillery strikes from allies in neighbouring sectors.\n",
L"Via Frequency Scan assignment, enemy patrols can be located.\n",
L"Communications can be jammed sector-wide.\n",
L"If communications are jammed, a operator can scan for the jamming device.\n",
L"Can call in militia reinforcements from neighbouring sectors.\n",
};
STR16 gzIMPMajorTraitsHelpTextsNone[]=
{
L"No bonuses",
+1
View File
@@ -18,6 +18,7 @@ extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
+64 -5
View File
@@ -1654,6 +1654,7 @@ STR16 pAssignmentStrings[] =
L"Pojazd", // in a vehicle
L"Podróż", // in transit - abbreviated form
L"Naprawa", // repairing
L"Radio Scan", // scanning for nearby patrols // TODO.Translate
L"Praktyka", // training themselves
L"Samoobr.", // training a town to revolt
L"R.Samoobr.", //training moving militia units
@@ -1742,6 +1743,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Pojazd",
L"Podróż",
L"Naprawa",
L"Radio Scan", // radio scan // TODO.Translate
L"Praktyka",
L"Trenuje samoobronę",
L"Training Mobile Militia", // TODO.Translate
@@ -1790,6 +1792,7 @@ STR16 pLongAssignmentStrings[] =
L"Pojazd",
L"W podróży",
L"Naprawa",
L"Radio Scan", // radio scan // TODO.Translate
L"Praktyka",
L"Trenuj samoobronę",
L"Train Mobiles", // TODO.Translate
@@ -1919,6 +1922,7 @@ STR16 pAssignMenuStrings[] =
L"Pacjent", // the merc is receiving medical attention
L"Pojazd", // the merc is in a vehicle
L"Naprawa", // the merc is repairing items
L"Radio Scan", // Flugente: the merc is scanning for patrols in neighbouring sectors
L"Szkolenie", // the merc is training
L"Move Item", // move items // TODO.Translate
L"Facility", // the merc is using/staffing a facility // TODO.Translate
@@ -1947,6 +1951,44 @@ STR16 pMilitiaControlMenuStrings[] =
L"Anuluj", // cancel this menu
};
//Flugente
STR16 pTraitSkillsMenuStrings[] = // TODO.Translate
{
// radio operator
L"Artillery Strike",
L"Jam communications",
L"Scan frequencies",
L"Eavesdrop",
L"Call reinforcements",
L"Switch off radio set",
};
//Flugente: short description of the above skills for the skill selection menu
STR16 pTraitSkillsMenuDescStrings[] =
{
// radio operator
L"Order an artillery strike from sector...",
L"Fill all radio frequencies with white noise, making communications impossible.",
L"Scan for jamming signals.",
L"Use your radio equipment to continously listen for enemy movement",
L"Call in reinforcements from neighbouring sectors.",
L"Turn off radio set to save batteries.",
};
STR16 pTraitSkillsDenialStrings[] =
{
L"Requires:\n",
L" - %d AP\n",
L" - %s\n",
L" - %s or higher\n",
L" - %s or higher or\n",
L" - %d minutes to be ready\n",
L" - mortar positions in neighbouring sectors\n",
L" - %s |o|r %s |a|n|d %s or %s or higher\n"
L" - posession by a demon",
};
//STR16 pTalkToAllMenuStrings[] =
//{
// L"Atak", // set militia to aggresive
@@ -2158,7 +2200,9 @@ STR16 gzMercSkillTextNew[] =
L"Uczenie",
L"Zwiad",
// covert ops is a major trait that was added later
L"Covert Ops", // 10 // TODO.Translate
L"Covert Ops", // 20 // TODO.Translate
// new minor traits
L"Radio Operator", // 21
// second names for major skills
L"Strzelec RKMu",
L"Bombardier",
@@ -2169,17 +2213,18 @@ STR16 gzMercSkillTextNew[] =
L"Dowódca Drużyny",
L"Inżynier",
L"Doktor",
L"Placeholder", // 30
L"Placeholder", // 31
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 35
L"Placeholder", // 36
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 39
L"Spy", // 40 // TODO.Translate
L"Placeholder", // 40
L"Spy", // 41 // TODO.Translate
L"Placeholder", // for radio operator (minor trait)
L"Więcej...",
};
//////////////////////////////////////////////////////////
@@ -6371,6 +6416,8 @@ STR16 MissingIMPSkillsDescriptions[] =
L"Zwiadowca: Nic nie umknie twej uwadze! ± ",
// Covert ops
L"Covert Operations: You make 007 look like an amateur! ± ", // TODO.Translate
// Radio Operator
L"Radio Operator: Your usage of communication devices broaden your team's tactical and strategic skills. ± ", // TOO.Translate
};
STR16 NewInvMessage[] =
@@ -7871,4 +7918,16 @@ STR16 szSexistText[]=
L"a Gentleman",
};
// Flugente: power pack texts
STR16 gPowerPackDesc[] =
{
L"Batteries are ",
L"full",
L"good",
L"at half",
L"low",
L"depleted",
L"."
};
#endif //POLISH
+63 -4
View File
@@ -1646,6 +1646,7 @@ STR16 pAssignmentStrings[] =
L"Транспорт", // in a vehicle
L"В пути", // in transit - abbreviated form
L"Ремонт", // repairing
L"Radio Scan", // scanning for nearby patrols // TODO.Translate
L"Практика", // training themselves
L"Ополчение", // training a town to revolt
L"Мобил.гр.", //training moving militia units //M.Militia
@@ -1734,6 +1735,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Транспорт",
L"В пути",
L"Ремонт",
L"Radio Scan", // radio scan // TODO.Translate
L"Практика",
L"Ополчение",
L"Тренирует мобильную группу", //Training Mobile Militia
@@ -1782,6 +1784,7 @@ STR16 pLongAssignmentStrings[] =
L"В транспорте",
L"В пути",
L"Ремонтирует",
L"Radio Scan", // radio scan // TODO.Translate
L"Практикуется",
L"Тренирует ополчение",
L"Тренирует мобильную группу", //Train Mobiles
@@ -1911,6 +1914,7 @@ STR16 pAssignMenuStrings[] =
L"Пациент", // the merc is receiving medical attention
L"Машина", // the merc is in a vehicle
L"Ремонт", // the merc is repairing items
L"Radio Scan", // Flugente: the merc is scanning for patrols in neighbouring sectors
L"Обучение", // the merc is training
L"Move Item", // move items // TODO.Translate
L"Удобства", // the merc is using/staffing a facility //Facility
@@ -1939,6 +1943,44 @@ STR16 pMilitiaControlMenuStrings[] =
L"Отмена", // cancel this menu
};
//Flugente
STR16 pTraitSkillsMenuStrings[] = // TODO.Translate
{
// radio operator
L"Artillery Strike",
L"Jam communications",
L"Scan frequencies",
L"Eavesdrop",
L"Call reinforcements",
L"Switch off radio set",
};
//Flugente: short description of the above skills for the skill selection menu
STR16 pTraitSkillsMenuDescStrings[] =
{
// radio operator
L"Order an artillery strike from sector...",
L"Fill all radio frequencies with white noise, making communications impossible.",
L"Scan for jamming signals.",
L"Use your radio equipment to continously listen for enemy movement",
L"Call in reinforcements from neighbouring sectors.",
L"Turn off radio set to save batteries.",
};
STR16 pTraitSkillsDenialStrings[] =
{
L"Requires:\n",
L" - %d AP\n",
L" - %s\n",
L" - %s or higher\n",
L" - %s or higher or\n",
L" - %d minutes to be ready\n",
L" - mortar positions in neighbouring sectors\n",
L" - %s |o|r %s |a|n|d %s or %s or higher\n"
L" - posession by a demon",
};
//STR16 pTalkToAllMenuStrings[] =
//{
// L"В атаку", // set militia to aggresive
@@ -2151,6 +2193,8 @@ STR16 gzMercSkillTextNew[] =
L"Разведчик", //Scouting
// covert ops is a major trait that was added later
L"Covert Ops", // 20 // TODO.Translate
// new minor traits
L"Radio Operator", // 21
// second names for major skills
L"Пулемётчик", //Machinegunner
L"Артиллерист", //Bombardier
@@ -2161,17 +2205,18 @@ STR16 gzMercSkillTextNew[] =
L"Командир", //Squadleader
L"Инженер", //Engineer
L"Доктор", //Doctor
L"Placeholder", // 30
L"Placeholder", // 31
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 35
L"Placeholder", // 36
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 39
L"Шпион", // 30
L"Placeholder", // 40
L"Шпион", // 41
L"Placeholder", // for radio operator (minor trait)
L"Ещё...",
};
//////////////////////////////////////////////////////////
@@ -6356,6 +6401,8 @@ STR16 MissingIMPSkillsDescriptions[] =
L"Разведчик: Ничто не скроется от вашего зоркого взгляда! ± ", //Scouting: Nothing can escape your notice!
// Covert ops
L"Covert Operations: You make 007 look like an amateur! ± ", // TODO.Translate
// Radio Operator
L"Radio Operator: Your usage of communication devices broaden your team's tactical and strategic skills. ± ", // TOO.Translate
};
STR16 NewInvMessage[] =
@@ -7845,4 +7892,16 @@ STR16 szSexistText[]=
L"a Gentleman",
};
// Flugente: power pack texts
STR16 gPowerPackDesc[] =
{
L"Batteries are ",
L"full",
L"good",
L"at half",
L"low",
L"depleted",
L"."
};
#endif //RUSSIAN
+67 -7
View File
@@ -1646,6 +1646,7 @@ STR16 pAssignmentStrings[] =
L"Vehicle", // in a vehicle
L"In Trans", // in transit - abbreviated form
L"Repair", // repairing
L"Radio Scan", // scanning for nearby patrols // TODO.Translate
L"Practice", // training themselves
L"Militia", // training a town to revolt
L"M.Militia", //training moving militia units // TODO.Translate
@@ -1734,6 +1735,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Vehicle",
L"In Transit",
L"Repair",
L"Radio Scan", // radio scan // TODO.Translate
L"Practice",
L"Training Militia",
L"Training Mobile Militia", // TODO.Translate
@@ -1782,6 +1784,7 @@ STR16 pLongAssignmentStrings[] =
L"Vehicle",
L"In Transit",
L"Repair",
L"Radio Scan", // radio scan // TODO.Translate
L"Practice",
L"Train Militia",
L"Train Mobiles", // TODO.Translate
@@ -1911,6 +1914,7 @@ STR16 pAssignMenuStrings[] =
L"Patient", // the merc is receiving medical attention
L"Vehicle", // the merc is in a vehicle
L"Repair", // the merc is repairing items
L"Radio Scan", // Flugente: the merc is scanning for patrols in neighbouring sectors
L"Train", // the merc is training
L"Move Item", // move items // TODO.Translate
L"Facility", // the merc is using/staffing a facility // TODO.Translate
@@ -1939,6 +1943,44 @@ STR16 pMilitiaControlMenuStrings[] =
L"Cancel", // cancel this menu
};
//Flugente
STR16 pTraitSkillsMenuStrings[] = // TODO.Translate
{
// radio operator
L"Artillery Strike",
L"Jam communications",
L"Scan frequencies",
L"Eavesdrop",
L"Call reinforcements",
L"Switch off radio set",
};
//Flugente: short description of the above skills for the skill selection menu
STR16 pTraitSkillsMenuDescStrings[] =
{
// radio operator
L"Order an artillery strike from sector...",
L"Fill all radio frequencies with white noise, making communications impossible.",
L"Scan for jamming signals.",
L"Use your radio equipment to continously listen for enemy movement",
L"Call in reinforcements from neighbouring sectors.",
L"Turn off radio set to save batteries.",
};
STR16 pTraitSkillsDenialStrings[] =
{
L"Requires:\n",
L" - %d AP\n",
L" - %s\n",
L" - %s or higher\n",
L" - %s or higher or\n",
L" - %d minutes to be ready\n",
L" - mortar positions in neighbouring sectors\n",
L" - %s |o|r %s |a|n|d %s or %s or higher\n"
L" - posession by a demon",
};
//STR16 pTalkToAllMenuStrings[] =
//{
// L"Attack", // set militia to aggresive
@@ -2151,28 +2193,32 @@ STR16 gzMercSkillTextNew[] =
L"Scouting", // 19
// covert ops is a major trait that was added later
L"Covert Ops", // 20
// new minor traits
L"Radio Operator", // 21
// second names for major skills
L"Machinegunner", // 21
L"Machinegunner", // 22
L"Bombardier",
L"Sniper",
L"Ranger",
L"Gunfighter", // 25
L"Gunfighter", // 26
L"Martial Arts",
L"Squadleader",
L"Engineer",
L"Doctor", // 20
L"Doctor", // 30
// placeholders for minor traits
L"Placeholder", // 30
L"Placeholder", // 31
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 35
L"Placeholder", // 36
L"Placeholder",
L"Placeholder",
L"Placeholder",
L"Placeholder", // 39
L"Spy", // 40
L"Placeholder", // 40
L"Spy", // 41
L"Placeholder", // for radio operator (minor trait)
L"More...",
};
//////////////////////////////////////////////////////////
@@ -6366,6 +6412,8 @@ STR16 MissingIMPSkillsDescriptions[] =
L"Scouting: Nothing can escape your notice! ± ",
// Covert ops
L"Covert Operations: You make 007 look like an amateur! ± ", // TODO.Translate
// Radio Operator
L"Radio Operator: Your usage of communication devices broaden your team's tactical and strategic skills. ± ", // TOO.Translate
};
STR16 NewInvMessage[] =
@@ -7862,4 +7910,16 @@ STR16 szSexistText[]=
L"a Gentleman",
};
// Flugente: power pack texts
STR16 gPowerPackDesc[] =
{
L"Batteries are ",
L"full",
L"good",
L"at half",
L"low",
L"depleted",
L"."
};
#endif //TAIWANESE