#ifdef PRECOMPILEDHEADERS
	#include "Laptop All.h"
#else
	#include "CharProfile.h"
	#include "IMP MainPage.h"
	#include "IMP HomePage.h"
	#include "IMPVideoObjects.h"
	#include "Utilities.h"
	#include "Debug.h"
	#include "WordWrap.h"
	#include "Encrypted File.h"
	#include "cursors.h"
	#include "laptop.h"
	#include "IMP Compile Character.h"
	#include "soldier profile type.h"
	#include "IMP Text System.h"
	#include "IMP Confirm.h"
	#include "finances.h"
	#include "Soldier Profile.h"
	#include "Soldier Profile Type.h"
	#include "Soldier Control.h"
	#include "IMP Portraits.h"
	#include "Overhead.h"
	#include "finances.h"
	#include "history.h"
	#include "Game Clock.h"
	#include "email.h"
	#include "Game Event Hook.h"
	#include "LaptopSave.h"
	#include "strategic.h"
	#include "weapons.h"
	#include "Random.h"
	#include "GameVersion.h"
	#include "GameSettings.h"
	#include "IMP Gear.h"				// added by Flugente
	#include "IMP Gear Entrance.h"		// added by Flugente
#endif

#include <vfs/Core/vfs.h>
#include <vfs/Aspects/vfs_settings.h>

#include "Soldier Profile.h"

#include "SaveLoadGame.h"

// Changed by ADB (rev 1513) to resolve IMPs created prior to structural changes
//#define IMP_FILENAME_SUFFIX ".dat"
#define OLD_IMP_FILENAME_SUFFIX ".dat"
#define NEW_IMP_FILENAME_SUFFIX ".dat2"



//CHRISL: structure needed to store temporary inventory information during IMP creation
typedef struct
{
	UINT16		inv;
	UINT16		iSize;
	UINT32		iClass;
	UINT8		iStatus;
	UINT8		iNumber;
}	INVNODE;

IMP_ITEM_CHOICE_TYPE gIMPItemChoices[MAX_IMP_ITEM_TYPES];
	
void GiveIMPRandomItems( MERCPROFILESTRUCT *pProfile, UINT8 typeIndex );
void GiveIMPItems( MERCPROFILESTRUCT *pProfile, INT8 abilityValue, UINT8 typeIndex );

UINT32 giIMPConfirmButton[ 2 ];
UINT32 giIMPConfirmButtonImage[ 2 ];
BOOLEAN fNoAlreadySelected = FALSE;

IMP_VALUES gIMPValues[NUM_PROFILES];

/*
UINT16 uiEyeXPositions[ ]={
	8,
	9,
	8,
	6,
	13,
	11,
	8,
	8,
	4,				//208
	5,				//209
	7,
	5,				//211
	7,
	11,
	8,				//214
	5,
};

UINT16 uiEyeYPositions[ ]=
{
	5,
	4,
	5,
	6,
	5,
	5,
	4,
	4,
	4,		//208
	5,
	5,		//210
	7,
	6,		//212
	5,
	5,		//214
	6,
};

UINT16 uiMouthXPositions[]=
{
	8,
	9,
	7,
	7,
	11,
	10,
	8,
	8,
	5,		//208
	6,
	7,		//210
	6,
	7,		//212
	9,
	7,		//214
	5,
};

UINT16 uiMouthYPositions[]={
	21,
	23,
	24,
	25,
	23,
	24,
	24,
	24,
	25,		//208
	24,
	24,		//210
	26,
	24,		//212
	23,
	24,		//214
	26,
};
*/
BOOLEAN fLoadingCharacterForPreviousImpProfile = FALSE;

void CreateConfirmButtons( void );
void DestroyConfirmButtons( void );
void GiveItemsToPC( UINT8 ubProfileId );
void MakeProfileInvItemThisSlot(MERCPROFILESTRUCT *pProfile, UINT32 uiPos, UINT16 usItem, UINT8 ubStatus, UINT8 ubHowMany);
INT32 FirstFreeBigEnoughPocket(MERCPROFILESTRUCT *pProfile, UINT16 usItem, UINT8 ubHowMany);

// CHRISL:
void RedistributeStartingItems(MERCPROFILESTRUCT *pProfile, UINT16 usItem, UINT8 sPocket);
void DistributeInitialGear(MERCPROFILESTRUCT *pProfile);
INT32 FirstFreeBigEnoughPocket(MERCPROFILESTRUCT *pProfile, INVNODE *tInv);
INT32 AnyFreeBigEnoughPocket(MERCPROFILESTRUCT *pProfile, INVNODE *tInv);
INT32 SpecificFreePocket(MERCPROFILESTRUCT *pProfile, UINT16 usItem, UINT8 ubHowMany, UINT32 usClass);
INT32 PickPocket(MERCPROFILESTRUCT *pProfile, UINT8 ppStart, UINT8 ppStop, UINT16 usItem, UINT8 iNumber, UINT8 * cap);

// callbacks
void BtnIMPConfirmNo( GUI_BUTTON *btn,INT32 reason );
void BtnIMPConfirmYes( GUI_BUTTON *btn,INT32 reason );


void EnterIMPConfirm( void )
{
	// create buttons
	CreateConfirmButtons( );
	return;
}

void RenderIMPConfirm( void )
{

	// the background
	RenderProfileBackGround( );

		// indent
	RenderAvgMercIndentFrame(90, 40 );

	// highlight answer
	PrintImpText( );

	return;
}

void ExitIMPConfirm( void )
{

	// destroy buttons
	DestroyConfirmButtons( );
	return;
}

void HandleIMPConfirm( void )
{
	return;
}

void CreateConfirmButtons( void )
{
	// create buttons for confirm screen

	giIMPConfirmButtonImage[0]=	LoadButtonImage( "LAPTOP\\button_2.sti" ,-1,0,-1,1,-1 );
	giIMPConfirmButton[0] = CreateIconAndTextButton( giIMPConfirmButtonImage[0], pImpButtonText[ 16 ], FONT12ARIAL,
														FONT_WHITE, DEFAULT_SHADOW,
														FONT_WHITE, DEFAULT_SHADOW,
														TEXT_CJUSTIFIED,
														LAPTOP_SCREEN_UL_X +	( 136 ), LAPTOP_SCREEN_WEB_UL_Y + ( 254 ), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
														BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPConfirmYes);

	giIMPConfirmButtonImage[1]=	LoadButtonImage( "LAPTOP\\button_2.sti" ,-1,0,-1,1,-1 );
	giIMPConfirmButton[1] = CreateIconAndTextButton( giIMPConfirmButtonImage[ 1 ], pImpButtonText[ 17 ], FONT12ARIAL,
														FONT_WHITE, DEFAULT_SHADOW,
														FONT_WHITE, DEFAULT_SHADOW,
														TEXT_CJUSTIFIED,
														LAPTOP_SCREEN_UL_X +	( 136 ), LAPTOP_SCREEN_WEB_UL_Y + ( 314 ), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
														BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPConfirmNo);

 SetButtonCursor(giIMPConfirmButton[ 0 ], CURSOR_WWW);
 SetButtonCursor(giIMPConfirmButton[ 1 ], CURSOR_WWW);

	return;
}


void DestroyConfirmButtons( void )
{
	// destroy buttons for confirm screen

	RemoveButton(giIMPConfirmButton[ 0 ] );
	UnloadButtonImage(giIMPConfirmButtonImage[ 0 ] );


	RemoveButton(giIMPConfirmButton[ 1 ] );
	UnloadButtonImage(giIMPConfirmButtonImage[ 1 ] );
	return;
}



