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
|
@ -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"));
|
||||||
|
@ -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
|
||||||
|
|
430
src/k_kart.c
430
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;
|
||||||
|
else
|
||||||
newodds *= min((secondist/distvar)-4, 3);
|
newodds *= min((secondist/distvar)-4, 3);
|
||||||
break;
|
break;
|
||||||
case KITEM_GROW:
|
|
||||||
POWERITEMODDS(newodds);
|
|
||||||
if ((!cv_grow.value) || (pinvin >= 2)) newodds = 0;
|
|
||||||
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
|
||||||
|
@ -1772,9 +1747,15 @@ 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 (!player)
|
||||||
|
return tics;
|
||||||
|
|
||||||
if (G_BattleGametype())
|
if (G_BattleGametype())
|
||||||
tics *= 2;
|
tics *= 2;
|
||||||
|
|
||||||
tics += (flashingtics/8) * (player->kartspeed);
|
tics += (flashingtics/8) * (player->kartspeed);
|
||||||
|
|
||||||
return tics;
|
return tics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,13 +3059,10 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mo)
|
|
||||||
{
|
|
||||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||||
mo->eflags |= MFE_VERTICALFLIP;
|
mo->eflags |= MFE_VERTICALFLIP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return mo;
|
return mo;
|
||||||
}
|
}
|
||||||
|
@ -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->kartstuff[k_offroad])
|
||||||
|
{
|
||||||
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 += 4608;
|
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 += 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,6 +5785,8 @@ 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
|
||||||
|
@ -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,6 +7097,11 @@ 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);
|
||||||
|
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUA_HudEnabled(hud_battlebumpers))
|
||||||
|
{
|
||||||
|
#endif
|
||||||
if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_bumper] > 0)
|
if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_bumper] > 0)
|
||||||
{
|
{
|
||||||
V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_tinybumper[0], colormap);
|
V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_tinybumper[0], colormap);
|
||||||
|
@ -7047,6 +7111,9 @@ static boolean K_drawKartPositionFaces(void)
|
||||||
V_DrawMappedPatch(bumperx, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_tinybumper[1], colormap);
|
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 (scorelines > 8)
|
||||||
|
{
|
||||||
|
if (players[tab[i].num].exiting)
|
||||||
|
V_DrawRightAlignedThinString(x+rightoffset, y-1, hilicol|V_6WIDTHSPACE, timestring(players[tab[i].num].realtime));
|
||||||
|
else if (players[tab[i].num].pflags & PF_TIMEOVER)
|
||||||
|
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)
|
if (players[tab[i].num].exiting)
|
||||||
V_DrawRightAlignedString(x+rightoffset, y, hilicol, timestring(players[tab[i].num].realtime));
|
V_DrawRightAlignedString(x+rightoffset, y, hilicol, timestring(players[tab[i].num].realtime));
|
||||||
else if (players[tab[i].num].pflags & PF_TIMEOVER)
|
else if (players[tab[i].num].pflags & PF_TIMEOVER)
|
||||||
V_DrawRightAlignedThinString(x+rightoffset, y-1, 0, "NO CONTEST.");
|
V_DrawRightAlignedThinString(x+rightoffset, y-1, 0, "NO CONTEST.");
|
||||||
else if (circuitmap)
|
else if (circuitmap)
|
||||||
V_DrawRightAlignedString(x+rightoffset, y, 0, va("Lap %d", tab[i].count));
|
V_DrawRightAlignedString(x+rightoffset, y, 0, va("Lap %d", tab[i].count));
|
||||||
|
}
|
||||||
#undef timestring
|
#undef timestring
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -7853,6 +7932,9 @@ static void K_drawBattleFullscreen(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUA_HudEnabled(hud_freeplay))
|
||||||
|
#endif
|
||||||
K_drawKartFreePlay(leveltime);
|
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,17 +8406,15 @@ 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)));
|
||||||
{
|
|
||||||
K_drawBattleFullscreen();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!battlefullscreen || splitscreen)
|
||||||
|
{
|
||||||
// Draw the CHECK indicator before the other items, so it's overlapped by everything else
|
// Draw the CHECK indicator before the other items, so it's overlapped by everything else
|
||||||
if (cv_kartcheck.value && !splitscreen && !players[displayplayer].exiting)
|
if (cv_kartcheck.value && !splitscreen && !players[displayplayer].exiting)
|
||||||
K_drawKartPlayerCheck();
|
K_drawKartPlayerCheck();
|
||||||
|
@ -8360,8 +8433,14 @@ void K_drawKartHUD(void)
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUA_HudEnabled(hud_minimap))
|
if (LUA_HudEnabled(hud_minimap))
|
||||||
#endif
|
#endif
|
||||||
K_drawKartMinimap(); // 3P splitscreen is handled above
|
K_drawKartMinimap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (battlefullscreen)
|
||||||
|
{
|
||||||
|
K_drawBattleFullscreen();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the item window
|
// Draw the item window
|
||||||
|
@ -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)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUA_HudEnabled(hud_freeplay))
|
||||||
|
#endif
|
||||||
K_drawKartFreePlay(leveltime);
|
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();
|
||||||
|
|
61
src/m_menu.c
61
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)
|
||||||
{
|
{
|
||||||
|
if (!majormods || prevmajormods)
|
||||||
|
{
|
||||||
CLEARNAME;
|
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)
|
||||||
{
|
{
|
||||||
|
|
239
src/p_map.c
239
src/p_map.c
|
@ -752,8 +752,6 @@ 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);
|
||||||
|
|
||||||
if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD)
|
|
||||||
S_StartSound(thing, sfx_s3k7b);
|
S_StartSound(thing, sfx_s3k7b);
|
||||||
|
|
||||||
// This Item Damage
|
// This Item Damage
|
||||||
|
@ -1035,8 +1033,6 @@ 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);
|
||||||
|
|
||||||
if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD)
|
|
||||||
S_StartSound(tmthing, sfx_s3k7b);
|
S_StartSound(tmthing, sfx_s3k7b);
|
||||||
|
|
||||||
// Other Item Damage
|
// Other Item Damage
|
||||||
|
@ -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;)
|
||||||
|
|
118
src/p_user.c
118
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
|
||||||
|
{
|
||||||
|
camspeed = FRACUNIT;
|
||||||
|
if (lookback)
|
||||||
{
|
{
|
||||||
camrotate += 180;
|
camrotate += 180;
|
||||||
camspeed *= 2;
|
lookbackdelay[num] = 2;
|
||||||
if (camspeed > FRACUNIT)
|
}
|
||||||
camspeed = FRACUNIT;
|
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)
|
||||||
|
@ -8363,6 +8308,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
else if (camstill || resetcalled || player->playerstate == PST_DEAD)
|
else if (camstill || resetcalled || player->playerstate == PST_DEAD)
|
||||||
angle = thiscam->angle;
|
angle = thiscam->angle;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (camspeed == FRACUNIT)
|
||||||
|
angle = focusangle + FixedAngle(camrotate<<FRACBITS);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
angle_t input = focusangle + FixedAngle(camrotate<<FRACBITS) - thiscam->angle;
|
angle_t input = focusangle + FixedAngle(camrotate<<FRACBITS) - thiscam->angle;
|
||||||
boolean invert = (input > ANGLE_180);
|
boolean invert = (input > ANGLE_180);
|
||||||
|
@ -8375,6 +8324,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
|
|
||||||
angle = thiscam->angle + input;
|
angle = thiscam->angle + input;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!resetcalled && (leveltime > starttime && timeover != 2)
|
if (!resetcalled && (leveltime > starttime && timeover != 2)
|
||||||
&& ((thiscam == &camera && t_cam_rotate != -42)
|
&& ((thiscam == &camera && t_cam_rotate != -42)
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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]]);
|
||||||
|
|
||||||
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
|
V_DrawRightAlignedThinString(x+135+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||||
|
else
|
||||||
V_DrawRightAlignedString(x+120+gutter, y, 0, strtime);
|
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]);
|
||||||
|
|
||||||
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
|
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||||
|
else
|
||||||
V_DrawRightAlignedString(x+152+gutter, y, 0, strtime);
|
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,12 +515,20 @@ 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';
|
||||||
|
|
||||||
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
|
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||||
|
else
|
||||||
V_DrawRightAlignedString(x+152+gutter, y, 0, strtime);
|
V_DrawRightAlignedString(x+152+gutter, y, 0, strtime);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
|
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, va("%i", data.match.val[i]));
|
||||||
else
|
else
|
||||||
V_DrawRightAlignedString(x+152+gutter, y, 0, va("%i", data.match.val[i]));
|
V_DrawRightAlignedString(x+152+gutter, y, 0, va("%i", data.match.val[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dojitter)
|
if (dojitter)
|
||||||
y++;
|
y++;
|
||||||
|
@ -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