Files
firestorm/Gameleap/code/mw4/Libraries/Adept/Player.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

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));
}