mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-19 14:32:34 +00:00
Merge branch 'master' into duel-stuff
This commit is contained in:
commit
d19924d96d
57 changed files with 2697 additions and 1108 deletions
|
|
@ -195,6 +195,14 @@ passthru_opts:=
|
||||||
# separate suffix with an underscore
|
# separate suffix with an underscore
|
||||||
exesuffix:=$(call _,$(EXESUFFIX))
|
exesuffix:=$(call _,$(EXESUFFIX))
|
||||||
|
|
||||||
|
# If there are uncommitted changes
|
||||||
|
# -uno: disregard untracked files
|
||||||
|
# Warning: this can only be accurate for comptime.c since
|
||||||
|
# that file is always recompiled!
|
||||||
|
ifneq ($(shell git status --porcelain -uno),)
|
||||||
|
opts+=-DCOMPVERSION_UNCOMMITTED
|
||||||
|
endif
|
||||||
|
|
||||||
include Makefile.d/platform.mk
|
include Makefile.d/platform.mk
|
||||||
include Makefile.d/features.mk
|
include Makefile.d/features.mk
|
||||||
include Makefile.d/versions.mk
|
include Makefile.d/versions.mk
|
||||||
|
|
|
||||||
|
|
@ -454,7 +454,7 @@ boolean AM_Responder(event_t *ev)
|
||||||
{
|
{
|
||||||
INT32 rc = false;
|
INT32 rc = false;
|
||||||
|
|
||||||
if (devparm || cv_debug) // only automap in Debug Tails 01-19-2001
|
if (devparm || cht_debug) // only automap in Debug Tails 01-19-2001
|
||||||
{
|
{
|
||||||
if (!automapactive)
|
if (!automapactive)
|
||||||
{
|
{
|
||||||
|
|
@ -625,7 +625,7 @@ static inline void AM_doFollowPlayer(void)
|
||||||
*/
|
*/
|
||||||
void AM_Ticker(void)
|
void AM_Ticker(void)
|
||||||
{
|
{
|
||||||
if (!cv_debug)
|
if (!cht_debug)
|
||||||
AM_Stop();
|
AM_Stop();
|
||||||
|
|
||||||
if (dedicated || !automapactive)
|
if (dedicated || !automapactive)
|
||||||
|
|
|
||||||
|
|
@ -139,12 +139,78 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
|
||||||
|
|
||||||
#undef DEALIGNED
|
#undef DEALIGNED
|
||||||
|
|
||||||
#define WRITESTRINGN(p,s,n) do { size_t tmp_i = 0; for (; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); if (tmp_i < n) WRITECHAR(p, '\0');} while (0)
|
#define WRITESTRINGN(p, s, n) do { \
|
||||||
#define WRITESTRING(p,s) do { size_t tmp_i = 0; for (; s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); WRITECHAR(p, '\0');} while (0)
|
size_t tmp_i; \
|
||||||
#define WRITEMEM(p,s,n) do { memcpy(p, s, n); p += n; } while (0)
|
\
|
||||||
|
for (tmp_i = 0; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) \
|
||||||
|
WRITECHAR(p, s[tmp_i]); \
|
||||||
|
\
|
||||||
|
if (tmp_i < n) \
|
||||||
|
WRITECHAR(p, '\0'); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define SKIPSTRING(p) while (READCHAR(p) != '\0')
|
#define WRITESTRINGL(p, s, n) do { \
|
||||||
|
size_t tmp_i; \
|
||||||
|
\
|
||||||
|
for (tmp_i = 0; tmp_i < n - 1 && s[tmp_i] != '\0'; tmp_i++) \
|
||||||
|
WRITECHAR(p, s[tmp_i]); \
|
||||||
|
\
|
||||||
|
WRITECHAR(p, '\0'); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define READSTRINGN(p,s,n) do { size_t tmp_i = 0; for (; tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';} while (0)
|
#define WRITESTRING(p, s) do { \
|
||||||
#define READSTRING(p,s) do { size_t tmp_i = 0; for (; (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';} while (0)
|
size_t tmp_i; \
|
||||||
#define READMEM(p,s,n) do { memcpy(s, p, n); p += n; } while (0)
|
\
|
||||||
|
for (tmp_i = 0; s[tmp_i] != '\0'; tmp_i++) \
|
||||||
|
WRITECHAR(p, s[tmp_i]); \
|
||||||
|
\
|
||||||
|
WRITECHAR(p, '\0'); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define WRITEMEM(p, s, n) do { \
|
||||||
|
memcpy(p, s, n); \
|
||||||
|
p += n; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SKIPSTRING(p) while (READCHAR(p) != '\0')
|
||||||
|
|
||||||
|
#define SKIPSTRINGN(p, n) do { \
|
||||||
|
size_t tmp_i = 0; \
|
||||||
|
\
|
||||||
|
while (tmp_i < n && READCHAR(p) != '\0') \
|
||||||
|
tmp_i++; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SKIPSTRINGL(p, n) SKIPSTRINGN(p, n)
|
||||||
|
|
||||||
|
#define READSTRINGN(p, s, n) do { \
|
||||||
|
size_t tmp_i = 0; \
|
||||||
|
\
|
||||||
|
while (tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0') \
|
||||||
|
tmp_i++; \
|
||||||
|
\
|
||||||
|
s[tmp_i] = '\0'; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define READSTRINGL(p, s, n) do { \
|
||||||
|
size_t tmp_i = 0; \
|
||||||
|
\
|
||||||
|
while (tmp_i < n - 1 && (s[tmp_i] = READCHAR(p)) != '\0') \
|
||||||
|
tmp_i++; \
|
||||||
|
\
|
||||||
|
s[tmp_i] = '\0'; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define READSTRING(p, s) do { \
|
||||||
|
size_t tmp_i = 0; \
|
||||||
|
\
|
||||||
|
while ((s[tmp_i] = READCHAR(p)) != '\0') \
|
||||||
|
tmp_i++; \
|
||||||
|
\
|
||||||
|
s[tmp_i] = '\0'; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define READMEM(p, s, n) do { \
|
||||||
|
memcpy(s, p, n); \
|
||||||
|
p += n; \
|
||||||
|
} while (0)
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "r_data.h" // Color_cons_t
|
#include "r_data.h" // Color_cons_t
|
||||||
#include "r_skins.h"
|
#include "r_skins.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
|
#include "p_local.h" // P_ResetPlayerCheats
|
||||||
|
|
||||||
//========
|
//========
|
||||||
// protos.
|
// protos.
|
||||||
|
|
@ -1891,7 +1892,6 @@ void CV_CheatsChanged(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
consvar_t *cvar;
|
consvar_t *cvar;
|
||||||
UINT8 i;
|
|
||||||
|
|
||||||
// Set everything back to default.
|
// Set everything back to default.
|
||||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||||
|
|
@ -1899,15 +1899,9 @@ void CV_CheatsChanged(void)
|
||||||
CV_SetCVar(cvar, cvar->defaultvalue, false);
|
CV_SetCVar(cvar, cvar->defaultvalue, false);
|
||||||
|
|
||||||
// Reset any other cheat command effects here, as well.
|
// Reset any other cheat command effects here, as well.
|
||||||
cv_debug = 0;
|
cht_debug = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
P_ResetPlayerCheats();
|
||||||
{
|
|
||||||
if (!playeringame[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
players[i].cheats = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,13 @@ const char *comprevision = SRB2_COMP_REVISION;
|
||||||
#elif (defined(COMPVERSION))
|
#elif (defined(COMPVERSION))
|
||||||
#include "comptime.h"
|
#include "comptime.h"
|
||||||
|
|
||||||
|
const int compuncommitted =
|
||||||
|
#if (defined(COMPVERSION_UNCOMMITTED))
|
||||||
|
1;
|
||||||
|
#else
|
||||||
|
0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
const char *compbranch = "Unknown";
|
const char *compbranch = "Unknown";
|
||||||
const char *comprevision = "illegal";
|
const char *comprevision = "illegal";
|
||||||
|
|
|
||||||
|
|
@ -1521,12 +1521,12 @@ void CONS_Alert(alerttype_t level, const char *fmt, ...)
|
||||||
CONS_Printf("%s", txt);
|
CONS_Printf("%s", txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CONS_Debug(INT32 debugflags, const char *fmt, ...)
|
void CONS_Debug(UINT32 debugflags, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
static char *txt = NULL;
|
static char *txt = NULL;
|
||||||
|
|
||||||
if ((cv_debug & debugflags) != debugflags)
|
if ((cht_debug & debugflags) != debugflags)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (txt == NULL)
|
if (txt == NULL)
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,7 @@ void SendNetXCmdForPlayer(UINT8 playerid, netxcmd_t id, const void *param, size_
|
||||||
{
|
{
|
||||||
if (localtextcmd[playerid][0]+2+nparam > MAXTEXTCMD)
|
if (localtextcmd[playerid][0]+2+nparam > MAXTEXTCMD)
|
||||||
{
|
{
|
||||||
// for future reference: if (cv_debug) != debug disabled.
|
// for future reference: if (cht_debug) != debug disabled.
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("NetXCmd buffer full, cannot add netcmd %d! (size: %d, needed: %s)\n"), id, localtextcmd[playerid][0], sizeu1(nparam));
|
CONS_Alert(CONS_ERROR, M_GetText("NetXCmd buffer full, cannot add netcmd %d! (size: %d, needed: %s)\n"), id, localtextcmd[playerid][0], sizeu1(nparam));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -895,8 +895,15 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||||
netbuffer->packettype = PT_SERVERINFO;
|
netbuffer->packettype = PT_SERVERINFO;
|
||||||
netbuffer->u.serverinfo._255 = 255;
|
netbuffer->u.serverinfo._255 = 255;
|
||||||
netbuffer->u.serverinfo.packetversion = PACKETVERSION;
|
netbuffer->u.serverinfo.packetversion = PACKETVERSION;
|
||||||
|
|
||||||
netbuffer->u.serverinfo.version = VERSION;
|
netbuffer->u.serverinfo.version = VERSION;
|
||||||
netbuffer->u.serverinfo.subversion = SUBVERSION;
|
netbuffer->u.serverinfo.subversion = SUBVERSION;
|
||||||
|
|
||||||
|
#ifdef DEVELOP
|
||||||
|
memcpy(netbuffer->u.serverinfo.commit,
|
||||||
|
comprevision_abbrev_bin, GIT_SHA_ABBREV);
|
||||||
|
#endif
|
||||||
|
|
||||||
strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION,
|
strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION,
|
||||||
sizeof netbuffer->u.serverinfo.application);
|
sizeof netbuffer->u.serverinfo.application);
|
||||||
// return back the time value so client can compute their ping
|
// return back the time value so client can compute their ping
|
||||||
|
|
@ -1681,6 +1688,35 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent)
|
||||||
|
|
||||||
if (client)
|
if (client)
|
||||||
{
|
{
|
||||||
|
#ifdef DEVELOP
|
||||||
|
// Commits do not match? Do not connect!
|
||||||
|
if (memcmp(serverlist[i].info.commit,
|
||||||
|
comprevision_abbrev_bin,
|
||||||
|
GIT_SHA_ABBREV))
|
||||||
|
{
|
||||||
|
char theirs[GIT_SHA_ABBREV * 2 + 1];
|
||||||
|
UINT8 n;
|
||||||
|
|
||||||
|
for (n = 0; n < GIT_SHA_ABBREV; ++n)
|
||||||
|
{
|
||||||
|
sprintf(&theirs[n * 2], "%02hhx",
|
||||||
|
serverlist[i].info.commit[n]);
|
||||||
|
}
|
||||||
|
|
||||||
|
D_QuitNetGame();
|
||||||
|
CL_Reset();
|
||||||
|
D_StartTitle();
|
||||||
|
|
||||||
|
M_StartMessage(va(
|
||||||
|
"Your EXE differs from the server.\n"
|
||||||
|
" Yours: %.*s\n"
|
||||||
|
"Theirs: %s\n\n"
|
||||||
|
"Press ESC\n",
|
||||||
|
GIT_SHA_ABBREV * 2, comprevision, theirs), NULL, MM_NOTHING);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CURL
|
#ifdef HAVE_CURL
|
||||||
if (serverlist[i].info.httpsource[0])
|
if (serverlist[i].info.httpsource[0])
|
||||||
strncpy(http_source, serverlist[i].info.httpsource, MAX_MIRROR_LENGTH);
|
strncpy(http_source, serverlist[i].info.httpsource, MAX_MIRROR_LENGTH);
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,9 @@ typedef struct
|
||||||
char application[MAXAPPLICATION];
|
char application[MAXAPPLICATION];
|
||||||
UINT8 version;
|
UINT8 version;
|
||||||
UINT8 subversion;
|
UINT8 subversion;
|
||||||
|
#ifdef DEVELOP
|
||||||
|
UINT8 commit[GIT_SHA_ABBREV];
|
||||||
|
#endif
|
||||||
UINT8 numberofplayer;
|
UINT8 numberofplayer;
|
||||||
UINT8 maxplayer;
|
UINT8 maxplayer;
|
||||||
UINT8 refusereason; // 0: joinable, 1: joins disabled, 2: full
|
UINT8 refusereason; // 0: joinable, 1: joins disabled, 2: full
|
||||||
|
|
|
||||||
24
src/d_main.c
24
src/d_main.c
|
|
@ -96,6 +96,10 @@
|
||||||
int VERSION;
|
int VERSION;
|
||||||
int SUBVERSION;
|
int SUBVERSION;
|
||||||
|
|
||||||
|
#ifdef DEVELOP
|
||||||
|
UINT8 comprevision_abbrev_bin[GIT_SHA_ABBREV];
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DISCORDRPC
|
#ifdef HAVE_DISCORDRPC
|
||||||
#include "discord.h"
|
#include "discord.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -962,7 +966,7 @@ void D_StartTitle(void)
|
||||||
splitscreen = 0;
|
splitscreen = 0;
|
||||||
SplitScreen_OnChange();
|
SplitScreen_OnChange();
|
||||||
|
|
||||||
cv_debug = 0;
|
cht_debug = 0;
|
||||||
emeralds = 0;
|
emeralds = 0;
|
||||||
memset(&luabanks, 0, sizeof(luabanks));
|
memset(&luabanks, 0, sizeof(luabanks));
|
||||||
lastmaploaded = 0;
|
lastmaploaded = 0;
|
||||||
|
|
@ -1170,6 +1174,20 @@ static void IdentifyVersion(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEVELOP
|
||||||
|
static void
|
||||||
|
D_AbbrevCommit (void)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
for (i = 0; i < GIT_SHA_ABBREV; ++i)
|
||||||
|
{
|
||||||
|
sscanf(&comprevision[i * 2], "%2hhx",
|
||||||
|
&comprevision_abbrev_bin[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
D_ConvertVersionNumbers (void)
|
D_ConvertVersionNumbers (void)
|
||||||
{
|
{
|
||||||
|
|
@ -1194,6 +1212,10 @@ void D_SRB2Main(void)
|
||||||
/* break the version string into version numbers, for netplay */
|
/* break the version string into version numbers, for netplay */
|
||||||
D_ConvertVersionNumbers();
|
D_ConvertVersionNumbers();
|
||||||
|
|
||||||
|
#ifdef DEVELOP
|
||||||
|
D_AbbrevCommit();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Print GPL notice for our console users (Linux)
|
// Print GPL notice for our console users (Linux)
|
||||||
CONS_Printf(
|
CONS_Printf(
|
||||||
"\n\nDr. Robotnik's Ring Racers\n"
|
"\n\nDr. Robotnik's Ring Racers\n"
|
||||||
|
|
|
||||||
338
src/d_netcmd.c
338
src/d_netcmd.c
|
|
@ -96,6 +96,7 @@ static void Got_DiscordInfo(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_ScheduleTaskcmd(UINT8 **cp, INT32 playernum);
|
static void Got_ScheduleTaskcmd(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_ScheduleClearcmd(UINT8 **cp, INT32 playernum);
|
static void Got_ScheduleClearcmd(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_Automatecmd(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 PointLimit_OnChange(void);
|
||||||
static void TimeLimit_OnChange(void);
|
static void TimeLimit_OnChange(void);
|
||||||
|
|
@ -325,8 +326,6 @@ consvar_t cv_splitdevice = CVAR_INIT ("splitdevice", "Off", CV_SAVE, CV_OnOff, N
|
||||||
|
|
||||||
consvar_t cv_skipmapcheck = CVAR_INIT ("skipmapcheck", "Off", CV_SAVE, CV_OnOff, NULL);
|
consvar_t cv_skipmapcheck = CVAR_INIT ("skipmapcheck", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||||
|
|
||||||
INT32 cv_debug;
|
|
||||||
|
|
||||||
consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse);
|
consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse);
|
||||||
|
|
||||||
consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS] = {
|
consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS] = {
|
||||||
|
|
@ -362,7 +361,6 @@ consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SRB2kart
|
// SRB2kart
|
||||||
consvar_t cv_superring = CVAR_INIT ("superring", "On", CV_NETVAR, CV_OnOff, NULL);
|
|
||||||
consvar_t cv_sneaker = CVAR_INIT ("sneaker", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_sneaker = CVAR_INIT ("sneaker", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_rocketsneaker = CVAR_INIT ("rocketsneaker", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_rocketsneaker = CVAR_INIT ("rocketsneaker", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_invincibility = CVAR_INIT ("invincibility", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_invincibility = CVAR_INIT ("invincibility", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
|
@ -372,7 +370,6 @@ consvar_t cv_orbinaut = CVAR_INIT ("orbinaut", "On", CV_NETVAR, CV_OnOff,
|
||||||
consvar_t cv_jawz = CVAR_INIT ("jawz", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_jawz = CVAR_INIT ("jawz", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_mine = CVAR_INIT ("mine", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_mine = CVAR_INIT ("mine", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_landmine = CVAR_INIT ("landmine", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_landmine = CVAR_INIT ("landmine", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_droptarget = CVAR_INIT ("droptarget", "On", CV_NETVAR, CV_OnOff, NULL);
|
|
||||||
consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
|
@ -382,7 +379,10 @@ consvar_t cv_bubbleshield = CVAR_INIT ("bubbleshield", "On", CV_NETVAR, CV_O
|
||||||
consvar_t cv_flameshield = CVAR_INIT ("flameshield", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_flameshield = CVAR_INIT ("flameshield", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_hyudoro = CVAR_INIT ("hyudoro", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_hyudoro = CVAR_INIT ("hyudoro", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_pogospring = CVAR_INIT ("pogospring", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_pogospring = CVAR_INIT ("pogospring", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
consvar_t cv_superring = CVAR_INIT ("superring", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
consvar_t cv_droptarget = CVAR_INIT ("droptarget", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
consvar_t cv_gardentop = CVAR_INIT ("gardentop", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
|
||||||
consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
|
@ -625,7 +625,8 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
||||||
"PLAYSOUND", // XD_PLAYSOUND
|
"PLAYSOUND", // XD_PLAYSOUND
|
||||||
"SCHEDULETASK", // XD_SCHEDULETASK
|
"SCHEDULETASK", // XD_SCHEDULETASK
|
||||||
"SCHEDULECLEAR", // XD_SCHEDULECLEAR
|
"SCHEDULECLEAR", // XD_SCHEDULECLEAR
|
||||||
"AUTOMATE" // XD_AUTOMATE
|
"AUTOMATE", // XD_AUTOMATE
|
||||||
|
"CHEAT", // XD_CHEAT
|
||||||
};
|
};
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
@ -678,6 +679,8 @@ void D_RegisterServerCommands(void)
|
||||||
RegisterNetXCmd(XD_SCHEDULECLEAR, Got_ScheduleClearcmd);
|
RegisterNetXCmd(XD_SCHEDULECLEAR, Got_ScheduleClearcmd);
|
||||||
RegisterNetXCmd(XD_AUTOMATE, Got_Automatecmd);
|
RegisterNetXCmd(XD_AUTOMATE, Got_Automatecmd);
|
||||||
|
|
||||||
|
RegisterNetXCmd(XD_CHEAT, Got_Cheat);
|
||||||
|
|
||||||
// Remote Administration
|
// Remote Administration
|
||||||
COM_AddCommand("password", Command_Changepassword_f);
|
COM_AddCommand("password", Command_Changepassword_f);
|
||||||
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
|
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
|
||||||
|
|
@ -1094,7 +1097,6 @@ void D_RegisterClientCommands(void)
|
||||||
COM_AddCommand("rteleport", Command_RTeleport_f);
|
COM_AddCommand("rteleport", Command_RTeleport_f);
|
||||||
COM_AddCommand("skynum", Command_Skynum_f);
|
COM_AddCommand("skynum", Command_Skynum_f);
|
||||||
COM_AddCommand("weather", Command_Weather_f);
|
COM_AddCommand("weather", Command_Weather_f);
|
||||||
COM_AddCommand("toggletwod", Command_Toggletwod_f);
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
COM_AddCommand("causecfail", Command_CauseCfail_f);
|
COM_AddCommand("causecfail", Command_CauseCfail_f);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1383,7 +1385,7 @@ UINT8 CanChangeSkin(INT32 playernum)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Not in game, so you can change
|
// Not in game, so you can change
|
||||||
if (players[playernum].spectator || players[playernum].playerstate == PST_DEAD || players[playernum].playerstate == PST_REBORN)
|
if (players[playernum].spectator)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Check for freeeplay
|
// Check for freeeplay
|
||||||
|
|
@ -1406,6 +1408,26 @@ UINT8 CanChangeSkin(INT32 playernum)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean CanChangeSkinWhilePlaying(INT32 playernum)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
// Force skin in effect.
|
||||||
|
if ((cv_forceskin.value != -1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; ++i)
|
||||||
|
{
|
||||||
|
if (D_IsPlayerHumanAndGaming(i) &&
|
||||||
|
!P_IsLocalPlayer(&players[i]))
|
||||||
|
{
|
||||||
|
return CanChangeSkin(playernum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void ForceAllSkins(INT32 forcedskin)
|
static void ForceAllSkins(INT32 forcedskin)
|
||||||
{
|
{
|
||||||
INT32 i, j;
|
INT32 i, j;
|
||||||
|
|
@ -1731,40 +1753,65 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendWeaponPref(UINT8 n)
|
enum {
|
||||||
|
WP_KICKSTARTACCEL = 1<<0,
|
||||||
|
WP_SHRINKME = 1<<1,
|
||||||
|
};
|
||||||
|
|
||||||
|
void WeaponPref_Send(UINT8 ssplayer)
|
||||||
{
|
{
|
||||||
UINT8 buf[1];
|
UINT8 prefs = 0;
|
||||||
|
|
||||||
buf[0] = 0;
|
if (cv_kickstartaccel[ssplayer].value)
|
||||||
|
prefs |= WP_KICKSTARTACCEL;
|
||||||
|
|
||||||
if (cv_kickstartaccel[n].value)
|
if (cv_shrinkme[ssplayer].value)
|
||||||
buf[0] |= 1;
|
prefs |= WP_SHRINKME;
|
||||||
|
|
||||||
if (cv_shrinkme[n].value)
|
SendNetXCmdForPlayer(ssplayer, XD_WEAPONPREF, &prefs, 1);
|
||||||
buf[0] |= 2;
|
|
||||||
|
|
||||||
SendNetXCmdForPlayer(n, XD_WEAPONPREF, buf, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Got_WeaponPref(UINT8 **cp,INT32 playernum)
|
void WeaponPref_Save(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
|
player_t *player = &players[playernum];
|
||||||
|
|
||||||
|
UINT8 prefs = 0;
|
||||||
|
|
||||||
|
if (player->pflags & PF_KICKSTARTACCEL)
|
||||||
|
prefs |= WP_KICKSTARTACCEL;
|
||||||
|
|
||||||
|
if (player->pflags & PF_SHRINKME)
|
||||||
|
prefs |= WP_SHRINKME;
|
||||||
|
|
||||||
|
WRITEUINT8(*cp, prefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeaponPref_Parse(UINT8 **cp, INT32 playernum)
|
||||||
|
{
|
||||||
|
player_t *player = &players[playernum];
|
||||||
|
|
||||||
UINT8 prefs = READUINT8(*cp);
|
UINT8 prefs = READUINT8(*cp);
|
||||||
|
|
||||||
players[playernum].pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME);
|
player->pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME);
|
||||||
|
|
||||||
if (prefs & 1)
|
if (prefs & WP_KICKSTARTACCEL)
|
||||||
players[playernum].pflags |= PF_KICKSTARTACCEL;
|
player->pflags |= PF_KICKSTARTACCEL;
|
||||||
|
|
||||||
if (prefs & 2)
|
if (prefs & WP_SHRINKME)
|
||||||
players[playernum].pflags |= PF_SHRINKME;
|
player->pflags |= PF_SHRINKME;
|
||||||
|
|
||||||
if (leveltime < 2)
|
if (leveltime < 2)
|
||||||
{
|
{
|
||||||
// BAD HACK: No other place I tried to slot this in
|
// BAD HACK: No other place I tried to slot this in
|
||||||
// made it work for the host when they initally host,
|
// made it work for the host when they initally host,
|
||||||
// so this will have to do.
|
// so this will have to do.
|
||||||
K_UpdateShrinkCheat(&players[playernum]);
|
K_UpdateShrinkCheat(player);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Got_WeaponPref(UINT8 **cp,INT32 playernum)
|
||||||
|
{
|
||||||
|
WeaponPref_Parse(cp, playernum);
|
||||||
|
|
||||||
// SEE ALSO g_demo.c
|
// SEE ALSO g_demo.c
|
||||||
demo_extradata[playernum] |= DXD_WEAPONPREF;
|
demo_extradata[playernum] |= DXD_WEAPONPREF;
|
||||||
|
|
@ -1952,7 +1999,7 @@ void D_SendPlayerConfig(UINT8 n)
|
||||||
UINT8 *p = buf;
|
UINT8 *p = buf;
|
||||||
|
|
||||||
SendNameAndColor(n);
|
SendNameAndColor(n);
|
||||||
SendWeaponPref(n);
|
WeaponPref_Send(n);
|
||||||
|
|
||||||
if (pr != NULL)
|
if (pr != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -1970,6 +2017,65 @@ void D_SendPlayerConfig(UINT8 n)
|
||||||
SendNetXCmdForPlayer(n, XD_POWERLEVEL, buf, p-buf);
|
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_SAVECHECKPOINT:
|
||||||
|
COPY(WRITEFIXED, fixed_t); // x
|
||||||
|
COPY(WRITEFIXED, fixed_t); // y
|
||||||
|
COPY(WRITEFIXED, fixed_t); // z
|
||||||
|
break;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
case CHEAT_RELATIVE_TELEPORT:
|
||||||
|
COPY(WRITEFIXED, fixed_t);
|
||||||
|
COPY(WRITEFIXED, fixed_t);
|
||||||
|
COPY(WRITEFIXED, fixed_t);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHEAT_DEVMODE:
|
||||||
|
COPY(WRITEUINT32, UINT32);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef COPY
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
SendNetXCmd(XD_CHEAT, buf, p - buf);
|
||||||
|
}
|
||||||
|
|
||||||
// Only works for displayplayer, sorry!
|
// Only works for displayplayer, sorry!
|
||||||
static void Command_ResetCamera_f(void)
|
static void Command_ResetCamera_f(void)
|
||||||
{
|
{
|
||||||
|
|
@ -2805,7 +2911,7 @@ static void Command_Map_f(void)
|
||||||
newresetplayers = false; // if not forcing and gametypes is the same
|
newresetplayers = false; // if not forcing and gametypes is the same
|
||||||
|
|
||||||
// don't use a gametype the map doesn't support
|
// don't use a gametype the map doesn't support
|
||||||
if (cv_debug || option_force || cv_skipmapcheck.value)
|
if (cht_debug || option_force || cv_skipmapcheck.value)
|
||||||
{
|
{
|
||||||
fromlevelselect = false; // The player wants us to trek on anyway. Do so.
|
fromlevelselect = false; // The player wants us to trek on anyway. Do so.
|
||||||
}
|
}
|
||||||
|
|
@ -4711,6 +4817,9 @@ static void Command_Version_f(void)
|
||||||
CONS_Printf("\x87" "DEVELOP " "\x80");
|
CONS_Printf("\x87" "DEVELOP " "\x80");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (compuncommitted)
|
||||||
|
CONS_Printf("\x85" "! UNCOMMITTED CHANGES ! " "\x80");
|
||||||
|
|
||||||
CONS_Printf("\n");
|
CONS_Printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5409,6 +5518,175 @@ 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_SAVECHECKPOINT: {
|
||||||
|
fixed_t x = READFIXED(*cp);
|
||||||
|
fixed_t y = READFIXED(*cp);
|
||||||
|
fixed_t z = READFIXED(*cp);
|
||||||
|
|
||||||
|
player->respawn.pointx = x;
|
||||||
|
player->respawn.pointy = y;
|
||||||
|
player->respawn.pointz = z;
|
||||||
|
player->respawn.manual = true;
|
||||||
|
|
||||||
|
CV_CheaterWarning(targetPlayer, va("temporary checkpoint created at %d, %d, %d",
|
||||||
|
x / FRACUNIT, y / FRACUNIT, z / FRACUNIT));
|
||||||
|
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 CHEAT_RELATIVE_TELEPORT: {
|
||||||
|
fixed_t x = READFIXED(*cp);
|
||||||
|
fixed_t y = READFIXED(*cp);
|
||||||
|
fixed_t z = READFIXED(*cp);
|
||||||
|
|
||||||
|
float f[3] = {
|
||||||
|
FIXED_TO_FLOAT(x),
|
||||||
|
FIXED_TO_FLOAT(y),
|
||||||
|
FIXED_TO_FLOAT(z),
|
||||||
|
};
|
||||||
|
char t[3][9];
|
||||||
|
|
||||||
|
if (!P_MobjWasRemoved(player->mo))
|
||||||
|
{
|
||||||
|
P_MapStart();
|
||||||
|
P_SetOrigin(player->mo,
|
||||||
|
player->mo->x + x,
|
||||||
|
player->mo->y + y,
|
||||||
|
player->mo->z + z);
|
||||||
|
P_MapEnd();
|
||||||
|
|
||||||
|
S_StartSound(player->mo, sfx_mixup);
|
||||||
|
}
|
||||||
|
|
||||||
|
strlcpy(t[0], M_Ftrim(f[0]), sizeof t[0]);
|
||||||
|
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",
|
||||||
|
(int)f[0], t[0], (int)f[1], t[1], (int)f[2], t[2]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CHEAT_DEVMODE: {
|
||||||
|
UINT32 flags = READUINT32(*cp);
|
||||||
|
cht_debug = flags;
|
||||||
|
CV_CheaterWarning(targetPlayer, va("devmode %x", flags));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NUMBER_OF_CHEATS:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Prints the number of displayplayers[0].
|
/** Prints the number of displayplayers[0].
|
||||||
*
|
*
|
||||||
* \todo Possibly remove this; it was useful for debugging at one point.
|
* \todo Possibly remove this; it was useful for debugging at one point.
|
||||||
|
|
@ -5464,7 +5742,7 @@ void Command_ExitGame_f(void)
|
||||||
splitscreen = 0;
|
splitscreen = 0;
|
||||||
SplitScreen_OnChange();
|
SplitScreen_OnChange();
|
||||||
|
|
||||||
cv_debug = 0;
|
cht_debug = 0;
|
||||||
emeralds = 0;
|
emeralds = 0;
|
||||||
memset(&luabanks, 0, sizeof(luabanks));
|
memset(&luabanks, 0, sizeof(luabanks));
|
||||||
|
|
||||||
|
|
@ -6046,7 +6324,7 @@ static void Skin_OnChange(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CanChangeSkin(consoleplayer))
|
if (CanChangeSkinWhilePlaying(consoleplayer))
|
||||||
SendNameAndColor(0);
|
SendNameAndColor(0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -6065,7 +6343,7 @@ static void Skin2_OnChange(void)
|
||||||
if (!Playing() || !splitscreen)
|
if (!Playing() || !splitscreen)
|
||||||
return; // do whatever you want
|
return; // do whatever you want
|
||||||
|
|
||||||
if (CanChangeSkin(g_localplayers[1]))
|
if (CanChangeSkinWhilePlaying(g_localplayers[1]))
|
||||||
SendNameAndColor(1);
|
SendNameAndColor(1);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -6079,7 +6357,7 @@ static void Skin3_OnChange(void)
|
||||||
if (!Playing() || splitscreen < 2)
|
if (!Playing() || splitscreen < 2)
|
||||||
return; // do whatever you want
|
return; // do whatever you want
|
||||||
|
|
||||||
if (CanChangeSkin(g_localplayers[2]))
|
if (CanChangeSkinWhilePlaying(g_localplayers[2]))
|
||||||
SendNameAndColor(2);
|
SendNameAndColor(2);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -6093,7 +6371,7 @@ static void Skin4_OnChange(void)
|
||||||
if (!Playing() || splitscreen < 3)
|
if (!Playing() || splitscreen < 3)
|
||||||
return; // do whatever you want
|
return; // do whatever you want
|
||||||
|
|
||||||
if (CanChangeSkin(g_localplayers[3]))
|
if (CanChangeSkinWhilePlaying(g_localplayers[3]))
|
||||||
SendNameAndColor(3);
|
SendNameAndColor(3);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -72,14 +72,38 @@ extern consvar_t cv_pause;
|
||||||
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_maxplayers, cv_respawntime;
|
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_maxplayers, cv_respawntime;
|
||||||
|
|
||||||
// SRB2kart items
|
// SRB2kart items
|
||||||
extern consvar_t cv_superring, cv_sneaker, cv_rocketsneaker, cv_invincibility, cv_banana;
|
extern consvar_t
|
||||||
extern consvar_t cv_eggmanmonitor, cv_orbinaut, cv_jawz, cv_mine, cv_landmine, cv_droptarget;
|
cv_sneaker,
|
||||||
extern consvar_t cv_ballhog, cv_selfpropelledbomb, cv_grow, cv_shrink;
|
cv_rocketsneaker,
|
||||||
extern consvar_t cv_lightningshield, cv_bubbleshield, cv_flameshield;
|
cv_invincibility,
|
||||||
extern consvar_t cv_hyudoro, cv_pogospring, cv_kitchensink;
|
cv_banana,
|
||||||
|
cv_eggmanmonitor,
|
||||||
|
cv_orbinaut,
|
||||||
|
cv_jawz,
|
||||||
|
cv_mine,
|
||||||
|
cv_landmine,
|
||||||
|
cv_ballhog,
|
||||||
|
cv_selfpropelledbomb,
|
||||||
|
cv_grow,
|
||||||
|
cv_shrink,
|
||||||
|
cv_lightningshield,
|
||||||
|
cv_bubbleshield,
|
||||||
|
cv_flameshield,
|
||||||
|
cv_hyudoro,
|
||||||
|
cv_pogospring,
|
||||||
|
cv_superring,
|
||||||
|
cv_kitchensink,
|
||||||
|
cv_droptarget,
|
||||||
|
cv_gardentop;
|
||||||
|
|
||||||
extern consvar_t cv_dualsneaker, cv_triplesneaker, cv_triplebanana, cv_decabanana;
|
extern consvar_t
|
||||||
extern consvar_t cv_tripleorbinaut, cv_quadorbinaut, cv_dualjawz;
|
cv_dualsneaker,
|
||||||
|
cv_triplesneaker,
|
||||||
|
cv_triplebanana,
|
||||||
|
cv_decabanana,
|
||||||
|
cv_tripleorbinaut,
|
||||||
|
cv_quadorbinaut,
|
||||||
|
cv_dualjawz;
|
||||||
|
|
||||||
extern consvar_t cv_kartminimap;
|
extern consvar_t cv_kartminimap;
|
||||||
extern consvar_t cv_kartcheck;
|
extern consvar_t cv_kartcheck;
|
||||||
|
|
@ -179,6 +203,7 @@ typedef enum
|
||||||
XD_SCHEDULETASK, // 36
|
XD_SCHEDULETASK, // 36
|
||||||
XD_SCHEDULECLEAR, // 37
|
XD_SCHEDULECLEAR, // 37
|
||||||
XD_AUTOMATE, // 38
|
XD_AUTOMATE, // 38
|
||||||
|
XD_CHEAT, // 39
|
||||||
|
|
||||||
MAXNETXCMD
|
MAXNETXCMD
|
||||||
} netxcmd_t;
|
} netxcmd_t;
|
||||||
|
|
@ -230,7 +255,9 @@ void D_RegisterServerCommands(void);
|
||||||
void D_RegisterClientCommands(void);
|
void D_RegisterClientCommands(void);
|
||||||
void CleanupPlayerName(INT32 playernum, const char *newname);
|
void CleanupPlayerName(INT32 playernum, const char *newname);
|
||||||
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum);
|
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum);
|
||||||
void SendWeaponPref(UINT8 n);
|
void WeaponPref_Send(UINT8 ssplayer);
|
||||||
|
void WeaponPref_Save(UINT8 **cp, INT32 playernum);
|
||||||
|
void WeaponPref_Parse(UINT8 **cp, INT32 playernum);
|
||||||
void D_SendPlayerConfig(UINT8 n);
|
void D_SendPlayerConfig(UINT8 n);
|
||||||
void Command_ExitGame_f(void);
|
void Command_ExitGame_f(void);
|
||||||
void Command_Retry_f(void);
|
void Command_Retry_f(void);
|
||||||
|
|
@ -278,7 +305,10 @@ void Automate_Clear(void);
|
||||||
extern UINT32 livestudioaudience_timer;
|
extern UINT32 livestudioaudience_timer;
|
||||||
void LiveStudioAudience(void);
|
void LiveStudioAudience(void);
|
||||||
|
|
||||||
|
void D_Cheat(INT32 playernum, INT32 cheat, ...);
|
||||||
|
|
||||||
// used for the player setup menu
|
// used for the player setup menu
|
||||||
UINT8 CanChangeSkin(INT32 playernum);
|
UINT8 CanChangeSkin(INT32 playernum);
|
||||||
|
boolean CanChangeSkinWhilePlaying(INT32 playernum);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -58,14 +58,15 @@ typedef enum
|
||||||
//
|
//
|
||||||
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
|
// Look back VFX has been spawned
|
||||||
// TODO: Is there a better way to track this?
|
// TODO: Is there a better way to track this?
|
||||||
PF_GAINAX = 1<<3,
|
PF_GAINAX = 1<<3,
|
||||||
|
|
||||||
// Accessibility and cheats
|
PF_KICKSTARTACCEL = 1<<4, // Accessibility feature: Is accelerate in kickstart mode?
|
||||||
PF_KICKSTARTACCEL = 1<<4, // Is accelerate in kickstart mode?
|
|
||||||
// 1<<5 free
|
// 1<<5 free
|
||||||
// 1<<6 free
|
// 1<<6 free
|
||||||
|
|
||||||
|
|
@ -105,13 +106,6 @@ typedef enum
|
||||||
// up to 1<<31 is free
|
// up to 1<<31 is free
|
||||||
} pflags_t;
|
} pflags_t;
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
PC_GODMODE = 1,
|
|
||||||
PC_NOCLIP = 1<<1,
|
|
||||||
// up to 1<<31 is free
|
|
||||||
} pcheats_t;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
// Are animation frames playing?
|
// Are animation frames playing?
|
||||||
|
|
@ -159,7 +153,8 @@ Run this macro, then #undef FOREACH afterward
|
||||||
FOREACH (POGOSPRING, 18),\
|
FOREACH (POGOSPRING, 18),\
|
||||||
FOREACH (SUPERRING, 19),\
|
FOREACH (SUPERRING, 19),\
|
||||||
FOREACH (KITCHENSINK, 20),\
|
FOREACH (KITCHENSINK, 20),\
|
||||||
FOREACH (DROPTARGET, 21)
|
FOREACH (DROPTARGET, 21),\
|
||||||
|
FOREACH (GARDENTOP, 22)
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
@ -187,6 +182,7 @@ typedef enum
|
||||||
KSHIELD_LIGHTNING = 1,
|
KSHIELD_LIGHTNING = 1,
|
||||||
KSHIELD_BUBBLE = 2,
|
KSHIELD_BUBBLE = 2,
|
||||||
KSHIELD_FLAME = 3,
|
KSHIELD_FLAME = 3,
|
||||||
|
KSHIELD_TOP = 4,
|
||||||
NUMKARTSHIELDS
|
NUMKARTSHIELDS
|
||||||
} kartshields_t;
|
} kartshields_t;
|
||||||
|
|
||||||
|
|
@ -288,6 +284,8 @@ typedef enum
|
||||||
#define ITEMSCALE_GROW 1
|
#define ITEMSCALE_GROW 1
|
||||||
#define ITEMSCALE_SHRINK 2
|
#define ITEMSCALE_SHRINK 2
|
||||||
|
|
||||||
|
#define GARDENTOP_MAXGRINDTIME (45)
|
||||||
|
|
||||||
// player_t struct for all respawn variables
|
// player_t struct for all respawn variables
|
||||||
typedef struct respawnvars_s
|
typedef struct respawnvars_s
|
||||||
{
|
{
|
||||||
|
|
@ -302,6 +300,7 @@ typedef struct respawnvars_s
|
||||||
UINT32 distanceleft; // How far along the course to respawn you
|
UINT32 distanceleft; // How far along the course to respawn you
|
||||||
tic_t dropdash; // Drop Dash charge timer
|
tic_t dropdash; // Drop Dash charge timer
|
||||||
boolean truedeath; // Your soul has left your body
|
boolean truedeath; // Your soul has left your body
|
||||||
|
boolean manual; // Respawn coords were manually set, please respawn exactly there
|
||||||
} respawnvars_t;
|
} respawnvars_t;
|
||||||
|
|
||||||
// player_t struct for all bot variables
|
// player_t struct for all bot variables
|
||||||
|
|
@ -372,7 +371,6 @@ typedef struct player_s
|
||||||
// Bit flags.
|
// Bit flags.
|
||||||
// See pflags_t, above.
|
// See pflags_t, above.
|
||||||
pflags_t pflags;
|
pflags_t pflags;
|
||||||
pcheats_t cheats;
|
|
||||||
|
|
||||||
// playing animation.
|
// playing animation.
|
||||||
panim_t panim;
|
panim_t panim;
|
||||||
|
|
@ -446,7 +444,6 @@ typedef struct player_s
|
||||||
INT32 underwatertilt;
|
INT32 underwatertilt;
|
||||||
|
|
||||||
fixed_t offroad; // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed
|
fixed_t offroad; // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed
|
||||||
UINT8 waterskip; // Water skipping counter
|
|
||||||
|
|
||||||
UINT16 tiregrease; // Reduced friction timer after hitting a spring
|
UINT16 tiregrease; // Reduced friction timer after hitting a spring
|
||||||
UINT16 springstars; // Spawn stars around a player when they hit a spring
|
UINT16 springstars; // Spawn stars around a player when they hit a spring
|
||||||
|
|
@ -599,6 +596,8 @@ typedef struct player_s
|
||||||
UINT8 kickstartaccel;
|
UINT8 kickstartaccel;
|
||||||
|
|
||||||
UINT8 stairjank;
|
UINT8 stairjank;
|
||||||
|
UINT8 topdriftheld;
|
||||||
|
UINT8 topinfirst;
|
||||||
|
|
||||||
UINT8 shrinkLaserDelay;
|
UINT8 shrinkLaserDelay;
|
||||||
|
|
||||||
|
|
@ -609,7 +608,4 @@ typedef struct player_s
|
||||||
#endif
|
#endif
|
||||||
} player_t;
|
} player_t;
|
||||||
|
|
||||||
// Value for infinite lives
|
|
||||||
#define INFLIVES 0x7F
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3740,6 +3740,14 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
||||||
"S_FLAMESHIELDLINE3",
|
"S_FLAMESHIELDLINE3",
|
||||||
"S_FLAMESHIELDFLASH",
|
"S_FLAMESHIELDFLASH",
|
||||||
|
|
||||||
|
// Marble Garden Zone Spinning Top
|
||||||
|
"S_GARDENTOP_FLOATING",
|
||||||
|
"S_GARDENTOP_SINKING1",
|
||||||
|
"S_GARDENTOP_SINKING2",
|
||||||
|
"S_GARDENTOP_SINKING3",
|
||||||
|
"S_GARDENTOP_DEAD",
|
||||||
|
"S_GARDENTOPSPARK",
|
||||||
|
|
||||||
// Caked-Up Booty-Sheet Ghost
|
// Caked-Up Booty-Sheet Ghost
|
||||||
"S_HYUDORO",
|
"S_HYUDORO",
|
||||||
|
|
||||||
|
|
@ -5346,6 +5354,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
||||||
"MT_FLAMESHIELDUNDERLAY",
|
"MT_FLAMESHIELDUNDERLAY",
|
||||||
"MT_FLAMESHIELDPAPER",
|
"MT_FLAMESHIELDPAPER",
|
||||||
"MT_BUBBLESHIELDTRAP",
|
"MT_BUBBLESHIELDTRAP",
|
||||||
|
"MT_GARDENTOP",
|
||||||
|
"MT_GARDENTOPSPARK",
|
||||||
|
|
||||||
"MT_HYUDORO",
|
"MT_HYUDORO",
|
||||||
"MT_HYUDORO_CENTER",
|
"MT_HYUDORO_CENTER",
|
||||||
|
|
@ -5651,7 +5661,7 @@ const char *const MOBJFLAG_LIST[] = {
|
||||||
// \tMF2_(\S+).*// (.+) --> \t"\1", // \2
|
// \tMF2_(\S+).*// (.+) --> \t"\1", // \2
|
||||||
const char *const MOBJFLAG2_LIST[] = {
|
const char *const MOBJFLAG2_LIST[] = {
|
||||||
"AXIS", // It's a NiGHTS axis! (For faster checking)
|
"AXIS", // It's a NiGHTS axis! (For faster checking)
|
||||||
"TWOD", // Moves like it's in a 2D level
|
"\x01", // free: 1<<1 (name un-matchable)
|
||||||
"DONTRESPAWN", // Don't respawn this object!
|
"DONTRESPAWN", // Don't respawn this object!
|
||||||
"\x01", // free: 1<<3 (name un-matchable)
|
"\x01", // free: 1<<3 (name un-matchable)
|
||||||
"AUTOMATIC", // Thrown ring has automatic properties
|
"AUTOMATIC", // Thrown ring has automatic properties
|
||||||
|
|
@ -5710,8 +5720,9 @@ const char *const MAPTHINGFLAG_LIST[4] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *const PLAYERFLAG_LIST[] = {
|
const char *const PLAYERFLAG_LIST[] = {
|
||||||
// free: 1<<0 to 1<<2 (name un-matchable)
|
"GODMODE",
|
||||||
"\x01",
|
|
||||||
|
// free: 1<<1 and 1<<2 (name un-matchable)
|
||||||
"\x01",
|
"\x01",
|
||||||
"\x01",
|
"\x01",
|
||||||
|
|
||||||
|
|
@ -6348,9 +6359,6 @@ struct int_const_s const INT_CONST[] = {
|
||||||
{"PA_DRIFT",PA_DRIFT},
|
{"PA_DRIFT",PA_DRIFT},
|
||||||
{"PA_HURT",PA_HURT},
|
{"PA_HURT",PA_HURT},
|
||||||
|
|
||||||
// Value for infinite lives
|
|
||||||
{"INFLIVES",INFLIVES},
|
|
||||||
|
|
||||||
// Got Flags, for player->gotflag!
|
// Got Flags, for player->gotflag!
|
||||||
// Used to be MF_ for some stupid reason, now they're GF_ to stop them looking like mobjflags
|
// Used to be MF_ for some stupid reason, now they're GF_ to stop them looking like mobjflags
|
||||||
{"GF_REDFLAG",GF_REDFLAG},
|
{"GF_REDFLAG",GF_REDFLAG},
|
||||||
|
|
@ -6670,6 +6678,7 @@ struct int_const_s const INT_CONST[] = {
|
||||||
{"KSHIELD_LIGHTNING",KSHIELD_LIGHTNING},
|
{"KSHIELD_LIGHTNING",KSHIELD_LIGHTNING},
|
||||||
{"KSHIELD_BUBBLE",KSHIELD_BUBBLE},
|
{"KSHIELD_BUBBLE",KSHIELD_BUBBLE},
|
||||||
{"KSHIELD_FLAME",KSHIELD_FLAME},
|
{"KSHIELD_FLAME",KSHIELD_FLAME},
|
||||||
|
{"KSHIELD_TOP",KSHIELD_TOP},
|
||||||
{"NUMKARTSHIELDS",NUMKARTSHIELDS},
|
{"NUMKARTSHIELDS",NUMKARTSHIELDS},
|
||||||
|
|
||||||
// kartspinoutflags_t
|
// kartspinoutflags_t
|
||||||
|
|
|
||||||
|
|
@ -480,7 +480,7 @@ typedef enum
|
||||||
|
|
||||||
void CONS_Printf(const char *fmt, ...) FUNCPRINTF;
|
void CONS_Printf(const char *fmt, ...) FUNCPRINTF;
|
||||||
void CONS_Alert(alerttype_t level, const char *fmt, ...) FUNCDEBUG;
|
void CONS_Alert(alerttype_t level, const char *fmt, ...) FUNCDEBUG;
|
||||||
void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG;
|
void CONS_Debug(UINT32 debugflags, const char *fmt, ...) FUNCDEBUG;
|
||||||
|
|
||||||
// For help debugging functions.
|
// For help debugging functions.
|
||||||
#define POTENTIALLYUNUSED CONS_Alert(CONS_WARNING, "(%s:%d) Unused code appears to be used.\n", __FILE__, __LINE__)
|
#define POTENTIALLYUNUSED CONS_Alert(CONS_WARNING, "(%s:%d) Unused code appears to be used.\n", __FILE__, __LINE__)
|
||||||
|
|
@ -516,24 +516,47 @@ char *sizeu5(size_t num);
|
||||||
// d_main.c
|
// d_main.c
|
||||||
extern int VERSION;
|
extern int VERSION;
|
||||||
extern int SUBVERSION;
|
extern int SUBVERSION;
|
||||||
extern boolean devparm; // development mode (-debug)
|
|
||||||
// d_netcmd.c
|
|
||||||
extern INT32 cv_debug;
|
|
||||||
|
|
||||||
#define DBG_BASIC 0x0001
|
#ifdef DEVELOP
|
||||||
#define DBG_DETAILED 0x0002
|
// 4 bytes handles 8 characters of a git object SHA. At
|
||||||
#define DBG_PLAYER 0x0004
|
// around 20k commits, we only need 6 characters for a unique
|
||||||
#define DBG_RENDER 0x0008
|
// abbreviation. Maybe in another 20k commits, more than 8
|
||||||
#define DBG_NIGHTSBASIC 0x0010
|
// characters will be required! =P
|
||||||
#define DBG_NIGHTS 0x0020
|
// P.S. 8 is also what comptime generates
|
||||||
#define DBG_POLYOBJ 0x0040
|
#define GIT_SHA_ABBREV (4)
|
||||||
#define DBG_GAMELOGIC 0x0080
|
extern UINT8 comprevision_abbrev_bin[GIT_SHA_ABBREV];
|
||||||
#define DBG_NETPLAY 0x0100
|
#endif
|
||||||
#define DBG_MEMORY 0x0200
|
|
||||||
#define DBG_SETUP 0x0400
|
extern boolean devparm; // development mode (-debug)
|
||||||
#define DBG_LUA 0x0800
|
|
||||||
#define DBG_RANDOMIZER 0x1000
|
// m_cheat.c
|
||||||
#define DBG_VIEWMORPH 0x2000
|
extern UINT32 cht_debug;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DBG_NONE = 0x00000000,
|
||||||
|
DBG_BASIC = 0x00000001,
|
||||||
|
DBG_DETAILED = 0x00000002,
|
||||||
|
DBG_PLAYER = 0x00000004,
|
||||||
|
DBG_RENDER = 0x00000008,
|
||||||
|
//DBG_NIGHTSBASIC = 0x00000010, // free
|
||||||
|
//DBG_NIGHTS = 0x00000020, // free
|
||||||
|
DBG_POLYOBJ = 0x00000040,
|
||||||
|
DBG_GAMELOGIC = 0x00000080,
|
||||||
|
DBG_NETPLAY = 0x00000100,
|
||||||
|
DBG_MEMORY = 0x00000200,
|
||||||
|
DBG_SETUP = 0x00000400,
|
||||||
|
DBG_LUA = 0x00000800,
|
||||||
|
DBG_RNG = 0x00001000,
|
||||||
|
} debugFlags_t;
|
||||||
|
|
||||||
|
struct debugFlagNames_s
|
||||||
|
{
|
||||||
|
const char *str;
|
||||||
|
debugFlags_t flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct debugFlagNames_s const debug_flag_names[];
|
||||||
|
|
||||||
// =======================
|
// =======================
|
||||||
// Misc stuff for later...
|
// Misc stuff for later...
|
||||||
|
|
@ -613,6 +636,7 @@ UINT32 quickncasehash (const char *p, size_t n)
|
||||||
|
|
||||||
// Compile date and time and revision.
|
// Compile date and time and revision.
|
||||||
extern const char *compdate, *comptime, *comprevision, *compbranch;
|
extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||||
|
extern int compuncommitted;
|
||||||
|
|
||||||
// Disabled code and code under testing
|
// Disabled code and code under testing
|
||||||
// None of these that are disabled in the normal build are guaranteed to work perfectly
|
// None of these that are disabled in the normal build are guaranteed to work perfectly
|
||||||
|
|
@ -691,10 +715,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||||
#undef UPDATE_ALERT
|
#undef UPDATE_ALERT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// - SRB2Kart options -
|
|
||||||
/// Camera always has noclip.
|
|
||||||
#define NOCLIPCAM
|
|
||||||
|
|
||||||
/// Other karma comeback modes
|
/// Other karma comeback modes
|
||||||
//#define OTHERKARMAMODES
|
//#define OTHERKARMAMODES
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -866,7 +866,7 @@ boolean F_CreditResponder(event_t *event)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (!(timesBeaten) && !(netgame || multiplayer) && !cv_debug)
|
/*if (!(timesBeaten) && !(netgame || multiplayer) && !cht_debug)
|
||||||
return false;*/
|
return false;*/
|
||||||
|
|
||||||
if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_BACKSPACE)
|
if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_BACKSPACE)
|
||||||
|
|
@ -2006,6 +2006,8 @@ void F_TitleScreenDrawer(void)
|
||||||
#else // Regular build
|
#else // Regular build
|
||||||
addtext(V_ALLOWLOWERCASE|V_TRANSLUCENT, va("%s", VERSIONSTRING));
|
addtext(V_ALLOWLOWERCASE|V_TRANSLUCENT, va("%s", VERSIONSTRING));
|
||||||
#endif
|
#endif
|
||||||
|
if (compuncommitted)
|
||||||
|
addtext(V_REDMAP|V_STRINGDANCE, "! UNCOMMITTED CHANGES !");
|
||||||
}
|
}
|
||||||
#undef addtext
|
#undef addtext
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
src/g_demo.c
22
src/g_demo.c
|
|
@ -364,20 +364,7 @@ void G_ReadDemoExtraData(void)
|
||||||
}
|
}
|
||||||
if (extradata & DXD_WEAPONPREF)
|
if (extradata & DXD_WEAPONPREF)
|
||||||
{
|
{
|
||||||
i = READUINT8(demo_p);
|
WeaponPref_Parse(&demo_p, p);
|
||||||
players[p].pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME);
|
|
||||||
if (i & 1)
|
|
||||||
players[p].pflags |= PF_KICKSTARTACCEL;
|
|
||||||
if (i & 2)
|
|
||||||
players[p].pflags |= PF_SHRINKME;
|
|
||||||
|
|
||||||
if (leveltime < 2)
|
|
||||||
{
|
|
||||||
// BAD HACK: No other place I tried to slot this in
|
|
||||||
// made it work for the host when they initally host,
|
|
||||||
// so this will have to do.
|
|
||||||
K_UpdateShrinkCheat(&players[p]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//CONS_Printf("weaponpref is %d for player %d\n", i, p);
|
//CONS_Printf("weaponpref is %d for player %d\n", i, p);
|
||||||
}
|
}
|
||||||
|
|
@ -492,12 +479,7 @@ void G_WriteDemoExtraData(void)
|
||||||
}
|
}
|
||||||
if (demo_extradata[i] & DXD_WEAPONPREF)
|
if (demo_extradata[i] & DXD_WEAPONPREF)
|
||||||
{
|
{
|
||||||
UINT8 prefs = 0;
|
WeaponPref_Save(&demo_p, i);
|
||||||
if (players[i].pflags & PF_KICKSTARTACCEL)
|
|
||||||
prefs |= 1;
|
|
||||||
if (players[i].pflags & PF_SHRINKME)
|
|
||||||
prefs |= 2;
|
|
||||||
WRITEUINT8(demo_p, prefs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
22
src/g_game.c
22
src/g_game.c
|
|
@ -1304,22 +1304,22 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n)
|
||||||
|
|
||||||
static void weaponPrefChange(void)
|
static void weaponPrefChange(void)
|
||||||
{
|
{
|
||||||
SendWeaponPref(0);
|
WeaponPref_Send(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void weaponPrefChange2(void)
|
static void weaponPrefChange2(void)
|
||||||
{
|
{
|
||||||
SendWeaponPref(1);
|
WeaponPref_Send(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void weaponPrefChange3(void)
|
static void weaponPrefChange3(void)
|
||||||
{
|
{
|
||||||
SendWeaponPref(2);
|
WeaponPref_Send(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void weaponPrefChange4(void)
|
static void weaponPrefChange4(void)
|
||||||
{
|
{
|
||||||
SendWeaponPref(3);
|
WeaponPref_Send(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -2219,7 +2219,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
UINT32 followitem;
|
UINT32 followitem;
|
||||||
|
|
||||||
INT32 pflags;
|
INT32 pflags;
|
||||||
INT32 cheats;
|
|
||||||
|
|
||||||
UINT8 ctfteam;
|
UINT8 ctfteam;
|
||||||
|
|
||||||
|
|
@ -2299,7 +2298,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
botrival = players[player].botvars.rival;
|
botrival = players[player].botvars.rival;
|
||||||
|
|
||||||
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE));
|
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE));
|
||||||
cheats = 0;
|
|
||||||
|
|
||||||
// SRB2kart
|
// SRB2kart
|
||||||
if (betweenmaps || leveltime < introtime)
|
if (betweenmaps || leveltime < introtime)
|
||||||
|
|
@ -2374,10 +2372,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
pflags |= (players[player].pflags & (PF_STASIS|PF_ELIMINATED|PF_NOCONTEST|PF_FAULT|PF_LOSTLIFE));
|
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)
|
if (!betweenmaps)
|
||||||
{
|
{
|
||||||
// Obliterate follower from existence (if valid memory)
|
// Obliterate follower from existence (if valid memory)
|
||||||
|
|
@ -2393,7 +2387,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
p->roundscore = roundscore;
|
p->roundscore = roundscore;
|
||||||
p->lives = lives;
|
p->lives = lives;
|
||||||
p->pflags = pflags;
|
p->pflags = pflags;
|
||||||
p->cheats = cheats;
|
|
||||||
p->ctfteam = ctfteam;
|
p->ctfteam = ctfteam;
|
||||||
p->jointime = jointime;
|
p->jointime = jointime;
|
||||||
p->splitscreenindex = splitscreenindex;
|
p->splitscreenindex = splitscreenindex;
|
||||||
|
|
@ -4597,7 +4590,7 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
|
||||||
|
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
|
|
||||||
if (cv_debug && saved)
|
if (cht_debug && saved)
|
||||||
CONS_Printf(M_GetText("Game saved.\n"));
|
CONS_Printf(M_GetText("Game saved.\n"));
|
||||||
else if (!saved)
|
else if (!saved)
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename));
|
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename));
|
||||||
|
|
@ -4699,7 +4692,7 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (cv_debug && saved)
|
if (cht_debug && saved)
|
||||||
CONS_Printf(M_GetText("Game saved.\n"));
|
CONS_Printf(M_GetText("Game saved.\n"));
|
||||||
else if (!saved)
|
else if (!saved)
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename));
|
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename));
|
||||||
|
|
@ -4784,9 +4777,6 @@ void G_InitNew(UINT8 pencoremode, INT32 map, boolean resetplayer, boolean skippr
|
||||||
players[i].playerstate = PST_REBORN;
|
players[i].playerstate = PST_REBORN;
|
||||||
memset(&players[i].respawn, 0, sizeof (players[i].respawn));
|
memset(&players[i].respawn, 0, sizeof (players[i].respawn));
|
||||||
|
|
||||||
// Clear cheatcodes too, just in case.
|
|
||||||
players[i].cheats = 0;
|
|
||||||
|
|
||||||
players[i].roundscore = 0;
|
players[i].roundscore = 0;
|
||||||
|
|
||||||
if (resetplayer && !(multiplayer && demo.playback)) // SRB2Kart
|
if (resetplayer && !(multiplayer && demo.playback)) // SRB2Kart
|
||||||
|
|
|
||||||
352
src/hu_stuff.c
352
src/hu_stuff.c
|
|
@ -85,9 +85,9 @@ patch_t *framecounter;
|
||||||
patch_t *frameslash; // framerate stuff. Used in screen.c
|
patch_t *frameslash; // framerate stuff. Used in screen.c
|
||||||
|
|
||||||
static player_t *plr;
|
static player_t *plr;
|
||||||
boolean chat_on; // entering a chat message?
|
|
||||||
boolean hu_keystrokes; // :)
|
boolean hu_keystrokes; // :)
|
||||||
static char w_chat[HU_MAXMSGLEN];
|
boolean chat_on; // entering a chat message?
|
||||||
|
static char w_chat[HU_MAXMSGLEN + 1];
|
||||||
static size_t c_input = 0; // let's try to make the chat input less shitty.
|
static size_t c_input = 0; // let's try to make the chat input less shitty.
|
||||||
static boolean headsupactive = false;
|
static boolean headsupactive = false;
|
||||||
boolean hu_showscores; // draw rankings
|
boolean hu_showscores; // draw rankings
|
||||||
|
|
@ -487,7 +487,7 @@ void HU_AddChatText(const char *text, boolean playsound)
|
||||||
|
|
||||||
static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
|
static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
|
||||||
{
|
{
|
||||||
char buf[254];
|
char buf[2 + HU_MAXMSGLEN + 1];
|
||||||
size_t numwords, ix;
|
size_t numwords, ix;
|
||||||
char *msg = &buf[2];
|
char *msg = &buf[2];
|
||||||
const size_t msgspace = sizeof buf - 2;
|
const size_t msgspace = sizeof buf - 2;
|
||||||
|
|
@ -567,7 +567,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
|
||||||
}
|
}
|
||||||
buf[0] = target;
|
buf[0] = target;
|
||||||
newmsg = msg+5+spc;
|
newmsg = msg+5+spc;
|
||||||
strlcpy(msg, newmsg, 252);
|
strlcpy(msg, newmsg, HU_MAXMSGLEN + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf);
|
SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf);
|
||||||
|
|
@ -697,7 +697,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||||
target = READSINT8(*p);
|
target = READSINT8(*p);
|
||||||
flags = READUINT8(*p);
|
flags = READUINT8(*p);
|
||||||
msg = (char *)*p;
|
msg = (char *)*p;
|
||||||
SKIPSTRING(*p);
|
SKIPSTRINGL(*p, HU_MAXMSGLEN + 1);
|
||||||
|
|
||||||
if ((cv_mute.value || flags & (HU_CSAY|HU_SHOUT)) && playernum != serverplayer && !(IsPlayerAdmin(playernum)))
|
if ((cv_mute.value || flags & (HU_CSAY|HU_SHOUT)) && playernum != serverplayer && !(IsPlayerAdmin(playernum)))
|
||||||
{
|
{
|
||||||
|
|
@ -916,71 +916,6 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles key input and string input
|
|
||||||
//
|
|
||||||
static inline boolean HU_keyInChatString(char *s, char ch)
|
|
||||||
{
|
|
||||||
size_t l;
|
|
||||||
|
|
||||||
if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && fontv[HU_FONT].font[ch-HU_FONTSTART])
|
|
||||||
|| ch == ' ') // Allow spaces, of course
|
|
||||||
{
|
|
||||||
l = strlen(s);
|
|
||||||
if (l < HU_MAXMSGLEN - 1)
|
|
||||||
{
|
|
||||||
if (c_input >= strlen(s)) // don't do anything complicated
|
|
||||||
{
|
|
||||||
s[l++] = ch;
|
|
||||||
s[l]=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// move everything past c_input for new characters:
|
|
||||||
size_t m = HU_MAXMSGLEN-1;
|
|
||||||
while (m>=c_input)
|
|
||||||
{
|
|
||||||
if (s[m])
|
|
||||||
s[m+1] = (s[m]);
|
|
||||||
if (m == 0) // prevent overflow
|
|
||||||
break;
|
|
||||||
m--;
|
|
||||||
}
|
|
||||||
s[c_input] = ch; // and replace this.
|
|
||||||
}
|
|
||||||
c_input++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (ch == KEY_BACKSPACE)
|
|
||||||
{
|
|
||||||
size_t i = c_input;
|
|
||||||
|
|
||||||
if (c_input <= 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!s[i-1])
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (i >= strlen(s)-1)
|
|
||||||
{
|
|
||||||
s[strlen(s)-1] = 0;
|
|
||||||
c_input--;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; (i < HU_MAXMSGLEN); i++)
|
|
||||||
{
|
|
||||||
s[i-1] = s[i];
|
|
||||||
}
|
|
||||||
c_input--;
|
|
||||||
}
|
|
||||||
else if (ch != KEY_ENTER)
|
|
||||||
return false; // did not eat key
|
|
||||||
|
|
||||||
return true; // ate the key
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
static void HU_TickSongCredits(void)
|
static void HU_TickSongCredits(void)
|
||||||
|
|
@ -1096,154 +1031,125 @@ void HU_Ticker(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean teamtalk = false;
|
static boolean teamtalk = false;
|
||||||
|
static boolean justscrolleddown;
|
||||||
|
static boolean justscrolledup;
|
||||||
|
static INT16 typelines = 1; // number of drawfill lines we need when drawing the chat. it's some weird hack and might be one frame off but I'm lazy to make another loop.
|
||||||
|
// It's up here since it has to be reset when we open the chat.
|
||||||
|
|
||||||
// Clear spaces so we don't end up with messages only made out of emptiness
|
static boolean HU_chatboxContainsOnlySpaces(void)
|
||||||
static boolean HU_clearChatSpaces(void)
|
|
||||||
{
|
{
|
||||||
size_t i = 0; // Used to just check our message
|
size_t i;
|
||||||
char c; // current character we're iterating.
|
|
||||||
boolean nothingbutspaces = true;
|
|
||||||
|
|
||||||
for (; i < strlen(w_chat); i++) // iterate through message and eradicate all spaces that don't belong.
|
for (i = 0; w_chat[i]; i++)
|
||||||
{
|
if (w_chat[i] != ' ')
|
||||||
c = w_chat[i];
|
return false;
|
||||||
if (!c)
|
|
||||||
break; // if there's nothing, it's safe to assume our message has ended, so let's not waste any more time here.
|
|
||||||
|
|
||||||
if (c != ' ') // Isn't a space
|
return true;
|
||||||
{
|
|
||||||
nothingbutspaces = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nothingbutspaces;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
static void HU_sendChatMessage(void)
|
||||||
//
|
|
||||||
static void HU_queueChatChar(INT32 c)
|
|
||||||
{
|
{
|
||||||
// send automaticly the message (no more chat char)
|
char buf[2 + HU_MAXMSGLEN + 1];
|
||||||
if (c == KEY_ENTER)
|
char *msg = &buf[2];
|
||||||
|
size_t ci;
|
||||||
|
INT32 target = 0;
|
||||||
|
|
||||||
|
// if our message was nothing but spaces, don't send it.
|
||||||
|
if (HU_chatboxContainsOnlySpaces())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// copy printable characters and terminating '\0' only.
|
||||||
|
for (ci = 2; w_chat[ci-2]; ci++)
|
||||||
{
|
{
|
||||||
char buf[2+256];
|
char c = w_chat[ci-2];
|
||||||
char *msg = &buf[2];
|
if (c >= ' ' && !(c & 0x80))
|
||||||
size_t i;
|
buf[ci] = c;
|
||||||
size_t ci = 2;
|
};
|
||||||
INT32 target = 0;
|
buf[ci] = '\0';
|
||||||
|
|
||||||
if (HU_clearChatSpaces()) // Avoids being able to send empty messages, or something.
|
memset(w_chat, '\0', sizeof(w_chat));
|
||||||
return; // If this returns true, that means our message was NOTHING but spaces, so don't send it period.
|
c_input = 0;
|
||||||
|
|
||||||
do {
|
// last minute mute check
|
||||||
c = w_chat[-2+ci++];
|
if (CHAT_MUTE)
|
||||||
if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only.
|
{
|
||||||
buf[ci-1]=c;
|
HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false);
|
||||||
} while (c);
|
return;
|
||||||
i = 0;
|
}
|
||||||
for (;(i<HU_MAXMSGLEN);i++)
|
|
||||||
w_chat[i] = 0; // reset this.
|
|
||||||
|
|
||||||
c_input = 0;
|
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
|
||||||
|
{
|
||||||
|
INT32 spc = 1; // used if playernum[1] is a space.
|
||||||
|
char playernum[3];
|
||||||
|
const char *newmsg;
|
||||||
|
|
||||||
for (;(i<HU_MAXMSGLEN);i++)
|
// what we're gonna do now is check if the player exists
|
||||||
w_chat[i] = 0; // reset this.
|
// with that logic, characters 4 and 5 are our numbers:
|
||||||
|
|
||||||
c_input = 0;
|
// teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko.
|
||||||
|
if (teamtalk)
|
||||||
// last minute mute check
|
|
||||||
if (CHAT_MUTE)
|
|
||||||
{
|
{
|
||||||
HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false);
|
HU_AddChatText(va("%sCannot send sayto in Say-Team.", "\x85"), false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
|
strncpy(playernum, msg+3, 3);
|
||||||
|
// check for undesirable characters in our "number"
|
||||||
|
if (!(isdigit(playernum[0]) && isdigit(playernum[1])))
|
||||||
{
|
{
|
||||||
INT32 spc = 1; // used if playernum[1] is a space.
|
// check if playernum[1] is a space
|
||||||
char playernum[3];
|
if (playernum[1] == ' ')
|
||||||
const char *newmsg;
|
spc = 0;
|
||||||
|
// let it slide
|
||||||
// what we're gonna do now is check if the player exists
|
|
||||||
// with that logic, characters 4 and 5 are our numbers:
|
|
||||||
|
|
||||||
// teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko.
|
|
||||||
if (teamtalk)
|
|
||||||
{
|
|
||||||
HU_AddChatText(va("%sCannot send sayto in Say-Team.", "\x85"), false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(playernum, msg+3, 3);
|
|
||||||
|
|
||||||
// check for undesirable characters in our "number"
|
|
||||||
if (((playernum[0] < '0') || (playernum[0] > '9')) || ((playernum[1] < '0') || (playernum[1] > '9')))
|
|
||||||
{
|
|
||||||
// check if playernum[1] is a space
|
|
||||||
if (playernum[1] == ' ')
|
|
||||||
spc = 0;
|
|
||||||
// let it slide
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<player num> \'.", false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// I'm very bad at C, I swear I am, additional checks eww!
|
|
||||||
if (spc != 0)
|
|
||||||
{
|
|
||||||
if (msg[5] != ' ')
|
|
||||||
{
|
|
||||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<player num> \'.", false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
target = atoi(playernum); // turn that into a number
|
|
||||||
//CONS_Printf("%d\n", target);
|
|
||||||
|
|
||||||
// check for target player, if it doesn't exist then we can't send the message!
|
|
||||||
if (target < MAXPLAYERS && playeringame[target]) // player exists
|
|
||||||
target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work!
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same
|
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<player num> \'.", false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to get rid of the /pm<player num>
|
|
||||||
newmsg = msg+5+spc;
|
|
||||||
strlcpy(msg, newmsg, 255);
|
|
||||||
}
|
}
|
||||||
if (ci > 3) // don't send target+flags+empty message.
|
// I'm very bad at C, I swear I am, additional checks eww!
|
||||||
|
if (spc != 0 && msg[5] != ' ')
|
||||||
{
|
{
|
||||||
if (teamtalk)
|
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<player num> \'.", false);
|
||||||
buf[0] = -1; // target
|
return;
|
||||||
else
|
|
||||||
buf[0] = target;
|
|
||||||
|
|
||||||
buf[1] = ((server || IsPlayerAdmin(consoleplayer)) && cv_autoshout.value) ? HU_SHOUT : 0; // flags
|
|
||||||
SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1);
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
target = atoi(playernum); // turn that into a number
|
||||||
|
|
||||||
|
// check for target player, if it doesn't exist then we can't send the message!
|
||||||
|
if (target < MAXPLAYERS && playeringame[target]) // player exists
|
||||||
|
target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work!
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need to get rid of the /pm<player num>
|
||||||
|
newmsg = msg+5+spc;
|
||||||
|
strlcpy(msg, newmsg, HU_MAXMSGLEN + 1);
|
||||||
|
}
|
||||||
|
if (ci > 2) // don't send target+flags+empty message.
|
||||||
|
{
|
||||||
|
if (teamtalk)
|
||||||
|
buf[0] = -1; // target
|
||||||
|
else
|
||||||
|
buf[0] = target;
|
||||||
|
|
||||||
|
buf[1] = ((server || IsPlayerAdmin(consoleplayer)) && cv_autoshout.value) ? HU_SHOUT : 0; // flags
|
||||||
|
SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HU_clearChatChars(void)
|
void HU_clearChatChars(void)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
memset(w_chat, '\0', sizeof(w_chat));
|
||||||
for (;i<HU_MAXMSGLEN;i++)
|
|
||||||
w_chat[i] = 0; // reset this.
|
|
||||||
chat_on = false;
|
chat_on = false;
|
||||||
c_input = 0;
|
c_input = 0;
|
||||||
|
|
||||||
I_UpdateMouseGrab();
|
I_UpdateMouseGrab();
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean justscrolleddown;
|
|
||||||
static boolean justscrolledup;
|
|
||||||
static INT16 typelines = 1; // number of drawfill lines we need when drawing the chat. it's some weird hack and might be one frame off but I'm lazy to make another loop.
|
|
||||||
// It's up here since it has to be reset when we open the chat.
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Returns true if key eaten
|
// Returns true if key eaten
|
||||||
//
|
//
|
||||||
|
|
@ -1327,14 +1233,16 @@ boolean HU_Responder(event_t *ev)
|
||||||
c = CON_ShiftChar(c);
|
c = CON_ShiftChar(c);
|
||||||
|
|
||||||
// pasting. pasting is cool. chat is a bit limited, though :(
|
// pasting. pasting is cool. chat is a bit limited, though :(
|
||||||
if (((c == 'v' || c == 'V') && ctrldown) && !CHAT_MUTE)
|
if ((c == 'v' || c == 'V') && ctrldown)
|
||||||
{
|
{
|
||||||
const char *paste = I_ClipboardPaste();
|
const char *paste;
|
||||||
size_t chatlen;
|
size_t chatlen;
|
||||||
size_t pastelen;
|
size_t pastelen;
|
||||||
|
|
||||||
// create a dummy string real quickly
|
if (CHAT_MUTE)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
paste = I_ClipboardPaste();
|
||||||
if (paste == NULL)
|
if (paste == NULL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -1343,40 +1251,16 @@ boolean HU_Responder(event_t *ev)
|
||||||
if (chatlen+pastelen > HU_MAXMSGLEN)
|
if (chatlen+pastelen > HU_MAXMSGLEN)
|
||||||
return true; // we can't paste this!!
|
return true; // we can't paste this!!
|
||||||
|
|
||||||
if (c_input >= strlen(w_chat)) // add it at the end of the string.
|
memmove(&w_chat[c_input + pastelen], &w_chat[c_input], pastelen);
|
||||||
{
|
memcpy(&w_chat[c_input], paste, pastelen); // copy all of that.
|
||||||
memcpy(&w_chat[chatlen], paste, pastelen); // copy all of that.
|
c_input += pastelen;
|
||||||
c_input += pastelen;
|
return true;
|
||||||
/*size_t i = 0;
|
|
||||||
for (;i<pastelen;i++)
|
|
||||||
{
|
|
||||||
HU_queueChatChar(paste[i]); // queue it so that it's actually sent. (this chat write thing is REALLY messy.)
|
|
||||||
}*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else // otherwise, we need to shift everything and make space, etc etc
|
|
||||||
{
|
|
||||||
size_t i = HU_MAXMSGLEN-1;
|
|
||||||
while (i >= c_input)
|
|
||||||
{
|
|
||||||
if (w_chat[i])
|
|
||||||
w_chat[i+pastelen] = w_chat[i];
|
|
||||||
if (i == 0) // prevent overflow
|
|
||||||
break;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
memcpy(&w_chat[c_input], paste, pastelen); // copy all of that.
|
|
||||||
c_input += pastelen;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (c == KEY_ENTER)
|
||||||
|
{
|
||||||
|
if (!CHAT_MUTE)
|
||||||
|
HU_sendChatMessage();
|
||||||
|
|
||||||
if (!CHAT_MUTE && HU_keyInChatString(w_chat,c))
|
|
||||||
{
|
|
||||||
HU_queueChatChar(c);
|
|
||||||
}
|
|
||||||
if (c == KEY_ENTER)
|
|
||||||
{
|
|
||||||
chat_on = false;
|
chat_on = false;
|
||||||
c_input = 0; // reset input cursor
|
c_input = 0; // reset input cursor
|
||||||
chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
|
chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
|
||||||
|
|
@ -1417,6 +1301,32 @@ boolean HU_Responder(event_t *ev)
|
||||||
else
|
else
|
||||||
c_input++;
|
c_input++;
|
||||||
}
|
}
|
||||||
|
else if ((c >= HU_FONTSTART && c <= HU_FONTEND && fontv[HU_FONT].font[c-HU_FONTSTART])
|
||||||
|
|| c == ' ') // Allow spaces, of course
|
||||||
|
{
|
||||||
|
if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1);
|
||||||
|
w_chat[c_input] = c;
|
||||||
|
c_input++;
|
||||||
|
}
|
||||||
|
else if (c == KEY_BACKSPACE)
|
||||||
|
{
|
||||||
|
if (CHAT_MUTE || c_input <= 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
memmove(&w_chat[c_input - 1], &w_chat[c_input], strlen(w_chat) - c_input + 1);
|
||||||
|
c_input--;
|
||||||
|
}
|
||||||
|
else if (c == KEY_DEL)
|
||||||
|
{
|
||||||
|
if (CHAT_MUTE || c_input >= strlen(w_chat))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
memmove(&w_chat[c_input], &w_chat[c_input + 1], strlen(w_chat) - c_input);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1962,8 +1872,8 @@ static void HU_DrawChat_Old(void)
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
|
const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
|
||||||
const char *talk = ntalk;
|
const char *talk = ntalk;
|
||||||
INT32 charwidth = 8 * con_scalefactor; //(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor;
|
INT32 charwidth = 8 * con_scalefactor; //(fontv[HU_FONT].font['A'-HU_FONTSTART]->width) * con_scalefactor;
|
||||||
INT32 charheight = 8 * con_scalefactor; //(hu_font['A'-HU_FONTSTART]->height) * con_scalefactor;
|
INT32 charheight = 8 * con_scalefactor; //(fontv[HU_FONT].font['A'-HU_FONTSTART]->height) * con_scalefactor;
|
||||||
if (teamtalk)
|
if (teamtalk)
|
||||||
{
|
{
|
||||||
talk = ttalk;
|
talk = ttalk;
|
||||||
|
|
@ -1984,7 +1894,7 @@ static void HU_DrawChat_Old(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//charwidth = (hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor;
|
//charwidth = (fontv[HU_FONT].font[talk[i]-HU_FONTSTART]->width) * con_scalefactor;
|
||||||
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, true);
|
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, true);
|
||||||
}
|
}
|
||||||
c += charwidth;
|
c += charwidth;
|
||||||
|
|
@ -2012,7 +1922,7 @@ static void HU_DrawChat_Old(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//charwidth = (hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
|
//charwidth = (fontv[HU_FONT].font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
|
||||||
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, true);
|
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,8 @@ typedef struct
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
// chat stuff
|
// chat stuff
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
#define HU_MAXMSGLEN 224
|
#define HU_MAXMSGLEN 223
|
||||||
#define CHAT_BUFSIZE 64 // that's enough messages, right? We'll delete the older ones when that gets out of hand.
|
#define CHAT_BUFSIZE 64 // that's enough messages, right? We'll delete the older ones when that gets out of hand.
|
||||||
#define NETSPLITSCREEN // why the hell WOULDN'T we want this?
|
#define NETSPLITSCREEN // why the hell WOULDN'T we want this?
|
||||||
#ifdef NETSPLITSCREEN
|
#ifdef NETSPLITSCREEN
|
||||||
#define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640)
|
#define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640)
|
||||||
|
|
|
||||||
61
src/info.c
61
src/info.c
|
|
@ -4320,6 +4320,13 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_FLML, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE|14, 7, {NULL}, 6, 1, S_NULL}, // S_FLAMESHIELDLINE3
|
{SPR_FLML, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE|14, 7, {NULL}, 6, 1, S_NULL}, // S_FLAMESHIELDLINE3
|
||||||
{SPR_FLMF, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDFLASH
|
{SPR_FLMF, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDFLASH
|
||||||
|
|
||||||
|
{SPR_GTOP, FF_ANIMATE, -1, {NULL}, 5, 1, S_NULL}, // S_GARDENTOP_FLOATING
|
||||||
|
{SPR_GTOP, 0, 1, {NULL}, 5, 1, S_GARDENTOP_SINKING2}, // S_GARDENTOP_SINKING1
|
||||||
|
{SPR_GTOP, 2, 1, {NULL}, 5, 1, S_GARDENTOP_SINKING3}, // S_GARDENTOP_SINKING2
|
||||||
|
{SPR_GTOP, 4, 1, {NULL}, 5, 1, S_GARDENTOP_SINKING1}, // S_GARDENTOP_SINKING3
|
||||||
|
{SPR_GTOP, FF_ANIMATE, 100, {A_Scream}, 5, 1, S_NULL}, // S_GARDENTOP_DEAD
|
||||||
|
{SPR_BDRF, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 5, 2, S_NULL}, // S_GARDENTOPSPARK
|
||||||
|
|
||||||
{SPR_HYUU, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_HYUDORO
|
{SPR_HYUU, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_HYUDORO
|
||||||
|
|
||||||
{SPR_GRWP, FF_FULLBRIGHT|FF_ANIMATE, 13, {NULL}, 7, 1, S_NULL}, // S_GROW_PARTICLE
|
{SPR_GRWP, FF_FULLBRIGHT|FF_ANIMATE, 13, {NULL}, 7, 1, S_NULL}, // S_GROW_PARTICLE
|
||||||
|
|
@ -24065,6 +24072,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_GARDENTOP
|
||||||
|
-1, // doomednum
|
||||||
|
S_GARDENTOP_FLOATING, // spawnstate
|
||||||
|
8, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
4, // reactiontime
|
||||||
|
sfx_s3k8b, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_GARDENTOP_DEAD, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_s3k7a, // deathsound
|
||||||
|
40*FRACUNIT, // speed
|
||||||
|
30*FRACUNIT, // radius
|
||||||
|
68*FRACUNIT, // height
|
||||||
|
-1, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOCLIPTHING|MF_DONTENCOREMAP, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_GARDENTOPSPARK
|
||||||
|
-1, // doomednum
|
||||||
|
S_GARDENTOPSPARK, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
8, // speed
|
||||||
|
8*FRACUNIT, // radius
|
||||||
|
8*FRACUNIT, // height
|
||||||
|
1, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP|MF_NOSQUISH, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_HYUDORO
|
{ // MT_HYUDORO
|
||||||
-1, // doomednum
|
-1, // doomednum
|
||||||
S_HYUDORO, // spawnstate
|
S_HYUDORO, // spawnstate
|
||||||
|
|
|
||||||
10
src/info.h
10
src/info.h
|
|
@ -4750,6 +4750,14 @@ typedef enum state
|
||||||
S_FLAMESHIELDLINE3,
|
S_FLAMESHIELDLINE3,
|
||||||
S_FLAMESHIELDFLASH,
|
S_FLAMESHIELDFLASH,
|
||||||
|
|
||||||
|
// Marble Garden Zone Spinning Top
|
||||||
|
S_GARDENTOP_FLOATING,
|
||||||
|
S_GARDENTOP_SINKING1,
|
||||||
|
S_GARDENTOP_SINKING2,
|
||||||
|
S_GARDENTOP_SINKING3,
|
||||||
|
S_GARDENTOP_DEAD,
|
||||||
|
S_GARDENTOPSPARK,
|
||||||
|
|
||||||
// Caked-Up Booty-Sheet Ghost
|
// Caked-Up Booty-Sheet Ghost
|
||||||
S_HYUDORO,
|
S_HYUDORO,
|
||||||
|
|
||||||
|
|
@ -6392,6 +6400,8 @@ typedef enum mobj_type
|
||||||
MT_FLAMESHIELDUNDERLAY,
|
MT_FLAMESHIELDUNDERLAY,
|
||||||
MT_FLAMESHIELDPAPER,
|
MT_FLAMESHIELDPAPER,
|
||||||
MT_BUBBLESHIELDTRAP,
|
MT_BUBBLESHIELDTRAP,
|
||||||
|
MT_GARDENTOP,
|
||||||
|
MT_GARDENTOPSPARK,
|
||||||
|
|
||||||
MT_HYUDORO,
|
MT_HYUDORO,
|
||||||
MT_HYUDORO_CENTER,
|
MT_HYUDORO_CENTER,
|
||||||
|
|
|
||||||
|
|
@ -66,17 +66,22 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
||||||
if (t1->type == MT_BANANA && t1->health > 1)
|
if (t1->type == MT_BANANA && t1->health > 1)
|
||||||
S_StartSound(t2, sfx_bsnipe);
|
S_StartSound(t2, sfx_bsnipe);
|
||||||
|
|
||||||
|
damageitem = true;
|
||||||
|
|
||||||
if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD)
|
if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD)
|
||||||
{
|
{
|
||||||
// Melt item
|
// Melt item
|
||||||
S_StartSound(t2, sfx_s3k43);
|
S_StartSound(t2, sfx_s3k43);
|
||||||
}
|
}
|
||||||
|
else if (K_IsRidingFloatingTop(t2->player))
|
||||||
|
{
|
||||||
|
// Float over silly banana
|
||||||
|
damageitem = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL|DMG_WOMBO);
|
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL|DMG_WOMBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
damageitem = true;
|
|
||||||
}
|
}
|
||||||
else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD
|
else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD
|
||||||
|| t2->type == MT_ORBINAUT || t2->type == MT_ORBINAUT_SHIELD
|
|| t2->type == MT_ORBINAUT || t2->type == MT_ORBINAUT_SHIELD
|
||||||
|
|
@ -774,11 +779,13 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
||||||
// Clash instead of damage if both parties have any of these conditions
|
// Clash instead of damage if both parties have any of these conditions
|
||||||
t1Condition = (K_IsBigger(t1, t2) == true)
|
t1Condition = (K_IsBigger(t1, t2) == true)
|
||||||
|| (t1->player->invincibilitytimer > 0)
|
|| (t1->player->invincibilitytimer > 0)
|
||||||
|| (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD);
|
|| (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD)
|
||||||
|
|| (t1->player->curshield == KSHIELD_TOP && !K_IsHoldingDownTop(t1->player));
|
||||||
|
|
||||||
t2Condition = (K_IsBigger(t2, t1) == true)
|
t2Condition = (K_IsBigger(t2, t1) == true)
|
||||||
|| (t2->player->invincibilitytimer > 0)
|
|| (t2->player->invincibilitytimer > 0)
|
||||||
|| (t2->player->flamedash > 0 && t2->player->itemtype == KITEM_FLAMESHIELD);
|
|| (t2->player->flamedash > 0 && t2->player->itemtype == KITEM_FLAMESHIELD)
|
||||||
|
|| (t2->player->curshield == KSHIELD_TOP && !K_IsHoldingDownTop(t2->player));
|
||||||
|
|
||||||
if (t1Condition == true && t2Condition == true)
|
if (t1Condition == true && t2Condition == true)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
29
src/k_hud.c
29
src/k_hud.c
|
|
@ -111,7 +111,7 @@ static patch_t *kp_itemtimer[2];
|
||||||
static patch_t *kp_itemmulsticker[2];
|
static patch_t *kp_itemmulsticker[2];
|
||||||
static patch_t *kp_itemx;
|
static patch_t *kp_itemx;
|
||||||
|
|
||||||
static patch_t *kp_superring[2];
|
static patch_t *kp_sadface[2];
|
||||||
static patch_t *kp_sneaker[2];
|
static patch_t *kp_sneaker[2];
|
||||||
static patch_t *kp_rocketsneaker[2];
|
static patch_t *kp_rocketsneaker[2];
|
||||||
static patch_t *kp_invincibility[13];
|
static patch_t *kp_invincibility[13];
|
||||||
|
|
@ -121,7 +121,6 @@ static patch_t *kp_orbinaut[5];
|
||||||
static patch_t *kp_jawz[2];
|
static patch_t *kp_jawz[2];
|
||||||
static patch_t *kp_mine[2];
|
static patch_t *kp_mine[2];
|
||||||
static patch_t *kp_landmine[2];
|
static patch_t *kp_landmine[2];
|
||||||
static patch_t *kp_droptarget[2];
|
|
||||||
static patch_t *kp_ballhog[2];
|
static patch_t *kp_ballhog[2];
|
||||||
static patch_t *kp_selfpropelledbomb[2];
|
static patch_t *kp_selfpropelledbomb[2];
|
||||||
static patch_t *kp_grow[2];
|
static patch_t *kp_grow[2];
|
||||||
|
|
@ -131,8 +130,10 @@ static patch_t *kp_bubbleshield[2];
|
||||||
static patch_t *kp_flameshield[2];
|
static patch_t *kp_flameshield[2];
|
||||||
static patch_t *kp_hyudoro[2];
|
static patch_t *kp_hyudoro[2];
|
||||||
static patch_t *kp_pogospring[2];
|
static patch_t *kp_pogospring[2];
|
||||||
|
static patch_t *kp_superring[2];
|
||||||
static patch_t *kp_kitchensink[2];
|
static patch_t *kp_kitchensink[2];
|
||||||
static patch_t *kp_sadface[2];
|
static patch_t *kp_droptarget[2];
|
||||||
|
static patch_t *kp_gardentop[2];
|
||||||
|
|
||||||
static patch_t *kp_check[6];
|
static patch_t *kp_check[6];
|
||||||
|
|
||||||
|
|
@ -390,7 +391,7 @@ void K_LoadKartHUDGraphics(void)
|
||||||
HU_UpdatePatch(&kp_itemmulsticker[0], "K_ITMUL");
|
HU_UpdatePatch(&kp_itemmulsticker[0], "K_ITMUL");
|
||||||
HU_UpdatePatch(&kp_itemx, "K_ITX");
|
HU_UpdatePatch(&kp_itemx, "K_ITX");
|
||||||
|
|
||||||
HU_UpdatePatch(&kp_superring[0], "K_ITRING");
|
HU_UpdatePatch(&kp_sadface[0], "K_ITSAD");
|
||||||
HU_UpdatePatch(&kp_sneaker[0], "K_ITSHOE");
|
HU_UpdatePatch(&kp_sneaker[0], "K_ITSHOE");
|
||||||
HU_UpdatePatch(&kp_rocketsneaker[0], "K_ITRSHE");
|
HU_UpdatePatch(&kp_rocketsneaker[0], "K_ITRSHE");
|
||||||
|
|
||||||
|
|
@ -411,7 +412,6 @@ void K_LoadKartHUDGraphics(void)
|
||||||
HU_UpdatePatch(&kp_jawz[0], "K_ITJAWZ");
|
HU_UpdatePatch(&kp_jawz[0], "K_ITJAWZ");
|
||||||
HU_UpdatePatch(&kp_mine[0], "K_ITMINE");
|
HU_UpdatePatch(&kp_mine[0], "K_ITMINE");
|
||||||
HU_UpdatePatch(&kp_landmine[0], "K_ITLNDM");
|
HU_UpdatePatch(&kp_landmine[0], "K_ITLNDM");
|
||||||
HU_UpdatePatch(&kp_droptarget[0], "K_ITDTRG");
|
|
||||||
HU_UpdatePatch(&kp_ballhog[0], "K_ITBHOG");
|
HU_UpdatePatch(&kp_ballhog[0], "K_ITBHOG");
|
||||||
HU_UpdatePatch(&kp_selfpropelledbomb[0], "K_ITSPB");
|
HU_UpdatePatch(&kp_selfpropelledbomb[0], "K_ITSPB");
|
||||||
HU_UpdatePatch(&kp_grow[0], "K_ITGROW");
|
HU_UpdatePatch(&kp_grow[0], "K_ITGROW");
|
||||||
|
|
@ -421,8 +421,10 @@ void K_LoadKartHUDGraphics(void)
|
||||||
HU_UpdatePatch(&kp_flameshield[0], "K_ITFLMS");
|
HU_UpdatePatch(&kp_flameshield[0], "K_ITFLMS");
|
||||||
HU_UpdatePatch(&kp_hyudoro[0], "K_ITHYUD");
|
HU_UpdatePatch(&kp_hyudoro[0], "K_ITHYUD");
|
||||||
HU_UpdatePatch(&kp_pogospring[0], "K_ITPOGO");
|
HU_UpdatePatch(&kp_pogospring[0], "K_ITPOGO");
|
||||||
|
HU_UpdatePatch(&kp_superring[0], "K_ITRING");
|
||||||
HU_UpdatePatch(&kp_kitchensink[0], "K_ITSINK");
|
HU_UpdatePatch(&kp_kitchensink[0], "K_ITSINK");
|
||||||
HU_UpdatePatch(&kp_sadface[0], "K_ITSAD");
|
HU_UpdatePatch(&kp_droptarget[0], "K_ITDTRG");
|
||||||
|
HU_UpdatePatch(&kp_gardentop[0], "K_ITGTOP");
|
||||||
|
|
||||||
sprintf(buffer, "FSMFGxxx");
|
sprintf(buffer, "FSMFGxxx");
|
||||||
for (i = 0; i < 104; i++)
|
for (i = 0; i < 104; i++)
|
||||||
|
|
@ -447,7 +449,7 @@ void K_LoadKartHUDGraphics(void)
|
||||||
HU_UpdatePatch(&kp_itemtimer[1], "K_ISIMER");
|
HU_UpdatePatch(&kp_itemtimer[1], "K_ISIMER");
|
||||||
HU_UpdatePatch(&kp_itemmulsticker[1], "K_ISMUL");
|
HU_UpdatePatch(&kp_itemmulsticker[1], "K_ISMUL");
|
||||||
|
|
||||||
HU_UpdatePatch(&kp_superring[1], "K_ISRING");
|
HU_UpdatePatch(&kp_sadface[1], "K_ISSAD");
|
||||||
HU_UpdatePatch(&kp_sneaker[1], "K_ISSHOE");
|
HU_UpdatePatch(&kp_sneaker[1], "K_ISSHOE");
|
||||||
HU_UpdatePatch(&kp_rocketsneaker[1], "K_ISRSHE");
|
HU_UpdatePatch(&kp_rocketsneaker[1], "K_ISRSHE");
|
||||||
sprintf(buffer, "K_ISINVx");
|
sprintf(buffer, "K_ISINVx");
|
||||||
|
|
@ -462,7 +464,6 @@ void K_LoadKartHUDGraphics(void)
|
||||||
HU_UpdatePatch(&kp_jawz[1], "K_ISJAWZ");
|
HU_UpdatePatch(&kp_jawz[1], "K_ISJAWZ");
|
||||||
HU_UpdatePatch(&kp_mine[1], "K_ISMINE");
|
HU_UpdatePatch(&kp_mine[1], "K_ISMINE");
|
||||||
HU_UpdatePatch(&kp_landmine[1], "K_ISLNDM");
|
HU_UpdatePatch(&kp_landmine[1], "K_ISLNDM");
|
||||||
HU_UpdatePatch(&kp_droptarget[1], "K_ISDTRG");
|
|
||||||
HU_UpdatePatch(&kp_ballhog[1], "K_ISBHOG");
|
HU_UpdatePatch(&kp_ballhog[1], "K_ISBHOG");
|
||||||
HU_UpdatePatch(&kp_selfpropelledbomb[1], "K_ISSPB");
|
HU_UpdatePatch(&kp_selfpropelledbomb[1], "K_ISSPB");
|
||||||
HU_UpdatePatch(&kp_grow[1], "K_ISGROW");
|
HU_UpdatePatch(&kp_grow[1], "K_ISGROW");
|
||||||
|
|
@ -472,8 +473,10 @@ void K_LoadKartHUDGraphics(void)
|
||||||
HU_UpdatePatch(&kp_flameshield[1], "K_ISFLMS");
|
HU_UpdatePatch(&kp_flameshield[1], "K_ISFLMS");
|
||||||
HU_UpdatePatch(&kp_hyudoro[1], "K_ISHYUD");
|
HU_UpdatePatch(&kp_hyudoro[1], "K_ISHYUD");
|
||||||
HU_UpdatePatch(&kp_pogospring[1], "K_ISPOGO");
|
HU_UpdatePatch(&kp_pogospring[1], "K_ISPOGO");
|
||||||
|
HU_UpdatePatch(&kp_superring[1], "K_ISRING");
|
||||||
HU_UpdatePatch(&kp_kitchensink[1], "K_ISSINK");
|
HU_UpdatePatch(&kp_kitchensink[1], "K_ISSINK");
|
||||||
HU_UpdatePatch(&kp_sadface[1], "K_ISSAD");
|
HU_UpdatePatch(&kp_droptarget[1], "K_ISDTRG");
|
||||||
|
HU_UpdatePatch(&kp_gardentop[1], "K_ISGTOP");
|
||||||
|
|
||||||
sprintf(buffer, "FSMFSxxx");
|
sprintf(buffer, "FSMFSxxx");
|
||||||
for (i = 0; i < 104; i++)
|
for (i = 0; i < 104; i++)
|
||||||
|
|
@ -662,8 +665,6 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny)
|
||||||
return (tiny ? "K_ISMINE" : "K_ITMINE");
|
return (tiny ? "K_ISMINE" : "K_ITMINE");
|
||||||
case KITEM_LANDMINE:
|
case KITEM_LANDMINE:
|
||||||
return (tiny ? "K_ISLNDM" : "K_ITLNDM");
|
return (tiny ? "K_ISLNDM" : "K_ITLNDM");
|
||||||
case KITEM_DROPTARGET:
|
|
||||||
return (tiny ? "K_ISDTRG" : "K_ITDTRG");
|
|
||||||
case KITEM_BALLHOG:
|
case KITEM_BALLHOG:
|
||||||
return (tiny ? "K_ISBHOG" : "K_ITBHOG");
|
return (tiny ? "K_ISBHOG" : "K_ITBHOG");
|
||||||
case KITEM_SPB:
|
case KITEM_SPB:
|
||||||
|
|
@ -686,6 +687,10 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny)
|
||||||
return (tiny ? "K_ISRING" : "K_ITRING");
|
return (tiny ? "K_ISRING" : "K_ITRING");
|
||||||
case KITEM_KITCHENSINK:
|
case KITEM_KITCHENSINK:
|
||||||
return (tiny ? "K_ISSINK" : "K_ITSINK");
|
return (tiny ? "K_ISSINK" : "K_ITSINK");
|
||||||
|
case KITEM_DROPTARGET:
|
||||||
|
return (tiny ? "K_ISDTRG" : "K_ITDTRG");
|
||||||
|
case KITEM_GARDENTOP:
|
||||||
|
return (tiny ? "K_ISGTOP" : "K_ITGTOP");
|
||||||
case KRITEM_TRIPLEORBINAUT:
|
case KRITEM_TRIPLEORBINAUT:
|
||||||
return (tiny ? "K_ISORBN" : "K_ITORB3");
|
return (tiny ? "K_ISORBN" : "K_ITORB3");
|
||||||
case KRITEM_QUADORBINAUT:
|
case KRITEM_QUADORBINAUT:
|
||||||
|
|
@ -721,6 +726,7 @@ static patch_t *K_GetCachedItemPatch(INT32 item, UINT8 offset)
|
||||||
kp_superring,
|
kp_superring,
|
||||||
kp_kitchensink,
|
kp_kitchensink,
|
||||||
kp_droptarget,
|
kp_droptarget,
|
||||||
|
kp_gardentop,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (item == KITEM_SAD || (item > KITEM_NONE && item < NUMKARTITEMS))
|
if (item == KITEM_SAD || (item > KITEM_NONE && item < NUMKARTITEMS))
|
||||||
|
|
@ -4456,6 +4462,7 @@ static void K_drawDistributionDebugger(void)
|
||||||
kp_superring[1],
|
kp_superring[1],
|
||||||
kp_kitchensink[1],
|
kp_kitchensink[1],
|
||||||
kp_droptarget[1],
|
kp_droptarget[1],
|
||||||
|
kp_gardentop[1],
|
||||||
|
|
||||||
kp_sneaker[1],
|
kp_sneaker[1],
|
||||||
kp_sneaker[1],
|
kp_sneaker[1],
|
||||||
|
|
|
||||||
730
src/k_kart.c
730
src/k_kart.c
File diff suppressed because it is too large
Load diff
10
src/k_kart.h
10
src/k_kart.h
|
|
@ -69,6 +69,7 @@ void K_SpawnDashDustRelease(player_t *player);
|
||||||
void K_SpawnDriftBoostClip(player_t *player);
|
void K_SpawnDriftBoostClip(player_t *player);
|
||||||
void K_SpawnDriftBoostClipSpark(mobj_t *clip);
|
void K_SpawnDriftBoostClipSpark(mobj_t *clip);
|
||||||
void K_SpawnNormalSpeedLines(player_t *player);
|
void K_SpawnNormalSpeedLines(player_t *player);
|
||||||
|
void K_SpawnGardenTopSpeedLines(player_t *player);
|
||||||
void K_SpawnInvincibilitySpeedLines(mobj_t *mo);
|
void K_SpawnInvincibilitySpeedLines(mobj_t *mo);
|
||||||
void K_SpawnBumpEffect(mobj_t *mo);
|
void K_SpawnBumpEffect(mobj_t *mo);
|
||||||
void K_KartMoveAnimation(player_t *player);
|
void K_KartMoveAnimation(player_t *player);
|
||||||
|
|
@ -142,7 +143,13 @@ boolean K_ApplyOffroad(player_t *player);
|
||||||
boolean K_SlopeResistance(player_t *player);
|
boolean K_SlopeResistance(player_t *player);
|
||||||
tripwirepass_t K_TripwirePassConditions(player_t *player);
|
tripwirepass_t K_TripwirePassConditions(player_t *player);
|
||||||
boolean K_TripwirePass(player_t *player);
|
boolean K_TripwirePass(player_t *player);
|
||||||
boolean K_WaterRun(player_t *player);
|
boolean K_MovingHorizontally(mobj_t *mobj);
|
||||||
|
boolean K_WaterRun(mobj_t *mobj);
|
||||||
|
boolean K_WaterSkip(mobj_t *mobj);
|
||||||
|
void K_SpawnWaterRunParticles(mobj_t *mobj);
|
||||||
|
boolean K_IsRidingFloatingTop(player_t *player);
|
||||||
|
boolean K_IsHoldingDownTop(player_t *player);
|
||||||
|
mobj_t *K_GetGardenTop(player_t *player);
|
||||||
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
|
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
|
||||||
INT16 K_GetSpindashChargeTime(player_t *player);
|
INT16 K_GetSpindashChargeTime(player_t *player);
|
||||||
fixed_t K_GetSpindashChargeSpeed(player_t *player);
|
fixed_t K_GetSpindashChargeSpeed(player_t *player);
|
||||||
|
|
@ -169,6 +176,7 @@ UINT8 K_GetOrbinautItemFrame(UINT8 count);
|
||||||
boolean K_IsSPBInGame(void);
|
boolean K_IsSPBInGame(void);
|
||||||
void K_KartEbrakeVisuals(player_t *p);
|
void K_KartEbrakeVisuals(player_t *p);
|
||||||
void K_HandleDirectionalInfluence(player_t *player);
|
void K_HandleDirectionalInfluence(player_t *player);
|
||||||
|
fixed_t K_DefaultPlayerRadius(player_t *player);
|
||||||
|
|
||||||
// sound stuff for lua
|
// sound stuff for lua
|
||||||
void K_PlayAttackTaunt(mobj_t *source);
|
void K_PlayAttackTaunt(mobj_t *source);
|
||||||
|
|
|
||||||
|
|
@ -2016,7 +2016,7 @@ void M_QuitResponse(INT32 ch)
|
||||||
|
|
||||||
if (ch == MA_YES)
|
if (ch == MA_YES)
|
||||||
{
|
{
|
||||||
if (!(netgame || cv_debug))
|
if (!(netgame || cht_debug))
|
||||||
{
|
{
|
||||||
mrand = M_RandomKey(sizeof(quitsounds) / sizeof(INT32));
|
mrand = M_RandomKey(sizeof(quitsounds) / sizeof(INT32));
|
||||||
if (quitsounds[mrand])
|
if (quitsounds[mrand])
|
||||||
|
|
@ -3577,7 +3577,7 @@ void M_LevelSelectHandler(INT32 choice)
|
||||||
strncpy(connectedservername, cv_servername.string, MAXSERVERNAME);
|
strncpy(connectedservername, cv_servername.string, MAXSERVERNAME);
|
||||||
|
|
||||||
// Still need to reset devmode
|
// Still need to reset devmode
|
||||||
cv_debug = 0;
|
cht_debug = 0;
|
||||||
|
|
||||||
if (demo.playback)
|
if (demo.playback)
|
||||||
G_StopDemo();
|
G_StopDemo();
|
||||||
|
|
@ -3686,7 +3686,7 @@ void M_StartTimeAttack(INT32 choice)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Still need to reset devmode
|
// Still need to reset devmode
|
||||||
cv_debug = 0;
|
cht_debug = 0;
|
||||||
emeralds = 0;
|
emeralds = 0;
|
||||||
|
|
||||||
if (demo.playback)
|
if (demo.playback)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,14 @@ void Obj_HyudoroThink(mobj_t *actor);
|
||||||
void Obj_HyudoroCenterThink(mobj_t *actor);
|
void Obj_HyudoroCenterThink(mobj_t *actor);
|
||||||
void Obj_HyudoroCollide(mobj_t *special, mobj_t *toucher);
|
void Obj_HyudoroCollide(mobj_t *special, mobj_t *toucher);
|
||||||
|
|
||||||
|
/* Garden Top */
|
||||||
|
void Obj_GardenTopDeploy(mobj_t *rider);
|
||||||
|
mobj_t *Obj_GardenTopThrow(player_t *player);
|
||||||
|
mobj_t *Obj_GardenTopDestroy(player_t *player);
|
||||||
|
void Obj_GardenTopThink(mobj_t *top);
|
||||||
|
void Obj_GardenTopSparkThink(mobj_t *spark);
|
||||||
|
boolean Obj_GardenTopPlayerIsGrinding(player_t *player);
|
||||||
|
|
||||||
/* Shrink */
|
/* Shrink */
|
||||||
void Obj_PohbeeThinker(mobj_t *pohbee);
|
void Obj_PohbeeThinker(mobj_t *pohbee);
|
||||||
void Obj_PohbeeRemoved(mobj_t *pohbee);
|
void Obj_PohbeeRemoved(mobj_t *pohbee);
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,13 @@ void K_DoIngameRespawn(player_t *player)
|
||||||
P_ResetPlayer(player);
|
P_ResetPlayer(player);
|
||||||
|
|
||||||
// Set up respawn position if invalid
|
// Set up respawn position if invalid
|
||||||
if (player->respawn.wp != NULL && leveltime >= starttime)
|
if (player->respawn.manual == true)
|
||||||
|
{
|
||||||
|
player->respawn.distanceleft = 0;
|
||||||
|
player->respawn.pointz += K_RespawnOffset(player, player->respawn.flip);
|
||||||
|
player->respawn.manual = false; // one respawn only!
|
||||||
|
}
|
||||||
|
else if (player->respawn.wp != NULL && leveltime >= starttime)
|
||||||
{
|
{
|
||||||
const UINT32 dist = RESPAWN_DIST + (player->airtime * 48);
|
const UINT32 dist = RESPAWN_DIST + (player->airtime * 48);
|
||||||
player->respawn.distanceleft = (dist * mapobjectscale) / FRACUNIT;
|
player->respawn.distanceleft = (dist * mapobjectscale) / FRACUNIT;
|
||||||
|
|
|
||||||
|
|
@ -1082,7 +1082,7 @@ void K_UpdateTerrainOverlay(mobj_t *mo)
|
||||||
fixed_t speedDiv = FRACUNIT + FixedMul(FixedDiv(speed, maxSpeed), o->speed);
|
fixed_t speedDiv = FRACUNIT + FixedMul(FixedDiv(speed, maxSpeed), o->speed);
|
||||||
tic_t animSpeed = max(FixedDiv(mo->state->tics, speedDiv), 1);
|
tic_t animSpeed = max(FixedDiv(mo->state->tics, speedDiv), 1);
|
||||||
|
|
||||||
mo->tics = min(mo->tics, animSpeed);
|
mo->tics = min((tic_t)mo->tics, animSpeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -954,12 +954,15 @@ static int lib_pCheckDeathPitCollide(lua_State *L)
|
||||||
|
|
||||||
static int lib_pCheckSolidLava(lua_State *L)
|
static int lib_pCheckSolidLava(lua_State *L)
|
||||||
{
|
{
|
||||||
|
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||||
ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR));
|
ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR));
|
||||||
//HUDSAFE
|
//HUDSAFE
|
||||||
INLEVEL
|
INLEVEL
|
||||||
|
if (!mo)
|
||||||
|
return LUA_ErrInvalid(L, "mobj_t");
|
||||||
if (!rover)
|
if (!rover)
|
||||||
return LUA_ErrInvalid(L, "ffloor_t");
|
return LUA_ErrInvalid(L, "ffloor_t");
|
||||||
lua_pushboolean(L, P_CheckSolidLava(rover));
|
lua_pushboolean(L, P_CheckSolidLava(mo, rover));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ static UINT8 lib_searchBlockmap_Objects(lua_State *L, INT32 x, INT32 y, mobj_t *
|
||||||
LUA_PushUserdata(L, thing, META_MOBJ);
|
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||||
LUA_PushUserdata(L, mobj, META_MOBJ);
|
LUA_PushUserdata(L, mobj, META_MOBJ);
|
||||||
if (lua_pcall(gL, 2, 1, 0)) {
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
if (!blockfuncerror || cv_debug & DBG_LUA)
|
if (!blockfuncerror || cht_debug & DBG_LUA)
|
||||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
lua_pop(gL, 1);
|
lua_pop(gL, 1);
|
||||||
blockfuncerror = true;
|
blockfuncerror = true;
|
||||||
|
|
@ -112,7 +112,7 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
|
||||||
LUA_PushUserdata(L, thing, META_MOBJ);
|
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||||
LUA_PushUserdata(L, po->lines[i], META_LINE);
|
LUA_PushUserdata(L, po->lines[i], META_LINE);
|
||||||
if (lua_pcall(gL, 2, 1, 0)) {
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
if (!blockfuncerror || cv_debug & DBG_LUA)
|
if (!blockfuncerror || cht_debug & DBG_LUA)
|
||||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
lua_pop(gL, 1);
|
lua_pop(gL, 1);
|
||||||
blockfuncerror = true;
|
blockfuncerror = true;
|
||||||
|
|
@ -149,7 +149,7 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
|
||||||
LUA_PushUserdata(L, thing, META_MOBJ);
|
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||||
LUA_PushUserdata(L, ld, META_LINE);
|
LUA_PushUserdata(L, ld, META_LINE);
|
||||||
if (lua_pcall(gL, 2, 1, 0)) {
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
if (!blockfuncerror || cv_debug & DBG_LUA)
|
if (!blockfuncerror || cht_debug & DBG_LUA)
|
||||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
lua_pop(gL, 1);
|
lua_pop(gL, 1);
|
||||||
blockfuncerror = true;
|
blockfuncerror = true;
|
||||||
|
|
@ -195,7 +195,7 @@ static UINT8 lib_searchBlockmap_PolyObjs(lua_State *L, INT32 x, INT32 y, mobj_t
|
||||||
LUA_PushUserdata(L, thing, META_MOBJ);
|
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||||
LUA_PushUserdata(L, po, META_POLYOBJ);
|
LUA_PushUserdata(L, po, META_POLYOBJ);
|
||||||
if (lua_pcall(gL, 2, 1, 0)) {
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
if (!blockfuncerror || cv_debug & DBG_LUA)
|
if (!blockfuncerror || cht_debug & DBG_LUA)
|
||||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
lua_pop(gL, 1);
|
lua_pop(gL, 1);
|
||||||
blockfuncerror = true;
|
blockfuncerror = true;
|
||||||
|
|
|
||||||
|
|
@ -411,7 +411,7 @@ static int call_single_hook_no_copy(Hook_State *hook)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* print the error message once */
|
/* print the error message once */
|
||||||
if (cv_debug & DBG_LUA || !in_bit_array(hooksErrored, hook->id))
|
if (cht_debug & DBG_LUA || !in_bit_array(hooksErrored, hook->id))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, "%s\n", lua_tostring(gL, -1));
|
CONS_Alert(CONS_WARNING, "%s\n", lua_tostring(gL, -1));
|
||||||
set_bit_array(hooksErrored, hook->id);
|
set_bit_array(hooksErrored, hook->id);
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ enum mobj_e {
|
||||||
mobj_spryoff,
|
mobj_spryoff,
|
||||||
mobj_sprzoff,
|
mobj_sprzoff,
|
||||||
mobj_hitlag,
|
mobj_hitlag,
|
||||||
|
mobj_waterskip,
|
||||||
mobj_dispoffset
|
mobj_dispoffset
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -181,6 +182,7 @@ static const char *const mobj_opt[] = {
|
||||||
"spryoff",
|
"spryoff",
|
||||||
"sprzoff",
|
"sprzoff",
|
||||||
"hitlag",
|
"hitlag",
|
||||||
|
"waterskip",
|
||||||
"dispoffset",
|
"dispoffset",
|
||||||
NULL};
|
NULL};
|
||||||
|
|
||||||
|
|
@ -460,6 +462,9 @@ static int mobj_get(lua_State *L)
|
||||||
case mobj_hitlag:
|
case mobj_hitlag:
|
||||||
lua_pushinteger(L, mo->hitlag);
|
lua_pushinteger(L, mo->hitlag);
|
||||||
break;
|
break;
|
||||||
|
case mobj_waterskip:
|
||||||
|
lua_pushinteger(L, mo->waterskip);
|
||||||
|
break;
|
||||||
case mobj_dispoffset:
|
case mobj_dispoffset:
|
||||||
lua_pushinteger(L, mo->dispoffset);
|
lua_pushinteger(L, mo->dispoffset);
|
||||||
break;
|
break;
|
||||||
|
|
@ -835,6 +840,9 @@ static int mobj_set(lua_State *L)
|
||||||
case mobj_hitlag:
|
case mobj_hitlag:
|
||||||
mo->hitlag = luaL_checkinteger(L, 3);
|
mo->hitlag = luaL_checkinteger(L, 3);
|
||||||
break;
|
break;
|
||||||
|
case mobj_waterskip:
|
||||||
|
mo->waterskip = (UINT8)luaL_checkinteger(L, 3);
|
||||||
|
break;
|
||||||
case mobj_dispoffset:
|
case mobj_dispoffset:
|
||||||
mo->dispoffset = luaL_checkinteger(L, 3);
|
mo->dispoffset = luaL_checkinteger(L, 3);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -264,8 +264,6 @@ static int player_get(lua_State *L)
|
||||||
lua_pushinteger(L, plr->aizdriftturn);
|
lua_pushinteger(L, plr->aizdriftturn);
|
||||||
else if (fastcmp(field,"offroad"))
|
else if (fastcmp(field,"offroad"))
|
||||||
lua_pushinteger(L, plr->offroad);
|
lua_pushinteger(L, plr->offroad);
|
||||||
else if (fastcmp(field,"waterskip"))
|
|
||||||
lua_pushinteger(L, plr->waterskip);
|
|
||||||
else if (fastcmp(field,"tiregrease"))
|
else if (fastcmp(field,"tiregrease"))
|
||||||
lua_pushinteger(L, plr->tiregrease);
|
lua_pushinteger(L, plr->tiregrease);
|
||||||
else if (fastcmp(field,"springstars"))
|
else if (fastcmp(field,"springstars"))
|
||||||
|
|
@ -634,8 +632,6 @@ static int player_set(lua_State *L)
|
||||||
plr->aizdriftturn = luaL_checkinteger(L, 3);
|
plr->aizdriftturn = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"offroad"))
|
else if (fastcmp(field,"offroad"))
|
||||||
plr->offroad = luaL_checkinteger(L, 3);
|
plr->offroad = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"waterskip"))
|
|
||||||
plr->waterskip = luaL_checkinteger(L, 3);
|
|
||||||
else if (fastcmp(field,"tiregrease"))
|
else if (fastcmp(field,"tiregrease"))
|
||||||
plr->tiregrease = luaL_checkinteger(L, 3);
|
plr->tiregrease = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"springstars"))
|
else if (fastcmp(field,"springstars"))
|
||||||
|
|
|
||||||
222
src/m_cheat.c
222
src/m_cheat.c
|
|
@ -38,6 +38,8 @@
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_hook.h"
|
#include "lua_hook.h"
|
||||||
|
|
||||||
|
#include "fastcmp.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// CHEAT SEQUENCE PACKAGE
|
// CHEAT SEQUENCE PACKAGE
|
||||||
//
|
//
|
||||||
|
|
@ -111,7 +113,7 @@ static UINT8 cheatf_devmode(void)
|
||||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||||
unlockables[i].unlocked = true;
|
unlockables[i].unlocked = true;
|
||||||
devparm = true;
|
devparm = true;
|
||||||
cv_debug |= 0x8000;
|
cht_debug |= 0x8000;
|
||||||
|
|
||||||
// Refresh secrets menu existing.
|
// Refresh secrets menu existing.
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
|
|
@ -251,37 +253,18 @@ boolean cht_Responder(event_t *ev)
|
||||||
// command that can be typed at the console!
|
// command that can be typed at the console!
|
||||||
void Command_CheatNoClip_f(void)
|
void Command_CheatNoClip_f(void)
|
||||||
{
|
{
|
||||||
player_t *plyr;
|
|
||||||
|
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_INLEVEL;
|
REQUIRE_INLEVEL;
|
||||||
REQUIRE_SINGLEPLAYER; // TODO: make netplay compatible
|
|
||||||
|
|
||||||
plyr = &players[consoleplayer];
|
D_Cheat(consoleplayer, CHEAT_NOCLIP);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_CheatGod_f(void)
|
void Command_CheatGod_f(void)
|
||||||
{
|
{
|
||||||
player_t *plyr;
|
|
||||||
|
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_INLEVEL;
|
REQUIRE_INLEVEL;
|
||||||
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
|
|
||||||
|
|
||||||
plyr = &players[consoleplayer];
|
D_Cheat(consoleplayer, CHEAT_GOD);
|
||||||
plyr->cheats ^= PC_GODMODE;
|
|
||||||
CONS_Printf(M_GetText("Cheese Mode %s\n"), plyr->cheats & PC_GODMODE ? M_GetText("On") : M_GetText("Off"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_Scale_f(void)
|
void Command_Scale_f(void)
|
||||||
|
|
@ -291,7 +274,6 @@ void Command_Scale_f(void)
|
||||||
|
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_INLEVEL;
|
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...
|
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 +281,21 @@ void Command_Scale_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!players[consoleplayer].mo)
|
D_Cheat(consoleplayer, CHEAT_SCALE, scale);
|
||||||
return;
|
|
||||||
|
|
||||||
players[consoleplayer].mo->destscale = scale;
|
|
||||||
|
|
||||||
CONS_Printf(M_GetText("Scale set to %s\n"), COM_Argv(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_Gravflip_f(void)
|
void Command_Gravflip_f(void)
|
||||||
{
|
{
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_INLEVEL;
|
REQUIRE_INLEVEL;
|
||||||
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
|
|
||||||
|
|
||||||
if (players[consoleplayer].mo)
|
D_Cheat(consoleplayer, CHEAT_FLIP);
|
||||||
players[consoleplayer].mo->flags2 ^= MF2_OBJECTFLIP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_Hurtme_f(void)
|
void Command_Hurtme_f(void)
|
||||||
{
|
{
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_INLEVEL;
|
REQUIRE_INLEVEL;
|
||||||
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
|
|
||||||
|
|
||||||
if (COM_Argc() < 2)
|
if (COM_Argc() < 2)
|
||||||
{
|
{
|
||||||
|
|
@ -329,69 +303,26 @@ void Command_Hurtme_f(void)
|
||||||
return;
|
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)
|
void Command_RTeleport_f(void)
|
||||||
{
|
{
|
||||||
fixed_t intx, inty, intz;
|
float x = atof(COM_Argv(1));
|
||||||
size_t i;
|
float y = atof(COM_Argv(2));
|
||||||
player_t *p = &players[consoleplayer];
|
float z = atof(COM_Argv(3));
|
||||||
subsector_t *ss;
|
|
||||||
|
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_INLEVEL;
|
REQUIRE_INLEVEL;
|
||||||
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
|
|
||||||
|
|
||||||
if (COM_Argc() < 3 || COM_Argc() > 7)
|
if (COM_Argc() != 4)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("rteleport -x <value> -y <value> -z <value>: relative teleport to a location\n"));
|
CONS_Printf(M_GetText("rteleport <x> <y> <z>: relative teleport to a location\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p->mo)
|
D_Cheat(consoleplayer, CHEAT_RELATIVE_TELEPORT,
|
||||||
return;
|
FLOAT_TO_FIXED(x), FLOAT_TO_FIXED(y), FLOAT_TO_FIXED(z));
|
||||||
|
|
||||||
i = COM_CheckParm("-x");
|
|
||||||
if (i)
|
|
||||||
intx = atoi(COM_Argv(i + 1));
|
|
||||||
else
|
|
||||||
intx = 0;
|
|
||||||
|
|
||||||
i = COM_CheckParm("-y");
|
|
||||||
if (i)
|
|
||||||
inty = atoi(COM_Argv(i + 1));
|
|
||||||
else
|
|
||||||
inty = 0;
|
|
||||||
|
|
||||||
ss = R_PointInSubsectorOrNull(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT);
|
|
||||||
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
i = COM_CheckParm("-z");
|
|
||||||
if (i)
|
|
||||||
{
|
|
||||||
intz = atoi(COM_Argv(i + 1));
|
|
||||||
intz <<= FRACBITS;
|
|
||||||
intz += p->mo->z;
|
|
||||||
if (intz < ss->sector->floorheight)
|
|
||||||
intz = ss->sector->floorheight;
|
|
||||||
if (intz > ss->sector->ceilingheight - p->mo->height)
|
|
||||||
intz = ss->sector->ceilingheight - p->mo->height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
intz = p->mo->z;
|
|
||||||
|
|
||||||
CONS_Printf(M_GetText("Teleporting by %d, %d, %d...\n"), intx, inty, FixedInt((intz-p->mo->z)));
|
|
||||||
|
|
||||||
P_MapStart();
|
|
||||||
if (!P_SetOrigin(p->mo, p->mo->x+intx*FRACUNIT, p->mo->y+inty*FRACUNIT, intz))
|
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n"));
|
|
||||||
else
|
|
||||||
S_StartSound(p->mo, sfx_mixup);
|
|
||||||
P_MapEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_Teleport_f(void)
|
void Command_Teleport_f(void)
|
||||||
|
|
@ -619,7 +550,6 @@ void Command_Skynum_f(void)
|
||||||
{
|
{
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_INLEVEL;
|
REQUIRE_INLEVEL;
|
||||||
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
|
|
||||||
|
|
||||||
if (COM_Argc() != 2)
|
if (COM_Argc() != 2)
|
||||||
{
|
{
|
||||||
|
|
@ -651,18 +581,6 @@ void Command_Weather_f(void)
|
||||||
P_SwitchWeather(atoi(COM_Argv(1)));
|
P_SwitchWeather(atoi(COM_Argv(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_Toggletwod_f(void)
|
|
||||||
{
|
|
||||||
player_t *p = &players[consoleplayer];
|
|
||||||
|
|
||||||
REQUIRE_CHEATS;
|
|
||||||
REQUIRE_INLEVEL;
|
|
||||||
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
|
|
||||||
|
|
||||||
if (p->mo)
|
|
||||||
p->mo->flags2 ^= MF2_TWOD;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
// You never thought you needed this, did you? >=D
|
// You never thought you needed this, did you? >=D
|
||||||
// Yes, this has the specific purpose of completely screwing you up
|
// Yes, this has the specific purpose of completely screwing you up
|
||||||
|
|
@ -715,15 +633,15 @@ void Command_Dumplua_f(void)
|
||||||
|
|
||||||
void Command_Savecheckpoint_f(void)
|
void Command_Savecheckpoint_f(void)
|
||||||
{
|
{
|
||||||
|
mobj_t *thing = players[consoleplayer].mo;
|
||||||
|
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_INLEVEL;
|
REQUIRE_INLEVEL;
|
||||||
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
|
|
||||||
|
|
||||||
players[consoleplayer].respawn.pointx = players[consoleplayer].mo->x;
|
if (!P_MobjWasRemoved(thing))
|
||||||
players[consoleplayer].respawn.pointy = players[consoleplayer].mo->y;
|
{
|
||||||
players[consoleplayer].respawn.pointz = players[consoleplayer].mo->floorz;
|
D_Cheat(consoleplayer, CHEAT_SAVECHECKPOINT, thing->x, thing->y, thing->z);
|
||||||
|
}
|
||||||
CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].respawn.pointx, players[consoleplayer].respawn.pointy, players[consoleplayer].respawn.pointz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like M_GetAllEmeralds() but for console devmode junkies.
|
// Like M_GetAllEmeralds() but for console devmode junkies.
|
||||||
|
|
@ -749,24 +667,81 @@ void Command_Resetemeralds_f(void)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Devmode
|
||||||
|
//
|
||||||
|
|
||||||
|
UINT32 cht_debug;
|
||||||
|
|
||||||
|
struct debugFlagNames_s const debug_flag_names[] =
|
||||||
|
{
|
||||||
|
{"None", DBG_NONE},
|
||||||
|
{"Basic", DBG_BASIC},
|
||||||
|
{"Detailed", DBG_DETAILED},
|
||||||
|
{"Player", DBG_PLAYER},
|
||||||
|
{"Render", DBG_RENDER},
|
||||||
|
{"Renderer", DBG_RENDER}, // alt name
|
||||||
|
{"Polyobj", DBG_POLYOBJ},
|
||||||
|
{"GameLogic", DBG_GAMELOGIC},
|
||||||
|
{"Game", DBG_GAMELOGIC}, // alt name
|
||||||
|
{"Netplay", DBG_NETPLAY},
|
||||||
|
{"Memory", DBG_MEMORY},
|
||||||
|
{"Setup", DBG_SETUP},
|
||||||
|
{"Lua", DBG_LUA},
|
||||||
|
{"RNG", DBG_RNG},
|
||||||
|
{"Randomizer", DBG_RNG}, // alt name
|
||||||
|
{NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
void Command_Devmode_f(void)
|
void Command_Devmode_f(void)
|
||||||
{
|
{
|
||||||
|
size_t argc = 0;
|
||||||
|
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_SINGLEPLAYER; // TODO: make multiplayer compatible
|
|
||||||
|
|
||||||
if (COM_Argc() > 1)
|
argc = COM_Argc();
|
||||||
|
if (argc > 1)
|
||||||
{
|
{
|
||||||
const char *arg = COM_Argv(1);
|
UINT32 flags = 0;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
if (arg[0] && arg[0] == '0' &&
|
for (i = 1; i < argc; i++)
|
||||||
arg[1] && arg[1] == 'x') // Use hexadecimal!
|
{
|
||||||
cv_debug = axtoi(arg+2);
|
const char *arg = COM_Argv(i);
|
||||||
else
|
size_t j;
|
||||||
cv_debug = atoi(arg);
|
|
||||||
|
// Try it as a string
|
||||||
|
for (j = 0; debug_flag_names[j].str; j++)
|
||||||
|
{
|
||||||
|
if (stricmp(arg, debug_flag_names[j].str) == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug_flag_names[j].str)
|
||||||
|
{
|
||||||
|
flags |= debug_flag_names[j].flag;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try it as a number
|
||||||
|
if (arg[0] && arg[0] == '0' &&
|
||||||
|
arg[1] && arg[1] == 'x') // Use hexadecimal!
|
||||||
|
{
|
||||||
|
flags |= axtoi(arg+2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flags |= atoi(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
D_Cheat(consoleplayer, CHEAT_DEVMODE, flags);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("devmode <flags>: enable debugging tools and info, prepend with 0x to use hexadecimal\n"));
|
CONS_Printf(M_GetText("devmode <flags>: Enable debugging info. Prepend with 0x to use hexadecimal\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -776,13 +751,7 @@ void Command_Setrings_f(void)
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_INLEVEL;
|
REQUIRE_INLEVEL;
|
||||||
|
|
||||||
if (COM_Argc() > 1)
|
D_Cheat(consoleplayer, CHEAT_RINGS, atoi(COM_Argv(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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_Setlives_f(void)
|
void Command_Setlives_f(void)
|
||||||
|
|
@ -790,20 +759,7 @@ void Command_Setlives_f(void)
|
||||||
REQUIRE_CHEATS;
|
REQUIRE_CHEATS;
|
||||||
REQUIRE_INLEVEL;
|
REQUIRE_INLEVEL;
|
||||||
|
|
||||||
if (COM_Argc() > 1)
|
D_Cheat(consoleplayer, CHEAT_LIVES, atoi(COM_Argv(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)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,24 @@
|
||||||
#include "p_mobj.h"
|
#include "p_mobj.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CHEAT_NOCLIP,
|
||||||
|
CHEAT_GOD,
|
||||||
|
CHEAT_SAVECHECKPOINT,
|
||||||
|
CHEAT_RINGS,
|
||||||
|
CHEAT_LIVES,
|
||||||
|
CHEAT_SCALE,
|
||||||
|
CHEAT_FLIP,
|
||||||
|
CHEAT_HURT,
|
||||||
|
CHEAT_RELATIVE_TELEPORT,
|
||||||
|
CHEAT_DEVMODE,
|
||||||
|
|
||||||
|
NUMBER_OF_CHEATS
|
||||||
|
} cheat_t;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cheat sequences
|
||||||
|
//
|
||||||
boolean cht_Responder(event_t *ev);
|
boolean cht_Responder(event_t *ev);
|
||||||
void cht_Init(void);
|
void cht_Init(void);
|
||||||
|
|
||||||
|
|
@ -56,7 +74,6 @@ void Command_Teleport_f(void);
|
||||||
void Command_RTeleport_f(void);
|
void Command_RTeleport_f(void);
|
||||||
void Command_Skynum_f(void);
|
void Command_Skynum_f(void);
|
||||||
void Command_Weather_f(void);
|
void Command_Weather_f(void);
|
||||||
void Command_Toggletwod_f(void);
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
void Command_CauseCfail_f(void);
|
void Command_CauseCfail_f(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
hyudoro.c
|
hyudoro.c
|
||||||
|
gardentop.c
|
||||||
shrink.c
|
shrink.c
|
||||||
item-debris.c
|
item-debris.c
|
||||||
spb.c
|
spb.c
|
||||||
|
|
|
||||||
614
src/objects/gardentop.c
Normal file
614
src/objects/gardentop.c
Normal file
|
|
@ -0,0 +1,614 @@
|
||||||
|
#include "../doomdef.h"
|
||||||
|
#include "../doomstat.h"
|
||||||
|
#include "../info.h"
|
||||||
|
#include "../k_kart.h"
|
||||||
|
#include "../k_objects.h"
|
||||||
|
#include "../m_random.h"
|
||||||
|
#include "../p_local.h"
|
||||||
|
#include "../r_local.h"
|
||||||
|
#include "../s_sound.h"
|
||||||
|
|
||||||
|
// TODO: separate from this file
|
||||||
|
static fixed_t K_FlipZOffset(mobj_t *us, mobj_t *them)
|
||||||
|
{
|
||||||
|
fixed_t z = 0;
|
||||||
|
|
||||||
|
if (them->eflags & MFE_VERTICALFLIP)
|
||||||
|
z += them->height;
|
||||||
|
|
||||||
|
if (us->eflags & MFE_VERTICALFLIP)
|
||||||
|
z -= us->height;
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SPARKCOLOR SKINCOLOR_ROBIN
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TOP_ANCHORED,
|
||||||
|
TOP_LOOSE,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define topsfx_floating sfx_s3k7d
|
||||||
|
#define topsfx_grinding sfx_s3k79
|
||||||
|
#define topsfx_lift sfx_s3ka0
|
||||||
|
|
||||||
|
#define rider_top(o) ((o)->hnext)
|
||||||
|
|
||||||
|
#define top_mode(o) ((o)->extravalue1)
|
||||||
|
#define top_float(o) ((o)->lastlook)
|
||||||
|
#define top_sound(o) ((o)->extravalue2)
|
||||||
|
#define top_soundtic(o) ((o)->movecount)
|
||||||
|
|
||||||
|
/* TOP_ANCHORED */
|
||||||
|
#define top_rider(o) ((o)->tracer)
|
||||||
|
|
||||||
|
/* TOP_LOOSE */
|
||||||
|
#define top_waveangle(o) ((o)->movedir)
|
||||||
|
/* wavepause will take mobjinfo reactiontime automatically */
|
||||||
|
#define top_wavepause(o) ((o)->reactiontime)
|
||||||
|
|
||||||
|
#define spark_top(o) ((o)->target)
|
||||||
|
#define spark_angle(o) ((o)->movedir)
|
||||||
|
|
||||||
|
static inline player_t *
|
||||||
|
get_rider_player (mobj_t *rider)
|
||||||
|
{
|
||||||
|
return rider ? rider->player : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline player_t *
|
||||||
|
get_top_rider_player (mobj_t *top)
|
||||||
|
{
|
||||||
|
return get_rider_player(top_rider(top));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline boolean
|
||||||
|
is_top_grind_input (mobj_t *top)
|
||||||
|
{
|
||||||
|
player_t *player = get_top_rider_player(top);
|
||||||
|
|
||||||
|
return player && K_IsHoldingDownTop(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline boolean
|
||||||
|
is_top_grinding (mobj_t *top)
|
||||||
|
{
|
||||||
|
if (top_float(top) > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!P_IsObjectOnGround(top))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline fixed_t
|
||||||
|
grind_spark_base_scale (player_t *player)
|
||||||
|
{
|
||||||
|
return FRACUNIT/2 +
|
||||||
|
player->topdriftheld * FRACUNIT
|
||||||
|
/ GARDENTOP_MAXGRINDTIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline INT32
|
||||||
|
get_player_steer_tilt
|
||||||
|
( player_t * player,
|
||||||
|
INT32 stages)
|
||||||
|
{
|
||||||
|
return player->steering
|
||||||
|
* stages
|
||||||
|
|
||||||
|
// 1 degree for a full turn
|
||||||
|
/ KART_FULLTURN
|
||||||
|
* ANG1
|
||||||
|
|
||||||
|
// stages is for fractions of a full turn, divide to
|
||||||
|
// get a fraction of a degree
|
||||||
|
/ stages
|
||||||
|
|
||||||
|
// angle is inverted in reverse gravity
|
||||||
|
* P_MobjFlip(player->mo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline fixed_t
|
||||||
|
goofy_shake (fixed_t n)
|
||||||
|
{
|
||||||
|
return P_RandomRange(PR_DECORATION, -1, 1) * n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
init_top
|
||||||
|
( mobj_t * top,
|
||||||
|
INT32 mode)
|
||||||
|
{
|
||||||
|
top_mode(top) = mode;
|
||||||
|
top_float(top) = 0;
|
||||||
|
top_sound(top) = sfx_None;
|
||||||
|
top_waveangle(top) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
spawn_spark
|
||||||
|
( mobj_t * top,
|
||||||
|
angle_t angle)
|
||||||
|
{
|
||||||
|
mobj_t *spark = P_SpawnMobjFromMobj(
|
||||||
|
top, 0, 0, 0, MT_GARDENTOPSPARK);
|
||||||
|
|
||||||
|
P_SetTarget(&spark_top(spark), top);
|
||||||
|
|
||||||
|
spark_angle(spark) = angle;
|
||||||
|
|
||||||
|
spark->color = SPARKCOLOR;
|
||||||
|
spark->spriteyscale = 3*FRACUNIT/4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
spawn_spark_circle
|
||||||
|
( mobj_t * top,
|
||||||
|
UINT8 n)
|
||||||
|
{
|
||||||
|
const angle_t a = ANGLE_MAX / n;
|
||||||
|
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
spawn_spark(top, i * a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
spawn_grind_spark (mobj_t *top)
|
||||||
|
{
|
||||||
|
mobj_t *rider = top_rider(top);
|
||||||
|
mobj_t *spark;
|
||||||
|
|
||||||
|
player_t *player = NULL;
|
||||||
|
|
||||||
|
fixed_t x = 0;
|
||||||
|
fixed_t y = 0;
|
||||||
|
|
||||||
|
angle_t angle = top->angle;
|
||||||
|
|
||||||
|
if (rider)
|
||||||
|
{
|
||||||
|
const fixed_t speed = -20 * top->scale;
|
||||||
|
|
||||||
|
angle = K_MomentumAngle(rider);
|
||||||
|
|
||||||
|
x = P_ReturnThrustX(rider, angle, speed);
|
||||||
|
y = P_ReturnThrustY(rider, angle, speed);
|
||||||
|
|
||||||
|
player = get_rider_player(rider);
|
||||||
|
}
|
||||||
|
|
||||||
|
spark = P_SpawnMobjFromMobj(
|
||||||
|
top, x, y, 0, MT_DRIFTSPARK);
|
||||||
|
|
||||||
|
spark->momx = x;
|
||||||
|
spark->momy = y;
|
||||||
|
|
||||||
|
P_SetMobjState(spark, S_DRIFTSPARK_A1);
|
||||||
|
|
||||||
|
spark->angle = angle;
|
||||||
|
spark->color = SPARKCOLOR;
|
||||||
|
|
||||||
|
if (player)
|
||||||
|
{
|
||||||
|
spark->destscale = FixedMul(spark->destscale,
|
||||||
|
grind_spark_base_scale(player));
|
||||||
|
|
||||||
|
P_SetScale(spark, spark->destscale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
loop_sfx
|
||||||
|
( mobj_t * top,
|
||||||
|
sfxenum_t sfx)
|
||||||
|
{
|
||||||
|
switch (sfx)
|
||||||
|
{
|
||||||
|
case topsfx_floating:
|
||||||
|
if (S_SoundPlaying(top, sfx))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case topsfx_grinding:
|
||||||
|
if ((sfxenum_t)top_sound(top) != sfx)
|
||||||
|
{
|
||||||
|
top_soundtic(top) = leveltime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: could this sound just be looped
|
||||||
|
normally? :face_holding_back_tears: */
|
||||||
|
if ((leveltime - top_soundtic(top)) % 28 > 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
S_StartSound(top, sfx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
modulate (mobj_t *top)
|
||||||
|
{
|
||||||
|
const fixed_t max_hover = top->height / 4;
|
||||||
|
const fixed_t hover_step = max_hover / 4;
|
||||||
|
|
||||||
|
sfxenum_t ambience = sfx_None;
|
||||||
|
|
||||||
|
if (is_top_grind_input(top))
|
||||||
|
{
|
||||||
|
if (top_float(top) == max_hover)
|
||||||
|
{
|
||||||
|
P_SetMobjState(top, S_GARDENTOP_SINKING1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top_float(top) > 0)
|
||||||
|
{
|
||||||
|
top_float(top) = max(0,
|
||||||
|
top_float(top) - hover_step);
|
||||||
|
}
|
||||||
|
else if (P_IsObjectOnGround(top))
|
||||||
|
{
|
||||||
|
spawn_grind_spark(top);
|
||||||
|
ambience = topsfx_grinding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (top_float(top) == 0)
|
||||||
|
{
|
||||||
|
P_SetMobjState(top, S_GARDENTOP_FLOATING);
|
||||||
|
|
||||||
|
S_StopSoundByID(top, topsfx_grinding);
|
||||||
|
S_StartSound(top, topsfx_lift);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top_float(top) < max_hover)
|
||||||
|
{
|
||||||
|
top_float(top) = min(max_hover,
|
||||||
|
top_float(top) + hover_step);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ambience = topsfx_floating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
top->sprzoff = top_float(top) * P_MobjFlip(top);
|
||||||
|
|
||||||
|
if (ambience)
|
||||||
|
{
|
||||||
|
loop_sfx(top, ambience);
|
||||||
|
}
|
||||||
|
|
||||||
|
top_sound(top) = ambience;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tilt (mobj_t *top)
|
||||||
|
{
|
||||||
|
player_t *player = get_top_rider_player(top);
|
||||||
|
|
||||||
|
INT32 tilt = top->rollangle;
|
||||||
|
|
||||||
|
if (is_top_grind_input(top))
|
||||||
|
{
|
||||||
|
const angle_t tiltmax = ANGLE_22h;
|
||||||
|
|
||||||
|
tilt += get_player_steer_tilt(player, 4);
|
||||||
|
|
||||||
|
if (abs(tilt) > tiltmax)
|
||||||
|
{
|
||||||
|
tilt = intsign(tilt) * tiltmax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const angle_t decay = ANG1 * 2;
|
||||||
|
|
||||||
|
if (abs(tilt) > decay)
|
||||||
|
{
|
||||||
|
tilt -= intsign(tilt) * decay;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tilt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
top->rollangle = tilt;
|
||||||
|
|
||||||
|
/* Vibrate left and right if you're about to lose it. */
|
||||||
|
if (player && player->topinfirst)
|
||||||
|
{
|
||||||
|
top->spritexoffset = P_LerpFlip(32*FRACUNIT, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
top->spritexoffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go ABSOLUTELY NUTS if the player is tumbling... */
|
||||||
|
if (player && player->tumbleBounces > 0)
|
||||||
|
{
|
||||||
|
const fixed_t yofs = 48 * FRACUNIT;
|
||||||
|
const fixed_t ofs3d = 24 * top->scale;
|
||||||
|
|
||||||
|
/* spriteyoffset scales, e.g. with K_Squish */
|
||||||
|
top->spriteyoffset = FixedDiv(
|
||||||
|
goofy_shake(yofs), top->spriteyscale);
|
||||||
|
|
||||||
|
top->sprxoff = goofy_shake(ofs3d);
|
||||||
|
top->spryoff = goofy_shake(ofs3d);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
top->spriteyoffset = 0;
|
||||||
|
top->sprxoff = 0;
|
||||||
|
top->spryoff = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
anchor_top (mobj_t *top)
|
||||||
|
{
|
||||||
|
mobj_t *rider = top_rider(top);
|
||||||
|
player_t *player = get_rider_player(rider);
|
||||||
|
|
||||||
|
if (player && player->curshield != KSHIELD_TOP)
|
||||||
|
{
|
||||||
|
P_RemoveMobj(top);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tilt(top);
|
||||||
|
|
||||||
|
P_MoveOrigin(top, rider->x, rider->y,
|
||||||
|
rider->z + K_FlipZOffset(top, rider));
|
||||||
|
|
||||||
|
K_GenericExtraFlagsNoZAdjust(top, rider);
|
||||||
|
|
||||||
|
/* Copying the Z momentum lets the Top squash and stretch
|
||||||
|
as it falls with the player. Don't copy the X/Y
|
||||||
|
momentum because then it would always get slightly
|
||||||
|
ahead of the player. */
|
||||||
|
top->momx = 0;
|
||||||
|
top->momy = 0;
|
||||||
|
top->momz = rider->momz;
|
||||||
|
|
||||||
|
/* The Z momentum can put the Top slightly ahead of the
|
||||||
|
player in that axis too. It looks cool if the Top
|
||||||
|
falls below you but not if it bounces up. */
|
||||||
|
if (top->momz * P_MobjFlip(top) > 0)
|
||||||
|
{
|
||||||
|
top->momz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* match rider's slope tilt */
|
||||||
|
top->pitch = rider->pitch;
|
||||||
|
top->roll = rider->roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
loose_think (mobj_t *top)
|
||||||
|
{
|
||||||
|
const fixed_t thrustamount = top->movefactor;
|
||||||
|
const angle_t momangle = K_MomentumAngle(top);
|
||||||
|
|
||||||
|
angle_t ang = top->angle;
|
||||||
|
|
||||||
|
mobj_t *ghost = P_SpawnGhostMobj(top);
|
||||||
|
ghost->colorized = true; // already has color!
|
||||||
|
|
||||||
|
if (AngleDelta(ang, momangle) > ANGLE_90)
|
||||||
|
{
|
||||||
|
top->angle = momangle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top_wavepause(top))
|
||||||
|
{
|
||||||
|
top_wavepause(top)--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* oscillate between +90 and -90 degrees */
|
||||||
|
ang += AbsAngle(top_waveangle(top)) - ANGLE_90;
|
||||||
|
}
|
||||||
|
|
||||||
|
P_InstaThrust(top, top->angle, thrustamount);
|
||||||
|
P_Thrust(top, ang, thrustamount);
|
||||||
|
|
||||||
|
//top_waveangle(top) = (angle_t)top_waveangle(top) + ANG10;
|
||||||
|
top_waveangle(top) += ANG10;
|
||||||
|
|
||||||
|
/* intangibility grace period */
|
||||||
|
if (top->threshold > 0)
|
||||||
|
{
|
||||||
|
top->threshold--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
anchor_spark (mobj_t *spark)
|
||||||
|
{
|
||||||
|
mobj_t *top = spark_top(spark);
|
||||||
|
mobj_t *rider = top_rider(top);
|
||||||
|
player_t *player = get_rider_player(rider);
|
||||||
|
|
||||||
|
const angle_t angle = top->angle + spark_angle(spark);
|
||||||
|
const fixed_t x = P_ReturnThrustX(top, angle, spark->scale);
|
||||||
|
const fixed_t y = P_ReturnThrustY(top, angle, spark->scale);
|
||||||
|
|
||||||
|
/* FIXME: THIS FUNCTION FUCKING SUCKS */
|
||||||
|
K_FlipFromObject(spark, top);
|
||||||
|
|
||||||
|
P_MoveOrigin(spark, top->x + x, top->y + y,
|
||||||
|
top->z + K_FlipZOffset(spark, top));
|
||||||
|
|
||||||
|
spark->angle = angle;
|
||||||
|
|
||||||
|
if (player)
|
||||||
|
{
|
||||||
|
const fixed_t topspeed =
|
||||||
|
K_GetKartSpeed(player, false, false);
|
||||||
|
|
||||||
|
const fixed_t speed = FixedHypot(
|
||||||
|
rider->momx, rider->momy);
|
||||||
|
|
||||||
|
P_SetScale(spark, FixedMul(top->scale, FRACUNIT/2 +
|
||||||
|
FixedDiv(speed / 2, topspeed)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Obj_GardenTopDeploy (mobj_t *rider)
|
||||||
|
{
|
||||||
|
player_t *player = rider->player;
|
||||||
|
|
||||||
|
mobj_t *top = P_SpawnMobjFromMobj(
|
||||||
|
rider, 0, 0, 0, MT_GARDENTOP);
|
||||||
|
|
||||||
|
init_top(top, TOP_ANCHORED);
|
||||||
|
|
||||||
|
top->flags |= MF_NOCLIPHEIGHT;
|
||||||
|
|
||||||
|
/* only the player's shadow needs to be rendered */
|
||||||
|
top->shadowscale = 0;
|
||||||
|
|
||||||
|
P_SetTarget(&top_rider(top), rider);
|
||||||
|
P_SetTarget(&rider_top(rider), top);
|
||||||
|
|
||||||
|
if (player)
|
||||||
|
{
|
||||||
|
player->curshield = KSHIELD_TOP;
|
||||||
|
rider->radius = K_DefaultPlayerRadius(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
spawn_spark_circle(top, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
mobj_t *
|
||||||
|
Obj_GardenTopThrow (player_t *player)
|
||||||
|
{
|
||||||
|
mobj_t *top = K_GetGardenTop(player);
|
||||||
|
|
||||||
|
if (top)
|
||||||
|
{
|
||||||
|
const fixed_t oldfloat = top_float(top);
|
||||||
|
const fixed_t height = top->height;
|
||||||
|
|
||||||
|
K_UpdateHnextList(player, true);
|
||||||
|
|
||||||
|
/* Sucks that another one needs to be spawned but
|
||||||
|
this way, the throwing function can be used. */
|
||||||
|
top = K_ThrowKartItem(
|
||||||
|
player, true, MT_GARDENTOP, 1, 0, 0);
|
||||||
|
|
||||||
|
init_top(top, TOP_LOOSE);
|
||||||
|
|
||||||
|
top_float(top) = oldfloat;
|
||||||
|
top_waveangle(top) = 0;
|
||||||
|
|
||||||
|
/* prevents it from hitting us on its way out */
|
||||||
|
top->threshold = 20;
|
||||||
|
|
||||||
|
/* ensure it's tangible */
|
||||||
|
top->flags &= ~(MF_NOCLIPTHING);
|
||||||
|
|
||||||
|
/* Put player PHYSICALLY on top. While riding the
|
||||||
|
Top, player collision was used and the player
|
||||||
|
technically remained on the ground. Now they
|
||||||
|
should fall off. */
|
||||||
|
P_SetOrigin(player->mo, player->mo->x, player->mo->y,
|
||||||
|
player->mo->z + height * P_MobjFlip(player->mo));
|
||||||
|
|
||||||
|
if (player->itemamount > 0)
|
||||||
|
player->itemamount--;
|
||||||
|
|
||||||
|
if (player->itemamount <= 0)
|
||||||
|
player->itemtype = KITEM_NONE;
|
||||||
|
|
||||||
|
player->curshield = KSHIELD_NONE;
|
||||||
|
|
||||||
|
player->mo->radius = K_DefaultPlayerRadius(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
|
mobj_t *
|
||||||
|
Obj_GardenTopDestroy (player_t *player)
|
||||||
|
{
|
||||||
|
mobj_t *top = Obj_GardenTopThrow(player);
|
||||||
|
|
||||||
|
if (top)
|
||||||
|
{
|
||||||
|
/* kill kill kill die die die */
|
||||||
|
P_KillMobj(top, NULL, NULL, DMG_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Obj_GardenTopThink (mobj_t *top)
|
||||||
|
{
|
||||||
|
modulate(top);
|
||||||
|
|
||||||
|
switch (top_mode(top))
|
||||||
|
{
|
||||||
|
case TOP_ANCHORED:
|
||||||
|
if (top_rider(top))
|
||||||
|
{
|
||||||
|
anchor_top(top);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TOP_LOOSE:
|
||||||
|
loose_think(top);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Obj_GardenTopSparkThink (mobj_t *spark)
|
||||||
|
{
|
||||||
|
mobj_t *top = spark_top(spark);
|
||||||
|
|
||||||
|
if (!top)
|
||||||
|
{
|
||||||
|
P_RemoveMobj(spark);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
anchor_spark(spark);
|
||||||
|
|
||||||
|
if (is_top_grinding(top))
|
||||||
|
{
|
||||||
|
spark->renderflags ^= RF_DONTDRAW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spark->renderflags |= RF_DONTDRAW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
Obj_GardenTopPlayerIsGrinding (player_t *player)
|
||||||
|
{
|
||||||
|
mobj_t *top = K_GetGardenTop(player);
|
||||||
|
|
||||||
|
return top ? is_top_grinding(top) : false;
|
||||||
|
}
|
||||||
|
|
@ -143,6 +143,7 @@ void Obj_OrbinautThink(mobj_t *th)
|
||||||
boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
boolean damageitem = false;
|
boolean damageitem = false;
|
||||||
|
boolean tumbleitem = false;
|
||||||
boolean sprung = false;
|
boolean sprung = false;
|
||||||
|
|
||||||
if ((orbinaut_selfdelay(t1) > 0 && t2->hitlag > 0)
|
if ((orbinaut_selfdelay(t1) > 0 && t2->hitlag > 0)
|
||||||
|
|
@ -173,6 +174,11 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t1->type == MT_GARDENTOP)
|
||||||
|
{
|
||||||
|
tumbleitem = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (t2->player)
|
if (t2->player)
|
||||||
{
|
{
|
||||||
if ((t2->player->flashing > 0 && t2->hitlag == 0)
|
if ((t2->player->flashing > 0 && t2->hitlag == 0)
|
||||||
|
|
@ -190,7 +196,8 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Player Damage
|
// Player Damage
|
||||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT|DMG_WOMBO);
|
P_DamageMobj(t2, t1, t1->target, 1, DMG_WOMBO |
|
||||||
|
(tumbleitem ? DMG_TUMBLE : DMG_WIPEOUT));
|
||||||
K_KartBouncing(t2, t1);
|
K_KartBouncing(t2, t1);
|
||||||
S_StartSound(t2, sfx_s3k7b);
|
S_StartSound(t2, sfx_s3k7b);
|
||||||
}
|
}
|
||||||
|
|
@ -233,6 +240,11 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
||||||
damageitem = true;
|
damageitem = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t1->type == MT_GARDENTOP)
|
||||||
|
{
|
||||||
|
damageitem = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (damageitem)
|
if (damageitem)
|
||||||
{
|
{
|
||||||
// This Item Damage
|
// This Item Damage
|
||||||
|
|
|
||||||
|
|
@ -8216,7 +8216,7 @@ void A_OrbitNights(mobj_t* actor)
|
||||||
|
|
||||||
if (!actor->target)
|
if (!actor->target)
|
||||||
{
|
{
|
||||||
if (cv_debug && !(actor->target && actor->target->player))
|
if (cht_debug && !(actor->target && actor->target->player))
|
||||||
CONS_Printf("ERROR: Powerup has no target!\n");
|
CONS_Printf("ERROR: Powerup has no target!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -8286,7 +8286,7 @@ void A_SetObjectState(mobj_t *actor)
|
||||||
|
|
||||||
if ((!locvar2 && !actor->target) || (locvar2 && !actor->tracer))
|
if ((!locvar2 && !actor->target) || (locvar2 && !actor->tracer))
|
||||||
{
|
{
|
||||||
if (cv_debug)
|
if (cht_debug)
|
||||||
CONS_Printf("A_SetObjectState: No target to change state!\n");
|
CONS_Printf("A_SetObjectState: No target to change state!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -8377,7 +8377,7 @@ void A_KnockBack(mobj_t *actor)
|
||||||
|
|
||||||
if (!target)
|
if (!target)
|
||||||
{
|
{
|
||||||
if(cv_debug)
|
if(cht_debug)
|
||||||
CONS_Printf("A_KnockBack: No target!\n");
|
CONS_Printf("A_KnockBack: No target!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -8441,7 +8441,7 @@ void A_RingDrain(mobj_t *actor)
|
||||||
|
|
||||||
if (!actor->target || !actor->target->player)
|
if (!actor->target || !actor->target->player)
|
||||||
{
|
{
|
||||||
if(cv_debug)
|
if(cht_debug)
|
||||||
CONS_Printf("A_RingDrain: No player targeted!\n");
|
CONS_Printf("A_RingDrain: No player targeted!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -8645,7 +8645,7 @@ void A_Custom3DRotate(mobj_t *actor)
|
||||||
|
|
||||||
if (hspeed==0 && vspeed==0)
|
if (hspeed==0 && vspeed==0)
|
||||||
{
|
{
|
||||||
if (cv_debug)
|
if (cht_debug)
|
||||||
CONS_Printf("Error: A_Custom3DRotate: Object has no speed.\n");
|
CONS_Printf("Error: A_Custom3DRotate: Object has no speed.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -9080,7 +9080,7 @@ void A_SetCustomValue(mobj_t *actor)
|
||||||
if (LUA_CallAction(A_SETCUSTOMVALUE, actor))
|
if (LUA_CallAction(A_SETCUSTOMVALUE, actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cv_debug)
|
if (cht_debug)
|
||||||
CONS_Printf("Init custom value is %d\n", actor->cusval);
|
CONS_Printf("Init custom value is %d\n", actor->cusval);
|
||||||
|
|
||||||
if (locvar1 == 0 && locvar2 == 4)
|
if (locvar1 == 0 && locvar2 == 4)
|
||||||
|
|
@ -9100,7 +9100,7 @@ void A_SetCustomValue(mobj_t *actor)
|
||||||
else // replace
|
else // replace
|
||||||
actor->cusval = locvar1;
|
actor->cusval = locvar1;
|
||||||
|
|
||||||
if(cv_debug)
|
if(cht_debug)
|
||||||
CONS_Printf("New custom value is %d\n", actor->cusval);
|
CONS_Printf("New custom value is %d\n", actor->cusval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9467,7 +9467,7 @@ void A_SetScale(mobj_t *actor)
|
||||||
|
|
||||||
if (locvar1 <= 0)
|
if (locvar1 <= 0)
|
||||||
{
|
{
|
||||||
if(cv_debug)
|
if(cht_debug)
|
||||||
CONS_Printf("A_SetScale: Valid scale not specified!\n");
|
CONS_Printf("A_SetScale: Valid scale not specified!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -9481,7 +9481,7 @@ void A_SetScale(mobj_t *actor)
|
||||||
|
|
||||||
if (!target)
|
if (!target)
|
||||||
{
|
{
|
||||||
if(cv_debug)
|
if(cht_debug)
|
||||||
CONS_Printf("A_SetScale: No target!\n");
|
CONS_Printf("A_SetScale: No target!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -9522,7 +9522,7 @@ void A_RemoteDamage(mobj_t *actor)
|
||||||
|
|
||||||
if (!target)
|
if (!target)
|
||||||
{
|
{
|
||||||
if(cv_debug)
|
if(cht_debug)
|
||||||
CONS_Printf("A_RemoteDamage: No target!\n");
|
CONS_Printf("A_RemoteDamage: No target!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -13149,7 +13149,7 @@ void A_ItemPop(mobj_t *actor)
|
||||||
|
|
||||||
if (!(actor->target && actor->target->player))
|
if (!(actor->target && actor->target->player))
|
||||||
{
|
{
|
||||||
if (cv_debug && !(actor->target && actor->target->player))
|
if (cht_debug && !(actor->target && actor->target->player))
|
||||||
CONS_Printf("ERROR: Powerup has no target!\n");
|
CONS_Printf("ERROR: Powerup has no target!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1879,7 +1879,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
|
|
||||||
if (player) // Player is the target
|
if (player) // Player is the target
|
||||||
{
|
{
|
||||||
if (player->cheats & PC_GODMODE)
|
if (player->pflags & PF_GODMODE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!force)
|
if (!force)
|
||||||
|
|
@ -2019,6 +2019,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
player->emeralds = 0;
|
player->emeralds = 0;
|
||||||
K_CheckEmeralds(source->player);
|
K_CheckEmeralds(source->player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Drop "shield" immediately on contact. */
|
||||||
|
if (source->player->curshield == KSHIELD_TOP)
|
||||||
|
{
|
||||||
|
Obj_GardenTopDestroy(source->player);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,8 @@ void P_PlayerAfterThink(player_t *player);
|
||||||
void P_DoPlayerExit(player_t *player);
|
void P_DoPlayerExit(player_t *player);
|
||||||
void P_DoTimeOver(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);
|
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_ReturnThrustX(mobj_t *mo, angle_t angle, fixed_t move);
|
||||||
fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move);
|
fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move);
|
||||||
|
|
@ -315,7 +317,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
|
||||||
|
|
||||||
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
|
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
|
||||||
boolean P_CheckDeathPitCollide(mobj_t *mo);
|
boolean P_CheckDeathPitCollide(mobj_t *mo);
|
||||||
boolean P_CheckSolidLava(ffloor_t *rover);
|
boolean P_CheckSolidLava(mobj_t *mobj, ffloor_t *rover);
|
||||||
void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype);
|
void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype);
|
||||||
|
|
||||||
mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type);
|
mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type);
|
||||||
|
|
@ -337,8 +339,8 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|
||||||
void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab);
|
void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab);
|
||||||
mobj_t *P_GetClosestAxis(mobj_t *source);
|
mobj_t *P_GetClosestAxis(mobj_t *source);
|
||||||
|
|
||||||
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover);
|
boolean P_CanRunOnWater(mobj_t *mobj, ffloor_t *rover);
|
||||||
boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover);
|
boolean P_CheckSolidFFloorSurface(mobj_t *mobj, ffloor_t *rover);
|
||||||
|
|
||||||
void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot);
|
void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot);
|
||||||
|
|
||||||
|
|
|
||||||
25
src/p_map.c
25
src/p_map.c
|
|
@ -866,6 +866,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
||||||
&& (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ
|
&& (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ
|
||||||
|| tmthing->type == MT_BANANA || tmthing->type == MT_EGGMANITEM || tmthing->type == MT_BALLHOG
|
|| tmthing->type == MT_BANANA || tmthing->type == MT_EGGMANITEM || tmthing->type == MT_BALLHOG
|
||||||
|| tmthing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || tmthing->type == MT_SINK
|
|| tmthing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || tmthing->type == MT_SINK
|
||||||
|
|| tmthing->type == MT_GARDENTOP
|
||||||
|| (tmthing->type == MT_PLAYER && thing->target != tmthing)))
|
|| (tmthing->type == MT_PLAYER && thing->target != tmthing)))
|
||||||
{
|
{
|
||||||
// see if it went over / under
|
// see if it went over / under
|
||||||
|
|
@ -881,6 +882,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
||||||
&& (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ
|
&& (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ
|
||||||
|| thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG
|
|| thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG
|
||||||
|| thing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || thing->type == MT_SINK
|
|| thing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || thing->type == MT_SINK
|
||||||
|
|| thing->type == MT_GARDENTOP
|
||||||
|| (thing->type == MT_PLAYER && tmthing->target != thing)))
|
|| (thing->type == MT_PLAYER && tmthing->target != thing)))
|
||||||
{
|
{
|
||||||
// see if it went over / under
|
// see if it went over / under
|
||||||
|
|
@ -901,6 +903,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
||||||
&& (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ
|
&& (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ
|
||||||
|| tmthing->type == MT_BANANA || tmthing->type == MT_EGGMANITEM || tmthing->type == MT_BALLHOG
|
|| tmthing->type == MT_BANANA || tmthing->type == MT_EGGMANITEM || tmthing->type == MT_BALLHOG
|
||||||
|| tmthing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || tmthing->type == MT_SINK
|
|| tmthing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || tmthing->type == MT_SINK
|
||||||
|
|| tmthing->type == MT_GARDENTOP
|
||||||
|| (tmthing->type == MT_PLAYER)))
|
|| (tmthing->type == MT_PLAYER)))
|
||||||
{
|
{
|
||||||
// see if it went over / under
|
// see if it went over / under
|
||||||
|
|
@ -915,6 +918,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
||||||
&& (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ
|
&& (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ
|
||||||
|| thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG
|
|| thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG
|
||||||
|| thing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || thing->type == MT_SINK
|
|| thing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || thing->type == MT_SINK
|
||||||
|
|| thing->type == MT_GARDENTOP
|
||||||
|| (thing->type == MT_PLAYER)))
|
|| (thing->type == MT_PLAYER)))
|
||||||
{
|
{
|
||||||
// see if it went over / under
|
// see if it went over / under
|
||||||
|
|
@ -932,7 +936,8 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
||||||
return BMIT_CONTINUE;
|
return BMIT_CONTINUE;
|
||||||
|
|
||||||
if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ
|
if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ
|
||||||
|| tmthing->type == MT_ORBINAUT_SHIELD || tmthing->type == MT_JAWZ_SHIELD)
|
|| tmthing->type == MT_ORBINAUT_SHIELD || tmthing->type == MT_JAWZ_SHIELD
|
||||||
|
|| tmthing->type == MT_GARDENTOP)
|
||||||
{
|
{
|
||||||
// see if it went over / under
|
// see if it went over / under
|
||||||
if (tmthing->z > thing->z + thing->height)
|
if (tmthing->z > thing->z + thing->height)
|
||||||
|
|
@ -943,7 +948,8 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
||||||
return Obj_OrbinautJawzCollide(tmthing, thing) ? BMIT_CONTINUE : BMIT_ABORT;
|
return Obj_OrbinautJawzCollide(tmthing, thing) ? BMIT_CONTINUE : BMIT_ABORT;
|
||||||
}
|
}
|
||||||
else if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ
|
else if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ
|
||||||
|| thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD)
|
|| thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD
|
||||||
|
|| thing->type == MT_GARDENTOP)
|
||||||
{
|
{
|
||||||
// see if it went over / under
|
// see if it went over / under
|
||||||
if (tmthing->z > thing->z + thing->height)
|
if (tmthing->z > thing->z + thing->height)
|
||||||
|
|
@ -1940,7 +1946,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thing->player && P_CheckSolidFFloorSurface(thing->player, rover))
|
if (P_CheckSolidFFloorSurface(thing, rover))
|
||||||
;
|
;
|
||||||
else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))
|
else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))
|
||||||
;
|
;
|
||||||
|
|
@ -2354,11 +2360,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||||
fixed_t tryx = thiscam->x;
|
fixed_t tryx = thiscam->x;
|
||||||
fixed_t tryy = thiscam->y;
|
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
|
if (!(players[displayplayers[i]].pflags & PF_NOCONTEST)) // Time Over should not clip through walls
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
floatok = true;
|
floatok = true;
|
||||||
thiscam->floorz = thiscam->z;
|
thiscam->floorz = thiscam->z;
|
||||||
|
|
@ -2524,9 +2526,7 @@ static boolean P_WaterRunning(mobj_t *thing)
|
||||||
|
|
||||||
static boolean P_WaterStepUp(mobj_t *thing)
|
static boolean P_WaterStepUp(mobj_t *thing)
|
||||||
{
|
{
|
||||||
player_t *player = thing->player;
|
return (thing->waterskip > 0 || P_WaterRunning(thing));
|
||||||
return (player && player->waterskip) ||
|
|
||||||
P_WaterRunning(thing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_t P_BaseStepUp(void)
|
fixed_t P_BaseStepUp(void)
|
||||||
|
|
@ -2844,6 +2844,11 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||||
thing->terrain = NULL;
|
thing->terrain = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thing->player && K_IsRidingFloatingTop(thing->player))
|
||||||
|
{
|
||||||
|
stairjank = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: slope step down (even up) has some false
|
/* FIXME: slope step down (even up) has some false
|
||||||
positives, so just ignore them entirely. */
|
positives, so just ignore them entirely. */
|
||||||
if (stairjank && !oldslope && !thing->standingslope &&
|
if (stairjank && !oldslope && !thing->standingslope &&
|
||||||
|
|
|
||||||
|
|
@ -777,7 +777,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||||
if (!(rover->flags & FF_EXISTS))
|
if (!(rover->flags & FF_EXISTS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mobj->player && P_CheckSolidFFloorSurface(mobj->player, rover))
|
if (P_CheckSolidFFloorSurface(mobj, rover))
|
||||||
;
|
;
|
||||||
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|
||||||
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
|
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
|
||||||
|
|
@ -821,7 +821,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||||
if (!(rover->flags & FF_EXISTS))
|
if (!(rover->flags & FF_EXISTS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mobj->player && P_CheckSolidFFloorSurface(mobj->player, rover))
|
if (P_CheckSolidFFloorSurface(mobj, rover))
|
||||||
;
|
;
|
||||||
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|
||||||
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
|
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
|
||||||
|
|
|
||||||
370
src/p_mobj.c
370
src/p_mobj.c
|
|
@ -1105,6 +1105,11 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mo->waterskip > 0)
|
||||||
|
{
|
||||||
|
gravityadd = (4*gravityadd)/3;
|
||||||
|
}
|
||||||
|
|
||||||
if (mo->player)
|
if (mo->player)
|
||||||
{
|
{
|
||||||
if (mo->flags2 & MF2_OBJECTFLIP)
|
if (mo->flags2 & MF2_OBJECTFLIP)
|
||||||
|
|
@ -1118,11 +1123,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
||||||
P_PlayerFlip(mo);
|
P_PlayerFlip(mo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mo->player->waterskip)
|
|
||||||
{
|
|
||||||
gravityadd = (4*gravityadd)/3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mo->player->trickpanel >= 2)
|
if (mo->player->trickpanel >= 2)
|
||||||
{
|
{
|
||||||
gravityadd = (5*gravityadd)/2;
|
gravityadd = (5*gravityadd)/2;
|
||||||
|
|
@ -1133,7 +1133,11 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
||||||
gravityadd = FixedMul(TUMBLEGRAVITY, gravityadd);
|
gravityadd = FixedMul(TUMBLEGRAVITY, gravityadd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mo->player->fastfall != 0)
|
if (K_IsHoldingDownTop(mo->player))
|
||||||
|
{
|
||||||
|
gravityadd = (5*gravityadd)/2;
|
||||||
|
}
|
||||||
|
else if (mo->player->fastfall != 0)
|
||||||
{
|
{
|
||||||
// Fast falling
|
// Fast falling
|
||||||
gravityadd *= 4;
|
gravityadd *= 4;
|
||||||
|
|
@ -1726,8 +1730,7 @@ void P_XYMovement(mobj_t *mo)
|
||||||
|
|
||||||
//{ SRB2kart - Orbinaut, Ballhog
|
//{ SRB2kart - Orbinaut, Ballhog
|
||||||
// Bump sparks
|
// Bump sparks
|
||||||
if (mo->type == MT_ORBINAUT || mo->type == MT_BALLHOG
|
if (mo->type == MT_ORBINAUT || mo->type == MT_BALLHOG)
|
||||||
|| mo->type == MT_DUELBOMB)
|
|
||||||
{
|
{
|
||||||
mobj_t *fx;
|
mobj_t *fx;
|
||||||
fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP);
|
fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP);
|
||||||
|
|
@ -1741,6 +1744,7 @@ void P_XYMovement(mobj_t *mo)
|
||||||
switch (mo->type)
|
switch (mo->type)
|
||||||
{
|
{
|
||||||
case MT_ORBINAUT: // Orbinaut speed decreasing
|
case MT_ORBINAUT: // Orbinaut speed decreasing
|
||||||
|
case MT_GARDENTOP:
|
||||||
if (mo->health > 1)
|
if (mo->health > 1)
|
||||||
{
|
{
|
||||||
S_StartSound(mo, mo->info->attacksound);
|
S_StartSound(mo, mo->info->attacksound);
|
||||||
|
|
@ -1945,7 +1949,7 @@ void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype)
|
||||||
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
|
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||||
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
|
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||||
|
|
||||||
if (mo->player && P_CheckSolidFFloorSurface(mo->player, rover)) // only the player should stand on lava or run on water
|
if (P_CheckSolidFFloorSurface(mo, rover)) // only the player should stand on lava or run on water
|
||||||
;
|
;
|
||||||
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
|
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -2089,7 +2093,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
|
||||||
I_Assert(mo != NULL);
|
I_Assert(mo != NULL);
|
||||||
I_Assert(!P_MobjWasRemoved(mo));
|
I_Assert(!P_MobjWasRemoved(mo));
|
||||||
|
|
||||||
if (mo->player && mo->player->cheats & PC_GODMODE)
|
if (mo->player && mo->player->pflags & PF_GODMODE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (((mo->z <= mo->subsector->sector->floorheight
|
if (((mo->z <= mo->subsector->sector->floorheight
|
||||||
|
|
@ -2104,11 +2108,18 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean P_CheckSolidLava(ffloor_t *rover)
|
boolean P_CheckSolidLava(mobj_t *mobj, ffloor_t *rover)
|
||||||
{
|
{
|
||||||
|
if (mobj->player == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
|
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
|
||||||
&& !(rover->master->flags & ML_BLOCKPLAYERS))
|
&& !(rover->master->flags & ML_BLOCKPLAYERS))
|
||||||
return true;
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2186,18 +2197,6 @@ boolean P_ZMovement(mobj_t *mo)
|
||||||
case MT_BIGTUMBLEWEED:
|
case MT_BIGTUMBLEWEED:
|
||||||
case MT_LITTLETUMBLEWEED:
|
case MT_LITTLETUMBLEWEED:
|
||||||
case MT_SHELL:
|
case MT_SHELL:
|
||||||
// SRB2kart stuff that should die in pits
|
|
||||||
// Shouldn't stop moving along the Z if there's no speed though!
|
|
||||||
case MT_EGGMANITEM:
|
|
||||||
case MT_BANANA:
|
|
||||||
case MT_ORBINAUT:
|
|
||||||
case MT_JAWZ:
|
|
||||||
case MT_BALLHOG:
|
|
||||||
case MT_SSMINE:
|
|
||||||
case MT_LANDMINE:
|
|
||||||
case MT_DROPTARGET:
|
|
||||||
case MT_BUBBLESHIELDTRAP:
|
|
||||||
case MT_DUELBOMB:
|
|
||||||
// Remove stuff from death pits.
|
// Remove stuff from death pits.
|
||||||
if (P_CheckDeathPitCollide(mo))
|
if (P_CheckDeathPitCollide(mo))
|
||||||
{
|
{
|
||||||
|
|
@ -2279,6 +2278,17 @@ boolean P_ZMovement(mobj_t *mo)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
// SRB2kart stuff that should die in pits
|
||||||
|
// Shouldn't stop moving along the Z if there's no speed though!
|
||||||
|
if (P_CanDeleteKartItem(mo->type))
|
||||||
|
{
|
||||||
|
// Remove stuff from death pits.
|
||||||
|
if (P_CheckDeathPitCollide(mo))
|
||||||
|
{
|
||||||
|
P_RemoveMobj(mo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3087,31 +3097,115 @@ boolean P_SceneryZMovement(mobj_t *mo)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// P_CanRunOnWater
|
// P_CanRunOnWater
|
||||||
//
|
//
|
||||||
// Returns true if player can waterrun on the 3D floor
|
// Returns true if player can water run on a 3D floor
|
||||||
//
|
//
|
||||||
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
|
boolean P_CanRunOnWater(mobj_t *mobj, ffloor_t *rover)
|
||||||
{
|
{
|
||||||
boolean flip = player->mo->eflags & MFE_VERTICALFLIP;
|
const boolean flip = (mobj->eflags & MFE_VERTICALFLIP);
|
||||||
fixed_t surfaceheight = flip ? player->mo->waterbottom : player->mo->watertop;
|
player_t *player = mobj->player;
|
||||||
fixed_t playerbottom = flip ? (player->mo->z + player->mo->height) : player->mo->z;
|
|
||||||
fixed_t clip = flip ? (surfaceheight - playerbottom) : (playerbottom - surfaceheight);
|
|
||||||
fixed_t span = player->mo->watertop - player->mo->waterbottom;
|
|
||||||
|
|
||||||
return
|
fixed_t surfaceheight = INT32_MAX;
|
||||||
clip > -(player->mo->height / 2) &&
|
fixed_t surfDiff = INT32_MAX;
|
||||||
span > player->mo->height &&
|
|
||||||
player->speed / 5 > abs(player->mo->momz) &&
|
fixed_t floorheight = INT32_MAX;
|
||||||
player->speed > K_GetKartSpeed(player, false, false) &&
|
fixed_t floorDiff = INT32_MAX;
|
||||||
K_WaterRun(player) &&
|
|
||||||
(rover->flags & FF_SWIMMABLE);
|
fixed_t mobjbottom = INT32_MAX;
|
||||||
|
fixed_t maxStep = INT32_MAX;
|
||||||
|
boolean doifit = false;
|
||||||
|
|
||||||
|
pslope_t *waterSlope = NULL;
|
||||||
|
angle_t ourZAng = 0;
|
||||||
|
angle_t waterZAng = 0;
|
||||||
|
|
||||||
|
if (rover == NULL)
|
||||||
|
{
|
||||||
|
// No rover.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(rover->flags & FF_SWIMMABLE))
|
||||||
|
{
|
||||||
|
// It's not even a water FOF.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player != NULL
|
||||||
|
&& player->carry != CR_NONE) // Special carry state.
|
||||||
|
{
|
||||||
|
// No good player state.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (P_IsObjectOnGround(mobj) == false)
|
||||||
|
{
|
||||||
|
// Don't allow jumping onto water to start a water run.
|
||||||
|
// (Already water running still counts as being on the ground.)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (K_WaterRun(mobj) == false)
|
||||||
|
{
|
||||||
|
// Basic conditions for enabling water run.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mobj->standingslope != NULL)
|
||||||
|
{
|
||||||
|
ourZAng = mobj->standingslope->zangle;
|
||||||
|
}
|
||||||
|
|
||||||
|
waterSlope = (flip ? *rover->b_slope : *rover->t_slope);
|
||||||
|
if (waterSlope != NULL)
|
||||||
|
{
|
||||||
|
waterZAng = waterSlope->zangle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ourZAng != waterZAng)
|
||||||
|
{
|
||||||
|
// The surface slopes are different.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
surfaceheight = flip ? P_GetFFloorBottomZAt(rover, mobj->x, mobj->y) : P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
||||||
|
mobjbottom = flip ? (mobj->z + mobj->height) : mobj->z;
|
||||||
|
|
||||||
|
doifit = flip ? (surfaceheight - mobj->floorz >= mobj->height) : (mobj->ceilingz - surfaceheight >= mobj->height);
|
||||||
|
|
||||||
|
if (!doifit)
|
||||||
|
{
|
||||||
|
// Object can't fit in this space.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxStep = P_GetThingStepUp(mobj);
|
||||||
|
|
||||||
|
surfDiff = flip ? (surfaceheight - mobjbottom) : (mobjbottom - surfaceheight);
|
||||||
|
if (surfDiff <= maxStep && surfDiff >= 0)
|
||||||
|
{
|
||||||
|
// We start water run IF we can step-down!
|
||||||
|
floorheight = flip ? P_GetSectorCeilingZAt(mobj->subsector->sector, mobj->x, mobj->y) : P_GetSectorFloorZAt(mobj->subsector->sector, mobj->x, mobj->y);
|
||||||
|
floorDiff = flip ? (floorheight - mobjbottom) : (mobjbottom - floorheight);
|
||||||
|
if (floorDiff <= maxStep && floorDiff >= 0)
|
||||||
|
{
|
||||||
|
// ... but NOT if real floor is in range.
|
||||||
|
// FIXME: Count solid FOFs in this check
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover)
|
boolean P_CheckSolidFFloorSurface(mobj_t *mobj, ffloor_t *rover)
|
||||||
{
|
{
|
||||||
return P_CheckSolidLava(rover) ||
|
return P_CheckSolidLava(mobj, rover) ||
|
||||||
P_CanRunOnWater(player, rover);
|
P_CanRunOnWater(mobj, rover);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -3133,6 +3227,8 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||||
boolean wasgroundpounding = false;
|
boolean wasgroundpounding = false;
|
||||||
fixed_t top2 = P_GetSectorCeilingZAt(sector, mobj->x, mobj->y);
|
fixed_t top2 = P_GetSectorCeilingZAt(sector, mobj->x, mobj->y);
|
||||||
fixed_t bot2 = P_GetSectorFloorZAt(sector, mobj->x, mobj->y);
|
fixed_t bot2 = P_GetSectorFloorZAt(sector, mobj->x, mobj->y);
|
||||||
|
pslope_t *topslope = NULL;
|
||||||
|
pslope_t *bottomslope = NULL;
|
||||||
|
|
||||||
// Default if no water exists.
|
// Default if no water exists.
|
||||||
mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT;
|
mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT;
|
||||||
|
|
@ -3175,6 +3271,9 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||||
mobj->watertop = topheight;
|
mobj->watertop = topheight;
|
||||||
mobj->waterbottom = bottomheight;
|
mobj->waterbottom = bottomheight;
|
||||||
|
|
||||||
|
topslope = *rover->t_slope;
|
||||||
|
bottomslope = *rover->b_slope;
|
||||||
|
|
||||||
// Just touching the water?
|
// Just touching the water?
|
||||||
if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - height < bottomheight)
|
if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - height < bottomheight)
|
||||||
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + height > topheight))
|
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + height > topheight))
|
||||||
|
|
@ -3212,13 +3311,28 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||||
mobj->watertop = mobj->z;
|
mobj->watertop = mobj->z;
|
||||||
mobj->waterbottom = mobj->z - height;
|
mobj->waterbottom = mobj->z - height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
topslope = bottomslope = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spectators and dead players don't get to do any of the things after this.
|
if (P_IsObjectOnGround(mobj) == true)
|
||||||
if (p && (p->spectator || p->playerstate != PST_LIVE))
|
|
||||||
{
|
{
|
||||||
return;
|
mobj->waterskip = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
// Spectators and dead players don't get to do any of the things after this.
|
||||||
|
if (p->spectator || p->playerstate != PST_LIVE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mobj->flags & MF_APPLYTERRAIN)
|
||||||
|
{
|
||||||
|
K_SpawnWaterRunParticles(mobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The rest of this code only executes on a water state change.
|
// The rest of this code only executes on a water state change.
|
||||||
|
|
@ -3227,20 +3341,21 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p && !p->waterskip &&
|
if (p != NULL
|
||||||
p->curshield != KSHIELD_BUBBLE && wasinwater)
|
&& p->curshield != KSHIELD_BUBBLE
|
||||||
|
&& mobj->waterskip == 0
|
||||||
|
&& wasinwater)
|
||||||
{
|
{
|
||||||
|
// Play the gasp sound
|
||||||
S_StartSound(mobj, sfx_s3k38);
|
S_StartSound(mobj, sfx_s3k38);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((p) // Players
|
if (mobj->flags & MF_APPLYTERRAIN)
|
||||||
|| (mobj->flags & MF_PUSHABLE) // Pushables
|
|
||||||
|| ((mobj->info->flags & MF_PUSHABLE) && mobj->fuse) // Previously pushable, might be moving still
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
fixed_t waterZ = INT32_MAX;
|
fixed_t waterZ = INT32_MAX;
|
||||||
fixed_t solidZ = INT32_MAX;
|
fixed_t solidZ = INT32_MAX;
|
||||||
fixed_t diff = INT32_MAX;
|
fixed_t diff = INT32_MAX;
|
||||||
|
INT32 waterDelta = 0;
|
||||||
|
|
||||||
fixed_t thingZ = INT32_MAX;
|
fixed_t thingZ = INT32_MAX;
|
||||||
boolean splashValid = false;
|
boolean splashValid = false;
|
||||||
|
|
@ -3249,11 +3364,19 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||||
{
|
{
|
||||||
waterZ = mobj->waterbottom;
|
waterZ = mobj->waterbottom;
|
||||||
solidZ = mobj->ceilingz;
|
solidZ = mobj->ceilingz;
|
||||||
|
if (bottomslope)
|
||||||
|
{
|
||||||
|
waterDelta = bottomslope->zdelta;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
waterZ = mobj->watertop;
|
waterZ = mobj->watertop;
|
||||||
solidZ = mobj->floorz;
|
solidZ = mobj->floorz;
|
||||||
|
if (topslope)
|
||||||
|
{
|
||||||
|
waterDelta = topslope->zdelta;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diff = waterZ - solidZ;
|
diff = waterZ - solidZ;
|
||||||
|
|
@ -3322,25 +3445,22 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||||
|
|
||||||
splish->destscale = mobj->scale;
|
splish->destscale = mobj->scale;
|
||||||
P_SetScale(splish, mobj->scale);
|
P_SetScale(splish, mobj->scale);
|
||||||
|
|
||||||
|
// skipping stone!
|
||||||
|
if (K_WaterSkip(mobj) == true
|
||||||
|
&& abs(waterDelta) < FRACUNIT/21) // Only on flat water
|
||||||
|
{
|
||||||
|
const fixed_t hop = 5 * mapobjectscale;
|
||||||
|
|
||||||
|
mobj->momx = (4*mobj->momx)/5;
|
||||||
|
mobj->momy = (4*mobj->momy)/5;
|
||||||
|
mobj->momz = hop * P_MobjFlip(mobj);
|
||||||
|
|
||||||
|
mobj->waterskip++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// skipping stone!
|
|
||||||
if (p && p->waterskip < 2
|
|
||||||
&& ((p->speed/3 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water.
|
|
||||||
|| (p->speed > 20*mapobjectscale && p->waterskip)) // Already skipped once, so you can skip once more!
|
|
||||||
&& (splashValid == true))
|
|
||||||
{
|
|
||||||
const fixed_t hop = 5 * mobj->scale;
|
|
||||||
|
|
||||||
mobj->momx = (4*mobj->momx)/5;
|
|
||||||
mobj->momy = (4*mobj->momy)/5;
|
|
||||||
mobj->momz = hop * P_MobjFlip(mobj);
|
|
||||||
|
|
||||||
p->waterskip++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (P_MobjFlip(mobj) * mobj->momz > 0)
|
else
|
||||||
{
|
{
|
||||||
if (splashValid == true && !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side
|
if (splashValid == true && !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side
|
||||||
{
|
{
|
||||||
|
|
@ -3628,7 +3748,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|
||||||
player->karthud[khud_timeovercam] = (2*TICRATE)+1;
|
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);
|
P_ResetCamera(player, thiscam);
|
||||||
}
|
}
|
||||||
|
|
@ -4472,7 +4592,7 @@ mobj_t *P_GetClosestAxis(mobj_t *source)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closestaxis == NULL)
|
if (closestaxis == NULL)
|
||||||
CONS_Debug(DBG_NIGHTS, "ERROR: No axis points found!\n");
|
CONS_Alert(CONS_ERROR, "No axis points found!\n");
|
||||||
|
|
||||||
return closestaxis;
|
return closestaxis;
|
||||||
}
|
}
|
||||||
|
|
@ -4544,7 +4664,7 @@ void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT
|
||||||
|
|
||||||
if (!axis)
|
if (!axis)
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_NIGHTS, "You forgot to put axis points in the map!\n");
|
CONS_Alert(CONS_WARNING, "You forgot to put axis points in the map!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5000,20 +5120,59 @@ cont:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kartitem stuff.
|
// Kartitem stuff.
|
||||||
|
|
||||||
|
// This item is never attached to a player -- it can DIE
|
||||||
|
// unconditionally in death sectors.
|
||||||
|
boolean P_IsKartFieldItem(INT32 type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case MT_BANANA:
|
||||||
|
case MT_EGGMANITEM:
|
||||||
|
case MT_ORBINAUT:
|
||||||
|
case MT_JAWZ:
|
||||||
|
case MT_SSMINE:
|
||||||
|
case MT_LANDMINE:
|
||||||
|
case MT_BALLHOG:
|
||||||
|
case MT_BUBBLESHIELDTRAP:
|
||||||
|
case MT_POGOSPRING:
|
||||||
|
case MT_SINK:
|
||||||
|
case MT_DROPTARGET:
|
||||||
|
case MT_DUELBOMB:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean P_IsKartItem(INT32 type)
|
boolean P_IsKartItem(INT32 type)
|
||||||
{
|
{
|
||||||
if (type == MT_EGGMANITEM || type == MT_EGGMANITEM_SHIELD ||
|
switch (type)
|
||||||
type == MT_BANANA || type == MT_BANANA_SHIELD ||
|
{
|
||||||
type == MT_DROPTARGET || type == MT_DROPTARGET_SHIELD ||
|
case MT_EGGMANITEM_SHIELD:
|
||||||
type == MT_ORBINAUT || type == MT_ORBINAUT_SHIELD ||
|
case MT_BANANA_SHIELD:
|
||||||
type == MT_JAWZ || type == MT_JAWZ_SHIELD ||
|
case MT_DROPTARGET_SHIELD:
|
||||||
type == MT_SSMINE || type == MT_SSMINE_SHIELD ||
|
case MT_ORBINAUT_SHIELD:
|
||||||
type == MT_SINK || type == MT_SINK_SHIELD ||
|
case MT_JAWZ_SHIELD:
|
||||||
type == MT_SPB || type == MT_BALLHOG || type == MT_BUBBLESHIELDTRAP ||
|
case MT_SSMINE_SHIELD:
|
||||||
type == MT_LANDMINE)
|
case MT_SINK_SHIELD:
|
||||||
return true;
|
case MT_SPB:
|
||||||
else
|
case MT_HYUDORO:
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return P_IsKartFieldItem(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This item can die in death sectors. There may be some
|
||||||
|
// special conditions for items that don't switch types...
|
||||||
|
// TODO: just make a general function for things that should
|
||||||
|
// die like this?
|
||||||
|
boolean P_CanDeleteKartItem(INT32 type)
|
||||||
|
{
|
||||||
|
return P_IsKartFieldItem(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when a kart item "thinks"
|
// Called when a kart item "thinks"
|
||||||
|
|
@ -6335,6 +6494,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
|
case MT_GARDENTOP:
|
||||||
case MT_ORBINAUT_SHIELD:
|
case MT_ORBINAUT_SHIELD:
|
||||||
case MT_BANANA_SHIELD:
|
case MT_BANANA_SHIELD:
|
||||||
case MT_EGGMANITEM_SHIELD:
|
case MT_EGGMANITEM_SHIELD:
|
||||||
|
|
@ -6725,11 +6885,13 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
case MT_ORBINAUT:
|
case MT_ORBINAUT:
|
||||||
{
|
{
|
||||||
Obj_OrbinautThink(mobj);
|
Obj_OrbinautThink(mobj);
|
||||||
|
P_MobjCheckWater(mobj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MT_JAWZ:
|
case MT_JAWZ:
|
||||||
{
|
{
|
||||||
Obj_JawzThink(mobj);
|
Obj_JawzThink(mobj);
|
||||||
|
P_MobjCheckWater(mobj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MT_EGGMANITEM:
|
case MT_EGGMANITEM:
|
||||||
|
|
@ -6793,6 +6955,8 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
|
|
||||||
if (mobj->threshold > 0)
|
if (mobj->threshold > 0)
|
||||||
mobj->threshold--;
|
mobj->threshold--;
|
||||||
|
|
||||||
|
P_MobjCheckWater(mobj);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_SINK:
|
case MT_SINK:
|
||||||
|
|
@ -7049,7 +7213,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_TRIPWIREBOOST:
|
case MT_TRIPWIREBOOST: {
|
||||||
|
mobj_t *top;
|
||||||
|
fixed_t newHeight;
|
||||||
|
fixed_t newScale;
|
||||||
|
|
||||||
if (!mobj->target || !mobj->target->health
|
if (!mobj->target || !mobj->target->health
|
||||||
|| !mobj->target->player || !mobj->target->player->tripwireLeniency)
|
|| !mobj->target->player || !mobj->target->player->tripwireLeniency)
|
||||||
{
|
{
|
||||||
|
|
@ -7057,10 +7225,21 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newHeight = mobj->target->height;
|
||||||
|
newScale = mobj->target->scale;
|
||||||
|
|
||||||
|
top = K_GetGardenTop(mobj->target->player);
|
||||||
|
|
||||||
|
if (top)
|
||||||
|
{
|
||||||
|
newHeight += 5 * top->height / 4;
|
||||||
|
newScale = FixedMul(newScale, FixedDiv(newHeight / 2, mobj->target->height));
|
||||||
|
}
|
||||||
|
|
||||||
mobj->angle = K_MomentumAngle(mobj->target);
|
mobj->angle = K_MomentumAngle(mobj->target);
|
||||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height >> 1));
|
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (newHeight / 2));
|
||||||
mobj->destscale = mobj->target->scale;
|
mobj->destscale = newScale;
|
||||||
P_SetScale(mobj, mobj->target->scale);
|
P_SetScale(mobj, newScale);
|
||||||
|
|
||||||
if (mobj->extravalue1)
|
if (mobj->extravalue1)
|
||||||
{
|
{
|
||||||
|
|
@ -7132,6 +7311,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case MT_BOOSTFLAME:
|
case MT_BOOSTFLAME:
|
||||||
if (!mobj->target || !mobj->target->health)
|
if (!mobj->target || !mobj->target->health)
|
||||||
{
|
{
|
||||||
|
|
@ -7703,6 +7883,16 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MT_GARDENTOP:
|
||||||
|
{
|
||||||
|
Obj_GardenTopThink(mobj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MT_GARDENTOPSPARK:
|
||||||
|
{
|
||||||
|
Obj_GardenTopSparkThink(mobj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MT_HYUDORO:
|
case MT_HYUDORO:
|
||||||
{
|
{
|
||||||
Obj_HyudoroThink(mobj);
|
Obj_HyudoroThink(mobj);
|
||||||
|
|
@ -9318,11 +9508,7 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Destroy items sector special
|
// Destroy items sector special
|
||||||
if (mobj->type == MT_BANANA || mobj->type == MT_EGGMANITEM
|
if (P_CanDeleteKartItem(mobj->type))
|
||||||
|| mobj->type == MT_ORBINAUT || mobj->type == MT_BALLHOG
|
|
||||||
|| mobj->type == MT_JAWZ
|
|
||||||
|| mobj->type == MT_SSMINE || mobj->type == MT_BUBBLESHIELDTRAP
|
|
||||||
|| mobj->type == MT_LANDMINE)
|
|
||||||
{
|
{
|
||||||
if (mobj->health > 0 && P_MobjTouchingSectorSpecial(mobj, 4, 7, true))
|
if (mobj->health > 0 && P_MobjTouchingSectorSpecial(mobj, 4, 7, true))
|
||||||
{
|
{
|
||||||
|
|
@ -9749,6 +9935,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
||||||
case MT_BUBBLESHIELD:
|
case MT_BUBBLESHIELD:
|
||||||
case MT_BUBBLESHIELDTRAP:
|
case MT_BUBBLESHIELDTRAP:
|
||||||
case MT_FLAMESHIELD:
|
case MT_FLAMESHIELD:
|
||||||
|
case MT_GARDENTOP:
|
||||||
thing->shadowscale = FRACUNIT;
|
thing->shadowscale = FRACUNIT;
|
||||||
break;
|
break;
|
||||||
case MT_RING:
|
case MT_RING:
|
||||||
|
|
@ -9891,6 +10078,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
mobj->colorized = false;
|
mobj->colorized = false;
|
||||||
|
|
||||||
mobj->hitlag = 0;
|
mobj->hitlag = 0;
|
||||||
|
mobj->waterskip = 0;
|
||||||
|
|
||||||
// Set shadowscale here, before spawn hook so that Lua can change it
|
// Set shadowscale here, before spawn hook so that Lua can change it
|
||||||
P_DefaultMobjShadowScale(mobj);
|
P_DefaultMobjShadowScale(mobj);
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ typedef enum
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MF2_AXIS = 1, // It's a NiGHTS axis! (For faster checking)
|
MF2_AXIS = 1, // It's a NiGHTS axis! (For faster checking)
|
||||||
MF2_TWOD = 1<<1, // Moves like it's in a 2D level
|
// free: 1<<1
|
||||||
MF2_DONTRESPAWN = 1<<2, // Don't respawn this object!
|
MF2_DONTRESPAWN = 1<<2, // Don't respawn this object!
|
||||||
// free: 1<<3
|
// free: 1<<3
|
||||||
MF2_AUTOMATIC = 1<<4, // Thrown ring has automatic properties
|
MF2_AUTOMATIC = 1<<4, // Thrown ring has automatic properties
|
||||||
|
|
@ -409,6 +409,7 @@ typedef struct mobj_s
|
||||||
struct mobj_s *terrainOverlay; // Overlay sprite object for terrain
|
struct mobj_s *terrainOverlay; // Overlay sprite object for terrain
|
||||||
|
|
||||||
INT32 hitlag; // Sal-style hit lag, straight from Captain Fetch's jowls
|
INT32 hitlag; // Sal-style hit lag, straight from Captain Fetch's jowls
|
||||||
|
UINT8 waterskip; // Water skipping counter
|
||||||
|
|
||||||
INT32 dispoffset;
|
INT32 dispoffset;
|
||||||
|
|
||||||
|
|
@ -499,7 +500,9 @@ void P_RunCachedActions(void);
|
||||||
void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
|
void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
|
||||||
|
|
||||||
// kartitem stuff: Returns true if the specified 'type' is one of the kart item constants we want in the kitemcap list
|
// kartitem stuff: Returns true if the specified 'type' is one of the kart item constants we want in the kitemcap list
|
||||||
|
boolean P_IsKartFieldItem(INT32 type);
|
||||||
boolean P_IsKartItem(INT32 type);
|
boolean P_IsKartItem(INT32 type);
|
||||||
|
boolean P_CanDeleteKartItem(INT32 type);
|
||||||
void P_AddKartItem(mobj_t *thing); // needs to be called in k_kart.c
|
void P_AddKartItem(mobj_t *thing); // needs to be called in k_kart.c
|
||||||
void P_RunKartItems(void);
|
void P_RunKartItems(void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -280,7 +280,6 @@ static void P_NetArchivePlayers(void)
|
||||||
WRITEINT32(save_p, players[i].underwatertilt);
|
WRITEINT32(save_p, players[i].underwatertilt);
|
||||||
|
|
||||||
WRITEFIXED(save_p, players[i].offroad);
|
WRITEFIXED(save_p, players[i].offroad);
|
||||||
WRITEUINT8(save_p, players[i].waterskip);
|
|
||||||
|
|
||||||
WRITEUINT16(save_p, players[i].tiregrease);
|
WRITEUINT16(save_p, players[i].tiregrease);
|
||||||
WRITEUINT16(save_p, players[i].springstars);
|
WRITEUINT16(save_p, players[i].springstars);
|
||||||
|
|
@ -379,6 +378,8 @@ static void P_NetArchivePlayers(void)
|
||||||
WRITEUINT8(save_p, players[i].kickstartaccel);
|
WRITEUINT8(save_p, players[i].kickstartaccel);
|
||||||
|
|
||||||
WRITEUINT8(save_p, players[i].stairjank);
|
WRITEUINT8(save_p, players[i].stairjank);
|
||||||
|
WRITEUINT8(save_p, players[i].topdriftheld);
|
||||||
|
WRITEUINT8(save_p, players[i].topinfirst);
|
||||||
|
|
||||||
WRITEUINT8(save_p, players[i].shrinkLaserDelay);
|
WRITEUINT8(save_p, players[i].shrinkLaserDelay);
|
||||||
|
|
||||||
|
|
@ -394,6 +395,7 @@ static void P_NetArchivePlayers(void)
|
||||||
WRITEUINT32(save_p, players[i].respawn.distanceleft);
|
WRITEUINT32(save_p, players[i].respawn.distanceleft);
|
||||||
WRITEUINT32(save_p, players[i].respawn.dropdash);
|
WRITEUINT32(save_p, players[i].respawn.dropdash);
|
||||||
WRITEUINT8(save_p, players[i].respawn.truedeath);
|
WRITEUINT8(save_p, players[i].respawn.truedeath);
|
||||||
|
WRITEUINT8(save_p, players[i].respawn.manual);
|
||||||
|
|
||||||
// botvars_t
|
// botvars_t
|
||||||
WRITEUINT8(save_p, players[i].botvars.difficulty);
|
WRITEUINT8(save_p, players[i].botvars.difficulty);
|
||||||
|
|
@ -577,7 +579,6 @@ static void P_NetUnArchivePlayers(void)
|
||||||
players[i].underwatertilt = READINT32(save_p);
|
players[i].underwatertilt = READINT32(save_p);
|
||||||
|
|
||||||
players[i].offroad = READFIXED(save_p);
|
players[i].offroad = READFIXED(save_p);
|
||||||
players[i].waterskip = READUINT8(save_p);
|
|
||||||
|
|
||||||
players[i].tiregrease = READUINT16(save_p);
|
players[i].tiregrease = READUINT16(save_p);
|
||||||
players[i].springstars = READUINT16(save_p);
|
players[i].springstars = READUINT16(save_p);
|
||||||
|
|
@ -676,6 +677,8 @@ static void P_NetUnArchivePlayers(void)
|
||||||
players[i].kickstartaccel = READUINT8(save_p);
|
players[i].kickstartaccel = READUINT8(save_p);
|
||||||
|
|
||||||
players[i].stairjank = READUINT8(save_p);
|
players[i].stairjank = READUINT8(save_p);
|
||||||
|
players[i].topdriftheld = READUINT8(save_p);
|
||||||
|
players[i].topinfirst = READUINT8(save_p);
|
||||||
|
|
||||||
players[i].shrinkLaserDelay = READUINT8(save_p);
|
players[i].shrinkLaserDelay = READUINT8(save_p);
|
||||||
|
|
||||||
|
|
@ -691,6 +694,7 @@ static void P_NetUnArchivePlayers(void)
|
||||||
players[i].respawn.distanceleft = READUINT32(save_p);
|
players[i].respawn.distanceleft = READUINT32(save_p);
|
||||||
players[i].respawn.dropdash = READUINT32(save_p);
|
players[i].respawn.dropdash = READUINT32(save_p);
|
||||||
players[i].respawn.truedeath = READUINT8(save_p);
|
players[i].respawn.truedeath = READUINT8(save_p);
|
||||||
|
players[i].respawn.manual = READUINT8(save_p);
|
||||||
|
|
||||||
// botvars_t
|
// botvars_t
|
||||||
players[i].botvars.difficulty = READUINT8(save_p);
|
players[i].botvars.difficulty = READUINT8(save_p);
|
||||||
|
|
@ -1638,6 +1642,7 @@ typedef enum
|
||||||
MD2_ITNEXT = 1<<27,
|
MD2_ITNEXT = 1<<27,
|
||||||
MD2_LASTMOMZ = 1<<28,
|
MD2_LASTMOMZ = 1<<28,
|
||||||
MD2_TERRAIN = 1<<29,
|
MD2_TERRAIN = 1<<29,
|
||||||
|
MD2_WATERSKIP = 1<<30,
|
||||||
} mobj_diff2_t;
|
} mobj_diff2_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
@ -1872,6 +1877,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
||||||
}
|
}
|
||||||
if (mobj->hitlag)
|
if (mobj->hitlag)
|
||||||
diff2 |= MD2_HITLAG;
|
diff2 |= MD2_HITLAG;
|
||||||
|
if (mobj->waterskip)
|
||||||
|
diff2 |= MD2_WATERSKIP;
|
||||||
if (mobj->dispoffset)
|
if (mobj->dispoffset)
|
||||||
diff2 |= MD2_DISPOFFSET;
|
diff2 |= MD2_DISPOFFSET;
|
||||||
if (mobj == waypointcap)
|
if (mobj == waypointcap)
|
||||||
|
|
@ -2082,6 +2089,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
||||||
{
|
{
|
||||||
WRITEINT32(save_p, mobj->hitlag);
|
WRITEINT32(save_p, mobj->hitlag);
|
||||||
}
|
}
|
||||||
|
if (diff2 & MD2_WATERSKIP)
|
||||||
|
{
|
||||||
|
WRITEUINT8(save_p, mobj->waterskip);
|
||||||
|
}
|
||||||
if (diff2 & MD2_DISPOFFSET)
|
if (diff2 & MD2_DISPOFFSET)
|
||||||
{
|
{
|
||||||
WRITEINT32(save_p, mobj->dispoffset);
|
WRITEINT32(save_p, mobj->dispoffset);
|
||||||
|
|
@ -3191,6 +3202,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
||||||
{
|
{
|
||||||
mobj->hitlag = READINT32(save_p);
|
mobj->hitlag = READINT32(save_p);
|
||||||
}
|
}
|
||||||
|
if (diff2 & MD2_WATERSKIP)
|
||||||
|
{
|
||||||
|
mobj->waterskip = READUINT8(save_p);
|
||||||
|
}
|
||||||
if (diff2 & MD2_DISPOFFSET)
|
if (diff2 & MD2_DISPOFFSET)
|
||||||
{
|
{
|
||||||
mobj->dispoffset = READINT32(save_p);
|
mobj->dispoffset = READINT32(save_p);
|
||||||
|
|
@ -4600,6 +4615,8 @@ static void P_NetArchiveMisc(boolean resending)
|
||||||
WRITEINT16(save_p, task->timer);
|
WRITEINT16(save_p, task->timer);
|
||||||
WRITESTRING(save_p, task->command);
|
WRITESTRING(save_p, task->command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITEUINT32(save_p, cht_debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
||||||
|
|
@ -4764,6 +4781,8 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
||||||
Schedule_Add(basetime, timer, command);
|
Schedule_Add(basetime, timer, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cht_debug = READUINT32(save_p);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
14
src/p_spec.c
14
src/p_spec.c
|
|
@ -2836,16 +2836,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||||
EV_DoCrush(line, crushBothOnce);
|
EV_DoCrush(line, crushBothOnce);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 432: // Enable 2D Mode (Disable if noclimb)
|
|
||||||
if (mo && mo->player)
|
|
||||||
{
|
|
||||||
if (line->flags & ML_NOCLIMB)
|
|
||||||
mo->flags2 &= ~MF2_TWOD;
|
|
||||||
else
|
|
||||||
mo->flags2 |= MF2_TWOD;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 433: // Flip gravity (Flop gravity if noclimb) Works on pushables, too!
|
case 433: // Flip gravity (Flop gravity if noclimb) Works on pushables, too!
|
||||||
if (line->flags & ML_NOCLIMB)
|
if (line->flags & ML_NOCLIMB)
|
||||||
mo->flags2 &= ~MF2_OBJECTFLIP;
|
mo->flags2 &= ~MF2_OBJECTFLIP;
|
||||||
|
|
@ -4426,7 +4416,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
||||||
switch (special)
|
switch (special)
|
||||||
{
|
{
|
||||||
case 1: // Damage (Generic)
|
case 1: // Damage (Generic)
|
||||||
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
if (!K_IsRidingFloatingTop(player) && (roversector || P_MobjReadyToTrigger(player->mo, sector)))
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL);
|
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL);
|
||||||
break;
|
break;
|
||||||
case 2: // Damage (Water) // SRB2kart - These three damage types are now offroad sectors
|
case 2: // Damage (Water) // SRB2kart - These three damage types are now offroad sectors
|
||||||
|
|
@ -4434,7 +4424,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
||||||
case 4: // Damage (Electrical)
|
case 4: // Damage (Electrical)
|
||||||
break;
|
break;
|
||||||
case 5: // Spikes
|
case 5: // Spikes
|
||||||
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
if (!K_IsRidingFloatingTop(player) && (roversector || P_MobjReadyToTrigger(player->mo, sector)))
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL);
|
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL);
|
||||||
break;
|
break;
|
||||||
case 6: // Death Pit (Camera Mod)
|
case 6: // Death Pit (Camera Mod)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
|
||||||
INT32 starpostnum, tic_t starposttime, angle_t starpostangle,
|
INT32 starpostnum, tic_t starposttime, angle_t starpostangle,
|
||||||
fixed_t starpostscale, angle_t drawangle, INT32 flags2)
|
fixed_t starpostscale, angle_t drawangle, INT32 flags2)
|
||||||
{
|
{
|
||||||
const INT32 takeflags2 = MF2_TWOD|MF2_OBJECTFLIP;
|
const INT32 takeflags2 = MF2_OBJECTFLIP;
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
(void)starposttime;
|
(void)starposttime;
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,14 @@ INT32 P_AltFlip(INT32 n, tic_t tics)
|
||||||
return leveltime % (2 * tics) < tics ? n : -(n);
|
return leveltime % (2 * tics) < tics ? n : -(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Please read p_tick.h
|
||||||
|
INT32 P_LerpFlip(INT32 n, tic_t tics)
|
||||||
|
{
|
||||||
|
const tic_t w = 2 * tics;
|
||||||
|
|
||||||
|
return P_AltFlip(((leveltime % w) - tics) * n, w);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// THINKERS
|
// THINKERS
|
||||||
// All thinkers should be allocated by Z_Calloc
|
// All thinkers should be allocated by Z_Calloc
|
||||||
|
|
|
||||||
|
|
@ -35,4 +35,12 @@ mobj_t *P_SetTarget(mobj_t **mo, mobj_t *target); // killough 11/98
|
||||||
INT32 P_AltFlip(INT32 value, tic_t tics);
|
INT32 P_AltFlip(INT32 value, tic_t tics);
|
||||||
#define P_RandomFlip(value) P_AltFlip(value, 1)
|
#define P_RandomFlip(value) P_AltFlip(value, 1)
|
||||||
|
|
||||||
|
// Multiply value back and forth between -(tics) and +(tics).
|
||||||
|
// Example output P_ModulateFlip(2, 2):
|
||||||
|
// Tic: 0 1 2 3 4 5 6 7 8
|
||||||
|
// Val: -4 -2 0 2 4 2 0 -2 -4
|
||||||
|
// A half cycle (one direction) takes 2 * tics.
|
||||||
|
// A full cycle takes 4 * tics.
|
||||||
|
INT32 P_LerpFlip(INT32 value, tic_t tics);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
355
src/p_user.c
355
src/p_user.c
|
|
@ -1801,7 +1801,7 @@ static void P_3dMovement(player_t *player)
|
||||||
// Get the old momentum; this will be needed at the end of the function! -SH
|
// Get the old momentum; this will be needed at the end of the function! -SH
|
||||||
oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
|
oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
|
||||||
|
|
||||||
if (player->stairjank > 8 && leveltime & 3)
|
if ((player->stairjank > 8 && leveltime & 3) || K_IsRidingFloatingTop(player))
|
||||||
{
|
{
|
||||||
movepushangle = K_MomentumAngle(player->mo);
|
movepushangle = K_MomentumAngle(player->mo);
|
||||||
}
|
}
|
||||||
|
|
@ -1884,6 +1884,7 @@ static void P_3dMovement(player_t *player)
|
||||||
if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration...
|
if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration...
|
||||||
movepushforward = FixedMul(movepushforward, player->mo->movefactor);
|
movepushforward = FixedMul(movepushforward, player->mo->movefactor);
|
||||||
|
|
||||||
|
if (player->curshield != KSHIELD_TOP)
|
||||||
{
|
{
|
||||||
INT32 a = K_GetUnderwaterTurnAdjust(player);
|
INT32 a = K_GetUnderwaterTurnAdjust(player);
|
||||||
INT32 adj = 0;
|
INT32 adj = 0;
|
||||||
|
|
@ -1967,6 +1968,24 @@ static void P_3dMovement(player_t *player)
|
||||||
player->mo->momx += totalthrust.x;
|
player->mo->momx += totalthrust.x;
|
||||||
player->mo->momy += totalthrust.y;
|
player->mo->momy += totalthrust.y;
|
||||||
|
|
||||||
|
// Releasing a drift while on the Top translates all your
|
||||||
|
// momentum (and even then some) into whichever direction
|
||||||
|
// you're facing
|
||||||
|
if (onground && player->curshield == KSHIELD_TOP && (K_GetKartButtons(player) & BT_DRIFT) != BT_DRIFT && (player->oldcmd.buttons & BT_DRIFT))
|
||||||
|
{
|
||||||
|
const fixed_t gmin = FRACUNIT/4;
|
||||||
|
const fixed_t gmax = 5*FRACUNIT/2;
|
||||||
|
|
||||||
|
const fixed_t grindfactor = (gmax - gmin) / GARDENTOP_MAXGRINDTIME;
|
||||||
|
const fixed_t grindscale = gmin + (player->topdriftheld * grindfactor);
|
||||||
|
|
||||||
|
const fixed_t speed = R_PointToDist2(0, 0, player->mo->momx, player->mo->momy);
|
||||||
|
|
||||||
|
P_InstaThrust(player->mo, player->mo->angle, FixedMul(speed, grindscale));
|
||||||
|
|
||||||
|
player->topdriftheld = 0;/* reset after release */
|
||||||
|
}
|
||||||
|
|
||||||
if (!onground)
|
if (!onground)
|
||||||
{
|
{
|
||||||
const fixed_t airspeedcap = (50*mapobjectscale);
|
const fixed_t airspeedcap = (50*mapobjectscale);
|
||||||
|
|
@ -2292,100 +2311,6 @@ void P_MovePlayer(player_t *player)
|
||||||
//GAMEPLAY STUFF//
|
//GAMEPLAY STUFF//
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
if (((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height >= player->mo->watertop && player->mo->z <= player->mo->watertop)
|
|
||||||
|| (player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height >= player->mo->waterbottom && player->mo->z <= player->mo->waterbottom))
|
|
||||||
&& (player->speed > runspd)
|
|
||||||
&& player->mo->momz == 0 && player->carry != CR_SLIDING && !player->spectator)
|
|
||||||
{
|
|
||||||
fixed_t playerTopSpeed = K_GetKartSpeed(player, false, false);
|
|
||||||
fixed_t trailScale = FixedMul(FixedDiv(player->speed - runspd, playerTopSpeed - runspd), mapobjectscale);
|
|
||||||
|
|
||||||
if (playerTopSpeed > runspd)
|
|
||||||
trailScale = FixedMul(FixedDiv(player->speed - runspd, playerTopSpeed - runspd), mapobjectscale);
|
|
||||||
else
|
|
||||||
trailScale = mapobjectscale; // Scaling is based off difference between runspeed and top speed
|
|
||||||
|
|
||||||
if (trailScale > 0)
|
|
||||||
{
|
|
||||||
const angle_t forwardangle = K_MomentumAngle(player->mo);
|
|
||||||
const fixed_t playerVisualRadius = player->mo->radius + (8 * player->mo->scale);
|
|
||||||
const size_t numFrames = S_WATERTRAIL8 - S_WATERTRAIL1;
|
|
||||||
const statenum_t curOverlayFrame = S_WATERTRAIL1 + (leveltime % numFrames);
|
|
||||||
const statenum_t curUnderlayFrame = S_WATERTRAILUNDERLAY1 + (leveltime % numFrames);
|
|
||||||
fixed_t x1, x2, y1, y2;
|
|
||||||
mobj_t *water;
|
|
||||||
|
|
||||||
x1 = player->mo->x + player->mo->momx + P_ReturnThrustX(player->mo, forwardangle + ANGLE_90, playerVisualRadius);
|
|
||||||
y1 = player->mo->y + player->mo->momy + P_ReturnThrustY(player->mo, forwardangle + ANGLE_90, playerVisualRadius);
|
|
||||||
x1 = x1 + P_ReturnThrustX(player->mo, forwardangle, playerVisualRadius);
|
|
||||||
y1 = y1 + P_ReturnThrustY(player->mo, forwardangle, playerVisualRadius);
|
|
||||||
|
|
||||||
x2 = player->mo->x + player->mo->momx + P_ReturnThrustX(player->mo, forwardangle - ANGLE_90, playerVisualRadius);
|
|
||||||
y2 = player->mo->y + player->mo->momy + P_ReturnThrustY(player->mo, forwardangle - ANGLE_90, playerVisualRadius);
|
|
||||||
x2 = x2 + P_ReturnThrustX(player->mo, forwardangle, playerVisualRadius);
|
|
||||||
y2 = y2 + P_ReturnThrustY(player->mo, forwardangle, playerVisualRadius);
|
|
||||||
|
|
||||||
// Left
|
|
||||||
// underlay
|
|
||||||
water = P_SpawnMobj(x1, y1,
|
|
||||||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY);
|
|
||||||
P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h);
|
|
||||||
water->destscale = trailScale;
|
|
||||||
water->momx = player->mo->momx;
|
|
||||||
water->momy = player->mo->momy;
|
|
||||||
water->momz = player->mo->momz;
|
|
||||||
P_SetScale(water, trailScale);
|
|
||||||
P_SetMobjState(water, curUnderlayFrame);
|
|
||||||
|
|
||||||
// overlay
|
|
||||||
water = P_SpawnMobj(x1, y1,
|
|
||||||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL);
|
|
||||||
P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h);
|
|
||||||
water->destscale = trailScale;
|
|
||||||
water->momx = player->mo->momx;
|
|
||||||
water->momy = player->mo->momy;
|
|
||||||
water->momz = player->mo->momz;
|
|
||||||
P_SetScale(water, trailScale);
|
|
||||||
P_SetMobjState(water, curOverlayFrame);
|
|
||||||
|
|
||||||
// Right
|
|
||||||
// Underlay
|
|
||||||
water = P_SpawnMobj(x2, y2,
|
|
||||||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY);
|
|
||||||
P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h);
|
|
||||||
water->destscale = trailScale;
|
|
||||||
water->momx = player->mo->momx;
|
|
||||||
water->momy = player->mo->momy;
|
|
||||||
water->momz = player->mo->momz;
|
|
||||||
P_SetScale(water, trailScale);
|
|
||||||
P_SetMobjState(water, curUnderlayFrame);
|
|
||||||
|
|
||||||
// Overlay
|
|
||||||
water = P_SpawnMobj(x2, y2,
|
|
||||||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL);
|
|
||||||
P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h);
|
|
||||||
water->destscale = trailScale;
|
|
||||||
water->momx = player->mo->momx;
|
|
||||||
water->momy = player->mo->momy;
|
|
||||||
water->momz = player->mo->momz;
|
|
||||||
P_SetScale(water, trailScale);
|
|
||||||
P_SetMobjState(water, curOverlayFrame);
|
|
||||||
|
|
||||||
if (!S_SoundPlaying(player->mo, sfx_s3kdbs))
|
|
||||||
{
|
|
||||||
const INT32 volume = (min(trailScale, FRACUNIT) * 255) / FRACUNIT;
|
|
||||||
S_StartSoundAtVolume(player->mo, sfx_s3kdbs, volume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Little water sound while touching water - just a nicety.
|
|
||||||
if ((player->mo->eflags & MFE_TOUCHWATER) && !(player->mo->eflags & MFE_UNDERWATER) && !player->spectator)
|
|
||||||
{
|
|
||||||
if (P_RandomChance(PR_BUBBLE, FRACUNIT/2) && leveltime % TICRATE == 0)
|
|
||||||
S_StartSound(player->mo, sfx_floush);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
//SPINNING AND SPINDASHING//
|
//SPINNING AND SPINDASHING//
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
|
|
@ -3068,10 +2993,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
mobj_t *mo;
|
mobj_t *mo;
|
||||||
fixed_t f1, f2;
|
fixed_t f1, f2;
|
||||||
fixed_t speed;
|
fixed_t speed;
|
||||||
#ifndef NOCLIPCAM
|
|
||||||
boolean cameranoclip;
|
|
||||||
subsector_t *newsubsec;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fixed_t playerScale = FixedDiv(player->mo->scale, mapobjectscale);
|
fixed_t playerScale = FixedDiv(player->mo->scale, mapobjectscale);
|
||||||
fixed_t scaleDiff = playerScale - FRACUNIT;
|
fixed_t scaleDiff = playerScale - FRACUNIT;
|
||||||
|
|
@ -3129,12 +3050,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
return true;
|
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
|
if ((player->pflags & PF_NOCONTEST) && (gametyperules & GTR_CIRCUIT)) // 1 for momentum keep, 2 for turnaround
|
||||||
timeover = (player->karthud[khud_timeovercam] > 2*TICRATE ? 2 : 1);
|
timeover = (player->karthud[khud_timeovercam] > 2*TICRATE ? 2 : 1);
|
||||||
else
|
else
|
||||||
|
|
@ -3263,6 +3178,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The Top is Big Large so zoom out */
|
||||||
|
if (player->curshield == KSHIELD_TOP)
|
||||||
|
{
|
||||||
|
camdist += 40 * mapobjectscale;
|
||||||
|
camheight += 40 * mapobjectscale;
|
||||||
|
}
|
||||||
|
|
||||||
if (!resetcalled && (leveltime >= introtime && timeover != 2)
|
if (!resetcalled && (leveltime >= introtime && timeover != 2)
|
||||||
&& (t_cam_rotate[num] != -42))
|
&& (t_cam_rotate[num] != -42))
|
||||||
{
|
{
|
||||||
|
|
@ -3377,204 +3299,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
z = mo->z + pviewheight + distz;
|
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
|
// point viewed by the camera
|
||||||
// this point is just 64 unit forward the player
|
// this point is just 64 unit forward the player
|
||||||
dist = 64*cameraScale;
|
dist = 64*cameraScale;
|
||||||
|
|
@ -4660,3 +4384,28 @@ boolean P_PlayerFullbright(player_t *player)
|
||||||
{
|
{
|
||||||
return (player->invincibilitytimer > 0);
|
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);
|
||||||
|
player->respawn.manual = false;
|
||||||
|
|
||||||
|
if (P_MobjWasRemoved(thing))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
thing->flags &= ~(MF_NOCLIP);
|
||||||
|
|
||||||
|
thing->destscale = mapobjectscale;
|
||||||
|
P_SetScale(thing, thing->destscale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
34
src/r_main.c
34
src/r_main.c
|
|
@ -915,39 +915,9 @@ void R_ApplyViewMorph(int s)
|
||||||
|
|
||||||
end = width * height;
|
end = width * height;
|
||||||
|
|
||||||
#if 0
|
for (p = 0; p < end; p++)
|
||||||
if (cv_debug & DBG_VIEWMORPH)
|
|
||||||
{
|
{
|
||||||
UINT8 border = 32;
|
tmpscr[p] = srcscr[viewmorph[s].scrmap[p]];
|
||||||
UINT8 grid = 160;
|
|
||||||
INT32 ws = vid.width / 4;
|
|
||||||
INT32 hs = vid.width * (vid.height / 4);
|
|
||||||
|
|
||||||
memcpy(tmpscr, srcscr, vid.width*vid.height);
|
|
||||||
for (p = 0; p < vid.width; p++)
|
|
||||||
{
|
|
||||||
tmpscr[viewmorph.scrmap[p]] = border;
|
|
||||||
tmpscr[viewmorph.scrmap[p + hs]] = grid;
|
|
||||||
tmpscr[viewmorph.scrmap[p + hs*2]] = grid;
|
|
||||||
tmpscr[viewmorph.scrmap[p + hs*3]] = grid;
|
|
||||||
tmpscr[viewmorph.scrmap[end - 1 - p]] = border;
|
|
||||||
}
|
|
||||||
for (p = vid.width; p < end; p += vid.width)
|
|
||||||
{
|
|
||||||
tmpscr[viewmorph.scrmap[p]] = border;
|
|
||||||
tmpscr[viewmorph.scrmap[p + ws]] = grid;
|
|
||||||
tmpscr[viewmorph.scrmap[p + ws*2]] = grid;
|
|
||||||
tmpscr[viewmorph.scrmap[p + ws*3]] = grid;
|
|
||||||
tmpscr[viewmorph.scrmap[end - 1 - p]] = border;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
for (p = 0; p < end; p++)
|
|
||||||
{
|
|
||||||
tmpscr[p] = srcscr[viewmorph[s].scrmap[p]];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VID_BlitLinearScreen(tmpscr, srcscr,
|
VID_BlitLinearScreen(tmpscr, srcscr,
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ static angle_t R_PlayerSpriteRotation(player_t *player, player_t *viewPlayer)
|
||||||
|
|
||||||
angle_t rollAngle = 0;
|
angle_t rollAngle = 0;
|
||||||
|
|
||||||
|
mobj_t *top = K_GetGardenTop(player);
|
||||||
|
|
||||||
if (player->mo->eflags & MFE_UNDERWATER)
|
if (player->mo->eflags & MFE_UNDERWATER)
|
||||||
{
|
{
|
||||||
rollAngle -= player->underwatertilt;
|
rollAngle -= player->underwatertilt;
|
||||||
|
|
@ -61,6 +63,14 @@ static angle_t R_PlayerSpriteRotation(player_t *player, player_t *viewPlayer)
|
||||||
(17 / player->stairjank));
|
(17 / player->stairjank));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (top)
|
||||||
|
{
|
||||||
|
/* FIXME: why does it not look right at more acute
|
||||||
|
angles without this? There's a related hack to
|
||||||
|
spritexoffset in K_KartPlayerThink. */
|
||||||
|
rollAngle += 3 * (INT32)top->rollangle / 2;
|
||||||
|
}
|
||||||
|
|
||||||
return rollAngle;
|
return rollAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -364,7 +364,7 @@ static void ST_drawDebugInfo(void)
|
||||||
if (!stplyr->mo)
|
if (!stplyr->mo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cv_debug & DBG_BASIC)
|
if (cht_debug & DBG_BASIC)
|
||||||
{
|
{
|
||||||
const fixed_t d = AngleFixed(stplyr->mo->angle);
|
const fixed_t d = AngleFixed(stplyr->mo->angle);
|
||||||
V_DrawRightAlignedString(320, 168, V_MONOSPACE, va("X: %6d", stplyr->mo->x>>FRACBITS));
|
V_DrawRightAlignedString(320, 168, V_MONOSPACE, va("X: %6d", stplyr->mo->x>>FRACBITS));
|
||||||
|
|
@ -375,7 +375,7 @@ static void ST_drawDebugInfo(void)
|
||||||
height = 152;
|
height = 152;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cv_debug & DBG_DETAILED)
|
if (cht_debug & DBG_DETAILED)
|
||||||
{
|
{
|
||||||
//V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield]));
|
//V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield]));
|
||||||
V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT));
|
V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT));
|
||||||
|
|
@ -404,7 +404,7 @@ static void ST_drawDebugInfo(void)
|
||||||
height -= 120;
|
height -= 120;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cv_debug & DBG_RANDOMIZER) // randomizer testing
|
if (cht_debug & DBG_RNG) // randomizer testing
|
||||||
{
|
{
|
||||||
// TODO: this only accounts for the undefined class,
|
// TODO: this only accounts for the undefined class,
|
||||||
// which should be phased out as much as possible anyway.
|
// which should be phased out as much as possible anyway.
|
||||||
|
|
@ -421,7 +421,7 @@ static void ST_drawDebugInfo(void)
|
||||||
height -= 32;
|
height -= 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cv_debug & DBG_MEMORY)
|
if (cht_debug & DBG_MEMORY)
|
||||||
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)));
|
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
// SRB2Kart
|
// SRB2Kart
|
||||||
#include "k_hud.h"
|
#include "k_hud.h"
|
||||||
|
#include "i_time.h"
|
||||||
|
|
||||||
// Each screen is [vid.width*vid.height];
|
// Each screen is [vid.width*vid.height];
|
||||||
UINT8 *screens[5];
|
UINT8 *screens[5];
|
||||||
|
|
@ -1636,6 +1637,14 @@ UINT8 *V_GetStringColormap(INT32 colorflags)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT32 V_DanceYOffset(INT32 counter)
|
||||||
|
{
|
||||||
|
const INT32 duration = 16;
|
||||||
|
const INT32 step = (I_GetTime() + counter) % duration;
|
||||||
|
|
||||||
|
return abs(step - (duration / 2)) - (duration / 4);
|
||||||
|
}
|
||||||
|
|
||||||
// Writes a single character (draw WHITE if bit 7 set)
|
// Writes a single character (draw WHITE if bit 7 set)
|
||||||
//
|
//
|
||||||
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed)
|
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed)
|
||||||
|
|
@ -2044,9 +2053,13 @@ void V_DrawStringScaled(
|
||||||
boolean uppercase;
|
boolean uppercase;
|
||||||
boolean notcolored;
|
boolean notcolored;
|
||||||
|
|
||||||
|
boolean dance;
|
||||||
|
boolean nodanceoverride;
|
||||||
|
INT32 dancecounter;
|
||||||
|
|
||||||
fixed_t cx, cy;
|
fixed_t cx, cy;
|
||||||
|
|
||||||
fixed_t cxoff;
|
fixed_t cxoff, cyoff;
|
||||||
fixed_t cw;
|
fixed_t cw;
|
||||||
|
|
||||||
INT32 spacing;
|
INT32 spacing;
|
||||||
|
|
@ -2057,6 +2070,14 @@ void V_DrawStringScaled(
|
||||||
uppercase = !( flags & V_ALLOWLOWERCASE );
|
uppercase = !( flags & V_ALLOWLOWERCASE );
|
||||||
flags &= ~(V_FLIP);/* These two (V_ALLOWLOWERCASE) share a bit. */
|
flags &= ~(V_FLIP);/* These two (V_ALLOWLOWERCASE) share a bit. */
|
||||||
|
|
||||||
|
dance = (flags & V_STRINGDANCE) != 0;
|
||||||
|
nodanceoverride = !dance;
|
||||||
|
dancecounter = 0;
|
||||||
|
|
||||||
|
/* Some of these flags get overloaded in this function so
|
||||||
|
don't pass them on. */
|
||||||
|
flags &= ~(V_PARAMMASK);
|
||||||
|
|
||||||
if (colormap == NULL)
|
if (colormap == NULL)
|
||||||
{
|
{
|
||||||
colormap = V_GetStringColormap(( flags & V_CHARCOLORMASK ));
|
colormap = V_GetStringColormap(( flags & V_CHARCOLORMASK ));
|
||||||
|
|
@ -2247,8 +2268,9 @@ void V_DrawStringScaled(
|
||||||
|
|
||||||
cx = x;
|
cx = x;
|
||||||
cy = y;
|
cy = y;
|
||||||
|
cyoff = 0;
|
||||||
|
|
||||||
for (; ( c = *s ); ++s)
|
for (; ( c = *s ); ++s, ++dancecounter)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
|
@ -2267,18 +2289,29 @@ void V_DrawStringScaled(
|
||||||
( ( c & 0x7f )<< V_CHARCOLORSHIFT )&
|
( ( c & 0x7f )<< V_CHARCOLORSHIFT )&
|
||||||
V_CHARCOLORMASK);
|
V_CHARCOLORMASK);
|
||||||
}
|
}
|
||||||
|
if (nodanceoverride)
|
||||||
|
{
|
||||||
|
dance = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == V_STRINGDANCE)
|
||||||
|
{
|
||||||
|
dance = true;
|
||||||
}
|
}
|
||||||
else if (cx < right)
|
else if (cx < right)
|
||||||
{
|
{
|
||||||
if (uppercase)
|
if (uppercase)
|
||||||
c = toupper(c);
|
c = toupper(c);
|
||||||
|
|
||||||
|
if (dance)
|
||||||
|
cyoff = V_DanceYOffset(dancecounter) * FRACUNIT;
|
||||||
|
|
||||||
c -= font->start;
|
c -= font->start;
|
||||||
if (c >= 0 && c < font->size && font->font[c])
|
if (c >= 0 && c < font->size && font->font[c])
|
||||||
{
|
{
|
||||||
cw = SHORT (font->font[c]->width) * dupx;
|
cw = SHORT (font->font[c]->width) * dupx;
|
||||||
cxoff = (*dim_fn)(scale, chw, hchw, dupx, &cw);
|
cxoff = (*dim_fn)(scale, chw, hchw, dupx, &cw);
|
||||||
V_DrawFixedPatch(cx + cxoff, cy, scale,
|
V_DrawFixedPatch(cx + cxoff, cy + cyoff, scale,
|
||||||
flags, font->font[c], colormap);
|
flags, font->font[c], colormap);
|
||||||
cx += cw;
|
cx += cw;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,9 @@ void V_CubeApply(RGBA_t *input);
|
||||||
// Bottom 8 bits are used for parameter (screen or character)
|
// Bottom 8 bits are used for parameter (screen or character)
|
||||||
#define V_PARAMMASK 0x000000FF
|
#define V_PARAMMASK 0x000000FF
|
||||||
|
|
||||||
|
// strings/characters only
|
||||||
|
#define V_STRINGDANCE 0x00000002
|
||||||
|
|
||||||
// flags hacked in scrn (not supported by all functions (see src))
|
// flags hacked in scrn (not supported by all functions (see src))
|
||||||
// patch scaling uses bits 9 and 10
|
// patch scaling uses bits 9 and 10
|
||||||
#define V_SCALEPATCHSHIFT 8
|
#define V_SCALEPATCHSHIFT 8
|
||||||
|
|
@ -220,6 +223,8 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color);
|
||||||
#define V__IntegerStringWidth( scale,option,font,string ) \
|
#define V__IntegerStringWidth( scale,option,font,string ) \
|
||||||
(V_StringScaledWidth(scale,FRACUNIT,FRACUNIT,option,font,string) / FRACUNIT)
|
(V_StringScaledWidth(scale,FRACUNIT,FRACUNIT,option,font,string) / FRACUNIT)
|
||||||
|
|
||||||
|
INT32 V_DanceYOffset(INT32 counter);
|
||||||
|
|
||||||
// draw a single character
|
// draw a single character
|
||||||
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed);
|
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed);
|
||||||
// draw a single character, but for the chat
|
// draw a single character, but for the chat
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue