Merge remote-tracking branch 'refs/remotes/origin/battle'

This commit is contained in:
TehRealSalt 2018-01-01 19:27:48 -05:00
commit 8fffa290ce
47 changed files with 3374 additions and 920 deletions

View file

@ -1228,7 +1228,7 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
char *svalue; char *svalue;
UINT8 stealth = false; UINT8 stealth = false;
if (playernum != serverplayer && playernum != adminplayer && !serverloading) if (playernum != serverplayer && !IsPlayerAdmin(playernum) && !serverloading)
{ {
// not from server or remote admin, must be hacked/buggy client // not from server or remote admin, must be hacked/buggy client
CONS_Alert(CONS_WARNING, M_GetText("Illegal netvar command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal netvar command received from %s\n"), player_names[playernum]);
@ -1357,7 +1357,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
// send the value of the variable // send the value of the variable
XBOXSTATIC UINT8 buf[128]; XBOXSTATIC UINT8 buf[128];
UINT8 *p = buf; UINT8 *p = buf;
if (!(server || (adminplayer == consoleplayer))) if (!(server || (IsPlayerAdmin(consoleplayer))))
{ {
CONS_Printf(M_GetText("Only the server or admin can change: %s %s\n"), var->name, var->string); CONS_Printf(M_GetText("Only the server or admin can change: %s %s\n"), var->name, var->string);
return; return;
@ -1447,8 +1447,8 @@ void CV_AddValue(consvar_t *var, INT32 increment)
INT32 newvalue, max; INT32 newvalue, max;
// count pointlimit better // count pointlimit better
if (var == &cv_pointlimit && (gametype == GT_MATCH)) /*if (var == &cv_pointlimit && (gametype == GT_MATCH))
increment *= 50; increment *= 50;*/
newvalue = var->value + increment; newvalue = var->value + increment;
if (var->PossibleValue) if (var->PossibleValue)

View file

@ -43,6 +43,7 @@
#include "lzf.h" #include "lzf.h"
#include "lua_script.h" #include "lua_script.h"
#include "lua_hook.h" #include "lua_hook.h"
#include "k_kart.h"
#ifdef CLIENT_LOADINGSCREEN #ifdef CLIENT_LOADINGSCREEN
// cl loading screen // cl loading screen
@ -519,8 +520,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]); rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]);
for (j = 0; j < NUMKARTSTUFF; ++j) for (j = 0; j < NUMKARTSTUFF; ++j)
rsp->kartstuff[j] = LONG(players[i].kartstuff[j]); // SRB2kart rsp->kartstuff[j] = LONG(players[i].kartstuff[j]); // SRB2kart
for (j = 0; j < MAXPLAYERS; ++j)
rsp->collide[j] = (UINT8)players[i].collide[j]; // SRB2kart
// Score is resynched in the rspfirm resync packet // Score is resynched in the rspfirm resync packet
rsp->health = 0; // resynched with mo health rsp->health = 0; // resynched with mo health
@ -535,8 +534,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
// Just in case Lua does something like // Just in case Lua does something like
// modify these at runtime // modify these at runtime
// SRB2kart // SRB2kart
rsp->kartspeed = (fixed_t)LONG(players[i].kartspeed); rsp->kartspeed = (UINT8)LONG(players[i].kartspeed);
rsp->kartweight = (fixed_t)LONG(players[i].kartweight); rsp->kartweight = (UINT8)LONG(players[i].kartweight);
// //
rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed); rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed);
rsp->runspeed = (fixed_t)LONG(players[i].runspeed); rsp->runspeed = (fixed_t)LONG(players[i].runspeed);
@ -576,6 +575,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->starposty = SHORT(players[i].starposty); rsp->starposty = SHORT(players[i].starposty);
rsp->starpostz = SHORT(players[i].starpostz); rsp->starpostz = SHORT(players[i].starpostz);
rsp->starpostnum = LONG(players[i].starpostnum); rsp->starpostnum = LONG(players[i].starpostnum);
rsp->starpostcount = LONG(players[i].starpostcount);
rsp->starposttime = (tic_t)LONG(players[i].starposttime); rsp->starposttime = (tic_t)LONG(players[i].starposttime);
rsp->starpostangle = (angle_t)LONG(players[i].starpostangle); rsp->starpostangle = (angle_t)LONG(players[i].starpostangle);
@ -653,8 +653,6 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]); players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]);
for (j = 0; j < NUMKARTSTUFF; ++j) for (j = 0; j < NUMKARTSTUFF; ++j)
players[i].kartstuff[j] = LONG(rsp->kartstuff[j]); // SRB2kart players[i].kartstuff[j] = LONG(rsp->kartstuff[j]); // SRB2kart
for (j = 0; j < MAXPLAYERS; ++j)
players[i].collide[j] = (UINT8)rsp->collide[j]; // SRB2kart
// Score is resynched in the rspfirm resync packet // Score is resynched in the rspfirm resync packet
players[i].health = rsp->health; players[i].health = rsp->health;
@ -668,8 +666,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].skin = LONG(rsp->skin); players[i].skin = LONG(rsp->skin);
// Just in case Lua does something like // Just in case Lua does something like
// modify these at runtime // modify these at runtime
players[i].kartspeed = (fixed_t)LONG(rsp->kartspeed); players[i].kartspeed = (UINT8)LONG(rsp->kartspeed);
players[i].kartweight = (fixed_t)LONG(rsp->kartweight); players[i].kartweight = (UINT8)LONG(rsp->kartweight);
players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed); players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed);
players[i].runspeed = (fixed_t)LONG(rsp->runspeed); players[i].runspeed = (fixed_t)LONG(rsp->runspeed);
@ -709,6 +707,7 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].starposty = SHORT(rsp->starposty); players[i].starposty = SHORT(rsp->starposty);
players[i].starpostz = SHORT(rsp->starpostz); players[i].starpostz = SHORT(rsp->starpostz);
players[i].starpostnum = LONG(rsp->starpostnum); players[i].starpostnum = LONG(rsp->starpostnum);
players[i].starpostcount = LONG(rsp->starpostcount);
players[i].starposttime = (tic_t)LONG(rsp->starposttime); players[i].starposttime = (tic_t)LONG(rsp->starposttime);
players[i].starpostangle = (angle_t)LONG(rsp->starpostangle); players[i].starpostangle = (angle_t)LONG(rsp->starpostangle);
@ -1366,15 +1365,18 @@ static boolean SV_SendServerConfig(INT32 node)
netbuffer->u.servercfg.gamestate = (UINT8)gamestate; netbuffer->u.servercfg.gamestate = (UINT8)gamestate;
netbuffer->u.servercfg.gametype = (UINT8)gametype; netbuffer->u.servercfg.gametype = (UINT8)gametype;
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame; netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
netbuffer->u.servercfg.adminplayer = (SINT8)adminplayer;
// we fill these structs with FFs so that any players not in game get sent as 0xFFFF // we fill these structs with FFs so that any players not in game get sent as 0xFFFF
// which is nice and easy for us to detect // which is nice and easy for us to detect
memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins)); memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins));
memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor)); memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor));
memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers));
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i];
if (!playeringame[i]) if (!playeringame[i])
continue; continue;
netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin; netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin;
@ -2030,7 +2032,7 @@ static void CL_ConnectToServer(boolean viams)
G_SetGamestate(GS_WAITINGPLAYERS); G_SetGamestate(GS_WAITINGPLAYERS);
wipegamestate = GS_WAITINGPLAYERS; wipegamestate = GS_WAITINGPLAYERS;
adminplayer = -1; ClearAdminPlayers();
pnumnodes = 1; pnumnodes = 1;
oldtic = I_GetTime() - 1; oldtic = I_GetTime() - 1;
#ifndef NONET #ifndef NONET
@ -2409,8 +2411,10 @@ static void CL_RemovePlayer(INT32 playernum)
// Reset the name // Reset the name
sprintf(player_names[playernum], "Player %d", playernum+1); sprintf(player_names[playernum], "Player %d", playernum+1);
if (playernum == adminplayer) if (IsPlayerAdmin(playernum))
adminplayer = -1; // don't stay admin after you're gone {
RemoveAdminPlayer(playernum); // don't stay admin after you're gone
}
if (playernum == displayplayer) if (playernum == displayplayer)
displayplayer = consoleplayer; // don't look through someone's view who isn't there displayplayer = consoleplayer; // don't look through someone's view who isn't there
@ -2421,6 +2425,8 @@ static void CL_RemovePlayer(INT32 playernum)
if (G_TagGametype()) //Check if you still have a game. Location flexible. =P if (G_TagGametype()) //Check if you still have a game. Location flexible. =P
P_CheckSurvivors(); P_CheckSurvivors();
else if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)
K_CheckBalloons(); // SRB2Kart
else if (gametype == GT_RACE || gametype == GT_COMPETITION) else if (gametype == GT_RACE || gametype == GT_COMPETITION)
P_CheckRacers(); P_CheckRacers();
} }
@ -2528,7 +2534,7 @@ static void Command_Nodes(void)
if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL) if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL)
CONS_Printf(" - %s", address); CONS_Printf(" - %s", address);
if (i == adminplayer) if (IsPlayerAdmin(i))
CONS_Printf(M_GetText(" (verified admin)")); CONS_Printf(M_GetText(" (verified admin)"));
if (players[i].spectator) if (players[i].spectator)
@ -2553,7 +2559,7 @@ static void Command_Ban(void)
return; return;
} }
if (server || adminplayer == consoleplayer) if (server || IsPlayerAdmin(consoleplayer))
{ {
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH]; XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
UINT8 *p = buf; UINT8 *p = buf;
@ -2619,7 +2625,7 @@ static void Command_Kick(void)
return; return;
} }
if (server || adminplayer == consoleplayer) if (server || IsPlayerAdmin(consoleplayer))
{ {
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH]; XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
UINT8 *p = buf; UINT8 *p = buf;
@ -2676,7 +2682,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
pnum = READUINT8(*p); pnum = READUINT8(*p);
msg = READUINT8(*p); msg = READUINT8(*p);
if (pnum == serverplayer && playernum == adminplayer) if (pnum == serverplayer && IsPlayerAdmin(playernum))
{ {
CONS_Printf(M_GetText("Server is being shut down remotely. Goodbye!\n")); CONS_Printf(M_GetText("Server is being shut down remotely. Goodbye!\n"));
@ -2687,7 +2693,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
} }
// Is playernum authorized to make this kick? // Is playernum authorized to make this kick?
if (playernum != serverplayer && playernum != adminplayer if (playernum != serverplayer && !IsPlayerAdmin(playernum)
&& !(playerpernode[playernode[playernum]] == 2 && !(playerpernode[playernode[playernum]] == 2
&& nodetoplayer2[playernode[playernum]] == pnum)) && nodetoplayer2[playernode[playernum]] == pnum))
{ {
@ -2950,6 +2956,7 @@ void SV_ResetServer(void)
playeringame[i] = false; playeringame[i] = false;
playernode[i] = UINT8_MAX; playernode[i] = UINT8_MAX;
sprintf(player_names[i], "Player %d", i + 1); sprintf(player_names[i], "Player %d", i + 1);
adminplayers[i] = -1; // Populate the entire adminplayers array with -1.
} }
mynode = 0; mynode = 0;
@ -3024,7 +3031,7 @@ void D_QuitNetGame(void)
} }
D_CloseConnection(); D_CloseConnection();
adminplayer = -1; ClearAdminPlayers();
DEBFILE("===========================================================================\n" DEBFILE("===========================================================================\n"
" Log finish\n" " Log finish\n"
@ -3055,7 +3062,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
INT16 node, newplayernum; INT16 node, newplayernum;
boolean splitscreenplayer; boolean splitscreenplayer;
if (playernum != serverplayer && playernum != adminplayer) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
// protect against hacked/buggy client // protect against hacked/buggy client
CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]);
@ -3540,7 +3547,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
gametype = netbuffer->u.servercfg.gametype; gametype = netbuffer->u.servercfg.gametype;
modifiedgame = netbuffer->u.servercfg.modifiedgame; modifiedgame = netbuffer->u.servercfg.modifiedgame;
adminplayer = netbuffer->u.servercfg.adminplayer; for (j = 0; j < MAXPLAYERS; j++)
adminplayers[j] = netbuffer->u.servercfg.adminplayers[j];
memcpy(server_context, netbuffer->u.servercfg.server_context, 8); memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
} }

View file

@ -163,7 +163,7 @@ typedef struct
UINT16 powers[NUMPOWERS]; UINT16 powers[NUMPOWERS];
INT32 kartstuff[NUMKARTSTUFF]; // SRB2kart INT32 kartstuff[NUMKARTSTUFF]; // SRB2kart
UINT8 collide[MAXPLAYERS]; // SRB2kart angle_t frameangle; // SRB2kart
// Score is resynched in the confirm resync packet // Score is resynched in the confirm resync packet
INT32 health; INT32 health;
@ -219,6 +219,7 @@ typedef struct
INT16 starposty; INT16 starposty;
INT16 starpostz; INT16 starpostz;
INT32 starpostnum; INT32 starpostnum;
INT32 starpostcount;
tic_t starposttime; tic_t starposttime;
angle_t starpostangle; angle_t starpostangle;
@ -289,7 +290,7 @@ typedef struct
UINT8 gametype; UINT8 gametype;
UINT8 modifiedgame; UINT8 modifiedgame;
SINT8 adminplayer; // Needs to be signed SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed
char server_context[8]; // Unique context id, generated at server startup. char server_context[8]; // Unique context id, generated at server startup.
@ -328,7 +329,7 @@ typedef struct
UINT8 cheatsenabled; UINT8 cheatsenabled;
UINT8 isdedicated; UINT8 isdedicated;
UINT8 fileneedednum; UINT8 fileneedednum;
SINT8 adminplayer; SINT8 adminplayers[MAXPLAYERS];
tic_t time; tic_t time;
tic_t leveltime; tic_t leveltime;
char servername[MAXSERVERNAME]; char servername[MAXSERVERNAME];

View file

@ -871,19 +871,23 @@ static void IdentifyVersion(void)
#else #else
const char *musicfile = "music.dta"; const char *musicfile = "music.dta";
#endif #endif
const char *kmusicfile;
const char *musicpath = va(pandf,srb2waddir,musicfile); const char *musicpath = va(pandf,srb2waddir,musicfile);
const char *kmusicpath;
int ms = W_VerifyNMUSlumps(musicpath); // Don't forget the music! int ms = W_VerifyNMUSlumps(musicpath); // Don't forget the music!
int kms;
if (ms == 1) if (ms == 1)
D_AddFile(musicpath); D_AddFile(musicpath);
else if (ms == 0) else if (ms == 0)
I_Error("File %s has been modified with non-music lumps",musicfile); I_Error("File %s has been modified with non-music lumps",musicfile);
const char* kmusicfile = "music.kart"; kmusicfile = "music.kart";
const char* kmusicpath = va(pandf,srb2waddir,kmusicfile); kmusicpath = va(pandf,srb2waddir,kmusicfile);
ms = W_VerifyNMUSlumps(kmusicpath); kms = W_VerifyNMUSlumps(kmusicpath); // kill me now
if (ms == 1)
if (kms == 1)
D_AddFile(kmusicpath); D_AddFile(kmusicpath);
else if (ms == 0) else if (kms == 0)
I_Error("File %s has been modified with non-music lumps",kmusicfile); I_Error("File %s has been modified with non-music lumps",kmusicfile);
} }
#endif #endif

View file

