//===================================| Idea of AlexusB. Totally rewritten by MAXIMUS and KK |===================================//

bool	bDeckStarted = false;
bool	bCabinStarted = false;
bool	bCrewStarted = false;
// KK -->
bool bDeckEnter = false;
bool bToDeckFromLand = false;
bool bEmergeOnStartloc = false;
string DeckID = "";
int FromDeckIdx = -1;
int LandLocationIdx = -1;
string LandLocator = "";
string current_locator_name = "";
float Land_posx[4];
float Land_posy[4];
float Land_posz[4];
float Land_angle[4];
// <-- KK

bool ownDeckStarted()//MAXIMUS
{
	if(bDeckStarted || bCabinStarted || bCrewStarted || bMutinyDeckStarted) return true;
	if(CheckAttribute(characters[GetMainCharacterIndex()],"location") && characters[GetMainCharacterIndex()].location=="Tutorial_Deck") return true;

	return false;
}

void Deck_ReloadStartFade()
{
	int a = GetEventData();
	aref reload_fader = GetEventData();
	LayerFreeze(SEA_EXECUTE,true);
	LayerFreeze(SEA_REALIZE,true);
	LayerFreeze("sea_reflection",true);
	LayerFreeze("execute",false);
	LayerFreeze("realize",false);

	MoveWeatherToLayers("execute", "realize");
	MoveSeaToLayers("execute", "realize");

	SendMessage(&AIBalls, "l", MSG_MODEL_RELEASE);

	DelEventHandler("FaderEvent_StartFade", "Deck_ReloadStartFade");

	if (CheckAttribute(Sea, "MaxSeaHeight")) { // KK
		fOldMaxSeaHeight = stf(Sea.MaxSeaHeight);
		Sea.MaxSeaHeight = 1.2;						// set maxinum sea height for ship Deck
	}
}

void Return2SeaAfterDeck()
{
// KK -->
	if (bToDeckFromLand) {
		SetEventHandler("FaderEvent_StartFade", "DeckToSea_ReloadStartFadeAfter", 0);
		SetEventHandler("FaderEvent_EndFade", "DeckToSea_ReloadEndFadeAfter", 0);
	} else {
// <-- KK
		//Установить хендлеры для обработки
		SetEventHandler("FaderEvent_StartFade", "Deck_ReloadStartFadeAfter", 0);
		SetEventHandler("FaderEvent_EndFade", "Deck_ReloadEndFadeAfter", 0);
	}
	//Создаём фейдер и запускаем
	CreateEntity(&boarding_fader, "fader");
	SendMessage(&boarding_fader, "ls", FADER_PICTURE, FindReloadPicture("sea.tga")); // KK

	float fadeOutTime = RELOAD_TIME_FADE_OUT;

	SendMessage(&boarding_fader, "lfl", FADER_OUT, fadeOutTime, false);
	SendMessage(&boarding_fader, "l", FADER_STARTFRAME);
	if(CheckAttribute(GetMainCharacter(),"IsOnDeck")) { DeleteAttribute(GetMainCharacter(),"IsOnDeck"); }//MAXIMUS
}

void Deck_ReloadEndFade()
{
	// Delete current cannonballs
	AIBalls.Clear = "";

	// unload all models
	aref arModel;
	if (FindClass(&arModel, "modelr")) 
	{
		SendMessage(arModel, "l", MSG_MODEL_RELEASE);
		while (FindClassNext(&arModel)) { SendMessage(arModel, "l", MSG_MODEL_RELEASE); }
	}

	PauseParticles(true);

	// start Deck location
	int a = GetEventData();
	aref reload_fader = GetEventData();
	
	Deck_Start();
	
	DelEventHandler("FaderEvent_EndFade", "Deck_ReloadEndFade");
	SendMessage(&reload_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);
}

void Sea_DeckStartNow(string deckname)
{
	bSeaReloadStarted = true;
	bToDeckFromLand = false; // KK

	object reload_fader;
	CreateEntity(&reload_fader, "fader");
	SetEventHandler("FaderEvent_StartFade", "Deck_ReloadStartFade", 0);
	SetEventHandler("FaderEvent_EndFade", "Deck_ReloadEndFade", 0);
	SetEventHandler("Control Activation", "TeleportToDeck", 1); // KK

	bDeckEnter = true; // KK

	DeckID = deckname; // KK

	// SCREWFACE : loading screen is different for different deck model
	if (CheckAttribute(&Locations[FindLocation(DeckID)], "image")) SendMessage(&reload_fader, "ls", FADER_PICTURE, FindReloadPicture(Locations[FindLocation(DeckID)].image)); // KK
	// SCREWFACE : END

	SendMessage(&reload_fader, "lfl", FADER_OUT, 1.0, false);
	SendMessage(&reload_fader, "l", FADER_STARTFRAME);

	PauseAllSounds();
	ResetSoundScheme();

	bAbordageStarted = true;
	bDeckStarted = true;
	if (DeckID == "seadogs") bCrewStarted = true;
	Sea.AbordageMode = true;
	//MAXIMUS [used for DirectSail] -->
	ref PChar = GetMainCharacter();
	PChar.IsOnDeck = true;
	//MAXIMUS [used for DirectSail] <--
}

//////////////
void Deck_Start()
{
	ResetSoundScheme();
	PauseAllSounds();
	int i;
	//=астроим интерфейс
	if (LandLocationIdx == -1) DeleteBattleInterface(); // KK
	StartBattleLandInterface();
	
	ref mchr = GetMainCharacter();
	
	// SCREWFACE : To have small different model of deck for different shipclass
	int locID = -1;
	locID = FindLocation(DeckID);
	if(locID < 0)
	{
		Trace("Boarding: ship location not found <" + DeckID + ">, set default");
		DeckID = "";
		return;
	}

	SetUpDeckReloadMap(); // KK

	//Tыставим  и запомним адреса
	boarding_adr[0].location = mchr.location;
	boarding_adr[0].group = mchr.location.group;
	boarding_adr[0].locator = mchr.location.locator;

	for(i = 1; i < 4; i++)
	{
		int idx = GetOfficersIndex(GetMainCharacter(), i);
		if(idx < 0)
		{
			boarding_adr[i].location = "";
			boarding_adr[i].group = "";
			boarding_adr[i].locator = "";
			continue;
		}
		boarding_adr[i].location = Characters[idx].location;
		boarding_adr[i].group = Characters[idx].location.group;
		boarding_adr[i].locator = Characters[idx].location.locator;
	}
	//Стартуем
	Deck_LoadLocation(DeckID); // KK //MAXIMUS
	CreateEntity(&boarding_fader, "fader");
	SendMessage(&boarding_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);
}

