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;
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
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
XBOXSTATIC UINT8 buf[128];
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);
return;
@ -1447,8 +1447,8 @@ void CV_AddValue(consvar_t *var, INT32 increment)
INT32 newvalue, max;
// count pointlimit better
if (var == &cv_pointlimit && (gametype == GT_MATCH))
increment *= 50;
/*if (var == &cv_pointlimit && (gametype == GT_MATCH))
increment *= 50;*/
newvalue = var->value + increment;
if (var->PossibleValue)

View file

@ -43,6 +43,7 @@
#include "lzf.h"
#include "lua_script.h"
#include "lua_hook.h"
#include "k_kart.h"
#ifdef CLIENT_LOADINGSCREEN
// 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]);
for (j = 0; j < NUMKARTSTUFF; ++j)
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
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
// modify these at runtime
// SRB2kart
rsp->kartspeed = (fixed_t)LONG(players[i].kartspeed);
rsp->kartweight = (fixed_t)LONG(players[i].kartweight);
rsp->kartspeed = (UINT8)LONG(players[i].kartspeed);
rsp->kartweight = (UINT8)LONG(players[i].kartweight);
//
rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed);
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->starpostz = SHORT(players[i].starpostz);
rsp->starpostnum = LONG(players[i].starpostnum);
rsp->starpostcount = LONG(players[i].starpostcount);
rsp->starposttime = (tic_t)LONG(players[i].starposttime);
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]);
for (j = 0; j < NUMKARTSTUFF; ++j)
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
players[i].health = rsp->health;
@ -668,8 +666,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].skin = LONG(rsp->skin);
// Just in case Lua does something like
// modify these at runtime
players[i].kartspeed = (fixed_t)LONG(rsp->kartspeed);
players[i].kartweight = (fixed_t)LONG(rsp->kartweight);
players[i].kartspeed = (UINT8)LONG(rsp->kartspeed);
players[i].kartweight = (UINT8)LONG(rsp->kartweight);
players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed);
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].starpostz = SHORT(rsp->starpostz);
players[i].starpostnum = LONG(rsp->starpostnum);
players[i].starpostcount = LONG(rsp->starpostcount);
players[i].starposttime = (tic_t)LONG(rsp->starposttime);
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.gametype = (UINT8)gametype;
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
// which is nice and easy for us to detect
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.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers));
for (i = 0; i < MAXPLAYERS; i++)
{
netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i];
if (!playeringame[i])
continue;
netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin;
@ -2030,7 +2032,7 @@ static void CL_ConnectToServer(boolean viams)
G_SetGamestate(GS_WAITINGPLAYERS);
wipegamestate = GS_WAITINGPLAYERS;
adminplayer = -1;
ClearAdminPlayers();
pnumnodes = 1;
oldtic = I_GetTime() - 1;
#ifndef NONET
@ -2409,8 +2411,10 @@ static void CL_RemovePlayer(INT32 playernum)
// Reset the name
sprintf(player_names[playernum], "Player %d", playernum+1);
if (playernum == adminplayer)
adminplayer = -1; // don't stay admin after you're gone
if (IsPlayerAdmin(playernum))
{
RemoveAdminPlayer(playernum); // don't stay admin after you're gone
}
if (playernum == displayplayer)
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
P_CheckSurvivors();
else if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)
K_CheckBalloons(); // SRB2Kart
else if (gametype == GT_RACE || gametype == GT_COMPETITION)
P_CheckRacers();
}
@ -2528,7 +2534,7 @@ static void Command_Nodes(void)
if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL)
CONS_Printf(" - %s", address);
if (i == adminplayer)
if (IsPlayerAdmin(i))
CONS_Printf(M_GetText(" (verified admin)"));
if (players[i].spectator)
@ -2553,7 +2559,7 @@ static void Command_Ban(void)
return;
}
if (server || adminplayer == consoleplayer)
if (server || IsPlayerAdmin(consoleplayer))
{
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
UINT8 *p = buf;
@ -2619,7 +2625,7 @@ static void Command_Kick(void)
return;
}
if (server || adminplayer == consoleplayer)
if (server || IsPlayerAdmin(consoleplayer))
{
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
UINT8 *p = buf;
@ -2676,7 +2682,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
pnum = 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"));
@ -2687,7 +2693,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
}
// Is playernum authorized to make this kick?
if (playernum != serverplayer && playernum != adminplayer
if (playernum != serverplayer && !IsPlayerAdmin(playernum)
&& !(playerpernode[playernode[playernum]] == 2
&& nodetoplayer2[playernode[playernum]] == pnum))
{
@ -2950,6 +2956,7 @@ void SV_ResetServer(void)
playeringame[i] = false;
playernode[i] = UINT8_MAX;
sprintf(player_names[i], "Player %d", i + 1);
adminplayers[i] = -1; // Populate the entire adminplayers array with -1.
}
mynode = 0;
@ -3024,7 +3031,7 @@ void D_QuitNetGame(void)
}
D_CloseConnection();
adminplayer = -1;
ClearAdminPlayers();
DEBFILE("===========================================================================\n"
" Log finish\n"
@ -3055,7 +3062,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
INT16 node, newplayernum;
boolean splitscreenplayer;
if (playernum != serverplayer && playernum != adminplayer)
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{
// protect against hacked/buggy client
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);
gametype = netbuffer->u.servercfg.gametype;
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);
}

View file

@ -163,7 +163,7 @@ typedef struct
UINT16 powers[NUMPOWERS];
INT32 kartstuff[NUMKARTSTUFF]; // SRB2kart
UINT8 collide[MAXPLAYERS]; // SRB2kart
angle_t frameangle; // SRB2kart
// Score is resynched in the confirm resync packet
INT32 health;
@ -219,6 +219,7 @@ typedef struct
INT16 starposty;
INT16 starpostz;
INT32 starpostnum;
INT32 starpostcount;
tic_t starposttime;
angle_t starpostangle;
@ -289,7 +290,7 @@ typedef struct
UINT8 gametype;
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.
@ -328,7 +329,7 @@ typedef struct
UINT8 cheatsenabled;
UINT8 isdedicated;
UINT8 fileneedednum;
SINT8 adminplayer;
SINT8 adminplayers[MAXPLAYERS];
tic_t time;
tic_t leveltime;
char servername[MAXSERVERNAME];

View file

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

View file

