object objLandInterface;
object objFastReloadTable;
// NK 05-04-23 switch to towns[] object objTownStateTable;
int g_intRetVal;

bool bDisableFastReload = false;

#define	BLI_UPDATE_PERIOD	500
#event_handler("evntBattleCommandSound","procBattleCommandSound");

bool bLandInterfaceStart = false;

void procBattleCommandSound()
{
	string comName = GetEventData();
	if(comName=="deactivate")
	{
		PlaySound("interface\ok.wav");
	}
	if(comName=="activate")
	{
		PlaySound("interface\ok.wav");
	}
	if(comName=="right" || comName=="left")
	{
		PlaySound("interface\ok.wav");
	}
}

void InitBattleLandInterface()
{
	bLandInterfaceStart = false;
	SetEventHandler(EVENT_LOCATION_LOAD,"StartBattleLandInterface",0);
	SetEventHandler(EVENT_LOCATION_UNLOAD,"EndBattleLandInterface",0);
	LoadLIStates();
}

void BLI_EnableShow()
{
	SetLandInterfaceShow(sti(InterfaceStates.BattleShow.Command));
}

void BLI_DisableShow()
{
	SetLandInterfaceShow(false);
}

void StartBattleLandInterface()
{
	if(bLandInterfaceStart)
	{
		BLI_SetObjectData();
		return;
	}
	bLandInterfaceStart = true;

	BLI_SetShowParameters();
	CreateEntity(&objLandInterface,"battle_land_interface");
	DeleteAttribute(&objLandInterface,"");
	LayerAddObject("execute",&objLandInterface,-1);
	LayerAddObject("realize",&objLandInterface,-1);

	SetEventHandler(EVENT_CHANGE_OFFICERS,"BLI_UpdateOfficers",0);
	SetEventHandler(EVENT_DIALOG_START,"BLI_DisableShow",0);
	SetEventHandler(EVENT_DIALOG_EXIT,"BLI_EnableShow",0);

	BLI_SetObjectData();

	if(dialogRun) BLI_DisableShow();
	else BLI_EnableShow();

	SetEventHandler("evntBLI_Update","BLI_UpdateObjectData",0);
	SetEventHandler("BI_CommandEndChecking","BLI_CheckCommand",0);
	SetEventHandler("BI_LaunchCommand","BLI_ExecuteCommand",0);
	SetEventHandler("BI_SetPossibleCommands","BLI_SetPossibleCommands",0);
	SetEventHandler("evntFindDialogChar","procFindDialogChar",0);
	SetEventHandler("Location_CharacterEntryToLocator", "BLI_ChrEnterToLocation", 0);
	SetEventHandler("Location_CharacterExitFromLocator", "BLI_ChrExitFromLocation", 0);
	SetEventHandler("evntPerkAgainUsable","BLI_RefreshCommandMenu",0);

	Event("evntBLI_Update");
	Event("evntFindDialogChar");
}

ref BLI_CheckCommand()
{
	string commandName = GetEventData();

	aref uiref;	makearef(uiref,objLandInterface.UserIcons);
	aref ar;
	int nq = GetAttributesNum(uiref);
	int i;

	ref pchar = GetMainCharacter(); // Viper - Emblemed Sails v2

	bool bUsed = false;
	for(i=0; i<nq; i++)
	{
		ar = GetAttributeN(uiref,i);
		ar.enable = false;
	}
	g_intRetVal = BI_COMMODE_USER_ICONS;

	switch(commandName)
	{
// KK -->
		case "BI_EnterShip":
			bUsed = SetShipIcons();
			break;

		case "BI_EnterTartane":
			bToDeckFromLand = true;
			Land_DeckStartNow(GetCharacterShipQDeck(pchar));
			g_intRetVal = 0;
			break;
		// added by KAM -->
// MAXIMUS Deck -->
		case "BI_ExitDeck":
			Return2SeaAfterDeck();
			g_intRetVal = 0;
			break;
// MAXIMUS Deck <--
		// <-- added by KAM

		case "BI_Back":
			Deck_GoBack();
			g_intRetVal = 0;
			break;

		case "BI_ReloadFromLandToSea":
			ReloadFromLandToSea();
			g_intRetVal = 0;
			break;
// <-- KK

  // Viper - Emblemed Sails v2 Start

		case "BI_viper_plainsails":
			pchar.Viper_SailsType = "plain";
			DeleteAttribute(pchar, "Viper_SailsNum");
			Log_SetStringToLog(TranslateString("","Plain Sails Selected"));
			g_intRetVal = 0;
		break;

		case "BI_viper_blacksails":
			bUsed = Viper_SetPirateSailIcons();
		break;

		case "BI_viper_tornsails":
			bUsed = Viper_SetPirateSailIcons();
		break;

	  // Viper - Emblemed Sails v2 End

		case "cancel":
			g_intRetVal = 0;
		break;

		case "BI_FastReload":
			bUsed = SetReloadIcons();
		break;

		case "BI_ItemsUse":
			bUsed = SetUsedPotionIcons();
		break;

		case "BI_DialogStart":
			g_intRetVal = 0;
		break;

		case "BI_ItemsChange":
			g_intRetVal = 0;
		break;

		case "BI_TakeItem":
			g_intRetVal = 0;
		break;

		case "BI_PlaceItem":
			g_intRetVal = 0;
		break;

		case "BI_OutDoor":
			g_intRetVal = 0;
		break;

		case "BI_UseBox":
			g_intRetVal = 0;
		break;
//MAXIMUS -->
		case "BI_UseCorpse":
			g_intRetVal = 0;
		break;

		case "BI_UseBarrel":
			g_intRetVal = 0;
		break;
//MAXIMUS <--
		case "BI_ActivateRush":
			g_intRetVal = 0;
		break;
	}

	if(!bUsed) objLandInterface.UserIcons.cancel.enable = true;
	return &g_intRetVal;
}

void BLI_ExecuteCommand()
{
	int		chrIdx = GetEventData();
	string	commName = GetEventData();
	int		targChrIdx = GetEventData();
	string	evntName = GetEventData();

	aref	uiref;
	int		curLocIdx;
	int		tmpi;

	ref pchar = GetMainCharacter(); // Viper - Emblemed Sails v2

	if( commName=="cancel" || evntName=="cancel" ) return;

	switch(commName)
	{
		// KK -->
		case "BI_EnterShip":
			DoFastReload(commName, evntName);//MAXIMUS
		break;
		// <-- KK
		// Viper - Emblemed Sails v2 Start
		case "BI_viper_blacksails":
			FindUserIcon(evntName,&uiref);
			Log_SetStringToLog( uiref.note + " " + TranslateString("","Sails Selected"));
			if (evntName == "nation")
			{
				pchar.Viper_SailsType	= "nationblack";
			}else{
				pchar.Viper_SailsType	= "black";
				pchar.Viper_SailsNum	= evntName;
			}
		break;

		case "BI_viper_tornsails":
			FindUserIcon(evntName,&uiref);
			Log_SetStringToLog(TranslateString("","Torn") + " " + uiref.note + " " + TranslateString("","Sails Selected"));
			if (evntName == "nation")
			{
				pchar.Viper_SailsType	= "nationtorn";
			}else{
				pchar.Viper_SailsType	= "torn";
				pchar.Viper_SailsNum	= evntName;
			}
		break;

		// Viper - Emblemed Sails v2 End

		case "BI_FastReload":
			DoFastReload(commName, evntName);//MAXIMUS
		break;
		case "BI_ItemsUse":
			if( FindUserIcon(evntName,&uiref) )
			{
				aref arItm;
				if( Items_FindItem(uiref.potion,&arItm) >= 0 )
				{
					if( CheckAttribute(arItm,"potion") )
					{
						DoCharacterUsedItem(GetMainCharacter(),arItm.id);
					}
				}
			}
		break;
		case "BI_DialogStart":
			tmpi = SendMessage(GetMainCharacter(),"ls",MSG_CHARACTER_EX_MSG,"FindDialogCharacter");
			ref tmpChar = GetCharacter(tmpi);
			if(tmpi>=0 && !CheckAttribute(tmpChar, "corpse"))	Event("dlgReady","l",tmpi);
			else Log_SetStringToLog(TranslateString("","Gamlet"));
		break;
		case "BI_ItemsChange":
			tmpi = SendMessage(GetMainCharacter(),"ls",MSG_CHARACTER_EX_MSG,"FindDialogCharacter");
			if(tmpi>=0)	LaunchCharacterItemChange(GetCharacter(tmpi));
		break;
		case "BI_TakeItem":
			Item_OnPickItem();
		break;
		case "BI_PlaceItem":
			Item_OnUseItem();
		break;
		case "BI_OutDoor":
			Event("Control Activation","s","ChrAction");
		break;
		case "BI_UseBox":
			OpenBoxProcedure();
		break;//MAXIMUS -->
		case "BI_UseCorpse":
			OpenBoxProcedure();
		break;
		case "BI_UseBarrel":
			OpenBoxProcedure();
		break;//MAXIMUS <--
		case "BI_ActivateRush":
			ActivateCharacterPerk(GetMainCharacter(),"Rush");
		break;
	}
}

