#include "rumour_data.c"

#define Few_Quest_Sum		400
#define Some_Quest_Sum		2000
#define Medium_Quest_Sum	4000
#define Large_Quest_Sum		6000
#define Huge_Quest_Sum		10000
#define QUEST_COUNTER 		3

#define FRA_COLONY 		 		"Falaise De Fleur"
#define SPA_COLONY 		 		"Isla Muelle"
#define POR_COLONY 		 		"Conceicao"	
#define HOL_COLONY 		 		"Douwesen"
#define RED_COLONY 		 		"Redmond"
#define OX_COLONY 		 		"Oxbay"
#define GREEN_COLONY 		 	"Greenford"
#define QC_COLONY 		 		"Quebradas Costillas"
#define CAY_COLONY 		 		"Grand Cayman"
#define SANTO_DOMINGO_COLONY	"Santo Domingo"
#define PORT_AU_PRINCE_COLONY	"Port au Prince"
#define POINTE_A_PITRE_COLONY	"Pointe a Pitre"
#define HAVANA_COLONY 		 	"Havana"
#define MARIGOT_COLONY 		 	"Marigot"
#define PHILIPSBURG_COLONY 		"Philipsburg"
#define SANTIAGO_COLONY 		"Santiago"
#define CHARLESTOWN_COLONY 		"Charlestown"
#define ST_JOHNS_COLONY 		"St John's"
#define TURK_COLONY 		 	"Grand Turk"
#define TORTUGA_COLONY 		 	"Tortuga"
#define SMUGGLERS_COLONY 		"Smugglers Lair"
#define PIRATES_COLONY 		 	"Pirate Fort"
*/
//=======================| OFFICERS |=======================//
#define OFFIC_TYPE_REGCAP 		"captain"// NK -->
#define OFFIC_TYPE_CAPMERCHANT	"merchant captain"
#define OFFIC_TYPE_CAPNAVY 		"navy captain"
#define OFFIC_TYPE_CAPPIRATE	"pirate captain"
#define OFFIC_TYPE_RANDCHAR 	"fighter"
#define OFFIC_TYPE_CIVILIAN 	"civilian"// NK <--
#define OFFIC_TYPE_BOATSWAIN 	"boatswain"
#define OFFIC_TYPE_CANNONEER 	"cannoneer"
#define OFFIC_TYPE_QMASTER 		"quartermaster"
#define OFFIC_TYPE_NAVIGATOR 	"navigator"
#define OFFIC_TYPE_FIRSTMATE 	"first mate"
#define OFFIC_TYPE_CARPENTER 	"carpenter"// MAXIMUS -->
#define OFFIC_TYPE_DOCTOR 		"doctor"
#define OFFIC_TYPE_ABORDAGE 	"deck fighter"// MAXIMUS <--
//=======================| OFFICERS |=======================//
// KK -->
#define OFFIC_TYPE_TRADER	 "trader"
// <-- KK
//========================| QUESTS |========================//any smugglers colony and island in the future
string DEFAULT_DESTINATION = "Conceicao smugglers";
string DEFAULT_TRADEISLAND = "Conceicao";

// NK -->
//MR -->
// states-->
#define MR_SINGLE				0
#define MR_MARRIED				1
#define MR_MISTRESS				2
// states <--
#define MRTALKPOINTS_SCALAR		5.0 //talkpoints scaled by this when added
//marpoints = ((fame * coeff)^pow*scalar + offset) * (basescale + frnd() * randscale)
#define MR_MPCOEFF				5.0
#define MR_MPPOW				0.415 //MUST BE >= 0.25
#define MR_MPSCALAR				18
#define MR_MPOFFSET				0
#define MR_MPBASESCALE			0.9
#define MR_MPRANDSCALE			0.2
#define MR_MPMIN				100 // if calc'd MP < this, MP = this.
#define MR_NONPROP_SCALAR		1.5 //scalar to marpoints if _not_ a proposal
#define MR_DAUGHTER_THRESH		500 //if frnd() < marpoints / this, mr is daughter; else niece
#define MR_INTRODUCE_CHANCE		0.25 // chance for gov to introduce MR to pchar. NOTE THIS IS ONLY ONCE PER DAY!
#define MR_INTR_CH_RANK_SCL		0.02 //sqrt(fame) * this is added to above
#define MR_MAXNUM				3 //max number of MRs introduced by governor at one time
//rep defines for dumping MR -->
#define MR_MINREP_TPTIMES		5 //min number times talked to for rep penalty
#define MR_REPPEN_SCALAR		0.5 //this * num times talked to = rep penalty
#define MR_MAXREPPENALTY		10 //max rep penalty for dumping, scaled by pcharrepphrase
#define MR_MIST_FAME_SCL		0.5 //scalar to mistresses' marp + talkp for scoring purposes
//rep defines for dumping MR <--
// MR <--

#define QUESTRUM_CHANCE			0.25 //chance to force selection of questrumor if one is available
#define QUESTRUM_UNGIVEN_CHANCE 0.5 //chance to force if above is available and not given yet.
// NK <--



object Address_Form; // not used 05-07-19
string AddressForms[256]; // size = MAX_NATIONS * MAX_ADDR_TYPES * 2. NK 05-07-18

void PlayerLostMoney(ref NPChar, int lostSum)
{
	ref PChar = GetMainCharacter();
	if(!CheckAttribute(PChar,"money")) PChar.money = 0;
	if(sti(PChar.money)==0) return;
	if(sti(PChar.money)<lostSum) lostSum = sti(PChar.money);
	PChar.money = makeint(sti(PChar.money)-lostSum);
	PlayStereoSound("INTERFACE\took_item.wav");
	if(IsMainCharacter(NPChar)) return;
	if(!CheckAttribute(NPChar,"money")) NPChar.money = 0;
	NPChar.money = makeint(sti(NPChar.money)+lostSum);
}