@ -145,7 +145,9 @@ static void Command_Changepassword_f(void);
static void Command_Login_f(void); static void Command_Login_f(void);
static void Got_Login(UINT8 **cp, INT32 playernum); static void Got_Login(UINT8 **cp, INT32 playernum);
static void Got_Verification(UINT8 **cp, INT32 playernum); static void Got_Verification(UINT8 **cp, INT32 playernum);
static void Got_Removal(UINT8 **cp, INT32 playernum);
static void Command_Verify_f(void); static void Command_Verify_f(void);
static void Command_RemoveAdmin_f(void);
static void Command_MotD_f(void); static void Command_MotD_f(void);
static void Got_MotD_f(UINT8 **cp, INT32 playernum); static void Got_MotD_f(UINT8 **cp, INT32 playernum);
@ -313,9 +315,18 @@ consvar_t cv_jaws = {"jaws", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0,
consvar_t cv_fireflower = {"fireflowers", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireflower = {"fireflowers", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_tripleredshell = {"tripleredshells", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_tripleredshell = {"tripleredshells", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_lightning = {"lightning", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lightning = {"lightning", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_feather = {"feathers", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_karthud = {"karthud", "Default", CV_SAVE|CV_CALL, karthud_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_karthud = {"karthud", "Default", CV_SAVE|CV_CALL, karthud_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartcheck = {"kartcheck", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t kartstarsfx_cons_t[] = {{0, "Music"}, {1, "SMK"}, {0, NULL}};
consvar_t cv_kartstarsfx = {"kartstarsfx", "SMK", CV_SAVE, kartstarsfx_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartcc = {"kartcc", "100cc", CV_NETVAR, kartcc_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartcc = {"kartcc", "100cc", CV_NETVAR, kartcc_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t kartballoons_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}};
consvar_t cv_kartballoons = {"kartballoons", "3", CV_NETVAR, kartballoons_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartfrantic = {"kartfrantic", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartmirror = {"kartmirror", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t speedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}}; static CV_PossibleValue_t speedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}};
consvar_t cv_speedometer = {"speedometer", "Kilometers", CV_SAVE, speedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display consvar_t cv_speedometer = {"speedometer", "Kilometers", CV_SAVE, speedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display
@ -401,7 +412,7 @@ consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL
INT16 gametype = GT_RACE; // SRB2kart INT16 gametype = GT_RACE; // SRB2kart
boolean splitscreen = false; boolean splitscreen = false;
boolean circuitmap = true; // SRB2kart boolean circuitmap = true; // SRB2kart
INT32 adminplayer = -1; INT32 adminplayers[MAXPLAYERS];
/// \warning Keep this up-to-date if you add/remove/rename net text commands /// \warning Keep this up-to-date if you add/remove/rename net text commands
const char *netxcmdnames[MAXNETXCMD - 1] = const char *netxcmdnames[MAXNETXCMD - 1] =
@ -426,6 +437,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
"DELFILE", "DELFILE",
"SETMOTD", "SETMOTD",
"SUICIDE", "SUICIDE",
"DEMOTED",
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
"LUACMD", "LUACMD",
"LUAVAR" "LUAVAR"
@ -463,8 +475,10 @@ void D_RegisterServerCommands(void)
COM_AddCommand("password", Command_Changepassword_f); COM_AddCommand("password", Command_Changepassword_f);
RegisterNetXCmd(XD_LOGIN, Got_Login); RegisterNetXCmd(XD_LOGIN, Got_Login);
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
COM_AddCommand("verify", Command_Verify_f); COM_AddCommand("giveadmin", Command_Verify_f);
RegisterNetXCmd(XD_VERIFIED, Got_Verification); RegisterNetXCmd(XD_VERIFIED, Got_Verification);
COM_AddCommand("removeadmin", Command_RemoveAdmin_f);
RegisterNetXCmd(XD_DEMOTED, Got_Removal);
COM_AddCommand("motd", Command_MotD_f); COM_AddCommand("motd", Command_MotD_f);
RegisterNetXCmd(XD_SETMOTD, Got_MotD_f); // For remote admin RegisterNetXCmd(XD_SETMOTD, Got_MotD_f); // For remote admin
@ -1049,7 +1063,7 @@ UINT8 CanChangeSkin(INT32 playernum)
return true; return true;
// Force skin in effect. // Force skin in effect.
if (client && (cv_forceskin.value != -1) && !(adminplayer == playernum && serverplayer == -1)) if (client && (cv_forceskin.value != -1) && !(IsPlayerAdmin(playernum) && serverplayer == -1))
return false; return false;
// Can change skin in intermission and whatnot. // Can change skin in intermission and whatnot.
@ -1063,7 +1077,7 @@ UINT8 CanChangeSkin(INT32 playernum)
return true; return true;
// Can change skin during initial countdown. // Can change skin during initial countdown.
if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) if (leveltime < 4*TICRATE)
return true; return true;
if (G_TagGametype()) if (G_TagGametype())
@ -1200,7 +1214,7 @@ static void SendNameAndColor(void)
snacpending++; snacpending++;
// Don't change name if muted // Don't change name if muted
if (cv_mute.value && !(server || adminplayer == consoleplayer)) if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
CV_StealthSet(&cv_playername, player_names[consoleplayer]); CV_StealthSet(&cv_playername, player_names[consoleplayer]);
else // Cleanup name if changing it else // Cleanup name if changing it
CleanupPlayerName(consoleplayer, cv_playername.zstring); CleanupPlayerName(consoleplayer, cv_playername.zstring);
@ -1607,7 +1621,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
mapchangepending = 0; mapchangepending = 0;
// spawn the server if needed // spawn the server if needed
// reset players if there is a new one // reset players if there is a new one
if (!(adminplayer == consoleplayer)) if (!IsPlayerAdmin(consoleplayer))
{ {
if (SV_SpawnServer()) if (SV_SpawnServer())
buf[0] &= ~(1<<1); buf[0] &= ~(1<<1);
@ -1665,7 +1679,7 @@ static void Command_Map_f(void)
return; return;
} }
if (client && !(adminplayer == consoleplayer)) if (client && !IsPlayerAdmin(consoleplayer))
{ {
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
return; return;
@ -1794,7 +1808,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
INT32 resetplayer = 1, lastgametype; INT32 resetplayer = 1, lastgametype;
UINT8 skipprecutscene, FLS; UINT8 skipprecutscene, FLS;
if (playernum != serverplayer && playernum != adminplayer) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]);
if (server) if (server)
@ -1868,8 +1882,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
// a copy of color // a copy of color
if (players[0].mo) if (players[0].mo)
players[0].mo->color = players[0].skincolor; players[0].mo->color = players[0].skincolor;
CV_StealthSetValue(&cv_kartcc, 150); // srb2kart
} }
if (metalrecording) if (metalrecording)
G_BeginMetal(); G_BeginMetal();
@ -1893,7 +1905,7 @@ static void Command_Pause(void)
else else
WRITEUINT8(cp, 0); WRITEUINT8(cp, 0);
if (cv_pause.value || server || (adminplayer == consoleplayer)) if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer)))
{ {
if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION))
{ {
@ -1911,7 +1923,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
UINT8 dedicatedpause = false; UINT8 dedicatedpause = false;
const char *playername; const char *playername;
if (netgame && !cv_pause.value && playernum != serverplayer && playernum != adminplayer) if (netgame && !cv_pause.value && playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal pause command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal pause command received from %s\n"), player_names[playernum]);
if (server) if (server)
@ -1970,11 +1982,11 @@ static void Command_Suicide(void)
return; return;
} }
if (!G_PlatformGametype()) /*if (!G_PlatformGametype()) // srb2kart: not necessary, suiciding makes you lose a balloon in battle, so it's not desirable to use as a way to escape a hit
{ {
CONS_Printf(M_GetText("You may only use this in co-op, race, and competition!\n")); CONS_Printf(M_GetText("You may only use this in co-op, race, and competition!\n"));
return; return;
} }*/
// Retry is quicker. Probably should force people to use it. // Retry is quicker. Probably should force people to use it.
if (!(netgame || multiplayer)) if (!(netgame || multiplayer))
@ -1991,7 +2003,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum)
INT32 suicideplayer = READINT32(*cp); INT32 suicideplayer = READINT32(*cp);
// You can't suicide someone else. Nice try, there. // You can't suicide someone else. Nice try, there.
if (suicideplayer != playernum || (!G_PlatformGametype())) if (suicideplayer != playernum) // srb2kart: "|| (!G_PlatformGametype())"
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]);
if (server) if (server)
@ -2040,7 +2052,7 @@ static void Got_RandomSeed(UINT8 **cp, INT32 playernum)
*/ */
static void Command_Clearscores_f(void) static void Command_Clearscores_f(void)
{ {
if (!(server || (adminplayer == consoleplayer))) if (!(server || (IsPlayerAdmin(consoleplayer))))
return; return;
SendNetXCmd(XD_CLEARSCORES, NULL, 1); SendNetXCmd(XD_CLEARSCORES, NULL, 1);
@ -2060,7 +2072,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum)
INT32 i; INT32 i;
(void)cp; (void)cp;
if (playernum != serverplayer && playernum != adminplayer) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal clear scores command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal clear scores command received from %s\n"), player_names[playernum]);
if (server) if (server)
@ -2281,7 +2293,7 @@ static void Command_ServerTeamChange_f(void)
UINT16 usvalue; UINT16 usvalue;
NetPacket.value.l = NetPacket.value.b = 0; NetPacket.value.l = NetPacket.value.b = 0;
if (!(server || (adminplayer == consoleplayer))) if (!(server || (IsPlayerAdmin(consoleplayer))))
{ {
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
return; return;
@ -2428,7 +2440,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
if (NetPacket.packet.verification) // Special marker that the server sent the request if (NetPacket.packet.verification) // Special marker that the server sent the request
{ {
if (playernum != serverplayer && (playernum != adminplayer)) if (playernum != serverplayer && (!IsPlayerAdmin(playernum)))
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
if (server) if (server)
@ -2467,7 +2479,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
} }
else else
{ {
if (playernum != serverplayer && (playernum != adminplayer)) if (playernum != serverplayer && (!IsPlayerAdmin(playernum)))
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
if (server) if (server)
@ -2661,6 +2673,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
// In tag, check to see if you still have a game. // In tag, check to see if you still have a game.
if (G_TagGametype()) if (G_TagGametype())
P_CheckSurvivors(); P_CheckSurvivors();
else if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)
K_CheckBalloons(); // SRB2Kart
} }
// //
@ -2776,13 +2790,60 @@ static void Got_Login(UINT8 **cp, INT32 playernum)
if (!memcmp(sentmd5, finalmd5, 16)) if (!memcmp(sentmd5, finalmd5, 16))
{ {
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[playernum]); CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[playernum]);
COM_BufInsertText(va("verify %d\n", playernum)); // do this immediately COM_BufInsertText(va("giveadmin %d\n", playernum)); // do this immediately
} }
else else
CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[playernum]); CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[playernum]);
#endif #endif
} }
boolean IsPlayerAdmin(INT32 playernum)
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
if (playernum == adminplayers[i])
return true;
return false;
}
void SetAdminPlayer(INT32 playernum)
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playernum == adminplayers[i])
return; // Player is already admin
if (adminplayers[i] == -1)
{
adminplayers[i] = playernum; // Set the player to a free spot
break; // End the loop now. If it keeps going, the same player might get assigned to two slots.
}
/*if (i == 3 && adminplayers[i] != -1) // End of the loop and all slots are full
{
adminplayers[0] = playernum; // Overwrite the first slot
break;
}*/
}
}
void ClearAdminPlayers(void)
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
adminplayers[i] = -1;
}
void RemoveAdminPlayer(INT32 playernum)
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
if (playernum == adminplayers[i])
adminplayers[i] = -1;
}
static void Command_Verify_f(void) static void Command_Verify_f(void)
{ {
XBOXSTATIC char buf[8]; // Should be plenty XBOXSTATIC char buf[8]; // Should be plenty
@ -2797,7 +2858,7 @@ static void Command_Verify_f(void)
if (COM_Argc() != 2) if (COM_Argc() != 2)
{ {
CONS_Printf(M_GetText("verify <node>: give admin privileges to a node\n")); CONS_Printf(M_GetText("giveadmin <node>: give admin privileges to a node\n"));
return; return;
} }
@ -2831,7 +2892,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum)
return; return;
} }
adminplayer = num; SetAdminPlayer(num);
if (num != consoleplayer) if (num != consoleplayer)
return; return;
@ -2839,6 +2900,62 @@ static void Got_Verification(UINT8 **cp, INT32 playernum)
CONS_Printf(M_GetText("You are now a server administrator.\n")); CONS_Printf(M_GetText("You are now a server administrator.\n"));
} }
static void Command_RemoveAdmin_f(void)
{
XBOXSTATIC char buf[8]; // Should be plenty
char *temp;
INT32 playernum;
if (client)
{
CONS_Printf(M_GetText("Only the server can use this.\n"));
return;
}
if (COM_Argc() != 2)
{
CONS_Printf(M_GetText("removeadmin <node>: remove admin privileges from a node\n"));
return;
}
strlcpy(buf, COM_Argv(1), sizeof(buf));
playernum = atoi(buf);
temp = buf;
WRITEUINT8(temp, playernum);
if (playeringame[playernum])
SendNetXCmd(XD_DEMOTED, buf, 1);
}
static void Got_Removal(UINT8 **cp, INT32 playernum)
{
INT16 num = READUINT8(*cp);
if (playernum != serverplayer) // it's not from the server (hacker or bug)
{
CONS_Alert(CONS_WARNING, M_GetText("Illegal demotion received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]);
if (server)
{
XBOXSTATIC UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return;
}
RemoveAdminPlayer(num);
if (num != consoleplayer)
return;
CONS_Printf(M_GetText("You are no longer a server administrator.\n"));
}
static void Command_MotD_f(void) static void Command_MotD_f(void)
{ {
size_t i, j; size_t i, j;
@ -2850,7 +2967,7 @@ static void Command_MotD_f(void)
return; return;
} }
if (!(server || (adminplayer == consoleplayer))) if (!(server || (IsPlayerAdmin(consoleplayer))))
{ {
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
return; return;
@ -2897,7 +3014,7 @@ static void Got_MotD_f(UINT8 **cp, INT32 playernum)
if (!isprint(mymotd[i]) || mymotd[i] == ';') if (!isprint(mymotd[i]) || mymotd[i] == ';')
kick = true; kick = true;
if ((playernum != serverplayer && playernum != adminplayer) || kick) if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal motd change received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal motd change received from %s\n"), player_names[playernum]);
if (server) if (server)
@ -2934,7 +3051,7 @@ static void Command_RunSOC(void)
else else
fn = COM_Argv(1); fn = COM_Argv(1);
if (netgame && !(server || consoleplayer == adminplayer)) if (netgame && !(server || IsPlayerAdmin(consoleplayer)))
{ {
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
return; return;
@ -2960,7 +3077,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
char filename[256]; char filename[256];
filestatus_t ncs = FS_NOTFOUND; filestatus_t ncs = FS_NOTFOUND;
if (playernum != serverplayer && playernum != adminplayer) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal runsoc command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal runsoc command received from %s\n"), player_names[playernum]);
if (server) if (server)
@ -3031,7 +3148,7 @@ static void Command_Addfile(void)
if (!musiconly) if (!musiconly)
{ {
// ... But only so long as they contain nothing more then music and sprites. // ... But only so long as they contain nothing more then music and sprites.
if (netgame && !(server || adminplayer == consoleplayer)) if (netgame && !(server || IsPlayerAdmin(consoleplayer)))
{ {
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
return; return;
@ -3074,7 +3191,7 @@ static void Command_Addfile(void)
WRITEMEM(buf_p, md5sum, 16); WRITEMEM(buf_p, md5sum, 16);
} }
if (adminplayer == consoleplayer) // Request to add file if (IsPlayerAdmin(consoleplayer)) // Request to add file
SendNetXCmd(XD_REQADDFILE, buf, buf_p - buf); SendNetXCmd(XD_REQADDFILE, buf, buf_p - buf);
else else
SendNetXCmd(XD_ADDFILE, buf, buf_p - buf); SendNetXCmd(XD_ADDFILE, buf, buf_p - buf);
@ -3123,7 +3240,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
UINT8 md5sum[16]; UINT8 md5sum[16];
boolean kick = false; boolean kick = false;
boolean toomany = false; boolean toomany = false;
INT32 i; INT32 i,j;
size_t packetsize = 0; size_t packetsize = 0;
serverinfo_pak *dummycheck = NULL; serverinfo_pak *dummycheck = NULL;
@ -3142,7 +3259,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
if (!isprint(filename[i]) || filename[i] == ';') if (!isprint(filename[i]) || filename[i] == ';')
kick = true; kick = true;
if ((playernum != serverplayer && playernum != adminplayer) || kick) if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick)
{ {
XBOXSTATIC UINT8 buf[2]; XBOXSTATIC UINT8 buf[2];
@ -3181,8 +3298,9 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
CONS_Printf("%s",message); CONS_Printf("%s",message);
if (adminplayer) for (j = 0; j < MAXPLAYERS; j++)
COM_BufAddText(va("sayto %d %s", adminplayer, message)); if (adminplayers[j])
COM_BufAddText(va("sayto %d %s", adminplayers[j], message));
return; return;
} }
@ -3496,9 +3614,9 @@ void D_GameTypeChanged(INT32 lastgametype)
case GT_TEAMMATCH: case GT_TEAMMATCH:
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
{ {
// default settings for match: timelimit 10 mins, no pointlimit // default settings for match: no timelimit, no pointlimit
CV_SetValue(&cv_pointlimit, 0); CV_SetValue(&cv_pointlimit, 0);
CV_SetValue(&cv_timelimit, 10); CV_SetValue(&cv_timelimit, 0);
} }
if (!cv_itemrespawntime.changed) if (!cv_itemrespawntime.changed)
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
@ -3556,7 +3674,7 @@ void D_GameTypeChanged(INT32 lastgametype)
// When swapping to a gametype that supports spectators, // When swapping to a gametype that supports spectators,
// make everyone a spectator initially. // make everyone a spectator initially.
if (!splitscreen && (G_GametypeHasSpectators())) /*if (!splitscreen && (G_GametypeHasSpectators()))
{ {
INT32 i; INT32 i;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
@ -3565,7 +3683,7 @@ void D_GameTypeChanged(INT32 lastgametype)
players[i].ctfteam = 0; players[i].ctfteam = 0;
players[i].spectator = true; players[i].spectator = true;
} }
} }*/
// don't retain teams in other modes or between changes from ctf to team match. // don't retain teams in other modes or between changes from ctf to team match.
// also, stop any and all forms of team scrambling that might otherwise take place. // also, stop any and all forms of team scrambling that might otherwise take place.
@ -3576,7 +3694,7 @@ void D_GameTypeChanged(INT32 lastgametype)
if (playeringame[i]) if (playeringame[i])
players[i].ctfteam = 0; players[i].ctfteam = 0;
if (server || (adminplayer == consoleplayer)) if (server || (IsPlayerAdmin(consoleplayer)))
{ {
CV_StealthSetValue(&cv_teamscramble, 0); CV_StealthSetValue(&cv_teamscramble, 0);
teamscramble = 0; teamscramble = 0;
@ -3659,7 +3777,7 @@ static void TeamScramble_OnChange(void)
if (!cv_teamscramble.value) if (!cv_teamscramble.value)
teamscramble = 0; teamscramble = 0;
if (!G_GametypeHasTeams() && (server || consoleplayer == adminplayer)) if (!G_GametypeHasTeams() && (server || IsPlayerAdmin(consoleplayer)))
{ {
CONS_Alert(CONS_NOTICE, M_GetText("This command cannot be used in this gametype.\n")); CONS_Alert(CONS_NOTICE, M_GetText("This command cannot be used in this gametype.\n"));
CV_StealthSetValue(&cv_teamscramble, 0); CV_StealthSetValue(&cv_teamscramble, 0);
@ -3838,7 +3956,7 @@ static void Command_ExitLevel_f(void)
{ {
if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug) if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug)
CONS_Printf(M_GetText("This only works in a netgame.\n")); CONS_Printf(M_GetText("This only works in a netgame.\n"));
else if (!(server || (adminplayer == consoleplayer))) else if (!(server || (IsPlayerAdmin(consoleplayer))))
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
else if (gamestate != GS_LEVEL || demoplayback) else if (gamestate != GS_LEVEL || demoplayback)
CONS_Printf(M_GetText("You must be in a level to use this.\n")); CONS_Printf(M_GetText("You must be in a level to use this.\n"));
@ -3854,7 +3972,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
if (gameaction == ga_completed) if (gameaction == ga_completed)
return; return;
if (playernum != serverplayer && playernum != adminplayer) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal exitlevel command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal exitlevel command received from %s\n"), player_names[playernum]);
if (server) if (server)
@ -4027,7 +4145,7 @@ static void Command_Cheats_f(void)
{ {
if (COM_CheckParm("off")) if (COM_CheckParm("off"))
{ {
if (!(server || (adminplayer == consoleplayer))) if (!(server || (IsPlayerAdmin(consoleplayer))))
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
else else
CV_ResetCheatNetVars(); CV_ResetCheatNetVars();
@ -4037,7 +4155,7 @@ static void Command_Cheats_f(void)
if (CV_CheatsEnabled()) if (CV_CheatsEnabled())
{ {
CONS_Printf(M_GetText("At least one CHEAT-marked variable has been changed -- Cheats are enabled.\n")); CONS_Printf(M_GetText("At least one CHEAT-marked variable has been changed -- Cheats are enabled.\n"));
if (server || (adminplayer == consoleplayer)) if (server || (IsPlayerAdmin(consoleplayer)))
CONS_Printf(M_GetText("Type CHEATS OFF to reset all cheat variables to default.\n")); CONS_Printf(M_GetText("Type CHEATS OFF to reset all cheat variables to default.\n"));
} }
else else
@ -4106,7 +4224,7 @@ static void Command_Archivetest_f(void)
*/ */
static void ForceSkin_OnChange(void) static void ForceSkin_OnChange(void)
{ {
if ((server || adminplayer == consoleplayer) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins)) if ((server || IsPlayerAdmin(consoleplayer)) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins))
{ {
if (cv_forceskin.value == -2) if (cv_forceskin.value == -2)
CV_SetValue(&cv_forceskin, numskins-1); CV_SetValue(&cv_forceskin, numskins-1);
@ -4136,7 +4254,7 @@ static void ForceSkin_OnChange(void)
//Allows the player's name to be changed if cv_mute is off. //Allows the player's name to be changed if cv_mute is off.
static void Name_OnChange(void) static void Name_OnChange(void)
{ {
if (cv_mute.value && !(server || adminplayer == consoleplayer)) if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n")); CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername, player_names[consoleplayer]); CV_StealthSet(&cv_playername, player_names[consoleplayer]);
@ -4259,7 +4377,7 @@ static void Color2_OnChange(void)
*/ */
static void Mute_OnChange(void) static void Mute_OnChange(void)
{ {
if (server || (adminplayer == consoleplayer)) if (server || (IsPlayerAdmin(consoleplayer)))
return; return;
if (cv_mute.value) if (cv_mute.value)

View file

@ -103,9 +103,16 @@ extern consvar_t cv_magnet, cv_boo, cv_mushroom, cv_triplemushroom, cv_megashroo
extern consvar_t cv_goldshroom, cv_star, cv_triplebanana, cv_fakeitem, cv_banana; extern consvar_t cv_goldshroom, cv_star, cv_triplebanana, cv_fakeitem, cv_banana;
extern consvar_t cv_greenshell, cv_redshell, cv_laserwisp, cv_triplegreenshell, cv_bobomb; extern consvar_t cv_greenshell, cv_redshell, cv_laserwisp, cv_triplegreenshell, cv_bobomb;
extern consvar_t cv_blueshell, cv_jaws, cv_fireflower, cv_tripleredshell, cv_lightning; extern consvar_t cv_blueshell, cv_jaws, cv_fireflower, cv_tripleredshell, cv_lightning;
extern consvar_t cv_feather;
extern consvar_t cv_karthud; extern consvar_t cv_karthud;
extern consvar_t cv_kartcheck;
extern consvar_t cv_kartstarsfx;
extern consvar_t cv_kartcc; extern consvar_t cv_kartcc;
extern consvar_t cv_kartballoons;
extern consvar_t cv_kartfrantic;
extern consvar_t cv_kartcomeback;
extern consvar_t cv_kartmirror;
extern consvar_t cv_speedometer; extern consvar_t cv_speedometer;
extern consvar_t cv_collideminimum; extern consvar_t cv_collideminimum;
@ -170,9 +177,10 @@ typedef enum
XD_DELFILE, // 18 XD_DELFILE, // 18
XD_SETMOTD, // 19 XD_SETMOTD, // 19
XD_SUICIDE, // 20 XD_SUICIDE, // 20
XD_DEMOTED, // 21
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
XD_LUACMD, // 21 XD_LUACMD, // 22
XD_LUAVAR, // 22 XD_LUAVAR, // 23
#endif #endif
MAXNETXCMD MAXNETXCMD
} netxcmd_t; } netxcmd_t;
@ -228,6 +236,10 @@ void Command_Retry_f(void);
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect);
void ObjectPlace_OnChange(void); void ObjectPlace_OnChange(void);
boolean IsPlayerAdmin(INT32 playernum);
void SetAdminPlayer(INT32 playernum);
void ClearAdminPlayers(void);
void RemoveAdminPlayer(INT32 playernum);
void ItemFinder_OnChange(void); void ItemFinder_OnChange(void);
void D_SetPassword(const char *pw); void D_SetPassword(const char *pw);

View file

@ -246,6 +246,7 @@ typedef enum
k_throwdir, // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir") k_throwdir, // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir")
k_camspin, // Used to 180 the camera while a button is held k_camspin, // Used to 180 the camera while a button is held
k_lapanimation, // Used to make a swoopy lap lakitu, maybe other effects in the future k_lapanimation, // Used to make a swoopy lap lakitu, maybe other effects in the future
k_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics
k_sounds, // Used this to stop and then force music restores as it hits zero k_sounds, // Used this to stop and then force music restores as it hits zero
k_boosting, // Determines if you're currently shroom-boosting k_boosting, // Determines if you're currently shroom-boosting
@ -266,6 +267,7 @@ typedef enum
// Some items use timers for their duration or effects // Some items use timers for their duration or effects
k_magnettimer, // Duration of Magnet's item-break and item box pull k_magnettimer, // Duration of Magnet's item-break and item box pull
k_bootimer, // Duration of the boo offroad effect itself
k_bootaketimer, // You are stealing an item, this is your timer k_bootaketimer, // You are stealing an item, this is your timer
k_boostolentimer, // You are being stolen from, this is your timer k_boostolentimer, // You are being stolen from, this is your timer
k_mushroomtimer, // Duration of the Mushroom Boost itself k_mushroomtimer, // Duration of the Mushroom Boost itself
@ -273,8 +275,11 @@ typedef enum
k_squishedtimer, // Squished frame timer k_squishedtimer, // Squished frame timer
k_goldshroomtimer, // Gold Mushroom duration timer k_goldshroomtimer, // Gold Mushroom duration timer
k_startimer, // Invincibility timer k_startimer, // Invincibility timer
k_spinouttimer, // Wipe-out from a banana peel or oil slick (was "pw_bananacam") k_spinouttimer, // Spin-out from a banana peel or oil slick (was "pw_bananacam")
k_laserwisptimer, // The duration and relative angle of the laser k_laserwisptimer, // The duration and relative angle of the laser
k_justbumped, // Prevent players from endlessly bumping into each other
k_poweritemtimer, // Battle mode, how long before you're allowed another power item (Star, Megashroom)
k_comebacktimer, // Battle mode, how long before you become a bomb after death
// Each item needs its own power slot, for the HUD and held use // Each item needs its own power slot, for the HUD and held use
k_magnet, // 0x1 = Magnet in inventory k_magnet, // 0x1 = Magnet in inventory
@ -301,8 +306,15 @@ typedef enum
k_tripleredshell, // 0x1 = 1 Red Shell orbiting, 0x2 = 2 Red Shells orbiting k_tripleredshell, // 0x1 = 1 Red Shell orbiting, 0x2 = 2 Red Shells orbiting
// 0x4 = 3 Red Shells orbiting, 0x8 = Triple Red Shell in inventory // 0x4 = 3 Red Shells orbiting, 0x8 = Triple Red Shell in inventory
k_lightning, // 0x1 = Lightning in inventory k_lightning, // 0x1 = Lightning in inventory
k_feather, // 0x1 = Feather in inventory, 0x2 = Player is feather jumping
k_kitchensink, // 0x1 = Sink in inventory k_kitchensink, // 0x1 = Sink in inventory
// Battle Mode vars
k_balloon, // Number of balloons left
k_comebackpoints, // Number of times you've bombed or gave an item to someone; once it's 3 it gets set back to 0 and you're given a balloon
k_comebackmode, // 0 = bomb, 1 = item
k_comebackshowninfo,// Have you already seen the info screen before?
NUMKARTSTUFF NUMKARTSTUFF
} kartstufftype_t; } kartstufftype_t;
//} //}
@ -365,7 +377,6 @@ typedef struct player_s
// SRB2kart stuff // SRB2kart stuff
INT32 kartstuff[NUMKARTSTUFF]; INT32 kartstuff[NUMKARTSTUFF];
boolean collide[MAXPLAYERS];
angle_t frameangle; // for the player add the ability to have the sprite only face other angles angle_t frameangle; // for the player add the ability to have the sprite only face other angles
// Bit flags. // Bit flags.
@ -467,6 +478,7 @@ typedef struct player_s
INT16 starposty; INT16 starposty;
INT16 starpostz; INT16 starpostz;
INT32 starpostnum; // The number of the last starpost you hit INT32 starpostnum; // The number of the last starpost you hit
INT32 starpostcount; // SRB2kart: how many did you hit?
tic_t starposttime; // Your time when you hit the starpost tic_t starposttime; // Your time when you hit the starpost
angle_t starpostangle; // Angle that the starpost is facing - you respawn facing this way angle_t starpostangle; // Angle that the starpost is facing - you respawn facing this way

View file

@ -981,6 +981,7 @@ static const struct {
{"RACE",TOL_RACE}, {"RACE",TOL_RACE},
{"MATCH",TOL_MATCH}, {"MATCH",TOL_MATCH},
{"BATTLE",TOL_MATCH}, // SRB2kart
{"TAG",TOL_TAG}, {"TAG",TOL_TAG},
{"CTF",TOL_CTF}, {"CTF",TOL_CTF},
@ -989,13 +990,13 @@ static const struct {
{"2D",TOL_2D}, {"2D",TOL_2D},
{"MARIO",TOL_MARIO}, {"MARIO",TOL_MARIO},
{"NIGHTS",TOL_NIGHTS}, {"NIGHTS",TOL_NIGHTS},
{"OLDBRAK",TOL_ERZ3}, //{"OLDBRAK",TOL_ERZ3},
{"XMAS",TOL_XMAS}, {"XMAS",TOL_XMAS},
{"CHRISTMAS",TOL_XMAS}, {"CHRISTMAS",TOL_XMAS},
{"WINTER",TOL_XMAS}, {"WINTER",TOL_XMAS},
{"KART",TOL_KART}, // SRB2kart //{"KART",TOL_KART}, // SRB2kart
{NULL, 0} {NULL, 0}
}; };
@ -1252,9 +1253,20 @@ static void readlevelheader(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "LEVELFLAGS")) else if (fastcmp(word, "LEVELFLAGS"))
mapheaderinfo[num-1]->levelflags = (UINT8)i; mapheaderinfo[num-1]->levelflags = get_number(word2);
else if (fastcmp(word, "MENUFLAGS")) else if (fastcmp(word, "MENUFLAGS"))
mapheaderinfo[num-1]->menuflags = (UINT8)i; mapheaderinfo[num-1]->menuflags = get_number(word2);
// SRB2Kart
/*else if (fastcmp(word, "AUTOMAP"))
{
if (i || word2[0] == 'T' || word2[0] == 'Y')
mapheaderinfo[num-1]->automap = true;
else
mapheaderinfo[num-1]->automap = false;
}*/
else if (fastcmp(word, "MOBJSCALE"))
mapheaderinfo[num-1]->mobj_scale = get_number(word2);
// Individual triggers for level flags, for ease of use (and 2.0 compatibility) // Individual triggers for level flags, for ease of use (and 2.0 compatibility)
else if (fastcmp(word, "SCRIPTISFILE")) else if (fastcmp(word, "SCRIPTISFILE"))
@ -6367,6 +6379,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_SINKTRAIL2", "S_SINKTRAIL2",
"S_SINKTRAIL3", "S_SINKTRAIL3",
// Battle Mode balloon
"S_BATTLEBALLOON1",
"S_BATTLEBALLOON2",
"S_BATTLEBALLOON3",
// Pokey // Pokey
"S_POKEY1", "S_POKEY1",
"S_POKEY2", "S_POKEY2",
@ -6401,6 +6418,28 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FIREDITEM3", "S_FIREDITEM3",
"S_FIREDITEM4", "S_FIREDITEM4",
"S_PLAYERARROW", // Above player arrow
"S_PLAYERARROW_MUSHROOM",
"S_PLAYERARROW_GREENSHELL",
"S_PLAYERARROW_BANANA",
"S_PLAYERARROW_FAKEITEM",
"S_PLAYERARROW_BOO",
"S_PLAYERARROW_FEATHER",
"S_PLAYERARROW_REDSHELL",
"S_PLAYERARROW_BOBOMB",
"S_PLAYERARROW_FIREFLOWER",
"S_PLAYERARROW_TRIPLEGREENSHELL",
"S_PLAYERARROW_TRIPLEBANANA",
"S_PLAYERARROW_TRIPLEREDSHELL",
"S_PLAYERARROW_STAR",
"S_PLAYERARROW_MEGASHROOM",
"S_PLAYERARROW_KITCHENSINK",
"S_PLAYERARROW_EMPTY",
"S_PLAYERARROW_ROULETTE",
"S_PLAYERBOMB", // Player bomb overlay
"S_PLAYERBOMB_WHEEL",
#ifdef SEENAMES #ifdef SEENAMES
"S_NAMECHECK", "S_NAMECHECK",
#endif #endif
@ -6958,6 +6997,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_SINK", // Kitchen Sink Stuff "MT_SINK", // Kitchen Sink Stuff
"MT_SINKTRAIL", "MT_SINKTRAIL",
"MT_BATTLEBALLOON", // Battle Mode balloon
"MT_LAKITU",
"MT_POKEY", // Huh, thought this was a default asset for some reason, guess not. "MT_POKEY", // Huh, thought this was a default asset for some reason, guess not.
"MT_ENEMYFLIP", "MT_ENEMYFLIP",
"MT_WAYPOINT", "MT_WAYPOINT",
@ -6969,6 +7012,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_FIREDITEM", "MT_FIREDITEM",
"MT_PLAYERARROW",
#ifdef SEENAMES #ifdef SEENAMES
"MT_NAMECHECK", "MT_NAMECHECK",
#endif #endif
@ -7281,6 +7326,81 @@ static const char *const POWERS_LIST[] = {
"INGOOP" // In goop "INGOOP" // In goop
}; };
static const char *const KARTSTUFF_LIST[] = {
"POSITION",
"OLDPOSITION",
"POSITIONDELAY",
"PREVCHECK",
"NEXTCHECK",
"WAYPOINT",
"STARPOSTWP",
"LAKITU",
"THROWDIR",
"CAMSPIN",
"LAPANIMATION",
"CARDANIMATION",
"SOUNDS",
"BOOSTING",
"FLOORBOOST",
"SPINOUT",
"SPINOUTTYPE",
"DRIFT",
"DRIFTEND",
"DRIFTCHARGE",
"DRIFTBOOST",
"BOOSTCHARGE",
"JMP",
"OFFROAD",
"ITEMROULETTE",
"ITEMCLOSE",
"MAGNETTIMER",
"BOOTIMER",
"BOOTAKETIMER",
"BOOSTOLENTIMER",
"MUSHROOMTIMER",
"GROWSHRINKTIMER",
"SQUISHEDTIMER",
"GOLDSHROOMTIMER",
"STARTIMER",
"SPINOUTTIMER",
"LASERWISPTIMER",
"JUSTBUMPED",
"POWERITEMTIMER",
"COMEBACKTIMER",
"MAGNET",
"BOO",
"MUSHROOM",
"MEGASHROOM",
"GOLDSHROOM",
"STAR",
"TRIPLEBANANA",
"FAKEITEM",
"BANANA",
"GREENSHELL",
"REDSHELL",
"LASERWISP",
"TRIPLEGREENSHELL",
"BOBOMB",
"BLUESHELL",
"JAWS",
"FIREFLOWER",
"TRIPLEREDSHELL",
"LIGHTNING",
"FEATHER",
"KITCHENSINK",
"BALLOON",
"COMEBACKPOINTS",
"COMEBACKMODE",
"COMEBACKSHOWNINFO"
};
static const char *const HUDITEMS_LIST[] = { static const char *const HUDITEMS_LIST[] = {
"LIVESNAME", "LIVESNAME",
"LIVESPIC", "LIVESPIC",
@ -7420,8 +7540,9 @@ struct {
{"TOL_2D",TOL_2D}, {"TOL_2D",TOL_2D},
{"TOL_MARIO",TOL_MARIO}, {"TOL_MARIO",TOL_MARIO},
{"TOL_NIGHTS",TOL_NIGHTS}, {"TOL_NIGHTS",TOL_NIGHTS},
{"TOL_ERZ3",TOL_ERZ3}, //{"TOL_ERZ3",TOL_ERZ3},
{"TOL_XMAS",TOL_XMAS}, {"TOL_XMAS",TOL_XMAS},
//{"TOL_KART",TOL_KART},
// Level flags // Level flags
{"LF_SCRIPTISFILE",LF_SCRIPTISFILE}, {"LF_SCRIPTISFILE",LF_SCRIPTISFILE},
@ -7915,6 +8036,20 @@ static powertype_t get_power(const char *word)
return pw_invulnerability; return pw_invulnerability;
} }
static kartstufftype_t get_kartstuff(const char *word)
{ // Returns the vlaue of k_ enumerations
kartstufftype_t i;
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("K_",word,2))
word += 2; // take off the k_
for (i = 0; i < NUMKARTSTUFF; i++)
if (fastcmp(word, KARTSTUFF_LIST[i]))
return i;
deh_warning("Couldn't find power named 'k_%s'",word);
return k_position;
}
/// \todo Make ANY of this completely over-the-top math craziness obey the order of operations. /// \todo Make ANY of this completely over-the-top math craziness obey the order of operations.
static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; } static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; }
static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; } static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; }
@ -8151,6 +8286,7 @@ void FUNCMATH DEH_Check(void)
const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*); const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*);
const size_t dehmobjs = sizeof(MOBJTYPE_LIST)/sizeof(const char*); const size_t dehmobjs = sizeof(MOBJTYPE_LIST)/sizeof(const char*);
const size_t dehpowers = sizeof(POWERS_LIST)/sizeof(const char*); const size_t dehpowers = sizeof(POWERS_LIST)/sizeof(const char*);
const size_t dehkartstuff = sizeof(KARTSTUFF_LIST)/sizeof(const char*);
const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*); const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*);
if (dehstates != S_FIRSTFREESLOT) if (dehstates != S_FIRSTFREESLOT)
@ -8162,6 +8298,9 @@ void FUNCMATH DEH_Check(void)
if (dehpowers != NUMPOWERS) if (dehpowers != NUMPOWERS)
I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers)); I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers));
if (dehkartstuff != NUMKARTSTUFF)
I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d kartstuff defined, versus %s in the Dehacked list)\n", NUMKARTSTUFF, sizeu1(dehkartstuff));
if (dehcolors != MAXTRANSLATIONS) if (dehcolors != MAXTRANSLATIONS)
I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", MAXTRANSLATIONS, sizeu1(dehcolors)); I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", MAXTRANSLATIONS, sizeu1(dehcolors));
#endif #endif
@ -8501,6 +8640,24 @@ static inline int lib_getenum(lua_State *L)
} }
return luaL_error(L, "power '%s' could not be found.\n", word); return luaL_error(L, "power '%s' could not be found.\n", word);
} }
else if (!mathlib && fastncmp("k_",word,2)) {
p = word+2;
for (i = 0; i < NUMKARTSTUFF; i++)
if (fasticmp(p, KARTSTUFF_LIST[i])) {
lua_pushinteger(L, i);
return 1;
}
return 0;
}
else if (mathlib && fastncmp("K_",word,2)) { // SOCs are ALL CAPS!
p = word+2;
for (i = 0; i < NUMKARTSTUFF; i++)
if (fastcmp(p, KARTSTUFF_LIST[i])) {
lua_pushinteger(L, i);
return 1;
}
return luaL_error(L, "kartstuff '%s' could not be found.\n", word);
}
else if (fastncmp("HUD_",word,4)) { else if (fastncmp("HUD_",word,4)) {
p = word+4; p = word+4;
for (i = 0; i < NUMHUDITEMS; i++) for (i = 0; i < NUMHUDITEMS; i++)
@ -8646,9 +8803,9 @@ static inline int lib_getenum(lua_State *L)
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
return 1; return 1;
} else if (fastcmp(word,"admin")) { } else if (fastcmp(word,"admin")) {
if (!playeringame[adminplayer] || adminplayer == serverplayer) //if (!playeringame[adminplayer] || IsPlayerAdmin(serverplayer))
return 0; //return 0;
LUA_PushUserdata(L, &players[adminplayer], META_PLAYER); //LUA_PushUserdata(L, &players[adminplayer], META_PLAYER);
return 1; return 1;
} else if (fastcmp(word,"emeralds")) { } else if (fastcmp(word,"emeralds")) {
lua_pushinteger(L, emeralds); lua_pushinteger(L, emeralds);

View file

@ -246,13 +246,14 @@ typedef struct
UINT8 numGradedMares; ///< Internal. For grade support. UINT8 numGradedMares; ///< Internal. For grade support.
nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful. nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful.
// SRB2kart
//boolean automap; ///< Displays a level's white map outline in modified games
fixed_t mobj_scale; ///< Replacement for TOL_ERZ3
// Lua stuff. // Lua stuff.
// (This is not ifdeffed so the map header structure can stay identical, just in case.) // (This is not ifdeffed so the map header structure can stay identical, just in case.)
UINT8 numCustomOptions; ///< Internal. For Lua custom value support. UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful. customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful.
// SRB2kart
boolean automap; ///< Displays a level's white map outline in modified games
} mapheader_t; } mapheader_t;
// level flags // level flags
@ -290,9 +291,9 @@ enum TypeOfLevel
TOL_2D = 0x0100, ///< 2D TOL_2D = 0x0100, ///< 2D
TOL_MARIO = 0x0200, ///< Mario TOL_MARIO = 0x0200, ///< Mario
TOL_NIGHTS = 0x0400, ///< NiGHTS TOL_NIGHTS = 0x0400, ///< NiGHTS
TOL_ERZ3 = 0x0800, ///< ERZ3 //TOL_ERZ3 = 0x0800, ///< ERZ3
TOL_XMAS = 0x1000, ///< Christmas NiGHTS TOL_XMAS = 0x1000 ///< Christmas NiGHTS
TOL_KART = 0x4000 ///< Kart 32768 //TOL_KART = 0x4000 ///< Kart 32768
}; };
// Gametypes // Gametypes
@ -329,7 +330,7 @@ extern UINT16 emeralds;
#define EMERALD7 64 #define EMERALD7 64
#define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) #define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7))
extern INT32 nummaprings; //keep track of spawned rings/coins extern INT32 nummaprings, nummapboxes, numgotboxes; //keep track of spawned rings/coins/battle mode items
/** Time attack information, currently a very small structure. /** Time attack information, currently a very small structure.
*/ */
@ -401,8 +402,10 @@ extern UINT16 extralifetics;
// SRB2kart // SRB2kart
extern INT32 bootime; extern INT32 bootime;
extern INT32 boostealtime;
extern INT32 mushroomtime; extern INT32 mushroomtime;
extern INT32 itemtime; extern INT32 itemtime;
extern INT32 comebacktime;
extern UINT8 introtoplay; extern UINT8 introtoplay;
extern UINT8 creditscutscene; extern UINT8 creditscutscene;
@ -491,7 +494,8 @@ extern consvar_t cv_timetic; // display high resolution timer
extern consvar_t cv_forceskin; // force clients to use the server's skin extern consvar_t cv_forceskin; // force clients to use the server's skin
extern consvar_t cv_downloading; // allow clients to downloading WADs. extern consvar_t cv_downloading; // allow clients to downloading WADs.
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
extern INT32 adminplayer, serverplayer; extern INT32 serverplayer;
extern INT32 adminplayers[MAXPLAYERS];
/// \note put these in d_clisrv outright? /// \note put these in d_clisrv outright?

