A Live Cam station is selected entirely by egg data - hostType=1 on that host's entry plus vehicle=camera - so no code path announces itself and a station that fails to come up leaves a log that simply stops. RP412CAMLOG=1 traces the sequence: the stand-alone host and its type, the local player node and game model, the interest-arena and interest-manager loads, the registry choosing a director, the director making its camera ship, and the launch handshake it waits on. Off by default. What it found immediately: a camera host wedges inside InterestManager::LoadMission - the map-entity load - and never returns. Everything upstream is correct (the egg parses, hostType 1 is adopted, gameModel reads 'camera'), and the same call with a racing egg passes straight through to making the player and launching. Same map both times, so it is the local host's TYPE that the map load cannot digest, not the map. That is a defect to fix before a lobby has anything to switch on. Also recorded while chasing it: a racing -egg run sits in application state 11 with the low-priority queue never empty for its whole life, and still simulates - so CheckLoad's no-console self-launch is not what starts a stand-alone race. Worth knowing before trusting that path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
313 lines
7.9 KiB
C++
313 lines
7.9 KiB
C++
#include "rpl4.h"
|
|
#pragma hdrstop
|
|
|
|
#include "rpl4mssn.h"
|
|
#include "..\munga_l4\l4grend.h"
|
|
#include "..\munga_l4\l4app.h"
|
|
#include "..\munga\notation.h"
|
|
#include "..\munga_l4\l4host.h"
|
|
#include "..\munga\hostmgr.h"
|
|
#include "..\munga\namelist.h"
|
|
|
|
//##########################################################################
|
|
//########################### RPL4Mission ############################
|
|
//##########################################################################
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
RPL4Mission::RPL4Mission(
|
|
NotationFile *notation_file,
|
|
ResourceFile *resources
|
|
):
|
|
RPMission(notation_file, resources)
|
|
{
|
|
Check_Fpu();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
RPL4Mission::~RPL4Mission()
|
|
{
|
|
Check(this);
|
|
Check_Fpu();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
RPL4Mission::SetPlayerData(NotationFile *notation_file)
|
|
{
|
|
Check(this);
|
|
//
|
|
//--------------------------------------------------------------
|
|
// Figure out which page we should be using to create the player
|
|
//--------------------------------------------------------------
|
|
//
|
|
Check(application);
|
|
HostManager *host_manager = application->GetHostManager();
|
|
Check(host_manager);
|
|
L4Host *host = (L4Host*)host_manager->GetLocalHost();
|
|
Check(host);
|
|
CString
|
|
player_node = host->GetSymbolicName();
|
|
|
|
//
|
|
//----------------------------------------------------------
|
|
// Copy the game model and dropzone strings into the mission
|
|
//----------------------------------------------------------
|
|
//
|
|
gameModel = NULL;
|
|
const char* player_model = NULL;
|
|
notation_file->GetEntry(player_node, "vehicle", &player_model);
|
|
if (!player_model)
|
|
{
|
|
DEBUG_STREAM << "Error: vehicle not specified!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
Check_Pointer(player_model);
|
|
gameModel = strdup(player_model);
|
|
Register_Pointer(gameModel);
|
|
|
|
if (RPCameraLog())
|
|
{
|
|
DEBUG_STREAM << "CamLog: local player node '" << (const char *) player_node
|
|
<< "' gameModel '" << gameModel << "'\n" << std::flush;
|
|
}
|
|
|
|
dropZoneName = NULL;
|
|
const char* drop_zone = NULL;
|
|
notation_file->GetEntry(player_node, "dropzone", &drop_zone);
|
|
if (!drop_zone)
|
|
{
|
|
DEBUG_STREAM << "Error: dropzone not specified!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
Check_Pointer(drop_zone);
|
|
dropZoneName = strdup(drop_zone);
|
|
Register_Pointer(dropZoneName);
|
|
|
|
dropZoneHost = False;
|
|
notation_file->GetEntry(player_node, "loadzones", &dropZoneHost);
|
|
|
|
colorName = NULL;
|
|
const char* color_name = NULL;
|
|
notation_file->GetEntry(player_node, "color", &color_name);
|
|
if (!color_name)
|
|
{
|
|
DEBUG_STREAM << "Error: color not specified!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
Check_Pointer(color_name);
|
|
colorName = strdup(color_name);
|
|
Register_Pointer(colorName);
|
|
|
|
badgeName = NULL;
|
|
const char* badge_name = NULL;
|
|
notation_file->GetEntry(player_node, "badge", &badge_name);
|
|
if (!badge_name)
|
|
{
|
|
DEBUG_STREAM << "Error: badge not specified!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
Check_Pointer(badge_name);
|
|
badgeName = strdup(badge_name);
|
|
Register_Pointer(badgeName);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~
|
|
// Get playerBitmapIndex
|
|
//~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
if (!notation_file->GetEntry(
|
|
player_node,
|
|
"bitmapindex",
|
|
&playerBitmapIndex
|
|
)
|
|
)
|
|
{
|
|
DEBUG_STREAM<<"No bitmapindex in egg"<<std::endl << std::flush;
|
|
}
|
|
else
|
|
{
|
|
//--------------------------------------------------------
|
|
// Show the bitmap on the plasma display (if it exists)
|
|
//--------------------------------------------------------
|
|
//
|
|
BitMap *bitmap = GetLargeNameBitmap(playerBitmapIndex);
|
|
if (bitmap)
|
|
{
|
|
Check(application);
|
|
L4GaugeRenderer
|
|
*gauge_renderer=((L4Application*)application)->
|
|
GetGaugeRenderer();
|
|
if (gauge_renderer != NULL)
|
|
{
|
|
Check(gauge_renderer);
|
|
GraphicsDisplay *graphics_display =
|
|
gauge_renderer->GetExternalDisplay();
|
|
|
|
if (graphics_display != NULL)
|
|
{
|
|
graphics_display->DrawBitMapOpaque(
|
|
1, // foreground color
|
|
0, // background color
|
|
0xFF, // bitmask
|
|
GraphicsDisplay::Replace, // operation
|
|
0, // rotation
|
|
0,0, // position
|
|
bitmap,
|
|
0, // sx1
|
|
0, // sy1
|
|
bitmap->Data.Size.x-1, // sx2
|
|
bitmap->Data.Size.y-1 // sy2
|
|
);
|
|
graphics_display->Update(True);
|
|
graphics_display->WaitForUpdate();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
//----------------------------------------------------------
|
|
// scoreCompression
|
|
//----------------------------------------------------------
|
|
//
|
|
scoreCompression = False;
|
|
const char* score_compression = NULL;
|
|
notation_file->GetEntry("mission", "compression", &score_compression);
|
|
if (!score_compression)
|
|
{
|
|
scoreCompression = False;
|
|
}
|
|
else if (strcmp("1", score_compression) == 0)
|
|
{
|
|
scoreCompression = True;
|
|
}
|
|
else
|
|
{
|
|
scoreCompression = False;
|
|
}
|
|
|
|
//
|
|
//-----------------------------------------------
|
|
// Get the position name "General" if not listed
|
|
//-----------------------------------------------
|
|
//
|
|
positionName = NULL;
|
|
const char* position_name = NULL;
|
|
notation_file->GetEntry(player_node, "position", &position_name);
|
|
if(!position_name)
|
|
{
|
|
position_name = strdup("General");
|
|
}
|
|
Check_Pointer(position_name);
|
|
positionName = strdup(position_name);
|
|
Register_Pointer(positionName);
|
|
//
|
|
//---------------------------------------
|
|
// Assign an integer value for the teamID
|
|
//---------------------------------------
|
|
//
|
|
const char* team_name;
|
|
notation_file->GetEntry(player_node, "team", &team_name);
|
|
int team_count;
|
|
|
|
NameList
|
|
*team_namelist = notation_file->MakeEntryList("teams");
|
|
|
|
teamID = -1;
|
|
if (team_namelist)
|
|
{
|
|
Register_Object(team_namelist);
|
|
team_count = team_namelist->EntryCount();
|
|
if(team_count)
|
|
{
|
|
int current_id=0;
|
|
NameList::Entry *team_entry = team_namelist->GetFirstEntry();
|
|
while(team_entry)
|
|
{
|
|
if (strcmp(team_name, team_entry->GetChar()) == 0)
|
|
{
|
|
teamID = current_id;
|
|
break;
|
|
}
|
|
current_id++;
|
|
team_entry = team_entry->GetNextEntry();
|
|
}
|
|
}
|
|
Unregister_Object(team_namelist);
|
|
delete team_namelist;
|
|
}
|
|
Check_Fpu();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
Logical
|
|
RPL4Mission::TestInstance() const
|
|
{
|
|
RPMission::TestInstance();
|
|
return True;
|
|
}
|
|
|
|
#if 0
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
RPL4Mission::CreatePlayerMessage(
|
|
NotationFile *notation_file,
|
|
StreamableResourceFile *resources
|
|
)
|
|
{
|
|
Check(this);
|
|
Check(notation_file);
|
|
Check(resources);
|
|
|
|
Check(application);
|
|
HostManager *host_manager = application->GetHostManager();
|
|
Check(host_manager);
|
|
L4Host *host = (L4Host*)host_manager->GetLocalHost();
|
|
Check(host);
|
|
CString player_node = host->GetSymbolicName();
|
|
|
|
const char* player_model = NULL;
|
|
notation_file->GetEntry(player_node, "gamemodel", &player_model);
|
|
Check_Pointer(player_model);
|
|
|
|
ResourceDescription *vtv =
|
|
resources->FindResourceDescription(
|
|
player_model,
|
|
ResourceDescription::ModelListResourceType
|
|
);
|
|
Check(vtv);
|
|
|
|
VTV::MakeMessage *create_player =
|
|
new VTV::MakeMessage(
|
|
VTV::MakeMessageID,
|
|
sizeof(VTV::MakeMessage),
|
|
EntityID(host_manager->GetLocalHostID()),
|
|
VTV::VTVClassID,
|
|
EntityID::Null,
|
|
vtv->resourceID,
|
|
VTV::DefaultFlags|VTV::InitialStasisFlag,
|
|
Origin(Point3D(0.0f, 10.0f, 0.0f), Quaternion::Identity),
|
|
Motion::Identity,
|
|
Motion::Identity
|
|
);
|
|
Register_Object(create_player);
|
|
|
|
AdoptCreatePlayerMessage(create_player);
|
|
Check_Fpu();
|
|
}
|
|
#endif
|