//MAXIMUS: moved here for excluding fast reload if character is in dialog -->
void DoFastReload(string commName, string evntName)
{
	if(commName=="" || evntName=="") return;
	if(commName=="cancel" || evntName=="cancel") return;
	if(dialogRun || dialogSelf) return;

	int curLocIdx = -1;
	aref uiref;

	switch(commName)
	{
		case "BI_EnterShip":
			FindUserIcon(evntName, &uiref);
			characters[GetMainCharacterIndex()].condition = "reload";
			switch(uiref.name)
			{
				case "ShipDeck":
					bToDeckFromLand = true;
					Land_DeckStartNow(GetCharacterShipQDeck(GetMainCharacter()));
				break;

				case "Cabin":
					Land_CabinStartNow();
				break;

				Land_DeckStartNow(uiref.name);
			}
		break;

		case "BI_FastReload":
			curLocIdx = FindLoadedLocation();
			if(curLocIdx==-1) return;
			if(FindUserIcon(evntName,&uiref))
			{
				if(CheckAttribute(uiref,"location"))
				{
					characters[GetMainCharacterIndex()].condition = "reload";
					if (CheckAttribute(Locations[curLocIdx], "fastreload") == true && Locations[curLocIdx].fastreload != "ship")
						PlayerFastTravel(curLocIdx, uiref.location);
					else
						TransferToDeck(uiref.location);
				}
			}
		break;
	}
}
//MAXIMUS: moved here for excluding fast reload if character is in dialog <--

void EndBattleLandInterface()
{
	if(!bLandInterfaceStart) return;
	bLandInterfaceStart = false;

	DeleteAttribute( GetMainCharacter(), "boxname" );

	BLI_DisableShow();
	SendMessage(&objLandInterface,"l",MSG_BATTLE_LAND_END);

	DeleteClass(&objLandInterface);

	DelEventHandler(EVENT_CHANGE_OFFICERS,"BLI_UpdateOfficers");
	DelEventHandler(EVENT_DIALOG_START,"BLI_DisableShow");
	DelEventHandler(EVENT_DIALOG_EXIT,"BLI_EnableShow");

	DelEventHandler("evntBLI_Update","BLI_UpdateObjectData");
	DelEventHandler("BI_CommandEndChecking","BLI_CheckCommand");
	DelEventHandler("BI_LaunchCommand","BLI_ExecuteCommand");
	DelEventHandler("BI_SetPossibleCommands","BLI_SetPossibleCommands");
	DelEventHandler("evntFindDialogChar","procFindDialogChar");
	DelEventHandler("Location_CharacterEntryToLocator", "BLI_ChrEnterToLocation");
	DelEventHandler("Location_CharacterExitFromLocator", "BLI_ChrExitFromLocation");
	DelEventHandler("evntPerkAgainUsable","BLI_RefreshCommandMenu");

	Log_SetActiveAction("Nothing");
}

void BLI_SetObjectData()
{
	DeleteAttribute(&objLandInterface,"");
	objLandInterface.data.riskAlarm = 0;
	// индикатор тревоги
	objLandInterface.data.alarm = 0.0;
	// персы вместе с нами
	ref mainCh = GetMainCharacter();
	aref ar;
	int i,cn;
	ref curCh;
	string attrName;
	for(i=0; i < 4; i++)
	{
		cn = GetOfficersIndex(mainCh,i);
		if(cn==-1) continue;
		curCh = GetCharacter(cn);
		if (curCh.location != mainCh.location) continue; // KK: that works and prevents appeareance of more icons than there present officers numbers
		attrName = "id"+i;
		makearef(ar,objLandInterface.data.icons.(attrName));
		ar.picture = curCh.FaceId;
		ar.health = 0.0;
		ar.charge = 0.0;
	}
	BLI_SetCommandParameters();
	BLI_SetMassageParameters();
	// текстуры
	int idLngFile = LanguageOpenFile("commands_name.txt");
	objLandInterface.CommandTextures.list.t0.name = "battle_interface\LandCommands.tga";
	objLandInterface.CommandTextures.list.t0.xsize = 2;
	objLandInterface.CommandTextures.list.t0.ysize = 8;//4;//MAXIMUS
	objLandInterface.CommandTextures.list.t1.name = "battle_interface\LandTarget4.tga";
	objLandInterface.CommandTextures.list.t1.xsize = 8; //Greatzen was 4
	objLandInterface.CommandTextures.list.t1.ysize = 2; // KK
	objLandInterface.CommandTextures.list.t2.name = "battle_interface\LandTarget1.tga";
	objLandInterface.CommandTextures.list.t2.xsize = 4; // KK
	objLandInterface.CommandTextures.list.t2.ysize = 2; // PB
	objLandInterface.CommandTextures.list.t3.name = "battle_interface\Cancel.tga";
	objLandInterface.CommandTextures.list.t3.xsize = 1;
	objLandInterface.CommandTextures.list.t3.ysize = 1;
	objLandInterface.CommandTextures.list.t4.name = "battle_interface\UsedItems1.tga";
	objLandInterface.CommandTextures.list.t4.xsize = 2;
	objLandInterface.CommandTextures.list.t4.ysize = 2;
	objLandInterface.CommandTextures.list.t5.name = "battle_interface\UsedItems2.tga";
	objLandInterface.CommandTextures.list.t5.xsize = 2; // PB: New health items
	objLandInterface.CommandTextures.list.t5.ysize = 2;
  // Viper - Emblemed Sails v2 Start
	objLandInterface.CommandTextures.list.t6.name = "battle_interface\Viper_SailsMain.tga";
	objLandInterface.CommandTextures.list.t6.xsize = 2;
	objLandInterface.CommandTextures.list.t6.ysize = 2;
	objLandInterface.CommandTextures.list.t7.name = "battle_interface\Viper_SailsPirate.tga";
	objLandInterface.CommandTextures.list.t7.xsize = 4;
	objLandInterface.CommandTextures.list.t7.ysize = 4;
	objLandInterface.CommandTextures.list.t8.name = "battle_interface\Viper_SailsNation.tga";
	objLandInterface.CommandTextures.list.t8.xsize = 4;
	objLandInterface.CommandTextures.list.t8.ysize = 4;
  // Viper - Emblemed Sails v2 End

	objLandInterface.CommandTextures.CommandTexNum = 0;
	// список команд
	objLandInterface.Commands.Cancel.enable			= false;
	objLandInterface.Commands.Cancel.picNum			= 0;
	objLandInterface.Commands.Cancel.texNum			= 3;
	objLandInterface.Commands.Cancel.event			= "Cancel";
	objLandInterface.Commands.ItemsUse.enable		= true;
	objLandInterface.Commands.ItemsUse.picNum		= 0;
	objLandInterface.Commands.ItemsUse.event		= "BI_ItemsUse";
	objLandInterface.Commands.ItemsUse.note			= LanguageConvertString(idLngFile, "land_ItemsUse");
	objLandInterface.Commands.DialogStart.enable	= true;
	objLandInterface.Commands.DialogStart.picNum	= 4;
	objLandInterface.Commands.DialogStart.event		= "BI_DialogStart";
	objLandInterface.Commands.DialogStart.note		= LanguageConvertString(idLngFile, "land_DialogStart");
	objLandInterface.Commands.ItemsChange.enable	= true;
	objLandInterface.Commands.ItemsChange.picNum	= 1;
	objLandInterface.Commands.ItemsChange.event		= "BI_ItemsChange";
	objLandInterface.Commands.ItemsChange.note		= LanguageConvertString(idLngFile, "land_ItemsChange");
	objLandInterface.Commands.TakeItem.enable		= true;
	objLandInterface.Commands.TakeItem.picNum		= 5;
	objLandInterface.Commands.TakeItem.event		= "BI_TakeItem";
	objLandInterface.Commands.TakeItem.note			= LanguageConvertString(idLngFile, "land_TakeItem");
	objLandInterface.Commands.PlaceItem.enable		= true;
	objLandInterface.Commands.PlaceItem.picNum		= 5;
	objLandInterface.Commands.PlaceItem.event		= "BI_PlaceItem";
	objLandInterface.Commands.PlaceItem.note		= LanguageConvertString(idLngFile, "land_PlaceItem");
	objLandInterface.Commands.OutDoor.enable		= true;
	objLandInterface.Commands.OutDoor.picNum		= 2;
	objLandInterface.Commands.OutDoor.event			= "BI_OutDoor";
	objLandInterface.Commands.OutDoor.note			= LanguageConvertString(idLngFile, "land_OutDoor");
	objLandInterface.Commands.UseBox.enable			= true;
	objLandInterface.Commands.UseBox.picNum			= 8;//1;//MAXIMUS
	objLandInterface.Commands.UseBox.texNum			= 0;//MAXIMUS
	objLandInterface.Commands.UseBox.event			= "BI_UseBox";
	objLandInterface.Commands.UseBox.note			= LanguageConvertString(idLngFile, "land_UseBox");
//MAXIMUS -->
	objLandInterface.Commands.UseCorpse.enable		= true;
	objLandInterface.Commands.UseCorpse.picNum		= 9;
	objLandInterface.Commands.UseCorpse.texNum		= 0;
	objLandInterface.Commands.UseCorpse.event		= "BI_UseCorpse";
	objLandInterface.Commands.UseCorpse.note		= LanguageConvertString(idLngFile, "land_UseCorpse");

	objLandInterface.Commands.UseBarrel.enable		= true;
	objLandInterface.Commands.UseBarrel.picNum		= 10;
	objLandInterface.Commands.UseBarrel.texNum		= 0;
	objLandInterface.Commands.UseBarrel.event		= "BI_UseBarrel";
	objLandInterface.Commands.UseBarrel.note		= LanguageConvertString(idLngFile, "land_UseBarrel");
//MAXIMUS <--
// KK -->
	objLandInterface.Commands.ReloadFromLandToSea.enable		= false;
	objLandInterface.Commands.ReloadFromLandToSea.picNum		= 7;
	objLandInterface.Commands.ReloadFromLandToSea.texNum		= 0;
	objLandInterface.Commands.ReloadFromLandToSea.event			= "BI_ReloadFromLandToSea";
	objLandInterface.Commands.ReloadFromLandToSea.note	    = LanguageConvertString(idLngFile, "land_ExitDeck");

	objLandInterface.Commands.FastReload.enable		= true;
	objLandInterface.Commands.FastReload.picNum		= 3;
	objLandInterface.Commands.FastReload.event		= "BI_FastReload";
	objLandInterface.Commands.FastReload.note		= LanguageConvertString(idLngFile, "land_FastReload");

	objLandInterface.Commands.EnterShip.enable 	= true;
	objLandInterface.Commands.EnterShip.picNum 	= 5;
	objLandInterface.Commands.EnterShip.texNum 	= 2;
	objLandInterface.Commands.EnterShip.event 	= "BI_EnterShip";
	objLandInterface.Commands.EnterShip.note 	= LanguageConvertString(idLngFile, "land_EnterShip");

	objLandInterface.Commands.EnterTartane.enable = true;
	objLandInterface.Commands.EnterTartane.picNum = 5;
	objLandInterface.Commands.EnterTartane.texNum = 2;
	objLandInterface.Commands.EnterTartane.event	= "BI_EnterTartane";
	objLandInterface.Commands.EnterTartane.note		= LanguageConvertString(idLngFile, "land_EnterShipDeck");
	// added by KAM -->
// MAXIMUS Deck -->
	objLandInterface.Commands.ExitDeck.enable		= false;
	objLandInterface.Commands.ExitDeck.picNum		= 7;
	objLandInterface.Commands.ExitDeck.texNum		= 0;
	objLandInterface.Commands.ExitDeck.event		= "BI_ExitDeck";
	objLandInterface.Commands.ExitDeck.note		    = LanguageConvertString(idLngFile, "land_ExitDeck");
// MAXIMUS Deck <--
	// <-- added by KAM
	objLandInterface.Commands.Back.enable		= false;
	objLandInterface.Commands.Back.picNum		= 4;
	objLandInterface.Commands.Back.texNum		= 2;
	objLandInterface.Commands.Back.event		= "BI_Back";
	objLandInterface.Commands.Back.note		    = LanguageConvertString(idLngFile, "land_Back");
// <-- KK
	objLandInterface.Commands.ActivateRush.enable	= true;
	objLandInterface.Commands.ActivateRush.picNum	= 6;
	objLandInterface.Commands.ActivateRush.event	= "BI_ActivateRush";
	objLandInterface.Commands.ActivateRush.note		= LanguageConvertString(idLngFile, "land_ActivateRush");

  // Viper - Emblemed Sails v2 Start

	objLandInterface.Commands.viper_plainsails.enable	= true;
	objLandInterface.Commands.viper_plainsails.picNum	= 0;
	objLandInterface.Commands.viper_plainsails.texNum	= 8;
	objLandInterface.Commands.viper_plainsails.event	= "BI_viper_plainsails";
	objLandInterface.Commands.viper_plainsails.note		= LanguageConvertString(idLngFile, "viper_plainsails");

	objLandInterface.Commands.viper_blacksails.enable	= true;
	objLandInterface.Commands.viper_blacksails.picNum	= 1;
	objLandInterface.Commands.viper_blacksails.texNum	= 6;
	objLandInterface.Commands.viper_blacksails.event	= "BI_viper_blacksails";
	objLandInterface.Commands.viper_blacksails.note		= LanguageConvertString(idLngFile, "viper_blacksails");

	objLandInterface.Commands.viper_tornsails.enable	= true;
	objLandInterface.Commands.viper_tornsails.picNum	= 2;
	objLandInterface.Commands.viper_tornsails.texNum	= 6;
	objLandInterface.Commands.viper_tornsails.event		= "BI_viper_tornsails";
	objLandInterface.Commands.viper_tornsails.note		= LanguageConvertString(idLngFile, "viper_tornsails");
  // Viper - Emblemed Sails v2 End

	// список пользовательских картинок
		// cancel icon
	objLandInterface.UserIcons.cancel.enable = true;
	objLandInterface.UserIcons.cancel.pic = 0;
	objLandInterface.UserIcons.cancel.tex = 3;
	objLandInterface.UserIcons.cancel.name = "cancel";

	LanguageCloseFile(idLngFile);
		// go to icons
	int idxloc = FindLoadedLocation();
	string outGroupName = "";
	RecalculateHireCrew(idxloc);
	if(idxloc>=0 && CheckAttribute(&Locations[idxloc],"fastreload"))
	{
		outGroupName = Locations[idxloc].fastreload;
		CreateReloadPaths(outGroupName);
	}

	SendMessage(&objLandInterface,"l",MSG_BATTLE_LAND_START);
}