@ -145,7 +145,9 @@ static void Command_Changepassword_f(void);
static void Command_Login_f(void);
static void Got_Login(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_RemoveAdmin_f(void);
static void Command_MotD_f(void);
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_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_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_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};
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}};
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
boolean splitscreen = false;
boolean circuitmap = true; // SRB2kart
INT32 adminplayer = -1;
INT32 adminplayers[MAXPLAYERS];
/// \warning Keep this up-to-date if you add/remove/rename net text commands
const char *netxcmdnames[MAXNETXCMD - 1] =
@ -426,6 +437,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
"DELFILE",
"SETMOTD",
"SUICIDE",
"DEMOTED",
#ifdef HAVE_BLUA
"LUACMD",
"LUAVAR"
@ -463,8 +475,10 @@ void D_RegisterServerCommands(void)
COM_AddCommand("password", Command_Changepassword_f);
RegisterNetXCmd(XD_LOGIN, Got_Login);
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);
COM_AddCommand("removeadmin", Command_RemoveAdmin_f);
RegisterNetXCmd(XD_DEMOTED, Got_Removal);
COM_AddCommand("motd", Command_MotD_f);
RegisterNetXCmd(XD_SETMOTD, Got_MotD_f); // For remote admin
@ -1049,7 +1063,7 @@ UINT8 CanChangeSkin(INT32 playernum)
return true;
// 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;
// Can change skin in intermission and whatnot.
@ -1063,7 +1077,7 @@ UINT8 CanChangeSkin(INT32 playernum)
return true;
// Can change skin during initial countdown.
if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)
if (leveltime < 4*TICRATE)
return true;
if (G_TagGametype())
@ -1200,7 +1214,7 @@ static void SendNameAndColor(void)
snacpending++;
// 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]);
else // Cleanup name if changing it
CleanupPlayerName(consoleplayer, cv_playername.zstring);
@ -1607,7 +1621,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
mapchangepending = 0;
// spawn the server if needed
// reset players if there is a new one
if (!(adminplayer == consoleplayer))
if (!IsPlayerAdmin(consoleplayer))
{
if (SV_SpawnServer())
buf[0] &= ~(1<<1);
@ -1665,7 +1679,7 @@ static void Command_Map_f(void)
return;
}
if (client && !(adminplayer == consoleplayer))
if (client && !IsPlayerAdmin(consoleplayer))
{
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
return;
@ -1794,7 +1808,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
INT32 resetplayer = 1, lastgametype;
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]);
if (server)
@ -1868,8 +1882,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
// a copy of color
if (players[0].mo)
players[0].mo->color = players[0].skincolor;
CV_StealthSetValue(&cv_kartcc, 150); // srb2kart
}
if (metalrecording)
G_BeginMetal();
@ -1893,7 +1905,7 @@ static void Command_Pause(void)
else
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))
{
@ -1911,7 +1923,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
UINT8 dedicatedpause = false;
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]);
if (server)
@ -1970,11 +1982,11 @@ static void Command_Suicide(void)
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"));
return;
}
}*/
// Retry is quicker. Probably should force people to use it.
if (!(netgame || multiplayer))
@ -1991,7 +2003,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum)
INT32 suicideplayer = READINT32(*cp);
// 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]);
if (server)
@ -2040,7 +2052,7 @@ static void Got_RandomSeed(UINT8 **cp, INT32 playernum)
*/
static void Command_Clearscores_f(void)
{
if (!(server || (adminplayer == consoleplayer)))
if (!(server || (IsPlayerAdmin(consoleplayer))))
return;
SendNetXCmd(XD_CLEARSCORES, NULL, 1);
@ -2060,7 +2072,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum)
INT32 i;
(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]);
if (server)
@ -2281,7 +2293,7 @@ static void Command_ServerTeamChange_f(void)
UINT16 usvalue;
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"));
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 (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]);
if (server)
@ -2467,7 +2479,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
}
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]);
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.
if (G_TagGametype())
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))
{
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
CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[playernum]);
#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)
{
XBOXSTATIC char buf[8]; // Should be plenty
@ -2797,7 +2858,7 @@ static void Command_Verify_f(void)
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;
}
@ -2831,7 +2892,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum)
return;
}
adminplayer = num;
SetAdminPlayer(num);
if (num != consoleplayer)
return;
@ -2839,6 +2900,62 @@ static void Got_Verification(UINT8 **cp, INT32 playernum)
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)
{
size_t i, j;
@ -2850,7 +2967,7 @@ static void Command_MotD_f(void)
return;
}
if (!(server || (adminplayer == consoleplayer)))
if (!(server || (IsPlayerAdmin(consoleplayer))))
{
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
return;
@ -2897,7 +3014,7 @@ static void Got_MotD_f(UINT8 **cp, INT32 playernum)
if (!isprint(mymotd[i]) || mymotd[i] == ';')
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]);
if (server)
@ -2934,7 +3051,7 @@ static void Command_RunSOC(void)
else
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"));
return;
@ -2960,7 +3077,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
char filename[256];
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]);
if (server)
@ -3031,7 +3148,7 @@ static void Command_Addfile(void)
if (!musiconly)
{
// ... 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"));
return;
@ -3074,7 +3191,7 @@ static void Command_Addfile(void)
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);
else
SendNetXCmd(XD_ADDFILE, buf, buf_p - buf);
@ -3123,7 +3240,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
UINT8 md5sum[16];
boolean kick = false;
boolean toomany = false;
INT32 i;
INT32 i,j;
size_t packetsize = 0;
serverinfo_pak *dummycheck = NULL;
@ -3142,7 +3259,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
if (!isprint(filename[i]) || filename[i] == ';')
kick = true;
if ((playernum != serverplayer && playernum != adminplayer) || kick)
if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick)
{
XBOXSTATIC UINT8 buf[2];
@ -3181,8 +3298,9 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
CONS_Printf("%s",message);
if (adminplayer)
COM_BufAddText(va("sayto %d %s", adminplayer, message));
for (j = 0; j < MAXPLAYERS; j++)
if (adminplayers[j])
COM_BufAddText(va("sayto %d %s", adminplayers[j], message));
return;
}
@ -3496,9 +3614,9 @@ void D_GameTypeChanged(INT32 lastgametype)
case GT_TEAMMATCH:
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_timelimit, 10);
CV_SetValue(&cv_timelimit, 0);
}
if (!cv_itemrespawntime.changed)
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,
// make everyone a spectator initially.
if (!splitscreen && (G_GametypeHasSpectators()))
/*if (!splitscreen && (G_GametypeHasSpectators()))
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
@ -3565,7 +3683,7 @@ void D_GameTypeChanged(INT32 lastgametype)
players[i].ctfteam = 0;
players[i].spectator = true;
}
}
}*/
// 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.
@ -3576,7 +3694,7 @@ void D_GameTypeChanged(INT32 lastgametype)
if (playeringame[i])
players[i].ctfteam = 0;
if (server || (adminplayer == consoleplayer))
if (server || (IsPlayerAdmin(consoleplayer)))
{
CV_StealthSetValue(&cv_teamscramble, 0);
teamscramble = 0;
@ -3659,7 +3777,7 @@ static void TeamScramble_OnChange(void)
if (!cv_teamscramble.value)
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"));
CV_StealthSetValue(&cv_teamscramble, 0);
@ -3838,7 +3956,7 @@ static void Command_ExitLevel_f(void)
{
if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug)
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"));
else if (gamestate != GS_LEVEL || demoplayback)
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)
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]);
if (server)
@ -4027,7 +4145,7 @@ static void Command_Cheats_f(void)
{
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"));
else
CV_ResetCheatNetVars();
@ -4037,7 +4155,7 @@ static void Command_Cheats_f(void)
if (CV_CheatsEnabled())
{
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"));
}
else
@ -4106,7 +4224,7 @@ static void Command_Archivetest_f(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)
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.
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"));
CV_StealthSet(&cv_playername, player_names[consoleplayer]);
@ -4259,7 +4377,7 @@ static void Color2_OnChange(void)
*/
static void Mute_OnChange(void)
{
if (server || (adminplayer == consoleplayer))
if (server || (IsPlayerAdmin(consoleplayer)))
return;
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_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_feather;
extern consvar_t cv_karthud;
extern consvar_t cv_kartcheck;
extern consvar_t cv_kartstarsfx;
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_collideminimum;
@ -170,9 +177,10 @@ typedef enum
XD_DELFILE, // 18
XD_SETMOTD, // 19
XD_SUICIDE, // 20
XD_DEMOTED, // 21
#ifdef HAVE_BLUA
XD_LUACMD, // 21
XD_LUAVAR, // 22
XD_LUACMD, // 22
XD_LUAVAR, // 23
#endif
MAXNETXCMD
} netxcmd_t;
@ -228,6 +236,10 @@ void Command_Retry_f(void);
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 ObjectPlace_OnChange(void);
boolean IsPlayerAdmin(INT32 playernum);
void SetAdminPlayer(INT32 playernum);
void ClearAdminPlayers(void);
void RemoveAdminPlayer(INT32 playernum);
void ItemFinder_OnChange(void);
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_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_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_boosting, // Determines if you're currently shroom-boosting
@ -266,6 +267,7 @@ typedef enum
// Some items use timers for their duration or effects
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_boostolentimer, // You are being stolen from, this is your timer
k_mushroomtimer, // Duration of the Mushroom Boost itself
@ -273,8 +275,11 @@ typedef enum
k_squishedtimer, // Squished frame timer
k_goldshroomtimer, // Gold Mushroom duration 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_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
k_magnet, // 0x1 = Magnet in inventory
@ -301,8 +306,15 @@ typedef enum
k_tripleredshell, // 0x1 = 1 Red Shell orbiting, 0x2 = 2 Red Shells orbiting
// 0x4 = 3 Red Shells orbiting, 0x8 = Triple Red Shell 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
// 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
} kartstufftype_t;
//}
@ -365,7 +377,6 @@ typedef struct player_s
// SRB2kart stuff
INT32 kartstuff[NUMKARTSTUFF];
boolean collide[MAXPLAYERS];
angle_t frameangle; // for the player add the ability to have the sprite only face other angles
// Bit flags.
@ -467,6 +478,7 @@ typedef struct player_s
INT16 starposty;
INT16 starpostz;
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
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},
{"MATCH",TOL_MATCH},
{"BATTLE",TOL_MATCH}, // SRB2kart
{"TAG",TOL_TAG},
{"CTF",TOL_CTF},
@ -989,13 +990,13 @@ static const struct {
{"2D",TOL_2D},
{"MARIO",TOL_MARIO},
{"NIGHTS",TOL_NIGHTS},
{"OLDBRAK",TOL_ERZ3},
//{"OLDBRAK",TOL_ERZ3},
{"XMAS",TOL_XMAS},
{"CHRISTMAS",TOL_XMAS},
{"WINTER",TOL_XMAS},
{"KART",TOL_KART}, // SRB2kart
//{"KART",TOL_KART}, // SRB2kart
{NULL, 0}
};
@ -1252,9 +1253,20 @@ static void readlevelheader(MYFILE *f, INT32 num)
}
else if (fastcmp(word, "LEVELFLAGS"))
mapheaderinfo[num-1]->levelflags = (UINT8)i;
mapheaderinfo[num-1]->levelflags = get_number(word2);
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)
else if (fastcmp(word, "SCRIPTISFILE"))
@ -6367,6 +6379,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_SINKTRAIL2",
"S_SINKTRAIL3",
// Battle Mode balloon
"S_BATTLEBALLOON1",
"S_BATTLEBALLOON2",
"S_BATTLEBALLOON3",
// Pokey
"S_POKEY1",
"S_POKEY2",
@ -6401,6 +6418,28 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FIREDITEM3",
"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
"S_NAMECHECK",
#endif
@ -6958,6 +6997,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_SINK", // Kitchen Sink Stuff
"MT_SINKTRAIL",
"MT_BATTLEBALLOON", // Battle Mode balloon
"MT_LAKITU",
"MT_POKEY", // Huh, thought this was a default asset for some reason, guess not.
"MT_ENEMYFLIP",
"MT_WAYPOINT",
@ -6969,6 +7012,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_FIREDITEM",
"MT_PLAYERARROW",
#ifdef SEENAMES
"MT_NAMECHECK",
#endif
@ -7281,6 +7326,81 @@ static const char *const POWERS_LIST[] = {
"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[] = {
"LIVESNAME",
"LIVESPIC",
@ -7420,8 +7540,9 @@ struct {
{"TOL_2D",TOL_2D},
{"TOL_MARIO",TOL_MARIO},
{"TOL_NIGHTS",TOL_NIGHTS},
{"TOL_ERZ3",TOL_ERZ3},
//{"TOL_ERZ3",TOL_ERZ3},
{"TOL_XMAS",TOL_XMAS},
//{"TOL_KART",TOL_KART},
// Level flags
{"LF_SCRIPTISFILE",LF_SCRIPTISFILE},
@ -7915,6 +8036,20 @@ static powertype_t get_power(const char *word)
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.
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; }
@ -8151,6 +8286,7 @@ void FUNCMATH DEH_Check(void)
const size_t dehstates = sizeof(STATE_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 dehkartstuff = sizeof(KARTSTUFF_LIST)/sizeof(const char*);
const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*);
if (dehstates != S_FIRSTFREESLOT)
@ -8162,6 +8298,9 @@ void FUNCMATH DEH_Check(void)
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));
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)
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
@ -8501,6 +8640,24 @@ static inline int lib_getenum(lua_State *L)
}
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)) {
p = word+4;
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);
return 1;
} else if (fastcmp(word,"admin")) {
if (!playeringame[adminplayer] || adminplayer == serverplayer)
return 0;
LUA_PushUserdata(L, &players[adminplayer], META_PLAYER);
//if (!playeringame[adminplayer] || IsPlayerAdmin(serverplayer))
//return 0;
//LUA_PushUserdata(L, &players[adminplayer], META_PLAYER);
return 1;
} else if (fastcmp(word,"emeralds")) {
lua_pushinteger(L, emeralds);

View file

@ -246,13 +246,14 @@ typedef struct
UINT8 numGradedMares; ///< Internal. For grade support.
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.
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
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;
// level flags
@ -290,9 +291,9 @@ enum TypeOfLevel
TOL_2D = 0x0100, ///< 2D
TOL_MARIO = 0x0200, ///< Mario
TOL_NIGHTS = 0x0400, ///< NiGHTS
TOL_ERZ3 = 0x0800, ///< ERZ3
TOL_XMAS = 0x1000, ///< Christmas NiGHTS
TOL_KART = 0x4000 ///< Kart 32768
//TOL_ERZ3 = 0x0800, ///< ERZ3
TOL_XMAS = 0x1000 ///< Christmas NiGHTS
//TOL_KART = 0x4000 ///< Kart 32768
};
// Gametypes
@ -329,7 +330,7 @@ extern UINT16 emeralds;
#define EMERALD7 64
#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.
*/
@ -401,8 +402,10 @@ extern UINT16 extralifetics;
// SRB2kart
extern INT32 bootime;
extern INT32 boostealtime;
extern INT32 mushroomtime;
extern INT32 itemtime;
extern INT32 comebacktime;
extern UINT8 introtoplay;
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_downloading; // allow clients to downloading WADs.
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
extern INT32 adminplayer, serverplayer;
extern INT32 serverplayer;
extern INT32 adminplayers[MAXPLAYERS];
/// \note put these in d_clisrv outright?