BOOLEAN AddCharacterToPlayersTeam( void )
{
	MERC_HIRE_STRUCT HireMercStruct;

	// last minute chage to make sure merc with right facehas not only the right body but body specific skills...
	// ie..small mercs have martial arts..but big guys and women don't don't

	HandleMercStatsForChangesInFace( );

	memset(&HireMercStruct, 0, sizeof(MERC_HIRE_STRUCT));

	HireMercStruct.ubProfileID = ( UINT8 )( LaptopSaveInfo.iIMPIndex ) ;

	if( fLoadingCharacterForPreviousImpProfile == FALSE )
	{
		// give them items
		GiveItemsToPC( 	HireMercStruct.ubProfileID );
	}

	HireMercStruct.sSectorX									= gsMercArriveSectorX;
	HireMercStruct.sSectorY									= gsMercArriveSectorY;
	HireMercStruct.fUseLandingZoneForArrival = TRUE;

	HireMercStruct.fCopyProfileItemsOver = TRUE;

	// indefinite contract length
	HireMercStruct.iTotalContractLength = -1;

	HireMercStruct.ubInsertionCode	= INSERTION_CODE_ARRIVING_GAME;
	HireMercStruct.uiTimeTillMercArrives = GetMercArrivalTimeOfDay( );

	if ( gIMPValues[iPortraitNumber].PortraitId != 0 )
	{
		SetProfileFaceData( HireMercStruct.ubProfileID, (UINT8)(gIMPValues[iPortraitNumber].PortraitId), gIMPValues[iPortraitNumber].uiEyeXPositions, gIMPValues[iPortraitNumber].uiEyeYPositions, gIMPValues[iPortraitNumber].uiMouthXPositions, gIMPValues[iPortraitNumber].uiMouthYPositions );
	}		
		
	//if we succesfully hired the merc
	if( !HireMerc( &HireMercStruct ) )
	{
		return(FALSE);
	}
	
	return (TRUE);
}


void	BtnIMPConfirmYes(GUI_BUTTON *btn,INT32 reason)
{
	// btn callback for IMP Homepage About US button
	if (!(btn->uiFlags & BUTTON_ENABLED))
		return;

	if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
	{
		btn->uiFlags|=(BUTTON_CLICKED_ON);
	}
	else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
	{
		if( btn->uiFlags & BUTTON_CLICKED_ON )
		{

			// reset button
			btn->uiFlags&=~(BUTTON_CLICKED_ON);
// Madd
/*			if( LaptopSaveInfo.fIMPCompletedFlag )
			{
				// already here, leave
				return;
			}
*/
			// SANDRO - changed to find the actual profile cost
			//if( LaptopSaveInfo.iCurrentBalance < COST_OF_PROFILE )

			// silversurfer: We need to store the profile cost here because right now our new IMP doesn't occupy a slot yet.
			// However function iGetProfileCost() will already calculate price including that slot. We would charge too much money after the IMP is created below.
			INT32 iIMPCost = GetProfileCost(TRUE, FALSE);
			if( LaptopSaveInfo.iCurrentBalance < iIMPCost ) 
			{
				// not enough
				 return;
			}

			CreateACharacterFromPlayerEnteredStats( );

			// line moved by CJC Nov 28 2002 to AFTER the check for money
			LaptopSaveInfo.fIMPCompletedFlag = TRUE;

			// charge the player
			// SANDRO - changed to find the actual profile cost
			//AddTransactionToPlayersBook(IMP_PROFILE, (UINT8)(LaptopSaveInfo.iIMPIndex), GetWorldTotalMin( ), - ( COST_OF_PROFILE ) );
			AddTransactionToPlayersBook(IMP_PROFILE, (UINT8)(LaptopSaveInfo.iIMPIndex), GetWorldTotalMin( ), - ( iIMPCost ) );

			AddHistoryToPlayersLog( HISTORY_CHARACTER_GENERATED, 0,GetWorldTotalMin( ), -1, -1 );
			AddCharacterToPlayersTeam( );

			// write the created imp merc
			WriteOutCurrentImpCharacter( ( UINT8 )( LaptopSaveInfo.iIMPIndex ) );

			fButtonPendingFlag = TRUE;
			iCurrentImpPage = IMP_HOME_PAGE;

			//Kaiden: Below is the Imp personality E-mail as it was.
/*
			// send email notice
			//AddEmail(IMP_EMAIL_PROFILE_RESULTS, IMP_EMAIL_PROFILE_RESULTS_LENGTH, IMP_PROFILE_RESULTS, GetWorldTotalMin( ),TYPE_EMAIL_NONE );
			AddFutureDayStrategicEvent( EVENT_DAY2_ADD_EMAIL_FROM_IMP, 60 * 7, 0, 2 );
*/

			//Kaiden: And here is my Answer to the IMP E-mails only
			// profiling the last IMP made. You get the results immediately
			AddEmail(IMP_EMAIL_PROFILE_RESULTS, IMP_EMAIL_PROFILE_RESULTS_LENGTH, IMP_PROFILE_RESULTS, GetWorldTotalMin( ), LaptopSaveInfo.iIMPIndex, -1, TYPE_EMAIL_EMAIL_EDT);

			//RenderCharProfile( );

			ResetCharacterStats();

			//Display a popup msg box telling the user when and where the merc will arrive
			//DisplayPopUpBoxExplainingMercArrivalLocationAndTime( LaptopSaveInfo.iIMPIndex );

			//reset the id of the last merc so we dont get the DisplayPopUpBoxExplainingMercArrivalLocationAndTime() pop up box in another screen by accident
			LaptopSaveInfo.sLastHiredMerc.iIdOfMerc = -1;
		}
	}
}

// fixed? by CJC Nov 28 2002
void BtnIMPConfirmNo( GUI_BUTTON *btn,INT32 reason )
{
		// btn callback for IMP Homepage About US button
	if (!(btn->uiFlags & BUTTON_ENABLED))
		return;

	if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
	{
		btn->uiFlags|=(BUTTON_CLICKED_ON);
	}
	else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
	{
		if( btn->uiFlags & BUTTON_CLICKED_ON )
		{

			iCurrentImpPage = IMP_FINISH;

			/*

			LaptopSaveInfo.fIMPCompletedFlag = FALSE;
			ResetCharacterStats();

			fButtonPendingFlag = TRUE;
			iCurrentImpPage = IMP_HOME_PAGE;
			*/
			/*
			if( fNoAlreadySelected == TRUE )
			{
				// already selected no 
				fButtonPendingFlag = TRUE;
				iCurrentImpPage = IMP_HOME_PAGE;
			}
		fNoAlreadySelected = TRUE;
			*/
		btn->uiFlags&=~(BUTTON_CLICKED_ON);
		}
	}
}

/*
void BtnIMPConfirmNo( GUI_BUTTON *btn,INT32 reason )
{
	

		// btn callback for IMP Homepage About US button
	if (!(btn->uiFlags & BUTTON_ENABLED))
		return;

	if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
	{
		btn->uiFlags|=(BUTTON_CLICKED_ON);
	}
	else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
	{
		if( btn->uiFlags & BUTTON_CLICKED_ON )
		{
			LaptopSaveInfo.fIMPCompletedFlag = TRUE;
			if( fNoAlreadySelected == TRUE )
			{
				// already selected no 
				fButtonPendingFlag = TRUE;
				iCurrentImpPage = IMP_HOME_PAGE;
			}
		fNoAlreadySelected = TRUE;
		btn->uiFlags&=~(BUTTON_CLICKED_ON);
		}
	}
}
*/

