Merge branch 'noclip-online' into 'master'

Cheat/Debug Commands ...ONLINE

See merge request KartKrew/Kart!717
This commit is contained in:
James R 2022-09-30 22:51:42 +00:00
commit ee2302d6ee
14 changed files with 222 additions and 312 deletions

View file

@ -37,6 +37,7 @@
#include "r_data.h" // Color_cons_t
#include "r_skins.h"
#include "m_random.h"
#include "p_local.h" // P_ResetPlayerCheats
//========
// protos.
@ -1891,7 +1892,6 @@ void CV_CheatsChanged(void)
else
{
consvar_t *cvar;
UINT8 i;
// Set everything back to default.
for (cvar = consvar_vars; cvar; cvar = cvar->next)
@ -1901,13 +1901,7 @@ void CV_CheatsChanged(void)
// Reset any other cheat command effects here, as well.
cv_debug = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
players[i].cheats = 0;
}
P_ResetPlayerCheats();
}
}

View file

@ -96,6 +96,7 @@ static void Got_DiscordInfo(UINT8 **cp, INT32 playernum);
static void Got_ScheduleTaskcmd(UINT8 **cp, INT32 playernum);
static void Got_ScheduleClearcmd(UINT8 **cp, INT32 playernum);
static void Got_Automatecmd(UINT8 **cp, INT32 playernum);
static void Got_Cheat(UINT8 **cp, INT32 playernum);
static void PointLimit_OnChange(void);
static void TimeLimit_OnChange(void);
@ -626,7 +627,8 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
"PLAYSOUND", // XD_PLAYSOUND
"SCHEDULETASK", // XD_SCHEDULETASK
"SCHEDULECLEAR", // XD_SCHEDULECLEAR
"AUTOMATE" // XD_AUTOMATE
"AUTOMATE", // XD_AUTOMATE
"CHEAT", // XD_CHEAT
};
// =========================================================================
@ -679,6 +681,8 @@ void D_RegisterServerCommands(void)
RegisterNetXCmd(XD_SCHEDULECLEAR, Got_ScheduleClearcmd);
RegisterNetXCmd(XD_AUTOMATE, Got_Automatecmd);
RegisterNetXCmd(XD_CHEAT, Got_Cheat);
// Remote Administration
COM_AddCommand("password", Command_Changepassword_f);
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
@ -2015,6 +2019,49 @@ void D_SendPlayerConfig(UINT8 n)
SendNetXCmdForPlayer(n, XD_POWERLEVEL, buf, p-buf);
}
void D_Cheat(INT32 playernum, INT32 cheat, ...)
{
va_list ap;
UINT8 buf[64];
UINT8 *p = buf;
if (!CV_CheatsEnabled())
{
CONS_Printf("This cannot be used without cheats enabled.\n");
return;
}
WRITEUINT8(p, playernum);
WRITEUINT8(p, cheat);
va_start(ap, cheat);
#define COPY(writemacro, type) writemacro (p, va_arg(ap, type))
switch (cheat)
{
case CHEAT_RINGS:
case CHEAT_LIVES:
// If you're confused why 'int' instead of
// 'SINT8', search online: 'default argument promotions'
COPY(WRITESINT8, int);
break;
case CHEAT_SCALE:
COPY(WRITEFIXED, fixed_t);
break;
case CHEAT_HURT:
COPY(WRITEINT32, INT32);
break;
}
#undef COPY
va_end(ap);
SendNetXCmd(XD_CHEAT, buf, p - buf);
}
// Only works for displayplayer, sorry!
static void Command_ResetCamera_f(void)
{
@ -5454,6 +5501,120 @@ static void Got_Automatecmd(UINT8 **cp, INT32 playernum)
}
}
static void Got_Cheat(UINT8 **cp, INT32 playernum)
{
UINT8 targetPlayer = READUINT8(*cp);
cheat_t cheat = READUINT8(*cp);
player_t *player;
if (cheat >= NUMBER_OF_CHEATS || !CV_CheatsEnabled() || targetPlayer >= MAXPLAYERS ||
playernode[targetPlayer] != playernode[playernum])
{
CONS_Alert(CONS_WARNING,
M_GetText ("Illegal cheat command received from %s\n"),
player_names[playernum]);
return;
}
player = &players[targetPlayer];
switch (cheat)
{
case CHEAT_NOCLIP: {
const char *status = "on";
if (!P_MobjWasRemoved(player->mo))
{
player->mo->flags ^= MF_NOCLIP;
if (!(player->mo->flags & MF_NOCLIP))
{
status = "off";
}
}
CV_CheaterWarning(targetPlayer, va("noclip %s", status));
break;
}
case CHEAT_GOD: {
const char *status = (player->pflags & PF_GODMODE) ? "off" : "on";
player->pflags ^= PF_GODMODE;
CV_CheaterWarning(targetPlayer, va("GOD MODE %s", status));
break;
}
case CHEAT_RINGS: {
SINT8 rings = READSINT8(*cp);
// P_GivePlayerRings does value clamping
player->rings = 0;
P_GivePlayerRings(player, rings);
CV_CheaterWarning(targetPlayer, va("rings = %d", rings));
break;
}
case CHEAT_LIVES: {
SINT8 lives = READSINT8(*cp);
// P_GivePlayerLives does value clamping
player->lives = 0;
P_GivePlayerLives(player, lives);
CV_CheaterWarning(targetPlayer, va("lives = %d", lives));
break;
}
case CHEAT_SCALE: {
const fixed_t smin = FRACUNIT/100;
const fixed_t smax = 100*FRACUNIT;
fixed_t s = READFIXED(*cp);
float f;
s = min(max(smin, s), smax);
f = FIXED_TO_FLOAT(s);
if (!P_MobjWasRemoved(player->mo))
{
player->mo->destscale = s;
}
CV_CheaterWarning(targetPlayer, va("scale = %d%s", (int)f, M_Ftrim(FIXED_TO_FLOAT(s))));
break;
}
case CHEAT_FLIP: {
if (!P_MobjWasRemoved(player->mo))
{
player->mo->flags2 ^= MF2_OBJECTFLIP;
}
CV_CheaterWarning(targetPlayer, "invert gravity");
break;
}
case CHEAT_HURT: {
INT32 damage = READINT32(*cp);
if (!P_MobjWasRemoved(player->mo))
{
P_DamageMobj(player->mo, NULL, NULL, damage, DMG_NORMAL);
}
CV_CheaterWarning(targetPlayer, va("%d damage to me", damage));
break;
}
case NUMBER_OF_CHEATS:
break;
}
}
/** Prints the number of displayplayers[0].
*
* \todo Possibly remove this; it was useful for debugging at one point.

View file

@ -203,6 +203,7 @@ typedef enum
XD_SCHEDULETASK, // 36
XD_SCHEDULECLEAR, // 37
XD_AUTOMATE, // 38
XD_CHEAT, // 39
MAXNETXCMD
} netxcmd_t;
@ -304,6 +305,8 @@ void Automate_Clear(void);
extern UINT32 livestudioaudience_timer;
void LiveStudioAudience(void);
void D_Cheat(INT32 playernum, INT32 cheat, ...);
// used for the player setup menu
UINT8 CanChangeSkin(INT32 playernum);
boolean CanChangeSkinWhilePlaying(INT32 playernum);

View file

@ -58,14 +58,15 @@ typedef enum
//
typedef enum
{
// free: 1<<0 to 1<<2
PF_GODMODE = 1<<0, // Immortal. No lightsnake from pits either
// free: 1<<1 and 1<<2
// Look back VFX has been spawned
// TODO: Is there a better way to track this?
PF_GAINAX = 1<<3,
// Accessibility and cheats
PF_KICKSTARTACCEL = 1<<4, // Is accelerate in kickstart mode?
PF_KICKSTARTACCEL = 1<<4, // Accessibility feature: Is accelerate in kickstart mode?
// 1<<5 free
// 1<<6 free
@ -105,13 +106,6 @@ typedef enum
// up to 1<<31 is free
} pflags_t;
typedef enum
{
PC_GODMODE = 1,
PC_NOCLIP = 1<<1,
// up to 1<<31 is free
} pcheats_t;
typedef enum
{
// Are animation frames playing?
@ -376,7 +370,6 @@ typedef struct player_s
// Bit flags.
// See pflags_t, above.
pflags_t pflags;
pcheats_t cheats;
// playing animation.
panim_t panim;
@ -614,7 +607,4 @@ typedef struct player_s
#endif
} player_t;
// Value for infinite lives
#define INFLIVES 0x7F
#endif

View file

@ -5718,8 +5718,9 @@ const char *const MAPTHINGFLAG_LIST[4] = {
};
const char *const PLAYERFLAG_LIST[] = {
// free: 1<<0 to 1<<2 (name un-matchable)
"\x01",
"GODMODE",
// free: 1<<1 and 1<<2 (name un-matchable)
"\x01",
"\x01",
@ -6356,9 +6357,6 @@ struct int_const_s const INT_CONST[] = {
{"PA_DRIFT",PA_DRIFT},
{"PA_HURT",PA_HURT},
// Value for infinite lives
{"INFLIVES",INFLIVES},
// Got Flags, for player->gotflag!
// Used to be MF_ for some stupid reason, now they're GF_ to stop them looking like mobjflags
{"GF_REDFLAG",GF_REDFLAG},

View file

@ -691,10 +691,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
#undef UPDATE_ALERT
#endif
/// - SRB2Kart options -
/// Camera always has noclip.
#define NOCLIPCAM
/// Other karma comeback modes
//#define OTHERKARMAMODES

View file

@ -2218,7 +2218,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
UINT32 followitem;
INT32 pflags;
INT32 cheats;
UINT8 ctfteam;
@ -2298,7 +2297,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
botrival = players[player].botvars.rival;
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE));
cheats = 0;
// SRB2kart
if (betweenmaps || leveltime < introtime)
@ -2373,10 +2371,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
pflags |= (players[player].pflags & (PF_STASIS|PF_ELIMINATED|PF_NOCONTEST|PF_FAULT|PF_LOSTLIFE));
}
// As long as we're not in multiplayer, carry over cheatcodes from map to map
if (!(netgame || multiplayer))
cheats = players[player].cheats;
if (!betweenmaps)
{
// Obliterate follower from existence (if valid memory)
@ -2392,7 +2386,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->roundscore = roundscore;
p->lives = lives;
p->pflags = pflags;
p->cheats = cheats;
p->ctfteam = ctfteam;
p->jointime = jointime;
p->splitscreenindex = splitscreenindex;
@ -4783,9 +4776,6 @@ void G_InitNew(UINT8 pencoremode, INT32 map, boolean resetplayer, boolean skippr
players[i].playerstate = PST_REBORN;
memset(&players[i].respawn, 0, sizeof (players[i].respawn));
// Clear cheatcodes too, just in case.
players[i].cheats = 0;
players[i].roundscore = 0;
if (resetplayer && !(multiplayer && demo.playback)) // SRB2Kart

View file

@ -251,37 +251,18 @@ boolean cht_Responder(event_t *ev)
// command that can be typed at the console!
void Command_CheatNoClip_f(void)
{
player_t *plyr;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER; // TODO: make netplay compatible
plyr = &players[consoleplayer];
if (!plyr->mo || P_MobjWasRemoved(plyr->mo))
return;
plyr->cheats ^= PC_NOCLIP;
CONS_Printf(M_GetText("No Clipping %s\n"), plyr->cheats & PC_NOCLIP ? M_GetText("On") : M_GetText("Off"));
if (plyr->cheats & PC_NOCLIP)
plyr->mo->flags |= MF_NOCLIP;
else
plyr->mo->flags &= ~MF_NOCLIP;
D_Cheat(consoleplayer, CHEAT_NOCLIP);
}
void Command_CheatGod_f(void)
{
player_t *plyr;
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
plyr = &players[consoleplayer];
plyr->cheats ^= PC_GODMODE;
CONS_Printf(M_GetText("Cheese Mode %s\n"), plyr->cheats & PC_GODMODE ? M_GetText("On") : M_GetText("Off"));
D_Cheat(consoleplayer, CHEAT_GOD);
}
void Command_Scale_f(void)
@ -291,7 +272,6 @@ void Command_Scale_f(void)
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (scale < FRACUNIT/100 || scale > 100*FRACUNIT) //COM_Argv(1) will return a null string if they did not give a paramater, so...
{
@ -299,29 +279,21 @@ void Command_Scale_f(void)
return;
}
if (!players[consoleplayer].mo)
return;
players[consoleplayer].mo->destscale = scale;
CONS_Printf(M_GetText("Scale set to %s\n"), COM_Argv(1));
D_Cheat(consoleplayer, CHEAT_SCALE, scale);
}
void Command_Gravflip_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (players[consoleplayer].mo)
players[consoleplayer].mo->flags2 ^= MF2_OBJECTFLIP;
D_Cheat(consoleplayer, CHEAT_FLIP);
}
void Command_Hurtme_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (COM_Argc() < 2)
{
@ -329,7 +301,7 @@ void Command_Hurtme_f(void)
return;
}
P_DamageMobj(players[consoleplayer].mo, NULL, NULL, atoi(COM_Argv(1)), DMG_NORMAL);
D_Cheat(consoleplayer, CHEAT_HURT, atoi(COM_Argv(1)));
}
void Command_RTeleport_f(void)
@ -619,7 +591,6 @@ void Command_Skynum_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
if (COM_Argc() != 2)
{
@ -764,13 +735,7 @@ void Command_Setrings_f(void)
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
if (COM_Argc() > 1)
{
// P_GivePlayerRings does value clamping
players[consoleplayer].rings = 0;
P_GivePlayerRings(&players[consoleplayer], atoi(COM_Argv(1)));
players[consoleplayer].totalring -= atoi(COM_Argv(1)); //undo totalring addition done in P_GivePlayerRings
}
D_Cheat(consoleplayer, CHEAT_RINGS, atoi(COM_Argv(1)));
}
void Command_Setlives_f(void)
@ -778,20 +743,7 @@ void Command_Setlives_f(void)
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
if (COM_Argc() > 1)
{
SINT8 lives = atoi(COM_Argv(1));
if (lives == -1)
{
players[consoleplayer].lives = INFLIVES; // infinity!
}
else
{
// P_GivePlayerLives does value clamping
players[consoleplayer].lives = 0;
P_GivePlayerLives(&players[consoleplayer], atoi(COM_Argv(1)));
}
}
D_Cheat(consoleplayer, CHEAT_LIVES, atoi(COM_Argv(1)));
}
//

View file

@ -19,6 +19,18 @@
#include "p_mobj.h"
#include "command.h"
typedef enum {
CHEAT_NOCLIP,
CHEAT_GOD,
CHEAT_RINGS,
CHEAT_LIVES,
CHEAT_SCALE,
CHEAT_FLIP,
CHEAT_HURT,
NUMBER_OF_CHEATS
} cheat_t;
boolean cht_Responder(event_t *ev);
void cht_Init(void);

View file

@ -1874,7 +1874,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (player) // Player is the target
{
if (player->cheats & PC_GODMODE)
if (player->pflags & PF_GODMODE)
return false;
if (!force)

View file

@ -195,6 +195,8 @@ void P_PlayerAfterThink(player_t *player);
void P_DoPlayerExit(player_t *player);
void P_DoTimeOver(player_t *player);
void P_ResetPlayerCheats(void);
void P_InstaThrust(mobj_t *mo, angle_t angle, fixed_t move);
fixed_t P_ReturnThrustX(mobj_t *mo, angle_t angle, fixed_t move);
fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move);

View file

@ -2360,11 +2360,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
fixed_t tryx = thiscam->x;
fixed_t tryy = thiscam->y;
#ifndef NOCLIPCAM
if ((players[displayplayers[i]].cheats & PC_NOCLIP) || (leveltime < introtime)) // Noclipping player camera noclips too!!
#else
if (!(players[displayplayers[i]].pflags & PF_NOCONTEST)) // Time Over should not clip through walls
#endif
{
floatok = true;
thiscam->floorz = thiscam->z;

View file

@ -2087,7 +2087,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
if (mo->player && mo->player->cheats & PC_GODMODE)
if (mo->player && mo->player->pflags & PF_GODMODE)
return false;
if (((mo->z <= mo->subsector->sector->floorheight
@ -3742,7 +3742,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
player->karthud[khud_timeovercam] = (2*TICRATE)+1;
}
if (!resetcalled && !(player->cheats & PC_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead.
if (!resetcalled && !(player->mo->flags & MF_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead.
{
P_ResetCamera(player, thiscam);
}

View file

@ -2993,10 +2993,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
mobj_t *mo;
fixed_t f1, f2;
fixed_t speed;
#ifndef NOCLIPCAM
boolean cameranoclip;
subsector_t *newsubsec;
#endif
fixed_t playerScale = FixedDiv(player->mo->scale, mapobjectscale);
fixed_t scaleDiff = playerScale - FRACUNIT;
@ -3054,12 +3050,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
return true;
}
#ifndef NOCLIPCAM
cameranoclip = ((player->cheats & PC_NOCLIP)
|| (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) // Noclipping player camera noclips too!!
|| (leveltime < introtime)); // Kart intro cam
#endif
if ((player->pflags & PF_NOCONTEST) && (gametyperules & GTR_CIRCUIT)) // 1 for momentum keep, 2 for turnaround
timeover = (player->karthud[khud_timeovercam] > 2*TICRATE ? 2 : 1);
else
@ -3309,204 +3299,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
z = mo->z + pviewheight + distz;
}
#ifndef NOCLIPCAM // Disable all z-clipping for noclip cam
// move camera down to move under lower ceilings
newsubsec = R_PointInSubsectorOrNull(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1));
if (!newsubsec)
newsubsec = thiscam->subsector;
if (newsubsec)
{
fixed_t myfloorz, myceilingz;
fixed_t midz = thiscam->z + (thiscam->z - mo->z)/2;
fixed_t midx = ((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1);
fixed_t midy = ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1);
// Cameras use the heightsec's heights rather then the actual sector heights.
// If you can see through it, why not move the camera through it too?
if (newsubsec->sector->camsec >= 0)
{
myfloorz = sectors[newsubsec->sector->camsec].floorheight;
myceilingz = sectors[newsubsec->sector->camsec].ceilingheight;
}
else if (newsubsec->sector->heightsec >= 0)
{
myfloorz = sectors[newsubsec->sector->heightsec].floorheight;
myceilingz = sectors[newsubsec->sector->heightsec].ceilingheight;
}
else
{
myfloorz = P_CameraGetFloorZ(thiscam, newsubsec->sector, midx, midy, NULL);
myceilingz = P_CameraGetCeilingZ(thiscam, newsubsec->sector, midx, midy, NULL);
}
// Check list of fake floors and see if floorz/ceilingz need to be altered.
if (newsubsec->sector->ffloors)
{
ffloor_t *rover;
fixed_t delta1, delta2;
INT32 thingtop = midz + thiscam->height;
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
delta1 = midz - (bottomheight
+ ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight
+ ((topheight - bottomheight)/2));
if (topheight > myfloorz && abs(delta1) < abs(delta2))
myfloorz = topheight;
if (bottomheight < myceilingz && abs(delta1) >= abs(delta2))
myceilingz = bottomheight;
}
}
// Check polyobjects and see if floorz/ceilingz need to be altered
{
INT32 xl, xh, yl, yh, bx, by;
validcount++;
xl = (unsigned)(tmbbox[BOXLEFT] - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
for (by = yl; by <= yh; by++)
for (bx = xl; bx <= xh; bx++)
{
INT32 offset;
polymaplink_t *plink; // haleyjd 02/22/06
if (bx < 0 || by < 0 || bx >= bmapwidth || by >= bmapheight)
continue;
offset = by*bmapwidth + bx;
// haleyjd 02/22/06: consider polyobject lines
plink = polyblocklinks[offset];
while (plink)
{
polyobj_t *po = plink->po;
if (po->validcount != validcount) // if polyobj hasn't been checked
{
sector_t *polysec;
fixed_t delta1, delta2, thingtop;
fixed_t polytop, polybottom;
po->validcount = validcount;
if (!P_PointInsidePolyobj(po, x, y) || !(po->flags & POF_SOLID))
{
plink = (polymaplink_t *)(plink->link.next);
continue;
}
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
if (GETSECSPECIAL(polysec->special, 4) == 12)
{ // Camera noclip polyobj.
plink = (polymaplink_t *)(plink->link.next);
continue;
}
if (po->flags & POF_CLIPPLANES)
{
polytop = polysec->ceilingheight;
polybottom = polysec->floorheight;
}
else
{
polytop = INT32_MAX;
polybottom = INT32_MIN;
}
thingtop = midz + thiscam->height;
delta1 = midz - (polybottom + ((polytop - polybottom)/2));
delta2 = thingtop - (polybottom + ((polytop - polybottom)/2));
if (polytop > myfloorz && abs(delta1) < abs(delta2))
myfloorz = polytop;
if (polybottom < myceilingz && abs(delta1) >= abs(delta2))
myceilingz = polybottom;
}
plink = (polymaplink_t *)(plink->link.next);
}
}
}
// crushed camera
if (myceilingz <= myfloorz + thiscam->height && !resetcalled && !cameranoclip)
{
P_ResetCamera(player, thiscam);
return true;
}
// camera fit?
if (myceilingz != myfloorz
&& myceilingz - thiscam->height < z)
{
/* // no fit
if (!resetcalled && !cameranoclip)
{
P_ResetCamera(player, thiscam);
return true;
}
*/
z = myceilingz - thiscam->height-FixedMul(11*FRACUNIT, mo->scale);
// is the camera fit is there own sector
}
// Make the camera a tad smarter with 3d floors
if (newsubsec->sector->ffloors && !cameranoclip)
{
ffloor_t *rover;
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if ((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
{
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
if (bottomheight - thiscam->height < z
&& midz < bottomheight)
z = bottomheight - thiscam->height-FixedMul(11*FRACUNIT, mo->scale);
else if (topheight + thiscam->height > z
&& midz > topheight)
z = topheight;
if ((mo->z >= topheight && midz < bottomheight)
|| ((mo->z < bottomheight && mo->z+mo->height < topheight) && midz >= topheight))
{
// Can't see
if (!resetcalled)
P_ResetCamera(player, thiscam);
return true;
}
}
}
}
}
if (thiscam->z < thiscam->floorz && !cameranoclip)
thiscam->z = thiscam->floorz;
#endif // NOCLIPCAM
// point viewed by the camera
// this point is just 64 unit forward the player
dist = 64*cameraScale;
@ -4592,3 +4384,27 @@ boolean P_PlayerFullbright(player_t *player)
{
return (player->invincibilitytimer > 0);
}
void P_ResetPlayerCheats(void)
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
{
player_t *player = &players[i];
mobj_t *thing = player->mo;
if (!playeringame[i])
continue;
player->pflags &= ~(PF_GODMODE);
if (P_MobjWasRemoved(thing))
continue;
thing->flags &= ~(MF_NOCLIP);
thing->destscale = mapobjectscale;
P_SetScale(thing, thing->destscale);
}
}