View file

@ -259,7 +259,8 @@ typedef enum
postimg_water,
postimg_motion,
postimg_flip,
postimg_heat
postimg_heat,
postimg_mirror
} postimg_t;
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++)
{
if (netgame && i != serverplayer && i != adminplayer)
if (netgame && i != serverplayer && !IsPlayerAdmin(i))
continue;
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!
INT32 nummaprings = 0;
// box respawning in battle mode
INT32 nummapboxes = 0;
INT32 numgotboxes = 0;
// Elminates unnecessary searching.
boolean CheckForBustableBlocks;
boolean CheckForBouncySector;
@ -198,8 +202,10 @@ UINT16 extralifetics = 4*TICRATE;
// SRB2kart
INT32 bootime = 7*TICRATE;
INT32 boostealtime = TICRATE/2;
INT32 mushroomtime = TICRATE + (TICRATE/3);
INT32 itemtime = 8*TICRATE;
INT32 comebacktime = 10*TICRATE;
INT32 gameovertics = 15*TICRATE;
@ -974,6 +980,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
gamepadjoystickmove = cv_usejoystick.value && Joystick.bGamepadStyle;
axis = JoyAxis(AXISTURN);
if (cv_kartmirror.value)
{
turnright = PLAYER1INPUTDOWN(gc_turnleft);
turnleft = PLAYER1INPUTDOWN(gc_turnright);
axis = -axis;
}
if (gamepadjoystickmove && 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->sidemove = (SINT8)(cmd->sidemove + side);
if (cv_kartmirror.value)
cmd->sidemove = -cmd->sidemove;
//{ SRB2kart - Drift support
axis = JoyAxis(AXISTURN);
if (cv_kartmirror.value)
axis = -axis;
if (cmd->angleturn > 0) // Drifting to the left
cmd->buttons |= BT_DRIFTLEFT;
@ -1322,6 +1341,14 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
gamepadjoystickmove = cv_usejoystick2.value && Joystick2.bGamepadStyle;
axis = Joy2Axis(AXISTURN);
if (cv_kartmirror.value)
{
turnright = PLAYER2INPUTDOWN(gc_turnleft);
turnleft = PLAYER2INPUTDOWN(gc_turnright);
axis = -axis;
}
if (gamepadjoystickmove && 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->sidemove = (SINT8)(cmd->sidemove + side);
if (cv_kartmirror.value)
cmd->sidemove = -cmd->sidemove;
//{ SRB2kart - Drift support
axis = Joy2Axis(AXISTURN);
if (cv_kartmirror.value)
axis = -axis;
if (cmd->angleturn > 0) // Drifting to the left
cmd->buttons |= BT_DRIFTLEFT;
@ -1784,7 +1816,7 @@ boolean G_Responder(event_t *ev)
if (players[displayplayer].spectator)
continue;
if (G_GametypeHasTeams())
/*if (G_GametypeHasTeams())
{
if (players[consoleplayer].ctfteam
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
@ -1806,6 +1838,12 @@ boolean G_Responder(event_t *ev)
{
if (!players[consoleplayer].spectator)
continue;
}*/
if (gametype != GT_RACE) // srb2kart
{
if (players[consoleplayer].kartstuff[k_balloon] > 0)
continue;
}
break;
@ -2120,7 +2158,6 @@ static inline void G_PlayerFinishLevel(INT32 player)
memset(p->powers, 0, sizeof (p->powers));
memset(p->kartstuff, 0, sizeof (p->kartstuff)); // SRB2kart
memset(p->collide, 0, sizeof (p->collide)); // SRB2kart
p->ringweapons = 0;
p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility
@ -2131,6 +2168,7 @@ static inline void G_PlayerFinishLevel(INT32 player)
p->starposty = 0;
p->starpostz = 0;
p->starpostnum = 0;
p->starpostcount = 0;
if (rendermode == render_soft)
V_SetPaletteLump(GetPalette()); // Reset the palette
@ -2171,6 +2209,7 @@ void G_PlayerReborn(INT32 player)
INT16 starposty;
INT16 starpostz;
INT32 starpostnum;
INT32 starpostcount;
INT32 starpostangle;
fixed_t jumpfactor;
INT32 exiting;
@ -2188,6 +2227,9 @@ void G_PlayerReborn(INT32 player)
// SRB2kart
INT32 starpostwp;
INT32 offroad;
INT32 balloon;
INT32 comebackpoints;
INT32 comebackshowninfo;
score = players[player].score;
lives = players[player].lives;
@ -2226,6 +2268,7 @@ void G_PlayerReborn(INT32 player)
starposty = players[player].starposty;
starpostz = players[player].starpostz;
starpostnum = players[player].starpostnum;
starpostcount = players[player].starpostcount;
starpostangle = players[player].starpostangle;
jumpfactor = players[player].jumpfactor;
thokitem = players[player].thokitem;
@ -2242,6 +2285,9 @@ void G_PlayerReborn(INT32 player)
// SRB2kart
starpostwp = players[player].kartstuff[k_starpostwp];
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];
memset(p, 0, sizeof (*p));
@ -2281,6 +2327,7 @@ void G_PlayerReborn(INT32 player)
p->starposty = starposty;
p->starpostz = starpostz;
p->starpostnum = starpostnum;
p->starpostcount = starpostcount;
p->starpostangle = starpostangle;
p->jumpfactor = jumpfactor;
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_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
p->pflags |= PF_USEDOWN;
p->pflags |= PF_ATTACKDOWN;
@ -2308,7 +2360,7 @@ void G_PlayerReborn(INT32 player)
p->panim = PA_IDLE; // standing animation
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)
{
@ -2399,6 +2451,9 @@ static boolean G_CheckSpot(INT32 playernum, mapthing_t *mthing)
if (!P_CheckPosition(players[playernum].mo, x, y))
return false;
if (!K_CheckPlayersRespawnColliding(playernum, x, y))
return false;
return true;
}
@ -2644,6 +2699,7 @@ void G_DoReborn(INT32 playernum)
player->starposty = 0;
player->starpostz = 0;
player->starpostnum = 0;
player->starpostcount = 0;
}
if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD))
{
@ -2801,7 +2857,8 @@ boolean G_GametypeHasTeams(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
D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false);
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);
}
@ -3692,6 +3749,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
players[i].playerstate = PST_REBORN;
players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0;
players[i].starpostx = players[i].starposty = players[i].starpostz = 0;
players[i].starpostcount = 0; // srb2kart
if (netgame || multiplayer)
{

View file

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

View file

@ -5591,6 +5591,11 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
else
atransform.flip = false;
if (*type == postimg_mirror)
atransform.mirror = true;
else
atransform.mirror = false;
atransform.x = gr_viewx; // FIXED_TO_FLOAT(viewx)
atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy)
atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz)
@ -5610,6 +5615,11 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
else
stransform.flip = false;
if (*type == postimg_mirror)
stransform.mirror = true;
else
stransform.mirror = false;
stransform.x = 0.0f;
stransform.y = 0.0f;
stransform.z = 0.0f;
@ -5821,6 +5831,11 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
else
atransform.flip = false;
if (*type == postimg_mirror)
atransform.mirror = true;
else
atransform.mirror = false;
atransform.x = gr_viewx; // FIXED_TO_FLOAT(viewx)
atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy)
atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz)
@ -5840,6 +5855,11 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
else
stransform.flip = false;
if (*type == postimg_mirror)
stransform.mirror = true;
else
stransform.mirror = false;
stransform.x = 0.0f;
stransform.y = 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
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);
else
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;
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"));
return;
}
// Only servers/admins can CSAY.
if(!server && adminplayer != consoleplayer)
if(!server && IsPlayerAdmin(consoleplayer))
flags &= ~HU_CSAY;
// We handle HU_SERVER_SAY, not the caller.
@ -462,7 +462,7 @@ static void Command_CSay_f(void)
return;
}
if(!server && adminplayer != consoleplayer)
if(!server && !IsPlayerAdmin(consoleplayer))
{
CONS_Alert(CONS_NOTICE, M_GetText("Only servers and admins can use csay.\n"));
return;
@ -491,7 +491,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
msg = (char *)*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 ?
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.
if (playernum == serverplayer)
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);
if (tempchar)
{
@ -724,7 +724,7 @@ static void HU_queueChatChar(char c)
} while (c);
// 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"));
return;
@ -782,9 +782,9 @@ boolean HU_Responder(event_t *ev)
{
// enter chat mode
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;
chat_on = true;
w_chat[0] = 0;
@ -792,9 +792,9 @@ boolean HU_Responder(event_t *ev)
return true;
}
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;
chat_on = true;
w_chat[0] = 0;