// SANDRO - improved this function
//#define PROFILE_HAS_SKILL_TRAIT( p, t ) ( gGameOptions.fNewTraitSystem ? ((p->bSkillTrait == t) || (p->bSkillTrait2 == t) || (p->bSkillTrait3 == t)) : ((p->bSkillTrait == t) || (p->bSkillTrait2 == t)))
#define PROFILE_HAS_SKILL_TRAIT( p, t ) ( ProfileHasSkillTrait( p, t ) > 0 )
// DBrot: need a check for experts
#define PROFILE_HAS_EXPERT_TRAIT( p, t ) ( ProfileHasSkillTrait( p, t ) > 1 )
//CHRISL: New function to handle proper distribution of starting gear
void DistributeInitialGear(MERCPROFILESTRUCT *pProfile)
{
	INVNODE			tInv[NUM_INV_SLOTS];
	int				i, j, number;
	UINT8			count = 0, length;
	int				iOrder[NUM_INV_SLOTS];
	INT32			iSlot;
	BOOLEAN			iSet = FALSE;

	// First move profile information to temporary storage
	for(i=INV_START_POS; i<NUM_INV_SLOTS; i++)
	{
		if(pProfile->inv[i] != NOTHING)
		{
			if((UsingNewInventorySystem() == true))
			{
				if(Item[pProfile->inv[i]].ItemSize != gGameExternalOptions.guiOIVSizeNumber) //JMich
				{
					tInv[count].inv = pProfile->inv[i];
					tInv[count].iSize = Item[pProfile->inv[i]].ItemSize;
					tInv[count].iClass = Item[pProfile->inv[i]].usItemClass;
					tInv[count].iStatus = (pProfile->bInvStatus[i] > 0) ? pProfile->bInvStatus[i] : 100;
					tInv[count].iNumber = (pProfile->bInvNumber[i] == 0) ? 1 :pProfile->bInvNumber[i];
					count++;
				}
				pProfile->inv[i] = 0;
				pProfile->bInvStatus[i] = 0;
				pProfile->bInvNumber[i] = 0;
			}
			else
			{
				if(Item[pProfile->inv[i]].usItemClass == IC_LBEGEAR)
				{
					pProfile->inv[i] = 0;
					pProfile->bInvStatus[i] = 0;
					pProfile->bInvNumber[i] = 0;
				}
			}
		}
	}

	//Now that we've weeded out illegal items, skip the rest if we're in OldInv
	if((UsingNewInventorySystem() == false))
		return;

	length = count;
	count = 0;
	// Next sort list by size
	for(j=gGameExternalOptions.guiMaxItemSize; j>=0; j--) //JMich
	{
		for(i=0; i<length; i++)
		{
			if(tInv[i].iSize == j)
			{
				//ADB this is a mem leak!!!
				//int *filler = new int;
				//iOrder.push_back(*filler);
				iOrder[count] = i;
				count++;
			}
		}
	}

	// Last, go through the temp data and put items into appropriate pockets
	// Start by putting items into specific pockets
	for(i=0; i<count; i++)
	{
		iSlot = SpecificFreePocket(pProfile, tInv[iOrder[i]].inv, tInv[iOrder[i]].iNumber, tInv[iOrder[i]].iClass);
		if(iSlot != -1)
		{
			MakeProfileInvItemThisSlot(pProfile, iSlot, tInv[iOrder[i]].inv, tInv[iOrder[i]].iStatus, tInv[iOrder[i]].iNumber);
			iOrder[i]=-1;
		}
	}
	// Next, put anything that isn't an attachment into a pocket
	for(i=0; i<count; i++)
	{
		if(iOrder[i]!=-1)
		{
			// skip if this item is an attachment
			if(Item[tInv[iOrder[i]].inv].attachment)
				continue;
			iSet = FALSE;
			number = tInv[iOrder[i]].iNumber;
			while(number > 0)
			{
				iSlot = FirstFreeBigEnoughPocket (pProfile, &tInv[iOrder[i]]);
				if(iSlot != -1)
				{
					MakeProfileInvItemThisSlot(pProfile, iSlot, tInv[iOrder[i]].inv, tInv[iOrder[i]].iStatus, tInv[iOrder[i]].iNumber);
					iSet = TRUE;
					number -= tInv[iOrder[i]].iNumber;
					tInv[iOrder[i]].iNumber = number;
				}
				else if(tInv[iOrder[i]].iNumber>1){
					tInv[iOrder[i]].iNumber --;
				}
				else {
					iSet = FALSE;
					tInv[iOrder[i]].iNumber = number;
					number = 0;
				}
			}
			if(iSet)
				iOrder[i]=-1;
		}
	}
	// finish by putting anything that's left into any pocket, including inactive pockets
	for(i=0; i<count; i++)
	{
		if(iOrder[i]!=-1)
		{
			iSet = FALSE;
			number = tInv[iOrder[i]].iNumber;
			tInv[iOrder[i]].iNumber = 1;
			for(int j=0; j<number; j++)
			{
				iSlot = AnyFreeBigEnoughPocket (pProfile, &tInv[iOrder[i]]);
				if(iSlot != -1)
				{
					MakeProfileInvItemThisSlot( pProfile, iSlot, tInv[iOrder[i]].inv, tInv[iOrder[i]].iStatus, pProfile->bInvNumber[iSlot] + 1 );
					iSet = TRUE;
				}
			}
			if(iSet)
				iOrder[i] = -1;
		}
	}
}

INT32 GetEquippedGearCost( MERCPROFILESTRUCT *pProfile )
{
	INT32 cost = 0;

	for ( int i = INV_START_POS; i<NUM_INV_SLOTS; ++i )
	{
		if ( pProfile->inv[i] != NOTHING )
		{
			cost += pProfile->bInvNumber[i] * Item[pProfile->inv[i]].usPrice;
		}
	}

	return cost;
}

