Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet', built on the MUNGA engine and its L4 (Win32/DirectX) platform layer: - MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend - RP / RP_L4: Red Planet game logic and Win32 application - DivLoader, Setup1: asset loader and installer project - lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies Removed stale Subversion metadata and added .gitignore/.gitattributes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+433
@@ -0,0 +1,433 @@
|
||||
#include "rp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "crusher.h"
|
||||
#include "..\munga\dropzone.h"
|
||||
#include "vtv.h"
|
||||
#include "..\munga\hostmgr.h"
|
||||
#include "..\munga\app.h"
|
||||
#include "scorzone.h"
|
||||
#include "..\munga\nttmgr.h"
|
||||
|
||||
//#############################################################################
|
||||
//############################### Crusher ##############################
|
||||
//#############################################################################
|
||||
|
||||
//#############################################################################
|
||||
// Shared Data Support
|
||||
//
|
||||
Derivation* Crusher::GetClassDerivations()
|
||||
{ static Derivation classDerivations(RPPlayer::GetClassDerivations(), "Crusher");
|
||||
return &classDerivations;
|
||||
}
|
||||
|
||||
|
||||
Crusher::SharedData
|
||||
Crusher::DefaultData(
|
||||
Crusher::GetClassDerivations(),
|
||||
Crusher::GetMessageHandlers(),
|
||||
Crusher::GetAttributeIndex(),
|
||||
Crusher::StateCount,
|
||||
(Crusher::MakeHandler)Crusher::Make
|
||||
);
|
||||
|
||||
const Receiver::HandlerEntry
|
||||
Crusher::MessageHandlerEntries[]=
|
||||
{
|
||||
MESSAGE_ENTRY(Crusher, Score),
|
||||
MESSAGE_ENTRY(Crusher, DropZoneReply),
|
||||
MESSAGE_ENTRY(Crusher, ScoreZoneReply)
|
||||
};
|
||||
|
||||
Receiver::MessageHandlerSet& Crusher::GetMessageHandlers()
|
||||
{
|
||||
static Receiver::MessageHandlerSet messageHandlers(ELEMENTS(Crusher::MessageHandlerEntries), Crusher::MessageHandlerEntries, RPPlayer::GetMessageHandlers());
|
||||
return messageHandlers;
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
// Message Support
|
||||
//
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void Crusher::DropZoneReplyMessageHandler(
|
||||
DropZone::ReplyMessage *message
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check(message);
|
||||
|
||||
if (!playerVehicle)
|
||||
{
|
||||
CreatePlayerVehicle(message->dropZoneLocation);
|
||||
InitializePlayerLink();
|
||||
SetPerformance(&Crusher::PlayerSimulation);
|
||||
AlwaysExecute();
|
||||
deathCount = 0;
|
||||
}
|
||||
else if (deathCount == message->deathCount)
|
||||
{
|
||||
if (GetSimulationState() == MissionEndingState)
|
||||
{
|
||||
Check_Fpu();
|
||||
return;
|
||||
}
|
||||
if (GetSimulationState() != DropZoneAcquiredState)
|
||||
{
|
||||
ResetAfterDeath(message);
|
||||
Check_Fpu();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_Fpu();
|
||||
return;
|
||||
}
|
||||
DeleteAllOffensivePlayers();
|
||||
ForceUpdate();
|
||||
SetSimulationState(VehicleTranslocatedState);
|
||||
VTV *vtv = (VTV*)playerVehicle;
|
||||
Check(vtv);
|
||||
vtv->Reset(message->dropZoneLocation, True);
|
||||
if (goalEntity)
|
||||
{
|
||||
Check(goalEntity);
|
||||
PointVTVTowardGoal();
|
||||
vtv->ForceUpdate();
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
Crusher::AddOffensivePlayer(OffensivePlayer &offensive_player)
|
||||
{
|
||||
Check(this);
|
||||
Check(offensive_player.offensivePlayer);
|
||||
RPPlayer *rp_player = offensive_player.offensivePlayer;
|
||||
//
|
||||
//---------------------------------------------
|
||||
// Damage & Death Points awarded if ....
|
||||
// This Crusher gets hit by a runner or a Blocker
|
||||
// from the other team with collision Damage!
|
||||
//---------------------------------------------
|
||||
//
|
||||
if (
|
||||
(
|
||||
rp_player->playerType == BlockerPlayerType
|
||||
|| rp_player->playerType == RunnerPlayerType
|
||||
)
|
||||
&& teamID != rp_player->teamID
|
||||
&& offensive_player.damageType == Damage::CollisionDamageType
|
||||
)
|
||||
{
|
||||
offensive_player.deathBonus = 500.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
offensive_player.deathBonus = 0.0f;
|
||||
}
|
||||
offensivePlayerList.AddValue(
|
||||
&offensive_player,
|
||||
offensive_player.damageType
|
||||
);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
Crusher::ScoreMessageHandler(ScoreMessage *message)
|
||||
{
|
||||
Check(this);
|
||||
Check(message);
|
||||
Check(application);
|
||||
|
||||
RPPlayer::ScoreMessageHandler(message);
|
||||
HostManager *host = application->GetHostManager();
|
||||
Check(host);
|
||||
RPPlayer *rp_player = (RPPlayer*)
|
||||
host->GetEntityPointer(message->pointSender);
|
||||
if (!rp_player)
|
||||
{
|
||||
Check_Fpu();
|
||||
return;
|
||||
}
|
||||
|
||||
Check(rp_player);
|
||||
if (
|
||||
rp_player->playerType == RunnerPlayerType
|
||||
&& rp_player->teamID != teamID
|
||||
)
|
||||
{
|
||||
Scalar score_award = message->scoreAward * 2.0f;
|
||||
//
|
||||
//------------------------------------------------------
|
||||
// Create the score award and pass it on to the runner
|
||||
//------------------------------------------------------
|
||||
//
|
||||
ScoreMessage score_message(
|
||||
RPPlayer::ScoreMessageID,
|
||||
sizeof(RPPlayer::ScoreMessage),
|
||||
CrusherScorePointType,
|
||||
score_award,
|
||||
GetEntityID()
|
||||
);
|
||||
if (teamRunner)
|
||||
{
|
||||
Check(teamRunner);
|
||||
teamRunner->Dispatch(&score_message);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// HACK - ECH 7/6/95 - Allow the player vehicle to respond to score
|
||||
// messages, allows attribute system to be used for scoring
|
||||
//
|
||||
Check(playerVehicle);
|
||||
playerVehicle->RespondToScoreMessage(message);
|
||||
Check_Fpu();
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
Crusher::ScoreZoneReplyMessageHandler(
|
||||
ScoreZone::ReplyMessage *//message
|
||||
)
|
||||
{
|
||||
//empty
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
Crusher::PlayerSimulation(Scalar time_slice)
|
||||
{
|
||||
Check(this);
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
// Service the status message queue
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
StatusMessageUpdate(time_slice);
|
||||
|
||||
//
|
||||
//-----------------------------------
|
||||
// Find the runners if we haven't yet
|
||||
//-----------------------------------
|
||||
//
|
||||
Player::PlayerSimulation(time_slice);
|
||||
InitTeamRunner();
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// If we know who the enemy is, but not what his vehicle is, try to find the
|
||||
// vehicle
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
if (enemyRunner)
|
||||
{
|
||||
Entity *our_vehicle = GetPlayerVehicle();
|
||||
Check(our_vehicle);
|
||||
if (!goalEntity)
|
||||
{
|
||||
goalEntity = enemyRunner->GetPlayerVehicle();
|
||||
if (goalEntity)
|
||||
{
|
||||
PointVTVTowardGoal();
|
||||
our_vehicle->ForceUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------
|
||||
// Otherwise, if we aren't running yet, make sure that we are pointed in
|
||||
// the correct direction - HACK
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
else if (
|
||||
application->GetApplicationState() < Application::RunningMission
|
||||
)
|
||||
{
|
||||
Scalar alignment = our_vehicle->localToWorld(2,2);
|
||||
PointVTVTowardGoal();
|
||||
if (alignment * goalEntity->localToWorld(2,2) < 0.0f)
|
||||
{
|
||||
our_vehicle->ForceUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------
|
||||
// If the game is running, set the goal properly
|
||||
//----------------------------------------------
|
||||
//
|
||||
else
|
||||
{
|
||||
goalEntity = enemyRunner->GetPlayerVehicle();
|
||||
}
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
Crusher::PointVTVTowardGoal()
|
||||
{
|
||||
Check(this);
|
||||
Vector3D to_goal(Vector3D::Identity);
|
||||
|
||||
if (goalEntity)
|
||||
{
|
||||
//
|
||||
//------------------------------
|
||||
// Find the distance to the goal
|
||||
//------------------------------
|
||||
//
|
||||
|
||||
to_goal.Subtract(
|
||||
goalEntity->localOrigin.linearPosition,
|
||||
playerVehicle->localOrigin.linearPosition
|
||||
);
|
||||
|
||||
Scalar length_to_goal;
|
||||
length_to_goal = to_goal.LengthSquared();
|
||||
|
||||
//
|
||||
//----------------------------
|
||||
// Less than 100 meters away?
|
||||
//----------------------------
|
||||
//
|
||||
if (length_to_goal < 10000.0f)
|
||||
{
|
||||
//
|
||||
//-----------------------------------------------
|
||||
// The goalEntity is in front of us so point in
|
||||
// the same direction as the goalEntity
|
||||
//-----------------------------------------------
|
||||
//
|
||||
playerVehicle->localOrigin.angularPosition.x = 0.0f;
|
||||
playerVehicle->localOrigin.angularPosition.z = 0.0f;
|
||||
if (goalEntity->localToWorld(2,2) >= 0.0f)
|
||||
{
|
||||
playerVehicle->localOrigin.angularPosition.y = 0.0f;
|
||||
playerVehicle->localOrigin.angularPosition.w = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
playerVehicle->localOrigin.angularPosition.y = 1.0f;
|
||||
playerVehicle->localOrigin.angularPosition.w = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
//---------------------------------
|
||||
// Point toward the goal Entity
|
||||
// disregard and Y direction
|
||||
//---------------------------------
|
||||
//
|
||||
playerVehicle->localOrigin.angularPosition.x = 0.0f;
|
||||
playerVehicle->localOrigin.angularPosition.z = 0.0f;
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// is the goal in front or behind me
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
if (to_goal.z <= 0.0f)
|
||||
{
|
||||
playerVehicle->localOrigin.angularPosition.y = 0.0f;
|
||||
playerVehicle->localOrigin.angularPosition.w = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
playerVehicle->localOrigin.angularPosition.y = 1.0f;
|
||||
playerVehicle->localOrigin.angularPosition.w = 0.0f;
|
||||
}
|
||||
}
|
||||
playerVehicle->localToWorld = playerVehicle->localOrigin;
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Crusher::Crusher(
|
||||
MakeMessage *creation_message,
|
||||
SharedData &shared_data
|
||||
)
|
||||
: RPPlayer(creation_message, shared_data)
|
||||
{
|
||||
StatusMessage
|
||||
*message = new StatusMessage(NULL,RPStatusMessage::CrusherMessage,1e10);
|
||||
Register_Object(message);
|
||||
AddStatusMessage(message);
|
||||
|
||||
teamRunner = NULL;
|
||||
enemyRunner = NULL;
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
Crusher::~Crusher()
|
||||
{
|
||||
Check(this);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Crusher*
|
||||
Crusher::Make(MakeMessage *creation_message)
|
||||
{
|
||||
Check_Fpu();
|
||||
return new Crusher(creation_message);
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
Crusher::InitTeamRunner()
|
||||
{
|
||||
Check(this);
|
||||
|
||||
Check(application);
|
||||
EntityManager *entity_mgr = application->GetEntityManager();
|
||||
Check(entity_mgr);
|
||||
EntityGroup *runner_group = entity_mgr->FindGroup("RunnerPlayers");
|
||||
if(runner_group)
|
||||
{
|
||||
Check(runner_group);
|
||||
ChainIteratorOf<Node*> iterator(runner_group->groupMembers);
|
||||
RPPlayer *runner;
|
||||
int winning_rank = 10000;
|
||||
while ((runner = (RPPlayer*) iterator.ReadAndNext()) != NULL)
|
||||
{
|
||||
Check(runner);
|
||||
if (runner->teamID == teamID)
|
||||
{
|
||||
teamRunner = runner;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (runner->playerRanking < winning_rank)
|
||||
{
|
||||
enemyRunner = runner;
|
||||
winning_rank = runner->playerRanking;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Logical
|
||||
Crusher::TestInstance() const
|
||||
{
|
||||
return IsDerivedFrom(*GetClassDerivations());
|
||||
}
|
||||
Reference in New Issue
Block a user