#include "MW4Headers.hpp"

#include "MWApplication.hpp"
#include "MWEntityManager.hpp"
#include "MWVideoRenderer.hpp"
#include "rail_move.hpp"
#include "MWMission.hpp"
#include "MWPlayer.hpp"
#include "MWTool.hpp"
#include "MechLab.hpp"
#include "MWGUIManager.hpp"
#include "MWVideoRenderer.hpp"
#include "AnimInstance.hpp"
#include "Salvage.hpp"
#include "abldbug.h"
#include "MW4Shell.hpp"
#include "GameInfo.hpp"
#include "VehicleInterface.hpp"
#include "Bucket.hpp"
#include "Netparams.h"
#include "GameTypes.h"
#include "MWGame.hpp"
#include "MWCampaign.hpp"
#include "Team.hpp"
#include "lancemate.hpp"
#include "MWTable.hpp"
#include "MissionReview.hpp"
#if !defined(NO_MR)
#include "review_playback.hpp"
#endif // !defined(NO_MR)
#include "MWOptions.hpp"
#include "Flag.hpp"
#include "DamageDispatch_SinglePlayer.hpp"
#include "DamageDispatch_Multiplayer.hpp"
#include "ShellFunctionHeaders.hpp"
#include "mwguimanager.hpp"
#include "hudcamera.hpp"
#include "hudscore.hpp"
// for COLISEUMAMB
#include <Adept\AudioCommand.hpp>
#include <Adept\AudioRenderer.hpp>
#include "Weapon.hpp"

// MSL 5.05
#include "EffectGenerator.hpp"

#include <Adept\AudioRenderer.hpp>
#include <Adept\RendererManager.hpp>
#include <Adept\NameTable.hpp>
#include <Adept\NetStatCollector.hpp>
#include <Adept\EntityManager.hpp>
#include <Adept\ResourceEffectLibrary.hpp>
#include <Adept\Map.hpp>
#include <Adept\Dropzone.hpp>
#include <Adept\LightManager.hpp>
#include <Adept\CollisionGrid.hpp>
#include <Adept\CollisionVolume.hpp>

#include <Compost\TerrainTextureLogistic.hpp>

#include <ElementRenderer\CameraElement.hpp>
#include <ElementRenderer\ShapeElement.hpp>
#include <ElementRenderer\LODElement.hpp>

#include <MLR\MLR.hpp>
#include <MLR\MLRTexturePool.hpp>

#include <GameOS\Network.hpp>
#include <GameOS\String.hpp>

// gosscript\ fo gos_Pane
#include <gosscript\script.hpp>
#include <gosscript\surface.hpp>
#include <gosscript\pane.hpp>

#include "weapon.hpp"
#include "hudchat.hpp"
#include "server\comline.hpp"
#include "buildnum\buildnum.h" // current version and build number

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

#include <MissionLang\Resource.h>

// ngLog addition
#if !defined(NO_LOG)
#include "nglog_mw4.hpp"
#endif // !defined(NO_LOG)

#include "AI_LancemateCommands.hpp"
using namespace MW4AI::LancemateCommands; // jcem

// mdm - needed for setting clan name key for players
const char * const PLAYER_CLAN_NAME_KEY = "Clan Name";

__int64 CalculateCodeHash(int key);

#include <wincrypt.h>

//THIS IS INCLUDED FOR THE CHAR NEXT CALL IN THE FILE VERIFICATION CALL
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <io.h>

// jcem - start
//#include "windows.h"
#include "ctcls.h"
#include "ctcl.h"

#include "armor.hpp"
#include "sensor.hpp"
#include <adept\DamageObject.hpp>

#include "recscore.h"
#include "recscore.cpp"

// jcem - mission replay
#define DIRECTINPUT_VERSION 0x700
#include <dinput.h>
#include <dsetup.h>
#include <dsound.h>
#include <d3d.h>
#include <dplay.h>
#include <dplobby.h>

#pragma warning( disable: 4201 )	// nameless struct/union (again - something reenables this!)
#include <amstream.h>
#include <control.h>
#include <process.h>
#include <mmreg.h>
#include <msacm.h>
#ifndef __IDDrawExclModeVideo_FWD_DEFINED__
#error DirectX Media 6.0 SDK is required
#endif

#include "gameos\Net_header.hpp"
#include "gameos\mreplay.h"
#include "mreplay2.h"
#include "mreplay2.cpp"

#undef STRICT
#include "gameos\pch.hpp"
#include "gameos\Debugger.hpp"
#include "gameos\DXRasterizer.hpp"
#include "gameos\DirectX.hpp"
#include "gameos\3DRasterizer.hpp"
#include "gameos\Texture Manager.hpp"
#include "gameos\font3D_dbcs_storage.hpp"

extern DWORD ModalScripts;					// ModalScripts
extern int g_nCoinCount;
extern int g_nCoinCountTemp;
extern int g_nCoinPerGame;
extern bool g_bUseCam;
extern HGOSAUDIO g_hCoinSound;
extern bool (__stdcall *g_pfnCTCL_HandleKey)(DWORD wParam, bool bDown);
bool __stdcall CTCL_HandleKey(DWORD wParam, bool bDown);
void __stdcall CTCL_RandomizeGameData(int nMode);

char g_szTeslaName[128];
char g_szTeslaAddr[128];
DWORD g_dwTeslaAddr;
char g_szTeslaInviter[128];

int MAX_CAMP_STAGES = 3;

extern int g_nWhyPaused; // 0: not paused - invitation in menu-state, 1: briefing, 2: score-sheet, 3: continue, 4: invited in single-game, 5: high-score(game-over?), 6: by ESC(for testing only)...
extern SCRIPTCALLBACK(CTCL_WhyPaused);
extern SCRIPTCALLBACK(CTCL_SetDispStateCOOP);
extern void (__stdcall *g_pfnCTCL_CoinDisplay)(bool bInsideBeginScene);
extern SCRIPTCALLBACK(CTCL_CheckInviteCOOP);
extern SCRIPTCALLBACK(CTCL_DoInviteCOOP);
extern SCRIPTCALLBACK(CTCL_Inviter);

//void _stdcall DrawRect( int x1, int y1, int x2, int y2, DWORD Color );
gos_DBCS *_stdcall MW4HUD_TextDrawDBCS(  char *Message ,int size,bool dorender = true);
gos_DBCS *_stdcall MW4HUD_gos_TextStringLength (DWORD* w,DWORD* h,char *Message,int size);

namespace MechWarrior4
{
SWeaponInfo g_aWIs[256];
};

bool g_bScoreMessageHandler = false;
extern bool sh_game_started;
extern float g_fGameEndScreenTimer;
extern float g_fSecsMissionReport;
extern float g_fTimeMsgSender;
extern int GetScore4Player(int& nKills, int& nDeaths);
int g_nCTCL;
HGOSVIDEO g_hVideo;

extern void CRIO_StartFrame();
extern void CRIO_StopFrame();
// jcem - mission replay

extern char aux1_messages[14 + 2][60];
char aux1_sounds[14 + 2][60] = {
    "vo\\created\\team1.wav{handle}", // "vo\\generic\\Attack1_Ian.wav{handle}",
    "vo\\created\\team2.wav{handle}", // "vo\\generic\\Defend1_Ian.wav{handle}",
    "vo\\created\\team3.wav{handle}", // "vo\\generic\\Form1_Ian.wav{handle}",
    "vo\\created\\team4.wav{handle}",
    "vo\\created\\team5.wav{handle}",
    "vo\\created\\team6.wav{handle}",
    "vo\\created\\team7.wav{handle}",
    "vo\\created\\TAUNT1.WAV{handle}",
    "vo\\created\\TAUNT2.WAV{handle}",
    "vo\\created\\TAUNT3.WAV{handle}",
    "vo\\created\\TAUNT4.WAV{handle}",
    "vo\\created\\TAUNT5.WAV{handle}",
    "vo\\created\\TAUNT6.WAV{handle}",
    "vo\\created\\TAUNT7.WAV{handle}",
    "vo\\created\\RESP1.WAV{handle}", // "vo\\generic\\Aff_Ian.wav{handle}",
    "vo\\created\\RESP2.WAV{handle}",
};
bool g_bUnlimitedRadarRange = false;
extern bool g_bMuteMode;
#ifdef _DEBUG
#define AUTO_DENY_TIME 30.0f
#else // !_DEBUG
#define AUTO_DENY_TIME 10.0f
#endif // _DEBUG
Time g_TOC_ADT = AUTO_DENY_TIME;

STeamOrderCommand* MechWarrior4::g_pCurTOC = NULL;
enum {TEAMORDER_NONE, TEAM_MODE, FREEFORALL_MODE, TEAM_MESSAGE1, TEAM_MESSAGE2};
extern int g_nTeamOrderMode;
extern bool g_bCOOP; // COin OPeration
// jcem - end

// hyun begin
extern void __stdcall RIO_StartStop (BOOL bStart);
void COOP_InputMode(bool bRestore);
extern int g_bNoPlasma;
extern void __stdcall PLASMA_Do(int nMode);
extern void GeneralReset();
// hyun end

extern bool __stdcall gos_NetDoneStartGame();
extern bool __stdcall PrepareDefaultServerAdvertisers(void);
extern int __stdcall Mech4CreateGame(char *szGameName, char *szPlayerName, char *szPassword);


char gszBuildNumber[] = "@(#) Microsoft MechWarrior IV Build " VER_PRODUCTVERSION_STR;

extern bool(__cdecl *NoCDMessageFunction)(void);

char *MWApplication::GameFile = NULL;
char *MWApplication::NetGameName = NULL;
char *MWApplication::NetPassword = NULL;
char *MWApplication::NetPlayerName = NULL;
bool MWApplication::AutoLaunchServerGame = false;
bool MWApplication::AutoLaunchClientGame = false;
bool MWApplication::RunFromLobby = false;
bool MWApplication::DemoMode = false;
bool MWApplication::SaveGameStats = false;
bool MWApplication::Win32DedicatedServer = false;

bool MWApplication::SecureNetGame = false;
bool MWApplication::DplayNetGame = true;

#ifdef LAB_ONLY
	bool MWApplication::ReKeyResources = false;
#endif

MWApplication::Bandwidth_Type MWApplication::MyConnectionSpeed = MWApplication::c_10_Mbps;
MWApplication::Connection_Type MWApplication::MyConnectionType = MWApplication::LAN;


int MWApplication::DefaultPacketSize = 512;
int MWApplication::NetworkDebugLevel = 1;
int MWApplication::ForceConnectionSpeed = -1;

#ifdef LAB_ONLY
	int MWApplication::MoveItAndShakeIt = 0;
#else
	int MWApplication::MoveItAndShakeIt = 1;
#endif

extern DWORD gCurrentHeapStackLevel;

extern void __stdcall GetGenericErrorInfo(FixedLengthString& buffer);

namespace MechWarrior4
{
	extern CCommandLineServer *g_ComServer;
}

void ABL_Debug_func (char *s)
{
	if (g_ComServer)
		g_ComServer->PushLine (s);
	else
		SPEW (("afarrier",s));
}

const char
	*Application_Name="MechWarrior4 v0.0 (" __TIMESTAMP__ ")";



#define SetMessageRule(message_id, server_allowed, client_allowed, waitingForGameAllowed, loadingGame_allowed, preRender_allowed, runningGame_allowed, stoppingGame_allowed, recycleGame_allowed, server_res, client_res) \
	MessageRules[message_id-Adept::Network::FirstDirectApplicationMessageID][ServerAllowedRule] = server_allowed;\
	MessageRules[message_id-Adept::Network::FirstDirectApplicationMessageID][ClientAllowedRule] = client_allowed;\
	MessageRules[message_id-Adept::Network::FirstDirectApplicationMessageID][WaitingForGameAllowedRule] = waitingForGameAllowed;\
	MessageRules[message_id-Adept::Network::FirstDirectApplicationMessageID][LoadingGameAllowedRule] = loadingGame_allowed;\
	MessageRules[message_id-Adept::Network::FirstDirectApplicationMessageID][PreRenderAllowedRule] = preRender_allowed;\
	MessageRules[message_id-Adept::Network::FirstDirectApplicationMessageID][RunningGameAllowedRule] = runningGame_allowed;\
	MessageRules[message_id-Adept::Network::FirstDirectApplicationMessageID][StoppingGameAllowedRule] = stoppingGame_allowed;\
	MessageRules[message_id-Adept::Network::FirstDirectApplicationMessageID][RecycleGameAllowedRule] = recycleGame_allowed;\
	MessageResolution[message_id-Adept::Network::FirstDirectApplicationMessageID][ServerResolution] = server_res;\
	MessageResolution[message_id-Adept::Network::FirstDirectApplicationMessageID][ClientResolution] = client_res;


int MWApplication::MessageRules[MWApplication::LastMessageID-Adept::Network::FirstDirectApplicationMessageID][MWApplication::AllowedRuleCount];
int MWApplication::MessageResolution[MWApplication::LastMessageID-Adept::Network::FirstDirectApplicationMessageID][2];


static bool __stdcall CheckModem() {return MWApplication::MyConnectionType==MWApplication::Modem;}
static void __stdcall EnableModem() {MWApplication::MyConnectionType = MWApplication::Modem;}

static bool __stdcall CheckISDN() {return MWApplication::MyConnectionType==MWApplication::ISDN;}
static void __stdcall EnableISDN() {MWApplication::MyConnectionType = MWApplication::ISDN;}

static bool __stdcall CheckxDSL() {return MWApplication::MyConnectionType==MWApplication::xDSL;}
static void __stdcall EnablexDSL() {MWApplication::MyConnectionType = MWApplication::xDSL;}

static bool __stdcall CheckCable() {return MWApplication::MyConnectionType==MWApplication::Cable;}
static void __stdcall EnableCable() {MWApplication::MyConnectionType = MWApplication::Cable;}

static bool __stdcall CheckLAN() {return MWApplication::MyConnectionType==MWApplication::LAN;}
static void __stdcall EnableLAN() {MWApplication::MyConnectionType = MWApplication::LAN;}


static bool __stdcall Check14() {return MWApplication::MyConnectionSpeed==MWApplication::c_14_4kbps;}
static void __stdcall Enable14() {MWApplication::MyConnectionSpeed = MWApplication::c_14_4kbps;}

static bool __stdcall Check28() {return MWApplication::MyConnectionSpeed==MWApplication::c_28_8kbps;}
static void __stdcall Enable28() {MWApplication::MyConnectionSpeed = MWApplication::c_28_8kbps;}

static bool __stdcall Check56() {return MWApplication::MyConnectionSpeed==MWApplication::c_56_6kbps;}
static void __stdcall Enable56() {MWApplication::MyConnectionSpeed = MWApplication::c_56_6kbps;}

static bool __stdcall Check64() {return MWApplication::MyConnectionSpeed==MWApplication::c_64_kbps;}
static void __stdcall Enable64() {MWApplication::MyConnectionSpeed = MWApplication::c_64_kbps;}

static bool __stdcall Check128() {return MWApplication::MyConnectionSpeed==MWApplication::c_128_kbps;}
static void __stdcall Enable128() {MWApplication::MyConnectionSpeed = MWApplication::c_128_kbps;}

static bool __stdcall Check384() {return MWApplication::MyConnectionSpeed==MWApplication::c_384_kbps;}
static void __stdcall Enable384() {MWApplication::MyConnectionSpeed = MWApplication::c_384_kbps;}

static bool __stdcall Check768() {return MWApplication::MyConnectionSpeed==MWApplication::c_768_kbps;}
static void __stdcall Enable768() {MWApplication::MyConnectionSpeed = MWApplication::c_768_kbps;}

static bool __stdcall Check1500() {return MWApplication::MyConnectionSpeed==MWApplication::c_1500_kbps;}
static void __stdcall Enable1500() {MWApplication::MyConnectionSpeed = MWApplication::c_1500_kbps;}

static bool __stdcall Check10000() {return MWApplication::MyConnectionSpeed==MWApplication::c_10_Mbps;}
static void __stdcall Enable10000() {MWApplication::MyConnectionSpeed = MWApplication::c_10_Mbps;}

static bool __stdcall Check100000() {return MWApplication::MyConnectionSpeed==MWApplication::c_100_Mbps;}
static void __stdcall Enable100000() {MWApplication::MyConnectionSpeed = MWApplication::c_100_Mbps;}

static bool __stdcall CheckNetworkDebugLevel0() {return MWApplication::NetworkDebugLevel==0;}
static void __stdcall EnableNetworkDebugLevel0()
{
	MWApplication::NetworkDebugLevel=0;
	if (Application::GetInstance() != NULL && EntityManager::GetInstance() != NULL)
	{
		if (Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState)
		{
			MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
			manager->SetDirtyFlag();
		}
	}
}

static bool __stdcall CheckNetworkDebugLevel1() {return MWApplication::NetworkDebugLevel==1;}
static void __stdcall EnableNetworkDebugLevel1()
{
	MWApplication::NetworkDebugLevel=1;
	if (Application::GetInstance() != NULL && EntityManager::GetInstance() != NULL)
	{
		if (Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState)
		{
			MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
			manager->SetDirtyFlag();
		}
	}
}

static bool __stdcall CheckNetworkDebugLevel2() {return MWApplication::NetworkDebugLevel==2;}
static void __stdcall EnableNetworkDebugLevel2()
{
	MWApplication::NetworkDebugLevel=2;
	if (Application::GetInstance() != NULL && EntityManager::GetInstance() != NULL)
	{
		if (Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState)
		{
			MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
			manager->SetDirtyFlag();
		}
	}
}


static bool __stdcall CheckForceUpdateLevelNone() {return MWApplication::ForceConnectionSpeed==-1;}
static void __stdcall EnableForceUpdateLevelNone()
{
	MWApplication::ForceConnectionSpeed=-1;
	if (Application::GetInstance() != NULL && EntityManager::GetInstance() != NULL)
	{
		if (Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState)
		{
			MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
			manager->SetDirtyFlag();
		}
	}
}


static bool __stdcall CheckForceUpdateLevelLow() {return MWApplication::ForceConnectionSpeed==0;}
static void __stdcall EnableForceUpdateLevelLow()
{
	MWApplication::ForceConnectionSpeed=0;
	if (Application::GetInstance() != NULL && EntityManager::GetInstance() != NULL)
	{
		if (Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState)
		{
			MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
			manager->SetDirtyFlag();
		}
	}
}



static bool __stdcall CheckForceUpdateLevelMed() {return MWApplication::ForceConnectionSpeed==1;}
static void __stdcall EnableForceUpdateLevelMed()
{
	MWApplication::ForceConnectionSpeed=1;
	if (Application::GetInstance() != NULL && EntityManager::GetInstance() != NULL)
	{
		if (Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState)
		{
			MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
			manager->SetDirtyFlag();
		}
	}
}


static bool __stdcall CheckForceUpdateLevelHigh() {return MWApplication::ForceConnectionSpeed==2;}
static void __stdcall EnableForceUpdateLevelHigh()
{
	MWApplication::ForceConnectionSpeed=2;
	if (Application::GetInstance() != NULL && EntityManager::GetInstance() != NULL)
	{
		if (Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState)
		{
			MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
			manager->SetDirtyFlag();
		}
	}
}



static bool __stdcall CheckMoveItAndShakeIt() {return MWApplication::MoveItAndShakeIt==1;}
static void __stdcall EnableMoveItAndShakeIt()
{
	MWApplication::MoveItAndShakeIt=!MWApplication::MoveItAndShakeIt;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
NetMissionParameters::TeamParameters::TeamParameters()
{
	ResetParameters(0);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void NetMissionParameters::TeamParameters::ResetParameters(int index)
{
	m_maxPlayersOnTeam = 16;
	m_minimumTonnage = 0;
	m_maximumTonnage = 100;
	m_maximumTotalTonnage = 1600;
	m_currentTotalTonnage = 0;
	m_skin = (int)'0';
	m_skin += index;
	m_alignment = index;

	m_allowedMech[0] = 0xffffffff;
	m_allowedBeam[0] = 0xfffffffd;
	m_allowedMissile[0] = 0xff3bffff;
	m_allowedProjectile[0] = 0xffffdfff;
	m_allowedSubsystem[0] = 0xffffffff;
	m_allowedMech[1] = 0xffffffff;
	m_allowedBeam[1] = 0xffffffff;
	m_allowedMissile[1] = 0xffffffff;
	m_allowedProjectile[1] = 0xffffffff;
	m_allowedSubsystem[1] = 0xffffffff;
}

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

void NetMissionParameters::TeamParameters::SaveParameters(Stuff::DynamicMemoryStream *stream)
{

	stream->WriteBits(&m_maxPlayersOnTeam,7);
	stream->WriteBits(&m_minimumTonnage,8);
	stream->WriteBits(&m_maximumTonnage,8);
	stream->WriteBits(&m_maximumTotalTonnage,16);
	stream->WriteBits(&m_currentTotalTonnage,8*sizeof(Stuff::Scalar));
	stream->WriteBits(&m_skin,8);
	stream->WriteBits(&m_alignment,4);


	stream->WriteBits(&m_allowedMech[0],32);
	stream->WriteBits(&m_allowedBeam[0],32);
	stream->WriteBits(&m_allowedMissile[0],32);
	stream->WriteBits(&m_allowedProjectile[0],32);
	stream->WriteBits(&m_allowedSubsystem[0],32);
	stream->WriteBits(&m_allowedMech[1],32);
	stream->WriteBits(&m_allowedBeam[1],32);
	stream->WriteBits(&m_allowedMissile[1],32);
	stream->WriteBits(&m_allowedProjectile[1],32);
	stream->WriteBits(&m_allowedSubsystem[1],32);
}

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


void NetMissionParameters::TeamParameters::LoadParameters(Stuff::MemoryStream *stream)
{

	stream->ReadBits(&m_maxPlayersOnTeam,7);
	stream->ReadBits(&m_minimumTonnage,8);
	stream->ReadBits(&m_maximumTonnage,8);
	stream->ReadBits(&m_maximumTotalTonnage,16);
	stream->ReadBits(&m_currentTotalTonnage,8*sizeof(Stuff::Scalar));
	stream->ReadBits(&m_skin,8);
	stream->ReadBits(&m_alignment,4);

	stream->ReadBits(&m_allowedMech[0],32);
	stream->ReadBits(&m_allowedBeam[0],32);
	stream->ReadBits(&m_allowedMissile[0],32);
	stream->ReadBits(&m_allowedProjectile[0],32);
	stream->ReadBits(&m_allowedSubsystem[0],32);
	stream->ReadBits(&m_allowedMech[1],32);
	stream->ReadBits(&m_allowedBeam[1],32);
	stream->ReadBits(&m_allowedMissile[1],32);
	stream->ReadBits(&m_allowedProjectile[1],32);
	stream->ReadBits(&m_allowedSubsystem[1],32);
}

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

void NetMissionParameters::TeamParameters::SaveParameters(NotationFile *notefile)
{

	Page *page = notefile->SetPage("teamdata");
	page->SetEntry("maxPlayersOnTeam", m_maxPlayersOnTeam);
	Clamp(m_minimumTonnage, 25, 100);
	page->SetEntry("minimumTonnage", m_minimumTonnage);
	Clamp(m_maximumTonnage, m_minimumTonnage, 100);
	page->SetEntry("maximumTonnage", m_maximumTonnage);
	Clamp(m_maximumTotalTonnage, 100, 1600);
	page->SetEntry("maximumTotalTonnage", m_maximumTotalTonnage);

	MString skin_text;
	skin_text = (char*)&m_skin;
	skin_text += "\0";
	page->SetEntry("skin", skin_text);

	page->SetEntry("alignment", m_alignment);

	page->SetEntry("allowedmech1",m_allowedMech[0]);
	page->SetEntry("allowedmech2",m_allowedMech[1]);
	page->SetEntry("allowedBeam1",m_allowedBeam[0]);
	page->SetEntry("allowedBeam2",m_allowedBeam[1]);
	page->SetEntry("allowedMissile1",m_allowedMissile[0]);
	page->SetEntry("allowedMissile2",m_allowedMissile[1]);
	page->SetEntry("allowedProjectile1",m_allowedProjectile[0]);
	page->SetEntry("allowedProjectile2",m_allowedProjectile[1]);
	page->SetEntry("allowedSubsystem1",m_allowedSubsystem[0]);
	page->SetEntry("allowedSubsystem2",m_allowedSubsystem[1]);

}

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

void NetMissionParameters::TeamParameters::LoadParameters(NotationFile *notefile)
{
	Page *page = notefile->FindPage("teamdata");
	if (page)
	{
		page->GetEntry("maxPlayersOnTeam", &m_maxPlayersOnTeam);
		page->GetEntry("minimumTonnage", &m_minimumTonnage);
		Clamp(m_minimumTonnage, 25, 100);
		page->GetEntry("maximumTonnage", &m_maximumTonnage);
		Clamp(m_maximumTonnage, m_minimumTonnage, 100);
		page->GetEntry("maximumTotalTonnage", &m_maximumTotalTonnage);
		Clamp(m_maximumTotalTonnage, 100, 1600);

		const char* skin_text;
		if (page->GetEntry("skin", &skin_text))
			m_skin = (int)(*skin_text);

		page->GetEntry("alignment", &m_alignment);

		page->GetEntry("allowedmech1",&m_allowedMech[0]);
		page->GetEntry("allowedmech2",&m_allowedMech[1]);
		page->GetEntry("allowedBeam1",&m_allowedBeam[0]);
		page->GetEntry("allowedBeam2",&m_allowedBeam[1]);
		page->GetEntry("allowedMissile1",&m_allowedMissile[0]);
		page->GetEntry("allowedMissile2",&m_allowedMissile[1]);
		page->GetEntry("allowedProjectile1",&m_allowedProjectile[0]);
		page->GetEntry("allowedProjectile2",&m_allowedProjectile[1]);
		page->GetEntry("allowedSubsystem1",&m_allowedSubsystem[0]);
		page->GetEntry("allowedSubsystem2",&m_allowedSubsystem[1]);
	}
}

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

NetMissionParameters::MWNetMissionParameters::MWNetMissionParameters()
{
	m_mapID = 0;
	m_mapName[0] = '\0';
	m_scenarioName[0] = '\0';
	m_scenarioPath[0] = '\0';
	m_serverName[0] = '\0';
	m_serverIP[0] = '\0';
	m_scriptName[0] = '\0';
	m_scenarioText[0] = '\0';
	m_mapClientCRC = 0;

	ResetParameters();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void NetMissionParameters::MWNetMissionParameters::ResetParameters(void)
{
	AdeptNetMissionParameters::ResetParameters();

	m_joinInProgress = 1;
	m_joinInProgressCutOff = false;
	m_joinInProgressCutOffTime = 0;

	m_heatOn = true;
	m_killLimit = false;
	m_killLimitNumber = 0;
	m_respawnLimit = false;
	m_respawnLimitNumber = 0;
	m_forceRespawn = true;
	m_splashOn = false;
	m_weaponjamOn = false;
	m_ammobayfireOn = false;
// MSL 5.05 Advance Mode
	m_advancemodeOn = false;
// MSL 5.06 Armor Mode
	m_armormodeOn = false;
	m_splashPercentage = 100;
	m_unlimitedAmmo = false;
	m_friendlyFirePercentage = 100;
	m_allowZoom = true;
	m_allow3rdPerson = true;
	m_allowAutoAim = true;
	m_allowDeadToChat = false;
	m_invulnerableDrop = false;
	m_isNight = false;
	

	
	m_weather = false;
	m_radarMode = 0;

	m_reportStats = true;
	m_serverConnection = MWApplication::MyConnectionType;
	m_serverBandwidth = MWApplication::MyConnectionSpeed;
	


	m_onlyStockMech = false;
	m_minimumTonnage = 0;
	m_maximumTonnage = 100;

	m_allowedMech[0] = 0xffffffff;
	m_allowedBeam[0] = 0xfffffffd;
	m_allowedMissile[0] = 0xff3bffff;
	m_allowedProjectile[0] = 0xffffdfff;
	m_allowedSubsystem[0] = 0xffffffff;
	m_allowedMech[1] = 0xffffffff;
	m_allowedBeam[1] = 0xffffffff;
	m_allowedMissile[1] = 0xffffffff;
	m_allowedProjectile[1] = 0xffffffff;
	m_allowedSubsystem[1] = 0xffffffff;

	m_gameLength = 10;
	m_serverRecycle = 0;
	m_recycleDelay = 60;
	m_playMissionReview = 0;

	m_ruleType = CustomAttrition; // StockAttrition;
	m_deadMechCantSee = false;
	m_deadMechCantSeeOtherTeam = false;

	m_teamAllowed = false;
	m_teamCount = 8;
	m_allowdecaltransfer = false;
	m_useMapCycle = false;
	m_pureMapCycle = false;


	for (int i = 0; i < 8; ++i)
	{
		m_teamParams[i].ResetParameters(i);
	}

	m_maxPlayers = 0;
	m_maxBots = 0;

	char *cpu = (char*)gos_GetMachineInformation(gos_Info_GetProcessorInfo);

	if (cpu != NULL)
	{
		strcpy(m_serverCPU, cpu);
	}



	//SPEW(("jerryeds", "RESET TIME : %d", m_gameLength));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void NetMissionParameters::MWNetMissionParameters::SaveParameters(DynamicMemoryStream *stream)
{
	AdeptNetMissionParameters::SaveParameters(stream);

	stream->WriteBits(&m_joinInProgress, 1);
	stream->WriteBits(&m_joinInProgressCutOff, 1);
	stream->WriteBits(&m_joinInProgressCutOffTime, 8); // minutes 256
	stream->WriteBits(&m_heatOn, 1);
	stream->WriteBits(&m_killLimit, 1);
	stream->WriteBits(&m_killLimitNumber, 8); //256
	stream->WriteBits(&m_respawnLimit, 1);
	stream->WriteBits(&m_respawnLimitNumber, 8); //256
	stream->WriteBits(&m_forceRespawn, 1);
	stream->WriteBits(&m_splashOn, 1);
	stream->WriteBits(&m_weaponjamOn, 1);
	stream->WriteBits(&m_ammobayfireOn, 1);
// MSL 5.05 Advance Mode
	stream->WriteBits(&m_advancemodeOn, 1);
// MSL 5.06 Armor Mode
	stream->WriteBits(&m_armormodeOn, 1);
	stream->WriteBits(&m_splashPercentage, 8); //256
	stream->WriteBits(&m_unlimitedAmmo, 1);
	stream->WriteBits(&m_friendlyFirePercentage, 8); //256
	stream->WriteBits(&m_allowZoom, 1);
	stream->WriteBits(&m_allow3rdPerson, 1);
	stream->WriteBits(&m_allowAutoAim, 1);
	stream->WriteBits(&m_allowDeadToChat, 1);
	stream->WriteBits(&m_invulnerableDrop, 1);
	stream->WriteBits(&m_onlyStockMech,1);
	stream->WriteBits(&m_minimumTonnage,8);
	stream->WriteBits(&m_maximumTonnage,8);
	stream->WriteBits(&m_allowedMech[0],32);
	stream->WriteBits(&m_allowedBeam[0],32);
	stream->WriteBits(&m_allowedMissile[0],32);
	stream->WriteBits(&m_allowedProjectile[0],32);
	stream->WriteBits(&m_allowedSubsystem[0],32);
	stream->WriteBits(&m_allowedMech[1],32);
	stream->WriteBits(&m_allowedBeam[1],32);
	stream->WriteBits(&m_allowedMissile[1],32);
	stream->WriteBits(&m_allowedProjectile[1],32);
	stream->WriteBits(&m_allowedSubsystem[1],32);
	stream->WriteBits(&m_gameLength, 8); // 256 minutes
	stream->WriteBits(&m_serverRecycle, 1);
	stream->WriteBits(&m_recycleDelay, 16); //65535 seconds
	stream->WriteBits(&m_playMissionReview, 1);
	stream->WriteBits(&m_isNight, 1);
	
	stream->WriteBits(&m_weather,1);
	stream->WriteBits(&m_radarMode,2);
	stream->WriteBits(&m_reportStats,1);
	stream->WriteBits(&m_serverConnection,5);//32
	stream->WriteBits(&m_serverBandwidth,5);//32
	stream->WriteBits(&m_ruleType, 5);//32
	stream->WriteBits(&m_deadMechCantSee,1);
	stream->WriteBits(&m_deadMechCantSeeOtherTeam,1);
	stream->WriteBits(&m_teamAllowed,1);
	stream->WriteBits(&m_teamCount, 4);
	stream->WriteBits(&m_allowdecaltransfer,1);
	stream->WriteBits(&m_useMapCycle,1);
	stream->WriteBits(&m_pureMapCycle,1);


	stream->WriteBits(&m_maxPlayers, 5); // 16 players maximum
	stream->WriteBits(&m_maxBots, 5); // 16 players maximum
	stream->WriteBits(&m_mapID, 16); // 65535 maps available
	stream->WriteBits(&m_mapClientCRC, 64);


	for (int i = 0; i < 8; ++i)
	{
		m_teamParams[i].SaveParameters(stream);
	}



	stream->WriteByteAlign();

	int map_length = strlen(&m_mapName[0]);
	stream->WriteBytes(&map_length, 1);
	if (map_length > 0)
		stream->WriteBytes(&m_mapName[0], map_length);
		
	int scn_length = strlen(&m_scenarioName[0]);
	stream->WriteBytes(&scn_length, 1);
	if (scn_length > 0)
		stream->WriteBytes(&m_scenarioName[0], scn_length);
	
	int scp_length = strlen(&m_scenarioPath[0]);
	stream->WriteBytes(&scp_length, 1);
	if (scp_length > 0)
		stream->WriteBytes(&m_scenarioPath[0], scp_length);

	int srn_length = strlen(&m_serverName[0]);
	stream->WriteBytes(&srn_length, 1);
	if (srn_length > 0)
		stream->WriteBytes(&m_serverName[0], srn_length);

	int sip_length = strlen(&m_serverIP[0]);
	stream->WriteBytes(&sip_length, 1);
	if (sip_length > 0)
		stream->WriteBytes(&m_serverIP[0], sip_length);

	int cpu_length = strlen(&m_serverCPU[0]);
	stream->WriteBytes(&cpu_length, 1);
	if (cpu_length > 0)
		stream->WriteBytes(&m_serverCPU[0], cpu_length);

	int scriptname_length = strlen(&m_scriptName[0]);
	stream->WriteBytes(&scriptname_length,1);
	if (scriptname_length > 0)
		stream->WriteBytes(&m_scriptName[0],scriptname_length);	

	int scenariotext_length = strlen(&m_scenarioText[0]); //_mbstrlen(&m_scenarioText[0]);
	++scenariotext_length;
	stream->WriteBytes(&scenariotext_length,4);
	if (scenariotext_length > 0)
		stream->WriteBytes(&m_scenarioText[0],scenariotext_length);	
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void NetMissionParameters::MWNetMissionParameters::LoadParameters(MemoryStream *stream)
{
	AdeptNetMissionParameters::LoadParameters(stream);

	stream->ReadBits(&m_joinInProgress, 1);
	stream->ReadBits(&m_joinInProgressCutOff, 1);
	stream->ReadBits(&m_joinInProgressCutOffTime, 8); // minutes 256
	stream->ReadBits(&m_heatOn, 1);
	stream->ReadBits(&m_killLimit, 1);
	stream->ReadBits(&m_killLimitNumber, 8); //256
	stream->ReadBits(&m_respawnLimit, 1);
	stream->ReadBits(&m_respawnLimitNumber, 8); //256
	stream->ReadBits(&m_forceRespawn, 1);
	stream->ReadBits(&m_splashOn, 1);
	stream->ReadBits(&m_weaponjamOn, 1);
	stream->ReadBits(&m_ammobayfireOn, 1);
// MSL 5.05 Advance Mode
	stream->ReadBits(&m_advancemodeOn, 1);
// MSL 5.05 Armor Mode
	stream->ReadBits(&m_armormodeOn, 1);
	stream->ReadBits(&m_splashPercentage, 8); //256
	stream->ReadBits(&m_unlimitedAmmo, 1);
	stream->ReadBits(&m_friendlyFirePercentage, 8); //256
	stream->ReadBits(&m_allowZoom, 1);
	stream->ReadBits(&m_allow3rdPerson, 1);
	stream->ReadBits(&m_allowAutoAim, 1);
	stream->ReadBits(&m_allowDeadToChat, 1);
	stream->ReadBits(&m_invulnerableDrop, 1);
	stream->ReadBits(&m_onlyStockMech,1);
	stream->ReadBits(&m_minimumTonnage,8);
	stream->ReadBits(&m_maximumTonnage,8);
	stream->ReadBits(&m_allowedMech[0],32);
	stream->ReadBits(&m_allowedBeam[0],32);
	stream->ReadBits(&m_allowedMissile[0],32);
	stream->ReadBits(&m_allowedProjectile[0],32);
	stream->ReadBits(&m_allowedSubsystem[0],32);
	stream->ReadBits(&m_allowedMech[1],32);
	stream->ReadBits(&m_allowedBeam[1],32);
	stream->ReadBits(&m_allowedMissile[1],32);
	stream->ReadBits(&m_allowedProjectile[1],32);
	stream->ReadBits(&m_allowedSubsystem[1],32);
	stream->ReadBits(&m_gameLength, 8); // 256 minutes
	stream->ReadBits(&m_serverRecycle, 1);
	stream->ReadBits(&m_recycleDelay, 16); //65535 seconds
	stream->ReadBits(&m_playMissionReview, 1);
	stream->ReadBits(&m_isNight, 1);
	
	stream->ReadBits(&m_weather,1);
	stream->ReadBits(&m_radarMode,2);
	stream->ReadBits(&m_reportStats,1);
	stream->ReadBits(&m_serverConnection,5);//32
	stream->ReadBits(&m_serverBandwidth,5);//32
	stream->ReadBits(&m_ruleType, 5);//32
	stream->ReadBits(&m_deadMechCantSee,1);
	stream->ReadBits(&m_deadMechCantSeeOtherTeam,1);
	stream->ReadBits(&m_teamAllowed,1);
	stream->ReadBits(&m_teamCount, 4);
	stream->ReadBits(&m_allowdecaltransfer,1);
	stream->ReadBits(&m_useMapCycle,1);
	stream->ReadBits(&m_pureMapCycle,1);

	stream->ReadBits(&m_maxPlayers, 5); // 16 players max
	stream->ReadBits(&m_maxBots, 5); // 16 players max
	stream->ReadBits(&m_mapID, 16); // 65535 maps available
	stream->ReadBits(&m_mapClientCRC, 64);

	
	for (int i = 0; i < 8; ++i)
	{
		m_teamParams[i].LoadParameters(stream);
	}

	stream->ReadByteAlign();

	int map_length = 0;
	stream->ReadBytes(&map_length, 1);
	if (map_length > 0)
		stream->ReadBytes(&m_mapName[0], map_length);
	m_mapName[map_length] = '\0';
	
	int scn_length = 0;
	stream->ReadBytes(&scn_length, 1);
	if (scn_length > 0)
		stream->ReadBytes(&m_scenarioName[0], scn_length);
	m_scenarioName[scn_length] = '\0';
	
	int scp_length = 0;
	stream->ReadBytes(&scp_length, 1);
	if (scp_length > 0)
		stream->ReadBytes(&m_scenarioPath[0], scp_length);
	m_scenarioPath[scp_length] = '\0';

	int srn_length = 0;
	stream->ReadBytes(&srn_length, 1);
	if (srn_length > 0)
		stream->ReadBytes(&m_serverName[0], srn_length);
	m_serverName[srn_length] = '\0';

	int sip_length = 0;
	stream->ReadBytes(&sip_length, 1);
	if (sip_length > 0)
		stream->ReadBytes(&m_serverIP[0], sip_length);
	m_serverIP[sip_length] = '\0';

	int cpu_length = 0;
	stream->ReadBytes(&cpu_length, 1);
	if (cpu_length > 0)
		stream->ReadBytes(&m_serverCPU[0], cpu_length);
	m_serverCPU[cpu_length] = '\0';

	int scriptname_length = 0;
	stream->ReadBytes(&scriptname_length,1);
	if (scriptname_length > 0)
		stream->ReadBytes(&m_scriptName[0],scriptname_length);

	int scenariotext_length = 0;
	stream->ReadBytes(&scenariotext_length,4);
	if (scenariotext_length > 0)
		stream->ReadBytes(&m_scenarioText[0],scenariotext_length);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void NetMissionParameters::MWNetMissionParameters::SaveParameters(NotationFile *notefile)
{
	AdeptNetMissionParameters::SaveParameters(notefile);

	Page *page = notefile->SetPage("server");
	page->SetEntry("joinInProgress", m_joinInProgress);
	page->SetEntry("joinInProgressCutOff", m_joinInProgressCutOff);
	page->SetEntry("joinInProgressCutOffTime", m_joinInProgressCutOffTime);
	page->SetEntry("heatOn", m_heatOn);
	page->SetEntry("killLimit", m_killLimit);
	page->SetEntry("killLimitNumber", m_killLimitNumber);
	page->SetEntry("respawnLimit", m_respawnLimit);
	page->SetEntry("respawnLimitNumber", m_respawnLimitNumber);
	page->SetEntry("forceRespawn", m_forceRespawn);
	page->SetEntry("splashOn", m_splashOn);
	page->SetEntry("weaponjamOn", m_weaponjamOn);
	page->SetEntry("ammobayfireOn", m_ammobayfireOn);
// MSL 5.05 Advance Mode
	page->SetEntry("advancemodeOn", m_advancemodeOn);
// MSL 5.06 Armor Mode
	page->SetEntry("armormodeOn", m_armormodeOn);
	page->SetEntry("splashPercentage", m_splashPercentage);
	page->SetEntry("unlimitedAmmo", m_unlimitedAmmo);
	page->SetEntry("friendlyFirePercentage", m_friendlyFirePercentage);
	page->SetEntry("allowZoom", m_allowZoom);
	page->SetEntry("allow3rdPerson", m_allow3rdPerson);
	page->SetEntry("allowDeadToChat", m_allowDeadToChat);
	page->SetEntry("isNight", m_isNight);
	
	page->SetEntry("weather", m_weather);
	page->SetEntry("radarMode", m_radarMode);
	page->SetEntry("reportStats", m_reportStats);
	page->SetEntry("onlyStockMech", m_onlyStockMech);
	page->SetEntry("minimumTonnage", m_minimumTonnage);
	Max_Clamp(m_maximumTonnage, 100);
	page->SetEntry("maximumTonnage", m_maximumTonnage);
	page->SetEntry("gameLength", m_gameLength);
	page->SetEntry("serverRecycle", m_serverRecycle);
	page->SetEntry("recycleDelay", m_recycleDelay);
	page->SetEntry("playMissionReview", m_playMissionReview);
	page->SetEntry("deadMechCantSee", m_deadMechCantSee);
	page->SetEntry("deadMechCantSeeOtherTeam", m_deadMechCantSeeOtherTeam);
	page->SetEntry("ruletype", m_ruleType);
	page->SetEntry("teamAllowed",m_teamAllowed);
	page->SetEntry("teamCount",m_teamCount);
	page->SetEntry("allowdecaltransfer",m_allowdecaltransfer);
	page->SetEntry("useMapCycle",m_useMapCycle);
	
	page->SetEntry("maxPlayers", m_maxPlayers);
	Max_Clamp(m_maxBots, m_maxPlayers);
	page->SetEntry("maxBots", m_maxBots);

	page->SetEntry("mapName", m_mapName);
	page->SetEntry("serverName", m_serverName);
	page->SetEntry("serverIP", m_serverIP);
	page->SetEntry("scenarioName", m_scenarioName);
	page->SetEntry("scenarioPath", m_scenarioPath);
	page->SetEntry("scriptName",m_scriptName);

	page->SetEntry("allowedmech1",m_allowedMech[0]);
	page->SetEntry("allowedmech2",m_allowedMech[1]);
	page->SetEntry("allowedBeam1",m_allowedBeam[0]);
	page->SetEntry("allowedBeam2",m_allowedBeam[1]);
	page->SetEntry("allowedMissile1",m_allowedMissile[0]);
	page->SetEntry("allowedMissile2",m_allowedMissile[1]);
	page->SetEntry("allowedProjectile1",m_allowedProjectile[0]);
	page->SetEntry("allowedProjectile2",m_allowedProjectile[1]);
	page->SetEntry("allowedSubsystem1",m_allowedSubsystem[0]);
	page->SetEntry("allowedSubsystem2",m_allowedSubsystem[1]);
	



	for (int i = 0; i < 8; ++i)
	{
		NotationFile team_file;
		m_teamParams[i].SaveParameters(&team_file);
		char team_page[50];
		sprintf(&team_page[0], "team_%d", i);
		page->SetEntry(team_page, &team_file);
	}

}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void NetMissionParameters::MWNetMissionParameters::SaveServerParameters(NotationFile *notefile)
{
	AdeptNetMissionParameters::SaveParameters(notefile);

	Page *page = notefile->SetPage("server");
	page->SetEntry("joinInProgress", m_joinInProgress);
	page->SetEntry("joinInProgressCutOff", m_joinInProgressCutOff);
	page->SetEntry("joinInProgressCutOffTime", m_joinInProgressCutOffTime);
	page->SetEntry("heatOn", m_heatOn);
	page->SetEntry("forceRespawn", m_forceRespawn);
	page->SetEntry("splashOn", m_splashOn);
	page->SetEntry("weaponjamOn", m_weaponjamOn);
	page->SetEntry("ammobayfireOn", m_ammobayfireOn);
// MSL 5.05 Advance Mode
	page->SetEntry("advancemodeOn", m_advancemodeOn);
// MSL 5.06 Armor Mode
	page->SetEntry("armormodeOn", m_armormodeOn);
	page->SetEntry("splashPercentage", m_splashPercentage);
	page->SetEntry("unlimitedAmmo", m_unlimitedAmmo);
	page->SetEntry("friendlyFirePercentage", m_friendlyFirePercentage);
	page->SetEntry("allowZoom", m_allowZoom);
	page->SetEntry("allow3rdPerson", m_allow3rdPerson);
	page->SetEntry("allowDeadToChat", m_allowDeadToChat);
	page->SetEntry("reportStats", m_reportStats);
	page->SetEntry("serverRecycle", m_serverRecycle);
	page->SetEntry("recycleDelay", m_recycleDelay);
	page->SetEntry("playMissionReview", m_playMissionReview);
	page->SetEntry("deadMechCantSee", m_deadMechCantSee);
	page->SetEntry("deadMechCantSeeOtherTeam", m_deadMechCantSeeOtherTeam);
	page->SetEntry("ruletype", m_ruleType);
	page->SetEntry("allowdecaltransfer",m_allowdecaltransfer);
	page->SetEntry("useMapCycle",m_useMapCycle);
	
	page->SetEntry("maxPlayers", m_maxPlayers);
	Max_Clamp(m_maxBots, m_maxPlayers);
	page->SetEntry("maxBots", m_maxBots);

	page->SetEntry("allowedmech1",m_allowedMech[0]);
	page->SetEntry("allowedmech2",m_allowedMech[1]);
	page->SetEntry("allowedBeam1",m_allowedBeam[0]);
	page->SetEntry("allowedBeam2",m_allowedBeam[1]);
	page->SetEntry("allowedMissile1",m_allowedMissile[0]);
	page->SetEntry("allowedMissile2",m_allowedMissile[1]);
	page->SetEntry("allowedProjectile1",m_allowedProjectile[0]);
	page->SetEntry("allowedProjectile2",m_allowedProjectile[1]);
	page->SetEntry("allowedSubsystem1",m_allowedSubsystem[0]);
	page->SetEntry("allowedSubsystem2",m_allowedSubsystem[1]);
	

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void NetMissionParameters::MWNetMissionParameters::LoadParameters(NotationFile *notefile)
{
	AdeptNetMissionParameters::LoadParameters(notefile);

	Page *page = notefile->FindPage("server");
	if (page)
	{
		page->GetEntry("joinInProgress", &m_joinInProgress);
		page->GetEntry("joinInProgressCutOff", &m_joinInProgressCutOff);
		page->GetEntry("joinInProgressCutOffTime", &m_joinInProgressCutOffTime);
		page->GetEntry("heatOn", &m_heatOn);
		page->GetEntry("killLimit", &m_killLimit);
		page->GetEntry("killLimitNumber", &m_killLimitNumber);
		page->GetEntry("respawnLimit", &m_respawnLimit);
		page->GetEntry("respawnLimitNumber", &m_respawnLimitNumber);
		page->GetEntry("forceRespawn", &m_forceRespawn);
		page->GetEntry("splashOn", &m_splashOn);
		page->GetEntry("weaponjamOn", &m_weaponjamOn);
		page->GetEntry("ammobayfireOn", &m_ammobayfireOn);
// MSL 5.05 Advance Mode
		page->GetEntry("advancemodeOn", &m_advancemodeOn);
// MSL 5.05 Armor Mode
		page->GetEntry("armormodeOn", &m_armormodeOn);
		page->GetEntry("splashPercentage", &m_splashPercentage);
		page->GetEntry("unlimitedAmmo", &m_unlimitedAmmo);
		page->GetEntry("friendlyFirePercentage", &m_friendlyFirePercentage);
		page->GetEntry("allowZoom", &m_allowZoom);
		page->GetEntry("allow3rdPerson", &m_allow3rdPerson);
		page->GetEntry("allowAutoAim", &m_allowAutoAim);
		page->GetEntry("allowDeadToChat", &m_allowDeadToChat);
		page->GetEntry("invulnerableDrop", &m_invulnerableDrop);
		page->GetEntry("isNight", &m_isNight);
		
		page->GetEntry("weather", &m_weather);
		page->GetEntry("radarMode", &m_radarMode);
		page->GetEntry("reportStats", &m_reportStats);
		page->GetEntry("onlyStockMech", &m_onlyStockMech);
		page->GetEntry("minimumTonnage", &m_minimumTonnage);
		page->GetEntry("maximumTonnage", &m_maximumTonnage);
		Max_Clamp(m_maximumTonnage, 100);
		page->GetEntry("gameLength", &m_gameLength);
		page->GetEntry("serverRecycle", &m_serverRecycle);

		if (!m_runDedicated)
			m_serverRecycle = 0;

		page->GetEntry("recycleDelay", &m_recycleDelay);
		page->GetEntry("playMissionReview", &m_playMissionReview);
		page->GetEntry("deadMechCantSee", &m_deadMechCantSee);
		page->GetEntry("deadMechCantSeeOtherTeam",& m_deadMechCantSeeOtherTeam);
		page->GetEntry("ruletype", &m_ruleType);
		page->GetEntry("teamAllowed",&m_teamAllowed);
		page->GetEntry("teamCount",&m_teamCount);
		Clamp(m_teamCount, 2, 8);
		page->GetEntry("allowdecaltransfer",&m_allowdecaltransfer);
		page->GetEntry("useMapCycle",&m_useMapCycle);

		page->GetEntry("maxPlayers", &m_maxPlayers);
		page->GetEntry("maxBots", &m_maxBots);
		Max_Clamp(m_maxBots, m_maxPlayers);

		page->GetEntry("allowedmech1",&m_allowedMech[0]);
		page->GetEntry("allowedmech2",&m_allowedMech[1]);
		page->GetEntry("allowedBeam1",&m_allowedBeam[0]);
		page->GetEntry("allowedBeam2",&m_allowedBeam[1]);
		page->GetEntry("allowedMissile1",&m_allowedMissile[0]);
		page->GetEntry("allowedMissile2",&m_allowedMissile[1]);
		page->GetEntry("allowedProjectile1",&m_allowedProjectile[0]);
		page->GetEntry("allowedProjectile2",&m_allowedProjectile[1]);
		page->GetEntry("allowedSubsystem1",&m_allowedSubsystem[0]);
		page->GetEntry("allowedSubsystem2",&m_allowedSubsystem[1]);

	
		

		for (int i = 0; i < 8; ++i)
		{
			NotationFile team_file;
			char team_page[50];
			sprintf(&team_page[0], "team_%d", i);
			if (page->GetEntry(team_page, &team_file))
			{
				m_teamParams[i].LoadParameters(&team_file);
			}
		}
	}




}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void NetMissionParameters::MWNetMissionParameters::LoadOverideParameters(NotationFile *notefile)
{
	AdeptNetMissionParameters::LoadOverideParameters(notefile);

	Page *page = notefile->FindPage("server");
	if (page)
	{
		
		
		page->GetEntry("killLimit", &m_killLimit);
		page->GetEntry("killLimitNumber", &m_killLimitNumber);
		page->GetEntry("respawnLimit", &m_respawnLimit);
		page->GetEntry("respawnLimitNumber", &m_respawnLimitNumber);
		page->GetEntry("isNight", &m_isNight);	
		page->GetEntry("weather", &m_weather);
		page->GetEntry("radarMode", &m_radarMode);
		page->GetEntry("onlyStockMech", &m_onlyStockMech);
		page->GetEntry("minimumTonnage", &m_minimumTonnage);
		page->GetEntry("maximumTonnage", &m_maximumTonnage);
		Max_Clamp(m_maximumTonnage, 100);
		page->GetEntry("gameLength", &m_gameLength);
		
		page->GetEntry("teamAllowed",&m_teamAllowed);
		page->GetEntry("teamCount",&m_teamCount);
		Clamp(m_teamCount, 2, 8);

		const char* script_name = 0;
		page->GetEntry("scriptName",&script_name);
		if (script_name != 0)
		{
			Str_Copy(m_scriptName,script_name,ELEMENTS(m_scriptName));
		}
		else
		{
			m_scriptName[0] = '\0';
		}


		const char* script_text = 0;
		if (page->GetEntry("scenariotext",&script_text))
		{

			if (gos_DoesFileExist(script_text))
			{
				FileStream stream(script_text);
				int text_length = 0;
				
				char buffer[1024];

				while (stream.ReadLine(&buffer[0],1024) && text_length < 1024)
				{
					int sub_length = strlen(buffer); //_mbstrlen(buffer);
					Max_Clamp(sub_length, (1024-text_length));
					buffer[sub_length] = '\0';

					_mbscpy( (unsigned char *)&m_scenarioText[text_length], (unsigned char *)&buffer[0]);
					text_length += sub_length;
					m_scenarioText[text_length] = '\n';

					text_length += 1;
				}

				m_scenarioText[text_length-1] = '\0';
			}
		}
		else
		{
			m_scenarioText[0] = '\0';
		}

		Verify(strlen(m_scenarioText) < 1024); //_mbstrlen(m_scenarioText) < 1024);


		for (int i = 0; i < 8; ++i)
		{
			NotationFile team_file;
			char team_page[50];
			sprintf(&team_page[0], "team_%d", i);
			if (page->GetEntry(team_page, &team_file))
			{
				m_teamParams[i].LoadParameters(&team_file);
			}
		}
	}
    CTCL_DefaultHostSetup(3); // jcem
}

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

ServedConnectionData::ServedConnectionData()
{
	clientConnected = false;
	clientVehicleAccepted = false;
	clientReady = false;
	vehicleCreateMessage = NULL;
	clientCustomResource = NULL;
	customResourceCRCFail = false;
	clientLoaded = false;
	clientReadyForPrerender = false;
	clientPlayer = NULL;
	clientLaunched = false;
	clientSentScoreFormat = false;
	clientConnectionRate = MWApplication::c_56_6kbps;
	clientConnectionType = MWApplication::Modem;
	bandwidthThrottle = 0;
	timeSinceLastThrottleTest = -1.0f;

	clientAllowTransfer = false;
	clientSquelched = false;
	clientStreamingReview = false;
	nextReviewPacket = 0;
	clientQuedForLaunch = false;
	clientQuedForKick = false;

	waitingForClientShutdownConfirmation = false;

	pilotDecals = -1;
	teamDecals = -1;
	
	pilotTeam = MWApplication::No_Team;
	pilotSkins = DefaultSkinPrefix;

	vehiclePosition = Point3D::Identity;
	vehicleRotation = YawPitchRange::Identity;

	chatTimeLog.SetSize(20, 0.0f);
	lastChat = 0.0f;
	chatTimeLog.Add(60.0f);

	mechChasisID = EmptyMechID;
	pilotName = NULL;
	clanName = NULL;
	effectivePing = 0.0f;
	averagePing.SetSize(10);
	packetLoss = 0;

	clientISP = 0;
	clientKey = GUID_NULL;

	// ngLog additions
#if !defined(NO_LOG)
	memset(&ngLogID, 0, sizeof(GUID));
	for(int i=FirstWeaponID; i<ServedConnectionData::NumWeaponsTracked; i++) {
		dmg_given[i] = 0;
		dmg_rcvd[i] = 0;
		wep_atts[i] = 0;
		wep_hits[i] = 0;
	}
	for(i=0; i<Maximum_Players+Maximum_Lancemates; i++) {
		pdmg_given[i] = 0;
		pdmg_rcvd[i] = 0;
		comp_inf[i] = 0;
		comp_rcv[i] = 0;
	}
#endif // !defined(NO_LOG)

    tonnage = 0.0;
}

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

ServedConnectionData::~ServedConnectionData()
{
	Disconnect();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ServedConnectionData::Recycle()
{

	clientVehicleAccepted = false;
	clientReady = false;
	clientLoaded = false;
	clientReadyForPrerender = false;
	clientLaunched = false;
	clientSentScoreFormat = false;
	clientQuedForLaunch = false;
	clientQuedForKick = false;

	clientPlayer = NULL;
	bandwidthThrottle = 0;
	timeSinceLastThrottleTest = -1.0f;

	MWApplication::GetInstance()->RemoveDecal(pilotDecals);
	MWApplication::GetInstance()->RemoveDecal(teamDecals);
	pilotDecals = -1;
	teamDecals = -1;
	pilotTeam = MWApplication::No_Team;
	pilotSkins = DefaultSkinPrefix;
	vehiclePosition = Point3D::Identity;
	vehicleRotation = YawPitchRange::Identity;

	mechChasisID = EmptyMechID;
	effectivePing = 0.0f;
	averagePing.SetSize(10);
	packetLoss = 0;

	chatTimeLog.SetSize(20, 0.0f);
	for (int i=0; i < 20; ++i)
	{
		chatTimeLog.Add(0.0f);
	}

	lastChat = 0.0f;

	// ngLog addition	
#if !defined(NO_LOG)
	for(i=FirstWeaponID; i<ServedConnectionData::NumWeaponsTracked; i++) {
		dmg_given[i] = 0;
		dmg_rcvd[i] = 0;
		wep_atts[i] = 0;
		wep_hits[i] = 0;
	}
	for(i=0; i<Maximum_Players+Maximum_Lancemates; i++) {
		pdmg_given[i] = 0;
		pdmg_rcvd[i] = 0;
		comp_inf[i] = 0;
		comp_rcv[i] = 0;
	}
#endif // !defined(NO_LOG)

    tonnage = 0.0;
}

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

void ServedConnectionData::Disconnect()
{
	Recycle();

	if (vehicleCreateMessage != NULL)
	{
		vehicleCreateMessage->Rewind();
		BYTE *data = (BYTE*)vehicleCreateMessage->GetPointer();
		delete[] data;
		
		Check_Object(vehicleCreateMessage);
		delete vehicleCreateMessage;

		vehicleCreateMessage = NULL;
	}
	

	if (clientCustomResource != NULL)
	{
		delete clientCustomResource;
		clientCustomResource = NULL;
	}

	customResourceCRCFail = false;


	clientConnected = false;
	pilotName = NULL;
	if (clanName != NULL)
		delete[] clanName;
	clanName = NULL;
#if !defined(NO_LOG)
	memset(&ngLogID, 0, sizeof(GUID));		// ngLog addition
#endif // !defined(NO_LOG)
	clientSquelched = false;
	clientStreamingReview = false;
	nextReviewPacket = 0;
	clientISP = 0;
	clientKey = GUID_NULL;

	waitingForClientShutdownConfirmation = false;

    tonnage = 0.0;
}



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

LancemateConnectionData::LancemateConnectionData()
{
	lancemateCreateMessage = NULL;
	lancemateCustomResource = NULL;
	customResourceCRCFail = false;

	lancemateName[0] = '\0';
	lancemateClan[0] = '\0';
	pilotTeam = MWApplication::No_Team;
	lancemateConnected = false;
	lancemateVehicleAccepted = false;
	buildName = false;
	mechChasisID = EmptyMechID;

	lancemateMech = NULL;

	scriptName[0] = '\0';
	aiModel = ResourceID::Null;
	pilotSkill = -1;
	gunnerySkill = -1;
	eliteSkill = -1;
	minHeatSkill = -1;
	maxheatSkill = -1;
	sensorSkill = -1;
	blindFightSkill = -1;
	longRangeGunSkill = -1;
	shortRangeGunSkill = -1;


#if !defined(NO_LOG)
	for(int i=FirstWeaponID; i<ServedConnectionData::NumWeaponsTracked; i++) {
		dmg_given[i] = 0;
		dmg_rcvd[i] = 0;
		wep_atts[i] = 0;
		wep_hits[i] = 0;
	}
	for(i=0; i<Maximum_Players+Maximum_Lancemates; i++) {
		pdmg_given[i] = 0;
		pdmg_rcvd[i] = 0;
		comp_inf[i] = 0;
		comp_rcv[i] = 0;
	}
#endif // !defined(NO_LOG)

    tonnage = 0.0;
}

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

LancemateConnectionData::~LancemateConnectionData()
{
	Disconnect();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancemateConnectionData::Recycle()
{
	if (lancemateCreateMessage != NULL)
	{
		lancemateCreateMessage->Rewind();
		BYTE* data = (BYTE*)lancemateCreateMessage->GetPointer();
		delete[] data;

		Check_Object(lancemateCreateMessage);
		delete lancemateCreateMessage;

		lancemateCreateMessage = NULL;
	}

	if (lancemateCustomResource != NULL)
	{
		delete lancemateCustomResource;
		lancemateCustomResource = NULL;
	}

	customResourceCRCFail = false;

	lancemateName[0] = '\0';
	lancemateClan[0] = '\0';
	pilotTeam = MWApplication::No_Team;
	lancemateConnected = false;
	lancemateVehicleAccepted = false;
	buildName = false;
	mechChasisID = EmptyMechID;
	lancemateMech = NULL;

	scriptName[0] = '\0';
	aiModel = ResourceID::Null;
	pilotSkill = -1;
	gunnerySkill = -1;
	eliteSkill = -1;
	minHeatSkill = -1;
	maxheatSkill = -1;
	sensorSkill = -1;
	blindFightSkill = -1;
	longRangeGunSkill = -1;
	shortRangeGunSkill = -1;
	dropZone = NameTable::NullObjectID;

    tonnage = 0.0;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancemateConnectionData::Disconnect()
{
	Recycle();
}

//#############################################################################
//##########################    MWApplication    ##############################
//#############################################################################


MWApplication::ClassData*
	MWApplication::DefaultData = NULL;

const Receiver::MessageEntry
	MWApplication::MessageEntries[]=
{
	MESSAGE_ENTRY(MWApplication, PauseGame)
};


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::InitializeClass()
{
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			MWApplicationClassID,
 			"MWApplication",
			Application::DefaultData,
			ELEMENTS(MessageEntries),
			MessageEntries
		);
	Register_Object(DefaultData);

	Verify(Network::LastDirectApplicationMessageID > MWApplication::LastMessageID);


	AddDebuggerMenuItem("Libraries\\Network\\Connection Type",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\----------------------",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\Modem",CheckModem,EnableModem,0);
	AddDebuggerMenuItem("Libraries\\Network\\ISDN",CheckISDN,EnableISDN,0);
	AddDebuggerMenuItem("Libraries\\Network\\xDSL",CheckxDSL,EnablexDSL,0);
	AddDebuggerMenuItem("Libraries\\Network\\Cable",CheckCable,EnableCable,0);
	AddDebuggerMenuItem("Libraries\\Network\\LAN",CheckLAN,EnableLAN,0);
	
	AddDebuggerMenuItem("Libraries\\Network\\ ",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\Connection Speed",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\----------------------",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\14.4 kbps",Check14,Enable14,0);
	AddDebuggerMenuItem("Libraries\\Network\\28.8 kbps",Check28,Enable28,0);
	AddDebuggerMenuItem("Libraries\\Network\\56.6 kbps",Check56,Enable56,0);
	AddDebuggerMenuItem("Libraries\\Network\\64 kbps",  Check64,Enable64,0);
	AddDebuggerMenuItem("Libraries\\Network\\128 kbps", Check128,Enable128,0);
	AddDebuggerMenuItem("Libraries\\Network\\384 kbps", Check384,Enable384,0);
	AddDebuggerMenuItem("Libraries\\Network\\769 kbps", Check768,Enable768,0);
	AddDebuggerMenuItem("Libraries\\Network\\1.5 mbps", Check1500,Enable1500,0);
	AddDebuggerMenuItem("Libraries\\Network\\10 mbps",  Check10000,Enable10000,0);
	AddDebuggerMenuItem("Libraries\\Network\\100 mbps", Check100000,Enable100000,0);
	
	AddDebuggerMenuItem("Libraries\\Network\\ ",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\Net Debug Level",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\----------------------",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\No Debug", CheckNetworkDebugLevel0,EnableNetworkDebugLevel0,0);
	AddDebuggerMenuItem("Libraries\\Network\\Packet Size Checks", CheckNetworkDebugLevel1,EnableNetworkDebugLevel1,0);
	AddDebuggerMenuItem("Libraries\\Network\\Full Packet Checking", CheckNetworkDebugLevel2,EnableNetworkDebugLevel2,0);

	AddDebuggerMenuItem("Libraries\\Network\\ ",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\Force Bandwidth Level",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\----------------------",0,0,0);
	AddDebuggerMenuItem("Libraries\\Network\\No Force / Autodetect", CheckForceUpdateLevelNone,EnableForceUpdateLevelNone,0);
	AddDebuggerMenuItem("Libraries\\Network\\Low", CheckForceUpdateLevelLow,EnableForceUpdateLevelLow,0);
	AddDebuggerMenuItem("Libraries\\Network\\Med", CheckForceUpdateLevelMed,EnableForceUpdateLevelMed,0);
	AddDebuggerMenuItem("Libraries\\Network\\High", CheckForceUpdateLevelHigh,EnableForceUpdateLevelHigh,0);
	

	AddDebuggerMenuItem("Libraries\\hAxorz\\Move it and shake it", CheckMoveItAndShakeIt,EnableMoveItAndShakeIt,0);
	


	for (int i = 0; i < LastMessageID-Adept::Network::FirstDirectApplicationMessageID; ++i)
	{
		MessageRules[i][ServerAllowedRule] = -1;
		MessageRules[i][ClientAllowedRule] = -1;
		MessageRules[i][WaitingForGameAllowedRule] = -1;
		MessageRules[i][LoadingGameAllowedRule] = -1;
		MessageRules[i][PreRenderAllowedRule] = -1;
		MessageRules[i][RunningGameAllowedRule] = -1;
		MessageRules[i][StoppingGameAllowedRule] = -1;
		MessageRules[i][RecycleGameAllowedRule] = -1;
	}



	/*
	SetMessageRule(message_id,
				  server_allowed,
				  client_allowed,
				  waitingForGameAllowed,
				  loadingGame_allowed,
				  preRender_allowed,
				  runningGame_allowed,
				  stoppingGame_allowed,
				  recycleGame_allowed)
	*/

	//												    s  c wt ld pr rn st rc	  server			client
	SetMessageRule(RequestConnectionMessageID,			1, 0, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(DenyRequestConnectionMessageID,		1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(AcceptConnectionMessageID,			1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(LoadGameMessageID,					1, 1, 1, 0, 0, 0, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(LoadPersitantHermitObjectsID,		1, 1, 0, 1, 0, 0, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(AddPlayerMessageID,					1, 1, 0, 1, 1, 1, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(RemovePlayerMessageID,				1, 1, 0, 1, 1, 1, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(RequestPlayerVehicleMessageID,		1, 0, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(AcceptPlayerVehicleMessageID,		1, 1, 1, 0, 0, 0, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(DenyPlayerVehicleMessageID,			1, 1, 1, 0, 0, 0, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(AddLancemateMessageID,				1, 1, 1, 1, 0, 0, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(ReadyToLaunchMessageID,				1, 0, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(ClientLoadedMessageID,				1, 0, 0, 1, 1, 1, 0, 0, ShellClientResolution,	WarnResolution);
	SetMessageRule(RunGameMessageID,					1, 1, 0, 0, 1, 0, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(ScoreMessageID,						1, 1, 0, 0, 1, 1, 0, 0, WarnResolution,			SilentResolution);
	SetMessageRule(RequestRespawnMessageID,				1, 0, 0, 0, 0, 1, 0, 0, ShellClientResolution,	WarnResolution);
	SetMessageRule(RespawnMessageID,					1, 1, 0, 0, 1, 1, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(ChatMessageID,						1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(StopMissionMessageID,				1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(PlayerLeavingMessageID,				1, 1, 0, 1, 1, 1, 0, 0, SilentResolution,		WarnResolution);
	SetMessageRule(RequestMissionParameterMessageID,	1, 0, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(MissionParameterMessageID,			1, 1, 1, 1, 1, 1, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(ScoreFormatMessageID,				1, 1, 0, 0, 1, 1, 0, 0, WarnResolution,			SilentResolution);
	SetMessageRule(RequestMapInfoMessageID,				1, 0, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(MapInfoMessageID,					1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(SwitchToCameraMessageID,				1, 1, 0, 0, 0, 1, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(DecalLayoutMessageID,				1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(RequestDecalsMessageID,				1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(DecalPayLoadMessageID,				1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(AddTeamMessageID,					1, 1, 0, 1, 0, 0, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(LobbyStatusMessageID,				1, 1, 1, 1, 1, 1, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(RequestTeamMessageID,				1, 0, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(RequestPreRenderMessageID,			1, 0, 0, 1, 1, 1, 0, 0, ShellClientResolution,	WarnResolution);
	SetMessageRule(PreRenderMessageID,					1, 1, 0, 1, 0, 0, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(MissionReviewAvailableMessageID,		1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(RequestMissionReviewMessageID,		1, 0, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(CancelMissionReviewMessageID,		1, 0, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(MissionReviewPartMessageID,			1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(RespawnFlagsMessageID,				1, 1, 0, 0, 1, 1, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(PlayerClanMessageID,					1, 1, 1, 1, 1, 1, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(RespawnLancemateMessageID,			1, 1, 0, 0, 1, 1, 0, 0, WarnResolution,			WarnResolution);
	SetMessageRule(UnreadyLaunchMessageID,				1, 0, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(StopMissionConfirmationMessageID,	1, 1, 1, 1, 1, 1, 1, 1, WarnResolution,			WarnResolution);
	SetMessageRule(RequestNewDictionaryMessageID,		1, 1, 1, 1, 1, 1, 1, 1, SilentResolution,		SilentResolution);
	SetMessageRule(KickPlayerMessageID,					1, 1, 1, 1, 1, 1, 1, 1, SilentResolution,		SilentResolution);			
	SetMessageRule(TeamBettyMessageID,					1, 1, 0, 0, 1, 1, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(StartMusicMessageID,					1, 1, 0, 0, 1, 1, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(TeamSetNavMessageID,					1, 1, 0, 0, 1, 1, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(RequestScoreFormatMessageID,			1, 1, 0, 0, 1, 1, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(RespawnMissionMessageID,				1, 1, 0, 0, 1, 1, 0, 0, SilentResolution,		SilentResolution);
	SetMessageRule(RespawnIndexMessageID,				0, 1, 0, 0, 1, 1, 0, 0, SilentResolution,		SilentResolution);
    // team order
    SetMessageRule(TeamOrderMessageID,                  1, 1, 0, 0, 0, 1, 0, 0, SilentResolution,		SilentResolution);
    SetMessageRule(svrTeamOrderMessageID,               1, 0, 0, 0, 0, 1, 0, 0, SilentResolution,		SilentResolution);
    SetMessageRule(RepTeamOrderMessageID,               1, 1, 0, 0, 0, 1, 0, 0, SilentResolution,		SilentResolution);
    SetMessageRule(svrRepTeamOrderMessageID,            1, 0, 0, 0, 0, 1, 0, 0, SilentResolution,		SilentResolution);
    // team order




#ifdef _ARMOR
	for (i = 0; i < LastMessageID-Adept::Network::FirstDirectApplicationMessageID; ++i)
	{
		Verify(MessageRules[i][ServerAllowedRule] != -1);
		Verify(MessageRules[i][ClientAllowedRule] != -1);
		Verify(MessageRules[i][WaitingForGameAllowedRule] != -1);
		Verify(MessageRules[i][LoadingGameAllowedRule] != -1);
		Verify(MessageRules[i][PreRenderAllowedRule] != -1);
		Verify(MessageRules[i][RunningGameAllowedRule] != -1);
		Verify(MessageRules[i][StoppingGameAllowedRule] != -1);
		Verify(MessageRules[i][RecycleGameAllowedRule] != -1);
	}
#endif

}

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


	if (MWApplication::GameFile != NULL)
	{
		delete MWApplication::GameFile;
		MWApplication::GameFile = NULL;
	}
	
	if (MWApplication::NetGameName != NULL)
	{
		delete MWApplication::NetGameName;
		MWApplication::NetGameName = NULL;
	}
	
	if (MWApplication::NetPlayerName != NULL)
	{
		delete MWApplication::NetPlayerName;
		MWApplication::NetPlayerName = NULL;
	}

	if (MWApplication::NetPassword != NULL)
	{
		delete MWApplication::NetPassword;
		MWApplication::NetPassword = NULL;
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
class TextBox
{
protected:
    bool m_bAdjust; // jcem
	char m_Text[MAX_HUD_TEXT];
	DWORD m_Color;
HGOSFONT3D m_Font;
	int m_Justification;
	bool m_Wrap;
	int m_Size;
	gos_DBCS *m_GosObject;

	Stuff::Scalar m_TopLeft[2],m_BottomRight[2];			// margins

	DWORD m_Width,m_Height;
	bool m_BoundsValid;
	bool m_UseOldText;

public:
	enum JUSTIFICATION
	{
		LEFT_ALIGN,
		RIGHT_ALIGN,
		CENTER_ALIGN,
		CENTERREGION_ALIGN
	};
	enum
	{
		SMALL_SIZE,
		MEDIUM_SIZE,
		LARGE_SIZE,
		LARGE2_SIZE,
		LARGE3_SIZE
	};

	TextBox (const char* pcszFontName, int nFontSize = -11, bool oldtext=false);
	virtual ~TextBox (void);

    bool GetAdjust() const { return m_bAdjust; }
    void SetAdjust(bool bAdjust) { m_bAdjust = bAdjust; }

	void TopLeft (Stuff::Scalar x,Stuff::Scalar y);
	void BottomRight (Stuff::Scalar x,Stuff::Scalar y);

	Stuff::Scalar Left (void) const
	{ return m_TopLeft[0]; }
	Stuff::Scalar Top (void) const
	{ return m_TopLeft[1]; }
	Stuff::Scalar Right (void) const
	{ return m_BottomRight[0]; }
	Stuff::Scalar Bottom (void) const
	{ return m_BottomRight[1]; }
	void Color (DWORD value)
	{ m_Color = value; }
	void Color (DWORD red,DWORD green,DWORD blue,DWORD alpha)
	{ m_Color = MakeColor (red,green,blue,alpha); }
	void Justification (JUSTIFICATION value)
	{ m_Justification = value; }
	void Wrap (bool value)
	{ m_Wrap = value; }
	void SetSize (int value)
	{
		m_Size = value;
#if 0
		if (value)
			m_Size = value-1;				// to correct for some funky math in gos
		else
			m_Size = defaultFontSize-1;				// to correct for some funky math in gos
#endif
	}
	int Size (void) const
	{
        return m_Size;
    }
    Stuff::Scalar GetRealSize(int& nGosFontSize) const
    {
        bool bGosFixSize;

        int nSize;
        if (m_Size <= -1000) {
            nSize = m_Size + 1000;
            bGosFixSize = true;
        } else {
            nSize = m_Size;
            bGosFixSize = false;
        }
	    Stuff::Scalar size = (float)nSize;

        if (m_bAdjust) {
	        Scalar fred=0;
	        AdjustCoords (fred,size);
        }

        nGosFontSize = (int)size;
        if (bGosFixSize) {
            nGosFontSize -= 1000;
        }

        return size;
    }
	void DrawSize (DWORD& x,DWORD& y);

	void UpdateText (const char *text,bool force=false,bool extrareturn=false);
	void Draw (Stuff::Point3D loc, bool bTextSetPos = true);
	void Draw (void);
	void EndPos (DWORD& x,DWORD& y);
	bool Empty (void)
	{ return (m_Text[0] == 0); }
	//sanghoon begin
	const char *hsh_get_m_Text(){return &m_Text[0];}
	//sanghoon end
};

TextBox::TextBox (const char* pcszFontName, int nFontSize/* = -11*/, bool oldmode/* = false*/)
{
    m_bAdjust = false;
	m_UseOldText = oldmode;
	m_GosObject = NULL;
	m_Justification = LEFT_ALIGN;
	m_Font = gos_LoadFont(pcszFontName, 0); // "arial black.ttf"
//	m_Font = gos_LoadFont("Assets\\Graphics\\ocraext10reg.d3f", 0);
	m_TopLeft[0] = 0;
	m_TopLeft[1] = 0;
	m_BottomRight[0] = 800;
	m_BottomRight[1] = 600;
	m_Wrap = false;
	m_Size = nFontSize ? nFontSize: -10;
	m_Text[0] = 0;
	m_BoundsValid = false;
}

TextBox::~TextBox (void)
{
	if (m_GosObject)
		m_GosObject->Release ();
	if (m_Font) {
		gos_DeleteFont (m_Font);
		m_Font = NULL;
	}
}

void TextBox::TopLeft (Stuff::Scalar x,Stuff::Scalar y)
{
	m_TopLeft[0] = x;
	m_TopLeft[1] = y;
}

void TextBox::BottomRight (Stuff::Scalar x,Stuff::Scalar y)
{
	m_BottomRight[0] = x;
	m_BottomRight[1] = y;
}

void TextBox::UpdateText (const char *text,bool force,bool extrareturn)
{
	if ((!force) && (!strcmp (m_Text,text)))
		return;

	if (m_GosObject)
	{
		m_GosObject->Release ();
	}
	m_BoundsValid = false;
	m_GosObject = NULL;
	Str_Copy (m_Text,text,MAX_HUD_TEXT);
	if (extrareturn)
		Str_Cat (m_Text,"\n",MAX_HUD_TEXT);
}

void TextBox::Draw (void)
{
#if !defined(NO_TIMERS)
	//MW4AI::my_AutoTimer wilma ((void *) &tTextBoxTime);
#endif
	Scalar size;
	m_Color = m_Color & 0x00ffffff;
	m_Color = m_Color | 0xff000000;
	
	int argb = m_Color;
	
    int nGosFontSize;
    size = GetRealSize(nGosFontSize);
	gos_TextSetAttributes(m_Font,argb,nGosFontSize/*size*/,m_Wrap,true,false,false,m_Justification);
#ifndef NO_HUD_TEXT
	if (m_UseOldText)
	{
    gos_TextDraw (m_Text);
	}
	else
	{
		if (m_GosObject)
			m_GosObject->Release ();
		m_GosObject = MW4HUD_TextDrawDBCS(m_Text,(int) size);
		if (m_GosObject)
			m_GosObject->AddRef ();
	}
#endif
}

void TextBox::Draw (Stuff::Point3D loc, bool bTextSetPos)
{
#if !defined(NO_TIMERS)
	//MW4AI::my_AutoTimer wilma ((void *) &tTextBoxTime);
#endif

	Scalar left,right,top,bottom;
#if 0
	if (loc.x <= 1.0f)
		loc.x *= 800;
	if (loc.y <= 1.0f)
		loc.y *= 600;
#endif
//	if (m_TopLeft[0] <= 1.0f)
//		left = m_TopLeft[0] * 800;
//	else
		left = m_TopLeft[0];
//	if (m_TopLeft[1] <= 1.0f)
//		top = m_TopLeft[1] * 600;
//	else
		top = m_TopLeft[1];

//	if (m_BottomRight[0] <= 1.0f)
//		right = m_BottomRight[0] * 800;
//	else
		right = m_BottomRight[0];
//	if (m_BottomRight[1] <= 1.0f)
//		bottom = m_BottomRight[1] * 600;
//	else
		bottom = m_BottomRight[1];

	m_Color = m_Color & 0x00ffffff;
	m_Color = m_Color | 0xff000000;
	int argb = m_Color;

    if (m_bAdjust) {
	AdjustCoords (left,top,right,bottom);
    }
	gos_TextSetRegion((int) left,(int) top,(int) right,(int) bottom);
	
    int nGosFontSize;
    Scalar size = GetRealSize(nGosFontSize);
	gos_TextSetAttributes(m_Font,argb,nGosFontSize/*size*/,m_Wrap,true,false,false,m_Justification);
				
    if (m_bAdjust) {
	AdjustCoords (loc.x,loc.y);
    }
//	Min_Clamp (loc.x,2);
//	Min_Clamp (loc.y,2);
	if (bTextSetPos)
		gos_TextSetPosition((int) loc.x,(int) loc.y);
#ifndef NO_HUD_TEXT
	if (m_UseOldText)
	{
    gos_TextDraw (m_Text);
	}
	else
	{
		if (m_GosObject)
			m_GosObject->Release ();
		m_GosObject = MW4HUD_TextDrawDBCS(m_Text,(int) size);
		if (m_GosObject)
		{
			m_GosObject->AddRef ();
		}
	}
#endif
}

void TextBox::EndPos (DWORD& x,DWORD& y)
{
	if (!m_GosObject)
	{
		x = y = 0;
		return;
	}
	x = (int) m_GosObject->m_doneFontX;
	y = (int) m_GosObject->m_doneFontY;
	if (m_bAdjust)
	{
		x = (int) (x/g_AdjustMultX);
		y = (int) (y/g_AdjustMultY);
	}
}

void TextBox::DrawSize (DWORD& x,DWORD& y)
{
#if !defined(NO_TIMERS)
	//MW4AI::my_AutoTimer wilma ((void *) &tTextBoxTime);
#endif

#if 0
	if (m_BoundsValid)
	{
		x = m_Width;
		y = m_Height;
		return;
	}
#endif

	Scalar size;
    int nGosFontSize;
    size = GetRealSize(nGosFontSize);

	Scalar left,right,top,bottom;

	left = m_TopLeft[0];
	top = m_TopLeft[1];
	right = m_BottomRight[0];
	bottom = m_BottomRight[1];

    if (m_bAdjust) {
	AdjustCoords (left,top,right,bottom);
    }
	gos_TextSetRegion((int) left,(int) top,(int) right,(int) bottom);

	gos_TextSetAttributes(m_Font,m_Color,nGosFontSize/*size*/,m_Wrap,true,false,false,m_Justification);
	gos_TextSetPosition((int) (left+1),(int) (top+1));

	if (m_GosObject)
		m_GosObject->Release ();
	m_GosObject = MW4HUD_gos_TextStringLength(&x,&y,m_Text,(int) nGosFontSize/*size*/);
	if (m_GosObject)
		m_GosObject->AddRef ();

    if (m_bAdjust) {
	x = (int) (x/g_AdjustMultX);
	y = (int) (y/g_AdjustMultY);
    }
	m_BoundsValid = true;
	m_Width = x;
	m_Height = y;
}

TextBox* g_pTB_Score = NULL;
TextBox* g_pTB_Credits = NULL;
int g_nCoinX = -1, g_nCoinY = -1;
enum {
    img_logo_battletech,
    img_logo_gameleap,

    img_bkscore,

    img_joy_trig1,
    img_arw_to_leftdown,
    img_joy_flash1,

    img_joy_hat_center,
    img_joy_hat_up,
    img_arw_to_up,
    img_joy_hat_down,
    img_arw_to_down,
    img_joy_hat_left,
    img_arw_to_left,
    img_joy_hat_right,
    img_arw_to_right,
    img_joy_flash2,

    img_credits,
    MAX_GOS_PANES
};

const char* g_paNames[MAX_GOS_PANES] = {
    // logos
    "hsh\\coop\\battletech.png",
    "hsh\\coop\\gameleap.png",
    // bk-score
    "hsh\\coop\\bkscore.png",
    // joy
    "hsh\\coop\\joy-trig1.png",
    "hsh\\coop\\arw-to-leftdown.png",
    "hsh\\coop\\joy-flash1.png",

    "hsh\\coop\\joy-hat-center.png",
    "hsh\\coop\\joy-hat-up.png",
    "hsh\\coop\\arw-to-up.png",
    "hsh\\coop\\joy-hat-down.png",
    "hsh\\coop\\arw-to-down.png",
    "hsh\\coop\\joy-hat-left.png",
    "hsh\\coop\\arw-to-left.png",
    "hsh\\coop\\joy-hat-right.png",
    "hsh\\coop\\arw-to-right.png",
    "hsh\\coop\\joy-flash2.png",
    // credit
    "hsh\\coop\\credits2.png",
};
gos_Pane* g_paPanes[MAX_GOS_PANES]; 

int g_naDispCOOPs[4] = { 0, 0, 0, 0} ;

int __stdcall CTCL_SetDispStateCOOP(void* instance, int args, void* data[])
{
	int nType = VALUEPARM(0);
	int nValue;
	switch(nType)
	{
	case 0: // left/top logo...
		nValue = g_naDispCOOPs[0];
		if (VALUEPARM(1)) { // set?
			if (0 < VALUEPARM(1))
				g_naDispCOOPs[0] = VALUEPARM(2);
			else
				g_naDispCOOPs[0] = INTPARM(2);
		}
		break;
	case 1: // right/top score...
		nValue = g_naDispCOOPs[1];
		if (VALUEPARM(1)) { // set?
			if (0 < VALUEPARM(1))
				g_naDispCOOPs[1] = VALUEPARM(2);
			else
				g_naDispCOOPs[1] = INTPARM(2);
		}
		break;
	case 2: // left/bottom joy help
		nValue = g_naDispCOOPs[2];
		if (VALUEPARM(1)) { // set?
			if (0 < VALUEPARM(1))
				g_naDispCOOPs[2] = VALUEPARM(2);
			else
				g_naDispCOOPs[2] = INTPARM(2);
		}
		break;
	case 3: // right/bottom credits
		nValue = g_naDispCOOPs[3];
		if (VALUEPARM(1)) { // set?
			if (0 < VALUEPARM(1))
				g_naDispCOOPs[3] = VALUEPARM(2);
			else
				g_naDispCOOPs[3] = INTPARM(2);
		}
		break;
	default:
		gosASSERT(FALSE);
		nValue = 0;
		break;
	}

	return nValue;
}

void __stdcall CTCL_CoinDisplay(bool bInsideBeginScene)
{
#if 1
	if (!bInsideBeginScene)
		return;

	MWApplication *app;
	app = MWApplication::GetInstance ();
	bool bInGame = (app->GetApplicationState() == ApplicationStateEngine::RunningGameState);
	bool bWaiting = (app->GetApplicationState() == ApplicationStateEngine::WaitingForGameState);

	if (!(bInGame || bWaiting))
		return;

	if (!g_pTB_Credits) {
        gosASSERT(!g_pTB_Score);

			gos_PushCurrentHeap(Heap);
        g_pTB_Score = new TextBox("Gunplay.ttf", -(1000 + 16), false);
		g_pTB_Credits = new TextBox("Gunplay.ttf", -(1000 + 18), false);

        int nLoopID;

        for(nLoopID = 0; nLoopID < MAX_GOS_PANES; nLoopID++)
        {
            g_paPanes[nLoopID] = new gos_Pane((char*)g_paNames[nLoopID], -1, false);
            g_paPanes[nLoopID]->m_alphaMode = gos_Alpha_AlphaInvAlpha;
        }
			gos_PopCurrentHeap();

        return;
		}

    const int s_nBdrOffsX = 5;
    const int s_nBdrOffsY = 5;
    static DWORD s_dwFrames = -1;
    s_dwFrames++;

	gos_PushCurrentHeap(Heap);

	bool bRenderStatePushed = false;

    int nLoopID;
	for(nLoopID = 0; nLoopID < 4; nLoopID++)
	{
		char szCoinText[256];
		int nDispValue;

		if (bInGame && !ModalScripts) {
            bool bAsCam = false;

            if (g_bUseCam) {
                VehicleInterface* pvi = VehicleInterface::GetInstance();
                if (pvi) {
                    Vehicle* pv = pvi->vehicle;
                    if (pv) {
                        if (!pv->IsDerivedFrom(Mech::DefaultData)) {
                            bAsCam = true;
                        }
                    }
                }
            }

            if (bAsCam) {
                nDispValue = 0;
					} else {
			    switch(nLoopID)
			    {
			    case 0: // left/top logo...
				    nDispValue = 1;
				    break;
			    case 1: // right/top score...
				    if (ModalScripts) {
					    nDispValue = 0;
				} else {
					    nDispValue = 1;
				    }
				    break;
			    case 2: // left/bottom joy help
				    nDispValue = 0;
                    // 1 - up/down, 2 - left/right
				    break;
			    case 3: // right/bottom credits
				    nDispValue = 1;
				    break;
			    }
            }
		} else { // bWaiting
			nDispValue = g_naDispCOOPs[nLoopID];
			if (nLoopID == 1)
				nDispValue = 0;
		}
		if (!nDispValue)
			continue;

        if (!bRenderStatePushed) {
	gos_PushRenderStates();
			bRenderStatePushed = true;
		}

		bool bTextDisplay = false;
		int x = 0, y = 0;
        int nPaneW = 0, nPaneH = 0;

        DWORD dwFrams;
		switch(nLoopID)
		{
		case 0: // left/top logo...
            dwFrams = s_dwFrames % (60 * 20);
            dwFrams /= (60 * 5);

            if (dwFrams == 0) {
                g_paPanes[img_logo_battletech]->Render(s_nBdrOffsX, s_nBdrOffsY);
            }
            if (dwFrams == 2) {
                g_paPanes[img_logo_gameleap]->Render(s_nBdrOffsX, s_nBdrOffsY);
            }
			break;
		case 1: // right/top score...
          {
            nPaneW = g_paPanes[img_bkscore]->m_pTextureList->m_width;
            x = Environment.screenWidth - nPaneW - s_nBdrOffsX;

            nPaneH = g_paPanes[img_bkscore]->m_pTextureList->m_height;
            y = s_nBdrOffsY;

            g_paPanes[img_bkscore]->Render(x, y);

			int nScore, nKills, nDeaths;

            nScore = GetScore4Player(nKills, nDeaths);

            MWMission* mission = Cast_Object(MWMission*, MWMission::GetInstance());
            int nTimeMin, nTimeSec;

            if (app->networkingFlag) {
                Scalar fRemain = mission->GetEndMissionTime();
                int nTime = (int)fRemain;
                nTimeSec = nTime % 60;
                nTimeMin = nTime / 60;
			    sprintf(szCoinText, "Score : %d\nTime: %d:%02d\nKill/Death: %d/%d",
                    nScore, nTimeMin, nTimeSec, nKills, nDeaths);
            } else {
		        nScore += app->m_nCamp_Score;
		        nKills += app->m_nCamp_Kills;
		        nDeaths += app->m_nCamp_Deaths;

                Stuff::Time	t = mission->Timer(7).CurrTime();
                int nTime = (int)t;
                nTime = mission->GetCOOP(MWMission::COOP_SUBSTAGE_TIMEGOAL) - nTime;
                if (nTime < 0)
                    nTime = 0;
                nTimeSec = nTime % 60;
                nTimeMin = nTime / 60;

                POINT ptDeadAndEnemy;
                if (!mission->GetCOOP(MWMission::COOP_ENEMY_GROUP, &ptDeadAndEnemy))
                    ptDeadAndEnemy.x = ptDeadAndEnemy.y = 0;

			    sprintf(szCoinText, "Score : %d\nTime: %d:%02d\nEnemy: %d/%d",
                    nScore, nTimeMin, nTimeSec, ptDeadAndEnemy.x, ptDeadAndEnemy.y);
            }
			bTextDisplay = true;
          }
			break;
		case 2: // left/bottom joy help
          {
            // img_joy_...
            int nW = g_paPanes[img_joy_trig1]->m_pTextureList->m_width;
            int nH = g_paPanes[img_joy_trig1]->m_pTextureList->m_height;

#define MAX_JOY_MODE_1 6
#define MAX_JOY_MODE_2 12
#define MAX_JOY_MODE_4 12
#define MAX_JOY_SEQS  4
            static int s_naaTimeAnis_1[MAX_JOY_MODE_1][MAX_JOY_SEQS] = {
                { img_joy_trig1, 0 },
                { img_joy_trig1, img_arw_to_leftdown, 17, 51 - 22 },
                { img_joy_trig1, 0 },
                { img_joy_trig1, img_arw_to_leftdown, 17 - 3, 51 - 22 + 3 },
                { 0, 0 },
                { 0, 0 },
            };
            static int s_naaTimeAnis_2[MAX_JOY_MODE_2][MAX_JOY_SEQS] = {
                { img_joy_hat_center, 0 },
                { img_joy_hat_left, img_arw_to_left, 38, 25 - 14 },
                { img_joy_hat_left, 0 },
                { img_joy_hat_left, img_arw_to_left, 38 + 3, 25 - 14 },
                { img_joy_hat_center, 0 },
                { img_joy_hat_right, img_arw_to_right, 38 - 21, 25 - 14 },
                { img_joy_hat_right, 0 },
                { img_joy_hat_right, img_arw_to_right, 38 - 21 - 3, 25 - 14 },
                { img_joy_hat_right, 0 },
                { img_joy_hat_center, 0 },
                { 0, 0 },
                { 0, 0 },
            };
            static int s_naaTimeAnis_4[MAX_JOY_MODE_4][MAX_JOY_SEQS] = {
                { img_joy_hat_center, 0 },
                { img_joy_hat_up, img_arw_to_up, 38 - 10, 25 },
                { img_joy_hat_up, 0 },
                { img_joy_hat_up, img_arw_to_up, 38 - 10, 25 - 3 },
                { img_joy_hat_center, 0 },
                { img_joy_hat_down, img_arw_to_down, 38 - 10, 25 - 27 },
                { img_joy_hat_down, 0 },
                { img_joy_hat_down, img_arw_to_down, 38 - 10, 25 - 27 + 3 },
                { img_joy_hat_down, 0 },
                { img_joy_hat_center, 0 },
                { 0, 0 },
                { 0, 0 },
            };
            int nMax = 0;
            if (nDispValue & 1) {
                nMax += MAX_JOY_MODE_1;
            }
            if (nDispValue & 2) {
                nMax += MAX_JOY_MODE_2;
            }
            if (nDispValue & 4) {
                nMax += MAX_JOY_MODE_4;
            }
            DWORD dwTicks = (DWORD)(gos_GetHiResTime() * 1000.0f);
            static DWORD s_dwTimeInterval = 400;
            DWORD dwTimeMode = dwTicks / s_dwTimeInterval;
            dwTimeMode %= nMax;

            const int* pn = NULL;
            if (nDispValue & 1) {
                if (dwTimeMode < MAX_JOY_MODE_1) {
                    pn = &s_naaTimeAnis_1[dwTimeMode][0];
                    goto as_skip;
                }
                dwTimeMode -= MAX_JOY_MODE_1;
            }
            if (nDispValue & 2) {
                if (dwTimeMode < MAX_JOY_MODE_2) {
                    pn = &s_naaTimeAnis_2[dwTimeMode][0];
                    goto as_skip;
                }
                dwTimeMode -= MAX_JOY_MODE_2;
            }
            pn = &s_naaTimeAnis_4[dwTimeMode][0];
as_skip:
            const int* pnEnd = &pn[MAX_JOY_SEQS];
            int nIdx;
            while(pn < pnEnd)
            {
                nIdx = *pn++;
                if (nIdx == 0)
                    break;
                int x = s_nBdrOffsX + 0;
                int y = Environment.screenHeight - nH - s_nBdrOffsY;
                switch(nIdx)
                {
                case img_arw_to_leftdown:
                case img_arw_to_up:
                case img_arw_to_down:
                case img_arw_to_left:
                case img_arw_to_right:
                    x += *pn++;
                    y += *pn++;
                    gosASSERT(pn <= pnEnd);
                    break;
                }

                g_paPanes[nIdx]->Render(x, y);
            }
#undef MAX_JOY_SEQS
#undef MAX_JOY_MODE_4
#undef MAX_JOY_MODE_2
#undef MAX_JOY_MODE_1
          }
			break;
		case 3: // right/bottom credits
			if (0 < g_nCoinPerGame) {
                nPaneW = g_paPanes[img_credits]->m_pTextureList->m_width;
                x = Environment.screenWidth - nPaneW - s_nBdrOffsX;

                nPaneH = g_paPanes[img_credits]->m_pTextureList->m_height;
                y = Environment.screenHeight - nPaneH - s_nBdrOffsY;

                g_paPanes[img_credits]->Render(x, y);

                DWORD dwTicks = (DWORD)(gos_GetHiResTime() * 1000.0f);
                static DWORD s_dwTimeInterval = 400;
                DWORD dwTimeMode = dwTicks / s_dwTimeInterval;

                bTextDisplay = (bInGame || (0 < g_nCoinCount) || (dwTimeMode % 2)) ? true: false;

                if (g_nCoinCount <= 0) {
                    sprintf(szCoinText, "Insert Coin(s)");
                } else if ((g_nCoinPerGame == 1) || (g_nCoinCount % g_nCoinPerGame == 0)) {
				    sprintf(szCoinText, "CREDITS: %d", g_nCoinCount / g_nCoinPerGame);
			    } else {
                    //if ((GetACP() == 949) && (g_nCoinPerGame == 2)) {
                    //    sprintf(szCoinText, "CREDITS: %d \xa8\xf6", g_nCoinCount / g_nCoinPerGame); // \xa8\xf6 <- korean symbol 1/2
                    //} else
                    {
				        sprintf(szCoinText, "CREDITS: %d %d/%d", g_nCoinCount / g_nCoinPerGame, g_nCoinCount % g_nCoinPerGame, g_nCoinPerGame);
                    }
                }
			}
			break;
		}

        if (bTextDisplay) {
            TextBox& TB = (nLoopID == 1) ? *g_pTB_Score: *g_pTB_Credits;

            if (TB.GetAdjust()) {
	HUDTexture::StartTexturePass();
            }

		    DWORD color = MakeColor (220, 220, 0, 255);; // MakeColor (0,255,255,255);
		    TB.Wrap(true);
		    TB.Color(color);
		    TB.TopLeft(x, y);
		    TB.BottomRight(x + nPaneW, y + nPaneH);
		    TB.Justification(TextBox::LEFT_ALIGN);
		    TB.UpdateText (szCoinText,false, false);

		DWORD w, h;
		    TB.DrawSize (w, h);

            switch(nLoopID)
            {
            case 1:
				x += (nPaneW - (int)w) / 2;
				y += (nPaneH - (int)h) / 2;
                break;
            case 3:
				x += (nPaneW - (int)w) / 2;
				y += (nPaneH - (int)h) / 2;
                break;
            default:
                gosASSERT(FALSE);
		}
		Stuff::Point3D loc(x, y, 0.9f);
			TB.Draw(loc, true); // loc, false

            if (TB.GetAdjust()) {
	HUDTexture::EndTexturePass();
            }
        }

		switch(nLoopID)
		{
		case 0: // left/top logo...
			break;
		case 1: // right/top score...
			break;
		case 2: // left/bottom joy help
			break;
		case 3: // right/bottom credits
			break;
		}
	}

	if (bRenderStatePushed) {
	gos_PopRenderStates ();
	}

    if (g_InviteCOOP.m_pParent) {
        // if I'm being invited?
        if (app->networkingFlag) {
            g_InviteCOOP.m_nResult = 2;
        } else {
        }
    }

	gos_PopCurrentHeap();
#endif
}

int __stdcall CTCL_CheckInviteCOOP(void* instance, int args, void* data[])
{
	MWApplication *app;
	app = MWApplication::GetInstance();

	int nCheck = VALUEPARM(0);
    if (nCheck == -1) { // still inviter waiting?...
        if (!g_InviteCOOP.m_pParent) {
            return -1;
        }
        return 1;
    } else if (nCheck == 0) {
        if (app->m_nCamp_Stage < 0) {
            if ((app->m_nCamp_Stage == -1) || (app->m_nCamp_Stage == -2)) {
                return 3;
            }
            gosASSERT((app->m_nCamp_Stage == -3) || (app->m_nCamp_Stage == -4)); // high score...
            return 0;
        }
        if (g_InviteCOOP.m_pParent) {
            // ask...
            if (g_nCoinPerGame <= g_nCoinCount)
                return g_InviteCOOP.m_nResult;
            else {
                bool bInGame = (app->GetApplicationState() == ApplicationStateEngine::RunningGameState);
                if (!bInGame || app->networkingFlag) {
                    //!ModalScripts
                    g_InviteCOOP.m_nResult = 2;
                }
                return g_InviteCOOP.m_nResult;
            }
        }

        return 0;
    } else if (nCheck == 1) {
        if (app->m_nCamp_Stage < 0) {
            return 3;
        }
        return 2;
    } else {
        gosASSERT((nCheck == 2) || (nCheck == 3));
        if (g_InviteCOOP.m_pParent) {
            g_InviteCOOP.m_nResult = nCheck;
            if (nCheck == 3) {
                memcpy(&g_guidGameDatas, &g_InviteCOOP.m_guidGameData, sizeof(GUID));
                app->m_nCamp_Stage = -2; // from menu
            }
        }

        return 0;
    }
}

int __stdcall CTCL_DoInviteCOOP(void* instance, int args, void* data[])
{
	int nTimeInvite = INTPARM(0);

    if (nTimeInvite == -998) {
        g_InviteCOOP.m_pParent = NULL;
        g_InviteCOOP.Clear();
        return g_nCoinCountTemp;
    } else {
        gosASSERT(nTimeInvite);
        int& nYes = INTPARM(1);
        int& nNo = INTPARM(2);
        int& nProcessings = INTPARM(3);
        return CTCL_InviteCOOP(nTimeInvite, nYes, nNo, nProcessings);
    }
}

int __stdcall CTCL_Inviter(void* instance, int args, void* data[])
{
    char*& pszInviter = *(char**)data[0];
	if (*pszInviter)
		gos_Free(pszInviter);
	pszInviter = (char*)gos_Malloc(strlen(g_szTeslaInviter) + 1);
	strcpy(pszInviter, g_szTeslaInviter);

    return 0;
}

MWApplication::MWApplication(ClassData *class_data, bool display_gui)
	: Application(class_data)
	, m_DisplayGUI(display_gui)
	, replicatedHermits(NULL)
	, animationScriptsLoadQue(NULL)
	, decalNames(NULL, false)
{
	m_nCamp_Stage = m_nCamp_Kills = m_nCamp_Deaths = m_nCamp_Score = 0;
    m_nCamp_Time = m_nCamp_Mech = m_bCamp_Success = 0;

// MSL 5.02 AVI and MPG Training

	if (g_nCTCL == _ECTCL_CameraShip) // CTCL_GetType()==_ECTCL_CameraShip)
	{
		if (!g_hVideo) {
			extern char AssetsDirectory1[MAX_PATH];
			char tempavi[256];
			char tempmpg[256];
			sprintf(tempavi, "%s\\hsh\\Training.avi", AssetsDirectory1);
			sprintf(tempmpg, "%s\\hsh\\Training.mpg", AssetsDirectory1);
			if (_access(tempavi,0)==0)
			{
				gosVideo_CreateResource(&g_hVideo, tempavi);
				if (g_hVideo) {
					gosVideo_SetPlayMode(g_hVideo, gosVideo_Stop); // gosVideo_Stop
				}
			}
			else
			{
				if (_access(tempmpg,0)==0)
				{
					gosVideo_CreateResource(&g_hVideo, tempmpg);
					if (g_hVideo) {
						gosVideo_SetPlayMode(g_hVideo, gosVideo_Stop); // gosVideo_Stop
					}
				}
			}
		}
	}

    if (g_bCOOP)
	{
		g_pfnCTCL_CoinDisplay = CTCL_CoinDisplay;
        g_pfnCTCL_HandleKey = CTCL_HandleKey;
    }

	#ifdef _ICECAP
//	StopCAPAll ();
	#endif
	m_localMissionParameters = new NetMissionParameters::MWNetMissionParameters;
	m_serverMissionParameters = new NetMissionParameters::MWNetMissionParameters;

	validDrop = true;
	scoreSaved = false;
	recycleTimerOn = false;
	recycleStartTime = 0.0f;

	m_pilotName = "Pilot1";
	m_currentMissionStatus = 0; //This is fail...2 is success

	langResources = gos_OpenResourceDLL("MissionLang.dll");
	if (!langResources)
		STOP(("You are missing the localization dll MissionLang.dll"));

	localVehicelAccepted = VEHICLE_NOTSENT;

	m_iaGameType = DefaultGameType;

	m_campaignIsComplete = false;
	m_isMasterTrial = false;

	m_lastMechID = 0;
	m_lastMechName = "";

	missionReady = false;
	missionName = NULL;

	m_iaDisplayGameType = 0;

	m_DifficultyLevel = MEDIUM_DIFFICULTY;

	quedStop = false;
	quedPlayerRespawn = false;
	noRecycle = false;
	waitingForRunMessage = false;

	m_lastMissionKills = 0;
	m_lastMissionDeaths = 0;

	m_mechTable = NULL;
	m_subsystemTable = NULL;
	m_mechChassisTable = NULL;
	m_weaponsTable = NULL;
	m_skinsTable = NULL;
	m_missionsRenameTable = NULL;

	parametersDirty = false;
	
	AllowDecalTransfer = false;

	timeSinceLastUnready = 0.0f;

	m_isNight = false;

	lastMapCRC = -1;
	haveNetworkMap = true;

	networkExitCode = NoExitCode;

	motdLength = 0;

	timeFromLastParameterSend = 0.0;
	timeFromLastLobbyStatus = 0.0;

	#if defined(LAB_ONLY)
		MWGameInfo::InitGameInfo();
	#endif

	for (int i = 0; i < Maximum_Teams; ++i)
	{
		teams[i] = new SlotOf<Team *>(NULL);
	}



	ngLogBanCount = 0;
	keyBanCount = 0;
	ispBanCount = 0;

	ngLogBans = NULL;
	keyBans = NULL;
	ispBans = NULL;

#if !defined(NO_MR)
	m_recordLog = NULL;
	m_playLog = NULL;
	totalReviewPackets = 0;
	reviewPackets = NULL;

	missionReviewAvailable = false;
	playingMissionReview = false;
#endif // !defined(NO_MR)

	lockTimer = false;
	lockTimerVal = 0;

	gameTimer = false;
	gameTimerVal = 0;

	recycleTimer = false;
	recycleTimerVal = 0;

	lastErrorCount = 0;
	lastBotErrorCount = 0;
	for (i = 0; i < MaxBuildErrorCount; ++i)
	{
		lastErrors[i]=NoError;
		lastErrorsParameter[i] = 0;

		lastBotErrors[i]=NoError;
		lastBotErrorsParameter[i] = 0;
	}

    MRP_Setup(); // jcem - mission replay
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWApplication::~MWApplication()
{
    FREE_PTR(LocalIPAddress);
    MRP_Cleanup(); // jcem - mission replay
    g_RSF.Reset();

	#ifdef LAB_ONLY
	MWGameInfo::QuitGameInfo();
	#endif

	for (int i = 0; i < Maximum_Players; ++i)
	{
		servedConnectionData[i].Disconnect();	
	}

	for (i = 0; i < Maximum_Lancemates; ++i)
	{
		lancemateConnectionData[i].Disconnect();
	}

	for (i = 0; i < Maximum_Teams; ++i)
	{
		delete teams[i];
	}



	if (missionName != NULL)
	{
		Check_Pointer(missionName);
		delete[] missionName;
	}

	
	Stuff::SortedChainIteratorOf<DecalEntry*, int> iterator(&decalNames);
	DecalEntry *string;
	while ((string = iterator.GetCurrent()) != NULL)
	{
		iterator.Remove();
		delete string;
	}

	ngLogBanCount = 0;
	keyBanCount = 0;
	ispBanCount = 0;

	if (ngLogBans != NULL)
		delete[] ngLogBans;
	if (keyBans != NULL)
		delete[] ngLogBans;
	if (ispBans != NULL)
		delete[] ngLogBans;


	delete m_localMissionParameters;
	delete m_serverMissionParameters;


#if !defined(NO_MR)
	if (m_recordLog)
	{
		delete m_recordLog;
		m_recordLog = NULL;
	}

	if (m_playLog)
	{
		delete m_playLog;
		m_playLog = NULL;
	}
#endif // !defined(NO_MR)

    ClearTOC();
}



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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::Initialize()
{
	Check_Object(this);

	gos_PushCurrentHeap(Heap);
	Verify(!MWEntityManager::GetInstance());
	GlobalPointers::AddGlobalPointer(new MWEntityManager, EntityManagerGlobalPointerIndex);
	Register_Object(MWEntityManager::GetInstance());
	
	gos_PopCurrentHeap();

	Application::Initialize();
	//
	//-----------------
	// Create renderers
	//-----------------
	//
	Check_Object(RendererManager::Instance);
	Verify(!VideoRenderer::Instance);
	gos_PushCurrentHeap(VideoRenderer::s_Heap);
	VideoRenderer::Instance = new MWVideoRenderer(DisplayGUI());
	Register_Object(VideoRenderer::Instance);
	RendererManager::Instance->AdoptRenderer(VideoRenderer::Instance);
	gos_PopCurrentHeap();

	gos_PushCurrentHeap(AudioRenderer::s_Heap);
	Verify(!AudioRenderer::Instance);
	AudioRenderer::Instance = new AudioRenderer();
	Register_Object(AudioRenderer::Instance);
	RendererManager::Instance->AdoptRenderer(AudioRenderer::Instance);
	gos_PopCurrentHeap();
	
	gos_PushCurrentHeap(Heap);
	MW4AI::g_PathManager = new MW4AI::CPathManager ();
	backgroundTasks->AddTask (MW4AI::g_PathManager);
	gos_PopCurrentHeap();

	if ((!MW4Shell::Instance) &&
		(DisplayGUI()))
	{
		MW4Shell::Instance = new MW4Shell;
		Check_Pointer(MW4Shell::Instance);
	}



}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::Terminate()
{
	Check_Object(this);
	//
	// Destroy the renderers
	//
    g_pfnCTCL_HandleKey = NULL;
	g_pfnCTCL_CoinDisplay = NULL;
    {for(int qq = 0; qq < MAX_GOS_PANES; qq++)
    {
        gos_Pane* p = g_paPanes[qq];
        if (p) {
            g_paPanes[qq] = NULL;
            delete p;
        }
    }}

	if (g_pTB_Score) {
		delete g_pTB_Score;
		g_pTB_Score = NULL;
	}
	if (g_pTB_Credits) {
		delete g_pTB_Credits;
		g_pTB_Credits = NULL;
	}

	if (g_hCoinSound) {
		gosAudio_DestroyResource(&g_hCoinSound);
		g_hCoinSound = NULL;
	}

	if (MW4Shell::Instance)
	{
		delete MW4Shell::Instance;
		MW4Shell::Instance = NULL;
	}

	if (MWCampaign::Instance)
	{
		delete MWCampaign::Instance;
		MWCampaign::Instance = NULL;
	}

	if (MWCampaign::TrainingInstance)
	{
		delete MWCampaign::TrainingInstance;
		MWCampaign::TrainingInstance = NULL;
	}

	if (MWCampaign::MasterTrialsInstance)
	{
		delete MWCampaign::MasterTrialsInstance;
		MWCampaign::MasterTrialsInstance = NULL;
	}

	if (MWCampaign::WaveInstance)
	{
		delete MWCampaign::WaveInstance;
		MWCampaign::WaveInstance = NULL;
	}

	if (SalvageManager::GetInstance())
	{
		delete SalvageManager::GetInstance();
		GlobalPointers::ClearPointer(SalvageManagerGlobalPointerIndex);
	}

	if (MWGame::GetInstance())
	{
		delete MWGame::GetInstance();
		GlobalPointers::ClearPointer(MWGameGlobalPointerIndex);
	}

	if(m_mechTable)
		delete m_mechTable;
	if(m_subsystemTable)
		delete m_subsystemTable;
	if(m_mechChassisTable)
		delete m_mechChassisTable;
	if(m_weaponsTable)
		delete m_weaponsTable;
	if(m_skinsTable)
		delete m_skinsTable;
	if (m_missionsRenameTable)
		delete m_missionsRenameTable;

	Unregister_Object(VideoRenderer::Instance);
	delete VideoRenderer::Instance;
	VideoRenderer::Instance = NULL;

	Unregister_Object(AudioRenderer::Instance);
	delete AudioRenderer::Instance;
	AudioRenderer::Instance = NULL;

	Application::Terminate();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MWApplication::DisplayGUI() const
{
	return (m_DisplayGUI);
}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::PauseGameMessageHandler(const ReceiverDataMessageOf<int> *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "PauseGameMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);

	//------------------------------------------
	// Ignore anything where the key is going up
	//------------------------------------------
	if (message && (message->dataContents < 0))
		return;

  if (IsCampCOOP()) {
	if (message) { // jcem
		gosASSERT(g_nWhyPaused == 0);
		g_nWhyPaused = 6;
	} else {
		gosASSERT((1 <= g_nWhyPaused) && (g_nWhyPaused <= 4));
	}
  } else {
	Check_Object(message);
	gosASSERT(g_nWhyPaused == 0);
  }

	
	
	
	// pause game...

	if (!networkingFlag)
	{
		if (AudioRenderer::Instance != 0)
		{
			AudioRenderer::Instance->PauseAll();
		}

		// Handle Pause Menu and Pause Option menu
		while (true)
		{
			MW4Shell::Instance->StartPauseShellExecuteModal();
			if (MW4Shell::Instance->shellCommand == MW4Shell::SetPauseOptionResCommand)
			{
				MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
				gos_SetScreenMode(800,600,Environment.bitDepth,Environment.FullScreenDevice);

				// Start the options screen
				MW4Shell::Instance->StartPauseOptionsShellExecute();

				if (MW4Shell::Instance->shellCommand == MW4Shell::UnsetPauseOptionResCommand)
				{
					MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
					gos_SetScreenMode(s_ScreenWidth, s_ScreenHeight,Environment.bitDepth,Environment.FullScreenDevice);
				}	
			}
			else
			{
				break;
			}
		}

		if (AudioRenderer::Instance != 0)
		{
			AudioRenderer::Instance->ResumeAll();
		}
		gos_RecreateTextureHeaps();

        int nWhyPausedSaved = g_nWhyPaused;
        g_nWhyPaused = 0; // use nWhyPausedSaved...

		MWMission* mission = Cast_Object(MWMission*, MWMission::GetInstance());

		if (MW4Shell::Instance->shellCommand == MW4Shell::ResumeMissionCommand)
		{
            switch(nWhyPausedSaved)
            {
            case 3:
            case 6:
                gosASSERT(IsCampCOOP());
                g_nCoinCount -= g_nCoinPerGame;
                break;
            case 4:
                g_InviteCOOP.m_nResult = 3; // yes challenge
                memcpy(&g_guidGameDatas, &g_InviteCOOP.m_guidGameData, sizeof(GUID));
                m_nCamp_Stage = -1;
                QueStopGame();
                break;
            }

			MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;

            mission->SetCOOP(MWMission::COOP_MODAL_IS_ENDED, +1);
        } else {
            gosASSERT((nWhyPausedSaved != 1) && (nWhyPausedSaved != 2));

            switch(nWhyPausedSaved)
            {
            case 3:
                if (MWGame::GetInstance()) {
                    m_currentMissionStatus = 0;
                    MWGame::GetInstance()->EarlyReactToEndMission();
                }
                break;
            case 4:
                g_InviteCOOP.m_nResult = 2; // no challenge
                break;
            }

          if (nWhyPausedSaved != 4) {
            if (MW4Shell::Instance->shellCommand == MW4Shell::ExitMissionCommand)
		{
			Verify(Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState);
			Application::GetInstance()->QueStopGame();
			MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
		}
		else if (MW4Shell::Instance->shellCommand == MW4Shell::ExitToMainMenuCommand)
		{	
			Verify(Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState);
			Application::GetInstance()->QueStopGame();
			MW4Shell::Instance->shellStart = MW4Shell::MainShellStart;
			MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
		}
          }

            mission->SetCOOP(MWMission::COOP_MODAL_IS_ENDED, -1);
        }
		Environment.DoGameLogic	= &MWApplication::DoGameLogic;

        if (0 < mission->GetCOOP(MWMission::COOP_MODAL_IS_ENDED)) {
            if (nWhyPausedSaved == 3) {
				Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestRespawnMessageID, NULL, true);
            }
        }
	}
	else
	{

		if (MW4Shell::Instance->currentShellRunning != MW4Shell::InGameShellRunning)
		{
			MW4Shell::Instance->StartPauseShellExecute();
			Environment.DoGameLogic	= &MWApplication::DoShellLogic;
			if (VehicleInterface::GetInstance())
			{
				VehicleInterface::GetInstance()->fireBlocked = true;
			}
			if (ControlsManager::Instance)
			{
				ControlsManager::Instance->m_IgnoreCommands = true;
			}
		}
		else
		{
			MW4Shell::Instance->StopPauseShellExecute();
			Environment.DoGameLogic	= &MWApplication::DoGameLogic;
			
			if (VehicleInterface::GetInstance())
			{
				VehicleInterface::GetInstance()->fireBlocked = false;
			}
			if (ControlsManager::Instance)
			{
				ControlsManager::Instance->m_IgnoreCommands = false;
			}
		}
	}
}


#if !defined(NO_LOG)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// ngLog addition
void
	MWApplication::LogPlayerConnect(int i)
{
	char *m_name = (char *)servedConnectionData[i].clientPlayer->GetVehicle()->GetModelName();
	float m_tonnage = servedConnectionData[i].clientPlayer->GetVehicle()->GetTonage();
	char *p_name = (char *)Network::GetInstance()->GetConnection(i)->GetConnectionName();


	if(!*p_name) {
		p_name = "UNKNOWN";
	}

	for(int j=FirstWeaponID; j<sizeof(servedConnectionData[i].ServedConnectionData::NumWeaponsTracked); j++) {
		servedConnectionData[i].dmg_given[j] = 0;
		servedConnectionData[i].dmg_rcvd[j] = 0;
		servedConnectionData[i].wep_atts[j] = 0;
		servedConnectionData[i].wep_hits[j] = 0;
	}

	for(j=0; j<Maximum_Players+Maximum_Lancemates; j++) {
		servedConnectionData[i].pdmg_given[j] = 0;
		servedConnectionData[i].pdmg_rcvd[j] = 0;
		servedConnectionData[i].comp_inf[j] = 0;
		servedConnectionData[i].comp_rcv[j] = 0;
	}

	servedConnectionData[i].stats_update = 1;
	MW4log_playerConnect(i, p_name, m_name, m_tonnage,
						(unsigned char *)&servedConnectionData[i].ngLogID,
						sizeof(GUID));

	if(GetLocalNetParams()->m_teamAllowed) {
		char tmp[32];

		sprintf(tmp, "Player_Team\t%d\t%d", i, servedConnectionData[i].pilotTeam);
		MW4log_generic(MW4GAME_GEN, tmp);
	}
	return;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// ngLog addition
void
	MWApplication::LogBotConnect(void)
{
	for(int i=0; i<Maximum_Lancemates; i++) {
		if(!lancemateConnectionData[i].lancemateConnected || !lancemateConnectionData[i].lancemateMech) {
			continue;
		}

		for(int j=FirstWeaponID; j<sizeof(lancemateConnectionData[i].LancemateConnectionData::NumWeaponsTracked); j++) {
			lancemateConnectionData[i].dmg_given[j] = 0;
			lancemateConnectionData[i].dmg_rcvd[j] = 0;
			lancemateConnectionData[i].wep_atts[j] = 0;
			lancemateConnectionData[i].wep_hits[j] = 0;
		}

		for(j=0; j<Maximum_Players+Maximum_Lancemates; j++) {
			lancemateConnectionData[i].pdmg_given[j] = 0;
			lancemateConnectionData[i].pdmg_rcvd[j] = 0;
			lancemateConnectionData[i].comp_inf[j] = 0;
			lancemateConnectionData[i].comp_rcv[j] = 0;
		}

		lancemateConnectionData[i].stats_update = 1;
		MW4log_generic(MW4L_ADD, va("Player_Connect\t%d\t%s\t%s\t%.2f\tIS_A_BOT:%s", i+Maximum_Players,
															lancemateConnectionData[i].lancemateName,
															lancemateConnectionData[i].lancemateMech->GetModelName(),
															lancemateConnectionData[i].lancemateMech->GetTonage(),
															lancemateConnectionData[i].scriptName));
		if(GetLocalNetParams()->m_teamAllowed) {	
			char tmp[32];

			sprintf(tmp, "Player_Team\t%d\t%d", i+Maximum_Players, lancemateConnectionData[i].pilotTeam);
			MW4log_generic(MW4GAME_GEN, tmp);
		}
	}

	return;
}
#endif // !defined(NO_LOG)

void (*RunFromOtherAppEnterStoppingGameState)(void) = NULL;
void (*RunFromOtherAppEnterRecyclingGameState)(void) = NULL;
void (*RunFromOtherAppEnterLoadingGameState)(void) = NULL;
void (*RunFromOtherAppEnterRunningGameState)(void) = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::EnterRunningGameState(void* data)
{
	if (g_hVideo) {
		gosVideo_SetPlayMode(g_hVideo, gosVideo_Stop); // gosVideo_Stop
	}

	#ifdef _ICECAP
//	StopCAPAll ();
	#endif
    MWEntityManager::GetInstance()->m_uPostDeathFlags = 0;

	scoreSaved = false;


	MWApplication *app = MWApplication::GetInstance();
	app->memoryDiffKiller.Uninit();

    g_fGameEndScreenTimer = 0.0;
    g_MRF.Starting(); // jcem
    g_RSF.Starting(); // jcem

	Application::EnterRunningGameState(data);

	if (!MWApplication::GetInstance()->Win32DedicatedServer){
		Check_Object(RendererManager::Instance);
		RendererManager::Instance->ActivateRenderers();
	}
	
	// launch any players not loaded
	if (serverFlag)
	{
		// ngLog addition
#if !defined(NO_LOG)
		if (networkingFlag && !GetLocalNetParams()->m_runDedicated) {
			LogPlayerConnect(Connection::Server->GetID());
		}
#endif // !defined(NO_LOG)

		for (int i = 1; i < Maximum_Players; ++i)
		{
            if (g_nMR == 2) {
                if (servedConnectionData[i].clientConnected) {
                    servedConnectionData[i].clientLoaded = true;
                }
            }
			if (servedConnectionData[i].clientLoaded && i != Connection::Server->GetID())
			{
				SendRunGameMessage(i);
				// ngLog addition
#if !defined(NO_LOG)
				if(networkingFlag) {
					LogPlayerConnect(i);
				}
#endif // !defined(NO_LOG)
			}
		}

		// ngLog addition -- Log connected bots here as they are already properly initialized
#if !defined(NO_LOG)
		if(networkingFlag) {
			LogBotConnect();
		}
#endif // !defined(NO_LOG)

#if !defined(NO_MR)
		if (m_recordLog)
		{
			m_recordLog->StartRecordingLog(1.0f);
		}
#endif // !defined(NO_MR)




		
		for (i = 0; i < Maximum_Players; ++i)
		{
			if (servedConnectionData[i].clientReady && !servedConnectionData[i].clientLaunched)
			{
				BroadcastAddNewPlayer(i);
				servedConnectionData[i].clientQuedForLaunch = true;
			}
		}

		

		
			



	}

	if (MW4Shell::Instance != NULL)
		MW4Shell::Instance->StopLoadingShell();

	Environment.DoGameLogic	= &MWApplication::DoGameLogic;

	Application::GetInstance()->UnpauseGame();

	MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());

	NetMissionParameters::MWNetMissionParameters *params = 0;
	if (serverFlag)
	{
		params = MWApplication::GetInstance()->GetLocalNetParams();
	}
	else
	{
		params = MWApplication::GetInstance()->GetServerNetParams();
	}

	if (networkingFlag &&
		(params != 0))
	{	
        if (g_nMR == 2) {
            mission->SetEndMissionTime(g_MRF.EndMissionTime()); // jcem - mission could be ended before end-mission-timer...
        } else {
#ifdef _DEBUG
		if (params->m_gameLength == 0)
			mission->SetEndMissionTime(20.0f);
		else {
#endif // _DEBUG
			if (params->m_gameLength > 0) {
		//mission->SetEndMissionTime((Stuff::Scalar)25.0f);
		mission->SetEndMissionTime((Stuff::Scalar)params->m_gameLength * 60.0f);
			}
#ifdef _DEBUG
		}
#endif // _DEBUG
        }
	}

	mission->StartMissionTimer();



	if (Application::GetInstance()->m_localMissionParameters->m_runDedicated)
	{
		MW4Shell::Instance->StartStatShell();
	}
	else
	{
		MWVideoRenderer::SetDrawBlack();
	}

	if (RunFromOtherAppEnterRunningGameState)
		RunFromOtherAppEnterRunningGameState();

// jcem - begin
    ClearTOC();
    if (CTCL_IsConsoleX()) {
        CTCL_SetGameState(_EGS_Running);
        if (serverFlag) {
            CTCL_SetGameTime(params->m_gameLength * 60);
            CTCL_SetGameIsServer(1);
        } else {
            CTCL_SetGameTime(-1);
            CTCL_SetGameIsServer(0);
        }
        Environment.DoGameLogic	= &MWApplication::DoGameLogic;
    }
    // hyun begin
	RIO_StartStop (TRUE);
    // hyun end

    g_MRF.Started(); // jcem
    g_RSF.Started(); // jcem

    sh_game_started = true;

    COOP_InputMode(true);

    extern void _stdcall CTCL_DoPlayMusic();
    CTCL_DoPlayMusic();
// jcem - end
	// tacky hard-coded hack: for coliseum multiplayer game, queue the music track because no
	// ABL is run on the client and we don't want silence in the beginning or interruptions
	#define ARCTICAMB_WAV		"music\\ArcticAmbLoop_music.wav{handle}" 
	#define ARCTICAMB_VOLUME	(20.0f / 100.0f)
	#define SWAMPAMB_WAV		"music\\SwampAmbLoop_music.wav{handle}" 
	#define SWAMPAMB_VOLUME		(20.0f / 100.0f)
	#define HOTPLATEAMB_WAV		"music\\LavaAmbLoop_music.wav{handle}" 
	#define HOTPLATEAMB_VOLUME	(20.0f / 100.0f)
	#define COLISEUMAMB_WAV		"music\\ColiseumAmb_music.wav{handle}" 
	#define COLISEUMAMB_VOLUME	(20.0f / 100.0f)
	#define FACTORYAMB_WAV		"music\\FactoryAmb_Music.wav{handle}" 
	#define FACTORYAMB_VOLUME	(40.0f / 100.0f)
	#define JUNGLEAMB_WAV		"music\\JungleAmb1_Music.wav{handle}" 
	#define JUNGLEAMB_VOLUME	(20.0f / 100.0f)
	Check_Object (mission);
	bool fIsArctic = (MWMission::MISSIONTYPE_ARCTIC == mission->GetMissionType());
	bool fIsSwamp = (MWMission::MISSIONTYPE_SWAMP == mission->GetMissionType());
	bool fIsHotplate = (MWMission::MISSIONTYPE_HOTPLATE == mission->GetMissionType());
	bool fIsColiseum = (MWMission::MISSIONTYPE_COLISEUM == mission->GetMissionType());
	bool fIsFactory = (MWMission::MISSIONTYPE_FACTORY == mission->GetMissionType());
	bool fIsJungle = (MWMission::MISSIONTYPE_JUNGLE == mission->GetMissionType());
	if (fIsColiseum || fIsFactory || fIsJungle || fIsArctic || fIsSwamp || fIsHotplate)
	{
		// this sound is the din of a roaring crowd:
		AudioCommand *command;
		if (fIsArctic)
			command = AudioCommand::Create(AudioRenderer::MusicType,ARCTICAMB_WAV,1.0f,1.0f);
		if (fIsSwamp)
			command = AudioCommand::Create(AudioRenderer::MusicType,SWAMPAMB_WAV,1.0f,1.0f);
//		if (fIsHotplate)
//			command = AudioCommand::Create(AudioRenderer::MusicType,HOTPLATEAMB_WAV,1.0f,1.0f);
		if (fIsColiseum)
			command = AudioCommand::Create(AudioRenderer::MusicType,COLISEUMAMB_WAV,1.0f,1.0f);
		if (fIsJungle)
			command = AudioCommand::Create(AudioRenderer::MusicType,JUNGLEAMB_WAV,1.0f,1.0f);
		if (fIsFactory)
			command = AudioCommand::Create(AudioRenderer::MusicType,FACTORYAMB_WAV,1.0f,1.0f);
		Check_Object(command);
		if (command)
		{
			command->Play(gosAudio_Loop);
			if ((AudioRenderer::Instance != 0) &&
				(AudioRenderer::Instance->m_channelTypes.GetLength() > AudioRenderer::MusicType))
			{
				AudioRenderer::Instance->m_channelTypes[AudioRenderer::MusicType].SetVolume(COLISEUMAMB_VOLUME);
			}
		}
	}

}

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

void MWApplication::EnterPreRenderState(void* data)
{
// jcem - begin
    g_fGameEndScreenTimer = 0.0;
    g_MRF.PreRendering(); // jcem
    ClearTOC();
    if (CTCL_IsConsoleX()) {
        CTCL_SetGameState(_EGS_Preparing);
        CTCL_SetGameTime(-1);
        if (serverFlag) {
            CTCL_SetGameIsServer(1);
        } else {
            CTCL_SetGameIsServer(0);
        }
    }
// jcem - end


	if (serverFlag)
	{
		for (int i = 1; i < Maximum_Players; ++i)
		{
			if (servedConnectionData[i].clientReadyForPrerender && i != Connection::Server->GetID())
			{
				SendPreRenderMessage(i);
			}
		}
	}

	Application::EnterPreRenderState(data);

    if (!g_bNoPlasma) {
        PLASMA_Do(1);
    }
    g_MRF.PreRendered(); // jcem
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::EnterStoppingGameState(void* data)
{
// jcem - begin
	MWApplication *app;
	app = MWApplication::GetInstance ();

    void _stdcall CTCL_DoStopMusic();
    CTCL_DoStopMusic();
    COOP_InputMode(false);

	if(MWGame::GetInstance())
        MWGame::GetInstance()->EarlyReactToEndMission();

    g_MRF.Stopping(); // jcem
    g_RSF.Stopping(); // jcem

    ClearTOC();
    // hyun begin
	RIO_StartStop (FALSE);
    // hyun end
    if (CTCL_IsConsoleX()) {
        CTCL_SetGameState(_EGS_Closing);
    }
// jcem - end

	if (MW4Shell::Instance != NULL)
	{
		MW4Shell::Instance->ClearMechLab(0);
	}

	#ifdef _ICECAP
//	StartCAPAll ();
	#endif
	#ifdef LAB_ONLY
	if ((SaveGameStats == true) &&
		(missionName != NULL))
	{
		SaveGameLog();
	}
	#endif

	waitingForRunMessage = false;

	scoreSaved = false;

	Flag::ResetAllFlags();

	if(serverFlag) {


#if !defined(NO_MR)
		if (reviewPackets != NULL)
		{
			delete[] reviewPackets;
			reviewPackets = NULL;
		}
		totalReviewPackets = 0;


		if (m_recordLog)
		{
			delete m_recordLog;
			m_recordLog = NULL;
		}
#endif // !defined(NO_MR)


		currentGameNumber = 0;

		// ngLog addition
#if !defined(NO_LOG)
		if(networkingFlag) {
			MW4log_writeAllStats();
			MW4log_GameEnd(MW4GAME_END, "StoppingState");
		}
#endif // !defined(NO_LOG)
	}

	Application::EnterStoppingGameState(data);

	if (missionName != NULL)
	{
		Check_Pointer(missionName);
		delete missionName;
		missionName = NULL;
	}


	ABL::ABLi_close ();

	Environment.DoGameLogic	= &MWApplication::DoShellLogic;


	// kill all the open resources except one...

	Check_Object(MW4Animation::AnimInstanceManager::Anim_Instance_Manager);
	MW4Animation::AnimInstanceManager::Anim_Instance_Manager->DeleteAnimations();

	MWApplication::GetInstance()->recycleTimerOn = false;


	ResourceManager::Instance->CloseAllButCore();
	delete gosFX::EffectLibrary::Instance;
	Verify(!gosFX::EffectLibrary::Instance);

	if (MW4Shell::Instance != NULL)
	{


		


		if (MW4Shell::Instance->currentShellRunning == MW4Shell::InGameShellRunning)
		{
			MW4Shell::Instance->StopNetworkShellsExecute();
			MW4Shell::Instance->EndAllScripts();
			MW4Shell::Instance->currentShellRunning = MW4Shell::NoShellRunning;
		}
		else
		{
			MW4Shell::Instance->StopNetworkShellsExecute();
		}
		
		if (Application::GetInstance()->m_localMissionParameters->m_runDedicated)
		{
			MW4Shell::Instance->StopStatShell();
		}

		MW4Shell::Instance->StopLoadingShell();

	}

	Application::GetInstance()->UnpauseGame();

	if (DamageDispatch::m_Instance != 0)
	{
		delete DamageDispatch::m_Instance;
		DamageDispatch::m_Instance = 0;
	}

	m_iaGameType = DefaultGameType;
	#ifdef _ICECAP
//	StopCAPAll ();
	#endif

	if (RunFromOtherAppEnterStoppingGameState)
		RunFromOtherAppEnterStoppingGameState();

// jcem - begin
    if (CTCL_IsConsoleX()) {
        if (!g_bCOOP) {
            // jcem : uncomment next line for every reset per game
            //    next line will reset RIO board every game - i.e. joystick center will be resetted wrong if correctly centered...
            //    if commented then only 1 center-detection will be processed when mw4.exe launched(every morning)...
            GeneralReset();
        CTCL_SendFile(g_SysTime, g_guidGameDatas, 2);
    }
    }
    g_MRF.Stopped(); // jcem
    g_RSF.Stopped(); // jcem
    if (CTCL_IsConsoleX()) {
        CTCL_SetGameStateAsIdle();
    }
    if (!g_bCOOP && CTCL_IsConsoleX()) {
        g_fGameEndScreenTimer = gos_GetElapsedTime() + g_fSecsMissionReport;
    } else {
#ifdef _DEBUG
		//g_fGameEndScreenTimer = gos_GetElapsedTime() + g_fSecsMissionReport;
#endif // _DEBUG
	}
// jcem - end
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::EnterRecyclingGameState(void* data)
{
// jcem - begin
        void _stdcall CTCL_DoStopMusic();
    CTCL_DoStopMusic();
    COOP_InputMode(false);

	if(MWGame::GetInstance())
        MWGame::GetInstance()->EarlyReactToEndMission();
sh_game_started = false;

    g_MRF.Stopping(); // jcem
    g_RSF.Stopping(); // jcem

    ClearTOC();
    // hyun begin
	RIO_StartStop (FALSE);
    // hyun end
    if (CTCL_IsConsoleX()) {
        CTCL_SetGameState(_EGS_Closing);
    }
// jcem - end

	if (serverFlag)
	{
		SendScore();
		SendStopGameMessage();
	}
	else
		SendPlayerLeavingMessage();


	#ifdef LAB_ONLY
	if ((SaveGameStats == true) &&
		(missionName != NULL))
	{
		SaveGameLog();
	}
	#endif

	waitingForRunMessage = false;

	Flag::ResetAllFlags();

	if(serverFlag) {
		currentGameNumber = 0;


		for (int i = 0; i < Maximum_Lancemates; i++)
		{
			ServerAdvertiser::RemovePlayerAll(i + 256, (char *)lancemateConnectionData[i].lancemateMech, true);
		}


		// ngLog addition
#if !defined(NO_LOG)
		if(networkingFlag) {
			MW4log_writeAllStats();
			MW4log_GameEnd(MW4GAME_END, "RecycleState");
		}
#endif // !defined(NO_LOG)

#if !defined(NO_MR)
		if (reviewPackets != NULL)
		{
			delete[] reviewPackets;
			reviewPackets = NULL;
		}
		totalReviewPackets = 0;

		for (i = 0; i < Maximum_Players; i++)
		{
			if (servedConnectionData[i].clientStreamingReview)
			{
				servedConnectionData[i].clientStreamingReview = false;
				Network::GetInstance()->SendNetMessage(i, CancelMissionReviewMessageID, NULL, true);
			}
		}

		NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();

		if (params->m_playMissionReview)
		{
			// save it off for play back.
			
			m_recordLog->StopRecordingLog();
			m_recordLog->SaveLog("lastgame.mr");
			

			DynamicMemoryStream header_stream;
			DynamicMemoryStream log_stream;
			
			m_recordLog->GetHeader(&header_stream);
			m_recordLog->GetDataLog(&log_stream);
			header_stream.Rewind();
			log_stream.Rewind();

			totalReviewPackets = (int)((Scalar)log_stream.GetBufferBytesUsed() / 3000.0f);
			if (totalReviewPackets * 3000 < log_stream.GetBufferBytesUsed())
			{
				totalReviewPackets += 1;
			}

			Verify((totalReviewPackets*3000) >= log_stream.GetBufferBytesUsed());

			// add in a spot for the headers
			++totalReviewPackets;


			//int totalReviewPackets;
			//DynamicMemoryStream *reviewPackets;
			reviewPackets = new DynamicMemoryStream[totalReviewPackets];
			reviewPackets[0].WriteBytes(header_stream.GetPointer(), header_stream.GetBufferBytesUsed());
			reviewPackets[0].Rewind();

			int bytes_remaining = log_stream.GetBufferBytesUsed();
			for (int i = 1; i < totalReviewPackets; ++i)
			{
				int bytes_to_write = 3000;
				Max_Clamp(bytes_to_write, bytes_remaining);
				bytes_remaining-=bytes_to_write;
				reviewPackets[i].WriteBytes(log_stream.GetPointer(), bytes_to_write);
				reviewPackets[i].Rewind();
				log_stream.AdvancePointer(bytes_to_write);
			}


			Verify(bytes_remaining == 0);
			Verify(log_stream.GetBytesRemaining() == 0);



			for (i = 0; i < Maximum_Players; i++)
			{
				if (servedConnectionData[i].clientConnected)
				{
					//SPEW(("jerryeds", "SEND : %d - MISSION REVIEW AVAILABLE", i));
					Network::GetInstance()->SendNetMessage(i, MissionReviewAvailableMessageID, NULL, true);
				}
			}

			


		}

		if (m_recordLog)
		{
			delete m_recordLog;
			m_recordLog = NULL;
		}
#endif // !defined(NO_MR)

	}





	scoreSaved = false;


	Application::EnterRecyclingGameState(data);

	if (missionName != NULL)
	{
		Check_Pointer(missionName);
		delete missionName;
		missionName = NULL;
	}


	ABL::ABLi_close ();

	Environment.DoGameLogic	= &MWApplication::DoShellLogic;

	MWApplication::GetInstance()->recycleTimerOn = false;

	// kill all the open resources except one...

	Check_Object(MW4Animation::AnimInstanceManager::Anim_Instance_Manager);
	MW4Animation::AnimInstanceManager::Anim_Instance_Manager->DeleteAnimations();


	ResourceManager::Instance->CloseAllButCore();
	delete gosFX::EffectLibrary::Instance;
	Verify(!gosFX::EffectLibrary::Instance);

	bool pause_up = false;
	if (MW4Shell::Instance->currentShellRunning == MW4Shell::InGameShellRunning)
		pause_up = true;

	MW4Shell::Instance->StopNetworkShellsExecute();
	MW4Shell::Instance->StopStatShell();
	MW4Shell::Instance->StopLoadingShell();

	if (pause_up)
		MW4Shell::Instance->EndAllScripts();


	Application::GetInstance()->UnpauseGame();

	NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
	if (params->m_runDedicated)
	{
		MW4Shell::Instance->StartNetworkServerExecute();
	}
	else
	{
        // jcem begin
        if (CTCL_IsConsoleX()) {
            MWApplication *app = MWApplication::GetInstance();

            if (g_bCOOP && app->networkingFlag) {
                app->m_nCamp_Stage = -4;
            }

			MW4Shell::Instance->StopNetworkShellsExecute();

			app->StopNetworking();
			app->GetLocalNetParams()->ResetParameters();
			app->GetServerNetParams()->ResetParameters();

            MW4Shell::Instance->StartMainShell();
        } else
        // jcem end
		    MW4Shell::Instance->StartNetworkScoreExecute();
	}
	
	if (DamageDispatch::m_Instance != 0)
	{
		delete DamageDispatch::m_Instance;
		DamageDispatch::m_Instance = 0;
	}

	m_iaGameType = DefaultGameType;

	if (RunFromOtherAppEnterRecyclingGameState)
		RunFromOtherAppEnterRecyclingGameState();
	
// jcem - begin
    if (CTCL_IsConsoleX()) {
                if (!g_bCOOP) {
            // jcem : uncomment next line for every reset per game
            //    next line will reset RIO board every game - i.e. joystick center will be resetted wrong if correctly centered...
            //    if commented then only 1 center-detection will be processed when mw4.exe launched(every morning)...
GeneralReset();
        CTCL_SendFile(g_SysTime, g_guidGameDatas, 2);
    }
    }
    g_MRF.Stopped(); // jcem
    g_RSF.Stopped(); // jcem

    if (CTCL_IsConsoleX()) {
        CTCL_SetGameStateAsIdle();
    }
    if (!g_bCOOP && CTCL_IsConsoleX()) {
        g_fGameEndScreenTimer = gos_GetElapsedTime() + g_fSecsMissionReport;
    } else {
#ifdef _DEBUG
		//g_fGameEndScreenTimer = gos_GetElapsedTime() + g_fSecsMissionReport;
#endif // _DEBUG
	}
// jcem - end
}

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

void MWApplication::EnterLoadingGameState(void* data)
{
// jcem - begin
    if (g_bCOOP && ((m_nCamp_Stage == 0) || (m_nCamp_Stage == 1))) {
        g_nCoinCount -= g_nCoinPerGame;
        if (g_nCoinCountTemp) {
            gosASSERT(g_nCoinCountTemp == g_nCoinPerGame);
            g_nCoinCountTemp = 0;
        }
        VehicleInterface::SetPreferredCameraPosition(0);
    }

	if (g_hVideo) {
		gosVideo_SetPlayMode(g_hVideo, gosVideo_Stop); // gosVideo_Stop
	}

    g_fGameEndScreenTimer = 0.0;
    g_MRF.Loading();
    g_RSF.Loading();

    ClearTOC();
    if (CTCL_IsConsoleX()) {
        CTCL_SetGameState(_EGS_Preparing);
    }
// jcem - end

	if (networkingFlag == true)
	{
		DamageDispatch::m_Instance = new DamageDispatch_Multiplayer;
	}
	else
	{
		DamageDispatch::m_Instance = new DamageDispatch_SinglePlayer;
	}


	if (serverFlag)
	{
		currentGameNumber = Random::GetInt();
	}


	waitingForRunMessage = false;
#if !defined(NO_MR)
	missionReviewAvailable = false;


	if (serverFlag)
	{
		NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
	
		if (params->m_playMissionReview)
		{
			m_recordLog = new MissionReview;
			m_recordLog->ReadyRecord();
		}

	}


	if (m_playLog)
	{
		delete m_playLog;
		m_playLog = NULL;
	}
#endif // !defined(NO_MR)

	//---------------------------------------------------------
	//Set up the ABL constants and load the mission script
	//---------------------------------------------------------
	//
	ABL::ABLi_init(767999, //AblSymbolTableHeapSize,
			  511999, //AblStackHeapSize,
			  307199, //AblCodeHeapSize,
			  20479, //AblRunTimeStackSize,
			  51199, //AblMaxCodeBlockSize,
			  200, //AblMaxRegisteredModules,
			  100, //AblMaxStaticVariables,
#if defined(LAB_ONLY)
				ABL_Debug_func,
				true,
				true,
				true
#else
				NULL,
				false,
				false,
				false
#endif
				);

	ABL::Debugger *fred = ABL::ABLi_getDebugger ();
	if (fred)
		fred->enable ();


	char filename[128];
	Str_Copy(filename, "content\\ablscripts\\miscfuncs.abl", sizeof(filename));
	/*int err = */ABL::ABLi_loadLibrary(filename, NULL,NULL,NULL);
//	gosASSERT (err >=0);

//	strcpy (filename,"content\\ABLScripts\\orders.abx");
//	ABL::ABLi_loadLibrary(filename, NULL, NULL,NULL,false);
//	strcpy (filename,"content\\ABLScripts\\miscfunc.abx");
//	ABL::ABLi_loadLibrary(filename, NULL, NULL,NULL,false);

	if (MW4Shell::Instance != NULL)
	{
		MW4Shell::Instance->StopNetworkShellsExecute();
		MW4Shell::Instance->StartLoadingShell(networkingFlag);
	}

	Application::EnterLoadingGameState(data);

	// load up the animations
	LoadAnimations();
	#ifdef _ICECAP
//	StopCAPAll ();
	#endif

	if (RunFromOtherAppEnterLoadingGameState)
		RunFromOtherAppEnterLoadingGameState();
    if (!g_bNoPlasma) {
        PLASMA_Do(0);
    }
    g_MRF.Loaded();
    g_RSF.Loaded();
}


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


void MWApplication::SaveScore()
{

	if (scoreSaved)
		return;


	scoreSaved = true;

	// let's clean up stuff before getting the scores...
	for (int i = 0; i < 32; i++)
	{
		if (MW4Shell::Instance->m_scoreNames[i] != NULL)
		{
			delete [] MW4Shell::Instance->m_scoreNames[i];
			MW4Shell::Instance->m_scoreNames[i] = NULL;
		}
	}
	if (MW4Shell::Instance->m_scoreMapName != NULL)
	{
		delete [] MW4Shell::Instance->m_scoreMapName;
		MW4Shell::Instance->m_scoreMapName = NULL;
	}
	MW4Shell::Instance->m_scoreCount = 0;
    MW4Shell::Instance->m_scorePlyrIndex = -1;
	MW4Shell::Instance->currentCycleNumber++;

	
	// copy the mission and scenario type and see if it is a team game or not
	if (serverFlag)
	{
		NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
		MW4Shell::Instance->m_scoreRuleType = params->m_ruleType;

		MW4Shell::Instance->m_scoreMapName = new char [256];
		Str_Copy(MW4Shell::Instance->m_scoreMapName, params->m_scenarioName, 256);

		MW4Shell::Instance->m_scoreTeamAllowed = params->m_teamAllowed;
	}
	else
	{
		NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetServerNetParams();
		MW4Shell::Instance->m_scoreRuleType = params->m_ruleType;

		MW4Shell::Instance->m_scoreMapName = new char [256];
		Str_Copy(MW4Shell::Instance->m_scoreMapName, params->m_scenarioName, 256);

		MW4Shell::Instance->m_scoreTeamAllowed = params->m_teamAllowed;
	}


	// copy the kills, deaths and custom scores
	// (assuming player maximum is smaller than 32 and team maximum is smaller than 8)
	MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());
	if (MW4Shell::Instance->m_scoreTeamAllowed)
	{
		// We have teams!
		for (int j = 0; j < Maximum_Teams; j++)
		{
			MW4Shell::Instance->m_scoreTeamCounts[j] = 0;

			if (TeamHasAnyPlayers(j))
			{
				MW4Shell::Instance->m_scoreTeamScores[j] = mission->m_BucketManager->FindBucketValue(CBucketManager::CUSTOM, - (j + 1));
				MW4Shell::Instance->m_scoreTeamKills[j] = mission->m_BucketManager->FindBucketValue(CBucketManager::KILLS, - (j + 1));
				MW4Shell::Instance->m_scoreTeamDeaths[j] = mission->m_BucketManager->FindBucketValue(CBucketManager::DEATHS, - (j + 1));			
	
				for (i = 0; i < Maximum_Players; i++)
				{	
					if (servedConnectionData[i].clientPlayer != NULL && servedConnectionData[i].clientPlayer->vehicle != NULL && servedConnectionData[i].pilotTeam == j)
					{
						Check_Object(servedConnectionData[i].clientPlayer);
						Check_Object(servedConnectionData[i].clientPlayer->vehicle);
			
						MW4Shell::Instance->m_scoreNames[MW4Shell::Instance->m_scoreCount] = new char [strlen(servedConnectionData[i].pilotName)+1];
						Str_Copy(MW4Shell::Instance->m_scoreNames[MW4Shell::Instance->m_scoreCount], servedConnectionData[i].pilotName, strlen(servedConnectionData[i].pilotName)+1);

						MW4Shell::Instance->m_scoreScores[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::CUSTOM, servedConnectionData[i].clientPlayer->vehicle->GetReplicatorID());
						MW4Shell::Instance->m_scoreKills[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::KILLS, servedConnectionData[i].clientPlayer->vehicle->GetReplicatorID());
						MW4Shell::Instance->m_scoreDeaths[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::DEATHS, servedConnectionData[i].clientPlayer->vehicle->GetReplicatorID());
                        MW4Shell::Instance->m_scorePlyrs[MW4Shell::Instance->m_scoreCount] = i;
			
						++MW4Shell::Instance->m_scoreCount;
						++MW4Shell::Instance->m_scoreTeamCounts[j];
					}
				}

				for (i = 0; i < Maximum_Lancemates; i++)
				{
					if (lancemateConnectionData[i].lancemateMech != NULL && lancemateConnectionData[i].lancemateConnected && lancemateConnectionData[i].lancemateVehicleAccepted && lancemateConnectionData[i].pilotTeam == j)
					{
						Check_Object(lancemateConnectionData[i].lancemateMech);
			
						MW4Shell::Instance->m_scoreNames[MW4Shell::Instance->m_scoreCount] = new char [strlen(lancemateConnectionData[i].lancemateName)+1];
						Str_Copy(MW4Shell::Instance->m_scoreNames[MW4Shell::Instance->m_scoreCount], lancemateConnectionData[i].lancemateName, strlen(lancemateConnectionData[i].lancemateName)+1);

						MW4Shell::Instance->m_scoreScores[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::CUSTOM, lancemateConnectionData[i].lancemateMech->GetReplicatorID());
						MW4Shell::Instance->m_scoreKills[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::KILLS, lancemateConnectionData[i].lancemateMech->GetReplicatorID());
						MW4Shell::Instance->m_scoreDeaths[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::DEATHS, lancemateConnectionData[i].lancemateMech->GetReplicatorID());
                        MW4Shell::Instance->m_scorePlyrs[MW4Shell::Instance->m_scoreCount] = -(i + 1); // lancemates...
			
						++MW4Shell::Instance->m_scoreCount;
						++MW4Shell::Instance->m_scoreTeamCounts[j];
					}
				}
		
				// let's do an insertion sort on the score
				char tmpName[1024];
				int tmpScore;
				int tmpKill;
				int tmpDeath;
                int tmpPlyr; // jcem
				int start = MW4Shell::Instance->m_scoreCount - MW4Shell::Instance->m_scoreTeamCounts[j];
				for (i = start; i < MW4Shell::Instance->m_scoreCount; i++)
				{
					int biggest = i;
					for (int k = i; k < MW4Shell::Instance->m_scoreCount; k++)
					{
						if (MW4Shell::Instance->m_scoreScores[biggest] < MW4Shell::Instance->m_scoreScores[k])
						{
							biggest = k;	
						}
					}

					// swap
					if (biggest != i)
					{
						Str_Copy(tmpName, MW4Shell::Instance->m_scoreNames[i], strlen(MW4Shell::Instance->m_scoreNames[i]) + 1);
						tmpScore = MW4Shell::Instance->m_scoreScores[i];
						tmpKill = MW4Shell::Instance->m_scoreKills[i];
						tmpDeath = MW4Shell::Instance->m_scoreDeaths[i];
                        tmpPlyr = MW4Shell::Instance->m_scorePlyrs[i];
	
						delete [] MW4Shell::Instance->m_scoreNames[i];
						MW4Shell::Instance->m_scoreNames[i] = new char [strlen(MW4Shell::Instance->m_scoreNames[biggest])+1];
						Str_Copy(MW4Shell::Instance->m_scoreNames[i], MW4Shell::Instance->m_scoreNames[biggest], strlen(MW4Shell::Instance->m_scoreNames[biggest]) + 1);
						MW4Shell::Instance->m_scoreScores[i] = MW4Shell::Instance->m_scoreScores[biggest];
						MW4Shell::Instance->m_scoreKills[i] = MW4Shell::Instance->m_scoreKills[biggest];
						MW4Shell::Instance->m_scoreDeaths[i] = MW4Shell::Instance->m_scoreDeaths[biggest];
                        MW4Shell::Instance->m_scorePlyrs[i] = MW4Shell::Instance->m_scorePlyrs[biggest];

						delete [] MW4Shell::Instance->m_scoreNames[biggest];
						MW4Shell::Instance->m_scoreNames[biggest] = new char [strlen(tmpName)+1];
						Str_Copy(MW4Shell::Instance->m_scoreNames[biggest], tmpName, strlen(tmpName) + 1);
						MW4Shell::Instance->m_scoreScores[biggest] = tmpScore;
						MW4Shell::Instance->m_scoreKills[biggest] = tmpKill;
						MW4Shell::Instance->m_scoreDeaths[biggest] = tmpDeath;
                        MW4Shell::Instance->m_scorePlyrs[biggest] = tmpPlyr;
					}
				}
			}
		}
	}
	else
	{
		// No team allowed
		for (i = 0; i < Maximum_Players; i++)
		{	
			if (servedConnectionData[i].clientPlayer != NULL && servedConnectionData[i].clientPlayer->vehicle != NULL)
			{
				Check_Object(servedConnectionData[i].clientPlayer);
				Check_Object(servedConnectionData[i].clientPlayer->vehicle);
                if (!servedConnectionData[i].clientPlayer->vehicle->IsDerivedFrom(Mech::DefaultData)) {
                    continue; // exclude cameraship for score... jcem
                }
		
				MW4Shell::Instance->m_scoreNames[MW4Shell::Instance->m_scoreCount] = new char [strlen(servedConnectionData[i].pilotName)+1];
				Str_Copy(MW4Shell::Instance->m_scoreNames[MW4Shell::Instance->m_scoreCount], servedConnectionData[i].pilotName, strlen(servedConnectionData[i].pilotName)+1);

				MW4Shell::Instance->m_scoreScores[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::CUSTOM, servedConnectionData[i].clientPlayer->vehicle->GetReplicatorID());
				MW4Shell::Instance->m_scoreKills[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::KILLS, servedConnectionData[i].clientPlayer->vehicle->GetReplicatorID());
				MW4Shell::Instance->m_scoreDeaths[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::DEATHS, servedConnectionData[i].clientPlayer->vehicle->GetReplicatorID());
                MW4Shell::Instance->m_scorePlyrs[MW4Shell::Instance->m_scoreCount] = i;
			
				++MW4Shell::Instance->m_scoreCount;
			}
		}

		for (i = 0; i < Maximum_Lancemates; i++)
		{
			if (lancemateConnectionData[i].lancemateMech != NULL && lancemateConnectionData[i].lancemateConnected && lancemateConnectionData[i].lancemateVehicleAccepted)
			{
				Check_Object(lancemateConnectionData[i].lancemateMech);
			
				MW4Shell::Instance->m_scoreNames[MW4Shell::Instance->m_scoreCount] = new char [strlen(lancemateConnectionData[i].lancemateName)+1];
				Str_Copy(MW4Shell::Instance->m_scoreNames[MW4Shell::Instance->m_scoreCount], lancemateConnectionData[i].lancemateName, strlen(lancemateConnectionData[i].lancemateName)+1);

				MW4Shell::Instance->m_scoreScores[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::CUSTOM, lancemateConnectionData[i].lancemateMech->GetReplicatorID());
				MW4Shell::Instance->m_scoreKills[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::KILLS, lancemateConnectionData[i].lancemateMech->GetReplicatorID());
				MW4Shell::Instance->m_scoreDeaths[MW4Shell::Instance->m_scoreCount] = mission->m_BucketManager->FindBucketValue(CBucketManager::DEATHS, lancemateConnectionData[i].lancemateMech->GetReplicatorID());
                MW4Shell::Instance->m_scorePlyrs[MW4Shell::Instance->m_scoreCount] = -(i + 1);
			
				++MW4Shell::Instance->m_scoreCount;
			}
		}

		// let's do an insertion sort on the score
		char tmpName[1024];
		int tmpScore;
		int tmpKill;
		int tmpDeath;
        int tmpPlyr; // jcem
		for (i = 0; i < MW4Shell::Instance->m_scoreCount; i++)
		{
			int biggest = i;
			for (int k = i; k < MW4Shell::Instance->m_scoreCount; k++)
			{
				if (MW4Shell::Instance->m_scoreScores[biggest] < MW4Shell::Instance->m_scoreScores[k])
				{
					biggest = k;
				}
			}

			// swap
			if (biggest != i)
			{
				Str_Copy(tmpName, MW4Shell::Instance->m_scoreNames[i], strlen(MW4Shell::Instance->m_scoreNames[i]) + 1);
				tmpScore = MW4Shell::Instance->m_scoreScores[i];
				tmpKill = MW4Shell::Instance->m_scoreKills[i];
				tmpDeath = MW4Shell::Instance->m_scoreDeaths[i];
                tmpPlyr = MW4Shell::Instance->m_scorePlyrs[i];

				delete [] MW4Shell::Instance->m_scoreNames[i];
				MW4Shell::Instance->m_scoreNames[i] = new char [strlen(MW4Shell::Instance->m_scoreNames[biggest])+1];
				Str_Copy(MW4Shell::Instance->m_scoreNames[i], MW4Shell::Instance->m_scoreNames[biggest], strlen(MW4Shell::Instance->m_scoreNames[biggest]) + 1);
				MW4Shell::Instance->m_scoreScores[i] = MW4Shell::Instance->m_scoreScores[biggest];
				MW4Shell::Instance->m_scoreKills[i] = MW4Shell::Instance->m_scoreKills[biggest];
				MW4Shell::Instance->m_scoreDeaths[i] = MW4Shell::Instance->m_scoreDeaths[biggest];
                MW4Shell::Instance->m_scorePlyrs[i] = MW4Shell::Instance->m_scorePlyrs[biggest];

				delete [] MW4Shell::Instance->m_scoreNames[biggest];
				MW4Shell::Instance->m_scoreNames[biggest] = new char [strlen(tmpName)+1];
				Str_Copy(MW4Shell::Instance->m_scoreNames[biggest], tmpName, strlen(tmpName) + 1);
				MW4Shell::Instance->m_scoreScores[biggest] = tmpScore;
				MW4Shell::Instance->m_scoreKills[biggest] = tmpKill;
				MW4Shell::Instance->m_scoreDeaths[biggest] = tmpDeath;
                MW4Shell::Instance->m_scorePlyrs[biggest] = tmpPlyr;
			}
		}
	}

    for (i = 0; i < MW4Shell::Instance->m_scoreCount; i++)
    {
        if (MW4Shell::Instance->m_scorePlyrs[i] == Connection::Local->GetID()) {
            MW4Shell::Instance->m_scorePlyrIndex = i;
            break;
		}
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


void MWApplication::LoadAnimations()
{
	// load up the animations
	MWObject *object;
	ChainIteratorOf<MWObject*> iterator(&animationScriptsLoadQue);

	while((object = iterator.GetCurrent()) != NULL)
	{
		object->LoadAnimationScripts();
		iterator.Remove();
	}

}

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

static char Transfer_Buffer[512];

const char* MWApplication::GetDecalName(int decal_index)
{
	
	MString full_name;

	if (decal_index < 64)
	{
		char file[5];

		sprintf(file,"%02d",decal_index);

		MString sub_file = file;
		full_name = "stockdecals\\decal_";
		full_name += sub_file;
	}
	else
	{
		DecalEntry *string = decalNames.Find(decal_index);
		if (string && string->decalName)
		{

			MString lower = string->decalName;
			lower.ToLower();


			if (strstr((char*)lower, "customdecals\\transfer\\"))
			{
				MString short_name = string->decalName;
				short_name.StripDirectory();
				short_name.StripExtension();

				full_name = "customdecals\\transfer\\";
				full_name += short_name;
			}
			else
			{
				MString short_name = string->decalName;
				short_name.StripDirectory();
				short_name.StripExtension();

				full_name = "customdecals\\";
				full_name += short_name;
			}
		}
		else
		{
			full_name = "stockdecals\\decal_00";
		}
	}

	strcpy(Transfer_Buffer, (char*)full_name);

	return Transfer_Buffer;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int
	MWApplication::AddDecal(const char *decal)
{

	//look for gaps or the end of the list...

	DecalEntry *decal_entry = FindDecal(decal);

	if (decal_entry)
	{
		decal_entry->refCount++;
		return decal_entry->index;
	}


	// start at 64
	int last_value = 64;

	if (IsStockDecalOnDisk(decal))
	{
		MString short_name = decal;
		short_name.StripDirectory();
		short_name.StripExtension();
		const char *number = short_name;
		number += 6;
		last_value = atoi(number);
		AddDecal(decal, last_value);
		return last_value;
	}

	Stuff::SortedChainIteratorOf<DecalEntry*, int> iterator(&decalNames);
	DecalEntry *string;
	while ((string = iterator.GetCurrent()) != NULL)
	{
		if(iterator.GetValue() > 64)
		{

			if (iterator.GetValue() > last_value + 1)
			{
				// add this...

				break;

			}
			else
			{
				last_value = iterator.GetValue();
			}
		}

		iterator.Next();
	}



	last_value += 1;

	//MString *new_string = new MString;
	//*new_string = decal;

	DecalEntry *new_decal_entry = new DecalEntry;
	new_decal_entry->decalName = decal;
	new_decal_entry->index = last_value;
	new_decal_entry->refCount++;
	decalNames.AddValue(new_decal_entry, last_value);

	return last_value;


}


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

void
	MWApplication::AddDecal(const char *decal, int index)
{

	DecalEntry *decal_entry = FindDecal(decal);

	if (decal_entry)
	{
		// we've already added it
		if (decal_entry->decalName == decal)
		{
			decal_entry->refCount++;
			return;
		}

		delete decal_entry;
	}

	DecalEntry *new_decal_entry = new DecalEntry;
	new_decal_entry->decalName = decal;
	new_decal_entry->index = index;
	new_decal_entry->refCount++;
	decalNames.AddValue(new_decal_entry, index);

}

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

DecalEntry*
	MWApplication::FindDecal(const char *decal)
{
	Stuff::SortedChainIteratorOf<DecalEntry*, int> iterator(&decalNames);
	DecalEntry *string;
	while ((string = iterator.ReadAndNext()) != NULL)
	{
		if (string->decalName == decal)
			return string;
	}

	return NULL;
}


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

void
	MWApplication::RemoveDecal(int decal_index)
{	

	if (decal_index == -1)
		return;

	DecalEntry *string = decalNames.Find(decal_index);

	if (string)
	{
		string->refCount--;

		if (string->refCount <= 0)
		{
			delete string;
		}
	}
}


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

bool
	MWApplication::IsDecalOnDisk(const char *decal)
{

	//MString decal_name;
	//decal_name = "Content\\Textures\\customdecals\\";
	//decal_name += decal;
//	decal_name += ".tga";


	if( gos_DoesFileExist(decal))
		return true;


	//decal_name = "Content\\Textures\\stockdecals\\";
	//decal_name += decal;
//	decal_name += ".tga";


//	if( gos_DoesFileExist(decal_name))
//		return true;


	return false;
}



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

bool
	MWApplication::IsStockDecalOnDisk(const char *decal)
{

	MString short_name = decal;
	short_name.StripDirectory();
	short_name.StripExtension();

	MString decal_name;
	decal_name = "Content\\Textures\\stockdecals\\";
	decal_name += short_name;
	decal_name += ".tga";

	if( gos_DoesFileExist(decal_name))
		return true;

	return false;
}

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


void MWApplication::StartGame()
{


	Verify(serverFlag);


	//
	//-------------------------------------------------------------
	// Build the network object.
	//-------------------------------------------------------------
	//
	gos_PushCurrentHeap(MechWarrior4::Heap);
//	ClearMechLab();

	if (Network::GetInstance() == NULL)
	{

		Verify(!Network::GetInstance());
		GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex);
		Register_Object(Network::GetInstance());
	}


	SendRequestConnectionMessage();
	
	if (!Application::GetInstance()->m_localMissionParameters->m_runDedicated)
		SendVehicleRequest();


	// technically we should wait for the server to accept our mech, but for right now it doesn't check anyway so
	// we just launch it...
	//Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), ReadyToLaunchMessageID, NULL, true);
	ReadyToLaunchMessageHandler(Connection::Server->GetID(), NULL);
	
	//
	//----------------------------------------
	// Time to launch the game
	//----------------------------------------
	//
	//

	Environment.DoGameLogic	= &MWApplication::DoGameLogic;

	if (DamageDispatch::m_Instance != 0)
	{
		delete DamageDispatch::m_Instance;
	}


	InputTrainer::GetInstance()->SetEnabled(InputTrainer::ALL,true);

	Stuff::MString mission_instance = MW4Shell::Instance->GetMissionInstanceFilename();
	MWApplication::GetInstance()->SetMissionName(mission_instance);
	MWApplication::GetInstance()->LaunchGame();

	gos_PopCurrentHeap();

}

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

void MWApplication::StartNetGame()
{

	Verify(serverFlag);

	servedConnectionData[1].clientReady = true;


	for (int i = 0; i < Maximum_Lancemates; i++)
	{
		if (lancemateConnectionData[i].lancemateConnected && !lancemateConnectionData[i].lancemateVehicleAccepted)
		{
			lancemateConnectionData[i].Disconnect();
		}
	}



	//
	//-------------------------------------------------------------
	// Build the network object.
	//-------------------------------------------------------------
	//
	gos_PushCurrentHeap(MechWarrior4::Heap);
//	ClearMechLab();

	Verify (Network::GetInstance() != NULL);

	if (!Application::GetInstance()->m_localMissionParameters->m_runDedicated)
	{
		SendVehicleRequest();
		Verify(servedConnectionData[1].clientVehicleAccepted);
		
		// release will squeak the server mech by in whatever he has choosen...
		// suck....but only alternative to crashing.
		servedConnectionData[1].clientVehicleAccepted = true;
		

	}

	// technically we should wait for the server to accept our mech, but for right now it doesn't check anyway so
	// we just launch it...
	//Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), ReadyToLaunchMessageID, NULL, true);
	ReadyToLaunchMessageHandler(Connection::Server->GetID(), NULL);
	
	//
	//----------------------------------------
	// Time to launch the game
	//----------------------------------------
	//
	//

	Environment.DoGameLogic	= &MWApplication::DoGameLogic;

	if (DamageDispatch::m_Instance != 0)
	{
		delete DamageDispatch::m_Instance;
	}



	InputTrainer::GetInstance()->SetEnabled(InputTrainer::ALL,true);


	//Stuff::MString mission_instance = MW4Shell::Instance->GetMissionInstanceFilename();

	MString stock_mission_name;
	stock_mission_name = "Resource\\Missions\\";
	stock_mission_name += MW4Shell::Instance->m_iaMissionName;
	stock_mission_name +=".mw4";

	MString custom_mission_name;
	custom_mission_name = "Resource\\UserMissions\\";
	custom_mission_name += MW4Shell::Instance->m_iaMissionName;
	custom_mission_name +=".mw4";

	TranslateMissionNameIfNecessary(stock_mission_name);
	TranslateMissionNameIfNecessary(custom_mission_name);

	TranslateMissionNameIfNecessary(stock_mission_name);
	TranslateMissionNameIfNecessary(custom_mission_name);


	MString mission_instance;
	if (gos_DoesFileExist(stock_mission_name))
	{
		mission_instance = "Missions\\";
		mission_instance += MW4Shell::Instance->m_iaMissionName;
		mission_instance += "\\";
		mission_instance += MW4Shell::Instance->m_iaMissionName;
		mission_instance += ".instance";
	}
	else if (gos_DoesFileExist(custom_mission_name))
	{
		mission_instance = "UserMissions\\";
		mission_instance += MW4Shell::Instance->m_iaMissionName;
		mission_instance += "\\";
		mission_instance += ".instance";
	}
	else
	{
		STOP(("This is impossible"));
	}


	MWApplication::GetInstance()->SetMissionName(mission_instance);
	MWApplication::GetInstance()->LaunchGame();

	gos_PopCurrentHeap();

}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int MWApplication::GetClientReady()
{
	if (Connection::Server != NULL && localVehicelAccepted == VEHICLE_ACCEPTED && haveNetworkMap)
	{
        if (servedConnectionData[Connection::Local->GetID()].clientReady)
            return 1;
    }

    return 0;
}

void MWApplication::SetClientReady()
{
	
	if (Connection::Server != NULL && localVehicelAccepted == VEHICLE_ACCEPTED && haveNetworkMap)
	{
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), ReadyToLaunchMessageID, NULL, true);
	}

}


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

void MWApplication::SetClientUnready()
{
	Scalar cur_time = (Scalar)gos_GetElapsedTime();
	if (servedConnectionData[Connection::Local->GetID()].clientReady && (cur_time-timeSinceLastUnready) > 2.0f)
	{
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), UnreadyLaunchMessageID, NULL, true);
		timeSinceLastUnready = cur_time;
	}
}

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


void MWApplication::ServerGameOver()
{

	// we are in the lobby waitin for a game so
	// go ahead and tell the server we have a vehicle.

//	if (applicationState->GetState() == ApplicationStateEngine::WaitingForGameState)
//		SendVehicleRequest();

}

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


void MWApplication::SendVehicleRequest()
{
    if (CTCL_IsConsole() || (g_nMR == 2))
        return;

	//
	//----------------------------------------------------------
	// Request our mech
	//----------------------------------------------------------
	//
	DynamicMemoryStream request_vehicle_stream;
	

	// write our decal...
	request_vehicle_stream.WriteBytes(&MW4Shell::Instance->m_skinPrefix, 1);


	
	const char *team_decal_note;
	const char *pilot_decal_note;

	int team_length;
	int pilot_length;
  if (!g_bCOOP && CTCL_IsConsoleX()) {
	const char *team_decal = "\0";
	const char *pilot_decal = "\0";

    SPlayerInfo& PI = g_aPlayerInfos[0];
    char szDecal[128];
    int nDecal;

    if ((0 <= PI.m_nDecal) && (PI.m_nDecal <= 63))
        nDecal = PI.m_nDecal;
    else
        nDecal = 0;

    sprintf(szDecal, "Content\\Textures\\Stockdecals\\decal_%02d.tga", nDecal);
    team_decal = szDecal;
    pilot_decal = szDecal;
	team_length = strlen(team_decal);
	request_vehicle_stream.WriteBytes(&team_length, 1);
	if (team_length > 0)
		request_vehicle_stream.WriteBytes(team_decal, team_length);

	pilot_length = strlen(pilot_decal);
	request_vehicle_stream.WriteBytes(&pilot_length, 1);
	if (pilot_length > 0)
		request_vehicle_stream.WriteBytes(pilot_decal, pilot_length);
  } else {
	const char *team_decal = "\0";
	const char *pilot_decal = "\0";

	NotationFile options_ini("options.ini", NotationFile::Standard, true);
	Page *page = options_ini.FindPage("Network Options");
	if (page)
	{
		if (page->GetEntry("PlayerIcon", &pilot_decal_note))
		{
			if (gos_DoesFileExist(pilot_decal_note))
			{

				// if not a stock decal check the size...
				bool valid = true;	

				if (!IsStockDecalOnDisk(pilot_decal_note))
				{
					if (gos_FileSize(pilot_decal_note) >= MaxDecalSize)
					{
						valid = false;
					}
				}
				
				Stuff::FileStream test(pilot_decal_note);

				if (!gos_CheckValidTGA((unsigned char *)test.GetPointer(), test.GetSize()))
				{
					valid = false;	
				}


				if (valid == true)
				{
					pilot_decal = pilot_decal_note;
				}

			}
		}


		if (page->GetEntry("TeamIcon", &team_decal_note))
		{
			if (gos_DoesFileExist(team_decal_note))
			{

				bool valid = true;	

				if (!IsStockDecalOnDisk(team_decal_note))
				{
					if (gos_FileSize(team_decal_note) >= MaxDecalSize)
					{
						valid = false;
					}
				}
				
				Stuff::FileStream test(team_decal_note);

				if (!gos_CheckValidTGA((unsigned char *)test.GetPointer(), test.GetSize()))
				{
					valid = false;	
				}


				if (valid == true)
				{
					team_decal = team_decal_note;
				}

			}
		}
	}
	team_length = strlen(team_decal);
	request_vehicle_stream.WriteBytes(&team_length, 1);
	if (team_length > 0)
		request_vehicle_stream.WriteBytes(team_decal, team_length);

	pilot_length = strlen(pilot_decal);
	request_vehicle_stream.WriteBytes(&pilot_length, 1);
	if (pilot_length > 0)
		request_vehicle_stream.WriteBytes(pilot_decal, pilot_length);
  }
	//
	//------------------------------------------------------------------------
	// Open up the resource files we are going to need to construct the player
	// message
	//------------------------------------------------------------------------
	//
	
	ResourceID vehicle_id = MW4Shell::Instance->m_mechID;
	if(vehicle_id == ResourceID::Null)
	{
		//
		//We are not in core and need to open the correct resource file
		//
		
		//ResourceManager::Instance->OpenResourceFile(
		//	MW4Shell::Instance->m_mechResourceFile,
		//	NULL,
		//	MechResourceFileID,
		//	VER_CONTENTVERSION,
		//	false,
		//	false
		//);

		vehicle_id.m_fileID = 10;
		vehicle_id.m_recordID = 1;
		
		// Write out the mechs custom resource file
		
		request_vehicle_stream.WriteBytes(&ResourceStreamType, 1);

		Stuff::FileStream file_stream(MW4Shell::Instance->m_mechResourceFile);

		request_vehicle_stream.AllocateBytes(file_stream.GetSize());
		file_stream.ReadBytes(request_vehicle_stream.GetPointer(), file_stream.GetSize());
		request_vehicle_stream.AdvancePointer(file_stream.GetSize());

	}
	else
	{
		// Write out the mechs stock resource_id
		request_vehicle_stream.WriteBytes(&ResourceIDType, 1);
		request_vehicle_stream << MW4Shell::Instance->m_mechID;
		
	}



	request_vehicle_stream.Rewind();
	request_vehicle_stream.AdvancePointer(3+team_length+pilot_length);
	MemoryStream sub_stream(request_vehicle_stream.GetPointer(), request_vehicle_stream.GetBytesRemaining());
	request_vehicle_stream.Rewind();


	
	// run it to make sure it doesn't crash us...
	sub_stream.Rewind();
	SetVehicleCreationMessage(Connection::Local->GetID(), &sub_stream);

	if (!serverFlag && servedConnectionData[Connection::Local->GetID()].pilotTeam != No_Team)
	{	
		if (servedConnectionData[Connection::Local->GetID()].clientVehicleAccepted) {
			NetMissionParameters::MWNetMissionParameters *params;
			params = GetServerNetParams();
			params->m_teamParams[servedConnectionData[Connection::Local->GetID()].pilotTeam].m_currentTotalTonnage -= 
				servedConnectionData[Connection::Local->GetID()].tonnage;
		}
	}

	VerifyPlayerVehicle(Connection::Local->GetID());
	
	localVehicelAccepted = VEHICLE_SUBMITTED;


	if (servedConnectionData[Connection::Local->GetID()].clientCustomResource != NULL)
	{
		delete servedConnectionData[Connection::Local->GetID()].clientCustomResource;
		servedConnectionData[Connection::Local->GetID()].clientCustomResource = NULL;

	}

	if (servedConnectionData[Connection::Local->GetID()].customResourceCRCFail)
	{
		localVehicelAccepted = VEHICLE_DENIED;
		lastErrorCount = 1;
		lastErrors[0] = UNKNOWN_BUILDERROR;
		return;
	}

	if (serverFlag)
	{
		RequestPlayerVehicleMessageHandler(Connection::Server->GetID(), &request_vehicle_stream);	
	}
	else
	{
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(Connection::Server->GetID(),request_vehicle_stream.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestPlayerVehicleMessageID, &request_vehicle_stream, true);
	}



}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWApplication::SendCampaignVehicleRequest()
{
	Check_Object(MWGame::GetInstance());

	localVehicelAccepted = VEHICLE_SUBMITTED;
	//
	//----------------------------------------------------------
	// Request our mech
	//----------------------------------------------------------
	//
	DynamicMemoryStream request_vehicle_stream;
	

	// write our decal...

	//This will change...it will come from somewhere else in the campaign
	request_vehicle_stream.WriteBytes(&MW4Shell::Instance->m_skinPrefix, 1);

	int team_length = strlen(MW4Shell::Instance->m_teamDecal);
	request_vehicle_stream.WriteBytes(&team_length, 1);
	if (team_length > 0)
		request_vehicle_stream.WriteBytes((char *)MW4Shell::Instance->m_teamDecal, team_length);

	int pilot_length = strlen(MW4Shell::Instance->m_pilotDecal);
	request_vehicle_stream.WriteBytes(&pilot_length, 1);
	if (pilot_length > 0)
		request_vehicle_stream.WriteBytes((char *)MW4Shell::Instance->m_pilotDecal, pilot_length);

#if 0
	request_vehicle_stream.WriteBytes(&ResourceStreamType, 1);

	MString vehicle_file;
	PilotPlug *player_plug = MWGame::GetInstance()->GetPilotLeader();
	Check_Object(player_plug);
	vehicle_file = player_plug->GetMechName();
	vehicle_file += ".mw4";
	Stuff::FileStream file_stream(vehicle_file);

	request_vehicle_stream.AllocateBytes(file_stream.GetSize());
	file_stream.ReadBytes(request_vehicle_stream.GetPointer(), file_stream.GetSize());
	request_vehicle_stream.AdvancePointer(file_stream.GetSize());
#endif

	request_vehicle_stream.WriteBytes(&ResourceIDType, 1);
	MechTablePlug *mech_plug = MWGame::GetInstance()->GetPilotLeader()->GetMechPlug();
	Check_Object(mech_plug);
	request_vehicle_stream << mech_plug->GetMechResourceID();

	//
	//-------------------------------------------------------------
	// We've requested our mech so we are ready
	// right now there is no double checking on the mech
	// status.  In the future we will send this and
	// wait for a reply before we send a ready message
	//-------------------------------------------------------------
	//

	request_vehicle_stream.Rewind();
	request_vehicle_stream.AdvancePointer(3+team_length+pilot_length);

	MemoryStream sub_stream(request_vehicle_stream.GetPointer(), request_vehicle_stream.GetBytesRemaining());
	if (VerifyPlayerVehicle(Connection::Local->GetID(), &sub_stream))
	{
		request_vehicle_stream.Rewind();

		if (serverFlag)
		{
			RequestPlayerVehicleMessageHandler(Connection::Server->GetID(), &request_vehicle_stream);
		}
		else
		{
			Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(Connection::Server->GetID(),request_vehicle_stream.GetBufferBytesUsed()*8);
			Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestPlayerVehicleMessageID, &request_vehicle_stream, true);
		}
	}
	// go ahead and kill the custom resource if we created one.
	
	if (servedConnectionData[Connection::Local->GetID()].clientCustomResource != NULL)
	{
		delete servedConnectionData[Connection::Local->GetID()].clientCustomResource;
		servedConnectionData[Connection::Local->GetID()].clientCustomResource = NULL;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWApplication::SendCampaignLancemateRequests()
{
	Check_Object(MWGame::GetInstance());

	PilotPlug *pilot_plug;
	SortedChainIteratorOf<PilotPlug *, int> iterator(&MWGame::GetInstance()->m_lancePilots);

	//Get past the leader and get to the real lances
	pilot_plug = iterator.ReadAndNext();
	Verify(pilot_plug);

	int count = 0;
	while((pilot_plug = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(pilot_plug);

		if((!pilot_plug->IsPlayer()) && (pilot_plug->IsValid()))
		{
			//Ok here is where we want to fill in the lancemate stream stuff!
			DynamicMemoryStream request_vehicle_stream;

			LancematePlug *lance_plug = pilot_plug->GetPilot();


			request_vehicle_stream.WriteBytes(&ResourceIDType, 1);
			MechTablePlug *mech_plug = pilot_plug->GetMechPlug();
			Check_Object(mech_plug);
			request_vehicle_stream << mech_plug->GetMechResourceID();

			request_vehicle_stream.Rewind();

			SetLancemateCreationMessage(count, &request_vehicle_stream);

			lancemateConnectionData[count].lancemateConnected = true;
			lancemateConnectionData[count].lancemateVehicleAccepted = true;
			Str_Copy(lancemateConnectionData[count].lancemateName, (char*)lance_plug->m_lancemateName, ELEMENTS(lancemateConnectionData[count].lancemateName));
			
			lancemateConnectionData[count].pilotSkill = lance_plug->PilotSkill();			
			lancemateConnectionData[count].gunnerySkill = lance_plug->GunnerySkill();
			lancemateConnectionData[count].eliteSkill = lance_plug->EliteSkill();
			lancemateConnectionData[count].minHeatSkill = lance_plug->MinHeatSkill();
			lancemateConnectionData[count].maxheatSkill = lance_plug->MaxHeatSkill();
			lancemateConnectionData[count].sensorSkill = lance_plug->SensorSkill();
			lancemateConnectionData[count].blindFightSkill = lance_plug->BlindFightingSkill();
			lancemateConnectionData[count].longRangeGunSkill = lance_plug->LongRangeGunnerySkill();
			lancemateConnectionData[count].shortRangeGunSkill = lance_plug->ShortRangeGunnerySkill();
			lancemateConnectionData[count].aiModel = lance_plug->m_lanceDataListID;
			
		}
		count ++; //This is outside because we want 0 to be the 0 in the lance list and 2 to be 2 if there
					//Are not valid ones...
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Entity::CreateMessage*
	MWApplication::MakeLancemateCreationMessage(int lancemate_index)
{
	
//	ObjectID drop_zone = 0;
//		lancemateCreateMessage[lancemate_index]->ReadBytes(&drop_zone,4);

//		Check_Object(EntityManager::Instance);
//		DropZone *zone = EntityManager::Instance->GetDropZone(drop_zone);
	DropZone *zone = NULL;

	if (zone == 0)
	{
		zone = EntityManager::GetInstance()->GetDropZone(NameTable::GetInstance()->FindID("PlayerStart"));

		if (zone == 0)
		{
			return (0);
		}
	}

	Check_Object(zone);

//	ObjectID object_id = NameTable::GetInstance()->AddEntry("lancemate1",NameTable::VehicleArray);


	MemoryStream *stream = GetLancemateCreationMessage(lancemate_index);
	BYTE message_type;

	stream->ReadBytes(&message_type, 1);

	if (message_type == ResourceIDType)
	{
		Mech::CreateMessage *mech_message = NULL;
		ResourceID mech_id;
		*stream >> mech_id;
		Resource mech_resource(mech_id);
		mech_message = Cast_Pointer(
			Mech::CreateMessage *, mech_resource.GetPointer());

		return mech_message;
	}
	else if (message_type == ResourceStreamType)
	{
	
		short resource_file_id;
	
		Mech::CreateMessage *mech_message = NULL;
		if (lancemateConnectionData[lancemate_index].lancemateCustomResource == NULL)
		{

			resource_file_id = ResourceManager::Instance->FindOpenResourceID();
			MemoryStream resource_pointer(stream->GetPointer(), stream->GetSize() - 1);

			
			char name[256];
			sprintf(&name[0], "CustomMechResource_%d", resource_file_id);

			lancemateConnectionData[lancemate_index].lancemateCustomResource = ResourceManager::Instance->OpenResourceFile(
				&resource_pointer,
				name,
				NULL,
				resource_file_id,
				VER_CONTENTVERSION,
				false
			);


			ResourceID mech_id(resource_file_id, 1);
			Resource mech_resource(mech_id);


			lancemateConnectionData[lancemate_index].customResourceCRCFail = false;
			ResourceID crc_res_id(resource_file_id, 3);
			Resource crc_resource(crc_res_id);

			if (!crc_resource.DoesResourceExist())
			{
				lancemateConnectionData[lancemate_index].customResourceCRCFail = true;
			}
			else
			{
				GUID comp_hash;

				crc_resource.ReadBytes(&comp_hash, 16);

				MD5_CTX resource_context;
				GUID resource_hash;
				unsigned char * buff=(unsigned char *) &resource_hash;

				mech_resource.Rewind();

				MD5Init(&resource_context);
				int key = 0xa1252388;
				MD5Update(&resource_context, (unsigned char *) &key, 4);
				MD5Update(&resource_context, (unsigned char *) mech_resource.GetPointer(), mech_resource.GetBytesRemaining());
				
				MD5Final(buff, &resource_context);

				if (resource_hash != comp_hash)
				{
					lancemateConnectionData[lancemate_index].customResourceCRCFail = true;
				}
			}



			Mech::CreateMessage *mech_message = Cast_Pointer(
				Mech::CreateMessage *, mech_resource.GetPointer());
			mech_message->subsystemStreamResourceID.m_fileID = resource_file_id;
	
		}
		else
		{
			resource_file_id = lancemateConnectionData[lancemate_index].lancemateCustomResource->GetFileID();

			ResourceID mech_id(resource_file_id, 1);
			
			Resource mech_resource(mech_id);
			Mech::CreateMessage *mech_message = Cast_Pointer(
				Mech::CreateMessage *, mech_resource.GetPointer());
			mech_message->subsystemStreamResourceID.m_fileID = resource_file_id;
		}

		ResourceID mech_id(resource_file_id, 1);
		
		Resource mech_resource(mech_id);
		mech_message = Cast_Pointer(
			Mech::CreateMessage *, mech_resource.GetPointer());


		return mech_message;
	}

	return NULL;
}


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

bool
	MWApplication::GetMechResourceID(int player_id, ResourceID &vehicle_id, MemoryStream *stream)
{
	Check_Object(stream);
	
	BYTE message_type;

	stream->ReadBytes(&message_type, 1);
	
	int custom = false;

	if (message_type == CreationMessageType)
	{
		int size = stream->GetSize() - 1;
		BYTE *message_buffer = new(MechWarrior4::Heap) BYTE[size];
		
		MemoryStream message_stream(message_buffer, size);
	
		message_stream.WriteBytes(stream->GetPointer(), size);
		message_stream.Rewind();

		MWPlayer::CreateMessage *create_message = Cast_Pointer(MWPlayer::CreateMessage *, message_stream.GetPointer());

		vehicle_id = create_message->vehicleResourceID;
	}
	else if (message_type == ResourceStreamType)
	{
		short resource_file_id;

		if (servedConnectionData[player_id].clientCustomResource == NULL)
		{

			resource_file_id = ResourceManager::Instance->FindOpenResourceID();
			MemoryStream resource_pointer(stream->GetPointer(), stream->GetSize() - 1);

			char name[256];
			sprintf(&name[0], "CustomMechResource_%d", resource_file_id);

			servedConnectionData[player_id].clientCustomResource = ResourceManager::Instance->OpenResourceFile(
				&resource_pointer,
				name,
				NULL,
				resource_file_id,
				VER_CONTENTVERSION,
				false,
				false
			);

			ResourceID mech_id(resource_file_id, 1);
			Resource mech_resource(mech_id);



			servedConnectionData[player_id].customResourceCRCFail = false;
			ResourceID crc_res_id(resource_file_id, 3);
			Resource crc_resource(crc_res_id);

			if (!crc_resource.DoesResourceExist())
			{
				servedConnectionData[player_id].customResourceCRCFail = true;
			}
			else
			{
				GUID comp_hash;

				crc_resource.ReadBytes(&comp_hash, 16);

				MD5_CTX resource_context;
				GUID resource_hash;
				unsigned char * buff=(unsigned char *) &resource_hash;

				mech_resource.Rewind();

				MD5Init(&resource_context);
				int key = 0xa1252388;
				MD5Update(&resource_context, (unsigned char *) &key, 4);
				MD5Update(&resource_context, (unsigned char *) mech_resource.GetPointer(), mech_resource.GetBytesRemaining());
				
				MD5Final(buff, &resource_context);

				if (resource_hash != comp_hash)
				{
					servedConnectionData[player_id].customResourceCRCFail = true;
				}
			}



			Mech::CreateMessage *mech_message = Cast_Pointer(
				Mech::CreateMessage *, mech_resource.GetPointer());
			mech_message->subsystemStreamResourceID.m_fileID = resource_file_id;

			//SPEW(("jerryeds", "GET - FILEID : %d",  servedConnectionData[player_id].clientCustomResource->GetFileID()));

		}
		else
		{
			resource_file_id = servedConnectionData[player_id].clientCustomResource->GetFileID();

			ResourceID mech_id(resource_file_id, 1);
			Resource mech_resource(mech_id);
			Mech::CreateMessage *mech_message = Cast_Pointer(
				Mech::CreateMessage *, mech_resource.GetPointer());
			mech_message->subsystemStreamResourceID.m_fileID = resource_file_id;


		}

		vehicle_id.m_fileID = resource_file_id;
		vehicle_id.m_recordID = 1;

		custom = true;
		

	}
	else if (message_type == ResourceIDType)
	{
		*stream >> vehicle_id;

		
	}
	else
	{
		STOP(("MWApplication::GetMechResourceID - BAD MAKE PLAYER MESSAGE"));
	}



	return custom;
}


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

bool
	MWApplication::GetLanceMateResourceID(int bot_id, ResourceID &vehicle_id, MemoryStream *stream)
{
	Check_Object(stream);
	
	BYTE message_type;

	stream->ReadBytes(&message_type, 1);
	
	int custom = false;

	if (message_type == CreationMessageType)
	{
		int size = stream->GetSize() - 1;
		BYTE *message_buffer = new(MechWarrior4::Heap) BYTE[size];
		
		MemoryStream message_stream(message_buffer, size);
	
		message_stream.WriteBytes(stream->GetPointer(), size);
		message_stream.Rewind();

		MWPlayer::CreateMessage *create_message = Cast_Pointer(MWPlayer::CreateMessage *, message_stream.GetPointer());

		vehicle_id = create_message->vehicleResourceID;
	}
	else if (message_type == ResourceStreamType)
	{
		short resource_file_id;

		if (lancemateConnectionData[bot_id].lancemateCustomResource == NULL)
		{

			resource_file_id = ResourceManager::Instance->FindOpenResourceID();
			MemoryStream resource_pointer(stream->GetPointer(), stream->GetSize() - 1);

			char name[256];
			sprintf(&name[0], "CustomMechResource_%d", resource_file_id);

			lancemateConnectionData[bot_id].lancemateCustomResource = ResourceManager::Instance->OpenResourceFile(
				&resource_pointer,
				name,
				NULL,
				resource_file_id,
				VER_CONTENTVERSION,
				false
			);

			ResourceID mech_id(resource_file_id, 1);
			Resource mech_resource(mech_id);



			lancemateConnectionData[bot_id].customResourceCRCFail = false;
			ResourceID crc_res_id(resource_file_id, 3);
			Resource crc_resource(crc_res_id);

			if (!crc_resource.DoesResourceExist())
			{
				lancemateConnectionData[bot_id].customResourceCRCFail = true;
			}
			else
			{
				GUID comp_hash;

				crc_resource.ReadBytes(&comp_hash, 16);

				MD5_CTX resource_context;
				GUID resource_hash;
				unsigned char * buff=(unsigned char *) &resource_hash;

				mech_resource.Rewind();

				MD5Init(&resource_context);
				int key = 0xa1252388;
				MD5Update(&resource_context, (unsigned char *) &key, 4);
				MD5Update(&resource_context, (unsigned char *) mech_resource.GetPointer(), mech_resource.GetBytesRemaining());
				
				MD5Final(buff, &resource_context);

				if (resource_hash != comp_hash)
				{
					lancemateConnectionData[bot_id].customResourceCRCFail = true;
				}
			}


			Mech::CreateMessage *mech_message = Cast_Pointer(
				Mech::CreateMessage *, mech_resource.GetPointer());
			mech_message->subsystemStreamResourceID.m_fileID = resource_file_id;

		}
		else
		{
			resource_file_id = lancemateConnectionData[bot_id].lancemateCustomResource->GetFileID();

			ResourceID mech_id(resource_file_id, 1);
			Resource mech_resource(mech_id);
			Mech::CreateMessage *mech_message = Cast_Pointer(
				Mech::CreateMessage *, mech_resource.GetPointer());
			mech_message->subsystemStreamResourceID.m_fileID = resource_file_id;

		}

		vehicle_id.m_fileID = resource_file_id;
		vehicle_id.m_recordID = 1;

		custom = true;
		

	}
	else if (message_type == ResourceIDType)
	{
		*stream >> vehicle_id;

		
	}
	else
	{
		STOP(("MWApplication::GetMechResourceID - BAD MAKE PLAYER MESSAGE"));
	}



	return custom;
}

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


Entity::CreateMessage *
	MWApplication::MakePlayerCreationMessage(int player_id)
{
	
	
	MWPlayer::CreateMessage *player_message = NULL;

	//
	//------------------------------------------------------------------------
	// Open up the resource files we are going to need to construct the player
	// message
	//------------------------------------------------------------------------
	//
	ResourceID vehicle_id;// = MW4Shell::Instance->m_mechID;
	

// for campaign skin - jcem
  if (IsCampCOOP()) {
		servedConnectionData[player_id].pilotSkins = MW4Shell::Instance->m_skinPrefix;

		MechTablePlug *mech_plug = MWGame::GetInstance()->GetPilotLeader()->GetMechPlug();
		Check_Object(mech_plug);
		vehicle_id = mech_plug->GetMechResourceID();
  } else {
// for campaign skin - jcem
	MemoryStream *stream = GetVehicleCreationmessage(player_id);

	Check_Object(stream);

	BYTE message_type;

	stream->ReadBytes(&message_type, 1);
	
	if (message_type == CreationMessageType)
	{
		int size = stream->GetSize() - 1;
		BYTE *message_buffer = new(MechWarrior4::Heap) BYTE[size];
		
		MemoryStream message_stream(message_buffer, size);
	
		message_stream.WriteBytes(stream->GetPointer(), size);
		message_stream.Rewind();

		Entity::CreateMessage *create_message = Cast_Pointer(Entity::CreateMessage *, message_stream.GetPointer());

		
		return create_message;
	}
	else if (message_type == ResourceStreamType)
	{
		short resource_file_id;

		if (servedConnectionData[player_id].clientCustomResource == NULL)
		{

			resource_file_id = ResourceManager::Instance->FindOpenResourceID();
			MemoryStream resource_pointer(stream->GetPointer(), stream->GetSize() - 1);

			char name[256];
			sprintf(&name[0], "CustomMechResource_%d", resource_file_id);

			servedConnectionData[player_id].clientCustomResource = ResourceManager::Instance->OpenResourceFile(
				&resource_pointer,
				name,
				NULL,
				resource_file_id,
				VER_CONTENTVERSION,
				false,
				false
			);

			ResourceID mech_id(resource_file_id, 1);
			Resource mech_resource(mech_id);


			servedConnectionData[player_id].customResourceCRCFail = false;
			ResourceID crc_res_id(resource_file_id, 3);
			Resource crc_resource(crc_res_id);

			if (!crc_resource.DoesResourceExist())
			{
				servedConnectionData[player_id].customResourceCRCFail = true;
			}
			else
			{
				GUID comp_hash;

				crc_resource.ReadBytes(&comp_hash, 16);

				MD5_CTX resource_context;
				GUID resource_hash;
				unsigned char * buff=(unsigned char *) &resource_hash;

				mech_resource.Rewind();

				MD5Init(&resource_context);
				int key = 0xa1252388;
				MD5Update(&resource_context, (unsigned char *) &key, 4);
				MD5Update(&resource_context, (unsigned char *) mech_resource.GetPointer(), mech_resource.GetBytesRemaining());
				
				MD5Final(buff, &resource_context);

				if (resource_hash != comp_hash)
				{
					servedConnectionData[player_id].customResourceCRCFail = true;
				}
			}



			Mech::CreateMessage *mech_message = Cast_Pointer(
				Mech::CreateMessage *, mech_resource.GetPointer());
			mech_message->subsystemStreamResourceID.m_fileID = resource_file_id;


			//SPEW(("jerryeds", "MAKE FILEID : %d",  servedConnectionData[player_id].clientCustomResource->GetFileID()));

		}
		else
		{
			resource_file_id = servedConnectionData[player_id].clientCustomResource->GetFileID();

			ResourceID mech_id(resource_file_id, 1);
			Resource mech_resource(mech_id);
			Mech::CreateMessage *mech_message = Cast_Pointer(
				Mech::CreateMessage *, mech_resource.GetPointer());
			mech_message->subsystemStreamResourceID.m_fileID = resource_file_id;
		}

		vehicle_id.m_fileID = resource_file_id;
		vehicle_id.m_recordID = 1;

		

	}
	else if (message_type == ResourceIDType)
	{
		*stream >> vehicle_id;
	}
	else
	{
		STOP(("MWApplication::MakePlayerCreationMessage - BAD MAKE PLAYER MESSAGE"));
	}
// for campaign skin - jcem
  }
// for campaign skin - jcem

	Resource vehicle_instance(vehicle_id);
	Resource interface_instance;
		
	if (DemoMode)
	{
		interface_instance.FindName("Interfaces\\SimpleInterface\\DemoSimpleInterface.instance");
	}
	else
	{
		interface_instance.FindName("Interfaces\\SimpleInterface\\SimpleInterface.instance");

	}

	Resource player_data("Players\\TestPlayer\\TestPlayer.data");

	player_message =
		new MWPlayer::CreateMessage(
			sizeof(MWPlayer::CreateMessage),
			DefaultEventPriority,
			MWPlayer::CreateMessage::DefaultFlags,
			MWPlayerClassID,
			0,
			player_data.GetResourceID(),
			LinearMatrix4D::Identity,
			0.0f,
			MWPlayer::ExecutionStateEngine::AlwaysExecuteState,
			-1,
			Entity::Player,
			vehicle_instance.GetResourceID(),
			interface_instance.GetResourceID(),
			NameTable::NullObjectID,
			servedConnectionData[player_id].pilotTeam,
			servedConnectionData[player_id].pilotSkins,
			servedConnectionData[player_id].teamDecals,
			servedConnectionData[player_id].pilotDecals
		);
	Check_Object(player_message);
	
		
	player_message->nameID =
		NameTableEntry::BuildObjectID(NameTable::PlayerArray, player_id-1);


	return player_message;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// FWang:: Hack for BRB 6/16/00

Stuff::MemoryStream *
	MWApplication::GetBRBVehicleCreationmessage(int player_id)
{
	
	Resource vehicle_instance("Content\\Vehicles\\ObservationVehicle\\ObservationVehicle.instance");	
	vehicle_instance.LoadData();
	MString interface_name = "Content\\games\\brb\\BRBInterface.instance";
	Resource interface_instance(interface_name);
	interface_instance.LoadData();
	Resource player_data("Players\\TestPlayer\\TestPlayer.data");
	player_data.LoadData();
	
	MWPlayer::CreateMessage *player_message =
		new MWPlayer::CreateMessage(
		sizeof(MWPlayer::CreateMessage),
		DefaultEventPriority,
		MWPlayer::CreateMessage::DefaultFlags,
		MWPlayerClassID,
		0,
		player_data.GetResourceID(),
		LinearMatrix4D::Identity,
		0.0f,
		MWPlayer::ExecutionStateEngine::AlwaysExecuteState,
		NameTableEntry::BuildObjectID(NameTable::PlayerArray, 0),
		Entity::Player,
		vehicle_instance.GetResourceID(),
		interface_instance.GetResourceID(),
		NameTable::NullObjectID,
		0,
		DefaultSkinPrefix,
		0,
		0
		);
	Check_Object(player_message);

	Stuff::DynamicMemoryStream* stream = new Stuff::DynamicMemoryStream;
	stream->AllocateBytes(player_message->messageLength+1);
	stream->WriteBytes(&CreationMessageType, 1);
	stream->WriteBytes(player_message, player_message->messageLength);
	stream->Rewind();
	delete player_message;
	return stream;
}

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


void
	MWApplication::LoadMissionResources(const char *mission_name)
{

	//
	//---------------------------------------------------------
	// Get the mission instance name and the resource file name
	//---------------------------------------------------------
	//
	Stuff::MString mission_instance = mission_name;
	Stuff::MString res_name = "Resource\\";
	res_name += mission_instance;
	char *p = __mbsrchr((char*)res_name, '\\');
	Check_Pointer(p);
	Str_Copy(p, ".mw4", res_name.GetLength() - (p - res_name));
	//
	// Since databases override the file hooking I have to specifically
	// make sure we do or don't need to translate the name at this point.
	//
	TranslateMissionNameIfNecessary(res_name);


	//
	//-------------------------------------------------------------------
	// Open up the resource file as a database and access record 0.  This
	// will contain the list of resource files this one is dependant on
	//-------------------------------------------------------------------
	//
	Stuff::DatabaseHandle *database =
		new Stuff::DatabaseHandle(res_name, true, VER_CONTENTVERSION);
	Stuff::RecordHandle record;
	record.m_databaseHandle = database;
	record.m_ID = ResourceID::BuildDependenciesRecordID;
	#if defined(_ARMOR)
		bool result =
	#endif
	record.FindID(true);
	Verify(result);

	//
	//-------------------------
	// Load up the core effects
	//-------------------------
	//
	Verify(!gosFX::EffectLibrary::Instance);
	gosFX::EffectLibrary::Instance = new ResourceEffectLibrary(false);
	Resource core_libraries("{effects}");
	Verify(core_libraries.DoesResourceExist());
	core_libraries.LoadData();
	ResourceID *lib = Cast_Pointer(ResourceID*, core_libraries.GetPointer());
	for (unsigned i=0; i<core_libraries.GetSize()/sizeof(ResourceID); ++i, ++lib)
	{
		Resource library(*lib);
		gosFX::EffectLibrary::Instance->Load(&library);
		library.UnloadData();
	}
	core_libraries.UnloadData();

	//
	//----------------------------------------------------------------------
	// The data points to a series of null terminated strings.  Step through
	// them until done
	//----------------------------------------------------------------------
	//
	const char* data = reinterpret_cast<const char*>(record.m_data);
	short level=MapResourceFileID;
	for (DWORD count=0; count<record.m_length; ++level)
	{
		if (!data[count])
			break;

		//
		//---------------------------
		// Load this resource file up
		//---------------------------
		//
		ResourceManager::Instance->OpenResourceFile(
			data+count,
			NULL,
			level,
			VER_CONTENTVERSION,
			false,
			false
		);

		//
		//----------------------------
		// Load up this file's effects
		//----------------------------
		//
		Resource libraries("{effects}");
		if (libraries.DoesResourceExist() && libraries.GetResourceID().GetFileID() == level)
		{
			libraries.LoadData();
			ResourceID *lib = Cast_Pointer(ResourceID*, libraries.GetPointer());
			for (unsigned i=0; i<libraries.GetSize()/sizeof(ResourceID); ++i, ++lib)
			{
				Resource library(*lib);
				gosFX::EffectLibrary::Instance->Load(&library);
				library.UnloadData();
			}
			libraries.UnloadData();
		}
			
		count += strlen(data+count)+1;
	}

	//
	//---------------------------------
	// Now create our own resource file
	//---------------------------------
	//
	ResourceManager::Instance->OpenResourceFile(database, level, false);
	Resource libraries("{effects}");
	if (libraries.DoesResourceExist() && libraries.GetResourceID().GetFileID() == level)
	{
		libraries.LoadData();
		ResourceID *lib = Cast_Pointer(ResourceID*, libraries.GetPointer());
		for (unsigned i=0; i<libraries.GetSize()/sizeof(ResourceID); ++i, ++lib)
		{
			Resource library(*lib);
			gosFX::EffectLibrary::Instance->Load(&library);
			library.UnloadData();
		}
		libraries.UnloadData();
	}
	gosFX::EffectLibrary::Instance->m_preloadEffects = true;
}

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


void MWApplication::StartCampaignGame()
{
	Check_Object(MWGame::GetInstance());

	if(MWGame::GetInstance()->HasLaunched())
		return;

	if (m_nCamp_Stage == 0) {
		m_nCamp_Kills = m_nCamp_Deaths = m_nCamp_Score = 0;
        m_nCamp_Time = m_nCamp_Mech = m_bCamp_Success = 0;
		if (g_bCOOP) { // ...
			m_nCamp_Stage++;
            VehicleInterface::SetPreferredCameraPosition(0);
		}
	} else {
        gosASSERT(0 < m_nCamp_Stage);
		m_nCamp_Stage++;
	}

	if (0 < m_nCamp_Stage) {
		Check_Object(MWGame::GetInstance());
        int nCamp = (m_nCamp_Stage - 1) % MAX_CAMP_STAGES;
		CampaignMissionPlug* mp = MWGame::GetInstance()->m_campaign->m_missions.GetNth(nCamp);

		MString name(mp->m_missionName);
		name.StripDirectory();
		name.StripExtension();

		FREEANDNULL(MW4Shell::Instance->m_iaMissionName);
		MW4Shell::Instance->m_iaMissionName = (char *)gos_Malloc(256);

		Str_Copy(MW4Shell::Instance->m_iaMissionName, (char *)name, 256);
		MWApplication::GetInstance()->m_currentMissionName = name;
	}

	MW4Shell::Instance->StartCampaignMission();
	//
	//--------------------------
	// Build the network object.
	//--------------------------
	//

	if (Network::GetInstance() == NULL)
	{
		Verify(!Network::GetInstance());
		GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex);
		Register_Object(Network::GetInstance());
	}


	//
	//-----------------
	// Request our mech
	//-----------------
	//
	SendRequestConnectionMessage();
	SendCampaignVehicleRequest();
	SendCampaignLancemateRequests();


	// technically we should wait for the server to accept our mech, but for right now it doesn't check anyway so
	// we just launch it...
	//Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), ReadyToLaunchMessageID, NULL, true);
	ReadyToLaunchMessageHandler(Connection::Server->GetID(), NULL);
	

	//
	//----------------------------------------
	// Now, create the message for the mission
	//----------------------------------------
	//
	
//	MWApplication::GetInstance()->SetMissionName(MWCampaign::Instance->GetNextMission());
	MWApplication::GetInstance()->SetMissionName(MW4Shell::Instance->GetMissionInstanceFilename());
	
	//
	//------------------------
	// Time to launch the game
	//------------------------
	//
	//

	Environment.DoGameLogic	= &MWApplication::DoGameLogic;
	MWApplication::GetInstance()->LaunchGame();

}

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

void MWApplication::StartUpDoShellLogic()
{

	// we have never run at all.  This is the very first time.


	if (MWApplication::GetInstance()->AutoLaunchClientGame)
	{
	
		MW4Shell::Instance->SelectLastUsedPilot();

		gos_InitializeNetworking();
		//gos_ConnectTCP(0,0);

		int verify_counter = 0;

		while( !gos_RunMainLoop() )
		{
	
	

			gos_JoinGame(MWApplication::NetGameName, MWApplication::NetPlayerName, MWApplication::NetPassword);
			DWORD networking = reinterpret_cast<DWORD>(gos_NetInformation(gos_Networking, 0));
			

			if (networking)
			{
				MWApplication::GetInstance()->networkingFlag = true;

#if defined(_ARMOR)
				DWORD server =
					reinterpret_cast<DWORD>(
						gos_NetInformation(gos_AmITheServer, 0)
					);
				Verify(!server);
#endif

				#if defined(LAB_ONLY)
						MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType;
						MWGameInfo::g_currentGameType = MWGameInfo::MultiClient;
				#endif


				MWApplication::GetInstance()->serverFlag = false;

				Verify(!Network::GetInstance());
				GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex);
				Register_Object(Network::GetInstance());

				MW4Shell::Instance->StartNetworkClientExecute();
				Environment.DoGameLogic = &MWApplication::DoShellLogic;
				break;
				
			}

			verify_counter++;

			if (verify_counter == 50000)
			{
#if defined(LAB_ONLY)
				PAUSE(("Can not find game %s, continue searching?", MWApplication::NetGameName));
#endif
				verify_counter = 0;
			}
			
		}

	}
	else if (MWApplication::GetInstance()->AutoLaunchServerGame)
	{
		MWApplication::GetInstance()->LoadServerOptions();
		MW4Shell::Instance->SelectLastUsedPilot();

		gos_InitializeNetworking();
		//gos_ConnectTCP(0,0);
		PrepareDefaultServerAdvertisers();

		Mech4CreateGame(MWApplication::NetGameName, MWApplication::NetPlayerName, MWApplication::NetPassword);
		DWORD networking = reinterpret_cast<DWORD>(gos_NetInformation(gos_Networking, 0));
		MWApplication::GetInstance()->networkingFlag = (networking)?true:false;

		NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
		Str_Copy(params->m_serverName, MWApplication::NetGameName, 256);
		Str_Copy(params->m_serverIP, LocalIPAddress, 256);


		if (MWApplication::GetInstance()->networkingFlag)
		{
#if defined(_ARMOR)
			DWORD server =
				reinterpret_cast<DWORD>(
					gos_NetInformation(gos_AmITheServer, 0)
				);
			Verify(server);
#endif

			MWApplication::GetInstance()->serverFlag = true;

			#if defined(LAB_ONLY)
				MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType;
				MWGameInfo::g_currentGameType = MWGameInfo::MultiServer;
			#endif


			Verify(!Network::GetInstance());
			GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex);
			Register_Object(Network::GetInstance());
			

			MWApplication::GetInstance()->SendRequestConnectionMessage();
			MW4Shell::Instance->StartNetworkServerExecute();
			Environment.DoGameLogic = &MWApplication::DoShellLogic;
			MW4Shell::Instance->shellStart = MW4Shell::MultiplayerShellStart;
		}
		else
		{
			STOP(("FAILED TO CREATE MULTIPLAYER GAME"));
		}

	}
	else if (MWApplication::GetInstance()->GameFile != NULL)
	{
		Verify(!Network::GetInstance());
		GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex);
		Register_Object(Network::GetInstance());

		//
		//-----------------------------------------------
		// Now create a load game and send it to the game
		//-----------------------------------------------
		//

		MWApplication::GetInstance()->SendRequestConnectionMessage();

		MWApplication::GetInstance()->ConstructEgg(MWApplication::GetInstance()->GameFile);
		Environment.DoGameLogic	= &MWApplication::DoGameLogic;
		MWApplication::GetInstance()->LaunchGame();

	}
	else if (MWApplication::RunFromLobby)
	{
		MW4Shell::Instance->SelectLastUsedPilot();

		if (MW4Shell::Instance && MW4Shell::Instance->m_optionsObject)
			Environment.defaultPlayerName = MW4Shell::Instance->m_optionsObject->m_playerName;
		gos_NetCheckLobby();
		DWORD networking = reinterpret_cast<DWORD>(gos_NetInformation(gos_Networking, 0));
		MWApplication::GetInstance()->networkingFlag = (networking)?true:false;

		if (MWApplication::GetInstance()->networkingFlag)
		{
			DWORD server =
				reinterpret_cast<DWORD>(
					gos_NetInformation(gos_AmITheServer, 0)
				);
			MWApplication::GetInstance()->serverFlag = (server)?true:false;


			if (Network::GetInstance() == NULL)
			{
				Verify(!Network::GetInstance());
				GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex);
				Register_Object(Network::GetInstance());
			}



			if (MWApplication::GetInstance()->serverFlag)
			{
				#if defined(LAB_ONLY)
					MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType;
					MWGameInfo::g_currentGameType = MWGameInfo::MultiServer;
				#endif

				MWApplication::GetInstance()->LoadServerOptions();
				MWApplication::GetInstance()->SendRequestConnectionMessage();
				MW4Shell::Instance->StartNetworkServerExecute();
			}
			else
			{
				#if defined(LAB_ONLY)
					MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType;
					MWGameInfo::g_currentGameType = MWGameInfo::MultiClient;
				#endif

				MWApplication *app = MWApplication::GetInstance();

				app->GetLocalNetParams()->ResetParameters();
				app->GetServerNetParams()->ResetParameters();
				


				MW4Shell::Instance->StartNetworkClientExecute();
			}

			Environment.DoGameLogic = &MWApplication::DoShellLogic;
		}
		else
		{
			//lobby failed...
			MW4Shell::Instance->StartMainShell();
			Environment.DoGameLogic = &MWApplication::DoShellLogic;
		}
	}
	else
	{
		MW4Shell::Instance->shellStart = MW4Shell::MainShellStart;
		MW4Shell::Instance->StartMainShell();
		Environment.DoGameLogic = &MWApplication::DoShellLogic;
	}

	
}



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

int diff_limiter = 0;

void MWApplication::DoShellLogic()
{
	MWApplication *app = MWApplication::GetInstance();

	if (MWApplication::GetInstance()->Win32DedicatedServer) {
		MWApplication::DoGameLogic();
		return;
	}

	if(MechLab::Instance)
	{
		MechLab::Instance->Execute();
	}

	if (MechLab::Instance || (app->networkingFlag&&app->GetApplicationState() == ApplicationStateEngine::WaitingForGameState))
	{
		diff_limiter++;
		if (diff_limiter > 3)
		{
			app->memoryDiffKiller.MoveItAndShakeIt();
			diff_limiter = 0;
		}
	}



	if(MWCampaign::Instance)
	{
		MWCampaign::Instance->m_movieManager->Execute();
	}

	if (MW4Shell::Instance != 0)
	{
		if (MW4Shell::Instance->currentShellRunning == MW4Shell::NoShellRunning)
		{
            if (CTCL_IsConsoleX()) {
                if (app->networkExitCode != MWApplication::NoExitCode) {
                    app->networkExitCode = MWApplication::NoExitCode;
                    if (g_bCOOP) {
                        g_InviteCOOP.m_pParent = NULL;
                        g_InviteCOOP.Clear();
                    }
                }
                MW4Shell::Instance->shellStart = MW4Shell::MainShellStart;
                MW4Shell::Instance->StartMainShell();
            } else {
			if (app->networkExitCode != MWApplication::NoExitCode)
			{
				
				MW4Shell::Instance->StartNetworkErrorExecuteModal();
				MW4Shell::Instance->shellStart = MW4Shell::MultiplayerShellStart;
				app->networkExitCode = MWApplication::NoExitCode;
			}

			if (MW4Shell::Instance->shellStart == MW4Shell::MultiplayerShellStart)
				MW4Shell::Instance->StartNetworkStartupScreen();
			else
				MW4Shell::Instance->StartMainShell();
            }
		}
		else
		{
			
			NetMissionParameters::MWNetMissionParameters *params = app->GetLocalNetParams();
			if (MW4Shell::Instance->currentShellRunning == MW4Shell::NetServerShellRunning)
			{
				if (params->m_runDedicated)
				{
					if (!app->recycleTimerOn && params->m_serverRecycle)
					{
						app->recycleTimerOn = true;
						app->recycleStartTime = gos_GetElapsedTime();
					}
					else if (app->recycleTimerOn && !params->m_serverRecycle)
					{
						app->recycleTimerOn = false;
					}
		
					if (app->recycleTimerOn)
					{
						if ((gos_GetElapsedTime() - app->recycleStartTime) > params->m_recycleDelay)
						{
							#if defined(LAB_ONLY)
								MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType;
								MWGameInfo::g_currentGameType = MWGameInfo::MultiServer;
							#endif
							
							app->StartNetGame();
							app->recycleTimerOn = false;
							MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
						}
					}
				}
			}
			else
			{
				app->recycleTimerOn = false;
			}
			

			// we are running a shell...
			
			// see if we have a command....

            if ((MW4Shell::Instance->shellCommand == MW4Shell::StartSinglePlayerGameCommand) && g_bMRTest) {
                MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
                if (g_MRF.LoadDefaultMR()) {
                g_MRF.DoReplay();
                }
            } else
			if (MW4Shell::Instance->shellCommand != MW4Shell::NoShellCommand)
			{
				
				if (MW4Shell::Instance->shellCommand != MW4Shell::DisconnectCommand)
					MW4Shell::Instance->currentShellRunning = MW4Shell::NoShellRunning;

				switch(MW4Shell::Instance->shellCommand)
				{
				
				case MW4Shell::ExitToWindowsShellCommand:
					gos_TerminateApplication();
					break;

				case MW4Shell::StartSinglePlayerGameCommand:
				{
					#if defined(LAB_ONLY)
						MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType;
						MWGameInfo::g_currentGameType = MWGameInfo::Instant;
					#endif
					#ifdef _ICECAP
//					StartCAPAll ();
					#endif

					HeatManager::g_OverrideHeatOption = false;
					switch (MW4Shell::Instance->ia_gameType)
					{
						case IA_WAVEBATTLE:
						{	
							app->InitializeWaveGame(
								MW4Shell::Instance->m_waves,
								MW4Shell::Instance->m_botsPerWave,
								MW4Shell::Instance->m_lancePerWave,
								MW4Shell::Instance->m_playerLives
							);
							break;
						}
						case IA_TRAININGMISSION:
						{
							app->InitializeTrainingMission();
							HeatManager::g_OverrideHeatOption = true;
							break;
						}
					}
					app->StartGame();

					MString s(MWApplication::GetInstance()->missionName);
					s.ToLower();
					if (s == "missions\\training01\\training01.instance")
					{
						HeatManager::g_OverrideHeatOption = true;
					}
					else
					{
						HeatManager::g_OverrideHeatOption = false;
					}

					MW4Shell::Instance->shellStart = MW4Shell::InstantActionShellStart;
					
					break;
				}
				case MW4Shell::StartCampaignGameCommand:
					#if defined(LAB_ONLY)
						MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType;
						MWGameInfo::g_currentGameType = MWGameInfo::Campaign;
					#endif

					MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
					app->StartCampaignGame();					
					MW4Shell::Instance->shellStart = MW4Shell::CampaignShellStart;

					break;

				case MW4Shell::StartNetworkShellsCommand:
					
					// start the network stuff...

					MW4Shell::Instance->EndAllScripts();

					MW4Shell::Instance->StartNetworkStartupScreen();
					MW4Shell::Instance->shellStart = MW4Shell::MainShellStart;
                    // jcem begin
                    if (g_bCOOP) {
                        if (app->m_nCamp_Stage < 0) {
                            if (app->m_nCamp_Stage == -1) {
                                g_nCoinCount += g_nCoinPerGame;
                                g_nCoinCountTemp += g_nCoinPerGame;
                                // from SingleGame...
                            }
                            app->m_nCamp_Stage = 0;

                            g_bIsServer = 0;
                            CTCL_RandomizeGameData(-1);

                            CTCL_DoJoinGame();
                        } else {
                            g_bIsServer = 1;
                            CTCL_RandomizeGameData(+1);

                            CTCL_DoCreateGame();
                        }
                    } else if (CTCL_IsConsole()) {
                        extern int __stdcall SetGameNameDefault( void * instance, int args, void * arg[]);
                        extern int __stdcall SetPlayerNameDefault( void * instance, int args, void * arg[]);

		                SetGameNameDefault(NULL, 0, NULL);
		                SetPlayerNameDefault(NULL, 0, NULL);
                        goto skip_hostsetup;
                    }
                    // jcem end

					break;


				case MW4Shell::EndNetworkShellsCommand:
skip_hostsetup:
					gos_NetDoneStartGame();

					// end the networking stuff
					DWORD networking;

                    if (CTCL_IsConsole()) {
                        app->networkingFlag = true;
                    } else {
					networking = reinterpret_cast<DWORD>(gos_NetInformation(gos_Networking, 0));
					app->networkingFlag = (networking)?true:false;
                    }
					
					if (app->networkingFlag)
					{
                        if (CTCL_IsConsole()) {
                            app->serverFlag = true;
                        } else {
						DWORD server;
                        
                        server = reinterpret_cast<DWORD>(gos_NetInformation(gos_AmITheServer, 0));
						app->serverFlag = (server)?true:false;
                        }

						if (Network::GetInstance() == NULL)
						{
							Verify(!Network::GetInstance());
							GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex);
							Register_Object(Network::GetInstance());
						}

						if (app->serverFlag)
						{
							// save the options that were set
							app->SaveServerOptions();

							#if defined(LAB_ONLY)
								MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType;
								MWGameInfo::g_currentGameType = MWGameInfo::MultiServer;
							#endif

							//app->LoadServerOptions();
							app->SendRequestConnectionMessage();
							MW4Shell::Instance->StartNetworkServerExecute();
						}
						else
						{
							app->GetLocalNetParams()->ResetParameters();
							app->GetServerNetParams()->ResetParameters();
							
							#if defined(LAB_ONLY)
								MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType;
								MWGameInfo::g_currentGameType = MWGameInfo::MultiClient;
							#endif

							MW4Shell::Instance->StartNetworkClientExecute();
						}
					}
					else
					{
						gos_NetEndGame();
						app->GetLocalNetParams()->ResetParameters();
						app->GetServerNetParams()->ResetParameters();
						MW4Shell::Instance->StartMainShell();
					}

					break;

				case MW4Shell::StartNetworkGameCommand:
					app->StartNetGame();
					break;

				case MW4Shell::DisconnectCommand:
                    // jcem begin
                  if (CTCL_IsConsoleX()) {
					MW4Shell::Instance->StopPauseShellExecute();
					Application::GetInstance()->QueStopGame();
					MW4Shell::Instance->shellStart = MW4Shell::MainShellStart;
                  } else {
                    // jcem end
					// ngLog addition
#if !defined(NO_LOG)
					if(app->serverFlag && app->networkingFlag) {
						MW4log_writeAllStats();
						MW4log_GameEnd(MW4GAME_END, "ServerDisconnect");
					}
#endif // !defined(NO_LOG)
					// Now Disconnect could be called before game hits running state
					// When user cancels out from "Connection is being established" screen
					//Verify(Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState);
					if (MW4Shell::Instance->currentShellRunning == MW4Shell::StatShellRunning)
					{
						MW4Shell::Instance->StopStatShell();
				}

					MW4Shell::Instance->currentShellRunning = MW4Shell::NoShellRunning;
					MW4Shell::Instance->StopPauseShellExecute();
					MW4Shell::Instance->StopNetworkShellsExecute();
					Application::GetInstance()->StopNetworking();
					app->GetLocalNetParams()->ResetParameters();
					app->GetServerNetParams()->ResetParameters();
					Application::GetInstance()->QueStopGame();
					MW4Shell::Instance->shellStart = MW4Shell::MultiplayerShellStart;
                    }
					break;

				case MW4Shell::DisconnectLobbyCommand:
					MW4Shell::Instance->StopNetworkShellsExecute();
					Application::GetInstance()->StopNetworking();
					app->GetLocalNetParams()->ResetParameters();
					app->GetServerNetParams()->ResetParameters();
                    // jcem begin
                    if (CTCL_IsConsole() || g_bCOOP) {
                        if (g_bCOOP) {
                            if (g_nCoinCountTemp) {
                                g_nCoinCount -= g_nCoinCountTemp;
                                g_nCoinCountTemp = 0;
                            }
                        }
                        MW4Shell::Instance->StartMainShell();
                    } else
                    // jcem end
					MW4Shell::Instance->StartNetworkStartupScreen();

					break;

				case MW4Shell::ExitMissionCommand:
					Verify(Application::GetInstance()->GetApplicationState() == ApplicationStateEngine::RunningGameState);
					MW4Shell::Instance->StopPauseShellExecute();
					Application::GetInstance()->QueStopGame();
					MW4Shell::Instance->shellStart = MW4Shell::MainShellStart;
					break;

				case MW4Shell::ResumeMissionCommand:
					// not sure...
					
					// unpause application...
					MW4Shell::Instance->StopPauseShellExecute();
					Environment.DoGameLogic	= &MWApplication::DoGameLogic;

					if (!Application::GetInstance()->networkingFlag)
						Application::GetInstance()->UnpauseGame();

					if (VehicleInterface::GetInstance())
					{
						VehicleInterface::GetInstance()->fireBlocked = false;
					}
					if (ControlsManager::Instance)
					{
						ControlsManager::Instance->m_IgnoreCommands = false;
					}

					break;

				case MW4Shell::ExitNetworkShellCommand:


					MW4Shell::Instance->StopNetworkShellsExecute();
					Application::GetInstance()->StopNetworking();
					app->GetLocalNetParams()->ResetParameters();
					app->GetServerNetParams()->ResetParameters();
					MW4Shell::Instance->StartMainShell();

					break;
			
				case MW4Shell::ReturnNetworkLobbyCommand:
					Verify(Network::GetInstance() != NULL);
					Verify(app->networkingFlag);

					MW4Shell::Instance->StopNetworkShellsExecute();

					if (app->serverFlag)
					{
						MW4Shell::Instance->StartNetworkServerExecute();
					}
					else
					{
						MW4Shell::Instance->StartNetworkClientExecute();
					}

#if !defined(NO_MR)
					if (app->playingMissionReview)
					{
						Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), CancelMissionReviewMessageID, NULL, true);
						app->playingMissionReview = false;
						NMissionReview::KillMissionReviewDisplay ();
					}
#endif // !defined(NO_MR)

					break;


				case MW4Shell::StartMissionReviewCommand:
					Verify(Network::GetInstance() != NULL);
					Verify(app->networkingFlag);

#if !defined(NO_MR)
					if (app->missionReviewAvailable)
					{
						MW4Shell::Instance->StopNetworkShellsExecute();
						MW4Shell::Instance->StartNetworkMissionReviewExecute();
						app->m_playLog = new MissionReview;
						app->m_playLog->StartLogBuffer();
						app->playingMissionReview = true;

						if (app->serverFlag)
						{
							app->m_playLog->LoadLog("lastgame.mr");						
						}
						else
						{
							Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestMissionReviewMessageID, NULL, true);
						}
						NMissionReview::InitMissionReviewDisplay ();
					}
#endif // !defined(NO_MR)

					break;

				case MW4Shell::SetPauseOptionResCommand:
					gos_SetScreenMode(800,600,Environment.bitDepth,Environment.FullScreenDevice);

					// Start the options screen
					MW4Shell::Instance->StartPauseOptionsShellExecute();
					MW4Shell::Instance->currentShellRunning = MW4Shell::InGameShellRunning;
					MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
					break;

				case MW4Shell::UnsetPauseOptionResCommand:
					gos_SetScreenMode(s_ScreenWidth, s_ScreenHeight,Environment.bitDepth,Environment.FullScreenDevice);

					// Stop the options screen
					MW4Shell::Instance->StopPauseOptionsShellExecute();
					MW4Shell::Instance->currentShellRunning = MW4Shell::InGameShellRunning;
					MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
					break;
				}

				MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
			}

		}
	}
    if (!g_bNoPlasma) {
        static s_nStaticFrame_Plasma = 0;
        if (++s_nStaticFrame_Plasma == 60) {
            s_nStaticFrame_Plasma = 0;
            PLASMA_Do(9);
        }
    }

	MWApplication::DoGameLogic();
}


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

__int64 MWApplication::CalculateExecutableDateCRC()
{
	MString path_name;
	#if defined(_DEBUG)
		path_name = "binaries\\mw4\\mw4_dbg.exe";
	#elif defined(_ARMOR)
		path_name = "binaries\\mw4\\mw4_arm.exe";
	#elif defined(LAB_ONLY)
		path_name = "binaries\\mw4\\mw4_prf.exe";
	#else
		path_name = "binaries\\mw4\\mw4_rel.exe";
	#endif
	
	
	return gos_FileTimeStamp(path_name);
	
	
}	

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

__int64 MWApplication::CalculateExecutableCRC()
{

	return 0;

#if 0
	MString path_name;
	#if defined(_DEBUG)
		path_name = "binaries\\mw4\\mw4_dbg.exe";
	#elif defined(_ARMOR)
		path_name = "binaries\\mw4\\mw4_arm.exe";
	#elif defined(LAB_ONLY)
		path_name = "binaries\\mw4\\mw4_prf.exe";
	#else
		path_name = "binaries\\mw4\\mw4_rel.exe";
	#endif
	
	FileStream stream(path_name);
	
	__int64 acumulator = 0;
	__int64 total_crc = 0;
	size_t acumulator_size = 0;


	while (stream.GetBytesRemaining() > 0)
	{
		if (stream.GetBytesRemaining() == 1)
		{
			BYTE buffer = 0;
			stream.ReadBytes(&buffer, 1);
			acumulator += buffer;
			acumulator_size += 1;
		}
		else
		{
			WORD buffer = 0;
			stream.ReadBytes(&buffer, 2);
			acumulator += buffer;
			acumulator_size += 2;
		}

		if (acumulator_size > 500000)
		{
			total_crc = total_crc ^ acumulator;
			acumulator = 0;
			acumulator_size = 0;
		}

	}

	if (acumulator_size)
	{
		total_crc = total_crc ^ acumulator;
		acumulator = 0;
		acumulator_size = 0;
	}


	//stream.Close();

	return total_crc;
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

__int64 MWApplication::CalculateMapMissionCRC(const char *mission_name)
{


	Stuff::MString mission_instance = mission_name;
	Stuff::MString res_name = "Resource\\Missions\\";
	res_name += mission_instance;
	res_name += ".mw4";


	Stuff::MString res_name_user = "Resource\\UserMissions\\";
	res_name_user += mission_instance;
	res_name_user += ".mw4";



	// if this is a stock mission


	bool stock_mission = false;

	MWTable::TableIterator *missionname_iterator;
	missionname_iterator = MWApplication::GetInstance()->m_missionsRenameTable->MakeTableIterator();
	MWTableEntry *missionname_entry;
	while((missionname_entry = missionname_iterator->ReadAndNext()) != NULL)
	{
		Check_Object(missionname_entry);
		if (!stricmp(missionname_entry->GetEntryName(), (char *)res_name))
		{
			
			stock_mission = true;
			break;

		}
	}
	delete missionname_iterator;
	


	TranslateMissionNameIfNecessary(res_name);
	TranslateMissionNameIfNecessary(res_name_user);

	if (stock_mission)
	{
		// if it doesn't exist on the hard-drive check the cd.
		if (!gos_DoesFileExist(res_name))
		{
			char cd_path[256];
			DWORD size=sizeof(cd_path);
			gos_LoadDataFromRegistry(
				"CDPath",
				cd_path,
				&size,
				TRUE
			);
			if (size>0)
			{
				size--;
				Verify(strlen(cd_path) == size);
				res_name=MString(cd_path)+res_name;
				bool res=true;
				while(!gos_DoesFileExist(res_name) && res)
				{
					if(NoCDMessageFunction)
						res=NoCDMessageFunction();
				}
			}
		}
	}
	

	if (!gos_DoesFileExist(res_name))
	{

		// the regular one doesn't exist
		// try the user one...
		res_name = res_name_user;
		if (!gos_DoesFileExist(res_name))
		{
			//no match, return
			return 0;
		}
		
	}
#if 0 // jcem
    return 0x123456;
#else // jcem
	FileStream stream(res_name);
	

	MD5_CTX resource_context;
	GUID resource_hash;
	unsigned char * buff=(unsigned char *) &resource_hash;
	
	MD5Init(&resource_context);
	int serverKey = Network::GetInstance()->GetServerKey();
	MD5Update(&resource_context, (unsigned char *) &serverKey, 4);
	MD5Update(&resource_context, (unsigned char *) stream.GetPointer(), stream.GetBytesRemaining());
	
	MD5Final(buff, &resource_context);


	__int64 total_crc;
	__int64 first_half = (__int64)buff[0];
	__int64 second_half = (__int64)buff[8];

	total_crc = first_half ^ second_half;


	return total_crc;
#endif // jcem

}

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

__int64 MWApplication::CalculateVersionNumber()
{

	__int64 final_number;


	// This is stupid!!!!!
	// you can't use the regular number due to the fact that it has leading zeros which
	// make the compiler think it is octal and produce errors on numbers larger than 8.

	// you can't use a straight scanf since the string has decimal places and that messes it up
	// no matter what format string you give it.
	// further the leading zeros mess up scanf also.


	__int64 number[4];


	// friggin seperate the strings..
	char *temp_string = new char [strlen(CURRENT_BUILD_FULL_STRING)+1];

	char *source = CURRENT_BUILD_FULL_STRING;
	char *dest = temp_string;


	char *string[4];

	string[0] = dest;
	int cur_string = 1;

	while (*source != '\0')
	{
		if (*source != '.')
		{
			*dest = *source;
			++dest;
			++source;
		}
		else
		{
			*dest = '\0';
			++dest;
			++source;
			
			if (cur_string < 4)
			{
				string[cur_string] = dest;
				cur_string++;
			}
		}
	}

	*dest = '\0';

	// remove the leading zeros...

	for (int i = 0; i < 4; ++i)
	{
		char *sub = string[i];
		while(*sub != '/0')
		{
			if (*sub != '0')
				break;
			else
				++sub;
		}

		if (*sub == '/0')
			number[i] = 0;
		else
			number[i] = atoi(sub);
	}



	final_number = number[3];
	final_number += (number[2] * 10000);
	final_number += (number[1] * 1000000);
	final_number += (number[0] * 100000000);

	delete temp_string;

	return final_number;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::InitializeOptions(MWOptions *new_options)
{
	Check_Object(this);
	Check_Object(new_options);

	//Setup Game Parameters
	NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();

	if (!networkingFlag)
	{
		params->m_heatOn = new_options->m_useHeat;
		params->m_unlimitedAmmo = new_options->m_unlimmitedAmmo;
		params->m_splashOn = new_options->m_splashDamage;
		params->m_weaponjamOn = new_options->m_weaponJam;
		params->m_ammobayfireOn = new_options->m_ammobayFire;
// MSL 5.05 Advance Mode
		params->m_advancemodeOn = new_options->m_advanceMode;
// MSL 5.06 Armor Mode
		params->m_armormodeOn = new_options->m_armorMode;
		params->m_friendlyFirePercentage = new_options->m_friendlyFire * 100;
	
		DamageDispatch::SetGlobalInvulnerability(new_options->m_useInvincibility);
	}


	VehicleInterface::SetPreferredCameraPosition(new_options->m_defaultView);

	if(new_options->m_defaultView == 1)
	{
		VehicleInterface::SetPreferredCameraPosition(3);
	}
		

	Scalar gamma = new_options->m_gamma * 1.7f + 0.8f;
	gos_SetGammaValue(gamma);
	
	int brightness = (int)(new_options->m_brightness * 10000);
	gos_SetBrightnessValue((DWORD)brightness );		// Value range 0-10,000, default 750 (See DirectX docs)

	int contrast = (int)(new_options->m_contrast * 20000);
	gos_SetContrastValue((DWORD)contrast );			// Value range 0-20,000, default 10,000 (See DirectX docs)

	SetDifficultyLevel(new_options->m_difficultyLevel);

	//Setup Video Parameters
	switch(new_options->m_resolution)
	{
	case MWOptions::Res1600x1200:
		Application::s_ScreenWidth = 1600;
		Application::s_ScreenHeight = 1200;
		break;
	case MWOptions::Res1280x1024:
		Application::s_ScreenWidth = 1280;
		Application::s_ScreenHeight = 1024;
		break;
	case MWOptions::Res1024x768:
		Application::s_ScreenWidth = 1024;
		Application::s_ScreenHeight = 768;
		break;
	case MWOptions::Res800x600:
		Application::s_ScreenWidth = 800;
		Application::s_ScreenHeight = 600;
		break;
	case MWOptions::Res640x480:
		Application::s_ScreenWidth = 640;
		Application::s_ScreenHeight = 480;
		break;
	
	}
		
	ChannelType::s_sfxVolume = new_options->m_sfxVolume / 100.0f;
	ChannelType::s_musicVolume = new_options->m_musicVolume / 100.0f;
}

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

void
	MWApplication::LoadServerOptions()
{

	LoadMOTD();
	LoadBans();
	NotationFile notefile("options.ini", NotationFile::Standard, true);
	NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();
	params->ResetParameters();
	params->LoadParameters(&notefile);
    CTCL_DefaultHostSetup(2); // jcem
}

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

void
	MWApplication::SaveServerOptions()
{

	NotationFile notefile("options.ini", NotationFile::Standard, true);
	NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();
	params->SaveServerParameters(&notefile);
	notefile.Save();
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::InitializeInstantAction()
{
	Check_Object(this);
	Check_Pointer(MW4Shell::Instance);

	for (int i = 0; i < Maximum_Lancemates; ++i)
	{
		lancemateConnectionData[i].Recycle();
	}

	if(MWCampaign::Instance)
	{
		delete MWCampaign::Instance;
		MWCampaign::Instance = NULL;
	}
	if(MWCampaign::TrainingInstance)
	{
		delete MWCampaign::TrainingInstance;
		MWCampaign::TrainingInstance = NULL;
	}
	if(MWCampaign::WaveInstance)
	{
		delete MWCampaign::WaveInstance;
		MWCampaign::WaveInstance = NULL;
	}
	if(MWCampaign::MasterTrialsInstance)
	{
		delete MWCampaign::MasterTrialsInstance;
		MWCampaign::MasterTrialsInstance = NULL;
	}

	Verify(!MWCampaign::Instance);
	MWCampaign::Instance = MWCampaign::MakeNewCampaign("Content\\Campaigns\\InstantAction.campaign");
	Check_Pointer(MWCampaign::Instance);

	Verify(!MWCampaign::TrainingInstance);
	MWCampaign::TrainingInstance = MWCampaign::MakeNewCampaign("Content\\Campaigns\\Training.campaign");
	Check_Pointer(MWCampaign::TrainingInstance);

	Verify(!MWCampaign::WaveInstance);
	MWCampaign::WaveInstance = MWCampaign::MakeNewCampaign("Content\\Campaigns\\Wave.campaign");
	Check_Pointer(MWCampaign::WaveInstance);

	Verify(!MWCampaign::MasterTrialsInstance);
	MWCampaign::MasterTrialsInstance = MWCampaign::MakeNewCampaign("Content\\Campaigns\\MasterTrials.campaign");
	Check_Pointer(MWCampaign::MasterTrialsInstance);


	Stuff::ChainIteratorOf<CampaignMissionPlug*>
		iterator(&MWCampaign::Instance->m_missions);
	MW4Shell::Instance->m_iaMissionCount = iterator.GetSize();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::InitializeCampaignGame()
{
	Check_Object(this);
	Check_Pointer(MW4Shell::Instance);
	//Here we Default the Game to load.  Base upon the pilot selected...we pick the
	//Last Game that was being played!

	//Check to see if we have games...

	//This is temporary!
	//We need to put pilot name shit here PILOT
	

	for (int i = 0; i < Maximum_Lancemates; ++i)
	{
		lancemateConnectionData[i].Recycle();
	}

	NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();
	params->ResetParameters();

	MString pilot_path = "Resource\\Pilots\\";
	if (!gos_DoesFileExist((char *)pilot_path))
		gos_CreateDirectory((char *)pilot_path);

	pilot_path += m_pilotName;
	if (!gos_DoesFileExist((char *)pilot_path))
		gos_CreateDirectory((char *)pilot_path);

	pilot_path += "\\Games";
	if (!gos_DoesFileExist((char *)pilot_path))
		gos_CreateDirectory((char *)pilot_path);

	Stuff::MString games_path = "Resource\\Pilots\\";
	games_path += m_pilotName;
	games_path += "\\Games\\*.mw4";
	Stuff::Directory *games_directory;
	games_directory = new Stuff::Directory(games_path, true);
	Check_Object(games_directory);

	//Check if we have loaded a game from the load area...
	//If not then load the most recent game or init the game because it is the first time
	if(!MW4Shell::Instance->m_doesHaveLoadGame)
	{
		if(MWCampaign::Instance)
		{
			delete MWCampaign::Instance;
			MWCampaign::Instance = NULL;
		}

		if(MWGame::GetInstance())
		{
			delete MWGame::GetInstance();
			GlobalPointers::ClearPointer(MWGameGlobalPointerIndex);
		}

		if(!g_bCOOP && games_directory->GetCurrentFileName())
		{
			//If so then load the most recent
			MString last_game = games_directory->GetNewestFile();
			last_game.StripDirectory();
			last_game.StripExtension();
			GlobalPointers::AddGlobalPointer(new MWGame((char *)last_game), MWGameGlobalPointerIndex);
		}
		else
		{
		  if (0 < m_nCamp_Stage) {
			GlobalPointers::AddGlobalPointer(new MWGame("Op1M0"), MWGameGlobalPointerIndex);
		  } else {
			if(MWCampaign::Instance)
			{
				delete MWCampaign::Instance;
				MWCampaign::Instance = NULL;
			}
		//If not then we need to make a new Game Object
			GlobalPointers::AddGlobalPointer(
				new MWGame(
					"Op1M0",
					"Campaigns\\Campaign.Campaign"
				), MWGameGlobalPointerIndex
			);
		  }
		}
	}
	MW4Shell::Instance->m_doesHaveLoadGame = false;

	Check_Object(MWGame::GetInstance());

	delete games_directory;
	MWCampaign::Instance = MWGame::GetInstance()->GetCampaign();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::SendMissonParameters(int connection)
{

	NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();

	DynamicMemoryStream stream;
	params->SaveParameters(&stream);
	stream.WriteByteAlign();
	stream.Rewind();

	Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection,stream.GetBufferBytesUsed()*8);
	Network::GetInstance()->SendNetMessage(connection, MissionParameterMessageID, &stream, true);
		

}

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

void
	MWApplication::ReceiveMissionParameters(Stuff::MemoryStream *message)
{

	NetMissionParameters::MWNetMissionParameters *server_params = GetServerNetParams();
	NetMissionParameters::MWNetMissionParameters *local_params = GetLocalNetParams();
	server_params->LoadParameters(message);

	if (server_params->m_mapClientCRC != lastMapCRC)
	{
		if (server_params->m_mapClientCRC != CalculateMapMissionCRC(server_params->m_mapName))
		{
			// send for map info...
			haveNetworkMap = false;
			Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestMapInfoMessageID, NULL, true);
		}
		else
		{
			haveNetworkMap = true;
		}
		
		// don't request more of them
		// we already know if we have it or not..
		lastMapCRC = server_params->m_mapClientCRC;
		
	}

    if (CTCL_IsConsoleX()) {
        if (haveNetworkMap) {
            local_params->m_mapID = server_params->m_mapID;
			Str_Copy(local_params->m_mapName, server_params->m_mapName, 124);
			Str_Copy(local_params->m_scenarioName, server_params->m_scenarioName, 124);
			Str_Copy(local_params->m_scenarioPath, server_params->m_scenarioPath, 124);
			local_params->m_mapClientCRC = server_params->m_mapClientCRC;
        }
    }
	//transfer the appropriate server options...
	local_params->m_forceRespawn = server_params->m_forceRespawn;
	local_params->m_unlimitedAmmo = server_params->m_unlimitedAmmo;	
	local_params->m_allowZoom = server_params->m_allowZoom;
	local_params->m_allow3rdPerson = server_params->m_allow3rdPerson;
	local_params->m_allowAutoAim = server_params->m_allowAutoAim;
	local_params->m_allowDeadToChat = server_params->m_allowDeadToChat;
	local_params->m_visibility = server_params->m_visibility;
	local_params->m_weather = server_params->m_weather;
	local_params->m_radarMode = server_params->m_radarMode;
	local_params->m_weaponjamOn = server_params->m_weaponjamOn;
	local_params->m_ammobayfireOn = server_params->m_ammobayfireOn;
// MSL 5.05 Advance Mode
	local_params->m_advancemodeOn = server_params->m_advancemodeOn;
// MSL 5.06 Armor Mode
	local_params->m_armormodeOn = server_params->m_armormodeOn;
}

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

void
	MWApplication::DisplayShellChat(BYTE from, BYTE type, BYTE players_sent_to, char *message)
{
	if (MW4Shell::Instance)
	{
		MW4Shell::Instance->AddChat(from, type, players_sent_to, message);
	}
}


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

void
	MWApplication::HandleHUDInput(bool team_chat, bool dead, bool observer, BYTE from, char* message)
{
	if (serverFlag)
	{
		// check to see if we are kicking or banning ppl
		char* kick_id_str = GetLocString(IDS_MP_KICK);
		char* ban_id_str = GetLocString(IDS_MP_BAN);
		int kick_id_len = strlen(kick_id_str);
		int ban_id_len = strlen(ban_id_str);
		bool is_kick = 0;
		bool is_ban = 0;
		int id_len = 0;
		int i;

		char* kick_usage_str = GetLocString(IDS_KICK_USAGE);
		char* ban_usage_str = GetLocString(IDS_BAN_USAGE);

		if ((_mbsnicmp((unsigned char*)message, (unsigned char*)kick_id_str, kick_id_len) == 0) &&
			((message[kick_id_len] == ' ') || (message[kick_id_len] == '\0')))
		{
			is_kick = 1;
			id_len = kick_id_len;
		}
		else if ((_mbsnicmp((unsigned char*)message, (unsigned char*)ban_id_str, ban_id_len) == 0) &&
			((message[ban_id_len] == ' ') || (message[ban_id_len] == '\0')))
		{
			is_ban = 1;
			id_len = ban_id_len;
		}

		if ((is_kick) || (is_ban))
		{
			// display the whole message again so that the server can see
			SendChat(from, SystemBroadcast, from, message);

			// check for missing name
			for (i = id_len; i < strlen(message) + 1; i++)
			{
				if (message[i] == '\0')
				{
					SendChat(from, SystemBroadcast, from, GetLocString(IDS_MISSINGNAME));
					if (is_kick)
						SendChat(from, SystemBroadcast, from, kick_usage_str);
					else
						SendChat(from, SystemBroadcast, from, ban_usage_str);
					return;
				}

				if (message[i] != ' ')
				{
					id_len = i;
					break;
				}
			}
	
			// check for open quote first
			if (message[id_len] != '"')
			{
				// invalid usage
				SendChat(from, SystemBroadcast, from, GetLocString(IDS_MISSINGQUOTE));
				if (is_kick)
					SendChat(from, SystemBroadcast, from, kick_usage_str);
				else
					SendChat(from, SystemBroadcast, from, ban_usage_str);
				return;
			}
			id_len++;

			// Check for quotes in the message and then get the names in quotes
			char player_name[256];
			int player_len = 0;
			for (i = id_len; i < strlen(message) + 1; i++)
			{
				if (message[i] == '\0')
				{
					// invalid usage
					SendChat(from, SystemBroadcast, from, GetLocString(IDS_MISSINGQUOTE));
					if (is_kick)
						SendChat(from, SystemBroadcast, from, kick_usage_str);
					else
						SendChat(from, SystemBroadcast, from, ban_usage_str);
					return;
				}

				if (message[i] == '"')
				{
					// done getting the names
					player_name[player_len] = '\0';
					id_len = i + 1;
					break;
				}
				else
				{
					player_name[player_len] = message[i];
					player_len++;
				}
			}

			// if the name is empty....
			if (player_len == 0)
			{
				SendChat(from, SystemBroadcast, from, GetLocString(IDS_MISSINGNAME));
				if (is_kick)
					SendChat(from, SystemBroadcast, from, kick_usage_str);
				else
					SendChat(from, SystemBroadcast, from, ban_usage_str);
				return;
			}

			// if there is something right after the close quote
			int connection_num = 0;
			if (message[id_len] != '\0')
			{
				if (message[id_len] != ' ')
				{
					// invalid format
					SendChat(from, SystemBroadcast, from, GetLocString(IDS_SPACENEEDED));
					if (is_kick)
						SendChat(from, SystemBroadcast, from, kick_usage_str);
					else
						SendChat(from, SystemBroadcast, from, ban_usage_str);
					return;
				}
				else
				{
					// check to see if we have a valid number
					bool is_num_present = false;
					for (i = id_len; i < strlen(message) + 1; i++)
					{
						if (message[i] == '\0')
							break;

						if (message[i] != ' ')
						{
							is_num_present = true;
							if (!isdigit(message[i]))
							{
								// invalid format
								SendChat(from, SystemBroadcast, from, GetLocString(IDS_INVALIDNUM));
								if (is_kick)
									SendChat(from, SystemBroadcast, from, kick_usage_str);
								else
									SendChat(from, SystemBroadcast, from, ban_usage_str);
								return;
							}
						}
					}

					// now grab the number
					if (is_num_present)
					{
						connection_num = atoi(&(message[id_len]));
						if ((connection_num < 2) || (connection_num > 255))
						{
							// invalid format
							SendChat(from, SystemBroadcast, from, GetLocString(IDS_INVALIDNUM));
							if (is_kick)
								SendChat(from, SystemBroadcast, from, kick_usage_str);
							else
								SendChat(from, SystemBroadcast, from, ban_usage_str);
							return;
						}
					}
				}
			}

			// initialize the connection number array
			int num_players = 0;
			int player_connections[Maximum_Players];
			for (i = 0; i < Maximum_Players; i++)
				player_connections[i] = -1;

			// check the name against every client's name
			for (i = 0; i < Maximum_Players; i++)
			{
				if (servedConnectionData[i].clientConnected)
				{
					if (_mbsnicmp((unsigned char*)player_name, (unsigned char*)servedConnectionData[i].pilotName, player_len + 1) == 0)
					{
						player_connections[num_players] = i;
						num_players++;
					}
				}
			}

			// let's see if we have a winner
			if (!num_players)				
			{
				// no winner.  Warn the server that no such person exists in the game
				SendChat(from, SystemBroadcast, from, GetLocString(IDS_NOTEXISTS));
				return;
			}
			else
			{
				if (num_players == 1)
				{
					if ((connection_num != 0) && (connection_num != player_connections[0]))
					{
						// invalid format
						SendChat(from, SystemBroadcast, from, GetLocString(IDS_WRONGNUM));
						return;
					}

					// Awesome, we have exactly one winner! 
					connection_num = player_connections[0];
				}
				else
				{	
					if (connection_num)
					{
						// Cool we have a number.
						// But let's check to see if the connection number is legit
						for (i = 0; i < num_players; i++)
						{
							if (connection_num == player_connections[i])
								break;
						}
						if (i == num_players)
						{
							SendChat(from, SystemBroadcast, from, GetLocString(IDS_WRONGNUM));
							return;
						}
					}
					else
					{
						// we don't have a connection number.
						// However, let's see if we can remove the server from the list
						if (num_players == 2)
						{
							if (player_connections[0] == Connection::Local->GetID()) 
								connection_num = player_connections[1];
							else if (player_connections[1] == Connection::Local->GetID())
								connection_num = player_connections[0];
						}
					}
				}

				if (connection_num)
				{
					// if the connection is a server, warn the server that it can't kick itself
					if (Connection::Local->GetID() == connection_num)
					{
						SendChat(from, SystemBroadcast, from, GetLocString(IDS_NOSELF));
						return;
					}

					// if the connection is not a server, go ahead and kick or ban this person
					if (is_kick)
					{
						KickPlayer(connection_num);
					}
					else
					{
						BanPlayer(connection_num);
					}
				}
				else
				{
					// if there are still multiple names, print them out!
					MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());
					int kills = 0;
					int deaths = 0;
					int score = 0;
					char player_str[512];
					char num_str[20];
					int player_len = 0;
					for (i = 0; i < num_players; i++)
					{
						if (player_connections[i] != Connection::Local->GetID())
						{
							kills = 0;
							deaths = 0;
							score = 0;
						
							Str_Copy(player_str, player_name, 512);
							player_len = strlen(player_str);
							player_str[player_len] = ',';
							player_str[player_len + 1] = ' ';
							player_str[player_len + 2] = '\0';
							_itoa(player_connections[i], num_str, 10);
							Str_Cat(player_str, num_str, 512);

							player_len = strlen(player_str);
							player_str[player_len] = ':';
							player_str[player_len + 1] = ' ';
							player_str[player_len + 2] = '\0';

							if ((servedConnectionData[player_connections[i]].clientPlayer != NULL) && (servedConnectionData[player_connections[i]].clientPlayer->vehicle != NULL))
							{
								// player is in the game
								kills = mission->m_BucketManager->FindBucketValue(CBucketManager::KILLS, servedConnectionData[player_connections[i]].clientPlayer->vehicle->GetReplicatorID());
								deaths = mission->m_BucketManager->FindBucketValue(CBucketManager::DEATHS, servedConnectionData[player_connections[i]].clientPlayer->vehicle->GetReplicatorID());
								score = mission->m_BucketManager->FindBucketValue(CBucketManager::CUSTOM, servedConnectionData[player_connections[i]].clientPlayer->vehicle->GetReplicatorID());

								_itoa(kills, num_str, 10);
								Str_Cat(player_str, num_str, 512);
								player_len = strlen(player_str);
								player_str[player_len] = ' ';
								player_str[player_len + 1] = '\0';

								Str_Cat(player_str, GetLocString(IDS_KILL_SMALL), 512);
								player_len = strlen(player_str);
								player_str[player_len] = ',';
								player_str[player_len + 1] = ' ';
								player_str[player_len + 2] = '\0';

								_itoa(deaths, num_str, 10);
								Str_Cat(player_str, num_str, 512);
								player_len = strlen(player_str);
								player_str[player_len] = ' ';
								player_str[player_len + 1] = '\0';

								Str_Cat(player_str, GetLocString(IDS_DEATH_SMALL), 512);
								player_len = strlen(player_str);
								player_str[player_len] = ',';
								player_str[player_len + 1] = ' ';
								player_str[player_len + 2] = '\0';
															
								_itoa(score, num_str, 10);
								Str_Cat(player_str, num_str, 512);
								player_len = strlen(player_str);
								player_str[player_len] = ' ';
								player_str[player_len + 1] = '\0';

								Str_Cat(player_str, GetLocString(IDS_SCORE_SMALL), 512);
								player_len = strlen(player_str);
								player_str[player_len] = '.';
								player_str[player_len + 1] = '\0';
							}
							else
							{
								// player is in the lobby
								Str_Cat(player_str, GetLocString(IDS_INLOBBY), 512);
							}
								
							SendChat(from, SystemBroadcast, from, player_str);
						}
					}
				}
			}
		}
		else
		{
			// We are not kicking or banning ppl, so just send out the message
			if (observer)
				SendChat(from,ObserverBroadcast,0,message);
			else
			{
				if (team_chat)
				{
					if (dead)
						SendChat(from,TeamDeadBroadcast,0,message);
					else
						SendChat(from,TeamAliveBroadcast,0,message);
				}
				else
				{
					if (dead)
						SendChat(from,DeadBroadcast,0,message);
					else
						SendChat(from,AliveBroadcast,0,message);
				}
			}
		}
	}
	else
	{
		// We are not a server, so just send out the message	
		if (observer)
			SendChat(from,ObserverBroadcast,0,message);
		else
		{
			if (team_chat)
			{
				if (dead)
					SendChat(from,TeamDeadBroadcast,0,message);
				else
					SendChat(from,TeamAliveBroadcast,0,message);
			}
			else
			{
				if (dead)
					SendChat(from,DeadBroadcast,0,message);
				else
					SendChat(from,AliveBroadcast,0,message);
			}
		}
	}
}

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

void MWApplication::ConnectClient(int connection, Connection *con)
{
	servedConnectionData[connection].clientConnected = true;
	servedConnectionData[connection].pilotName = con->GetConnectionName();

	#if defined(LAB_ONLY)
		// add this to the gameinfo
		Check_Object(con);

		const char *name;
		name = con->GetConnectionName();
		strncpy (MWGameInfo::g_playerNames[connection],name,MWGameInfo::MAX_GAME_INFO_STR_LEN-1);
		MWGameInfo::g_playerNames[connection][MWGameInfo::MAX_GAME_INFO_STR_LEN-1] = 0;

		MWGameInfo::g_playerVehicleNames[connection][0] = '\0';

		MWGameInfo::g_playerConnectTime[connection] = gos_GetElapsedTime();;
		MWGameInfo::g_playerDisconnectTime[connection] = -1.0;

		MWGameInfo::g_playerJoinTime[connection] = -1.0;
		MWGameInfo::g_playerLeaveTime[connection] = -1.0;


		MWGameInfo::g_lastConnectID = connection;
		++MWGameInfo::g_totalNetworkConnects;
		++MWGameInfo::g_currentlyConnected;
	#endif


	Adept::g_lastPacketFromPlayer[connection] = -1.0;
	Adept::g_lastPacketToPlayer[connection] = -1.0;
}


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

void MWApplication::DisconnectClient(int connection, Connection *con)
{


	#if defined(LAB_ONLY)
		// add this to the gameinfo
		MWGameInfo::g_playerDisconnectTime[connection] = gos_GetElapsedTime();;
		
		MWGameInfo::g_lastDisconnectID = connection;

		++MWGameInfo::g_totalNetworkDisconnects;
		--MWGameInfo::g_currentlyConnected;
	#endif

	int pilotTeam = servedConnectionData[connection].pilotTeam;
	servedConnectionData[connection].Disconnect();

	if (pilotTeam != No_Team)
	{
		char* message = GetTeamCount();
		if (message)
		{
			SendChat(
				Connection::Local->GetID(),
				SystemBroadcast,
				0,
				message);
			delete [] message;
		}
	}
}

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

void
	MWApplication::RecycleNetworking()
{
	//reset network stuff.	
	

	localVehicelAccepted = VEHICLE_NOTSENT;

	for (int i = 0; i < Maximum_Players; ++i)
	{
		servedConnectionData[i].Recycle();
	}

	for (i = 0; i < Maximum_Lancemates; ++i)
	{
		lancemateConnectionData[i].Recycle();
	}


	Application::RecycleNetworking();
}



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

void
	MWApplication::StopNetworking()
{

	//reset network stuff.	
	serverFlag = true;
	networkingFlag = false;
	
	localVehicelAccepted = VEHICLE_NOTSENT;

	for (int i = 0; i < Maximum_Players; ++i)
	{
	
		servedConnectionData[i].Disconnect();
	}

	for (i = 0; i < Maximum_Lancemates; ++i)
	{
		lancemateConnectionData[i].Recycle();
	}

	Application::StopNetworking();
}

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

void
	MWApplication::ConnectServer()
{
	MWApplication::GetInstance()->SendRequestConnectionMessage();
}

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

void MWApplication::UpdateDisplay()
{
	MWApplication *app = MWApplication::GetInstance();
#if !defined(NO_MR)
	if (app->playingMissionReview)
	{
		NMissionReview::PlayMissionReview (gos_GetElapsedTime ());
	}	
#endif // !defined(NO_MR)

	if (g_hVideo) {
		if (app->GetApplicationState() == ApplicationStateEngine::WaitingForGameState) {
/*
			static int s_nFrCount = 0;
			if (s_nFrCount % 120 < 60) {
				gosVideo_SetPlayMode(g_hVideo, gosVideo_Stop);
			} else {
				gosVideo_SetPlayMode(g_hVideo, gosVideo_Continue);
			}
			if (++s_nFrCount < 0)
				s_nFrCount = 0;
*/
			gosVideo_ResourceInfo gvi;
			gosVideo_GetResourceInfo(g_hVideo, &gvi);

			switch(gvi.ePlayStatus)
			{
			case gosVideo_Stop:
				if (g_fGameEndScreenTimer <= 0.0f) {
					// case 0
					//gosVideo_Command(g_hVideo, gosVideo_SetCoords, (Environment.screenWidth-gvi.dwWidth)/2, (Environment.screenHeight-gvi.dwHeight)/2);
					//gosVideo_Command(g_hVideo, gosVideo_SetScale, 1.0f, 1.0f);
					// case 1
					gosVideo_Command(g_hVideo, gosVideo_SetCoords, 0, 0);
					gosVideo_Command(g_hVideo, gosVideo_SetScale, Environment.screenWidth/(float)gvi.dwWidth, Environment.screenHeight/(float)gvi.dwHeight);

					gosVideo_SetPlayMode(g_hVideo, gosVideo_Loop); // gosVideo_Continue
				}
				break;
			}
		} else {
			gosVideo_SetPlayMode(g_hVideo, gosVideo_Stop);
		}
	}

	Application::UpdateDisplay ();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//


void MWApplication::DoGameLogic()
{
	/*if (g_hVideo) {
		gosVideo_SetPlayMode(g_hVideo, gosVideo_Stop); // gosVideo_Stop
	}*/
	MWApplication *app = MWApplication::GetInstance();

	if (!ModalScripts && app->serverFlag && !app->networkingFlag && (g_nWhyPaused == 0) && MWMission::GetInstance()) {
		MWMission* mission = Cast_Object(MWMission*, MWMission::GetInstance());
		if (app->IsCampCOOP() && mission && (mission->GetMissionTime() >= 5.0f)) {
          if (mission->GetCOOP(MWMission::COOP_MODAL_IS_ENDED) == 0) {
            int nModalType = mission->GetCOOP(MWMission::COOP_MODAL_START);
            if (nModalType || (g_InviteCOOP.m_pParent && (g_InviteCOOP.m_nResult != 2) && (g_InviteCOOP.m_nResult != 3))) {
                gosASSERT(g_nWhyPaused == 0);
                if (!nModalType)
                    nModalType = 4;
                gosASSERT((1 <= nModalType) && (nModalType <= 4));

                Mech* pMech = NULL;
                if (nModalType == 2) {
                    VehicleInterface* pvi = VehicleInterface::GetInstance();
                    gosASSERT(pvi);
                    pMech = Cast_Object(Mech*, pvi->vehicle);
                    gosASSERT(pMech);
                    //if (!pMech->vehicleShutDown) {
                        //pMech->ShutDownRequest(true);
                    //} else {
                        pMech->RepairForCOOP();
                        goto go_modal;
                    //}
                } else {
go_modal:
                    mission->SetCOOP(MWMission::COOP_MODAL_START, 0);

                    g_nWhyPaused = nModalType;
                    app->PauseGameMessageHandler(NULL);

                    if (nModalType == 2) {
                        //pMech->ShutDownRequest(false);
                    }
                }
            }
          }
		}
	}
    g_RSF.StartFrame(); // jcem
    g_MRF.StartFrame(); // jcem
    CRIO_StartFrame();

	if(app->QuedForPlayerRespawn() && Network::GetInstance() != NULL)
	{
		app->UnQuePlayerRespawn();

        if (g_nMR != 2) {
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestRespawnMessageID, NULL, true);
		}
	}
    static int g_nRespawnCount = -1;
    if (++g_nRespawnCount >= 10) {
        g_nRespawnCount = -1;

        if (EntityManager::GetInstance()) {
		    if (MWMission::GetInstance())
		    {
                MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
			    MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());
                Stuff::Time fTime = mission->GetMissionTime();
                manager->servedRespawnLances;
	            Stuff::ChainIteratorOf<Mech*> iter(&manager->servedRespawnLances);
                Mech* pLance;
	            while ((pLance = iter.ReadAndNext()) != NULL)
	            {
                    if (pLance->m_fTimeRespawnRequestEnd <= fTime) {
                        pLance->m_fTimeRespawnRequestEnd = 0.0f;
                        manager->servedRespawnLances.Remove(pLance);
                        int nLanceID;
                        for(nLanceID = 0; nLanceID < Maximum_Lancemates; nLanceID++) {
                            if (app->lancemateConnectionData[nLanceID].lancemateMech == pLance) {
                                app->RespawnLancemate(nLanceID);
                                break;
                            }
                        }
                        gosASSERT(nLanceID != Maximum_Lancemates);
                    }
	            }
            }
        }
    }


	if (app->serverFlag)
	{
#if !defined(NO_MR)
		if (app->m_recordLog)
		{
			app->m_recordLog->TakeSnapShot();
		}
#endif // !defined(NO_MR)

		// ngLog addition
#if !defined(NO_LOG)
		if(app->networkingFlag) {
			MW4log_checkCurrentStats();
		}
#endif // !defined(NO_LOG)

#if !defined(NO_MR)
		if (app->reviewPackets)
		{
			for (int i = 0; i < Maximum_Players; ++i)
			{
				if (app->servedConnectionData[i].clientStreamingReview)
				{
					Connection *conn = Network::GetInstance()->GetConnection(i);
					DWORD que = reinterpret_cast<DWORD>(gos_NetInformation(gos_GetMessageSendQueue, conn->GetNetworkAddress()));

					if (que < 3)
					{
						Network::GetInstance()->SendNetMessage(i, MissionReviewPartMessageID, &app->reviewPackets[app->servedConnectionData[i].nextReviewPacket], true);
						++app->servedConnectionData[i].nextReviewPacket;

						if (app->servedConnectionData[i].nextReviewPacket >= app->totalReviewPackets)
						{
							app->servedConnectionData[i].nextReviewPacket = 0;
							app->servedConnectionData[i].clientStreamingReview = false;
						}
					}
				}
			}
		}
#endif // !defined(NO_MR)


		if (app->parametersDirty && Network::GetInstance() != NULL)
		{

			Time elapsed_flood_time = gos_GetElapsedTime() - app->timeFromLastParameterSend;

			if (elapsed_flood_time > 2.0f)
			{
				app->timeFromLastParameterSend = gos_GetElapsedTime();
				app->parametersDirty = false;
				app->BroadcastMissionParameters();
			}
		}

      if (!CTCL_IsConsole()) {
		Time elapsed_player_status_time = gos_GetElapsedTime() - app->timeFromLastLobbyStatus;
		if (elapsed_player_status_time > 2.0f)
		{
			// this only sends to lobby players..
			app->timeFromLastLobbyStatus = gos_GetElapsedTime();
			app->SendLobbyStatus();
		}
      }


		NetMissionParameters::MWNetMissionParameters *params = params = app->GetLocalNetParams();
			

		app->gameTimer = false;
		app->lockTimer = false;
		app->recycleTimer = false;

		if (MWMission::GetInstance())
		{

			MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());

			app->gameTimer = true;
            Stuff::Scalar fEndMissTime = mission->GetEndMissionTime();
			app->gameTimerVal = fEndMissTime;

            static s_nStaticFrame = 0;
            if (++s_nStaticFrame == 10) {
                s_nStaticFrame = 0;
                if (CTCL_IsConsoleX()) {
                    int nGameTime = (int)(fEndMissTime + 0.5);
                    CTCL_SetGameTime(nGameTime);
                }
            }

			if (params->m_joinInProgressCutOff )
			{
				app->lockTimer = true;
				app->lockTimerVal = (params->m_joinInProgressCutOffTime*60) - mission->GetMissionTime();
				Min_Clamp(app->lockTimerVal, 0.0f);
			}
			
		}
		else
		{
			if (app->recycleTimerOn)
			{
				app->recycleTimer = true;
				app->recycleTimerVal =  Scalar(params->m_recycleDelay - (gos_GetElapsedTime() - app->recycleStartTime));

			}
		}

		if (app->applicationState->GetState() == ApplicationStateEngine::RunningGameState)
		{
			for (int i = 0; i < Maximum_Players; ++i)
			{
				if(app->servedConnectionData[i].clientConnected && app->servedConnectionData[i].clientQuedForLaunch)
				{
					app->LaunchPlayer(i);
				}
			}
		}
        if (CTCL_IsConsoleX()) {
            if (g_nMech4Comm) {
				//$$COOP
                if (g_nMech4Comm == 9) {
                    app->CTCL_CheckRunningStart();
                } else if (g_nMech4Comm == 11) {
		            if (app->parametersDirty)
		            {
				        app->timeFromLastParameterSend = gos_GetElapsedTime();
				        app->parametersDirty = false;
				        app->BroadcastMissionParameters();
		            }
                    MWApplication::GetInstance()->CTCL_GoRunningState();
                    g_nMech4Comm = 0;
                }
            }
        }
	}
    else
    {
		if (MWMission::GetInstance())
		{

            static s_nStaticFrame = 0;
            if (++s_nStaticFrame == 10) {
                s_nStaticFrame = 0;
                if (CTCL_IsConsoleX()) {
			        MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());

                    Stuff::Scalar fEndMissTime = mission->GetEndMissionTime();

                    int nGameTime = (int)(fEndMissTime + 0.5);
                    CTCL_SetGameTime(nGameTime);
                }
            }
        }
    }
    app->DoTOCs();

    if (!g_bNoPlasma) {
        static s_nStaticFrame_Plasma = 0;
        if (++s_nStaticFrame_Plasma == 30) {
            s_nStaticFrame_Plasma = 0;
            PLASMA_Do(2);
        }
    }


	if (app->applicationState->GetState() == ApplicationStateEngine::PreRenderState)
	{
		if (!app->waitingForRunMessage)
		{
			bool load_done = true;

			if (EventQueue::Instance->PeekAtNextEvent())
			{
				load_done = false;
			}

			ChainIteratorOf<MidLevelRenderer::MLRTexture *> textures(&MidLevelRenderer::MLRTexturePool::Instance->unloadedTextures);
			if (textures.GetCurrent() != NULL)
			{
				load_done = false;
			}

			if (load_done)
			{
				Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), ClientLoadedMessageID, NULL, true);
				app->waitingForRunMessage = true;
			}
		}

	}


  if (!CTCL_IsConsole()) // jcem
    app->RunTimeOuts();

	#if defined(LAB_ONLY)
		MWGameInfo::g_currentTime = gos_GetElapsedTime();
	#endif

	Application::DoGameLogic();

    CRIO_StopFrame();
    g_MRF.StopFrame(); // jcem
    g_RSF.StopFrame(); // jcem
}


void MWApplication::RunTimeOuts()
{

	if (!networkingFlag)
	{
		return;
	}


	MWApplication *app = MWApplication::GetInstance();

	if (serverFlag)
	{
		double current_time = gos_GetElapsedTime();
		for (int i = 0; i < Maximum_Players; ++i)
		{
			if (app->servedConnectionData[i].clientConnected)
			{
				
				if (i == Connection::Server->GetID())
					continue;

				if (Adept::g_lastPacketFromPlayer[i] != -1.0f)
				{
					double time_since_last_packet = current_time - Adept::g_lastPacketFromPlayer[i];

					if (time_since_last_packet > 75.0)
					{
						//drop player..
						app->KickPlayer(i);
					}
				}
				
				if (app->servedConnectionData[i].clientQuedForKick)
				{
					app->KickPlayer(i);
				}
			}
		}
	}
	else
	{

		if (networkingFlag)
		{
			if (Connection::Server != NULL)
			{
				if (Adept::g_lastPacketFromPlayer[Connection::Server->GetID()] != -1.0f)
				{
					double time_since_last_packet = gos_GetElapsedTime() - Adept::g_lastPacketFromPlayer[Connection::Server->GetID()];

					if (time_since_last_packet > 75.0)
					{
						app->SessionLost();
						app->QueStopGame(true);
					}
				}
			}
		}

	}
}

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


void
	MWApplication::StopGame()
{
	Check_Object(this);

	if (networkingFlag && applicationState->GetState() != ApplicationStateEngine::WaitingForGameState && !noRecycle)
	{
		applicationState->RequestState(ApplicationStateEngine::RecycleGameState);
		quedStop = false;
	}
	else
	{
		applicationState->RequestState(ApplicationStateEngine::StoppingGameState);
		quedStop = false;
	}

	//This is here to insure reset!!!!!
	m_iaGameType = DefaultGameType;

	noRecycle = false;
}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::ConstructEgg(
		const char* game_file
	)
{


	Check_Object(this);
	Check_Pointer(game_file);


	//
	//------------------------------
	// Now, open it as a file stream
	//------------------------------
	//
	//Check_Object(Tool::Instance);
	NotationFile notation_file(game_file, NotationFile::NonEmpty);

	//
	//-------------------------------------------
	// Find the mission name.  It should be first
	//-------------------------------------------
	//
	NotationFile::PageIterator *instance_names = notation_file.MakePageIterator();
	Check_Object(instance_names);
	Page *instance = instance_names->ReadAndNext();
	if (!instance)
		STOP(("%s is a bad game file!", game_file));
	Check_Object(instance);
	const char * instance_name;
	instance_name = instance->GetName();

	

	MWApplication::GetInstance()->SetMissionName(instance_name);

	//
	//-------------------------------------------------------------------------
	// Now create all the other players.  The pagename will be the connectionID
	// to look up
	//-------------------------------------------------------------------------
	//
	while ((instance = instance_names->ReadAndNext()) != NULL)
	{
		DynamicMemoryStream request_vehicle_stream;

		int length = 0;
		char prefix = DefaultSkinPrefix;
		request_vehicle_stream.WriteBytes(&prefix, 1);
		request_vehicle_stream.WriteBytes(&length, 1);
		request_vehicle_stream.WriteBytes(&length, 1);

		instance_name = instance->GetName();
		Check_Pointer(instance_name);

		request_vehicle_stream.WriteBytes(&CreationMessageType, 1);
		
		
		Tool::Instance = new MWTool();
		Check_Object(Tool::Instance);

		//
		//------------------------------------------
		// Find the connection and create its player
		//------------------------------------------
		//
		ReplicatorID base_id = ReplicatorID::Null;
		Entity::CreateMessage *player_message =
			Tool::Instance->ConstructCreateMessage(
				&request_vehicle_stream,
				instance,
				&base_id
			);
		Check_Object(player_message);
		request_vehicle_stream.AdvancePointer(player_message->messageLength);
		request_vehicle_stream.Rewind();


		delete Tool::Instance;
		Tool::Instance = NULL;

		// request our mech...

		//Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(Connection::Server->GetID(),request_vehicle_stream.GetBufferBytesUsed()*8);
		//Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestPlayerVehicleMessageID, &request_vehicle_stream, true);

		RequestPlayerVehicleMessageHandler(Connection::Server->GetID(), &request_vehicle_stream);


	}


	// technically we should wait for the server to accept our mech, but for right now it doesn't check anyway so
	// we just launch it...
	//Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), ReadyToLaunchMessageID, NULL, true);
	ReadyToLaunchMessageHandler(Connection::Server->GetID(), NULL);

	Resource::ParentFileDependencies = NULL;

	

	//
	//--------------------
	// Clean up our memory
	//--------------------
	//
	Check_Object(instance_names);
	delete instance_names;


}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::LoadGameMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "LoadGameMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	Check_Object(message);

	servedConnectionData[connection].clientReady = true;

	//
	//-------------------------------------------------
	// Make sure that it is really legal to do this now
	//-------------------------------------------------
	//
	applicationState->RequestState(ApplicationStateEngine::LoadingGameState);


	#if defined(LAB_ONLY)
			
		if (serverFlag)
		{
			if (m_localMissionParameters->m_runDedicated)
				MWGameInfo::g_dedicatedServer = true;
			else
				MWGameInfo::g_dedicatedServer = false;
		}
		else
		{
			if (m_serverMissionParameters->m_runDedicated)
				MWGameInfo::g_dedicatedServer = true;
			else
				MWGameInfo::g_dedicatedServer = false;
		}

	#endif

	//
	//-----------------------------------------------------------------------
	// Wrap a stream around the creation messages appended to the actual load
	// message header
	//-----------------------------------------------------------------------
	//

	BYTE is_night;
	*message >> is_night;
	char *mission_name = (char *)message->GetPointer();


	LoadMissionResources(mission_name);

	//
	//-------------------
	// Create the mission
	//-------------------
	//
	Verify(!Mission::GetInstance());
	
//	Resource mission_instance(mission_name);
	ResourceID mission_resource_id(MissionResourceFileID, 1);
	Resource mission_instance(mission_resource_id);
	void *new_data = new BYTE[mission_instance.GetSize()];
	mission_instance.LoadData();
	Mem_Copy(new_data, mission_instance.GetPointer(), mission_instance.GetSize(), mission_instance.GetSize());

	Mission::CreateMessage *create_message =
		Cast_Pointer(Mission::CreateMessage*, new_data);
	Check_Object(create_message);

	create_message->m_isNightMission = false;
	create_message->m_isNightMission = is_night;

	MemoryStream stream(create_message, create_message->messageLength);

	Check_Object(Connection::Server);
	ReplicatorID id = Connection::Server->GetNextReplicatorID();

	Entity::CreateEntity(&stream, &id);

	mission_instance.UnloadData();

	if (m_localMissionParameters->m_runDedicated)
		Mission::GetInstance()->BecomeInteresting(false);
	else
		Mission::GetInstance()->BecomeInteresting(true);

	stream.AdvancePointer(create_message->messageLength);

	delete new_data;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::RunGameMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RunGameMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	
	#if defined(LAB_ONLY)
		++MWGameInfo::g_totalNumberOfPlayedGames;
	#endif

	if (serverFlag && m_localMissionParameters->m_runDedicated)
	{
		
		// we are running dedicated...
		// don't do anything
	}
	else
	{
        // jcem - begin
	    NetMissionParameters::MWNetMissionParameters *params = 0;
	    if (serverFlag)
		    params = GetLocalNetParams();
	    else
		    params = GetServerNetParams();
#if 0 // def _DEBUG
        if (CTCL_IsNone())
		    params->m_radarMode =3;
#endif // _DEBUG
	    if (params->m_radarMode == 3)
            g_bUnlimitedRadarRange = true;
        else
            g_bUnlimitedRadarRange = false;
        // jcem - end

		Player::GetInstance()->ReceiveDropZone(preRenderDropLocation);

		//Player::GetInstance()->vehicle->SetNewLocalToParent(new_local_to_world);
		//Player::GetInstance()->vehicle->SyncMatrices(true);
		
		// connect to vehicle
		Check_Object(Player::GetInstance());
		Player::GetInstance()->ConnectToVehicle();

		EntityManager::GetInstance()->SetPlayerReady(Player::GetInstance()->vehicle);

	}

	// the server has one more entity than us- his ai.
	//if (!serverFlag && !m_localMissionParameters->m_runDedicated)
	//	Connection::Server->GetNextReplicatorID();

    if (g_bCOOP || (g_nMR == 2) || !(serverFlag && CTCL_IsConsoleX())) { // jcem for sync running...
	applicationState->RequestState(ApplicationStateEngine::RunningGameState);
    }
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::RequestPreRenderMessageHandler(int connection_id, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RequestPreRenderMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...


	//SPEWALWAYS(("jerryeds", "REQUEST PRERENDER HANDLER : %d ", connection_id));

	servedConnectionData[connection_id].clientReadyForPrerender = true;
	
	// if this isn't the server and we are still loading then don't send the message, que it.
	if (connection_id != Connection::Server->GetID() && GetApplicationState() == ApplicationStateEngine::LoadingGameState)
	{
		return;
	}


	SendPreRenderMessage(connection_id);

	
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWApplication::SendPreRenderMessage(int connection_id)
{
	//SPEWALWAYS(("jerryeds", "SEND PRERENDER : %d ", connection_id));

	DynamicMemoryStream positoin;

	if (connection_id == Connection::Server->GetID() && m_localMissionParameters->m_runDedicated)
	{
		Network::GetInstance()->SendNetMessage(connection_id,PreRenderMessageID,NULL,true);
	}
	else
	{

		if (servedConnectionData[connection_id].clientPlayer == NULL)
		{
#ifdef LAB_ONLY
			PAUSE(("TRYING TO CREATE PLAYER BEFORE CREATION"));
#endif


			Connection *conn = Network::GetInstance()->GetConnection(connection_id);
			if(conn != NULL)
			{
				servedConnectionData[connection_id].waitingForClientShutdownConfirmation = true;
				Network::GetInstance()->SendNetMessage(connection_id, StopMissionMessageID, NULL, true);
				
				PlayerLeavingMessageHandler(connection_id, NULL);
			}

			return;

		}

		Check_Object(servedConnectionData[connection_id].clientPlayer);
		ObjectID drop_zone = servedConnectionData[connection_id].clientPlayer->dropZone;
	
		Check_Object(EntityManager::GetInstance());
		DropZone *zone;
		zone = EntityManager::GetInstance()->GetDropZone(drop_zone);
		Check_Object(zone);

		Stuff::LinearMatrix4D drop_location = Stuff::LinearMatrix4D::Identity;

		drop_location = zone->RequestDrop();


		Point3D tran(drop_location);
		YawPitchRoll rot(drop_location);


		DynamicMemoryStream stream;
		

		int player_count = 0;
		for (int i = 1; i < Maximum_Players; ++i)
		{
			if (servedConnectionData[i].clientConnected && servedConnectionData[i].clientPlayer && servedConnectionData[i].clientPlayer->vehicle)
			{
				++player_count;
			}
		}

		stream.WriteBytes(&player_count,1);

		for (i = 1; i < Maximum_Players; ++i)
		{
			if (servedConnectionData[i].clientConnected && servedConnectionData[i].clientPlayer && servedConnectionData[i].clientPlayer->vehicle)
			{
				stream.WriteBytes(&i,1);
				stream.WriteBytes(&servedConnectionData[i].clientPlayer->GetVehicle()->respawnCount,4);
			}
		}


		player_count = 0;
		for (i = 0; i < Maximum_Lancemates; ++i)
		{
			if (lancemateConnectionData[i].lancemateConnected && lancemateConnectionData[i].lancemateMech)
			{
				++player_count;
			}
		}

		stream.WriteBytes(&player_count,1);
		for (i = 0; i < Maximum_Lancemates; ++i)
		{
			if (lancemateConnectionData[i].lancemateConnected && lancemateConnectionData[i].lancemateMech)
			{
				stream.WriteBytes(&i,1);
				stream.WriteBytes(&lancemateConnectionData[i].lancemateMech->respawnCount,4);
			}
		}




		stream.WriteBytes(&currentGameNumber,4);
		stream.WriteBytes(&tran.x,4);
		stream.WriteBytes(&tran.y,4);
		stream.WriteBytes(&tran.z,4);
		stream.WriteBytes(&rot.yaw,4);
		stream.WriteBytes(&rot.pitch,4);
		stream.WriteBytes(&rot.roll,4);

		stream.Rewind();


		MWEntityManager::GetInstance()->RespawnClient(connection_id, tran);
	

		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection_id,stream.GetBufferBytesUsed()*8);
		
		if (connection_id == Connection::Server->GetID())
		{
			PreRenderMessageHandler(connection_id,&stream);
		}
		else
		{
			Network::GetInstance()->SendNetMessage(connection_id,PreRenderMessageID,&stream,true);
		}
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::PreRenderMessageHandler(int connection, Stuff::MemoryStream *message)
{

	//SPEWALWAYS(("jerryeds", "RECIEVE PRERENDER HANDLER"));

	if (serverFlag && m_localMissionParameters->m_runDedicated)
	{
		
		// we are running dedicated...
		// don't do anything
	}
	else
	{
		Check_Object(message);

		Point3D tran;
		YawPitchRoll rot;

		BYTE player_count = 0;
		message->ReadBytes(&player_count, 1);
		

		for (int i = 0; i < player_count; ++i)
		{
			BYTE player_id = 0;
			message->ReadBytes(&player_id, 1);
			
			if (servedConnectionData[player_id].clientConnected && servedConnectionData[player_id].clientPlayer && servedConnectionData[player_id].clientPlayer->vehicle)
			{
				Verify(sizeof(servedConnectionData[player_id].clientPlayer->GetVehicle()->respawnCount) >= 4);
				message->ReadBytes(&servedConnectionData[player_id].clientPlayer->GetVehicle()->respawnCount,4);
			}
		}


		player_count = 0;
		message->ReadBytes(&player_count, 1);
		
		for (i = 0; i < player_count; ++i)
		{
			BYTE player_id = 0;
			message->ReadBytes(&player_id, 1);
			
			if (lancemateConnectionData[player_id].lancemateConnected && lancemateConnectionData[player_id].lancemateMech)
			{
				Verify(sizeof(lancemateConnectionData[player_id].lancemateMech->respawnCount) >= 4);
				message->ReadBytes(&lancemateConnectionData[player_id].lancemateMech->respawnCount,4);
			}	
		}



		Verify(sizeof(currentGameNumber) >= 4);
		message->ReadBytes(&currentGameNumber,4);
		message->ReadBytes(&tran.x,4);
		message->ReadBytes(&tran.y,4);
		message->ReadBytes(&tran.z,4);
		message->ReadBytes(&rot.yaw,4);
		message->ReadBytes(&rot.pitch,4);
		message->ReadBytes(&rot.roll,4);

		preRenderDropLocation = LinearMatrix4D::Identity;
		preRenderDropLocation.BuildRotation(rot);
		preRenderDropLocation.BuildTranslation(tran);


	}

	
	applicationState->RequestState(ApplicationStateEngine::PreRenderState);
}


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

void
	MWApplication::SendRequestNewDictionaryMessage()
{
	
	Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestNewDictionaryMessageID,NULL,true);
	
}


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


void
	MWApplication::RequestNewDictionaryMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RequestNewDictionaryMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	
	MWEntityManager::GetInstance()->UpdateDictionaries(connection);
	
	
}

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


void
	MWApplication::KickPlayerMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "KickPlayerMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	
	networkExitCode = KickedExitCode;
	
	Check_Object(Application::GetInstance());
	Application::GetInstance()->QueStopGame(true);

}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
	MWApplication::TeamBettyMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "TeamBettyMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(Application::GetInstance());

	if (serverFlag && m_localMissionParameters->m_runDedicated)
	{
		// we are running dedicated...
		// don't do anything
	}
	else
	{
		int team = 0;
		int betty = 0;
		message->ReadBytes(&team,1);
		message->ReadBytes(&betty,1);

		if ((Player::GetInstance() != 0) &&
			(VehicleInterface::GetInstance() != 0) &&
			(Player::GetInstance()->vehicle != 0) &&
			(Player::GetInstance()->vehicle->IsDerivedFrom(Vehicle::DefaultData) == true))
		{
			Vehicle* vehicle = Cast_Object(Vehicle*,Player::GetInstance()->vehicle);

            if (team == No_Team + 10) {
                VehicleInterface::GetInstance()->ReactToEvent((VehicleInterface::SOUND_TRIGGER)betty);
            } else
			if (vehicle->GetTeam() == team)
			{
				VehicleInterface::GetInstance()->ReactToEvent((VehicleInterface::SOUND_TRIGGER)betty);
			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
	MWApplication::StartMusicMessageHandler(int connection, Stuff::MemoryStream *message)
{
	Check_Object(Application::GetInstance());

	if (serverFlag && m_localMissionParameters->m_runDedicated)
	{
		// we are running dedicated...
		// don't do anything
	}
	else
	{
		int eventNum = 0;
		message->ReadBytes(&eventNum,1);

		if ((Player::GetInstance() != 0) && (VehicleInterface::GetInstance() != 0))
		{
			VehicleInterface::GetInstance()->ReactToEvent((VehicleInterface::SOUND_TRIGGER)eventNum);
		}
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
	MWApplication::TeamSetNavMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "TeamSetNavMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(Application::GetInstance());

	if (serverFlag && m_localMissionParameters->m_runDedicated)
	{
		// we are running dedicated...
		// don't do anything
	}
	else
	{
		int team = 0;
		int nav = 0;
		message->ReadBytes(&team,1);
		message->ReadBytes(&nav,4);

		if ((Player::GetInstance() != 0) &&
			(VehicleInterface::GetInstance() != 0) &&
			(Player::GetInstance()->vehicle != 0) &&
			(Player::GetInstance()->vehicle->IsDerivedFrom(Vehicle::DefaultData) == true))
		{
			Vehicle* vehicle = Cast_Object(Vehicle*,Player::GetInstance()->vehicle);

			if (vehicle->GetTeam() == team)
			{
				NavPoint* nav_point = Cast_Object(NavPoint *,NameTable::GetInstance()->FindData(nav));

				if (nav_point == 0)
				{
					return;
				}

				Check_Object (nav_point);
				nav_point->Reveal();

				if (VehicleInterface::GetInstance() != 0)
				{
					Check_Object(VehicleInterface::GetInstance());
					VehicleInterface::GetInstance()->SetNavPoint(nav_point);
				}
			}
		}
	}
}


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

void
	MWApplication::LaunchGame()
{
	Verify(Network::GetInstance() != NULL);
	Check_Object(this);

	Verify(serverFlag);
	Verify(missionReady);



	for (int i = 0; i < Maximum_Players; ++i)
	{
		if(servedConnectionData[i].clientReady && servedConnectionData[i].clientVehicleAccepted && i != Connection::Server->GetID())
		{
			LaunchPlayer(i);
		}
	}

	
	LaunchPlayer(Connection::Server->GetID());

	// ngLog addition
#if !defined(NO_LOG)
	if(serverFlag && networkingFlag) {
		MW4log_init();
		MW4log_generic(MW4GAME_START, "Game_Start");
	}
#endif // !defined(NO_LOG)
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::ChatMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "ChatMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...



	BYTE players_sent_to;
	BYTE from;
	BYTE type;

	message->ReadBytes(&type, 1);


	message->ReadBytes(&players_sent_to, 1);
	message->ReadBytes(&from, 1);

	char *text = (char*)message->GetPointer();
	message->AdvancePointer(strlen(text)+1); //_mbstrlen(text)+1);

	if (message)
		message->Rewind();

	if (type == SystemBroadcast && from != Connection::Server->GetID())
	{
		// hacker entry
		return;
	}

	if (!servedConnectionData[from].clientConnected)
		return;

	if (type == LobbyTeamBroadcast)
	{		
		NetMissionParameters::MWNetMissionParameters *params;
		if (serverFlag)
			params = GetLocalNetParams();
		else
			params = GetServerNetParams();
		if ((!params->m_teamAllowed) || (servedConnectionData[from].pilotTeam == No_Team))
		{
			type = LobbyBroadcast;
		}
		else
		{		
			char* team_chat_id_str = GetLocString(IDS_MP_TEAMCHAT);
			int team_chat_str_len = strlen(team_chat_id_str);
			// if nothing after the team chat identifier, then returns without displaying anything
			if (text[team_chat_str_len] == '\0')
				return;
		}
	}

	servedConnectionData[from].chatTimeLog.Add((float)(gos_GetElapsedTime() - servedConnectionData[from].lastChat));
	servedConnectionData[from].lastChat = gos_GetElapsedTime();

	// 20 message all within a minute
	if ((type != SystemBroadcast) && (servedConnectionData[from].chatTimeLog.GetArraySize() == 20 && servedConnectionData[from].chatTimeLog.CalculateSum() < 45.0f))
	{
		return;
	}


	// if the type is illeagal, change it to a legal type.
	type = TypeCheckChat((BYTE)from, type, players_sent_to);

	// echo the chat to everyone
	if (serverFlag)
	{
		// echo this message to all connected players	
		for (int i = 0; i < Maximum_Players; ++i)
		{
			if (servedConnectionData[i].clientConnected && i != Connection::Server->GetID())
			{
				if (!CullChat(from, type, players_sent_to, (BYTE)i))
				{
					Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(i,message->GetBufferBytesUsed()*8);
					Network::GetInstance()->SendNetMessage(i,ChatMessageID,message,true);
				}
			}
		}
	}


	DisplayChat(from, type, players_sent_to, text);

}

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

void
	MWApplication::DisplayChat(BYTE from, BYTE type, BYTE player_sent_to, char *message)
{

	if (Connection::Local == NULL)
		return;
	
	// all messages will be shown to a dedicated server
	if ((serverFlag) && (m_localMissionParameters->m_runDedicated))
	{
		// even though we haven't implemented private broadcast, it is just safe to put it here.
		if ((type == PrivateBroadcast) && (player_sent_to != Connection::Local->GetID()))
			return;

		DisplayShellChat(from, type, player_sent_to, message);
		return;
	}

	// otherwise do a cull chat first
	if (CullChat(from, type, player_sent_to, Connection::Local->GetID()))
		return;	

	// do the local display....
	if (applicationState->GetState() == ApplicationStateEngine::RunningGameState)
	{
		// filter out lobby broadcasts.
		if ((type != LobbyBroadcast) && (type != LobbyTeamBroadcast))
		{

			if (MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT))
			{

				HUDChat *chat = Cast_Object (HUDChat *, MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT));
				chat->AddChat (message,from,type,player_sent_to);
	//			(*chatCallback)(chatCallbackData, from, type, player_sent_to, message);
			}
		}
	}
	
	// filter out anything but lobby and system for non-dedicated server and client shell
	if ((type == LobbyBroadcast || type == LobbyTeamBroadcast || type == SystemBroadcast))
		DisplayShellChat(from, type, player_sent_to, message);
		
}

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

bool
	MWApplication::CullChat(BYTE from, BYTE type, BYTE player_sent_to, BYTE local_connection)
{

	NetMissionParameters::MWNetMissionParameters *params;
	if (serverFlag)
		params = GetLocalNetParams();
	else
		params = GetServerNetParams();


	MWPlayer *our_player = servedConnectionData[local_connection].clientPlayer;
	Vehicle *our_veh = NULL;
	bool our_dest = false;

	if (our_player != NULL)
	{
		if (our_player->vehicle != NULL)
			our_veh = Cast_Object(Vehicle *, our_player->vehicle);
		our_dest = our_veh->IsDestroyed();
	}


	switch (type)
	{
		case SystemBroadcast:
			//everyone receives system messages, period...
			if (player_sent_to != 0)
			{
				if (player_sent_to != local_connection)
					return true;
			}
			break;

		case AliveBroadcast:
			// if dead cant talk is on...
			if (!params->m_allowDeadToChat)
			{
				//Verify we are alive and we are not an observer to recieve
				if ((our_dest) || (servedConnectionData[local_connection].mechChasisID == M_CameraShip))
					return true;
			}

			break;

		case ObserverBroadcast:
		case DeadBroadcast:
			if (!params->m_allowDeadToChat)
			{
				//Verify we are dead or we are an observer to recieve
				if ((!our_dest) && (!(servedConnectionData[local_connection].mechChasisID == M_CameraShip)))
					return true;
			}

			break;

		case TeamAliveBroadcast:
			{
				if (!params->m_allowDeadToChat)
				{
					//Verify we are alive to recieve
					if (our_dest)
						return true;
				}

				if (our_veh == NULL)
					return true;
				
				//if (our_veh->GetTeam() != player_sent_to)
				//	return true;

				int team = our_veh->GetTeam();

				// if we don't have a team than this message isn't for us
				if (team == No_Team)
					return true;

				
				Team *pteam = teams[team]->GetCurrent();

				// if the team doesn't exist cull the chat
				if (!pteam)
				{
					return true;
				}

				if (pteam->GetTeamAlignment() != player_sent_to)
				{
					return true;
				}
			}
			break;
		case TeamDeadBroadcast:
			{
				if (!params->m_allowDeadToChat)
				{
					//Verify we are dead to recieve
					if (!our_dest)
						return true;
				}

				if (our_veh == NULL)
					return true;
				
				//if (our_veh->GetTeam() != player_sent_to)
				//	return true;

				int team = our_veh->GetTeam();

				// if we don't have a team than this message isn't for us
				if (team == No_Team)
					return true;

				
				Team *pteam = teams[team]->GetCurrent();

				// if the team doesn't exist cull the chat
				if (!pteam)
				{
					return true;
				}

				if (pteam->GetTeamAlignment() != player_sent_to)
				{
					return true;
				}
			}
			break;

		case PrivateBroadcast:
			// not us
			if (player_sent_to != local_connection)
				return true;
			break;

		case LobbyBroadcast:
			break;
				
		case LobbyTeamBroadcast:
			{
				// if the to client doesn't have a team than this message isn't for this client					
				if (servedConnectionData[local_connection].pilotTeam == 8)
					return true;

				int from_align = params->m_teamParams[servedConnectionData[from].pilotTeam].m_alignment;
				int to_align = params->m_teamParams[servedConnectionData[local_connection].pilotTeam].m_alignment;

				if (from_align != to_align)
					return true;
			}
			break;
	}

	
	if (type == SystemBroadcast)
		return false;

	if (!((serverFlag) && (m_localMissionParameters->m_runDedicated)))
	{
		if (type != LobbyBroadcast && type != LobbyTeamBroadcast && !our_veh)
		{
			return true;
		}
	}

	return false;
}

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

void
	MWApplication::LoadMOTD()
{
	if (!CTCL_IsNone()) // jcem
        return;
	if (!gos_DoesFileExist("MOTD.txt"))
	{
		return;
	}

	FileStream stream("MOTD.txt");

	motdLength = 0;
	while (stream.ReadLine(&motd[motdLength][0],MaxChatSize))
	{
		++motdLength;
		if (motdLength == 5)
			break;
	}


}


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



void
	MWApplication::SendChat(BYTE from, BYTE type, BYTE player_sent_to, char *text)
{

	if (type == SystemBroadcast && from != Connection::Server->GetID())
	{
		// god damn hackers...
		return;
	}
	
	type = TypeCheckChat(from, type, player_sent_to);


	DynamicMemoryStream message;
	message.WriteBytes(&type, 1);
	message.WriteBytes(&player_sent_to, 1);
	message.WriteBytes(&from, 1);
	
	size_t length = strlen(text); //_mbstrlen(text);
	++length;

	Max_Clamp(length, MaxChatSize);
	text[length-1] = 0;

	message.WriteBytes(text, length);
	message.Rewind();


	// 20 message all within a minute
	if ((type != SystemBroadcast) && (servedConnectionData[from].chatTimeLog.CalculateSum()+(float)(gos_GetElapsedTime() - servedConnectionData[from].lastChat) < 45.0f))
	{
		return;
	}


	if (serverFlag)
	{
		ChatMessageHandler(Connection::Server->GetID(), &message);
	}
	else
	{
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(Connection::Server->GetID(),message.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), ChatMessageID,&message,true);
	}

}

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


BYTE MWApplication::TypeCheckChat(BYTE from, BYTE type, BYTE &player_sent_to)
{
	if (type == SystemBroadcast && from == Connection::Server->GetID())
	{
		return type;
	}

	// Dedicated servers always send system broadcast
	if (from == Connection::Server->GetID())
	{
		if (serverFlag && m_localMissionParameters->m_runDedicated) {
			type = SystemBroadcast;
			return type;
		}
	}

	// if you don't have a player, your in the lobby...
	if (servedConnectionData[from].clientPlayer == NULL)
	{
		if ((type != LobbyBroadcast) && (type != LobbyTeamBroadcast))
			type = LobbyBroadcast;
	}
	else
	{
		//your in the game
		if (servedConnectionData[from].clientPlayer->vehicle == NULL)
		{
			type = DeadBroadcast;
		}
		else
		{
			Vehicle *veh = Cast_Object(Vehicle *, servedConnectionData[from].clientPlayer->vehicle);

			if ((veh->IsDestroyed()) && (type != DeadBroadcast) && (type != TeamDeadBroadcast))
			{
				type = DeadBroadcast;
			}
			
			if (type == TeamAliveBroadcast)
			{
				if (veh->GetTeam() == MWApplication::No_Team)
				{
					type = AliveBroadcast;
				}
				else
				{
					
					Team *pteam = teams[veh->GetTeam()]->GetCurrent();
					if (pteam)
					{
						player_sent_to = (BYTE)pteam->GetTeamAlignment();
					}
					else
					{
						type = AliveBroadcast;
					}
				}
			}
			
			if (type == TeamDeadBroadcast)
			{
				if (veh->GetTeam() == MWApplication::No_Team)
				{
					type = DeadBroadcast;
				}
				else
				{
					
					Team *pteam = teams[veh->GetTeam()]->GetCurrent();
					if (pteam)
					{
						player_sent_to = (BYTE)pteam->GetTeamAlignment();
					}
					else
					{
						type = DeadBroadcast;
					}
				}
			}

			if (type == DeadBroadcast)
			{
				if (!veh->IsDestroyed())
				{
					type = AliveBroadcast;
				}
			}
		}
	}

	return type;
}

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

void
	MWApplication::SendPersitantHermitObjects(int connection)
{
	

	if (connection == Connection::Server->GetID())
		return;


	ChainIteratorOf<Entity *> hermit_iterator(&replicatedHermits);
	Entity *entity;

	DynamicMemoryStream memory_stream;


	Point3D position;
	YawPitchRoll angle;

	while((entity = hermit_iterator.ReadAndNext()) != NULL)
	{
		
		Point3D position;
		YawPitchRoll angle;

		position = entity->GetLocalToWorld();
		angle = entity->GetLocalToWorld();

		memory_stream.WriteBytes(&entity->GetDataListResourceID().m_fileID,sizeof(entity->GetDataListResourceID().m_fileID));
		memory_stream.WriteBytes(&entity->GetDataListResourceID().m_recordID,sizeof(entity->GetDataListResourceID().m_recordID));
		memory_stream.WriteBytes(&position.x,sizeof(position.x));
		memory_stream.WriteBytes(&position.y,sizeof(position.y));
		memory_stream.WriteBytes(&position.z,sizeof(position.z));
		memory_stream.WriteBytes(&angle.yaw.angle,sizeof(angle.yaw.angle));
		memory_stream.WriteBytes(&angle.pitch.angle,sizeof(angle.pitch.angle));
		memory_stream.WriteBytes(&angle.roll.angle,sizeof(angle.roll.angle));
		
	}
	

	if (memory_stream.GetBytesUsed())
	{
		memory_stream.Rewind();
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection,memory_stream.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(connection,LoadPersitantHermitObjectsID,&memory_stream,true);
	}
	
	

}





//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::LoadPersitantHermitObjectsMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "LoadPersitantHermitObjectsMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	while (message->GetBytesRemaining())
	{	
		HermitEntry entry;

		message->ReadBytes(&entry.m_fileID,sizeof(entry.m_fileID));
		message->ReadBytes(&entry.m_recordID,sizeof(entry.m_recordID));
		message->ReadBytes(&entry.m_position.x,sizeof(entry.m_position.x));
		message->ReadBytes(&entry.m_position.y,sizeof(entry.m_position.y));
		message->ReadBytes(&entry.m_position.z,sizeof(entry.m_position.z));
		message->ReadBytes(&entry.m_rotation.yaw.angle,sizeof(entry.m_rotation.yaw.angle));
		message->ReadBytes(&entry.m_rotation.pitch.angle,sizeof(entry.m_rotation.pitch.angle));
		message->ReadBytes(&entry.m_rotation.roll.angle,sizeof(entry.m_rotation.roll.angle));



		LinearMatrix4D matrix;
		matrix.BuildIdentity();
		matrix.BuildTranslation(entry.m_position);
		matrix.BuildRotation(entry.m_rotation);

		ResourceID resource_id(entry.m_fileID, entry.m_recordID);


		// read position, rotation and resource id
		
		ClassID class_ID;
		class_ID = Entity::GetClassIDFromDataListID(resource_id);
		Verify(class_ID != NullClassID);

		unsigned flags = Entity::HermitMode;

		Entity::CreateMessage entity_create_message(
			sizeof(Entity::CreateMessage),
			DefaultEventPriority,
			Entity::CreateMessage::DefaultFlags,
			class_ID,
			flags,
			resource_id,
			matrix,
			0.0f,
			Entity::ExecutionStateEngine::NeverExecuteState,
			NameTable::NullObjectID,
			Entity::DefaultAlignment
		);
		MemoryStream stream(&entity_create_message, entity_create_message.messageLength);

		Entity *entity;
		ReplicatorID beam_id = Connection::Hermit->GetNextReplicatorID();
		entity = Entity::CreateEntity(&stream, &beam_id, false);
		Check_Object(entity);
		entity->SetPropType(Entity::MissionPropType);
		Map::GetInstance()->AddChild(entity);
		entity->SyncMatrices(true);


	}
}




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

void
	MWApplication::SendTeams(int connection)
{
	
	NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();

	if (params->m_teamAllowed)
	{

		DynamicMemoryStream memory_stream;

		memory_stream.WriteBits(&params->m_teamCount, 4);

		for (int i = 0; i < params->m_teamCount; ++i)
		{
			memory_stream.WriteBits(&params->m_teamParams[i].m_alignment, 4);
			memory_stream.WriteBits(&params->m_teamParams[i].m_skin, 8);

		}

		memory_stream.WriteByteAlign();
		memory_stream.Rewind();
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection,memory_stream.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(connection,AddTeamMessageID,&memory_stream,true);

	}

	

}



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

void
	MWApplication::AddTeamMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "AddTeamMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	
	int count = 0; // jcem: critical error - should clear before ReadBits(...)...
	message->ReadBits(&count, 4);;

	for (int i = 0; i < count; ++i)
	{
		int alignment = 0;
		message->ReadBits(&alignment, 4);
		BYTE prefix = 0;
		message->ReadBits(&prefix, 8);

		Resource team_instance("Content\\Misc\\Team\\Team.instance");
		Verify(team_instance.DoesResourceExist());
		team_instance.LoadData();
		ReplicatorID rep_id = Connection::Server->GetNextReplicatorID();
		Team *team = Cast_Object(Team *,Entity::CreateEntity(&team_instance, &rep_id));
		Check_Object(team);

		teams[i]->Add( team );

		team->SetTeamAlignment(alignment);
		team->SetTeamPrefix(prefix);

	}

}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::AddPlayerMessageHandler(int orig_connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "AddPlayerMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...


	Check_Object(this);

	//SPEW(("jerryeds", "%d : Add PLAYER MESSAGE HANDLER", Connection::Local->GetID()));


	
	Verify(
		applicationState->GetState() == ApplicationStateEngine::LoadingGameState ||
		applicationState->GetState() == ApplicationStateEngine::PreRenderState ||
		applicationState->GetState() == ApplicationStateEngine::RunningGameState
	);


	bool local_recieved = false;

	if (message)
	{

		Check_Object(message);



		
		//
		//-------------------
		// Create the players
		//-------------------
		//

		
		while (message->GetBytesRemaining())
		{
			
			BYTE connection_id;
			message->ReadBytes(&connection_id,1);

			servedConnectionData[connection_id].pilotTeam = 0;
			servedConnectionData[connection_id].teamDecals = 0;
			servedConnectionData[connection_id].pilotDecals = 0;
			servedConnectionData[connection_id].pilotSkins = 0;

			message->ReadBytes(&servedConnectionData[connection_id].pilotTeam, 1);
			message->ReadBytes(&servedConnectionData[connection_id].teamDecals, 1);
			message->ReadBytes(&servedConnectionData[connection_id].pilotDecals, 1);
			message->ReadBytes(&servedConnectionData[connection_id].pilotSkins, 1);


			Connection *connection = Network::GetInstance()->GetConnection(connection_id);
			Check_Object(connection);
			
			int size;
			message->ReadBytes(&size, 4);
		
			servedConnectionData[connection_id].clientVehicleAccepted = true;

			if (!serverFlag)
			{
				Stuff::MemoryStream create_stream(message->GetPointer(), size);
				SetVehicleCreationMessage(connection_id, &create_stream);	
				servedConnectionData[connection_id].clientLoaded = true;
				servedConnectionData[connection_id].clientLaunched = true;
				
			}


			if (servedConnectionData[connection_id].clientPlayer != NULL)
			{
#ifdef _ARMOR
				PAUSE(("CLIENT PLAYER ALREADY CREATED"));
#endif
				message->AdvancePointer(size);
				continue;
			}

			Entity::CreateMessage *create_message = MakePlayerCreationMessage(connection_id);
			message->AdvancePointer(size);


			ReplicatorID id = connection->GetNextReplicatorID();

			//SPEW(("jerryeds", "%d : CREATING PLAYER : %d", Connection::Local->GetID(), id.connectionID));

			Stuff::MemoryStream create_stream(create_message, create_message->messageLength);

			MWPlayer *player = Cast_Object(MWPlayer*, Entity::CreateEntity(&create_stream, &id));
			

			MWObject *object = Cast_Object(MWObject *,player->vehicle);

			if (serverFlag)
			{
				object->GetElement()->SetCullMode(object->originalCullMode);
				object->SetCollisionMask(object->originalCollisionMask);
			}


			Verify(player->vehicle->executionState->GetState() == Entity::ExecutionStateEngine::NeverExecuteState);
			player->vehicle->executionState->RequestState(Entity::ExecutionStateEngine::NeverExecuteState);

			Check_Object(player->vehicle);
			const LinearMatrix4D &drop =
				player->vehicle->GetElement()->GetNewLocalToParent();
			Point3D location(drop);
			

			if (connection == Connection::Local)
			{
				local_recieved = true;

				Verify(!Player::GetInstance());
				Check_Object(Network::GetInstance());
				GlobalPointers::AddGlobalPointer(player, PlayerGlobalPointerIndex);

				//we've created ourselves so we can "launch the game"

				Map::GetInstance()->UpdateRenderOrigin(location);
			}

			servedConnectionData[connection_id].clientPlayer = player;

			if (m_localMissionParameters->m_runDedicated)
				player->BecomeInteresting(false);
			else
				player->BecomeInteresting(true);

			player->vehicle->SetPlayerVehicle();
			if(MWGame::GetInstance())
			{
				PilotPlug *player_plug = MWGame::GetInstance()->GetPilotLeader();
				Check_Object(player_plug);

				Cast_Object(Mech *, player->vehicle)->SetMechTablePlug(player_plug->GetMechPlug());
			}

			Check_Object(Mission::GetInstance());
			ReplicatorID mech_id = player->vehicle->GetReplicatorID();
			
			Check_Object(EntityManager::GetInstance());
			EntityManager::GetInstance()->AddPlayerVehicle(Cast_Object(Mover*,player->vehicle));
			

			Verify(player->vehicle->executionState->GetState() == Entity::ExecutionStateEngine::NeverExecuteState);

            if (serverFlag) {
                if (object->GetClassData() == Mech::DefaultData) {
                    Mech* pMech = Cast_Object(Mech*, player->vehicle);
                    g_RSF.AddScoreObject(pMech, servedConnectionData[connection_id].pilotName, servedConnectionData[connection_id].pilotTeam, servedConnectionData[connection_id].teamDecals, servedConnectionData[connection_id].pilotDecals); // jcem
                }
            }

            PMRPPlayer pMRPPlayer = g_MRF.AddMRPPlayer(false);
            if (pMRPPlayer) {
                pMRPPlayer->m_strName = servedConnectionData[connection_id].pilotName;
                if (servedConnectionData[connection_id].clanName)
                    pMRPPlayer->m_strClan = servedConnectionData[connection_id].clanName;
                else
                    pMRPPlayer->m_strClan = "";
			    pMRPPlayer->m_connection_id = connection_id;
			    pMRPPlayer->m_pilotTeam = servedConnectionData[connection_id].pilotTeam;
			    pMRPPlayer->m_teamDecals = servedConnectionData[connection_id].teamDecals;
			    pMRPPlayer->m_pilotDecals = servedConnectionData[connection_id].pilotDecals;
			    pMRPPlayer->m_pilotSkins = servedConnectionData[connection_id].pilotSkins;
                pMRPPlayer->m_mechChasisID = servedConnectionData[connection_id].mechChasisID;
                pMRPPlayer->m_tonnage = servedConnectionData[connection_id].tonnage;
                MemoryStream* pVCM = GetVehicleCreationmessage(connection_id);
                pMRPPlayer->m_pBufVCM = (BYTE*)malloc(pVCM->GetSize());
                memcpy(pMRPPlayer->m_pBufVCM, pVCM->GetPointer(), pVCM->GetSize());
                pMRPPlayer->m_vehicleCreateMessage = new MemoryStream(pMRPPlayer->m_pBufVCM, pVCM->GetSize());
            }

			delete create_message;

		}
	}


	if (m_localMissionParameters->m_runDedicated && applicationState->GetState() == ApplicationStateEngine::LoadingGameState)
	{
		RequestPreRenderMessageHandler(Connection::Server->GetID(),NULL);
	}
	else if (applicationState->GetState() == ApplicationStateEngine::LoadingGameState && local_recieved)
	{
		//applicationState->RequestState(ApplicationStateEngine::PreRenderState);
		Network::GetInstance()->SendNetMessage(orig_connection,RequestPreRenderMessageID,NULL,true);
		//SPEWALWAYS(("jerryeds", "SEND REQUEST PRERENDER HANDLER"));
	}



	LoadAnimations();

	Check_Object(Mission::GetInstance());
	Mission::GetInstance()->SyncMatrices(true);
}

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

void
	MWApplication::RequestPlayerVehicleMessageHandler(int connection, MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RequestPlayerVehicleMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	Check_Object(message);
	

	// if they are already loaded than skip this.
	if (servedConnectionData[connection].clientLaunched)
	{
		return;
	}


	
	int team_length;
	int pilot_length;
	char team_text[256];
	char pilot_text[256];

	char prefix;

	message->ReadBytes(&prefix, 1);
	servedConnectionData[connection].pilotSkins = prefix;

	team_length = 0;
	team_text[0] = '\0';
	message->ReadBytes(&team_length, 1);
	if (team_length)
		message->ReadBytes(&team_text[0], team_length);
	team_text[team_length] = '\0';

	
	pilot_length = 0;
	pilot_text[0] = '\0';
	message->ReadBytes(&pilot_length, 1);
	if (pilot_length)
		message->ReadBytes(&pilot_text[0], pilot_length);
	pilot_text[pilot_length] = '\0';


	Stuff::MemoryStream create_stream(message->GetPointer(), message->GetBytesRemaining());
	SetVehicleCreationMessage(connection, &create_stream);
	servedConnectionData[connection].clientVehicleAccepted = true;

	bool have_team = false;
	bool have_pilot = false;





	if (team_length)
	{

		MString short_name = team_text;
		short_name.StripDirectory();

		MString transfer_decal_name;
		transfer_decal_name = "Content\\Textures\\customdecals\\transfer\\" + short_name;

		MString custom_decal_name;
		custom_decal_name = "Content\\Textures\\customdecals\\" + short_name;

		if (IsDecalOnDisk(team_text))
		{
			// we have them so we don't need to request them...
			have_team = true;
			RemoveDecal(servedConnectionData[connection].teamDecals);
			servedConnectionData[connection].teamDecals = AddDecal(team_text);
		}
		else if (IsDecalOnDisk(custom_decal_name))
		{
			// we have them so we don't need to request them...
			have_team = true;
			RemoveDecal(servedConnectionData[connection].teamDecals);
			servedConnectionData[connection].teamDecals = AddDecal(custom_decal_name);

		}
		else if (IsDecalOnDisk(transfer_decal_name))
		{
			// we have them so we don't need to request them...
			have_team = true;
			RemoveDecal(servedConnectionData[connection].teamDecals);
			servedConnectionData[connection].teamDecals = AddDecal(transfer_decal_name);

		}
		
	}
	if (pilot_length)
	{
		MString short_name = pilot_text;
		short_name.StripDirectory();

		MString transfer_decal_name;
		transfer_decal_name = "Content\\Textures\\customdecals\\transfer\\" + short_name;

		MString custom_decal_name;
		custom_decal_name = "Content\\Textures\\customdecals\\" + short_name;

		if ( IsDecalOnDisk(pilot_text) )
		{
			have_pilot = true;
			RemoveDecal(servedConnectionData[connection].pilotDecals);
			servedConnectionData[connection].pilotDecals = AddDecal(pilot_text);
		}
		else if ( IsDecalOnDisk(custom_decal_name) )
		{
			have_pilot = true;
			RemoveDecal(servedConnectionData[connection].pilotDecals);
			servedConnectionData[connection].pilotDecals = AddDecal(custom_decal_name);
		}
		else if ( IsDecalOnDisk(transfer_decal_name) )
		{
			have_pilot = true;
			RemoveDecal(servedConnectionData[connection].pilotDecals);
			servedConnectionData[connection].pilotDecals = AddDecal(transfer_decal_name);
		}
	}


	if (pilot_text[0] == '\0')
		have_pilot = true;

	if (team_text[0] == '\0')
		have_team = true;


	
	if (AllowDecalTransfer && servedConnectionData[connection].clientAllowTransfer && (!have_pilot || !have_team))
	{
		//ask for those textures...
		
		DynamicMemoryStream message;

		if (!have_team)
		{
			message.WriteBytes(&team_length, 1);
			message.WriteBytes(&team_text[0], team_length);
		}
		if (!have_pilot)
		{
			message.WriteBytes(&pilot_length, 1);
			message.WriteBytes(&pilot_text[0], pilot_length);
		}

		Network::GetInstance()->SendNetMessage(connection, RequestDecalsMessageID, &message, true);

	}
	else
	{
		// Have to verify all other player vehicles as well if team game
		if (serverFlag && GetLocalNetParams()->m_teamAllowed) {
			servedConnectionData[connection].clientVehicleAccepted = false;
			ReverifyDeniedVehicles();
		}
		VerifyPlayerVehicle(connection);
	}
}

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

void
	MWApplication::AcceptPlayerVehicleMessageHandler(int connection, MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "AcceptPlayerVehicleMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	

	//allowed to launch

	localVehicelAccepted = VEHICLE_ACCEPTED;


	lastErrorCount = 0;

}

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

void
	MWApplication::DenyPlayerVehicleMessageHandler(int connection, MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "DenyPlayerVehicleMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	
	//not allowed to launch

	localVehicelAccepted = VEHICLE_DENIED;


	if (servedConnectionData[Connection::Local->GetID()].vehicleCreateMessage==NULL)
	{
		lastErrorCount = 1;
		lastErrors[0] = UNKNOWN_BUILDERROR;
		return;
	}




	if (MechLab::Instance)
	{
		lastErrorCount = 1;
		lastErrors[0] = UNKNOWN_BUILDERROR;
		return;
	}



	if (applicationState->GetState() != ApplicationStateEngine::WaitingForGameState)
	{
		lastErrorCount = 1;
		lastErrors[0] = UNKNOWN_BUILDERROR;
		return;
	}


	Stuff::MemoryStream *stream;
	stream = GetVehicleCreationmessage(Connection::Local->GetID());

	NetMissionParameters::MWNetMissionParameters *params;
	if (serverFlag && servedConnectionData[Connection::Local->GetID()].pilotTeam != No_Team)
	{	
		servedConnectionData[Connection::Local->GetID()].clientVehicleAccepted = false;
		params = GetLocalNetParams();
		params->m_teamParams[servedConnectionData[Connection::Local->GetID()].pilotTeam].m_currentTotalTonnage = 
			GetCurrentTeamTotalTonage(servedConnectionData[Connection::Local->GetID()].pilotTeam);
	}

	if (!serverFlag && servedConnectionData[Connection::Local->GetID()].pilotTeam != No_Team)
	{	
		if (servedConnectionData[Connection::Local->GetID()].clientVehicleAccepted) {
			params = GetServerNetParams();
			params->m_teamParams[servedConnectionData[Connection::Local->GetID()].pilotTeam].m_currentTotalTonnage -= 
				servedConnectionData[Connection::Local->GetID()].tonnage;
		}
	}

	if (VerifyPlayerVehicle(Connection::Local->GetID(), stream))
	{
		lastErrorCount = 1;
		lastErrors[0] = UNKNOWN_BUILDERROR;
	}


	if (servedConnectionData[Connection::Local->GetID()].clientCustomResource != NULL)
	{
		delete servedConnectionData[Connection::Local->GetID()].clientCustomResource;
		servedConnectionData[Connection::Local->GetID()].clientCustomResource = NULL;
	}


}
/*
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void AddToLancemateGroup(Mech& lancemate)
{
	if ((Adept::Mission::GetInstance() != 0) &&
		(Adept::Mission::GetInstance()->IsDerivedFrom(MWMission::DefaultData) == true))
	{
		Group::identifier group_id(1);

		if (lancemate.GetAlignment() != Entity::Player)
		{
			group_id = 950 + lancemate.GetAlignment();
		}

		MWMission* mwmission = Cast_Object(MWMission*,Adept::Mission::GetInstance());
		GroupContainer& group_container = mwmission->GetGroupContainer();

														// create the group if it doesn't exist
		if (group_container.GroupExists(group_id) == false)
		{
			group_container.AddObjectToGroup(lancemate,group_id);
		}

														// add us to the group if we're not in it
		Group& group = group_container.GetGroup(group_id);

		if (std::find(lancemate.GetGroups().begin(),lancemate.GetGroups().end(),group_id) == lancemate.GetGroups().end())
		{
			lancemate.GetGroups().push_back(group_id);
		}

		std::vector<MWObject*> members;
		group.GetMembers(members);
		if (std::find(members.begin(),members.end(),&lancemate) == members.end())
		{
			group.AddObject(lancemate.objectID);
		}

		if (group_id == 1)
		{
														// make sure the group has a GROUPAI_LANCEMATE AI type
			if ((group.GetAI() == 0) ||
				(group.GetAI()->GetID() != MW4AI::Squad::GROUPAI_LANCEMATE))
			{
				Stuff::Auto_Ptr<MW4AI::Squad::AI> ai_ptr(MW4AI::Squad::CreateAI((MW4AI::Squad::ID)MW4AI::Squad::GROUPAI_LANCEMATE));
				group.SetSquadAI(ai_ptr);
			}
		}
	}
}
*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::AddLancemateMessageHandler(int connection, Stuff::MemoryStream* message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "AddLancemateMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);

	if (message == NULL)
		return;

	Check_Object(message);

	Verify(
		applicationState->GetState() == ApplicationStateEngine::LoadingGameState ||
		applicationState->GetState() == ApplicationStateEngine::PreRenderState ||
		applicationState->GetState() == ApplicationStateEngine::RunningGameState
	);

	//
	//-------------------
	// Create the lancemates
	//-------------------
	//

	while (message->GetBytesRemaining())
	{
		BYTE lancemate_index = 0;
		
		message->ReadBytes(&lancemate_index, 1);

		int team_number = 0;
		message->ReadBytes(&team_number,1);

		int size;
		message->ReadBytes(&size, 4);


		int name_size = 0;
		char *lancemate_name = NULL;

		message->ReadBytes(&name_size,4);
		lancemate_name = (char*)message->GetPointer();
		message->AdvancePointer(name_size);

		


//		if (!serverFlag)
		{
			Stuff::MemoryStream create_stream(message->GetPointer(),size);
			SetLancemateCreationMessage(lancemate_index,&create_stream);
		}


		bool should_set_skin = false;
		char skin_prefix = DefaultSkinPrefix;
		Team* team = 0;
		if (team_number != MWApplication::No_Team)
		{
			team = MWApplication::GetInstance()->teams[team_number]->GetCurrent();
			if (team)
			{
				skin_prefix = team->GetTeamPrefix();
				should_set_skin = true;
			}
		}


		//
		// add on the skin prefix to the message...
		//

		Mech::CreateMessage* create_message = (Mech::CreateMessage*)MakeLancemateCreationMessage(lancemate_index);
		message->AdvancePointer(size);

		if(should_set_skin)
			create_message->skinPrefix = skin_prefix;
		

		//
		//  Create the lancemate
		//

		Connection *connection = Connection::Server;
		Check_Object(connection);

		ReplicatorID id = connection->GetNextReplicatorID();

		Stuff::MemoryStream create_stream(create_message, create_message->messageLength);
		Mech::CreateMessage *mech_message = Cast_Pointer(Mech::CreateMessage *, create_stream.GetPointer());
		mech_message->nameID = NameTableEntry::BuildObjectID(NameTable::TableSize, 0);
		if(mech_message->initialAge == 0.0f)
		{
			Stuff::LinearMatrix4D drop_location = Stuff::LinearMatrix4D::Identity;
			drop_location.BuildTranslation(Point3D::HellPoint);

			mech_message->localToParent = drop_location;
		}
		
		Mech* lancemate = Cast_Object(Mech*, Entity::CreateEntity(&create_stream, &id));

		Mission::GetInstance()->AddScoreMember (lancemate->GetReplicatorID(),lancemate_name);

		//
		// Assign the lancemate to a team
		//


		if (team)
		{
			lancemate->SetTeam(team_number);
			team->AddMemberToTeam(lancemate);
		}


		Check_Object(lancemate);
		lancemate->SetPropType(Entity::PlayerPropType);

		if (MWGame::GetInstance())
		{
			//It is possible to enter this area if you have clicked on campaign previously and then
			//enter the game through instant action.
			Check_Object(MWGame::GetInstance());
			PilotPlug *pilot_plug;
			int pilot_index = (int)lancemate_index + 1;
			pilot_plug = MWGame::GetInstance()->GetPilot(pilot_index);
			if(pilot_plug)
			{
				if(pilot_plug->GetMechPlug())
					lancemate->SetMechTablePlug(pilot_plug->GetMechPlug());
			}
		}

		if(lancemateConnectionData[lancemate_index].buildName)
		{
			MString lance_name = lancemate->instanceName;
			lance_name += " ";
			lance_name += lancemate_name;
			lancemate->instanceName = lance_name;

			//Need to set a name
			NameTable::GetInstance()->AddEntry(lancemate, NameTable::VehicleArray);


		}
		else
		{
			lancemate->instanceName = lancemate_name;

			char id[10];
			sprintf(&id[0], "_%d", lancemate_index);

			lancemate->instanceName += id;

		
			//Need to set a name
			NameTable::GetInstance()->AddEntry(lancemate, NameTable::VehicleArray);


			lancemate->instanceName = lancemate_name;
		}
	
		

		Map::GetInstance()->AddChild(lancemate);

		lancemate->lancemateIndex = lancemate_index;
		lancemateConnectionData[lancemate_index].lancemateMech = lancemate;

		Check_Object(Mission::GetInstance());
		ReplicatorID mech_id = lancemate->GetReplicatorID();


		//
		// Assign the lancemate a drop
		//


		lancemateConnectionData[lancemate_index].dropZone = MWPlayer::FindDropZone(team_number);
		Check_Object(EntityManager::GetInstance());
		DropZone *zone;
		zone = EntityManager::GetInstance()->GetDropZone(lancemateConnectionData[lancemate_index].dropZone);
		
		if (zone)
		{
			Check_Object(zone);
	
			Stuff::LinearMatrix4D drop_location = Stuff::LinearMatrix4D::Identity;
			
			drop_location = zone->RequestDrop();
			
			lancemate->SetNewLocalToParent(drop_location);
			lancemate->SyncMatrices(true);
		}
		else
		{
			STOP(("no valid dropzone for lancemate"));
		}

		

		//
		// If we are the server make the ai
		//


		if (Network::GetInstance()->AmIServer())
		{
			Stuff::Scalar blank_cells[MechWarrior4::DEFAULT_MEMORYCELL_VALUES];
			for (int i = 0;
				  i < DEFAULT_MEMORYCELL_VALUES;
				  ++i)
			{
				blank_cells[i] = 0;
			}

			MString ai_name = lancemate_name;
			ai_name += "AI";
			ObjectID object_id = NameTable::GetInstance()->AddEntry(
				ai_name,
				NameTable::AIArray
			);

			

			MechAI::CreateMessage* ai_message =
				new MechAI::CreateMessage(
					sizeof(MechAI::CreateMessage),		// length
					DefaultEventPriority,				// priority
					MechAI::CreateMessage::DefaultFlags, // message_flags
					MechAIClassID,						// class_id
					0,									// replicator_flags
					lancemateConnectionData[lancemate_index].aiModel,	// data_list_id			
					lancemate->GetLocalToWorld(),			// creation_matrix,
					0.0f,								// age,
					Mech::ExecutionStateEngine::AlwaysExecuteState,	// execution_state
					object_id,							// name_id
					lancemate->GetAlignment(),			// entity_alignment
					DropZone::Null,						// drop_zone [NOT USED???]
					lancemate->objectID,							// entity_name_id
					lancemateConnectionData[lancemate_index].scriptName,	// script_name
					blank_cells,						// cell_values
					lancemateConnectionData[lancemate_index].pilotSkill, // pilotSkill
					lancemateConnectionData[lancemate_index].gunnerySkill, // gunnerySkill
					lancemateConnectionData[lancemate_index].eliteSkill, // eliteSkill
					lancemateConnectionData[lancemate_index].minHeatSkill, // minHeatSkill
					lancemateConnectionData[lancemate_index].maxheatSkill, // maxHeatSkill
					lancemateConnectionData[lancemate_index].sensorSkill, // sensor
					lancemateConnectionData[lancemate_index].blindFightSkill, // blind
					lancemateConnectionData[lancemate_index].longRangeGunSkill, // longrange
					lancemateConnectionData[lancemate_index].shortRangeGunSkill, // shortrange
					0,
					0,
					0
				);

			ReplicatorID ai_id = connection->GetNextReplicatorID();
			Stuff::MemoryStream ai_create_stream(ai_message,ai_message->messageLength);

			MechAI* lancemate_ai = Cast_Object(MechAI*, Entity::CreateEntity(&ai_create_stream,&ai_id,false));
			Check_Object(lancemate);

			lancemate_ai->ConnectEntity(lancemate);


			if (MWGame::GetInstance())
			{
				Check_Object(MWGame::GetInstance());
				PilotPlug *pilot_plug;
				int pilot_index = (int)lancemate_index + 1;
				pilot_plug = MWGame::GetInstance()->GetPilot(pilot_index);
				if(pilot_plug)
				{
					if(pilot_plug->GetPilot())
					{
						LancematePlug *lance_plug = pilot_plug->GetPilot();
						lancemate_ai->ConnectLancemate (lance_plug);
					}
				}
			}

				
			MWMission* mwmission = Cast_Object(MWMission*,Adept::Mission::GetInstance());
			mwmission->AddLancemate (lancemate_ai);
			Map::GetInstance()->AddChild(lancemate_ai);

			lancemate_ai->ExecutionNumber(MW4AI::g_AIExecutionNumber);
			
			delete ai_message;

            g_RSF.AddScoreObject(lancemate, lancemate_name, lancemateConnectionData[lancemate_index].pilotTeam, -1, -1); // jcem

            PMRPPlayer pMRPPlayer = g_MRF.AddMRPPlayer(true);
            if (pMRPPlayer) {
                pMRPPlayer->m_strName = lancemate_name;
                pMRPPlayer->m_strClan = lancemateConnectionData[lancemate_index].lancemateClan;
                pMRPPlayer->m_strScript = lancemateConnectionData[lancemate_index].scriptName;
			    pMRPPlayer->m_connection_id = lancemate_index;
			    pMRPPlayer->m_pilotTeam = team_number;
			    pMRPPlayer->m_teamDecals = 0;
			    pMRPPlayer->m_pilotDecals = 0;
			    pMRPPlayer->m_pilotSkins = skin_prefix;
                pMRPPlayer->m_mechChasisID = lancemateConnectionData[lancemate_index].mechChasisID;
                pMRPPlayer->m_tonnage = lancemateConnectionData[lancemate_index].tonnage;
                pMRPPlayer->m_aiModel = lancemateConnectionData[lancemate_index].aiModel;
                MemoryStream* pVCM = GetLancemateCreationMessage(lancemate_index);
                pMRPPlayer->m_pBufVCM = (BYTE*)malloc(pVCM->GetSize());
                memcpy(pMRPPlayer->m_pBufVCM, pVCM->GetPointer(), pVCM->GetSize());
                pMRPPlayer->m_vehicleCreateMessage = new MemoryStream(pMRPPlayer->m_pBufVCM, pVCM->GetSize());
            }


		}
		else
		{
			//
			// If we not the server skip it
			//

			connection->GetNextReplicatorID();
		}

		LoadAnimations();
	}
}

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

void
	MWApplication::ReadyToLaunchMessageHandler(int connection_id, MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "ReadyToLaunchMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	//Check_Object(message); EMPTY

	if (servedConnectionData[connection_id].clientLaunched == true)
		return;

	if (servedConnectionData[connection_id].clientVehicleAccepted)
	{

		NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();
		if (params->m_teamAllowed && servedConnectionData[connection_id].mechChasisID != M_CameraShip)
		{
			if (servedConnectionData[connection_id].pilotTeam == No_Team)
			{
				return;
			}
		}

		if (applicationState->GetState() == ApplicationStateEngine::RunningGameState)
		{
			NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();
			if (!params->m_joinInProgress)
			{
				return;
			}

			MWMission *mission = Cast_Object(MWMission*, MWMission::GetInstance());
			if ((params->m_joinInProgressCutOff) && mission->GetMissionTime() > params->m_joinInProgressCutOffTime*60)
			{
				return;
			}
		}

		servedConnectionData[connection_id].clientReady = true;
		servedConnectionData[connection_id].clientQuedForLaunch = true;

		if (applicationState->GetState() == ApplicationStateEngine::RunningGameState)
		{
			BroadcastAddNewPlayer(connection_id);	
		}
		// else it will be sent when we launch

	}
	else
	{
		if (m_localMissionParameters->m_runDedicated && connection_id == Connection::Server->GetID())
		{
			//?? don't think we have to do anything... we've already got the loading message
			servedConnectionData[connection_id].clientReady = true;
			servedConnectionData[connection_id].clientQuedForLaunch = true;
		}
		else
		{
			Network::GetInstance()->SendNetMessage(connection_id, DenyPlayerVehicleMessageID, NULL, true);
			//STOP(("PLAYER READY BUT NOT ACCEPTED: NOT IMPLEMENTED"));
		}
	}
	
}


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


void
	MWApplication::UnreadyLaunchMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "UnreadyLaunchMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...


	if (servedConnectionData[connection].clientLaunched == true)
		return;

	servedConnectionData[connection].clientReady = false;
	servedConnectionData[connection].clientQuedForLaunch = false;

}

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

void
	MWApplication::LaunchPlayer(int connection_id)
{
// send that client a start message
			
	Verify(Network::GetInstance() != NULL);
	Verify(serverFlag);
	Verify(missionReady);


	//SPEW(("jerryeds", "%d : LaunchPlayer", Connection::Local->GetID()));

	

	//Network::GetInstance()->SendConnections();

	Connection *connection = Network::GetInstance()->GetConnection(connection_id);
	Check_Object(connection);

	//
	//----------------------------------------------------------
	// Go ahead and put the load mission message into the stream
	//----------------------------------------------------------
	//

  if ((g_nMR != 2) || (connection_id == Connection::Server->GetID())) {
	int size = strlen(GetMissionName())+1;

	DynamicMemoryStream load_game_stream(size + 1);
	BYTE is_night = m_isNight;
	load_game_stream.WriteBytes(&is_night, 1);
	load_game_stream.WriteBytes(GetMissionName(), size);
	load_game_stream.Rewind();


	Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection->GetID(),load_game_stream.GetBufferBytesUsed()*8);
	Network::GetInstance()->SendNetMessage(connection->GetID(), LoadGameMessageID, &load_game_stream, true);

	SendPersitantHermitObjects(connection_id);


	SendTeams(connection_id);
  


	//skip ourselves...
	DynamicMemoryStream player_stream;


	// create all the players ...
	for (int i = 0; i < Maximum_Players; ++i)
	{
		if(servedConnectionData[i].clientReady && servedConnectionData[i].clientVehicleAccepted && i != connection_id)
		{

			if (i == Connection::Server->GetID() && m_localMissionParameters->m_runDedicated)
			{
				continue;
			}

			//SPEW(("jerryeds", "%d : ADD NEW PLAYER LOAD : %d -> %d", Connection::Local->GetID(), i, connection_id));




			player_stream.WriteBytes(&i, 1);

			player_stream.WriteBytes(&servedConnectionData[i].pilotTeam, 1);
			player_stream.WriteBytes(&servedConnectionData[i].teamDecals, 1);
			player_stream.WriteBytes(&servedConnectionData[i].pilotDecals, 1);
			player_stream.WriteBytes(&servedConnectionData[i].pilotSkins, 1);


			MemoryStream *vehicle_message = GetVehicleCreationmessage(i);
			Check_Object(vehicle_message);
		
			int player_size = vehicle_message->GetSize();
			player_stream.WriteBytes(&player_size, 4);
			player_stream.WriteBytes(vehicle_message->GetPointer(), vehicle_message->GetSize());
		}
	}

	if (connection_id == Connection::Server->GetID() && m_localMissionParameters->m_runDedicated)
	{

	}
	else
	{

		//SPEW(("jerryeds", "%d : ADD NEW PLAYER LOAD : %d -> %d", Connection::Local->GetID(), connection_id, connection_id));


		Verify(servedConnectionData[connection_id].clientVehicleAccepted);
		player_stream.WriteBytes(&connection_id, 1);
		player_stream.WriteBytes(&servedConnectionData[connection_id].pilotTeam, 1);
		player_stream.WriteBytes(&servedConnectionData[connection_id].teamDecals, 1);
		player_stream.WriteBytes(&servedConnectionData[connection_id].pilotDecals, 1);
		player_stream.WriteBytes(&servedConnectionData[connection_id].pilotSkins, 1);


		MemoryStream *vehicle_message = GetVehicleCreationmessage(connection_id);
		Check_Object(vehicle_message);
		int player_size = vehicle_message->GetSize();
		player_stream.WriteBytes(&player_size, 4);
		player_stream.WriteBytes(vehicle_message->GetPointer(), vehicle_message->GetSize());
	}



	DynamicMemoryStream lancemate_stream;
	// create all the lancemates
	{for (int i = 0;
		  i < Maximum_Lancemates;
		  ++i)
	{
		if (lancemateConnectionData[i].lancemateConnected && lancemateConnectionData[i].lancemateVehicleAccepted)
		{
			Verify(lancemateConnectionData[i].lancemateCreateMessage != NULL);

			lancemate_stream.WriteBytes(&i,1);

			lancemate_stream.WriteBytes(&lancemateConnectionData[i].pilotTeam,1);

			MemoryStream* lancemate_message = GetLancemateCreationMessage(i);
			Check_Object(lancemate_message);

			int size = lancemate_message->GetSize();

			lancemate_stream.WriteBytes(&size,4);
			
			int name_size = strlen(lancemateConnectionData[i].lancemateName)+1;
			lancemate_stream.WriteBytes(&name_size, 4);
			lancemate_stream.WriteBytes(lancemateConnectionData[i].lancemateName, name_size);

			lancemate_stream.WriteBytes(lancemate_message->GetPointer(),lancemate_message->GetSize());
		}
	}}

	player_stream.Rewind();
	
	SendDecalQuery(connection_id);
	
	if (lancemate_stream.GetBufferBytesUsed())
	{
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection->GetID(),lancemate_stream.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(connection->GetID(),AddLancemateMessageID,&lancemate_stream,true);
	}

	if (player_stream.GetBufferBytesUsed())
	{
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection->GetID(),player_stream.GetBufferBytesUsed()*8);

		Network::GetInstance()->SendNetMessage(connection->GetID(), AddPlayerMessageID, &player_stream, true);
	}
	else
	{
		Network::GetInstance()->SendNetMessage(connection->GetID(), AddPlayerMessageID, NULL, true);
	}
  }

	servedConnectionData[connection_id].clientLaunched = true;
	servedConnectionData[connection_id].clientQuedForLaunch = false;
}


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

void
	MWApplication::BroadcastAddNewPlayer(int connection_id)
{

	//SPEW(("jerryeds", "%d : BROADCAST NEW PLAYER : %d", Connection::Local->GetID(), connection_id));


	//Now create our vehicle
	DynamicMemoryStream new_player_stream;
	

	Verify(servedConnectionData[connection_id].clientVehicleAccepted);
	new_player_stream.WriteBytes(&connection_id, 1);

	new_player_stream.WriteBytes(&servedConnectionData[connection_id].pilotTeam, 1);
	new_player_stream.WriteBytes(&servedConnectionData[connection_id].teamDecals, 1);
	new_player_stream.WriteBytes(&servedConnectionData[connection_id].pilotDecals, 1);
	new_player_stream.WriteBytes(&servedConnectionData[connection_id].pilotSkins, 1);


	MemoryStream *vehicle_message = GetVehicleCreationmessage(connection_id);
	Check_Object(vehicle_message);
	int player_size = vehicle_message->GetSize();
	new_player_stream.WriteBytes(&player_size, 4);
	new_player_stream.WriteBytes(vehicle_message->GetPointer(), vehicle_message->GetSize());
	
	// and broadcast it!
	new_player_stream.Rewind();
	
	for (int i = 0; i < Maximum_Players; ++i)
	{
		if(servedConnectionData[i].clientLaunched && i != connection_id)
		{
			Connection *connection = Network::GetInstance()->GetConnection(i);
			Check_Object(connection);

			SendDecalQuery(i);
			Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection->GetID(),new_player_stream.GetBufferBytesUsed()*8);
			
			if (connection->GetID() == Connection::Server->GetID())
				AddPlayerMessageHandler(1, &new_player_stream);
			else
				Network::GetInstance()->SendNetMessage(connection->GetID(), AddPlayerMessageID, &new_player_stream, true);
		}
	}
}


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

void
	MWApplication::ClientLoadedMessageHandler(int connection_id, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "ClientLoadedMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	//Check_Object(message); EMPTY

	Verify(Network::GetInstance()->AmIServer());

	servedConnectionData[connection_id].clientLoaded = true;

	if (applicationState->GetState() == ApplicationStateEngine::RunningGameState)
	{
		// start the client

		// if we are not waiting for the buckets to be initialized send this
		// format to the player...
		MWMission *mission = Cast_Object(MWMission*, Mission::GetInstance());
	
		if (mission->m_BucketManager->NumTrackedBuckets() && servedConnectionData[connection_id].clientSentScoreFormat == false)
		{
			SendScoreFormat(connection_id);
	
		}

		SendRunGameMessage(connection_id);

		SendEveryoneRespawnIndex();

		MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
		manager->SetDirtyFlag();

		// ngLog addition
#if !defined(NO_LOG)
		if(serverFlag && networkingFlag) {
			LogPlayerConnect(connection_id);
		}
#endif // !defined(NO_LOG)
	

	}
	else
	{
		//if this is a local server message then go ahead an launch.
		if (connection_id == Connection::Server->GetID())
		{
			
			SendRunGameMessage(connection_id);

			MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
			manager->SetDirtyFlag();
		}
	}


	// if not he is cued for the when I am ready.
}


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

void MWApplication::SendRunGameMessage(int connection_id)
{
	
  if (CTCL_IsNone()) {
	char szString[256];
	sprintf(szString, Application::GetInstance()->GetLocString(IDS_ADEPT_NET_PLAYER_HAS_JOINED), servedConnectionData[connection_id].pilotName);
	Application::GetInstance()->SendChat(1, 0, 0, szString);
  }

	Network::GetInstance()->SendNetMessage(connection_id,RunGameMessageID,NULL,true);

}




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

void
	MWApplication::StopMissionMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "StopMissionMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...


	Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), StopMissionConfirmationMessageID, NULL, true);

	if (applicationState->GetState() != ApplicationStateEngine::WaitingForGameState && !QuedForStop())
	{
		SaveScore();
		QueStopGame();
	}

	ServerGameOver();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWApplication::PlayerLeavingMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "PlayerLeavingMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

  if (CTCL_IsNone()) {
	char szString[256];
	sprintf(szString, Application::GetInstance()->GetLocString(IDS_ADEPT_NET_PLAYER_HAS_LEFT), servedConnectionData[connection].pilotName);
	Application::GetInstance()->SendChat(1, 0, 0, szString);
  }



	SendRemovePlayerMessage(connection);

	if (Mission::GetInstance() && servedConnectionData[connection].clientPlayer != NULL && servedConnectionData[connection].clientPlayer->vehicle != NULL)
	{
		ScoreObject *score_object = Mission::GetInstance()->GetScoreMember(servedConnectionData[connection].clientPlayer->vehicle->GetReplicatorID());
		
		if (score_object)
		{
			delete score_object;
		}
	}


	// ngLog addition
#if !defined(NO_LOG)
	if(serverFlag && networkingFlag) {
		const char *p_name = Network::GetInstance()->GetConnection(connection)->GetConnectionName();

		if(!*p_name) {
			p_name = "UNKNOWN";
		}

		MW4log_writePlayerStats(connection, 0);
		MW4log_generic(MW4P_DISCONN, va("Player_Disconnect\t%i\t%s", connection, p_name));
	}
#endif // !defined(NO_LOG)

	servedConnectionData[connection].Recycle();

	Connection *conn = Network::GetInstance()->GetConnection(connection);


	if (conn != NULL)
	{
		conn->DeleteChildren();
	}

	servedConnectionData[connection].clientPlayer = NULL;

}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWApplication::RemovePlayerMessageHandler(int send_connection_id, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RemovePlayerMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	BYTE connection = 0;
	message->ReadBytes(&connection,1);

	if (Mission::GetInstance() && servedConnectionData[connection].clientPlayer != NULL && servedConnectionData[connection].clientPlayer->vehicle != NULL)
	{
		ScoreObject *score_object = Mission::GetInstance()->GetScoreMember(servedConnectionData[connection].clientPlayer->vehicle->GetReplicatorID());
		
		if (score_object)
		{
			delete score_object;
		}
	}

	servedConnectionData[connection].Recycle();

	Connection *conn = Network::GetInstance()->GetConnection(connection);
	if (conn != NULL)
	{
		conn->DeleteChildren();
	}

	servedConnectionData[connection].clientPlayer = NULL;

    if (CTCL_IsConsoleX()) {
        DoRemoveTOCs(connection);
    }
}


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

void
	MWApplication::SendRemovePlayerMessage(int connection_id)
{

	DynamicMemoryStream stream;
	stream.WriteBytes(&connection_id, 1);
	stream.Rewind();

	for (int i = 0; i < Maximum_Players; ++i)
	{
		Connection *connection = Network::GetInstance()->GetConnection(i);

		if(connection != NULL && i != Connection::Server->GetID() && i != connection_id && servedConnectionData[i].clientLaunched)
		{
			Network::GetInstance()->SendNetMessage(i, RemovePlayerMessageID, &stream, true);
		}
	}	
}


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

void
	MWApplication::SendPlayerLeavingMessage()
{
	if (Connection::Server != NULL)
	{
		SaveScore();
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), PlayerLeavingMessageID, NULL, true);
	}
}

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

extern void _stdcall TimeManagerUpdate();

void
	MWApplication::SendStopGameMessage()
{
	SaveScore();

	for (int i = 0; i < Maximum_Players; ++i)
	{
		if(servedConnectionData[i].clientConnected && i != Connection::Server->GetID())
		{
			servedConnectionData[i].waitingForClientShutdownConfirmation = true;
			Network::GetInstance()->SendNetMessage(i, StopMissionMessageID, NULL, true);
		}
	}	

	

	double time=gos_GetElapsedTime(1);

	while (gos_GetElapsedTime(1)-time < 1.5)
	{
		TimeManagerUpdate();
#ifdef OUTBOUND_WINDOW // jcem
		gos_OutboundWindowSync();
#endif // OUTBOUND_WINDOW
		Sleep(30);
	}


}


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

void
	MWApplication::StopMissionConfirmationMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "StopMissionConfirmationMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	servedConnectionData[connection].waitingForClientShutdownConfirmation = false;
}

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

void
	MWApplication::RequestMissionParametersMessageHandler(int connection, MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RequestMissionParametersMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);

	SendMissonParameters(connection);
}

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

void
	MWApplication::MissionParametersMessageHandler(int connection, MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "MissionParametersMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	Check_Object(message);
	
	ReceiveMissionParameters(message);

}

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

void
	MWApplication::RequestScoreFormatMessageHandler(int connection, MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RequestScoreFormatMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);	

	servedConnectionData[connection].clientSentScoreFormat = false;
	SendScoreFormat(connection);


}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
	bool ReadScoreFromStream(MemoryStream& message, const Adept::ReplicatorID& rep_id)
	{
		MWMission *mission = Cast_Object(MWMission*, Mission::GetInstance());

		int num_buckets = 0;
		message.ReadBytes(&num_buckets,1);

		bool read_a_score = false;

		{for (int i_buckets = 0;
			  i_buckets < num_buckets;
			  ++i_buckets)
		{
			int type = 0;
			message.ReadBytes(&type,1);
			int value = 0;
			message.ReadBytes(&value,4);

			CBucket *player_bucket = mission->m_BucketManager->PlayerBucket(rep_id,(CBucketManager::Bucket_Type)type);
			if (player_bucket != 0)
			{
				player_bucket->Value(value);
				read_a_score = true;
			}
		}}

		return read_a_score;
	}

void
	MWApplication::ScoreMessageHandler(int connection, MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "ScoreMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	Check_Object(message);
	

	if (!Mission::GetInstance())
		return;

	if (!servedConnectionData[Connection::Local->GetID()].clientSentScoreFormat)
	{
      if (g_nMR != 2) {
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestScoreFormatMessageID, NULL, true);
		return;
      }
        servedConnectionData[Connection::Local->GetID()].clientSentScoreFormat = true;
	}


	MWMission *mission = Cast_Object(MWMission*, Mission::GetInstance());
	

	if (mission->m_BucketManager->GetBucketCount() == 0)
	{
		
		if (MWGUIManager::GetInstance() != NULL)
		{
			HUDScore *score = (HUDScore*)MWGUIManager::GetInstance()->Component(MWGUIManager::HUD_SCORE);
			if (score)
			{
				score->KillData();
			}
		}

		delete mission->m_BucketManager;
		mission->m_BucketManager = NULL;

		mission->m_BucketManager = new CBucketManager ();

		servedConnectionData[Connection::Local->GetID()].clientSentScoreFormat = false;
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestScoreFormatMessageID, NULL, true);
		return;
	}

	BYTE player_count=0;
	message->ReadBytes(&player_count,1);


	int players_read = 0;

	{for (int i = 0; i < player_count; ++i)
	{

		BYTE id=0;
		message->ReadBytes(&id,1);

		if(servedConnectionData[id].clientConnected && servedConnectionData[id].clientPlayer != NULL && servedConnectionData[id].clientPlayer->vehicle != NULL)
		{
		
			if (servedConnectionData[id].clientPlayer->vehicle->GetClassID() == MechClassID)
			{
				Check_Object(servedConnectionData[id].clientPlayer);
				Check_Object(servedConnectionData[id].clientPlayer->vehicle);

				if (ReadScoreFromStream(*message,servedConnectionData[id].clientPlayer->vehicle->GetReplicatorID()))
				{
					players_read++;
				}
			}
		}
		else
		{
			int num_buckets = 0;
			message->ReadBytes(&num_buckets,1);
			
			message->AdvancePointer(5*num_buckets);
		}

	}}



	// if there are players but we haven't read any of them
	// erase our formate and request a new one, our score is messed up
	
	if (players_read == 0 && player_count)
	{
		if (MWGUIManager::GetInstance() != NULL)
		{
			HUDScore *score = (HUDScore*)MWGUIManager::GetInstance()->Component(MWGUIManager::HUD_SCORE);
			if (score)
			{
				score->KillData();
			}
		}

		delete mission->m_BucketManager;
		mission->m_BucketManager = NULL;

		mission->m_BucketManager = new CBucketManager ();

		servedConnectionData[Connection::Local->GetID()].clientSentScoreFormat = false;
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestScoreFormatMessageID, NULL, true);
		return;
	}


	BYTE lancemate_count = 0;
	message->ReadBytes(&lancemate_count,1);

	{for (int i = 0; i < lancemate_count; ++i)
	{
		BYTE id = 0;
		message->ReadBytes(&id,1);

		if (lancemateConnectionData[id].lancemateMech != 0)
		{
			ReadScoreFromStream(*message,lancemateConnectionData[id].lancemateMech->GetReplicatorID());
		}
		else
		{
			int num_buckets = 0;
			message->ReadBytes(&num_buckets,1);

			{for (int i_buckets = 0;
				  i_buckets < num_buckets;
				  ++i_buckets)
			{
				int x=0;
				message->ReadBytes(&x,1);
				message->ReadBytes(&x,4);
			}}
		}
	}}

	stlport::vector<CBucket*> team_buckets;

	{for (int i = 0;
		  i < 8;
		  ++i)
	{
		mission->m_BucketManager->FillTeamBuckets(i,team_buckets);

		int num_buckets = 0;
		message->ReadBytes(&num_buckets,1);

		{for (int i_buckets = 0;
			  i_buckets < num_buckets;
			  ++i_buckets)
		{
			int type = 0;
			message->ReadBytes(&type,1);
			int value = 0;
			message->ReadBytes(&value,4);

			{for (stlport::vector<CBucket*>::iterator j = team_buckets.begin();
				  j != team_buckets.end();
				  ++j)
			{
				if ((*j)->Type() == type)
				{
					(*j)->Value(value);
					break;
				}
			}}
		}}

		team_buckets.clear();
	}}

    // jcem : PVP...
    stlport::vector <CBucketManager::PVP_Rec>& aPVP_Recs = mission->m_BucketManager->m_aPVP_Recs;
    aPVP_Recs.clear();
    int nSize = 0;
    message->ReadBytes(&nSize,2);
    if (0 < nSize) {
	    {for (int i = 0; i < nSize; ++i)
	    {
            Adept::ReplicatorID id1;
            message->ReadBytes(&id1.connectionID, 1);
            message->ReadBytes(&id1.localID, 2);

            Adept::ReplicatorID id2;
            message->ReadBytes(&id2.connectionID, 1);
            message->ReadBytes(&id2.localID, 2);

            CBucketManager::PVP_Rec pvp(id1, id2);
            message->ReadBytes(&pvp.m_nKills, 4);
            message->ReadBytes(&pvp.m_nScore, 4);

            aPVP_Recs.push_back(pvp);
        }}
    }
    // jcem
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
	void WriteScoreToStream(MemoryStream& message, const Adept::ReplicatorID& rep_id)
	{
		MWMission *mission = Cast_Object(MWMission*, Mission::GetInstance());

		int size = mission->m_BucketManager->NumPlayerBuckets(rep_id);
		std::vector<CBucket*> nonzero_buckets;

		{for (int i_buckets = 0;
			 i_buckets < size;
			 ++i_buckets)
		{
			CBucket *player_bucket = mission->m_BucketManager->PlayerBucket(rep_id,i_buckets);
			if ((player_bucket->Tracked() == true) &&
				(player_bucket->GetVisible() == true))
			{
				nonzero_buckets.push_back(player_bucket);
			}
		}}

		int num_buckets = nonzero_buckets.size();
		message.WriteBytes(&num_buckets,1);

		{for (std::vector<CBucket*>::const_iterator i = nonzero_buckets.begin();
			  i != nonzero_buckets.end();
			  ++i)
		{
			int type = (*i)->Type();
			int value = (*i)->Value();
			message.WriteBytes(&type,1);
			message.WriteBytes(&value,4);
		}}
	}


void
	MWApplication::SendScore()
{
    if (g_nMR == 2)
		return;


	DynamicMemoryStream message;
	




	MWMission *mission = Cast_Object(MWMission*, Mission::GetInstance());

	BYTE player_count = 0;

	{for (int i = 0; i < Maximum_Players; ++i)
	{
		if (servedConnectionData[i].clientPlayer != NULL && servedConnectionData[i].clientPlayer->vehicle != NULL && servedConnectionData[i].clientLoaded)
		{
			if (servedConnectionData[i].clientPlayer->vehicle->GetClassID() == MechClassID)
			{
				player_count++;
			}
		}

	}}

	message.WriteBytes(&player_count,1);
	
	{for (int i = 0; i < Maximum_Players; ++i)
	{
		if (servedConnectionData[i].clientPlayer != NULL && servedConnectionData[i].clientPlayer->vehicle != NULL && servedConnectionData[i].clientLoaded)
		{
			Check_Object(servedConnectionData[i].clientPlayer);
			Check_Object(servedConnectionData[i].clientPlayer->vehicle);

			if (servedConnectionData[i].clientPlayer->vehicle->GetClassID() == MechClassID)
			{

				BYTE id = (BYTE)i;
				message.WriteBytes(&id,1);

				WriteScoreToStream(message,servedConnectionData[i].clientPlayer->vehicle->GetReplicatorID());
			}
		}
	}}

	BYTE lancemate_count = 0;

	{for (int i = 0; i < Maximum_Lancemates; ++i)
	{
		if (lancemateConnectionData[i].lancemateMech != 0)
		{
			++lancemate_count;
		}
	}}

	message.WriteBytes(&lancemate_count,1);

	{for (int i = 0; i < Maximum_Lancemates; ++i)
	{
		if (lancemateConnectionData[i].lancemateMech != 0)
		{
			BYTE id = (BYTE)i;
			message.WriteBytes(&id,1);

			WriteScoreToStream(message,lancemateConnectionData[i].lancemateMech->GetReplicatorID());
		}
	}}

	stlport::vector<CBucket*> team_buckets;

	{for (int i = 0;
		  i < 8;
		  ++i)
	{
		mission->m_BucketManager->FillTeamBuckets(i,team_buckets);

		std::vector<CBucket*> nonzero_buckets;

		{for (stlport::vector<CBucket*>::iterator i = team_buckets.begin();
			  i != team_buckets.end();
			  ++i)
		{
			if (((*i)->Tracked() == true) &&
				((*i)->GetVisible() == true))
			{
				nonzero_buckets.push_back(*i);
			}
		}}

		int num_buckets = nonzero_buckets.size();
		message.WriteBytes(&num_buckets,1);

		{for (stlport::vector<CBucket*>::iterator i = nonzero_buckets.begin();
			  i != nonzero_buckets.end();
			  ++i)
		{
			unsigned char type = (unsigned char)((*i)->Type());
			int value = (*i)->Value();
			message.WriteBytes(&type,1);
			message.WriteBytes(&value,4);
		}}

		team_buckets.clear();
	}}

	// if we have buckets send those...

	if (mission->m_BucketManager->BucketFormatDirty())
	{
		SendScoreFormat();
	}

    // jcem : PVP...
    stlport::vector <CBucketManager::PVP_Rec>& aPVP_Recs = mission->m_BucketManager->m_aPVP_Recs;
    int nSize = aPVP_Recs.size();
    message.WriteBytes(&nSize,2);
    if (0 < nSize) {
	    {for (stlport::vector<CBucketManager::PVP_Rec>::iterator i = aPVP_Recs.begin(); i != aPVP_Recs.end(); ++i)
	    {
            CBucketManager::PVP_Rec& pvp = (*i);
            const ReplicatorID& id1 = pvp.m_Inf;
            message.WriteBytes(&id1.connectionID, 1);
            message.WriteBytes(&id1.localID, 2);
            const ReplicatorID& id2 = pvp.m_Rcv;
            message.WriteBytes(&id2.connectionID, 1);
            message.WriteBytes(&id2.localID, 2);
            message.WriteBytes(&pvp.m_nKills, 4);
            message.WriteBytes(&pvp.m_nScore, 4);
        }}
    }
    // jcem

	message.Rewind();

	if (message.GetBufferBytesUsed())
	{

		{for (int i = 0; i < Maximum_Players; ++i)
		{
            if (!servedConnectionData[i].clientLoaded)
                continue;
            if (i == Connection::Server->GetID()) {
                if (g_nMR != 1)
                    continue;
            }
            if (!servedConnectionData[i].clientSentScoreFormat) {
				SendScoreFormat(i);
                if (!servedConnectionData[i].clientSentScoreFormat)
                    continue;
            }
			gosASSERT(servedConnectionData[i].clientSentScoreFormat);

			Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(i,message.GetBufferBytesUsed()*8);
			Network::GetInstance()->SendNetMessage(i, ScoreMessageID, &message, true);
		}}		
	}




}

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

void
	MWApplication::SendScoreFormat()
{

	for (int i = 0; i < Maximum_Players; ++i)
	{
		if(servedConnectionData[i].clientLoaded) // (i != Connection::Server->GetID())
		{
			SendScoreFormat(i);
		}
	}

	MWMission *mission = Cast_Object(MWMission*, Mission::GetInstance());


	mission->m_BucketManager->CleandBucketFormat();
}

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

void
	MWApplication::SendScoreFormat(int connection)
{
    if (g_nMR == 2) {
        servedConnectionData[connection].clientSentScoreFormat = true;
        return;
    }

	MWMission *mission = Cast_Object(MWMission*, Mission::GetInstance());
	

	DynamicMemoryStream message;
	
	//Verify(servedConnectionData[connection].clientSentScoreFormat == false);

	if (servedConnectionData[connection].clientSentScoreFormat == true)
		return;

    if (g_nMR == 1) {
        if ((connection == 1) && (Application::GetInstance()->GetApplicationState() != ApplicationStateEngine::RunningGameState))
            return;
    }
	//SPEW(("jerryeds", "SEND SCORE FORMAT : %d", connection));

	servedConnectionData[connection].clientSentScoreFormat = true;


	stlport::vector <CBucketManager::Track_Data>::iterator iter;
	stlport::vector <CBucketManager::Track_Data> *tracked_data = mission->m_BucketManager->GetTrackedData();

	if (!tracked_data->size())
		return;

	for (iter =tracked_data->begin ();iter != tracked_data->end ();iter++)
	{
		message.WriteBytes(&iter->buckettype, 1);
		message.WriteBytes(&iter->mod2,4);
		message.WriteBytes(&iter->objid,4);
		message.WriteBytes(&iter->visible,1);

		char score_name[25];
		for (int i = 0; i < 25; ++i)
		{
			score_name[i] = '\0';
		}

		MString text = mission->m_BucketManager->GetCustomBucketName();
		int length = strlen((char*)text);
		Max_Clamp(length, 24);
		strncpy(score_name,(char*)text,length);
		score_name[24] = '\0';
		message.WriteBytes(&score_name,25);
	}


	message.Rewind();

	
	if(servedConnectionData[connection].clientLoaded)
	{
      if ((connection != Connection::Server->GetID()) || (g_nMR == 1)) {
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection,message.GetBufferBytesUsed()*8);

		Network::GetInstance()->SendNetMessage(connection, ScoreFormatMessageID, &message, true);
      }
	}


	mission->m_BucketManager->CleandBucketFormat();

}

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

void
	MWApplication::ScoreFormatMessageHandler(int connection, MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "ScoreFormatMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	Check_Object(message);
	
	if (!Mission::GetInstance())
		return;



	MWMission *mission = Cast_Object(MWMission*, Mission::GetInstance());


	if (MWGUIManager::GetInstance() != NULL)
	{
		HUDScore *score = (HUDScore*)MWGUIManager::GetInstance()->Component(MWGUIManager::HUD_SCORE);
		if (score)
		{
			score->KillData();
		}
	}

	delete mission->m_BucketManager;
	mission->m_BucketManager = NULL;

	mission->m_BucketManager = new CBucketManager ();



	//SPEW(("jerryeds", "RECIEVE SCORE FORMAT "));

	servedConnectionData[Connection::Local->GetID()].clientSentScoreFormat = true;

	//MWMission *mission = Cast_Object(MWMission*, Mission::GetInstance());
	

	Verify(	mission->m_BucketManager->NumTrackedBuckets() == 0);

	while (message->GetBytesRemaining())
	{
		int p1 = 0;
		int p2 = 0;
		int p3 = 0;
		bool p4 = false;
		message->ReadBytes(&p1, 1);
		message->ReadBytes(&p2,4);
		message->ReadBytes(&p3,4);
		message->ReadBytes(&p4,1);

		char bucket_name[25];
		message->ReadBytes(&bucket_name,25);
		bucket_name[24] = '\0';
	
		mission->m_BucketManager->SetupTrackNet((CBucketManager::Bucket_Type)p1, p2, p3,p4);
		mission->m_BucketManager->SetCustomBucketName(bucket_name);
	}

}




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

void
	MWApplication::SendEveryoneRespawnIndex()
{

	DynamicMemoryStream stream;
	

	int player_count = 0;
	for (int i = 1; i < Maximum_Players; ++i)
	{
		if (servedConnectionData[i].clientConnected && servedConnectionData[i].clientPlayer && servedConnectionData[i].clientPlayer->vehicle)
		{
			++player_count;
		}
	}

	stream.WriteBytes(&player_count,1);

	for (i = 1; i < Maximum_Players; ++i)
	{
		if (servedConnectionData[i].clientConnected && servedConnectionData[i].clientPlayer && servedConnectionData[i].clientPlayer->vehicle)
		{
			stream.WriteBytes(&i,1);
			stream.WriteBytes(&servedConnectionData[i].clientPlayer->GetVehicle()->respawnCount,4);
		}
	}


	player_count = 0;
	for (i = 0; i < Maximum_Lancemates; ++i)
	{
		if (lancemateConnectionData[i].lancemateConnected && lancemateConnectionData[i].lancemateMech)
		{
			++player_count;
		}
	}

	stream.WriteBytes(&player_count,1);
	for (i = 0; i < Maximum_Lancemates; ++i)
	{
		if (lancemateConnectionData[i].lancemateConnected && lancemateConnectionData[i].lancemateMech)
		{
			stream.WriteBytes(&i,1);
			stream.WriteBytes(&lancemateConnectionData[i].lancemateMech->respawnCount,4);
		}
	}


	stream.Rewind();


	for (i = 0; i < Maximum_Players; ++i)
	{
		if(servedConnectionData[i].clientLoaded && i != Connection::Server->GetID())
		{
			Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(i,stream.GetBufferBytesUsed()*8);
			Network::GetInstance()->SendNetMessage(i, RespawnIndexMessageID, &stream, true);
		}
	}		

}

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

void
	MWApplication::RespawnIndexMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RespawnIndexMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	BYTE player_count = 0;
	message->ReadBytes(&player_count, 1);
	

	for (int i = 0; i < player_count; ++i)
	{
		BYTE player_id = 0;
		message->ReadBytes(&player_id, 1);
		
		if (servedConnectionData[player_id].clientConnected && servedConnectionData[player_id].clientPlayer && servedConnectionData[player_id].clientPlayer->vehicle)
		{
			Verify(sizeof(servedConnectionData[player_id].clientPlayer->GetVehicle()->respawnCount) >= 4);
			message->ReadBytes(&servedConnectionData[player_id].clientPlayer->GetVehicle()->respawnCount,4);
		}
	}


	player_count = 0;
	message->ReadBytes(&player_count, 1);
	
	for (i = 0; i < player_count; ++i)
	{
		BYTE player_id = 0;
		message->ReadBytes(&player_id, 1);
		
		if (lancemateConnectionData[player_id].lancemateConnected && lancemateConnectionData[player_id].lancemateMech)
		{
			Verify(sizeof(lancemateConnectionData[player_id].lancemateMech->respawnCount) >= 4);
			message->ReadBytes(&lancemateConnectionData[player_id].lancemateMech->respawnCount,4);
		}	
	}

}

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

void
	MWApplication::RequestMapInfoMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RequestMapInfoMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...


	Stuff::MString mission_instance = MW4Shell::Instance->m_iaMissionName;
	Stuff::MString res_name = "Resource\\Missions\\";
	res_name += mission_instance;
	res_name += ".nfo";

	Stuff::DynamicMemoryStream mem_stream;

	if (gos_DoesFileExist(res_name))
	{

		NotationFile note_file(res_name, NotationFile::Standard, true);
		Page *page = note_file.FindPage("info");
		if (page)
		{
			const char *author_text = '\0';
			const char *info_text = '\0';
			const char *link_text = '\0';

			page->GetEntry("author", &author_text);
			page->GetEntry("info", &info_text);
			page->GetEntry("link", &link_text);

			int length = strlen(author_text);
			mem_stream.WriteBytes(&length, 2);
			mem_stream.WriteBytes(author_text, length);
		
			length = strlen(info_text)+1;
			mem_stream.WriteBytes(&length, 2);
			mem_stream.WriteBytes(info_text, length);
		
			length = strlen(link_text)+1;
			mem_stream.WriteBytes(&length, 2);
			mem_stream.WriteBytes(link_text, length);
		
			Network::GetInstance()->SendNetMessage(connection, MapInfoMessageID, &mem_stream, true);

			return;

		}

	}
	else
	{
		Stuff::MString res_name = "Resource\\UserMissions\\";
		res_name += mission_instance;
		res_name += ".nfo";

		Stuff::DynamicMemoryStream mem_stream;

		if (gos_DoesFileExist(res_name))
		{

			NotationFile note_file(res_name, NotationFile::Standard, true);
			Page *page = note_file.FindPage("info");
			if (page)
			{
				const char *author_text = '\0';
				const char *info_text = '\0';
				const char *link_text = '\0';

				page->GetEntry("author", &author_text);
				page->GetEntry("info", &info_text);
				page->GetEntry("link", &link_text);

				int length = strlen(author_text);
				mem_stream.WriteBytes(&length, 2);
				mem_stream.WriteBytes(author_text, length);
			
				length = strlen(info_text)+1;
				mem_stream.WriteBytes(&length, 2);
				mem_stream.WriteBytes(info_text, length);
			
				length = strlen(link_text)+1;
				mem_stream.WriteBytes(&length, 2);
				mem_stream.WriteBytes(link_text, length);
			
				Network::GetInstance()->SendNetMessage(connection, MapInfoMessageID, &mem_stream, true);

				return;
			}
		}
	}
		

		
	// else we didn't get anything so send a blank.
	Network::GetInstance()->SendNetMessage(connection, MapInfoMessageID, NULL, true);
	
	


}

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


void	
	MWApplication::MapInfoMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "MapInfoMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...



	// show the map info in gosscript...
	
	//Verify();


	const char *author_text = NULL;
	const char *info_text = NULL;
	const char *link_text = NULL;

	if (message != NULL)
	{
		
		int size = 0;
		message->ReadBytes(&size, 2);
		author_text = (char*)message->GetPointer();
		message->AdvancePointer(size);

		message->ReadBytes(&size, 2);
		info_text = (char*)message->GetPointer();
		message->AdvancePointer(size);

		message->ReadBytes(&size, 2);
		link_text = (char*)message->GetPointer();
		message->AdvancePointer(size);

		MW4Shell::Instance->SetMapInfo(author_text, info_text, link_text);

		
	}
	else
	{
		MW4Shell::Instance->m_mapLinkAvailable = -1;
	}

}


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

void
	MWApplication::BroadcastMissionParameters()
{
	for (int i = 1; i < Maximum_Players; ++i)
	{
		Connection *connection = Network::GetInstance()->GetConnection(i);

		if(connection != NULL && i != Connection::Server->GetID())
		{
			SendMissonParameters(i);
		}
	}	
}

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

void
	MWApplication::RequestRespawnMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RequestRespawnMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);

	Verify(serverFlag);

	Verify(connection >= 0);
	Verify(connection <= Maximum_Players);
	BYTE connection_id = (BYTE)connection;



	//SPEW(("jerryeds", "REQUEST RESPAWN : %d", connection_id));


	if (servedConnectionData[connection_id].clientPlayer == NULL)
		return;

	Check_Object(servedConnectionData[connection_id].clientPlayer);

	if (!servedConnectionData[connection_id].clientPlayer->vehicle->IsDestroyed())
		return;
	
	//respawn it...


	NetMissionParameters::MWNetMissionParameters *params;	
	params = GetLocalNetParams();
	if (params->m_respawnLimit && servedConnectionData[connection_id].clientPlayer->GetVehicle()->respawnCount >= params->m_respawnLimitNumber)
	{
		if (params->m_deadMechCantSee)
		{
			Network::GetInstance()->SendNetMessage(connection_id, SwitchToCameraMessageID, NULL, true);
		}

		return;
	}
	//else
	//{
	//	servedConnectionData[connection_id].clientPlayer->GetVehicle()->respawnCount++;
	//}


	//Entity::CreateMessage *create_message = MakePlayerCreationMessage(connection_id);

	//servedConnectionData[connection_id].clientPlayer->Respawn((Adept::Player__CreateMessage*)create_message);

	//delete create_message;


	// send the message to everyone...

	DynamicMemoryStream respawn_message(256);
	respawn_message.WriteBytes(&connection_id, 1);


	Check_Object(servedConnectionData[connection_id].clientPlayer);
	ObjectID drop_zone = servedConnectionData[connection_id].clientPlayer->dropZone;
	
	Check_Object(EntityManager::GetInstance());
	DropZone *zone;
	zone = EntityManager::GetInstance()->GetDropZone(drop_zone);
	Check_Object(zone);

	Stuff::LinearMatrix4D drop_location = Stuff::LinearMatrix4D::Identity;

	drop_location = zone->RequestDrop();


	Point3D tran(drop_location);
	YawPitchRoll rot(drop_location);

	servedConnectionData[connection_id].clientPlayer->GetVehicle()->respawnCount += 1;
	int respawn_number = servedConnectionData[connection_id].clientPlayer->GetVehicle()->respawnCount;

	respawn_message.WriteBytes(&respawn_number,4);
	respawn_message.WriteBytes(&tran.x,4);
	respawn_message.WriteBytes(&tran.y,4);
	respawn_message.WriteBytes(&tran.z,4);
	respawn_message.WriteBytes(&rot.yaw,4);
	respawn_message.WriteBytes(&rot.pitch,4);
	respawn_message.WriteBytes(&rot.roll,4);

	respawn_message.Rewind();

	EntityManager::GetInstance()->SetPlayerReady(servedConnectionData[connection_id].clientPlayer->vehicle);

	for (int i = 0; i < Maximum_Players; ++i)
	{
		if(servedConnectionData[i].clientConnected && servedConnectionData[i].clientLoaded && i != Connection::Server->GetID())
		{
			Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(i,respawn_message.GetBufferBytesUsed()*8);
			Network::GetInstance()->SendNetMessage(i, RespawnMessageID, &respawn_message, true);
		}
		
	}

	RespawnMessageHandler(Connection::Server->GetID(), &respawn_message);
	respawn_message.Rewind();

	EntityManager::GetInstance()->RespawnClient(connection_id, tran);

	SendEveryoneRespawnIndex();
}

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

void
	MWApplication::RespawnMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RespawnMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	Check_Object(message);

	BYTE connection_id;
	message->ReadBytes(&connection_id, 1);

	Point3D tran;
	YawPitchRoll rot;

	int respawn_number;
	message->ReadBytes(&respawn_number,4);
	message->ReadBytes(&tran.x,4);
	message->ReadBytes(&tran.y,4);
	message->ReadBytes(&tran.z,4);
	message->ReadBytes(&rot.yaw,4);
	message->ReadBytes(&rot.pitch,4);
	message->ReadBytes(&rot.roll,4);

	LinearMatrix4D new_local_to_world;
	new_local_to_world.BuildRotation(rot);
	new_local_to_world.BuildTranslation(tran);



	//SPEW(("jerryeds","RESPAWN : %d", connection_id));

	
	if (servedConnectionData[connection_id].clientPlayer == NULL)
		return;

	Check_Object(servedConnectionData[connection_id].clientPlayer);

    if ((g_nMR == 1) && serverFlag) {
        g_MRF.SendMessage(connection_id, message, MRP_RESPAWNMESSAGEID);
    }
	servedConnectionData[connection_id].clientPlayer->GetVehicle()->respawnCount = respawn_number;

	Adept::Player__CreateMessage* create_message = (Adept::Player__CreateMessage*)MakePlayerCreationMessage(connection_id);

	servedConnectionData[connection_id].clientPlayer->Respawn(create_message);

	delete create_message;


	EntityManager::GetInstance()->SetPlayerReady(servedConnectionData[connection_id].clientPlayer->vehicle);
	
	//if (connection_id == Connection::Local->GetID())
	//{
		servedConnectionData[connection_id].clientPlayer->vehicle->SetNewLocalToParent(new_local_to_world);
		servedConnectionData[connection_id].clientPlayer->vehicle->SyncMatrices(true);
		Map::GetInstance()->UpdateZone(servedConnectionData[connection_id].clientPlayer->vehicle);
	//}


	EntityManager::GetInstance()->RespawnClient(connection_id, tran);

}


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

void MWApplication::RespawnLancemateMessageHandler(int connection,MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RespawnLancemateMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	
	Point3D tran;
	YawPitchRoll rot;
	int respawn_number;

	BYTE bot_id;
	message->ReadBytes(&bot_id, 1);

	message->ReadBytes(&respawn_number,4);
	message->ReadBytes(&tran.x,4);
	message->ReadBytes(&tran.y,4);
	message->ReadBytes(&tran.z,4);
	message->ReadBytes(&rot.yaw,4);
	message->ReadBytes(&rot.pitch,4);
	message->ReadBytes(&rot.roll,4);

	LinearMatrix4D new_local_to_world;
	new_local_to_world.BuildRotation(rot);
	new_local_to_world.BuildTranslation(tran);


	if (lancemateConnectionData[bot_id].lancemateMech == NULL)
		return;

    if ((g_nMR == 1) && serverFlag) {
        g_MRF.SendMessage(-(bot_id + 1), message, MRP_RESPAWNMESSAGEID);
    }

	lancemateConnectionData[bot_id].lancemateMech->respawnCount = respawn_number;

	Mech::CreateMessage* create_message = (Mech::CreateMessage*)this->MakeLancemateCreationMessage(bot_id);
	lancemateConnectionData[bot_id].lancemateMech->Respawn(create_message);

	lancemateConnectionData[bot_id].lancemateMech->SetNewLocalToParent(new_local_to_world);
	lancemateConnectionData[bot_id].lancemateMech->SyncMatrices(true);
	Map::GetInstance()->UpdateZone(lancemateConnectionData[bot_id].lancemateMech);

}

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

void
	MWApplication::SwitchToCameraMessage(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "SwitchToCameraMessage\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	//
	NetMissionParameters::MWNetMissionParameters *params;
	params =GetServerNetParams();

	// if dead mechs can't see and we are not the server, the only exception to the rule
	if (params->m_deadMechCantSee && !MWApplication::GetInstance()->serverFlag)
		QueStopGame();

	if (MWGUIManager::GetInstance ())
	{
		
		MWGUIManager::GetInstance()->ClearGUIChain();
		MWGUIManager::GetInstance()->InitializeNewVehicle(NULL);

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

	}
	VehicleInterface::GetInstance()->SetObservationMode();

}

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

bool crcs_stored = false;
//__int64 server_resource_date_crc = 0;
__int64 server_resource_crc = 0;
//__int64 server_executable_date_crc = 0;
__int64 server_executable_crc = 0;
__int64 server_executable_version = 0;


void
	MWApplication::RequestConnectionMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RequestConnectionMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	Check_Object(message);


	//if (!crcs_stored)
	{

		//server_resource_date_crc = ResourceManager::GetInstance()->CalculateDateCRC();
		ResourceFile *core = ResourceManager::Instance->GetResourceFile(CoreResourceFileID);
		server_resource_crc = core->CalculateCRC(Network::GetInstance()->GetServerKey());

		server_resource_crc = server_resource_crc ^ CalculateCodeHash(Network::GetInstance()->GetServerKey());

		//server_executable_date_crc = CalculateExecutableDateCRC();
		server_executable_crc = CalculateExecutableCRC();
		server_executable_version = CalculateVersionNumber();
		
		crcs_stored = true;
	}


	//__int64 resource_date_crc = 0;
	__int64 resource_crc = 0;
	//__int64 executable_date_crc = 0;
	//__int64 executable_crc = 0;
	__int64 executable_version = 0;


	//message->ReadBytes(&resource_date_crc, 8);
	message->ReadBytes(&resource_crc, 8);
	//message->ReadBytes(&executable_date_crc, 8);
	//message->ReadBytes(&executable_crc, 8);
	message->ReadBytes(&executable_version, 8);


	int error = NoError;
	int rate = 0;
	int type = 0;
	int allow_transfer = 0;
	GUID key = GUID_NULL;
	DWORD ip = 0;

	// ngLog addition
#if !defined(NO_LOG)
	GUID    playerId = GUID_NULL;
#endif // !defined(NO_LOG)



	if (server_executable_version != executable_version)
	{
		error = VersionsDoNotMatch;
	}
	else
	{


	
		message->ReadBytes(&type, 1);
		message->ReadBytes(&rate, 1);
		message->ReadBytes(&allow_transfer, 1);

	
		if (servedConnectionData[connection].clanName)
		{
			delete servedConnectionData[connection].clanName;
			servedConnectionData[connection].clanName = NULL;
		}

		Verify(servedConnectionData[connection].clanName == NULL);
		int clan_size = 0;

		message->ReadBytes(&clan_size, 4);
		servedConnectionData[connection].clanName = new char[clan_size];
		message->ReadBytes(servedConnectionData[connection].clanName, clan_size);
		servedConnectionData[connection].clanName[clan_size-1] = '\0';


		// mdm - set clan size properties for this player
		if ( gos_NetInformation(gos_AmITheServer, 0, NULL) == (void *) 1 )
		{
    		Connection * pConnectObj = Network::GetInstance()->GetConnection(connection);
    		Check_Object(pConnectObj);

			// all players are registered with ServerAdvertisers in GameOS when the dplay
			// AddPlayer message arrives.  GUN registers the player using their dplay ID
			// as their unique identifier.

			ServerAdvertiser::AdvertiseItem( pConnectObj->GetNetworkAddress(), // player ID; 0 = server
											 PLAYER_CLAN_NAME_KEY,  // key name
											 servedConnectionData[connection].clanName); // key val
		}



		// unique key
		
		message->ReadBytes(&key, 16);
		
		message->ReadBytes(&ip, 4);

		// ngLog addition
#if !defined(NO_LOG)
		message->ReadBytes(&playerId,16);
#endif // !defined(NO_LOG)


		//if (server_resource_date_crc != resource_date_crc)
		//{
		//	error = ResourcesOutOfDate;	
		//}
#if 0 // !defined(_DEBUG) // jcem
		if (server_resource_crc != resource_crc)
		{
			error = ResourcesDoNotMatch;
		}
#endif // !defined(_DEBUG)

		//if (server_executable_date_crc != executable_date_crc)
		//{
		//	error = ExecutableOutOfDate;
		//}

		//if (server_executable_crc != executable_crc)
		//{
		//	error = ExecutablesDoNotMatch;
		//}

		


		

#if !defined(NO_LOG)
		if (connection != Connection::Server->GetID() && IsPlayerBanned(key, playerId, ip))
		{
			error = BannedClient;
		}
#endif // !defined(NO_LOG)
	}

	if (error == NoError)
	{
		ResourceFile *core = ResourceManager::Instance->GetResourceFile(CoreResourceFileID);
		

		unsigned char * buff=(unsigned char *) &key;
	
		int *first_half = (int*)&buff[0];
		int *second_half = (int*)&buff[4];

		int client_key = *first_half^*second_half;

		__int64 resource_crc = core->CalculateCRC(client_key);
		resource_crc = resource_crc ^ CalculateCodeHash(client_key);

		DynamicMemoryStream stream;
		stream.WriteBytes(&resource_crc, 8);
		stream.Rewind();

		Network::GetInstance()->SendNetMessage(connection, AcceptConnectionMessageID, &stream, true);

		servedConnectionData[connection].clientConnectionRate = rate;
		servedConnectionData[connection].clientConnectionType = type;
		servedConnectionData[connection].clientAllowTransfer = allow_transfer;
		servedConnectionData[connection].clientKey = key;
		servedConnectionData[connection].clientISP = ip;
		// ngLog addition
#if !defined(NO_LOG)
		servedConnectionData[connection].ngLogID = playerId;	
#endif // !defined(NO_LOG)
		
		if (connection != Connection::Server->GetID())
			SendMissonParameters(connection);


		for (int i = 0; i < motdLength; ++i)
		{
			// send motd
			SendChat(
				Connection::Local->GetID(),
				SystemBroadcast,
				(BYTE)connection,
				motd[i]
			);
		}

		char* message = GetTeamCount();
		if (message)
		{
			SendChat(
				Connection::Local->GetID(),
				SystemBroadcast,
				(BYTE)connection,
				message);
			delete [] message;
		}

		SendPlayerClanMessage();


	}
	else
	{
		DynamicMemoryStream new_message;
		new_message.WriteBytes(&error, 4);
		new_message.Rewind();
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection,new_message.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(connection, DenyRequestConnectionMessageID, &new_message, true);

		KickPlayer(connection);

		// kick the player

		// ngLog addition
#if !defined(NO_LOG)
        MW4log_generic(MW4P_REJECT, va("Player_Reject\t%d\t%d", connection, error));
#endif // !defined(NO_LOG)
	}

}

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

void
	MWApplication::DenyRequestConnectionMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "DenyRequestConnectionMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);
	Check_Object(message);


	int error=0;
	message->ReadBytes(&error, 4);

#ifdef _ARMOR
	switch (error)
	{
	case NoError:
		STOP(("Connection Denied, no error!?!?!"));
		break;
	case ExecutableOutOfDate:
		STOP(("Executable date does not match server"));
		break;
	case ExecutablesDoNotMatch:
		STOP(("Executable does not match server"));
		break;
	case ResourcesOutOfDate:
		STOP(("Resource dates do not match server"));
		break;
	case ResourcesDoNotMatch:
		STOP(("Resources do not match server"));
		break;
	case VersionsDoNotMatch:
		STOP(("Game Version does not match servers game version"));
		break;
	case BannedClient:
		STOP(("You are banned from the server"));
	}
#endif
	switch (error)
	{
	case ExecutableOutOfDate:
	case ExecutablesDoNotMatch:
	case ResourcesOutOfDate:
	case ResourcesDoNotMatch:
	case VersionsDoNotMatch:
		networkExitCode = BadServerExitCode;
		break;
	case BannedClient:
		networkExitCode = BannedExitCode;
		break;
	}

	Check_Object(Application::GetInstance());
	Application::GetInstance()->QueStopGame(true);

}

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


void
	MWApplication::AcceptConnectionMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "AcceptConnectionMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);

	unsigned char * buff=(unsigned char *) &localKey;

	int *first_half = (int*)&buff[0];
	int *second_half = (int*)&buff[4];

	int client_key = *first_half^*second_half;

	ResourceFile *core = ResourceManager::Instance->GetResourceFile(CoreResourceFileID);
	__int64 resource_crc = core->CalculateCRC(client_key);
	resource_crc = resource_crc ^ CalculateCodeHash(client_key);

	__int64 server_crc = 0;

	message->ReadBytes(&server_crc, 8);
	if (resource_crc != server_crc)
	{

		networkExitCode = BadServerExitCode;

		#ifdef _ARMOR
			STOP(("Resources do not match server"));
		#endif

		Check_Object(Application::GetInstance());
		Application::GetInstance()->QueStopGame(true);
	}
	// if everything goes well, let's reset the last map crc
	lastMapCRC = -1;
	haveNetworkMap = true;
}

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

void
	MWApplication::SendRequestConnectionMessage()
{
	if (CTCL_IsConsole())
        return;
	DynamicMemoryStream stream;
	
	Check_Object(ResourceManager::Instance);
	
	// resource crcs
	//__int64 resource_date_crc = ResourceManager::Instance->CalculateDateCRC();
	ResourceFile *core = ResourceManager::Instance->GetResourceFile(CoreResourceFileID);
	__int64 resource_crc = core->CalculateCRC(Network::GetInstance()->GetServerKey());
	
	resource_crc = resource_crc ^ CalculateCodeHash(Network::GetInstance()->GetServerKey());

	// executable crcs
	//__int64 executable_date_crc = CalculateExecutableDateCRC();
	//__int64 executable_crc = CalculateExecutableCRC();
	__int64 executable_version = CalculateVersionNumber();

	
	
	//stream.WriteBytes(&resource_date_crc, 8);
	stream.WriteBytes(&resource_crc, 8);
	//stream.WriteBytes(&executable_date_crc, 8);
	//stream.WriteBytes(&executable_crc, 8);
	stream.WriteBytes(&executable_version, 8);

	stream.WriteBytes(&MyConnectionType, 1);
	stream.WriteBytes(&MyConnectionSpeed, 1);


//	NetMissionParameters::MWNetMissionParameters *params;
//	params = GetLocalNetParams();


	AllowDecalTransfer = 0;

	NotationFile notefile("options.ini", NotationFile::Standard, true);
	Page *page = notefile.FindPage("server");
	if (page)
	{
		page->GetEntry("allowdecaltransfer",&AllowDecalTransfer);
	}

	stream.WriteBytes(&AllowDecalTransfer, 1);




#if 0
	const char *my_clan_name = "\0";
	GUID password_guid;

	memset(&password_guid, 0, sizeof(GUID));

	NotationFile options_ini("options.ini", NotationFile::Standard, true);
	Page *page = options_ini.FindPage("Network Options");
	if (page)
	{
		page->GetEntry("TeamName", &my_clan_name);
		
		int connection = Connection::Local->GetID();
		int size = strlen(my_clan_name)+1;
		if (servedConnectionData[connection].clanName != NULL)
		{
			delete servedConnectionData[connection].clanName;
			servedConnectionData[connection].clanName = NULL;
		}
		servedConnectionData[connection].clanName = new char[size];

		strcpy(servedConnectionData[connection].clanName, my_clan_name);

		// ngLog addition
#if !defined(NO_LOG)
		MD5_CTX resource_context;
		unsigned char * buff=(unsigned char *) &password_guid;
		const char *my_password = "\0";
		const char *my_name = "\0";
		const char *my_usepassword = "\0";

		page->GetEntry("password", &my_password);
		page->GetEntry("playername", &my_name);
		page->GetEntry("usepassword", &my_usepassword);

		if(*my_usepassword && *my_usepassword != 'n' && *my_usepassword != 'N' && *my_password && *my_name) {
			MD5Init(&resource_context);
			MD5Update(&resource_context, (unsigned char *) my_name, strlen(my_name));
			MD5Update(&resource_context, (unsigned char *) my_password, strlen(my_password));
			MD5Final(buff, &resource_context);
		}
#endif // !defined(NO_LOG)
	}
#else
	char my_clan_name[64] = {0};
	GUID password_guid;

	if(MW4Shell::Instance && MW4Shell::Instance->m_optionsObject) {
		memset(&password_guid, 0, sizeof(GUID));
		if (MW4Shell::Instance->m_optionsObject->m_teamName)
		{
			if(MW4Shell::Instance->m_optionsObject->m_teamName[0])
			{
				strncpy(my_clan_name, MW4Shell::Instance->m_optionsObject->m_teamName, sizeof(my_clan_name)-1);
				my_clan_name[sizeof(my_clan_name)-1] = 0;
			}
		}
		
		int connection = Connection::Local->GetID();
		int size = strlen(my_clan_name)+1;

		if(servedConnectionData[connection].clanName != NULL) {
			delete servedConnectionData[connection].clanName;
			servedConnectionData[connection].clanName = NULL;
		}

		servedConnectionData[connection].clanName = new char[size];
		strcpy(servedConnectionData[connection].clanName, my_clan_name);

		// ngLog addition
#if !defined(NO_LOG)
		MD5_CTX resource_context;
		unsigned char *buff = (unsigned char *)&password_guid;
		char my_name[64] = {0};
		char my_pass[64] = {0};

		if(MW4Shell::Instance->m_optionsObject->m_password) {
			strncpy(my_pass, MW4Shell::Instance->m_optionsObject->m_password, sizeof(my_pass)-1);
			my_pass[sizeof(my_pass)-1] = 0;
		}

		if(MW4Shell::Instance->m_optionsObject->m_playerName) {
			strncpy(my_name, MW4Shell::Instance->m_optionsObject->m_playerName, sizeof(my_name)-1);
			my_name[sizeof(my_name)-1] = 0;
		}

		if(my_pass[0] && my_name[0]) {
			MD5Init(&resource_context);
			MD5Update(&resource_context, (unsigned char *)&my_name, strlen(my_name));
			MD5Update(&resource_context, (unsigned char *)&my_pass, strlen(my_pass));
			MD5Final(buff, &resource_context);
		}
#endif // !defined(NO_LOG)
	}
#endif

	int size = strlen(my_clan_name)+1;
	Max_Clamp(size, 255);
	stream.WriteBytes(&size,4);
	stream.WriteBytes(my_clan_name, size);


	// unique key
	GUID key = localKey;
	stream.WriteBytes(&key, 16);


	const char* player_ip =
	reinterpret_cast<const char*>(gos_NetInformation(gos_MyIPAddress,0));

	DWORD ip = 0;
	BYTE *sub_byte = (BYTE*)&ip;
	if (player_ip)
		sscanf(player_ip, "%d.%d.%d.%d", &sub_byte[0],  &sub_byte[1],  &sub_byte[2],  &sub_byte[3]);

	sub_byte[3] = 0;

	stream.WriteBytes(&ip, 4);

	// ngLog addition
//	stream.WriteBytes(&NGStatsPlayerId, 16);
#if !defined(NO_LOG)
	stream.WriteBytes(&password_guid, 16);
#endif // !defined(NO_LOG)


	stream.Rewind();


	Check_Object(Connection::Server);

	// go ahead and skip this...
	if (!serverFlag)
	{
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(Connection::Server->GetID(),stream.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestConnectionMessageID, &stream, true);
	}
	else
	{
		RequestConnectionMessageHandler(Connection::Server->GetID(), &stream);
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::VerifyAllPlayerVehicles()
{
    if (CTCL_IsConsole())
        return;
	if (!serverFlag)
		return;

	for (int connection = 0; connection < Maximum_Players; ++connection)
	{

		VerifyPlayerVehicle(connection);
	}

	for (connection = 0; connection < Maximum_Lancemates; ++connection)
	{

		VerifyLancemateVehicle(connection);
	}

	UpdateAllTeamTotalTonnages();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::ReverifyDeniedVehicles()
{
    if (CTCL_IsConsole())
        return;

	if (!serverFlag)
		return;

	for (int connection = 0; connection < Maximum_Players; ++connection)
	{
		if (!servedConnectionData[connection].clientVehicleAccepted)
			VerifyPlayerVehicle(connection);
	}

	for (connection = 0; connection < Maximum_Lancemates; ++connection)
	{
		if (!lancemateConnectionData[connection].lancemateVehicleAccepted)
			VerifyLancemateVehicle(connection);
	}

	UpdateAllTeamTotalTonnages();
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::VerifyPlayerVehicle(int connection)
{



	if (servedConnectionData[connection].clientConnected && servedConnectionData[connection].vehicleCreateMessage != NULL)
	{
		Stuff::MemoryStream *stream;
		stream = GetVehicleCreationmessage(connection);
		servedConnectionData[connection].clientVehicleAccepted = false;

		NetMissionParameters::MWNetMissionParameters *params;
		if (serverFlag && servedConnectionData[connection].pilotTeam != No_Team)
		{	
			params = GetLocalNetParams();
			params->m_teamParams[servedConnectionData[connection].pilotTeam].m_currentTotalTonnage = GetCurrentTeamTotalTonage(servedConnectionData[connection].pilotTeam);
		}

		if (VerifyPlayerVehicle(connection, stream))
		{
			Network::GetInstance()->SendNetMessage(connection, AcceptPlayerVehicleMessageID, NULL, true);
			servedConnectionData[connection].clientVehicleAccepted = true;
		}
		else
		{
			Network::GetInstance()->SendNetMessage(connection, DenyPlayerVehicleMessageID, NULL, true);
			servedConnectionData[connection].clientVehicleAccepted = false;
		}
		
		if (serverFlag && servedConnectionData[connection].pilotTeam != No_Team)
		{	
			params = GetLocalNetParams();
			params->m_teamParams[servedConnectionData[connection].pilotTeam].m_currentTotalTonnage = GetCurrentTeamTotalTonage(servedConnectionData[connection].pilotTeam);
			parametersDirty = true;
		}
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::VerifyLancemateVehicle(int connection)
{

	if (lancemateConnectionData[connection].lancemateConnected && lancemateConnectionData[connection].lancemateCreateMessage != NULL)
	{
		Stuff::MemoryStream *stream;
		stream = GetLancemateCreationMessage(connection);
		lancemateConnectionData[connection].lancemateVehicleAccepted = false;
		
		NetMissionParameters::MWNetMissionParameters *params;
		if (serverFlag && lancemateConnectionData[connection].pilotTeam != No_Team)
		{	
			params = GetLocalNetParams();
			params->m_teamParams[lancemateConnectionData[connection].pilotTeam].m_currentTotalTonnage = GetCurrentTeamTotalTonage(lancemateConnectionData[connection].pilotTeam);
		}

		if (VerifyLancemateVehicle(connection, stream))
		{
			
			lancemateConnectionData[connection].lancemateVehicleAccepted = true;
		}
		else
		{
			lancemateConnectionData[connection].lancemateVehicleAccepted = false;
		}

		if (serverFlag && lancemateConnectionData[connection].pilotTeam != No_Team)
		{	
			params = GetLocalNetParams();
			params->m_teamParams[lancemateConnectionData[connection].pilotTeam].m_currentTotalTonnage = GetCurrentTeamTotalTonage(lancemateConnectionData[connection].pilotTeam);
			parametersDirty = true;
		}
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::UnreadyPlayers()
{

	for (int connection = 0; connection < Maximum_Players; ++connection)
	{
		if (servedConnectionData[connection].clientConnected)
		{
			servedConnectionData[connection].clientReady = false;
			servedConnectionData[connection].clientQuedForLaunch = false;
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::RemovePlayersFromTeam()
{

	for (int connection = 0; connection < Maximum_Players; ++connection)
	{
		if (servedConnectionData[connection].clientConnected)
		{
			servedConnectionData[connection].pilotTeam = No_Team;
		}
	}


	for (connection = 0; connection < Maximum_Lancemates; ++connection)
	{
		if (lancemateConnectionData[connection].lancemateConnected)
		{
			lancemateConnectionData[connection].pilotTeam = No_Team;
		}
	}


}

Stuff::Scalar
	MWApplication::GetCurrentTeamTotalTonage(int team)
{
	if (!networkingFlag)
		return 0;

	if (team == No_Team)
		return 0;

	Stuff::Scalar teamTotalTonnage = 0;
	for (int connection = 0; connection < Maximum_Players; ++connection)
	{
		if (servedConnectionData[connection].clientConnected && 
			servedConnectionData[connection].clientVehicleAccepted &&
			servedConnectionData[connection].pilotTeam == team)
			teamTotalTonnage += servedConnectionData[connection].tonnage;
	}
	
	for (connection = 0; connection < Maximum_Lancemates; ++connection)
	{
		if (lancemateConnectionData[connection].lancemateConnected &&
			lancemateConnectionData[connection].lancemateVehicleAccepted &&
			lancemateConnectionData[connection].pilotTeam == team)
			teamTotalTonnage += lancemateConnectionData[connection].tonnage;
	}
	return teamTotalTonnage;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  Client Server

bool
	MWApplication::VerifyPlayerVehicle(int connection, MemoryStream *message)
{
	//Verify(serverFlag);

	if (serverFlag && connection == Connection::Server->GetID() && MechLab::Instance)
		return false;
	
	bool flag = MWEntityManager::GetInstance()->GetDirtyFlag();


	Check_Object(message);

	if (!networkingFlag)
		return true;

	// default to allowing all vehicle types

	ResourceID mech_res_id;
	bool custom  = GetMechResourceID(connection, mech_res_id, message);
	Resource mech_resource(mech_res_id);

	Connection *conn = Network::GetInstance()->GetConnection(connection);

	Verify(mech_resource.DoesResourceExist());
	ReplicatorID base_id = conn->GetNextReplicatorID();

	
	
	if (connection == Connection::Local->GetID())
	{
		lastErrorCount = 0;
		lastErrors[lastErrorCount] = NO_BUILDERROR;
	}



	if (custom && servedConnectionData[connection].customResourceCRCFail)
	{
		if (connection == Connection::Local->GetID())
		{	
			lastErrors[lastErrorCount] = UNKNOWN_BUILDERROR;
			++lastErrorCount;
		}

		return false;
	}


	Entity *entity = Entity::CreateEntity(&mech_resource, &base_id);


	NetMissionParameters::MWNetMissionParameters *params;
	
	if (serverFlag)
	{	
		params = GetLocalNetParams();
	}
	else
	{
		params = GetServerNetParams();
	}

	bool result = true;



	if (entity->GetClassID() == MechClassID)
	{
	

		Mech *mech = Cast_Object(Mech*, entity);


		int min_tonage;
		int max_tonage;
		
		DWORD allowed_mechs[2];
		DWORD allowed_beams[2];
		DWORD allowed_missiles[2];
		DWORD allowed_projectile[2];
		DWORD allowed_subsystem[2];



		if (params->m_teamAllowed)
		{
			
			if (servedConnectionData[connection].pilotTeam != No_Team)
			{
				min_tonage = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_minimumTonnage;
				max_tonage = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_maximumTonnage;

#if 0
				allowed_mechs[0] = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_allowedMech[0];
				allowed_beams[0] = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_allowedBeam[0];
				allowed_missiles[0] = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_allowedMissile[0];
				allowed_projectile[0] = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_allowedProjectile[0];
				allowed_subsystem[0] = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_allowedSubsystem[0];
				allowed_mechs[1] = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_allowedMech[1];
				allowed_beams[1] = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_allowedBeam[1];
				allowed_missiles[1] = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_allowedMissile[1];
				allowed_projectile[1] = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_allowedProjectile[1];
				allowed_subsystem[1] = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_allowedSubsystem[1];
#else
				allowed_mechs[0] = params->m_allowedMech[0];
				allowed_beams[0] = params->m_allowedBeam[0];
				allowed_missiles[0] = params->m_allowedMissile[0];
				allowed_projectile[0] = params->m_allowedProjectile[0];
				allowed_subsystem[0] = params->m_allowedSubsystem[0];

				allowed_mechs[1] = params->m_allowedMech[1];
				allowed_beams[1] = params->m_allowedBeam[1];
				allowed_missiles[1] = params->m_allowedMissile[1];
				allowed_projectile[1] = params->m_allowedProjectile[1];
				allowed_subsystem[1] = params->m_allowedSubsystem[1];
#endif


			}
			else
			{
				min_tonage = params->m_minimumTonnage;
				max_tonage = params->m_maximumTonnage;
				allowed_mechs[0] = params->m_allowedMech[0];
				allowed_beams[0] = params->m_allowedBeam[0];
				allowed_missiles[0] = params->m_allowedMissile[0];
				allowed_projectile[0] = params->m_allowedProjectile[0];
				allowed_subsystem[0] = params->m_allowedSubsystem[0];

				allowed_mechs[1] = params->m_allowedMech[1];
				allowed_beams[1] = params->m_allowedBeam[1];
				allowed_missiles[1] = params->m_allowedMissile[1];
				allowed_projectile[1] = params->m_allowedProjectile[1];
				allowed_subsystem[1] = params->m_allowedSubsystem[1];

				result = false;

				if (connection == Connection::Local->GetID())
				{	
					lastErrors[lastErrorCount] = NO_TEAM_BUILDERROR;
					++lastErrorCount;
				}

			}

		}
		else
		{
			min_tonage = params->m_minimumTonnage;
			max_tonage = params->m_maximumTonnage;
			allowed_mechs[0] = params->m_allowedMech[0];
			allowed_beams[0] = params->m_allowedBeam[0];
			allowed_missiles[0] = params->m_allowedMissile[0];
			allowed_projectile[0] = params->m_allowedProjectile[0];
			allowed_subsystem[0] = params->m_allowedSubsystem[0];

			allowed_mechs[1] = params->m_allowedMech[1];
			allowed_beams[1] = params->m_allowedBeam[1];
			allowed_missiles[1] = params->m_allowedMissile[1];
			allowed_projectile[1] = params->m_allowedProjectile[1];
			allowed_subsystem[1] = params->m_allowedSubsystem[1];

		}


		Max_Clamp(max_tonage, 100);

#if 0 // no verify - jcem		
		if (custom && params->m_onlyStockMech)
		{
			result = false;

			if (connection == Connection::Local->GetID())
			{	
				lastErrors[lastErrorCount] = NO_CUSTOM_BUILDERROR;
				++lastErrorCount;
			}

		}
#endif // no verify - jcem
		servedConnectionData[connection].tonnage = mech->GetTonage();
#if 0 // no verify - jcem
		if (mech->GetTonage() < min_tonage)
		{
			result = false;

			if (connection == Connection::Local->GetID())
			{	
				lastErrors[lastErrorCount] = UNDER_TONNAGE_BUILDERROR;
				++lastErrorCount;
			}

		}
		if (mech->GetTonage() > max_tonage)
		{
			result = false;

			if (connection == Connection::Local->GetID())
			{	
				lastErrors[lastErrorCount] = OVER_TONNAGE_BUILDERROR;
				++lastErrorCount;
			}
		}

		if (params->m_teamAllowed && servedConnectionData[connection].pilotTeam != No_Team)
		{
			Stuff::Scalar currentTotal = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_currentTotalTonnage;
			int maxTotal = params->m_teamParams[servedConnectionData[connection].pilotTeam].m_maximumTotalTonnage;
			if (mech->GetTonage() + currentTotal > maxTotal)
			{
				result = false;
				
				if (connection == Connection::Local->GetID())
				{	
					lastErrors[lastErrorCount] = OVER_TOTALTONNAGE_BUILDERROR;
					++lastErrorCount;
				}
			}
		}
#endif // no verify - jcem
		const Mech::GameModel *mech_model = mech->GetGameModel();
		servedConnectionData[connection].mechChasisID = mech_model->mechID;

#if 0 // no verify - jcem
		if (mech->GetTonage() > mech_model->maxVehicleTonnage)
		{
			result = false;

			if (connection == Connection::Local->GetID())
			{	
				lastErrors[lastErrorCount] = OVER_TONNAGE_BUILDERROR;
				++lastErrorCount;
			}
		}


		if (!CheckAllowedChasis(mech_model->mechID, allowed_mechs))
		{
			result = false;

			if (connection == Connection::Local->GetID())
			{	
				lastErrorsParameter[lastErrorCount] = mech_model->mechID;
				lastErrors[lastErrorCount] = CHASIS_BUILDERROR;
				++lastErrorCount;
			}
		}


	
		if (mech->DoesHaveLightAmp())
		{

			if (!CheckAllowedSubsystem(Sub_LightAmp, allowed_subsystem))
			{
				if (connection == Connection::Local->GetID())
				{	
					lastErrorsParameter[lastErrorCount] = Sub_LightAmp;
					lastErrors[lastErrorCount] = SUBSYTEM_BUILDERROR;
					++lastErrorCount;
				}
				result = false;
			}
		}


		if (result) //only check the weapons if you have no other errors
		{

		Stuff::ChainIteratorOf<Subsystem *> iter(&mech->subsystemsInVehicle);
		Subsystem *sub;
		
		const Subsystem::GameModel *sub_model;

		while ((sub = iter.ReadAndNext()) != NULL)
		{
			sub_model = sub->GetGameModel();
			
			if (sub_model->itemID >= FirstWeaponID && sub_model->itemID <= LastBeamID)
			{
				if (!CheckAllowedBeam(sub_model->itemID, allowed_beams))
				{
					if (connection == Connection::Local->GetID())
					{	
						lastErrorsParameter[lastErrorCount] = sub_model->itemID;
						lastErrors[lastErrorCount] = BEAM_BUILDERROR;
						++lastErrorCount;
					}

					result = false;
				}
			}
			else if (sub_model->itemID >= FirstMissileID && sub_model->itemID <= LastMissileID)
			{
				if (!CheckAllowedMissile(sub_model->itemID, allowed_missiles))
				{
					if (connection == Connection::Local->GetID())
					{	
						lastErrorsParameter[lastErrorCount] = sub_model->itemID;
						lastErrors[lastErrorCount] = MISSILE_BUILDERROR;
						++lastErrorCount;
					}
					result = false;
				}
			}
			else if (sub_model->itemID >= FirstProjectileID && sub_model->itemID <= LastProjectileID)
			{
				if (!CheckAllowedProjectile(sub_model->itemID, allowed_projectile))
				{
					if (connection == Connection::Local->GetID())
					{	
						lastErrorsParameter[lastErrorCount] = sub_model->itemID;
						lastErrors[lastErrorCount] = PROJECTILE_BUILDERROR;
						++lastErrorCount;
					}
					result = false;
				}
			}
			else if (sub_model->itemID >= FirstGenericSubsystemID && sub_model->itemID <= LastGenericSubsystemID)
			{
				if (!CheckAllowedSubsystem(sub_model->itemID, allowed_subsystem))
				{
					if (connection == Connection::Local->GetID())
					{	
						lastErrorsParameter[lastErrorCount] = sub_model->itemID;
						lastErrors[lastErrorCount] = SUBSYTEM_BUILDERROR;
						++lastErrorCount;
					}
					result = false;
				}
			}
			else if (sub_model->itemID == -1)
			{
				//s'ok for now
			}
			else
			{
				//STOP(("BAD WEAPON TYPE"));
			}
		}
      }
#endif // no verify - jcem
	}
	else if (entity->GetClassID() == ObservationVehicleClassID)
	{
		if (params->m_deadMechCantSee)
		{
			result = false;
			if (connection == Connection::Local->GetID())
			{	
				lastErrors[lastErrorCount] = NO_CAMERA_BUILDERROR;
				++lastErrorCount;
			}
		}
		else
		{
			lastErrorCount = 0;
			lastErrors[lastErrorCount] = NO_BUILDERROR;

			servedConnectionData[connection].pilotTeam = No_Team;
			servedConnectionData[connection].mechChasisID = M_CameraShip;
			result = true;
		}
	}
	else
	{
		result = false;
	}


	if (result == false)
	{
		servedConnectionData[connection].mechChasisID = EmptyMechID;
	}

	conn->DeleteChildren();

	
	
	MWEntityManager::GetInstance()->SetDirtyFlag(flag);


//#ifdef _ARMOR
//	ChainIteratorOf<MWObject*> iterator(&animationScriptsLoadQue);
//	Verify(!iterator.GetSize());
//#endif


	


	return result;
}




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

bool
	MWApplication::VerifyLancemateVehicle(int bot, MemoryStream *message)
{
	//Verify(serverFlag);

	Check_Object(message);

	if (!networkingFlag)
		return true;

	bool flag = MWEntityManager::GetInstance()->GetDirtyFlag();


	// default to allowing all vehicle types

	ResourceID mech_res_id;
	bool custom  = GetLanceMateResourceID(bot, mech_res_id, message);
	Resource mech_resource(mech_res_id);

	Connection *conn = Network::GetInstance()->GetConnection(1);

	Verify(mech_resource.DoesResourceExist());
	ReplicatorID base_id(conn->GetNextReplicatorID());

	Entity *entity = Entity::CreateEntity(&mech_resource, &base_id);


	bool result = true;

	lastBotErrorCount = 0;
	lastBotErrors[lastBotErrorCount] = NO_BUILDERROR;
	
	if (custom && lancemateConnectionData[bot].customResourceCRCFail)
	{
		lastBotErrors[lastBotErrorCount] = UNKNOWN_BUILDERROR;
		++lastBotErrorCount;
		return false;
	}




	if (entity->GetClassID() == MechClassID)
	{
		NetMissionParameters::MWNetMissionParameters *params;
		
		if (serverFlag)
		{	
			params = GetLocalNetParams();
		}
		else
		{
			params = GetServerNetParams();
		}



		int min_tonage;
		int max_tonage;
		
		DWORD allowed_mechs[2];
		DWORD allowed_beams[2];
		DWORD allowed_missiles[2];
		DWORD allowed_projectile[2];
		DWORD allowed_subsystem[2];



		if (params->m_teamAllowed)
		{
			
			if (lancemateConnectionData[bot].pilotTeam != No_Team)
			{
				min_tonage = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_minimumTonnage;
				max_tonage = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_maximumTonnage;

#if 0
				allowed_mechs[0] = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_allowedMech[0];
				allowed_beams[0] = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_allowedBeam[0];
				allowed_missiles[0] = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_allowedMissile[0];
				allowed_projectile[0] = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_allowedProjectile[0];
				allowed_subsystem[0] = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_allowedSubsystem[0];

				allowed_mechs[1] = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_allowedMech[1];
				allowed_beams[1] = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_allowedBeam[1];
				allowed_missiles[1] = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_allowedMissile[1];
				allowed_projectile[1] = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_allowedProjectile[1];
				allowed_subsystem[1] = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_allowedSubsystem[1];

#else
				allowed_mechs[0] = params->m_allowedMech[0];
				allowed_beams[0] = params->m_allowedBeam[0];
				allowed_missiles[0] = params->m_allowedMissile[0];
				allowed_projectile[0] = params->m_allowedProjectile[0];
				allowed_subsystem[0] = params->m_allowedSubsystem[0];

				allowed_mechs[1] = params->m_allowedMech[1];
				allowed_beams[1] = params->m_allowedBeam[1];
				allowed_missiles[1] = params->m_allowedMissile[1];
				allowed_projectile[1] = params->m_allowedProjectile[1];
				allowed_subsystem[1] = params->m_allowedSubsystem[1];
#endif
			}
			else
			{
				min_tonage = params->m_minimumTonnage;
				max_tonage = params->m_maximumTonnage;
				allowed_mechs[0] = params->m_allowedMech[0];
				allowed_beams[0] = params->m_allowedBeam[0];
				allowed_missiles[0] = params->m_allowedMissile[0];
				allowed_projectile[0] = params->m_allowedProjectile[0];
				allowed_subsystem[0] = params->m_allowedSubsystem[0];

				allowed_mechs[1] = params->m_allowedMech[1];
				allowed_beams[1] = params->m_allowedBeam[1];
				allowed_missiles[1] = params->m_allowedMissile[1];
				allowed_projectile[1] = params->m_allowedProjectile[1];
				allowed_subsystem[1] = params->m_allowedSubsystem[1];
				result = false;

				lastBotErrors[lastBotErrorCount] = NO_TEAM_BUILDERROR;
				++lastBotErrorCount;
			}

		}
		else
		{
			min_tonage = params->m_minimumTonnage;
			max_tonage = params->m_maximumTonnage;
			allowed_mechs[0] = params->m_allowedMech[0];
			allowed_beams[0] = params->m_allowedBeam[0];
			allowed_missiles[0] = params->m_allowedMissile[0];
			allowed_projectile[0] = params->m_allowedProjectile[0];
			allowed_subsystem[0] = params->m_allowedSubsystem[0];

			allowed_mechs[1] = params->m_allowedMech[1];
			allowed_beams[1] = params->m_allowedBeam[1];
			allowed_missiles[1] = params->m_allowedMissile[1];
			allowed_projectile[1] = params->m_allowedProjectile[1];
			allowed_subsystem[1] = params->m_allowedSubsystem[1];

		}




		Mech *mech = Cast_Object(Mech*, entity);


		Max_Clamp(max_tonage, 100);

#if 0 // no verify - jcem		
		if (custom && params->m_onlyStockMech)
		{
			result = false;
			lastBotErrors[lastBotErrorCount] = NO_CUSTOM_BUILDERROR;
			++lastBotErrorCount;
		}
#endif // no verify - jcem
		lancemateConnectionData[bot].tonnage = mech->GetTonage();
#if 0 // no verify - jcem
		if (mech->GetTonage() < min_tonage)
		{
			result = false;
			lastBotErrors[lastBotErrorCount] = UNDER_TONNAGE_BUILDERROR;
			++lastBotErrorCount;
		}
		if (mech->GetTonage() > max_tonage)
		{
			result = false;
			lastBotErrors[lastBotErrorCount] = OVER_TONNAGE_BUILDERROR;
			++lastBotErrorCount;
		}

		if (params->m_teamAllowed && lancemateConnectionData[bot].pilotTeam != No_Team)
		{
			Stuff::Scalar currentTotal = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_currentTotalTonnage;
			int maxTotal = params->m_teamParams[lancemateConnectionData[bot].pilotTeam].m_maximumTotalTonnage;
			if (mech->GetTonage() + currentTotal > maxTotal)
			{
				result = false;
				lastBotErrors[lastBotErrorCount] = OVER_TOTALTONNAGE_BUILDERROR;
				++lastBotErrorCount;
			}
		}
#endif // no verify - jcem
		const Mech::GameModel *mech_model = mech->GetGameModel();
		lancemateConnectionData[bot].mechChasisID = mech_model->mechID;

#if 0 // no verify - jcem
		if (mech->GetTonage() > mech_model->maxVehicleTonnage)
		{
			result = false;
			lastBotErrors[lastBotErrorCount] = OVER_TONNAGE_BUILDERROR;
			++lastBotErrorCount;
		}
		

		if (!CheckAllowedChasis(mech_model->mechID, allowed_mechs))
		{
			result = false;
			lastBotErrorsParameter[lastBotErrorCount] = mech_model->mechID;
			lastBotErrors[lastBotErrorCount] = CHASIS_BUILDERROR;
			++lastBotErrorCount;		
		}

		if (mech->DoesHaveLightAmp())
		{

			if (!CheckAllowedSubsystem(Sub_LightAmp, allowed_subsystem))
			{
				result = false;
				lastBotErrorsParameter[lastBotErrorCount] = mech_model->mechID;
				lastBotErrors[lastBotErrorCount] = SUBSYTEM_BUILDERROR;
				++lastBotErrorCount;
			}
		}



		Stuff::ChainIteratorOf<Subsystem *> iter(&mech->subsystemsInVehicle);
		Subsystem *sub;
		
		const Subsystem::GameModel *sub_model;

		while ((sub = iter.ReadAndNext()) != NULL)
		{
			sub_model = sub->GetGameModel();
			
			if (sub_model->itemID >= FirstWeaponID && sub_model->itemID <= LastBeamID)
			{
				if (!CheckAllowedBeam(sub_model->itemID, allowed_beams))
				{
					result = false;
					lastBotErrorsParameter[lastBotErrorCount] = sub_model->itemID;
					lastBotErrors[lastBotErrorCount] = SUBSYTEM_BUILDERROR;
					++lastBotErrorCount;
				}
			}
			else if (sub_model->itemID >= FirstMissileID && sub_model->itemID <= LastMissileID)
			{
				if (!CheckAllowedMissile(sub_model->itemID, allowed_missiles))
				{
					result = false;
					lastBotErrorsParameter[lastBotErrorCount] = sub_model->itemID;
					lastBotErrors[lastBotErrorCount] = MISSILE_BUILDERROR;
					++lastBotErrorCount;
				}
			}
			else if (sub_model->itemID >= FirstProjectileID && sub_model->itemID <= LastProjectileID)
			{
				if (!CheckAllowedProjectile(sub_model->itemID, allowed_projectile))
				{
					result = false;
					lastBotErrorsParameter[lastBotErrorCount] = sub_model->itemID;
					lastBotErrors[lastBotErrorCount] = PROJECTILE_BUILDERROR;
					++lastBotErrorCount;
				}
			}
			else if (sub_model->itemID >= FirstGenericSubsystemID && sub_model->itemID <= LastGenericSubsystemID)
			{
				if (!CheckAllowedSubsystem(sub_model->itemID, allowed_subsystem))
				{
					result = false;
					lastBotErrorsParameter[lastBotErrorCount] = sub_model->itemID;
					lastBotErrors[lastBotErrorCount] = SUBSYTEM_BUILDERROR;
					++lastBotErrorCount;
				}
			}
			else if (sub_model->itemID == -1)
			{
				//s'ok for now
			}
			else
			{
				//STOP(("BAD WEAPON TYPE"));
			}
		}
#endif // no verify - jcem
	}
	else if (entity->GetClassID() == ObservationVehicleClassID)
	{
		lancemateConnectionData[bot].mechChasisID = M_CameraShip;
		result = true;
	}
	else
	{
		result = false;
	}


	if (result == false)
	{
		lancemateConnectionData[bot].mechChasisID = EmptyMechID;
	}

	conn->DeleteChildren();

//#ifdef _ARMOR
//	ChainIteratorOf<MWObject*> iterator(&animationScriptsLoadQue);
//	Verify(!iterator.GetSize());
//#endif


	MWEntityManager::GetInstance()->SetDirtyFlag(flag);



	return result;
}



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

void
	MWApplication::SendDecalQuery(int connection)
{

	DynamicMemoryStream decal_reqeust_message;


	Stuff::SortedChainIteratorOf<DecalEntry*, int> iterator(&decalNames);
	DecalEntry *string;
	while ((string = iterator.ReadAndNext()) != NULL)
	{
		if (string->index >= 64)
		{
			int length = strlen(string->decalName);
			decal_reqeust_message.WriteBytes(&length, 1);
			decal_reqeust_message.WriteBytes(&string->index, 1);
			decal_reqeust_message.WriteBytes((char*)string->decalName, length);
		}
	}

	if (decal_reqeust_message.GetBufferBytesUsed())
	{
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection,decal_reqeust_message.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(connection, DecalLayoutMessageID, &decal_reqeust_message, true);
	}

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

void
	MWApplication::DecalLayoutMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "DecalLayoutMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	
	if (!AllowDecalTransfer)
		return;

	DynamicMemoryStream decal_reqeust_message;


	while (message->GetBytesRemaining())
	{
		int text_length = 0;
		char text[256];
		text[0] = '\0';
		message->ReadBytes(&text_length, 1);
		int id = 0;
		message->ReadBytes(&id, 1);
		if (text_length)
			message->ReadBytes(&text[0], text_length);
		text[text_length] = '\0';

//		MString decal_name;
//		decal_name = "Content\\Textures\\customdecals\\";
//		decal_name += text;
//		decal_name += ".tga";


		MString short_name = text;
		short_name.StripDirectory();

		MString transfer_decal_name;
		transfer_decal_name = "Content\\Textures\\customdecals\\transfer\\" + short_name;

		MString custom_decal_name;
		custom_decal_name = "Content\\Textures\\customdecals\\" + short_name;

		if( IsDecalOnDisk(text))
		{
			AddDecal(text, id);
		}
		else if (IsDecalOnDisk(transfer_decal_name))
		{
			AddDecal(transfer_decal_name, id);
		}
		else if (IsDecalOnDisk(custom_decal_name))
		{
			AddDecal(custom_decal_name, id);
		}
		else
		{
			decal_reqeust_message.WriteBytes(&text_length, 1);
			decal_reqeust_message.WriteBytes(&text[0], text_length);
		}

	}


	if (decal_reqeust_message.GetBufferBytesUsed())
	{
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection,decal_reqeust_message.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(connection, RequestDecalsMessageID, &decal_reqeust_message, true);
	}

}

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


void
	MWApplication::RequestDecalsMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RequestDecalsMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	
	// stop potential flood attacks.
	if (serverFlag)
	{
		
		if (!AllowDecalTransfer)
			return;
		if (!servedConnectionData[connection].clientAllowTransfer)
			return;
	}
	else
	{
		if (!AllowDecalTransfer)
			return;
	}


	DynamicMemoryStream decal_message;

	while (message->GetBytesRemaining())
	{
		int text_length = 0;
		char text[256];
		text[0] = '\0';
		message->ReadBytes(&text_length, 1);
		if (text_length)
			message->ReadBytes(&text[0], text_length);
		text[text_length] = '\0';

		MString decal_name;
		decal_name = text;
//		decal_name = "Content\\Textures\\customdecals\\";
//		decal_name += text;
//		decal_name += ".tga";



	

		if( gos_DoesFileExist(text) && gos_FileSize(text) < MaxDecalSize)
		{
			
			Stuff::FileStream test(decal_name);

			if (gos_CheckValidTGA((unsigned char *)test.GetPointer(), test.GetSize()))
			{


				decal_message.WriteBytes(&text_length,1);
				decal_message.WriteBytes(&text[0], text_length);

				int id = 0;

				if (serverFlag)
				{
					DecalEntry *decal = FindDecal(text);
					if (decal)
					{
						id = decal->index;
					}

				}
				else
				{

					const char *pilot_decal = "\0";
					NotationFile options_ini("options.ini", NotationFile::Standard, true);
					Page *page = options_ini.FindPage("Network Options");
					if (page)
					{
						page->GetEntry("PlayerIcon", &pilot_decal);
					}


					MString comp_name1 = decal_name;
					MString comp_name2 = pilot_decal;

					comp_name1.StripDirectory();
					comp_name1.StripExtension();
					comp_name2.StripDirectory();
					comp_name2.StripExtension();

					if (comp_name1 == comp_name2)
						id = 1;
					else
						id = 0;
				}

				decal_message.WriteBytes(&id, 1);


				Stuff::FileStream file_stream(decal_name);
				int file_size = file_stream.GetSize();
				decal_message.WriteBytes(&file_size, 4);

				decal_message.AllocateBytes(file_stream.GetSize());
				file_stream.ReadBytes(decal_message.GetPointer(), file_stream.GetSize());
				decal_message.AdvancePointer(file_stream.GetSize());
			}
		}

	}

	if (decal_message.GetBufferBytesUsed())
	{
		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(connection,decal_message.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(connection, DecalPayLoadMessageID, &decal_message, true);
	}
}
	
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void
	MWApplication::DecalPayLoadMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "DecalPayLoadMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...



	// if server we now have the decals from the client
	// save them and go thru the acceptance process

	// if we are client just save them off
	
	bool have_team = false;
	bool have_pilot = false;

	





	while (message->GetBytesRemaining())
	{
		int text_length = 0;
		char text[256];
		text[0] = '\0';
		message->ReadBytes(&text_length, 1);
		if (text_length)
			message->ReadBytes(&text[0], text_length);
		text[text_length] = '\0';

		int id = 0;
		message->ReadBytes(&id, 1);


		int file_size = 0;
		message->ReadBytes(&file_size, 4);

		MString decal_name;

//		decal_name = "Content\\Textures\\customdecals\\";
//		decal_name += text;
//		decal_name += ".tga";


		FileStream::IsRedirected = false;
		if (!gos_DoesFileExist("Content"))
			gos_CreateDirectory("Content");
		FileStream::IsRedirected = false;
		if (!gos_DoesFileExist("Content\\Textures"))
			gos_CreateDirectory("Content\\Textures");
		FileStream::IsRedirected = false;
		if (!gos_DoesFileExist("Content\\Textures\\customdecals"))
			gos_CreateDirectory("Content\\Textures\\customdecals");
		
		FileStream::IsRedirected = false;
		if (!gos_DoesFileExist("Content\\Textures\\customdecals\\transfer"))
			gos_CreateDirectory("Content\\Textures\\customdecals\\transfer");


		MString short_name = text;
		short_name.StripDirectory();
		
		MString real_name;
		real_name = "Content\\Textures\\customdecals\\transfer\\" + short_name;


		Stuff::FileStream file_stream(real_name, Stuff::FileStream::WriteOnly);
		file_stream.WriteBytes(message->GetPointer(), file_size);
		message->AdvancePointer(file_size);
		file_stream.Close();

		if (!serverFlag)
		{
			AddDecal(real_name, id);
		}
		else
		{
			if (id == 0)
			{
				have_team = true;
				RemoveDecal(servedConnectionData[connection].teamDecals);
				servedConnectionData[connection].teamDecals = AddDecal(text);
			}
			if (id == 1)
			{
				have_pilot = true;
				RemoveDecal(servedConnectionData[connection].pilotDecals);
				servedConnectionData[connection].pilotDecals = AddDecal(text);
			}
		}
	}



	if (serverFlag)
	{
		if (have_team && have_pilot)
		{
			VerifyPlayerVehicle(connection);
		}
	}
	
}


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


void
	MWApplication::LobbyStatusMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "LobbyStatusMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	int player_count = 0; // jcem: critical error - should clear before ReadBits(...)...

	message->ReadBit(lockTimer);
	message->ReadBits(&lockTimerVal,32);
	
	message->ReadBit(gameTimer);
	message->ReadBits(&gameTimerVal,32);
	
	message->ReadBit(recycleTimer);
	message->ReadBits(&recycleTimerVal,32);


	message->ReadBits(&player_count,8);

	for (int i = 0; i < player_count; ++i)
	{
		int connection = 0;	
		message->ReadBits(&connection, 8);
		message->ReadBits(&servedConnectionData[connection].mechChasisID, 8);
		message->ReadBit(servedConnectionData[connection].clientReady);
		message->ReadBit(servedConnectionData[connection].clientLaunched);
		message->ReadBits(&servedConnectionData[connection].pilotTeam, 4);
		BYTE skin = 0;
		message->ReadBits(&skin, 8);
		
		// don't set our own skin.
		if (connection != Connection::Local->GetID())
		{
			servedConnectionData[connection].pilotSkins = (char)skin;
		}
	}

	for (i = 0; i < Maximum_Lancemates; ++i)
	{
		lancemateConnectionData[i].lancemateConnected = false;
	}

	while (message->GetBytesRemaining())
	{
		message->ReadBits(&i, 8);
		lancemateConnectionData[i].lancemateConnected = true;
		message->ReadBits(&lancemateConnectionData[i].mechChasisID, 8);
		message->ReadBit(lancemateConnectionData[i].lancemateVehicleAccepted);
		message->ReadBits(&lancemateConnectionData[i].pilotTeam, 4);
		
		message->ReadByteAlign();
		int name_size=0;
		message->ReadBytes(&name_size,4);
		message->ReadBytes(&lancemateConnectionData[i].lancemateName,name_size);

		message->ReadByteAlign();
		message->ReadBytes(&name_size,4);
		message->ReadBytes(&lancemateConnectionData[i].lancemateClan,name_size);
	}

	for (i = 0; i < Maximum_Lancemates; ++i)
	{
		if (!lancemateConnectionData[i].lancemateConnected)
		{
			lancemateConnectionData[i].Disconnect();
		}
	}

}

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

void
	MWApplication::SendLobbyStatus()
{
	

	if (!networkingFlag)
		return;

	DynamicMemoryStream stream;


	stream.WriteBit(lockTimer);
	stream.WriteBits(&lockTimerVal,32);
	
	stream.WriteBit(gameTimer);
	stream.WriteBits(&gameTimerVal,32);
	
	stream.WriteBit(recycleTimer);
	stream.WriteBits(&recycleTimerVal,32);


	int conneciton_count = Network::GetInstance()->GetPlayerCount();
	stream.WriteBits(&conneciton_count, 8);

	for (int i = 0; i < Maximum_Players; ++i)
	{
		if (servedConnectionData[i].clientConnected)
		{
			stream.WriteBits(&i, 8);
			stream.WriteBits(&servedConnectionData[i].mechChasisID, 8);
			stream.WriteBit(servedConnectionData[i].clientReady);
			stream.WriteBit(servedConnectionData[i].clientLaunched);
			stream.WriteBits(&servedConnectionData[i].pilotTeam, 4);
			stream.WriteBits(&servedConnectionData[i].pilotSkins, 8);

		}
	}


	for (i = 0; i < Maximum_Lancemates; ++i)
	{
		if (lancemateConnectionData[i].lancemateConnected)
		{
			stream.WriteBits(&i, 8);
			stream.WriteBits(&lancemateConnectionData[i].mechChasisID, 8);
			stream.WriteBit(&lancemateConnectionData[i].lancemateVehicleAccepted);
			stream.WriteBits(&lancemateConnectionData[i].pilotTeam, 4);
			
			stream.WriteByteAlign();
			int name_size = strlen(lancemateConnectionData[i].lancemateName)+1;
			stream.WriteBytes(&name_size,4);
			stream.WriteBytes(&lancemateConnectionData[i].lancemateName,name_size);

			stream.WriteByteAlign();
			name_size = strlen(lancemateConnectionData[i].lancemateClan)+1;
			stream.WriteBytes(&name_size,4);
			stream.WriteBytes(&lancemateConnectionData[i].lancemateClan,name_size);

		}
	}





	if (stream.GetBufferBytesUsed())
	{
		for (int i = 0; i < Maximum_Players; ++i)
		{
			// only send this to lobby players...
			if(servedConnectionData[i].clientConnected && !servedConnectionData[i].clientLaunched && i != Connection::Server->GetID())
			{
				Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(i,stream.GetBufferBytesUsed()*8);
				Network::GetInstance()->SendNetMessage(i, LobbyStatusMessageID, &stream, true);
			}
		}
	}


}

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


void
	MWApplication::PlayerClanMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "PlayerClanMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...


	while (message->GetBytesRemaining())
	{
		BYTE connection = 0;	
		message->ReadBytes(&connection, 1);
		int size = 0;
		message->ReadBytes(&size, 4);

		if (servedConnectionData[connection].clanName != NULL)
		{
			delete servedConnectionData[connection].clanName;
			servedConnectionData[connection].clanName = NULL;
		}

		if (size)
		{
			servedConnectionData[connection].clanName = new char[size];
			message->ReadBytes(&servedConnectionData[connection].clanName[0], size);
		}
	}

}

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

void
	MWApplication::SendPlayerClanMessage()
{
	
	DynamicMemoryStream stream;


	for (int i = 0; i < Maximum_Players; ++i)
	{
		if (servedConnectionData[i].clientConnected)
		{
			stream.WriteBytes(&i, 1);
			
			if (servedConnectionData[i].clanName != NULL)
			{
				int size = strlen(servedConnectionData[i].clanName)+1;
				stream.WriteBytes(&size, 4);
				stream.WriteBytes(&servedConnectionData[i].clanName[0], size);
			}
			else
			{
				int size = 0;
				stream.WriteBytes(&size, 4);
			}
		}
	}

	if (stream.GetBufferBytesUsed())
	{
		for (int i = 0; i < Maximum_Players; ++i)
		{
			// only send this to lobby players...
			if(servedConnectionData[i].clientConnected && i != Connection::Server->GetID())
			{
				Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(i,stream.GetBufferBytesUsed()*8);
				Network::GetInstance()->SendNetMessage(i, PlayerClanMessageID, &stream, true);
			}
		}
	}

}


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

void
	MWApplication::RequestTeamMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RequestTeamMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...


	NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();
	if (params->m_teamAllowed)
	{
		int team_request = 0;
		message->ReadBytes(&team_request, 1);

		if (team_request == servedConnectionData[connection].pilotTeam)
			return;

		// see if there is room on that team...
		//
		//
		if (servedConnectionData[connection].mechChasisID == M_CameraShip)
		{
			servedConnectionData[connection].pilotTeam = No_Team;
		}
		if (team_request == No_Team)
		{
			servedConnectionData[connection].pilotTeam = team_request;
		}
		else
		{
			if (team_request >= params->m_teamCount)
				return;

			int amount_on_requested_team = 0;
			for (int i = 0; i < Maximum_Players; ++i)
			{
				if (servedConnectionData[i].clientConnected && servedConnectionData[i].pilotTeam == team_request)
				{
					++amount_on_requested_team;
				}
			}

			for (i = 0; i < Maximum_Lancemates; ++i)
			{
				if (lancemateConnectionData[i].lancemateConnected && lancemateConnectionData[i].pilotTeam == team_request)
				{
					++amount_on_requested_team;
				}
			}


			if ((amount_on_requested_team + 1) <= params->m_teamParams[team_request].m_maxPlayersOnTeam)
			{
				servedConnectionData[connection].pilotTeam = team_request;
				
				// Verify his vehicle on the new team...
				servedConnectionData[connection].clientVehicleAccepted = false;
				ReverifyDeniedVehicles();
				VerifyPlayerVehicle(connection);
			}
		}
		
		// update everybody's status
		SendLobbyStatus();

		// send a tally on team members to everyone
		char* message = GetTeamCount();
		if (message)
		{
			SendChat(
				Connection::Local->GetID(),
				SystemBroadcast,
				0,
				message);
			delete [] message;
		}
	}
}

char*
	MWApplication::GetTeamCount()
{		
	char* message = NULL;

	if (serverFlag)
	{	
		NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();
		if (params->m_teamAllowed)
		{
			int team_count[8];
			for (int i = 0; i < 8; i++)
				team_count[i] = 0;

			for (i = 0; i < Maximum_Players; ++i)
			{
				if (servedConnectionData[i].clientConnected && servedConnectionData[i].pilotTeam != No_Team)
				{
					team_count[servedConnectionData[i].pilotTeam]++;				
				}
			}

			for (i = 0; i < Maximum_Lancemates; ++i)
			{
				if (lancemateConnectionData[i].lancemateConnected && lancemateConnectionData[i].pilotTeam != No_Team)
				{
					team_count[lancemateConnectionData[i].pilotTeam]++;
				}
			}

			// send an update of team member count to everyone
			message = new char[256];
			message[0] = '\0';
			int message_len = 0;
			char* team_count_str = GetLocString(IDS_MP_TEAMCOUNT);
			int team_count_len = strlen(team_count_str);
			for (i = 0; i < 8; i++)
			{
				if (team_count[i])
				{
					if (message_len != 0)
					{
						message[message_len] = ';';
						message_len++;
						message[message_len] = ' ';
						message_len++;
						message[message_len] = '\0';
					}
					Str_Cat(message, (const char*)team_count_str, 256);
					message_len += team_count_len;
					message[message_len] = ' ';
					message_len++;
					message[message_len] = (unsigned char)(48 + i + 1);
					message_len++;
					message[message_len] = ' ';
					message_len++;
					message[message_len] = '(';
					message_len++;
					if (team_count[i] > 9)
					{
						message[message_len] = (unsigned char)(48 + team_count[i] / 10);
						message_len++;
						message[message_len] = (unsigned char)(48 + team_count[i] % 10);
						message_len++;
					}
					else
					{
						message[message_len] = (unsigned char)(48 + team_count[i]);
						message_len++;
					}
					message[message_len] = ')';
					message_len++;

				}
			}

			if (message_len != 0)
			{
				message[message_len] = '.';
				message[message_len + 1] = '\0';
			}
			else
			{
				delete [] message;
				message = NULL;
			}
		}
	}

	return message;
}


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


void
	MWApplication::SendTeamRequest(int team)
{
	DynamicMemoryStream stream;

	NetMissionParameters::MWNetMissionParameters *params;
	if (serverFlag)
		params = GetLocalNetParams();
	else
		params = GetServerNetParams();

	if (params->m_teamAllowed)
	{

		if (team == servedConnectionData[Connection::Local->GetID()].pilotTeam)
			return;

		if (serverFlag) {
			// server has to update the team right away so that 
			// total team tonnages will be computed correctly and 
			// sent out to clients immediately
			servedConnectionData[Connection::Local->GetID()].pilotTeam = team;
		}
		else {
			// client will wait for server to update the team id
			servedConnectionData[Connection::Local->GetID()].pilotTeam = No_Team;
		}

		stream.WriteBytes(&team, 1);

		Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(Connection::Server->GetID(),stream.GetBufferBytesUsed()*8);
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), RequestTeamMessageID, &stream, true);
	

	}

}


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


int
	MWApplication::CheckAllowedChasis(int type, DWORD allowed_flags[2])
{
	int offset = type - FirstMechID;
	
	
	Verify(offset < 64);
	Verify(offset >= 0);

	if (offset < 0)
		return false;
	if (offset >= 64)
		return false;


	DWORD *data;
	if (offset >= 32)
	{
		offset -= 32;
		data = &allowed_flags[1];
	}
	else
	{	
		data = &allowed_flags[0];
	}

	return *data & (0x1 << offset);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MWApplication::CheckAllowedBeam(int type, DWORD allowed_flags[2])
{
	int offset = type - FirstBeamID;
	
	Verify(offset < 64);
	Verify(offset >= 0);

	if (offset < 0)
		return false;
	if (offset >= 64)
		return false;
	
	DWORD *data;
	if (offset >= 32)
	{
		offset -= 32;
		data = &allowed_flags[1];
	}
	else
	{	
		data = &allowed_flags[0];
	}

	return *data & (0x1 << offset);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MWApplication::CheckAllowedMissile(int type, DWORD allowed_flags[2])
{
	int offset = type - FirstMissileID;
	
	Verify(offset < 64);
	Verify(offset >= 0);

	if (offset < 0)
		return false;
	if (offset >= 64)
		return false;

	DWORD *data;
	if (offset >= 32)
	{
		offset -= 32;
		data = &allowed_flags[1];
	}
	else
	{	
		data = &allowed_flags[0];
	}

	return *data & (0x1 << offset);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MWApplication::CheckAllowedProjectile(int type, DWORD allowed_flags[2])
{
	int offset = type - FirstProjectileID;
	
	Verify(offset < 64);
	Verify(offset >= 0);

	if (offset < 0)
		return false;
	if (offset >= 64)
		return false;

	
	DWORD *data;
	if (offset >= 32)
	{
		offset -= 32;
		data = &allowed_flags[1];
	}
	else
	{	
		data = &allowed_flags[0];
	}

	return *data & (0x1 << offset);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MWApplication::CheckAllowedSubsystem(int type, DWORD allowed_flags[2])
{
	int offset = type - FirstGenericSubsystemID;
	
	Verify(offset < 64);
	Verify(offset >= 0);

	if (offset < 0)
		return false;
	if (offset >= 64)
		return false;

	
	DWORD *data;
	if (offset >= 32)
	{
		offset -= 32;
		data = &allowed_flags[1];
	}
	else
	{	
		data = &allowed_flags[0];
	}

	return *data & (0x1 << offset);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::SetVehicleCreationMessage(int player_id, MemoryStream *vehicle_message)
{
	//Verify(serverFlag);
	Verify(player_id >= 0 && player_id < Maximum_Players);
	Check_Object(vehicle_message);

	if (servedConnectionData[player_id].vehicleCreateMessage != NULL)
	{
		servedConnectionData[player_id].vehicleCreateMessage->Rewind();
		BYTE *data = (BYTE*)servedConnectionData[player_id].vehicleCreateMessage->GetPointer();
		delete[] data;
		
		Check_Object(servedConnectionData[player_id].vehicleCreateMessage);
		delete servedConnectionData[player_id].vehicleCreateMessage;

		servedConnectionData[player_id].vehicleCreateMessage = NULL;
	}

	if (servedConnectionData[player_id].clientCustomResource != NULL)
	{
		delete servedConnectionData[player_id].clientCustomResource;
		servedConnectionData[player_id].clientCustomResource = NULL;
	}

	
	BYTE *message_buffer = new(MechWarrior4::Heap) BYTE[vehicle_message->GetSize()];
	Register_Pointer(message_buffer);

	servedConnectionData[player_id].vehicleCreateMessage = new MemoryStream(message_buffer, vehicle_message->GetSize());
	servedConnectionData[player_id].vehicleCreateMessage->WriteBytes(vehicle_message->GetPointer(), vehicle_message->GetSize());
	servedConnectionData[player_id].vehicleCreateMessage->Rewind();

	DWORD crc = 0;
	for (int i = 0; i < servedConnectionData[player_id].vehicleCreateMessage->GetSize(); ++i)
	{
		BYTE data;
		servedConnectionData[player_id].vehicleCreateMessage->ReadBytes(&data, 1);
		crc += data;
	}
	servedConnectionData[player_id].vehicleCreateMessage->Rewind();
	//SPEW(("jerryeds", "SETVEH CRC %d : %x : %d", player_id, crc, vehicleCreateMessage[player_id]->GetSize()));
}

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

void
	MWApplication::ClearVehicleCreationMessage(int player_id)
{
	//Verify(serverFlag);
	Verify(player_id >= 0 && player_id < Maximum_Players);

	if (servedConnectionData[player_id].vehicleCreateMessage != NULL)
	{
		servedConnectionData[player_id].vehicleCreateMessage->Rewind();
		BYTE *data = (BYTE*)servedConnectionData[player_id].vehicleCreateMessage->GetPointer();
		delete[] data;
		
		Check_Object(servedConnectionData[player_id].vehicleCreateMessage);
		delete servedConnectionData[player_id].vehicleCreateMessage;

		servedConnectionData[player_id].vehicleCreateMessage = NULL;
	}

	if (servedConnectionData[player_id].clientCustomResource != NULL)
	{
		delete servedConnectionData[player_id].clientCustomResource;
		servedConnectionData[player_id].clientCustomResource = NULL;
	}


}

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

Stuff::MemoryStream *
	MWApplication::GetVehicleCreationmessage(int player_id)
{
	//Verify(serverFlag);
	Verify(player_id >= 0 && player_id < Maximum_Players);
	//Verify(servedConnectionData[player_id].clientVehicleAccepted);

	if (servedConnectionData[player_id].vehicleCreateMessage==NULL)
		return GetBRBVehicleCreationmessage(player_id);

	servedConnectionData[player_id].vehicleCreateMessage->Rewind();

	Check_Object(servedConnectionData[player_id].vehicleCreateMessage);
	return servedConnectionData[player_id].vehicleCreateMessage;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
	MWApplication::SetLancemateCreationMessage(int lancemate_index, Stuff::MemoryStream* lancemate_message)
{
	if (lancemateConnectionData[lancemate_index].lancemateCreateMessage != NULL)
	{
		lancemateConnectionData[lancemate_index].lancemateCreateMessage->Rewind();
		BYTE *data = (BYTE*)lancemateConnectionData[lancemate_index].lancemateCreateMessage->GetPointer();
		delete[] data;
		
		Check_Object(lancemateConnectionData[lancemate_index].lancemateCreateMessage);
		delete lancemateConnectionData[lancemate_index].lancemateCreateMessage;

		lancemateConnectionData[lancemate_index].lancemateCreateMessage = NULL;
	}

	if (lancemateConnectionData[lancemate_index].lancemateCustomResource != NULL)
	{
		delete lancemateConnectionData[lancemate_index].lancemateCustomResource;
		lancemateConnectionData[lancemate_index].lancemateCustomResource = NULL;
	}

	BYTE* message_buffer = new(MechWarrior4::Heap) BYTE[lancemate_message->GetSize()];
	Register_Pointer(message_buffer);

	lancemateConnectionData[lancemate_index].lancemateCreateMessage = new MemoryStream(message_buffer, lancemate_message->GetSize());
	lancemateConnectionData[lancemate_index].lancemateCreateMessage->WriteBytes(lancemate_message->GetPointer(),lancemate_message->GetSize());
	lancemateConnectionData[lancemate_index].lancemateCreateMessage->Rewind();

	DWORD crc = 0;
	for (int i = 0; i < lancemateConnectionData[lancemate_index].lancemateCreateMessage->GetSize(); ++i)
	{
		BYTE data;
		lancemateConnectionData[lancemate_index].lancemateCreateMessage->ReadBytes(&data, 1);
		crc += data;
	}
	lancemateConnectionData[lancemate_index].lancemateCreateMessage->Rewind();
	//SPEW(("jerryeds", "LANCEMATECREATE CRC %d : %x : %d", lancemate_index, crc, lancemateCreateMessage[lancemate_index]->GetSize()));
}

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

Stuff::MemoryStream*
	MWApplication::GetLancemateCreationMessage(int lancemate_index)
{
	Verify(lancemate_index >= 0 && lancemate_index < Maximum_Lancemates);

	lancemateConnectionData[lancemate_index].lancemateCreateMessage->Rewind();

	Check_Object(lancemateConnectionData[lancemate_index].lancemateCreateMessage);
	return lancemateConnectionData[lancemate_index].lancemateCreateMessage;
}

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

void
	MWApplication::SetMissionName(const char *name)
{
	Verify(serverFlag);
	Check_Pointer(name);

	missionReady = true;

	missionName = new(MechWarrior4::Heap) char[strlen(name)+1];

	Str_Copy(missionName, name, strlen(name)+1);

	Register_Pointer(missionName);

}

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

const char *
	MWApplication::GetMissionName()
{
	Verify(serverFlag);
	Verify(missionReady);

	Check_Pointer(missionName);
	return missionName;
}


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

void
	MWApplication::SquelchPlayer(int connection_id)
{
	servedConnectionData[connection_id].clientSquelched = !servedConnectionData[connection_id].clientSquelched;
}

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

void
	MWApplication::KickPlayer(int connection_id, bool print_msg)
{
	if (print_msg)
	{
		char kicked_str[512];
		Str_Copy(kicked_str, servedConnectionData[connection_id].pilotName, 512);
		int kicked_len = strlen(kicked_str);
		kicked_str[kicked_len] = ' ';
		kicked_str[kicked_len + 1] = '\0';
		Str_Cat(kicked_str, GetLocString(IDS_KICKED), 512);
		SendChat(Connection::Local->GetID(), SystemBroadcast, 0, kicked_str);
	}

	Network::GetInstance()->SendNetMessage(connection_id, KickPlayerMessageID, NULL, true);


	Connection *con = Network::GetInstance()->GetConnection(connection_id);
	gos_NetServerCommands(gos_Command_KillPlayer, (DWORD)con->GetNetworkAddress());

	//servedConnectionData[connection_id].Disconnect();
	Network::GetInstance()->RemovePlayer(connection_id);

	ReverifyDeniedVehicles();
}

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

void
	MWApplication::BanPlayer(int connection_id)
{
	char banned_str[512];
	Str_Copy(banned_str, servedConnectionData[connection_id].pilotName, 512);
	int banned_len = strlen(banned_str);
	banned_str[banned_len] = ' ';
	banned_str[banned_len + 1] = '\0';
	Str_Cat(banned_str, GetLocString(IDS_BANNED), 512);
	SendChat(Connection::Local->GetID(), SystemBroadcast, 0, banned_str);

	// write down the info to disable him from returning...

	NotationFile key_ban("ban.txt");
	

#if !defined(NO_LOG)
	if (servedConnectionData[connection_id].ngLogID != GUID_NULL)
	{
		Page *page = key_ban.FindPage("ngban");
		if (page == NULL)
		{
			page = key_ban.AddPage("ngban");
		}

		char buffer[256];

		
		int *print_byte = (int*)&servedConnectionData[connection_id].ngLogID;
		sprintf(buffer, "%d.%d.%d.%d", print_byte[0],  print_byte[1],  print_byte[2], print_byte[3]);

		page->AppendEntry("ngban" , buffer);
	}
#endif // !defined(NO_LOG)


	Page *page = key_ban.FindPage("ban");
	if (page == NULL)
	{
		page = key_ban.AddPage("ban");
	}

	char buffer[256];

	
	int *print_byte = (int*)&servedConnectionData[connection_id].clientKey;
	sprintf(buffer, "%d.%d.%d.%d", print_byte[0],  print_byte[1],  print_byte[2], print_byte[3]);
	page->AppendEntry("ban" , buffer);

	key_ban.Save();

	LoadBans();

	KickPlayer(connection_id, false);
}

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

void
	MWApplication::BanPlayersISP(int connection_id)
{
	char banned_str[512];
	Str_Copy(banned_str, servedConnectionData[connection_id].pilotName, 512);
	int banned_len = strlen(banned_str);
	banned_str[banned_len] = ' ';
	banned_str[banned_len + 1] = '\0';
	Str_Cat(banned_str, GetLocString(IDS_BANNED), 512);
	SendChat(Connection::Local->GetID(), SystemBroadcast, 0, banned_str);

	// write down the info to disable him from returning...
	
	NotationFile key_ban("ban.txt");

	Page *page = key_ban.FindPage("ispban");
	if (page == NULL)
	{
		page = key_ban.AddPage("ispban");
	}

	char buffer[256];

	BYTE *print_byte = (BYTE*)&servedConnectionData[connection_id].clientISP;
	sprintf(buffer, "%d.%d.%d.%d", print_byte[0],  print_byte[1],  print_byte[2],  print_byte[3]);

	page->AppendEntry("ispban" , buffer);


	key_ban.Save();

	LoadBans();

	KickPlayer(connection_id, false);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


void MWApplication::LoadBans()
{
	
	ngLogBanCount = 0;
	keyBanCount = 0;
	ispBanCount = 0;

    if (ngLogBans != NULL) {
		delete[] ngLogBans;
		ngLogBans = NULL;
    }
    if (keyBans != NULL) {
		delete[] keyBans; // org ocde error
		keyBans = NULL;
    }
    if (ispBans != NULL) {
		delete[] ispBans; // org ocde error
		ispBans = NULL;
    }

    if (!CTCL_IsNone()) { // jcem
        return;
    }

	NotationFile key_ban("ban.txt");
	
	Page *page = key_ban.FindPage("ngban");
	if (page != NULL)
	{

		ChainIteratorOf<Note*> *note_iterator = page->MakeNoteIterator();

		int size = note_iterator->GetSize();

		if (size)
		{
			ngLogBanCount = size;
			ngLogBans = new GUID[size];
			int i = 0;
			Note *note;
			while ((note = note_iterator->ReadAndNext()) != NULL)
			{
				ngLogBans[i] = GUID_NULL;
				int *print_byte = (int*)&ngLogBans[i];
				const char *text;
				note->GetEntry(&text);
				sscanf(text, "%d.%d.%d.%d", &print_byte[0],  &print_byte[1],  &print_byte[2],  &print_byte[3]);
				++i;
			}
		}
	}
		
	page = key_ban.FindPage("ban");
	if (page != NULL)
	{
		ChainIteratorOf<Note*> *note_iterator = page->MakeNoteIterator();

		int size = note_iterator->GetSize();

		if (size)
		{
			keyBanCount = size;
			keyBans = new GUID[size];
			int i = 0;
			Note *note;
			while ((note = note_iterator->ReadAndNext()) != NULL)
			{
				keyBans[i] = GUID_NULL;
				int *print_byte = (int*)&keyBans[i];
				const char *text;
				note->GetEntry(&text);
				sscanf(text, "%d.%d.%d.%d", &print_byte[0],  &print_byte[1],  &print_byte[2],  &print_byte[3]);
				++i;
			}
		}
	}


	page = key_ban.FindPage("ispban");
	if (page != NULL)
	{
		ChainIteratorOf<Note*> *note_iterator = page->MakeNoteIterator();

		int size = note_iterator->GetSize();

		if (size)
		{
			ispBanCount = size;
			ispBans = new DWORD[size];
			int i = 0;
			Note *note;
			while ((note = note_iterator->ReadAndNext()) != NULL)
			{
				BYTE *print_byte = (BYTE*)&ispBans[i];
				const char *text;
				note->GetEntry(&text);
				sscanf(text, "%d.%d.%d.%d", &print_byte[0],  &print_byte[1],  &print_byte[2],  &print_byte[3]);
				++i;
			}
		}
	}

}


#if !defined(NO_MR)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void MWApplication::SetMissionReviewWeaponFired(int player)
{
	if (m_recordLog && m_recordLog->m_mode == MissionReview::RecordMode)
	{
		m_recordLog->m_playerData[player].m_firedWeapon = true;
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void MWApplication::SetMissionReviewTakeDamage(int player)
{

	if (m_recordLog && m_recordLog->m_mode == MissionReview::RecordMode)
	{
		m_recordLog->m_playerData[player].m_takenDamage = true;
	}
}
#endif // !defined(NO_MR)


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

void
	MWApplication::MissionReviewAvailableMessageHandler(int connection, Stuff::MemoryStream *message)
{
	//SPEW(("jerryeds", "REC - MISSION REVIEW AVAILABLE"));
#if !defined(NO_MR)
	missionReviewAvailable = true;
#endif // !defined(NO_MR)
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#if !defined(NO_MR)


void
	MWApplication::RespawnFlagsMessageHandler(int connection, Stuff::MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RespawnFlagsMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	NameTable *table = NameTable::GetInstance();
	int size(table->nameTableArray[NameTable::FlagArray].GetLength());

	{for (int i = 0;
		  i < size;
		  ++i)
	{
		NameTableEntry *data;

		data = &table->nameTableArray [NameTable::FlagArray][i];
		Adept::Entity* ent = data->dataPointer->GetCurrent ();

		if ((ent != 0) ||
			(ent->IsDerivedFrom(Flag::DefaultData) == true))
		{
			ent->Respawn(0);
		}
	}}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
	MWApplication::RequestMissionReviewMessageHandler(int connection, Stuff::MemoryStream *message)
{

	Verify(serverFlag);

#if !defined(NO_MR)
	if (reviewPackets && totalReviewPackets)
	{
		servedConnectionData[connection].clientStreamingReview = true;
		servedConnectionData[connection].nextReviewPacket = 0;
	}
	else
	{
		Network::GetInstance()->SendNetMessage(connection, CancelMissionReviewMessageID, NULL, true);
	}
#endif // !defined(NO_MR)

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


void
	MWApplication::CancelMissionReviewMessageHandler(int connection, Stuff::MemoryStream *message)
{
	
#if !defined(NO_MR)
	if (serverFlag)
	{
		servedConnectionData[connection].clientStreamingReview = false;
	}
	else
	{
		// Kill mission review...
		
	}
#endif // !defined(NO_MR)
	
}

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

void
	MWApplication::MissionReviewPartMessageHandler(int connection, Stuff::MemoryStream *message)
{
	Verify(!serverFlag);
#if !defined(NO_MR)
	Verify (m_playLog);

	if (m_playLog)
	{
		m_playLog->AddPartToLogBuffer(message);
	}
	//else we are receiving a late mr packet and just don't care.
#endif // !defined(NO_MR)
	
}


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


#ifdef HACKER_COMMENT
// keys are stored in these files...

// this is the dummy key.  Just fill it in and let the hackers find it
// it won't do a damn thing.
//	Misc\UniquePlayerKey.data

//  3rd bytes holds the which of the resources the unique key is in
//	Mechs\Atlas\atlas.animskript


//  these are the three resources which could hold the key
//	Mechs\Hellspawn\animation\hs_walkKUP.mw4anim
//	Vehicles \APC\APC.kbb
//	Vehicles\Transport_Destroyed\Transpork_Destoryed.instance

// the text is stored in the binary encrypted so that it is not easily seen in the string table
// by browsing the binary of the executable.
//  decode text key is 179

#endif


GUID
	MWApplication::GetUniqueKey()
{




	GUID test_key = GUID_NULL;
	DWORD size = 16;
	gos_LoadDataFromRegistry("settings",&test_key,&size);

	if (size > 0)
	{
		return test_key;
	}


	test_key = gos_GenerateUniqueGUID();
		
	gos_SaveDataToRegistry("settings",&test_key, 16);
	

#ifdef _ARMOR

	{
		GUID armor_check = GUID_NULL;
		DWORD size = 16;
		gos_LoadDataFromRegistry("settings",&armor_check,&size);

		Verify(armor_check == test_key);
	}

#endif
		
	return test_key;
}

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

bool
	MWApplication::IsPlayerBanned(const GUID& unique_key, const GUID& ngstat_id, DWORD isp)
{

	if (ngstat_id != GUID_NULL)
	{
		for (int i = 0; i < ngLogBanCount; ++i)
		{
			if (ngstat_id == ngLogBans[i])
				return true;
		}
	}

	for (int i = 0; i < keyBanCount; ++i)
	{
		if (unique_key == keyBans[i])
			return true;
	}

	for (i = 0; i < ispBanCount; ++i)
	{
		if (isp == ispBans[i])
			return true;
	}


	return false;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
char *
	MWApplication::GetLocString(int index)
{
	Check_Object(this);
	Verify(langResources);

	return gos_GetResourceString(langResources, index);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::LoadLookupTables()
{
	Check_Object(this);
	
	Resource mech_table("Tables\\MechTable.tbl");
	mech_table.LoadData();
	if(mech_table.DoesResourceExist())
	{
		if(m_mechTable)
		{
			delete m_mechTable;
			m_mechTable = NULL;
		}
		m_mechTable = new MWTable(&mech_table);
	}
	
	Resource sub_table("Tables\\SubsystemTable.tbl");
	sub_table.LoadData();
	if(sub_table.DoesResourceExist())
	{
		if(m_subsystemTable)
		{
			delete m_subsystemTable;
			m_subsystemTable = NULL;
		}
		m_subsystemTable = new MWTable(&sub_table);
	}

	Resource chassis_table("Tables\\MechChassisTable.tbl");
	chassis_table.LoadData();
	if(chassis_table.DoesResourceExist())
	{
		if(m_mechChassisTable)
		{
			delete m_mechChassisTable;
			m_mechChassisTable = NULL;
		}
		m_mechChassisTable = new MWTable(&chassis_table);
	}

	Resource weapons_table("Tables\\WeaponsTable.tbl");
	weapons_table.LoadData();
	if(weapons_table.DoesResourceExist())
	{
		if(m_weaponsTable)
		{
			delete m_weaponsTable;
			m_weaponsTable = NULL;
		}
		m_weaponsTable = new MWTable(&weapons_table);
	}

	MWTable::TableIterator *weapon_iterator;
	Check_Object(m_weaponsTable);

	weapon_iterator = m_weaponsTable->MakeTableIterator();
	MWTableEntry *weapon_entry;
	while((weapon_entry = weapon_iterator->ReadAndNext()) != NULL)
	{
		Check_Object(weapon_entry);
		Resource model_resource;
		Entity::GetGameModelResourceFromDataListID(&model_resource, weapon_entry->GetEntryResourceID());
		Verify(model_resource.DoesResourceExist());
		Weapon::GameModel *weapon_model = Cast_Pointer(Weapon::GameModel *, model_resource.GetPointer());
        gosASSERT((0 <= weapon_model->itemID) && (weapon_model->itemID < 256));
        g_aWIs[weapon_model->itemID].m_HudEffect = weapon_model->m_HudEffect;
	}
	delete weapon_iterator;

	Resource skins_table("Tables\\SkinsTable.tbl");
	skins_table.LoadData();
	if(skins_table.DoesResourceExist())
	{
		if(m_skinsTable)
		{
			delete m_skinsTable;
			m_skinsTable = NULL;
		}
		m_skinsTable = new MWTable(&skins_table);
	}
	
	Resource missionnames_table("Tables\\MissionNames.tbl");
	missionnames_table.LoadData();
	if (missionnames_table.DoesResourceExist())
	{
		if (m_missionsRenameTable)
		{
			delete m_missionsRenameTable;
			m_missionsRenameTable = NULL;
		}
		m_missionsRenameTable = new MWTable(&missionnames_table);
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MWApplication::NameToTeamNumber(char* name)
{
	if (name == 0)
	{
		return (MWApplication::No_Team);
	}

	char buf[200];
	strcpy(buf,name);
	std::string s(_strlwr(buf));
	std::string::size_type pos(s.find("team"));

	if (pos != std::string::npos)
	{
		pos += 4;
		if (pos < s.size())
		{
			s.erase(0,pos);

			if (s.size() > 1)
			{
				s.erase(1,s.size() - 1);
			}
			char* stopstring;
			long team_number(strtol(s.c_str(),&stopstring,10));

			if (team_number == 0)
			{
				team_number = MWApplication::No_Team;
			}
			else
			{
				--team_number;
			}

			if ((team_number >= 0) &&
				(team_number <= 7))
			{
				return (team_number);
			}
		}
	}

	return (No_Team);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MWApplication::GetGameType()
{
	NetMissionParameters::MWNetMissionParameters* net_params = 0;

	if (Network::GetInstance()->AmIServer() == true)
	{
		net_params = GetLocalNetParams();
	}
	else
	{
		net_params = GetServerNetParams();
	}

	if (net_params == 0)
	{
		return (0);
	}

	return (net_params->m_ruleType);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MWApplication::TeamHasAnyPlayers(int team_number)
{
	return ((team_number >= 0) &&
			(team_number <= 7) &&
			(MWApplication::GetInstance() != 0) &&
			(MWApplication::GetInstance()->teams[team_number] != 0) &&
			(MWApplication::GetInstance()->teams[team_number]->GetCurrent() != 0) &&
			(MWApplication::GetInstance()->teams[team_number]->GetCurrent()->IsEmpty() == false));
}

bool
	MWApplication::TeamsAreFriendly(const Adept::ReplicatorID& inflicting_id, const Adept::ReplicatorID& victim_id)
{
	MWObject* a = MWObjectFromRepId(inflicting_id);
	MWObject* b = MWObjectFromRepId(victim_id);

	if ((a == 0) ||
		(b == 0))
	{
		return (false);
	}

	if (a == b)
	{
		return (true);
	}

	if (b->GetRelativeAlignment(a->GetAlignment()) == Entity::Enemy)
	{
		return (false);
	}

	return (true);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MWApplication::GetTeamAlignment(int team)
{
	if ((team < 0) ||
		(team > 7))
	{
		return (MWApplication::No_Team);
	}

	if ((teams[team] != 0) &&
		(teams[team]->GetCurrent() != 0))
	{
		return (teams[team]->GetCurrent()->GetTeamAlignment());
	}

	return (MWApplication::No_Team);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::ResetMission()
{
	if (networkingFlag != false)
	{
		{for (int i = 0; i < Maximum_Players; ++i)
		{
			if(servedConnectionData[i].clientLaunched)
			{
				RespawnConnection(i);
			}
		}}
	}
	else
	{
		NameTable *table = NameTable::GetInstance();

		int size(table->nameTableArray[NameTable::VehicleArray].GetLength());

		{for (int i = 0;
			  i < size;
			  ++i)
		{
			NameTableEntry *data;

			data = &table->nameTableArray [NameTable::VehicleArray][i];
			Adept::Entity* ent = data->dataPointer->GetCurrent ();

			if (ent != 0)
			{
				ent->ClearDestroyedFlag();
			}
		}}		
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::RespawnMission()
{
	Check_Object(this);

	
	MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
	manager->SetDirtyFlag();

	// respawn the mission...
	for (int i = 0; i < Maximum_Players; ++i)
	{
		if(servedConnectionData[i].clientLaunched)
		{
			Network::GetInstance()->SendNetMessage(i, RespawnMissionMessageID, NULL, true);
		}
	}



}


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

void
	MWApplication::RespawnMissionMessageHandler(int connection, MemoryStream *message)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
  {
	char Buffer[128];
	sprintf(Buffer, "RespawnMissionMessageHandler\n");
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	Check_Object(this);	


	Mission::GetInstance()->RespawnMission();

	if (serverFlag)
	{

		
		if (networkingFlag != false)
		{
			for (int i = 0; i < Maximum_Players; ++i)
			{
				if(servedConnectionData[i].clientLaunched)
				{
					RespawnConnection(i);
				}
			}

			for (i = 0; i < Maximum_Lancemates; ++i)
			{
				RespawnLancemate(i);
			}


		}

		else
		{
			NameTable *table = NameTable::GetInstance();

			int size(table->nameTableArray[NameTable::VehicleArray].GetLength());

			{for (int i = 0;
				  i < size;
				  ++i)
			{
				NameTableEntry *data;

				data = &table->nameTableArray [NameTable::VehicleArray][i];
				Adept::Entity* ent = data->dataPointer->GetCurrent ();

				if (ent != 0)
				{
					ent->ClearDestroyedFlag();
				}
			}}		
		}

	}

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::RespawnConnection(int connection)
{
	Check_Object(this);

	Verify(serverFlag);
	Verify(connection >= 0);
	Verify(connection <= Maximum_Players);
	BYTE connection_id = (BYTE)connection;

	if (servedConnectionData[connection_id].clientPlayer == NULL)
		return;

	Check_Object(servedConnectionData[connection_id].clientPlayer);

	if (!servedConnectionData[connection_id].clientPlayer)
		return;

	NetMissionParameters::MWNetMissionParameters *params;	
	params = GetLocalNetParams();
	if (params->m_respawnLimit && servedConnectionData[connection_id].clientPlayer->GetVehicle()->respawnCount >= params->m_respawnLimitNumber)
	{
		if (params->m_deadMechCantSee)
		{
			Network::GetInstance()->SendNetMessage(connection_id, SwitchToCameraMessageID, NULL, true);
		}

		return;
	}

	Network::GetInstance()->SendNetMessage(connection,RespawnFlagsMessageID,NULL,true);

	DynamicMemoryStream respawn_message(256);
	respawn_message.WriteBytes(&connection_id, 1);

	Check_Object(servedConnectionData[connection_id].clientPlayer);
	ObjectID drop_zone = servedConnectionData[connection_id].clientPlayer->dropZone;
	
	Check_Object(EntityManager::GetInstance());
	DropZone *zone;
	zone = EntityManager::GetInstance()->GetDropZone(drop_zone);
	Check_Object(zone);

	Stuff::LinearMatrix4D drop_location = Stuff::LinearMatrix4D::Identity;

	drop_location = zone->RequestDrop();


	Point3D tran(drop_location);
	YawPitchRoll rot(drop_location);

	servedConnectionData[connection_id].clientPlayer->GetVehicle()->respawnCount += 1;
	int respawn_number = servedConnectionData[connection_id].clientPlayer->GetVehicle()->respawnCount;

	respawn_message.WriteBytes(&respawn_number,4);
	respawn_message.WriteBytes(&tran.x,4);
	respawn_message.WriteBytes(&tran.y,4);
	respawn_message.WriteBytes(&tran.z,4);
	respawn_message.WriteBytes(&rot.yaw,4);
	respawn_message.WriteBytes(&rot.pitch,4);
	respawn_message.WriteBytes(&rot.roll,4);

	respawn_message.Rewind();

	EntityManager::GetInstance()->SetPlayerReady(servedConnectionData[connection_id].clientPlayer->vehicle);

	for (int i = 0; i < Maximum_Players; ++i)
	{
		if(servedConnectionData[i].clientLaunched && i != Connection::Server->GetID())
		{
			Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(i,respawn_message.GetBufferBytesUsed()*8);
			Network::GetInstance()->SendNetMessage(i, RespawnMessageID, &respawn_message, true);
		}
	}

	RespawnMessageHandler(Connection::Server->GetID(), &respawn_message);
	respawn_message.Rewind();

	EntityManager::GetInstance()->RespawnClient(connection_id, tran);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::QueRespawnLancemate(int lance_id)
{
    if (g_nMR == 2)
        return;
	Check_Object(this);

	NetMissionParameters::MWNetMissionParameters *params;	
	params = GetLocalNetParams();
	switch(m_iaGameType)
	{
	case DefaultGameType:
		{
            MWEntityManager* manager = Cast_Object(MWEntityManager*, EntityManager::GetInstance());
			if(params->m_respawnLimit && lancemateConnectionData[lance_id].lancemateMech->respawnCount < params->m_respawnLimitNumber)
			{
                manager->QueRespawnLancemate(lancemateConnectionData[lance_id].lancemateMech); // jcem - for delayed lancemate respawn
				//RespawnLancemate(lance_id);
			}
			else if ((!params->m_respawnLimit) && (networkingFlag == true))
			{
                manager->QueRespawnLancemate(lancemateConnectionData[lance_id].lancemateMech); // jcem - for delayed lancemate respawn
				//RespawnLancemate(lance_id);
			}
			break;
		}
	case WaveBattleGameType:
		{
			//First check to see if we are a lance or an enemy bot
			if(lance_id >= BotConnectionStart)
			{
				//We are an enemy bot
				m_botRespawnQueue[m_numberQuedBots] = lance_id;
				m_numberQuedBots ++;
				if(m_numberQuedBots >= m_numberOfEnemiesPerWave)
				{
					m_numberOfCompletedWaves ++;
					if((m_numberOfCompletedWaves >= m_numberOfWaves) && (m_numberOfWaves != -1))
					{
						//If we are master trial then we don't want to end...the script will do it
						if(!m_isMasterTrial)
						{
							//We have killed all of our waves and we should end and we are not unlimmited
							m_currentMissionStatus = MWCampaign::Completed;
							QueStopGame();
						}
					}
					else
					{
						//We have all our bots dead and should respawn them all
						for(int i=0; i<m_numberOfEnemiesPerWave; i++)
						{
							Verify(i<MaxWaveBotCount); //This is because we can only have 4 and we hardcoded our queue array to 4
							if(m_botRespawnQueue[i] > -1)
							{
								RespawnLancemate(m_botRespawnQueue[i]);
								m_botRespawnQueue[i] = -1;
							}
						}

						//Reset all tracking values
						m_numberQuedBots = 0;
					}
				}
			}
			else
			{
				//we are a lancemate so we use the network params respawn info
				if(params->m_respawnLimit && lancemateConnectionData[lance_id].lancemateMech->respawnCount < params->m_respawnLimitNumber)
				{
					//We are a lancemate
					m_lancemateRespawnQueue[m_numberQuedLancemates] = lance_id;
					m_numberQuedLancemates ++;
					if(m_numberQuedLancemates >= m_numberOfLancematesPerWave)
					{
						//We have all our bots dead and should respawn them all
						for(int i=0; i<m_numberOfLancematesPerWave; i++)
						{
							Verify(i<MaxWaveLanceCount); //This is because we can only have 3 and we hardcoded our queue array to 3
							if(m_lancemateRespawnQueue[i] > -1)
							{
								RespawnLancemate(m_lancemateRespawnQueue[i]);
								m_lancemateRespawnQueue[i] = -1;
							}
						}
						//Reset all tracking values
						m_numberQuedLancemates = 0;
					}
				}
			}
			break;
		}
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::RespawnLancemate(int lance_id)
{
	Check_Object(this);

	Verify(serverFlag);
	Verify(lance_id >= 0);
	Verify(lance_id <= Maximum_Players);
	

	if (lancemateConnectionData[lance_id].lancemateMech == NULL)
		return;

	Check_Object(lancemateConnectionData[lance_id].lancemateMech);

	
	NetMissionParameters::MWNetMissionParameters *params;	
	params = GetLocalNetParams();
	
	// game over for this bot... out of lives
	//this check has been moved up to the QueLancemateRespawn function.
//	if (params->m_respawnLimit && lancemateConnectionData[lance_id].lancemateMech->respawnCount >= params->m_respawnLimitNumber)
//	{
//		return;
//	}


	DynamicMemoryStream respawn_message(256);
	respawn_message.WriteBytes(&lance_id, 1);

	Check_Object(lancemateConnectionData[lance_id].lancemateMech);
	ObjectID drop_zone = lancemateConnectionData[lance_id].dropZone;
	
	Check_Object(EntityManager::GetInstance());
	DropZone *zone;
	zone = EntityManager::GetInstance()->GetDropZone(drop_zone);
	Check_Object(zone);

	Stuff::LinearMatrix4D drop_location = Stuff::LinearMatrix4D::Identity;

	drop_location = zone->RequestDrop();


	Point3D tran(drop_location);
	YawPitchRoll rot(drop_location);

	lancemateConnectionData[lance_id].lancemateMech->respawnCount+=1;
	int respawn_number = lancemateConnectionData[lance_id].lancemateMech->respawnCount;

	respawn_message.WriteBytes(&respawn_number,4);
	respawn_message.WriteBytes(&tran.x,4);
	respawn_message.WriteBytes(&tran.y,4);
	respawn_message.WriteBytes(&tran.z,4);
	respawn_message.WriteBytes(&rot.yaw,4);
	respawn_message.WriteBytes(&rot.pitch,4);
	respawn_message.WriteBytes(&rot.roll,4);

	respawn_message.Rewind();

	for (int i = 0; i < Maximum_Players; ++i)
	{
		if(servedConnectionData[i].clientLaunched && i != Connection::Server->GetID())
		{
			Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(i,respawn_message.GetBufferBytesUsed()*8);
			Network::GetInstance()->SendNetMessage(i, RespawnLancemateMessageID, &respawn_message, true);
		}
	}

	RespawnLancemateMessageHandler(Connection::Server->GetID(), &respawn_message);
	respawn_message.Rewind();


	SendEveryoneRespawnIndex();
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::SaveGameLog()
{
	#ifdef LAB_ONLY
	Verify(SaveGameStats == true);

	if ((networkingFlag == true) &&
		(serverFlag == false))
	{
		return;
	}

	FixedLengthString buffer(32768);

	GetGenericErrorInfo(buffer);

	gos_CreateDirectory("GameStats");

	std::string s;
	int index = 0;

	while (1)
	{
		char buf[100];
		sprintf(buf,"%d",index);
		std::string suffix = buf;
		while (suffix.size() < 4)
		{
			suffix = "0" + suffix;
		}

		s = "GameStats\\stats" + suffix + ".txt";

		if (gos_DoesFileExist(s.c_str()) == false)
		{
			break;
		}

		++index;
		if (index > 2000)
		{
			break;
		}
	}

	HGOSFILE hGOSfile;
	gos_OpenFile(&hGOSfile,s.c_str(),READWRITE);
	gos_WriteFile(hGOSfile,buffer,buffer.Length());
	gos_CloseFile(hGOSfile);
	#endif
}


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

int
	MWApplication::GetNextLancemateID()
{
	
	for (int i = 0; i < Maximum_Lancemates; ++i)
	{
		if (!lancemateConnectionData[i].lancemateConnected)
		{
			return i;
		}
	}

	STOP(("NO LANCEMATE SLOTS OPEN"));
	return -1;
}

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


void
	MWApplication::RequestLancemateTeam(int bot, int team_request)
{
    gosASSERT(!CTCL_IsConsole());
	NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();
	if (params->m_teamAllowed)
	{


		if (team_request == No_Team)
		{
			lancemateConnectionData[bot].pilotTeam = team_request;
		}
		else
		{
			int amount_on_requested_team = 0;
			for (int i = 0; i < Maximum_Players; ++i)
			{
				if (servedConnectionData[i].clientConnected && servedConnectionData[i].pilotTeam == team_request)
				{
					++amount_on_requested_team;
				}
			}

			for (i = 0; i < Maximum_Lancemates; ++i)
			{
				if (lancemateConnectionData[i].lancemateConnected && lancemateConnectionData[i].pilotTeam == team_request)
				{
					++amount_on_requested_team;
				}
			}

			if ((amount_on_requested_team + 1) <= params->m_teamParams[team_request].m_maxPlayersOnTeam)
			{
				lancemateConnectionData[bot].pilotTeam = team_request;
#if 0
				// Verify his vehicle on the new team...
				if (lancemateConnectionData[bot].lancemateCreateMessage)
				{
					Stuff::MemoryStream *stream;
					stream = GetLancemateCreationMessage(bot);
					if (VerifyLancemateVehicle(bot, stream))
					{
						
						lancemateConnectionData[bot].lancemateVehicleAccepted = true;
					}
					else
					{
						
						lancemateConnectionData[bot].lancemateVehicleAccepted = false;
						//ClearLancemateCreationMessage(bot);
					}
				}
#else
				lancemateConnectionData[bot].lancemateVehicleAccepted = false;	
				ReverifyDeniedVehicles();
				VerifyLancemateVehicle(bot);
#endif
			}
		}

      if (!CTCL_IsConsole()) { // jcem
		// give a tally of team count to everyone
		char* message = GetTeamCount();
		if (message)
		{
			SendChat(
				Connection::Local->GetID(),
				SystemBroadcast,
				0,
				message);
			delete [] message;
		}
      }
	}
}

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

void
	MWApplication::RequestLancemateMech(int bot, ResourceID mech_id, MString &mech_name)
{
	
	
	DynamicMemoryStream request_vehicle_stream;

	//
	//------------------------------------------------------------------------
	// Open up the resource files we are going to need to construct the player
	// message
	//------------------------------------------------------------------------
	//
	

	if(mech_id == ResourceID::Null)
	{
		//
		//We are not in core and need to open the correct resource file
		//
		
		//ResourceManager::Instance->OpenResourceFile(
		//	MW4Shell::Instance->m_mechResourceFile,
		//	NULL,
		//	MechResourceFileID,
		//	VER_CONTENTVERSION,
		//	false,
		//	false
		//);

		mech_id.m_fileID = 10;
		mech_id.m_recordID = 1;
		
		// Write out the mechs custom resource file
		
		request_vehicle_stream.WriteBytes(&ResourceStreamType, 1);

		Stuff::FileStream file_stream(mech_name);

		request_vehicle_stream.AllocateBytes(file_stream.GetSize());
		file_stream.ReadBytes(request_vehicle_stream.GetPointer(), file_stream.GetSize());
		request_vehicle_stream.AdvancePointer(file_stream.GetSize());

	}
	else
	{
		// Write out the mechs stock resource_id
		request_vehicle_stream.WriteBytes(&ResourceIDType, 1);
		request_vehicle_stream << mech_id;
		
	}

	request_vehicle_stream.Rewind();
	SetLancemateCreationMessage(bot, &request_vehicle_stream);

#if 0
	if (VerifyLancemateVehicle(bot, &request_vehicle_stream))
	{	
		lancemateConnectionData[bot].lancemateVehicleAccepted = true;		

	}
	else
	{
		lancemateConnectionData[bot].lancemateVehicleAccepted = false;	
		//ClearLancemateCreationMessage(bot);
	}
#else
	// Have to verify all other player vehicles as well if team game
	if (serverFlag && GetLocalNetParams()->m_teamAllowed) {
		lancemateConnectionData[bot].lancemateVehicleAccepted = false;	
		ReverifyDeniedVehicles();
	}
	// Verify this vehicle to make sure error code is correct
	VerifyLancemateVehicle(bot);
#endif
}


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

void
	MWApplication::ClearLancemateCreationMessage(int bot)
{

	Verify(bot >= 0 && bot < Maximum_Lancemates);

	if (lancemateConnectionData[bot].lancemateCreateMessage != NULL)
	{
		lancemateConnectionData[bot].lancemateCreateMessage->Rewind();
		BYTE *data = (BYTE*)lancemateConnectionData[bot].lancemateCreateMessage->GetPointer();
		delete[] data;
		
		Check_Object(lancemateConnectionData[bot].lancemateCreateMessage);
		delete lancemateConnectionData[bot].lancemateCreateMessage;

		lancemateConnectionData[bot].lancemateCreateMessage = NULL;
	}

	if (lancemateConnectionData[bot].lancemateCustomResource != NULL)
	{
		delete lancemateConnectionData[bot].lancemateCustomResource;
		lancemateConnectionData[bot].lancemateCustomResource = NULL;
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::InitializeWaveGame(int waves, int bots, int lancemates, int player_lives)
{
	m_iaGameType = WaveBattleGameType;
	m_numberOfWaves = waves;
	m_numberOfCompletedWaves = 0;
	m_numberOfEnemiesPerWave = bots;
	m_numberOfLancematesPerWave = lancemates;
	m_numberQuedLancemates = 0;
	m_numberQuedBots = 0;

	NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();

	params->m_forceRespawn = true;
	if(player_lives > 0)
	{
		params->m_respawnLimit = true;
		params->m_respawnLimitNumber = player_lives - 1;
	}

	int i;
	for(i=0; i<MaxWaveLanceCount; i++)
	{
		m_lancemateRespawnQueue[i] = -1;
	}
	for(i=0; i<MaxWaveBotCount; i++)
	{
		m_botRespawnQueue[i] = -1;
	}
}

void
	MWApplication::InitializeTrainingMission()
{
	if (MW4Shell::Instance == 0)
	{
		return;
	}

	MW4Shell::Instance->m_mechResourceFile = "";

	MWTable::TableIterator * mech_iterator = MWApplication::GetInstance()->m_mechTable->MakeTableIterator();
	MWTableEntry *mech_entry;
	while((mech_entry = mech_iterator->ReadAndNext()) != NULL)
	{
		MString s(mech_entry->GetData());
		s.ToLower();
		if (s == "mechs\\shadowcat\\shadowcat.instance")
		{
			MW4Shell::Instance->m_mechID = mech_entry->GetEntryResourceID();
			break;
		}
	}
	
	delete mech_iterator;
}




#ifdef LAB_ONLY

char *message_name_table [MWApplication::LastMessageID - Adept::Network::FirstDirectApplicationMessageID] =
{
	"RequestConnectionMessageID",
	"DenyRequestConnectionMessageID",		
	"AcceptConnectionMessageID",			
	"LoadGameMessageID",					
	"LoadPersitantHermitObjectsID",		
	"AddPlayerMessageID",					
	"RemovePlayerMessageID",				
	"RequestPlayerVehicleMessageID",		
	"AcceptPlayerVehicleMessageID",		
	"DenyPlayerVehicleMessageID",			
	"AddLancemateMessageID",				
	"ReadyToLaunchMessageID",				
	"ClientLoadedMessageID",				
	"RunGameMessageID",					
	"ScoreMessageID",						
	"RequestRespawnMessageID",			
	"RespawnMessageID",					
	"ChatMessageID",						
	"StopMissionMessageID",				
	"PlayerLeavingMessageID",				
	"RequestMissionParameterMessageID",	
	"MissionParameterMessageID",			
	"ScoreFormatMessageID",				
	"RequestMapInfoMessageID",			
	"MapInfoMessageID",					
	"SwitchToCameraMessageID",			
	"DecalLayoutMessageID",				
	"RequestDecalsMessageID",				
	"DecalPayLoadMessageID",				
	"AddTeamMessageID",					
	"LobbyStatusMessageID",				
	"RequestTeamMessageID",				
	"RequestPreRenderMessageID",			
	"PreRenderMessageID",					
	"MissionReviewAvailableMessageID",	
	"RequestMissionReviewMessageID",		
	"CancelMissionReviewMessageID",		
	"MissionReviewPartMessageID",			
	"RespawnFlagsMessageID",				
	"PlayerClanMessageID",				
	"RespawnLancemateMessageID",			
	"UnreadyLaunchMessageID",
	"StopMissionConfirmationMessageID",
	"RequestNewDictionaryMessageID",	
	"KickPlayerMessageID",			
	"TeamBettyMessageID",				
	"StartMusicMessageID",
	"TeamSetNavMessageID",			
	"RequestScoreFormatMessageID",
	"RespawnMissionMessageID",
    // team order
    "TeamOrderMessageID",
    "svrTeamOrderMessageID",
    "RepTeamOrderMessageID",
    "svrRepTeamOrderMessageID",
    // team order
};

#endif


char *rule_name_table [MWApplication::AllowedRuleCount+1] =
{
	"ServerAllowedRule",
	"ClientAllowedRule",
	"WaitingForGameAllowedRule",
	"LoadingGameAllowedRule",
	"PreRenderAllowedRule",
	"RunningGameAllowedRule",
	"StoppingGameAllowedRule",
	"RecycleGameAllowedRule",
	"ERROR NO RULE"
};

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

bool
	MWApplication::CullWhackedMessages(int connection, int message_type)
{

	if (servedConnectionData[connection].waitingForClientShutdownConfirmation && message_type != StopMissionConfirmationMessageID)
		return true;

	
	message_type -= Adept::Network::FirstDirectApplicationMessageID;


	bool result = false;

	int rule = AllowedRuleCount;
	int resolution;

	if (serverFlag)
	{
		resolution = ServerResolution;
		if (!MessageRules[message_type][ServerAllowedRule])
		{
			rule = ServerAllowedRule;
			result = true;
		}
	}
	else
	{
		resolution = ClientResolution;
		if (!MessageRules[message_type][ClientAllowedRule])
		{
			rule = ClientAllowedRule;
			result = true;
		}
	}


	switch (applicationState->GetState())
	{
		case ApplicationStateEngine::WaitingForGameState:
			if (!MessageRules[message_type][WaitingForGameAllowedRule])
			{
				rule = WaitingForGameAllowedRule;
				result = true;
			}
			break;

		case ApplicationStateEngine::LoadingGameState:
			if (!MessageRules[message_type][LoadingGameAllowedRule])
			{
				rule = LoadingGameAllowedRule;
				result = true;
			}
			break;

		case ApplicationStateEngine::PreRenderState:
			if (!MessageRules[message_type][PreRenderAllowedRule])
			{
				rule = PreRenderAllowedRule;
				result = true;
			}
			break;

		case ApplicationStateEngine::RunningGameState:
			if (!MessageRules[message_type][RunningGameAllowedRule])
			{
				rule = RunningGameAllowedRule;
				result = true;
			}
			break;

		case ApplicationStateEngine::StoppingGameState:
			if (!MessageRules[message_type][StoppingGameAllowedRule])
			{
				rule = StoppingGameAllowedRule;
				result = true;
			}
			break;

		case ApplicationStateEngine::RecycleGameState:
			if (!MessageRules[message_type][RecycleGameAllowedRule])
			{
				rule = RecycleGameAllowedRule;
				result = true;
			}
			break;
	}
	


	if (result)
	{
		
		if (MessageResolution[message_type][resolution] == WarnResolution)
		{
#ifdef LAB_ONLY
			PAUSE(("Message type received out of order : %s failed %s", message_name_table[message_type], rule_name_table[rule]));
#endif
		}
		else if (MessageResolution[message_type][resolution] == ShellClientResolution)
		{
			Verify(serverFlag);

			// send the client to the shell...
			Connection *conn = Network::GetInstance()->GetConnection(connection);
			if(conn != NULL)
			{
				servedConnectionData[connection].waitingForClientShutdownConfirmation = true;
				Network::GetInstance()->SendNetMessage(connection, StopMissionMessageID, NULL, true);
				
				PlayerLeavingMessageHandler(connection, NULL);
			}
		}
	}


	return result;
}


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

void
	MWApplication::ReceiveDirectMessage(int connection, int message_type, MemoryStream *message)
{
	Verify(Network::GetInstance() != NULL);
	Check_Object(this);

	if (CullWhackedMessages(connection, message_type))
	{
		return;
	}

#if defined(_DEBUG) && 0 // jcem - for MR test
  {
    extern int g_nLocalPacketLevel;
	char Buffer[128];
    const char* pcszMsg = message_name_table[message_type - Adept::Network::FirstDirectApplicationMessageID];
    sprintf(Buffer, "App%s:: %s\n  >> ", g_nLocalPacketLevel ? "(Local)": "", pcszMsg);
	OutputDebugString(Buffer);
  }
#endif // _DEBUG && ...

	switch(message_type)
	{
		case RequestConnectionMessageID:
			RequestConnectionMessageHandler(connection, message);
			break;

		case DenyRequestConnectionMessageID:
			DenyRequestConnectionMessageHandler(connection, message);
			break;

		case AcceptConnectionMessageID:
			AcceptConnectionMessageHandler(connection, message);
			break;

		case LoadGameMessageID:
			LoadGameMessageHandler(connection, message);
			break;
	
		case AddPlayerMessageID:
			AddPlayerMessageHandler(connection, message);
			break;
		
		case LoadPersitantHermitObjectsID:
			LoadPersitantHermitObjectsMessageHandler(connection, message);
			break;

		case RequestPlayerVehicleMessageID:
			RequestPlayerVehicleMessageHandler(connection, message);
			break;

		case AcceptPlayerVehicleMessageID:
			AcceptPlayerVehicleMessageHandler(connection, message);
			break;

		case DenyPlayerVehicleMessageID:
			DenyPlayerVehicleMessageHandler(connection, message);
			break;

		case AddLancemateMessageID:
			AddLancemateMessageHandler(connection,message);
			break;

		case ReadyToLaunchMessageID:
			ReadyToLaunchMessageHandler(connection, message);
			break;

		case ClientLoadedMessageID:
			ClientLoadedMessageHandler(connection, message);
			break;

		case RunGameMessageID:
			RunGameMessageHandler(connection, message);
			break;

		case ScoreMessageID:
            g_bScoreMessageHandler = true;
			ScoreMessageHandler(connection, message);
            g_bScoreMessageHandler = false;
			break;

		case RequestRespawnMessageID:
			RequestRespawnMessageHandler(connection, message);
			break;

		case RespawnMessageID:
			RespawnMessageHandler(connection, message);
			break;

		case ChatMessageID:
			ChatMessageHandler(connection, message);
			break;
			
		case StopMissionMessageID:
			StopMissionMessageHandler(connection, message);
			break;

		case PlayerLeavingMessageID:
			PlayerLeavingMessageHandler(connection, message);
			break;

		case RequestMissionParameterMessageID:
			RequestMissionParametersMessageHandler(connection, message);
			break;

		case MissionParameterMessageID:
			MissionParametersMessageHandler(connection, message);
			break;

		case RemovePlayerMessageID:
			RemovePlayerMessageHandler(connection, message);
			break;

		case ScoreFormatMessageID:
			ScoreFormatMessageHandler(connection, message);
			break;

		case RequestMapInfoMessageID:
			RequestMapInfoMessageHandler(connection, message);
			break;

		case MapInfoMessageID:
			MapInfoMessageHandler(connection, message);
			break;

		case SwitchToCameraMessageID:
			SwitchToCameraMessage(connection, message);
			break;

		case DecalLayoutMessageID:
			DecalLayoutMessageHandler(connection, message);
			break;

		case RequestDecalsMessageID:
			RequestDecalsMessageHandler(connection, message);
			break;
		
		case DecalPayLoadMessageID:
			DecalPayLoadMessageHandler(connection, message);
			break;

		case AddTeamMessageID:
			AddTeamMessageHandler(connection, message);
			break;

		case RequestTeamMessageID:
			RequestTeamMessageHandler(connection, message);
			break;
		
		case LobbyStatusMessageID:
			LobbyStatusMessageHandler(connection, message);
			break;

		case RequestPreRenderMessageID:
			RequestPreRenderMessageHandler(connection, message);
			break;

		case PreRenderMessageID:
			PreRenderMessageHandler(connection, message);
			break;

		case RequestMissionReviewMessageID:
			RequestMissionReviewMessageHandler(connection, message);
			break;

		case CancelMissionReviewMessageID:
			CancelMissionReviewMessageHandler(connection, message);
			break;

		case MissionReviewPartMessageID:
			MissionReviewPartMessageHandler(connection, message);
			break;

		case MissionReviewAvailableMessageID:
			MissionReviewAvailableMessageHandler(connection, message);
			break;

		case RespawnFlagsMessageID:
			RespawnFlagsMessageHandler(connection,message);
			break;

		case PlayerClanMessageID:
			PlayerClanMessageHandler(connection,message);
			break;

		case RespawnLancemateMessageID:
			RespawnLancemateMessageHandler(connection,message);
			break;

		case UnreadyLaunchMessageID:
			UnreadyLaunchMessageHandler(connection,message);
			break;

		case StopMissionConfirmationMessageID:
			StopMissionConfirmationMessageHandler(connection,message);
			break;

		case RequestNewDictionaryMessageID:
			RequestNewDictionaryMessageHandler(connection,message);
			break;

		case KickPlayerMessageID:
			KickPlayerMessageHandler(connection, message);
			break;

		case TeamBettyMessageID:
			TeamBettyMessageHandler(connection, message);
			break;

		case StartMusicMessageID:
			StartMusicMessageHandler(connection, message);
			break;

		case TeamSetNavMessageID:
			TeamSetNavMessageHandler(connection, message);
			break;

		case RequestScoreFormatMessageID:
			RequestScoreFormatMessageHandler(connection, message);
			break;

		case RespawnMissionMessageID:
			RespawnMissionMessageHandler(connection, message);
			break;

		case RespawnIndexMessageID:
			RespawnIndexMessageHandler(connection, message);
			break;
        // team order
        case TeamOrderMessageID:
            TeamOrderMessageHandler(connection, message);
			break;
        case svrTeamOrderMessageID:
            svrTeamOrderMessageHandler(connection, message);
			break;
        case RepTeamOrderMessageID:
            RepTeamOrderMessageHandler(connection, message);
			break;
        case svrRepTeamOrderMessageID:
            svrRepTeamOrderMessageHandler(connection, message);
			break;
        // team order

		default:
			STOP(("MWApplication::DirectMessage UNKNOWN MESSAGE TYPE"));
			break;

	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MWApplication::BotsAllowed()
{
	if (networkingFlag == false)
	{
		return (true);
	}

	NetMissionParameters::MWNetMissionParameters *params = 0;

	if (serverFlag)
	{
		params = GetLocalNetParams();
	}
	else
	{
		params = GetServerNetParams();
	}

	if (params == 0)
	{
		return (false);
	}

	switch (params->m_ruleType)
	{
		case StockDestruction:
		case StockTeamDestruction:
		case StockAttrition:
		case StockTeamAttrition:

		case CustomDestruction:
		case CustomTeamDestruction:
		case CustomAttrition:
		case CustomTeamAttrition:
		{
			return (true);
		}
	}

	return (false);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWApplication::AlignmentSchema
	MWApplication::GetAlignmentSchema()
{
	MWApplication* app = MWApplication::GetInstance();

	if (app->networkingFlag == false)
	{
		return (SINGLE_PLAYER);
	}

	NetMissionParameters::MWNetMissionParameters *params = 0;

	if (app->serverFlag)
	{
		params = app->GetLocalNetParams();
	}
	else
	{
		params = app->GetServerNetParams();
	}

	if (params->m_teamAllowed != 0)
	{
		return (MP_TEAMPLAY);
	}

	return (MP_NON_TEAMPLAY);
}


/*//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// by jcem
void __stdcall
	MWApplication::MW4GetFileForGOS(
		const char* file_name,
		BYTE** memory,
		DWORD* size
	)
{
	Check_Pointer(file_name);

	Check_Object(MWApplication::GetInstance());
	Check_Object(MWApplication::GetInstance()->m_missionsRenameTable);

	//
	// If we have a file ending in .mw4 then search for it in the list.
	//
	if (strlen(file_name) > 4 && !stricmp((file_name + strlen(file_name) - 4), ".mw4"))
	{
		MWTableEntry *mission_remap = MWApplication::GetInstance()->m_missionsRenameTable->FindEntry(file_name);
		if (mission_remap)
		{
			Check_Object(mission_remap);
			const char * szMissionRename = (const char *)mission_remap->GetData();
/*
// set them explicitely including the path and we don't have to process it.
			//
			// Now we need to replace, just the part that has the filename.
			//
			char newpath[MAX_PATH *2];
			strcpy(newpath, file_name);
			char *p = _mbsrchr(newpath, '\\');
			Check_Pointer(p);
			Str_Copy(p+1, szMissionRename, MAX_PATH*2 - ((p+1) - newpath));
			Adept::Tool::GetFileForGOS(newpath, memory, size);

*//*
			Adept::Application::GetFileForGOS(szMissionRename, memory, size);
			return;
		}
	}
	Adept::Application::GetFileForGOS(file_name, memory, size);
	return;

}

/*
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool __stdcall
	MWApplication::MW4FindFileForGOS(const char* file_name)
{
	Check_Pointer(file_name);
	Check_Object(MWApplication::GetInstance());
	Check_Object(MWApplication::GetInstance()->m_missionsRenameTable);

	//
	// If we have a file ending in .mw4 then search for it in the list.
	//
	if (strlen(file_name) > 4 && !stricmp((file_name + strlen(file_name) - 4), ".mw4"))
	{
		

		MWTableEntry *mission_remap = MWApplication::GetInstance()->m_missionsRenameTable->FindEntry(file_name);
		if (mission_remap)
		{
			Check_Object(mission_remap);
			const char * szMissionRename = (const char *)mission_remap->GetData();
/*
// set them explicitely including the path and we don't have to process it.
			//
			// Now we need to replace, just the part that has the filename.
			//
			char newpath[MAX_PATH *2];
			strcpy(newpath, file_name);
			char *p = _mbsrchr(newpath, '\\');
			Check_Pointer(p);
			Str_Copy(p+1, szMissionRename, MAX_PATH*2 - ((p+1) - newpath));
			Adept::Tool::FindFileForGOS(newpath);

*//*
			return Adept::Application::FindFileForGOS(szMissionRename);
		}

	}
	return Adept::Application::FindFileForGOS(file_name);
}

*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// For resources that need to be converted from non-8.3 names we need to be able to map
// them to new names.
//
bool __stdcall
	MWApplication::TranslateMissionNameIfNecessary(MString & res_name)
{
	Check_Object(MWApplication::GetInstance());
	Check_Object(MWApplication::GetInstance()->m_missionsRenameTable);
	const char * file_name = res_name;
	//
	// If we have a file ending in .mw4 then search for it in the list.
	//
	if (strlen(file_name) > 4 && !stricmp((file_name + strlen(file_name) - 4), ".mw4"))
	{

		MWTable::TableIterator *missionname_iterator;
		missionname_iterator = MWApplication::GetInstance()->m_missionsRenameTable->MakeTableIterator();
		MWTableEntry *missionname_entry;
		while((missionname_entry = missionname_iterator->ReadAndNext()) != NULL)
		{
			Check_Object(missionname_entry);
			if (!stricmp(missionname_entry->GetEntryName(), file_name))
			{
				const char * szMissionRename = (const char *)missionname_entry->GetData();
				if (szMissionRename && *szMissionRename)
				{
					res_name = szMissionRename;
					delete missionname_iterator;
					return true;
				}
			}
		}
		delete missionname_iterator;
	}
	return false;
}
	
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// For resources that need to be converted from non-8.3 names we need to be able to map
// them to new names.
//
bool __stdcall
	MWApplication::TranslateMissionNameBackIfNecessary(MString & res_name)
{
	Check_Object(MWApplication::GetInstance());
	Check_Object(MWApplication::GetInstance()->m_missionsRenameTable);
	const char * file_name = res_name;
	//
	// If we have a file ending in .mw4 then search for it in the list.
	//
	if (strlen(file_name) > 4 && !stricmp((file_name + strlen(file_name) - 4), ".mw4"))
	{

		MWTable::TableIterator *missionname_iterator;
		missionname_iterator = MWApplication::GetInstance()->m_missionsRenameTable->MakeTableIterator();
		MWTableEntry *missionname_entry;
		while((missionname_entry = missionname_iterator->ReadAndNext()) != NULL)
		{
			Check_Object(missionname_entry);
			if (!stricmp(missionname_entry->GetData(), file_name))
			{
				const char * szMissionRename = (const char *)missionname_entry->GetEntryName();
				if (szMissionRename && *szMissionRename)
				{
					res_name = szMissionRename;
					delete missionname_iterator;
					return true;
				}
			}
		}
		delete missionname_iterator;
	}
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MWApplication::ValidateName(char *pszData, bool fCheckBSlash)
{
	char *pszTmp;
	//
	//Special case the name "NUL", it doesn't return a failure code for CreateDirectory()
	//or CreateFile(), even though no such folder\file gets created!
	//
	if (0 == lstrcmpi(pszData, "NUL"))
	{
		return false;
	}

	pszTmp = pszData;
	while (*pszTmp)
	{
		switch (*pszTmp)
		{
		case '\"':
		case  '*':
		case  '?':
		case  '/':
		case  ':':
		case  '<':
		case  '>':
		case  '|':
		case  '&':
			return false;
		case '\\':
			if (fCheckBSlash)
				return false;
		}

		pszTmp = CharNext(pszTmp);
	}
	return true;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MWApplication::ValidatePath(char *pszData, bool fDirectory)
{
	return ValidateName(pszData, false);

#if 0
	char szBuf[MAX_PATH * 2];
	bool  fOK = true;
	//
	//Point to end of parent path...
	//
	pszTmp = szBuf + lstrlen(szBuf);

	GetTempPath(MAX_PATH * 2, szBuf);
	lstrcat(szBuf, "~RCSA~");
	CreateDirectory(szBuf, NULL);

	lstrcat(szBuf, "\\");
	lstrcat(szBuf, pszData);

	if (fDirectory)
	{
		SetFileAttributes(szBuf, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY);
		RemoveDirectory(szBuf);
		if (!CreateDirectory(szBuf, NULL))
		{
			fOK = false;
		}
		else
		{
			RemoveDirectory(szBuf);
		}
	}
	else
	{
		SetFileAttributes(szBuf, FILE_ATTRIBUTE_NORMAL);
		HANDLE hDest = CreateFile(szBuf,
								  GENERIC_READ,
								  FILE_SHARE_READ,
								  NULL,
								  CREATE_ALWAYS,
								  FILE_ATTRIBUTE_NORMAL,
								  NULL);

		if (INVALID_HANDLE_VALUE == hDest)
		{
			fOK = false;
		}
		else
		{
			CloseHandle(hDest);
			DeleteFile(szBuf);
		}
	}

	*pszTmp = '\0';
	RemoveDirectory(szBuf);

	return fOK;
#endif
}

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

bool
	MWApplication::CheckValidDrop(Point3D position)
{

	Stuff::Sphere sphere;
	sphere.center = position;
		
	sphere.radius = 10.0f;
	validDrop = true;
	CollisionGrid::Instance->FindEntitiesWithin(sphere, (Adept::CollisionGrid::WithinCallback)CollisionCallBack, NULL);

	return validDrop;

}


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

void MWApplication::CollisionCallBack(Adept::Entity *entity, Adept::Entity *original_caller, const Stuff::Sphere &sphere)
{

	Check_Object(entity);
	// CBT 3/19/02 - original_caller is set to NULL above in CheckValidDrop() and is unused here
	//Check_Object(original_caller);


	MWApplication *app = MWApplication::GetInstance();


	if (entity->GetClassID() == MechClassID)
	{
		app->validDrop = false;
	}
	
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MWApplication::UpdateAllTeamTotalTonnages()
{
    if (CTCL_IsConsole())
        return;

	if (!serverFlag)
		return;

	NetMissionParameters::MWNetMissionParameters *params = GetLocalNetParams();
	if (params->m_teamAllowed) {
		for (int i=0; i<params->m_teamCount; i++)
			params->m_teamParams[i].m_currentTotalTonnage = GetCurrentTeamTotalTonage(i);	
		
		parametersDirty = true; 
	}
}
// jcem - begin
void MWApplication::CTCL_CheckRunningStart()
{ // sync game start
    if (GetApplicationState() == ApplicationStateEngine::PreRenderState) {
        BOOL bAllOK = TRUE;
        int i;
        for(i = 0; i < Maximum_Players; ++i) {
            const MechWarrior4::ServedConnectionData& scd = servedConnectionData[i];
            //if (i != Connection::Server->GetID()) {
                if (scd.clientConnected) {
                    if (!scd.clientLoaded) {
                        bAllOK = FALSE;
                        break;
                    }
                }
            //}
        }
        if (bAllOK) {
			//$$COOP
			if (g_bCOOP) {
				g_nMech4Comm = -3;
			} else {
				CTCL_DoSendGameReturn(_EGR_OkLaunchReady);
				g_nMech4Comm = 10;
			}
        }
    }
}

void MWApplication::CTCL_GoRunningState()
{
    applicationState->RequestState(ApplicationStateEngine::RunningGameState);
}

void MWApplication::CTCL_DoEndMission()
{
    if (GetApplicationState() == ApplicationStateEngine::RunningGameState) {
		Application::GetInstance()->QueStopGame();
		MW4Shell::Instance->shellStart = MW4Shell::MainShellStart;
		MW4Shell::Instance->shellCommand = MW4Shell::NoShellCommand;
    }
}

void MWApplication::SendSound(const Adept::ReplicatorID& inflicting_id, int nSound)
{
    Mech* pMech = MechFromRepId(inflicting_id);
    if (pMech) {
        if (pMech->isPlayerVehicle) {
            /*
            if (inflicting_id.connectionID == 0) {
            } else {
            */
	            DynamicMemoryStream stream;

                int team_number = No_Team + 10;
	            stream.WriteBytes(&team_number,1);
	            stream.WriteBytes(&nSound,1);

	            stream.Rewind();
	            Network::GetInstance()->SendNetMessage(inflicting_id.connectionID, MWApplication::TeamBettyMessageID, &stream, true);
            //}
        }
    }
}

bool MWApplication::IsTeamAllowed() const
{
    NetMissionParameters::MWNetMissionParameters* params = serverFlag ? GetLocalNetParams(): GetServerNetParams();
    return !!params->m_teamAllowed;
}

int MWApplication::GetMechInfos(int nMode, SMechInfo aMechInfos[16], int& nOthers) const
{
    // nMode : 0 - team, 1 - enemy, 2 - all
    int nCount = 0, nO = 0;
    int con = Connection::Local->GetID();
    const ServedConnectionData& scd = servedConnectionData[con];
    Mech* pMech = scd.GetMech();
    if (pMech) {
        aMechInfos[nCount].SetInfo(pMech, scd.pilotName, false, scd.pilotTeam);
        nCount++;
    }
    int i;
    for(i = 0; i < Maximum_Players; ++i) {
        const MechWarrior4::ServedConnectionData& scd2 = servedConnectionData[i];
        if (i != con) {
            Mech* pMech2 = scd2.GetMech();
            if (pMech2) {
                BOOL bAdd = FALSE;
                if (nMode == 0) {
                    if (scd2.pilotTeam == scd.pilotTeam) {
                        bAdd = TRUE;
                    }
                } else if (nMode == 1) {
                    if (scd2.pilotTeam != scd.pilotTeam) {
                        bAdd = FALSE;
                    }
                } else {
                    bAdd = TRUE;
                }
                if (bAdd) {
                    aMechInfos[nCount].SetInfo(pMech2, scd2.pilotName, false, scd2.pilotTeam);
                    nCount++;
                } else {
                    nO++;
                    aMechInfos[16 - nO].SetInfo(pMech2, scd2.pilotName, false, scd2.pilotTeam);
                }
            }
        }
    }
    for(i = 0; i < Maximum_Lancemates; ++i) {
        const MechWarrior4::LancemateConnectionData& lcd2 = lancemateConnectionData[i];
        Mech* pMech2 = lcd2.GetMech();
        if (pMech2) {
            BOOL bAdd = FALSE;
            if (nMode == 0) {
                if (lcd2.pilotTeam == scd.pilotTeam) {
                    bAdd = TRUE;
                }
            } else if (nMode == 1) {
                if (lcd2.pilotTeam != scd.pilotTeam) {
                    bAdd = FALSE;
                }
            } else {
                bAdd = TRUE;
            }
            if (bAdd) {
                aMechInfos[nCount].SetInfo(pMech2, pMech2->instanceName, true, lcd2.pilotTeam);
                nCount++;
            } else {
                nO++;
                aMechInfos[16 - nO].SetInfo(pMech2, pMech2->instanceName, true, lcd2.pilotTeam);
            }
        }
    }

    nOthers = nO;
    if (nO > 0) {
        memcpy(&aMechInfos[nCount], &aMechInfos[16 - nO], sizeof(aMechInfos[0]) * nO);
    }

    return nCount;
}

void MWApplication::TeamOrderMessageHandler(int connection, Stuff::MemoryStream *message)
{
    int nFrom = 0;
    message->ReadBytes(&nFrom, 1);
	Connection* con = Network::GetInstance()->GetConnection(nFrom);
	if (con != NULL) {
        int nMsgIndex = 0;
        message->ReadBytes(&nMsgIndex, 1);
        if ((0 <= nMsgIndex) && (nMsgIndex < 14)) {
            if ((nMsgIndex == 0) || (nMsgIndex == 1) || (nMsgIndex == 2) || (nMsgIndex == 6)) {
                STeamOrderCommand& TOC = m_aPTOCs.DoReserveTOC(-1, nFrom, nMsgIndex);

                if ((nMsgIndex == 0) || (nMsgIndex == 1)) {
                    // attack|defend my target
		            BYTE connection_id;
		            WORD local_id;

                    message->ReadBytes(&connection_id, 1);
                    message->ReadBytes(&local_id, 2);
                    ReplicatorID id(connection_id, local_id);
                    TOC.m_Target = id;
                } else {
                    gosASSERT((nMsgIndex == 2) || (nMsgIndex == 6));
                    // form up on me, taking fire, need assistance...
                    TOC.m_Target = ReplicatorID::Null;
                }
            } else {
                DoTeamOrderSoundPlay(nFrom, nMsgIndex);
            }
        }
    }
}

void MWApplication::svrTeamOrderMessageHandler(int connection, Stuff::MemoryStream *message)
{
    int nBOTs = 0;
    BYTE connectionID;

    message->ReadBytes(&nBOTs, 1);

    if (nBOTs) {
        int nMsgIndex = 0;
        message->ReadBytes(&nMsgIndex, 1);
        if ((0 <= nMsgIndex) && (nMsgIndex < 14)) {
            if ((nMsgIndex == 0) || (nMsgIndex == 1) || (nMsgIndex == 2) || (nMsgIndex == 6)) {
                STeamOrderCommand& TOC = m_aBTOCs.DoReserveTOC(nBOTs, connection, nMsgIndex);

                for(int i = 0; i < nBOTs; i++) {
                    message->ReadBytes(&TOC.m_waBots[i], 2);
                }
                if ((nMsgIndex == 0) || (nMsgIndex == 1)) {
		            BYTE connection_id;
		            WORD local_id;
                    message->ReadBytes(&connection_id, 1);
                    message->ReadBytes(&local_id, 2);
                    ReplicatorID id(connection_id, local_id);
                    TOC.m_Target = id;
                } else {
                    TOC.m_Target = ReplicatorID::Null;
                }
            }
        }
    } else {
        message->ReadBytes(&connectionID, 1); // to
	    DynamicMemoryStream sub_stream;
	    sub_stream.WriteBytes(message->GetPointer(), message->GetBytesRemaining());
	    sub_stream.WriteByteAlign();
        sub_stream.Rewind();
	    Connection* con = Network::GetInstance()->GetConnection(connectionID);
	    if (con != NULL) {
            Network::GetInstance()->SendNetMessage(connectionID, MWApplication::TeamOrderMessageID, &sub_stream, true);
        }
    }
}

void MWApplication::RepTeamOrderMessageHandler(int connection, Stuff::MemoryStream *message)
{
    int nFrom = 0;
    message->ReadBytes(&nFrom, 1);
	Connection* con = Network::GetInstance()->GetConnection(nFrom);
	if (con != NULL) {
        int nMsgIndex = 0;
        message->ReadBytes(&nMsgIndex, 1);

        if ((14 <= nMsgIndex) && (nMsgIndex <= 15)) {
            DoTeamOrderSoundPlay(nFrom, nMsgIndex);
        }
    }
}

void MWApplication::svrRepTeamOrderMessageHandler(int connection, Stuff::MemoryStream *message)
{
    int nTo = 0;
    message->ReadBytes(&nTo, 1);

	DynamicMemoryStream sub_stream;
	sub_stream.WriteBytes(message->GetPointer(), message->GetBytesRemaining());
	sub_stream.WriteByteAlign();
    sub_stream.Rewind();
	Connection* con = Network::GetInstance()->GetConnection(nTo);
	if (con != NULL) {
        Network::GetInstance()->SendNetMessage(nTo, MWApplication::RepTeamOrderMessageID, &sub_stream, true);
    }
}

void MWApplication::DoTeamOrderSoundPlay(int nFrom, int nMsgIndex)
{
    Mech* pMech = servedConnectionData[nFrom].GetMech();
    if (pMech) {
        pMech->m_fTimeMsgSentEnd = gos_GetElapsedTime() + g_fTimeMsgSender;
        pMech->m_nMsgKind = nMsgIndex;
    }
	HUDChat *chat = Cast_Object (HUDChat *, MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT));
    if (chat) {
        chat->AddChat(&aux1_messages[nMsgIndex][4], nFrom/*connection*/, MWApplication::PrivateBroadcast, Connection::Local->GetID());
    }

    if (!g_bMuteMode || (nMsgIndex < 7) || (14 <= nMsgIndex)) {
        const char* pcsz = &aux1_sounds[nMsgIndex][0];
        if (pcsz[0]) {
            // see VehicleInterface.cpp:#define PLAY_SOUND
		    AudioCommand *asdf = AudioCommand::Create(AudioRenderer::MechanicalType, pcsz, 1.0f, 1.0f);
            if (asdf) {
                Check_Object(asdf);
                asdf->Play();
            }
        }
    }
}

int MWApplication::CheckCampaign(int nType) const
{
	switch(nType)
	{
	case -1:
		if (g_bCOOP && !networkingFlag) {
			gosASSERT(serverFlag);
			return TRUE;
		}
		return FALSE;
	case 0:
		return m_nCamp_Stage;
	case 1:
		return m_nCamp_Score;
	case 2:
		return m_nCamp_Kills;
	case 3:
		return m_nCamp_Deaths;
    case 4:
        return m_nCamp_Time;
    case 5:
        return m_nCamp_Mech;
    case 6:
        return m_bCamp_Success;
	default:
		gosASSERT(FALSE);
		return 0;
	}
}

void MWApplication::CheckCampaignEnd()
{
	if (0 < m_nCamp_Stage) {
        extern float g_fGameEndScreenTimer;
        
        g_fGameEndScreenTimer = 0.0;

		int nScore, nKills, nDeaths;

		nScore = GetScore4Player(nKills, nDeaths);

        m_nCamp_Score += nScore;
		m_nCamp_Kills += nKills;
        m_nCamp_Deaths += nDeaths;

		MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
		Check_Object (mission);

        //m_nCamp_Time // see MWGame::ReactToEndMission(bool success)
        //m_nCamp_Mech // see MWGame::ReactToEndMission(bool success)
        m_bCamp_Success = m_currentMissionStatus; // && (m_nCamp_Stage == 3);

		if (!m_currentMissionStatus/* || (3 <= m_nCamp_Stage)*/) { // MAX Single Stages?
            m_nCamp_Stage = -3; // HighScore...
        } else {
        }
	} else {
        // m_nCamp_Stage: invititation from other...
	}
}

void CTCL_API CTCL_DoEndMission()
{
    MWApplication *app = MWApplication::GetInstance();
    app->CTCL_DoEndMission();
}

Mech* ServedConnectionData::GetMech() const
{
    if (clientConnected && clientLoaded) {
        MWPlayer* plyr = clientPlayer;
        if (plyr) {
            Vehicle* pv = plyr->GetVehicle();
            if (pv && (pv->GetClassID() == MechClassID)) {
                return Cast_Object(Mech*, pv);
            }
        }
    }

    return NULL;
}

ReplicatorID ServedConnectionData::GetReplicatorID() const
{
    Mech* pMech = GetMech();
    if (pMech)
        return pMech->GetReplicatorID();
    return ReplicatorID::Null;
}

Mech* LancemateConnectionData::GetMech() const
{
    if (lancemateConnected && lancemateMech) {
        return lancemateMech;
    }

    return (Mech*)NULL;
}

ReplicatorID LancemateConnectionData::GetReplicatorID() const
{
    Mech* pMech = GetMech();
    if (pMech)
        return pMech->GetReplicatorID();
    return ReplicatorID::Null;
}

void SMechInfo::SetInfo(Mech* pMech, const char* pcszName, bool bBOT, int nTeam)
{
    m_pMech = pMech;
    m_pcszName = pcszName;
    m_bBOT = bBOT;
    m_nTeam = nTeam;

    ReplicatorID& REP = *this;
    REP = pMech->GetReplicatorID();
}

void MWApplication::ClearTOC()
{
    if (this) {
        g_pCurTOC = NULL;
        m_aPTOCs.ClearTOC();
        m_aBTOCs.ClearTOC();
    }
}

void MWApplication::DoTOCs()
{
    if (!g_pCurTOC) {
        m_aPTOCs.DoTOC(*this);
    }
    m_aBTOCs.DoTOC(*this);
}

void MWApplication::EndTOC(bool bAutoDeny/* = false*/)
{
    gosASSERT(g_pCurTOC);
    gosASSERT(g_pCurTOC == &m_aPTOCs.GetTOC(m_aPTOCs.m_nCurTOC));
    gosASSERT(m_aPTOCs.m_nMaxTOC > 0);
    m_aPTOCs.m_nMaxTOC--;
    m_aPTOCs.m_nCurTOC = m_aPTOCs.NormalizeIndex(m_aPTOCs.m_nCurTOC + 1);
    g_pCurTOC = NULL;
}

void MWApplication::DoRemoveTOCs(int connection)
{
    if (g_pCurTOC) {
        if (g_pCurTOC->m_nFrom == connection) {
            EndTOC(true);
        }
    }
    m_aPTOCs.DoRemoveTOCs(connection);
    m_aBTOCs.DoRemoveTOCs(connection);
}

void STeamOrderCommandArray::ClearTOC()
{
    m_nCurTOC = m_nMaxTOC = 0;
}

STeamOrderCommand& STeamOrderCommandArray::DoReserveTOC(int nType, int nFrom, int nMsgIndex)
{
    gosASSERT(nType != 0);
    STeamOrderCommand* pTOC;
    if (m_nMaxTOC >= MAX_TEAMORDER_COUNT) {
        pTOC = &m_aTOCs[m_nCurTOC];
        gosASSERT(pTOC->m_nType != 0);
        // reply...
        if (nType == -1) {
            if (g_pCurTOC) {
                MWApplication::GetInstance()->EndTOC(true);
                m_nMaxTOC++;
            } else {
                m_nCurTOC = NormalizeIndex(m_nCurTOC + 1);
            }
        } else {
            m_nCurTOC = NormalizeIndex(m_nCurTOC + 1);
        }
    } else {
        pTOC = &m_aTOCs[(m_nCurTOC + m_nMaxTOC) % MAX_TEAMORDER_COUNT];
        m_nMaxTOC++;
    }
    pTOC->m_nType = nType;
    pTOC->m_fArrived = gos_GetElapsedTime();
    pTOC->m_nFrom = nFrom;
    pTOC->m_nMsgIndex = nMsgIndex;

    return *pTOC;
}

int STeamOrderCommandArray::NormalizeIndex(int nIndex) const
{
    while(nIndex < 0)
        nIndex += MAX_TEAMORDER_COUNT;
    return nIndex % MAX_TEAMORDER_COUNT;
}

STeamOrderCommand& STeamOrderCommandArray::GetTOC(int nIndex) const
{
    return *(STeamOrderCommand*)&m_aTOCs[NormalizeIndex(nIndex)];
}

void STeamOrderCommandArray::CopyTOC(int nDest, int nSrc)
{
    memcpy(&GetTOC(nDest), &GetTOC(nSrc), sizeof(m_aTOCs[0]));
}

void STeamOrderCommandArray::DoTOC(MWApplication& app)
{
    if (m_nMaxTOC > 0) {
        int nStart = m_nCurTOC;
        int nEnd = nStart + m_nMaxTOC;

        Time tCur = gos_GetElapsedTime();
        while(nStart < nEnd) {
            STeamOrderCommand& TOC = GetTOC(nStart);
            nStart++;
            gosASSERT(TOC.m_nType != 0);
            if (TOC.m_fArrived + g_TOC_ADT <= tCur) {
                AdvanceHead();
            } else {
                Entity* target_entity = NULL;

                const ServedConnectionData& scd = app.servedConnectionData[TOC.m_nFrom];
                if (scd.clientConnected && scd.clientLoaded) {
                    MWPlayer* plyr = scd.clientPlayer;
                    if (plyr) {
                        Vehicle* pv = plyr->GetVehicle();
                        if (pv && (pv->GetClassID() == MechClassID)) {
                            target_entity = pv;
                        }
                    }
                }
                if (target_entity) {
                    MWObject* pLeader = (MWObject*)target_entity;
                    if ((TOC.m_nMsgIndex == 0) || (TOC.m_nMsgIndex == 1)) {
                        // attack|defend my target
			            Connection* con2 = Network::GetInstance()->GetConnection(TOC.m_Target.connectionID);
			            if (con2 != NULL) {
				            Check_Object(con2);
				            target_entity = (Entity*)con2->FindReplicator(TOC.m_Target);
                        }
                        if (!target_entity) {
                            AdvanceHead();
                            continue;
                        }
                        if (!target_entity->IsDerivedFrom(MWObject::DefaultData)) {
                            AdvanceHead();
                            continue;
                        }
                    } else {
                        // form up on me or...
                    }
                    if (target_entity->IsDestroyed()) {
                        AdvanceHead();
                        continue;
                    }
                    MWObject* pTarget = (MWObject*)target_entity;
                    if (TOC.m_nType == -1) { // player?
                        gosASSERT(!g_pCurTOC);
                        if ((g_nTeamOrderMode == TEAM_MESSAGE1) || (g_nTeamOrderMode == TEAM_MESSAGE2)) {
                            // waiting...
                            break;
                        }
                        VehicleInterface* pvi = VehicleInterface::GetInstance();
                        if (pvi) {
                            if (pvi->SetNewRequestedTarget(pTarget)) {
                                g_pCurTOC = &TOC;
                                app.DoTeamOrderSoundPlay(TOC.m_nFrom, TOC.m_nMsgIndex);
                                break;
                            } else {
                                AdvanceHead();
                            }
                        } else {
                            AdvanceHead();
                        }
                    } else {
                        Mech* paMechs[16];
                        int nMechs = 0;
                        int nServerID = Connection::Local->GetID();
                        for(int k = 0; k < TOC.m_nType; k++) {
                            ReplicatorID id(nServerID, TOC.m_waBots[k]);
				            target_entity = (Entity*)Connection::Local->FindReplicator(id);
                            if (target_entity) {
                                if (target_entity->IsDerivedFrom(Mech::DefaultData)) {
                                    if (!target_entity->IsDestroyed()) {
                                        paMechs[nMechs++] = (Mech*)target_entity;
                                    }
                                }
                            }
                        }
                        if (nMechs > 0) {
                            MW4AI::LancemateCommands::ID id_command;
                            switch(TOC.m_nMsgIndex) {
                            default: // case 0: 
                                id_command = LANCEMATE_ATTACKPLAYERSTARGET;
                                break;
                            case 1:
                                id_command = LANCEMATE_DEFENDPLAYERSTARGET;
                                break;
                            case 2:
                                id_command = LANCEMATE_FORMONME;
                                break;
                            case 6:
                                id_command = LANCEMATE_DEFENDPLAYERSTARGET;
                                break;
                            }
                            ExecuteForAllLancemates2(&paMechs[0], nMechs, id_command, pLeader, pTarget);
                            AdvanceHead();
                            break;
                        } else {
                            AdvanceHead();
                        }
                    }
                } else {
                    AdvanceHead();
                }
            }
        }
    }
}

void STeamOrderCommandArray::DoRemoveTOCs(int connection)
{
    int nStart = m_nCurTOC;
    int nEnd = nStart + m_nMaxTOC;

    while(nStart < nEnd) {
        STeamOrderCommand& TOC = GetTOC(nStart);
        gosASSERT(TOC.m_nType != 0);
        if (TOC.m_nFrom == connection) {
            int nCopyDest = nStart;
            int nCopySrc = nStart + 1;
            while(nCopySrc < nEnd) {
                CopyTOC(nCopyDest, nCopySrc);
                nCopyDest++;
                nCopySrc++;
            }
            nEnd--;
            m_nMaxTOC--;
        } else {
            nStart++;
        }
    }
}

void STeamOrderCommandArray::AdvanceHead()
{
    gosASSERT(m_nMaxTOC > 0);
    m_nCurTOC = NormalizeIndex(m_nCurTOC + 1);
    m_nMaxTOC--;
}

bool _stdcall CTCL_DoMissionReplay(const char* pcszFile)
{
    gosASSERT(!pcszFile || (*pcszFile != '\0'));
    if (g_nMR)
        return false;

    if (g_fGameEndScreenTimer != 0.0)
        return false;
	MWApplication *app = MWApplication::GetInstance();
	if (app->GetApplicationState() != ApplicationStateEngine::WaitingForGameState)
        return false;

    if (g_MRF.LoadMR(pcszFile)) {
        g_MRF.DoReplay();
    } else {
        CTCL_SetGameStateAsIdle();
    }

    return true;
}
// jcem - end
MWObject* MWObjectFromRepId(const Adept::ReplicatorID& id)
{
	Connection* connection = Network::GetInstance()->GetConnection(id.connectionID);

	if (connection != NULL)
	{
		Check_Object(connection);
		Replicator* rep = connection->FindReplicator(id);

		if (rep != NULL)
		{
			Entity* ent = Cast_Object(Entity*,rep);
			if (ent->IsDerivedFrom(MWObject::DefaultData) == true)
			{
				return (Cast_Object(MWObject*,ent));
			}
		}
	}

	return (0);
}

Mech* MechFromRepId(const Adept::ReplicatorID& id)
{
	Connection* connection = Network::GetInstance()->GetConnection(id.connectionID);

	if (connection != NULL)
	{
		Check_Object(connection);
		Replicator* rep = connection->FindReplicator(id);

		if (rep != NULL)
		{
			Entity* ent = Cast_Object(Entity*,rep);
			if (ent->IsDerivedFrom(Mech::DefaultData) == true)
			{
				return (Cast_Object(Mech*,ent));
			}
		}
	}

	return (0);
}

int __stdcall CTCL_DoReprint(void* instance, int args, void* data[])
{
	if (VALUEPARM(0)) {
		// real print...
		return CTCL_DoReprintOrCheck(true);
	} else {
		return CTCL_DoReprintOrCheck(false);
	}
}

int __stdcall CTCL_CheckPlayMovie(void* instance, int args, void* data[])
{
	MWApplication *app = MWApplication::GetInstance();

	if (g_hVideo) {
		if (app->GetApplicationState() == ApplicationStateEngine::WaitingForGameState) {
			gosVideo_ResourceInfo gvi;
			gosVideo_GetResourceInfo(g_hVideo, &gvi);

			switch(gvi.ePlayStatus)
			{
			case gosVideo_Stop:
				break;
			default:
				return TRUE;
			}
		}
	}

	return FALSE;
}

int __stdcall CTCL_CheckCoinCounts(void* instance, int args, void* data[])
{
    if (1 <= args) {
        int* p = INTARRAYPARAM(0);
        if (p)
            *p = g_nCoinCount;
    }
    if (2 <= args) {
        int* p = INTARRAYPARAM(1);
        if (p)
            *p = g_nCoinPerGame;
    }
    if (g_nCoinPerGame <= g_nCoinCount)
	    return 1;
    return 0;
}

int __stdcall CTCL_CheckUseJPD(void* instance, int args, void* data[])
{
extern bool g_bUseJPD;
return g_bUseJPD ? 1: 0;
}

void __stdcall CTCL_RandomizeGameData(int nMode)
{
    // nMode: -1 = from client, 0: normal, +1 from server
    if (nMode != -1) {
	    g_guidGameDatas = gos_GenerateUniqueGUID();
    } else {
    }

    const GUID& guid = *(const GUID*)&g_guidGameDatas;
    sprintf(g_szGameName, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
            guid.Data1, guid.Data2, guid.Data3,
            guid.Data4[0], guid.Data4[1],
            guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);

    extern SYSTEMTIME g_SysTime;
    GetLocalTime(&g_SysTime); // GetSystemTime
}

int __stdcall CTCL_GetPlayerName(void* instance, int args, void* data[])
{
	char **plyr_name  = &STRPARM(0);

	FREEANDNULL(*plyr_name);
	*plyr_name = (char *)gos_Malloc(256);

	_mbscpy((unsigned char *)*plyr_name, (const unsigned char *)g_aPlayerInfos[0].m_szName);

    return *(int*)&g_aPlayerInfos[0].m_uPlayerID;
}

int __stdcall CTCL_SetPlayerName(void* instance, int args, void* data[])
{
	const char* plyr_name  = STRPARM(0);

  if (plyr_name)
	_mbscpy((unsigned char *)g_aPlayerInfos[0].m_szName, (const unsigned char *)plyr_name);

    UINT* puID = (UINT*)data[1];
    if (puID)
        g_aPlayerInfos[0].m_uPlayerID = *puID;

    return 0;
}

int __stdcall CTCL_CheckCOOP(void* instance, int args, void* data[])
{
return g_bCOOP ? 1: 0;
}

int __stdcall CTCL_StartCOOP(void* instance, int args, void* data[])
{
    if (g_nMR)
		return 0;
	MWApplication *app;
	app = MWApplication::GetInstance ();
	if (!app)
		return 0;
	if (app->GetApplicationState() != ApplicationStateEngine::WaitingForGameState) {
		return 0;
	}
    if (g_fGameEndScreenTimer != 0.0)
        return 0;
	if (g_nCoinCount < g_nCoinPerGame) {
		if (g_nCoinPerGame > 0)
			return 0;
	}

	extern void _stdcall PlayCoinSound(int nSound);
	PlayCoinSound(1);

	// $$COOP: see void CSOC_Client::OnReadyStartGame()
    // C_ReadyStartGame

	g_nTeslas = 0; // single player game
	g_nBOTs = 7;
	g_nPlayerInfos = 1 + g_nBOTs + g_nTeslas;
	g_bIsServer = TRUE;

    CTCL_RandomizeGameData(0);

// MSL ADD MECH
	//SaveMNP
	static const char* s_paMechNames[] =
	{
		"Camera Ship",	// 0
		"Annihilator",
		"Archer",
		"Arcticwolf",
		"Ares",
		"Argus",		// 1
		"AssassinII",
		"Atlas",		// 2
		"Avatar",
		"Awesome",		// 3
		"Battlemaster",
		"BattlemasterIIc",
		"Behemoth",
		"BehemothII",
		"Blackhawk",
		"Blackknight",
		"Blacklanner",
		"Brigand",
		"Bushwacker",	// 4
		"Catapult",		// 5
		"Cauldronborn",
		"Chimera",		// 6
		"Commando",
		"Cougar",		// 7
		"Cyclops",
		"Daishi",		// 8
//		"Dasher",
		"Deimos",
		"Dragon",
		"Fafnir",
		"Flea",
		"Gladiator",
		"Grizzly",
		"Hauptmann",
		"Hellhound",
		"Hellspawn",	// 9
		"Highlander",
		"HollanderII",
		"Hunchback",
		"Kodiak",
		"Loki",			// 10
		"Longbow",
		"Mad Cat",		// 11
		"Mad Cat MKII",	// 12
		"Masakari",
		"Mauler",		// 13
		"Nova Cat",		// 14
		"Osiris",		// 15
		"Owens",
		"Puma",
		"Raven",		// 16
		"Rifleman",
		"Ryoken",
		"Shadow Cat",	// 17
		"Solitaire",
		"Sunder",
		"Templar",
		"Thanatos",		// 18
		"Thor",			// 19
		"Uller",
		"Urbanmech",
		"Uziel",		// 20
		"Victor",
		"Vulture",		// 21
		"Warhammer",
		"Wolfhound",
		"Zeus",
	};

    SPlayerInfo& PI = g_aPlayerInfos[0];
    PI.m_bBot = FALSE;
	PI.m_bTeam = FALSE;
    PI.m_nLevelOrTesla = 0; // never mind
    strcpy(PI.m_szName, "Fire Storm");
// MSL ADD MECH
    PI.m_nMechIndex = -1;
//*
//	See MechIndex for each mech's info
	PI.m_fileID = 0;
	PI.m_recordID = 0;
    strcpy(PI.m_szMech, s_paMechNames[11]); // Madcat
	strcpy(PI.m_szMech, "$Yellow");
//*/
    PI.m_nTeamOrSkin = 1; // red
    PI.m_nDecal = 1; // nDecal;
    PI.m_dwAddr = 0; // dwAddr;
    g_nPrintOut = FALSE;
    g_nMissionReview = FALSE;
    //g_guidGameDatas = *(GUID*)pGUID;
    //g_SysTime = *pSysTime;

	static int s_aLBN[3][7] = {
		{ 3, 4, 4, 5, 5, 6, 7 }, // Level
		{ 5, 5, 13, 21, 6, 10, 19 }, // MechType
		{ 0, 1, 2, 3, 4, 5, 6 }, // Bot name index
	};

	static PCSTR s_pNames[7] = {
		"Sixfingers", "Special K", "Sea Wolf",
		"Crusher", "Dark Priest", "Paladin",
		"Untouchable",
	};
	int row, col, aLBN[3][7];
	for(row = 0; row < 3; row++) {
		for(col = 0; col < 7; col++) {
			aLBN[row][col] = s_aLBN[row][col];
		}
	}
	for(row = 0; row < 3; row++) {
		for(col = 0; col < 7; col++) {
			int nCol2 = rand() % 7;
			if ((0 <= nCol2) && (nCol2 < 7) && (nCol2 != col)) {
				int nTemp = aLBN[row][col];
				aLBN[row][col] = aLBN[row][nCol2];
				aLBN[row][nCol2] = nTemp;
			}
		}
	}

	// $$COOP: see void CSOC_Client::OnBOTS()
	// C_BOTS
    for(int i = 1; i < g_nPlayerInfos; i++) {
        SPlayerInfo& PI = g_aPlayerInfos[i];
        PI.m_bBot = TRUE;
        PI.m_nTeamOrSkin = (i == 1) ? 0: i;
        PI.m_nDecal = 0;
		PI.m_nLevelOrTesla = aLBN[0][i - 1];
		strcpy(PI.m_szName, s_pNames[aLBN[2][i - 1]]);
		PI.m_nMechIndex = -1;
		//*
		//See MechIndex for each mech's info
		PI.m_fileID = 0;
		PI.m_recordID = 0;
		/*if (i == 1)
			strcpy(PI.m_szMech, "$Yellow");
		else if (i == 2)
			strcpy(PI.m_szMech, "$Orange");
		else if (i == 3)
			strcpy(PI.m_szMech, s_paMechNames[3]);
		else if (i == 4)
			strcpy(PI.m_szMech, s_paMechNames[5]);
		else*/
		strcpy(PI.m_szMech, s_paMechNames[aLBN[1][i - 1]]);
		//*/
    }
    g_nMech4Comm = -1;

	return 1;
}

int __stdcall CTCL_PosCOOP(void* instance, int args, void* data[])
{
	g_nCoinX = INTPARM(0);
	g_nCoinY = INTPARM(1);
	return 1;
}

bool __stdcall CTCL_HandleKey(DWORD wParam, bool bDown)
{
    if (bDown && g_bCOOP && (CTCL_GetType() == _ECTCL_Game)) {
        if (wParam == 0xc0) { // '~'
            extern void _stdcall PlayCoinSound(int nSound);

            g_nCoinCount++;
            PlayCoinSound(0);
        }
    }
    
    return true;
}

void COOP_InputMode(bool bRestore)
{
    // store & restore last g_nInputMode.... for COOP 3 single waves
    MWApplication *app = MWApplication::GetInstance ();
    if (app->IsCampCOOP()) {
        extern int g_nInputMode;
        static int s_nInputMode;
        if (bRestore) {
            if (app->m_nCamp_Stage == 1) {
                g_nInputMode = s_nInputMode = 0; // 0 == _BIGINNER_MODE, see criomain.h
            } else {
                g_nInputMode = s_nInputMode;
            }
        } else { // store
            s_nInputMode = g_nInputMode;
        }
    }
}