void GiveItemsToPC( UINT8 ubProfileId )
{
	MERCPROFILESTRUCT *pProfile;

	// gives starting items to merc
	// NOTE: Any guns should probably be from those available in regular gun set

	pProfile = &(gMercProfiles[ubProfileId]);

	// Flugente: if necessary, give us the gear we selected
	if ( IsIMPGearUsed() )
	{
		GiveIMPSelectedGear( pProfile );
	}
	else
	{
		// STANDARD EQUIPMENT
		// SANDRO - obsolete code deleted

		GiveIMPItems(pProfile, 100, IMP_DEFAULT);
		GiveIMPRandomItems(pProfile, IMP_RANDOMDEFAULT);
		// silversurfer: added sidearm selection
		GiveIMPRandomItems(pProfile, IMP_SIDEARM);

		GiveIMPItems (pProfile,pProfile->bWisdom,IMP_WISDOM);
		GiveIMPItems (pProfile,pProfile->bMarksmanship,IMP_MARKSMANSHIP);
		GiveIMPItems (pProfile,pProfile->bMedical,IMP_MEDICAL);
		GiveIMPItems (pProfile,pProfile->bMechanical,IMP_MECHANICAL);
		GiveIMPItems (pProfile,pProfile->bExplosive,IMP_EXPLOSIVE);
		GiveIMPItems (pProfile,pProfile->bAgility,IMP_AGILITY);
		GiveIMPItems (pProfile,pProfile->bDexterity,IMP_DEXTERITY);
		GiveIMPItems (pProfile,pProfile->bStrength,IMP_STRENGTH);
		GiveIMPItems (pProfile,pProfile->bLifeMax,IMP_HEALTH);
		GiveIMPItems (pProfile,pProfile->bLeadership,IMP_LEADERSHIP);

		// check for special skills
		/////////////////////////////////////////////////////////////////////
		// Check for new traits - SANDRO 
		// DBrot: experts get other stuff
		if ( gGameOptions.fNewTraitSystem )
		{
			// MAJOR TRAITS
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, AUTO_WEAPONS_NT))
			{	
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, AUTO_WEAPONS_NT))
				{
 					GiveIMPRandomItems(pProfile,IMP_AUTO_WEAPONS_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_AUTO_WEAPONS);
				}
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, HEAVY_WEAPONS_NT ))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, HEAVY_WEAPONS_NT))
				{
 					GiveIMPRandomItems(pProfile,IMP_HEAVY_WEAPONS_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_HEAVY_WEAPONS);
				}
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, SNIPER_NT))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, SNIPER_NT))
				{
 					GiveIMPRandomItems(pProfile,IMP_SNIPER_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_SNIPER);
				}
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, RANGER_NT))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, RANGER_NT))
				{
 					GiveIMPRandomItems(pProfile,IMP_RANGER_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_RANGER);
				}
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, GUNSLINGER_NT))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, GUNSLINGER_NT))
				{
 					GiveIMPRandomItems(pProfile,IMP_GUNSLINGER_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_GUNSLINGER);
				}		
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, MARTIAL_ARTS_NT))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, MARTIAL_ARTS_NT))
				{
 					GiveIMPRandomItems(pProfile,IMP_MARTIAL_ARTS_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_MARTIAL_ARTS);
				}
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, SQUADLEADER_NT))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, SQUADLEADER_NT))
				{
 					GiveIMPRandomItems(pProfile,IMP_SQUADLEADER_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_SQUADLEADER);
				}
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, TECHNICIAN_NT) && ( iMechanical ) )
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, TECHNICIAN_NT))
				{
 					GiveIMPRandomItems(pProfile,IMP_TECHNICIAN_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_TECHNICIAN);
				}
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, DOCTOR_NT ))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, DOCTOR_NT))
				{
 					GiveIMPRandomItems(pProfile,IMP_DOCTOR_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_DOCTOR);
				}
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, COVERT_NT))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, COVERT_NT))
				{
 					GiveIMPRandomItems(pProfile,IMP_COVERT_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_COVERT);
				}
			}
			// MINOR TRAITS
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, AMBIDEXTROUS_NT))
			{
				GiveIMPRandomItems(pProfile,IMP_AMBIDEXTROUS);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, MELEE_NT))
			{
				GiveIMPRandomItems(pProfile,IMP_MELEE);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, THROWING_NT))
			{
				GiveIMPRandomItems(pProfile,IMP_THROWING);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, NIGHT_OPS_NT))
			{
				GiveIMPRandomItems(pProfile,IMP_NIGHT_OPS);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, STEALTHY_NT))
			{
				GiveIMPRandomItems(pProfile,IMP_STEALTHY);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, ATHLETICS_NT))
			{
				GiveIMPRandomItems(pProfile,IMP_ATHLETICS);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, BODYBUILDING_NT))
			{
				GiveIMPRandomItems(pProfile,IMP_BODYBUILDING);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, DEMOLITIONS_NT))
			{
				GiveIMPRandomItems(pProfile,IMP_DEMOLITIONS);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, TEACHING_NT))
			{
				GiveIMPRandomItems(pProfile,IMP_TEACHING);
			}
			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);
			}
			if ( PROFILE_HAS_SKILL_TRAIT( ubProfileId, SURVIVAL_NT ) )
			{
				GiveIMPRandomItems( pProfile, IMP_SURVIVAL );
			}
		}
		else
		{
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, LOCKPICKING_OT) && ( iMechanical ) )
			{
				//MakeProfileInvItemAnySlot(pProfile, LOCKSMITHKIT, 100, 1);
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, LOCKPICKING_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_LOCKPICKING_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_LOCKPICKING);
				}
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, ELECTRONICS_OT) && ( iMechanical ) )
			{
				//MakeProfileInvItemAnySlot(pProfile, METALDETECTOR, 100, 1);
				GiveIMPRandomItems(pProfile,IMP_ELECTRONICS);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, CAMOUFLAGED_OT)) // TODO: Madd - other camouflage types, once we figure out a way to enable more traits
			{
				//MakeProfileInvItemAnySlot(pProfile, CAMOUFLAGEKIT, 100, 1);
				GiveIMPRandomItems(pProfile,IMP_CAMOUFLAGED);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, AMBIDEXT_OT))
			{
				//MakeProfileInvItemAnySlot(pProfile, M950, 100, 1);
				GiveIMPRandomItems(pProfile,IMP_AMBIDEXTROUS);
			}
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, NIGHTOPS_OT))
			{
	//			MakeProfileInvItemAnySlot(pProfile, SILENCER, 100, 2);
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, NIGHTOPS_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_NIGHT_OPS_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_NIGHT_OPS);
				}
			}
		
			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, HANDTOHAND_OT))
			{
				//MakeProfileInvItemAnySlot(pProfile, BRASS_KNUCKLES, 100, 1);
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, HANDTOHAND_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_MARTIAL_ARTS_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_MARTIAL_ARTS);
				}
			}

			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, THROWING_OT))
			{
	//			MakeProfileInvItemAnySlot(pProfile, THROWING_KNIFE, 100, 1);
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, THROWING_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_THROWING_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_THROWING);
				}
			}

			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, STEALTHY_OT))
			{
	//			MakeProfileInvItemAnySlot(pProfile, SILENCER, 100, 1);
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, STEALTHY_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_STEALTHY_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_STEALTHY);
				}
			}

			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, KNIFING_OT))
			{
	//			MakeProfileInvItemAnySlot(pProfile, COMBAT_KNIFE, 100, 1);
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, KNIFING_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_MELEE_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_MELEE);
				}
			}

			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, MARTIALARTS_OT))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, MARTIALARTS_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_MARTIAL_ARTS_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_MARTIAL_ARTS);
				}
			}

			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, PROF_SNIPER_OT))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, PROF_SNIPER_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_SNIPER_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_SNIPER);
				}
			}

			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, TEACHING_OT))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, TEACHING_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_TEACHING_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_TEACHING);
				}
			}

			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, AUTO_WEAPS_OT))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, AUTO_WEAPS_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_AUTO_WEAPONS_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_AUTO_WEAPONS);
				}
			}

			if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, HEAVY_WEAPS_OT ))
			{
				if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, HEAVY_WEAPS_OT))
				{
 					GiveIMPRandomItems(pProfile,IMP_HEAVY_WEAPONS_EXP);
				}
				else
				{
					GiveIMPRandomItems(pProfile, IMP_HEAVY_WEAPONS);
				}
			}
		}
		/////////////////////////////////////////////////////////////////////
	}

	// CHRISL: Now that all items have been issued, distribute them into appropriate pockets, starting with the largest items
	DistributeInitialGear(pProfile);
}


void MakeProfileInvItemAnySlot(MERCPROFILESTRUCT *pProfile, UINT16 usItem, UINT8 ubStatus, UINT8 ubHowMany)
{
	INT32 iSlot = -1;

	if((UsingNewInventorySystem() == false))
		iSlot = FirstFreeBigEnoughPocket(pProfile, usItem, ubHowMany);
	else
	{
		// CHRISL: Alter the placement of initial equipment to come last.  At this stage, just add items, one pocket at a time
		for(int i=INV_START_POS; i<NUM_INV_SLOTS; i++)
		{
			if(pProfile->inv[i] == NOTHING)
			{
				iSlot = i;
				break;
			}
		}
	}

	if (iSlot == -1)
	{
		// no room, item not received
		return;
	}

	// put the item into that slot
	MakeProfileInvItemThisSlot(pProfile, iSlot, usItem, ubStatus, ubHowMany);
}

// CHRISL: New function to move initial gear into LBE pockets when LBE items are given during creation
void RedistributeStartingItems(MERCPROFILESTRUCT *pProfile, UINT16 usItem, UINT8 sPocket)
{
	UINT16	lbeIndex, iSize;
	UINT8	lbeClass;
	UINT16	inv[NUM_INV_SLOTS], istatus[NUM_INV_SLOTS], inumber[NUM_INV_SLOTS];

	lbeIndex = Item[usItem].ubClassIndex;
	lbeClass = LoadBearingEquipment[lbeIndex].lbeClass;

	// Move non-worn items into temporary storage
	for(int i=INV_START_POS; i<NUM_INV_SLOTS; i++)
	{
		if(i>=BODYPOSFINAL)
		{
			inv[i] = pProfile->inv[i];
			istatus[i] = pProfile->bInvStatus[i];
			inumber[i] = pProfile->bInvNumber[i];
			pProfile->inv[i] = 0;
			pProfile->bInvStatus[i] = 0;
			pProfile->bInvNumber[i] = 0;
		}
		else
		{
			switch (i)
			{
				case HANDPOS:
				case SECONDHANDPOS:
					inv[i] = pProfile->inv[i];
					istatus[i] = pProfile->bInvStatus[i];
					inumber[i] = pProfile->bInvNumber[i];
					pProfile->inv[i] = 0;
					pProfile->bInvStatus[i] = 0;
					pProfile->bInvNumber[i] = 0;
					break;
				default:
					inv[i] = 0;
					istatus[i] = 0;
					inumber[i] = 0;
					break;
			}
		}
	}

	// Redistribute stored items with the assumption of the new LBE item
	for(int i=INV_START_POS; i<NUM_INV_SLOTS; i++)
	{
		if(inv[i] != NONE)
		{
			iSize = Item[inv[i]].ItemSize;
			for(int j=INV_START_POS; j<NUM_INV_SLOTS; j++)
			{
				if(icLBE[j] == sPocket && pProfile->inv[j] == NONE && LBEPocketType[LoadBearingEquipment[lbeIndex].lbePocketIndex[icPocket[j]]].ItemCapacityPerSize[iSize] != NONE)
				{
					pProfile->inv[j] = inv[i];
					pProfile->bInvStatus[j] = istatus[i];
					pProfile->bInvNumber[j] = inumber[i];
					inv[i] = istatus[i] = inumber[i] = 0;
					break;
				}
			}
			pProfile->inv[i] = inv[i];
			pProfile->bInvStatus[i] = istatus[i];
			pProfile->bInvNumber[i] = inumber[i];
			inv[i] = istatus[i] = inumber[i] = 0;
		}
	}
}