bool FindUserIcon(string id,ref uiref)
{
	aref arroot,ar; makearef(arroot,objLandInterface.UserIcons);
	for(int i=0; i<GetAttributesNum(arroot); i++)
	{
		ar = GetAttributeN(arroot,i);
		if(!CheckAttribute(ar,"name")) continue;//MAXIMUS
		if(ar.name != id) continue;
		uiref = ar;
		return true;
	}
	return false;
}

void BLI_SetShowParameters()
{
	aref ar; makearef(ar,objLandInterface.Parameters);

	ar.shadowH = RecalculateVIcon(28);
	ar.shadowW = RecalculateHIcon(20);
	ar.shadowTOP = RecalculateVIcon(18);
	ar.widthCom = RecalculateHIcon(64);
	ar.heightCom = RecalculateVIcon(64);
	ar.leftPosCom = sti(showWindow.left)+RecalculateHIcon(16);
	ar.topPosCom = sti(showWindow.bottom)-RecalculateVIcon(80);
	ar.distCom = RecalculateHIcon(8);

	ar.widthHealth = RecalculateHIcon(64);
	ar.heightHealth = RecalculateVIcon(16);
	ar.distHealth = RecalculateVIcon(4);

	// высота и отступ для количества зарядов пистолета
	ar.GunShootHeight = RecalculateHIcon(16);
	ar.GunShootSpace = RecalculateVIcon(2);

	ar.AlarmColorLight	= argb(255,128,128,128);
	ar.AlarmColorDark	= argb(255,148,38,38);
	ar.PoisonColorLight	= argb(255,128,128,128);
	ar.PoisonColorDark	= argb(255,38,148,38);
	ar.AlarmBlindUpTime		= 0.3;
	ar.AlarmBlindDownTime	= 0.7;

	ar.DoShowCommandos = true;
	ar.CommandosQuantity = 4;

	ar.shadowTexture = "battle_interface\portraits_shadow.tga";

//MAXIMUS: fixed officers-icons - we'll see proper icon for each officer in any location -->
	//SetOfficerTexture(0);
	//SetOfficerTexture(1);
	//SetOfficerTexture(2);
	//SetOfficerTexture(3);
	for(int i=0; i<sti(ar.CommandosQuantity); i++)
	{
		SetOfficerTexture(i);
	}
//MAXIMUS: fixed officers-icons - we'll see proper icon for each officer in any location <--

	ar.stateTexture = "battle_interface\officerstate.tga";
	ar.gunChargeTexture = "battle_interface\guncharge.tga";

	ar.iconHorzQuantity = 8;
	ar.iconVertQuantity = 4;
	BLI_SetCommandParameters();
	BLI_SetMassageParameters();
}

void BLI_SetCommandParameters()
{
	objLandInterface.CommandShowParam.maxShowQuantity = 10;
	objLandInterface.CommandShowParam.iconDistance = RecalculateHIcon(4);
	objLandInterface.CommandShowParam.iconWidth = RecalculateHIcon(64);
	objLandInterface.CommandShowParam.iconHeight = RecalculateVIcon(64);
	objLandInterface.CommandShowParam.leftIconsOffset = sti(showWindow.left)+RecalculateHIcon(16);
	objLandInterface.CommandShowParam.downIconsOffset = sti(showWindow.bottom)-RecalculateVIcon(80);
	objLandInterface.CommandShowParam.buttonWidth = RecalculateHIcon(8);
	objLandInterface.CommandShowParam.buttonHeight = RecalculateVIcon(64);
	objLandInterface.CommandShowParam.buttonOffset = RecalculateHIcon(4);
	objLandInterface.CommandShowParam.buttonTexture = "battle_interface\lr_buttons.tga";
	objLandInterface.CommandShowParam.shipStateWidth = RecalculateHIcon(64);
	objLandInterface.CommandShowParam.shipStateHeight = RecalculateVIcon(16);
	objLandInterface.CommandShowParam.shipStateTexture = "battle_interface\indicators.tga";
	objLandInterface.CommandShowParam.shipStateOffset = RecalculateVIcon(0);
	objLandInterface.CommandShowParam.commandFont = "bold_numbers";
	objLandInterface.CommandShowParam.printXOffset = RecalculateHIcon(32);
	objLandInterface.CommandShowParam.printYOffset = RecalculateVIcon(-26);
	objLandInterface.CommandShowParam.commandNoteFont = "interface_normal";
	objLandInterface.CommandShowParam.noteXOffset = RecalculateHIcon(0);
	objLandInterface.CommandShowParam.noteYOffset = RecalculateVIcon(-28);
	objLandInterface.CommandShowParam.argbTFactorColor = argb(256,64,64,64);
}