View file

@ -259,7 +259,8 @@ typedef enum
postimg_water, postimg_water,
postimg_motion, postimg_motion,
postimg_flip, postimg_flip,
postimg_heat postimg_heat,
postimg_mirror
} postimg_t; } postimg_t;
typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num) typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)

View file

@ -1345,7 +1345,7 @@ void F_CutsceneTicker(void)
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (netgame && i != serverplayer && i != adminplayer) if (netgame && i != serverplayer && !IsPlayerAdmin(i))
continue; continue;
if (players[i].cmd.buttons & BT_BRAKE || players[i].cmd.buttons & BT_ACCELERATE) // SRB2kart if (players[i].cmd.buttons & BT_BRAKE || players[i].cmd.buttons & BT_ACCELERATE) // SRB2kart

View file

@ -179,6 +179,10 @@ UINT32 bluescore, redscore; // CTF and Team Match team scores
// ring count... for PERFECT! // ring count... for PERFECT!
INT32 nummaprings = 0; INT32 nummaprings = 0;
// box respawning in battle mode
INT32 nummapboxes = 0;
INT32 numgotboxes = 0;
// Elminates unnecessary searching. // Elminates unnecessary searching.
boolean CheckForBustableBlocks; boolean CheckForBustableBlocks;
boolean CheckForBouncySector; boolean CheckForBouncySector;
@ -198,8 +202,10 @@ UINT16 extralifetics = 4*TICRATE;
// SRB2kart // SRB2kart
INT32 bootime = 7*TICRATE; INT32 bootime = 7*TICRATE;
INT32 boostealtime = TICRATE/2;
INT32 mushroomtime = TICRATE + (TICRATE/3); INT32 mushroomtime = TICRATE + (TICRATE/3);
INT32 itemtime = 8*TICRATE; INT32 itemtime = 8*TICRATE;
INT32 comebacktime = 10*TICRATE;
INT32 gameovertics = 15*TICRATE; INT32 gameovertics = 15*TICRATE;
@ -974,6 +980,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
gamepadjoystickmove = cv_usejoystick.value && Joystick.bGamepadStyle; gamepadjoystickmove = cv_usejoystick.value && Joystick.bGamepadStyle;
axis = JoyAxis(AXISTURN); axis = JoyAxis(AXISTURN);
if (cv_kartmirror.value)
{
turnright = PLAYER1INPUTDOWN(gc_turnleft);
turnleft = PLAYER1INPUTDOWN(gc_turnright);
axis = -axis;
}
if (gamepadjoystickmove && axis != 0) if (gamepadjoystickmove && axis != 0)
{ {
turnright = turnright || (axis > 0); turnright = turnright || (axis > 0);
@ -1246,8 +1260,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
cmd->forwardmove = (SINT8)(cmd->forwardmove + forward); cmd->forwardmove = (SINT8)(cmd->forwardmove + forward);
cmd->sidemove = (SINT8)(cmd->sidemove + side); cmd->sidemove = (SINT8)(cmd->sidemove + side);
if (cv_kartmirror.value)
cmd->sidemove = -cmd->sidemove;
//{ SRB2kart - Drift support //{ SRB2kart - Drift support
axis = JoyAxis(AXISTURN); axis = JoyAxis(AXISTURN);
if (cv_kartmirror.value)
axis = -axis;
if (cmd->angleturn > 0) // Drifting to the left if (cmd->angleturn > 0) // Drifting to the left
cmd->buttons |= BT_DRIFTLEFT; cmd->buttons |= BT_DRIFTLEFT;
@ -1322,6 +1341,14 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
gamepadjoystickmove = cv_usejoystick2.value && Joystick2.bGamepadStyle; gamepadjoystickmove = cv_usejoystick2.value && Joystick2.bGamepadStyle;
axis = Joy2Axis(AXISTURN); axis = Joy2Axis(AXISTURN);
if (cv_kartmirror.value)
{
turnright = PLAYER2INPUTDOWN(gc_turnleft);
turnleft = PLAYER2INPUTDOWN(gc_turnright);
axis = -axis;
}
if (gamepadjoystickmove && axis != 0) if (gamepadjoystickmove && axis != 0)
{ {
turnright = turnright || (axis > 0); turnright = turnright || (axis > 0);
@ -1578,8 +1605,13 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
cmd->forwardmove = (SINT8)(cmd->forwardmove + forward); cmd->forwardmove = (SINT8)(cmd->forwardmove + forward);
cmd->sidemove = (SINT8)(cmd->sidemove + side); cmd->sidemove = (SINT8)(cmd->sidemove + side);
if (cv_kartmirror.value)
cmd->sidemove = -cmd->sidemove;
//{ SRB2kart - Drift support //{ SRB2kart - Drift support
axis = Joy2Axis(AXISTURN); axis = Joy2Axis(AXISTURN);
if (cv_kartmirror.value)
axis = -axis;
if (cmd->angleturn > 0) // Drifting to the left if (cmd->angleturn > 0) // Drifting to the left
cmd->buttons |= BT_DRIFTLEFT; cmd->buttons |= BT_DRIFTLEFT;
@ -1784,7 +1816,7 @@ boolean G_Responder(event_t *ev)
if (players[displayplayer].spectator) if (players[displayplayer].spectator)
continue; continue;
if (G_GametypeHasTeams()) /*if (G_GametypeHasTeams())
{ {
if (players[consoleplayer].ctfteam if (players[consoleplayer].ctfteam
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam) && players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
@ -1806,6 +1838,12 @@ boolean G_Responder(event_t *ev)
{ {
if (!players[consoleplayer].spectator) if (!players[consoleplayer].spectator)
continue; continue;
}*/
if (gametype != GT_RACE) // srb2kart
{
if (players[consoleplayer].kartstuff[k_balloon] > 0)
continue;
} }
break; break;
@ -2120,7 +2158,6 @@ static inline void G_PlayerFinishLevel(INT32 player)
memset(p->powers, 0, sizeof (p->powers)); memset(p->powers, 0, sizeof (p->powers));
memset(p->kartstuff, 0, sizeof (p->kartstuff)); // SRB2kart memset(p->kartstuff, 0, sizeof (p->kartstuff)); // SRB2kart
memset(p->collide, 0, sizeof (p->collide)); // SRB2kart
p->ringweapons = 0; p->ringweapons = 0;
p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility
@ -2131,6 +2168,7 @@ static inline void G_PlayerFinishLevel(INT32 player)
p->starposty = 0; p->starposty = 0;
p->starpostz = 0; p->starpostz = 0;
p->starpostnum = 0; p->starpostnum = 0;
p->starpostcount = 0;
if (rendermode == render_soft) if (rendermode == render_soft)
V_SetPaletteLump(GetPalette()); // Reset the palette V_SetPaletteLump(GetPalette()); // Reset the palette
@ -2171,6 +2209,7 @@ void G_PlayerReborn(INT32 player)
INT16 starposty; INT16 starposty;
INT16 starpostz; INT16 starpostz;
INT32 starpostnum; INT32 starpostnum;
INT32 starpostcount;
INT32 starpostangle; INT32 starpostangle;
fixed_t jumpfactor; fixed_t jumpfactor;
INT32 exiting; INT32 exiting;
@ -2188,6 +2227,9 @@ void G_PlayerReborn(INT32 player)
// SRB2kart // SRB2kart
INT32 starpostwp; INT32 starpostwp;
INT32 offroad; INT32 offroad;
INT32 balloon;
INT32 comebackpoints;
INT32 comebackshowninfo;
score = players[player].score; score = players[player].score;
lives = players[player].lives; lives = players[player].lives;
@ -2226,6 +2268,7 @@ void G_PlayerReborn(INT32 player)
starposty = players[player].starposty; starposty = players[player].starposty;
starpostz = players[player].starpostz; starpostz = players[player].starpostz;
starpostnum = players[player].starpostnum; starpostnum = players[player].starpostnum;
starpostcount = players[player].starpostcount;
starpostangle = players[player].starpostangle; starpostangle = players[player].starpostangle;
jumpfactor = players[player].jumpfactor; jumpfactor = players[player].jumpfactor;
thokitem = players[player].thokitem; thokitem = players[player].thokitem;
@ -2242,6 +2285,9 @@ void G_PlayerReborn(INT32 player)
// SRB2kart // SRB2kart
starpostwp = players[player].kartstuff[k_starpostwp]; starpostwp = players[player].kartstuff[k_starpostwp];
offroad = players[player].kartstuff[k_offroad]; offroad = players[player].kartstuff[k_offroad];
balloon = players[player].kartstuff[k_balloon];
comebackpoints = players[player].kartstuff[k_comebackpoints];
comebackshowninfo = players[player].kartstuff[k_comebackshowninfo];
p = &players[player]; p = &players[player];
memset(p, 0, sizeof (*p)); memset(p, 0, sizeof (*p));
@ -2281,6 +2327,7 @@ void G_PlayerReborn(INT32 player)
p->starposty = starposty; p->starposty = starposty;
p->starpostz = starpostz; p->starpostz = starpostz;
p->starpostnum = starpostnum; p->starpostnum = starpostnum;
p->starpostcount = starpostcount;
p->starpostangle = starpostangle; p->starpostangle = starpostangle;
p->jumpfactor = jumpfactor; p->jumpfactor = jumpfactor;
p->exiting = exiting; p->exiting = exiting;
@ -2298,6 +2345,11 @@ void G_PlayerReborn(INT32 player)
p->kartstuff[k_starpostwp] = starpostwp; // TODO: get these out of kartstuff, it causes desync p->kartstuff[k_starpostwp] = starpostwp; // TODO: get these out of kartstuff, it causes desync
p->kartstuff[k_offroad] = offroad; p->kartstuff[k_offroad] = offroad;
p->kartstuff[k_balloon] = balloon;
p->kartstuff[k_comebackpoints] = comebackpoints;
p->kartstuff[k_comebackshowninfo] = comebackshowninfo;
p->kartstuff[k_comebacktimer] = comebacktime;
// Don't do anything immediately // Don't do anything immediately
p->pflags |= PF_USEDOWN; p->pflags |= PF_USEDOWN;
p->pflags |= PF_ATTACKDOWN; p->pflags |= PF_ATTACKDOWN;
@ -2308,7 +2360,7 @@ void G_PlayerReborn(INT32 player)
p->panim = PA_IDLE; // standing animation p->panim = PA_IDLE; // standing animation
if ((netgame || multiplayer) && !p->spectator) if ((netgame || multiplayer) && !p->spectator)
p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent p->powers[pw_flashing] = K_GetKartFlashing()-1; // Babysitting deterrent
if (p-players == consoleplayer) if (p-players == consoleplayer)
{ {
@ -2399,6 +2451,9 @@ static boolean G_CheckSpot(INT32 playernum, mapthing_t *mthing)
if (!P_CheckPosition(players[playernum].mo, x, y)) if (!P_CheckPosition(players[playernum].mo, x, y))
return false; return false;
if (!K_CheckPlayersRespawnColliding(playernum, x, y))
return false;
return true; return true;
} }
@ -2644,6 +2699,7 @@ void G_DoReborn(INT32 playernum)
player->starposty = 0; player->starposty = 0;
player->starpostz = 0; player->starpostz = 0;
player->starpostnum = 0; player->starpostnum = 0;
player->starpostcount = 0;
} }
if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD)) if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD))
{ {
@ -2801,7 +2857,8 @@ boolean G_GametypeHasTeams(void)
// //
boolean G_GametypeHasSpectators(void) boolean G_GametypeHasSpectators(void)
{ {
return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE); return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE
&& gametype != GT_MATCH); // srb2kart: temporary?
} }
// //
@ -3066,7 +3123,7 @@ static void G_DoWorldDone(void)
// don't reset player between maps // don't reset player between maps
D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false); D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false);
else else
// resetplayer in match/chaos/tag/CTF/race for more equality // resetplayer in match/tag/CTF for more equality
D_MapChange(nextmap+1, gametype, ultimatemode, true, 0, false, false); D_MapChange(nextmap+1, gametype, ultimatemode, true, 0, false, false);
} }
@ -3692,6 +3749,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
players[i].playerstate = PST_REBORN; players[i].playerstate = PST_REBORN;
players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0; players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0;
players[i].starpostx = players[i].starposty = players[i].starpostz = 0; players[i].starpostx = players[i].starposty = players[i].starpostz = 0;
players[i].starpostcount = 0; // srb2kart
if (netgame || multiplayer) if (netgame || multiplayer)
{ {

View file

@ -109,6 +109,7 @@ typedef struct
FLOAT fovxangle, fovyangle; FLOAT fovxangle, fovyangle;
INT32 splitscreen; INT32 splitscreen;
boolean flip; // screenflip boolean flip; // screenflip
boolean mirror; // SRB2Kart: Mirror Mode
} FTransform; } FTransform;
// Transformed vector, as passed to HWR API // Transformed vector, as passed to HWR API

View file

@ -5591,6 +5591,11 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
else else
atransform.flip = false; atransform.flip = false;
if (*type == postimg_mirror)
atransform.mirror = true;
else
atransform.mirror = false;
atransform.x = gr_viewx; // FIXED_TO_FLOAT(viewx) atransform.x = gr_viewx; // FIXED_TO_FLOAT(viewx)
atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy) atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy)
atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz) atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz)
@ -5610,6 +5615,11 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
else else
stransform.flip = false; stransform.flip = false;
if (*type == postimg_mirror)
stransform.mirror = true;
else
stransform.mirror = false;
stransform.x = 0.0f; stransform.x = 0.0f;
stransform.y = 0.0f; stransform.y = 0.0f;
stransform.z = 0.0f; stransform.z = 0.0f;
@ -5821,6 +5831,11 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
else else
atransform.flip = false; atransform.flip = false;
if (*type == postimg_mirror)
atransform.mirror = true;
else
atransform.mirror = false;
atransform.x = gr_viewx; // FIXED_TO_FLOAT(viewx) atransform.x = gr_viewx; // FIXED_TO_FLOAT(viewx)
atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy) atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy)
atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz) atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz)
@ -5840,6 +5855,11 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
else else
stransform.flip = false; stransform.flip = false;
if (*type == postimg_mirror)
stransform.mirror = true;
else
stransform.mirror = false;
stransform.x = 0.0f; stransform.x = 0.0f;
stransform.y = 0.0f; stransform.y = 0.0f;
stransform.z = 0.0f; stransform.z = 0.0f;

View file

@ -2013,7 +2013,9 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
// keep a trace of the transformation for md2 // keep a trace of the transformation for md2
memcpy(&md2_transform, stransform, sizeof (md2_transform)); memcpy(&md2_transform, stransform, sizeof (md2_transform));
if (stransform->flip) if (stransform->mirror)
pglScalef(-stransform->scalex, stransform->scaley, -stransform->scalez);
else if (stransform->flip)
pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez); pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez);
else else
pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez); pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez);

View file