// CHRISL: New function to work with LBE pockets
INT32 SpecificFreePocket(MERCPROFILESTRUCT *pProfile, UINT16 usItem, UINT8 ubHowMany, UINT32 usClass)
{
	UINT8	lbePocket;

	if (ubHowMany == 1)
	{
		switch (usClass)
		{
			case IC_LBEGEAR:
				if(pProfile->inv[VESTPOCKPOS]==NONE && LoadBearingEquipment[Item[usItem].ubClassIndex].lbeClass==VEST_PACK)
					return VESTPOCKPOS;
				if(pProfile->inv[LTHIGHPOCKPOS]==NONE && LoadBearingEquipment[Item[usItem].ubClassIndex].lbeClass==THIGH_PACK)
					return LTHIGHPOCKPOS;
				if(pProfile->inv[RTHIGHPOCKPOS]==NONE && LoadBearingEquipment[Item[usItem].ubClassIndex].lbeClass==THIGH_PACK)
					return RTHIGHPOCKPOS;
				if(LoadBearingEquipment[Item[usItem].ubClassIndex].lbeClass==COMBAT_PACK)
				{
					if(pProfile->inv[CPACKPOCKPOS]==NONE)
					{
						if(LoadBearingEquipment[Item[usItem].ubClassIndex].lbeCombo!=0)
						{
							//DBrot: changed to bitwise comparison
							if((pProfile->inv[BPACKPOCKPOS]!=NONE && (LoadBearingEquipment[Item[pProfile->inv[BPACKPOCKPOS]].ubClassIndex].lbeCombo & LoadBearingEquipment[Item[usItem].ubClassIndex].lbeCombo)) || pProfile->inv[BPACKPOCKPOS]==NONE)
								return CPACKPOCKPOS;
						}
						else if(pProfile->inv[BPACKPOCKPOS]==NONE)
							return CPACKPOCKPOS;
					}
				}
				if(LoadBearingEquipment[Item[usItem].ubClassIndex].lbeClass==BACKPACK)
				{
					if(pProfile->inv[BPACKPOCKPOS]==NONE)
					{
						if(LoadBearingEquipment[Item[usItem].ubClassIndex].lbeCombo!=0)
						{
							//DBrot: changed to bitwise comparison
							if((pProfile->inv[CPACKPOCKPOS]!=NONE && (LoadBearingEquipment[Item[pProfile->inv[CPACKPOCKPOS]].ubClassIndex].lbeCombo & LoadBearingEquipment[Item[usItem].ubClassIndex].lbeCombo)) || pProfile->inv[CPACKPOCKPOS]==NONE)
								return BPACKPOCKPOS;
						}
						else if(pProfile->inv[CPACKPOCKPOS]==NONE)
							return BPACKPOCKPOS;
					}
				}
				break;
			case IC_ARMOUR:
				if ( pProfile->inv[HELMETPOS] == NONE && Armour[Item[usItem].ubClassIndex].ubArmourClass == ARMOURCLASS_HELMET )
					return HELMETPOS;
				if ( pProfile->inv[VESTPOS] == NONE && Armour[Item[usItem].ubClassIndex].ubArmourClass == ARMOURCLASS_VEST )
					return VESTPOS;
				if ( pProfile->inv[LEGPOS] == NONE && Armour[Item[usItem].ubClassIndex].ubArmourClass == ARMOURCLASS_LEGGINGS && !(Item[usItem].attachment))
					return LEGPOS;
				break;
			case IC_BLADE:
				if ( pProfile->inv[KNIFEPOCKPOS] == NONE)
					return KNIFEPOCKPOS;
				break;
			/* CHRISL: This won't work without hard coding pocket definitions since there is no way to
			guarantee that the pocket definitions won't change. */
//			case IC_BOMB:
//				for(int i=BIGPOCKSTART; i<NUM_INV_SLOTS; i++)
//				{
//					if(LoadBearingEquipment[Item[pProfile->inv[icLBE[i]]].ubClassIndex].lbePocketIndex[icPocket[i]]==7)	// TNT Pocket
//						if(pProfile->inv[i] == NONE)
//							return i;
//				}
//				break;
//			case IC_GRENADE:
//				for(int i=BIGPOCKSTART; i<NUM_INV_SLOTS; i++)
//				{
//					if(pProfile->inv[i]==NONE && Item[usItem].ItemSize==16 && LoadBearingEquipment[Item[pProfile->inv[icLBE[i]]].ubClassIndex].lbePocketIndex[icPocket[i]]==12)	// Rifle Grenade
//						return i;
//					else if(pProfile->inv[i]==NONE && LoadBearingEquipment[Item[pProfile->inv[icLBE[i]]].ubClassIndex].lbePocketIndex[icPocket[i]]==13)	// Grenade
//						return i;
//				}
//				break;
			case IC_GUN:
				if ( pProfile->inv[HANDPOS] == NONE )
					return HANDPOS;
				if ( pProfile->inv[SECONDHANDPOS] == NONE && !(Item[pProfile->inv[HANDPOS]].twohanded))
					return SECONDHANDPOS;
				if((UsingNewInventorySystem() == true))
					if ( pProfile->inv[GUNSLINGPOCKPOS] == NONE && pProfile->inv[BPACKPOCKPOS] == NONE && LBEPocketType[1].ItemCapacityPerSize[Item[usItem].ItemSize]!=0)
						return GUNSLINGPOCKPOS;
				for(int i=BIGPOCKSTART; i<NUM_INV_SLOTS; i++)
				{
					lbePocket = LoadBearingEquipment[Item[pProfile->inv[icLBE[i]]].ubClassIndex].lbePocketIndex[icPocket[i]];
					if(pProfile->inv[i]==NONE && (lbePocket==6 || lbePocket==10) && LBEPocketType[lbePocket].ItemCapacityPerSize[Item[usItem].ItemSize]!=0)
						return i;
				}
				break;
			case IC_FACE:
				if ( pProfile->inv[HEAD1POS] == NONE && CompatibleFaceItem(usItem,pProfile->inv[HEAD2POS]) )
					return HEAD1POS;
				if ( pProfile->inv[HEAD2POS] == NONE && CompatibleFaceItem(usItem,pProfile->inv[HEAD1POS]) )
					return HEAD2POS;
				break;
			default:
				break;
		}
	}
	return(-1);
}


void MakeProfileInvItemThisSlot(MERCPROFILESTRUCT *pProfile, UINT32 uiPos, UINT16 usItem, UINT8 ubStatus, UINT8 ubHowMany)
{
	pProfile->inv[uiPos]				= usItem;
	pProfile->bInvStatus[uiPos] = ubStatus;
	pProfile->bInvNumber[uiPos] = ubHowMany;
}