//Загрузить локаци| абордажа
void Deck_LoadLocation(string locID) // KK //MAXIMUS
{
	SetDeckPortBackground(); // PB
	ReloadProgressStart();
	//Lщем локаци|
	int locIndex = FindLocation(locID);
	if(locIndex >= 0)
	{
		if(!bCanEnterToLand && HasSubStr(DeckID,"ShipDeck")) locations[locIndex].coxswain = true;//MAXIMUS: added for placing monster near steering-wheel
		//Устанавливаем главного персонажа
		ref mchr = GetMainCharacter();
		mchr.location = locID;

	// SCREWFACE : locators to load nathaniel are different for different model
// KK -->
		if (FromDeckIdx == -1) {
			if (!bEmergeOnStartloc) {
				mchr.location.group = "reload";
				mchr.location.locator = GetRandSubString("boatr,boatl");//MAXIMUS
				bEmergeOnStartloc = true;
			} else {
				mchr.location.group = "rld";
				mchr.location.locator = "startloc";
			}
		} else {
			mchr.location.group = "reload";
			mchr.location.locator = GetReloadMapAttrib(FromDeckIdx, current_locator_name, "emerge");
		}

		//chrWaitReloadLocator = "";
		chrWaitReloadIsNoLink = false;
		FromDeckIdx = -1;
		current_locator_name = "";
// <-- KK

	//JRH -->
		string weaponID = GetCharacterEquipByGroup(mchr,GUN_ITEM_TYPE);
		aref weapon;
		Items_FindItem(weaponID, &weapon);

		int s; //shots
		int ShCl = makeint(GetCharacterShipClass(mchr));
	//<-- JRH 
		int logined = 1; // added by MAXIMUS
		//Устанавливаем офицеров, если такие есть
// KK -->
		int idx = -1;
		ref tmpChr;
		int i;/*
		for(i = 1; i < 4; i++) {
			idx = GetOfficersIndex(mchr, i);
			if(idx < 0) continue;
			tmpChr = GetCharacter(idx);
			if (CheckAttribute(tmpChr,"quest.officertype")) {
				if (FindCurrentDeck() == "CannonsDeck" && tmpChr.quest.officertype == OFFIC_TYPE_CANNONEER) {
					ChangeCharacterAddressGroup(tmpChr, mchr.location, "rld", "loc" + logined);
					logined++;
				}
				if (FindCurrentDeck() == "Hold" && tmpChr.quest.officertype == OFFIC_TYPE_CARPENTER) {
					ChangeCharacterAddressGroup(tmpChr, mchr.location, "rld", "loc" + logined);
					logined++;
				}
				if (FindCurrentDeck() == "ShipDeck") {
					if (GetCharacterShipCabin(mchr) == "Cabin_none") {
						ChangeCharacterAddressGroup(tmpChr, mchr.location, "rld", "loc" + logined);
						logined++;
					} else {
						if (tmpChr.quest.officertype == OFFIC_TYPE_ABORDAGE || tmpChr.quest.officertype == OFFIC_TYPE_CANNONEER) {
							ChangeCharacterAddressGroup(tmpChr, mchr.location, "rld", "loc" + logined);
							logined++;
						}
					}
				}
				if (FindCurrentDeck() == "seadogs") {
					if (tmpChr.quest.officertype == OFFIC_TYPE_BOATSWAIN || tmpChr.quest.officertype == OFFIC_TYPE_DOCTOR || tmpChr.quest.officertype == OFFIC_TYPE_QMASTER || tmpChr.quest.officertype == OFFIC_TYPE_ABORDAGE)
					{
						ChangeCharacterAddressGroup(tmpChr, mchr.location, "rld", "loc" + logined);
						logined++;
					}
				}
			}
// <-- KK

		//JRH -->
		  if (ENABLE_AMMOMOD) {// TIH --> mod toggle 7-7-06
				if(CheckAttribute(weapon, "shottype") )
				{
					if(weapon.shottype == "pg2" || weapon.shottype == "pg" || weapon.shottype == "mb" || weapon.shottype == "pb")
					{
					// TIH --> adjustments of code Jul16'06
						if(CheckAttribute(tmpChr,"quest.officertype") && tmpChr.quest.officertype=="cannoneer")
						{
							int priorGP = GetCharacterItem(mchr,"gunpowder");
							int priorPB = GetCharacterItem(mchr,"pistolbullets");
							int priorPG = GetCharacterItem(mchr,"pistolgrapes");
							int priorMB = GetCharacterItem(mchr,"musketbullets");
							
							DeleteAttribute(mchr,"Items.gunpowder");
							DeleteAttribute(mchr,"Items.pistolbullets");
							DeleteAttribute(mchr,"Items.pistolgrapes");
							DeleteAttribute(mchr,"Items.musketbullets");
							
							// we dont inform about just getting gunpowder
							if(CheckCharacterItem(mchr,"powderflask")) 	{ TakeNItems(mchr,"gunpowder", 12); }
							else 										{ TakeNItems(mchr,"gunpowder", 6); }
							if(CheckCharacterItem(mchr,"ammopouch")) 	{ s = 12; }	
							else 										{ s = 6; }
							
							if(weapon.shottype == "mb") 				{ s /= 2; }// can only carry half for muskets
							
							string strAmmoLoaded;
							bool doInform = false;
							if(weapon.shottype == "pb")  { TakeNItems(mchr,"pistolbullets", s); strAmmoLoaded = "Pistol"; 	 if (s > priorPB) { doInform = true; } }
							if(weapon.shottype == "pg")  { TakeNItems(mchr,"pistolgrapes", s);  strAmmoLoaded = "Grapeshot"; if (s > priorPG) { doInform = true; } }
							if(weapon.shottype == "pg2") { TakeNItems(mchr,"pistolgrapes", s);  strAmmoLoaded = "Grapeshot"; if (s > priorPG) { doInform = true; } }
							if(weapon.shottype == "mb")  { TakeNItems(mchr,"musketbullets", s); strAmmoLoaded = "Musket"; 	 if (s > priorMB) { doInform = true; } }
							
							if ( doInform ) {
								Log_SetStringToLog("The Gunner has provided you with "+ strAmmoLoaded +" Ammunition!");
								PlaySound("INTERFACE\important_item.wav");
							}
						}
					// TIH <-- adjustments
					}
				}
		  }// TIH <-- mod toggle
		//<-- JRH
		}*/

		// KK if (FindCurrentDeck() == "ShipDeck") ChangeCharacterAddressGroup(CharacterFromId("Crewmember_07"), mchr.location, "goto", "goto1");

// MAXIMUS deck MODE -[Sets up prisoners, if we have them]->
		if(RANSOM_PRISONERS && GetPrisonerQuantity(mchr)>0)
		{//MAXIMUS: all models have a proper poor-animation
			aref locRef = &Nullcharacter;
			string prLocGroup = "goto";
			string prLocName = "goto";
			if(HasSubStr(FindCurrentDeck(),"Hold"))
			{
				logined = 1;
				int captive = 0;
				if(mchr.location=="Hold2" && GetCharacterShipCargoHoldCount(mchr)>1) { logined = 1; captive = 8; }
				for(i = captive; i < GetPrisonerQuantity(mchr); i++)
				{
					if(logined==9) break;
					idx = GetPrisoner(mchr, i);
					if(idx==-1) continue;
					tmpChr = GetCharacter(idx);

					ChangeCharacterAddressGroup(tmpChr, mchr.location, "rld", "prison" + logined);
					DisarmCharacter(tmpChr, false, false);

					if(tmpChr.sex!="woman") { LAi_SetPoorTypeNoGroup(tmpChr); }
					else { LAi_SetStayTypeNoGroup(tmpChr); }
					if(!CheckAttribute(tmpChr,"gambled"))
					{
						tmpChr.Dialog.Filename = "Prisoned_dialog.c";
						tmpChr.Dialog.CurrentNode = "First time";
						if(tmpChr.sex=="woman") tmpChr.greeting = "Gr_Pirate_f";
						else tmpChr.greeting = "Gr_Smugglers_vs_Blythe";
					}
					logined++;
				}
			}
			if(GetCharacterShipCargoHoldCount(mchr)==0)
			{//MAXIMUS: so we can meet random prisoner
				idx = GetPrisoner(mchr, Rand(GetPrisonerQuantity(mchr)-1));
				if(idx>0)
				{
					tmpChr = GetCharacter(idx);
					if(CheckAttribute(tmpChr,"prisoned.status"))
					{
						if(sti(tmpChr.prisoned.status)<=GetPrisonerQuantity(mchr))
						{
							tmpChr.prisoned.status = sti(tmpChr.prisoned.status)+1;
						}
						else DeleteAttribute(tmpChr,"prisoned.status");
					}
					int count = 1;
					while(count<GetPrisonerQuantity(mchr) && CheckAttribute(tmpChr,"prisoned.status"))
					{
						tmpChr = GetCharacter(GetPrisoner(mchr, Rand(GetPrisonerQuantity(mchr)-1)));
						count++;
					}
					if(count==GetPrisonerQuantity(mchr)) DeleteAttribute(tmpChr,"prisoned.status");

					aref refLocators; makearef(refLocators,Locations[locIndex].locators);
					if(CheckAttribute(refLocators,"goto"))
					{
						makearef(locRef,Locations[locIndex].locators.goto);
						prLocName = "goto" + Rand(GetAttributesNum(locRef)-1);
						while(!CheckAttribute(locRef, prLocName))
						{
							prLocName = "goto" + Rand(GetAttributesNum(locRef)-1);
						}

						ChangeCharacterAddressGroup(tmpChr, locID, prLocGroup, prLocName);trace("BOAL_Deck: Prisoner "+GetMySimpleName(tmpChr)+" placed onto locator "+prLocName);
						DisarmCharacter(tmpChr, false, false);
						tmpChr.prisoned.status = 1;

						if(tmpChr.sex!="woman") { LAi_SetPoorTypeNoGroup(tmpChr); }
						else { LAi_SetStayTypeNoGroup(tmpChr); }
						if(!CheckAttribute(tmpChr,"gambled"))
						{
							tmpChr.Dialog.Filename = "Prisoned_dialog.c";
							tmpChr.Dialog.CurrentNode = "First time";
							if(tmpChr.sex=="woman") tmpChr.greeting = "Gr_Pirate_f";
							else tmpChr.greeting = "Gr_Smugglers_vs_Blythe";
						}
					}
					else
					{
						if(CheckAttribute(refLocators,"rld"))
						{
							prLocGroup = "rld";
							prLocName = GetRandSubString("aloc,loc");
							makearef(locRef,Locations[locIndex].locators.rld);
							string prName = prLocName + Rand(GetAttributesNum(locRef)-1);
							while(!CheckAttribute(locRef, prName))
							{
								prName = prLocName + Rand(GetAttributesNum(locRef)-1);
							}

							ChangeCharacterAddressGroup(tmpChr, locID, prLocGroup, prName);trace("BOAL_Deck: Prisoner "+GetMySimpleName(tmpChr)+" placed onto locator "+prName);
							DisarmCharacter(tmpChr, false, false);
							tmpChr.prisoned.status = 1;

							if(tmpChr.sex!="woman") { LAi_SetPoorTypeNoGroup(tmpChr); }
							else { LAi_SetStayTypeNoGroup(tmpChr); }
							if(!CheckAttribute(tmpChr,"gambled"))
							{
								tmpChr.Dialog.Filename = "Prisoned_dialog.c";
								tmpChr.Dialog.CurrentNode = "First time";
								if(tmpChr.sex=="woman") tmpChr.greeting = "Gr_Pirate_f";
								else tmpChr.greeting = "Gr_Smugglers_vs_Blythe";
							}
						}
					}
				}
			}
		}
// MAXIMUS deck MODE <-[Sets up prisoners, if we have them]-
		//Loading character into location
		boarding_location = locIndex;
		Locations[locIndex].boarding = "true";
		if(LoadLocation(&Locations[locIndex]))
		{
			PlaceOfficersToDeck("Deck");// MAXIMUS
			BLI_UpdateOfficers();//MAXIMUS: officers-icons fixed
			dialogDisable = false;
		} else {
			Trace("Boarding: Boarding location not loaded, current loc <" + DeckID + ">"); // KK
		}
	} else {
		Trace("Boarding: Boarding location not found, current loc <" + locID + ">");
	}

	if (HasSubStr(FindCurrentDeck(),"ShipDeck")) {
		Whr_UpdateWeather(false);//JA 8DEC06 on deck so resume raining
	} else {
		WhrDeleteRainEnvironment();// otherwise, stop raining
	}

	// PB: First Contact Quest -->
	if (CheckQuestAttribute("Firstcontact", "start_davyencounter")) {
		LAi_QuestDelay("voirdavy", 1.0);
	}
	// PB: First Contact Quest <--

	ReloadProgressEnd();
	PostEvent("LoadSceneSound", 500);
}

