Files
CydandClaude Opus 4.8 4abbf8879f 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>
2026-06-30 07:59:51 -05:00

272 lines
6.2 KiB
C++

#include "rp.h"
#pragma hdrstop
#include "blocker.h"
#include "..\munga\dropzone.h"
#include "vtv.h"
#include "..\munga\hostmgr.h"
#include "..\munga\app.h"
#include "scorzone.h"
#include "..\munga\nttmgr.h"
//#############################################################################
//############################### Blocker ##############################
//#############################################################################
//#############################################################################
// Shared Data Support
//
Derivation* Blocker::GetClassDerivations()
{ static Derivation classDerivations(Crusher::GetClassDerivations(), "Blocker");
return &classDerivations;
}
Blocker::SharedData
Blocker::DefaultData(
Blocker::GetClassDerivations(),
Blocker::MessageHandlers,
Blocker::GetAttributeIndex(),
Blocker::StateCount,
(Blocker::MakeHandler)Blocker::Make
);
const Receiver::HandlerEntry
Blocker::MessageHandlerEntries[]=
{
MESSAGE_ENTRY(Blocker, Score),
MESSAGE_ENTRY(Blocker, DropZoneReply)
};
Receiver::MessageHandlerSet
Blocker::MessageHandlers(
ELEMENTS(Blocker::MessageHandlerEntries),
Blocker::MessageHandlerEntries,
Crusher::GetMessageHandlers()
);
//#############################################################################
// Message Support
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void Blocker::DropZoneReplyMessageHandler(
DropZone::ReplyMessage *message
)
{
Check(this);
Check(message);
if (!playerVehicle)
{
CreatePlayerVehicle(message->dropZoneLocation);
InitializePlayerLink();
SetPerformance(&Blocker::PlayerSimulation);
AlwaysExecute();
deathCount = 0;
}
else if (deathCount == message->deathCount)
{
if (GetSimulationState() == MissionEndingState)
{
Check_Fpu();
return;
}
if (GetSimulationState() != DropZoneAcquiredState)
{
ResetAfterDeath(message);
return;
}
}
else
{
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
Blocker::AddOffensivePlayer(OffensivePlayer &offensive_player)
{
Check(this);
Check(offensive_player.offensivePlayer);
RPPlayer *rp_player = offensive_player.offensivePlayer;
//
//---------------------------------------------
// Death Points awarded if ....
// This Blocker gets hit by a runner
// from the other team with collision Damage!
//---------------------------------------------
//
if ( (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
Blocker::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 == CrusherPlayerType) || (rp_player->playerType == RunnerPlayerType)) &&
(rp_player->teamID != teamID)
)
{
ScoreMessage score_message(
Blocker::ScoreMessageID,
sizeof(Blocker::ScoreMessage),
CrusherScorePointType,
message->scoreAward*1.5f,
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);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Blocker::PlayerSimulation(Scalar time_slice)
{
Check(this);
//
//------------------------------------------------------------------------
// Service the status message queue
//------------------------------------------------------------------------
//
StatusMessageUpdate(time_slice);
//
//------------------------------------------------
// Only one team runner only have to do this once
//-------------------------------------------------
//
Player::PlayerSimulation(time_slice);
if (!teamRunner)
{
InitTeamRunner();
}
if (teamRunner)
{
Entity *our_vehicle = GetPlayerVehicle();
Check(our_vehicle);
if (!goalEntity)
{
goalEntity = teamRunner->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();
}
}
}
Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Blocker::Blocker(
MakeMessage *creation_message,
SharedData &shared_data
)
: Crusher(creation_message, shared_data)
{
StatusMessage
*message = new StatusMessage(NULL,RPStatusMessage::BlockerMessage,1e10);
Register_Object(message);
AddStatusMessage(message);
}
Blocker::~Blocker()
{
Check(this);
Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Blocker*
Blocker::Make(MakeMessage *creation_message)
{
Check_Fpu();
return new Blocker(creation_message);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Logical
Blocker::TestInstance() const
{
return IsDerivedFrom(*GetClassDerivations());
}