//INT32 FirstFreeBigEnoughPocket(MERCPROFILESTRUCT *pProfile, UINT16 usItem, UINT8 ubHowMany, UINT32 usClass)
INT32 FirstFreeBigEnoughPocket(MERCPROFILESTRUCT *pProfile, INVNODE *tInv)
{
	INT32	sPocket=-1, mPocket=-1, lPocket=-1;
	UINT8	sCapacity=0;
	UINT8	mCapacity=0;
	UINT8	lCapacity=0;
	UINT8	capacity=0;

	/*CHRISL: Make the assumption that by the time we get to this function, we've already activated
	all the pockets we're going to activate.  LBE Items were all placed in SpecificFreePocket function
	which should activate everything. */
	//Start with active big pockets
	sPocket=PickPocket(pProfile, SMALLPOCKSTART, SMALLPOCKFINAL, tInv->inv, tInv->iNumber, &sCapacity);
	//Next search active medium pockets
	mPocket=PickPocket(pProfile, MEDPOCKSTART, MEDPOCKFINAL, tInv->inv, tInv->iNumber, &mCapacity);
	//Lastly search active small pockets
	lPocket=PickPocket(pProfile, BIGPOCKSTART, BIGPOCKFINAL, tInv->inv, tInv->iNumber, &lCapacity);
	//Finally, compare the three pockets we've found and return the pocket that is most logical to use
	capacity = min(sCapacity, mCapacity);
	capacity = min(lCapacity, capacity);
	if(capacity == 254) {	//no pocket found
		return -1;
	}
	else if(capacity == sCapacity) {
		return sPocket;
	}
	else if(capacity == mCapacity) {
		return mPocket;
	}
	else if(capacity == lCapacity) {
		return lPocket;
	}
	return(-1);
}

// CHRISL: Use to find best pocket to store item in.  Could probably be merged with FitsInSmallPocket
INT32 PickPocket(MERCPROFILESTRUCT *pProfile, UINT8 ppStart, UINT8 ppStop, UINT16 usItem, UINT8 iNumber, UINT8 * cap)
{
	UINT16	pIndex=0;
	INT32	pocket=0;
	UINT8	capacity=254;

	for(UINT32 uiPos=ppStart; uiPos<ppStop; uiPos++){
		if(pProfile->inv[icLBE[uiPos]]==0){
			pIndex=LoadBearingEquipment[Item[icDefault[uiPos]].ubClassIndex].lbePocketIndex[icPocket[uiPos]];
		}
		else {
			pIndex=LoadBearingEquipment[Item[pProfile->inv[icLBE[uiPos]]].ubClassIndex].lbePocketIndex[icPocket[uiPos]];
		}
		// Here's were we get complicated.  We should look for the smallest pocket all items can fit in
		if(LBEPocketType[pIndex].ItemCapacityPerSize[Item[usItem].ItemSize] >= iNumber &&
			LBEPocketType[pIndex].ItemCapacityPerSize[Item[usItem].ItemSize] < capacity &&
			pProfile->inv[uiPos] == 0) {
				if((LBEPocketType[pIndex].pRestriction != 0 && (LBEPocketType[pIndex].pRestriction & Item[usItem].usItemClass)) ||
					LBEPocketType[pIndex].pRestriction == 0) {
						capacity = LBEPocketType[pIndex].ItemCapacityPerSize[Item[usItem].ItemSize];
						pocket = uiPos;
				}
		}
	}
	if(pocket!=0){
		*cap=capacity;
		return pocket;
	}
	else{
		*cap=254;
		return -1;
	}
}

INT32 FirstFreeBigEnoughPocket(MERCPROFILESTRUCT *pProfile, UINT16 usItem, UINT8 ubHowMany)
{
	UINT32 uiPos;

	if (ubHowMany == 1)
	{
		// check body spots

		if ( pProfile->inv[HELMETPOS] == NONE && Item[usItem].usItemClass == IC_ARMOUR && Armour[Item[usItem].ubClassIndex].ubArmourClass == ARMOURCLASS_HELMET )
			return HELMETPOS;
		if ( pProfile->inv[VESTPOS] == NONE && Item[usItem].usItemClass == IC_ARMOUR && Armour[Item[usItem].ubClassIndex].ubArmourClass == ARMOURCLASS_VEST )
			return VESTPOS;
		if ( pProfile->inv[LEGPOS] == NONE && Item[usItem].usItemClass == IC_ARMOUR && Armour[Item[usItem].ubClassIndex].ubArmourClass == ARMOURCLASS_LEGGINGS )
			return LEGPOS;
		if ( pProfile->inv[HEAD1POS] == NONE && Item[usItem].usItemClass == IC_FACE && CompatibleFaceItem(usItem,pProfile->inv[HEAD2POS]) )
			return HEAD1POS;
		if ( pProfile->inv[HEAD2POS] == NONE && Item[usItem].usItemClass == IC_FACE && CompatibleFaceItem(usItem,pProfile->inv[HEAD1POS]) )
			return HEAD2POS;
		if ( pProfile->inv[HANDPOS] == NONE )
			return HANDPOS;
		if ( pProfile->inv[SECONDHANDPOS] == NONE )
			return SECONDHANDPOS;
	}
	// if it fits into a small pocket
	if (Item[usItem].ubPerPocket != 0)
	{
		// check small pockets first
		for (uiPos = SMALLPOCK1POS; uiPos <= SMALLPOCK8POS; uiPos++)
		{
			if (pProfile->inv[uiPos] == NONE)
			{
				return(uiPos);
			}
		}
	}

	// check large pockets
	for (uiPos = BIGPOCK1POS; uiPos <= BIGPOCK4POS; uiPos++)
	{
		if (pProfile->inv[uiPos] == NONE)
		{
			return(uiPos);
		}
	}

	return(-1);
}

// CHRISL: This function will place objects anywhere it can.  It tries to use active pockets but will use any pocket as a last resort
INT32 AnyFreeBigEnoughPocket(MERCPROFILESTRUCT *pProfile, INVNODE *tInv)
{
	INT32		iSlot;
	INT32		iPos;
	UINT16		iSize, lbeCap, usItem;

	iSlot = FirstFreeBigEnoughPocket (pProfile, tInv);
	if(iSlot != -1)
		return(iSlot);
	else
	{
		/* CHRISL: FAILSAFE: We can't find any active pockets to put this item. Rather then losing the item,
		put it in any pocket using old inventory method.  Player can then manually resort items later. */
		usItem = tInv->inv;
		iSize = Item[usItem].ubPerPocket;
		lbeCap = max(1, (iSize/2));
		for(iPos = BIGPOCKSTART; iPos < NUM_INV_SLOTS; iPos ++)
		{
			if(iPos >= MEDPOCKFINAL && iSize > 0)
				return(-1);
			else
			{
				if(pProfile->inv[iPos] == NONE)
					return(iPos);
				else if(pProfile->inv[iPos] == usItem)
				{
					if((iPos < BIGPOCKFINAL && iSize >= (tInv->iNumber+1)) || (iPos >= BIGPOCKFINAL && lbeCap >= (tInv->iNumber+1)))
					{
					tInv->iNumber++;
					return(iPos);
					}
				}
			}
		}
	}
	return(-1);
}

void WriteOutCurrentImpCharacter( INT32 iProfileId )
{
	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("WriteOutCurrentImpCharacter: IMP.dat"));
	char zImpFileName[13];
	strcpy(zImpFileName,IMP_MERC_FILENAME);
	// Changed by ADB, rev 1513, to resolve IMPs created prior to structural changes
	//strcat(zImpFileName,IMP_FILENAME_SUFFIX);
	strcat(zImpFileName,NEW_IMP_FILENAME_SUFFIX);
	WriteOutCurrentImpCharacter ( iProfileId, zImpFileName);


	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("WriteOutCurrentImpCharacter: Nickname.dat"));

#ifndef USE_VFS
	char zFileName[13];
	char temp;

	for(int i=0;i < 9;i++) // Madd: I couldn't get strcpy or anything to work here... weird... if s/o wants to fix it, go ahead
	{
		temp = (char) gMercProfiles[iProfileId].zNickname[i];
		zFileName[i] = temp;
	}
#else
	char zFileName[32];
	if(vfs::Settings::getUseUnicode())
	{
		strncpy(zFileName, vfs::String::as_utf8(gMercProfiles[iProfileId].zNickname,10).c_str(), 32);
	}
	else
	{
		vfs::String::narrow(gMercProfiles[iProfileId].zNickname, 10, zFileName, 32);
	}