void BLI_SetMassageParameters()
{
	objLandInterface.MessageIcons.IconWidth = RecalculateHIcon(64);
	objLandInterface.MessageIcons.IconHeight = RecalculateVIcon(24);
	objLandInterface.MessageIcons.IconDist = RecalculateVIcon(2);
	objLandInterface.MessageIcons.IconBottom = sti(showWindow.bottom)-RecalculateHIcon(80+40);
	objLandInterface.MessageIcons.IconMaxQuantity = 4;
	objLandInterface.MessageIcons.BlendTime = 3.0;
	objLandInterface.MessageIcons.FallSpeed = 22.0;
	objLandInterface.MessageIcons.argbHighBlind = argb(255,128,128,128);
	objLandInterface.MessageIcons.argbLowBlind = argb(255,68,68,68);
	objLandInterface.MessageIcons.BlindUpTime = 0.5;
	objLandInterface.MessageIcons.BlindDownTime = 1.0;
	objLandInterface.MessageIcons.texture = "battle_interface\MessageIcons.tga";
	objLandInterface.MessageIcons.TexHSize = 2;
	objLandInterface.MessageIcons.TexVSize = 2;
}

void BLI_UpdateObjectData()
{
	objLandInterface.data.alarm = LAi_group_GetPlayerAlarm();
	bool bIsRiskAlarm = LAi_group_IsActivePlayerAlarm();
	if(sti(objLandInterface.data.riskAlarm)!=bIsRiskAlarm) BLI_RefreshCommandMenu();
	objLandInterface.data.riskAlarm = bIsRiskAlarm;
	ref mainCh = GetMainCharacter();
	aref ar,arItm;
	int i,cn;
	ref curCh;
	string attrName;
	for(i=0; i<4; i++)
	{
		attrName = "id"+i;
		cn = GetOfficersIndex(mainCh,i);
		if(cn==-1 || !IsEntity(&Characters[cn]))
		{
			DeleteAttribute(&objLandInterface,"data.icons."+attrName);
			continue;
		}
		curCh = GetCharacter(cn);
		makearef(ar,objLandInterface.data.icons.(attrName));
		ar.picture = curCh.FaceId;
		ar.health = LAi_GetCharacterRelHP(curCh);
		ar.charge = LAi_GetCharacterRelCharge(curCh);//gun's reload speed (calculates from charges quantity)
		ar.shootMax = LAi_GetCharacterChargeQuant(curCh);//maximal charges quantity (for current gun)
		ar.shootCur = LAi_GetCharacterChargeCur(curCh);//actual charges quantity
		ar.poison = LAi_IsPoison(curCh);
	}

	SearchAdditionalLocators();//MAXIMUS: makes box from corpse with hand-icon in the top-left corner
	CheckOfficers();//MAXIMUS: updates officers-icons
	PostEvent("evntBLI_Update",150);//MAXIMUS (was BLI_UPDATE_PERIOD)
}

void SearchAdditionalLocators()
{
	if(chrWaitReloadLocator!="")
	{
		if(!CheckAttribute(GetMainCharacter(),"fakereload.locator")) { CharacterBoxUpdate(GetMainCharacter(),"",false); return; }
	}
	if(characters[GetMainCharacterIndex()].location=="") return;
	if(FindLocation(characters[GetMainCharacterIndex()].location)<0) return;

	ref chr = GetMainCharacter();
	string locationID = chr.location;
	string curLocName = "";
	string curLocGroup = "";
	ref lcn = &Locations[FindLocation(locationID)];
	aref rootLocators, curGrp, curLoc;
	int i, j, itmIdx;
	bool bPos, exacLocator;

	makearef(rootLocators,lcn.locators);
	for(i=0; i<GetAttributesNum(rootLocators); i++)
	{
		curGrp = GetAttributeN(rootLocators,i);
		curLocGroup = GetAttributeName(curGrp);
		for(j=0; j<GetAttributesNum(curGrp); j++)
		{
			curLoc = GetAttributeN(curGrp,j);
			curLocName = GetAttributeName(curLoc);
			exacLocator = false;
			bPos = false;
			if(CheckAttribute(lcn, "locators."+curLocGroup+"."+curLocName+".tmpLocator")) exacLocator = true;
			if(!exacLocator) continue;
			if(exacLocator)
			{
				int itemN = sti(lcn.locators.(curLocGroup).(curLocName).corpseIdx);
				bPos = CheckCharPosition(stf(lcn.locators.(curLocGroup).(curLocName).x), stf(lcn.locators.(curLocGroup).(curLocName).y), stf(lcn.locators.(curLocGroup).(curLocName).z));
				if(bPos)
				{
					switch(curLocGroup)
					{
						case "box":
							chr.boxname = curLocName;
// KK -->
							if (HasSubStr(curLocName, "corpse_box")) {
								int corpseidx = -1;
								if (CheckAttribute(lcn, "locators.box." + curLocName + ".corpseIdx")) corpseidx = sti(lcn.locators.box.(curLocName).corpseIdx);
								ClearAllLogStrings();
								if (corpseidx >= 0 && CheckAttribute(characters[corpseidx], "old.name") == true && CheckAttribute(characters[corpseidx], "old.lastname") == true)
									chr.boxname.label = XI_ConvertString("BodyOf") + characters[corpseidx].old.name + " " + characters[corpseidx].old.lastname;
								else
									chr.boxname.label = "Corpse";
								Log_SetActiveAction("Corpse");
							}
							if(HasSubStr(curLocName, "treasure_box"))
							{
								Log_SetActiveAction("OpenBox");
								chr.boxname.label = "Treasure";
							}
							CharacterBoxUpdate(chr,chr.boxname.label,true);
						break;

						case "items":
							Log_SetActiveAction("Pick");
							chr.activeItem = itemN;
							chr.activeLocator = curLocName;
							chr.activeRandItem = false;
							chr.activeItem.pick = true;
						break;

						case "reload":
							chr.fakereload.locator = curLocName;
							EnterToReloadLocator(chr);
						break;
					}
				}
				else
				{
					switch(curLocGroup)
					{
						case "box":
							if(CheckAttribute(chr,"boxname") && chr.boxname==curLocName)
							{
								DeleteAttribute(chr,"boxname.label");
								DeleteAttribute(chr,"boxname");
								CharacterBoxUpdate(chr,"",false);
								if(!CheckAttribute(chr,"activeItem")) { CheckCharacterAction(); }
								else
								{
									if(chr.activeItem=="") { CheckCharacterAction(); }
									else
									{
										if(CheckAttribute(chr,"activeItem.pick") && chr.activeItem.pick!="1") { CheckCharacterAction(); }
									}
								}
							}
						break;

						case "items":
							if(itemN>=0)
							{
								if(!CheckAttribute(chr,"boxname")) { CheckCharacterAction(); }
								chr.activeItem = "";
								chr.activeLocator = "";
								chr.activeItem.pick = false;
							}
						break;

						case "reload":
							if(CheckAttribute(chr,"fakereload.locator") && chr.fakereload.locator==curLocName)
							{
								ExitFromReloadLocator(chr);
								if(!CheckAttribute(chr,"activeItem")) { CheckCharacterAction(); }
								else
								{
									if(chr.activeItem=="") { CheckCharacterAction(); }
									else { if(CheckAttribute(chr,"activeItem.pick") && chr.activeItem.pick!="1") { CheckCharacterAction(); } }
								}
							}
						break;
					}
				}
			}
		}
	}
	if(!CheckAttribute(chr,"boxname"))
	{
		if(!CheckAttribute(chr,"activeItem")) { CheckCharacterAction(); }
		else
		{
			if(chr.activeItem=="") { CheckCharacterAction(); }
			else
			{
				if(CheckAttribute(chr,"activeItem.pick") && chr.activeItem.pick!="1") { CheckCharacterAction(); }
			}
		}
	}
	BLI_RefreshCommandMenu();
}

void CharacterBoxUpdate(ref chr, string label, bool bClear)
{
	if(!CheckAttribute(chr,"boxname") || dialogRun || dialogSelf || label=="")
	{
		if(bClear) ClearAllLogStrings();
		if(CheckAttribute(chr,"BoxName.update")) DeleteAttribute(chr,"BoxName.update");
		if(chrWaitReloadLocator=="") RestoreLogInterface();
		return;
	}

	chr.BoxName.update = true;
	ClearAllLogStrings();
	SetUpLogInterface(label,COLOR_GREEN_LIGHT,16,80);
	SendMessage(&ILogAndActions,"lls",LOG_ADD_STRING, false, TranslateString("", label));
//	Log_SetStringToLog(TranslateString("", label));
}