@ -361,14 +361,14 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
numwords = COM_Argc() - usedargs; numwords = COM_Argc() - usedargs;
I_Assert(numwords > 0); I_Assert(numwords > 0);
if (cv_mute.value && !(server || adminplayer == consoleplayer)) if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
{ {
CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n"));
return; return;
} }
// Only servers/admins can CSAY. // Only servers/admins can CSAY.
if(!server && adminplayer != consoleplayer) if(!server && IsPlayerAdmin(consoleplayer))
flags &= ~HU_CSAY; flags &= ~HU_CSAY;
// We handle HU_SERVER_SAY, not the caller. // We handle HU_SERVER_SAY, not the caller.
@ -462,7 +462,7 @@ static void Command_CSay_f(void)
return; return;
} }
if(!server && adminplayer != consoleplayer) if(!server && !IsPlayerAdmin(consoleplayer))
{ {
CONS_Alert(CONS_NOTICE, M_GetText("Only servers and admins can use csay.\n")); CONS_Alert(CONS_NOTICE, M_GetText("Only servers and admins can use csay.\n"));
return; return;
@ -491,7 +491,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
msg = (char *)*p; msg = (char *)*p;
SKIPSTRING(*p); SKIPSTRING(*p);
if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && playernum != adminplayer) if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
CONS_Alert(CONS_WARNING, cv_mute.value ? CONS_Alert(CONS_WARNING, cv_mute.value ?
M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"), M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"),
@ -589,7 +589,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
// Give admins and remote admins their symbols. // Give admins and remote admins their symbols.
if (playernum == serverplayer) if (playernum == serverplayer)
tempchar = (char *)Z_Calloc(strlen(cstart) + strlen(adminchar) + 1, PU_STATIC, NULL); tempchar = (char *)Z_Calloc(strlen(cstart) + strlen(adminchar) + 1, PU_STATIC, NULL);
else if (playernum == adminplayer) else if (IsPlayerAdmin(playernum))
tempchar = (char *)Z_Calloc(strlen(cstart) + strlen(remotechar) + 1, PU_STATIC, NULL); tempchar = (char *)Z_Calloc(strlen(cstart) + strlen(remotechar) + 1, PU_STATIC, NULL);
if (tempchar) if (tempchar)
{ {
@ -724,7 +724,7 @@ static void HU_queueChatChar(char c)
} while (c); } while (c);
// last minute mute check // last minute mute check
if (cv_mute.value && !(server || adminplayer == consoleplayer)) if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
{ {
CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n"));
return; return;
@ -782,9 +782,9 @@ boolean HU_Responder(event_t *ev)
{ {
// enter chat mode // enter chat mode
if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1]) if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1])
&& netgame && (!cv_mute.value || server || (adminplayer == consoleplayer))) && netgame && (!cv_mute.value || server || IsPlayerAdmin(consoleplayer)))
{ {
if (cv_mute.value && !(server || adminplayer == consoleplayer)) if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
return false; return false;
chat_on = true; chat_on = true;
w_chat[0] = 0; w_chat[0] = 0;
@ -792,9 +792,9 @@ boolean HU_Responder(event_t *ev)
return true; return true;
} }
if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1]) if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1])
&& netgame && (!cv_mute.value || server || (adminplayer == consoleplayer))) && netgame && (!cv_mute.value || server || (IsPlayerAdmin(consoleplayer))))
{ {
if (cv_mute.value && !(server || adminplayer == consoleplayer)) if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
return false; return false;
chat_on = true; chat_on = true;
w_chat[0] = 0; w_chat[0] = 0;

View file

@ -57,8 +57,8 @@ char sprnames[NUMSPRITES + 1][5] =
//SRB2kart Sprites //SRB2kart Sprites
"SPRG","BSPR","RNDM","RPOP","KFRE","DRIF","DSMO","FITM","DFAK","BANA", "SPRG","BSPR","RNDM","RPOP","KFRE","DRIF","DSMO","FITM","DFAK","BANA",
"DBAN","GSHE","DGSH","RSHE","DRSH","BOMB","BLIG","LIGH","SINK","SITR", "DBAN","GSHE","DGSH","RSHE","DRSH","BOMB","BLIG","LIGH","SINK","SITR",
"LAKI","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM", "KBLN","LAKI","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB",
"SACO","CRAB","SHAD","BUMP","FLEN","CLAS","PSHW" "CHOM","SACO","CRAB","SHAD","BUMP","FLEN","CLAS","PSHW","ARRO","PBOM"
}; };
// Doesn't work with g++, needs actionf_p1 (don't modify this comment) // Doesn't work with g++, needs actionf_p1 (don't modify this comment)
@ -2704,6 +2704,10 @@ state_t states[NUMSTATES] =
{SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2 {SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2
{SPR_SITR, 2, 3, {NULL}, 0, 0, S_NULL}, // S_SINKTRAIL3 {SPR_SITR, 2, 3, {NULL}, 0, 0, S_NULL}, // S_SINKTRAIL3
{SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BATTLEBALLOON1}, // S_BATTLEBALLOON1
{SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_BATTLEBALLOON2}, // S_BATTLEBALLOON2
{SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_BATTLEBALLOON3}, // S_BATTLEBALLOON3
{SPR_LAKI, 0, 64, {NULL}, 1, 0, S_LAKITU2}, // S_LAKITU1 {SPR_LAKI, 0, 64, {NULL}, 1, 0, S_LAKITU2}, // S_LAKITU1
{SPR_LAKI, 1, 35, {NULL}, 0, 0, S_NULL}, // S_LAKITU2 {SPR_LAKI, 1, 35, {NULL}, 0, 0, S_NULL}, // S_LAKITU2
@ -2857,6 +2861,29 @@ state_t states[NUMSTATES] =
{SPR_PSHW, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_FIREDITEM4}, // S_FIREDITEM3 {SPR_PSHW, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_FIREDITEM4}, // S_FIREDITEM3
{SPR_PSHW, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_NULL}, // S_FIREDITEM4 {SPR_PSHW, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_NULL}, // S_FIREDITEM4
// Above player arrow
{SPR_ARRO, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW
{SPR_ARRO, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_MUSHROOM
{SPR_ARRO, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_GREENSHELL
{SPR_ARRO, FF_FULLBRIGHT|3, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BANANA
{SPR_ARRO, FF_FULLBRIGHT|4, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_FAKEITEM
{SPR_ARRO, FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOO
{SPR_ARRO, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_FEATHER
{SPR_ARRO, FF_FULLBRIGHT|7, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_REDSHELL
{SPR_ARRO, FF_FULLBRIGHT|8, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOBOMB
{SPR_ARRO, FF_FULLBRIGHT|9, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_FIREFLOWER
{SPR_ARRO, FF_FULLBRIGHT|10, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_TRIPLEGREENSHELL
{SPR_ARRO, FF_FULLBRIGHT|11, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_TRIPLEBANANA
{SPR_ARRO, FF_FULLBRIGHT|12, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_TRIPLEREDSHELL
{SPR_ARRO, FF_FULLBRIGHT|13, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_STAR
{SPR_ARRO, FF_FULLBRIGHT|14, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_MEGASHROOM
{SPR_ARRO, FF_FULLBRIGHT|15, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_KITCHENSINK
{SPR_ARRO, FF_FULLBRIGHT|16, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_EMPTY
{SPR_ARRO, FF_FULLBRIGHT|FF_ANIMATE|1, -1, {NULL}, 5, 3, S_NULL}, // S_PLAYERARROW_ROULETTE
{SPR_PBOM, FF_ANIMATE, -1, {NULL}, 3, 3, S_NULL}, // S_PLAYERBOMB
{SPR_PBOM, 4, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERBOMB_WHEEL
#ifdef SEENAMES #ifdef SEENAMES
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
#endif #endif
@ -15112,6 +15139,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_BATTLEBALLOON
-1, // doomednum
S_BATTLEBALLOON1,// 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
4*FRACUNIT, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
100, // mass
1, // damage
sfx_None, // activesound
MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_LAKITU { // MT_LAKITU
-1, // doomednum -1, // doomednum
S_LAKITU1, // spawnstate S_LAKITU1, // spawnstate
@ -16596,6 +16650,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_PLAYERARROW
-1, // doomednum
S_PLAYERARROW, // 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
36*FRACUNIT, // radius
37*FRACUNIT, // height
0, // display offset
16, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
// ============================================================================================================================// // ============================================================================================================================//
#ifdef SEENAMES #ifdef SEENAMES

View file

@ -598,6 +598,7 @@ typedef enum sprite
SPR_LIGH, // Lightning SPR_LIGH, // Lightning
SPR_SINK, // Kitchen Sink SPR_SINK, // Kitchen Sink
SPR_SITR, // Kitchen Sink Trail SPR_SITR, // Kitchen Sink Trail
SPR_KBLN, // Battle Mode Balloon
SPR_LAKI, // Lakitu SPR_LAKI, // Lakitu
@ -620,6 +621,10 @@ typedef enum sprite
SPR_CLAS, // items clash SPR_CLAS, // items clash
SPR_PSHW, // thrown indicator SPR_PSHW, // thrown indicator
SPR_ARRO, // player arrows
SPR_PBOM, // player bomb
SPR_FIRSTFREESLOT, SPR_FIRSTFREESLOT,
SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
NUMSPRITES NUMSPRITES
@ -3212,6 +3217,11 @@ typedef enum state
S_SINKTRAIL2, S_SINKTRAIL2,
S_SINKTRAIL3, S_SINKTRAIL3,
// Battle Mode balloons
S_BATTLEBALLOON1,
S_BATTLEBALLOON2,
S_BATTLEBALLOON3,
// Lakitu // Lakitu
S_LAKITU1, S_LAKITU1,
S_LAKITU2, S_LAKITU2,
@ -3373,6 +3383,28 @@ typedef enum state
S_FIREDITEM3, S_FIREDITEM3,
S_FIREDITEM4, S_FIREDITEM4,
S_PLAYERARROW, // Above player arrow
S_PLAYERARROW_MUSHROOM,
S_PLAYERARROW_GREENSHELL,
S_PLAYERARROW_BANANA,
S_PLAYERARROW_FAKEITEM,
S_PLAYERARROW_BOO,
S_PLAYERARROW_FEATHER,
S_PLAYERARROW_REDSHELL,
S_PLAYERARROW_BOBOMB,
S_PLAYERARROW_FIREFLOWER,
S_PLAYERARROW_TRIPLEGREENSHELL,
S_PLAYERARROW_TRIPLEBANANA,
S_PLAYERARROW_TRIPLEREDSHELL,
S_PLAYERARROW_STAR,
S_PLAYERARROW_MEGASHROOM,
S_PLAYERARROW_KITCHENSINK,
S_PLAYERARROW_EMPTY,
S_PLAYERARROW_ROULETTE,
S_PLAYERBOMB,
S_PLAYERBOMB_WHEEL,
#ifdef SEENAMES #ifdef SEENAMES
S_NAMECHECK, S_NAMECHECK,
#endif #endif
@ -3947,6 +3979,8 @@ typedef enum mobj_type
MT_SINK, // Kitchen Sink Stuff MT_SINK, // Kitchen Sink Stuff
MT_SINKTRAIL, MT_SINKTRAIL,
MT_BATTLEBALLOON, // Battle Mode balloons
MT_LAKITU, MT_LAKITU,
MT_POKEY, // Huh, thought this was a default asset for some reason, guess not. MT_POKEY, // Huh, thought this was a default asset for some reason, guess not.
@ -4017,6 +4051,8 @@ typedef enum mobj_type
MT_FIREDITEM, MT_FIREDITEM,
MT_PLAYERARROW,
#ifdef SEENAMES #ifdef SEENAMES
MT_NAMECHECK, MT_NAMECHECK,
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -9,28 +9,39 @@
#include "doomdef.h" #include "doomdef.h"
#include "d_player.h" // Need for player_t #include "d_player.h" // Need for player_t
UINT8 colortranslations[MAXSKINCOLORS][16];
extern const char *KartColor_Names[MAXSKINCOLORS]; extern const char *KartColor_Names[MAXSKINCOLORS];
void K_StarmanColormap(UINT8 *dest_colormap, UINT8 skincolor);
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color); void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color);
UINT8 K_GetKartColorByName(const char *name); UINT8 K_GetKartColorByName(const char *name);
void K_RegisterKartStuff(void); void K_RegisterKartStuff(void);
void K_KartBouncer(void); UINT8 K_GetKartCC(void);
void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce);
void K_LakituChecker(player_t *player);
void K_KartMoveAnimation(player_t *player); void K_KartMoveAnimation(player_t *player);
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
void K_SpinPlayer(player_t *player, mobj_t *source); void K_SpinPlayer(player_t *player, mobj_t *source);
void K_SquishPlayer(player_t *player, mobj_t *source); void K_SquishPlayer(player_t *player, mobj_t *source);
void K_ExplodePlayer(player_t *player, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *source);
void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit); void K_StealBalloon(player_t *player, player_t *victim, boolean force);
void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source);
void K_SpawnDriftTrail(player_t *player); void K_SpawnDriftTrail(player_t *player);
void K_DoMushroom(player_t *player, boolean doPFlag, boolean startboost); void K_DoMushroom(player_t *player, boolean doPFlag, boolean startboost);
void K_DoBouncePad(mobj_t *mo, fixed_t vertispeed);
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
void K_MomentumToFacing(player_t *player); void K_MomentumToFacing(player_t *player);
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower); fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower);
fixed_t K_GetKartAccel(player_t *player);
UINT16 K_GetKartFlashing(void);
fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove); fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove);
void K_MoveKartPlayer(player_t *player, boolean onground); void K_MoveKartPlayer(player_t *player, boolean onground);
void K_CheckBalloons(void);
void K_LoadKartHUDGraphics(void); void K_LoadKartHUDGraphics(void);
fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fixed_t my);
void K_drawKartHUD(void); void K_drawKartHUD(void);
// ========================================================================= // =========================================================================

View file

@ -20,6 +20,7 @@
#include "m_random.h" #include "m_random.h"
#include "s_sound.h" #include "s_sound.h"
#include "g_game.h" #include "g_game.h"
#include "k_kart.h"
#include "lua_script.h" #include "lua_script.h"
#include "lua_libs.h" #include "lua_libs.h"
@ -1009,10 +1010,11 @@ static int lib_pTeleportMove(lua_State *L)
static int lib_pSlideMove(lua_State *L) static int lib_pSlideMove(lua_State *L)
{ {
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
boolean forceslide = luaL_checkboolean(L, 2);
NOHUD NOHUD
if (!mo) if (!mo)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
P_SlideMove(mo); P_SlideMove(mo, forceslide);
return 0; return 0;
} }
@ -1980,6 +1982,184 @@ static int lib_gTicsToMilliseconds(lua_State *L)
return 1; return 1;
} }
// K_KART
////////////
static int lib_kGetKartColorByName(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
//HUDSAFE
lua_pushinteger(L, K_GetKartColorByName(name));
return 1;
}
static int lib_kGetKartCC(lua_State *L)
{
//HUDSAFE
lua_pushinteger(L, K_GetKartCC());
return 1;
}
static int lib_kKartBouncing(lua_State *L)
{
mobj_t *mobj1 = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *mobj2 = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
boolean bounce = luaL_checkboolean(L, 3);
NOHUD
if (!mobj1)
return LUA_ErrInvalid(L, "mobj_t");
if (!mobj2)
return LUA_ErrInvalid(L, "mobj_t");
K_KartBouncing(mobj1, mobj2, bounce);
return 0;
}
static int lib_kSpinPlayer(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
K_SpinPlayer(player, source);
return 0;
}
static int lib_kSquishPlayer(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
K_SquishPlayer(player, source);
return 0;
}
static int lib_kExplodePlayer(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
K_ExplodePlayer(player, source);
return 0;
}
static int lib_kStealBalloon(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
boolean force = luaL_checkboolean(L, 3);
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (!victim)
return LUA_ErrInvalid(L, "player_t");
K_StealBalloon(player, victim, force);
return 0;
}
static int lib_kSpawnKartExplosion(lua_State *L)
{
fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = luaL_checkfixed(L, 2);
fixed_t z = luaL_checkfixed(L, 3);
fixed_t radius = luaL_checkfixed(L, 4);
INT32 number = (INT32)luaL_checkinteger(L, 5);
mobjtype_t type = luaL_checkinteger(L, 6);
angle_t rotangle = luaL_checkangle(L, 7);
boolean spawncenter = luaL_checkboolean(L, 8);
boolean ghostit = luaL_checkboolean(L, 9);
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 10, META_MOBJ));
NOHUD
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
K_SpawnKartExplosion(x, y, z, radius, number, type, rotangle, spawncenter, ghostit, source);
return 0;
}
static int lib_kSpawnDriftTrail(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_SpawnDriftTrail(player);
return 0;
}
static int lib_kDoMushroom(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean doPFlag = luaL_checkboolean(L, 2);
boolean startboost = luaL_checkboolean(L, 3);
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_DoMushroom(player, doPFlag, startboost);
return 0;
}
static int lib_kDoBouncePad(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t vertispeed = luaL_checkfixed(L, 2);
NOHUD
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
K_DoBouncePad(mo, vertispeed);
return 0;
}
static int lib_kMomentumToFacing(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_MomentumToFacing(player);
return 0;
}
static int lib_kGetKartSpeed(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean doboostpower = luaL_checkboolean(L, 2);
//HUDSAFE
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushinteger(L, K_GetKartSpeed(player, doboostpower));
return 0;
}
static int lib_kGetKartAccel(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
//HUDSAFE
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushinteger(L, K_GetKartAccel(player));
return 0;
}
static int lib_kGetKartFlashing(lua_State *L)
{
//player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
//HUDSAFE
//if (!player)
//return LUA_ErrInvalid(L, "player_t");
lua_pushinteger(L, K_GetKartFlashing());
return 0;
}
static luaL_Reg lib[] = { static luaL_Reg lib[] = {
{"print", lib_print}, {"print", lib_print},
{"EvalMath", lib_evalMath}, {"EvalMath", lib_evalMath},
@ -2153,6 +2333,23 @@ static luaL_Reg lib[] = {
{"G_TicsToCentiseconds",lib_gTicsToCentiseconds}, {"G_TicsToCentiseconds",lib_gTicsToCentiseconds},
{"G_TicsToMilliseconds",lib_gTicsToMilliseconds}, {"G_TicsToMilliseconds",lib_gTicsToMilliseconds},
// k_kart
{"K_GetKartColorByName",lib_kGetKartColorByName},
{"K_GetKartCC",lib_kGetKartCC},
{"K_KartBouncing",lib_kKartBouncing},
{"K_SpinPlayer",lib_kSpinPlayer},
{"K_SquishPlayer",lib_kSquishPlayer},
{"K_ExplodePlayer",lib_kExplodePlayer},
{"K_StealBalloon",lib_kStealBalloon},
{"K_SpawnKartExplosion",lib_kSpawnKartExplosion},
{"K_SpawnDriftTrail",lib_kSpawnDriftTrail},
{"K_DoMushroom",lib_kDoMushroom},
{"K_DoBouncePad",lib_kDoBouncePad},
{"K_MomentumToFacing",lib_kMomentumToFacing},
{"K_GetKartSpeed",lib_kGetKartSpeed},
{"K_GetKartAccel",lib_kGetKartAccel},
{"K_GetKartFlashing",lib_kGetKartFlashing},
{NULL, NULL} {NULL, NULL}
}; };

View file

@ -55,7 +55,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
lua_pop(gL, 1); // pop flags lua_pop(gL, 1); // pop flags
// requires server/admin and the player is not one of them // requires server/admin and the player is not one of them
if ((flags & 1) && playernum != serverplayer && playernum != adminplayer) if ((flags & 1) && playernum != serverplayer && !IsPlayerAdmin(playernum))
goto deny; goto deny;
lua_rawgeti(gL, -1, 1); // push function from command info table lua_rawgeti(gL, -1, 1); // push function from command info table
@ -131,7 +131,7 @@ void COM_Lua_f(void)
UINT8 argc; UINT8 argc;
lua_pop(gL, 1); // pop command info table lua_pop(gL, 1); // pop command info table
if (flags & 1 && !server && adminplayer != playernum) // flag 1: only server/admin can use this command. if (flags & 1 && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command.
{ {
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
return; return;

View file

@ -1235,6 +1235,10 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->levelflags); lua_pushinteger(L, header->levelflags);
else if (fastcmp(field,"menuflags")) else if (fastcmp(field,"menuflags"))
lua_pushinteger(L, header->menuflags); lua_pushinteger(L, header->menuflags);
/*else if (fastcmp(field,"automap"))
lua_pushboolean(L, header->automap);*/
else if (fastcmp(field,"mobj_scale"))
lua_pushfixed(L, header->mobj_scale);
// TODO add support for reading numGradedMares and grades // TODO add support for reading numGradedMares and grades
else { else {
// Read custom vars now // Read custom vars now

View file

@ -130,8 +130,6 @@ static int player_get(lua_State *L)
LUA_PushUserdata(L, plr->powers, META_POWERS); LUA_PushUserdata(L, plr->powers, META_POWERS);
else if (fastcmp(field,"kartstuff")) else if (fastcmp(field,"kartstuff"))
LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF); LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF);
else if (fastcmp(field,"collide"))
LUA_PushUserdata(L, plr->collide, META_COLLIDE);
else if (fastcmp(field,"frameangle")) else if (fastcmp(field,"frameangle"))
lua_pushangle(L, plr->frameangle); lua_pushangle(L, plr->frameangle);
else if (fastcmp(field,"pflags")) else if (fastcmp(field,"pflags"))
@ -152,9 +150,9 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->dashtime); lua_pushinteger(L, plr->dashtime);
// SRB2kart // SRB2kart
else if (fastcmp(field,"kartspeed")) else if (fastcmp(field,"kartspeed"))
lua_pushfixed(L, plr->kartspeed); lua_pushinteger(L, plr->kartspeed);
else if (fastcmp(field,"kartweight")) else if (fastcmp(field,"kartweight"))
lua_pushfixed(L, plr->kartweight); lua_pushinteger(L, plr->kartweight);
// //
else if (fastcmp(field,"normalspeed")) else if (fastcmp(field,"normalspeed"))
lua_pushfixed(L, plr->normalspeed); lua_pushfixed(L, plr->normalspeed);
@ -248,6 +246,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->starpostz); lua_pushinteger(L, plr->starpostz);
else if (fastcmp(field,"starpostnum")) else if (fastcmp(field,"starpostnum"))
lua_pushinteger(L, plr->starpostnum); lua_pushinteger(L, plr->starpostnum);
else if (fastcmp(field,"starpostcount"))
lua_pushinteger(L, plr->starpostcount);
else if (fastcmp(field,"starposttime")) else if (fastcmp(field,"starposttime"))
lua_pushinteger(L, plr->starposttime); lua_pushinteger(L, plr->starposttime);
else if (fastcmp(field,"starpostangle")) else if (fastcmp(field,"starpostangle"))
@ -414,10 +414,14 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"dashtime")) else if (fastcmp(field,"dashtime"))
plr->dashtime = (INT32)luaL_checkinteger(L, 3); plr->dashtime = (INT32)luaL_checkinteger(L, 3);
// SRB2kart // SRB2kart
else if (fastcmp(field,"kartstuff"))
return NOSET;
else if (fastcmp(field,"frameangle"))
plr->frameangle = luaL_checkangle(L, 3);
else if (fastcmp(field,"kartspeed")) else if (fastcmp(field,"kartspeed"))
plr->kartspeed = (UINT8)luaL_checkfixed(L, 3); plr->kartspeed = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"kartweight")) else if (fastcmp(field,"kartweight"))
plr->kartweight = (UINT8)luaL_checkfixed(L, 3); plr->kartweight = (UINT8)luaL_checkinteger(L, 3);
// //
else if (fastcmp(field,"normalspeed")) else if (fastcmp(field,"normalspeed"))
plr->normalspeed = luaL_checkfixed(L, 3); plr->normalspeed = luaL_checkfixed(L, 3);
@ -511,6 +515,8 @@ static int player_set(lua_State *L)
plr->starpostz = (INT16)luaL_checkinteger(L, 3); plr->starpostz = (INT16)luaL_checkinteger(L, 3);
else if (fastcmp(field,"starpostnum")) else if (fastcmp(field,"starpostnum"))
plr->starpostnum = (INT32)luaL_checkinteger(L, 3); plr->starpostnum = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"starpostcount"))
plr->starpostcount = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"starposttime")) else if (fastcmp(field,"starposttime"))
plr->starposttime = (tic_t)luaL_checkinteger(L, 3); plr->starposttime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"starpostangle")) else if (fastcmp(field,"starpostangle"))
@ -672,6 +678,38 @@ static int power_len(lua_State *L)
return 1; return 1;
} }
// kartstuff, ks -> kartstuff[ks]
static int kartstuff_get(lua_State *L)
{
INT32 *kartstuff = *((INT32 **)luaL_checkudata(L, 1, META_KARTSTUFF));
kartstufftype_t ks = luaL_checkinteger(L, 2);
if (ks >= NUMKARTSTUFF)
return luaL_error(L, LUA_QL("kartstufftype_t") " cannot be %u", ks);
lua_pushinteger(L, kartstuff[ks]);
return 1;
}
// kartstuff, ks, value -> kartstuff[ks] = value
static int kartstuff_set(lua_State *L)
{
INT32 *kartstuff = *((INT32 **)luaL_checkudata(L, 1, META_KARTSTUFF));
kartstufftype_t ks = luaL_checkinteger(L, 2);
INT32 i = (INT32)luaL_checkinteger(L, 3);
if (ks >= NUMKARTSTUFF)
return luaL_error(L, LUA_QL("kartstufftype_t") " cannot be %u", ks);
if (hud_running)
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
kartstuff[ks] = i;
return 0;
}
// #kartstuff -> NUMKARTSTUFF
static int kartstuff_len(lua_State *L)
{
lua_pushinteger(L, NUMKARTSTUFF);
return 1;
}
#define NOFIELD luaL_error(L, LUA_QL("ticcmd_t") " has no field named " LUA_QS, field) #define NOFIELD luaL_error(L, LUA_QL("ticcmd_t") " has no field named " LUA_QS, field)
static int ticcmd_get(lua_State *L) static int ticcmd_get(lua_State *L)
@ -749,6 +787,17 @@ int LUA_PlayerLib(lua_State *L)
lua_setfield(L, -2, "__len"); lua_setfield(L, -2, "__len");
lua_pop(L,1); lua_pop(L,1);
luaL_newmetatable(L, META_KARTSTUFF);
lua_pushcfunction(L, kartstuff_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, kartstuff_set);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, kartstuff_len);
lua_setfield(L, -2, "__len");
lua_pop(L,1);
luaL_newmetatable(L, META_TICCMD); luaL_newmetatable(L, META_TICCMD);
lua_pushcfunction(L, ticcmd_get); lua_pushcfunction(L, ticcmd_get);
lua_setfield(L, -2, "__index"); lua_setfield(L, -2, "__index");

View file

@ -435,7 +435,6 @@ void LUA_InvalidatePlayer(player_t *player)
LUA_InvalidateUserdata(player); LUA_InvalidateUserdata(player);
LUA_InvalidateUserdata(player->powers); LUA_InvalidateUserdata(player->powers);
LUA_InvalidateUserdata(player->kartstuff); LUA_InvalidateUserdata(player->kartstuff);
LUA_InvalidateUserdata(player->collide);
LUA_InvalidateUserdata(&player->cmd); LUA_InvalidateUserdata(&player->cmd);
} }

View file

@ -165,10 +165,10 @@ static int skin_get(lua_State *L)
break; break;
// SRB2kart // SRB2kart
case skin_kartspeed: case skin_kartspeed:
lua_pushfixed(L, skin->kartspeed); lua_pushinteger(L, skin->kartspeed);
break; break;
case skin_kartweight: case skin_kartweight:
lua_pushfixed(L, skin->kartweight); lua_pushinteger(L, skin->kartweight);
break; break;
// //
case skin_normalspeed: case skin_normalspeed:

View file

@ -33,6 +33,8 @@
#include "z_zone.h" #include "z_zone.h"
#include "p_slopes.h" #include "p_slopes.h"
#include "k_kart.h" // srb2kart
#include "lua_script.h" #include "lua_script.h"
#include "lua_hook.h" #include "lua_hook.h"
@ -1348,7 +1350,7 @@ void Command_ObjectPlace_f(void)
players[0].mo->color = op_oldcolor; players[0].mo->color = op_oldcolor;
// This is necessary for recovery of dying players. // This is necessary for recovery of dying players.
if (players[0].powers[pw_flashing] >= flashingtics) if (players[0].powers[pw_flashing] >= K_GetKartFlashing())
players[0].powers[pw_flashing] = flashingtics - 1; players[0].powers[pw_flashing] = K_GetKartFlashing() - 1;
} }
} }

View file