#endif

	// Changed by ADB, rev 1513
	//strcat(zFileName,IMP_FILENAME_SUFFIX);
	strcat(zFileName,NEW_IMP_FILENAME_SUFFIX);

	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("WriteOutCurrentImpCharacter: %s", zFileName));
	WriteOutCurrentImpCharacter ( iProfileId, zFileName);
}

void WriteOutCurrentImpCharacter( INT32 iProfileId, STR fileName )
{
	// grab the profile number and write out what is contained there in 
	HWFILE hFile;
	UINT32 uiBytesWritten = 0;

	// open the file for writing
	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("WriteOutCurrentImpCharacter: %s", fileName));
	hFile = FileOpen(fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE);

	// ADB we need to indicate that we have saved under the new format
	int nine = 9999;
	if (!FileWrite(hFile, &nine, sizeof( INT32 ), &uiBytesWritten))
	{
		if (hFile)
			FileClose(hFile);
		return;
	}

	int version = SAVE_GAME_VERSION;
	if (!FileWrite(hFile, &version, sizeof( INT32 ), &uiBytesWritten))
	{
		if (hFile)
			FileClose(hFile);
		return;
	}

	// write out the profile id
	if (!FileWrite(hFile, &iProfileId, sizeof( INT32 ), &uiBytesWritten))
	{
		if (hFile)
			FileClose(hFile);
		return;
	}

	// write out the portrait id
	if (!FileWrite(hFile, &iPortraitNumber, sizeof( INT32 ), &uiBytesWritten))
	{
		if (hFile)
			FileClose(hFile);
		return;
	}

	// write out the profile itself
	if ( !gMercProfiles[ iProfileId ].Save(hFile) )
	{
		if (hFile)
			FileClose(hFile);
		return;
	}

	// close file
	if (hFile)
		FileClose(hFile);

	return;
}

BOOLEAN ImpExists ( STR nickName )
{
	// Changed by ADB, rev 1513, to resolve IMPs created prior to structural changes
	char zFileName[32];

	strcpy(zFileName,nickName);
	//strcat(zFileName,IMP_FILENAME_SUFFIX);
	strcat(zFileName,OLD_IMP_FILENAME_SUFFIX);

	//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("ImpExists: %s",	zFileName));
	//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("ImpExists: %d", FileExistsNoDB(zFileName) ));
	BOOLEAN oldExists = FileExistsNoDB(zFileName);
	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("OLD ImpExists: %s",	zFileName));
	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("OLD ImpExists: %d", oldExists ));

	//return FileExistsNoDB(zFileName);
	strcpy(zFileName,nickName);
	strcat(zFileName,NEW_IMP_FILENAME_SUFFIX);

	BOOLEAN newExists = FileExistsNoDB(zFileName);
	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("NEW ImpExists: %s",	zFileName));
	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("NEW ImpExists: %d", newExists ));

	return (oldExists || newExists);
}

BOOLEAN LoadImpCharacter( STR nickName )
{
	INT32 iProfileId = 0;
	HWFILE hFile;
	UINT32 uiBytesRead = 0;

	char zFileName[32];

	//ADB first try to load the new kind
	strcpy(zFileName,nickName);
	//strcat(zFileName,IMP_FILENAME_SUFFIX);
	strcat(zFileName,NEW_IMP_FILENAME_SUFFIX);

	// open the file for reading
	hFile = FileOpen(zFileName, FILE_ACCESS_READ, FALSE);

	// valid file?
	if( !hFile )
	{
		//DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 7 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
		//return FALSE;
		//if the new kind doesn't exist, load the old kind
		strcpy(zFileName,nickName);
		strcat(zFileName,OLD_IMP_FILENAME_SUFFIX);

		// open the file for reading
		hFile = FileOpen(zFileName, FILE_ACCESS_READ, FALSE);

		// valid file?
		if( !hFile )
		{
			DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 7 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
			return FALSE;
		}
	}

	// read in the profile
	if (!FileRead(hFile, &iProfileId, sizeof( INT32 ), &uiBytesRead))
	{
		DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 7 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
		return FALSE;
	}

	int version = SAVE_GAME_VERSION;
	bool isOldVersion = true;
	if (iProfileId == 9999) {
		//ADB if we saved under the original version, then iProfileId is some low number
		//if we saved under the new version, then it's 9999, and we need to know what version it was saved under
		isOldVersion = false;

		//load the version, atm not used
		if (!FileRead(hFile, &version, sizeof( INT32 ), &uiBytesRead))
		{
			DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 7 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
			return FALSE;
		}

		//load the REAL iProfileId
		if (!FileRead(hFile, &iProfileId, sizeof( INT32 ), &uiBytesRead))
		{
			DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 7 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
			return FALSE;
		}
	}

	// read in the portrait
	if (!FileRead(hFile, &iPortraitNumber ,sizeof( INT32 ), &uiBytesRead))
	{
		DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 7 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
		return FALSE;
	}

	// Set the ID of the new IMP
	iProfileId = GetFreeIMPSlot(iProfileId);

	// We can create the new imp, beacuse we found an empty slot
	if (iProfileId != -1)
	{
		LaptopSaveInfo.iIMPIndex = iProfileId;
		
		// anv: before loading profile we need to set guiCurrentSaveGameVersion to profile's version
		// and set it back to SAVE_GAME_VERSION right after or else new saves will be broken!
		guiCurrentSaveGameVersion = version;

		if ( !gMercProfiles[ iProfileId ].Load(hFile, isOldVersion, false, false) )
		{
			guiCurrentSaveGameVersion = SAVE_GAME_VERSION;
			DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 7 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
			return FALSE;
		}

		/// Flugente: until the introduction of a separate variable for the voiceset, the voice was identical with the slot
		if ( guiCurrentSaveGameVersion < SEPARATE_VOICESETS )
		{
			gMercProfiles[iProfileId].usVoiceIndex = iProfileId;
		}

		// Flugente: if this is an older savefile, load from separate structure
		if ( guiCurrentSaveGameVersion < PROFILETYPE_STORED )
		{
			gMercProfiles[iProfileId].Type = gProfileType[iProfileId];
		}

		guiCurrentSaveGameVersion = SAVE_GAME_VERSION;

		// close file
		FileClose(hFile);
		//CHRISL: At this point, we need to resort profile inventory so that NewInv items don't accidentally appear in OldInv
		DistributeInitialGear(&gMercProfiles[iProfileId]);

		// silversurfer: Store current IMP cost. Function iGetProfileCost() already takes the new slot into account.
		// If we create the IMP first we would charge too much.
		INT32 iIMPCost = GetProfileCost(FALSE, TRUE);

		// Flugente: as we do not store the cost of the gear in the IMP file, we have to determine the cost here
		iIMPCost += max(0, GetEquippedGearCost( &gMercProfiles[iProfileId] ) - gGameExternalOptions.iIMPProfileCost );

		// Changed to find actual IMP cost - SANDRO
		if( LaptopSaveInfo.iCurrentBalance < iIMPCost )
		{
			DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 3 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);

			// not enough
			return FALSE;
		}
		
		/*
			//new camo face
			if ( gGameExternalOptions.fShowCamouflageFaces == TRUE )
				{
					gCamoFace[iProfileId].gCamoface = TRUE;
					gCamoFace[iProfileId].gUrbanCamoface = FALSE;
					gCamoFace[iProfileId].gDesertCamoface = FALSE;
					gCamoFace[iProfileId].gSnowCamoface = FALSE;
				}
		*/

		// charge the player
		// is the character male?
		fCharacterIsMale = ( gMercProfiles[ iProfileId ].bSex == MALE );
		fLoadingCharacterForPreviousImpProfile = TRUE;
		// Changed to find actual IMP cost - SANDRO
		AddTransactionToPlayersBook(IMP_PROFILE,0, GetWorldTotalMin( ), - ( iIMPCost ) );
		AddHistoryToPlayersLog( HISTORY_CHARACTER_GENERATED, 0,GetWorldTotalMin( ), -1, -1 );
		LaptopSaveInfo.iIMPIndex = iProfileId;
		AddCharacterToPlayersTeam( );
		// WANNE: Email is sent immediatly after the imp was created. So no need to send it later again
		//AddFutureDayStrategicEvent( EVENT_DAY2_ADD_EMAIL_FROM_IMP, 60 * 7, 0, 2 );
		LaptopSaveInfo.fIMPCompletedFlag = TRUE;
		fPausedReDrawScreenFlag = TRUE;
		fLoadingCharacterForPreviousImpProfile = FALSE;

		return TRUE;
	}
	else
	{
		// close file
		FileClose(hFile);

		// WDS: Allow flexible numbers of IMPs of each sex
		//	note: check this

		// You cannot have more than 3 I.M.P characters with the same gender on your team.
		DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 9 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
		return FALSE;
	}
}



