Martian Football: the second scenario is playable
The setup menu gains a SCENARIO group. Picking Football relayouts the menu live: the track list swaps to the football-legal set (drops Paingod Passage and the race build of Freezemoon Freeway, adds the football build headmf - RPConfig per-scenario invalid lists), the COLOR and BADGE columns become TEAM and POSITION, and the title reads MARTIAN FOOTBALL. The egg builder was restructured around one flat pilot table so both scenarios share it. Football emits scenario=football, per-pilot team= and position= entries, and the [teams] / [team::X] / [pilots::X] / [teambitmap] blocks in RPFootballMission layout (team name bitmaps generated by the same GDI plasma renderer as pilot names). Colors are derived rather than chosen, as the arcade did it: the runner wears the team runner color, crushers and blockers the team color. Multi-pod games alternate pilots across two teams and give each team exactly one runner, honoring the host own position pick. Verified end to end: Football launches from the menu, the engine loads the football mission (the cockpit shows the RUNNER - GO FOR POINTS panel), the console marshals it to a scored finish, and the Death Race path still passes its regression unchanged. Known gap: lobby members cannot pick their own team or position yet - the host pick seeds a deterministic assignment. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+305
-69
@@ -35,6 +35,52 @@ namespace
|
||||
{ "headoff", "Freezemoon's Freeway" },
|
||||
};
|
||||
|
||||
// Football excludes pain/headoff and adds the football build of
|
||||
// Freezemoon's Freeway (RPConfig.xml per-scenario invalid lists).
|
||||
const CatalogEntry kFootballMaps[] =
|
||||
{
|
||||
{ "wise", "Wiseguy's Wake" },
|
||||
{ "lyzlane", "Lyz's Lane" },
|
||||
{ "yip", "Yip's Yahoorama" },
|
||||
{ "blade", "Blade's Edge" },
|
||||
{ "otto", "Berserker's Bahnzai" },
|
||||
{ "frstrm", "Firestorm's Fury" },
|
||||
{ "burnt", "Burnt Cookies" },
|
||||
{ "brewers", "Brewer's Bane" },
|
||||
{ "headmf", "Freezemoon's Freeway" },
|
||||
};
|
||||
|
||||
const CatalogEntry kScenarios[] =
|
||||
{
|
||||
{ "race", "Death Race" },
|
||||
{ "football", "Football" },
|
||||
};
|
||||
|
||||
// Two-color teams: crushers/blockers wear the team color, the
|
||||
// runner wears the runner color (that is how you spot the ball).
|
||||
struct TeamEntry
|
||||
{
|
||||
const char *key;
|
||||
const char *name;
|
||||
const char *teamColor;
|
||||
const char *runnerColor;
|
||||
};
|
||||
|
||||
const TeamEntry kTeams[] =
|
||||
{
|
||||
{ "Red/Pink", "Red / Pink", "Red", "Pink" },
|
||||
{ "Blue/Aqua", "Blue / Aqua", "Blue", "Aqua" },
|
||||
{ "Green/Yellow", "Green / Yellow", "Green", "Yellow" },
|
||||
{ "Black/Purple", "Black / Purple", "Black", "Purple" },
|
||||
};
|
||||
|
||||
const CatalogEntry kPositions[] =
|
||||
{
|
||||
{ "runner", "Runner" },
|
||||
{ "crusher", "Crusher" },
|
||||
{ "blocker", "Blocker" },
|
||||
};
|
||||
|
||||
const CatalogEntry kVehicles[] =
|
||||
{
|
||||
{ "quark", "Quark" },
|
||||
@@ -125,12 +171,31 @@ namespace
|
||||
GroupTime,
|
||||
GroupWeather,
|
||||
GroupLength,
|
||||
GroupScenario,
|
||||
GroupTeam, // football only
|
||||
GroupPosition, // football only
|
||||
GroupLaunch,
|
||||
GroupSteamHost, // buttons, not selections (Steam builds only)
|
||||
GroupSteamJoin,
|
||||
GroupCount
|
||||
};
|
||||
|
||||
Logical IsFootball(const int *selection)
|
||||
{
|
||||
return selection[GroupScenario] == 1;
|
||||
}
|
||||
|
||||
const CatalogEntry *ActiveMaps(const int *selection, int *count)
|
||||
{
|
||||
if (IsFootball(selection))
|
||||
{
|
||||
*count = (int)(sizeof(kFootballMaps) / sizeof(kFootballMaps[0]));
|
||||
return kFootballMaps;
|
||||
}
|
||||
*count = (int)(sizeof(kMaps) / sizeof(kMaps[0]));
|
||||
return kMaps;
|
||||
}
|
||||
|
||||
struct FEItem
|
||||
{
|
||||
int group;
|
||||
@@ -311,8 +376,10 @@ namespace
|
||||
int top = client_h / 7;
|
||||
|
||||
int y = top;
|
||||
AddGroupItems(fe, GroupMap, FE_COUNT(kMaps), col1, &y, row_h, col_w);
|
||||
int y_after_maps = y;
|
||||
AddGroupItems(fe, GroupScenario, FE_COUNT(kScenarios), col1, &y, row_h, col_w);
|
||||
int map_count;
|
||||
ActiveMaps(fe->selection, &map_count);
|
||||
AddGroupItems(fe, GroupMap, map_count, col1, &y, row_h, col_w);
|
||||
AddGroupItems(fe, GroupTime, FE_COUNT(kTimes), col1, &y, row_h, col_w);
|
||||
AddGroupItems(fe, GroupWeather, FE_COUNT(kWeather), col1, &y, row_h, col_w);
|
||||
AddGroupItems(fe, GroupLength, FE_COUNT(kLengths), col1, &y, row_h, col_w);
|
||||
@@ -321,8 +388,16 @@ namespace
|
||||
AddGroupItems(fe, GroupVehicle, FE_COUNT(kVehicles), col2, &y, row_h, col_w);
|
||||
|
||||
y = top + 2 * row_h; // leave room for the name edit + header
|
||||
AddGroupItems(fe, GroupColor, FE_COUNT(kColors), col3, &y, row_h, col_w);
|
||||
AddGroupItems(fe, GroupBadge, FE_COUNT(kBadges), col3, &y, row_h, col_w);
|
||||
if (IsFootball(fe->selection))
|
||||
{
|
||||
AddGroupItems(fe, GroupTeam, FE_COUNT(kTeams), col3, &y, row_h, col_w);
|
||||
AddGroupItems(fe, GroupPosition, FE_COUNT(kPositions), col3, &y, row_h, col_w);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddGroupItems(fe, GroupColor, FE_COUNT(kColors), col3, &y, row_h, col_w);
|
||||
AddGroupItems(fe, GroupBadge, FE_COUNT(kBadges), col3, &y, row_h, col_w);
|
||||
}
|
||||
|
||||
// launch button
|
||||
FEItem *launch = &fe->items[fe->itemCount++];
|
||||
@@ -365,31 +440,45 @@ namespace
|
||||
{
|
||||
switch (group)
|
||||
{
|
||||
case GroupScenario: return "SCENARIO";
|
||||
case GroupMap: return "TRACK";
|
||||
case GroupVehicle: return "VEHICLE";
|
||||
case GroupColor: return "COLOR";
|
||||
case GroupBadge: return "BADGE";
|
||||
case GroupTeam: return "TEAM";
|
||||
case GroupPosition: return "POSITION";
|
||||
case GroupTime: return "TIME OF DAY";
|
||||
case GroupWeather: return "WEATHER";
|
||||
case GroupLength: return "RACE LENGTH";
|
||||
case GroupLength: return "GAME LENGTH";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// the map rows need the active scenario's list
|
||||
const int *gItemNameSelection = NULL;
|
||||
|
||||
const char *ItemName(int group, int index)
|
||||
{
|
||||
switch (group)
|
||||
{
|
||||
case GroupMap: return kMaps[index].name;
|
||||
case GroupScenario: return kScenarios[index].name;
|
||||
case GroupMap:
|
||||
if (gItemNameSelection != NULL && IsFootball(gItemNameSelection))
|
||||
{
|
||||
return kFootballMaps[index].name;
|
||||
}
|
||||
return kMaps[index].name;
|
||||
case GroupVehicle: return kVehicles[index].name;
|
||||
case GroupColor: return kColors[index].name;
|
||||
case GroupBadge: return kBadges[index].name;
|
||||
case GroupTeam: return kTeams[index].name;
|
||||
case GroupPosition: return kPositions[index].name;
|
||||
case GroupTime: return kTimes[index].name;
|
||||
case GroupWeather: return kWeather[index].name;
|
||||
case GroupLength: return kLengths[index].name;
|
||||
case GroupLaunch: return "L A U N C H R A C E";
|
||||
case GroupSteamHost: return "HOST STEAM RACE";
|
||||
case GroupSteamJoin: return "JOIN STEAM RACE";
|
||||
case GroupLaunch: return "L A U N C H G A M E";
|
||||
case GroupSteamHost: return "HOST STEAM GAME";
|
||||
case GroupSteamJoin: return "JOIN STEAM GAME";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -413,13 +502,17 @@ namespace
|
||||
SetBkMode(mem, TRANSPARENT);
|
||||
|
||||
// title
|
||||
gItemNameSelection = fe->selection;
|
||||
SelectObject(mem, fe->titleFont);
|
||||
SetTextColor(mem, kGreenBright);
|
||||
RECT title = client;
|
||||
title.top = client.bottom / 28;
|
||||
title.bottom = title.top + client.bottom / 10;
|
||||
DrawTextA(mem, "RED PLANET - MARTIAN DEATH RACE", -1, &title,
|
||||
DT_CENTER | DT_TOP | DT_SINGLELINE);
|
||||
DrawTextA(mem,
|
||||
IsFootball(fe->selection)
|
||||
? "RED PLANET - MARTIAN FOOTBALL"
|
||||
: "RED PLANET - MARTIAN DEATH RACE",
|
||||
-1, &title, DT_CENTER | DT_TOP | DT_SINGLELINE);
|
||||
|
||||
SelectObject(mem, fe->textFont);
|
||||
|
||||
@@ -521,6 +614,20 @@ namespace
|
||||
else
|
||||
{
|
||||
fe->selection[item->group] = item->index;
|
||||
if (item->group == GroupScenario)
|
||||
{
|
||||
// the scenario swaps the map list and the
|
||||
// color/badge vs team/position columns
|
||||
int map_count;
|
||||
ActiveMaps(fe->selection, &map_count);
|
||||
if (fe->selection[GroupMap] >= map_count)
|
||||
{
|
||||
fe->selection[GroupMap] = 0;
|
||||
}
|
||||
RECT client;
|
||||
GetClientRect(fe->menuWindow, &client);
|
||||
LayoutMenu(fe, client.right, client.bottom);
|
||||
}
|
||||
InvalidateRect(fe->menuWindow, NULL, FALSE);
|
||||
}
|
||||
return;
|
||||
@@ -655,13 +762,19 @@ namespace
|
||||
extern const char *kOrdinalsBlock;
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Egg assembly (console RPMission.ToEggString, race scenario).
|
||||
// Single player uses the standalone address; a hosted network
|
||||
// race lists the owner first plus one pilot per member pod.
|
||||
// Egg assembly (console RPMission.ToEggString / RPFootballMission).
|
||||
// Single player uses the standalone address; a hosted network game
|
||||
// lists the owner first plus one pilot per member pod. Football
|
||||
// adds team=/position= per pilot and the [teams] blocks; the
|
||||
// owner's team/position picks seed a deterministic assignment
|
||||
// across two teams (each team's first member without a runner
|
||||
// becomes one; the rest alternate crusher/blocker; the runner
|
||||
// wears the team's runner color, everyone else the team color).
|
||||
//---------------------------------------------------------------
|
||||
void BuildEggText(const FEState *fe, std::string &egg)
|
||||
{
|
||||
char line[256];
|
||||
Logical football = IsFootball(fe->selection);
|
||||
|
||||
ExtraPilot extras[maxExtraPilots];
|
||||
char owner_address[64];
|
||||
@@ -672,11 +785,100 @@ namespace
|
||||
extra_count = 0; // single player
|
||||
}
|
||||
|
||||
//
|
||||
// One flat pilot table: the owner then the extras
|
||||
//
|
||||
struct PilotEntry
|
||||
{
|
||||
const char *address;
|
||||
const char *name;
|
||||
const char *vehicle;
|
||||
const char *color;
|
||||
const char *badge;
|
||||
int team; // kTeams index, -1 outside football
|
||||
const char *position;
|
||||
};
|
||||
PilotEntry pilots[maxExtraPilots + 1];
|
||||
int pilot_count = 0;
|
||||
|
||||
PilotEntry *owner = &pilots[pilot_count++];
|
||||
owner->address = owner_address;
|
||||
owner->name = fe->pilotName;
|
||||
owner->vehicle = kVehicles[fe->selection[GroupVehicle]].key;
|
||||
owner->color = kColors[fe->selection[GroupColor]].key;
|
||||
owner->badge = kBadges[fe->selection[GroupBadge]].key;
|
||||
owner->team = -1;
|
||||
owner->position = NULL;
|
||||
for (int p = 0; p < extra_count; ++p)
|
||||
{
|
||||
PilotEntry *pilot = &pilots[pilot_count++];
|
||||
pilot->address = extras[p].address;
|
||||
pilot->name = extras[p].name;
|
||||
pilot->vehicle = extras[p].vehicle;
|
||||
pilot->color = extras[p].color;
|
||||
pilot->badge = extras[p].badge;
|
||||
pilot->team = -1;
|
||||
pilot->position = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Football: assign teams and positions, derive colors
|
||||
//
|
||||
int teams_used[2] = { 0, 1 };
|
||||
if (football)
|
||||
{
|
||||
teams_used[0] = fe->selection[GroupTeam];
|
||||
teams_used[1] = (teams_used[0] + 1) % FE_COUNT(kTeams);
|
||||
|
||||
int runner_on_team[2] = { 0, 0 };
|
||||
int line_position[2] = { 0, 0 }; // crusher/blocker rotation
|
||||
|
||||
owner->team = 0;
|
||||
owner->position = kPositions[fe->selection[GroupPosition]].key;
|
||||
if (strcmp(owner->position, "runner") == 0)
|
||||
{
|
||||
runner_on_team[0] = 1;
|
||||
}
|
||||
|
||||
for (int p = 1; p < pilot_count; ++p)
|
||||
{
|
||||
int side = p % 2; // alternate: B, A, B, A...
|
||||
side = (side == 1) ? 1 : 0;
|
||||
pilots[p].team = side;
|
||||
if (!runner_on_team[side])
|
||||
{
|
||||
pilots[p].position = "runner";
|
||||
runner_on_team[side] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pilots[p].position =
|
||||
(line_position[side]++ % 2) ? "blocker" : "crusher";
|
||||
}
|
||||
}
|
||||
|
||||
for (int p = 0; p < pilot_count; ++p)
|
||||
{
|
||||
const TeamEntry *team = &kTeams[teams_used[pilots[p].team]];
|
||||
pilots[p].color =
|
||||
(strcmp(pilots[p].position, "runner") == 0)
|
||||
? team->runnerColor : team->teamColor;
|
||||
pilots[p].badge = "None";
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// [mission]
|
||||
//
|
||||
int map_count;
|
||||
const CatalogEntry *maps = ActiveMaps(fe->selection, &map_count);
|
||||
|
||||
egg += "[mission]\n";
|
||||
egg += "adventure=Red Planet\n";
|
||||
sprintf(line, "map=%s\n", kMaps[fe->selection[GroupMap]].key);
|
||||
sprintf(line, "map=%s\n", maps[fe->selection[GroupMap]].key);
|
||||
egg += line;
|
||||
sprintf(line, "scenario=%s\n", kScenarios[fe->selection[GroupScenario]].key);
|
||||
egg += line;
|
||||
egg += "scenario=race\n";
|
||||
sprintf(line, "time=%s\n", kTimes[fe->selection[GroupTime]].key);
|
||||
egg += line;
|
||||
sprintf(line, "weather=%s\n", kWeather[fe->selection[GroupWeather]].key);
|
||||
@@ -690,84 +892,118 @@ namespace
|
||||
egg += line;
|
||||
}
|
||||
|
||||
//
|
||||
// [pilots] + per-pilot sections
|
||||
//
|
||||
egg += "[pilots]\n";
|
||||
sprintf(line, "pilot=%s\n", owner_address);
|
||||
egg += line;
|
||||
for (int p = 0; p < extra_count; ++p)
|
||||
for (int p = 0; p < pilot_count; ++p)
|
||||
{
|
||||
sprintf(line, "pilot=%s\n", extras[p].address);
|
||||
sprintf(line, "pilot=%s\n", pilots[p].address);
|
||||
egg += line;
|
||||
}
|
||||
|
||||
sprintf(line, "[%s]\n", owner_address);
|
||||
egg += line;
|
||||
egg += "hostType=0\n";
|
||||
egg += "dropzone=one\n";
|
||||
sprintf(line, "name=%s\n", fe->pilotName);
|
||||
egg += line;
|
||||
egg += "bitmapindex=1\n";
|
||||
egg += "loadzones=1\n";
|
||||
sprintf(line, "vehicle=%s\n", kVehicles[fe->selection[GroupVehicle]].key);
|
||||
egg += line;
|
||||
sprintf(line, "color=%s\n", kColors[fe->selection[GroupColor]].key);
|
||||
egg += line;
|
||||
sprintf(line, "badge=%s\n", kBadges[fe->selection[GroupBadge]].key);
|
||||
egg += line;
|
||||
|
||||
for (int p = 0; p < extra_count; ++p)
|
||||
for (int p = 0; p < pilot_count; ++p)
|
||||
{
|
||||
sprintf(line, "[%s]\n", extras[p].address);
|
||||
sprintf(line, "[%s]\n", pilots[p].address);
|
||||
egg += line;
|
||||
egg += "hostType=0\n";
|
||||
egg += "dropzone=one\n";
|
||||
sprintf(line, "name=%s\n", extras[p].name);
|
||||
sprintf(line, "name=%s\n", pilots[p].name);
|
||||
egg += line;
|
||||
sprintf(line, "bitmapindex=%d\n", p + 2);
|
||||
sprintf(line, "bitmapindex=%d\n", p + 1);
|
||||
egg += line;
|
||||
egg += "loadzones=1\n";
|
||||
sprintf(line, "vehicle=%s\n", extras[p].vehicle);
|
||||
sprintf(line, "vehicle=%s\n", pilots[p].vehicle);
|
||||
egg += line;
|
||||
sprintf(line, "color=%s\n", extras[p].color);
|
||||
sprintf(line, "color=%s\n", pilots[p].color);
|
||||
egg += line;
|
||||
sprintf(line, "badge=%s\n", extras[p].badge);
|
||||
sprintf(line, "badge=%s\n", pilots[p].badge);
|
||||
egg += line;
|
||||
if (football)
|
||||
{
|
||||
sprintf(line, "team=team::%s\n", kTeams[teams_used[pilots[p].team]].key);
|
||||
egg += line;
|
||||
sprintf(line, "position=%s\n", pilots[p].position);
|
||||
egg += line;
|
||||
}
|
||||
}
|
||||
|
||||
egg += "[largebitmap]\n";
|
||||
sprintf(line, "bitmap=BitMap::Large::%s\n", fe->pilotName);
|
||||
egg += line;
|
||||
for (int p = 0; p < extra_count; ++p)
|
||||
//
|
||||
// Football team blocks (console RPFootballMission layout)
|
||||
//
|
||||
if (football)
|
||||
{
|
||||
sprintf(line, "bitmap=BitMap::Large::%s\n", extras[p].name);
|
||||
Logical team_present[2] = { False, False };
|
||||
for (int p = 0; p < pilot_count; ++p)
|
||||
{
|
||||
team_present[pilots[p].team] = True;
|
||||
}
|
||||
|
||||
std::string teams_list = "[teams]\n";
|
||||
std::string team_sections, pilots_sections;
|
||||
std::string teambitmap_list = "[teambitmap]\n";
|
||||
std::string teambitmap_sections;
|
||||
int bitmap_index = 1;
|
||||
for (int side = 0; side < 2; ++side)
|
||||
{
|
||||
if (!team_present[side])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const char *team_key = kTeams[teams_used[side]].key;
|
||||
sprintf(line, "team=team::%s\n", team_key);
|
||||
teams_list += line;
|
||||
sprintf(line, "[team::%s]\nbitmapindex=%d\npilots=pilots::%s\n",
|
||||
team_key, bitmap_index++, team_key);
|
||||
team_sections += line;
|
||||
sprintf(line, "[pilots::%s]\n", team_key);
|
||||
pilots_sections += line;
|
||||
for (int p = 0; p < pilot_count; ++p)
|
||||
{
|
||||
if (pilots[p].team == side)
|
||||
{
|
||||
sprintf(line, "pilot=%s\n", pilots[p].address);
|
||||
pilots_sections += line;
|
||||
}
|
||||
}
|
||||
sprintf(line, "bitmap=BitMap::Small::team::%s\n", team_key);
|
||||
teambitmap_list += line;
|
||||
sprintf(line, "[BitMap::Small::team::%s]\n", team_key);
|
||||
teambitmap_sections += line;
|
||||
AppendNameBitmap(teambitmap_sections, 64, 16, team_key);
|
||||
teambitmap_sections += "width=4\n";
|
||||
}
|
||||
egg += teams_list;
|
||||
egg += team_sections;
|
||||
egg += pilots_sections;
|
||||
egg += teambitmap_list;
|
||||
egg += teambitmap_sections;
|
||||
}
|
||||
|
||||
//
|
||||
// Name bitmaps + ordinals
|
||||
//
|
||||
egg += "[largebitmap]\n";
|
||||
for (int p = 0; p < pilot_count; ++p)
|
||||
{
|
||||
sprintf(line, "bitmap=BitMap::Large::%s\n", pilots[p].name);
|
||||
egg += line;
|
||||
}
|
||||
egg += "[smallbitmap]\n";
|
||||
sprintf(line, "bitmap=BitMap::Small::%s\n", fe->pilotName);
|
||||
egg += line;
|
||||
for (int p = 0; p < extra_count; ++p)
|
||||
for (int p = 0; p < pilot_count; ++p)
|
||||
{
|
||||
sprintf(line, "bitmap=BitMap::Small::%s\n", extras[p].name);
|
||||
sprintf(line, "bitmap=BitMap::Small::%s\n", pilots[p].name);
|
||||
egg += line;
|
||||
}
|
||||
|
||||
sprintf(line, "[BitMap::Large::%s]\n", fe->pilotName);
|
||||
egg += line;
|
||||
AppendNameBitmap(egg, 128, 32, fe->pilotName);
|
||||
egg += "width=8\n";
|
||||
sprintf(line, "[BitMap::Small::%s]\n", fe->pilotName);
|
||||
egg += line;
|
||||
AppendNameBitmap(egg, 64, 16, fe->pilotName);
|
||||
egg += "width=4\n";
|
||||
|
||||
for (int p = 0; p < extra_count; ++p)
|
||||
for (int p = 0; p < pilot_count; ++p)
|
||||
{
|
||||
sprintf(line, "[BitMap::Large::%s]\n", extras[p].name);
|
||||
sprintf(line, "[BitMap::Large::%s]\n", pilots[p].name);
|
||||
egg += line;
|
||||
AppendNameBitmap(egg, 128, 32, extras[p].name);
|
||||
AppendNameBitmap(egg, 128, 32, pilots[p].name);
|
||||
egg += "width=8\n";
|
||||
sprintf(line, "[BitMap::Small::%s]\n", extras[p].name);
|
||||
sprintf(line, "[BitMap::Small::%s]\n", pilots[p].name);
|
||||
egg += line;
|
||||
AppendNameBitmap(egg, 64, 16, extras[p].name);
|
||||
AppendNameBitmap(egg, 64, 16, pilots[p].name);
|
||||
egg += "width=4\n";
|
||||
}
|
||||
|
||||
@@ -775,13 +1011,13 @@ namespace
|
||||
|
||||
// [pilots]-order names for the network console's results
|
||||
strcpy(gLastPilotNamesCsv, fe->pilotName);
|
||||
for (int p = 0; p < extra_count; ++p)
|
||||
for (int p = 1; p < pilot_count; ++p)
|
||||
{
|
||||
if (strlen(gLastPilotNamesCsv) + strlen(extras[p].name) + 2 <
|
||||
if (strlen(gLastPilotNamesCsv) + strlen(pilots[p].name) + 2 <
|
||||
sizeof(gLastPilotNamesCsv))
|
||||
{
|
||||
strcat(gLastPilotNamesCsv, ",");
|
||||
strcat(gLastPilotNamesCsv, extras[p].name);
|
||||
strcat(gLastPilotNamesCsv, pilots[p].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user