/////////////
void Deck_ReloadStartFadeAfter()
{
	//Tыгружаем локаци|
	ResetSoundScheme();
	PauseAllSounds();
	DelEventHandler("FaderEvent_StartFade", "Deck_ReloadStartFadeAfter");
	DelEventHandler("Control Activation", "TeleportToDeck");//JA 6DEC06 this eventhandler was hanging around after you went from deck to sea.
	if(boarding_location >= 0) UnloadLocation(&Locations[boarding_location]);
}

void Deck_ReloadEndFadeAfter()
{
	ReloadProgressStart(); // KK
	//Загружаем следу|щу| локаци|
	DelEventHandler("FaderEvent_EndFade", "Deck_ReloadEndFadeAfter");
	SendMessage(&boarding_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);
	//+пределим возможность продолжения перегрузок
	//Следу|щей локации нет
	//DelEventHandler("LAi_event_GroupKill", "LAi_BoardingGroupKill");
	boarding_location = -1;
	//=астроим интерфейс
	Log_SetActiveAction("Nothing");
	EndBattleLandInterface();
	//Tостановим адреса
	ref mchr = GetMainCharacter();
	mchr.location = boarding_adr[0].location;
	mchr.location.group = boarding_adr[0].group;
	mchr.location.locator = boarding_adr[0].locator;
	for(int i = 1; i < 4; i++)
	{
		int idx = GetOfficersIndex(mchr, i); // KK
		if(idx < 0) continue;
		Characters[idx].location = boarding_adr[i].location;
		Characters[idx].location.group = boarding_adr[i].group;
		Characters[idx].location.locator = boarding_adr[i].locator;
	}
/////////////////////////////////////////////////////////////////////
    // load all models back to sea
	aref arModel;
	if (FindClass(&arModel, "modelr"))
	{
		SendMessage(arModel, "l", MSG_MODEL_RESTORE);
		while (FindClassNext(&arModel))
		{
			//Trace("XYZ");
			SendMessage(arModel, "l", MSG_MODEL_RESTORE);
		}
	}

	LayerFreeze("execute",true);
	LayerFreeze("realize",true);

	LayerFreeze("sea_reflection", false);
	LayerFreeze(SEA_EXECUTE,false);
	LayerFreeze(SEA_REALIZE,false);

	MoveWeatherToLayers(SEA_EXECUTE, SEA_REALIZE);
	MoveSeaToLayers(SEA_EXECUTE, SEA_REALIZE);

	Sea.MaxSeaHeight = fOldMaxSeaHeight;		// restore old MaxSeaHeight
	bAbordageStarted = false;
	bDeckStarted = false;
	bCrewStarted = false;
	Sea.AbordageMode = false;
	chrWaitReloadLocator = "";

	InitBattleInterface();
	StartBattleInterface();
	RefreshBattleInterface();

	SetSchemeForSea();

	PauseParticles(false);

	bSeaReloadStarted = false;
	bDeckEnter = false; // KK

	Whr_UpdateWeather(false); //JA 8DEC06 on deck so resume raining

	ReloadProgressEnd(); // KK
}

// Cabin ---------------------------------------------------

void Cabin_ReloadStartFade()
{
	int a = GetEventData();
	aref reload_fader = GetEventData();
	LayerFreeze(SEA_EXECUTE,true);
	LayerFreeze(SEA_REALIZE,true);
	LayerFreeze("sea_reflection",true);
	LayerFreeze("execute",false);
	LayerFreeze("realize",false);

	MoveWeatherToLayers("execute", "realize");
	MoveSeaToLayers("execute", "realize");

	SendMessage(&AIBalls, "l", MSG_MODEL_RELEASE);

	DelEventHandler("FaderEvent_StartFade", "Cabin_ReloadStartFade");

	if (CheckAttribute(Sea, "MaxSeaHeight")) { // KK
		fOldMaxSeaHeight = stf(Sea.MaxSeaHeight);
		Sea.MaxSeaHeight = 1.2;						// set maxinum sea height for ship Cabin
	}
}

void Cabin_ReloadEndFade()
{
	// Delete current cannonballs
	AIBalls.Clear = "";

	// unload all models
	aref arModel;
	if (FindClass(&arModel, "modelr")) 
	{
		SendMessage(arModel, "l", MSG_MODEL_RELEASE);
		while (FindClassNext(&arModel)) { SendMessage(arModel, "l", MSG_MODEL_RELEASE); }
	}

	PauseParticles(true);

	// start Cabin location
	int a = GetEventData();
	aref reload_fader = GetEventData();
	
	Cabin_Start();
	
	DelEventHandler("FaderEvent_EndFade", "Cabin_ReloadEndFade");
	SendMessage(&reload_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);
}

void Sea_CabinStartNow()
{
	bSeaReloadStarted = true;
	bToDeckFromLand = false; // KK

	object reload_fader;
	CreateEntity(&reload_fader, "fader");
	SetEventHandler("FaderEvent_StartFade", "Cabin_ReloadStartFade", 0);
	SetEventHandler("FaderEvent_EndFade", "Cabin_ReloadEndFade", 0);
	SetEventHandler("Control Activation", "TeleportToDeck", 1); // KK

	bDeckEnter = true;

	WhrDeleteRainEnvironment(); //JA 8DEC06 Stop it raining inside

	// SCREWFACE : New loading screen for small and medium cabin model
	ref mchr = GetMainCharacter();
// KK -->
	deckID = GetCharacterShipCabin(mchr);
	if (CheckAttribute(Locations[FindLocation(deckID)], "image")) SendMessage(&reload_fader, "ls", FADER_PICTURE, FindReloadPicture(Locations[FindLocation(DeckID)].image));
// <-- KK
	// SCREWFACE : END

	SendMessage(&reload_fader, "lfl", FADER_OUT, 1.0, false);
	SendMessage(&reload_fader, "l", FADER_STARTFRAME);

	PauseAllSounds();
	ResetSoundScheme();

	bAbordageStarted = true;
	bCabinStarted = true;
	Sea.AbordageMode = true;
	mchr.IsOnDeck = true;
}