void ResetIMPCharactersEyesAndMouthOffsets( UINT8 ubMercProfileID )
{
	// ATE: Check boundary conditions!
/*	
    if( ( ( gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ) > MAX_NEW_IMP_PORTRAITS ) || ( ubMercProfileID >= PROF_HUMMER ) )  // 16
	{
	return;
	}
*/
	
	gMercProfiles[ubMercProfileID].usEyesX = gIMPValues[gMercProfiles[ubMercProfileID].ubFaceIndex].uiEyeXPositions;
	gMercProfiles[ubMercProfileID].usEyesY = gIMPValues[gMercProfiles[ubMercProfileID].ubFaceIndex].uiEyeYPositions;

	gMercProfiles[ubMercProfileID].usMouthX = gIMPValues[gMercProfiles[ubMercProfileID].ubFaceIndex].uiMouthXPositions;
	gMercProfiles[ubMercProfileID].usMouthY = gIMPValues[gMercProfiles[ubMercProfileID].ubFaceIndex].uiMouthYPositions;
}


void GiveIMPRandomItems( MERCPROFILESTRUCT *pProfile, UINT8 typeIndex )
{
	/////////////////////////////////////////////////////////////////////
	// SANDRO - I've changed this formula a bit, <- me too - silversurfer
	// now it should not take the same choice twice
	/////////////////////////////////////////////////////////////////////
	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPRandomItems: typeIndex = %d",typeIndex ));

	UINT16 usItem = 0;
	INT32 iChoice;
	UINT8 ubValidChoices = 0;
	UINT8 ubNumChoices = gIMPItemChoices[ typeIndex ].ubChoices;
	UINT8 ubNumItemsToGive = 0;
	BOOLEAN ubItemsGiven[ 50 ]={FALSE};

	// check how many legal items are in the choices list, this is to prevent infinite loop
	for ( UINT8 cnt=0; cnt < ubNumChoices; ++cnt )
	{
		usItem = gIMPItemChoices[ typeIndex ].bItemNo[ cnt ];
		// allow guns no matter if Tons of Guns was selected so the merc doesn't have to start without a weapon
		if ( ItemIsLegal(usItem) || Item[usItem].usItemClass == IC_GUN )
			++ubValidChoices;
	}

	// if no valid items found, bail out
	if ( ubValidChoices <= 0 )
		return;
	
	// define how many items we get
	if ( ubValidChoices < gIMPItemChoices[typeIndex].ubNumItems )
		// if there are less legal items than the number we should get, we only get the number of legal items
		ubNumItemsToGive = ubValidChoices;
	else
		// give us the maximum possible
		ubNumItemsToGive = gIMPItemChoices[typeIndex].ubNumItems;

	for ( int i=0; i < ubNumItemsToGive; ++i )
	{
		usItem = 0;
		while (usItem == 0 )
		{
				iChoice = Random( ubNumChoices );
				usItem = gIMPItemChoices[ typeIndex ].bItemNo[ iChoice ];
				// is this legal and we don't have it already?
				if ( (ItemIsLegal(usItem) || Item[usItem].usItemClass == IC_GUN) && !ubItemsGiven[iChoice] )
					ubItemsGiven[iChoice] = TRUE;
				else
					usItem=0;
		}
		DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPRandomItems: typeIndex = %d, usItem = %d ",typeIndex, usItem ));
		if ( usItem > 0 )
			MakeProfileInvItemAnySlot(pProfile,usItem,100,1);

		// give ammo for guns
		Assert( usItem < gMAXITEMS_READ );
		if ( Item[usItem].usItemClass == IC_GUN && !Item[usItem].rocketlauncher )
		{
			usItem = DefaultMagazine(usItem);
			DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPRandomItems: give ammo typeIndex = %d, usItem = %d ",typeIndex, usItem ));
			MakeProfileInvItemAnySlot(pProfile,usItem,100,(1+Random(1)));
		}

		// give launchables for launchers
		if ( Item[usItem].usItemClass == IC_LAUNCHER )
		{
			usItem = PickARandomLaunchable(usItem);
			DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPRandomItems: give launchable typeIndex = %d, usItem = %d",typeIndex, usItem ));
			MakeProfileInvItemAnySlot(pProfile,usItem,100,(2+Random(2)));
		}
	}
}

void GiveIMPItems( MERCPROFILESTRUCT *pProfile, INT8 abilityValue, UINT8 typeIndex )
{
	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPItems: typeIndex = %d, abilityValue = %d",typeIndex,abilityValue ));

	UINT16 usItem = 0;
	INT32 iChoice;

	if ( gIMPItemChoices[ typeIndex ].ubChoices <= 0 )
		return;

	iChoice = (UINT32) (abilityValue / (100 / gIMPItemChoices[ typeIndex ].ubChoices)) ;

	if ( iChoice >= gIMPItemChoices[ typeIndex ].ubChoices )
		iChoice = gIMPItemChoices[ typeIndex ].ubChoices - 1;

	DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPItems: 1 iChoice = %d",iChoice));
	for ( int i=0; i < gIMPItemChoices[typeIndex].ubNumItems ;i++ )
	{
		DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPItems: 2 iChoice = %d",iChoice));
		usItem = gIMPItemChoices[ typeIndex ].bItemNo[ iChoice ];
		DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPItems: typeIndex = %d, usItem = %d, iChoice = %d, abilityValue = %d",typeIndex, usItem,iChoice, abilityValue ));
		//CHRISL: Let "illegal" guns be allowed so we don't have to worry about an IMP failing to start with a weapon simply
		//	because Tons of Guns was not selected.
		if ( usItem > 0 && (ItemIsLegal(usItem) || Item[usItem].usItemClass == IC_GUN))
		{
			MakeProfileInvItemAnySlot(pProfile,usItem,100,1);
			
			// give ammo for guns
			if ( Item[usItem].usItemClass == IC_GUN && !Item[usItem].rocketlauncher )
			{
				usItem = DefaultMagazine(usItem);
				DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPItems: give ammo typeIndex = %d, usItem = %d",typeIndex, usItem ));
				MakeProfileInvItemAnySlot(pProfile,usItem,100,(2+Random(2)));
			}

			// give launchables for launchers
			if ( Item[usItem].usItemClass == IC_LAUNCHER )
			{
				usItem = PickARandomLaunchable(usItem);
				DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPItems: give launchable typeIndex = %d, usItem = %d",typeIndex, usItem ));
				MakeProfileInvItemAnySlot(pProfile,usItem,100,(2+Random(2)));
			}
		}
		iChoice--;
		if (iChoice < 0)
			iChoice = 0;
	}
}

// SANDRO - Function to determine actual cost of profile
INT32 GetProfileCost( BOOLEAN aWithGearCost, BOOLEAN profileSlotAllocated )
{
	// Flugente: aditional imp gear cost
	INT32 impgearcost = aWithGearCost ? GetIMPGearCost() : 0;
	INT32 impProfileCost = gGameExternalOptions.iIMPProfileCost;

	if (gGameExternalOptions.fDynamicIMPProfileCost)
	{
		// sun_alf: if the IMP profile already occupies a slot, CountFilledIMPSlots() return the number we want to multiply on,
		// but if a slot is not allocated still, we need to add 1 to get the correct price in advance.
		impProfileCost *= profileSlotAllocated ? CountFilledIMPSlots() : CountFilledIMPSlots() + 1;
	}

	return impProfileCost + impgearcost;
}