#event_handler("procChrOpenBox","BoxNameUpdate");
void BoxNameUpdate()
{
	if(!CheckAttribute(GetMainCharacter(),"boxname") || dialogRun || dialogSelf)
	{
		ClearAllLogStrings();
		if(CheckAttribute(GetMainCharacter(),"BoxName.update")) DeleteAttribute(GetMainCharacter(),"BoxName.update");
		if(chrWaitReloadLocator=="") RestoreLogInterface();
		return;
	}

	string label = GetEventData();
	characters[GetMainCharacterIndex()].BoxName.update = true;
	ClearAllLogStrings();
	SetUpLogInterface(label,COLOR_GREEN_LIGHT,16,80);
	SendMessage(&ILogAndActions,"lls",LOG_ADD_STRING, false, TranslateString("", label));
//	Log_SetStringToLog(TranslateString("", label));
	PostEvent("procChrOpenBox",125,"s",label);
}

void SetLandInterfaceShow(bool commandosShow)
{
	SendMessage(&objLandInterface,"ll",MSG_BATTLE_LAND_SET_SHOW,commandosShow);
}

void BLI_SetPossibleCommands()
{
	int idLngFile = LanguageOpenFile("commands_name.txt");
	ref mchref = GetMainCharacter();
	int chrMode = SendMessage(mchref,"ls",MSG_CHARACTER_EX_MSG,"IsFightMode");

	bool bTmpBool = false;
	bool bUseCommand = false;
	int i;
	aref rootcom,curcom;
	makearef(rootcom,objLandInterface.Commands);
	for(i=0; i<GetAttributesNum(rootcom); i++)
	{
		curcom = GetAttributeN(rootcom,i);
		curcom.enable = false;
	}

  // Viper - Emblemed Sails v2 Start
	ref pchar = GetMainCharacter();
	// if (pchar.viper_changesails == true) // scheffnow - bfd
	if (CheckAttribute(pchar,"viper_changesails") && pchar.viper_changesails == true)
	{
		objLandInterface.Commands.viper_plainsails.picNum	= sti(pchar.nation);
		objLandInterface.Commands.viper_plainsails.enable	= true;
		objLandInterface.Commands.viper_blacksails.enable	= true;
		objLandInterface.Commands.viper_tornsails.enable	= true;
		DeleteAttribute(pchar, "viper_changesails");
		return;
	}
  // Viper - Emblemed Sails v2 End

	if(chrMode==0)
	{
		bTmpBool = true;
		if(LAi_group_IsActivePlayerAlarm()) bTmpBool = false;
		if(!LAi_IsCharacterControl(mchref)) bTmpBool = false;
		if(bDisableFastReload)	bTmpBool = false;
		if(!IsEnableFastTravel()) bTmpBool = false;
		i = -1;
		if(CheckAttribute(mchref,"dialogready")) i=sti(mchref.dialogready);
		if(i>=0)
		{
			objLandInterface.Commands.DialogStart.enable = CheckAttribute(&Characters[i],"Dialog.FileName")==true && Characters[i].Dialog.FileName!="";//true;//MAXIMUS
			if( IsOfficer(&Characters[i]) )
			{
				objLandInterface.Commands.ItemsChange.enable = true;
			}
			else
			{
				if( CheckAttribute(&Characters[i],"InterfaceFlags.ItemsChange") &&
					Characters[i].InterfaceFlags.ItemsChange != "0" )
				{
					objLandInterface.Commands.ItemsChange.enable = true;
				}
			}
		}
		objLandInterface.Commands.FastReload.enable	= bTmpBool==true; // KK causes more problems than good && objLandInterface.Commands.DialogStart.enable==false;//MAXIMUS
		bUseCommand = true;
	}

	if(GetCharacterPerkUsing(mchref,"Rush"))
	{
		objLandInterface.Commands.ActivateRush.enable = true;
		bUseCommand = true;
	}

	if( CanBeUseItem(mchref) )
	{
		objLandInterface.Commands.ItemsUse.enable = true;
		bUseCommand = true;
	}

	if(CheckAttribute(mchref,"boxname"))//MAXIMUS -->
	{
		objLandInterface.Commands.UseBox.enable	= false;
		objLandInterface.Commands.UseBarrel.enable	= false;
		objLandInterface.Commands.UseCorpse.enable	= false;
		if(HasSubStr(mchref.boxname,"corpse")) objLandInterface.Commands.UseCorpse.enable = true;
		if(HasSubStr(mchref.boxname,"gunpowder"))
		{
			objLandInterface.Commands.UseBarrel.enable = true;
			objLandInterface.Commands.UseBarrel.note = LanguageConvertString(idLngFile, "land_UseBarrel");
			if(LAi_IsBoardingProcess() && mchref.location!=GetShipLocationID(mchref) && mchref.location!=GetShipLocationID(boarding_enemy))
			{
				objLandInterface.Commands.UseBarrel.note = LanguageConvertString(idLngFile, "land_UseStorage");
			}
			if(ownDeckStarted() && mchref.location!=GetCharacterShipQDeck(mchref))
			{
				objLandInterface.Commands.UseBarrel.note = LanguageConvertString(idLngFile, "land_UseStorage");
			}
		}
		objLandInterface.Commands.UseBox.enable	= !HasSubStr(mchref.boxname,"gunpowder") && !HasSubStr(mchref.boxname,"corpse");
		bUseCommand = true;
	}//MAXIMUS <--

	if( CheckAttribute(mchref,"activeItem") && mchref.activeItem!="" )
	{
		bUseCommand = true;
		if( CheckAttribute(mchref,"activeItem.pick") && mchref.activeItem.pick=="1" )
		{
			objLandInterface.Commands.TakeItem.enable = true;
		}
		else
		{
			objLandInterface.Commands.PlaceItem.enable = true;
		}
	}

	if(CheckForReload() && GetReloadMapAttrib(FindLoadedLocation(), chrWaitReloadLocator, "go") != "") // KK //MAXIMUS
	{
		bUseCommand = true;
		objLandInterface.Commands.OutDoor.enable = true;
	}
	if(bMutinyDeckStarted || LAi_IsBoardingProcess())
	{
		objLandInterface.Commands.OutDoor.enable = false;
		bUseCommand = false;
	}

// KK -[changed by MAXIMUS: isn't simpler and faster? Also without lags ;)]->
	int curlocidx = FindLoadedLocation();
	int portlocidx = -1;
	if(CheckAttribute(mchref, "location.from_sea")) portlocidx = FindLocation(mchref.location.from_sea);
	if(!bSeaActive) bTmpBool = objLandInterface.Commands.FastReload.enable==true;//MAXIMUS: full check already done above :)
	//else bTmpBool = CheckAttribute(mchref, "Interlocutor.update")==false;
	if(bTmpBool && curLocIdx!=-1 && portlocidx!=-1)//MAXIMUS: I doubt, that even it's needed (curLocIdx!=-1 && portlocidx!=-1)...
	{
		objLandInterface.Commands.EnterShip.enable = false;
		objLandInterface.Commands.EnterTartane.enable = false;
		objLandInterface.Commands.ExitDeck.enable = false;
		if(!bMutinyDeckStarted && !LAi_IsBoardingProcess())
		{
			objLandInterface.Commands.EnterShip.enable = !bDeckEnter && GetCharacterShipCabin(mchref) != "Cabin_none";
			objLandInterface.Commands.EnterTartane.enable = !bDeckEnter && GetCharacterShipCabin(mchref) == "Cabin_none";
			objLandInterface.Commands.ExitDeck.enable = bDeckEnter;
			bTmpBool = chrWaitReloadLocator!="" && CheckAttribute(mchref,"reloadStatus")==true;
			if(bTmpBool) { if(mchref.reloadStatus!="ToSea" && mchref.reloadStatus!="ToBoat") bTmpBool = false; }
			objLandInterface.Commands.ReloadFromLandToSea.enable = objLandInterface.Commands.OutDoor.enable==true && VISIT_DECK==1 && !bDeckEnter && bTmpBool;
			BattleInterface.Commands.EnterTartane.note = LanguageConvertString(idLngFile, "land_EnterShipDeck");
			if(CheckAttribute(mchref,"Ship.Type"))
			{
				if(mchref.Ship.Type=="Tartane3" || mchref.Ship.Type=="Gunboat")
				{
					BattleInterface.Commands.EnterTartane.note = LanguageConvertString(idLngFile, "land_EnterShip");
				}
			}
		}
	}

	bTmpBool = true;
	if(bSeaActive) bTmpBool = bMapEnter;
	objLandInterface.Commands.Back.enable = objLandInterface.Commands.ExitDeck.enable==true && bTmpBool && bDeckEnter && LandLocationIdx!=-1;
	bUseCommand = true;
// MAXIMUS Deck <--
// <-[changed by MAXIMUS: isn't simpler and faster? Also without lags ;)]- KK

	if(!bUseCommand)
	{
		SendMessage(&objLandInterface,"llllll",BI_IN_SET_COMMAND_MODE,0,-1,-1,-1,-1);
	}
	LanguageCloseFile(idLngFile);
}

