Files
source/Tactical/Soldier Profile.cpp
T
Wanne 09ad70f868 *************************************************************************
** Merged source code from development (MP+BMP) trunk (Revision: 3352) **
** https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP    **
*************************************************************************

1 (Rev. 3343)
Changes:
	Control hardcoded list of unclickable ("bad") sectors via XML file. (by Realist)
	On the strategic map, the player cannot click or highlight specific
	sectors (e.g. A4, A5). Introduce a <BadSector> tag in MovementCosts.xml
	that flags a sector as "bad". (<BadSector>1</BadSector>)
Files:
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Map Screen Interface Map.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Strategic Movement Costs.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/mapscreen.cpp
	/branches/Wanne/JA2 1.13 MP/GameDir/Data/TableData/Map
	/branches/Wanne/JA2 1.13 MP/GameDir/Data/TableData/Map/MovementCosts.xml
	/branches/Wanne/JA2 1.13 MP/GameDir/Data-1.13/TableData/Map
	/branches/Wanne/JA2 1.13 MP/GameDir/Data-1.13/TableData/Map/MovementCosts.xml

2 (Rev. 3344)
Changes:
	Move hardcoded underground sectors initialization to Lua script file. (by Realist)
	Locate "initunderground.lua" at data-xyz\scripts ("xyz" subject to change).
	Lua script allows easily adding underground sectors at arbitrary locations and defining enemy garrisons and creature population.
	Also enables underground bloodcat population.
Files:
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Campaign Init.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Campaign Types.h
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Queen Command.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Strategic AI.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Strategic_2005Express.vcproj
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Strategic_VS2008.vcproj
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/UndergroundInit.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/UndergroundInit.h
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/strategicmap.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Soldier Init List.cpp
	/branches/Wanne/JA2 1.13 MP/GameDir/Data/Scripts
	/branches/Wanne/JA2 1.13 MP/GameDir/Data/Scripts/initunderground.lua
	/branches/Wanne/JA2 1.13 MP/GameDir/Data-1.13/Scripts
	/branches/Wanne/JA2 1.13 MP/GameDir/Data-1.13/Scripts/initunderground.lua

3 (Rev. 3345)
Changes:
	Bugfix: In Method CreateDestroyMouseRegionsForFacilityAssignmentMenu() (by Headrock)
Files:
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Assignments.cpp

4 (Rev. 3346)
Changes:
	Changed order of properties in GameSettings.cpp (by Headrock)
	HAM 3.6 fixes (by Headrock)
	Sorted Data-1.13\ja2_options.ini (by Headrock)
Files:
	/branches/Wanne/JA2 1.13 MP/Build/GameSettings.cpp
	/branches/Wanne/JA2 1.13 MP/Build/GameSettings.h
	/branches/Wanne/JA2 1.13 MP/Build/Laptop/BobbyRGuns.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Assignments.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/MilitiaSquads.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Strategic Mines.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Strategic/Town Militia.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Campaign.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Interface Enhanced.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Interface Items.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Items.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Items.h
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Overhead.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Soldier Control.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Soldier Profile.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Weapons.cpp
	/branches/Wanne/JA2 1.13 MP/Build/TileEngine/Explosion Control.cpp
	/branches/Wanne/JA2 1.13 MP/GameDir/Data-1.13/Ja2_Options.INI
	/branches/Wanne/JA2 1.13 MP/GameDir/INIEditorJA2Options.xml

5 (Rev. 3347)
Changes:
	Bugfix: Turns out that the program is saving the number of used Placement Slots to the temp file fine, 
	but if that number is equal to the limit of how many enemies/civvies are allowed in a sector by the INI settings, 
	it leads to an assertion error instead when trying to re-load that sector. (by Headrock)
	Re-ordered Data/Ja2_Options.INI (by Headrock)
Files:
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Enemy Soldier Save.cpp
	/branches/Wanne/JA2 1.13 MP/GameDir/Data/Ja2_Options.INI

6 (Rev. 3348)
Changes:
	Translated missing HAM 3.6 German Texts (by systemfehler)
Files:
	/branches/Wanne/JA2 1.13 MP/Build/Utils/_GermanText.cpp

7 (Rev. 3351)
Changes:
	PlusAI 1.0 Patch (by Headrock)
Files:
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Points.cpp
	/branches/Wanne/JA2 1.13 MP/Build/Tactical/Points.h
	/branches/Wanne/JA2 1.13 MP/Build/TacticalAI/Attacks.cpp
	/branches/Wanne/JA2 1.13 MP/Build/TacticalAI/DecideAction.cpp
	/branches/Wanne/JA2 1.13 MP/Build/TacticalAI/FindLocations.cpp
	/branches/Wanne/JA2 1.13 MP/Build/TacticalAI/ai.h

8 (Rev. 3352)
Changes:
	Bugfix: The DEBUG only setting "fEnableInventoryPoolQ" is now only enabled in a DEBUG version. In all other builds it is set to FALSE.
Files:
	/branches/Wanne/JA2 1.13 MP/Build/GameSettings.cpp

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@3354 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2010-03-07 11:37:32 +00:00

1790 lines
54 KiB
C++

