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.
503 lines
13 KiB
C++
503 lines
13 KiB
C++
//===========================================================================//
|
|
// File: Player.cpp //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 03/08/99 DPB Created file //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1998, Fasa Interactive //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include "AdeptHeaders.hpp"
|
|
|
|
#include "Player.hpp"
|
|
#include "Interface.hpp"
|
|
#include "Application.hpp"
|
|
#include "Map.hpp"
|
|
#include "EntityManager.hpp"
|
|
#include "Mission.hpp"
|
|
#include "DropZone.hpp"
|
|
|
|
//#############################################################################
|
|
//############################### Player ##############################
|
|
//#############################################################################
|
|
|
|
Player::ClassData*
|
|
Player::DefaultData = NULL;
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Player::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
PlayerClassID,
|
|
"Adept::Player",
|
|
BaseClass::DefaultData,
|
|
0, NULL,
|
|
(Entity::Factory)Make,
|
|
(Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage,
|
|
ExecutionStateEngine::DefaultData,
|
|
(Entity::GameModel::Factory)GameModel::ConstructGameModel,
|
|
NULL,
|
|
(Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify,
|
|
(Entity::GameModel::ModelWrite)GameModel::WriteToText,
|
|
(Entity::GameModel::ModelSave)GameModel::SaveGameModel
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Player::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
GlobalPointers::ClearPointer(PlayerGlobalPointerIndex);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Player*
|
|
Player::Make(
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
)
|
|
{
|
|
gos_PushCurrentHeap(g_LibraryHeap);
|
|
Player *new_entity = new Player(DefaultData, message, base_id, NULL);
|
|
Check_Object(new_entity);
|
|
gos_PopCurrentHeap();
|
|
return new_entity;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Replicator::CreateMessage*
|
|
Player::SaveMakeMessage(MemoryStream *stream, ResourceFile *res_file)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(stream);
|
|
|
|
stream->AllocateBytes(sizeof(CreateMessage));
|
|
BaseClass::SaveMakeMessage(stream, res_file);
|
|
CreateMessage *message =
|
|
Cast_Pointer(CreateMessage*, stream->GetPointer());
|
|
message->messageLength = sizeof(*message);
|
|
|
|
Verify(message->initialAge != 0.0f);
|
|
//
|
|
//------------------------------------------
|
|
// Create the memory stream for the vehicle
|
|
//------------------------------------------
|
|
//
|
|
Resource vehicle_resource(NULL);
|
|
DynamicMemoryStream vehicle_stream;
|
|
Check_Object(vehicle);
|
|
vehicle->SaveMakeMessage(&vehicle_stream, NULL);
|
|
vehicle_resource.Save(&vehicle_stream, NULL);
|
|
STOP(("Not updated"));
|
|
Check_Object(&vehicle_resource);
|
|
message->vehicleResourceID = vehicle_resource.GetResourceID();
|
|
//
|
|
//-------------------------------------------
|
|
// Create the memory stream for the interface
|
|
//-------------------------------------------
|
|
//
|
|
Resource interface_resource(NULL);
|
|
DynamicMemoryStream interface_stream;
|
|
Check_Object(playerInterface);
|
|
playerInterface->SaveMakeMessage(&interface_stream, NULL);
|
|
interface_resource.Save(&interface_stream, NULL);
|
|
Check_Object(&interface_resource);
|
|
message->interfaceResourceID = interface_resource.GetResourceID();
|
|
return message;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Player::Player(
|
|
ClassData *class_data,
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id,
|
|
ElementRenderer::Element *element
|
|
):
|
|
Driver(class_data, message, base_id, element)
|
|
{
|
|
// Check_Pointer(this);
|
|
// Check_Object(message);
|
|
|
|
|
|
#if 0 // moved to mwplayer
|
|
isDropped = false;
|
|
|
|
|
|
Mission::GetInstance()->AddChild(this);
|
|
|
|
//
|
|
//----------------------
|
|
// Create the interface
|
|
//----------------------
|
|
//
|
|
playerInterface = NULL;
|
|
interfaceResourceID = ResourceID::Null;
|
|
if (GetReplicatorMode() == Replicator::ClientMasterMode || GetReplicatorMode() == Replicator::MasterMode)
|
|
{
|
|
Resource stream(message->interfaceResourceID);
|
|
Verify(stream.DoesResourceExist());
|
|
ReplicatorID id = owningConnection->GetNextReplicatorID();
|
|
ReplicatorID interface_id = Connection::Hermit->GetNextReplicatorID();
|
|
playerInterface = Cast_Object(Interface *, CreateEntity(&stream, &interface_id));
|
|
Check_Object(playerInterface);
|
|
interfaceResourceID = message->interfaceResourceID;
|
|
}
|
|
|
|
//
|
|
//-------------------
|
|
// Create the vehicle
|
|
//-------------------
|
|
//
|
|
Resource stream(message->vehicleResourceID);
|
|
Verify(stream.DoesResourceExist());
|
|
|
|
vehicle = CreateEntity(&stream, base_id);
|
|
Check_Object(vehicle);
|
|
|
|
|
|
|
|
vehicle->SetPropType(PlayerPropType);
|
|
Check_Object(Map::GetInstance());
|
|
Map::GetInstance()->AddChild(vehicle);
|
|
|
|
|
|
EntityManager::GetInstance()->RemoveMover((Mover*)vehicle);
|
|
|
|
ReplicatorID mech_id = vehicle->GetReplicatorID();
|
|
vehicle->instanceName =
|
|
Network::GetInstance()->GetConnection(mech_id.connectionID)->GetConnectionName();
|
|
|
|
if(!vehicle->instanceName || !vehicle->instanceName.GetLength())
|
|
{
|
|
char buffer[10];
|
|
sprintf(buffer, "%d::", owningConnection->GetID());
|
|
MString new_name;
|
|
new_name = buffer + vehicle->instanceName;
|
|
vehicle->instanceName = new_name;
|
|
}
|
|
|
|
Check_Object(NameTable::GetInstance());
|
|
vehicle->objectID = NameTable::GetInstance()->FindID(vehicle->instanceName);
|
|
|
|
if(vehicle->objectID == NameTable::NullObjectID)
|
|
NameTable::GetInstance()->AddEntry(vehicle, NameTable::VehicleArray);
|
|
else
|
|
NameTable::GetInstance()->SetData(vehicle);
|
|
if (owningConnection != Connection::Local)
|
|
{
|
|
vehicle->SetAlignment(Entity::Enemy);
|
|
}
|
|
|
|
Check_Object(EntityManager::GetInstance());
|
|
EntityManager::GetInstance()->AddMover((Mover*)vehicle);
|
|
|
|
|
|
// connect to the drop zone
|
|
|
|
if (message->initialAge != 0.0f)
|
|
{
|
|
|
|
ElementRenderer::Element *element = vehicle->GetElement();
|
|
Check_Object(element);
|
|
ReceiveDropZone(element->GetNewLocalToParent());
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
dropZone = NameTable::GetInstance()->FindID("PlayerStart");
|
|
|
|
Stuff::LinearMatrix4D drop_location = Stuff::LinearMatrix4D::Identity;
|
|
drop_location.BuildTranslation(Point3D::HellPoint);
|
|
|
|
vehicle->SetNewLocalToParent(drop_location);
|
|
vehicle->SyncMatrices(true);
|
|
Map::GetInstance()->UpdateZone(vehicle);
|
|
}
|
|
|
|
|
|
//
|
|
//----------------------------
|
|
//Store the Vehicle ResourceID
|
|
//----------------------------
|
|
//
|
|
vehicleResourceID = message->vehicleResourceID;
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Player::~Player()
|
|
{
|
|
if (this == Player::GetInstance())
|
|
GlobalPointers::ClearPointer(PlayerGlobalPointerIndex);
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void
|
|
Player::Respawn(CreateMessage *message)
|
|
{
|
|
#if 0
|
|
Check_Pointer(this);
|
|
Check_Object(message);
|
|
|
|
isDropped = false;
|
|
|
|
|
|
//
|
|
//----------------------
|
|
// Respawn the interface
|
|
//----------------------
|
|
//
|
|
|
|
Entity::CreateMessage *interface_respawn_message = NULL;
|
|
|
|
|
|
interfaceResourceID = ResourceID::Null;
|
|
if (GetReplicatorMode() == Replicator::ClientMasterMode || GetReplicatorMode() == Replicator::MasterMode)
|
|
{
|
|
Resource stream(message->interfaceResourceID);
|
|
Verify(stream.DoesResourceExist());
|
|
ReplicatorID id = owningConnection->GetNextReplicatorID();
|
|
ReplicatorID interface_id = Connection::Hermit->GetNextReplicatorID();
|
|
|
|
interface_respawn_message =
|
|
Cast_Pointer(Entity::CreateMessage*, stream.GetPointer());
|
|
|
|
//playerInterface->Respawn(new_message);
|
|
//Check_Object(playerInterface);
|
|
|
|
}
|
|
|
|
//
|
|
//-------------------
|
|
// Create the vehicle
|
|
//-------------------
|
|
//
|
|
Resource stream(message->vehicleResourceID);
|
|
Verify(stream.DoesResourceExist());
|
|
|
|
Entity::CreateMessage *new_message =
|
|
Cast_Pointer(Entity::CreateMessage*, stream.GetPointer());
|
|
vehicle->Respawn(new_message);
|
|
Check_Object(vehicle);
|
|
|
|
// we do this after the vehicle for a respawn since farther down
|
|
// the stream there is no reconnect
|
|
if (interface_respawn_message != NULL)
|
|
{
|
|
playerInterface->Respawn(new_message);
|
|
Check_Object(playerInterface);
|
|
}
|
|
|
|
|
|
// connect to the drop zone
|
|
if (message->initialAge != 0.0f)
|
|
{
|
|
ElementRenderer::Element *element = vehicle->GetElement();
|
|
Check_Object(element);
|
|
ReceiveDropZone(element->GetNewLocalToParent());
|
|
|
|
}
|
|
else
|
|
{
|
|
dropZone = NameTable::GetInstance()->FindID("PlayerStart");
|
|
|
|
Stuff::LinearMatrix4D drop_location = Stuff::LinearMatrix4D::Identity;
|
|
drop_location.BuildTranslation(Point3D::HellPoint);
|
|
|
|
vehicle->SetNewLocalToParent(drop_location);
|
|
vehicle->SyncMatrices(true);
|
|
Map::GetInstance()->UpdateZone(vehicle);
|
|
}
|
|
if (owningConnection != Connection::Local)
|
|
{
|
|
vehicle->SetAlignment(Entity::Enemy);
|
|
}
|
|
|
|
|
|
//
|
|
//----------------------------
|
|
//Store the Vehicle ResourceID
|
|
//----------------------------
|
|
//
|
|
vehicleResourceID = message->vehicleResourceID;
|
|
#endif
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Player::BecomeInteresting(bool render_me)
|
|
{
|
|
Check_Object(this);
|
|
LOAD_LOGIC("Become Interesting::Player");
|
|
BaseClass::BecomeInteresting(render_me);
|
|
|
|
//
|
|
//------------------
|
|
// Validate children
|
|
//------------------
|
|
//
|
|
ChainIteratorOf<Entity*> children(&childEntityChain);
|
|
Entity *entity;
|
|
while ((entity = children.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(entity);
|
|
Verify(entity->GetInterestLevel() == DormantInterestLevel);
|
|
entity->BecomeInteresting(render_me);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Player::AddChild(Entity *entity)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(entity);
|
|
Verify(entity == playerInterface);
|
|
BaseClass::AddChild(entity);
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Player::ChildPreCollisionChanged(Entity *entity)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(entity);
|
|
Verify(entity == playerInterface);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Player::PreCollisionExecute(Time till)
|
|
{
|
|
Check_Object(this);
|
|
PRECOLLISION_LOGIC("Player");
|
|
|
|
Check_Object(this);
|
|
oldLocalToWorld = vehicle->GetLocalToWorld();
|
|
//
|
|
//---------------------------------
|
|
// Verify that this always executes
|
|
//---------------------------------
|
|
//
|
|
Check_Object(executionState);
|
|
Verify(
|
|
executionState->GetState() !=
|
|
ExecutionStateEngine::NeverExecuteState
|
|
);
|
|
BaseClass::PreCollisionExecute(till);
|
|
|
|
//
|
|
//-----------------
|
|
// Execute children
|
|
//-----------------
|
|
//
|
|
ChainIteratorOf<Entity*> children(&childEntityChain);
|
|
Entity *entity;
|
|
while ((entity = children.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity != playerInterface)
|
|
{
|
|
Check_Object(entity);
|
|
Verify(entity->GetInterestLevel() != DormantInterestLevel);
|
|
entity->PreCollisionExecute(till);
|
|
Verify(!entity->IsUsingPostCollision() || EntityManager::GetInstance()->IsInPostCollisionExecution(entity));
|
|
}
|
|
else
|
|
{
|
|
// make this guy have the last execute
|
|
Check_Object(EntityManager::GetInstance());
|
|
EntityManager::GetInstance()->RequestPostCollisionExecution(entity);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
Stuff::LinearMatrix4D
|
|
Player::GetEyePoint()
|
|
{
|
|
if (playerInterface != NULL)
|
|
return playerInterface->GetLocalToWorld();
|
|
else
|
|
return BaseClass::GetEyePoint();
|
|
}
|
|
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Player::ReceiveDropZone(const Stuff::LinearMatrix4D& drop_location)
|
|
{
|
|
Check_Object(this);
|
|
|
|
SetNewLocalToParent(drop_location);
|
|
|
|
EntityManager::GetInstance()->SetPlayerReady(vehicle);
|
|
vehicle->SetNewLocalToParent(drop_location);
|
|
vehicle->SyncMatrices(true);
|
|
Map::GetInstance()->UpdateZone(vehicle);
|
|
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void
|
|
Player::ConnectToVehicle(void)
|
|
{
|
|
isDropped = true;
|
|
Check_Object(playerInterface);
|
|
|
|
SyncMatrices(true);
|
|
AddChild(playerInterface);
|
|
|
|
if (Application::GetInstance()->m_localMissionParameters->m_runDedicated)
|
|
playerInterface->BecomeInteresting(false);
|
|
else
|
|
playerInterface->BecomeInteresting(true);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Player::TestInstance()
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|