//===========================================================================//
// File:	VehicleInterface.cpp								
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 09/09/98  JSE  Inital base class based off of Shadowrun/Adept			 //
// 12/26/01  MSL  Added Eject Betty to both SetEjectMode and SetDeathMode    //
// 04/18/02  MSL  Changed Centering to be smooth all the way thru            //
// 04/18/02  MSL  Changed code for Shutdown due to Autostartup issue         //
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive										 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

// hyun begin
#include "MW4.hpp"
#include "Vehicle.hpp"
#include "MechAnimationState.hpp"
#include "Blanderizer.hpp"
#include "DeceleratorOf.hpp"
#include "SpringOf.hpp"
#include "MechLabHeaders.h"
#include <Stuff\Spline.hpp>
// hyun end


#include "MW4Headers.hpp"

#include "VehicleInterface.hpp"
#include "PlayerAI.hpp"
#include "MWGUIManager.hpp"
#include "Torso.hpp"
#include "MWMission.hpp"
#include "CameraShip.hpp"
#include "BeamWeapon.hpp"
#include "MissileWeapon.hpp"
// MSL 5.03 RTX
//#include "rtxweaponsub.hpp"
#include "GUIRadarManager.hpp"
#include "hudmap.hpp"
#include "GUILightAmp.hpp"
#include "GUIStaticView.hpp"
#include "MWPlayer.hpp"
#include "GUIWeaponManager.hpp"
#include "MWDebugHelper.hpp"
#include "HeatManager.hpp"
#include "Beagle.hpp"
#include "ECM.hpp"
// MSL 5.02 SubSystems
#include "IFF_Jammer.hpp"
#include "AdvancedGyro.hpp"
//#include "MWTable.hpp"
#include "LongTomWeapon.hpp"
#include "AI_Groups.hpp"
#include "MWApplication.hpp"
#include "SubsystemClassData.hpp"
#include "hudweapon.hpp"
#include "hudcomp2.hpp"
#include "hudcomm.hpp"
#include "hudchat.hpp"
#include "huddamage.hpp"
#include "hudcamera.hpp"
#include "DamageDispatch.hpp"
#include "EyePointManager.hpp"
#include "mw4shell.hpp"
#include "NavPoint.hpp"
//sanghoon begin
#include "MWVideoRenderer.hpp"
//sanghoon end

#include <Adept\CollisionGrid.hpp>
#include <Adept\Controls.hpp>
#include <Adept\DropZone.hpp>
#include <Adept\Effect.hpp>
#include <Adept\GUITextManager.hpp>
#include <Adept\GUITextObject.hpp>
#include <Adept\CameraComponent.hpp>
#include <Adept\Map.hpp>
#include <Adept\CollisionVolume.hpp>
#include <Adept\AudioRenderer.hpp>
#include <adept\joystick.hpp>
#include <Adept\DamageObject.hpp>
#include <MLR\MLRClipper.hpp>
#include <Adept\AudioCommand.hpp>
#include <Adept\AudioRenderer.hpp>
#include "ABLAudio.hpp" // for PLAY_MUSIC
#include "HUDscore.hpp"

#include "objective.hpp"
#include "missionlang\resource.h"

#undef STRICT
#include "gameos\pch.hpp"
extern int ScreenImageSize;
extern void __stdcall End3DScene();
extern BYTE* _stdcall GrabScreenImage(IDirectDrawSurface7* pBBSurface, int nScrW, int nScrH);
bool _stdcall WriteImageAfterGrab(BYTE* Image, const char* pcszFilePrefix);

#include <gosFX\Flare.hpp>
#include <mbstring.h>
#define __mbsrchr(s,c) (char*)_mbsrchr((const unsigned char*)(s),(c))

// hyun begin
#include <windows.h>

#include "ctcls.h"
#include "ctcl.h"

extern const char g_szRadarShutdown[];
extern const char g_szRadarStartup[];
extern const char g_szRadarJumpjet[];
extern const char g_szRadarZoom[];
extern char g_aaRadarText[12][32];

extern int g_nTimeList_Index;
extern int g_nTimeList_Value;

// MSL 5.06
extern int g_nBlackMech;
extern int g_nMechVariant;
extern int g_nMechLabOp;
extern int g_nMechPodNum;

extern bool g_bCOOP;

int g_nNoWeapons = 0;

enum {TEAMORDER_NONE, TEAM_MODE, FREEFORALL_MODE, TEAM_MESSAGE1, TEAM_MESSAGE2};

#ifdef _DEBUG
#define USE_DEATH_OVERSHOULD 0
#define DEATH_TRANS_2 0
#else // !_DEBUG
#define USE_DEATH_OVERSHOULD 0
#define DEATH_TRANS_2 0
#endif // _DEBUG

#if USE_DEATH_OVERSHOULD
LinearMatrix4D g_camToParent4Temp;
#endif // USE_DEATH_OVERSHOULD

static Scalar s_fUseInter = 30.0;
extern int g_nMR;
bool g_bNoTOCKeys = false;
int g_nTeamOrderMode = 0;//han
int g_TeamOrderCount = 0;//han
int g_TeamOrderOthers = 0;//han
SMechInfo g_aMechInfos[16];
int g_TeamOrderCountSave = 0;//han
int g_TeamOrderOthersSave = 0;//han
SMechInfo g_aSavedMechInfos[16];
int g_nTeamOrderSelect = 0; // rio button number...

Scalar g_fLastStartTime;
Scalar g_fLastCameraShipTime;
Scalar g_fLastScoringTimeCechk;
Scalar g_fLastScoringTime;
Adept::ReplicatorID g_LastTarget;

Time g_PlasmaClearTime = 15.0;

bool g_bFixedCamera = false;
Point3D g_ptFixedCameraPos(0.0, 0.0, 0.0);

extern bool g_bCanSuicideAllways;
extern bool g_f3dtarget;

extern bool g_bMuteMode;
// MSL 5.05 Objective Display
extern bool g_bObjMode;

// MSL 5.02 Pinky Button
extern bool g_bJumpZoom;
extern bool g_bZoomMode;
extern bool g_bJumpMode;
extern bool g_bFlushMode;
extern bool g_bLightAmpMode;
extern bool	g_bNextTargetMode;
extern bool g_bCrossTargetMode;
// MSL 5.03 Secondary Damage Display
extern int g_nAuxilMode;

BOOL MechWarrior4::g_baChainFireMode[3] = { FALSE, FALSE, FALSE };//han

#include "Criomain.h"
#include "Criomain.cpp"

extern HWND		hWindow;

#define CAMERASHIP_SCORING_CHECK  1.5

// MSL 5.02 Zoom
//float g_fZoomMarginLR = 0.12f;
float g_fZoomMarginLR = 0.35f;
float g_fZoomFOVA = 0.2f;
float g_fZoomFOVB = 0.1f;
// float g_fZoomTime = 0.5f;
float g_fZoomTime = 0.0f;
float g_fZoomTimeC = 0.0f;
///

bool g_bLockCurrentHero = false;
int g_nSecsMissionReplay = 60;
float g_fSecsMissionReport = 15.0f;
float g_fAutoPowerUpLevel = 0.66;
float g_fNeedFlushLevel = 0.66;
float g_fTimeMsgSender = 1.5f;
float g_fTimeScoringAtEnd = 10.0f;
Mech* FindNextMechToFollowByScore(Mech* pCur); // jcem
// hyun end

CamerashipParams g_CamerashipParams;

const Scalar TORSO_TWIST_SOUND_DELAY 	= 5.0f;
const Scalar STEP_WATER_SOUND_DELAY 	= 60.0f;
const Scalar HEAT_SOUND_DELAY					= 5.0f;
const Scalar NEW_RADAR_SOUND_DELAY		= 1.0f;
const Scalar OUT_AMMO_SOUND_DELAY			= 3.0f;
const Scalar LIGHT_AMP_MOD_PER_SECOND = 0.6f;
const Scalar ENGINE_SOUND_DELAY				= 0.5f;

bool VehicleInterface::m_MouseYEnable = true;
Scalar VehicleInterface::m_MouseMinChange = 0.015f;
Scalar VehicleInterface::m_MouseMaxChange = 0.75f;

static int	s_preferredTargetReticuleCameraPosition = 3;
#define C_MAXEXTERNALTARGETRETICULEVALUE  3 // internal is max + 1
void VehicleInterface::RestorePreferredCameraPosition() {m_currentTargetReticuleCameraPosition = s_preferredTargetReticuleCameraPosition;}
void VehicleInterface::SetPreferredCameraPosition(int newCameraReticuleCameraPosition) {s_preferredTargetReticuleCameraPosition = newCameraReticuleCameraPosition;}

#if defined(_ARMOR)
	int Debug_Frame_Rate_Counter = 0;
#endif

bool __stdcall Check_MouseControl(void);
void __stdcall Activate_MouseControl(void);

#define C_MAXZOOMSETTINGS 2
static Stuff::Scalar s_zoomFOV[C_MAXZOOMSETTINGS-1]={0.0525f};
static int s_zoomDisplayLevel[C_MAXZOOMSETTINGS-1]={5 /* ="5x" */};

void MechWarrior4::VehicleInterfaceSecurityCheckStart()
{
	_asm
	{
		nop
	}	
}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// wave data
//
#if !defined(LAB_ONLY)
	#define PLAY_SOUND(string)\
	{\
		if ((g_nMR != 2) && ((string##_TYPE != AudioRenderer::BettyType) || (MW4Shell::Instance->m_optionsObject->m_bettyOn))) \
		{\
			AudioCommand *asdf = AudioCommand::Create(string##_TYPE, string##_WAV, 1.0f, 1.0f);\
			Check_Object(asdf); asdf->Play();\
		}\
	}
#else
	#define PLAY_SOUND(string)\
	{\
		if ((g_nMR != 2) && ((string##_TYPE != AudioRenderer::BettyType) || (MW4Shell::Instance->m_optionsObject->m_bettyOn))) \
		{\
		AudioCommand *asdf = AudioCommand::Create(string##_TYPE, string##_WAV, 1.0f, 1.0f);\
		if (asdf)\
			asdf->Play();\
		else\
			PAUSE(("%s can't be found!", string##_WAV));\
		}\
	}
#endif

// 3/20/02 CBT: new support for playing music across the network
#if !defined(LAB_ONLY)
	#define PLAY_MUSIC(string)\
	{\
		AudioCommand *command = AudioCommand::Create(AudioRenderer::MusicType, string##_WAV, 1.0f, 1.0f);\
		if ((command) &&\
			(ABL::AudioManager::GetInstance() != 0))\
		{\
			ABL::AudioManager::GetInstance()->AddMusicCommand(command, string##_OLD_TIMEOUT, string##_NEW_TIMEIN, string##_NEW_VOLUME);\
		}\
	}
#else
	#define PLAY_MUSIC(string)\
	{\
		AudioCommand *command = AudioCommand::Create(AudioRenderer::MusicType, string##_WAV, 1.0f, 1.0f);\
		if ((command) &&\
			(ABL::AudioManager::GetInstance() != 0))\
		{\
			ABL::AudioManager::GetInstance()->AddMusicCommand(command, string##_OLD_TIMEOUT, string##_NEW_TIMEIN, string##_NEW_VOLUME);\
		}\
		else\
			PAUSE(("%s can't be found!", string##_WAV));\
	}
#endif

#define COINDROP_TYPE AudioRenderer::MechanicalType
#define COINDROP_WAV "sfx_signal_objectivechange.wav{handle}" // sfx_narc_idle.wav

#define ENGINE_IDLE_TYPE AudioRenderer::MechanicalType
#define ENGINE_IDLE_WAV "engineidle01_22.wav{handle}"

#define DAMAGE_CRITICAL_TYPE AudioRenderer::BettyType
#define DAMAGE_CRITICAL_WAV "vo\\generic\\DamageCritical_Bet.wav{handle}"
#define INTERNAL_PPC_WASH_TYPE AudioRenderer::MechanicalType
#define INTERNAL_PPC_WASH_WAV "sfx_ppc_wash.wav{handle}"
#define REACT_TO_GIMP_TYPE AudioRenderer::BettyType
#define REACT_TO_GIMP_WAV "vo\\generic\\LegDestroyed_Bet.wav{handle}"
#define WEAPON_DESTROYED_TYPE AudioRenderer::BettyType
#define WEAPON_DESTROYED_WAV "vo\\generic\\WeaponDestroyed_Bet.wav{handle}"
#define CORE_BREACHED_TYPE AudioRenderer::BettyType
#define CORE_BREACHED_WAV "vo\\generic\\ArmorBreached_Bet.wav{handle}"

#define HIGH_HEAT_TYPE AudioRenderer::BettyType
#define HIGH_HEAT_WAV "vo\\generic\\HeatSuperHigh_Bet.wav{handle}"
#define MED_HEAT_TYPE AudioRenderer::BettyType
#define MED_HEAT_WAV "vo\\generic\\HeatVeryHigh_Bet.wav{handle}"
#define LOW_HEAT_TYPE AudioRenderer::BettyType
#define LOW_HEAT_WAV "vo\\generic\\HeatHigh_Bet.wav{handle}"

#define NAVPOINT_REACHED_TYPE AudioRenderer::BettyType
#define NAVPOINT_REACHED_WAV "vo\\generic\\NavReached_BET.wav{handle}"	// "nav reached" sound for Escort missions

#define RADAR_RANGE_CHANGE_TYPE AudioRenderer::MechanicalType
#define RADAR_RANGE_CHANGE_WAV "sfx_zoom.wav{handle}"						// set to zoom on purpose.
#define RADAR_ON_TYPE AudioRenderer::MechanicalType // jcem - AudioRenderer::BettyType // Probably will have voice in it somewhere
#define RADAR_ON_WAV "sfx_button5.wav{handle}" // jcem - "vo\\generic\\RadarActive_Bet.wav{handle}"
#define RADAR_OFF_TYPE AudioRenderer::MechanicalType // jcem - AudioRenderer::BettyType // Probably will have voice in it somewhere
#define RADAR_OFF_WAV "sfx_button5.wav{handle}" // jcem - "vo\\generic\\RadarPassive_Bet.wav{handle}"
#define RADAR_JAMMED_TYPE AudioRenderer::MechanicalType			// Andrew, based on game, we should only have two radar
#define RADAR_JAMMED_WAV "sfx_radar_jammed.wav{handle}"			// commands.  1 for turn on (active), 1 for turn off (passive).
#define NEW_VEHICLE_RADAR_POWER_UP_TYPE AudioRenderer::BettyType  // you can cut the radar jammed audio.
#define NEW_VEHICLE_RADAR_POWER_UP_WAV "vo\\generic\\EnemyDetected_Bet.wav{handle}"
#define OBJECT_SCANNED_TYPE AudioRenderer::MechanicalType
#define OBJECT_SCANNED_WAV "sfx_radar_scanned.wav{handle}"  // you can cut the radar scanned audio.
#define ZOOM_TYPE AudioRenderer::MechanicalType
#define ZOOM_WAV "sfx_zoom.wav{handle}"

#define NARC_SIGNAL_START_TYPE AudioRenderer::MechanicalType
#define NARC_SIGNAL_START_WAV "sfx_narc_idle_2d.wav{handle}"
#define NARC_HIT_TYPE AudioRenderer::MechanicalType
#define NARC_HIT_WAV "sfx_narc_hit_2d.wav{handle}"

#define ENGINE_WALK_TYPE AudioRenderer::MechanicalType
#define ENGINE_WALK_WAV "engineshiftfwd01_22.wav{handle}"
#define ENGINE_RUN_TYPE AudioRenderer::MechanicalType
#define ENGINE_RUN_WAV "engineshiftfwdfast01_22.wav{handle}"
#define ENGINE_STOP_TYPE AudioRenderer::MechanicalType
#define ENGINE_STOP_WAV "engineshiftstop01_22.wav{handle}"
#define ENGINE_REVERSE_TYPE AudioRenderer::MechanicalType
#define ENGINE_REVERSE_WAV "engineshiftrev01_22.wav{handle}"
// Need an engine loop here

#define TORSO_TWIST_TYPE AudioRenderer::MechanicalType
#define TORSO_TWIST_WAV "sfx_torso.wav{handle}"
#define TORSO_TWIST_MAX_REACHED_TYPE AudioRenderer::MechanicalType
#define TORSO_TWIST_MAX_REACHED_WAV "sfx_torso_maxed.wav{handle}"
// Need a torso end sound

#define HILL_TOO_STEEP_TYPE AudioRenderer::BettyType // maybe will have betty in it
#define HILL_TOO_STEEP_WAV "cmp_hill_too_steep.wav{handle}"
#define TERRAIN_BAD_TYPE AudioRenderer::BettyType // maybe will have betty in it
#define TERRAIN_BAD_WAV "cmp_terrain_bad.wav{handle}"		// Can cut this also I think - Davelueh
#define WATER_TYPE AudioRenderer::MechanicalType
#define WATER_WAV "sfx_water.wav{handle}"

#define RECHARGE_BEAM_TYPE AudioRenderer::MechanicalType
#define RECHARGE_BEAM_WAV "sfx_laserlrg_charge.wav{handle}"
#define RECHARGE_MISSILE_TYPE AudioRenderer::MechanicalType
#define RECHARGE_MISSILE_WAV "sfx_missle_reload.wav{handle}"
#define RECHARGE_PROJECTILE_TYPE AudioRenderer::MechanicalType
#define RECHARGE_PROJECTILE_WAV "sfx_ac_reload.wav{handle}"
#define RECHARGE_PPC_TYPE AudioRenderer::MechanicalType
#define RECHARGE_PPC_WAV "sfx_ppc_charge.wav{handle}"
#define OUT_OF_AMMO_TYPE AudioRenderer::BettyType
#define OUT_OF_AMMO_WAV "vo\\generic\\ammodepleted_bet.wav{handle}"
#define AMMO_DUMPED_TYPE AudioRenderer::BettyType
#define AMMO_DUMPED_WAV "vo\\generic\\ammodumped_bet.wav{handle}"
// MSL 5.03 No Weapon Betty
#define NO_WEAPON_TYPE AudioRenderer::BettyType
#define NO_WEAPON_WAV "vo\\generic\\NoWeapons_bet.wav{handle}"

#define MECH_POWERUP_TYPE AudioRenderer::MechanicalType //maybe will have betty
#define MECH_POWERUP_WAV "sfx_engine_powerup.wav{handle}"
#define MECH_POWERDOWN_TYPE AudioRenderer::MechanicalType //maybe will have betty
#define MECH_POWERDOWN_WAV "sfx_engine_powerdown.wav{handle}"

#define MECH_POWERDOWN_OVERRIDE_TYPE AudioRenderer::BettyType //maybe will have betty
#define MECH_POWERDOWN_OVERRIDE_WAV "vo\\generic\\shutdownoveride_Bet.wav{handle}"

#define INCOMING_MISSILE_TYPE AudioRenderer::MechanicalType // nasty loop here
#define INCOMING_MISSILE_WAV "cmp_incoming_missile.wav{handle}"
#define MISSILE_LOCK_TYPE AudioRenderer::MechanicalType
#define MISSILE_LOCK_WAV "sfx_misslelock.wav{handle}"
#define AMS_TYPE AudioRenderer::MechanicalType
#define AMS_WAV "sfx_ams.wav{handle}"
#define LAMS_TYPE AudioRenderer::MechanicalType
#define LAMS_WAV "sfx_lams.wav{handle}"

#define COOLANT_TYPE AudioRenderer::MechanicalType
#define COOLANT_WAV "sfx_coolant_flush.wav{handle}"
#define COOLANT_END_TYPE AudioRenderer::MechanicalType
#define COOLANT_END_WAV "sfx_coolant_flush_end.wav{handle}"

#define TARGET_DESTROYED_TYPE AudioRenderer::BettyType
#define TARGET_DESTROYED_WAV "vo\\generic\\TargetDestroyed_Bet.wav{handle}"

#define KILLAWARDED_TYPE AudioRenderer::BettyType
#define KILLAWARDED_WAV "vo\\generic\\KillAwarded_Bet.wav{handle}"

#define FRIENDLYFIREPENALTY_TYPE AudioRenderer::BettyType
#define FRIENDLYFIREPENALTY_WAV "vo\\generic\\FriendlyFirePenalty_Bet.wav{handle}"

#define YOUHAVEFLAG_TYPE AudioRenderer::BettyType
#define YOUHAVEFLAG_WAV "vo\\generic\\YouHaveFlag_Bet.wav{handle}"

#define YOUINLEAD_TYPE AudioRenderer::BettyType
#define YOUINLEAD_WAV "vo\\generic\\YouInLead_Bet.wav{handle}"

#define TEAMMATEDESTROYED_TYPE AudioRenderer::BettyType
#define TEAMMATEDESTROYED_WAV "vo\\generic\\TeammateDestroyed_Bet.wav{handle}"

#define FLAGTAKEN_TYPE AudioRenderer::BettyType
#define FLAGTAKEN_WAV "vo\\generic\\FlagTaken_Bet.wav{handle}"

#define FLAGCAPTURED_TYPE AudioRenderer::BettyType
#define FLAGCAPTURED_WAV "vo\\generic\\FlagCaptured_Bet.wav{handle}"

#define FLAGCAPTUREDHORN_TYPE AudioRenderer::BettyType
#define FLAGCAPTUREDHORN_WAV "vo\\generic\\FlagCapturedHorn_Bet.wav{handle}"

#define FLAGCAPTUREDBUZZER_TYPE AudioRenderer::BettyType
#define FLAGCAPTUREDBUZZER_WAV "vo\\generic\\FlagCapturedBuzzer_Bet.wav{handle}"

#define FLAGRETURNED_TYPE AudioRenderer::BettyType
#define FLAGRETURNED_WAV "vo\\generic\\FlagReturned_Bet.wav{handle}"

#define HILLCONTESTED_TYPE AudioRenderer::BettyType
#define HILLCONTESTED_WAV "vo\\generic\\HillContested_Bet.wav{handle}"

#define HILLCAPTURED_TYPE AudioRenderer::BettyType
#define HILLCAPTURED_WAV "vo\\generic\\HillCaptured_Bet.wav{handle}"

#define REPAIR_START_TYPE AudioRenderer::BettyType
#define REPAIR_START_WAV "vo\\generic\\InitRepairs_Bet.wav{handle}"

#define REPAIR_STOP_TYPE AudioRenderer::BettyType
#define REPAIR_STOP_WAV "vo\\generic\\RepairsComplete_Bet.wav{handle}"

#define DEFENDEDDESTROYED_TYPE AudioRenderer::BettyType
#define DEFENDEDDESTROYED_WAV "vo\\generic\\DEFENDEDDESTROYED_bet.wav{handle}" 

#define MECH_DESTROYED_TYPE AudioRenderer::BettyType
#define MECH_DESTROYED_WAV "vo\\generic\\MechDestroyed_Bet.wav{handle}" 

#define ENEMY_DEAD_TYPE AudioRenderer::BettyType
#define ENEMY_DEAD_WAV "vo\\generic\\EnemyUnitDestroyed_Bet.wav{handle}" 

#define ALLY_DEAD_TYPE AudioRenderer::BettyType
#define ALLY_DEAD_WAV "vo\\generic\\AlliedUnitDestroyed_Bet.wav{handle}" 

#define LANCE_DEAD_TYPE AudioRenderer::BettyType
#define LANCE_DEAD_WAV "vo\\generic\\LancemateDestroyed_Bet.wav{handle}" 

#define COMM_OFF_TYPE AudioRenderer::BettyType
#define COMM_OFF_WAV "vo\\generic\\CommOffline_Bet.wav{handle}" 

#define INIT_REPAIR_TYPE AudioRenderer::BettyType
#define INIT_REPAIR_WAV "vo\\generic\\InitRepairs_Bet.wav{handle}" 

#define REPAIR_COMP_TYPE AudioRenderer::BettyType
#define REPAIR_COMP_WAV "vo\\generic\\RepairsComplete_Bet.wav{handle}" 

#define ENEMY_CAPTURED_TYPE AudioRenderer::BettyType
#define ENEMY_CAPTURED_WAV "vo\\generic\\EnemyCaptured_Bet.wav{handle}" 

#define NAV_ALPHA_TYPE AudioRenderer::BettyType
#define NAV_ALPHA_WAV "vo\\generic\\NavAlpha_Bet.wav{handle}" 

#define NAVA_TYPE AudioRenderer::BettyType
#define NAVA_WAV "vo\\generic\\NavBeta_Bet.wav{handle}" 

#define NAV_GAMMA_TYPE AudioRenderer::BettyType
#define NAV_GAMMA_WAV "vo\\generic\\NavGamma_Bet.wav{handle}" 

#define NAV_DELTA_TYPE AudioRenderer::BettyType
#define NAV_DELTA_WAV "vo\\generic\\NavDelta_Bet.wav{handle}" 

#define NAV_EPSL_TYPE AudioRenderer::BettyType
#define NAV_EPSL_WAV "vo\\generic\\NavEpsilon_Bet.wav{handle}" 

#define EXTRACT_POINT_TYPE AudioRenderer::BettyType
#define EXTRACT_POINT_WAV "vo\\generic\\ExtractionPoint_Bet.wav{handle}" 

#define TEAM_DEAD_TYPE AudioRenderer::BettyType
#define TEAM_DEAD_WAV "vo\\generic\\TeammateDestroyed_Bet.wav{handle}" 

#define YOU_WIN_TYPE AudioRenderer::BettyType
#define YOU_WIN_WAV "vo\\generic\\YouWin_Bet.wav{handle}" 

#define YOU_LOSE_TYPE AudioRenderer::BettyType
#define YOU_LOSE_WAV "vo\\generic\\YouLose_Bet.wav{handle}" 

#define VICTORY_BABY_TYPE AudioRenderer::BettyType
#define VICTORY_BABY_WAV "vo\\generic\\VictoryImminent_Bet.wav{handle}" 

#define ALL_HILLS_TYPE AudioRenderer::BettyType
#define ALL_HILLS_WAV "vo\\generic\\AllHillsCaptured_Bet.wav{handle}" 

#define BASE_CAPTURED_TYPE AudioRenderer::BettyType
#define BASE_CAPTURED_WAV "vo\\generic\\BaseCaptured_Bet.wav{handle}" 
 
// MSL 5.02 headshot
#define COMPONENT_DESTROYED_TYPE AudioRenderer::BettyType
#define COMPONENT_DESTROYED_WAV "vo\\generic\\ComponentDestroyed_Bet.wav{handle}" //temporary

// MSL 5.03 Gyro Hit
#define COMPDESTROYED_TYPE AudioRenderer::BettyType
#define COMPDESTROYED_WAV "vo\\generic\\CompDestroyed_Bet.wav{handle}" //temporary

#define ZOOM_FAIL_TYPE AudioRenderer::MechanicalType
#define ZOOM_FAIL_WAV "sfx_wrongbutton.wav{handle}" 

#define MECH_AMMOBAY_FIRE_TYPE AudioRenderer::MechanicalType
//#define MECH_AMMOBAY_FIRE_WAV "sfx_signal_missilelock.wav{handle}" 
#define MECH_AMMOBAY_FIRE_WAV "sfx_ammo_bay_fire.wav{handle}" 

// coliseum crowd sounds ---
#define COLISEUM_AHH_TYPE AudioRenderer::MechanicalType
#define COLISEUM_AHH_WAV "vo\\generic\\mp\\Ahh.wav{handle}" 

#define COLISEUM_AWW_TYPE AudioRenderer::MechanicalType
#define COLISEUM_AWW_WAV "vo\\generic\\mp\\Aww.wav{handle}" 

#define COLISEUM_BOO1_TYPE AudioRenderer::MechanicalType
#define COLISEUM_BOO1_WAV "vo\\generic\\mp\\boo1.wav{handle}" 

#define COLISEUM_BOO2_TYPE AudioRenderer::MechanicalType
#define COLISEUM_BOO2_WAV "vo\\generic\\mp\\boo2.wav{handle}" 

#define COLISEUM_BOO3_TYPE AudioRenderer::MechanicalType
#define COLISEUM_BOO3_WAV "vo\\generic\\mp\\boo3.wav{handle}" 

#define COLISEUM_CHANT1_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CHANT1_WAV "vo\\generic\\mp\\chant1.wav{handle}" 

#define COLISEUM_CHANT3_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CHANT3_WAV "vo\\generic\\mp\\chant3.wav{handle}" 

#define COLISEUM_CHEER1_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CHEER1_WAV "vo\\generic\\mp\\cheer1.wav{handle}" 

#define COLISEUM_CHEER2_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CHEER2_WAV "vo\\generic\\mp\\cheer2.wav{handle}" 

#define COLISEUM_CHEER3_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CHEER3_WAV "vo\\generic\\mp\\cheer3.wav{handle}" 

#define COLISEUM_CHEER4_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CHEER4_WAV "vo\\generic\\mp\\cheer4.wav{handle}" 

#define COLISEUM_CHEER5_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CHEER5_WAV "vo\\generic\\mp\\cheer5.wav{handle}" 

#define COLISEUM_CHEER8_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CHEER8_WAV "vo\\generic\\mp\\cheer8.wav{handle}" 

#define COLISEUM_CHEER9_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CHEER9_WAV "vo\\generic\\mp\\cheer9.wav{handle}" 

#define COLISEUM_CROWD1_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CROWD1_WAV "vo\\generic\\mp\\Crowd1.wav{handle}" 

#define COLISEUM_CROWD2_TYPE AudioRenderer::MechanicalType
#define COLISEUM_CROWD2_WAV "vo\\generic\\mp\\Crowd2.wav{handle}" 

#define COLISEUM_ENERGYZAP_TYPE AudioRenderer::MechanicalType
#define COLISEUM_ENERGYZAP_WAV "vo\\generic\\mp\\EnergyZap.wav{handle}" 

#define COLISEUM_HORN_TYPE AudioRenderer::MechanicalType
#define COLISEUM_HORN_WAV "vo\\generic\\mp\\horn.wav{handle}" 

#define COLISEUM_JEERS_TYPE AudioRenderer::MechanicalType
#define COLISEUM_JEERS_WAV "vo\\generic\\mp\\jeers.wav{handle}" 

#define COLISEUM_ROAR_TYPE AudioRenderer::MechanicalType
#define COLISEUM_ROAR_WAV "vo\\generic\\mp\\Roar.wav{handle}" 

#define COLISEUM_STADAMB_TYPE AudioRenderer::MechanicalType
#define COLISEUM_STADAMB_WAV "vo\\generic\\mp\\StadAmb.wav{handle}" 

#define COLISEUM_FACTORYHORN_TYPE AudioRenderer::MechanicalType
#define COLISEUM_FACTORYHORN_WAV "vo\\generic\\mp\\FactoryHorn.wav{handle}" 

#define COLISEUM_FACTORYBANG_TYPE AudioRenderer::MechanicalType
#define COLISEUM_FACTORYBANG_WAV "vo\\generic\\mp\\Factory_bang.wav{handle}"

#define COLISEUM_FACTORYBUZZ_TYPE AudioRenderer::MechanicalType
#define COLISEUM_FACTORYBUZZ_WAV "vo\\generic\\mp\\Factory_buzz.wav{handle}"

#define COLISEUM_FACTORYCLANG_TYPE AudioRenderer::MechanicalType
#define COLISEUM_FACTORYCLANG_WAV "vo\\generic\\mp\\Factory_clang.wav{handle}"

#define COLISEUM_FACTORYDRILL_TYPE AudioRenderer::MechanicalType
#define COLISEUM_FACTORYDRILL_WAV "vo\\generic\\mp\\Factory_Drill.wav{handle}"

#define COLISEUM_FACTORYSTEAM_TYPE AudioRenderer::MechanicalType
#define COLISEUM_FACTORYSTEAM_WAV "vo\\generic\\mp\\Factory_Steam.wav{handle}"

#define COLISEUMAMB_WAV			"music\\ColiseumAmb_music.wav{handle}" 
#define COLISEUMAMB_OLD_TIMEOUT	0.1f
#define COLISEUMAMB_NEW_TIMEIN	0.1f
#define COLISEUMAMB_NEW_VOLUME	(40.0f / 100.0f)
// --- end coliseum crowd sounds

#define COLISEUM_JUNGLEBIRD1_TYPE AudioRenderer::MechanicalType
#define COLISEUM_JUNGLEBIRD1_WAV "vo\\generic\\mp\\Jungle_bird1.wav{handle}"

#define COLISEUM_JUNGLEBIRD2_TYPE AudioRenderer::MechanicalType
#define COLISEUM_JUNGLEBIRD2_WAV "vo\\generic\\mp\\Jungle_bird2.wav{handle}"

#define COLISEUM_JUNGLEBIRD3_TYPE AudioRenderer::MechanicalType
#define COLISEUM_JUNGLEBIRD3_WAV "vo\\generic\\mp\\Jungle_bird3.wav{handle}"

#define COLISEUM_JUNGLEBIRD4_TYPE AudioRenderer::MechanicalType
#define COLISEUM_JUNGLEBIRD4_WAV "vo\\generic\\mp\\Jungle_bird4.wav{handle}"

#define COLISEUM_JUNGLEMONKEY1_TYPE AudioRenderer::MechanicalType
#define COLISEUM_JUNGLEMONKEY1_WAV "vo\\generic\\mp\\Jungle_monkey1.wav{handle}"

#define COLISEUM_JUNGLEMONKEY2_TYPE AudioRenderer::MechanicalType
#define COLISEUM_JUNGLEMONKEY2_WAV "vo\\generic\\mp\\Jungle_monkey2.wav{handle}"

#define TARGETATTACKED_TYPE AudioRenderer::BettyType
#define TARGETATTACKED_WAV "vo\\generic\\MissionTargetAtt_Bet.wav{handle}"

#define TARGETDESTROYED_TYPE AudioRenderer::BettyType
#define TARGETDESTROYED_WAV "vo\\generic\\MissionTargetDes_Bet.wav{handle}"

#define ALARM1_TYPE AudioRenderer::MechanicalType
#define ALARM1_WAV "vo\\generic\\Alarm1_Bet.wav{handle}"

#define ALARM2_TYPE AudioRenderer::MechanicalType
#define ALARM2_WAV "vo\\generic\\Alarm1_Bet.wav{handle}"

#define ProcessKeyUp(message, commandCount) \
{ \
	if (message->dataContents <=0) \
	{	commandCount--; } \
	Min_Clamp(commandCount, 0); \
}

HGOSAUDIO g_hCoinSound = NULL;

extern void _stdcall PlayCoinSound(int nSound)
{
	static int s_n = 1;

	if (s_n) {
		if (g_hCoinSound) {
			gosAudio_DestroyResource(&g_hCoinSound);
			g_hCoinSound = NULL;
		}
		const char* pcszSound;
		switch(nSound) {
		default: // case 0:
			pcszSound = "audio\\sfx_signal_objectivechange.wav";
			break;
		case 1:
			pcszSound = "audio\\sfx_narc_idle.wav";
			break;
		}
		gosAudio_CreateResource(&g_hCoinSound, gosAudio_CachedFile, pcszSound, 0,0,0, true);
		gosAudio_AssignResourceToChannel(1, g_hCoinSound);
		gosAudio_SetChannelPlayMode(1, gosAudio_PlayOnce);
	} else {
		PLAY_SOUND(COINDROP);
	}
}

const char* ViewName(int curView)
{
    switch(curView)
    {
    case VehicleInterface::STATE_FRONT_SHOT:
        return "Front Shot";
	case VehicleInterface::STATE_OVERSHOULDER_SHOT:
        return "Over Shoulder";
	case VehicleInterface::STATE_FIXED_TRACKING_SHOT:
        return "Fixed Tracking";
	case VehicleInterface::STATE_SIDE_SHOT:
        return "Side Shot";
    case VehicleInterface::STATE_DEATH_SEQUENCE_START:
        return "Watching Death";
    case VehicleInterface::STATE_DEATH_SEQUENCE_TRANS:
        return "Death Transition";
    default: // case VehicleInterface::STATE_STD_OBSERVERMODE
        return "Standard";
    }
}

const char* RangeName(int curRange)
{
    switch(curRange)
    {
    default: // case VehicleInterface::NO_RANGE:
        return "";
    case VehicleInterface::CLOSESHOT:
        return "(Close)";
    case VehicleInterface::MEDIUMSHOT:
        return "(Medium)";
    case VehicleInterface::LONGSHOT:
        return "(Long)";
    }
}

Mech* FindNextMechToFollowByScore(Mech* pCur)
{
#define MAX_MECHS_TOSELECT 128
    if (pCur && g_bLockCurrentHero)
        return pCur;
	MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());

	MWGUIManager *gui_manager = MWGUIManager::GetInstance ();
    Mech* entity;

    bool bScoreArray = false;
    int i;
    int nMechCount = 0;
	Mech* aEntities[MAX_MECHS_TOSELECT];

	if (gui_manager && gui_manager->Component(MWGUIManager::HUD_SCORE))
	{
        HUDScore *hud = Cast_Object (HUDScore *, gui_manager->Component(MWGUIManager::HUD_SCORE));
        if (hud) {
            CHudScoreInfo aScores[MAX_MECHS_TOSELECT];
            const ReplicatorID& id = pCur ? pCur->GetReplicatorID(): *(const ReplicatorID*)NULL;
            int nCount = hud->GetScoreArray(aScores, *(const ReplicatorID*)NULL/*id*/);
            for(i = 0; i < nCount; i++) {
                Replicator* pREP = aScores[i].m_pREP;
                if (pREP && pREP->IsDerivedFrom(Mech::DefaultData)) {
                    aEntities[nMechCount++] = Cast_Pointer(Mech*, pREP);
                    if (MAX_MECHS_TOSELECT <= nMechCount) // for Map Editor...
                        break;
                }
            }
            if (nMechCount > 0)
                bScoreArray = true;
        }
    }

	Stuff::SortedChainIteratorOf<Mech*, Adept::ReplicatorID> iterator(&manager->servedMechs);
    if (!bScoreArray) {
        while((entity = iterator.ReadAndNext()) != NULL) {
            aEntities[nMechCount++] = entity;
            if (MAX_MECHS_TOSELECT <= nMechCount) // for Map Editor...
                break;
        }
    }
    if (nMechCount <= 0)
        return NULL;

    int nSelectable = 0;
    Mech* aSelectable[MAX_MECHS_TOSELECT];

    int nActives = 0;
    int nHumanMechs = 0, nActiveHumanMechs = 0;

    for(i = 0; i < nMechCount; i++) {
        entity = aEntities[i];
        if (entity->isPlayerVehicle) {
            nHumanMechs++;
        }
        if (!entity->IsDestroyed() && (entity->executionState->GetState() != Entity::ExecutionStateEngine::NeverExecuteState)) {
            nActives++;
            if (entity->isPlayerVehicle) {
                nActiveHumanMechs++;
            }
        }
    }
    if (!g_CamerashipParams.m_bAllowBOTs) {
        if (nHumanMechs > 0) {
            bool bCurExist = false;
            for(i = 0; i < nMechCount; i++) {
                entity = aEntities[i];
                if (entity->isPlayerVehicle) {
                    if ((nActiveHumanMechs <= 0) || (!entity->IsDestroyed() && (entity->executionState->GetState() != Entity::ExecutionStateEngine::NeverExecuteState))) {
                        aSelectable[nSelectable++] = entity;
                        if (pCur && (pCur == entity))
                            bCurExist = true;
                    }
                }
            }
            int nRandCount = nSelectable;
            if (bCurExist) {
                if (nSelectable == 1) {
                    return aSelectable[0];
                }
                nRandCount--;
            }
            if (nRandCount > 3) {
                nRandCount = 3;
            }
            nRandCount = Random::GetInt() % nRandCount; // rand() % nRandCount;
            for(i = 0; i < nSelectable; i++) {
                entity = aSelectable[i];
                if (entity != pCur) {
                    if (nRandCount == 0)
                        return entity;
                    nRandCount--;
                }
            }
            if (aSelectable[0])
                return aSelectable[0];
            return aEntities[0];
        }
    }
    Mech* p1st = NULL;
    bool bCurNextFound = false;

    for(i = 0; i < nMechCount; i++) {
        entity = aEntities[i];
        if ((nActives <= 0) || (!entity->IsDestroyed() && entity->executionState->GetState() != Entity::ExecutionStateEngine::NeverExecuteState)) {
            if (!p1st) {
                p1st = entity;
            }
            if (bCurNextFound) {
                return entity;
            }
        }
        if (pCur && (pCur == entity))
            bCurNextFound = true;
    }
    if (p1st)
        return p1st;
    return aEntities[0];
#undef MAX_MECHS_TOSELECT
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
static bool
	Ray_Caster(Stuff::Line3D *line)
{
	Check_Object(line);
	Check_Object(CollisionGrid::Instance);

	Stuff::Normal3D normal;
	Check_Object(Player::GetInstance());
	VehicleInterface *intface =
		Cast_Object(VehicleInterface*, Player::GetInstance()->playerInterface);
	Entity::CollisionQuery query(
		line,
		&normal,
		Entity::CanBeShotFlag,
		(intface->cameraView == VehicleInterface::InMechCameraView) ? Player::GetInstance()->vehicle : NULL
	);
	bool occluded = CollisionGrid::Instance->ProjectLine(&query) != NULL;
	return occluded;
}

//#############################################################################
//##########################    ExecutionStateEngine    #######################
//#############################################################################

VehicleInterface::ExecutionStateEngine::ClassData*
	VehicleInterface::ExecutionStateEngine::DefaultData = NULL;

const StateEngine::StateEntry
	VehicleInterface::ExecutionStateEngine::StateEntries[]=
{
	STATE_ENTRY(VehicleInterface__ExecutionStateEngine, Following),
	STATE_ENTRY(VehicleInterface__ExecutionStateEngine, WatchingDeath),
	STATE_ENTRY(VehicleInterface__ExecutionStateEngine, AIRunning),
	STATE_ENTRY(VehicleInterface__ExecutionStateEngine, FieldBase),
	STATE_ENTRY(VehicleInterface__ExecutionStateEngine, Observation)
//	STATE_ENTRY(VehicleInterface__ExecutionStateEngine, AutoPilot)
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ExecutionStateEngine::InitializeClass()
{
	g_pRIOMain = new CRIOMAIN (hWindow);
	Check_Object(StateEngine::DefaultData);
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			VehicleInterface__ExecutionStateEngineClassID,
			"VehicleInterface::ExecutionStateEngine",
			BaseClass::DefaultData,
			ELEMENTS(StateEntries), StateEntries,
			(Entity::ExecutionStateEngine::Factory)Make,
			(Entity::ExecutionStateEngine::FactoryRequest::Factory)
				&FactoryRequest::ConstructFactoryRequest
		);
	Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ExecutionStateEngine::TerminateClass()
{
	if (g_pRIOMain) {
		delete g_pRIOMain;
		g_pRIOMain = NULL;
	}

	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
VehicleInterface::ExecutionStateEngine*
	VehicleInterface::ExecutionStateEngine::Make(
		VehicleInterface *vehicle_interface,
		FactoryRequest *request
	)
{
	Check_Object(vehicle_interface);
	Check_Object(request);
	gos_PushCurrentHeap(Heap);
	VehicleInterface::ExecutionStateEngine *engine =
		new VehicleInterface::ExecutionStateEngine(DefaultData, vehicle_interface, request);
	gos_PopCurrentHeap();
	return engine;
		
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int VehicleInterface::ExecutionStateEngine::RequestState(int new_state,void* data)
{
	Check_Object(this);
	Check_Object(owningEntity);

	//
	//----------------------------------------------
	// Now, switch the state and tickle the watchers
	//----------------------------------------------
	//

	VehicleInterface *vehicle;
	vehicle = Cast_Object(VehicleInterface *, owningEntity);

	int oldState = currentState;
#if 0
	switch (currentState)
	{
		case AutoPilotState:
			if (new_state != currentState)
			{
				vehicle->getPlayerAI()->AutoPilot (false);
			}
		break;
	}
#endif

	extern bool sh_isdeathmode;

    int n_NS = BaseClass::RequestState(new_state, data);
    if (n_NS != WatchingDeathState) {
	    sh_isdeathmode = false;
    }
	switch (n_NS)
	{
		case AIRunningState:
				if (oldState != AIRunningState)
				{
					Verify (vehicle->getPlayerAI ());
					vehicle->getPlayerAI ()->StartCinema ();
				}
			break;
		case FieldBaseState:
			if (oldState != FieldBaseState)
			{
				Verify (vehicle->getPlayerAI ());
				vehicle->getPlayerAI ()->StartFieldBase ();
			}
			break;
#if 0
		case AutoPilotState:
				if (oldState != AutoPilotState)
				{
					vehicle->getPlayerAI ()->NavPoint (vehicle->m_selectedNavPoint.GetCurrent());
					vehicle->getPlayerAI ()->AutoPilot (true);
				}
			break;
#endif
		case WatchingDeathState:
			{
				// Death
                if (g_nMR != 2)
				sh_isdeathmode = true;
				g_pRIOMain->SetTable (FALSE);

				if(MWApplication::GetInstance()->networkingFlag)
				{
					if(MWGUIManager::GetInstance())
					{
//						MWGUIManager::GetInstance()->ShowScoring();
					}
				}
			}
		default:
				if ((oldState == AIRunningState) || (oldState == FieldBaseState))
				{
					Verify (vehicle->getPlayerAI ());
					vehicle->getPlayerAI ()->StopExecuting ();
				}
			break;
	}

	return currentState;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ExecutionStateEngine::TestInstance() const
{
	Verify(IsDerivedFrom(DefaultData));
}

//#############################################################################
//########################     VehicleInterface    ############################
//#############################################################################

VehicleInterface::ClassData*
	VehicleInterface::DefaultData = NULL;

int VehicleInterface::perminateTorsoMode = VehicleInterface::CenterLegsToTorso;
bool VehicleInterface::hudDamageMode = 0;
bool VehicleInterface::hudTargetDamageMode = 0;

const Receiver::MessageEntry
	VehicleInterface::MessageEntries[]=
{
	MESSAGE_ENTRY(VehicleInterface, ChangeView),
	MESSAGE_ENTRY(VehicleInterface, JoyStickButton1),
	MESSAGE_ENTRY(VehicleInterface, GetUpCommand),
	MESSAGE_ENTRY(VehicleInterface, ShutDownCommand),
	MESSAGE_ENTRY(VehicleInterface, ShutDownOnlyCommand),
	MESSAGE_ENTRY(VehicleInterface, StartUpOnlyCommand),
	MESSAGE_ENTRY(VehicleInterface, CrouchCommand),
	MESSAGE_ENTRY(VehicleInterface, JumpCommand),
	MESSAGE_ENTRY(VehicleInterface, AnimDiagTest1),
	MESSAGE_ENTRY(VehicleInterface, AnimDiagTest2),
	MESSAGE_ENTRY(VehicleInterface, AnimDiagTest3),
	MESSAGE_ENTRY(VehicleInterface, AnimDiagTest4),
	MESSAGE_ENTRY(VehicleInterface, AnimDiagTest5),
	MESSAGE_ENTRY(VehicleInterface, AnimDiagTest6),
	MESSAGE_ENTRY(VehicleInterface, AnimDiagTest7),
	MESSAGE_ENTRY(VehicleInterface, AnimDiagTest8),
	MESSAGE_ENTRY(VehicleInterface, DebugText),
	MESSAGE_ENTRY(VehicleInterface, Lancemate1),
	MESSAGE_ENTRY(VehicleInterface, Lancemate2),
	MESSAGE_ENTRY(VehicleInterface, Lancemate3),
	MESSAGE_ENTRY(VehicleInterface, LancemateAll),
	MESSAGE_ENTRY(VehicleInterface, LancemateAttackMyTarget),
	MESSAGE_ENTRY(VehicleInterface, LancemateDefendMyTarget),
	MESSAGE_ENTRY(VehicleInterface, LancemateFormOnMe),
	MESSAGE_ENTRY(VehicleInterface, LancemateHoldFire),
	MESSAGE_ENTRY(VehicleInterface, LancemateGoToMyNavPoint),
	MESSAGE_ENTRY(VehicleInterface, LancemateStop),
	MESSAGE_ENTRY(VehicleInterface, LancemateShutdown),
	MESSAGE_ENTRY(VehicleInterface, LancemateAttackNearestThreat),
	MESSAGE_ENTRY(VehicleInterface, LancemateRepairAtNearestRepairBay),
	MESSAGE_ENTRY(VehicleInterface, LancemateCapturePlayersFlag),
	MESSAGE_ENTRY(VehicleInterface, ChangeWeaponMode),
	MESSAGE_ENTRY(VehicleInterface, WeaponGroup1),
	MESSAGE_ENTRY(VehicleInterface, WeaponGroup2),
	MESSAGE_ENTRY(VehicleInterface, WeaponGroup3),
	MESSAGE_ENTRY(VehicleInterface, WeaponGroup4),
	MESSAGE_ENTRY(VehicleInterface, WeaponGroup5),
	MESSAGE_ENTRY(VehicleInterface, WeaponGroup6),
	MESSAGE_ENTRY(VehicleInterface, NextWeaponGroup),
	MESSAGE_ENTRY(VehicleInterface, PreviousWeaponGroup),
	MESSAGE_ENTRY(VehicleInterface, NextWeapon),
	MESSAGE_ENTRY(VehicleInterface, TopDownView),
	MESSAGE_ENTRY(VehicleInterface, ToggleInvulnerable),
	MESSAGE_ENTRY(VehicleInterface, KillCurrentTarget),
	MESSAGE_ENTRY(VehicleInterface, NextVehicle),
	MESSAGE_ENTRY(VehicleInterface, ToggleSearchLight),
	MESSAGE_ENTRY(VehicleInterface, SelfDestruct),
	MESSAGE_ENTRY(VehicleInterface, Coolant),
	MESSAGE_ENTRY(VehicleInterface, SendChatMessage1),
	MESSAGE_ENTRY(VehicleInterface, SendChatMessage2),
	MESSAGE_ENTRY(VehicleInterface, SendChatMessage3),
	MESSAGE_ENTRY(VehicleInterface, SendChatMessage4),
	MESSAGE_ENTRY(VehicleInterface, ToggleLightAmp),
	MESSAGE_ENTRY(VehicleInterface, ToggleHUD),
	MESSAGE_ENTRY(VehicleInterface, ToggleMultiplayerScoring),
	MESSAGE_ENTRY(VehicleInterface, NextNavPoint),
	MESSAGE_ENTRY(VehicleInterface, PreviousNavPoint),
	MESSAGE_ENTRY(VehicleInterface, NextEnemy),
	MESSAGE_ENTRY(VehicleInterface, PreviousEnemy),
	MESSAGE_ENTRY(VehicleInterface, NearestEnemy),
	MESSAGE_ENTRY(VehicleInterface, TargetReticuleEnemy),
	MESSAGE_ENTRY(VehicleInterface, ToggleRadarRange),
	MESSAGE_ENTRY(VehicleInterface, Forward),
	MESSAGE_ENTRY(VehicleInterface, Backward),
	MESSAGE_ENTRY(VehicleInterface, RotateLeft),
	MESSAGE_ENTRY(VehicleInterface, RotateRight),
	MESSAGE_ENTRY(VehicleInterface, Origin),
	MESSAGE_ENTRY(VehicleInterface, TorsoTwistLeft),
	MESSAGE_ENTRY(VehicleInterface, TorsoTwistRight),
	MESSAGE_ENTRY(VehicleInterface, PitchUp),
	MESSAGE_ENTRY(VehicleInterface, PitchDown),
	MESSAGE_ENTRY(VehicleInterface, Reverse),
	MESSAGE_ENTRY(VehicleInterface, FireWeapon),
	MESSAGE_ENTRY(VehicleInterface, LookLeft),
	MESSAGE_ENTRY(VehicleInterface, LookRight),
	MESSAGE_ENTRY(VehicleInterface, LookBack),
	MESSAGE_ENTRY(VehicleInterface, LookDown),
	MESSAGE_ENTRY(VehicleInterface, CameraDetach),
	MESSAGE_ENTRY(VehicleInterface, CameraReset),
	MESSAGE_ENTRY(VehicleInterface, CameraTerrain),
	MESSAGE_ENTRY(VehicleInterface, CameraTargetReticule),
	MESSAGE_ENTRY(VehicleInterface, CameraPitchUp),
	MESSAGE_ENTRY(VehicleInterface, CameraPitchDown),
	MESSAGE_ENTRY(VehicleInterface, CameraRollRight),
	MESSAGE_ENTRY(VehicleInterface, CameraRollLeft),
	MESSAGE_ENTRY(VehicleInterface, CameraYawLeft),
	MESSAGE_ENTRY(VehicleInterface, CameraYawRight),
	MESSAGE_ENTRY(VehicleInterface, CameraPanUp),
	MESSAGE_ENTRY(VehicleInterface, CameraPanDown),
	MESSAGE_ENTRY(VehicleInterface, CameraPanLeft),
	MESSAGE_ENTRY(VehicleInterface, CameraPanRight),
	MESSAGE_ENTRY(VehicleInterface, CameraZoomIn),
	MESSAGE_ENTRY(VehicleInterface, CameraZoomOut),
	MESSAGE_ENTRY(VehicleInterface, MFDComm1),
	MESSAGE_ENTRY(VehicleInterface, MFDComm2),
	MESSAGE_ENTRY(VehicleInterface, MFDComm3),
	MESSAGE_ENTRY(VehicleInterface, MFDComm4),
	MESSAGE_ENTRY(VehicleInterface, MFDComm5),
	MESSAGE_ENTRY(VehicleInterface, MFDComm6),
	MESSAGE_ENTRY(VehicleInterface, MFDComm7),
	MESSAGE_ENTRY(VehicleInterface, MFDComm8),
	MESSAGE_ENTRY(VehicleInterface, Throttle0),
	MESSAGE_ENTRY(VehicleInterface, Throttle10),
	MESSAGE_ENTRY(VehicleInterface, Throttle20),
	MESSAGE_ENTRY(VehicleInterface, Throttle30),
	MESSAGE_ENTRY(VehicleInterface, Throttle40),
	MESSAGE_ENTRY(VehicleInterface, Throttle50),
	MESSAGE_ENTRY(VehicleInterface, Throttle60),
	MESSAGE_ENTRY(VehicleInterface, Throttle70),
	MESSAGE_ENTRY(VehicleInterface, Throttle80),
	MESSAGE_ENTRY(VehicleInterface, Throttle90),
	MESSAGE_ENTRY(VehicleInterface, Throttle100),
	MESSAGE_ENTRY(VehicleInterface, CenterTorsoToLegs),
	MESSAGE_ENTRY(VehicleInterface, CenterLegsToTorso),
	MESSAGE_ENTRY(VehicleInterface, NextFriendly),
	MESSAGE_ENTRY(VehicleInterface, PreviousFriendly),
	MESSAGE_ENTRY(VehicleInterface, NearestFriendly),
	MESSAGE_ENTRY(VehicleInterface, ToggleZoomReticule),
	MESSAGE_ENTRY(VehicleInterface, ShowObjectives),
// MSL 5.05 Objective Switch
	MESSAGE_ENTRY(VehicleInterface, Mute),
	MESSAGE_ENTRY(VehicleInterface, MouseTorsoToggle),
	MESSAGE_ENTRY(VehicleInterface, MouseDeltaToggle),
//	MESSAGE_ENTRY(VehicleInterface, AutoPilot),
	MESSAGE_ENTRY(VehicleInterface, Eject),
	MESSAGE_ENTRY(VehicleInterface, OverrideAutoCenterToTorso),
	MESSAGE_ENTRY(VehicleInterface, ToggleRadarPassive),
	MESSAGE_ENTRY(VehicleInterface, ShowMap),
	MESSAGE_ENTRY(VehicleInterface, StartChat),
	MESSAGE_ENTRY(VehicleInterface, StartTeamChat),
	MESSAGE_ENTRY(VehicleInterface, OverrideShutdown),
	MESSAGE_ENTRY(VehicleInterface, LeftMFD),
	MESSAGE_ENTRY(VehicleInterface, RightMFD),
	MESSAGE_ENTRY(VehicleInterface, ToggleMouseControl),
	MESSAGE_ENTRY(VehicleInterface, ToggleLargeChat),
	MESSAGE_ENTRY(VehicleInterface, TakeSnapShot),
	MESSAGE_ENTRY(VehicleInterface, ToggleGroup1),
	MESSAGE_ENTRY(VehicleInterface, ToggleGroup2),
	MESSAGE_ENTRY(VehicleInterface, ToggleGroup3),
	MESSAGE_ENTRY(VehicleInterface, ToggleGroup4),
	MESSAGE_ENTRY(VehicleInterface, ToggleGroup5),
	MESSAGE_ENTRY(VehicleInterface, ToggleGroup6),
	MESSAGE_ENTRY(VehicleInterface, ToggleGroupWeaponMode)

//
// Section for keys we don't want in the release build
//
	,
	MESSAGE_ENTRY(VehicleInterface, DebugFast),
	MESSAGE_ENTRY(VehicleInterface, FreezeGameLogic),
	MESSAGE_ENTRY(VehicleInterface, ImmediateWeaponLockMode),
	MESSAGE_ENTRY(VehicleInterface, SucceedMission),
	MESSAGE_ENTRY(VehicleInterface, FailMission),
	MESSAGE_ENTRY(VehicleInterface, ToggleDebugHud)
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::InitializeClass()
{
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			VehicleInterfaceClassID,
			"MechWarrior4::VehicleInterface",
			BaseClass::DefaultData,
			ELEMENTS(MessageEntries), MessageEntries,
			(Entity::Factory)Make,
			(Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage,
			ExecutionStateEngine::DefaultData,
			(Entity::GameModel::Factory)GameModel::ConstructGameModel,
			NULL,
			(Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify,
			(Entity::GameModel::ModelWrite)GameModel::WriteToText,
			(Entity::GameModel::ModelSave)GameModel::SaveGameModel
		);
	Register_Object(DefaultData);

	//JoyStick Attributes
	CUSTOM_DIRECT_ATTRIBUTE(VehicleInterface,
		JoyStickXAxis,joystickXAxis,Scalar,ScalarClassID);
	CUSTOM_DIRECT_ATTRIBUTE(VehicleInterface,
		JoyStickYAxis,joystickYAxis,Scalar,ScalarClassID);
	CUSTOM_DIRECT_ATTRIBUTE(VehicleInterface,
		JoyStickRudder,joystickRudder,Scalar,ScalarClassID);
	CUSTOM_DIRECT_ATTRIBUTE(VehicleInterface,
		JoyStickThrottle,joystickThrottle,Scalar,ScalarClassID);

	CUSTOM_DIRECT_ATTRIBUTE(VehicleInterface,JoyStickHat,joystickHat,Scalar,ScalarClassID);

	CUSTOM_DIRECT_ATTRIBUTE(VehicleInterface,MouseWheel,mouseWheel,int,IntClassID);
	CUSTOM_DIRECT_ATTRIBUTE(VehicleInterface,MousePosX,mousePosX,Scalar,ScalarClassID);
	CUSTOM_DIRECT_ATTRIBUTE(VehicleInterface,MousePosY,mousePosY,Scalar,ScalarClassID);
	CUSTOM_DIRECT_ATTRIBUTE(VehicleInterface,MouseDeltaX,mouseDeltaX,Scalar,ScalarClassID);
	CUSTOM_DIRECT_ATTRIBUTE(VehicleInterface,MouseDeltaY,mouseDeltaY,Scalar,ScalarClassID);


	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		CameraStartOffset,
		cameraStartOffset,
		Point3D
	);
	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		CameraStartAngle,
		cameraStartAngle,
		UnitQuaternion
	);
	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		CameraExternalTargetStartOffset1,
		cameraExternalTargetStartOffset1,
		Point3D
	);
	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		CameraExternalTargetStartOffset2,
		cameraExternalTargetStartOffset2,
		Point3D
	);
	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		CameraExternalTargetStartOffset3,
		cameraExternalTargetStartOffset3,
		Point3D
	);
  DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		MaxTargetDistance,
		maxTargetDistance,
		Scalar
	);
  DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		TurnSpeedZoomModifierTorso,
		turnSpeedZoomModifierTorso,
		Scalar
	);
  DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		TurnSpeedZoomModifierYaw,
		turnSpeedZoomModifierYaw,
		Scalar
	);
  DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		TurnSpeedZoomModifierPitch,
		turnSpeedZoomModifierPitch,
		Scalar
	);
	CUSTOM_DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		BRBMode,
		brbMode,
		int,
		IntClassID
	);

	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		RotationPerSecond,
		rotationPerSecond,
		Radian
	);

	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		TranslationPerSecond,
		translationPerSecond,
		Point3D
	);

	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		DeathTimer,
		deathTimer,
		Scalar
	);
	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		PlayerAIResource,
		playerAIResource,
		ResourceID
	);

	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		DelayTorsoCenter,
		delayTorsoCenter,
		Scalar
	);

	DIRECT_GAME_MODEL_ATTRIBUTE(
		VehicleInterface__GameModel,
		MaxSpeedAboveMinTransToTorsoCenterKPH,
		maxSpeedAboveMinTransToTorsoCenterKPH,
		Scalar
	);

	gosFX::Flare::RayCaster = Ray_Caster;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
VehicleInterface*
	VehicleInterface::Make(
		CreateMessage *message,
		ReplicatorID *base_id
	)
{
	Check_Object(message);
	gos_PushCurrentHeap(Heap);
	VehicleInterface *new_entity =
		new VehicleInterface(DefaultData, message, base_id, NULL);
	gos_PopCurrentHeap();
	Check_Object(new_entity);
	return new_entity;
}

void VehicleInterface::SetLightAmpFlareOut(Stuff::Scalar modifier)
{
	if (m_CurrentLightAmpMod > modifier)
		return;
	if (MWGUIManager::GetInstance())
	{
		m_CurrentLightAmpMod = modifier;
		if (MWGUIManager::GetInstance()->lightAmp)
			MWGUIManager::GetInstance()->lightAmp->SetModifier (m_CurrentLightAmpMod);
//		if (MWGUIManager::GetInstance()->zoomLightAmp)
//			MWGUIManager::GetInstance()->zoomLightAmp->SetModifier (m_CurrentLightAmpMod);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Replicator::CreateMessage*
	VehicleInterface::SaveMakeMessage(MemoryStream *stream, ResourceFile *res_file)
{
	Check_Object(this);
	Check_Object(stream);

	stream->AllocateBytes(sizeof(CreateMessage));
	BaseClass::SaveMakeMessage(stream, res_file);
	CreateMessage *message =
		Cast_Pointer(CreateMessage*, stream->GetPointer());
	message->messageLength = sizeof(*message);

	Resource gui_resource(NULL);
	DynamicMemoryStream gui_stream;
	Check_Object(MWGUIManager::GetInstance());
	MWGUIManager::GetInstance()->SaveObjectsToStream(&gui_stream);
	gui_resource.Save(&gui_stream, NULL);
	STOP(("Not updated"));
	Check_Object(&gui_resource);
	message->guiStreamResourceID = gui_resource.GetResourceID();

	return message;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
VehicleInterface::VehicleInterface(
	ClassData *class_data,
	CreateMessage *message,
	ReplicatorID *base_id,
	ElementRenderer::Element *element
):
	Interface(class_data, message, base_id, element),
	//weaponGroup[0](NULL),
	//weaponGroup[1](NULL),
	//weaponGroup[2](NULL),
	//weaponGroup[3](NULL),
	//weaponGroup[4](NULL),
	//weaponGroup[5](NULL),
	quedCommands(NULL),
	weatherEffect(NULL),
	targetQueryEntity(NULL),
	lockedTargetEntity(NULL),
	lockedTargetEntityPart(NULL),
	targetEntity(NULL),
	targetLastVehicleEntity(NULL),
	targetEntityPart(NULL),
	m_interfaceTarget(NULL),
	m_selectedNavPoint(NULL),
	observingEntity(NULL),
	//REMOVE
//	m_LockTimeObject(0),
	m_Temporary_AddedLancemate(false),
	m_narcSound(NULL),
	m_missileLockSound(NULL),
	m_coolantSound(NULL),
	m_damageCriticalSound(NULL),
// MSL 5.02 headshot
	hudZoomDestroyed(false),
	m_torsoSound(NULL)
	
	// [MSR SPECTATOR STUFF] =============================================
	,
    m_curView(STATE_STD_OBSERVERMODE),
    m_curRange(NO_RANGE),
    m_pEnemy(NULL),
    m_pMechDying(NULL),
    m_fTimeStateEnd(0.0f),
	m_fixedPoint(Stuff::Point3D::Identity),
	m_dyingHeroPoint(Stuff::Point3D::Identity),
	m_tempEnemyPos(Stuff::Point3D::Identity),
	m_fDyingSequenceInited(false),
	m_fDeathTransDone(false),
	m_fDeathTransInited(false),
	m_fDampingInited(false),
	m_fDampTransDone(true),
    m_pLastParent(NULL),
    m_fLastTorsoYAW(0.0f),
    m_fLastTorsoTime(0.0f)
	// END [MSR SPECTATOR STUFF] =========================================
{
	Check_Pointer(this);
	Check_Object(message);

	isAttachedVehicleAMech = false;
	cameraView = InMechCameraView;
	rememberCameraView = InMechCameraView;
	
	m_CurrentLightAmpMod = 0;
	m_LastTorsoTwistSoundTime = 0;
	m_LastStepWaterSoundTime = 0;
	m_LastHeatSoundTime = 0;
	m_NewRadarSoundTime = 0;
	m_LastEngineSoundTime = 0;
	m_LastAmmoDepletedSoundTime = 0;
	minForwardKPH = 0;
	minReverseKPH = 0;
	maxForwardKPH = 1.0f;
	maxReverseKPH = 1.0f;


	m_BoundsWarningsEnabled = true;

	{for (int i = 0;
		  i < 6;
		  ++i)
	{
		m_LastTimeFiredWeaponGroup[i] = 0;
	}}

	//Respawn the Nav Points
	NavPoint::s_RevealedNavPointsIterator->First();
	NavPoint::s_CurrentNavPoint = NULL;

	CommonCreation(message);

	rememberCameraOffset = cameraOffset;
	rememberCameraRotation = cameraRotation;

	m_PlayerAI = NULL;

	perminateTorsoMode = CenterLegsToTorso;

	longTomDistance = 0.0f;
	longTomAngle = 0.0f;
	longTom = NULL;
	gosASSERT(g_ControlList);
	m_MouseEnable = g_ControlList->IsMouseAllowed();

	MW4AI::UserConstants::IncrementRefCount();
	
	//joystick_throttle_center = MW4AI::UserConstants::Instance ()->Get(MW4AI::UserConstants::throttle_center);
	//joystick_throttle_dead_low = MW4AI::UserConstants::Instance ()->Get(MW4AI::UserConstants::throttle_dead_low);
	//joystick_throttle_dead_high = MW4AI::UserConstants::Instance ()->Get(MW4AI::UserConstants::throttle_dead_high);

#if defined(_ARMOR)
	Debug_Frame_Rate_Counter = 0;
#endif


	//
	//---------------------------
	//Camera needs to have a post
	//---------------------------
	//
	// but the post needs to be guarenteed
	// last, so the player manually puts it on
	// the stack last.  This way entity::precollision
	// won't put it on before the mech.
	
	// You see, the controls need to be read BEFORE the mech.
	// the camera needs to be run AFTER the mech and map.

	eyeSitePointer = NULL;
	vehicle = NULL;
  vehiclerootJointIndex = -1; // need this to compensate for jump in target reticule external mode

	netBandwidth = -1;

	// Sound tests

	observerMode = false;

	if ((MWGUIManager::GetInstance()) && (!brbMode))
	{
		Check_Object(MWGUIManager::GetInstance());
		
		MWGUIManager::GetInstance()->vehicleInterface = this;

		if(message->guiStreamResourceID != ResourceID::Null)
		{
			Resource gui_resource(message->guiStreamResourceID);
			Verify(gui_resource.DoesResourceExist());
	//		MWGUIManager::GetInstance()->ReadObjectsFromStream(&gui_resource);
		}

	//	MWGUIManager::GetInstance()->InitializeTargetSystem();
//		MWGUIManager::GetInstance()->InitializeGOSHUD();

		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"LongTomAngle: ",
			&longTomAngle,
			GUIDebugText::ScalarType
		);

		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"LongTomDistance: ",
			&longTomDistance,
			GUIDebugText::ScalarType
		);

		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"Camera Offset",
			&cameraOffset,
			GUIDebugText::Vector3DType
		);

		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"Camera Rotation",
			&cameraRotation,
			GUIDebugText::YawPitchRollType
		);

		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"SpeedCurrent-MPS: ",
			&currentSpeedMPS,
			GUIDebugText::ScalarType
		);

		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"SpeedCurrent-KPH: ",
			&currentSpeedKPH,
			GUIDebugText::ScalarType
		);

		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"SpeedDemand-MPS: ",
			&currentSpeedMPS,
			GUIDebugText::ScalarType
		);

		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"SpeedDemand-KPH: ",
			&currentSpeedKPH,
			GUIDebugText::ScalarType
		);

		
		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"Vehicle Position",
			&vehiclePosition,
			GUIDebugText::Vector3DType
		);

		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"Foot : Left : ",
			&leftFootFlag,
			GUIDebugText::IntType
		);
		
			GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"Foot : Right : ",
			&rightFootFlag,
			GUIDebugText::IntType
		);


		GUITextManager::GetInstance()->MakeNewDebugTextObject(
			"Net Bandwidth Level : ",
			&netBandwidth,
			GUIDebugText::IntType
		);

	}

	weaponIterator = NULL;
	for (int i=0; i<6; i++) {
		//weaponGroup[i] = NULL;
		groupWeaponIterator[i] = NULL;
	}

	m_targetCamera = NULL;
	m_reticuleCamera = NULL;
#ifdef LAB_ONLY
	m_fImmediateWeaponLockMode = false;	
#endif
	requestedZoomChange = false;
	reticuleZoomShowing = false;
	cinemaPlaying = false;




	externalCameraOffsetStartMinZ = -2.0f;
	CreateWeatherEffect();

	
	GlobalPointers::AddGlobalPointer(this, VehicleInterfaceGlobalPointerIndex);



	m_Forces[LeftFootForce] = NULL;
	m_Forces[RightFootForce] = NULL;
	m_Forces[FireMissleForce] = NULL;
	m_Forces[FireProjectileForce] = NULL;
	m_Forces[HitBackForce] = NULL;
	m_Forces[HitFrontForce] = NULL;
	m_Forces[HitLeftForce] = NULL;
	m_Forces[HitRightForce] = NULL;
	m_Forces[WaterMoveForce] = NULL;
	m_Forces[FallDownForce] = NULL;
	m_HitForce = NULL;

	const GameModel *model = GetGameModel();
	Check_Object(model);
	LoadControlStream (model->mappingStreamResourceID);
	m_currentTargetReticuleCameraPosition = 3;// has to start at an valid number 0 - 2 or 3 for internal

	m_eFogType = NormalFogType; // for setting below water fog
	m_fltFogTransitionEndTime = 0.0f;
	pointLockedEntityPartOffset = Stuff::Point3D::Identity;
	m_maxSpeedTorsoCenterKPH = 0.0f;
	m_fHudCurrentlyShowing = false; // used to allow us to continually and cheaply call hide for all views
	m_fZoomCurrentlyShowing = false; // used to allow us to continually and cheaply call hide for all views
	m_fHudShouldShow = true; // current state of the hud
	m_fStaticView = false;
	targetStartTime = 0.0f;
	targetLossTime = 0.0f;

	//
	// If there is a frame for some reason that shouldn't fire then we have a flag to set for that.
	// There was a bug allowing firing backwards and to the side due to the out of synch between the UI
	// and the current frame. (User is acting one frame backwards.)
	//
	preventFireThisFrame = false;
}

void VehicleInterface::LoadControlStream (const ResourceID& control_stream)
{
	if (brbMode)
	{
		Resource res ("Content\\Games\\BRB\\BRBInterface.control");
		res.LoadData ();
		Verify (res.DoesResourceExist ());
		g_ControlList->LoadList (res);
	}
	Interface::LoadControlStream (control_stream);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::EnterChatMode (bool team)
{
	if(!MWApplication::GetInstance()->networkingFlag)
		return;
	BaseClass::EnterChatMode (team);
	if (MWGUIManager::GetInstance ())
	{
		HUDComm *comm;
		comm = Cast_Object (HUDComm*,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_COMM));
		Verify (comm);
		comm->DeselectLancemate ();
		HUDChat *chat;
		chat = Cast_Object (HUDChat*,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT));
		Verify (chat);
		chat->SetCurrentChat (m_CurrentChatMessage);
		chat->SetCursorPos (&m_InChatMessage);
		chat->TeamChat (team);
		chat->SetTextLength(&m_ChatLen);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::LeaveChatMode (void)
{
	if(!MWApplication::GetInstance()->networkingFlag)
		return;

	HUDChat *chat;
	chat = Cast_Object (HUDChat*,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT));
	Verify (chat);
	chat->SetCurrentChat (NULL);
	chat->SetCursorPos (NULL);
	chat->SetTextLength (NULL);

	if (m_CurrentChatMessage[0] != 0)
	{
		Check_Object(Application::GetInstance());

		MWApplication::GetInstance()->HandleHUDInput(m_TeamChat, vehicle->IsDestroyed(), observerMode, Connection::Local->GetID(), m_CurrentChatMessage);
	}
	
	BaseClass::LeaveChatMode ();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ForceFeedBack (bool value)
{
	int i;
	for (i = 0;i<maxForces;i++)
		StopForce (i);

	int id;
	Check_Object (ControlsManager::Instance);
	if (m_Forces[LeftFootForce])
		gosJoystick_DestroyEffect (&m_Forces[LeftFootForce]);
	if (m_Forces[RightFootForce])
		gosJoystick_DestroyEffect (&m_Forces[RightFootForce]);
	if (m_Forces[FireMissleForce])
		gosJoystick_DestroyEffect (&m_Forces[FireMissleForce]);
	if (m_Forces[FireProjectileForce])
		gosJoystick_DestroyEffect (&m_Forces[FireProjectileForce]);
	if (m_Forces[HitBackForce])
		gosJoystick_DestroyEffect (&m_Forces[HitBackForce]);
	if (m_Forces[HitFrontForce])
		gosJoystick_DestroyEffect (&m_Forces[HitFrontForce]);
	if (m_Forces[HitLeftForce])
		gosJoystick_DestroyEffect (&m_Forces[HitLeftForce]);
	if (m_Forces[HitRightForce])
		gosJoystick_DestroyEffect (&m_Forces[HitRightForce]);
	if (m_Forces[WaterMoveForce])
		gosJoystick_DestroyEffect (&m_Forces[WaterMoveForce]);
	if (m_Forces[FallDownForce])
		gosJoystick_DestroyEffect (&m_Forces[FallDownForce]);
	if (m_HitForce)
		gosJoystick_DestroyEffect (&m_HitForce);
	
	m_Forces[LeftFootForce] = NULL;
	m_Forces[RightFootForce] = NULL;
	m_Forces[FireMissleForce] = NULL;
	m_Forces[FireProjectileForce] = NULL;
	m_Forces[HitBackForce] = NULL;
	m_Forces[HitFrontForce] = NULL;
	m_Forces[HitLeftForce] = NULL;
	m_Forces[HitRightForce] = NULL;
	m_Forces[WaterMoveForce] = NULL;
	m_Forces[FallDownForce] = NULL;
	m_HitForce = NULL;

	Check_Object (ControlsManager::Instance);
	if (ControlsManager::Instance->systemJoystick)
	{
		id = ControlsManager::Instance->systemJoystick->StickID ();
		if (ControlsManager::Instance->systemJoystick->IsForceFeedback ())
		{
			gosJoystick_LoadEffect (&m_Forces[LeftFootForce],id,"content\\force\\leftfoot.ffe");
			gosJoystick_LoadEffect (&m_Forces[RightFootForce],id,"content\\force\\rightfoot.ffe");
			gosJoystick_LoadEffect (&m_Forces[FireMissleForce],id,"content\\force\\firemissle.ffe");
			gosJoystick_LoadEffect (&m_Forces[FireProjectileForce],id,"content\\force\\fireprojectile.ffe");
			gosJoystick_LoadEffect (&m_Forces[HitBackForce],id,"content\\force\\hitback.ffe");
			gosJoystick_LoadEffect (&m_Forces[HitFrontForce],id,"content\\force\\hitfront.ffe");
			gosJoystick_LoadEffect (&m_Forces[HitLeftForce],id,"content\\force\\hitleft.ffe");
			gosJoystick_LoadEffect (&m_Forces[HitRightForce],id,"content\\force\\hitright.ffe");
			gosJoystick_LoadEffect (&m_Forces[WaterMoveForce],id,"content\\force\\watermove.ffe");
			gosJoystick_LoadEffect (&m_Forces[FallDownForce],id,"content\\force\\falldown.ffe");

			m_HitForceDetails.eType = gosForce_Constant;
			m_HitForceDetails.fMagnitude = 1.0f;
			m_HitForceDetails.fDurationSec = 1.0f;
			int i;
			for (i=0;i<12;i++)
			{
				m_HitForceDetails.bAffectedAxes[i] = false;
			}
			m_HitForceDetails.bAffectedAxes[JOY_XAXIS] = true;
			m_HitForceDetails.bAffectedAxes[JOY_YAXIS] = true;
			m_HitForceDetails.fXOrigin = 0;
			m_HitForceDetails.fYOrigin = 1.0f;
			m_HitForceDetails.fScale = 1.0f;
			m_HitForceDetails.fPeriodSec = 0;
			m_HitForceDetails.lpEnvelope = 0;
			gosJoystick_CreateEffect (&m_HitForce,id,&m_HitForceDetails);
		}
	}

	Interface::ForceFeedBack (value);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::PlayForce (int id)
{
	Verify (id >=0);
	Verify (id < maxForces);

	Check_Object (ControlsManager::Instance);
	if (m_ForceFeedBack)
	{
		if (ControlsManager::Instance->systemJoystick)
		{
			if (ControlsManager::Instance->systemJoystick->IsForceFeedback ())
			{
				if (m_Forces[id])
				{
					gosJoystick_PlayEffect(m_Forces[id]);
				}
			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::StopForce (int id)
{
	Verify (id >=0);
	Verify (id < maxForces);

	Check_Object (ControlsManager::Instance);
	if (ControlsManager::Instance->systemJoystick)
	{
		if (ControlsManager::Instance->systemJoystick->IsForceFeedback ())
		{
			if (m_Forces[id])
			{
				if (gosJoystick_IsEffectPlaying (m_Forces[id]))
					gosJoystick_StopEffect(m_Forces[id]);
			}
		}
	}
}

void VehicleInterface::PlayHitForce (Point3D dir,Scalar amplitude)
{
	Check_Object (ControlsManager::Instance);
	if (m_ForceFeedBack)
	{
		if (ControlsManager::Instance->systemJoystick)
		{
			if (ControlsManager::Instance->systemJoystick->IsForceFeedback ())
			{
				if (m_HitForce)
				{
					m_HitForceDetails.fXOrigin = -dir.x;
					m_HitForceDetails.fYOrigin = -dir.z;
					m_HitForceDetails.fMagnitude = amplitude;
					m_HitForceDetails.fScale = 1.0f;
	
					gosJoystick_UpdateEffect(m_HitForce,&m_HitForceDetails);
					gosJoystick_PlayEffect(m_HitForce);
				}
			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::CommonCreation(CreateMessage *message)
{
	Check_Object(this);
	Check_Object(message);

	const GameModel *model = GetGameModel();
	Check_Object(model);

#ifdef LAB_ONLY
	AddDebuggerMenuItem("Libraries\\Mech\\Mouse Control",
						Check_MouseControl,
						Activate_MouseControl,
						0);
#endif

	m_PlayedDamageCritical = false;

	m_LastForwardCommand = 0;
	m_LastBackwardCommand = 0;
	m_TorsoSpaceBarDown = 0;
    m_currentTargetReticuleCameraPosition = 3;// has to start at an valid number 0 - 2 or 3 for internal
	lastJoystickHat = -1.0f;
	joystickHat = lastJoystickHat;
	curMouseX = 0;
	curMouseY = 0;
	m_ChangeMouseTorsoThisFrame = false;

	userRequestForreticuleZoomChange = false;
	m_FrameCount = 0;
	m_LastShootTime = FLT_MIN;
	brbMode = model->brbMode;
	testAcceleration = 1.0f;
	needFireRequestReset = false;	
	targetDistance = model->maxTargetDistance;
	addedLengthToTarget = 0.0f;
	if (MW4Shell::Instance && MW4Shell::Instance->currentShellRunning == MW4Shell::InGameShellRunning)
	{
		fireBlocked = true;
		if (ControlsManager::Instance)
		{
			ControlsManager::Instance->m_IgnoreCommands = true;
		}
	}
	else
	{
		fireBlocked = false;
		if (ControlsManager::Instance)
		{
			ControlsManager::Instance->m_IgnoreCommands = false;
		}
	}

	//
	//--------------------------
	// Initialize the attributes
	//--------------------------
	//
	
	forwardCommand	= 0;
	backwardCommand	= 0;
	originCommand	= 0;
	lControl		= 0;
	rControl		= 0;
	currentDistance	= 0;
	reverseToggle = false;
//	reverseCommand = 0;
	rotateLeftCommand = 0;
	rotateRightCommand = 0;
	
	torsoTwistRight = 0;
	torsoTwistLeft = 0;
	pitchUp = 0;
	pitchDown = 0;

	cameraDetachCommand = 0;
	cameraResetCommand = 0;
	cameraTerrainCommand = 0;
	cameraTargetReticuleCommand = 0;

	m_selectedNavPoint.Remove();

	joystickXAxis = 0.0f;
	joystickYAxis = 0.0f;
	joystickRudder = 0.0f;
	joystickThrottle = 0.0f;
	lastJoystickTrottle = -1.0f;

	mouseWheel = 0;
	mousePosX = mousePosY = 0;
	mouseDeltaX = mouseDeltaY = 0;
	mouseTorsoToggle = true;
	mouseDeltaToggle = true;

	throttle0Percent = 0;
	throttle10Percent = 0;
	throttle20Percent = 0;
	throttle30Percent = 0;
	throttle40Percent = 0;
	throttle50Percent = 0;
	throttle60Percent = 0;
	throttle70Percent = 0;
	throttle80Percent = 0;
	throttle90Percent = 0;
	throttle100Percent = 0;

	isCooling = 0;

	fireRequest = 0;
	group1FireRequest = 0;
	group2FireRequest = 0;
	group3FireRequest = 0;
	group4FireRequest = 0;
	group5FireRequest = 0;
	group6FireRequest = 0;

	lookLeft = 0;
	lookRight = 0;
	lookBack = 0;
	lookDown = 0;

	twistRightTime = 0.0f;
	twistLeftTime = 0.0f;
	pitchUpTime = 0.0f;
	pitchDownTime = 0.0f;
	rotateRightTime = 0.0f;
	rotateLeftTime = 0.0f;

	cameraPitchUp = 0;
	cameraPitchDown = 0;
	cameraRollRight = 0;
	cameraRollLeft = 0;
	cameraYawLeft = 0;
	cameraYawRight = 0;
	cameraPanUp = 0;
	cameraPanDown = 0;
	cameraPanLeft = 0;
	cameraPanRight = 0;
	cameraZoomIn = 0;
	cameraZoomOut = 0;

	cameraOffset	= model->cameraStartOffset;
	cameraRotation	= model->cameraStartAngle;

	deathTimer = 0.0f;


	currentSpeedMPS = 0.0f;
	currentSpeedKPH = 0.0f;
	speedDemandMPS = 0.0f;
	speedDemandKPH = 0.0f;

	lastSpeedDemand = 0.0f;

	vehiclePosition = Point3D::Identity;
	leftFootFlag = 0;
	rightFootFlag = 0;
	
	weaponCommandReady = false;
	weaponCommand.weaponFired = 0;
	weaponCommand.originator.Remove();
	weaponCommand.target.Remove();
	weaponCommand.targetOffset = Point3D::Identity;


	lockedWeaponCommandReady = false;
	lockedWeaponCommand.weaponFired = 0;
	lockedWeaponCommand.originator.Remove();
	lockedWeaponCommand.target.Remove();
	lockedWeaponCommand.targetOffset = Point3D::Identity;

	spinTorsoPitchTimer = 0.0f;
	spinTorsoYawTimer = 0.0f;
	spinMechYawTimer = 0.0f;
	spinTorsoPitchMagnitude = 0.0f;
	spinTorsoYawMagnitude = 0.0f;
	spinMechYawMagnitude = 0.0f;

	
	temporaryTorsoMode = LeaveTorsoAlone;
	torsoAtRestTimer = 0.0f;


	cinemaPlaying = false;

	commandCount = 0;
	ChainIteratorOf<VehicleCommand*> command_iterator(&quedCommands);
	VehicleCommand *command;

	while ((command = command_iterator.GetCurrent()) != NULL)
	{
		command_iterator.Remove();
		delete command;
	}


	//set up an initial one just in case...
	targetLine.SetOrigin(Point3D(0.0f, 0.0f, 0.0f));
	targetLine.SetDirection(Vector3D(0.0f, 0.0f, 1.0f));
	targetLine.m_length = 1.0f;
	reticuleNormal = Normal3D(0.0f, 0.0f, 1.0f);


	targetQuery.m_line = &targetLine;
	targetQuery.m_normal = &reticuleNormal;
	targetQuery.m_collisionMask = CanBeShotFlag;
	targetQuery.m_raySource = vehicle;

	
	fNeedSmoke = false;
	executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);

	m_AIControlledHUD = false;


	jumpHeightAdjustment.SetNewDampen(0.0f);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Respawn(Entity::CreateMessage *message)
{
	Check_Object(this);
	Check_Object(message);

	BaseClass::Respawn(message);

	m_PlayedDamageCritical = false;

	if (rememberCameraView == ExternalCameraTerrainFollowView)
	{
		rememberCameraView = InMechCameraView;
		const GameModel *model = GetGameModel();
		cameraOffset	= model->cameraStartOffset;
		cameraRotation	= model->cameraStartAngle;
	}

    if (g_nMR == 2)
        cameraView = ExternalCameraTerrainFollowView;
    else
	    cameraView = rememberCameraView;
	

	CreateMessage *interface_message = Cast_Pointer(CreateMessage *, message);
	CommonCreation(interface_message);

	if(MWGUIManager::GetInstance())
		MWGUIManager::GetInstance()->Reset();

	cameraOffset = rememberCameraOffset;
	cameraRotation = rememberCameraRotation;

    if ((MWApplication::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState) && (vehicle != NULL))
	SetCameraMode(cameraView);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
VehicleInterface::~VehicleInterface()
{
	GlobalPointers::ClearPointer(VehicleInterfaceGlobalPointerIndex);

	MW4AI::UserConstants::DecrementRefCount();
	m_PlayerAI = NULL;
	if(weaponIterator)
		delete weaponIterator;
	for (int i=0; i<6; i++)
		delete groupWeaponIterator[i];


	ChainIteratorOf<VehicleCommand*> command_iterator(&quedCommands);
	VehicleCommand *command;

	commandCount = 0;
	while ((command = command_iterator.GetCurrent()) != NULL)
	{
		command_iterator.Remove();
		delete command;
	}

	if (MWGUIManager::GetInstance())
	{
		Check_Object(MWGUIManager::GetInstance());
		MWGUIManager::GetInstance()->ClearGUIChain();
	}
	if (weatherEffect.GetCurrent())
	{
		weatherEffect.GetCurrent()->executionState->
			RequestState(Effect::ExecutionStateEngine::StoppingState);
	}

	Check_Object (ControlsManager::Instance);
	if (ControlsManager::Instance->systemJoystick)
	{
		if (ControlsManager::Instance->systemJoystick->IsForceFeedback ())
		{
			gosJoystick_DestroyEffect (&m_Forces[LeftFootForce]);
			gosJoystick_DestroyEffect (&m_Forces[RightFootForce]);
			gosJoystick_DestroyEffect (&m_Forces[FireMissleForce]);
			gosJoystick_DestroyEffect (&m_Forces[FireProjectileForce]);
			gosJoystick_DestroyEffect (&m_Forces[HitBackForce]);
			gosJoystick_DestroyEffect (&m_Forces[HitFrontForce]);
			gosJoystick_DestroyEffect (&m_Forces[HitLeftForce]);
			gosJoystick_DestroyEffect (&m_Forces[HitRightForce]);
			gosJoystick_DestroyEffect (&m_Forces[WaterMoveForce]);
			gosJoystick_DestroyEffect (&m_Forces[FallDownForce]);
		}
	}

	//REMOVE
//	if (m_LockTimeObject != 0)
//	{
//		GUITextManager::GetInstance()->RemoveTextObject(m_LockTimeObject);
//		// delete here???
	//}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::TestInstance() const
{
	Verify(IsDerivedFrom(DefaultData));
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void
	VehicleInterface::PreCollisionExecute(Time till)
{
	Check_Object(this);

	PRECOLLISION_LOGIC("VehicleInterface");
	if (m_FrameCount == 0)
	{
		Check_Object (ControlsManager::Instance);
		ControlsManager::Instance->CenterMouse ();
	}

	Check_Object(this);
	Check_Object(vehicle);
	Check_Object(executionState);

	//BaseClass::PreCollisionExecute(till);

	//
	//----------------------
	// Call inherited method
	//----------------------
	//
	Scalar time_slice = GetTimeSlice(till);


	jumpHeightAdjustment.AdvanceTime(time_slice);

	if (MWGUIManager::GetInstance () && IsObserving(true))
	{
		Check_Object(MWGUIManager::GetInstance());
		//sanghoon
        if (!CTCL_IsConsoleX() && !g_CamerashipParams.m_bAllowChatDisplay) {
		    HUDChat *chat;
		    chat = Cast_Object (HUDChat *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT));
		    if (chat)
			    chat->Hide();
        }

		HUDCamera *hud;
		hud = Cast_Object (HUDCamera *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CAMERA));

		HUDScore *hud_score;
		hud_score = Cast_Object (HUDScore*,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_SCORE));

        Entity* pFollow = observingEntity.GetCurrent();
		if (pFollow)
		{
			Mech *mech;
			if (pFollow->IsDerivedFrom (Mech::DefaultData))
			{
				mech = Cast_Object (Mech *, pFollow);
                const ReplicatorID& RepID = mech->GetReplicatorID();

                int nScore, nKills, nDeaths;
                if (hud_score) {
                    nScore = hud_score->GetScore4Player(RepID, nKills, nDeaths); // jcem
                } else {
                    nScore = nKills = nDeaths = 0;
                }
                
                const char* pcszFollowName;
				if (mech->isPlayerVehicle)
				{
					int id = RepID.connectionID;
					MWApplication *app = MWApplication::GetInstance ();
					ServedConnectionData *data;
					data = &(app->servedConnectionData[id]);
                    pcszFollowName = data->pilotName;
					//hud->FactionName (data->clanName);

				}
				else
				{
					pcszFollowName = observingEntity.GetCurrent ()->instanceName;
					//jcem - Check_Object(MWGUIManager::GetInstance());
					//jcem - MWGUIManager::GetInstance()->ShowHudComponent(MWGUIManager::HUD_CHAT);
					hud->FactionName ("");
				}
                char sz[128];
                if (hud_score) {
                    if (g_CamerashipParams.m_bDisplayCameraStates)
                        sprintf(sz, " %s  %s%s", pcszFollowName, ViewName(m_curView), RangeName(m_curRange)); // %d/%d/%d nScore, nKills, nDeaths, 
                    else
                        sprintf(sz, " %s", pcszFollowName); // / %d/%d/%d nScore, nKills, nDeaths, 
                    pcszFollowName = &sz[0];
                }
				hud->FollowName (pcszFollowName);
			}
			else
			{
				hud->FollowName (pFollow->instanceName);
				hud->FactionName ("");
			}
		}
		else
		{
			hud->FollowName ("");
			hud->FactionName ("");
		}
	}
	if ((MWGUIManager::GetInstance()) && (m_CurrentLightAmpMod != 0))
	{
		m_CurrentLightAmpMod -= (time_slice * LIGHT_AMP_MOD_PER_SECOND);
		if (m_CurrentLightAmpMod < 0)
			m_CurrentLightAmpMod = 0;
		if (MWGUIManager::GetInstance()->lightAmp)
			MWGUIManager::GetInstance()->lightAmp->SetModifier (m_CurrentLightAmpMod);
//		if (MWGUIManager::GetInstance()->zoomLightAmp)
//			MWGUIManager::GetInstance()->zoomLightAmp->SetModifier (m_CurrentLightAmpMod);
	}

	// NEW FROM GOS?? WHAT SHOULD WE DO???
	//Verify(time_slice > 0.0f);
	if (time_slice <= 0.0f)
	{
		SPEW((0,"VehicleInterface::PreCollisionExecute TimeSlice <= 0.0f  What should we do??? %f ", time_slice));
	}

	// update debug interface
	currentSpeedMPS = vehicle->currentSpeedMPS;
	currentSpeedKPH = vehicle->currentSpeedKPH;
	speedDemandMPS = vehicle->speedDemandMPS;
	speedDemandKPH = vehicle->speedDemandKPH;
	vehicle->GetTransSpeedKPH (minForwardKPH,minReverseKPH);
	vehicle->GetMaxSpeedKPH (maxForwardKPH,maxReverseKPH);
	vehicle->GetTransSpeedNormalized (minForwardNormal,minReverseNormal);
	

#if 0
	MWEntityManager *manager = Cast_Object (MWEntityManager*, MWEntityManager::GetInstance());
	DictionaryManager *dictionary_manager = manager->GetDictionaryManager(Connection::Local->GetID());
	if(dictionary_manager != NULL)
	{
		Dictionary *dictionary = dictionary_manager->GetCurrentDictionary();
		netBandwidth = dictionary->dictionaryBandwidth;
	}
#endif


#if 0
	if (MWGUIManager::GetInstance())
	{
		Check_Object(MWGUIManager::GetInstance());
		MWGUIManager::GetInstance()->SetSpeedBar(speedDemandKPH,transSpeedKPH);
		SetTargetInfo();
		//Dave Here
	}
#endif

	vehiclePosition = vehicle->GetLocalToWorld();
	leftFootFlag = vehicle->leftFootDown;
	rightFootFlag = vehicle->rightFootDown;

	fNeedSmoke = false;

	spinTorsoPitchTimer -= time_slice;
	spinTorsoYawTimer -= time_slice;
	spinMechYawTimer -= time_slice;

	Min_Clamp(spinTorsoPitchTimer, 0.0f);
	Min_Clamp(spinTorsoYawTimer, 0.0f);
	Min_Clamp(spinMechYawTimer, 0.0f);


	if (brbMode)
	{
		//
		//--------------------------------------------------------
		// If the interface is in camera mode, then move it around
		//--------------------------------------------------------
		//
		BRBModeSimulation(till);
	}
	else
	{
	
		
		#if defined(_ARMOR)
			++Debug_Frame_Rate_Counter;
		#endif
		
		

		// these buffers are cleared and sent in
		// MWEntityManager::ServerLocalEntities()
		
		if (executionState->GetState() == ExecutionStateEngine::WatchingDeathState)
		{
			//watch the death from external view
			
			deathTimer += time_slice;

			
			ReadControls(till);
			
			CameraSimulation(till);
		
		}
		else if ((g_nMR == 2) || (executionState->GetState() == ExecutionStateEngine::ObservationState))
		{
			ReadControls(till);
			
			CameraSimulation(till);
		}
		else if (executionState->GetState() == ExecutionStateEngine::AIRunningState)
		{
			Verify (m_PlayerAI);
		}
		else if (executionState->GetState() == ExecutionStateEngine::FieldBaseState)
		{
			Verify (m_PlayerAI);
			CheckEndFieldBase (till);
		}
#if 0
		else if (executionState->GetState() == ExecutionStateEngine::AutoPilotState)
		{
			Verify (m_PlayerAI);
			CheckEndAutoPilot (till);
		}
#endif
		else if(executionState->GetState() != ExecutionStateEngine::FollowingState)
		{
          extern int g_nMR;
          if (g_nMR != 2) {
			ReadControls(till);			

//      ModifyControls(till); // any tweaks that need doing to the controls can go here

			ApplyControls(till);

			CameraSimulation(till);
          }
		}
	}

  //
  // If we are in the external view with the target reticule that we will need to use the controls differently
  // so that the targetting reticule move smoothly in this view.
  //



	Torso *torso;
	torso = vehicle->GetTorso();
	if ((torso) &&
		(MWGUIManager::GetInstance()))
	{
		Check_Object(MWGUIManager::GetInstance());
		MWGUIManager::GetInstance()->SetTorsoTwist(torso->yawValue);
		MWGUIManager::GetInstance()->SetTorsoPitch(torso->pitchValue);

		UnitVector3D direction;
		vehicle->eyeSitePointer.GetCurrent()->GetLocalToWorld().GetLocalForwardInWorld(&direction);

		longTomAngle = direction.y;
		if(longTom)
			longTomDistance = longTom->GetDistanceWithAngle(longTomAngle);
	}

	if ((reticuleEntity.GetCurrent() != 0) &&
		(vehicle != 0) &&
		(Application::GetInstance() != 0) &&
		(Application::GetInstance()->networkingFlag == false) &&
		(reticuleEntity.GetCurrent()->IsDerivedFrom(MWMover::DefaultData) == true))
	{
		MWMover* mover = Cast_Object(MWMover*,reticuleEntity.GetCurrent());
		Check_Object(mover);

		if (mover->GetParentVehicle() != 0)
		{
			Check_Object(mover);

			mover->GetParentVehicle()->NotifyInTargetingReticule(*vehicle);
		}
		else
		{
			if (mover->IsDerivedFrom(MWObject::DefaultData) == true)
			{
				MWObject* mwobject = Cast_Object(MWObject*,mover);

				mwobject->NotifyInTargetingReticule(*vehicle);
			}
		}
	}

//	m_LancemateCommandDisplay.Update();

	//Check the player mech's reaction spheres (used for fog right now)
	if(isAttachedVehicleAMech)
	{
		MWMission *mw_mission = Cast_Object(MWMission *, MWMission::GetInstance());
		Mech *mech = Cast_Object(Mech *, vehicle);
		mw_mission->ProcessPlayerReactionSpheres(mech);
	}

	//If we have no target, but our sensors do then we should set it up!
	if(!m_interfaceTarget.GetCurrent())
	{
		if (vehicle->GetSensor() != NULL)
		{
			Entity *target = vehicle->GetSensor()->GetNearestEnemy();
			if (MWGUIManager::GetInstance() != 0)
			{
				MWGUIManager::GetInstance()->SetNewTargetWindowEntity(target);
			}
			if(target)
			{
				m_interfaceTarget.Add(target);
				ReactToEvent (OBJECT_SCANNED);
				if (ShowTargetCamera ())
					m_targetCamera->SetScene(target->GetElement());
				else
					m_targetCamera->SetScene (NULL);
			}
		}
	}

	if(reticuleZoomShowing && m_reticuleCamera)
	{
		Stuff::Scalar near_clip;
		Stuff::Scalar far_clip;
		Stuff::Scalar horizontal_fov_zoom_halfed;
		Stuff::Scalar height_to_width;
		Stuff::Scalar left, top, right, bottom;
		ElementRenderer::CameraElement *camera_zoom = m_reticuleCamera;
		Check_Object(camera_zoom);

		//
		// Update this camera to properly clip
		//
		camera_zoom->GetPerspective(near_clip, far_clip, horizontal_fov_zoom_halfed, height_to_width);

        // jcem - begin
        if (!((g_fZoomTimeC < 0.0) || Stuff::Close_Enough(g_fZoomTime, 0.0) || Stuff::Close_Enough(g_fZoomFOVA, g_fZoomFOVB))) {
    	    MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());
            float fZoomTime = mission->GetMissionTime();
            fZoomTime -= g_fZoomTimeC;
            float fZoom;
            if (fZoomTime < g_fZoomTime) {
                if (fZoomTime < 0.0)
                    fZoomTime = 0.0;
                fZoom = g_fZoomFOVA - ((g_fZoomFOVA - g_fZoomFOVB) * (fZoomTime / g_fZoomTime));
                if (Stuff::Close_Enough(fZoom, g_fZoomFOVB)) {
                    fZoom = g_fZoomFOVB;
                }
            } else {
                fZoom = g_fZoomFOVB;
            }
            m_reticuleCamera->SetPerspective(near_clip, far_clip, fZoom, height_to_width);
            camera_zoom->GetPerspective(near_clip, far_clip, horizontal_fov_zoom_halfed, height_to_width);
        }
        // jcem - end

		camera_zoom->GetViewport(left, top, right, bottom);

		MidLevelRenderer::MLRClipper *clipper_zoom;
		camera_zoom->Sync();
		clipper_zoom = camera_zoom->GetClipper();

		Check_Object(clipper_zoom);
		clipper_zoom->UpdateClipperCameraData(
					camera_zoom->GetLocalToWorld(),
					camera_zoom->GetCameraToClip()
				);
	}

	switch (g_nInputMode)
	{
	case _BIGINNER_MODE:
		perminateTorsoMode = CenterLegsToTorso;
		break;
	case _VETERAN_MODE:
	case _EXPERT_MODE:
        if (g_nOldInputMode != g_nInputMode) {
			perminateTorsoMode = LeaveTorsoAlone;
            g_nOldInputMode = g_nInputMode;
        }
		break;
	}

/////////////////////////////////////
    if (!vehicle->IsDerivedFrom(Mech::DefaultData))
        return;
	Mech *mech = Cast_Object(Mech *, vehicle);

	if (mech->IsCrouched ())
	{
		g_bCrouch = TRUE;
	}
	else
	{
		g_bCrouch = FALSE;
	}

	//if (m_gCool > 0) {
	//	g_bCool = TRUE;
	//} else {
	//	g_bCool = FALSE;
	//}

// MSL 5.02 Searchlight
//	searchlight allowed based on Map settings, not console
//	if (Mission::GetInstance()->m_isNightMission)
	if (Mission::GetInstance()->DoesAllowSearchLights())
	{
		g_SearchLight = TRUE;
	} else {
		g_SearchLight = FALSE;
	}

	if (vehicle->DoesHaveLightAmp ())
	{
		g_LightAmp = TRUE;
	}
	else
	{
		g_LightAmp = FALSE;
	}
	
	if (mech->IsSearchLightOn ()) {
		if (g_SearchLight == TRUE) {
			g_UsingSearchLight = TRUE;
		}
	} else {
		g_UsingSearchLight = FALSE;
	}

	if (g_LightAmp == TRUE) {
	    g_UsingLightAmp = !!MWGUIManager::GetInstance()->lightAmp->IsOn();
	} else {
		g_UsingLightAmp = FALSE;
	}

/////////////////////////////////////////
	if (GetShutdownState())
	{
		g_pRIOMain->ResetTable (FALSE);
		g_pRIOMain->m_bOneFlagShutDown = TRUE;

		if (g_nInputMode == _BIGINNER_MODE) 
		{			
            if (mech->m_heatManager->GetHeatPercentage() < g_fAutoPowerUpLevel) {
                ReactToEvent (POWER_UP);
                QueCommand(VehicleCommand::PowerDownCommand);
            }
		}

// MSL 5.02 Zoom
		if (reticuleZoomShowing)
		{
				HideZoom ();
				requestedZoomChange = false;
		}

		if (g_UsingLightAmp == TRUE) {
			MWGUIManager::GetInstance()->HideLightAmplification();
			Mission::GetInstance()->ResetMissionLights();
		}

		g_pRIOMain->SetLampState (51, LAMP_OFF); // Zoom Lamp
		g_pRIOMain->SetLampState (50, LAMP_OFF); // Jump Jet Lamp
		g_pRIOMain->SetLampState (48, LAMP_OFF); // Light Amp Lamp
		g_pRIOMain->SetLampState (33, LAMP_OFF); // Jump Jet Lamp
		g_pRIOMain->SetLampState (34, LAMP_OFF); // Jump Jet Lamp
		g_pRIOMain->SetLampState (16, LAMP_OFF); // Jump/Zoom Lamp

	}
	else
	{
		if (g_pRIOMain->m_bOneFlagShutDown == TRUE) {
			g_pRIOMain->SetTable (FALSE);
			g_pRIOMain->m_bOneFlagShutDown = FALSE;
		}
	}

	if (!GetShutdownState()) 
	{
		//
		if (g_nInputMode == _BIGINNER_MODE) 
		{			
// MSL 5.02 Zoom
			if (reticuleZoomShowing) {
				HideZoom ();
				requestedZoomChange = false;
			}

			if (!g_bJumpZoom) {
				g_pRIOMain->SetLampState (16, LAMP_OFF);
			}

			if (g_bCrouch == TRUE) {
				QueCommand (VehicleCommand::CrouchCommand);
			}

			if (g_UsingLightAmp == TRUE) {
				MWGUIManager::GetInstance()->HideLightAmplification();
				Mission::GetInstance()->ResetMissionLights();
			}

			Sensor *sensor;
			sensor = vehicle->GetSensor();

			if (sensor->GetSensorMode () == Sensor::PassiveMode) {
				sensor->SetSensorMode(Sensor::ActiveMode, vehicle->DoesHaveBeagle());
				ReactToEvent (RADAR_ON);
				GUIRadarManager *radarhud;
				radarhud = Cast_Object (GUIRadarManager *,MWGUIManager::GetInstance()->Component (MWGUIManager::HUD_RADAR));
				radarhud->SetRange(sensor->GetMaxRange ());
			}

			g_pRIOMain->SetLampState (20, LAMP_OFF); // Crouch Lamp Secondary
			g_pRIOMain->SetLampState (17, LAMP_OFF); // Shutdown Lamp Secondary
			g_pRIOMain->SetLampState (25, LAMP_OFF); // Radar Mode Lamp Secondary
			g_pRIOMain->SetLampState (26, LAMP_OFF); // Light Amp Lamp Secondary
			g_pRIOMain->SetLampState (51, LAMP_OFF);	// Zoom Lamp MFD
			g_pRIOMain->SetLampState (48, LAMP_OFF);	// Light Amp Lamp MFD
		}
		else
		{
			if (IsLampOFF (20))
				g_pRIOMain->SetLampState (20, LAMP_DEFAULT);
			if (IsLampOFF (17))
				g_pRIOMain->SetLampState (17, LAMP_DEFAULT);
			if (IsLampOFF (25))
				g_pRIOMain->SetLampState (25, LAMP_DEFAULT);
            if (IsLampOFF (26)) {
    		    if (vehicle->DoesHaveLightAmp())
				{
    				g_pRIOMain->SetLampState (26, LAMP_DEFAULT);
					g_pRIOMain->SetLampState (48, LAMP_DEFAULT);
				}
            }
			g_pRIOMain->SetLampState (51, LAMP_DEFAULT);
		}
		//

		// Program Mode
		if (g_nProgramMode == FALSE) {
			g_pRIOMain->SetLampState (29, LAMP_OFF);
		} else {
			if (IsLampOFF (29)) 
				g_pRIOMain->SetLampState (29, LAMP_DEFAULT);
		}
		//

		//if (g_bCool == FALSE) {
		//	g_pRIOMain->SetLampState (19, LAMP_OFF);
		//} else {
		//	if (IsLampOFF (19) == TRUE) {
		//		g_pRIOMain->SetLampState (19, LAMP_DEFAULT);
		//	}
		//}

		if (g_SearchLight == FALSE) {
			g_pRIOMain->SetLampState (27, LAMP_OFF);
		}

		//if (g_LightAmp == FALSE) {
		//	g_pRIOMain->SetLampState (26, LAMP_OFF);
		//}

		////////////////////////
		// Aux#1
		////////////////////////

		g_pRIOMain->SetTeamOrderButtons();
    }
    if (!mech->IsDestroyed())
	{
        Check_Object(mech);

		NetMissionParameters::MWNetMissionParameters *params;
		if (MWApplication::GetInstance()->serverFlag)
			params = MWApplication::GetInstance()->GetLocalNetParams();
		else
			params = MWApplication::GetInstance()->GetServerNetParams();
		m_HeatMode = params->m_heatOn;

		if (m_HeatMode)
		{
			if (mech->m_heatManager->IsCooling())
			{
				if (g_pRIOMain->GetLampState(19) != LAMP_BRIGHT)
				{
			    g_pRIOMain->SetLampState (19, LAMP_BRIGHT);
            }
			}
			else
			{
	            if (0 < mech->m_heatManager->GetCoolant())
				{
	                if (g_fNeedFlushLevel <= mech->m_heatManager->GetHeatPercentage())
					{
			            if (g_pRIOMain->GetLampState(19) != LAMP_FLASH)
						{
			            g_pRIOMain->SetLampState (19, LAMP_FLASH);
                    }
					}
					else
					{
			            if (g_pRIOMain->GetLampState(19) != LAMP_DIM)
						{
			            g_pRIOMain->SetLampState (19, LAMP_DIM);
							g_pRIOMain->SetLampState (49, LAMP_DIM);
						}
	                }	
				}	
				else
				{
		        if (!IsLampOFF(19))
				{
			        g_pRIOMain->SetLampState (19, LAMP_OFF);
						g_pRIOMain->SetLampState (49, LAMP_OFF);
					}
				}
			}
		}
		else
		{
	        g_pRIOMain->SetLampState (19, LAMP_OFF);
			g_pRIOMain->SetLampState (49, LAMP_OFF);
		}

// MSL 5.03 Ammo Bay Fire
// 
		int m_WeaponJamMode = params->m_weaponjamOn;
		int m_AmmoMode = params->m_ammobayfireOn;

		if (weaponIterator)
		{
			Weapon* weapon = weaponIterator->GetCurrent();
			if (weapon)
			{
				if(weapon->executionState->GetState() == ProjectileWeapon::ExecutionStateEngine::AmmoFireState)
				{
			        g_pRIOMain->SetLampState (32, LAMP_FLASH);
				}
				else
				{
					if (!m_AmmoMode)
					{
						g_pRIOMain->SetLampState (32, LAMP_OFF);
					}
					else
					{
						g_pRIOMain->SetLampState (32, LAMP_DEFAULT);
					}
				}

				if(weapon->executionState->GetState() == ProjectileWeapon::ExecutionStateEngine::HeatJammedState)
				{
			        g_pRIOMain->SetLampState (35, LAMP_FLASH);
				}
				else
				{
					if (!m_WeaponJamMode)
					{
				        g_pRIOMain->SetLampState (35, LAMP_OFF);
					}
					else
					{
						g_pRIOMain->SetLampState (35, LAMP_DEFAULT);
					}
				}
			}
		}
// MSL 5.03 Ammo Bay Fire
// Random chance of Ammo Bay Fire
		if(m_AmmoMode == 1)
		{
			if (mech->m_heatManager->GetHeatPercentage() > 0.90f)
			{
				int ammofire_check = 0;

				Subsystem *subsystem;
		        ChainIteratorOf<Subsystem*> iterator(&mech->subsystemsInVehicle);
			    while((subsystem = iterator.ReadAndNext()) != NULL)
				{
				    if(subsystem->IsDerivedFrom(Weapon::DefaultData))
					{
						Weapon *weapon = Cast_Object(Weapon *, subsystem);
						Check_Object(weapon);
						{
							if(weapon->DoesHaveAmmo())
							{
								if (weapon->executionState->GetState() == ProjectileWeapon::ExecutionStateEngine::AmmoFireState)
								{
									ammofire_check = 1;
									break;
								}
							}
						}
					}
				}

				if (ammofire_check == 0)
				{
					iterator.First();
					while((subsystem = iterator.ReadAndNext ()) != NULL)
					{
					    if(subsystem->IsDerivedFrom(Weapon::DefaultData))
						{
							Weapon *weapon = Cast_Object(Weapon *, subsystem);
							Check_Object(weapon);
							{
								if(weapon->DoesHaveAmmo())
								{	
									ProjectileWeapon *projectile_weapon;
									projectile_weapon = Cast_Object(ProjectileWeapon *, weapon);
									const ProjectileWeapon__GameModel *model = projectile_weapon->GetGameModel();
									Check_Object(model);
									if(model->m_timeToAmmoBay > 0)
									{
										int heatjam = 0;
										heatjam = (Stuff::Random::GetLessThan(100) * 10);
										if (heatjam < 5)
										{
											weapon->executionState->RequestState(ProjectileWeapon::ExecutionStateEngine::AmmoFireState);
										}
									}
								}
							}
						}
					}	
	            }
            }
		}

// MSL 5.03 Ammo Bay Fire
// Generate Audio-Visual Warning if Ammo Bay Fire
		if(m_AmmoMode == 1)
		{
            Subsystem *subsystem;
            ChainIteratorOf<Subsystem*> iterator(&mech->subsystemsInVehicle);
	        while((subsystem = iterator.ReadAndNext()) != NULL)
			{
			    if(subsystem->IsDerivedFrom(Weapon::DefaultData))
				{
					Weapon *weapon = Cast_Object(Weapon *, subsystem);
					Check_Object(weapon);
					if (weapon->executionState->GetState() == ProjectileWeapon::ExecutionStateEngine::AmmoFireState)
					{
						ReactToEvent (VehicleInterface::MECH_AMMOBAY_FIRE);
						MWGUIManager::GetInstance()->ShowFIRE(true);
						break;
					}
					else
					{
						MWGUIManager::GetInstance()->ShowFIRE(false);
					}
				}
			}
		}

// MSL 5.03 Weapon Jam
// Generate Visual Warning if Weapon Jammed
		if(m_WeaponJamMode == 1)
		{
            Subsystem *subsystem;
            ChainIteratorOf<Subsystem*> iterator(&mech->subsystemsInVehicle);
	        while((subsystem = iterator.ReadAndNext()) != NULL)
			{
			    if(subsystem->IsDerivedFrom(Weapon::DefaultData))
				{
					Weapon *weapon = Cast_Object(Weapon *, subsystem);
					Check_Object(weapon);
					if (weapon->executionState->GetState() == ProjectileWeapon::ExecutionStateEngine::HeatJammedState)
					{
						MWGUIManager::GetInstance()->ShowJAM(true);
						break;
					}
					else
					{
						MWGUIManager::GetInstance()->ShowJAM(false);
					}
				}
			}
		}

// MSL 5.03 No Weapons Betty

		if (g_nNoWeapons == 1)
		{
			ReactToEvent (VehicleInterface::NO_WEAPON);
			g_nNoWeapons = 2;
		}

// MSL 5.03 Dump Ammo
		// Dump Ammo Round Always active
		if (g_nAmmoDump1 == TRUE)
		{
			DumpAmmoRound();
			g_nAmmoDump1 = FALSE;
		}

// MSL 5.03 Dump Ammo		
		// Dump Ammo Magazine only if limited ammo.
		if(m_AmmoMode == 1)
		{
			if (g_nAmmoDump2 == TRUE)
			{
				DumpAmmoMagazine();
			}
		}

        int nState = GetEjectableState();
        if (nState) {
            if (nState == -1) { // already ejecting...
		        if (g_pRIOMain->GetLampState(g_nEjectButton) != LAMP_BRIGHT) {
			        g_pRIOMain->SetLampState(g_nEjectButton, LAMP_BRIGHT);
                }
            } else {
		        if (g_pRIOMain->GetLampState(g_nEjectButton) != LAMP_FLASH) {
			        g_pRIOMain->SetLampState(g_nEjectButton, LAMP_FLASH);
                }
            }
        } else {
		    if (!IsLampOFF(g_nEjectButton))
			    g_pRIOMain->SetLampState(g_nEjectButton, LAMP_OFF);
        }
        if (g_nFiringMode) {
            g_pRIOMain->SetLampState (2, g_baChainFireMode[0] ? LAMP_FLASH: LAMP_BRIGHT);
            g_pRIOMain->SetLampState (1, g_baChainFireMode[1] ? LAMP_FLASH: LAMP_BRIGHT);
            g_pRIOMain->SetLampState (0, g_baChainFireMode[2] ? LAMP_FLASH: LAMP_BRIGHT);
        } else {
            g_pRIOMain->SetLampState (2, LAMP_DEFAULT);
            g_pRIOMain->SetLampState (1, LAMP_DEFAULT);
            g_pRIOMain->SetLampState (0, LAMP_DEFAULT);
        }
    }
	else
	{
// MSL 5.03 Light Amp - Turn off Light Amp if Dead
		if (g_UsingLightAmp == TRUE) {
			MWGUIManager::GetInstance()->HideLightAmplification();
			Mission::GetInstance()->ResetMissionLights();
		}

		if (!IsLampOFF(28))
		{
			g_pRIOMain->SetLampState (28, LAMP_OFF);
		}
		if (!IsLampOFF(19))
		{
			g_pRIOMain->SetLampState (19, LAMP_OFF);
			g_pRIOMain->SetLampState (49, LAMP_OFF);
		}
		if (!IsLampOFF(g_nEjectButton))
		{
			g_pRIOMain->SetLampState(g_nEjectButton, LAMP_OFF);
		}
        g_pRIOMain->SetLampState (2, LAMP_OFF);
        g_pRIOMain->SetLampState (1, LAMP_OFF);
        g_pRIOMain->SetLampState (0, LAMP_OFF);
    }
	if (g_pRIOMain->GetLampState(55) != LAMP_BRIGHT)
	{
		g_pRIOMain->SetLampState (55, LAMP_DIM);
    }
// MSL 5.05 Objective Display
	if (g_pRIOMain->GetLampState(36) != LAMP_BRIGHT)
	{
		g_pRIOMain->SetLampState (36, LAMP_DIM);
    }
    if (!g_pRIOMain->GetLampState(50)) {
        switch(GetJumpJetState())
        {
        case 0:
		    g_pRIOMain->SetLampState (50, LAMP_OFF);
            break;
        case 1:
		    g_pRIOMain->SetLampState (50, LAMP_DIM);
            break;
        default:
		    g_pRIOMain->SetLampState (50, LAMP_OFF);
            break;
        }
    }

    if (reticuleZoomShowing)
		g_pRIOMain->SetLampState (16, LAMP_BRIGHT);
	
	if (g_nInputMode != _BIGINNER_MODE) 
	{
		if (vehicle->DoesHaveLightAmp())
		{
			if (MWGUIManager::GetInstance ())
			{
				if (MWGUIManager::GetInstance ()->lightAmp->IsOn())
				{
					g_pRIOMain->SetLampState (26, LAMP_BRIGHT);
				}
				else
				{
					g_pRIOMain->SetLampState (26, LAMP_DIM);
				}
			}
		}	
		else
		{
			g_pRIOMain->SetLampState (26, LAMP_OFF);
		}
	}
	else
	{
		g_pRIOMain->SetLampState (26, LAMP_OFF);
  }

    if (g_pRIOMain->GetLampState (33) != LAMP_BRIGHT) {
	    switch(GetJumpJetState())
        {
        case 1:
            if (g_bJumpZoom)
			{
		        g_pRIOMain->SetLampState (16, LAMP_DIM);
            }
			g_pRIOMain->SetLampState (50, LAMP_DIM);
		    g_pRIOMain->SetLampState (33, LAMP_DIM);
		    g_pRIOMain->SetLampState (34, LAMP_DIM);
            break;
        default:
			g_pRIOMain->SetLampState (50, LAMP_OFF);
		    g_pRIOMain->SetLampState (33, LAMP_OFF);
		    g_pRIOMain->SetLampState (34, LAMP_OFF);
            break;
	    }
    }
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::SetDeathMode()
{
	ReactToEvent (MISSILE_LOCKLOST);

	if (executionState->GetState() != ExecutionStateEngine::WatchingDeathState)
	{
		//SPEWALWAYS(("jerryeds", "SET DEATH"));

// Added Ejecting Betty to death
// MSL 5.00
        if (g_nMR != 2)
		{
			AudioCommand *command = AudioCommand::Create(AudioRenderer::VOType, "VO\\Generic\\Ejecting_Bet.wav{handle}", 1.0f,	1.0f);
			Check_Object(command);
		    command->Play();
        }
		const GameModel *model = GetGameModel();
		Check_Object(model);

		if (cameraView != ExternalCameraTerrainFollowView)
		{
			rememberCameraView = cameraView;
			rememberCameraOffset = cameraOffset;
			rememberCameraRotation = cameraRotation;
		}

		SetCameraMode(ExternalCameraTerrainFollowView, *model);
		
		cameraOffset = model->cameraStartOffset;
		cameraRotation	= YawPitchRoll(150.0f*Degrees_Per_Radian, 0.0f, 0.0f);

		ReactToEvent (VehicleInterface::NO_HEAT);
		ReactToEvent (VehicleInterface::COOLANT_FLUSH_STOP);
		ReactToEvent (VehicleInterface::NARC_SIGNAL_STOP);
		ReactToEvent (VehicleInterface::STEP_WATER_STOP);
		executionState->RequestState(ExecutionStateEngine::WatchingDeathState);

		deathTimer = 0.0f;
		ShowZoomIfOn(false);
		ShowStatic(false);

		if(MWGUIManager::GetInstance())
		{
			MWGUIManager::GetInstance()->Hide();
			if(MWApplication::GetInstance()->networkingFlag)
			{
				HUDChat *chat;
				chat = Cast_Object (HUDChat *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT));
				chat->Show ();
			}
		}

	}


}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//


void
	VehicleInterface::SetObservationMode()
{
	const GameModel *model = GetGameModel();
	
	observerMode = true;

	SetCameraMode(ExternalCameraTerrainFollowView, *model);

	executionState->RequestState(ExecutionStateEngine::ObservationState);

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::SetEjectMode()
{
	ReactToEvent (MISSILE_LOCKLOST);
	const GameModel *model = GetGameModel();
	Check_Object(model);

	if (executionState->GetState() != ExecutionStateEngine::WatchingDeathState)
	{

		//SPEWALWAYS(("jerryeds", "SET EJECT"));

// Added Eject Betty to Eject sequence
// MSL 5.00
        if (g_nMR != 2) {
		    AudioCommand *command = AudioCommand::Create(AudioRenderer::VOType, "VO\\Generic\\Ejecting_Bet.wav{handle}", 1.0f,	1.0f);
		    Check_Object(command);
		    command->Play();
        }

		if (cameraView != ExternalCameraTerrainFollowView)
		{
			rememberCameraView = cameraView;
			rememberCameraOffset = cameraOffset;
			rememberCameraRotation = cameraRotation;
		}

		SetCameraMode(ExternalCameraTerrainFollowView, *model);
		
		cameraOffset = model->cameraStartOffset;
		cameraRotation	= YawPitchRoll(150.0f*Degrees_Per_Radian, 0.0f, 0.0f);

		//deathTimer = 100.0f;

		executionState->RequestState(ExecutionStateEngine::WatchingDeathState);
		ShowZoomIfOn(false);
		ShowStatic(false);

		if(MWGUIManager::GetInstance())
		{
			MWGUIManager::GetInstance()->Hide();
			if(MWApplication::GetInstance()->networkingFlag)
			{
				HUDChat *chat;
				chat = Cast_Object (HUDChat *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT));
				chat->Show ();
			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void
	VehicleInterface::BRBModeSimulation(Time till)
{

	const GameModel *model = GetGameModel();
	Check_Object(model);

	Scalar time_slice = GetTimeSlice(till);

	if (forwardCommand > 0)
	{
		cameraOffset.z += (model->translationPerSecond.z * time_slice);
	}
	if (backwardCommand > 0)	
	{
		cameraOffset.z -= (model->translationPerSecond.z * time_slice);
	}
	if (cameraYawLeft > 0)
	{
		cameraRotation.yaw += (model->rotationPerSecond * time_slice);
	}
	if (cameraYawRight > 0)
	{
		cameraRotation.yaw -= (model->rotationPerSecond * time_slice);
	}
	if (cameraPanUp > 0)
	{
		cameraOffset.y += (model->translationPerSecond.y * time_slice);
	}
	if (cameraPanDown > 0)
	{
		cameraOffset.y -= (model->translationPerSecond.y * time_slice);
	}
	if (cameraPanRight > 0)
	{
		cameraOffset.x -= (model->translationPerSecond.x * time_slice);
	}
	if (cameraPanLeft > 0)
	{
		cameraOffset.x += (model->translationPerSecond.x * time_slice);
	}
	if (cameraPitchUp > 0)
	{
		cameraRotation.pitch += (model->rotationPerSecond * time_slice);
	}
	if (cameraPitchDown > 0)
	{
		cameraRotation.pitch -= (model->rotationPerSecond * time_slice);
	}
	if (cameraZoomIn > 0)
	{
		cameraOffset.z += (model->translationPerSecond.z * time_slice);
	}
	if (cameraZoomOut > 0)
	{
		cameraOffset.z -= (model->translationPerSecond.z * time_slice);
	}
	if (originCommand > 0)
	{
		cameraOffset	= Point3D::Identity;
		cameraRotation	= YawPitchRoll::Identity;
	}

}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//


void
	VehicleInterface::CameraSimulation(Time till)
{

	Scalar time_slice = GetTimeSlice(till);

	const GameModel *model = GetGameModel();
	Check_Object(model);

	
	if (cameraPanUp > 0)
	{
	  switch (cameraView)
    {
      case TopDownCameraView:
  			cameraOffset.z += ((model->translationPerSecond.z * time_slice) * cameraOffset.y*0.15f);
      break;

      case ExternalCameraTargetReticule:
      {
  			cameraOffset.y += (model->translationPerSecond.y * time_slice)/2.0f;
        Max_Clamp(cameraOffset.y, 20.0f);
      }
      break;

      default:
  			cameraOffset.y += (model->translationPerSecond.y * time_slice);
      break;

    } // switch
	}
	if (cameraPanDown > 0)
	{
		switch (cameraView)
    {
		  case TopDownCameraView:
		  {
			  cameraOffset.z -= ((model->translationPerSecond.z * time_slice) * cameraOffset.y*0.15f);
		  }
      break;

      case ExternalCameraTargetReticule:
      {
			  cameraOffset.y -= (model->translationPerSecond.y * time_slice)/2.0f;
        Min_Clamp(cameraOffset.y, 2.0f);
      }
      break;

		  default:
			  cameraOffset.y -= (model->translationPerSecond.y * time_slice);
      break;

    } // switch
	}
	if (cameraYawLeft > 0)
	{
		switch (cameraView)
    {
      case ExternalCameraTargetReticule:
      {
			  cameraOffset.x -= ((model->translationPerSecond.x * time_slice) * cameraOffset.y*0.15f)/2.0f;	
        Min_Clamp(cameraOffset.x, -20.0f);
      }
      break;

      case TopDownCameraView:
		  {																																										
			  cameraOffset.x -= ((model->translationPerSecond.x * time_slice) * cameraOffset.y*0.15f);	
		  }
      break;

      case InMechCameraView:
		  {
			  cameraRotation.yaw += (model->rotationPerSecond * time_slice);
		  }
      break;

      case ExternalCameraDetachedView:
      default: // old code was wrong so this was always run. default is here for legacy expectations.
		  {
			  cameraRotation.yaw -= (model->rotationPerSecond * time_slice);
		  }
      break;


    }
	}
	if (cameraYawRight > 0)
	{
		switch (cameraView)
    {
      case ExternalCameraTargetReticule:
      {
			  cameraOffset.x += ((model->translationPerSecond.x * time_slice) * cameraOffset.y*0.15f)/2.0f;	
        Max_Clamp(cameraOffset.x, 20.0f);
      }
      break;

      case TopDownCameraView:
		  {
			  cameraOffset.x += ((model->translationPerSecond.x * time_slice) * cameraOffset.y*0.15f);
		  }
      break;


      case InMechCameraView:
		  {
			  cameraRotation.yaw -= (model->rotationPerSecond * time_slice);
		  }
      break;

      case ExternalCameraDetachedView:
      default: // old code was wrong so this was always run. default is here for legacy expectations.
		  {
			  cameraRotation.yaw += (model->rotationPerSecond * time_slice);
		  }
      break;

    }// switch		
  } // if cameraYawRight
	if (cameraZoomIn > 0)
	{
    switch (cameraView)
    {
		  case ExternalCameraDetachedView:
		  {
			  Point3D local_movement = Point3D::Identity;
			  local_movement.z += (model->translationPerSecond.z * time_slice);
			
			  LinearMatrix4D camera_local = LinearMatrix4D::Identity;
			  camera_local.BuildRotation(cameraRotation);


			  Point3D adjustment;
			  adjustment.Multiply(local_movement, camera_local);

			  cameraOffset += adjustment;
		  }
      break;

      case TopDownCameraView:
		  {
			  cameraOffset.y -= (model->translationPerSecond.y * time_slice);
		  }
      break;

      case ExternalCameraTargetReticule:
      {
			  cameraOffset.z -= (model->translationPerSecond.z * time_slice)/2.0f;
  		  Min_Clamp(cameraOffset.z, 2.0f); // what does this accomplish?
      }
      break;

      default:
		  {
			  cameraOffset.z += (model->translationPerSecond.z * time_slice);
			  Max_Clamp(cameraOffset.z, 150.0f);
      }
      break;
    }
  } // if cameraZoomIn
	if (cameraZoomOut > 0)
	{
    switch (cameraView)
    {
      case ExternalCameraDetachedView:
		  {
			  Point3D local_movement = Point3D::Identity;
			  local_movement.z -= (model->translationPerSecond.z * time_slice);
			
			  LinearMatrix4D camera_local = LinearMatrix4D::Identity;
			  camera_local.BuildRotation(cameraRotation);


			  Point3D adjustment;
			  adjustment.Multiply(local_movement, camera_local);


			  cameraOffset += adjustment;
		  }
      break;

		  case TopDownCameraView:
		  {
			  cameraOffset.y += (model->translationPerSecond.y * time_slice);
		  }
      break;

      case ExternalCameraTargetReticule:
      {
			  cameraOffset.z += (model->translationPerSecond.z * time_slice)/2.0f;
        Max_Clamp(cameraOffset.z, 40.0f);
      }
      break;

      default:
		  {
			  cameraOffset.z -= (model->translationPerSecond.z * time_slice);
			
		  }
      break;
    } // switch
  } // if cameraZoomOut


	if(IsObserving(true))
	{
        // jcem - start
        bool bAutoCamera = (0 < g_CamerashipParams.m_fDistStandard) ? true: false;
        if (bAutoCamera) {
            //g_CamerashipParams.m_fHeightStandard;
            //g_CamerashipParams.m_fDistStandard;
        } else {
        // jcem - end
		cameraRotation.yaw += model->rotationPerSecond * time_slice * controlPacket.vehicleYawDemand;
		cameraOffset.y += model->translationPerSecond.y * time_slice * controlPacket.torsoPitchDemand;
        if(fabs(controlPacket.vehicleSpeedDemand)>0.25f) {
			Stuff::Scalar speedDemand = controlPacket.vehicleSpeedDemand;
			if (reverseToggle)
			{
				speedDemand = -speedDemand;
			}

			cameraOffset.z -= model->translationPerSecond.z * time_slice * speedDemand;
		}
		
		Min_Clamp(cameraOffset.z, 10.0f);
		Max_Clamp(cameraOffset.z, 150.0f);
		Max_Clamp(cameraOffset.y, cameraOffset.z*2.0f);
        // jcem - start
        }
        // jcem - end
	}
	
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::QueCommand(int command)
{
	if (cinemaPlaying)
		return;

	if (observerMode)
		return;

	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	if (commandCount < 4)
	{
		++commandCount;
		gos_PushCurrentHeap(Heap);
		VehicleCommand *new_command = new VehicleCommand();
		new_command->m_Command = command;
		quedCommands.Add(new_command);
		gos_PopCurrentHeap();

		MWEntityManager* entity_manager = Cast_Object(MWEntityManager*,EntityManager::GetInstance());
		entity_manager->QueCommand(command);
	}

}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::ModifyControls(Time till)
{

  //
  // We only modify the torso comands since they are primarily for aiming, we don't want to
  // actually slow turns down, or other motions as it changes the way the mech responds.
  //
	const GameModel *model = GetGameModel();
	Check_Object(model);

  if (reticuleZoomShowing)
  {
    controlPacket.torsoYawDemand *= model->turnSpeedZoomModifierTorso;
    controlPacket.torsoPitchDemand *= model->turnSpeedZoomModifierPitch;
		// This will cause turning to slow down drastically if not left at 1.
    controlPacket.vehicleYawDemand *= model->turnSpeedZoomModifierYaw;
  }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::ApplyControls(Time till)
{
	
	
	if (cinemaPlaying)
		return;
	if (IsObserving(true))
		return;

	vehicle->pitchDemand  = 0.0;
	vehicle->rollDemand  = 0.0;

//	if (executionState->GetState() != ExecutionStateEngine::AutoPilotState)
	{
		if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::TURN) == true)
		{
			vehicle->yawDemand  = controlPacket.vehicleYawDemand;

			if (Stuff::Close_Enough(controlPacket.vehicleYawDemand,0.0f))
			{
				vehicle->yawDemand = 0.0f;
			}
		}

		if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::THROTTLE) == true)
		{
			vehicle->speedDemand = controlPacket.vehicleSpeedDemand;
			if (reverseToggle)
			{
				vehicle->speedDemand = -vehicle->speedDemand;
			}
			if (vehicle->speedDemand != 0)
			{
				if (vehicle->speedDemand > 0)
					Min_Clamp (vehicle->speedDemand,(minForwardNormal+0.02f));
				else
					Max_Clamp (vehicle->speedDemand,(minReverseNormal-0.02f));
			}

			//SPEW(("jerryeds", "sd:%f", vehicle->speedDemand));

			// could have been sampled bad
			if (Stuff::Close_Enough(controlPacket.vehicleSpeedDemand,0.0f))
			{
				vehicle->speedDemand = 0.0f;
			}
		}		
	}



	
	Torso *torso;
	torso = vehicle->GetTorso();
	int oldTorsoDirection = 0;
	if(torso)
	{
		oldTorsoDirection = torso->GetLookDirection();
		if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::TORSO) == true)
		{
			torso->pitchDemand = controlPacket.torsoPitchDemand;
			if (controlPacket.torsoYawDemand != 0)
				ReactToEvent (TORSO_TWIST);
			torso->yawDemand = controlPacket.torsoYawDemand;
			if (Stuff::Close_Enough(controlPacket.torsoPitchDemand,0.0f))
			{
				torso->pitchDemand = 0.0f;
			}
			if (Stuff::Close_Enough(controlPacket.torsoYawDemand,0.0f))
			{
				torso->yawDemand = 0.0f;
			}
		}

		//SPEWALWAYS((0,"CONTROL X:%f Y:%f Z:%f", vehicle->yawDemand, torso->pitchDemand, torso->yawDemand));
	
		if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::VIEW_MODES) == true)
		{
			if (cameraView == InMechCameraView)
				torso->SetInternal();
			else
				torso->SetExternal();
		}

		if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == true)
		{
			if (controlPacket.lookCommand == AnalogControlSave::LookRight)
			{
				ShowHUDIfOn(true);
				ShowStatic(false);
				ShowZoomIfOn(true);
				torso->LookRight();
			}
			else if (controlPacket.lookCommand == AnalogControlSave::LookLeft)
			{
				ShowHUDIfOn(true);
				ShowStatic(false);
				ShowZoomIfOn(true);
				torso->LookLeft();
			}
			else if (controlPacket.lookCommand == AnalogControlSave::LookBack)
			{
				//sanghoon
				ShowHUDIfOn(true);
				//MWGUIManager::GetInstance()->HideHudComponent (HUD_TARGETARROW);
				//ShowHUDIfOn(false);
				//sanghoon
// MSL 5.04 Rear Firing Weapons
//				ShowStatic(cameraView == InMechCameraView);
				ShowStatic(true);
				ShowZoomIfOn(false);
				torso->LookBack();
			}
			else if (controlPacket.lookCommand == AnalogControlSave::LookDown)
			{
				ShowHUDIfOn(true);
				ShowStatic(cameraView == InMechCameraView);
				ShowZoomIfOn(false);
				torso->LookDown();
			}
			else
			{
				ShowHUDIfOn(true);
				ShowStatic(false);
				ShowZoomIfOn(true);
				torso->LookForward();
			}
			if (oldTorsoDirection != torso->GetLookDirection())
			{
				preventFireThisFrame = true;
			}
		}
	}

	if ((cameraView==InMechCameraView) &&	(!torso || (oldTorsoDirection != torso->GetLookDirection())) &&
		(InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == true))
	{
		if(controlPacket.lookCommand == AnalogControlSave::LookDown)
		{
			 vehicle->ToggleLightsOff(false);
			 //
			 //	Changed to remove odd artifacts of clipping the mech from this angle
			 //
			 vehicle->SetNoneRepresentation();
//			 vehicle->SetExternalRepresentation();
			 vehicle->ExecuteChildComponentWebs();
		}
		else if (controlPacket.lookCommand == AnalogControlSave::LookRight)
		{
			 vehicle->ToggleLightsOff(false);
			MString mech_name = vehicle->GetGameModelResourceName();
			mech_name.StripDirectory();
			mech_name.StripExtension();
// MSL 5.05 Hollander Cockpit Art Fix
			if (mech_name == "hollander")
			{
				vehicle->SetInternalRepresentation();
				vehicle->ExecuteChildComponentWebs();
			}
			else
			{
				vehicle->SetBothRepresentation();
				vehicle->ExecuteChildComponentWebs();
			}

		}
		else if (controlPacket.lookCommand == AnalogControlSave::LookLeft)
		{
			 vehicle->ToggleLightsOff(false);
			 vehicle->SetBothRepresentation();
			 vehicle->ExecuteChildComponentWebs();
		}
		else if (controlPacket.lookCommand == AnalogControlSave::LookBack)
		{
			 vehicle->ToggleLightsOff(true);
			 vehicle->SetNoneRepresentation();
			 vehicle->ExecuteChildComponentWebs();
		}
		else
		{
			 vehicle->ToggleLightsOff(false);
			 vehicle->SetInternalRepresentation();
			 vehicle->ExecuteChildComponentWebs();
		}
	}

	ChainIteratorOf<VehicleCommand*> command_iterator(&quedCommands);
	VehicleCommand *command = command_iterator.GetCurrent();

	if (command != NULL)
	{
		commandCount--;
		vehicle->ProcessCommand(command->m_Command);
		command_iterator.Remove();
		delete command;
	}
	


}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Scalar VehicleInterface::UseJoystickThrottle (Scalar value)
{
	if (value < (m_joystick_throttle_center-m_joystick_throttle_dead_low))
	{
		value = NormalizedValue (value,0,m_joystick_throttle_center-m_joystick_throttle_dead_low);
		value -= 1.0f;
	}
	else if (value > (m_joystick_throttle_center+m_joystick_throttle_dead_high))
	{
		value = NormalizedValue (value,m_joystick_throttle_center+m_joystick_throttle_dead_high,1);
	}
	else
	{
		value = 0;
	}
	return value;
}

bool VehicleInterface::ThrottleMoved (Scalar newvalue)
{
	Scalar dx;
	dx = newvalue - lastJoystickTrottle;
	return ((dx<-0.005f) || (dx>0.005f));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ReadJoystick (Time till)
{
//	if (m_MouseEnable)
//		return;

	if(joystickThrottle >= 0.0f)
	{
		if(ThrottleMoved (joystickThrottle))
		{
			if (lastJoystickTrottle == -1)
			{
				lastJoystickTrottle = joystickThrottle;
			}
			else
			{
			
				controlPacket.vehicleSpeedDemand = UseJoystickThrottle (joystickThrottle);
				Clamp(controlPacket.vehicleSpeedDemand, -1.0f, 1.0f);
/*
				if (controlPacket.vehicleSpeedDemand < 0)
					reverseToggle = true;
				else
					reverseToggle = false;
*/					
				lastJoystickTrottle = joystickThrottle;
			}
		}
	}

	//This is to raise the dead zone for rudder if we are turning

	Scalar rudder_scalar = 0.0f;

	Scalar yawaxis=0,rudderaxis = 0;

	if (m_JoystickXAxisType == CControlMappingList::TURNING_AXIS)
		yawaxis += joystickXAxis;
	else if (m_JoystickXAxisType == CControlMappingList::TORSO_AXIS)
		rudderaxis += joystickXAxis;
	if (m_JoystickRudderAxisType == CControlMappingList::TURNING_AXIS)
		yawaxis += joystickRudder;
	else if (m_JoystickRudderAxisType == CControlMappingList::TORSO_AXIS)
		rudderaxis += joystickRudder;

	if((yawaxis) && (!vehicle->vehicleShutDown) && (!vehicle->IsCrouched()))
	{
		controlPacket.vehicleYawDemand = -yawaxis;
		Clamp(controlPacket.vehicleYawDemand, -1.0f, 1.0f);
		if(Fabs(controlPacket.vehicleYawDemand) > 0.5f)
		{
			rudder_scalar = 0.1f;
		}
	}
	if((Fabs(rudderaxis) > rudder_scalar) && (!vehicle->vehicleShutDown))
		controlPacket.torsoYawDemand = -rudderaxis;
	else
		controlPacket.torsoYawDemand = 0.0f;

	if(!vehicle->vehicleShutDown)
		controlPacket.torsoPitchDemand = -joystickYAxis;

	if (joystickHat != lastJoystickHat)
	{
		if (joystickHat == -1.0f)
			lookLeft = lookRight = lookBack = lookDown = 0;
		else if ((joystickHat > 0.875f) || (joystickHat < 0.125f))
			lookDown++;
		else if ((joystickHat>= 0.125f) && (joystickHat <= 0.375f))
			lookRight++;
		else if ((joystickHat> 0.375f) && (joystickHat < 0.625f))
			lookBack++;
		else if ((joystickHat>= 0.625f) && (joystickHat <= 0.875f))
			lookLeft++;
		else
			lookLeft = lookRight = lookBack = lookDown = 0;
		if (lastJoystickHat == -1.0f)
		{
		}
		else if ((lastJoystickHat > 0.875f) || (lastJoystickHat < 0.125f))
			lookDown--;
		else if ((lastJoystickHat>= 0.125f) && (lastJoystickHat <= 0.375f))
			lookRight--;
		else if ((lastJoystickHat> 0.375f) && (lastJoystickHat < 0.625f))
			lookBack--;
		else if ((lastJoystickHat>= 0.625f) && (lastJoystickHat <= 0.875f))
			lookLeft--;
		lastJoystickHat = joystickHat;
		Min_Clamp (lookLeft,0);
		Min_Clamp (lookRight,0);
		Min_Clamp (lookBack,0);
		Min_Clamp (lookDown,0);
	}



}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::LoadMouseYFlag (NotationFile *startup_ini)
{
	m_MouseYEnable = true;
	Page *page=startup_ini->FindPage("special commands");
	if (page)
	{
		Check_Object(page);
		page->GetEntry("mousey",&m_MouseYEnable,false);
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::LoadMouseMinMax (NotationFile *startup_ini)
{
	Page *page=startup_ini->FindPage("mouse");
	if (page)
	{
		Check_Object(page);
		page->GetEntry("minchange",&m_MouseMinChange,false);
		page->GetEntry("maxchange",&m_MouseMaxChange,false);
		Clamp(m_MouseMinChange, 0.0f, 0.05f);
		Clamp(m_MouseMaxChange, m_MouseMinChange, 1.0f);
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ReadMouse (Time till)
{
//	static bool mousePosReadToggle = false;

//	mousePosReadToggle = !mousePosReadToggle;
	if (fireBlocked)
	{
		return;
	}

	if (m_ChangeMouseTorsoThisFrame)
	{
		m_ChangeMouseTorsoThisFrame = false;
		controlPacket.vehicleYawDemand = 0;
		controlPacket.torsoYawDemand = 0;
		controlPacket.torsoPitchDemand = 0;
		mouseDeltaX = 0;
		mouseDeltaY = 0;
	}

//	if (mousePosReadToggle)
	{
		Scalar interia_mult = m_MouseSensitivity;			//MW4AI::UserConstants::Instance ()->Get(MW4AI::UserConstants::mouse_interia_mult);
		Scalar min_change = m_MouseMinChange;				//MW4AI::UserConstants::Instance ()->Get(MW4AI::UserConstants::mouse_min_change);
		Scalar max_mouse =	m_MouseMaxChange;				//MW4AI::UserConstants::Instance ()->Get(MW4AI::UserConstants::mouse_max_mouse);

		mousePosX -= 0.5f;			// to make -1.0 to 1.0, was 0-1
		mousePosX *= 2.0f;
		mousePosY -= 0.5f;		
		mousePosY *= 2.0f;
		Clamp (mousePosX,-1.0f,1.0f);
		Clamp (mousePosY,-1.0f,1.0f);

		mouseDeltaX *= interia_mult;
		mouseDeltaY *= interia_mult;
		if (!m_MouseEnable)																										
			return;
		Scalar yawaxis=0,rudderaxis = 0,pitchaxis=0;
//		if (mouseDeltaToggle)
		{
			Scalar sx,sy;
	//		Mech *mech;
	//		mech = Cast_Object (Mech *,vehicle);
	//		const Mech__GameModel *model = static_cast<const Mech__GameModel *> (mech->GetGameModel ()) ;

	//		Scalar max_step = Lerp(model->fullStopTurnRate, model->topSpeedTurnRate, mech->currentSpeedMPS/mech->GetMaxSpeed());
	//		Torso *torso;
	//		torso = mech->GetTorso ();
	//		const Torso__GameModel *torsomodel = static_cast<const Torso__GameModel *> (torso->GetGameModel ());
			curMouseX += mouseDeltaX;
			curMouseY += mouseDeltaY;
			Clamp (curMouseX,-1.0f,1.0f);
			Clamp (curMouseY,-1.0f,1.0f);
			Check_Object (ControlsManager::Instance);
			sx = curMouseX;
			sy = curMouseY;
			Scalar time_slice = GetTimeSlice(till);

			Clamp (sx,-max_mouse,max_mouse);
			Clamp (sy,-max_mouse,max_mouse);
			sx *= (time_slice*4.0f);
			sy *= (time_slice*4.0f);

			if (!m_MouseYEnable)
				curMouseY = 0;
			if (m_MouseXAxisType == CControlMappingList::TURNING_AXIS)
				yawaxis += curMouseX;
			else if (m_MouseXAxisType == CControlMappingList::TORSO_AXIS)
				rudderaxis += curMouseX;
			pitchaxis = curMouseY;

			if (curMouseX < 0)
			{
				Max_Clamp (sx,-min_change);
				curMouseX -= sx;
				Max_Clamp (curMouseX,0);
			}
			else
			{
				Min_Clamp (sx,min_change);
				curMouseX -= sx;
				Min_Clamp (curMouseX,0);
			}
			if (curMouseY < 0)
			{
				Max_Clamp (sy,-min_change);
				curMouseY -= sy;
				Max_Clamp (curMouseY,0);
			}
			else
			{
				Min_Clamp (sy,min_change);
				curMouseY -= sy;
				Min_Clamp (curMouseY,0);
			}
			ControlsManager::Instance->CenterMouse ();
		}

		if ((!mouseTorsoToggle) && (!vehicle->vehicleShutDown) && (!vehicle->IsCrouched()))
		{
			controlPacket.vehicleYawDemand += -rudderaxis;
			controlPacket.torsoYawDemand += -yawaxis;
			Clamp(controlPacket.vehicleYawDemand, -1.0f, 1.0f);
		}
		else if(!vehicle->vehicleShutDown)
		{
			controlPacket.vehicleYawDemand += -yawaxis;
			controlPacket.torsoYawDemand += -rudderaxis;
			Clamp(controlPacket.torsoYawDemand, -1.0f, 1.0f);
		}
		if (!vehicle->vehicleShutDown)
		{
			controlPacket.torsoPitchDemand += -pitchaxis;
			Clamp(controlPacket.torsoPitchDemand, -1.0f, 1.0f);
		}
	}

	if ((mouseWheel != 0) && (!vehicle->vehicleShutDown))
	{
		if (mouseWheel > 0)
		{
			controlPacket.vehicleSpeedDemand += 0.1f;
//			if (controlPacket.vehicleSpeedDemand > 0.0f && reverseToggle)
//				reverseToggle = false;
			Max_Clamp(controlPacket.vehicleSpeedDemand, 1.0f);
		}
		else
		{
			controlPacket.vehicleSpeedDemand -= 0.1f;
			
//			if (controlPacket.vehicleSpeedDemand < 0.0f && !reverseToggle)
//				reverseToggle = true;

			Min_Clamp(controlPacket.vehicleSpeedDemand, -1.0f);
		}
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::HandleKeyboard (Time till)
{
	Scalar time_slice = GetTimeSlice(till);;
	if ((rotateLeftCommand > 0) && (!vehicle->vehicleShutDown) && (!vehicle->IsCrouched()))
	{
		Clamp(rotateLeftTime, 0.2f, 1.0f);
		controlPacket.vehicleYawDemand = rotateLeftTime;
		rotateLeftTime += time_slice;
		rotateRightTime = 0.0f;
	}
	else
	{
		rotateLeftTime = 0.0f;

	}
	if ((rotateRightCommand > 0) && (!vehicle->vehicleShutDown) && (!vehicle->IsCrouched()))
	{
		Clamp(rotateRightTime, -1.0f, -0.2f);
		controlPacket.vehicleYawDemand = rotateRightTime;
		rotateRightTime -= time_slice;
		rotateLeftTime = 0.0f;
	}
	else
	{
		rotateRightTime = 0.0f;
	}
// If vehicle is crouched then It can't move forward or backwards...Thus no demand...
// MSL 5.00
  if (!vehicle->IsCrouched())
  {
	if (throttle0Percent > 0)
	{
 		controlPacket.vehicleSpeedDemand = 0.0f;
	}
	else if (throttle10Percent > 0)
	{
		controlPacket.vehicleSpeedDemand = 0.1f;
	}
	else if (throttle20Percent > 0)
	{
		controlPacket.vehicleSpeedDemand = 0.2f;
	}
	else if (throttle30Percent > 0)
	{
		controlPacket.vehicleSpeedDemand = 0.3f;
	}
	else if (throttle40Percent > 0)
	{
		controlPacket.vehicleSpeedDemand = 0.4f;
	}
	else if (throttle50Percent > 0)
	{
		controlPacket.vehicleSpeedDemand = 0.5f;
	}
	else if (throttle60Percent > 0)
	{
		controlPacket.vehicleSpeedDemand = 0.6f;
	}
	else if (throttle70Percent > 0)
	{
		controlPacket.vehicleSpeedDemand = 0.7f;
	}
	else if (throttle80Percent > 0)
	{
		controlPacket.vehicleSpeedDemand = 0.8f;
	}
	else if (throttle90Percent > 0)
	{
		controlPacket.vehicleSpeedDemand = 0.9f;
	}
	else if (throttle100Percent > 0)
	{
		controlPacket.vehicleSpeedDemand = 1.0f;
	}
  } else {
    controlPacket.vehicleSpeedDemand = 0.0f;
  }

	if (IsObserving(true)) {
		if (forwardCommand == 0 && m_LastForwardCommand > till) {
			controlPacket.vehicleSpeedDemand = 0;
			m_LastForwardCommand = till;
		}
		if (backwardCommand == 0 && m_LastBackwardCommand > till) {
			controlPacket.vehicleSpeedDemand = 0;
			m_LastBackwardCommand = till;
		}
		
		if (forwardCommand > 0) {
			Min_Clamp (m_LastForwardCommand,till-1.0);
			while (m_LastForwardCommand < till) {
				controlPacket.vehicleSpeedDemand = 0.5;
				m_LastForwardCommand += 0.5f;
			}
		}

		if (backwardCommand > 0) {
			Min_Clamp (m_LastBackwardCommand,till-1.0);
			while (m_LastBackwardCommand < till) {
				controlPacket.vehicleSpeedDemand = -0.5;
				m_LastBackwardCommand += 0.5f;
			}
		}
	}
	else {
		if (forwardCommand > 0)
		{
			Min_Clamp (m_LastForwardCommand,till-1.0);
			while (m_LastForwardCommand < till)
			{
				// 20 spots of demand 0-1.0f
				int trans=1;
				if (controlPacket.vehicleSpeedDemand==0)
					trans = 1;
				else if (controlPacket.vehicleSpeedDemand < 0)
					trans = 2;
				else
					trans = 3;
				switch (trans)
				{
				case 1:
					controlPacket.vehicleSpeedDemand = minForwardNormal+0.02f;
					break;
				case 2:
					controlPacket.vehicleSpeedDemand += 0.02f;
					if ((controlPacket.vehicleSpeedDemand>0) && (controlPacket.vehicleSpeedDemand < minForwardNormal))
						controlPacket.vehicleSpeedDemand = minForwardNormal+0.02f;
					else if (controlPacket.vehicleSpeedDemand > minReverseNormal)
						controlPacket.vehicleSpeedDemand = 0;
					break;
				case 3:
					controlPacket.vehicleSpeedDemand += 0.02f;		
					if ((controlPacket.vehicleSpeedDemand>0) && (controlPacket.vehicleSpeedDemand < minForwardNormal))
						controlPacket.vehicleSpeedDemand = minForwardNormal+0.02f;
					break;
				}
				//		if (controlPacket.vehicleSpeedDemand > 0.0f && reverseToggle)
				//			reverseToggle = false;
				Max_Clamp(controlPacket.vehicleSpeedDemand, 1.0f);
				//		forwardCommand = 0;
				m_LastForwardCommand += 0.05f;
			}
		}
		if (backwardCommand > 0)	
		{
			Min_Clamp (m_LastBackwardCommand,till-1.0);
			while (m_LastBackwardCommand < till)
			{
				int trans=1;
				if (controlPacket.vehicleSpeedDemand==0)
					trans = 1;
				else if (controlPacket.vehicleSpeedDemand < 0)
					trans = 2;
				else
					trans = 3;
				switch (trans)
				{
				case 1:
					controlPacket.vehicleSpeedDemand = minReverseNormal-0.02f;
					break;
				case 2:
					controlPacket.vehicleSpeedDemand -= 0.02f;
					if ((controlPacket.vehicleSpeedDemand<0) && (controlPacket.vehicleSpeedDemand > minReverseNormal))
						controlPacket.vehicleSpeedDemand = minReverseNormal-0.02f;
					break;
				case 3:
					controlPacket.vehicleSpeedDemand -= 0.02f;		
					if ((controlPacket.vehicleSpeedDemand<0) && (controlPacket.vehicleSpeedDemand > minReverseNormal))
						controlPacket.vehicleSpeedDemand = minReverseNormal-0.02f;
					else if (controlPacket.vehicleSpeedDemand < minForwardNormal)
						controlPacket.vehicleSpeedDemand = 0;
					break;
				}
				
				//		if (controlPacket.vehicleSpeedDemand < 0.0f && !reverseToggle)
				//			reverseToggle = true;
				
				Min_Clamp(controlPacket.vehicleSpeedDemand, -1.0f);
				//		backwardCommand = 0;
				m_LastBackwardCommand += 0.05f;
			}
		}
	}
/*
	if (reverseToggle)
	{
		if (controlPacket.vehicleSpeedDemand > 0.0f)
			controlPacket.vehicleSpeedDemand = -controlPacket.vehicleSpeedDemand;
		Verify(controlPacket.vehicleSpeedDemand <= 0.0f);
	}

	else
	{
		if (controlPacket.vehicleSpeedDemand < 0.0f)
			controlPacket.vehicleSpeedDemand = -controlPacket.vehicleSpeedDemand;
	}
*/	

	
	//If the Vehicle has a torso...then tell is to rotate or pitch!!!
	if((torsoTwistRight > 0) || (torsoTwistLeft > 0) || (pitchUp > 0) || (pitchDown > 0))
	{

		if((torsoTwistRight > 0)  && (!vehicle->vehicleShutDown))
		{
			Clamp(twistRightTime, -1.0f, -0.2f);
			controlPacket.torsoYawDemand = twistRightTime;
			twistRightTime -= time_slice;
			twistLeftTime = 0.0f;
		}
		else
		{
			twistRightTime = 0.0f;
		}
		if((torsoTwistLeft > 0)  && (!vehicle->vehicleShutDown))
		{
			Clamp(twistLeftTime, 0.2f, 1.0f);
			controlPacket.torsoYawDemand = twistLeftTime;
			twistLeftTime += time_slice;
			twistRightTime = 0.0f;
		}
		else
		{
			twistLeftTime = 0.0f;
		}
		if((pitchUp > 0) && (!vehicle->vehicleShutDown))
		{
			Clamp(pitchUpTime, 0.2f, 1.0f);
			controlPacket.torsoPitchDemand = pitchUpTime;
			pitchUpTime += time_slice;
			pitchDownTime = 0.0f;
		}
		else
		{
			pitchUpTime = 0.0f;
		}
		if((pitchDown > 0) && (!vehicle->vehicleShutDown))
		{
			Clamp(pitchDownTime, -1.0f, -0.2f);
			controlPacket.torsoPitchDemand = pitchDownTime;
			pitchDownTime -= time_slice;
			pitchUpTime = 0.0f;
		}
		else
		{
			pitchDownTime = 0.0f;
		}
	
	}
	else
	{
		twistRightTime = 0.0f;
		twistLeftTime = 0.0f;
		pitchDownTime = 0.0f;
		pitchUpTime = 0.0f;
	}

	if (lookLeft > 0)
	{
		controlPacket.lookCommand = AnalogControlSave::LookLeft;
	}
	else if (lookRight > 0)
	{
		controlPacket.lookCommand = AnalogControlSave::LookRight;
	}
	else if (lookBack > 0)
	{
		controlPacket.lookCommand = AnalogControlSave::LookBack;
	}
	else if (lookDown > 0)
	{
		controlPacket.lookCommand = AnalogControlSave::LookDown;
	}
	else
	{
		controlPacket.lookCommand = AnalogControlSave::LookForward;
	}


	lastSpeedDemand = controlPacket.vehicleSpeedDemand;

	if (spinTorsoPitchTimer > 0.0f)
	{
		controlPacket.torsoPitchDemand += spinTorsoPitchMagnitude;
		Clamp(controlPacket.torsoPitchDemand, -1.0f, 1.0f);
	}

	if (spinTorsoYawTimer > 0.0f)
	{
		controlPacket.torsoYawDemand += spinTorsoYawMagnitude;
		Clamp(controlPacket.torsoYawDemand, -1.0f, 1.0f);
	}

	if (spinMechYawTimer > 0.0f)
	{
		controlPacket.vehicleYawDemand += spinMechYawMagnitude;
		Clamp(controlPacket.vehicleYawDemand, -1.0f, 1.0f);
	}


	torsoAtRestTimer += time_slice;
	
	if (controlPacket.torsoYawDemand > 0.1f || controlPacket.torsoYawDemand < -0.1f)
	{
		torsoAtRestTimer = 0.0f;
		if (!m_TorsoSpaceBarDown)
		{
			temporaryTorsoMode = LeaveTorsoAlone;
		}
	}

	if (controlPacket.vehicleYawDemand > 0.1f || controlPacket.vehicleYawDemand < -0.1f)
	{
		if (temporaryTorsoMode == CenterLegsToTorso || perminateTorsoMode == CenterLegsToTorso)
		{
			torsoAtRestTimer = 0.0f;
			if (!m_TorsoSpaceBarDown)
			{
				temporaryTorsoMode = LeaveTorsoAlone;
			}
		}
	}

	const GameModel *model = GetGameModel();
	Check_Object(model);

	if (vehicle->GetTorso())
	{
		if (perminateTorsoMode == CenterTorsoToLegs || temporaryTorsoMode == CenterTorsoToLegs)
		{
			if ((torsoAtRestTimer > model->delayTorsoCenter &&
				vehicle->currentSpeedKPH < m_maxSpeedTorsoCenterKPH)
				|| temporaryTorsoMode == CenterTorsoToLegs)
			{
				if (!Small_Enough(vehicle->GetTorso()->yawValue, Radians_Per_Degree * 2.0f))
				{	
					Scalar speed_demand;
//					speed_demand = -vehicle->GetTorso()->yawValue / (vehicle->GetTorso()->GetTwistSpeed() * model->turnSpeedZoomModifierTorso);
// MSL 5.00
					speed_demand = -(vehicle->GetTorso()->GetTwistSpeed() * model->turnSpeedZoomModifierTorso);
					speed_demand = Abs(speed_demand);

					Max_Clamp(speed_demand, 1.0f);

					if(vehicle->GetTorso()->yawValue > 0.0f)
					{
						controlPacket.torsoYawDemand = -speed_demand;
					}
					if(vehicle->GetTorso()->yawValue < 0.0f)
					{
						controlPacket.torsoYawDemand = speed_demand;
					}
				}
				else
				{
					temporaryTorsoMode = LeaveTorsoAlone;
				}
			}
			else
			{
				temporaryTorsoMode = LeaveTorsoAlone;
			}
		}
		else if (perminateTorsoMode == CenterLegsToTorso || temporaryTorsoMode == CenterLegsToTorso)
		{			
			if (
				(torsoAtRestTimer > model->delayTorsoCenter /*&&
				vehicle->currentSpeedKPH < m_maxSpeedTorsoCenterKPH*/)
				|| temporaryTorsoMode == CenterLegsToTorso)				
			{
				if (!Small_Enough(vehicle->GetTorso()->yawValue, Radians_Per_Degree * 2.0f))
				{	
					Stuff::Scalar revisedTwistSpeed = vehicle->GetTorso()->GetTwistSpeed();
				  if (reticuleZoomShowing)
					{
						revisedTwistSpeed *= model->turnSpeedZoomModifierTorso;
					}
					Stuff::Scalar revisedTurnSpeed = vehicle->GetTurnSpeed();
				  if (reticuleZoomShowing)
					{
						revisedTurnSpeed *= model->turnSpeedZoomModifierYaw;
					}
					if (revisedTwistSpeed > revisedTurnSpeed)
					{
						Scalar ratio =  revisedTurnSpeed / revisedTwistSpeed;

						Scalar speed_demand;
//						speed_demand = -vehicle->GetTorso()->yawValue / revisedTwistSpeed;
// MSL 5.00
						speed_demand = -revisedTwistSpeed;
						speed_demand = Abs(speed_demand);

						Max_Clamp(speed_demand, 1.0f);

						Verify(ratio < 1.0f);

						if(vehicle->GetTorso()->yawValue > 0.0f)
						{
							controlPacket.torsoYawDemand = -speed_demand * ratio;
							controlPacket.vehicleYawDemand = speed_demand;
						}
						if(vehicle->GetTorso()->yawValue < 0.0f)
						{
							controlPacket.torsoYawDemand = speed_demand * ratio;
							controlPacket.vehicleYawDemand = -speed_demand;
						}

					}
					else
					{

						Scalar ratio = revisedTwistSpeed / revisedTurnSpeed;

						Scalar speed_demand;
//						speed_demand = -vehicle->GetTorso()->yawValue / revisedTurnSpeed;
// MSL 5.00
						speed_demand = -revisedTurnSpeed;
						speed_demand = Abs(speed_demand);

						Max_Clamp(speed_demand, 1.0f);

						Verify(ratio <= 1.0f);

						if(vehicle->GetTorso()->yawValue > 0.0f)
						{
							controlPacket.torsoYawDemand = -speed_demand;
							controlPacket.vehicleYawDemand = speed_demand * ratio;
						}
						if(vehicle->GetTorso()->yawValue < 0.0f)
						{
							controlPacket.torsoYawDemand = speed_demand;
							controlPacket.vehicleYawDemand = -speed_demand * ratio;
						}
					}
				}
				else
				{
					temporaryTorsoMode = LeaveTorsoAlone;
				}
			}			
			else
			{
				temporaryTorsoMode = LeaveTorsoAlone;
			}			
		}
		else
		{
			temporaryTorsoMode = LeaveTorsoAlone;
		}
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::ReadControls(Time till)
{

	if (MWApplication::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState)
	{
		controlPacket.vehicleYawDemand = 0.0f;
	
		controlPacket.vehicleSpeedDemand = lastSpeedDemand;

		ReadJoystick (till);
		ReadMouse (till);
		HandleKeyboard (till);
		ModifyControls(till); // any tweaks that need doing to the controls can go here
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

#if 0
void VehicleInterface::CheckEndAutoPilot(Time till)
{
	ReadControls (till);

	Check_Object (m_PlayerAI);
	Verify (executionState->GetState () == ExecutionStateEngine::AutoPilotState);
	m_PlayerAI->ChangeAutoPilotSpeed (controlPacket.vehicleSpeedDemand);

	if (controlPacket.vehicleYawDemand)
	{
		executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);		
	}
#if 0
	if (controlPacket.torsoPitchDemand)
	{
		executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);		
		ApplyControls (till);
	}
	if (controlPacket.torsoYawDemand)
	{
		executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);		
		ApplyControls (till);
	}
#endif
	ApplyControls (till);
}
#endif

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::CheckEndFieldBase(Time till)
{
	ReadControls (till);

	Check_Object (m_PlayerAI);

	ChainIteratorOf<VehicleCommand*> command_iterator(&quedCommands);
	VehicleCommand *command = command_iterator.GetCurrent();

	if (command != NULL)
	{
		commandCount--;
		if (command->m_Command == VehicleCommand::PowerDownCommand)
		{
			vehicle->ProcessCommand(command->m_Command);
		}
		command_iterator.Remove();
		delete command;
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::PostCollisionExecute(Time till)
{
	Check_Object(this);	
	POSTCOLLISION_LOGIC("VehicleInterface");

	weaponCommandReady = false;
	weaponCommand.weaponFired = 0;
	weaponCommand.target.Remove();
	weaponCommand.originator.Remove();
	weaponCommand.targetOffset = Point3D::Identity;


	lockedWeaponCommandReady = false;
	lockedWeaponCommand.weaponFired = 0;
	lockedWeaponCommand.target.Remove();
	lockedWeaponCommand.originator.Remove();
	lockedWeaponCommand.targetOffset = Point3D::Identity;


	if (executionState->GetState() == ExecutionStateEngine::WatchingDeathState)
	{
		//watch the death from external view
		NetMissionParameters::MWNetMissionParameters *params;
		if (MWApplication::GetInstance()->serverFlag)
			params = MWApplication::GetInstance()->GetLocalNetParams();
		else
			params = MWApplication::GetInstance()->GetServerNetParams();

		const GameModel *model = GetGameModel();
		Check_Object(model);

		if (vehicle->IsDestroyed())
		{
			if (deathTimer >= model->deathTimer)
			{

				if (Application::GetInstance()->IsCampCOOP())
				{
				}
				else
				// if we are networking...
				if (Application::GetInstance()->networkingFlag)
				{
					// if force respawn is on..
					if (params->m_forceRespawn)
					{
						// if there are lives left...
						if (!(params->m_respawnLimit && vehicle->respawnCount >= params->m_respawnLimitNumber))
						{
							//send the request respawn command to the server
							MWApplication::GetInstance()->QueRespawnPlayer();
							const GameModel *model = GetGameModel();
							Check_Object(model);
							deathTimer = model->deathTimer * 0.5f;
						}
						else
						{
							MWApplication::GetInstance()->SwitchToCameraMessage(Connection::Local->GetID() , NULL);
						}
					} // else if the player is requesting a respawn
					else if (RequestingToFire())
					{
						// if there are lives left...
						if (!(params->m_respawnLimit && vehicle->respawnCount >= params->m_respawnLimitNumber))
						{
							MWApplication::GetInstance()->QueRespawnPlayer();
							const GameModel *model = GetGameModel();
							Check_Object(model);
							deathTimer = model->deathTimer * 0.5f;
						}
						else
						{
							MWApplication::GetInstance()->SwitchToCameraMessage(Connection::Local->GetID() , NULL);
						}
					}
					
				}
				else if (MWApplication::GetInstance()->m_iaGameType == MWApplication::WaveBattleGameType)
				{
					// if there are lives left...
					if(params->m_respawnLimit)
					{
						if (vehicle->respawnCount < params->m_respawnLimitNumber)
						{
							//send the request respawn command to the server
							MWApplication::GetInstance()->QueRespawnPlayer();
							const GameModel *model = GetGameModel();
							Check_Object(model);
							deathTimer = model->deathTimer * 0.5f;
							
						}
						else
						{
							MWApplication::GetInstance()->m_currentMissionStatus = 0;
							MWApplication::GetInstance()->QueStopGame();
						}
					}
					else
					{
						MWApplication::GetInstance()->QueRespawnPlayer();
						const GameModel *model = GetGameModel();
						Check_Object(model);
						deathTimer = model->deathTimer * 0.5f;
					}
				
				}
				else if (Adept::Mission::GetInstance()->AllowRespawn())
				{
					// unlimited respawn
					MWApplication::GetInstance()->QueRespawnPlayer();
				}
				else
				{
					MWMission* mission = Cast_Object(MWMission*,MWMission::GetInstance());

					if ((mission == 0) ||
						(mission->EndMissionTimerRunning() == false))
					{
						// no respawn
						MWApplication::GetInstance()->QueStopGame();
					}
				}
				if (m_interfaceTarget.GetCurrent ())
				{
					if (ShowTargetCamera ())
						m_targetCamera->SetScene(m_interfaceTarget.GetCurrent ()->GetElement());
					else
						m_targetCamera->SetScene (NULL);
				}
			}
		}
        else {
        }
	}
	

	if (m_FrameCount != 0)
	{
		if (preventFireThisFrame)			 // sometimes necessary during camera switches to prevent illegal firing
		{
			preventFireThisFrame = false;
		}
		else
		{
			if ((RequestingToFire()) &&
				((executionState->GetState() == ExecutionStateEngine::AlwaysExecuteState)
	//			|| (executionState->GetState() == ExecutionStateEngine::AutoPilotState)
				) && !vehicle->IsDestroyed() &&
				!vehicle->vehicleShutDown&&
				!IsObserving(true))
			{
				FireWeapon(till);
				if(needFireRequestReset)
				{
					fireRequest = 0;
					needFireRequestReset = false;
				}
			}
		}

	

	}

	if (IsObserving(true))
	{
		if (RequestingToFire())
		{
			//find a new vehicle..
            bool bLockCurrentHeroOld = g_bLockCurrentHero;
            g_bLockCurrentHero = false;
			FindNextMechToFollow();
            g_bLockCurrentHero = bLockCurrentHeroOld;

			fireRequest = 0;

		}

		if (observingEntity.GetCurrent() == NULL)
		{
			FindNextMechToFollow();
		}

	}

	if (brbMode)
	{
		UpdateBRBView();
	}
	else
	{
		UpdateViews();
	}

	UpdateTargetReticule(till);




	//
	//---------------------------------
	//Cast the interface collision line
	//---------------------------------
	//
	Check_Object(EntityManager::GetInstance());
	if(!EntityManager::GetInstance()->IsExecutionSuspended() && EntityManager::GetInstance()->PlayerReady())
		CastCollisionLine();

	if (MWGUIManager::GetInstance() && !IsObserving(true))
	{
		Check_Object(MWGUIManager::GetInstance());
		MWGUIManager::GetInstance()->SetSpeedBar(speedDemandKPH,minForwardKPH,minReverseKPH,maxForwardKPH,maxReverseKPH);
		SetTargetInfo();
		CalculateInterfaceTargetPosition();
		ExecuteNavSystem();
		UpdateTargetWindow();
		if (userRequestForreticuleZoomChange)
		{
			userRequestForreticuleZoomChange = false;

			if (requestedZoomChange)
			{
				//
				// Don't allow the user to turn on the zoom unless they are facing forward or to the side
				//
				if (!vehicle || !vehicle->GetTorso() ||
					(vehicle->GetTorso()->GetLookDirection() != Torso::LookBackDirection &&
					 vehicle->GetTorso()->GetLookDirection() != Torso::LookDownDirection))
				{
					ShowZoom ();
					if (!g_bJumpZoom)
						g_pRIOMain->SetLampState (16, LAMP_BRIGHT);
				}
			}
			else
			{
// MSL 5.02 Zoom
				HideZoom ();
				requestedZoomChange = false;
			    ReactToEvent (ZOOM_RETICAL_ENGAGED);
				if (!g_bJumpZoom)
				{
					g_pRIOMain->SetLampState (16, LAMP_DIM);
				}
			}
		}
//		UpdateReticuleWindow();
		//Dave Here
	}

	BaseClass::PostCollisionExecute(till);

	if(MWGUIManager::GetInstance())
	{
		Check_Object(MWGUIManager::GetInstance());

        if (!CTCL_IsConsoleX() && !g_CamerashipParams.m_bAllowChatDisplay) {
			HUDChat *chat;
			chat = Cast_Object (HUDChat *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT));
			if (chat)
				chat->Hide();
        }
        if (IsObserving(true) && (g_CamerashipParams.m_fTimeScoringInterval > 0)) { // vehicle && (vehicle->GetClassID() == ObservationVehicleClassID)
            Scalar fT = gos_GetElapsedTime();
            if ((fT - g_fLastScoringTimeCechk) >= CAMERASHIP_SCORING_CHECK) {
                g_fLastScoringTimeCechk = fT;
//sanghoon
			    if (Application::GetInstance()->networkingFlag)
			    {
                    bool bNearEnd = false;
		            MWMission* mission = Cast_Object(MWMission*,MWMission::GetInstance());
		            if (mission != 0)
		            {
				        if (mission->GetEndMissionTime() <= g_fTimeScoringAtEnd)
                            bNearEnd = true;
                    }
                    if (bNearEnd) {
                        if (!MWGUIManager::GetInstance()->IsDrawingScoring()) {
                            MWGUIManager::GetInstance()->ShowScoring();
                            g_fLastScoringTime = fT;
                        }
                    } else if (MWGUIManager::GetInstance()->IsDrawingScoring()) {
                        if ((fT - g_fLastScoringTime) >= g_CamerashipParams.m_fTimeScoringDuration) {
                            MWGUIManager::GetInstance()->HideScoring();
                            g_fLastScoringTime = fT;
                        }
                    } else {
                        if ((fT - g_fLastScoringTime) >= g_CamerashipParams.m_fTimeScoringInterval) {
				            MWGUIManager::GetInstance()->ShowScoring();
                            g_fLastScoringTime = fT;
                        }
                    }
			    }
		    }
        }
	}
    // jcem - end

	m_FrameCount++;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::FindNextMechToFollow(void)
{
	Mech *entity;

    Entity* p = observingEntity.GetCurrent();
    if (p)
	    entity = FindNextMechToFollowByScore(Cast_Object(Mech*, p));
    else
        entity = FindNextMechToFollowByScore(NULL);
    if (entity) {
        while(observingEntity.GetCurrent())
		    observingEntity.Remove();
		observingEntity.Add(entity);
        g_fLastCameraShipTime = gos_GetElapsedTime();
    }
}


void
	VehicleInterface::UpdateTargetReticuleCameraPosition(void)
{
    //
    // Here I am going to experiment with fixing the camera position, except to make sure that it isn't colliding with
    // with anything behind the mech. Then I'll rotate the camera based on torso yaw and pitch
    //
    // It doesn't precisely match up with the eyepoint, but we can still cause the mech to have all the normal torso
    // twist and pitch limitations.
    //
    // BUGBUG: Since the eyepoint and camera location don't precisely line up it does allow a little bit of
    //         error in the exact target range, but not enough that it should affect game play.
    //         Compensating for that error would require a little extra math per frame and is most likely
    //         not worth it at this point.
    //
    //

    // clear out the current camera roll and pitch that we don't want
		cameraRotation.pitch = 0.0f;
		cameraRotation.roll = 0.0f;


    //
    // Build a matrix that can generate camera to world based on torso and vehicle position and pitch(es)
    //
    Point3D tempPoint/*parentShoulderLocation_Local_To_Parent*/ = cameraOffset;
    tempPoint/*parentShoulderLocation_Local_To_Parent*/.z = externalCameraOffsetStartMinZ;

    //
    // To save space I'm going to reuse matrices, but I will use the comment after the name of the
    // variable to establish what is expected to be in the matrix at that time.
    //

    LinearMatrix4D tempMatrix/*vehicle_local_to_world*/ = LinearMatrix4D::Identity;
    YawPitchRoll tempypr/*Vehicle_Local_to_world*/;
    tempypr/*Vehicle_Local_to_world*/ = vehicle->GetLocalToWorld();


    // only take the vehicles yaw, to prevent us from falling, or pitching with the vehicle as a whole
    YawPitchRoll vehicle_local_to_world_ypr = YawPitchRoll::Identity;


	if (vehicle->GetClassID() == MechClassID)
	{
		Mech *mech = Cast_Object(Mech*, vehicle);
		vehicle_local_to_world_ypr = mech->GetEyePointManager()->m_springOffset;
		vehicle_local_to_world_ypr.yaw += tempypr/*Vehicle_Local_to_world*/.yaw;

	}
	else
	{
		vehicle_local_to_world_ypr.yaw = tempypr/*Vehicle_Local_to_world*/.yaw;
	}

	tempMatrix/*vehicle_local_to_world*/.BuildRotation(vehicle_local_to_world_ypr);

    LinearMatrix4D camera_local_to_torso = LinearMatrix4D::Identity;

    //
    // Default value for camera_local_to_torso, overridden if we are in fly mode
    //
    camera_local_to_torso.BuildTranslation(tempPoint/*parentShoulderLocation_Local_To_Parent*/);

    //
    // Adjust for any height changes due to the animation.
    // Only do it for the fly state. Otherwise it will wobble during most motion.
    //
    if (isAttachedVehicleAMech)
    {
      MechWarrior4::MWObject* mwobject = Cast_Object(MechWarrior4::MWObject*,vehicle);


	  if (mwobject->animStateEngine->IsTransitioning())
	  {
		  if (mwobject->animStateEngine->GetTransitionState() == MechAnimationStateEngine::FlyState)
		  {
			jumpHeightAdjustment.FadeToNewDampen(1.0f, 0.25f);
		  }
		  else if (mwobject->animStateEngine->GetState() == MechAnimationStateEngine::FlyState)
		  {
			jumpHeightAdjustment.FadeToNewDampen(0.0f, 0.25f);
		  }
	  }


		LinearMatrix4D jumpOffsetMatrix;

	    LinearMatrix4D tempJumpMatrix;
        tempJumpMatrix = camera_local_to_torso;

		jumpOffsetMatrix.BuildIdentity();
		Point3D non_jump = Point3D(0.0f,0.0f,0.0f);
		Point3D jump = Point3D(0.0f,5.0f,0.0f);
		Point3D lerped_pos = jumpHeightAdjustment.DampenValue(jump,non_jump);
		jumpOffsetMatrix.BuildTranslation(lerped_pos);
		
		camera_local_to_torso.Multiply(tempJumpMatrix, jumpOffsetMatrix);


    }

    //
    //  Done with tempPoint/*parentShoulderLocation_Local_To_Parent*/
    //
    //Point3D tempPoint/*Vehicle_Local_To_World*/;
    tempPoint/*Vehicle_Local_To_World*/ = vehicle->GetLocalToWorld();
    tempMatrix/*vehicle_local_to_world*/.BuildTranslation(tempPoint/*Vehicle_Local_To_World*/);
    LinearMatrix4D tempMatrix2/*torso_local_to_vehicle*/ = LinearMatrix4D::Identity;

    //
    // I'm no longer going to compensate for the target position with this, instead I'm going to follow the torso
    // turn itself, and rotate around the back of the mech. Then I'll move the mech eyepoint to match the camera
    // instead of the other way around.
    //
    // Get the current Pitch and Yaw from the torso
    MechWarrior4::Torso * torso = vehicle->GetTorso();
	  if(torso) // if not, then torso_local_to_vehicle is just "Identity"
	  {
      YawPitchRoll tempypr;
      tempypr.yaw = torso->yawValue;

      //
      // Need to compensate for leekLeft, lookRight
      //
    	tempypr.yaw += torso->eyeYaw;

      tempypr.pitch = torso->pitchValue + torso->eyePitch;
      tempypr.roll = 0.0f;
      tempMatrix2/*torso_local_to_vehicle*/.BuildRotation(tempypr);
    }

    LinearMatrix4D torso_local_to_world;

    torso_local_to_world.Multiply(tempMatrix2/*torso_local_to_vehicle*/, tempMatrix/*vehicle_local_to_world*/);
    //
    // Done with tempMatrix2/*torso_local_to_vehicle*/
    //

    LinearMatrix4D camera_local_to_world;
    camera_local_to_world.Multiply(camera_local_to_torso, torso_local_to_world);

    //
    // Now bring a line from the camera backwards and see if it hits anything. This prevents us from locking the
    // the view into a building or other mech behind this one. It could be disturbing and will provide a minor
    // shift in aim, so we don't want this happening all the time.
    //

    Stuff::Line3D cameraQueryLine;
    Stuff::Normal3D cameraQueryNormal;
    //
    // See if there is a clear line of sight from the position of the camera even with the mech in Z (relative to camera), and then
    // place the camera where it belongs.
    //
    //

    //
    //Point3D tempPoint/*cameraPosition*/;
    tempPoint/*cameraPosition*/ = (camera_local_to_world);
	  cameraQueryLine.SetOrigin(tempPoint/*cameraPosition*/);
    //
    // Done with tempPoint/*cameraPosition*/
    //

    //
    // Get the backward direction of the current camera.
    //
    UnitVector3D backwardLocalToWorld;
    camera_local_to_world.GetLocalBackwardInWorld(&backwardLocalToWorld);

	  cameraQueryLine.SetDirection(backwardLocalToWorld);
	  cameraQueryLine.m_length = cameraOffset.z - 2.0f; // starts at -2


		CollisionQuery cameraQuery(&cameraQueryLine, &cameraQueryNormal, CanBeShotFlag, this);
		if (vehicle)
		{
			cameraQuery.m_raySource = vehicle;
		}


		Adept::Entity *entity_hit;
		Check_Object(CollisionGrid::Instance);
		if (executionState->GetState() != ExecutionStateEngine::FieldBaseState)
		{
			entity_hit = CollisionGrid::Instance->ProjectLine(&cameraQuery); // we don't care if we hit anything we just want
																												 // the end of the line. Since the near clip is
																												 // 1.0 meter we have room to be partially in an object
																												 // and not have it affect the view.
	
			//
			// Verify that we aren't interpenetrating water (do we have to do this for fog as well?)
			//
			
			Stuff::Plane waterPlane(0.0f, 1.0f, 0.0f, Map::GetInstance()->GetGameModel()->m_waterLevel + 0.5f);
			Stuff::Scalar distanceToWater, dotProduct;
			distanceToWater = cameraQuery.m_line->GetDistanceTo(waterPlane, &dotProduct);
			if (distanceToWater >= - 4.0f && dotProduct < 0.0f && !Small_Enough(dotProduct))
			{
				Max_Clamp(cameraQuery.m_line->m_length, distanceToWater);
			}
	
			// Point3D tempPoint/*cameraLocation*/;
	
			//
			// Shorten the line just a little bit in case we did collide with something, or the camera is hovering too close
			// but didn't trigger collision. Otherwise the item we target could be behind the mech.
			//
			cameraQuery.m_line->m_length -= 0.25f;
		}

    cameraQuery.m_line->FindEnd(&tempPoint/*cameraLocation*/);
    //
    // Need slightly added distance to targetting based on how far behind the mech we are.
    // This will actually be slightly less distance than allowed by the 1st person view, but it should be so small
    // as to be unnoticed by the player.
    addedLengthToTarget = targetQuery.m_line->m_length;


    // LinearMatrix4D tempMatrix/*camera_local_to_parent*/;
		camera_local_to_world.BuildTranslation(tempPoint/*cameraLocation*/);
    //
    // Now we have the camera position calculated and we need to get the rotation.
    //

		Entity *parent = GetParentEntity();
		Check_Object(parent);
		// LinearMatrix4D tempMatrix2/*parent_local_to_world*/;
    tempMatrix2/*parent_local_to_world*/ = parent->GetLocalToWorld();
    tempMatrix/*camera_local_to_parent*/.Multiply(camera_local_to_world, tempMatrix2/*parent_local_to_world*/.Invert());

    SetNewLocalToParent(tempMatrix/*camera_local_to_parent*/);
		SyncMatrices(true);
		cameraDirty = true;

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::UpdateViews(void)
{
	Check_Object(this);
	Check_Object(vehicle);

	//
	//-----------------------------------------------------------------------
	// If we are in external mode, figure out where we want the camera in the
	// world
	//-----------------------------------------------------------------------
	//
	Stuff::Point3D Camera_Point_LTW;
	Camera_Point_LTW.x = 0.0f;
	Camera_Point_LTW.y = 1000.0f;
	Camera_Point_LTW.z = 0.0f		;


	CameraShip *camera = CameraShipManager::Instance->GetActiveCamera();

	if (camera != NULL)
	{
		Check_Object(camera);

		LinearMatrix4D camera_to_world = camera->GetLocalToWorld();
		Camera_Point_LTW = camera_to_world;
		Entity *parent = GetParentEntity();
		Check_Object(parent);
		LinearMatrix4D world_to_parent;
		world_to_parent.Invert(parent->GetLocalToWorld());
		LinearMatrix4D camera_to_parent;
		camera_to_parent.Multiply(camera_to_world, world_to_parent);
		SetNewLocalToParent(camera_to_parent);
		SyncMatrices(true);
		cameraDirty = true;


	}
	else if(cameraView == ExternalCameraAttachedView)
	{
	
		LinearMatrix4D camera_trans;
		LinearMatrix4D camera_rot;
		LinearMatrix4D camera_to_parent;

		camera_trans = cameraOffset;
		camera_rot = cameraRotation;
		camera_to_parent.Multiply(camera_trans,camera_rot);

		camera_to_parent.Normalize();

		SetNewLocalToParent(camera_to_parent);

		Entity *parent = GetParentEntity();
		Check_Object(parent);
		camera_trans.Multiply(camera_to_parent, parent->GetLocalToWorld());
		Camera_Point_LTW = camera_trans;

		SyncMatrices(true);
		cameraDirty = true;
	}
	else if (cameraView == ExternalCameraDetachedView)
	{
		LinearMatrix4D camera_to_world;
		camera_to_world.BuildTranslation(cameraOffset);
		camera_to_world.BuildRotation(cameraRotation);
		Camera_Point_LTW = camera_to_world;

		Entity *parent = GetParentEntity();
		Check_Object(parent);
		LinearMatrix4D world_to_parent;
		world_to_parent.Invert(parent->GetLocalToWorld());
		LinearMatrix4D camera_to_parent;
		camera_to_parent.Multiply(camera_to_world, world_to_parent);
		SetNewLocalToParent(camera_to_parent);
		SyncMatrices(true);
		cameraDirty = true;

	}
    else if (cameraView == ExternalCameraTargetReticule)
    {


        UpdateTargetReticuleCameraPosition();


		Stuff::LinearMatrix4D local_to_parent = this->entityElement->GetNewLocalToParent();
		Stuff::LinearMatrix4D local_to_world;
		Entity *parent = GetParentEntity();
		Check_Object(parent);
		local_to_world.Multiply(local_to_parent, parent->GetLocalToWorld());
		Camera_Point_LTW = local_to_world;

    }
	else if ((cameraView == ExternalCameraTerrainFollowView)/* || IsObserving(true)*/)
	{
        if (!observingEntity.GetCurrent()) {
            FindNextMechToFollow();
        }
		Entity *parent = observingEntity.GetCurrent(); // GetParentEntity();
        if ((0.0f < g_CamerashipParams.m_fDistStandard) && parent) {
		    Check_Object(parent);
            Mech* pMech = Cast_Object(Mech*, parent);
            Stuff::Scalar fTime;
            Mech* pMechEnemy;
		    LinearMatrix4D parent_local_to_world;
		    LinearMatrix4D interestObj_local_to_world;
            MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());
            Stuff::Scalar fMT = mission->GetMissionTime();
            float tempDist;

again:
		    parent_local_to_world = pMech->GetLocalToWorld();
            if ((m_curView == STATE_DEATH_SEQUENCE_START) || (m_curView == STATE_DEATH_SEQUENCE_TRANS)) {
                bool bStateEnded = false;
                if (m_pMechDying != pMech) {
                    // Case where target changes while dying
                    ClearFixedPoint();
                    m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeStandard;
                    m_pMechDying = m_pEnemy = NULL;
                    m_curView = STATE_STD_OBSERVERMODE;
                    m_curRange = NO_RANGE;
                    m_pLastParent = NULL;
                    ClearFixedPoint();
                    goto again;
                }
                if (!m_pMechDying->IsDestroyed()) {
                    if (m_curView == STATE_DEATH_SEQUENCE_START) {
                        // already respawned...
                        if (m_pEnemy == m_pMechDying) {
                            // self destruction...
                            m_pEnemy = FindNextMechToFollowByScore(m_pMechDying);
                            if (!m_pEnemy) {
                                m_pEnemy = m_pMechDying;
                            }
                            while(observingEntity.GetCurrent())
                                observingEntity.Remove();
					        observingEntity.Add(m_pEnemy);
                            pMech = m_pEnemy;
                            g_fLastCameraShipTime = gos_GetElapsedTime();
                            ClearFixedPoint();
                            m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeStandard;
                            m_pMechDying = m_pEnemy = NULL;
                            m_curView = STATE_STD_OBSERVERMODE;
                            m_curRange = NO_RANGE;
                            m_pLastParent = NULL;
                            ClearFixedPoint();
                            goto again;
                        } else {
                            // move to trans...
                            bStateEnded = true;
                        }
                    } else {
                    }
                }
                if ((m_pEnemy != m_pMechDying) && m_pEnemy->IsDestroyed()) {
                    if (m_curView == STATE_DEATH_SEQUENCE_START) {
                        // Case where opponent dies while death animation is playing...
                        // move to trans...
                        bStateEnded = true;
                    }
                }
                if (bStateEnded || (m_fTimeStateEnd <= fMT)) {
                    if (!g_bLockCurrentHero && (m_curView == STATE_DEATH_SEQUENCE_START) && ((m_pEnemy != m_pMechDying) && (g_CamerashipParams.m_bAllowBOTs || m_pEnemy->isPlayerVehicle))) {
                        m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeDeathTransition;
                        m_curView = STATE_DEATH_SEQUENCE_TRANS;
                        m_curRange = NO_RANGE;
                        m_pLastParent = NULL;

                        m_dyingLocalToWorld = m_pMechDying->GetLocalToWorld();
                        HeroDeathToEnemyTrans(m_dyingLocalToWorld, 0.0f);
                    } else {
                        if (m_curView == STATE_DEATH_SEQUENCE_START) {
                            // self destruction...
                            m_pEnemy = FindNextMechToFollowByScore(m_pMechDying);
                            if (!m_pEnemy) {
                                m_pEnemy = m_pMechDying;
                            }
                        }
                        while(observingEntity.GetCurrent())
                            observingEntity.Remove();
					    observingEntity.Add(m_pEnemy);
                        g_fLastCameraShipTime = gos_GetElapsedTime();
#if USE_DEATH_OVERSHOULD
                        m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeOverShoulder;
                        m_pMechDying = m_pEnemy = NULL;
                        m_curView = STATE_OVERSHOULDER_SHOT;
                        m_curRange = CLOSESHOT;
                        m_pLastParent = NULL;
#else // !USE_DEATH_OVERSHOULD
                        m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeStandard;
                        m_pMechDying = m_pEnemy = NULL;
                        m_curView = STATE_STD_OBSERVERMODE;
                        m_curRange = NO_RANGE;
                        m_pLastParent = NULL;
#endif // USE_DEATH_OVERSHOULD
                        ClearFixedPoint();
                        goto again;
                    }
                } else {
                    if (m_curView == STATE_DEATH_SEQUENCE_START) {
                        // do nothing...
                    } else {
#if USE_DEATH_OVERSHOULD
                        OverShoulderShot(m_pEnemy->GetLocalToWorld(), m_dyingLocalToWorld, NO_RANGE);
                        HeroDeathToEnemyTrans(m_dyingLocalToWorld, (g_CamerashipParams.m_fTimeDeathTransition - (m_fTimeStateEnd - fMT)) / g_CamerashipParams.m_fTimeDeathTransition, g_camToParent4Temp);
#else // !USE_DEATH_OVERSHOULD
                        Entity *parent;
                        bool bUseTORSO;

                        if (0.0f < g_CamerashipParams.m_fDistStandard) {
                            parent = m_pEnemy;
                            bUseTORSO = true;
                        } else {
                            parent = GetParentEntity();
                            bUseTORSO = false;
                        }
                        Point3D ptWorldPos;
                        LinearMatrix4D camToParent;
                        m_tempEnemyPos = parent->GetLocalToWorld();
	                    m_tempEnemyPos.y += g_CamerashipParams.m_fHeightStandardLookAt;

                        GetObserverPosition(parent, bUseTORSO, false, cameraOffset, cameraRotation, ptWorldPos, camToParent);
                        HeroDeathToEnemyTrans(m_dyingLocalToWorld, (g_CamerashipParams.m_fTimeDeathTransition - (m_fTimeStateEnd - fMT)) / g_CamerashipParams.m_fTimeDeathTransition, camToParent/*m_pEnemy->GetLocalToWorld()*/);
#endif // USE_DEATH_OVERSHOULD
                    }
                }
            } else if (pMech->IsDestroyed()) {
again3:
                pMechEnemy = pMech->m_Others[1].Get();
                m_curView = STATE_DEATH_SEQUENCE_START;
                m_curRange = NO_RANGE;
                m_pLastParent = NULL;
                if (pMechEnemy)
                    m_pEnemy = pMechEnemy; // self destruction or destroyed by...
                else
                    m_pEnemy = pMech; // self destruction...
                m_pMechDying = pMech;
                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeDeathWatching;
                ClearFixedPoint();
                m_dyingLocalToWorld = pMech->GetLocalToWorld();
                HeroDeathToEnemyStart(m_dyingLocalToWorld);
            } else {
                bool bAgain2 = false;
again2:
                pMechEnemy = pMech->m_Others[0].Get(fTime);
                if (!bAgain2 && ((m_fTimeStateEnd - 0.05) <= fMT) && (g_CamerashipParams.m_fTimeIdleChange <= fTime)) {
                    // too long idle times...
                    // switch to next mech...
                    Mech* pMechTemp = pMech;
                    Mech* pMechBest;
#if 1
                    pMechBest = FindNextMechToFollowByScore(pMechTemp);
#else
                    pMechBest = NULL;
                    Stuff::Scalar fTimeBest = 0.0f;
                    Mech* pMech1st = NULL;
                    int nErrorLoop = 0;
                    while((pMechTemp = FindNextMechToFollowByScore(pMechTemp)) != NULL) {
                        if ((pMechTemp == pMech) || (pMechTemp == pMech1st) || (++nErrorLoop >= 16))
                            break;
                        if (!pMech1st)
                            pMech1st = pMechTemp;

                        Stuff::Scalar fTime2;
                        pMechTemp->m_Others[0].Get(fTime2);
                        int nUpdate = 0;
                        if (!pMechBest) {
                            nUpdate = 1;
                        } else {
                            if (pMechBest->IsDestroyed()) {
                                if (!pMechTemp->IsDestroyed()) {
                                    nUpdate = 1;
                                }
                            } else {
                                if (!pMechTemp->IsDestroyed()) {
                                    if (fTime2 < g_CamerashipParams.m_fTimeIdleChange) {
                                        nUpdate = -1;
                                    } else {
                                        if (fTime2 < fTimeBest) {
                                            nUpdate = 1;
                                        }
                                    }
                                }
                            }
                        }
                        if (nUpdate) {
                            pMechBest = pMechTemp;
                            fTimeBest = fTime2;
                            if (nUpdate == -1)
                                break;
                        }
                    }
#endif
                    if (pMechBest) {
                        pMech = pMechBest;
                        pMechTemp = pMech->m_Others[0].Get(fTime);

                        pMech->m_Others[0].Clear();
                        if (pMechTemp)
                            pMech->m_Others[0].Set(pMechTemp);

                        while(observingEntity.GetCurrent())
                            observingEntity.Remove();
                        observingEntity.Add(pMech);
                        parent_local_to_world = pMech->GetLocalToWorld();
                        if (pMech->IsDestroyed()) {
                            goto again3;
                        }
                        bAgain2 = true;
                        goto again2;
                    }
                }

                if ((pMechEnemy != NULL) && !pMechEnemy->IsDestroyed()) {
                    m_pEnemy = pMechEnemy;
		            interestObj_local_to_world = pMechEnemy->GetLocalToWorld();

		            LinearMatrix4D camera_to_world;
		            LinearMatrix4D camera_to_parent;

		            // we use distance to help choose a camera
		            Point3D tempHero;
		            tempHero = parent_local_to_world;
		            Point3D tempEnemy;
		            tempEnemy = interestObj_local_to_world;

		            Vector3D tempVectToEnemy;
		            tempVectToEnemy.Subtract(tempEnemy, tempHero);

		            tempDist = tempVectToEnemy.GetLength();
                    if (bAgain2 || (m_fTimeStateEnd <= fMT)) {
                        if (tempDist <= g_CamerashipParams.m_fDistSideShot) {
                            if (rand() % 10 < 2) {
                                // 20 %
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeFixedTracking;
                                m_curView = STATE_FIXED_TRACKING_SHOT;
                                m_curRange = MEDIUMSHOT;
                                m_pLastParent = NULL;
                            } else {
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeSideShot;
                                m_curView = STATE_SIDE_SHOT;
                                m_curRange = NO_RANGE;
                                m_pLastParent = NULL;
                            }
                            ClearFixedPoint();
                        } else if (tempDist < 210.0f) {
			                if ((m_curView == STATE_OVERSHOULDER_SHOT) || ((m_curView != STATE_FRONT_SHOT) && ((rand() % 10) < 4)))
			                { // 40%
				                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeFrontShot;
				                m_curView = STATE_FRONT_SHOT;
                                m_curRange = CLOSESHOT;
                                m_pLastParent = NULL;
			                }
			                else
			                {
				                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeOverShoulder;
				                m_curView = STATE_OVERSHOULDER_SHOT;
                                m_curRange = MEDIUMSHOT;
                                m_pLastParent = NULL;
			                }
                            ClearFixedPoint();
                        } else if (tempDist < 290.0f) {
			                int cameraState, cameraDist;
                            do {
                                switch(rand() % 3) {
                                case 0:
                                    cameraState = STATE_FRONT_SHOT;
                                    break;
                                case 1:
                                    cameraState = STATE_OVERSHOULDER_SHOT;
                                    break;
                                default:
                                    cameraState = STATE_FIXED_TRACKING_SHOT;
                                    break;
                                }
                                switch(rand() % 3) {
                                case 0:
                                    cameraDist = CLOSESHOT;
                                    break;
                                case 1:
                                    cameraDist = MEDIUMSHOT;
                                    break;
                                default:
                                    cameraDist = LONGSHOT;
                                    break;
                                }
                            } while(((cameraState == m_curView) && (cameraDist == m_curRange)) || ((cameraState == STATE_OVERSHOULDER_SHOT) && (m_curView == STATE_OVERSHOULDER_SHOT)));
                            switch(cameraState) {
                            case STATE_FRONT_SHOT:
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeFrontShot;
                                break;
                            case STATE_OVERSHOULDER_SHOT:
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeOverShoulder;
                                break;
                            case STATE_FIXED_TRACKING_SHOT:
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeFixedTracking;
                                break;
                            default:
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeStandard;
                                break;
                            }
                            m_curView = cameraState;
                            //m_curRange = cameraDist;
                            if (cameraState == STATE_FRONT_SHOT) {
                                m_curRange = MEDIUMSHOT;
                            } else {
                                m_curRange = LONGSHOT;
                            }
                            m_pLastParent = NULL;
                            ClearFixedPoint();
                        } else {
			                int cameraState, cameraDist;
                            do {
                                switch(rand() % 3) {
                                case 0:
                                    cameraState = STATE_FRONT_SHOT;
                                    break;
                                case 1:
                                    cameraState = STATE_OVERSHOULDER_SHOT;
                                    break;
                                case 2:
                                    cameraState = STATE_FIXED_TRACKING_SHOT;
                                default:
                                    cameraState = STATE_STD_OBSERVERMODE;
                                    break;
                                }
                                if (cameraState == STATE_STD_OBSERVERMODE) {
                                    cameraDist = NO_RANGE;
                                } else {
                                    switch(rand() % 3) {
                                    case 0:
                                        cameraDist = CLOSESHOT;
                                        break;
                                    case 1:
                                        cameraDist = MEDIUMSHOT;
                                        break;
                                    default:
                                        cameraDist = LONGSHOT;
                                        break;
                                    }
                                }
                            } while(((cameraState == m_curView) && (cameraDist == m_curRange)) || ((cameraState == STATE_OVERSHOULDER_SHOT) && (m_curView == STATE_OVERSHOULDER_SHOT)));
                            switch(cameraState) {
                            case STATE_FRONT_SHOT:
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeFrontShot;
                                break;
                            case STATE_OVERSHOULDER_SHOT:
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeOverShoulder;
                                break;
                            case STATE_FIXED_TRACKING_SHOT:
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeFixedTracking;
                                break;
                            default:
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeStandard;
                                break;
                            }
                            m_curView = cameraState;
                            //m_curRange = cameraDist;
			                switch (cameraState)
			                {
			                case STATE_FIXED_TRACKING_SHOT:
				                m_curRange = LONGSHOT;
				                break;
			                
			                case STATE_FRONT_SHOT:
				                m_curRange = CLOSESHOT;
				                break;
			                
			                case STATE_OVERSHOULDER_SHOT:
				                m_curRange = CLOSESHOT;
				                break;
                            default: // case STATE_STD_OBSERVERMODE:
				                m_curRange = NO_RANGE;
				                break;
			                }
                            m_pLastParent = NULL;
                            ClearFixedPoint();
                        }
                    } else {
                        if (!m_pEnemy || m_pEnemy->IsDestroyed()) {
                            switch(m_curView) {
                            case STATE_SIDE_SHOT:
			                case STATE_FRONT_SHOT:	
			                case STATE_OVERSHOULDER_SHOT:
                                m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeStandard;
                                m_pMechDying = m_pEnemy = NULL;
                                m_curView = STATE_STD_OBSERVERMODE;
                                m_curRange = NO_RANGE;
                                m_pLastParent = NULL;
                                ClearFixedPoint();
                                break;
                            default:
                                // do nothing...
                                break;
                            }
                        }
                    }
                } else {
                    m_pMechDying = m_pEnemy = NULL;
                    if (m_fTimeStateEnd <= fMT) {
                        m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeStandard;
                    }
                    m_curView = STATE_STD_OBSERVERMODE;
                    m_curRange = NO_RANGE;
                    m_pLastParent = NULL;
                    ClearFixedPoint();
                }
            }
            switch(m_curView) {
            case STATE_STD_OBSERVERMODE:
                ClearFixedPoint();
                StdObserverMode(Camera_Point_LTW);
                break;
            case STATE_SIDE_SHOT:
                if (tempDist <= g_CamerashipParams.m_fDistSideShot) {
                    SideShot( parent_local_to_world, interestObj_local_to_world);
                } else {
                    FrontShot( parent_local_to_world, interestObj_local_to_world, MEDIUMSHOT);
				    m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeFrontShot;
				    m_curView = STATE_FRONT_SHOT;
                    m_curRange = MEDIUMSHOT;
                    m_pLastParent = NULL;
                }
                ClearFixedPoint();
                break;
            case STATE_DEATH_SEQUENCE_START:
            case STATE_DEATH_SEQUENCE_TRANS:
                //StdObserverMode(Camera_Point_LTW);
                break;
            case STATE_FIXED_TRACKING_SHOT:
                FixedTracking(parent_local_to_world, m_curRange);
                break;
			case STATE_FRONT_SHOT:	
				FrontShot( parent_local_to_world, interestObj_local_to_world, m_curRange);
				ClearFixedPoint();
                break;
			case STATE_OVERSHOULDER_SHOT:
				OverShoulderShot( parent_local_to_world, interestObj_local_to_world, m_curRange);
				ClearFixedPoint();
                break;
            }
        } else {
            ClearFixedPoint();
            StdObserverMode(Camera_Point_LTW);
        }
	}
	else if(cameraView == EditorCameraView)
	{
		SyncMatrices(true);
		cameraDirty = true;
	}
	else if(cameraView == TopDownCameraView)
	{
		LinearMatrix4D camera_to_world;
		YawPitchRoll camera_rotation = YawPitchRoll::Identity;
		camera_rotation.pitch = Pi_Over_2;
		camera_to_world.BuildTranslation(cameraOffset);
		camera_to_world.BuildRotation(camera_rotation);
		
		Entity *parent = GetParentEntity();
		Check_Object(parent);
		LinearMatrix4D world_to_parent;
		world_to_parent.Invert(parent->GetLocalToWorld());
		LinearMatrix4D camera_to_parent;
		camera_to_parent.Multiply(camera_to_world, world_to_parent);
		SetNewLocalToParent(camera_to_parent);
		SyncMatrices(true);
		cameraDirty = true;
	}
	else if(cameraView == InMechCameraView)
	{
		if(cameraDirty)
		{
			if (eyeSitePointer == NULL)
			{
				SetNewLocalToParent(LinearMatrix4D::Identity);
				SyncMatrices(true);
				cameraDirty = true;
			}
			else
			{
				const LinearMatrix4D &site_to_world = eyeSitePointer->GetLocalToWorld();
				Check_Object(&site_to_world);

				const LinearMatrix4D &parent_to_world = GetParentEntity()->GetLocalToWorld();
				Check_Object(&parent_to_world);

				LinearMatrix4D world_to_parent;
				world_to_parent.Invert(parent_to_world);

				LinearMatrix4D site_to_parent;
				site_to_parent.Multiply(site_to_world, world_to_parent);

				SetNewLocalToParent(site_to_parent);
				Camera_Point_LTW = site_to_world;
			}
		}
	}
	//
	// See if the camera is underwater
	//
	if (Camera_Point_LTW.y <= Map::GetInstance()->GetGameModel()->m_waterLevel)
	{
		if (m_eFogType != UnderwaterFogType)
		{
			Adept::Mission::GetInstance()->SetUnderwaterFogData();
			m_eFogType = UnderwaterFogType;
		}
	}
	else
	{
		//
		// There are four cases here
		//
		// 1. Already in the state we want, exit
		if (!(m_eFogType == NormalFogType && !fNeedSmoke))
		{
			if (!(m_eFogType == SmokeFogType && fNeedSmoke))
			{
				//
				// If we were in water, then just pop
				//
				if (m_eFogType == UnderwaterFogType)
				{
					if (fNeedSmoke)
					{
						m_eFogType = SmokeFogType;
						Adept::Mission::GetInstance()->SetSmokeFogData();
					}
					else
					{
						m_eFogType = NormalFogType;
						Adept::Mission::GetInstance()->ResetNormalFogData();
					}
				}
				else
				{
					Stuff::Scalar currentTime = (float)gos_GetElapsedTime();
#define MAX_TRANSITION_TIME_FOR_SMOKE (2.0f)
					//
					// We need to transition
					//
					if (fNeedSmoke)
					{
						Stuff::Scalar timeRemaining = MAX_TRANSITION_TIME_FOR_SMOKE;
						if (m_eFogType == NormalFogType)
						{
							m_eFogType  = TransitionToSmokeFogType;
							m_fltFogTransitionEndTime = currentTime + MAX_TRANSITION_TIME_FOR_SMOKE; // hard coded time to fade, first transition will be next frame
						}
						else if (m_eFogType == TransitionToNormalFogType)
						{
							// In this case we were on our way up to smoke so the transition time should be less
							// and we should start midway
							m_eFogType = TransitionToSmokeFogType;
							timeRemaining = m_fltFogTransitionEndTime - currentTime;
							timeRemaining = MAX_TRANSITION_TIME_FOR_SMOKE - timeRemaining; // since we're now going backwards
							m_fltFogTransitionEndTime = currentTime + timeRemaining; // hard coded time to fade, first transition will be next frame
						}
						else
						{
							timeRemaining = m_fltFogTransitionEndTime - currentTime;
						}
						Min_Clamp(timeRemaining, 0.0f);
						Max_Clamp(timeRemaining, MAX_TRANSITION_TIME_FOR_SMOKE);
						Adept::Mission::GetInstance()->BlendSmokeFogData((MAX_TRANSITION_TIME_FOR_SMOKE - timeRemaining)/MAX_TRANSITION_TIME_FOR_SMOKE);
						if (Small_Enough(timeRemaining))
						{
							m_eFogType = SmokeFogType;
						}

					}
					else // this is the case for !fNeedSmoke
					{
						Stuff::Scalar timeRemaining = MAX_TRANSITION_TIME_FOR_SMOKE;
						if (m_eFogType == SmokeFogType)
						{
							m_eFogType = TransitionToNormalFogType;
							m_fltFogTransitionEndTime = currentTime + MAX_TRANSITION_TIME_FOR_SMOKE; // hard coded time to fade, first transition will be next frame
						}
						else if (m_eFogType == TransitionToSmokeFogType)
						{
							// In this case we were on our way up to smoke so the transition time should be less
							// and we should start midway
							m_eFogType = TransitionToNormalFogType;
							timeRemaining = m_fltFogTransitionEndTime - currentTime;
							timeRemaining = MAX_TRANSITION_TIME_FOR_SMOKE - timeRemaining; // since we're now going backwards
							m_fltFogTransitionEndTime = currentTime + timeRemaining; // hard coded time to fade, first transition will be next frame
						}
						else
						{
							timeRemaining = m_fltFogTransitionEndTime - currentTime;
						}
						Min_Clamp(timeRemaining, 0.0f);
						Max_Clamp(timeRemaining, MAX_TRANSITION_TIME_FOR_SMOKE);
						// since it is going backwards the percentage calc must show that
						if (Small_Enough(timeRemaining))
						{
							m_eFogType = NormalFogType;
							Adept::Mission::GetInstance()->ResetNormalFogData();
						}
						else
						{
							Adept::Mission::GetInstance()->BlendSmokeFogData(timeRemaining/MAX_TRANSITION_TIME_FOR_SMOKE);
						}

					} // don't need smoke
				}  // we were underwater, previously
			}	// else of have smoke, need smoke
		}	// have normal, want normal
	}	 // we're above water

	SyncMatrices(true);
	cameraDirty = true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::UpdateBRBView(void)
{
	Check_Object(this);

	const Stuff::LinearMatrix4D &local_to_world = vehicle->GetLocalToWorld();
		
	LinearMatrix4D temp_local_to_world;
	temp_local_to_world = cameraOffset;

	LinearMatrix4D temp_local_to_world2;
	temp_local_to_world2 = cameraRotation;

	LinearMatrix4D combined_matrix;
	combined_matrix.Multiply(temp_local_to_world,temp_local_to_world2);

	LinearMatrix4D new_matrix;
	new_matrix.Multiply(combined_matrix, local_to_world);

	SetNewLocalToParent(new_matrix);
	SyncMatrices(true);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Entity*
	VehicleInterface::TraceToParent(Entity *entity)
{
 	if(!entity)
		return NULL;

	if(entity->IsDerivedFrom(MWMover::DefaultData))
	{
		MWMover *mover;
		mover = Cast_Object(MWMover *, entity);
		if(mover->myParentVehicle)
			return mover->myParentVehicle;
	}
	return entity;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::UpdateTargetReticule(Time till)
{
	Check_Object(this);
	Check_Object(vehicle);
	Entity *entity_hit = targetQueryEntity.GetCurrent();
	Entity *entity_hit_part = entity_hit;
	bool weapon_lock = GetWeaponLock();

	Time current_time = gos_GetElapsedTime();
	Time time_slice_amount = GetTimeSlice(till);
	Stuff::Scalar weapon_Lock_Time = GetWeaponLockTime();
	
	//
	//--------------------------------------------------------
	//Check if we are hitting something other than the terrain
	//--------------------------------------------------------
	//
	targetStartTime = current_time;

	//
	// Don't go through all this if we are looking backwards
	//
	Torso * torso = NULL;
	Sensor *sensor = NULL;
	int sensorMode = Sensor::ActiveMode;
	if (vehicle)
	{
		torso = vehicle->GetTorso();
		sensor = vehicle->GetSensor();
		if (sensor)
		{
			Check_Object(sensor);
			sensorMode = sensor->GetSensorMode ();
		}
	}
// MSL 5.04 Back View Torso
	if ((sensorMode == Sensor::PassiveMode)	|| vehicle->vehicleShutDown	|| cinemaPlaying)
		{
			targetEntity.Remove();
			targetStartTime = current_time;
			targetLossTime = 0.0f;;
			lockedTargetEntity.Remove();
			lockedTargetEntityPart.Remove();
			pointLockedEntityPartOffset = Stuff::Point3D::Identity;
		}
	else
	{
		if((entity_hit) && (!entity_hit->IsDerivedFrom(Map::DefaultData)))
		{
			entity_hit = TraceToParent(entity_hit);

			if ((entity_hit != 0) &&
				(vehicle != 0))
			{
				MW4AI::Groups::NotifyPlayerFocusedOnEntity(*vehicle,*entity_hit);
			}

		//	targetQuery.m_raySource = entity_hit;
			//
			//--------------------------------------------------------
			//Check to see if we are hitting the same entity as before
			//--------------------------------------------------------
			//
			// We now ignore non-moving objects from locking.
			//
			//
			if (entity_hit->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData))
			{
				Entity * lastVehicle = targetLastVehicleEntity.GetCurrent();

				if (targetLastVehicleEntity.GetCurrent())
					targetLastVehicleEntity.Remove();
				targetLastVehicleEntity.Add(entity_hit);

				//
				// With the new instalock weapon, SSRM, we need to always store this part, as long as we're on a vehicle.
				//
				
				lockedTargetEntityPart.Remove();
				lockedTargetEntityPart.Add( entity_hit_part );
				//
				// We also need to store the offset that we hit from the part.
				// It's the only way to guarantee we have a hittable part of the entity we're aiming for.
				//
				Stuff::Point3D tempTargetPoint;
				targetQuery.m_line->FindEnd(&tempTargetPoint);
				pointLockedEntityPartOffset.MultiplyByInverse(tempTargetPoint, entity_hit_part->GetLocalToWorld());


				//
				// Make sure we are only doing this logic for the last vehicle entity
				//
				if(entity_hit == lastVehicle)
				{

					//
					// Are we already locked to this item
					//
					targetLossTime +=	time_slice_amount;
					Max_Clamp(targetLossTime, weapon_Lock_Time+0.0001f);
					if(lockedTargetEntity.GetCurrent() == entity_hit)
					{
						targetStartTime = current_time - weapon_Lock_Time - 0.0001f;
						if (cameraView == InMechCameraView || cameraView == ExternalCameraTargetReticule)
						{
							if(MWGUIManager::GetInstance())
							{
								Check_Object(MWGUIManager::GetInstance());
								//
								// New design requests that they have an instalock missile that does not effect the HUD
								// so I am using .0001 as the instalock targetlocktime
								//
// MSL 5.02 lock affects hud
								if (GetWeaponLock() == true)
								{
									if (GetWeaponLockLRM() == true)
										MWGUIManager::GetInstance()->DisplayTargetSystemLRM(true);
									else
										MWGUIManager::GetInstance()->DisplayTargetSystemLRM(false);
									if (GetWeaponLockMRM() == true)
										MWGUIManager::GetInstance()->DisplayTargetSystemMRM(true);
									else
										MWGUIManager::GetInstance()->DisplayTargetSystemMRM(false);
									if (GetWeaponLockSRM() == true)
										MWGUIManager::GetInstance()->DisplayTargetSystemSRM(true);
									else
										MWGUIManager::GetInstance()->DisplayTargetSystemSRM(false);
									if (GetWeaponLockSSRM() == true)
										MWGUIManager::GetInstance()->DisplayTargetSystemSSRM(true);
									else
										MWGUIManager::GetInstance()->DisplayTargetSystemSSRM(false);
									MWGUIManager::GetInstance()->DisplayTargetSystem(true);
									ReactToEvent (MISSILE_LOCKED);
								}
								else
								{
									lockedTargetEntity.Remove();
									lockedTargetEntityPart.Remove();
									pointLockedEntityPartOffset = Stuff::Point3D::Identity;
									targetEntity.Remove();
									targetLastVehicleEntity.Remove();

									MWGUIManager::GetInstance()->DisplayTargetSystem(false);
									MWGUIManager::GetInstance()->DisplayTargetSystemLRM(false);
									MWGUIManager::GetInstance()->DisplayTargetSystemMRM(false);
									MWGUIManager::GetInstance()->DisplayTargetSystemSRM(false);
									MWGUIManager::GetInstance()->DisplayTargetSystemSSRM(false);
									ReactToEvent (MISSILE_LOCKLOST);
								}
								return;
							}
						}
					}
					else
					{
						//
						//---------------------------------
						//Check to see if we are locked yet
						//---------------------------------
						//
						// //	We are pointing at our current entity
						// // Calculate the new value for the lock count.
						// //

						if(GetWeaponLock() == true)
						{
							lockedTargetEntity.Remove();
							lockedTargetEntity.Add( entity_hit );
							lockedTargetEntityPart.Remove();
							lockedTargetEntityPart.Add( entity_hit_part );
							targetStartTime = current_time - weapon_Lock_Time - 0.0001f;
							//
							// We also need to store the offset that we hit from the part.
							// It's the only way to guarantee we have a hittable part of the entity we're aiming for.
							//
							Stuff::Point3D tempTargetPoint;
							targetQuery.m_line->FindEnd(&tempTargetPoint);
							pointLockedEntityPartOffset.MultiplyByInverse(tempTargetPoint, entity_hit_part->GetLocalToWorld());
							if (cameraView == InMechCameraView || cameraView == ExternalCameraTargetReticule)
							{
								if(MWGUIManager::GetInstance())
								{
									Check_Object(MWGUIManager::GetInstance());
									if (GetWeaponLock() == true)
									{
										if (GetWeaponLockLRM() == true)
											MWGUIManager::GetInstance()->DisplayTargetSystemLRM(true);
										else
											MWGUIManager::GetInstance()->DisplayTargetSystemLRM(false);
										if (GetWeaponLockMRM() == true)
											MWGUIManager::GetInstance()->DisplayTargetSystemMRM(true);
										else
											MWGUIManager::GetInstance()->DisplayTargetSystemMRM(false);
										if (GetWeaponLockSRM() == true)
											MWGUIManager::GetInstance()->DisplayTargetSystemSRM(true);
										else
											MWGUIManager::GetInstance()->DisplayTargetSystemSRM(false);
										if (GetWeaponLockSSRM() == true)
											MWGUIManager::GetInstance()->DisplayTargetSystemSSRM(true);
										else
											MWGUIManager::GetInstance()->DisplayTargetSystemSSRM(false);
										MWGUIManager::GetInstance()->DisplayTargetSystem(true);
										ReactToEvent (MISSILE_LOCKED);
									}
									else
									{
										lockedTargetEntity.Remove();
										lockedTargetEntityPart.Remove();
										pointLockedEntityPartOffset = Stuff::Point3D::Identity;
										targetEntity.Remove();
										targetLastVehicleEntity.Remove();
	
										MWGUIManager::GetInstance()->DisplayTargetSystem(false);
										MWGUIManager::GetInstance()->DisplayTargetSystemLRM(false);
										MWGUIManager::GetInstance()->DisplayTargetSystemMRM(false);
										MWGUIManager::GetInstance()->DisplayTargetSystemSRM(false);
										MWGUIManager::GetInstance()->DisplayTargetSystemSSRM(false);
										ReactToEvent (MISSILE_LOCKLOST);
									}
									return;
								}
							}	// cameraView check
						}	// if we have a new lock
					} //	else			if (we have a current lock)
				}	// if the entity changed
				else	//if(entity_hit == targetEntity.GetCurrent() && entity_hit->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData))
				{
					// we hit a different vehicle entity, so reset
						targetEntity.Remove();
						targetEntity.Add(entity_hit);
						targetStartTime = current_time;
						targetLossTime = 0.0f;;
						lockedTargetEntity.Remove();
						lockedTargetEntityPart.Remove();
						//
						// lockedTargetEntityPart has to be filled all the time in order to support the weapons
						// that lock faster than the one returned by GetWeaponLockTime() with no weapon specified.
						//
						lockedTargetEntityPart.Add( entity_hit_part );
						Stuff::Point3D tempTargetPoint;
						targetQuery.m_line->FindEnd(&tempTargetPoint);
						pointLockedEntityPartOffset.MultiplyByInverse(tempTargetPoint, entity_hit_part->GetLocalToWorld());
				}
			}
			else //if (entity_hit->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData))
			{
				//
				// If we are on an entity that is not a vehicle we treat it like we do the map, for unlock purposes
				//
				if(lockedTargetEntity.GetCurrent())
				{
					targetLossTime -= (time_slice_amount * 0.5f);
					Min_Clamp(targetLossTime, -0.0001f);
					lockedTargetEntity.Remove();
					lockedTargetEntityPart.Remove();
					pointLockedEntityPartOffset = Stuff::Point3D::Identity;
					targetEntity.Remove();
					targetLastVehicleEntity.Remove();
					targetStartTime = current_time;
					targetLossTime = 0.0f;;
				}
				else // we have no locked object anyway
				{
				targetLossTime -= (time_slice_amount * 0.25f);
				lockedTargetEntityPart.Remove();
				pointLockedEntityPartOffset = Stuff::Point3D::Identity;
				Min_Clamp(targetLossTime, -0.0001f);
				}
			}
		}
		else //if((entity_hit) && (!entity_hit->IsDerivedFrom(Map::DefaultData)))
		{
			//
			// In this case we need to subtract from the current lock time so that we either are farther from locking, or we
			// unlock
			//
			if(lockedTargetEntity.GetCurrent())
			{
				targetLossTime -= (time_slice_amount * 0.5f);
				Min_Clamp(targetLossTime, -0.0001f);
				lockedTargetEntity.Remove();
				lockedTargetEntityPart.Remove();
				pointLockedEntityPartOffset = Stuff::Point3D::Identity;
				targetEntity.Remove();
				targetLastVehicleEntity.Remove();
				targetStartTime = current_time;
				targetLossTime = 0.0f;;
			}
			//
			// If there was no previously targetted object locked, then we need to reset targetEntity, otherwise you can lock by just
			// touching an object twice.
			//
			else
			{
				targetLossTime -= (time_slice_amount * 0.25f);
				Min_Clamp(targetLossTime, -0.0001f);
				targetEntity.Remove();
				lockedTargetEntityPart.Remove();
				pointLockedEntityPartOffset = Stuff::Point3D::Identity;
	//			targetLastVehicleEntity.Remove();
			}
		}
	}

	if(MWGUIManager::GetInstance())
	{
		Check_Object(MWGUIManager::GetInstance());
		MWGUIManager::GetInstance()->DisplayTargetSystem(false);
		MWGUIManager::GetInstance()->DisplayTargetSystemLRM(false);
		MWGUIManager::GetInstance()->DisplayTargetSystemMRM(false);
		MWGUIManager::GetInstance()->DisplayTargetSystemSRM(false);
		MWGUIManager::GetInstance()->DisplayTargetSystemSSRM(false);
		ReactToEvent (MISSILE_LOCKLOST);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::SaveTarget()
{
	
	lockedWeaponCommand.targetOffset = Point3D::Identity;

	if (targetQueryEntity.GetCurrent() == Map::GetInstance())
	{
		weaponCommand.target.Add(targetQueryEntity.GetCurrent());
		weaponCommand.originator.Add(vehicle);

		Point3D target_point = Point3D::Identity;
		targetQuery.m_line->FindEnd(&target_point);

		weaponCommand.targetOffset = target_point;
		weaponCommand.targetOffset = weaponCommand.targetOffset;
		weaponCommand.lockTime = 0.0f;
		lockedWeaponCommand.targetOffset = pointLockedEntityPartOffset;
	}
	else if (targetQueryEntity.GetCurrent() != NULL)
	{

		weaponCommand.target.Add(targetQueryEntity.GetCurrent());
		weaponCommand.originator.Add(vehicle);

		Point3D target_point = Point3D::Identity;
		targetQuery.m_line->FindEnd(&target_point);

		weaponCommand.targetOffset.MultiplyByInverse(target_point, targetQueryEntity.GetCurrent()->GetLocalToWorld());
		weaponCommand.lockTime = 0.0f;
		weaponCommand.targetOffset = weaponCommand.targetOffset;
		lockedWeaponCommand.targetOffset = pointLockedEntityPartOffset;
	}
	else
	{
		weaponCommand.target.Remove();
		weaponCommand.originator.Add(vehicle);
		
		Point3D target_point = Point3D::Identity;
		targetQuery.m_line->FindEnd(&target_point);

		weaponCommand.targetOffset = target_point;
		weaponCommand.targetOffset = weaponCommand.targetOffset;
		weaponCommand.lockTime = 0.0f;
	}



	if (lockedTargetEntityPart.GetCurrent() != NULL)
	{
		lockedWeaponCommand.target.Remove();
		lockedWeaponCommand.target.Add(lockedTargetEntityPart.GetCurrent());
	}
	else
	{
		// if we don't have a target we use the target from the regular fire command.
		lockedWeaponCommand.target.Remove();

		if (weaponCommand.target.GetCurrent())
		{
			lockedWeaponCommand.target.Add(weaponCommand.target.GetCurrent());
		}
		lockedWeaponCommand.targetOffset = weaponCommand.targetOffset;

	}
	lockedWeaponCommand.originator.Add(vehicle);

	
	Time time_now = gos_GetElapsedTime();
	Time target_time = time_now - targetStartTime;
	Entity *target = targetEntity.GetCurrent();
	Scalar multiplier = GetLockTimeMultiplier(vehicle, target);
	target_time = target_time / multiplier;

	lockedWeaponCommand.lockTime = (Scalar)target_time;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

Scalar
	VehicleInterface::GetLockTimeMultiplier(Vehicle * vehicle, Entity * target)
{
	Scalar multiplier = 1.0f;
	if(vehicle->DoesHaveBeagle())
	{
		const Beagle::GameModel *beagle_model = vehicle->GetBeagle()->GetGameModel();
		multiplier -= beagle_model->m_holderMissileLockPercent;
	}
	if(target)
	{
		if(target->IsDerivedFrom(MWObject::DefaultData))
		{
			MWObject *mw_object = Cast_Object(MWObject *, target);
			if(mw_object->DoesHaveBeagle())
			{
				const Beagle::GameModel *beagle_model = mw_object->GetBeagle()->GetGameModel();
				multiplier -= beagle_model->m_targeterMissileLockPercent;
			}
			if(mw_object->DoesHaveECM())
			{
				const ECM::GameModel *ecm_model = mw_object->GetECM()->GetGameModel();
				multiplier -= ecm_model->m_targeterMissileLockPercent;
			}
// MSL 5.02 SubSystems
			if(mw_object->DoesHaveIFF_Jammer())
			{
				const IFF_Jammer::GameModel *iff_jammer_model = mw_object->GetIFF_Jammer()->GetGameModel();
				multiplier += iff_jammer_model->m_targeterMissileLockPercent;
			}
		}
	}
	// multiplier ends up being used as a divisor in lieing to the weapons about the time they were locked.
	// so it must not be 0.0 or too close to it.
	Min_Clamp(multiplier, 0.01f);
	return multiplier;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

float
	VehicleInterface::GetLockModifier(Vehicle * vehicle, Entity * target)
{
	float modifier = 0.0f;

// MSL 5.05 Advance Mode
	MWApplication *m_App;
	m_App = MWApplication::GetInstance ();
	m_AdvanceMode = m_App->GetLocalNetParams()->m_advancemodeOn;

	if (m_AdvanceMode)
	{
		if(target)
		{
			if(target->IsDerivedFrom(Mech::DefaultData))
			{
				Mech *mech = Cast_Object(Mech *, target);
				Sensor *sensorme;
				Sensor *sensortarget;
				sensorme = vehicle->GetSensor();
				sensortarget = mech->GetSensor();
				// A -
				if(sensorme->GetSensorMode() == Sensor::ActiveMode)
				{
					// A - A
					if(sensortarget->GetSensorMode() == Sensor::ActiveMode)
					{
						if(mech->DoesHaveECM())
						{
							if(vehicle->DoesHaveBeagle())
							{
								// AB - AE
								modifier = 700.0f;
							}
							else
							{
								// A - AE
								modifier = 500.0f;
							}
						}
						else
						{
							if(vehicle->DoesHaveBeagle())
							{
								// AB - A
								modifier = 1200.0f;
							}
							else
							{
								// A - A
								modifier = 1000.0f;
							}
						}
					}
					// A - P
					if(sensortarget->GetSensorMode() == Sensor::PassiveMode)
					{
						if(mech->DoesHaveECM())
						{
							if(vehicle->DoesHaveBeagle())
							{
								// AB - PE
								modifier = 600.0f;
							}
							else
							{
								// A - PE
								modifier = 500.0f;
							}
						}
						else
						{
							if(vehicle->DoesHaveBeagle())
							{
								// AB - P
								modifier = 600.0f;
							}
							else
							{
								// A - P
								modifier = 500.0f;
							}
						}
					}
				}
				// P -
				if(sensorme->GetSensorMode() == Sensor::PassiveMode)
				{
					// P - A
					if(sensortarget->GetSensorMode() == Sensor::ActiveMode)
					{
						if(mech->DoesHaveECM())
						{
							if(vehicle->DoesHaveBeagle())
							{
								// PB - AE
								modifier = 250.0f;
							}
							else
							{
								// P - AE
								modifier = 100.0f;
							}
						}
						else
						{
							if(vehicle->DoesHaveBeagle())
							{
								// PB - A
								modifier = 250.0f;
							}
							else
							{
								// P - A
								modifier = 100.0f;
							}
						}
					}
					// P - P
					if(sensortarget->GetSensorMode() == Sensor::PassiveMode)
					{
						if(mech->DoesHaveECM())
						{
							if(vehicle->DoesHaveBeagle())
							{
								// PB - PE
								modifier = 0.0f;
							}
							else
							{
								// P - PE
								modifier = 0.0f;
							}
						}
						else
						{
							if(vehicle->DoesHaveBeagle())
							{
								// PB - P
								modifier = 0.0f;
							}
							else
							{
								// P - P
								modifier = 0.0f;
							}
						}
					}
				}
				// SD - 
				if(sensorme->GetSensorMode() == Sensor::ShutdownMode)
				{
					// SD - A
					if(sensortarget->GetSensorMode() == Sensor::ActiveMode)
					{
						if(mech->DoesHaveECM())
						{
							if(vehicle->DoesHaveBeagle())
							{
								// SDB - AE
								modifier = 0.0f;
							}
							else
							{
								// SD - AE
								modifier = 0.0f;
							}
						}
						else
						{
							if(vehicle->DoesHaveBeagle())
							{
								// SDB - A
								modifier = 0.0f;
							}
							else
							{
								// SD - A
								modifier = 0.0f;
							}
						}
					}
					// SD - P
					if(sensortarget->GetSensorMode() == Sensor::PassiveMode)
					{
						if(mech->DoesHaveECM())
						{
							if(vehicle->DoesHaveBeagle())
							{
								// SDB - PE
								modifier = 0.0f;
							}
							else
							{
								// SD - PE
								modifier = 0.0f;
							}
						}
						else
						{
							if(vehicle->DoesHaveBeagle())
							{
								// SDB - P
								modifier = 0.0f;
							}
							else
							{
								// SD - P
								modifier = 0.0f;
							}
						}
					}
				}
			}
		}
	}
	return modifier;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

bool
	VehicleInterface::GetLockModifierSTK(Vehicle * vehicle, Entity * target)
{
	float modifier = 0.0f;

// MSL 5.05 Advance Mode
	MWApplication *m_App;
	m_App = MWApplication::GetInstance ();
	m_AdvanceMode = m_App->GetLocalNetParams()->m_advancemodeOn;

	if (m_AdvanceMode)
	{
		if(target)
		{
			if(target->IsDerivedFrom(Mech::DefaultData))
			{
				return (true);
			}
		}
	}
	return (false);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

bool
	VehicleInterface::GetWeaponLock(Weapon *weapon)
{

	if(weapon->IsDerivedFrom(MissileWeapon::DefaultData) &&
		weapon->DoesHaveAmmo() &&
		weapon->executionState->GetState()!=Subsystem::ExecutionStateEngine::DestroyedState)
		 // see if we have ammo, don't use > 0 since unlimitted matters
	{
		MissileWeapon *missile_weapon;
		missile_weapon = Cast_Object(MissileWeapon *, weapon);
		const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
		Check_Object(model);

		float targetRange = 0.0f;
		targetRange = model->maxDistance;
		
		Entity *target = targetEntity.GetCurrent();
		float modifier = GetLockModifier(vehicle, target);
		if (modifier > 0.0f)
		{
			if (modifier < targetRange)
				targetRange = modifier;
		}

//		if((targetQuery.m_line->m_length < targetRange) && (targetQuery.m_line->m_length > model->minDistance))
		if(targetQuery.m_line->m_length < targetRange)
		{
			return (true);
		}
	}

	return (false);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	VehicleInterface::GetWeaponLockLRM()
{
	Check_Object(this);
	Check_Object(vehicle);

//	Entity *target = targetEntity.GetCurrent();

	ChainIteratorOf<Weapon *> iterator(&vehicle->weaponChain);
	Weapon *weapon;
	while((weapon = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(weapon);
		if(weapon->IsDerivedFrom(MissileWeapon::DefaultData) &&
			weapon->DoesHaveAmmo() &&
	  		weapon->executionState->GetState()!=Subsystem::ExecutionStateEngine::DestroyedState &&
			weapon->GetClassID() == LRMWeaponSubsystemClassID)
		{
			
			MissileWeapon *missile_weapon;
			missile_weapon = Cast_Object(MissileWeapon *, weapon);
			const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
			Check_Object(model);

			float targetRange = 0.0f;
			targetRange = model->maxDistance;
		
			Entity *target = targetEntity.GetCurrent();
			float modifier = GetLockModifier(vehicle, target);
			if (modifier > 0.0f)
			{
				if (modifier < targetRange)
					targetRange = modifier;
			}

//			if((targetQuery.m_line->m_length < targetRange) && (targetQuery.m_line->m_length > model->minDistance))
			if(targetQuery.m_line->m_length < targetRange)
			{
				return (true);
			}
		}
	}
	return (false);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	VehicleInterface::GetWeaponLockMRM()
{
	Check_Object(this);
	Check_Object(vehicle);

//	Entity *target = targetEntity.GetCurrent();

	ChainIteratorOf<Weapon *> iterator(&vehicle->weaponChain);
	Weapon *weapon;
	while((weapon = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(weapon);
		if(weapon->IsDerivedFrom(MissileWeapon::DefaultData) &&
			weapon->DoesHaveAmmo() &&
	  		weapon->executionState->GetState()!=Subsystem::ExecutionStateEngine::DestroyedState &&
			weapon->GetClassID() == MRMWeaponSubsystemClassID)
		{
			
			MissileWeapon *missile_weapon;
			missile_weapon = Cast_Object(MissileWeapon *, weapon);
			const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
			Check_Object(model);

			float targetRange = 0.0f;
			targetRange = model->maxDistance;
		
			Entity *target = targetEntity.GetCurrent();
			float modifier = GetLockModifier(vehicle, target);
			if (modifier > 0.0f)
			{
				if (modifier < targetRange)
					targetRange = modifier;
			}

//			if((targetQuery.m_line->m_length < targetRange) && (targetQuery.m_line->m_length > model->minDistance))
			if(targetQuery.m_line->m_length < targetRange)
			{
				return (true);
			}
		}
	}
	return (false);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	VehicleInterface::GetWeaponLockSRM()
{
	Check_Object(this);
	Check_Object(vehicle);

//	Entity *target = targetEntity.GetCurrent();

	ChainIteratorOf<Weapon *> iterator(&vehicle->weaponChain);
	Weapon *weapon;
	while((weapon = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(weapon);
		if(weapon->IsDerivedFrom(MissileWeapon::DefaultData) &&
			weapon->DoesHaveAmmo() &&
	  		weapon->executionState->GetState()!=Subsystem::ExecutionStateEngine::DestroyedState &&
			weapon->GetClassID() == SRMWeaponSubsystemClassID)
		{
			
			MissileWeapon *missile_weapon;
			missile_weapon = Cast_Object(MissileWeapon *, weapon);
			const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
			Check_Object(model);

			float targetRange = 0.0f;
			targetRange = model->maxDistance;
		
			Entity *target = targetEntity.GetCurrent();
			float modifier = GetLockModifier(vehicle, target);
			if (modifier > 0.0f)
			{
				if (modifier < targetRange)
					targetRange = modifier;
			}

//			if((targetQuery.m_line->m_length < targetRange) && (targetQuery.m_line->m_length > model->minDistance))
			if(targetQuery.m_line->m_length < targetRange)
			{
				return (true);
			}
		}
	}
	return (false);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	VehicleInterface::GetWeaponLockSSRM()
{
	Check_Object(this);
	Check_Object(vehicle);

//	Entity *target = targetEntity.GetCurrent();

	ChainIteratorOf<Weapon *> iterator(&vehicle->weaponChain);
	Weapon *weapon;
	while((weapon = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(weapon);
		if(weapon->IsDerivedFrom(MissileWeapon::DefaultData) &&
			weapon->DoesHaveAmmo() &&
	  		weapon->executionState->GetState()!=Subsystem::ExecutionStateEngine::DestroyedState &&
			weapon->GetClassID() == SSRMWeaponSubsystemClassID)
		{
			
			MissileWeapon *missile_weapon;
			missile_weapon = Cast_Object(MissileWeapon *, weapon);
			const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
			Check_Object(model);

			float targetRange = 0.0f;
			targetRange = model->maxDistance;
		
			Entity *target = targetEntity.GetCurrent();
			float modifier = GetLockModifier(vehicle, target);
			if (modifier > 0.0f)
			{
				if (modifier < targetRange)
					targetRange = modifier;
			}

			if (GetLockModifierSTK(vehicle, target) == false)
			{
				return (false);
			}
			
//			if((targetQuery.m_line->m_length < targetRange) && (targetQuery.m_line->m_length > model->minDistance))
			if(targetQuery.m_line->m_length < targetRange)
			{
				return (true);
			}
		}
	}
	return (false);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	VehicleInterface::GetWeaponLock()
{
	Check_Object(this);
	Check_Object(vehicle);

//	Entity *target = targetEntity.GetCurrent();

	ChainIteratorOf<Weapon *> iterator(&vehicle->weaponChain);
	Weapon *weapon;
	while((weapon = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(weapon);
		if(weapon->IsDerivedFrom(MissileWeapon::DefaultData) &&
			weapon->DoesHaveAmmo() &&
	  		weapon->executionState->GetState()!=Subsystem::ExecutionStateEngine::DestroyedState)
		{
			MissileWeapon *missile_weapon;
			missile_weapon = Cast_Object(MissileWeapon *, weapon);
			const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
			Check_Object(model);

//			float LRMtargetRangeMin = 0.0f;
			float LRMtargetRangeMax = 0.0f; 
//			float MRMtargetRangeMin = 0.0f;
			float MRMtargetRangeMax = 0.0f;
//			float SRMtargetRangeMin = 0.0f;
			float SRMtargetRangeMax = 0.0f;
//			float SSRMtargetRangeMin = 0.0f;
			float SSRMtargetRangeMax = 0.0f;

			if(weapon->GetClassID() == LRMWeaponSubsystemClassID)
			{
//				LRMtargetRangeMin = model->minDistance;
				LRMtargetRangeMax = model->maxDistance;
			}
			if(weapon->GetClassID() == MRMWeaponSubsystemClassID)
			{
//				MRMtargetRangeMin = model->minDistance;
				MRMtargetRangeMax = model->maxDistance;
			}
			if(weapon->GetClassID() == SRMWeaponSubsystemClassID)
			{
//				SRMtargetRangeMin = model->minDistance;
				SRMtargetRangeMax = model->maxDistance;
			}
			if(weapon->GetClassID() == SSRMWeaponSubsystemClassID)
			{
//				SSRMtargetRangeMin = model->minDistance;
				SSRMtargetRangeMax = model->maxDistance;
			}
		
			Entity *target = targetEntity.GetCurrent();
			float modifier = GetLockModifier(vehicle, target);
			if (modifier > 0.0f)
			{
				if (modifier < LRMtargetRangeMax)
					LRMtargetRangeMax = modifier;
				if (modifier < MRMtargetRangeMax)
					MRMtargetRangeMax = modifier;
				if (modifier < SRMtargetRangeMax)
					SRMtargetRangeMax = modifier;
				if (modifier < SSRMtargetRangeMax)
					SSRMtargetRangeMax = modifier;
			}

//			if((targetQuery.m_line->m_length < LRMtargetRangeMax) && (targetQuery.m_line->m_length > LRMtargetRangeMin))
			if(targetQuery.m_line->m_length < LRMtargetRangeMax)
			{
				return (true);
			}
//			else if((targetQuery.m_line->m_length < MRMtargetRangeMax) && (targetQuery.m_line->m_length > MRMtargetRangeMin))
			else if(targetQuery.m_line->m_length < MRMtargetRangeMax)
			{
				return (true);
			}
//			else if((targetQuery.m_line->m_length < SRMtargetRangeMax) && (targetQuery.m_line->m_length > SRMtargetRangeMin))
			else if(targetQuery.m_line->m_length < SRMtargetRangeMax)
			{
				return (true);
			}
//			else if((targetQuery.m_line->m_length < SSRMtargetRangeMax) && (targetQuery.m_line->m_length > SSRMtargetRangeMin))
			else if(targetQuery.m_line->m_length < SSRMtargetRangeMax)
			{
				return (true);
			}
		}
	}
	return (false);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

Scalar
	VehicleInterface::GetWeaponLockTime(Weapon *weapon)
{

	if(weapon->IsDerivedFrom(MissileWeapon::DefaultData) &&
		weapon->DoesHaveAmmo() &&
		weapon->executionState->GetState()!=Subsystem::ExecutionStateEngine::DestroyedState)
		 // see if we have ammo, don't use > 0 since unlimitted matters
	{
		MissileWeapon *missile_weapon;
		missile_weapon = Cast_Object(MissileWeapon *, weapon);
		const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
		Check_Object(model);
		Scalar lock_time = -1.0f;
		lock_time = model->targetLockTime;

#ifdef LAB_ONLY
		if (m_fImmediateWeaponLockMode)
		{
			return 0.0001f;
		}
#endif
		Entity *target = targetEntity.GetCurrent();
		Scalar multiplier = GetLockTimeMultiplier(vehicle, target);
		return (lock_time * multiplier);
	}

	return 0.0f;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//


Scalar
	VehicleInterface::GetWeaponLockTime()
{
	Check_Object(this);
	Check_Object(vehicle);

	Scalar value = -1.0f;

	ChainIteratorOf<Weapon *> iterator(&vehicle->weaponChain);
	Weapon *weapon;
	while((weapon = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(weapon);
		if(weapon->IsDerivedFrom(MissileWeapon::DefaultData) &&
				weapon->DoesHaveAmmo() &&
	  		weapon->executionState->GetState()!=Subsystem::ExecutionStateEngine::DestroyedState)
		{
			MissileWeapon *missile_weapon;
			missile_weapon = Cast_Object(MissileWeapon *, weapon);
			const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
			Check_Object(model);
			if(value < model->targetLockTime)
				value = model->targetLockTime;
		}
	}

	Entity *target = targetEntity.GetCurrent();
	Scalar multiplier = GetLockTimeMultiplier(vehicle, target);

#ifdef LAB_ONLY
		if (m_fImmediateWeaponLockMode)
		{
			return 0.0001f;
		}
#endif
	return (value * multiplier);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Entity*
	VehicleInterface::CastCollisionLine()
{
	Check_Object(this);
	
	Stuff::Point3D origin_point;
	LinearMatrix4D our_matrix;

  if (cameraView == ExternalCameraTargetReticule)
  {
    origin_point = GetLocalToWorld(); // get the interface location since we are the camera location
    our_matrix = GetLocalToWorld();
  }
  else
  {
	  if(eyeSitePointer)
	  {
		  Check_Object(eyeSitePointer);
		  origin_point = eyeSitePointer->GetLocalToWorld();
		  our_matrix = eyeSitePointer->GetLocalToWorld();
	  }
	  else
	  {
		  origin_point = GetLocalToWorld();
		  our_matrix = GetLocalToWorld();
	  }
  }

	UnitVector3D origin_direction;
	our_matrix.GetLocalForwardInWorld(&origin_direction);

	targetLine.SetOrigin(origin_point);
	targetLine.SetDirection(origin_direction);
  targetLine.m_length = targetDistance + addedLengthToTarget; // this is an approximation, that will slightly
                                                                  // decrease the target range, but only by a negligable amount
	
	targetQuery.m_line = &targetLine;
	targetQuery.m_normal = &reticuleNormal;
	targetQuery.m_collisionMask = CanBeShotFlag;
	targetQuery.m_raySource = vehicle;
	
	Adept::Entity *entity_hit;
	Check_Object(CollisionGrid::Instance);
	entity_hit = CollisionGrid::Instance->ProjectLine(&targetQuery);

  //
  // If we are in an external view we need to fake the internal line to target. This will also make sure that
  // anything truly blocking the mechs shot can't be avoided by going to the external view.
  //
  if (cameraView == ExternalCameraTargetReticule)
  {
	  if(eyeSitePointer)
	  {
		  Check_Object(eyeSitePointer);
		  origin_point = eyeSitePointer->GetLocalToWorld();
      our_matrix = eyeSitePointer->GetLocalToWorld();
	  }
	  else
	  {
		  origin_point = GetLocalToWorld();
		  our_matrix = GetLocalToWorld();
	  }

    Point3D endOfTargetQuery;

	Min_Clamp(targetQuery.m_line->m_length, 0.0001f);
    targetQuery.m_line->FindEnd(&endOfTargetQuery);


    //
    // If somehow we are trying to target something behind the mech, just cast in the direction of the current
    // eyepoint
    // This will also prevent any targetting > 45 degrees off center of the mech. Minor deviation is expected,
    // but > 45 degrees is considered to be something too sharp to hit without turning your mech.
    //
    // This could happen if something is between the camera and the mech, or in border cases where the camera
    // is partially embedded in a building or the ground.
    //
    //
    // Old code that just checked for behind.
    //    Point3D endOfTargetQuery_Local_To_Eye;
    //    endOfTargetQuery_Local_To_Eye.Multiply(endOfTargetQuery, our_matrix.Invert());

    UnitVector3D lineToTargetPointNormalized;
    UnitVector3D eyepointForwardNormalized;
    Vector3D lineToTargetPoint;

    our_matrix.GetLocalForwardInWorld(&eyepointForwardNormalized);

    lineToTargetPoint.Subtract(endOfTargetQuery, origin_point);
    lineToTargetPointNormalized.Normalize(lineToTargetPoint);


    Stuff::Scalar dotProductOfTargetLines;
    dotProductOfTargetLines = lineToTargetPointNormalized * eyepointForwardNormalized;


    if (dotProductOfTargetLines > 0.707f) // .707 == cos(45 degrees)
    {
  	  targetLine.SetDirection(lineToTargetPointNormalized);
    }
    else
    {
  	  targetLine.SetDirection(eyepointForwardNormalized);
    }
	
    targetLine.SetOrigin(origin_point);
    targetLine.m_length = targetDistance; // this is an approximation, that will slightly

	  targetQuery.m_line = &targetLine;
	  targetQuery.m_normal = &reticuleNormal;
	  targetQuery.m_collisionMask = CanBeShotFlag;
	  targetQuery.m_raySource = vehicle;

  	entity_hit = CollisionGrid::Instance->ProjectLine(&targetQuery);
  }


	if (entity_hit != NULL)
	{
		targetQueryEntity.Remove();
		targetEntityPart.Remove();
		targetQueryEntity.Add(entity_hit);
		targetEntityPart.Add(entity_hit);
	}
	else
	{
		targetQueryEntity.Remove();
		targetEntityPart.Remove();
	}

	reticuleEntity.Remove();

	if (entity_hit != NULL)
	{
		Check_Object(entity_hit);
		reticuleEntity.Add(entity_hit);
		Point3D trans;
		targetLine.FindEnd(&trans);

		reticuleOffset.MultiplyByInverse(
			trans,
			entity_hit->GetLocalToWorld()
		);
	}
	Verify(reticuleEntity.GetCurrent() == entity_hit);

	return entity_hit;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ConnectVehicleToInterface(Vehicle *connecting_vehicle,MWPlayer *player)
{
	Check_Object(this);
	Check_Object(connecting_vehicle);

    MWApplication* app = MWApplication::GetInstance();
    Check_Object(app);
	
	m_currentTargetReticuleCameraPosition = 3;// has to start at an valid number 0 - 2 or 3 for internal
	StartEngineIdle ();
	vehicle = connecting_vehicle;
	gos_PushCurrentHeap(Heap);
	eyeSitePointer = GetEyeSite("site_eyepoint");	
	connecting_vehicle->vehicleInterface = this;


	if (connecting_vehicle->GetClassID() == ObservationVehicleClassID)
		SetObservationMode();
    else {
        if (g_nMR == 2) {
            SetCameraMode(ExternalCameraTerrainFollowView, *GetGameModel()); // from SetObservationMode();
        }
    }


	if ((MWGUIManager::GetInstance()) && (!brbMode) )
	{
		if(!observerMode)
		{
			MWGUIManager::GetInstance()->InitializeNewVehicle(connecting_vehicle);
#if 0
			GUIRadarManager *radar;
			radar = Cast_Object (GUIRadarManager *,MWGUIManager::GetInstance()->Component (MWGUIManager::HUD_RADAR));
			radar->SetVehicle(connecting_vehicle);
			HUDMap *map;
			map = Cast_Object (HUDMap *,MWGUIManager::GetInstance()->Component (MWGUIManager::HUD_MAP));
			map->SetVehicle(connecting_vehicle);

			MWGUIManager::GetInstance()->InitializeTargetSystem();
#endif
			MWGUIManager::GetInstance()->lightAmp->Initialize();
//			MWGUIManager::GetInstance()->zoomLightAmp->Initialize();
			MWGUIManager::GetInstance()->staticViewManager->Initialize();
			m_fHudCurrentlyShowing = true; // used to allow us to continually and cheaply call hide for all views
			m_fHudShouldShow = true; // current state of the hud
			m_fZoomCurrentlyShowing = false; // used to allow us to continually and cheaply call hide for all views
			m_fStaticView = false;
		}
		else
		{
			MWGUIManager::GetInstance()->InitializeNewVehicle(NULL);
			m_fHudCurrentlyShowing = false; // used to allow us to continually and cheaply call hide for all views
			m_fHudShouldShow = false; // current state of the hud
			m_fZoomCurrentlyShowing = false; // used to allow us to continually and cheaply call hide for all views
			m_fStaticView = false;
		}
	}
	else if (brbMode)
	{
		MWGUIManager::GetInstance()->InitializeNewVehicle(NULL);
		m_fHudCurrentlyShowing = true; // used to allow us to continually and cheaply call hide for all views
		m_fHudShouldShow = false; // current state of the hud
		m_fZoomCurrentlyShowing = false; // used to allow us to continually and cheaply call hide for all views
		m_fStaticView = false;
	}


	InitializeWeapons();
	gos_PopCurrentHeap();

	const VehicleInterface__GameModel *model = GetGameModel ();
	Entity::ClassID class_ID;

	if (model->playerAIResource != ResourceID::Null && !Application::GetInstance()->networkingFlag && !observerMode)
	{
		class_ID = Entity::GetClassIDFromDataListID(model->playerAIResource);
		Verify(class_ID != NullClassID);
		if ((!m_PlayerAI) && (class_ID != NullClassID) && (player))
		{

			Check_Object (player);
			int fred;
			Stuff::Scalar cells[MechWarrior4::DEFAULT_MEMORYCELL_VALUES];			// used in memory cell data
			for (fred=0;fred<DEFAULT_MEMORYCELL_VALUES;fred++)
				cells[fred] = 0;

			char filename[255],*occ;
			MWMission *miss;

			Verify (MWMission::GetInstance()->IsDerivedFrom (MWMission::DefaultData));
			miss = (MWMission *) MWMission::GetInstance();
			occ = __mbsrchr (miss->scriptName,'\\');
			if (occ == NULL)
				Str_Copy (filename,"scripts\\player.abl",sizeof(filename));
			else
			{
				miss->scriptName[occ-&(miss->scriptName[0])] = 0;
	//			*occ = 0;
				Str_Copy (filename,miss->scriptName,sizeof (filename));
				miss->scriptName[occ-&(miss->scriptName[0])] = '\\';
	//			*occ = '\\';
				Str_Cat (filename,"\\player.abl",sizeof (filename));
			}
			int aiid;
			aiid = player->objectID;
			aiid &= 0x00ffffff;
			aiid += ((NameTable::PlayerAIArray) << 24);

			PlayerAI::CreateMessage AI_Create_Message(sizeof(PlayerAI::CreateMessage),
													  DefaultEventPriority,
													  PlayerAI::CreateMessage::DefaultFlags,
													  class_ID,
													  PlayerAI::CreateMessage::DefaultFlags,
													  model->playerAIResource,
													  connecting_vehicle->GetLocalToWorld(),
													  0.0f,
													  Entity__ExecutionStateEngine::AlwaysExecuteState,
													  aiid,
													  Entity::DefaultAlignment,
													  DropZone::Null,
													  //			 NameTable::NullObjectID,
													  connecting_vehicle->objectID,
													  filename,		// script name,  should be scripts\<filename>.abl
													  cells,		// memory cell data
													  200,			// gunnery skill
													  100,			// pilot skill
													  100,			// elite skill
													  0,			// min heat
													  100,			// max heat
													  2,			// sensor
													  100,			// blind
													  100,			// long range
													  100,			// short range
													  0,			// towards gunnery
													  0,			// towards pilot
													  0				// towards elite
													  );

			MemoryStream stream(&AI_Create_Message, AI_Create_Message.messageLength);
			ReplicatorID AI_id = Connection::Local->GetNextReplicatorID();
			Entity *AI_Entity = Entity::CreateEntity(&stream, &AI_id, false);
			Check_Object(AI_Entity);
			Verify(AI_Entity->IsDerivedFrom(PlayerAI::DefaultData));
			m_PlayerAI = (PlayerAI *) AI_Entity;

			Check_Object(Map::GetInstance());
			Map::GetInstance()->AddChild(AI_Entity);

			AI_Entity->SetPropType(Entity::MissionPropType);
			AI_Entity->SyncMatrices(true);
			m_PlayerAI->StopExecuting ();

		}
		
	}
	

	CameraComponent *camera = VideoRenderer::Instance->GetSecondaryCamera(0);
	if(camera)
	{
		m_targetCamera = camera->GetElement();
		RGBAColor tint_color(0.0, 1.0, 0.0, 0.0);
		m_targetCamera->SetTintColor(&tint_color);
//		m_targetCamera->SetScene(vehicle->GetElement());
	}

    Stuff::RGBColor color;
    color = RGBColor(0.0f, 0.0f, 0.0f);
    MWVideoRenderer *vid_rend = Cast_Object(MWVideoRenderer *, VideoRenderer::Instance);
    vid_rend->SetFadeLevel(0, color);

	camera = VideoRenderer::Instance->GetSecondaryCamera(1);
	if(camera)
	{
		m_reticuleCamera = camera->GetElement();
		//
		// We need to see where the zoom window ends in the camera fov for determining target reticule info later
		//
		Stuff::Scalar near_clip_zoom;
		Stuff::Scalar far_clip_zoom;
		Stuff::Scalar horizontal_fov_zoom;
		Stuff::Scalar height_to_width_zoom;
		Stuff::Scalar left_zoom, top_zoom, right_zoom, bottom_zoom;
		Check_Object(m_reticuleCamera);
		m_reticuleCamera->GetPerspective(near_clip_zoom, far_clip_zoom, horizontal_fov_zoom, height_to_width_zoom);
		m_reticuleCamera->GetViewport(left_zoom, top_zoom, right_zoom, bottom_zoom);
		
 	//
		// Find out the width of the main view
		//
		percentage_of_zoom_screen_on_left = 0.15f;
		percentage_of_zoom_screen_on_right = 0.15f;
		percentage_of_zoom_screen_on_top = 0.15f;
		percentage_of_zoom_screen_on_bottom = 0.15f;
		if (VideoRenderer::Instance->GetSceneCamera())
		{
			Check_Object(VideoRenderer::Instance->GetSceneCamera());		
			ElementRenderer::CameraElement * camera_main = VideoRenderer::Instance->GetSceneCamera()->GetElement();
			Check_Object(camera_main);
			Stuff::Scalar near_clip_main;
			Stuff::Scalar far_clip_main;
			Stuff::Scalar horizontal_fov_main;
			Stuff::Scalar height_to_width_main;
			camera_main->GetPerspective(near_clip_main, far_clip_main, horizontal_fov_main, height_to_width_main);

			Stuff::Scalar width_main = near_clip_main * Stuff::Tan(horizontal_fov_main*0.5f);
			Stuff::Scalar height_main = near_clip_main * Stuff::Tan(horizontal_fov_main*0.5f)*height_to_width_main;
			percentage_of_zoom_screen_on_left = (left_zoom - 0.5f)*2.0f;
			percentage_of_zoom_screen_on_right = (right_zoom - 0.5f)*2.0f;
			percentage_of_zoom_screen_on_top = (top_zoom - 0.5f)*2.0f;
			percentage_of_zoom_screen_on_bottom = (bottom_zoom - 0.5f)*2.0f;

			percentage_of_zoom_screen_on_left = Stuff::Arctan(width_main * percentage_of_zoom_screen_on_left, near_clip_main) /
																					Stuff::Arctan(width_main, near_clip_main);
			percentage_of_zoom_screen_on_right = Stuff::Arctan(width_main * percentage_of_zoom_screen_on_right, near_clip_main) /
																					Stuff::Arctan(width_main, near_clip_main);
			percentage_of_zoom_screen_on_top = Stuff::Arctan(height_main * percentage_of_zoom_screen_on_top, near_clip_main) /
																					Stuff::Arctan(height_main, near_clip_main);
			percentage_of_zoom_screen_on_bottom = Stuff::Arctan(height_main * percentage_of_zoom_screen_on_bottom, near_clip_main) /
																					Stuff::Arctan(height_main, near_clip_main);
			//
			// Move out the far clip slightly in order to compensate for bad math
			//
			// We are expectin the normal fov to be approximately 1.0 larger than the zoom
			// fov. This allows us to add ~50M in our normal case but support the generic case which
			// would roughly support other magnifications.
			//

			Verify(((horizontal_fov_main - horizontal_fov_zoom) > 0.9f));
// MSL 5.02 Zoom
//			m_reticuleCamera->SetPerspective(near_clip_zoom, far_clip_main + (100.0f * (horizontal_fov_main - horizontal_fov_zoom)), horizontal_fov_zoom, (height_to_width_zoom));
			m_reticuleCamera->SetPerspective(near_clip_zoom, far_clip_main + (100.0f * (horizontal_fov_main - horizontal_fov_zoom)), horizontal_fov_zoom, (height_to_width_zoom*1.75));
			//sanghoon
//			float height=(1-g_fZoomMarginLR*2)*800 * height_to_width_zoom/600;
//			float tb_margin=(1-height)/2;
//			m_reticuleCamera->SetViewport(1-g_fZoomMarginLR,1-tb_margin, g_fZoomMarginLR, tb_margin);
// MSL 5.02 Zoom
			m_reticuleCamera->SetViewport(1-g_fZoomMarginLR, 1-g_fZoomMarginLR, g_fZoomMarginLR, g_fZoomMarginLR);

		}
	
	}

	vehicle->SyncMatrices(true);

  isAttachedVehicleAMech = vehicle->IsDerivedFrom(MechWarrior4::Mech::DefaultData);
  vehiclerootJointIndex = vehicle->FindChildMoverIndex("joint_ROOT");


  //
  // When a vehicle is attached we need to trigger the appropriate things to happen for the current camera mode
  //
  // Has to be one of the last things we do here once everything is attached
  //
	//
	//  Preserve the value from the last run.

	if (!observerMode && (g_nMR != 2))
	{
		RestorePreferredCameraPosition();
		SetCameraViewLevel(m_currentTargetReticuleCameraPosition);
		cameraDirty = true;
		SetCameraMode(cameraView);
		pointLockedEntityPartOffset = Stuff::Point3D::Identity;
	}	


	m_eFogType = NormalFogType; // for setting below water fog
	m_fltFogTransitionEndTime = 0.0f;
	m_maxSpeedTorsoCenterKPH = 0.0f;

	if (isAttachedVehicleAMech)
	{
		Mech * mech = Cast_Object(Mech *, vehicle);
		const Mech__GameModel * mechmodel = mech->GetGameModel();
		if (!Small_Enough(model->maxSpeedAboveMinTransToTorsoCenterKPH))
		{
			m_maxSpeedTorsoCenterKPH = model->maxSpeedAboveMinTransToTorsoCenterKPH + mechmodel->minStandTransitionSpeed*3.6f;
		}
	}

	targetStartTime = gos_GetElapsedTime();

	UpdateViews();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	VehicleInterface::IsZoomReticuleAllowed()
{
	if (MWGUIManager::GetInstance ())
		if (MWGUIManager::GetInstance ()->lightAmp->IsOn())
			return false;
	return ((cameraView == ExternalCameraTargetReticule || cameraView == InMechCameraView) && !cinemaPlaying);
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ShowZoomIfOn(bool fShowZoomIfShould)
{
	if (cinemaPlaying)
	{
		fShowZoomIfShould= false;
	}
	if (MWGUIManager::GetInstance ())
		if (MWGUIManager::GetInstance ()->lightAmp->IsOn())
			fShowZoomIfShould = false;

	if (fShowZoomIfShould && m_fZoomCurrentlyShowing ||
			!fShowZoomIfShould && !m_fZoomCurrentlyShowing)
	{
		return;
	}
	m_fZoomCurrentlyShowing = fShowZoomIfShould;
	if (fShowZoomIfShould && requestedZoomChange)
	{
		ShowZoom();
	}
	else if (!fShowZoomIfShould)
	{
		HideZoom();
// MSL 5.02 Zoom
		requestedZoomChange = false;
	}


}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ShowHUDIfOn(bool fShowHUDIfShould)
{
	if (cinemaPlaying)
	{
		fShowHUDIfShould = false;
	}
		if (fShowHUDIfShould == m_fHudCurrentlyShowing || !m_fHudShouldShow)
			return;

		m_fHudCurrentlyShowing = fShowHUDIfShould;

		if(MWGUIManager::GetInstance())
		{
			if (m_fHudCurrentlyShowing && fShowHUDIfShould)
			{
				MWGUIManager::GetInstance()->ReshowHud();
			}
			else
			{
				MWGUIManager::GetInstance()->Hide();
			}
		}

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ShowStatic(bool fShowStatic)
{
		if (m_fStaticView == fShowStatic)
		{
			if (fShowStatic)
			{
				if(MWGUIManager::GetInstance())
				{
					MWGUIManager::GetInstance()->AnimateStaticView();
				}
			}
			return;
		}

		m_fStaticView = fShowStatic;

		if(MWGUIManager::GetInstance())
		{
			if (fShowStatic)
			{
				MWGUIManager::GetInstance()->ShowStaticView();
			}
			else
			{
				MWGUIManager::GetInstance()->HideStaticView();
			}
		}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ResetInterface(int execution_mode)
{
	Check_Object(this);
	Check_Object(executionState);

	if (MWGUIManager::GetInstance())
	{
		Check_Object(MWGUIManager::GetInstance());
		MWGUIManager::GetInstance()->ClearGUIChain();
	}

	executionState->RequestState(execution_mode);

	if (MWGUIManager::GetInstance())
	{
		Check_Object(MWGUIManager::GetInstance());
		gos_PushCurrentHeap(Heap);
		MWGUIManager::GetInstance()->weaponManager->ClearWeaponsManager();
		gos_PopCurrentHeap();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWMover*
	VehicleInterface::GetEyeSite(Stuff::MString site_name)
{
	Check_Object(this);
	return vehicle->FindChildMover(site_name);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	ClearWeaponChain(Stuff::ChainOf<Weapon *>& chain)
{
	ChainIteratorOf<Weapon *> i(&chain);
	Weapon *weapon;
	while((weapon = i.ReadAndNext()) != NULL)
	{
		chain.Remove(weapon);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::SetTargetInfo()
{
	Check_Object(this);
	Check_Object(MWGUIManager::GetInstance());

	Entity *target_entity;
	target_entity = TraceToParent(targetQueryEntity.GetCurrent());

	MWGUIManager::GetInstance ()->SetReticuleTarget (target_entity);

// MSL 5.02 SubSystems
	bool fSetIFF = false;
	if (target_entity &&
		target_entity->IsDerivedFrom (Vehicle::DefaultData))
	{
		Vehicle *target_vehicle = Cast_Object(Vehicle *,target_entity);
		if (target_vehicle->DoesHaveIFF_Jammer())
			fSetIFF = true;
	}
	MWGUIManager::GetInstance()->SetReticleIFFJammer(fSetIFF);

	if(target_entity)
	{
		if(!target_entity->IsDerivedFrom(Map::DefaultData))
		{
			MWGUIManager::GetInstance()->SetReticleName(target_entity->GetObjectName());
			MWGUIManager::GetInstance()->SetReticleAlignment(target_entity->GetAlignment());	
		}
		else
		{
			MWGUIManager::GetInstance()->SetReticleName("");
			MWGUIManager::GetInstance()->SetReticleAlignment(Entity::DefaultAlignment);
		}
	}
	else
	{
		MWGUIManager::GetInstance()->SetReticleName("");
		MWGUIManager::GetInstance()->SetReticleAlignment(Entity::DefaultAlignment);
	}
	
	if (targetQuery.m_line != NULL)
		MWGUIManager::GetInstance()->SetReticleDistance(targetQuery.m_line->m_length);
	else
		MWGUIManager::GetInstance()->SetReticleDistance(0.0f);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::InitializeWeapons()
{
	Check_Object(this);
	Check_Object(vehicle);

	ClearWeaponChain(weaponGroup[0]);
	ClearWeaponChain(weaponGroup[1]);
	ClearWeaponChain(weaponGroup[2]);
	ClearWeaponChain(weaponGroup[3]);
	ClearWeaponChain(weaponGroup[4]);
	ClearWeaponChain(weaponGroup[5]);

	weaponIterator = new ChainIteratorOf<Weapon *>(&vehicle->weaponChain);
	Weapon *weapon;
	while((weapon = weaponIterator->ReadAndNext()) != NULL)
	{
		Check_Object(weapon);
		
		if(weapon->IsDerivedFrom(LongTomWeaponSubsystem::DefaultData))
		{
			longTom = Cast_Object(LongTomWeaponSubsystem *, weapon);
		}
		RGBAColor color;
		color.alpha = 1.0f;
		color.blue = 0.0f;
		color.red = 0.0f;
		color.green = 1.0f;

		MString weapon_name = weapon->GetGameModelResourceName();
		weapon_name.StripDirectory();
		weapon_name.StripExtension();

		if (MWGUIManager::GetInstance())
		{
			weapon->guiWeapon.Remove();
			weapon->guiWeapon.Add(MWGUIManager::GetInstance()->weaponManager->MakeGUIWeapon(
				weapon_name, 0.0f, &color, &weapon->encryptedAmmoCount, weapon));
			weapon->guiWeapon.GetCurrent()->Ready();
		}
		weapon->vehicleInterface = this;

		if(weapon->IsInWeaponGroup1())
			weaponGroup[0].Add(weapon);
		if(weapon->IsInWeaponGroup2())
			weaponGroup[1].Add(weapon);
		if(weapon->IsInWeaponGroup3())
			weaponGroup[2].Add(weapon);
		if(weapon->IsInWeaponGroup4())
			weaponGroup[3].Add(weapon);
		if(weapon->IsInWeaponGroup5())
			weaponGroup[4].Add(weapon);
		if(weapon->IsInWeaponGroup6())
			weaponGroup[5].Add(weapon);
	}
	weaponIterator->First();
	SetWeaponMode(GroupFireMode);
	selectedWeaponGroup = 1;

	for (int i=0; i<6; i++) {
		groupWeaponIterator[i] = new ChainIteratorOf<Weapon *>(&weaponGroup[i]);
		groupWeaponIterator[i]->First();
		groupWeaponMode[i] = GroupFireMode;
	}

	if (MWGUIManager::GetInstance())
	{
		HUDWeapon *hudweap;
		hudweap = Cast_Object (HUDWeapon *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_WEAPON));
		hudweap->SetupWeapons ();
		hudweap->SelectedWeaponGroup(selectedWeaponGroup);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::SetWeaponMode(int weapon_mode)
{
	Check_Object(this);

	weaponMode = weapon_mode;
	if (MWGUIManager::GetInstance())
	{
		Check_Object(MWGUIManager::GetInstance());
		MWGUIManager::GetInstance()->SetWeaponMode(weaponMode,weaponIterator->GetCurrent());
	}
/*
	switch(weaponMode)
	{
	case SingleFireMode:
	case ChainFireMode:
		if (MWGUIManager::GetInstance())
		{
			Check_Object(MWGUIManager::GetInstance());
			MWGUIManager::GetInstance()->SetWeaponMode(weaponMode,weaponIterator->GetCurrent());
		}
		break;
	default:
		if (MWGUIManager::GetInstance())
		{
			Check_Object(MWGUIManager::GetInstance());
			MWGUIManager::GetInstance()->SetWeaponMode(weaponMode,NULL);
		}
		break;
	}
*/
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ToggleGroupWeaponMode(int group)
{
	Check_Object(this);
	Verify(group >= 1 && group <= 6);

	switch(groupWeaponMode[group-1])
	{
	case GroupFireMode:
		groupWeaponMode[group-1] = ChainFireMode;
		if (MWGUIManager::GetInstance())
		{
			Check_Object(MWGUIManager::GetInstance());
			MWGUIManager::GetInstance()->SetWeaponMode(ChainFireMode,groupWeaponIterator[group-1]->GetCurrent());
		}
		break;
	case ChainFireMode:
		groupWeaponMode[group-1] = GroupFireMode;
		if (MWGUIManager::GetInstance())
		{
			Check_Object(MWGUIManager::GetInstance());
			MWGUIManager::GetInstance()->SetWeaponMode(GroupFireMode,NULL);
		}
		break;
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	VehicleInterface::RequestingToFire()
{
	Check_Object(this);

	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::FIRING) == false)
		return false;

	if (fireBlocked)
		return false;

	if(fireRequest)
		return true;
	if(group1FireRequest)
		return true;
	if(group2FireRequest)
		return true;
	if(group3FireRequest)
		return true;
	if(group4FireRequest)
		return true;
	if(group5FireRequest)
		return true;
	if(group6FireRequest)
		return true;

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::GroupFireGroup (Stuff::Time till,Stuff::ChainOf<Weapon *>& group)
{
	Check_Object(this);
	Check_Object(vehicle);

	Time time_now = gos_GetElapsedTime();
	Time target_time = time_now - targetStartTime;
	
	//
	// Since the weapons don't know anything about who fired them, or necessarily who their target is, we will lie about
	// how long the object was targetted so that the locks will behave in sync with the HUD indicator.
	//
	Entity *target = targetEntity.GetCurrent();
	Scalar multiplier = GetLockTimeMultiplier(vehicle, target);
	target_time = target_time / multiplier;

	ChainIteratorOf<Weapon *> iterator(&group);
	Weapon *weapon;
	while((weapon = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(weapon);
//		if (GetWeaponLockTime(weapon))
// MSL 5.04 Missile Code Change
		if(weapon->IsDerivedFrom(MissileWeapon::DefaultData))
		{
			if (GetWeaponLock(weapon) == true)
		{
			targetQuery.m_raySource = lockedTargetEntityPart.GetCurrent();

			MissileWeapon *missile_weapon;
			missile_weapon = Cast_Object(MissileWeapon *, weapon);
			const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
			Check_Object(model);

// MSL 5.05 Advance Mode
			if((weapon->GetClassID() == SSRMWeaponSubsystemClassID) && (GetWeaponLockSSRM() == false) && (m_AdvanceMode))
			{
				// DO NOT FIRE
			}
//			else if((targetQuery.m_line->m_length < model->minDistance) && (m_RadarMode != 3))
//			{
				// DO NOT FIRE
//			}
			else
			{
			if (weapon->ReadyToFire())
			{
				// mark this weapon	
				MarkLockedWeapon(weapon->GetWeaponID());
			}

			weapon->FireWeapon(&targetQuery, target_time, pointLockedEntityPartOffset);

			Verify (weapon->IsDerivedFrom(MissileWeapon::DefaultData));
			lockedWeaponCommand.AntiWeaponCount[weapon->GetWeaponID()] = missile_weapon->GetAMSNumber();
		}
		}
		else
		{
			targetQuery.m_raySource = targetEntityPart.GetCurrent();
			
// MSL 5.05 Advance Mode
			MWApplication *m_App;
			m_App = MWApplication::GetInstance ();
			m_AdvanceMode = m_App->GetLocalNetParams()->m_advancemodeOn;

			const Weapon__GameModel *model = weapon->GetGameModel();
			Check_Object(model);

// MSL 5.05 Advance Mode
				if((weapon->GetClassID() == SSRMWeaponSubsystemClassID) && (GetWeaponLockSSRM() == false) && (m_AdvanceMode))
				{
					// DO NOT FIRE
				}
//				else if((targetQuery.m_line->m_length < model->minDistance) && (m_RadarMode != 3))
//				{
					// DO NOT FIRE
//				}
				else
				{
					if (weapon->ReadyToFire())
					{
						MarkWeapon(weapon->GetWeaponID());
					}
					weapon->FireWeapon(&targetQuery, target_time, pointLockedEntityPartOffset);
				}
			}
		}
		else
		{
			targetQuery.m_raySource = targetEntityPart.GetCurrent();
			
//			MWApplication *m_App;
//			m_App = MWApplication::GetInstance ();
//			m_RadarMode = m_App->GetLocalNetParams()->m_radarMode;

			const Weapon__GameModel *model = weapon->GetGameModel();
			Check_Object(model);

// MSL 5.03 Min Distance
//			if((targetQuery.m_line->m_length < model->minDistance) && (m_RadarMode != 3))
//			{
				// Do Not Fire
//			}
//			else
//			{
			if (weapon->ReadyToFire())
			{
				// mark this weapon
				MarkWeapon(weapon->GetWeaponID());
			}
			weapon->FireWeapon(&targetQuery, target_time, pointLockedEntityPartOffset);
//			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::FireGroup(Time till, int group)
{
	switch(groupWeaponMode[group-1])
	{
	case GroupFireMode:
		GroupFireGroup (till,weaponGroup[group-1]);
		break;
	case ChainFireMode:
		ChainFireGroup (till,groupWeaponIterator[group-1]);
		break;
	}
	m_LastTimeFiredWeaponGroup[group-1] = (Stuff::Scalar)gos_GetElapsedTime();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
BOOL GetWeaponGroupID (Weapon &weapon, const int nGroupID)
{
	switch (nGroupID)
	{
	case 1:
		if (weapon.IsInWeaponGroup1 ())
			return TRUE;
		else 
			return FALSE;
		break;
	case 2:
		if (weapon.IsInWeaponGroup2 ())
			return TRUE;
		else 
			return FALSE;
		break;

	case 3:
		if (weapon.IsInWeaponGroup3 ())
			return TRUE;
		else 
			return FALSE;
		break;

	}


	return FALSE;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ChainFireGroup (Stuff::Time till,ChainIteratorOf<Weapon *> *groupWeaponIterator, int nGroupID)
{
	Check_Object(this);
	Check_Object(vehicle);

	Time time_now = gos_GetElapsedTime();
	Time target_time = time_now - targetStartTime;
	
	//
	// Since the weapons don't know anything about who fired them, or necessarily who their target is, we will lie about
	// how long the object was targetted so that the locks will behave in sync with the HUD indicator.
	//
	Entity *target = targetEntity.GetCurrent();
	Scalar multiplier = GetLockTimeMultiplier(vehicle, target);
	target_time = target_time / multiplier;

	Weapon *weapon;
	bool has_fired = false;
	int total_num_weapons, num_weapons;
	total_num_weapons = groupWeaponIterator->GetSize();
	num_weapons = 1;
	while((!has_fired)
		&& (num_weapons <= total_num_weapons))
	{
		weapon = groupWeaponIterator->GetCurrent();
		if(!weapon)
		{
			groupWeaponIterator->First();
			weapon = groupWeaponIterator->GetCurrent();
		}

		//
		// hyun begin

		groupWeaponIterator->ReadAndNext();

		if((groupWeaponIterator->GetCurrent()) == NULL) {
			groupWeaponIterator->First();
		}

// MSL 5.00
		BOOL bWeaponGroup1 = (group1FireRequest > 0) && GetWeaponGroupID (*weapon, 1);
		BOOL bWeaponGroup2 = (group2FireRequest > 0) && GetWeaponGroupID (*weapon, 2);
		BOOL bWeaponGroup3 = (group3FireRequest > 0) && GetWeaponGroupID (*weapon, 3);
		
		//
		// hyun end
		//

		num_weapons ++;
// MSL 5.00
// MSL 5.05 Chain Fire Timing (Bug Fix - causing graphic issues if less then 1.0)
		if(((bWeaponGroup1 == TRUE)||
			(bWeaponGroup2 == TRUE)||
			(bWeaponGroup3 == TRUE)) &&
			(weapon->ReadyToFire()) &&
			(GetTimeParameter(till) >= 1.0))
		{
//			if (GetWeaponLockTime(weapon))
// MSL 5.04 Missile Code Change
			if(weapon->IsDerivedFrom(MissileWeapon::DefaultData))
			{
				if (GetWeaponLock(weapon) == true)
				{
					targetQuery.m_raySource = lockedTargetEntityPart.GetCurrent();
				
					MissileWeapon *missile_weapon;
					missile_weapon = Cast_Object(MissileWeapon *, weapon);
					const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
					Check_Object(model);

// MSL 5.05 Advance Mode
					if((weapon->GetClassID() == SSRMWeaponSubsystemClassID) && (GetWeaponLockSSRM() == false) && (m_AdvanceMode))
					{
						// DO NOT FIRE
					}
//					else if((targetQuery.m_line->m_length < model->minDistance) && (m_RadarMode != 3))
//					{
						// DO NOT FIRE
//					}
					else
					{
						if (weapon->ReadyToFire())
						{
							// mark this weapon
							MarkLockedWeapon(weapon->GetWeaponID());
						}

						weapon->FireWeapon(&targetQuery, target_time, pointLockedEntityPartOffset);
				
						Verify (weapon->IsDerivedFrom(MissileWeapon::DefaultData));
						lockedWeaponCommand.AntiWeaponCount[weapon->GetWeaponID()] = missile_weapon->GetAMSNumber();
					}				
				}
				else
				{
					targetQuery.m_raySource = targetEntityPart.GetCurrent();

// MSL 5.05 Advance Mode
					MWApplication *m_App;
					m_App = MWApplication::GetInstance ();
					m_AdvanceMode = m_App->GetLocalNetParams()->m_advancemodeOn;

					const Weapon__GameModel *model = weapon->GetGameModel();
					Check_Object(model);

// MSL 5.05 Advance Mode
					if((weapon->GetClassID() == SSRMWeaponSubsystemClassID) && (GetWeaponLockSSRM() == false) && (m_AdvanceMode))
					{
						// DO NOT FIRE
					}
//					else if((targetQuery.m_line->m_length < model->minDistance) && (m_RadarMode != 3))
//					{
						// DO NOT FIRE
//					}
					else
					{
						if (weapon->ReadyToFire())
						{
							MarkWeapon(weapon->GetWeaponID());
						}
						weapon->FireWeapon(&targetQuery, target_time, pointLockedEntityPartOffset);
					}
				}
			}
			else
			{
				
				targetQuery.m_raySource = targetEntityPart.GetCurrent();
				
// MSL 5.05 Advance Mode (Disabled)
//				MWApplication *m_App;
//				m_App = MWApplication::GetInstance ();
//				m_AdvanceMode = m_App->GetLocalNetParams()->m_advancemodeOn;

				const Weapon__GameModel *model = weapon->GetGameModel();
				Check_Object(model);

// MSL 5.03 Min Distance
//				if((targetQuery.m_line->m_length < model->minDistance) && (m_RadarMode != 3))
//				{
					// Do Not Fire
//				}
//				else
//				{
				if (weapon->ReadyToFire())
				{
					// mark this weapon
					MarkWeapon(weapon->GetWeaponID());
				}
				weapon->FireWeapon(&targetQuery, target_time, pointLockedEntityPartOffset);
//				}
				
			}
			
			has_fired = true;
			
			lastParameterization = gos_GetElapsedTime();
			
			
			
		}
		//
		//-------------------------------------------------------
		//Must Check to see if we are the the next weapon in NULL
		//-------------------------------------------------------
		//
		weapon = groupWeaponIterator->GetCurrent();
		if(!weapon)
			groupWeaponIterator->First();
		
		weapon = groupWeaponIterator->GetCurrent();
		if (MWGUIManager::GetInstance())
		{
			Check_Object(MWGUIManager::GetInstance());
			MWGUIManager::GetInstance()->SetWeaponMode(weaponMode,weapon);
		}
		//if(weapon->guiWeapon)
		//	weapon->guiWeapon->Select();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::FireWeapon(Time till)
{
	Check_Object(this);
	Check_Object(vehicle);


	if (cinemaPlaying)
		return;

	if (observerMode)
	{
		// OBSERVER SWITCH MECHS
		return;
	}
		

	Time time_now = gos_GetElapsedTime();
	Time target_time = time_now - targetStartTime;
	//
	// Since the weapons don't know anything about who fired them, or necessarily who their target is, we will lie about
	// how long the object was targetted so that the locks will behave in sync with the HUD indicator.
	//
	Entity *target = targetEntity.GetCurrent();
	Scalar multiplier = GetLockTimeMultiplier(vehicle, target);
	target_time = target_time / multiplier;

	m_LastShootTime = time_now;

	SaveTarget();

    bool bChainfireNeeded = false;
    if (group1FireRequest > 0) {
        if (g_baChainFireMode[0])
            bChainfireNeeded = true;
        else
            FireGroup(till, 1);
    }
    if (group2FireRequest > 0) {
        if (g_baChainFireMode[1])
            bChainfireNeeded = true;
        else
            FireGroup(till, 2);
    }
    if (group3FireRequest > 0) {
        if (g_baChainFireMode[2])
            bChainfireNeeded = true;
        else
            FireGroup(till, 3);
    }
    if (bChainfireNeeded) {
        ChainFireGroup(till, weaponIterator);
    }
/*
	if (g_bChainFireMode == TRUE)
	{
		if(group1FireRequest > 0) {
			ChainFireGroup(till, weaponIterator); //, 1
		}

		if(group2FireRequest > 0) {
			ChainFireGroup(till, weaponIterator); //, 2
		}

		if(group3FireRequest > 0) {
			ChainFireGroup(till, weaponIterator); //, 3
		}
	}
	else
	{
		if(group1FireRequest > 0)
		{
			FireGroup(till, 1);
		}
		if(group2FireRequest > 0)
		{
			FireGroup(till, 2);
		}
		if(group3FireRequest > 0)
		{
			FireGroup(till, 3);
		}
		if(group4FireRequest > 0)
		{
			FireGroup(till, 4);
		}
		if(group5FireRequest > 0)
		{
			FireGroup(till, 5);
		}
		if(group6FireRequest > 0)
		{
			FireGroup(till, 6);
		}
	}
*/
	// fireRequest > 0 (Enter Key : None Used) : hyun
	if(fireRequest > 0)
	{
		switch(weaponMode)
		{
		case GroupFireMode:
			{
				FireGroup(till, selectedWeaponGroup);
				break;
			}
		case ChainFireMode:
			{
				ChainFireGroup(till, weaponIterator);
				break;
			}
		case SingleFireMode:
			{
				Weapon *weapon;
				weapon = weaponIterator->GetCurrent();
				Check_Object(weapon);
				
//				if (GetWeaponLockTime(weapon))
// MSL 5.04 Missile Code Change
				if(weapon->IsDerivedFrom(MissileWeapon::DefaultData))
				{
					if (GetWeaponLock(weapon) == true)
					{
						targetQuery.m_raySource = lockedTargetEntityPart.GetCurrent();

						MissileWeapon *missile_weapon;
						missile_weapon = Cast_Object(MissileWeapon *, weapon);
						const MissileWeapon__GameModel *model = missile_weapon->GetGameModel();
						Check_Object(model);

// MSL 5.05 Advance Mode
						if((weapon->GetClassID() == SSRMWeaponSubsystemClassID) && (GetWeaponLockSSRM() == false) && (m_AdvanceMode))
						{
							// DO NOT FIRE
						}
//						else if((targetQuery.m_line->m_length < model->minDistance) && (m_RadarMode != 3))
//						{
							// DO NOT FIRE
//						}
						else
						{
						if (weapon->ReadyToFire())
						{
							// mark this weapon
							MarkLockedWeapon(weapon->GetWeaponID());
						}
	
						weapon->FireWeapon(&targetQuery, target_time, pointLockedEntityPartOffset);

						Verify (weapon->IsDerivedFrom(MissileWeapon::DefaultData));
						lockedWeaponCommand.AntiWeaponCount[weapon->GetWeaponID()] = missile_weapon->GetAMSNumber();
						}
					}
					else
					{
						targetQuery.m_raySource = targetEntityPart.GetCurrent();

// MSL 5.05 Advance Mode
						MWApplication *m_App;
						m_App = MWApplication::GetInstance ();
						m_AdvanceMode = m_App->GetLocalNetParams()->m_advancemodeOn;

						const Weapon__GameModel *model = weapon->GetGameModel();
						Check_Object(model);

// MSL 5.05 Advance Mode
						if((weapon->GetClassID() == SSRMWeaponSubsystemClassID) && (GetWeaponLockSSRM() == false) && (m_AdvanceMode))
						{
							// DO NOT FIRE
						}
//						else if((targetQuery.m_line->m_length < model->minDistance) && (m_RadarMode != 3))
//						{
							// DO NOT FIRE
//						}
						else
						{
							if (weapon->ReadyToFire())
							{
								MarkWeapon(weapon->GetWeaponID());
							}
							weapon->FireWeapon(&targetQuery, target_time, pointLockedEntityPartOffset);
						}
					}
				}
				else
				{

					targetQuery.m_raySource = targetEntityPart.GetCurrent();

//					MWApplication *m_App;
//					m_App = MWApplication::GetInstance ();
//					m_RadarMode = m_App->GetLocalNetParams()->m_radarMode;

					const Weapon__GameModel *model = weapon->GetGameModel();
					Check_Object(model);

// MSL 5.03 Min Distance
//					if((targetQuery.m_line->m_length < model->minDistance) && (m_RadarMode != 3))
//					{
						// Do Not Fire
//					}
//					else
//					{
					if (weapon->ReadyToFire())
					{
						// mark this weapon
						MarkWeapon(weapon->GetWeaponID());
					}
					weapon->FireWeapon(&targetQuery, target_time, pointLockedEntityPartOffset);
//					}
				}
				break;
			}
		}
	}


	if (weaponCommandReady)
	{
		MWEntityManager::GetInstance()->PlayerWeaponUpdate(&weaponCommand);
	}

	if (lockedWeaponCommandReady)
	{
		MWEntityManager::GetInstance()->PlayerWeaponUpdate(&lockedWeaponCommand);
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::OverrideAutoCenterToTorsoMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == OverrideAutoCenterToTorsoMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (28, LAMP_OFF); // hyun
        return;
    }
	if(message->dataContents > 0)
	{
		g_pRIOMain->SetLampState (28, LAMP_BRIGHT); // hyun

		if (perminateTorsoMode == CenterLegsToTorso)
		{
			perminateTorsoMode = LeaveTorsoAlone;
		}
		else
		{
			perminateTorsoMode = CenterLegsToTorso;
		}
	}
	else
	{
		g_pRIOMain->SetLampState (28, LAMP_DEFAULT); // hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ChangeViewMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (IsObserving(true))
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ChangeViewMessageID);

	if(message->dataContents > 0)
	{
		if(cameraView != InMechCameraView)
		{
			SetCameraMode(InMechCameraView);
		}
		else
		{
			NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
			if (!params->m_allow3rdPerson)
				return;

			SetCameraMode(ExternalCameraAttachedView);
		}
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::JoyStickButton1MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == JoyStickButton1MessageID);

	if(message->dataContents > 0)
	{
	//	fireRequest = 1;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::GetUpCommandMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == GetUpCommandMessageID);

	if(message->dataContents > 0)
	{
//		if (executionState->GetState () == ExecutionStateEngine::AutoPilotState)
			executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);		
		QueCommand(VehicleCommand::GetUpCommand);
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ShutDownCommandMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ShutDownCommandMessageID);

	if(message->dataContents > 0)
	{
		if (executionState->GetState () == ExecutionStateEngine::FieldBaseState)
		{
			if (vehicle->vehicleShutDown == true)
			{
				ReactToEvent (POWER_UP);
				QueCommand(VehicleCommand::PowerDownCommand);
			}
		}
		else
		{
          if (g_nInputMode != _BIGINNER_MODE) {
            if (vehicle->vehicleShutDown == false) {
				ReactToEvent (SHUTDOWN);
            } else {
				ReactToEvent (POWER_UP);
            }

			QueCommand(VehicleCommand::PowerDownCommand);
          }
		}		

		g_pRIOMain->SetLampState (17, LAMP_BRIGHT);// hyun
	}
	else
	{
		g_pRIOMain->SetLampState (17, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ShutDownOnlyCommandMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ShutDownOnlyCommandMessageID);

	if(message->dataContents > 0)
	{
		if (executionState->GetState () != ExecutionStateEngine::FieldBaseState)
		{
			if (vehicle->vehicleShutDown == false) {
				ReactToEvent (SHUTDOWN);
				QueCommand(VehicleCommand::PowerDownCommand);
			}
		}
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::StartUpOnlyCommandMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == StartUpOnlyCommandMessageID);

	if(message->dataContents > 0)
	{
		if (vehicle->vehicleShutDown == true)
		{
			ReactToEvent (POWER_UP);
			QueCommand(VehicleCommand::PowerDownCommand);
		}
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CrouchCommandMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;
    if (g_nInputMode == _BIGINNER_MODE) {
        if (!vehicle->IsDerivedFrom(Mech::DefaultData))
            return;
	    Mech *mech = Cast_Object(Mech *, vehicle);
        if (!mech->IsCrouched ())
            return;
    }


	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == CrouchCommandMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (20, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{
		g_pRIOMain->SetLampState (20, LAMP_BRIGHT);// hyun
//		if (executionState->GetState () == ExecutionStateEngine::AutoPilotState)
			executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);		
		QueCommand(VehicleCommand::CrouchCommand);
    } else {
		g_pRIOMain->SetLampState (20, LAMP_DEFAULT);// hyun
    }
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::JumpCommandMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;
	if (executionState->GetState () == ExecutionStateEngine::FieldBaseState)
		return;
	if (executionState->GetState() != ExecutionStateEngine::AlwaysExecuteState)
		return;

	Check_Object(this);
	Check_Object(message);
	//jcem - Verify(message->messageID == JumpCommandMessageID);

    if (GetShutdownState()) {
        if (g_bJumpZoom)
	        g_pRIOMain->SetLampState (16, LAMP_OFF);// hyun
		g_pRIOMain->SetLampState (50, LAMP_OFF);
        g_pRIOMain->SetLampState (33, LAMP_OFF);// hyun
        g_pRIOMain->SetLampState (34, LAMP_OFF);// hyun
        return;
    }

	if((message->dataContents > 0) && (!vehicle->vehicleShutDown))
	{
			if (GetJumpJetState() > 0) {
                if (g_bJumpZoom)
				    g_pRIOMain->SetLampState (16, LAMP_BRIGHT);// hyun
				g_pRIOMain->SetLampState (33, LAMP_BRIGHT);
				g_pRIOMain->SetLampState (34, LAMP_BRIGHT);
			}
			
//		if (executionState->GetState () == ExecutionStateEngine::AutoPilotState)
			executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);		
		QueCommand(VehicleCommand::JumpCommand);
	}
	else
	{
		if (!GetShutdownState())
			if (GetJumpJetState() > 0) {
                if (g_bJumpZoom)
				    g_pRIOMain->SetLampState (16, LAMP_DEFAULT);// hyun
				g_pRIOMain->SetLampState (50, LAMP_DEFAULT);
				g_pRIOMain->SetLampState (33, LAMP_DEFAULT);// hyun
				g_pRIOMain->SetLampState (34, LAMP_DEFAULT);// hyun
			}
	}

	if(message->dataContents < 0)
	{
//		if (executionState->GetState () == ExecutionStateEngine::AutoPilotState)
			executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);		
		QueCommand(VehicleCommand::StopJumpCommand);
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::AnimDiagTest1MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	//if (Application::GetInstance()->networkingFlag)
	//	return;

#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == AnimDiagTest1MessageID);

	if(message->dataContents > 0)
	{
		vehicle->AnimDiagTest1();
	}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::AnimDiagTest2MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	//if (Application::GetInstance()->networkingFlag)
	//	return;

#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == AnimDiagTest2MessageID);

	if(message->dataContents > 0)
	{
		vehicle->AnimDiagTest2();
	}
#endif

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::AnimDiagTest3MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	//if (Application::GetInstance()->networkingFlag)
	//	return;

#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == AnimDiagTest3MessageID);

	if(message->dataContents > 0)
	{
		vehicle->AnimDiagTest3();
	}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::AnimDiagTest4MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	//if (Application::GetInstance()->networkingFlag)
	//	return;

#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == AnimDiagTest4MessageID);

	if(message->dataContents > 0)
	{
		vehicle->AnimDiagTest4();
	}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::AnimDiagTest5MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	//if (Application::GetInstance()->networkingFlag)
	//	return;

#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == AnimDiagTest5MessageID);

	if(message->dataContents > 0)
	{
		vehicle->AnimDiagTest5();
	}
#endif

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::AnimDiagTest6MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	//if (Application::GetInstance()->networkingFlag)
	//	return;

#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == AnimDiagTest6MessageID);

	if(message->dataContents > 0)
	{
		vehicle->AnimDiagTest6();
	}
#endif

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::AnimDiagTest7MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{

	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	//if (Application::GetInstance()->networkingFlag)
	//	return;

#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == AnimDiagTest7MessageID);

	if(message->dataContents > 0)
	{
		vehicle->AnimDiagTest7();
	}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::AnimDiagTest8MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	//if (Application::GetInstance()->networkingFlag)
	//	return;

#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == AnimDiagTest8MessageID);

	if(message->dataContents > 0)
	{
		vehicle->AnimDiagTest8();
	}
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::DebugTextMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
#ifdef LAB_ONLY
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == DebugTextMessageID);

	if(message->dataContents > 0)
	{
		Check_Object(GUITextManager::GetInstance());
		if(GUITextManager::GetInstance()->debugScreenVisible)
		{
			GUITextManager::GetInstance()->debugScreenVisible = false;
		}
		else
		{
			GUITextManager::GetInstance()->debugScreenVisible = true;
		}
	}
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::IssueLancemateCommand(Adept::ReceiverDataMessageOf<int> *message, int command)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;

	Check_Object(this);
	Check_Object(message);
	
	if (message->dataContents <= 0)
	{
		return;
	}

	QueCommand(command);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Lancemate1MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::Lancemate1Command);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Lancemate2MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::Lancemate2Command);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Lancemate3MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::Lancemate3Command);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateAllMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::LancemateAllCommand);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateAttackMyTargetMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::LancemateAttackMyTargetCommand);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateDefendMyTargetMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::LancemateDefendMyTargetCommand);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateFormOnMeMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::LancemateFormOnMeCommand);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateHoldFireMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::LancemateHoldFireCommand);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateGoToMyNavPointMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::LancemateGoToMyNavPointCommand);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateStopMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::LancemateStopCommand);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateShutdownMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::LancemateShutDownCommand);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateAttackNearestThreatMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::LancemateAttackNearestCommand);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateRepairAtNearestRepairBayMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	IssueLancemateCommand(message,VehicleCommand::LancemateRepairCommand);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LancemateCapturePlayersFlagMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	// THIS SPACE INTENTIONALLY LEFT BLANK -- CAPTURE-FLAG COMMAND NOT IMPLEMENTED, BY DESIGN.
}

#if 0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
VehicleInterface::LancemateCommandDisplay::LancemateCommandDisplay()
	: m_WhenToStopDisplayingText(0)
	, m_Object(0)
{
}

VehicleInterface::LancemateCommandDisplay::~LancemateCommandDisplay()
{
	if (m_Object != 0)
	{
		GUITextManager::GetInstance()->RemoveTextObject(m_Object);
		// delete here???
	}
}


void
	VehicleInterface::LancemateCommandDisplay::SetText(const std::string& text, Stuff::Scalar duration)
{
	if (GUITextManager::GetInstance() == 0)
	{
		return;
	}

	m_WhenToStopDisplayingText = gos_GetElapsedTime() + duration;
	if (m_Object != 0)
	{
		GUITextManager::GetInstance()->RemoveTextObject(m_Object);
		// delete here???
	}

	m_Object = GUITextManager::GetInstance()->MakeNewTextObject(text.c_str(),4,4);
	GUITextManager::GetInstance()->AddTextObject(m_Object);
}

void
	VehicleInterface::LancemateCommandDisplay::Update()
{
	if ((m_WhenToStopDisplayingText > 0) &&
		(gos_GetElapsedTime() > m_WhenToStopDisplayingText))
	{
		m_WhenToStopDisplayingText = 0;
		if (m_Object != 0)
		{
			GUITextManager::GetInstance()->RemoveTextObject(m_Object);
			// delete here???
		}
	}
}
#endif

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ChangeWeaponModeMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (IsObserving(true))
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ChangeWeaponModeMessageID);
/*
	if(message->dataContents > 0)
	{
		g_bChainFireMode = FALSE;

		if(weaponMode == ChainFireMode) {
			SetWeaponMode(GroupFireMode);
		} else if(weaponMode == GroupFireMode) {
			SetWeaponMode(ChainFireMode);

			g_bChainFireMode = TRUE;
		}

		if (!GetShutdownState())
			g_pRIOMain->SetLampState (7, LAMP_BRIGHT);// hyun
	}
	else
	{
		if (!GetShutdownState())
			g_pRIOMain->SetLampState (7, LAMP_DEFAULT);// hyun
	}
*/
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleGroupWeaponModeMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (IsObserving(true))
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ToggleGroupWeaponModeMessageID);

	if(message->dataContents > 0)
	{
		ToggleGroupWeaponMode(selectedWeaponGroup);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::WeaponGroup1MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	//if (vehicle->IsDestroyed())
	//	return;
	if (cinemaPlaying)
	{
		//if (message->dataContents <=0)
		//	group1FireRequest--;
		ProcessKeyUp(message, group1FireRequest);
		return;
	}
	if (observerMode)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == WeaponGroup1MessageID);

	if(message->dataContents > 0)
	{
		//hyun SetWeaponMode(GroupFireMode);
//		selectedWeaponGroup = 1;
		group1FireRequest ++;
	//	fireRequest ++;
	//	needFireRequestReset = true;
	}
	else
	{
	//	fireRequest --;
		group1FireRequest --;
	}

	Min_Clamp(group1FireRequest, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::WeaponGroup2MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	//if (vehicle->IsDestroyed())
	//	return;
	if (cinemaPlaying)
	{
		//if (message->dataContents <=0)
		//	group2FireRequest--;
		ProcessKeyUp(message, group2FireRequest);
		return;
	}
	if (observerMode)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == WeaponGroup2MessageID);

	if(message->dataContents > 0)
	{
		//hyun SetWeaponMode(GroupFireMode);
//		selectedWeaponGroup = 2;
		group2FireRequest ++;
//		fireRequest ++;
	}
	else
	{
//		fireRequest --;
		group2FireRequest --;
	}
	Min_Clamp(group2FireRequest, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::WeaponGroup3MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	//if (vehicle->IsDestroyed())
	//	return;
	if (cinemaPlaying)
	{
		//if (message->dataContents <=0)
		//	group3FireRequest--;
		ProcessKeyUp(message, group3FireRequest);
		return;
	}
	if (observerMode)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == WeaponGroup3MessageID);

	if(message->dataContents > 0)
	{
		//hyun SetWeaponMode(GroupFireMode);
//		selectedWeaponGroup = 3;
//		fireRequest ++;
		group3FireRequest ++;
	}
	else
	{
//		fireRequest --;
		group3FireRequest --;
	}

	Min_Clamp(group3FireRequest, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::WeaponGroup4MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	//if (vehicle->IsDestroyed())
	//	return;
	if (cinemaPlaying)
	{
		//if (message->dataContents <=0)
		//	group4FireRequest--;
		ProcessKeyUp(message, group4FireRequest);
		return;
	}
    if (IsObserving(true)) {
        if(message->dataContents > 0) {
            //s_fUseInter = -s_fUseInter;
            g_CamerashipParams.m_fDistStandard = -g_CamerashipParams.m_fDistStandard;

            MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());
            Stuff::Scalar fMT = mission->GetMissionTime();
            
            ClearFixedPoint();
            m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeStandard;
            m_pMechDying = m_pEnemy = NULL;
            m_curView = STATE_STD_OBSERVERMODE;
            m_curRange = NO_RANGE;
            m_pLastParent = NULL;
            ClearFixedPoint();
        }
		return;
    }

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == WeaponGroup4MessageID);

	if(message->dataContents > 0)
	{
		//hyun SetWeaponMode(GroupFireMode);
//		selectedWeaponGroup = 4;
//		fireRequest ++;
//		group4FireRequest ++;
	}
	else
	{
//		fireRequest --;
//		group4FireRequest --;
	}

	Min_Clamp(group4FireRequest, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::WeaponGroup5MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	//if (vehicle->IsDestroyed())
	//	return;
	if (cinemaPlaying)
	{
		//if (message->dataContents <=0)
		//	group5FireRequest--;
		ProcessKeyUp(message, group5FireRequest);
		return;
	}
    if (IsObserving(true)) {
    	if(message->dataContents > 0)
            g_bLockCurrentHero = !g_bLockCurrentHero;
		return;
    }

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == WeaponGroup5MessageID);

	if(message->dataContents > 0)
	{
		//hyun SetWeaponMode(GroupFireMode);
//		selectedWeaponGroup = 5;
//		fireRequest ++;
//		group5FireRequest ++;
	}
	else
	{
//		fireRequest --;
//		group5FireRequest --;
	}

	Min_Clamp(group5FireRequest, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::WeaponGroup6MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	//if (vehicle->IsDestroyed())
	//	return;
	if (cinemaPlaying)
	{
		//if (message->dataContents <=0)
		//	group6FireRequest--;
		ProcessKeyUp(message, group6FireRequest);
		return;
	}
    if (IsObserving(true)) {
    	if(message->dataContents > 0)
		{
            //g_CamerashipParams.m_fTimeScoringInterval = -g_CamerashipParams.m_fTimeScoringInterval;
			g_bFixedCamera = !g_bFixedCamera;
			Entity *parent = observingEntity.GetCurrent();
			if (parent)
				g_ptFixedCameraPos = parent->GetLocalToWorld();
		}
        return;
    }

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == WeaponGroup6MessageID);

	if(message->dataContents > 0)
	{
		//hyun SetWeaponMode(GroupFireMode);
		//group6FireRequest ++;
	}
	else
	{
		//group6FireRequest --;
	}

	Min_Clamp(group6FireRequest, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleGroup1MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
  if (1/*CTCL_IsConsoleX()*/) {
	if (message->dataContents > 0)
	{	
        if (g_nFiringMode) {
            g_baChainFireMode[0] = !g_baChainFireMode[0];
        } else {
	        if (weaponIterator)
	        {
		        Weapon* weapon = weaponIterator->GetCurrent();
		        if (weapon)
		        {
				    if (weapon->IsInWeaponGroup1())
				    {
                        //if (weapon->IsInWeaponGroup2() || weapon->IsInWeaponGroup3()) { // to prevent a weapon assigned to no-group
					    weapon->ClearGroup1();
					    weaponGroup[0].Remove(weapon);
                        //}
				    }
				    else
				    {
					    weapon->SetGroup1();
					    weaponGroup[0].Add(weapon);
				    }
			    }
            }
        }
    }
  } else {
	if ((weaponIterator) && ((weaponMode == SingleFireMode) || (weaponMode == ChainFireMode)))
	{
		Weapon* weapon = weaponIterator->GetCurrent();
		if (weapon)
		{
			if (message->dataContents > 0)
			{	
				if (weapon->IsInWeaponGroup1())
				{
                    //if (CTCL_IsNone() || (weapon->IsInWeaponGroup2() || weapon->IsInWeaponGroup3())) { // to prevent a weapon assigned to no-group
					weapon->ClearGroup1();
					weaponGroup[0].Remove(weapon);
                    //}
				}
				else
				{
					weapon->SetGroup1();
					weaponGroup[0].Add(weapon);
				}
			}
		}
	}
  }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void
	VehicleInterface::ToggleGroup2MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
  if (1/*CTCL_IsConsoleX()*/) {
	if (message->dataContents > 0)
	{	
        if (g_nFiringMode) {
            g_baChainFireMode[1] = !g_baChainFireMode[1];
        } else {
	        if (weaponIterator)
	        {
		        Weapon* weapon = weaponIterator->GetCurrent();
		        if (weapon)
		        {
				    if (weapon->IsInWeaponGroup2())
				    {
                        //if (weapon->IsInWeaponGroup1() || weapon->IsInWeaponGroup3()) { // to prevent a weapon assigned to no-group
					    weapon->ClearGroup2();
					    weaponGroup[1].Remove(weapon);
                        //}
				    }
				    else
				    {
					    weapon->SetGroup2();
					    weaponGroup[1].Add(weapon);
				    }
			    }
            }
        }
    }
  } else {
	if ((weaponIterator) && ((weaponMode == SingleFireMode) || (weaponMode == ChainFireMode)))
	{
		Weapon* weapon = weaponIterator->GetCurrent();
		if (weapon)
		{
			if (message->dataContents > 0)
			{	
				if (weapon->IsInWeaponGroup2())
				{
                    //if (CTCL_IsNone() || (weapon->IsInWeaponGroup1() || weapon->IsInWeaponGroup3())) { // to prevent a weapon assigned to no-group
					weapon->ClearGroup2();
					weaponGroup[1].Remove(weapon);
                    //}
				}
				else
				{
					weapon->SetGroup2();
					weaponGroup[1].Add(weapon);
				}
			}
		}
	}
  }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleGroup3MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
  if (1/*CTCL_IsConsoleX()*/) {
	if (message->dataContents > 0)
	{	
        if (g_nFiringMode) {
            g_baChainFireMode[2] = !g_baChainFireMode[2];
        } else {
	        if (weaponIterator)
	        {
		        Weapon* weapon = weaponIterator->GetCurrent();
		        if (weapon)
		        {
				    if (weapon->IsInWeaponGroup3())
				    {
                        //if (weapon->IsInWeaponGroup1() || weapon->IsInWeaponGroup2()) { // to prevent a weapon assigned to no-group
					    weapon->ClearGroup3();
					    weaponGroup[2].Remove(weapon);
                        //}
				    }
				    else
				    {
					    weapon->SetGroup3();
					    weaponGroup[2].Add(weapon);
				    }
			    }
            }
        }
    }
  } else {
	if ((weaponIterator) && ((weaponMode == SingleFireMode) || (weaponMode == ChainFireMode)))
	{
		Weapon* weapon = weaponIterator->GetCurrent();
		if (weapon)
		{
			if (message->dataContents > 0)
			{					
				if (weapon->IsInWeaponGroup3())
				{
                    //if (CTCL_IsNone() || (weapon->IsInWeaponGroup1() || weapon->IsInWeaponGroup2())) { // to prevent a weapon assigned to no-group
					weapon->ClearGroup3();
					weaponGroup[2].Remove(weapon);
                    //}
				}
				else
				{
					weapon->SetGroup3();
					weaponGroup[2].Add(weapon);
				}
			}
		}
	}
  }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleGroup4MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
    if (message->dataContents > 0) {
        g_bNoTOCKeys = !g_bNoTOCKeys;
    }
/*
	if ((weaponIterator) && ((weaponMode == SingleFireMode) || (weaponMode == ChainFireMode)))
	{
		Weapon* weapon = weaponIterator->GetCurrent();
		if (weapon)
		{
			if (message->dataContents > 0)
			{	
				if (weapon->IsInWeaponGroup4())
				{
					weapon->ClearGroup4();
					weaponGroup[3].Remove(weapon);
				}
				else
				{
					weapon->SetGroup4();
					weaponGroup[3].Add(weapon);
				}
			}
		}
	}
*/
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleGroup5MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
  if (1/*CTCL_IsConsoleX()*/) {
    if (message->dataContents > 0) {
        if (weaponIterator) {
            weaponIterator->ReadAndPrevious();
            if (!weaponIterator->GetCurrent()) {
                weaponIterator->Last();
            }
			if (MWGUIManager::GetInstance())
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->SetWeaponMode(weaponMode,weaponIterator->GetCurrent());
			}
        }
        g_pRIOMain->SetLampState(4, LAMP_BRIGHT);
    } else {
        g_pRIOMain->SetLampState(4, LAMP_DEFAULT);
    }
  } else {
	if ((weaponIterator) && ((weaponMode == SingleFireMode) || (weaponMode == ChainFireMode)))
	{
		Weapon* weapon = weaponIterator->GetCurrent();
		if (weapon)
		{
			if (message->dataContents > 0)
			{	
				if (weapon->IsInWeaponGroup5())
				{
					weapon->ClearGroup5();
					weaponGroup[4].Remove(weapon);
				}
				else
				{
					weapon->SetGroup5();
					weaponGroup[4].Add(weapon);
				}
			}
		}
	}
  }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleGroup6MessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
  if (1/*CTCL_IsConsoleX()*/) {
    if (message->dataContents > 0) {
        if (weaponIterator) {
            weaponIterator->ReadAndNext();
            if (!weaponIterator->GetCurrent()) {
                weaponIterator->First();
            }
			if (MWGUIManager::GetInstance())
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->SetWeaponMode(weaponMode,weaponIterator->GetCurrent());
			}
        }
        g_pRIOMain->SetLampState(5, LAMP_BRIGHT);
    } else {
        g_pRIOMain->SetLampState(5, LAMP_DEFAULT);
    }
  } else {
	if ((weaponIterator) && ((weaponMode == SingleFireMode) || (weaponMode == ChainFireMode)))
	{
		Weapon* weapon = weaponIterator->GetCurrent();
		if (weapon)
		{
			if (message->dataContents > 0)
			{	
				if (weapon->IsInWeaponGroup6())
				{
					weapon->ClearGroup6();
					weaponGroup[5].Remove(weapon);
				}
				else
				{
					weapon->SetGroup6();
					weaponGroup[5].Add(weapon);
				}
			}
		}
	}
  }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::NextWeaponGroupMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (IsObserving(true))
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == NextWeaponGroupMessageID);

	if(message->dataContents > 0)
	{
		if(weaponMode == SingleFireMode)
		{
			weaponIterator->ReadAndNext();
			Weapon *weapon;
			if((weapon = weaponIterator->GetCurrent()) == NULL)
				weaponIterator->First();
			if (MWGUIManager::GetInstance())
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->SetWeaponMode(weaponMode,weaponIterator->GetCurrent());
			}
		}
		else
		{
			bool group_found = false;
			int count = 0;
			while((!group_found) && (count < 6))
			{
				selectedWeaponGroup ++;
				if(selectedWeaponGroup > 6)
					selectedWeaponGroup = 1;
				switch(selectedWeaponGroup)
				{
				case 1:
					if(weaponGroup[0].GetSize() > 0)
						group_found = true;
					break;
				case 2:
					if(weaponGroup[1].GetSize() > 0)
						group_found = true;
					break;
				case 3:
					if(weaponGroup[2].GetSize() > 0)
						group_found = true;
					break;
				case 4:
					if(weaponGroup[3].GetSize() > 0)
						group_found = true;
					break;
				case 5:
					if(weaponGroup[4].GetSize() > 0)
						group_found = true;
					break;
				case 6:
					if(weaponGroup[5].GetSize() > 0)
						group_found = true;
					break;
				}
				count ++;
			}
			if (MWGUIManager::GetInstance())
			{
				HUDWeapon *hudweap;
				hudweap = Cast_Object (HUDWeapon *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_WEAPON));
				hudweap->SelectedWeaponGroup(selectedWeaponGroup);
			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::PreviousWeaponGroupMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (IsObserving(true))
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == PreviousWeaponGroupMessageID);

	if(message->dataContents > 0)
	{	
		if(weaponMode == SingleFireMode)
		{
			weaponIterator->Previous();
			Weapon *weapon;
			if((weapon = weaponIterator->GetCurrent()) == NULL)
				weaponIterator->Last();
			if (MWGUIManager::GetInstance())
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->SetWeaponMode(weaponMode,weaponIterator->GetCurrent());
			}
		}
		else
		{
			bool group_found = false;
			int count = 0;
			while((!group_found) && (count < 6))
			{
				selectedWeaponGroup --;
				if(selectedWeaponGroup < 1)
					selectedWeaponGroup = 6;
				switch(selectedWeaponGroup)
				{
				case 1:
					if(weaponGroup[0].GetSize() > 0)
						group_found = true;
					break;
				case 2:
					if(weaponGroup[1].GetSize() > 0)
						group_found = true;
					break;
				case 3:
					if(weaponGroup[2].GetSize() > 0)
						group_found = true;
					break;
				case 4:
					if(weaponGroup[3].GetSize() > 0)
						group_found = true;
					break;
				case 5:
					if(weaponGroup[4].GetSize() > 0)
						group_found = true;
					break;
				case 6:
					if(weaponGroup[5].GetSize() > 0)
						group_found = true;
					break;
				}
				count ++;
			}
			if (MWGUIManager::GetInstance())
			{
				HUDWeapon *hudweap;
				hudweap = Cast_Object (HUDWeapon *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_WEAPON));
				hudweap->SelectedWeaponGroup(selectedWeaponGroup);
			}
		}
	}
}

// MSL 5.03 Dump Ammo
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::DumpAmmoRound()
{
	if (1/*CTCL_IsConsoleX()*/)
	{
		if (weaponIterator)
		{
			Weapon* weapon = weaponIterator->GetCurrent();
			if (weapon)
			{
				if(weapon->DoesHaveAmmo())
				{
					weapon->UseAmmo();
					weapon->CreateEjectEffect();
					ReactToEvent (VehicleInterface::RECHARGE_PROJECTILE);
					// UnJam - Heat induced Jams
					if(weapon->executionState->GetState() == ProjectileWeapon::ExecutionStateEngine::HeatJammedState)
					{
						weapon->executionState->RequestState(ProjectileWeapon::ExecutionStateEngine::NeverExecuteState);
						if(weapon->guiWeapon.GetCurrent())
							weapon->guiWeapon.GetCurrent()->Ready();
					}
				}
			}
			else
			{
				// Do Nothing
			}
		}
	}
}

// MSL 5.03 Dump Ammo
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::DumpAmmoMagazine()
{
	if (1/*CTCL_IsConsoleX()*/)
	{
		if (weaponIterator)
		{
			Weapon* weapon = weaponIterator->GetCurrent();
			if (weapon)
			{
				if(weapon->DoesHaveAmmo())
				{
					if(weapon->executionState->GetState() == ProjectileWeapon::ExecutionStateEngine::AmmoFireState)
					{
						weapon->executionState->RequestState(ProjectileWeapon::ExecutionStateEngine::NeverExecuteState);
						if(weapon->guiWeapon.GetCurrent())
							weapon->guiWeapon.GetCurrent()->Ready();
					}
					int ammoamount = weapon->GetAmmoCount();
					for(int i = 0; i < ammoamount; i++)
					{
						weapon->CreateEjectEffect();
					}
					weapon->SetAmmoCount(0);
					ReactToEvent (VehicleInterface::AMMO_DUMPED);
				}
			}
			else
			{
				// Do Nothing
			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::NextWeaponMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (IsObserving(true))
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == NextWeaponMessageID);

	if(weaponIterator)
	{
		if(message->dataContents > 0)
		{
			// Assign Group Mode
			if (g_nAssignGroup1) {
				g_nAssignGroup1 = FALSE;
				ToggleGroup1MessageHandler (message);
				if (!GetShutdownState())					
					g_pRIOMain->SetLampState (2, LAMP_BRIGHT);
			}

			if (g_nAssignGroup2) {
				g_nAssignGroup2 = FALSE;
				ToggleGroup2MessageHandler (message);
				if (!GetShutdownState())
					g_pRIOMain->SetLampState (1, LAMP_BRIGHT);
			}
			
			if (g_nAssignGroup3) {
				g_nAssignGroup3 = FALSE;
				ToggleGroup3MessageHandler (message);
				if (!GetShutdownState())
					g_pRIOMain->SetLampState (0, LAMP_BRIGHT);
			}

			if (g_nAssignGroup1 == TRUE || 
				g_nAssignGroup2 == TRUE ||
				g_nAssignGroup3 == TRUE)
				return;

			// Next, Previos Mode
			if (g_nPrevWeapon) {
				weaponIterator->ReadAndPrevious ();
				if (!GetShutdownState())
					g_pRIOMain->SetLampState (4, LAMP_BRIGHT);
			}
			if (g_nNextWeapon) {
				weaponIterator->ReadAndNext ();
				if (!GetShutdownState())
					g_pRIOMain->SetLampState (5, LAMP_BRIGHT);
			}

			//weaponIterator->ReadAndNext();
			Weapon *weapon;

			if((weapon = weaponIterator->GetCurrent()) == NULL) {
				
				if (g_nPrevWeapon) {
					weaponIterator->Last();
				}
				if (g_nNextWeapon) {
					weaponIterator->First();
				}
				
				
				//weaponIterator->Last();
			}
			
			if (g_nPrevWeapon) {
				g_nPrevWeapon = FALSE;
			}
			if (g_nNextWeapon) {
				g_nNextWeapon = FALSE;
			}			


			if (MWGUIManager::GetInstance())
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->SetWeaponMode(weaponMode,weaponIterator->GetCurrent());
			}
		}
		else {
			if (!GetShutdownState()) {
				g_pRIOMain->SetLampState (0, LAMP_DEFAULT);
				g_pRIOMain->SetLampState (1, LAMP_DEFAULT);
				g_pRIOMain->SetLampState (2, LAMP_DEFAULT);
				g_pRIOMain->SetLampState (4, LAMP_DEFAULT);
				g_pRIOMain->SetLampState (5, LAMP_DEFAULT);
			}

		}
	}
	
	
	
	
/*
	if (g_bChainFireMode == FALSE)
		return;

	if(weaponIterator)
	{
		if(message->dataContents > 0)
		{
			// Assign Group Mode

			if (g_pRIOMain->m_AssignGroup1) {
				g_pRIOMain->m_AssignGroup1 = FALSE;
				ToggleGroup1MessageHandler (message);
				if (!GetShutdownState())					
					g_pRIOMain->SetLampState (2, LAMP_BRIGHT);
			}

			if (g_pRIOMain->m_AssignGroup2) {
				g_pRIOMain->m_AssignGroup2 = FALSE;
				ToggleGroup2MessageHandler (message);
				if (!GetShutdownState())
					g_pRIOMain->SetLampState (1, LAMP_BRIGHT);
			}
			
			if (g_pRIOMain->m_AssignGroup3) {
				g_pRIOMain->m_AssignGroup3 = FALSE;
				ToggleGroup3MessageHandler (message);
				if (!GetShutdownState())
					g_pRIOMain->SetLampState (0, LAMP_BRIGHT);
			}

			if (g_pRIOMain->m_AssignGroup1 == TRUE || 
				g_pRIOMain->m_AssignGroup2 == TRUE ||
				g_pRIOMain->m_AssignGroup3 == TRUE)
				return;

			// Next, Previos Mode
			if (g_pRIOMain->m_PrevWeapon) {
				weaponIterator->ReadAndPrevious ();
				if (!GetShutdownState())
					g_pRIOMain->SetLampState (4, LAMP_BRIGHT);
			}
			if (g_pRIOMain->m_NextWeapon) {
				weaponIterator->ReadAndNext ();
				if (!GetShutdownState())
					g_pRIOMain->SetLampState (5, LAMP_BRIGHT);
			}

			//weaponIterator->ReadAndNext();
			Weapon *weapon;

			if((weapon = weaponIterator->GetCurrent()) == NULL) {
				
				
				if (g_pRIOMain->m_PrevWeapon) {
					weaponIterator->Last();
				}
				if (g_pRIOMain->m_NextWeapon) {
					weaponIterator->First();
				}
				
				
				//weaponIterator->Last();
			}

			
			if (g_pRIOMain->m_PrevWeapon) {
				g_pRIOMain->m_PrevWeapon = FALSE;
			}
			if (g_pRIOMain->m_NextWeapon) {
				g_pRIOMain->m_NextWeapon = FALSE;
			}			


			if (MWGUIManager::GetInstance())
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->SetWeaponMode(weaponMode,weaponIterator->GetCurrent());
			}
		}
		else {
			if (!GetShutdownState()) {
				g_pRIOMain->SetLampState (0, LAMP_DEFAULT);
				g_pRIOMain->SetLampState (1, LAMP_DEFAULT);
				g_pRIOMain->SetLampState (2, LAMP_DEFAULT);
				g_pRIOMain->SetLampState (4, LAMP_DEFAULT);
				g_pRIOMain->SetLampState (5, LAMP_DEFAULT);
			}

		}
	}
*/
}
		
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::TopDownViewMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
		#ifdef LAB_ONLY

	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == TopDownViewMessageID);

	if(message->dataContents > 0)
	{	
		NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
		if (!params->m_allow3rdPerson)
			return;


		Stuff::Point3D loc = (Point3D) vehicle->GetLocalToWorld();
		loc.y = 200.0f;
		SetCameraMode(TopDownCameraView,&loc);
	}
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleSearchLightMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ToggleSearchLightMessageID);

    if (GetShutdownState()) {
        g_pRIOMain->SetLampState (27, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		if (g_SearchLight == TRUE)
			g_pRIOMain->SetLampState (27, LAMP_BRIGHT);// hyun
		QueCommand(VehicleCommand::ToggleSearchLightCommand);
	}
	else 
	{
		if (g_SearchLight == TRUE)
			g_pRIOMain->SetLampState (27, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::SelfDestructMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == SelfDestructMessageID);

	if(message->dataContents > 0)
	{	
		Check_Object(vehicle);
		
// begin of jcem
        int nState = GetEjectableState();
        if (nState == 1) {
// end of jcem
//		if (executionState->GetState () == ExecutionStateEngine::AutoPilotState)
			executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);	
//		PlayerAIRun(true);
		QueCommand(VehicleCommand::SelfDestructCommand);
        }
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleInvulnerableMessageHandler(
		Adept::ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ToggleInvulnerableMessageID);

	if(message->dataContents <= 0)
	{
		return;
	}
	if (Application::GetInstance()->networkingFlag)
		return;

	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

#ifdef LAB_ONLY
	if (vehicle)
	{
		if (DamageDispatch::GetGlobalInvulnerability() == true)
		{
			DamageDispatch::SetGlobalInvulnerability(false);
		}
		else
		{
			DamageDispatch::SetGlobalInvulnerability(true);
		}
	}
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::KillCurrentTargetMessageHandler(
		Adept::ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == KillCurrentTargetMessageID);

	if (message->dataContents <= 0)
	{
		return;
	}
	if (Application::GetInstance()->networkingFlag)
		return;

	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

#ifdef LAB_ONLY

	

	if ((vehicle != 0) &&
		(m_interfaceTarget.GetCurrent() != 0))
	{
		Entity::TakeDamageMessage damage_message(
			m_interfaceTarget.GetCurrent()->GetReplicatorID(),
			vehicle->GetReplicatorID(),
//			100000,
			0.0f,
// MSL 5.05 Advance Mode
			0,
			Adept::RammingDamageFromAboveType,
			Stuff::UnitVector3D(1,0,0),
			(Stuff::Point3D)m_interfaceTarget.GetCurrent()->GetLocalToWorld(),
			0,
			false,
			TakeDamageMessage::DefaultWeaponType
		);
		
		m_interfaceTarget.GetCurrent()->Receive(&damage_message);
	}
#endif

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::NextVehicleMessageHandler(
		Adept::ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == NextVehicleMessageID);

	if (message->dataContents <= 0)
	{
		return;
	}

	if (Application::GetInstance()->networkingFlag)
		return;

	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;
#ifdef LAB_ONLY
	DebugHelper::Activate_CameraAttachToNext();
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CoolantMessageHandler(
		Adept::ReceiverDataMessageOf<int> *message
	)
{

	NetMissionParameters::MWNetMissionParameters *params;
	if (MWApplication::GetInstance()->serverFlag)
		params = MWApplication::GetInstance()->GetLocalNetParams();
	else
		params = MWApplication::GetInstance()->GetServerNetParams();
	m_HeatMode = params->m_heatOn;

	if (!m_HeatMode)
		return;
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == CoolantMessageID);
	Check_Object(vehicle);

	if (message->dataContents > 0)
	{
		//if (!GetShutdownState())
		//if (g_bCool == TRUE) {
		//	g_pRIOMain->SetLampState (19, LAMP_BRIGHT);// hyun
		//}

		isCooling ++;
		if (isCooling == 1)
		{
			QueCommand(VehicleCommand::PressFlushCommand);
//			ReactToEvent (COOLANT_FLUSH_START);
		}
	}
	else
	{
		//if (!GetShutdownState())
		//if (g_bCool == TRUE) {
		//	g_pRIOMain->SetLampState (19, LAMP_DEFAULT);// hyun
		//} 

		isCooling --;
		if(isCooling <= 0)
		{
			isCooling = 0;
			
			QueCommand(VehicleCommand::ReleaseFlushCommand);
			ReactToEvent (COOLANT_FLUSH_STOP);
		}
	}	
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::SendChatMessage1MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == SendChatMessage1MessageID);

//	extern int g_bUseOrgJoy;
	//if (g_bUseOrgJoy)
//	{
		if(message->dataContents > 0)
		{	
			if (++g_nInputMode > _EXPERT_MODE)
				g_nInputMode = _BIGINNER_MODE;
			const char* pcszMode;
			if (g_nInputMode == _BIGINNER_MODE)
				pcszMode = "Beginner Mode";
			else if (g_nInputMode == _BIGINNER_MODE)
				pcszMode = "Veteran Mode";
			else
				pcszMode = "Expert Mode";

			Check_Object(Application::GetInstance());
			HUDChat *chat = Cast_Object (HUDChat *, MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT));
			if (chat) {
				chat->AddChat(pcszMode, Connection::Local->GetID(), MWApplication::SystemBroadcast, Connection::Local->GetID());
			}
		}
//	}
#ifdef LAB_ONLY
/*
	if(message->dataContents > 0)
	{	
		Check_Object(Application::GetInstance());
		MWApplication::GetInstance()->SendChat(
			Connection::Local->GetID(),
			MWApplication::AliveBroadcast,
			0,
			"Suck it Down! (tm)");
	}
*/
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::SendChatMessage2MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == SendChatMessage2MessageID);

	if(message->dataContents > 0)
	{	
		Check_Object(Application::GetInstance());
		MWApplication::GetInstance()->SendChat(
			Connection::Local->GetID(),
			MWApplication::AliveBroadcast,
			0,
			"Bite my shiney metal ass");	
	}
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::SendChatMessage3MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == SendChatMessage3MessageID);

	if(message->dataContents > 0)
	{	
		Check_Object(Application::GetInstance());
		MWApplication::GetInstance()->SendChat(
			Connection::Local->GetID(),
			MWApplication::AliveBroadcast,
			0,
			"Eat missile fan boy");
	}
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::SendChatMessage4MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == SendChatMessage4MessageID);

	if(message->dataContents > 0)
	{	
		Check_Object(Application::GetInstance());
		MWApplication::GetInstance()->SendChat(
			Connection::Local->GetID(),
			MWApplication::AliveBroadcast,
			0,
			"Blank Message");
	}
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleLightAmpMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ToggleLightAmpMessageID);

// MSL 5.02 headshot
	// If the hud is comprimised then Zoom and Light Amp is disabled.
	if (hudZoomDestroyed)
	{
		if(vehicle->DoesHaveLightAmp())
		{
			if(MWGUIManager::GetInstance())
			{
				if(MWGUIManager::GetInstance()->lightAmp->IsOn())
				{
					MWGUIManager::GetInstance()->HideLightAmplification();
					Mission::GetInstance()->ResetMissionLights();
				}
			}
		}
		VehicleInterface::ReactToEvent (VehicleInterface::ZOOM_FAIL); //play failure sound
		return; //do not allow LightAmp if hud is comprimised
	}


    if (GetShutdownState())
	{
        g_pRIOMain->SetLampState (26, LAMP_OFF);// hyun
		g_pRIOMain->SetLampState (48, LAMP_OFF); // Light Amp Lamp MFD
        return;
    }

	if(message->dataContents > 0)
	{	
		if(vehicle->DoesHaveLightAmp())
		{
			if(MWGUIManager::GetInstance())
			{
				if(MWGUIManager::GetInstance()->lightAmp->IsOn())
				{
					MWGUIManager::GetInstance()->HideLightAmplification();
					Mission::GetInstance()->ResetMissionLights();
				}
				else
				{
                    if (g_nInputMode == _BIGINNER_MODE)
					{
                        return;
                    }
					MWGUIManager::GetInstance()->ShowLightAmplification();
					Mission::GetInstance()->SetLightAmpMissionLights();
					ShowZoomIfOn (false);
					g_pRIOMain->SetLampState (26, LAMP_BRIGHT);// hyun
					if (!g_bJumpZoom)
					{
						if (g_pRIOMain->GetLampState (16) == LAMP_BRIGHT)
							g_pRIOMain->SetLampState (16, LAMP_DIM);
					}
				}
			}
		}
	}
	else
	{
		if(vehicle->DoesHaveLightAmp())
		{
			g_pRIOMain->SetLampState (26, LAMP_DEFAULT);// hyun
			g_pRIOMain->SetLampState (48, LAMP_DEFAULT); // Light Amp Lamp MFD
          }
		else
		{
			g_pRIOMain->SetLampState (26, LAMP_OFF);// hyun
			g_pRIOMain->SetLampState (48, LAMP_OFF); // Light Amp Lamp MFD
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleHUDMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
//	if (observerMode)
//		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ToggleHUDMessageID);

	if(message->dataContents > 0)
	{	
		if(MWGUIManager::GetInstance())
		{
			MWGUIManager::GetInstance()->Toggle();
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleMultiplayerScoringMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ToggleMultiplayerScoringMessageID);

	if(message->dataContents > 0)
	{	
		if(MWGUIManager::GetInstance())
		{
			if(Application::GetInstance()->networkingFlag)
			{
				MWGUIManager::GetInstance()->ShowScoring();
			}
		}
	}
	else if (message->dataContents < 0)
	{
		if(MWGUIManager::GetInstance())
		{
			if(Application::GetInstance()->networkingFlag)
			{
				MWGUIManager::GetInstance()->HideScoring();
			}
		}
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::NextNavPointMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::NAV_SWITCHING) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == NextNavPointMessageID);

    if (GetShutdownState()) {
        g_pRIOMain->SetLampState (38, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (38, LAMP_BRIGHT);// hyun
		m_selectedNavPoint.Remove();
		NavPoint *nav_point;
		if((nav_point = NavPoint::GetNextNavPoint()) != NULL)
			m_selectedNavPoint.Add(nav_point);
//		if (executionState->GetState() == ExecutionStateEngine::AutoPilotState)
		{
			if (!m_selectedNavPoint.GetCurrent ())
				executionState->RequestState (ExecutionStateEngine::AlwaysExecuteState);
			else
				//
				// This was causing a crash when GetCurrent() was NULL
				//
			{
			if (m_PlayerAI)
				m_PlayerAI->NavPoint (m_selectedNavPoint.GetCurrent ());
			}
		}
	}
	else
	{
		g_pRIOMain->SetLampState (38, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::PreviousNavPointMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::NAV_SWITCHING) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == PreviousNavPointMessageID);

    if (GetShutdownState()) {
        g_pRIOMain->SetLampState (37, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{
		g_pRIOMain->SetLampState (37, LAMP_BRIGHT);// hyun
		m_selectedNavPoint.Remove();
		NavPoint *nav_point;
		if((nav_point = NavPoint::GetPreviousNavPoint()) != NULL)
			m_selectedNavPoint.Add(nav_point);
//		if (executionState->GetState() == ExecutionStateEngine::AutoPilotState)
		{
			if (m_PlayerAI)
				m_PlayerAI->NavPoint (m_selectedNavPoint.GetCurrent ());

			if (!m_selectedNavPoint.GetCurrent ())
				executionState->RequestState (ExecutionStateEngine::AlwaysExecuteState);
		}
	}
	else
	{
		g_pRIOMain->SetLampState (37, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::NextEnemyMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::TARGET_SELECTION) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == NextEnemyMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (10, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (10, LAMP_BRIGHT);// hyun
		Entity *next_enemy = NULL;
		Sensor *sensor = vehicle->GetSensor();
		if(sensor)
		{
			next_enemy = sensor->GetNextEnemy(m_interfaceTarget.GetCurrent());
		}
		if (next_enemy)
			SetGUITarget(next_enemy);
	}
	else
	{
		g_pRIOMain->SetLampState (10, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::PreviousEnemyMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::TARGET_SELECTION) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == PreviousEnemyMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (9, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (9, LAMP_BRIGHT);// hyun
		Entity *next_enemy = NULL;
		Sensor *sensor = vehicle->GetSensor();
		if(sensor)
		{
			next_enemy = sensor->GetNextEnemy(m_interfaceTarget.GetCurrent(),true);
		}
		if (next_enemy)
			SetGUITarget(next_enemy);
	}
	else
	{
		g_pRIOMain->SetLampState (9, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::NearestEnemyMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::TARGET_SELECTION) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == NearestEnemyMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (11, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (11, LAMP_BRIGHT);// hyun
		m_interfaceTarget.Remove();
		m_targetCamera->SetScene(NULL);
		Entity *entity = NULL;
		Sensor *sensor = vehicle->GetSensor();
		if (sensor)
		{
			entity = sensor->GetNearestEnemy();
		}

		if (entity)
			SetGUITarget(entity);
	}
	else
	{
		g_pRIOMain->SetLampState (11, LAMP_DEFAULT);// hyun
	}
}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::DebugFastMessageHandler(ReceiverDataMessageOf<int> *message)
{
#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == DebugFastMessageID);
	
	if (Application::GetInstance()->networkingFlag)
			return;

	if(message->dataContents > 0)
	{	
		
		
		vehicle->m_DebugFast = !vehicle->m_DebugFast;
	}
#endif

}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::FreezeGameLogicMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{

#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == FreezeGameLogicMessageID);

	if(message->dataContents > 0)
	{	
    //
    // Toggle the state of the game logic
    //
    //CallDebuggerMenuItem("Debugger\\Options\\Disable gamelogic", gosMenu_Activated);
    // Using the menu item won't work since then we can't respond to another key press to unfreeze

    //
    // Try this instead.
    //
    DWORD key ;
    gos_KeyboardFlush();
    while (!gos_RunMainLoop())
    {
      key = gos_GetKey() & 255/*-32*/;
      if (key==',')
        break;
    }
	}
#endif
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ImmediateWeaponLockModeMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{

#ifdef LAB_ONLY
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ImmediateWeaponLockModeMessageID);

	if (Application::GetInstance()->networkingFlag)
			return;
	if (observerMode)
		return;

	if(message->dataContents > 0)
	{	
    m_fImmediateWeaponLockMode = ! m_fImmediateWeaponLockMode;
	}
#endif
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::SucceedMissionMessageHandler(ReceiverDataMessageOf<int> *message)
{
#ifdef LAB_ONLY
	if (!Application::GetInstance()->serverFlag)
		return;

	if (message->dataContents > 0)
	{
		MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
		Check_Object (mission);
		mission->SetEndMissionTime ((Stuff::Scalar) 2.0f);
		mission->EndMissionState (true);
	}
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ToggleDebugHudMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
#ifdef LAB_ONLY
	if (message->dataContents > 0)
	{
		MWGUIManager *gui;
		gui = MWGUIManager::GetInstance ();
		if (!gui)
			return;
		gui->ToggleDebug ();
	}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::FailMissionMessageHandler(ReceiverDataMessageOf<int> *message)
{
#ifdef LAB_ONLY
	if (!Application::GetInstance()->serverFlag)
		return;


	if (message->dataContents > 0)
	{
		MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
		Check_Object (mission);
		mission->SetEndMissionTime ((Stuff::Scalar) 2.0f);
		mission->EndMissionState (false);
	}
#endif
}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::TargetReticuleEnemyMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == TargetReticuleEnemyMessageID);

    if (GetShutdownState())
	{
		g_pRIOMain->SetLampState (8, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (8, LAMP_BRIGHT);// hyun

		Entity *target_entity;
		target_entity = targetQueryEntity.GetCurrent();
        if(target_entity)
		{
		    m_interfaceTarget.Remove();
		    m_targetCamera->SetScene(NULL);

            if (!target_entity->IsDerivedFrom(Map::DefaultData))
            {
			    target_entity = TraceToParent(target_entity);
			    m_interfaceTarget.Add(target_entity);
			    if (ShowTargetCamera ())
				    m_targetCamera->SetScene(target_entity->GetElement());
			    else
				    m_targetCamera->SetScene(NULL);
		    }
		    MWGUIManager::GetInstance()->SetNewTargetWindowEntity(target_entity);
        }
	}
	else
	{
		g_pRIOMain->SetLampState (8, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::NextFriendlyMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == NextFriendlyMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (14, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (14, LAMP_BRIGHT);// hyun
		Entity *next_friendly = NULL;
		Sensor *sensor = vehicle->GetSensor();
		if(sensor)
		{
			next_friendly = sensor->GetNextFriendly(m_interfaceTarget.GetCurrent());
		}

		if (next_friendly)
			SetGUITarget(next_friendly);
	}
	else
	{
		g_pRIOMain->SetLampState (14, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::PreviousFriendlyMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == PreviousFriendlyMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (13, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (13, LAMP_BRIGHT);// hyun
		Entity *next_friendly = NULL;
		Sensor *sensor = vehicle->GetSensor();
		if(sensor)
		{
			next_friendly = sensor->GetNextFriendly(m_interfaceTarget.GetCurrent(),true);
		}

		if (next_friendly)
			SetGUITarget(next_friendly);
	}
	else
	{
		g_pRIOMain->SetLampState (13, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::NearestFriendlyMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == NearestFriendlyMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (15, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (15, LAMP_BRIGHT);// hyun
        Entity *entity = NULL;
		Sensor *sensor = vehicle->GetSensor();
		if(sensor)
		{
			entity = sensor->GetNearestFriendly();
		}
		if (entity)
			SetGUITarget(entity);
	}
	else
	{
		g_pRIOMain->SetLampState (15, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::StartChatMessageHandler (Adept::ReceiverDataMessageOf<int> *message)
{
	if (cinemaPlaying)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == StartChatMessageID);

	if(message->dataContents > 0)
	{	
		EnterChatMode (false);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::StartTeamChatMessageHandler (Adept::ReceiverDataMessageOf<int> *message)
{
	if (cinemaPlaying)
		return;

	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == StartTeamChatMessageID);

	if(message->dataContents > 0)
	{	
		EnterChatMode (true);
	}
}

void VehicleInterface::ToggleMouseControlMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ToggleMouseControlMessageID);

	if(message->dataContents > 0)
	{	
		m_MouseEnable = !m_MouseEnable;
		ControlsManager::Instance->CenterMouse ();
	}
}

void VehicleInterface::ToggleLargeChatMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == ToggleLargeChatMessageID);

	if(message->dataContents > 0)
	{	
		if(MWApplication::GetInstance()->networkingFlag)
		{
			MWGUIManager *gui = MWGUIManager::GetInstance ();
			Verify (gui);
			HUDChat *chat = Cast_Object (HUDChat *,gui->Component (MWGUIManager::HUD_CHAT));
			chat->ToggleLargeSize ();
		}
	}
}

void VehicleInterface::OverrideShutdownMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == OverrideShutdownMessageID);

    //if (GetShutdownState()) {
    //    g_pRIOMain->SetLampState (18, LAMP_OFF);
    //    return;
    //}
	if(message->dataContents > 0)
	{	
		//if (!GetShutdownState())
		//	g_pRIOMain->SetLampState (18, LAMP_BRIGHT);// hyun
		HeatManager *heat;
		if (vehicle->IsDerivedFrom (Mech::DefaultData))
		{
			Mech *mech = Cast_Object (Mech *,vehicle);
			heat = mech->m_heatManager;
			if (heat)
			{
				heat->OverrideShutDown ();
			}
		}
	}
    else {
		//if (!GetShutdownState())
		//	g_pRIOMain->SetLampState (18, LAMP_DEFAULT);// hyun
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ShowMapMessageHandler (Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (IsObserving(true))
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == ShowMapMessageID);

	if(message->dataContents > 0)
	{	
		if(!vehicle->vehicleShutDown)
		{
			if(MWGUIManager::GetInstance())
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance ()->ToggleMap ();
			}
		}
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::RightMFDMessageHandler (Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (IsObserving(true))
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == RightMFDMessageID);

	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (52, LAMP_BRIGHT);// hyun
		if(MWGUIManager::GetInstance())
		{
			Check_Object(MWGUIManager::GetInstance());
			MWGUIManager *gui = MWGUIManager::GetInstance ();
			HUDDamage *hud = Cast_Object (HUDDamage *,gui->Component (MWGUIManager::HUD_DAMAGE));
			hud->ToggleMode ();
		}
	}
	else
	{
		g_pRIOMain->SetLampState (52, LAMP_DEFAULT);// hyun
	}
}

bool VehicleInterface::ShowTargetCamera (void)
{
	if(MWGUIManager::GetInstance())
	{
		Check_Object(MWGUIManager::GetInstance());
		MWGUIManager *gui = MWGUIManager::GetInstance ();
		HUDTargetDamage *hud = Cast_Object (HUDTargetDamage *,gui->Component (MWGUIManager::HUD_TARGETDAMAGE));
		return hud->ShowCamera ();
	}
	return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::LeftMFDMessageHandler (Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (IsObserving(true))
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == LeftMFDMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (12, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (12, LAMP_BRIGHT);// hyun
		if(MWGUIManager::GetInstance())
		{
			Check_Object(MWGUIManager::GetInstance());
			MWGUIManager *gui = MWGUIManager::GetInstance ();
			HUDTargetDamage *hud = Cast_Object (HUDTargetDamage *,gui->Component (MWGUIManager::HUD_TARGETDAMAGE));
			if (hud->ToggleMode ())
			{
				m_targetCamera->SetScene (NULL);
			}
			else
			{
				if (m_interfaceTarget.GetCurrent ())
				{
					m_targetCamera->SetScene(m_interfaceTarget.GetCurrent ()->GetElement());
				}
			}
		}
	}
	else
	{
		g_pRIOMain->SetLampState (12, LAMP_DEFAULT);// hyun
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ToggleRadarPassiveMessageHandler (Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == ToggleRadarPassiveMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (25, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (25, LAMP_BRIGHT);// hyun
		if(!vehicle->vehicleShutDown)
		{
			if(MWGUIManager::GetInstance())
			{
				Check_Object(MWGUIManager::GetInstance());
				Sensor *sensor;
				sensor = vehicle->GetSensor();
				if(sensor)
				{
					switch (sensor->GetSensorMode ())
					{
						case Sensor::ActiveMode:
                          if (g_nInputMode != _BIGINNER_MODE) {
							sensor->SetSensorMode(Sensor::PassiveMode, vehicle->DoesHaveBeagle());
							ReactToEvent (RADAR_OFF);
							GUIRadarManager *radar;
							radar = Cast_Object (GUIRadarManager *,MWGUIManager::GetInstance()->Component (MWGUIManager::HUD_RADAR));
							radar->SetRange(sensor->GetMaxRange ());
                          }
							break;
						case Sensor::PassiveMode:
							sensor->SetSensorMode(Sensor::ActiveMode, vehicle->DoesHaveBeagle());
							ReactToEvent (RADAR_ON);
							GUIRadarManager *radarhud;
							radarhud = Cast_Object (GUIRadarManager *,MWGUIManager::GetInstance()->Component (MWGUIManager::HUD_RADAR));
							radarhud->SetRange(sensor->GetMaxRange ());
							break;
						case Sensor::ShutdownMode:
							return;
							break;

					}
				}
			}
		}
	}
    else
	{
		g_pRIOMain->SetLampState (25, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ToggleRadarRangeMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == ToggleRadarRangeMessageID);

    if (GetShutdownState()) {
		g_pRIOMain->SetLampState (24, LAMP_OFF);// hyun
        return;
    }
	if(message->dataContents > 0)
	{	
		g_pRIOMain->SetLampState (24, LAMP_BRIGHT);// hyun
		if(!vehicle->vehicleShutDown)
		{
			if(MWGUIManager::GetInstance())
			{
				Check_Object(MWGUIManager::GetInstance());
				Sensor *sensor;
				sensor = vehicle->GetSensor();
				if(sensor)
				{
					Scalar range = sensor->GetMaxRange();
					ReactToEvent (RADAR_RANGE_CHANGE);
					GUIRadarManager *radar;
					radar = Cast_Object (GUIRadarManager *,MWGUIManager::GetInstance()->Component (MWGUIManager::HUD_RADAR));
					switch (sensor->GetSensorMode ())
					{
					case Sensor::ActiveMode:
						if(range == radar->GetRange())
							radar->SetRange(400.0f);
						else
							radar->SetRange(range);
						break;
					case Sensor::PassiveMode:
					case Sensor::ShutdownMode:
						break;
					}
				}
			}
		}
	}
    else
	{
		g_pRIOMain->SetLampState (24, LAMP_DEFAULT);// hyun
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ForwardMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, forwardCommand);
		return;
	}

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == ForwardMessageID);

	if(message->dataContents > 0)
	{	
		forwardCommand++;
		m_LastForwardCommand = gos_GetElapsedTime ()-0.05f;
	}
	else
	{
		forwardCommand--;
	}

	Min_Clamp(forwardCommand, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::BackwardMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, backwardCommand);
		return;
	}

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == BackwardMessageID);

	if(message->dataContents > 0)
	{	
		backwardCommand++;
		m_LastBackwardCommand = gos_GetElapsedTime ()-0.05f;
	}
	else
	{
		backwardCommand--;
	}

	Min_Clamp(backwardCommand, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::RotateLeftMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, rotateLeftCommand);
		return;
	}

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == RotateLeftMessageID);

	if(message->dataContents > 0)
	{	
		rotateLeftCommand++;
	}
	else
	{
		rotateLeftCommand--;
	}

	Min_Clamp(rotateLeftCommand, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::RotateRightMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, rotateRightCommand);
		return;
	}

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == RotateRightMessageID);

	if(message->dataContents > 0)
	{
		rotateRightCommand++;
	}
	else
	{
		rotateRightCommand--;
	}

	Min_Clamp(rotateRightCommand, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::OriginMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, originCommand);
		return;
	}

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == OriginMessageID);

	if(message->dataContents > 0)
	{
		originCommand++;
	}
	else
	{
		originCommand--;
	}

	Min_Clamp(originCommand, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::TorsoTwistLeftMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, torsoTwistLeft);
		return;
	}

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == TorsoTwistLeftMessageID);

	if(message->dataContents > 0)
	{	
		torsoTwistLeft++;
	}
	else
	{
		torsoTwistLeft--;
	}

	Min_Clamp(torsoTwistLeft, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::TorsoTwistRightMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, torsoTwistRight);
		return;
	}

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == TorsoTwistRightMessageID);

	if(message->dataContents > 0)
	{
		torsoTwistRight++;
	}
	else
	{
		torsoTwistRight--;
	}

	Min_Clamp(torsoTwistRight, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::PitchUpMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, pitchDown);
		return;
	}

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == PitchUpMessageID);

	if(message->dataContents > 0)
	{
		pitchDown++;
	}
	else
	{
		pitchDown--;
	}

	Min_Clamp(pitchDown, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::PitchDownMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, pitchUp);
		return;
	}

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == PitchDownMessageID);

	if(message->dataContents > 0)
	{	
		pitchUp++;
	}
	else
	{
		pitchUp--;
	}

	Min_Clamp(pitchUp, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReverseMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == ReverseMessageID);

	if(message->dataContents > 0)
	{	
		reverseToggle = !reverseToggle;
//    reverseCommand++;
  }
/*
  else
  {
    reverseCommand--;
  }
*/	

//	Min_Clamp(reverseCommand, 0);
//	reverseToggle = (reverseCommand > 0);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::FireWeaponMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	//if (vehicle->IsDestroyed())
	//	return;
	if (cinemaPlaying)
	{
		//if (message->dataContents <=0)
		//	fireRequest--;
		ProcessKeyUp(message, fireRequest);
		return;
	}
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::FIRING) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == FireWeaponMessageID);

	if(message->dataContents > 0)
	{	
		fireRequest++;
	}
	else
	{
		fireRequest--;
	}

	Min_Clamp(fireRequest, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::MouseTorsoToggleMessageHandler(ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MouseTorsoToggleMessageID);

	curMouseX = 0;
	curMouseY = 0;
	m_ChangeMouseTorsoThisFrame = true;
	if(message->dataContents > 0)
	{	
		mouseTorsoToggle = false;
	}
	else
	{
		mouseTorsoToggle = true;
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::MouseDeltaToggleMessageHandler(ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MouseDeltaToggleMessageID);

	if(message->dataContents > 0)
	{	
		mouseDeltaToggle = !mouseDeltaToggle;
		if (!mouseDeltaToggle)
		{
			Check_Object (ControlsManager::Instance);
			ControlsManager::Instance->CenterMouse ();
		}
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LookLeftMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, lookLeft);
		return;
	}
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == LookLeftMessageID);

	if(message->dataContents > 0)
	{
		lookLeft++;
	}
	else
	{
		lookLeft--;
	}

	Min_Clamp(lookLeft, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LookRightMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, lookRight);
		return;
	}
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == LookRightMessageID);

	if(message->dataContents > 0)
	{
		lookRight ++;
	}
	else
	{
		lookRight--;
	}

	Min_Clamp(lookRight, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LookBackMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, lookBack);
		return;
	}
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == LookBackMessageID);

	if(message->dataContents > 0)
	{
		lookBack ++;
	}
	else
	{
		lookBack--;
	}

	Min_Clamp(lookBack, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::LookDownMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, lookDown);
		return;
	}
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::MISC) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == LookDownMessageID);

	if(message->dataContents > 0)
	{
		lookDown ++;
	}
	else
	{
		lookDown--;
	}

	Min_Clamp(lookDown, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraDetachMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
		#ifdef LAB_ONLY

	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::VIEW_MODES) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraDetachMessageID);

	if(message->dataContents > 0)
	{
		NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
		if (!params->m_allow3rdPerson)
			return;


		if (cameraView != ExternalCameraDetachedView)
		{
			SetCameraMode(ExternalCameraDetachedView);
		}
	}
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraResetMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
			#ifdef LAB_ONLY

	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::VIEW_MODES) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraResetMessageID);

	if(message->dataContents > 0)
	{	
		NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
		if (!params->m_allow3rdPerson)
			return;


		const GameModel *model = GetGameModel();
		Check_Object(model);
		SetCameraMode(ExternalCameraAttachedView,*model);
	}
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraTerrainMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
			#ifdef LAB_ONLY

	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::VIEW_MODES) == false)
		return;

	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraTerrainMessageID);

	if(message->dataContents > 0)
	{
		NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
		if (!params->m_allow3rdPerson)
			return;

		const GameModel *model = GetGameModel();
		Check_Object(model);
		SetCameraMode(ExternalCameraTerrainFollowView,*model);
	}

	#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraTargetReticuleMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (observerMode)
		return;
	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::VIEW_MODES) == false)
		return;


	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraTargetReticuleMessageID);

	if(message->dataContents > 0)
	{
	  //
	  // If we are already in this view, up the current default view position, and load it.
	  //
		int oldlevel = m_currentTargetReticuleCameraPosition;
		if (!SetCameraViewLevel((m_currentTargetReticuleCameraPosition + 1) % (C_MAXEXTERNALTARGETRETICULEVALUE + 1)))
			m_currentTargetReticuleCameraPosition = oldlevel;
		else
			SetPreferredCameraPosition(m_currentTargetReticuleCameraPosition);
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool VehicleInterface::SetCameraViewLevel(int level)
{
	Verify(level >= 0);
	Verify(level <= C_MAXEXTERNALTARGETRETICULEVALUE);

	m_currentTargetReticuleCameraPosition = level;

	if (level == C_MAXEXTERNALTARGETRETICULEVALUE)
	{
		SetCameraMode(InMechCameraView);
		return true;
	}

	if (MWApplication::GetInstance()->networkingFlag)
	{
		NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
		if (!params->m_allow3rdPerson)
			return false;
	}

	CalculatePresetsForExternalTargetReticule();
	SetCameraMode(ExternalCameraTargetReticule);
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	VehicleInterface::GetCameraViewLevel() const
{
	return (m_currentTargetReticuleCameraPosition);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::CalculatePresetsForExternalTargetReticule()
{
	Check_Object(this);
	Check_Object(vehicle);

  //
  // offset of 1 since these start at 2nd index in array
  // arrays won't work with the macros for reading the data so I have to have them in separate variables
  // TODO: This may have to change to work with other mechs if defaults can't be found that work with all of
  //       them correctly
  CollisionVolume *cv = NULL;;
  MechWarrior4::Torso * torso = vehicle->GetTorso();
	if(torso) // if not, then torso_local_to_vehicle is just "Identity"
  {
    cv = torso->GetSolidVolume();
  }
  if (!cv)
  {
    cv = vehicle->GetSolidVolume();
  }

  Stuff::Point3D cameraOffsetModifier;

  ExtentBox collisionBox;
  if (cv)
  {
		//
		// Don't need to apply localtoparent explicitely here since it's done in the extent box constructor.
		//
    ExtentBox temp(cv->m_localSpaceBounds);
    collisionBox =  temp;
    externalCameraOffsetStartMinZ = collisionBox.minZ - 0.25f; // if we don't end up with some other way to find this...
  }
  else
  {
    externalCameraOffsetStartMinZ = -2.0f; // if we don't end up with some other way to find this...
    collisionBox.maxX = 0.0f;
    collisionBox.maxY = 0.0f;
    collisionBox.maxZ = 0.0f;
    collisionBox.minX = 0.0f;
    collisionBox.minY = 0.0f;
    collisionBox.minZ = 0.0f;
  }
	const GameModel *model = GetGameModel();
	Check_Object(model);
  switch (m_currentTargetReticuleCameraPosition)
  {
  case 0:
    cameraOffset = model->cameraExternalTargetStartOffset1;
//      cameraOffset.x += collisionBox.minX;
    cameraOffset.y += collisionBox.maxY;
    break;
  case 1:
    cameraOffset = model->cameraExternalTargetStartOffset2;
    cameraOffset.x += collisionBox.minX;
    cameraOffset.y += collisionBox.maxY;
    break;
  case 2:
    cameraOffset = model->cameraExternalTargetStartOffset3;
    cameraOffset.x += collisionBox.maxX;
    cameraOffset.y += collisionBox.maxY;
    break;
  // case C_MAXEXTERNALTARGETRETICULEVALUE: // internal camera view
  }
  cameraOffset.z -= collisionBox.minZ;
	if (Application::GetInstance()->IsCampCOOP()) {
		cameraOffset.z -= 5.0;
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraPitchUpMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraPitchUpMessageID);

	if(message->dataContents > 0)
	{	
		cameraPitchUp++;
	}
	else
	{
		cameraPitchUp--;
	}

	Min_Clamp(cameraPitchUp, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraPitchDownMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraPitchDownMessageID);

	if(message->dataContents > 0)
	{	
		cameraPitchDown++;
	}
	else
	{
		cameraPitchDown--;
	}

	Min_Clamp(cameraPitchDown, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraRollRightMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraRollRightMessageID);
#ifndef LAB_ONLY
	if (!observerMode)
		return;
#endif


	if(message->dataContents > 0)
	{
		cameraRollRight++;
	}
	else
	{
		cameraRollRight--;
	}

	Min_Clamp(cameraRollRight, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraRollLeftMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraRollLeftMessageID);
	
#ifndef LAB_ONLY
	if (!observerMode)
		return;
#endif

	if(message->dataContents > 0)
	{	
		cameraRollLeft++;
	}
	else
	{
		cameraRollLeft--;
	}

	Min_Clamp(cameraRollLeft, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraYawLeftMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraYawLeftMessageID);
#ifndef LAB_ONLY
	if (!observerMode)
		return;
#endif

	if(message->dataContents > 0)
	{	
		cameraYawLeft++;
	}
	else
	{
		cameraYawLeft--;
	}

	Min_Clamp(cameraYawLeft, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraYawRightMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraYawRightMessageID);
#ifndef LAB_ONLY
	if (!observerMode)
		return;
#endif

	if(message->dataContents > 0)
	{	
		cameraYawRight++;
	}
	else
	{
		cameraYawRight--;
	}

	Min_Clamp(cameraYawRight, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraPanUpMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraPanUpMessageID);
#ifndef LAB_ONLY
	if (!observerMode)
		return;
#endif

	if(message->dataContents > 0)
	{	
		cameraPanUp++;
	}
	else
	{
		cameraPanUp--;
	}
	Min_Clamp(cameraPanUp, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraPanDownMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraPanDownMessageID);
#ifndef LAB_ONLY
	if (!observerMode)
		return;
#endif

	if(message->dataContents > 0)
	{	
		cameraPanDown++;
	}
	else
	{
		cameraPanDown--;
	}

	Min_Clamp(cameraPanDown, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraPanLeftMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraPanLeftMessageID);
#ifndef LAB_ONLY
	if (!observerMode)
		return;
#endif

	if(message->dataContents > 0)
	{	
		cameraPanLeft++;
	}
	else
	{
		cameraPanLeft--;
	}

	Min_Clamp(cameraPanLeft, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraPanRightMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraPanRightMessageID);
#ifndef LAB_ONLY
	if (!observerMode)
		return;
#endif

	if(message->dataContents > 0)
	{	
		cameraPanRight++;
	}
	else
	{
		cameraPanRight--;
	}

	Min_Clamp(cameraPanRight, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraZoomInMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraZoomInMessageID);
#ifndef LAB_ONLY
	if (!observerMode)
		return;
#endif

	if(message->dataContents > 0)
	{	
		cameraZoomIn++;
	}
	else
	{
		cameraZoomIn--;
	}

	Min_Clamp(cameraZoomIn, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CameraZoomOutMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CameraZoomOutMessageID);
#ifndef LAB_ONLY
	if (!observerMode)
		return;
#endif

	if(message->dataContents > 0)
	{	
		cameraZoomOut++;
	}
	else
	{
		cameraZoomOut--;
	}

	Min_Clamp(cameraZoomOut, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::MFDComm1MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MFDComm1MessageID);

	g_pRIOMain->Redf_ThrottleMessageHandler(*this, 0, message->dataContents);
	return;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::MFDComm2MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MFDComm2MessageID);

	g_pRIOMain->Redf_ThrottleMessageHandler(*this, 1, message->dataContents);
	return;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::MFDComm3MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MFDComm3MessageID);

	g_pRIOMain->Redf_ThrottleMessageHandler(*this, 2, message->dataContents);
	return;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::MFDComm4MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MFDComm4MessageID);

	g_pRIOMain->Redf_ThrottleMessageHandler(*this, 3, message->dataContents);
	return;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::MFDComm5MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MFDComm5MessageID);

	g_pRIOMain->Redf_ThrottleMessageHandler(*this, 4, message->dataContents);
	return;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::MFDComm6MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MFDComm6MessageID);

	g_pRIOMain->Redf_ThrottleMessageHandler(*this, 5, message->dataContents);
	return;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::MFDComm7MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MFDComm7MessageID);

	g_pRIOMain->Redf_ThrottleMessageHandler(*this, 6, message->dataContents);
	return;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::MFDComm8MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MFDComm8MessageID);

	g_pRIOMain->Redf_ThrottleMessageHandler(*this, 7, message->dataContents);
	return;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle0MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle0Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle0MessageID);

//	if (g_bNoTOCKeys) {
//		g_pRIOMain->Redf_ThrottleMessageHandler(*this, 0, message->dataContents);
//		return;
//	}


	if(message->dataContents > 0)
	{
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle0Percent++;
	}
	else
	{
		throttle0Percent--;
	}

	Min_Clamp(throttle0Percent, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle10MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle10Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle10MessageID);

	if(message->dataContents > 0)
	{	
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle10Percent++;
	}
	else
	{
		throttle10Percent--;
	}

	Min_Clamp(throttle10Percent, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle20MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle20Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle20MessageID);

//	if (g_bNoTOCKeys) {
//		g_pRIOMain->Redf_ThrottleMessageHandler (*this, 1, message->dataContents);
//		return;
//	}


	if(message->dataContents > 0)
	{	
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle20Percent++;
	}
	else
	{
		throttle20Percent--;
	}

	Min_Clamp(throttle20Percent, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle30MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle30Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle30MessageID);

//	if (g_bNoTOCKeys) {
//		g_pRIOMain->Redf_ThrottleMessageHandler (*this, 2, message->dataContents);
//		return;
//	}


	if(message->dataContents > 0)
	{	
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle30Percent++;
	}
	else
	{
		throttle30Percent--;
	}

	Min_Clamp(throttle30Percent, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle40MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle40Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle40MessageID);

//	if (g_bNoTOCKeys) {
//		g_pRIOMain->Redf_ThrottleMessageHandler (*this, 3, message->dataContents);
//		return;
//	}

	if(message->dataContents > 0)
	{	
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle40Percent++;
	}
	else
	{
		throttle40Percent--;
	}

	Min_Clamp(throttle40Percent, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle50MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle50Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle50MessageID);

//	if (g_bNoTOCKeys) {
//		g_pRIOMain->Redf_ThrottleMessageHandler (*this, 4, message->dataContents);
//		return;
//	}

	if(message->dataContents > 0)
	{	
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle50Percent++;
	}
	else
	{
		throttle50Percent--;
	}

	Min_Clamp(throttle50Percent, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle60MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle60Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle60MessageID);

//	if (g_bNoTOCKeys) {
//		g_pRIOMain->Redf_ThrottleMessageHandler (*this, 5, message->dataContents);
//		return;
//	}

	if(message->dataContents > 0)
	{	
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle60Percent++;
	}
	else
	{
		throttle60Percent--;
	}

	Min_Clamp(throttle60Percent, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle70MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle70Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle70MessageID);

//	if (g_bNoTOCKeys) {
//		g_pRIOMain->Redf_ThrottleMessageHandler (*this, 6, message->dataContents);
//		return;
//	}

	if(message->dataContents > 0)
	{	
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle70Percent++;
	}
	else
	{
		throttle70Percent--;
	}

	Min_Clamp(throttle70Percent, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle80MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle80Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle80MessageID);

//	if (g_bNoTOCKeys) {
//		g_pRIOMain->Redf_ThrottleMessageHandler (*this, 7, message->dataContents);
//		return;
//	}

	if(message->dataContents > 0)
	{	
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle80Percent++;
	}
	else
	{
		throttle80Percent--;
	}

	Min_Clamp(throttle80Percent, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle90MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle90Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle90MessageID);

	if(message->dataContents > 0)
	{	
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle90Percent++;
	}
	else
	{
		throttle90Percent--;
	}

	Min_Clamp(throttle90Percent, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::Throttle100MessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, throttle100Percent);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == Throttle100MessageID);

	if(message->dataContents > 0)
	{
	    Mech *mech = Cast_Object(Mech *, vehicle);

	    if (!(mech->IsShutdown () || mech->IsCrouched ())) // jcem - no speed demand will be accepted when shutdown/crouched...
		throttle100Percent++;
	}
	else
	{
		throttle100Percent--;
	}

	Min_Clamp(throttle100Percent, 0);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CenterTorsoToLegsMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, m_TorsoSpaceBarDown);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CenterTorsoToLegsMessageID);

	if(message->dataContents > 0)
	{	
		temporaryTorsoMode = CenterTorsoToLegs;
		m_TorsoSpaceBarDown++;
	}
	else
	{
		m_TorsoSpaceBarDown--;
		Min_Clamp (m_TorsoSpaceBarDown,0);
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CenterLegsToTorsoMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying) {
		ProcessKeyUp(message, m_TorsoSpaceBarDown);
		return;
	}

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == CenterLegsToTorsoMessageID);

	if(message->dataContents > 0)
	{	
		temporaryTorsoMode = CenterLegsToTorso;
		m_TorsoSpaceBarDown++;
	}
	else
	{
		m_TorsoSpaceBarDown--;
		Min_Clamp (m_TorsoSpaceBarDown,0);
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::ShowObjectivesMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == ShowObjectivesMessageID);
	Check_Object (ObjectiveRenderer::Instance);

	if (!CTCL_IsNone())
	{
		if(message->dataContents > 0)
		{	
			g_pRIOMain->SetLampState (36, LAMP_BRIGHT);// hyun
			g_bObjMode = !g_bObjMode;
//			ObjectiveRenderer::Instance->ToggleObjective ();
		}
		else
		{
			g_pRIOMain->SetLampState (36, LAMP_DEFAULT);// hyun
		}
	}
	else
	{
		if(message->dataContents > 0)
		{	
			ObjectiveRenderer::Instance->ToggleObjective ();
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::MuteMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == MuteMessageID);

    if(message->dataContents > 0)
    {	
		g_pRIOMain->SetLampState (55, LAMP_BRIGHT);// hyun
		g_bMuteMode = !g_bMuteMode;
	}
	else
	{
		g_pRIOMain->SetLampState (55, LAMP_DEFAULT);// hyun
    }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void VehicleInterface::EjectMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == EjectMessageID);

	if(message->dataContents > 0)
	{
// begin of jcem
        if (CTCL_IsConsoleX()) {
            if (vehicle->IsDerivedFrom(Mech::DefaultData)) {
                Mech* mech = Cast_Object(Mech*, vehicle);
                Check_Object(mech);

                if ((g_nInputMode != _BIGINNER_MODE) && mech->IsGimped()) {
                    bool bAnyWeaponIsAlive = false;
	                Subsystem *subsystem;
	                ChainIteratorOf<Subsystem*> iterator(&mech->subsystemsInVehicle);
	                while((subsystem = iterator.ReadAndNext()) != NULL)
	                {
		                if(subsystem->IsDerivedFrom(Weapon::DefaultData))
		                {
			                Weapon *weapon = Cast_Object(Weapon *, subsystem);
			                Check_Object(weapon);
                            if (!(weapon->executionState->GetState() == Subsystem::ExecutionStateEngine::DestroyedState)/*don't use weapon->IsDestroyed()*/) {
								bAnyWeaponIsAlive = true;
			                    break;
                            }
		                }
	                }
	                if (bAnyWeaponIsAlive)
                        QueCommand(VehicleCommand::EjectCommand);
                }
            }
        } else
// end of jcem
        QueCommand(VehicleCommand::EjectCommand);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
#if 0
void VehicleInterface::AutoPilotMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	Verify(message->messageID == AutoPilotMessageID);

	if(message->dataContents > 0)
	{	
		if ((!m_selectedNavPoint.GetCurrent()) || (executionState->GetState () == ExecutionStateEngine::AutoPilotState))
		{
			executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);
		}
		else
		{
			executionState->RequestState(ExecutionStateEngine::AutoPilotState);
		}

	}
}
#endif
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void
	VehicleInterface::ToggleZoomReticuleMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
	if (vehicle->IsDestroyed())
		return;
	if (cinemaPlaying)
		return;
	if (observerMode)
		return;

	if (InputTrainer::GetInstance()->GetEnabled(InputTrainer::ZOOM) == false)
		return;

	NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
	
	if (!params->m_allowZoom)
		return;

	if (g_nInputMode == _BIGINNER_MODE) {
        return;
    }

	Check_Object(this);	
	Check_Object(message);
	Check_Object(vehicle);
	//jcem - Verify(message->messageID == ToggleZoomReticuleMessageID);

    if (GetShutdownState()) {
        if (!g_bJumpZoom)
            g_pRIOMain->SetLampState (16, LAMP_OFF);// hyun
		g_pRIOMain->SetLampState (51, LAMP_OFF);
        return;
    }

// MSL 5.02 Zoom Amp
	if(MWGUIManager::GetInstance())
		if(MWGUIManager::GetInstance()->lightAmp->IsOn())
		{
			MWGUIManager::GetInstance()->HideLightAmplification();
			Mission::GetInstance()->ResetMissionLights();
		}

	if(message->dataContents > 0)
	{	
// MSL 5.02 Zoom Amp
//		if (IsZoomReticuleAllowed ())
//		{
			if (!vehicle || !vehicle->GetTorso() ||
				(vehicle->GetTorso()->GetLookDirection() != Torso::LookBackDirection &&
				 vehicle->GetTorso()->GetLookDirection() != Torso::LookDownDirection))
			{

				userRequestForreticuleZoomChange = true;

				if (reticuleZoomShowing)
				{
					requestedZoomChange = false;
				}
				else
				{
                    if (g_nInputMode != _BIGINNER_MODE) {
					    ReactToEvent (ZOOM_RETICAL_ENGAGED);
					    requestedZoomChange = true;
                    }
				}
			}
//		}
    } else {
        // jcem - begin
        if (!((g_fZoomTimeC < 0.0) || Stuff::Close_Enough(g_fZoomTime, 0.0) || Stuff::Close_Enough(g_fZoomFOVA, g_fZoomFOVB))) {
            g_fZoomTimeC = -9999;
        }
        // jcem - end
    }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void
	VehicleInterface::SetCameraMode(
		int camera_mode,
		const Stuff::Point3D* point
	)
{
	Check_Object(this);

	cameraView = camera_mode;

	const GameModel *model = GetGameModel();
	Check_Object(model);
  //
  // Reset since addedLengthToTarget, external reticule mode needs slight increase.
  //
  addedLengthToTarget = 0.0f;

	if (camera_mode == EditorCameraView)
	{
		SetNewLocalToParent(Stuff::LinearMatrix4D::Identity);
		SyncMatrices(true);
		cameraDirty = true;
	}

  if (observerMode && camera_mode != ExternalCameraTerrainFollowView)
		return;


	switch (camera_mode)
	{
		case InMechCameraView:
		{
    	cameraOffset = model->cameraStartOffset;
			vehicle->SetInternalRepresentation();
			vehicle->ExecuteChildComponentWebs();
			vehicle->internalViewPoint = true;
// MSL 5.03 Gyro Hit
        	Mech *mech = Cast_Object(Mech *, vehicle);
			if (mech->DoesHaveAdvancedGyro())
				vehicle->usingEyeSpring = true;
			else
				vehicle->usingEyeSpring = false;

#if 0
			if ((MWGUIManager::GetInstance()) &&
				(m_AIControlledHUD == false))
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->ShowHudComponent(MWGUIManager::HUD_RADAR);
			}
#endif

			break;
		}
		case ExternalCameraAttachedView:
		{
    	cameraOffset = model->cameraStartOffset;
			vehicle->internalViewPoint = false;
			vehicle->usingEyeSpring = false;
			vehicle->SetExternalRepresentation();
			vehicle->ExecuteChildComponentWebs();

#if 0
			if ((MWGUIManager::GetInstance()) &&
				(m_AIControlledHUD == false))
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->HideHudComponent(MWGUIManager::HUD_RADAR);
			}
#endif

			break;
		}
		case ExternalCameraDetachedView:
		{
    	cameraOffset = model->cameraStartOffset;
			vehicle->internalViewPoint = false;
			vehicle->usingEyeSpring = false;
			vehicle->SetExternalRepresentation();
			vehicle->ExecuteChildComponentWebs();
			LinearMatrix4D camera_to_parent;
			LinearMatrix4D camera_to_world;
			LinearMatrix4D camera_trans;
			LinearMatrix4D camera_rot;

			camera_trans = cameraOffset;
			camera_rot = cameraRotation;
			camera_to_parent.Multiply(camera_trans,camera_rot);

			camera_to_parent.Normalize();
			Entity *parent = GetParentEntity();
			camera_to_world.Multiply(camera_to_parent, parent->GetLocalToWorld());

			cameraRotation = camera_to_world;
			cameraOffset = camera_to_world;

#if 0
			if ((MWGUIManager::GetInstance()) &&
				(m_AIControlledHUD == false))
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->HideHudComponent(MWGUIManager::HUD_RADAR);
			}
#endif

			break;
		}
    case ExternalCameraTargetReticule:
    {
      Max_Clamp(cameraOffset.z, 40.0f);
  		Min_Clamp(cameraOffset.z, 2.0f); // what does this accomplish?
      Min_Clamp(cameraOffset.x, -20.0f);
      Max_Clamp(cameraOffset.x, 20.0f);
      Min_Clamp(cameraOffset.y, 2.0f);
      Max_Clamp(cameraOffset.y, 20.0f);

      vehicle->internalViewPoint = false;
	  vehicle->usingEyeSpring = true;
			vehicle->SetExternalRepresentation();
			vehicle->ExecuteChildComponentWebs();
#if 0
			if ((MWGUIManager::GetInstance()) &&
				(m_AIControlledHUD == false))
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->ShowHudComponent(MWGUIManager::HUD_RADAR);
			}
#endif
      UpdateTargetReticuleCameraPosition(); // effects next targetting pass
      break;
    }
		case ExternalCameraTerrainFollowView:
		{
			vehicle->internalViewPoint = false;
			vehicle->usingEyeSpring = false;
			vehicle->SetExternalRepresentation();
			vehicle->ExecuteChildComponentWebs();
    	cameraOffset = model->cameraStartOffset;
#if 0
			if ((MWGUIManager::GetInstance()) &&
				(m_AIControlledHUD == false))
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->HideHudComponent(MWGUIManager::HUD_RADAR);
			}
#endif

			break;
		}
		case TopDownCameraView:
		{
			vehicle->internalViewPoint = false;
			vehicle->usingEyeSpring = false;
			vehicle->SetExternalRepresentation();
			vehicle->ExecuteChildComponentWebs();
			Verify(point != 0);
			cameraOffset = *point;

#if 0
			if ((MWGUIManager::GetInstance()) &&
				(m_AIControlledHUD == false))
			{
				Check_Object(MWGUIManager::GetInstance());
				MWGUIManager::GetInstance()->HideHudComponent(MWGUIManager::HUD_RADAR);
			}
#endif

			break;
		}
		case NextCameraView:
		{
    	cameraOffset = model->cameraStartOffset;
			break;
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::SetCameraMode(
		int camera_mode,
		const VehicleInterface__GameModel& model
	)
{
	Check_Object(this);
	Check_Object(&model);

	cameraView = camera_mode;
  //
  // Reset since addedLengthToTarget, external reticule mode needs slight increase.
  //
  addedLengthToTarget = 0.0f;

	switch (camera_mode)
	{
		case ExternalCameraAttachedView:
		{
			vehicle->internalViewPoint = false;
			vehicle->usingEyeSpring = false;
			cameraOffset	= model.cameraStartOffset;
			cameraRotation	= model.cameraStartAngle;
			vehicle->SetExternalRepresentation();
			vehicle->ExecuteChildComponentWebs();
			return;
		}

		case ExternalCameraTerrainFollowView:
		{
			vehicle->internalViewPoint = false;
			vehicle->usingEyeSpring = false;
			cameraOffset	= model.cameraStartOffset;
			cameraRotation	= model.cameraStartAngle;
			vehicle->SetExternalRepresentation();
			vehicle->ExecuteChildComponentWebs();
			return;
		}
		case ExternalCameraTargetReticule:
		{
			vehicle->internalViewPoint = false;
			vehicle->usingEyeSpring = true;
//			cameraOffset	= model.cameraStartOffset;
//			cameraRotation	= model.cameraStartAngle;
      Max_Clamp(cameraOffset.z, 40.0f);
  		Min_Clamp(cameraOffset.z, 2.0f); // what does this accomplish?
      Min_Clamp(cameraOffset.x, -20.0f);
      Max_Clamp(cameraOffset.x, 20.0f);
      Min_Clamp(cameraOffset.y, 2.0f);
      Max_Clamp(cameraOffset.y, 20.0f);
      UpdateTargetReticuleCameraPosition(); // effects next targetting pass

			return;
		}
	}

	Verify(!"Should never get here.");
}

void VehicleInterface::ConnectPlayerAI (PlayerAI *p1)
{
}

void VehicleInterface::PlayerAIRun (bool value)
{

	if (!Application::GetInstance()->serverFlag)
		return;

	if (value)
		executionState->RequestState(ExecutionStateEngine::AIRunningState);
	else
		executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);
}

void VehicleInterface::PlayerAIFieldBase (bool value)
{

	if (!Application::GetInstance()->serverFlag)
		return;

	if (value)
		executionState->RequestState(ExecutionStateEngine::FieldBaseState);
	else
		executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CreateWeatherEffect()
{
	Check_Object(this);
	Check_Object(Mission::GetInstance());

	const Mission__GameModel *mission_model = Mission::GetInstance()->GetGameModel();
	Check_Object(mission_model);

	NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
	if (MWApplication::GetInstance()->networkingFlag && !params->m_weather)
	{
		return;
	}

	if(Mission::GetInstance()->m_isNightMission)
	{
		CreateWeatherEffect(mission_model->m_nightWeatherEffectResource);
	}
	else
	{
		CreateWeatherEffect(mission_model->m_weatherEffectResource);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CreateWeatherEffect(const Adept::ResourceID& resource_id)
{
	if (resource_id == ResourceID::Null)
	{
		return;
	}

	Resource resource(resource_id);
	Verify(resource.DoesResourceExist());

	ClassID class_ID;
	class_ID = Entity::GetClassIDFromDataListID(resource_id);
	Verify(class_ID != NullClassID);

	LinearMatrix4D effect_location = GetLocalToWorld();

	Effect::CreateMessage effect_create_message(
		sizeof(Effect::CreateMessage),
		DefaultEventPriority,
		Entity::CreateMessage::DefaultFlags,
		class_ID,
		Effect::DefaultFlags,
		resource_id,
		GetLocalToWorld(),
		0.0f,
		Entity::ExecutionStateEngine::AlwaysExecuteState,
		NameTable::NullObjectID,
		Entity::DefaultAlignment
	);
	MemoryStream stream(&effect_create_message, effect_create_message.messageLength);

	ReplicatorID effect_rep_id = Connection::Hermit->GetNextReplicatorID();
	weatherEffect.Remove();
	weatherEffect.Add(Cast_Object(Effect *,Entity::CreateEntity(&stream, &effect_rep_id, false)));
	Map::GetInstance()->AddChild(weatherEffect.GetCurrent());
	weatherEffect.GetCurrent()->SetFollowEntity(this);
	weatherEffect.GetCurrent()->PlaceOnEntity();
	weatherEffect.GetCurrent()->SyncMatrices(true);
	weatherEffect.GetCurrent()->videoStatus = true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ExecuteNavSystem()
{
	Check_Object(this);
	NavPoint *nav_point;
	nav_point = m_selectedNavPoint.GetCurrent();

	YawPitchRoll our_rotation;
	our_rotation = vehicle->GetLocalToWorld();
	Scalar nav_point_range = -1;
	Scalar nav_point_facing = 0.0f;
	int nav_point_id = NameTable::NullObjectID;

	if(nav_point)
	{
		Point3D nav_world;
		nav_world = nav_point->GetLocalToWorld();
		Point3D nav_local_to_us;
		nav_local_to_us.MultiplyByInverse(nav_world, vehicle->GetLocalToWorld());
		YawPitchRange nav_facing(nav_local_to_us);
		nav_point_facing = nav_facing.yaw;
		nav_point_range = nav_local_to_us.GetApproximateLength();
		nav_point_id = nav_point->objectID;
	}


	MWGUIManager::GetInstance()->SetNavSystem(
		our_rotation.yaw,
		nav_point_facing,
		nav_point_range,
		nav_point_id
	);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::CalculateInterfaceTargetPosition()
{
	Check_Object(this);
	Check_Object(vehicle);
	
	MWGUIManager::GetInstance()->ClearTargetIndicator();

	Entity *target;
	target = m_interfaceTarget.GetCurrent();
	if(!target)
		return;

	if (target->IsDestroyed())
	{
		ReactToTargetDestruction();
		m_interfaceTarget.Remove();
		target = vehicle->GetSensor()->GetNearestEnemy();
		MWGUIManager::GetInstance()->SetNewTargetWindowEntity(target);
		if(target)
		{
			m_interfaceTarget.Add(target);
			if (ShowTargetCamera ())
				m_targetCamera->SetScene(target->GetElement());
			else
				m_targetCamera->SetScene (NULL);
		}
		else
			return;
	}

	if (vehicle->GetSensor()->ContainsEntity(target) == false)
	{
		SetGUITarget(NULL);
		return;
	}

	Check_Object(target);
	Point3D target_world;
	Point3D target_size;
	target_size.Zero();


	//
	// Need to see if the target has a solid volume and if so, use that for the positioning of the target
	// bracket.
	CollisionVolume * volume = target->GetSolidVolume();
	if (!volume)
	{
		volume = target->GetHierarchicalVolume();
	}
	if (volume)
	{
		OBB world_bounds;
		world_bounds.Multiply(volume->m_localSpaceBounds, target->GetLocalToWorld());

		target_world = world_bounds.localToParent;
		target_size = world_bounds.axisExtents;
	}
  else
	{
		target_world = target->GetLocalToWorld();
	}
	
	if (target_world.y < -1000)
	{
		MWGUIManager::GetInstance()->SetTargetPosition(0, target_world, Point3D (-1,-1,-1), 0, 0, 0,0);
		return;
	}

	CameraComponent *cam_comp_main = VideoRenderer::Instance->GetSceneCamera();
	CameraComponent *cam_comp_zoom = VideoRenderer::Instance->GetSecondaryCamera(1);
	Check_Object(cam_comp_main);
	ElementRenderer::CameraElement *camera_main = cam_comp_main->GetElement();
	Check_Object(camera_main);
	ElementRenderer::CameraElement *camera_zoom = NULL;
	//
	// Sync the main camera and it's clipper data
	//
	MidLevelRenderer::MLRClipper *clipper_main;
	camera_main->Sync();
	clipper_main = camera_main->GetClipper();

	Check_Object(clipper_main);
	clipper_main->UpdateClipperCameraData(
				camera_main->GetLocalToWorld(),
				camera_main->GetCameraToClip()
			);
	


	Point3D target_local_to_us;
//	LinearMatrix4D our_facing;
//	if(vehicle->GetTorso())
//	{
//		LinearMatrix4D our_facing_twist;
//		our_facing_twist = vehicle->GetTorso()->GetTwistJointMatrix();
//		our_facing.Multiply(our_facing_twist, vehicle->GetTorso()->GetPitchJointMatrix());
//	}
//	else
//	{
//		our_facing = vehicle->GetLocalToWorld();
//	}
	target_local_to_us.MultiplyByInverse(target_world, camera_main->GetLocalToWorld());

	YawPitchRange target_direction;
	target_direction = target_local_to_us;
	
	
	//
	// Behavior changes depending on whether we are showing the zoom camera or not.
	//
	// If it is up we have to test against it first:
	//		If object is visible in it, show the cursor on the main camera
	//		If object is off the zoom camera, but under it, show left/right/down/up indicators on zoom camera
	//    If object is off zoom completely, do old behavior
	


	

	Stuff::Scalar horizontal_fov_main_halfed = camera_main->GetFOVAngle() * 0.5f;
	//
	// First check if it's off screen totally.
	//
	if(target_direction.yaw > (horizontal_fov_main_halfed))
	{
		MWGUIManager::GetInstance()->SetLeftTargetIndicator();
		return;
	}
	else if(target_direction.yaw < -(horizontal_fov_main_halfed))
	{
		MWGUIManager::GetInstance()->SetRightTargetIndicator();
		return;
	}
	else if(reticuleZoomShowing && m_reticuleCamera)
	{
		Stuff::Scalar near_clip;
		Stuff::Scalar far_clip;
		Stuff::Scalar horizontal_fov_zoom_halfed;
		Stuff::Scalar height_to_width;
		Stuff::Scalar left, top, right, bottom;
		camera_zoom = m_reticuleCamera;
		Check_Object(camera_zoom);

		//
		// Update this camera to properly clip
		//
		camera_zoom->GetPerspective(near_clip, far_clip, horizontal_fov_zoom_halfed, height_to_width);
		camera_zoom->GetViewport(left, top, right, bottom);

		MidLevelRenderer::MLRClipper *clipper_zoom;
		camera_zoom->Sync();
		clipper_zoom = camera_zoom->GetClipper();

		Check_Object(clipper_zoom);
		clipper_zoom->UpdateClipperCameraData(
					camera_zoom->GetLocalToWorld(),
					camera_zoom->GetCameraToClip()
				);


		//
		// First see if it is outside the physical area of the screen taken up by the zoom reticule
		// If it is, we're done (roughly), otherwise we have more checks to make
		
		//
		// Since we keep using this below I want to do it once
		//

		
		
		
		

		horizontal_fov_zoom_halfed *= 0.5f;

		if (target_direction.yaw < ((horizontal_fov_main_halfed * percentage_of_zoom_screen_on_left)) &&
				target_direction.yaw > ((horizontal_fov_main_halfed * percentage_of_zoom_screen_on_right)) &&
				target_direction.pitch < ((horizontal_fov_main_halfed * percentage_of_zoom_screen_on_top)) &&
				target_direction.pitch > ((horizontal_fov_main_halfed * percentage_of_zoom_screen_on_bottom))
			)
		{
			//
			// If we are here, the object is under the zoom window somewhere
			//

			if(target_direction.yaw > (horizontal_fov_zoom_halfed ))
			{
				MWGUIManager::GetInstance()->SetLeftTargetIndicator();
				MWGUIManager::GetInstance()->SetTargetIndicatorInZoom();
				return;
			}
			else if(target_direction.yaw < -(horizontal_fov_zoom_halfed  ))
			{
				MWGUIManager::GetInstance()->SetRightTargetIndicator();
				MWGUIManager::GetInstance()->SetTargetIndicatorInZoom();
				return;
			}
			else if(target_direction.pitch < -(horizontal_fov_zoom_halfed  *(height_to_width)))
			{
				MWGUIManager::GetInstance()->SetTopTargetIndicator();
				MWGUIManager::GetInstance()->SetTargetIndicatorInZoom();
				return;
			}
			else if(target_direction.pitch > (horizontal_fov_zoom_halfed  *(height_to_width)))	
			{
				MWGUIManager::GetInstance()->SetBottomTargetIndicator();
				MWGUIManager::GetInstance()->SetTargetIndicatorInZoom();
				return;
			}
			else
			{
				MWGUIManager::GetInstance()->SetTargetPosition(cam_comp_zoom, target_world, target_size, (left - right)*Environment.screenWidth, (top - bottom)*Environment.screenHeight, (1.0f - left)*Environment.screenWidth, (1.0f - top)*Environment.screenHeight);
				return;
			}
		}

	}
	
	//
	// If we got here, one of two things is happening.
	// 1. There is no zoom reticule and it's on screen
	// 2. There	is a zoom reticule and it's not interfering
	//
	MWGUIManager::GetInstance()->SetTargetPosition(cam_comp_main, target_world, target_size, (Stuff::Scalar)Environment.screenWidth, (Stuff::Scalar)Environment.screenHeight,
																								0.0f, 0.0f);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::UpdateTargetWindow()
{
	Check_Object(this);

	if(!m_targetCamera)
		return;

	Entity *target_entity = m_interfaceTarget.GetCurrent();
	if(!target_entity)
		return;

	//
	//------------------------------
	//Now we have to move the camera
	//------------------------------
	//

	//setup translation
	Point3D camera_local_to_target = Point3D::Identity;
	LinearMatrix4D camera_local_to_world = LinearMatrix4D::Identity;

	LinearMatrix4D target_to_world;
	CollisionVolume *target_volume = target_entity->GetSolidVolume();
	if(target_volume)
	{
		target_to_world.Multiply(target_volume->m_localSpaceBounds.localToParent, target_entity->GetLocalToWorld());
	}
	else
	{
		target_to_world = target_entity->GetLocalToWorld();
	}

	Point3D our_position;
	our_position = vehicle->GetLocalToWorld();

	Vector3D us_to_target;
	us_to_target.Subtract((Point3D)target_to_world, our_position);
	us_to_target.y = 0.0f;

	UnitVector3D normalized_direction;
	normalized_direction.Normalize(us_to_target);

	if(target_volume)
	{
		camera_local_to_target.Multiply(normalized_direction, (-target_volume->m_localSpaceBounds.sphereRadius * 2.31f));
	}
	else
	{
		camera_local_to_target.Multiply(normalized_direction, -20.0f);
	}

	Point3D camera_translation;
	camera_translation.Add(camera_local_to_target, (Point3D)target_to_world);
	if(target_volume)
	{
		Point3D target_trans;
		target_trans = target_to_world;
		camera_translation.y = target_trans.y;
	}
	else
	{
		camera_translation.y += 5.0f;
	}

	//set up rotation;
	Vector3D camera_to_center;
	camera_to_center.Subtract((Point3D)target_to_world, camera_translation);
	camera_local_to_world.AlignLocalAxisToWorldVector(camera_to_center, Z_Axis, Y_Axis, X_Axis);
	camera_local_to_world.BuildTranslation(camera_translation);
	LinearMatrix4D world_to_interface;
	world_to_interface.Invert(GetLocalToWorld());
	LinearMatrix4D camera_to_interface;
	camera_to_interface.Multiply(camera_local_to_world, world_to_interface);

	//set camera position and sync
	m_targetCamera->SetLocalToParent(camera_to_interface);
	m_targetCamera->Sync();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ShowZoom (void)
{
	Check_Object(this);

	if(!m_reticuleCamera)
		return;

// MSL 5.02 Zoom
    if (g_nInputMode == _BIGINNER_MODE) {
        if (reticuleZoomShowing) {
            HideZoom();
			requestedZoomChange = false;
        }
        return;
    }

	if (reticuleZoomShowing)
		return;

// MSL 5.02 headshot
	if (hudZoomDestroyed)
	{
		VehicleInterface::ReactToEvent (VehicleInterface::ZOOM_FAIL); //play failure sound
		return; //do not allow zoom if it is destroyed
	}

	if (IsZoomReticuleAllowed ())
	{
		if (!reticuleZoomShowing)
		{
			if(MWGUIManager::GetInstance())
			{
				HUDZoom *hudzoom;
				Scalar left,right,top,bottom;
				hudzoom = Cast_Object (HUDZoom *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_ZOOM));
				m_reticuleCamera->GetViewport (left,top,right,bottom);
				hudzoom->SetWindow (left,top,right,bottom);
				HUDTargetArrow * hudarrow;
				hudarrow = Cast_Object (HUDTargetArrow *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_TARGETARROW));
				hudarrow->SetZoomWindow (left,top,right,bottom);

				MWGUIManager *gui;
				gui = MWGUIManager::GetInstance ();
				Verify (gui);
//				gui->zoomLightAmp->AdoptCamera (m_reticuleCamera);

				MWGUIManager::GetInstance()->ShowZoom (true);
			}
			Element *root = VideoRenderer::Instance->GetSceneRoot();
			Check_Object(root);
			m_reticuleCamera->SetScene(root);
		}

		MWGUIManager::GetInstance()->SetZoomDisplayLevel(s_zoomDisplayLevel[0]);

		Stuff::Scalar near_clip;
		Stuff::Scalar far_clip;
		Stuff::Scalar horizontal_fov;
		Stuff::Scalar height_to_width;
		Check_Object(m_reticuleCamera);
		m_reticuleCamera->GetPerspective(near_clip, far_clip, horizontal_fov, height_to_width);
		//m_reticuleCamera->SetPerspective(near_clip, far_clip, s_zoomFOV[0], height_to_width);
		//sanghoon
        // jcem - begin
        float fZoom;
         gosASSERT(g_fZoomFOVA >= g_fZoomFOVB);
        if (Stuff::Close_Enough(g_fZoomTime, 0.0) || Stuff::Close_Enough(g_fZoomFOVA, g_fZoomFOVB)) {
            fZoom = g_fZoomFOVB;
        } else {
            fZoom = g_fZoomFOVA;
        }
       	MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());
        g_fZoomTimeC = mission->GetMissionTime();
        // jcem - end

		m_reticuleCamera->SetPerspective(near_clip, far_clip, fZoom, height_to_width);

		m_reticuleCamera->Sync();
		reticuleZoomShowing = true;
	}
}

void VehicleInterface::HideZoom (void)
{
	Check_Object(this);

	if(!m_reticuleCamera)
		return;

	if (!reticuleZoomShowing)
		return;

	// if the user wants it off
	if(MWGUIManager::GetInstance())
	{
		MWGUIManager *gui;
		gui = MWGUIManager::GetInstance ();
		Verify (gui);
		MWGUIManager::GetInstance()->ShowZoom (false);
	}
	m_reticuleCamera->SetScene(NULL);
	reticuleZoomShowing = false;
}

#if 0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::UpdateReticuleWindow()
{
	Check_Object(this);

	if(!m_reticuleCamera)
		return;


	bool reticule_allowed = false;

	reticule_allowed = IsZoomReticuleAllowed();

	if (reticule_allowed)
	{
		if (userRequestForreticuleZoom)
		{
			reticuleZoomMode++;
			userRequestForreticuleZoom = false;
			if (reticuleZoomMode < C_MAXZOOMSETTINGS)
			{
				if (reticuleZoomMode == 1) // just turned on
				{
					// if the user wants it on and it isn't but can be...
					if(MWGUIManager::GetInstance())
					{
						HUDZoom *hudzoom;
						Scalar left,right,top,bottom;
						hudzoom = Cast_Object (HUDZoom *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_ZOOM));
						m_reticuleCamera->GetViewport (left,top,right,bottom);
						hudzoom->SetWindow (left,top,right,bottom);
						HUDTargetArrow * hudarrow;
						hudarrow = Cast_Object (HUDTargetArrow *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_TARGETARROW));
						hudarrow->SetZoomWindow (left,top,right,bottom);
						
						MWGUIManager *gui;
						gui = MWGUIManager::GetInstance ();
						Verify (gui);
//						gui->zoomLightAmp->AdoptCamera (m_reticuleCamera);

						MWGUIManager::GetInstance()->ShowZoom (true);
					}
					Element *root = VideoRenderer::Instance->GetSceneRoot();
					Check_Object(root);
					m_reticuleCamera->SetScene(root);
				}

				MWGUIManager::GetInstance()->SetZoomDisplayLevel(s_zoomDisplayLevel[reticuleZoomMode-1]);

				Stuff::Scalar near_clip;
				Stuff::Scalar far_clip;
				Stuff::Scalar horizontal_fov;
				Stuff::Scalar height_to_width;
				Check_Object(m_reticuleCamera);
				m_reticuleCamera->GetPerspective(near_clip, far_clip, horizontal_fov, height_to_width);
				Verify(reticuleZoomMode > 0);
				m_reticuleCamera->SetPerspective(near_clip, far_clip, s_zoomFOV[reticuleZoomMode-1], height_to_width);

			}
			else
			{
				reticuleZoomMode = 0;
				// if the user wants it off
				if(MWGUIManager::GetInstance())
				{
					MWGUIManager *gui;
					gui = MWGUIManager::GetInstance ();
					Verify (gui);
//					gui->zoomLightAmp->RemoveCamera ();
					MWGUIManager::GetInstance()->ShowZoom (false);
				}
				m_reticuleCamera->SetScene(NULL);

			}
		}
	}
	else if (reticuleZoomMode)
	{
		// if the reticule is not allowed to be on....
		reticuleZoomMode = 0;
		if(MWGUIManager::GetInstance())
			MWGUIManager::GetInstance()->ShowZoom (false);
		m_reticuleCamera->SetScene(NULL);
	}


	if (reticuleZoomMode)
	{
		m_reticuleCamera->Sync();
	}
}
#endif
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::SetNavPoint(NavPoint *nav_point)
{
	Check_Object(this);
	Check_Object(nav_point);
	
	m_selectedNavPoint.Remove();
	m_selectedNavPoint.Add(nav_point);
}

MechWarrior4::NavPoint*
	VehicleInterface::GetNavPoint()
{
	return (m_selectedNavPoint.GetCurrent());
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::StartEngineIdle (void)
{
	if (m_EngineIdleSound.GetCurrent() == NULL)
	{
		AudioCommand *command = AudioCommand::Create(ENGINE_IDLE_TYPE,ENGINE_IDLE_WAV,1.0f,1.0f);
		Check_Object(command);
		m_EngineIdleSound.Add(command);
		command->Play(gosAudio_Loop);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::EndEngineIdle (void)
{
	if (m_EngineIdleSound.GetCurrent())
	{
		m_EngineIdleSound.GetCurrent ()->Stop ();
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ReactToEvent (SOUND_TRIGGER event, DWORD dwParam/* = 0*/)
{
	if ((cinemaPlaying == true) || (m_FrameCount < 5))
	{
		return;
	}
	if (executionState->GetState() == ExecutionStateEngine::WatchingDeathState)
	{
		if ((event != NO_HEAT) && (event != COOLANT_FLUSH_STOP) && (event != NARC_SIGNAL_STOP) && (event != STEP_WATER_STOP))
			return;
	}

	MWGUIManager *gui = NULL;
	switch (event)
	{
		case CRITICAL_HIT_WEAPON:
// MSL 5.05
//			ReactToCriticalWeaponHit ();
			break;
		case CRITICAL_HIT_GIMP:
			ReactToGimp ();
			break;
		case DAMAGE_CRITICAL:
			if ((m_damageCriticalSound.GetCurrent() == NULL) && (!m_PlayedDamageCritical))
			{
				if ((g_nMR != 2) && MW4Shell::Instance->m_optionsObject->m_bettyOn)
				{
					AudioCommand *command = AudioCommand::Create(
						DAMAGE_CRITICAL_TYPE,
						DAMAGE_CRITICAL_WAV,
						1.0f,
						1.0f
					);
					Check_Object(command);
					m_damageCriticalSound.Add(command);
					command->Play();
				}
			}
			m_PlayedDamageCritical = true;
			break;
		case NAVPOINT_REACHED:
			PLAY_SOUND(NAVPOINT_REACHED);
			break;
		case HIGH_HEAT:
			if ((m_LastHeatSoundTime+HEAT_SOUND_DELAY) < gos_GetElapsedTime() || (m_LastHeatLevel != event))
			{
				if (m_LastHeatLevel != event)
				{
					if (m_heatCriticalSound.GetCurrent())
						m_heatCriticalSound.GetCurrent ()->Stop ();
				}
				if (!m_heatCriticalSound.GetCurrent ())
				{
					m_LastHeatSoundTime = gos_GetElapsedTime ();
					if ((g_nMR != 2) && MW4Shell::Instance->m_optionsObject->m_bettyOn)
					{
						AudioCommand *command = AudioCommand::Create(HIGH_HEAT_TYPE,HIGH_HEAT_WAV,1.0f,1.0f);
						Check_Object(command);
						m_heatCriticalSound.Add(command);
						command->Play();
					}
				}
				m_LastHeatLevel = event;
			}
			break;
		case MED_HEAT:
			if ((m_LastHeatSoundTime+HEAT_SOUND_DELAY) < gos_GetElapsedTime() && (m_LastHeatLevel < event))
			{
				m_LastHeatSoundTime = gos_GetElapsedTime ();
				if (m_heatCriticalSound.GetCurrent() == NULL)
				{
					if ((g_nMR != 2) && MW4Shell::Instance->m_optionsObject->m_bettyOn)
					{
						AudioCommand *command = AudioCommand::Create(MED_HEAT_TYPE,MED_HEAT_WAV,1.0f,1.0f);
						Check_Object(command);
						m_heatCriticalSound.Add(command);
						command->Play();
					}
				}
				m_LastHeatLevel = event;
			}
			break;
		case LOW_HEAT:
			if ((m_LastHeatSoundTime+HEAT_SOUND_DELAY) < gos_GetElapsedTime() && (m_LastHeatLevel < event))
			{
				m_LastHeatSoundTime = gos_GetElapsedTime ();
				if (m_heatCriticalSound.GetCurrent() == NULL)
				{
					if ((g_nMR != 2) && MW4Shell::Instance->m_optionsObject->m_bettyOn)
					{
						AudioCommand *command = AudioCommand::Create(LOW_HEAT_TYPE,LOW_HEAT_WAV,1.0f,1.0f);
						Check_Object(command);
						m_heatCriticalSound.Add(command);
						command->Play();
					}
				}
				m_LastHeatLevel = event;
			}
			break;
		case NO_HEAT:
			m_LastHeatLevel = event;
			break;
		case MELTDOWN:
			ReactToHeatMeltdown ();
			break;
		case AUTO_SHUTDOWN_OVERRIDE:
			ReactToMechShutDownOverride ();
			break;
		case SHUTDOWN:
			ReactToMechShutDown ();
			break;
		case POWER_UP:
			ReactToMechPowerUp ();
			break;
		case MISSILE_LOCKED:
			if ((!cinemaPlaying) && (!vehicle->vehicleShutDown))
				ReactToMissileLock (true);
			break;
		case MISSILE_LOCKLOST:
			ReactToMissileLock (false);
			break;
		case NO_WEAPON:
			PLAY_SOUND(NO_WEAPON);
			break;
		case MISSILE_LOCKED_ON_ME:
			ReactToIncommingMissile ();
			break;
		case RADAR_RANGE_CHANGE:
			PLAY_SOUND(RADAR_RANGE_CHANGE);
			break;
		case RADAR_OFF:
			PLAY_SOUND(RADAR_OFF);
			break;
		case RADAR_ON:	
			PLAY_SOUND(RADAR_ON);
			break;
		case ZOOM_RETICAL_ENGAGED:
			ReactToZoom ();
			break;
		case AMS_ENGAGED:
			ReactToAMS ();
			break;
		case LAMS_ENGAGED:
			ReactToLAMS ();
			break;
		case NARC_SIGNAL_START:
			if (!m_narcSound.GetCurrent())
			{
				AudioCommand *command = AudioCommand::Create(
					NARC_SIGNAL_START_TYPE,
					NARC_SIGNAL_START_WAV,
					1.0f,
					1.0f
				);
				Check_Object(command);
				m_narcSound.Add(command);
				command->Play(gosAudio_Loop);
			}
			break;
		case NARC_SIGNAL_STOP:
			if (m_narcSound.GetCurrent())
				m_narcSound.GetCurrent()->Stop();
			break;
		case NARC_HIT:
			PLAY_SOUND(NARC_HIT);
			break;
		case NEW_VEHICLE_RADAR_POWER_UP:
			if ((m_NewRadarSoundTime+NEW_RADAR_SOUND_DELAY) < gos_GetElapsedTime())
			{
				m_NewRadarSoundTime = gos_GetElapsedTime ();
				PLAY_SOUND(NEW_VEHICLE_RADAR_POWER_UP);
			}
			break;
		case ENGINE_WALK:
			if ((m_LastEngineSoundTime+ENGINE_SOUND_DELAY) < gos_GetElapsedTime())
			{
				m_LastEngineSoundTime = gos_GetElapsedTime ();
				PLAY_SOUND(ENGINE_WALK);
			}
			break;
		case ENGINE_RUN:
			if ((m_LastEngineSoundTime+ENGINE_SOUND_DELAY) < gos_GetElapsedTime())
			{
				m_LastEngineSoundTime = gos_GetElapsedTime ();
				PLAY_SOUND(ENGINE_RUN);
			}
			break;
		case ENGINE_STOP:
			if ((m_LastEngineSoundTime+ENGINE_SOUND_DELAY) < gos_GetElapsedTime())
			{
				m_LastEngineSoundTime = gos_GetElapsedTime ();
				PLAY_SOUND(ENGINE_STOP);
			}
			break;
		case ENGINE_REVERSE:
			if ((m_LastEngineSoundTime+ENGINE_SOUND_DELAY) < gos_GetElapsedTime())
			{
				m_LastEngineSoundTime = gos_GetElapsedTime ();
				PLAY_SOUND(ENGINE_REVERSE);
			}
			break;
		case TORSO_TWIST:
			if ((g_nMR != 2) && !m_torsoSound.GetCurrent())
			{
				AudioCommand *command = AudioCommand::Create(
					TORSO_TWIST_TYPE,
					TORSO_TWIST_WAV,
					1.0f,
					1.0f
				);
				Check_Object(command);
				m_torsoSound.Add(command);
				command->Play();
			}
			break;
		case TORSO_TWIST_MAX_REACHED:
#if 0 // no sound for TORSO_TWIST_MAX_REACHED - jcem
			if (m_torsoSound.GetCurrent())
			{
				m_torsoSound.GetCurrent()->Stop();
				PLAY_SOUND(TORSO_TWIST_MAX_REACHED);
			}
#endif
			break;
		case RADAR_JAMMED:						//blurt
			PLAY_SOUND(RADAR_JAMMED);
			break;
		case COOLANT_FLUSH_START:
			ReactToCoolantFlush (true);
			break;
		case COOLANT_FLUSH_STOP:
			ReactToCoolantFlush (false);
			break;
		case AMMO_DUMPED:
			ReactToAmmoDump ();
			break;
		case OUT_OF_AMMO:
			ReactToOutOfAmmo ();
			break;
		case OBJECT_SCANNED:
			PLAY_SOUND(OBJECT_SCANNED);
			break;
		case INTERNAL_PPC_WASH:
			gui = MWGUIManager::GetInstance ();
			if (gui)
			{
                if (0.0f < g_aWIs[dwParam].m_HudEffect)
				    gui->AddPPCLevel (15.0f * g_aWIs[dwParam].m_HudEffect); // 
                else
                    gui->AddPPCLevel (15.0f); // 
			}
			PLAY_SOUND(INTERNAL_PPC_WASH);
            if (vehicle) {
                Mech* pMech = Cast_Object(Mech*, vehicle);
                HideZoom();
	            requestedZoomChange = false;
                if (pMech->IsSearchLightOn()) {
                    QueCommand(VehicleCommand::ToggleSearchLightCommand);
                }
                if (pMech->DoesHaveLightAmp())
                {
			        if(MWGUIManager::GetInstance())
			        {
				        if(MWGUIManager::GetInstance()->lightAmp->IsOn())
                        {
					        MWGUIManager::GetInstance()->HideLightAmplification();
					        Mission::GetInstance()->ResetMissionLights();
                        }
                    }
                }
            }
			break;
// MSL 5.02 headshot
		case RETICULE_WASH:
			gui = MWGUIManager::GetInstance ();
			if (gui)
			{
				gui->AddPPCLevel (15.0f);
			}
			PLAY_SOUND(INTERNAL_PPC_WASH);
			break;
		case HILL_TOO_STEEP:
			PLAY_SOUND(HILL_TOO_STEEP);
			break;
		case TARGET_DESTROYED:
			ReactToTargetDestruction ();
			break;
		case TERRAIN_BAD:
			PLAY_SOUND(TERRAIN_BAD);
			break;
		case RECHARGE_BEAM:
			PLAY_SOUND(RECHARGE_BEAM);
			break;
		case RECHARGE_MISSILE:
			PLAY_SOUND(RECHARGE_MISSILE);
			break;
		case RECHARGE_PROJECTILE:
			PLAY_SOUND(RECHARGE_PROJECTILE);
			break;
		case RECHARGE_PPC:
			PLAY_SOUND(RECHARGE_PPC);
			break;
		case STEP_WATER_START:
			ReactToStepWater (true);
			break;
		case STEP_WATER_STOP:
			ReactToStepWater (false);
			break;
		case KILLAWARDED:
			CalculateInterfaceTargetPosition();
			PLAY_SOUND(KILLAWARDED);
			break;
		case FRIENDLYFIREPENALTY:
			CalculateInterfaceTargetPosition();
			PLAY_SOUND(FRIENDLYFIREPENALTY);
			break;
		case YOUHAVEFLAG:
			PLAY_SOUND(YOUHAVEFLAG);
			break;
		case YOUINLEAD:
			PLAY_SOUND(YOUINLEAD);
			break;
		case TEAMMATEDESTROYED:
			PLAY_SOUND(TEAMMATEDESTROYED);
			break;
		case FLAGTAKEN:
			PLAY_SOUND(FLAGTAKEN);
			break;
		case FLAGCAPTURED:
			PLAY_SOUND(FLAGCAPTURED);
			break;
		case FLAGCAPTUREDHORN:
			PLAY_SOUND(FLAGCAPTUREDHORN);
			break;
		case FLAGCAPTUREDBUZZER:
			PLAY_SOUND(FLAGCAPTUREDBUZZER);
			break;
		case FLAGRETURNED:
			PLAY_SOUND(FLAGRETURNED);
			break;
		case HILLCONTESTED:
			PLAY_SOUND(HILLCONTESTED);
			break;
		case HILLCAPTURED:
			PLAY_SOUND(HILLCAPTURED);
			break;
		case REPAIR_START:
			PLAY_SOUND(REPAIR_START);
			break;
		case REPAIR_STOP:
			PLAY_SOUND(REPAIR_STOP);
			break;
// MSL 5.02 headshot
		case COMPONENT_DESTROYED:
			PLAY_SOUND(COMPONENT_DESTROYED);
			break;	
// MSL 5.03 Gyro Hit
		case COMPDESTROYED:
			PLAY_SOUND(COMPDESTROYED);
			break;	
		case ZOOM_FAIL:
			PLAY_SOUND(ZOOM_FAIL);
			break;	
		case MECH_AMMOBAY_FIRE:
			PLAY_SOUND(MECH_AMMOBAY_FIRE);
			break;	
		// coliseum crowd sounds
		case COLISEUM_AHH:
			PLAY_SOUND(COLISEUM_AHH);
			break;		
		case COLISEUM_AWW:
			PLAY_SOUND(COLISEUM_AWW);
			break;		
		case COLISEUM_BOO1:
			PLAY_SOUND(COLISEUM_BOO1);
			break;		
		case COLISEUM_BOO2:
			PLAY_SOUND(COLISEUM_BOO2);
			break;		
		case COLISEUM_BOO3:
			PLAY_SOUND(COLISEUM_BOO3);
			break;		
		case COLISEUM_CHANT1:
			PLAY_SOUND(COLISEUM_CHANT1);
			break;		
		case COLISEUM_CHANT3:
			PLAY_SOUND(COLISEUM_CHANT3);
			break;		
		case COLISEUM_CHEER1:
			PLAY_SOUND(COLISEUM_CHEER1);
			break;		
		case COLISEUM_CHEER2:
			PLAY_SOUND(COLISEUM_CHEER2);
			break;		
		case COLISEUM_CHEER3:
			PLAY_SOUND(COLISEUM_CHEER3);
			break;		
		case COLISEUM_CHEER4:
			PLAY_SOUND(COLISEUM_CHEER4);
			break;		
		case COLISEUM_CHEER5:
			PLAY_SOUND(COLISEUM_CHEER5);
			break;		
		case COLISEUM_CHEER8:
			PLAY_SOUND(COLISEUM_CHEER8);
			break;		
		case COLISEUM_CHEER9:
			PLAY_SOUND(COLISEUM_CHEER9);
			break;		
		case COLISEUM_CROWD1:
			PLAY_SOUND(COLISEUM_CROWD1);
			break;		
		case COLISEUM_CROWD2:
			PLAY_SOUND(COLISEUM_CROWD2);
			break;		
		case COLISEUM_ENERGYZAP:
			PLAY_SOUND(COLISEUM_ENERGYZAP);
			break;		
		case COLISEUM_HORN:
			PLAY_SOUND(COLISEUM_HORN);
			break;		
		case COLISEUM_JEERS:
			PLAY_SOUND(COLISEUM_JEERS);
			break;		
		case COLISEUM_ROAR:
			PLAY_SOUND(COLISEUM_ROAR);
			break;		
		case COLISEUM_STADAMB:
			PLAY_SOUND(COLISEUM_STADAMB);
			break;
		case COLISEUM_FACTORYHORN:
			PLAY_SOUND(COLISEUM_FACTORYHORN);
			break;
		case COLISEUM_FACTORYBANG:
			PLAY_SOUND(COLISEUM_FACTORYBANG);
			break;
		case COLISEUM_FACTORYBUZZ:
			PLAY_SOUND(COLISEUM_FACTORYBUZZ);
			break;
		case COLISEUM_FACTORYCLANG:
			PLAY_SOUND(COLISEUM_FACTORYCLANG);
			break;
		case COLISEUM_FACTORYDRILL:
			PLAY_SOUND(COLISEUM_FACTORYDRILL);
			break;
		case COLISEUM_FACTORYSTEAM:
			PLAY_SOUND(COLISEUM_FACTORYSTEAM);
			break;
		case COLISEUMAMB:
			PLAY_MUSIC(COLISEUMAMB);
			break;
		case COLISEUM_JUNGLEBIRD1:
			PLAY_SOUND(COLISEUM_JUNGLEBIRD1);
			break;
		case COLISEUM_JUNGLEBIRD2:
			PLAY_SOUND(COLISEUM_JUNGLEBIRD2);
			break;
		case COLISEUM_JUNGLEBIRD3:
			PLAY_SOUND(COLISEUM_JUNGLEBIRD3);
			break;
		case COLISEUM_JUNGLEBIRD4:
			PLAY_SOUND(COLISEUM_JUNGLEBIRD4);
			break;
		case COLISEUM_JUNGLEMONKEY1:
			PLAY_SOUND(COLISEUM_JUNGLEMONKEY1);
			break;
		case COLISEUM_JUNGLEMONKEY2:
			PLAY_SOUND(COLISEUM_JUNGLEMONKEY2);
			break;
		case TARGETATTACKED:
			PLAY_SOUND(TARGETATTACKED);
			break;
		case TARGETDESTROYED:
			PLAY_SOUND(TARGETDESTROYED);
			break;
		case ALARM1:
			PLAY_SOUND(ALARM1);
			break;
		case ALARM2:
			PLAY_SOUND(ALARM2);
			break;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ReactToStepWater(bool start)
{
	Check_Object(this);
	static bool canplay = true;

	if (start)
	{
		if (((m_LastStepWaterSoundTime+STEP_WATER_SOUND_DELAY) < gos_GetElapsedTime()) && (canplay))
		{
			m_LastTorsoTwistSoundTime = gos_GetElapsedTime ();
			if ((g_nMR != 2) && m_WaterStepSound.GetCurrent() == NULL)
			{
				AudioCommand *command = AudioCommand::Create(WATER_TYPE,WATER_WAV,1.0f,1.0f);
				Check_Object(command);
				m_WaterStepSound.Add(command);
				command->Play(gosAudio_Loop);
			}
			canplay = false;
		}
	}
	else
	{
		if (m_WaterStepSound.GetCurrent())
		{
			m_WaterStepSound.GetCurrent ()->Stop ();
		}
		canplay = true;
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ReactToGimp()
{
	Check_Object(this);
    // to avoid hearing after death...
    if (vehicle && !vehicle->IsDestroyed())
	PLAY_SOUND(REACT_TO_GIMP);
}
			
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReactToMechPowerUp()
{
	Check_Object(this);
	
	PLAY_SOUND(MECH_POWERUP);
	MWGUIManager *gui;
	gui = MWGUIManager::GetInstance ();
	gui->ShowShutDown ();
	if (m_interfaceTarget.GetCurrent())
		m_targetCamera->SetScene(m_interfaceTarget.GetCurrent()->GetElement());

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ReactToMechShutDownOverride()
{
	Check_Object(this);

	PLAY_SOUND(MECH_POWERDOWN_OVERRIDE);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ReactToMechShutDown()
{
	Check_Object(this);

	PLAY_SOUND(MECH_POWERDOWN);
	MWGUIManager *gui;
	gui = MWGUIManager::GetInstance ();
	gui->HideShutDown ();
	m_targetCamera->SetScene(NULL);
}
	
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReactToIncommingMissile()
{
	Check_Object(this);

	PLAY_SOUND(INCOMING_MISSILE);
}

// MSL 5.03 Ammo Dump
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReactToAmmoDump()
{
	Check_Object(this);

	PLAY_SOUND(AMMO_DUMPED);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReactToOutOfAmmo()
{
	Check_Object(this);

	if ((m_LastAmmoDepletedSoundTime+OUT_AMMO_SOUND_DELAY) < gos_GetElapsedTime())
	{
		m_LastAmmoDepletedSoundTime = gos_GetElapsedTime ();
		PLAY_SOUND(OUT_OF_AMMO);
	}
}
		
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReactToMissileLock(bool lock)
{
	Check_Object(this);

	if (lock)
	{
		if ((g_nMR != 2) && !m_missileLockSound.GetCurrent())
		{
			AudioCommand *command = AudioCommand::Create(
				MISSILE_LOCK_TYPE,
				MISSILE_LOCK_WAV,
				1.0f,
				1.0f
			);
			Check_Object(command);
			m_missileLockSound.Add(command);
			command->Play(gosAudio_Loop);
		}
	}
	else if (m_missileLockSound.GetCurrent())
	{
		m_missileLockSound.GetCurrent()->Stop();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReactToZoom()
{
	Check_Object(this);

	PLAY_SOUND(ZOOM);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ReactToAMS()
{
	Check_Object(this);

	PLAY_SOUND(AMS);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::ReactToLAMS()
{
	Check_Object(this);

	PLAY_SOUND(LAMS);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReactToCoolantFlush(bool start)
{
	Check_Object(this);

	if (start)
	{
		if ((g_nMR != 2) && !m_coolantSound.GetCurrent())
		{
			AudioCommand *command = AudioCommand::Create(COOLANT_TYPE, COOLANT_WAV, 1.0f, 1.0f);
			Check_Object(command);
			m_coolantSound.Add(command);
			command->Play(gosAudio_Loop);
		}
	}
	else if (m_coolantSound.GetCurrent())
	{
		m_coolantSound.GetCurrent()->Stop();
		PLAY_SOUND(COOLANT_END);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReactToCriticalWeaponHit()
{
	Check_Object(this);

	PLAY_SOUND(WEAPON_DESTROYED);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReactToHeatMeltdown()
{
	Check_Object(this);

	PLAY_SOUND(CORE_BREACHED);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::ReactToTargetDestruction()
{
	Check_Object(this);

    if (CTCL_IsNone())
	PLAY_SOUND(TARGET_DESTROYED);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void VehicleInterface::SetGUITarget(Entity* target)
{
    if (g_pCurTOC) {
		g_LastTarget = ReplicatorID::Null;
    }
	m_interfaceTarget.Remove();
	m_targetCamera->SetScene(NULL);
	MWGUIManager::GetInstance()->SetNewTargetWindowEntity(target);
	if (target)
	{
		m_interfaceTarget.Add(target);
		ReactToEvent (OBJECT_SCANNED);
		if (ShowTargetCamera ())
			m_targetCamera->SetScene(target->GetElement());
		else
			m_targetCamera->SetScene (NULL);
	}
}

Entity* VehicleInterface::GetGUITarget()
{
	return (m_interfaceTarget.GetCurrent());
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool __stdcall MechWarrior4::Check_MouseControl(void)
{
	if (VehicleInterface::GetInstance() == 0)
	{
		return (false);
	}

	return (VehicleInterface::GetInstance()->m_MouseEnable);
}

void __stdcall MechWarrior4::Activate_MouseControl(void)
{

	if (VehicleInterface::GetInstance() == 0)
	{
		return ;
	}

	VehicleInterface::GetInstance()->m_MouseEnable = !VehicleInterface::GetInstance()->m_MouseEnable;
}

void
	VehicleInterface::SetBoundsWarningsEnabled(bool enabled)
{
	m_BoundsWarningsEnabled = enabled;
}

bool

VehicleInterface::GetBoundsWarningsEnabled() const
{
	return (m_BoundsWarningsEnabled);
}

void VehicleInterface::SetCinemaPlaying(bool value)
{
	Check_Object(this);
	cinemaPlaying = value;
	if (MWGUIManager::GetInstance ())
	{
		if (value)
		{
			ReactToEvent (MISSILE_LOCKLOST);
			MWGUIManager::GetInstance ()->Hide ();
			HideZoom ();
			VehicleInterface::GetInstance ()->requestedZoomChange = false;
			VehicleInterface::GetInstance ()->userRequestForreticuleZoomChange = true;
			if (vehicle->DoesHaveLightAmp() &&
					MWGUIManager::GetInstance()->lightAmp && MWGUIManager::GetInstance()->lightAmp->IsOn())
			{
					MWGUIManager::GetInstance()->HideLightAmplification();
					Mission::GetInstance()->ResetMissionLights();
			}
		}
		else
			MWGUIManager::GetInstance ()->ReshowHud ();
	}
	if (!value)
	{
		RestorePreferredCameraPosition();
	}
	else
	{
		cinemaPlaying = false;
		ReactToEvent (MISSILE_LOCKLOST);
		cinemaPlaying = true;
	}
};



Stuff::Scalar
	VehicleInterface::GetLastTimeFiredWeaponGroup(int weapon_group) const
{
	Verify(weapon_group >= 0);
	Verify(weapon_group < 6);

	return (m_LastTimeFiredWeaponGroup[weapon_group]);
}


void MechWarrior4::VehicleInterfaceSecurityCheckStop()
{
	_asm
	{
		nop
	}	
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	VehicleInterface::TakeSnapShotMessageHandler(
		ReceiverDataMessageOf<int> *message
	)
{
	Check_Object(this);
	Check_Object(message);
	Verify(message->messageID == TakeSnapShotMessageID);

	if(message->dataContents > 0)
	{	
    //
    // Toggle the state of the game logic
    //
#ifdef LAB_ONLY
		CallDebuggerMenuItem("Rasterizer\\Save screen shot", gosMenu_Activated);
#else

		End3DScene();
		BYTE* Image=GrabScreenImage(NULL, 0, 0);
        WriteImageAfterGrab(Image, "screen%04d.%s");
#endif
	}
}

// [MSR SPECTATOR STUFF] ===========================================================

// SPECTATOR CAMERAS -------------


void VehicleInterface::ClearFixedPoint()
{
	m_fixedPoint = Stuff::Point3D::Identity;
}


void VehicleInterface::DampedOverShoulderShot(LinearMatrix4D parentLocalToWorld, Point3D heroPos, Point3D enemyPos, int shotRangeTypeID)
{
	LinearMatrix4D cameraToParent;
	LinearMatrix4D cameraToWorld;

	// ---- offset Enemy point ----------------------

	Vector3D paramEnemyOffset;
	paramEnemyOffset.y = -5.0f; // OVER_SHOULDER_ENEMY_OFFSET_Y

	heroPos.y += 4.0f;

	Vector3D vectorToHero;
	vectorToHero.Subtract(heroPos, enemyPos);

	// keep our enemy viewed in third right of screen
	float tempDist = vectorToHero.GetLength();
	paramEnemyOffset.x = tempDist * 0.2f;

	vectorToHero.Normalize(vectorToHero);

	Vector3D rightEnemyVec;
	rightEnemyVec.Cross(vectorToHero, Vector3D::Up);

	Point3D tempEnemyPnt1, tempEnemyPnt2;
	tempEnemyPnt1.AddScaled(enemyPos, rightEnemyVec, paramEnemyOffset.x);
	tempEnemyPnt2.AddScaled(tempEnemyPnt1, Vector3D::Up, paramEnemyOffset.y);

	//----- offset Hero point -----------------------
	
	Vector3D paramHeroOffset;
	paramHeroOffset.x = 4.5f; // OVER_SHOULDER_HERO_OFFSET_X
	paramHeroOffset.y = 1.0f; // OVER_SHOULDER_HERO_OFFSET_Y
	paramHeroOffset.z = -10.0f; // OVER_SHOULDER_HERO_OFFSET_Z

	switch(shotRangeTypeID)
	{
	case CLOSESHOT:
		// default INI data
		break;

	case MEDIUMSHOT:
		paramHeroOffset.x *= 1.2f;
		paramHeroOffset.y *= 0.4f;
		paramHeroOffset.z *= 2.0f;
		break;

	case LONGSHOT:
		paramHeroOffset.x *= 3.0f;
		paramHeroOffset.y *= 1.3f;
		paramHeroOffset.z *= 4.0f;
		break;
	}

	Vector3D vectorToEnemy;
	vectorToEnemy.Subtract(tempEnemyPnt2, heroPos);
	vectorToEnemy.Normalize(vectorToEnemy);

	Vector3D rightHeroVec;
	rightHeroVec.Cross(vectorToEnemy, Vector3D::Up);
	
	Point3D tempHeroPnt1, tempHeroPnt2, tempHeroPnt3;
	tempHeroPnt1.AddScaled(heroPos, vectorToEnemy, paramHeroOffset.z);
	tempHeroPnt2.AddScaled(tempHeroPnt1, rightHeroVec, paramHeroOffset.x);


	// find the ground relative to this camera pos
	Point3D worldPos;
	worldPos = tempHeroPnt2;

	Stuff::Normal3D normal;
	Stuff::Line3D line;
	CollisionQuery query(&line, &normal, CanBeWalkedOnFlag, this);

	line.m_length = g_CamerashipParams.m_fDistGroundLevel;
	line.m_direction = Vector3D(0.0f, -1.0f, 0.0f);
	line.m_origin = worldPos;
	// push well up above the ground before looking for collision
	line.m_origin.y += g_CamerashipParams.m_fDistGroundLevelShift;

	Adept::Entity *entityHit;
	Check_Object(CollisionGrid::Instance);
	entityHit = CollisionGrid::Instance->ProjectLine(&query);
	float groundOffsetY = 0.0f;
	if(entityHit != NULL)
	{
		line.FindEnd(&worldPos);
		groundOffsetY = (worldPos.y + 8.0f + paramHeroOffset.y ); // 8.0 average height of a mech
	}

	// distance our camera from the ground
	Point3D tempPnt1, tempPnt2;
	tempPnt1 = tempHeroPnt2;
	tempPnt1.y = 0.0f;
	tempPnt2.AddScaled(tempPnt1, Vector3D::Up, groundOffsetY);


	vectorToEnemy.Subtract(tempEnemyPnt2, tempPnt2);
	vectorToEnemy.Normalize(vectorToEnemy);
	
	// align and build the camera to the world

	cameraToWorld.BuildIdentity();;
	cameraToWorld.AlignLocalAxisToWorldVector(vectorToEnemy, Z_Axis, Y_Axis, X_Axis);
	cameraToWorld.BuildTranslation(tempPnt2);

	cameraToParent.Multiply(cameraToWorld, parentLocalToWorld.Invert());

	SetNewLocalToParent(cameraToParent);
	SyncMatrices(true);
	cameraDirty = true;
}





void VehicleInterface::OverShoulderShot(LinearMatrix4D parentLocalToWorld, LinearMatrix4D targetLocalToWorld, int shotRangeTypeID)
{
	LinearMatrix4D cameraToParent;
	LinearMatrix4D cameraToWorld;

	// ---- offset Enemy point ----------------------

	Vector3D paramEnemyOffset;

	Point3D heroPos;
	heroPos = parentLocalToWorld;
	heroPos.y += 4.0f;

	Point3D enemyPos;
	enemyPos = targetLocalToWorld;

	Vector3D vectorToHero;
	vectorToHero.Subtract(heroPos, enemyPos);

	// keep our enemy viewed in third right of screen
	float tempDist = vectorToHero.GetLength();
	paramEnemyOffset.x = tempDist * 0.2f;
	paramEnemyOffset.y = g_CamerashipParams.m_fOffsOverShoulderEnemyY; // OVER_SHOULDER_ENEMY_OFFSET_Y

	vectorToHero.Normalize(vectorToHero);

	Vector3D rightEnemyVec;
	rightEnemyVec.Cross(vectorToHero, Vector3D::Up);

	Point3D tempEnemyPnt1, tempEnemyPnt2;
	tempEnemyPnt1.AddScaled(enemyPos, rightEnemyVec, paramEnemyOffset.x);
	tempEnemyPnt2.AddScaled(tempEnemyPnt1, Vector3D::Up, paramEnemyOffset.y);

	//----- offset Hero point -----------------------
	
	Vector3D paramHeroOffset;
	paramHeroOffset.x = g_CamerashipParams.m_fOffsOverShoulderHeroX; // OVER_SHOULDER_HERO_OFFSET_X
	paramHeroOffset.y = g_CamerashipParams.m_fOffsOverShoulderHeroY; // OVER_SHOULDER_HERO_OFFSET_Y
	paramHeroOffset.z = g_CamerashipParams.m_fOffsOverShoulderHeroZ; // OVER_SHOULDER_HERO_OFFSET_Z

	switch(shotRangeTypeID)
	{
    default: // case NO_RANGE: // temporary range to find over-should value...
	//case CLOSESHOT:
		// default INI data
		break;

	case MEDIUMSHOT:
		paramHeroOffset.x *= 1.2f;
		paramHeroOffset.y *= 0.4f;
		paramHeroOffset.z *= 2.0f;
		break;

	case LONGSHOT:
		paramHeroOffset.x *= 3.0f;
		paramHeroOffset.y *= 1.3f;
		paramHeroOffset.z *= 4.0f;
		break;
	}

	Vector3D vectorToEnemy;
	vectorToEnemy.Subtract(tempEnemyPnt2, heroPos);
	vectorToEnemy.Normalize(vectorToEnemy);

	Vector3D rightHeroVec;
	rightHeroVec.Cross(vectorToEnemy, Vector3D::Up);
	
	Point3D tempHeroPnt1, tempHeroPnt2, tempHeroPnt3;
	tempHeroPnt1.AddScaled(heroPos, vectorToEnemy, paramHeroOffset.z);
	tempHeroPnt2.AddScaled(tempHeroPnt1, rightHeroVec, paramHeroOffset.x);


	// find the ground relative to this camera pos
	Point3D worldPos;
	worldPos = tempHeroPnt2;

	Stuff::Normal3D normal;
	Stuff::Line3D line;
	CollisionQuery query(&line, &normal, CanBeWalkedOnFlag, this);
	
	line.m_length = g_CamerashipParams.m_fDistGroundLevel;
	line.m_direction = Vector3D(0.0f, -1.0f, 0.0f);
	line.m_origin = worldPos;
	// push well up above the ground before looking for collision
	line.m_origin.y += g_CamerashipParams.m_fDistGroundLevelShift;

	Adept::Entity *entityHit;
	Check_Object(CollisionGrid::Instance);
	entityHit = CollisionGrid::Instance->ProjectLine(&query);
	float groundOffsetY = 0.0f;
	if(entityHit != NULL)
	{
		line.FindEnd(&worldPos);
		groundOffsetY = (worldPos.y + 8.0f + paramHeroOffset.y ); // 8.0 average height of a mech
	}

	// distance our camera from the ground
	Point3D tempPnt1, tempPnt2;
	tempPnt1 = tempHeroPnt2;
	tempPnt1.y = 0.0f;
	tempPnt2.AddScaled(tempPnt1, Vector3D::Up, groundOffsetY);


	vectorToEnemy.Subtract(tempEnemyPnt2, tempPnt2);
	vectorToEnemy.Normalize(vectorToEnemy);
	
	// align and build the camera to the world

	cameraToWorld.BuildIdentity();;
	cameraToWorld.AlignLocalAxisToWorldVector(vectorToEnemy, Z_Axis, Y_Axis, X_Axis);
	cameraToWorld.BuildTranslation(tempPnt2);

	cameraToParent.Multiply(cameraToWorld, parentLocalToWorld.Invert());

#if USE_DEATH_OVERSHOULD
    if (shotRangeTypeID == NO_RANGE) {
        g_camToParent4Temp = cameraToParent;
    } else {
#endif // USE_DEATH_OVERSHOULD
	SetNewLocalToParent(cameraToParent);
	SyncMatrices(true);
	cameraDirty = true;
#if USE_DEATH_OVERSHOULD
    }
#endif // USE_DEATH_OVERSHOULD
}


void VehicleInterface::SideShot(LinearMatrix4D parentLocalToWorld, LinearMatrix4D targetLocalToWorld)
{
	float deltaX = g_CamerashipParams.m_fOffsSideShotX; // SIDE_SHOT_DELTA_X
	float deltaY = g_CamerashipParams.m_fOffsSideShotY; // SIDE_SHOT_DELTA_Y
	float headY = g_CamerashipParams.m_fOffsSideShotHeadY; // SIDE_SHOT_HEAD_Y

	LinearMatrix4D cameraToParent;
	LinearMatrix4D cameraToWorld;

	Point3D heroPos;
	heroPos = parentLocalToWorld;
	heroPos.y += headY;

	Point3D enemyPos;
	enemyPos = targetLocalToWorld;

	Vector3D vectorToEnemy;
	vectorToEnemy.Subtract(enemyPos, heroPos);

	Vector3D paramOffset;
	float dist = vectorToEnemy.GetLength();
	paramOffset.x = dist / deltaX;
	paramOffset.y = dist / deltaY;

	vectorToEnemy.Normalize(vectorToEnemy);

	Vector3D rightVector;
	rightVector.Cross(vectorToEnemy, Vector3D::Up);
	
	Point3D tempPnt1, tempPnt2, tempPnt3;
	tempPnt1.AddScaled(heroPos, vectorToEnemy, dist/2.0f);
	tempPnt2.AddScaled(tempPnt1, rightVector, paramOffset.x);
	tempPnt3.AddScaled(tempPnt2, Vector3D::Up, paramOffset.y);

	// find the ground 
	Stuff::Normal3D normal;
	Stuff::Line3D line;
	CollisionQuery query(&line, &normal, CanBeWalkedOnFlag, this);
	
	// we want to check the Y out where the camera will be
	Point3D worldPos;
	worldPos = tempPnt3;
	line.m_length = g_CamerashipParams.m_fDistGroundLevel;
	line.m_direction = Vector3D(0.0f, -1.0f, 0.0f);
	line.m_origin = worldPos;
	// push well up above the ground before looking for collision
	line.m_origin.y += g_CamerashipParams.m_fDistGroundLevelShift;

	Adept::Entity *entityHit;
	Check_Object(CollisionGrid::Instance);
	entityHit = CollisionGrid::Instance->ProjectLine(&query);
	// float groundOffsetY = 0.0f;
	if(entityHit != NULL)
	{
		line.FindEnd(&worldPos);
		tempPnt3.y = (worldPos.y + paramOffset.y);
		
	}

	Vector3D vectorToMidpt;
	vectorToMidpt.Subtract(tempPnt1, tempPnt3);
	vectorToMidpt.Normalize(vectorToMidpt);
	
	cameraToWorld.BuildIdentity();;
	cameraToWorld.AlignLocalAxisToWorldVector(vectorToMidpt, Z_Axis, Y_Axis, X_Axis);
	cameraToWorld.BuildTranslation(tempPnt3);

	cameraToParent.Multiply(cameraToWorld, parentLocalToWorld.Invert());

	SetNewLocalToParent(cameraToParent);
	SyncMatrices(true);
	cameraDirty = true;
}

void VehicleInterface::FrontShot(LinearMatrix4D parentLocalToWorld, LinearMatrix4D targetLocalToWorld, int shotRangeTypeID)
{
	float headY = g_CamerashipParams.m_fOffsFrontShotHeadY; //FRTSHOT_HEAD_Y
	float camY = g_CamerashipParams.m_fOffsFrontShotCameraY; //FRTSHOT_CAM_Y
	float dist = g_CamerashipParams.m_fDistFrontShot; //FRTSHOT_DIST

	switch(shotRangeTypeID)
	{
	case CLOSESHOT:
		// default INI data
		break;
	case MEDIUMSHOT:
		camY += camY/2;
		dist += dist;
		break;
	case LONGSHOT:
		camY *= 2;
		dist *= 4;
		break;
	}
	
	LinearMatrix4D cameraToParent;
	LinearMatrix4D cameraToWorld;
	LinearMatrix4D cameraTrans;
	LinearMatrix4D cameraRot;


	Point3D heroPos, heroPosOrigin;
	heroPos = heroPosOrigin = parentLocalToWorld;
	heroPos.y += headY;

	// zero out the y's so we don't have bad pitching when calculating to the ground
	Point3D levelHeroPos;
	levelHeroPos = parentLocalToWorld;
	levelHeroPos.y = 0.0f;

	Point3D levelEnemyPos;
	levelEnemyPos = targetLocalToWorld;
	levelEnemyPos.y = 0.0f;

	Vector3D vectorToEnemy;
	vectorToEnemy.Subtract(levelEnemyPos, levelHeroPos);
	vectorToEnemy.Normalize(vectorToEnemy);

	Point3D tempPnt1;
	tempPnt1.AddScaled(levelHeroPos, vectorToEnemy, dist);

	// find the ground relative to our hero
	Point3D worldPos;
	worldPos = tempPnt1;

	Stuff::Normal3D normal;
	Stuff::Line3D line;
	CollisionQuery query(&line, &normal, CanBeWalkedOnFlag, this);
	
	// we want to check the Y out where the camera will be
	// so we temporarily project our hero there to get a relative Y to the local terrain
	worldPos.y = heroPos.y;
	line.m_length = g_CamerashipParams.m_fDistGroundLevel;
	line.m_direction = Vector3D(0.0f, -1.0f, 0.0f);
	line.m_origin = worldPos;
	// push well up above the ground before looking for collision
	line.m_origin.y += g_CamerashipParams.m_fDistGroundLevelShift;

	Adept::Entity *entityHit;
	Check_Object(CollisionGrid::Instance);
	entityHit = CollisionGrid::Instance->ProjectLine(&query);

	// we want to keep the ground referenced, even when we're flying
	float groundOffsetY = 0.0f;
	float mechToGroundOffset;
	if(entityHit != NULL)
	{
		line.FindEnd(&worldPos);
		groundOffsetY = (worldPos.y + camY);
	}

	mechToGroundOffset = heroPosOrigin.y - worldPos.y;

	if ((heroPosOrigin.y - camY)+mechToGroundOffset > groundOffsetY)
	{
	tempPnt1.y = 0.0f;
	tempPnt1.AddScaled(tempPnt1, Vector3D::Up, (heroPosOrigin.y - camY)+mechToGroundOffset);
	}
	else
	{
	tempPnt1.y = 0.0f;
	tempPnt1.AddScaled(tempPnt1, Vector3D::Up, groundOffsetY);
	}

	

	Vector3D vectorMidPtToHero;
	vectorMidPtToHero.Subtract(heroPos, tempPnt1);
	vectorMidPtToHero.Normalize(vectorMidPtToHero);
	
	
	// align and build the camera to the world

	cameraToWorld.BuildIdentity();;
	cameraToWorld.AlignLocalAxisToWorldVector(vectorMidPtToHero, Z_Axis, Y_Axis, X_Axis);
	cameraToWorld.BuildTranslation(tempPnt1);

	cameraToParent.Multiply(cameraToWorld, parentLocalToWorld.Invert());

	SetNewLocalToParent(cameraToParent);
	SyncMatrices(true);
	cameraDirty = true;
}

void VehicleInterface::FixedTracking(LinearMatrix4D targetLocalToWorld, int shotRangeTypeID)
{
	float offsetX = g_CamerashipParams.m_fOffsFixedTrackingX; // FIXED_TRACK_X
	float offsetY = g_CamerashipParams.m_fOffsFixedTrackingY; // FIXED_TRACK_Y
	float offsetZ = g_CamerashipParams.m_fOffsFixedTrackingZ; // FIXED_TRACK_Z

	switch(shotRangeTypeID)
	{
	case CLOSESHOT:
		// default values from INI data
		break;
	case MEDIUMSHOT:
		offsetZ *= 2.0f;
		offsetY += offsetY * 0.25f;
		break;
	case LONGSHOT:
		offsetZ *= 4.0f;
		offsetY += offsetY * 0.5f;
		break;
	}

	LinearMatrix4D cameraToParent;
	LinearMatrix4D cameraToWorld;

	if (m_fixedPoint == Stuff::Point3D::Identity)
	{
		Point3D fixedPnt;
		fixedPnt = targetLocalToWorld;
		fixedPnt.x += offsetX;
		fixedPnt.y += offsetY;
		fixedPnt.z += offsetZ;

		m_fixedPoint = fixedPnt;
	}

	// find the ground relative to this camera pos
	Point3D worldPos;
	worldPos = m_fixedPoint;

	Stuff::Normal3D normal;
	Stuff::Line3D line;
	CollisionQuery query(&line, &normal, CanBeWalkedOnFlag, this);
	
	line.m_length = g_CamerashipParams.m_fDistGroundLevel;
	line.m_direction = Vector3D(0.0f, -1.0f, 0.0f);
	line.m_origin = worldPos;
	// push well up above the ground before looking for collision
	line.m_origin.y += g_CamerashipParams.m_fDistGroundLevelShift;

	Adept::Entity *entityHit;
	Check_Object(CollisionGrid::Instance);
	entityHit = CollisionGrid::Instance->ProjectLine(&query);
	float groundOffsetY = 0.0f;
	if(entityHit != NULL)
	{
		line.FindEnd(&worldPos);
		groundOffsetY = (worldPos.y + offsetY);
	}

	// distance our camera from the ground
	Point3D tempCamPos;
	tempCamPos = m_fixedPoint;
	if (tempCamPos.y < groundOffsetY)
	{
		tempCamPos.y = 0.0f;
		tempCamPos.AddScaled(tempCamPos, Vector3D::Up, groundOffsetY);
	}

	Point3D heroPos;
	heroPos = targetLocalToWorld;
	heroPos.y += offsetY/3;

	Vector3D vectorFixedToHero;
	vectorFixedToHero.Subtract(heroPos, tempCamPos);
	vectorFixedToHero.Normalize(vectorFixedToHero);

	cameraToWorld.BuildIdentity();;
	cameraToWorld.AlignLocalAxisToWorldVector(vectorFixedToHero, Z_Axis, Y_Axis, X_Axis);
	cameraToWorld.BuildTranslation(tempCamPos);

	cameraToParent.Multiply(cameraToWorld, targetLocalToWorld.Invert());

	SetNewLocalToParent(cameraToParent);
	SyncMatrices(true);
	cameraDirty = true;
}

void VehicleInterface::HeroDeathToEnemyStart(LinearMatrix4D dyingLocalToWorld)
{
	float offsetX = g_CamerashipParams.m_fOffsDeathWatchingX;
	float offsetY = g_CamerashipParams.m_fOffsDeathWatchingY;
	float offsetZ = g_CamerashipParams.m_fOffsDeathWatchingZ;

	LinearMatrix4D cameraToParent;
	LinearMatrix4D cameraToWorld;

	Point3D newHeroPos;
	Point3D dyingHeroPos;

	bool fTransitionDone = false;

	gosASSERT(m_fixedPoint == Stuff::Point3D::Identity);
	// define our camera start pos
	m_fixedPoint = dyingLocalToWorld;
	m_fixedPoint.y += 20.0f;
	m_fixedPoint.z += -15.0f;

	// store focal point
	m_dyingHeroPoint = dyingLocalToWorld;
	
	// find the ground relative to this camera pos
	Point3D worldPos;
	worldPos = m_fixedPoint;

	Stuff::Normal3D normal;
	Stuff::Line3D line;
	CollisionQuery query(&line, &normal, CanBeWalkedOnFlag, this);
	
	line.m_length = g_CamerashipParams.m_fDistGroundLevel;
	line.m_direction = Vector3D(0.0f, -1.0f, 0.0f);
	line.m_origin = worldPos;
	// push well up above the ground before looking for collision
	line.m_origin.y += g_CamerashipParams.m_fDistGroundLevelShift;

	Adept::Entity *entityHit;
	Check_Object(CollisionGrid::Instance);
	entityHit = CollisionGrid::Instance->ProjectLine(&query);
	float groundOffsetY = 0.0f;
	if(entityHit != NULL)
	{
		line.FindEnd(&worldPos);
		groundOffsetY += worldPos.y + 18.0f;
	}

	// distance our camera from the ground
	m_fixedPoint.y = 0.0f;
	m_fixedPoint.AddScaled(m_fixedPoint, Vector3D::Up, groundOffsetY);
    m_oldEnemyPos = m_fixedPoint;

	Point3D tempDyingPnt;
	tempDyingPnt = m_dyingHeroPoint;
	
	// position and point the camera from the new position
	Vector3D vectorHeroToDying;
	vectorHeroToDying.Subtract(tempDyingPnt, m_fixedPoint);
	vectorHeroToDying.Normalize(vectorHeroToDying);

	cameraToWorld.BuildIdentity();;
	cameraToWorld.AlignLocalAxisToWorldVector(vectorHeroToDying, Z_Axis, Y_Axis, X_Axis);
	cameraToWorld.BuildTranslation(m_fixedPoint);

	cameraToParent.Multiply(cameraToWorld, dyingLocalToWorld.Invert());

	SetNewLocalToParent(cameraToParent);
	SyncMatrices(true);
	cameraDirty = true;
}

void VehicleInterface::HeroDeathToEnemyTrans(LinearMatrix4D dyingLocalToWorld, float fPer, const LinearMatrix4D& newHeroLocalToWorld/* = *(const LinearMatrix4D*)NULL*/)
{
	float offsetX = g_CamerashipParams.m_fOffsDeathWatchingX;
	float offsetY = g_CamerashipParams.m_fOffsDeathWatchingY;
	float offsetZ = g_CamerashipParams.m_fOffsDeathWatchingZ;

	LinearMatrix4D cameraToParent;
	LinearMatrix4D cameraToWorld;

	Point3D newHeroPos;
	Point3D dyingHeroPos;

	// calculate the new heros over shoulder point from now
	// calculate the current percent time
	double curPcntTime = fPer;
    if (curPcntTime < 0.00001)
        curPcntTime = 0.0;
    else if (curPcntTime >= 0.99999)
        curPcntTime = 1.0;

    m_fixedPoint = m_oldEnemyPos;
#if DEATH_TRANS_2
	Point3D inter2(m_dyingHeroPoint);
#endif // DEATH_TRANS_2
    if (&newHeroLocalToWorld) {
	    newHeroPos = newHeroLocalToWorld;
	    // apply ease-in ease-out modifications to current time percent;
	    if (curPcntTime < 0.5)
	    {
		    curPcntTime = pow( (2.0 * curPcntTime), 0.8 ) * 0.5;
	    }
	    else
	    {
		    curPcntTime = ( 2.0 - pow( (2.0 * (1 - curPcntTime)), 0.8 ) ) * 0.5;
	    }
	    Vector3D vecTemp;
	    vecTemp.Subtract(newHeroPos, m_fixedPoint);

	    Point3D interpolatedPnt;
	    interpolatedPnt.x = float(m_fixedPoint.x + curPcntTime * vecTemp.x);
	    interpolatedPnt.y = float(m_fixedPoint.y + curPcntTime * vecTemp.y);
	    interpolatedPnt.z = float(m_fixedPoint.z + curPcntTime * vecTemp.z);

        float tempDist = vecTemp.GetLength();
        if (curPcntTime < 0.5)
            interpolatedPnt.y += tempDist * 0.30 * curPcntTime;
        else
            interpolatedPnt.y += tempDist * 0.30 * (1.0 - curPcntTime);

	    m_fixedPoint = interpolatedPnt;
#if DEATH_TRANS_2
	    vecTemp.Subtract(m_tempEnemyPos, inter2);

	    interpolatedPnt.x = float(inter2.x + curPcntTime * vecTemp.x);
	    interpolatedPnt.y = float(inter2.y + curPcntTime * vecTemp.y);
	    interpolatedPnt.z = float(inter2.z + curPcntTime * vecTemp.z);

	    inter2 = interpolatedPnt;
#endif // DEATH_TRANS_2
    }

	// find the ground relative to this camera pos
	Point3D worldPos;
	worldPos = m_fixedPoint;

	Stuff::Normal3D normal;
	Stuff::Line3D line;
	CollisionQuery query(&line, &normal, CanBeWalkedOnFlag, this);
	
	line.m_length = g_CamerashipParams.m_fDistGroundLevel;
	line.m_direction = Vector3D(0.0f, -1.0f, 0.0f);
	line.m_origin = worldPos;
	// push well up above the ground before looking for collision
	line.m_origin.y += g_CamerashipParams.m_fDistGroundLevelShift;

	Adept::Entity *entityHit;
	Check_Object(CollisionGrid::Instance);
	entityHit = CollisionGrid::Instance->ProjectLine(&query);
	float groundOffsetY = 0.0f;
	if(entityHit != NULL)
	{
		line.FindEnd(&worldPos);
		groundOffsetY = worldPos.y + m_fixedPoint.y;
	}

	// distance our camera from the ground
	m_fixedPoint.y = 0.0f;
	m_fixedPoint.AddScaled(m_fixedPoint, Vector3D::Up, groundOffsetY);

	// keep our dying hero viewed in third right of screen
	//float tempDist = vectorToNewHero.GetLength();
	//float tempX = tempDist * 0.2f;
	float tempX = 0.0f;

	Vector3D vectorToNewHero;
#if DEATH_TRANS_2
    vectorToNewHero.Subtract(m_fixedPoint, inter2/*m_dyingHeroPoint*/);
#else
	vectorToNewHero.Subtract(m_fixedPoint, m_dyingHeroPoint);
#endif

	vectorToNewHero.Normalize(vectorToNewHero);

	Vector3D rightEnemyVec;
	rightEnemyVec.Cross(vectorToNewHero, Vector3D::Up);


	Point3D tempDyingPnt1, tempDyingPnt2;
#if DEATH_TRANS_2
    tempDyingPnt1.AddScaled(inter2/*m_dyingHeroPoint*/, rightEnemyVec, tempX);
#else // !DEATH_TRANS_2
	tempDyingPnt1.AddScaled(m_dyingHeroPoint, rightEnemyVec, tempX);
#endif // DEATH_TRANS_2

	Vector3D vectorToDying;
	vectorToDying.Subtract(tempDyingPnt1, m_fixedPoint);
	vectorToDying.Normalize(vectorToDying);

	Vector3D rightHeroVec;
	rightHeroVec.Cross(vectorToDying, Vector3D::Up);
	
	Point3D tempHeroPnt1, tempHeroPnt2;
	tempHeroPnt1.AddScaled(m_fixedPoint, vectorToDying, float(curPcntTime * offsetZ));
	tempHeroPnt2.AddScaled(tempHeroPnt1, rightHeroVec, float(curPcntTime * offsetX));
	m_fixedPoint.AddScaled(tempHeroPnt2, Vector3D::Up, float(curPcntTime * offsetY));

	// position and point the camera from the new position
	Vector3D vectorOffsetHeroToDying;
#if DEATH_TRANS_2
	vectorOffsetHeroToDying.Subtract(inter2/*m_dyingHeroPoint*/, m_fixedPoint);
#else // !DEATH_TRANS_2
	vectorOffsetHeroToDying.Subtract(m_dyingHeroPoint, m_fixedPoint);
#endif // DEATH_TRANS_2
	vectorOffsetHeroToDying.Normalize(vectorOffsetHeroToDying);

	cameraToWorld.BuildIdentity();;
	cameraToWorld.AlignLocalAxisToWorldVector(vectorOffsetHeroToDying, Z_Axis, Y_Axis, X_Axis);
	cameraToWorld.BuildTranslation(m_fixedPoint);
	
	cameraToParent.Multiply(cameraToWorld, dyingLocalToWorld.Invert());

	SetNewLocalToParent(cameraToParent);
	SyncMatrices(true);
	cameraDirty = true;
}

void VehicleInterface::StdObserverMode(Point3D Camera_Point_LTW)
{
	Entity *parent;
    bool bUseTORSO;

    if (IsObserving(true) && observingEntity.GetCurrent()) {
        parent = observingEntity.GetCurrent();
		if (0.0f < g_CamerashipParams.m_fDistStandard)
			bUseTORSO = true;
		else
			bUseTORSO = false;
    } else {
        parent = GetParentEntity();
        bUseTORSO = false;
    }
    Point3D ptWorldPos;
    LinearMatrix4D camToParent;
    GetObserverPosition(parent, bUseTORSO, true, cameraOffset, cameraRotation, ptWorldPos, camToParent);

	SetNewLocalToParent(camToParent);
	SyncMatrices(true);
	cameraDirty = true;
}

void VehicleInterface::GetObserverPosition(Entity* parent, bool bUseTORSO, bool bUseInterpolation, Stuff::Point3D camOffset, Stuff::YawPitchRoll camRotation, Point3D& ptWorldPos, LinearMatrix4D& camToParent/* = *(LinearMatrix4D*)NULL*/)
{
	Check_Object(parent);
    gosASSERT(&ptWorldPos);

    Min_Clamp(camOffset.y, 2.0f);

    bool bUseAutoCamera = (0.0f < g_CamerashipParams.m_fDistStandard);
    if (bUseAutoCamera) {
        camOffset.x = GetGameModel()->cameraStartOffset.x;
		camOffset.z = g_CamerashipParams.m_fDistStandard;
        camOffset.y = g_CamerashipParams.m_fHeightStandard;
		camRotation.yaw = Pi;
    }
	camRotation.pitch = 0.0f;
	camRotation.roll = 0.0f;

    if (bUseTORSO) {
        Torso *torso = ((Vehicle*)parent)->GetTorso();
        Check_Object(torso);
        Stuff::Time fTime = gos_GetElapsedTime();
        if ((0.0f < s_fUseInter) && bUseInterpolation && (parent == m_pLastParent)) {
            Scalar fDif = torso->yawValue - m_fLastTorsoYAW;
            Stuff::Time fTimeDif = fTime - m_fLastTorsoTime;
            if (0.0 < fTimeDif) {
                // 1.0: s_fUseInter = fTimeDif: ?
                // ? = s_fUseInter * fTimeDif
                Scalar fValue = s_fUseInter * fTimeDif;
                fValue = static_cast<Scalar>(fValue * M_PI / 180.0);
                if (fDif < -fValue) {
                    m_fLastTorsoYAW += -fValue;
                } else if (+fValue < fDif) {
                    m_fLastTorsoYAW += +fValue;
                } else {
                    m_fLastTorsoYAW = torso->yawValue;
                }
                camRotation.yaw += m_fLastTorsoYAW;
            }
        } else {
		    camRotation.yaw += torso->yawValue;
            m_pLastParent = parent;
            m_fLastTorsoYAW = torso->yawValue;
        }
        m_fLastTorsoTime = fTime;
		camRotation.pitch += torso->pitchValue;
    }

	LinearMatrix4D camera_to_parent;
	LinearMatrix4D camera_to_world;
	LinearMatrix4D camera_trans;
	LinearMatrix4D camera_rot;
	LinearMatrix4D parent_local_to_world; // = parent->GetLocalToWorld();
	
	parent_local_to_world = parent->GetLocalToWorld();
	if (!bUseAutoCamera && g_bFixedCamera) {
		parent_local_to_world.BuildTranslation(g_ptFixedCameraPos);
	}
    camera_trans = camOffset;
	camera_rot = camRotation;

	camera_to_parent.Multiply(camera_trans,camera_rot);

    if (bUseAutoCamera) {
	    camera_to_world.Multiply(camera_to_parent, parent_local_to_world);
    } else {
	    LinearMatrix4D temp = parent_local_to_world;
	    temp.BuildRotation(YawPitchRoll::Identity);
	    camera_to_world.Multiply(camera_to_parent, temp);
    }
	Point3D world_position;
	world_position = camera_to_world;

	// find the ground here

	Point3D world_ground_position;
	Stuff::Normal3D normal;
	Stuff::Line3D line;
	CollisionQuery query(&line, &normal, CanBeWalkedOnFlag, this);
	
	line.m_length = g_CamerashipParams.m_fDistGroundLevel;
	line.m_direction = Vector3D(0.0f, -1.0f, 0.0f);
	line.m_origin = world_position;
	line.m_origin.y += g_CamerashipParams.m_fDistGroundLevelShift;

	Adept::Entity *entity_hit;
	Check_Object(CollisionGrid::Instance);
	entity_hit = CollisionGrid::Instance->ProjectLine(&query);
	if(entity_hit != NULL)
	{
		line.FindEnd(&world_position);
		world_position.y += camOffset.y;
	}

    if (world_position.y < (Map::GetInstance()->GetGameModel ()->m_waterLevel + 0.1)) {
        world_position.y = Map::GetInstance()->GetGameModel ()->m_waterLevel + 0.1;
    }
    ptWorldPos = world_position; // return WorldPosition...
    if (&camToParent) {
	    camera_to_world.BuildIdentity();
	    camera_to_world.BuildTranslation(world_position);

	    YawPitchRoll world_rotation = YawPitchRoll::Identity;
	    
        // point at the mech...
	    Point3D world_mech_position;
		if (!bUseAutoCamera && g_bFixedCamera)
			world_mech_position = g_ptFixedCameraPos;
		else
			world_mech_position = parent_local_to_world;
	    world_mech_position.y += g_CamerashipParams.m_fHeightStandardLookAt;

	    Point3D local_mech_position;
	    local_mech_position.MultiplyByInverse( world_mech_position , camera_to_world);

	    Vector3D vector_to_mech;
	    vector_to_mech = local_mech_position;

	    YawPitchRange polar_to_mech(vector_to_mech);

	    world_rotation.yaw = polar_to_mech.yaw;
	    world_rotation.pitch = polar_to_mech.pitch;

	    camera_to_world.BuildRotation(world_rotation);
	    
		if (!bUseAutoCamera && g_bFixedCamera) {
			parent_local_to_world = parent->GetLocalToWorld();
		}
		camera_to_parent.Multiply(camera_to_world, parent_local_to_world.Invert());

        camToParent = camera_to_parent; // return Matrix
    }
}
// END [MSR SPECTATOR STUFF] ===========================================================

bool VehicleInterface::SetNewRequestedTarget(Entity* target_entity)
{
    Entity* oldTarget = m_interfaceTarget.GetCurrent();
    if (oldTarget != target_entity) {
        g_fLastStartTime = gos_GetElapsedTime();
		if (oldTarget)
			g_LastTarget = oldTarget->GetReplicatorID();
		else {
			g_LastTarget = ReplicatorID::Null;
		}
        SetGUITarget(target_entity);
		if (g_pRIOMain->m_bFreeForAll)
			g_nTeamOrderMode = FREEFORALL_MODE;
		else 
			g_nTeamOrderMode = TEAM_MODE;

        return true;
    }

    return false;
}

int VehicleInterface::IsObserving(bool bIncObserverMode/* = false*/) const
{
    if (observerMode) {
        if (bIncObserverMode)
            return 1;
    } else {
        if (g_nMR == 2)
            return 1;
    }

    return 0;
}

int VehicleInterface::GetShutdownState() const
{
    if (vehicle) {
        if (vehicle->IsDerivedFrom(Mech::DefaultData)) {
        	Mech *mech = Cast_Object(Mech *, vehicle);

            return mech->IsShutdown() ? 1: 0;
        } else {
            return -1; // no mech
        }
    }

    return -2; // no vehicle
}

int VehicleInterface::GetJumpJetState() const
{
    if (vehicle) {
        if (vehicle->IsDerivedFrom(Mech::DefaultData)) {
        	Mech *mech = Cast_Object(Mech *, vehicle);

            return mech->GetJumpJetState();
        } else {
            return -2; // no mech
        }
    }

    return -3; // no vehicle
}

int VehicleInterface::GetGUIRadarStates(int state[/*12*/]) const
{
    if (this) {
        if (vehicle) {
            if (vehicle->IsDerivedFrom(Mech::DefaultData)) {
        	    Mech *mech = Cast_Object(Mech *, vehicle);

                int i;

	            for(i = 0; i < 10; i++) {
                    int index = (i < 6) ? 16 + i: 24 + (i - 6); // 16+i+(i/6*2);
		            //int index=16+i;
		            //BYTE& lamp=g_Button_Table[index].lamp;
		            state[i] = (IsLampOFF (index)==1) ? 0: 1;
	            }
	            //state[1] = mech->IsShutdown () ? 2: 1;
	            state[4] = state[4] ? (mech->IsCrouched ()? 2 : 1) : 0;
	            state[5]=g_nProgramMode?2:1;
	            if(g_UsingLightAmp)state[8]=2;
	            if(g_UsingSearchLight)state[9]=2;

	            state[10]=(MechWarrior4::VehicleInterface::perminateTorsoMode != MechWarrior4::VehicleInterface::LeaveTorsoAlone)?2:1;
// MSL 5.03 Secondary Damage Display
				state[2]=g_nAuxilMode;
	            state[11]=g_nInputMode;

				if (GetJumpJetState() > 0) {
	                if (g_bJumpZoom)
					{
				            strcpy(&g_aaRadarText[0][0], g_szRadarJumpjet);
					}
						else
					{
							strcpy(&g_aaRadarText[0][0], g_szRadarZoom);
				}
				}
				else
				{
					strcpy(&g_aaRadarText[0][0], g_szRadarZoom);
				}


				if (!g_bJumpZoom)
				{
					if (g_nInputMode != _BIGINNER_MODE)
						if (reticuleZoomShowing)
							state[0] = 2;
						else
							state[0] = 1;
				}


                if (state[i])
                    strcpy(&g_aaRadarText[1][0], g_szRadarShutdown);
                else
                    strcpy(&g_aaRadarText[1][0], g_szRadarStartup);

                return +1;
            } else {
                return 0;
            }
        } else {
            return -1;
        }
    } else {
        return -999;
    }
}

int VehicleInterface::GetEjectableState() const
{
    if (!vehicle || vehicle->IsDestroyed())
        return 0;
    if (vehicle->IsDerivedFrom(Mech::DefaultData)) {
        Mech* mech = Cast_Object(Mech*, vehicle);
        Check_Object(mech);

        if (mech->m_needSelfDestruct)
            return -1;
        if (g_bCanSuicideAllways)
            return 1;
// MSL 5.04 Eject Enabled if Gimped
		if (mech->IsGimped())
			return 1;

#if !defined(_DEBUG)
        if (CTCL_IsConsoleX()) {
#endif // !defined(_DEBUG)
            //if (g_nInputMode != _BIGINNER_MODE) {
	            Subsystem *subsystem;
	            ChainIteratorOf<Subsystem*> iterator(&mech->subsystemsInVehicle);
	            while((subsystem = iterator.ReadAndNext()) != NULL)
	            {
		            if(subsystem->IsDerivedFrom(Weapon::DefaultData))
		            {
			            Weapon *weapon = Cast_Object(Weapon *, subsystem);
			            Check_Object(weapon);
                        if (!(weapon->executionState->GetState() == Subsystem::ExecutionStateEngine::DestroyedState)/*don't use weapon->IsDestroyed()*/ && (weapon->IsDerivedFrom(BeamWeapon::DefaultData) || weapon->DoesHaveAmmo()))
						{
							g_nNoWeapons = 0; // Set to 0 to reset no weapon audio trigger
			                return 0;
                        }
		            }
	            }
// MSL 5.03 No Weapon Audio Trigger
				if (g_nNoWeapons == 0)
				{
					g_nNoWeapons = 1; // Set to 1 if no weapons and to trigger no weapon audio
				}
                return 1;
            //}
#if !defined(_DEBUG)
        } else {
            return +1;
        }
#endif // !defined(_DEBUG)
    }

    return 0;
}

CamerashipParams::CamerashipParams()
{
    m_bAllowChatDisplay = true;
    m_bAllowBOTs = false;
    m_bDisplayCameraStates = false;
    m_fDistGroundLevel = 800.0f;
    m_fDistGroundLevelShift = 400.0f;
    m_fTimeScoringInterval = 30.0f;
    m_fTimeScoringDuration = 5.0f;
    m_fTimeIdleChange = 8.0;
    m_fTimeStandard = 1.5f;
    m_fDistStandard = 35.0f;
    m_fHeightStandard = 12.0;
    m_fHeightStandardLookAt = 5.0;
    m_fTimeDeathWatching = 2.7f;
    m_fOffsDeathWatchingX = 0.0f;
    m_fOffsDeathWatchingY = 4.0f;
    m_fOffsDeathWatchingZ = -50.0f;
    m_fTimeDeathTransition = 1.3f;
    m_fTimeFixedTracking = 3.0f;
    m_fOffsFixedTrackingX = 1.0f;
    m_fOffsFixedTrackingY = 15.0f;
    m_fOffsFixedTrackingZ = 25.0f;
    m_fTimeSideShot = 3.0f;
    m_fDistSideShot = 90.0f;
    m_fOffsSideShotX = 0.7f;
    m_fOffsSideShotY = 5.0f;
    m_fOffsSideShotHeadY = 10.0f;
    m_fTimeFrontShot = 3.0f;
    m_fOffsFrontShotHeadY = 6.0f;
    m_fOffsFrontShotCameraY = 3.0f;
    m_fDistFrontShot = 15.0f;
    m_fTimeOverShoulder = 3.0f;
    m_fOffsOverShoulderHeroX = 4.5f;
    m_fOffsOverShoulderHeroY = 1.0f;
    m_fOffsOverShoulderHeroZ = -10.0f;
    m_fOffsOverShoulderEnemyY = -5.0;

    g_nSecsMissionReplay = 60;
    g_fSecsMissionReport = 15.0f;
}

void CamerashipParams::LoadOptions(NotationFile& startup_ini)
{
	Stuff::Page* pPage = startup_ini.FindPage("Cameraship Params");
	if (pPage)
	{
		bool bBoolean;

		if (pPage->GetEntry("AllowChatDisplay", &bBoolean))
            m_bAllowChatDisplay = bBoolean;
		if (pPage->GetEntry("AllowBOTs", &bBoolean))
            m_bAllowBOTs = bBoolean;
		if (pPage->GetEntry("DisplayCameraStates", &bBoolean))
            m_bDisplayCameraStates = bBoolean;

        Stuff::Scalar fScalar;

        if (pPage->GetEntry("DegreesPerSec", &fScalar)) {
            if ((-180.0 < fScalar) && (fScalar < 180.0))
                s_fUseInter = fScalar;
        }

        if (pPage->GetEntry("DistGroundLevel", &fScalar))
            m_fDistGroundLevel = fScalar;
        if (pPage->GetEntry("DistGroundLevelShift", &fScalar))
            m_fDistGroundLevelShift = fScalar;
        if (pPage->GetEntry("TimeScoringInterval", &fScalar))
            m_fTimeScoringInterval = fScalar;
        if (pPage->GetEntry("TimeScoringDuration", &fScalar))
            m_fTimeScoringDuration = fScalar;
        if (pPage->GetEntry("TimeScoringAtEnd", &fScalar))
            g_fTimeScoringAtEnd = fScalar;
        
        if (pPage->GetEntry("TimeIdleChange", &fScalar))
            m_fTimeIdleChange = fScalar;
        if (pPage->GetEntry("TimeStandard", &fScalar))
            m_fTimeStandard = fScalar;
        if (pPage->GetEntry("DistStandard", &fScalar))
            m_fDistStandard = fScalar;
        if (pPage->GetEntry("HeightStandard", &fScalar))
            m_fHeightStandard = fScalar;
        if (pPage->GetEntry("HeightStandardLookAt", &fScalar))
            m_fHeightStandardLookAt = fScalar;
        if (pPage->GetEntry("TimeDeathWatching", &fScalar))
            m_fTimeDeathWatching = fScalar;
        if (pPage->GetEntry("OffsDeathWatchingX", &fScalar))
            m_fOffsDeathWatchingX = fScalar;
        if (pPage->GetEntry("OffsDeathWatchingY", &fScalar))
            m_fOffsDeathWatchingY = fScalar;
        if (pPage->GetEntry("OffsDeathWatchingZ", &fScalar))
            m_fOffsDeathWatchingZ = fScalar;
        if (pPage->GetEntry("TimeDeathTransition", &fScalar))
            m_fTimeDeathTransition = fScalar;
        if (pPage->GetEntry("TimeFixedTracking", &fScalar))
            m_fTimeFixedTracking = fScalar;
        if (pPage->GetEntry("OffsFixedTrackingX", &fScalar))
            m_fOffsFixedTrackingX = fScalar;
        if (pPage->GetEntry("OffsFixedTrackingY", &fScalar))
            m_fOffsFixedTrackingY = fScalar;
        if (pPage->GetEntry("OffsFixedTrackingZ", &fScalar))
            m_fOffsFixedTrackingZ = fScalar;
        if (pPage->GetEntry("TimeSideShot", &fScalar))
            m_fTimeSideShot = fScalar;
        if (pPage->GetEntry("DistSideShot", &fScalar))
            m_fDistSideShot = fScalar;
        if (pPage->GetEntry("OffsSideShotX", &fScalar))
            m_fOffsSideShotX = fScalar;
        if (pPage->GetEntry("OffsSideShotY", &fScalar))
            m_fOffsSideShotY = fScalar;
        if (pPage->GetEntry("OffsSideShotHeadY", &fScalar))
            m_fOffsSideShotHeadY = fScalar;
        if (pPage->GetEntry("TimeFrontShot", &fScalar))
            m_fTimeFrontShot = fScalar;
        if (pPage->GetEntry("OffsFrontShotHeadY", &fScalar))
            m_fOffsFrontShotHeadY = fScalar;
        if (pPage->GetEntry("OffsFrontShotCameraY", &fScalar))
            m_fOffsFrontShotCameraY = fScalar;
        if (pPage->GetEntry("DistFrontShot", &fScalar))
            m_fDistFrontShot = fScalar;
        if (pPage->GetEntry("TimeOverShoulder", &fScalar))
            m_fTimeOverShoulder = fScalar;
        if (pPage->GetEntry("OffsOverShoulderHeroX", &fScalar))
            m_fOffsOverShoulderHeroX = fScalar;
        if (pPage->GetEntry("OffsOverShoulderHeroY", &fScalar))
            m_fOffsOverShoulderHeroY = fScalar;
        if (pPage->GetEntry("OffsOverShoulderHeroZ", &fScalar))
            m_fOffsOverShoulderHeroZ = fScalar;
        if (pPage->GetEntry("OffsOverShoulderEnemyY", &fScalar))
            m_fOffsOverShoulderEnemyY = fScalar;
    }
	pPage = startup_ini.FindPage("Battle Tech Misc");
	if (pPage)
	{
        int nValue;
        if (pPage->GetEntry("SecsMissionReplay", &nValue)) {
            if (nValue < 0)
                nValue = 60;
            else if (100 <= nValue)
                nValue = 60;
            g_nSecsMissionReplay = nValue;
        }

        Stuff::Scalar fScalar;

        if (pPage->GetEntry("SecsMissionReport", &fScalar)) {
            if (fScalar < 0.0f)
                fScalar = 15.0f;
            else if (30.0f <= fScalar)
                fScalar = 15.0f;
            g_fSecsMissionReport = fScalar;
        }

        if (pPage->GetEntry("AutoPowerUpLevel", &fScalar)) {
            if (fScalar < 0.0f)
                fScalar = 0.0f;
            else if (1.0 <= fScalar)
                fScalar = 1.0f;
            g_fAutoPowerUpLevel = fScalar;
        }
        if (pPage->GetEntry("NeedFlushLevel", &fScalar)) {
            if (fScalar < 0.0f)
                fScalar = 0.0f;
            else if (1.0 <= fScalar)
                fScalar = 1.0f;
            g_fNeedFlushLevel = fScalar;
        }

        if (pPage->GetEntry("TimeMsgSender", &fScalar)) {
            if (fScalar < 0.1f)
                fScalar = 0.1f;
            else if (5.0 <= fScalar)
                fScalar = 5.0f;
            g_fTimeMsgSender = fScalar;
        }

        bool bValue;
/*
        if (pPage->GetEntry("3d_target", &bValue)) {
            g_f3dtarget = bValue;
        }
*/
        if (pPage->GetEntry("TimeList_Index", &nValue)) {
            if (nValue < 0)
                nValue = 0;
            else if (20 <= nValue)
                nValue = 3;
            g_nTimeList_Index = nValue;
        }
        if (pPage->GetEntry("TimeList_Value", &nValue)) {
            if (nValue < 0)
                nValue = 7;
            else if (100 <= nValue)
                nValue = 7;
            g_nTimeList_Value = nValue;
        }
// MSL 5.06
        if (pPage->GetEntry("RuleBook", &nValue)) {
            if (nValue < 0)
                nValue = 0;
            else if (1 <= nValue)
                nValue = 1;
            g_nMechVariant = nValue;
        }
        if (pPage->GetEntry("DawnWar", &nValue)) {
            if (nValue < 0)
                nValue = 0;
            else if (1 <= nValue)
                nValue = 1;
            g_nMechLabOp = nValue;
        }
        if (pPage->GetEntry("BiggieSizeIt", &nValue)) {
            if (nValue < 0)
                nValue = 0;
            else if (1 <= nValue)
                nValue = 1;
            g_nMechPodNum = nValue;
        }
        if (pPage->GetEntry("CanYouHearTheFootSteps", &nValue)) {
            if (nValue < 0)
                nValue = 0;
            else if (1 <= nValue)
                nValue = 1;
            g_nBlackMech = nValue;
        }
    }
}

int MechWarrior4::GetFiringMode()
{
    int nChains = 0;

    for(int i = 0; i < 3; i++)
    {
        if (MechWarrior4::g_baChainFireMode[i])
            nChains++;
    }

    if (nChains == 3) // all chain
        return 2;
    if (nChains == 0) // all group
        return 1;
    return 0; // mixed
}