#ifdef PRECOMPILEDHEADERS
#include "Tactical All.h"
#else
#include <stdio.h>
#include <string.h>
#include "wcheck.h"
#include "stdlib.h"
#include "debug.h"
#include "math.h"
#include "worlddef.h"
#include "worldman.h"
#include "renderworld.h"
#include "Animation Control.h"
#include "Animation Data.h"
#include "Isometric Utils.h"
#include "Event Pump.h"
#include "Timer Control.h"
#include "Render Fun.h"
#include "Render Dirty.h"
#include "mousesystem.h"
#include "interface.h"
#include "sysutil.h"
#include "FileMan.h"
#include "points.h"
#include "Random.h"
#include "ai.h"
#include "Interactive Tiles.h"
#include "soldier ani.h"
#include "english.h"
#include "overhead.h"
#include "Soldier Profile.h"
#include "Game Clock.h"
#include "assignments.h"
#include "Dialogue Control.h"
#include "soldier create.h"
#include "soldier add.h"
#include "opplist.h"
#include "weapons.h"
#include "Strategic Town Loyalty.h"
#include "squads.h"
#include "Tactical Save.h"
#include "Quests.h"
#include "aim.h"
#include "Interface Dialogue.h"
#include "GameSettings.h"
#include "strategic town reputation.h"
#include "interface utils.h"
#include "Game Event Hook.h"
#include "Map Information.h"
#include "history.h"
#include "personnel.h"
#include "environment.h"
#include "Player Command.h"
#include "strategic.h"
#endif
#include "connect.h"
#ifdef JA2EDITOR
extern BOOLEAN gfProfileDataLoaded;
#endif
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
BOOLEAN gfPotentialTeamChangeDuringDeath = FALSE;
#define MIN_BLINK_FREQ 3000
#define MIN_EXPRESSION_FREQ 2000
#define SET_PROFILE_GAINS2 500, 500, 500, 500, 500, 500, 500, 500, 500
MERCPROFILESTRUCT gMercProfiles[ NUM_PROFILES ];
MERCPROFILEGEAR gMercProfileGear[ NUM_PROFILES ];
extern UINT8 gubItemDroppableFlag[NUM_INV_SLOTS];
INT8 gbSkillTraitBonus[NUM_SKILLTRAITS] =
{
0, //NO_SKILLTRAIT
25, //LOCKPICKING
15, //HANDTOHAND
15, //ELECTRONICS
15, //NIGHTOPS
12, //THROWING
15, //TEACHING
15, //HEAVY_WEAPS
0, //AUTO_WEAPS
15, //STEALTHY
0, //AMBIDEXT
0, //THIEF // UNUSED!
30, //MARTIALARTS
30, //KNIFING
5, //PROF_SNIPER
0, //CAMOUFLAGED
0, //CAMOUFLAGED_URBAN
0, //CAMOUFLAGED_DESERT
0, //CAMOUFLAGED_SNOW
};
UINT8 gubBasicInventoryPositions[] = {
HELMETPOS,
VESTPOS,
LEGPOS,
HANDPOS,
BIGPOCK1POS,
BIGPOCK2POS,
BIGPOCK3POS,
BIGPOCK4POS
};
#define NUM_TERRORISTS 6
UINT8 gubTerrorists[NUM_TERRORISTS + 1] =
{
DRUGGIST,
SLAY,
ANNIE,
CHRIS,
TIFFANY,
T_REX,
0
};
UINT8 gubNumTerrorists = 0;
#define NUM_TERRORIST_POSSIBLE_LOCATIONS 5
INT16 gsTerroristSector[NUM_TERRORISTS][NUM_TERRORIST_POSSIBLE_LOCATIONS][2] =
{
// Elgin... preplaced
{
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 }
},
// Slay
{
{ 9, MAP_ROW_F },
{ 14, MAP_ROW_I },
{ 1, MAP_ROW_G },
{ 2, MAP_ROW_G },
{ 8, MAP_ROW_G }
},
// Matron
{
{ 14, MAP_ROW_I },
{ 6, MAP_ROW_C },
{ 2, MAP_ROW_B },
{ 11, MAP_ROW_L },
{ 8, MAP_ROW_G }
},
// Imposter
{
{ 1, MAP_ROW_G },
{ 9, MAP_ROW_F },
{ 11, MAP_ROW_L },
{ 8, MAP_ROW_G },
{ 2, MAP_ROW_G }
},
// Tiffany
{
{ 14, MAP_ROW_I },
{ 2, MAP_ROW_G },
{ 14, MAP_ROW_H },
{ 6, MAP_ROW_C },
{ 2, MAP_ROW_B }
},
// Rexall
{
{ 9, MAP_ROW_F },
{ 14, MAP_ROW_H },
{ 2, MAP_ROW_H },
{ 1, MAP_ROW_G },
{ 2, MAP_ROW_B }
}
};
INT32 gsRobotGridNo;
#define NUM_ASSASSINS 6
UINT8 gubAssassins[NUM_ASSASSINS] =
{
JIM,
JACK,
OLAF,
RAY,
OLGA,
TYRONE
};
#define NUM_ASSASSIN_POSSIBLE_TOWNS 5
INT8 gbAssassinTown[NUM_ASSASSINS][NUM_ASSASSIN_POSSIBLE_TOWNS] =
{
// Jim
{ CAMBRIA, DRASSEN, ALMA, BALIME, GRUMM },
// Jack
{ CHITZENA, ESTONI, ALMA, BALIME, GRUMM },
// Olaf
{ DRASSEN, ESTONI, ALMA, CAMBRIA, BALIME },
// Ray
{ CAMBRIA, OMERTA, BALIME, GRUMM, DRASSEN },
// Olga
{ CHITZENA, OMERTA, CAMBRIA, ALMA, GRUMM },
// Tyrone
{ CAMBRIA, BALIME, ALMA, GRUMM, DRASSEN },
};
UINT16 CalcCompetence( MERCPROFILESTRUCT * pProfile );
INT16 CalcMedicalDeposit( MERCPROFILESTRUCT * pProfile );
extern void HandleEndDemoInCreatureLevel( );
void DecideActiveTerrorists( void );
extern SOLDIERTYPE *gpSMCurrentMerc;
extern BOOLEAN gfRerenderInterfaceFromHelpText;
// WANNE - BMP: DONE!
BOOLEAN LoadMercProfiles(void)
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"LoadMercProfiles");
// FILE *fptr;
HWFILE fptr;
STR8 pFileName = "BINARYDATA\\Prof.dat";
STR8 pFileName1_Normal = "BINARYDATA\\Prof_Novice_NormalGuns.dat";
STR8 pFileName2_Normal = "BINARYDATA\\Prof_Experienced_NormalGuns.dat";
STR8 pFileName3_Normal = "BINARYDATA\\Prof_Expert_NormalGuns.dat";
STR8 pFileName4_Normal = "BINARYDATA\\Prof_Insane_NormalGuns.dat";
STR8 pFileName1_Tons = "BINARYDATA\\Prof_Novice_TonsOfGuns.dat";
STR8 pFileName2_Tons = "BINARYDATA\\Prof_Experienced_TonsOfGuns.dat";
STR8 pFileName3_Tons = "BINARYDATA\\Prof_Expert_TonsOfGuns.dat";
STR8 pFileName4_Tons = "BINARYDATA\\Prof_Insane_TonsOfGuns.dat";
UINT32 uiLoop, uiLoop2;//, uiLoop3;
UINT16 usItem;//, usNewGun, usAmmo, usNewAmmo;
if (gGameExternalOptions.fUseDifficultyBasedProfDat == TRUE)
{
switch ( gGameOptions.ubDifficultyLevel)
{
case DIF_LEVEL_EASY:
if ( gGameOptions.fGunNut )
fptr = FileOpen(pFileName1_Tons, FILE_ACCESS_READ, FALSE );
else
fptr = FileOpen(pFileName1_Normal, FILE_ACCESS_READ, FALSE );
break;
case DIF_LEVEL_MEDIUM:
if ( gGameOptions.fGunNut )
fptr = FileOpen(pFileName2_Tons, FILE_ACCESS_READ, FALSE );
else
fptr = FileOpen(pFileName2_Normal, FILE_ACCESS_READ, FALSE );
break;
case DIF_LEVEL_HARD:
if ( gGameOptions.fGunNut )
fptr = FileOpen(pFileName3_Tons, FILE_ACCESS_READ, FALSE );
else
fptr = FileOpen(pFileName3_Normal, FILE_ACCESS_READ, FALSE );
break;
case DIF_LEVEL_INSANE:
if ( gGameOptions.fGunNut )
fptr = FileOpen(pFileName4_Tons, FILE_ACCESS_READ, FALSE );
else
fptr = FileOpen(pFileName4_Normal, FILE_ACCESS_READ, FALSE );
break;
default:
fptr = FileOpen(pFileName, FILE_ACCESS_READ, FALSE );
break;
}
}
else
{
fptr = FileOpen(pFileName, FILE_ACCESS_READ, FALSE );
}
if( !fptr )
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to LoadMercProfiles from file %s", pFileName) );
return(FALSE);
}
for(uiLoop=0; uiLoop< NUM_PROFILES; uiLoop++)
{
// Changed by ADB, rev 1513
//if( !gMercProfiles[uiLoop].Load(fptr, true))
if( !gMercProfiles[uiLoop].Load(fptr, true, true, true))
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to Read Merc Profiles from File %d %s",uiLoop, pFileName) );
FileClose( fptr );
return(FALSE);
}
// WANNE - BMP: NEED TESTING!
// WANNE - BMP: DONE!
//<SB> convert old MERCPROFILESTRUCT to new MERCPROFILESTRUCT
gMercProfiles[uiLoop].sGridNo = gMercProfiles[uiLoop]._old_sGridNo;
gMercProfiles[uiLoop].sPreCombatGridNo = gMercProfiles[uiLoop]._old_sGridNo;
//</SB>
/* CHRISL: For now, we should only overwrite prof.dat in the new inventory system. Old system should still use
prof.dat until we're sure we want to replace it with the xml file.*/
if(UsingNewInventorySystem() == true){
// Start by resetting all profile inventory values to 0
gMercProfiles[uiLoop].clearInventory();
gMercProfiles[uiLoop].ubInvUndroppable = 0;
// Next, go through and assign everything but lbe gear
for(uiLoop2=INV_START_POS; uiLoop2<NUM_INV_SLOTS; uiLoop2++)
{
if(gMercProfileGear[uiLoop].inv[uiLoop2] != NONE)
{
gMercProfiles[uiLoop].inv[uiLoop2] = gMercProfileGear[uiLoop].inv[uiLoop2];
gMercProfiles[uiLoop].bInvStatus[uiLoop2] = gMercProfileGear[uiLoop].iStatus[uiLoop2];
if(uiLoop2 > 5)
gMercProfiles[uiLoop].bInvNumber[uiLoop2] = gMercProfileGear[uiLoop].iNumber[uiLoop2];
else
gMercProfiles[uiLoop].bInvNumber[uiLoop2] = 1;
}
//CHRISL: Moved outside first condition we we set ubInvUndroppable regardless of having an item
if(gMercProfileGear[uiLoop].iDrop[uiLoop2] == 0 && uiLoop > 56){
gMercProfiles[uiLoop].ubInvUndroppable |= gubItemDroppableFlag[uiLoop2];
}
}
// Last, go through and assign LBE items. Only needed for new inventory system
if((UsingNewInventorySystem() == true))
{
for(uiLoop2=0; uiLoop2<5; uiLoop2++)
{
UINT32 uiLoop3 = uiLoop2 + VESTPOCKPOS;
if(gMercProfileGear[uiLoop].lbe[uiLoop2] != NONE){
gMercProfiles[uiLoop].inv[uiLoop3] = gMercProfileGear[uiLoop].lbe[uiLoop2];
gMercProfiles[uiLoop].bInvStatus[uiLoop3] = gMercProfileGear[uiLoop].lStatus[uiLoop2];
gMercProfiles[uiLoop].bInvNumber[uiLoop3] = 1;
}
}
}
}
//if the Dialogue exists for the merc, allow the merc to be hired
if( DialogueDataFileExistsForProfile( (UINT8)uiLoop, 0, FALSE, NULL ) )
{
gMercProfiles[uiLoop].bMercStatus = 0;
}
else
gMercProfiles[uiLoop].bMercStatus = MERC_HAS_NO_TEXT_FILE;
// if the merc has a medical deposit
if( gMercProfiles[ uiLoop ].bMedicalDeposit )
{
gMercProfiles[uiLoop].sMedicalDepositAmount = CalcMedicalDeposit( &gMercProfiles[uiLoop]);
}
else
gMercProfiles[uiLoop].sMedicalDepositAmount = 0;
// ATE: New, face display indipendent of ID num now
// Setup face index value
// Default is the ubCharNum
gMercProfiles[uiLoop].ubFaceIndex = (UINT8)uiLoop;
/*
if ( !gGameOptions.fGunNut )
{
// CJC: replace guns in profile if they aren't available
for ( uiLoop2 = 0; uiLoop2 < gMercProfiles[uiLoop].inv.size(); uiLoop2++ )
{
usItem = gMercProfiles[uiLoop].inv[ uiLoop2 ];
if ( ( Item[ usItem ].usItemClass & IC_GUN ) && ExtendedGunListGun( usItem ) )
{
usNewGun = StandardGunListReplacement( usItem );
if ( usNewGun != NOTHING )
{
gMercProfiles[uiLoop].inv[ uiLoop2 ] = usNewGun;
// must search through inventory and replace ammo accordingly
for ( uiLoop3 = 0; uiLoop3 < gMercProfiles[ uiLoop ].inv.size(); uiLoop3++ )
{
usAmmo = gMercProfiles[ uiLoop ].inv[ uiLoop3 ];
if ( (Item[ usAmmo ].usItemClass & IC_AMMO) )
{
usNewAmmo = FindReplacementMagazineIfNecessary( usItem, usAmmo, usNewGun );
if (usNewAmmo != NOTHING )
{
// found a new magazine, replace...
gMercProfiles[ uiLoop ].inv[ uiLoop3 ] = usNewAmmo;
}
}
}
}
}
}
} // end of if not gun nut
*/
//ATE: Calculate some inital attractiveness values for buddy's inital equipment...
// Look for gun and armour
gMercProfiles[uiLoop].bMainGunAttractiveness = -1;
gMercProfiles[uiLoop].bArmourAttractiveness = -1;
for ( uiLoop2 = 0; uiLoop2 < gMercProfiles[uiLoop].inv.size(); uiLoop2++ )
{
usItem = gMercProfiles[uiLoop].inv[ uiLoop2 ];
if ( usItem != NOTHING )
{
// Check if it's a gun
if ( Item[ usItem ].usItemClass & IC_GUN )
{
gMercProfiles[uiLoop].bMainGunAttractiveness = Weapon[ usItem ].ubDeadliness;
}
// If it's armour
if ( Item[ usItem ].usItemClass & IC_ARMOUR )
{
gMercProfiles[uiLoop].bArmourAttractiveness = min(128,Armour[ Item[ usItem ].ubClassIndex ].ubProtection);
}
}
}
// OK, if we are a created slot, this will get overriden at some time..
//add up the items the merc has for the usOptionalGearCost
gMercProfiles[ uiLoop ].usOptionalGearCost = 0;
for ( uiLoop2 = 0; uiLoop2< gMercProfiles[ uiLoop ].inv.size(); uiLoop2++ )
{
if ( gMercProfiles[ uiLoop ].inv[ uiLoop2 ] != NOTHING )
{
//get the item
usItem = gMercProfiles[ uiLoop ].inv[ uiLoop2 ];
//add the cost
gMercProfiles[ uiLoop ].usOptionalGearCost += Item[ usItem ].usPrice;
}
}
//These variables to get loaded in
gMercProfiles[ uiLoop ].fUseProfileInsertionInfo = FALSE;
gMercProfiles[ uiLoop ].sGridNo = 0;
// ARM: this is also being done inside the profile editor, but put it here too, so this project's code makes sense
gMercProfiles[ uiLoop ].bHatedCount[0] = gMercProfiles[ uiLoop ].bHatedTime[0];
gMercProfiles[ uiLoop ].bHatedCount[1] = gMercProfiles[ uiLoop ].bHatedTime[1];
gMercProfiles[ uiLoop ].bLearnToHateCount = gMercProfiles[ uiLoop ].bLearnToHateTime;
gMercProfiles[ uiLoop ].bLearnToLikeCount = gMercProfiles[ uiLoop ].bLearnToLikeTime;
if (gGameExternalOptions.fReadProfileDataFromXML)
{
// HEADROCK PROFEX: Overwrite data read from PROF.DAT with data read from XML
OverwriteMercProfileWithXMLData( uiLoop );
OverwriteMercOpinionsWithXMLData( uiLoop );
}
}
// SET SOME DEFAULT LOCATIONS FOR STARTING NPCS
FileClose( fptr );
// decide which terrorists are active
DecideActiveTerrorists();
// initialize mercs' status
if(!is_networked)StartSomeMercsOnAssignment( );
// initial recruitable mercs' reputation in each town
InitializeProfilesForTownReputation( );
#ifdef JA2EDITOR
gfProfileDataLoaded = TRUE;
#endif
// no better place..heh?.. will load faces for profiles that are 'extern'.....won't have soldiertype instances
InitalizeStaticExternalNPCFaces( );
// car portrait values
LoadCarPortraitValues( );
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"LoadMercProfiles done");
return(TRUE);
}
#define MAX_ADDITIONAL_TERRORISTS 5 // instead of 4
void DecideActiveTerrorists( void )
{
UINT8 ubLoop, ubLoop2;
UINT8 ubTerrorist;
UINT8 ubNumAdditionalTerrorists, ubNumTerroristsAdded = 0;
UINT32 uiChance, uiLocationChoice;
BOOLEAN fFoundSpot;
INT16 sTerroristPlacement[MAX_ADDITIONAL_TERRORISTS][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} }; // added one here
#ifdef CRIPPLED_VERSION
return;
#endif
// one terrorist will always be Elgin
// determine how many more terrorists - 2 to 4 more
// using this stochastic process(!), the chances for terrorists are:
// EASY: 3, 9% 4, 42% 5, 49%
// MEDIUM: 3, 25% 4, 50% 5, 25%
// HARD: 3, 49% 4, 42% 5, 9%
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
uiChance = 70;
break;
case DIF_LEVEL_INSANE:
uiChance = 30;
break;
default:
uiChance = 50;
break;
}
//////////////////////////////////////////////////////////////////////////
// this makes no sense now, we just set the exact number of them below
//if ( gGameExternalOptions.fEnableAllTerrorists )
// uiChance = 100;
//////////////////////////////////////////////////////////////////////////
// add at least 2 more
ubNumAdditionalTerrorists = 2;
for (ubLoop = 0; ubLoop < (MAX_ADDITIONAL_TERRORISTS - 3); ubLoop++) // -3 instead of -2 because we increased MAX_ADDITIONAL_TERRORISTS above by 1
{
if (Random( 100 ) < uiChance)
{
ubNumAdditionalTerrorists++;
}
}
/////////////////////////////////////////////////////
// Added so with ENABLE_ALL_TERRORISTS you really get all of them (5 + Charlie)
if ( gGameExternalOptions.fEnableAllTerrorists )
ubNumAdditionalTerrorists = 5;
/////////////////////////////////////////////////////
// ifdefs added by CJC
#ifdef JA2TESTVERSION
ubNumAdditionalTerrorists = 4;
#endif
while ( ubNumTerroristsAdded < ubNumAdditionalTerrorists )
{
ubLoop = 1; // start at beginning of array (well, after Elgin)
// NB terrorist ID of 0 indicates end of array
while ( ubNumTerroristsAdded < ubNumAdditionalTerrorists && gubTerrorists[ ubLoop ] != 0 )
{
ubTerrorist = gubTerrorists[ ubLoop ];
// random 40% chance of adding this terrorist if not yet placed
if ( ( gMercProfiles[ ubTerrorist ].sSectorX == 0 ) && (( Random( 100 ) < 40 ) || gGameExternalOptions.fEnableAllTerrorists ) ) // also added the check because it makes no sense to choose randomly which terrorist will be in game, all of them should
{
//fFoundSpot = FALSE;
// Since there are 5 spots per terrorist and a maximum of 5 terrorists, we
// are guaranteed to be able to find a spot for each terrorist since there
// aren't enough other terrorists to use up all the spots for any one
// terrorist
do
{
fFoundSpot = TRUE;
// pick a random spot, see if it's already been used by another terrorist
uiLocationChoice = Random( NUM_TERRORIST_POSSIBLE_LOCATIONS );
for (ubLoop2 = 0; ubLoop2 < ubNumTerroristsAdded; ubLoop2++)
{
if (sTerroristPlacement[ubLoop2][0] == gsTerroristSector[ubLoop][uiLocationChoice][0] )
{
if (sTerroristPlacement[ubLoop2][1] == gsTerroristSector[ubLoop][uiLocationChoice][1] )
{
// WANNE: Fix a vanilla bug: Due to a logic bug multiple terrorists could end up in the same sector.
// Fixed by Tron (Straciatella): Revision: 6932
fFoundSpot = FALSE;
break;
//continue;
}
}
}
//fFoundSpot = TRUE;
} while( !fFoundSpot );
// place terrorist!
gMercProfiles[ ubTerrorist ].sSectorX = gsTerroristSector[ ubLoop ][ uiLocationChoice ][ 0 ];
gMercProfiles[ ubTerrorist ].sSectorY = gsTerroristSector[ ubLoop ][ uiLocationChoice ][ 1 ];
gMercProfiles[ ubTerrorist ].bSectorZ = 0;
sTerroristPlacement[ ubNumTerroristsAdded ][ 0 ] = gMercProfiles[ ubTerrorist ].sSectorX;
sTerroristPlacement[ ubNumTerroristsAdded ][ 1 ] = gMercProfiles[ ubTerrorist ].sSectorY;
ubNumTerroristsAdded++;
}
ubLoop++;
}
// start over if necessary
}
// set total terrorists outstanding in Carmen's info byte
gMercProfiles[ 78 ].bNPCData = 1 + ubNumAdditionalTerrorists;
// store total terrorists
gubNumTerrorists = 1 + ubNumAdditionalTerrorists;
}
void MakeRemainingTerroristsTougher( void )
{
UINT8 ubRemainingTerrorists = 0, ubLoop;
UINT16 usNewItem, usOldItem;
UINT8 ubRemainingDifficulty;
for ( ubLoop = 0; ubLoop < NUM_TERRORISTS; ubLoop++ )
{
if ( gMercProfiles[ gubTerrorists[ ubLoop ] ].bMercStatus != MERC_IS_DEAD && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorX != 0 && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorY != 0 )
{
if ( gubTerrorists[ ubLoop ] == SLAY )
{
if ( FindSoldierByProfileID( SLAY, TRUE ) != NULL )
{
// Slay on player's team, doesn't count towards remaining terrorists
continue;
}
}
ubRemainingTerrorists++;
}
}
ubRemainingDifficulty = (60 / gubNumTerrorists) * (gubNumTerrorists - ubRemainingTerrorists);
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_MEDIUM:
ubRemainingDifficulty = (ubRemainingDifficulty * 13) / 10;
break;
case DIF_LEVEL_HARD:
ubRemainingDifficulty = (ubRemainingDifficulty * 16) / 10;
break;
case DIF_LEVEL_INSANE:
ubRemainingDifficulty = (ubRemainingDifficulty * 19) / 10;
break;
default:
break;
}
if ( ubRemainingDifficulty < 14 )
{
// nothing
return;
}
else if ( ubRemainingDifficulty < 28 )
{
// mini grenade
usOldItem = NOTHING;
usNewItem = MINI_GRENADE;
}
else if ( ubRemainingDifficulty < 42)
{
// hand grenade
usOldItem = MINI_GRENADE;
usNewItem = HAND_GRENADE;
}
else if ( ubRemainingDifficulty < 56)
{
// mustard
usOldItem = HAND_GRENADE;
usNewItem = MUSTARD_GRENADE;
}
else if ( ubRemainingDifficulty < 70)
{
// LAW
usOldItem = MUSTARD_GRENADE;
usNewItem = ROCKET_LAUNCHER;
}
else
{
// LAW and hand grenade
usOldItem = NOTHING;
usNewItem = HAND_GRENADE;
}
CreateItem(usNewItem, 100, &gTempObject);
for ( ubLoop = 0; ubLoop < NUM_TERRORISTS; ubLoop++ )
{
if ( gMercProfiles[ gubTerrorists[ ubLoop ] ].bMercStatus != MERC_IS_DEAD && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorX != 0 && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorY != 0 )
{
if ( gubTerrorists[ ubLoop ] == SLAY )
{
if ( FindSoldierByProfileID( SLAY, TRUE ) != NULL )
{
// Slay on player's team, doesn't count towards remaining terrorists
continue;
}
}
if ( usOldItem != NOTHING )
{
RemoveObjectFromSoldierProfile( gubTerrorists[ ubLoop ], usOldItem );
}
PlaceObjectInSoldierProfile( gubTerrorists[ ubLoop ], &gTempObject );
}
}
}
void DecideOnAssassin( void )
{
UINT8 ubAssassinPossibility[NUM_ASSASSINS] = { NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE };
UINT8 ubAssassinsPossible = 0;
UINT8 ubLoop, ubLoop2;
UINT8 ubTown;
#ifdef CRIPPLED_VERSION
return;
#endif
ubTown = GetTownIdForSector( gWorldSectorX, gWorldSectorY );
for ( ubLoop = 0; ubLoop < NUM_ASSASSINS; ubLoop++ )
{
// make sure alive and not placed already
if ( gMercProfiles[ gubAssassins[ ubLoop ] ].bMercStatus != MERC_IS_DEAD && gMercProfiles[ gubAssassins[ ubLoop ] ].sSectorX == 0 && gMercProfiles[ gubAssassins[ ubLoop ] ].sSectorY == 0 )
{
// check this merc to see if the town is a possibility
for ( ubLoop2 = 0; ubLoop2 < NUM_ASSASSIN_POSSIBLE_TOWNS; ubLoop2++ )
{
if ( gbAssassinTown[ ubLoop ][ ubLoop2 ] == ubTown )
{
ubAssassinPossibility[ ubAssassinsPossible ] = gubAssassins[ ubLoop ];
ubAssassinsPossible++;
}
}
}
}
if ( ubAssassinsPossible != 0 )
{
ubLoop = ubAssassinPossibility[ Random( ubAssassinsPossible ) ];
gMercProfiles[ ubLoop ].sSectorX = gWorldSectorX;
gMercProfiles[ ubLoop ].sSectorY = gWorldSectorY;
AddStrategicEvent( EVENT_REMOVE_ASSASSIN, GetWorldTotalMin() + 60 * ( 3 + Random( 3 ) ), ubLoop );
}
}
void MakeRemainingAssassinsTougher( void )
{
UINT8 ubRemainingAssassins = 0, ubLoop;
UINT16 usNewItem, usOldItem;
UINT8 ubRemainingDifficulty;
for ( ubLoop = 0; ubLoop < NUM_ASSASSINS; ubLoop++ )
{
if ( gMercProfiles[ gubAssassins[ ubLoop ] ].bMercStatus != MERC_IS_DEAD )
{
ubRemainingAssassins++;
}
}
ubRemainingDifficulty = (60 / NUM_ASSASSINS) * (NUM_ASSASSINS - ubRemainingAssassins);
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_MEDIUM:
ubRemainingDifficulty = (ubRemainingDifficulty * 13) / 10;
break;
case DIF_LEVEL_HARD:
ubRemainingDifficulty = (ubRemainingDifficulty * 16) / 10;
break;
case DIF_LEVEL_INSANE:
ubRemainingDifficulty = (ubRemainingDifficulty * 19) / 10;
break;
default:
break;
}
if ( ubRemainingDifficulty < 14 )
{
// nothing
return;
}
else if ( ubRemainingDifficulty < 28 )
{
// mini grenade
usOldItem = NOTHING;
usNewItem = MINI_GRENADE;
}
else if ( ubRemainingDifficulty < 42)
{
// hand grenade
usOldItem = MINI_GRENADE;
usNewItem = HAND_GRENADE;
}
else if ( ubRemainingDifficulty < 56)
{
// mustard
usOldItem = HAND_GRENADE;
usNewItem = MUSTARD_GRENADE;
}
else if ( ubRemainingDifficulty < 70)
{
// LAW
usOldItem = MUSTARD_GRENADE;
usNewItem = ROCKET_LAUNCHER;
}
else
{
// LAW and hand grenade
usOldItem = NOTHING;
usNewItem = HAND_GRENADE;
}
CreateItem(usNewItem, 100, &gTempObject);
for ( ubLoop = 0; ubLoop < NUM_ASSASSINS; ubLoop++ )
{
if ( gMercProfiles[ gubAssassins[ ubLoop ] ].bMercStatus != MERC_IS_DEAD )
{
if ( usOldItem != NOTHING )
{
RemoveObjectFromSoldierProfile( gubAssassins[ ubLoop ], usOldItem );
}
PlaceObjectInSoldierProfile( gubAssassins[ ubLoop ], &gTempObject );
}
}
}
void StartSomeMercsOnAssignment(void)
{
UINT32 uiCnt;
MERCPROFILESTRUCT *pProfile;
UINT32 uiChance;
// some randomly picked A.I.M. mercs will start off "on assignment" at the beginning of each new game
for( uiCnt = 0; uiCnt < AIM_AND_MERC_MERCS; uiCnt++)
{
if( !IsProfileIdAnAimOrMERCMerc( (UINT8)uiCnt ) )
{
continue;
}
pProfile = &(gMercProfiles[ uiCnt ]);
// calc chance to start on assignment
uiChance = 5 * pProfile->bExpLevel;
if (Random(100) < uiChance)
{
pProfile->bMercStatus = MERC_WORKING_ELSEWHERE;
pProfile->uiDayBecomesAvailable = 1 + Random(6 + (pProfile->bExpLevel / 2) ); // 1-(6 to 11) days
}
else
{
pProfile->bMercStatus = MERC_OK;
pProfile->uiDayBecomesAvailable = 0;
}
pProfile->uiPrecedentQuoteSaid = 0;
pProfile->ubDaysOfMoraleHangover = 0;
}
}
void SetProfileFaceData( UINT8 ubCharNum, UINT8 ubFaceIndex, UINT16 usEyesX, UINT16 usEyesY, UINT16 usMouthX, UINT16 usMouthY )
{
gMercProfiles[ ubCharNum ].ubFaceIndex = ubFaceIndex;
gMercProfiles[ ubCharNum ].usEyesX = usEyesX;
gMercProfiles[ ubCharNum ].usEyesY = usEyesY;
gMercProfiles[ ubCharNum ].usMouthX = usMouthX;
gMercProfiles[ ubCharNum ].usMouthY = usMouthY;
}
UINT16 CalcCompetence( MERCPROFILESTRUCT * pProfile )
{
UINT32 uiStats, uiSkills, uiActionPoints, uiSpecialSkills;
UINT16 usCompetence;
// count life twice 'cause it's also hit points
// mental skills are halved 'cause they're actually not that important within the game
uiStats = ((2 * pProfile->bLifeMax) + pProfile->bStrength + pProfile->bAgility + pProfile->bDexterity + ((pProfile->bLeadership + pProfile->bWisdom) / 2)) / 3;
// marksmanship is very important, count it double
uiSkills = (UINT32) ((2 * (pow((double)pProfile->bMarksmanship, 3) / 10000)) +
1.5 * (pow((double)pProfile->bMedical, 3) / 10000) +
(pow((double)pProfile->bMechanical, 3) / 10000) +
(pow((double)pProfile->bExplosive, 3) / 10000));
// action points
uiActionPoints = 5 + (((10 * pProfile->bExpLevel +
3 * pProfile->bAgility +
2 * pProfile->bLifeMax +
2 * pProfile->bDexterity) + 20) / 40);
// count how many he has, don't care what they are
uiSpecialSkills = ((pProfile->bSkillTrait != 0) ? 1 : 0) + ((pProfile->bSkillTrait2 != 0) ? 1 : 0);
usCompetence = (UINT16) ((pow((double)pProfile->bExpLevel, 0.2) * uiStats * uiSkills * (uiActionPoints - 6) * (1 + (0.05 * (FLOAT)uiSpecialSkills))) / 1000);
// this currently varies from about 10 (Flo) to 1200 (Gus)
return(usCompetence);
}
INT16 CalcMedicalDeposit( MERCPROFILESTRUCT * pProfile )
{
UINT16 usDeposit;
// this rounds off to the nearest hundred
usDeposit = (((5 * CalcCompetence(pProfile)) + 50) / 100) * 100;
return(usDeposit);
}
SOLDIERTYPE * FindSoldierByProfileID( UINT8 ubProfileID, BOOLEAN fPlayerMercsOnly )
{
UINT8 ubLoop, ubLoopLimit;
SOLDIERTYPE * pSoldier;
if (fPlayerMercsOnly)
{
ubLoopLimit = gTacticalStatus.Team[0].bLastID;
}
else
{
ubLoopLimit = MAX_NUM_SOLDIERS;
}
for (ubLoop = 0, pSoldier = MercPtrs[0]; ubLoop < ubLoopLimit; ubLoop++, pSoldier++)
{
if (pSoldier->bActive && pSoldier->ubProfile == ubProfileID)
{
return( pSoldier );
}
}
return( NULL );
}
SOLDIERTYPE *ChangeSoldierTeam( SOLDIERTYPE *pSoldier, UINT8 ubTeam )
{
UINT8 ubID;
SOLDIERTYPE *pNewSoldier = NULL;
SOLDIERCREATE_STRUCT MercCreateStruct;
UINT32 cnt;
INT32 sOldGridNo;
UINT8 ubOldID;
UINT32 uiOldUniqueId;
UINT32 uiSlot;
SOLDIERTYPE *pGroupMember;
BOOLEAN success;
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("ChangeSoldierTeam"));
if (gfInTalkPanel)
{
DeleteTalkingMenu();
}
// Save merc id for this guy...
ubID = pSoldier->ubID;
ubOldID = ubID;
uiOldUniqueId = pSoldier->uiUniqueSoldierIdValue;
sOldGridNo = pSoldier->sGridNo;
// Remove him from the game!
InternalTacticalRemoveSoldier( ubID, FALSE );
// Create a new one!
MercCreateStruct.bTeam = ubTeam;
MercCreateStruct.ubProfile = pSoldier->ubProfile;
MercCreateStruct.bBodyType = pSoldier->ubBodyType;
MercCreateStruct.sSectorX = pSoldier->sSectorX;
MercCreateStruct.sSectorY = pSoldier->sSectorY;
MercCreateStruct.bSectorZ = pSoldier->bSectorZ;
MercCreateStruct.sInsertionGridNo = pSoldier->sGridNo;
MercCreateStruct.ubDirection = pSoldier->ubDirection;
if ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
{
MercCreateStruct.ubProfile = NO_PROFILE;
MercCreateStruct.fUseGivenVehicle = TRUE;
MercCreateStruct.bUseGivenVehicleID = pSoldier->bVehicleID;
}
if ( ubTeam == gbPlayerNum )
{
MercCreateStruct.fPlayerMerc = TRUE;
}
if ( TacticalCreateSoldier( &MercCreateStruct, &ubID ) )
{
pNewSoldier = MercPtrs[ ubID ];
// Copy vital stats back!
pNewSoldier->stats.bLife = pSoldier->stats.bLife;
pNewSoldier->stats.bLifeMax = pSoldier->stats.bLifeMax;
pNewSoldier->stats.bAgility = pSoldier->stats.bAgility;
pNewSoldier->stats.bLeadership = pSoldier->stats.bLeadership;
pNewSoldier->stats.bDexterity = pSoldier->stats.bDexterity;
pNewSoldier->stats.bStrength = pSoldier->stats.bStrength;
pNewSoldier->stats.bWisdom = pSoldier->stats.bWisdom;
pNewSoldier->stats.bExpLevel = pSoldier->stats.bExpLevel;
pNewSoldier->stats.bMarksmanship = pSoldier->stats.bMarksmanship;
pNewSoldier->stats.bMedical = pSoldier->stats.bMedical;
pNewSoldier->stats.bMechanical = pSoldier->stats.bMechanical;
pNewSoldier->stats.bExplosive = pSoldier->stats.bExplosive;
pNewSoldier->stats.bScientific = pSoldier->stats.bScientific;
pNewSoldier->bLastRenderVisibleValue = pSoldier->bLastRenderVisibleValue;
pNewSoldier->bVisible = pSoldier->bVisible;
// WANNE: Fix a vanilla bug: When a soldier changed team (e.g. getting hostile), he lost his camouflage.
// Fixed by Tron (Stracciatella): Revision: 7055
pNewSoldier->bCamo = pSoldier->bCamo;
if (pNewSoldier->bCamo != 0)
{
pNewSoldier->CreateSoldierPalettes();
}
// 0verhaul: Need to pass certain flags over. COWERING is one of them. Others to be determined.
// copy uiStatusFlags, etc. - hayden :)
if (is_networked)
{
pNewSoldier->flags.uiStatusFlags = pSoldier->flags.uiStatusFlags;
pNewSoldier->ubProfile = pSoldier->ubProfile;
}
else
{
pNewSoldier->flags.uiStatusFlags |= pSoldier->flags.uiStatusFlags & (SOLDIER_COWERING | SOLDIER_MUTE | SOLDIER_GASSED);
}
if ( ubTeam == gbPlayerNum )
{
pNewSoldier->bVisible= 1;
}
//CHRISL: Rather then resorting the profile, which recreates all the items, what if we simply try and sort the
// objects that are already attached to the RPC we're hiring?
//if(UsingNewInventorySystem() == true)
{
// Start by direct copy of all BODYPOS items (armor, hands, head and LBE)
for(cnt = 0; cnt < (UINT32)BODYPOSFINAL; cnt++)
{
pNewSoldier->inv[cnt] = pSoldier->inv[cnt];
}
// Next, direct copy of the gunsling and knife pockets
pNewSoldier->inv[GUNSLINGPOCKPOS] = pSoldier->inv[GUNSLINGPOCKPOS];
pNewSoldier->inv[KNIFEPOCKPOS] = pSoldier->inv[KNIFEPOCKPOS];
// Then, try to autoplace everything else
for(cnt = BIGPOCKSTART; cnt < pNewSoldier->inv.size(); cnt++ )
{
if(pSoldier->inv[cnt].exists() == true)
{
success = PlaceInAnyPocket(pNewSoldier, &pSoldier->inv[cnt], FALSE);
if(!success)
{
PlaceObject( pNewSoldier, cnt, &pSoldier->inv[cnt] );
}
}
}
}
// OK, loop through all active merc slots, change
// Change ANY attacker's target if they were once on this guy.....
for ( uiSlot = 0; uiSlot < guiNumMercSlots; uiSlot++ )
{
pGroupMember = MercSlots[ uiSlot ];
if ( pGroupMember != NULL )
{
if ( pGroupMember->ubTargetID == pSoldier->ubID )
{
pGroupMember->ubTargetID = pNewSoldier->ubID;
}
}
}
// Set insertion gridNo
pNewSoldier->sInsertionGridNo = sOldGridNo;
if ( gfPotentialTeamChangeDuringDeath )
{
HandleCheckForDeathCommonCode( pSoldier );
}
if ( gfWorldLoaded && pSoldier->bInSector
//pSoldier->sSectorX == gWorldSectorX && pSoldier->sSectorY == gWorldSectorY && pSoldier->bSectorZ == gbWorldSectorZ
)
{
AddSoldierToSectorNoCalculateDirectionUseAnimation( ubID, pSoldier->usAnimState, pSoldier->usAniCode );
HandleSight(pNewSoldier, SIGHT_LOOK | SIGHT_RADIO);
}
// fix up the event queue...
// ChangeSoldierIDInQueuedEvents( ubOldID, uiOldUniqueId, pNewSoldier->ubID, pNewSoldier->uiUniqueSoldierIdValue );
if ( pNewSoldier->ubProfile != NO_PROFILE )
{
if ( ubTeam == gbPlayerNum )
{
gMercProfiles[ pNewSoldier->ubProfile ].ubMiscFlags |= PROFILE_MISC_FLAG_RECRUITED;
}
else
{
gMercProfiles[ pNewSoldier->ubProfile ].ubMiscFlags &= (~PROFILE_MISC_FLAG_RECRUITED);
}
}
}
// AT the low level check if this poor guy is in inv panel, else
// remove....
if ( gsCurInterfacePanel == SM_PANEL && gpSMCurrentMerc == pSoldier )
{
// Switch....
SetCurrentInterfacePanel( TEAM_PANEL );
}
return( pNewSoldier );
}
BOOLEAN RecruitRPC( UINT8 ubCharNum )
{
SOLDIERTYPE *pSoldier, *pNewSoldier;
// Get soldier pointer
pSoldier = FindSoldierByProfileID( ubCharNum, FALSE );
if (!pSoldier)
{
return( FALSE );
}
// OK, set recruit flag..
gMercProfiles[ ubCharNum ].ubMiscFlags |= PROFILE_MISC_FLAG_RECRUITED;
// Add this guy to our team!
pNewSoldier = ChangeSoldierTeam( pSoldier, gbPlayerNum );
if (!pNewSoldier)
{
return( FALSE );
}
if ( ubCharNum == SLAY )
{
if(gGameExternalOptions.fEnableSlayForever == TRUE)
{
if(gMercProfiles[ ubCharNum ].sSalary == 0)
gMercProfiles[ ubCharNum ].sSalary = gMercProfiles[ 7 ].sSalary;
if(gMercProfiles[ ubCharNum ].uiWeeklySalary == 0)
gMercProfiles[ ubCharNum ].uiWeeklySalary = gMercProfiles[ 7 ].uiWeeklySalary;
if(gMercProfiles[ ubCharNum ].uiBiWeeklySalary == 0)
gMercProfiles[ ubCharNum ].uiBiWeeklySalary = gMercProfiles[ 7 ].uiBiWeeklySalary;
pNewSoldier->iTotalContractLength = 7;
}
// slay will leave in a week
pNewSoldier->iEndofContractTime = GetWorldTotalMin() + ( 7 * 24 * 60 );
KickOutWheelchair( pNewSoldier );
}
else if ( ubCharNum == DYNAMO && gubQuest[ QUEST_FREE_DYNAMO ] == QUESTINPROGRESS )
{
EndQuest( QUEST_FREE_DYNAMO, pSoldier->sSectorX, pSoldier->sSectorY );
}
// handle town loyalty adjustment
HandleTownLoyaltyForNPCRecruitment( pNewSoldier );
// Try putting them into the current squad
if ( AddCharacterToSquad( pNewSoldier, (INT8)CurrentSquad( ) ) == FALSE )
{
AddCharacterToAnySquad( pNewSoldier );
}
ResetDeadSquadMemberList( pNewSoldier->bAssignment );
DirtyMercPanelInterface( pNewSoldier, DIRTYLEVEL2 );
if ( pNewSoldier->inv[ HANDPOS ].exists() == false )
{
// empty handed - swap in first available weapon
INT8 bSlot;
bSlot = FindObjClass( pNewSoldier, IC_WEAPON );
if ( bSlot != NO_SLOT )
{
// if ( Item[ pNewSoldier->inv[ bSlot ].usItem ].fFlags & ITEM_TWO_HANDED )
if ( Item[ pNewSoldier->inv[ bSlot ].usItem ].twohanded )
{
if ( bSlot != SECONDHANDPOS && pNewSoldier->inv[ SECONDHANDPOS ].exists() == true )
{
// need to move second hand item out first
AutoPlaceObject( pNewSoldier, &(pNewSoldier->inv[ SECONDHANDPOS ]), FALSE );
}
}
// swap item to hand
SwapObjs( pNewSoldier, bSlot, HANDPOS, TRUE );
}
}
if ( ubCharNum == IRA )
{
// trigger 0th PCscript line
TriggerNPCRecord( IRA, 0 );
}
// Set whatkind of merc am i
pNewSoldier->ubWhatKindOfMercAmI = MERC_TYPE__NPC;
if ( ubCharNum == SLAY && gGameExternalOptions.fEnableSlayForever == TRUE )
{
pNewSoldier->ubWhatKindOfMercAmI = MERC_TYPE__AIM_MERC;
}
//
//add a history log that tells the user that a npc has joined the team
//
// ( pass in pNewSoldier->sSectorX cause if its invalid, -1, n/a will appear as the sector in the history log )
AddHistoryToPlayersLog( HISTORY_RPC_JOINED_TEAM, pNewSoldier->ubProfile, GetWorldTotalMin(), pNewSoldier->sSectorX, pNewSoldier->sSectorY );
//remove the merc from the Personnel screens departed list ( if they have never been hired before, its ok to call it )
RemoveNewlyHiredMercFromPersonnelDepartedList( pSoldier->ubProfile );
return( TRUE );
}
BOOLEAN RecruitEPC( UINT8 ubCharNum )
{
SOLDIERTYPE *pSoldier, *pNewSoldier;
// Get soldier pointer
pSoldier = FindSoldierByProfileID( ubCharNum, FALSE );
if (!pSoldier)
{
return( FALSE );
}
// OK, set recruit flag..
gMercProfiles[ ubCharNum ].ubMiscFlags |= PROFILE_MISC_FLAG_EPCACTIVE;
gMercProfiles[ ubCharNum ].ubMiscFlags3 &= ~PROFILE_MISC_FLAG3_PERMANENT_INSERTION_CODE;
// Add this guy to our team!
pNewSoldier = ChangeSoldierTeam( pSoldier, gbPlayerNum );
pNewSoldier->ubWhatKindOfMercAmI = MERC_TYPE__EPC;
// Try putting them into the current squad
if ( AddCharacterToSquad( pNewSoldier, (INT8)CurrentSquad( ) ) == FALSE )
{
AddCharacterToAnySquad( pNewSoldier );
}
ResetDeadSquadMemberList( pNewSoldier->bAssignment );
DirtyMercPanelInterface( pNewSoldier, DIRTYLEVEL2 );
// Make the interface panel dirty..
// This will dirty the panel next frame...
gfRerenderInterfaceFromHelpText = TRUE;
// If we are a robot, look to update controller....
if ( pNewSoldier->flags.uiStatusFlags & SOLDIER_ROBOT )
{
pNewSoldier->UpdateRobotControllerGivenRobot( );
}
// Set whatkind of merc am i
pNewSoldier->ubWhatKindOfMercAmI = MERC_TYPE__EPC;
UpdateTeamPanelAssignments( );
return( TRUE );
}
BOOLEAN UnRecruitEPC( UINT8 ubCharNum )
{
SOLDIERTYPE *pSoldier, *pNewSoldier;
// Get soldier pointer
pSoldier = FindSoldierByProfileID( ubCharNum, FALSE );
if (!pSoldier)
{
return( FALSE );
}
if (pSoldier->ubWhatKindOfMercAmI != MERC_TYPE__EPC)
{
return( FALSE );
}
if ( pSoldier->bAssignment < ON_DUTY )
{
ResetDeadSquadMemberList( pSoldier->bAssignment );
}
// Rmeove from squad....
RemoveCharacterFromSquads( pSoldier );
// O< check if this is the only guy in the sector....
if ( gusSelectedSoldier == pSoldier->ubID )
{
gusSelectedSoldier = NOBODY;
}
// OK, UN set recruit flag..
gMercProfiles[ ubCharNum ].ubMiscFlags &= (~PROFILE_MISC_FLAG_EPCACTIVE);
// update sector values to current
// check to see if this person should disappear from the map after this
if ( (ubCharNum == JOHN || ubCharNum == MARY) && pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_B && pSoldier->bSectorZ == 0 )
{
gMercProfiles[ ubCharNum ].sSectorX = 0;
gMercProfiles[ ubCharNum ].sSectorY = 0;
gMercProfiles[ ubCharNum ].bSectorZ = 0;
}
else
{
gMercProfiles[ ubCharNum ].sSectorX = pSoldier->sSectorX;
gMercProfiles[ ubCharNum ].sSectorY = pSoldier->sSectorY;
gMercProfiles[ ubCharNum ].bSectorZ = pSoldier->bSectorZ;
}
// how do we decide whether or not to set this?
gMercProfiles[ ubCharNum ].ubMiscFlags3 |= PROFILE_MISC_FLAG3_PERMANENT_INSERTION_CODE;
gMercProfiles[ ubCharNum ].usStrategicInsertionData = pSoldier->sGridNo;
gMercProfiles[ ubCharNum ].fUseProfileInsertionInfo = TRUE;
gMercProfiles[ ubCharNum ].ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
// Add this guy to CIV team!
pNewSoldier = ChangeSoldierTeam( pSoldier, CIV_TEAM );
UpdateTeamPanelAssignments( );
return( TRUE );
}
INT8 WhichBuddy( UINT8 ubCharNum, UINT8 ubBuddy )
{
MERCPROFILESTRUCT * pProfile;
INT8 bLoop;
pProfile = &( gMercProfiles[ ubCharNum ] );
for (bLoop = 0; bLoop < 3; bLoop++)
{
if ( pProfile->bBuddy[bLoop] == ubBuddy )
{
return( bLoop );
}
}
return( -1 );
}
INT8 WhichHated( UINT8 ubCharNum, UINT8 ubHated )
{
MERCPROFILESTRUCT * pProfile;
INT8 bLoop;
pProfile = &( gMercProfiles[ ubCharNum ] );
for (bLoop = 0; bLoop < 3; bLoop++)
{
if ( pProfile->bHated[bLoop] == ubHated )
{
return( bLoop );
}
}
return( -1 );
}
BOOLEAN IsProfileATerrorist( UINT8 ubProfile )
{
if ( ubProfile == 83 || ubProfile == 111 ||
ubProfile == 64 || ubProfile == 112 ||
ubProfile == 82 || ubProfile == 110 )
{
return( TRUE );
}
else
{
return( FALSE );
}
}
BOOLEAN IsProfileAHeadMiner( UINT8 ubProfile )
{
if ( ubProfile == 106 || ubProfile == 148 ||
ubProfile == 156 || ubProfile == 157 ||
ubProfile == 158 )
{
return( TRUE );
}
else
{
return( FALSE );
}
}
void UpdateSoldierPointerDataIntoProfile( BOOLEAN fPlayerMercs )
{
UINT32 uiCount;
SOLDIERTYPE *pSoldier = NULL;
MERCPROFILESTRUCT * pProfile;
BOOLEAN fDoCopy = FALSE;
for( uiCount=0; uiCount < guiNumMercSlots; uiCount++)
{
pSoldier = MercSlots[ uiCount ];
if ( pSoldier != NULL )
{
if ( pSoldier->ubProfile != NO_PROFILE )
{
fDoCopy = FALSE;
// If we are above player mercs
if ( fPlayerMercs )
{
if ( pSoldier->ubProfile < FIRST_RPC || pSoldier->ubProfile >= GASTON )
{
fDoCopy = TRUE;
}
}
else
{
if ( pSoldier->ubProfile >= FIRST_RPC && pSoldier->ubProfile < GASTON )
{
fDoCopy = TRUE;
}
}
if ( fDoCopy )
{
// get profile...
pProfile = &( gMercProfiles[ pSoldier->ubProfile ] );
// Copy....
pProfile->bLife = pSoldier->stats.bLife;
pProfile->bLifeMax = pSoldier->stats.bLifeMax;
pProfile->bAgility = pSoldier->stats.bAgility;
pProfile->bLeadership = pSoldier->stats.bLeadership;
pProfile->bDexterity = pSoldier->stats.bDexterity;
pProfile->bStrength = pSoldier->stats.bStrength;
pProfile->bWisdom = pSoldier->stats.bWisdom;
pProfile->bExpLevel = pSoldier->stats.bExpLevel;
pProfile->bMarksmanship = pSoldier->stats.bMarksmanship;
pProfile->bMedical = pSoldier->stats.bMedical;
pProfile->bMechanical = pSoldier->stats.bMechanical;
pProfile->bExplosive = pSoldier->stats.bExplosive;
pProfile->bScientific = pSoldier->stats.bScientific;
}
}
}
}
}
BOOLEAN DoesMercHaveABuddyOnTheTeam( UINT8 ubMercID )
{
UINT8 ubCnt;
INT8 bBuddyID;
// loop through the list of people the merc is buddies with
for(ubCnt=0; ubCnt< 3; ubCnt++)
{
//see if the merc has a buddy on the team
bBuddyID = gMercProfiles[ ubMercID ].bBuddy[ubCnt];
//If its not a valid 'buddy'
if( bBuddyID < 0 )
continue;
if( IsMercOnTeam( bBuddyID ) )
{
if( !IsMercDead( bBuddyID ) )
{
return( TRUE );
}
}
}
return( FALSE );
}
BOOLEAN MercIsHot( SOLDIERTYPE * pSoldier )
{
if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait == HEAT_INTOLERANT )
{
if ( SectorTemperature( GetWorldMinutesInDay(), pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ) > 0 )
{
return( TRUE );
}
}
return( FALSE );
}
SOLDIERTYPE * SwapLarrysProfiles( SOLDIERTYPE * pSoldier )
{
UINT8 ubSrcProfile;
UINT8 ubDestProfile;
MERCPROFILESTRUCT * pNewProfile;
ubSrcProfile = pSoldier->ubProfile;
if ( ubSrcProfile == LARRY_NORMAL)
{
ubDestProfile = LARRY_DRUNK;
}
else if ( ubSrcProfile == LARRY_DRUNK )
{
ubDestProfile = LARRY_NORMAL;
}
else
{
// I don't think so!
return( pSoldier );
}
pNewProfile = &gMercProfiles[ ubDestProfile ];
pNewProfile->ubMiscFlags2 = gMercProfiles[ ubSrcProfile ].ubMiscFlags2;
pNewProfile->ubMiscFlags = gMercProfiles[ ubSrcProfile ].ubMiscFlags;
pNewProfile->sSectorX = gMercProfiles[ ubSrcProfile ].sSectorX;
pNewProfile->sSectorY = gMercProfiles[ ubSrcProfile ].sSectorY;
pNewProfile->uiDayBecomesAvailable = gMercProfiles[ ubSrcProfile ].uiDayBecomesAvailable;
pNewProfile->usKills = gMercProfiles[ ubSrcProfile ].usKills;
pNewProfile->usAssists = gMercProfiles[ ubSrcProfile ].usAssists;
pNewProfile->usShotsFired = gMercProfiles[ ubSrcProfile ].usShotsFired;
pNewProfile->usShotsHit = gMercProfiles[ ubSrcProfile ].usShotsHit;
pNewProfile->usBattlesFought = gMercProfiles[ ubSrcProfile ].usBattlesFought;
pNewProfile->usTimesWounded = gMercProfiles[ ubSrcProfile ].usTimesWounded;
pNewProfile->usTotalDaysServed = gMercProfiles[ ubSrcProfile ].usTotalDaysServed;
pNewProfile->bResigned = gMercProfiles[ ubSrcProfile ].bResigned;
pNewProfile->bActive = gMercProfiles[ ubSrcProfile ].bActive;
pNewProfile->fUseProfileInsertionInfo = gMercProfiles[ ubSrcProfile ].fUseProfileInsertionInfo;
pNewProfile->sGridNo = gMercProfiles[ ubSrcProfile ].sGridNo;
pNewProfile->ubQuoteActionID = gMercProfiles[ ubSrcProfile ].ubQuoteActionID;
pNewProfile->ubLastQuoteSaid = gMercProfiles[ ubSrcProfile ].ubLastQuoteSaid;
pNewProfile->ubStrategicInsertionCode = gMercProfiles[ ubSrcProfile ].ubStrategicInsertionCode;
pNewProfile->bMercStatus = gMercProfiles[ ubSrcProfile ].bMercStatus;
pNewProfile->bSectorZ = gMercProfiles[ ubSrcProfile ].bSectorZ;
pNewProfile->usStrategicInsertionData = gMercProfiles[ ubSrcProfile ].usStrategicInsertionData;
pNewProfile->sTrueSalary = gMercProfiles[ ubSrcProfile ].sTrueSalary;
pNewProfile->ubMiscFlags3 = gMercProfiles[ ubSrcProfile ].ubMiscFlags3;
pNewProfile->ubDaysOfMoraleHangover = gMercProfiles[ ubSrcProfile ].ubDaysOfMoraleHangover;
pNewProfile->ubNumTimesDrugUseInLifetime = gMercProfiles[ ubSrcProfile ].ubNumTimesDrugUseInLifetime;
pNewProfile->uiPrecedentQuoteSaid = gMercProfiles[ ubSrcProfile ].uiPrecedentQuoteSaid;
pNewProfile->sPreCombatGridNo = gMercProfiles[ ubSrcProfile ].sPreCombatGridNo;
// CJC: this is causing problems so just skip the transfer of exp...
/*
pNewProfile->sLifeGain = gMercProfiles[ ubSrcProfile ].sLifeGain;
pNewProfile->sAgilityGain = gMercProfiles[ ubSrcProfile ].sAgilityGain;
pNewProfile->sDexterityGain = gMercProfiles[ ubSrcProfile ].sDexterityGain;
pNewProfile->sStrengthGain = gMercProfiles[ ubSrcProfile ].sStrengthGain;
pNewProfile->sLeadershipGain = gMercProfiles[ ubSrcProfile ].sLeadershipGain;
pNewProfile->sWisdomGain = gMercProfiles[ ubSrcProfile ].sWisdomGain;
pNewProfile->sExpLevelGain = gMercProfiles[ ubSrcProfile ].sExpLevelGain;
pNewProfile->sMarksmanshipGain = gMercProfiles[ ubSrcProfile ].sMarksmanshipGain;
pNewProfile->sMedicalGain = gMercProfiles[ ubSrcProfile ].sMedicalGain;
pNewProfile->sMechanicGain = gMercProfiles[ ubSrcProfile ].sMechanicGain;
pNewProfile->sExplosivesGain = gMercProfiles[ ubSrcProfile ].sExplosivesGain;
pNewProfile->bLifeDelta = gMercProfiles[ ubSrcProfile ].bLifeDelta;
pNewProfile->bAgilityDelta = gMercProfiles[ ubSrcProfile ].bAgilityDelta;
pNewProfile->bDexterityDelta = gMercProfiles[ ubSrcProfile ].bDexterityDelta;
pNewProfile->bStrengthDelta = gMercProfiles[ ubSrcProfile ].bStrengthDelta;
pNewProfile->bLeadershipDelta = gMercProfiles[ ubSrcProfile ].bLeadershipDelta;
pNewProfile->bWisdomDelta = gMercProfiles[ ubSrcProfile ].bWisdomDelta;
pNewProfile->bExpLevelDelta = gMercProfiles[ ubSrcProfile ].bExpLevelDelta;
pNewProfile->bMarksmanshipDelta = gMercProfiles[ ubSrcProfile ].bMarksmanshipDelta;
pNewProfile->bMedicalDelta = gMercProfiles[ ubSrcProfile ].bMedicalDelta;
pNewProfile->bMechanicDelta = gMercProfiles[ ubSrcProfile ].bMechanicDelta;
pNewProfile->bExplosivesDelta = gMercProfiles[ ubSrcProfile ].bExplosivesDelta;
*/
pNewProfile->bInvStatus = gMercProfiles[ ubSrcProfile ].bInvStatus;
pNewProfile->bInvNumber = gMercProfiles[ ubSrcProfile ].bInvNumber;
pNewProfile->inv = gMercProfiles[ ubSrcProfile ].inv;
memcpy( pNewProfile->bMercTownReputation , gMercProfiles[ ubSrcProfile ].bMercTownReputation , sizeof( UINT8 ) * 20 );
// remove face
DeleteSoldierFace( pSoldier );
pSoldier->ubProfile = ubDestProfile;
// create new face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
// replace profile in group
ReplaceSoldierProfileInPlayerGroup( pSoldier->ubGroupID, ubSrcProfile, ubDestProfile );
pSoldier->stats.bStrength = pNewProfile->bStrength + pNewProfile->bStrengthDelta;
pSoldier->stats.bDexterity = pNewProfile->bDexterity + pNewProfile->bDexterityDelta;
pSoldier->stats.bAgility = pNewProfile->bAgility + pNewProfile->bAgilityDelta;
pSoldier->stats.bWisdom = pNewProfile->bWisdom + pNewProfile->bWisdomDelta;
pSoldier->stats.bExpLevel = pNewProfile->bExpLevel + pNewProfile->bExpLevelDelta;
pSoldier->stats.bLeadership = pNewProfile->bLeadership + pNewProfile->bLeadershipDelta;
pSoldier->stats.bMarksmanship = pNewProfile->bMarksmanship + pNewProfile->bMarksmanshipDelta;
pSoldier->stats.bMechanical = pNewProfile->bMechanical + pNewProfile->bMechanicDelta;
pSoldier->stats.bMedical = pNewProfile->bMedical + pNewProfile->bMedicalDelta;
pSoldier->stats.bExplosive = pNewProfile->bExplosive + pNewProfile->bExplosivesDelta;
if ( pSoldier->ubProfile == LARRY_DRUNK )
{
SetFactTrue( FACT_LARRY_CHANGED );
}
else
{
SetFactFalse( FACT_LARRY_CHANGED );
}
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
return( pSoldier );
}
BOOLEAN DoesNPCOwnBuilding( SOLDIERTYPE *pSoldier, INT32 sGridNo )
{
UINT8 ubRoomInfo;
// Get room info
ubRoomInfo = gubWorldRoomInfo[ sGridNo ];
if ( ubRoomInfo == NO_ROOM )
{
return( FALSE );
}
// Are we an NPC?
if ( pSoldier->bTeam != CIV_TEAM )
{
return( FALSE );
}
// OK, check both ranges
if ( ubRoomInfo >= gMercProfiles[ pSoldier->ubProfile ].ubRoomRangeStart[ 0 ] &&
ubRoomInfo <= gMercProfiles[ pSoldier->ubProfile ].ubRoomRangeEnd[ 0 ] )
{
return( TRUE );
}
if ( ubRoomInfo >= gMercProfiles[ pSoldier->ubProfile ].ubRoomRangeStart[ 1 ] &&
ubRoomInfo <= gMercProfiles[ pSoldier->ubProfile ].ubRoomRangeEnd[ 1 ] )
{
return( TRUE );
}
return( FALSE );
}
BOOLEAN IsProfileIdAnAimOrMERCMerc( UINT8 ubProfileID )
{
if( ubProfileID < BIFF ||
( ubProfileID >= BIFF && ubProfileID <= BUBBA ) ||
ubProfileID >= GASTON )
{
return( TRUE );
}
return( FALSE );
}
void OverwriteMercProfileWithXMLData( UINT32 uiLoop )
{
//////////////////////////////////////////////////////////////////////////////////
//
// HEADROCK PROFEX: Profile Externalization
//
// This is a complete hack which is meant for temporary use until a better system
// can be implemented. This bit OVERWRITES data accumulated so far, by drawing
// new data from XML. This allows making PROEDIT obsolete.
//
//////////////////////////////////////////////////////////////////////////////////
wcscpy(gMercProfiles[ uiLoop ].zName, tempProfiles[ uiLoop ].zName) ;
wcscpy(gMercProfiles[ uiLoop ].zNickname, tempProfiles[ uiLoop ].zNickname) ;
gMercProfiles[ uiLoop ].ubFaceIndex = tempProfiles[ uiLoop ].ubFaceIndex ;
gMercProfiles[ uiLoop ].usEyesX = tempProfiles[ uiLoop ].usEyesX ;
gMercProfiles[ uiLoop ].usEyesY = tempProfiles[ uiLoop ].usEyesY ;
gMercProfiles[ uiLoop ].usMouthX = tempProfiles[ uiLoop ].usMouthX ;
gMercProfiles[ uiLoop ].usMouthY = tempProfiles[ uiLoop ].usMouthY ;
gMercProfiles[ uiLoop ].uiEyeDelay = tempProfiles[ uiLoop ].uiEyeDelay ;
gMercProfiles[ uiLoop ].uiMouthDelay = tempProfiles[ uiLoop ].uiMouthDelay ;
gMercProfiles[ uiLoop ].uiBlinkFrequency = tempProfiles[ uiLoop ].uiBlinkFrequency ;
gMercProfiles[ uiLoop ].uiExpressionFrequency = tempProfiles[ uiLoop ].uiExpressionFrequency ;
strcpy(gMercProfiles[ uiLoop ].PANTS, tempProfiles[ uiLoop ].PANTS) ;
strcpy(gMercProfiles[ uiLoop ].VEST, tempProfiles[ uiLoop ].VEST) ;
strcpy(gMercProfiles[ uiLoop ].SKIN, tempProfiles[ uiLoop ].SKIN) ;
strcpy(gMercProfiles[ uiLoop ].HAIR, tempProfiles[ uiLoop ].HAIR) ;
gMercProfiles[ uiLoop ].bSex = tempProfiles[ uiLoop ].bSex ;
gMercProfiles[ uiLoop ].ubBodyType = tempProfiles[ uiLoop ].ubBodyType ;
gMercProfiles[ uiLoop ].uiBodyTypeSubFlags = tempProfiles[ uiLoop ].uiBodyTypeSubFlags ;
gMercProfiles[ uiLoop ].bAttitude = tempProfiles[ uiLoop ].bAttitude ;
gMercProfiles[ uiLoop ].bPersonalityTrait = tempProfiles[ uiLoop ].bPersonalityTrait ;
gMercProfiles[ uiLoop ].ubNeedForSleep = tempProfiles[ uiLoop ].ubNeedForSleep ;
gMercProfiles[ uiLoop ].bReputationTolerance = tempProfiles[ uiLoop ].bReputationTolerance ;
gMercProfiles[ uiLoop ].bDeathRate = tempProfiles[ uiLoop ].bDeathRate ;
gMercProfiles[ uiLoop ].bLifeMax = tempProfiles[ uiLoop ].bLifeMax ;
gMercProfiles[ uiLoop ].bLife = tempProfiles[ uiLoop ].bLife ;
gMercProfiles[ uiLoop ].bStrength = tempProfiles[ uiLoop ].bStrength ;
gMercProfiles[ uiLoop ].bAgility = tempProfiles[ uiLoop ].bAgility ;
gMercProfiles[ uiLoop ].bDexterity = tempProfiles[ uiLoop ].bDexterity ;
gMercProfiles[ uiLoop ].bWisdom = tempProfiles[ uiLoop ].bWisdom ;
gMercProfiles[ uiLoop ].bMarksmanship = tempProfiles[ uiLoop ].bMarksmanship ;
gMercProfiles[ uiLoop ].bExplosive = tempProfiles[ uiLoop ].bExplosive ;
gMercProfiles[ uiLoop ].bLeadership = tempProfiles[ uiLoop ].bLeadership ;
gMercProfiles[ uiLoop ].bMedical = tempProfiles[ uiLoop ].bMedical ;
gMercProfiles[ uiLoop ].bMechanical = tempProfiles[ uiLoop ].bMechanical ;
gMercProfiles[ uiLoop ].bExpLevel = tempProfiles[ uiLoop ].bExpLevel ;
gMercProfiles[ uiLoop ].bEvolution = tempProfiles[ uiLoop ].bEvolution ;
gMercProfiles[ uiLoop ].bSkillTrait = tempProfiles[ uiLoop ].bSkillTrait ;
gMercProfiles[ uiLoop ].bSkillTrait2 = tempProfiles[ uiLoop ].bSkillTrait2 ;
memcpy( &(gMercProfiles[ uiLoop ].bBuddy), &(tempProfiles[ uiLoop ].bBuddy), 5 * sizeof (INT8));
gMercProfiles[ uiLoop ].bLearnToLike = tempProfiles[ uiLoop ].bLearnToLike ;
gMercProfiles[ uiLoop ].bLearnToLikeTime = tempProfiles[ uiLoop ].bLearnToLikeTime ;
memcpy( &(gMercProfiles[ uiLoop ].bHated), &(tempProfiles[ uiLoop ].bHated), 5 * sizeof (INT8));
memcpy( &(gMercProfiles[ uiLoop ].bHatedTime), &(tempProfiles[ uiLoop ].bHatedTime), 5 * sizeof (INT8));
gMercProfiles[ uiLoop ].bLearnToHate = tempProfiles[ uiLoop ].bLearnToHate ;
gMercProfiles[ uiLoop ].bLearnToHateTime = tempProfiles[ uiLoop ].bLearnToHateTime ;
gMercProfiles[ uiLoop ].sSalary = tempProfiles[ uiLoop ].sSalary ;
gMercProfiles[ uiLoop ].uiWeeklySalary = tempProfiles[ uiLoop ].uiWeeklySalary ;
gMercProfiles[ uiLoop ].uiBiWeeklySalary = tempProfiles[ uiLoop ].uiBiWeeklySalary ;
gMercProfiles[ uiLoop ].bMedicalDeposit = tempProfiles[ uiLoop ].bMedicalDeposit ;
gMercProfiles[ uiLoop ].sMedicalDepositAmount = tempProfiles[ uiLoop ].sMedicalDepositAmount ;
gMercProfiles[ uiLoop ].usOptionalGearCost = tempProfiles[ uiLoop ].usOptionalGearCost ;
gMercProfiles[ uiLoop ].bArmourAttractiveness = tempProfiles[ uiLoop ].bArmourAttractiveness ;
gMercProfiles[ uiLoop ].bMainGunAttractiveness = tempProfiles[ uiLoop ].bMainGunAttractiveness ;
memcpy( &(gMercProfiles[ uiLoop ].usApproachFactor), &(tempProfiles[ uiLoop ].usApproachFactor), 4 * sizeof (UINT16));
if (tempProfiles[ uiLoop ].fGoodGuy)
{
gMercProfiles[ uiLoop ].ubMiscFlags3 |= PROFILE_MISC_FLAG3_GOODGUY;
}
}
void OverwriteMercOpinionsWithXMLData( UINT32 uiLoop )
{
UINT8 cnt;
for (cnt=0; cnt<75; cnt++ )
{
gMercProfiles[ uiLoop ].bMercOpinion[cnt] = tempProfiles[ uiLoop ].bMercOpinion[cnt] ;
}
}