@ -271,8 +271,8 @@ static void M_SetupMultiPlayer2(INT32 choice);
// Options // Options
// Split into multiple parts due to size // Split into multiple parts due to size
// Controls // Controls
menu_t OP_ControlsDef, OP_ControlListDef, OP_MoveControlsDef; menu_t OP_ControlsDef, /*OP_ControlListDef,*/ OP_MoveControlsDef;
menu_t /*OP_MPControlsDef,*/ OP_CameraControlsDef, OP_MiscControlsDef; menu_t /*OP_MPControlsDef, OP_CameraControlsDef, OP_MiscControlsDef,*/ OP_CustomControlsDef;
menu_t OP_P1ControlsDef, OP_P2ControlsDef, OP_MouseOptionsDef; menu_t OP_P1ControlsDef, OP_P2ControlsDef, OP_MouseOptionsDef;
menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def; menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def;
static void M_VideoModeMenu(INT32 choice); static void M_VideoModeMenu(INT32 choice);
@ -375,7 +375,7 @@ consvar_t cv_chooseskin = {"chooseskin", DEFAULTSKIN, CV_HIDEN|CV_CALL, skins_co
// When you add gametypes here, don't forget to update them in CV_AddValue! // When you add gametypes here, don't forget to update them in CV_AddValue!
CV_PossibleValue_t gametype_cons_t[] = CV_PossibleValue_t gametype_cons_t[] =
{ {
{GT_RACE, "Race"}, {GT_MATCH, "Match"}, {GT_RACE, "Race"}, {GT_MATCH, "Battle"},
/* // SRB2kart /* // SRB2kart
{GT_COOP, "Co-op"}, {GT_COOP, "Co-op"},
@ -977,9 +977,9 @@ static menuitem_t MP_SplitServerMenu[] =
static menuitem_t MP_PlayerSetupMenu[] = static menuitem_t MP_PlayerSetupMenu[] =
{ {
{IT_KEYHANDLER | IT_STRING, NULL, "Your name", M_HandleSetupMultiPlayer, 0}, {IT_KEYHANDLER | IT_STRING, NULL, "Name", M_HandleSetupMultiPlayer, 0},
{IT_KEYHANDLER | IT_STRING, NULL, "Your color", M_HandleSetupMultiPlayer, 16}, {IT_KEYHANDLER | IT_STRING, NULL, "Character", M_HandleSetupMultiPlayer, 16}, // Tails 01-18-2001
{IT_KEYHANDLER | IT_STRING, NULL, "Your player", M_HandleSetupMultiPlayer, 96}, // Tails 01-18-2001 {IT_KEYHANDLER | IT_STRING, NULL, "Color", M_HandleSetupMultiPlayer, 152},
}; };
// ------------------------------------ // ------------------------------------
@ -1030,28 +1030,47 @@ static menuitem_t OP_P2ControlsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 80}, {IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 80},
}; };
static menuitem_t OP_ControlListMenu[] = /*static menuitem_t OP_ControlListMenu[] =
{ {
{IT_SUBMENU | IT_STRING, NULL, "Kart Controls...", &OP_MoveControlsDef, 10}, {IT_SUBMENU | IT_STRING, NULL, "Kart Controls...", &OP_MoveControlsDef, 10},
// {IT_SUBMENU | IT_STRING, NULL, "Multiplayer Controls...", &OP_MPControlsDef, 20}, // {IT_SUBMENU | IT_STRING, NULL, "Multiplayer Controls...", &OP_MPControlsDef, 20},
{IT_SUBMENU | IT_STRING, NULL, "Camera Controls...", &OP_CameraControlsDef, 20}, // {IT_SUBMENU | IT_STRING, NULL, "Camera Controls...", &OP_CameraControlsDef, 20},
{IT_SUBMENU | IT_STRING, NULL, "Miscellaneous Controls...", &OP_MiscControlsDef, 30}, // {IT_SUBMENU | IT_STRING, NULL, "Miscellaneous Controls...", &OP_MiscControlsDef, 20},
}; };*/
static menuitem_t OP_MoveControlsMenu[] = static menuitem_t OP_MoveControlsMenu[] =
{ {
{IT_CALL | IT_STRING2, NULL, "Forward", M_ChangeControl, gc_forward }, {IT_CALL | IT_STRING2, NULL, "Aim Forward", M_ChangeControl, gc_aimforward },
{IT_CALL | IT_STRING2, NULL, "Reverse", M_ChangeControl, gc_backward }, {IT_CALL | IT_STRING2, NULL, "Aim Backward", M_ChangeControl, gc_aimbackward},
{IT_CALL | IT_STRING2, NULL, "Turn Left", M_ChangeControl, gc_turnleft }, {IT_CALL | IT_STRING2, NULL, "Turn Left", M_ChangeControl, gc_turnleft },
{IT_CALL | IT_STRING2, NULL, "Turn Right", M_ChangeControl, gc_turnright }, {IT_CALL | IT_STRING2, NULL, "Turn Right", M_ChangeControl, gc_turnright },
{IT_CALL | IT_STRING2, NULL, "Accelerate", M_ChangeControl, gc_accelerate }, {IT_CALL | IT_STRING2, NULL, "Accelerate", M_ChangeControl, gc_accelerate },
{IT_CALL | IT_STRING2, NULL, "Drift", M_ChangeControl, gc_jump }, {IT_CALL | IT_STRING2, NULL, "Drift", M_ChangeControl, gc_jump },
{IT_CALL | IT_STRING2, NULL, "Brake", M_ChangeControl, gc_brake }, {IT_CALL | IT_STRING2, NULL, "Brake", M_ChangeControl, gc_brake },
{IT_CALL | IT_STRING2, NULL, "Use/Throw Item", M_ChangeControl, gc_fire }, {IT_CALL | IT_STRING2, NULL, "Use/Throw Item", M_ChangeControl, gc_fire },
{IT_CALL | IT_STRING2, NULL, "Look Backward", M_ChangeControl, gc_lookback },
{IT_CALL | IT_STRING2, NULL, "Toggle Chasecam", M_ChangeControl, gc_camtoggle },
{IT_CALL | IT_STRING2, NULL, "Pause", M_ChangeControl, gc_pause },
{IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console },
{IT_CALL | IT_STRING2, NULL, "Talk key", M_ChangeControl, gc_talkkey },
{IT_CALL | IT_STRING2, NULL, "Team-Talk key", M_ChangeControl, gc_teamkey },
{IT_CALL | IT_STRING2, NULL, "Rankings/Scores", M_ChangeControl, gc_scores },
{IT_CALL | IT_STRING2, NULL, "Spectate", M_ChangeControl, gc_spectate },
{IT_SUBMENU | IT_STRING, NULL, "Custom Actions...",&OP_CustomControlsDef, 128},
// {IT_CALL | IT_STRING2, NULL, "Strafe Left", M_ChangeControl, gc_strafeleft }, // {IT_CALL | IT_STRING2, NULL, "Strafe Left", M_ChangeControl, gc_strafeleft },
// {IT_CALL | IT_STRING2, NULL, "Strafe Right", M_ChangeControl, gc_straferight}, // {IT_CALL | IT_STRING2, NULL, "Strafe Right", M_ChangeControl, gc_straferight},
}; };
static menuitem_t OP_CustomControlsMenu[] =
{
{IT_CALL | IT_STRING2, NULL, "Custom Action 1", M_ChangeControl, gc_custom1},
{IT_CALL | IT_STRING2, NULL, "Custom Action 2", M_ChangeControl, gc_custom2},
{IT_CALL | IT_STRING2, NULL, "Custom Action 3", M_ChangeControl, gc_custom3},
};
// Obsolete thanks to Kart // Obsolete thanks to Kart
/*static menuitem_t OP_MPControlsMenu[] = /*static menuitem_t OP_MPControlsMenu[] =
{ {
@ -1064,18 +1083,14 @@ static menuitem_t OP_MoveControlsMenu[] =
// {IT_CALL | IT_STRING2, NULL, "Weapon Slot 5", M_ChangeControl, gc_wepslot5 }, // {IT_CALL | IT_STRING2, NULL, "Weapon Slot 5", M_ChangeControl, gc_wepslot5 },
// {IT_CALL | IT_STRING2, NULL, "Weapon Slot 6", M_ChangeControl, gc_wepslot6 }, // {IT_CALL | IT_STRING2, NULL, "Weapon Slot 6", M_ChangeControl, gc_wepslot6 },
// {IT_CALL | IT_STRING2, NULL, "Weapon Slot 7", M_ChangeControl, gc_wepslot7 }, // {IT_CALL | IT_STRING2, NULL, "Weapon Slot 7", M_ChangeControl, gc_wepslot7 },
};*/ };
static menuitem_t OP_CameraControlsMenu[] = static menuitem_t OP_CameraControlsMenu[] =
{ {
// {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, gc_lookup }, // {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, gc_lookup },
// {IT_CALL | IT_STRING2, NULL, "Look Down", M_ChangeControl, gc_lookdown }, // {IT_CALL | IT_STRING2, NULL, "Look Down", M_ChangeControl, gc_lookdown },
{IT_CALL | IT_STRING2, NULL, "Aim Forward", M_ChangeControl, gc_aimforward },
{IT_CALL | IT_STRING2, NULL, "Aim Backward", M_ChangeControl, gc_aimbackward },
// {IT_CALL | IT_STRING2, NULL, "Center View", M_ChangeControl, gc_centerview }, // {IT_CALL | IT_STRING2, NULL, "Center View", M_ChangeControl, gc_centerview },
// {IT_CALL | IT_STRING2, NULL, "Mouselook", M_ChangeControl, gc_mouseaiming }, // {IT_CALL | IT_STRING2, NULL, "Mouselook", M_ChangeControl, gc_mouseaiming },
{IT_CALL | IT_STRING2, NULL, "Look Backward", M_ChangeControl, gc_lookback },
{IT_CALL | IT_STRING2, NULL, "Toggle Chasecam", M_ChangeControl, gc_camtoggle },
}; };
static menuitem_t OP_MiscControlsMenu[] = static menuitem_t OP_MiscControlsMenu[] =
@ -1091,7 +1106,7 @@ static menuitem_t OP_MiscControlsMenu[] =
{IT_CALL | IT_STRING2, NULL, "Team-Talk key", M_ChangeControl, gc_teamkey }, {IT_CALL | IT_STRING2, NULL, "Team-Talk key", M_ChangeControl, gc_teamkey },
{IT_CALL | IT_STRING2, NULL, "Rankings/Scores", M_ChangeControl, gc_scores }, {IT_CALL | IT_STRING2, NULL, "Rankings/Scores", M_ChangeControl, gc_scores },
{IT_CALL | IT_STRING2, NULL, "Spectate", M_ChangeControl, gc_spectate }, {IT_CALL | IT_STRING2, NULL, "Spectate", M_ChangeControl, gc_spectate },
}; };*/
static menuitem_t OP_Joystick1Menu[] = static menuitem_t OP_Joystick1Menu[] =
{ {
@ -1657,12 +1672,12 @@ menu_t MP_RoomDef =
menu_t MP_SplitServerDef = MAPICONMENUSTYLE("M_MULTI", MP_SplitServerMenu, &MP_MainDef); menu_t MP_SplitServerDef = MAPICONMENUSTYLE("M_MULTI", MP_SplitServerMenu, &MP_MainDef);
menu_t MP_PlayerSetupDef = menu_t MP_PlayerSetupDef =
{ {
"M_SPLAYR", NULL, //"M_SPLAYR"
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t), sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
&MP_MainDef, &MP_MainDef,
MP_PlayerSetupMenu, MP_PlayerSetupMenu,
M_DrawSetupMultiPlayerMenu, M_DrawSetupMultiPlayerMenu,
27, 40, 32, 16,
0, 0,
M_QuitMultiPlayerMenu M_QuitMultiPlayerMenu
}; };
@ -1670,11 +1685,12 @@ menu_t MP_PlayerSetupDef =
// Options // Options
menu_t OP_MainDef = DEFAULTMENUSTYLE("M_OPTTTL", OP_MainMenu, &MainDef, 60, 30); menu_t OP_MainDef = DEFAULTMENUSTYLE("M_OPTTTL", OP_MainMenu, &MainDef, 60, 30);
menu_t OP_ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlsMenu, &OP_MainDef, 60, 30); menu_t OP_ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlsMenu, &OP_MainDef, 60, 30);
menu_t OP_ControlListDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlListMenu, &OP_ControlsDef, 60, 30); //menu_t OP_ControlListDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlListMenu, &OP_ControlsDef, 60, 30);
menu_t OP_MoveControlsDef = CONTROLMENUSTYLE(OP_MoveControlsMenu, &OP_ControlListDef); menu_t OP_MoveControlsDef = CONTROLMENUSTYLE(OP_MoveControlsMenu, &OP_ControlsDef);
//menu_t OP_MPControlsDef = CONTROLMENUSTYLE(OP_MPControlsMenu, &OP_ControlListDef); //menu_t OP_MPControlsDef = CONTROLMENUSTYLE(OP_MPControlsMenu, &OP_ControlListDef);
menu_t OP_CameraControlsDef = CONTROLMENUSTYLE(OP_CameraControlsMenu, &OP_ControlListDef); //menu_t OP_CameraControlsDef = CONTROLMENUSTYLE(OP_CameraControlsMenu, &OP_ControlListDef);
menu_t OP_MiscControlsDef = CONTROLMENUSTYLE(OP_MiscControlsMenu, &OP_ControlListDef); //menu_t OP_MiscControlsDef = CONTROLMENUSTYLE(OP_MiscControlsMenu, &OP_ControlListDef);
menu_t OP_CustomControlsDef = CONTROLMENUSTYLE(OP_CustomControlsMenu, &OP_MoveControlsDef);
menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P1ControlsMenu, &OP_ControlsDef, 60, 30); menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P1ControlsMenu, &OP_ControlsDef, 60, 30);
menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P2ControlsMenu, &OP_ControlsDef, 60, 30); menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P2ControlsMenu, &OP_ControlsDef, 60, 30);
menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 60, 30); menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 60, 30);
@ -2620,7 +2636,7 @@ void M_StartControlPanel(void)
MPauseMenu[mpause_switchteam].status = IT_DISABLED; MPauseMenu[mpause_switchteam].status = IT_DISABLED;
MPauseMenu[mpause_psetup].status = IT_DISABLED; MPauseMenu[mpause_psetup].status = IT_DISABLED;
if ((server || adminplayer == consoleplayer)) if ((server || IsPlayerAdmin(consoleplayer)))
{ {
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL; MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
if (G_GametypeHasTeams()) if (G_GametypeHasTeams())
@ -3962,7 +3978,7 @@ static void M_Options(INT32 choice)
(void)choice; (void)choice;
// if the player is not admin or server, disable server options // if the player is not admin or server, disable server options
OP_MainMenu[5].status = (Playing() && !(server || adminplayer == consoleplayer)) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); OP_MainMenu[5].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
// if the player is playing _at all_, disable the erase data options // if the player is playing _at all_, disable the erase data options
OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
@ -5637,11 +5653,11 @@ static void M_HandleStaffReplay(INT32 choice)
{ {
case KEY_DOWNARROW: case KEY_DOWNARROW:
M_NextOpt(); M_NextOpt();
S_StartSound(NULL, sfx_bewar1); S_StartSound(NULL, sfx_menu1);
break; break;
case KEY_UPARROW: case KEY_UPARROW:
M_PrevOpt(); M_PrevOpt();
S_StartSound(NULL, sfx_bewar1); S_StartSound(NULL, sfx_menu1);
break; break;
case KEY_BACKSPACE: case KEY_BACKSPACE:
case KEY_ESCAPE: case KEY_ESCAPE:
@ -6462,9 +6478,6 @@ static void M_HandleConnectIP(INT32 choice)
// ======================== // ========================
// Tails 03-02-2002 // Tails 03-02-2002
#define PLBOXW 8
#define PLBOXH 9
static INT32 multi_tics; static INT32 multi_tics;
static state_t *multi_state; static state_t *multi_state;
@ -6483,8 +6496,13 @@ static void M_DrawSetupMultiPlayerMenu(void)
INT32 mx, my, st, flags = 0; INT32 mx, my, st, flags = 0;
spritedef_t *sprdef; spritedef_t *sprdef;
spriteframe_t *sprframe; spriteframe_t *sprframe;
patch_t *statbg = W_CachePatchName("K_STATBG", PU_CACHE);
patch_t *statdot = W_CachePatchName("K_SDOT0", PU_CACHE);
patch_t *patch; patch_t *patch;
UINT8 frame; UINT8 frame;
UINT8 speed;
UINT8 weight;
UINT8 i;
mx = MP_PlayerSetupDef.x; mx = MP_PlayerSetupDef.x;
my = MP_PlayerSetupDef.y; my = MP_PlayerSetupDef.y;
@ -6493,21 +6511,101 @@ static void M_DrawSetupMultiPlayerMenu(void)
M_DrawGenericMenu(); M_DrawGenericMenu();
// draw name string // draw name string
M_DrawTextBox(mx + 90, my - 8, MAXPLAYERNAME, 1); M_DrawTextBox(mx + 32, my - 8, MAXPLAYERNAME, 1);
V_DrawString(mx + 98, my, V_ALLOWLOWERCASE, setupm_name); V_DrawString(mx + 40, my, V_ALLOWLOWERCASE, setupm_name);
// draw skin string // draw skin string
V_DrawString(mx + 90, my + 96, V_DrawString(mx + 80, my + 16,
((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|V_YELLOWMAP|V_ALLOWLOWERCASE, ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|V_YELLOWMAP|V_ALLOWLOWERCASE,
skins[setupm_fakeskin].realname); skins[setupm_fakeskin].realname);
// draw the name of the color you have chosen // draw the name of the color you have chosen
// Just so people don't go thinking that "Default" is Green. // Just so people don't go thinking that "Default" is Green.
V_DrawString(208, 72, V_YELLOWMAP|V_ALLOWLOWERCASE, KartColor_Names[setupm_fakecolor]); // SRB2kart V_DrawString(mx + 48, my + 152, V_YELLOWMAP|V_ALLOWLOWERCASE, KartColor_Names[setupm_fakecolor]); // SRB2kart
// draw text cursor for name // draw text cursor for name
if (!itemOn && skullAnimCounter < 4) // blink cursor if (!itemOn && skullAnimCounter < 4) // blink cursor
V_DrawCharacter(mx + 98 + V_StringWidth(setupm_name, 0), my, '_',false); V_DrawCharacter(mx + 48 + V_StringWidth(setupm_name, 0), my, '_',false);
// SRB2Kart: draw the stat backer
V_DrawFixedPatch((mx+141)<<FRACBITS, (my+62)<<FRACBITS, FRACUNIT, 0, statbg, NULL);
for (i = 0; i < numskins; i++) // draw the stat dots
{
if (i != setupm_fakeskin && R_SkinAvailable(skins[i].name) != -1)
{
speed = skins[i].kartspeed;
weight = skins[i].kartweight;
V_DrawFixedPatch(((mx+178) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, NULL);
}
}
// 2.2 color bar backported with permission
#define charw 74
#define indexwidth 8
{
const INT32 colwidth = (282-charw)/(2*indexwidth);
INT32 j = -colwidth;
INT16 col = setupm_fakecolor - colwidth;
INT32 x = mx-13;
INT32 w = indexwidth;
UINT8 h;
while (col < 1)
col += MAXSKINCOLORS-1;
while (j <= colwidth)
{
if (!(j++))
w = charw;
else
w = indexwidth;
for (h = 0; h < 16; h++)
V_DrawFill(x, my+164+h, w, 1, colortranslations[col][h]);
if (++col >= MAXSKINCOLORS)
col -= MAXSKINCOLORS-1;
x += w;
}
}
#undef indexwidth
// character bar, ripped off the color bar :V
#define iconwidth 32
{
const INT32 icons = 4;
INT32 k = -icons;
INT16 col = setupm_fakeskin - icons;
INT32 x = BASEVIDWIDTH/2 - ((icons+1)*24) - 4;
fixed_t scale = FRACUNIT/2;
INT32 offx = 8, offy = 8;
patch_t *cursor = W_CachePatchName("K_CHRCUR", PU_CACHE);
patch_t *face;
if (col < 0)
col += numskins;
while (k <= icons)
{
if (!(k++))
{
scale = FRACUNIT;
offx = 12;
offy = 0;
}
else
{
scale = FRACUNIT/2;
offx = 8;
offy = 8;
}
face = W_CachePatchName(skins[col].face, PU_CACHE);
V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, scale, 0, face, R_GetTranslationColormap(col, setupm_fakecolor, 0));
if (scale == FRACUNIT) // bit of a hack
V_DrawFixedPatch((x-2+offx)<<FRACBITS, (my+26+offy)<<FRACBITS, scale, 0, cursor, R_GetTranslationColormap(col, setupm_fakecolor, 0));
if (++col >= numskins)
col -= numskins;
x += FixedMul(iconwidth<<FRACBITS, 3*scale/2)/FRACUNIT;
}
}
#undef iconwidth
// anim the player in the box // anim the player in the box
if (--multi_tics <= 0) if (--multi_tics <= 0)
@ -6534,25 +6632,34 @@ static void M_DrawSetupMultiPlayerMenu(void)
frame = 0; // Try to use standing frame frame = 0; // Try to use standing frame
sprframe = &sprdef->spriteframes[frame]; sprframe = &sprdef->spriteframes[frame];
patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); patch = W_CachePatchNum(sprframe->lumppat[1], PU_CACHE);
if (sprframe->flip & 1) // Only for first sprite if (sprframe->flip & 1) // Only for first sprite
flags |= V_FLIP; // This sprite is left/right flipped! flags |= V_FLIP; // This sprite is left/right flipped!
// draw box around guy // draw box around guy
M_DrawTextBox(mx + 90, my + 8, PLBOXW, PLBOXH); V_DrawFill((mx+42)-(charw/2), my+66, charw, 84, 239);
if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats
statdot = W_CachePatchName("K_SDOT2", PU_CACHE);
else
statdot = W_CachePatchName("K_SDOT1", PU_CACHE);
speed = skins[setupm_fakeskin].kartspeed;
weight = skins[setupm_fakeskin].kartweight;
// draw player sprite // draw player sprite
if (!setupm_fakecolor) // should never happen but hey, who knows if (!setupm_fakecolor) // should never happen but hey, who knows
{ {
if (skins[setupm_fakeskin].flags & SF_HIRES) if (skins[setupm_fakeskin].flags & SF_HIRES)
{ {
V_DrawSciencePatch((mx+98+(PLBOXW*8/2))<<FRACBITS, V_DrawSciencePatch((mx+42)<<FRACBITS,
(my+16+(PLBOXH*8)-12)<<FRACBITS, (my+132)<<FRACBITS,
flags, patch, flags, patch,
skins[setupm_fakeskin].highresscale); skins[setupm_fakeskin].highresscale);
} }
else else
V_DrawScaledPatch(mx + 98 + (PLBOXW*8/2), my + 16 + (PLBOXH*8) - 12, flags, patch); V_DrawScaledPatch(mx+42, my+132, flags, patch);
V_DrawFixedPatch(((mx+178) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, NULL);
} }
else else
{ {
@ -6560,16 +6667,18 @@ static void M_DrawSetupMultiPlayerMenu(void)
if (skins[setupm_fakeskin].flags & SF_HIRES) if (skins[setupm_fakeskin].flags & SF_HIRES)
{ {
V_DrawFixedPatch((mx+98+(PLBOXW*8/2))<<FRACBITS, V_DrawFixedPatch((mx+42)<<FRACBITS,
(my+16+(PLBOXH*8)-12)<<FRACBITS, (my+132)<<FRACBITS,
skins[setupm_fakeskin].highresscale, skins[setupm_fakeskin].highresscale,
flags, patch, colormap); flags, patch, colormap);
} }
else else
V_DrawMappedPatch(mx + 98 + (PLBOXW*8/2), my + 16 + (PLBOXH*8) - 12, flags, patch, colormap); V_DrawMappedPatch(mx+42, my+132, flags, patch, colormap);
V_DrawFixedPatch(((mx+178) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, colormap);
Z_Free(colormap); Z_Free(colormap);
} }
#undef charw
} }
// Handle 1P/2P MP Setup // Handle 1P/2P MP Setup
@ -6591,12 +6700,12 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break; break;
case KEY_LEFTARROW: case KEY_LEFTARROW:
if (itemOn == 2) //player skin if (itemOn == 1) //player skin
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakeskin--; setupm_fakeskin--;
} }
else if (itemOn == 1) // player color else if (itemOn == 2) // player color
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor--; setupm_fakecolor--;
@ -6604,12 +6713,12 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break; break;
case KEY_RIGHTARROW: case KEY_RIGHTARROW:
if (itemOn == 2) //player skin if (itemOn == 1) //player skin
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakeskin++; setupm_fakeskin++;
} }
else if (itemOn == 1) // player color else if (itemOn == 2) // player color
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor++; setupm_fakecolor++;
@ -6873,15 +6982,15 @@ static void M_Setup1PControlsMenu(INT32 choice)
currentMenu->lastOn = itemOn; currentMenu->lastOn = itemOn;
// Unhide the three non-P2 controls // Unhide the three non-P2 controls
//OP_MPControlsMenu[0].status = IT_CALL|IT_STRING2; OP_MoveControlsMenu[12].status = IT_CALL|IT_STRING2;
//OP_MPControlsMenu[1].status = IT_CALL|IT_STRING2; OP_MoveControlsMenu[13].status = IT_CALL|IT_STRING2;
//OP_MPControlsMenu[2].status = IT_CALL|IT_STRING2; OP_MoveControlsMenu[14].status = IT_CALL|IT_STRING2;
// Unide the pause/console controls too // Unide the pause/console controls too
OP_MiscControlsMenu[3].status = IT_CALL|IT_STRING2; OP_MoveControlsMenu[10].status = IT_CALL|IT_STRING2;
OP_MiscControlsMenu[4].status = IT_CALL|IT_STRING2; OP_MoveControlsMenu[11].status = IT_CALL|IT_STRING2;
OP_ControlListDef.prevMenu = &OP_P1ControlsDef; OP_MoveControlsDef.prevMenu = &OP_P1ControlsDef;
M_SetupNextMenu(&OP_ControlListDef); M_SetupNextMenu(&OP_MoveControlsDef);
} }
static void M_Setup2PControlsMenu(INT32 choice) static void M_Setup2PControlsMenu(INT32 choice)
@ -6892,15 +7001,15 @@ static void M_Setup2PControlsMenu(INT32 choice)
currentMenu->lastOn = itemOn; currentMenu->lastOn = itemOn;
// Hide the three non-P2 controls // Hide the three non-P2 controls
//OP_MPControlsMenu[0].status = IT_GRAYEDOUT2; OP_MoveControlsMenu[12].status = IT_GRAYEDOUT2;
//OP_MPControlsMenu[1].status = IT_GRAYEDOUT2; OP_MoveControlsMenu[13].status = IT_GRAYEDOUT2;
//OP_MPControlsMenu[2].status = IT_GRAYEDOUT2; OP_MoveControlsMenu[14].status = IT_GRAYEDOUT2;
// Hide the pause/console controls too // Hide the pause/console controls too
OP_MiscControlsMenu[3].status = IT_GRAYEDOUT2; OP_MoveControlsMenu[10].status = IT_GRAYEDOUT2;
OP_MiscControlsMenu[4].status = IT_GRAYEDOUT2; OP_MoveControlsMenu[11].status = IT_GRAYEDOUT2;
OP_ControlListDef.prevMenu = &OP_P2ControlsDef; OP_MoveControlsDef.prevMenu = &OP_P2ControlsDef;
M_SetupNextMenu(&OP_ControlListDef); M_SetupNextMenu(&OP_MoveControlsDef);
} }
// Draws the Customise Controls menu // Draws the Customise Controls menu

View file

@ -850,7 +850,7 @@ void A_Look(mobj_t *actor)
if (!P_LookForPlayers(actor, locvar1 & 65535, false , FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale))) if (!P_LookForPlayers(actor, locvar1 & 65535, false , FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale)))
return; return;
if (leveltime < 4*TICRATE && gametype == GT_RACE) // SRB2kart - no looking before race starts if (leveltime < 4*TICRATE) // SRB2kart - no looking before race starts
return; return;
// go into chase state // go into chase state
@ -3627,12 +3627,16 @@ void A_AttractChase(mobj_t *actor)
P_LookForShield(actor); // Go find 'em, boy! P_LookForShield(actor); // Go find 'em, boy!
if (!actor->tracer if (actor->tracer && actor->tracer->player && actor->tracer->player->kartstuff[k_comebackmode] == 1)
;
else if (!actor->tracer
|| !actor->tracer->player || !actor->tracer->player
|| !actor->tracer->health || !actor->tracer->health
|| !P_CheckSight(actor, actor->tracer)) // You have to be able to SEE it...sorta || !P_CheckSight(actor, actor->tracer)) // You have to be able to SEE it...sorta
{ {
// Lost attracted rings don't through walls anymore. // Lost attracted rings don't through walls anymore.
if (actor->tracer && actor->tracer->player)
actor->tracer->player->kartstuff[k_comebackmode] = 0;
actor->flags &= ~MF_NOCLIP; actor->flags &= ~MF_NOCLIP;
P_SetTarget(&actor->tracer, NULL); P_SetTarget(&actor->tracer, NULL);
return; return;
@ -3921,10 +3925,11 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing)
if (thing == grenade->target && !(grenade->threshold == 0)) // Don't blow up at your owner. if (thing == grenade->target && !(grenade->threshold == 0)) // Don't blow up at your owner.
return true; return true;
if (thing->player && thing->player->kartstuff[k_bootaketimer]) if (thing->player && (thing->player->kartstuff[k_bootimer]
|| (thing->player->kartstuff[k_balloon] <= 0 && thing->player->kartstuff[k_comebacktimer])))
return true; return true;
if ((gametype == GT_CTF || gametype == GT_MATCH) if ((gametype == GT_CTF || gametype == GT_TEAMMATCH)
&& !cv_friendlyfire.value && grenade->target->player && thing->player && !cv_friendlyfire.value && grenade->target->player && thing->player
&& grenade->target->player->ctfteam == thing->player->ctfteam) // Don't blow up at your teammates, unless friendlyfire is on && grenade->target->player->ctfteam == thing->player->ctfteam) // Don't blow up at your teammates, unless friendlyfire is on
return true; return true;
@ -8089,6 +8094,17 @@ void A_ToggleFlameJet(mobj_t* actor)
void A_ItemPop(mobj_t *actor) void A_ItemPop(mobj_t *actor)
{ {
mobj_t *remains; mobj_t *remains;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_ItemPop", actor))
return;
#endif
if (!(actor->target && actor->target->player))
{
if (cv_debug && !(actor->target && actor->target->player))
CONS_Printf("ERROR: Powerup has no target!\n");
return;
}
// de-solidify // de-solidify
//P_UnsetThingPosition(actor); //P_UnsetThingPosition(actor);
@ -8123,26 +8139,13 @@ void A_ItemPop(mobj_t *actor)
return; return;
} }
if (actor->target && actor->target->player // These used to be &2's and &8's for box only, but are now universal. actor->target->player->kartstuff[k_itemroulette] = 1;
&& !(actor->target->player->kartstuff[k_greenshell] || actor->target->player->kartstuff[k_triplegreenshell]
|| actor->target->player->kartstuff[k_redshell] || actor->target->player->kartstuff[k_tripleredshell]
|| actor->target->player->kartstuff[k_banana] || actor->target->player->kartstuff[k_triplebanana]
|| actor->target->player->kartstuff[k_fakeitem] & 2 || actor->target->player->kartstuff[k_magnet]
|| actor->target->player->kartstuff[k_bobomb] || actor->target->player->kartstuff[k_blueshell]
|| actor->target->player->kartstuff[k_mushroom] || actor->target->player->kartstuff[k_fireflower]
|| actor->target->player->kartstuff[k_star] || actor->target->player->kartstuff[k_goldshroom]
|| actor->target->player->kartstuff[k_lightning] || actor->target->player->kartstuff[k_megashroom]
|| actor->target->player->kartstuff[k_itemroulette]
|| actor->target->player->kartstuff[k_boo] || actor->target->player->kartstuff[k_bootaketimer]
|| actor->target->player->kartstuff[k_boostolentimer]
|| actor->target->player->kartstuff[k_growshrinktimer] > 1
|| actor->target->player->kartstuff[k_goldshroomtimer]))
actor->target->player->kartstuff[k_itemroulette] = 1;
else if (cv_debug && !(actor->target && actor->target->player))
CONS_Printf("ERROR: Powerup has no target!\n");
remains->flags2 &= ~MF2_AMBUSH; remains->flags2 &= ~MF2_AMBUSH;
if (gametype != GT_RACE)
numgotboxes++;
P_RemoveMobj(actor); P_RemoveMobj(actor);
} }
@ -8152,6 +8155,10 @@ void A_RedShellChase(mobj_t *actor)
INT32 c = 0; INT32 c = 0;
INT32 stop; INT32 stop;
player_t *player; player_t *player;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_RedShellChase", actor))
return;
#endif
if (actor->tracer) if (actor->tracer)
{ {
@ -8213,8 +8220,11 @@ void A_RedShellChase(mobj_t *actor)
continue; continue;
} }
if (!(gametype == GT_RACE)) if (gametype != GT_RACE)
{ {
if (player->kartstuff[k_balloon] <= 0)
continue;
if (P_AproxDistance(P_AproxDistance(player->mo->x-actor->x, if (P_AproxDistance(P_AproxDistance(player->mo->x-actor->x,
player->mo->y-actor->y), player->mo->z-actor->z) > RING_DIST) player->mo->y-actor->y), player->mo->z-actor->z) > RING_DIST)
continue; continue;
@ -8223,7 +8233,8 @@ void A_RedShellChase(mobj_t *actor)
if ((gametype == GT_RACE) || (gametype != GT_RACE // If in match etc. only home in when you get close enough, in race etc. home in all the time if ((gametype == GT_RACE) || (gametype != GT_RACE // If in match etc. only home in when you get close enough, in race etc. home in all the time
&& P_AproxDistance(P_AproxDistance(player->mo->x-actor->x, && P_AproxDistance(P_AproxDistance(player->mo->x-actor->x,
player->mo->y-actor->y), player->mo->z-actor->z) < RING_DIST)) player->mo->y-actor->y), player->mo->z-actor->z) < RING_DIST
&& player->kartstuff[k_balloon] > 0))
P_SetTarget(&actor->tracer, player->mo); P_SetTarget(&actor->tracer, player->mo);
return; return;
@ -8249,11 +8260,15 @@ void A_BobombExplode(mobj_t *actor)
INT32 d; INT32 d;
INT32 locvar1 = var1; INT32 locvar1 = var1;
mobjtype_t type; mobjtype_t type;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_BobombExplode", actor))
return;
#endif
type = (mobjtype_t)locvar1; type = (mobjtype_t)locvar1;
for (d = 0; d < 16; d++) for (d = 0; d < 16; d++)
K_SpawnKartExplosion(actor->x, actor->y, actor->z, actor->info->painchance + 32*FRACUNIT, 32, type, d*(ANGLE_45/4), false, false); // 32 <-> 64 K_SpawnKartExplosion(actor->x, actor->y, actor->z, actor->info->painchance + 32*FRACUNIT, 32, type, d*(ANGLE_45/4), false, false, actor->target); // 32 <-> 64
P_SpawnMobj(actor->x, actor->y, actor->z, MT_BOMBEXPLOSIONSOUND); P_SpawnMobj(actor->x, actor->y, actor->z, MT_BOMBEXPLOSIONSOUND);
@ -8269,6 +8284,9 @@ void A_BobombExplode(mobj_t *actor)
if (mo2 == actor || mo2->type == MT_BOMBEXPLOSIONSOUND) // Don't explode yourself! Endless loop! if (mo2 == actor || mo2->type == MT_BOMBEXPLOSIONSOUND) // Don't explode yourself! Endless loop!
continue; continue;
if (actor->target && actor->target->player && actor->target->player->kartstuff[k_balloon] <= 0 && mo2 == actor->target)
continue;
if (P_AproxDistance(P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y), mo2->z - actor->z) > actor->info->painchance) if (P_AproxDistance(P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y), mo2->z - actor->z) > actor->info->painchance)
continue; continue;

View file

@ -2037,33 +2037,6 @@ foundenemy:
P_RemoveThinker(&nobaddies->thinker); P_RemoveThinker(&nobaddies->thinker);
} }
//
// P_IsObjectOnRealGround
//
// Helper function for T_EachTimeThinker
// Like P_IsObjectOnGroundIn, except ONLY THE REAL GROUND IS CONSIDERED, NOT FOFS
// I'll consider whether to make this a more globally accessible function or whatever in future
// -- Monster Iestyn
//
static boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec)
{
// Is the object in reverse gravity?
if (mo->eflags & MFE_VERTICALFLIP)
{
// Detect if the player is on the ceiling.
if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec))
return true;
}
// Nope!
else
{
// Detect if the player is on the floor.
if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec))
return true;
}
return false;
}
// //
// P_HavePlayersEnteredArea // P_HavePlayersEnteredArea
// //

View file

