mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2025-01-09 11:21:24 +00:00
Merge branch 'master' of git.magicalgirl.moe:KartKrew/Kart-Public into followme
This commit is contained in:
commit
16004e5ba9
51 changed files with 9395 additions and 9104 deletions
|
@ -129,7 +129,7 @@ Oni: Sev, Sal, and toast were the most unexpected things to ever happen to this
|
||||||
|
|
||||||
[Oni wiping sweat off his brow] Things only got more drastically revamped… very very rapidly.
|
[Oni wiping sweat off his brow] Things only got more drastically revamped… very very rapidly.
|
||||||
|
|
||||||
The Mario aesthetic was entirely tossed out, as Sal was willing to work with me night and day on redoing most of everything about items… and then sounds. My power level for sprites massively jumped during TD development, so I decided to take it upon myself to do almost everything. They’re such friendly and cooperative coders that I can’t help but push a little harder than I used to (I was WAY lazier before they got here) to keep up.
|
The Mario aesthetic was entirely tossed out, as Sal was willing to work with me night and day on redoing most of everything about items… and then sounds. My power level for sprites massively jumped during TD development, so I decided to take it upon myself to do almost everything. They’re such friendly and cooperative coders that I can’t help but push a little harder than I used to (I was WAY lazier before they got here) to keep up.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
* Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb
|
* Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb
|
||||||
* Last updated 2018 / 12 / 23 - SRB2 v2.1.22 - patch.dta
|
* Last updated 2018 / 12 / 23 - SRB2 v2.1.22 - patch.dta
|
||||||
* Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets
|
* Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets
|
||||||
* Last updated 2019 / 01 / 15 - Kart v1.0.2 - patch.kart
|
* Last updated 2019 / 02 / 04 - Kart v1.0.3 - patch.kart
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Base SRB2 hashes
|
// Base SRB2 hashes
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
#define ASSET_HASH_CHARS_KART "e2c428347dde52858a3dacd29fc5b964"
|
#define ASSET_HASH_CHARS_KART "e2c428347dde52858a3dacd29fc5b964"
|
||||||
#define ASSET_HASH_MAPS_KART "1335cd064656aedca359cfbb5233ac4a"
|
#define ASSET_HASH_MAPS_KART "1335cd064656aedca359cfbb5233ac4a"
|
||||||
#ifdef USE_PATCH_KART
|
#ifdef USE_PATCH_KART
|
||||||
#define ASSET_HASH_PATCH_KART "899aee1b63e731b7e2098406c85608b4"
|
#define ASSET_HASH_PATCH_KART "e06c1c90e5645c886026311964f8e1f5"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
112
src/d_clisrv.c
112
src/d_clisrv.c
|
@ -4083,6 +4083,21 @@ FILESTAMP
|
||||||
else if (resynch_score[node])
|
else if (resynch_score[node])
|
||||||
--resynch_score[node];
|
--resynch_score[node];
|
||||||
break;
|
break;
|
||||||
|
case PT_BASICKEEPALIVE:
|
||||||
|
if (client)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// This should probably still timeout though, as the node should always have a player 1 number
|
||||||
|
if (netconsole == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// If a client sends this it should mean they are done receiving the savegame
|
||||||
|
sendingsavegame[node] = false;
|
||||||
|
|
||||||
|
// As long as clients send keep alives, the server can keep running, so reset the timeout
|
||||||
|
/// \todo Use a separate cvar for that kind of timeout?
|
||||||
|
freezetimeout[node] = I_GetTime() + connectiontimeout;
|
||||||
|
break;
|
||||||
case PT_TEXTCMD:
|
case PT_TEXTCMD:
|
||||||
case PT_TEXTCMD2:
|
case PT_TEXTCMD2:
|
||||||
case PT_TEXTCMD3:
|
case PT_TEXTCMD3:
|
||||||
|
@ -4586,6 +4601,15 @@ static INT16 Consistancy(void)
|
||||||
return (INT16)(ret & 0xFFFF);
|
return (INT16)(ret & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// confusing, but this DOESN'T send PT_NODEKEEPALIVE, it sends PT_BASICKEEPALIVE
|
||||||
|
// used during wipes to tell the server that a node is still connected
|
||||||
|
static void CL_SendClientKeepAlive(void)
|
||||||
|
{
|
||||||
|
netbuffer->packettype = PT_BASICKEEPALIVE;
|
||||||
|
|
||||||
|
HSendPacket(servernode, false, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// send the client packet to the server
|
// send the client packet to the server
|
||||||
static void CL_SendClientCmd(void)
|
static void CL_SendClientCmd(void)
|
||||||
{
|
{
|
||||||
|
@ -5032,9 +5056,77 @@ static inline void PingUpdate(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static tic_t gametime = 0;
|
||||||
|
|
||||||
|
#ifdef NEWPING
|
||||||
|
static void UpdatePingTable(void)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
if (server)
|
||||||
|
{
|
||||||
|
if (netgame && !(gametime % 255))
|
||||||
|
PingUpdate();
|
||||||
|
// update node latency values so we can take an average later.
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
if (playeringame[i])
|
||||||
|
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
||||||
|
pingmeasurecount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Handle timeouts to prevent definitive freezes from happenning
|
||||||
|
static void HandleNodeTimeouts(void)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
if (server)
|
||||||
|
for (i = 1; i < MAXNETNODES; i++)
|
||||||
|
if (nodeingame[i] && freezetimeout[i] < I_GetTime())
|
||||||
|
Net_ConnectionTimeout(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep the network alive while not advancing tics!
|
||||||
|
void NetKeepAlive(void)
|
||||||
|
{
|
||||||
|
tic_t nowtime;
|
||||||
|
INT32 realtics;
|
||||||
|
|
||||||
|
nowtime = I_GetTime();
|
||||||
|
realtics = nowtime - gametime;
|
||||||
|
|
||||||
|
// return if there's no time passed since the last call
|
||||||
|
if (realtics <= 0) // nothing new to update
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef NEWPING
|
||||||
|
UpdatePingTable();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (server)
|
||||||
|
CL_SendClientKeepAlive();
|
||||||
|
|
||||||
|
// Sryder: What is FILESTAMP???
|
||||||
|
FILESTAMP
|
||||||
|
GetPackets();
|
||||||
|
FILESTAMP
|
||||||
|
|
||||||
|
MasterClient_Ticker();
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
// send keep alive
|
||||||
|
CL_SendClientKeepAlive();
|
||||||
|
// No need to check for resynch because we aren't running any tics
|
||||||
|
}
|
||||||
|
// No else because no tics are being run and we can't resynch during this
|
||||||
|
|
||||||
|
Net_AckTicker();
|
||||||
|
HandleNodeTimeouts();
|
||||||
|
SV_FileSendTicker();
|
||||||
|
}
|
||||||
|
|
||||||
void NetUpdate(void)
|
void NetUpdate(void)
|
||||||
{
|
{
|
||||||
static tic_t gametime = 0;
|
|
||||||
static tic_t resptime = 0;
|
static tic_t resptime = 0;
|
||||||
tic_t nowtime;
|
tic_t nowtime;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
@ -5056,16 +5148,7 @@ void NetUpdate(void)
|
||||||
gametime = nowtime;
|
gametime = nowtime;
|
||||||
|
|
||||||
#ifdef NEWPING
|
#ifdef NEWPING
|
||||||
if (server)
|
UpdatePingTable();
|
||||||
{
|
|
||||||
if (netgame && !(gametime % 255))
|
|
||||||
PingUpdate();
|
|
||||||
// update node latency values so we can take an average later.
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
if (playeringame[i])
|
|
||||||
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
|
||||||
pingmeasurecount++;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (client)
|
if (client)
|
||||||
|
@ -5133,12 +5216,7 @@ FILESTAMP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Net_AckTicker();
|
Net_AckTicker();
|
||||||
// Handle timeouts to prevent definitive freezes from happenning
|
HandleNodeTimeouts();
|
||||||
if (server)
|
|
||||||
for (i = 1; i < MAXNETNODES; i++)
|
|
||||||
if (nodeingame[i] && freezetimeout[i] < I_GetTime())
|
|
||||||
Net_ConnectionTimeout(i);
|
|
||||||
nowtime /= NEWTICRATERATIO;
|
|
||||||
if (nowtime > resptime)
|
if (nowtime > resptime)
|
||||||
{
|
{
|
||||||
resptime = nowtime;
|
resptime = nowtime;
|
||||||
|
|
|
@ -71,6 +71,7 @@ typedef enum
|
||||||
PT_CLIENT3MIS,
|
PT_CLIENT3MIS,
|
||||||
PT_CLIENT4CMD, // 4P
|
PT_CLIENT4CMD, // 4P
|
||||||
PT_CLIENT4MIS,
|
PT_CLIENT4MIS,
|
||||||
|
PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
|
||||||
|
|
||||||
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
|
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
|
||||||
// allows HSendPacket(*, true, *, *) to return false.
|
// allows HSendPacket(*, true, *, *) to return false.
|
||||||
|
@ -538,6 +539,7 @@ void SendNetXCmd3(netxcmd_t id, const void *param, size_t nparam); // splitsreen
|
||||||
void SendNetXCmd4(netxcmd_t id, const void *param, size_t nparam); // splitsreen4 player
|
void SendNetXCmd4(netxcmd_t id, const void *param, size_t nparam); // splitsreen4 player
|
||||||
|
|
||||||
// Create any new ticcmds and broadcast to other players.
|
// Create any new ticcmds and broadcast to other players.
|
||||||
|
void NetKeepAlive(void);
|
||||||
void NetUpdate(void);
|
void NetUpdate(void);
|
||||||
|
|
||||||
void SV_StartSinglePlayerServer(void);
|
void SV_StartSinglePlayerServer(void);
|
||||||
|
|
|
@ -1162,7 +1162,7 @@ void D_SRB2Main(void)
|
||||||
if (s) // Check for NULL?
|
if (s) // Check for NULL?
|
||||||
{
|
{
|
||||||
if (!W_VerifyNMUSlumps(s))
|
if (!W_VerifyNMUSlumps(s))
|
||||||
G_SetGameModified(true);
|
G_SetGameModified(true, false);
|
||||||
D_AddFile(s);
|
D_AddFile(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1189,7 +1189,7 @@ void D_SRB2Main(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!M_CheckParm("-server"))
|
if (!M_CheckParm("-server"))
|
||||||
G_SetGameModified(true);
|
G_SetGameModified(true, true);
|
||||||
autostart = true;
|
autostart = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -903,6 +903,9 @@ static void DebugPrintpacket(const char *header)
|
||||||
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic),
|
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic),
|
||||||
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom));
|
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom));
|
||||||
break;
|
break;
|
||||||
|
case PT_BASICKEEPALIVE:
|
||||||
|
fprintf(debugfile, " keep alive\n");
|
||||||
|
break;
|
||||||
case PT_TEXTCMD:
|
case PT_TEXTCMD:
|
||||||
case PT_TEXTCMD2:
|
case PT_TEXTCMD2:
|
||||||
case PT_TEXTCMD3:
|
case PT_TEXTCMD3:
|
||||||
|
|
|
@ -236,6 +236,9 @@ static consvar_t cv_dummyconsvar = {"dummyconsvar", "Off", CV_CALL|CV_NOSHOWHELP
|
||||||
consvar_t cv_restrictskinchange = {"restrictskinchange", "No", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_restrictskinchange = {"restrictskinchange", "No", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_allowteamchange = {"allowteamchange", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_allowteamchange = {"allowteamchange", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
static CV_PossibleValue_t ingamecap_cons_t[] = {{0, "MIN"}, {MAXPLAYERS-1, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_ingamecap = {"ingamecap", "0", CV_NETVAR, ingamecap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, startingliveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, startingliveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
|
||||||
|
@ -642,6 +645,7 @@ void D_RegisterServerCommands(void)
|
||||||
CV_RegisterVar(&cv_allowexitlevel);
|
CV_RegisterVar(&cv_allowexitlevel);
|
||||||
CV_RegisterVar(&cv_restrictskinchange);
|
CV_RegisterVar(&cv_restrictskinchange);
|
||||||
CV_RegisterVar(&cv_allowteamchange);
|
CV_RegisterVar(&cv_allowteamchange);
|
||||||
|
CV_RegisterVar(&cv_ingamecap);
|
||||||
CV_RegisterVar(&cv_respawntime);
|
CV_RegisterVar(&cv_respawntime);
|
||||||
CV_RegisterVar(&cv_killingdead);
|
CV_RegisterVar(&cv_killingdead);
|
||||||
|
|
||||||
|
@ -2209,10 +2213,12 @@ static void Command_Map_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(netgame || multiplayer) && (!modifiedgame || savemoddata))
|
if (!(netgame || multiplayer) && !majormods)
|
||||||
{
|
{
|
||||||
if (COM_CheckParm("-force"))
|
if (COM_CheckParm("-force"))
|
||||||
G_SetGameModified(false);
|
{
|
||||||
|
G_SetGameModified(false, true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n"));
|
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n"));
|
||||||
|
@ -2496,6 +2502,12 @@ static void Command_Respawn(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (players[consoleplayer].mo && !P_IsObjectOnGround(players[consoleplayer].mo)) // KART: Nice try, but no, you won't be cheesing spb anymore.
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("You must be on the floor to use this.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*if (!G_RaceGametype()) // srb2kart: not necessary, respawning makes you lose a bumper in battle, so it's not desirable to use as a way to escape a hit
|
/*if (!G_RaceGametype()) // srb2kart: not necessary, respawning makes you lose a bumper in battle, so it's not desirable to use as a way to escape a hit
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("You may only use this in co-op, race, and competition!\n"));
|
CONS_Printf(M_GetText("You may only use this in co-op, race, and competition!\n"));
|
||||||
|
@ -2517,7 +2529,7 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
INT32 respawnplayer = READINT32(*cp);
|
INT32 respawnplayer = READINT32(*cp);
|
||||||
|
|
||||||
// You can't respawn someone else. Nice try, there.
|
// You can't respawn someone else. Nice try, there.
|
||||||
if (respawnplayer != playernum) // srb2kart: "|| (!G_RaceGametype())"
|
if (respawnplayer != playernum) // srb2kart: "|| (!G_RaceGametype())"
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal respawn command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal respawn command received from %s\n"), player_names[playernum]);
|
||||||
|
@ -2532,6 +2544,10 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// incase the above checks were modified to allow sending a respawn on these occasions:
|
||||||
|
if (players[respawnplayer].mo && !P_IsObjectOnGround(players[respawnplayer].mo))
|
||||||
|
return;
|
||||||
|
|
||||||
if (players[respawnplayer].mo)
|
if (players[respawnplayer].mo)
|
||||||
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 10000);
|
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 10000);
|
||||||
}
|
}
|
||||||
|
@ -3781,7 +3797,7 @@ static void Command_RunSOC(void)
|
||||||
if (!P_RunSOC(fn))
|
if (!P_RunSOC(fn))
|
||||||
CONS_Printf(M_GetText("Could not find SOC.\n"));
|
CONS_Printf(M_GetText("Could not find SOC.\n"));
|
||||||
else
|
else
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3835,7 +3851,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
|
||||||
}
|
}
|
||||||
|
|
||||||
P_RunSOC(filename);
|
P_RunSOC(filename);
|
||||||
G_SetGameModified(true);
|
G_SetGameModified(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a pwad at runtime.
|
/** Adds a pwad at runtime.
|
||||||
|
@ -3872,7 +3888,7 @@ static void Command_Addfile(void)
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add file on your client directly if it is trivial, or you aren't in a netgame.
|
// Add file on your client directly if it is trivial, or you aren't in a netgame.
|
||||||
|
@ -4118,7 +4134,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_SetGameModified(true);
|
G_SetGameModified(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Command_ListWADS_f(void)
|
static void Command_ListWADS_f(void)
|
||||||
|
@ -4475,7 +4491,7 @@ static void Ringslinger_OnChange(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cv_ringslinger.value) // Only if it's been turned on
|
if (cv_ringslinger.value) // Only if it's been turned on
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Gravity_OnChange(void)
|
static void Gravity_OnChange(void)
|
||||||
|
@ -4496,7 +4512,7 @@ static void Gravity_OnChange(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!CV_IsSetToDefault(&cv_gravity))
|
if (!CV_IsSetToDefault(&cv_gravity))
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, true);
|
||||||
gravity = cv_gravity.value;
|
gravity = cv_gravity.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4892,7 +4908,7 @@ static void Fishcake_OnChange(void)
|
||||||
// so don't make modifiedgame always on!
|
// so don't make modifiedgame always on!
|
||||||
if (cv_debug)
|
if (cv_debug)
|
||||||
{
|
{
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cv_debug != cv_fishcake.value)
|
else if (cv_debug != cv_fishcake.value)
|
||||||
|
@ -4908,12 +4924,14 @@ static void Fishcake_OnChange(void)
|
||||||
*/
|
*/
|
||||||
static void Command_Isgamemodified_f(void)
|
static void Command_Isgamemodified_f(void)
|
||||||
{
|
{
|
||||||
if (savemoddata)
|
if (majormods)
|
||||||
CONS_Printf(M_GetText("modifiedgame is true, but you can save medal and record data in this mod.\n"));
|
CONS_Printf("The game has been modified with major add-ons, so you cannot play Record Attack.\n");
|
||||||
|
else if (savemoddata)
|
||||||
|
CONS_Printf("The game has been modified with an add-on with its own save data, so you can play Record Attack and earn medals.\n");
|
||||||
else if (modifiedgame)
|
else if (modifiedgame)
|
||||||
CONS_Printf(M_GetText("modifiedgame is true, extras will not be unlocked\n"));
|
CONS_Printf("The game has been modified with only minor add-ons. You can play Record Attack, earn medals and unlock extras.\n");
|
||||||
else
|
else
|
||||||
CONS_Printf(M_GetText("modifiedgame is false, you can unlock extras\n"));
|
CONS_Printf("The game has not been modified. You can play Record Attack, earn medals and unlock extras.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Command_Cheats_f(void)
|
static void Command_Cheats_f(void)
|
||||||
|
|
|
@ -93,7 +93,7 @@ extern consvar_t cv_mute;
|
||||||
extern consvar_t cv_killingdead;
|
extern consvar_t cv_killingdead;
|
||||||
extern consvar_t cv_pause;
|
extern consvar_t cv_pause;
|
||||||
|
|
||||||
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_respawntime;
|
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_ingamecap, cv_respawntime;
|
||||||
|
|
||||||
/*extern consvar_t cv_teleporters, cv_superring, cv_supersneakers, cv_invincibility;
|
/*extern consvar_t cv_teleporters, cv_superring, cv_supersneakers, cv_invincibility;
|
||||||
extern consvar_t cv_jumpshield, cv_watershield, cv_ringshield, cv_forceshield, cv_bombshield;
|
extern consvar_t cv_jumpshield, cv_watershield, cv_ringshield, cv_forceshield, cv_bombshield;
|
||||||
|
|
|
@ -426,7 +426,7 @@ void CL_LoadServerFiles(void)
|
||||||
else if (fileneeded[i].status == FS_FOUND)
|
else if (fileneeded[i].status == FS_FOUND)
|
||||||
{
|
{
|
||||||
P_AddWadFile(fileneeded[i].filename);
|
P_AddWadFile(fileneeded[i].filename);
|
||||||
G_SetGameModified(true);
|
G_SetGameModified(true, false);
|
||||||
fileneeded[i].status = FS_OPEN;
|
fileneeded[i].status = FS_OPEN;
|
||||||
}
|
}
|
||||||
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
||||||
|
|
|
@ -348,10 +348,12 @@ typedef enum
|
||||||
k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo
|
k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo
|
||||||
k_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly
|
k_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly
|
||||||
|
|
||||||
// v1.0.2 vars
|
// v1.0.2+ vars
|
||||||
k_itemblink, // Item flashing after roulette, prevents Hyudoro stealing AND serves as a mashing indicator
|
k_itemblink, // Item flashing after roulette, prevents Hyudoro stealing AND serves as a mashing indicator
|
||||||
k_itemblinkmode, // Type of flashing: 0 = white (normal), 1 = red (mashing), 2 = rainbow (enhanced items)
|
k_itemblinkmode, // Type of flashing: 0 = white (normal), 1 = red (mashing), 2 = rainbow (enhanced items)
|
||||||
k_getsparks, // Disable drift sparks at low speed, JUST enough to give acceleration the actual headstart above speed
|
k_getsparks, // Disable drift sparks at low speed, JUST enough to give acceleration the actual headstart above speed
|
||||||
|
k_jawztargetdelay, // Delay for Jawz target switching, to make it less twitchy
|
||||||
|
k_spectatewait, // How long have you been waiting as a spectator
|
||||||
|
|
||||||
NUMKARTSTUFF
|
NUMKARTSTUFF
|
||||||
} kartstufftype_t;
|
} kartstufftype_t;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
#include "m_menu.h"
|
#include "m_menu.h"
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
|
#include "filesrch.h" // for refreshdirmenu
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
#include "dehacked.h"
|
#include "dehacked.h"
|
||||||
#include "st_stuff.h"
|
#include "st_stuff.h"
|
||||||
|
@ -80,8 +81,6 @@ static powertype_t get_power(const char *word);
|
||||||
boolean deh_loaded = false;
|
boolean deh_loaded = false;
|
||||||
static int dbg_line;
|
static int dbg_line;
|
||||||
|
|
||||||
static boolean gamedataadded = false;
|
|
||||||
|
|
||||||
#ifdef DELFILE
|
#ifdef DELFILE
|
||||||
typedef struct undehacked_s
|
typedef struct undehacked_s
|
||||||
{
|
{
|
||||||
|
@ -603,6 +602,14 @@ done:
|
||||||
Z_Free(s);
|
Z_Free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int freeslotusage[2][2] = {{0, 0}, {0, 0}}; // [S_, MT_][max, previous .wad's max]
|
||||||
|
|
||||||
|
void DEH_UpdateMaxFreeslots(void)
|
||||||
|
{
|
||||||
|
freeslotusage[0][1] = freeslotusage[0][0];
|
||||||
|
freeslotusage[1][1] = freeslotusage[1][0];
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Figure out how to do undolines for this....
|
// TODO: Figure out how to do undolines for this....
|
||||||
// TODO: Warnings for running out of freeslots
|
// TODO: Warnings for running out of freeslots
|
||||||
static void readfreeslots(MYFILE *f)
|
static void readfreeslots(MYFILE *f)
|
||||||
|
@ -665,6 +672,7 @@ static void readfreeslots(MYFILE *f)
|
||||||
if (!FREE_STATES[i]) {
|
if (!FREE_STATES[i]) {
|
||||||
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
||||||
strcpy(FREE_STATES[i],word);
|
strcpy(FREE_STATES[i],word);
|
||||||
|
freeslotusage[0][0]++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -674,6 +682,7 @@ static void readfreeslots(MYFILE *f)
|
||||||
if (!FREE_MOBJS[i]) {
|
if (!FREE_MOBJS[i]) {
|
||||||
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
||||||
strcpy(FREE_MOBJS[i],word);
|
strcpy(FREE_MOBJS[i],word);
|
||||||
|
freeslotusage[1][0]++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3205,6 +3214,7 @@ static void readmaincfg(MYFILE *f)
|
||||||
strlcpy(gamedatafilename, word2, sizeof (gamedatafilename));
|
strlcpy(gamedatafilename, word2, sizeof (gamedatafilename));
|
||||||
strlwr(gamedatafilename);
|
strlwr(gamedatafilename);
|
||||||
savemoddata = true;
|
savemoddata = true;
|
||||||
|
majormods = false;
|
||||||
|
|
||||||
// Also save a time attack folder
|
// Also save a time attack folder
|
||||||
filenamelen = strlen(gamedatafilename)-4; // Strip off the extension
|
filenamelen = strlen(gamedatafilename)-4; // Strip off the extension
|
||||||
|
@ -3217,7 +3227,7 @@ static void readmaincfg(MYFILE *f)
|
||||||
// can't use sprintf since there is %u in savegamename
|
// can't use sprintf since there is %u in savegamename
|
||||||
strcatbf(savegamename, srb2home, PATHSEP);
|
strcatbf(savegamename, srb2home, PATHSEP);
|
||||||
|
|
||||||
gamedataadded = true;
|
refreshdirmenu |= REFRESHDIR_GAMEDATA;
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "RESETDATA"))
|
else if (fastcmp(word, "RESETDATA"))
|
||||||
{
|
{
|
||||||
|
@ -3448,8 +3458,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
for (i = 0; i < NUMSFX; i++)
|
for (i = 0; i < NUMSFX; i++)
|
||||||
savesfxnames[i] = S_sfx[i].name;
|
savesfxnames[i] = S_sfx[i].name;
|
||||||
|
|
||||||
gamedataadded = false;
|
|
||||||
|
|
||||||
// it doesn't test the version of SRB2 and version of dehacked file
|
// it doesn't test the version of SRB2 and version of dehacked file
|
||||||
dbg_line = -1; // start at -1 so the first line is 0.
|
dbg_line = -1; // start at -1 so the first line is 0.
|
||||||
while (!myfeof(f))
|
while (!myfeof(f))
|
||||||
|
@ -3483,10 +3491,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
if (fastcmp(word, "FREESLOT"))
|
if (fastcmp(word, "FREESLOT"))
|
||||||
{
|
{
|
||||||
readfreeslots(f);
|
readfreeslots(f);
|
||||||
|
// This is not a major mod.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "MAINCFG"))
|
else if (fastcmp(word, "MAINCFG"))
|
||||||
{
|
{
|
||||||
|
G_SetGameModified(multiplayer, true);
|
||||||
readmaincfg(f);
|
readmaincfg(f);
|
||||||
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
||||||
continue;
|
continue;
|
||||||
|
@ -3495,6 +3505,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
{
|
{
|
||||||
readwipes(f);
|
readwipes(f);
|
||||||
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
||||||
|
// This is not a major mod.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
word2 = strtok(NULL, " ");
|
word2 = strtok(NULL, " ");
|
||||||
|
@ -3515,6 +3526,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
ignorelines(f);
|
ignorelines(f);
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
|
// This is not a major mod.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (word2)
|
if (word2)
|
||||||
|
@ -3528,12 +3540,14 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
// Read texture from spec file.
|
// Read texture from spec file.
|
||||||
readtexture(f, word2);
|
readtexture(f, word2);
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
|
// This is not a major mod.
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "PATCH"))
|
else if (fastcmp(word, "PATCH"))
|
||||||
{
|
{
|
||||||
// Read patch from spec file.
|
// Read patch from spec file.
|
||||||
readpatch(f, word2, wad);
|
readpatch(f, word2, wad);
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
|
// This is not a major mod.
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "FOLLOWER"))
|
else if (fastcmp(word, "FOLLOWER"))
|
||||||
{
|
{
|
||||||
|
@ -3545,7 +3559,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||||
i = get_mobjtype(word2); // find a thing by name
|
i = get_mobjtype(word2); // find a thing by name
|
||||||
if (i < NUMMOBJTYPES && i >= 0)
|
if (i < NUMMOBJTYPES && i >= 0)
|
||||||
|
{
|
||||||
|
if (i < (MT_FIRSTFREESLOT+freeslotusage[1][1]))
|
||||||
|
G_SetGameModified(multiplayer, true); // affecting something earlier than the first freeslot allocated in this .wad? DENIED
|
||||||
readthing(f, i);
|
readthing(f, i);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
deh_warning("Thing %d out of range (0 - %d)", i, NUMMOBJTYPES-1);
|
deh_warning("Thing %d out of range (0 - %d)", i, NUMMOBJTYPES-1);
|
||||||
|
@ -3556,6 +3574,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
/* else if (fastcmp(word, "ANIMTEX"))
|
/* else if (fastcmp(word, "ANIMTEX"))
|
||||||
{
|
{
|
||||||
readAnimTex(f, i);
|
readAnimTex(f, i);
|
||||||
|
// This is not a major mod.
|
||||||
}*/
|
}*/
|
||||||
else if (fastcmp(word, "LIGHT"))
|
else if (fastcmp(word, "LIGHT"))
|
||||||
{
|
{
|
||||||
|
@ -3569,6 +3588,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
ignorelines(f);
|
ignorelines(f);
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
|
// This is not a major mod.
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "SPRITE"))
|
else if (fastcmp(word, "SPRITE"))
|
||||||
|
@ -3584,6 +3604,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
ignorelines(f);
|
ignorelines(f);
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
|
// This is not a major mod.
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "LEVEL"))
|
else if (fastcmp(word, "LEVEL"))
|
||||||
|
@ -3596,7 +3617,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
i = M_MapNumber(word2[0], word2[1]);
|
i = M_MapNumber(word2[0], word2[1]);
|
||||||
|
|
||||||
if (i > 0 && i <= NUMMAPS)
|
if (i > 0 && i <= NUMMAPS)
|
||||||
|
{
|
||||||
|
if (mapheaderinfo[i])
|
||||||
|
G_SetGameModified(multiplayer, true); // only mark as a major mod if it replaces an already-existing mapheaderinfo
|
||||||
readlevelheader(f, i);
|
readlevelheader(f, i);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
deh_warning("Level number %d out of range (1 - %d)", i, NUMMAPS);
|
deh_warning("Level number %d out of range (1 - %d)", i, NUMMAPS);
|
||||||
|
@ -3614,13 +3639,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
ignorelines(f);
|
ignorelines(f);
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
|
//G_SetGameModified(multiplayer, true); -- might have to reconsider in a future update
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE"))
|
else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE"))
|
||||||
{
|
{
|
||||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||||
i = get_state(word2); // find a state by name
|
i = get_state(word2); // find a state by name
|
||||||
if (i < NUMSTATES && i >= 0)
|
if (i < NUMSTATES && i >= 0)
|
||||||
|
{
|
||||||
|
if (i < (S_FIRSTFREESLOT+freeslotusage[0][1]))
|
||||||
|
G_SetGameModified(multiplayer, true); // affecting something earlier than the first freeslot allocated in this .wad? DENIED
|
||||||
readframe(f, i);
|
readframe(f, i);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
deh_warning("Frame %d out of range (0 - %d)", i, NUMSTATES-1);
|
deh_warning("Frame %d out of range (0 - %d)", i, NUMSTATES-1);
|
||||||
|
@ -3649,6 +3679,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
deh_warning("pointer (Frame %d) : missing ')'", i);
|
deh_warning("pointer (Frame %d) : missing ')'", i);
|
||||||
|
G_SetGameModified(multiplayer, true);
|
||||||
}*/
|
}*/
|
||||||
else if (fastcmp(word, "SOUND"))
|
else if (fastcmp(word, "SOUND"))
|
||||||
{
|
{
|
||||||
|
@ -3662,6 +3693,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
ignorelines(f);
|
ignorelines(f);
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
|
// This is not a major mod.
|
||||||
}
|
}
|
||||||
/* else if (fastcmp(word, "SPRITE"))
|
/* else if (fastcmp(word, "SPRITE"))
|
||||||
{
|
{
|
||||||
|
@ -3682,6 +3714,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
deh_warning("Sprite %d doesn't exist",i);
|
deh_warning("Sprite %d doesn't exist",i);
|
||||||
|
// This is not a major mod.
|
||||||
}*/
|
}*/
|
||||||
else if (fastcmp(word, "HUDITEM"))
|
else if (fastcmp(word, "HUDITEM"))
|
||||||
{
|
{
|
||||||
|
@ -3695,10 +3728,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
ignorelines(f);
|
ignorelines(f);
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
|
// This is not a major mod.
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "EMBLEM"))
|
else if (fastcmp(word, "EMBLEM"))
|
||||||
{
|
{
|
||||||
if (!gamedataadded)
|
if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
|
||||||
{
|
{
|
||||||
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
||||||
ignorelines(f);
|
ignorelines(f);
|
||||||
|
@ -3718,7 +3752,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "EXTRAEMBLEM"))
|
else if (fastcmp(word, "EXTRAEMBLEM"))
|
||||||
{
|
{
|
||||||
if (!gamedataadded)
|
if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
|
||||||
{
|
{
|
||||||
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
||||||
ignorelines(f);
|
ignorelines(f);
|
||||||
|
@ -3738,7 +3772,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "UNLOCKABLE"))
|
else if (fastcmp(word, "UNLOCKABLE"))
|
||||||
{
|
{
|
||||||
if (!gamedataadded)
|
if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
|
||||||
{
|
{
|
||||||
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
||||||
ignorelines(f);
|
ignorelines(f);
|
||||||
|
@ -3754,7 +3788,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "CONDITIONSET"))
|
else if (fastcmp(word, "CONDITIONSET"))
|
||||||
{
|
{
|
||||||
if (!gamedataadded)
|
if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
|
||||||
{
|
{
|
||||||
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
||||||
ignorelines(f);
|
ignorelines(f);
|
||||||
|
@ -3789,7 +3823,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
{
|
{
|
||||||
boolean clearall = (fastcmp(word2, "ALL"));
|
boolean clearall = (fastcmp(word2, "ALL"));
|
||||||
|
|
||||||
if (!gamedataadded)
|
if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
|
||||||
{
|
{
|
||||||
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
||||||
continue;
|
continue;
|
||||||
|
@ -3826,8 +3860,8 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
deh_warning("No word in this line: %s", s);
|
deh_warning("No word in this line: %s", s);
|
||||||
} // end while
|
} // end while
|
||||||
|
|
||||||
if (gamedataadded)
|
/*if (gamedataadded) -- REFRESHDIR_GAMEDATA murdered this
|
||||||
G_LoadGameData();
|
G_LoadGameData();*/
|
||||||
|
|
||||||
dbg_line = -1;
|
dbg_line = -1;
|
||||||
if (deh_num_warning)
|
if (deh_num_warning)
|
||||||
|
@ -8370,7 +8404,9 @@ static const char *const KARTSTUFF_LIST[] = {
|
||||||
|
|
||||||
"ITEMBLINK",
|
"ITEMBLINK",
|
||||||
"ITEMBLINKMODE",
|
"ITEMBLINKMODE",
|
||||||
"GETSPARKS"
|
"GETSPARKS",
|
||||||
|
"JAWZTARGETDELAY",
|
||||||
|
"SPECTATEWAIT"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const HUDITEMS_LIST[] = {
|
static const char *const HUDITEMS_LIST[] = {
|
||||||
|
@ -9427,6 +9463,7 @@ static inline int lib_freeslot(lua_State *L)
|
||||||
CONS_Printf("State S_%s allocated.\n",word);
|
CONS_Printf("State S_%s allocated.\n",word);
|
||||||
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
||||||
strcpy(FREE_STATES[i],word);
|
strcpy(FREE_STATES[i],word);
|
||||||
|
freeslotusage[0][0]++;
|
||||||
lua_pushinteger(L, i);
|
lua_pushinteger(L, i);
|
||||||
r++;
|
r++;
|
||||||
break;
|
break;
|
||||||
|
@ -9442,6 +9479,7 @@ static inline int lib_freeslot(lua_State *L)
|
||||||
CONS_Printf("MobjType MT_%s allocated.\n",word);
|
CONS_Printf("MobjType MT_%s allocated.\n",word);
|
||||||
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
||||||
strcpy(FREE_MOBJS[i],word);
|
strcpy(FREE_MOBJS[i],word);
|
||||||
|
freeslotusage[1][0]++;
|
||||||
lua_pushinteger(L, i);
|
lua_pushinteger(L, i);
|
||||||
r++;
|
r++;
|
||||||
break;
|
break;
|
||||||
|
@ -9811,6 +9849,9 @@ static inline int lib_getenum(lua_State *L)
|
||||||
} else if (fastcmp(word,"modifiedgame")) {
|
} else if (fastcmp(word,"modifiedgame")) {
|
||||||
lua_pushboolean(L, modifiedgame && !savemoddata);
|
lua_pushboolean(L, modifiedgame && !savemoddata);
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (fastcmp(word,"majormods")) {
|
||||||
|
lua_pushboolean(L, majormods);
|
||||||
|
return 1;
|
||||||
} else if (fastcmp(word,"menuactive")) {
|
} else if (fastcmp(word,"menuactive")) {
|
||||||
lua_pushboolean(L, menuactive);
|
lua_pushboolean(L, menuactive);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -37,6 +37,8 @@ void DEH_UnloadDehackedWad(UINT16 wad);
|
||||||
void DEH_LoadDehackedLump(lumpnum_t lumpnum);
|
void DEH_LoadDehackedLump(lumpnum_t lumpnum);
|
||||||
void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump);
|
void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump);
|
||||||
|
|
||||||
|
void DEH_UpdateMaxFreeslots(void);
|
||||||
|
|
||||||
void DEH_Check(void);
|
void DEH_Check(void);
|
||||||
|
|
||||||
fixed_t get_number(const char *word);
|
fixed_t get_number(const char *word);
|
||||||
|
|
|
@ -150,9 +150,9 @@ extern FILE *logstream;
|
||||||
// we use comprevision and compbranch instead.
|
// we use comprevision and compbranch instead.
|
||||||
#else
|
#else
|
||||||
#define VERSION 100 // Game version
|
#define VERSION 100 // Game version
|
||||||
#define SUBVERSION 2 // more precise version number
|
#define SUBVERSION 3 // more precise version number
|
||||||
#define VERSIONSTRING "v1.0.2"
|
#define VERSIONSTRING "v1.0.3"
|
||||||
#define VERSIONSTRINGW L"v1.0.2"
|
#define VERSIONSTRINGW L"v1.0.3"
|
||||||
// Hey! If you change this, add 1 to the MODVERSION below!
|
// Hey! If you change this, add 1 to the MODVERSION below!
|
||||||
// Otherwise we can't force updates!
|
// Otherwise we can't force updates!
|
||||||
#endif
|
#endif
|
||||||
|
@ -221,7 +221,7 @@ extern FILE *logstream;
|
||||||
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
||||||
// Only set it higher, not lower, obviously.
|
// Only set it higher, not lower, obviously.
|
||||||
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
||||||
#define MODVERSION 2
|
#define MODVERSION 3
|
||||||
|
|
||||||
// Filter consvars by version
|
// Filter consvars by version
|
||||||
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
|
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
|
||||||
|
|
|
@ -54,6 +54,7 @@ extern boolean gamecomplete;
|
||||||
|
|
||||||
// Set if homebrew PWAD stuff has been added.
|
// Set if homebrew PWAD stuff has been added.
|
||||||
extern boolean modifiedgame;
|
extern boolean modifiedgame;
|
||||||
|
extern boolean majormods;
|
||||||
extern UINT16 mainwads;
|
extern UINT16 mainwads;
|
||||||
extern boolean savemoddata; // This mod saves time/emblem data.
|
extern boolean savemoddata; // This mod saves time/emblem data.
|
||||||
extern boolean disableSpeedAdjust; // Don't alter the duration of player states if true
|
extern boolean disableSpeedAdjust; // Don't alter the duration of player states if true
|
||||||
|
@ -280,6 +281,8 @@ typedef struct
|
||||||
#define LF2_NIGHTSATTACK 8 ///< Show this map in NiGHTS mode menu
|
#define LF2_NIGHTSATTACK 8 ///< Show this map in NiGHTS mode menu
|
||||||
#define LF2_NOVISITNEEDED 16 ///< Available in time attack/nights mode without visiting the level
|
#define LF2_NOVISITNEEDED 16 ///< Available in time attack/nights mode without visiting the level
|
||||||
|
|
||||||
|
#define LF2_EXISTSHACK 128 ///< Map lump exists; as noted, a single-bit hack that can be freely movable to other variables without concern.
|
||||||
|
|
||||||
// Save override
|
// Save override
|
||||||
#define SAVE_NEVER -1
|
#define SAVE_NEVER -1
|
||||||
#define SAVE_DEFAULT 0
|
#define SAVE_DEFAULT 0
|
||||||
|
|
14
src/f_wipe.c
14
src/f_wipe.c
|
@ -26,6 +26,7 @@
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "m_misc.h" // movie mode
|
#include "m_misc.h" // movie mode
|
||||||
|
#include "d_clisrv.h" // So the network state can be updated during the wipe
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
#include "hardware/hw_main.h"
|
#include "hardware/hw_main.h"
|
||||||
|
@ -96,7 +97,7 @@ static fixed_t paldiv;
|
||||||
* \return fademask_t for lump
|
* \return fademask_t for lump
|
||||||
*/
|
*/
|
||||||
static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
|
static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
|
||||||
static char lumpname[10] = "FADEmmss";
|
static char lumpname[9] = "FADEmmss";
|
||||||
static fademask_t fm = {NULL,0,0,0,0,0};
|
static fademask_t fm = {NULL,0,0,0,0,0};
|
||||||
lumpnum_t lumpnum;
|
lumpnum_t lumpnum;
|
||||||
UINT8 *lump, *mask;
|
UINT8 *lump, *mask;
|
||||||
|
@ -106,7 +107,14 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
|
||||||
if (masknum > 99 || scrnnum > 99)
|
if (masknum > 99 || scrnnum > 99)
|
||||||
goto freemask;
|
goto freemask;
|
||||||
|
|
||||||
sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)masknum, (UINT16)scrnnum);
|
// SRB2Kart: This suddenly triggers ERRORMODE now
|
||||||
|
//sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)masknum, (UINT16)scrnnum);
|
||||||
|
|
||||||
|
lumpname[4] = '0'+(masknum/10);
|
||||||
|
lumpname[5] = '0'+(masknum%10);
|
||||||
|
|
||||||
|
lumpname[6] = '0'+(scrnnum/10);
|
||||||
|
lumpname[7] = '0'+(scrnnum%10);
|
||||||
|
|
||||||
lumpnum = W_CheckNumForName(lumpname);
|
lumpnum = W_CheckNumForName(lumpname);
|
||||||
if (lumpnum == LUMPERROR)
|
if (lumpnum == LUMPERROR)
|
||||||
|
@ -375,6 +383,8 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
||||||
|
|
||||||
if (moviemode)
|
if (moviemode)
|
||||||
M_SaveFrame();
|
M_SaveFrame();
|
||||||
|
|
||||||
|
NetKeepAlive(); // Update the network so we don't cause timeouts
|
||||||
}
|
}
|
||||||
WipeInAction = false;
|
WipeInAction = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -88,7 +88,8 @@ typedef enum
|
||||||
REFRESHDIR_WARNING = 4,
|
REFRESHDIR_WARNING = 4,
|
||||||
REFRESHDIR_ERROR = 8,
|
REFRESHDIR_ERROR = 8,
|
||||||
REFRESHDIR_NOTLOADED = 16,
|
REFRESHDIR_NOTLOADED = 16,
|
||||||
REFRESHDIR_MAX = 32
|
REFRESHDIR_MAX = 32,
|
||||||
|
REFRESHDIR_GAMEDATA = 64
|
||||||
} refreshdir_enum;
|
} refreshdir_enum;
|
||||||
|
|
||||||
void closefilemenu(boolean validsize);
|
void closefilemenu(boolean validsize);
|
||||||
|
|
105
src/g_game.c
105
src/g_game.c
|
@ -16,6 +16,7 @@
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
|
#include "filesrch.h" // for refreshdirmenu
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "p_saveg.h"
|
#include "p_saveg.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
@ -86,7 +87,8 @@ INT16 lastmapsaved = 0; // Last map we auto-saved at
|
||||||
boolean gamecomplete = false;
|
boolean gamecomplete = false;
|
||||||
|
|
||||||
UINT16 mainwads = 0;
|
UINT16 mainwads = 0;
|
||||||
boolean modifiedgame; // Set if homebrew PWAD stuff has been added.
|
boolean modifiedgame = false; // Set if homebrew PWAD stuff has been added.
|
||||||
|
boolean majormods = false; // Set if Lua/Gameplay SOC/replacement map has been added.
|
||||||
boolean savemoddata = false;
|
boolean savemoddata = false;
|
||||||
UINT8 paused;
|
UINT8 paused;
|
||||||
UINT8 modeattacking = ATTACKING_NONE;
|
UINT8 modeattacking = ATTACKING_NONE;
|
||||||
|
@ -752,16 +754,21 @@ void G_SetNightsRecords(void)
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// for consistency among messages: this modifies the game and removes savemoddata.
|
// for consistency among messages: this modifies the game and removes savemoddata.
|
||||||
void G_SetGameModified(boolean silent)
|
void G_SetGameModified(boolean silent, boolean major)
|
||||||
{
|
{
|
||||||
if (modifiedgame && !savemoddata)
|
if ((majormods && modifiedgame) || !mainwads || (refreshdirmenu & REFRESHDIR_GAMEDATA)) // new gamedata amnesty?
|
||||||
return;
|
return;
|
||||||
|
|
||||||
modifiedgame = true;
|
modifiedgame = true;
|
||||||
savemoddata = false;
|
|
||||||
|
if (!major)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//savemoddata = false; -- there is literally no reason to do this anymore.
|
||||||
|
majormods = true;
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to record statistics.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to play record attack.\n"));
|
||||||
|
|
||||||
// If in record attack recording, cancel it.
|
// If in record attack recording, cancel it.
|
||||||
if (modeattacking)
|
if (modeattacking)
|
||||||
|
@ -1595,10 +1602,26 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lua: Allow this hook to overwrite ticcmd.
|
||||||
|
We check if we're actually in a level because for some reason this Hook would run in menus and on the titlescreen otherwise.
|
||||||
|
Be aware that within this hook, nothing but this player's cmd can be edited (otherwise we'd run in some pretty bad synching problems since this is clientsided, or something)
|
||||||
|
|
||||||
|
Possible usages for this are:
|
||||||
|
-Forcing the player to perform an action, which could otherwise require terrible, terrible hacking to replicate.
|
||||||
|
-Preventing the player to perform an action, which would ALSO require some weirdo hacks.
|
||||||
|
-Making some galaxy brain autopilot Lua if you're a masochist
|
||||||
|
-Making a Mario Kart 8 Deluxe tier baby mode that steers you away from walls and whatnot. You know what, do what you want!
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (gamestate == GS_LEVEL)
|
||||||
|
LUAh_PlayerCmd(player, cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
//Reset away view if a command is given.
|
//Reset away view if a command is given.
|
||||||
if ((cmd->forwardmove || cmd->sidemove || cmd->buttons)
|
if ((cmd->forwardmove || cmd->sidemove || cmd->buttons)
|
||||||
&& displayplayer != consoleplayer && ssplayer == 1)
|
&& displayplayer != consoleplayer && ssplayer == 1)
|
||||||
displayplayer = consoleplayer;
|
displayplayer = consoleplayer;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// User has designated that they want
|
// User has designated that they want
|
||||||
|
@ -3926,7 +3949,6 @@ void G_LoadGameData(void)
|
||||||
// Saves the main data file, which stores information such as emblems found, etc.
|
// Saves the main data file, which stores information such as emblems found, etc.
|
||||||
void G_SaveGameData(boolean force)
|
void G_SaveGameData(boolean force)
|
||||||
{
|
{
|
||||||
const boolean wasmodified = modifiedgame;
|
|
||||||
size_t length;
|
size_t length;
|
||||||
INT32 i, j;
|
INT32 i, j;
|
||||||
UINT8 btemp;
|
UINT8 btemp;
|
||||||
|
@ -3943,9 +3965,7 @@ void G_SaveGameData(boolean force)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (force) // SRB2Kart: for enabling unlocks online, even if the game is modified
|
if (majormods && !force)
|
||||||
modifiedgame = savemoddata; // L-let's just sort of... hack around the cheat protection, because I'm too worried about just removing it @@;
|
|
||||||
else if (modifiedgame && !savemoddata)
|
|
||||||
{
|
{
|
||||||
free(savebuffer);
|
free(savebuffer);
|
||||||
save_p = savebuffer = NULL;
|
save_p = savebuffer = NULL;
|
||||||
|
@ -3958,7 +3978,7 @@ void G_SaveGameData(boolean force)
|
||||||
WRITEUINT32(save_p, totalplaytime);
|
WRITEUINT32(save_p, totalplaytime);
|
||||||
WRITEUINT32(save_p, matchesplayed);
|
WRITEUINT32(save_p, matchesplayed);
|
||||||
|
|
||||||
btemp = (UINT8)(savemoddata || modifiedgame);
|
btemp = (UINT8)(savemoddata); // what used to be here was profoundly dunderheaded
|
||||||
WRITEUINT8(save_p, btemp);
|
WRITEUINT8(save_p, btemp);
|
||||||
|
|
||||||
// TODO put another cipher on these things? meh, I don't care...
|
// TODO put another cipher on these things? meh, I don't care...
|
||||||
|
@ -4044,9 +4064,6 @@ void G_SaveGameData(boolean force)
|
||||||
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer, length);
|
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer, length);
|
||||||
free(savebuffer);
|
free(savebuffer);
|
||||||
save_p = savebuffer = NULL;
|
save_p = savebuffer = NULL;
|
||||||
|
|
||||||
if (force) // Eeeek, I'm sorry for my sins!
|
|
||||||
modifiedgame = wasmodified;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VERSIONSIZE 16
|
#define VERSIONSIZE 16
|
||||||
|
@ -5134,22 +5151,20 @@ void G_GhostTicker(void)
|
||||||
if (ziptic & EZT_HIT)
|
if (ziptic & EZT_HIT)
|
||||||
{ // Spawn hit poofs for killing things!
|
{ // Spawn hit poofs for killing things!
|
||||||
UINT16 i, count = READUINT16(g->p), health;
|
UINT16 i, count = READUINT16(g->p), health;
|
||||||
UINT32 type;
|
//UINT32 type;
|
||||||
fixed_t x,y,z;
|
fixed_t x,y,z;
|
||||||
angle_t angle;
|
angle_t angle;
|
||||||
mobj_t *poof;
|
mobj_t *poof;
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
g->p += 4; // reserved
|
g->p += 4; // reserved
|
||||||
type = READUINT32(g->p);
|
g->p += 4; // backwards compat., type used to be here
|
||||||
health = READUINT16(g->p);
|
health = READUINT16(g->p);
|
||||||
x = READFIXED(g->p);
|
x = READFIXED(g->p);
|
||||||
y = READFIXED(g->p);
|
y = READFIXED(g->p);
|
||||||
z = READFIXED(g->p);
|
z = READFIXED(g->p);
|
||||||
angle = READANGLE(g->p);
|
angle = READANGLE(g->p);
|
||||||
if (!(mobjinfo[type].flags & MF_SHOOTABLE)
|
if (health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad.
|
||||||
|| !(mobjinfo[type].flags & (MF_ENEMY|MF_MONITOR))
|
|
||||||
|| health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad.
|
|
||||||
continue;
|
continue;
|
||||||
poof = P_SpawnMobj(x, y, z, MT_GHOST);
|
poof = P_SpawnMobj(x, y, z, MT_GHOST);
|
||||||
poof->angle = angle;
|
poof->angle = angle;
|
||||||
|
@ -5905,6 +5920,32 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skin not loaded?
|
||||||
|
if (!SetPlayerSkin(0, skin))
|
||||||
|
{
|
||||||
|
snprintf(msg, 1024, M_GetText("%s features a character that is not currently loaded.\n"), pdemoname);
|
||||||
|
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||||
|
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||||
|
Z_Free(pdemoname);
|
||||||
|
Z_Free(demobuffer);
|
||||||
|
demoplayback = false;
|
||||||
|
titledemo = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...*map* not loaded?
|
||||||
|
if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK))
|
||||||
|
{
|
||||||
|
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
|
||||||
|
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||||
|
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||||
|
Z_Free(pdemoname);
|
||||||
|
Z_Free(demobuffer);
|
||||||
|
demoplayback = false;
|
||||||
|
titledemo = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Z_Free(pdemoname);
|
Z_Free(pdemoname);
|
||||||
|
|
||||||
memset(&oldcmd,0,sizeof(oldcmd));
|
memset(&oldcmd,0,sizeof(oldcmd));
|
||||||
|
@ -5936,9 +5977,6 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
P_SetRandSeed(randseed);
|
P_SetRandSeed(randseed);
|
||||||
G_InitNew(false, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer.
|
G_InitNew(false, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer.
|
||||||
|
|
||||||
// Set skin
|
|
||||||
SetPlayerSkin(0, skin);
|
|
||||||
|
|
||||||
// Set color
|
// Set color
|
||||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||||
if (!stricmp(KartColor_Names[i],color)) // SRB2kart
|
if (!stricmp(KartColor_Names[i],color)) // SRB2kart
|
||||||
|
@ -5988,6 +6026,7 @@ void G_AddGhost(char *defdemoname)
|
||||||
UINT8 *buffer,*p;
|
UINT8 *buffer,*p;
|
||||||
mapthing_t *mthing;
|
mapthing_t *mthing;
|
||||||
UINT16 count, ghostversion;
|
UINT16 count, ghostversion;
|
||||||
|
skin_t *ghskin = &skins[0];
|
||||||
|
|
||||||
name[16] = '\0';
|
name[16] = '\0';
|
||||||
skin[16] = '\0';
|
skin[16] = '\0';
|
||||||
|
@ -6133,6 +6172,21 @@ void G_AddGhost(char *defdemoname)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < numskins; i++)
|
||||||
|
if (!stricmp(skins[i].name,skin))
|
||||||
|
{
|
||||||
|
ghskin = &skins[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == numskins)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid character.\n"), pdemoname);
|
||||||
|
Z_Free(pdemoname);
|
||||||
|
Z_Free(buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gh = Z_Calloc(sizeof(demoghost), PU_LEVEL, NULL);
|
gh = Z_Calloc(sizeof(demoghost), PU_LEVEL, NULL);
|
||||||
gh->next = ghosts;
|
gh->next = ghosts;
|
||||||
gh->buffer = buffer;
|
gh->buffer = buffer;
|
||||||
|
@ -6178,14 +6232,7 @@ void G_AddGhost(char *defdemoname)
|
||||||
gh->oldmo.z = gh->mo->z;
|
gh->oldmo.z = gh->mo->z;
|
||||||
|
|
||||||
// Set skin
|
// Set skin
|
||||||
gh->mo->skin = &skins[0];
|
gh->mo->skin = gh->oldmo.skin = ghskin;
|
||||||
for (i = 0; i < numskins; i++)
|
|
||||||
if (!stricmp(skins[i].name,skin))
|
|
||||||
{
|
|
||||||
gh->mo->skin = &skins[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gh->oldmo.skin = gh->mo->skin;
|
|
||||||
|
|
||||||
// Set color
|
// Set color
|
||||||
gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor;
|
gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor;
|
||||||
|
|
|
@ -226,7 +226,7 @@ boolean G_GetRetryFlag(void);
|
||||||
void G_LoadGameData(void);
|
void G_LoadGameData(void);
|
||||||
void G_LoadGameSettings(void);
|
void G_LoadGameSettings(void);
|
||||||
|
|
||||||
void G_SetGameModified(boolean silent);
|
void G_SetGameModified(boolean silent, boolean major);
|
||||||
|
|
||||||
void G_SetGamestate(gamestate_t newstate);
|
void G_SetGamestate(gamestate_t newstate);
|
||||||
|
|
||||||
|
|
|
@ -15449,7 +15449,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_ORBINAUT_SHIELDDEAD, // deathstate
|
S_ORBINAUT_SHIELDDEAD, // deathstate
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_None, // deathsound
|
sfx_None, // deathsound
|
||||||
10*FRACUNIT, // speed
|
4*FRACUNIT, // speed
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
32*FRACUNIT, // height
|
32*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
|
@ -15530,7 +15530,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_JAWZ_DEAD1, // deathstate
|
S_JAWZ_DEAD1, // deathstate
|
||||||
S_JAWZ_DEAD2, // xdeathstate
|
S_JAWZ_DEAD2, // xdeathstate
|
||||||
sfx_None, // deathsound
|
sfx_None, // deathsound
|
||||||
10*FRACUNIT, // speed
|
4*FRACUNIT, // speed
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
32*FRACUNIT, // height
|
32*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
|
|
|
@ -608,7 +608,7 @@ typedef enum sprite
|
||||||
// Kart Items
|
// Kart Items
|
||||||
SPR_RSHE, // Rocket sneaker
|
SPR_RSHE, // Rocket sneaker
|
||||||
SPR_FITM, // Eggman Monitor
|
SPR_FITM, // Eggman Monitor
|
||||||
SPR_BANA, // Banana Peel
|
SPR_BANA, // Banana Peel
|
||||||
SPR_ORBN, // Orbinaut
|
SPR_ORBN, // Orbinaut
|
||||||
SPR_JAWZ, // Jawz
|
SPR_JAWZ, // Jawz
|
||||||
SPR_SSMN, // SS Mine
|
SPR_SSMN, // SS Mine
|
||||||
|
|
528
src/k_kart.c
528
src/k_kart.c
|
@ -499,9 +499,9 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS][10] =
|
||||||
/*Sneaker*/ {20, 0, 0, 4, 6, 6, 0, 0, 0, 0 }, // Sneaker
|
/*Sneaker*/ {20, 0, 0, 4, 6, 6, 0, 0, 0, 0 }, // Sneaker
|
||||||
/*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3, 0 }, // Rocket Sneaker
|
/*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3, 0 }, // Rocket Sneaker
|
||||||
/*Invincibility*/ { 0, 0, 0, 0, 0, 1, 4, 6,14, 0 }, // Invincibility
|
/*Invincibility*/ { 0, 0, 0, 0, 0, 1, 4, 6,14, 0 }, // Invincibility
|
||||||
/*Banana*/ { 0, 9, 4, 2, 1, 0, 0, 0, 0, 0 }, // Banana
|
/*Banana*/ { 0,10, 4, 2, 1, 0, 0, 0, 0, 0 }, // Banana
|
||||||
/*Eggman Monitor*/ { 0, 4, 3, 2, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor
|
/*Eggman Monitor*/ { 0, 3, 2, 1, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor
|
||||||
/*Orbinaut*/ { 0, 6, 5, 3, 2, 0, 0, 0, 0, 0 }, // Orbinaut
|
/*Orbinaut*/ { 0, 8, 6, 4, 2, 0, 0, 0, 0, 0 }, // Orbinaut
|
||||||
/*Jawz*/ { 0, 0, 3, 2, 1, 1, 0, 0, 0, 0 }, // Jawz
|
/*Jawz*/ { 0, 0, 3, 2, 1, 1, 0, 0, 0, 0 }, // Jawz
|
||||||
/*Mine*/ { 0, 0, 2, 2, 1, 0, 0, 0, 0, 0 }, // Mine
|
/*Mine*/ { 0, 0, 2, 2, 1, 0, 0, 0, 0, 0 }, // Mine
|
||||||
/*Ballhog*/ { 0, 0, 0, 2, 1, 0, 0, 0, 0, 0 }, // Ballhog
|
/*Ballhog*/ { 0, 0, 0, 2, 1, 0, 0, 0, 0, 0 }, // Ballhog
|
||||||
|
@ -616,6 +616,32 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
|
||||||
UINT8 pingame = 0, pexiting = 0, pinvin = 0;
|
UINT8 pingame = 0, pexiting = 0, pinvin = 0;
|
||||||
SINT8 first = -1, second = -1;
|
SINT8 first = -1, second = -1;
|
||||||
INT32 secondist = 0;
|
INT32 secondist = 0;
|
||||||
|
boolean itemenabled[NUMKARTRESULTS] = {
|
||||||
|
cv_sneaker.value,
|
||||||
|
cv_rocketsneaker.value,
|
||||||
|
cv_invincibility.value,
|
||||||
|
cv_banana.value,
|
||||||
|
cv_eggmanmonitor.value,
|
||||||
|
cv_orbinaut.value,
|
||||||
|
cv_jawz.value,
|
||||||
|
cv_mine.value,
|
||||||
|
cv_ballhog.value,
|
||||||
|
cv_selfpropelledbomb.value,
|
||||||
|
cv_grow.value,
|
||||||
|
cv_shrink.value,
|
||||||
|
cv_thundershield.value,
|
||||||
|
cv_hyudoro.value,
|
||||||
|
cv_kitchensink.value,
|
||||||
|
cv_triplesneaker.value,
|
||||||
|
cv_triplebanana.value,
|
||||||
|
cv_decabanana.value,
|
||||||
|
cv_tripleorbinaut.value,
|
||||||
|
cv_quadorbinaut.value,
|
||||||
|
cv_dualjawz.value
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!itemenabled[item] && !modeattacking)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (G_BattleGametype())
|
if (G_BattleGametype())
|
||||||
newodds = K_KartItemOddsBattle[item-1][pos];
|
newodds = K_KartItemOddsBattle[item-1][pos];
|
||||||
|
@ -626,21 +652,24 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
|
||||||
{
|
{
|
||||||
if (!playeringame[i] || players[i].spectator)
|
if (!playeringame[i] || players[i].spectator)
|
||||||
continue;
|
continue;
|
||||||
|
if (!G_BattleGametype() || players[i].kartstuff[k_bumper])
|
||||||
pingame++;
|
pingame++;
|
||||||
if (players[i].exiting)
|
if (players[i].exiting)
|
||||||
pexiting++;
|
pexiting++;
|
||||||
if (players[i].mo)
|
if (players[i].mo)
|
||||||
{
|
{
|
||||||
if (players[i].kartstuff[k_position] == 1 && first == -1)
|
|
||||||
first = i;
|
|
||||||
if (players[i].kartstuff[k_position] == 2 && second == -1)
|
|
||||||
second = i;
|
|
||||||
if (players[i].kartstuff[k_itemtype] == KITEM_INVINCIBILITY
|
if (players[i].kartstuff[k_itemtype] == KITEM_INVINCIBILITY
|
||||||
|| players[i].kartstuff[k_itemtype] == KITEM_GROW
|
|| players[i].kartstuff[k_itemtype] == KITEM_GROW
|
||||||
|| players[i].kartstuff[k_invincibilitytimer]
|
|| players[i].kartstuff[k_invincibilitytimer]
|
||||||
|| players[i].kartstuff[k_growshrinktimer] > 0)
|
|| players[i].kartstuff[k_growshrinktimer] > 0)
|
||||||
pinvin++;
|
pinvin++;
|
||||||
|
if (!G_BattleGametype())
|
||||||
|
{
|
||||||
|
if (players[i].kartstuff[k_position] == 1 && first == -1)
|
||||||
|
first = i;
|
||||||
|
if (players[i].kartstuff[k_position] == 2 && second == -1)
|
||||||
|
second = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,120 +679,61 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
|
||||||
players[first].mo->y - players[second].mo->y),
|
players[first].mo->y - players[second].mo->y),
|
||||||
players[first].mo->z - players[second].mo->z) / mapobjectscale;
|
players[first].mo->z - players[second].mo->z) / mapobjectscale;
|
||||||
if (franticitems)
|
if (franticitems)
|
||||||
secondist = (15*secondist/14);
|
secondist = (15 * secondist) / 14;
|
||||||
if (pingame < 8 && !G_BattleGametype())
|
secondist = ((28 + (8-pingame)) * secondist) / 28;
|
||||||
secondist = ((28+(8-pingame))*secondist/28);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// POWERITEMODDS handles all of the "frantic item" related functionality, for all of our powerful items.
|
// POWERITEMODDS handles all of the "frantic item" related functionality, for all of our powerful items.
|
||||||
// First, it multiplies it by 2 if franticitems is true; easy-peasy.
|
// First, it multiplies it by 2 if franticitems is true; easy-peasy.
|
||||||
// Next, it multiplies it again if it's in SPB mode and 2nd needs to apply pressure to 1st.
|
// Next, it multiplies it again if it's in SPB mode and 2nd needs to apply pressure to 1st.
|
||||||
// Then, it multiplies it further if there's less than 8 players in game.
|
// Then, it multiplies it further if there's less than 5 players in game.
|
||||||
// This is done to make low player count races more fair & interesting. (1v1s are basically the same as franticitems false in a normal race)
|
// This is done to make low player count races more fair & interesting. (2P normal would be about halfway between 8P normal and 8P frantic)
|
||||||
// Lastly, it *divides* it by your mashed value, which was determined in K_KartItemRoulette, to punish those who are impatient.
|
// Lastly, it *divides* it by your mashed value, which was determined in K_KartItemRoulette, to punish those who are impatient.
|
||||||
// The last two are very fractional and complicated, very sorry!
|
|
||||||
#define POWERITEMODDS(odds) \
|
#define POWERITEMODDS(odds) \
|
||||||
if (franticitems) \
|
if (franticitems) \
|
||||||
odds *= 2; \
|
odds <<= 1; \
|
||||||
if (pingame < 8 && !G_BattleGametype()) \
|
odds = FixedMul(odds<<FRACBITS, FRACUNIT + ((8-pingame) * (FRACUNIT/25))) >> FRACBITS; \
|
||||||
odds = FixedMul(odds*FRACUNIT, FRACUNIT+min((8-pingame)*(FRACUNIT/25), FRACUNIT))/FRACUNIT; \
|
|
||||||
if (mashed > 0) \
|
if (mashed > 0) \
|
||||||
odds = FixedDiv(odds*FRACUNIT, mashed+FRACUNIT)/FRACUNIT \
|
odds = FixedDiv(odds<<FRACBITS, FRACUNIT + mashed) >> FRACBITS \
|
||||||
|
|
||||||
switch (item)
|
switch (item)
|
||||||
{
|
{
|
||||||
case KITEM_SNEAKER:
|
|
||||||
if ((!cv_sneaker.value) && (!modeattacking)) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KITEM_ROCKETSNEAKER:
|
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if (!cv_rocketsneaker.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KITEM_INVINCIBILITY:
|
case KITEM_INVINCIBILITY:
|
||||||
POWERITEMODDS(newodds);
|
case KITEM_GROW:
|
||||||
if ((!cv_invincibility.value) || (pinvin >= 2)) newodds = 0;
|
if (pinvin >= max(1, (pingame+2) / 4))
|
||||||
break;
|
newodds = 0;
|
||||||
case KITEM_BANANA:
|
else
|
||||||
if (!cv_banana.value) newodds = 0;
|
/* FALLTHRU */
|
||||||
break;
|
case KITEM_ROCKETSNEAKER:
|
||||||
case KITEM_EGGMAN:
|
|
||||||
if (!cv_eggmanmonitor.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KITEM_ORBINAUT:
|
|
||||||
if (!cv_orbinaut.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KITEM_JAWZ:
|
case KITEM_JAWZ:
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if (!cv_jawz.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KITEM_MINE:
|
case KITEM_MINE:
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if (!cv_mine.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KITEM_BALLHOG:
|
case KITEM_BALLHOG:
|
||||||
|
case KITEM_THUNDERSHIELD:
|
||||||
|
case KRITEM_TRIPLESNEAKER:
|
||||||
|
case KRITEM_TRIPLEBANANA:
|
||||||
|
case KRITEM_TENFOLDBANANA:
|
||||||
|
case KRITEM_TRIPLEORBINAUT:
|
||||||
|
case KRITEM_QUADORBINAUT:
|
||||||
|
case KRITEM_DUALJAWZ:
|
||||||
POWERITEMODDS(newodds);
|
POWERITEMODDS(newodds);
|
||||||
if (!cv_ballhog.value) newodds = 0;
|
|
||||||
break;
|
break;
|
||||||
case KITEM_SPB:
|
case KITEM_SPB:
|
||||||
//POWERITEMODDS(newodds);
|
//POWERITEMODDS(newodds);
|
||||||
if (((!cv_selfpropelledbomb.value)
|
if (((indirectitemcooldown > 0) || (pexiting > 0) || (secondist/distvar < 3))
|
||||||
|| (indirectitemcooldown > 0)
|
|
||||||
|| (pexiting > 0)
|
|
||||||
|| (secondist/distvar < 3))
|
|
||||||
&& (pos != 9)) // Force SPB
|
&& (pos != 9)) // Force SPB
|
||||||
newodds = 0;
|
newodds = 0;
|
||||||
newodds *= min((secondist/distvar)-4, 3);
|
else
|
||||||
break;
|
newodds *= min((secondist/distvar)-4, 3);
|
||||||
case KITEM_GROW:
|
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if ((!cv_grow.value) || (pinvin >= 2)) newodds = 0;
|
|
||||||
break;
|
break;
|
||||||
case KITEM_SHRINK:
|
case KITEM_SHRINK:
|
||||||
POWERITEMODDS(newodds);
|
POWERITEMODDS(newodds);
|
||||||
if ((!cv_shrink.value)
|
if ((indirectitemcooldown > 0) || (pingame-1 <= pexiting))
|
||||||
|| (indirectitemcooldown > 0)
|
newodds = 0;
|
||||||
|| (pingame-1 <= pexiting)) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KITEM_THUNDERSHIELD:
|
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if (!cv_thundershield.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KITEM_HYUDORO:
|
|
||||||
if (!cv_hyudoro.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KITEM_POGOSPRING:
|
|
||||||
if (!cv_pogospring.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KITEM_KITCHENSINK:
|
|
||||||
newodds = 0; // Not obtained via normal means.
|
|
||||||
break;
|
|
||||||
case KRITEM_TRIPLESNEAKER:
|
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if (!cv_triplesneaker.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KRITEM_TRIPLEBANANA:
|
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if (!cv_triplebanana.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KRITEM_TENFOLDBANANA:
|
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if (!cv_decabanana.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KRITEM_TRIPLEORBINAUT:
|
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if (!cv_tripleorbinaut.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KRITEM_QUADORBINAUT:
|
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if (!cv_quadorbinaut.value) newodds = 0;
|
|
||||||
break;
|
|
||||||
case KRITEM_DUALJAWZ:
|
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if (!cv_dualjawz.value) newodds = 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef POWERITEMODDS
|
#undef POWERITEMODDS
|
||||||
|
|
||||||
return newodds;
|
return newodds;
|
||||||
|
@ -851,11 +821,12 @@ static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT3
|
||||||
if (oddsvalid[8]) SETUPDISTTABLE(8,1);
|
if (oddsvalid[8]) SETUPDISTTABLE(8,1);
|
||||||
|
|
||||||
if (franticitems) // Frantic items make the distances between everyone artifically higher, for crazier items
|
if (franticitems) // Frantic items make the distances between everyone artifically higher, for crazier items
|
||||||
pdis = (15*pdis)/14;
|
pdis = (15 * pdis) / 14;
|
||||||
|
|
||||||
if (spbrush) // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell
|
if (spbrush) // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell
|
||||||
pdis = (3*pdis)/2;
|
pdis = (3 * pdis) / 2;
|
||||||
if (pingame < 8)
|
|
||||||
pdis = ((28+(8-pingame))*pdis)/28;
|
pdis = ((28 + (8-pingame)) * pdis) / 28;
|
||||||
|
|
||||||
if (pingame == 1 && oddsvalid[0]) // Record Attack, or just alone
|
if (pingame == 1 && oddsvalid[0]) // Record Attack, or just alone
|
||||||
useodds = 0;
|
useodds = 0;
|
||||||
|
@ -1097,6 +1068,26 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
||||||
|| (mobj2->player && mobj2->player->kartstuff[k_respawn]))
|
|| (mobj2->player && mobj2->player->kartstuff[k_respawn]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
{ // Don't bump if you're flashing
|
||||||
|
INT32 flash;
|
||||||
|
|
||||||
|
flash = K_GetKartFlashing(mobj1->player);
|
||||||
|
if (mobj1->player && mobj1->player->powers[pw_flashing] > 0 && mobj1->player->powers[pw_flashing] < flash)
|
||||||
|
{
|
||||||
|
if (mobj1->player->powers[pw_flashing] < flash-1)
|
||||||
|
mobj1->player->powers[pw_flashing]++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flash = K_GetKartFlashing(mobj2->player);
|
||||||
|
if (mobj2->player && mobj2->player->powers[pw_flashing] > 0 && mobj2->player->powers[pw_flashing] < flash)
|
||||||
|
{
|
||||||
|
if (mobj2->player->powers[pw_flashing] < flash-1)
|
||||||
|
mobj2->player->powers[pw_flashing]++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Don't bump if you've recently bumped
|
// Don't bump if you've recently bumped
|
||||||
if (mobj1->player && mobj1->player->kartstuff[k_justbumped])
|
if (mobj1->player && mobj1->player->kartstuff[k_justbumped])
|
||||||
{
|
{
|
||||||
|
@ -1211,8 +1202,8 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
||||||
mobj1->player->kartstuff[k_justbumped] = bumptime;
|
mobj1->player->kartstuff[k_justbumped] = bumptime;
|
||||||
if (mobj1->player->kartstuff[k_spinouttimer])
|
if (mobj1->player->kartstuff[k_spinouttimer])
|
||||||
{
|
{
|
||||||
mobj1->player->kartstuff[k_wipeoutslow] += wipeoutslowtime+1;
|
mobj1->player->kartstuff[k_wipeoutslow] = wipeoutslowtime+1;
|
||||||
mobj1->player->kartstuff[k_spinouttimer] += wipeoutslowtime+1;
|
mobj1->player->kartstuff[k_spinouttimer] = max(wipeoutslowtime+1, mobj1->player->kartstuff[k_spinouttimer]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,8 +1214,8 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
||||||
mobj2->player->kartstuff[k_justbumped] = bumptime;
|
mobj2->player->kartstuff[k_justbumped] = bumptime;
|
||||||
if (mobj2->player->kartstuff[k_spinouttimer])
|
if (mobj2->player->kartstuff[k_spinouttimer])
|
||||||
{
|
{
|
||||||
mobj2->player->kartstuff[k_wipeoutslow] += wipeoutslowtime+1;
|
mobj2->player->kartstuff[k_wipeoutslow] = wipeoutslowtime+1;
|
||||||
mobj2->player->kartstuff[k_spinouttimer] += wipeoutslowtime+1;
|
mobj2->player->kartstuff[k_spinouttimer] = max(wipeoutslowtime+1, mobj2->player->kartstuff[k_spinouttimer]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1248,9 +1239,8 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo, sector_t *sec)
|
||||||
for (i = 2; i < 5; i++)
|
for (i = 2; i < 5; i++)
|
||||||
{
|
{
|
||||||
if ((sec2 && GETSECSPECIAL(sec2->special, 1) == i)
|
if ((sec2 && GETSECSPECIAL(sec2->special, 1) == i)
|
||||||
|| (P_IsObjectOnRealGround(mo, sec)
|
|| (P_IsObjectOnRealGround(mo, sec) && GETSECSPECIAL(sec->special, 1) == i))
|
||||||
&& GETSECSPECIAL(sec->special, 1) == i))
|
return i-1;
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1264,33 +1254,20 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo, sector_t *sec)
|
||||||
*/
|
*/
|
||||||
static void K_UpdateOffroad(player_t *player)
|
static void K_UpdateOffroad(player_t *player)
|
||||||
{
|
{
|
||||||
fixed_t kartweight = player->kartweight;
|
|
||||||
fixed_t offroad;
|
fixed_t offroad;
|
||||||
sector_t *nextsector = R_PointInSubsector(
|
sector_t *nextsector = R_PointInSubsector(
|
||||||
player->mo->x + player->mo->momx*2, player->mo->y + player->mo->momy*2)->sector;
|
player->mo->x + player->mo->momx*2, player->mo->y + player->mo->momy*2)->sector;
|
||||||
|
UINT8 offroadstrength = K_CheckOffroadCollide(player->mo, nextsector);
|
||||||
|
|
||||||
fixed_t offroadstrength = 0;
|
// If you are in offroad, a timer starts.
|
||||||
|
|
||||||
if (K_CheckOffroadCollide(player->mo, nextsector) == 2) // Weak Offroad
|
|
||||||
offroadstrength = 1;
|
|
||||||
else if (K_CheckOffroadCollide(player->mo, nextsector) == 3) // Mid Offroad
|
|
||||||
offroadstrength = 2;
|
|
||||||
else if (K_CheckOffroadCollide(player->mo, nextsector) == 4) // Strong Offroad
|
|
||||||
offroadstrength = 3;
|
|
||||||
|
|
||||||
// If you are offroad, a timer starts. Depending on your weight value, the timer increments differently.
|
|
||||||
//if ((nextsector->special & 256) && nextsector->special != 768
|
|
||||||
// && nextsector->special != 1024 && nextsector->special != 4864)
|
|
||||||
if (offroadstrength)
|
if (offroadstrength)
|
||||||
{
|
{
|
||||||
if (K_CheckOffroadCollide(player->mo, player->mo->subsector->sector) && player->kartstuff[k_offroad] == 0)
|
if (K_CheckOffroadCollide(player->mo, player->mo->subsector->sector) && player->kartstuff[k_offroad] == 0)
|
||||||
player->kartstuff[k_offroad] = 16;
|
player->kartstuff[k_offroad] = (TICRATE/2);
|
||||||
|
|
||||||
if (player->kartstuff[k_offroad] > 0)
|
if (player->kartstuff[k_offroad] > 0)
|
||||||
{
|
{
|
||||||
// 1872 is the magic number - 35 frames adds up to approximately 65536. 1872/4 = 468/3 = 156
|
offroad = (offroadstrength << FRACBITS) / (TICRATE/2);
|
||||||
// A higher kart weight means you can stay offroad for longer without losing speed
|
|
||||||
offroad = (1872 + 5*156 - kartweight*156)*offroadstrength;
|
|
||||||
|
|
||||||
//if (player->kartstuff[k_growshrinktimer] > 1) // grow slows down half as fast
|
//if (player->kartstuff[k_growshrinktimer] > 1) // grow slows down half as fast
|
||||||
// offroad /= 2;
|
// offroad /= 2;
|
||||||
|
@ -1298,8 +1275,8 @@ static void K_UpdateOffroad(player_t *player)
|
||||||
player->kartstuff[k_offroad] += offroad;
|
player->kartstuff[k_offroad] += offroad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->kartstuff[k_offroad] > FRACUNIT*offroadstrength)
|
if (player->kartstuff[k_offroad] > (offroadstrength << FRACBITS))
|
||||||
player->kartstuff[k_offroad] = FRACUNIT*offroadstrength;
|
player->kartstuff[k_offroad] = (offroadstrength << FRACBITS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
player->kartstuff[k_offroad] = 0;
|
player->kartstuff[k_offroad] = 0;
|
||||||
|
@ -1548,7 +1525,7 @@ static void K_RegularVoiceTimers(player_t *player)
|
||||||
player->kartstuff[k_tauntvoices] = 4*TICRATE;
|
player->kartstuff[k_tauntvoices] = 4*TICRATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void K_PlayAttackTaunt(mobj_t *source)
|
void K_PlayAttackTaunt(mobj_t *source)
|
||||||
{
|
{
|
||||||
sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons
|
sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons
|
||||||
boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]);
|
boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]);
|
||||||
|
@ -1562,7 +1539,7 @@ static void K_PlayAttackTaunt(mobj_t *source)
|
||||||
K_TauntVoiceTimers(source->player);
|
K_TauntVoiceTimers(source->player);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void K_PlayBoostTaunt(mobj_t *source)
|
void K_PlayBoostTaunt(mobj_t *source)
|
||||||
{
|
{
|
||||||
sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons
|
sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons
|
||||||
boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]);
|
boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]);
|
||||||
|
@ -1576,7 +1553,7 @@ static void K_PlayBoostTaunt(mobj_t *source)
|
||||||
K_TauntVoiceTimers(source->player);
|
K_TauntVoiceTimers(source->player);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void K_PlayOvertakeSound(mobj_t *source)
|
void K_PlayOvertakeSound(mobj_t *source)
|
||||||
{
|
{
|
||||||
boolean tasteful = (!source->player || !source->player->kartstuff[k_voices]);
|
boolean tasteful = (!source->player || !source->player->kartstuff[k_voices]);
|
||||||
|
|
||||||
|
@ -1596,7 +1573,7 @@ static void K_PlayOvertakeSound(mobj_t *source)
|
||||||
K_RegularVoiceTimers(source->player);
|
K_RegularVoiceTimers(source->player);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void K_PlayHitEmSound(mobj_t *source)
|
void K_PlayHitEmSound(mobj_t *source)
|
||||||
{
|
{
|
||||||
if (cv_kartvoices.value)
|
if (cv_kartvoices.value)
|
||||||
S_StartSound(source, sfx_khitem);
|
S_StartSound(source, sfx_khitem);
|
||||||
|
@ -1606,7 +1583,7 @@ static void K_PlayHitEmSound(mobj_t *source)
|
||||||
K_RegularVoiceTimers(source->player);
|
K_RegularVoiceTimers(source->player);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void K_PlayPowerGloatSound(mobj_t *source)
|
void K_PlayPowerGloatSound(mobj_t *source)
|
||||||
{
|
{
|
||||||
if (cv_kartvoices.value)
|
if (cv_kartvoices.value)
|
||||||
S_StartSound(source, sfx_kgloat);
|
S_StartSound(source, sfx_kgloat);
|
||||||
|
@ -1649,10 +1626,8 @@ static void K_GetKartBoostPower(player_t *player)
|
||||||
&& player->kartstuff[k_offroad] >= 0)
|
&& player->kartstuff[k_offroad] >= 0)
|
||||||
boostpower = FixedDiv(boostpower, player->kartstuff[k_offroad] + FRACUNIT);
|
boostpower = FixedDiv(boostpower, player->kartstuff[k_offroad] + FRACUNIT);
|
||||||
|
|
||||||
if (player->kartstuff[k_itemtype] == KITEM_KITCHENSINK)
|
if (player->kartstuff[k_bananadrag] > TICRATE)
|
||||||
boostpower = max((TICRATE/2), (5*TICRATE)-(player->kartstuff[k_bananadrag]/2))*boostpower/(5*TICRATE);
|
boostpower = (4*boostpower)/5;
|
||||||
else if (player->kartstuff[k_bananadrag] > TICRATE)
|
|
||||||
boostpower = 4*boostpower/5;
|
|
||||||
|
|
||||||
// Banana drag/offroad dust
|
// Banana drag/offroad dust
|
||||||
if (boostpower < FRACUNIT
|
if (boostpower < FRACUNIT
|
||||||
|
@ -1771,11 +1746,17 @@ fixed_t K_GetKartAccel(player_t *player)
|
||||||
|
|
||||||
UINT16 K_GetKartFlashing(player_t *player)
|
UINT16 K_GetKartFlashing(player_t *player)
|
||||||
{
|
{
|
||||||
UINT16 tics = flashingtics;
|
UINT16 tics = flashingtics;
|
||||||
if (G_BattleGametype())
|
|
||||||
tics *= 2;
|
if (!player)
|
||||||
tics += (flashingtics/8) * (player->kartspeed);
|
return tics;
|
||||||
return tics;
|
|
||||||
|
if (G_BattleGametype())
|
||||||
|
tics *= 2;
|
||||||
|
|
||||||
|
tics += (flashingtics/8) * (player->kartspeed);
|
||||||
|
|
||||||
|
return tics;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove)
|
fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove)
|
||||||
|
@ -2534,7 +2515,17 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
|
||||||
break;
|
break;
|
||||||
case MT_JAWZ:
|
case MT_JAWZ:
|
||||||
if (source && source->player)
|
if (source && source->player)
|
||||||
|
{
|
||||||
|
INT32 lasttarg = source->player->kartstuff[k_lastjawztarget];
|
||||||
th->cvmem = source->player->skincolor;
|
th->cvmem = source->player->skincolor;
|
||||||
|
if ((lasttarg >= 0 && lasttarg < MAXPLAYERS)
|
||||||
|
&& playeringame[lasttarg]
|
||||||
|
&& !players[lasttarg].spectator
|
||||||
|
&& players[lasttarg].mo)
|
||||||
|
{
|
||||||
|
P_SetTarget(&th->tracer, players[lasttarg].mo);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
th->cvmem = SKINCOLOR_KETCHUP;
|
th->cvmem = SKINCOLOR_KETCHUP;
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
|
@ -3036,7 +3027,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
|
||||||
newz = player->mo->z;
|
newz = player->mo->z;
|
||||||
}
|
}
|
||||||
|
|
||||||
mo = P_SpawnMobj(newx, newy, newz, mapthing);
|
mo = P_SpawnMobj(newx, newy, newz, mapthing); // this will never return null because collision isn't processed here
|
||||||
|
|
||||||
if (P_MobjFlip(player->mo) < 0)
|
if (P_MobjFlip(player->mo) < 0)
|
||||||
mo->z = player->mo->z + player->mo->height - mo->height;
|
mo->z = player->mo->z + player->mo->height - mo->height;
|
||||||
|
@ -3048,7 +3039,9 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
|
||||||
{
|
{
|
||||||
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
|
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
|
||||||
// This should set it for FOFs
|
// This should set it for FOFs
|
||||||
P_TeleportMove(mo, mo->x, mo->y, mo->z);
|
P_TeleportMove(mo, mo->x, mo->y, mo->z); // however, THIS can fuck up your day. just absolutely ruin you.
|
||||||
|
if (P_MobjWasRemoved(mo))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (P_MobjFlip(mo) > 0)
|
if (P_MobjFlip(mo) > 0)
|
||||||
{
|
{
|
||||||
|
@ -3066,11 +3059,8 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mo)
|
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||||
{
|
mo->eflags |= MFE_VERTICALFLIP;
|
||||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
|
||||||
mo->eflags |= MFE_VERTICALFLIP;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3658,6 +3648,7 @@ static void K_MoveHeldObjects(player_t *player)
|
||||||
case MT_JAWZ_SHIELD:
|
case MT_JAWZ_SHIELD:
|
||||||
{
|
{
|
||||||
mobj_t *cur = player->mo->hnext;
|
mobj_t *cur = player->mo->hnext;
|
||||||
|
fixed_t speed = ((8 - min(4, player->kartstuff[k_itemamount])) * cur->info->speed) / 7;
|
||||||
|
|
||||||
player->kartstuff[k_bananadrag] = 0; // Just to make sure
|
player->kartstuff[k_bananadrag] = 0; // Just to make sure
|
||||||
|
|
||||||
|
@ -3675,10 +3666,10 @@ static void K_MoveHeldObjects(player_t *player)
|
||||||
cur->color = player->skincolor;
|
cur->color = player->skincolor;
|
||||||
|
|
||||||
cur->angle -= ANGLE_90;
|
cur->angle -= ANGLE_90;
|
||||||
cur->angle += FixedAngle(cur->info->speed);
|
cur->angle += FixedAngle(speed);
|
||||||
|
|
||||||
if (cur->extravalue1 < radius)
|
if (cur->extravalue1 < radius)
|
||||||
cur->extravalue1 += FixedMul(P_AproxDistance(cur->extravalue1, radius), FRACUNIT/12);
|
cur->extravalue1 += P_AproxDistance(cur->extravalue1, radius) / 12;
|
||||||
if (cur->extravalue1 > radius)
|
if (cur->extravalue1 > radius)
|
||||||
cur->extravalue1 = radius;
|
cur->extravalue1 = radius;
|
||||||
|
|
||||||
|
@ -3938,13 +3929,14 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source)
|
||||||
if (thisang > ANGLE_180)
|
if (thisang > ANGLE_180)
|
||||||
thisang = InvAngle(thisang);
|
thisang = InvAngle(thisang);
|
||||||
|
|
||||||
if (thisang > ANGLE_45) // Don't go for people who are behind you
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Jawz only go after the person directly ahead of you in race... sort of literally now!
|
// Jawz only go after the person directly ahead of you in race... sort of literally now!
|
||||||
if (G_RaceGametype())
|
if (G_RaceGametype())
|
||||||
{
|
{
|
||||||
if (player->kartstuff[k_position] >= source->kartstuff[k_position]) // Don't pay attention to people behind you
|
// Don't go for people who are behind you
|
||||||
|
if (thisang > ANGLE_67h)
|
||||||
|
continue;
|
||||||
|
// Don't pay attention to people who aren't above your position
|
||||||
|
if (player->kartstuff[k_position] >= source->kartstuff[k_position])
|
||||||
continue;
|
continue;
|
||||||
if ((best == -1) || (player->kartstuff[k_position] > best))
|
if ((best == -1) || (player->kartstuff[k_position] > best))
|
||||||
{
|
{
|
||||||
|
@ -3957,6 +3949,11 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source)
|
||||||
fixed_t thisdist;
|
fixed_t thisdist;
|
||||||
fixed_t thisavg;
|
fixed_t thisavg;
|
||||||
|
|
||||||
|
// Don't go for people who are behind you
|
||||||
|
if (thisang > ANGLE_45)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Don't pay attention to dead players
|
||||||
if (player->kartstuff[k_bumper] <= 0)
|
if (player->kartstuff[k_bumper] <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -4470,12 +4467,22 @@ void K_KartPlayerAfterThink(player_t *player)
|
||||||
// Jawz reticule (seeking)
|
// Jawz reticule (seeking)
|
||||||
if (player->kartstuff[k_itemtype] == KITEM_JAWZ && player->kartstuff[k_itemheld])
|
if (player->kartstuff[k_itemtype] == KITEM_JAWZ && player->kartstuff[k_itemheld])
|
||||||
{
|
{
|
||||||
player_t *targ = K_FindJawzTarget(player->mo, player);
|
INT32 lasttarg = player->kartstuff[k_lastjawztarget];
|
||||||
|
player_t *targ;
|
||||||
mobj_t *ret;
|
mobj_t *ret;
|
||||||
|
|
||||||
if (!targ)
|
if (player->kartstuff[k_jawztargetdelay] && playeringame[lasttarg] && !players[lasttarg].spectator)
|
||||||
|
{
|
||||||
|
targ = &players[lasttarg];
|
||||||
|
player->kartstuff[k_jawztargetdelay]--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
targ = K_FindJawzTarget(player->mo, player);
|
||||||
|
|
||||||
|
if (!targ || !targ->mo || P_MobjWasRemoved(targ->mo))
|
||||||
{
|
{
|
||||||
player->kartstuff[k_lastjawztarget] = -1;
|
player->kartstuff[k_lastjawztarget] = -1;
|
||||||
|
player->kartstuff[k_jawztargetdelay] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4485,7 +4492,7 @@ void K_KartPlayerAfterThink(player_t *player)
|
||||||
ret->tics = 1;
|
ret->tics = 1;
|
||||||
ret->color = player->skincolor;
|
ret->color = player->skincolor;
|
||||||
|
|
||||||
if (targ-players != player->kartstuff[k_lastjawztarget])
|
if (targ-players != lasttarg)
|
||||||
{
|
{
|
||||||
if (P_IsLocalPlayer(player) || P_IsLocalPlayer(targ))
|
if (P_IsLocalPlayer(player) || P_IsLocalPlayer(targ))
|
||||||
S_StartSound(NULL, sfx_s3k89);
|
S_StartSound(NULL, sfx_s3k89);
|
||||||
|
@ -4493,11 +4500,13 @@ void K_KartPlayerAfterThink(player_t *player)
|
||||||
S_StartSound(targ->mo, sfx_s3k89);
|
S_StartSound(targ->mo, sfx_s3k89);
|
||||||
|
|
||||||
player->kartstuff[k_lastjawztarget] = targ-players;
|
player->kartstuff[k_lastjawztarget] = targ-players;
|
||||||
|
player->kartstuff[k_jawztargetdelay] = 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
player->kartstuff[k_lastjawztarget] = -1;
|
player->kartstuff[k_lastjawztarget] = -1;
|
||||||
|
player->kartstuff[k_jawztargetdelay] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4670,8 +4679,6 @@ static void K_KartDrift(player_t *player, boolean onground)
|
||||||
player->kartstuff[k_driftend] = 0;
|
player->kartstuff[k_driftend] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Incease/decrease the drift value to continue drifting in that direction
|
// Incease/decrease the drift value to continue drifting in that direction
|
||||||
if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_jmp] == 1 && onground && player->kartstuff[k_drift] != 0)
|
if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_jmp] == 1 && onground && player->kartstuff[k_drift] != 0)
|
||||||
{
|
{
|
||||||
|
@ -4701,7 +4708,7 @@ static void K_KartDrift(player_t *player, boolean onground)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable drift-sparks until you're going fast enough
|
// Disable drift-sparks until you're going fast enough
|
||||||
if (player->kartstuff[k_getsparks] == 0)
|
if (player->kartstuff[k_getsparks] == 0 || player->kartstuff[k_offroad])
|
||||||
driftadditive = 0;
|
driftadditive = 0;
|
||||||
if (player->speed > minspeed*2)
|
if (player->speed > minspeed*2)
|
||||||
player->kartstuff[k_getsparks] = 1;
|
player->kartstuff[k_getsparks] = 1;
|
||||||
|
@ -5143,7 +5150,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
|
|
||||||
for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++)
|
for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++)
|
||||||
{
|
{
|
||||||
newangle = FixedAngle(((360/player->kartstuff[k_itemamount])*moloop)*FRACUNIT) + ANGLE_90;
|
newangle = (player->mo->angle + ANGLE_157h) + FixedAngle(((360 / player->kartstuff[k_itemamount]) * moloop) << FRACBITS) + ANGLE_90;
|
||||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ORBINAUT_SHIELD);
|
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ORBINAUT_SHIELD);
|
||||||
if (!mo)
|
if (!mo)
|
||||||
{
|
{
|
||||||
|
@ -5184,7 +5191,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
|
|
||||||
for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++)
|
for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++)
|
||||||
{
|
{
|
||||||
newangle = FixedAngle(((360/player->kartstuff[k_itemamount])*moloop)*FRACUNIT) + ANGLE_90;
|
newangle = (player->mo->angle + ANGLE_157h) + FixedAngle(((360 / player->kartstuff[k_itemamount]) * moloop) << FRACBITS) + ANGLE_90;
|
||||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_JAWZ_SHIELD);
|
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_JAWZ_SHIELD);
|
||||||
if (!mo)
|
if (!mo)
|
||||||
{
|
{
|
||||||
|
@ -5428,10 +5435,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Friction
|
// Friction
|
||||||
if (player->speed > 0 && cmd->forwardmove == 0 && player->mo->friction == 59392)
|
if (!player->kartstuff[k_offroad])
|
||||||
player->mo->friction += 4608;
|
{
|
||||||
if (player->speed > 0 && cmd->forwardmove < 0 && player->mo->friction == 59392)
|
if (player->speed > 0 && cmd->forwardmove == 0 && player->mo->friction == 59392)
|
||||||
player->mo->friction += 1608;
|
player->mo->friction += 4608;
|
||||||
|
if (player->speed > 0 && cmd->forwardmove < 0 && player->mo->friction == 59392)
|
||||||
|
player->mo->friction += 1608;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Karma ice physics
|
||||||
if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0)
|
if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0)
|
||||||
{
|
{
|
||||||
player->mo->friction += 1228;
|
player->mo->friction += 1228;
|
||||||
|
@ -5451,11 +5463,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
if (player->mo->movefactor < 32)
|
if (player->mo->movefactor < 32)
|
||||||
player->mo->movefactor = 32;
|
player->mo->movefactor = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wipeout slowdown
|
||||||
if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow])
|
if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow])
|
||||||
{
|
{
|
||||||
player->mo->friction -= FixedMul(1228, player->kartstuff[k_offroad]);
|
if (player->kartstuff[k_offroad])
|
||||||
if (player->kartstuff[k_wipeoutslow] == 1)
|
|
||||||
player->mo->friction -= 4912;
|
player->mo->friction -= 4912;
|
||||||
|
if (player->kartstuff[k_wipeoutslow] == 1)
|
||||||
|
player->mo->friction -= 9824;
|
||||||
}
|
}
|
||||||
|
|
||||||
K_KartDrift(player, onground);
|
K_KartDrift(player, onground);
|
||||||
|
@ -5744,9 +5759,22 @@ void K_CheckBumpers(void)
|
||||||
void K_CheckSpectateStatus(void)
|
void K_CheckSpectateStatus(void)
|
||||||
{
|
{
|
||||||
UINT8 respawnlist[MAXPLAYERS];
|
UINT8 respawnlist[MAXPLAYERS];
|
||||||
UINT8 i, numingame = 0, numjoiners = 0;
|
UINT8 i, j, numingame = 0, numjoiners = 0;
|
||||||
|
|
||||||
if (!cv_allowteamchange.value) return;
|
// Maintain spectate wait timer
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (!playeringame[i])
|
||||||
|
continue;
|
||||||
|
if (players[i].spectator && (players[i].pflags & PF_WANTSTOJOIN))
|
||||||
|
players[i].kartstuff[k_spectatewait]++;
|
||||||
|
else
|
||||||
|
players[i].kartstuff[k_spectatewait] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No one's allowed to join
|
||||||
|
if (!cv_allowteamchange.value)
|
||||||
|
return;
|
||||||
|
|
||||||
// Get the number of players in game, and the players to be de-spectated.
|
// Get the number of players in game, and the players to be de-spectated.
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
@ -5757,16 +5785,18 @@ void K_CheckSpectateStatus(void)
|
||||||
if (!players[i].spectator)
|
if (!players[i].spectator)
|
||||||
{
|
{
|
||||||
numingame++;
|
numingame++;
|
||||||
|
if (cv_ingamecap.value && numingame >= cv_ingamecap.value) // DON'T allow if you've hit the in-game player cap
|
||||||
|
return;
|
||||||
if (gamestate != GS_LEVEL) // Allow if you're not in a level
|
if (gamestate != GS_LEVEL) // Allow if you're not in a level
|
||||||
continue;
|
continue;
|
||||||
if (players[i].exiting) // DON'T allow if anyone's exiting
|
if (players[i].exiting) // DON'T allow if anyone's exiting
|
||||||
return;
|
return;
|
||||||
if (numingame < 2 || leveltime < starttime || mapreset) // Allow if the match hasn't started yet
|
if (numingame < 2 || leveltime < starttime || mapreset) // Allow if the match hasn't started yet
|
||||||
continue;
|
continue;
|
||||||
if (leveltime > (starttime + 20*TICRATE)) // DON'T allow if the match is 20 seconds in
|
if (leveltime > (starttime + 20*TICRATE)) // DON'T allow if the match is 20 seconds in
|
||||||
return;
|
return;
|
||||||
if (G_RaceGametype() && players[i].laps) // DON'T allow if the race is at 2 laps
|
if (G_RaceGametype() && players[i].laps) // DON'T allow if the race is at 2 laps
|
||||||
return;
|
return;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (!(players[i].pflags & PF_WANTSTOJOIN))
|
else if (!(players[i].pflags & PF_WANTSTOJOIN))
|
||||||
|
@ -5779,16 +5809,45 @@ void K_CheckSpectateStatus(void)
|
||||||
if (!numjoiners)
|
if (!numjoiners)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Reset the match if you're in an empty server
|
// Organize by spectate wait timer
|
||||||
if (!mapreset && gamestate == GS_LEVEL && leveltime >= starttime && (numingame < 2 && numingame+numjoiners >= 2))
|
if (cv_ingamecap.value)
|
||||||
{
|
{
|
||||||
S_ChangeMusicInternal("chalng", false); // COME ON
|
UINT8 oldrespawnlist[MAXPLAYERS];
|
||||||
mapreset = 3*TICRATE; // Even though only the server uses this for game logic, set for everyone for HUD in the future
|
memcpy(oldrespawnlist, respawnlist, numjoiners);
|
||||||
|
for (i = 0; i < numjoiners; i++)
|
||||||
|
{
|
||||||
|
UINT8 pos = 0;
|
||||||
|
INT32 ispecwait = players[oldrespawnlist[i]].kartstuff[k_spectatewait];
|
||||||
|
|
||||||
|
for (j = 0; j < numjoiners; j++)
|
||||||
|
{
|
||||||
|
INT32 jspecwait = players[oldrespawnlist[j]].kartstuff[k_spectatewait];
|
||||||
|
if (j == i)
|
||||||
|
continue;
|
||||||
|
if (jspecwait > ispecwait)
|
||||||
|
pos++;
|
||||||
|
else if (jspecwait == ispecwait && j < i)
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
respawnlist[pos] = oldrespawnlist[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, we can de-spectate everyone!
|
// Finally, we can de-spectate everyone!
|
||||||
for (i = 0; i < numjoiners; i++)
|
for (i = 0; i < numjoiners; i++)
|
||||||
|
{
|
||||||
|
if (cv_ingamecap.value && numingame+i >= cv_ingamecap.value) // Hit the in-game player cap while adding people?
|
||||||
|
break;
|
||||||
P_SpectatorJoinGame(&players[respawnlist[i]]);
|
P_SpectatorJoinGame(&players[respawnlist[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the match if you're in an empty server
|
||||||
|
if (!mapreset && gamestate == GS_LEVEL && leveltime >= starttime && (numingame < 2 && numingame+i >= 2)) // use previous i value
|
||||||
|
{
|
||||||
|
S_ChangeMusicInternal("chalng", false); // COME ON
|
||||||
|
mapreset = 3*TICRATE; // Even though only the server uses this for game logic, set for everyone for HUD
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
@ -7038,15 +7097,23 @@ static boolean K_drawKartPositionFaces(void)
|
||||||
colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE);
|
colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE);
|
||||||
|
|
||||||
V_DrawMappedPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, facerankprefix[players[rankplayer[i]].skin], colormap);
|
V_DrawMappedPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, facerankprefix[players[rankplayer[i]].skin], colormap);
|
||||||
if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_bumper] > 0)
|
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUA_HudEnabled(hud_battlebumpers))
|
||||||
{
|
{
|
||||||
V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_tinybumper[0], colormap);
|
#endif
|
||||||
for (j = 1; j < players[rankplayer[i]].kartstuff[k_bumper]; j++)
|
if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_bumper] > 0)
|
||||||
{
|
{
|
||||||
bumperx += 5;
|
V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_tinybumper[0], colormap);
|
||||||
V_DrawMappedPatch(bumperx, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_tinybumper[1], colormap);
|
for (j = 1; j < players[rankplayer[i]].kartstuff[k_bumper]; j++)
|
||||||
|
{
|
||||||
|
bumperx += 5;
|
||||||
|
V_DrawMappedPatch(bumperx, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_tinybumper[1], colormap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
#ifdef HAVE_BLUA
|
||||||
|
} // A new level of stupidity: checking if lua is enabled to close a bracket. :Fascinating:
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == strank)
|
if (i == strank)
|
||||||
|
@ -7145,12 +7212,24 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
||||||
if (G_RaceGametype())
|
if (G_RaceGametype())
|
||||||
{
|
{
|
||||||
#define timestring(time) va("%i'%02i\"%02i", G_TicsToMinutes(time, true), G_TicsToSeconds(time), G_TicsToCentiseconds(time))
|
#define timestring(time) va("%i'%02i\"%02i", G_TicsToMinutes(time, true), G_TicsToSeconds(time), G_TicsToCentiseconds(time))
|
||||||
if (players[tab[i].num].exiting)
|
if (scorelines > 8)
|
||||||
V_DrawRightAlignedString(x+rightoffset, y, hilicol, timestring(players[tab[i].num].realtime));
|
{
|
||||||
else if (players[tab[i].num].pflags & PF_TIMEOVER)
|
if (players[tab[i].num].exiting)
|
||||||
V_DrawRightAlignedThinString(x+rightoffset, y-1, 0, "NO CONTEST.");
|
V_DrawRightAlignedThinString(x+rightoffset, y-1, hilicol|V_6WIDTHSPACE, timestring(players[tab[i].num].realtime));
|
||||||
else if (circuitmap)
|
else if (players[tab[i].num].pflags & PF_TIMEOVER)
|
||||||
V_DrawRightAlignedString(x+rightoffset, y, 0, va("Lap %d", tab[i].count));
|
V_DrawRightAlignedThinString(x+rightoffset, y-1, V_6WIDTHSPACE, "NO CONTEST.");
|
||||||
|
else if (circuitmap)
|
||||||
|
V_DrawRightAlignedThinString(x+rightoffset, y-1, V_6WIDTHSPACE, va("Lap %d", tab[i].count));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (players[tab[i].num].exiting)
|
||||||
|
V_DrawRightAlignedString(x+rightoffset, y, hilicol, timestring(players[tab[i].num].realtime));
|
||||||
|
else if (players[tab[i].num].pflags & PF_TIMEOVER)
|
||||||
|
V_DrawRightAlignedThinString(x+rightoffset, y-1, 0, "NO CONTEST.");
|
||||||
|
else if (circuitmap)
|
||||||
|
V_DrawRightAlignedString(x+rightoffset, y, 0, va("Lap %d", tab[i].count));
|
||||||
|
}
|
||||||
#undef timestring
|
#undef timestring
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -7853,7 +7932,10 @@ static void K_drawBattleFullscreen(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
K_drawKartFreePlay(leveltime);
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUA_HudEnabled(hud_freeplay))
|
||||||
|
#endif
|
||||||
|
K_drawKartFreePlay(leveltime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8304,6 +8386,7 @@ static void K_drawCheckpointDebugger(void)
|
||||||
void K_drawKartHUD(void)
|
void K_drawKartHUD(void)
|
||||||
{
|
{
|
||||||
boolean isfreeplay = false;
|
boolean isfreeplay = false;
|
||||||
|
boolean battlefullscreen = false;
|
||||||
|
|
||||||
// Define the X and Y for each drawn object
|
// Define the X and Y for each drawn object
|
||||||
// This is handled by console/menu values
|
// This is handled by console/menu values
|
||||||
|
@ -8316,14 +8399,6 @@ void K_drawKartHUD(void)
|
||||||
|| ((splitscreen > 2 && stplyr == &players[fourthdisplayplayer]) && !camera4.chase))
|
|| ((splitscreen > 2 && stplyr == &players[fourthdisplayplayer]) && !camera4.chase))
|
||||||
K_drawKartFirstPerson();
|
K_drawKartFirstPerson();
|
||||||
|
|
||||||
/* if (splitscreen == 2) // Player 4 in 3P is the minimap :p
|
|
||||||
{
|
|
||||||
#ifdef HAVE_BLUA
|
|
||||||
if (LUA_HudEnabled(hud_minimap))
|
|
||||||
#endif
|
|
||||||
K_drawKartMinimap();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Draw full screen stuff that turns off the rest of the HUD
|
// Draw full screen stuff that turns off the rest of the HUD
|
||||||
if (mapreset && stplyr == &players[displayplayer])
|
if (mapreset && stplyr == &players[displayplayer])
|
||||||
{
|
{
|
||||||
|
@ -8331,39 +8406,43 @@ void K_drawKartHUD(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((G_BattleGametype())
|
battlefullscreen = ((G_BattleGametype())
|
||||||
&& (stplyr->exiting
|
&& (stplyr->exiting
|
||||||
|| (stplyr->kartstuff[k_bumper] <= 0
|
|| (stplyr->kartstuff[k_bumper] <= 0
|
||||||
&& stplyr->kartstuff[k_comebacktimer]
|
&& stplyr->kartstuff[k_comebacktimer]
|
||||||
&& comeback
|
&& comeback
|
||||||
&& stplyr->playerstate == PST_LIVE)))
|
&& stplyr->playerstate == PST_LIVE)));
|
||||||
|
|
||||||
|
if (!battlefullscreen || splitscreen)
|
||||||
|
{
|
||||||
|
// Draw the CHECK indicator before the other items, so it's overlapped by everything else
|
||||||
|
if (cv_kartcheck.value && !splitscreen && !players[displayplayer].exiting)
|
||||||
|
K_drawKartPlayerCheck();
|
||||||
|
|
||||||
|
// Draw WANTED status
|
||||||
|
if (G_BattleGametype())
|
||||||
|
{
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUA_HudEnabled(hud_wanted))
|
||||||
|
#endif
|
||||||
|
K_drawKartWanted();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cv_kartminimap.value && !titledemo)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUA_HudEnabled(hud_minimap))
|
||||||
|
#endif
|
||||||
|
K_drawKartMinimap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (battlefullscreen)
|
||||||
{
|
{
|
||||||
K_drawBattleFullscreen();
|
K_drawBattleFullscreen();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the CHECK indicator before the other items, so it's overlapped by everything else
|
|
||||||
if (cv_kartcheck.value && !splitscreen && !players[displayplayer].exiting)
|
|
||||||
K_drawKartPlayerCheck();
|
|
||||||
|
|
||||||
// Draw WANTED status
|
|
||||||
if (G_BattleGametype())
|
|
||||||
{
|
|
||||||
#ifdef HAVE_BLUA
|
|
||||||
if (LUA_HudEnabled(hud_wanted))
|
|
||||||
#endif
|
|
||||||
K_drawKartWanted();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cv_kartminimap.value && !titledemo)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_BLUA
|
|
||||||
if (LUA_HudEnabled(hud_minimap))
|
|
||||||
#endif
|
|
||||||
K_drawKartMinimap(); // 3P splitscreen is handled above
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the item window
|
// Draw the item window
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUA_HudEnabled(hud_item))
|
if (LUA_HudEnabled(hud_item))
|
||||||
|
@ -8475,7 +8554,12 @@ void K_drawKartHUD(void)
|
||||||
|
|
||||||
// Draw FREE PLAY.
|
// Draw FREE PLAY.
|
||||||
if (isfreeplay && !stplyr->spectator && timeinmap > 113)
|
if (isfreeplay && !stplyr->spectator && timeinmap > 113)
|
||||||
K_drawKartFreePlay(leveltime);
|
{
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUA_HudEnabled(hud_freeplay))
|
||||||
|
#endif
|
||||||
|
K_drawKartFreePlay(leveltime);
|
||||||
|
}
|
||||||
|
|
||||||
if (cv_kartdebugdistribution.value)
|
if (cv_kartdebugdistribution.value)
|
||||||
K_drawDistributionDebugger();
|
K_drawDistributionDebugger();
|
||||||
|
|
|
@ -65,6 +65,13 @@ void K_CalculateBattleWanted(void);
|
||||||
void K_CheckBumpers(void);
|
void K_CheckBumpers(void);
|
||||||
void K_CheckSpectateStatus(void);
|
void K_CheckSpectateStatus(void);
|
||||||
|
|
||||||
|
// sound stuff for lua
|
||||||
|
void K_PlayAttackTaunt(mobj_t *source);
|
||||||
|
void K_PlayBoostTaunt(mobj_t *source);
|
||||||
|
void K_PlayOvertakeSound(mobj_t *source);
|
||||||
|
void K_PlayHitEmSound(mobj_t *source);
|
||||||
|
void K_PlayPowerGloatSound(mobj_t *source);
|
||||||
|
|
||||||
const char *K_GetItemPatch(UINT8 item, boolean tiny);
|
const char *K_GetItemPatch(UINT8 item, boolean tiny);
|
||||||
INT32 K_calcSplitFlags(INT32 snapflags);
|
INT32 K_calcSplitFlags(INT32 snapflags);
|
||||||
void K_LoadKartHUDGraphics(void);
|
void K_LoadKartHUDGraphics(void);
|
||||||
|
|
|
@ -31,9 +31,10 @@
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
#include "lua_hud.h" // hud_running errors
|
#include "lua_hud.h" // hud_running errors
|
||||||
|
#include "lua_hook.h" // hook_cmd_running
|
||||||
|
|
||||||
#define NOHUD if (hud_running) return luaL_error(L, "HUD rendering code should not call this function!");
|
#define NOHUD if (hud_running) return luaL_error(L, "HUD rendering code should not call this function!"); else if (hook_cmd_running) return luaL_error(L, "CMD Building code should not call this function!");
|
||||||
|
// Yes technically cmd hook isn't a hud but whatever, this avoids having 2 defines for virtually the same thing.
|
||||||
|
|
||||||
boolean luaL_checkboolean(lua_State *L, int narg) {
|
boolean luaL_checkboolean(lua_State *L, int narg) {
|
||||||
luaL_checktype(L, narg, LUA_TBOOLEAN);
|
luaL_checktype(L, narg, LUA_TBOOLEAN);
|
||||||
|
@ -2131,6 +2132,72 @@ static int lib_gTicsToMilliseconds(lua_State *L)
|
||||||
// K_KART
|
// K_KART
|
||||||
////////////
|
////////////
|
||||||
|
|
||||||
|
// Seriously, why weren't those exposed before?
|
||||||
|
static int lib_kAttackSound(lua_State *L)
|
||||||
|
{
|
||||||
|
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||||
|
NOHUD
|
||||||
|
if (!mobj->player)
|
||||||
|
return luaL_error(L, "K_PlayAttackTaunt: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||||
|
K_PlayAttackTaunt(mobj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_kBoostSound(lua_State *L)
|
||||||
|
{
|
||||||
|
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||||
|
NOHUD
|
||||||
|
if (!mobj->player)
|
||||||
|
return luaL_error(L, "K_PlayBoostTaunt: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||||
|
K_PlayBoostTaunt(mobj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_kOvertakeSound(lua_State *L)
|
||||||
|
{
|
||||||
|
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||||
|
NOHUD
|
||||||
|
if (!mobj->player)
|
||||||
|
return luaL_error(L, "K_PlayOvertakeSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||||
|
K_PlayOvertakeSound(mobj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_kHitEmSound(lua_State *L)
|
||||||
|
{
|
||||||
|
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||||
|
NOHUD
|
||||||
|
if (!mobj->player)
|
||||||
|
return luaL_error(L, "K_PlayHitEmSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||||
|
K_PlayHitEmSound(mobj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_kGloatSound(lua_State *L)
|
||||||
|
{
|
||||||
|
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||||
|
NOHUD
|
||||||
|
if (!mobj->player)
|
||||||
|
return luaL_error(L, "K_PlayPowerGloatSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||||
|
K_PlayPowerGloatSound(mobj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_kLossSound(lua_State *L)
|
||||||
|
{
|
||||||
|
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); // let's require a mobj for consistency with the other functions
|
||||||
|
sfxenum_t sfx_id;
|
||||||
|
NOHUD
|
||||||
|
if (!mobj->player)
|
||||||
|
return luaL_error(L, "K_PlayLossSound: mobj_t isn't a player object.");
|
||||||
|
|
||||||
|
sfx_id = ((skin_t *)mobj->skin)->soundsid[S_sfx[sfx_klose].skinsound];
|
||||||
|
S_StartSound(mobj, sfx_id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Pain, Death and Victory are already exposed.
|
||||||
|
|
||||||
static int lib_kGetKartColorByName(lua_State *L)
|
static int lib_kGetKartColorByName(lua_State *L)
|
||||||
{
|
{
|
||||||
const char *name = luaL_checkstring(L, 1);
|
const char *name = luaL_checkstring(L, 1);
|
||||||
|
@ -2697,6 +2764,12 @@ static luaL_Reg lib[] = {
|
||||||
{"G_TicsToMilliseconds",lib_gTicsToMilliseconds},
|
{"G_TicsToMilliseconds",lib_gTicsToMilliseconds},
|
||||||
|
|
||||||
// k_kart
|
// k_kart
|
||||||
|
{"K_PlayAttackTaunt", lib_kAttackSound},
|
||||||
|
{"K_PlayBoostTaunt", lib_kBoostSound},
|
||||||
|
{"K_PlayPowerGloatSund", lib_kGloatSound},
|
||||||
|
{"K_PlayOvertakeSound", lib_kOvertakeSound},
|
||||||
|
{"K_PlayLossSound", lib_kLossSound},
|
||||||
|
{"K_PlayHitEmSound", lib_kHitEmSound},
|
||||||
{"K_GetKartColorByName",lib_kGetKartColorByName},
|
{"K_GetKartColorByName",lib_kGetKartColorByName},
|
||||||
{"K_IsPlayerLosing",lib_kIsPlayerLosing},
|
{"K_IsPlayerLosing",lib_kIsPlayerLosing},
|
||||||
{"K_IsPlayerWanted",lib_kIsPlayerWanted},
|
{"K_IsPlayerWanted",lib_kIsPlayerWanted},
|
||||||
|
|
|
@ -50,11 +50,14 @@ enum hook {
|
||||||
hook_PlayerSpin, //SRB2KART
|
hook_PlayerSpin, //SRB2KART
|
||||||
hook_PlayerExplode, //SRB2KART
|
hook_PlayerExplode, //SRB2KART
|
||||||
hook_PlayerSquish, //SRB2KART
|
hook_PlayerSquish, //SRB2KART
|
||||||
|
hook_PlayerCmd, //SRB2KART
|
||||||
|
|
||||||
hook_MAX // last hook
|
hook_MAX // last hook
|
||||||
};
|
};
|
||||||
extern const char *const hookNames[];
|
extern const char *const hookNames[];
|
||||||
|
|
||||||
|
extern boolean hook_cmd_running; // This is used by PlayerCmd and lua_playerlib to prevent anything from being wirtten to player while we run PlayerCmd.
|
||||||
|
|
||||||
void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load)
|
void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load)
|
||||||
void LUAh_MapLoad(void); // Hook for map load
|
void LUAh_MapLoad(void); // Hook for map load
|
||||||
void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer
|
void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer
|
||||||
|
@ -93,4 +96,7 @@ UINT8 LUAh_ShouldSquish(player_t *player, mobj_t *inflictor, mobj_t *source); //
|
||||||
boolean LUAh_PlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SpinPlayer. Allows Lua to execute code and/or overwrite its behavior.
|
boolean LUAh_PlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SpinPlayer. Allows Lua to execute code and/or overwrite its behavior.
|
||||||
boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_ExplodePlayer. Allows Lua to execute code and/or overwrite its behavior.
|
boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_ExplodePlayer. Allows Lua to execute code and/or overwrite its behavior.
|
||||||
boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SquishPlayer. Allows Lua to execute code and/or overwrite its behavior.
|
boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SquishPlayer. Allows Lua to execute code and/or overwrite its behavior.
|
||||||
|
|
||||||
|
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to player cmd before the game does anything with them.
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,6 +61,7 @@ const char *const hookNames[hook_MAX+1] = {
|
||||||
"PlayerSpin",
|
"PlayerSpin",
|
||||||
"PlayerExplode",
|
"PlayerExplode",
|
||||||
"PlayerSquish",
|
"PlayerSquish",
|
||||||
|
"PlayerCmd",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -877,6 +878,47 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd)
|
||||||
return hooked;
|
return hooked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hook for G_BuildTicCmd
|
||||||
|
boolean hook_cmd_running = false;
|
||||||
|
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd)
|
||||||
|
{
|
||||||
|
hook_p hookp;
|
||||||
|
boolean hooked = false;
|
||||||
|
if (!gL || !(hooksAvailable[hook_PlayerCmd/8] & (1<<(hook_PlayerCmd%8))))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
lua_settop(gL, 0);
|
||||||
|
|
||||||
|
hook_cmd_running = true;
|
||||||
|
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||||
|
if (hookp->type == hook_PlayerCmd)
|
||||||
|
{
|
||||||
|
if (lua_gettop(gL) == 0)
|
||||||
|
{
|
||||||
|
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||||
|
LUA_PushUserdata(gL, cmd, META_TICCMD);
|
||||||
|
}
|
||||||
|
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||||
|
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
|
if (!hookp->error || cv_debug & DBG_LUA)
|
||||||
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
hookp->error = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (lua_toboolean(gL, -1))
|
||||||
|
hooked = true;
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
hook_cmd_running = false;
|
||||||
|
lua_settop(gL, 0);
|
||||||
|
return hooked;
|
||||||
|
}
|
||||||
|
|
||||||
// Hook for B_BuildTailsTiccmd by skin name
|
// Hook for B_BuildTailsTiccmd by skin name
|
||||||
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
|
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,8 +20,10 @@ enum hud {
|
||||||
hud_item,
|
hud_item,
|
||||||
hud_position,
|
hud_position,
|
||||||
hud_minirankings, // Rankings to the left
|
hud_minirankings, // Rankings to the left
|
||||||
|
hud_battlebumpers, // mini rankings battle bumpers.
|
||||||
hud_wanted,
|
hud_wanted,
|
||||||
hud_speedometer,
|
hud_speedometer,
|
||||||
|
hud_freeplay,
|
||||||
hud_rankings, // Tab rankings
|
hud_rankings, // Tab rankings
|
||||||
|
|
||||||
hud_MAX
|
hud_MAX
|
||||||
|
|
|
@ -34,6 +34,8 @@ static UINT8 hud_enabled[(hud_MAX/8)+1];
|
||||||
|
|
||||||
static UINT8 hudAvailable; // hud hooks field
|
static UINT8 hudAvailable; // hud hooks field
|
||||||
|
|
||||||
|
static UINT8 camnum = 1;
|
||||||
|
|
||||||
// must match enum hud in lua_hud.h
|
// must match enum hud in lua_hud.h
|
||||||
static const char *const hud_disable_options[] = {
|
static const char *const hud_disable_options[] = {
|
||||||
"stagetitle",
|
"stagetitle",
|
||||||
|
@ -45,8 +47,10 @@ static const char *const hud_disable_options[] = {
|
||||||
"item",
|
"item",
|
||||||
"position",
|
"position",
|
||||||
"minirankings", // Gametype rankings to the left
|
"minirankings", // Gametype rankings to the left
|
||||||
|
"battlerankingsbumpers", // bumper drawer for battle. Useful if you want to make a custom battle gamemode without bumpers being involved.
|
||||||
"wanted",
|
"wanted",
|
||||||
"speedometer",
|
"speedometer",
|
||||||
|
"freeplay",
|
||||||
"rankings",
|
"rankings",
|
||||||
NULL};
|
NULL};
|
||||||
|
|
||||||
|
@ -132,7 +136,8 @@ enum cameraf {
|
||||||
camera_height,
|
camera_height,
|
||||||
camera_momx,
|
camera_momx,
|
||||||
camera_momy,
|
camera_momy,
|
||||||
camera_momz
|
camera_momz,
|
||||||
|
camera_pnum
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,6 +156,7 @@ static const char *const camera_opt[] = {
|
||||||
"momx",
|
"momx",
|
||||||
"momy",
|
"momy",
|
||||||
"momz",
|
"momz",
|
||||||
|
"pnum",
|
||||||
NULL};
|
NULL};
|
||||||
|
|
||||||
static int lib_getHudInfo(lua_State *L)
|
static int lib_getHudInfo(lua_State *L)
|
||||||
|
@ -306,6 +312,9 @@ static int camera_get(lua_State *L)
|
||||||
case camera_momz:
|
case camera_momz:
|
||||||
lua_pushinteger(L, cam->momz);
|
lua_pushinteger(L, cam->momz);
|
||||||
break;
|
break;
|
||||||
|
case camera_pnum:
|
||||||
|
lua_pushinteger(L, camnum);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -482,6 +491,20 @@ static int libd_drawString(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int libd_drawKartString(lua_State *L)
|
||||||
|
{
|
||||||
|
fixed_t x = luaL_checkinteger(L, 1);
|
||||||
|
fixed_t y = luaL_checkinteger(L, 2);
|
||||||
|
const char *str = luaL_checkstring(L, 3);
|
||||||
|
INT32 flags = luaL_optinteger(L, 4, V_ALLOWLOWERCASE);
|
||||||
|
|
||||||
|
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||||
|
|
||||||
|
HUDONLY
|
||||||
|
V_DrawKartString(x, y, flags, str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int libd_stringWidth(lua_State *L)
|
static int libd_stringWidth(lua_State *L)
|
||||||
{
|
{
|
||||||
const char *str = luaL_checkstring(L, 1);
|
const char *str = luaL_checkstring(L, 1);
|
||||||
|
@ -593,6 +616,7 @@ static luaL_Reg lib_draw[] = {
|
||||||
{"drawFill", libd_drawFill},
|
{"drawFill", libd_drawFill},
|
||||||
{"fadeScreen", libd_fadeScreen},
|
{"fadeScreen", libd_fadeScreen},
|
||||||
{"drawString", libd_drawString},
|
{"drawString", libd_drawString},
|
||||||
|
{"drawKartString", libd_drawKartString},
|
||||||
{"stringWidth", libd_stringWidth},
|
{"stringWidth", libd_stringWidth},
|
||||||
{"getColormap", libd_getColormap},
|
{"getColormap", libd_getColormap},
|
||||||
{"width", libd_width},
|
{"width", libd_width},
|
||||||
|
@ -755,13 +779,25 @@ void LUAh_GameHUD(player_t *stplayr)
|
||||||
LUA_PushUserdata(gL, stplayr, META_PLAYER);
|
LUA_PushUserdata(gL, stplayr, META_PLAYER);
|
||||||
|
|
||||||
if (splitscreen > 2 && stplayr == &players[fourthdisplayplayer])
|
if (splitscreen > 2 && stplayr == &players[fourthdisplayplayer])
|
||||||
|
{
|
||||||
LUA_PushUserdata(gL, &camera4, META_CAMERA);
|
LUA_PushUserdata(gL, &camera4, META_CAMERA);
|
||||||
|
camnum = 4;
|
||||||
|
}
|
||||||
else if (splitscreen > 1 && stplayr == &players[thirddisplayplayer])
|
else if (splitscreen > 1 && stplayr == &players[thirddisplayplayer])
|
||||||
|
{
|
||||||
LUA_PushUserdata(gL, &camera3, META_CAMERA);
|
LUA_PushUserdata(gL, &camera3, META_CAMERA);
|
||||||
|
camnum = 3;
|
||||||
|
}
|
||||||
else if (splitscreen && stplayr == &players[secondarydisplayplayer])
|
else if (splitscreen && stplayr == &players[secondarydisplayplayer])
|
||||||
|
{
|
||||||
LUA_PushUserdata(gL, &camera2, META_CAMERA);
|
LUA_PushUserdata(gL, &camera2, META_CAMERA);
|
||||||
|
camnum = 2;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
LUA_PushUserdata(gL, &camera, META_CAMERA);
|
LUA_PushUserdata(gL, &camera, META_CAMERA);
|
||||||
|
camnum = 1;
|
||||||
|
}
|
||||||
|
|
||||||
lua_pushnil(gL);
|
lua_pushnil(gL);
|
||||||
while (lua_next(gL, -5) != 0) {
|
while (lua_next(gL, -5) != 0) {
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
#include "lua_hud.h" // hud_running errors
|
#include "lua_hud.h" // hud_running errors
|
||||||
|
#include "lua_hook.h" // cmd errors
|
||||||
|
|
||||||
boolean LUA_CallAction(const char *action, mobj_t *actor);
|
boolean LUA_CallAction(const char *action, mobj_t *actor);
|
||||||
state_t *astate;
|
state_t *astate;
|
||||||
|
@ -169,6 +170,8 @@ static int lib_setState(lua_State *L)
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter states in HUD rendering code!");
|
return luaL_error(L, "Do not alter states in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter states in BuildCMD code!");
|
||||||
|
|
||||||
// clear the state to start with, in case of missing table elements
|
// clear the state to start with, in case of missing table elements
|
||||||
memset(state,0,sizeof(state_t));
|
memset(state,0,sizeof(state_t));
|
||||||
|
@ -378,6 +381,8 @@ static int state_set(lua_State *L)
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter states in HUD rendering code!");
|
return luaL_error(L, "Do not alter states in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter states in BuildCMD code!");
|
||||||
|
|
||||||
if (fastcmp(field,"sprite")) {
|
if (fastcmp(field,"sprite")) {
|
||||||
value = luaL_checknumber(L, 3);
|
value = luaL_checknumber(L, 3);
|
||||||
|
@ -466,6 +471,8 @@ static int lib_setMobjInfo(lua_State *L)
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter mobjinfo in HUD rendering code!");
|
return luaL_error(L, "Do not alter mobjinfo in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter mobjinfo in BuildCMD code!");
|
||||||
|
|
||||||
// clear the mobjinfo to start with, in case of missing table elements
|
// clear the mobjinfo to start with, in case of missing table elements
|
||||||
memset(info,0,sizeof(mobjinfo_t));
|
memset(info,0,sizeof(mobjinfo_t));
|
||||||
|
@ -633,6 +640,8 @@ static int mobjinfo_set(lua_State *L)
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter mobjinfo in HUD rendering code!");
|
return luaL_error(L, "Do not alter mobjinfo in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter mobjinfo in BuildCMD code!");
|
||||||
|
|
||||||
I_Assert(info != NULL);
|
I_Assert(info != NULL);
|
||||||
I_Assert(info >= mobjinfo);
|
I_Assert(info >= mobjinfo);
|
||||||
|
@ -755,6 +764,8 @@ static int lib_setSfxInfo(lua_State *L)
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter sfxinfo in HUD rendering code!");
|
return luaL_error(L, "Do not alter sfxinfo in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter sfxinfo in BuildCMD code!");
|
||||||
|
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next(L, 1)) {
|
while (lua_next(L, 1)) {
|
||||||
|
@ -830,6 +841,8 @@ static int sfxinfo_set(lua_State *L)
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter S_sfx in HUD rendering code!");
|
return luaL_error(L, "Do not alter S_sfx in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter S_sfx in BuildCMD code!");
|
||||||
|
|
||||||
I_Assert(sfx != NULL);
|
I_Assert(sfx != NULL);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
#include "lua_hud.h" // hud_running errors
|
#include "lua_hud.h" // hud_running errors
|
||||||
|
#include "lua_hook.h" // cmd errors
|
||||||
|
|
||||||
#include "dehacked.h"
|
#include "dehacked.h"
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
|
@ -484,6 +485,8 @@ static int sector_set(lua_State *L)
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter sector_t in HUD rendering code!");
|
return luaL_error(L, "Do not alter sector_t in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter sector_t in BuildCMD code!");
|
||||||
|
|
||||||
switch(field)
|
switch(field)
|
||||||
{
|
{
|
||||||
|
@ -1174,6 +1177,8 @@ static int ffloor_set(lua_State *L)
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter ffloor_t in HUD rendering code!");
|
return luaL_error(L, "Do not alter ffloor_t in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter ffloor_t in BuildCMD code!");
|
||||||
|
|
||||||
switch(field)
|
switch(field)
|
||||||
{
|
{
|
||||||
|
@ -1303,6 +1308,8 @@ static int slope_set(lua_State *L)
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter pslope_t in HUD rendering code!");
|
return luaL_error(L, "Do not alter pslope_t in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter pslope_t in BuildCMD code!");
|
||||||
|
|
||||||
switch(field) // todo: reorganize this shit
|
switch(field) // todo: reorganize this shit
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
#include "lua_hud.h" // hud_running errors
|
#include "lua_hud.h" // hud_running errors
|
||||||
|
#include "lua_hook.h" // cmd errors
|
||||||
|
|
||||||
static const char *const array_opt[] ={"iterate",NULL};
|
static const char *const array_opt[] ={"iterate",NULL};
|
||||||
|
|
||||||
|
@ -391,6 +392,9 @@ static int mobj_set(lua_State *L)
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter mobj_t in HUD rendering code!");
|
return luaL_error(L, "Do not alter mobj_t in HUD rendering code!");
|
||||||
|
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter mobj_t in BuildCMD code!");
|
||||||
|
|
||||||
switch(field)
|
switch(field)
|
||||||
{
|
{
|
||||||
case mobj_valid:
|
case mobj_valid:
|
||||||
|
@ -756,6 +760,8 @@ static int mapthing_set(lua_State *L)
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter mapthing_t in HUD rendering code!");
|
return luaL_error(L, "Do not alter mapthing_t in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter mapthing_t in BuildCMD code!");
|
||||||
|
|
||||||
if(fastcmp(field,"x"))
|
if(fastcmp(field,"x"))
|
||||||
mt->x = (INT16)luaL_checkinteger(L, 3);
|
mt->x = (INT16)luaL_checkinteger(L, 3);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
#include "lua_hud.h" // hud_running errors
|
#include "lua_hud.h" // hud_running errors
|
||||||
|
#include "lua_hook.h" // hook_cmd_running
|
||||||
|
|
||||||
static int lib_iteratePlayers(lua_State *L)
|
static int lib_iteratePlayers(lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -356,6 +357,9 @@ static int player_set(lua_State *L)
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||||
|
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
|
||||||
|
|
||||||
if (fastcmp(field,"mo")) {
|
if (fastcmp(field,"mo")) {
|
||||||
mobj_t *newmo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
mobj_t *newmo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||||
plr->mo->player = NULL; // remove player pointer from old mobj
|
plr->mo->player = NULL; // remove player pointer from old mobj
|
||||||
|
@ -667,6 +671,8 @@ static int power_set(lua_State *L)
|
||||||
return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p);
|
return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p);
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
|
||||||
powers[p] = i;
|
powers[p] = i;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -699,6 +705,8 @@ static int kartstuff_set(lua_State *L)
|
||||||
return luaL_error(L, LUA_QL("kartstufftype_t") " cannot be %u", ks);
|
return luaL_error(L, LUA_QL("kartstufftype_t") " cannot be %u", ks);
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||||
|
if (hook_cmd_running)
|
||||||
|
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
|
||||||
kartstuff[ks] = i;
|
kartstuff[ks] = i;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,6 +212,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
|
||||||
|
|
||||||
LUA_LoadFile(&f, name); // actually load file!
|
LUA_LoadFile(&f, name); // actually load file!
|
||||||
|
|
||||||
|
// Okay, we've modified the game beyond the point of no return.
|
||||||
|
G_SetGameModified(multiplayer, true);
|
||||||
|
|
||||||
free(name);
|
free(name);
|
||||||
Z_Free(f.data);
|
Z_Free(f.data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ static UINT8 cheatf_devmode(void)
|
||||||
S_StartSound(0, sfx_itemup);
|
S_StartSound(0, sfx_itemup);
|
||||||
|
|
||||||
// Just unlock all the things and turn on -debug and console devmode.
|
// Just unlock all the things and turn on -debug and console devmode.
|
||||||
G_SetGameModified(false);
|
G_SetGameModified(false, false); // might need to revist the latter later
|
||||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||||
unlockables[i].unlocked = true;
|
unlockables[i].unlocked = true;
|
||||||
devparm = true;
|
devparm = true;
|
||||||
|
@ -295,7 +295,7 @@ void Command_CheatNoClip_f(void)
|
||||||
plyr->pflags ^= PF_NOCLIP;
|
plyr->pflags ^= PF_NOCLIP;
|
||||||
CONS_Printf(M_GetText("No Clipping %s\n"), plyr->pflags & PF_NOCLIP ? M_GetText("On") : M_GetText("Off"));
|
CONS_Printf(M_GetText("No Clipping %s\n"), plyr->pflags & PF_NOCLIP ? M_GetText("On") : M_GetText("Off"));
|
||||||
|
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_CheatGod_f(void)
|
void Command_CheatGod_f(void)
|
||||||
|
@ -310,7 +310,7 @@ void Command_CheatGod_f(void)
|
||||||
plyr->pflags ^= PF_GODMODE;
|
plyr->pflags ^= PF_GODMODE;
|
||||||
CONS_Printf(M_GetText("Sissy Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off"));
|
CONS_Printf(M_GetText("Sissy Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off"));
|
||||||
|
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_CheatNoTarget_f(void)
|
void Command_CheatNoTarget_f(void)
|
||||||
|
@ -325,7 +325,7 @@ void Command_CheatNoTarget_f(void)
|
||||||
plyr->pflags ^= PF_INVIS;
|
plyr->pflags ^= PF_INVIS;
|
||||||
CONS_Printf(M_GetText("SEP Field %s\n"), plyr->pflags & PF_INVIS ? M_GetText("On") : M_GetText("Off"));
|
CONS_Printf(M_GetText("SEP Field %s\n"), plyr->pflags & PF_INVIS ? M_GetText("On") : M_GetText("Off"));
|
||||||
|
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_Scale_f(void)
|
void Command_Scale_f(void)
|
||||||
|
@ -727,7 +727,7 @@ void Command_Devmode_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void Command_Setrings_f(void)
|
/*void Command_Setrings_f(void)
|
||||||
|
@ -1267,7 +1267,7 @@ void Command_ObjectPlace_f(void)
|
||||||
REQUIRE_SINGLEPLAYER;
|
REQUIRE_SINGLEPLAYER;
|
||||||
REQUIRE_NOULTIMATE;
|
REQUIRE_NOULTIMATE;
|
||||||
|
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, true);
|
||||||
|
|
||||||
// Entering objectplace?
|
// Entering objectplace?
|
||||||
if (!objectplacing)
|
if (!objectplacing)
|
||||||
|
|
|
@ -385,8 +385,7 @@ UINT8 M_UpdateUnlockablesAndExtraEmblems(boolean force)
|
||||||
char cechoText[992] = "";
|
char cechoText[992] = "";
|
||||||
UINT8 cechoLines = 0;
|
UINT8 cechoLines = 0;
|
||||||
|
|
||||||
if (modifiedgame && !savemoddata
|
if (majormods && !force) // SRB2Kart: for enabling unlocks online in modified servers
|
||||||
&& !force) // SRB2Kart: for enabling unlocks online in modified servers
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
M_CheckUnlockConditions();
|
M_CheckUnlockConditions();
|
||||||
|
|
63
src/m_menu.c
63
src/m_menu.c
|
@ -274,14 +274,13 @@ static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef;
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
static void M_StartServerMenu(INT32 choice);
|
static void M_StartServerMenu(INT32 choice);
|
||||||
static void M_ConnectMenu(INT32 choice);
|
static void M_ConnectMenu(INT32 choice);
|
||||||
#endif
|
static void M_ConnectMenuModChecks(INT32 choice);
|
||||||
static void M_StartOfflineServerMenu(INT32 choice);
|
|
||||||
static void M_StartServer(INT32 choice);
|
|
||||||
#ifndef NONET
|
|
||||||
static void M_Refresh(INT32 choice);
|
static void M_Refresh(INT32 choice);
|
||||||
static void M_Connect(INT32 choice);
|
static void M_Connect(INT32 choice);
|
||||||
static void M_ChooseRoom(INT32 choice);
|
static void M_ChooseRoom(INT32 choice);
|
||||||
#endif
|
#endif
|
||||||
|
static void M_StartOfflineServerMenu(INT32 choice);
|
||||||
|
static void M_StartServer(INT32 choice);
|
||||||
static void M_SetupMultiPlayer(INT32 choice);
|
static void M_SetupMultiPlayer(INT32 choice);
|
||||||
static void M_SetupMultiPlayer2(INT32 choice);
|
static void M_SetupMultiPlayer2(INT32 choice);
|
||||||
static void M_SetupMultiPlayer3(INT32 choice);
|
static void M_SetupMultiPlayer3(INT32 choice);
|
||||||
|
@ -443,7 +442,7 @@ static CV_PossibleValue_t serversort_cons_t[] = {
|
||||||
{5,"Gametype"},
|
{5,"Gametype"},
|
||||||
{0,NULL}
|
{0,NULL}
|
||||||
};
|
};
|
||||||
consvar_t cv_serversort = {"serversort", "Ping", CV_HIDEN | CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_serversort = {"serversort", "Ping", CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
// autorecord demos for time attack
|
// autorecord demos for time attack
|
||||||
static consvar_t cv_autorecord = {"autorecord", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
static consvar_t cv_autorecord = {"autorecord", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
@ -935,11 +934,11 @@ static menuitem_t MP_MainMenu[] =
|
||||||
|
|
||||||
{IT_HEADER, NULL, "Join a game", NULL, 132-24},
|
{IT_HEADER, NULL, "Join a game", NULL, 132-24},
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
{IT_STRING|IT_CALL, NULL, "Internet server browser...",M_ConnectMenu, 142-24},
|
{IT_STRING|IT_CALL, NULL, "Internet server browser...",M_ConnectMenuModChecks, 142-24},
|
||||||
{IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 150-24},
|
{IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 150-24},
|
||||||
#else
|
#else
|
||||||
{IT_GRAYEDOUT, NULL, "Internet server browser...",M_ConnectMenu, 142-24},
|
{IT_GRAYEDOUT, NULL, "Internet server browser...",NULL, 142-24},
|
||||||
{IT_GRAYEDOUT, NULL, "Specify IPv4 address:", M_HandleConnectIP, 150-24},
|
{IT_GRAYEDOUT, NULL, "Specify IPv4 address:", NULL, 150-24},
|
||||||
#endif
|
#endif
|
||||||
//{IT_HEADER, NULL, "Player setup", NULL, 80},
|
//{IT_HEADER, NULL, "Player setup", NULL, 80},
|
||||||
//{IT_STRING|IT_CALL, NULL, "Name, character, color...", M_SetupMultiPlayer, 90},
|
//{IT_STRING|IT_CALL, NULL, "Name, character, color...", M_SetupMultiPlayer, 90},
|
||||||
|
@ -2739,10 +2738,10 @@ boolean M_Responder(event_t *ev)
|
||||||
|| (currentMenu->menuitems[itemOn].status & IT_TYPE)==IT_SUBMENU)
|
|| (currentMenu->menuitems[itemOn].status & IT_TYPE)==IT_SUBMENU)
|
||||||
&& (currentMenu->menuitems[itemOn].status & IT_CALLTYPE))
|
&& (currentMenu->menuitems[itemOn].status & IT_CALLTYPE))
|
||||||
{
|
{
|
||||||
if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && modifiedgame && !savemoddata)
|
if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && majormods)
|
||||||
{
|
{
|
||||||
S_StartSound(NULL, sfx_menu1);
|
S_StartSound(NULL, sfx_menu1);
|
||||||
M_StartMessage(M_GetText("This cannot be done with add-ons\nor in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
|
M_StartMessage(M_GetText("This cannot be done with complex add-ons\nor in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4527,9 +4526,14 @@ static char *M_AddonsHeaderPath(void)
|
||||||
#define CLEARNAME Z_Free(refreshdirname);\
|
#define CLEARNAME Z_Free(refreshdirname);\
|
||||||
refreshdirname = NULL
|
refreshdirname = NULL
|
||||||
|
|
||||||
|
static boolean prevmajormods = false;
|
||||||
|
|
||||||
static void M_AddonsClearName(INT32 choice)
|
static void M_AddonsClearName(INT32 choice)
|
||||||
{
|
{
|
||||||
CLEARNAME;
|
if (!majormods || prevmajormods)
|
||||||
|
{
|
||||||
|
CLEARNAME;
|
||||||
|
}
|
||||||
M_StopMessage(choice);
|
M_StopMessage(choice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4539,10 +4543,17 @@ static boolean M_AddonsRefresh(void)
|
||||||
if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true))
|
if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true))
|
||||||
{
|
{
|
||||||
UNEXIST;
|
UNEXIST;
|
||||||
|
if (refreshdirname)
|
||||||
|
{
|
||||||
|
CLEARNAME;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refreshdirmenu & REFRESHDIR_ADDFILE)
|
if (!majormods && prevmajormods)
|
||||||
|
prevmajormods = false;
|
||||||
|
|
||||||
|
if ((refreshdirmenu & REFRESHDIR_ADDFILE) || (majormods && !prevmajormods))
|
||||||
{
|
{
|
||||||
char *message = NULL;
|
char *message = NULL;
|
||||||
|
|
||||||
|
@ -4550,7 +4561,7 @@ static boolean M_AddonsRefresh(void)
|
||||||
{
|
{
|
||||||
S_StartSound(NULL, sfx_s26d);
|
S_StartSound(NULL, sfx_s26d);
|
||||||
if (refreshdirmenu & REFRESHDIR_MAX)
|
if (refreshdirmenu & REFRESHDIR_MAX)
|
||||||
message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you wish to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||||
else
|
else
|
||||||
message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||||
}
|
}
|
||||||
|
@ -4559,6 +4570,12 @@ static boolean M_AddonsRefresh(void)
|
||||||
S_StartSound(NULL, sfx_s224);
|
S_StartSound(NULL, sfx_s224);
|
||||||
message = va("%c%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings"));
|
message = va("%c%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings"));
|
||||||
}
|
}
|
||||||
|
else if (majormods && !prevmajormods)
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_s221);
|
||||||
|
message = va("%c%s\x80\nGameplay has now been modified.\nIf you wish to play Record Attack mode, restart the game to clear existing add-ons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||||
|
prevmajormods = majormods;
|
||||||
|
}
|
||||||
|
|
||||||
if (message)
|
if (message)
|
||||||
{
|
{
|
||||||
|
@ -4709,7 +4726,7 @@ static void M_DrawAddons(void)
|
||||||
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+3]);
|
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+3]);
|
||||||
|
|
||||||
x = BASEVIDWIDTH - x - 16;
|
x = BASEVIDWIDTH - x - 16;
|
||||||
V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
|
V_DrawSmallScaledPatch(x, y + 4, ((!majormods) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
|
||||||
|
|
||||||
if (modifiedgame)
|
if (modifiedgame)
|
||||||
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+2]);
|
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+2]);
|
||||||
|
@ -5106,7 +5123,7 @@ static void M_GetAllEmeralds(INT32 choice)
|
||||||
emeralds = ((EMERALD7)*2)-1;
|
emeralds = ((EMERALD7)*2)-1;
|
||||||
M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING);
|
M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING);
|
||||||
|
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_DestroyRobotsResponse(INT32 ch)
|
static void M_DestroyRobotsResponse(INT32 ch)
|
||||||
|
@ -5117,7 +5134,7 @@ static void M_DestroyRobotsResponse(INT32 ch)
|
||||||
// Destroy all robots
|
// Destroy all robots
|
||||||
P_DestroyRobots();
|
P_DestroyRobots();
|
||||||
|
|
||||||
G_SetGameModified(multiplayer);
|
G_SetGameModified(multiplayer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_DestroyRobots(INT32 choice)
|
static void M_DestroyRobots(INT32 choice)
|
||||||
|
@ -7384,6 +7401,20 @@ static void M_ConnectMenu(INT32 choice)
|
||||||
M_Refresh(0);
|
M_Refresh(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void M_ConnectMenuModChecks(INT32 choice)
|
||||||
|
{
|
||||||
|
(void)choice;
|
||||||
|
// okay never mind we want to COMMUNICATE to the player pre-emptively instead of letting them try and then get confused when it doesn't work
|
||||||
|
|
||||||
|
if (modifiedgame)
|
||||||
|
{
|
||||||
|
M_StartMessage(M_GetText("Add-ons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing add-ons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_ConnectMenu(-1);
|
||||||
|
}
|
||||||
|
|
||||||
static UINT32 roomIds[NUM_LIST_ROOMS];
|
static UINT32 roomIds[NUM_LIST_ROOMS];
|
||||||
|
|
||||||
static void M_RoomMenu(INT32 choice)
|
static void M_RoomMenu(INT32 choice)
|
||||||
|
|
|
@ -8264,8 +8264,8 @@ void A_JawzChase(mobj_t *actor)
|
||||||
|
|
||||||
if (actor->tracer)
|
if (actor->tracer)
|
||||||
{
|
{
|
||||||
if (G_RaceGametype()) // Stop looking after first target in race
|
/*if (G_RaceGametype()) // Stop looking after first target in race
|
||||||
actor->extravalue1 = 1;
|
actor->extravalue1 = 1;*/
|
||||||
|
|
||||||
if (actor->tracer->health)
|
if (actor->tracer->health)
|
||||||
{
|
{
|
||||||
|
|
243
src/p_map.c
243
src/p_map.c
|
@ -752,9 +752,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
// Player Damage
|
// Player Damage
|
||||||
P_DamageMobj(thing, tmthing, tmthing->target, 1);
|
P_DamageMobj(thing, tmthing, tmthing->target, 1);
|
||||||
K_KartBouncing(thing, tmthing, false, false);
|
K_KartBouncing(thing, tmthing, false, false);
|
||||||
|
S_StartSound(thing, sfx_s3k7b);
|
||||||
if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD)
|
|
||||||
S_StartSound(thing, sfx_s3k7b);
|
|
||||||
|
|
||||||
// This Item Damage
|
// This Item Damage
|
||||||
if (tmthing->eflags & MFE_VERTICALFLIP)
|
if (tmthing->eflags & MFE_VERTICALFLIP)
|
||||||
|
@ -1035,9 +1033,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
// Player Damage
|
// Player Damage
|
||||||
P_DamageMobj(tmthing, thing, thing->target, 1);
|
P_DamageMobj(tmthing, thing, thing->target, 1);
|
||||||
K_KartBouncing(tmthing, thing, false, false);
|
K_KartBouncing(tmthing, thing, false, false);
|
||||||
|
S_StartSound(tmthing, sfx_s3k7b);
|
||||||
if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD)
|
|
||||||
S_StartSound(tmthing, sfx_s3k7b);
|
|
||||||
|
|
||||||
// Other Item Damage
|
// Other Item Damage
|
||||||
if (thing->eflags & MFE_VERTICALFLIP)
|
if (thing->eflags & MFE_VERTICALFLIP)
|
||||||
|
@ -3231,129 +3227,6 @@ isblocking:
|
||||||
return false; // stop
|
return false; // stop
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// P_IsClimbingValid
|
|
||||||
//
|
|
||||||
// Unlike P_DoClimbing, don't use when up against a one-sided linedef.
|
|
||||||
//
|
|
||||||
static boolean P_IsClimbingValid(player_t *player, angle_t angle)
|
|
||||||
{
|
|
||||||
fixed_t platx, platy;
|
|
||||||
subsector_t *glidesector;
|
|
||||||
fixed_t floorz, ceilingz;
|
|
||||||
|
|
||||||
platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
|
|
||||||
platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
|
|
||||||
|
|
||||||
glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy);
|
|
||||||
|
|
||||||
#ifdef ESLOPE
|
|
||||||
floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight;
|
|
||||||
ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight;
|
|
||||||
#else
|
|
||||||
floorz = glidesector->sector->floorheight;
|
|
||||||
ceilingz = glidesector->sector->ceilingheight;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (glidesector->sector != player->mo->subsector->sector)
|
|
||||||
{
|
|
||||||
boolean floorclimb = false;
|
|
||||||
fixed_t topheight, bottomheight;
|
|
||||||
|
|
||||||
if (glidesector->sector->ffloors)
|
|
||||||
{
|
|
||||||
ffloor_t *rover;
|
|
||||||
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
|
|
||||||
{
|
|
||||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
topheight = *rover->topheight;
|
|
||||||
bottomheight = *rover->bottomheight;
|
|
||||||
|
|
||||||
#ifdef ESLOPE
|
|
||||||
if (*rover->t_slope)
|
|
||||||
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
|
|
||||||
if (*rover->b_slope)
|
|
||||||
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
floorclimb = true;
|
|
||||||
|
|
||||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
|
||||||
{
|
|
||||||
if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight))
|
|
||||||
{
|
|
||||||
floorclimb = true;
|
|
||||||
}
|
|
||||||
if (topheight < player->mo->z) // Waaaay below the ledge.
|
|
||||||
{
|
|
||||||
floorclimb = false;
|
|
||||||
}
|
|
||||||
if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
|
|
||||||
{
|
|
||||||
floorclimb = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight))
|
|
||||||
{
|
|
||||||
floorclimb = true;
|
|
||||||
}
|
|
||||||
if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
|
|
||||||
{
|
|
||||||
floorclimb = false;
|
|
||||||
}
|
|
||||||
if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
|
|
||||||
{
|
|
||||||
floorclimb = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (floorclimb)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
|
||||||
{
|
|
||||||
if ((floorz <= player->mo->z + player->mo->height)
|
|
||||||
&& ((player->mo->z + player->mo->height - player->mo->momz) <= floorz))
|
|
||||||
floorclimb = true;
|
|
||||||
|
|
||||||
if ((floorz > player->mo->z)
|
|
||||||
&& glidesector->sector->floorpic == skyflatnum)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz)
|
|
||||||
|| (player->mo->z + player->mo->height <= floorz))
|
|
||||||
floorclimb = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((ceilingz >= player->mo->z)
|
|
||||||
&& ((player->mo->z - player->mo->momz) >= ceilingz))
|
|
||||||
floorclimb = true;
|
|
||||||
|
|
||||||
if ((ceilingz < player->mo->z+player->mo->height)
|
|
||||||
&& glidesector->sector->ceilingpic == skyflatnum)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz)
|
|
||||||
|| (player->mo->z >= ceilingz))
|
|
||||||
floorclimb = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!floorclimb)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// PTR_SlideTraverse
|
// PTR_SlideTraverse
|
||||||
//
|
//
|
||||||
|
@ -3407,117 +3280,7 @@ isblocking:
|
||||||
P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector);
|
P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slidemo->player && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing)
|
if (in->frac < bestslidefrac)
|
||||||
&& slidemo->player->charability == CA_GLIDEANDCLIMB)
|
|
||||||
{
|
|
||||||
line_t *checkline = li;
|
|
||||||
sector_t *checksector;
|
|
||||||
ffloor_t *rover;
|
|
||||||
fixed_t topheight, bottomheight;
|
|
||||||
boolean fofline = false;
|
|
||||||
INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li);
|
|
||||||
|
|
||||||
if (!side && li->backsector)
|
|
||||||
checksector = li->backsector;
|
|
||||||
else
|
|
||||||
checksector = li->frontsector;
|
|
||||||
|
|
||||||
if (checksector->ffloors)
|
|
||||||
{
|
|
||||||
for (rover = checksector->ffloors; rover; rover = rover->next)
|
|
||||||
{
|
|
||||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
topheight = *rover->topheight;
|
|
||||||
bottomheight = *rover->bottomheight;
|
|
||||||
|
|
||||||
#ifdef ESLOPE
|
|
||||||
if (*rover->t_slope)
|
|
||||||
topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y);
|
|
||||||
if (*rover->b_slope)
|
|
||||||
bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (topheight < slidemo->z)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (bottomheight > slidemo->z + slidemo->height)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this?
|
|
||||||
if (rover->master->flags & ML_TFERLINE)
|
|
||||||
{
|
|
||||||
size_t linenum = li-checksector->lines[0];
|
|
||||||
checkline = rover->master->frontsector->lines[0] + linenum;
|
|
||||||
fofline = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// see about climbing on the wall
|
|
||||||
if (!(checkline->flags & ML_NOCLIMB))
|
|
||||||
{
|
|
||||||
boolean canclimb;
|
|
||||||
angle_t climbangle, climbline;
|
|
||||||
INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li);
|
|
||||||
|
|
||||||
climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y);
|
|
||||||
|
|
||||||
if (whichside) // on second side?
|
|
||||||
climbline += ANGLE_180;
|
|
||||||
|
|
||||||
climbangle += (ANGLE_90 * (whichside ? -1 : 1));
|
|
||||||
|
|
||||||
canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true);
|
|
||||||
|
|
||||||
if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|
|
||||||
|| (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135))
|
|
||||||
&& canclimb)
|
|
||||||
{
|
|
||||||
slidemo->angle = climbangle;
|
|
||||||
if (!demoplayback || P_AnalogMove(slidemo->player))
|
|
||||||
{
|
|
||||||
if (slidemo->player == &players[consoleplayer])
|
|
||||||
localangle = slidemo->angle;
|
|
||||||
else if (slidemo->player == &players[secondarydisplayplayer])
|
|
||||||
localangle2 = slidemo->angle;
|
|
||||||
else if (slidemo->player == &players[thirddisplayplayer])
|
|
||||||
localangle3 = slidemo->angle;
|
|
||||||
else if (slidemo->player == &players[fourthdisplayplayer])
|
|
||||||
localangle4 = slidemo->angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!slidemo->player->climbing)
|
|
||||||
{
|
|
||||||
S_StartSound(slidemo->player->mo, sfx_s3k4a);
|
|
||||||
slidemo->player->climbing = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_THOKKED);
|
|
||||||
slidemo->player->glidetime = 0;
|
|
||||||
slidemo->player->secondjump = 0;
|
|
||||||
|
|
||||||
if (slidemo->player->climbing > 1)
|
|
||||||
slidemo->momz = slidemo->momx = slidemo->momy = 0;
|
|
||||||
|
|
||||||
if (fofline)
|
|
||||||
whichside = 0;
|
|
||||||
|
|
||||||
if (!whichside)
|
|
||||||
{
|
|
||||||
slidemo->player->lastsidehit = checkline->sidenum[whichside];
|
|
||||||
slidemo->player->lastlinehit = (INT16)(checkline - lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing))
|
|
||||||
{
|
{
|
||||||
secondslidefrac = bestslidefrac;
|
secondslidefrac = bestslidefrac;
|
||||||
secondslideline = bestslideline;
|
secondslideline = bestslideline;
|
||||||
|
|
12
src/p_mobj.c
12
src/p_mobj.c
|
@ -1354,7 +1354,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
||||||
if (wasflip == !(mo->eflags & MFE_VERTICALFLIP)) // note!! == ! is not equivalent to != here - turns numeric into bool this way
|
if (wasflip == !(mo->eflags & MFE_VERTICALFLIP)) // note!! == ! is not equivalent to != here - turns numeric into bool this way
|
||||||
P_PlayerFlip(mo);
|
P_PlayerFlip(mo);
|
||||||
if (mo->player->kartstuff[k_pogospring])
|
if (mo->player->kartstuff[k_pogospring])
|
||||||
gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2);
|
gravityadd = (5*gravityadd)/2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1404,11 +1404,12 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
||||||
break;
|
break;
|
||||||
case MT_BANANA:
|
case MT_BANANA:
|
||||||
case MT_EGGMANITEM:
|
case MT_EGGMANITEM:
|
||||||
|
case MT_ORBINAUT:
|
||||||
|
case MT_JAWZ:
|
||||||
|
case MT_JAWZ_DUD:
|
||||||
case MT_SSMINE:
|
case MT_SSMINE:
|
||||||
gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2);
|
|
||||||
break;
|
|
||||||
case MT_SINK:
|
case MT_SINK:
|
||||||
gravityadd = FixedMul(gravityadd, 5*FRACUNIT); // Double gravity
|
gravityadd = (5*gravityadd)/2;
|
||||||
break;
|
break;
|
||||||
case MT_SIGN:
|
case MT_SIGN:
|
||||||
gravityadd /= 8;
|
gravityadd /= 8;
|
||||||
|
@ -3233,8 +3234,7 @@ boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
|
||||||
#endif
|
#endif
|
||||||
*rover->topheight;
|
*rover->topheight;
|
||||||
|
|
||||||
if (!(player->pflags & PF_NIGHTSMODE) && !player->homing
|
if (((player->charflags & SF_RUNONWATER) && player->mo->ceilingz-topheight >= player->mo->height)
|
||||||
&& (((player->charability == CA_SWIM) || player->powers[pw_super] || player->charflags & SF_RUNONWATER) && player->mo->ceilingz-topheight >= player->mo->height)
|
|
||||||
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
|
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
|
||||||
&& !(player->pflags & PF_SLIDING)
|
&& !(player->pflags & PF_SLIDING)
|
||||||
&& abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
|
&& abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
|
||||||
|
|
|
@ -234,7 +234,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
||||||
DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE);
|
DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE);
|
||||||
mapheaderinfo[num]->levelflags = 0;
|
mapheaderinfo[num]->levelflags = 0;
|
||||||
DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE);
|
DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE);
|
||||||
mapheaderinfo[num]->menuflags = 0;
|
mapheaderinfo[num]->menuflags = (mainwads ? 0 : LF2_EXISTSHACK); // see p_setup.c - prevents replacing maps in addons with easier versions
|
||||||
// TODO grades support for delfile (pfft yeah right)
|
// TODO grades support for delfile (pfft yeah right)
|
||||||
P_DeleteGrades(num);
|
P_DeleteGrades(num);
|
||||||
// SRB2Kart
|
// SRB2Kart
|
||||||
|
@ -1120,7 +1120,7 @@ static inline void P_SpawnEmblems(void)
|
||||||
static void P_SpawnSecretItems(boolean loademblems)
|
static void P_SpawnSecretItems(boolean loademblems)
|
||||||
{
|
{
|
||||||
// Now let's spawn those funky emblem things! Tails 12-08-2002
|
// Now let's spawn those funky emblem things! Tails 12-08-2002
|
||||||
if (netgame || multiplayer || (modifiedgame && !savemoddata)) // No cheating!!
|
if (netgame || multiplayer || majormods) // No cheating!!
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (loademblems)
|
if (loademblems)
|
||||||
|
@ -2857,6 +2857,9 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
lastwipetic = nowtime;
|
lastwipetic = nowtime;
|
||||||
if (moviemode) // make sure we save frames for the white hold too
|
if (moviemode) // make sure we save frames for the white hold too
|
||||||
M_SaveFrame();
|
M_SaveFrame();
|
||||||
|
|
||||||
|
// Keep the network alive
|
||||||
|
NetKeepAlive();
|
||||||
}
|
}
|
||||||
|
|
||||||
ranspecialwipe = 1;
|
ranspecialwipe = 1;
|
||||||
|
@ -3272,7 +3275,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
nextmapoverride = 0;
|
nextmapoverride = 0;
|
||||||
skipstats = false;
|
skipstats = false;
|
||||||
|
|
||||||
if (!(netgame || multiplayer) && (!modifiedgame || savemoddata))
|
if (!(netgame || multiplayer) && !majormods)
|
||||||
mapvisited[gamemap-1] |= MV_VISITED;
|
mapvisited[gamemap-1] |= MV_VISITED;
|
||||||
|
|
||||||
levelloading = false;
|
levelloading = false;
|
||||||
|
@ -3455,6 +3458,14 @@ boolean P_AddWadFile(const char *wadfilename)
|
||||||
continue;
|
continue;
|
||||||
num = (INT16)M_MapNumber(name[3], name[4]);
|
num = (INT16)M_MapNumber(name[3], name[4]);
|
||||||
|
|
||||||
|
// we want to record whether this map exists. if it doesn't have a header, we can assume it's not relephant
|
||||||
|
if (num <= NUMMAPS && mapheaderinfo[num-1])
|
||||||
|
{
|
||||||
|
if (mapheaderinfo[num-1]->menuflags & LF2_EXISTSHACK)
|
||||||
|
G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
|
||||||
|
mapheaderinfo[num-1]->menuflags |= LF2_EXISTSHACK;
|
||||||
|
}
|
||||||
|
|
||||||
//If you replaced the map you're on, end the level when done.
|
//If you replaced the map you're on, end the level when done.
|
||||||
if (num == gamemap)
|
if (num == gamemap)
|
||||||
replacedcurrentmap = true;
|
replacedcurrentmap = true;
|
||||||
|
@ -3481,6 +3492,8 @@ boolean P_AddWadFile(const char *wadfilename)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshdirmenu &= ~REFRESHDIR_GAMEDATA; // Under usual circumstances we'd wait for REFRESHDIR_GAMEDATA to disappear the next frame, but it's a bit too dangerous for that...
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
src/p_spec.c
19
src/p_spec.c
|
@ -1758,12 +1758,12 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
||||||
|
|
||||||
switch (specialtype)
|
switch (specialtype)
|
||||||
{
|
{
|
||||||
case 305: // continuous
|
/*case 305: // continuous
|
||||||
case 306: // each time
|
case 306: // each time
|
||||||
case 307: // once
|
case 307: // once
|
||||||
if (!(actor && actor->player && actor->player->charability == dist/10))
|
if (!(actor && actor->player && actor->player->charability == dist/10))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;*/
|
||||||
case 309: // continuous
|
case 309: // continuous
|
||||||
case 310: // each time
|
case 310: // each time
|
||||||
// Only red team members can activate this.
|
// Only red team members can activate this.
|
||||||
|
@ -3864,14 +3864,6 @@ DoneSection2:
|
||||||
|
|
||||||
P_InstaThrust(player->mo, player->mo->angle, linespeed);
|
P_InstaThrust(player->mo, player->mo->angle, linespeed);
|
||||||
|
|
||||||
/*if (GETSECSPECIAL(sector->special, 3) == 6 && (player->charability2 == CA2_SPINDASH)) // SRB2kart
|
|
||||||
{
|
|
||||||
if (!(player->pflags & PF_SPINNING))
|
|
||||||
player->pflags |= PF_SPINNING;
|
|
||||||
|
|
||||||
//P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
player->kartstuff[k_dashpadcooldown] = TICRATE/3;
|
player->kartstuff[k_dashpadcooldown] = TICRATE/3;
|
||||||
player->kartstuff[k_drift] = 0;
|
player->kartstuff[k_drift] = 0;
|
||||||
player->kartstuff[k_driftcharge] = 0;
|
player->kartstuff[k_driftcharge] = 0;
|
||||||
|
@ -5781,7 +5773,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
lines[i].special = 0;
|
lines[i].special = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/*else -- commented out because irrelevant to kart
|
/*else -- commented out because irrelevant to kart. keeping here because we can use these flags for something else now
|
||||||
{
|
{
|
||||||
if ((players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
if ((players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
||||||
|| (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
|
|| (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
|
||||||
|
@ -7997,12 +7989,13 @@ static void P_SearchForDisableLinedefs(void)
|
||||||
}
|
}
|
||||||
else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY)
|
else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY)
|
||||||
continue; // Net-only never triggers in single player
|
continue; // Net-only never triggers in single player
|
||||||
else if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
// commented out because irrelevant to kart. keeping here because we can use these flags for something else now
|
||||||
|
/*else if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
||||||
continue;
|
continue;
|
||||||
else if (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
|
else if (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
|
||||||
continue;
|
continue;
|
||||||
else if (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX))
|
else if (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX))
|
||||||
continue;
|
continue;*/
|
||||||
|
|
||||||
// Disable any linedef specials with our tag.
|
// Disable any linedef specials with our tag.
|
||||||
for (j = -1; (j = P_FindLineFromLineTag(&lines[i], j)) >= 0;)
|
for (j = -1; (j = P_FindLineFromLineTag(&lines[i], j)) >= 0;)
|
||||||
|
|
136
src/p_user.c
136
src/p_user.c
|
@ -7323,74 +7323,6 @@ static void P_MovePlayer(player_t *player)
|
||||||
if (CheckForBustableBlocks)
|
if (CheckForBustableBlocks)
|
||||||
P_CheckBustableBlocks(player);
|
P_CheckBustableBlocks(player);
|
||||||
|
|
||||||
// Special handling for
|
|
||||||
// gliding in 2D mode
|
|
||||||
if ((twodlevel || player->mo->flags2 & MF2_TWOD) && player->pflags & PF_GLIDING && player->charability == CA_GLIDEANDCLIMB
|
|
||||||
&& !(player->mo->flags & MF_NOCLIP))
|
|
||||||
{
|
|
||||||
msecnode_t *node; // only place it's being used in P_MovePlayer now
|
|
||||||
fixed_t oldx;
|
|
||||||
fixed_t oldy;
|
|
||||||
fixed_t floorz, ceilingz;
|
|
||||||
|
|
||||||
oldx = player->mo->x;
|
|
||||||
oldy = player->mo->y;
|
|
||||||
|
|
||||||
P_UnsetThingPosition(player->mo);
|
|
||||||
player->mo->x += player->mo->momx;
|
|
||||||
player->mo->y += player->mo->momy;
|
|
||||||
P_SetThingPosition(player->mo);
|
|
||||||
|
|
||||||
for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
|
||||||
{
|
|
||||||
if (!node->m_sector)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (node->m_sector->ffloors)
|
|
||||||
{
|
|
||||||
ffloor_t *rover;
|
|
||||||
fixed_t topheight, bottomheight;
|
|
||||||
|
|
||||||
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
|
|
||||||
{
|
|
||||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
|
|
||||||
bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
|
|
||||||
if (topheight > player->mo->z && bottomheight < player->mo->z)
|
|
||||||
{
|
|
||||||
P_ResetPlayer(player);
|
|
||||||
S_StartSound(player->mo, sfx_s3k4a);
|
|
||||||
player->climbing = 5;
|
|
||||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
floorz = P_GetFloorZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL);
|
|
||||||
ceilingz = P_GetCeilingZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL);
|
|
||||||
|
|
||||||
if (player->mo->z+player->mo->height > ceilingz
|
|
||||||
&& node->m_sector->ceilingpic == skyflatnum)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (floorz > player->mo->z || ceilingz < player->mo->z)
|
|
||||||
{
|
|
||||||
P_ResetPlayer(player);
|
|
||||||
S_StartSound(player->mo, sfx_s3k4a);
|
|
||||||
player->climbing = 5;
|
|
||||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
P_UnsetThingPosition(player->mo);
|
|
||||||
player->mo->x = oldx;
|
|
||||||
player->mo->y = oldy;
|
|
||||||
P_SetThingPosition(player->mo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for a BOUNCY sector!
|
// Check for a BOUNCY sector!
|
||||||
if (CheckForBouncySector)
|
if (CheckForBouncySector)
|
||||||
P_CheckBouncySectors(player);
|
P_CheckBouncySectors(player);
|
||||||
|
@ -8165,6 +8097,8 @@ void P_ResetCamera(player_t *player, camera_t *thiscam)
|
||||||
|
|
||||||
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled)
|
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled)
|
||||||
{
|
{
|
||||||
|
static UINT8 lookbackdelay[4] = {0,0,0,0};
|
||||||
|
UINT8 num;
|
||||||
angle_t angle = 0, focusangle = 0, focusaiming = 0;
|
angle_t angle = 0, focusangle = 0, focusaiming = 0;
|
||||||
fixed_t x, y, z, dist, height, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
|
fixed_t x, y, z, dist, height, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
|
||||||
fixed_t pan, xpan, ypan;
|
fixed_t pan, xpan, ypan;
|
||||||
|
@ -8293,6 +8227,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
|
|
||||||
if (thiscam == &camera)
|
if (thiscam == &camera)
|
||||||
{
|
{
|
||||||
|
num = 0;
|
||||||
camspeed = cv_cam_speed.value;
|
camspeed = cv_cam_speed.value;
|
||||||
camstill = cv_cam_still.value;
|
camstill = cv_cam_still.value;
|
||||||
camrotate = cv_cam_rotate.value;
|
camrotate = cv_cam_rotate.value;
|
||||||
|
@ -8302,6 +8237,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
}
|
}
|
||||||
else if (thiscam == &camera2) // Camera 2
|
else if (thiscam == &camera2) // Camera 2
|
||||||
{
|
{
|
||||||
|
num = 1;
|
||||||
camspeed = cv_cam2_speed.value;
|
camspeed = cv_cam2_speed.value;
|
||||||
camstill = cv_cam2_still.value;
|
camstill = cv_cam2_still.value;
|
||||||
camrotate = cv_cam2_rotate.value;
|
camrotate = cv_cam2_rotate.value;
|
||||||
|
@ -8311,6 +8247,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
}
|
}
|
||||||
else if (thiscam == &camera3) // Camera 3
|
else if (thiscam == &camera3) // Camera 3
|
||||||
{
|
{
|
||||||
|
num = 2;
|
||||||
camspeed = cv_cam3_speed.value;
|
camspeed = cv_cam3_speed.value;
|
||||||
camstill = cv_cam3_still.value;
|
camstill = cv_cam3_still.value;
|
||||||
camrotate = cv_cam3_rotate.value;
|
camrotate = cv_cam3_rotate.value;
|
||||||
|
@ -8320,6 +8257,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
}
|
}
|
||||||
else // Camera 4
|
else // Camera 4
|
||||||
{
|
{
|
||||||
|
num = 3;
|
||||||
camspeed = cv_cam4_speed.value;
|
camspeed = cv_cam4_speed.value;
|
||||||
camstill = cv_cam4_still.value;
|
camstill = cv_cam4_still.value;
|
||||||
camrotate = cv_cam4_rotate.value;
|
camrotate = cv_cam4_rotate.value;
|
||||||
|
@ -8342,12 +8280,16 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
}
|
}
|
||||||
else if (player->exiting) // SRB2Kart: Leave the camera behind while exiting, for dramatic effect!
|
else if (player->exiting) // SRB2Kart: Leave the camera behind while exiting, for dramatic effect!
|
||||||
camstill = true;
|
camstill = true;
|
||||||
else if (lookback) // SRB2kart - Camera flipper
|
else if (lookback || lookbackdelay[num]) // SRB2kart - Camera flipper
|
||||||
{
|
{
|
||||||
camrotate += 180;
|
camspeed = FRACUNIT;
|
||||||
camspeed *= 2;
|
if (lookback)
|
||||||
if (camspeed > FRACUNIT)
|
{
|
||||||
camspeed = FRACUNIT;
|
camrotate += 180;
|
||||||
|
lookbackdelay[num] = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lookbackdelay[num]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mo->eflags & MFE_VERTICALFLIP)
|
if (mo->eflags & MFE_VERTICALFLIP)
|
||||||
|
@ -8356,6 +8298,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
if (splitscreen == 1)
|
if (splitscreen == 1)
|
||||||
camspeed = (3*camspeed)/4;
|
camspeed = (3*camspeed)/4;
|
||||||
|
|
||||||
|
if (camspeed > FRACUNIT)
|
||||||
|
camspeed = FRACUNIT;
|
||||||
|
|
||||||
if (timeover)
|
if (timeover)
|
||||||
angle = mo->angle + FixedAngle(camrotate*FRACUNIT);
|
angle = mo->angle + FixedAngle(camrotate*FRACUNIT);
|
||||||
else if (leveltime < starttime)
|
else if (leveltime < starttime)
|
||||||
|
@ -8364,16 +8309,21 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
angle = thiscam->angle;
|
angle = thiscam->angle;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
angle_t input = focusangle + FixedAngle(camrotate<<FRACBITS) - thiscam->angle;
|
if (camspeed == FRACUNIT)
|
||||||
boolean invert = (input > ANGLE_180);
|
angle = focusangle + FixedAngle(camrotate<<FRACBITS);
|
||||||
if (invert)
|
else
|
||||||
input = InvAngle(input);
|
{
|
||||||
|
angle_t input = focusangle + FixedAngle(camrotate<<FRACBITS) - thiscam->angle;
|
||||||
|
boolean invert = (input > ANGLE_180);
|
||||||
|
if (invert)
|
||||||
|
input = InvAngle(input);
|
||||||
|
|
||||||
input = FixedAngle(FixedMul(AngleFixed(input), camspeed));
|
input = FixedAngle(FixedMul(AngleFixed(input), camspeed));
|
||||||
if (invert)
|
if (invert)
|
||||||
input = InvAngle(input);
|
input = InvAngle(input);
|
||||||
|
|
||||||
angle = thiscam->angle + input;
|
angle = thiscam->angle + input;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!resetcalled && (leveltime > starttime && timeover != 2)
|
if (!resetcalled && (leveltime > starttime && timeover != 2)
|
||||||
|
@ -8697,8 +8647,25 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
if (twodlevel || (mo->flags2 & MF2_TWOD) || (!camstill && !timeover)) // Keep the view still...
|
if (twodlevel || (mo->flags2 & MF2_TWOD) || (!camstill && !timeover)) // Keep the view still...
|
||||||
{
|
{
|
||||||
G_ClipAimingPitch((INT32 *)&angle);
|
G_ClipAimingPitch((INT32 *)&angle);
|
||||||
dist = thiscam->aiming - angle;
|
|
||||||
thiscam->aiming -= (dist>>3);
|
if (camspeed == FRACUNIT)
|
||||||
|
thiscam->aiming = angle;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
angle_t input;
|
||||||
|
boolean invert;
|
||||||
|
|
||||||
|
input = thiscam->aiming - angle;
|
||||||
|
invert = (input > ANGLE_180);
|
||||||
|
if (invert)
|
||||||
|
input = InvAngle(input);
|
||||||
|
|
||||||
|
input = FixedAngle(FixedMul(AngleFixed(input), (5*camspeed)/16));
|
||||||
|
if (invert)
|
||||||
|
input = InvAngle(input);
|
||||||
|
|
||||||
|
thiscam->aiming -= input;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!resetcalled && (player->playerstate == PST_DEAD || player->playerstate == PST_REBORN))
|
if (!resetcalled && (player->playerstate == PST_DEAD || player->playerstate == PST_REBORN))
|
||||||
|
@ -8763,6 +8730,7 @@ boolean P_SpectatorJoinGame(player_t *player)
|
||||||
}
|
}
|
||||||
player->spectator = false;
|
player->spectator = false;
|
||||||
player->pflags &= ~PF_WANTSTOJOIN;
|
player->pflags &= ~PF_WANTSTOJOIN;
|
||||||
|
player->kartstuff[k_spectatewait] = 0;
|
||||||
player->ctfteam = changeto;
|
player->ctfteam = changeto;
|
||||||
player->playerstate = PST_REBORN;
|
player->playerstate = PST_REBORN;
|
||||||
|
|
||||||
|
@ -8787,6 +8755,7 @@ boolean P_SpectatorJoinGame(player_t *player)
|
||||||
}
|
}
|
||||||
player->spectator = false;
|
player->spectator = false;
|
||||||
player->pflags &= ~PF_WANTSTOJOIN;
|
player->pflags &= ~PF_WANTSTOJOIN;
|
||||||
|
player->kartstuff[k_spectatewait] = 0;
|
||||||
player->playerstate = PST_REBORN;
|
player->playerstate = PST_REBORN;
|
||||||
|
|
||||||
//Reset away view
|
//Reset away view
|
||||||
|
@ -9876,4 +9845,3 @@ void P_PlayerAfterThink(player_t *player)
|
||||||
|
|
||||||
K_KartPlayerAfterThink(player);
|
K_KartPlayerAfterThink(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2638,7 +2638,7 @@ INT32 R_SkinAvailable(const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// network code calls this when a 'skin change' is received
|
// network code calls this when a 'skin change' is received
|
||||||
void SetPlayerSkin(INT32 playernum, const char *skinname)
|
boolean SetPlayerSkin(INT32 playernum, const char *skinname)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
player_t *player = &players[playernum];
|
player_t *player = &players[playernum];
|
||||||
|
@ -2649,7 +2649,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname)
|
||||||
if (stricmp(skins[i].name, skinname) == 0)
|
if (stricmp(skins[i].name, skinname) == 0)
|
||||||
{
|
{
|
||||||
SetPlayerSkinByNum(playernum, i);
|
SetPlayerSkinByNum(playernum, i);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2659,6 +2659,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname)
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname);
|
CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname);
|
||||||
|
|
||||||
SetPlayerSkinByNum(playernum, 0);
|
SetPlayerSkinByNum(playernum, 0);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as SetPlayerSkin, but uses the skin #.
|
// Same as SetPlayerSkin, but uses the skin #.
|
||||||
|
@ -2897,27 +2898,27 @@ void R_AddSkins(UINT16 wadnum)
|
||||||
#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value);
|
#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value);
|
||||||
// character type identification
|
// character type identification
|
||||||
FULLPROCESS(flags)
|
FULLPROCESS(flags)
|
||||||
FULLPROCESS(ability)
|
//FULLPROCESS(ability)
|
||||||
FULLPROCESS(ability2)
|
//FULLPROCESS(ability2)
|
||||||
|
|
||||||
FULLPROCESS(thokitem)
|
//FULLPROCESS(thokitem)
|
||||||
FULLPROCESS(spinitem)
|
//FULLPROCESS(spinitem)
|
||||||
FULLPROCESS(revitem)
|
//FULLPROCESS(revitem)
|
||||||
#undef FULLPROCESS
|
#undef FULLPROCESS
|
||||||
|
|
||||||
#define GETSPEED(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS;
|
#define GETSPEED(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS;
|
||||||
GETSPEED(normalspeed)
|
//GETSPEED(normalspeed)
|
||||||
GETSPEED(runspeed)
|
GETSPEED(runspeed)
|
||||||
GETSPEED(mindash)
|
//GETSPEED(mindash)
|
||||||
GETSPEED(maxdash)
|
//GETSPEED(maxdash)
|
||||||
GETSPEED(actionspd)
|
//GETSPEED(actionspd)
|
||||||
#undef GETSPEED
|
#undef GETSPEED
|
||||||
|
|
||||||
#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value);
|
/*#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value);
|
||||||
GETINT(thrustfactor)
|
GETINT(thrustfactor)
|
||||||
GETINT(accelstart)
|
GETINT(accelstart)
|
||||||
GETINT(acceleration)
|
GETINT(acceleration)
|
||||||
#undef GETINT
|
#undef GETINT*/
|
||||||
|
|
||||||
#define GETKARTSTAT(field) \
|
#define GETKARTSTAT(field) \
|
||||||
else if (!stricmp(stoken, #field)) \
|
else if (!stricmp(stoken, #field)) \
|
||||||
|
@ -2936,8 +2937,8 @@ void R_AddSkins(UINT16 wadnum)
|
||||||
|
|
||||||
else if (!stricmp(stoken, "prefcolor"))
|
else if (!stricmp(stoken, "prefcolor"))
|
||||||
skin->prefcolor = K_GetKartColorByName(value);
|
skin->prefcolor = K_GetKartColorByName(value);
|
||||||
else if (!stricmp(stoken, "jumpfactor"))
|
//else if (!stricmp(stoken, "jumpfactor"))
|
||||||
skin->jumpfactor = FLOAT_TO_FIXED(atof(value));
|
//skin->jumpfactor = FLOAT_TO_FIXED(atof(value));
|
||||||
else if (!stricmp(stoken, "highresscale"))
|
else if (!stricmp(stoken, "highresscale"))
|
||||||
skin->highresscale = FLOAT_TO_FIXED(atof(value));
|
skin->highresscale = FLOAT_TO_FIXED(atof(value));
|
||||||
else
|
else
|
||||||
|
@ -3047,6 +3048,9 @@ next_token:
|
||||||
HWR_AddPlayerMD2(numskins);
|
HWR_AddPlayerMD2(numskins);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (skin->flags & SF_RUNONWATER) // this is literally the only way a skin can be a major mod... this might be a bit heavy handed
|
||||||
|
G_SetGameModified(multiplayer, true);
|
||||||
|
|
||||||
numskins++;
|
numskins++;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -220,7 +220,7 @@ extern skin_t skins[MAXSKINS];
|
||||||
extern INT32 numfollowers;
|
extern INT32 numfollowers;
|
||||||
extern follower_t followers[MAXSKINS]; // again, use the same rules as skins, no reason not to.
|
extern follower_t followers[MAXSKINS]; // again, use the same rules as skins, no reason not to.
|
||||||
|
|
||||||
void SetPlayerSkin(INT32 playernum,const char *skinname);
|
boolean SetPlayerSkin(INT32 playernum,const char *skinname);
|
||||||
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
|
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
|
||||||
INT32 R_SkinAvailable(const char *name);
|
INT32 R_SkinAvailable(const char *name);
|
||||||
void R_AddSkins(UINT16 wadnum);
|
void R_AddSkins(UINT16 wadnum);
|
||||||
|
|
|
@ -1229,7 +1229,7 @@ void I_GetEvent(void)
|
||||||
// update the menu
|
// update the menu
|
||||||
if (currentMenu == &OP_JoystickSetDef)
|
if (currentMenu == &OP_JoystickSetDef)
|
||||||
M_SetupJoystickMenu(0);
|
M_SetupJoystickMenu(0);
|
||||||
break;
|
break;
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
I_Quit();
|
I_Quit();
|
||||||
M_QuitResponse('y');
|
M_QuitResponse('y');
|
||||||
|
|
|
@ -1952,31 +1952,38 @@ static void ST_overlayDrawer(void)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
const char *itemtxt = M_GetText("Item - Join Game");
|
||||||
|
|
||||||
|
if (stplyr->powers[pw_flashing])
|
||||||
|
itemtxt = M_GetText("Item - . . .");
|
||||||
|
else if (stplyr->pflags & PF_WANTSTOJOIN)
|
||||||
|
itemtxt = M_GetText("Item - Cancel Join");
|
||||||
|
else if (G_GametypeHasTeams())
|
||||||
|
itemtxt = M_GetText("Item - Join Team");
|
||||||
|
|
||||||
|
if (cv_ingamecap.value)
|
||||||
|
{
|
||||||
|
UINT8 numingame = 0;
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
if (playeringame[i] && !players[i].spectator)
|
||||||
|
numingame++;
|
||||||
|
|
||||||
|
itemtxt = va("%s (%s: %d)", itemtxt, M_GetText("Slots left"), max(0, cv_ingamecap.value - numingame));
|
||||||
|
}
|
||||||
|
|
||||||
// SRB2kart: changed positions & text
|
// SRB2kart: changed positions & text
|
||||||
if (splitscreen)
|
if (splitscreen)
|
||||||
{
|
{
|
||||||
INT32 splitflags = K_calcSplitFlags(0);
|
INT32 splitflags = K_calcSplitFlags(0);
|
||||||
V_DrawThinString(2, (BASEVIDHEIGHT/2)-20, V_YELLOWMAP|V_HUDTRANSHALF|splitflags, M_GetText("- SPECTATING -"));
|
V_DrawThinString(2, (BASEVIDHEIGHT/2)-20, V_YELLOWMAP|V_HUDTRANSHALF|splitflags, M_GetText("- SPECTATING -"));
|
||||||
if (stplyr->powers[pw_flashing])
|
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, itemtxt);
|
||||||
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - . . ."));
|
|
||||||
else if (stplyr->pflags & PF_WANTSTOJOIN)
|
|
||||||
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - Cancel Join"));
|
|
||||||
/*else if (G_GametypeHasTeams())
|
|
||||||
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - Join Team"));*/
|
|
||||||
else
|
|
||||||
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - Join Game"));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -"));
|
V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -"));
|
||||||
if (stplyr->powers[pw_flashing])
|
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, itemtxt);
|
||||||
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - . . ."));
|
|
||||||
else if (stplyr->pflags & PF_WANTSTOJOIN)
|
|
||||||
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - Cancel Join"));
|
|
||||||
/*else if (G_GametypeHasTeams())
|
|
||||||
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - Join Team"));*/
|
|
||||||
else
|
|
||||||
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - Join Game"));
|
|
||||||
V_DrawString(2, BASEVIDHEIGHT-20, V_HUDTRANSHALF, M_GetText("Accelerate - Float"));
|
V_DrawString(2, BASEVIDHEIGHT-20, V_HUDTRANSHALF, M_GetText("Accelerate - Float"));
|
||||||
V_DrawString(2, BASEVIDHEIGHT-10, V_HUDTRANSHALF, M_GetText("Brake - Sink"));
|
V_DrawString(2, BASEVIDHEIGHT-10, V_HUDTRANSHALF, M_GetText("Brake - Sink"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
|
|
||||||
|
#include "g_game.h" // G_LoadGameData
|
||||||
#include "filesrch.h"
|
#include "filesrch.h"
|
||||||
|
|
||||||
#include "i_video.h" // rendermode
|
#include "i_video.h" // rendermode
|
||||||
|
@ -799,6 +800,10 @@ UINT16 W_InitFile(const char *filename)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (refreshdirmenu & REFRESHDIR_GAMEDATA)
|
||||||
|
G_LoadGameData();
|
||||||
|
DEH_UpdateMaxFreeslots();
|
||||||
|
|
||||||
W_InvalidateLumpnumCache();
|
W_InvalidateLumpnumCache();
|
||||||
return wadfile->numlumps;
|
return wadfile->numlumps;
|
||||||
}
|
}
|
||||||
|
|
|
@ -432,7 +432,7 @@ void Y_IntermissionDrawer(void)
|
||||||
if (data.match.encore)
|
if (data.match.encore)
|
||||||
V_DrawCenteredString(-4 + x + BASEVIDWIDTH/2, 12-8, hilicol, "ENCORE MODE");
|
V_DrawCenteredString(-4 + x + BASEVIDWIDTH/2, 12-8, hilicol, "ENCORE MODE");
|
||||||
|
|
||||||
if (!gutter)
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
{
|
{
|
||||||
V_DrawFill(x+156, 24, 1, 158, 0);
|
V_DrawFill(x+156, 24, 1, 158, 0);
|
||||||
V_DrawFill((x-3) - duptweak, 182, dupadjust-2, 1, 0);
|
V_DrawFill((x-3) - duptweak, 182, dupadjust-2, 1, 0);
|
||||||
|
@ -476,8 +476,8 @@ void Y_IntermissionDrawer(void)
|
||||||
|
|
||||||
STRBUFCPY(strtime, data.match.name[i]);
|
STRBUFCPY(strtime, data.match.name[i]);
|
||||||
|
|
||||||
if (!gutter)
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
V_DrawThinString(x+36, y, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
|
V_DrawThinString(x+36, y-1, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
|
||||||
else
|
else
|
||||||
V_DrawString(x+36, y, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime);
|
V_DrawString(x+36, y, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime);
|
||||||
|
|
||||||
|
@ -490,17 +490,23 @@ void Y_IntermissionDrawer(void)
|
||||||
else
|
else
|
||||||
snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[data.match.num[i]]);
|
snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[data.match.num[i]]);
|
||||||
|
|
||||||
V_DrawRightAlignedString(x+120+gutter, y, 0, strtime);
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
|
V_DrawRightAlignedThinString(x+135+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||||
|
else
|
||||||
|
V_DrawRightAlignedString(x+120+gutter, y, 0, strtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(strtime, sizeof strtime, "%d", data.match.val[i]);
|
snprintf(strtime, sizeof strtime, "%d", data.match.val[i]);
|
||||||
|
|
||||||
V_DrawRightAlignedString(x+152+gutter, y, 0, strtime);
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
|
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||||
|
else
|
||||||
|
V_DrawRightAlignedString(x+152+gutter, y, 0, strtime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (data.match.val[i] == (UINT32_MAX-1))
|
if (data.match.val[i] == (UINT32_MAX-1))
|
||||||
V_DrawRightAlignedThinString(x+152+gutter, y-1, 0, "NO CONTEST.");
|
V_DrawRightAlignedThinString(x+152+gutter, y-1, (data.match.numplayers > NUMFORNEWCOLUMN ? V_6WIDTHSPACE : 0), "NO CONTEST.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (intertype == int_race)
|
if (intertype == int_race)
|
||||||
|
@ -509,10 +515,18 @@ void Y_IntermissionDrawer(void)
|
||||||
G_TicsToSeconds(data.match.val[i]), G_TicsToCentiseconds(data.match.val[i]));
|
G_TicsToSeconds(data.match.val[i]), G_TicsToCentiseconds(data.match.val[i]));
|
||||||
strtime[sizeof strtime - 1] = '\0';
|
strtime[sizeof strtime - 1] = '\0';
|
||||||
|
|
||||||
V_DrawRightAlignedString(x+152+gutter, y, 0, strtime);
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
|
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||||
|
else
|
||||||
|
V_DrawRightAlignedString(x+152+gutter, y, 0, strtime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
V_DrawRightAlignedString(x+152+gutter, y, 0, va("%i", data.match.val[i]));
|
{
|
||||||
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
|
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, va("%i", data.match.val[i]));
|
||||||
|
else
|
||||||
|
V_DrawRightAlignedString(x+152+gutter, y, 0, va("%i", data.match.val[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,7 +796,7 @@ void Y_StartIntermission(void)
|
||||||
}
|
}
|
||||||
case int_race: // (time-only race)
|
case int_race: // (time-only race)
|
||||||
{
|
{
|
||||||
if ((!modifiedgame || savemoddata) && !multiplayer && !demoplayback) // remove this once we have a proper time attack screen
|
if (!majormods && !multiplayer && !demoplayback) // remove this once we have a proper time attack screen
|
||||||
{
|
{
|
||||||
// Update visitation flags
|
// Update visitation flags
|
||||||
mapvisited[gamemap-1] |= MV_BEATEN;
|
mapvisited[gamemap-1] |= MV_BEATEN;
|
||||||
|
|
Loading…
Reference in a new issue