diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f0f6eea77..20eadd721 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -87,7 +87,6 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum); static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum); static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum); static void Got_PickVotecmd(UINT8 **cp, INT32 playernum); -static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum); static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum); static void Got_Addfilecmd(UINT8 **cp, INT32 playernum); static void Got_Pause(UINT8 **cp, INT32 playernum); @@ -518,7 +517,6 @@ consvar_t cv_kartdebugamount = CVAR_INIT ("kartdebugamount", "1", CV_NETVAR|CV_C #else #define VALUE "No" #endif -consvar_t cv_kartallowgiveitem = CVAR_INIT ("kartallowgiveitem", VALUE, CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_YesNo, NULL); #undef VALUE consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL); @@ -695,7 +693,6 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "ACCEPTPARTYINVITE", // XD_ACCEPTPARTYINVITE "LEAVEPARTY", // XD_LEAVEPARTY "CANCELPARTYINVITE", // XD_CANCELPARTYINVITE - "GIVEITEM", // XD_GIVEITEM "ADDBOT", // XD_ADDBOT "DISCORD", // XD_DISCORD "PLAYSOUND", // XD_PLAYSOUND @@ -755,8 +752,6 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_MODIFYVOTE, Got_ModifyVotecmd); RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd); - RegisterNetXCmd(XD_GIVEITEM, Got_GiveItemcmd); - RegisterNetXCmd(XD_SCHEDULETASK, Got_ScheduleTaskcmd); RegisterNetXCmd(XD_SCHEDULECLEAR, Got_ScheduleClearcmd); RegisterNetXCmd(XD_AUTOMATE, Got_Automatecmd); @@ -1193,15 +1188,18 @@ void D_RegisterClientCommands(void) COM_AddCommand("god", Command_CheatGod_f); COM_AddCommand("setrings", Command_Setrings_f); COM_AddCommand("setlives", Command_Setlives_f); + COM_AddCommand("setscore", Command_Setscore_f); COM_AddCommand("devmode", Command_Devmode_f); COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f); COM_AddCommand("scale", Command_Scale_f); COM_AddCommand("gravflip", Command_Gravflip_f); COM_AddCommand("hurtme", Command_Hurtme_f); + COM_AddCommand("ateleport", Command_ATeleport_f); COM_AddCommand("teleport", Command_Teleport_f); COM_AddCommand("rteleport", Command_RTeleport_f); COM_AddCommand("skynum", Command_Skynum_f); COM_AddCommand("weather", Command_Weather_f); + COM_AddCommand("angle", Command_Angle_f); CV_RegisterVar(&cv_renderhitbox); CV_RegisterVar(&cv_showgremlins); @@ -2121,6 +2119,24 @@ void D_Cheat(INT32 playernum, INT32 cheat, ...) return; } + if (demo.playback && cheat == CHEAT_DEVMODE) + { + // There is no networking in demos, but devmode is + // too useful to be inaccessible! + // TODO: maybe allow everything, even though it would + // desync replays? May be useful for debugging. + va_start(ap, cheat); + cht_debug = va_arg(ap, UINT32); + va_end(ap); + return; + } + + // sanity check + if (demo.playback) + { + return; + } + WRITEUINT8(p, playernum); WRITEUINT8(p, cheat); @@ -2151,6 +2167,7 @@ void D_Cheat(INT32 playernum, INT32 cheat, ...) break; case CHEAT_RELATIVE_TELEPORT: + case CHEAT_TELEPORT: COPY(WRITEFIXED, fixed_t); COPY(WRITEFIXED, fixed_t); COPY(WRITEFIXED, fixed_t); @@ -2159,6 +2176,20 @@ void D_Cheat(INT32 playernum, INT32 cheat, ...) case CHEAT_DEVMODE: COPY(WRITEUINT32, UINT32); break; + + case CHEAT_GIVEITEM: + COPY(WRITESINT8, int); + COPY(WRITEUINT8, unsigned int); + break; + + case CHEAT_SCORE: + COPY(WRITEUINT32, UINT32); + break; + + case CHEAT_ANGLE: + COPY(WRITEANGLE, angle_t); + break; + } #undef COPY @@ -5547,34 +5578,6 @@ static void Got_PickVotecmd(UINT8 **cp, INT32 playernum) Y_SetupVoteFinish(pick, level); } -static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum) -{ - int item; - int amt; - - item = READSINT8 (*cp); - amt = READUINT8 (*cp); - - if ( - ( netgame && ! cv_kartallowgiveitem.value ) || - ( item < KITEM_SAD || item >= NUMKARTITEMS ) - ) - { - CONS_Alert(CONS_WARNING, - M_GetText ("Illegal give item received from %s\n"), - player_names[playernum]); - if (server) - SendKick(playernum, KICK_MSG_CON_FAIL); - return; - } - - K_StripItems(&players[playernum]); - players[playernum].itemroulette = KROULETTE_DISABLED; - - players[playernum].itemtype = item; - players[playernum].itemamount = amt; -} - static void Got_ScheduleTaskcmd(UINT8 **cp, INT32 playernum) { char command[MAXTEXTCMD]; @@ -5704,10 +5707,12 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum) if (!P_MobjWasRemoved(player->mo)) { player->mo->flags ^= MF_NOCLIP; + player->noclip = true; if (!(player->mo->flags & MF_NOCLIP)) { status = "off"; + player->noclip = false; } } @@ -5801,7 +5806,8 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum) break; } - case CHEAT_RELATIVE_TELEPORT: { + case CHEAT_RELATIVE_TELEPORT: + case CHEAT_TELEPORT: { fixed_t x = READFIXED(*cp); fixed_t y = READFIXED(*cp); fixed_t z = READFIXED(*cp); @@ -5816,12 +5822,22 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum) if (!P_MobjWasRemoved(player->mo)) { P_MapStart(); - P_SetOrigin(player->mo, - player->mo->x + x, - player->mo->y + y, - player->mo->z + z); + if (cheat == CHEAT_RELATIVE_TELEPORT) + { + P_SetOrigin(player->mo, + player->mo->x + x, + player->mo->y + y, + player->mo->z + z); + } + else + { + P_SetOrigin(player->mo, x, y, z); + } P_MapEnd(); + player->pflags |= PF_TRUSTWAYPOINTS; + player->bigwaypointgap = 0; + S_StartSound(player->mo, sfx_mixup); } @@ -5829,7 +5845,10 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum) strlcpy(t[1], M_Ftrim(f[1]), sizeof t[1]); strlcpy(t[2], M_Ftrim(f[2]), sizeof t[2]); - CV_CheaterWarning(targetPlayer, va("relative teleport by %d%s, %d%s, %d%s", + CV_CheaterWarning(targetPlayer, va("%s %d%s, %d%s, %d%s", + cheat == CHEAT_RELATIVE_TELEPORT + ? "relative teleport by" + : "teleport to", (int)f[0], t[0], (int)f[1], t[1], (int)f[2], t[2])); break; } @@ -5841,6 +5860,54 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum) break; } + case CHEAT_GIVEITEM: { + SINT8 item = READSINT8(*cp); + UINT8 amt = READUINT8(*cp); + + item = max(item, KITEM_SAD); + item = min(item, NUMKARTITEMS - 1); + + K_StripItems(player); + + // Cancel roulette if rolling + player->itemroulette = KROULETTE_DISABLED; + + player->itemtype = item; + player->itemamount = amt; + + if (amt == 0) + { + CV_CheaterWarning(playernum, "delete my items"); + } + else + { + // FIXME: we should have actual KITEM_ name array + const char *itemname = cv_kartdebugitem.PossibleValue[1 + item].strvalue; + + CV_CheaterWarning(playernum, va("give item %s x%d", itemname, amt)); + } + break; + } + + case CHEAT_SCORE: { + UINT32 score = READUINT32(*cp); + + player->roundscore = score; + + CV_CheaterWarning(targetPlayer, va("score = %u", score)); + break; + } + + case CHEAT_ANGLE: { + angle_t angle = READANGLE(*cp); + float anglef = FIXED_TO_FLOAT(AngleFixed(angle)); + + P_SetPlayerAngle(player, angle); + + CV_CheaterWarning(targetPlayer, va("angle = %d%s", (int)anglef, M_Ftrim(anglef))); + break; + } + case NUMBER_OF_CHEATS: break; } @@ -6080,77 +6147,73 @@ static void Command_Archivetest_f(void) } #endif -/** Give yourself an, optional quantity or one of, an item. - * - * \sa cv_kartallowgiveitem -*/ +/** Give yourself an, optional quantity or one of, an item.**/ + static void Command_KartGiveItem_f(void) { - char buf[2]; + UINT8 localplayer = g_localplayers[consoleplayer]; int ac; const char *name; - int item; + INT32 item; const char * str; int i; - /* Allow always in local games. */ - if (! netgame || cv_kartallowgiveitem.value) + ac = COM_Argc(); + if (ac < 2) { - ac = COM_Argc(); - if (ac < 2) - { - CONS_Printf( -"kartgiveitem [amount]: Give yourself an item\n" - ); - } - else - { - item = NUMKARTITEMS; - - name = COM_Argv(1); - - if (isdigit(*name) || *name == '-') - { - item = atoi(name); - } - else - { - for (i = 0; ( str = kartdebugitem_cons_t[i].strvalue ); ++i) - { - if (strcasecmp(name, str) == 0) - { - item = kartdebugitem_cons_t[i].value; - break; - } - } - } - - if (item < NUMKARTITEMS) - { - buf[0] = item; - - if (ac > 2) - buf[1] = atoi(COM_Argv(2)); - else - buf[1] = 1;/* default to one quantity */ - - SendNetXCmd(XD_GIVEITEM, buf, 2); - } - else - { - CONS_Alert(CONS_WARNING, - "No item matches '%s'\n", - name); - } - } + CONS_Printf( + "give [amount]: Give yourself an item\n" + ); } else { - CONS_Alert(CONS_NOTICE, - "The server does not allow this.\n"); + item = NUMKARTITEMS; + + name = COM_Argv(1); + + if (isdigit(*name) || *name == '-') + { + item = atoi(name); + } + else + { + /* first check exact match */ + if (!CV_CompleteValue(&cv_kartdebugitem, &name, &item)) + { + CONS_Printf("\x83" "Autocomplete:\n"); + + /* then do very loose partial matching */ + for (i = 0; ( str = kartdebugitem_cons_t[i].strvalue ); ++i) + { + if (strcasestr(str, name) != NULL) + { + CONS_Printf("\x83\t%s\n", str); + item = kartdebugitem_cons_t[i].value; + } + } + } + } + + if (item < NUMKARTITEMS) + { + INT32 amt; + + if (ac > 2) + amt = atoi(COM_Argv(2)); + else + amt = (item != KITEM_NONE);/* default to one quantity, or zero, if KITEM_NONE */ + + D_Cheat(localplayer, CHEAT_GIVEITEM, item, amt); + } + else + { + CONS_Alert(CONS_WARNING, + "No item matches '%s'\n", + name); + } } } diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 43761bd3b..e23549def 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -171,7 +171,7 @@ extern consvar_t cv_kartslipdash; extern consvar_t cv_votetime; -extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugdistribution, cv_kartdebughuddrop; +extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugdistribution, cv_kartdebughuddrop; extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector; extern consvar_t cv_kartdebugwaypoints, cv_kartdebuglap,cv_kartdebugbotpredict; @@ -249,14 +249,13 @@ typedef enum XD_ACCEPTPARTYINVITE, // 29 XD_LEAVEPARTY, // 30 XD_CANCELPARTYINVITE, // 31 - XD_GIVEITEM, // 32 - XD_ADDBOT, // 33 - XD_DISCORD, // 34 - XD_PLAYSOUND, // 35 - XD_SCHEDULETASK, // 36 - XD_SCHEDULECLEAR, // 37 - XD_AUTOMATE, // 38 - XD_CHEAT, // 39 + XD_ADDBOT, // 32 + XD_DISCORD, // 33 + XD_PLAYSOUND, // 34 + XD_SCHEDULETASK, // 35 + XD_SCHEDULECLEAR, // 36 + XD_AUTOMATE, // 37 + XD_CHEAT, // 38 MAXNETXCMD } netxcmd_t; diff --git a/src/d_player.h b/src/d_player.h index f2de78d0f..73b6550d4 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -612,6 +612,7 @@ struct player_t UINT8 instashield; // Instashield no-damage animation timer UINT8 wipeoutslow; // Timer before you slowdown when getting wiped out UINT8 justbumped; // Prevent players from endlessly bumping into each other + boolean noclip; // Fix Grow breaking the "noclip" cheat. Also applies noclip as a bonus. SINT8 drift; // (-5 to 5) - Drifting Left or Right, plus a bigger counter = sharper turn fixed_t driftcharge; // Charge your drift so you can release a burst of speed diff --git a/src/k_kart.c b/src/k_kart.c index ff09aaf9e..d836564ca 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -261,7 +261,6 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartdebugitem); CV_RegisterVar(&cv_kartdebugamount); - CV_RegisterVar(&cv_kartallowgiveitem); CV_RegisterVar(&cv_kartdebugdistribution); CV_RegisterVar(&cv_kartdebughuddrop); CV_RegisterVar(&cv_kartdebugwaypoints); @@ -7801,7 +7800,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) // If a Grow player or a sector crushes you, get flattened instead of being killed. if (player->squishedtimer <= 0) { - player->mo->flags &= ~MF_NOCLIP; + if (!player->noclip) + { + // le no clipping cheat. + player->mo->flags &= ~MF_NOCLIP; + } } else { @@ -7810,6 +7813,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->mo->momy = 0; } + if (player->noclip) + { + // Might as well make it apply this as well. + player->mo->flags |= MF_NOCLIP; + } + if ((player->mo->eflags & MFE_UNDERWATER) && player->curshield != KSHIELD_BUBBLE) { if (player->breathTimer < UINT16_MAX) diff --git a/src/m_cheat.c b/src/m_cheat.c index 9830ebcec..60e0bd807 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -354,7 +354,7 @@ void Command_RTeleport_f(void) FLOAT_TO_FIXED(x), FLOAT_TO_FIXED(y), FLOAT_TO_FIXED(z)); } -void Command_Teleport_f(void) +void Command_ATeleport_f(void) { fixed_t intx, inty, intz; size_t i; @@ -575,6 +575,25 @@ void Command_Teleport_f(void) P_MapEnd(); } +void Command_Teleport_f(void) +{ + float x = atof(COM_Argv(1)); + float y = atof(COM_Argv(2)); + float z = atof(COM_Argv(3)); + + REQUIRE_DEVMODE; + REQUIRE_INLEVEL; + + if (COM_Argc() != 4) + { + CONS_Printf(M_GetText("teleport : teleport to a location\n")); + return; + } + + D_Cheat(consoleplayer, CHEAT_TELEPORT, + FLOAT_TO_FIXED(x), FLOAT_TO_FIXED(y), FLOAT_TO_FIXED(z)); +} + void Command_Skynum_f(void) { REQUIRE_DEVMODE; @@ -782,8 +801,6 @@ void Command_Devmode_f(void) void Command_Setrings_f(void) { REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; - REQUIRE_PANDORA; D_Cheat(consoleplayer, CHEAT_RINGS, atoi(COM_Argv(1))); } @@ -791,12 +808,27 @@ void Command_Setrings_f(void) void Command_Setlives_f(void) { REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; - REQUIRE_PANDORA; D_Cheat(consoleplayer, CHEAT_LIVES, atoi(COM_Argv(1))); } +void Command_Setscore_f(void) +{ + REQUIRE_INLEVEL; + + D_Cheat(consoleplayer, CHEAT_SCORE, atoi(COM_Argv(1))); +} + +void Command_Angle_f(void) +{ + const float anglef = atof(COM_Argv(1)); + const angle_t angle = FixedAngle(FLOAT_TO_FIXED(anglef)); + + REQUIRE_INLEVEL; + + D_Cheat(consoleplayer, CHEAT_ANGLE, angle); +} + // // OBJECTPLACE (and related variables) // diff --git a/src/m_cheat.h b/src/m_cheat.h index c217d7f01..e795cad2a 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -33,7 +33,11 @@ typedef enum { CHEAT_FLIP, CHEAT_HURT, CHEAT_RELATIVE_TELEPORT, + CHEAT_TELEPORT, CHEAT_DEVMODE, + CHEAT_GIVEITEM, + CHEAT_SCORE, + CHEAT_ANGLE, NUMBER_OF_CHEATS } cheat_t; @@ -76,8 +80,11 @@ void Command_Gravflip_f(void); void Command_Hurtme_f(void); void Command_Teleport_f(void); void Command_RTeleport_f(void); +void Command_ATeleport_f(void); void Command_Skynum_f(void); void Command_Weather_f(void); +void Command_Angle_f(void); +void Command_Setscore_f(void); #ifdef _DEBUG void Command_CauseCfail_f(void); #endif diff --git a/src/p_saveg.c b/src/p_saveg.c index e0b3b41bb..94edc68fd 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -255,6 +255,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].instashield); WRITEUINT8(save->p, players[i].wipeoutslow); WRITEUINT8(save->p, players[i].justbumped); + WRITEUINT8(save->p, players[i].noclip); WRITESINT8(save->p, players[i].drift); WRITEFIXED(save->p, players[i].driftcharge); @@ -582,6 +583,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].instashield = READUINT8(save->p); players[i].wipeoutslow = READUINT8(save->p); players[i].justbumped = READUINT8(save->p); + players[i].noclip = READUINT8(save->p); players[i].drift = READSINT8(save->p); players[i].driftcharge = READFIXED(save->p);