//////////////
void Cabin_Start()
{
	ResetSoundScheme();
	PauseAllSounds();
	int i;
	//=астроим интерфейс
	if (LandLocationIdx == -1) DeleteBattleInterface(); // KK
	StartBattleLandInterface();

	deckID = "tutorial_deck";

	int locID = -1;
	locID = FindLocation(deckID);
	
	if(locID < 0)
	{
		Trace("Boarding: ship location not found <" + deckID + ">, set default");
		deckID = "";
		return;
	}

	ref mchr = GetMainCharacter();

	SetUpCabin(mchr); // KK
	SetUpDeckReloadMap(); // KK

	//Tыставим  и запомним адреса
	boarding_adr[0].location = mchr.location;
	boarding_adr[0].group = mchr.location.group;
	boarding_adr[0].locator = mchr.location.locator;
	for(i = 1; i < 4; i++)
	{
		int idx = GetOfficersIndex(mchr, i); // KK
		if(idx < 0)
		{
			boarding_adr[i].location = "";
			boarding_adr[i].group = "";
			boarding_adr[i].locator = "";
			continue;
		}
		boarding_adr[i].location = Characters[idx].location;
		boarding_adr[i].group = Characters[idx].location.group;
		boarding_adr[i].locator = Characters[idx].location.locator;
	}
	//Стартуем
	Cabin_LoadLocation();
	CreateEntity(&boarding_fader, "fader");
	SendMessage(&boarding_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);
}

//Загрузить локаци| абордажа
void Cabin_LoadLocation()
{
	ReloadProgressStart();
	//Lщем локаци|
	int locIndex = FindLocation(DeckID);
	if(locIndex >= 0)
	{
		//Устанавливаем главного персонажа
		ref mchr = GetMainCharacter();
		mchr.location = DeckID;
// KK -->
		if (FromDeckIdx == -1) {
			mchr.location.group = "rld";
			mchr.location.locator = "startloc";
		} else {
			mchr.location.group = "reload";
			mchr.location.locator = GetReloadMapAttrib(FromDeckIdx, current_locator_name, "emerge");
		}
		//chrWaitReloadLocator = "";
		chrWaitReloadIsNoLink = false;
		FromDeckIdx = -1;
		current_locator_name = "";

		//Устанавливаем офицеров, если такие есть
		int logined = 0;/*
		for(int i = 1; i < 4; i++) {
			int idx = GetOfficersIndex(mchr, i);
			if(idx < 0) continue;
			ref tmpChr = GetCharacter(idx);
			ChangeCharacterAddressGroup(tmpChr, "None", "", "");
			//SCREWFACE : to have officers on small and madium cabins too
			string cab = GetCharacterShipCabin(mchr);
			if (cab == "Cabin1" || cab == "Cabin2")
			{
				if (CheckAttribute(tmpChr,"quest.officertype"))
				{
					if (tmpChr.quest.officertype == OFFIC_TYPE_FIRSTMATE || tmpChr.quest.officertype == OFFIC_TYPE_NAVIGATOR || tmpChr.quest.officertype == OFFIC_TYPE_DOCTOR) {
				  	logined++;
						ChangeCharacterAddressGroup(tmpChr, mchr.location, "rld", "loc" + logined);
					}
				} else { // to have companions (not officers in cabin)
			  	logined++;
					ChangeCharacterAddressGroup(tmpChr, mchr.location, "rld", "loc" + logined);
				}
			}
			else
			{
				if(CheckAttribute(tmpChr,"quest.officertype"))
				{
					if (tmpChr.quest.officertype == OFFIC_TYPE_FIRSTMATE || tmpChr.quest.officertype == OFFIC_TYPE_NAVIGATOR || tmpChr.quest.officertype == OFFIC_TYPE_DOCTOR) {
						ChangeCharacterAddressGroup(tmpChr, mchr.location, "rld", "loc" + logined);
				  	logined++;
					}
				}
				else  // to have companions (not officers in cabin)
				{
					ChangeCharacterAddressGroup(tmpChr, mchr.location, "rld", "loc" + logined);
			  	logined++;
				}
				if (cab == "Cabin_small" && logined > 2) break;
			}
			// SCREWFACE : END
		}*/
// <-- KK

		//Перегружаемся в локаци|
		boarding_location = locIndex;
		Locations[locIndex].boarding = "true";
		if(LoadLocation(&Locations[locIndex]))
		{
			PlaceOfficersToDeck("Cabin");// MAXIMUS
			BLI_UpdateOfficers();//MAXIMUS: officers-icons fixed
			//Расставляем персонажей
			//SetEventHandler(EVENT_LOCATION_LOAD,"qprocEndReload",0);
			//Запретим диалог
			dialogDisable = false;
		}else{
			Trace("Boarding: Boarding location not loaded, current loc <" + DeckID + ">");
		}
	}else{
		Trace("Boarding: Boarding location not found, current loc <" + DeckID + ">");
	}

	WhrDeleteRainEnvironment(); // JA 8dec06 stop raining

	ReloadProgressEnd();
	PostEvent("LoadSceneSound", 500);
}

// KK -->
aref GetReloadMapRef(ref ReloadRef, string attrib, string value)
{
	int i = 0;
	int num = GetAttributesNum(ReloadRef);
	aref LocatorRef;
	for (i = 0; i < num; i++) {
		LocatorRef = GetAttributeN(ReloadRef, i);
		if (LocatorRef.(attrib) == value) return LocatorRef;
	}
	makearef(LocatorRef, NullCharacter);
	return LocatorRef;
}

string GetReloadMapAttrib(int locidx, string locator_name, string attrib)
{
	int i = 0;
	if (locidx == -1) return "";
	aref ReloadRef; makearef(ReloadRef, Locations[locidx].reload);
	int num = GetAttributesNum(ReloadRef);
	aref LocatorRef;
	for (i = 0; i < num; i++) {
		LocatorRef = GetAttributeN(ReloadRef, i);
		if (CheckAttribute(LocatorRef, "name") == true && LocatorRef.name == locator_name) break;//MAXIMUS
	}
	if (i == num) return "";
	if (!CheckAttribute(LocatorRef, attrib)) return "";
	return LocatorRef.(attrib);
}

string FindCurrentDeck()
{
	ref mchr = GetMainCharacter();
	if (!CheckAttribute(mchr, "location")) return "";
	if (HasSubStr(mchr.location, "ShipDeck")) return "ShipDeck";
	if (mchr.location == "Tutorial_Deck") return "Cabin";
	if (mchr.location == "seadogs") return mchr.location;
	if (HasSubStr(mchr.location, "Deck")) return "CannonsDeck";
	if (HasSubStr(mchr.location, "Hold")) return "Hold";
	return "";
}