//MAXIMUS: for additional locators -->
bool CheckForReload()
{
	if(chrWaitReloadLocator!="" || CheckAttribute(characters[GetMainCharacterIndex()],"fakereload.locator")) return true;
	return false;
}
//MAXIMUS: for additional locators <--

void BLI_evntRefreshCommandMenu()
{
	DelEventHandler("frame","BLI_evntRefreshCommandMenu");
	BLI_RefreshCommandMenu();
}
void BLI_RefreshCommandMenu()
{
	SendMessage(&objLandInterface,"lllll",BI_IN_SET_COMMAND_MODE,-1,-1,-1,-1,-1);
}
/*
void procFindDialogChar()
{
	ref mchref = GetMainCharacter();
	int dlgChar = -1;
	// NK comment this out, enable in boarding. 05-07-12 - if(!LAi_IsBoardingProcess())
	dlgChar = SendMessage(mchref,"ls",MSG_CHARACTER_EX_MSG,"FindDialogCharacter");

	int oldDlgChar = -1;
	if(CheckAttribute(mchref,"dialogready")) oldDlgChar = sti(mchref.dialogready);

	if(dlgChar!=oldDlgChar)
	{
		mchref.dialogready = dlgChar;
		BLI_RefreshCommandMenu();
	// PB: Auto show name -->
	// Coding by AlexusB, automated by Viper, made toggleable in BS.h by NK
		if(!CheckAttribute(mchref,"reloadStatus.update") && !dialogRun && !dialogSelf)
		{
			ref NPChar = GetCharacter(dlgChar);
			if (dlgChar>0 && AUTO_SHOW_NAME_HP)
			{
				if(CheckAttribute(NPChar,"name"))
				{
					if(CheckAttribute(NPChar, "corpse")) Log_SetStringToLog(NPChar.name + " " + NPChar.lastname + ": " + XI_ConvertString("Rank") + ": " + NPChar.rank + " " + XI_ConvertString("HP") + ": 0/" + makeint(NPChar.chr_ai.hp_max) ) ;
					else Log_SetStringToLog(GetMyFullName(NPChar) + " " + XI_ConvertString("Rank") + ": " + NPChar.rank + " " + XI_ConvertString("HP") + ": "+ makeint(NPChar.chr_ai.hp) + "/" + makeint(NPChar.chr_ai.hp_max) ) ;
				}
			}
		}
	}

	PostEvent("evntFindDialogChar",500);
	// PB: Auto show name <--
}*/

//MAXIMUS: -[small improvement for these processes]->
void procFindDialogChar()
{
	ref mchref = GetMainCharacter();
	int dlgChar = SendMessage(mchref,"ls",MSG_CHARACTER_EX_MSG,"FindDialogCharacter");
	mchref.dialogready = dlgChar;

	if(dlgChar==-1)
	{
		if(chrWaitReloadLocator=="" && !CheckAttribute(mchref,"boxname"))
		{
			RestoreLogInterface();
		}
		RestoreLogActions();
		if(CheckAttribute(mchref,"Interlocutor.update")) DeleteAttribute(mchref,"Interlocutor.update");
		if(CheckAttribute(mchref,"Interlocutor.index")) DeleteAttribute(mchref,"Interlocutor.index");
		BLI_RefreshCommandMenu();
		PostEvent("evntFindDialogChar",250);
		return;
	}

	int oldDlgChar = -1;
	if(CheckAttribute(mchref,"dialogready")) oldDlgChar = sti(mchref.dialogready);

	bool bShow = chrWaitReloadLocator=="" && !CheckAttribute(mchref,"boxname") && !CheckAttribute(mchref,"activeItem.Action");
	string chrName = "";
	ref NPChar = &Nullcharacter;
	if(dlgChar!=oldDlgChar) mchref.dialogready = dlgChar;
	BLI_RefreshCommandMenu();
	if(AUTO_SHOW_NAME_HP)//MAXIMUS: actually we not need to show HP - we can see all info by KEY_O. So, I leave only name here
	{
		NPChar = GetCharacter(dlgChar);
		if(GetMyFullName(NPChar)!="")
		{
			chrName = GetMyFullName(NPChar);
			if(CheckAttribute(NPChar, "corpse"))
			{
				chrName = FirstLetter(TranslateString("","body_of_"+NPChar.sex)) + " " + chrName;
			}
		}
		PortraitUpdate(mchref,NPChar,chrName,bShow);
	}
}

void PortraitUpdate(ref mchref, ref NPChar, string chrName, bool bShow)
{
	if(bShow && chrName!="" && CheckAttribute(NPChar,"FaceId") && sti(NPChar.FaceId)!=-1)
	{
		string facePict = "INTERFACES\PORTRAITS\64\face_"+sti(NPChar.FaceId)+".tga";
		if(CheckAttribute(NPChar, "corpse") || FindFile("RESOURCE\TEXTURES\INTERFACES\PORTRAITS\64","*.tga.tx","face_"+sti(NPChar.FaceId)+".tga.tx")=="") facePict = "INTERFACES\PORTRAITS\128\face_skull.tga";
		SetUpLogInterface("",COLOR_GREEN_LIGHT,16,80);
		SetUpLogActions(facePict,1,1,0);
		Log_SetActiveAction("TalkWith");
		mchref.Interlocutor.update = true;
		mchref.Interlocutor.index = sti(NPChar.index);
		InterlocutorUpdate(mchref, NPChar, chrName);
		bShow = true;
	}
	else bShow = false;

	if(!bShow)
	{
		RestoreLogActions();
		if(CheckAttribute(mchref,"Interlocutor.update")) DeleteAttribute(mchref,"Interlocutor.update");
		if(CheckAttribute(mchref,"Interlocutor.index")) DeleteAttribute(mchref,"Interlocutor.index");
		if(chrWaitReloadLocator=="" && !CheckAttribute(mchref,"boxname") && !CheckAttribute(mchref,"activeItem.Action"))
		{
			RestoreLogInterface();
		}
		PostEvent("evntFindDialogChar",50);
	}
}

void InterlocutorUpdate(ref chr, ref NPChar, string name)
{
	if(!IsMainCharacter(chr)) return;

	bool bHide = CheckAttribute(chr, "condition")==true && chr.condition=="reload";
	if(!bHide) bHide = name=="";

	if(FindLocation(chr.location)==-1 || !CheckAttribute(chr,"Interlocutor.update") || bHide || chrWaitReloadLocator!="")
	{
		PortraitUpdate(chr, NPChar, "", false);
		return;
	}

	ClearAllLogStrings();
	SendMessage(&ILogAndActions,"lls",LOG_ADD_STRING, false, name);
//	Log_SetStringToLog(name);
	PostEvent("evntFindDialogChar",150);
}

#event_handler("UpdateLocator","BLI_ChrEnterToLocation");
void BLI_ChrEnterToLocation()
{
	if(bMutinyDeckStarted || LAi_IsBoardingProcess()) return;// MAXIMUS
	//int tmpLangFileID = LanguageOpenFile("interface_strings.txt");
	aref loc = GetEventData();	
	aref chr = GetEventData();
	string group = GetEventData();
	string locator = GetEventData();
	aref locList,locCur;
	int i,n;

	if(!IsMainCharacter(chr)) return;

	if(group=="reload")
	{
		makearef(locList,loc.reload);
		n = GetAttributesNum(locList);
		for(i=0;i<n;i++)
		{
			locCur = GetAttributeN(locList,i);
			if(CheckAttribute(locCur,"name")) { if(locCur.name == locator) break; }
		}
		if(i<n)
		{
			if(CheckAttribute(locCur,"go"))
			{
				i = FindLocation(locCur.go);
// KK -->
				if(i>=0 && CheckAttribute(&locations[i], "id.label")) {
					string label = TranslateString("", locations[i].id.label);
					Preprocessor_Add("island_name", XI_ConvertString(GetIslandNameByLocationID(chr.location)));
					if (CheckAttribute(&Locations[i], "townsack")) Preprocessor_Add("town_name", GetTownName(Locations[i].townsack));
					Log_SetStringToLog(PreprocessText(label)); // returned by MAXIMUS - language switching mod
					Preprocessor_Remove("town_name");
					Preprocessor_Remove("island_name");
				}
				if (i < 0 && CheckAttribute(locCur, "label") == true) {
					Log_SetStringToLog(TranslateString("", locCur.label));
				}
// <-- KK
			}
		}
		SetEventHandler("frame","BLI_evntRefreshCommandMenu",1);
	}
	//LanguageCloseFile(tmpLangFileID);
}

#event_handler("procChrEnterToLocator","updateChrEntryToLocator");
void updateChrEntryToLocator()
{
	aref chr = GetEventData();
	string label = GetEventData();

	if(FindLoadedLocation()==-1 || label=="") { BreakLabelUpdate(chr); return; }
	if(dialogRun || dialogSelf) { BreakLabelUpdate(chr); return; }
	if(CheckAttribute(chr, "condition") && chr.condition=="reload") { BreakLabelUpdate(chr); return; }
	if(CheckAttribute(chr,"activeItem.Action")) { BreakLabelUpdate(chr); return; }
	if(chrWaitReloadLocator=="") { BreakLabelUpdate(chr); return; }

	ClearAllLogStrings();
	SendMessage(&ILogAndActions,"lls",LOG_ADD_STRING, false, label);
//	Log_SetStringToLog(label);
	PostEvent("procChrEnterToLocator",125,"is",chr,label);
}

