From cb06fedc18c7373a3bbfdace3e89e6d231c1077d Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 26 Aug 2023 06:05:09 -0700 Subject: [PATCH] Make -writetextmap a console command, call it "writetextmap" - Convert multiple maps at once - The game cheers for you when it's done and tells you where it saved the TEXTMAP files --- src/d_netcmd.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/g_game.c | 28 +++++++++++++++++++ src/g_game.h | 1 + src/p_setup.c | 11 +++++--- 4 files changed, 110 insertions(+), 3 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e5e3e267f..003af15c4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -187,6 +187,8 @@ static void Command_Automate_Set(void); static void Command_Eval(void); +static void Command_WriteTextmap(void); + // ========================================================================= // CLIENT VARIABLES // ========================================================================= @@ -426,6 +428,8 @@ void D_RegisterServerCommands(void) COM_AddCommand("eval", Command_Eval); + COM_AddCommand("writetextmap", Command_WriteTextmap); + // for master server connection AddMServCommands(); @@ -6136,6 +6140,75 @@ static void Command_Eval(void) } } +static void Command_WriteTextmap(void) +{ + if (COM_Argc() < 2) + { + CONS_Printf( +"writetextmap [map2...]: Update a map to the latest UDMF version.\n" +"- Use the full map name, e.g. RR_TestRun.\n" +"- You can give this command UP TO %d map names and it will convert all of them.\n" +"- This command generates TEXTMAP files.\n" +"- The location of the generated TEXTMAPs will appear in the console.\n", +ROUNDQUEUE_MAX + ); + return; + } + + if (Playing()) + { + CONS_Alert(CONS_ERROR, "This command cannot be used in-game. Return to the titlescreen first!\n"); + return; + } + + if (COM_Argc() - 1 > ROUNDQUEUE_MAX) + { + CONS_Alert(CONS_ERROR, "Cannot convert more than %d maps. Try again.\n", ROUNDQUEUE_MAX); + return; + } + + // Start up a "minor" grand prix session + memset(&grandprixinfo, 0, sizeof(struct grandprixinfo)); + memset(&roundqueue, 0, sizeof(struct roundqueue)); + + grandprixinfo.gamespeed = KARTSPEED_NORMAL; + grandprixinfo.masterbots = false; + + grandprixinfo.gp = true; + grandprixinfo.cup = NULL; + grandprixinfo.wonround = false; + + grandprixinfo.initalize = true; + + roundqueue.position = 1; + roundqueue.roundnum = 1; + roundqueue.writetextmap = true; + + size_t i; + + for (i = 1; i < COM_Argc(); ++i) + { + INT32 map = G_MapNumber(COM_Argv(i)); + + if (map < 0 || map >= nummapheaders) + { + CONS_Alert(CONS_WARNING, "%s: Map doesn't exist. Not doing anything.\n", COM_Argv(i)); + + // clear round queue (to be safe) + memset(&roundqueue, 0, sizeof(struct roundqueue)); + return; + } + + INT32 gt = G_GuessGametypeByTOL(mapheaderinfo[map]->typeoflevel); + + G_MapIntoRoundQueue(map, gt != -1 ? gt : GT_RACE, false, false); + } + + D_MapChange(1 + roundqueue.entries[0].mapnum, roundqueue.entries[0].gametype, false, true, 1, false, false); + + CON_ToggleOff(); +} + /** Makes a change to ::cv_forceskin take effect immediately. * * \sa Command_SetForcedSkin_f, cv_forceskin, forcedskin diff --git a/src/g_game.c b/src/g_game.c index 345b65d95..5dcd41f39 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1130,6 +1130,33 @@ void G_DoLoadLevelEx(boolean resetplayer, gamestate_t newstate) Z_CheckHeap(-2); #endif + if (roundqueue.writetextmap == true) + { + if (roundqueue.size > 0) + { + G_GetNextMap(); + + // roundqueue is wiped after the last round, but + // preserve this to track state into the Podium! + roundqueue.writetextmap = true; + + G_NextLevel(); + return; + } + else + { + // Podium: writetextmap is finished. Yay! + HU_DoTitlecardCEcho(va("Congratulations,\\%s!\\Check the console!", cv_playername[0].string)); + + livestudioaudience_timer = 0; + LiveStudioAudience(); + + CONS_Printf("\n\n\x83""writetextmap: Find your TEXTMAPs in %s\n", srb2home); + + roundqueue.writetextmap = false; + } + } + for (i = 0; i <= r_splitscreen; i++) { if (camera[i].chase) @@ -1899,6 +1926,7 @@ void G_Ticker(boolean run) case GS_CEREMONY: P_Ticker(run); K_CeremonyTicker(run); + HU_Ticker(); break; case GS_WAITINGPLAYERS: diff --git a/src/g_game.h b/src/g_game.h index 84dc5f4ac..b12124aef 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -70,6 +70,7 @@ extern struct roundqueue UINT8 position; // Head position in the round queue UINT8 size; // Number of entries in the round queue boolean netcommunicate; // As server, should we net-communicate this in XD_MAP? + boolean writetextmap; // This queue is for automated map conversion roundentry_t entries[ROUNDQUEUE_MAX]; // Entries in the round queue } roundqueue; diff --git a/src/p_setup.c b/src/p_setup.c index 958bfa22e..798c6dbb3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2134,10 +2134,15 @@ typedef struct mapthing_t *angleanchor; } sectorspecialthings_t; +static boolean P_CanWriteTextmap(void) +{ + return roundqueue.writetextmap == true && roundqueue.size > 0; +} + static FILE *P_OpenTextmap(const char *mode, const char *error) { FILE *f; - char *filepath = va(pandf, srb2home, "TEXTMAP"); + char *filepath = va("%s" PATHSEP "TEXTMAP.%s.txt", srb2home, mapheaderinfo[gamemap-1]->lumpname); f = fopen(filepath, mode); if (!f) @@ -7439,7 +7444,7 @@ static boolean P_LoadMapFromFile(void) if (!udmf) P_ConvertBinaryMap(); - if (M_CheckParm("-writetextmap")) + if (P_CanWriteTextmap()) P_WriteTextmap(); // Copy relevant map data for NetArchive purposes. @@ -8364,7 +8369,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) // Backwards compatibility for non-UDMF maps K_AdjustWaypointsParameters(); - if (M_CheckParm("-writetextmap")) + if (P_CanWriteTextmap()) P_WriteTextmapWaypoints(); }