void SetUpDeckReloadMap()
{
	ref mc = GetMainCharacter();
	string deck = GetCharacterShipQDeck(mc);
	int ncdecks = GetCharacterShipCannonsDeckCount(mc);
	int nholds = GetCharacterShipCargoHoldCount(mc);
	int ndecks = GetCharacterShipDeckCount(mc);
	int ideck = FindLocation(deck);
	int icabin = FindLocation("Tutorial_Deck");
	int iseadogs = FindLocation("Seadogs");
	int icdeck1 = FindLocation("Deck1");
	int icdeck2 = FindLocation("Deck2");
	int icdeck3 = FindLocation("Deck3");
	int ihold1 = FindLocation("Hold1");
	int ihold2 = FindLocation("Hold2");
	string tmpdeck = "";
	int itmpdeck = -1;

	if (ncdecks == 0) {
		Locations[iseadogs].reload.l1.go = "Hold1";
		Locations[iseadogs].reload.l1.emerge = "reload2";
		Locations[ihold1].reload.l2.go = "Seadogs";
		Locations[ihold1].reload.l2.emerge = "reload1";
	} else {
		Locations[iseadogs].reload.l1.go = "Deck1";
		Locations[iseadogs].reload.l1.emerge = "reload2";
		Locations[icdeck1].reload.l2.go = "Seadogs";
		Locations[icdeck1].reload.l2.emerge = "reload1";
	}

	if (ncdecks == 1) {
		Locations[icdeck1].id.label = "Main Cannons Deck";
		if (nholds == 1) {
			Locations[icdeck1].reload.l3.go = "Hold1";
			Locations[icdeck1].reload.l3.emerge = "reload1";
			Locations[icdeck1].reload.l4.go = "";
			Locations[icdeck1].reload.l4.emerge = "";
			Locations[ihold1].reload.l1.go = "Deck1";
			Locations[ihold1].reload.l1.emerge = "reload3";
			Locations[ihold1].reload.l2.go = "";
			Locations[ihold1].reload.l2.emerge = "";
		} else {
			Locations[icdeck1].reload.l3.go = "Hold1";
			Locations[icdeck1].reload.l3.emerge = "reload1";
			Locations[icdeck1].reload.l4.go = "";
			Locations[icdeck1].reload.l4.emerge = "";
			Locations[ihold1].reload.l1.go = "Deck1";
			Locations[ihold1].reload.l1.emerge = "reload3";
		}
	} else {
		tmpdeck = "Deck2";
		itmpdeck = icdeck2;
		if (ncdecks == 2) {
			tmpdeck = "Deck3";
			itmpdeck = icdeck3;
		}
		Locations[icdeck1].id.label = "Upper Cannons Deck";
		Locations[icdeck3].id.label = "Main Cannons Deck";
		Locations[icdeck1].reload.l3.go = tmpdeck;
		Locations[icdeck1].reload.l3.emerge = "reload2";
		Locations[icdeck1].reload.l4.go = tmpdeck;
		Locations[icdeck1].reload.l4.emerge = "reload1";
		Locations[itmpdeck].reload.l1.go = "Deck1";
		Locations[itmpdeck].reload.l1.emerge = "reload4";
		Locations[itmpdeck].reload.l2.go = "Deck1";
		Locations[itmpdeck].reload.l2.emerge = "reload3";
	}

	if (ncdecks == 3) {
		Locations[icdeck2].id.label = "Lower Cannons Deck";
		Locations[icdeck2].reload.l3.go = "Deck3";
		Locations[icdeck2].reload.l3.emerge = "reload2";
		Locations[icdeck2].reload.l4.go = "Deck3";
		Locations[icdeck2].reload.l4.emerge = "reload1";
		Locations[icdeck3].reload.l1.go = "Deck2";
		Locations[icdeck3].reload.l1.emerge = "reload4";
		Locations[icdeck3].reload.l2.go = "Deck2";
		Locations[icdeck3].reload.l2.emerge = "reload3";
	}

	if (ncdecks > 1 && nholds > 0) {
		Locations[icdeck3].reload.l3.go = "Hold1";
		Locations[icdeck3].reload.l3.emerge = "reload1";
		Locations[ihold1].reload.l1.go = "Deck3";
		Locations[ihold1].reload.l1.emerge = "reload3";
	}

	if (nholds == 2) {
		Locations[ihold1].id.label = "1st Cargo Hold";
		Locations[ihold1].reload.l2.go = "Hold2";
		Locations[ihold1].reload.l2.emerge = "reload2";
		Locations[ihold2].id.label = "2nd Cargo Hold";
		Locations[ihold2].reload.l2.go = "Hold1";
		Locations[ihold2].reload.l2.emerge = "reload2";
		Locations[ihold2].reload.l1.go = "";
		Locations[ihold2].reload.l1.emerge = "";
	} else {
		Locations[ihold1].id.label = "Cargo Hold";
	}

	Locations[icabin].reload.l1.go = deck;
	Locations[icabin].reload.l1.emerge = "reload1";
	Locations[ideck].reload.l1.go = "Tutorial_Deck";
	Locations[ideck].reload.l1.emerge = "reload1";

	if (deck == "ShipDeck2" || deck == "ShipDeck4" || deck == "ShipDeck6") {
		Locations[ideck].reload.l7.go = "Tutorial_Deck";
		Locations[ideck].reload.l7.emerge = "reload1";
	}

	if (deck != "ShipDeck6") {
		Locations[iseadogs].reload.l2.go = deck;
		Locations[iseadogs].reload.l2.emerge = "reload2";
		Locations[ideck].reload.l2.go = "Seadogs";
		Locations[ideck].reload.l2.emerge = "reload2";
	}

	if(ncdecks > 0) {
		tmpdeck = "Deck1";
		itmpdeck = icdeck1;
	} else {
		tmpdeck = "Hold1";
		itmpdeck = ihold1;
	}
	if (deck != "ShipDeck3") {
		Locations[itmpdeck].reload.l1.go = deck;
		Locations[itmpdeck].reload.l1.emerge = "reload3";
		Locations[ideck].reload.l3.go = tmpdeck;
		Locations[ideck].reload.l3.emerge = "reload1";
	}
	if (deck == "ShipDeck6") {
		Locations[ideck].reload.l8.go = tmpdeck;
		Locations[ideck].reload.l8.emerge = "reload1";
	}

	if (ndecks == 0) {
		Locations[ideck].reload.l1.go = "";
		Locations[ideck].reload.l1.emerge = "";
		Locations[ideck].reload.l2.go = "";
		Locations[ideck].reload.l2.emerge = "";
		Locations[ideck].reload.l3.go = "";
		Locations[ideck].reload.l3.emerge = "";
		if (deck == "ShipDeck2") {
			Locations[ideck].reload.l7.go = "";
			Locations[ideck].reload.l7.emerge = "";
		}
	}

	if(!bCanEnterToLand)
	{
		Locations[ideck].reload.l4.go = "";
		Locations[ideck].reload.l4.emerge = "";
		Locations[ideck].reload.l5.go = "";
		Locations[ideck].reload.l5.emerge = "";
	}
	else
	{
		aref LocatorRef;
		if(LandLocationIdx==-1) { LocatorRef = GetReloadMapRef(arIslandReload, "name", sIslandLocator); }
		else
		{
			int fslocidx = FindLocation(mc.location.from_sea);
			if (fslocidx < 0) return;
			string island = Locations[fslocidx].island;
			if (island=="") return;
			ref IslandRef = GetIslandByID(island);
			if (!CheckAttribute(IslandRef, "reload")) return;
			aref IslandReload; makearef(IslandReload, IslandRef.reload);
			LocatorRef = GetReloadMapRef(IslandReload, "go", mc.location.from_sea);
		}
		if (LocatorRef == NullCharacter) return;
		Locations[ideck].reload.l4.go = LocatorRef.go;
		Locations[ideck].reload.l4.emerge = LocatorRef.emerge;
		Locations[ideck].reload.l5.go = LocatorRef.go;
		Locations[ideck].reload.l5.emerge = LocatorRef.emerge;
	}
}

void DeckToSea_ReloadStartFadeAfter()
{
	ResetSoundScheme();
	PauseAllSounds();
	DelEventHandler("FaderEvent_StartFade", "DeckToSea_ReloadStartFadeAfter");

	UnloadDeck();
	Sea.MaxSeaHeight = fOldMaxSeaHeight;
}

void DeckToSea_ReloadEndFadeAfter()
{
	ReloadProgressStart();

	DelEventHandler("FaderEvent_EndFade", "DeckToSea_ReloadEndFadeAfter");
	SendMessage(&boarding_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);

	ref mchr = GetMainCharacter();
	if(!CheckAttribute(mchr,"location.from_sea")) return;
	int fslocidx = FindLocation(mchr.location.from_sea);
	if (fslocidx < 0) return;
	string island = Locations[fslocidx].island;
	if (!CheckAttribute(Locations[fslocidx], "reload")) return;
	aref PortReload; makearef(PortReload, Locations[fslocidx].reload);
	aref LocatorRef = GetReloadMapRef(PortReload, "go", island);
	lockedReloadLocator = "";
	chrWaitReloadLocator = "";
	chrWaitReloadIsNoLink = false;
	ReloadToSea(FindIsland(island), LocatorRef);

	MoveSeaToLayers(SEA_EXECUTE, SEA_REALIZE); //JA 8Dec06 Fix a bug where if you came from land to deck, then to sea-view, the Sea was missing

	bDeckEnter = false;
	LandLocationIdx = -1;

	Log_SetActiveAction("Nothing");
	BLI_RefreshCommandMenu();

	SendMessage(&reload_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);
	PostEvent("LoadSceneSound", 500);

	Whr_UpdateWeather(false); //JA 8DEC06 on deck so resume raining

	ReloadProgressEnd();
}

void UnloadDeck()
{
	bDeckStarted = false;
	bCabinStarted = false;
	bCrewStarted = false;
	Sea.AbordageMode = false;
	bAbordageStarted = false;
	DelEventHandler("Control Activation", "TeleportToDeck");
	ref mchr = GetMainCharacter();
//	DeleteSeaEnvironment(); //JA 5DEC06 I think this was unloading your own ship model as well as all other models on the sea
	EndBattleLandInterface();
	Log_SetActiveAction("Nothing");
	Characters[GetMainCharacterIndex()].activeItem = "";
	BLI_RefreshCommandMenu();
	if (FindLoadedLocation() >= 0) UnloadLocation(&Locations[FindLoadedLocation()]);
	if (boarding_location >= 0) DeleteAttribute(Locations[boarding_location], "boarding");
	boarding_location = -1;
	if (!CheckAttribute(boarding_adr[0], "location")) return;
	mchr.location = boarding_adr[0].location;
	mchr.location.group = boarding_adr[0].group;
	mchr.location.locator = boarding_adr[0].locator;
	for (int i = 1; i < 4; i++) {
		int idx = GetOfficersIndex(mchr, i);
		if (idx < 0) continue;
		Characters[idx].location = boarding_adr[i].location;
		Characters[idx].location.group = boarding_adr[i].group;
		Characters[idx].location.locator = boarding_adr[i].locator;
	}
}