View file

@ -57,8 +57,8 @@ char sprnames[NUMSPRITES + 1][5] =
//SRB2kart Sprites
"SPRG","BSPR","RNDM","RPOP","KFRE","DRIF","DSMO","FITM","DFAK","BANA",
"DBAN","GSHE","DGSH","RSHE","DRSH","BOMB","BLIG","LIGH","SINK","SITR",
"LAKI","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM",
"SACO","CRAB","SHAD","BUMP","FLEN","CLAS","PSHW"
"KBLN","LAKI","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB",
"CHOM","SACO","CRAB","SHAD","BUMP","FLEN","CLAS","PSHW","ARRO","PBOM"
};
// 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, 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, 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|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
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
#endif
@ -15112,6 +15139,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
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
-1, // doomednum
S_LAKITU1, // spawnstate
@ -16596,6 +16650,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
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

View file

@ -598,6 +598,7 @@ typedef enum sprite
SPR_LIGH, // Lightning
SPR_SINK, // Kitchen Sink
SPR_SITR, // Kitchen Sink Trail
SPR_KBLN, // Battle Mode Balloon
SPR_LAKI, // Lakitu
@ -620,6 +621,10 @@ typedef enum sprite
SPR_CLAS, // items clash
SPR_PSHW, // thrown indicator
SPR_ARRO, // player arrows
SPR_PBOM, // player bomb
SPR_FIRSTFREESLOT,
SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
NUMSPRITES
@ -3212,6 +3217,11 @@ typedef enum state
S_SINKTRAIL2,
S_SINKTRAIL3,
// Battle Mode balloons
S_BATTLEBALLOON1,
S_BATTLEBALLOON2,
S_BATTLEBALLOON3,
// Lakitu
S_LAKITU1,
S_LAKITU2,
@ -3373,6 +3383,28 @@ typedef enum state
S_FIREDITEM3,
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
S_NAMECHECK,
#endif
@ -3947,6 +3979,8 @@ typedef enum mobj_type
MT_SINK, // Kitchen Sink Stuff
MT_SINKTRAIL,
MT_BATTLEBALLOON, // Battle Mode balloons
MT_LAKITU,
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_PLAYERARROW,
#ifdef SEENAMES
MT_NAMECHECK,
#endif

File diff suppressed because it is too large Load diff

View file

@ -9,28 +9,39 @@
#include "doomdef.h"
#include "d_player.h" // Need for player_t
UINT8 colortranslations[MAXSKINCOLORS][16];
extern const char *KartColor_Names[MAXSKINCOLORS];
void K_StarmanColormap(UINT8 *dest_colormap, UINT8 skincolor);
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color);
UINT8 K_GetKartColorByName(const char *name);
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_KartPlayerThink(player_t *player, ticcmd_t *cmd);
void K_SpinPlayer(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_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_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);
void K_MomentumToFacing(player_t *player);
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);
void K_MoveKartPlayer(player_t *player, boolean onground);
void K_CheckBalloons(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);
// =========================================================================

View file

@ -20,6 +20,7 @@
#include "m_random.h"
#include "s_sound.h"
#include "g_game.h"
#include "k_kart.h"
#include "lua_script.h"
#include "lua_libs.h"
@ -1009,10 +1010,11 @@ static int lib_pTeleportMove(lua_State *L)
static int lib_pSlideMove(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
boolean forceslide = luaL_checkboolean(L, 2);
NOHUD
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
P_SlideMove(mo);
P_SlideMove(mo, forceslide);
return 0;
}
@ -1980,6 +1982,184 @@ static int lib_gTicsToMilliseconds(lua_State *L)
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[] = {
{"print", lib_print},
{"EvalMath", lib_evalMath},
@ -2153,6 +2333,23 @@ static luaL_Reg lib[] = {
{"G_TicsToCentiseconds",lib_gTicsToCentiseconds},
{"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}
};

View file

@ -55,7 +55,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
lua_pop(gL, 1); // pop flags
// 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;
lua_rawgeti(gL, -1, 1); // push function from command info table
@ -131,7 +131,7 @@ void COM_Lua_f(void)
UINT8 argc;
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"));
return;

View file

@ -1235,6 +1235,10 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->levelflags);
else if (fastcmp(field,"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
else {
// Read custom vars now

View file

@ -130,8 +130,6 @@ static int player_get(lua_State *L)
LUA_PushUserdata(L, plr->powers, META_POWERS);
else if (fastcmp(field,"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"))
lua_pushangle(L, plr->frameangle);
else if (fastcmp(field,"pflags"))
@ -152,9 +150,9 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->dashtime);
// SRB2kart
else if (fastcmp(field,"kartspeed"))
lua_pushfixed(L, plr->kartspeed);
lua_pushinteger(L, plr->kartspeed);
else if (fastcmp(field,"kartweight"))
lua_pushfixed(L, plr->kartweight);
lua_pushinteger(L, plr->kartweight);
//
else if (fastcmp(field,"normalspeed"))
lua_pushfixed(L, plr->normalspeed);
@ -248,6 +246,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->starpostz);
else if (fastcmp(field,"starpostnum"))
lua_pushinteger(L, plr->starpostnum);
else if (fastcmp(field,"starpostcount"))
lua_pushinteger(L, plr->starpostcount);
else if (fastcmp(field,"starposttime"))
lua_pushinteger(L, plr->starposttime);
else if (fastcmp(field,"starpostangle"))
@ -414,10 +414,14 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"dashtime"))
plr->dashtime = (INT32)luaL_checkinteger(L, 3);
// SRB2kart
else if (fastcmp(field,"kartstuff"))
return NOSET;
else if (fastcmp(field,"frameangle"))
plr->frameangle = luaL_checkangle(L, 3);
else if (fastcmp(field,"kartspeed"))
plr->kartspeed = (UINT8)luaL_checkfixed(L, 3);
plr->kartspeed = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"kartweight"))
plr->kartweight = (UINT8)luaL_checkfixed(L, 3);
plr->kartweight = (UINT8)luaL_checkinteger(L, 3);
//
else if (fastcmp(field,"normalspeed"))
plr->normalspeed = luaL_checkfixed(L, 3);
@ -511,6 +515,8 @@ static int player_set(lua_State *L)
plr->starpostz = (INT16)luaL_checkinteger(L, 3);
else if (fastcmp(field,"starpostnum"))
plr->starpostnum = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"starpostcount"))
plr->starpostcount = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"starposttime"))
plr->starposttime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"starpostangle"))
@ -672,6 +678,38 @@ static int power_len(lua_State *L)
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)
static int ticcmd_get(lua_State *L)
@ -749,6 +787,17 @@ int LUA_PlayerLib(lua_State *L)
lua_setfield(L, -2, "__len");
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);
lua_pushcfunction(L, ticcmd_get);
lua_setfield(L, -2, "__index");

View file

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

View file

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

View file

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

View file