// KK -->
//MAXIMUS: universal translation method -->
string SpellString(string tdir, string tfile, ref str1, ref str2, string joinString)
{
	string strData1 = str1;
	string strData2 = str2;
	string translator = tdir + "\" + tfile;
	bool bUseCommonIni = tfile == "";
	int tmpLangFileID = -1;

	if (!bUseCommonIni) {
		if (FindFile("RESOURCE\INI\TEXTS\" + LanguageGetLanguage() + "\" + tdir, "*.txt", tfile) == "") {
			str1 = "";
			str2 = "";
			return "";
		}
		tmpLangFileID = LanguageOpenFile(translator);
	}

	string tmpData = " ";
	if (strData1 == "" || strData2 == "") tmpData = "";
	string resultString1 = "";
	if (bUseCommonIni)
		resultString1 = XI_ConvertString(strData1);
	else
		resultString1 = LanguageConvertString(tmpLangFileID, strData1);
	string resultString2 = "";
	if (bUseCommonIni)
		resultString2 = XI_ConvertString(strData2);
	else
		resultString2 = LanguageConvertString(tmpLangFileID, strData2);
	string resultString = joinString;
	if (bUseCommonIni)
		resultString = XI_ConvertString(resultString);
	else
		resultString = LanguageConvertString(tmpLangFileID, resultString);

	if (!bUseCommonIni) LanguageCloseFile(tmpLangFileID);

	str1 = resultString1;
	str2 = resultString2;
	return resultString;
}
//MAXIMUS: universal translation method <--

string TranslateString(string strData1, string strData2)
{
	string tmpData = " ";
	if (strData1 == "" || strData2 == "") tmpData = "";
	string joinString = strData1 + tmpData + strData2;//default for English
	string resultString = "";
	string str1 = strData1;
	string str2 = strData2;
	string rStr1 = "";
	string rStr2 = "";
	bool swap = false;

	resultString = SpellString("", "", &str1, &str2, joinString);
	if (resultString != "") return resultString;
	rStr1 = str1;
	rStr2 = str2;

	str1 = strData1;
	str2 = strData2;
	resultString = SpellString("", "interface_strings.txt", &str1, &str2, joinString);
	if (resultString != "") return resultString;
	if (rStr1 == "") rStr1 = str1;
	if (rStr2 == "") rStr2 = str2;

	str1 = strData1;
	str2 = strData2;
	resultString = SpellString("", "characters_names.txt", &str1, &str2, joinString);
	if (resultString != "") return resultString;
	if (rStr1 == "") rStr1 = str1;
	if (rStr2 == "") rStr2 = str2;

	str1 = strData1;
	str2 = strData2;
	resultString = SpellString(GetStorylineDir(FindCurrentStoryline()), "characters_names.txt", &str1, &str2, joinString);
	if (resultString != "") return resultString;
	if (rStr1 == "") rStr1 = str1;
	if (rStr2 == "") rStr2 = str2;

	str1 = strData1;
	str2 = strData2;
	resultString = SpellString("", "ItemsDescribe.txt", &str1, &str2, joinString);
	if (resultString != "") return resultString;
	if (rStr1 == "") rStr1 = str1;
	if (rStr2 == "") rStr2 = str2;

	str1 = strData1;
	str2 = strData2;
	resultString = SpellString(GetStorylineDir(FindCurrentStoryline()), "ItemsDescribe.txt", &str1, &str2, joinString);
	if (resultString != "") return resultString;
	if (rStr1 == "") rStr1 = str1;
	if (rStr2 == "") rStr2 = str2;

	str1 = strData1;
	str2 = strData2;
	resultString = SpellString("", "GoodsDescribe.txt", &str1, &str2, joinString);
	if (resultString != "") return resultString;
	if (rStr1 == "") rStr1 = str1;
	if (rStr2 == "") rStr2 = str2;

	str1 = strData1;
	str2 = strData2;
	resultString = SpellString("", "rumour_strings.txt", &str1, &str2, joinString);
	if (resultString != "") return resultString;
	if (rStr1 == "") rStr1 = str1;
	if (rStr2 == "") rStr2 = str2;

	str1 = strData1;
	str2 = strData2;
	resultString = SpellString(GetStorylineDir(FindCurrentStoryline()), "rumour_strings.txt", &str1, &str2, joinString);
	if (resultString != "") return resultString;
	if (rStr1 == "") rStr1 = str1;
	if (rStr2 == "") rStr2 = str2;


	if (rStr1 == "") rStr1 = strData1;
	if (rStr2 == "") rStr2 = strData2;
	switch(LanguageGetLanguage())
	{
		case "Russian":
			resultString = rStr2 + tmpData + rStr1;
		break;
		case "Polish":
			resultString = rStr2 + tmpData + rStr1;
		break;
		resultString = rStr1 + tmpData + rStr2;//default for English
	}

	return resultString;
}
// <-- KK

/*string LAi_FindRandomLocator(string group)
{
	if(IsEntity(loadedLocation) != true) return "";
	string at = "locators." + group;
	if(CheckAttribute(loadedLocation, at) == 0) return "";
	aref grp;
	makearef(grp, loadedLocation.(at));
	int num = GetAttributesNum(grp);
	if(num <= 0) return "";
	num = rand(num - 1);
	return GetAttributeName(GetAttributeN(grp, num));
}*/


void Quest_Init()
{
	//SetRumourDefaults(false); // NK
}

// NK -->
int GetDifficulty()
{
	ref pchar = GetMainCharacter();
	if(!CheckAttribute(pchar,"Difficulty")) pchar.Difficulty = 1;
	return sti(pchar.Difficulty);
}

int SetDifficulty(int newdiff)
{
	ref pchar = GetMainCharacter();
	if(!CheckAttribute(pchar,"Difficulty")) pchar.Difficulty = CharDifficulty;
	int olddiff =  sti(pchar.Difficulty);
	pchar.Difficulty = newdiff;
	SetTownMonsterProb("Oxbay", 2.0); // NK temp to fix Oxbay monsterprob for after first playing
	return olddiff;
}

string GetDifficultyName(int d)
{                             
	string retstr;
	switch(d)
	{
		case 1:
			retstr = XI_ConvertString("Apprentice");
			break;
		case 2:
			retstr = XI_ConvertString("Journeyman");
			break;
		case 3:
			retstr = XI_ConvertString("Adventurer");
			break;
		case 4:
			retstr = XI_ConvertString("Swashbuckler");
			break;

		//default: // scheffnow - bf
			retstr = XI_ConvertString("Unknown");
	}
	return retstr;
}

bool GetShipCap()
{
	ref pchar = GetMainCharacter();
	if(!CheckAttribute(pchar,"shipcap")) pchar.shipcap = START_DIFF_SHIPCAP; // NK add default. 05-04-24
	return sti(pchar.shipcap);
}

void SetShipCap(bool cap)
{

	ref pchar = GetMainCharacter();
	pchar.shipcap = cap;
}
// NK <--

// KAM -->
bool KAM_GetSailingIconsState()
{
	ref pchar = GetMainCharacter();
	if(!CheckAttribute(pchar,"sailingiconsstate")) pchar.sailingiconsstate = true;
	return sti(pchar.sailingiconsstate);
}

void KAM_SetSailingIconsState(bool cap)
{

	ref pchar = GetMainCharacter();
	pchar.sailingiconsstate = cap;
	// NK test 04-17 to make navigator disappear when icon pressed, not on reload BI
	//bah, doesn't work.
	/*if(IsEntity(&BattleInterface))
	{
		if(KAM_GetSailingIconsState())
		{
			BattleInterface.ShowNavigator = InterfaceStates.BattleShow.Navigator;
		}
		else
		{
			BattleInterface.ShowNavigator = false;
		}
		RefreshBattleInterface(); // try to refresh BI
	}*/
	// NK <--
	
}
// KAM <--

// move to set_indialogattributes to address section below 05-07-18

string RandSwear()	// ccc Nov05  fixed mess by unknown source :(
{
	int RandS = Rand(16);

	switch (RandS)
	{
		case 0:
			return XI_ConvertString("Anchor in my stern") +"!! ";
		break;

		case 1:
			return XI_ConvertString("Damn") +"!! ";
		break;

		case 2:
			return XI_ConvertString("O God") +"!! ";
		break;

		case 3:
			return XI_ConvertString("Devil") +"!! ";
		break;

		case 4:
			return XI_ConvertString("Sink my ship") +"!! ";
		break;

		case 5:
			return XI_ConvertString("Blow my belly") +"!! ";
		break;

		case 6:
			return XI_ConvertString("Thousand sharks") +"!! ";
		break;

		case 7:
			return XI_ConvertString("Arrgh") +"!! ";
		break;

		case 8:
			return XI_ConvertString("Oh heaven") +"!! ";
		break;

		case 9:
			return XI_ConvertString("Hell") +"!! ";
		break;

		case 10:
			return XI_ConvertString("Blow me butt") +"!! ";
		break;

		case 11:
			return XI_ConvertString("Goodness gracious me") +"!! ";
		break;

		case 12:
			return XI_ConvertString("Yikes") +"!! ";
		break;

		case 13:
			return XI_ConvertString("Poxridden doxy") +"!! ";
		break;

		case 14:
			return XI_ConvertString("Christ") +"!! ";
		break;

		case 15:
			return "(*" +  XI_ConvertString("Censored obscene language")  + "*) ";
		break;

		case 16:
			return XI_ConvertString("By Jove") +"!! ";
		break;


	}
}


int RandSum(string Amount)
{
	int Sum;

	switch(Amount)
	{
		case "Few":

			Sum = Few_Quest_Sum + Rand(Few_Quest_Sum/20)*10;
			trace("Generated sum is: " + Sum);
			return Sum;

		break;


		case "Some":

			Sum = Some_Quest_Sum + Rand(Some_Quest_Sum/200)*100;
			trace("Generated sum is: " + Sum);
			return Sum;

		break;

		case "Medium":

			Sum = Medium_Quest_Sum + Rand(Medium_Quest_Sum/200)*100;
			trace("Generated sum is: " + Sum);
			return Sum;

		break;

		case "Large":

			Sum = Large_Quest_Sum + Rand(Large_Quest_Sum/200)*100;
			trace("Generated sum is: " + Sum);
			return Sum;

		break;

		case "Huge":

			Sum = Huge_Quest_Sum + Rand(Huge_Quest_Sum/1000+1)*500;
			trace("Generated sum is: " + Sum);
			return Sum;

		break;
	}
return 0;
}


string LinkRandPhrase (string Var1, string Var2, string Var3)
{
	int RandP;
	RandP = Rand(2);
	//Trace("AAA: " + RandP);
	//Trace("AAA1: " + Var1);
	//Trace("AAA2: " + Var2);
	//Trace("AAA3: " + Var3);
	switch(RandP)
	{
		case 0:

			return /*"First phrase selected" + */ Var1;

		break;

		case 1:

			return /*"Second phrase selected" + */Var2;

		break;

		case 2:

			return /*"Third phrase selected" + */Var3;

		break;
	}
	return "ERROR";
}



string RandPhrase (string Var1, string Var2, string Var3, ref Diag, string Sound1, string sound2, string sound3)
{
	int RandP;
	RandP = Rand(2);
	//Trace("AAA: " + RandP);
	//Trace("AAA1: " + Var1);
	//Trace("AAA2: " + Var2);
	//Trace("AAA3: " + Var3);
	DeleteAttribute(Diag, "snd1");
	DeleteAttribute(Diag, "snd2");
	DeleteAttribute(Diag, "snd3");
	switch(RandP)
	{
		case 0:

			diag.snd = sound1;
			return /*"First phrase selected" + */ Var1;

		break;

		case 1:

			diag.snd = sound2;
			return /*"Second phrase selected" + */Var2;

		break;

		case 2:

			diag.snd = sound3;
			return /*"Third phrase selected" + */Var3;

		break;
	}
	return "ERROR";
}

string PCharPhrase (string Var1, string Var2)
{
	ref PlayerCharacter = GetMainCharacter();

	switch(PlayerCharacter.id)
	{
		case "Blaze":

			return Var1;

		break;

		case "Danielle":

			return Var2;

		break;
	}
	return "___Player Character is not defined - can't select character phrase___";
}

// NK -->
//selects random rumor based on island and nation.
//set either to "any" to override loc-based rumors
string SelectRumour(string rIsland, string rNation)
{
	//build available rumor table, borrowed from build encounter table. ;)
	int AvailRumors[256]; //temp, should be [TOTAL_RUMOURS];
	int NumRumours = 0;
	bool questavail = false;
	bool qonly = false;
	bool qungiven = false;

	for(int i = 0; i < TOTAL_RUMOURS; i++)
	{
		//if not active because quest not in progress, skip
		if(!CheckAttribute(&Rumour[i],"given")) Rumour[i].given = false;
		if(Rumour[i].state != "active") { continue; }
		
		// check chance
		if(rand(100) > sti(Rumour[i].chance)) { continue; }

		//Check island/country
		if(rIsland != "any" && rNation != "any")
			{ if(Rumour[i].loc != "all" && Rumour[i].loc != rIsland && Rumour[i].loc != rNation) { continue; } }

		if(CheckAttribute(&Rumour[i],"id")) { questavail = true; if(!sti(Rumour[i].given)) { qungiven = true; } } //there is a quest rumor available
		
		AvailRumors[NumRumours] = i;
		NumRumours++;
	}
	if (NumRumours == 0) 
	{
		//if none found, return default rumor
		return Rumour[0].text;
	}

	//get random rumor to return
	if(frnd() < QUESTRUM_CHANCE && questavail) qonly = true;
	if(qungiven && frnd() < QUESTRUM_UNGIVEN_CHANCE) qonly = true;
	int RumPlace = rand(NumRumours - 1);
	int RetRum = AvailRumors[RumPlace];
	if(qonly && !CheckAttribute(&Rumour[RetRum],"id"))
	{
		while(!CheckAttribute(&Rumour[RetRum],"id"))
		{
			RumPlace = rand(NumRumours - 1);
			RetRum = AvailRumors[RumPlace];
		}
	}
	//Log_SetStringToLog("Return: " + RetRum);

	//return rumor
	Rumour[RetRum].given = true;
	return Rumour[RetRum].text;

	//return Rumour[0].text;
}

//turns rumor on or off. NOTE: Rumor must have an ID! If not found, returns false, else true
bool SetRumourState(string id, bool bstate)
{
	string rstate = "active";
	if(!bstate) rstate = "in" + rstate;

	int idx = GetRumourIndex(id);
	if(idx == -1) return false;

	Rumour[idx].state = rstate;
	return true;
}

//checks if rumor with id matching exists, and if so returns index
int GetRumourIndex(string id)
{
	for(int i = 0; i < TOTAL_RUMOURS; i++)
	{
		if(CheckAttribute(Rumour[i],"id"))
		{
			if(Rumour[i].id == id) { return i; }
		}
	}
	return -1;
}
// NK <--


string SelectFraRumour()
{
	int Rumour_Index;
	ref CurrentRumour;
	Rumour_Index = rand(MAX_RUMOURS - 1);

	for(Rumour_Index; Rumour_Index<MAX_RUMOURS; Rumour_Index++)
	{
		makeref (CurrentRumour, Rumour[Rumour_Index]);
		if(CurrentRumour.state == "active")
		{
			if(CurrentRumour.country == "fra")
			{
				return CurrentRumour.text;
			}
		}
	}
	return Rumour[0].text;

}

string PCharRepPhrase (string Var1, string Var2)
{
	ref pchar = GetMainCharacter();

	if(makeint(pchar.reputation) < 41)
	{
		return Var2;
	}
	else
	{
		return Var1;
	}
}

void Alchogol (string ncharID)
{
	ref PChar;
	PChar = GetMainCharacter();

	switch(pchar.location)
	{
		case "Redmond_tavern":
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit1")
			{
				DoQuestReloadToLocation("redmond_tavern", "Sit", "Sit9", "alc2");
			}
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit3")
			{
				DoQuestReloadToLocation("redmond_tavern", "Sit", "Sit2", "alc2");
			}
		break;

		case "Oxbay_tavern":
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit1")
			{
				DoQuestReloadToLocation("Oxbay_tavern", "Sit", "Sit9", "alc2");
			}
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit3")
			{
				DoQuestReloadToLocation("Oxbay_tavern", "Sit", "Sit2", "alc2");
			}
		break;

		case "Greenford_tavern":
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit5")
			{
				DoQuestReloadToLocation("Greenford_tavern", "Sit", "Sit4", "alc2");
			}
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit1")
			{
				DoQuestReloadToLocation("Greenford_tavern", "Sit", "Sit2", "alc2");
			}
		break;

		case "Falaise_De_Fleur_tavern":

		break;

		case "Muelle_tavern":
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit1")
			{
				DoQuestReloadToLocation("Muelle_tavern", "Sit", "Sit2", "alc2");
			}
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit7")
			{
				DoQuestReloadToLocation("Muelle_tavern", "Sit", "Sit3", "alc2");
			}
		break;

		case "Douwesen_tavern":
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit1")
			{
				DoQuestReloadToLocation("Douwesen_tavern", "Sit", "Sit2", "alc2");
			}
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit7")
			{
				DoQuestReloadToLocation("Douwesen_tavern", "Sit", "Sit3", "alc2");
			}
		break;

		case "Pirate_tavern":
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit1")
			{
				DoQuestReloadToLocation("Conceicao_tavern", "Sit", "Sit2", "alc2");
			}
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit4")
			{
				DoQuestReloadToLocation("Conceicao_tavern", "Sit", "Sit3", "alc2");
			}
		break;

		case "Conceicao_tavern":
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit1")
			{
				DoQuestReloadToLocation("Conceicao_tavern", "Sit", "Sit2", "alc2");
			}
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit7")
			{
				DoQuestReloadToLocation("Conceicao_tavern", "Sit", "Sit3", "alc2");
			}
		break;

		case "Smugglers_tavern":
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit5")
			{
				DoQuestReloadToLocation("Conceicao_tavern", "Sit", "Sit6", "alc2");
			}
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit4")
			{
				DoQuestReloadToLocation("Conceicao_tavern", "Sit", "Sit3", "alc2");
			}
		break;

		case "QC_tavern":
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit1")
			{
				DoQuestReloadToLocation("Conceicao_tavern", "Sit", "Sit2", "alc2");
			}
			if (characters[GetCharacterIndex(ncharID)].location.locator == "sit3")
			{
				DoQuestReloadToLocation("Conceicao_tavern", "Sit", "Sit7", "alc2");
			}
		break;
	}
}

void PlaceSmugglersOnShore(string LocationId)
{
	ref Smuggler, player;
	int RandCounter;

	player = GetMainCharacter();

	string Models[20];
	Models[0] = "man1";
	Models[1] = "man1_1";
	Models[2] = "man1_2";
	Models[3] = "old_man1";
	Models[4] = "old_man2";
	Models[5] = "sailor1";
	Models[6] = "sailor2";
	Models[7] = "sailor3";
	Models[8] = "sailor4";
	Models[9] = "chelovek";
	Models[10] = "chelovek1";
	Models[11] = "man5_1";
	Models[12] = "bocman3";
	Models[13] = "bocman4";
	Models[14] = "sailor5";
	Models[15] = "Corsair1_2";
	Models[16] = "korsar";
	Models[17] = "Korsar1";
	Models[18] = "Black_Corsair";
	Models[19] = "Sailor6";

	//Trace("Перемещаю персонажей в локацию " + LocationID);

	Smuggler = CharacterFromId("Rand_Smug01");
	LAi_SetCurHPMax(CharacterFromId("Rand_Smug01"));
	Smuggler.model = Models[Rand(19)];
	Smuggler.Headmodel = "h_" + smuggler.model;
	Facemaker(Smuggler);

	LAi_SetWarriorTypeNoGroup(CharacterFromId("Rand_Smug01"));
	LAi_warrior_DialogEnable(CharacterFromId("Rand_Smug01"), true);
	LAi_warrior_SetStay(CharacterFromId("Rand_Smug01"), true);

	//CalculateAppropriateSkills(Smuggler); // NK

	LAi_group_MoveCharacter(Smuggler, "Smugglers");
	ChangeCharacterAddressGroup(Smuggler,LocationID,"Smugglers","Smuggler01");

	Smuggler = CharacterFromId("Rand_Smug02");
	LAi_SetCurHPMax(CharacterFromId("Rand_Smug02"));
	Smuggler.model = Models[Rand(19)];
	Smuggler.Headmodel = "h_" + smuggler.model;
	Facemaker(Smuggler);

	LAi_SetWarriorTypeNoGroup(CharacterFromId("Rand_Smug02"));
	LAi_warrior_DialogEnable(CharacterFromId("Rand_Smug02"), true);
	LAi_warrior_SetStay(CharacterFromId("Rand_Smug02"), true);

	//CalculateAppropriateSkills(Smuggler); // NK

	LAi_group_MoveCharacter(Smuggler, "Smugglers");
	ChangeCharacterAddressGroup(Smuggler,LocationID,"Smugglers","Smuggler02");

	Smuggler = CharacterFromId("Rand_Smug03");
	LAi_SetCurHPMax(CharacterFromId("Rand_Smug03"));
	Smuggler.model = Models[Rand(19)];
	Smuggler.Headmodel = "h_" + smuggler.model;
	Facemaker(Smuggler);

	LAi_SetWarriorTypeNoGroup(CharacterFromId("Rand_Smug03"));
	LAi_warrior_DialogEnable(CharacterFromId("Rand_Smug03"), true);
	LAi_warrior_SetStay(CharacterFromId("Rand_Smug03"), true);

	//CalculateAppropriateSkills(Smuggler); // NK

	LAi_group_MoveCharacter(Smuggler, "Smugglers");

	ChangeCharacterAddressGroup(Smuggler,LocationID,"Smugglers","Smuggler03");
	AddGeometryToLocation(LocationID, "smg");

	LAi_group_SetRelation(PLAYER_GROUP, "Smugglers", LAI_GROUP_NEITRAL);
	LAi_group_SetRelation("CoastalGuards", "Smugglers", LAI_GROUP_NEITRAL);

	Player.quest.Rand_Smuggling.win_condition.l1 = "Timer";
	Player.quest.Rand_Smuggling.win_condition.l1.date.day = GetAddingDataDay(0,0,3);
	Player.quest.Rand_Smuggling.win_condition.l1.date.month = GetAddingDataMonth(0,0,3);
	Player.quest.Rand_Smuggling.win_condition.l1.date.year = GetAddingDataYear(0,0,3);
	Player.quest.Rand_Smuggling.win_condition = "Rand_Smuggling";
}


void RemoveSmugglersFromShore()
{
	ref Smuggler, player;
	int RandCounter;

	player = getmainCharacter();

	//Trace("Убираю персонажей-контрабандистов");

	Player.quest.Rand_SmugglingRemove.win_condition.l1 = "ExitFromLocation";
	Player.quest.Rand_SmugglingRemove.win_condition.l1.location = player.location;
	Player.quest.Rand_SmugglingRemove.win_condition = "Rand_SmugglingRemove";

	DeleteAttribute(player, "quest.Contraband.Active");

	RemoveGeometryFromLocation(Player.Quest.SelectedSmugglingLocation, "smg");

	LAi_group_SetRelation(LAI_GROUP_PLAYER, "CoastalGuards", LAI_GROUP_NEITRAL);

}



string SelectSmugglingLocation()
{
	ref Pchar, CurIsland;
	String SmugLocation[4];
	string TargetLocation;

	Pchar = GetMainCharacter();
	int n;
	n = GetCharacterCurrentIsland(Pchar);
	if(n < 0) return "none";
	CurIsland = GetIslandByIndex(n);

	Trace("Selection Started. Island - " + CurIsland.id);
	TargetLocation = "None";

	switch (CurIsland.id)
	{
		case "FalaiseDeFleur":
			TargetLocation = "Falaise_de_fleur_shore";
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "Redmond":
			SmugLocation[0] = "Redmond_shore_01";
			SmugLocation[1] = "Redmond_shore_02";
			TargetLocation = SmugLocation[Rand(1)];
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "Conceicao":
			SmugLocation[0] = "Conceicao_shore_01";
			SmugLocation[1] = "Conceicao_shore_02";
			TargetLocation = SmugLocation[Rand(1)];
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "Oxbay":
			SmugLocation[0] = "Oxbay_shore_01";
			SmugLocation[1] = "Oxbay_shore_02";
			SmugLocation[2] = "Oxbay_lighthouse";
			TargetLocation = SmugLocation[Rand(2)];
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "IslaMuelle":
			TargetLocation = "muelle_shore";
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "Douwesen":
			SmugLocation[0] = "Douwesen_shore_01";
			SmugLocation[1] = "Douwesen_shore_02";
			TargetLocation = SmugLocation[Rand(1)];
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "QuebradasCostillas":
			TargetLocation = "none";
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "KhaelRoa":
			TargetLocation = "none";
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "Guadeloupe":
			TargetLocation = "Guadeloupe_shore_01";
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "Hispaniola":
			SmugLocation[0] = "Hispaniola_shore_02";
			SmugLocation[1] = "Hispaniola_shore_01";
			SmugLocation[2] = "Hispaniola_shore_03"; // KK
			SmugLocation[3] = "Hispaniola_shore_04"; // KK
			TargetLocation = SmugLocation[Rand(3)];
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "Turks":
			TargetLocation = "none";
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "Cuba":
// KK -->
			SmugLocation[0] = "Cuba_shore_01";
			SmugLocation[1] = "Cuba_shore_02";
			TargetLocation = SmugLocation[Rand(1)];
// <-- KK
			Trace("Location " + TargetLocation + " Selected");
		break;

// KK -->
		case "SaintMartin":
			SmugLocation[0] = "SaintMartin_shore_01";
			SmugLocation[1] = "SaintMartin_shore_02";
			TargetLocation = SmugLocation[Rand(1)];
			Trace("Location " + TargetLocation + " Selected");
		break;
// <-- KK

		case "Antigua":
			TargetLocation = "Antigua_shore";
			Trace("Location " + TargetLocation + " Selected");
		break;

		case "Cayman":
			SmugLocation[0] = "Cayman_Shore_01";
			SmugLocation[1] = "Cayman_Shore_02";
			SmugLocation[2] = "Cayman_Shore_03";
			TargetLocation = SmugLocation[Rand(2)];
			Trace("Location " + TargetLocation + " Selected");
		break;
	}

	Pchar.Quest.SelectedSmugglingLocation = TargetLocation;
return TargetLocation;
}


void SetCoastalGuardPursuit()
{
	ref Pchar, CurIsland, rCap1, rCap2, rCap3;
	// NK -->
	float mult = 1.0;
	string sFantomType = "war";
	ref Shiptype;
	aref arship;
	int CGNation;
	if(PIRATE_COASTGUARD == 1) // Captain Hawk Fix
	{CGNation = PIRATE;}
	else
	{CGNation = GetCurrentLocationNation();}
	// NK <--
	Pchar = GetMainCharacter();
	rCap1 = CharacterFromID("Coastal_Captain01");
	rCap2 = CharacterFromID("Coastal_Captain02");
	rCap3 = CharacterFromID("Coastal_Captain03");
	trace("Индекс текущего острова " + GetCharacterCurrentIsland(Pchar));
	CurIsland = GetIslandByIndex(GetCharacterCurrentIsland(Pchar));
	trace("Текущий остров: " + CurIsland.id);
	trace("Текущая нация острова: " + CGNation);

	//Простановка параметров капитанам береговой стражи
	LAi_SetHP(rCap1, 120, 120);
	rCap1.nation =  CGNation;
	Trace("НАЦИЯ КАПИТАНА" + rCap1.nation);
	SetRandomNameToCharacter(rCap1);
	rCap1.rank = makeint(Pchar.rank) - 2 + Rand(4);
	rCap1.experience = CalculateExperienceFromRank(sti(rCap1.rank));
	rCap1.model = SelectSoldierModelByNation(CGNation, "Officer");
	//rCap1.Headmodel = "h_" + rCap1.model;
	Facemaker(rCap1);

	//CalculateAppropriateSkills(rCap1); // NK

	SelectCoastalGuardShip(rCap1);

	SetBaseShipData(rCap1);
	// NK -->
	rCap1.shiptype = rCap1.ship.type;
	rCap1.FantomType = sFantomType;
	mult = 1.25;
	Shiptype = GetShipByType(GetCharacterShipType(rCap1));
	makearef(arship, rCap1.ship); // PRS3
	rCap1.Points = mult * stf(GetLocalShipAttrib(arship, Shiptype, "Weight")) / 5000; // PRS3
	rCap1.quest.officertype = OFFIC_TYPE_CAPNAVY;
	Fantom_SetRandomMoney(rCap1, sFantomType);
	Fantom_SetCannons(rCap1, sFantomType);
	Fantom_SetSails(rCap1, sFantomType);
	Fantom_ClearCargo(rCap1); // TIH clear out prior slot cargo
	Fantom_SetBalls(rCap1, sFantomType);
	Fantom_SetGoods(rCap1, sFantomType);
	Ship_SetFantomData(rCap1);
	LAi_Create_Officer(0, rCap1);
	LAi_NPC_Equip(rCap1, sti(rCap1.rank), true, 1.0);
	SetRandomNameToShip(rCap1);
	// NK <--

	Group_CreateGroup("Coastal_Guards");
	Group_addCharacter("Coastal_Guards", "Coastal_Captain01");
	Group_SetGroupCommander("Coastal_Guards", "Coastal_Captain01");

	if(GetCompanionQuantity(Pchar) > 1 || makeint(Pchar.rank) > 5)
	{
		LAi_SetHP(rCap2, 120, 120);
		rCap2.nation =  CGNation;
		SetRandomNameToCharacter(rCap2);
		rCap2.rank = makeint(Pchar.rank) - 2 + Rand(4);
		rCap2.experience = CalculateExperienceFromRank(sti(rCap2.rank));
		rCap2.model = SelectSoldierModelByNation(CGNation, "Officer");
		//rCap2.Headmodel = "h_" + rCap2.model;
		Facemaker(rCap2);

		//CalculateAppropriateSkills(rCap2); // NK

		SelectCoastalGuardShip(rCap2);

		SetBaseShipData(rCap2);
		// NK -->
		rCap2.shiptype = rCap2.ship.type;
		rCap2.FantomType = sFantomType;
		mult = 1.25;
		Shiptype = GetShipByType(GetCharacterShipType(rCap2));
		makearef(arship, rCap2.ship); // PRS3
		rCap2.Points = mult * stf(GetLocalShipAttrib(arship, Shiptype, "Weight")) / 5000; // PRS3
		rCap2.quest.officertype = OFFIC_TYPE_CAPNAVY;
		Fantom_SetRandomMoney(rCap2, sFantomType);
		Fantom_SetCannons(rCap2, sFantomType);
		Fantom_SetSails(rCap2, sFantomType);
		Fantom_ClearCargo(rCap2); // TIH clear out prior slot cargo
		Fantom_SetBalls(rCap2, sFantomType);
		Fantom_SetGoods(rCap2, sFantomType);
		Ship_SetFantomData(rCap2);
		LAi_Create_Officer(0, rCap2);
		LAi_NPC_Equip(rCap2, sti(rCap2.rank), true, 1.0);
		SetRandomNameToShip(rCap1);
		// NK <--



		Group_addCharacter("Coastal_Guards", "Coastal_Captain02");

	}

	if(GetCompanionQuantity(Pchar) > 2 || makeint(Pchar.rank) > 8)
	{
		LAi_SetHP(rCap3, 120, 120);
		rCap3.nation =  CGNation;
		SetRandomNameToCharacter(rCap3);
		rCap3.rank = makeint(Pchar.rank) - 2 + Rand(4);
		rCap3.experience = CalculateExperienceFromRank(sti(rCap3.rank));
		rCap3.model = SelectSoldierModelByNation(CGNation, "Officer");
		//rCap3.Headmodel = "h_" + rCap3.model;
		Facemaker(rCap3);


		//CalculateAppropriateSkills(rCap3); // NK

		SelectCoastalGuardShip(rCap3);

		SetBaseShipData(rCap3);
		// NK -->
		rCap3.shiptype = rCap3.ship.type;
		rCap3.FantomType = sFantomType;
		mult = 1.25;
		Shiptype = GetShipByType(GetCharacterShipType(rCap3));
		makearef(arship, rCap3.ship); // PRS3
		rCap3.Points = mult * stf(GetLocalShipAttrib(arship, Shiptype, "Weight")) / 5000; // PRS3
		rCap3.quest.officertype = OFFIC_TYPE_CAPNAVY;
		Fantom_SetRandomMoney(rCap3, sFantomType);
		Fantom_SetCannons(rCap3, sFantomType);
		Fantom_SetSails(rCap3, sFantomType);
		Fantom_ClearCargo(rCap3); // TIH clear out prior slot cargo
		Fantom_SetBalls(rCap3, sFantomType);
		Fantom_SetGoods(rCap3, sFantomType);
		Ship_SetFantomData(rCap3);
		LAi_Create_Officer(0, rCap3);
		LAi_NPC_Equip(rCap3, sti(rCap3.rank), true, 1.0);
		SetRandomNameToShip(rCap1);
		// NK <--



		Group_addCharacter("Coastal_Guards", "Coastal_Captain03");
	}
	Trace("FUNCTION SetCoastalGuardPursuit Reports: Current PLayer Island is: " + Islands[GetCharacterCurrentIsland(Pchar)].id);

	Group_SetPursuitGroup("Coastal_Guards", PLAYER_GROUP);
	Group_SetAddress("Coastal_Guards", Islands[GetCharacterCurrentIsland(Pchar)].id, "", "");
	SetCharacterRelationBoth(GetCharacterIndex("Coastal_Captain01"),GetMainCharacterIndex(),RELATION_ENEMY);
	Group_SetTaskAttack("Coastal_Guards", PLAYER_GROUP);
	Group_LockTask("Coastal_Guards");
}


void StopCoastalGuardPursuit()
{
	ref Pchar, rCap1, rCap2, rCap3;
	Pchar = GetMainCharacter();
	rCap1 = CharacterFromID("Coastal_Captain01");
	rCap2 = CharacterFromID("Coastal_Captain02");
	rCap3 = CharacterFromID("Coastal_Captain03");

	group_DeleteGroup("Coastal_Guards");
	ChangeCharacterAddressGroup(CharacterFromID("Coastal_Captain01"), "None", "", "");
	ChangeCharacterAddressGroup(CharacterFromID("Coastal_Captain02"), "None", "", "");
	ChangeCharacterAddressGroup(CharacterFromID("Coastal_Captain03"), "None", "", "");

}

void SelectCoastalGuardShip(ref rCharacter)
{
	// PS -->
	ref PChar;
	PChar = GetMainCharacter();
	int irank = sti(PChar.Rank)/2;
	int pRank = sti(PChar.rank);
	if(GetShipCap()) { if((8-GetCharacterShipClass(PChar)) * 2 < pRank) { pRank = (8-GetCharacterShipClass(PChar)) * 2; } } // NK
	irank = makeint((pRank/2.0 + Rand(pRank/2)) * (2.0/3.0 + ((makefloat(GetDifficulty())-1.0)/5.0)) + 0.5);
	if(irank < 1) irank = 1;
	//Log_SetStringToLog("P" + pRank +" N" + irank);

	//NK new findship function
	//int minrank = makeint(irank/2.0 + rand(irank*50/100.0) + 0.25);
	//if(minrank > irank) minrank = irank;
	//int maxrank = makeint(minrank + rand(irank*37/100) + 0.25);
	//Log_SetStringToLog("Minrank " + minrank + "; Max " + maxrank);
	//Log_SetStringToLog("Rank " + irank);
	int minclass = 7 - makeint((irank - Rand(3))/2) ;
	int maxclass = 7 - makeint((irank + Rand(3))/2) ;
	if(maxclass < 7 - makeint(makeint(PChar.rank) * 2 / 3)) maxclass = 7 - makeint(makeint(PChar.rank) * 2 / 3);
	if(minclass < 7 - makeint(makeint(PChar.rank) * 2 / 3)) minclass = 7 - makeint(makeint(PChar.rank) * 2 / 3);
	if(maxclass < MAXCOASTGUARDCLASS) maxclass = MAXCOASTGUARDCLASS;
	if(minclass < MAXCOASTGUARDCLASS) minclass = MAXCOASTGUARDCLASS;
	if(minclass > 6) minclass = 6;
	if(maxclass > 6) maxclass = 6;
	rCharacter.Ship.idx = Force_GetShipType(maxclass, minclass, "War", sti(rCharacter.nation)); // PS
	rCharacter.Ship.Type = GetShipID(sti(rCharacter.Ship.idx)); // NK
	// PRS3 -->
	aref arship; makearef(arship, rCharacter.ship);
	DeleteAttribute(rCharacter, "ship.stats");
//KB - Tuning ships - changed call to SetRandomStatsToShip
	SetRandomStatsToShip(sti(rCharacter.index), sti(arship.idx), sti(rCharacter.nation));
//KB - orig SetRandomStatsToShip(arship, sti(arship.idx), sti(rCharacter.nation));
//KB
	// PRS3 <--
	/*int Jopa;

	Pchar = Getmaincharacter();
	trace("FUNCTION SelectCoastalGuardShip Reports: Current Captain Nation Is: " + rCharacter.nation);

	if(sti(rCharacter.nation) == ENGLAND || sti(rCharacter.nation) == FRANCE || sti(rCharacter.nation) == SPAIN || sti(rCharacter.nation) == HOLLAND || sti(rCharacter.nation) == PORTUGAL)
	{

		jopa = sti(rCharacter.nation);
		switch(jopa)
		{
			case ENGLAND:
				rCharacter.ship = SHIP_SLOOP_ENGLAND;
				if(sti(Pchar.rank) >= 3) rCharacter.ship.type = SHIP_BRIG_ENGLAND;
				if(sti(Pchar.rank) >= 5) rCharacter.ship.type = SHIP_CORVETTE_ENGLAND;
				if(sti(Pchar.rank) >= 7) rCharacter.ship.type = SHIP_FRIGATE_ENGLAND;
				trace("FUNCTION SelectCoastalGuardShip Reports: Ship " + rCharacter.ship.type + " was selected for " + RCharacter.id);
			break;

			case FRANCE:
				rCharacter.ship = SHIP_SLOOP_FRANCE;
				if(sti(Pchar.rank) >= 3) rCharacter.ship.type = SHIP_BRIG_FRANCE;
				if(sti(Pchar.rank) >= 5) rCharacter.ship.type = SHIP_CORVETTE_FRANCE;
				if(sti(Pchar.rank) >= 7) rCharacter.ship.type = SHIP_FRIGATE_FRANCE;
				trace("FUNCTION SelectCoastalGuardShip Reports: Ship " + rCharacter.ship.type + " was selected for " + RCharacter.id);
			break;

			case SPAIN:
				rCharacter.ship = SHIP_SLOOP_SPAIN;
				if(sti(Pchar.rank) >= 3) rCharacter.ship.type = SHIP_BRIG_SPAIN;
				if(sti(Pchar.rank) >= 5) rCharacter.ship.type = SHIP_CORVETTE_SPAIN;
				if(sti(Pchar.rank) >= 7) rCharacter.ship.type = SHIP_FRIGATE_SPAIN;
				trace("FUNCTION SelectCoastalGuardShip Reports: Ship " + rCharacter.ship.type + " was selected for " + RCharacter.id);
			break;

			case HOLLAND:
				rCharacter.ship = SHIP_SLOOP_HOLLAND;
				if(sti(Pchar.rank) >= 3) rCharacter.ship.type = SHIP_BRIG_HOLLAND;
				if(sti(Pchar.rank) >= 5) rCharacter.ship.type = SHIP_CORVETTE_HOLLAND;
				if(sti(Pchar.rank) >= 7) rCharacter.ship.type = SHIP_FRIGATE_HOLLAND;
				trace("FUNCTION SelectCoastalGuardShip Reports: Ship " + rCharacter.ship.type + " was selected for " + RCharacter.id);
			break;

			case PORTUGAL:
				rCharacter.ship = SHIP_SLOOP_PORTUGAL;
				if(sti(Pchar.rank) >= 3) rCharacter.ship.type = SHIP_BRIG_PORTUGAL;
				if(sti(Pchar.rank) >= 5) rCharacter.ship.type = SHIP_CORVETTE_PORTUGAL;
				if(sti(Pchar.rank) >= 7) rCharacter.ship.type = SHIP_FRIGATE_PORTUGAL;
				trace("FUNCTION SelectCoastalGuardShip Reports: Ship " + rCharacter.ship.type + " was selected for " + RCharacter.id);
			break;
		}
	}
	else
	{
		trace("FUNCTION SelectCoastalGuardShip reports: Character is a pirate or has no nation at all");
	}*/
}

string SelectSoldierModelByNation(int nat, string SoldierOrOfficer) // NK switched from ref char to int nat 05-07-10, rewritten for modeltypes
{
	switch(SoldierOrOfficer)
	{
		case "officer": return GetRandomModelForTypeNation(true, "Land_Officers", nat); break;
		// default, soldier
			return GetRandomModelForTypeNation(true, "Soldiers", nat);
	}
	/*string model;
	int jopa;

	if(sti(rCharacter.nation) == ENGLAND || sti(rCharacter.nation) == FRANCE || sti(rCharacter.nation) == SPAIN || sti(rCharacter.nation) == HOLLAND || sti(rCharacter.nation) == PORTUGAL)
	{
		jopa = sti(rCharacter.nation);
		switch(jopa)
		{
			case ENGLAND:
				if(SoldierorOfficer == "officer") model = "offic_eng";
				if(SoldierorOfficer == "soldier") model = "soldier_eng";
			break;

			case FRANCE:
				if(SoldierorOfficer == "officer") model = "offic_fra";
				if(SoldierorOfficer == "soldier") model = "soldier_fra";
			break;

			case SPAIN:
				if(SoldierorOfficer == "officer") model = "offic_spa";
				if(SoldierorOfficer == "soldier") model = "soldier_spa";
			break;

			case HOLLAND:
				if(SoldierorOfficer == "officer") model = "offic_hol";
				if(SoldierorOfficer == "soldier") model = "soldier_hol";
			break;

			case PORTUGAL:
				if(SoldierorOfficer == "officer") model = "offic_por";
				if(SoldierorOfficer == "soldier") model = "soldier_por";
			break;

		}
		return model;

	}
	else
	{
		trace("FUNCTION SelectSoldierModelByNation Reports: Character is a pirate or has no nation at all");
		//Log_SetStringToLog("FUNCTION SelectSoldierModelByNation Reports: Character is a pirate or has no nation at all");
		return "Blaze";
	}*/
}

void AddGeometryToLocation(string LocationID, string ModelName)
{
	ref LocationRef;
	int n = 1;
	string str;
	locationRef = &locations[FindLocation(LocationID)];

	for(n = 1; n < 10; n++)
	{
		str = n;
		if(!CheckAttribute(LocationRef, "models.always." + str))
		{
			LocationRef.models.always.(str) = ModelName;
			LocationRef.models.always.(str).tech = "dLightModel";
			break;
		}
	}
}

void RemoveGeometryFromLocation(string LocationID, string ModelName)
{
	ref LocationRef;
	int n = 1;
	string str;
	trace("FUNCTION RemoveGeometryFromLocation reports: Current location ID is " + LocationID + " and geometry " + ModelName + " should be removed");
	if(FindLocation(LocationID) != -1)
	{
		locationRef = &locations[FindLocation(LocationID)];
	}
	else
	{
		return;
	}

	for(n = 1; n < 10; n++)
	{
		str = n;
		trace("FUNCTION RemoveGeometryFromLocation reports: Checking Geometry name for n = " + str + ". It is " + LocationRef.models.always.(str));
		if(LocationRef.models.always.(str) == ModelName)
		{
			trace("JOPA!");
			DeleteAttribute(LocationRef, "models.always." + str);
			break;
		}
	}
}

// NK -->
void FindPerks(ref NPChar)
{
	//set up chances
	int perk_first = 10;
	int perk_first_two = 8;
	int perk_first_unlikey = 6;
	int perk_second = 5;
	int perk_second_unlikely = 4;
	int perk_third = 3;
	int perk_fourth = 2;

	//Melee
	if(Rand(100) < makeint(Npchar.skill.Fencing) * perk_first) Npchar.perks.list.BasicDefense = "1";
	if(Rand(100) < makeint(Npchar.skill.Fencing) * perk_second && Npchar.perks.list.BasicDefense == "1") Npchar.perks.list.AdvancedDefense = "1";
	if(Rand(100) < makeint(Npchar.skill.Fencing) * perk_first) Npchar.perks.list.CriticalHit = "1";
	if(Rand(100) < makeint(Npchar.skill.Fencing) * perk_third && Npchar.perks.list.AdvancedDefense == "1" && Npchar.perks.list.CriticalHit == "1") Npchar.perks.list.SwordplayProfessional = "1";
	if(Rand(100) < makeint(Npchar.skill.Fencing) * perk_first_two) Npchar.perks.list.Gunman = "1";
	if(Rand(100) < makeint(Npchar.skill.Fencing) * perk_second && Npchar.perks.list.Gunman == "1") Npchar.perks.list.GunProfessional = "1";


	//Cannons
	if(Rand(100) < makeint(Npchar.skill.Cannons) * perk_first) Npchar.perks.list.FastReload = "1";
	if(Rand(100) < makeint(Npchar.skill.Cannons) * perk_second_unlikely && Npchar.perks.list.FastReload == "1") Npchar.perks.list.ImmediateReload = "1";

	if(Rand(100) < makeint(Npchar.skill.Accuracy) * perk_first_two) Npchar.perks.list.HullDamageUp = "1";
	if(Rand(100) < makeint(Npchar.skill.Accuracy) * perk_first_two) Npchar.perks.list.SailsDamageUp = "1";
	if(Rand(100) < makeint(Npchar.skill.Accuracy) * perk_first_two) Npchar.perks.list.CrewDamageUp = "1";
	if(Rand(100) < makeint(Npchar.skill.Accuracy) * perk_first_two) Npchar.perks.list.LongRangeShoot = "1";

	if(Rand(100) < makeint(Npchar.skill.Accuracy) * perk_second_unlikely && Npchar.perks.list.HullDamageUp == "1" && Npchar.perks.list.SailsDamageUp == "1" && Npchar.perks.list.CrewDamageUp == "1") Npchar.perks.list.CriticalShoot = "1";

	if(Rand(100) < makeint(Npchar.skill.Accuracy) * perk_third && Rand(100) < makeint(Npchar.skill.Cannons) * perk_third && Npchar.perks.list.LongRangeShoot == "1" && Npchar.perks.list.CriticalShoot == "1" && Npchar.perks.list.FastReload == "1") Npchar.perks.list.CannonProfessional = "1";


	//Sailing
	if(Rand(100) < makeint(Npchar.skill.Sailing) * perk_first_two) Npchar.perks.list.ShipSpeedUp = "1";
	if(Rand(100) < makeint(Npchar.skill.Sailing) * perk_first_two) Npchar.perks.list.ShipTurnRateUp = "1";
	if(Rand(100) < makeint(Npchar.skill.Sailing) * perk_first_two) Npchar.perks.list.StormProfessional = "1";

	if(Rand(100) < makeint(Npchar.skill.Sailing) * perk_second && Npchar.perks.list.ShipSpeedUp == "1" && Npchar.perks.list.ShipTurnRateUp == "1") Npchar.perks.list.Turn180 = "1";
	if(Rand(100) < makeint(Npchar.skill.Sailing) * perk_third && Npchar.perks.list.Turn180 == "1") Npchar.perks.list.SandbankManeuver = "1";
	if(Rand(100) < makeint(Npchar.skill.Sailing) *  perk_fourth && Npchar.perks.list.StormProfessional == "1" && Npchar.perks.list.SandbankManeuver == "1") Npchar.perks.list.SailingProfessional = "1";


	//Grappling
	if(Rand(100) < makeint(Npchar.skill.Grappling) * perk_first) Npchar.perks.list.LongRangeGrappling = "1";
	if(Rand(100) < makeint(Npchar.skill.Grappling) * perk_second && Npchar.perks.list.LongRangeGrappling == "1") Npchar.perks.list.GrapplingProfessional = "1";
	if(Rand(100) < makeint(Npchar.skill.Grappling) * perk_third && Npchar.perks.list.SailingProfessional == "1" && Npchar.perks.list.GrapplingProfessional == "1") Npchar.perks.list.InstantBoarding = "1";


	//Repair
	if(Rand(100) < makeint(Npchar.skill.Repair) * perk_first) Npchar.perks.list.LightRepair = "1";
	if(Rand(100) < makeint(Npchar.skill.Repair) * perk_second && Npchar.perks.list.LightRepair == "1") Npchar.perks.list.InstantRepair = "1";


	//Defense
	if(Rand(100) < makeint(Npchar.skill.Defence) * perk_first) Npchar.perks.list.BasicBattleState = "1";
	if(Rand(100) < makeint(Npchar.skill.Defence) * perk_second && Npchar.perks.list.BasicBattleState == "1") Npchar.perks.list.AdvancedBattleState = "1";
	if(Rand(100) < makeint(Npchar.skill.Defence) * perk_second_unlikely && Npchar.perks.list.BasicBattleState == "1" && Npchar.perks.list.AdvancedBattleState == "1") Npchar.perks.list.ShipDefenseProfessional = "1";


	//Leadership
	if(Rand(100) < makeint(Npchar.skill.Leadership) * perk_first_unlikey) Npchar.perks.list.IronWill = "1";
	if(Rand(100) < makeint(Npchar.skill.Leadership) * perk_first) Npchar.perks.list.SharedExperience = "1";

	//Commerce
	if(Rand(100) < makeint(Npchar.skill.Commerce) * perk_first_two) Npchar.perks.list.Trustworthy = "1";
	if(Rand(100) < makeint(Npchar.skill.Commerce) * perk_first) Npchar.perks.list.BasicCommerce = "1";
	if(Rand(100) < makeint(Npchar.skill.Commerce) * perk_second && Npchar.perks.list.BasicCommerce == "1") Npchar.perks.list.AdvancedCommerce = "1";
}
// NK <--

void CalculateAppropriateSkills(ref NPchar)
{
// NK -->
	float MiddleK;

	ref Pchar;
	Pchar = GetMainCharacter();
	MiddleK = makeint((makeint(Pchar.skill.Leadership) + makeint(Pchar.skill.Fencing) + makeint(Pchar.skill.Sailing) +
makeint(Pchar.skill.Accuracy) + makeint(Pchar.skill.Cannons) + makeint(Pchar.skill.Grappling) + makeint(Pchar.skill.Repair) +
makeint(Pchar.skill.Defence) + makeint(Pchar.skill.Commerce) + makeint(Pchar.skill.Sneak))/10);
	if(MiddleK < (10 + makeint(NPchar.rank) * 2) / 10) MiddleK = (10 + makeint(NPchar.rank) * 2) / 10;

			//make skills
			Npchar.skill.Leadership = makeint(MiddleK - 2.5 + rand(5));
			if(makeint(Npchar.skill.Leadership)	<= 1) Npchar.skill.Leadership = 1;
			if(makeint(Npchar.skill.Leadership)	>= 10) Npchar.skill.Leadership = 10;

			Npchar.skill.Fencing = makeint(MiddleK - 2.5 + rand(5));
			if(makeint(Npchar.skill.Fencing)	<= 1) Npchar.skill.Fencing = 1;
			if(makeint(Npchar.skill.Fencing)	>= 10) Npchar.skill.Fencing = 10;

			Npchar.skill.Sailing = makeint(MiddleK - 2.5 + rand(5));
			if(makeint(Npchar.skill.Sailing)	<= 1) Npchar.skill.Sailing = 1;
			if(makeint(Npchar.skill.Sailing)	>= 10) Npchar.skill.Sailing = 10;

			Npchar.skill.Accuracy = makeint(MiddleK - 2.5 + rand(5));
			if(makeint(Npchar.skill.Accuracy)	<= 1) Npchar.skill.Accuracy = 1;
			if(makeint(Npchar.skill.Accuracy)	>= 10) Npchar.skill.Accuracy = 10;

			Npchar.skill.Cannons = makeint(MiddleK - 2.5 + rand(5));
			if(makeint(Npchar.skill.Cannons)	<= 1) Npchar.skill.Cannons = 1;
			if(makeint(Npchar.skill.Cannons)	>= 10) Npchar.skill.Cannons = 10;

			Npchar.skill.Grappling = makeint(MiddleK - 2.5 + rand(5));
			if(makeint(Npchar.skill.Grappling)	<= 1) Npchar.skill.Grappling = 1;
			if(makeint(Npchar.skill.Grappling)	>= 10) Npchar.skill.Grappling = 10;

			Npchar.skill.Repair = makeint(MiddleK - 2.5 + rand(5));
			if(makeint(Npchar.skill.Repair)	<= 1) Npchar.skill.Repair = 1;
			if(makeint(Npchar.skill.Repair)	>= 10) Npchar.skill.Repair = 10;

			Npchar.skill.Defence = makeint(MiddleK - 2.5 + rand(5));
			if(makeint(Npchar.skill.Defence)	<= 1) Npchar.skill.Defence = 1;
			if(makeint(Npchar.skill.Defence)	>= 10) Npchar.skill.Defence = 10;

			Npchar.skill.Commerce = makeint(MiddleK - 2.5 + rand(5));
			if(makeint(Npchar.skill.Commerce)	<= 1) Npchar.skill.Commerce = 1;
			if(makeint(Npchar.skill.Commerce)	>= 10) Npchar.skill.Commerce = 10;

			Npchar.skill.Sneak = makeint(MiddleK - 2.5 + rand(5));
			if(makeint(Npchar.skill.Sneak)	<= 1) Npchar.skill.Sneak = 1;
			if(makeint(Npchar.skill.Sneak)	>= 10) Npchar.skill.Sneak = 10;

			FindPerks(Npchar);
// NK <--
}


/*
int FindFreeRandomOfficer()
{
	int Counter, OfficerIdx;
	ref Pchar;
	
	Pchar = GetMainCharacter();
	string OfficerId;

	// NK-->
		int i, cn;
	
		for(counter = 0; counter <=24; counter++)
		{
			OfficerId = "Enc_Officer_" + counter;
	
			OfficerIdx = GetCharacterIndex(OfficerId);
			bool temp = FindFellowTravellers(PChar, CharacterFromId(OfficerId))==0;
			for(i=1; i<4; i++)
			{
				cn = GetCompanionIndex(&Pchar,i);
				if(cn != -1)
				{
					if(temp) temp = FindFellowTravellers(GetCharacter(cn), CharacterFromId(OfficerId))==0;
				}
			}
			if(temp) return OfficerIdx;
	// NK <--
	}

	return -1;
}
*/


int FindFreeRandomOfficer()
{
	// this function rewritten by KAM so new officers don't keep overwriting captains on shore leave [changes made by MAXIMUS 07.10.2007]

	for(int tempnum=0; tempnum<=NUM_RANDOM_OFFICERS; tempnum++) // NK 05-03-30 we now use char not exist to stop loop, so we can have any number of enc_off.
	{
		string tempid = "Enc_Officer_" + tempnum;
		int tempidx = GetCharacterIndex(tempid);
		if(tempidx==-1) break; // NK 05-03-30 ditto
		ref tempChar = GetCharacter(tempidx);

		if(bAllies(tempChar)) { continue; }

		DeleteCharacter(tempChar);

		return tempidx;
	}

	return -1;
}

//MAXIMUS: the same way, as Enc_Officer -[it was my first version of this function (rewritten later by TIH)]->
int FindFreeCabinCaptain()
{
	for(int tempnum=0; tempnum<=CABINCAPTAINS_MAX; tempnum++)
	{
		string tempid = "Enc_CabinCaptain_" + tempnum;
		int tempidx = GetCharacterIndex(tempid);
		if(tempidx==-1) break;
		ref tempChar = GetCharacter(tempidx);

		if(bAllies(tempChar)) { continue; }

		DeleteCharacter(tempChar);

		return tempidx;
	}

	return -1;
}
//MAXIMUS: the same way, as Enc_Officer <-[it was my first version of this function (rewritten later by TIH)]-

// TIH --> consolidated officer hired functions
// used for cabinfight_dialog.c
// used for prisoned_dialog.c
// used for enc_fort_dialog.c 	(not yet needed ?)
// used for enc_shipmate.c 		(not yet needed ?)
// used for both_reaction.c 	(not yet needed ?)
// this makes a character into an officer for the player. Function flags allow control of how the officer is handled:
//	bLowSalary 		- makes their salary lower
//	bAutoAssign 	- will force the officer into one of the officer slots of the character
//	bPurgeCrud 		- this will 'clean' the copied result from garbage that existed in the copy from character (needed for shipcaptains)
//	bSetType 		- this will run the officer type setup function (needed for ones that dont show you stats when hiring)
//	bCreateOfficer 	- this will actually run the full create officer functions on a character slot (not used at the moment)
void TIH_OfficerHiredProcess(ref RefChar, bool bLowSalary, bool bAutoAssign, bool bPurgeCrud, bool bSetType, bool bCreateOfficer)
{
	ref PChar = GetMainCharacter();
	ref NewOfficer = &NullCharacter();
	int NewOfficerIdx;
	string NewOfficerID;

	PChar.quest.HiringOfficerIDX = GetCharacterIndex(RefChar.id);

	int freeidx = FindFreeRandomOfficer();// get an open officer slot to use (50 maximum)
	if(freeidx != -1)
	{
		//trace("-----------------------------------------------------------------");
		//trace("dialog_func.c:");

		// cleaner method
		NewOfficerIdx 	= sti(Characters[freeidx].index);
		NewOfficer 		= GetCharacter(NewOfficerIdx);
		NewOfficerID 	= NewOfficer.id;// store this because we have to put it back after the copyattr

		PChar.quest.NewOfficerIdx = NewOfficerIdx;// store for second function

		//	trace("Hiring Officer IDX is " + PChar.quest.HiringOfficerIDX + " and he has id  " + Characters[sti(PChar.quest.HiringOfficerIDX)].id);
		//	trace("Free Random Officer IDX is " + NewOfficerIdx + " and he has id  " + NewOfficerID);

//MAXIMUS: hired captain will stay in location with player -->
//		ChangeCharacterAddressGroup(&RefChar, "None", "", "");// get rid of the reference character
		if(RefChar.sex == "woman") RefChar.greeting = "Gr_Officer_f common";
		else RefChar.greeting = "Gr_Officer_m common";
		RefChar.Dialog.Filename = "Enc_Officer_dialog.c";
		RefChar.Dialog.CurrentNode = "Hired";
		CopyAttributes(&NewOfficer, &RefChar);// copy all attr from the reference character (the hiring officer) to the new officer char
		if(bSetType) { LAi_SetOfficerType(RefChar); }
		LAi_group_MoveCharacter(RefChar, LAI_GROUP_PLAYER);
		RefChar.location = "none";
//MAXIMUS: hired captain will stay in location with player <--

		NewOfficer.index = NewOfficerIdx;// reset these after the copyattr
		NewOfficer.id    = NewOfficerID; // reset these after the copyattr
		NewOfficer.friend = true;
		NewOfficer.ship.type = "Not Used";
		NewOfficer.ship.idx = 1000;
		NewOfficer.nodisarm = 1;
		NewOfficer.location = "none";


		//trace("New Officer IDX is " + NewOfficer.index + " and he has id  " + NewOfficer.id);
		//trace("dialog_func.c - > officer dump before cleaning:"); DumpAttributes( Characters[sti(PChar.quest.NewOfficerIdx)] );
/*
		// these do fixing
		if(NewOfficer.sex == "woman") 	NewOfficer.greeting = "Gr_Officer_f common";
		else 							NewOfficer.greeting = "Gr_Officer_m common";
		NewOfficer.Dialog.Filename = "Enc_Officer_dialog.c";
		NewOfficer.Dialog.CurrentNode = "Hired";
		NewOfficer.AbordageMode = 1;// boal 05.09.03 officer set to go to abordage
*/
		// TIH --> suggested additions from maximus, adjusted for this code Aug29'06
// TIH --> no, see if this attr doesnt exist for NEW officer, its because REF officer didn't have it in the first place, so trying to assign it the null field again is a bit pointless and dangerous - Oct30'06
//		if (!CheckAttribute(NewOfficer,"location.locator") && CheckAttribute(RefChar, "location.locator")) NewOfficer.location.locator = RefChar.location.locator;// ? was a bug with not existent location.locator // KK now that should be OK 
//		if (!CheckAttribute(NewOfficer,"location.locator"))	NewOfficer.location.locator = "";// TIH - actually set it to nothing for fresh reset - Oct30'06
// TIH <--
		if (!CheckAttribute(NewOfficer,"model.entity")) 	NewOfficer.model.entity = "NPCharacter";// ? sometimes was an error - "can't create class"
		if (!CheckAttribute(NewOfficer,"noFollowType")) 	NewOfficer.noFollowType = "nofollow";// ? new identifier for template LAi_follow.c
		if (!CheckAttribute(NewOfficer,"money")) 			NewOfficer.money = 1+rand(100);// ? was a bug with not existent money
		// TIH <--

		if (bPurgeCrud) {// purge a whole bunch of broken crud that causes bugs for this new officer (captured captains only)
			if ( CheckAttribute(NewOfficer,"ship") ) 			DeleteAttribute(NewOfficer,"ship");
			if ( CheckAttribute(NewOfficer,"shiptype") ) 		DeleteAttribute(NewOfficer,"shiptype");
			if ( CheckAttribute(NewOfficer,"shipmoney") ) 		DeleteAttribute(NewOfficer,"shipmoney");
			if ( CheckAttribute(NewOfficer,"curshipnum") ) 		DeleteAttribute(NewOfficer,"curshipnum");
			if ( CheckAttribute(NewOfficer,"seaai") ) 			DeleteAttribute(NewOfficer,"seaai");
			if ( CheckAttribute(NewOfficer,"features") ) 		DeleteAttribute(NewOfficer,"features");
			if ( CheckAttribute(NewOfficer,"viper_sailstype") ) DeleteAttribute(NewOfficer,"viper_sailstype");
			if ( CheckAttribute(NewOfficer,"seatime") ) 		DeleteAttribute(NewOfficer,"seatime");
			if ( CheckAttribute(NewOfficer,"relation") ) 		DeleteAttribute(NewOfficer,"relation");
			if ( CheckAttribute(NewOfficer,"fantomtype") ) 		DeleteAttribute(NewOfficer,"fantomtype");
			if ( CheckAttribute(NewOfficer,"canfiretime") ) 	DeleteAttribute(NewOfficer,"canfiretime");
			if ( CheckAttribute(NewOfficer,"rankscale") ) 		DeleteAttribute(NewOfficer,"rankscale");
			if ( CheckAttribute(NewOfficer,"tmpperks") ) 		DeleteAttribute(NewOfficer,"tmpperks");
			if ( CheckAttribute(NewOfficer,"tmpskill") ) 		DeleteAttribute(NewOfficer,"tmpskill");
			if ( CheckAttribute(NewOfficer,"points") ) 			DeleteAttribute(NewOfficer,"points");
			if ( CheckAttribute(NewOfficer,"randofficers") ) 	DeleteAttribute(NewOfficer,"randofficers");
			if ( CheckAttribute(NewOfficer,"skillnatmult") ) 	DeleteAttribute(NewOfficer,"skillnatmult");
			if ( CheckAttribute(NewOfficer,"nodisarm") ) 		DeleteAttribute(NewOfficer,"nodisarm");
			if ( CheckAttribute(NewOfficer,"points") ) 			DeleteAttribute(NewOfficer,"points");
			if ( CheckAttribute(NewOfficer,"isFantom") ) 		DeleteAttribute(NewOfficer,"isFantom");
			if ( CheckAttribute(NewOfficer,"status") ) 			DeleteAttribute(RefChar,"status");
			if ( CheckAttribute(NewOfficer,"position") ) 		DeleteAttribute(RefChar,"position");
			if ( CheckAttribute(NewOfficer,"fight") ) 			DeleteAttribute(RefChar,"fight");
			if ( CheckAttribute(NewOfficer,"cabinfight") ) 		DeleteAttribute(RefChar,"cabinfight");
		}
		LAi_SetOfficerType(NewOfficer);
		if(bCreateOfficer)
		{
			switch(Rand(7))
			{
				case 0: NewOfficer.quest.officertype = OFFIC_TYPE_BOATSWAIN; break;
				case 1: NewOfficer.quest.officertype = OFFIC_TYPE_CANNONEER; break;
				case 2: NewOfficer.quest.officertype = OFFIC_TYPE_QMASTER; break;
				case 3: NewOfficer.quest.officertype = OFFIC_TYPE_NAVIGATOR; break;
				case 4: NewOfficer.quest.officertype = OFFIC_TYPE_FIRSTMATE; break;
				case 5: NewOfficer.quest.officertype = OFFIC_TYPE_CARPENTER; break;
				case 6: NewOfficer.quest.officertype = OFFIC_TYPE_DOCTOR; break;
				case 7: NewOfficer.quest.officertype = OFFIC_TYPE_ABORDAGE; break;
			}
			LAi_Create_Officer(rand(8), &NewOfficer);/*
			NewOfficer.offgen = true;
			NewOfficer.officer = true;
			LAi_Create_Officer(rand(1),NewOfficer);*/
		}
		else
		{
//			if (!CheckAttribute(PChar, "IsOnDeck") && !bAbordageStarted) NewOfficer.location = "None"; // KK
			//NewOfficer.location.group = "officers";// not needed
			NewOfficer.chr_ai.type = "officer";
			NewOfficer.offgen = true;
			NewOfficer.officer = true;
			NewOfficer.friend = true;
			NewOfficer.land = "0";
			if(CheckAttribute(NewOfficer,"wealth"))  			NewOfficer.wealth = makeint(NewOfficer.wealth);// clean up the ungainly float!
			if(CheckAttribute(NewOfficer,"quest.officertype"))	NewOfficer.current = NewOfficer.quest.officertype;
		}

		if (bAutoAssign)
		{
			// added by MAXIMUS [for placing new officer in empty slot (default for some officers)] -->
			int ofNum = 3;// default force into last slot
			if ( CheckAttribute(NewOfficer,"quest.officertype") ) {
				switch( NewOfficer.quest.officertype )
				{
					case OFFIC_TYPE_FIRSTMATE: ofNum = 1; break;
					case OFFIC_TYPE_BOATSWAIN: ofNum = 2; break;
					case OFFIC_TYPE_NAVIGATOR: ofNum = 3; break;
					//case OFFIC_TYPE_QMASTER:   ofNum = 1; break;
					//case OFFIC_TYPE_CANNONEER: ofNum = 2; break;
				}
			}
			SetOfficersIndex(PChar, ofNum, NewOfficerIdx);
			// added by MAXIMUS [for placing new officer in empty slot (default for some officers)] <--
		} else {
			//SetOfficersIndex(PChar, -1, NewOfficerIdx);// put them into an available slot if one exists (do not force it)
			AddPassenger(PChar,NewOfficer,false);// just add them as a passenger for now
//			AssignCaptiveAsCompanion(RefChar, NewOfficer);//MAXIMUS: not needed
		}

		// if they joined freely (no cost), they have a low salary ?
		if(!CheckAttribute(NewOfficer,"quest.officerprice"))
		{
			NewOfficer.quest.officerprice = makeint((sti(PChar.rank) * 2 + 10)*100) - 330 + rand(40)*15 + rand(10);
		}
		if(bLowSalary) NewOfficer.quest.officerprice = makeint( sti(NewOfficer.quest.officerprice) / 2 );

		if (!CheckCharacterEquipByGroup(NewOfficer, BLADE_ITEM_TYPE)) // KK
			LAi_NPC_Equip(NewOfficer, sti(PChar.rank), true, 0);// give the officer some weapons and equip them (NO GUN)

		// move any money they may have into their wealth, so MC can't steal their money
		if (CheckAttribute(NewOfficer,"money") && sti(NewOfficer.money) > 0)
		{
			if (!CheckAttribute(NewOfficer,"wealth")) { NewOfficer.wealth = 0; } // set if not set
			NewOfficer.wealth = makeint(sti(NewOfficer.wealth) + sti(NewOfficer.money)); // merge together into wealth
			NewOfficer.money = 0; // clear out their money now that its moved
		}

		// keep the NewOfficerIdx attribute, as its needed in the second function

		//trace("dialog_func.c -> officer dump at end:"); DumpAttributes( Characters[sti(PChar.quest.NewOfficerIdx)] );
		//trace("-----------------------------------------------------------------");
	}
	else
	{
		Log_SetStringToLog(QUEST_MESSAGE12);
	}
	DeleteAttribute(Pchar, "quest.HiringOfficerIDX");// deleted here, because we certainly no longer need it now
//	if (!CheckAttribute(PChar, "IsOnDeck") && bAbordageStarted) refEnCharacter = NewOfficer;
}

void TIH_OfficerHiredShow(bool bPlaceChar, bool bSameSpot, bool bStartDialog)
{
	ref PChar = GetMainCharacter();
	if ( CheckAttribute(PChar, "quest.NewOfficerIdx") ) {
		ref NewOfficer = GetCharacter(sti(PChar.quest.NewOfficerIdx));

	// TIH --> This section won't be activated from at-sea conditions yet.
	// Cabins and decks don't properly unload all characters when you leave them.
	// Thus hired captains or captives get 'left there' pretty much until you get to 
	// land and assign them as your officer. However if you had them assigned to a ship
	// you can't assign them as an officer, and then they will ALWAYS show up in cabins/decks.
	// So, until something is made for that, this section is not activated for now.
		if (bPlaceChar) {
			string locGroup;
			if (bAbordageStarted) 	locGroup = "rld";
			else 					locGroup = "goto";

			// prevents the officer from popping up somewhere else in the room when appearing
			// do not use bSameSpot for post quest officers (like officers sitting at a table!)
			if ( bSameSpot && CheckAttribute(NewOfficer,"location.locator") ) {
				LAi_SetStayTypeNoGroup(NewOfficer);
				ChangeCharacterAddressGroup(&NewOfficer, PChar.location, locGroup, NewOfficer.location.locator);
			} else {
				PlaceCharacter(NewOfficer, locGroup, PChar.location);
			}

			if (bStartDialog) DialogMain(NewOfficer);// they strike up a conversation with you

			BLI_UpdateOfficers();// for officers icons updates after new officer hire
		}
	// TIH <--

		DeleteAttribute(PChar, "quest.NewOfficerIdx");
	}
}
// TIH <--

string SelectSoldierModelbyLocationNation(string LocationID, string SoldierOrOfficer)
{
	// NK rewrite to use modeltypes 05-07-16

	ref PChar = GetMainCharacter();
	if(LocationID == "") LocationID = PChar.location;
	return SelectSoldierModelByNation(GetLocationNationFromID(LocationID), SoldierOrOfficer); // bugfix 05-07-19 GetLocationNation takes aref, not string.
	// NK <--
	
	/*string model, islandID;
	int jopa;


	//Pchar = GetMainCharacter();

	//jopa = GetLocationNation(&Locations[FindLocation(LocationID)]);

	jopa = GetCharacterCurrentIsland(Pchar);

//	if(jopa == -1) return "pirat1";

	IslandID = Islands[jopa].id;

		switch(IslandID)
		{

		case "FalaiseDeFleur":
			if(SoldierorOfficer == "officer") model = "offic_fra";
			if(SoldierorOfficer == "soldier") model = "soldier_fra" + (rand(4) + 2);
		break;

		case "Redmond":
			if(SoldierorOfficer == "officer") model = "offic_eng";
			if(SoldierorOfficer == "soldier") model = "soldier_eng" + (rand(4) + 2);
		break;

		case "Conceicao":
			if(SoldierorOfficer == "officer") model = "offic_por";
			if(SoldierorOfficer == "soldier") model = "soldier_por" + (rand(4) + 2);
		break;

		case "Oxbay":
			if(SoldierorOfficer == "officer") model = "offic_eng";
			if(SoldierorOfficer == "soldier") model = "soldier_eng" + (rand(4) + 2);
		break;

		case "IslaMuelle":
			if(SoldierorOfficer == "officer") model = "offic_spa";
			if(SoldierorOfficer == "soldier") model = "soldier_spa" + (rand(4) + 2);
		break;

		case "Douwesen":
			if(SoldierorOfficer == "officer") model = "offic_hol";
			if(SoldierorOfficer == "soldier") model = "soldier_hol" + (rand(4) + 2);
		break;

		case "QuebradasCostillas":
			if(SoldierorOfficer == "officer") model = "pirat1";
			if(SoldierorOfficer == "soldier") model = "pirat" + (rand(4) + 2);
		break;

		case "KhaelRoa":
			if(SoldierorOfficer == "officer") model = "mummy";
			if(SoldierorOfficer == "soldier") model = "mummy";
		break;
		}
	return model;*/

}
/*
int SelectRandomLandEncounter(aref CurLoc)
{
	int EncType;

	switch(CurLoc.EncType)
	{
		case "town":

			EncType = rand();

		break;

		case "jungle":

		break;

		case "shore":

		break;

		case "cave":

		break;
	}

}

void CreateJungleEncounters(int Type)
{
	switch(type)
	{


		case 1:
		break;
	}

}

void CreateTownEncounters(int Type)
{
}


void CreateShoreEncounters(int Type)
{
}


void CreateCaveEncounters(int Type)
{
}

*/
int getDeadManMoney()
{
	int money;

	money = Rand(10)*Rand(10)*10;

	return money;
}

string returnRandomDeadItem()
{
	return "potion";
}

//----------------------------- Недописанные функции, введенные для прописывания в диалоги ---------------------------


string TimeGreeting()
{
	// NK -->
	switch(GetDayTime())
	{
		case DAY_TIME_DAY: return XI_ConvertString("Good day"); break;
		case DAY_TIME_MORNING: return XI_ConvertString("Good morning"); break;
		case DAY_TIME_EVENING: return XI_ConvertString("Good evening"); break;
		case DAY_TIME_NIGHT: return XI_ConvertString("Good evening"); break;
	}
	// NK <--
	return XI_ConvertString("Good day");
}

//shorter way to check sex. Returns true if sex == "woman" (thus "man"/"skeleton"/whatever == 0 and "woman" == 1)
bool chrsex(ref chr)
{
	return chr.sex == "woman";
}

// address types:
#define ADDR_CIVIL		0
#define ADDR_TITLE		1	// this defaults to CIVIL if no title.
#define ADDR_IMPTITLE	2	// Impersonal Title. Either rank or sir/madam. Used for, e.g., "my dear sir/captain/baron". This returns rank if exist, or ADDR_POLITE if not.
#define ADDR_COURTING	3
#define ADDR_POLITE		4
#define ADDR_INFORMAL	5
#define ADDR_INSULT		6
#define ADDR_HOSTILE	7
#define ADDR_CHILD		8
#define ADDR_KIN		9
#define ADDR_GENDER	10
// KK -->
#define ADDR_CLERIC	11
// <-- KK
// you also use address_form.noun, which I assume to return man/lady?
// for now I've replaced it in Alan Milds with GENDER...

// the reason I'm using defines rather than strings is so we can do math with them.

#define MAX_ADDR_TYPES	12 // must be last above addr form + 1!

void Set_inDialog_Attributes()
{
	// 05-07-18
	// Hijack this to set addressforms[] array.
	int csize = MAX_NATIONS * MAX_ADDR_TYPES * 2;
	SetArraySize(&AddressForms, csize);
	for(int i = 0; i < csize; i++)
	{
		AddressForms[i] = "";
	}

	// note: If the specific nation version does not exist, it will default to the English version.

	// TODO NOTE: PUT THESE IN COMMON.INI AND USE CONVERTSTRING!
	// Although we shouldn't for the ADDR_CIVIL because they're already translated; and for those other address forms we make multinational.
	
	AddressForms[GetAddressIndex(ADDR_CIVIL, ENGLAND, 0)] = XI_ConvertString("Mister");	// should this and Miss be master and mistress? This makes
	AddressForms[GetAddressIndex(ADDR_CIVIL, ENGLAND, 1)] = XI_ConvertString("Miss");	// especial sense because often it's used with the player's _first_ name...
	AddressForms[GetAddressIndex(ADDR_CIVIL, FRANCE, 0)] = XI_ConvertString("Monsieur");
	AddressForms[GetAddressIndex(ADDR_CIVIL, FRANCE, 1)] = XI_ConvertString("Mademoiselle");
	AddressForms[GetAddressIndex(ADDR_CIVIL, SPAIN, 0)] = XI_ConvertString("Seсor");
	AddressForms[GetAddressIndex(ADDR_CIVIL, SPAIN, 1)] = XI_ConvertString("Seсorita");
	// pirate omitted.
	AddressForms[GetAddressIndex(ADDR_CIVIL, HOLLAND, 0)] = XI_ConvertString("Mijnheer");
	AddressForms[GetAddressIndex(ADDR_CIVIL, HOLLAND, 1)] = XI_ConvertString("Juffrouw");
	AddressForms[GetAddressIndex(ADDR_CIVIL, PORTUGAL, 0)] = XI_ConvertString("Senhor");
	AddressForms[GetAddressIndex(ADDR_CIVIL, PORTUGAL, 1)] = XI_ConvertString("Senhorita");
	
	AddressForms[GetAddressIndex(ADDR_COURTING, ENGLAND, 0)] = XI_ConvertString("m'lord");	//	Romancing, flattering or generally buttering up
	AddressForms[GetAddressIndex(ADDR_COURTING, ENGLAND, 1)] = XI_ConvertString("m'lady");
	
	
	AddressForms[GetAddressIndex(ADDR_POLITE, ENGLAND, 0)] = XI_ConvertString("sir");		//	Polite conversations (traders et cetera)
	AddressForms[GetAddressIndex(ADDR_POLITE, ENGLAND, 1)] = XI_ConvertString("ma'am");	// ma'am is then not a new contraction? Boy, learn something every day. :)
	// civil titles copied for polite for non-Eng
	AddressForms[GetAddressIndex(ADDR_POLITE, FRANCE, 0)] = XI_ConvertString("Monsieur");	
	AddressForms[GetAddressIndex(ADDR_POLITE, FRANCE, 1)] = XI_ConvertString("Mademoiselle");
	AddressForms[GetAddressIndex(ADDR_POLITE, SPAIN, 0)] = XI_ConvertString("Seсor");
	AddressForms[GetAddressIndex(ADDR_POLITE, SPAIN, 1)] = XI_ConvertString("Seсorita");
	AddressForms[GetAddressIndex(ADDR_POLITE, HOLLAND, 0)] = XI_ConvertString("Mijnheer");
	AddressForms[GetAddressIndex(ADDR_POLITE, HOLLAND, 1)] = XI_ConvertString("Juffrouw");
	AddressForms[GetAddressIndex(ADDR_POLITE, PORTUGAL, 0)] = XI_ConvertString("Senhor");
	AddressForms[GetAddressIndex(ADDR_POLITE, PORTUGAL, 1)] = XI_ConvertString("Senhorita");
	
	AddressForms[GetAddressIndex(ADDR_INFORMAL, ENGLAND, 0)] = XI_ConvertString("lad");	//	Friendly references (matey's and friends)
	AddressForms[GetAddressIndex(ADDR_INFORMAL, ENGLAND, 1)] = XI_ConvertString("lass");
	
	AddressForms[GetAddressIndex(ADDR_INSULT, ENGLAND, 0)] = XI_ConvertString("sirrah");	//	Patronising reference (marriage duel et cetera)
	AddressForms[GetAddressIndex(ADDR_INSULT, ENGLAND, 1)] = XI_ConvertString("wench");
	
	AddressForms[GetAddressIndex(ADDR_HOSTILE, ENGLAND, 0)] = XI_ConvertString("bastard");	//	Insulting references (congratulations, you got an enemy)
	AddressForms[GetAddressIndex(ADDR_HOSTILE, ENGLAND, 1)] = XI_ConvertString("trollop");
	
	AddressForms[GetAddressIndex(ADDR_CHILD, ENGLAND, 0)] = XI_ConvertString("son");		//	Governors' daughters and what you are to the church
	AddressForms[GetAddressIndex(ADDR_CHILD, ENGLAND, 1)] = XI_ConvertString("daughter");
	
	AddressForms[GetAddressIndex(ADDR_KIN, ENGLAND, 0)] = XI_ConvertString("nephew");		//	Governors' nieces
	AddressForms[GetAddressIndex(ADDR_KIN, ENGLAND, 1)] = XI_ConvertString("niece");
	
	AddressForms[GetAddressIndex(ADDR_GENDER, ENGLAND, 0)] = XI_ConvertString("man"); 	//	Gendered noun ("My good woman" et cetera)
	AddressForms[GetAddressIndex(ADDR_GENDER, ENGLAND, 1)] = XI_ConvertString("woman");	//

// KK -->
	AddressForms[GetAddressIndex(ADDR_CLERIC, ENGLAND, 0)] = XI_ConvertString("son"); 	//	Priests saying to men
	AddressForms[GetAddressIndex(ADDR_CLERIC, ENGLAND, 1)] = XI_ConvertString("daughter");	// How PRIESTS was treating women????
// <-- KK
}



// NK address wrapper function 05-06-28
// will return the address form addrtype used by chr on pchr, with optionally first (if fname is true) and/or last (if lname is true) names appended.
// will automatically handle nations based on chr.nation
// maybe later we can add checking for chr's wealth level and pass addrtype == -1 to automate things.
// if both fname and lname are true, add middle name as well to string if it exists (we don't need a third bool that way).
// updated 05-07-18
string GetMyAddressForm(ref chr, ref pchr, int addrtype, bool fname, bool lname)
{
	string retstr;
	int nat = sti(chr.nation);
	int fakeNat = nat;//MAXIMUS: -[05.10.2007]->
	if(CheckAttribute(chr,"nation.name"))
	{
		if(nat==PIRATE || nat!=sti(chr.nation.name)) fakeNat = sti(chr.nation.name);//MAXIMUS: pirates can have a different own-nation <-[05.10.2007]-
	}
	bool bsex = chrsex(pchr);
	switch(addrtype)
	{
		case ADDR_TITLE:	retstr = stringret(GetRank(&pchr, nat) > 0, XI_ConvertString(GetRankName(&pchr, nat)), GetAddressForm(ADDR_TITLE, fakeNat, bsex)); break;// MAXIMUS 16.10.2006
		case ADDR_IMPTITLE:	retstr = stringret(GetRank(&pchr, nat) > 0, XI_ConvertString(GetRankName(&pchr, nat)), GetAddressForm(ADDR_IMPTITLE, fakeNat, bsex)); break;// MAXIMUS 16.10.2006
		/*default:*/			retstr = GetAddressForm(addrtype, fakeNat, bsex);
	}
	if(fname) retstr += " " + GetMyName(pchr);
	if(lname && lname && CheckAttribute(pchr, "middlename")) retstr += " " + pchr.middlename;
	if(lname) retstr += " " + pchr.lastname;
	return retstr;
}

// Swindler 05-09-25 -->
/**
 * Returns the address form of character <chr>. It takes into account the
 * the nationality of the character. It works very similar to
 * GetMyAddressForm().
 */
string GetCharacterAddressForm(ref chr, int addrtype, bool fname, bool lname)
{
	string retstr;
	int nat = sti(chr.nation);
	int fakeNat = nat;//MAXIMUS: -[05.10.2007]->
	if(CheckAttribute(chr,"nation.name"))
	{
		if(nat==PIRATE || nat!=sti(chr.nation.name)) fakeNat = sti(chr.nation.name);//MAXIMUS: pirates can have a different own-nation <-[05.10.2007]-
	}
	bool bsex = chrsex(chr);
	switch(addrtype)
	{
		case ADDR_TITLE:
			retstr = stringret(GetRank(&chr, nat) > 0, XI_ConvertString(GetRankName(&chr, nat)), GetAddressForm(ADDR_TITLE, fakeNat, bsex));// MAXIMUS 16.10.2006 [changed 05.10.2007]
		break;
		case ADDR_IMPTITLE:
			retstr = stringret(GetRank(&chr, nat) > 0, XI_ConvertString(GetRankName(&chr, nat)), GetAddressForm(ADDR_IMPTITLE, fakeNat, bsex));// MAXIMUS 16.10.2006 [changed 05.10.2007]
		break;
		//default:
		retstr = GetAddressForm(addrtype, fakeNat, bsex);//MAXIMUS: 05.10.2007
	}
	
	if(fname)
		retstr += " " + chr.name;
	if(lname && lname && CheckAttribute(chr, "middlename"))
		retstr += " " + chr.middlename;
	if(lname)
		retstr += " " + chr.lastname;
	return retstr;	
}
/**
 * Retunrns the officers address form as used e.g in the tailor's mod. But
 * it also takes into account the the nationality of the officer.
 */
string GetOfficerAddressForm(ref officer)
{
	return GetCharacterAddressForm(&officer, ADDR_CIVIL, true, true);
}	 
// Swindler <--

// gets the addressform of specified type of nation nat and for sex == "woman"
string GetAddressForm(int type, int nat, bool bsex)
{
	int idx = GetAddressIndex(type, nat, bsex);
	string retstr = AddressForms[idx];
	if(AddressForms[idx] != "" || nat == ENGLAND) return retstr; // for now check ENGLAND if blank
	return GetAddressForm(type, ENGLAND, bsex);
}

// gets the index of the address form. See above.
int GetAddressIndex(int type, int nat, bool bsex)
{
	// convert some address forms into their base types.
	// assume the only time we call TITLE and IMPTITTLE is if GetMyAddressForm() calls this; and the only time it would do that is
	// if the rank doesn't exist, so we go back to to CIVIL (for title) and POLITE (for imp. title)
	switch(type)
	{
		case ADDR_TITLE: type = ADDR_CIVIL; break;
		case ADDR_IMPTITLE: type = ADDR_POLITE; break;
	}
	return type * (MAX_NATIONS * 2) + nat*2 + bsex;
}

//RM put in dialog_func.c -->
//gets address form based on chr's nation
// 05-07-19 please DON'T use this!!!!
// use a GetMyAddressForm call above.
string GetMyNationAddress(ref chr, ref pchr)
{
	// PUT THESE IN COMMON.INI AND USE CONVERTSTRING!!!
	// rewritten 05-06-28 by NK
	string nataddr[MAX_NATIONS];
	
	if(pchr.sex == "woman")
	{
		nataddr[SPAIN] = XI_ConvertString("Seсorita");			//spell-checked by KAM
		nataddr[FRANCE] = XI_ConvertString("Mademoiselle");
		nataddr[ENGLAND] = XI_ConvertString("Miss");
		nataddr[PORTUGAL] = XI_ConvertString("Senhorita");
		nataddr[HOLLAND] = XI_ConvertString("Juffrouw");
	}
	nataddr[SPAIN] = XI_ConvertString("Seсor");			//spell-checked by KAM
	nataddr[FRANCE] = XI_ConvertString("Monsieur");
	nataddr[ENGLAND] = XI_ConvertString("Mister"); // NK
	nataddr[PORTUGAL] = XI_ConvertString("Senhor");
	nataddr[HOLLAND] = XI_ConvertString("Mijnheer");

	nataddr[PIRATE] = nataddr[ENGLAND]; // argh. Oh well.

	if(CheckAttribute(chr,"nation.name") && sti(chr.nation.name)!=1) return nataddr[sti(chr.nation.name)];
	if(!CheckAttribute(chr,"nation")) return nataddr[ENGLAND];
	return nataddr[sti(chr.nation)];
}

// NAMES
//get chr's full name: Mister Nathaniel Hawk (or Baron Nathaniel Hawk)
// For more advanced things, use GetMyAddressForm() above...
string GetMyFullName(ref chr)
{
	string name = "";
	if(!CheckAttribute(chr,"name")) chr.name = name;//MAXIMUS -->
	if(!CheckAttribute(chr,"lastname")) chr.lastname = name;
	if(CheckAttribute(chr,"title"))
	{
		if(XI_ConvertString(chr.title)!="") chr.title = XI_ConvertString(chr.title);
		name = chr.title + " ";
	}//MAXIMUS <--
	if(CheckAttribute(chr,"firstname")) { name += chr.firstname; }
	else { name += chr.name; }
	if(CheckAttribute(chr,"middlename")) { name += " " + chr.middlename; }
	name += " " + chr.lastname;
	return name;
}
//get chr's simple name: Nathaniel Hawk or Christofor Manuel De Alencar
string GetMySimpleName(ref chr)
{
	string name = "";
	if(!CheckAttribute(chr,"name")) chr.name = name;//MAXIMUS
	if(!CheckAttribute(chr,"lastname")) chr.lastname = name;//MAXIMUS
	if(CheckAttribute(chr,"firstname"))
	{
		if(CheckAttribute(chr,"middlename")) { name += chr.middlename; }
		else { name += chr.firstname; }
	}
	else
	{
		name += chr.name;
		if(CheckAttribute(chr,"middlename")) { name += " " + chr.middlename; }
	}
	name += " " + chr.lastname;
	return name;
}

//get chr's first name; for "default" name (i.e. first if no title) just get chr.name.
string GetMyName(ref chr)
{
	string name = "";
	if(CheckAttribute(chr,"firstname")) { name += chr.firstname; }
	else { name += chr.name; }
	return name;
}

//get character's family name with a title, if he has one of them
string GetMyRespectfullyName(ref chr)
{
	if(!CheckAttribute(chr,"lastname")) chr.lastname = "";
	string name = "";
	if(CheckAttribute(chr,"title"))
	{
		string ourTitle = chr.title;
		if(XI_ConvertString(chr.title)!="") ourTitle = XI_ConvertString(chr.title);
		if(chr.lastname=="") name += ourTitle;
		else name += ourTitle + " " + chr.lastname;
	}
	else
	{
		if(CheckAttribute(chr,"Ship.type") && chr.Ship.type!="" && chr.Ship.type!=SHIP_NOTUSED)
		{
			if(chr.lastname=="") name += XI_ConvertString("Scaptain");
			else name += XI_ConvertString("Scaptain") + " " + chr.lastname;
		}
		else name += chr.lastname;
	}
	return name;
}


//translates #defined married state into string
string GetMarriedName(ref chr)
{
	if(CheckAttribute(chr,"married"))
	{
		switch(sti(chr.married))
		{
			case MR_MARRIED: return XI_ConvertString("wife"); break;
			case MR_MISTRESS: return XI_ConvertString("mistress"); break;
		}
	}
	return XI_ConvertString("friend");
}

// HSL 05-06-23 -->
string GetMyPronounSubj(ref chr)
{
	if(chr.sex == "woman")
	{
		return "she";
	}
	return "he";
}

string GetMyPronounObj(ref chr)
{
	if(chr.sex == "woman")
	{
		return "her";
	}
	return "him";
}


string GetMyPronounPoss(ref chr)
{
	if(chr.sex == "woman")
	{
		return "hers";
	}
	return "his";
}

string GetMyPronoun(ref chr, string model)
{
	switch(model)
	{
		case "he": return XI_ConvertString(GetMyPronounSubj(&chr)); break;
		case "she": return XI_ConvertString(GetMyPronounSubj(&chr)); break;
		
		case "him": return XI_ConvertString(GetMyPronounObj(&chr)); break;
		case "her": return XI_ConvertString(GetMyPronounObj(&chr)); break;
		
		case "his": return XI_ConvertString(GetMyPronounPoss(&chr)); break;
		case "hers": return XI_ConvertString(GetMyPronounPoss(&chr)); break;
	}
	return XI_ConvertString(GetMyPronounObj(&chr));
}
// HSL <--

//returns name of model to use for MR
string FindMRModel(int rank)
{
	//rank = 10; //testing
	string modelch[2];
	int i;
	int size = 2;
	if(rank<3) return "towngirl2";
	modelch[0] = "towngirl2";
	modelch[1] = "towngirl2-1";
	if(rank>=3)
	{
		for(i = 0; i < 5; i++) //actually +1 because above
		{
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "towngirl2";
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "towngirl2-1";
		}
	}
	if(rank>=4)
	{
		for(i = 0; i < 9; i++)
		{
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "towngirl5";
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "towngirl6";
		}
	}
	if(rank>=5)
	{
		for(i = 0; i < 11; i++)
		{
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "towngirl3";
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "towngirl3-1";
		}
	}
	if(rank>=6)
	{
		for(i = 0; i < 15; i++)
		{
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "towngirl1";
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "towngirl1-1";
		}
	}
	if(rank>=7)
	{
		for(i = 0; i < 35; i++)
		{
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "towngirl7";
		}
	}
	if(rank>=7)
	{
		for(i = 0; i < 39; i++)
		{
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "towngirl4";
		}
	}
	if(rank>=8)
	{
		for(i = 0; i < 44; i++)
		{
			size++;
			SetArraySize(&modelch,size);
			modelch[size-1] = "liz1"; // KK
		}
	}
	return modelch[rand(size-1)];
}


//finds index of free MR
int FindFreeMR()
{
	int Counter, MRIdx;
	ref PChar;
	
	PChar = GetMainCharacter();
	if(sti(PChar.married)) return -1;
	string MRId;

	int i;

	for(counter = 0; counter <10; counter++)
	{
		MRId = "GovRel" + counter;
		MRIdx = GetCharacterIndex(MRId);		
		if(sti(Characters[MRIdx].talkpoints) == 0 && sti(Characters[MRIdx].married) == MR_SINGLE) return MRIdx;
	}

	return -1;
}

//clears locations of all unused MRs, run after meeting MR and /not/ talking with her.
void ClearMRLocations()
{
	ref PChar = GetMainCharacter();
	int Counter, MRIdx;
	string MRId;
	ref mr;
	ref gov;
	int i, qty;

	for(counter = 0; counter <10; counter++)
	{
		MRId = "GovRel" + counter;
		MRIdx = GetCharacterIndex(MRId);
		mr = GetCharacter(MRIdx);
		if((mr.married) == MR_SINGLE)
		{
			if(sti(mr.talkpoints) == 0 || sti(PChar.married))
			{
				mr.location = "none";
				if(CheckAttribute(mr,"father"))
				{
					gov = GetCharacter(GetCharacterIndex(mr.father));
					if(CheckAttribute(gov,"MRs."+MRId))
					{
						aref mrs;
						makearef(mrs, gov.MRs);
						DeleteAttribute(gov,"MRs."+MRId);
						if(GetAttributesNum(mrs))
						{
							gov.currentMR = GetAttributeName(GetAttributeN(mrs,rand(GetAttributesNum(mrs)-1)));
						}
						else {DeleteAttribute(gov,"currentMR"); }
					}
					DeleteAttribute(mr,"father");
				}
			}
		}
	}
}

//sets gov's current MR to given MR
void SetCurrentMR(ref mr)
{
	ref gov = CharacterFromID(mr.father);
	gov.currentMR = mr.id;
}

//sets up first free MR and teleports to pchar.location
bool SetupMR(ref pchar, ref govchar)
{
	if(CheckAttribute(govchar,"currentMR.relationtype")) return false;//MAXIMUS: prevents from doubled MRs in location
	int mridx = FindFreeMR();
	if(mridx == -1) return false;
	ref mr = GetCharacter(mridx);
	mr.quest.officertype = OFFIC_TYPE_CIVILIAN;
	int offset = sti(pchar.rank);
	if(offset >= 12) offset = -10;
	else offset = 0 - offset/2;
	LAi_Create_Officer(offset, mr);
	
	string MRID = mr.id;
	int nation = sti(govchar.nation);
	if(GetRank(pchar, nation) < 3) return false;
	if(!DEBUG && frnd() > MR_INTRODUCE_CHANCE + sqrt(GetFame(pchar,nation))*MR_INTR_CH_RANK_SCL) return false;
	if(!DEBUG && "" + environment.date.day + " " + environment.date.month == govchar.quest.Meeting) return false;
	int MRs = 0;
	aref govmrs;
	makearef(govmrs, govchar.MRs);
	MRs = GetAttributesNum(govmrs);
	if(MRs > MR_MAXNUM) return false;
	MRs++;
	govchar.MRs.(MRID) = true;

	mr.nation = nation;
	SetRandomNameToCharacter(mr);
	mr.lastname = govchar.lastname;
	mr.father = govchar.id;
	
	govchar.currentMR = MRID;
	mr.marpoints = MRCalcMarpoints(&pchar, nation);
	if(DEBUGINFO) Log_SetStringToLog("MP: " + mr.marpoints + ", " + stf(mr.marpoints)/GetFame(pchar, nation) + "x fame");
	if(frnd() < sti(mr.marpoints)/MR_DAUGHTER_THRESH) mr.relationtype = "daughter";
	else mr.relationtype = "niece";
	govchar.currentMR.relationtype = mr.relationtype;
	mr.model = FindMRModel(GetRank(pchar,nation));
	facemaker(mr);
	mr.talkpoints = 0;
	mr.dialog.currentnode = "First Time";
	mr.pcounter = 0;
	mr.married = 0;
	if(mr.location == pchar.location) // if debugging above
	{
		SendMessage(mr, "lss", MSG_CHARACTER_SETMODEL, mr.model, mr.model.animation);
	}
	PlaceCharacter(&mr, "goto", pchar.location);
	return true;
}

//returns string saying gov's nation's status vs. other nations
/*string GovNationStatus(ref char, ref gov)
{
	int iNation = sti(gov.nation);
	int warnat[1];
	int alliednat[1];
	int wsize = 0;
	int asize = 0;
	int i;
	string retstr = "";
	if(GetRMRelationWithGov(char, gov >= 0) retstr += "My dear "
	retstr += char.title +", we are currently ";

	//get enemies
	for(i = 0; i < MAX_NATIONS; i++)
	{
		if(GetNationRelation(iNation, i) == RELATION_ENEMY && iNation != i)
		{
			wsize++;
			SetArraySize(&warnat, wsize);
			warnat[wsize-1] = i;
		}
	}
	//get allies
	for(i = 0; i < MAX_NATIONS; i++)
	{
		if(GetNationRelation(iNation, i) == RELATION_FRIEND && iNation != i)
		{
			asize++;
			SetArraySize(&alliednat, asize);
			alliednat[asize-1] = i;
		}
	}

	//output allies
	if(asize)
	{
		retstr += "allied with ";
		for(i =0; i < asize; i++)
		{
			if(i == asize-1 && i) retstr += "and ";
			retstr += "the " + GetNationDescByType(alliednat[i]);
			if(i < asize-1) retstr +=", ";
		}
	}
	//output enemies
	if(wsize)
	{
		if(asize) retstr += ", and are ";
		retstr += "at war with ";
		for(i =0; i < asize; i++)
		{
			if(i == asize-1 && i) retstr += "and ";
			retstr += "the " + GetNationDescByType(warnat[i]);
			if(i < asize-1) retstr +=", ";
		}
	}
	retstr += ".";
	if(wsize && GetRMRelationWithGov(char, gov >= 0) retstr += " I charge you to seek out and destroy our enemies' ships and towns!";
	return retstr;
}*/
// RM <--

// NK -->
//return captain type based on fantomtype
string CaptainTypeFromFantomType(string ftype)
{
	switch(ftype)
	{
		case "pirate": return OFFIC_TYPE_CAPPIRATE; break;
		case "trade": return OFFIC_TYPE_CAPMERCHANT; break;
		case "war": return OFFIC_TYPE_CAPNAVY; break;
	}
	return OFFIC_TYPE_CAPNAVY;
}
// NK <--

void SetCoastalEnemy(string model, string sex, string name, string lastname)
{
	ref Pchar, CurIsland, rCap1, rCap2, rCap3;
	// NK -->
	float mult = 1.0;
	string sFantomType = "war";
	ref Shiptype;
	aref arship;
	int CGNation;
	CGNation = GetCurrentLocationNation();
	// NK <--
	Pchar = GetMainCharacter();
	rCap1 = CharacterFromID("Coastal_Captain01");
	rCap2 = CharacterFromID("Coastal_Captain02");
	trace("Индекс текущего острова " + GetCharacterCurrentIsland(Pchar));
	CurIsland = GetIslandByIndex(GetCharacterCurrentIsland(Pchar));
	trace("Текущий остров: " + CurIsland.id);
	trace("Текущая нация острова: " + CGNation);

	//Простановка параметров капитанам береговой стражи
	LAi_SetHP(rCap1, 120, 120);
	rCap1.nation =  CGNation;
	Trace("НАЦИЯ КАПИТАНА" + rCap1.nation);
	SetRandomNameToCharacter(rCap1);
	rCap1.rank = makeint(Pchar.rank) - 2 + Rand(4);
	rCap1.experience = CalculateExperienceFromRank(sti(rCap1.rank));
	if(model=="")
	{
		SelectSoldierModelByNation(CGNation, "Officer");
		rCap1.sex = "man";
		rCap1.ani ="man";
	}
	else
	{
		rCap1.model = model;
		rCap1.name 	= name;
		rCap1.lastname = lastname;
		if(sex=="woman")
		{
			rCap1.sex = sex;
			rCap1.ani ="woman";
		}
		
	}
	//rCap1.Headmodel = "h_" + rCap1.model;
	Facemaker(rCap1);

	//CalculateAppropriateSkills(rCap1); // NK

	SelectCoastalGuardShip(rCap1);

	SetBaseShipData(rCap1);
	// NK -->
	rCap1.shiptype = rCap1.ship.type;
	rCap1.FantomType = sFantomType;
	mult = 1.25;
	Shiptype = GetShipByType(GetCharacterShipType(rCap1));
	makearef(arship, rCap1.ship); // PRS3
	rCap1.Points = mult * stf(GetLocalShipAttrib(arship, Shiptype, "Weight")) / 5000; // PRS3
	rCap1.quest.officertype = OFFIC_TYPE_CAPNAVY;
	Fantom_SetRandomMoney(rCap1, sFantomType);
	Fantom_SetCannons(rCap1, sFantomType);
	Fantom_SetSails(rCap1, sFantomType);
	Fantom_ClearCargo(rCap1); // TIH clear out prior slot cargo
	Fantom_SetBalls(rCap1, sFantomType);
	Fantom_SetGoods(rCap1, sFantomType);
	Ship_SetFantomData(rCap1);
	LAi_Create_Officer(0, rCap1);
	LAi_NPC_Equip(rCap1, sti(rCap1.rank), true, 1.0);
	SetRandomNameToShip(rCap1);
	// NK <--

	Group_CreateGroup("Coastal_Guards");
	Group_addCharacter("Coastal_Guards", "Coastal_Captain01");
	Group_SetGroupCommander("Coastal_Guards", "Coastal_Captain01");

	if(GetCompanionQuantity(Pchar) > 1 || makeint(Pchar.rank) > 50)
	{
		LAi_SetHP(rCap2, 120, 120);
		rCap2.nation =  CGNation;
		SetRandomNameToCharacter(rCap2);
		rCap2.rank = makeint(Pchar.rank) - 2 + Rand(4);
		rCap2.experience = CalculateExperienceFromRank(sti(rCap2.rank));
		rCap2.model = SelectSoldierModelByNation(CGNation, "Officer");
		//rCap2.Headmodel = "h_" + rCap2.model;
		Facemaker(rCap2);

		//CalculateAppropriateSkills(rCap2); // NK

		SelectCoastalGuardShip(rCap2);

		SetBaseShipData(rCap2);
		// NK -->
		rCap2.shiptype = rCap2.ship.type;
		rCap2.FantomType = sFantomType;
		mult = 1.25;
		Shiptype = GetShipByType(GetCharacterShipType(rCap2));
		makearef(arship, rCap2.ship); // PRS3
		rCap2.Points = mult * stf(GetLocalShipAttrib(arship, Shiptype, "Weight")) / 5000; // PRS3
		rCap2.quest.officertype = OFFIC_TYPE_CAPNAVY;
		Fantom_SetRandomMoney(rCap2, sFantomType);
		Fantom_SetCannons(rCap2, sFantomType);
		Fantom_SetSails(rCap2, sFantomType);
		Fantom_ClearCargo(rCap2); // TIH clear out prior slot cargo
		Fantom_SetBalls(rCap2, sFantomType);
		Fantom_SetGoods(rCap2, sFantomType);
		Ship_SetFantomData(rCap2);
		LAi_Create_Officer(0, rCap2);
		LAi_NPC_Equip(rCap2, sti(rCap2.rank), true, 1.0);
		SetRandomNameToShip(rCap1);
		// NK <--

		Group_addCharacter("Coastal_Guards", "Coastal_Captain02");

	}

	Trace("FUNCTION SetCoastalGuardPursuit Reports: Current PLayer Island is: " + Islands[GetCharacterCurrentIsland(Pchar)].id);

	Group_SetPursuitGroup("Coastal_Guards", PLAYER_GROUP);
	Group_SetAddress("Coastal_Guards", Islands[GetCharacterCurrentIsland(Pchar)].id, "", "");
	SetCharacterRelationBoth(GetCharacterIndex("Coastal_Captain01"),GetMainCharacterIndex(),RELATION_ENEMY);
	Group_SetTaskAttack("Coastal_Guards", PLAYER_GROUP);
	Group_LockTask("Coastal_Guards");
}

// KK -->
//MAXIMUS: changes, which was made here:
//Only Enc_Officer can be hired now. If we haven't free Enc_Officer - NPC will reject our suggestion
//NPC will stay in location, until we'll not leave this location
void TIH_PrisonerHiredAsOfficerProcess(ref RefChar, bool bLowSalary, bool bSetType, bool bCreateOfficer)
{
	if(FindFreeRandomOfficer()==-1) { RefChar.Dialog.CurrentNode = "officer"; DialogMain(RefChar); return; }
	ref PChar = GetMainCharacter();
	int freeidx = FindFreeRandomOfficer();

	RemovePassenger(PChar, RefChar);

	if (CheckAttribute(RefChar, "prisoned")) DeleteAttribute(RefChar, "prisoned");
	if (CheckAttribute(RefChar, "status")) DeleteAttribute(RefChar, "status");
	if (CheckAttribute(RefChar, "ransom")) DeleteAttribute(RefChar, "ransom");
	if (CheckAttribute(RefChar, "released")) DeleteAttribute(RefChar, "released");
	if (CheckAttribute(RefChar, "position")) DeleteAttribute(RefChar, "position");
	if (CheckAttribute(RefChar, "fight")) DeleteAttribute(RefChar, "fight");
	if (CheckAttribute(RefChar, "cabinfight")) DeleteAttribute(RefChar, "cabinfight");

	// these do fixing
	if(RefChar.sex=="woman") RefChar.greeting = "Gr_Officer_f common";
	else RefChar.greeting = "Gr_Officer_m common";
	RefChar.Dialog.Filename = "Enc_Officer_dialog.c";
	RefChar.Dialog.CurrentNode = "Hired";

	Pchar.quest.HiringOfficerIDX = RefChar.index;
	Pchar.quest.FreeRandomOfficerIdx = Characters[freeidx].index;
	Pchar.quest.FreeRandomOfficerID = Characters[makeint(Pchar.quest.FreeRandomOfficerIdx)].id;

	trace("Free Random Officer IDX is " + Pchar.quest.FreeRandomOfficerIdx + " and he has id  " + Pchar.quest.FreeRandomOfficerID);

	CopyAttributes(&Characters[makeint(Pchar.quest.FreeRandomOfficerIdx)], &Characters[makeint(Pchar.quest.HiringOfficerIDX)]);

	Characters[makeint(Pchar.quest.FreeRandomOfficerIdx)].index = Pchar.quest.FreeRandomOfficerIdx;
	Characters[makeint(Pchar.quest.FreeRandomOfficerIdx)].id = Pchar.quest.FreeRandomOfficerID;
	Characters[makeint(Pchar.quest.FreeRandomOfficerIdx)].location = "None";
	Characters[makeint(Pchar.quest.FreeRandomOfficerIdx)].Dialog.Filename = "Enc_Officer_dialog.c";
	Characters[makeint(Pchar.quest.FreeRandomOfficerIdx)].Dialog.CurrentNode = "hired";
	Characters[makeint(Pchar.quest.FreeRandomOfficerIdx)].AbordageMode = makeint(1);
	ref NewOfficer = &Characters[makeint(Pchar.quest.FreeRandomOfficerIdx)];
	DeleteAttribute(Pchar, "quest.FreeRandomOfficerIdx");
	DeleteAttribute(Pchar, "quest.FreeRandomOfficerID");
	DeleteAttribute(Pchar, "quest.HiringOfficerIDX");

//	RefChar.AbordageMode = 1;// boal 05.09.03 officer set to go to abordage

//	if (!CheckAttribute(RefChar, "model.entity")) 	RefChar.model.entity = "NPCharacter";// ? sometimes was an error - "can't create class"
//	if (!CheckAttribute(RefChar, "noFollowType")) 	RefChar.noFollowType = "nofollow";// ? new identifier for template LAi_follow.c
	if (!CheckAttribute(NewOfficer, "money")) NewOfficer.money = makeint(0);// ? was a bug with not existent money

	NewOfficer.chr_ai.type = "officer";
	if(bSetType) LAi_SetOfficerType(NewOfficer);
	NewOfficer.offgen = true;
	NewOfficer.officer = true;
	NewOfficer.friend = true;
	NewOfficer.land = "0";
	NewOfficer.nation = PChar.nation;
	NewOfficer.nation.name = RefChar.nation;
	NewOfficer.location = "none";
	if ( CheckAttribute(NewOfficer,"wealth") )  			NewOfficer.wealth = makeint(NewOfficer.wealth);// clean up the ungainly float!
	if ( CheckAttribute(NewOfficer,"quest.officertype") )	NewOfficer.current = NewOfficer.quest.officertype;

	// if they joined freely (no cost), they have a low salary ?
	if ( CheckAttribute(NewOfficer,"quest.officerprice") ) {
		if (bLowSalary) NewOfficer.quest.officerprice = makeint( sti(NewOfficer.quest.officerprice) / 2 );
	}

	if (!CheckCharacterEquipByGroup(NewOfficer, BLADE_ITEM_TYPE)) // KK
		LAi_NPC_Equip(NewOfficer, sti(NewOfficer.rank), true, 0);// give the officer some weapons and equip them (NO GUN)

	// move any money they may have into their wealth, so MC can't steal their money
	if (CheckAttribute(NewOfficer,"money") && sti(NewOfficer.money) > 0)
	{
		if (!CheckAttribute(NewOfficer,"wealth")) { NewOfficer.wealth = 0; } // set if not set
		NewOfficer.wealth = makeint(sti(NewOfficer.wealth) + sti(NewOfficer.money)); // merge together into wealth
		NewOfficer.money = 0; // clear out their money now that its moved
	}
	NewOfficer.old.chr_ai.group = "player";
	NewOfficer.chr_ai.group = "player";

	LAi_group_MoveCharacter(NewOfficer, LAI_GROUP_PLAYER);
	LAi_group_MoveCharacter(RefChar, LAI_GROUP_PLAYER);
	RefChar.location = "none";
	RefChar.friend = true;
	if(bSetType) LAi_SetOfficerType(RefChar);

	AddPassenger(PChar,NewOfficer,false);// just add them as a passenger for now
}
//MAXIMUS: changes, which was made here:
//All code for prisoner was moved from Cabinfight_dialog.c
//FindFreeRandomOfficer changed to FindFreeCabinCaptain, because we not need to create an officer on this stage
//Also added check for Enc_CabinCaptain - not need to make him twice
//Also added small action (if we haven't free Enc_CabinCaptain): angry NPC will attack player
void TIH_PrisonerTakenProcess(ref RefChar, bool bPurgeCrud)
{
	ref PChar = GetMainCharacter();
	ref Prisoner = &NullCharacter();
	int PrisonerIdx;
	string PrisonerID;
	//int tmpLangFileID = LanguageOpenFile("interface_strings.txt");
	if(CORPSEMODE==4)
	{
		if(!CheckAttribute(RefChar,"money")) RefChar.money = "0";
		if(!CheckAttribute(RefChar,"wealth")) RefChar.wealth = "0";
		RefChar.money = sti(RefChar.money) + sti(RefChar.wealth);
		RefChar.wealth = "0";
	}

	//PChar.quest.HiringOfficerIDX = GetCharacterIndex(RefChar.id);

	int freeidx = sti(RefChar.index);
	if(!HasSubStr(RefChar.id,"Enc_CabinCaptain")) freeidx = FindFreeCabinCaptain();// get an open officer slot to use (50 maximum)
	if(freeidx != -1)
	{
		//trace("-----------------------------------------------------------------");
		//trace("dialog_func.c:");

		// cleaner method
		PrisonerIdx		= sti(Characters[freeidx].index);
		Prisoner		= GetCharacter(PrisonerIdx);
		PrisonerID		= Prisoner.id;// store this because we have to put it back after the copyattr

		//PChar.quest.PrisonerIdx = PrisonerIdx;// store for second function

		//	trace("Hiring Officer IDX is " + PChar.quest.HiringOfficerIDX + " and he has id  " + Characters[sti(PChar.quest.HiringOfficerIDX)].id);
		//	trace("Free Random Officer IDX is " + PrisonerIdx + " and he has id  " + PrisonerID);

		if(!HasSubStr(RefChar.id,"Enc_CabinCaptain"))
		{
			CopyAttributes(&Prisoner, &RefChar);// copy all attr from the reference character (the hiring officer) to the new officer char

			Prisoner.index = PrisonerIdx;// reset these after the copyattr
			Prisoner.id    = PrisonerID; // reset these after the copyattr
		}

		DisarmCharacter(Prisoner, true, false);

		PlayStereoSound("INTERFACE\took_item.wav");
		AddMoneyToCharacter(PChar,sti(Prisoner.money));
		Log_SetStringToLog(TranslateString("","CaptainMoney1")+" "+MakeMoneyShow(sti(Prisoner.money),"",MONEY_DELIVER)+" "+TranslateString("","CaptainMoney2"));
		if(Prisoner.sex=="woman") Prisoner.greeting = "Gr_Pirate_f";
		else Prisoner.greeting = "Gr_Dark Teacher";
		boarding_enemy.status = "dead";
		boarding_enemy.position = "captive";
		PlayStereoSound("AMBIENT\JAIL\jail_door2.wav");

		//trace("New Officer IDX is " + Prisoner.index + " and he has id  " + Prisoner.id);
		//trace("dialog_func.c - > officer dump before cleaning:"); DumpAttributes( Characters[sti(PChar.quest.PrisonerIdx)] );

		// these do fixing
		/*if(Prisoner.sex == "woman") 	Prisoner.greeting = "Gr_Officer_f common";
		else 							Prisoner.greeting = "Gr_Officer_m common";*/
		Prisoner.Dialog.Filename = "Prisoned_dialog.c";
		Prisoner.Dialog.CurrentNode = "First time";
		//Prisoner.AbordageMode = 1;// boal 05.09.03 officer set to go to abordage

		// TIH --> suggested additions from maximus, adjusted for this code Aug29'06
// TIH --> no, see if this attr doesnt exist for NEW officer, its because REF officer didn't have it in the first place, so trying to assign it the null field again is a bit pointless and dangerous - Oct30'06
//		if (!CheckAttribute(Prisoner,"location.locator") && CheckAttribute(RefChar, "location.locator")) Prisoner.location.locator = RefChar.location.locator;// ? was a bug with not existent location.locator // KK now that should be OK 
//		if (!CheckAttribute(Prisoner,"location.locator"))	Prisoner.location.locator = "";// TIH - actually set it to nothing for fresh reset - Oct30'06
// TIH <--
		if (!CheckAttribute(Prisoner,"model.entity")) 	Prisoner.model.entity = "NPCharacter";// ? sometimes was an error - "can't create class"
		if (!CheckAttribute(Prisoner,"noFollowType")) 	Prisoner.noFollowType = "nofollow";// ? new identifier for template LAi_follow.c
		if (!CheckAttribute(Prisoner,"money")) 			Prisoner.money = 1+rand(100);// ? was a bug with not existent money
		// TIH <--

		if (bPurgeCrud) {// purge a whole bunch of broken crud that causes bugs for this new officer (captured captains only)
			if ( CheckAttribute(Prisoner,"ship") ) 			DeleteAttribute(Prisoner,"ship");
			if ( CheckAttribute(Prisoner,"shiptype") ) 		DeleteAttribute(Prisoner,"shiptype");
			if ( CheckAttribute(Prisoner,"shipmoney") ) 		DeleteAttribute(Prisoner,"shipmoney");
			if ( CheckAttribute(Prisoner,"curshipnum") ) 		DeleteAttribute(Prisoner,"curshipnum");
			if ( CheckAttribute(Prisoner,"seaai") ) 			DeleteAttribute(Prisoner,"seaai");
			if ( CheckAttribute(Prisoner,"features") ) 		DeleteAttribute(Prisoner,"features");
			if ( CheckAttribute(Prisoner,"viper_sailstype") ) DeleteAttribute(Prisoner,"viper_sailstype");
			if ( CheckAttribute(Prisoner,"seatime") ) 		DeleteAttribute(Prisoner,"seatime");
			if ( CheckAttribute(Prisoner,"relation") ) 		DeleteAttribute(Prisoner,"relation");
			if ( CheckAttribute(Prisoner,"fantomtype") ) 		DeleteAttribute(Prisoner,"fantomtype");
			if ( CheckAttribute(Prisoner,"canfiretime") ) 	DeleteAttribute(Prisoner,"canfiretime");
			if ( CheckAttribute(Prisoner,"rankscale") ) 		DeleteAttribute(Prisoner,"rankscale");
			if ( CheckAttribute(Prisoner,"tmpperks") ) 		DeleteAttribute(Prisoner,"tmpperks");
			if ( CheckAttribute(Prisoner,"tmpskill") ) 		DeleteAttribute(Prisoner,"tmpskill");
			if ( CheckAttribute(Prisoner,"points") ) 			DeleteAttribute(Prisoner,"points");
			if ( CheckAttribute(Prisoner,"randofficers") ) 	DeleteAttribute(Prisoner,"randofficers");
			if ( CheckAttribute(Prisoner,"skillnatmult") ) 	DeleteAttribute(Prisoner,"skillnatmult");
			if ( CheckAttribute(Prisoner,"nodisarm") ) 		DeleteAttribute(Prisoner,"nodisarm");
			if ( CheckAttribute(Prisoner,"points") ) 			DeleteAttribute(Prisoner,"points");
			if ( CheckAttribute(Prisoner,"isFantom") ) 		DeleteAttribute(Prisoner,"isFantom");
		}
			//Prisoner.location.group = "officers";// not needed
			//Prisoner.chr_ai.type = "officer";
			//Prisoner.offgen = true;
			//Prisoner.officer = true;
			//Prisoner.friend = true;
		Prisoner.prisoned = true;
		Prisoner.land = "0";
		Prisoner.wealth = "0";

		AddPassenger(PChar, Prisoner, true);// just add them as a passenger for now
		ChangeCharacterAddressGroup(&RefChar, "None", "", "");// get rid of the reference character
		LAi_EnableReload();

		// keep the PrisonerIdx attribute, as its needed in the second function

		//trace("dialog_func.c -> officer dump at end:"); DumpAttributes( Characters[sti(PChar.quest.PrisonerIdx)] );
		//trace("-----------------------------------------------------------------");
	}
	else
	{
		LAi_SetImmortal(RefChar, false);
		LAi_SetPlayerType(PChar);
		if(CORPSEMODE<4) { if(CheckAttribute(RefChar,"location")) RefChar.location = "none"; }
		boarding_enemy.status = "dead";
		boarding_enemy.position = "corpse";
		LAi_group_MoveCharacter(RefChar, LAI_GROUP_BRDENEMY);
		LAi_group_FightGroups(LAI_GROUP_BRDENEMY, LAI_GROUP_PLAYER, true);
		LAi_group_SetCheckEvent(LAI_GROUP_BRDENEMY);

//		Log_SetStringToLog(QUEST_MESSAGE12);
	}
	//LanguageCloseFile(tmpLangFileID);
	//DeleteAttribute(Pchar, "quest.HiringOfficerIDX");// deleted here, because we certainly no longer need it now
//	if (bAbordageStarted) refEnCharacter = Prisoner;//commented by MAXIMUS: we need this? for what?
}

// LDH -->  03Sep06  Reset AlwaysRunToggle if it was changed before boarding cabin dialog
void RestoreAlwaysRunState()
{
	ref mchr = GetMainCharacter();
	if (CheckAttribute(mchr, "SavedAlwaysRunToggle"))
	{
		if (sti(mchr.SavedAlwaysRunToggle))
		{
			DeleteAttribute(mchr, "SavedAlwaysRunToggle");
			AlwaysRunToggle = true;		// global alwaysrun variable, set by K key
			BeginChangeCharacterActions(GetMainCharacter());
			SetDefaultNormWalk(GetMainCharacter());
			SetDefaultFight(GetMainCharacter());
			EndChangeCharacterActions(GetMainCharacter());
		}
		DeleteAttribute(mchr, "SavedAlwaysRunToggle");
	}
}
// LDH <--

// Riley -->
void Riley_Restock_Ammo(int gunpowder, int pistol_bullets, int grapeshot, int musket_bullets, int theprice)
{
	// restock the weapons locker in the captain's cabin
	ref _loc = &Locations[FindLocation("Tutorial_Deck")];

// KK -->
	if (CheckAttribute(_loc, "weaponslocker.items.gunpowder")) {
		_loc.weaponslocker.items.gunpowder = sti(_loc.weaponslocker.items.gunpowder) + gunpowder;
	} else {
		_loc.weaponslocker.items.gunpowder = gunpowder;
	}
	if (CheckAttribute(_loc, "weaponslocker.items.pistolbullets")) {
		_loc.weaponslocker.items.pistolbullets = sti(_loc.weaponslocker.items.pistolbullets) + pistol_bullets;
	} else {
		_loc.weaponslocker.items.pistolbullets = pistol_bullets;
	}
	if (CheckAttribute(_loc, "weaponslocker.items.pistolgrapes")) {
		_loc.weaponslocker.items.pistolgrapes = sti(_loc.weaponslocker.items.pistolgrapes) + grapeshot;
	} else {
		_loc.weaponslocker.items.pistolgrapes = grapeshot;
	}
	if (CheckAttribute(_loc, "weaponslocker.items.musketbullets")) {
		_loc.weaponslocker.items.musketbullets = sti(_loc.weaponslocker.items.musketbullets) + musket_bullets;
	} else {
		_loc.weaponslocker.items.musketbullets = musket_bullets;
	}
// <-- KK
	Log_SetStringToLog(XI_ConvertString("Weapons locker") + ": " + gunpowder + " " + XI_ConvertString("wgunpowder") + ", "  + pistol_bullets + " " + XI_ConvertString("wpistol bullets") + ", " + grapeshot + " " + XI_ConvertString("wgrapeshot loads") + ", " +  musket_bullets + " " + XI_ConvertString("wmusket bullets purchased for") + " " + theprice + " " + XI_ConvertString("wgold") + ".");
	PlaySound("interface\took_item.wav");
}

void Riley_Officer_Restock_Ammo(int officer_price)
{
// restock the officer's and your own ammo and gunpowder supply

	if (!ENABLE_AMMOMOD) return;	// LDH -- skip if ammo mod is not enabled

	ref _refCharacter = GetMainCharacter();
	int psgQuant = GetPassengersQuantity(_refCharacter);

	int gunpowder_officers = 0;
	int pistolbullets_officers = 0;
	int pistolgrapes_officers = 0;
	int musketbullets_officers = 0;
	int pistolbulletcheck = 0;
	int max_powder = 6;
	int max_ammo = 6;

	string pb_sgpl = " " + XI_ConvertString("wpistol bullets") + ", ";
	string pg_sgpl = " " + XI_ConvertString("wgrapeshot loads") + ", ";
	string mb_sgpl = " " + XI_ConvertString("wmusket bullets bought for") + " ";
	if (LAi_IsCapturedLocation) mb_sgpl = " " + XI_ConvertString("wmusket bullets taken"); // KK
			
	ref curChar;
	int cn;
	for(int i=0;i<psgQuant;i++)
	{
		cn = GetPassenger(_refCharacter,i);
		if(cn==-1) break;

		curChar = GetCharacter(cn);
		if(CheckAttribute(curChar,"prisoned"))
		{
			if(sti(curChar.prisoned)==true) continue;
		}
		pistolbulletcheck = 0;

		// checking for powder flask, ammo pouch, powder barrel and ammunition bag
		max_powder = 6;
		max_ammo = 6;
		if(CheckCharacterItem(curChar,"powderflask") > 0 && CheckCharacterItem(curChar,"powderbarrel") == 0) { max_powder = 12; }
		if(CheckCharacterItem(curChar,"powderflask") > 0 && CheckCharacterItem(curChar,"powderbarrel") > 0) { max_powder = 24; }
		if(CheckCharacterItem(curChar,"ammopouch") > 0 && CheckCharacterItem(curChar,"ammobag") == 0) { max_ammo = 12; }
		if(CheckCharacterItem(curChar,"ammopouch") > 0 && CheckCharacterItem(curChar,"ammobag") > 0) { max_ammo = 24; }

		// restock gunpowder to max_powder loads if the amount of gunpowder is < max_powder.

		if(sti(curChar.items.gunpowder) < max_powder)
		{
			gunpowder_officers += max_powder - sti(curChar.items.gunpowder);
			curChar.items.gunpowder = max_powder;
		}

		// restock pistolgrapes to max_ammo loads, if a grapeshot pistol or musketoon is equipped and the amount of pistolgrapes is < max_ammo.
		if(IsEquipCharacterByItem(curChar, "pistol3-2") || IsEquipCharacterByItem(curChar, "pistol3-1") || IsEquipCharacterByItem(curChar, "pistol3") || IsEquipCharacterByItem(curChar, "pistol3+1") || IsEquipCharacterByItem(curChar, "pistol3+2") || IsEquipCharacterByItem(curChar, "pistol3+3") || IsEquipCharacterByItem(curChar, "pistolmtoon"))
		{
			pistolbulletcheck++;

			if(sti(curChar.items.pistolgrapes) < max_ammo)
			{
				pistolgrapes_officers += max_ammo - sti(curChar.items.pistolgrapes);
				curChar.items.pistolgrapes = max_ammo;
			}
			curChar.items.pistolbullets = 0;
			curChar.items.musketbullets = 0;
		}

		// restock musketbullets to (max_ammo/2) loads, if a musket is equipped and the amount of musketbullets is < (max_ammo/2).
		if(IsEquipCharacterByItem(curChar, "pistolmket"))
		{
			pistolbulletcheck++;

			if(sti(curChar.items.musketbullets) < (max_ammo/2))
			{
				musketbullets_officers += (max_ammo/2) - sti(curChar.items.musketbullets);
				curChar.items.musketbullets = (max_ammo/2);
			}
			curChar.items.pistolbullets = 0;
			curChar.items.pistolgrapes = 0;
		}

		// restock pistol bullets to max_ammo, if grapes and musketbullets were not restocked before and the amount of pistolbullets is < max_ammo.
		if(pistolbulletcheck == 0)
		{

			if(sti(curChar.items.pistolbullets) < max_ammo)
			{
				pistolbullets_officers += max_ammo - sti(curChar.items.pistolbullets);
				curChar.items.pistolbullets = max_ammo;
			}
			curChar.items.pistolgrapes = 0;
			curChar.items.musketbullets = 0;
		}
	}

	if(officer_price > 0)
	{
		// singular / plural check for words. Wheeeee! :)
		if(pistolbullets_officers == 1)pb_sgpl = " " + XI_ConvertString("wpistol bullet") + ", ";
		if(pistolgrapes_officers == 1)pg_sgpl = " " + XI_ConvertString("wgrapeshot load") + ", ";
		if(musketbullets_officers == 1)mb_sgpl = " " + XI_ConvertString("wmusket bullet bought for") + " ";
		// Log entry and sound
		Log_SetStringToLog(XI_ConvertString("Officers") + ": " + gunpowder_officers + " " + XI_ConvertString("wgunpowder") + ", "  + pistolbullets_officers + pb_sgpl + pistolgrapes_officers + pg_sgpl +  musketbullets_officers + mb_sgpl + officer_price + " " + XI_ConvertString("wgold") + ".");
		PlaySound("interface\officers_ammo.wav");
	}
// KK -->
	if (LAi_IsCapturedLocation) {
		// singular / plural check for words. Wheeeee! :)
		if(pistolbullets_officers == 1)pb_sgpl = " " + XI_ConvertString("wpistol bullet") + ", ";
		if(pistolgrapes_officers == 1)pg_sgpl = " " + XI_ConvertString("wgrapeshot load") + ", ";
		if(musketbullets_officers == 1)mb_sgpl = " " + XI_ConvertString("wmusket bullet taken");
		// Log entry and sound
		Log_SetStringToLog(XI_ConvertString("Officers") + ": " + gunpowder_officers + " " + XI_ConvertString("wgunpowder") + ", "  + pistolbullets_officers + pb_sgpl + pistolgrapes_officers + pg_sgpl +  musketbullets_officers + mb_sgpl + ".");
		PlaySound("interface\officers_ammo.wav");
	}
// <-- KK
}

int Riley_Officer_Restock_Ammo_Price()
{
	if (!ENABLE_AMMOMOD) return 0;		// LDH -- skip if ammo mod is not enabled
	if (LAi_IsCapturedLocation) return 0; // KK

	// restock the officer's and your own ammo and gunpowder supply
	ref _refCharacter = GetMainCharacter();
	int psgQuant = GetPassengersQuantity(_refCharacter);

	int gunpowder_officers = 0;
	int pistolbullets_officers = 0;
	int pistolgrapes_officers = 0;
	int musketbullets_officers = 0;
	int pistolbulletcheck = 0;
	int officer_restock_price = 0;
	int maxpowder = 6;
	int maxammo = 6;

	ref curChar;
	int cn;
	for(int i=0;i<psgQuant;i++)
	{
		cn = GetPassenger(_refCharacter,i);
		if(cn==-1) break;

		curChar = GetCharacter(cn);
		if(CheckAttribute(curChar,"prisoned"))
		{
			if(sti(curChar.prisoned)==true) continue;
		}
		pistolbulletcheck = 0;
		

		// checking for powder flask, ammo pouch, powder barrel and ammunition bag
		maxpowder = 6;
		maxammo = 6;
		if(CheckCharacterItem(curChar,"powderflask") > 0 && CheckCharacterItem(curChar,"powderbarrel") == 0) { maxpowder = 12; }
		if(CheckCharacterItem(curChar,"powderflask") > 0 && CheckCharacterItem(curChar,"powderbarrel") > 0) { maxpowder = 24; }
		if(CheckCharacterItem(curChar,"ammopouch") > 0 && CheckCharacterItem(curChar,"ammobag") == 0) { maxammo = 12; }
		if(CheckCharacterItem(curChar,"ammopouch") > 0 && CheckCharacterItem(curChar,"ammobag") > 0) { maxammo = 24; }

		// restocking gunpowder to maxpowder loads if the amount of gunpowder is < 24.

		if (CheckAttribute(curChar, "items.gunpowder") == true && sti(curChar.items.gunpowder) < maxpowder) gunpowder_officers += maxpowder - sti(curChar.items.gunpowder); // KK

		// restocking pistolgrapes to maxammo loads, if a grapeshot pistol or musketoon is equipped and the amount of pistolgrapes is < maxammo.
		if(IsEquipCharacterByItem(curChar, "pistol3-2") || IsEquipCharacterByItem(curChar, "pistol3-1") || IsEquipCharacterByItem(curChar, "pistol3") || IsEquipCharacterByItem(curChar, "pistol3+1") || IsEquipCharacterByItem(curChar, "pistol3+2") || IsEquipCharacterByItem(curChar, "pistol3+3") || IsEquipCharacterByItem(curChar, "pistolmtoon"))
		{
			pistolbulletcheck++;
			if(sti(curChar.items.pistolgrapes) < maxammo)pistolgrapes_officers += maxammo - sti(curChar.items.pistolgrapes);
		}

		// restocking musketbullets to (maxammo/2) loads, if a musket is equipped and the amount of musketbullets is < (maxammo/2).
		if(IsEquipCharacterByItem(curChar, "pistolmket"))
		{
			pistolbulletcheck++;
			if(sti(curChar.items.musketbullets) < (maxammo/2))musketbullets_officers += (maxammo/2) - sti(curChar.items.musketbullets);
		}
		// restock pistol bullets to maxammo, if grapes and musketbullets were not restocked before and the amount of pistolbullets is < maxammo.
		if(pistolbulletcheck == 0)
		{
			if (CheckAttribute(curChar, "items.pistolbullets") == true && sti(curChar.items.pistolbullets) < maxammo) pistolbullets_officers += maxammo - sti(curChar.items.pistolbullets); // KK
		}
	}
	// Calculate price for restock of the officer's supplies
	officer_restock_price = gunpowder_officers * (13 - rand(3)) + pistolbullets_officers * (8 - rand(3)) + pistolgrapes_officers * (14 - rand(4)) + musketbullets_officers * (15 - rand(5));
	return officer_restock_price;
}
// <-- Riley

void RansomColony(ref gov)
{
	int iNation = sti(gov.nation);
	string TownName = gov.town;
	ref ctown = GetTownFromID(TownName);
	ref PChar = GetMainCharacter();
	int townsize = GetTownSize(TownName);
	int troops = GetTownNumTroops(TownName);
	UpdateRMRelation(PChar, iNation, makefloat(townsize+troops)/100.0);
	int nBooty = makeint(makefloat(GetTownGold(TownName)) * TOWN_GOLD_SACK_SCALAR * (0.75 + frand(0.25) + makefloat(GetSummonSkillFromName(PChar, SKILL_SNEAK)/20.0)));
	SetTownGold(TownName, GetTownGold(TownName) - nBooty);
	AddMoneyToCharacter(PChar, nBooty);
	int nExp = troops * 50;
	SetTownNumTroops(TownName, makeint(makefloat(troops) * SACK_TROOPS_DECREASE * (0.75 + frand(0.5))));
	if(AUTO_SKILL_SYSTEM)
	{
		AddCharacterExpChar(PChar, "Cannons", makeint(nExp/2));
		AddCharacterExpChar(PChar, "Grappling", makeint(nExp/2));
	}
	else { AddCharacterExp(PChar, nExp); }
	AddMoneyToCharacter(PChar,nBooty);
	SetTownSize(TownName, townsize * SACK_TOWN_DECREASE); // NK

	float relchg = 10;
	int i = 0;
	ChangeRMRelation(PChar, iNation, -relchg);
	for (i = 0; i < MAX_NATIONS; i++) {
		if (i == iNation) continue;
		if (GetNationRelation(iNation, i) == RELATION_ENEMY) ChangeRMRelation(PChar, i, 1.0);
	}

	SetTownCapturedState(TownName, true);
	OccupyTown(TownName);

	for (i = 0; i < 4; i++) {
		int cn = GetCompanionIndex(PChar, i);
		if(cn >= 0) {
			ref chref = GetCharacter(cn);
			chref.ship.hp = GetCharacterShipHP(chref);
			chref.ship.sp = GetCharacterShipSP(chref);
// added by MAXIMUS [full ship's repairing] -->
			chref.Ship.crew.quantity = GetMaxCrewQuantity(chref);
			SetCannonArcQty(chref, 0, GetCannonArcMaxQty(chref, 0));
			SetCannonArcQty(chref, 1, GetCannonArcMaxQty(chref, 1));
			SetCannonArcQty(chref, 2, GetCannonArcMaxQty(chref, 2));
			SetCannonArcQty(chref, 3, GetCannonArcMaxQty(chref, 3));
// added by MAXIMUS [full ship's repairing] <--
			DeleteAttribute(chref,"ship.sails");
			DeleteAttribute(chref,"ship.masts");
		}
	}
}

void CaptureColony(ref gov, int toNation)
{
	bool tmpbool = toNation >= 0 || toNation < MAX_NATIONS;
	tmpbool = tmpbool || toNation == PERSONAL_NATION;
	if (!tmpbool) return;
	int iNation = sti(gov.nation);
	string TownName = gov.town;
	ref ctown = GetTownFromID(TownName);
	ref PChar = GetMainCharacter();
	int townsize = GetTownSize(TownName);
	int troops = GetTownNumTroops(TownName);
	if (toNation != PERSONAL_NATION) {
		UpdateRMRelation(PChar, iNation, makefloat(townsize+troops)/100.0);
		int nBooty = makeint(makefloat(GetTownGold(TownName)) * TOWN_GOLD_SACK_SCALAR * (0.75 + frand(0.25) + makefloat(GetSummonSkillFromName(PChar, SKILL_SNEAK)/20.0) * 0.75));
		SetTownGold(TownName, GetTownGold(TownName) - nBooty);
		AddMoneyToCharacter(PChar, nBooty);
	}
	int nExp = troops * 50;
	SetTownNumTroops(TownName, makeint(makefloat(troops) * SACK_TROOPS_DECREASE * (0.75 + frand(0.5))));
	if(AUTO_SKILL_SYSTEM)
	{
		AddCharacterExpChar(PChar, "Cannons", makeint(nExp/2));
		AddCharacterExpChar(PChar, "Grappling", makeint(nExp/2));
	}
	else { AddCharacterExp(PChar, nExp); }
	SetTownSize(TownName, townsize * SACK_TOWN_DECREASE); // NK

	float relchg = REL_MIN;
	ChangeRMRelation(PChar, iNation, relchg);
	if (toNation != PERSONAL_NATION) {
		relchg = 10;
		SetActualRMRelation(iNation, REL_NEUTRAL);
		ChangeRMRelation(PChar, toNation, relchg);
	}

	for (int i = 0; i < 4; i++) {
		int cn = GetCompanionIndex(PChar, i);
		if(cn >= 0) {
			ref chref = GetCharacter(cn);
			chref.ship.hp = GetCharacterShipHP(chref);
			chref.ship.sp = GetCharacterShipSP(chref);
// added by MAXIMUS [full ship's repairing] -->
			chref.Ship.crew.quantity = GetMaxCrewQuantity(chref);
			SetCannonArcQty(chref, 0, GetCannonArcMaxQty(chref, 0));
			SetCannonArcQty(chref, 1, GetCannonArcMaxQty(chref, 1));
			SetCannonArcQty(chref, 2, GetCannonArcMaxQty(chref, 2));
			SetCannonArcQty(chref, 3, GetCannonArcMaxQty(chref, 3));
// added by MAXIMUS [full ship's repairing] <--
			DeleteAttribute(chref,"ship.sails");
			DeleteAttribute(chref,"ship.masts");
		}
	}

	CaptureTownForNation(TownName, toNation);
}
// <-- KK

// MAXIMUS: can be used in any situation [used in Silehard-dialog] --> // KK -->
string GetShipDescribe(string charId, bool nation, bool nguns, bool shipname, bool accusative)
{
	ref chr, shipRef;
	int canQuantity;
	aref arShip;
	string shipType;
	string shipDescribe = "";

	chr = characterFromID(charId);
	shipRef = GetShipByType(GetCharacterShipType(chr));
	shipType = XI_ConvertString(shipRef.Sname);

	if (nation) shipDescribe += XI_ConvertString("sw_" + GetNationDescByType(sti(chr.nation))) + " ";
	if (nguns) shipDescribe += GetMaxCannonQuantity(chr) + XI_ConvertString("cannonsQuantity") + " ";
	shipDescribe += strlower(shipType);
	if (accusative) {
		switch (LanguageGetLanguage()) {
			case "Polish":
				int dl = strlen(shipDescribe);
				if (GetSymbol(shipDescribe, dl - 1) == "a") {
					string tmpstr = "";
					for (int i = 0; i < dl - 1; i++) {
						if (GetSymbol(shipDescribe, i + 1) == " ")
							tmpstr += "№";
						else
							tmpstr += strcut(shipDescribe, i, i);
					}
					tmpstr += "Ч";
					shipDescribe = tmpstr;
				}
			break;
			// default:
		}
	}
	if (shipname) shipDescribe += " '" + chr.Ship.Name + "'";

	if(HasSubStr(shipType,"0") || HasSubStr(shipType,"1") || HasSubStr(shipType,"2") || HasSubStr(shipType,"3") || HasSubStr(shipType,"4") || HasSubStr(shipType,"5") || HasSubStr(shipType,"6") || HasSubStr(shipType,"7") || HasSubStr(shipType,"8") || HasSubStr(shipType,"9"))
	{
		if(!HasSubStr(shipType," 0") && !HasSubStr(shipType," 1") && !HasSubStr(shipType," 2") && !HasSubStr(shipType," 3") && !HasSubStr(shipType," 4") && !HasSubStr(shipType," 5") && !HasSubStr(shipType," 6") && !HasSubStr(shipType," 7") && !HasSubStr(shipType," 8") && !HasSubStr(shipType," 9"))
		{
			shipDescribe = shipType;
		}
	}
	return shipDescribe;
}
// MAXIMUS: can be used in any situation [used in Silehard-dialog] <-- // <-- KK

//MAXIMUS -->
void GotSlut(string wait)
{
	ref pchar = GetMainCharacter();
	PlayStereoSound("INTERFACE\took_item.wav");
	AddMoneyToCharacter(pchar, -50);
	string roomName = pchar.location;
	aref cLoctr; makearef(cLoctr,locations[FindLocation(pchar.location)].reload);
	for(int i=0; i<GetAttributesNum(cLoctr); i++)
	{
		aref curItem1 = GetAttributeN(cLoctr,i);
		string attrName1 = GetAttributeName(curItem1);
		if(CheckAttribute(cLoctr,attrName1+".go"))
		{
			if(HasSubStr(cLoctr.(attrName1).go,"_upstairs") || HasSubStr(cLoctr.(attrName1).go,"_bedroom")) roomName = cLoctr.(attrName1).go;
		}
	}
	DoQuestReloadToLocation(roomName, "goto", "goto4", "restore_hp");
	TavernWaitDate2("wait_"+wait);
}
//MAXIMUS <--

// MAXIMUS: sometimes player can't see his interlocutor - now camera will be moved to the some side for full scene viewing <--
bool DialogCamera(ref pchar, float mag, bool docheck)
{
	if(FindLoadedLocation()==-1) return false; //if not in loc mode, return
	int side = 1;
	if(Rand(3)==Rand(3)) side = -1;
	mag = stf(side*mag);
	ref curLocation = &locations[FindLoadedLocation()];
	float x, y, z, ay, tmpY;
	GetCharacterPos(&pchar, &x, &y, &z); // get pos
	bool bSmallLoc = false;
	if(CheckAttribute(curLocation,"models.back") || HasSubStr(curLocation.id,"House") || HasSubStr(curLocation.id,"Tutorial_Deck") || HasSubStr(curLocation.id,"Cabin") || HasSubStr(curLocation.id,"Seadog")) bSmallLoc = true;
	if(bSmallLoc) { tmpY = stf(y+2.2); }
	else { tmpY = stf(y+3.0); }
	GetCharacterAy(&pchar, &ay); // get angle

	//moves back a little for viewing interlocutor
	z += cos(ay) * stf(-1.0); // add Z component
	x += sin(ay) * stf(-1.0); // add X component

	ay += PId2; // rotate angle to perpendicular
	z += cos(ay) * mag; // add Z component
	x += sin(ay) * mag; // add X component
	if(docheck)
	{
		if(CheckLocationPosition(curLocation, x, tmpY, z)==0)
		{
			locCameraFollow();
			return false;
		}
	}
	locCameraToPos(x, tmpY, z, true);
	return true;
}
// MAXIMUS: sometimes player can't see his interlocutor - now camera will be moved to the some side for full scene viewing <--

// CCC -->
void GotSkill(string topic)
{
	//int tmpLangFileID = LanguageOpenFile("interface_strings.txt");
	LAi_Fade("", "");
	WaitDate("", 0,0,0,5,0);
	RecalculateJumpTable();
	PlaySound("AMBIENT\SHOP\sigh2.wav");
	Log_SetStringToLog(TranslateString("","For five hours are you being lectured on") + " " + XI_ConvertString(topic));
	Log_SetStringToLog(TranslateString("","This has improved your") + " " + XI_ConvertString(topic) + " " + TranslateString("","skill"));
	//LanguageCloseFile(tmpLangFileID);
}
// <-- CCC