void Deck_GoBack()
{
	if(dialogRun || dialogSelf)//MAXIMUS -->
	{
		traceif("Can't reload...");
		traceif("BOAL_Deck: character is in dialog");
		return;
	}//MAXIMUS <--
	if(CheckAttribute(GetMainCharacter(),"lastlocation")) LandLocationIdx = sti(characters[GetMainCharacterIndex()].lastlocation);
	if (LandLocationIdx == -1) {
		Land_ToPort();
		return;
	}

//	if(CheckAttribute(Locations[LandLocationIdx], "townsack")) { DeleteSeaEnvironment(); }//JA 8DEC06 If returning to a town building.//MAXIMUS: moved from here to DeckBack_ReloadEndFadeAfter()

	SetEventHandler("FaderEvent_StartFade", "DeckBack_ReloadStartFadeAfter", 0);
	SetEventHandler("FaderEvent_EndFade", "DeckBack_ReloadEndFadeAfter", 0);

	CreateEntity(&boarding_fader, "fader");
	if (CheckAttribute(&Locations[LandLocationIdx], "image")) SendMessage(&boarding_fader, "ls", FADER_PICTURE, FindReloadPicture(Locations[LandLocationIdx].image));

	float fadeOutTime = RELOAD_TIME_FADE_OUT;

	SendMessage(&boarding_fader, "lfl", FADER_OUT, fadeOutTime, false);
	SendMessage(&boarding_fader, "l", FADER_STARTFRAME);
	if(CheckAttribute(GetMainCharacter(),"IsOnDeck")) DeleteAttribute(GetMainCharacter(),"IsOnDeck");
}

void DeckBack_ReloadStartFadeAfter()
{
	ResetSoundScheme();
	PauseAllSounds();
	DelEventHandler("FaderEvent_StartFade", "DeckBack_ReloadStartFadeAfter");

	UnloadDeck();
	Sea.MaxSeaHeight = fOldMaxSeaHeight;
}

void DeckBack_ReloadEndFadeAfter()
{
	ReloadProgressStart();

	DelEventHandler("FaderEvent_EndFade", "DeckBack_ReloadEndFadeAfter");
	SendMessage(&boarding_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);

	ref mchr = GetMainCharacter();
	mchr.location = Locations[LandLocationIdx].id;
	mchr.location.group = "reload";
	mchr.location.locator = LandLocator;
	if(!CheckAttribute(&Locations[LandLocationIdx],"environment.sea") || Locations[LandLocationIdx].environment.sea!="true") DeleteSeaEnvironment();//MAXIMUS
	if(!CheckAttribute(&Locations[LandLocationIdx],"environment.weather") || Locations[LandLocationIdx].environment.weather!="true") DeleteWeatherEnvironment();//MAXIMUS
	if (LoadLocation(&Locations[LandLocationIdx]))
		dialogDisable = false;
	else
		Trace("ReturnFromShip: location not loaded, current loc <" + mchr.location + ">");
	lockedReloadLocator = "";
	chrWaitReloadLocator = "";
	chrWaitReloadIsNoLink = false;
	for (int i = 0; i < 4; i++) {
		int idx = GetOfficersIndex(mchr, i);
		if (idx == -1) continue;
		TeleportCharacterToPosAy(GetCharacter(idx), Land_posx[i], Land_posy[i], Land_posz[i], Land_angle[i]);
	}

	bDeckEnter = false;
	LandLocationIdx = -1;

	Log_SetActiveAction("Nothing");
	BLI_RefreshCommandMenu();

	PauseAllSounds();
	ResetSoundScheme();

	ReloadProgressEnd();
}

void TeleportToDeck()
{
	if(dialogRun || dialogSelf)//MAXIMUS -->
	{
		traceif("Can't reload...");
		traceif("BOAL_Deck: character is in dialog");
		return;
	}//MAXIMUS <--
	if (chrWaitReloadLocator == "") return;
	string controlName = GetEventData();
	if (controlName != "ChrAction") return;
	FromDeckIdx = FindLoadedLocation();
	current_locator_name = chrWaitReloadLocator;
	if (HasSubStr(chrWaitReloadLocator, "boat")) {
		Land_ToPort();
		Log_SetActiveAction("Nothing");
		BLI_RefreshCommandMenu();
		return;
	}
	string target = GetReloadMapAttrib(FromDeckIdx, chrWaitReloadLocator, "go");
	if (target == "") return;
	UnloadDeck();
	if (bToDeckFromLand) {
		switch (target) {
			case "Tutorial_Deck":
				Land_CabinStartNow();
			break;
			case "Sea":
				Return2SeaAfterDeck();
			break;
			// default:
				Land_DeckStartNow(target);
		}
	} else {
		switch (target) {
			case "Tutorial_Deck":
				Sea_CabinStartNow();
			break;
			case "Sea":
				Return2SeaAfterDeck();
			break;
			// default:
				Sea_DeckStartNow(target);
		}
	}
	Log_SetActiveAction("Nothing");
	BLI_RefreshCommandMenu();
}

void TransferToDeck(string finishLocName)
{
	if(dialogRun || dialogSelf)//MAXIMUS -->
	{
		traceif("Can't reload...");
		traceif("BOAL_Deck: character is in dialog");
		return;
	}//MAXIMUS <--
	if (finishLocName == "") return;

	UnloadDeck();
	if (bToDeckFromLand) {
		switch (finishLocName) {
			case "Cabin":
				Land_CabinStartNow();
			break;
			case "ShipDeck":
				Land_DeckStartNow(GetCharacterShipQDeck(GetMainCharacter()));
			break;
			case "Port":
				Land_ToPort();
			break;
			// default:
				Land_DeckStartNow(finishLocName);
		}
	} else {
		switch (finishLocName) {
			case "Cabin":
				Sea_CabinStartNow();
			break;
			case "ShipDeck":
				Sea_DeckStartNow(GetCharacterShipQDeck(GetMainCharacter()));
			break;
			case "Port":
				Land_ToPort();
			break;
			// default:
				Sea_DeckStartNow(finishLocName);
		}
	}
	Log_SetActiveAction("Nothing");
	BLI_RefreshCommandMenu();
}

void Land_DeckStartNow(string deckname)
{
	bToDeckFromLand = true;

	ref mchr = GetMainCharacter();
	if (LandLocationIdx == -1) {
		LandLocationIdx = FindLoadedLocation();
		mchr.lastlocation = FindLoadedLocation();
		for (int i = 0; i < 4; i++) {
			int idx = GetOfficersIndex(mchr, i);
			if (idx == -1) continue;
			GetCharacterPos(GetCharacter(idx), &Land_posx[i], &Land_posy[i], &Land_posz[i]);
			GetCharacterAy(GetCharacter(idx), &Land_angle[i]);
		}
		LandLocator = LAi_FindRandomLocator("reload");
		bCanEnterToLand = true;
	}

	bSeaReloadStarted = true;

	object reload_fader;
	CreateEntity(&reload_fader, "fader");
	SetEventHandler("FaderEvent_StartFade", "LandDeck_ReloadStartFade", 0);
	SetEventHandler("FaderEvent_EndFade", "LandDeck_ReloadEndFade", 0);
	SetEventHandler("Control Activation", "TeleportToDeck", 1);

	bDeckEnter = true;

	deckID = deckname;
	if (!bEmergeOnStartloc == true && HasSubStr(deckname, "ShipDeck") == true) {
		SendMessage(&reload_fader, "ls", FADER_PICTURE, FindReloadPicture("Landing.tga"));
	} else {
		if (CheckAttribute(Locations[FindLocation(deckID)], "image")) SendMessage(&reload_fader, "ls", FADER_PICTURE, FindReloadPicture(Locations[FindLocation(DeckID)].image)); 
	}

	SendMessage(&reload_fader, "lfl", FADER_OUT, 1.0, false);
	SendMessage(&reload_fader, "l", FADER_STARTFRAME);

	PauseAllSounds();
	ResetSoundScheme();

	bAbordageStarted = true;
	bDeckStarted = true;
	if (deckID == "seadogs") bCrewStarted = true;
	Sea.AbordageMode = true;
	mchr.IsOnDeck = true;
}

void LandDeck_ReloadStartFade()
{
	ref mchr = GetMainCharacter();
	if (FindLocation(mchr.location) >= 0) UnloadLocation(&Locations[FindLocation(mchr.location)]);

	DelEventHandler("FaderEvent_StartFade", "LandDeck_ReloadStartFade");
}

void LandDeck_ReloadEndFade()
{
	int a = GetEventData();
	aref reload_fader = GetEventData();
	
	Deck_Start();

	if (CheckAttribute(Sea, "MaxSeaHeight")) {
		fOldMaxSeaHeight = stf(Sea.MaxSeaHeight);
		Sea.MaxSeaHeight = 1.2;
	}
	
	DelEventHandler("FaderEvent_EndFade", "LandDeck_ReloadEndFade");
	SendMessage(&reload_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);
}