void BreakLabelUpdate(aref chr)
{
	if(CheckAttribute(chr,"reloadStatus.label")) DeleteAttribute(chr,"reloadStatus.label");
	if(CheckAttribute(chr,"reloadStatus.update")) DeleteAttribute(chr,"reloadStatus.update");
	if(!CheckAttribute(chr,"boxname") && !CheckAttribute(chr,"activeItem.Action")) { RestoreLogInterface(); }
}

void RestoreLogInterface()
{
	if(!CheckAttribute(ILogAndActions,"log.changed")) return;
	CreateLogEnvironment();
	DeleteAttribute(ILogAndActions,"log.changed");

	SendMessage(&ILogAndActions,"lll",LOG_AND_ACTIONS_INIT,sti(InterfaceStates.BattleShow.FastCommand),sti(InterfaceStates.BattleShow.LogString));
	CheckCharacterAction();
	Log_SetStringToLog("");
}

void RestoreLogActions()
{
	if(!CheckAttribute(ILogAndActions,"ActiveActions.changed")) return;
	CreateLandActionsEnvironment();
	DeleteAttribute(ILogAndActions,"ActiveActions.changed");

	SendMessage(&ILogAndActions,"lll",LOG_AND_ACTIONS_CHANGE,sti(InterfaceStates.BattleShow.FastCommand),sti(InterfaceStates.BattleShow.LogString));
	if(chrWaitReloadLocator!="") CheckReloadAction(GetMainCharacter(), "");
	else CheckCharacterAction();
}

void SetUpLogInterface(string strData, int stColor, int stLeft, int stTop)
{//MAXIMUS: log-string can have any color and can be shown in any place (COLOR_*** can be replaced with argb(*,*,*,*))
	int stepLeft = sti(showWindow.left)+16;
	if(sti(stLeft)>0) stepLeft = sti(showWindow.left)+sti(stLeft);

	int stepUp = sti(showWindow.top)+80;
	if(sti(stTop)>0) stepUp = sti(showWindow.top)+sti(stTop);

	int stepColor = COLOR_GREEN_LIGHT;
	if(sti(stColor)==-1) stepColor = argb(0,255,255,255);//default
	else stepColor = sti(stColor);
	if(strData!="") { if(HasSubStr(strData,"careful") || HasSubStr(strData,"warning")) stepColor = COLOR_RED_LIGHT; }

	ILogAndActions.Log.left = stepLeft;
	ILogAndActions.Log.up = stepUp;
	ILogAndActions.Log.color = stepColor;
	ILogAndActions.log.changed = true;

	SendMessage(&ILogAndActions,"lll",LOG_AND_ACTIONS_INIT,sti(InterfaceStates.BattleShow.FastCommand),sti(InterfaceStates.BattleShow.LogString));
	CheckCharacterAction();
}

void SetUpLogActions(string textPath, int horzQuantity, int vertQuantity, int picNum)
{//MAXIMUS: action-icon can use any texture
	ILogAndActions.ActiveActions.TextureName = textPath;
	ILogAndActions.ActiveActions.horzQ = horzQuantity;
	ILogAndActions.ActiveActions.vertQ = vertQuantity;
	ILogAndActions.ActiveActions.TalkWith.IconNum = picNum;
	ILogAndActions.ActiveActions.changed = true;

	SendMessage(&ILogAndActions,"lll",LOG_AND_ACTIONS_CHANGE,sti(InterfaceStates.BattleShow.FastCommand),sti(InterfaceStates.BattleShow.LogString));
}
//MAXIMUS: <-[small improvement for these processes]-

void BLI_ChrExitFromLocation()
{
	SetEventHandler("frame","BLI_evntRefreshCommandMenu",1);
}

void LI_Reload()
{
/*	SetEvemt
	chrCharacterKeys
	ref mc = GetMainCharacter();
	Reload(chrWaitReloadRef, chrWaitReloadLocator, mc.location);
	chrWaitReloadLocator = "";
	chrWaitReloadIsNoLink = false;*/
	Event("Control Activation","s","ChrAction");
}

bool SetUsedPotionIcons()
{
	aref arItm, ar, uiref;
	int i, itmIdx, nq;
	ref mc = GetMainCharacter();

	bool bUsed = false;

	makearef(uiref,objLandInterface.UserIcons);
	nq = GetAttributesNum(uiref);
	for(i=0; i<nq; i++)
	{
		ar = GetAttributeN(uiref,i);
		if( CheckAttribute(ar,"potion") ) {
			DeleteAttribute(uiref,GetAttributeName(ar));
			nq--; i--;
		}
	}

	string UI_name;
	int UI_idx = 0;

	itmIdx = FindPotionFromChr(mc, &arItm, 0);
	while(itmIdx>=0)
	{
		if( EnablePotionUsing(mc,arItm) )
		{
			UI_idx++;
			UI_name = "potion"+UI_idx;
			objLandInterface.UserIcons.(UI_name).enable = true;
			objLandInterface.UserIcons.(UI_name).pic = GetPotionPicture(arItm);
			objLandInterface.UserIcons.(UI_name).tex = GetPotionTexture(arItm);
			objLandInterface.UserIcons.(UI_name).name = UI_name;
			objLandInterface.UserIcons.(UI_name).potion = arItm.id;
			objLandInterface.UserIcons.(UI_name).note = GetItemNameByID(arItm.id) + ": " + GetCharacterItem(mc, arItm.id); // KK
			bUsed = true;
		}
		itmIdx = FindPotionFromChr(mc, &arItm, itmIdx+1);
	}

	return bUsed;
}

bool Viper_SetPirateSailIcons() // Viper - Emblemed Sails v2
{
	ref pchar = GetMainCharacter();

	objLandInterface.UserIcons.viper_nation.enable		= true;
	objLandInterface.UserIcons.viper_nation.pic		= sti(pchar.nation) + 8
	objLandInterface.UserIcons.viper_nation.tex		= 8;
	objLandInterface.UserIcons.viper_nation.note		= "NationEmblem";
	objLandInterface.UserIcons.viper_nation.name		= "nation";

	string viperstr;
	int idLngFile = LanguageOpenFile("commands_name.txt");
	for (int i=0; i<15; i++)
	{
		viperstr = "viper_pirate" + i
		objLandInterface.UserIcons.(viperstr).enable		= true;
		objLandInterface.UserIcons.(viperstr).pic		= i;
		objLandInterface.UserIcons.(viperstr).tex		= 7;
		objLandInterface.UserIcons.(viperstr).note		= LanguageConvertString(idLngFile, viperstr);
		objLandInterface.UserIcons.(viperstr).name		= i;
	}
	objLandInterface.UserIcons.viper_pirate15.enable	= true;
	objLandInterface.UserIcons.viper_pirate15.pic		= 15;
	objLandInterface.UserIcons.viper_pirate15.tex		= 7;
	objLandInterface.UserIcons.viper_pirate15.note		= "Custom(15)";
	objLandInterface.UserIcons.viper_pirate15.name		= 15;
	LanguageCloseFile(idLngFile);
	return true;
}

bool SetReloadIcons()
{
	int tmpLangFileID = LanguageOpenFile("commands_name.txt"); // KK
	int i, nq, locidx;
	aref ar, curloc, locref, locList, uiref;
	ref mc = GetMainCharacter();

	bool bUse = false;

	makearef(uiref,objLandInterface.UserIcons);
	nq = GetAttributesNum(uiref);
	for(i=0; i<nq; i++)
	{
		ar = GetAttributeN(uiref,i);
		if( CheckAttribute(ar,"location") ) {
			DeleteAttribute(uiref,GetAttributeName(ar));
			nq--; i--;
		}
	}

	int idxloc = FindLoadedLocation();
	string str1,str2,fastLocName;
	string outGroupName = "";
	if(idxloc>=0 && CheckAttribute(&Locations[idxloc],"fastreload"))
	{
		outGroupName = Locations[idxloc].fastreload;
		if( CheckAttribute(&objFastReloadTable,"table."+outGroupName) )
		{
			makearef(locList,objFastReloadTable.table.(outGroupName));
			nq = GetAttributesNum(locList);
			for(i=0; i<nq; i++)
			{
				curloc = GetAttributeN(locList,i);
				if (CheckFastJump(Locations[idxloc].id, curloc.location)) {
					fastLocName = "fr_"+(i+1);
					objLandInterface.UserIcons.(fastLocName).enable = true;
					objLandInterface.UserIcons.(fastLocName).pic = curloc.pic;
					objLandInterface.UserIcons.(fastLocName).tex = 1+sti(curloc.tex);
					objLandInterface.UserIcons.(fastLocName).name = "reload"+i;
					objLandInterface.UserIcons.(fastLocName).location = curloc.location;
					objLandInterface.UserIcons.(fastLocName).note = LanguageConvertString(tmpLangFileID, curloc.note); // KK

// KK -->
					if (curloc.location == "Hold1" && GetCharacterShipCargoHoldCount(mc) > 1)
						objLandInterface.UserIcons.(fastLocName).note = LanguageConvertString(tmpLangFileID, curloc.note+"1");
					if (curloc.location == "Deck1" && GetCharacterShipCannonsDeckCount(mc) > 1)
						objLandInterface.UserIcons.(fastLocName).note = LanguageConvertString(tmpLangFileID, "go_UpperCannonsDeck");
// <-- KK

					bUse = true;
				}
			}
		}
		// to port icon
		if( GetCharacterShipType(mc)!=SHIP_NOTUSED )
		{
			if (CheckFastJump(Locations[idxloc].id, mc.location.from_sea) || Truncate(Locations[idxloc].id,0,3)=="QC_") //GreatZen
			{
				if(Locations[idxloc].id!="QC_port")//MAXIMUS -->
				{
					bool temp = true;
					if(Locations[FindLoadedLocation()].fastreload=="ship") temp = false;
					if(bDeckEnter) temp = false;
					if(temp)
					{
						objLandInterface.UserIcons.port.enable = true;
						objLandInterface.UserIcons.port.pic = 2;
						if(Locations[idxloc].fastreload=="QC") objLandInterface.UserIcons.port.pic = 1;
						objLandInterface.UserIcons.port.tex = 2;
						objLandInterface.UserIcons.port.name = "reloadtoport";

						if(Truncate(Locations[idxloc].id,0,3)=="QC_")
						{
							objLandInterface.UserIcons.port.location = "QC_port";
						}
						else 
						{ 
							objLandInterface.UserIcons.port.location = mc.location.from_sea; 
						}
						objLandInterface.UserIcons.port.note = LanguageConvertString(tmpLangFileID, "go_port");
					}
				}//MAXIMUS <--
				bUse = true;
			}
		}
	}
	LanguageCloseFile(tmpLangFileID);
	return bUse;
}

