diff --git a/RP_L4/RPL4FE.cpp b/RP_L4/RPL4FE.cpp index 9cb3407..7603933 100644 --- a/RP_L4/RPL4FE.cpp +++ b/RP_L4/RPL4FE.cpp @@ -2267,6 +2267,12 @@ Logical return gHavePersist && IsFootball(gPersistSelection); } +Logical + RPL4FrontEnd_IsCameraRole() +{ + return gHavePersist && WantsCamera(gPersistSelection); +} + void RPL4FrontEnd_SetHostedPilots( const char *owner_address, diff --git a/RP_L4/RPL4FE.h b/RP_L4/RPL4FE.h index b6bf02c..1ad3643 100644 --- a/RP_L4/RPL4FE.h +++ b/RP_L4/RPL4FE.h @@ -110,6 +110,16 @@ void Logical RPL4FrontEnd_IsFootballSelected(); +// +// True when this player's setup menu has YOUR ROLE on Live Cam. Only the +// HOST's pick is acted on - the host is the one that writes the egg - so +// the lobby publishes this and then shows it against the owner's row +// only. A member who picked it still races, which is what their row goes +// on saying. +// +Logical + RPL4FrontEnd_IsCameraRole(); + // Hosted-race pilots fed by the Steam lobby: overrides the // RP412HOSTPODS parsing with real personas and loadouts. owner_address // is this pod's mesh IP (the FakeIP); count 0 clears the override. diff --git a/RP_L4/RPL4LOBBY.cpp b/RP_L4/RPL4LOBBY.cpp index 01118f2..549065d 100644 --- a/RP_L4/RPL4LOBBY.cpp +++ b/RP_L4/RPL4LOBBY.cpp @@ -65,6 +65,9 @@ namespace const char kNetRevision[] = "2"; const char kNetRevKey[] = "nr"; + // this member picked Live Cam rather than a grid slot + const char kCamKey[] = "cam"; + // the owner's mission setup, shown to everyone in the room const char kMapKey[] = "mp"; const char kTimeKey[] = "td"; @@ -172,6 +175,15 @@ namespace SteamMatchmaking()->SetLobbyMemberData(gLobby, "cl", color); SteamMatchmaking()->SetLobbyMemberData(gLobby, "bd", badge); + // + // Live Cam. The loadout above still goes out unchanged - the pick + // is a role, not a vehicle, and it is only acted on for the host, + // so a member's own row must go on showing what it will really + // fly. The room screen reads this against the owner's row. + // + SteamMatchmaking()->SetLobbyMemberData(gLobby, kCamKey, + RPL4FrontEnd_IsCameraRole() ? "1" : "0"); + // football: this member's own team and position pick SteamMatchmaking()->SetLobbyMemberData(gLobby, "tm", RPL4FrontEnd_TeamKey(RPL4FrontEnd_GetTeamIndex())); @@ -246,6 +258,7 @@ namespace char team[32]; // football pick char position[16]; char netRev[8]; // simulation protocol revision + Logical camera; // picked Live Cam (acted on for the host) Logical published; }; @@ -289,6 +302,9 @@ namespace strncpy(member->netRev, SteamMatchmaking()->GetLobbyMemberData(gLobby, member->id, kNetRevKey), sizeof(member->netRev) - 1); + member->camera = (atoi( + SteamMatchmaking()->GetLobbyMemberData(gLobby, member->id, kCamKey)) != 0) + ? True : False; member->published = member->ip[0] != '\0' && member->consolePort > 0 && member->gamePort > 0; } @@ -566,7 +582,19 @@ namespace // travel on the wire; the catalogs turn them back into // names, so nobody reads "bttlbrg". //----------------------------------------------------------- - if (FootballLobby()) + // + // A Live Cam host brings no vehicle, so its row says the role + // instead of a loadout. Only the owner's row: the host writes + // the egg, so only the host's pick is acted on, and a member + // who set Live Cam is still going to race - saying otherwise + // here would be the room screen lying about the grid. + // + if (member->camera && is_owner_row) + { + DrawTextA(mem, "LIVE CAM", -1, &row, + DT_RIGHT | DT_VCENTER | DT_SINGLELINE); + } + else if (FootballLobby()) { if (member->team[0] != '\0') {