@ -150,6 +150,28 @@ boolean P_CanPickupItem(player_t *player, boolean weapon)
//if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] <= flashingtics) //if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] <= flashingtics)
// return false; // return false;
if (gametype != GT_RACE && player->kartstuff[k_balloon] <= 0) // No balloons in Match
return false;
if (player->kartstuff[k_magnettimer]) // You should probably collect stuff when you're attracting it :V
return true;
if (player->kartstuff[k_bootaketimer] || player->kartstuff[k_boostolentimer]
|| player->kartstuff[k_growshrinktimer] > 1 || player->kartstuff[k_goldshroomtimer]) // Item-specific timer going off
return false;
if (player->kartstuff[k_itemroulette]
|| player->kartstuff[k_greenshell] || player->kartstuff[k_triplegreenshell]
|| player->kartstuff[k_redshell] || player->kartstuff[k_tripleredshell]
|| player->kartstuff[k_banana] || player->kartstuff[k_triplebanana]
|| player->kartstuff[k_fakeitem] & 2 || player->kartstuff[k_magnet]
|| player->kartstuff[k_bobomb] || player->kartstuff[k_blueshell]
|| player->kartstuff[k_mushroom] || player->kartstuff[k_fireflower]
|| player->kartstuff[k_star] || player->kartstuff[k_goldshroom]
|| player->kartstuff[k_lightning] || player->kartstuff[k_megashroom]
|| player->kartstuff[k_boo] || player->kartstuff[k_feather] & 1) // Item slot already taken up
return false;
return true; return true;
} }
@ -388,8 +410,34 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
case MT_RANDOMITEM: // SRB2kart case MT_RANDOMITEM: // SRB2kart
case MT_FLINGRANDOMITEM: case MT_FLINGRANDOMITEM:
if (!(P_CanPickupItem(player, false))) if (gametype != GT_RACE && player->kartstuff[k_balloon] <= 0)
{
if (player->kartstuff[k_comebackmode] == 0 && !player->kartstuff[k_comebacktimer])
{
if (special->tracer)
return;
P_SetTarget(&special->tracer, toucher);
player->kartstuff[k_comebackmode] = 1;
}
return; return;
}
if (!P_CanPickupItem(player, false) && special->tracer != toucher)
return;
if (gametype != GT_RACE && special->tracer && special->tracer->player)
{
special->tracer->player->kartstuff[k_comebackmode] = 0;
special->tracer->player->kartstuff[k_comebackpoints]++;
CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[special->tracer->player-players], player_names[player-players]);
if (special->tracer->player->kartstuff[k_comebackpoints] >= 3)
K_StealBalloon(special->tracer->player, player, true);
special->tracer->player->kartstuff[k_comebacktimer] = comebacktime;
}
special->momx = special->momy = special->momz = 0; special->momx = special->momy = special->momz = 0;
P_SetTarget(&special->target, toucher); P_SetTarget(&special->target, toucher);
P_SetMobjState(special, special->info->deathstate); P_SetMobjState(special, special->info->deathstate);
@ -1165,9 +1213,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return; return;
} }
// //
// In circuit, player must have touched all previous starposts // SRB2kart: make sure the player will have enough checkpoints to touch
if (circuitmap if (circuitmap
&& special->health - player->starpostnum > 1) && special->health >= (numstarposts/2 + player->starpostnum))
{ {
// blatant reuse of a variable that's normally unused in circuit // blatant reuse of a variable that's normally unused in circuit
if (!player->tossdelay) if (!player->tossdelay)
@ -1194,6 +1242,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->starpostz = special->z>>FRACBITS; player->starpostz = special->z>>FRACBITS;
player->starpostangle = special->angle; player->starpostangle = special->angle;
player->starpostnum = special->health; player->starpostnum = special->health;
player->starpostcount++;
P_ClearStarPost(special->health); P_ClearStarPost(special->health);
// Find all starposts in the level with this value. // Find all starposts in the level with this value.
@ -2004,6 +2053,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
target->target->player->kartstuff[k_triplebanana] &= ~2; target->target->player->kartstuff[k_triplebanana] &= ~2;
else if (target->type == MT_TRIPLEBANANASHIELD3 && target->target->player->kartstuff[k_triplebanana] & 4) else if (target->type == MT_TRIPLEBANANASHIELD3 && target->target->player->kartstuff[k_triplebanana] & 4)
target->target->player->kartstuff[k_triplebanana] &= ~4; target->target->player->kartstuff[k_triplebanana] &= ~4;
/*else if (target->type == MT_BATTLEBALLOON && target->target->player->kartstuff[k_balloon] > target->threshold-1)
target->target->player->kartstuff[k_balloon] = target->threshold-1;*/
} }
// //
@ -2046,14 +2097,14 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{ {
if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording! if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording!
G_StopMetalRecording(); G_StopMetalRecording();
if (gametype == GT_MATCH && cv_match_scoring.value == 0 // note, no team match suicide penalty /*if (gametype == GT_MATCH && cv_match_scoring.value == 0 // note, no team match suicide penalty
&& ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player))) && ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player)))
{ // Suicide penalty - Not in Kart { // Suicide penalty - Not in Kart
//if (target->player->score >= 50) if (target->player->score >= 50)
// target->player->score -= 50; target->player->score -= 50;
//else else
// target->player->score = 0; target->player->score = 0;
} }*/
target->flags2 &= ~MF2_DONTDRAW; target->flags2 &= ~MF2_DONTDRAW;
} }
@ -2066,11 +2117,13 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
P_SetTarget(&target->target, source); P_SetTarget(&target->target, source);
source->player->numboxes++; source->player->numboxes++;
if ((cv_itemrespawn.value && gametype != GT_COOP && (modifiedgame || netgame || multiplayer))) if ((cv_itemrespawn.value && gametype != GT_COOP && (modifiedgame || netgame || multiplayer)))
{
target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation
}
} }
// Award Score Tails // Award Score Tails
{ /*{ // Enemies shouldn't award points in Kart
INT32 score = 0; INT32 score = 0;
if (maptol & TOL_NIGHTS) // Enemies always worth 200, bosses don't do anything. if (maptol & TOL_NIGHTS) // Enemies always worth 200, bosses don't do anything.
@ -2146,7 +2199,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
} }
P_AddPlayerScore(source->player, score); P_AddPlayerScore(source->player, score);
} }*/
} }
// if a player avatar dies... // if a player avatar dies...
@ -2214,7 +2267,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
for (w=0; w < MAXPLAYERS; w++) for (w=0; w < MAXPLAYERS; w++)
{ {
if (players[w].pflags & PF_TAGIT) if (players[w].pflags & PF_TAGIT)
P_AddPlayerScore(&players[w], 100); P_AddPlayerScore(&players[w], 1);
} }
target->player->pflags |= PF_TAGGED; target->player->pflags |= PF_TAGGED;
@ -2224,6 +2277,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
} }
} }
} }
else if (gametype == GT_MATCH)
{
K_CheckBalloons();
}
} }
if (source && target && target->player && source->player) if (source && target && target->player && source->player)
@ -2535,7 +2592,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
target->momy = FixedMul(FINESINE(fa),target->target->radius); target->momy = FixedMul(FINESINE(fa),target->target->radius);
} }
player->powers[pw_flashing] = flashingtics; player->powers[pw_flashing] = K_GetKartFlashing();
P_SetMobjState(target->tracer, S_NIGHTSHURT1); P_SetMobjState(target->tracer, S_NIGHTSHURT1);
S_StartSound(target, sfx_nghurt); S_StartSound(target, sfx_nghurt);
@ -2580,7 +2637,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
// The tag occurs so long as you aren't shooting another tagger with friendlyfire on. // The tag occurs so long as you aren't shooting another tagger with friendlyfire on.
if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT)) if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT))
{ {
P_AddPlayerScore(source->player, 100); //award points to tagger. P_AddPlayerScore(source->player, 1); //award points to tagger.
P_HitDeathMessages(player, inflictor, source); P_HitDeathMessages(player, inflictor, source);
if (gametype == GT_TAG) //survivor if (gametype == GT_TAG) //survivor
@ -2694,21 +2751,21 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
P_ResetPlayer(player); P_ResetPlayer(player);
P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); P_SetPlayerMobjState(player->mo, player->mo->info->deathstate);
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) /*if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
{ {
P_PlayerFlagBurst(player, false); P_PlayerFlagBurst(player, false);
if (source && source->player) if (source && source->player)
{ {
// Award no points when players shoot each other when cv_friendlyfire is on. // Award no points when players shoot each other when cv_friendlyfire is on.
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
P_AddPlayerScore(source->player, 25); P_AddPlayerScore(source->player, 1);
} }
} }
if (source && source->player && !player->powers[pw_super]) //don't score points against super players if (source && source->player && !player->powers[pw_super]) //don't score points against super players
{ {
// Award no points when players shoot each other when cv_friendlyfire is on. // Award no points when players shoot each other when cv_friendlyfire is on.
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
P_AddPlayerScore(source->player, 100); P_AddPlayerScore(source->player, 1);
} }
// If the player was super, tell them he/she ain't so super nomore. // If the player was super, tell them he/she ain't so super nomore.
@ -2718,6 +2775,18 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
HU_SetCEchoFlags(0); HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5); HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players])); HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}*/
if (gametype != GT_RACE)
{
if (player->kartstuff[k_balloon] > 0)
{
if (player->kartstuff[k_balloon] == 1)
CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]);
player->kartstuff[k_balloon]--;
}
K_CheckBalloons();
} }
} }
@ -2858,7 +2927,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
{ {
// Award no points when players shoot each other when cv_friendlyfire is on. // Award no points when players shoot each other when cv_friendlyfire is on.
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
P_AddPlayerScore(source->player, 50); P_AddPlayerScore(source->player, 1);
} }
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
@ -2868,7 +2937,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
{ {
// Award no points when players shoot each other when cv_friendlyfire is on. // Award no points when players shoot each other when cv_friendlyfire is on.
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
P_AddPlayerScore(source->player, 25); P_AddPlayerScore(source->player, 1);
} }
} }
@ -2901,6 +2970,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
#else #else
static const boolean force = false; static const boolean force = false;
#endif #endif
mobj_t *blueexplode;
if (objectplacing) if (objectplacing)
return false; return false;
@ -3092,7 +3162,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
{ {
// Just need to do this now! Being thrown upwards is done by the explosion. // Just need to do this now! Being thrown upwards is done by the explosion.
P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUELIGHTNING); P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUELIGHTNING);
P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUEEXPLOSION); blueexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUEEXPLOSION);
P_SetTarget(&blueexplode->target, source);
return true; return true;
} }
else if (damage == 65 && player->kartstuff[k_position] > 1) else if (damage == 65 && player->kartstuff[k_position] > 1)
@ -3124,17 +3195,29 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false; return false;
else else
{ {
player->kartstuff[k_spinouttype] = 1; if (inflictor && (inflictor->type == MT_GREENITEM || inflictor->type == MT_GREENSHIELD
K_SpinPlayer(player, source); || inflictor->type == MT_REDITEM || inflictor->type == MT_REDSHIELD || inflictor->type == MT_REDITEMDUD
damage = player->mo->health - 1; || inflictor->type == MT_FAKEITEM || inflictor->type == MT_FAKESHIELD
P_RingDamage(player, inflictor, source, damage); || inflictor->type == MT_TRIPLEGREENSHIELD1 || inflictor->type == MT_TRIPLEGREENSHIELD2 || inflictor->type == MT_TRIPLEGREENSHIELD3
if (inflictor && (inflictor->type == MT_GREENITEM || inflictor->type == MT_REDITEM || inflictor->type == MT_REDITEMDUD)) || inflictor->type == MT_TRIPLEREDSHIELD1 || inflictor->type == MT_TRIPLEREDSHIELD2 || inflictor->type == MT_TRIPLEREDSHIELD3
P_PlayerRingBurst(player, 5); || inflictor->player))
player->mo->momx = player->mo->momy = 0;
if (P_IsLocalPlayer(player))
{ {
quake.intensity = 32*FRACUNIT; player->kartstuff[k_spinouttype] = 1;
quake.time = 5; K_SpinPlayer(player, source);
damage = player->mo->health - 1;
P_RingDamage(player, inflictor, source, damage);
P_PlayerRingBurst(player, 5);
player->mo->momx = player->mo->momy = 0;
if (P_IsLocalPlayer(player))
{
quake.intensity = 32*FRACUNIT;
quake.time = 5;
}
}
else
{
player->kartstuff[k_spinouttype] = -1;
K_SpinPlayer(player, source);
} }
return true; return true;
} }
@ -3227,7 +3310,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
player->health -= damage; // mirror mobj health here player->health -= damage; // mirror mobj health here
if (damage < 10000) if (damage < 10000)
{ {
target->player->powers[pw_flashing] = flashingtics; target->player->powers[pw_flashing] = K_GetKartFlashing();
if (damage > 0) // don't spill emeralds/ammo/panels for shield damage if (damage > 0) // don't spill emeralds/ammo/panels for shield damage
P_PlayerRingBurst(player, damage); P_PlayerRingBurst(player, damage);
} }

View file

@ -135,6 +135,7 @@ boolean P_IsLocalPlayer(player_t *player);
boolean P_IsObjectInGoop(mobj_t *mo); boolean P_IsObjectInGoop(mobj_t *mo);
boolean P_IsObjectOnGround(mobj_t *mo); boolean P_IsObjectOnGround(mobj_t *mo);
boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec); boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec); // SRB2Kart
boolean P_InSpaceSector(mobj_t *mo); boolean P_InSpaceSector(mobj_t *mo);
boolean P_InQuicksand(mobj_t *mo); boolean P_InQuicksand(mobj_t *mo);
@ -153,7 +154,7 @@ void P_DoJumpShield(player_t *player);
void P_BlackOw(player_t *player); void P_BlackOw(player_t *player);
void P_ElementalFireTrail(player_t *player); void P_ElementalFireTrail(player_t *player);
void P_DoPityCheck(player_t *player); //void P_DoPityCheck(player_t *player);
void P_PlayerThink(player_t *player); void P_PlayerThink(player_t *player);
void P_PlayerAfterThink(player_t *player); void P_PlayerAfterThink(player_t *player);
void P_DoPlayerExit(player_t *player); void P_DoPlayerExit(player_t *player);
@ -201,6 +202,7 @@ extern size_t iquehead, iquetail;
extern consvar_t cv_gravity, cv_viewheight; extern consvar_t cv_gravity, cv_viewheight;
void P_RespawnSpecials(void); void P_RespawnSpecials(void);
void P_RespawnBattleSpecials(void);
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
@ -326,7 +328,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
boolean P_Move(mobj_t *actor, fixed_t speed); boolean P_Move(mobj_t *actor, fixed_t speed);
boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
void P_SlideMove(mobj_t *mo); void P_SlideMove(mobj_t *mo, boolean forceslide);
void P_BounceMove(mobj_t *mo); void P_BounceMove(mobj_t *mo);
boolean P_CheckSight(mobj_t *t1, mobj_t *t2); boolean P_CheckSight(mobj_t *t1, mobj_t *t2);
void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fixed_t radius); void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fixed_t radius);

View file