void SetOfficerTexture(int officerIdx)
{
	aref ar; makearef(ar,objLandInterface.Parameters);
	string attrName = "iconTexture"+officerIdx;

	int cn = GetOfficersIndex(GetMainCharacter(),officerIdx);
	if (cn < 0) {
		DeleteAttribute(ar,attrName);
		ar.(attrName) = "";
	} else {
		ar.(attrName) = "interfaces\portraits\64\face_"+Characters[cn].FaceID+".tga";
	}
}

// KK: fixed officers-icons - we'll see proper icon for each officer in any location (simpler than MAXIMUS did) -->
void BLI_UpdateOfficers()
{
	BLI_SetObjectData();
	CheckOfficers();//MAXIMUS: all was moved down and BLI_UpdateObjectData will check officers-icons too :) [this will exclude hundreds of BLI_UpdateOfficers() in different places]
}

void CheckOfficers()
{
	ref mchr = GetMainCharacter();
	int i = -1;
	for (int o = 0; o < 4; o++) {
		int idx = GetOfficersIndex(mchr, o);
		if (idx < 0) continue;
		ref ochr = GetCharacter(idx);
		if (IsEntity(ochr)) {
			i++;
			SetOfficerTexture(o);
			string iTex = "iconTexture" + o;
			SendMessage(&objLandInterface, "lls", MSG_BATTLE_LAND_SET_ICONTEX, i, objLandInterface.Parameters.(iTex));
		}
	}
}
// <-- KK

int GetPotionPicture(aref arItm)
{
	if( CheckAttribute(arItm,"potion.pic") ) {
		return sti(arItm.potion.pic);
	}
	traceif("Item "+arItm.id+ " hav`t POTION.PIC attribute");
	return 0;
}

int GetPotionTexture(aref arItm)
{
	if( !CheckAttribute(arItm,"potion.tex") ) {
		traceif("Item "+arItm.id+ " hav`t POTION.TEX attribute");
		return 0;
	}
	return 3+sti(arItm.potion.tex);
}

bool CanBeUseItem(ref chref)
{
	// NK rewrite for speed 04-09-08 -->
	/*for(int i=0; i<ITEMS_QUANTITY; i++)
	{
		if( CheckAttribute(&Items[i],"potion") && CheckAttribute(chref,"items."+Items[i].id) ) {
			if( EnablePotionUsing(chref,&Items[i]) ) {return true;}
		}
	}*/
	aref chritems; makearef(chritems, chref.items);
	int idx;
	for(int i = 0; i < GetAttributesNum(chritems); i++)
	{
		idx = GetItemIndex(GetAttributeName(GetAttributeN(chritems, i)));
		if (idx < 0) continue;		// LDH fix for negative index
		if(CheckAttribute(&Items[idx],"potion")) { if( EnablePotionUsing(chref,&Items[idx]) ) {return true;} }
	}
	return false;
	// NK <--
}

// NK rewrite to use native StrCut() -->
string Truncate(string str,int pos,int pos2)
{               
  /*string a="";
  int i;
  for (i=pos;i<pos2;i++)
 {
   a=a+GetSymbol(str,i);
 }

  return a;*/
	return strcut(str, pos, pos2-1);
}
// NK <--

// KK -->
bool SetShipIcons()
{
	int idLngFile = LanguageOpenFile("commands_name.txt");

	ref mchr = GetMainCharacter();
	int ndecks = GetCharacterShipCannonsDeckCount(mchr);
	int nholds = GetCharacterShipCargoHoldCount(mchr);

	objLandInterface.UserIcons.ShipDeck.enable	= true;
	objLandInterface.UserIcons.ShipDeck.pic		= 11;
	objLandInterface.UserIcons.ShipDeck.tex		= 1;
	objLandInterface.UserIcons.ShipDeck.note	= LanguageConvertString(idLngFile, "land_EnterShipDeck");
	objLandInterface.UserIcons.ShipDeck.name	= "ShipDeck";

	objLandInterface.UserIcons.Cabin.enable		= GetCharacterShipCabin(mchr)!="Cabin_none";
	objLandInterface.UserIcons.Cabin.pic		= 12;
	objLandInterface.UserIcons.Cabin.tex		= 1;
	objLandInterface.UserIcons.Cabin.note		= LanguageConvertString(idLngFile, "land_EnterCabin");
	objLandInterface.UserIcons.Cabin.name		= "Cabin";

	objLandInterface.UserIcons.Seadogs.enable	= GetCharacterShipCQuarters(mchr)!="";
	objLandInterface.UserIcons.Seadogs.pic		= 13;
	objLandInterface.UserIcons.Seadogs.tex		= 1;
	objLandInterface.UserIcons.Seadogs.note		= LanguageConvertString(idLngFile, "land_EnterSeadogs");
	objLandInterface.UserIcons.Seadogs.name		= "Seadogs";

	if (ndecks > 0) {
		objLandInterface.UserIcons.Deck1.enable		= true;
		objLandInterface.UserIcons.Deck1.pic		= 14;
		objLandInterface.UserIcons.Deck1.tex		= 1;
		if (ndecks == 1)
			objLandInterface.UserIcons.Deck1.note	= LanguageConvertString(idLngFile, "land_EnterMainCannonsDeck");
		else
			objLandInterface.UserIcons.Deck1.note	= LanguageConvertString(idLngFile, "land_EnterUpperCannonsDeck");
		objLandInterface.UserIcons.Deck1.name		= "Deck1";
	}

	if (ndecks > 2) {
		objLandInterface.UserIcons.Deck2.enable		= true;
		objLandInterface.UserIcons.Deck2.pic		= 14;
		objLandInterface.UserIcons.Deck2.tex		= 1;
		objLandInterface.UserIcons.Deck2.note		= LanguageConvertString(idLngFile, "land_EnterLowerCannonsDeck");
		objLandInterface.UserIcons.Deck2.name		= "Deck2";
	}

	if (ndecks > 1) {
		objLandInterface.UserIcons.Deck3.enable		= true;
		objLandInterface.UserIcons.Deck3.pic		= 14;
		objLandInterface.UserIcons.Deck3.tex		= 1;
		objLandInterface.UserIcons.Deck3.note		= LanguageConvertString(idLngFile, "land_EnterMainCannonsDeck");
		objLandInterface.UserIcons.Deck3.name		= "Deck3";
	}

	if (nholds > 0) {
		objLandInterface.UserIcons.Hold1.enable		= true;
		objLandInterface.UserIcons.Hold1.pic		= 15;
		objLandInterface.UserIcons.Hold1.tex		= 1;
		objLandInterface.UserIcons.Hold1.note		= LanguageConvertString(idLngFile, "land_EnterHold");
		objLandInterface.UserIcons.Hold1.name		= "Hold1";
	}

	if (nholds > 1) {
		objLandInterface.UserIcons.Hold2.enable		= true;
		objLandInterface.UserIcons.Hold2.pic		= 15;
		objLandInterface.UserIcons.Hold2.tex		= 1;
		objLandInterface.UserIcons.Hold2.note		= LanguageConvertString(idLngFile, "land_EnterHold2");
		objLandInterface.UserIcons.Hold2.name		= "Hold2";

		objLandInterface.UserIcons.Hold1.note		= LanguageConvertString(idLngFile, "land_EnterHold1");
	}

	LanguageCloseFile(idLngFile);
	return true;
}

void ReloadFromLandToSea()
{
	ref pchar = GetMainCharacter();
	Reload(chrWaitReloadRef, chrWaitReloadLocator, pchar.location);
	DirectsailCheck();
}
// <-- KK
