mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
new feature: soldier profiles allows defining individual names/bodytypes/hair/skin/traits of soldiers and militia. The game will choose randomly from this pool.
WARNING: GameDir revision >= 1672 is required. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6071 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -1246,6 +1246,10 @@ void LoadGameExternalOptions()
|
||||
//Enemy Rank by Jazz
|
||||
gGameExternalOptions.fEnemyRank = iniReader.ReadBoolean("Tactical Gameplay Settings","INDIVIDUAL_ENEMY_RANK",FALSE);
|
||||
|
||||
// Flugente: soldier profiles
|
||||
gGameExternalOptions.fSoldierProfiles_Enemy = iniReader.ReadBoolean("Tactical Gameplay Settings", "SOLDIER_PROFILES_ENEMY", TRUE);
|
||||
gGameExternalOptions.fSoldierProfiles_Militia = iniReader.ReadBoolean("Tactical Gameplay Settings", "SOLDIER_PROFILES_MILITIA", TRUE);
|
||||
|
||||
// *** ddd - BEGIN
|
||||
gGameExternalOptions.fExtMouseKeyEnabled = iniReader.ReadBoolean("Tactical Interface Settings", "ENABLE_EXT_MOUSE_KEYS", FALSE);
|
||||
|
||||
|
||||
@@ -1138,6 +1138,10 @@ typedef struct
|
||||
|
||||
//Enemy Rank Legion 2 by Jazz
|
||||
BOOLEAN fEnemyRank;
|
||||
|
||||
// Flugente: soldier profiles
|
||||
BOOLEAN fSoldierProfiles_Enemy;
|
||||
BOOLEAN fSoldierProfiles_Militia;
|
||||
|
||||
BOOLEAN fShowCamouflageFaces;
|
||||
|
||||
|
||||
+2
-1
@@ -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 SOLDIER_PROFILES 143 // Flugente: profiles for enemy and militia (possibly any non-NPC/RPC character)
|
||||
#define DYNAMIC_FLASHLIGHTS 142 // Flugente: had to add variables to LIGHTEFFECT-struct
|
||||
#define ENLARGED_OPINIONS 141 // Flugente: increased numberof merc opinions to 255, thus need to change savegame reading
|
||||
#define MODULARIZED_AI 140 // Flugente: new savegame version due to modularized AI
|
||||
@@ -61,7 +62,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 DYNAMIC_FLASHLIGHTS
|
||||
#define SAVE_GAME_VERSION SOLDIER_PROFILES
|
||||
|
||||
//#define RUSSIANGOLD
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1011,6 +1011,43 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Flugente: soldier profiles
|
||||
strcpy(fileName, directoryName);
|
||||
strcat(fileName, ENEMY_ADMIN_PROFILE_FILENAME);
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
|
||||
SGP_THROW_IFFALSE(ReadInSoldierProfiles(zSoldierProfile[0], fileName), ENEMY_ADMIN_PROFILE_FILENAME);
|
||||
num_found_soldier_profiles[0] = num_found_profiles;
|
||||
|
||||
strcpy(fileName, directoryName);
|
||||
strcat(fileName, ENEMY_REGULAR_PROFILE_FILENAME);
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
|
||||
SGP_THROW_IFFALSE(ReadInSoldierProfiles(zSoldierProfile[1], fileName), ENEMY_REGULAR_PROFILE_FILENAME);
|
||||
num_found_soldier_profiles[1] = num_found_profiles;
|
||||
|
||||
strcpy(fileName, directoryName);
|
||||
strcat(fileName, ENEMY_ELITE_PROFILE_FILENAME);
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
|
||||
SGP_THROW_IFFALSE(ReadInSoldierProfiles(zSoldierProfile[2], fileName), ENEMY_ELITE_PROFILE_FILENAME);
|
||||
num_found_soldier_profiles[2] = num_found_profiles;
|
||||
|
||||
strcpy(fileName, directoryName);
|
||||
strcat(fileName, MILITIA_GREEN_PROFILE_FILENAME);
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
|
||||
SGP_THROW_IFFALSE(ReadInSoldierProfiles(zSoldierProfile[3], fileName), MILITIA_GREEN_PROFILE_FILENAME);
|
||||
num_found_soldier_profiles[3] = num_found_profiles;
|
||||
|
||||
strcpy(fileName, directoryName);
|
||||
strcat(fileName, MILITIA_REGULAR_PROFILE_FILENAME);
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
|
||||
SGP_THROW_IFFALSE(ReadInSoldierProfiles(zSoldierProfile[4], fileName), MILITIA_REGULAR_PROFILE_FILENAME);
|
||||
num_found_soldier_profiles[4] = num_found_profiles;
|
||||
|
||||
strcpy(fileName, directoryName);
|
||||
strcat(fileName, MILITIA_VETERAN_PROFILE_FILENAME);
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
|
||||
SGP_THROW_IFFALSE(ReadInSoldierProfiles(zSoldierProfile[5], fileName), MILITIA_VETERAN_PROFILE_FILENAME);
|
||||
num_found_soldier_profiles[5] = num_found_profiles;
|
||||
|
||||
LoadIMPPortraitsTEMP();
|
||||
|
||||
//Sound profile by jazz
|
||||
|
||||
+45
-2
@@ -2042,7 +2042,23 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
|
||||
numBytesRead = ReadFieldByField(hFile, &this->usMultiTurnAction, sizeof(usMultiTurnAction), sizeof(UINT8), numBytesRead);
|
||||
numBytesRead = ReadFieldByField(hFile, &this->bAIIndex, sizeof(bAIIndex), sizeof(UINT16), numBytesRead);
|
||||
|
||||
numBytesRead = ReadFieldByField(hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead);
|
||||
if ( guiCurrentSaveGameVersion >= SOLDIER_PROFILES )
|
||||
{
|
||||
numBytesRead = ReadFieldByField(hFile, &this->usSoldierProfile, sizeof(usSoldierProfile), sizeof(UINT16), numBytesRead);
|
||||
|
||||
numBytesRead = ReadFieldByField(hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->usSoldierProfile = 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(usSoldierProfile);
|
||||
UINT8 blarg[tmp];
|
||||
numBytesRead = ReadFieldByField(hFile, &blarg, tmp, sizeof(UINT8), numBytesRead);
|
||||
|
||||
numBytesRead = ReadFieldByField(hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2050,9 +2066,11 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
|
||||
this->sMTActionGridNo = NOWHERE;
|
||||
this->usMultiTurnAction = 0;
|
||||
this->bAIIndex = 0;
|
||||
this->usSoldierProfile = 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(bOverTurnAPS) + sizeof(this->sMTActionGridNo) + sizeof(usMultiTurnAction);
|
||||
// +1 for padding
|
||||
const UINT8 tmp = sizeof(bOverTurnAPS) + sizeof(this->sMTActionGridNo) + sizeof(usMultiTurnAction) + sizeof(bAIIndex) + 1 + sizeof(usSoldierProfile);
|
||||
UINT8 blarg[tmp];
|
||||
numBytesRead = ReadFieldByField(hFile, &blarg, tmp, sizeof(UINT8), numBytesRead);
|
||||
|
||||
@@ -2082,6 +2100,31 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
|
||||
while((buffer%4) > 0)
|
||||
buffer++;
|
||||
|
||||
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++;
|
||||
|
||||
for(int i = 0; i < sizeof(usSoldierProfile); ++i)
|
||||
buffer++;
|
||||
while((buffer%4) > 0)
|
||||
buffer++;
|
||||
|
||||
for(int i = 0; i < sizeof(ubFiller); ++i)
|
||||
buffer++;
|
||||
while((buffer%4) > 0)
|
||||
|
||||
+62
-3
@@ -100,9 +100,13 @@ int INV_INTERFACE_START_Y;// = ( SCREEN_HEIGHT - INV_INTERFACE_HEIGHT );
|
||||
|
||||
HIDDEN_NAMES_VALUES zHiddenNames[500]; //legion2 Jazz
|
||||
ENEMY_NAMES_VALUES zEnemyName[500];
|
||||
ENEMY_RANK_VALUES zEnemyRank[20]; // Flugente: set this to 20, which should be way enough, as there are onyl 10 exp levels
|
||||
ENEMY_RANK_VALUES zEnemyRank[20]; // Flugente: set this to 20, which should be way enough, as there are only 10 exp levels
|
||||
CIV_NAMES_VALUES zCivGroupName[NUM_CIV_GROUPS];
|
||||
|
||||
// Flugente: soldier profiles
|
||||
SOLDIER_PROFILE_VALUES zSoldierProfile[6][NUM_SOLDIER_PROFILES];
|
||||
UINT16 num_found_soldier_profiles[6]; // the correct number is set on reading the xml
|
||||
|
||||
BOOLEAN gfInMovementMenu = FALSE;
|
||||
INT32 giMenuAnchorX, giMenuAnchorY;
|
||||
|
||||
@@ -2058,7 +2062,20 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
||||
{
|
||||
if ( pSoldier->bTeam == ENEMY_TEAM )
|
||||
{
|
||||
if (gGameExternalOptions.fEnemyNames == TRUE && gGameExternalOptions.fEnemyRank == FALSE)
|
||||
// Flugente: soldier profiles
|
||||
if ( gGameExternalOptions.fSoldierProfiles_Enemy && pSoldier->usSoldierProfile )
|
||||
{
|
||||
swprintf(NameStr, pSoldier->GetName());
|
||||
|
||||
SetFont( TINYFONT1 );
|
||||
SetFontBackground( FONT_MCOLOR_BLACK );
|
||||
SetFontForeground( FONT_YELLOW );
|
||||
|
||||
FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 20 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
|
||||
gprintfdirty( sX, sY, NameStr );
|
||||
mprintf( sX, sY, NameStr );
|
||||
}
|
||||
else if (gGameExternalOptions.fEnemyNames == TRUE && gGameExternalOptions.fEnemyRank == FALSE)
|
||||
{
|
||||
for( iCounter2 = 0; iCounter2 < 500; ++iCounter2 )
|
||||
{
|
||||
@@ -2107,6 +2124,20 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
||||
}
|
||||
}
|
||||
}
|
||||
// Flugente: soldier profiles
|
||||
else if ( pSoldier->bTeam == MILITIA_TEAM && gGameExternalOptions.fSoldierProfiles_Militia && pSoldier->usSoldierProfile )
|
||||
{
|
||||
// get a proper chaos name
|
||||
swprintf(NameStr, pSoldier->GetName());
|
||||
|
||||
SetFont( TINYFONT1 );
|
||||
SetFontBackground( FONT_MCOLOR_BLACK );
|
||||
SetFontForeground( FONT_YELLOW );
|
||||
|
||||
FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 20 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
|
||||
gprintfdirty( sX, sY, NameStr );
|
||||
mprintf( sX, sY, NameStr );
|
||||
}
|
||||
else if (gGameExternalOptions.fCivGroupName == TRUE && pSoldier->ubCivilianGroup > 0 )
|
||||
{
|
||||
if (zCivGroupName[pSoldier->ubCivilianGroup].Enabled == 1)
|
||||
@@ -2181,7 +2212,21 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
||||
#endif
|
||||
if ( pSoldier->bTeam == ENEMY_TEAM )
|
||||
{
|
||||
if (gGameExternalOptions.fEnemyNames == TRUE && gGameExternalOptions.fEnemyRank == FALSE)
|
||||
// Flugente: soldier profiles
|
||||
if ( gGameExternalOptions.fSoldierProfiles_Enemy && pSoldier->usSoldierProfile )
|
||||
{
|
||||
// get a proper chaos name
|
||||
swprintf(NameStr, pSoldier->GetName());
|
||||
|
||||
SetFont( TINYFONT1 );
|
||||
SetFontBackground( FONT_MCOLOR_BLACK );
|
||||
SetFontForeground( FONT_YELLOW );
|
||||
|
||||
FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 20 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
|
||||
gprintfdirty( sX, sY, NameStr );
|
||||
mprintf( sX, sY, NameStr );
|
||||
}
|
||||
else if (gGameExternalOptions.fEnemyNames == TRUE && gGameExternalOptions.fEnemyRank == FALSE)
|
||||
{
|
||||
for( iCounter2 = 0; iCounter2 < 500; ++iCounter2 )
|
||||
{
|
||||
@@ -2230,6 +2275,20 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
||||
}
|
||||
}
|
||||
}
|
||||
// Flugente: soldier profiles
|
||||
else if ( pSoldier->bTeam == MILITIA_TEAM && gGameExternalOptions.fSoldierProfiles_Militia && pSoldier->usSoldierProfile )
|
||||
{
|
||||
// get a proper chaos name
|
||||
swprintf(NameStr, pSoldier->GetName());
|
||||
|
||||
SetFont( TINYFONT1 );
|
||||
SetFontBackground( FONT_MCOLOR_BLACK );
|
||||
SetFontForeground( FONT_YELLOW );
|
||||
|
||||
FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 20 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
|
||||
gprintfdirty( sX, sY, NameStr );
|
||||
mprintf( sX, sY, NameStr );
|
||||
}
|
||||
else if (gGameExternalOptions.fCivGroupName == TRUE && pSoldier->ubCivilianGroup > 0 )
|
||||
{
|
||||
if (zCivGroupName[pSoldier->ubCivilianGroup].Enabled == 1)
|
||||
|
||||
@@ -87,6 +87,25 @@ typedef struct
|
||||
|
||||
extern CIV_NAMES_VALUES zCivGroupName[NUM_CIV_GROUPS];
|
||||
|
||||
// Flugente: soldier profiles
|
||||
typedef struct
|
||||
{
|
||||
UINT16 uiIndex;
|
||||
CHAR16 szName[MAX_ENEMY_NAMES_CHARS];
|
||||
UINT8 uiBodyType;
|
||||
UINT8 uiHair;
|
||||
UINT8 uiSkin;
|
||||
UINT8 uiTrait[3];
|
||||
UINT32 uiFlags;
|
||||
} SOLDIER_PROFILE_VALUES;
|
||||
|
||||
#define NUM_SOLDIER_PROFILES 100
|
||||
|
||||
extern SOLDIER_PROFILE_VALUES zSoldierProfile[6][NUM_SOLDIER_PROFILES];
|
||||
|
||||
extern UINT16 num_found_soldier_profiles[6]; // the correct number is set on reading the xml
|
||||
extern UINT16 num_found_profiles; // a helper variable during reading xmls
|
||||
|
||||
extern int INTERFACE_WIDTH; // 640
|
||||
extern int INTERFACE_HEIGHT; // 120
|
||||
extern int INV_INTERFACE_HEIGHT; // 140
|
||||
|
||||
@@ -10151,3 +10151,41 @@ BOOLEAN AllowedToStealFromTeamMate( UINT8 ubID, UINT8 ubTargetID )
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Flugente: is a soldier profile already used?
|
||||
BOOLEAN IsProfileInUse(UINT8 usTeam, INT8 aType, UINT16 aNr)
|
||||
{
|
||||
if ( aType < 0 || aType > 5 )
|
||||
return FALSE;
|
||||
|
||||
UINT8 searchedclass = SOLDIER_CLASS_ADMINISTRATOR;
|
||||
switch( aType )
|
||||
{
|
||||
case 1:
|
||||
searchedclass = SOLDIER_CLASS_ARMY;
|
||||
break;
|
||||
case 2:
|
||||
searchedclass = SOLDIER_CLASS_ELITE;
|
||||
break;
|
||||
case 3:
|
||||
searchedclass = SOLDIER_CLASS_GREEN_MILITIA;
|
||||
break;
|
||||
case 4:
|
||||
searchedclass = SOLDIER_CLASS_REG_MILITIA;
|
||||
break;
|
||||
case 5:
|
||||
searchedclass = SOLDIER_CLASS_ELITE_MILITIA;
|
||||
break;
|
||||
}
|
||||
|
||||
SOLDIERTYPE* pSoldier = NULL;
|
||||
for( INT32 i = gTacticalStatus.Team[ usTeam ].bFirstID; i <= gTacticalStatus.Team[ usTeam ].bLastID; ++i )
|
||||
{
|
||||
pSoldier = MercPtrs[ i ];
|
||||
|
||||
if ( pSoldier && pSoldier->ubSoldierClass == searchedclass && pSoldier->usSoldierProfile == aNr )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -361,5 +361,8 @@ void TeamDropAll(UINT8 bTeam, BOOLEAN fForce = FALSE);
|
||||
// are we allowed to steal access this guy's inventory?
|
||||
BOOLEAN AllowedToStealFromTeamMate( UINT8 aAccessorID, UINT8 aTargetID );
|
||||
|
||||
// Flugente: is an soldier profile already used?
|
||||
BOOLEAN IsProfileInUse(UINT8 usTeam, INT8 aType, UINT16 aNr);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1020,6 +1020,7 @@ SOLDIERTYPE& SOLDIERTYPE::operator=(const OLDSOLDIERTYPE_101& src)
|
||||
this->usStarveDamageHealth = 0;
|
||||
this->usStarveDamageStrength = 0;
|
||||
this->bAIIndex = 0;
|
||||
this->usSoldierProfile = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -16074,6 +16075,13 @@ STR16 SOLDIERTYPE::GetName()
|
||||
tmpname[tmpuser][0] = '\0' ;
|
||||
wcscat( tmpname[tmpuser], this->name );
|
||||
|
||||
if ( this->usSoldierProfile )
|
||||
{
|
||||
INT8 type = this->GetSoldierProfileType(this->bTeam);
|
||||
if ( type > -1 )
|
||||
wcscpy( tmpname[tmpuser], zSoldierProfile[type][this->usSoldierProfile].szName );
|
||||
}
|
||||
|
||||
return tmpname[tmpuser];
|
||||
}
|
||||
|
||||
@@ -16414,6 +16422,46 @@ UINT8 SOLDIERTYPE::GetBestEquippedFlashLightRange()
|
||||
return( bestrange );
|
||||
}
|
||||
|
||||
// Flugente: soldier profiles
|
||||
// retrieves the correct sub-array
|
||||
INT8 SOLDIERTYPE::GetSoldierProfileType(UINT8 usTeam)
|
||||
{
|
||||
INT8 type = -1;
|
||||
|
||||
if ( usTeam == ENEMY_TEAM && gGameExternalOptions.fSoldierProfiles_Enemy )
|
||||
{
|
||||
switch( this->ubSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ELITE :
|
||||
type = 2;
|
||||
break;
|
||||
case SOLDIER_CLASS_ARMY :
|
||||
type = 1;
|
||||
break;
|
||||
case SOLDIER_CLASS_ADMINISTRATOR :
|
||||
type = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( usTeam == ENEMY_TEAM && gGameExternalOptions.fSoldierProfiles_Enemy )
|
||||
{
|
||||
switch( this->ubSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ELITE_MILITIA :
|
||||
type = 5;
|
||||
break;
|
||||
case SOLDIER_CLASS_REG_MILITIA :
|
||||
type = 4;
|
||||
break;
|
||||
case SOLDIER_CLASS_GREEN_MILITIA :
|
||||
type = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
INT8 bBandaged; //,savedOurTurn;
|
||||
|
||||
@@ -1270,10 +1270,13 @@ public:
|
||||
INT32 sMTActionGridNo; // gridno on which we perfrom our multi-turn action
|
||||
UINT8 usMultiTurnAction; // specifies which multi-turn action we are currently performing, 0: none
|
||||
|
||||
INT16 bAIIndex; // PlanFactory from the modularized tactical AI that shall be used
|
||||
INT16 bAIIndex; // feynman: PlanFactory from the modularized tactical AI that shall be used
|
||||
|
||||
UINT16 usSoldierProfile; // Flugente: allow linking to a xml-based profile specifiying name, visuals, traits etc.
|
||||
|
||||
// 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[10];
|
||||
UINT8 ubFiller[8];
|
||||
|
||||
#ifdef JA2UB
|
||||
//ja25
|
||||
@@ -1563,6 +1566,9 @@ public:
|
||||
|
||||
void HandleFlashLights();
|
||||
UINT8 GetBestEquippedFlashLightRange();
|
||||
|
||||
// Flugente: soldier profiles
|
||||
INT8 GetSoldierProfileType(UINT8 usTeam); // retrieves the correct sub-array
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // SOLDIERTYPE;
|
||||
|
||||
+100
-2
@@ -44,6 +44,7 @@
|
||||
#include "Strategic Mines.h"
|
||||
#include "math.h"
|
||||
#include "Game Clock.h" // added this one - SANDRO
|
||||
#include "Interface.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "connect.h"
|
||||
@@ -1434,6 +1435,21 @@ void GeneratePaletteForSoldier( SOLDIERTYPE *pSoldier, UINT8 ubSoldierClass )
|
||||
|
||||
//choose random skin tone which will limit the choice of hair colors.
|
||||
skin = (INT8)Random( NUMSKINS );
|
||||
|
||||
//Choose hair color which uses the skin color to limit choices
|
||||
hair = ChooseHairColor( pSoldier, skin );
|
||||
|
||||
if ( pSoldier->usSoldierProfile )
|
||||
{
|
||||
INT8 type = pSoldier->GetSoldierProfileType(pSoldier->bTeam);
|
||||
|
||||
if ( type > -1 && zSoldierProfile[type][pSoldier->usSoldierProfile].uiSkin )
|
||||
skin = zSoldierProfile[type][pSoldier->usSoldierProfile].uiSkin - 1;
|
||||
|
||||
if ( type > -1 && zSoldierProfile[type][pSoldier->usSoldierProfile].uiHair )
|
||||
hair = zSoldierProfile[type][pSoldier->usSoldierProfile].uiHair - 1;
|
||||
}
|
||||
|
||||
switch( skin )
|
||||
{
|
||||
case PINKSKIN:
|
||||
@@ -1453,8 +1469,6 @@ void GeneratePaletteForSoldier( SOLDIERTYPE *pSoldier, UINT8 ubSoldierClass )
|
||||
break;
|
||||
}
|
||||
|
||||
//Choose hair color which uses the skin color to limit choices
|
||||
hair = ChooseHairColor( pSoldier, skin );
|
||||
switch( hair )
|
||||
{
|
||||
case BROWNHEAD: SET_PALETTEREP_ID( pSoldier->HeadPal, "BROWNHEAD" ); break;
|
||||
@@ -1631,6 +1645,63 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
|
||||
pSoldier->flags.bHasKeys = pCreateStruct->fHasKeys;
|
||||
pSoldier->ubSoldierClass = pCreateStruct->ubSoldierClass;
|
||||
|
||||
// Flugente: soldier profiles
|
||||
if ( 1 )
|
||||
{
|
||||
INT8 type = -1;
|
||||
if ( pCreateStruct->bTeam == ENEMY_TEAM && gGameExternalOptions.fSoldierProfiles_Enemy )
|
||||
{
|
||||
switch( pCreateStruct->ubSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ELITE :
|
||||
type = 2;
|
||||
break;
|
||||
case SOLDIER_CLASS_ARMY :
|
||||
type = 1;
|
||||
break;
|
||||
case SOLDIER_CLASS_ADMINISTRATOR :
|
||||
type = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( pCreateStruct->bTeam == ENEMY_TEAM && gGameExternalOptions.fSoldierProfiles_Enemy )
|
||||
{
|
||||
switch( pCreateStruct->ubSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ELITE_MILITIA :
|
||||
type = 5;
|
||||
break;
|
||||
case SOLDIER_CLASS_REG_MILITIA :
|
||||
type = 4;
|
||||
break;
|
||||
case SOLDIER_CLASS_GREEN_MILITIA :
|
||||
type = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( type > -1 )
|
||||
{
|
||||
INT16 availablenames[NUM_SOLDIER_PROFILES];
|
||||
UINT16 cnt = 0;
|
||||
|
||||
for (UINT16 i = 1; i < num_found_soldier_profiles[type]; ++i)
|
||||
{
|
||||
// make sure the name isn't already currently in use!
|
||||
if ( !IsProfileInUse(pCreateStruct->bTeam, type, i) )
|
||||
availablenames[cnt++] = i;
|
||||
}
|
||||
|
||||
if ( cnt > 0 )
|
||||
{
|
||||
pSoldier->usSoldierProfile = availablenames[Random(cnt)];
|
||||
|
||||
if ( zSoldierProfile[type][pSoldier->usSoldierProfile].uiBodyType > 0 && zSoldierProfile[type][pSoldier->usSoldierProfile].uiBodyType < 5 )
|
||||
pSoldier->ubBodyType = zSoldierProfile[type][pSoldier->usSoldierProfile].uiBodyType - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pCreateStruct->fVisible )
|
||||
{
|
||||
sprintf( pSoldier->HeadPal, pCreateStruct->HeadPal );
|
||||
@@ -3997,6 +4068,33 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
ubProgress = HighestPlayerProgressPercentage();
|
||||
ubSolClass = pSoldier->ubSoldierClass;
|
||||
|
||||
// Flugente: soldier profiles - if any traits are in the xml, use them, but fill up empty slots afterwards
|
||||
if ( pSoldier->usSoldierProfile )
|
||||
{
|
||||
INT8 type = pSoldier->GetSoldierProfileType(pCreateStruct->bTeam);
|
||||
|
||||
if ( type > -1 )
|
||||
{
|
||||
if ( zSoldierProfile[type][pSoldier->usSoldierProfile].uiTrait[0] > 0 )
|
||||
{
|
||||
pSoldier->stats.ubSkillTraits[0] = zSoldierProfile[type][pSoldier->usSoldierProfile].uiTrait[0];
|
||||
ATraitAssigned = TRUE;
|
||||
}
|
||||
|
||||
if ( zSoldierProfile[type][pSoldier->usSoldierProfile].uiTrait[1] > 0 )
|
||||
{
|
||||
pSoldier->stats.ubSkillTraits[1] = zSoldierProfile[type][pSoldier->usSoldierProfile].uiTrait[1];
|
||||
BTraitAssigned = TRUE;
|
||||
}
|
||||
|
||||
if ( zSoldierProfile[type][pSoldier->usSoldierProfile].uiTrait[2] > 0 )
|
||||
{
|
||||
pSoldier->stats.ubSkillTraits[2] = zSoldierProfile[type][pSoldier->usSoldierProfile].uiTrait[2];
|
||||
CTraitAssigned = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First determine who will be the squadleader for this group (administrators do not get a squadleader
|
||||
if ( gGameOptions.fNewTraitSystem && bNumSquadleadersInArmy < ((ubSolClass == SOLDIER_CLASS_ELITE || ubSolClass == SOLDIER_CLASS_ARMY) ? gGameOptions.ubDifficultyLevel : 2 ) &&
|
||||
( ubSolClass == SOLDIER_CLASS_ELITE || ubSolClass == SOLDIER_CLASS_ELITE_MILITIA ||
|
||||
|
||||
@@ -1164,6 +1164,10 @@
|
||||
RelativePath=".\XML_SectorLoadscreens.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_SoldierProfiles.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_SoundProfile.cpp"
|
||||
>
|
||||
|
||||
@@ -1166,6 +1166,10 @@
|
||||
RelativePath="XML_SectorLoadscreens.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_SoldierProfiles.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_SoundProfile.cpp"
|
||||
>
|
||||
|
||||
@@ -230,6 +230,7 @@
|
||||
<ClCompile Include="XML_RandomStats.cpp" />
|
||||
<ClCompile Include="XML_RPCFacesSmall.cpp" />
|
||||
<ClCompile Include="XML_SectorLoadscreens.cpp" />
|
||||
<ClCompile Include="XML_SoldierProfiles.cpp" />
|
||||
<ClCompile Include="XML_SoundProfile.cpp" />
|
||||
<ClCompile Include="XML_Sounds.cpp" />
|
||||
<ClCompile Include="XML_SpreadPatterns.cpp" />
|
||||
|
||||
@@ -641,5 +641,8 @@
|
||||
<ClCompile Include="XML_LoadScreenHints.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="XML_SoldierProfiles.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -233,6 +233,13 @@ typedef PARSE_STAGE;
|
||||
#define VEHICLESFILENAME "Vehicles.xml"
|
||||
#define SQUADNAMEFILENAME "SquadNames.xml"
|
||||
|
||||
#define ENEMY_ADMIN_PROFILE_FILENAME "Profiles\\SoldierProfileEnemyAdmin.xml"
|
||||
#define ENEMY_REGULAR_PROFILE_FILENAME "Profiles\\SoldierProfileEnemyRegular.xml"
|
||||
#define ENEMY_ELITE_PROFILE_FILENAME "Profiles\\SoldierProfileEnemyElite.xml"
|
||||
#define MILITIA_GREEN_PROFILE_FILENAME "Profiles\\SoldierProfileMilitiaGreen.xml"
|
||||
#define MILITIA_REGULAR_PROFILE_FILENAME "Profiles\\SoldierProfileMilitiaRegular.xml"
|
||||
#define MILITIA_VETERAN_PROFILE_FILENAME "Profiles\\SoldierProfileMilitiaVeteran.xml"
|
||||
|
||||
extern BOOLEAN ReadInItemStats(STR fileName, BOOLEAN localizedVersion);
|
||||
extern BOOLEAN WriteItemStats();
|
||||
|
||||
@@ -307,6 +314,10 @@ extern BOOLEAN WriteSquadNamesStats();
|
||||
extern BOOLEAN ReadInLoadScreenHints(STR fileName);
|
||||
extern BOOLEAN WriteLoadScreenHints();
|
||||
|
||||
// Flugente: soldier profiles
|
||||
extern BOOLEAN ReadInSoldierProfiles(SOLDIER_PROFILE_VALUES* pProfiles, STR fileName);
|
||||
extern BOOLEAN WriteSoldierProfiles();
|
||||
|
||||
extern BOOLEAN ReadInAmmoStats(STR fileName);
|
||||
extern BOOLEAN WriteAmmoStats();
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
#include "Event Pump.h"
|
||||
#include "Render Dirty.h"
|
||||
#include "Sys Globals.h"
|
||||
#include "interface.h"
|
||||
#include "Interface.h"
|
||||
#include <wchar.h>
|
||||
#include <tchar.h>
|
||||
#include "english.h"
|
||||
|
||||
Reference in New Issue
Block a user