@ -320,6 +320,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
} }
} }
#if 0
static void P_DoTailsCarry(player_t *sonic, player_t *tails) static void P_DoTailsCarry(player_t *sonic, player_t *tails)
{ {
INT32 p; INT32 p;
@ -400,6 +401,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
sonic->pflags &= ~PF_CARRIED; sonic->pflags &= ~PF_CARRIED;
} }
} }
#endif
// //
// PIT_CheckThing // PIT_CheckThing
@ -673,6 +675,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& (tmthing->target == thing->target)) // Don't hit each other if you have the same target && (tmthing->target == thing->target)) // Don't hit each other if you have the same target
return true; return true;
if (thing->player && thing->player->powers[pw_flashing]
&& !(tmthing->type == MT_GREENITEM || tmthing->type == MT_REDITEM || tmthing->type == MT_REDITEMDUD))
return true;
if (thing->type == MT_PLAYER) if (thing->type == MT_PLAYER)
{ {
// Player Damage // Player Damage
@ -808,6 +814,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0))) if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0)))
return true; return true;
if (thing->player && thing->player->powers[pw_flashing])
return true;
if (thing->type == MT_PLAYER) if (thing->type == MT_PLAYER)
{ {
S_StartSound(NULL, sfx_cgot); //let all players hear it. S_StartSound(NULL, sfx_cgot); //let all players hear it.
@ -832,6 +841,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (!(thing->type == MT_PLAYER)) if (!(thing->type == MT_PLAYER))
return true; return true;
if (thing->player && thing->player->powers[pw_flashing])
return true;
if (thing->type == MT_PLAYER) if (thing->type == MT_PLAYER)
{ {
K_SpinPlayer(thing->player, tmthing->target); K_SpinPlayer(thing->player, tmthing->target);
@ -863,6 +875,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->type == MT_FIREBALL && thing->type == MT_FIREBALL) if (tmthing->type == MT_FIREBALL && thing->type == MT_FIREBALL)
return true; // Fireballs don't collide with eachother return true; // Fireballs don't collide with eachother
if (thing->player && thing->player->powers[pw_flashing])
return true;
if (thing->type == MT_PLAYER) if (thing->type == MT_PLAYER)
{ {
// Player Damage // Player Damage
@ -960,6 +975,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->health <= 0 || thing->health <= 0) if (tmthing->health <= 0 || thing->health <= 0)
return true; return true;
if (thing->player && thing->player->powers[pw_flashing])
return true;
if (thing->type == MT_GREENITEM // When these items collide with the fake item, just the fake item is destroyed if (thing->type == MT_GREENITEM // When these items collide with the fake item, just the fake item is destroyed
|| thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD
|| thing->type == MT_BOMBITEM || thing->type == MT_BOMBITEM
@ -1043,6 +1061,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->health <= 0 || thing->health <= 0) if (tmthing->health <= 0 || thing->health <= 0)
return true; return true;
if (thing->player && thing->player->powers[pw_flashing])
return true;
if (thing->type == MT_PLAYER) if (thing->type == MT_PLAYER)
{ {
P_KillMobj(tmthing, thing, thing); P_KillMobj(tmthing, thing, thing);
@ -1087,6 +1108,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->z + tmthing->height < thing->z) if (tmthing->z + tmthing->height < thing->z)
return true; // underneath return true; // underneath
if (tmthing->player && tmthing->player->powers[pw_flashing]
&& !(thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD))
return true;
if (thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 if (thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3
|| thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3 || thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3
|| thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD || thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD
@ -1534,7 +1559,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
} }
// Force solid players in hide and seek to avoid corner stacking. // Force solid players in hide and seek to avoid corner stacking.
if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK) // Kart: No Tailspickup ever, players are always solid
/*if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK)
{ {
if (tmthing->player && thing->player) if (tmthing->player && thing->player)
{ {
@ -1546,7 +1572,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->player-players == consoleplayer && botingame) if (thing->player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true); CV_SetValue(&cv_analog2, true);
thing->player->pflags &= ~PF_CARRIED; thing->player->pflags &= ~PF_CARRIED;
} }*/
if (thing->player) if (thing->player)
{ {
@ -1592,6 +1618,87 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& tmthing->z <= thing->z + thing->height) && tmthing->z <= thing->z + thing->height)
iwassprung = P_DoSpring(thing, tmthing); iwassprung = P_DoSpring(thing, tmthing);
} }
else if (thing->player) // bounce when players collide
{
// see if it went over / under
if (tmthing->z > thing->z + thing->height)
return true; // overhead
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath
if (thing->player->kartstuff[k_growshrinktimer] || thing->player->kartstuff[k_squishedtimer]
|| thing->player->kartstuff[k_bootimer] || thing->player->kartstuff[k_spinouttimer]
|| thing->player->kartstuff[k_startimer] || thing->player->kartstuff[k_justbumped]
|| (gametype != GT_RACE && (thing->player->kartstuff[k_balloon] <= 0
&& (thing->player->kartstuff[k_comebacktimer] || thing->player->kartstuff[k_comebackmode] == 1)))
|| tmthing->player->kartstuff[k_growshrinktimer] || tmthing->player->kartstuff[k_squishedtimer]
|| tmthing->player->kartstuff[k_bootimer] || tmthing->player->kartstuff[k_spinouttimer]
|| tmthing->player->kartstuff[k_startimer] || tmthing->player->kartstuff[k_justbumped]
|| (gametype != GT_RACE && (tmthing->player->kartstuff[k_balloon] <= 0
&& (tmthing->player->kartstuff[k_comebacktimer] || tmthing->player->kartstuff[k_comebackmode] == 1))))
{
return true;
}
if (gametype != GT_RACE)
{
if ((thing->player->kartstuff[k_balloon] <= 0 && thing->player->kartstuff[k_comebackmode] == 0)
|| (tmthing->player->kartstuff[k_balloon] <= 0 && tmthing->player->kartstuff[k_comebackmode] == 0))
{
if (tmthing->player->kartstuff[k_balloon] > 0)
{
K_ExplodePlayer(tmthing->player, thing);
thing->player->kartstuff[k_comebacktimer] = comebacktime;
return true;
}
else if (thing->player->kartstuff[k_balloon] > 0)
{
K_ExplodePlayer(thing->player, tmthing);
tmthing->player->kartstuff[k_comebacktimer] = comebacktime;
return true;
}
}
}
if (P_IsObjectOnGround(thing) && tmthing->momz < 0)
{
K_KartBouncing(tmthing, thing, true);
if (gametype != GT_RACE && tmthing->player->kartstuff[k_feather] & 2)
{
K_StealBalloon(tmthing->player, thing->player, false);
K_SpinPlayer(thing->player, tmthing);
}
}
else if (P_IsObjectOnGround(tmthing) && thing->momz < 0)
{
K_KartBouncing(thing, tmthing, true);
if (gametype != GT_RACE && thing->player->kartstuff[k_feather] & 2)
{
K_StealBalloon(thing->player, tmthing->player, false);
K_SpinPlayer(tmthing->player, thing);
}
}
else
K_KartBouncing(tmthing, thing, false);
if (gametype != GT_RACE)
{
if (thing->player->kartstuff[k_mushroomtimer] && !(tmthing->player->kartstuff[k_mushroomtimer]))
{
K_StealBalloon(thing->player, tmthing->player, false);
K_SpinPlayer(tmthing->player, thing);
}
else if (tmthing->player->kartstuff[k_mushroomtimer] && !(thing->player->kartstuff[k_mushroomtimer]))
{
K_StealBalloon(tmthing->player, thing->player, false);
K_SpinPlayer(thing->player, tmthing);
}
}
thing->player->kartstuff[k_justbumped] = 6;
tmthing->player->kartstuff[k_justbumped] = 6;
return true;
}
// Are you touching the side of the object you're interacting with? // Are you touching the side of the object you're interacting with?
else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
&& thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z) && thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z)
@ -2613,7 +2720,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (!(thing->flags & MF_NOCLIP)) if (!(thing->flags & MF_NOCLIP))
{ {
//All things are affected by their scale. //All things are affected by their scale.
fixed_t maxstep = FixedMul(MAXSTEPMOVE, thing->scale); fixed_t maxstep = MAXSTEPMOVE; //FixedMul(MAXSTEPMOVE, thing->scale);
if (thing->player) if (thing->player)
{ {
@ -3522,7 +3629,7 @@ stairstep:
// //
// This is a kludgy mess. // This is a kludgy mess.
// //
void P_SlideMove(mobj_t *mo) void P_SlideMove(mobj_t *mo, boolean forceslide)
{ {
fixed_t leadx, leady, trailx, traily, newx, newy; fixed_t leadx, leady, trailx, traily, newx, newy;
INT16 hitcount = 0; INT16 hitcount = 0;
@ -3600,7 +3707,7 @@ retry:
PT_ADDLINES, PTR_SlideTraverse); PT_ADDLINES, PTR_SlideTraverse);
// Some walls are bouncy even if you're not // Some walls are bouncy even if you're not
if (bestslideline && !(bestslideline->flags & ML_BOUNCY)) // SRB2kart - All walls are bouncy unless specified otherwise if (!forceslide && bestslideline && !(bestslideline->flags & ML_BOUNCY)) // SRB2kart - All walls are bouncy unless specified otherwise
{ {
P_BounceMove(mo); P_BounceMove(mo);
return; return;

View file

@ -216,11 +216,11 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
} }
} }
// You were in pain state after taking a hit, and you're moving out of pain state now? // You were in pain state after taking a hit, and you're moving out of pain state now?
else */if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == flashingtics && state != mobj->info->painstate) else */if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == K_GetKartFlashing() && state != mobj->info->painstate)
{ {
// Start flashing, since you've landed. // Start flashing, since you've landed.
player->powers[pw_flashing] = flashingtics-1; player->powers[pw_flashing] = K_GetKartFlashing()-1;
P_DoPityCheck(player); //P_DoPityCheck(player);
} }
// Set animation state // Set animation state
@ -1331,6 +1331,8 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
} }
if (wasflip == !(mo->eflags & MFE_VERTICALFLIP)) // note!! == ! is not equivalent to != here - turns numeric into bool this way if (wasflip == !(mo->eflags & MFE_VERTICALFLIP)) // note!! == ! is not equivalent to != here - turns numeric into bool this way
P_PlayerFlip(mo); P_PlayerFlip(mo);
if (mo->player->kartstuff[k_feather] & 2)
gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2);
} }
else else
{ {
@ -1378,6 +1380,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
break; break;
case MT_WATERDROP: case MT_WATERDROP:
gravityadd >>= 1; gravityadd >>= 1;
case MT_BANANAITEM:
case MT_FAKEITEM:
case MT_BOMBITEM:
gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2);
default: default:
break; break;
} }
@ -1809,7 +1815,7 @@ void P_XYMovement(mobj_t *mo)
} }
else if (player || mo->flags & (MF_SLIDEME|MF_PUSHABLE)) else if (player || mo->flags & (MF_SLIDEME|MF_PUSHABLE))
{ // try to slide along it { // try to slide along it
P_SlideMove(mo); P_SlideMove(mo, false);
xmove = ymove = 0; xmove = ymove = 0;
} }
else if (mo->type == MT_SPINFIRE) else if (mo->type == MT_SPINFIRE)
@ -1990,7 +1996,7 @@ static void P_RingXYMovement(mobj_t *mo)
I_Assert(!P_MobjWasRemoved(mo)); I_Assert(!P_MobjWasRemoved(mo));
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy)) if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy))
P_SlideMove(mo); P_SlideMove(mo, false);
} }
static void P_SceneryXYMovement(mobj_t *mo) static void P_SceneryXYMovement(mobj_t *mo)
@ -2004,7 +2010,7 @@ static void P_SceneryXYMovement(mobj_t *mo)
oldy = mo->y; oldy = mo->y;
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy)) if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy))
P_SlideMove(mo); P_SlideMove(mo, false);
if ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz)) if ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz))
return; // no friction when airborne return; // no friction when airborne
@ -2299,6 +2305,14 @@ static 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_FAKEITEM:
case MT_BANANAITEM:
case MT_GREENITEM:
case MT_REDITEM:
case MT_REDITEMDUD:
case MT_FIREBALL:
// Remove stuff from death pits. // Remove stuff from death pits.
if (P_CheckDeathPitCollide(mo)) if (P_CheckDeathPitCollide(mo))
{ {
@ -2325,13 +2339,6 @@ static boolean P_ZMovement(mobj_t *mo)
case MT_FLINGCOIN: case MT_FLINGCOIN:
case MT_FLINGRANDOMITEM: case MT_FLINGRANDOMITEM:
case MT_FLINGEMERALD: case MT_FLINGEMERALD:
// SRB2kart stuff that should die in pits
case MT_RANDOMITEM:
case MT_BANANAITEM:
case MT_GREENITEM:
case MT_REDITEM:
case MT_REDITEMDUD:
case MT_FIREBALL:
// Remove flinged stuff from death pits. // Remove flinged stuff from death pits.
if (P_CheckDeathPitCollide(mo)) if (P_CheckDeathPitCollide(mo))
{ {
@ -3574,7 +3581,9 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|| (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD))) || (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD)))
itsatwodlevel = true; itsatwodlevel = true;
if (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP) if (cv_kartmirror.value)
postimg = postimg_mirror;
else if (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP)
postimg = postimg_flip; postimg = postimg_flip;
else if (player->awayviewtics) else if (player->awayviewtics)
{ {
@ -5915,6 +5924,13 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
if (!dest || dest->health <= 0 || !dest->player || !source->tracer) if (!dest || dest->health <= 0 || !dest->player || !source->tracer)
return; return;
if (dest->player && dest->player->kartstuff[k_comebackmode] == 1)
{
P_TeleportMove(source, dest->x+dest->momx, dest->y+dest->momy, dest->z+dest->momz);
source->angle = dest->angle;
return;
}
// change angle // change angle
source->angle = R_PointToAngle2(source->x, source->y, tx, ty); source->angle = R_PointToAngle2(source->x, source->y, tx, ty);
@ -6452,19 +6468,30 @@ void P_MobjThinker(mobj_t *mobj)
//{ SRB2kart mobs //{ SRB2kart mobs
case MT_DRIFT: case MT_DRIFT:
{ {
fixed_t dsone = 26*4 + mobj->target->player->kartspeed*2 + (9 - mobj->target->player->kartweight); if (mobj->target && mobj->target->player && mobj->target->player->mo && mobj->target->player->health > 0 && !mobj->target->player->spectator)
fixed_t dstwo = dsone*2;
if ((mobj->target && mobj->target->player && mobj->target->player->mo && mobj->target->player->health > 0 && !mobj->target->player->spectator)
&& (mobj->type == MT_DRIFT && mobj->target->player->kartstuff[k_driftcharge] >= dsone))
{ {
UINT8 kartspeed = mobj->target->player->kartspeed;
fixed_t dsone, dstwo;
INT32 HEIGHT; INT32 HEIGHT;
fixed_t radius; fixed_t radius;
if (mobj->target->player->kartstuff[k_bootaketimer] > 0) if (gametype != GT_RACE && mobj->target->player->kartstuff[k_balloon] <= 0)
kartspeed = 1;
dsone = 26*4 + kartspeed*2 + (9 - mobj->target->player->kartweight);
dstwo = dsone*2;
if (mobj->target->player->kartstuff[k_driftcharge] < dsone)
{
P_RemoveMobj(mobj);
return;
}
if (mobj->target->player->kartstuff[k_bootimer] > 0)
{ {
if ((mobj->target->player == &players[displayplayer] || (splitscreen && mobj->target->player == &players[secondarydisplayplayer])) if ((mobj->target->player == &players[displayplayer] || (splitscreen && mobj->target->player == &players[secondarydisplayplayer]))
|| (!(mobj->target->player == &players[displayplayer] || (splitscreen && mobj->target->player == &players[secondarydisplayplayer])) || (!(mobj->target->player == &players[displayplayer] || (splitscreen && mobj->target->player == &players[secondarydisplayplayer]))
&& (mobj->target->player->kartstuff[k_bootaketimer] < 1*TICRATE/2 || mobj->target->player->kartstuff[k_bootaketimer] > bootime-(1*TICRATE/2)))) && (mobj->target->player->kartstuff[k_bootimer] < 1*TICRATE/2 || mobj->target->player->kartstuff[k_bootimer] > bootime-(1*TICRATE/2))))
{ {
if (leveltime & 1) if (leveltime & 1)
mobj->flags2 |= MF2_DONTDRAW; mobj->flags2 |= MF2_DONTDRAW;
@ -6474,13 +6501,13 @@ void P_MobjThinker(mobj_t *mobj)
else else
mobj->flags2 |= MF2_DONTDRAW; mobj->flags2 |= MF2_DONTDRAW;
} }
else if (mobj->target->player->kartstuff[k_bootaketimer] == 0) else if (mobj->target->player->kartstuff[k_bootimer] == 0)
{ {
mobj->flags2 &= ~MF2_DONTDRAW; mobj->flags2 &= ~MF2_DONTDRAW;
} }
// Actor's distance from its Target, or Radius. // Actor's distance from its Target, or Radius.
radius = FixedDiv(7, mobj->target->scale)*FRACUNIT; radius = 7*mobj->target->scale;
// Switch blue flames to red flames // Switch blue flames to red flames
if (mobj->target->player && mobj->type == MT_DRIFT if (mobj->target->player && mobj->type == MT_DRIFT
@ -6489,7 +6516,8 @@ void P_MobjThinker(mobj_t *mobj)
P_SetMobjStateNF(mobj, S_DRIFTSPARK4); P_SetMobjStateNF(mobj, S_DRIFTSPARK4);
// Get the angle // Get the angle
mobj->angle = ANGLE_180 + mobj->target->angle; if (mobj->target->player)
mobj->angle = ANGLE_180 + mobj->target->player->frameangle;
// If the player is on the ceiling, then flip // If the player is on the ceiling, then flip
if (mobj->target->player && mobj->target->eflags & MFE_VERTICALFLIP) if (mobj->target->player && mobj->target->eflags & MFE_VERTICALFLIP)
@ -6504,8 +6532,7 @@ void P_MobjThinker(mobj_t *mobj)
} }
// Shrink if the player shrunk too. // Shrink if the player shrunk too.
if (mobj->target->player) mobj->scale = mobj->target->scale;
mobj->scale = mobj->target->scale;
P_UnsetThingPosition(mobj); P_UnsetThingPosition(mobj);
{ {
@ -6540,15 +6567,8 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->mo if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->mo
&& mobj->target->player->health > 0 && !mobj->target->player->spectator) && mobj->target->player->health > 0 && !mobj->target->player->spectator)
{ {
INT32 zfixds = 56; fixed_t z;
INT32 DIST = FixedMul(zfixds, mobj->target->scale); const fixed_t radius = FixedHypot(mobj->target->radius, mobj->target->radius) + FixedHypot(mobj->radius, mobj->radius); // mobj's distance from its Target, or Radius.
INT32 HEIGHT;
const fixed_t radius = DIST*FRACUNIT; // mobj's distance from its Target, or Radius.
if (mobj->type == MT_BANANASHIELD || mobj->type == MT_TRIPLEBANANASHIELD1 || mobj->type == MT_TRIPLEBANANASHIELD2 || mobj->type == MT_TRIPLEBANANASHIELD3)
zfixds = 64;
else
zfixds = 56;
//mobj->angle += FixedAngle(12*FRACUNIT); // mobj's actual speed. //mobj->angle += FixedAngle(12*FRACUNIT); // mobj's actual speed.
if (mobj->type == MT_TRIPLEGREENSHIELD1 || mobj->type == MT_TRIPLEGREENSHIELD2 || mobj->type == MT_TRIPLEGREENSHIELD3 if (mobj->type == MT_TRIPLEGREENSHIELD1 || mobj->type == MT_TRIPLEGREENSHIELD2 || mobj->type == MT_TRIPLEGREENSHIELD3
@ -6565,26 +6585,51 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->target->player && mobj->target->eflags & MFE_VERTICALFLIP) if (mobj->target->player && mobj->target->eflags & MFE_VERTICALFLIP)
{ {
mobj->eflags |= MFE_VERTICALFLIP; mobj->eflags |= MFE_VERTICALFLIP;
HEIGHT = mobj->target->height / 2;
} }
else else
{ {
mobj->eflags &= ~MFE_VERTICALFLIP; mobj->eflags &= ~MFE_VERTICALFLIP;
HEIGHT = mobj->target->height / 5;
} }
// Shrink your items if the player shrunk too. // Shrink your items if the player shrunk too.
if (mobj->target->player) if (mobj->target->player)
mobj->scale = mobj->target->scale; mobj->scale = mobj->target->scale;
P_UnsetThingPosition(mobj); if (P_MobjFlip(mobj) > 0)
{ {
const angle_t fa = mobj->angle>>ANGLETOFINESHIFT; z = mobj->target->z;
mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa),radius);
mobj->y = mobj->target->y + FixedMul(FINESINE(fa), radius);
mobj->z = mobj->target->z + HEIGHT;
P_SetThingPosition(mobj);
} }
else
{
z = mobj->target->z + mobj->target->height - mobj->height;
}
mobj->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, z);
mobj->momx = FixedMul(FINECOSINE(mobj->angle>>ANGLETOFINESHIFT),radius);
mobj->momy = FixedMul(FINESINE(mobj->angle>>ANGLETOFINESHIFT), radius);
mobj->flags &= ~MF_NOCLIPTHING;
if (!P_TryMove(mobj, mobj->target->x + mobj->momx, mobj->target->y + mobj->momy, true))
P_SlideMove(mobj, true);
if (P_IsObjectOnGround(mobj->target))
{
if (P_MobjFlip(mobj) > 0)
{
if (mobj->floorz > mobj->target->z - mobj->height)
{
z = mobj->floorz;
}
}
else
{
if (mobj->ceilingz < mobj->target->z + mobj->target->height + mobj->height)
{
z = mobj->ceilingz - mobj->height;
}
}
}
mobj->z = z;
mobj->momx = mobj->momy = 0;
// Was this so hard? // Was this so hard?
if ((mobj->type == MT_GREENSHIELD && !(mobj->target->player->kartstuff[k_greenshell] & 1)) if ((mobj->type == MT_GREENSHIELD && !(mobj->target->player->kartstuff[k_greenshell] & 1))
@ -6615,6 +6660,163 @@ void P_MobjThinker(mobj_t *mobj)
return; return;
} }
break; break;
case MT_BATTLEBALLOON:
if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->mo
&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
{
fixed_t rad = 32*mobj->target->scale;
fixed_t offz;
angle_t ang, diff;
if (!((mobj->target->player-players) & 1))
ang = (FixedAngle(mobj->info->speed) * -1);
else
ang = FixedAngle(mobj->info->speed);
if (mobj->target->player->kartstuff[k_balloon] <= 1)
diff = 0;
else
diff = FixedAngle(360*FRACUNIT/mobj->target->player->kartstuff[k_balloon]);
ang = (ang*leveltime) + (diff * (mobj->threshold-1));
// If the player is on the ceiling, then flip your items as well.
if (mobj->target->eflags & MFE_VERTICALFLIP)
{
mobj->eflags |= MFE_VERTICALFLIP;
offz = mobj->target->height / 2;
}
else
{
mobj->eflags &= ~MFE_VERTICALFLIP;
offz = mobj->target->height / 5;
}
if (mobj->target->flags2 & MF2_DONTDRAW)
mobj->flags2 |= MF2_DONTDRAW;
else
mobj->flags2 &= ~MF2_DONTDRAW;
if (mobj->target->eflags & MFE_VERTICALFLIP)
offz += 4*FRACUNIT;
else
offz -= 4*FRACUNIT;
if (mobj->tracer && mobj->tracer->player && mobj->tracer->player->mo
&& mobj->tracer->player->health > 0 && !mobj->tracer->player->spectator) // STOLEN
mobj->color = mobj->tracer->player->skincolor; // don't do star flashing for stolen balloons
else
mobj->color = mobj->target->color; // but do so if it belongs to you :B
if (mobj->target->player->kartstuff[k_balloon] < 2)
P_SetMobjState(mobj, S_BATTLEBALLOON3);
else if (mobj->target->player->kartstuff[k_balloon] < 3)
P_SetMobjState(mobj, S_BATTLEBALLOON2);
else
P_SetMobjState(mobj, S_BATTLEBALLOON1);
// Shrink your items if the player shrunk too.
mobj->scale = mobj->target->scale;
P_UnsetThingPosition(mobj);
{
const angle_t fa = ang>>ANGLETOFINESHIFT;
mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa), rad);
mobj->y = mobj->target->y + FixedMul(FINESINE(fa), rad);
mobj->z = mobj->target->z + offz;
P_SetThingPosition(mobj);
}
// Was this so hard?
if (mobj->target->player->kartstuff[k_balloon] <= mobj->threshold)
{
P_RemoveMobj(mobj);
return;
}
}
else if ((mobj->health > 0
&& (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->player->health <= 0 || mobj->target->player->spectator))
|| (mobj->health <= 0 && mobj->z <= mobj->floorz)
|| P_CheckDeathPitCollide(mobj)) // When in death state
{
P_RemoveMobj(mobj);
return;
}
break;
case MT_PLAYERARROW:
if (mobj->target && mobj->target->health
&& mobj->target->player && mobj->target->player->mo
&& mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD)
{
fixed_t scale = mobj->target->scale;
mobj->color = mobj->target->color;
if ((splitscreen || !netgame)
|| gametype == GT_RACE
|| mobj->target->player == &players[displayplayer]
|| mobj->target->player->kartstuff[k_balloon] <= 0
|| (mobj->target->player->mo->flags2 & MF2_DONTDRAW))
mobj->flags2 |= MF2_DONTDRAW;
else
mobj->flags2 &= ~MF2_DONTDRAW;
P_UnsetThingPosition(mobj);
mobj->x = mobj->target->x;
mobj->y = mobj->target->y;
if (!(mobj->target->eflags & MFE_VERTICALFLIP))
{
mobj->z = mobj->target->z + P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT;
mobj->eflags &= ~MFE_VERTICALFLIP;
}
else
{
mobj->z = mobj->target->z - P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT;
mobj->eflags |= MFE_VERTICALFLIP;
}
P_SetThingPosition(mobj);
// Set it to use the correct states for its condition
if (mobj->target->player->kartstuff[k_itemroulette])
{
if (mobj->state != &states[S_PLAYERARROW_ROULETTE]) // don't reset FF_ANIMATE
P_SetMobjState(mobj, S_PLAYERARROW_ROULETTE);
}
else if (mobj->target->player->kartstuff[k_kitchensink]) P_SetMobjState(mobj, S_PLAYERARROW_KITCHENSINK);
else if (mobj->target->player->kartstuff[k_megashroom] == 1
|| (mobj->target->player->kartstuff[k_growshrinktimer] > 1
&& (leveltime & 1))) P_SetMobjState(mobj, S_PLAYERARROW_MEGASHROOM);
else if (mobj->target->player->kartstuff[k_growshrinktimer] > 1
&& !(leveltime & 1)) P_SetMobjState(mobj, S_PLAYERARROW_EMPTY); // S_INVISIBLE
else if (mobj->target->player->kartstuff[k_star] == 1) P_SetMobjState(mobj, S_PLAYERARROW_STAR);
else if (mobj->target->player->kartstuff[k_tripleredshell]) P_SetMobjState(mobj, S_PLAYERARROW_TRIPLEREDSHELL);
else if (mobj->target->player->kartstuff[k_triplebanana]) P_SetMobjState(mobj, S_PLAYERARROW_TRIPLEBANANA);
else if (mobj->target->player->kartstuff[k_triplegreenshell]) P_SetMobjState(mobj, S_PLAYERARROW_TRIPLEGREENSHELL);
else if (mobj->target->player->kartstuff[k_fireflower]) P_SetMobjState(mobj, S_PLAYERARROW_FIREFLOWER);
else if (mobj->target->player->kartstuff[k_bobomb]) P_SetMobjState(mobj, S_PLAYERARROW_BOBOMB);
else if (mobj->target->player->kartstuff[k_redshell]) P_SetMobjState(mobj, S_PLAYERARROW_REDSHELL);
else if (mobj->target->player->kartstuff[k_feather] & 1) P_SetMobjState(mobj, S_PLAYERARROW_FEATHER);
else if (mobj->target->player->kartstuff[k_boo] == 1) P_SetMobjState(mobj, S_PLAYERARROW_BOO);
else if (mobj->target->player->kartstuff[k_fakeitem] & 2) P_SetMobjState(mobj, S_PLAYERARROW_FAKEITEM);
else if (mobj->target->player->kartstuff[k_banana]) P_SetMobjState(mobj, S_PLAYERARROW_BANANA);
else if (mobj->target->player->kartstuff[k_greenshell]) P_SetMobjState(mobj, S_PLAYERARROW_GREENSHELL);
else if (mobj->target->player->kartstuff[k_mushroom]) P_SetMobjState(mobj, S_PLAYERARROW_MUSHROOM);
else P_SetMobjState(mobj, S_PLAYERARROW); // S_INVISIBLE
scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x,
players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
if (scale > 16*FRACUNIT)
{
scale = 16*FRACUNIT;
}
mobj->destscale = scale;
}
else if (mobj->health > 0)
{
P_KillMobj(mobj, NULL, NULL);
return;
}
break;
//} //}
case MT_WATERDROP: case MT_WATERDROP:
P_SceneryCheckWater(mobj); P_SceneryCheckWater(mobj);
@ -7486,15 +7688,16 @@ void P_MobjThinker(mobj_t *mobj)
break; break;
case MT_GREENITEM: case MT_GREENITEM:
{ {
sector_t *sec2;
fixed_t finalspeed = mobj->info->speed; fixed_t finalspeed = mobj->info->speed;
P_SpawnGhostMobj(mobj); P_SpawnGhostMobj(mobj);
if (cv_kartcc.value == 50) if (K_GetKartCC() == 50)
{ {
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
} }
else if (cv_kartcc.value == 150) else if (K_GetKartCC() == 150)
{ {
finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4); finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4);
} }
@ -7513,14 +7716,23 @@ void P_MobjThinker(mobj_t *mobj)
{ {
P_InstaThrust(mobj, mobj->angle, finalspeed); P_InstaThrust(mobj, mobj->angle, finalspeed);
} }
sec2 = P_ThingOnSpecial3DFloor(mobj);
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
K_DoBouncePad(mobj, 0);
if (mobj->threshold > 0) if (mobj->threshold > 0)
mobj->threshold--; mobj->threshold--;
if (leveltime % 6 == 0) if (leveltime % 6 == 0)
S_StartSound(mobj, mobj->info->activesound); S_StartSound(mobj, mobj->info->activesound);
break; break;
} }
case MT_REDITEM: case MT_REDITEM:
{ {
sector_t *sec2;
fixed_t topspeed = 64*FRACUNIT; fixed_t topspeed = 64*FRACUNIT;
fixed_t distbarrier = 512*FRACUNIT; fixed_t distbarrier = 512*FRACUNIT;
fixed_t distaway; fixed_t distaway;
@ -7532,18 +7744,18 @@ void P_MobjThinker(mobj_t *mobj)
if (leveltime % 7 == 0) if (leveltime % 7 == 0)
S_StartSound(mobj, mobj->info->activesound); S_StartSound(mobj, mobj->info->activesound);
if (cv_kartcc.value == 50) if (K_GetKartCC() == 50)
{ {
topspeed = FixedMul(topspeed, FRACUNIT-FRACUNIT/4); topspeed = FixedMul(topspeed, FRACUNIT-FRACUNIT/4);
distbarrier = FixedMul(distbarrier, FRACUNIT-FRACUNIT/4); distbarrier = FixedMul(distbarrier, FRACUNIT-FRACUNIT/4);
} }
else if (cv_kartcc.value == 150) else if (K_GetKartCC() == 150)
{ {
topspeed = FixedMul(topspeed, FRACUNIT+FRACUNIT/4); topspeed = FixedMul(topspeed, FRACUNIT+FRACUNIT/4);
distbarrier = FixedMul(distbarrier, FRACUNIT+FRACUNIT/4); distbarrier = FixedMul(distbarrier, FRACUNIT+FRACUNIT/4);
} }
if (mobj->tracer) if (gametype == GT_RACE && mobj->tracer)
{ {
distaway = P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y); distaway = P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y);
if (distaway < distbarrier) if (distaway < distbarrier)
@ -7556,18 +7768,47 @@ void P_MobjThinker(mobj_t *mobj)
} }
} }
if (gametype != GT_RACE)
{
mobj->friction -= 1228;
if (mobj->friction > FRACUNIT)
mobj->friction = FRACUNIT;
if (mobj->friction < 0)
mobj->friction = 0;
}
P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), topspeed); P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), topspeed);
sec2 = P_ThingOnSpecial3DFloor(mobj);
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
K_DoBouncePad(mobj, 0);
break; break;
} }
case MT_REDITEMDUD: case MT_REDITEMDUD:
{
sector_t *sec2;
P_SpawnGhostMobj(mobj); P_SpawnGhostMobj(mobj);
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->x+mobj->momx, mobj->y+mobj->momy); mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->x+mobj->momx, mobj->y+mobj->momy);
P_InstaThrust(mobj, mobj->angle, mobj->info->speed); P_InstaThrust(mobj, mobj->angle, mobj->info->speed);
sec2 = P_ThingOnSpecial3DFloor(mobj);
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
K_DoBouncePad(mobj, 0);
if (mobj->threshold > 0) if (mobj->threshold > 0)
mobj->threshold--; mobj->threshold--;
if (leveltime % 7 == 0) if (leveltime % 7 == 0)
S_StartSound(mobj, mobj->info->activesound); S_StartSound(mobj, mobj->info->activesound);
break; break;
}
case MT_BANANAITEM: case MT_BANANAITEM:
case MT_FAKEITEM: case MT_FAKEITEM:
if (mobj->momx || mobj->momy) if (mobj->momx || mobj->momy)
@ -8224,9 +8465,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->destscale = mobj->scale; mobj->destscale = mobj->scale;
mobj->scalespeed = FRACUNIT/12; mobj->scalespeed = FRACUNIT/12;
// TODO: Make this a special map header if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->mobj_scale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN)) mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
mobj->destscale = FRACUNIT/2;
// set subsector and/or block links // set subsector and/or block links
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
@ -8387,6 +8627,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_COIN: case MT_COIN:
case MT_BLUEBALL: case MT_BLUEBALL:
nummaprings++; nummaprings++;
break;
default: default:
break; break;
} }
@ -8402,9 +8643,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_TRIPLEGREENSHIELD1: case MT_TRIPLEGREENSHIELD2: case MT_TRIPLEGREENSHIELD3: case MT_TRIPLEGREENSHIELD1: case MT_TRIPLEGREENSHIELD2: case MT_TRIPLEGREENSHIELD3:
case MT_REDITEM: case MT_REDSHIELD: case MT_REDITEMDUD: case MT_REDITEM: case MT_REDSHIELD: case MT_REDITEMDUD:
case MT_TRIPLEREDSHIELD1: case MT_TRIPLEREDSHIELD2: case MT_TRIPLEREDSHIELD3: case MT_TRIPLEREDSHIELD1: case MT_TRIPLEREDSHIELD2: case MT_TRIPLEREDSHIELD3:
case MT_BATTLEBALLOON: case MT_FIREBALL:
case MT_FAKEITEM: case MT_FAKESHIELD: case MT_FAKEITEM: case MT_FAKESHIELD:
case MT_BOMBITEM: case MT_BOMBSHIELD: case MT_BOMBITEM: case MT_BOMBSHIELD:
case MT_FIREBALL:
P_SpawnShadowMobj(mobj); P_SpawnShadowMobj(mobj);
default: default:
break; break;
@ -8494,9 +8735,8 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
mobj->destscale = mobj->scale; mobj->destscale = mobj->scale;
mobj->scalespeed = FRACUNIT/12; mobj->scalespeed = FRACUNIT/12;
// TODO: Make this a special map header if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->mobj_scale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN)) mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
mobj->destscale = FRACUNIT/2;
// set subsector and/or block links // set subsector and/or block links
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
@ -8978,6 +9218,12 @@ void P_RespawnSpecials(void)
mobj_t *mo = NULL; mobj_t *mo = NULL;
mapthing_t *mthing = NULL; mapthing_t *mthing = NULL;
if (gametype != GT_RACE) // Battle Mode vers
{
P_RespawnBattleSpecials();
return;
}
// only respawn items when cv_itemrespawn is on // only respawn items when cv_itemrespawn is on
if (!cv_itemrespawn.value) if (!cv_itemrespawn.value)
return; return;
@ -9059,6 +9305,97 @@ void P_RespawnSpecials(void)
iquetail = (iquetail+1)&(ITEMQUESIZE-1); iquetail = (iquetail+1)&(ITEMQUESIZE-1);
} }
//
// P_RespawnBattleSpecials
//
void P_RespawnBattleSpecials(void)
{
fixed_t x, y, z;
subsector_t *ss;
mobj_t *mo = NULL;
mapthing_t *mthing = NULL;
// only respawn items when cv_itemrespawn is on
if (!cv_itemrespawn.value)
return;
// Didn't collect enough boxes
if (numgotboxes < (4*nummapboxes/5))
return;
// wait a teeeensy bit after collecting everything
if (leveltime - itemrespawntime[iquehead-1] < (tic_t)cv_itemrespawntime.value*(5*TICRATE))
return;
while (iquehead != iquetail) // respawn EVERYTHING in que!
{
mthing = itemrespawnque[iquetail];
#ifdef PARANOIA
if (!mthing)
I_Error("itemrespawnque[iquetail] is NULL!");
#endif
if (mthing)
{
mobjtype_t i;
x = mthing->x << FRACBITS;
y = mthing->y << FRACBITS;
ss = R_PointInSubsector(x, y);
// find which type to spawn
for (i = 0; i < NUMMOBJTYPES; i++)
if (mthing->type == mobjinfo[i].doomednum)
break;
//CTF rings should continue to respawn as normal rings outside of CTF.
if (gametype != GT_CTF)
{
if (i == MT_REDTEAMRING || i == MT_BLUETEAMRING)
i = MT_RING;
}
if (mthing->options & MTF_OBJECTFLIP)
{
z = (
#ifdef ESLOPE
ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) :
#endif
ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT;
if (mthing->options & MTF_AMBUSH
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i)))
z -= 24*FRACUNIT;
z -= mobjinfo[i].height; // Don't forget the height!
}
else
{
z = (
#ifdef ESLOPE
ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) :
#endif
ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT;
if (mthing->options & MTF_AMBUSH
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i)))
z += 24*FRACUNIT;
}
mo = P_SpawnMobj(x, y, z, i);
mo->spawnpoint = mthing;
mo->angle = ANGLE_45 * (mthing->angle/45);
if (mthing->options & MTF_OBJECTFLIP)
{
mo->eflags |= MFE_VERTICALFLIP;
mo->flags2 |= MF2_OBJECTFLIP;
}
}
// pull it from the que
iquetail = (iquetail+1)&(ITEMQUESIZE-1);
}
numgotboxes = 0;
}
// //
// P_SpawnPlayer // P_SpawnPlayer
// Called when a player is spawned on the level. // Called when a player is spawned on the level.
@ -9068,6 +9405,7 @@ void P_SpawnPlayer(INT32 playernum)
{ {
player_t *p = &players[playernum]; player_t *p = &players[playernum];
mobj_t *mobj; mobj_t *mobj;
mobj_t *overheadarrow;
if (p->playerstate == PST_REBORN) if (p->playerstate == PST_REBORN)
G_PlayerReborn(playernum); G_PlayerReborn(playernum);
@ -9077,13 +9415,13 @@ void P_SpawnPlayer(INT32 playernum)
{ {
// Special case for (NiGHTS) special stages! // Special case for (NiGHTS) special stages!
// if stage has already started, force players to become spectators until the next stage // if stage has already started, force players to become spectators until the next stage
if (multiplayer && netgame && G_IsSpecialStage(gamemap) && useNightsSS && leveltime > 0) /*if (multiplayer && netgame && G_IsSpecialStage(gamemap) && useNightsSS && leveltime > 0)
p->spectator = true; p->spectator = true;
else else*/
p->spectator = false; p->spectator = false;
} }
else if (netgame && p->jointime < 1) else if (netgame && p->jointime < 1)
p->spectator = true; /*p->spectator = true*/;
else if (multiplayer && !netgame) else if (multiplayer && !netgame)
{ {
// If you're in a team game and you don't have a team assigned yet... // If you're in a team game and you don't have a team assigned yet...
@ -9153,7 +9491,65 @@ void P_SpawnPlayer(INT32 playernum)
P_FlashPal(p, 0, 0); // Resets P_FlashPal(p, 0, 0); // Resets
// Spawn with a pity shield if necessary. // Spawn with a pity shield if necessary.
P_DoPityCheck(p); //P_DoPityCheck(p);
overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + P_GetPlayerHeight(p)+16*FRACUNIT, MT_PLAYERARROW);
P_SetTarget(&overheadarrow->target, mobj);
overheadarrow->flags2 |= MF2_DONTDRAW;
P_SetScale(overheadarrow, mobj->destscale);
if (leveltime < 1)
p->kartstuff[k_comebackshowninfo] = 0;
if (gametype != GT_RACE)
{
/*INT32 i;
INT32 pcount = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator || &players[i] == p)
continue;
if (players[i].jointime > 0)
continue;
pcount++;
}*/
if (p->kartstuff[k_balloon] > 0 || leveltime < 1/* || pcount <= 1*/) // srb2kart
{
INT32 i;
angle_t newangle;
angle_t diff;
fixed_t newx;
fixed_t newy;
mobj_t *mo;
if (leveltime < 1 /*|| pcount <= 1*/) // Start of the map?
p->kartstuff[k_balloon] = cv_kartballoons.value; // Reset those balloons!
if (p->kartstuff[k_balloon] <= 1)
diff = 0;
else
diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_balloon]);
newangle = mobj->angle;
newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT);
newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT);
for (i = 0; i < p->kartstuff[k_balloon]; i++)
{
mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBALLOON);
mo->threshold = i;
P_SetTarget(&mo->target, mobj);
mo->angle = (diff * (i-1));
mo->color = mobj->color;
if (mobj->flags2 & MF2_DONTDRAW)
mo->flags2 |= MF2_DONTDRAW;
else
mo->flags2 &= ~MF2_DONTDRAW;
}
}
}
} }
void P_AfterPlayerSpawn(INT32 playernum) void P_AfterPlayerSpawn(INT32 playernum)

View file

@ -138,8 +138,6 @@ static void P_NetArchivePlayers(void)
WRITEUINT16(save_p, players[i].powers[j]); WRITEUINT16(save_p, players[i].powers[j]);
for (j = 0; j < NUMKARTSTUFF; j++) for (j = 0; j < NUMKARTSTUFF; j++)
WRITEINT32(save_p, players[i].kartstuff[j]); WRITEINT32(save_p, players[i].kartstuff[j]);
for (j = 0; j < MAXPLAYERS; j++)
WRITEUINT8(save_p, players[i].collide[j]);
WRITEANGLE(save_p, players[i].frameangle); WRITEANGLE(save_p, players[i].frameangle);
@ -323,8 +321,6 @@ static void P_NetUnArchivePlayers(void)
players[i].powers[j] = READUINT16(save_p); players[i].powers[j] = READUINT16(save_p);
for (j = 0; j < NUMKARTSTUFF; j++) for (j = 0; j < NUMKARTSTUFF; j++)
players[i].kartstuff[j] = READINT32(save_p); players[i].kartstuff[j] = READINT32(save_p);
for (j = 0; j < MAXPLAYERS; j++)
players[i].collide[j] = (boolean)READUINT8(save_p);
players[i].frameangle = READANGLE(save_p); players[i].frameangle = READANGLE(save_p);

View file