void Land_ToPort()
{
	DeckID = "";
	FromDeckIdx = -1;
	DelEventHandler("Control Activation", "TeleportToDeck");

	Whr_UpdateWeather(false); //JA 8DEC06 Resume weather if leaving cabin/deck

	if(CheckAttribute(GetMainCharacter(),"IsOnDeck")) DeleteAttribute(GetMainCharacter(),"IsOnDeck");

	if (LandLocationIdx == -1) {
		UnloadDeck();
		DeleteShipEnvironment();
		Sea_LandLoad();
		bDeckEnter = false;
	} else {
		SetEventHandler("FaderEvent_StartFade", "LandToPort_ReloadStartFadeAfter", 0);
		SetEventHandler("FaderEvent_EndFade", "LandToPort_ReloadEndFadeAfter", 0);

		ref mchr = GetMainCharacter();
		CreateEntity(&boarding_fader, "fader");
		if (CheckAttribute(&Locations[FindLocation(mchr.location.from_sea)], "image")) SendMessage(&boarding_fader, "ls", FADER_PICTURE, FindReloadPicture(Locations[FindLocation(mchr.location.from_sea)].image));

		float fadeOutTime = RELOAD_TIME_FADE_OUT;

		SendMessage(&boarding_fader, "lfl", FADER_OUT, fadeOutTime, false);
		SendMessage(&boarding_fader, "l", FADER_STARTFRAME);
	}
}

void LandToPort_ReloadStartFadeAfter()
{
	ResetSoundScheme();
	PauseAllSounds();
	DelEventHandler("FaderEvent_StartFade", "LandToPort_ReloadStartFadeAfter");

	UnloadDeck();

	Sea.MaxSeaHeight = fOldMaxSeaHeight;
}

void LandToPort_ReloadEndFadeAfter()
{
	ReloadProgressStart();

	DelEventHandler("FaderEvent_EndFade", "LandToPort_ReloadEndFadeAfter");
	SendMessage(&boarding_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);

	ref mchr = GetMainCharacter();
	int fslocidx = FindLocation(mchr.location.from_sea);
	if (fslocidx < 0) return;
	string island = Locations[fslocidx].island;
	ref IslandRef = GetIslandByID(island);
	if (!CheckAttribute(IslandRef, "reload")) return;
	aref IslandReload; makearef(IslandReload, IslandRef.reload);
	aref TownReload = GetReloadMapRef(IslandReload, "go", mchr.location.from_sea)
	mchr.location = TownReload.go;
	mchr.location.group = "reload";
	mchr.location.locator = TownReload.emerge;
	if (LoadLocation(&Locations[FindLocation(mchr.location)]))
		dialogDisable = false;
	else
		Trace("ReturnFromShip: location not loaded, current loc <" + mchr.location + ">");
	lockedReloadLocator = "";
	chrWaitReloadLocator = "";
	chrWaitReloadIsNoLink = false;

	bDeckEnter = false;
	LandLocationIdx = -1;

	Log_SetActiveAction("Nothing");
	BLI_RefreshCommandMenu();

	PauseAllSounds();
	ResetSoundScheme();

	ReloadProgressEnd();
}

void SetUpCabin(ref chr)
{
	int locID = FindLocation("Tutorial_Deck");

	// SCREWFACE : To have small and medium model of Cabin when for different shipclass
	// Keep the same location and only change the model is very important to have weapons locker
	string cabinID = GetCharacterShipCabin(chr);
	if (cabinID == "Cabin_none") return;
	if (cabinID != "Tutorial_Deck") {
		int cabinloc = FindLocation(cabinID);
		Locations[locID].filespath.models = Locations[cabinloc].filespath.models;
		Locations[locID].image = Locations[cabinloc].image;
		Locations[locID].models.always.locators = Locations[cabinloc].models.always.locators;
		Locations[locID].models.always.l1 = Locations[cabinloc].models.always.l1;
		Locations[locID].models.day.charactersPatch = Locations[cabinloc].models.day.charactersPatch;
		Locations[locID].models.day.fonar = Locations[cabinloc].models.day.fonar;
		Locations[locID].models.night.charactersPatch = Locations[cabinloc].models.night.charactersPatch;
		Locations[locID].models.night.fonar = Locations[cabinloc].models.night.fonar;
		if (CheckAttribute(Locations[cabinloc], "models.always.window"))
			Locations[locID].models.always.window = Locations[cabinloc].models.always.window;
		else
			Locations[locID].models.always.window = "";
	} else {
		Locations[locID].filespath.models = "locations\decks\cabin\tut_deck";
		Locations[locID].image = "Cabin.tga";
		Locations[locID].models.always.locators = "tut_Deck_ld";
		Locations[locID].models.always.l1 = "tut_Deck";
		Locations[locID].models.day.charactersPatch = "tut_Deck_p";
		Locations[locID].models.day.fonar = "tut_Deck_fd";
		Locations[locID].models.night.charactersPatch = "tut_Deck_p";
		Locations[locID].models.night.fonar = "tut_Deck_fn";
		Locations[locID].models.always.window = "tut_deck_w";
	}
}

void Land_CabinStartNow()
{
	bToDeckFromLand = true;

	ref mchr = GetMainCharacter();
	if (LandLocationIdx == -1) {
		LandLocationIdx = FindLoadedLocation();
		for (int i = 0; i < 4; i++) {
			int idx = GetOfficersIndex(mchr, i);
			if (idx == -1) continue;
			GetCharacterPos(GetCharacter(idx), &Land_posx[i], &Land_posy[i], &Land_posz[i]);
			GetCharacterAy(GetCharacter(idx), &Land_angle[i]);
		}
		LandLocator = LAi_FindRandomLocator("reload");
		bCanEnterToLand = true;
	}

	bSeaReloadStarted = true;

	object reload_fader;
	CreateEntity(&reload_fader, "fader");
	SetEventHandler("FaderEvent_StartFade", "LandCabin_ReloadStartFade", 0);
	SetEventHandler("FaderEvent_EndFade", "LandCabin_ReloadEndFade", 0);
	SetEventHandler("Control Activation", "TeleportToDeck", 1);

	bDeckEnter = true;

	deckID = GetCharacterShipCabin(mchr);
	if (CheckAttribute(Locations[FindLocation(deckID)], "image")) SendMessage(&reload_fader, "ls", FADER_PICTURE, FindReloadPicture(Locations[FindLocation(DeckID)].image));
	SendMessage(&reload_fader, "lfl", FADER_OUT, 1.0, false);
	SendMessage(&reload_fader, "l", FADER_STARTFRAME);

	PauseAllSounds();
	ResetSoundScheme();

	bAbordageStarted = true;
	bCabinStarted = true;
	Sea.AbordageMode = true;
	mchr.IsOnDeck = true;
}

void LandCabin_ReloadStartFade()
{
	ref mchr = GetMainCharacter();
	if (FindLocation(mchr.location) >= 0) UnloadLocation(&Locations[FindLocation(mchr.location)]);

	DelEventHandler("FaderEvent_StartFade", "LandCabin_ReloadStartFade");
}

void LandCabin_ReloadEndFade()
{
	int a = GetEventData();
	aref reload_fader = GetEventData();

	Cabin_Start();

	if (CheckAttribute(Sea, "MaxSeaHeight")) {
		fOldMaxSeaHeight = stf(Sea.MaxSeaHeight);
		Sea.MaxSeaHeight = 1.2;
	}

	DelEventHandler("FaderEvent_EndFade", "LandCabin_ReloadEndFade");
	SendMessage(&reload_fader, "lfl", FADER_IN, RELOAD_TIME_FADE_IN, true);
}
// <-- KK

