mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-06-20 23:03:29 +00:00
Merge branch 'trick-panels-changes' into 'trick-panels'
Trick panels changes See merge request KartKrew/Kart!343
This commit is contained in:
commit
e2552d59d4
77 changed files with 3819 additions and 1908 deletions
|
|
@ -453,8 +453,9 @@ if(${SRB2_CONFIG_HAVE_DISCORDRPC})
|
|||
if(${DISCORDRPC_FOUND})
|
||||
set(SRB2_HAVE_DISCORDRPC ON)
|
||||
add_definitions(-DHAVE_DISCORDRPC)
|
||||
set(SRB2_DISCORDRPC_SOURCES discord.c)
|
||||
set(SRB2_DISCORDRPC_HEADERS discord.h)
|
||||
add_definitions(-DUSE_STUN)
|
||||
set(SRB2_DISCORDRPC_SOURCES discord.c stun.c)
|
||||
set(SRB2_DISCORDRPC_HEADERS discord.h stun.h)
|
||||
prepend_sources(SRB2_DISCORDRPC_SOURCES)
|
||||
prepend_sources(SRB2_DISCORDRPC_HEADERS)
|
||||
source_group("Discord Rich Presence" FILES ${SRB2_DISCORDRPC_SOURCES} ${SRB2_DISCORDRPC_HEADERS})
|
||||
|
|
|
|||
|
|
@ -393,8 +393,8 @@ endif
|
|||
|
||||
ifdef HAVE_DISCORDRPC
|
||||
LIBS+=-ldiscord-rpc
|
||||
CFLAGS+=-DHAVE_DISCORDRPC
|
||||
OBJS+=$(OBJDIR)/discord.o
|
||||
CFLAGS+=-DHAVE_DISCORDRPC -DUSE_STUN
|
||||
OBJS+=$(OBJDIR)/discord.o $(OBJDIR)/stun.o
|
||||
endif
|
||||
|
||||
include blua/Makefile.cfg
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ enum
|
|||
/* Command buffer flags. */
|
||||
enum
|
||||
{
|
||||
COM_SAFE = 1,
|
||||
COM_SAFE = 0x01,
|
||||
};
|
||||
|
||||
typedef void (*com_func_t)(void);
|
||||
|
|
|
|||
140
src/d_clisrv.c
140
src/d_clisrv.c
|
|
@ -546,6 +546,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
|
||||
// Score is resynched in the rspfirm resync packet
|
||||
rsp->rings = SHORT(players[i].rings);
|
||||
rsp->spheres = SHORT(players[i].spheres);
|
||||
rsp->lives = players[i].lives;
|
||||
rsp->lostlife = players[i].lostlife;
|
||||
rsp->continues = players[i].continues;
|
||||
|
|
@ -616,7 +617,14 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
|
||||
rsp->airtime = (tic_t)LONG(players[i].airtime);
|
||||
rsp->trickpanel = (UINT8)players[i].trickpanel;
|
||||
rsp->trickdelay = (tic_t)LONG(players[i].trickdelay);
|
||||
rsp->trickdelay = (boolean)players[i].trickdelay;
|
||||
rsp->trickmomx = (fixed_t)LONG(players[i].trickmomx);
|
||||
rsp->trickmomy = (fixed_t)LONG(players[i].trickmomy);
|
||||
rsp->trickmomz = (fixed_t)LONG(players[i].trickmomz);
|
||||
|
||||
rsp->bumpers = players[i].bumpers;
|
||||
rsp->karmadelay = SHORT(players[i].karmadelay);
|
||||
rsp->eliminated = players[i].eliminated;
|
||||
|
||||
// respawnvars_t
|
||||
rsp->respawn_state = players[i].respawn.state;
|
||||
|
|
@ -692,6 +700,7 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
|
||||
// Score is resynched in the rspfirm resync packet
|
||||
players[i].rings = SHORT(rsp->rings);
|
||||
players[i].spheres = SHORT(rsp->spheres);
|
||||
players[i].lives = rsp->lives;
|
||||
players[i].lostlife = rsp->lostlife;
|
||||
players[i].continues = rsp->continues;
|
||||
|
|
@ -761,7 +770,14 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
|
||||
players[i].airtime = (tic_t)LONG(rsp->airtime);
|
||||
players[i].trickpanel = (UINT8)rsp->trickpanel;
|
||||
players[i].trickdelay = (tic_t)LONG(rsp->trickdelay);
|
||||
players[i].trickdelay = (boolean)rsp->trickdelay;
|
||||
players[i].trickmomx = (fixed_t)LONG(rsp->trickmomx);
|
||||
players[i].trickmomy = (fixed_t)LONG(rsp->trickmomy);
|
||||
players[i].trickmomz = (fixed_t)LONG(rsp->trickmomz);
|
||||
|
||||
players[i].bumpers = rsp->bumpers;
|
||||
players[i].karmadelay = SHORT(rsp->karmadelay);
|
||||
players[i].eliminated = rsp->eliminated;
|
||||
|
||||
// respawnvars_t
|
||||
players[i].respawn.state = rsp->respawn_state;
|
||||
|
|
@ -1250,7 +1266,7 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
cltext = M_GetText("Server full, waiting for a slot...");
|
||||
else
|
||||
cltext = M_GetText("Requesting to join...");
|
||||
|
||||
|
||||
break;
|
||||
#ifdef HAVE_CURL
|
||||
case CL_PREPAREHTTPFILES:
|
||||
|
|
@ -1994,6 +2010,9 @@ static void SendAskInfo(INT32 node)
|
|||
// now allowed traffic from the host to us in, so once the MS relays
|
||||
// our address to the host, it'll be able to speak to us.
|
||||
HSendPacket(node, false, 0, sizeof (askinfo_pak));
|
||||
|
||||
if (node != 0 && node != BROADCASTADDR)
|
||||
I_NetRequestHolePunch();
|
||||
}
|
||||
|
||||
serverelem_t serverlist[MAXSERVERLIST];
|
||||
|
|
@ -2116,7 +2135,7 @@ void CL_UpdateServerList (void)
|
|||
|
||||
static void M_ConfirmConnect(event_t *ev)
|
||||
{
|
||||
#ifndef NONET
|
||||
#ifndef NONET
|
||||
if (ev->type == ev_keydown)
|
||||
{
|
||||
if (ev->data1 == ' ' || ev->data1 == 'y' || ev->data1 == KEY_ENTER || ev->data1 == gamecontrol[0][gc_accelerate][0] || ev->data1 == gamecontrol[0][gc_accelerate][1])
|
||||
|
|
@ -2139,7 +2158,7 @@ static void M_ConfirmConnect(event_t *ev)
|
|||
}
|
||||
else
|
||||
cl_mode = CL_LOADFILES;
|
||||
|
||||
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
else if (ev->data1 == 'n' || ev->data1 == KEY_ESCAPE|| ev->data1 == gamecontrol[0][gc_brake][0] || ev->data1 == gamecontrol[0][gc_brake][1])
|
||||
|
|
@ -2350,7 +2369,10 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent)
|
|||
cl_mode = CL_CHECKFILES;
|
||||
}
|
||||
else
|
||||
{
|
||||
cl_mode = CL_ASKJOIN; // files need not be checked for the server.
|
||||
*asksent = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2384,7 +2406,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
{
|
||||
boolean waitmore;
|
||||
INT32 i;
|
||||
|
||||
|
||||
#ifdef NONET
|
||||
(void)tmpsave;
|
||||
#endif
|
||||
|
|
@ -2421,7 +2443,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
{
|
||||
curl_transfers++;
|
||||
}
|
||||
|
||||
|
||||
cl_mode = CL_DOWNLOADHTTPFILES;
|
||||
}
|
||||
break;
|
||||
|
|
@ -2986,9 +3008,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
|
|||
}
|
||||
}
|
||||
|
||||
if (K_IsPlayerWanted(&players[playernum]))
|
||||
K_CalculateBattleWanted();
|
||||
|
||||
K_CalculateBattleWanted();
|
||||
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
|
||||
|
||||
// don't look through someone's view who isn't there
|
||||
|
|
@ -3579,6 +3599,76 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
/** Add a login for HTTP downloads. If the
|
||||
* user/password is missing, remove it.
|
||||
*
|
||||
* \sa Command_list_http_logins
|
||||
*/
|
||||
static void Command_set_http_login (void)
|
||||
{
|
||||
HTTP_login *login;
|
||||
HTTP_login **prev_next;
|
||||
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(
|
||||
"set_http_login <URL> [user:password]: Set or remove a login to "
|
||||
"authenticate HTTP downloads.\n"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
login = CURLGetLogin(COM_Argv(1), &prev_next);
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
{
|
||||
if (login)
|
||||
{
|
||||
(*prev_next) = login->next;
|
||||
CONS_Printf("Login for '%s' removed.\n", login->url);
|
||||
Z_Free(login);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (login)
|
||||
Z_Free(login->auth);
|
||||
else
|
||||
{
|
||||
login = ZZ_Alloc(sizeof *login);
|
||||
login->url = Z_StrDup(COM_Argv(1));
|
||||
}
|
||||
|
||||
login->auth = Z_StrDup(COM_Argv(2));
|
||||
|
||||
login->next = curl_logins;
|
||||
curl_logins = login;
|
||||
}
|
||||
}
|
||||
|
||||
/** List logins for HTTP downloads.
|
||||
*
|
||||
* \sa Command_set_http_login
|
||||
*/
|
||||
static void Command_list_http_logins (void)
|
||||
{
|
||||
HTTP_login *login;
|
||||
|
||||
for (
|
||||
login = curl_logins;
|
||||
login;
|
||||
login = login->next
|
||||
){
|
||||
CONS_Printf(
|
||||
"'%s' -> '%s'\n",
|
||||
login->url,
|
||||
login->auth
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif/*HAVE_CURL*/
|
||||
|
||||
static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_netticbuffer = CVAR_INIT ("netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL);
|
||||
|
||||
|
|
@ -3654,6 +3744,10 @@ void D_ClientServerInit(void)
|
|||
COM_AddCommand("reloadbans", Command_ReloadBan);
|
||||
COM_AddCommand("connect", Command_connect);
|
||||
COM_AddCommand("nodes", Command_Nodes);
|
||||
#ifdef HAVE_CURL
|
||||
COM_AddCommand("set_http_login", Command_set_http_login);
|
||||
COM_AddCommand("list_http_logins", Command_list_http_logins);
|
||||
#endif
|
||||
#ifdef PACKETDROP
|
||||
COM_AddCommand("drop", Command_Drop);
|
||||
COM_AddCommand("droprate", Command_Droprate);
|
||||
|
|
@ -5491,7 +5585,10 @@ static void CL_SendClientCmd(void)
|
|||
boolean mis = false;
|
||||
|
||||
if (lowest_lag && ( gametic % lowest_lag ))
|
||||
{
|
||||
cl_packetmissed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
netbuffer->packettype = PT_CLIENTCMD;
|
||||
|
||||
|
|
@ -6016,6 +6113,19 @@ static void UpdatePingTable(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void RenewHolePunch(void)
|
||||
{
|
||||
static time_t past;
|
||||
|
||||
const time_t now = time(NULL);
|
||||
|
||||
if ((now - past) > 20)
|
||||
{
|
||||
I_NetRegisterHolePunch();
|
||||
past = now;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle timeouts to prevent definitive freezes from happenning
|
||||
static void HandleNodeTimeouts(void)
|
||||
{
|
||||
|
|
@ -6054,6 +6164,11 @@ void NetKeepAlive(void)
|
|||
MasterClient_Ticker();
|
||||
#endif
|
||||
|
||||
if (netgame && serverrunning)
|
||||
{
|
||||
RenewHolePunch();
|
||||
}
|
||||
|
||||
if (client)
|
||||
{
|
||||
// send keep alive
|
||||
|
|
@ -6113,6 +6228,11 @@ void NetUpdate(void)
|
|||
MasterClient_Ticker(); // Acking the Master Server
|
||||
#endif
|
||||
|
||||
if (netgame && serverrunning)
|
||||
{
|
||||
RenewHolePunch();
|
||||
}
|
||||
|
||||
if (client)
|
||||
{
|
||||
if (!resynch_local_inprogress)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ applications may follow different packet versions.
|
|||
// be transmitted.
|
||||
|
||||
// Networking and tick handling related.
|
||||
#define BACKUPTICS 32
|
||||
#define BACKUPTICS 1024
|
||||
#define TICQUEUE 512 // more than enough for most timeouts....
|
||||
#define MAXTEXTCMD 256
|
||||
//
|
||||
|
|
@ -214,6 +214,7 @@ typedef struct
|
|||
|
||||
// Score is resynched in the confirm resync packet
|
||||
INT16 rings;
|
||||
INT16 spheres;
|
||||
SINT8 lives;
|
||||
boolean lostlife;
|
||||
SINT8 continues;
|
||||
|
|
@ -281,7 +282,14 @@ typedef struct
|
|||
INT32 kartstuff[NUMKARTSTUFF];
|
||||
tic_t airtime;
|
||||
UINT8 trickpanel;
|
||||
tic_t trickdelay;
|
||||
boolean trickdelay;
|
||||
fixed_t trickmomx;
|
||||
fixed_t trickmomy;
|
||||
fixed_t trickmomz;
|
||||
|
||||
UINT8 bumpers;
|
||||
INT16 karmadelay;
|
||||
boolean eliminated;
|
||||
|
||||
// respawnvars_t
|
||||
UINT8 respawn_state;
|
||||
|
|
@ -569,6 +577,7 @@ extern INT32 mapchangepending;
|
|||
|
||||
// Points inside doomcom
|
||||
extern doomdata_t *netbuffer;
|
||||
extern consvar_t cv_stunserver;
|
||||
extern consvar_t cv_httpsource;
|
||||
|
||||
extern consvar_t cv_showjoinaddress;
|
||||
|
|
|
|||
|
|
@ -1494,6 +1494,11 @@ void D_SRB2Main(void)
|
|||
|
||||
CON_Init();
|
||||
|
||||
memset(timelimits, 0, sizeof(timelimits));
|
||||
memset(pointlimits, 0, sizeof(pointlimits));
|
||||
|
||||
timelimits[GT_BATTLE] = 2;
|
||||
|
||||
D_RegisterServerCommands();
|
||||
D_RegisterClientCommands(); // be sure that this is called before D_CheckNetGame
|
||||
R_RegisterEngineStuff();
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ tic_t connectiontimeout = (10*TICRATE);
|
|||
doomcom_t *doomcom = NULL;
|
||||
/// \brief network packet data, points inside doomcom
|
||||
doomdata_t *netbuffer = NULL;
|
||||
/// \brief hole punching packet, also points inside doomcom
|
||||
holepunch_t *holepunchpacket = NULL;
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
FILE *debugfile = NULL; // put some net info in a file during the game
|
||||
|
|
@ -72,6 +74,8 @@ boolean (*I_NetCanGet)(void) = NULL;
|
|||
void (*I_NetCloseSocket)(void) = NULL;
|
||||
void (*I_NetFreeNodenum)(INT32 nodenum) = NULL;
|
||||
SINT8 (*I_NetMakeNodewPort)(const char *address, const char* port) = NULL;
|
||||
void (*I_NetRequestHolePunch)(void) = NULL;
|
||||
void (*I_NetRegisterHolePunch)(void) = NULL;
|
||||
boolean (*I_NetOpenSocket)(void) = NULL;
|
||||
boolean (*I_Ban) (INT32 node) = NULL;
|
||||
void (*I_ClearBans)(void) = NULL;
|
||||
|
|
@ -1347,6 +1351,7 @@ boolean D_CheckNetGame(void)
|
|||
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES);
|
||||
|
||||
netbuffer = (doomdata_t *)(void *)&doomcom->data;
|
||||
holepunchpacket = (holepunch_t *)(void *)&doomcom->data;
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (M_CheckParm("-debugfile"))
|
||||
|
|
|
|||
|
|
@ -289,10 +289,10 @@ consvar_t cv_skin[MAXSPLITSCREENPLAYERS] = {
|
|||
|
||||
// player's followers. Also saved.
|
||||
consvar_t cv_follower[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("follower", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange),
|
||||
CVAR_INIT ("follower2", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange),
|
||||
CVAR_INIT ("follower3", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange),
|
||||
CVAR_INIT ("follower4", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange)
|
||||
CVAR_INIT ("follower", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange),
|
||||
CVAR_INIT ("follower2", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange),
|
||||
CVAR_INIT ("follower3", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange),
|
||||
CVAR_INIT ("follower4", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange)
|
||||
};
|
||||
|
||||
// player's follower colors... Also saved...
|
||||
|
|
@ -453,8 +453,7 @@ consvar_t cv_scrambleonchange = CVAR_INIT ("scrambleonchange", "Off", CV_SAVE|CV
|
|||
consvar_t cv_itemfinder = CVAR_INIT ("itemfinder", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, ItemFinder_OnChange);
|
||||
|
||||
// Scoring type options
|
||||
static CV_PossibleValue_t overtime_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Super"}, {0, NULL}};
|
||||
consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_NETVAR|CV_CHEAT, overtime_cons_t, NULL);
|
||||
consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL);
|
||||
|
||||
consvar_t cv_rollingdemos = CVAR_INIT ("rollingdemos", "On", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
|
|
@ -462,9 +461,9 @@ static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"},
|
|||
consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange);
|
||||
static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}};
|
||||
consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange);
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_numlaps = CVAR_INIT ("numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange);
|
||||
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}};
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_numlaps = CVAR_INIT ("numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange);
|
||||
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, "Map default"}, {0, NULL}};
|
||||
consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange);
|
||||
|
||||
// Point and time limits for every gametype
|
||||
|
|
@ -749,6 +748,10 @@ void D_RegisterServerCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_dummyconsvar);
|
||||
|
||||
#ifdef USE_STUN
|
||||
CV_RegisterVar(&cv_stunserver);
|
||||
#endif
|
||||
|
||||
CV_RegisterVar(&cv_discordinvites);
|
||||
RegisterNetXCmd(XD_DISCORD, Got_DiscordInfo);
|
||||
}
|
||||
|
|
@ -2854,13 +2857,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
memset(&luabanks, 0, sizeof(luabanks));
|
||||
}
|
||||
|
||||
if (modeattacking)
|
||||
{
|
||||
SetPlayerSkinByNum(0, cv_chooseskin.value-1);
|
||||
players[0].skincolor = skins[players[0].skin].prefcolor;
|
||||
CV_StealthSetValue(&cv_playercolor[0], players[0].skincolor);
|
||||
}
|
||||
|
||||
mapnumber = M_MapNumber(mapname[3], mapname[4]);
|
||||
LUAh_MapChange(mapnumber);
|
||||
|
||||
|
|
@ -3470,8 +3466,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
if (gametyperules & GTR_BUMPERS) // SRB2kart
|
||||
{
|
||||
players[playernum].marescore = 0;
|
||||
if (K_IsPlayerWanted(&players[playernum]))
|
||||
K_CalculateBattleWanted();
|
||||
K_CalculateBattleWanted();
|
||||
}
|
||||
|
||||
K_PlayerForfeit(playernum, true);
|
||||
|
|
@ -4330,15 +4325,13 @@ static void TimeLimit_OnChange(void)
|
|||
|
||||
if (cv_timelimit.value != 0)
|
||||
{
|
||||
CONS_Printf(M_GetText("Levels will end after %d second%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003
|
||||
timelimitintics = cv_timelimit.value * TICRATE;
|
||||
CONS_Printf(M_GetText("Rounds will end after %d minute%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003
|
||||
timelimitintics = cv_timelimit.value * (60*TICRATE);
|
||||
|
||||
// Note the deliberate absence of any code preventing
|
||||
// pointlimit and timelimit from being set simultaneously.
|
||||
// Some people might like to use them together. It works.
|
||||
}
|
||||
else if (netgame || multiplayer)
|
||||
CONS_Printf(M_GetText("Time limit disabled\n"));
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
DRPC_UpdatePresence();
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ static UINT32 curl_origfilesize;
|
|||
static UINT32 curl_origtotalfilesize;
|
||||
static char *curl_realname = NULL;
|
||||
fileneeded_t *curl_curfile = NULL;
|
||||
HTTP_login *curl_logins;
|
||||
#endif
|
||||
|
||||
luafiletransfer_t *luafiletransfers = NULL;
|
||||
|
|
@ -476,10 +477,10 @@ INT32 CL_CheckFiles(void)
|
|||
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
{
|
||||
if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_FALLBACK)
|
||||
if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD || fileneeded[i].status == FS_FALLBACK)
|
||||
downloadrequired = true;
|
||||
|
||||
if (fileneeded[i].status == FS_FOUND || fileneeded[i].status == FS_NOTFOUND)
|
||||
if (fileneeded[i].status != FS_OPEN)
|
||||
filestoload++;
|
||||
|
||||
if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics
|
||||
|
|
@ -1646,6 +1647,8 @@ int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ul
|
|||
|
||||
void CURLPrepareFile(const char* url, int dfilenum)
|
||||
{
|
||||
HTTP_login *login;
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (M_CheckParm("-nodownload"))
|
||||
I_Error("Attempted to download files in -nodownload mode");
|
||||
|
|
@ -1674,6 +1677,14 @@ void CURLPrepareFile(const char* url, int dfilenum)
|
|||
|
||||
curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d", VERSION, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents.
|
||||
|
||||
// Authenticate if the user so wishes
|
||||
login = CURLGetLogin(url, NULL);
|
||||
|
||||
if (login)
|
||||
{
|
||||
curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth);
|
||||
}
|
||||
|
||||
// Follow a redirect request, if sent by the server.
|
||||
curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
|
||||
|
|
@ -1775,4 +1786,27 @@ void CURLGetFile(void)
|
|||
curl_global_cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
HTTP_login *
|
||||
CURLGetLogin (const char *url, HTTP_login ***return_prev_next)
|
||||
{
|
||||
HTTP_login * login;
|
||||
HTTP_login ** prev_next;
|
||||
|
||||
for (
|
||||
prev_next = &curl_logins;
|
||||
( login = (*prev_next));
|
||||
prev_next = &login->next
|
||||
){
|
||||
if (strcmp(login->url, url) == 0)
|
||||
{
|
||||
if (return_prev_next)
|
||||
(*return_prev_next) = prev_next;
|
||||
|
||||
return login;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -72,6 +72,16 @@ extern UINT32 totalfilesrequestedsize;
|
|||
extern boolean curl_failedwebdownload;
|
||||
extern boolean curl_running;
|
||||
extern INT32 curl_transfers;
|
||||
|
||||
typedef struct HTTP_login HTTP_login;
|
||||
|
||||
extern struct HTTP_login
|
||||
{
|
||||
char * url;
|
||||
char * auth;
|
||||
HTTP_login * next;
|
||||
}
|
||||
*curl_logins;
|
||||
#endif
|
||||
|
||||
UINT8 *PutFileNeeded(UINT16 firstfile);
|
||||
|
|
@ -151,6 +161,7 @@ size_t nameonlylength(const char *s);
|
|||
#ifdef HAVE_CURL
|
||||
void CURLPrepareFile(const char* url, int dfilenum);
|
||||
void CURLGetFile(void);
|
||||
HTTP_login * CURLGetLogin (const char *url, HTTP_login ***return_prev_next);
|
||||
#endif
|
||||
|
||||
#endif // __D_NETFIL__
|
||||
|
|
|
|||
|
|
@ -449,6 +449,10 @@ typedef enum
|
|||
// QUICKLY GET RING TOTAL, INCLUDING RINGS CURRENTLY IN THE PICKUP ANIMATION
|
||||
#define RINGTOTAL(p) (p->rings + p->kartstuff[k_pickuprings])
|
||||
|
||||
// CONSTANTS FOR TRICK PANELS
|
||||
#define TRICKMOMZRAMP (30)
|
||||
#define TRICKLAG (9)
|
||||
|
||||
//}
|
||||
|
||||
// player_t struct for all respawn variables
|
||||
|
|
@ -512,6 +516,7 @@ typedef struct player_s
|
|||
|
||||
// player's ring count
|
||||
INT16 rings;
|
||||
INT16 spheres;
|
||||
|
||||
// Power ups. invinc and invis are tic counters.
|
||||
UINT16 powers[NUMPOWERS];
|
||||
|
|
@ -522,9 +527,18 @@ typedef struct player_s
|
|||
UINT32 distancetofinish;
|
||||
waypoint_t *nextwaypoint;
|
||||
respawnvars_t respawn; // Respawn info
|
||||
tic_t airtime; // Keep track of how long you've been in the air
|
||||
UINT8 trickpanel; // Trick panel state
|
||||
tic_t trickdelay;
|
||||
tic_t airtime; // Keep track of how long you've been in the air
|
||||
|
||||
UINT8 trickpanel; // Trick panel state
|
||||
boolean trickdelay; // Prevent tricks until control stick is neutral
|
||||
fixed_t trickmomx;
|
||||
fixed_t trickmomy;
|
||||
fixed_t trickmomz; // Instead of stupid auxiliary variables let's... just make some ourselves.
|
||||
|
||||
UINT8 bumpers;
|
||||
INT16 karmadelay;
|
||||
boolean eliminated;
|
||||
|
||||
|
||||
// Bit flags.
|
||||
// See pflags_t, above.
|
||||
|
|
|
|||
265
src/dehacked.c
265
src/dehacked.c
|
|
@ -1271,8 +1271,6 @@ static void readspriteframe(MYFILE *f, spriteinfo_t *sprinfo, UINT8 frame)
|
|||
sprinfo->pivot[frame].x = value;
|
||||
else if (fastcmp(word, "YPIVOT"))
|
||||
sprinfo->pivot[frame].y = value;
|
||||
else if (fastcmp(word, "ROTAXIS"))
|
||||
sprinfo->pivot[frame].rotaxis = value;
|
||||
else
|
||||
{
|
||||
f->curpos = lastline;
|
||||
|
|
@ -6174,10 +6172,43 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_FASTRING11",
|
||||
"S_FASTRING12",
|
||||
|
||||
// Blue Sphere for special stages
|
||||
// Blue Sphere
|
||||
"S_BLUESPHERE",
|
||||
"S_BLUESPHEREBONUS",
|
||||
"S_BLUESPHERESPARK",
|
||||
"S_BLUESPHERE_SPAWN",
|
||||
|
||||
"S_BLUESPHERE_BOUNCE1",
|
||||
"S_BLUESPHERE_BOUNCE2",
|
||||
|
||||
"S_BLUESPHERE_BOUNCE3",
|
||||
"S_BLUESPHERE_BOUNCE4",
|
||||
|
||||
"S_BLUESPHERE_BOUNCE5",
|
||||
"S_BLUESPHERE_BOUNCE6",
|
||||
"S_BLUESPHERE_BOUNCE7",
|
||||
"S_BLUESPHERE_BOUNCE8",
|
||||
|
||||
"S_BLUESPHERE_BOUNCE9",
|
||||
"S_BLUESPHERE_BOUNCE10",
|
||||
"S_BLUESPHERE_BOUNCE11",
|
||||
"S_BLUESPHERE_BOUNCE12",
|
||||
|
||||
"S_BLUESPHERE_BOUNCE13",
|
||||
"S_BLUESPHERE_BOUNCE14",
|
||||
"S_BLUESPHERE_BOUNCE15",
|
||||
"S_BLUESPHERE_BOUNCE16",
|
||||
"S_BLUESPHERE_BOUNCE17",
|
||||
"S_BLUESPHERE_BOUNCE18",
|
||||
"S_BLUESPHERE_BOUNCE19",
|
||||
"S_BLUESPHERE_BOUNCE20",
|
||||
|
||||
"S_BLUESPHERE_BOUNCE21",
|
||||
"S_BLUESPHERE_BOUNCE22",
|
||||
"S_BLUESPHERE_BOUNCE23",
|
||||
"S_BLUESPHERE_BOUNCE24",
|
||||
"S_BLUESPHERE_BOUNCE25",
|
||||
"S_BLUESPHERE_BOUNCE26",
|
||||
"S_BLUESPHERE_BOUNCE27",
|
||||
"S_BLUESPHERE_BOUNCE28",
|
||||
|
||||
// Bomb Sphere
|
||||
"S_BOMBSPHERE1",
|
||||
|
|
@ -6236,13 +6267,17 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_EMBLEM26",
|
||||
|
||||
// Chaos Emeralds
|
||||
"S_CEMG1",
|
||||
"S_CEMG2",
|
||||
"S_CEMG3",
|
||||
"S_CEMG4",
|
||||
"S_CEMG5",
|
||||
"S_CEMG6",
|
||||
"S_CEMG7",
|
||||
"S_CHAOSEMERALD1",
|
||||
"S_CHAOSEMERALD2",
|
||||
"S_CHAOSEMERALD_UNDER",
|
||||
|
||||
"S_EMERALDSPARK1",
|
||||
"S_EMERALDSPARK2",
|
||||
"S_EMERALDSPARK3",
|
||||
"S_EMERALDSPARK4",
|
||||
"S_EMERALDSPARK5",
|
||||
"S_EMERALDSPARK6",
|
||||
"S_EMERALDSPARK7",
|
||||
|
||||
// Emerald hunt shards
|
||||
"S_SHRD1",
|
||||
|
|
@ -8687,6 +8722,44 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_BATTLEBUMPER2",
|
||||
"S_BATTLEBUMPER3",
|
||||
|
||||
"S_BATTLEBUMPER_EXCRYSTALA1",
|
||||
"S_BATTLEBUMPER_EXCRYSTALA2",
|
||||
"S_BATTLEBUMPER_EXCRYSTALA3",
|
||||
"S_BATTLEBUMPER_EXCRYSTALA4",
|
||||
|
||||
"S_BATTLEBUMPER_EXCRYSTALB1",
|
||||
"S_BATTLEBUMPER_EXCRYSTALB2",
|
||||
"S_BATTLEBUMPER_EXCRYSTALB3",
|
||||
"S_BATTLEBUMPER_EXCRYSTALB4",
|
||||
|
||||
"S_BATTLEBUMPER_EXCRYSTALC1",
|
||||
"S_BATTLEBUMPER_EXCRYSTALC2",
|
||||
"S_BATTLEBUMPER_EXCRYSTALC3",
|
||||
"S_BATTLEBUMPER_EXCRYSTALC4",
|
||||
|
||||
"S_BATTLEBUMPER_EXSHELLA1",
|
||||
"S_BATTLEBUMPER_EXSHELLA2",
|
||||
|
||||
"S_BATTLEBUMPER_EXSHELLB1",
|
||||
"S_BATTLEBUMPER_EXSHELLB2",
|
||||
|
||||
"S_BATTLEBUMPER_EXSHELLC1",
|
||||
"S_BATTLEBUMPER_EXSHELLC2",
|
||||
|
||||
"S_BATTLEBUMPER_EXDEBRIS1",
|
||||
"S_BATTLEBUMPER_EXDEBRIS2",
|
||||
|
||||
"S_BATTLEBUMPER_EXBLAST1",
|
||||
"S_BATTLEBUMPER_EXBLAST2",
|
||||
"S_BATTLEBUMPER_EXBLAST3",
|
||||
"S_BATTLEBUMPER_EXBLAST4",
|
||||
"S_BATTLEBUMPER_EXBLAST5",
|
||||
"S_BATTLEBUMPER_EXBLAST6",
|
||||
"S_BATTLEBUMPER_EXBLAST7",
|
||||
"S_BATTLEBUMPER_EXBLAST8",
|
||||
"S_BATTLEBUMPER_EXBLAST9",
|
||||
"S_BATTLEBUMPER_EXBLAST10",
|
||||
|
||||
// DEZ respawn laser
|
||||
"S_DEZLASER",
|
||||
"S_DEZLASER_TRAIL1",
|
||||
|
|
@ -9287,9 +9360,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
"S_TIREGREASE",
|
||||
|
||||
"S_OVERTIMEFOG",
|
||||
"S_OVERTIMEORB",
|
||||
"S_OVERTIMEBEAM",
|
||||
"S_OVERTIME_BULB1",
|
||||
"S_OVERTIME_BULB2",
|
||||
"S_OVERTIME_LASER",
|
||||
"S_OVERTIME_CENTER",
|
||||
|
||||
"S_BATTLECAPSULE_SIDE1",
|
||||
"S_BATTLECAPSULE_SIDE2",
|
||||
|
|
@ -9317,6 +9391,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_WATERTRAILUNDERLAY7",
|
||||
"S_WATERTRAILUNDERLAY8",
|
||||
|
||||
"S_SPINDASHDUST",
|
||||
"S_SPINDASHWIND",
|
||||
|
||||
#ifdef SEENAMES
|
||||
"S_NAMECHECK",
|
||||
#endif
|
||||
|
|
@ -9465,16 +9542,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_REDFLAG", // Red CTF Flag
|
||||
"MT_BLUEFLAG", // Blue CTF Flag
|
||||
"MT_EMBLEM",
|
||||
"MT_EMERALD1",
|
||||
"MT_EMERALD2",
|
||||
"MT_EMERALD3",
|
||||
"MT_EMERALD4",
|
||||
"MT_EMERALD5",
|
||||
"MT_EMERALD6",
|
||||
"MT_EMERALD7",
|
||||
"MT_EMERALD",
|
||||
"MT_EMERALDSPARK",
|
||||
"MT_EMERHUNT", // Emerald Hunt
|
||||
"MT_EMERALDSPAWN", // Emerald spawner w/ delay
|
||||
"MT_FLINGEMERALD", // Lost emerald
|
||||
|
||||
// Springs and others
|
||||
"MT_FAN",
|
||||
|
|
@ -10169,6 +10240,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_SINKTRAIL",
|
||||
|
||||
"MT_BATTLEBUMPER", // Battle Mode bumper
|
||||
"MT_BATTLEBUMPER_DEBRIS",
|
||||
"MT_BATTLEBUMPER_BLAST",
|
||||
|
||||
"MT_DEZLASER",
|
||||
|
||||
|
|
@ -10383,9 +10456,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_SPBDUST",
|
||||
"MT_TIREGREASE",
|
||||
|
||||
"MT_OVERTIMEFOG",
|
||||
"MT_OVERTIMEORB",
|
||||
"MT_OVERTIMEBEAM",
|
||||
"MT_OVERTIME_PARTICLE",
|
||||
"MT_OVERTIME_CENTER",
|
||||
|
||||
"MT_BATTLECAPSULE",
|
||||
"MT_BATTLECAPSULE_PIECE",
|
||||
|
|
@ -10397,6 +10469,11 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_WATERTRAIL",
|
||||
"MT_WATERTRAILUNDERLAY",
|
||||
|
||||
"MT_SPINDASHDUST",
|
||||
"MT_SPINDASHWIND",
|
||||
|
||||
"MT_PAPERITEMSPOT",
|
||||
|
||||
#ifdef SEENAMES
|
||||
"MT_NAMECHECK",
|
||||
#endif
|
||||
|
|
@ -10717,67 +10794,67 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
|
|||
|
||||
// Special super colors
|
||||
// Super Sonic Yellow
|
||||
"SUPER1", // SKINCOLOR_SUPER1
|
||||
"SUPER2", // SKINCOLOR_SUPER2,
|
||||
"SUPER3", // SKINCOLOR_SUPER3,
|
||||
"SUPER4", // SKINCOLOR_SUPER4,
|
||||
"SUPER5", // SKINCOLOR_SUPER5,
|
||||
"SUPERSILVER1",
|
||||
"SUPERSILVER2",
|
||||
"SUPERSILVER3",
|
||||
"SUPERSILVER4",
|
||||
"SUPERSILVER5",
|
||||
|
||||
// Super Tails Orange
|
||||
"TSUPER1", // SKINCOLOR_TSUPER1,
|
||||
"TSUPER2", // SKINCOLOR_TSUPER2,
|
||||
"TSUPER3", // SKINCOLOR_TSUPER3,
|
||||
"TSUPER4", // SKINCOLOR_TSUPER4,
|
||||
"TSUPER5", // SKINCOLOR_TSUPER5,
|
||||
"SUPERRED1",
|
||||
"SUPERRED2",
|
||||
"SUPERRED3",
|
||||
"SUPERRED4",
|
||||
"SUPERRED5",
|
||||
|
||||
// Super Knuckles Red
|
||||
"KSUPER1", // SKINCOLOR_KSUPER1,
|
||||
"KSUPER2", // SKINCOLOR_KSUPER2,
|
||||
"KSUPER3", // SKINCOLOR_KSUPER3,
|
||||
"KSUPER4", // SKINCOLOR_KSUPER4,
|
||||
"KSUPER5", // SKINCOLOR_KSUPER5,
|
||||
"SUPERORANGE1",
|
||||
"SUPERORANGE2",
|
||||
"SUPERORANGE3",
|
||||
"SUPERORANGE4",
|
||||
"SUPERORANGE5",
|
||||
|
||||
// Hyper Sonic Pink
|
||||
"PSUPER1", // SKINCOLOR_PSUPER1,
|
||||
"PSUPER2", // SKINCOLOR_PSUPER2,
|
||||
"PSUPER3", // SKINCOLOR_PSUPER3,
|
||||
"PSUPER4", // SKINCOLOR_PSUPER4,
|
||||
"PSUPER5", // SKINCOLOR_PSUPER5,
|
||||
"SUPERGOLD1",
|
||||
"SUPERGOLD2",
|
||||
"SUPERGOLD3",
|
||||
"SUPERGOLD4",
|
||||
"SUPERGOLD5",
|
||||
|
||||
// Hyper Sonic Blue
|
||||
"BSUPER1", // SKINCOLOR_BSUPER1,
|
||||
"BSUPER2", // SKINCOLOR_BSUPER2,
|
||||
"BSUPER3", // SKINCOLOR_BSUPER3,
|
||||
"BSUPER4", // SKINCOLOR_BSUPER4,
|
||||
"BSUPER5", // SKINCOLOR_BSUPER5,
|
||||
"SUPERPERIDOT1",
|
||||
"SUPERPERIDOT2",
|
||||
"SUPERPERIDOT3",
|
||||
"SUPERPERIDOT4",
|
||||
"SUPERPERIDOT5",
|
||||
|
||||
// Aqua Super
|
||||
"ASUPER1", // SKINCOLOR_ASUPER1,
|
||||
"ASUPER2", // SKINCOLOR_ASUPER2,
|
||||
"ASUPER3", // SKINCOLOR_ASUPER3,
|
||||
"ASUPER4", // SKINCOLOR_ASUPER4,
|
||||
"ASUPER5", // SKINCOLOR_ASUPER5,
|
||||
"SUPERSKY1",
|
||||
"SUPERSKY2",
|
||||
"SUPERSKY3",
|
||||
"SUPERSKY4",
|
||||
"SUPERSKY5",
|
||||
|
||||
// Hyper Sonic Green
|
||||
"GSUPER1", // SKINCOLOR_GSUPER1,
|
||||
"GSUPER2", // SKINCOLOR_GSUPER2,
|
||||
"GSUPER3", // SKINCOLOR_GSUPER3,
|
||||
"GSUPER4", // SKINCOLOR_GSUPER4,
|
||||
"GSUPER5", // SKINCOLOR_GSUPER5,
|
||||
"SUPERPURPLE1",
|
||||
"SUPERPURPLE2",
|
||||
"SUPERPURPLE3",
|
||||
"SUPERPURPLE4",
|
||||
"SUPERPURPLE5",
|
||||
|
||||
// Hyper Sonic White
|
||||
"WSUPER1", // SKINCOLOR_WSUPER1,
|
||||
"WSUPER2", // SKINCOLOR_WSUPER2,
|
||||
"WSUPER3", // SKINCOLOR_WSUPER3,
|
||||
"WSUPER4", // SKINCOLOR_WSUPER4,
|
||||
"WSUPER5", // SKINCOLOR_WSUPER5,
|
||||
"SUPERRUST1",
|
||||
"SUPERRUST2",
|
||||
"SUPERRUST3",
|
||||
"SUPERRUST4",
|
||||
"SUPERRUST5",
|
||||
|
||||
// Creamy Super (Shadow?)
|
||||
"CSUPER1", // SKINCOLOR_CSUPER1,
|
||||
"CSUPER2", // SKINCOLOR_CSUPER2,
|
||||
"CSUPER3", // SKINCOLOR_CSUPER3,
|
||||
"CSUPER4", // SKINCOLOR_CSUPER4,
|
||||
"CSUPER5" // SKINCOLOR_CSUPER5,
|
||||
"SUPERTAN1",
|
||||
"SUPERTAN2",
|
||||
"SUPERTAN3",
|
||||
"SUPERTAN4",
|
||||
"SUPERTAN5",
|
||||
|
||||
"CHAOSEMERALD1",
|
||||
"CHAOSEMERALD2",
|
||||
"CHAOSEMERALD3",
|
||||
"CHAOSEMERALD4",
|
||||
"CHAOSEMERALD5",
|
||||
"CHAOSEMERALD6",
|
||||
"CHAOSEMERALD7"
|
||||
};
|
||||
|
||||
static const char *const POWERS_LIST[] = {
|
||||
|
|
@ -11169,13 +11246,23 @@ struct {
|
|||
{"LF2_VISITNEEDED",LF2_VISITNEEDED},
|
||||
|
||||
// Emeralds
|
||||
{"EMERALD1",EMERALD1},
|
||||
{"EMERALD2",EMERALD2},
|
||||
{"EMERALD3",EMERALD3},
|
||||
{"EMERALD4",EMERALD4},
|
||||
{"EMERALD5",EMERALD5},
|
||||
{"EMERALD6",EMERALD6},
|
||||
{"EMERALD7",EMERALD7},
|
||||
{"EMERALD_CHAOS1",EMERALD_CHAOS1},
|
||||
{"EMERALD_CHAOS2",EMERALD_CHAOS2},
|
||||
{"EMERALD_CHAOS3",EMERALD_CHAOS3},
|
||||
{"EMERALD_CHAOS4",EMERALD_CHAOS4},
|
||||
{"EMERALD_CHAOS5",EMERALD_CHAOS5},
|
||||
{"EMERALD_CHAOS6",EMERALD_CHAOS6},
|
||||
{"EMERALD_CHAOS7",EMERALD_CHAOS7},
|
||||
{"EMERALD_ALLCHAOS",EMERALD_ALLCHAOS},
|
||||
{"EMERALD_SUPER1",EMERALD_SUPER1},
|
||||
{"EMERALD_SUPER2",EMERALD_SUPER2},
|
||||
{"EMERALD_SUPER3",EMERALD_SUPER3},
|
||||
{"EMERALD_SUPER4",EMERALD_SUPER4},
|
||||
{"EMERALD_SUPER5",EMERALD_SUPER5},
|
||||
{"EMERALD_SUPER6",EMERALD_SUPER6},
|
||||
{"EMERALD_SUPER7",EMERALD_SUPER7},
|
||||
{"EMERALD_ALLSUPER",EMERALD_ALLSUPER},
|
||||
{"EMERALD_ALL",EMERALD_ALL},
|
||||
|
||||
// SKINCOLOR_ doesn't include these..!
|
||||
{"MAXSKINCOLORS",MAXSKINCOLORS},
|
||||
|
|
@ -11269,6 +11356,7 @@ struct {
|
|||
{"DMG_EXPLODE",DMG_EXPLODE},
|
||||
{"DMG_SQUISH",DMG_SQUISH},
|
||||
{"DMG_STING",DMG_STING},
|
||||
{"DMG_KARMA",DMG_KARMA},
|
||||
//// Death types
|
||||
{"DMG_INSTAKILL",DMG_INSTAKILL},
|
||||
{"DMG_DEATHPIT",DMG_DEATHPIT},
|
||||
|
|
@ -11480,11 +11568,6 @@ struct {
|
|||
{"DI_SOUTHEAST",DI_SOUTHEAST},
|
||||
{"NUMDIRS",NUMDIRS},
|
||||
|
||||
// Sprite rotation axis (rotaxis_t)
|
||||
{"ROTAXIS_X",ROTAXIS_X},
|
||||
{"ROTAXIS_Y",ROTAXIS_Y},
|
||||
{"ROTAXIS_Z",ROTAXIS_Z},
|
||||
|
||||
// Buttons (ticcmd_t) // SRB2kart
|
||||
{"BT_ACCELERATE",BT_ACCELERATE},
|
||||
{"BT_DRIFT",BT_DRIFT},
|
||||
|
|
|
|||
138
src/discord.c
138
src/discord.c
|
|
@ -12,9 +12,7 @@
|
|||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
#include <curl/curl.h>
|
||||
#endif // HAVE_CURL
|
||||
#include <time.h>
|
||||
|
||||
#include "i_system.h"
|
||||
#include "d_clisrv.h"
|
||||
|
|
@ -27,6 +25,8 @@
|
|||
#include "mserv.h" // cv_advertise
|
||||
#include "z_zone.h"
|
||||
#include "byteptr.h"
|
||||
#include "stun.h"
|
||||
#include "i_tcp.h" // current_port
|
||||
|
||||
#include "discord.h"
|
||||
#include "doomdef.h"
|
||||
|
|
@ -45,16 +45,7 @@ struct discordInfo_s discordInfo;
|
|||
|
||||
discordRequest_t *discordRequestList = NULL;
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
struct SelfIPbuffer
|
||||
{
|
||||
CURL *curl;
|
||||
char *pointer;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
static char self_ip[IP_SIZE];
|
||||
#endif // HAVE_CURL
|
||||
|
||||
/*--------------------------------------------------
|
||||
static char *DRPC_XORIPString(const char *input)
|
||||
|
|
@ -335,39 +326,23 @@ void DRPC_Init(void)
|
|||
DRPC_UpdatePresence();
|
||||
}
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
/*--------------------------------------------------
|
||||
static size_t DRPC_WriteServerIP(char *s, size_t size, size_t n, void *userdata)
|
||||
static void DRPC_GotServerIP(UINT32 address)
|
||||
|
||||
Writing function for use with curl. Only intended to be used with simple text.
|
||||
Callback triggered by successful STUN response.
|
||||
|
||||
Input Arguments:-
|
||||
s - Data to write
|
||||
size - Always 1.
|
||||
n - Length of data
|
||||
userdata - Passed in from CURLOPT_WRITEDATA, intended to be SelfIPbuffer
|
||||
address - IPv4 address of this machine, in network byte order.
|
||||
|
||||
Return:-
|
||||
Number of bytes wrote in this pass.
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
static size_t DRPC_WriteServerIP(char *s, size_t size, size_t n, void *userdata)
|
||||
static void DRPC_GotServerIP(UINT32 address)
|
||||
{
|
||||
struct SelfIPbuffer *buffer;
|
||||
size_t newlength;
|
||||
|
||||
buffer = userdata;
|
||||
|
||||
newlength = buffer->length + size*n;
|
||||
buffer->pointer = realloc(buffer->pointer, newlength+1);
|
||||
|
||||
memcpy(buffer->pointer + buffer->length, s, size*n);
|
||||
|
||||
buffer->pointer[newlength] = '\0';
|
||||
buffer->length = newlength;
|
||||
|
||||
return size*n;
|
||||
const unsigned char * p = (const unsigned char *)&address;
|
||||
sprintf(self_ip, "%u.%u.%u.%u:%u", p[0], p[1], p[2], p[3], current_port);
|
||||
DRPC_UpdatePresence();
|
||||
}
|
||||
#endif // HAVE_CURL
|
||||
|
||||
/*--------------------------------------------------
|
||||
static const char *DRPC_GetServerIP(void)
|
||||
|
|
@ -387,64 +362,21 @@ static const char *DRPC_GetServerIP(void)
|
|||
{
|
||||
// We're not the server, so we could successfully get the IP!
|
||||
// No need to do anything else :)
|
||||
return address;
|
||||
sprintf(self_ip, "%s:%u", address, current_port);
|
||||
return self_ip;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
// This is a little bit goofy, but
|
||||
// there's practically no good way to get your own public IP address,
|
||||
// so we've gotta break out curl for this :V
|
||||
if (!self_ip[0])
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (curl)
|
||||
{
|
||||
// The API to get your public IP address from.
|
||||
// Picked because it's stupid simple and it's been up for a long time.
|
||||
const char *api = "http://ip4only.me/api/";
|
||||
|
||||
struct SelfIPbuffer buffer;
|
||||
CURLcode success;
|
||||
|
||||
buffer.length = 0;
|
||||
buffer.pointer = malloc(buffer.length+1);
|
||||
buffer.pointer[0] = '\0';
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, api);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DRPC_WriteServerIP);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
|
||||
|
||||
success = curl_easy_perform(curl);
|
||||
|
||||
if (success == CURLE_OK)
|
||||
{
|
||||
char *tmp;
|
||||
tmp = strtok(buffer.pointer, ",");
|
||||
|
||||
if (!strcmp(tmp, "IPv4")) // ensure correct type of IP
|
||||
{
|
||||
tmp = strtok(NULL, ",");
|
||||
strncpy(self_ip, tmp, IP_SIZE); // Yay, we have the IP :)
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer.pointer);
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
if (self_ip[0])
|
||||
{
|
||||
return self_ip;
|
||||
}
|
||||
else
|
||||
#endif // HAVE_CURL
|
||||
return NULL; // Could not get your IP for whatever reason, so we cannot do Discord invites
|
||||
{
|
||||
// There happens to be a good way to get it after all! :D
|
||||
STUN_bind(DRPC_GotServerIP);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -510,19 +442,6 @@ void DRPC_UpdatePresence(void)
|
|||
// Server info
|
||||
if (netgame)
|
||||
{
|
||||
if (cv_advertise.value)
|
||||
{
|
||||
discordPresence.state = "Public";
|
||||
}
|
||||
else
|
||||
{
|
||||
discordPresence.state = "Private";
|
||||
}
|
||||
|
||||
discordPresence.partyId = server_context; // Thanks, whoever gave us Mumble support, for implementing the EXACT thing Discord wanted for this field!
|
||||
discordPresence.partySize = D_NumPlayers(); // Players in server
|
||||
discordPresence.partyMax = discordInfo.maxPlayers; // Max players
|
||||
|
||||
if (DRPC_InvitesAreAllowed() == true)
|
||||
{
|
||||
const char *join;
|
||||
|
|
@ -536,7 +455,24 @@ void DRPC_UpdatePresence(void)
|
|||
|
||||
joinSecretSet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cv_advertise.value)
|
||||
{
|
||||
discordPresence.state = "Public";
|
||||
}
|
||||
else
|
||||
{
|
||||
discordPresence.state = "Private";
|
||||
}
|
||||
|
||||
discordPresence.partyId = server_context; // Thanks, whoever gave us Mumble support, for implementing the EXACT thing Discord wanted for this field!
|
||||
discordPresence.partySize = D_NumPlayers(); // Players in server
|
||||
discordPresence.partyMax = discordInfo.maxPlayers; // Max players
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -386,6 +386,14 @@ typedef enum
|
|||
SKINCOLOR_SUPERTAN4,
|
||||
SKINCOLOR_SUPERTAN5,
|
||||
|
||||
SKINCOLOR_CHAOSEMERALD1,
|
||||
SKINCOLOR_CHAOSEMERALD2,
|
||||
SKINCOLOR_CHAOSEMERALD3,
|
||||
SKINCOLOR_CHAOSEMERALD4,
|
||||
SKINCOLOR_CHAOSEMERALD5,
|
||||
SKINCOLOR_CHAOSEMERALD6,
|
||||
SKINCOLOR_CHAOSEMERALD7,
|
||||
|
||||
SKINCOLOR_FIRSTFREESLOT,
|
||||
SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1,
|
||||
|
||||
|
|
@ -661,10 +669,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
/// Render flats on walls
|
||||
#define WALLFLATS
|
||||
|
||||
/// - SRB2Kart options -
|
||||
/// Camera always has noclip.
|
||||
#define NOCLIPCAM
|
||||
|
||||
/// Divide volume of music and sounds by this much (loudest sounds on earth)
|
||||
#define VOLUME_DIVIDER 4
|
||||
#define USER_VOLUME_SCALE 2
|
||||
|
|
@ -682,4 +686,11 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
#undef UPDATE_ALERT
|
||||
#endif
|
||||
|
||||
/// - SRB2Kart options -
|
||||
/// Camera always has noclip.
|
||||
#define NOCLIPCAM
|
||||
|
||||
/// Other karma comeback modes
|
||||
//#define OTHERKARMAMODES
|
||||
|
||||
#endif // __DOOMDEF__
|
||||
|
|
|
|||
|
|
@ -456,30 +456,31 @@ enum GameTypeRules
|
|||
{
|
||||
// Race rules
|
||||
GTR_CIRCUIT = 1, // Enables the finish line, laps, and the waypoint system.
|
||||
GTR_RINGS = 1<<1, // Rings will be spawned in this mode. (Don't get too cheeky, ring sting is still enabled :])
|
||||
GTR_BOTS = 1<<2, // Allows bots in this gametype. Combine with BotTiccmd hooks to make bots support your gametype.
|
||||
|
||||
// Battle gametype rules
|
||||
GTR_BUMPERS = 1<<3, // Enables the bumper health system
|
||||
GTR_WANTED = 1<<4, // Enables the wanted anti-camping system
|
||||
GTR_KARMA = 1<<5, // Enables the Karma system if you're out of bumpers
|
||||
GTR_ITEMARROWS = 1<<6, // Show item box arrows above players
|
||||
GTR_CAPSULES = 1<<7, // Enables the wanted anti-camping system
|
||||
GTR_BATTLESTARTS = 1<<8, // Use Battle Mode start positions.
|
||||
GTR_SPHERES = 1<<4, // Replaces rings with blue spheres
|
||||
GTR_PAPERITEMS = 1<<5, // Replaces item boxes with paper item spawners
|
||||
GTR_WANTED = 1<<6, // Enables the wanted anti-camping system
|
||||
GTR_KARMA = 1<<7, // Enables the Karma system if you're out of bumpers
|
||||
GTR_ITEMARROWS = 1<<8, // Show item box arrows above players
|
||||
GTR_CAPSULES = 1<<9, // Enables the wanted anti-camping system
|
||||
GTR_BATTLESTARTS = 1<<10, // Use Battle Mode start positions.
|
||||
|
||||
GTR_POINTLIMIT = 1<<9, // Reaching point limit ends the round
|
||||
GTR_TIMELIMIT = 1<<10, // Reaching time limit ends the round
|
||||
GTR_OVERTIME = 1<<11, // Allow overtime behavior
|
||||
GTR_POINTLIMIT = 1<<11, // Reaching point limit ends the round
|
||||
GTR_TIMELIMIT = 1<<12, // Reaching time limit ends the round
|
||||
GTR_OVERTIME = 1<<13, // Allow overtime behavior
|
||||
|
||||
// Custom gametype rules
|
||||
GTR_TEAMS = 1<<12, // Teams are forced on
|
||||
GTR_NOTEAMS = 1<<13, // Teams are forced off
|
||||
GTR_TEAMSTARTS = 1<<14, // Use team-based start positions
|
||||
GTR_TEAMS = 1<<14, // Teams are forced on
|
||||
GTR_NOTEAMS = 1<<15, // Teams are forced off
|
||||
GTR_TEAMSTARTS = 1<<16, // Use team-based start positions
|
||||
|
||||
// Grand Prix rules
|
||||
GTR_CAMPAIGN = 1<<15, // Handles cup-based progression
|
||||
GTR_LIVES = 1<<16, // Lives system, players are forced to spectate during Game Over.
|
||||
GTR_SPECIALBOTS = 1<<17, // Bot difficulty gets stronger between rounds, and the rival system is enabled.
|
||||
GTR_CAMPAIGN = 1<<17, // Handles cup-based progression
|
||||
GTR_LIVES = 1<<18, // Lives system, players are forced to spectate during Game Over.
|
||||
GTR_SPECIALBOTS = 1<<19, // Bot difficulty gets stronger between rounds, and the rival system is enabled.
|
||||
|
||||
// free: to and including 1<<31
|
||||
};
|
||||
|
|
@ -521,15 +522,34 @@ extern UINT32 matchesplayed;
|
|||
extern UINT8 stagefailed;
|
||||
|
||||
// Emeralds stored as bits to throw savegame hackers off.
|
||||
typedef enum
|
||||
{
|
||||
EMERALD_CHAOS1 = 1,
|
||||
EMERALD_CHAOS2 = 1<<1,
|
||||
EMERALD_CHAOS3 = 1<<2,
|
||||
EMERALD_CHAOS4 = 1<<3,
|
||||
EMERALD_CHAOS5 = 1<<4,
|
||||
EMERALD_CHAOS6 = 1<<5,
|
||||
EMERALD_CHAOS7 = 1<<6,
|
||||
EMERALD_ALLCHAOS = EMERALD_CHAOS1|EMERALD_CHAOS2|EMERALD_CHAOS3|EMERALD_CHAOS4|EMERALD_CHAOS5|EMERALD_CHAOS6|EMERALD_CHAOS7,
|
||||
|
||||
EMERALD_SUPER1 = 1<<7,
|
||||
EMERALD_SUPER2 = 1<<8,
|
||||
EMERALD_SUPER3 = 1<<9,
|
||||
EMERALD_SUPER4 = 1<<10,
|
||||
EMERALD_SUPER5 = 1<<11,
|
||||
EMERALD_SUPER6 = 1<<12,
|
||||
EMERALD_SUPER7 = 1<<13,
|
||||
EMERALD_ALLSUPER = EMERALD_SUPER1|EMERALD_SUPER2|EMERALD_SUPER3|EMERALD_SUPER4|EMERALD_SUPER5|EMERALD_SUPER6|EMERALD_SUPER7,
|
||||
|
||||
EMERALD_ALL = EMERALD_ALLCHAOS|EMERALD_ALLSUPER
|
||||
} emeraldflags_t;
|
||||
|
||||
extern UINT16 emeralds;
|
||||
#define EMERALD1 1
|
||||
#define EMERALD2 2
|
||||
#define EMERALD3 4
|
||||
#define EMERALD4 8
|
||||
#define EMERALD5 16
|
||||
#define EMERALD6 32
|
||||
#define EMERALD7 64
|
||||
#define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7))
|
||||
|
||||
#define ALLCHAOSEMERALDS(v) ((v & EMERALD_ALLCHAOS) == EMERALD_ALLCHAOS)
|
||||
#define ALLSUPEREMERALDS(v) ((v & EMERALD_ALLSUPER) == EMERALD_ALLSUPER)
|
||||
#define ALLEMERALDS(v) ((v & EMERALD_ALL) == EMERALD_ALL)
|
||||
|
||||
#define NUM_LUABANKS 16 // please only make this number go up between versions, never down. you'll break saves otherwise. also, must fit in UINT8
|
||||
extern INT32 luabanks[NUM_LUABANKS];
|
||||
|
|
|
|||
|
|
@ -889,7 +889,7 @@ void F_StartGameEvaluation(void)
|
|||
// Just in case they're open ... somehow
|
||||
M_ClearMenus(true);
|
||||
|
||||
goodending = (ALL7EMERALDS(emeralds));
|
||||
goodending = (ALLCHAOSEMERALDS(emeralds));
|
||||
|
||||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
|
|
@ -1154,7 +1154,7 @@ static void F_CacheEnding(void)
|
|||
endescp[4] = W_CachePatchName("ENDESCP4", PU_PATCH);
|
||||
|
||||
// so we only need to check once
|
||||
if ((goodending = ALL7EMERALDS(emeralds)))
|
||||
if ((goodending = ALLCHAOSEMERALDS(emeralds)))
|
||||
{
|
||||
endfwrk[0] = W_CachePatchName("ENDFWRK3", PU_PATCH);
|
||||
endfwrk[1] = W_CachePatchName("ENDFWRK4", PU_PATCH);
|
||||
|
|
|
|||
150
src/g_demo.c
150
src/g_demo.c
|
|
@ -104,7 +104,7 @@ demoghost *ghosts = NULL;
|
|||
// DEMO RECORDING
|
||||
//
|
||||
|
||||
#define DEMOVERSION 0x0004
|
||||
#define DEMOVERSION 0x0007
|
||||
#define DEMOHEADER "\xF0" "KartReplay" "\x0F"
|
||||
|
||||
#define DF_GHOST 0x01 // This demo contains ghost data too!
|
||||
|
|
@ -112,7 +112,7 @@ demoghost *ghosts = NULL;
|
|||
#define DF_BREAKTHECAPSULES 0x04 // This demo is from Break the Capsules and contains its final completion time!
|
||||
#define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ???
|
||||
|
||||
#define DF_LUAVARS 0x20 // this demo contains extra lua vars; this is mostly used for backwards compability
|
||||
#define DF_LUAVARS 0x20 // this demo contains extra lua vars
|
||||
|
||||
#define DF_ATTACKSHIFT 1
|
||||
#define DF_ENCORE 0x40
|
||||
|
|
@ -419,7 +419,10 @@ void G_WriteDemoExtraData(void)
|
|||
{
|
||||
// write follower
|
||||
memset(name, 0, 16);
|
||||
strncpy(name, followers[players[i].followerskin].skinname, 16);
|
||||
if (players[i].followerskin == -1)
|
||||
strncpy(name, "None", 16);
|
||||
else
|
||||
strncpy(name, followers[players[i].followerskin].skinname, 16);
|
||||
M_Memcpy(demo_p, name, 16);
|
||||
demo_p += 16;
|
||||
|
||||
|
|
@ -619,13 +622,21 @@ void G_WriteAllGhostTics(void)
|
|||
|
||||
counter++;
|
||||
|
||||
if (counter % cv_netdemosyncquality.value != 0) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size.
|
||||
if (multiplayer && ((counter % cv_netdemosyncquality.value) != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size.
|
||||
continue;
|
||||
|
||||
WRITEUINT8(demo_p, i);
|
||||
G_WriteGhostTic(players[i].mo, i);
|
||||
}
|
||||
WRITEUINT8(demo_p, 0xFF);
|
||||
|
||||
// attention here for the ticcmd size!
|
||||
// latest demos with mouse aiming byte in ticcmd
|
||||
if (demo_p >= demoend - (13 + 9 + 9))
|
||||
{
|
||||
G_CheckDemoStatus(); // no more space
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
||||
|
|
@ -722,26 +733,22 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
|||
ghostext[playernum].flags |= EZT_SPRITE;
|
||||
}
|
||||
|
||||
if (ghost->player && (
|
||||
ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] ||
|
||||
ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] ||
|
||||
ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper]
|
||||
))
|
||||
{
|
||||
ghostext[playernum].flags |= EZT_KART;
|
||||
ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype];
|
||||
ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount];
|
||||
ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper];
|
||||
}
|
||||
|
||||
if (ghostext[playernum].flags)
|
||||
{
|
||||
ziptic |= GZT_EXTRA;
|
||||
|
||||
if (ghost->player)
|
||||
{
|
||||
if (
|
||||
ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] ||
|
||||
ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] ||
|
||||
ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper]
|
||||
)
|
||||
{
|
||||
ghostext[playernum].flags |= EZT_KART;
|
||||
ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype];
|
||||
ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount];
|
||||
ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (ghostext[playernum].color == ghostext[playernum].lastcolor)
|
||||
ghostext[playernum].flags &= ~EZT_COLOR;
|
||||
if (ghostext[playernum].scale == ghostext[playernum].lastscale)
|
||||
|
|
@ -836,14 +843,6 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
|||
oldghost[playernum].flags2 &= ~MF2_AMBUSH;
|
||||
|
||||
*ziptic_p = ziptic;
|
||||
|
||||
// attention here for the ticcmd size!
|
||||
// latest demos with mouse aiming byte in ticcmd
|
||||
if (demo_p >= demoend - (13 + 9 + 9))
|
||||
{
|
||||
G_CheckDemoStatus(); // no more space
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void G_ConsAllGhostTics(void)
|
||||
|
|
@ -1067,16 +1066,18 @@ void G_GhostTicker(void)
|
|||
if (ziptic & DXD_FOLLOWER)
|
||||
g->p += 32; // ok (32 because there's both the skin and the colour)
|
||||
if (ziptic & DXD_PLAYSTATE && READUINT8(g->p) != DXD_PST_PLAYING)
|
||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
||||
I_Error("Ghost is not a record attack ghost PLAYSTATE"); //@TODO lmao don't blow up like this
|
||||
}
|
||||
else if (ziptic == DW_RNG)
|
||||
g->p += 4; // RNG seed
|
||||
else
|
||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
||||
I_Error("Ghost is not a record attack ghost DXD"); //@TODO lmao don't blow up like this
|
||||
|
||||
ziptic = READUINT8(g->p);
|
||||
}
|
||||
|
||||
ziptic = READUINT8(g->p);
|
||||
|
||||
if (ziptic & ZT_FWD)
|
||||
g->p++;
|
||||
if (ziptic & ZT_TURNING)
|
||||
|
|
@ -1086,9 +1087,9 @@ void G_GhostTicker(void)
|
|||
if (ziptic & ZT_AIMING)
|
||||
g->p += 2;
|
||||
if (ziptic & ZT_LATENCY)
|
||||
g->p += 1;
|
||||
g->p++;
|
||||
if (ziptic & ZT_FLAGS)
|
||||
g->p += 1;
|
||||
g->p++;
|
||||
|
||||
// Grab ghost data.
|
||||
ziptic = READUINT8(g->p);
|
||||
|
|
@ -1096,7 +1097,7 @@ void G_GhostTicker(void)
|
|||
if (ziptic == 0xFF)
|
||||
goto skippedghosttic; // Didn't write ghost info this frame
|
||||
else if (ziptic != 0)
|
||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
||||
I_Error("Ghost is not a record attack ghost ZIPTIC"); //@TODO lmao don't blow up like this
|
||||
ziptic = READUINT8(g->p);
|
||||
|
||||
if (ziptic & GZT_XYZ)
|
||||
|
|
@ -1109,17 +1110,17 @@ void G_GhostTicker(void)
|
|||
{
|
||||
if (ziptic & GZT_MOMXY)
|
||||
{
|
||||
g->oldmo.momx = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
|
||||
g->oldmo.momy = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
|
||||
g->oldmo.momx = READFIXED(g->p);
|
||||
g->oldmo.momy = READFIXED(g->p);
|
||||
}
|
||||
if (ziptic & GZT_MOMZ)
|
||||
g->oldmo.momz = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
|
||||
g->oldmo.momz = READFIXED(g->p);
|
||||
g->oldmo.x += g->oldmo.momx;
|
||||
g->oldmo.y += g->oldmo.momy;
|
||||
g->oldmo.z += g->oldmo.momz;
|
||||
}
|
||||
if (ziptic & GZT_ANGLE)
|
||||
g->mo->angle = READUINT8(g->p)<<24;
|
||||
g->oldmo.angle = READUINT8(g->p)<<24;
|
||||
if (ziptic & GZT_FRAME)
|
||||
g->oldmo.frame = READUINT8(g->p);
|
||||
if (ziptic & GZT_SPR2)
|
||||
|
|
@ -1205,30 +1206,6 @@ void G_GhostTicker(void)
|
|||
g->p += 12; // kartitem, kartamount, kartbumpers
|
||||
}
|
||||
|
||||
if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here.
|
||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
||||
|
||||
skippedghosttic:
|
||||
// Tick ghost colors (Super and Mario Invincibility flashing)
|
||||
switch(g->color)
|
||||
{
|
||||
case GHC_SUPER: // Super (P_DoSuperStuff)
|
||||
if (g->mo->skin)
|
||||
{
|
||||
skin_t *skin = (skin_t *)g->mo->skin;
|
||||
g->mo->color = skin->supercolor;
|
||||
}
|
||||
else
|
||||
g->mo->color = SKINCOLOR_SUPERGOLD1;
|
||||
g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
|
||||
break;
|
||||
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
|
||||
g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#define follow g->mo->tracer
|
||||
if (ziptic & GZT_FOLLOW)
|
||||
{ // Even more...
|
||||
|
|
@ -1294,6 +1271,31 @@ skippedghosttic:
|
|||
P_RemoveMobj(follow);
|
||||
P_SetTarget(&follow, NULL);
|
||||
}
|
||||
|
||||
skippedghosttic:
|
||||
// Tick ghost colors (Super and Mario Invincibility flashing)
|
||||
switch(g->color)
|
||||
{
|
||||
case GHC_SUPER: // Super (P_DoSuperStuff)
|
||||
if (g->mo->skin)
|
||||
{
|
||||
skin_t *skin = (skin_t *)g->mo->skin;
|
||||
g->mo->color = skin->supercolor;
|
||||
}
|
||||
else
|
||||
g->mo->color = SKINCOLOR_SUPERGOLD1;
|
||||
g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
|
||||
break;
|
||||
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
|
||||
g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here.
|
||||
I_Error("Ghost is not a record attack ghost GHOSTEND"); //@TODO lmao don't blow up like this
|
||||
|
||||
// Demo ends after ghost data.
|
||||
if (*g->p == DEMOMARKER)
|
||||
{
|
||||
|
|
@ -1314,6 +1316,7 @@ skippedghosttic:
|
|||
Z_Free(g);
|
||||
continue;
|
||||
}
|
||||
|
||||
p = g;
|
||||
#undef follow
|
||||
}
|
||||
|
|
@ -1436,8 +1439,11 @@ void G_PreviewRewind(tic_t previewtime)
|
|||
players[i].drawangle = info->playerinfo[i].player.drawangle + FixedMul((INT32) (next_info->playerinfo[i].player.drawangle - info->playerinfo[i].player.drawangle), tweenvalue);
|
||||
|
||||
players[i].mo->sprite = info->playerinfo[i].mobj.sprite;
|
||||
players[i].mo->sprite2 = info->playerinfo[i].mobj.sprite2;
|
||||
players[i].mo->frame = info->playerinfo[i].mobj.frame;
|
||||
|
||||
players[i].mo->hitlag = info->playerinfo[i].mobj.hitlag;
|
||||
|
||||
players[i].realtime = info->playerinfo[i].player.realtime;
|
||||
for (j = 0; j < NUMKARTSTUFF; j++)
|
||||
players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j];
|
||||
|
|
@ -1462,7 +1468,7 @@ void G_ConfirmRewind(tic_t rewindtime)
|
|||
|
||||
if (rewindtime <= starttime)
|
||||
{
|
||||
demo.rewinding = false;
|
||||
demo.rewinding = true; // this doesn't APPEAR to cause any misery, and it allows us to prevent running all the wipes again
|
||||
G_DoPlayDemo(NULL); // Restart the current demo
|
||||
}
|
||||
else
|
||||
|
|
@ -1899,7 +1905,8 @@ void G_BeginRecording(void)
|
|||
if (encoremode)
|
||||
demoflags |= DF_ENCORE;
|
||||
|
||||
demoflags |= DF_LUAVARS;
|
||||
if (multiplayer)
|
||||
demoflags |= DF_LUAVARS;
|
||||
|
||||
// Setup header.
|
||||
M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12;
|
||||
|
|
@ -2033,9 +2040,8 @@ void G_BeginRecording(void)
|
|||
WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing
|
||||
|
||||
// player lua vars, always saved even if empty
|
||||
LUA_Archive(&demo_p);
|
||||
|
||||
WRITEUINT32(demo_p,P_GetInitSeed());
|
||||
if (demoflags & DF_LUAVARS)
|
||||
LUA_Archive(&demo_p);
|
||||
|
||||
memset(&oldcmd,0,sizeof(oldcmd));
|
||||
memset(&oldghost,0,sizeof(oldghost));
|
||||
|
|
@ -2712,7 +2718,6 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
demo.version = READUINT16(demo_p);
|
||||
switch(demo.version)
|
||||
{
|
||||
case 0x000d:
|
||||
case DEMOVERSION: // latest always supported
|
||||
break;
|
||||
// too old, cannot support.
|
||||
|
|
@ -3101,7 +3106,6 @@ void G_AddGhost(char *defdemoname)
|
|||
ghostversion = READUINT16(p);
|
||||
switch(ghostversion)
|
||||
{
|
||||
case 0x000d:
|
||||
case DEMOVERSION: // latest always supported
|
||||
break;
|
||||
// too old, cannot support.
|
||||
|
|
@ -3145,6 +3149,14 @@ void G_AddGhost(char *defdemoname)
|
|||
return;
|
||||
}
|
||||
|
||||
if (flags & DF_LUAVARS) // can't be arsed to add support for grinding away ported lua material
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Replay data contains luavars, cannot continue.\n"), pdemoname);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
p++; // gametype
|
||||
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
|
||||
|
||||
|
|
@ -3211,6 +3223,8 @@ void G_AddGhost(char *defdemoname)
|
|||
kartspeed = READUINT8(p);
|
||||
kartweight = READUINT8(p);
|
||||
|
||||
p += 4; // followitem (maybe change later)
|
||||
|
||||
if (READUINT8(p) != 0xFF)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname);
|
||||
|
|
|
|||
28
src/g_game.c
28
src/g_game.c
|
|
@ -1252,7 +1252,7 @@ void G_StartTitleCard(void)
|
|||
{
|
||||
// The title card has been disabled for this map.
|
||||
// Oh well.
|
||||
if (!G_IsTitleCardAvailable())
|
||||
if (!G_IsTitleCardAvailable() || demo.rewinding)
|
||||
{
|
||||
WipeStageTitle = false;
|
||||
return;
|
||||
|
|
@ -1575,7 +1575,7 @@ boolean G_CouldView(INT32 playernum)
|
|||
// I don't know if we want this actually, but I'll humor the suggestion anyway
|
||||
if ((gametyperules & GTR_BUMPERS) && !demo.playback)
|
||||
{
|
||||
if (player->kartstuff[k_bumper] <= 0)
|
||||
if (player->bumpers <= 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2056,6 +2056,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
UINT8 botdifficulty;
|
||||
|
||||
INT16 rings;
|
||||
INT16 spheres;
|
||||
angle_t playerangleturn;
|
||||
|
||||
UINT8 botdiffincrease;
|
||||
|
|
@ -2071,9 +2072,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
INT32 roulettetype;
|
||||
INT32 growshrinktimer;
|
||||
INT32 bumper;
|
||||
INT32 comebackpoints;
|
||||
INT32 wanted;
|
||||
boolean songcredit = false;
|
||||
boolean eliminated;
|
||||
|
||||
score = players[player].score;
|
||||
marescore = players[player].marescore;
|
||||
|
|
@ -2139,8 +2140,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
itemamount = 0;
|
||||
growshrinktimer = 0;
|
||||
bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0);
|
||||
rings = ((gametyperules & GTR_RINGS) ? 5 : 0);
|
||||
comebackpoints = 0;
|
||||
rings = ((gametyperules & GTR_SPHERES) ? 0 : 5);
|
||||
spheres = 0;
|
||||
eliminated = false;
|
||||
wanted = 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -2165,9 +2167,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
else
|
||||
growshrinktimer = 0;
|
||||
|
||||
bumper = players[player].kartstuff[k_bumper];
|
||||
bumper = players[player].bumpers;
|
||||
rings = players[player].rings;
|
||||
comebackpoints = players[player].kartstuff[k_comebackpoints];
|
||||
spheres = players[player].spheres;
|
||||
eliminated = players[player].eliminated;
|
||||
wanted = players[player].kartstuff[k_wanted];
|
||||
}
|
||||
|
||||
|
|
@ -2215,6 +2218,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->bot = bot;
|
||||
p->botvars.difficulty = botdifficulty;
|
||||
p->rings = rings;
|
||||
p->spheres = spheres;
|
||||
p->botvars.diffincrease = botdiffincrease;
|
||||
p->botvars.rival = botrival;
|
||||
p->xtralife = xtralife;
|
||||
|
|
@ -2225,9 +2229,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->kartstuff[k_itemtype] = itemtype;
|
||||
p->kartstuff[k_itemamount] = itemamount;
|
||||
p->kartstuff[k_growshrinktimer] = growshrinktimer;
|
||||
p->kartstuff[k_bumper] = bumper;
|
||||
p->kartstuff[k_comebackpoints] = comebackpoints;
|
||||
p->kartstuff[k_comebacktimer] = comebacktime;
|
||||
p->bumpers = bumper;
|
||||
p->karmadelay = comebacktime;
|
||||
p->eliminated = eliminated;
|
||||
p->kartstuff[k_wanted] = wanted;
|
||||
p->kartstuff[k_eggmanblame] = -1;
|
||||
p->kartstuff[k_lastdraft] = -1;
|
||||
|
|
@ -2787,9 +2791,9 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] =
|
|||
UINT32 gametypedefaultrules[NUMGAMETYPES] =
|
||||
{
|
||||
// Race
|
||||
GTR_CIRCUIT|GTR_RINGS|GTR_BOTS,
|
||||
GTR_CIRCUIT|GTR_BOTS,
|
||||
// Battle
|
||||
GTR_BUMPERS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME
|
||||
GTR_SPHERES|GTR_BUMPERS|GTR_PAPERITEMS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -101,21 +101,13 @@ typedef struct
|
|||
//Hurdler: Transform (coords + angles)
|
||||
//BP: transform order : scale(rotation_x(rotation_y(translation(v))))
|
||||
|
||||
// Kart features
|
||||
//#define USE_FTRANSFORM_ANGLEZ
|
||||
//#define USE_FTRANSFORM_MIRROR
|
||||
|
||||
// Vanilla features
|
||||
#define USE_MODEL_NEXTFRAME
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FLOAT x,y,z; // position
|
||||
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||
FLOAT anglex,angley,anglez; // aimingangle / viewangle
|
||||
#else
|
||||
FLOAT anglex,angley; // aimingangle / viewangle
|
||||
#endif
|
||||
FLOAT scalex,scaley,scalez;
|
||||
FLOAT fovxangle, fovyangle;
|
||||
UINT8 splitscreen;
|
||||
|
|
@ -123,13 +115,10 @@ typedef struct
|
|||
boolean shearing; // 14042019
|
||||
angle_t viewaiming; // 17052019
|
||||
boolean roll;
|
||||
SINT8 rollflip;
|
||||
FLOAT rollangle; // done to not override USE_FTRANSFORM_ANGLEZ
|
||||
UINT8 rotaxis;
|
||||
FLOAT centerx, centery;
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
FLOAT rollx, rollz;
|
||||
boolean mirror; // SRB2Kart: Encore Mode
|
||||
#endif
|
||||
} FTransform;
|
||||
|
||||
// Transformed vector, as passed to HWR API
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void);
|
|||
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
|
||||
|
||||
//Hurdler: added for new development
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface, FBITFIELD blendmode);
|
||||
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
|
||||
EXPORT void HWRAPI(SetTransform) (FTransform *stransform);
|
||||
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
||||
|
|
|
|||
|
|
@ -3617,9 +3617,9 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
|
|||
|
||||
static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
||||
{
|
||||
const fixed_t thingxpos = thing->x + thing->sprxoff;
|
||||
const fixed_t thingypos = thing->y + thing->spryoff;
|
||||
const fixed_t thingzpos = thing->z + thing->sprzoff;
|
||||
fixed_t thingxpos = thing->x + thing->sprxoff;
|
||||
fixed_t thingypos = thing->y + thing->spryoff;
|
||||
fixed_t thingzpos = thing->z + thing->sprzoff;
|
||||
|
||||
GLPatch_t *gpatch;
|
||||
FOutVector shadowVerts[4];
|
||||
|
|
@ -3637,6 +3637,21 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
fixed_t slopez;
|
||||
pslope_t *groundslope;
|
||||
|
||||
// hitlag vibrating
|
||||
if (thing->hitlag > 0)
|
||||
{
|
||||
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
mul = -mul;
|
||||
}
|
||||
|
||||
thingxpos += FixedMul(thing->momx, mul);
|
||||
thingypos += FixedMul(thing->momy, mul);
|
||||
thingzpos += FixedMul(thing->momz, mul);
|
||||
}
|
||||
|
||||
groundz = R_GetShadowZ(thing, &groundslope);
|
||||
|
||||
floordiff = abs((flip < 0 ? thing->height : 0) + thingzpos - groundz);
|
||||
|
|
@ -4263,20 +4278,10 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
|||
UINT8 brightmode = 0;
|
||||
extracolormap_t *colormap = sector->extra_colormap;
|
||||
|
||||
if (spr->mobj->drawflags & MFD_BRIGHTMASK)
|
||||
{
|
||||
if (spr->mobj->drawflags & MFD_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->drawflags & MFD_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spr->mobj->frame & FF_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
}
|
||||
if (spr->mobj->frame & FF_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
|
||||
if (sector->numlights)
|
||||
{
|
||||
|
|
@ -4305,9 +4310,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
|||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
}
|
||||
|
||||
if (spr->mobj->drawflags & MFD_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf);
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
if (spr->mobj->frame & FF_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
else
|
||||
{
|
||||
|
|
@ -4867,9 +4870,9 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
// BP why not use xtoviexangle/viewangletox like in bsp ?....
|
||||
static void HWR_ProjectSprite(mobj_t *thing)
|
||||
{
|
||||
const fixed_t thingxpos = thing->x + thing->sprxoff;
|
||||
const fixed_t thingypos = thing->y + thing->spryoff;
|
||||
const fixed_t thingzpos = thing->z + thing->sprzoff;
|
||||
fixed_t thingxpos = thing->x + thing->sprxoff;
|
||||
fixed_t thingypos = thing->y + thing->spryoff;
|
||||
fixed_t thingzpos = thing->z + thing->sprzoff;
|
||||
|
||||
gl_vissprite_t *vis;
|
||||
float tr_x, tr_y;
|
||||
|
|
@ -4902,11 +4905,27 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
#ifdef ROTSPRITE
|
||||
patch_t *rotsprite = NULL;
|
||||
INT32 rollangle = 0;
|
||||
angle_t spriterotangle = 0;
|
||||
#endif
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
// hitlag vibrating
|
||||
if (thing->hitlag > 0)
|
||||
{
|
||||
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
mul = -mul;
|
||||
}
|
||||
|
||||
thingxpos += FixedMul(thing->momx, mul);
|
||||
thingypos += FixedMul(thing->momy, mul);
|
||||
thingzpos += FixedMul(thing->momz, mul);
|
||||
}
|
||||
|
||||
dispoffset = thing->info->dispoffset;
|
||||
|
||||
this_scale = FIXED_TO_FLOAT(thing->scale);
|
||||
|
|
@ -5025,9 +5044,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
spr_topoffset = spritecachedinfo[lumpoff].topoffset;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (thing->rollangle)
|
||||
spriterotangle = R_SpriteRotationAngle(thing);
|
||||
|
||||
if (spriterotangle != 0)
|
||||
{
|
||||
rollangle = R_GetRollAngle(thing->rollangle);
|
||||
rollangle = R_GetRollAngle(spriterotangle);
|
||||
if (!(sprframe->rotsprite.cached & (1<<rot)))
|
||||
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip);
|
||||
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
|
||||
|
|
@ -5508,6 +5529,8 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
fixed_t rol = AngleFixed(player->viewrollangle);
|
||||
dometransform.rollangle = FIXED_TO_FLOAT(rol);
|
||||
dometransform.roll = true;
|
||||
dometransform.rollx = 1.0f;
|
||||
dometransform.rollz = 0.0f;
|
||||
}
|
||||
dometransform.splitscreen = r_splitscreen;
|
||||
|
||||
|
|
@ -5786,6 +5809,8 @@ void HWR_RenderSkyboxView(player_t *player)
|
|||
fixed_t rol = AngleFixed(player->viewrollangle);
|
||||
atransform.rollangle = FIXED_TO_FLOAT(rol);
|
||||
atransform.roll = true;
|
||||
atransform.rollx = 1.0f;
|
||||
atransform.rollz = 0.0f;
|
||||
}
|
||||
atransform.splitscreen = r_splitscreen;
|
||||
|
||||
|
|
@ -5987,6 +6012,8 @@ void HWR_RenderPlayerView(void)
|
|||
fixed_t rol = AngleFixed(player->viewrollangle);
|
||||
atransform.rollangle = FIXED_TO_FLOAT(rol);
|
||||
atransform.roll = true;
|
||||
atransform.rollx = 1.0f;
|
||||
atransform.rollz = 0.0f;
|
||||
}
|
||||
atransform.splitscreen = r_splitscreen;
|
||||
|
||||
|
|
|
|||
|
|
@ -1340,9 +1340,9 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
|
||||
// Look at HWR_ProjectSprite for more
|
||||
{
|
||||
const fixed_t thingxpos = spr->mobj->x + spr->mobj->sprxoff;
|
||||
const fixed_t thingypos = spr->mobj->y + spr->mobj->spryoff;
|
||||
const fixed_t thingzpos = spr->mobj->z + spr->mobj->sprzoff;
|
||||
fixed_t thingxpos = spr->mobj->x + spr->mobj->sprxoff;
|
||||
fixed_t thingypos = spr->mobj->y + spr->mobj->spryoff;
|
||||
fixed_t thingzpos = spr->mobj->z + spr->mobj->sprzoff;
|
||||
|
||||
GLPatch_t *gpatch;
|
||||
INT32 durs = spr->mobj->state->tics;
|
||||
|
|
@ -1353,22 +1353,41 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !(spr->mobj->frame & FF_HORIZONTALFLIP));
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
spriteinfo_t *sprinfo;
|
||||
angle_t ang;
|
||||
INT32 mod;
|
||||
float finalscale;
|
||||
FBITFIELD blendmode = PF_Masked;
|
||||
|
||||
// hitlag vibrating
|
||||
if (spr->mobj->hitlag > 0)
|
||||
{
|
||||
fixed_t mul = spr->mobj->hitlag * (FRACUNIT / 10);
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
mul = -mul;
|
||||
}
|
||||
|
||||
thingxpos += FixedMul(spr->mobj->momx, mul);
|
||||
thingypos += FixedMul(spr->mobj->momy, mul);
|
||||
thingzpos += FixedMul(spr->mobj->momz, mul);
|
||||
}
|
||||
|
||||
// Apparently people don't like jump frames like that, so back it goes
|
||||
//if (tics > durs)
|
||||
//durs = tics;
|
||||
|
||||
if (spr->mobj->drawflags & MFD_TRANSMASK)
|
||||
HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf);
|
||||
blendmode = HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf);
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
blendmode = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
else
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
|
||||
if (blendmode == PF_Masked)
|
||||
{
|
||||
blendmode |= PF_Occlude;
|
||||
}
|
||||
|
||||
// dont forget to enabled the depth test because we can't do this like
|
||||
// before: polygons models are not sorted
|
||||
|
||||
|
|
@ -1378,12 +1397,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
{
|
||||
md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins];
|
||||
md2->skin = (skin_t*)spr->mobj->skin-skins;
|
||||
sprinfo = &((skin_t *)spr->mobj->skin)->sprinfo[spr->mobj->sprite2];
|
||||
}
|
||||
else
|
||||
{
|
||||
md2 = &md2_models[spr->mobj->sprite];
|
||||
sprinfo = &spriteinfo[spr->mobj->sprite];
|
||||
}
|
||||
|
||||
// texture loading before model init, so it knows if sprite graphics are used, which
|
||||
|
|
@ -1578,60 +1595,35 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
}
|
||||
|
||||
p.rollangle = 0.0f;
|
||||
p.rollflip = 1;
|
||||
p.rotaxis = 0;
|
||||
|
||||
if (spr->mobj->rollangle)
|
||||
{
|
||||
fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know
|
||||
fixed_t anglef = AngleFixed(spr->mobj->rollangle);
|
||||
|
||||
p.rollangle = FIXED_TO_FLOAT(anglef);
|
||||
p.roll = true;
|
||||
|
||||
// rotation pivot
|
||||
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
|
||||
p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2));
|
||||
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2);
|
||||
p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2);
|
||||
|
||||
// rotation axis
|
||||
if (sprinfo->available)
|
||||
p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis);
|
||||
|
||||
// for NiGHTS specifically but should work everywhere else
|
||||
ang = R_PointToAngle (spr->mobj->x, spr->mobj->y) - (spr->mobj->player ? spr->mobj->player->drawangle : spr->mobj->angle);
|
||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
p.rollflip = 1;
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
p.rollflip = -1;
|
||||
|
||||
if (flip)
|
||||
p.rollflip *= -1;
|
||||
// rotation axes relative to camera
|
||||
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
|
||||
p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
|
||||
}
|
||||
|
||||
p.anglex = 0.0f;
|
||||
|
||||
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||
// Slope rotation from Kart
|
||||
p.anglez = 0.0f;
|
||||
if (spr->mobj->standingslope)
|
||||
{
|
||||
fixed_t tempz = spr->mobj->standingslope->normal.z;
|
||||
fixed_t tempy = spr->mobj->standingslope->normal.y;
|
||||
fixed_t tempx = spr->mobj->standingslope->normal.x;
|
||||
fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
|
||||
p.anglez = FIXED_TO_FLOAT(tempangle);
|
||||
tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy));
|
||||
p.anglex = FIXED_TO_FLOAT(tempangle);
|
||||
}
|
||||
#endif
|
||||
p.anglez = FIXED_TO_FLOAT(AngleFixed(spr->mobj->pitch));
|
||||
p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll));
|
||||
|
||||
// SRB2CBTODO: MD2 scaling support
|
||||
finalscale *= FIXED_TO_FLOAT(spr->mobj->scale);
|
||||
|
||||
p.flip = atransform.flip;
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
p.mirror = atransform.mirror; // from Kart
|
||||
#endif
|
||||
p.mirror = atransform.mirror;
|
||||
|
||||
HWD.pfnSetShader(SHADER_MODEL); // model shader
|
||||
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf);
|
||||
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf, blendmode);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -2513,7 +2513,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model)
|
|||
|
||||
#define BUFFER_OFFSET(i) ((void*)(i))
|
||||
|
||||
static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface, FBITFIELD blendmode)
|
||||
{
|
||||
static GLRGBAFloat poly = {0,0,0,0};
|
||||
static GLRGBAFloat tint = {0,0,0,0};
|
||||
|
|
@ -2593,7 +2593,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
else
|
||||
pglColor4ubv((GLubyte*)&Surface->PolyColor.s);
|
||||
|
||||
SetBlend((poly.alpha < 1 ? PF_Translucent : (PF_Masked|PF_Occlude))|PF_Modulated);
|
||||
SetBlend(blendmode|PF_Modulated);
|
||||
|
||||
tint.red = byte2float[Surface->TintColor.s.red];
|
||||
tint.green = byte2float[Surface->TintColor.s.green];
|
||||
|
|
@ -2610,7 +2610,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
pglEnable(GL_CULL_FACE);
|
||||
pglEnable(GL_NORMALIZE);
|
||||
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
// flipped is if the object is vertically flipped
|
||||
// hflipped is if the object is horizontally flipped
|
||||
// pos->flip is if the screen is flipped vertically
|
||||
|
|
@ -2623,17 +2622,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
else
|
||||
pglCullFace(GL_BACK);
|
||||
}
|
||||
#else
|
||||
// pos->flip is if the screen is flipped too
|
||||
if (flipped ^ hflipped ^ pos->flip) // If one or three of these are active, but not two, invert the model's culling
|
||||
{
|
||||
pglCullFace(GL_FRONT);
|
||||
}
|
||||
else
|
||||
{
|
||||
pglCullFace(GL_BACK);
|
||||
}
|
||||
#endif
|
||||
|
||||
pglPushMatrix(); // should be the same as glLoadIdentity
|
||||
//Hurdler: now it seems to work
|
||||
|
|
@ -2643,22 +2631,14 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
if (hflipped)
|
||||
scalez = -scalez;
|
||||
|
||||
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart
|
||||
#endif
|
||||
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
|
||||
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f);
|
||||
pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f);
|
||||
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
|
||||
|
||||
if (pos->roll)
|
||||
{
|
||||
float roll = (1.0f * pos->rollflip);
|
||||
pglTranslatef(pos->centerx, pos->centery, 0);
|
||||
if (pos->rotaxis == 2) // Z
|
||||
pglRotatef(pos->rollangle, 0.0f, 0.0f, roll);
|
||||
else if (pos->rotaxis == 1) // Y
|
||||
pglRotatef(pos->rollangle, 0.0f, roll, 0.0f);
|
||||
else // X
|
||||
pglRotatef(pos->rollangle, roll, 0.0f, 0.0f);
|
||||
pglRotatef(pos->rollangle, pos->rollx, 0.0f, pos->rollz);
|
||||
pglTranslatef(-pos->centerx, -pos->centery, 0);
|
||||
}
|
||||
|
||||
|
|
@ -2812,9 +2792,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
// -----------------+
|
||||
// HWRAPI DrawModel : Draw a model
|
||||
// -----------------+
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface, FBITFIELD blendmode)
|
||||
{
|
||||
DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface);
|
||||
DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface, blendmode);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
|
|
@ -2831,13 +2811,9 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
|||
if (stransform)
|
||||
{
|
||||
used_fov = stransform->fovxangle;
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
// mirroring from Kart
|
||||
if (stransform->mirror)
|
||||
pglScalef(-stransform->scalex, stransform->scaley, -stransform->scalez);
|
||||
else
|
||||
#endif
|
||||
if (stransform->flip)
|
||||
else if (stransform->flip)
|
||||
pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez);
|
||||
else
|
||||
pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez);
|
||||
|
|
|
|||
17
src/i_net.h
17
src/i_net.h
|
|
@ -77,11 +77,19 @@ typedef struct
|
|||
char data[MAXPACKETLENGTH];
|
||||
} ATTRPACK doomcom_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 magic;
|
||||
INT32 addr;
|
||||
INT16 port;
|
||||
} ATTRPACK holepunch_t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
extern doomcom_t *doomcom;
|
||||
extern holepunch_t *holepunchpacket;
|
||||
|
||||
/** \brief return packet in doomcom struct
|
||||
*/
|
||||
|
|
@ -140,6 +148,15 @@ extern boolean (*I_NetOpenSocket)(void);
|
|||
extern void (*I_NetCloseSocket)(void);
|
||||
|
||||
|
||||
/** \brief send a hole punching request
|
||||
*/
|
||||
extern void (*I_NetRequestHolePunch)(void);
|
||||
|
||||
/** \brief register this machine on the hole punching server
|
||||
*/
|
||||
extern void (*I_NetRegisterHolePunch)(void);
|
||||
|
||||
|
||||
extern boolean (*I_Ban) (INT32 node);
|
||||
extern void (*I_ClearBans)(void);
|
||||
extern const char *(*I_GetNodeAddress) (INT32 node);
|
||||
|
|
|
|||
144
src/i_tcp.c
144
src/i_tcp.c
|
|
@ -152,6 +152,7 @@ static UINT8 UPNP_support = TRUE;
|
|||
#include "d_netfil.h"
|
||||
#include "i_tcp.h"
|
||||
#include "m_argv.h"
|
||||
#include "stun.h"
|
||||
|
||||
#include "doomstat.h"
|
||||
|
||||
|
|
@ -203,6 +204,7 @@ static size_t broadcastaddresses = 0;
|
|||
static boolean nodeconnected[MAXNETNODES+1];
|
||||
static mysockaddr_t banned[MAXBANS];
|
||||
static UINT8 bannedmask[MAXBANS];
|
||||
static const INT32 hole_punch_magic = MSBF_LONG (0x52eb11);
|
||||
#endif
|
||||
|
||||
static size_t numbans = 0;
|
||||
|
|
@ -559,6 +561,27 @@ void Command_Numnodes(void)
|
|||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
static boolean hole_punch(ssize_t c)
|
||||
{
|
||||
if (c == 10 && holepunchpacket->magic == hole_punch_magic)
|
||||
{
|
||||
mysockaddr_t addr;
|
||||
addr.ip4.sin_family = AF_INET;
|
||||
addr.ip4.sin_addr.s_addr = holepunchpacket->addr;
|
||||
addr.ip4.sin_port = holepunchpacket->port;
|
||||
sendto(mysockets[0], NULL, 0, 0, &addr.any, sizeof addr.ip4);
|
||||
|
||||
CONS_Debug(DBG_NETPLAY,
|
||||
"hole punching request from %s\n", SOCK_AddrToStr(&addr));
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if a packet was received from a new node, false in all other cases
|
||||
static boolean SOCK_Get(void)
|
||||
{
|
||||
|
|
@ -573,8 +596,20 @@ static boolean SOCK_Get(void)
|
|||
fromlen = (socklen_t)sizeof(fromaddress);
|
||||
c = recvfrom(mysockets[n], (char *)&doomcom->data, MAXPACKETLENGTH, 0,
|
||||
(void *)&fromaddress, &fromlen);
|
||||
if (c != ERRSOCKET)
|
||||
if (c > 0)
|
||||
{
|
||||
#ifdef USE_STUN
|
||||
if (STUN_got_response(doomcom->data, c))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (hole_punch(c))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// find remote node number
|
||||
for (j = 1; j <= MAXNETNODES; j++) //include LAN
|
||||
{
|
||||
|
|
@ -1257,17 +1292,14 @@ void I_ShutdownTcpDriver(void)
|
|||
}
|
||||
|
||||
#ifndef NONET
|
||||
static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||
static boolean SOCK_GetAddr(struct sockaddr_in *sin, const char *address, const char *port, boolean test)
|
||||
{
|
||||
SINT8 newnode = -1;
|
||||
struct my_addrinfo *ai = NULL, *runp, hints;
|
||||
int gaie;
|
||||
|
||||
if (!port || !port[0])
|
||||
if (!port || !port[0])
|
||||
port = DEFAULTPORT;
|
||||
|
||||
DEBFILE(va("Creating new node: %s@%s\n", address, port));
|
||||
|
||||
memset (&hints, 0x00, sizeof (hints));
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
|
|
@ -1275,30 +1307,91 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
|||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
gaie = I_getaddrinfo(address, port, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
newnode = getfreenode();
|
||||
}
|
||||
if (newnode == -1)
|
||||
|
||||
if (gaie != 0)
|
||||
{
|
||||
I_freeaddrinfo(ai);
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
runp = ai;
|
||||
|
||||
if (test)
|
||||
{
|
||||
while (runp != NULL)
|
||||
{
|
||||
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
|
||||
break;
|
||||
|
||||
runp = runp->ai_next;
|
||||
}
|
||||
}
|
||||
|
||||
if (runp != NULL)
|
||||
memcpy(sin, runp->ai_addr, runp->ai_addrlen);
|
||||
|
||||
I_freeaddrinfo(ai);
|
||||
|
||||
return (runp != NULL);
|
||||
}
|
||||
|
||||
static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||
{
|
||||
SINT8 newnode = getfreenode();
|
||||
|
||||
DEBFILE(va("Creating new node: %s@%s\n", address, port));
|
||||
|
||||
if (newnode != -1)
|
||||
{
|
||||
if (!SOCK_GetAddr(&clientaddress[newnode].ip4, address, port, true))
|
||||
{
|
||||
nodeconnected[newnode] = false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static void rendezvous(int size)
|
||||
{
|
||||
char *addrs = strdup(cv_rendezvousserver.string);
|
||||
|
||||
char *host = strtok(addrs, ":");
|
||||
char *port = strtok(NULL, ":");
|
||||
|
||||
mysockaddr_t rzv;
|
||||
|
||||
if (SOCK_GetAddr(&rzv.ip4, host, (port ? port : "7777"), false))
|
||||
{
|
||||
holepunchpacket->magic = hole_punch_magic;
|
||||
sendto(mysockets[0], doomcom->data, size, 0, &rzv.any, sizeof rzv.ip4);
|
||||
}
|
||||
else
|
||||
runp = ai;
|
||||
|
||||
while (runp != NULL)
|
||||
{
|
||||
// find ip of the server
|
||||
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
|
||||
{
|
||||
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
||||
break;
|
||||
}
|
||||
runp = runp->ai_next;
|
||||
CONS_Alert(CONS_ERROR, "Failed to contact rendezvous server (%s).\n",
|
||||
cv_rendezvousserver.string);
|
||||
}
|
||||
I_freeaddrinfo(ai);
|
||||
return newnode;
|
||||
|
||||
free(addrs);
|
||||
}
|
||||
|
||||
static void SOCK_RequestHolePunch(void)
|
||||
{
|
||||
mysockaddr_t * addr = &clientaddress[doomcom->remotenode];
|
||||
|
||||
holepunchpacket->addr = addr->ip4.sin_addr.s_addr;
|
||||
holepunchpacket->port = addr->ip4.sin_port;
|
||||
|
||||
CONS_Debug(DBG_NETPLAY,
|
||||
"requesting hole punch to node %s\n", SOCK_AddrToStr(addr));
|
||||
|
||||
rendezvous(10);
|
||||
}
|
||||
|
||||
static void SOCK_RegisterHolePunch(void)
|
||||
{
|
||||
rendezvous(4);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1325,6 +1418,9 @@ static boolean SOCK_OpenSocket(void)
|
|||
I_NetCanGet = SOCK_CanGet;
|
||||
#endif
|
||||
|
||||
I_NetRequestHolePunch = SOCK_RequestHolePunch;
|
||||
I_NetRegisterHolePunch = SOCK_RegisterHolePunch;
|
||||
|
||||
// build the socket but close it first
|
||||
SOCK_CloseSocket();
|
||||
return UDP_Socket();
|
||||
|
|
|
|||
593
src/info.c
593
src/info.c
|
|
@ -135,11 +135,12 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"TOKE", // Special Stage Token
|
||||
"RFLG", // Red CTF Flag
|
||||
"BFLG", // Blue CTF Flag
|
||||
//"SPHR", // Sphere
|
||||
"BSPH", // Sphere
|
||||
"NCHP", // NiGHTS chip
|
||||
"NSTR", // NiGHTS star
|
||||
"EMBM", // Emblem
|
||||
"CEMG", // Chaos Emeralds
|
||||
"EMRC", // Chaos Emeralds
|
||||
"ESPK",
|
||||
"SHRD", // Emerald Hunt
|
||||
|
||||
// Interactive Objects
|
||||
|
|
@ -557,6 +558,10 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"SINK", // Kitchen Sink
|
||||
"SITR", // Kitchen Sink Trail
|
||||
"KBLN", // Battle Mode Bumper
|
||||
"BEXC", // Battle Bumper Explosion: Crystal
|
||||
"BEXS", // Battle Bumper Explosion: Shell
|
||||
"BDEB", // Battle Bumper Explosion: Debris
|
||||
"BEXB", // Battle Bumper Explosion: Blast
|
||||
|
||||
"DEZL", // DEZ Laser respawn
|
||||
|
||||
|
|
@ -713,7 +718,9 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"DRAF",
|
||||
"GRES",
|
||||
|
||||
"OTFG",
|
||||
"OTBU",
|
||||
"OTLS",
|
||||
"OTCP",
|
||||
|
||||
"DBOS", // Drift boost flame
|
||||
|
||||
|
|
@ -730,6 +737,9 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"DBCL", // Drift boost clip
|
||||
"DBNC", // Drift boost clip's sparks
|
||||
"DBST", // Drift boost plume
|
||||
|
||||
"SDDS", // Spindash dust
|
||||
"SDWN", // Spindash wind
|
||||
};
|
||||
|
||||
char spr2names[NUMPLAYERSPRITES][5] =
|
||||
|
|
@ -1799,20 +1809,49 @@ state_t states[NUMSTATES] =
|
|||
{SPR_RING, 20, 1, {NULL}, 0, 0, S_FASTRING12}, // S_FASTRING11
|
||||
{SPR_RING, 22, 1, {NULL}, 0, 0, S_FASTRING1}, // S_FASTRING12
|
||||
|
||||
// Blue Sphere for special stages
|
||||
{SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE
|
||||
{SPR_SPHR, FF_FULLBRIGHT
|
||||
#ifdef MANIASPHERES
|
||||
|FF_ANIMATE|FF_RANDOMANIM
|
||||
#endif
|
||||
, -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS
|
||||
{SPR_SPHR, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK
|
||||
// Blue Sphere
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|2, TICRATE, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE1}, // S_BLUESPHERE
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|2, TICRATE, {A_SetRandomTics}, 1, TICRATE, S_BLUESPHERE_BOUNCE1}, // S_BLUESPHERE_SPAWN
|
||||
|
||||
{SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE2}, // S_BLUESPHERE_BOUNCE1
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE3}, // S_BLUESPHERE_BOUNCE2
|
||||
|
||||
{SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE4}, // S_BLUESPHERE_BOUNCE3
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE5}, // S_BLUESPHERE_BOUNCE4
|
||||
|
||||
{SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE6}, // S_BLUESPHERE_BOUNCE5
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE7}, // S_BLUESPHERE_BOUNCE6
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE8}, // S_BLUESPHERE_BOUNCE7
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE9}, // S_BLUESPHERE_BOUNCE8
|
||||
|
||||
{SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE10}, // S_BLUESPHERE_BOUNCE9
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE11}, // S_BLUESPHERE_BOUNCE10
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE12}, // S_BLUESPHERE_BOUNCE11
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE13}, // S_BLUESPHERE_BOUNCE12
|
||||
|
||||
{SPR_BSPH, FF_SEMIBRIGHT, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE14}, // S_BLUESPHERE_BOUNCE13
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|1, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE15}, // S_BLUESPHERE_BOUNCE14
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|2, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE16}, // S_BLUESPHERE_BOUNCE15
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|3, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE17}, // S_BLUESPHERE_BOUNCE16
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|4, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE18}, // S_BLUESPHERE_BOUNCE17
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|3, 4, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE19}, // S_BLUESPHERE_BOUNCE18
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|2, 4, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE20}, // S_BLUESPHERE_BOUNCE19
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|1, 4, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE21}, // S_BLUESPHERE_BOUNCE20
|
||||
|
||||
{SPR_BSPH, FF_SEMIBRIGHT, 6, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE22}, // S_BLUESPHERE_BOUNCE21
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|1, 6, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE23}, // S_BLUESPHERE_BOUNCE22
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|2, 6, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE24}, // S_BLUESPHERE_BOUNCE23
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|3, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE25}, // S_BLUESPHERE_BOUNCE24
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|4, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE26}, // S_BLUESPHERE_BOUNCE25
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|3, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE27}, // S_BLUESPHERE_BOUNCE26
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|2, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE28}, // S_BLUESPHERE_BOUNCE27
|
||||
{SPR_BSPH, FF_SEMIBRIGHT|1, 9, {NULL}, 0, 0, S_BLUESPHERE}, // S_BLUESPHERE_BOUNCE28
|
||||
|
||||
// Bomb Sphere
|
||||
{SPR_SPHR, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1
|
||||
{SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3}, // S_BOMBSPHERE2
|
||||
{SPR_SPHR, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4}, // S_BOMBSPHERE3
|
||||
{SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1}, // S_BOMBSPHERE4
|
||||
{SPR_BSPH, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1
|
||||
{SPR_BSPH, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3}, // S_BOMBSPHERE2
|
||||
{SPR_BSPH, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4}, // S_BOMBSPHERE3
|
||||
{SPR_BSPH, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1}, // S_BOMBSPHERE4
|
||||
|
||||
// NiGHTS Chip
|
||||
{SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 15, 2, S_NULL}, // S_NIGHTSCHIP
|
||||
|
|
@ -1865,13 +1904,17 @@ state_t states[NUMSTATES] =
|
|||
{SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26
|
||||
|
||||
// Chaos Emeralds
|
||||
{SPR_CEMG, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG1
|
||||
{SPR_CEMG, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG2
|
||||
{SPR_CEMG, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG3
|
||||
{SPR_CEMG, FF_FULLBRIGHT|3, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG4
|
||||
{SPR_CEMG, FF_FULLBRIGHT|4, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG5
|
||||
{SPR_CEMG, FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG6
|
||||
{SPR_CEMG, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG7
|
||||
{SPR_EMRC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_CHAOSEMERALD2}, // S_CHAOSEMERALD1
|
||||
{SPR_EMRC, FF_FULLBRIGHT|FF_TRANSADD, 1, {NULL}, 0, 0, S_CHAOSEMERALD1}, // S_CHAOSEMERALD2
|
||||
{SPR_EMRC, FF_FULLBRIGHT|1, -1, {NULL}, 1, 0, S_NULL}, // S_CHAOSEMERALD_UNDER
|
||||
|
||||
{SPR_ESPK, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EMERALDSPARK2}, // S_EMERALDSPARK1
|
||||
{SPR_ESPK, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_EMERALDSPARK3}, // S_EMERALDSPARK2
|
||||
{SPR_ESPK, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_EMERALDSPARK4}, // S_EMERALDSPARK3
|
||||
{SPR_ESPK, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_EMERALDSPARK5}, // S_EMERALDSPARK4
|
||||
{SPR_ESPK, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_EMERALDSPARK6}, // S_EMERALDSPARK5
|
||||
{SPR_ESPK, FF_FULLBRIGHT|5, 3, {NULL}, 0, 0, S_EMERALDSPARK7}, // S_EMERALDSPARK6
|
||||
{SPR_ESPK, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_NULL}, // S_EMERALDSPARK7
|
||||
|
||||
// Emerald hunt shards
|
||||
{SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD1
|
||||
|
|
@ -3715,14 +3758,14 @@ state_t states[NUMSTATES] =
|
|||
{SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE
|
||||
|
||||
// Orbiting Chaos Emeralds/Ideya for NiGHTS
|
||||
{SPR_CEMG, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1
|
||||
{SPR_CEMG, FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2
|
||||
{SPR_CEMG, FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3
|
||||
{SPR_CEMG, FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4
|
||||
{SPR_CEMG, FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5
|
||||
{SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6
|
||||
{SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7
|
||||
{SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8
|
||||
{SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1
|
||||
{SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2
|
||||
{SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3
|
||||
{SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4
|
||||
{SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5
|
||||
{SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6
|
||||
{SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7
|
||||
{SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8
|
||||
{SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1
|
||||
{SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2
|
||||
{SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3
|
||||
|
|
@ -4362,9 +4405,47 @@ state_t states[NUMSTATES] =
|
|||
{SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2
|
||||
{SPR_SITR, 2, 3, {NULL}, 0, 0, S_NULL}, // S_SINKTRAIL3
|
||||
|
||||
{SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BATTLEBUMPER1}, // S_BATTLEBUMPER1
|
||||
{SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_BATTLEBUMPER2}, // S_BATTLEBUMPER2
|
||||
{SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_BATTLEBUMPER3}, // S_BATTLEBUMPER3
|
||||
{SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER1
|
||||
{SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER2
|
||||
{SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER3
|
||||
|
||||
{SPR_BEXC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA2}, // S_BATTLEBUMPER_EXCRYSTALA1
|
||||
{SPR_BEXC, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA3}, // S_BATTLEBUMPER_EXCRYSTALA2
|
||||
{SPR_BEXC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA4}, // S_BATTLEBUMPER_EXCRYSTALA3
|
||||
{SPR_BEXC, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA1}, // S_BATTLEBUMPER_EXCRYSTALA4
|
||||
|
||||
{SPR_BEXC, FF_SEMIBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB2}, // S_BATTLEBUMPER_EXCRYSTALB1
|
||||
{SPR_BEXC, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB3}, // S_BATTLEBUMPER_EXCRYSTALB2
|
||||
{SPR_BEXC, FF_SEMIBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB4}, // S_BATTLEBUMPER_EXCRYSTALB3
|
||||
{SPR_BEXC, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB1}, // S_BATTLEBUMPER_EXCRYSTALB4
|
||||
|
||||
{SPR_BEXC, FF_SEMIBRIGHT|6, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC2}, // S_BATTLEBUMPER_EXCRYSTALC1
|
||||
{SPR_BEXC, FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC3}, // S_BATTLEBUMPER_EXCRYSTALC2
|
||||
{SPR_BEXC, FF_SEMIBRIGHT|6, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC4}, // S_BATTLEBUMPER_EXCRYSTALC3
|
||||
{SPR_BEXC, FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC1}, // S_BATTLEBUMPER_EXCRYSTALC4
|
||||
|
||||
{SPR_BEXS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLA2}, // S_BATTLEBUMPER_EXSHELLA1
|
||||
{SPR_BEXS, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLA1}, // S_BATTLEBUMPER_EXSHELLA2
|
||||
|
||||
{SPR_BEXS, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLB2}, // S_BATTLEBUMPER_EXSHELLB1
|
||||
{SPR_BEXS, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLB1}, // S_BATTLEBUMPER_EXSHELLB2
|
||||
|
||||
{SPR_BEXS, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC2}, // S_BATTLEBUMPER_EXSHELLC1
|
||||
{SPR_BEXS, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC1}, // S_BATTLEBUMPER_EXSHELLC2
|
||||
|
||||
{SPR_BDEB, FF_FULLBRIGHT|FF_ANIMATE, 84, {NULL}, 13, 6, S_BATTLEBUMPER_EXDEBRIS2}, // S_BATTLEBUMPER_EXDEBRIS1
|
||||
{SPR_BDEB, FF_FULLBRIGHT|13, 20, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER_EXDEBRIS2
|
||||
|
||||
{SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST2}, // S_BATTLEBUMPER_EXBLAST1
|
||||
{SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS10, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST3}, // S_BATTLEBUMPER_EXBLAST2
|
||||
{SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS20, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST4}, // S_BATTLEBUMPER_EXBLAST3
|
||||
{SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS30, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST5}, // S_BATTLEBUMPER_EXBLAST4
|
||||
{SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS40, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST6}, // S_BATTLEBUMPER_EXBLAST5
|
||||
{SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS50, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST7}, // S_BATTLEBUMPER_EXBLAST6
|
||||
{SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS60, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST8}, // S_BATTLEBUMPER_EXBLAST7
|
||||
{SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS70, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST9}, // S_BATTLEBUMPER_EXBLAST8
|
||||
{SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS80, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST10}, // S_BATTLEBUMPER_EXBLAST9
|
||||
{SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS90, 2, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER_EXBLAST10
|
||||
|
||||
{SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER
|
||||
{SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL2}, // S_DEZLASER_TRAIL1
|
||||
|
|
@ -4995,9 +5076,10 @@ state_t states[NUMSTATES] =
|
|||
|
||||
{SPR_GRES, FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 2, 4, S_NULL}, // S_TIREGREASE
|
||||
|
||||
{SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, TICRATE, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG
|
||||
{SPR_OTFG, 2|FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB
|
||||
{SPR_OTFG, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEBEAM
|
||||
{SPR_OTBU, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_BULB1
|
||||
{SPR_OTBU, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_BULB2
|
||||
{SPR_OTLS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_LASER
|
||||
{SPR_OTCP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_CENTER
|
||||
|
||||
{SPR_CAPS, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SIDE1
|
||||
{SPR_CAPS, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SIDE2
|
||||
|
|
@ -5026,6 +5108,9 @@ state_t states[NUMSTATES] =
|
|||
{SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|14, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY7
|
||||
{SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|15, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY8
|
||||
|
||||
{SPR_SDDS, FF_ANIMATE, 9, {NULL}, 9, 1, S_NULL}, // S_SPINDASHDUST
|
||||
{SPR_SDWN, FF_ANIMATE|FF_PAPERSPRITE, 18, {NULL}, 9, 2, S_NULL}, // S_SPINDASHWIND
|
||||
|
||||
#ifdef SEENAMES
|
||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
|
||||
#endif
|
||||
|
|
@ -7923,35 +8008,35 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
},
|
||||
|
||||
{ // MT_BLUESPHERE
|
||||
1706, // doomednum
|
||||
S_BLUESPHERE, // spawnstate
|
||||
-1, // doomednum
|
||||
S_BLUESPHERE_SPAWN, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
MT_FLINGBLUESPHERE, // reactiontime
|
||||
MT_FLINGBLUESPHERE, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_BLUESPHERESPARK, // deathstate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_s3k65, // deathsound
|
||||
38*FRACUNIT, // speed
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
48*FRACUNIT, // radius
|
||||
48*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
S_BLUESPHEREBONUS // raisestate
|
||||
MF_RUNSPAWNFUNC|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FLINGBLUESPHERE
|
||||
-1, // doomednum
|
||||
S_BLUESPHERE, // spawnstate
|
||||
S_BLUESPHERE_SPAWN, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
|
@ -7962,7 +8047,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_BLUESPHERESPARK, // deathstate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_s3k65, // deathsound
|
||||
38*FRACUNIT, // speed
|
||||
|
|
@ -7973,7 +8058,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SLIDEME|MF_SPECIAL, // flags
|
||||
S_BLUESPHEREBONUS // raisestate
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BOMBSPHERE
|
||||
|
|
@ -8165,9 +8250,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_EMERALD1
|
||||
313, // doomednum
|
||||
S_CEMG1, // spawnstate
|
||||
{ // MT_EMERALD
|
||||
-1, // doomednum
|
||||
S_CHAOSEMERALD1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
|
@ -8178,22 +8263,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_SPRK1, // deathstate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_cgot, // deathsound
|
||||
EMERALD1, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
sfx_s3k9c, // deathsound
|
||||
0, // speed
|
||||
72*FRACUNIT, // radius
|
||||
72*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SPECIAL, // flags
|
||||
MF_SPECIAL|MF_PICKUPFROMBELOW|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_EMERALD2
|
||||
314, // doomednum
|
||||
S_CEMG2, // spawnstate
|
||||
|
||||
{ // MT_EMERALDSPARK
|
||||
-1, // doomednum
|
||||
S_EMERALDSPARK1,// spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
|
@ -8204,147 +8290,17 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_SPRK1, // deathstate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_cgot, // deathsound
|
||||
EMERALD2, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8*FRACUNIT, // radius
|
||||
8*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SPECIAL, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_EMERALD3
|
||||
315, // doomednum
|
||||
S_CEMG3, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_SPRK1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_cgot, // deathsound
|
||||
EMERALD3, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SPECIAL, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_EMERALD4
|
||||
316, // doomednum
|
||||
S_CEMG4, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_SPRK1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_cgot, // deathsound
|
||||
EMERALD4, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SPECIAL, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_EMERALD5
|
||||
317, // doomednum
|
||||
S_CEMG5, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_SPRK1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_cgot, // deathsound
|
||||
EMERALD5, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SPECIAL, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_EMERALD6
|
||||
318, // doomednum
|
||||
S_CEMG6, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_SPRK1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_cgot, // deathsound
|
||||
EMERALD6, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SPECIAL, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_EMERALD7
|
||||
319, // doomednum
|
||||
S_CEMG7, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_SPRK1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_cgot, // deathsound
|
||||
EMERALD7, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SPECIAL, // flags
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -8402,33 +8358,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FLINGEMERALD
|
||||
-1, // doomednum
|
||||
S_CEMG1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_SPRK1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_cgot, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
16*FRACUNIT, // radius
|
||||
48*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SLIDEME|MF_SPECIAL, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FAN
|
||||
540, // doomednum
|
||||
S_FAN, // spawnstate
|
||||
|
|
@ -8560,7 +8489,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
25*FRACUNIT, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
|
||||
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
S_YELLOWSPRING2 // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -8587,7 +8516,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
40*FRACUNIT, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
|
||||
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
S_REDSPRING2 // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -8614,7 +8543,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
64*FRACUNIT, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
|
||||
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
S_BLUESPRING2 // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -8641,7 +8570,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
15*FRACUNIT, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
|
||||
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
S_GREYSPRING2 // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -8668,7 +8597,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
25*FRACUNIT, // mass
|
||||
25*FRACUNIT, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
|
||||
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
S_YDIAG2 // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -8695,7 +8624,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
40*FRACUNIT, // mass
|
||||
40*FRACUNIT, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
|
||||
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
S_RDIAG2 // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -8722,7 +8651,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
64*FRACUNIT, // mass
|
||||
64*FRACUNIT, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
|
||||
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
S_BDIAG2 // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -8749,7 +8678,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
15*FRACUNIT, // mass
|
||||
15*FRACUNIT, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags
|
||||
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
S_GDIAG2 // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -19073,7 +19002,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
|
||||
{ // MT_GOTEMERALD
|
||||
-1, // doomednum
|
||||
S_CEMG1, // spawnstate
|
||||
S_CHAOSEMERALD1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
|
@ -22908,13 +22837,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_itpick, // deathsound
|
||||
0, // speed
|
||||
32*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
48*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SLIDEME|MF_SPECIAL|MF_DONTENCOREMAP, // flags
|
||||
MF_SLIDEME|MF_SPECIAL|MF_PICKUPFROMBELOW|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -24200,7 +24129,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_BATTLEBUMPER1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
4*FRACUNIT, // speed
|
||||
|
|
@ -24214,6 +24143,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BATTLEBUMPER_DEBRIS
|
||||
-1, // doomednum
|
||||
S_BATTLEBUMPER_EXDEBRIS1,// spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8*FRACUNIT, // radius
|
||||
16*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BATTLEBUMPER_BLAST
|
||||
-1, // doomednum
|
||||
S_BATTLEBUMPER_EXBLAST1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8*FRACUNIT, // radius
|
||||
16*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DEZLASER
|
||||
-1, // doomednum
|
||||
S_DEZLASER, // spawnstate
|
||||
|
|
@ -28402,9 +28385,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_OVERTIMEFOG
|
||||
{ // MT_OVERTIME_PARTICLE
|
||||
-1, // doomednum
|
||||
S_OVERTIMEFOG, // spawnstate
|
||||
S_NULL, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
|
@ -28420,8 +28403,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
16<<FRACBITS, // radius
|
||||
32<<FRACBITS, // height
|
||||
-1, // display offset
|
||||
24<<FRACBITS, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
|
|
@ -28429,9 +28412,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_OVERTIMEORB
|
||||
-1, // doomednum
|
||||
S_OVERTIMEORB, // spawnstate
|
||||
{ // MT_OVERTIME_CENTER
|
||||
3775, // doomednum
|
||||
S_OVERTIME_CENTER, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
|
@ -28446,40 +28429,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
16<<FRACBITS, // radius
|
||||
48<<FRACBITS, // height
|
||||
-1, // display offset
|
||||
12<<FRACBITS, // radius
|
||||
72<<FRACBITS, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_OVERTIMEBEAM
|
||||
-1, // doomednum
|
||||
S_OVERTIMEBEAM, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
48<<FRACBITS, // radius
|
||||
48<<FRACBITS, // height
|
||||
-1, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
MF_SOLID|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -28675,6 +28631,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_SPINDASHDUST
|
||||
-1, // doomednum
|
||||
S_SPINDASHDUST, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
12*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_SPINDASHWIND
|
||||
-1, // doomednum
|
||||
S_SPINDASHWIND, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
12*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_PAPERITEMSPOT
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
48*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
1, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
// ============================================================================================================================//
|
||||
|
||||
#ifdef SEENAMES
|
||||
|
|
@ -28864,7 +28901,15 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
|
|||
{"Super Tan 2", {0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, SKINCOLOR_BROWN, 13, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN2
|
||||
{"Super Tan 3", {0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, SKINCOLOR_BROWN, 12, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN3
|
||||
{"Super Tan 4", {0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, SKINCOLOR_BROWN, 11, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN4
|
||||
{"Super Tan 5", {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef}, SKINCOLOR_BROWN, 10, V_BROWNMAP, false} // SKINCOLOR_SUPERTAN5
|
||||
{"Super Tan 5", {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef}, SKINCOLOR_BROWN, 10, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN5
|
||||
|
||||
{"Chaos Emerald 1", { 0, 88, 188, 98, 114, 116, 117, 119, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD1
|
||||
{"Chaos Emerald 2", { 0, 80, 82, 74, 65, 52, 56, 60, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD2
|
||||
{"Chaos Emerald 3", { 0, 252, 201, 179, 182, 183, 185, 187, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD3
|
||||
{"Chaos Emerald 4", { 0, 144, 146, 147, 149, 165, 167, 169, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD4
|
||||
{"Chaos Emerald 5", { 0, 1, 144, 4, 9, 170, 14, 21, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD5
|
||||
{"Chaos Emerald 6", { 0, 208, 50, 32, 34, 37, 40, 44, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD6
|
||||
{"Chaos Emerald 7", { 0, 120, 121, 140, 133, 135, 149, 156, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false} // SKINCOLOR_CHAOSEMERALD7
|
||||
};
|
||||
|
||||
/** Patches the mobjinfo, state, and skincolor tables.
|
||||
|
|
|
|||
141
src/info.h
141
src/info.h
|
|
@ -406,11 +406,12 @@ typedef enum sprite
|
|||
SPR_TOKE, // Special Stage Token
|
||||
SPR_RFLG, // Red CTF Flag
|
||||
SPR_BFLG, // Blue CTF Flag
|
||||
//SPR_SPHR, // Sphere
|
||||
SPR_BSPH, // Sphere
|
||||
SPR_NCHP, // NiGHTS chip
|
||||
SPR_NSTR, // NiGHTS star
|
||||
SPR_EMBM, // Emblem
|
||||
SPR_CEMG, // Chaos Emeralds
|
||||
SPR_EMRC, // Chaos Emeralds
|
||||
SPR_ESPK,
|
||||
SPR_SHRD, // Emerald Hunt
|
||||
|
||||
// Interactive Objects
|
||||
|
|
@ -828,6 +829,10 @@ typedef enum sprite
|
|||
SPR_SINK, // Kitchen Sink
|
||||
SPR_SITR, // Kitchen Sink Trail
|
||||
SPR_KBLN, // Battle Mode Bumper
|
||||
SPR_BEXC, // Battle Bumper Explosion: Crystal
|
||||
SPR_BEXS, // Battle Bumper Explosion: Shell
|
||||
SPR_BDEB, // Battle Bumper Explosion: Debris
|
||||
SPR_BEXB, // Battle Bumper Explosion: Blast
|
||||
|
||||
SPR_DEZL, // DEZ Laser respawn
|
||||
|
||||
|
|
@ -984,7 +989,9 @@ typedef enum sprite
|
|||
SPR_DRAF,
|
||||
SPR_GRES,
|
||||
|
||||
SPR_OTFG,
|
||||
SPR_OTBU,
|
||||
SPR_OTLS,
|
||||
SPR_OTCP,
|
||||
|
||||
SPR_DBOS, // Drift boost flame
|
||||
|
||||
|
|
@ -1002,6 +1009,9 @@ typedef enum sprite
|
|||
SPR_DBNC, // Drift boost clip's sparks
|
||||
SPR_DBST, // Drift boost plume
|
||||
|
||||
SPR_SDDS, // Spindash dust
|
||||
SPR_SDWN, // Spindash wind
|
||||
|
||||
SPR_FIRSTFREESLOT,
|
||||
SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
|
||||
NUMSPRITES
|
||||
|
|
@ -2016,8 +2026,41 @@ typedef enum state
|
|||
|
||||
// Blue Sphere for special stages
|
||||
S_BLUESPHERE,
|
||||
S_BLUESPHEREBONUS,
|
||||
S_BLUESPHERESPARK,
|
||||
S_BLUESPHERE_SPAWN,
|
||||
|
||||
S_BLUESPHERE_BOUNCE1,
|
||||
S_BLUESPHERE_BOUNCE2,
|
||||
|
||||
S_BLUESPHERE_BOUNCE3,
|
||||
S_BLUESPHERE_BOUNCE4,
|
||||
|
||||
S_BLUESPHERE_BOUNCE5,
|
||||
S_BLUESPHERE_BOUNCE6,
|
||||
S_BLUESPHERE_BOUNCE7,
|
||||
S_BLUESPHERE_BOUNCE8,
|
||||
|
||||
S_BLUESPHERE_BOUNCE9,
|
||||
S_BLUESPHERE_BOUNCE10,
|
||||
S_BLUESPHERE_BOUNCE11,
|
||||
S_BLUESPHERE_BOUNCE12,
|
||||
|
||||
S_BLUESPHERE_BOUNCE13,
|
||||
S_BLUESPHERE_BOUNCE14,
|
||||
S_BLUESPHERE_BOUNCE15,
|
||||
S_BLUESPHERE_BOUNCE16,
|
||||
S_BLUESPHERE_BOUNCE17,
|
||||
S_BLUESPHERE_BOUNCE18,
|
||||
S_BLUESPHERE_BOUNCE19,
|
||||
S_BLUESPHERE_BOUNCE20,
|
||||
|
||||
S_BLUESPHERE_BOUNCE21,
|
||||
S_BLUESPHERE_BOUNCE22,
|
||||
S_BLUESPHERE_BOUNCE23,
|
||||
S_BLUESPHERE_BOUNCE24,
|
||||
S_BLUESPHERE_BOUNCE25,
|
||||
S_BLUESPHERE_BOUNCE26,
|
||||
S_BLUESPHERE_BOUNCE27,
|
||||
S_BLUESPHERE_BOUNCE28,
|
||||
|
||||
// Bomb Sphere
|
||||
S_BOMBSPHERE1,
|
||||
|
|
@ -2076,13 +2119,17 @@ typedef enum state
|
|||
S_EMBLEM26,
|
||||
|
||||
// Chaos Emeralds
|
||||
S_CEMG1,
|
||||
S_CEMG2,
|
||||
S_CEMG3,
|
||||
S_CEMG4,
|
||||
S_CEMG5,
|
||||
S_CEMG6,
|
||||
S_CEMG7,
|
||||
S_CHAOSEMERALD1,
|
||||
S_CHAOSEMERALD2,
|
||||
S_CHAOSEMERALD_UNDER,
|
||||
|
||||
S_EMERALDSPARK1,
|
||||
S_EMERALDSPARK2,
|
||||
S_EMERALDSPARK3,
|
||||
S_EMERALDSPARK4,
|
||||
S_EMERALDSPARK5,
|
||||
S_EMERALDSPARK6,
|
||||
S_EMERALDSPARK7,
|
||||
|
||||
// Emerald hunt shards
|
||||
S_SHRD1,
|
||||
|
|
@ -4527,6 +4574,44 @@ typedef enum state
|
|||
S_BATTLEBUMPER2,
|
||||
S_BATTLEBUMPER3,
|
||||
|
||||
S_BATTLEBUMPER_EXCRYSTALA1,
|
||||
S_BATTLEBUMPER_EXCRYSTALA2,
|
||||
S_BATTLEBUMPER_EXCRYSTALA3,
|
||||
S_BATTLEBUMPER_EXCRYSTALA4,
|
||||
|
||||
S_BATTLEBUMPER_EXCRYSTALB1,
|
||||
S_BATTLEBUMPER_EXCRYSTALB2,
|
||||
S_BATTLEBUMPER_EXCRYSTALB3,
|
||||
S_BATTLEBUMPER_EXCRYSTALB4,
|
||||
|
||||
S_BATTLEBUMPER_EXCRYSTALC1,
|
||||
S_BATTLEBUMPER_EXCRYSTALC2,
|
||||
S_BATTLEBUMPER_EXCRYSTALC3,
|
||||
S_BATTLEBUMPER_EXCRYSTALC4,
|
||||
|
||||
S_BATTLEBUMPER_EXSHELLA1,
|
||||
S_BATTLEBUMPER_EXSHELLA2,
|
||||
|
||||
S_BATTLEBUMPER_EXSHELLB1,
|
||||
S_BATTLEBUMPER_EXSHELLB2,
|
||||
|
||||
S_BATTLEBUMPER_EXSHELLC1,
|
||||
S_BATTLEBUMPER_EXSHELLC2,
|
||||
|
||||
S_BATTLEBUMPER_EXDEBRIS1,
|
||||
S_BATTLEBUMPER_EXDEBRIS2,
|
||||
|
||||
S_BATTLEBUMPER_EXBLAST1,
|
||||
S_BATTLEBUMPER_EXBLAST2,
|
||||
S_BATTLEBUMPER_EXBLAST3,
|
||||
S_BATTLEBUMPER_EXBLAST4,
|
||||
S_BATTLEBUMPER_EXBLAST5,
|
||||
S_BATTLEBUMPER_EXBLAST6,
|
||||
S_BATTLEBUMPER_EXBLAST7,
|
||||
S_BATTLEBUMPER_EXBLAST8,
|
||||
S_BATTLEBUMPER_EXBLAST9,
|
||||
S_BATTLEBUMPER_EXBLAST10,
|
||||
|
||||
// DEZ Laser respawn
|
||||
S_DEZLASER,
|
||||
S_DEZLASER_TRAIL1,
|
||||
|
|
@ -5147,9 +5232,10 @@ typedef enum state
|
|||
|
||||
S_TIREGREASE,
|
||||
|
||||
S_OVERTIMEFOG,
|
||||
S_OVERTIMEORB,
|
||||
S_OVERTIMEBEAM,
|
||||
S_OVERTIME_BULB1,
|
||||
S_OVERTIME_BULB2,
|
||||
S_OVERTIME_LASER,
|
||||
S_OVERTIME_CENTER,
|
||||
|
||||
S_BATTLECAPSULE_SIDE1,
|
||||
S_BATTLECAPSULE_SIDE2,
|
||||
|
|
@ -5177,6 +5263,9 @@ typedef enum state
|
|||
S_WATERTRAILUNDERLAY7,
|
||||
S_WATERTRAILUNDERLAY8,
|
||||
|
||||
S_SPINDASHDUST,
|
||||
S_SPINDASHWIND,
|
||||
|
||||
#ifdef SEENAMES
|
||||
S_NAMECHECK,
|
||||
#endif
|
||||
|
|
@ -5345,16 +5434,10 @@ typedef enum mobj_type
|
|||
MT_REDFLAG, // Red CTF Flag
|
||||
MT_BLUEFLAG, // Blue CTF Flag
|
||||
MT_EMBLEM,
|
||||
MT_EMERALD1,
|
||||
MT_EMERALD2,
|
||||
MT_EMERALD3,
|
||||
MT_EMERALD4,
|
||||
MT_EMERALD5,
|
||||
MT_EMERALD6,
|
||||
MT_EMERALD7,
|
||||
MT_EMERALD,
|
||||
MT_EMERALDSPARK,
|
||||
MT_EMERHUNT, // Emerald Hunt
|
||||
MT_EMERALDSPAWN, // Emerald spawner w/ delay
|
||||
MT_FLINGEMERALD, // Lost emerald
|
||||
|
||||
// Springs and others
|
||||
MT_FAN,
|
||||
|
|
@ -6049,6 +6132,8 @@ typedef enum mobj_type
|
|||
MT_SINKTRAIL,
|
||||
|
||||
MT_BATTLEBUMPER, // Battle Mode bumpers
|
||||
MT_BATTLEBUMPER_DEBRIS,
|
||||
MT_BATTLEBUMPER_BLAST,
|
||||
|
||||
MT_DEZLASER,
|
||||
|
||||
|
|
@ -6263,9 +6348,8 @@ typedef enum mobj_type
|
|||
MT_SPBDUST,
|
||||
MT_TIREGREASE,
|
||||
|
||||
MT_OVERTIMEFOG,
|
||||
MT_OVERTIMEORB,
|
||||
MT_OVERTIMEBEAM,
|
||||
MT_OVERTIME_PARTICLE,
|
||||
MT_OVERTIME_CENTER,
|
||||
|
||||
MT_BATTLECAPSULE,
|
||||
MT_BATTLECAPSULE_PIECE,
|
||||
|
|
@ -6277,6 +6361,11 @@ typedef enum mobj_type
|
|||
MT_WATERTRAIL,
|
||||
MT_WATERTRAILUNDERLAY,
|
||||
|
||||
MT_SPINDASHDUST,
|
||||
MT_SPINDASHWIND,
|
||||
|
||||
MT_PAPERITEMSPOT,
|
||||
|
||||
#ifdef SEENAMES
|
||||
MT_NAMECHECK,
|
||||
#endif
|
||||
|
|
|
|||
609
src/k_battle.c
609
src/k_battle.c
|
|
@ -41,6 +41,9 @@ INT32 K_StartingBumperCount(void)
|
|||
|
||||
boolean K_IsPlayerWanted(player_t *player)
|
||||
{
|
||||
#if 1
|
||||
return (player->kartstuff[k_position] == 1);
|
||||
#else
|
||||
UINT8 i;
|
||||
|
||||
if (!(gametyperules & GTR_WANTED))
|
||||
|
|
@ -54,28 +57,26 @@ boolean K_IsPlayerWanted(player_t *player)
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void K_CalculateBattleWanted(void)
|
||||
{
|
||||
UINT8 numingame = 0, numplaying = 0, numwanted = 0;
|
||||
SINT8 bestbumperplayer = -1, bestbumper = -1;
|
||||
UINT8 numingame = 0, numwanted = 0;
|
||||
SINT8 camppos[MAXPLAYERS]; // who is the biggest camper
|
||||
UINT8 ties = 0, nextcamppos = 0;
|
||||
boolean setbumper = false;
|
||||
UINT8 i, j;
|
||||
|
||||
#if 0
|
||||
if (!(gametyperules & GTR_WANTED))
|
||||
#endif
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
battlewanted[i] = -1;
|
||||
memset(battlewanted, -1, sizeof (battlewanted));
|
||||
return;
|
||||
}
|
||||
|
||||
wantedcalcdelay = wantedfrequency;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
camppos[i] = -1; // initialize
|
||||
memset(camppos, -1, sizeof (camppos)); // initialize
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
|
@ -87,33 +88,38 @@ void K_CalculateBattleWanted(void)
|
|||
if (players[i].exiting) // We're done, don't calculate.
|
||||
return;
|
||||
|
||||
numplaying++;
|
||||
|
||||
if (players[i].kartstuff[k_bumper] <= 0) // Not alive, so don't do anything else
|
||||
if (players[i].bumpers <= 0) // Not alive, so don't do anything else
|
||||
continue;
|
||||
|
||||
numingame++;
|
||||
|
||||
if (bestbumper == -1 || players[i].kartstuff[k_bumper] > bestbumper)
|
||||
{
|
||||
bestbumper = players[i].kartstuff[k_bumper];
|
||||
bestbumperplayer = i;
|
||||
}
|
||||
else if (players[i].kartstuff[k_bumper] == bestbumper)
|
||||
bestbumperplayer = -1; // Tie, no one has best bumper.
|
||||
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
{
|
||||
if (!playeringame[j] || players[j].spectator)
|
||||
continue;
|
||||
if (players[j].kartstuff[k_bumper] <= 0)
|
||||
|
||||
if (players[j].bumpers <= 0)
|
||||
continue;
|
||||
|
||||
if (j == i)
|
||||
continue;
|
||||
if (players[j].kartstuff[k_wanted] == players[i].kartstuff[k_wanted] && players[j].marescore > players[i].marescore)
|
||||
|
||||
if (K_NumEmeralds(&players[j]) > K_NumEmeralds(&players[i]))
|
||||
{
|
||||
position++;
|
||||
}
|
||||
else if (players[j].bumpers > players[i].bumpers)
|
||||
{
|
||||
position++;
|
||||
}
|
||||
else if (players[j].marescore > players[i].marescore)
|
||||
{
|
||||
position++;
|
||||
}
|
||||
else if (players[j].kartstuff[k_wanted] > players[i].kartstuff[k_wanted])
|
||||
{
|
||||
position++;
|
||||
}
|
||||
}
|
||||
|
||||
position--; // Make zero based
|
||||
|
|
@ -124,7 +130,7 @@ void K_CalculateBattleWanted(void)
|
|||
camppos[position] = i;
|
||||
}
|
||||
|
||||
if (numplaying <= 2 || (numingame <= 2 && bestbumper == 1)) // In 1v1s then there's no need for WANTED. In bigger netgames, don't show anyone as WANTED when they're equally matched.
|
||||
if (numingame <= 2) // In 1v1s then there's no need for WANTED.
|
||||
numwanted = 0;
|
||||
else
|
||||
numwanted = min(4, 1 + ((numingame-2) / 4));
|
||||
|
|
@ -132,19 +138,11 @@ void K_CalculateBattleWanted(void)
|
|||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (i+1 > numwanted) // Not enough players for this slot to be wanted!
|
||||
battlewanted[i] = -1;
|
||||
else if (bestbumperplayer != -1 && !setbumper) // If there's a player who has an untied bumper lead over everyone else, they are the first to be wanted.
|
||||
{
|
||||
battlewanted[i] = bestbumperplayer;
|
||||
setbumper = true; // Don't set twice
|
||||
battlewanted[i] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't accidentally set the same player, if the bestbumperplayer is also a huge camper.
|
||||
while (bestbumperplayer != -1 && camppos[nextcamppos] != -1
|
||||
&& bestbumperplayer == camppos[nextcamppos])
|
||||
nextcamppos++;
|
||||
|
||||
// Do not add *any* more people if there's too many times that are tied with others.
|
||||
// This could theoretically happen very easily if people don't hit each other for a while after the start of a match.
|
||||
// (I will be sincerely impressed if more than 2 people tie after people start hitting each other though)
|
||||
|
|
@ -230,7 +228,7 @@ void K_CheckBumpers(void)
|
|||
numingame++;
|
||||
winnerscoreadd += players[i].marescore;
|
||||
|
||||
if (players[i].kartstuff[k_bumper] <= 0) // if you don't have any bumpers, you're probably not a winner
|
||||
if (players[i].bumpers <= 0) // if you don't have any bumpers, you're probably not a winner
|
||||
{
|
||||
nobumpers = true;
|
||||
continue;
|
||||
|
|
@ -277,125 +275,411 @@ void K_CheckBumpers(void)
|
|||
P_DoPlayerExit(&players[i]);
|
||||
}
|
||||
|
||||
#define MAXPLANESPERSECTOR (MAXFFLOORS+1)*2
|
||||
|
||||
static void K_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjtype_t type, boolean ceiling)
|
||||
void K_CheckEmeralds(player_t *player)
|
||||
{
|
||||
UINT8 i;
|
||||
fixed_t flatz[MAXPLANESPERSECTOR];
|
||||
boolean flip[MAXPLANESPERSECTOR];
|
||||
UINT8 numflats = 0;
|
||||
mobj_t *mo;
|
||||
subsector_t *ss = R_PointInSubsectorOrNull(x, y);
|
||||
sector_t *sec;
|
||||
|
||||
if (!ss)
|
||||
if (!ALLCHAOSEMERALDS(player->powers[pw_emeralds]))
|
||||
{
|
||||
return;
|
||||
sec = ss->sector;
|
||||
|
||||
// convoluted stuff JUST to get all of the planes we need to draw orbs on :V
|
||||
|
||||
for (i = 0; i < MAXPLANESPERSECTOR; i++)
|
||||
flip[i] = false;
|
||||
|
||||
if (sec->floorpic != skyflatnum)
|
||||
{
|
||||
flatz[numflats] = P_GetZAt(sec->f_slope, x, y, sec->floorheight);
|
||||
numflats++;
|
||||
}
|
||||
if (sec->ceilingpic != skyflatnum && ceiling)
|
||||
{
|
||||
flatz[numflats] = P_GetZAt(sec->c_slope, x, y, sec->ceilingheight) - FixedMul(mobjinfo[type].height, scale);
|
||||
flip[numflats] = true;
|
||||
numflats++;
|
||||
}
|
||||
|
||||
if (sec->ffloors)
|
||||
player->marescore++; // lol
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
|
||||
continue;
|
||||
if (*rover->toppic != skyflatnum)
|
||||
{
|
||||
flatz[numflats] = P_GetZAt(*rover->t_slope, x, y, *rover->topheight);
|
||||
numflats++;
|
||||
}
|
||||
if (*rover->bottompic != skyflatnum && ceiling)
|
||||
{
|
||||
flatz[numflats] = P_GetZAt(*rover->b_slope, x, y, *rover->bottomheight);
|
||||
flip[numflats] = true;
|
||||
numflats++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (&players[i] == player)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
players[i].bumpers = 0;
|
||||
}
|
||||
|
||||
if (numflats <= 0) // no flats
|
||||
return;
|
||||
K_CheckBumpers();
|
||||
}
|
||||
|
||||
for (i = 0; i < numflats; i++)
|
||||
mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT32 emeraldType)
|
||||
{
|
||||
boolean validEmerald = true;
|
||||
mobj_t *emerald = P_SpawnMobj(x, y, z, MT_EMERALD);
|
||||
mobj_t *overlay;
|
||||
|
||||
P_Thrust(emerald,
|
||||
FixedAngle(P_RandomFixed() * 180) + angle,
|
||||
32 * mapobjectscale);
|
||||
|
||||
emerald->momz = flip * 24 * mapobjectscale;
|
||||
if (emerald->eflags & MFE_UNDERWATER)
|
||||
emerald->momz = (117 * emerald->momz) / 200;
|
||||
|
||||
emerald->threshold = 10;
|
||||
|
||||
switch (emeraldType)
|
||||
{
|
||||
mo = P_SpawnMobj(x, y, flatz[i], type);
|
||||
case EMERALD_CHAOS1:
|
||||
emerald->color = SKINCOLOR_CHAOSEMERALD1;
|
||||
break;
|
||||
case EMERALD_CHAOS2:
|
||||
emerald->color = SKINCOLOR_CHAOSEMERALD2;
|
||||
break;
|
||||
case EMERALD_CHAOS3:
|
||||
emerald->color = SKINCOLOR_CHAOSEMERALD3;
|
||||
break;
|
||||
case EMERALD_CHAOS4:
|
||||
emerald->color = SKINCOLOR_CHAOSEMERALD4;
|
||||
break;
|
||||
case EMERALD_CHAOS5:
|
||||
emerald->color = SKINCOLOR_CHAOSEMERALD5;
|
||||
break;
|
||||
case EMERALD_CHAOS6:
|
||||
emerald->color = SKINCOLOR_CHAOSEMERALD6;
|
||||
break;
|
||||
case EMERALD_CHAOS7:
|
||||
emerald->color = SKINCOLOR_CHAOSEMERALD7;
|
||||
break;
|
||||
default:
|
||||
CONS_Printf("Invalid emerald type %d\n", emeraldType);
|
||||
validEmerald = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Lastly, if this can see the skybox mobj, then... we just wasted our time :V
|
||||
if (skyboxmo[0] && !P_MobjWasRemoved(skyboxmo[0]))
|
||||
if (validEmerald == true)
|
||||
{
|
||||
emerald->extravalue1 = emeraldType;
|
||||
}
|
||||
|
||||
overlay = P_SpawnMobjFromMobj(emerald, 0, 0, 0, MT_OVERLAY);
|
||||
P_SetTarget(&overlay->target, emerald);
|
||||
P_SetMobjState(overlay, S_CHAOSEMERALD_UNDER);
|
||||
overlay->color = emerald->color;
|
||||
|
||||
return emerald;
|
||||
}
|
||||
|
||||
void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType)
|
||||
{
|
||||
UINT8 i;
|
||||
SINT8 flip = P_MobjFlip(player->mo);
|
||||
|
||||
for (i = 0; i < 14; i++)
|
||||
{
|
||||
UINT32 emeraldFlag = (1 << i);
|
||||
|
||||
if ((player->powers[pw_emeralds] & emeraldFlag) && (emeraldFlag & emeraldType))
|
||||
{
|
||||
const fixed_t sbz = skyboxmo[0]->z;
|
||||
fixed_t checkz = sec->floorheight;
|
||||
mobj_t *emerald = K_SpawnChaosEmerald(player->mo->x, player->mo->y, player->mo->z, player->mo->angle - ANGLE_90, flip, emeraldFlag);
|
||||
P_SetTarget(&emerald->target, player->mo);
|
||||
|
||||
while (checkz < sec->ceilingheight)
|
||||
{
|
||||
P_TeleportMove(skyboxmo[0], skyboxmo[0]->x, skyboxmo[0]->y, checkz);
|
||||
if (P_CheckSight(skyboxmo[0], mo))
|
||||
{
|
||||
P_RemoveMobj(mo);
|
||||
break;
|
||||
}
|
||||
else
|
||||
checkz += 32*mapobjectscale;
|
||||
}
|
||||
|
||||
P_TeleportMove(skyboxmo[0], skyboxmo[0]->x, skyboxmo[0]->y, sbz);
|
||||
|
||||
if (P_MobjWasRemoved(mo))
|
||||
continue;
|
||||
}
|
||||
|
||||
P_SetScale(mo, scale);
|
||||
|
||||
if (flip[i])
|
||||
{
|
||||
mo->flags2 |= MF2_OBJECTFLIP;
|
||||
mo->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case MT_OVERTIMEFOG:
|
||||
mo->destscale = 8*mo->scale;
|
||||
mo->momz = P_RandomRange(1,8)*mo->scale;
|
||||
break;
|
||||
case MT_OVERTIMEORB:
|
||||
//mo->destscale = mo->scale/4;
|
||||
mo->frame += ((leveltime/4) % 8);
|
||||
/*if (battleovertime.enabled < 10*TICRATE)
|
||||
mo->drawflags |= MFD_SHADOW;*/
|
||||
mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90;
|
||||
mo->z += P_RandomRange(0,48) * mo->scale;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
player->powers[pw_emeralds] &= ~emeraldFlag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef MAXPLANESPERSECTOR
|
||||
UINT8 K_NumEmeralds(player_t *player)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT8 num = 0;
|
||||
|
||||
for (i = 0; i < 14; i++)
|
||||
{
|
||||
UINT32 emeraldFlag = (1 << i);
|
||||
|
||||
if (player->powers[pw_emeralds] & emeraldFlag)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
void K_RunPaperItemSpawners(void)
|
||||
{
|
||||
const boolean overtime = (battleovertime.enabled >= 10*TICRATE);
|
||||
tic_t interval = 8*TICRATE;
|
||||
|
||||
UINT32 emeraldsSpawned = 0;
|
||||
UINT32 firstUnspawnedEmerald = 0;
|
||||
|
||||
thinker_t *th;
|
||||
mobj_t *mo;
|
||||
|
||||
UINT8 pcount = 0;
|
||||
INT16 i;
|
||||
|
||||
if (leveltime < starttime)
|
||||
{
|
||||
// Round hasn't started yet!
|
||||
return;
|
||||
}
|
||||
|
||||
if (overtime == true)
|
||||
{
|
||||
if (battleovertime.radius < 512*mapobjectscale)
|
||||
{
|
||||
// Barrier has closed in too much
|
||||
return;
|
||||
}
|
||||
|
||||
// Double frequency of items
|
||||
interval /= 2;
|
||||
}
|
||||
|
||||
if (((leveltime - starttime) % interval) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
emeraldsSpawned |= players[i].powers[pw_emeralds];
|
||||
|
||||
if ((players[i].exiting > 0 || players[i].eliminated)
|
||||
|| ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
pcount++;
|
||||
}
|
||||
|
||||
if (overtime == true)
|
||||
{
|
||||
SINT8 flip = 1;
|
||||
|
||||
// Just find emeralds, no paper spots
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
|
||||
if (mo->type == MT_EMERALD)
|
||||
{
|
||||
emeraldsSpawned |= mo->extravalue1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
UINT32 emeraldFlag = (1 << i);
|
||||
|
||||
if (!(emeraldsSpawned & emeraldFlag))
|
||||
{
|
||||
firstUnspawnedEmerald = emeraldFlag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstUnspawnedEmerald != 0)
|
||||
{
|
||||
K_SpawnChaosEmerald(
|
||||
battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip),
|
||||
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
|
||||
firstUnspawnedEmerald
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
K_CreatePaperItem(
|
||||
battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip),
|
||||
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
|
||||
0, 0
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pcount > 0)
|
||||
{
|
||||
#define MAXITEM 64
|
||||
UINT8 item = 0;
|
||||
mobj_t *spotList[MAXITEM];
|
||||
boolean spotUsed[MAXITEM];
|
||||
|
||||
INT16 starti = 0;
|
||||
|
||||
memset(spotUsed, false, sizeof(spotUsed));
|
||||
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
|
||||
if (mo->type == MT_PAPERITEMSPOT)
|
||||
{
|
||||
if (item >= MAXITEM)
|
||||
continue;
|
||||
|
||||
spotList[item] = mo;
|
||||
item++;
|
||||
}
|
||||
else if (mo->type == MT_EMERALD)
|
||||
{
|
||||
emeraldsSpawned |= mo->extravalue1;
|
||||
}
|
||||
}
|
||||
|
||||
if (item <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
UINT32 emeraldFlag = (1 << i);
|
||||
|
||||
if (!(emeraldsSpawned & emeraldFlag))
|
||||
{
|
||||
firstUnspawnedEmerald = emeraldFlag;
|
||||
starti = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = starti; i < min(item + starti, pcount); i++)
|
||||
{
|
||||
UINT8 r = P_RandomKey(item);
|
||||
UINT8 recursion = 0;
|
||||
mobj_t *drop = NULL;
|
||||
SINT8 flip = 1;
|
||||
|
||||
while (spotUsed[r] == true)
|
||||
{
|
||||
r = P_RandomKey(item);
|
||||
|
||||
if ((recursion++) > MAXITEM)
|
||||
{
|
||||
// roll with it anyway I guess
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flip = P_MobjFlip(spotList[r]);
|
||||
|
||||
// When -1, we're spawning a Chaos Emerald.
|
||||
if (i == -1)
|
||||
{
|
||||
drop = K_SpawnChaosEmerald(
|
||||
spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip),
|
||||
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
|
||||
firstUnspawnedEmerald
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
drop = K_CreatePaperItem(
|
||||
spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip),
|
||||
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
|
||||
0, 0
|
||||
);
|
||||
}
|
||||
|
||||
K_FlipFromObject(drop, spotList[r]);
|
||||
spotUsed[r] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void K_SpawnOvertimeLaser(fixed_t x, fixed_t y, fixed_t scale)
|
||||
{
|
||||
UINT8 i, j;
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
player_t *player = &players[displayplayers[i]];
|
||||
fixed_t zpos;
|
||||
SINT8 flip;
|
||||
|
||||
if (player == NULL || player->mo == NULL || P_MobjWasRemoved(player->mo) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
zpos = player->mo->z + player->mo->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
zpos = player->mo->z;
|
||||
}
|
||||
|
||||
flip = P_MobjFlip(player->mo);
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
mobj_t *mo = P_SpawnMobj(x, y, zpos, MT_OVERTIME_PARTICLE);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
mo->flags2 |= MF2_OBJECTFLIP;
|
||||
mo->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
|
||||
mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90;
|
||||
mo->drawflags |= (MFD_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player)));
|
||||
|
||||
P_SetScale(mo, scale);
|
||||
|
||||
switch (j)
|
||||
{
|
||||
case 0:
|
||||
P_SetMobjState(mo, S_OVERTIME_BULB1);
|
||||
|
||||
if (leveltime & 1)
|
||||
mo->frame += 1;
|
||||
|
||||
//P_SetScale(mo, mapobjectscale);
|
||||
zpos += 35 * mo->scale * flip;
|
||||
break;
|
||||
case 1:
|
||||
P_SetMobjState(mo, S_OVERTIME_LASER);
|
||||
|
||||
if (leveltime & 1)
|
||||
mo->frame += 3;
|
||||
else
|
||||
mo->frame += (leveltime / 2) % 3;
|
||||
|
||||
//P_SetScale(mo, scale);
|
||||
zpos += 346 * mo->scale * flip;
|
||||
|
||||
if (battleovertime.enabled < 10*TICRATE)
|
||||
mo->drawflags |= MFD_TRANS50;
|
||||
break;
|
||||
case 2:
|
||||
P_SetMobjState(mo, S_OVERTIME_BULB2);
|
||||
|
||||
if (leveltime & 1)
|
||||
mo->frame += 1;
|
||||
|
||||
//P_SetScale(mo, mapobjectscale);
|
||||
break;
|
||||
default:
|
||||
I_Error("Bruh moment has occured\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void K_RunBattleOvertime(void)
|
||||
{
|
||||
UINT16 i, j;
|
||||
|
||||
if (battleovertime.enabled < 10*TICRATE)
|
||||
{
|
||||
battleovertime.enabled++;
|
||||
|
|
@ -404,70 +688,37 @@ void K_RunBattleOvertime(void)
|
|||
if (battleovertime.enabled == 10*TICRATE)
|
||||
S_StartSound(NULL, sfx_kc40);
|
||||
}
|
||||
else
|
||||
else if (battleovertime.radius > 0)
|
||||
{
|
||||
if (battleovertime.radius > battleovertime.minradius)
|
||||
battleovertime.radius -= mapobjectscale;
|
||||
if (battleovertime.radius > 2*mapobjectscale)
|
||||
battleovertime.radius -= 2*mapobjectscale;
|
||||
else
|
||||
battleovertime.radius = battleovertime.minradius;
|
||||
battleovertime.radius = 0;
|
||||
}
|
||||
|
||||
if (leveltime & 1)
|
||||
if (battleovertime.radius > 0)
|
||||
{
|
||||
UINT8 transparency = tr_trans50;
|
||||
const fixed_t pi = (22 * FRACUNIT) / 7; // loose approximation, this doesn't need to be incredibly precise
|
||||
const INT32 orbs = 32;
|
||||
const angle_t angoff = ANGLE_MAX / orbs;
|
||||
const UINT8 spriteSpacing = 128;
|
||||
|
||||
if (!splitscreen && players[displayplayers[0]].mo)
|
||||
{
|
||||
INT32 dist = P_AproxDistance(battleovertime.x-players[displayplayers[0]].mo->x, battleovertime.y-players[displayplayers[0]].mo->y);
|
||||
transparency = max(0, NUMTRANSMAPS - ((256 + (dist>>FRACBITS)) / 256));
|
||||
}
|
||||
fixed_t circumference = FixedMul(pi, battleovertime.radius * 2);
|
||||
fixed_t scale = max(circumference / spriteSpacing / orbs, mapobjectscale);
|
||||
|
||||
if (transparency < NUMTRANSMAPS)
|
||||
{
|
||||
mobj_t *beam = P_SpawnMobj(battleovertime.x, battleovertime.y, battleovertime.z + (mobjinfo[MT_RANDOMITEM].height/2), MT_OVERTIMEBEAM);
|
||||
P_SetScale(beam, beam->scale*2);
|
||||
if (transparency > 0)
|
||||
beam->frame |= transparency<<FF_TRANSSHIFT;
|
||||
}
|
||||
}
|
||||
fixed_t size = FixedMul(mobjinfo[MT_OVERTIME_PARTICLE].radius, scale);
|
||||
fixed_t posOffset = max(battleovertime.radius - size, 0);
|
||||
|
||||
// 16 orbs at the normal minimum size of 512
|
||||
{
|
||||
const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise
|
||||
fixed_t scale = mapobjectscale + (battleovertime.radius/2048);
|
||||
fixed_t sprwidth = 32*scale;
|
||||
fixed_t circumference = FixedMul(pi, battleovertime.radius<<1);
|
||||
UINT16 orbs = circumference / sprwidth;
|
||||
angle_t angoff = ANGLE_MAX / orbs;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < orbs; i++)
|
||||
{
|
||||
angle_t ang = (i * angoff) + FixedAngle((leveltime/2)<<FRACBITS);
|
||||
fixed_t x = battleovertime.x + P_ReturnThrustX(NULL, ang, battleovertime.radius - FixedMul(mobjinfo[MT_OVERTIMEORB].radius, scale));
|
||||
fixed_t y = battleovertime.y + P_ReturnThrustY(NULL, ang, battleovertime.radius - FixedMul(mobjinfo[MT_OVERTIMEORB].radius, scale));
|
||||
K_SpawnOvertimeParticles(x, y, scale, MT_OVERTIMEORB, false);
|
||||
}
|
||||
}
|
||||
angle_t ang = (i * angoff) + FixedAngle((leveltime * FRACUNIT) / 4);
|
||||
|
||||
if (battleovertime.enabled < 10*TICRATE)
|
||||
return;
|
||||
fixed_t x = battleovertime.x + P_ReturnThrustX(NULL, ang, posOffset);
|
||||
fixed_t y = battleovertime.y + P_ReturnThrustY(NULL, ang, posOffset);
|
||||
|
||||
/*if (!S_IdPlaying(sfx_s3kd4s)) // global ambience
|
||||
S_StartSoundAtVolume(NULL, sfx_s3kd4s, min(255, ((4096*mapobjectscale) - battleovertime.radius)>>FRACBITS / 2));*/
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
j = 0;
|
||||
while (j < 32) // max attempts
|
||||
{
|
||||
fixed_t x = battleovertime.x + ((P_RandomRange(-64,64) * 128)<<FRACBITS);
|
||||
fixed_t y = battleovertime.y + ((P_RandomRange(-64,64) * 128)<<FRACBITS);
|
||||
fixed_t closestdist = battleovertime.radius + (8*mobjinfo[MT_OVERTIMEFOG].radius);
|
||||
j++;
|
||||
if (P_AproxDistance(x-battleovertime.x, y-battleovertime.y) < closestdist)
|
||||
continue;
|
||||
K_SpawnOvertimeParticles(x, y, 4*mapobjectscale, MT_OVERTIMEFOG, false);
|
||||
break;
|
||||
K_SpawnOvertimeLaser(x, y, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
extern struct battleovertime
|
||||
{
|
||||
UINT16 enabled; ///< Has this been initalized yet?
|
||||
fixed_t radius, minradius; ///< Radius of kill field
|
||||
fixed_t radius; ///< Radius of kill field
|
||||
fixed_t x, y, z; ///< Position to center on
|
||||
} battleovertime;
|
||||
|
||||
|
|
@ -20,6 +20,11 @@ boolean K_IsPlayerWanted(player_t *player);
|
|||
void K_CalculateBattleWanted(void);
|
||||
void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount);
|
||||
void K_CheckBumpers(void);
|
||||
void K_CheckEmeralds(player_t *player);
|
||||
mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT32 emeraldType);
|
||||
void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType);
|
||||
UINT8 K_NumEmeralds(player_t *player);
|
||||
void K_RunPaperItemSpawners(void);
|
||||
void K_RunBattleOvertime(void);
|
||||
void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj);
|
||||
void K_SpawnBattleCapsules(void);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t2->player)
|
||||
{
|
||||
if (t2->player->powers[pw_flashing]
|
||||
if ((t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0)
|
||||
&& !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ || t1->type == MT_JAWZ_DUD))
|
||||
return true;
|
||||
|
||||
|
|
@ -58,11 +58,6 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
|||
|| t2->type == MT_BALLHOG)
|
||||
{
|
||||
// Other Item Damage
|
||||
if (t2->eflags & MFE_VERTICALFLIP)
|
||||
t2->z -= t2->height;
|
||||
else
|
||||
t2->z += t2->height;
|
||||
|
||||
S_StartSound(t2, t2->info->deathsound);
|
||||
P_KillMobj(t2, t1, t1, DMG_NORMAL);
|
||||
|
||||
|
|
@ -94,11 +89,6 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
|||
if (damageitem)
|
||||
{
|
||||
// This Item Damage
|
||||
if (t1->eflags & MFE_VERTICALFLIP)
|
||||
t1->z -= t1->height;
|
||||
else
|
||||
t1->z += t1->height;
|
||||
|
||||
S_StartSound(t1, t1->info->deathsound);
|
||||
P_KillMobj(t1, t2, t2, DMG_NORMAL);
|
||||
|
||||
|
|
@ -133,7 +123,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t2->player)
|
||||
{
|
||||
if (t2->player->powers[pw_flashing])
|
||||
if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0)
|
||||
return true;
|
||||
|
||||
// Banana snipe!
|
||||
|
|
@ -147,7 +137,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Player Damage
|
||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL);
|
||||
}
|
||||
|
||||
|
|
@ -159,11 +148,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
|||
|| t2->type == MT_BALLHOG)
|
||||
{
|
||||
// Other Item Damage
|
||||
if (t2->eflags & MFE_VERTICALFLIP)
|
||||
t2->z -= t2->height;
|
||||
else
|
||||
t2->z += t2->height;
|
||||
|
||||
S_StartSound(t2, t2->info->deathsound);
|
||||
P_KillMobj(t2, t1, t1, DMG_NORMAL);
|
||||
|
||||
|
|
@ -184,11 +168,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
|||
if (damageitem)
|
||||
{
|
||||
// This Item Damage
|
||||
if (t1->eflags & MFE_VERTICALFLIP)
|
||||
t1->z -= t1->height;
|
||||
else
|
||||
t1->z += t1->height;
|
||||
|
||||
S_StartSound(t1, t1->info->deathsound);
|
||||
P_KillMobj(t1, t2, t2, DMG_NORMAL);
|
||||
|
||||
|
|
@ -219,11 +198,15 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
|
|||
if (!P_CanPickupItem(t2->player, 2))
|
||||
return true;
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && t2->player->kartstuff[k_bumper] <= 0)
|
||||
if ((gametyperules & GTR_BUMPERS) && t2->player->bumpers <= 0)
|
||||
{
|
||||
if (t2->player->kartstuff[k_comebackmode] || t2->player->kartstuff[k_comebacktimer])
|
||||
#ifdef OTHERKARMAMODES
|
||||
if (t2->player->kartstuff[k_comebackmode] || t2->player->karmadelay)
|
||||
return true;
|
||||
t2->player->kartstuff[k_comebackmode] = 2;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -253,7 +236,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t1->target && t1->target->player)
|
||||
{
|
||||
if ((gametyperules & GTR_CIRCUIT) || t1->target->player->kartstuff[k_bumper] > 0)
|
||||
if ((gametyperules & GTR_CIRCUIT) || t1->target->player->bumpers > 0)
|
||||
t2->player->kartstuff[k_eggmanblame] = t1->target->player-players;
|
||||
else
|
||||
t2->player->kartstuff[k_eggmanblame] = t2->player-players;
|
||||
|
|
@ -283,15 +266,19 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t2->player)
|
||||
{
|
||||
if (t2->player->powers[pw_flashing])
|
||||
if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0)
|
||||
return true;
|
||||
|
||||
// Bomb punting
|
||||
if ((t1->state >= &states[S_SSMINE1] && t1->state <= &states[S_SSMINE4])
|
||||
|| (t1->state >= &states[S_SSMINE_DEPLOY8] && t1->state <= &states[S_SSMINE_DEPLOY13]))
|
||||
{
|
||||
P_KillMobj(t1, t2, t2, DMG_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
K_PuntMine(t1, t2);
|
||||
}
|
||||
}
|
||||
else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD
|
||||
|| t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD)
|
||||
|
|
@ -300,11 +287,6 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
|
|||
P_KillMobj(t1, t2, t2, DMG_NORMAL);
|
||||
|
||||
// Other Item Damage
|
||||
if (t2->eflags & MFE_VERTICALFLIP)
|
||||
t2->z -= t2->height;
|
||||
else
|
||||
t2->z += t2->height;
|
||||
|
||||
S_StartSound(t2, t2->info->deathsound);
|
||||
P_KillMobj(t2, t1, t1, DMG_NORMAL);
|
||||
|
||||
|
|
@ -326,10 +308,17 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2)
|
|||
{
|
||||
if (t2->player)
|
||||
{
|
||||
if (t2->player->powers[pw_flashing])
|
||||
if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0)
|
||||
return true;
|
||||
|
||||
P_DamageMobj(t2, t1, t1->target, 1, (t1->state == &states[S_MINEEXPLOSION1]) ? DMG_EXPLODE : DMG_NORMAL);
|
||||
if (t1->state == &states[S_MINEEXPLOSION1])
|
||||
{
|
||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_EXPLODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL);
|
||||
}
|
||||
}
|
||||
else if (t2->flags & MF_SHOOTABLE)
|
||||
{
|
||||
|
|
@ -347,14 +336,16 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t2->player)
|
||||
{
|
||||
if (t2->player->powers[pw_flashing])
|
||||
if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0)
|
||||
return true;
|
||||
|
||||
S_StartSound(NULL, sfx_bsnipe); // let all players hear it.
|
||||
|
||||
HU_SetCEchoFlags(0);
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[t2->player-players]));
|
||||
I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[t2->player-players]);
|
||||
|
||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_INSTAKILL);
|
||||
P_KillMobj(t1, t2, t2, DMG_NORMAL);
|
||||
}
|
||||
|
|
|
|||
255
src/k_hud.c
255
src/k_hud.c
|
|
@ -50,6 +50,7 @@ static patch_t *kp_bumperstickerwide;
|
|||
static patch_t *kp_capsulesticker;
|
||||
static patch_t *kp_capsulestickerwide;
|
||||
static patch_t *kp_karmasticker;
|
||||
static patch_t *kp_spheresticker;
|
||||
static patch_t *kp_splitkarmabomb;
|
||||
static patch_t *kp_timeoutsticker;
|
||||
|
||||
|
|
@ -87,6 +88,9 @@ static patch_t *kp_rankbumper;
|
|||
static patch_t *kp_tinybumper[2];
|
||||
static patch_t *kp_ranknobumpers;
|
||||
static patch_t *kp_rankcapsule;
|
||||
static patch_t *kp_rankemerald;
|
||||
static patch_t *kp_rankemeraldflash;
|
||||
static patch_t *kp_rankemeraldback;
|
||||
|
||||
static patch_t *kp_battlewin;
|
||||
static patch_t *kp_battlecool;
|
||||
|
|
@ -174,6 +178,7 @@ void K_LoadKartHUDGraphics(void)
|
|||
kp_capsulesticker = W_CachePatchName("K_STCAPN", PU_HUDGFX);
|
||||
kp_capsulestickerwide = W_CachePatchName("K_STCAPW", PU_HUDGFX);
|
||||
kp_karmasticker = W_CachePatchName("K_STKARM", PU_HUDGFX);
|
||||
kp_spheresticker = W_CachePatchName("K_STBSMT", PU_HUDGFX);
|
||||
kp_splitkarmabomb = W_CachePatchName("K_SPTKRM", PU_HUDGFX);
|
||||
kp_timeoutsticker = W_CachePatchName("K_STTOUT", PU_HUDGFX);
|
||||
|
||||
|
|
@ -348,6 +353,9 @@ void K_LoadKartHUDGraphics(void)
|
|||
kp_tinybumper[1] = W_CachePatchName("K_BLNB", PU_HUDGFX);
|
||||
kp_ranknobumpers = W_CachePatchName("K_NOBLNS", PU_HUDGFX);
|
||||
kp_rankcapsule = W_CachePatchName("K_CAPICO", PU_HUDGFX);
|
||||
kp_rankemerald = W_CachePatchName("K_EMERC", PU_HUDGFX);
|
||||
kp_rankemeraldflash = W_CachePatchName("K_EMERW", PU_HUDGFX);
|
||||
kp_rankemeraldback = W_CachePatchName("K_EMERBK", PU_HUDGFX);
|
||||
|
||||
// Battle graphics
|
||||
kp_battlewin = W_CachePatchName("K_BWIN", PU_HUDGFX);
|
||||
|
|
@ -729,11 +737,12 @@ void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du
|
|||
|
||||
if (options & V_SLIDEIN)
|
||||
{
|
||||
tic_t length = TICRATE/2;
|
||||
const tic_t length = TICRATE/2;
|
||||
const tic_t end = (lt_endtime + length);
|
||||
|
||||
if (leveltime < introtime + length)
|
||||
if (lt_ticker < end)
|
||||
{
|
||||
INT32 offset = screenwidth - (((leveltime - introtime) * screenwidth) / length);
|
||||
INT32 offset = screenwidth - ((lt_exitticker * screenwidth) / length);
|
||||
boolean slidefromright = false;
|
||||
|
||||
if (r_splitscreen > 1)
|
||||
|
|
@ -1513,7 +1522,7 @@ static boolean K_drawKartPositionFaces(void)
|
|||
INT32 i, j, ranklines, strank = -1;
|
||||
boolean completed[MAXPLAYERS];
|
||||
INT32 rankplayer[MAXPLAYERS];
|
||||
INT32 bumperx, numplayersingame = 0;
|
||||
INT32 bumperx, emeraldx, numplayersingame = 0;
|
||||
UINT8 *colormap;
|
||||
|
||||
ranklines = 0;
|
||||
|
|
@ -1594,6 +1603,7 @@ static boolean K_drawKartPositionFaces(void)
|
|||
if (!players[rankplayer[i]].mo) continue;
|
||||
|
||||
bumperx = FACE_X+19;
|
||||
emeraldx = FACE_X+16;
|
||||
|
||||
if (players[rankplayer[i]].mo->color)
|
||||
{
|
||||
|
|
@ -1607,22 +1617,35 @@ static boolean K_drawKartPositionFaces(void)
|
|||
|
||||
if (LUA_HudEnabled(hud_battlebumpers))
|
||||
{
|
||||
if (gametype == GT_BATTLE && players[rankplayer[i]].kartstuff[k_bumper] > 0)
|
||||
if ((gametyperules & GTR_BUMPERS) && players[rankplayer[i]].bumpers > 0)
|
||||
{
|
||||
V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[0], colormap);
|
||||
for (j = 1; j < players[rankplayer[i]].kartstuff[k_bumper]; j++)
|
||||
for (j = 1; j < players[rankplayer[i]].bumpers; j++)
|
||||
{
|
||||
bumperx += 5;
|
||||
V_DrawMappedPatch(bumperx, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[1], colormap);
|
||||
}
|
||||
}
|
||||
} // A new level of stupidity: checking if lua is enabled to close a bracket. :Fascinating:
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 7; j++)
|
||||
{
|
||||
UINT32 emeraldFlag = (1 << j);
|
||||
UINT16 emeraldColor = SKINCOLOR_CHAOSEMERALD1 + j;
|
||||
|
||||
if (players[rankplayer[i]].powers[pw_emeralds] & emeraldFlag)
|
||||
{
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, emeraldColor, GTC_CACHE);
|
||||
V_DrawMappedPatch(emeraldx, Y+7, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_rankemerald, colormap);
|
||||
emeraldx += 7;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == strank)
|
||||
V_DrawScaledPatch(FACE_X, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_facehighlight[(leveltime / 4) % 8]);
|
||||
|
||||
if (gametype == GT_BATTLE && players[rankplayer[i]].kartstuff[k_bumper] <= 0)
|
||||
if (gametype == GT_BATTLE && players[rankplayer[i]].bumpers <= 0)
|
||||
V_DrawScaledPatch(FACE_X-4, Y-3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_ranknobumpers);
|
||||
else
|
||||
{
|
||||
|
|
@ -1639,6 +1662,59 @@ static boolean K_drawKartPositionFaces(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void K_drawKartEmeralds(void)
|
||||
{
|
||||
static const INT32 emeraldOffsets[7][2] = {
|
||||
{34, 0},
|
||||
{25, 8},
|
||||
{43, 8},
|
||||
{16, 0},
|
||||
{52, 0},
|
||||
{7, 8},
|
||||
{61, 8}
|
||||
};
|
||||
|
||||
const INT32 startx = BASEVIDWIDTH - 77 - 8;
|
||||
const INT32 starty = BASEVIDHEIGHT - 29 - 8;
|
||||
|
||||
INT32 i;
|
||||
|
||||
V_DrawScaledPatch(startx, starty, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, kp_rankemeraldback);
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
UINT32 emeraldFlag = (1 << i);
|
||||
UINT16 emeraldColor = SKINCOLOR_CHAOSEMERALD1 + i;
|
||||
|
||||
if (stplyr->powers[pw_emeralds] & emeraldFlag)
|
||||
{
|
||||
boolean whiteFlash = (leveltime & 1);
|
||||
UINT8 *colormap;
|
||||
|
||||
if (i & 1)
|
||||
{
|
||||
whiteFlash = !whiteFlash;
|
||||
}
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, emeraldColor, GTC_CACHE);
|
||||
V_DrawMappedPatch(
|
||||
startx + emeraldOffsets[i][0], starty + emeraldOffsets[i][1],
|
||||
V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT,
|
||||
kp_rankemerald, colormap
|
||||
);
|
||||
|
||||
if (whiteFlash == true)
|
||||
{
|
||||
V_DrawScaledPatch(
|
||||
startx + emeraldOffsets[i][0], starty + emeraldOffsets[i][1],
|
||||
V_HUDTRANSHALF|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT,
|
||||
kp_rankemeraldflash
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// HU_DrawTabRankings -- moved here to take advantage of kart stuff!
|
||||
//
|
||||
|
|
@ -1720,11 +1796,11 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
|
|||
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE);
|
||||
|
||||
V_DrawMappedPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin][FACE_RANK], colormap);
|
||||
/*if (gametype == GT_BATTLE && players[tab[i].num].kartstuff[k_bumper] > 0) -- not enough space for this
|
||||
/*if (gametype == GT_BATTLE && players[tab[i].num].bumpers > 0) -- not enough space for this
|
||||
{
|
||||
INT32 bumperx = x+19;
|
||||
V_DrawMappedPatch(bumperx-2, y-4, 0, kp_tinybumper[0], colormap);
|
||||
for (j = 1; j < players[tab[i].num].kartstuff[k_bumper]; j++)
|
||||
for (j = 1; j < players[tab[i].num].bumpers; j++)
|
||||
{
|
||||
bumperx += 5;
|
||||
V_DrawMappedPatch(bumperx, y-4, 0, kp_tinybumper[1], colormap);
|
||||
|
|
@ -1735,7 +1811,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
|
|||
if (tab[i].num == whiteplayer)
|
||||
V_DrawScaledPatch(x, y-4, 0, kp_facehighlight[(leveltime / 4) % 8]);
|
||||
|
||||
if (gametype == GT_BATTLE && players[tab[i].num].kartstuff[k_bumper] <= 0)
|
||||
if (gametype == GT_BATTLE && players[tab[i].num].bumpers <= 0)
|
||||
V_DrawScaledPatch(x-4, y-7, 0, kp_ranknobumpers);
|
||||
else
|
||||
{
|
||||
|
|
@ -1903,11 +1979,7 @@ static void K_drawKartLapsAndRings(void)
|
|||
{
|
||||
// Laps
|
||||
V_DrawScaledPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_lapsticker);
|
||||
|
||||
if (stplyr->exiting)
|
||||
V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, "FIN");
|
||||
else
|
||||
V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->laps, cv_numlaps.value));
|
||||
V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", min(stplyr->laps, cv_numlaps.value), cv_numlaps.value));
|
||||
|
||||
// Rings
|
||||
if (!uselives)
|
||||
|
|
@ -1951,7 +2023,7 @@ static void K_drawKartSpeedometer(void)
|
|||
UINT8 labeln = 0;
|
||||
UINT8 numbers[3];
|
||||
INT32 splitflags = V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN;
|
||||
UINT8 battleoffset = 0;
|
||||
INT32 battleoffset = 0;
|
||||
|
||||
if (!stplyr->exiting) // Keep the same speed value as when you crossed the finish line!
|
||||
{
|
||||
|
|
@ -1986,7 +2058,7 @@ static void K_drawKartSpeedometer(void)
|
|||
numbers[2] = (convSpeed % 10);
|
||||
|
||||
if (gametype == GT_BATTLE)
|
||||
battleoffset = 8;
|
||||
battleoffset = -4;
|
||||
|
||||
V_DrawScaledPatch(LAPS_X, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_speedometersticker);
|
||||
V_DrawScaledPatch(LAPS_X+7, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[numbers[0]]);
|
||||
|
|
@ -1995,6 +2067,36 @@ static void K_drawKartSpeedometer(void)
|
|||
V_DrawScaledPatch(LAPS_X+29, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_speedometerlabel[labeln]);
|
||||
}
|
||||
|
||||
static void K_drawBlueSphereMeter(void)
|
||||
{
|
||||
const UINT8 maxBars = 4;
|
||||
const UINT8 segColors[] = {73, 64, 52, 54, 55, 35, 34, 33, 202, 180, 181, 182, 164, 165, 166, 153, 152};
|
||||
const UINT8 sphere = max(min(stplyr->spheres, 40), 0);
|
||||
|
||||
UINT8 numBars = min((sphere / 10), maxBars);
|
||||
UINT8 colorIndex = (sphere * sizeof(segColors)) / (40 + 1);
|
||||
INT32 x = LAPS_X + 25;
|
||||
UINT8 i;
|
||||
|
||||
V_DrawScaledPatch(LAPS_X, LAPS_Y - 22, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN, kp_spheresticker);
|
||||
|
||||
for (i = 0; i <= numBars; i++)
|
||||
{
|
||||
UINT8 segLen = 10;
|
||||
|
||||
if (i == numBars)
|
||||
{
|
||||
segLen = (sphere % 10);
|
||||
}
|
||||
|
||||
V_DrawFill(x, LAPS_Y - 16, segLen, 3, segColors[max(colorIndex-1, 0)] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN);
|
||||
V_DrawFill(x, LAPS_Y - 15, segLen, 1, segColors[max(colorIndex-2, 0)] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN);
|
||||
V_DrawFill(x, LAPS_Y - 13, segLen, 3, segColors[colorIndex] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN);
|
||||
|
||||
x += 15;
|
||||
}
|
||||
}
|
||||
|
||||
static void K_drawKartBumpersOrKarma(void)
|
||||
{
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE);
|
||||
|
|
@ -2058,37 +2160,28 @@ static void K_drawKartBumpersOrKarma(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (stplyr->kartstuff[k_bumper] <= 0)
|
||||
INT32 maxbumper = K_StartingBumperCount();
|
||||
V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap);
|
||||
|
||||
if (stplyr->bumpers > 9 || maxbumper > 9)
|
||||
{
|
||||
V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_splitkarmabomb, colormap);
|
||||
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->kartstuff[k_comebackpoints]) % 10]);
|
||||
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[2]);
|
||||
UINT8 ln[2];
|
||||
ln[0] = (stplyr->bumpers / 10 % 10);
|
||||
ln[1] = (stplyr->bumpers % 10);
|
||||
|
||||
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
|
||||
V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
|
||||
|
||||
ln[0] = ((abs(maxbumper) / 10) % 10);
|
||||
ln[1] = (abs(maxbumper) % 10);
|
||||
|
||||
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
|
||||
V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 maxbumper = K_StartingBumperCount();
|
||||
V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap);
|
||||
|
||||
if (stplyr->kartstuff[k_bumper] > 9 || maxbumper > 9)
|
||||
{
|
||||
UINT8 ln[2];
|
||||
ln[0] = ((abs(stplyr->kartstuff[k_bumper]) / 10) % 10);
|
||||
ln[1] = (abs(stplyr->kartstuff[k_bumper]) % 10);
|
||||
|
||||
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
|
||||
V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
|
||||
|
||||
ln[0] = ((abs(maxbumper) / 10) % 10);
|
||||
ln[1] = (abs(maxbumper) % 10);
|
||||
|
||||
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
|
||||
V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->kartstuff[k_bumper]) % 10]);
|
||||
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(maxbumper) % 10]);
|
||||
}
|
||||
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->bumpers) % 10]);
|
||||
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(maxbumper) % 10]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2104,22 +2197,14 @@ static void K_drawKartBumpersOrKarma(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (stplyr->kartstuff[k_bumper] <= 0)
|
||||
{
|
||||
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_karmasticker, colormap);
|
||||
V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/2", stplyr->kartstuff[k_comebackpoints]));
|
||||
}
|
||||
INT32 maxbumper = K_StartingBumperCount();
|
||||
|
||||
if (stplyr->bumpers > 9 && maxbumper > 9)
|
||||
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumperstickerwide, colormap);
|
||||
else
|
||||
{
|
||||
INT32 maxbumper = K_StartingBumperCount();
|
||||
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap);
|
||||
|
||||
if (stplyr->kartstuff[k_bumper] > 9 && maxbumper > 9)
|
||||
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumperstickerwide, colormap);
|
||||
else
|
||||
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap);
|
||||
|
||||
V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->kartstuff[k_bumper], maxbumper));
|
||||
}
|
||||
V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->bumpers, maxbumper));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2130,6 +2215,9 @@ static void K_drawKartWanted(void)
|
|||
UINT8 *colormap = NULL;
|
||||
INT32 basex = 0, basey = 0;
|
||||
|
||||
if (!splitscreen)
|
||||
return;
|
||||
|
||||
if (stplyr != &players[displayplayers[0]])
|
||||
return;
|
||||
|
||||
|
|
@ -2542,6 +2630,18 @@ static void K_drawKartNameTags(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (ntplayer->mo->drawflags & K_GetPlayerDontDrawFlag(stplyr))
|
||||
{
|
||||
// Invisible on this screen
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && (ntplayer->bumpers <= 0))
|
||||
{
|
||||
// Dead in Battle
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!P_CheckSight(stplyr->mo, ntplayer->mo))
|
||||
{
|
||||
// Can't see
|
||||
|
|
@ -2864,7 +2964,7 @@ static void K_drawKartMinimap(void)
|
|||
|
||||
if (i != displayplayers[0] || r_splitscreen)
|
||||
{
|
||||
if (gametype == GT_BATTLE && players[i].kartstuff[k_bumper] <= 0)
|
||||
if (gametype == GT_BATTLE && players[i].bumpers <= 0)
|
||||
continue;
|
||||
|
||||
if (players[i].kartstuff[k_hyudorotimer] > 0)
|
||||
|
|
@ -3300,9 +3400,9 @@ static void K_drawBattleFullscreen(void)
|
|||
else
|
||||
K_drawKartFinish();
|
||||
}
|
||||
else if (stplyr->kartstuff[k_bumper] <= 0 && stplyr->kartstuff[k_comebacktimer] && comeback && !stplyr->spectator && drawcomebacktimer)
|
||||
else if (stplyr->bumpers <= 0 && stplyr->karmadelay && comeback && !stplyr->spectator && drawcomebacktimer)
|
||||
{
|
||||
UINT16 t = stplyr->kartstuff[k_comebacktimer]/(10*TICRATE);
|
||||
UINT16 t = stplyr->karmadelay/(10*TICRATE);
|
||||
INT32 txoff, adjust = (r_splitscreen > 1) ? 4 : 6; // normal string is 8, kart string is 12, half of that for ease
|
||||
INT32 ty = (BASEVIDHEIGHT/2)+66;
|
||||
|
||||
|
|
@ -3332,11 +3432,11 @@ static void K_drawBattleFullscreen(void)
|
|||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battlewait, NULL);
|
||||
|
||||
if (r_splitscreen > 1)
|
||||
V_DrawString(x-txoff, ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE));
|
||||
V_DrawString(x-txoff, ty, 0, va("%d", stplyr->karmadelay/TICRATE));
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, 0, kp_timeoutsticker, NULL);
|
||||
V_DrawKartString(x-txoff, ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE));
|
||||
V_DrawKartString(x-txoff, ty, 0, va("%d", stplyr->karmadelay/TICRATE));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3523,7 +3623,7 @@ static void K_drawInput(void)
|
|||
#define BUTTH 11
|
||||
|
||||
#define drawbutt(xoffs, butt, symb)\
|
||||
if (stplyr->cmd.buttons & butt)\
|
||||
if (!stplyr->exiting && (cmd->buttons & butt))\
|
||||
{\
|
||||
offs = 2;\
|
||||
col = accent1;\
|
||||
|
|
@ -3549,7 +3649,7 @@ static void K_drawInput(void)
|
|||
|
||||
y -= 1;
|
||||
|
||||
if (!cmd->turning) // no turn
|
||||
if (stplyr->exiting || !cmd->turning) // no turn
|
||||
target = 0;
|
||||
else // turning of multiple strengths!
|
||||
{
|
||||
|
|
@ -3757,8 +3857,8 @@ static void K_drawDistributionDebugger(void)
|
|||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
pingame++;
|
||||
if (players[i].kartstuff[k_bumper] > bestbumper)
|
||||
bestbumper = players[i].kartstuff[k_bumper];
|
||||
if (players[i].bumpers > bestbumper)
|
||||
bestbumper = players[i].bumpers;
|
||||
}
|
||||
|
||||
// lovely double loop......
|
||||
|
|
@ -3879,11 +3979,12 @@ void K_drawKartHUD(void)
|
|||
return;
|
||||
}
|
||||
|
||||
battlefullscreen = ((gametype == GT_BATTLE)
|
||||
battlefullscreen = ((gametyperules & (GTR_BUMPERS|GTR_KARMA)) == (GTR_BUMPERS|GTR_KARMA)
|
||||
&& (stplyr->exiting
|
||||
|| (stplyr->kartstuff[k_bumper] <= 0
|
||||
&& stplyr->kartstuff[k_comebacktimer]
|
||||
&& comeback
|
||||
|| (stplyr->bumpers <= 0
|
||||
&& stplyr->karmadelay > 0
|
||||
&& stplyr->eliminated == false
|
||||
&& comeback == true
|
||||
&& stplyr->playerstate == PST_LIVE)));
|
||||
|
||||
if (!demo.title && (!battlefullscreen || r_splitscreen))
|
||||
|
|
@ -3995,6 +4096,11 @@ void K_drawKartHUD(void)
|
|||
if (LUA_HudEnabled(hud_gametypeinfo))
|
||||
K_drawKartBumpersOrKarma();
|
||||
}
|
||||
|
||||
if (gametyperules & GTR_SPHERES)
|
||||
{
|
||||
K_drawBlueSphereMeter();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the countdowns after everything else.
|
||||
|
|
@ -4084,4 +4190,9 @@ void K_drawKartHUD(void)
|
|||
}
|
||||
|
||||
K_DrawWaypointDebugger();
|
||||
|
||||
if (gametype == GT_BATTLE)
|
||||
{
|
||||
K_drawKartEmeralds();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
967
src/k_kart.c
967
src/k_kart.c
File diff suppressed because it is too large
Load diff
14
src/k_kart.h
14
src/k_kart.h
|
|
@ -27,7 +27,7 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum
|
|||
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, boolean bot, boolean rival);
|
||||
INT32 K_GetShieldFromItem(INT32 item);
|
||||
fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against);
|
||||
void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid);
|
||||
boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid);
|
||||
void K_KartPainEnergyFling(player_t *player);
|
||||
void K_FlipFromObject(mobj_t *mo, mobj_t *master);
|
||||
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
|
||||
|
|
@ -39,14 +39,17 @@ void K_KartMoveAnimation(player_t *player);
|
|||
void K_KartPlayerHUDUpdate(player_t *player);
|
||||
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
|
||||
void K_KartPlayerAfterThink(player_t *player);
|
||||
angle_t K_MomentumAngle(mobj_t *mo);
|
||||
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics);
|
||||
void K_DoInstashield(player_t *player);
|
||||
void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted);
|
||||
void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||
void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved);
|
||||
void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type);
|
||||
void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||
void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||
void K_DebtStingPlayer(player_t *player, mobj_t *source);
|
||||
void K_StealBumper(player_t *player, player_t *victim);
|
||||
void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers);
|
||||
void K_DestroyBumpers(player_t *player, UINT8 amount);
|
||||
void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount);
|
||||
void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source);
|
||||
void K_SpawnMineExplosion(mobj_t *source, UINT8 color);
|
||||
UINT16 K_DriftSparkColor(player_t *player, INT32 charge);
|
||||
|
|
@ -70,6 +73,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
|
|||
INT32 K_GetKartDriftSparkValue(player_t *player);
|
||||
void K_SpawnDriftBoostExplosion(player_t *player, int stage);
|
||||
void K_KartUpdatePosition(player_t *player);
|
||||
mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT8 amount);
|
||||
void K_DropItems(player_t *player);
|
||||
void K_DropRocketSneaker(player_t *player);
|
||||
void K_DropKitchenSink(player_t *player);
|
||||
|
|
@ -77,7 +81,7 @@ void K_StripItems(player_t *player);
|
|||
void K_StripOther(player_t *player);
|
||||
void K_MomentumToFacing(player_t *player);
|
||||
boolean K_ApplyOffroad(player_t *player);
|
||||
tic_t K_GetSpindashChargeTime(player_t *player);
|
||||
INT16 K_GetSpindashChargeTime(player_t *player);
|
||||
fixed_t K_GetSpindashChargeSpeed(player_t *player);
|
||||
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);
|
||||
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower);
|
||||
|
|
|
|||
|
|
@ -387,7 +387,8 @@ static int lib_pAproxDistance(lua_State *L)
|
|||
fixed_t dx = luaL_checkfixed(L, 1);
|
||||
fixed_t dy = luaL_checkfixed(L, 2);
|
||||
//HUDSAFE
|
||||
lua_pushfixed(L, P_AproxDistance(dx, dy));
|
||||
LUA_Deprecated(L, "P_AproxDistance", "FixedHypot");
|
||||
lua_pushfixed(L, FixedHypot(dx, dy));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -3431,16 +3432,17 @@ static int lib_kExplodePlayer(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kStealBumper(lua_State *L)
|
||||
static int lib_kTakeBumpersFromPlayer(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
|
||||
UINT8 amount = (UINT8)luaL_optinteger(L, 3, 1);
|
||||
NOHUD
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
if (!victim)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
K_StealBumper(player, victim);
|
||||
K_TakeBumpersFromPlayer(player, victim, amount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3917,7 +3919,7 @@ static luaL_Reg lib[] = {
|
|||
{"K_SpinPlayer",lib_kSpinPlayer},
|
||||
{"K_SquishPlayer",lib_kSquishPlayer},
|
||||
{"K_ExplodePlayer",lib_kExplodePlayer},
|
||||
{"K_StealBumper",lib_kStealBumper},
|
||||
{"K_TakeBumpersFromPlayer",lib_kTakeBumpersFromPlayer},
|
||||
{"K_SpawnKartExplosion",lib_kSpawnKartExplosion},
|
||||
{"K_SpawnMineExplosion",lib_kSpawnMineExplosion},
|
||||
{"K_SpawnBoostTrail",lib_kSpawnBoostTrail},
|
||||
|
|
|
|||
|
|
@ -536,7 +536,6 @@ static luaL_Reg lib[] = {
|
|||
{"CV_StealthSet", lib_cvStealthSet},
|
||||
{"CV_AddValue", lib_cvAddValue},
|
||||
{"CONS_Printf", lib_consPrintf},
|
||||
{"CV_FindVar", lib_cvFindVar},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -109,10 +109,10 @@ void LUAh_PlayerQuit(player_t *plr, kickreason_t reason); // Hook for player qui
|
|||
boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping,
|
||||
UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes
|
||||
|
||||
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to player cmd before the game does anything with them.
|
||||
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to player cmd before the game does anything with them.
|
||||
|
||||
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
||||
void LUAh_VoteThinker(void); // Hook for Y_VoteTicker
|
||||
void LUAh_VoteThinker(void); // Hook for Y_VoteTicker
|
||||
|
||||
#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb
|
||||
#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities
|
||||
|
|
@ -128,4 +128,3 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_
|
|||
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
|
||||
boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing
|
||||
void LUAh_GameQuit(void); // Hook for game quitting
|
||||
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building player's ticcmd struct (Ported from SRB2Kart)
|
||||
|
|
|
|||
|
|
@ -313,8 +313,6 @@ static int PopPivotSubTable(spriteframepivot_t *pivot, lua_State *L, int stk, in
|
|||
pivot[idx].x = (INT32)value;
|
||||
else if (ikey == 2 || (key && fastcmp(key, "y")))
|
||||
pivot[idx].y = (INT32)value;
|
||||
else if (ikey == 3 || (key && fastcmp(key, "rotaxis")))
|
||||
pivot[idx].rotaxis = (UINT8)value;
|
||||
else if (ikey == -1 && (key != NULL))
|
||||
FIELDERROR("pivot key", va("invalid option %s", key));
|
||||
okcool = 1;
|
||||
|
|
@ -579,8 +577,6 @@ static int framepivot_get(lua_State *L)
|
|||
lua_pushinteger(L, framepivot->x);
|
||||
else if (fastcmp("y", field))
|
||||
lua_pushinteger(L, framepivot->y);
|
||||
else if (fastcmp("rotaxis", field))
|
||||
lua_pushinteger(L, (UINT8)framepivot->rotaxis);
|
||||
else
|
||||
return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field));
|
||||
|
||||
|
|
@ -605,8 +601,6 @@ static int framepivot_set(lua_State *L)
|
|||
framepivot->x = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp("y", field))
|
||||
framepivot->y = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp("rotaxis", field))
|
||||
framepivot->rotaxis = luaL_checkinteger(L, 3);
|
||||
else
|
||||
return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field));
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
//#include "fastcmp.h"
|
||||
#include "tables.h"
|
||||
#include "p_local.h"
|
||||
#include "doomstat.h" // for ALL7EMERALDS
|
||||
#include "doomstat.h" // for ALLCHAOSEMERALDS
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
|
@ -162,7 +162,7 @@ static int lib_getsecspecial(lua_State *L)
|
|||
|
||||
static int lib_all7emeralds(lua_State *L)
|
||||
{
|
||||
lua_pushboolean(L, ALL7EMERALDS(luaL_checkinteger(L, 1)));
|
||||
lua_pushboolean(L, ALLCHAOSEMERALDS(luaL_checkinteger(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ enum mobj_e {
|
|||
mobj_whiteshadow,
|
||||
mobj_sprxoff,
|
||||
mobj_spryoff,
|
||||
mobj_sprzoff
|
||||
mobj_sprzoff,
|
||||
mobj_hitlag
|
||||
};
|
||||
|
||||
static const char *const mobj_opt[] = {
|
||||
|
|
@ -170,6 +171,7 @@ static const char *const mobj_opt[] = {
|
|||
"sprxoff",
|
||||
"spryoff",
|
||||
"sprzoff",
|
||||
"hitlag",
|
||||
NULL};
|
||||
|
||||
#define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field])
|
||||
|
|
@ -430,6 +432,9 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_sprzoff:
|
||||
lua_pushfixed(L, mo->sprzoff);
|
||||
break;
|
||||
case mobj_hitlag:
|
||||
lua_pushinteger(L, mo->hitlag);
|
||||
break;
|
||||
default: // extra custom variables in Lua memory
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
|
|
@ -787,6 +792,9 @@ static int mobj_set(lua_State *L)
|
|||
case mobj_sprzoff:
|
||||
mo->sprzoff = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case mobj_hitlag:
|
||||
mo->hitlag = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
default:
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
|
|
|
|||
|
|
@ -26,25 +26,35 @@
|
|||
static int lib_iteratePlayers(lua_State *L)
|
||||
{
|
||||
INT32 i = -1;
|
||||
|
||||
if (lua_gettop(L) < 2)
|
||||
{
|
||||
//return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do <block> end'.");
|
||||
lua_pushcfunction(L, lib_iteratePlayers);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // state is unused.
|
||||
|
||||
if (!lua_isnil(L, 1))
|
||||
i = (INT32)(*((player_t **)luaL_checkudata(L, 1, META_PLAYER)) - players);
|
||||
for (i++; i < MAXPLAYERS; i++)
|
||||
|
||||
i++;
|
||||
|
||||
if (i == serverplayer)
|
||||
{
|
||||
return LUA_PushServerPlayer(L);
|
||||
}
|
||||
|
||||
for (; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
if (!players[i].mo)
|
||||
continue;
|
||||
LUA_PushUserdata(L, &players[i], META_PLAYER);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -57,10 +67,10 @@ static int lib_getPlayer(lua_State *L)
|
|||
lua_Integer i = luaL_checkinteger(L, 2);
|
||||
if (i < 0 || i >= MAXPLAYERS)
|
||||
return luaL_error(L, "players[] index %d out of range (0 - %d)", i, MAXPLAYERS-1);
|
||||
if (i == serverplayer)
|
||||
return LUA_PushServerPlayer(L);
|
||||
if (!playeringame[i])
|
||||
return 0;
|
||||
if (!players[i].mo)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[i], META_PLAYER);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -121,8 +131,6 @@ static int lib_iterateDisplayplayers(lua_State *L)
|
|||
if (i > splitscreen || !playeringame[displayplayers[i]])
|
||||
return 0; // Stop! There are no more players for us to go through. There will never be a player gap in displayplayers.
|
||||
|
||||
if (!players[displayplayers[i]].mo)
|
||||
continue;
|
||||
LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER);
|
||||
lua_pushinteger(L, i); // push this to recall what number we were on for the next function call. I suppose this also means you can retrieve the splitscreen player number with 'for p, n in displayplayers.iterate'!
|
||||
return 2;
|
||||
|
|
@ -143,8 +151,6 @@ static int lib_getDisplayplayers(lua_State *L)
|
|||
return 0;
|
||||
if (!playeringame[displayplayers[i]])
|
||||
return 0;
|
||||
if (!players[displayplayers[i]].mo)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -182,17 +188,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushboolean(L, true);
|
||||
else if (fastcmp(field,"name"))
|
||||
lua_pushstring(L, player_names[plr-players]);
|
||||
else if (fastcmp(field,"realmo"))
|
||||
LUA_PushUserdata(L, plr->mo, META_MOBJ);
|
||||
// Kept for backward-compatibility
|
||||
// Should be fixed to work like "realmo" later
|
||||
else if (fastcmp(field,"mo"))
|
||||
{
|
||||
if (plr->spectator)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
LUA_PushUserdata(L, plr->mo, META_MOBJ);
|
||||
}
|
||||
LUA_PushUserdata(L, plr->mo, META_MOBJ);
|
||||
else if (fastcmp(field,"cmd"))
|
||||
LUA_PushUserdata(L, &plr->cmd, META_TICCMD);
|
||||
else if (fastcmp(field,"playerstate"))
|
||||
|
|
@ -209,6 +206,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushangle(L, plr->drawangle);
|
||||
else if (fastcmp(field,"rings"))
|
||||
lua_pushinteger(L, plr->rings);
|
||||
else if (fastcmp(field,"spheres"))
|
||||
lua_pushinteger(L, plr->spheres);
|
||||
else if (fastcmp(field,"powers"))
|
||||
LUA_PushUserdata(L, plr->powers, META_POWERS);
|
||||
else if (fastcmp(field,"kartstuff"))
|
||||
|
|
@ -219,6 +218,12 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->trickpanel);
|
||||
else if (fastcmp(field,"trickdelay"))
|
||||
lua_pushinteger(L, plr->trickdelay);
|
||||
else if (fastcmp(field,"trickmomx"))
|
||||
lua_pushfixed(L, plr->trickmomx);
|
||||
else if (fastcmp(field,"trickmomy"))
|
||||
lua_pushfixed(L, plr->trickmomy);
|
||||
else if (fastcmp(field,"trickmomz"))
|
||||
lua_pushfixed(L, plr->trickmomz);
|
||||
else if (fastcmp(field,"pflags"))
|
||||
lua_pushinteger(L, plr->pflags);
|
||||
else if (fastcmp(field,"panim"))
|
||||
|
|
@ -451,7 +456,7 @@ static int player_set(lua_State *L)
|
|||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
|
||||
|
||||
if (fastcmp(field,"mo") || fastcmp(field,"realmo")) {
|
||||
if (fastcmp(field,"mo")) {
|
||||
mobj_t *newmo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
plr->mo->player = NULL; // remove player pointer from old mobj
|
||||
(newmo->player = plr)->mo = newmo; // set player pointer for new mobj, and set new mobj as the player's mobj
|
||||
|
|
@ -482,6 +487,8 @@ static int player_set(lua_State *L)
|
|||
plr->drawangle = luaL_checkangle(L, 3);
|
||||
else if (fastcmp(field,"rings"))
|
||||
plr->rings = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"spheres"))
|
||||
plr->spheres = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"powers"))
|
||||
return NOSET;
|
||||
else if (fastcmp(field,"pflags"))
|
||||
|
|
@ -510,6 +517,12 @@ static int player_set(lua_State *L)
|
|||
plr->trickpanel = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"trickdelay"))
|
||||
plr->trickdelay = (tic_t)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"trickmomx"))
|
||||
plr->trickmomx = (fixed_t)luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"trickmomy"))
|
||||
plr->trickmomy = (fixed_t)luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"trickmomz"))
|
||||
plr->trickmomz = (fixed_t)luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"kartspeed"))
|
||||
plr->kartspeed = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"kartweight"))
|
||||
|
|
|
|||
|
|
@ -731,6 +731,14 @@ void LUA_PushUserdata(lua_State *L, void *data, const char *meta)
|
|||
lua_remove(L, -2); // remove LREG_VALID
|
||||
}
|
||||
|
||||
int LUA_PushServerPlayer(lua_State *L)
|
||||
{
|
||||
if ((!multiplayer || !(netgame || demo.playback)) && !playeringame[serverplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// When userdata is freed, use this function to remove it from Lua.
|
||||
void LUA_InvalidateUserdata(void *data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ void LUA_DumpFile(const char *filename);
|
|||
fixed_t LUA_EvalMath(const char *word);
|
||||
void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta);
|
||||
void LUA_PushUserdata(lua_State *L, void *data, const char *meta);
|
||||
int LUA_PushServerPlayer(lua_State *L);
|
||||
void LUA_InvalidateUserdata(void *data);
|
||||
void LUA_InvalidateLevel(void);
|
||||
void LUA_InvalidateMapthings(void);
|
||||
|
|
|
|||
|
|
@ -771,12 +771,13 @@ void Command_Savecheckpoint_f(void)
|
|||
}
|
||||
|
||||
// Like M_GetAllEmeralds() but for console devmode junkies.
|
||||
/*void Command_Getallemeralds_f(void)
|
||||
/*
|
||||
void Command_Getallemeralds_f(void)
|
||||
{
|
||||
REQUIRE_SINGLEPLAYER;
|
||||
REQUIRE_PANDORA;
|
||||
|
||||
emeralds = ((EMERALD7)*2)-1;
|
||||
emeralds = EMERALD_ALL;
|
||||
|
||||
CONS_Printf(M_GetText("You now have all 7 emeralds.\n"));
|
||||
}
|
||||
|
|
@ -788,7 +789,8 @@ void Command_Resetemeralds_f(void)
|
|||
emeralds = 0;
|
||||
|
||||
CONS_Printf(M_GetText("Emeralds reset to zero.\n"));
|
||||
}*/
|
||||
}
|
||||
*/
|
||||
|
||||
void Command_Devmode_f(void)
|
||||
{
|
||||
|
|
|
|||
12
src/m_cond.c
12
src/m_cond.c
|
|
@ -341,6 +341,12 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa
|
|||
UINT8 M_AnySecretUnlocked(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
#ifdef DEVELOP
|
||||
if (1)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAXUNLOCKABLES; ++i)
|
||||
{
|
||||
if (!unlockables[i].nocecho && unlockables[i].unlocked)
|
||||
|
|
@ -376,6 +382,12 @@ UINT8 M_SecretUnlocked(INT32 type)
|
|||
|
||||
UINT8 M_MapLocked(INT32 mapnum)
|
||||
{
|
||||
|
||||
#ifdef DEVELOP
|
||||
if (1)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0)
|
||||
return false;
|
||||
if (!unlockables[mapheaderinfo[mapnum-1]->unlockrequired].unlocked)
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@
|
|||
#define HAVE_SQRTF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "m_fixed.h"
|
||||
#include "tables.h" // ANGLETOFINESHIFT
|
||||
|
||||
#ifdef __USE_C_FIXEDMUL__
|
||||
|
||||
|
|
@ -105,20 +107,34 @@ fixed_t FixedSqrt(fixed_t x)
|
|||
|
||||
fixed_t FixedHypot(fixed_t x, fixed_t y)
|
||||
{
|
||||
fixed_t ax, yx, yx2, yx1;
|
||||
if (abs(y) > abs(x)) // |y|>|x|
|
||||
// Moved the code from R_PointToDist2 to here,
|
||||
// since R_PointToDist2 did the same thing,
|
||||
// except less prone to overflowing.
|
||||
|
||||
angle_t angle;
|
||||
fixed_t dist;
|
||||
|
||||
x = abs(x);
|
||||
y = abs(y);
|
||||
|
||||
if (y > x)
|
||||
{
|
||||
ax = abs(y); // |y| => ax
|
||||
yx = FixedDiv(x, y); // (x/y)
|
||||
fixed_t temp;
|
||||
|
||||
temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
}
|
||||
else // |x|>|y|
|
||||
{
|
||||
ax = abs(x); // |x| => ax
|
||||
yx = FixedDiv(y, x); // (x/y)
|
||||
}
|
||||
yx2 = FixedMul(yx, yx); // (x/y)^2
|
||||
yx1 = FixedSqrt(1 * FRACUNIT + yx2); // (1 + (x/y)^2)^1/2
|
||||
return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2)
|
||||
|
||||
if (!y)
|
||||
return x;
|
||||
|
||||
angle = (tantoangle[FixedDiv(y, x)>>DBITS] + ANGLE_90) >> ANGLETOFINESHIFT;
|
||||
|
||||
// use as cosine
|
||||
dist = FixedDiv(x, FINESINE(angle));
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y)
|
||||
|
|
|
|||
16
src/m_menu.c
16
src/m_menu.c
|
|
@ -6374,7 +6374,7 @@ static void M_GetAllEmeralds(INT32 choice)
|
|||
{
|
||||
(void)choice;
|
||||
|
||||
emeralds = ((EMERALD7)*2)-1;
|
||||
emeralds = EMERALD_ALL;
|
||||
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, true);
|
||||
|
|
@ -8139,11 +8139,11 @@ static void M_ReplayTimeAttack(INT32 choice)
|
|||
break;
|
||||
case 3: // guest
|
||||
// srb2/replay/main/map01-guest.lmp
|
||||
G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
|
||||
G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
|
||||
return;
|
||||
}
|
||||
// srb2/replay/main/map01-sonic-time-best.lmp
|
||||
G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which));
|
||||
G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which));
|
||||
}
|
||||
/*else if (currentMenu == &SP_NightsReplayDef)
|
||||
{
|
||||
|
|
@ -8165,13 +8165,13 @@ static void M_ReplayTimeAttack(INT32 choice)
|
|||
break;
|
||||
}
|
||||
// srb2/replay/main/map01-score-best.lmp
|
||||
G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which));
|
||||
G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which));
|
||||
}*/
|
||||
}
|
||||
|
||||
static void M_EraseGuest(INT32 choice)
|
||||
{
|
||||
const char *rguest = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
|
||||
const char *rguest = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
|
||||
(void)choice;
|
||||
if (FIL_FileExists(rguest))
|
||||
remove(rguest);
|
||||
|
|
@ -8186,10 +8186,10 @@ static void M_EraseGuest(INT32 choice)
|
|||
|
||||
static void M_OverwriteGuest(const char *which)
|
||||
{
|
||||
char *rguest = Z_StrDup(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
|
||||
char *rguest = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
|
||||
UINT8 *buf;
|
||||
size_t len;
|
||||
len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf);
|
||||
len = FIL_ReadFile(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf);
|
||||
if (!len) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -8258,7 +8258,7 @@ static void M_SetGuestReplay(INT32 choice)
|
|||
M_StartMessage(M_GetText("Are you sure you want to\ndelete the guest replay data?\n\n(Press 'Y' to confirm)\n"),M_EraseGuest,MM_YESNO);
|
||||
return;
|
||||
}
|
||||
if (FIL_FileExists(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))))
|
||||
if (FIL_FileExists(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))))
|
||||
M_StartMessage(M_GetText("Are you sure you want to\noverwrite the guest replay data?\n\n(Press 'Y' to confirm)\n"),which,MM_YESNO);
|
||||
else
|
||||
which(0);
|
||||
|
|
|
|||
46
src/m_swap.h
46
src/m_swap.h
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2020 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2018 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
@ -14,30 +14,34 @@
|
|||
#ifndef __M_SWAP__
|
||||
#define __M_SWAP__
|
||||
|
||||
// Endianess handling.
|
||||
// WAD files are stored little endian.
|
||||
#include "endian.h"
|
||||
|
||||
// Little to big endian
|
||||
#define SWAP_SHORT(x) ((INT16)(\
|
||||
(((UINT16)(x) & (UINT16)0x00ffU) << 8) \
|
||||
| \
|
||||
(((UINT16)(x) & (UINT16)0xff00U) >> 8))) \
|
||||
|
||||
#define SWAP_LONG(x) ((INT32)(\
|
||||
(((UINT32)(x) & (UINT32)0x000000ffUL) << 24) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0x0000ff00UL) << 8) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0x00ff0000UL) >> 8) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0xff000000UL) >> 24)))
|
||||
|
||||
// Endianess handling.
|
||||
// WAD files are stored little endian.
|
||||
#ifdef SRB2_BIG_ENDIAN
|
||||
|
||||
#define SHORT(x) ((INT16)(\
|
||||
(((UINT16)(x) & (UINT16)0x00ffU) << 8) \
|
||||
| \
|
||||
(((UINT16)(x) & (UINT16)0xff00U) >> 8))) \
|
||||
|
||||
#define LONG(x) ((INT32)(\
|
||||
(((UINT32)(x) & (UINT32)0x000000ffUL) << 24) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0x0000ff00UL) << 8) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0x00ff0000UL) >> 8) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0xff000000UL) >> 24)))
|
||||
|
||||
#define SHORT SWAP_SHORT
|
||||
#define LONG SWAP_LONG
|
||||
#define MSBF_SHORT(x) ((INT16)(x))
|
||||
#define MSBF_LONG(x) ((INT32)(x))
|
||||
#else
|
||||
#define SHORT(x) ((INT16)(x))
|
||||
#define LONG(x) ((INT32)(x))
|
||||
#define SHORT(x) ((INT16)(x))
|
||||
#define LONG(x) ((INT32)(x))
|
||||
#define MSBF_SHORT SWAP_SHORT
|
||||
#define MSBF_LONG SWAP_LONG
|
||||
#endif
|
||||
|
||||
// Big to little endian
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
|||
};
|
||||
|
||||
consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ms.kartkrew.org/ms/api", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange);
|
||||
consvar_t cv_rendezvousserver = CVAR_INIT ("rendezvousserver", "jart-dev.jameds.org", CV_SAVE, NULL, NULL);
|
||||
consvar_t cv_servername = CVAR_INIT ("servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters);
|
||||
consvar_t cv_server_contact = CVAR_INIT ("server_contact", "", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters);
|
||||
|
||||
|
|
@ -99,6 +100,7 @@ void AddMServCommands(void)
|
|||
CV_RegisterVar(&cv_masterserver_debug);
|
||||
CV_RegisterVar(&cv_masterserver_token);
|
||||
CV_RegisterVar(&cv_advertise);
|
||||
CV_RegisterVar(&cv_rendezvousserver);
|
||||
CV_RegisterVar(&cv_servername);
|
||||
CV_RegisterVar(&cv_server_contact);
|
||||
#ifdef MASTERSERVER
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ extern consvar_t cv_masterserver_update_rate;
|
|||
extern consvar_t cv_masterserver_timeout;
|
||||
extern consvar_t cv_masterserver_debug;
|
||||
extern consvar_t cv_masterserver_token;
|
||||
extern consvar_t cv_rendezvousserver;
|
||||
|
||||
extern consvar_t cv_advertise;
|
||||
|
||||
|
|
|
|||
|
|
@ -4428,7 +4428,7 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing)
|
|||
return true;
|
||||
|
||||
if (thing->player && (thing->player->kartstuff[k_hyudorotimer]
|
||||
|| ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->kartstuff[k_bumper] <= 0 && thing->player->kartstuff[k_comebacktimer])))
|
||||
|| ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->bumpers <= 0 && thing->player->karmadelay)))
|
||||
return true;
|
||||
|
||||
// see if it went over / under
|
||||
|
|
@ -4457,6 +4457,9 @@ void A_GrenadeRing(mobj_t *actor)
|
|||
if (actor->flags2 & MF2_DEBRIS)
|
||||
return;
|
||||
|
||||
if (actor->hitlag > 0)
|
||||
return;
|
||||
|
||||
if (actor->state == &states[S_SSMINE_DEPLOY8])
|
||||
explodedist = (3*explodedist)/2;
|
||||
|
||||
|
|
@ -4493,7 +4496,7 @@ static inline boolean PIT_MineExplode(mobj_t *thing)
|
|||
if (netgame && thing->player && thing->player->spectator)
|
||||
return true;
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->kartstuff[k_bumper] <= 0 && thing == grenade->target)
|
||||
if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->bumpers <= 0 && thing == grenade->target)
|
||||
return true;
|
||||
|
||||
// see if it went over / under
|
||||
|
|
@ -4524,6 +4527,9 @@ void A_SSMineExplode(mobj_t *actor)
|
|||
if (actor->flags2 & MF2_DEBRIS)
|
||||
return;
|
||||
|
||||
if (actor->hitlag > 0)
|
||||
return;
|
||||
|
||||
type = (mobjtype_t)locvar1;
|
||||
|
||||
// Use blockmap to check for nearby shootables
|
||||
|
|
@ -8642,7 +8648,7 @@ void A_ItemPop(mobj_t *actor)
|
|||
if (actor->info->deathsound)
|
||||
S_StartSound(remains, actor->info->deathsound);
|
||||
|
||||
if (!((gametyperules & GTR_BUMPERS) && actor->target->player->kartstuff[k_bumper] <= 0))
|
||||
if (!((gametyperules & GTR_BUMPERS) && actor->target->player->bumpers <= 0))
|
||||
actor->target->player->kartstuff[k_itemroulette] = 1;
|
||||
|
||||
remains->flags2 &= ~MF2_AMBUSH;
|
||||
|
|
@ -8676,7 +8682,7 @@ void A_JawzChase(mobj_t *actor)
|
|||
angle_t angledelta = actor->angle - targetangle;
|
||||
boolean turnclockwise = true;
|
||||
|
||||
if ((gametyperules & GTR_CIRCUIT))
|
||||
if (gametyperules & GTR_CIRCUIT)
|
||||
{
|
||||
const fixed_t distbarrier = FixedMul(512*mapobjectscale, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4)));
|
||||
const fixed_t distaway = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y);
|
||||
|
|
@ -8757,7 +8763,7 @@ void A_JawzChase(mobj_t *actor)
|
|||
|
||||
if (!actor->tracer)
|
||||
{
|
||||
actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy);
|
||||
actor->angle = K_MomentumAngle(actor);
|
||||
}
|
||||
|
||||
P_Thrust(actor, actor->angle, thrustamount);
|
||||
|
|
@ -8887,7 +8893,7 @@ static void SpawnSPBAIZDust(mobj_t *mo, INT32 dir)
|
|||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
sz = mo->ceilingz;
|
||||
|
||||
travelangle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
|
||||
travelangle = K_MomentumAngle(mo);
|
||||
if (leveltime & 1 && abs(mo->z - sz) < FRACUNIT*64)
|
||||
{
|
||||
newx = mo->x + P_ReturnThrustX(mo, travelangle - (dir*ANGLE_45), FixedMul(24*FRACUNIT, mo->scale));
|
||||
|
|
@ -8917,7 +8923,7 @@ static void SpawnSPBSpeedLines(mobj_t *actor)
|
|||
MT_FASTLINE);
|
||||
|
||||
P_SetTarget(&fast->target, actor);
|
||||
fast->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy);
|
||||
fast->angle = K_MomentumAngle(actor);
|
||||
fast->color = SKINCOLOR_RED;
|
||||
fast->colorized = true;
|
||||
K_MatchGenericExtraFlags(fast, actor);
|
||||
|
|
@ -9708,7 +9714,7 @@ void A_ReaperThinker(mobj_t *actor)
|
|||
continue;
|
||||
|
||||
player = &players[i];
|
||||
if (player && player->mo && player->kartstuff[k_bumper] && player->score >= maxscore)
|
||||
if (player && player->mo && player->bumpers && player->score >= maxscore)
|
||||
{
|
||||
targetplayermo = player->mo;
|
||||
maxscore = player->score;
|
||||
|
|
|
|||
|
|
@ -2371,7 +2371,7 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
|
|||
P_SetThingPosition(thing);
|
||||
if (thing->flags & MF_SHOOTABLE)
|
||||
P_DamageMobj(thing, puncher, puncher, 1, DMG_NORMAL);
|
||||
else if (thing->type == MT_RING || thing->type == MT_COIN || thing->type == MT_RANDOMITEM)
|
||||
else if (thing->type == MT_RING || thing->type == MT_RANDOMITEM)
|
||||
{
|
||||
thing->momz = FixedMul(3*FRACUNIT, thing->scale);
|
||||
P_TouchSpecialThing(thing, puncher, false);
|
||||
|
|
|
|||
364
src/p_inter.c
364
src/p_inter.c
|
|
@ -30,7 +30,7 @@
|
|||
#include "f_finale.h"
|
||||
|
||||
// SRB2kart
|
||||
#include "k_kart.h"
|
||||
#include "k_kart.h"
|
||||
#include "k_battle.h"
|
||||
#include "k_pwrlv.h"
|
||||
#include "k_grandprix.h"
|
||||
|
|
@ -108,11 +108,13 @@ void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End)
|
|||
//
|
||||
boolean P_CanPickupItem(player_t *player, UINT8 weapon)
|
||||
{
|
||||
if (player->exiting || mapreset)
|
||||
if (player->exiting || mapreset || player->eliminated)
|
||||
return false;
|
||||
|
||||
/*if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0) // No bumpers in Match
|
||||
return false;*/
|
||||
#ifndef OTHERKARMAMODES
|
||||
if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) // No bumpers in Match
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (weapon)
|
||||
{
|
||||
|
|
@ -182,15 +184,24 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
if (heightcheck)
|
||||
{
|
||||
fixed_t toucher_bottom = toucher->z;
|
||||
fixed_t special_bottom = special->z;
|
||||
|
||||
if (toucher->flags & MF_PICKUPFROMBELOW)
|
||||
toucher_bottom -= toucher->height;
|
||||
|
||||
if (special->flags & MF_PICKUPFROMBELOW)
|
||||
special_bottom -= special->height;
|
||||
|
||||
if (toucher->momz < 0) {
|
||||
if (toucher->z + toucher->momz > special->z + special->height)
|
||||
if (toucher_bottom + toucher->momz > special->z + special->height)
|
||||
return;
|
||||
} else if (toucher->z > special->z + special->height)
|
||||
} else if (toucher_bottom > special->z + special->height)
|
||||
return;
|
||||
if (toucher->momz > 0) {
|
||||
if (toucher->z + toucher->height + toucher->momz < special->z)
|
||||
if (toucher->z + toucher->height + toucher->momz < special_bottom)
|
||||
return;
|
||||
} else if (toucher->z + toucher->height < special->z)
|
||||
} else if (toucher->z + toucher->height < special_bottom)
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -231,11 +242,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
P_SetObjectMomZ(player->mo, 12<<FRACBITS, false);
|
||||
P_InstaThrust(player->mo, player->mo->angle, 20<<FRACBITS);
|
||||
return;
|
||||
case MT_FLOATINGITEM: // SRB2kart
|
||||
case MT_FLOATINGITEM: // SRB2Kart
|
||||
if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold))
|
||||
return;
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0)
|
||||
if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)
|
||||
return;
|
||||
|
||||
player->kartstuff[k_itemtype] = special->threshold;
|
||||
|
|
@ -252,15 +263,19 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
special->flags &= ~MF_SPECIAL;
|
||||
return;
|
||||
case MT_RANDOMITEM: // SRB2kart
|
||||
case MT_RANDOMITEM:
|
||||
if (!P_CanPickupItem(player, 1))
|
||||
return;
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0)
|
||||
if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)
|
||||
{
|
||||
if (player->kartstuff[k_comebackmode] || player->kartstuff[k_comebacktimer])
|
||||
#ifdef OTHERKARMAMODES
|
||||
if (player->kartstuff[k_comebackmode] || player->karmadelay)
|
||||
return;
|
||||
player->kartstuff[k_comebackmode] = 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
special->momx = special->momy = special->momz = 0;
|
||||
|
|
@ -272,7 +287,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
if (player == special->target->player)
|
||||
return;
|
||||
if (player->kartstuff[k_bumper] <= 0)
|
||||
if (player->bumpers <= 0)
|
||||
return;
|
||||
if (special->target->player->exiting || player->exiting)
|
||||
return;
|
||||
|
|
@ -280,53 +295,38 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (P_PlayerInPain(special->target->player))
|
||||
return;
|
||||
|
||||
if (special->target->player->karmadelay > 0)
|
||||
return;
|
||||
|
||||
#ifdef OTHERKARMAMODES
|
||||
if (!special->target->player->kartstuff[k_comebackmode])
|
||||
{
|
||||
if (player->kartstuff[k_growshrinktimer] || player->kartstuff[k_squishedtimer]
|
||||
|| player->kartstuff[k_hyudorotimer] || P_PlayerInPain(player)
|
||||
|| player->kartstuff[k_invincibilitytimer] || player->powers[pw_flashing])
|
||||
return;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
mobj_t *boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE);
|
||||
UINT8 ptadd = (K_IsPlayerWanted(player) ? 2 : 1);
|
||||
mobj_t *boom;
|
||||
|
||||
if (P_DamageMobj(toucher, special, special->target, 1, DMG_KARMA) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE);
|
||||
|
||||
boom->scale = special->target->scale;
|
||||
boom->destscale = special->target->scale;
|
||||
boom->momz = 5*FRACUNIT;
|
||||
|
||||
if (special->target->color)
|
||||
boom->color = special->target->color;
|
||||
else
|
||||
boom->color = SKINCOLOR_KETCHUP;
|
||||
|
||||
S_StartSound(boom, special->info->attacksound);
|
||||
|
||||
if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1
|
||||
{
|
||||
INT32 numingame = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator || players[i].kartstuff[k_bumper] <= 0)
|
||||
continue;
|
||||
numingame++;
|
||||
}
|
||||
|
||||
if (numingame <= 2) // If so, then an extra karma point so they are 100% certain to switch places; it's annoying to end matches with a bomb kill
|
||||
ptadd++;
|
||||
}
|
||||
|
||||
special->target->player->kartstuff[k_comebackpoints] += ptadd;
|
||||
|
||||
if (ptadd > 1)
|
||||
special->target->player->karthud[khud_yougotem] = 2*TICRATE;
|
||||
|
||||
if (special->target->player->kartstuff[k_comebackpoints] >= 2)
|
||||
K_StealBumper(special->target->player, player);
|
||||
|
||||
special->target->player->kartstuff[k_comebacktimer] = comebacktime;
|
||||
|
||||
P_DamageMobj(toucher, special, special->target, 1, DMG_EXPLODE);
|
||||
special->target->player->karthud[khud_yougotem] = 2*TICRATE;
|
||||
special->target->player->karmadelay = comebacktime;
|
||||
}
|
||||
#ifdef OTHERKARMAMODES
|
||||
}
|
||||
else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, 1))
|
||||
{
|
||||
|
|
@ -349,8 +349,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
special->target->player->kartstuff[k_comebackpoints]++;
|
||||
|
||||
if (special->target->player->kartstuff[k_comebackpoints] >= 2)
|
||||
K_StealBumper(special->target->player, player);
|
||||
special->target->player->kartstuff[k_comebacktimer] = comebacktime;
|
||||
K_StealBumper(special->target->player, player, 1);
|
||||
special->target->player->karmadelay = comebacktime;
|
||||
|
||||
player->kartstuff[k_itemroulette] = 1;
|
||||
player->kartstuff[k_roulettetype] = 1;
|
||||
|
|
@ -362,13 +362,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
S_StartSound(poof, special->info->seesound);
|
||||
|
||||
if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1
|
||||
if (player->bumpers == 1) // If you have only one bumper left, and see if it's a 1v1
|
||||
{
|
||||
INT32 numingame = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator || players[i].kartstuff[k_bumper] <= 0)
|
||||
if (!playeringame[i] || players[i].spectator || players[i].bumpers <= 0)
|
||||
continue;
|
||||
numingame++;
|
||||
}
|
||||
|
|
@ -384,9 +384,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
special->target->player->karthud[khud_yougotem] = 2*TICRATE;
|
||||
|
||||
if (special->target->player->kartstuff[k_comebackpoints] >= 2)
|
||||
K_StealBumper(special->target->player, player);
|
||||
K_StealBumper(special->target->player, player, 1);
|
||||
|
||||
special->target->player->kartstuff[k_comebacktimer] = comebacktime;
|
||||
special->target->player->karmadelay = comebacktime;
|
||||
|
||||
K_DropItems(player); //K_StripItems(player);
|
||||
//K_StripOther(player);
|
||||
|
|
@ -404,6 +404,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
special->target->player->kartstuff[k_eggmanblame] = -1;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
case MT_SPB:
|
||||
if ((special->target == toucher || special->target == toucher->target) && (special->threshold > 0))
|
||||
|
|
@ -441,10 +442,25 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
P_DamageMobj(player->mo, special, special->target, 1, DMG_NORMAL);
|
||||
}
|
||||
return;
|
||||
/*case MT_EERIEFOG:
|
||||
case MT_EMERALD:
|
||||
if (!P_CanPickupItem(player, 0))
|
||||
return;
|
||||
|
||||
if (special->threshold > 0)
|
||||
return;
|
||||
|
||||
if (toucher->hitlag > 0)
|
||||
return;
|
||||
|
||||
player->powers[pw_emeralds] |= special->extravalue1;
|
||||
K_CheckEmeralds(player);
|
||||
break;
|
||||
/*
|
||||
case MT_EERIEFOG:
|
||||
special->frame &= ~FF_TRANS80;
|
||||
special->frame |= FF_TRANS90;
|
||||
return;*/
|
||||
return;
|
||||
*/
|
||||
case MT_SMK_MOLE:
|
||||
if (special->target && !P_MobjWasRemoved(special->target))
|
||||
return;
|
||||
|
|
@ -474,7 +490,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
S_StartSound(special, sfx_s1a2);
|
||||
return;
|
||||
case MT_CDUFO: // SRB2kart
|
||||
if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0))
|
||||
if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0))
|
||||
return;
|
||||
|
||||
player->kartstuff[k_itemroulette] = 1;
|
||||
|
|
@ -553,6 +569,22 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
return;
|
||||
|
||||
case MT_BLUESPHERE:
|
||||
if (!(P_CanPickupItem(player, 0)))
|
||||
return;
|
||||
|
||||
// Reached the cap, don't waste 'em!
|
||||
if (player->spheres >= 40)
|
||||
return;
|
||||
|
||||
// Not alive
|
||||
if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0))
|
||||
return;
|
||||
|
||||
special->momx = special->momy = special->momz = 0;
|
||||
player->spheres++;
|
||||
break;
|
||||
|
||||
// Secret emblem thingy
|
||||
case MT_EMBLEM:
|
||||
{
|
||||
|
|
@ -714,7 +746,7 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost)
|
|||
}
|
||||
|
||||
// Easily make it so that overtime works offline
|
||||
//#define TESTOVERTIMEINFREEPLAY
|
||||
#define TESTOVERTIMEINFREEPLAY
|
||||
|
||||
/** Checks if the level timer is over the timelimit and the round should end,
|
||||
* unless you are in overtime. In which case leveltime may stretch out beyond
|
||||
|
|
@ -731,11 +763,10 @@ void P_CheckTimeLimit(void)
|
|||
if (!cv_timelimit.value)
|
||||
return;
|
||||
|
||||
if (!(multiplayer || netgame))
|
||||
return;
|
||||
|
||||
#ifndef TESTOVERTIMEINFREEPLAY
|
||||
if (battlecapsules) // capsules override any time limit settings
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!(gametyperules & GTR_TIMELIMIT))
|
||||
return;
|
||||
|
|
@ -754,58 +785,53 @@ void P_CheckTimeLimit(void)
|
|||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
if (foundone)
|
||||
{
|
||||
#endif
|
||||
// Initiate the kill zone
|
||||
if (!battleovertime.enabled)
|
||||
{
|
||||
INT32 b = 0;
|
||||
thinker_t *th;
|
||||
mobj_t *item = NULL;
|
||||
mobj_t *center = NULL;
|
||||
|
||||
P_RespawnBattleBoxes(); // FORCE THESE TO BE RESPAWNED FOR THIS!!!!!!!
|
||||
|
||||
// Find us an item box to center on.
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
{
|
||||
mobj_t *thismo;
|
||||
|
||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
continue;
|
||||
|
||||
thismo = (mobj_t *)th;
|
||||
|
||||
if (thismo->type != MT_RANDOMITEM)
|
||||
continue;
|
||||
if (thismo->threshold == 69) // Disappears
|
||||
continue;
|
||||
|
||||
b++;
|
||||
|
||||
// Only select items that are on the ground, ignore ones in the air. Ambush flag inverts this rule.
|
||||
if ((!P_IsObjectOnGround(thismo)) != (thismo->flags2 & MF2_AMBUSH))
|
||||
continue;
|
||||
|
||||
if (item == NULL || (b < nummapboxes && P_RandomChance(((nummapboxes-b)*FRACUNIT)/nummapboxes))) // This is to throw off the RNG some
|
||||
item = thismo;
|
||||
if (b >= nummapboxes) // end early if we've found them all already
|
||||
if (thismo->type == MT_OVERTIME_CENTER)
|
||||
{
|
||||
center = thismo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (item == NULL) // no item found, could happen if every item is in the air or has ambush flag, or the map has none
|
||||
if (center == NULL || P_MobjWasRemoved(center))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "No usuable items for Battle overtime!\n");
|
||||
return;
|
||||
CONS_Alert(CONS_WARNING, "No center point for overtime!\n");
|
||||
|
||||
battleovertime.x = 0;
|
||||
battleovertime.y = 0;
|
||||
battleovertime.z = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
battleovertime.x = center->x;
|
||||
battleovertime.y = center->y;
|
||||
battleovertime.z = center->z;
|
||||
}
|
||||
|
||||
item->threshold = 70; // Set constant respawn
|
||||
battleovertime.x = item->x;
|
||||
battleovertime.y = item->y;
|
||||
battleovertime.z = item->z;
|
||||
battleovertime.radius = 4096*mapobjectscale;
|
||||
battleovertime.minradius = (cv_overtime.value == 2 ? 40 : 512) * mapobjectscale;
|
||||
battleovertime.radius = 4096 * mapobjectscale;
|
||||
battleovertime.enabled = 1;
|
||||
|
||||
S_StartSound(NULL, sfx_kc47);
|
||||
}
|
||||
|
||||
return;
|
||||
#ifndef TESTOVERTIMEINFREEPLAY
|
||||
}
|
||||
|
|
@ -1039,12 +1065,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
{
|
||||
mobj_t *mo;
|
||||
|
||||
//if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL))
|
||||
// P_SetTarget(&target->tracer, inflictor);
|
||||
|
||||
if (G_IsSpecialStage(gamemap) && target->player && target->player->nightstime > 6)
|
||||
target->player->nightstime = 6; // Just let P_Ticker take care of the rest.
|
||||
|
||||
if (target->flags & (MF_ENEMY|MF_BOSS))
|
||||
target->momx = target->momy = target->momz = 0;
|
||||
|
||||
|
|
@ -1070,11 +1090,17 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SPECIAL);
|
||||
target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL);
|
||||
target->health = 0; // This makes it easy to check if something's dead elsewhere.
|
||||
target->shadowscale = 0;
|
||||
|
||||
if (target->type != MT_BATTLEBUMPER)
|
||||
{
|
||||
target->shadowscale = 0;
|
||||
}
|
||||
|
||||
if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target))
|
||||
return;
|
||||
|
||||
//K_SetHitLagForObjects(target, inflictor, 15);
|
||||
|
||||
// SRB2kart
|
||||
// I wish I knew a better way to do this
|
||||
if (target->target && target->target->player && target->target->player->mo)
|
||||
|
|
@ -1191,7 +1217,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
}
|
||||
}
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS))
|
||||
if (gametyperules & GTR_BUMPERS)
|
||||
K_CheckBumpers();
|
||||
|
||||
target->player->trickpanel = 0;
|
||||
|
|
@ -1421,6 +1447,35 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
}
|
||||
break;
|
||||
|
||||
case MT_BATTLEBUMPER:
|
||||
{
|
||||
mobj_t *owner = target->target;
|
||||
mobj_t *overlay;
|
||||
|
||||
S_StartSound(target, sfx_kc52);
|
||||
target->flags &= ~MF_NOGRAVITY;
|
||||
|
||||
target->destscale = (3 * target->destscale) / 2;
|
||||
target->scalespeed = FRACUNIT/100;
|
||||
|
||||
if (owner && !P_MobjWasRemoved(owner))
|
||||
{
|
||||
P_Thrust(target, R_PointToAngle2(owner->x, owner->y, target->x, target->y), 4 * target->scale);
|
||||
}
|
||||
|
||||
target->momz += (24 * target->scale) * P_MobjFlip(target);
|
||||
target->fuse = 8;
|
||||
|
||||
overlay = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_OVERLAY);
|
||||
|
||||
P_SetTarget(&target->tracer, overlay);
|
||||
P_SetTarget(&overlay->target, target);
|
||||
|
||||
overlay->color = target->color;
|
||||
P_SetMobjState(overlay, S_INVISIBLE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1646,8 +1701,10 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
return true;
|
||||
}
|
||||
|
||||
static boolean P_KillPlayer(player_t *player, UINT8 type)
|
||||
static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 type)
|
||||
{
|
||||
(void)source;
|
||||
|
||||
if (player->exiting)
|
||||
{
|
||||
player->mo->destscale = 1;
|
||||
|
|
@ -1655,7 +1712,7 @@ static boolean P_KillPlayer(player_t *player, UINT8 type)
|
|||
return false;
|
||||
}
|
||||
|
||||
K_RemoveBumper(player, NULL, NULL);
|
||||
K_DestroyBumpers(player, 1);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -1668,12 +1725,12 @@ static boolean P_KillPlayer(player_t *player, UINT8 type)
|
|||
break;
|
||||
}
|
||||
|
||||
K_DropEmeraldsFromPlayer(player, player->powers[pw_emeralds]);
|
||||
K_SetHitLagForObjects(player->mo, inflictor, 15);
|
||||
|
||||
player->pflags &= ~PF_SLIDING;
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
|
||||
// Get rid of shield
|
||||
player->powers[pw_shield] = SH_NONE;
|
||||
|
||||
player->mo->color = player->skincolor;
|
||||
player->mo->colorized = false;
|
||||
|
||||
|
|
@ -1688,15 +1745,21 @@ static boolean P_KillPlayer(player_t *player, UINT8 type)
|
|||
|
||||
if (type == DMG_TIMEOVER)
|
||||
{
|
||||
mobj_t *boom;
|
||||
if (gametyperules & GTR_CIRCUIT)
|
||||
{
|
||||
mobj_t *boom;
|
||||
|
||||
player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP);
|
||||
player->mo->drawflags |= MFD_DONTDRAW;
|
||||
player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP);
|
||||
player->mo->drawflags |= MFD_DONTDRAW;
|
||||
|
||||
boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM);
|
||||
boom->scale = player->mo->scale;
|
||||
boom->angle = player->mo->angle;
|
||||
P_SetTarget(&boom->target, player->mo);
|
||||
boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM);
|
||||
boom->scale = player->mo->scale;
|
||||
boom->angle = player->mo->angle;
|
||||
P_SetTarget(&boom->target, player->mo);
|
||||
}
|
||||
|
||||
K_DestroyBumpers(player, player->bumpers);
|
||||
player->eliminated = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1753,6 +1816,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
player_t *player;
|
||||
boolean force = false;
|
||||
|
||||
INT32 laglength = 10;
|
||||
|
||||
if (objectplacing)
|
||||
return false;
|
||||
|
||||
|
|
@ -1760,13 +1825,16 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return false;
|
||||
|
||||
// Spectator handling
|
||||
if (multiplayer)
|
||||
{
|
||||
if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator)
|
||||
return false;
|
||||
if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator)
|
||||
return false;
|
||||
|
||||
if (source && source->player && source->player->spectator)
|
||||
return false;
|
||||
if (source && source->player && source->player->spectator)
|
||||
return false;
|
||||
|
||||
if (((damagetype & DMG_TYPEMASK) == DMG_STING)
|
||||
|| ((inflictor && !P_MobjWasRemoved(inflictor)) && inflictor->type == MT_BANANA && inflictor->health <= 1))
|
||||
{
|
||||
laglength = 5;
|
||||
}
|
||||
|
||||
// Everything above here can't be forced.
|
||||
|
|
@ -1830,7 +1898,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
// Instant-Death
|
||||
if ((damagetype & DMG_DEATHMASK))
|
||||
{
|
||||
if (!P_KillPlayer(player, damagetype))
|
||||
if (!P_KillPlayer(player, inflictor, source, damagetype))
|
||||
return false;
|
||||
}
|
||||
else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype))
|
||||
|
|
@ -1845,9 +1913,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
{
|
||||
if (gametyperules & GTR_BUMPERS)
|
||||
{
|
||||
if ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1)
|
||||
if ((player->bumpers <= 0 && player->karmadelay) || (player->kartstuff[k_comebackmode] == 1))
|
||||
{
|
||||
// No bumpers, can't be hurt
|
||||
// No bumpers & in WAIT, can't be hurt
|
||||
K_DoInstashield(player);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1880,20 +1948,60 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
}
|
||||
}
|
||||
|
||||
// We successfully hit 'em!
|
||||
// We successfully damaged them! Give 'em some bumpers!
|
||||
if (type != DMG_STING)
|
||||
{
|
||||
UINT8 takeBumpers = 1;
|
||||
|
||||
if (damagetype & DMG_STEAL)
|
||||
{
|
||||
takeBumpers = 2;
|
||||
|
||||
if (type == DMG_KARMA)
|
||||
{
|
||||
takeBumpers = player->bumpers;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type == DMG_KARMA)
|
||||
{
|
||||
// Take half of their bumpers for karma comeback damage
|
||||
takeBumpers = max(1, player->bumpers / 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (source && source != player->mo && source->player)
|
||||
{
|
||||
K_PlayHitEmSound(source);
|
||||
|
||||
K_BattleAwardHit(source->player, player, inflictor, takeBumpers);
|
||||
K_TakeBumpersFromPlayer(source->player, player, takeBumpers);
|
||||
|
||||
if (type == DMG_KARMA)
|
||||
{
|
||||
// Destroy any remainder bumpers from the player for karma comeback damage
|
||||
K_DestroyBumpers(player, player->bumpers);
|
||||
}
|
||||
|
||||
if (damagetype & DMG_STEAL)
|
||||
{
|
||||
K_StealBumper(source->player, player);
|
||||
// Give them ALL of your emeralds instantly :)
|
||||
source->player->powers[pw_emeralds] |= player->powers[pw_emeralds];
|
||||
player->powers[pw_emeralds] = 0;
|
||||
K_CheckEmeralds(source->player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
K_DestroyBumpers(player, takeBumpers);
|
||||
}
|
||||
|
||||
K_RemoveBumper(player, inflictor, source);
|
||||
if (!(damagetype & DMG_STEAL))
|
||||
{
|
||||
// Drop all of your emeralds
|
||||
K_DropEmeraldsFromPlayer(player, player->powers[pw_emeralds]);
|
||||
}
|
||||
}
|
||||
|
||||
player->kartstuff[k_sneakertimer] = player->kartstuff[k_numsneakers] = 0;
|
||||
|
|
@ -1908,6 +2016,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
ringburst = 0;
|
||||
break;
|
||||
case DMG_EXPLODE:
|
||||
case DMG_KARMA:
|
||||
K_ExplodePlayer(player, inflictor, source);
|
||||
break;
|
||||
case DMG_WIPEOUT:
|
||||
|
|
@ -1924,14 +2033,20 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
}
|
||||
|
||||
if (type != DMG_STING)
|
||||
{
|
||||
player->powers[pw_flashing] = K_GetKartFlashing(player);
|
||||
}
|
||||
|
||||
P_PlayRinglossSound(player->mo);
|
||||
|
||||
if (ringburst > 0)
|
||||
{
|
||||
P_PlayerRingBurst(player, ringburst);
|
||||
}
|
||||
|
||||
K_PlayPainSound(player->mo);
|
||||
|
||||
if ((type == DMG_EXPLODE) || (cv_kartdebughuddrop.value && !modeattacking))
|
||||
if ((type == DMG_EXPLODE || type == DMG_KARMA) || (cv_kartdebughuddrop.value && !modeattacking))
|
||||
{
|
||||
K_DropItems(player);
|
||||
}
|
||||
|
|
@ -1941,6 +2056,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
}
|
||||
|
||||
player->kartstuff[k_instashield] = 15;
|
||||
K_SetHitLagForObjects(target, inflictor, laglength);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1962,12 +2078,16 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
if (source && source->player && target)
|
||||
G_GhostAddHit((INT32) (source->player - players), target);
|
||||
|
||||
K_SetHitLagForObjects(target, inflictor, laglength);
|
||||
|
||||
if (target->health <= 0)
|
||||
{
|
||||
P_KillMobj(target, inflictor, source, damagetype);
|
||||
return true;
|
||||
}
|
||||
|
||||
//K_SetHitLagForObjects(target, inflictor, laglength);
|
||||
|
||||
if (player)
|
||||
P_ResetPlayer(target->player);
|
||||
else
|
||||
|
|
@ -2000,7 +2120,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
fixed_t momxy = 5<<FRACBITS, momz = 12<<FRACBITS; // base horizonal/vertical thrusts
|
||||
|
||||
// Rings shouldn't be in Battle!
|
||||
if (!(gametyperules & GTR_RINGS))
|
||||
if (gametyperules & GTR_SPHERES)
|
||||
return;
|
||||
|
||||
// Better safe than sorry.
|
||||
|
|
|
|||
|
|
@ -467,6 +467,7 @@ typedef struct BasicFF_s
|
|||
#define DMG_EXPLODE 0x02
|
||||
#define DMG_SQUISH 0x03
|
||||
#define DMG_STING 0x04
|
||||
#define DMG_KARMA 0x05 // Karma Bomb explosion -- works like DMG_EXPLODE, but steals half of their bumpers & deletes the rest
|
||||
//// Death types - cannot be combined with damage types
|
||||
#define DMG_INSTAKILL 0x80
|
||||
#define DMG_DEATHPIT 0x81
|
||||
|
|
@ -517,5 +518,6 @@ boolean P_CheckMissileSpawn(mobj_t *th);
|
|||
void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move);
|
||||
void P_ExplodeMissile(mobj_t *mo);
|
||||
void P_CheckGravity(mobj_t *mo, boolean affect);
|
||||
void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope);
|
||||
|
||||
#endif // __P_LOCAL__
|
||||
|
|
|
|||
89
src/p_map.c
89
src/p_map.c
|
|
@ -357,7 +357,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
mobj_t *grease;
|
||||
grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE);
|
||||
P_SetTarget(&grease->target, object);
|
||||
grease->angle = R_PointToAngle2(0, 0, object->momx, object->momy);
|
||||
grease->angle = K_MomentumAngle(object);
|
||||
grease->extravalue1 = i;
|
||||
}
|
||||
}
|
||||
|
|
@ -449,7 +449,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
|
|||
if (object->player)
|
||||
{
|
||||
object->player->trickpanel = 1;
|
||||
object->player->trickdelay = TICRATE/2;
|
||||
object->player->trickdelay = 1;
|
||||
}
|
||||
|
||||
K_DoPogoSpring(object, 32<<FRACBITS, 0);
|
||||
|
|
@ -1222,19 +1222,31 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam)
|
||||
{
|
||||
if (tmthing->scale > thing->scale + (mapobjectscale/8)) // SRB2kart - Handle squishes first!
|
||||
{
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SQUISH);
|
||||
}
|
||||
else if (thing->scale > tmthing->scale + (mapobjectscale/8))
|
||||
{
|
||||
P_DamageMobj(tmthing, thing, thing, 1, DMG_SQUISH);
|
||||
}
|
||||
else if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer]) // SRB2kart - Then invincibility!
|
||||
{
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT);
|
||||
}
|
||||
else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer])
|
||||
{
|
||||
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT);
|
||||
}
|
||||
else if ((tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)
|
||||
&& !(thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)) // SRB2kart - Then flame shield!
|
||||
{
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT);
|
||||
}
|
||||
else if ((thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)
|
||||
&& !(tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD))
|
||||
{
|
||||
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1301,8 +1313,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
}
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS)
|
||||
&& ((thing->player->kartstuff[k_bumper] && !tmthing->player->kartstuff[k_bumper])
|
||||
|| (tmthing->player->kartstuff[k_bumper] && !thing->player->kartstuff[k_bumper])))
|
||||
&& ((thing->player->bumpers && !tmthing->player->bumpers)
|
||||
|| (tmthing->player->bumpers && !thing->player->bumpers)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1329,17 +1341,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (thing->player->trickpanel)
|
||||
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL);
|
||||
}
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS))
|
||||
else if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer]) && !(thing->player->powers[pw_flashing])) // Don't steal bumpers while intangible
|
||||
{
|
||||
if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer]) && !(thing->player->powers[pw_flashing])) // Don't steal bumpers while intangible
|
||||
{
|
||||
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL);
|
||||
}
|
||||
else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer]) && !(tmthing->player->powers[pw_flashing]))
|
||||
{
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL);
|
||||
}
|
||||
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL);
|
||||
}
|
||||
else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer]) && !(tmthing->player->powers[pw_flashing]))
|
||||
{
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL);
|
||||
}
|
||||
|
||||
K_KartBouncing(mo1, mo2, zbounce, false);
|
||||
|
|
@ -1621,6 +1629,23 @@ static boolean PIT_CheckCameraLine(line_t *ld)
|
|||
return true;
|
||||
}
|
||||
|
||||
static boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing)
|
||||
{
|
||||
// missiles can cross uncrossable lines
|
||||
if ((thing->flags & MF_MISSILE))
|
||||
return false;
|
||||
else
|
||||
{
|
||||
return
|
||||
(
|
||||
(ld->flags & ML_IMPASSABLE) || // block objects from moving through this linedef.
|
||||
(thing->player && !thing->player->spectator &&
|
||||
ld->flags & ML_BLOCKPLAYERS) || // SRB2Kart: Only block players, not items
|
||||
((thing->flags & (MF_ENEMY|MF_BOSS)) && ld->special == 81) // case 81: block monsters only
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// PIT_CheckLine
|
||||
// Adjusts tmfloorz and tmceilingz as lines are contacted
|
||||
|
|
@ -1696,14 +1721,8 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
return false;
|
||||
}
|
||||
|
||||
// missiles can cross uncrossable lines
|
||||
if (!(tmthing->flags & MF_MISSILE))
|
||||
{
|
||||
if (ld->flags & ML_IMPASSABLE) // block objects from moving through this linedef.
|
||||
return false;
|
||||
if (tmthing->player && !tmthing->player->spectator && ld->flags & ML_BLOCKPLAYERS)
|
||||
return false; // SRB2Kart: Only block players, not items
|
||||
}
|
||||
if (P_IsLineBlocking(ld, tmthing))
|
||||
return false;
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
P_LineOpening(ld, tmthing);
|
||||
|
|
@ -2272,7 +2291,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
|
|||
{
|
||||
subsector_t *s = R_PointInSubsector(x, y);
|
||||
boolean retval = true;
|
||||
|
||||
|
||||
UINT8 i;
|
||||
|
||||
floatok = false;
|
||||
|
|
@ -2477,6 +2496,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
if (radius < mapobjectscale)
|
||||
radius = mapobjectscale;
|
||||
|
||||
if (thing->hitlag > 0)
|
||||
{
|
||||
// Do not move during hitlag
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
if (thing->flags & MF_NOCLIP) {
|
||||
tryx = x;
|
||||
|
|
@ -2638,9 +2663,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
if (thing->momz <= 0)
|
||||
{
|
||||
thing->standingslope = tmfloorslope;
|
||||
#ifdef HWRENDER
|
||||
thing->modeltilt = thing->standingslope;
|
||||
#endif
|
||||
P_SetPitchRollFromSlope(thing, thing->standingslope);
|
||||
|
||||
if (thing->momz == 0 && thing->player && !startingonground)
|
||||
P_PlayerHitFloor(thing->player, true);
|
||||
|
|
@ -2653,9 +2676,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
if (thing->momz >= 0)
|
||||
{
|
||||
thing->standingslope = tmceilingslope;
|
||||
#ifdef HWRENDER
|
||||
thing->modeltilt = thing->standingslope;
|
||||
#endif
|
||||
P_SetPitchRollFromSlope(thing, thing->standingslope);
|
||||
|
||||
if (thing->momz == 0 && thing->player && !startingonground)
|
||||
P_PlayerHitFloor(thing->player, true);
|
||||
|
|
@ -3167,14 +3188,8 @@ static boolean PTR_LineIsBlocking(line_t *li)
|
|||
if (!li->backsector)
|
||||
return !P_PointOnLineSide(slidemo->x, slidemo->y, li);
|
||||
|
||||
if (!(slidemo->flags & MF_MISSILE))
|
||||
{
|
||||
if (li->flags & ML_IMPASSABLE)
|
||||
return true;
|
||||
|
||||
if (slidemo->player && !slidemo->player->spectator && li->flags & ML_BLOCKPLAYERS)
|
||||
return true;
|
||||
}
|
||||
if (P_IsLineBlocking(li, slidemo))
|
||||
return true;
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
P_LineOpening(li, slidemo);
|
||||
|
|
|
|||
|
|
@ -24,19 +24,6 @@
|
|||
#include "p_slopes.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
//
|
||||
// P_AproxDistance
|
||||
// Gives an estimation of distance (not exact)
|
||||
//
|
||||
fixed_t P_AproxDistance(fixed_t dx, fixed_t dy)
|
||||
{
|
||||
dx = abs(dx);
|
||||
dy = abs(dy);
|
||||
if (dx < dy)
|
||||
return dx + dy - (dx>>1);
|
||||
return dx + dy - (dy>>1);
|
||||
}
|
||||
|
||||
//
|
||||
// P_ClosestPointOnLine
|
||||
// Finds the closest point on a given line to the supplied point
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ typedef boolean (*traverser_t)(intercept_t *in);
|
|||
boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
|
||||
INT32 pflags, traverser_t ptrav);
|
||||
|
||||
FUNCMATH fixed_t P_AproxDistance(fixed_t dx, fixed_t dy);
|
||||
#define P_AproxDistance(dx, dy) FixedHypot(dx, dy)
|
||||
void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result);
|
||||
void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *line, vector3_t *result);
|
||||
INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line);
|
||||
|
|
|
|||
429
src/p_mobj.c
429
src/p_mobj.c
|
|
@ -1130,7 +1130,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
case MT_FLINGCOIN:
|
||||
case MT_FLINGBLUESPHERE:
|
||||
case MT_FLINGNIGHTSCHIP:
|
||||
case MT_FLINGEMERALD:
|
||||
case MT_BOUNCERING:
|
||||
case MT_RAILRING:
|
||||
case MT_INFINITYRING:
|
||||
|
|
@ -1158,18 +1157,19 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
break;
|
||||
case MT_WATERDROP:
|
||||
case MT_CYBRAKDEMON:
|
||||
case MT_BATTLEBUMPER:
|
||||
gravityadd /= 2;
|
||||
break;
|
||||
case MT_BANANA:
|
||||
case MT_EGGMANITEM:
|
||||
case MT_SSMINE:
|
||||
case MT_SINK:
|
||||
case MT_EMERALD:
|
||||
if (mo->extravalue2 > 0)
|
||||
{
|
||||
gravityadd *= mo->extravalue2;
|
||||
/* FALLTHRU */
|
||||
case MT_ORBINAUT:
|
||||
case MT_JAWZ:
|
||||
case MT_JAWZ_DUD:
|
||||
}
|
||||
|
||||
gravityadd = (5*gravityadd)/2;
|
||||
break;
|
||||
case MT_KARMAFIREWORK:
|
||||
|
|
@ -1216,6 +1216,26 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_SetPitchRollFromSlope
|
||||
//
|
||||
void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope)
|
||||
{
|
||||
if (slope)
|
||||
{
|
||||
fixed_t tempz = slope->normal.z;
|
||||
fixed_t tempy = slope->normal.y;
|
||||
fixed_t tempx = slope->normal.x;
|
||||
|
||||
mo->pitch = R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx);
|
||||
mo->roll = R_PointToAngle2(0, 0, tempz, tempy);
|
||||
}
|
||||
else
|
||||
{
|
||||
mo->pitch = mo->roll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define STOPSPEED (FRACUNIT)
|
||||
|
||||
//
|
||||
|
|
@ -1620,8 +1640,10 @@ void P_XYMovement(mobj_t *mo)
|
|||
relation = transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy);
|
||||
else // Give it for free, I guess.
|
||||
relation = ANGLE_90;
|
||||
|
||||
transfermomz = FixedMul(transfermomz,
|
||||
abs(FINESINE((relation >> ANGLETOFINESHIFT) & FINEMASK)));
|
||||
|
||||
if (P_MobjFlip(mo)*(transfermomz - mo->momz) > 2*FRACUNIT) // Do the actual launch!
|
||||
{
|
||||
mo->momz = transfermomz;
|
||||
|
|
@ -1696,7 +1718,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
|
||||
if (oldslope != mo->standingslope) { // First, compare different slopes
|
||||
angle_t oldangle, newangle;
|
||||
angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
|
||||
angle_t moveangle = K_MomentumAngle(mo);
|
||||
|
||||
oldangle = FixedMul((signed)oldslope->zangle, FINECOSINE((moveangle - oldslope->xydirection) >> ANGLETOFINESHIFT));
|
||||
|
||||
|
|
@ -1708,9 +1730,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
// Now compare the Zs of the different quantizations
|
||||
if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later
|
||||
mo->standingslope = oldslope;
|
||||
#ifdef HWRENDER
|
||||
mo->modeltilt = mo->standingslope;
|
||||
#endif
|
||||
P_SetPitchRollFromSlope(mo, mo->standingslope);
|
||||
P_SlopeLaunch(mo);
|
||||
|
||||
//CONS_Printf("launched off of slope - ");
|
||||
|
|
@ -1728,7 +1748,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
P_SlopeLaunch(mo);
|
||||
}
|
||||
} else if (moved && mo->standingslope && predictedz) {
|
||||
angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
|
||||
angle_t moveangle = K_MomentumAngle(mo);
|
||||
angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
|
||||
|
||||
/*CONS_Printf("flat to angle %f - predicted z of %f\n",
|
||||
|
|
@ -2093,6 +2113,7 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_REDFLAG:
|
||||
case MT_BLUEFLAG:
|
||||
// Remove from death pits. DON'T FUCKING DESPAWN IT DAMMIT
|
||||
|
|
@ -2103,19 +2124,23 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
}
|
||||
break;
|
||||
|
||||
case MT_EMERALD:
|
||||
if (P_CheckDeathPitCollide(mo))
|
||||
{
|
||||
P_RemoveMobj(mo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz)
|
||||
{
|
||||
// Stop when hitting the floor
|
||||
mo->momx = mo->momy = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_RING: // Ignore still rings
|
||||
case MT_COIN:
|
||||
case MT_BLUESPHERE:
|
||||
case MT_BOMBSPHERE:
|
||||
case MT_NIGHTSCHIP:
|
||||
case MT_NIGHTSSTAR:
|
||||
case MT_REDTEAMRING:
|
||||
case MT_BLUETEAMRING:
|
||||
case MT_FLINGRING:
|
||||
case MT_FLINGCOIN:
|
||||
case MT_FLINGBLUESPHERE:
|
||||
case MT_FLINGNIGHTSCHIP:
|
||||
case MT_FLINGEMERALD:
|
||||
// Remove flinged stuff from death pits.
|
||||
if (P_CheckDeathPitCollide(mo))
|
||||
{
|
||||
|
|
@ -2228,9 +2253,7 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
|
||||
{
|
||||
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
|
||||
#ifdef HWRENDER
|
||||
mo->modeltilt = mo->standingslope;
|
||||
#endif
|
||||
P_SetPitchRollFromSlope(mo, mo->standingslope);
|
||||
P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
|
||||
}
|
||||
|
||||
|
|
@ -4881,8 +4904,6 @@ static boolean P_ParticleGenSceneryThink(mobj_t *mobj)
|
|||
|
||||
mobj->angle += mobj->movedir;
|
||||
}
|
||||
|
||||
mobj->angle += (angle_t)mobj->movecount;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -5277,7 +5298,117 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
}
|
||||
break;
|
||||
case MT_BATTLEBUMPER:
|
||||
if (mobj->health > 0 && mobj->target && mobj->target->player
|
||||
if (mobj->health <= 0)
|
||||
{
|
||||
mobj->fuse--;
|
||||
|
||||
if (!S_SoundPlaying(mobj, sfx_cdfm71))
|
||||
{
|
||||
S_StartSound(mobj, sfx_cdfm71);
|
||||
}
|
||||
|
||||
if (mobj->fuse <= 0)
|
||||
{
|
||||
statenum_t curState = (mobj->state - states);
|
||||
|
||||
if (curState == S_BATTLEBUMPER1)
|
||||
{
|
||||
P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALA1);
|
||||
|
||||
if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer))
|
||||
{
|
||||
P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLA1);
|
||||
}
|
||||
|
||||
mobj->shadowscale *= 2;
|
||||
mobj->fuse = 12;
|
||||
}
|
||||
else if (curState >= S_BATTLEBUMPER_EXCRYSTALA1 && curState <= S_BATTLEBUMPER_EXCRYSTALA4)
|
||||
{
|
||||
P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALB1);
|
||||
|
||||
if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer))
|
||||
{
|
||||
P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLB1);
|
||||
}
|
||||
|
||||
mobj->shadowscale *= 2;
|
||||
mobj->fuse = 24;
|
||||
break;
|
||||
}
|
||||
else if (curState >= S_BATTLEBUMPER_EXCRYSTALB1 && curState <= S_BATTLEBUMPER_EXCRYSTALB4)
|
||||
{
|
||||
P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALC1);
|
||||
|
||||
if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer))
|
||||
{
|
||||
P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLC1);
|
||||
}
|
||||
|
||||
mobj->shadowscale *= 2;
|
||||
mobj->fuse = 32;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
const INT16 spacing = 64;
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
mobj_t *debris = P_SpawnMobjFromMobj(
|
||||
mobj,
|
||||
P_RandomRange(-spacing, spacing) * FRACUNIT,
|
||||
P_RandomRange(-spacing, spacing) * FRACUNIT,
|
||||
P_RandomRange(-spacing, spacing) * FRACUNIT,
|
||||
MT_BATTLEBUMPER_DEBRIS
|
||||
);
|
||||
|
||||
P_SetScale(debris, (debris->destscale *= 2));
|
||||
debris->color = mobj->color;
|
||||
|
||||
debris->momz = -debris->scale * P_MobjFlip(debris);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
mobj_t *blast = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BATTLEBUMPER_BLAST);
|
||||
|
||||
blast->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy) + ANGLE_45;
|
||||
blast->destscale *= 4;
|
||||
|
||||
if (i & 1)
|
||||
{
|
||||
blast->angle += ANGLE_90;
|
||||
S_StartSound(blast, sfx_cdfm64);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
mobj_t *puff = P_SpawnMobjFromMobj(
|
||||
mobj,
|
||||
P_RandomRange(-spacing, spacing) * FRACUNIT,
|
||||
P_RandomRange(-spacing, spacing) * FRACUNIT,
|
||||
P_RandomRange(-spacing, spacing) * FRACUNIT,
|
||||
MT_SPINDASHDUST
|
||||
);
|
||||
|
||||
P_SetScale(puff, (puff->destscale *= 5));
|
||||
puff->momz = puff->scale * P_MobjFlip(puff);
|
||||
|
||||
P_Thrust(puff, R_PointToAngle2(mobj->x, mobj->y, puff->x, puff->y), puff->scale);
|
||||
}
|
||||
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player
|
||||
&& mobj->target->health > 0 && !mobj->target->player->spectator)
|
||||
{
|
||||
fixed_t rad = 32*mobj->target->scale;
|
||||
|
|
@ -5285,14 +5416,14 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
angle_t ang, diff;
|
||||
|
||||
if (!((mobj->target->player-players) & 1))
|
||||
ang = (FixedAngle(mobj->info->speed) * -1);
|
||||
ang = -FixedAngle(mobj->info->speed);
|
||||
else
|
||||
ang = FixedAngle(mobj->info->speed);
|
||||
|
||||
if (mobj->target->player->kartstuff[k_bumper] <= 1)
|
||||
if (mobj->target->player->bumpers <= 1)
|
||||
diff = 0;
|
||||
else
|
||||
diff = FixedAngle(360*FRACUNIT/mobj->target->player->kartstuff[k_bumper]);
|
||||
diff = FixedAngle(360*FRACUNIT/mobj->target->player->bumpers);
|
||||
|
||||
ang = (ang*leveltime) + (diff * (mobj->threshold-1));
|
||||
|
||||
|
|
@ -5311,51 +5442,66 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
mobj->drawflags = (mobj->target->drawflags & MFD_DONTDRAW);
|
||||
|
||||
if (mobj->target->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
offz += 4*FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
offz -= 4*FRACUNIT;
|
||||
}
|
||||
|
||||
if (mobj->tracer && mobj->tracer->player && mobj->tracer->player->mo
|
||||
if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer) && mobj->tracer->player
|
||||
&& mobj->tracer->health > 0 && !mobj->tracer->player->spectator) // STOLEN
|
||||
mobj->color = mobj->tracer->player->skincolor; // don't do star flashing for stolen bumpers
|
||||
{
|
||||
mobj->color = mobj->tracer->color;
|
||||
}
|
||||
else
|
||||
mobj->color = mobj->target->color; // but do so if it belongs to you :B
|
||||
{
|
||||
mobj->color = mobj->target->color;
|
||||
}
|
||||
|
||||
if (mobj->target->player->kartstuff[k_bumper] < 2)
|
||||
if (mobj->target->player->bumpers < 2)
|
||||
P_SetMobjState(mobj, S_BATTLEBUMPER3);
|
||||
else if (mobj->target->player->kartstuff[k_bumper] < 3)
|
||||
else if (mobj->target->player->bumpers < 3)
|
||||
P_SetMobjState(mobj, S_BATTLEBUMPER2);
|
||||
else
|
||||
P_SetMobjState(mobj, S_BATTLEBUMPER1);
|
||||
|
||||
// Shrink your items if the player shrunk too.
|
||||
mobj->scale = mobj->target->scale;
|
||||
P_SetScale(mobj, mobj->target->scale);
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
{
|
||||
const angle_t fa = ang>>ANGLETOFINESHIFT;
|
||||
const angle_t fa = ang >> ANGLETOFINESHIFT;
|
||||
mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa), rad);
|
||||
mobj->y = mobj->target->y + FixedMul(FINESINE(fa), rad);
|
||||
mobj->z = mobj->target->z + offz;
|
||||
P_SetThingPosition(mobj);
|
||||
}
|
||||
|
||||
// Was this so hard?
|
||||
if (mobj->target->player->kartstuff[k_bumper] <= mobj->threshold)
|
||||
if (mobj->target->player->bumpers <= mobj->threshold)
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
// Do bumper destruction
|
||||
P_KillMobj(mobj, NULL, NULL, DMG_NORMAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((mobj->health > 0
|
||||
&& (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->health <= 0 || mobj->target->player->spectator))
|
||||
|| (mobj->health <= 0 && P_IsObjectOnGround(mobj))
|
||||
|| P_CheckDeathPitCollide(mobj)) // When in death state
|
||||
else
|
||||
{
|
||||
// Sliently remove
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MT_BATTLEBUMPER_DEBRIS:
|
||||
if (mobj->state == states + S_BATTLEBUMPER_EXDEBRIS2)
|
||||
{
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_PLAYERARROW:
|
||||
if (mobj->target && mobj->target->health
|
||||
&& mobj->target->player && !mobj->target->player->spectator
|
||||
|
|
@ -5366,7 +5512,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
mobj->color = mobj->target->color;
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
|
||||
if ((gametype == GT_RACE || mobj->target->player->kartstuff[k_bumper] <= 0)
|
||||
if ((gametype == GT_RACE || mobj->target->player->bumpers <= 0)
|
||||
#if 1 // Set to 0 to test without needing to host
|
||||
|| (P_IsDisplayPlayer(mobj->target->player))
|
||||
#endif
|
||||
|
|
@ -5623,6 +5769,9 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
if (mobj->tics > 0)
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
break;
|
||||
case MT_SPINDASHWIND:
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
break;
|
||||
case MT_VWREF:
|
||||
case MT_VWREB:
|
||||
{
|
||||
|
|
@ -6139,7 +6288,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
frictionsafety = FRACUNIT;
|
||||
}
|
||||
|
||||
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
|
||||
mobj->angle = K_MomentumAngle(mobj);
|
||||
if (mobj->health <= 5)
|
||||
{
|
||||
INT32 i;
|
||||
|
|
@ -6194,6 +6343,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true))
|
||||
K_DoPogoSpring(mobj, 0, 1);
|
||||
|
||||
if (!(gametyperules & GTR_CIRCUIT))
|
||||
mobj->friction = max(0, 3 * mobj->friction / 4);
|
||||
|
||||
break;
|
||||
}
|
||||
case MT_JAWZ_DUD:
|
||||
|
|
@ -6241,7 +6393,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
thrustamount = beatfriction + FixedDiv(mobj->movefactor - currentspeed, frictionsafety);
|
||||
}
|
||||
|
||||
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
|
||||
mobj->angle = K_MomentumAngle(mobj);
|
||||
P_Thrust(mobj, mobj->angle, thrustamount);
|
||||
|
||||
if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true))
|
||||
|
|
@ -6395,6 +6547,37 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
S_StartSound(mobj, sfx_s3k4e);
|
||||
mobj->health--;
|
||||
break;
|
||||
case MT_EMERALD:
|
||||
{
|
||||
if (battleovertime.enabled >= 10*TICRATE)
|
||||
{
|
||||
fixed_t distance = R_PointToDist2(mobj->x, mobj->y, battleovertime.x, battleovertime.y);
|
||||
|
||||
if (distance > battleovertime.radius)
|
||||
{
|
||||
// Delete emeralds to let them reappear
|
||||
P_KillMobj(mobj, NULL, NULL, DMG_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (leveltime % 3 == 0)
|
||||
{
|
||||
mobj_t *sparkle = P_SpawnMobjFromMobj(
|
||||
mobj,
|
||||
P_RandomRange(-48, 48) * FRACUNIT,
|
||||
P_RandomRange(-48, 48) * FRACUNIT,
|
||||
P_RandomRange(0, 64) * FRACUNIT,
|
||||
MT_EMERALDSPARK
|
||||
);
|
||||
|
||||
sparkle->color = mobj->color;
|
||||
sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj);
|
||||
}
|
||||
|
||||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
}
|
||||
break;
|
||||
case MT_DRIFTEXPLODE:
|
||||
if (!mobj->target || !mobj->target->health)
|
||||
{
|
||||
|
|
@ -6404,7 +6587,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
|
||||
//mobj->angle = mobj->target->angle;
|
||||
{
|
||||
angle_t angle = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy);
|
||||
angle_t angle = K_MomentumAngle(mobj->target);
|
||||
fixed_t nudge;
|
||||
|
||||
mobj->angle = angle;
|
||||
|
|
@ -6426,9 +6609,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->target->z);
|
||||
}
|
||||
P_SetScale(mobj, mobj->target->scale);
|
||||
#ifdef HWRENDER
|
||||
mobj->modeltilt = mobj->target->modeltilt;
|
||||
#endif
|
||||
|
||||
mobj->roll = mobj->target->roll;
|
||||
mobj->pitch = mobj->target->pitch;
|
||||
|
||||
if (mobj->fuse <= 16)
|
||||
{
|
||||
|
|
@ -6442,7 +6625,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->color = K_RainbowColor(
|
||||
(SKINCOLOR_PURPLE - SKINCOLOR_PINK) // Smoothly transition into the other state
|
||||
+ ((mobj->fuse - 32) * 2) // Make the color flashing slow down while it runs out
|
||||
);
|
||||
);
|
||||
|
||||
switch (mobj->extravalue1)
|
||||
{
|
||||
|
|
@ -6490,9 +6673,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
|
||||
mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
|
||||
P_SetScale(mobj, mobj->target->scale);
|
||||
#ifdef HWRENDER
|
||||
mobj->modeltilt = mobj->target->modeltilt;
|
||||
#endif
|
||||
|
||||
mobj->roll = mobj->target->roll;
|
||||
mobj->pitch = mobj->target->pitch;
|
||||
|
||||
{
|
||||
player_t *p = NULL;
|
||||
|
|
@ -6672,7 +6855,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
|
||||
{
|
||||
const angle_t off = FixedAngle(40*FRACUNIT);
|
||||
angle_t ang = mobj->target->angle;
|
||||
angle_t ang = K_MomentumAngle(mobj->target);
|
||||
fixed_t z;
|
||||
UINT8 trans = (mobj->target->player->kartstuff[k_tiregrease] * (NUMTRANSMAPS+1)) / greasetics;
|
||||
|
||||
|
|
@ -6685,9 +6868,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
z += mobj->target->height;
|
||||
|
||||
if (mobj->target->momx || mobj->target->momy)
|
||||
ang = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy);
|
||||
|
||||
if (mobj->extravalue1)
|
||||
ang = (signed)(ang - off);
|
||||
else
|
||||
|
|
@ -6982,10 +7162,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
}
|
||||
|
||||
P_TeleportMove(mobj, destx, desty, mobj->target->z);
|
||||
if (mobj->target->momx || mobj->target->momy)
|
||||
mobj->angle = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy);
|
||||
else
|
||||
mobj->angle = mobj->target->angle;
|
||||
mobj->angle = K_MomentumAngle(mobj->target);
|
||||
|
||||
if (underlayst != S_NULL)
|
||||
{
|
||||
|
|
@ -7022,7 +7199,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
statenum_t state = (mobj->state-states);
|
||||
|
||||
if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator
|
||||
|| (gametype == GT_RACE || mobj->target->player->kartstuff[k_bumper]))
|
||||
|| (gametype == GT_RACE || mobj->target->player->bumpers))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return false;
|
||||
|
|
@ -7043,11 +7220,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->radius = 24*mobj->target->scale;
|
||||
mobj->height = 2*mobj->radius;
|
||||
|
||||
if (mobj->target->player->kartstuff[k_comebacktimer] > 0)
|
||||
if (mobj->target->player->karmadelay > 0)
|
||||
{
|
||||
if (state < S_PLAYERBOMB1 || state > S_PLAYERBOMB20)
|
||||
P_SetMobjState(mobj, S_PLAYERBOMB1);
|
||||
if (mobj->target->player->kartstuff[k_comebacktimer] < TICRATE && (leveltime & 1))
|
||||
if (mobj->target->player->karmadelay < TICRATE && (leveltime & 1))
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
else
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
|
|
@ -7862,7 +8039,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->momx = (23*mobj->momx)/24;
|
||||
mobj->momy = (23*mobj->momy)/24;
|
||||
|
||||
mobj->angle = R_PointToAngle2(0,0,mobj->momx,mobj->momy);
|
||||
mobj->angle = K_MomentumAngle(mobj);
|
||||
|
||||
if ((mobj->z - mobj->floorz) < (24*mobj->scale) && (leveltime % 3 != 0))
|
||||
{
|
||||
|
|
@ -8354,6 +8531,7 @@ static boolean P_FuseThink(mobj_t *mobj)
|
|||
if (mobj->threshold == 70)
|
||||
newmobj->threshold = 70;
|
||||
}
|
||||
|
||||
P_RemoveMobj(mobj); // make sure they disappear
|
||||
return false;
|
||||
case MT_SMK_ICEBLOCK:
|
||||
|
|
@ -8416,6 +8594,13 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (mobj->hprev && P_MobjWasRemoved(mobj->hprev))
|
||||
P_SetTarget(&mobj->hprev, NULL);
|
||||
|
||||
// Don't run any thinker code while in hitlag
|
||||
if (mobj->hitlag > 0)
|
||||
{
|
||||
mobj->hitlag--;
|
||||
return;
|
||||
}
|
||||
|
||||
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL);
|
||||
|
||||
tmfloorthing = tmhitthing = NULL;
|
||||
|
|
@ -8433,7 +8618,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (mobj->scale != mobj->destscale)
|
||||
P_MobjScaleThink(mobj); // Slowly scale up/down to reach your destscale.
|
||||
|
||||
if ((mobj->type == MT_GHOST || mobj->type == MT_THOK) && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
|
||||
if (mobj->type == MT_GHOST && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
|
||||
{
|
||||
if (mobj->flags2 & MF2_BOSSNOTRAP) // "fast" flag
|
||||
{
|
||||
|
|
@ -8577,7 +8762,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
|| mobj->type == MT_FLINGCOIN
|
||||
|| mobj->type == MT_FLINGBLUESPHERE
|
||||
|| mobj->type == MT_FLINGNIGHTSCHIP
|
||||
|| mobj->type == MT_FLINGEMERALD
|
||||
|| mobj->type == MT_EMERALD
|
||||
|| mobj->type == MT_BIGTUMBLEWEED
|
||||
|| mobj->type == MT_LITTLETUMBLEWEED
|
||||
|| mobj->type == MT_CANNONBALLDECOR
|
||||
|
|
@ -8909,6 +9094,8 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
|||
break;
|
||||
case MT_RING:
|
||||
case MT_FLOATINGITEM:
|
||||
case MT_BLUESPHERE:
|
||||
case MT_EMERALD:
|
||||
thing->shadowscale = FRACUNIT/2;
|
||||
break;
|
||||
case MT_DRIFTCLIP:
|
||||
|
|
@ -9017,6 +9204,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
|
||||
mobj->colorized = false;
|
||||
|
||||
mobj->hitlag = 0;
|
||||
|
||||
// Set shadowscale here, before spawn hook so that Lua can change it
|
||||
P_DefaultMobjShadowScale(mobj);
|
||||
|
||||
|
|
@ -9198,8 +9387,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
mobj->color = skincolor_blueteam;
|
||||
break;
|
||||
case MT_RING:
|
||||
case MT_COIN:
|
||||
case MT_NIGHTSSTAR:
|
||||
if (nummaprings >= 0)
|
||||
nummaprings++;
|
||||
break;
|
||||
|
|
@ -9557,10 +9744,7 @@ void P_RemoveMobj(mobj_t *mobj)
|
|||
// Rings only, please!
|
||||
if (mobj->spawnpoint &&
|
||||
(mobj->type == MT_RING
|
||||
|| mobj->type == MT_COIN
|
||||
|| mobj->type == MT_NIGHTSSTAR
|
||||
|| mobj->type == MT_REDTEAMRING
|
||||
|| mobj->type == MT_BLUETEAMRING)
|
||||
|| mobj->type == MT_BLUESPHERE)
|
||||
&& !(mobj->flags2 & MF2_DONTRESPAWN))
|
||||
{
|
||||
itemrespawnque[iquehead] = mobj->spawnpoint;
|
||||
|
|
@ -9959,11 +10143,11 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype)
|
|||
void P_RespawnSpecials(void)
|
||||
{
|
||||
UINT8 p, pcount = 0;
|
||||
tic_t time = 30*TICRATE; // Respawn things in empty dedicated servers
|
||||
INT32 time = 30*TICRATE; // Respawn things in empty dedicated servers
|
||||
mapthing_t *mthing = NULL;
|
||||
|
||||
if (!(gametyperules & GTR_CIRCUIT) && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way
|
||||
P_RespawnBattleBoxes();
|
||||
//if (!(gametyperules & GTR_CIRCUIT) && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way
|
||||
//P_RespawnBattleBoxes();
|
||||
|
||||
// wait time depends on player count
|
||||
for (p = 0; p < MAXPLAYERS; p++)
|
||||
|
|
@ -9972,22 +10156,33 @@ void P_RespawnSpecials(void)
|
|||
pcount++;
|
||||
}
|
||||
|
||||
if (pcount == 1) // No respawn when alone
|
||||
return;
|
||||
else if (pcount > 1)
|
||||
if (gametyperules & GTR_SPHERES)
|
||||
{
|
||||
time = (120 - ((pcount-2) * 10))*TICRATE;
|
||||
if (pcount > 2)
|
||||
time -= (5*TICRATE) * (pcount-2);
|
||||
|
||||
// If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this.
|
||||
// 5 lap courses would have more retreaded ground, while 2 lap courses would have less.
|
||||
if ((mapheaderinfo[gamemap-1]->numlaps != 3)
|
||||
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE))
|
||||
time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps);
|
||||
|
||||
if (time < 10*TICRATE)
|
||||
if (time < 5*TICRATE)
|
||||
time = 5*TICRATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pcount == 1) // No respawn when alone
|
||||
return;
|
||||
else if (pcount > 1)
|
||||
{
|
||||
// Ensure it doesn't go into absurdly low values
|
||||
time = 10*TICRATE;
|
||||
time = (120 - ((pcount-2) * 10)) * TICRATE;
|
||||
|
||||
// If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this.
|
||||
// 5 lap courses would have more retreaded ground, while 2 lap courses would have less.
|
||||
if ((mapheaderinfo[gamemap-1]->numlaps != 3)
|
||||
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE))
|
||||
time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps);
|
||||
|
||||
if (time < 10*TICRATE)
|
||||
{
|
||||
// Ensure it doesn't go into absurdly low values
|
||||
time = 10*TICRATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -9996,7 +10191,7 @@ void P_RespawnSpecials(void)
|
|||
return;
|
||||
|
||||
// the first item in the queue is the first to respawn
|
||||
if (leveltime - itemrespawntime[iquetail] < time)
|
||||
if (leveltime - itemrespawntime[iquetail] < (tic_t)time)
|
||||
return;
|
||||
|
||||
mthing = itemrespawnque[iquetail];
|
||||
|
|
@ -10048,7 +10243,7 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
/*
|
||||
if (bonusgame || specialstage)
|
||||
{
|
||||
// Bots should avoid
|
||||
// Bots should avoid
|
||||
p->spectator = true;
|
||||
}
|
||||
*/
|
||||
|
|
@ -10145,30 +10340,35 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
P_SetScale(mobj, mobj->destscale);
|
||||
P_FlashPal(p, 0, 0); // Resets
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS)) // SRB2kart
|
||||
if (gametyperules & GTR_BUMPERS)
|
||||
{
|
||||
mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height + 16*FRACUNIT, MT_PLAYERARROW);
|
||||
P_SetTarget(&overheadarrow->target, mobj);
|
||||
overheadarrow->drawflags |= MFD_DONTDRAW;
|
||||
P_SetScale(overheadarrow, mobj->destscale);
|
||||
|
||||
if (p->spectator && pcount > 1) // HEY! No being cheap...
|
||||
p->kartstuff[k_bumper] = 0;
|
||||
else if (p->kartstuff[k_bumper] > 0 || leveltime < 1
|
||||
|| (p->jointime <= 1 && pcount <= 1))
|
||||
if (p->spectator)
|
||||
{
|
||||
if (leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) // Start of the map?
|
||||
p->kartstuff[k_bumper] = K_StartingBumperCount(); // Reset those bumpers!
|
||||
|
||||
if (p->kartstuff[k_bumper])
|
||||
// HEY! No being cheap...
|
||||
p->bumpers = 0;
|
||||
}
|
||||
else if ((p->bumpers > 0) || (leveltime < starttime) || (pcount <= 1))
|
||||
{
|
||||
if ((leveltime < starttime) || (pcount <= 1)) // Start of the map?
|
||||
{
|
||||
angle_t diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_bumper]);
|
||||
// Reset those bumpers!
|
||||
p->bumpers = K_StartingBumperCount();
|
||||
}
|
||||
|
||||
if (p->bumpers)
|
||||
{
|
||||
angle_t diff = FixedAngle(360*FRACUNIT/p->bumpers);
|
||||
angle_t newangle = mobj->angle;
|
||||
fixed_t newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT);
|
||||
fixed_t newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT);
|
||||
mobj_t *mo;
|
||||
|
||||
for (i = 0; i < p->kartstuff[k_bumper]; i++)
|
||||
for (i = 0; i < p->bumpers; i++)
|
||||
{
|
||||
mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBUMPER);
|
||||
mo->threshold = i;
|
||||
|
|
@ -10182,7 +10382,7 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (p->kartstuff[k_bumper] <= 0)
|
||||
else if (p->bumpers <= 0)
|
||||
{
|
||||
mobj_t *karmahitbox = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_KARMAHITBOX); // Player hitbox is too small!!
|
||||
P_SetTarget(&karmahitbox->target, mobj);
|
||||
|
|
@ -10403,6 +10603,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
|
|||
case MT_SPIKEBALL:
|
||||
case MT_EMBLEM:
|
||||
case MT_RING:
|
||||
case MT_BLUESPHERE:
|
||||
offset += mthing->options & MTF_AMBUSH ? 24*mapobjectscale : 0;
|
||||
break;
|
||||
|
||||
|
|
@ -10509,8 +10710,14 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
|
|||
|
||||
static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i)
|
||||
{
|
||||
// Don't need this for Kart YET!
|
||||
(void)mthing;
|
||||
|
||||
if ((gametyperules & GTR_SPHERES) && (i == MT_RING))
|
||||
return MT_BLUESPHERE;
|
||||
|
||||
if ((gametyperules & GTR_PAPERITEMS) && (i == MT_RANDOMITEM))
|
||||
return MT_PAPERITEMSPOT;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
@ -11594,8 +11801,11 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
|
||||
static void P_SetAmbush(mobj_t *mobj)
|
||||
{
|
||||
if (mobj->type == MT_YELLOWDIAG || mobj->type == MT_REDDIAG || mobj->type == MT_BLUEDIAG)
|
||||
mobj->angle += ANGLE_22h;
|
||||
if (mobj->flags & MF_SPRING)
|
||||
{
|
||||
// gravity toggle
|
||||
mobj->flags ^= MF_NOGRAVITY;
|
||||
}
|
||||
|
||||
if (mobj->flags & MF_NIGHTSITEM)
|
||||
{
|
||||
|
|
@ -11624,9 +11834,6 @@ static void P_SetAmbush(mobj_t *mobj)
|
|||
|
||||
static void P_SetObjectSpecial(mobj_t *mobj)
|
||||
{
|
||||
if (mobj->type == MT_YELLOWDIAG || mobj->type == MT_REDDIAG || mobj->type == MT_BLUEDIAG)
|
||||
mobj->flags |= MF_NOGRAVITY;
|
||||
|
||||
if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0)
|
||||
{
|
||||
// flag for strong/weak random boxes
|
||||
|
|
|
|||
|
|
@ -157,6 +157,8 @@ typedef enum
|
|||
MF_RUNSPAWNFUNC = 1<<27,
|
||||
// Don't remap in Encore mode. (Not a drawflag so that it's settable by mobjinfo.)
|
||||
MF_DONTENCOREMAP = 1<<28,
|
||||
// Hitbox extends just as far below as above.
|
||||
MF_PICKUPFROMBELOW = 1<<29,
|
||||
// free: to and including 1<<31
|
||||
} mobjflag_t;
|
||||
|
||||
|
|
@ -408,9 +410,6 @@ typedef struct mobj_s
|
|||
INT32 cvmem;
|
||||
|
||||
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
|
||||
#ifdef HWRENDER
|
||||
struct pslope_s *modeltilt; // Slope used for model tilting. Also is not synched, this is totally visual.
|
||||
#endif
|
||||
|
||||
boolean colorized; // Whether the mobj uses the rainbow colormap
|
||||
boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left
|
||||
|
|
@ -420,6 +419,8 @@ typedef struct mobj_s
|
|||
|
||||
fixed_t sprxoff, spryoff, sprzoff; // Sprite offsets in real space, does NOT affect position or collision
|
||||
|
||||
INT32 hitlag; // Sal-style hit lag, straight from Captain Fetch's jowls
|
||||
|
||||
// WARNING: New fields must be added separately to savegame and Lua.
|
||||
} mobj_t;
|
||||
|
||||
|
|
@ -530,7 +531,6 @@ boolean P_ZMovement(mobj_t *mo);
|
|||
void P_RingZMovement(mobj_t *mo);
|
||||
boolean P_SceneryZMovement(mobj_t *mo);
|
||||
void P_PlayerZMovement(mobj_t *mo);
|
||||
void P_EmeraldManager(void);
|
||||
|
||||
extern INT32 modulothing;
|
||||
|
||||
|
|
|
|||
|
|
@ -876,6 +876,10 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy)
|
|||
|
||||
for (; mo; mo = mo->bnext)
|
||||
{
|
||||
// lastlook is used by the SPB to determine targets, do not let it affect it
|
||||
if (mo->type == MT_SPB)
|
||||
continue;
|
||||
|
||||
if (mo->lastlook == pomovecount)
|
||||
continue;
|
||||
|
||||
|
|
@ -1106,6 +1110,10 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta,
|
|||
|
||||
for (; mo; mo = mo->bnext)
|
||||
{
|
||||
// lastlook is used by the SPB to determine targets, do not let it affect it
|
||||
if (mo->type == MT_SPB)
|
||||
continue;
|
||||
|
||||
if (mo->lastlook == pomovecount)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEANGLE(save_p, players[i].awayviewaiming);
|
||||
WRITEINT32(save_p, players[i].awayviewtics);
|
||||
WRITEINT16(save_p, players[i].rings);
|
||||
WRITEINT16(save_p, players[i].spheres);
|
||||
|
||||
for (j = 0; j < NUMPOWERS; j++)
|
||||
WRITEUINT16(save_p, players[i].powers[j]);
|
||||
|
|
@ -234,7 +235,7 @@ static void P_NetArchivePlayers(void)
|
|||
|
||||
if (flags & FOLLOWITEM)
|
||||
WRITEUINT32(save_p, players[i].followmobj->mobjnum);
|
||||
|
||||
|
||||
WRITEUINT32(save_p, (UINT32)players[i].followitem);
|
||||
|
||||
WRITEUINT32(save_p, players[i].charflags);
|
||||
|
|
@ -256,7 +257,14 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint));
|
||||
WRITEUINT32(save_p, players[i].airtime);
|
||||
WRITEUINT8(save_p, players[i].trickpanel);
|
||||
WRITEUINT32(save_p, players[i].trickdelay);
|
||||
WRITEUINT8(save_p, players[i].trickdelay);
|
||||
WRITEUINT32(save_p, players[i].trickmomx);
|
||||
WRITEUINT32(save_p, players[i].trickmomy);
|
||||
WRITEUINT32(save_p, players[i].trickmomz);
|
||||
|
||||
WRITEUINT8(save_p, players[i].bumpers);
|
||||
WRITEINT16(save_p, players[i].karmadelay);
|
||||
WRITEUINT8(save_p, players[i].eliminated);
|
||||
|
||||
// respawnvars_t
|
||||
WRITEUINT8(save_p, players[i].respawn.state);
|
||||
|
|
@ -306,6 +314,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].awayviewaiming = READANGLE(save_p);
|
||||
players[i].awayviewtics = READINT32(save_p);
|
||||
players[i].rings = READINT16(save_p);
|
||||
players[i].spheres = READINT16(save_p);
|
||||
|
||||
for (j = 0; j < NUMPOWERS; j++)
|
||||
players[i].powers[j] = READUINT16(save_p);
|
||||
|
|
@ -420,7 +429,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
|
||||
if (flags & FOLLOWITEM)
|
||||
players[i].followmobj = (mobj_t *)(size_t)READUINT32(save_p);
|
||||
|
||||
|
||||
players[i].followitem = (mobjtype_t)READUINT32(save_p);
|
||||
|
||||
//SetPlayerSkinByNum(i, players[i].skin);
|
||||
|
|
@ -443,7 +452,14 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p);
|
||||
players[i].airtime = READUINT32(save_p);
|
||||
players[i].trickpanel = READUINT8(save_p);
|
||||
players[i].trickdelay = READUINT32(save_p);
|
||||
players[i].trickdelay = READUINT8(save_p);
|
||||
players[i].trickmomx = READUINT32(save_p);
|
||||
players[i].trickmomy = READUINT32(save_p);
|
||||
players[i].trickmomz = READUINT32(save_p);
|
||||
|
||||
players[i].bumpers = READUINT8(save_p);
|
||||
players[i].karmadelay = READINT16(save_p);
|
||||
players[i].eliminated = (boolean)READUINT8(save_p);
|
||||
|
||||
// respawnvars_t
|
||||
players[i].respawn.state = READUINT8(save_p);
|
||||
|
|
@ -1373,9 +1389,10 @@ typedef enum
|
|||
MD2_ROLLANGLE = 1<<14,
|
||||
MD2_SHADOWSCALE = 1<<15,
|
||||
MD2_DRAWFLAGS = 1<<16,
|
||||
MD2_WAYPOINTCAP = 1<<17,
|
||||
MD2_KITEMCAP = 1<<18,
|
||||
MD2_ITNEXT = 1<<19,
|
||||
MD2_HITLAG = 1<<17,
|
||||
MD2_WAYPOINTCAP = 1<<18,
|
||||
MD2_KITEMCAP = 1<<19,
|
||||
MD2_ITNEXT = 1<<20,
|
||||
} mobj_diff2_t;
|
||||
|
||||
typedef enum
|
||||
|
|
@ -1590,6 +1607,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
diff2 |= MD2_SHADOWSCALE;
|
||||
if (mobj->drawflags)
|
||||
diff2 |= MD2_DRAWFLAGS;
|
||||
if (mobj->hitlag)
|
||||
diff2 |= MD2_HITLAG;
|
||||
if (mobj == waypointcap)
|
||||
diff2 |= MD2_WAYPOINTCAP;
|
||||
if (mobj == kitemcap)
|
||||
|
|
@ -1754,6 +1773,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
|
||||
WRITEUINT16(save_p, df);
|
||||
}
|
||||
if (diff2 & MD2_HITLAG)
|
||||
WRITEINT32(save_p, mobj->hitlag);
|
||||
|
||||
WRITEUINT32(save_p, mobj->mobjnum);
|
||||
}
|
||||
|
|
@ -2799,12 +2820,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
if (diff2 & MD2_ITNEXT)
|
||||
mobj->itnext = (mobj_t *)(size_t)READUINT32(save_p);
|
||||
if (diff2 & MD2_SLOPE)
|
||||
{
|
||||
mobj->standingslope = P_SlopeById(READUINT16(save_p));
|
||||
#ifdef HWRENDER
|
||||
mobj->modeltilt = mobj->standingslope;
|
||||
#endif
|
||||
}
|
||||
if (diff2 & MD2_COLORIZED)
|
||||
mobj->colorized = READUINT8(save_p);
|
||||
if (diff2 & MD2_MIRRORED)
|
||||
|
|
@ -2818,6 +2834,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
}
|
||||
if (diff2 & MD2_DRAWFLAGS)
|
||||
mobj->drawflags = READUINT16(save_p);
|
||||
if (diff2 & MD2_HITLAG)
|
||||
mobj->hitlag = READINT32(save_p);
|
||||
|
||||
if (diff & MD_REDFLAG)
|
||||
{
|
||||
|
|
@ -4121,7 +4139,6 @@ static void P_NetArchiveMisc(void)
|
|||
// battleovertime_t
|
||||
WRITEUINT16(save_p, battleovertime.enabled);
|
||||
WRITEFIXED(save_p, battleovertime.radius);
|
||||
WRITEFIXED(save_p, battleovertime.minradius);
|
||||
WRITEFIXED(save_p, battleovertime.x);
|
||||
WRITEFIXED(save_p, battleovertime.y);
|
||||
WRITEFIXED(save_p, battleovertime.z);
|
||||
|
|
@ -4255,7 +4272,6 @@ static inline boolean P_NetUnArchiveMisc(void)
|
|||
// battleovertime_t
|
||||
battleovertime.enabled = READUINT16(save_p);
|
||||
battleovertime.radius = READFIXED(save_p);
|
||||
battleovertime.minradius = READFIXED(save_p);
|
||||
battleovertime.x = READFIXED(save_p);
|
||||
battleovertime.y = READFIXED(save_p);
|
||||
battleovertime.z = READFIXED(save_p);
|
||||
|
|
|
|||
|
|
@ -3924,40 +3924,40 @@ boolean P_LoadLevel(boolean fromnetsave)
|
|||
}
|
||||
*/
|
||||
|
||||
// Make sure all sounds are stopped before Z_FreeTags.
|
||||
S_StopSounds();
|
||||
S_ClearSfx();
|
||||
|
||||
// Fade out music here. Deduct 2 tics so the fade volume actually reaches 0.
|
||||
// But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug.
|
||||
if (!titlemapinaction)
|
||||
S_FadeMusic(0, FixedMul(
|
||||
FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE));
|
||||
|
||||
// Reset the palette now all fades have been done
|
||||
if (rendermode != render_none)
|
||||
V_SetPaletteLump(GetPalette()); // Set the level palette
|
||||
|
||||
if (!titlemapinaction)
|
||||
{
|
||||
if (ranspecialwipe == 2)
|
||||
{
|
||||
pausedelay = -3; // preticker plus one
|
||||
S_StartSound(NULL, sfx_s3k73);
|
||||
}
|
||||
|
||||
// As oddly named as this is, this handles music only.
|
||||
// We should be fine starting it here.
|
||||
// Don't do this during titlemap, because the menu code handles music by itself.
|
||||
S_Start();
|
||||
}
|
||||
|
||||
levelfadecol = (encoremode ? 0 : 31);
|
||||
|
||||
// Let's fade to white here
|
||||
// But only if we didn't do the encore startup wipe
|
||||
if (!demo.rewinding)
|
||||
{
|
||||
// Make sure all sounds are stopped before Z_FreeTags.
|
||||
S_StopSounds();
|
||||
S_ClearSfx();
|
||||
|
||||
// Fade out music here. Deduct 2 tics so the fade volume actually reaches 0.
|
||||
// But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug.
|
||||
if (!titlemapinaction)
|
||||
S_FadeMusic(0, FixedMul(
|
||||
FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE));
|
||||
|
||||
// Reset the palette now all fades have been done
|
||||
if (rendermode != render_none)
|
||||
V_SetPaletteLump(GetPalette()); // Set the level palette
|
||||
|
||||
if (!titlemapinaction)
|
||||
{
|
||||
if (ranspecialwipe == 2)
|
||||
{
|
||||
pausedelay = -3; // preticker plus one
|
||||
S_StartSound(NULL, sfx_s3k73);
|
||||
}
|
||||
|
||||
// As oddly named as this is, this handles music only.
|
||||
// We should be fine starting it here.
|
||||
// Don't do this during titlemap, because the menu code handles music by itself.
|
||||
S_Start();
|
||||
}
|
||||
|
||||
levelfadecol = (encoremode ? 0 : 31);
|
||||
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
|
|
|
|||
|
|
@ -897,9 +897,8 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
|||
if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope
|
||||
{
|
||||
thing->standingslope = slope;
|
||||
#ifdef HWRENDER
|
||||
thing->modeltilt = thing->standingslope;
|
||||
#endif
|
||||
P_SetPitchRollFromSlope(thing, slope);
|
||||
|
||||
if (!thing->player || !(thing->player->pflags & PF_BOUNCING))
|
||||
thing->momz = -P_MobjFlip(thing);
|
||||
}
|
||||
|
|
@ -916,9 +915,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
|||
thing->momx = mom.x;
|
||||
thing->momy = mom.y;
|
||||
thing->standingslope = slope;
|
||||
#ifdef HWRENDER
|
||||
thing->modeltilt = thing->standingslope;
|
||||
#endif
|
||||
P_SetPitchRollFromSlope(thing, slope);
|
||||
if (!thing->player || !(thing->player->pflags & PF_BOUNCING))
|
||||
thing->momz = -P_MobjFlip(thing);
|
||||
}
|
||||
|
|
|
|||
23
src/p_spec.c
23
src/p_spec.c
|
|
@ -1612,7 +1612,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
|||
{
|
||||
if (GETSECSPECIAL(caller->special, 2) == 6)
|
||||
{
|
||||
if (!(ALL7EMERALDS(emeralds)))
|
||||
if (!(ALLCHAOSEMERALDS(emeralds)))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2028,6 +2028,14 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
player->karthud[khud_laphand] = 0; // No hands in FREE PLAY
|
||||
|
||||
player->karthud[khud_lapanimation] = 80;
|
||||
|
||||
// save best lap for record attack
|
||||
if (player == &players[consoleplayer])
|
||||
{
|
||||
if (curlap < bestlap || bestlap == 0)
|
||||
bestlap = curlap;
|
||||
curlap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rainbowstartavailable == true)
|
||||
|
|
@ -2041,14 +2049,6 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
if (netgame && player->laps >= (UINT8)cv_numlaps.value)
|
||||
CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players]));
|
||||
|
||||
// SRB2Kart: save best lap for record attack
|
||||
if (player == &players[consoleplayer])
|
||||
{
|
||||
if (curlap < bestlap || bestlap == 0)
|
||||
bestlap = curlap;
|
||||
curlap = 0;
|
||||
}
|
||||
|
||||
player->starpostnum = 0;
|
||||
|
||||
if (P_IsDisplayPlayer(player))
|
||||
|
|
@ -2133,6 +2133,7 @@ static void K_HandleLapDecrement(player_t *player)
|
|||
{
|
||||
player->starpostnum = numstarposts;
|
||||
player->laps--;
|
||||
curlap = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4617,7 +4618,7 @@ DoneSection2:
|
|||
}
|
||||
|
||||
player->trickpanel = 1;
|
||||
player->trickdelay = TICRATE/2;
|
||||
player->trickdelay = 1;
|
||||
K_DoPogoSpring(player->mo, upwards, 1);
|
||||
|
||||
// Reduce speed
|
||||
|
|
@ -4667,7 +4668,7 @@ DoneSection2:
|
|||
}
|
||||
|
||||
lineangle = K_ReflectAngle(
|
||||
R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy), lineangle,
|
||||
K_MomentumAngle(player->mo), lineangle,
|
||||
playerspeed, linespeed
|
||||
);
|
||||
|
||||
|
|
|
|||
17
src/p_tick.c
17
src/p_tick.c
|
|
@ -332,6 +332,11 @@ static inline void P_RunThinkers(void)
|
|||
ps_thlist_times[i] = I_GetTimeMicros() - ps_thlist_times[i];
|
||||
}
|
||||
|
||||
if (gametyperules & GTR_PAPERITEMS)
|
||||
K_RunPaperItemSpawners();
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled)
|
||||
K_RunBattleOvertime();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -516,6 +521,8 @@ void P_Ticker(boolean run)
|
|||
if (demo.rewinding && leveltime > 0)
|
||||
{
|
||||
leveltime = (leveltime-1) & ~3;
|
||||
if (timeinmap > 0)
|
||||
timeinmap = (timeinmap-1) & ~3;
|
||||
G_PreviewRewind(leveltime);
|
||||
}
|
||||
else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause!
|
||||
|
|
@ -592,9 +599,6 @@ void P_Ticker(boolean run)
|
|||
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
|
||||
P_PlayerAfterThink(&players[i]);
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled)
|
||||
K_RunBattleOvertime();
|
||||
|
||||
ps_lua_thinkframe_time = I_GetTimeMicros();
|
||||
LUAh_ThinkFrame();
|
||||
ps_lua_thinkframe_time = I_GetTimeMicros() - ps_lua_thinkframe_time;
|
||||
|
|
@ -613,9 +617,7 @@ void P_Ticker(boolean run)
|
|||
if (run)
|
||||
leveltime++;
|
||||
|
||||
// as this is mostly used for HUD stuff, add the record attack specific hack to it as well!
|
||||
if (!(modeattacking && !demo.playback) || leveltime >= starttime - TICRATE*4)
|
||||
timeinmap++;
|
||||
timeinmap++;
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
P_DoTeamStuff();
|
||||
|
|
@ -752,9 +754,6 @@ void P_PreTicker(INT32 frames)
|
|||
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
|
||||
P_PlayerAfterThink(&players[i]);
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled)
|
||||
K_RunBattleOvertime();
|
||||
|
||||
LUAh_ThinkFrame();
|
||||
|
||||
// Run shield positioning
|
||||
|
|
|
|||
35
src/p_user.c
35
src/p_user.c
|
|
@ -461,15 +461,9 @@ UINT8 P_FindHighestLap(void)
|
|||
//
|
||||
boolean P_PlayerInPain(player_t *player)
|
||||
{
|
||||
if (player->kartstuff[k_spinouttimer] || player->kartstuff[k_squishedtimer] || player->respawn.state != RESPAWNST_NONE)
|
||||
if (player->kartstuff[k_spinouttimer] || player->kartstuff[k_squishedtimer])
|
||||
return true;
|
||||
|
||||
if (gametyperules & GTR_KARMA)
|
||||
{
|
||||
if (player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1290,6 +1284,8 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
ghost->colorized = mobj->colorized; // Kart: they should also be colorized if their origin is
|
||||
|
||||
ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle);
|
||||
ghost->roll = mobj->roll;
|
||||
ghost->pitch = mobj->pitch;
|
||||
ghost->sprite = mobj->sprite;
|
||||
ghost->sprite2 = mobj->sprite2;
|
||||
ghost->frame = mobj->frame;
|
||||
|
|
@ -1298,13 +1294,11 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
ghost->fuse = ghost->info->damage;
|
||||
ghost->skin = mobj->skin;
|
||||
ghost->standingslope = mobj->standingslope;
|
||||
#ifdef HWRENDER
|
||||
ghost->modeltilt = mobj->modeltilt;
|
||||
#endif
|
||||
|
||||
ghost->sprxoff = mobj->sprxoff;
|
||||
ghost->spryoff = mobj->spryoff;
|
||||
ghost->sprzoff = mobj->sprzoff;
|
||||
ghost->rollangle = mobj->rollangle;
|
||||
|
||||
if (mobj->flags2 & MF2_OBJECTFLIP)
|
||||
ghost->flags |= MF2_OBJECTFLIP;
|
||||
|
|
@ -1940,11 +1934,6 @@ static void P_3dMovement(player_t *player)
|
|||
|
||||
totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward);
|
||||
totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward);
|
||||
|
||||
if (K_PlayerUsesBotMovement(player) == true)
|
||||
{
|
||||
K_MomentumToFacing(player);
|
||||
}
|
||||
}
|
||||
|
||||
if ((totalthrust.x || totalthrust.y)
|
||||
|
|
@ -2274,7 +2263,7 @@ void P_MovePlayer(player_t *player)
|
|||
|
||||
if (trailScale > 0)
|
||||
{
|
||||
const angle_t forwardangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
|
||||
const angle_t forwardangle = K_MomentumAngle(player->mo);
|
||||
const fixed_t playerVisualRadius = player->mo->radius + 8*FRACUNIT;
|
||||
const size_t numFrames = S_WATERTRAIL8 - S_WATERTRAIL1;
|
||||
const statenum_t curOverlayFrame = S_WATERTRAIL1 + (leveltime % numFrames);
|
||||
|
|
@ -2647,7 +2636,7 @@ static void P_DeathThink(player_t *player)
|
|||
{
|
||||
if (player->spectator || !circuitmap)
|
||||
curlap = 0;
|
||||
else
|
||||
else if (curlap != UINT32_MAX)
|
||||
curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
|
||||
}
|
||||
}
|
||||
|
|
@ -4074,7 +4063,7 @@ static void P_HandleFollower(player_t *player)
|
|||
player->follower->drawflags |= MFD_DONTDRAW;
|
||||
|
||||
if (player->speed && (player->follower->momx || player->follower->momy))
|
||||
player->follower->angle = R_PointToAngle2(0, 0, player->follower->momx, player->follower->momy);
|
||||
player->follower->angle = K_MomentumAngle(player->follower);
|
||||
// if we're moving let's make the angle the direction we're moving towards. This is to avoid drifting / reverse looking awkward.
|
||||
// Make sure the follower itself is also moving however, otherwise we'll be facing angle 0
|
||||
|
||||
|
|
@ -4220,6 +4209,11 @@ void P_PlayerThink(player_t *player)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (player->mo->hitlag > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj))
|
||||
{
|
||||
P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid
|
||||
|
|
@ -4306,6 +4300,7 @@ void P_PlayerThink(player_t *player)
|
|||
|
||||
if (player->playerstate == PST_DEAD)
|
||||
{
|
||||
LUAh_PlayerThink(player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -4382,7 +4377,7 @@ void P_PlayerThink(player_t *player)
|
|||
{
|
||||
if (player->spectator || !circuitmap)
|
||||
curlap = 0;
|
||||
else
|
||||
else if (curlap != UINT32_MAX)
|
||||
curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
|
||||
}
|
||||
}
|
||||
|
|
@ -4535,7 +4530,7 @@ void P_PlayerThink(player_t *player)
|
|||
|| player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either.
|
||||
|| (player->respawn.state != RESPAWNST_NONE) // Respawn timer (for drop dash effect)
|
||||
|| (player->pflags & PF_GAMETYPEOVER) // NO CONTEST explosion
|
||||
|| ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer])
|
||||
|| ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay)
|
||||
|| leveltime < starttime)) // Level intro
|
||||
{
|
||||
if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < K_GetKartFlashing(player)
|
||||
|
|
|
|||
24
src/r_main.c
24
src/r_main.c
|
|
@ -368,29 +368,7 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y)
|
|||
|
||||
fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1)
|
||||
{
|
||||
angle_t angle;
|
||||
fixed_t dx, dy, dist;
|
||||
|
||||
dx = abs(px1 - px2);
|
||||
dy = abs(py1 - py2);
|
||||
|
||||
if (dy > dx)
|
||||
{
|
||||
fixed_t temp;
|
||||
|
||||
temp = dx;
|
||||
dx = dy;
|
||||
dy = temp;
|
||||
}
|
||||
if (!dy)
|
||||
return dx;
|
||||
|
||||
angle = (tantoangle[FixedDiv(dy, dx)>>DBITS] + ANGLE_90) >> ANGLETOFINESHIFT;
|
||||
|
||||
// use as cosine
|
||||
dist = FixedDiv(dx, FINESINE(angle));
|
||||
|
||||
return dist;
|
||||
return FixedHypot(px1 - px2, py1 - py2);
|
||||
}
|
||||
|
||||
// Little extra utility. Works in the same way as R_PointToAngle2
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "v_video.h"
|
||||
#include "z_zone.h"
|
||||
#include "w_wad.h"
|
||||
#include "r_main.h" // R_PointToAngle
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_glob.h"
|
||||
|
|
@ -1605,6 +1606,27 @@ void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps)
|
|||
}
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
//
|
||||
// R_SpriteRotationAngle
|
||||
//
|
||||
// Gets the rollangle for the input object.
|
||||
//
|
||||
angle_t R_SpriteRotationAngle(mobj_t *mobj)
|
||||
{
|
||||
#if 0
|
||||
angle_t viewingAngle = R_PointToAngle(mobj->x, mobj->y);
|
||||
|
||||
fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT);
|
||||
fixed_t rollMul = FINECOSINE(viewingAngle >> ANGLETOFINESHIFT);
|
||||
|
||||
angle_t rollOrPitch = FixedMul(mobj->pitch, pitchMul) + FixedMul(mobj->roll, rollMul);
|
||||
|
||||
return (rollOrPitch + mobj->rollangle);
|
||||
#else
|
||||
return mobj->rollangle;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// R_GetRollAngle
|
||||
//
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
|
|||
|
||||
// Sprite rotation
|
||||
#ifdef ROTSPRITE
|
||||
angle_t R_SpriteRotationAngle(mobj_t *mobj);
|
||||
INT32 R_GetRollAngle(angle_t rollangle);
|
||||
void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip);
|
||||
void R_FreeSingleRotSprite(spritedef_t *spritedef);
|
||||
|
|
|
|||
|
|
@ -876,6 +876,11 @@ boolean SetPlayerFollower(INT32 playernum, const char *skinname)
|
|||
INT32 i;
|
||||
player_t *player = &players[playernum];
|
||||
|
||||
if (stricmp("None", skinname) == 0)
|
||||
{
|
||||
SetFollower(playernum, -1); // reminder that -1 is nothing
|
||||
return true;
|
||||
}
|
||||
for (i = 0; i < numfollowers; i++)
|
||||
{
|
||||
// search in the skin list
|
||||
|
|
|
|||
|
|
@ -1230,32 +1230,6 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
|||
return groundz;
|
||||
}
|
||||
|
||||
static void R_SetSpritePlaneHeights(vissprite_t *vis)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
fixed_t top;
|
||||
fixed_t bot;
|
||||
|
||||
vis->pt = vis->sector->floorheight;
|
||||
vis->pb = vis->sector->ceilingheight;
|
||||
|
||||
for (rover = vis->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->flags & FF_EXISTS)
|
||||
{
|
||||
top = P_GetFFloorTopZAt (rover, vis->gx, vis->gy);
|
||||
bot = P_GetFFloorBottomZAt (rover, vis->gx, vis->gy);
|
||||
|
||||
if (top <= vis->gzt && top > vis->pt)
|
||||
vis->pt = top;
|
||||
|
||||
if (bot >= vis->gz && bot < vis->pb)
|
||||
vis->pb = bot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz)
|
||||
{
|
||||
vissprite_t *shadow;
|
||||
|
|
@ -1344,8 +1318,6 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000
|
||||
shadow->scale = FixedMul(yscale, shadowyscale);
|
||||
shadow->sector = vis->sector;
|
||||
shadow->pt = vis->pt;
|
||||
shadow->pb = vis->pb;
|
||||
shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS);
|
||||
shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS);
|
||||
shadow->cut = SC_ISSCALED|SC_SHADOW; //check this
|
||||
|
|
@ -1403,9 +1375,9 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
//
|
||||
static void R_ProjectSprite(mobj_t *thing)
|
||||
{
|
||||
const fixed_t thingxpos = thing->x + thing->sprxoff;
|
||||
const fixed_t thingypos = thing->y + thing->spryoff;
|
||||
const fixed_t thingzpos = thing->z + thing->sprzoff;
|
||||
fixed_t thingxpos = thing->x + thing->sprxoff;
|
||||
fixed_t thingypos = thing->y + thing->spryoff;
|
||||
fixed_t thingzpos = thing->z + thing->sprzoff;
|
||||
|
||||
mobj_t *oldthing = thing;
|
||||
|
||||
|
|
@ -1462,8 +1434,24 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
#ifdef ROTSPRITE
|
||||
patch_t *rotsprite = NULL;
|
||||
INT32 rollangle = 0;
|
||||
angle_t spriterotangle = 0;
|
||||
#endif
|
||||
|
||||
// hitlag vibrating
|
||||
if (thing->hitlag > 0)
|
||||
{
|
||||
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
mul = -mul;
|
||||
}
|
||||
|
||||
thingxpos += FixedMul(thing->momx, mul);
|
||||
thingypos += FixedMul(thing->momy, mul);
|
||||
thingzpos += FixedMul(thing->momz, mul);
|
||||
}
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thingxpos - viewx;
|
||||
tr_y = thingypos - viewy;
|
||||
|
|
@ -1587,9 +1575,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
spr_topoffset = spritecachedinfo[lump].topoffset;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (thing->rollangle)
|
||||
spriterotangle = R_SpriteRotationAngle(thing);
|
||||
|
||||
if (spriterotangle != 0)
|
||||
{
|
||||
rollangle = R_GetRollAngle(thing->rollangle);
|
||||
rollangle = R_GetRollAngle(spriterotangle);
|
||||
if (!(sprframe->rotsprite.cached & (1<<rot)))
|
||||
R_CacheRotSprite(thing->sprite, frame, sprinfo, sprframe, rot, flip);
|
||||
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
|
||||
|
|
@ -1845,9 +1835,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->sector = thing->subsector->sector;
|
||||
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS);
|
||||
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS);
|
||||
|
||||
R_SetSpritePlaneHeights(vis);
|
||||
|
||||
vis->cut = cut;
|
||||
if (thing->subsector->sector->numlights)
|
||||
vis->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap;
|
||||
|
|
@ -2062,8 +2049,6 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, yscale))>>FRACBITS);
|
||||
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, yscale))>>FRACBITS);
|
||||
|
||||
R_SetSpritePlaneHeights(vis);
|
||||
|
||||
iscale = FixedDiv(FRACUNIT, xscale);
|
||||
|
||||
vis->startfrac = 0;
|
||||
|
|
@ -2443,12 +2428,12 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
|
|||
// bird: if any part of the sprite peeks in front the plane
|
||||
if (planecameraz < viewz)
|
||||
{
|
||||
if (rover->pt >= planeobjectz && rover->gzt >= planeobjectz)
|
||||
if (rover->gzt >= planeobjectz)
|
||||
continue;
|
||||
}
|
||||
else if (planecameraz > viewz)
|
||||
{
|
||||
if (rover->pb <= planeobjectz && rover->gz <= planeobjectz)
|
||||
if (rover->gz <= planeobjectz)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2481,7 +2466,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
|
|||
}
|
||||
else if (r2->thickseg)
|
||||
{
|
||||
fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz;
|
||||
//fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz;
|
||||
if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1)
|
||||
continue;
|
||||
|
||||
|
|
@ -2492,6 +2477,11 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
|
|||
if (scale <= rover->sortscale)
|
||||
continue;
|
||||
|
||||
// bird: Always sort sprites behind segs. This helps the plane
|
||||
// sorting above too. Basically if the sprite gets sorted behind
|
||||
// the seg here, it will be behind the plane too, since planes
|
||||
// are added after segs in the list.
|
||||
#if 0
|
||||
topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy);
|
||||
topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy);
|
||||
botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy);
|
||||
|
|
@ -2500,6 +2490,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
|
|||
if ((topplanecameraz > viewz && botplanecameraz < viewz) ||
|
||||
(topplanecameraz < viewz && rover->gzt < topplaneobjectz) ||
|
||||
(botplanecameraz > viewz && rover->gz > botplaneobjectz))
|
||||
#endif
|
||||
{
|
||||
entry = R_CreateDrawNode(NULL);
|
||||
(entry->prev = r2->prev)->next = entry;
|
||||
|
|
|
|||
|
|
@ -171,7 +171,6 @@ typedef struct vissprite_s
|
|||
|
||||
// Precalculated top and bottom screen coords for the sprite.
|
||||
sector_t *sector; // The sector containing the thing.
|
||||
fixed_t pt, pb; // plane heights, also for sorting against 3D floors
|
||||
INT16 sz, szt;
|
||||
|
||||
spritecut_e cut;
|
||||
|
|
|
|||
|
|
@ -2336,7 +2336,7 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
|
|||
S_InitMusicVolume(); // switch between digi and sequence volume
|
||||
|
||||
if (S_MusicNotInFocus())
|
||||
S_PauseAudio();
|
||||
I_SetMusicVolume(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2780,9 +2780,9 @@ static void PlayMusicIfUnfocused_OnChange(void)
|
|||
if (window_notinfocus)
|
||||
{
|
||||
if (cv_playmusicifunfocused.value)
|
||||
I_PauseSong();
|
||||
I_SetMusicVolume(0);
|
||||
else
|
||||
I_ResumeSong();
|
||||
S_InitMusicVolume();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -651,7 +651,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
|||
window_notinfocus = false;
|
||||
|
||||
if (!paused)
|
||||
S_ResumeAudio(); //resume it
|
||||
S_InitMusicVolume();
|
||||
|
||||
if (cv_gamesounds.value)
|
||||
S_EnableSound();
|
||||
|
|
@ -670,7 +670,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
|||
// Tell game we lost focus, pause music
|
||||
window_notinfocus = true;
|
||||
if (!cv_playmusicifunfocused.value)
|
||||
I_PauseSong();
|
||||
I_SetMusicVolume(0);
|
||||
if (!cv_playsoundifunfocused.value)
|
||||
S_DisableSound();
|
||||
|
||||
|
|
|
|||
|
|
@ -740,14 +740,14 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"cdfm61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Speed boost"},
|
||||
{"cdfm63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm64", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm64", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm70", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm71", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm73", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm74", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
|
@ -808,7 +808,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"kc4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc51", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc52", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc54", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
|
|
|||
|
|
@ -673,10 +673,8 @@ void ST_preDrawTitleCard(void)
|
|||
if (lt_ticker >= (lt_endtime + TICRATE))
|
||||
return;
|
||||
|
||||
if (!lt_exitticker)
|
||||
st_translucency = 0;
|
||||
else
|
||||
st_translucency = max(0, min((INT32)lt_exitticker-4, cv_translucenthud.value));
|
||||
// Kart: nothing
|
||||
st_translucency = cv_translucenthud.value;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
235
src/stun.c
Normal file
235
src/stun.c
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2020 by James R.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file stun.c
|
||||
/// \brief RFC 5389 client implementation to fetch external IP address.
|
||||
|
||||
/* https://tools.ietf.org/html/rfc5389 */
|
||||
|
||||
#if defined (__linux__)
|
||||
#include <sys/random.h>
|
||||
#elif defined (_WIN32)
|
||||
#define _CRT_RAND_S
|
||||
#elif defined (__APPLE__)
|
||||
#include <CommonCrypto/CommonRandom.h>
|
||||
#else
|
||||
#error "Need CSPRNG."
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "command.h"
|
||||
#include "i_net.h"
|
||||
#include "stun.h"
|
||||
|
||||
/* https://gist.github.com/zziuni/3741933 */
|
||||
/* I can only trust google to keep their shit up :y */
|
||||
consvar_t cv_stunserver = CVAR_INIT (
|
||||
"stunserver", "stun.l.google.com:19302", CV_SAVE, NULL, NULL
|
||||
);
|
||||
|
||||
static stun_callback_t stun_callback;
|
||||
|
||||
/* 18.4 STUN UDP and TCP Port Numbers */
|
||||
|
||||
#define STUN_PORT "3478"
|
||||
|
||||
/* 6. STUN Message Structure */
|
||||
|
||||
#define BIND_REQUEST 0x0001
|
||||
#define BIND_RESPONSE 0x0101
|
||||
|
||||
static const UINT32 MAGIC_COOKIE = MSBF_LONG (0x2112A442);
|
||||
|
||||
static char transaction_id[12];
|
||||
|
||||
/* 18.2 STUN Attribute Registry */
|
||||
|
||||
#define XOR_MAPPED_ADDRESS 0x0020
|
||||
|
||||
/* 15.1 MAPPED-ADDRESS */
|
||||
|
||||
#define STUN_IPV4 0x01
|
||||
|
||||
static SINT8
|
||||
STUN_node (void)
|
||||
{
|
||||
SINT8 node;
|
||||
|
||||
char * const colon = strchr(cv_stunserver.zstring, ':');
|
||||
|
||||
const char * const host = cv_stunserver.zstring;
|
||||
const char * const port = &colon[1];
|
||||
|
||||
I_Assert(I_NetMakeNodewPort != NULL);
|
||||
|
||||
if (colon != NULL)
|
||||
{
|
||||
*colon = '\0';
|
||||
|
||||
node = I_NetMakeNodewPort(host, port);
|
||||
|
||||
*colon = ':';
|
||||
}
|
||||
else
|
||||
{
|
||||
node = I_NetMakeNodewPort(host, STUN_PORT);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static void
|
||||
csprng
|
||||
(
|
||||
void * const buffer,
|
||||
const size_t size
|
||||
){
|
||||
#if defined (_WIN32)
|
||||
size_t o;
|
||||
|
||||
for (o = 0; o < size; o += sizeof (unsigned int))
|
||||
{
|
||||
rand_s((unsigned int *)&((char *)buffer)[o]);
|
||||
}
|
||||
#elif defined (__linux__)
|
||||
getrandom(buffer, size, 0U);
|
||||
#elif defined (__APPLE__)
|
||||
CCRandomGenerateBytes(buffer, size);
|
||||
#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__)
|
||||
arc4random_buf(buffer, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
STUN_bind (stun_callback_t callback)
|
||||
{
|
||||
/* 6. STUN Message Structure */
|
||||
|
||||
const UINT16 type = MSBF_SHORT (BIND_REQUEST);
|
||||
|
||||
const SINT8 node = STUN_node();
|
||||
|
||||
doomcom->remotenode = node;
|
||||
doomcom->datalength = 20;
|
||||
|
||||
csprng(transaction_id, 12U);
|
||||
|
||||
memcpy(&doomcom->data[0], &type, 2U);
|
||||
memset(&doomcom->data[2], 0, 2U);
|
||||
memcpy(&doomcom->data[4], &MAGIC_COOKIE, 4U);
|
||||
memcpy(&doomcom->data[8], transaction_id, 12U);
|
||||
|
||||
stun_callback = callback;
|
||||
|
||||
I_NetSend();
|
||||
Net_CloseConnection(node);/* will handle response at I_NetGet */
|
||||
}
|
||||
|
||||
static size_t
|
||||
STUN_xor_mapped_address (const char * const value)
|
||||
{
|
||||
const UINT32 xaddr = *(const UINT32 *)&value[4];
|
||||
const UINT32 addr = xaddr ^ MAGIC_COOKIE;
|
||||
|
||||
(*stun_callback)(addr);
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
static size_t
|
||||
align4 (size_t n)
|
||||
{
|
||||
return n + n % 4U;
|
||||
}
|
||||
|
||||
static size_t
|
||||
STUN_parse_attribute (const char * const attribute)
|
||||
{
|
||||
/* 15. STUN Attributes */
|
||||
const UINT16 type = MSBF_SHORT (*(const UINT16 *)&attribute[0]);
|
||||
const UINT16 length = MSBF_SHORT (*(const UINT16 *)&attribute[2]);
|
||||
|
||||
/* 15.2 XOR-MAPPED-ADDRESS */
|
||||
if (
|
||||
type == XOR_MAPPED_ADDRESS &&
|
||||
length == 8U &&
|
||||
(unsigned char)attribute[5] == STUN_IPV4
|
||||
){
|
||||
return STUN_xor_mapped_address(&attribute[4]);
|
||||
}
|
||||
|
||||
return align4(4U + length);
|
||||
}
|
||||
|
||||
boolean
|
||||
STUN_got_response
|
||||
(
|
||||
const char * const buffer,
|
||||
const size_t size
|
||||
){
|
||||
const char * const end = &buffer[size];
|
||||
|
||||
const char * p = &buffer[20];
|
||||
|
||||
UINT16 type;
|
||||
UINT16 length;
|
||||
|
||||
/*
|
||||
Check for STUN response.
|
||||
|
||||
Header is 20 bytes.
|
||||
XOR-MAPPED-ADDRESS attribute is required.
|
||||
Each attribute has a 2 byte header.
|
||||
The XOR-MAPPED-ADDRESS attribute also has a 8 byte value.
|
||||
This totals 10 bytes for the attribute.
|
||||
*/
|
||||
|
||||
if (size < 30U || stun_callback == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 6. STUN Message Structure */
|
||||
|
||||
if (
|
||||
*(const UINT32 *)&buffer[4] == MAGIC_COOKIE &&
|
||||
memcmp(&buffer[8], transaction_id, 12U) == 0
|
||||
){
|
||||
type = MSBF_SHORT (*(const UINT16 *)&buffer[0]);
|
||||
length = MSBF_SHORT (*(const UINT16 *)&buffer[2]);
|
||||
|
||||
if (
|
||||
(type >> 14) == 0U &&
|
||||
(length & 0x02) == 0U &&
|
||||
(20U + length) <= size
|
||||
){
|
||||
if (type == BIND_RESPONSE)
|
||||
{
|
||||
do
|
||||
{
|
||||
length = STUN_parse_attribute(p);
|
||||
|
||||
if (length == 0U)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
p += length;
|
||||
}
|
||||
while (p < end) ;
|
||||
}
|
||||
|
||||
stun_callback = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
20
src/stun.h
Normal file
20
src/stun.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2020 by James R.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file stun.h
|
||||
/// \brief RFC 5389 client implementation to fetch external IP address.
|
||||
|
||||
#ifndef KART_STUN_H
|
||||
#define KART_STUN_H
|
||||
|
||||
typedef void (*stun_callback_t)(UINT32 address);
|
||||
|
||||
void STUN_bind (stun_callback_t);
|
||||
boolean STUN_got_response (const char * const buffer, const size_t size);
|
||||
|
||||
#endif/*KART_STUN_H*/
|
||||
Loading…
Add table
Reference in a new issue