@ -160,7 +160,7 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
I_Error("Invalid or corrupt map.\nLook in log file or text console for technical details."); I_Error("Invalid or corrupt map.\nLook in log file or text console for technical details.");
} }
#define NUMLAPS_DEFAULT 4 #define NUMLAPS_DEFAULT 3
/** Clears the data from a single map header. /** Clears the data from a single map header.
* *
@ -224,9 +224,14 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE); DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE);
mapheaderinfo[num]->levelflags = 0; mapheaderinfo[num]->levelflags = 0;
DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE); DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE);
mapheaderinfo[num]->menuflags = LF2_RECORDATTACK|LF2_NOVISITNEEDED; // 0 mapheaderinfo[num]->menuflags = 0;
// TODO grades support for delfile (pfft yeah right) // TODO grades support for delfile (pfft yeah right)
P_DeleteGrades(num); P_DeleteGrades(num);
// SRB2Kart
//DEH_WriteUndoline("AUTOMAP", va("%d", mapheaderinfo[num]->automap), UNDO_NONE);
//mapheaderinfo[num]->automap = false;
DEH_WriteUndoline("MOBJSCALE", va("%d", mapheaderinfo[num]->mobj_scale), UNDO_NONE);
mapheaderinfo[num]->mobj_scale = FRACUNIT;
// an even further impossibility, delfile custom opts support // an even further impossibility, delfile custom opts support
mapheaderinfo[num]->customopts = NULL; mapheaderinfo[num]->customopts = NULL;
mapheaderinfo[num]->numCustomOptions = 0; mapheaderinfo[num]->numCustomOptions = 0;
@ -983,6 +988,9 @@ static void P_LoadThings(void)
|| mt->type == 1702) // MT_AXISTRANSFERLINE || mt->type == 1702) // MT_AXISTRANSFERLINE
continue; // These were already spawned continue; // These were already spawned
if (mt->type == 2000) // MT_RANDOMITEM
nummapboxes++;
mt->mobj = NULL; mt->mobj = NULL;
P_SpawnMapThing(mt); P_SpawnMapThing(mt);
} }
@ -2154,6 +2162,8 @@ static void P_LevelInitStuff(void)
tokenbits = 0; tokenbits = 0;
runemeraldmanager = false; runemeraldmanager = false;
nummaprings = 0; nummaprings = 0;
nummapboxes = 0;
numgotboxes = 0;
// emerald hunt // emerald hunt
hunt1 = hunt2 = hunt3 = NULL; hunt1 = hunt2 = hunt3 = NULL;
@ -2451,11 +2461,11 @@ static void P_LoadRecordGhosts(void)
if (cv_ghost_staff.value) if (cv_ghost_staff.value)
{ {
lumpnum_t l; lumpnum_t l;
UINT8 i = 1; UINT8 j = 1;
while (i <= 99 && (l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(gamemap),i))) != LUMPERROR) while (j <= 99 && (l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(gamemap),j))) != LUMPERROR)
{ {
G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),i)); G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),j));
i++; j++;
} }
} }
@ -2566,8 +2576,7 @@ boolean P_SetupLevel(boolean skipprecip)
// chasecam on in chaos, race, coop // chasecam on in chaos, race, coop
// chasecam off in match, tag, capture the flag // chasecam off in match, tag, capture the flag
chase = (gametype == GT_RACE || gametype == GT_COMPETITION || gametype == GT_COOP) chase = true; // srb2kart: always on
|| (maptol & TOL_2D);
if (!dedicated) if (!dedicated)
{ {

View file

@ -3728,7 +3728,20 @@ DoneSection2:
// Process Section 3 // Process Section 3
switch (special) switch (special)
{ {
case 1: // Unused (was "Ice/Sludge") case 1: // SRB2kart: bounce pad
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
{
if (player->mo->eflags & MFE_SPRUNG)
break;
if (player->speed < K_GetKartSpeed(player, true)/4) // Push forward to prevent getting stuck
P_InstaThrust(player->mo, player->mo->angle, FixedMul(K_GetKartSpeed(player, true)/4, player->mo->scale));
player->kartstuff[k_feather] |= 2;
K_DoBouncePad(player->mo, 0);
}
break;
case 2: // Wind/Current case 2: // Wind/Current
case 3: // Unused (was "Ice/Sludge and Wind/Current") case 3: // Unused (was "Ice/Sludge and Wind/Current")
case 4: // Conveyor Belt case 4: // Conveyor Belt
@ -3878,7 +3891,7 @@ DoneSection2:
mo->spawnpoint = bflagpoint; mo->spawnpoint = bflagpoint;
mo->flags2 |= MF2_JUSTATTACKED; mo->flags2 |= MF2_JUSTATTACKED;
redscore += 1; redscore += 1;
P_AddPlayerScore(player, 250); P_AddPlayerScore(player, 5);
} }
} }
break; break;
@ -3911,7 +3924,7 @@ DoneSection2:
mo->spawnpoint = rflagpoint; mo->spawnpoint = rflagpoint;
mo->flags2 |= MF2_JUSTATTACKED; mo->flags2 |= MF2_JUSTATTACKED;
bluescore += 1; bluescore += 1;
P_AddPlayerScore(player, 250); P_AddPlayerScore(player, 5);
} }
} }
break; break;
@ -3928,20 +3941,22 @@ DoneSection2:
break; break;
case 6: // SRB2kart 190117 - Mushroom Boost Panel case 6: // SRB2kart 190117 - Mushroom Boost Panel
if (!P_IsObjectOnGround(player->mo)) if (roversector || P_MobjReadyToTrigger(player->mo, sector))
break; {
if (!player->kartstuff[k_floorboost]) if (!player->kartstuff[k_floorboost])
player->kartstuff[k_floorboost] = 3; player->kartstuff[k_floorboost] = 3;
else else
player->kartstuff[k_floorboost] = 2; player->kartstuff[k_floorboost] = 2;
K_DoMushroom(player, false, false); K_DoMushroom(player, false, false);
}
break; break;
case 7: // SRB2kart 190117 - Oil Slick case 7: // SRB2kart 190117 - Oil Slick
if (!P_IsObjectOnGround(player->mo)) if (roversector || P_MobjReadyToTrigger(player->mo, sector))
break; {
player->kartstuff[k_spinouttype] = -1; player->kartstuff[k_spinouttype] = -1;
K_SpinPlayer(player, NULL); K_SpinPlayer(player, NULL);
}
break; break;
case 8: // Zoom Tube Start case 8: // Zoom Tube Start
@ -4099,12 +4114,12 @@ DoneSection2:
case 10: // Finish Line case 10: // Finish Line
// SRB2kart - 150117 // SRB2kart - 150117
if (gametype == GT_RACE && (player->starpostnum == numstarposts || player->exiting)) if (gametype == GT_RACE && (player->starpostcount >= numstarposts/2 || player->exiting))
player->kartstuff[k_starpostwp] = player->kartstuff[k_waypoint] = 0; player->kartstuff[k_starpostwp] = player->kartstuff[k_waypoint] = 0;
// //
if (gametype == GT_RACE && !player->exiting) if (gametype == GT_RACE && !player->exiting)
{ {
if (player->starpostnum == numstarposts) // Must have touched all the starposts if (player->starpostcount >= numstarposts/2) // srb2kart: must have touched *enough* starposts (was originally "(player->starpostnum == numstarposts)")
{ {
player->laps++; player->laps++;
player->kartstuff[k_lapanimation] = 80; player->kartstuff[k_lapanimation] = 80;
@ -4123,6 +4138,7 @@ DoneSection2:
// SRB2kart 200117 // SRB2kart 200117
player->starpostangle = player->starpostnum = 0; player->starpostangle = player->starpostnum = 0;
player->starpostx = player->starposty = player->starpostz = 0; player->starpostx = player->starposty = player->starpostz = 0;
player->starpostcount = 0;
//except the time! //except the time!
player->starposttime = player->realtime; player->starposttime = player->realtime;
@ -7140,7 +7156,7 @@ void T_Friction(friction_t *f)
// friction works for all mobj's // friction works for all mobj's
// (or at least MF_PUSHABLEs, which is all I care about anyway) // (or at least MF_PUSHABLEs, which is all I care about anyway)
if ((!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) && thing->z == thing->floorz) && (thing->player if ((!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) && thing->z == thing->floorz) && (thing->player
&& (thing->player->kartstuff[k_startimer] == 0 && thing->player->kartstuff[k_bootaketimer] == 0 && (thing->player->kartstuff[k_startimer] == 0 && thing->player->kartstuff[k_bootimer] == 0
&& thing->player->kartstuff[k_mushroomtimer] == 0 && thing->player->kartstuff[k_growshrinktimer] <= 0))) && thing->player->kartstuff[k_mushroomtimer] == 0 && thing->player->kartstuff[k_growshrinktimer] <= 0)))
{ {
if (f->roverfriction) if (f->roverfriction)
@ -7537,7 +7553,7 @@ void T_Pusher(pusher_t *p)
if (thing->player && thing->player->pflags & PF_ROPEHANG) if (thing->player && thing->player->pflags & PF_ROPEHANG)
continue; continue;
if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics)) if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (K_GetKartFlashing()/4)*3 && thing->player->powers[pw_flashing] <= K_GetKartFlashing()))
continue; continue;
inFOF = touching = moved = false; inFOF = touching = moved = false;

View file

@ -625,9 +625,6 @@ void P_Ticker(boolean run)
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
P_PlayerAfterThink(&players[i]); P_PlayerAfterThink(&players[i]);
// SRB2kart - runs bounce collision for players
K_KartBouncer();
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
LUAh_ThinkFrame(); LUAh_ThinkFrame();
#endif #endif
@ -743,9 +740,6 @@ void P_PreTicker(INT32 frames)
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
P_PlayerAfterThink(&players[i]); P_PlayerAfterThink(&players[i]);
// SRB2kart - runs bounce collision for players
K_KartBouncer();
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
LUAh_ThinkFrame(); LUAh_ThinkFrame();
#endif #endif

View file

@ -853,17 +853,17 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
// Point penalty for hitting a hazard during tag. // Point penalty for hitting a hazard during tag.
// Discourages players from intentionally hurting themselves to avoid being tagged. // Discourages players from intentionally hurting themselves to avoid being tagged.
if (gametype == GT_TAG && (!(player->pflags & PF_TAGGED) && !(player->pflags & PF_TAGIT))) /*if (gametype == GT_TAG && (!(player->pflags & PF_TAGGED) && !(player->pflags & PF_TAGIT)))
{ {
//if (player->score >= 50) if (player->score >= 50)
// player->score -= 50; player->score -= 50;
//else else
// player->score = 0; player->score = 0;
} }*/
P_ResetPlayer(player); P_ResetPlayer(player);
P_SetPlayerMobjState(player->mo, player->mo->info->painstate); P_SetPlayerMobjState(player->mo, player->mo->info->painstate);
player->powers[pw_flashing] = flashingtics; player->powers[pw_flashing] = K_GetKartFlashing();
if (player->timeshit != UINT8_MAX) if (player->timeshit != UINT8_MAX)
++player->timeshit; ++player->timeshit;
@ -1007,12 +1007,12 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
{ {
UINT32 oldscore; UINT32 oldscore;
return; // SRB2kart - no score.
// This will probably be temporary until we do battle modes?
if (player->bot) if (player->bot)
player = &players[consoleplayer]; player = &players[consoleplayer];
if (player->exiting) // srb2kart
return;
// NiGHTS does it different! // NiGHTS does it different!
if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->typeoflevel & TOL_NIGHTS) if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->typeoflevel & TOL_NIGHTS)
{ {
@ -1312,6 +1312,36 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
return false; return false;
} }
//
// P_IsObjectOnRealGround
//
// Helper function for T_EachTimeThinker
// Like P_IsObjectOnGroundIn, except ONLY THE REAL GROUND IS CONSIDERED, NOT FOFS
// I'll consider whether to make this a more globally accessible function or whatever in future
// -- Monster Iestyn
//
// Really simple, but personally I think it's also incredibly helpful. I think this is fine in p_user.c
// -- Sal
boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec)
{
// Is the object in reverse gravity?
if (mo->eflags & MFE_VERTICALFLIP)
{
// Detect if the player is on the ceiling.
if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec))
return true;
}
// Nope!
else
{
// Detect if the player is on the floor.
if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec))
return true;
}
return false;
}
// //
// P_SetObjectMomZ // P_SetObjectMomZ
// //
@ -1607,9 +1637,7 @@ void P_DoPlayerExit(player_t *player)
if (player->exiting) if (player->exiting)
return; return;
if (cv_allowexitlevel.value == 0 && !G_PlatformGametype()) if (gametype == GT_RACE || gametype == GT_COMPETITION) // If in Race Mode, allow
return;
else if (gametype == GT_RACE || gametype == GT_COMPETITION) // If in Race Mode, allow
{ {
// SRB2kart 120217 // SRB2kart 120217
if (!countdown && !(netgame || multiplayer)) if (!countdown && !(netgame || multiplayer))
@ -1652,6 +1680,8 @@ void P_DoPlayerExit(player_t *player)
if (P_CheckRacers()) if (P_CheckRacers())
player->exiting = (14*TICRATE)/5 + 1; player->exiting = (14*TICRATE)/5 + 1;
} }
else if (gametype != GT_RACE)
player->exiting = 8*TICRATE + 1; // Battle Mode exiting
else else
player->exiting = (14*TICRATE)/5 + 2; // Accidental death safeguard??? player->exiting = (14*TICRATE)/5 + 2; // Accidental death safeguard???
@ -1666,10 +1696,11 @@ void P_DoPlayerExit(player_t *player)
*/ */
player->powers[pw_underwater] = 0; player->powers[pw_underwater] = 0;
player->powers[pw_spacetime] = 0; player->powers[pw_spacetime] = 0;
player->kartstuff[k_cardanimation] = 0; // srb2kart: reset battle animation
P_RestoreMusic(player); P_RestoreMusic(player);
if (playeringame[player-players] && netgame && !circuitmap) /*if (playeringame[player-players] && netgame && !circuitmap)
CONS_Printf(M_GetText("%s has completed the level.\n"), player_names[player-players]); CONS_Printf(M_GetText("%s has completed the level.\n"), player_names[player-players]);*/
} }
#define SPACESPECIAL 12 #define SPACESPECIAL 12
@ -3557,7 +3588,7 @@ static void P_DoSuperStuff(player_t *player)
} }
if (gametype != GT_COOP) if (gametype != GT_COOP)
player->powers[pw_flashing] = flashingtics-1; player->powers[pw_flashing] = K_GetKartFlashing(player)-1;
/* /*
if (player->mo->health > 0) if (player->mo->health > 0)
@ -4706,6 +4737,10 @@ static void P_3dMovement(player_t *player)
// Do not let the player control movement if not onground. // Do not let the player control movement if not onground.
onground = P_IsObjectOnGround(player->mo); onground = P_IsObjectOnGround(player->mo);
// SRB2Kart: shhhhhhh don't question me, feather and speed bumps are supposed to control like you're on the ground :p
if (player->kartstuff[k_feather] & 2)
onground = true;
player->aiming = cmd->aiming<<FRACBITS; player->aiming = cmd->aiming<<FRACBITS;
// Set the player speeds. // Set the player speeds.
@ -4833,7 +4868,7 @@ static void P_3dMovement(player_t *player)
P_Thrust(player->mo, movepushangle, movepushforward); P_Thrust(player->mo, movepushangle, movepushforward);
#endif #endif
} }
else if (!player->kartstuff[k_spinouttimer]) else if (!(player->kartstuff[k_spinouttimer]))
{ {
K_MomentumToFacing(player); K_MomentumToFacing(player);
} }
@ -5842,7 +5877,7 @@ static void P_NiGHTSMovement(player_t *player)
} }
// Currently reeling from being hit. // Currently reeling from being hit.
if (player->powers[pw_flashing] > (2*flashingtics)/3) if (player->powers[pw_flashing] > (2*K_GetKartFlashing())/3)
{ {
{ {
const angle_t fa = (FixedAngle(player->flyangle*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK; const angle_t fa = (FixedAngle(player->flyangle*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK;
@ -6499,7 +6534,7 @@ static void P_MovePlayer(player_t *player)
*/ */
cmd = &player->cmd; cmd = &player->cmd;
runspd = FixedMul(player->runspeed, player->mo->scale); runspd = 14*player->mo->scale; //srb2kart
// Let's have some movement speed fun on low-friction surfaces, JUST for players... // Let's have some movement speed fun on low-friction surfaces, JUST for players...
// (high friction surfaces shouldn't have any adjustment, since the acceleration in // (high friction surfaces shouldn't have any adjustment, since the acceleration in
@ -6700,10 +6735,12 @@ static void P_MovePlayer(player_t *player)
{ {
K_KartMoveAnimation(player); K_KartMoveAnimation(player);
player->frameangle = player->mo->angle; if (player->kartstuff[k_feather] & 2)
player->frameangle += ANGLE_22h;
else
player->frameangle = player->mo->angle;
} }
player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame. player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame.
// If you are stopped and are still walking, stand still! // If you are stopped and are still walking, stand still!
@ -7935,13 +7972,8 @@ static void P_DeathThink(player_t *player)
} }
//player->kartstuff[k_lakitu] = 48; // See G_PlayerReborn in g_game.c //player->kartstuff[k_lakitu] = 48; // See G_PlayerReborn in g_game.c
// SRB2kart - spawn automatically after 1.5 seconds // SRB2kart - spawn automatically after 1 second
if (player->deadtimer > (TICRATE + TICRATE/2) && (gametype == GT_RACE || player->spectator)) if (player->deadtimer > TICRATE)
player->playerstate = PST_REBORN;
// SRB2kart - spawn after 1.5 seconds & Button press
if ((cmd->buttons & BT_JUMP || cmd->buttons & BT_ACCELERATE) && player->deadtimer > (TICRATE + TICRATE/2)
&& (gametype == GT_RACE || player->spectator))
player->playerstate = PST_REBORN; player->playerstate = PST_REBORN;
// Single player auto respawn // Single player auto respawn
@ -8000,41 +8032,33 @@ static void P_DeathThink(player_t *player)
} }
} }
if (gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame))) // Keep time rolling
if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_TIMEOVER))
{ {
// Keep time rolling in race mode if (leveltime >= 4*TICRATE)
if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_TIMEOVER)) player->realtime = leveltime - 4*TICRATE;
{ else
if (gametype == GT_RACE || gametype == GT_COMPETITION) player->realtime = 0;
{ }
if (leveltime >= 4*TICRATE)
player->realtime = leveltime - 4*TICRATE;
else
player->realtime = 0;
}
else
player->realtime = leveltime;
}
if ((gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame))) && (player->lives <= 0))
{
// Return to level music // Return to level music
if (player->lives <= 0) if (netgame)
{ {
if (netgame) if (player->deadtimer == gameovertics && P_IsLocalPlayer(player))
{ S_ChangeMusic(mapmusname, mapmusflags, true);
if (player->deadtimer == gameovertics && P_IsLocalPlayer(player)) }
S_ChangeMusic(mapmusname, mapmusflags, true); else if (multiplayer) // local multiplayer only
} {
else if (multiplayer) // local multiplayer only if (player->deadtimer != gameovertics)
{ ;
if (player->deadtimer != gameovertics) // Restore the other player's music once we're dead for long enough
; // -- that is, as long as they aren't dead too
// Restore the other player's music once we're dead for long enough else if (player == &players[displayplayer] && players[secondarydisplayplayer].lives > 0)
// -- that is, as long as they aren't dead too P_RestoreMusic(&players[secondarydisplayplayer]);
else if (player == &players[displayplayer] && players[secondarydisplayplayer].lives > 0) else if (player == &players[secondarydisplayplayer] && players[displayplayer].lives > 0)
P_RestoreMusic(&players[secondarydisplayplayer]); P_RestoreMusic(&players[displayplayer]);
else if (player == &players[secondarydisplayplayer] && players[displayplayer].lives > 0)
P_RestoreMusic(&players[displayplayer]);
}
} }
} }
@ -8707,7 +8731,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
} }
// Make player translucent if camera is too close (only in single player). // Make player translucent if camera is too close (only in single player).
if (!(multiplayer || netgame) && !splitscreen) /*if (!(multiplayer || netgame) && !splitscreen)
{ {
fixed_t vx = 0, vy = 0; fixed_t vx = 0, vy = 0;
if (player->awayviewtics) { if (player->awayviewtics) {
@ -8726,7 +8750,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
player->mo->flags2 &= ~MF2_SHADOW; player->mo->flags2 &= ~MF2_SHADOW;
} }
else else
player->mo->flags2 &= ~MF2_SHADOW; player->mo->flags2 &= ~MF2_SHADOW;*/
/* if (!resetcalled && (player->pflags & PF_NIGHTSMODE && player->exiting)) /* if (!resetcalled && (player->pflags & PF_NIGHTSMODE && player->exiting))
{ {
@ -8967,9 +8991,12 @@ static void P_CalcPostImg(player_t *player)
*param = 5; *param = 5;
} }
#endif #endif
if (cv_kartmirror.value) // srb2kart
*type = postimg_mirror;
} }
void P_DoPityCheck(player_t *player) /*void P_DoPityCheck(player_t *player)
{ {
// No pity outside of match or CTF. // No pity outside of match or CTF.
if (player->spectator if (player->spectator
@ -8986,7 +9013,7 @@ void P_DoPityCheck(player_t *player)
player->powers[pw_shield] = SH_PITY; player->powers[pw_shield] = SH_PITY;
P_SpawnShieldOrb(player); P_SpawnShieldOrb(player);
} }
} }*/
// //
// P_PlayerThink // P_PlayerThink
@ -9131,7 +9158,7 @@ void P_PlayerThink(player_t *player)
// If it is set, start subtracting // If it is set, start subtracting
// Don't allow it to go back to 0 // Don't allow it to go back to 0
if (player->exiting > 1 && player->exiting < 3*TICRATE && player->exiting > 1) // SRB2kart - " && player->exiting > 1" if (player->exiting > 1 && (player->exiting < 3*TICRATE || gametype != GT_RACE)) // SRB2kart - "&& player->exiting > 1"
player->exiting--; player->exiting--;
if (player->exiting && countdown2) if (player->exiting && countdown2)
@ -9214,7 +9241,7 @@ void P_PlayerThink(player_t *player)
playerdeadview = false; playerdeadview = false;
// SRB2kart 010217 // SRB2kart 010217
if (gametype == GT_RACE && leveltime < 4*TICRATE) if (leveltime < 4*TICRATE)
player->powers[pw_nocontrol] = 2; player->powers[pw_nocontrol] = 2;
/* /*
if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)
@ -9228,15 +9255,10 @@ void P_PlayerThink(player_t *player)
// Synchronizes the "real" amount of time spent in the level. // Synchronizes the "real" amount of time spent in the level.
if (!player->exiting) if (!player->exiting)
{ {
if (gametype == GT_RACE || gametype == GT_COMPETITION) if (leveltime >= 4*TICRATE)
{ player->realtime = leveltime - 4*TICRATE;
if (leveltime >= 4*TICRATE)
player->realtime = leveltime - 4*TICRATE;
else
player->realtime = 0;
}
else else
player->realtime = leveltime; player->realtime = 0;
} }
if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]) if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing])
@ -9391,7 +9413,7 @@ void P_PlayerThink(player_t *player)
if (player->powers[pw_invulnerability] && player->powers[pw_invulnerability] < UINT16_MAX) if (player->powers[pw_invulnerability] && player->powers[pw_invulnerability] < UINT16_MAX)
player->powers[pw_invulnerability]--; player->powers[pw_invulnerability]--;
if (player->powers[pw_flashing] && player->powers[pw_flashing] < UINT16_MAX && ((player->pflags & PF_NIGHTSMODE) || player->powers[pw_flashing] < flashingtics)) if (player->powers[pw_flashing] && player->powers[pw_flashing] < UINT16_MAX && ((player->pflags & PF_NIGHTSMODE) || player->powers[pw_flashing] < K_GetKartFlashing()))
player->powers[pw_flashing]--; player->powers[pw_flashing]--;
if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM && !(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) // tails fly counter if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM && !(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) // tails fly counter
@ -9480,9 +9502,10 @@ void P_PlayerThink(player_t *player)
{ {
// SRB2kart - fixes boo not flashing when it should. Mega doesn't flash either. Flashing is local. // SRB2kart - fixes boo not flashing when it should. Mega doesn't flash either. Flashing is local.
if ((player == &players[displayplayer] || (splitscreen && player == &players[secondarydisplayplayer])) if ((player == &players[displayplayer] || (splitscreen && player == &players[secondarydisplayplayer]))
&& player->kartstuff[k_bootaketimer] == 0 && player->kartstuff[k_growshrinktimer] <= 0) && player->kartstuff[k_bootimer] == 0 && player->kartstuff[k_growshrinktimer] <= 0
&& (player->kartstuff[k_comebacktimer] == 0 || (gametype == GT_RACE || player->kartstuff[k_balloon] > 0)))
{ {
if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1)) if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < K_GetKartFlashing() && (leveltime & 1))
player->mo->flags2 |= MF2_DONTDRAW; player->mo->flags2 |= MF2_DONTDRAW;
else else
player->mo->flags2 &= ~MF2_DONTDRAW; player->mo->flags2 &= ~MF2_DONTDRAW;

View file

@ -1262,7 +1262,7 @@ static void R_ProjectSprite(mobj_t *thing)
offset2 = FixedMul(spritecachedinfo[lump].width, this_scale); offset2 = FixedMul(spritecachedinfo[lump].width, this_scale);
tx += FixedMul(offset2, ang_scale); tx += FixedMul(offset2, ang_scale);
x2 = ((centerxfrac + FixedMul (tx,xscale)) >>FRACBITS) - 1; x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1);
// off the left side // off the left side
if (x2 < 0) if (x2 < 0)
@ -2582,7 +2582,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname)
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
CONS_Alert(CONS_WARNING, M_GetText("Skin '%s' not found.\n"), skinname); CONS_Alert(CONS_WARNING, M_GetText("Skin '%s' not found.\n"), skinname);
else if(server || adminplayer == consoleplayer) else if(server || IsPlayerAdmin(consoleplayer))
CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname); CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname);
SetPlayerSkinByNum(playernum, 0); SetPlayerSkinByNum(playernum, 0);
@ -2651,7 +2651,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum); CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum);
else if(server || adminplayer == consoleplayer) else if(server || IsPlayerAdmin(consoleplayer))
CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum); CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum);
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
} }

View file

@ -91,8 +91,8 @@ typedef struct
fixed_t maxdash; fixed_t maxdash;
// SRB2kart // SRB2kart
UINT8 kartspeed; // Normal ground UINT8 kartspeed;
UINT8 kartweight; // Normal ground UINT8 kartweight;
// //
fixed_t normalspeed; // Normal ground fixed_t normalspeed; // Normal ground

View file

@ -23,8 +23,8 @@
<ProjectGuid>{61BA7D3C-F77D-4D31-B718-1177FE482CF2}</ProjectGuid> <ProjectGuid>{61BA7D3C-F77D-4D31-B718-1177FE482CF2}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>Srb2SDL</RootNamespace> <RootNamespace>Srb2SDL</RootNamespace>
<ProjectName>srb2kart</ProjectName>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<ProjectName>Srb2Win</ProjectName>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup> <PropertyGroup>
@ -160,6 +160,7 @@
<ClInclude Include="..\i_tcp.h" /> <ClInclude Include="..\i_tcp.h" />
<ClInclude Include="..\i_video.h" /> <ClInclude Include="..\i_video.h" />
<ClInclude Include="..\keys.h" /> <ClInclude Include="..\keys.h" />
<ClInclude Include="..\k_kart.h" />
<ClInclude Include="..\lua_hook.h" /> <ClInclude Include="..\lua_hook.h" />
<ClInclude Include="..\lua_hud.h" /> <ClInclude Include="..\lua_hud.h" />
<ClInclude Include="..\lua_libs.h" /> <ClInclude Include="..\lua_libs.h" />
@ -294,6 +295,7 @@
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\i_tcp.c" /> <ClCompile Include="..\i_tcp.c" />
<ClCompile Include="..\k_kart.c" />
<ClCompile Include="..\lua_baselib.c" /> <ClCompile Include="..\lua_baselib.c" />
<ClCompile Include="..\lua_consolelib.c" /> <ClCompile Include="..\lua_consolelib.c" />
<ClCompile Include="..\lua_hooklib.c" /> <ClCompile Include="..\lua_hooklib.c" />

View file

@ -444,6 +444,9 @@
<ClInclude Include="sdlmain.h"> <ClInclude Include="sdlmain.h">
<Filter>SDLApp</Filter> <Filter>SDLApp</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\k_kart.h">
<Filter>D_Doom</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="..\tmap.nas"> <CustomBuild Include="..\tmap.nas">
@ -876,6 +879,9 @@
<ClCompile Include="SDL_main\SDL_windows_main.c"> <ClCompile Include="SDL_main\SDL_windows_main.c">
<Filter>SDLApp</Filter> <Filter>SDLApp</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\k_kart.c">
<Filter>D_Doom</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Image Include="Srb2SDL.ico"> <Image Include="Srb2SDL.ico">

View file

@ -498,10 +498,12 @@ sfxinfo_t S_sfx[NUMSFX] =
{"mkitm7", true, 72, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"mkitm7", true, 72, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mkitm8", true, 72, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"mkitm8", true, 72, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mkitmF", true, 72, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"mkitmF", true, 72, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"clash", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"clash", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"tossed", false,150, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"tossed", false, 150, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"shelit", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR}, {"shelit", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR},
{"vroom", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"vroom", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"boing", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"smkinv", false, 140, 16, -1, NULL, 0, -1, -1, LUMPERROR},
// SRB2kart - Skin sounds // SRB2kart - Skin sounds
{"kwin", false, 64, 0, -1, NULL, 0, SKSWIN, -1, LUMPERROR}, {"kwin", false, 64, 0, -1, NULL, 0, SKSWIN, -1, LUMPERROR},

View file

@ -574,6 +574,8 @@ typedef enum
sfx_tossed, sfx_tossed,
sfx_shelit, sfx_shelit,
sfx_vroom, sfx_vroom,
sfx_boing,
sfx_smkinv,
sfx_kwin, sfx_kwin,
sfx_klose, sfx_klose,

View file

@ -1922,14 +1922,14 @@ static void ST_overlayDrawer(void)
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding."));
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player."));
} }
else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. /*else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text.
{ {
INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE;
if (respawntime > 0 && !stplyr->spectator) if (respawntime > 0 && !stplyr->spectator)
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s"));
else else
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Jump to respawn."));
} }*/
else if (stplyr->spectator else if (stplyr->spectator
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_textspectator) && LUA_HudEnabled(hud_textspectator)

View file

@ -2121,6 +2121,21 @@ Unoptimized version
heatindex[view]++; heatindex[view]++;
heatindex[view] %= vid.height; heatindex[view] %= vid.height;
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset, screens[0]+vid.width*vid.bpp*yoffset,
vid.width*vid.bpp, height, vid.width*vid.bpp, vid.width);
}
else if (type == postimg_mirror) // Flip the screen on the x axis
{
UINT8 *tmpscr = screens[4];
UINT8 *srcscr = screens[0];
INT32 y, x, x2;
for (y = yoffset; y < yoffset+height; y++)
{
for (x = 0, x2 = (vid.width*vid.bpp)-1; x < (vid.width*vid.bpp); x++, x2--)
tmpscr[y*vid.width + x2] = srcscr[y*vid.width + x];
}
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset, screens[0]+vid.width*vid.bpp*yoffset, VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset, screens[0]+vid.width*vid.bpp*yoffset,
vid.width*vid.bpp, height, vid.width*vid.bpp, vid.width); vid.width*vid.bpp, height, vid.width*vid.bpp, vid.width);
} }