//MAXIMUS -->
void PlaceOfficersToDeck(string deckType)
{
	ref mchr = GetMainCharacter();
	ref tmpChr;
	int i, _curCharIdx, logined;
	aref pRef; makearef(pRef,mchr.Fellows.Passengers);
	string PsgAttrName;
	switch(deckType)
	{
		case "Deck":
			logined = 1;
			for(i=1; i<GetPassengersQuantity(mchr); i++)
			{
				PsgAttrName = "id"+(i+1);
				_curCharIdx = sti(pRef.(PsgAttrName));
				tmpChr = GetCharacter(_curCharIdx);
				if(!CheckAttribute(tmpChr,"prisoned") && CheckAttribute(tmpChr,"quest.officertype"))
				{
					switch(FindCurrentDeck())
					{
						case "CannonsDeck":
							if(tmpChr.quest.officertype==OFFIC_TYPE_CANNONEER)
							{
								CharacterIntoLocationLocator(_curCharIdx, mchr.location);
								LAi_SetPatrolType(tmpChr);
							}
						break;
						case "Hold":
							if(tmpChr.quest.officertype==OFFIC_TYPE_CARPENTER)
							{
								CharacterIntoLocationLocator(_curCharIdx, mchr.location);
								LAi_SetPatrolType(tmpChr);
							}
						break;
						case "ShipDeck":
							if(GetCharacterShipCabin(mchr)=="Cabin_none")
							{
								CharacterIntoLocationLocator(_curCharIdx, mchr.location);
								LAi_SetPatrolType(tmpChr);
							}
							else
							{
								if(tmpChr.quest.officertype==OFFIC_TYPE_ABORDAGE || tmpChr.quest.officertype==OFFIC_TYPE_CANNONEER || tmpChr.quest.officertype==OFFIC_TYPE_CAPNAVY) // KK
								{
									CharacterIntoLocationLocator(_curCharIdx, mchr.location);
									LAi_SetPatrolType(tmpChr);
								}
							}
						break;
						case "Seadogs":
							if(tmpChr.quest.officertype==OFFIC_TYPE_BOATSWAIN || tmpChr.quest.officertype==OFFIC_TYPE_DOCTOR || tmpChr.quest.officertype==OFFIC_TYPE_QMASTER || tmpChr.quest.officertype==OFFIC_TYPE_ABORDAGE)
							{
								CharacterIntoLocationLocator(_curCharIdx, mchr.location);
								LAi_SetPatrolType(tmpChr);
							}
						break;
					}
					//JRH -->
					string weaponID = GetCharacterEquipByGroup(mchr,GUN_ITEM_TYPE);
					aref weapon;
					Items_FindItem(weaponID, &weapon);

					int s; //shots
					int ShCl = makeint(GetCharacterShipClass(mchr));
					if(ENABLE_AMMOMOD)
					{// TIH --> mod toggle 7-7-06
						if(CheckAttribute(weapon, "shottype"))
						{
							if(weapon.shottype == "pg2" || weapon.shottype == "pg" || weapon.shottype == "mb" || weapon.shottype == "pb")
							{// TIH --> adjustments of code Jul16'06
								if(CheckAttribute(tmpChr,"quest.officertype") && tmpChr.quest.officertype=="cannoneer")
								{
									int priorGP = GetCharacterItem(mchr,"gunpowder");
									int priorPB = GetCharacterItem(mchr,"pistolbullets");
									int priorPG = GetCharacterItem(mchr,"pistolgrapes");
									int priorMB = GetCharacterItem(mchr,"musketbullets");

									DeleteAttribute(mchr,"Items.gunpowder");
									DeleteAttribute(mchr,"Items.pistolbullets");
									DeleteAttribute(mchr,"Items.pistolgrapes");
									DeleteAttribute(mchr,"Items.musketbullets");

									// we dont inform about just getting gunpowder
									if(CheckCharacterItem(mchr,"powderflask")) { TakeNItems(mchr,"gunpowder", 12); }
									else { TakeNItems(mchr,"gunpowder", 6); }
									if(CheckCharacterItem(mchr,"ammopouch")) { s = 12; }	
									else { s = 6; }

									if(weapon.shottype == "mb") { s /= 2; }// can only carry half for muskets

									string strAmmoLoaded;
									bool doInform = false;
									if(weapon.shottype == "pb")  { TakeNItems(mchr,"pistolbullets", s); strAmmoLoaded = "Pistol"; 	 if (s > priorPB) { doInform = true; } }
									if(weapon.shottype == "pg")  { TakeNItems(mchr,"pistolgrapes", s);  strAmmoLoaded = "Grapeshot"; if (s > priorPG) { doInform = true; } }
									if(weapon.shottype == "pg2") { TakeNItems(mchr,"pistolgrapes", s);  strAmmoLoaded = "Grapeshot"; if (s > priorPG) { doInform = true; } }
									if(weapon.shottype == "mb")  { TakeNItems(mchr,"musketbullets", s); strAmmoLoaded = "Musket"; 	 if (s > priorMB) { doInform = true; } }

									if(doInform)
									{
										Log_SetStringToLog("The Gunner has provided you with "+ strAmmoLoaded +" Ammunition!");
										PlaySound("INTERFACE\important_item.wav");
									}
								}// TIH <-- adjustments
							}
						}
					}// TIH <-- mod toggle
					//<-- JRH
				}
			}
			PostEvent("SetAnotherType", 2500 , "i", mchr);
		break;

		case "Cabin":
			logined = 1;
			for(i = 1; i < 4; i++)
			{
				_curCharIdx = GetOfficersIndex(mchr, i);
				if(_curCharIdx < 0) continue;
				tmpChr = GetCharacter(_curCharIdx);
				if(CheckAttribute(tmpChr,"quest.officertype"))
				{
					bool bPlace = false;
					switch(Rand(4))
					{
						case 0: bPlace = tmpChr.quest.officertype==OFFIC_TYPE_FIRSTMATE; break;
						case 1: bPlace = tmpChr.quest.officertype==OFFIC_TYPE_NAVIGATOR; break;
						case 2: bPlace = tmpChr.quest.officertype==OFFIC_TYPE_BOATSWAIN; break;
						case 3: bPlace = tmpChr.quest.officertype==OFFIC_TYPE_QMASTER; break;
						case 4: bPlace = tmpChr.quest.officertype==OFFIC_TYPE_DOCTOR; break;
					}
					if(bPlace)
					{
						ChangeCharacterAddressGroup(tmpChr, "None", "", "");
						CharacterIntoLocationLocator(_curCharIdx, mchr.location);
						logined++;
					}
// KK -->
					if (mchr.location == "Cabin_small" && logined > 2) break;
/*					if(cab=="Cabin1" || cab=="Cabin2")
					{
						if(tmpChr.quest.officertype==OFFIC_TYPE_FIRSTMATE || tmpChr.quest.officertype==OFFIC_TYPE_NAVIGATOR || tmpChr.quest.officertype==OFFIC_TYPE_DOCTOR)
						{
							CharacterIntoLocationLocator(_curCharIdx, mchr.location);
						}
						else
						{// to have companions (not officers in cabin)
							if (tmpChr.quest.officertype != OFFIC_TYPE_CANNONEER && tmpChr.quest.officertype != OFFIC_TYPE_ABORDAGE && tmpChr.quest.officertype != OFFIC_TYPE_BOATSWAIN && tmpChr.quest.officertype != OFFIC_TYPE_QMASTER)
								CharacterIntoLocationLocator(_curCharIdx, mchr.location);
						}
					}
					else
					{
						if(tmpChr.quest.officertype==OFFIC_TYPE_FIRSTMATE || tmpChr.quest.officertype==OFFIC_TYPE_NAVIGATOR || tmpChr.quest.officertype==OFFIC_TYPE_DOCTOR)
						{
							CharacterIntoLocationLocator(_curCharIdx, mchr.location);
						}
						else
						{// to have companions (not officers in cabin)
							if (tmpChr.quest.officertype != OFFIC_TYPE_CANNONEER && tmpChr.quest.officertype != OFFIC_TYPE_ABORDAGE && tmpChr.quest.officertype != OFFIC_TYPE_BOATSWAIN && tmpChr.quest.officertype != OFFIC_TYPE_QMASTER)
								CharacterIntoLocationLocator(_curCharIdx, mchr.location);
						}
					}*/// SCREWFACE : END
					if(!IsOfficer(tmpChr)) continue;
					CharacterIntoLocationLocator(_curCharIdx, mchr.location);
// <-- KK
				}
			}
		break;
	}
	for(i=1; i<GetPassengersQuantity(mchr); i++)
	{
		PsgAttrName = "id"+(i+1);
		_curCharIdx = sti(pRef.(PsgAttrName));
		tmpChr = GetCharacter(_curCharIdx);
		if(IsOfficer(tmpChr)) continue;
		if(!CheckAttribute(tmpChr,"prisoned") && CheckAttribute(tmpChr,"quest.officertype"))
		{
			LAi_ClearIndexedLocators(mchr.location, tmpChr.location.group);
		}
	}
}

#event_handler("SetAnotherType", "AnotherType");
void AnotherType()
{
	ref mchr = GetMainCharacter();
	for(int i=1; i<GetPassengersQuantity(mchr); i++)
	{
		aref pRef; makearef(pRef,mchr.Fellows.Passengers);
		string PsgAttrName = "id"+(i+1);
		int _curCharIdx = sti(pRef.(PsgAttrName));
		ref tmpChr = GetCharacter(_curCharIdx);
		if(IsOfficer(tmpChr)) continue;
		if(!CheckAttribute(tmpChr,"prisoned") && CheckAttribute(tmpChr,"quest.officertype"))
		{
			LAi_SetCitizenType(tmpChr);
		}
	}
}
//MAXIMUS <--