@ -271,8 +271,8 @@ static void M_SetupMultiPlayer2(INT32 choice);
// Options
// Split into multiple parts due to size
// Controls
menu_t OP_ControlsDef, OP_ControlListDef, OP_MoveControlsDef;
menu_t /*OP_MPControlsDef,*/ OP_CameraControlsDef, OP_MiscControlsDef;
menu_t OP_ControlsDef, /*OP_ControlListDef,*/ OP_MoveControlsDef;
menu_t /*OP_MPControlsDef, OP_CameraControlsDef, OP_MiscControlsDef,*/ OP_CustomControlsDef;
menu_t OP_P1ControlsDef, OP_P2ControlsDef, OP_MouseOptionsDef;
menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def;
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!
CV_PossibleValue_t gametype_cons_t[] =
{
{GT_RACE, "Race"}, {GT_MATCH, "Match"},
{GT_RACE, "Race"}, {GT_MATCH, "Battle"},
/* // SRB2kart
{GT_COOP, "Co-op"},
@ -977,9 +977,9 @@ static menuitem_t MP_SplitServerMenu[] =
static menuitem_t MP_PlayerSetupMenu[] =
{
{IT_KEYHANDLER | IT_STRING, NULL, "Your name", M_HandleSetupMultiPlayer, 0},
{IT_KEYHANDLER | IT_STRING, NULL, "Your color", M_HandleSetupMultiPlayer, 16},
{IT_KEYHANDLER | IT_STRING, NULL, "Your player", M_HandleSetupMultiPlayer, 96}, // Tails 01-18-2001
{IT_KEYHANDLER | IT_STRING, NULL, "Name", M_HandleSetupMultiPlayer, 0},
{IT_KEYHANDLER | IT_STRING, NULL, "Character", M_HandleSetupMultiPlayer, 16}, // 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},
};
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, "Multiplayer Controls...", &OP_MPControlsDef, 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, "Camera Controls...", &OP_CameraControlsDef, 20},
// {IT_SUBMENU | IT_STRING, NULL, "Miscellaneous Controls...", &OP_MiscControlsDef, 20},
};*/
static menuitem_t OP_MoveControlsMenu[] =
{
{IT_CALL | IT_STRING2, NULL, "Forward", M_ChangeControl, gc_forward },
{IT_CALL | IT_STRING2, NULL, "Reverse", M_ChangeControl, gc_backward },
{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, "Accelerate", M_ChangeControl, gc_accelerate },
{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, "Use/Throw Item", M_ChangeControl, gc_fire },
{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, "Turn Left", M_ChangeControl, gc_turnleft },
{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, "Drift", M_ChangeControl, gc_jump },
{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, "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 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
/*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 6", M_ChangeControl, gc_wepslot6 },
// {IT_CALL | IT_STRING2, NULL, "Weapon Slot 7", M_ChangeControl, gc_wepslot7 },
};*/
};
static menuitem_t OP_CameraControlsMenu[] =
{
// {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, "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, "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[] =
@ -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, "Rankings/Scores", M_ChangeControl, gc_scores },
{IT_CALL | IT_STRING2, NULL, "Spectate", M_ChangeControl, gc_spectate },
};
};*/
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_PlayerSetupDef =
{
"M_SPLAYR",
NULL, //"M_SPLAYR"
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
&MP_MainDef,
MP_PlayerSetupMenu,
M_DrawSetupMultiPlayerMenu,
27, 40,
32, 16,
0,
M_QuitMultiPlayerMenu
};
@ -1670,11 +1685,12 @@ menu_t MP_PlayerSetupDef =
// Options
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_ControlListDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlListMenu, &OP_ControlsDef, 60, 30);
menu_t OP_MoveControlsDef = CONTROLMENUSTYLE(OP_MoveControlsMenu, &OP_ControlListDef);
//menu_t OP_ControlListDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlListMenu, &OP_ControlsDef, 60, 30);
menu_t OP_MoveControlsDef = CONTROLMENUSTYLE(OP_MoveControlsMenu, &OP_ControlsDef);
//menu_t OP_MPControlsDef = CONTROLMENUSTYLE(OP_MPControlsMenu, &OP_ControlListDef);
menu_t OP_CameraControlsDef = CONTROLMENUSTYLE(OP_CameraControlsMenu, &OP_ControlListDef);
menu_t OP_MiscControlsDef = CONTROLMENUSTYLE(OP_MiscControlsMenu, &OP_ControlListDef);
//menu_t OP_CameraControlsDef = CONTROLMENUSTYLE(OP_CameraControlsMenu, &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_P2ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P2ControlsMenu, &OP_ControlsDef, 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_psetup].status = IT_DISABLED;
if ((server || adminplayer == consoleplayer))
if ((server || IsPlayerAdmin(consoleplayer)))
{
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
if (G_GametypeHasTeams())
@ -3962,7 +3978,7 @@ static void M_Options(INT32 choice)
(void)choice;
// 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
OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
@ -5637,11 +5653,11 @@ static void M_HandleStaffReplay(INT32 choice)
{
case KEY_DOWNARROW:
M_NextOpt();
S_StartSound(NULL, sfx_bewar1);
S_StartSound(NULL, sfx_menu1);
break;
case KEY_UPARROW:
M_PrevOpt();
S_StartSound(NULL, sfx_bewar1);
S_StartSound(NULL, sfx_menu1);
break;
case KEY_BACKSPACE:
case KEY_ESCAPE:
@ -6462,9 +6478,6 @@ static void M_HandleConnectIP(INT32 choice)
// ========================
// Tails 03-02-2002
#define PLBOXW 8
#define PLBOXH 9
static INT32 multi_tics;
static state_t *multi_state;
@ -6483,8 +6496,13 @@ static void M_DrawSetupMultiPlayerMenu(void)
INT32 mx, my, st, flags = 0;
spritedef_t *sprdef;
spriteframe_t *sprframe;
patch_t *statbg = W_CachePatchName("K_STATBG", PU_CACHE);
patch_t *statdot = W_CachePatchName("K_SDOT0", PU_CACHE);
patch_t *patch;
UINT8 frame;
UINT8 speed;
UINT8 weight;
UINT8 i;
mx = MP_PlayerSetupDef.x;
my = MP_PlayerSetupDef.y;
@ -6493,21 +6511,101 @@ static void M_DrawSetupMultiPlayerMenu(void)
M_DrawGenericMenu();
// draw name string
M_DrawTextBox(mx + 90, my - 8, MAXPLAYERNAME, 1);
V_DrawString(mx + 98, my, V_ALLOWLOWERCASE, setupm_name);
M_DrawTextBox(mx + 32, my - 8, MAXPLAYERNAME, 1);
V_DrawString(mx + 40, my, V_ALLOWLOWERCASE, setupm_name);
// 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,
skins[setupm_fakeskin].realname);
// draw the name of the color you have chosen
// 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
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
if (--multi_tics <= 0)
@ -6534,25 +6632,34 @@ static void M_DrawSetupMultiPlayerMenu(void)
frame = 0; // Try to use standing 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
flags |= V_FLIP; // This sprite is left/right flipped!
// 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
if (!setupm_fakecolor) // should never happen but hey, who knows
{
if (skins[setupm_fakeskin].flags & SF_HIRES)
{
V_DrawSciencePatch((mx+98+(PLBOXW*8/2))<<FRACBITS,
(my+16+(PLBOXH*8)-12)<<FRACBITS,
V_DrawSciencePatch((mx+42)<<FRACBITS,
(my+132)<<FRACBITS,
flags, patch,
skins[setupm_fakeskin].highresscale);
}
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
{
@ -6560,16 +6667,18 @@ static void M_DrawSetupMultiPlayerMenu(void)
if (skins[setupm_fakeskin].flags & SF_HIRES)
{
V_DrawFixedPatch((mx+98+(PLBOXW*8/2))<<FRACBITS,
(my+16+(PLBOXH*8)-12)<<FRACBITS,
V_DrawFixedPatch((mx+42)<<FRACBITS,
(my+132)<<FRACBITS,
skins[setupm_fakeskin].highresscale,
flags, patch, colormap);
}
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);
}
#undef charw
}
// Handle 1P/2P MP Setup
@ -6591,12 +6700,12 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break;
case KEY_LEFTARROW:
if (itemOn == 2) //player skin
if (itemOn == 1) //player skin
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakeskin--;
}
else if (itemOn == 1) // player color
else if (itemOn == 2) // player color
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor--;
@ -6604,12 +6713,12 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break;
case KEY_RIGHTARROW:
if (itemOn == 2) //player skin
if (itemOn == 1) //player skin
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakeskin++;
}
else if (itemOn == 1) // player color
else if (itemOn == 2) // player color
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor++;
@ -6873,15 +6982,15 @@ static void M_Setup1PControlsMenu(INT32 choice)
currentMenu->lastOn = itemOn;
// Unhide the three non-P2 controls
//OP_MPControlsMenu[0].status = IT_CALL|IT_STRING2;
//OP_MPControlsMenu[1].status = IT_CALL|IT_STRING2;
//OP_MPControlsMenu[2].status = IT_CALL|IT_STRING2;
OP_MoveControlsMenu[12].status = IT_CALL|IT_STRING2;
OP_MoveControlsMenu[13].status = IT_CALL|IT_STRING2;
OP_MoveControlsMenu[14].status = IT_CALL|IT_STRING2;
// Unide the pause/console controls too
OP_MiscControlsMenu[3].status = IT_CALL|IT_STRING2;
OP_MiscControlsMenu[4].status = IT_CALL|IT_STRING2;
OP_MoveControlsMenu[10].status = IT_CALL|IT_STRING2;
OP_MoveControlsMenu[11].status = IT_CALL|IT_STRING2;
OP_ControlListDef.prevMenu = &OP_P1ControlsDef;
M_SetupNextMenu(&OP_ControlListDef);
OP_MoveControlsDef.prevMenu = &OP_P1ControlsDef;
M_SetupNextMenu(&OP_MoveControlsDef);
}
static void M_Setup2PControlsMenu(INT32 choice)
@ -6892,15 +7001,15 @@ static void M_Setup2PControlsMenu(INT32 choice)
currentMenu->lastOn = itemOn;
// Hide the three non-P2 controls
//OP_MPControlsMenu[0].status = IT_GRAYEDOUT2;
//OP_MPControlsMenu[1].status = IT_GRAYEDOUT2;
//OP_MPControlsMenu[2].status = IT_GRAYEDOUT2;
OP_MoveControlsMenu[12].status = IT_GRAYEDOUT2;
OP_MoveControlsMenu[13].status = IT_GRAYEDOUT2;
OP_MoveControlsMenu[14].status = IT_GRAYEDOUT2;
// Hide the pause/console controls too
OP_MiscControlsMenu[3].status = IT_GRAYEDOUT2;
OP_MiscControlsMenu[4].status = IT_GRAYEDOUT2;
OP_MoveControlsMenu[10].status = IT_GRAYEDOUT2;
OP_MoveControlsMenu[11].status = IT_GRAYEDOUT2;
OP_ControlListDef.prevMenu = &OP_P2ControlsDef;
M_SetupNextMenu(&OP_ControlListDef);
OP_MoveControlsDef.prevMenu = &OP_P2ControlsDef;
M_SetupNextMenu(&OP_MoveControlsDef);
}
// 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)))
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;
// go into chase state
@ -3627,12 +3627,16 @@ void A_AttractChase(mobj_t *actor)
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->health
|| !P_CheckSight(actor, actor->tracer)) // You have to be able to SEE it...sorta
{
// 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;
P_SetTarget(&actor->tracer, NULL);
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.
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;
if ((gametype == GT_CTF || gametype == GT_MATCH)
if ((gametype == GT_CTF || gametype == GT_TEAMMATCH)
&& !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
return true;
@ -8089,6 +8094,17 @@ void A_ToggleFlameJet(mobj_t* actor)
void A_ItemPop(mobj_t *actor)
{
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
//P_UnsetThingPosition(actor);
@ -8123,26 +8139,13 @@ void A_ItemPop(mobj_t *actor)
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_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");
actor->target->player->kartstuff[k_itemroulette] = 1;
remains->flags2 &= ~MF2_AMBUSH;
if (gametype != GT_RACE)
numgotboxes++;
P_RemoveMobj(actor);
}
@ -8152,6 +8155,10 @@ void A_RedShellChase(mobj_t *actor)
INT32 c = 0;
INT32 stop;
player_t *player;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_RedShellChase", actor))
return;
#endif
if (actor->tracer)
{
@ -8213,8 +8220,11 @@ void A_RedShellChase(mobj_t *actor)
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,
player->mo->y-actor->y), player->mo->z-actor->z) > RING_DIST)
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
&& 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);
return;
@ -8249,11 +8260,15 @@ void A_BobombExplode(mobj_t *actor)
INT32 d;
INT32 locvar1 = var1;
mobjtype_t type;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_BobombExplode", actor))
return;
#endif
type = (mobjtype_t)locvar1;
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);
@ -8269,6 +8284,9 @@ void A_BobombExplode(mobj_t *actor)
if (mo2 == actor || mo2->type == MT_BOMBEXPLOSIONSOUND) // Don't explode yourself! Endless loop!
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)
continue;

