Files
firestorm/Gameleap/code/mw4/Code/MW4/MWEntityManager.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

2288 lines
68 KiB
C++

//===========================================================================//
// File: EntityUpdateManager.cpp
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 07/26/1999 JSE Inital coding
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Microsoft Corp. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "MW4Headers.hpp"
#include "MWEntityManager.hpp"
#include "MWApplication.hpp"
#include "ObservationVehicle.hpp"
#include "Mech.hpp"
#include "Torso.hpp"
#include "VehicleInterface.hpp"
#include "MWPlayer.hpp"
#include "Weapon.hpp"
#include "MissileWeapon.hpp"
// MSL 5.03 RTX
//#include "rtxweaponsub.hpp"
#include "GameInfo.hpp"
#include "SubsystemClassData.hpp"
#include "NetAutoPacketSpliter.hpp"
#include "MissionReview.hpp"
#include "Flag.hpp"
#include <Adept\Map.hpp>
#include <Adept\Player.hpp>
#include <Adept\CollisionGrid.hpp>
#include <Adept\CollisionVolume.hpp>
#include <Adept\Mission.hpp>
#include <Adept\NetStatCollector.hpp>
#include "MechLabHeaders.h"
#include "mwmission.hpp"
#include <Adept\Site.hpp>
#pragma warning(push)
#include <stlport\string>
#pragma warning(pop)
// ngLog addition // JKK
#if !defined(NO_LOG)
#include "nglog_mw4.hpp"
#endif // !defined(NO_LOG)
#include "BeamWeapon.hpp"
#include <Adept\DamageObject.hpp>
// jcem - start
#include "windows.h"
#include "ctcls.h"
#include "ctcl.h"
#include "recscore.h"
// 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"
extern bool g_bCOOP;
// jcem - mission replay
// jcem - end
BYTE *MWEntityManager::Packet_Buffer = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//#############################################################################
//########################### MWEntityManager #############################
//#############################################################################
MWEntityManager::ClassData*
MWEntityManager::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
__int64 tServerRewind;
__int64 tServerEncode;
__int64 tClientDecode;
__int64 tClientEncode;
extern DWORD g_clientControlPackets;
extern DWORD g_clientPacketsWaitingConfirmation;
extern DWORD g_clientSkippedPackets;
extern DWORD g_clientForgotenPackets;
extern DWORD g_clientTimedOutPackets;
extern DWORD g_clientLatePackets;
extern DWORD g_clientFullConfirms;
extern DWORD g_clientSmallConfirms;
extern DWORD g_serverControlsApplied;
extern DWORD g_serverFullRetransmits;
extern DWORD g_serverSmallRetransmits;
extern DWORD g_serverPacketsOutOfRange;
extern DWORD g_serverFullConfirms;
extern DWORD g_serverSmallConfirms;
extern DWORD g_serverTimeOuts;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::InitializeClass()
{
g_clientControlPackets = 0;
g_clientPacketsWaitingConfirmation = 0;
g_clientSkippedPackets = 0;
g_clientForgotenPackets = 0;
g_clientTimedOutPackets = 0;
g_clientLatePackets = 0;
g_clientFullConfirms = 0;
g_clientSmallConfirms = 0;
g_serverControlsApplied = 0;
g_serverFullConfirms = 0;
g_serverSmallConfirms = 0;
g_serverFullRetransmits = 0;
g_serverSmallRetransmits = 0;
g_serverPacketsOutOfRange = 0;
g_serverTimeOuts = 0;
#if !(defined(NO_TIMERS) && defined(NO_STATS))
StatisticFormat("");
StatisticFormat("MW4 Networking Entity Manager");
StatisticFormat("=============");
#endif
#if !defined(NO_TIMERS)
AddStatistic( "Server Rewind", "%", gos_timedata, &tServerRewind, 0);
AddStatistic( "Server Encode", "%", gos_timedata, &tServerEncode, 0);
AddStatistic( "Client Encode", "%", gos_timedata, &tClientEncode, 0);
AddStatistic( "Client Decode", "%", gos_timedata, &tClientDecode, 0);
#endif
#if !defined(NO_STATS)
AddStatistic( "C: ControlPacket","m", gos_DWORD, &g_clientControlPackets, 0);
AddStatistic( "C: Qued", "m", gos_DWORD, &g_clientPacketsWaitingConfirmation, 0);
AddStatistic( "C: Skipped", "m", gos_DWORD, &g_clientSkippedPackets, 0);
AddStatistic( "C: Forgotten", "m", gos_DWORD, &g_clientForgotenPackets, 0);
AddStatistic( "C: TimedOut", "m", gos_DWORD, &g_clientTimedOutPackets, 0);
AddStatistic( "C: Late", "m", gos_DWORD, &g_clientLatePackets, 0);
AddStatistic( "C: FConfirm", "m", gos_DWORD, &g_clientFullConfirms, 0);
AddStatistic( "C: SConfirm", "m", gos_DWORD, &g_clientSmallConfirms, 0);
AddStatistic( "S: ControlsApplied","m", gos_DWORD, &g_serverControlsApplied, 0);
AddStatistic( "S: OutOfRange", "m", gos_DWORD, &g_serverPacketsOutOfRange, 0);
AddStatistic( "S: FConfirm", "m", gos_DWORD, &g_serverFullConfirms, 0);
AddStatistic( "S: SConfirm", "m", gos_DWORD, &g_serverSmallConfirms, 0);
AddStatistic( "S: FRetransmits", "m", gos_DWORD, &g_serverFullRetransmits, 0);
AddStatistic( "S: SRetransmits", "m", gos_DWORD, &g_serverSmallRetransmits, 0);
AddStatistic( "S: TimeOuts", "m", gos_DWORD, &g_serverTimeOuts, 0);
#endif
Verify(!DefaultData);
DefaultData =
new ClassData(
MWEntityManagerClassID,
"MechWarrior4::MWEntityManager",
Adept::EntityManager::DefaultData
);
Check_Object(DefaultData);
WeaponUpdate::InitializeClass();
Packet_Buffer = new BYTE[DefaultPacketBufferSize];
Network::HashMessageTypeFlags[FirstPersonControlMessageID] = Network::GameSpecificHash;
//Network::HashMessageTypeFlags[FirstPersonObserverControlMessageID] = Network::GameSpecificHash;
Network::HashMessageTypeFlags[FirstPersonSmallConfirmationMessageID] = Network::GameSpecificHash;
Network::HashMessageTypeFlags[FirstPersonFullConfirmationMessageID] = Network::GameSpecificHash;
Network::HashMessageTypeFlags[FirstPersonWeaponToMechCommandMessageID] = Network::GameSpecificHash;
Network::HashMessageTypeFlags[FirstPersonWeaponToGroundCommandMessageID] = Network::GameSpecificHash;
Network::HashMessageTypeFlags[FirstPersonWeaponToServerObjectCommandMessageID] = Network::GameSpecificHash;
Network::HashMessageTypeFlags[FirstPersonWeaponNoTargetCommandMessageID] = Network::GameSpecificHash;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::TerminateClass()
{
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
delete[] Packet_Buffer;
WeaponUpdate::TerminateClass();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool MWEntityManager::IsNumberAhead(int value, int position, int number_ahead, int wrap_around_number)
{
Verify(number_ahead < wrap_around_number);
int result = value - position;
if (result >= 0 && result <= number_ahead)
return true;
result = value + wrap_around_number - position;
if (result >= 0 && result <= number_ahead)
return true;
return false;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool MWEntityManager::IsNumberBehind(int value, int position, int number_behind, int wrap_around_number)
{
Verify(number_behind < wrap_around_number);
int result = position - value;
if (result > 0 && result <= number_behind)
return true;
result = position + wrap_around_number - value;
if (result > 0 && result <= number_behind)
return true;
return false;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool MWEntityManager::IsNumberWithin(int value, int positoin, int number_within, int wrap_around_number)
{
if (IsNumberAhead(value, positoin, number_within, wrap_around_number)||IsNumberBehind(value, positoin, number_within, wrap_around_number))
{
return true;
}
return false;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWEntityManager::SetPlayerReady(Entity *entity)
{
EntityManager::SetPlayerReady(entity);
Check_Object(entity);
Vehicle *vehicle = Cast_Object(Vehicle *, entity);
vehicle->TurnOn();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::StartUpdates()
{
tServerRewind = 0;
tServerEncode = 0;
tClientDecode = 0;
tClientEncode = 0;
//SPEW(("jerryeds","SIM EXECUTE"));
// clear out any frame by frame stuff here.
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::EndUpdates()
{
if (m_uPostDeathFlags) {
if (m_uPostDeathFlags & 1) {
VehicleInterface* pVI = VehicleInterface::GetInstance();
if (pVI) {
pVI->ReactToEvent(VehicleInterface::CRITICAL_HIT_GIMP);
}
}
m_uPostDeathFlags = 0;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::StartClient()
{
Verify(clientController == NULL);
clientController = new ClientController;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::StopClient()
{
if (clientController != NULL)
{
delete clientController;
clientController = NULL;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::StartServer()
{
Verify(serverController == NULL);
serverController = new ServerController;
if (g_nMR == 2) {
StartClient();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::StopServer()
{
if (g_nMR == 2) {
StopClient();
}
if (serverController != NULL)
{
delete serverController;
serverController = NULL;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::Reset()
{
maximumNearBuildings = 124;
maximumMidBuildings = 256;
maximumFarBuildings = 256;
if (clientController != NULL)
{
clientController->Reset();
}
if (serverController != NULL)
{
serverController->Reset();
}
lastExecuted = 0.0f;
for (int i = 0; i < Maximum_Players; ++i)
{
playerVehicle[i] = NULL;
if (dictionaryManager[i] != NULL)
{
delete dictionaryManager[i];
dictionaryManager[i] = NULL;
}
}
Stuff::ChainIteratorOf<WeaponUpdate*> iterator(&weaponUpdates);
WeaponUpdate *update;
while ((update = iterator.GetCurrent()) != NULL)
{
iterator.Remove();
delete update;
}
Stuff::ChainIteratorOf<WeaponUpdate*> iterator1(&networkWeaponsQue);
while ((update = iterator1.GetCurrent()) != NULL)
{
iterator1.Remove();
delete update;
}
ChainIteratorOf<VehicleCommand*> command_iterator(&quedCommands);
VehicleCommand *command;
while ((command = command_iterator.GetCurrent()) != NULL)
{
command_iterator.Remove();
delete command;
}
commandCount = 0;
m_uPostDeathFlags = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::PreCollisionNetworkEvents()
{
Stuff::ChainIteratorOf<WeaponUpdate*> iterator1(&networkWeaponsQue);
WeaponUpdate *update;
while ((update = iterator1.GetCurrent()) != NULL)
{
CreateWeaponEffect(*update);
iterator1.Remove();
delete update;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWEntityManager::MWEntityManager():
EntityManager(DefaultData),
servedMechs(NULL, false),
servedRespawnLances(NULL), // jcem - for delayed lancemate respawn
servedAirplanes(NULL),
servedBoats(NULL),
servedDropships(NULL),
servedHelicopters(NULL),
servedHovercraft(NULL),
servedTanks(NULL),
servedTrucks(NULL),
servedTurrets(NULL),
weaponUpdates(NULL),
networkWeaponsQue(NULL),
quedCommands(NULL)
{
Check_Pointer(this);
dictionaryDirtyFlag = false;
lastExecuted = 0.0f;
lastScore = 0.0;
lastWeapon = 0.0;
lastActiveReset = 0.0f;
maximumNearBuildings = 124;
maximumMidBuildings = 256;
maximumFarBuildings = 256;
for (int i = 0; i < Maximum_Players; ++i)
{
playerVehicle[i] = NULL;
dictionaryManager[i] = NULL;
}
serverController = NULL;
clientController = NULL;
commandCount = 0;
m_uPostDeathFlags = 0;
//open the bitdepth file
bitManager = new BitDepthManager;
bitManager->InitilizeBitDepths();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWEntityManager::~MWEntityManager()
{
Check_Pointer(this);
bitManager->TerminateBitDepths();
delete bitManager;
Verify(serverController == NULL);
Verify(clientController == NULL);
for (int i = 0; i < Maximum_Players; ++i)
{
if (dictionaryManager[i] != NULL)
{
delete dictionaryManager[i];
dictionaryManager[i] = NULL;
}
}
Stuff::ChainIteratorOf<WeaponUpdate*> iterator(&weaponUpdates);
WeaponUpdate *update;
while ((update = iterator.GetCurrent()) != NULL)
{
iterator.Remove();
delete update;
}
Stuff::ChainIteratorOf<WeaponUpdate*> iterator1(&networkWeaponsQue);
while ((update = iterator1.GetCurrent()) != NULL)
{
iterator1.Remove();
delete update;
}
ChainIteratorOf<VehicleCommand*> command_iterator(&quedCommands);
VehicleCommand *command;
while ((command = command_iterator.GetCurrent()) != NULL)
{
command_iterator.Remove();
delete command;
}
commandCount = 0;
m_uPostDeathFlags = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::ServeLocalEntities(Time till)
{
Scalar time_slice = GetTimeSlice(till);
if (!Application::GetInstance()->networkingFlag)
{
lastExecuted = till;
return;
}
if (Mission::GetInstance() && ((till - lastScore) > 5.0))
{
lastScore = till;
Mission::GetInstance()->scoreDirty = true;
}
MWApplication *app = MWApplication::GetInstance();
if (!app->serverFlag)
{
// client control updates
__int64 temp=GetCycles();
{
#ifdef GROUP_ADEPT_NETWORK
LOG_BLOCK("Game Logic::Network::Send Weapon Packets To Server");
#endif
clientController->SendWeaponCommands();
}
{
#ifdef GROUP_ADEPT_NETWORK
LOG_BLOCK("Game Logic::Network::Send Control Packets To Server");
#endif
clientController->SendControlPacketToServer(time_slice);
}
tClientEncode+=GetCycles() - temp;
lastExecuted = till;
return;
}
else
{
//we are server
#ifdef GROUP_ADEPT_NETWORK
LOG_BLOCK("Game Logic::Network::Encode Dictionary");
#endif
if ((till - lastWeapon) > 0.25)
{
lastWeapon = till;
while(serverController->SendWeaponCommands())
{
}
}
if ((dictionaryDirtyFlag == true) || ((g_nMR == 1) && !dictionaryManager[1]))
{
// make and send a new dictionary
UpdateDictionaries();
app->SendScore();
Mission::GetInstance()->scoreDirty = false;
}
else if (Mission::GetInstance()->scoreDirty)
{
app->SendScore();
Mission::GetInstance()->scoreDirty = false;
}
// run through the updates...
// right now we just count em down...
if ((g_nMR == 1) && dictionaryManager[1]) {
Dictionary *dictionary = dictionaryManager[1]->GetCurrentDictionary();
if (dictionary) {
int nWritten = 0;
DynamicMemoryStream movement_packet(MWEntityManager::Packet_Buffer, DefaultPacketBufferSize);
movement_packet.WriteBits(&dictionary->versionNumber,8);
Stuff::SortedChainIteratorOf<Mech*, Adept::ReplicatorID> iterator(&servedMechs);
Mech* mech;
while ((mech = iterator.ReadAndNext()) != NULL)
{
Check_Object(mech);
ReplicatorID id = mech->GetReplicatorID();
movement_packet.WriteBits(&id.connectionID, 8);
movement_packet.WriteBits(&id.localID, 16);
MechPositionUpdate::Encode(mech, &movement_packet, id.connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth);
ExternalJumpJetUpdate::Encode(mech, &movement_packet, id.connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth);
MechInternalDamageUpdate::Encode(mech, &movement_packet, id.connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth);
movement_packet.WriteByteAlign();
nWritten++;
}
if (nWritten > 0) {
movement_packet.Rewind();
}
g_MRF.SendMessage(nWritten, &movement_packet, MRP_FULLCONFIRM);
}
}
__int64 temp=GetCycles();
if (g_nMR != 2) {
for (int i = 0; i < Maximum_Players; ++i)
{
if (app->servedConnectionData[i].clientLoaded && dictionaryManager[i])
{
if (i == Connection::Server->GetID()) {
if ((g_nMR != 1) || (g_MRF.m_nCount < 0))
continue;
}
Check_Object(dictionaryManager[i]);
dictionaryManager[i]->Encode(till);
}
}
}
if (((till - lastActiveReset) > 2.0))
{
lastActiveReset = till;
ResetActivityFlags();
}
tServerEncode+=GetCycles()-temp;
}
lastExecuted = till;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
MWEntityManager::ResetActivityFlags()
{
Stuff::SortedChainIteratorOf<Mech*, Adept::ReplicatorID> iterator(&servedMechs);
Mech *mech;
Scalar current_time = (Scalar)gos_GetElapsedTime();
while ((mech = iterator.ReadAndNext()) != NULL)
{
if (mech->takenDamageThisFrame)
{
if (current_time - mech->lastDamageTaken > 2.0f)
{
mech->takenDamageThisFrame = false;
mech->lastDamageTaken = 0.0f;
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
MWEntityManager::UpdateEntities()
{
// NO MORE CLIENT UPDATES
return;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int Exit_Count = 0;
void MWEntityManager::UpdateClientEntites(int connection, int message_type, Stuff::MemoryStream *message)
{
MWApplication *app = MWApplication::GetInstance();
switch (app->GetApplicationState())
{
case ApplicationStateEngine::RunningGameState:
break;
default:
return;
};
// decode and update the entites...
if (message_type == DictionaryIndexMessageID)
{
#if defined(_DEBUG) && 0 // jcem - for MR test
{
char Buffer[128];
sprintf(Buffer, "EntityMgr:: DictionaryIndexMessageID\n");
OutputDebugString(Buffer);
}
#endif // _DEBUG && ...
//SPEW(("jerryeds", "%d : RECIEVE INDEX", Connection::Local->GetID()));
Network::GetInstance()->netStatCollector[Network::IncomingSystemMessageBitSizeStat].AddToStatistic(connection,message->GetBufferBytesUsed()*8);
Verify(!Network::GetInstance()->AmIServer());
// make the index
__int64 temp=GetCycles();
// we might as well use our own id!
if (dictionaryManager[Connection::Local->GetID()] == NULL)
{
dictionaryManager[Connection::Local->GetID()] = new DictionaryManager(Connection::Local->GetID());
}
int version = 0;
int debug_level = 0;
int bandwidth = 0;
message->ReadBits(&version, 8);
message->ReadBits(&debug_level, 2);
message->ReadBits(&bandwidth, 2);
int player_count = 0; // jcem: critical error - should clear before ReadBits(...)...
message->ReadBits(&player_count, 8);
int vehicle_id[Maximum_Players];
for (int j = 0; j < Maximum_Players; ++j)
{
vehicle_id[j] = -1;
}
for(j = 0; j < player_count; ++j)
{
BYTE player;
int id;
message->ReadBits(&player,8);
message->ReadBits(&id, 32);
vehicle_id[player] = id;
}
bool error = false;
for ( j = 0; j < Maximum_Players; ++j)
{
if (vehicle_id[j] == -1)
{
if (app->servedConnectionData[j].clientConnected && app->servedConnectionData[j].clientPlayer)
{
//STOP(("GAME STATE DOESNT MATCH ---- %d : LOADED BUT SHOULDNT BE", j));
// FAIL
#ifdef LAB_ONLY
PAUSE(("GAME STATE DOESNT MATCH ---- %d : LOADED BUT SHOULDNT BE", j));
#endif
error = true;
}
}
else
{
if (app->servedConnectionData[j].clientConnected && app->servedConnectionData[j].clientPlayer)
{
ResourceID id = app->servedConnectionData[j].clientPlayer->vehicle->GetGameModelResourceID();
if (id.GetRecordID() != vehicle_id[j])
{
//STOP(("GAME STATE DOESNT MATCH ---- %d : Not in correct vehicle", j));
#ifdef LAB_ONLY
PAUSE(("GAME STATE DOESNT MATCH ---- %d : Not in correct vehicle", j));
#endif
error = true;
}
}
else
{
//STOP(("GAME STATE DOESNT MATCH ---- %d : Not loaded", j));
#ifdef LAB_ONLY
PAUSE(("GAME STATE DOESNT MATCH ---- %d : Not in correct vehicle", j));
#endif
error = true;
}
}
}
if (error)
{
++Exit_Count;
}
else
{
Exit_Count = 0;
}
if (Exit_Count)
{
if(Exit_Count < 10)
MWApplication::GetInstance()->SendRequestNewDictionaryMessage();
else
MWApplication::GetInstance()->QueStopGame();
return;
}
Dictionary *dictionary = dictionaryManager[Connection::Local->GetID()]->MakeNewDictionary(version, debug_level, bandwidth);
MakeDictionaryPages(dictionary);
#if defined(LAB_ONLY)
MWGameInfo::g_networkDebugLevel[Connection::Local->GetID()] = dictionary->debugDictionaryLevel;
MWGameInfo::g_connectRate[Connection::Local->GetID()] = dictionary->dictionaryBandwidth;
#endif
tClientDecode+=GetCycles()-temp;
return;
}
// we will take dictionaries but nothing else unless we are running...
// we will be loaded by the time that message arrives...
if (
app->GetApplicationState() !=
ApplicationStateEngine::RunningGameState
)
{
return;
}
if(message_type == FirstPersonControlMessageID && playerVehicle[connection] != NULL)
{
Verify(Network::GetInstance()->AmIServer());
#if defined(_DEBUG) && 0 // jcem - for MR test
{
char Buffer[128];
sprintf(Buffer, "EntityMgr:: FirstPersonControlMessageID\n");
OutputDebugString(Buffer);
}
#endif // _DEBUG && ...
serverController->ReceivePlayerControl(connection,message);
}
else if (message_type == FirstPersonObserverControlMessageID)
{
Verify(Network::GetInstance()->AmIServer());
#if defined(_DEBUG) && 0 // jcem - for MR test
{
char Buffer[128];
sprintf(Buffer, "EntityMgr:: FirstPersonObserverControlMessageID\n");
OutputDebugString(Buffer);
}
#endif // _DEBUG && ...
serverController->ReceivePlayerObserverControl(connection,message);
}
else if (message_type == FirstPersonControlMessageID && playerVehicle[connection] == NULL)
{
SPEW(("jerryeds", "received control message from %d but do not have mech in list!!!!", connection));
}
else if (message_type == FirstPersonFullConfirmationMessageID)
{
Verify(!Network::GetInstance()->AmIServer());
#if defined(_DEBUG) && 0 // jcem - for MR test
{
char Buffer[128];
sprintf(Buffer, "EntityMgr:: FirstPersonFullConfirmationMessageID\n");
OutputDebugString(Buffer);
}
#endif // _DEBUG && ...
clientController->ReceiveFullConfirmation(message);
}
else if (message_type == FirstPersonSmallConfirmationMessageID)
{
Network::GetInstance()->netStatCollector[Network::MovementConfirmationBitSizeStat].AddToStatistic(connection,message->GetBufferBytesUsed()*8);
Verify(!Network::GetInstance()->AmIServer());
#if defined(_DEBUG) && 0 // jcem - for MR test
{
char Buffer[128];
sprintf(Buffer, "EntityMgr:: FirstPersonSmallConfirmationMessageID\n");
OutputDebugString(Buffer);
}
#endif // _DEBUG && ...
clientController->ReceiveSmallConfirmation(message);
}
else if (message_type >= MWEntityManager::StartThirdPersonWeaponMessageID && message_type <= MWEntityManager::EndThirdPersonWeaponMessageID)
{
Network::GetInstance()->netStatCollector[Network::IncomingWeaponMessageBitSizeStat].AddToStatistic(connection,message->GetBufferBytesUsed()*8);
clientController->ReceiveWeaponCommand(connection, message_type, message);
}
else if (message_type >= MWEntityManager::StartFirstPersonWeaponMessageID && message_type <= MWEntityManager::EndFirstPersonWeaponMessageID)
{
Network::GetInstance()->netStatCollector[Network::IncomingWeaponMessageBitSizeStat].AddToStatistic(connection,message->GetBufferBytesUsed()*8);
serverController->ReceiveWeaponCommand(connection, message_type, message);
}
else if (message_type >= MWEntityManager::StartAIWeaponMessageID && message_type <= MWEntityManager::EndAIWeaponMessageID)
{
Network::GetInstance()->netStatCollector[Network::IncomingWeaponMessageBitSizeStat].AddToStatistic(connection,message->GetBufferBytesUsed()*8);
clientController->ReceiveWeaponCommand(connection, message_type, message);
}
else if (message_type == MWEntityManager::WeaponBundleMessageID)
{
Network::GetInstance()->netStatCollector[Network::IncomingWeaponMessageBitSizeStat].AddToStatistic(connection,message->GetBufferBytesUsed()*8);
#if defined(_DEBUG) && 0 // jcem - for MR test
{
char Buffer[128];
sprintf(Buffer, "EntityMgr:: MWEntityManager::WeaponBundleMessageID\n");
OutputDebugString(Buffer);
}
#endif // _DEBUG && ...
clientController->ReceiveWeaponBundle(connection, message_type, message);
}
else if (message_type >= MWEntityManager::DictionaryPage0MessageID && message_type <= MWEntityManager::DictionaryPageMaxMessageID)
{
if (dictionaryManager[Connection::Local->GetID()] == NULL)
return;
#if defined(_DEBUG) && 0 // jcem - for MR test
{
char Buffer[128];
sprintf(Buffer, "EntityMgr:: MWEntityManager::DictionaryPage###\n");
OutputDebugString(Buffer);
}
#endif // _DEBUG && ...
if (g_nMR != 2)
NetVerify(!Network::GetInstance()->AmIServer());
NetVerify(message != NULL);
NetVerify(message->GetBytesRemaining() > 0);
dictionaryManager[Connection::Local->GetID()]->Decode(message_type, message);
}
else
{
STOP(("MWEntityManager::UNHANDLED PACKET!!!!!"));
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::CreateWeaponEffect(WeaponUpdate &weapon_packet)
{
if (weapon_packet.obsolete)
return;
if (weapon_packet.originator.GetCurrent() == NULL)
return;
//make the collision query...
Stuff::Point3D local_point;
Stuff::Point3D origin_point;
LinearMatrix4D our_matrix;
MWObject *vehicle = Cast_Object(MWObject *, weapon_packet.originator.GetCurrent());
// the packet originiated locally.
if (g_nMR != 2) {
if (vehicle->GetReplicatorID().connectionID == Connection::Local->GetID())
{
return;
}
}
LinearMatrix4D eye_mat;
origin_point = vehicle->GetLocalToWorld();
eye_mat = vehicle->GetLocalToWorld();
if(vehicle->eyeSitePointer.GetCurrent())
{
origin_point = vehicle->eyeSitePointer.GetCurrent()->GetLocalToWorld();
eye_mat = vehicle->eyeSitePointer.GetCurrent()->GetLocalToWorld();
}
else
{
Stuff::ChainIteratorOf<Weapon*> iterator(&vehicle->weaponChain);
Weapon *weapon;
if ((weapon = iterator.ReadAndNext()) != NULL)
{
if (weapon->sitePointer)
{
origin_point = weapon->sitePointer->GetLocalToWorld();
eye_mat = weapon->sitePointer->GetLocalToWorld();
}
}
}
Vector3D line_direction;
Point3D target_point = Point3D::Identity;
if (weapon_packet.target.GetCurrent() != NULL)
{
if (weapon_packet.target.GetCurrent() != Map::GetInstance())
{
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - packet target is not a map"));
//target_point = weapon_packet.target->GetLocalToWorld();
//target_point += weapon_packet.targetOffset;
target_point.Multiply(weapon_packet.targetOffset, weapon_packet.target.GetCurrent()->GetLocalToWorld());
}
else
{
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - packet target is a map"));
target_point = weapon_packet.targetOffset;
}
line_direction.Subtract(target_point, origin_point);
}
else
{
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - packet target is NULL"));
//UnitVector3D temp_vector;
//eye_mat.GetLocalForwardInWorld(&temp_vector);
//line_direction = temp_vector;
Point3D target_point;
target_point = weapon_packet.targetOffset;
line_direction.Subtract(target_point, origin_point);
}
Stuff::Normal3D normal(0.0f, 1.0f, 0.0f);
Stuff::Line3D target_line;
target_line.SetOrigin(origin_point);
target_line.SetDirection(line_direction);
target_line.m_length = 1500.0f;
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - target_line origin, %f, %f, %f", origin_point.x, origin_point.y, origin_point.z));
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - target_line direction, %f, %f, %f", line_direction.x, line_direction.y, line_direction.z));
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - target_line length, %f", 1500));
Adept::Entity::CollisionQuery query(&target_line, &normal, Adept::Entity::CanBeShotFlag, weapon_packet.originator.GetCurrent());
Adept::Entity *entity_hit = NULL;
Check_Object(CollisionGrid::Instance);
entity_hit = CollisionGrid::Instance->ProjectLine(&query);
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - query line origin, %f, %f, %f", query.m_line->m_origin.x, query.m_line->m_origin.y, query.m_line->m_origin.z));
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - query line direction, %f, %f, %f", query.m_line->m_direction.x, query.m_line->m_direction.y, query.m_line->m_direction.z));
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - query line length, %f", query.m_line->m_length));
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - query normal, %f, %f, %f", query.m_normal->x, query.m_normal->y, query.m_normal->z));
// {
// Stuff::Point3D target_point;
// query.m_line->FindEnd(&target_point);
//
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - target_point, %f, %f, %f",
// target_point.x,
// target_point.y,
// target_point.z));
// }
#ifdef _ARMOR
// if (entity_hit != NULL && weapon_packet.target != NULL && weapon_packet.target->instanceName && entity_hit->instanceName )
// SPEW(("jerryeds", "AIMED AT %s, HIT : %s", (char*)weapon_packet.target->instanceName, (char*)entity_hit->instanceName));
// else if (weapon_packet.target != NULL && weapon_packet.target->instanceName)
// SPEW(("jerryeds", "AIMED AT %s, MISSEd", (char*)weapon_packet.target->instanceName));
// else
// SPEW(("jerryeds", "NO NAMES"));
//
// SPEW(("jerryeds", "TARGETPOINT : <%f:%f:%f> ", target_point.x, target_point.y, target_point.z));
#endif
if (weapon_packet.target.GetCurrent() && weapon_packet.target.GetCurrent()->IsDerivedFrom(Vehicle::DefaultData))
{
/*
SPEWALWAYS(("jackyc", "CreateWeaponEffect - weapon_packet.target.GetCurrent()"));
if (weapon_packet.target.GetCurrent() == NULL)
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To No Target"));
}
else if (weapon_packet.target.GetCurrent() == Map::GetInstance())
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To Ground or No Target"));
}
else if (weapon_packet.target.GetCurrent()->GetReplicatorID().connectionID == Connection::Hermit->GetID())
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To Ground"));
}
else if (weapon_packet.target.GetCurrent()->GetReplicatorID().connectionID != Connection::Server->GetID())
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To Mech"));
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To Mech"));
SPEWALWAYS(("jackyc", "CreateWeaponEffect - Mech connection ID, %d, %d",
weapon_packet.target.GetCurrent()->GetReplicatorID().connectionID,
weapon_packet.target.GetCurrent()->GetReplicatorID().localID));
Entity* parent_target = weapon_packet.target.GetCurrent();
int class_id = parent_target->GetClassID();
if (class_id == MWMoverClassID)
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - Mover Name - NOT AVAILABLE"));
}
else
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - Not a MWMover"));
}
}
else if (weapon_packet.target.GetCurrent()->GetReplicatorID().connectionID == Connection::Server->GetID())
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To Server"));
}
*/
query.m_raySource = weapon_packet.target.GetCurrent();
}
else
{
/*
SPEWALWAYS(("jackyc", "CreateWeaponEffect - entity_hit"));
if (entity_hit == NULL)
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To No Target"));
}
else if (entity_hit == Map::GetInstance())
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To Ground or No Target"));
}
else if (entity_hit->GetReplicatorID().connectionID == Connection::Hermit->GetID())
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To Ground"));
}
else if (entity_hit->GetReplicatorID().connectionID != Connection::Server->GetID())
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To Mech"));
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To Mech"));
SPEWALWAYS(("jackyc", "CreateWeaponEffect - Mech connection ID, %d, %d",
entity_hit->GetReplicatorID().connectionID,
entity_hit->GetReplicatorID().localID));
Entity* parent_target = entity_hit;
int class_id = parent_target->GetClassID();
if (class_id == MWMoverClassID)
{
// MWMover* mover = Cast_Object(MWMover*, parent_target);
// if (entity_hit->instanceName)
// {
// SPEWALWAYS(("jackyc", "CreateWeaponEffect - Mover Name - %s", (char*)entity_hit->instanceName));
// }
// else
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - Mover Name - NOT AVAILABLE"));
}
}
else
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - Not a MWMover"));
}
}
else if (entity_hit->GetReplicatorID().connectionID == Connection::Server->GetID())
{
SPEWALWAYS(("jackyc", "CreateWeaponEffect - First Person Weapon To Server"));
}
*/
query.m_raySource = entity_hit;
}
// missile lock vector is straight ahead...
//UnitVector3D temp_vector;
//eye_mat.GetLocalForwardInWorld(&temp_vector);
//line_direction = temp_vector;
#if 0
Stuff::Normal3D lock_normal(0.0f, 1.0f, 0.0f);
Stuff::Line3D locktarget_line;
locktarget_line.SetOrigin(origin_point);
locktarget_line.SetDirection(line_direction);
locktarget_line.m_length = 1000.0f;
Adept::Entity::CollisionQuery lock_query(&locktarget_line, &lock_normal, Adept::Entity::CanBeShotFlag, weapon_packet.originator.GetCurrent());
lock_query.m_raySource = weapon_packet.target.GetCurrent();
#endif
Stuff::ChainIteratorOf<Weapon*> iterator(&vehicle->weaponChain);
Weapon *weapon;
while ((weapon = iterator.ReadAndNext()) != NULL)
{
int id = weapon->GetWeaponID();
if (weapon_packet.weaponFired & (0x1 << id))
{
if (weapon->IsDerivedFrom(MissileWeapon::DefaultData))
{
MissileWeapon *missile_weapon;
missile_weapon = Cast_Object(MissileWeapon *, weapon);
query.m_raySource = weapon_packet.target.GetCurrent();
if (missile_weapon->IsAMSValid(weapon_packet.target.GetCurrent()))
{
missile_weapon->SetAMSNumber(weapon_packet.AntiWeaponCount[id]);
}
weapon->FireWeapon(&query, weapon_packet.lockTime, Stuff::Point3D::Identity);
}
else
{
weapon->FireWeapon(&query, weapon_packet.lockTime, Stuff::Point3D::Identity);
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::UpdateDictionaries(void)
{
if (g_nMR != 2) {
MWApplication *app = MWApplication::GetInstance();
for (int i = 0; i < Maximum_Players; ++i)
{
// if they are connected and have a vehicle
// than make them one.
if (app->servedConnectionData[i].clientConnected && app->servedConnectionData[i].clientLoaded)
{
//SPEW(("jerryeds", "%d : SEND INDEX : %d", Connection::Local->GetID(), i));
if (i == Connection::Server->GetID()) {
if ((g_nMR != 1) || (g_MRF.m_nCount < 0))
continue;
int nForceConnectionSpeedOld = MWApplication::ForceConnectionSpeed;
MWApplication::ForceConnectionSpeed = BitDepthManager::HighBandwidth; // BitDepthManager::LowBandwidth, BitDepthManager::MediumBandwidth
UpdateDictionaries(i);
MWApplication::ForceConnectionSpeed = nForceConnectionSpeedOld;
} else {
UpdateDictionaries(i);
}
}
else
{
if (dictionaryManager[i] != NULL)
{
Unregister_Object(dictionaryManager[i]);
delete dictionaryManager[i];
dictionaryManager[i] = NULL;
}
}
}
}
dictionaryDirtyFlag = false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::UpdateDictionaries(int i)
{
if (g_nMR != 2) {
MWApplication *app = MWApplication::GetInstance();
if (dictionaryManager[i] == NULL)
{
dictionaryManager[i] = new DictionaryManager(i);
Register_Object(dictionaryManager[i]);
}
int connection_rate = BitDepthManager::LowBandwidth;
if (MWApplication::ForceConnectionSpeed != -1)
{
connection_rate = MWApplication::ForceConnectionSpeed;
}
else if (app->servedConnectionData[i].bandwidthThrottle)
{
connection_rate = BitDepthManager::LowBandwidth;
}
else if (MWApplication::MyConnectionSpeed >= MWApplication::c_1500_kbps)
{
if (app->servedConnectionData[i].clientConnectionRate >= MWApplication::c_1500_kbps)
{
connection_rate = BitDepthManager::HighBandwidth;
}
else if (app->servedConnectionData[i].clientConnectionRate >= MWApplication::c_128_kbps)
{
connection_rate = BitDepthManager::MediumBandwidth;
}
else
{
connection_rate = BitDepthManager::LowBandwidth;
}
}
else if (MWApplication::MyConnectionSpeed >= MWApplication::c_768_kbps)
{
if (app->servedConnectionData[i].clientConnectionRate > MWApplication::c_64_kbps)
{
connection_rate = BitDepthManager::MediumBandwidth;
}
else
{
connection_rate = BitDepthManager::LowBandwidth;
}
}
else
{
connection_rate = BitDepthManager::LowBandwidth;
}
#if defined(LAB_ONLY)
MWGameInfo::g_networkDebugLevel[i] = MWApplication::NetworkDebugLevel;
MWGameInfo::g_connectRate[i] = connection_rate;
#endif
Dictionary *dictionary = dictionaryManager[i]->MakeNewDictionary(dictionaryManager[i]->GetNextDictionaryID(), MWApplication::NetworkDebugLevel, connection_rate);
MakeDictionaryPages(dictionary);
DynamicMemoryStream stream;
//dictionaryManager[i]->EncodeDictionary(&stream);
stream.WriteBits(&dictionary->versionNumber, 8);
stream.WriteBits(&dictionary->debugDictionaryLevel, 2);
stream.WriteBits(&dictionary->dictionaryBandwidth, 2);
BYTE player_count = 0;
for (int j = 0; j < Maximum_Players; ++j)
{
if (app->servedConnectionData[j].clientConnected && app->servedConnectionData[j].clientPlayer)
{
++player_count;
}
}
stream.WriteBits(&player_count, 8);
for ( j = 0; j < Maximum_Players; ++j)
{
if (app->servedConnectionData[j].clientConnected && app->servedConnectionData[j].clientPlayer)
{
ResourceID id = app->servedConnectionData[j].clientPlayer->vehicle->GetGameModelResourceID();
int sub_id = id.GetRecordID();
stream.WriteBits(&j,8);
stream.WriteBits(&sub_id, 32);
}
}
stream.WriteByteAlign();
stream.Rewind();
// This is dangerous as it creates NEW pages that will
// be updated. ICK. That doubles the bandwidth on
// a armor build!!!!
//#if defined(_ARMOR)
//dictionaryManager[i]->DecodeDictionary(&stream);
//stream.Rewind();
//#endif
// send the dictionary
Check_Object(Application::GetInstance());
// break up the message...
Network::GetInstance()->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(i,stream.GetBufferBytesUsed()*8);
Network::GetInstance()->SendNetMessage(i, DictionaryIndexMessageID, &stream, true);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::MakeDictionaryPages(Dictionary *dictionary)
{
Stuff::SortedChainIteratorOf<Mech*, Adept::ReplicatorID> iterator(&servedMechs);
int connection_rate = dictionary->dictionaryBandwidth;
NetUpdateSorter sorter(dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth);
Entity *entity;
if (g_nMR && (dictionary->connectionID == 1)) {
while ((entity = iterator.ReadAndNext()) != NULL)
{
Check_Object(entity);
//-sorter.AddUpdateToList(entity, UpdateManager::MechPositionUpdateID, bitManager->GetUpdateRate(UpdateManager::MechPositionUpdateID, connection_rate));
//sorter.AddUpdateToList(entity, UpdateManager::MechAnimationUpdateID, bitManager->GetUpdateRate(UpdateManager::MechAnimationUpdateID, connection_rate));
//sorter.AddUpdateToList(entity, UpdateManager::MechMovemntUpdateID, bitManager->GetUpdateRate(UpdateManager::MechMovemntUpdateID, connection_rate));
//sorter.AddUpdateToList(entity, UpdateManager::MechExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::MechExternalDamageUpdateID, connection_rate));
//jcem-dead or alive-sorter.AddUpdateToList(entity, UpdateManager::MechInternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::MechExternalDamageUpdateID, connection_rate));
//--sorter.AddUpdateToList(entity, UpdateManager::MechInternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::MechInternalDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::MechInternalHeatUpdateID, bitManager->GetUpdateRate(UpdateManager::MechInternalHeatUpdateID, connection_rate)); //
sorter.AddUpdateToList(entity, UpdateManager::SubsystemUpdateID, bitManager->GetUpdateRate(UpdateManager::SubsystemUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::FlushUpdateID, bitManager->GetUpdateRate(UpdateManager::FlushUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::SearchLightUpdateID, bitManager->GetUpdateRate(UpdateManager::SearchLightUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::ExternalAMSAmmoUpdateID, bitManager->GetUpdateRate(UpdateManager::ExternalAMSAmmoUpdateID, connection_rate));
//-sorter.AddUpdateToList(entity, UpdateManager::ExternalJumpJetUpdateID, bitManager->GetUpdateRate(UpdateManager::ExternalJumpJetUpdateID, connection_rate));
//--sorter.AddUpdateToList(entity, UpdateManager::InternalAMSAmmoUpdateID, bitManager->GetUpdateRate(UpdateManager::InternalAMSAmmoUpdateID, connection_rate));
//--sorter.AddUpdateToList(entity, UpdateManager::InternalJumpJetUpdateID, bitManager->GetUpdateRate(UpdateManager::InternalJumpJetUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::NearBuildingExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::NearBuildingExternalDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::SecondaryBuildingExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::SecondaryBuildingExternalDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::FarBuildingExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::FarBuildingExternalDamageUpdateID, connection_rate));
if (entity->IsPlayerVehicle())
{
//sorter.AddUpdateToList(entity, UpdateManager::PingUpdateID, bitManager->GetUpdateRate(UpdateManager::PingUpdateID, connection_rate));
}
}
entity = MWApplication::GetInstance()->servedConnectionData[dictionary->connectionID].clientPlayer->vehicle;
//-sorter.AddUpdateToList(entity, UpdateManager::SecurityResponseID, bitManager->GetUpdateRate(UpdateManager::SecurityResponseID, connection_rate));
//-sorter.AddUpdateToList(entity, UpdateManager::SecurityQueryID, bitManager->GetUpdateRate(UpdateManager::SecurityQueryID, connection_rate));
//-sorter.AddUpdateToList(entity, UpdateManager::SecurityQueryID, bitManager->GetUpdateRate(UpdateManager::SecurityQueryID, connection_rate));
//-sorter.AddUpdateToList(entity, UpdateManager::TimeUpdateID, bitManager->GetUpdateRate(UpdateManager::TimeUpdateID, connection_rate));
// moved to above : 3 lines
//-sorter.AddUpdateToList(entity, UpdateManager::NearBuildingExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::NearBuildingExternalDamageUpdateID, connection_rate));
//-sorter.AddUpdateToList(entity, UpdateManager::SecondaryBuildingExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::SecondaryBuildingExternalDamageUpdateID, connection_rate));
//-sorter.AddUpdateToList(entity, UpdateManager::FarBuildingExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::FarBuildingExternalDamageUpdateID, connection_rate));
//-sorter.AddUpdateToList(entity, UpdateManager::MissionObjectiveUpdateID, bitManager->GetUpdateRate(UpdateManager::MissionObjectiveUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::VehicleDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::VehicleDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::NavPointUpdateID, bitManager->GetUpdateRate(UpdateManager::NavPointUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::FlagUpdateID, bitManager->GetUpdateRate(UpdateManager::FlagUpdateID, connection_rate));
} else {
gosASSERT(g_nMR != 2);
while ((entity = iterator.ReadAndNext()) != NULL)
{
Check_Object(entity);
if (entity->GetReplicatorID().connectionID != dictionary->connectionID)
{
sorter.AddUpdateToList(entity, UpdateManager::MechPositionUpdateID, bitManager->GetUpdateRate(UpdateManager::MechPositionUpdateID, connection_rate));
//sorter.AddUpdateToList(entity, UpdateManager::MechAnimationUpdateID, bitManager->GetUpdateRate(UpdateManager::MechAnimationUpdateID, connection_rate));
//sorter.AddUpdateToList(entity, UpdateManager::MechMovemntUpdateID, bitManager->GetUpdateRate(UpdateManager::MechMovemntUpdateID, connection_rate));
//sorter.AddUpdateToList(entity, UpdateManager::MechExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::MechExternalDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::MechInternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::MechExternalDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::SubsystemUpdateID, bitManager->GetUpdateRate(UpdateManager::SubsystemUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::FlushUpdateID, bitManager->GetUpdateRate(UpdateManager::FlushUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::SearchLightUpdateID, bitManager->GetUpdateRate(UpdateManager::SearchLightUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::ExternalAMSAmmoUpdateID, bitManager->GetUpdateRate(UpdateManager::ExternalAMSAmmoUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::ExternalJumpJetUpdateID, bitManager->GetUpdateRate(UpdateManager::ExternalJumpJetUpdateID, connection_rate));
if (entity->IsPlayerVehicle())
{
sorter.AddUpdateToList(entity, UpdateManager::PingUpdateID, bitManager->GetUpdateRate(UpdateManager::PingUpdateID, connection_rate));
}
}
else
{
if (entity->IsPlayerVehicle())
{
sorter.AddUpdateToList(entity, UpdateManager::MechInternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::MechInternalDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::MechInternalHeatUpdateID, bitManager->GetUpdateRate(UpdateManager::MechInternalHeatUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::SubsystemUpdateID, bitManager->GetUpdateRate(UpdateManager::SubsystemUpdateID, connection_rate));
//sorter.AddUpdateToList(entity, UpdateManager::FlushUpdateID, bitManager->GetUpdateRate(UpdateManager::FlushUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::SearchLightUpdateID, bitManager->GetUpdateRate(UpdateManager::SearchLightUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::InternalAMSAmmoUpdateID, bitManager->GetUpdateRate(UpdateManager::InternalAMSAmmoUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::InternalJumpJetUpdateID, bitManager->GetUpdateRate(UpdateManager::InternalJumpJetUpdateID, connection_rate));
}
}
}
entity = MWApplication::GetInstance()->servedConnectionData[dictionary->connectionID].clientPlayer->vehicle;
sorter.AddUpdateToList(entity, UpdateManager::SecurityResponseID, bitManager->GetUpdateRate(UpdateManager::SecurityResponseID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::SecurityQueryID, bitManager->GetUpdateRate(UpdateManager::SecurityQueryID, connection_rate));
// sorter.AddUpdateToList(entity, UpdateManager::SecurityQueryID, bitManager->GetUpdateRate(UpdateManager::SecurityQueryID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::TimeUpdateID, bitManager->GetUpdateRate(UpdateManager::TimeUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::NearBuildingExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::NearBuildingExternalDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::SecondaryBuildingExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::SecondaryBuildingExternalDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::FarBuildingExternalDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::FarBuildingExternalDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::MissionObjectiveUpdateID, bitManager->GetUpdateRate(UpdateManager::MissionObjectiveUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::VehicleDamageUpdateID, bitManager->GetUpdateRate(UpdateManager::VehicleDamageUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::NavPointUpdateID, bitManager->GetUpdateRate(UpdateManager::NavPointUpdateID, connection_rate));
sorter.AddUpdateToList(entity, UpdateManager::FlagUpdateID, bitManager->GetUpdateRate(UpdateManager::FlagUpdateID, connection_rate));
}
Stuff::ChainIteratorOf<Airplane*> iterator1(&servedAirplanes);
while ((entity = iterator1.ReadAndNext()) != NULL)
{
sorter.AddUpdateToList(entity, UpdateManager::AirMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::AirMovementUpdateID, connection_rate));
MWObject *object = Cast_Object(MWObject*, entity);
if (object->GetTorso())
{
sorter.AddUpdateToList(object->GetTorso(), UpdateManager::TorsoMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::TorsoMovementUpdateID, connection_rate));
}
}
Stuff::ChainIteratorOf<Boat*> iterator2(&servedBoats);
while ((entity = iterator2.ReadAndNext()) != NULL)
{
sorter.AddUpdateToList(entity, UpdateManager::GroundMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::GroundMovementUpdateID, connection_rate));
MWObject *object = Cast_Object(MWObject*, entity);
if (object->GetTorso())
{
sorter.AddUpdateToList(object->GetTorso(), UpdateManager::TorsoMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::TorsoMovementUpdateID, connection_rate));
}
}
Stuff::ChainIteratorOf<Dropship*> iterator3(&servedDropships);
while ((entity = iterator3.ReadAndNext()) != NULL)
{
sorter.AddUpdateToList(entity, UpdateManager::AirMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::AirMovementUpdateID, connection_rate));
MWObject *object = Cast_Object(MWObject*, entity);
if (object->GetTorso())
{
sorter.AddUpdateToList(object->GetTorso(), UpdateManager::TorsoMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::TorsoMovementUpdateID, connection_rate));
}
}
Stuff::ChainIteratorOf<Helicopter*> iterator4(&servedHelicopters);
while ((entity = iterator4.ReadAndNext()) != NULL)
{
sorter.AddUpdateToList(entity, UpdateManager::AirMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::AirMovementUpdateID, connection_rate));
MWObject *object = Cast_Object(MWObject*, entity);
if (object->GetTorso())
{
sorter.AddUpdateToList(object->GetTorso(), UpdateManager::TorsoMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::TorsoMovementUpdateID, connection_rate));
}
}
Stuff::ChainIteratorOf<Hovercraft*> iterator5(&servedHovercraft);
while ((entity = iterator5.ReadAndNext()) != NULL)
{
sorter.AddUpdateToList(entity, UpdateManager::GroundMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::GroundMovementUpdateID, connection_rate));
MWObject *object = Cast_Object(MWObject*, entity);
if (object->GetTorso())
{
sorter.AddUpdateToList(object->GetTorso(), UpdateManager::TorsoMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::TorsoMovementUpdateID, connection_rate));
}
}
Stuff::ChainIteratorOf<Tank*> iterator7(&servedTanks);
while ((entity = iterator7.ReadAndNext()) != NULL)
{
sorter.AddUpdateToList(entity, UpdateManager::GroundMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::GroundMovementUpdateID, connection_rate));
MWObject *object = Cast_Object(MWObject*, entity);
if (object->GetTorso())
{
sorter.AddUpdateToList(object->GetTorso(), UpdateManager::TorsoMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::TorsoMovementUpdateID, connection_rate));
}
}
Stuff::ChainIteratorOf<Truck*> iterator8(&servedTrucks);
while ((entity = iterator8.ReadAndNext()) != NULL)
{
sorter.AddUpdateToList(entity, UpdateManager::GroundMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::GroundMovementUpdateID, connection_rate));
MWObject *object = Cast_Object(MWObject*, entity);
if (object->GetTorso())
{
sorter.AddUpdateToList(object->GetTorso(), UpdateManager::TorsoMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::TorsoMovementUpdateID, connection_rate));
}
}
Stuff::ChainIteratorOf<Turret*> iterator9(&servedTurrets);
while ((entity = iterator9.ReadAndNext()) != NULL)
{
sorter.AddUpdateToList(entity, UpdateManager::TurretMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::TurretMovementUpdateID, connection_rate));
MWObject *object = Cast_Object(MWObject*, entity);
if (object->GetTorso())
{
sorter.AddUpdateToList(object->GetTorso(), UpdateManager::TorsoMovementUpdateID, bitManager->GetUpdateRate(UpdateManager::TorsoMovementUpdateID, connection_rate));
}
}
sorter.MakeDictionaryPages(dictionary);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::QueCommand(int command)
{
#if defined(LAB_ONLY)
if (commandCount >= 4)
{
SPEWALWAYS(("jerryeds", "TOO MANY COMMANDS"));
}
#endif
if (Application::GetInstance()->networkingFlag && !Application::GetInstance()->serverFlag)
{
commandCount++;
VehicleCommand *new_command = new VehicleCommand();
new_command->m_Command = command;
quedCommands.Add(new_command);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::RespawnClient(int connection_id, Point3D trans)
{
if (serverController != NULL)
{
serverController->RespawnClient(connection_id, trans);
}
if (clientController != NULL)
{
clientController->RespawnClient(connection_id);
}
// ngLog addition // JKK
#if !defined(NO_LOG)
MW4log_generic(MW4P_RESPAWN, va("Player_Respawn\t%d", connection_id));
#endif // !defined(NO_LOG)
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::AddPlayerVehicle(Mover *mover)
{
if (mover->GetClassData() == Mech::DefaultData)
{
Verify(mover->GetClassData() == Mech::DefaultData);
Verify(mover->IsPlayerVehicle());
int mech_id = mover->GetReplicatorID().connectionID;
Verify(playerVehicle[mech_id] == NULL);
playerVehicle[mech_id] = Cast_Object(Vehicle*, mover);
// add score member for the player mech
Mission::GetInstance()->AddScoreMember (mover->GetReplicatorID(), mover->instanceName);
// reset security response
if (Application::GetInstance()->serverFlag && serverController != NULL)
{
serverController->ResetClient(mech_id);
}
#if defined(LAB_ONLY)
int connection = mover->GetReplicatorID().connectionID;
MWGameInfo::g_playerJoinTime[connection] = gos_GetElapsedTime();
++MWGameInfo::g_totalNetworkJoins;
++MWGameInfo::g_currentlyJoined;
++MWGameInfo::g_playerJoins[connection];
MWGameInfo::g_lastJoinID = connection;
const char *name;
name = mover->GetModelName ();
std::string s(name);
std::string::size_type last_period = s.find_last_of('.');
if (last_period != std::string::npos)
{
s.erase(last_period,s.size() - 1 - last_period);
}
std::string::size_type last_slash = s.find_last_of('\\');
if (last_slash != std::string::npos)
{
s.erase(0,last_slash + 1);
}
strncpy (MWGameInfo::g_playerVehicleNames[connection],s.c_str(),s.size() - 1);
MWGameInfo::g_playerVehicleNames[connection][s.size()] = 0;
if (mover->IsDerivedFrom(Vehicle::DefaultData) == true)
{
Vehicle* v = Cast_Object(Vehicle*,mover);
MWGameInfo::g_playerTeams[connection] = v->GetTeam();
}
#endif
#if !defined(NO_MR)
int conn = mover->GetReplicatorID().connectionID;
MWApplication *app = MWApplication::GetInstance();
if(app->m_recordLog) {
app->m_recordLog->AddPlayer(Network::GetInstance()->GetConnection(conn)->GetConnectionName(), conn);
}
#endif // !defined(NO_MR)
}
//else we are in brb or something
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::RemovePlayerVehicle(Mover *mover)
{
#if defined(LAB_ONLY)
int connection = mover->GetReplicatorID().connectionID;
MWGameInfo::g_playerLeaveTime[connection] = gos_GetElapsedTime();
++MWGameInfo::g_totalNetworkLeaves;
--MWGameInfo::g_currentlyJoined;
++MWGameInfo::g_playerLeaves[connection];
MWGameInfo::g_lastLeaveID = mover->GetReplicatorID().connectionID;
#endif
if (MWApplication::GetInstance()->serverFlag) {
if (mover->GetClassData() == Mech::DefaultData) {
Mech* mech = Cast_Pointer(Mech*, mover);
g_RSF.RemoveScoreObject(mech); // jcem
}
}
#if !defined(NO_MR)
if (MWApplication::GetInstance()->m_recordLog)
{
int connection = mover->GetReplicatorID().connectionID;
MWApplication::GetInstance()->m_recordLog->RemovePlayer(connection);
}
#endif // !defined(NO_MR)
int mech_id = mover->GetReplicatorID().connectionID;
playerVehicle[mech_id] = NULL;
if (MWApplication::GetInstance()->servedConnectionData[mech_id].clientPlayer != NULL)
{
MWApplication::GetInstance()->servedConnectionData[mech_id].clientPlayer->vehicle = NULL;
}
if(Mission::GetInstance())
{
Check_Object(this);
Mission::GetInstance()->RemoveScoreMember (mover->GetReplicatorID());
}
if (mover != 0)
{
Flag::RemoveAllFlagsFrom(*mover);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::AddMover(Mover *mover)
{
SetDirtyFlag();
if(mover->GetClassData() == Mech::DefaultData)
{
Mech *mech = Cast_Object(Mech*, mover);
servedMechs.AddValue(mech, mech->GetReplicatorID());
/*
if (mover->GetReplicatorMode() == Replicator::MasterMode)
{
servedMechs.AddValue(mech, mech->GetReplicatorID());
}
else if (mover->GetReplicatorMode() == Replicator::ServerMasterMode)
{
// turn this mech off
// mech->executionState->RequestState(Mech::ExecutionStateEngine::NeverExecuteState);
servedMechs.AddValue(mech, mech->GetReplicatorID());
}
*/
}
else
{
switch(mover->GetClassID())
{
case AirplaneClassID:
{
Airplane *obj = Cast_Object(Airplane*, mover);
servedAirplanes.Add(obj);
}
break;
case BoatClassID:
{
Boat *obj = Cast_Object(Boat*, mover);
servedBoats.Add(obj);
}
break;
case DropshipClassID:
{
Dropship *obj = Cast_Object(Dropship*, mover);
servedDropships.Add(obj);
}
break;
case HelicopterClassID:
{
Helicopter *obj = Cast_Object(Helicopter*, mover);
servedHelicopters.Add(obj);
}
break;
case HovercraftClassID:
{
Hovercraft *obj = Cast_Object(Hovercraft*, mover);
servedHovercraft.Add(obj);
}
break;
case TankClassID:
{
Tank *obj = Cast_Object(Tank*, mover);
servedTanks.Add(obj);
}
break;
case TruckClassID:
{
Truck *obj = Cast_Object(Truck*, mover);
servedTrucks.Add(obj);
}
break;
case TurretClassID:
{
Turret *obj = Cast_Object(Turret*, mover);
servedTurrets.Add(obj);
}
break;
}
}
EntityManager::AddMover(mover);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MWEntityManager::RemoveMover(Mover *mover)
{
SetDirtyFlag();
if(mover->GetClassData() == Mech::DefaultData)
{
//Mech *mech = Cast_Object(Mech*, mover);
Mech *mech = Cast_Pointer(Mech*, mover);
if (mech->IsPlayerVehicle())
{
RemovePlayerVehicle(mover);
}
servedMechs.Remove(mech);
/*
if (mover->GetReplicatorMode() == Replicator::MasterMode)
{
servedMechs.Remove(mech);
}
else if (mover->GetReplicatorMode() == Replicator::ServerMasterMode)
{
// remove all the server side control buffers for this player
if (Application::GetInstance()->serverFlag)
{
int mech_id = mech->GetReplicatorID().connectionID;
if (serverController != NULL)
{
serverController->RemovePlayer(mech_id);
}
}
servedMechs.Remove(mech);
}
*/
}
else
{
switch(mover->GetClassID())
{
case AirplaneClassID:
{
Airplane *obj = Cast_Pointer(Airplane*, mover);
Check_Object(obj);
servedAirplanes.Remove(obj);
}
break;
case BoatClassID:
{
Boat *obj = Cast_Pointer(Boat*, mover);
Check_Object(obj);
servedBoats.Remove(obj);
}
break;
case DropshipClassID:
{
Dropship *obj = Cast_Pointer(Dropship*, mover);
Check_Object(obj);
servedDropships.Remove(obj);
}
break;
case HelicopterClassID:
{
Helicopter *obj = Cast_Pointer(Helicopter*, mover);
Check_Object(obj);
servedHelicopters.Remove(obj);
}
break;
case HovercraftClassID:
{
Hovercraft *obj = Cast_Pointer(Hovercraft*, mover);
Check_Object(obj);
servedHovercraft.Remove(obj);
}
break;
case TankClassID:
{
Tank *obj = Cast_Pointer(Tank*, mover);
Check_Object(obj);
servedTanks.Remove(obj);
}
break;
case TruckClassID:
{
Truck *obj = Cast_Pointer(Truck*, mover);
Check_Object(obj);
servedTrucks.Remove(obj);
}
break;
case TurretClassID:
{
Turret *obj = Cast_Pointer(Turret*, mover);
Check_Object(obj);
servedTurrets.Remove(obj);
}
break;
}
}
EntityManager::RemoveMover(mover);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Scalar MWEntityManager::FindGroundHeight(Stuff::Scalar x_position, Stuff::Scalar z_position)
{
// one would think I can just get the
Point3D test_point;
test_point.x = x_position;
test_point.y = 500.0f;
test_point.z = z_position;
Stuff::Vector3D world_avg_normal(Stuff::Vector3D::Identity);
Stuff::Normal3D normal;
Stuff::Line3D line;
Adept::Entity::CollisionQuery query(&line, &normal, Adept::Entity::CanBeWalkedOnFlag, NULL);
//
// Cast ray
//
Adept::Entity *entity_hit;
Check_Object(CollisionGrid::Instance);
line.m_length = 1000.0f;
line.m_direction = Vector3D::Down;
line.m_origin = test_point;
entity_hit = CollisionGrid::Instance->ProjectLine(&query);
if(entity_hit != NULL)
{
// if we hit ground, great!
Point3D end_point;
line.FindEnd(&end_point);
return end_point.y;
}
return 0.0f;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::AIWeaponUpdate(WeaponUpdate *weapon)
{
if (Application::GetInstance()->networkingFlag)
{
Check_Object(weapon);
Check_Object(weapon->originator.GetCurrent());
#if defined (_ARMOR)
if (weapon->target.GetCurrent() != NULL)
{
Check_Object(weapon->target.GetCurrent());
}
#endif
weaponUpdates.Add(weapon);
}
else
delete weapon;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::PlayerWeaponUpdate(WeaponUpdate *weapon)
{
if (Application::GetInstance()->networkingFlag && weapon->weaponFired)
{
Check_Object(weapon);
Check_Object(weapon->originator.GetCurrent());
#if defined (_ARMOR)
if (weapon->target.GetCurrent() != NULL)
{
Check_Object(weapon->target.GetCurrent());
}
#endif
WeaponUpdate *copy = new WeaponUpdate;
if (weapon->originator.GetCurrent())
copy->originator.Add(weapon->originator.GetCurrent());
if (weapon->target.GetCurrent())
copy->target.Add(weapon->target.GetCurrent());
copy->weaponFired = weapon->weaponFired;
copy->targetOffset = weapon->targetOffset;
copy->lockTime = weapon->lockTime;
for (int i = 0; i < 32; ++i)
{
copy->AntiWeaponCount[i] = weapon->AntiWeaponCount[i];
}
weaponUpdates.Add(copy);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::QueWeapon(WeaponUpdate *weapon)
{
Verify (Application::GetInstance()->networkingFlag);
Verify(!weapon->obsolete);
networkWeaponsQue.Add(weapon);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::BuildTileBoundDamageList()
{
EntityManager::BuildTileBoundDamageList();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWEntityManager::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
void MWEntityManager::QueRespawnLancemate(Mech* lancemateMech)
{
Check_Object(lancemateMech);
// jcem - for delayed lancemate respawn
MWMission* mission = Cast_Object(MWMission*, MWMission::GetInstance());
Check_Object(mission);
VehicleInterface* pVH = VehicleInterface::GetInstance();
Check_Object(pVH);
lancemateMech->m_fTimeRespawnRequestEnd = mission->GetMissionTime() + pVH->GetGameModel()->deathTimer;
servedRespawnLances.Add(lancemateMech);
}