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

282 lines
7.1 KiB
C++

#include "rp.h"
#pragma hdrstop
#include "runner.h"
#include "..\munga\dropzone.h"
#include "vtv.h"
#include "..\munga\hostmgr.h"
#include "..\munga\app.h"
#include "scorzone.h"
#include "..\munga\nttmgr.h"
//#############################################################################
//############################### Runner ##############################
//#############################################################################
//#############################################################################
// Shared Data Support
//
Derivation* Runner::GetClassDerivations()
{ static Derivation classDerivations(RPPlayer::GetClassDerivations(), "Runner");
return &classDerivations;
}
Runner::SharedData
Runner::DefaultData(
Runner::GetClassDerivations(),
Runner::MessageHandlers,
Runner::GetAttributeIndex(),
Runner::StateCount,
(Runner::MakeHandler)Runner::Make
);
const Receiver::HandlerEntry
Runner::MessageHandlerEntries[]=
{
MESSAGE_ENTRY(Runner, VehicleDead),
MESSAGE_ENTRY(Runner, Score),
MESSAGE_ENTRY(Runner, DropZoneReply),
MESSAGE_ENTRY(Runner, ScoreZoneReply)
};
Receiver::MessageHandlerSet
Runner::MessageHandlers(
ELEMENTS(Runner::MessageHandlerEntries),
Runner::MessageHandlerEntries,
RPPlayer::GetMessageHandlers()
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Runner::Runner(
MakeMessage *creation_message,
SharedData &shared_data
)
: RPPlayer(creation_message, shared_data)
{
StatusMessage
*message = new StatusMessage(NULL,RPStatusMessage::RunnerMessage,1e10);
Register_Object(message);
AddStatusMessage(message);
dropZonePenaltyOver.ticks = 0;
scoreMultiplier = 1.0f;
//----------------------------------------
// Add to runner group
//----------------------------------------
EntityManager
*entity_manager = application->GetEntityManager();
Check(entity_manager);
EntityGroup
*runner_group = entity_manager->UseGroup("RunnerPlayers");
Check(runner_group);
runner_group->Add(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Runner*
Runner::Make(MakeMessage *creation_message)
{
return new Runner(creation_message);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Runner::AddOffensivePlayer(OffensivePlayer &offensive_player)
{
Check(offensive_player.offensivePlayer);
RPPlayer *rp_player = offensive_player.offensivePlayer;
//
//---------------------------------------------
// Death Points awarded if ....
// This Runner gets hit by a crusher, blocker or runner
// from the other team with collision Damage!
//---------------------------------------------
//
if (
rp_player->playerType == CrusherPlayerType
&& teamID != rp_player->teamID
&& offensive_player.damageType == Damage::CollisionDamageType)
{
VTV *vtv = (VTV*)playerVehicle;
Check(vtv);
if (vtv->boosterOn)
{
dropZonePenaltyOver.ticks = 0;
}
offensive_player.deathBonus = (Now() <= dropZonePenaltyOver) ? -5000.0f : 500.0f;
}
else
if (
rp_player->playerType == BlockerPlayerType
&& teamID != rp_player->teamID
&& offensive_player.damageType == Damage::CollisionDamageType)
{
VTV *vtv = (VTV*)playerVehicle;
Check(vtv);
if (vtv->boosterOn)
{
dropZonePenaltyOver.ticks = 0;
}
offensive_player.deathBonus = (Now() <= dropZonePenaltyOver) ? -6666.0f : 0.0f;
}
else
if (
rp_player->playerType == RunnerPlayerType
&& teamID != rp_player->teamID
&& offensive_player.damageType == Damage::CollisionDamageType)
{
VTV *vtv = (VTV*)playerVehicle;
Check(vtv);
if (vtv->boosterOn)
{
dropZonePenaltyOver.ticks = 0;
}
offensive_player.deathBonus = (Now() <= dropZonePenaltyOver) ? -10000.0f : 0.0f;
}
else
{
offensive_player.deathBonus = 0.0f;
}
offensivePlayerList.AddValue(&offensive_player,offensive_player.damageType);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Runner::ScoreMessageHandler(ScoreMessage *message)
{
RPPlayer::ScoreMessageHandler(message);
switch (message->scoreType)
{
case ScoreZonePointType:
case SpeedBonusPointType:
currentScore += message->scoreAward * scoreMultiplier;
break;
case DamageScoreLossPointType:
{
if (Now() >= dropZonePenaltyOver)
{
goto Standard_Score;
}
VTV *vtv = (VTV*)playerVehicle;
Check(vtv);
if (vtv->boosterOn)
{
dropZonePenaltyOver.ticks = 0;
goto Standard_Score;
}
}
break;
default:
Standard_Score:
currentScore += message->scoreAward;
break;
}
//
// 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
Runner::ScoreZoneReplyMessageHandler(
ScoreZone::ReplyMessage *message
)
{
RPPlayer::ScoreZoneReplyMessageHandler(message);
//
//---------------------------------------------------------
// double the scoreMultiplier
//---------------------------------------------------------
//
Check(playerVehicle);
VTV *vtv = (VTV*)playerVehicle;
if (vtv->GetSimulationState() != VTV::BurningState)
{
scoreMultiplier *= 2.0f;
if (scoreMultiplier > 16.0f)
scoreMultiplier = 16.0f;
if (scoreMultiplier == 2.0f)
{
RPStatusMessage *message = new RPStatusMessage(NULL, RPStatusMessage::Score2xMessage, 6.0f);
Register_Object(message);
AddStatusMessage((StatusMessage *) message);
}
if (scoreMultiplier == 4.0f)
{
RPStatusMessage *message = new RPStatusMessage(NULL, RPStatusMessage::Score4xMessage, 6.0f);
Register_Object(message);
AddStatusMessage((StatusMessage *) message);
}
if (scoreMultiplier == 8.0f)
{
RPStatusMessage *message = new RPStatusMessage(NULL, RPStatusMessage::Score8xMessage, 6.0f);
Register_Object(message);
AddStatusMessage((StatusMessage *) message);
}
if (scoreMultiplier == 16.0f)
{
RPStatusMessage *message = new RPStatusMessage(NULL, RPStatusMessage::Score16xMessage, 6.0f);
Register_Object(message);
AddStatusMessage((StatusMessage *) message);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Runner::VehicleDeadMessageHandler(VehicleDeadMessage *message)
{
Check(this);
Check(message);
scoreMultiplier = 1.0f;
RPPlayer::VehicleDeadMessageHandler(message);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Runner::DropZoneReplyMessageHandler(
DropZone__ReplyMessage *message
)
{
Check(this);
Check(message);
if (
playerVehicle
&& deathCount == message->deathCount
&& GetSimulationState() != DropZoneAcquiredState
)
{
dropZonePenaltyOver = Now();
dropZonePenaltyOver += 5.0f;
}
RPPlayer::DropZoneReplyMessageHandler(message);
Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Logical
Runner::TestInstance() const
{
return IsDerivedFrom(*GetClassDerivations());
}