View file

@ -2037,33 +2037,6 @@ foundenemy:
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
//

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)
// 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;
}
@ -388,8 +410,34 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{
case MT_RANDOMITEM: // SRB2kart
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;
}
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;
P_SetTarget(&special->target, toucher);
P_SetMobjState(special, special->info->deathstate);
@ -1165,9 +1213,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
}
//
// In circuit, player must have touched all previous starposts
// SRB2kart: make sure the player will have enough checkpoints to touch
if (circuitmap
&& special->health - player->starpostnum > 1)
&& special->health >= (numstarposts/2 + player->starpostnum))
{
// blatant reuse of a variable that's normally unused in circuit
if (!player->tossdelay)
@ -1194,6 +1242,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->starpostz = special->z>>FRACBITS;
player->starpostangle = special->angle;
player->starpostnum = special->health;
player->starpostcount++;
P_ClearStarPost(special->health);
// 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;
else if (target->type == MT_TRIPLEBANANASHIELD3 && 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!
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)))
{ // Suicide penalty - Not in Kart
//if (target->player->score >= 50)
// target->player->score -= 50;
//else
// target->player->score = 0;
}
if (target->player->score >= 50)
target->player->score -= 50;
else
target->player->score = 0;
}*/
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);
source->player->numboxes++;
if ((cv_itemrespawn.value && gametype != GT_COOP && (modifiedgame || netgame || multiplayer)))
{
target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation
}
}
// Award Score Tails
{
/*{ // Enemies shouldn't award points in Kart
INT32 score = 0;
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);
}
}*/
}
// 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++)
{
if (players[w].pflags & PF_TAGIT)
P_AddPlayerScore(&players[w], 100);
P_AddPlayerScore(&players[w], 1);
}
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)
@ -2535,7 +2592,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
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);
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.
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);
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_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);
if (source && source->player)
{
// Award no points when players shoot each other when cv_friendlyfire is on.
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
{
// Award no points when players shoot each other when cv_friendlyfire is on.
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.
@ -2718,6 +2775,18 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
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.
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)))
@ -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.
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
static const boolean force = false;
#endif
mobj_t *blueexplode;
if (objectplacing)
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.
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;
}
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;
else
{
player->kartstuff[k_spinouttype] = 1;
K_SpinPlayer(player, source);
damage = player->mo->health - 1;
P_RingDamage(player, inflictor, source, damage);
if (inflictor && (inflictor->type == MT_GREENITEM || inflictor->type == MT_REDITEM || inflictor->type == MT_REDITEMDUD))
P_PlayerRingBurst(player, 5);
player->mo->momx = player->mo->momy = 0;
if (P_IsLocalPlayer(player))
if (inflictor && (inflictor->type == MT_GREENITEM || inflictor->type == MT_GREENSHIELD
|| inflictor->type == MT_REDITEM || inflictor->type == MT_REDSHIELD || inflictor->type == MT_REDITEMDUD
|| inflictor->type == MT_FAKEITEM || inflictor->type == MT_FAKESHIELD
|| inflictor->type == MT_TRIPLEGREENSHIELD1 || inflictor->type == MT_TRIPLEGREENSHIELD2 || inflictor->type == MT_TRIPLEGREENSHIELD3
|| inflictor->type == MT_TRIPLEREDSHIELD1 || inflictor->type == MT_TRIPLEREDSHIELD2 || inflictor->type == MT_TRIPLEREDSHIELD3
|| inflictor->player))
{
quake.intensity = 32*FRACUNIT;
quake.time = 5;
player->kartstuff[k_spinouttype] = 1;
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;
}
@ -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
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
P_PlayerRingBurst(player, damage);
}

View file

@ -135,6 +135,7 @@ boolean P_IsLocalPlayer(player_t *player);
boolean P_IsObjectInGoop(mobj_t *mo);
boolean P_IsObjectOnGround(mobj_t *mo);
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_InQuicksand(mobj_t *mo);
@ -153,7 +154,7 @@ void P_DoJumpShield(player_t *player);
void P_BlackOw(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_PlayerAfterThink(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;
void P_RespawnSpecials(void);
void P_RespawnBattleSpecials(void);
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_Move(mobj_t *actor, fixed_t speed);
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);
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);

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)
{
INT32 p;
@ -400,6 +401,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
sonic->pflags &= ~PF_CARRIED;
}
}
#endif
//
// 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
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)
{
// 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)))
return true;
if (thing->player && thing->player->powers[pw_flashing])
return true;
if (thing->type == MT_PLAYER)
{
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))
return true;
if (thing->player && thing->player->powers[pw_flashing])
return true;
if (thing->type == MT_PLAYER)
{
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)
return true; // Fireballs don't collide with eachother
if (thing->player && thing->player->powers[pw_flashing])
return true;
if (thing->type == MT_PLAYER)
{
// Player Damage
@ -960,6 +975,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->health <= 0 || thing->health <= 0)
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
|| thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD
|| thing->type == MT_BOMBITEM
@ -1043,6 +1061,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->health <= 0 || thing->health <= 0)
return true;
if (thing->player && thing->player->powers[pw_flashing])
return true;
if (thing->type == MT_PLAYER)
{
P_KillMobj(tmthing, thing, thing);
@ -1087,6 +1108,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->z + tmthing->height < thing->z)
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
|| 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
@ -1534,7 +1559,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
}
// 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)
{
@ -1546,7 +1572,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true);
thing->player->pflags &= ~PF_CARRIED;
}
}*/
if (thing->player)
{
@ -1592,6 +1618,87 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& tmthing->z <= thing->z + thing->height)
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?
else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
&& 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))
{
//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)
{
@ -3522,7 +3629,7 @@ stairstep:
//
// 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;
INT16 hitcount = 0;
@ -3600,7 +3707,7 @@ retry:
PT_ADDLINES, PTR_SlideTraverse);
// 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);
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?
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.
player->powers[pw_flashing] = flashingtics-1;
P_DoPityCheck(player);
player->powers[pw_flashing] = K_GetKartFlashing()-1;
//P_DoPityCheck(player);
}
// 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
P_PlayerFlip(mo);
if (mo->player->kartstuff[k_feather] & 2)
gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2);
}
else
{
@ -1378,6 +1380,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
break;
case MT_WATERDROP:
gravityadd >>= 1;
case MT_BANANAITEM:
case MT_FAKEITEM:
case MT_BOMBITEM:
gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2);
default:
break;
}
@ -1809,7 +1815,7 @@ void P_XYMovement(mobj_t *mo)
}
else if (player || mo->flags & (MF_SLIDEME|MF_PUSHABLE))
{ // try to slide along it
P_SlideMove(mo);
P_SlideMove(mo, false);
xmove = ymove = 0;
}
else if (mo->type == MT_SPINFIRE)
@ -1990,7 +1996,7 @@ static void P_RingXYMovement(mobj_t *mo)
I_Assert(!P_MobjWasRemoved(mo));
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)
@ -2004,7 +2010,7 @@ static void P_SceneryXYMovement(mobj_t *mo)
oldy = mo->y;
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))
return; // no friction when airborne
@ -2299,6 +2305,14 @@ static boolean P_ZMovement(mobj_t *mo)
case MT_BIGTUMBLEWEED:
case MT_LITTLETUMBLEWEED:
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.
if (P_CheckDeathPitCollide(mo))
{
@ -2325,13 +2339,6 @@ static boolean P_ZMovement(mobj_t *mo)
case MT_FLINGCOIN:
case MT_FLINGRANDOMITEM:
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.
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)))
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;
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)
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
source->angle = R_PointToAngle2(source->x, source->y, tx, ty);
@ -6452,19 +6468,30 @@ void P_MobjThinker(mobj_t *mobj)
//{ SRB2kart mobs
case MT_DRIFT:
{
fixed_t dsone = 26*4 + mobj->target->player->kartspeed*2 + (9 - mobj->target->player->kartweight);
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))
if (mobj->target && mobj->target->player && mobj->target->player->mo && mobj->target->player->health > 0 && !mobj->target->player->spectator)
{
UINT8 kartspeed = mobj->target->player->kartspeed;
fixed_t dsone, dstwo;
INT32 HEIGHT;
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]))
|| (!(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)
mobj->flags2 |= MF2_DONTDRAW;
@ -6474,13 +6501,13 @@ void P_MobjThinker(mobj_t *mobj)
else
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;
}
// 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
if (mobj->target->player && mobj->type == MT_DRIFT
@ -6489,7 +6516,8 @@ void P_MobjThinker(mobj_t *mobj)
P_SetMobjStateNF(mobj, S_DRIFTSPARK4);
// 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 (mobj->target->player && mobj->target->eflags & MFE_VERTICALFLIP)
@ -6504,8 +6532,7 @@ void P_MobjThinker(mobj_t *mobj)
}
// Shrink if the player shrunk too.
if (mobj->target->player)
mobj->scale = mobj->target->scale;
mobj->scale = mobj->target->scale;
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
&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
{
INT32 zfixds = 56;
INT32 DIST = FixedMul(zfixds, mobj->target->scale);
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;
fixed_t z;
const fixed_t radius = FixedHypot(mobj->target->radius, mobj->target->radius) + FixedHypot(mobj->radius, mobj->radius); // mobj's distance from its Target, or Radius.
//mobj->angle += FixedAngle(12*FRACUNIT); // mobj's actual speed.
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)
{
mobj->eflags |= MFE_VERTICALFLIP;
HEIGHT = mobj->target->height / 2;
}
else
{
mobj->eflags &= ~MFE_VERTICALFLIP;
HEIGHT = mobj->target->height / 5;
}
// Shrink your items if the player shrunk too.
if (mobj->target->player)
mobj->scale = mobj->target->scale;
P_UnsetThingPosition(mobj);
if (P_MobjFlip(mobj) > 0)
{
const angle_t fa = mobj->angle>>ANGLETOFINESHIFT;
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);
z = mobj->target->z;
}
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?
if ((mobj->type == MT_GREENSHIELD && !(mobj->target->player->kartstuff[k_greenshell] & 1))
@ -6615,6 +6660,163 @@ void P_MobjThinker(mobj_t *mobj)
return;
}
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:
P_SceneryCheckWater(mobj);
@ -7486,15 +7688,16 @@ void P_MobjThinker(mobj_t *mobj)
break;
case MT_GREENITEM:
{
sector_t *sec2;
fixed_t finalspeed = mobj->info->speed;
P_SpawnGhostMobj(mobj);
if (cv_kartcc.value == 50)
if (K_GetKartCC() == 50)
{
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
}
else if (cv_kartcc.value == 150)
else if (K_GetKartCC() == 150)
{
finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4);
}
@ -7513,14 +7716,23 @@ void P_MobjThinker(mobj_t *mobj)
{
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)
mobj->threshold--;
if (leveltime % 6 == 0)
S_StartSound(mobj, mobj->info->activesound);
break;
}
case MT_REDITEM:
{
sector_t *sec2;
fixed_t topspeed = 64*FRACUNIT;
fixed_t distbarrier = 512*FRACUNIT;
fixed_t distaway;
@ -7532,18 +7744,18 @@ void P_MobjThinker(mobj_t *mobj)
if (leveltime % 7 == 0)
S_StartSound(mobj, mobj->info->activesound);
if (cv_kartcc.value == 50)
if (K_GetKartCC() == 50)
{
topspeed = FixedMul(topspeed, 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);
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);
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);
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;
}
case MT_REDITEMDUD:
{
sector_t *sec2;
P_SpawnGhostMobj(mobj);
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->x+mobj->momx, mobj->y+mobj->momy);
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)
mobj->threshold--;
if (leveltime % 7 == 0)
S_StartSound(mobj, mobj->info->activesound);
break;
}
case MT_BANANAITEM:
case MT_FAKEITEM:
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->scalespeed = FRACUNIT/12;
// TODO: Make this a special map header
if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN))
mobj->destscale = FRACUNIT/2;
if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->mobj_scale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
// set subsector and/or block links
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_BLUEBALL:
nummaprings++;
break;
default:
break;
}
@ -8401,10 +8642,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_GREENITEM: case MT_GREENSHIELD:
case MT_TRIPLEGREENSHIELD1: case MT_TRIPLEGREENSHIELD2: case MT_TRIPLEGREENSHIELD3:
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_BOMBITEM: case MT_BOMBSHIELD:
case MT_FIREBALL:
P_SpawnShadowMobj(mobj);
default:
break;
@ -8494,9 +8735,8 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
mobj->destscale = mobj->scale;
mobj->scalespeed = FRACUNIT/12;
// TODO: Make this a special map header
if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN))
mobj->destscale = FRACUNIT/2;
if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->mobj_scale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
// set subsector and/or block links
P_SetThingPosition(mobj);
@ -8978,6 +9218,12 @@ void P_RespawnSpecials(void)
mobj_t *mo = NULL;
mapthing_t *mthing = NULL;
if (gametype != GT_RACE) // Battle Mode vers
{
P_RespawnBattleSpecials();
return;
}
// only respawn items when cv_itemrespawn is on
if (!cv_itemrespawn.value)
return;
@ -9059,6 +9305,97 @@ void P_RespawnSpecials(void)
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
// Called when a player is spawned on the level.
@ -9068,6 +9405,7 @@ void P_SpawnPlayer(INT32 playernum)
{
player_t *p = &players[playernum];
mobj_t *mobj;
mobj_t *overheadarrow;
if (p->playerstate == PST_REBORN)
G_PlayerReborn(playernum);
@ -9077,13 +9415,13 @@ void P_SpawnPlayer(INT32 playernum)
{
// Special case for (NiGHTS) special stages!
// 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;
else
else*/
p->spectator = false;
}
else if (netgame && p->jointime < 1)
p->spectator = true;
/*p->spectator = true*/;
else if (multiplayer && !netgame)
{
// 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
// 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)

View file

@ -138,8 +138,6 @@ static void P_NetArchivePlayers(void)
WRITEUINT16(save_p, players[i].powers[j]);
for (j = 0; j < NUMKARTSTUFF; 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);
@ -323,8 +321,6 @@ static void P_NetUnArchivePlayers(void)
players[i].powers[j] = READUINT16(save_p);
for (j = 0; j < NUMKARTSTUFF; j++)
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);

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.");
}
#define NUMLAPS_DEFAULT 4
#define NUMLAPS_DEFAULT 3
/** 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);
mapheaderinfo[num]->levelflags = 0;
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)
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
mapheaderinfo[num]->customopts = NULL;
mapheaderinfo[num]->numCustomOptions = 0;
@ -983,6 +988,9 @@ static void P_LoadThings(void)
|| mt->type == 1702) // MT_AXISTRANSFERLINE
continue; // These were already spawned
if (mt->type == 2000) // MT_RANDOMITEM
nummapboxes++;
mt->mobj = NULL;
P_SpawnMapThing(mt);
}
@ -2154,6 +2162,8 @@ static void P_LevelInitStuff(void)
tokenbits = 0;
runemeraldmanager = false;
nummaprings = 0;
nummapboxes = 0;
numgotboxes = 0;
// emerald hunt
hunt1 = hunt2 = hunt3 = NULL;
@ -2451,11 +2461,11 @@ static void P_LoadRecordGhosts(void)
if (cv_ghost_staff.value)
{
lumpnum_t l;
UINT8 i = 1;
while (i <= 99 && (l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(gamemap),i))) != LUMPERROR)
UINT8 j = 1;
while (j <= 99 && (l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(gamemap),j))) != LUMPERROR)
{
G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),i));
i++;
G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),j));
j++;
}
}
@ -2566,8 +2576,7 @@ boolean P_SetupLevel(boolean skipprecip)
// chasecam on in chaos, race, coop
// chasecam off in match, tag, capture the flag
chase = (gametype == GT_RACE || gametype == GT_COMPETITION || gametype == GT_COOP)
|| (maptol & TOL_2D);
chase = true; // srb2kart: always on
if (!dedicated)
{

View file

@ -3728,7 +3728,20 @@ DoneSection2:
// Process Section 3
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 3: // Unused (was "Ice/Sludge and Wind/Current")
case 4: // Conveyor Belt
@ -3878,7 +3891,7 @@ DoneSection2:
mo->spawnpoint = bflagpoint;
mo->flags2 |= MF2_JUSTATTACKED;
redscore += 1;
P_AddPlayerScore(player, 250);
P_AddPlayerScore(player, 5);
}
}
break;
@ -3911,7 +3924,7 @@ DoneSection2:
mo->spawnpoint = rflagpoint;
mo->flags2 |= MF2_JUSTATTACKED;
bluescore += 1;
P_AddPlayerScore(player, 250);
P_AddPlayerScore(player, 5);
}
}
break;
@ -3928,20 +3941,22 @@ DoneSection2:
break;
case 6: // SRB2kart 190117 - Mushroom Boost Panel
if (!P_IsObjectOnGround(player->mo))
break;
if (!player->kartstuff[k_floorboost])
player->kartstuff[k_floorboost] = 3;
else
player->kartstuff[k_floorboost] = 2;
K_DoMushroom(player, false, false);
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
{
if (!player->kartstuff[k_floorboost])
player->kartstuff[k_floorboost] = 3;
else
player->kartstuff[k_floorboost] = 2;
K_DoMushroom(player, false, false);
}
break;
case 7: // SRB2kart 190117 - Oil Slick
if (!P_IsObjectOnGround(player->mo))
break;
player->kartstuff[k_spinouttype] = -1;
K_SpinPlayer(player, NULL);
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
{
player->kartstuff[k_spinouttype] = -1;
K_SpinPlayer(player, NULL);
}
break;
case 8: // Zoom Tube Start
@ -4099,12 +4114,12 @@ DoneSection2:
case 10: // Finish Line
// 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;
//
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->kartstuff[k_lapanimation] = 80;
@ -4123,6 +4138,7 @@ DoneSection2:
// SRB2kart 200117
player->starpostangle = player->starpostnum = 0;
player->starpostx = player->starposty = player->starpostz = 0;
player->starpostcount = 0;
//except the time!
player->starposttime = player->realtime;
@ -7140,7 +7156,7 @@ void T_Friction(friction_t *f)
// friction works for all mobj's
// (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
&& (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)))
{
if (f->roverfriction)
@ -7537,7 +7553,7 @@ void T_Pusher(pusher_t *p)
if (thing->player && thing->player->pflags & PF_ROPEHANG)
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;
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))
P_PlayerAfterThink(&players[i]);
// SRB2kart - runs bounce collision for players
K_KartBouncer();
#ifdef HAVE_BLUA
LUAh_ThinkFrame();
#endif
@ -743,9 +740,6 @@ void P_PreTicker(INT32 frames)
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
P_PlayerAfterThink(&players[i]);
// SRB2kart - runs bounce collision for players
K_KartBouncer();
#ifdef HAVE_BLUA
LUAh_ThinkFrame();
#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.
// 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)
// player->score -= 50;
//else
// player->score = 0;
}
if (player->score >= 50)
player->score -= 50;
else
player->score = 0;
}*/
P_ResetPlayer(player);
P_SetPlayerMobjState(player->mo, player->mo->info->painstate);
player->powers[pw_flashing] = flashingtics;
player->powers[pw_flashing] = K_GetKartFlashing();
if (player->timeshit != UINT8_MAX)
++player->timeshit;
@ -1007,12 +1007,12 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
{
UINT32 oldscore;
return; // SRB2kart - no score.
// This will probably be temporary until we do battle modes?
if (player->bot)
player = &players[consoleplayer];
if (player->exiting) // srb2kart
return;
// NiGHTS does it different!
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;
}
//
// 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
//
@ -1607,9 +1637,7 @@ void P_DoPlayerExit(player_t *player)
if (player->exiting)
return;
if (cv_allowexitlevel.value == 0 && !G_PlatformGametype())
return;
else if (gametype == GT_RACE || gametype == GT_COMPETITION) // If in Race Mode, allow
if (gametype == GT_RACE || gametype == GT_COMPETITION) // If in Race Mode, allow
{
// SRB2kart 120217
if (!countdown && !(netgame || multiplayer))
@ -1652,6 +1680,8 @@ void P_DoPlayerExit(player_t *player)
if (P_CheckRacers())
player->exiting = (14*TICRATE)/5 + 1;
}
else if (gametype != GT_RACE)
player->exiting = 8*TICRATE + 1; // Battle Mode exiting
else
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_spacetime] = 0;
player->kartstuff[k_cardanimation] = 0; // srb2kart: reset battle animation
P_RestoreMusic(player);
if (playeringame[player-players] && netgame && !circuitmap)
CONS_Printf(M_GetText("%s has completed the level.\n"), player_names[player-players]);
/*if (playeringame[player-players] && netgame && !circuitmap)
CONS_Printf(M_GetText("%s has completed the level.\n"), player_names[player-players]);*/
}
#define SPACESPECIAL 12
@ -3557,7 +3588,7 @@ static void P_DoSuperStuff(player_t *player)
}
if (gametype != GT_COOP)
player->powers[pw_flashing] = flashingtics-1;
player->powers[pw_flashing] = K_GetKartFlashing(player)-1;
/*
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.
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;
// Set the player speeds.
@ -4833,7 +4868,7 @@ static void P_3dMovement(player_t *player)
P_Thrust(player->mo, movepushangle, movepushforward);
#endif
}
else if (!player->kartstuff[k_spinouttimer])
else if (!(player->kartstuff[k_spinouttimer]))
{
K_MomentumToFacing(player);
}
@ -5842,7 +5877,7 @@ static void P_NiGHTSMovement(player_t *player)
}
// 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;
@ -6499,7 +6534,7 @@ static void P_MovePlayer(player_t *player)
*/
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...
// (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);
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.
// 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
// SRB2kart - spawn automatically after 1.5 seconds
if (player->deadtimer > (TICRATE + TICRATE/2) && (gametype == GT_RACE || player->spectator))
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))
// SRB2kart - spawn automatically after 1 second
if (player->deadtimer > TICRATE)
player->playerstate = PST_REBORN;
// 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))
{
if (leveltime >= 4*TICRATE)
player->realtime = leveltime - 4*TICRATE;
else
player->realtime = 0;
}
if ((gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame))) && (player->lives <= 0))
{
// Keep time rolling in race mode
if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_TIMEOVER))
{
if (gametype == GT_RACE || gametype == GT_COMPETITION)
{
if (leveltime >= 4*TICRATE)
player->realtime = leveltime - 4*TICRATE;
else
player->realtime = 0;
}
else
player->realtime = leveltime;
}
// Return to level music
if (player->lives <= 0)
if (netgame)
{
if (netgame)
{
if (player->deadtimer == gameovertics && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusname, mapmusflags, true);
}
else if (multiplayer) // local multiplayer only
{
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
else if (player == &players[displayplayer] && players[secondarydisplayplayer].lives > 0)
P_RestoreMusic(&players[secondarydisplayplayer]);
else if (player == &players[secondarydisplayplayer] && players[displayplayer].lives > 0)
P_RestoreMusic(&players[displayplayer]);
}
if (player->deadtimer == gameovertics && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusname, mapmusflags, true);
}
else if (multiplayer) // local multiplayer only
{
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
else if (player == &players[displayplayer] && players[secondarydisplayplayer].lives > 0)
P_RestoreMusic(&players[secondarydisplayplayer]);
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).
if (!(multiplayer || netgame) && !splitscreen)
/*if (!(multiplayer || netgame) && !splitscreen)
{
fixed_t vx = 0, vy = 0;
if (player->awayviewtics) {
@ -8726,7 +8750,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
player->mo->flags2 &= ~MF2_SHADOW;
}
else
player->mo->flags2 &= ~MF2_SHADOW;
player->mo->flags2 &= ~MF2_SHADOW;*/
/* if (!resetcalled && (player->pflags & PF_NIGHTSMODE && player->exiting))
{
@ -8967,9 +8991,12 @@ static void P_CalcPostImg(player_t *player)
*param = 5;
}
#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.
if (player->spectator
@ -8986,7 +9013,7 @@ void P_DoPityCheck(player_t *player)
player->powers[pw_shield] = SH_PITY;
P_SpawnShieldOrb(player);
}
}
}*/
//
// P_PlayerThink
@ -9131,7 +9158,7 @@ void P_PlayerThink(player_t *player)
// If it is set, start subtracting
// 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--;
if (player->exiting && countdown2)
@ -9214,7 +9241,7 @@ void P_PlayerThink(player_t *player)
playerdeadview = false;
// SRB2kart 010217
if (gametype == GT_RACE && leveltime < 4*TICRATE)
if (leveltime < 4*TICRATE)
player->powers[pw_nocontrol] = 2;
/*
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.
if (!player->exiting)
{
if (gametype == GT_RACE || gametype == GT_COMPETITION)
{
if (leveltime >= 4*TICRATE)
player->realtime = leveltime - 4*TICRATE;
else
player->realtime = 0;
}
if (leveltime >= 4*TICRATE)
player->realtime = leveltime - 4*TICRATE;
else
player->realtime = leveltime;
player->realtime = 0;
}
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)
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]--;
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.
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;
else
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);
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
if (x2 < 0)
@ -2582,7 +2582,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname)
if (P_IsLocalPlayer(player))
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);
SetPlayerSkinByNum(playernum, 0);
@ -2651,7 +2651,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
if (P_IsLocalPlayer(player))
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);
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
}

View file

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

View file

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

View file

@ -444,6 +444,9 @@
<ClInclude Include="sdlmain.h">
<Filter>SDLApp</Filter>
</ClInclude>
<ClInclude Include="..\k_kart.h">
<Filter>D_Doom</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\tmap.nas">
@ -876,6 +879,9 @@
<ClCompile Include="SDL_main\SDL_windows_main.c">
<Filter>SDLApp</Filter>
</ClCompile>
<ClCompile Include="..\k_kart.c">
<Filter>D_Doom</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<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},
{"mkitm8", 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},
{"tossed", false,150, 8, -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},
{"clash", false, 64, 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},
{"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
{"kwin", false, 64, 0, -1, NULL, 0, SKSWIN, -1, LUMPERROR},

View file

@ -574,6 +574,8 @@ typedef enum
sfx_tossed,
sfx_shelit,
sfx_vroom,
sfx_boing,
sfx_smkinv,
sfx_kwin,
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(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;
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"));
else
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Jump to respawn."));
}
}*/
else if (stplyr->spectator
#ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_textspectator)

View file

@ -2121,6 +2121,21 @@ Unoptimized version
heatindex[view]++;
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.width*vid.bpp, height, vid.width*vid.bpp, vid.width);
}