Compare commits
80
Commits
maperrors
...
luaprofile
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c440d240c | ||
|
|
5c7be85977 | ||
|
|
c401926c0b | ||
|
|
957d3f7229 | ||
|
|
38a248193e | ||
|
|
934f2d347c | ||
|
|
551d7d4d89 | ||
|
|
a2184d2bef | ||
|
|
d638baeda6 | ||
|
|
4a06e8a6d1 | ||
|
|
e2a3992787 | ||
|
|
ec06150432 | ||
|
|
2413a3503c | ||
|
|
d9e339cb56 | ||
|
|
408db7a2eb | ||
|
|
e12ecabcf0 | ||
|
|
65c2d2733d | ||
|
|
00aa023e9e | ||
|
|
f43a4a2eb6 | ||
|
|
4eb108e0a6 | ||
|
|
ea76af5a81 | ||
|
|
4b8f998c85 | ||
|
|
d687be4997 | ||
|
|
1bcadf3c46 | ||
|
|
80e4d02c51 | ||
|
|
352d1faacf | ||
|
|
7f9d70285d | ||
|
|
496477fa9a | ||
|
|
530bb50709 | ||
|
|
8bb04a68a8 | ||
|
|
820ab4b2bc | ||
|
|
af6abb5458 | ||
|
|
5c373b6251 | ||
|
|
24bac9c133 | ||
|
|
73c7a5a0c4 | ||
|
|
49d6374505 | ||
|
|
2ba4757c6a | ||
|
|
3606b0ae66 | ||
|
|
ba75523d48 | ||
|
|
71640202ed | ||
|
|
5fb5af05be | ||
|
|
4f036c9312 | ||
|
|
d99c272a79 | ||
|
|
c4ed75fbc6 | ||
|
|
91927e324b | ||
|
|
13dc0db9a9 | ||
|
|
8aafde4c9d | ||
|
|
266a4effb7 | ||
|
|
948c9399de | ||
|
|
db4aedf498 | ||
|
|
f12d5a246d | ||
|
|
6efe56808a | ||
|
|
ec047151e3 | ||
|
|
b1100d6215 | ||
|
|
cb8df4c3d0 | ||
|
|
fbae43f61a | ||
|
|
7ea95b4495 | ||
|
|
07c780dc9c | ||
|
|
f6d3ab1f3a | ||
|
|
2c8099e228 | ||
|
|
7c84dd5661 | ||
|
|
cabd8baae5 | ||
|
|
593540a3f9 | ||
|
|
407af1d25c | ||
|
|
029c21eae8 | ||
|
|
568f29ed1c | ||
|
|
2dacc333b5 | ||
|
|
363612c488 | ||
|
|
d8ffffd86e | ||
|
|
4b2a13defb | ||
|
|
9cc74d8b17 | ||
|
|
066adb972e | ||
|
|
0f1ad8a086 | ||
|
|
40537eca81 | ||
|
|
0cff3c23f3 | ||
|
|
9bdda66a0c | ||
|
|
3b6a09da9b | ||
|
|
c275555678 | ||
|
|
fc588f8046 | ||
|
|
17093e8022 |
No files matched your search
@@ -275,6 +275,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
|
||||
lua_hooklib.c
|
||||
lua_hudlib.c
|
||||
lua_hudlib_drawlist.c
|
||||
lua_profile.cpp
|
||||
lua_infolib.c
|
||||
lua_maplib.c
|
||||
lua_mathlib.c
|
||||
@@ -290,6 +291,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
|
||||
lua_hook.h
|
||||
lua_hud.h
|
||||
lua_hudlib_drawlist.h
|
||||
lua_profile.h
|
||||
lua_libs.h
|
||||
lua_script.h
|
||||
lua_udatalib.h
|
||||
|
||||
@@ -99,3 +99,4 @@ lua_skinlib.c
|
||||
lua_thinkerlib.c
|
||||
lua_udatalib.c
|
||||
lua_glib.c
|
||||
lua_profile.cpp
|
||||
+53
-39
@@ -62,7 +62,7 @@ static boolean con_started = false; // console has been initialised
|
||||
static boolean con_forcepic = true; // at startup toggle console translucency when first off
|
||||
boolean con_recalc = false; // set true when screen size has changed
|
||||
|
||||
static tic_t con_tick; // console ticker for anim or blinking prompt cursor
|
||||
static tic_t con_tick; // console ticker for blinking prompt cursor
|
||||
// con_scrollup should use time (currenttime - lasttime)..
|
||||
|
||||
static boolean consoletoggle; // true when console key pushed, ticker will handle
|
||||
@@ -103,6 +103,7 @@ static void CON_InputInit(void);
|
||||
static void CON_RecalcSize(void);
|
||||
static void CON_ChangeHeight(void);
|
||||
|
||||
static void CONS_height_Change(void);
|
||||
static void CONS_hudlines_Change(void);
|
||||
static void CONS_backcolor_Change(void);
|
||||
|
||||
@@ -131,7 +132,7 @@ static CV_PossibleValue_t speed_cons_t[] = {{0, "MIN"}, {64, "MAX"}, {0, NULL}};
|
||||
static consvar_t cons_speed = {"con_speed", "8", CV_SAVE, speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// percentage of screen height to use for console
|
||||
static consvar_t cons_height = {"con_height", "50", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static consvar_t cons_height = {"con_height", "50", CV_CALL|CV_SAVE, CV_Unsigned, CONS_height_Change, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t backpic_cons_t[] = {{0, "translucent"}, {1, "picture"}, {0, NULL}};
|
||||
// whether to use console background picture, or translucent mode
|
||||
@@ -173,6 +174,18 @@ consvar_t cons_consoleprintinmenu = {"consoleprintinmenu", "Off", CV_SAVE, CV_On
|
||||
|
||||
static void CON_Print(char *msg);
|
||||
|
||||
// Change the console height on demand
|
||||
//
|
||||
static void CONS_height_Change(void)
|
||||
{
|
||||
Lock_state();
|
||||
|
||||
if (con_destlines > 0 && !con_startup) // If the console is open (as in, not using "bind")...
|
||||
CON_ChangeHeight(); // ...update its height now, not only when it's closed and re-opened
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
static void CONS_hudlines_Change(void)
|
||||
@@ -1637,53 +1650,54 @@ static void CON_DrawConsole(void)
|
||||
}
|
||||
|
||||
// draw console text lines from top to bottom
|
||||
if (con_curlines < minheight)
|
||||
return;
|
||||
|
||||
i = con_cy - con_scrollup;
|
||||
|
||||
// skip the last empty line due to the cursor being at the start of a new line
|
||||
i--;
|
||||
|
||||
i -= (con_curlines - minheight) / charheight;
|
||||
|
||||
if (rendermode == render_none) return;
|
||||
|
||||
for (y = (con_curlines-minheight) % charheight; y <= con_curlines-minheight; y += charheight, i++)
|
||||
if (con_curlines >= minheight)
|
||||
{
|
||||
INT32 x;
|
||||
size_t c;
|
||||
i = con_cy - con_scrollup;
|
||||
|
||||
p = (UINT8 *)&con_buffer[((i > 0 ? i : 0)%con_totallines)*con_width];
|
||||
// skip the last empty line due to the cursor being at the start of a new line
|
||||
i--;
|
||||
|
||||
for (c = 0, x = charwidth; c < con_width; c++, x += charwidth, p++)
|
||||
i -= (con_curlines - minheight) / charheight;
|
||||
|
||||
if (rendermode == render_none)
|
||||
return;
|
||||
|
||||
for (y = (con_curlines-minheight) % charheight; y <= con_curlines-minheight; y += charheight, i++)
|
||||
{
|
||||
while (*p & 0x80)
|
||||
INT32 x;
|
||||
size_t c;
|
||||
|
||||
p = (UINT8 *)&con_buffer[((i > 0 ? i : 0)%con_totallines)*con_width];
|
||||
|
||||
for (c = 0, x = charwidth; c < con_width; c++, x += charwidth, p++)
|
||||
{
|
||||
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
|
||||
p++;
|
||||
c++;
|
||||
while (*p & 0x80)
|
||||
{
|
||||
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
|
||||
p++;
|
||||
c++;
|
||||
}
|
||||
|
||||
if (c >= con_width)
|
||||
break;
|
||||
|
||||
int emotelen;
|
||||
emote_t *emote;
|
||||
|
||||
if ((emote = M_VerifyEmote((const char *)p, &emotelen)))
|
||||
{
|
||||
M_DrawScaledEmote(x<<FRACBITS, (y+2*con_scalefactor)<<FRACBITS, charwidth*FRACUNIT/EMOTEWIDTH, emote, V_NOSCALESTART|V_NOSCALEPATCH);
|
||||
p += emotelen-1;
|
||||
c += emotelen-1;
|
||||
continue;
|
||||
}
|
||||
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
}
|
||||
|
||||
if (c >= con_width)
|
||||
break;
|
||||
|
||||
int emotelen;
|
||||
emote_t *emote;
|
||||
|
||||
if ((emote = M_VerifyEmote((const char *)p, &emotelen)))
|
||||
{
|
||||
M_DrawScaledEmote(x<<FRACBITS, (y+2*con_scalefactor)<<FRACBITS, charwidth*FRACUNIT/EMOTEWIDTH, emote, V_NOSCALESTART|V_NOSCALEPATCH);
|
||||
p += emotelen-1;
|
||||
c += emotelen-1;
|
||||
continue;
|
||||
}
|
||||
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
}
|
||||
}
|
||||
|
||||
// draw prompt if enough place (not while game startup)
|
||||
if ((con_curlines == con_destlines) && (con_curlines >= minheight) && !con_startup)
|
||||
if ((con_curlines >= (minheight-charheight)) && !con_startup)
|
||||
CON_DrawInput();
|
||||
}
|
||||
|
||||
|
||||
+15
-3
@@ -841,11 +841,13 @@ static void resynch_write_ctf(resynchend_pak *rst)
|
||||
rst->flagplayer[i] = (SINT8)j;
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == MAXPLAYERS) // fine, no I_Error
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "One of the flags has gone completely missing...\n");
|
||||
rst->flagplayer[i] = -2;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1135,6 +1137,7 @@ static void CV_SavePlayerNames(UINT8 **p)
|
||||
WRITEUINT8(*p, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
WRITESTRING(*p, player_names[i]);
|
||||
}
|
||||
}
|
||||
@@ -1148,10 +1151,13 @@ static void CV_LoadPlayerNames(UINT8 **p)
|
||||
for (; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
READSTRING(*p, tmp_name);
|
||||
|
||||
if (tmp_name[0] == 0)
|
||||
continue;
|
||||
|
||||
if (tmp_name[MAXPLAYERNAME]) // overflow detected
|
||||
I_Error("Received bad server config packet when trying to join");
|
||||
|
||||
memcpy(player_names[i], tmp_name, MAXPLAYERNAME+1);
|
||||
}
|
||||
}
|
||||
@@ -1449,6 +1455,7 @@ static void CL_DrawConnectionStatus(void)
|
||||
if (playerinfo[i].node < 255)
|
||||
{
|
||||
strncpy(player_name, playerinfo[i].name, MAXPLAYERNAME);
|
||||
player_name[MAXPLAYERNAME] = '\0';
|
||||
|
||||
// if we get a skin color
|
||||
// try to colourize the player name
|
||||
@@ -2028,6 +2035,7 @@ static void SV_SendSaveGame(INT32 node, boolean resending)
|
||||
P_SaveNetGame(&save, resending);
|
||||
|
||||
length = save.p - save.buffer;
|
||||
|
||||
if (length > SAVEGAMESIZE)
|
||||
{
|
||||
Z_Free(save.buffer);
|
||||
@@ -2180,7 +2188,8 @@ static void CL_LoadReceivedSavegame(boolean reloading)
|
||||
if (unlink(tmpsave) == -1)
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
|
||||
consistancy[gametic%BACKUPTICS] = Consistancy();
|
||||
CON_ToggleOff();
|
||||
if (!reloading)
|
||||
CON_ToggleOff();
|
||||
|
||||
#ifdef SATURNPAK
|
||||
// Tell the server we have received and reloaded the gamestate
|
||||
@@ -4798,7 +4807,7 @@ void CL_RemoveSplitscreenPlayer(UINT8 p)
|
||||
// is there a game running
|
||||
boolean Playing(void)
|
||||
{
|
||||
return (server && serverrunning) || (client && cl_mode == CL_CONNECTED);
|
||||
return ((server && serverrunning) || (client && cl_mode == CL_CONNECTED));
|
||||
}
|
||||
|
||||
boolean SV_SpawnServer(void)
|
||||
@@ -5399,7 +5408,7 @@ static void PT_ServerCFG(SINT8 node)
|
||||
{
|
||||
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
||||
if ((gametype = netbuffer->u.servercfg.gametype) >= NUMGAMETYPES)
|
||||
I_Error("Bad gametype in cliserv!");
|
||||
I_Error("Bad gametype %d in cliserv!", gametype);
|
||||
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
adminplayers[j] = netbuffer->u.servercfg.adminplayers[j];
|
||||
@@ -6839,7 +6848,10 @@ boolean TryRunTics(tic_t realtics)
|
||||
DEBFILE(va("============ Running tic %d (local %d)\n", gametic, leveltime));
|
||||
|
||||
if (update_stats)
|
||||
{
|
||||
ps_prevtictime = ps_tictime;
|
||||
PS_START_TIMING(ps_tictime);
|
||||
}
|
||||
|
||||
G_Ticker((gametic % NEWTICRATERATIO) == 0);
|
||||
ExtraDataTicker();
|
||||
|
||||
+23
-11
@@ -79,6 +79,7 @@
|
||||
#include "core/memory.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_profile.h"
|
||||
|
||||
/* Manually defined asset hashes for non-CMake builds
|
||||
* Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb
|
||||
@@ -658,6 +659,11 @@ static boolean D_Display(void)
|
||||
|
||||
CON_Drawer(); // Ha, i LIED!
|
||||
|
||||
if (cv_lua_profile.value > 0)
|
||||
{
|
||||
LUA_RenderTimers();
|
||||
}
|
||||
|
||||
PS_START_TIMING(ps_swaptime);
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
PS_STOP_TIMING(ps_swaptime);
|
||||
@@ -1159,7 +1165,7 @@ static void D_FindAddonsToAutoload(void)
|
||||
// you can probably imagine how that goes in a netgame....
|
||||
if (W_CheckAutoLoadContainsMap(wadsToAutoload))
|
||||
{
|
||||
CONS_Printf("Autoload: file %s contains map data! skipping...", wadsToAutoload);
|
||||
CONS_Alert(CONS_WARNING, "Autoload: file %s contains map data, this WILL cause crashes and desynchs! skipping...\n", wadsToAutoload);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1353,20 +1359,24 @@ static void IdentifyVersion(void)
|
||||
//
|
||||
// search for maps
|
||||
//
|
||||
static void D_CheckMaps(boolean checkreplaced)
|
||||
static void D_CheckMapReplacements(boolean pwad)
|
||||
{
|
||||
INT32 i;
|
||||
char *name;
|
||||
UINT16 wadnum;
|
||||
lumpinfo_t *lumpinfo;
|
||||
size_t numfiles;
|
||||
|
||||
for (wadnum = 0; wadnum < mainwads; wadnum++)
|
||||
wadnum = pwad ? (mainwads+1) : 0;
|
||||
numfiles = pwad ? numwadfiles : mainwads;
|
||||
|
||||
for (; wadnum < numfiles; wadnum++)
|
||||
{
|
||||
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
P_CheckMapReplacements(name, checkreplaced);
|
||||
P_CheckMapReplacements(name, pwad);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1829,17 +1839,19 @@ void D_SRB2Main(void)
|
||||
// conversion sometimes needs the palette
|
||||
V_ReloadPalette();
|
||||
|
||||
D_CheckMaps(false);
|
||||
D_CheckMapReplacements(false);
|
||||
|
||||
W_InitMultipleFiles(startuppwads, startuppwadcount, true);
|
||||
|
||||
// Only search for pwad maps if we actually have a pwad added
|
||||
if (startuppwadcount > 0)
|
||||
{
|
||||
D_CheckMaps(true);
|
||||
CONS_Printf("W_InitMultipleFiles(): Adding extra PWADs.\n");
|
||||
W_InitMultipleFiles(startuppwads, startuppwadcount, true);
|
||||
|
||||
// Only search for pwad maps if we actually have a pwad added
|
||||
D_CheckMapReplacements(true);
|
||||
|
||||
D_CleanFile(startuppwads, startuppwadcount);
|
||||
}
|
||||
|
||||
D_CleanFile(startuppwads, startuppwadcount);
|
||||
startuppwadcount = 0;
|
||||
|
||||
cht_Init();
|
||||
@@ -1926,7 +1938,7 @@ void D_SRB2Main(void)
|
||||
CONS_Printf("R_Init(): Init SRB2 refresh daemon.\n");
|
||||
R_Init();
|
||||
|
||||
#if SOUND==SOUND_DUMMY
|
||||
#if SOUND == SOUND_DUMMY
|
||||
sound_disabled = true;
|
||||
music_disabled = true;
|
||||
#else
|
||||
|
||||
+31
-5
@@ -47,6 +47,7 @@
|
||||
#include "z_zone.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
#include "lua_profile.h"
|
||||
#include "m_cond.h"
|
||||
#include "m_anigif.h"
|
||||
#include "k_kart.h" // SRB2kart
|
||||
@@ -150,6 +151,7 @@ static void Command_ListWADS_f(void);
|
||||
static void Command_LocateLump_f(void);
|
||||
static void Command_ListDoomednums_f(void);
|
||||
static void Command_ListUnusedSprites_f(void);
|
||||
static void Command_ListUnusedMapSlots_f(void);
|
||||
static void Command_RunSOC(void);
|
||||
static void Command_Pause(void);
|
||||
static void Command_Respawn(void);
|
||||
@@ -505,6 +507,9 @@ static CV_PossibleValue_t ps_descriptor_cons_t[] = {
|
||||
{1, "Average"}, {2, "SD"}, {3, "Minimum"}, {4, "Maximum"}, {0, NULL}};
|
||||
consvar_t cv_ps_descriptor = {"ps_descriptor", "Average", 0, ps_descriptor_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
//consvar_t cv_lua_profile = {"lua_profile", "0").values(CV_Unsigned).onchange(lua_profile_OnChange).description("Show hook timings over an average of N tics");
|
||||
consvar_t cv_lua_profile = {"lua_profile", "0", CV_CALL, CV_Unsigned, lua_profile_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// only there to better keep track of it globally
|
||||
consvar_t cv_director = {"director", "Off", CV_HIDEN, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -645,6 +650,7 @@ void D_RegisterServerCommands(void)
|
||||
COM_AddCommand("locatelump", Command_LocateLump_f);
|
||||
COM_AddCommand("listmapthings", Command_ListDoomednums_f);
|
||||
COM_AddCommand("listunusedsprites", Command_ListUnusedSprites_f);
|
||||
COM_AddCommand("listunusedmapslots", Command_ListUnusedMapSlots_f);
|
||||
|
||||
COM_AddCommand("runsoc", Command_RunSOC);
|
||||
COM_AddCommand("pause", Command_Pause);
|
||||
@@ -928,11 +934,11 @@ void D_RegisterClientCommands(void)
|
||||
|
||||
COM_AddCommand("displayplayer", Command_Displayplayer_f);
|
||||
|
||||
CV_RegisterVar(&cv_audbuffersize);
|
||||
|
||||
CV_RegisterVar(&cv_palette);
|
||||
CV_RegisterVar(&cv_palettenum);
|
||||
|
||||
CV_RegisterVar(&cv_lua_profile);
|
||||
|
||||
// m_menu.c
|
||||
CV_RegisterVar(&cv_chatheight);
|
||||
CV_RegisterVar(&cv_chatwidth);
|
||||
@@ -940,6 +946,9 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_chatspamprotection);
|
||||
CV_RegisterVar(&cv_consolechat);
|
||||
CV_RegisterVar(&cv_chatnotifications);
|
||||
CV_RegisterVar(&cv_chat_xoffset);
|
||||
CV_RegisterVar(&cv_chat_yoffset);
|
||||
CV_RegisterVar(&cv_chat_showlimit);
|
||||
CV_RegisterVar(&cv_chatbacktint);
|
||||
CV_RegisterVar(&cv_chatcentertext);
|
||||
CV_RegisterVar(&cv_songcredits);
|
||||
@@ -1027,6 +1036,7 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_midimusicvolume);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_numChannels);
|
||||
CV_RegisterVar(&cv_audbuffersize);
|
||||
|
||||
#ifdef HAVE_OPENMPT
|
||||
CV_RegisterVar(&cv_modfilter);
|
||||
@@ -1548,8 +1558,8 @@ static void SendNameAndColor(UINT8 splitplayer)
|
||||
// TODO: make those cvars arrays
|
||||
consvar_t *playercolor, *playername, *playerskin;
|
||||
consvar_t *colorvars[] = {&cv_playercolor, &cv_playercolor2, &cv_playercolor3, &cv_playercolor4};
|
||||
consvar_t *namevars[] = {&cv_playername, &cv_playername2, &cv_playername3, &cv_playername4};
|
||||
consvar_t *skinvars[] = {&cv_skin, &cv_skin2, &cv_skin3, &cv_skin4};
|
||||
consvar_t *namevars[] = {&cv_playername, &cv_playername2, &cv_playername3, &cv_playername4};
|
||||
consvar_t *skinvars[] = {&cv_skin, &cv_skin2, &cv_skin3, &cv_skin4};
|
||||
|
||||
playercolor = colorvars[splitplayer];
|
||||
playername = namevars[splitplayer];
|
||||
@@ -4591,6 +4601,23 @@ void Command_ListUnusedSprites_f(void)
|
||||
}
|
||||
}
|
||||
|
||||
void Command_ListUnusedMapSlots_f(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
CONS_Printf("\x82Printing map slot non-usage...\n");
|
||||
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
{
|
||||
// is checking this enough?
|
||||
if (mapheaderinfo[i])
|
||||
continue;
|
||||
|
||||
CONS_Printf("%s\n", G_BuildMapName(i+1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =========================================================================
|
||||
// MISC. COMMANDS
|
||||
// =========================================================================
|
||||
@@ -5471,7 +5498,6 @@ static void Name_OnChange(void)
|
||||
}
|
||||
|
||||
SendNameAndColor(0);
|
||||
|
||||
}
|
||||
|
||||
static void Name2_OnChange(void)
|
||||
|
||||
@@ -149,6 +149,7 @@ extern consvar_t cv_showminimapnames;
|
||||
extern consvar_t cv_showminimapfinished;
|
||||
extern consvar_t cv_minihead;
|
||||
extern consvar_t cv_showminimapangle;
|
||||
extern consvar_t cv_spinoutroll;
|
||||
|
||||
extern consvar_t cv_showlapemblem;
|
||||
|
||||
@@ -188,6 +189,8 @@ extern consvar_t cv_ps_thinkframe_page;
|
||||
extern consvar_t cv_ps_samplesize;
|
||||
extern consvar_t cv_ps_descriptor;
|
||||
|
||||
extern consvar_t cv_lua_profile;
|
||||
|
||||
extern consvar_t cv_director, cv_kartdebugdirector, cv_showdirectorhud;
|
||||
|
||||
extern consvar_t cv_showtrackaddon;
|
||||
|
||||
@@ -566,6 +566,8 @@ typedef struct player_s
|
||||
fixed_t fovadd; // adjust FOV for hw rendering
|
||||
|
||||
SINT8 driftlevel; // just for controller rumble for now
|
||||
|
||||
UINT8 stairjank;
|
||||
} player_t;
|
||||
|
||||
#endif
|
||||
+3
-1
@@ -81,10 +81,12 @@ typedef struct
|
||||
INT16 flags;
|
||||
INT16 special;
|
||||
INT16 tag;
|
||||
// sidenum[1] will be 0xffff if one sided
|
||||
// sidenum[1] will be NO_INDEX if one sided
|
||||
UINT16 sidenum[2];
|
||||
} ATTRPACK maplinedef_t;
|
||||
|
||||
#define NO_INDEX 0xffff
|
||||
|
||||
//
|
||||
// LineDef attributes.
|
||||
//
|
||||
|
||||
@@ -602,6 +602,13 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
// None of these that are disabled in the normal build are guaranteed to work perfectly
|
||||
// Compile them at your own risk!
|
||||
|
||||
// undefine to enable fixes and features that are not vanilla compatible
|
||||
#define COMPAT_VANILLA
|
||||
// if we build with 32 player (or more!) support we dont need to care vanilla compat
|
||||
#if MAXPLAYERS > 16
|
||||
#undef COMPAT_VANILLA
|
||||
#endif
|
||||
|
||||
//-- SATURN __
|
||||
/// Detect if a client is on Saturn in the clientconfig.
|
||||
/// To seperately allow them to join or block joining from vanilla clients.
|
||||
@@ -666,6 +673,13 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
#undef UPDATE_ALERT
|
||||
#endif
|
||||
|
||||
// overwrite some of those
|
||||
// when not compiling in vanilla compat mode
|
||||
#ifndef COMPAT_VANILLA
|
||||
#define SATURNJOIN
|
||||
#define SATURNPAK
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
+58
-53
@@ -447,7 +447,8 @@ void G_WriteDemoExtraData(void)
|
||||
{
|
||||
static UINT8 timeout = 0;
|
||||
|
||||
if (timeout) timeout--;
|
||||
if (timeout)
|
||||
timeout--;
|
||||
|
||||
if (demo_writerng == 1 || (demo_writerng == 2 && timeout == 0))
|
||||
{
|
||||
@@ -467,6 +468,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
||||
|
||||
if (!demobuf.p || !demo.deferstart)
|
||||
return;
|
||||
|
||||
ziptic = READUINT8(demobuf.p);
|
||||
|
||||
if (ziptic & ZT_FWD)
|
||||
@@ -488,11 +490,12 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
||||
|
||||
// what in the actual fuck is this???
|
||||
// SRB2kart: Copy-pasted from ticcmd building, removes that crappy demo cam
|
||||
if (((players[displayplayers[0]].mo && players[displayplayers[0]].speed > 0) // Moving
|
||||
const player_t *player = &players[displayplayers[0]];
|
||||
if (((player->mo && player->speed > 0) // Moving
|
||||
|| (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn
|
||||
|| (players[displayplayers[0]].kartstuff[k_respawn]) // Respawning
|
||||
|| (players[displayplayers[0]].spectator || objectplacing)) // Not a physical player
|
||||
&& !(players[displayplayers[0]].kartstuff[k_spinouttimer] && players[displayplayers[0]].kartstuff[k_sneakertimer])) // Spinning and boosting cancels out spinout
|
||||
|| (player->kartstuff[k_respawn]) // Respawning
|
||||
|| (player->spectator || objectplacing)) // Not a physical player
|
||||
&& !(player->kartstuff[k_spinouttimer] && player->kartstuff[k_sneakertimer])) // Spinning and boosting cancels out spinout
|
||||
localangle[0] += (cmd->angleturn<<16);
|
||||
|
||||
if (!(demoflags & DF_GHOST) && *demobuf.p == DEMOMARKER)
|
||||
@@ -1344,7 +1347,7 @@ fadeghost:
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z - FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK);
|
||||
mobj = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z - FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height, 3*FRACUNIT), MT_THOK);
|
||||
mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
|
||||
mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
|
||||
mobj->tics = -1; // nope.
|
||||
@@ -1518,7 +1521,9 @@ void G_PreviewRewind(tic_t previewtime)
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
player_t *player = &players[i];
|
||||
|
||||
if (!playeringame[i] || player->spectator)
|
||||
{
|
||||
if (info->playerinfo[i].player.mo)
|
||||
{
|
||||
@@ -1530,35 +1535,35 @@ void G_PreviewRewind(tic_t previewtime)
|
||||
|
||||
if (!info->playerinfo[i].ingame || !info->playerinfo[i].player.mo)
|
||||
{
|
||||
if (players[i].mo)
|
||||
players[i].mo->flags2 |= MF2_DONTDRAW;
|
||||
if (player->mo)
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!players[i].mo)
|
||||
if (!player->mo)
|
||||
continue; //@TODO spawn temp object to act as a player display
|
||||
|
||||
players[i].mo->flags2 &= ~MF2_DONTDRAW;
|
||||
player->mo->flags2 &= ~MF2_DONTDRAW;
|
||||
|
||||
P_UnsetThingPosition(players[i].mo);
|
||||
P_UnsetThingPosition(player->mo);
|
||||
#define TWEEN(pr) info->playerinfo[i].mobj.pr + FixedMul((INT32) (next_info->playerinfo[i].mobj.pr - info->playerinfo[i].mobj.pr), tweenvalue)
|
||||
players[i].mo->x = TWEEN(x);
|
||||
players[i].mo->y = TWEEN(y);
|
||||
players[i].mo->z = TWEEN(z);
|
||||
players[i].mo->angle = TWEEN(angle);
|
||||
player->mo->x = TWEEN(x);
|
||||
player->mo->y = TWEEN(y);
|
||||
player->mo->z = TWEEN(z);
|
||||
player->mo->angle = TWEEN(angle);
|
||||
#undef TWEEN
|
||||
P_SetThingPosition(players[i].mo);
|
||||
P_SetThingPosition(player->mo);
|
||||
|
||||
players[i].frameangle = info->playerinfo[i].player.frameangle + FixedMul((INT32) (next_info->playerinfo[i].player.frameangle - info->playerinfo[i].player.frameangle), tweenvalue);
|
||||
player->frameangle = info->playerinfo[i].player.frameangle + FixedMul((INT32) (next_info->playerinfo[i].player.frameangle - info->playerinfo[i].player.frameangle), tweenvalue);
|
||||
|
||||
players[i].mo->sprite = info->playerinfo[i].mobj.sprite;
|
||||
players[i].mo->frame = info->playerinfo[i].mobj.frame;
|
||||
player->mo->sprite = info->playerinfo[i].mobj.sprite;
|
||||
player->mo->frame = info->playerinfo[i].mobj.frame;
|
||||
|
||||
players[i].realtime = info->playerinfo[i].player.realtime;
|
||||
player->realtime = info->playerinfo[i].player.realtime;
|
||||
|
||||
for (j = 0; j < NUMKARTSTUFF; j++)
|
||||
players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j];
|
||||
player->kartstuff[j] = info->playerinfo[i].player.kartstuff[j];
|
||||
}
|
||||
|
||||
for (i = splitscreen; i >= 0; i--)
|
||||
@@ -1691,7 +1696,7 @@ void G_BeginRecording(void)
|
||||
return;
|
||||
}
|
||||
|
||||
memset(name,0,sizeof(name));
|
||||
memset(name, 0, sizeof(name));
|
||||
|
||||
demobuf.p = demobuf.buffer;
|
||||
demoflags = DF_GHOST|(multiplayer ? DF_MULTIPLAYER : (modeattacking<<DF_ATTACKSHIFT));
|
||||
@@ -1705,9 +1710,9 @@ void G_BeginRecording(void)
|
||||
|
||||
// Setup header.
|
||||
memcpy(demobuf.p, DEMOHEADER, 12); demobuf.p += 12;
|
||||
WRITEUINT8(demobuf.p,VERSION);
|
||||
WRITEUINT8(demobuf.p,SUBVERSION);
|
||||
WRITEUINT16(demobuf.p,DEMOVERSION);
|
||||
WRITEUINT8(demobuf.p, VERSION);
|
||||
WRITEUINT8(demobuf.p, SUBVERSION);
|
||||
WRITEUINT16(demobuf.p, DEMOVERSION);
|
||||
|
||||
// Full replay title
|
||||
demobuf.p += 64;
|
||||
@@ -1736,7 +1741,7 @@ void G_BeginRecording(void)
|
||||
|
||||
// game data
|
||||
memcpy(demobuf.p, "PLAY", 4); demobuf.p += 4;
|
||||
WRITEINT16(demobuf.p,gamemap);
|
||||
WRITEINT16(demobuf.p, gamemap);
|
||||
memcpy(demobuf.p, mapmd5, 16); demobuf.p += 16;
|
||||
|
||||
WRITEUINT8(demobuf.p, demoflags);
|
||||
@@ -1768,8 +1773,8 @@ void G_BeginRecording(void)
|
||||
break;
|
||||
case ATTACKING_RECORD: // 1
|
||||
demotime_p = demobuf.p;
|
||||
WRITEUINT32(demobuf.p,UINT32_MAX); // time
|
||||
WRITEUINT32(demobuf.p,UINT32_MAX); // lap
|
||||
WRITEUINT32(demobuf.p, UINT32_MAX); // time
|
||||
WRITEUINT32(demobuf.p, UINT32_MAX); // lap
|
||||
break;
|
||||
default: // 3
|
||||
break;
|
||||
@@ -1826,9 +1831,9 @@ void G_BeginRecording(void)
|
||||
if (demoflags & DF_LUAVARS)
|
||||
LUA_Archive(&demobuf, false);
|
||||
|
||||
memset(&oldcmd,0,sizeof(oldcmd));
|
||||
memset(&oldghost,0,sizeof(oldghost));
|
||||
memset(&ghostext,0,sizeof(ghostext));
|
||||
memset(&oldcmd, 0, sizeof(oldcmd));
|
||||
memset(&oldghost, 0, sizeof(oldghost));
|
||||
memset(&ghostext, 0, sizeof(ghostext));
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
@@ -1868,19 +1873,19 @@ void G_WriteStanding(UINT8 ranking, char *name, INT32 skinnum, UINT8 color, UINT
|
||||
// Name
|
||||
memset(temp, 0, 16);
|
||||
strncpy(temp, name, 16);
|
||||
memcpy(demobuf.p,temp,16);
|
||||
memcpy(demobuf.p, temp, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Skin
|
||||
memset(temp, 0, 16);
|
||||
strncpy(temp, skins[skinnum].name, 16);
|
||||
memcpy(demobuf.p,temp,16);
|
||||
memcpy(demobuf.p, temp, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Color
|
||||
memset(temp, 0, 16);
|
||||
strncpy(temp, KartColor_Names[color], 16);
|
||||
memcpy(demobuf.p,temp,16);
|
||||
memcpy(demobuf.p, temp, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Score/time/whatever
|
||||
@@ -2339,7 +2344,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
extrainfo_p += 16;
|
||||
|
||||
// Skin
|
||||
memcpy(temp,extrainfo_p,16);
|
||||
memcpy(temp, extrainfo_p, 16);
|
||||
extrainfo_p += 16;
|
||||
pdemo->standings[count].skin = UINT8_MAX;
|
||||
|
||||
@@ -2353,12 +2358,12 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
}
|
||||
|
||||
// Color
|
||||
memcpy(temp,extrainfo_p,16);
|
||||
memcpy(temp, extrainfo_p, 16);
|
||||
extrainfo_p += 16;
|
||||
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
{
|
||||
if (fasticmp(KartColor_Names[i],temp)) // SRB2kart
|
||||
if (fasticmp(KartColor_Names[i], temp)) // SRB2kart
|
||||
{
|
||||
pdemo->standings[count].color = i;
|
||||
break;
|
||||
@@ -2827,15 +2832,15 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
if (demo.version == 0x0001)
|
||||
{
|
||||
// Player name
|
||||
memcpy(player_names[0],demobuf.p,16);
|
||||
memcpy(player_names[0], demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Skin
|
||||
memcpy(skin,demobuf.p,16);
|
||||
memcpy(skin, demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Color
|
||||
memcpy(color,demobuf.p,16);
|
||||
memcpy(color, demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
demobuf.p += 5; // Backwards compat - some stats
|
||||
@@ -2868,7 +2873,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
// Set color
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
{
|
||||
if (fasticmp(KartColor_Names[i],color)) // SRB2kart
|
||||
if (fasticmp(KartColor_Names[i], color)) // SRB2kart
|
||||
{
|
||||
players[0].skincolor = i;
|
||||
break;
|
||||
@@ -2888,9 +2893,9 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&oldcmd,0,sizeof(oldcmd));
|
||||
memset(&oldghost,0,sizeof(oldghost));
|
||||
memset(&ghostext,0,sizeof(ghostext));
|
||||
memset(&oldcmd, 0, sizeof(oldcmd));
|
||||
memset(&oldghost, 0, sizeof(oldghost));
|
||||
memset(&ghostext, 0, sizeof(ghostext));
|
||||
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo version does not match game version. Desyncs may occur.\n"));
|
||||
|
||||
@@ -2994,16 +2999,16 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
players[p].spectator = spectator;
|
||||
|
||||
// Name
|
||||
memcpy(player_names[p],demobuf.p,16);
|
||||
memcpy(player_names[p], demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Skin
|
||||
memcpy(skin,demobuf.p,16);
|
||||
memcpy(skin, demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
SetPlayerSkin(p, skin);
|
||||
|
||||
// Color
|
||||
memcpy(color,demobuf.p,16);
|
||||
memcpy(color, demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
@@ -3221,15 +3226,15 @@ void G_AddGhost(char *defdemoname)
|
||||
if (ghostversion == 0x0001)
|
||||
{
|
||||
// Player name (TODO: Display this somehow if it doesn't match cv_playername!)
|
||||
memcpy(name, p,16);
|
||||
memcpy(name, p, 16);
|
||||
p += 16;
|
||||
|
||||
// Skin
|
||||
memcpy(skin, p,16);
|
||||
memcpy(skin, p, 16);
|
||||
p += 16;
|
||||
|
||||
// Color
|
||||
memcpy(color, p,16);
|
||||
memcpy(color, p, 16);
|
||||
p += 16;
|
||||
|
||||
// Ghosts do not have a player structure to put this in.
|
||||
@@ -3381,7 +3386,7 @@ void G_AddGhost(char *defdemoname)
|
||||
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
{
|
||||
if (fasticmp(KartColor_Names[i],color)) // SRB2kart
|
||||
if (fasticmp(KartColor_Names[i], color)) // SRB2kart
|
||||
{
|
||||
gh->mo->color = (UINT8)i;
|
||||
break;
|
||||
@@ -3473,7 +3478,7 @@ void G_UpdateStaffGhostName(lumpnum_t l)
|
||||
if (ghostversion == 0x0001)
|
||||
{
|
||||
// Player name
|
||||
memcpy(dummystaffname, p,16);
|
||||
memcpy(dummystaffname, p, 16);
|
||||
dummystaffname[16] = '\0';
|
||||
return; // Not really a failure but whatever
|
||||
}
|
||||
|
||||
+6
-2
@@ -857,7 +857,8 @@ static void G_HandleLocalDriftturn(ticcmd_t *cmd, UINT8 ssplayer)
|
||||
static void G_BuildLocalTiccmd(ticcmd_t *cmd, UINT8 ssplayer, boolean freecam)
|
||||
{
|
||||
INT32 axis = 0;
|
||||
const boolean usejoystick = cv_usejoystick[(ssplayer-1)].value;
|
||||
const UINT8 forplayer = (ssplayer-1);
|
||||
const boolean usejoystick = cv_usejoystick[forplayer].value;
|
||||
|
||||
// check for inputs and return button commands
|
||||
// for stuff like joining with item button, saltyhop, honking, etc.
|
||||
@@ -893,7 +894,7 @@ static void G_BuildLocalTiccmd(ticcmd_t *cmd, UINT8 ssplayer, boolean freecam)
|
||||
#undef CHECKINPUT
|
||||
|
||||
axis = JoyAxis(AXISLOOKBACK, ssplayer);
|
||||
camspin[ssplayer-1] = (InputDown(gc_lookback, ssplayer) || (usejoystick && axis > 0));
|
||||
camspin[forplayer] = (InputDown(gc_lookback, ssplayer) || (usejoystick && axis > 0));
|
||||
|
||||
// Reset to our spec player if we watch someone else.
|
||||
if ((cmd->driftturn || cmd->buttons)
|
||||
@@ -1309,6 +1310,7 @@ static void G_DoLoadLevel(boolean resetplayer)
|
||||
{
|
||||
// fail so reset game stuff
|
||||
Command_ExitGame_f();
|
||||
P_FreeCorruptMapWarnings();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1342,6 +1344,8 @@ static void G_DoLoadLevel(boolean resetplayer)
|
||||
|
||||
// clear hud messages remains (usually from game startup)
|
||||
CON_ClearHUD();
|
||||
// print any map errors now due to clearhud above :chaosleep:
|
||||
P_PrintCorruptMapWarnings();
|
||||
|
||||
server_lagless = !cv_gentlemens.value;
|
||||
|
||||
|
||||
+2
-1
@@ -118,10 +118,11 @@ extern consvar_t cv_driftsparkpulse;
|
||||
extern consvar_t cv_gravstretch;
|
||||
extern consvar_t cv_sloperoll;
|
||||
extern consvar_t cv_sliptideroll;
|
||||
extern consvar_t cv_stairjank;
|
||||
extern consvar_t cv_stairjanksfx;
|
||||
extern consvar_t cv_slamsound;
|
||||
extern consvar_t cv_sloperolldist;
|
||||
extern consvar_t cv_sparkroll;
|
||||
extern consvar_t cv_spinoutroll;
|
||||
|
||||
extern consvar_t cv_squishdance, cv_squishdancespeed;
|
||||
|
||||
|
||||
@@ -1139,6 +1139,12 @@ void G_DeviceRumbleTick(void)
|
||||
if (leveltime & 1) // this is actually funny lel
|
||||
high = RUMBLE_MODERATE;
|
||||
}
|
||||
/*else if ((player->stairjank > 8) // this is kinda cool but prob gets annoying after a while
|
||||
&& player->speed != 0
|
||||
&& P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
low = high = RUMBLE_WEAK;
|
||||
}*/
|
||||
|
||||
if (player->kartstuff[k_brakedrift])
|
||||
{
|
||||
|
||||
@@ -373,7 +373,7 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
|
||||
if (!gl_maphashorizonlines && line->special == HORIZONSPECIAL)
|
||||
gl_maphashorizonlines = true;
|
||||
|
||||
if (line->sidenum[1] != 0xffff)
|
||||
if (line->sidenum[1] != NO_INDEX)
|
||||
{
|
||||
if (sides[line->sidenum[0]].sector == sides[line->sidenum[1]].sector)
|
||||
{
|
||||
|
||||
@@ -729,7 +729,7 @@ static void HWR_PrecacheLevelTextures(void)
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
// check if single-sided linedef
|
||||
if (line->sidenum[j] == 0xffff)
|
||||
if (line->sidenum[j] == NO_INDEX)
|
||||
continue;
|
||||
|
||||
const side_t *side = &sides[line->sidenum[j]];
|
||||
|
||||
+131
-18
@@ -1001,8 +1001,9 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
const fixed_t v2y = FloatToFixed(wallVerts[1].z);
|
||||
|
||||
const UINT8 alpha = Surf->PolyColor.s.alpha;
|
||||
FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, gl_curline, NULL);
|
||||
FUINT lightnum = sector->lightlevel;
|
||||
extracolormap_t *colormap = NULL;
|
||||
lightnum = HWR_CalcWallLight(lightnum, gl_curline, NULL);
|
||||
|
||||
realtop = top = wallVerts[3].y;
|
||||
realbot = bot = wallVerts[0].y;
|
||||
@@ -1071,11 +1072,11 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
else
|
||||
solid = false;
|
||||
|
||||
height = FixedToFloat(P_GetLightZAt(&list[i], v1x, v1y));
|
||||
endheight = FixedToFloat(P_GetLightZAt(&list[i], v2x, v2y));
|
||||
|
||||
if (solid)
|
||||
{
|
||||
height = FixedToFloat(P_GetLightZAt(&list[i], v1x, v1y));
|
||||
endheight = FixedToFloat(P_GetLightZAt(&list[i], v2x, v2y));
|
||||
|
||||
bheight = FixedToFloat(P_GetFFloorBottomZAt(list[i].caster, v1x, v1y));
|
||||
endbheight = FixedToFloat(P_GetFFloorBottomZAt(list[i].caster, v2x, v2y));
|
||||
|
||||
@@ -1105,8 +1106,8 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
|
||||
// Found a break
|
||||
// The heights are clamped to ensure the polygon doesn't cross itself.
|
||||
bot = std::max(bheight, realbot);
|
||||
endbot = std::max(endbheight, endrealbot);
|
||||
bot = std::clamp(bheight, realbot, top);
|
||||
endbot = std::clamp(endbheight, endrealbot, endtop);
|
||||
|
||||
Surf->PolyColor.s.alpha = alpha;
|
||||
|
||||
@@ -2050,11 +2051,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
lightnum = HWR_CalcWallLight(lightnum, gl_curline, colormap);
|
||||
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(lightnum, colormap);
|
||||
|
||||
lightnum = HWR_CalcWallLight(lightnum, gl_curline, colormap);
|
||||
|
||||
if (other_sector->numlights)
|
||||
HWR_SplitWall(other_sector, wallVerts, 0, false, &Surf, roverflags, rover, blendmode);
|
||||
else
|
||||
@@ -3671,8 +3671,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
|
||||
// Found a break
|
||||
// The heights are clamped to ensure the polygon doesn't cross itself.
|
||||
bot = std::max(bheight, realbot);
|
||||
endbot = std::max(endbheight, endrealbot);
|
||||
bot = std::clamp(bheight, realbot, top);
|
||||
endbot = std::clamp(endbheight, endrealbot, endtop);
|
||||
|
||||
wallVerts[3].t = towtop + ((realtop - top) * towmult);
|
||||
wallVerts[2].t = towtop + ((endrealtop - endtop) * towmult);
|
||||
@@ -4630,7 +4630,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||
#ifdef ROTSPRITE
|
||||
// determine here if sprite should rotate for optimization
|
||||
const boolean sliprollrotate = (cv_sliptideroll.value && (thing->player && thing->player->sliproll));
|
||||
const boolean shouldrotate = (interp.sloperoll || interp.slopepitch || interp.roll || interp.pitch || thing->rollangle || sliprollrotate);
|
||||
const boolean shouldrotate = (interp.sloperoll || interp.slopepitch || interp.roll || interp.pitch || thing->rollangle || thing->temprollangle || sliprollrotate);
|
||||
#endif
|
||||
|
||||
if (sprframe->rotate != SRF_SINGLE || papersprite
|
||||
@@ -4688,7 +4688,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||
// this is very messy, but it on-the-fly calculates rotations for all the
|
||||
// pitch and roll variables
|
||||
pitchnroll = R_RotationAngle(ang, camang, &interp);
|
||||
rollangle = thing->rollangle;
|
||||
rollangle = (thing->rollangle - thing->temprollangle);
|
||||
|
||||
if (rollangle || pitchnroll || sliprollrotate)
|
||||
{
|
||||
@@ -5186,15 +5186,10 @@ void HWR_BuildSkyDome(void)
|
||||
// precompute to save a bit of division
|
||||
static constexpr float FINEDEGREE = (360.0f/static_cast<float>(FINEANGLES));
|
||||
|
||||
static void HWR_DrawSkyBackground(void)
|
||||
static void HWR_DrawSkyDome(void)
|
||||
{
|
||||
FTransform dometransform;
|
||||
|
||||
if (HWR_IsWireframeMode())
|
||||
return;
|
||||
|
||||
GL_SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||
|
||||
memcpy(&dometransform, &atransform, sizeof(FTransform));
|
||||
|
||||
dometransform.x = dometransform.y = dometransform.z = 0.0;
|
||||
@@ -5219,6 +5214,124 @@ static void HWR_DrawSkyBackground(void)
|
||||
GL_RenderSkyDome(&gl_sky);
|
||||
}
|
||||
|
||||
// the following is karts old sky code from before the skydome stuff
|
||||
// this appears to differ a bit from srb2´s old sky code
|
||||
static void HWR_DrawSkyTexture(void)
|
||||
{
|
||||
FOutVector v[4];
|
||||
angle_t angle;
|
||||
float dimensionmultiply;
|
||||
float aspectratio;
|
||||
float angleturn;
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture], false);
|
||||
|
||||
aspectratio = (float)vid.width/(float)vid.height;
|
||||
|
||||
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
|
||||
// because it's called just after clearing the screen
|
||||
// and thus, the near clipping plane is set to 3.99
|
||||
// Sryder: Just use the near clipping plane value then
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
v[0].x = v[3].x = -ZCLIP_PLANE-1;
|
||||
v[1].x = v[2].x = ZCLIP_PLANE+1;
|
||||
v[0].y = v[1].y = -ZCLIP_PLANE-1;
|
||||
v[2].y = v[3].y = ZCLIP_PLANE+1;
|
||||
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1;
|
||||
|
||||
// X
|
||||
|
||||
// NOTE: This doesn't work right with texture widths greater than 1024
|
||||
// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
|
||||
// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
|
||||
|
||||
//angle = (viewangle + ANGLE_45);
|
||||
angle = (viewangle + xtoviewangle[0]);
|
||||
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
|
||||
|
||||
if (atransform.fliptype == TRANSFORM_MIRROR ||
|
||||
atransform.fliptype == TRANSFORM_MIRRORFLIP)
|
||||
{
|
||||
angle = InvAngle(angle);
|
||||
dimensionmultiply *= -1;
|
||||
}
|
||||
|
||||
v[0].s = v[3].s = ((float)angle / ((float)(ANGLE_90-1)*dimensionmultiply));
|
||||
v[2].s = v[1].s = (-1.0f/dimensionmultiply)+((float) angle / ((float)(ANGLE_90-1)*dimensionmultiply));
|
||||
|
||||
// Y
|
||||
angle = aimingangle;
|
||||
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio));
|
||||
|
||||
if (splitscreen == 1)
|
||||
{
|
||||
dimensionmultiply *= 2;
|
||||
angle *= 2;
|
||||
}
|
||||
|
||||
// Middle of the sky should always be at angle 0
|
||||
// need to keep correct aspect ratio with X
|
||||
if (atransform.fliptype == TRANSFORM_FLIP ||
|
||||
atransform.fliptype == TRANSFORM_MIRRORFLIP)
|
||||
{
|
||||
// During vertical flip the sky should be flipped and it's y movement should also be flipped obviously
|
||||
v[3].t = v[2].t = -(0.5f-(0.5f/dimensionmultiply));
|
||||
v[0].t = v[1].t = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply));
|
||||
}
|
||||
else
|
||||
{
|
||||
v[3].t = v[2].t = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply));
|
||||
v[0].t = v[1].t = -(0.5f-(0.5f/dimensionmultiply));
|
||||
}
|
||||
|
||||
angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply;
|
||||
|
||||
if (cv_glshearing.value)
|
||||
{
|
||||
// Doesn't really make sense, but what can I do?
|
||||
angle_t dy = FixedAngle(FixedMul(360*FRACUNIT, FixedDiv(AIMINGTODY(aimingangle), 900*FRACUNIT)));
|
||||
v[3].t = v[2].t -= ((float) dy / angleturn);
|
||||
v[0].t = v[1].t -= ((float) dy / angleturn);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa
|
||||
{
|
||||
angle = InvAngle(angle);
|
||||
v[3].t = v[2].t += ((float) angle / angleturn);
|
||||
v[0].t = v[1].t += ((float) angle / angleturn);
|
||||
}
|
||||
else
|
||||
{
|
||||
v[3].t = v[2].t -= ((float) angle / angleturn);
|
||||
v[0].t = v[1].t -= ((float) angle / angleturn);
|
||||
}
|
||||
}
|
||||
|
||||
// since sky is drawn as a "flat quad" this way, we have to unset any view transformations for it to work
|
||||
GL_SetTransform(NULL);
|
||||
GL_UnSetShader();
|
||||
GL_DrawPolygon(NULL, v, 4, 0);
|
||||
}
|
||||
|
||||
static void HWR_DrawSkyBackground(void)
|
||||
{
|
||||
if (HWR_IsWireframeMode())
|
||||
return;
|
||||
|
||||
GL_SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||
|
||||
if (cv_skydome.value)
|
||||
HWR_DrawSkyDome();
|
||||
else
|
||||
HWR_DrawSkyTexture();
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// HWR_ClearView : clear the viewwindow, with maximum z value. also clears stencil buffer.
|
||||
// -----------------+
|
||||
|
||||
@@ -1400,12 +1400,11 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
|
||||
|
||||
const angle_t sliptideroll = ((cv_sliptideroll.value && spr->mobj->player) ? spr->mobj->player->sliproll : 0);
|
||||
const SINT8 flipfactor = flip ? -1 : 1;
|
||||
const angle_t thingrollangle = (spr->mobj->rollangle - spr->mobj->temprollangle);
|
||||
|
||||
if (spr->mobj->rollangle || sliptideroll)
|
||||
if (thingrollangle || sliptideroll)
|
||||
{
|
||||
angle_t rollang = sliptideroll
|
||||
? (spr->mobj->rollangle) + (sliptideroll * spr->mobj->player->kartstuff[k_aizdriftstrat])
|
||||
: (spr->mobj->rollangle);
|
||||
angle_t rollang = sliptideroll ? (thingrollangle + (sliptideroll * spr->mobj->player->kartstuff[k_aizdriftstrat])) : thingrollangle;
|
||||
|
||||
rollang *= flipfactor;
|
||||
|
||||
|
||||
@@ -2915,7 +2915,7 @@ void GL_CreateModelVBOs(model_t *model)
|
||||
}
|
||||
}
|
||||
|
||||
#define BUFFER_OFFSET(i) ((char*)(i))
|
||||
#define BUFFER_OFFSET(i) ((void*)(i))
|
||||
|
||||
void GL_DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
{
|
||||
|
||||
+102
-37
@@ -117,6 +117,11 @@ static void HU_DrawRankings(void);
|
||||
|
||||
consvar_t cv_showspecstuff = {"showspecstuff", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// stuff from SRB2-Banpyura thx alot! :3
|
||||
consvar_t cv_chat_xoffset = {"chat_xoffset", "0", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_chat_yoffset = {"chat_yoffset", "0", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_chat_showlimit = {"chat_showlimit", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static char cechotext[1024];
|
||||
static tic_t cechotimer = 0;
|
||||
static tic_t cechoduration = 5*TICRATE;
|
||||
@@ -966,7 +971,7 @@ void HU_Ticker(void)
|
||||
size_t i = 0;
|
||||
|
||||
// handle spam while we're at it:
|
||||
for(; (i < MAXPLAYERS); i++)
|
||||
for (; (i < MAXPLAYERS); i++)
|
||||
{
|
||||
if (stop_spamming[i] > 0)
|
||||
stop_spamming[i]--;
|
||||
@@ -1135,6 +1140,7 @@ static void HU_SendChatMessage(void)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// I'm very bad at C, I swear I am, additional checks eww!
|
||||
if (spc != 0)
|
||||
{
|
||||
@@ -1369,7 +1375,12 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
|
||||
// 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense.
|
||||
|
||||
INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh
|
||||
// let's use this as our coordinates, shh
|
||||
// :chao: guess this just works lol
|
||||
#define chatx ((INT16)(13 + (cv_chat_xoffset.value)))
|
||||
#define chaty ((INT16)(169 + (cv_chat_yoffset.value)))
|
||||
|
||||
#define CHATSNAP (V_SNAPTOBOTTOM|V_SNAPTOLEFT)
|
||||
|
||||
// chat stuff by VincyTM LOL XD!
|
||||
|
||||
@@ -1396,7 +1407,7 @@ static void HU_drawMiniChat(void)
|
||||
|
||||
for (; i > 0; i--)
|
||||
{
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), CHATSNAP|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||
size_t j = 0;
|
||||
INT32 linescount = 0;
|
||||
emote_t *emote = NULL;
|
||||
@@ -1456,6 +1467,7 @@ static void HU_drawMiniChat(void)
|
||||
if (splitscreen)
|
||||
{
|
||||
y -= BASEVIDHEIGHT/2;
|
||||
|
||||
if (splitscreen > 1)
|
||||
y += 16;
|
||||
}
|
||||
@@ -1473,7 +1485,7 @@ static void HU_drawMiniChat(void)
|
||||
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
|
||||
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
|
||||
size_t j = 0;
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), CHATSNAP|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
@@ -1506,9 +1518,9 @@ static void HU_drawMiniChat(void)
|
||||
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
|
||||
{
|
||||
if (cv_chatbacktint.value) // on request of wolfy
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, EMOTEWIDTH, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, EMOTEWIDTH, charheight, 239|CHATSNAP);
|
||||
|
||||
M_DrawEmote(x+dx+2, y+dy, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag);
|
||||
M_DrawEmote(x+dx+2, y+dy, emote, CHATSNAP|transflag);
|
||||
dx += EMOTEWIDTH - charwidth;
|
||||
|
||||
j += emotelen;
|
||||
@@ -1516,9 +1528,9 @@ static void HU_drawMiniChat(void)
|
||||
else
|
||||
{
|
||||
if (cv_chatbacktint.value) // on request of wolfy
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|CHATSNAP);
|
||||
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+cv_chatcentertext.value, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap);
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+cv_chatcentertext.value, msg[j++] |CHATSNAP|transflag, !cv_allcaps.value, colormap);
|
||||
}
|
||||
|
||||
dx += charwidth;
|
||||
@@ -1579,13 +1591,13 @@ static void HU_drawChatLog(INT32 offset)
|
||||
chat_topy = y + chat_scroll*charheight;
|
||||
chat_bottomy = chat_topy + boxh*charheight;
|
||||
|
||||
V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box
|
||||
V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|CHATSNAP); // log box
|
||||
|
||||
for (i = 0; i < chat_nummsg_log; i++) // iterate through our chatlog
|
||||
{
|
||||
INT32 clrflag = 0;
|
||||
INT32 j = 0;
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), CHATSNAP|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
@@ -1615,7 +1627,7 @@ static void HU_drawChatLog(INT32 offset)
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
{
|
||||
M_DrawEmote(x+dx+2, y+dy+1, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
M_DrawEmote(x+dx+2, y+dy+1, emote, CHATSNAP);
|
||||
dx += EMOTEWIDTH - charwidth;
|
||||
}
|
||||
j += emotelen;
|
||||
@@ -1623,7 +1635,7 @@ static void HU_drawChatLog(INT32 offset)
|
||||
else
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, colormap);
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |CHATSNAP, !cv_allcaps.value, colormap);
|
||||
else
|
||||
j++; // don't forget to increment this or we'll get stuck in the limbo.
|
||||
}
|
||||
@@ -1660,9 +1672,9 @@ static void HU_drawChatLog(INT32 offset)
|
||||
|
||||
// draw arrows to indicate that we can (or not) scroll.
|
||||
if (chat_scroll > 0)
|
||||
V_DrawCharacter(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1A', false); // up arrow
|
||||
V_DrawCharacter(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), CHATSNAP | highlight | '\x1A', false); // up arrow
|
||||
if (chat_scroll < chat_maxscroll)
|
||||
V_DrawCharacter(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1B', false); // down arrow
|
||||
V_DrawCharacter(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), CHATSNAP | highlight | '\x1B', false); // down arrow
|
||||
|
||||
justscrolleddown = false;
|
||||
justscrolledup = false;
|
||||
@@ -1680,6 +1692,7 @@ static void HU_DrawChat(void)
|
||||
INT32 boxw = cv_chatwidth.value;
|
||||
INT32 t = 0, c = 0, y = chaty - (typelines*charheight);
|
||||
UINT32 i = 0, saylen = strlen(w_chat_buf); // You learn new things everyday!
|
||||
UINT32 charcount = 0;
|
||||
INT32 cflag = 0;
|
||||
INT32 pm_offset = 0; // for cases when you type emote while also doing /pm
|
||||
size_t select_start = 0, select_end = 0;
|
||||
@@ -1711,7 +1724,7 @@ static void HU_DrawChat(void)
|
||||
cflag = V_GRAYMAP; // set text in gray if chat is muted.
|
||||
}
|
||||
|
||||
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
|
||||
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | CHATSNAP);
|
||||
|
||||
while (talk[i])
|
||||
{
|
||||
@@ -1719,7 +1732,7 @@ static void HU_DrawChat(void)
|
||||
++i;
|
||||
else
|
||||
{
|
||||
V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, !cv_allcaps.value, V_GetStringColormap(talk[i]|cflag));
|
||||
V_DrawChatCharacter(chatx + c + 2, y, talk[i] |CHATSNAP|cflag, !cv_allcaps.value, V_GetStringColormap(talk[i]|cflag));
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -1737,7 +1750,7 @@ static void HU_DrawChat(void)
|
||||
typelines = 1;
|
||||
|
||||
if ((w_chat.cursor == 0 || w_chat.length == 0) && hu_tick < 4)
|
||||
V_DrawChatCharacter(chatx+2+c, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
V_DrawChatCharacter(chatx+2+c, y+1, '_'|CHATSNAP|t, !cv_allcaps.value, NULL);
|
||||
|
||||
if (w_chat.select != w_chat.cursor)
|
||||
{
|
||||
@@ -1754,17 +1767,23 @@ static void HU_DrawChat(void)
|
||||
|
||||
if ((emote = M_VerifyEmote(w_chat_buf+i, &emotelen)))
|
||||
{
|
||||
M_DrawEmote(chatx + c + 2, y-1, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
|
||||
M_DrawEmote(chatx + c + 2, y-1, emote, CHATSNAP|t);
|
||||
c += EMOTEWIDTH - charwidth;
|
||||
i += emotelen-1;
|
||||
drawwidth = EMOTEWIDTH;
|
||||
if (cv_chat_showlimit.value)
|
||||
charcount += emotelen;
|
||||
}
|
||||
else if (w_chat_buf[i] >= HU_FONTSTART) //Hurdler: isn't it better like that?
|
||||
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
|
||||
{
|
||||
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | CHATSNAP | t, !cv_allcaps.value, NULL);
|
||||
if (cv_chat_showlimit.value)
|
||||
charcount++;
|
||||
}
|
||||
|
||||
// Draw selection
|
||||
if (i >= select_start && i < select_end)
|
||||
V_DrawFill(chatx + c + 2 - (drawwidth-charwidth), y-1, drawwidth, charheight, 103|V_TRANSLUCENT|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
|
||||
V_DrawFill(chatx + c + 2 - (drawwidth-charwidth), y-1, drawwidth, charheight, 103|V_TRANSLUCENT|CHATSNAP|t);
|
||||
|
||||
++i;
|
||||
|
||||
@@ -1773,7 +1792,7 @@ static void HU_DrawChat(void)
|
||||
INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
|
||||
INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
|
||||
if (hu_tick < 4)
|
||||
V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
V_DrawChatCharacter(cursorx, cursory+1, '_' |CHATSNAP|t, !cv_allcaps.value, NULL);
|
||||
|
||||
if (cursorx == chatx+1 && saylen == i-1) // a weirdo hack
|
||||
{
|
||||
@@ -1791,6 +1810,13 @@ static void HU_DrawChat(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (cv_chat_showlimit.value)
|
||||
{
|
||||
// Limit
|
||||
const INT32 clr = ((HU_MAXMSGLEN - charcount) > 64 ? V_TRANSLUCENT : (charcount == HU_MAXMSGLEN ? V_REDMAP : V_YELLOWMAP));
|
||||
V_DrawSmallString(chatx, y+7, CHATSNAP|clr, va("%d/%d", charcount, HU_MAXMSGLEN));
|
||||
}
|
||||
|
||||
// handle /pm list. It's messy, horrible and I don't care.
|
||||
if (strnicmp(w_chat_buf, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
|
||||
{
|
||||
@@ -1826,6 +1852,7 @@ static void HU_DrawChat(void)
|
||||
{
|
||||
char nodenum[3];
|
||||
UINT32 n;
|
||||
|
||||
// right, that's half important: (w_chat_buf[4] may be a space since /pm0 msg is perfectly acceptable!)
|
||||
if (!isdigit(w_chat_buf[3]) || !(isdigit(w_chat_buf[4]) || (w_chat_buf[4] == ' ') || (w_chat_buf[4] == 0)))
|
||||
break;
|
||||
@@ -1863,17 +1890,17 @@ static void HU_DrawChat(void)
|
||||
}
|
||||
|
||||
// fill it like the chat so the text doesn't become hard to read because of the hud.
|
||||
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), (longest_name_length+4)*4, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
|
||||
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), (longest_name_length+4)*4, 6, 239 | CHATSNAP);
|
||||
|
||||
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, player_names[i]));
|
||||
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), CHATSNAP|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, player_names[i]));
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0) // no results.
|
||||
{
|
||||
pm_offset = 48 + 2;
|
||||
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud.
|
||||
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, "NO RESULT.");
|
||||
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), 48, 6, 239 | CHATSNAP); // fill it like the chat so the text doesn't become hard to read because of the hud.
|
||||
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), CHATSNAP|V_ALLOWLOWERCASE, "NO RESULT.");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1925,15 +1952,15 @@ static void HU_DrawChat(void)
|
||||
|
||||
while ((suggest = M_FindEmote(complete, complete_len, skip)) != NULL)
|
||||
{
|
||||
V_DrawFillConsoleMap(chatx + boxw + pm_offset + 2, suggesty - (7*skip), emote_suggest_boxw, 6, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
V_DrawFillConsoleMap(chatx + boxw + pm_offset + 2, suggesty - (7*skip), emote_suggest_boxw, 6, CHATSNAP);
|
||||
|
||||
// Highlight currently suggested emote
|
||||
int hlflag = 0;
|
||||
if (skip == emote_autocomplete.skip && emote_autocomplete.complete[0])
|
||||
hlflag = V_YELLOWMAP;
|
||||
|
||||
V_DrawSmallString(chatx + boxw + pm_offset + 4 + EMOTEWIDTH, suggesty - (7*skip), hlflag|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va(":%s:", suggest->name));
|
||||
M_DrawEmote(chatx + boxw + pm_offset + 2, suggesty - skip*7, suggest, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
V_DrawSmallString(chatx + boxw + pm_offset + 4 + EMOTEWIDTH, suggesty - (7*skip), hlflag|CHATSNAP|V_ALLOWLOWERCASE, va(":%s:", suggest->name));
|
||||
M_DrawEmote(chatx + boxw + pm_offset + 2, suggesty - skip*7, suggest, CHATSNAP);
|
||||
|
||||
++skip;
|
||||
}
|
||||
@@ -1947,6 +1974,7 @@ static void HU_DrawChat(void)
|
||||
static void HU_DrawChat_Old(void)
|
||||
{
|
||||
INT32 t = 0, c = 0, y = HU_INPUTY;
|
||||
UINT32 charcount = 0;
|
||||
size_t i = 0;
|
||||
const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
|
||||
const char *talk = ntalk;
|
||||
@@ -1992,11 +2020,17 @@ static void HU_DrawChat_Old(void)
|
||||
{
|
||||
M_DrawScaledEmote((HU_INPUTX + c)<<FRACBITS, (y+con_scalefactor*2)<<FRACBITS, charwidth*FRACUNIT/EMOTEWIDTH, emote, V_NOSCALESTART | V_NOSCALEPATCH | t);
|
||||
i += emotelen-1;
|
||||
|
||||
if (cv_chat_showlimit.value)
|
||||
charcount += emotelen;
|
||||
}
|
||||
else if (w_chat_buf[i] >= HU_FONTSTART) //Hurdler: isn't it better like that?
|
||||
{
|
||||
//charwidth = hu_font[w_chat[i]-HU_FONTSTART]->width * con_scalefactor;
|
||||
V_DrawCharacter(HU_INPUTX + c, y, w_chat_buf[i] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
|
||||
|
||||
if (cv_chat_showlimit.value)
|
||||
charcount++;
|
||||
}
|
||||
|
||||
// Draw selection
|
||||
@@ -2009,7 +2043,7 @@ static void HU_DrawChat_Old(void)
|
||||
{
|
||||
INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down.
|
||||
INT32 cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight);
|
||||
V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value);
|
||||
V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' | cv_constextsize.value | V_NOSCALESTART |t, !cv_allcaps.value);
|
||||
}
|
||||
|
||||
c += charwidth;
|
||||
@@ -2019,6 +2053,24 @@ static void HU_DrawChat_Old(void)
|
||||
y += charheight;
|
||||
}
|
||||
}
|
||||
|
||||
// console chat users are FINALLY being fed!
|
||||
if (cv_chat_showlimit.value)
|
||||
{
|
||||
const char *lim = va(" (%i/%i)", charcount, HU_MAXMSGLEN);
|
||||
for (i = 0; lim[i]; i++)
|
||||
{
|
||||
V_DrawCharacter(HU_INPUTX + c, y, lim[i] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
|
||||
|
||||
c += charwidth;
|
||||
if (c >= vid.width) // text wrapping
|
||||
{
|
||||
c = 0;
|
||||
y += charheight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void HU_DrawCEcho(void)
|
||||
@@ -2239,7 +2291,22 @@ void HU_DrawSongCredits(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void HU_ForceShowChat(void)
|
||||
{
|
||||
// only matters for non console chat
|
||||
// see m_menu for how forceshowchat is set
|
||||
if (!chat_on && forceshowchat)
|
||||
{
|
||||
// only print this if theres nothing in chat already
|
||||
if (chat_nummsg_log == 0)
|
||||
{
|
||||
HU_AddChatText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", false);
|
||||
}
|
||||
|
||||
HU_DrawChat();
|
||||
}
|
||||
}
|
||||
|
||||
// Heads up displays drawer, call each frame
|
||||
//
|
||||
void HU_Drawer(void)
|
||||
@@ -2247,6 +2314,8 @@ void HU_Drawer(void)
|
||||
if (cv_vhseffect.value && ((paused && !camera[R_GetViewNumber()].freecam) || (demo.playback && cv_playbackspeed.value > 1)))
|
||||
V_DrawVhsEffect(demo.rewinding);
|
||||
|
||||
HU_ForceShowChat();
|
||||
|
||||
// draw chat string plus cursor
|
||||
if (chat_on)
|
||||
{
|
||||
@@ -2326,8 +2395,7 @@ void HU_Drawer(void)
|
||||
// IN-LEVEL MULTIPLAYER RANKINGS
|
||||
//======================================================================
|
||||
|
||||
static int
|
||||
Ping_gfx_num (int lag)
|
||||
static int Ping_gfx_num(int lag)
|
||||
{
|
||||
if (lag < 2)
|
||||
return 0;
|
||||
@@ -2341,8 +2409,7 @@ Ping_gfx_num (int lag)
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int
|
||||
Ping_gfx_color (UINT32 lag)
|
||||
static int Ping_gfx_color(UINT32 lag)
|
||||
{
|
||||
if (lag < 2)
|
||||
return SKINCOLOR_JAWZ;
|
||||
@@ -2365,8 +2432,7 @@ Ping_gfx_color (UINT32 lag)
|
||||
return SKINCOLOR_WHITE; // to make the flashing work
|
||||
}
|
||||
|
||||
static const UINT8 *
|
||||
Ping_gfx_colormap (UINT32 lag, boolean gentleman)
|
||||
static const UINT8 *Ping_gfx_colormap(UINT32 lag, boolean gentleman)
|
||||
{
|
||||
const UINT8 *colormap = NULL;
|
||||
|
||||
@@ -2386,8 +2452,7 @@ Ping_gfx_colormap (UINT32 lag, boolean gentleman)
|
||||
return colormap;
|
||||
}
|
||||
|
||||
static UINT32
|
||||
Ping_conversion (UINT32 lag)
|
||||
static UINT32 Ping_conversion(UINT32 lag)
|
||||
{
|
||||
if (cv_pingmeasurement.value)
|
||||
{
|
||||
|
||||
@@ -88,6 +88,10 @@ extern patch_t *tallminus;
|
||||
// set true whenever the tab rankings are being shown for any reason
|
||||
extern boolean hu_showscores;
|
||||
|
||||
extern consvar_t cv_chat_xoffset;
|
||||
extern consvar_t cv_chat_yoffset;
|
||||
extern consvar_t cv_chat_showlimit;
|
||||
|
||||
// init heads up data at game startup.
|
||||
void HU_Init(void);
|
||||
|
||||
|
||||
@@ -452,7 +452,11 @@ void A_SpawnFreshCopy(void *actor);
|
||||
extern boolean actionsoverridden[NUMACTIONS];
|
||||
|
||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||
#ifdef COMPAT_VANILLA
|
||||
#define NUMMOBJFREESLOTS 1024
|
||||
#else
|
||||
#define NUMMOBJFREESLOTS 4096 // should be sufficient
|
||||
#endif
|
||||
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
|
||||
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
|
||||
|
||||
|
||||
+11
-4
@@ -98,6 +98,8 @@ consvar_t cv_showminimapfinished = {"showminimapfinished", "On", CV_SAVE, CV_OnO
|
||||
CV_PossibleValue_t minimapdot_cons_t[NUMMINIMAPDOTSTUFF];
|
||||
consvar_t cv_showminimapangle = {"showminimapangle", "Off", CV_SAVE, minimapdot_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_spinoutroll = {"spinoutroll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t posanim_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}};
|
||||
consvar_t cv_posanim = {"postitionanimation", "On", CV_SAVE, posanim_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_smallposnum = {"smallpositionnumber", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -231,6 +233,7 @@ void K_RegisterKartHudStuff(void)
|
||||
CV_RegisterVar(&cv_showminimapnames);
|
||||
CV_RegisterVar(&cv_showminimapfinished);
|
||||
CV_RegisterVar(&cv_showminimapangle);
|
||||
CV_RegisterVar(&cv_spinoutroll);
|
||||
|
||||
CV_RegisterVar(&cv_showlapemblem);
|
||||
|
||||
@@ -1143,7 +1146,7 @@ enum
|
||||
SPEEDO_PMETERSMOL,
|
||||
};
|
||||
|
||||
static SINT8 K_GetSpeedometerStyle(void)
|
||||
static UINT8 K_GetSpeedometerStyle(void)
|
||||
{
|
||||
if (cv_newspeedometer.value == 2 && xtra_speedo)
|
||||
return SPEEDO_EXTRA;
|
||||
@@ -4394,6 +4397,9 @@ static void K_drawChallengerScreen(void)
|
||||
|
||||
static void K_drawLapStartAnim(void)
|
||||
{
|
||||
if (!cv_showlapemblem.value)
|
||||
return;
|
||||
|
||||
// This is an EVEN MORE insanely complicated animation.
|
||||
const UINT8 progress = 80-stplyr->kartstuff[k_lapanimation];
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
|
||||
@@ -4437,9 +4443,10 @@ static void K_drawLapStartAnim(void)
|
||||
V_DrawFixedPatch(leftx, y, FRACUNIT, vflags, kp_lapanim_lap[min(progress/2, 6)], NULL);
|
||||
|
||||
char *lapnum = va("%02d", stplyr->laps + 1);
|
||||
const size_t laplength = strlen(lapnum);
|
||||
|
||||
for (size_t i = 0; i < laplength; i++)
|
||||
const int laplength = (int)strlen(lapnum);
|
||||
|
||||
for (int i = 0; i < laplength; i++)
|
||||
{
|
||||
int digit = lapnum[i] - '0';
|
||||
int frame = min(2, progress/2 - 8 - (i*2));
|
||||
@@ -4821,7 +4828,7 @@ void K_drawKartHUD(void)
|
||||
{
|
||||
if (stplyr->exiting)
|
||||
K_drawKartFinish();
|
||||
else if (stplyr->kartstuff[k_lapanimation] && !splitscreen && cv_showlapemblem.value)
|
||||
else if (stplyr->kartstuff[k_lapanimation] && !splitscreen)
|
||||
K_drawLapStartAnim();
|
||||
}
|
||||
|
||||
|
||||
+107
-52
@@ -67,7 +67,8 @@ static CV_PossibleValue_t sloperoll_cons_t[] = {{0, "Off"}, {1, "Players"}, {2,
|
||||
consvar_t cv_sloperoll = {"sloperoll", "Off", CV_SAVE|CV_CALL, sloperoll_cons_t, PDistort_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_sparkroll = {"sparkroll", "Off", CV_SAVE|CV_CALL, CV_OnOff, PDistort_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_sliptideroll = {"sliptideroll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_spinoutroll = {"spinoutroll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_stairjank = {"stairjank", "Off", CV_SAVE|CV_CALL, CV_OnOff, PDistort_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_stairjanksfx = {"stairjanksfx", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
//hardcode saltyhop mhhm
|
||||
static void saltyhop_onchange(void);
|
||||
@@ -3511,6 +3512,36 @@ boolean K_ShouldSlopeRoll(mobj_t *mobj)
|
||||
return K_CheckSlopeRollDist(mobj);
|
||||
}
|
||||
|
||||
static INT32 K_AltFlip(INT32 n, tic_t tics)
|
||||
{
|
||||
return leveltime % (2 * tics) < tics ? n : -(n);
|
||||
}
|
||||
|
||||
static INT32 K_StairJankFlip(INT32 value)
|
||||
{
|
||||
return K_AltFlip(value, 2);
|
||||
}
|
||||
|
||||
// reset banan and eggbox rollangle when they´re on the ground
|
||||
// if not cv_bananthrowroll option "+Onground"
|
||||
static void K_ResetBananaRollangle(mobj_t* mo)
|
||||
{
|
||||
if (cv_bananthrowroll.value != 1)
|
||||
return;
|
||||
|
||||
if (!mo->rollangle)
|
||||
return;
|
||||
|
||||
if (mo->type != MT_BANANA && mo->type != MT_EGGMANITEM)
|
||||
return;
|
||||
|
||||
// only reset if on ground
|
||||
if (!P_IsObjectOnGround(mo))
|
||||
return;
|
||||
|
||||
mo->rollangle = 0;
|
||||
}
|
||||
|
||||
#define SLOPEROLL_DIV 3
|
||||
void K_RollMobjBySlopes(mobj_t* mo, pslope_t *slope)
|
||||
{
|
||||
@@ -3524,6 +3555,9 @@ void K_RollMobjBySlopes(mobj_t* mo, pslope_t *slope)
|
||||
I_Assert(mo->subsector != NULL);
|
||||
I_Assert(mo->subsector->sector != NULL);
|
||||
|
||||
// kinda stupid but idk where else to put this
|
||||
K_ResetBananaRollangle(mo);
|
||||
|
||||
if (!K_ShouldSlopeRoll(mo))
|
||||
{
|
||||
mo->pitch_sprite = mo->roll_sprite = 0;
|
||||
@@ -3945,11 +3979,9 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
|
||||
|
||||
if (cv_bananthrowroll.value && (mapthing == MT_BANANA))
|
||||
{
|
||||
//mo->angle = FixedAngle(M_RandomRange(-180, 180) << FRACBITS);
|
||||
if (cv_bananthrowroll.value == 1 && K_CheckSlopeRollDist(mo))
|
||||
mo->sloperoll = (angle_t)FixedAngle(M_RandomRange(-180, 180) << FRACBITS); // im lazy but this makes sure the banan goes back to upright when it lands lmao
|
||||
else if (cv_bananthrowroll.value == 2)
|
||||
mo->rollangle = (angle_t)FixedAngle(M_RandomRange(-180, 180) << FRACBITS);
|
||||
const angle_t speen = (angle_t)FixedAngle(M_RandomRange(-180, 180) << FRACBITS);
|
||||
//mo->angle = speen;
|
||||
mo->rollangle = speen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4559,50 +4591,59 @@ void K_DropHnextList(player_t *player)
|
||||
P_RemoveMobj(work);
|
||||
}
|
||||
|
||||
{
|
||||
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
|
||||
P_SetTarget(&player->mo->hnext, NULL);
|
||||
player->kartstuff[k_bananadrag] = 0;
|
||||
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
|
||||
P_SetTarget(&player->mo->hnext, NULL);
|
||||
player->kartstuff[k_bananadrag] = 0;
|
||||
|
||||
if (player->kartstuff[k_eggmanheld])
|
||||
player->kartstuff[k_eggmanheld] = 0;
|
||||
else if (player->kartstuff[k_itemheld]
|
||||
&& (dropall || (--player->kartstuff[k_itemamount] <= 0)))
|
||||
{
|
||||
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
|
||||
player->kartstuff[k_itemtype] = KITEM_NONE;
|
||||
}
|
||||
if (player->kartstuff[k_eggmanheld])
|
||||
player->kartstuff[k_eggmanheld] = 0;
|
||||
else if (player->kartstuff[k_itemheld]
|
||||
&& (dropall || (--player->kartstuff[k_itemamount] <= 0)))
|
||||
{
|
||||
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
|
||||
player->kartstuff[k_itemtype] = KITEM_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void K_DropPaperItem(player_t *player, boolean thunderhack, INT32 itemamount)
|
||||
{
|
||||
const mobj_t *pmo = player->mo;
|
||||
|
||||
if (P_MobjWasRemoved(pmo))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mobj_t *drop = P_SpawnMobj(pmo->x, pmo->y, (pmo->z + pmo->height/2), MT_FLOATINGITEM);
|
||||
P_SetScale(drop, drop->scale>>4);
|
||||
|
||||
drop->destscale = (3*drop->destscale)/2;
|
||||
|
||||
drop->angle = pmo->angle + ANGLE_90;
|
||||
P_Thrust(drop, FixedAngle(P_RandomFixed()*180) + pmo->angle + ANGLE_90, 16*mapobjectscale);
|
||||
drop->momz = P_MobjFlip(pmo)*3*mapobjectscale;
|
||||
if (drop->eflags & MFE_UNDERWATER)
|
||||
drop->momz = (117 * drop->momz) / 200;
|
||||
|
||||
drop->threshold = (thunderhack ? KITEM_THUNDERSHIELD : player->kartstuff[k_itemtype]);
|
||||
drop->movecount = itemamount;
|
||||
|
||||
drop->flags |= MF_NOCLIPTHING;
|
||||
}
|
||||
|
||||
// For getting EXTRA hit!
|
||||
void K_DropItems(player_t *player)
|
||||
{
|
||||
boolean thunderhack = (player->kartstuff[k_curshield] && player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD);
|
||||
const boolean thunderhack = (player->kartstuff[k_curshield] && player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD);
|
||||
|
||||
if (thunderhack)
|
||||
player->kartstuff[k_itemtype] = KITEM_NONE;
|
||||
|
||||
K_DropHnextList(player);
|
||||
|
||||
if (!P_MobjWasRemoved(player->mo) && player->kartstuff[k_itemamount])
|
||||
if (player->kartstuff[k_itemamount])
|
||||
{
|
||||
mobj_t *drop = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FLOATINGITEM);
|
||||
P_SetScale(drop, drop->scale>>4);
|
||||
drop->destscale = (3*drop->destscale)/2;
|
||||
|
||||
drop->angle = player->mo->angle + ANGLE_90;
|
||||
P_Thrust(drop,
|
||||
FixedAngle(P_RandomFixed()*180) + player->mo->angle + ANGLE_90,
|
||||
16*mapobjectscale);
|
||||
drop->momz = P_MobjFlip(player->mo)*3*mapobjectscale;
|
||||
if (drop->eflags & MFE_UNDERWATER)
|
||||
drop->momz = (117 * drop->momz) / 200;
|
||||
|
||||
drop->threshold = (thunderhack ? KITEM_THUNDERSHIELD : player->kartstuff[k_itemtype]);
|
||||
drop->movecount = player->kartstuff[k_itemamount];
|
||||
|
||||
drop->flags |= MF_NOCLIPTHING;
|
||||
K_DropPaperItem(player, thunderhack, player->kartstuff[k_itemamount]);
|
||||
}
|
||||
|
||||
K_StripItems(player);
|
||||
@@ -4620,7 +4661,7 @@ void K_DropRocketSneaker(player_t *player)
|
||||
while ((shoe = shoe->hnext) && !P_MobjWasRemoved(shoe))
|
||||
{
|
||||
if (shoe->type != MT_ROCKETSNEAKER)
|
||||
return; //woah, not a rocketsneaker, bail! safeguard in case this gets used when you're holding non-rocketsneakers
|
||||
return; // woah, not a rocketsneaker, bail! safeguard in case this gets used when you're holding non-rocketsneakers
|
||||
|
||||
shoe->flags2 &= ~MF2_DONTDRAW;
|
||||
shoe->flags &= ~MF_NOGRAVITY;
|
||||
@@ -4658,7 +4699,7 @@ void K_DropKitchenSink(player_t *player)
|
||||
return;
|
||||
|
||||
if (player->mo->hnext->type != MT_SINK_SHIELD)
|
||||
return; //so we can just call this function regardless of what is being held
|
||||
return; // so we can just call this function regardless of what is being held
|
||||
|
||||
P_KillMobj(player->mo->hnext, NULL, NULL);
|
||||
|
||||
@@ -4684,9 +4725,12 @@ void K_RepairOrbitChain(mobj_t *orbit)
|
||||
}
|
||||
|
||||
// Then recount to make sure item amount is correct
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (!P_MobjWasRemoved(orbit->target) && orbit->target->player)
|
||||
#else
|
||||
if (orbit->target && orbit->target->player)
|
||||
#endif
|
||||
{
|
||||
player_t *player = orbit->target->player;
|
||||
INT32 num = 0;
|
||||
|
||||
mobj_t *cur = orbit->target->hnext;
|
||||
@@ -4696,13 +4740,18 @@ void K_RepairOrbitChain(mobj_t *orbit)
|
||||
{
|
||||
prev = cur;
|
||||
cur = cur->hnext;
|
||||
if (++num > player->kartstuff[k_itemamount])
|
||||
if (++num > orbit->target->player->kartstuff[k_itemamount])
|
||||
P_RemoveMobj(prev);
|
||||
else
|
||||
prev->movedir = num;
|
||||
}
|
||||
|
||||
player->kartstuff[k_itemamount] = num;
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (!P_MobjWasRemoved(orbit->target))
|
||||
#else
|
||||
if (orbit->target)
|
||||
#endif
|
||||
orbit->target->player->kartstuff[k_itemamount] = num;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4934,8 +4983,10 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
cur->momx = FixedMul(FINECOSINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1);
|
||||
cur->momy = FixedMul(FINESINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1);
|
||||
cur->flags &= ~MF_NOCLIPTHING;
|
||||
|
||||
if (!P_TryMove(cur, player->mo->x + cur->momx, player->mo->y + cur->momy, true))
|
||||
P_SlideMove(cur, true);
|
||||
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (P_MobjFlip(cur) > 0)
|
||||
@@ -4969,9 +5020,7 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
mobj_t *cur = player->mo->hnext;
|
||||
mobj_t *targ = player->mo;
|
||||
|
||||
const boolean ponground = P_IsObjectOnGround(player->mo);
|
||||
|
||||
if (ponground && player->speed > 0)
|
||||
if (player->speed > 0 && P_IsObjectOnGround(player->mo))
|
||||
player->kartstuff[k_bananadrag]++;
|
||||
|
||||
while (!P_MobjWasRemoved(cur))
|
||||
@@ -5020,7 +5069,8 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
|
||||
cur->angle = R_PointToAngle2(cur->x, cur->y, targx, targy);
|
||||
|
||||
/*if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->kartstuff[k_bananadrag] > TICRATE
|
||||
/*if (player->speed > 0 && P_IsObjectOnGround(player->mo)
|
||||
&& player->kartstuff[k_bananadrag] > TICRATE
|
||||
&& P_RandomChance(min(FRACUNIT/2, FixedDiv(player->speed, K_GetKartSpeed(player, false))/2)))
|
||||
{
|
||||
if (leveltime & 1)
|
||||
@@ -5029,8 +5079,9 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
targz -= 8*(2*FRACUNIT)/7;
|
||||
}*/
|
||||
|
||||
if (cv_bananajitter.value && ponground
|
||||
&& player->speed > 0 && player->kartstuff[k_bananadrag] > TICRATE)
|
||||
// "jitter" dragged bananas around
|
||||
if (cv_bananajitter.value &&
|
||||
player->speed > 0 && P_IsObjectOnGround(player->mo) && player->kartstuff[k_bananadrag] > TICRATE)
|
||||
{
|
||||
const fixed_t halfpspeed = FixedDiv(player->speed, K_GetKartSpeed(player, false))/2;
|
||||
|
||||
@@ -5531,8 +5582,6 @@ FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player, bool
|
||||
*/
|
||||
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
const boolean onground = P_IsObjectOnGround(player->mo);
|
||||
|
||||
K_UpdateOffroad(player);
|
||||
K_UpdateEngineSounds(player, cmd); // Thanks, VAda!
|
||||
|
||||
@@ -5649,7 +5698,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||
|
||||
if (player->kartstuff[k_spinouttimer])
|
||||
{
|
||||
if ((onground || ((player->kartstuff[k_spinouttype]+1)/2 == 1)) // spinouttype 1 and 2 - explosion and spb
|
||||
if ((P_IsObjectOnGround(player->mo) || ((player->kartstuff[k_spinouttype]+1)/2 == 1)) // spinouttype 1 and 2 - explosion and spb
|
||||
&& (player->kartstuff[k_sneakertimer] == 0))
|
||||
{
|
||||
player->kartstuff[k_spinouttimer]--;
|
||||
@@ -5748,7 +5797,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||
if (G_BattleGametype() && player->kartstuff[k_bumper] > 0)
|
||||
player->kartstuff[k_wanted]++;
|
||||
|
||||
if (onground)
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
player->kartstuff[k_waterskip] = 0;
|
||||
|
||||
if (player->kartstuff[k_instashield])
|
||||
@@ -5792,7 +5841,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||
if (player->kartstuff[k_comebacktimer])
|
||||
player->kartstuff[k_comebackmode] = 0;
|
||||
|
||||
if (onground && player->kartstuff[k_pogospring])
|
||||
if (player->kartstuff[k_pogospring] && P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (P_MobjFlip(player->mo)*player->mo->momz <= 0)
|
||||
player->kartstuff[k_pogospring] = 0;
|
||||
@@ -7014,6 +7063,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||
|
||||
K_RollMobjBySlopes(player->mo, player->mo->standingslope);
|
||||
|
||||
// "Stair jank" visuals akin to RR
|
||||
if (cv_stairjank.value && player->stairjank > 0)
|
||||
{
|
||||
player->mo->temprollangle += K_StairJankFlip(ANGLE_11hh / 2 / (17 / player->stairjank)); // TODO: make strength adjustable?
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
// Quick Turning
|
||||
|
||||
+55
-7
@@ -25,6 +25,7 @@
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hook.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_profile.h"
|
||||
|
||||
/* =========================================================================
|
||||
ABSTRACTION
|
||||
@@ -65,6 +66,8 @@ static stringhook_t stringHooks[STRING_HOOK(MAX)];
|
||||
|
||||
bool hook_important = true;
|
||||
|
||||
#define NONMOHOOK ((mobjtype_t)-1)
|
||||
|
||||
// This will be indexed by hook id, the value of which fetches the registry.
|
||||
static int * hookRefs;
|
||||
static int nextid;
|
||||
@@ -296,7 +299,7 @@ struct Hook_State {
|
||||
INT32 status; /* return status to calling function */
|
||||
void * userdata;
|
||||
int hook_type;
|
||||
mobjtype_t mobj_type; /* < NUMMOBJTYPES if mobj hook */
|
||||
mobjtype_t mobj_type; /* != NONMOHOOK if mobj hook */
|
||||
const char * string; /* used to fetch table, ran first if set */
|
||||
int top; /* index of last argument passed to hook */
|
||||
int id; /* id to fetch ref */
|
||||
@@ -364,7 +367,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_hook
|
||||
int hook_type
|
||||
){
|
||||
return init_hook_type(hook, default_status,
|
||||
hook_type, NUMMOBJTYPES, NULL,
|
||||
hook_type, NONMOHOOK, NULL,
|
||||
hookIds[hook_type].numHooks);
|
||||
}
|
||||
|
||||
@@ -391,7 +394,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_string_hook
|
||||
const char * string
|
||||
){
|
||||
if (init_hook_type(hook, default_status,
|
||||
hook_type, NUMMOBJTYPES, string,
|
||||
hook_type, NONMOHOOK, string,
|
||||
stringHooks[hook_type].ref))
|
||||
{
|
||||
lua_pushstring(gL, string);
|
||||
@@ -407,7 +410,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_hud_hook
|
||||
int hook_type
|
||||
){
|
||||
return init_hook_type(hook, 0,
|
||||
hook_type, NUMMOBJTYPES, NULL,
|
||||
hook_type, NONMOHOOK, NULL,
|
||||
hudHookIds[hook_type].numHooks);
|
||||
}
|
||||
|
||||
@@ -443,11 +446,54 @@ FUNCINLINE static ATTRINLINE void get_hook_from_table(Hook_State *hook, int n)
|
||||
lua_getref(gL, hookRefs[hook->id]);
|
||||
}
|
||||
|
||||
static int pcall(Hook_State *hook)
|
||||
{
|
||||
return lua_pcall(gL, hook->values, hook->results, EINDEX);
|
||||
}
|
||||
|
||||
static const char *hook_name(Hook_State *hook)
|
||||
{
|
||||
if (hud_running)
|
||||
{
|
||||
return hudHookNames[hook->hook_type];
|
||||
}
|
||||
else if (hook->string)
|
||||
{
|
||||
return stringHookNames[hook->hook_type];
|
||||
}
|
||||
//else if (hook->mobj_type > 0)
|
||||
else if (hook->mobj_type != NONMOHOOK)
|
||||
{
|
||||
return mobjHookNames[hook->hook_type];
|
||||
}
|
||||
else
|
||||
{
|
||||
return hookNames[hook->hook_type];
|
||||
}
|
||||
}
|
||||
|
||||
static int pcall_timed_or_untimed(Hook_State *hook)
|
||||
{
|
||||
if (!hud_running && cv_lua_profile.value > 0)
|
||||
{
|
||||
lua_timer_t *timer = LUA_BeginFunctionTimer(gL, -1 - hook->values, hook_name(hook));
|
||||
int k = pcall(hook);
|
||||
LUA_EndFunctionTimer(timer);
|
||||
|
||||
return k;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pcall(hook);
|
||||
}
|
||||
}
|
||||
|
||||
static int call_single_hook_no_copy(Hook_State *hook)
|
||||
{
|
||||
hook_important = hook->important;
|
||||
|
||||
if (lua_pcall(gL, hook->values, hook->results, EINDEX) == 0)
|
||||
//if (lua_pcall(gL, hook->values, hook->results, EINDEX) == 0)
|
||||
if (pcall_timed_or_untimed(hook) == 0)
|
||||
{
|
||||
if (hook->results > 0)
|
||||
{
|
||||
@@ -547,11 +593,13 @@ static int call_hooks
|
||||
{
|
||||
calls += call_string_hooks(hook);
|
||||
}
|
||||
else if (hook->mobj_type < NUMMOBJTYPES)
|
||||
//else if (hook->mobj_type > 0)
|
||||
else if (hook->mobj_type != NONMOHOOK)
|
||||
{
|
||||
/* call generic mobj hooks first */
|
||||
calls += call_mobj_type_hooks(hook, MT_NULL);
|
||||
calls += call_mobj_type_hooks(hook, hook->mobj_type);
|
||||
if (hook->mobj_type < NUMMOBJTYPES)
|
||||
calls += call_mobj_type_hooks(hook, hook->mobj_type);
|
||||
ps_lua_mobjhooks.value.i += calls;
|
||||
}
|
||||
else
|
||||
|
||||
+13
-8
@@ -644,20 +644,22 @@ static int libd_drawScaled(lua_State *L)
|
||||
// KART: draw patch on minimap from x, y coordinates on the map
|
||||
static int libd_drawOnMinimap(lua_State *L)
|
||||
{
|
||||
fixed_t x, y, scale; // coordinates of the object
|
||||
patch_t *patch; // patch we want to draw
|
||||
UINT8 *colormap = NULL; // do we want to colormap this patch?
|
||||
boolean centered; // the patch is centered and doesn't need readjusting on x/y coordinates.
|
||||
fixed_t x, y, scale; // coordinates of the object
|
||||
patch_t *patch; // patch we want to draw
|
||||
UINT8 *colormap = NULL; // do we want to colormap this patch?
|
||||
boolean centered; // the patch is centered and doesn't need readjusting on x/y coordinates.
|
||||
huddrawlist_h list;
|
||||
patch_t *AutomapPic = NULL;
|
||||
drawinfo_t info;
|
||||
|
||||
// variables used to replicate k_kart's mmap drawer:
|
||||
patch_t *AutomapPic;
|
||||
|
||||
// variables used for actually drawing the icon:
|
||||
INT32 splitflags, minimaptrans;
|
||||
fixed_t amnumxpos, amnumypos;
|
||||
fixed_t amxpos, amypos;
|
||||
INT32 mm_x, mm_y;
|
||||
fixed_t patchw = 0, patchh = 0;
|
||||
fixed_t patchw, patchh;
|
||||
|
||||
HUDONLY // only run this function in hud hooks
|
||||
|
||||
@@ -722,8 +724,11 @@ static int libd_drawOnMinimap(lua_State *L)
|
||||
|
||||
mm_y -= AutomapPic->topoffset;
|
||||
|
||||
// patch is supposedly already centered, don't butt in.
|
||||
if (!centered)
|
||||
if (centered)
|
||||
{
|
||||
patchw = patchh = 0; // patch is supposedly already centered, don't butt in.
|
||||
}
|
||||
else
|
||||
{
|
||||
// scale patch coords
|
||||
patchw = (patch->width * scale / 2);
|
||||
|
||||
+5
-1
@@ -22,7 +22,8 @@
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // cmd errors
|
||||
#include "lua_hook.h" // hook_cmd_running errors
|
||||
#include "lua_profile.h"
|
||||
|
||||
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
|
||||
state_t *astate = NULL;
|
||||
@@ -110,7 +111,10 @@ static void A_Lua(mobj_t *actor)
|
||||
LUA_PushUserdata(gL, actor, META_MOBJ);
|
||||
lua_pushinteger(gL, var1);
|
||||
lua_pushinteger(gL, var2);
|
||||
|
||||
lua_timer_t *timer = LUA_BeginFunctionTimer(gL, -4, "A_Lua");
|
||||
LUA_Call(gL, 3, 0, 1);
|
||||
LUA_EndFunctionTimer(timer);
|
||||
|
||||
lua_pop(gL, 1); // pop error handler
|
||||
|
||||
|
||||
+1
-1
@@ -652,7 +652,7 @@ static int line_get(lua_State *L)
|
||||
LUA_PushUserdata(L, &sides[line->sidenum[0]], META_SIDE);
|
||||
return 1;
|
||||
case line_backside: // backside
|
||||
if (line->sidenum[1] == 0xffff)
|
||||
if (line->sidenum[1] == NO_INDEX)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &sides[line->sidenum[1]], META_SIDE);
|
||||
return 1;
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by James Robert Roman
|
||||
// Copyright (C) 2025 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "screen.h"
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
extern "C" {
|
||||
#include "blua/lua.h"
|
||||
};
|
||||
|
||||
#include "v_video.h"
|
||||
|
||||
#include "command.h"
|
||||
#include "doomtype.h"
|
||||
#include "i_system.h"
|
||||
#include "lua_profile.h"
|
||||
#include "m_perfstats.h"
|
||||
|
||||
extern "C" consvar_t cv_lua_profile;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
precise_t g_time_reference;
|
||||
int g_tics_counted;
|
||||
|
||||
double g_running_tic_time;
|
||||
double g_avg_tic_time;
|
||||
|
||||
bool g_invalid;
|
||||
|
||||
}; // namespace
|
||||
|
||||
struct lua_timer_t
|
||||
{
|
||||
struct Stat
|
||||
{
|
||||
double calls = 0;
|
||||
double time = 0.0;
|
||||
};
|
||||
|
||||
Stat running, avg;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::unordered_map<std::string, lua_timer_t> g_tic_timers;
|
||||
|
||||
}; // namespace
|
||||
|
||||
lua_timer_t* LUA_BeginFunctionTimer(lua_State* L, int fn_idx, const char* name)
|
||||
{
|
||||
lua_Debug ar;
|
||||
|
||||
lua_pushvalue(L, fn_idx);
|
||||
lua_getinfo(L, ">S", &ar);
|
||||
|
||||
auto label = [&]
|
||||
{
|
||||
using sv = std::string_view;
|
||||
sv view{ar.source};
|
||||
|
||||
switch (view.front())
|
||||
{
|
||||
case '@': // file
|
||||
if (std::size_t p = view.rfind('/'); p != sv::npos) // lump or base
|
||||
{
|
||||
return view.substr(p + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case '=': // ??
|
||||
view.remove_prefix(1);
|
||||
break;
|
||||
}
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
// i sure hope this std::string mess is fine...
|
||||
auto [it, ins] = g_tic_timers.try_emplace(std::string(va("%s:%d (%s)", std::string(label()).c_str(), ar.linedefined, name)));
|
||||
auto& [key, timer] = *it;
|
||||
|
||||
g_time_reference = I_GetPreciseTime();
|
||||
|
||||
return &timer;
|
||||
}
|
||||
|
||||
void LUA_EndFunctionTimer(lua_timer_t* timer)
|
||||
{
|
||||
precise_t t = I_GetPreciseTime() - g_time_reference;
|
||||
double precision = I_GetPrecisePrecision();
|
||||
|
||||
timer->running.time += t / precision;
|
||||
timer->running.calls += 1.0;
|
||||
}
|
||||
|
||||
void LUA_ResetTicTimers(void)
|
||||
{
|
||||
if (cv_lua_profile.value <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_tics_counted < cv_lua_profile.value)
|
||||
{
|
||||
g_tics_counted++;
|
||||
|
||||
double precision = I_GetPrecisePrecision();
|
||||
g_running_tic_time += ps_prevtictime.value.p / precision;
|
||||
}
|
||||
else
|
||||
{
|
||||
double counted = g_tics_counted;
|
||||
|
||||
for (auto& [key, timer] : g_tic_timers)
|
||||
{
|
||||
timer.avg = {timer.running.calls / counted, timer.running.time / counted};
|
||||
timer.running = {};
|
||||
}
|
||||
|
||||
g_avg_tic_time = g_running_tic_time / counted;
|
||||
g_running_tic_time = 0.0;
|
||||
|
||||
g_tics_counted = 1;
|
||||
|
||||
g_invalid = false;
|
||||
}
|
||||
}
|
||||
|
||||
void LUA_RenderTimers(void)
|
||||
{
|
||||
constexpr int kRowHeight = 4;
|
||||
float row_y = kRowHeight;
|
||||
|
||||
// pretty much what the whole srb2::Draw does lol
|
||||
auto draw_row = [](float x, float y, INT32 flags, const char *str)
|
||||
{
|
||||
V_DrawSmallStringAtFixed(
|
||||
FloatToFixed(x),
|
||||
FloatToFixed(y),
|
||||
V_MONOSPACE|V_ALLOWLOWERCASE|flags,
|
||||
str
|
||||
);
|
||||
};
|
||||
|
||||
draw_row(0.f, 0.f, 0, va("-- AVERAGES PER TIC (over %d tics) --", cv_lua_profile.value));
|
||||
|
||||
if (g_invalid)
|
||||
{
|
||||
draw_row(0.f, row_y, V_GRAYMAP, " <Data pending>");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<decltype(g_tic_timers)::iterator> view;
|
||||
view.reserve(g_tic_timers.size());
|
||||
|
||||
auto color_flag = [](double t)
|
||||
{
|
||||
if (t < 10.0)
|
||||
{
|
||||
return V_GRAYMAP;
|
||||
}
|
||||
else if (t >= 100.0)
|
||||
{
|
||||
return V_YELLOWMAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
double cum = 0.0;
|
||||
|
||||
for (auto it = g_tic_timers.begin(); it != g_tic_timers.end(); ++it)
|
||||
{
|
||||
auto& [key, timer] = *it;
|
||||
|
||||
cum += timer.avg.time;
|
||||
|
||||
if (timer.avg.time > 0.0)
|
||||
{
|
||||
view.push_back(it);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const INT32 tally_flags = color_flag(cum * 1'000'000.0);
|
||||
|
||||
draw_row(0.f, row_y, tally_flags, va("%8.2f us - TOTAL", cum * 1'000'000.0));
|
||||
draw_row(0.f, row_y + kRowHeight, tally_flags, va("%8.2f ms", cum * 1000.0));
|
||||
|
||||
// dont need to show this if we didnt capture over time
|
||||
// this would just show nan or inf anyways
|
||||
if (std::fpclassify(g_avg_tic_time) != FP_ZERO)
|
||||
{
|
||||
draw_row(0.f, row_y + kRowHeight * 2, tally_flags, va(
|
||||
"%8.2f%% overhead (%.2f / %.2f) <-- not counting rendering time",
|
||||
(cum / g_avg_tic_time) * 100.0,
|
||||
(cum * (double)TICRATE),
|
||||
(g_avg_tic_time * (double)TICRATE)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
row_y += kRowHeight * 4;
|
||||
}
|
||||
|
||||
std::sort(
|
||||
view.rbegin(),
|
||||
view.rend(),
|
||||
[](auto a, auto b)
|
||||
{
|
||||
auto& [k1, t1] = *a;
|
||||
auto& [k2, t2] = *b;
|
||||
return t1.avg.time < t2.avg.time;
|
||||
}
|
||||
);
|
||||
|
||||
for (auto it : view)
|
||||
{
|
||||
auto& [key, timer] = *it;
|
||||
|
||||
double t = timer.avg.time * 1'000'000.0;
|
||||
|
||||
draw_row(0.f, row_y, color_flag(t), va(
|
||||
"%8.2f us %8.2f calls - %s",
|
||||
t,
|
||||
timer.avg.calls,
|
||||
key.c_str()
|
||||
));
|
||||
|
||||
row_y += kRowHeight;
|
||||
|
||||
// FIXME this is all ugly and sucks
|
||||
if (row_y >= BASEVIDHEIGHT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void lua_profile_OnChange(void)
|
||||
{
|
||||
g_invalid = true;
|
||||
|
||||
if (cv_lua_profile.value == 0)
|
||||
{
|
||||
g_tic_timers = {};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by James Robert Roman
|
||||
// Copyright (C) 2025 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef lua_profile_h
|
||||
#define lua_profile_h
|
||||
|
||||
#include "blua/lua.h"
|
||||
#include "doomtype.h"
|
||||
//#include "typedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct lua_timer_t;
|
||||
typedef struct lua_timer_t lua_timer_t;
|
||||
|
||||
void LUA_ResetTicTimers(void);
|
||||
|
||||
lua_timer_t *LUA_BeginFunctionTimer(lua_State *L, int fn_idx, const char *name);
|
||||
void LUA_EndFunctionTimer(lua_timer_t *timer);
|
||||
|
||||
void LUA_RenderTimers(void);
|
||||
|
||||
void lua_profile_OnChange(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif/*lua_profile_h*/
|
||||
+8
-1
@@ -713,9 +713,12 @@ static UINT8 GetUserdataArchType(int index)
|
||||
|
||||
static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
|
||||
{
|
||||
int type = lua_type(gL, myindex);
|
||||
|
||||
if (myindex < 0)
|
||||
myindex = lua_gettop(gL)+1+myindex;
|
||||
switch (lua_type(gL, myindex))
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LUA_TNONE:
|
||||
case LUA_TNIL:
|
||||
@@ -725,8 +728,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
case LUA_TTHREAD:
|
||||
case LUA_TFUNCTION:
|
||||
{
|
||||
const char *typestr = (type == LUA_TLIGHTUSERDATA ? "light userdata" : (type == LUA_TTHREAD ? "thread" : (type == LUA_TFUNCTION ? "function" : "??")));
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Archived an invalid value! (%s)\n"), typestr);
|
||||
WRITEUINT8(*p, ARCH_NULL);
|
||||
return 2;
|
||||
}
|
||||
case LUA_TBOOLEAN:
|
||||
WRITEUINT8(*p, ARCH_BOOLEAN);
|
||||
WRITEUINT8(*p, lua_toboolean(gL, myindex));
|
||||
|
||||
+95
-49
@@ -151,8 +151,6 @@ const char *quitmsg[NUM_QUITMESSAGES] = {};
|
||||
|
||||
INT32 mapwads[NUMMAPS] = {};
|
||||
|
||||
boolean browselocalskins = false;
|
||||
|
||||
boolean menuactive = false;
|
||||
boolean fromlevelselect = false;
|
||||
|
||||
@@ -214,12 +212,19 @@ static INT32 setupm_fakeskin;
|
||||
static INT32 setupm_fakecolor;
|
||||
static UINT8 setupm_pselect = 1;
|
||||
|
||||
//variables used for other skin select menus
|
||||
// variables used for other skin select menus
|
||||
static UINT8 setupm_skinypos;
|
||||
static INT32 setupm_skinselect;
|
||||
static boolean setupm_skinlockedselect;
|
||||
|
||||
static UINT8 setupm_playernum; //brap
|
||||
static UINT8 setupm_playernum; // brap
|
||||
|
||||
// Addons Menu: Local mode
|
||||
static void M_LocalAddons(INT32 choice);
|
||||
static boolean addons_localmode = false;
|
||||
|
||||
#define LOCALMODE_KEY (KEY_RALT)
|
||||
#define AUTOLOAD_KEY (KEY_END)
|
||||
|
||||
//
|
||||
// PROTOTYPES
|
||||
@@ -325,7 +330,6 @@ static void M_EraseData(INT32 choice);
|
||||
|
||||
static void M_AddonsInternal();
|
||||
static void M_Addons(INT32 choice);
|
||||
static void M_LocalSkins(INT32 choice);
|
||||
static void M_AddonsOptions(INT32 choice);
|
||||
#define addonmenusize 9 // number of items actually displayed in the addons menu view, formerly (2*numaddonsshown + 1)
|
||||
#define numaddonsshown 4 // number of items to each side of the currently selected item, unless at top/bottom ends of directory
|
||||
@@ -409,6 +413,7 @@ static INT32 M_GetFirstLevelInList(void);
|
||||
|
||||
// crap to force hud to show when in saturns hud options
|
||||
boolean forceshowhud = false;
|
||||
boolean forceshowchat = false;
|
||||
|
||||
// smol text indicating if game is modified
|
||||
// so ppl dont wonder where their ra times went and stuff
|
||||
@@ -447,13 +452,13 @@ consvar_t cv_showallmaps = {"showallmaps", "No", CV_SAVE, CV_YesNo, NULL, 0, NUL
|
||||
consvar_t cv_showmusicfilename = {"showmusicfilename", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t serversort_cons_t[] = {
|
||||
{0,"Ping"},
|
||||
{1,"Modified State"},
|
||||
{2,"Most Players"},
|
||||
{3,"Least Players"},
|
||||
{4,"Max Player Slots"},
|
||||
{5,"Gametype"},
|
||||
{0,NULL}
|
||||
{0, "Ping"},
|
||||
{1, "Modified State"},
|
||||
{2, "Most Players"},
|
||||
{3, "Least Players"},
|
||||
{4, "Max Player Slots"},
|
||||
{5, "Gametype"},
|
||||
{0, NULL}
|
||||
};
|
||||
consvar_t cv_serversort = {"serversort", "Ping", CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -702,7 +707,7 @@ static void Dummystaff_OnChange(void)
|
||||
|
||||
dummystaffname[0] = '\0';
|
||||
|
||||
if ((l = W_CheckNumForName(va("%sS01",G_BuildMapName(cv_nextmap.value)))) == LUMPERROR)
|
||||
if ((l = W_CheckNumForName(va("%sS01", G_BuildMapName(cv_nextmap.value)))) == LUMPERROR)
|
||||
{
|
||||
CV_StealthSetValue(&cv_dummystaff, 0);
|
||||
return;
|
||||
@@ -711,7 +716,7 @@ static void Dummystaff_OnChange(void)
|
||||
{
|
||||
char *temp = dummystaffname;
|
||||
UINT8 numstaff = 1;
|
||||
while (numstaff < 99 && (l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(cv_nextmap.value),numstaff+1))) != LUMPERROR)
|
||||
while (numstaff < 99 && (l = W_CheckNumForName(va("%sS%02u", G_BuildMapName(cv_nextmap.value), numstaff+1))) != LUMPERROR)
|
||||
numstaff++;
|
||||
|
||||
if (cv_dummystaff.value < 1)
|
||||
@@ -719,7 +724,7 @@ static void Dummystaff_OnChange(void)
|
||||
else if (cv_dummystaff.value > numstaff)
|
||||
CV_StealthSetValue(&cv_dummystaff, 1);
|
||||
|
||||
if ((l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(cv_nextmap.value), cv_dummystaff.value))) == LUMPERROR)
|
||||
if ((l = W_CheckNumForName(va("%sS%02u", G_BuildMapName(cv_nextmap.value), cv_dummystaff.value))) == LUMPERROR)
|
||||
return; // shouldn't happen but might as well check...
|
||||
|
||||
G_UpdateStaffGhostName(l);
|
||||
@@ -804,7 +809,8 @@ static void M_ChangeCvar(INT32 choice)
|
||||
CV_SetValue(cv,skins[skinno].prefcolor);
|
||||
return;
|
||||
}
|
||||
CV_Set(cv,cv->defaultvalue);
|
||||
|
||||
CV_Set(cv, cv->defaultvalue);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -953,6 +959,7 @@ static void Command_Manual_f(void)
|
||||
{
|
||||
if (modeattacking)
|
||||
return;
|
||||
|
||||
M_StartControlPanel();
|
||||
M_Manual(INT32_MAX);
|
||||
itemOn = 0;
|
||||
@@ -1014,6 +1021,24 @@ boolean M_Responder(event_t *ev)
|
||||
case KEY_HAT1 + 3:
|
||||
ch = KEY_RIGHTARROW;
|
||||
break;
|
||||
//Local Addon Mode
|
||||
case LOCALMODE_KEY:
|
||||
{
|
||||
if (!(server || IsPlayerAdmin(consoleplayer)))
|
||||
break;
|
||||
|
||||
if (!addons_localmode)
|
||||
{
|
||||
S_StartSound(NULL, sfx_ding);
|
||||
addons_localmode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound(NULL, sfx_jshard);
|
||||
addons_localmode = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (menuactive)
|
||||
@@ -1579,11 +1604,16 @@ static boolean ShouldDrawMenuBG(void)
|
||||
if (forceshowhud)
|
||||
return false;
|
||||
|
||||
if (forceshowchat)
|
||||
return false;
|
||||
|
||||
// camera options stuff, only do when in level
|
||||
if (gamestate == GS_LEVEL &&
|
||||
(currentMenu == &OP_CamOptionsDef || currentMenu == &OP_Player1CamOptionsDef
|
||||
|| currentMenu == &OP_Player2CamOptionsDef || currentMenu == &OP_Player3CamOptionsDef
|
||||
|| currentMenu == &OP_Player4CamOptionsDef))
|
||||
(currentMenu == &OP_CamOptionsDef ||
|
||||
currentMenu == &OP_Player1CamOptionsDef ||
|
||||
currentMenu == &OP_Player2CamOptionsDef ||
|
||||
currentMenu == &OP_Player3CamOptionsDef ||
|
||||
currentMenu == &OP_Player4CamOptionsDef))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -1599,7 +1629,9 @@ void M_Drawer(void)
|
||||
if (currentMenu == &MessageDef)
|
||||
menuactive = true;
|
||||
|
||||
// pain and suffering
|
||||
forceshowhud = (gamestate == GS_LEVEL && menuactive && (currentMenu == &OP_SaturnHudDef || currentMenu == &OP_HudOffsetDef || currentMenu == &OP_NametagDef || currentMenu == &OP_DriftGaugeDef)); // holy fuick
|
||||
forceshowchat = (gamestate == GS_LEVEL && menuactive && currentMenu == &OP_ChatOptionsDef && (!OLDCHAT) && (itemOn == op_chat_boxwidth || itemOn == op_chat_boxheight || itemOn == op_chat_xoffs || itemOn == op_chat_yoffs || itemOn == op_chat_charlmt)); // man i dont gaf anymore lmao
|
||||
|
||||
if (menuactive)
|
||||
{
|
||||
@@ -1718,19 +1750,16 @@ void M_StartControlPanel(void)
|
||||
MPauseMenu[mpause_switchteam].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_switchspectate].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_psetup].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_localaddons].status = IT_STRING | IT_CALL;
|
||||
|
||||
MISC_ChangeTeamMenu[0].status = IT_DISABLED;
|
||||
MISC_ChangeSpectateMenu[0].status = IT_DISABLED;
|
||||
|
||||
MPauseMenu[mpause_addlocalskins].status = IT_STRING | IT_CALL;
|
||||
MPauseMenu[mpause_localskin].status = IT_STRING | IT_CALL;
|
||||
|
||||
// Reset these in case splitscreen messes things up
|
||||
MPauseMenu[mpause_addons].alphaKey = 8;
|
||||
|
||||
if (IsPlayerAdmin(consoleplayer))
|
||||
MPauseMenu[mpause_addlocalskins].alphaKey = 16;
|
||||
else
|
||||
MPauseMenu[mpause_addlocalskins].alphaKey = 24;
|
||||
MPauseMenu[mpause_localaddons].alphaKey = 24;
|
||||
|
||||
MPauseMenu[mpause_scramble].alphaKey = 8;
|
||||
MPauseMenu[mpause_switchmap].alphaKey = 24;
|
||||
@@ -1748,14 +1777,13 @@ void M_StartControlPanel(void)
|
||||
{
|
||||
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
|
||||
MPauseMenu[mpause_addons].status = IT_STRING | IT_CALL;
|
||||
|
||||
MPauseMenu[mpause_localaddons].status = IT_DISABLED;
|
||||
if (G_GametypeHasTeams())
|
||||
MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU;
|
||||
}
|
||||
|
||||
if (server || (!cv_showlocalskinmenus.value))
|
||||
{
|
||||
MPauseMenu[mpause_addlocalskins].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_localskin].status = IT_DISABLED;
|
||||
|
||||
MPauseMenu[mpause_options].alphaKey = 64;
|
||||
@@ -1763,7 +1791,6 @@ void M_StartControlPanel(void)
|
||||
MPauseMenu[mpause_quit].alphaKey = 88;
|
||||
}
|
||||
|
||||
|
||||
if (splitscreen)
|
||||
{
|
||||
MPauseMenu[mpause_psetupsplit].status = MPauseMenu[mpause_psetupsplit2].status = IT_STRING | IT_CALL;
|
||||
@@ -3308,14 +3335,14 @@ static void M_AddonsInternal(void)
|
||||
static void M_Addons(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
browselocalskins = false;
|
||||
addons_localmode = false;
|
||||
M_AddonsInternal();
|
||||
}
|
||||
|
||||
static void M_LocalSkins(INT32 choice)
|
||||
static void M_LocalAddons(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
browselocalskins = true;
|
||||
addons_localmode = true;
|
||||
M_AddonsInternal();
|
||||
}
|
||||
|
||||
@@ -3484,8 +3511,8 @@ static void M_DrawAddons(void)
|
||||
|
||||
if (Playing())
|
||||
{
|
||||
if (browselocalskins)
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 5, V_ALLOWLOWERCASE, "Load \x83local skins\x80 from addons!");
|
||||
if (addons_localmode) // Draw notice that you're adding locally
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 5, V_ALLOWLOWERCASE, "Load addons or \x83local skins\x80 locally!");
|
||||
else
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 5, warningflags, "Adding files mid-game may cause problems.");
|
||||
}
|
||||
@@ -3648,7 +3675,10 @@ static void M_DrawAddons(void)
|
||||
//m = numwadfiles-(mainwads+2+1);
|
||||
//V_DrawCenteredString(BASEVIDWIDTH/2, y+24, (majormods ? highlightflags : V_TRANSLUCENT), va("%d ADD-ON%s LOADED", (int)m, (m == 1) ? "" : "S")); //+2 for music, sounds, +1 for main.kart
|
||||
|
||||
V_DrawThinString(0, BASEVIDHEIGHT-10, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_TRANSLUCENT|V_ALLOWLOWERCASE, ("END Key - Add addon to autoload"));
|
||||
V_DrawThinString(0, BASEVIDHEIGHT-10, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s Key - Add addon to autoload", G_KeynumToString(AUTOLOAD_KEY)));
|
||||
|
||||
if (Playing() && (server || IsPlayerAdmin(consoleplayer)))
|
||||
V_DrawThinString(0, BASEVIDHEIGHT-20, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s Key - Switch to local addon mode", G_KeynumToString(LOCALMODE_KEY)));
|
||||
}
|
||||
|
||||
static void M_AddonExec(INT32 ch)
|
||||
@@ -3670,7 +3700,7 @@ static void M_AddonAutoLoad(INT32 ch)
|
||||
FILE *autoloadconfigfile;
|
||||
|
||||
// check our controls //
|
||||
if (ch != 'y' && ch != KEY_ENTER && ch != KEY_END)
|
||||
if (ch != 'y' && ch != KEY_ENTER && ch != AUTOLOAD_KEY)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s26d);
|
||||
return;
|
||||
@@ -3684,7 +3714,7 @@ static void M_AddonAutoLoad(INT32 ch)
|
||||
switch (dirmenu[dir_on[menudepthleft]][DIR_TYPE])
|
||||
{
|
||||
case EXT_FOLDER:
|
||||
M_StartMessage(va("%c%s\x80\nAutoloading folders is not supported as of yet. \n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
|
||||
M_StartMessage(va("%c%s\x80\nAutoloading folders is not supported as of yet. \n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING), NULL, MM_NOTHING);
|
||||
break;
|
||||
case EXT_TXT:
|
||||
case EXT_CFG:
|
||||
@@ -3825,7 +3855,7 @@ static void M_HandleAddons(INT32 choice)
|
||||
}
|
||||
break;
|
||||
case EXT_TXT:
|
||||
M_StartMessage(va("%c%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),M_AddonExec,MM_YESNO);
|
||||
M_StartMessage(va("%c%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING), M_AddonExec, MM_YESNO);
|
||||
break;
|
||||
case EXT_CFG:
|
||||
M_AddonExec(KEY_ENTER);
|
||||
@@ -3838,30 +3868,40 @@ static void M_HandleAddons(INT32 choice)
|
||||
case EXT_KART:
|
||||
#endif
|
||||
case EXT_PK3:
|
||||
if (browselocalskins)
|
||||
{
|
||||
if (DumbStartsWith("KC_", dirmenu[dir_on[menudepthleft]]+DIR_STRING) || DumbStartsWith("kc_", dirmenu[dir_on[menudepthleft]]+DIR_STRING)) {
|
||||
M_StartMessage(va("%c%s\x80\nYou are loading a local skin.\nLocal skins will not be usable\nafter going back from\nthe title screen.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
|
||||
COM_BufAddText(va("addfilelocal \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||
const char *addonname = dirmenu[dir_on[menudepthleft]]+DIR_STRING;
|
||||
|
||||
if (addons_localmode)
|
||||
{
|
||||
if (DumbStartsWith("KC_", addonname) || DumbStartsWith("kc_", addonname))
|
||||
{
|
||||
M_StartMessage(va("%c%s\x80\nYou are loading a local skin.\nLocal skins will not be usable\nafter going back from\nthe title screen.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), addonname), NULL, MM_NOTHING);
|
||||
}
|
||||
else if (DumbStartsWith("KCL_", addonname) || DumbStartsWith("kcl_", addonname)) // skins with lua
|
||||
{
|
||||
M_StartMessage(va("%c%s\x80\nYou are loading a local skin with lua.\nBeware that this may cause issues like crashes or desyncs in some cases!\nLocal skins will not be usable\nafter going back from\nthe title screen.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), addonname), NULL, MM_NOTHING);
|
||||
}
|
||||
// no need to account for KRC cases
|
||||
|
||||
COM_BufAddText(va("addfilelocal \"%s%s\"", menupath, addonname));
|
||||
}
|
||||
else
|
||||
S_StartSound(NULL, sfx_s26d);
|
||||
}
|
||||
else
|
||||
{
|
||||
COM_BufAddText(va("addfile \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||
{
|
||||
COM_BufAddText(va("addfile \"%s%s\"", menupath, addonname));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
S_StartSound(NULL, sfx_s26d);
|
||||
}
|
||||
}
|
||||
|
||||
if (refresh)
|
||||
refreshdirmenu |= REFRESHDIR_NORMAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_END:
|
||||
case AUTOLOAD_KEY:
|
||||
{
|
||||
boolean refresh = true;
|
||||
if (!dirmenu[dir_on[menudepthleft]])
|
||||
@@ -3928,6 +3968,8 @@ static void M_HandleAddons(INT32 choice)
|
||||
M_SetupNextMenu(currentMenu->prevMenu);
|
||||
else
|
||||
M_ClearMenus(true);
|
||||
|
||||
addons_localmode = false; //Exiting this menu, disable addons_localmode already.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7608,7 +7650,11 @@ Update the maxplayers label...
|
||||
|
||||
// draw name string
|
||||
if (itemOn != 9)
|
||||
V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, setupm_ip);
|
||||
{
|
||||
char buf[28];
|
||||
strlcpy(buf, setupm_ip, sizeof(buf));
|
||||
V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, buf);
|
||||
}
|
||||
else
|
||||
M_DrawTextInputScroll(x+8, y+12, &setupm_input_ip, 0, SETUPM_IP_MAXSIZE);
|
||||
|
||||
@@ -7740,7 +7786,7 @@ static void M_SetupMultiHandler(INT32 choice)
|
||||
if (exitmenu)
|
||||
{
|
||||
if (currentMenu->prevMenu)
|
||||
M_SetupNextMenu (currentMenu->prevMenu);
|
||||
M_SetupNextMenu(currentMenu->prevMenu);
|
||||
else
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ extern "C" {
|
||||
#include "mserv.h"
|
||||
#include "r_things.h" // for SKINNAMESIZE
|
||||
|
||||
extern boolean forceshowhud;
|
||||
extern boolean forceshowhud, forceshowchat;
|
||||
|
||||
//
|
||||
// MENUS
|
||||
|
||||
+131
-92
@@ -208,7 +208,7 @@ typedef enum
|
||||
static menuitem_t MPauseMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_CALL, NULL, "Addons...", M_Addons, 8},
|
||||
{IT_STRING | IT_CALL, NULL, "Add local skins...", M_LocalSkins, 16},
|
||||
{IT_STRING | IT_CALL, NULL, "Local Add-ons...", M_LocalAddons, 8},
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 24},
|
||||
{IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 32},
|
||||
|
||||
@@ -238,7 +238,7 @@ static menuitem_t MPauseMenu[] =
|
||||
typedef enum
|
||||
{
|
||||
mpause_addons = 0,
|
||||
mpause_addlocalskins,
|
||||
mpause_localaddons,
|
||||
mpause_scramble,
|
||||
mpause_switchmap,
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
@@ -446,25 +446,25 @@ enum
|
||||
|
||||
static menuitem_t SP_ReplayMenu[] =
|
||||
{
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Time", M_ReplayTimeAttack, 90},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Lap", M_ReplayTimeAttack, 98},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Time", M_ReplayTimeAttack, 90},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Lap", M_ReplayTimeAttack, 98},
|
||||
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Last", M_ReplayTimeAttack, 106},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Guest", M_ReplayTimeAttack, 114},
|
||||
{IT_WHITESTRING|IT_KEYHANDLER, NULL, "Replay Staff",M_HandleStaffReplay,122},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Last", M_ReplayTimeAttack, 106},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Guest", M_ReplayTimeAttack, 114},
|
||||
{IT_WHITESTRING|IT_KEYHANDLER, NULL, "Replay Staff",M_HandleStaffReplay, 122},
|
||||
|
||||
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
|
||||
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
|
||||
};
|
||||
|
||||
static menuitem_t SP_GuestReplayMenu[] =
|
||||
{
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", M_SetGuestReplay, 94},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Lap as Guest", M_SetGuestReplay,102},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Last as Guest", M_SetGuestReplay,110},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", M_SetGuestReplay, 94},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Lap as Guest", M_SetGuestReplay, 102},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Last as Guest", M_SetGuestReplay, 110},
|
||||
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Delete Guest Replay", M_SetGuestReplay,120},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Delete Guest Replay", M_SetGuestReplay, 120},
|
||||
|
||||
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
|
||||
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
|
||||
};
|
||||
|
||||
static menuitem_t SP_GhostMenu[] =
|
||||
@@ -555,10 +555,10 @@ static menuitem_t MP_PlayerSetupMenu[] =
|
||||
|
||||
static menuitem_t MP_ConnectMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_CVAR, NULL, "Sort By", &cv_serversort, 0},
|
||||
{IT_STRING | IT_KEYHANDLER, NULL, "Page", M_HandleServerPage, 8},
|
||||
{IT_STRING | IT_CALL, NULL, "Refresh", M_Refresh, 16},
|
||||
{IT_STRING | IT_KEYHANDLER, NULL, "", M_HandleServerSearch,25},
|
||||
{IT_STRING | IT_CVAR, NULL, "Sort By", &cv_serversort, 0},
|
||||
{IT_STRING | IT_KEYHANDLER, NULL, "Page", M_HandleServerPage, 8},
|
||||
{IT_STRING | IT_CALL, NULL, "Refresh", M_Refresh, 16},
|
||||
{IT_STRING | IT_KEYHANDLER, NULL, "", M_HandleServerSearch, 25},
|
||||
|
||||
{IT_STRING | IT_SPACE, NULL, "", M_Connect, 48},
|
||||
{IT_STRING | IT_SPACE, NULL, "", M_Connect, 60},
|
||||
@@ -725,29 +725,29 @@ static const char* OP_AllControlsTooltips[sizeof(OP_AllControlsMenu)/sizeof(OP_A
|
||||
// The rest is null, for now
|
||||
};
|
||||
|
||||
#define OP_JOYMENU(pnum) \
|
||||
{IT_HEADER, NULL, "Gameplay Controls", NULL, 7}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Aim Forward/Back" , &cv_aimaxis[pnum] , 15}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_turnaxis[pnum] , 20}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Accelerate" , &cv_moveaxis[pnum] , 25}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Brake" , &cv_brakeaxis[pnum] , 30}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Drift" , &cv_driftaxis[pnum] , 35}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Use Item" , &cv_fireaxis[pnum] , 40}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Look Backward" , &cv_lookbackaxis[pnum] , 45}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 1" , &cv_custom1axis[pnum] , 50}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 2" , &cv_custom2axis[pnum] , 55}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 3" , &cv_custom3axis[pnum] , 60}, \
|
||||
{IT_HEADER, NULL, "Camera Controls", NULL, 67}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Look Up/Down" , &cv_lookaxis[pnum] , 75}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_camturnaxis[pnum] , 80}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Strafe Left/Right" , &cv_camstrafeaxis[pnum] , 85}, \
|
||||
{IT_HEADER, NULL, "Deadzones", NULL, 92}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone[pnum] , 100}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone[pnum] , 105}, \
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, 112}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Controller Rumble" , &cv_rumble[pnum] , 120}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Controller Rumble Strength" , &cv_rumblestrength[pnum] , 125}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Set LED to Player color" , &cv_gamepadled[pnum] , 130},
|
||||
#define OP_JOYMENU(pnum) \
|
||||
{IT_HEADER, NULL, "Gameplay Controls", NULL, 7}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Aim Forward/Back" , &cv_aimaxis[pnum] , 15}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_turnaxis[pnum] , 20}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Accelerate" , &cv_moveaxis[pnum] , 25}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Brake" , &cv_brakeaxis[pnum] , 30}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Drift" , &cv_driftaxis[pnum] , 35}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Use Item" , &cv_fireaxis[pnum] , 40}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Look Backward" , &cv_lookbackaxis[pnum] , 45}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 1" , &cv_custom1axis[pnum] , 50}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 2" , &cv_custom2axis[pnum] , 55}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 3" , &cv_custom3axis[pnum] , 60}, \
|
||||
{IT_HEADER, NULL, "Camera Controls", NULL, 67}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Look Up/Down" , &cv_lookaxis[pnum] , 75}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_camturnaxis[pnum] , 80}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Strafe Left/Right" , &cv_camstrafeaxis[pnum] , 85}, \
|
||||
{IT_HEADER, NULL, "Deadzones", NULL, 92}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone[pnum] , 100}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone[pnum] , 105}, \
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, 112}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Controller Rumble" , &cv_rumble[pnum] , 120}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Controller Rumble Strength" , &cv_rumblestrength[pnum] , 125}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Set LED to Player color" , &cv_gamepadled[pnum] , 130},
|
||||
|
||||
static menuitem_t OP_Joystick1Menu[] =
|
||||
{
|
||||
@@ -789,10 +789,9 @@ static menuitem_t OP_JoystickSetMenu[] =
|
||||
static menuitem_t OP_MouseOptionsMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_CVAR, NULL, "Use Mouse", &cv_usemouse, 10},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Mouse Turning", &cv_mouseturn, 20},
|
||||
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 30},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Mouse X Speed", &cv_mousexsens, 40},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Mouse X Speed", &cv_mousexsens, 40},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Mouse Y Speed", &cv_mouseysens, 50},
|
||||
};
|
||||
|
||||
@@ -861,7 +860,6 @@ static const char* OP_VideoTooltips[] =
|
||||
"Advanced graphical options.",
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
op_video_res = 0,
|
||||
@@ -945,24 +943,25 @@ static menuitem_t OP_ExpOptionsMenu[] =
|
||||
//{IT_STRING | IT_CVAR, NULL, "Randomized Directional Light", &cv_randomdirlight, 45}, // should this ever come back
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Skyboxes", &cv_skybox, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Skydome", &cv_skydome, 45},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Precache Level Textures", &cv_precachetextures, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Precache Level Textures", &cv_precachetextures, 55},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "FPS counter sampling", &cv_accuratefps, 60},
|
||||
{IT_STRING | IT_CVAR, NULL, "FPS counter sampling", &cv_accuratefps, 65},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Frameskip", &cv_frameskip, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Frameskip", &cv_frameskip, 75},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Votescreen Scaling", &cv_votebgscaling, 80},
|
||||
{IT_STRING | IT_CVAR, NULL, "Votescreen Scaling", &cv_votebgscaling, 85},
|
||||
|
||||
#ifdef HWRENDER
|
||||
{IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_glscreentextures, 90},
|
||||
{IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_glscreentextures, 95},
|
||||
#ifdef USE_FBO_OGL
|
||||
{IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_glframebuffer, 95},
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 105},
|
||||
{IT_DISABLED, NULL, "", NULL, 115}, // dummy text
|
||||
{IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_glframebuffer, 100},
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 110},
|
||||
{IT_DISABLED, NULL, "", NULL, 120}, // dummy text
|
||||
#else
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 100},
|
||||
{IT_DISABLED, NULL, "", NULL, 110}, // dummy text
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 110},
|
||||
{IT_DISABLED, NULL, "", NULL, 120}, // dummy text
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
@@ -975,12 +974,13 @@ static const char* OP_ExpTooltips[] =
|
||||
"Sets minimum sector brightness, useful for dark areas.",
|
||||
//"Should the directional lightning be randomized each map?\nTakes effect on next map load.",
|
||||
"Toggle being able to see the sky.",
|
||||
"Toggle skydome.", // idk man someone give a better description of this
|
||||
"Preload all level textures on level load.\nMassively reduces texture related stuttering during gameplay\nat the cost of longer level loading times.\nDisable this if you experience timeouts during level switches.",
|
||||
"Change the FPS counter sampling method\nInaccurate updates slower\nand might miss sudden framerate changes and drops,\nproviding a more averaged result.\nAccurate updates faster, but might be less readable.", // how to ingles??
|
||||
"Skips rendering frames if game logic takes too long\npreventing gameplay issues during performance drops.", // idk im shit as describing things
|
||||
"Different methods of scaling the votescreen backgrounds.",
|
||||
#ifdef HWRENDER
|
||||
"Disabling Screen Textures may result in a performance boost\nbut will break certain effects.\nScreen textures are required at resolutions lower than your desktop resolution!"
|
||||
"Disabling Screen Textures may result in a performance boost\nbut will break certain effects.\nScreen textures are required at resolutions lower than your desktop resolution!",
|
||||
#ifdef USE_FBO_OGL
|
||||
"Allows the game to downsample from a higher resolution\nthan your display in OpenGL renderer mode.\nRequires a GPU with atleast OpenGL 2.1 support.",
|
||||
#endif
|
||||
@@ -996,6 +996,7 @@ enum
|
||||
op_exp_secbright,
|
||||
//op_exp_dirlight,
|
||||
op_exp_skybox,
|
||||
op_exp_skydome,
|
||||
op_exp_texcache,
|
||||
op_exp_accuratefps,
|
||||
op_exp_frameskip,
|
||||
@@ -1009,7 +1010,6 @@ enum
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef HWRENDER
|
||||
static menuitem_t OP_OpenGLOptionsMenu[] =
|
||||
{
|
||||
@@ -1066,7 +1066,6 @@ enum
|
||||
op_gl_shearing,
|
||||
op_gl_renderdist,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static menuitem_t OP_SoundOptionsMenu[] =
|
||||
@@ -1077,8 +1076,7 @@ static menuitem_t OP_SoundOptionsMenu[] =
|
||||
{IT_STRING|IT_CVAR|IT_CV_NOPRINT, NULL, "Music", &cv_gamedigimusic, 30},
|
||||
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Music Volume", &cv_digmusicvolume, 38},
|
||||
|
||||
//#ifndef NO_MIDI
|
||||
#if 0
|
||||
#if 0 //#ifndef NO_MIDI
|
||||
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "MIDI Volume", &cv_midimusicvolume, 46},
|
||||
|
||||
{IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 60},
|
||||
@@ -1113,8 +1111,7 @@ static const char* OP_SoundTooltips[] =
|
||||
"Volume of Sound effects.",
|
||||
"Turn Music on or off.",
|
||||
"Volume of Music.",
|
||||
//#ifndef NO_MIDI
|
||||
#if 0
|
||||
#if 0 //#ifndef NO_MIDI
|
||||
"Volume of Midi Music.",
|
||||
#endif
|
||||
"Reverse left and right channels of audio.",
|
||||
@@ -1174,7 +1171,7 @@ static const char* OP_SoundAdvancedTooltips[] =
|
||||
"Should the Grow music be on or off?",
|
||||
"Should the Invulnerability music be on or off?",
|
||||
"Should music be kept when restarting the map?",
|
||||
"Should the Intro fanfare be skipped\nand map music be played on map start?",
|
||||
"Should the Intro fanfare be skipped\nand map music be played on map start?\nNote that this WILL skip sounds played by the map before round start as well!",
|
||||
"Controls Sound effects caching.\nKeep will retain previously played sound effects in cache." // man idk how to describe this in a non awful way lmao
|
||||
"\nOn will preload all sound effects.\nEliminates sound-related lag and stutters but increases memory usage.",
|
||||
"Size of the Audio Buffer\nreducing it will result in less sound latency\nbut may cause issues such as crackling or distorted Sound.",
|
||||
@@ -1408,44 +1405,70 @@ static const char* OP_PlayerCamOptionsTooltips[] =
|
||||
static menuitem_t OP_ChatOptionsMenu[] =
|
||||
{
|
||||
// will ANYONE who doesn't know how to use the console want to touch this one?
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 5}, // nonetheless...
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 5}, // nonetheless...
|
||||
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Chat Box Width", &cv_chatwidth, 20},
|
||||
NULL, "Chat Box Width", &cv_chatwidth, 10},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Chat Box Height", &cv_chatheight, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Center Text in Chat", &cv_chatcentertext, 40},
|
||||
NULL, "Chat Box Height", &cv_chatheight, 15},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Horizontal Offset", &cv_chat_xoffset, 20},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Vertical Offset", &cv_chat_yoffset, 25},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 55},
|
||||
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 65},
|
||||
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Max Chat Messages", &cv_chatlogsize, 85},
|
||||
{IT_STRING | IT_CVAR, NULL, "Center Text in Chat", &cv_chatcentertext, 35},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 45},
|
||||
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Max Chat Messages", &cv_chatlogsize, 55},
|
||||
{IT_STRING | IT_CVAR, NULL, "Display Character Limit", &cv_chat_showlimit, 60},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 105}, // shows ping above the framerate if we want to.
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping display style", &cv_pingstyle, 115},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping measurement", &cv_pingmeasurement, 125},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping icon", &cv_pingicon, 135},
|
||||
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 70}, // shows ping above the framerate if we want to.
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping display style", &cv_pingstyle, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping measurement", &cv_pingmeasurement, 80},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping icon", &cv_pingicon, 85},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show IP address in playerlist", &cv_shownodeip, 145},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show IP address in playerlist", &cv_shownodeip, 90},
|
||||
};
|
||||
|
||||
static const char* OP_ChatOptionsTooltips[] =
|
||||
{
|
||||
"Chat mode used for in-game chat.",
|
||||
"Width of chat box.",
|
||||
"Height of chat box.",
|
||||
"Width of the chat box.",
|
||||
"Height of the chat box.",
|
||||
"Horizontal Offset of the chat box.",
|
||||
"Vertical Offset of the chat box.",
|
||||
"Center text in the chat message pop ups.",
|
||||
"Chatbox background.",
|
||||
"Background for the chat message pop ups.",
|
||||
"Fadeout time for new chat message.",
|
||||
"Spam protection for in-game chat.",
|
||||
"Maxiumum amount of chat messages to look back at.",
|
||||
"Show how many characters you have left to type in the chat.",
|
||||
"Show player ping.",
|
||||
"Choose the looks of the ping display.", // this is ass idk english lmao
|
||||
"Choose the style of the ping display.",
|
||||
"Measurement used for ping.",
|
||||
"Visibility of ping icon.",
|
||||
"Should Player IP addresses be printed when using\nthe nodes or listplayers command?",
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
op_chat_mode,
|
||||
op_chat_boxwidth,
|
||||
op_chat_boxheight,
|
||||
op_chat_yoffs,
|
||||
op_chat_xoffs,
|
||||
op_chat_centertxt,
|
||||
op_chat_bgtint,
|
||||
op_chat_fadetime,
|
||||
op_chat_spamprotect,
|
||||
op_chat_maxmsg,
|
||||
op_chat_charlmt,
|
||||
op_chat_showping,
|
||||
op_chat_pingstyle,
|
||||
op_chat_pingmeasr,
|
||||
op_chat_pingico,
|
||||
op_chat_nodeip,
|
||||
};
|
||||
|
||||
static menuitem_t OP_GameOptionsMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Random Item Toggles...", &OP_MonitorToggleDef, 10},
|
||||
@@ -1631,7 +1654,7 @@ static menuitem_t OP_AccessibilityMenu[] =
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Video Color Settings...", &OP_ColorOptionsDef, 30},
|
||||
|
||||
{IT_STRING|IT_CVAR, NULL, "Reduce Effects", &cv_reducevfx, 35},
|
||||
{IT_STRING|IT_CVAR, NULL, "Midnight Channel Flicker", &cv_lessflicker, 40}, // obsolete now? or still better be a seperate toggle?
|
||||
{IT_STRING|IT_CVAR, NULL, "Less Midnight Channel Flicker", &cv_lessflicker, 40}, // obsolete now? or still better be a seperate toggle?
|
||||
|
||||
{IT_STRING|IT_CVAR, NULL, "Minimum Sector Brightness", &cv_secbright, 45},
|
||||
|
||||
@@ -1767,20 +1790,23 @@ static menuitem_t OP_PlayerDistortMenu[] =
|
||||
{IT_STRING | IT_CVAR, NULL, "Slope Rotation Distance", &cv_sloperolldist, 15},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Rotate Players when Sliptiding", &cv_sliptideroll, 25},
|
||||
{IT_STRING | IT_CVAR, NULL, "Rotate Sparks and Boost Trails", &cv_sparkroll, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Rotate Bananas on Throw", &cv_bananthrowroll, 35},
|
||||
{IT_STRING | IT_CVAR, NULL, "Stair Janking Effect", &cv_stairjank, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Stair Janking Sound Effect", &cv_stairjanksfx, 35}, // idk if that should be here but i dont care atm
|
||||
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Player Stretch Factor", &cv_gravstretch, 45},
|
||||
{IT_STRING | IT_CVAR, NULL, "Squish Sound Effect", &cv_slamsound, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Rotate Sparks and Boost Trails", &cv_sparkroll, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Rotate Bananas on Throw", &cv_bananthrowroll, 45},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop", &cv_saltyhop, 60},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saltyhop Height", &cv_saltyheight, 65},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Sound Effect", &cv_saltyhopsfx, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Squish", &cv_saltysquish, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Roll", &cv_saltyroll, 80},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Player Stretch Factor", &cv_gravstretch, 55},
|
||||
{IT_STRING | IT_CVAR, NULL, "Squish Sound Effect", &cv_slamsound, 60},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Squishdance", &cv_squishdance, 90},
|
||||
{IT_STRING | IT_CVAR, NULL, "Squishdance Speed", &cv_squishdancespeed, 96},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop", &cv_saltyhop, 70},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saltyhop Height", &cv_saltyheight, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Sound Effect", &cv_saltyhopsfx, 80},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Squish", &cv_saltysquish, 85},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Roll", &cv_saltyroll, 90},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Squishdance", &cv_squishdance, 100},
|
||||
{IT_STRING | IT_CVAR, NULL, "Squishdance Speed", &cv_squishdancespeed, 106}, // why is this offset by 6? idk cant remember lulul
|
||||
};
|
||||
|
||||
static const char* OP_PlayerDistortTooltips[] =
|
||||
@@ -1789,6 +1815,8 @@ static const char* OP_PlayerDistortTooltips[] =
|
||||
"Sprite rotation on slopes. Can either be just players or all objects.",
|
||||
"Distance object rotation should be visable.",
|
||||
"Player rotation when sliptiding.",
|
||||
"Slightly tilt the player when driving over stairs or small bumps.",
|
||||
"Sound effect when driving over stairs or small bumps.",
|
||||
"Rotation of a player's boost trails and drift sparks.",
|
||||
"Should banans rotate when thrown?\nAnd should they stay rotated when on the ground?",
|
||||
"Player squash and stretch.",
|
||||
@@ -1799,7 +1827,7 @@ static const char* OP_PlayerDistortTooltips[] =
|
||||
"Player hop squash and stretch.",
|
||||
"Should the player rotation be kept during player hop.",
|
||||
"Do a funny squishy dance when holding CUSTOM 3.",
|
||||
"Speed of the Squishy dance in BPM.",
|
||||
"Speed of the Squishy dance in SPM (Squishes Per Minute).",
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -1808,6 +1836,8 @@ enum
|
||||
sloperotate,
|
||||
slrotatedist,
|
||||
sliptide,
|
||||
stairjank,
|
||||
stairjanksfx,
|
||||
sparkrotate,
|
||||
bananrotat,
|
||||
stretchyplayer,
|
||||
@@ -2591,7 +2621,7 @@ menu_t OP_Player2CamOptionsDef = DEFAULTMENUSTYLE(NULL, OP_Player2CamOptionsMenu
|
||||
menu_t OP_Player3CamOptionsDef = DEFAULTMENUSTYLE(NULL, OP_Player3CamOptionsMenu, &OP_CamOptionsDef, 30, 30, OP_PlayerCamOptionsTooltips);
|
||||
menu_t OP_Player4CamOptionsDef = DEFAULTMENUSTYLE(NULL, OP_Player4CamOptionsMenu, &OP_CamOptionsDef, 30, 30, OP_PlayerCamOptionsTooltips);
|
||||
|
||||
menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE("M_HUD", OP_ChatOptionsMenu, &OP_HUDOptionsDef, 30, 30, OP_ChatOptionsTooltips);
|
||||
menu_t OP_ChatOptionsDef = DEFAULTSCROLLSTYLE("M_HUD", OP_ChatOptionsMenu, &OP_HUDOptionsDef, 30, 25, OP_ChatOptionsTooltips);
|
||||
|
||||
menu_t OP_SoundAdvancedDef = DEFAULTSCROLLSTYLE("M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30, OP_SoundAdvancedTooltips);
|
||||
|
||||
@@ -2716,6 +2746,15 @@ void PDistort_menu_Onchange(void)
|
||||
OP_PlayerDistortMenu[slrotatedist].status = IT_GRAYEDOUT;
|
||||
OP_PlayerDistortMenu[saltroll].status = IT_GRAYEDOUT;
|
||||
}
|
||||
|
||||
if (cv_stairjank.value)
|
||||
{
|
||||
OP_PlayerDistortMenu[stairjanksfx].status = IT_STRING | IT_CVAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
OP_PlayerDistortMenu[stairjanksfx].status = IT_GRAYEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
void Bird_menu_Onchange(void)
|
||||
|
||||
@@ -47,6 +47,7 @@ struct perfstatrow {
|
||||
static ps_metric_t ps_frametime = {0};
|
||||
|
||||
ps_metric_t ps_tictime = {0};
|
||||
ps_metric_t ps_prevtictime = {0};
|
||||
|
||||
ps_metric_t ps_playerthink_time = {0};
|
||||
ps_metric_t ps_thinkertime = {0};
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef struct
|
||||
#define PS_STOP_TIMING(metric) metric.value.p = I_GetPreciseTime() - metric.value.p
|
||||
|
||||
extern ps_metric_t ps_tictime;
|
||||
extern ps_metric_t ps_prevtictime;
|
||||
|
||||
extern ps_metric_t ps_playerthink_time;
|
||||
extern ps_metric_t ps_thinkertime;
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key);
|
||||
// If currently typing something that looks like an existing emote, return suggestions for it
|
||||
boolean M_TextInputHandleEmotes(textinput_t *input, INT32 key, emote_autocomplete_t *autocomplete);
|
||||
|
||||
#define M_DrawTextInput(x, y, input, flags) M_DrawTextInputScroll((x), (y), (input), (flags), ((input)->buffer_size-1)*8)
|
||||
#define M_DrawTextInput(x, y, input, flags) M_DrawTextInputScroll((x), (y), (input), (flags), ((input)->buffer_size-2)*8)
|
||||
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH);
|
||||
|
||||
#endif
|
||||
+2
-2
@@ -2338,7 +2338,7 @@ void T_RaiseSector(levelspecthink_t *raise)
|
||||
fixed_t origspeed = raise->vars[3];
|
||||
|
||||
// Slow down as you get closer to the bottom
|
||||
raise->vars[3] = FixedMul(raise->vars[3],FixedDiv(raise->sector->ceilingheight - raise->vars[7], (raise->vars[5] - raise->vars[7])>>5));
|
||||
raise->vars[3] = FixedMul(raise->vars[3], FixedDiv(raise->sector->ceilingheight - raise->vars[7], (raise->vars[5] - raise->vars[7])>>5));
|
||||
|
||||
if (raise->vars[3] <= origspeed/16)
|
||||
raise->vars[3] = origspeed/16;
|
||||
@@ -2349,7 +2349,7 @@ void T_RaiseSector(levelspecthink_t *raise)
|
||||
{
|
||||
fixed_t origspeed = raise->vars[3];
|
||||
// Slow down as you get closer to the top
|
||||
raise->vars[3] = FixedMul(raise->vars[3],FixedDiv(raise->vars[5] - raise->sector->ceilingheight, (raise->vars[5] - raise->vars[7])>>5));
|
||||
raise->vars[3] = FixedMul(raise->vars[3], FixedDiv(raise->vars[5] - raise->sector->ceilingheight, (raise->vars[5] - raise->vars[7])>>5));
|
||||
|
||||
if (raise->vars[3] <= origspeed/16)
|
||||
raise->vars[3] = origspeed/16;
|
||||
|
||||
+106
-72
@@ -1462,49 +1462,15 @@ boolean P_CheckRacers(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Kills an object.
|
||||
*
|
||||
* \param target The victim.
|
||||
* \param inflictor The attack weapon. May be NULL (environmental damage).
|
||||
* \param source The attacker. May be NULL.
|
||||
* \todo Cleanup, refactor, split up.
|
||||
* \sa P_DamageMobj
|
||||
*/
|
||||
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
static void P_UpdateRemovedOrbital(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
{
|
||||
mobjtype_t item;
|
||||
mobj_t *mo;
|
||||
int ms;
|
||||
|
||||
if (target->flags & (MF_ENEMY|MF_BOSS))
|
||||
target->momx = target->momy = target->momz = 0;
|
||||
|
||||
// SRB2kart
|
||||
if (target->type != MT_PLAYER && !(target->flags & MF_MONITOR)
|
||||
&& !(target->type == MT_ORBINAUT || target->type == MT_ORBINAUT_SHIELD
|
||||
|| target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD
|
||||
|| target->type == MT_BANANA || target->type == MT_BANANA_SHIELD
|
||||
|| target->type == MT_EGGMANITEM || target->type == MT_EGGMANITEM_SHIELD
|
||||
|| target->type == MT_BALLHOG || target->type == MT_SPB)) // kart dead items
|
||||
target->flags |= MF_NOGRAVITY; // Don't drop Tails 03-08-2000
|
||||
else
|
||||
target->flags &= ~MF_NOGRAVITY; // lose it if you for whatever reason have it, I'm looking at you shields
|
||||
//
|
||||
|
||||
if (target->flags2 & MF2_NIGHTSPULL)
|
||||
P_SetTarget(&target->tracer, NULL);
|
||||
|
||||
// dead target is no more shootable
|
||||
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.
|
||||
|
||||
if (LUA_HookMobjDeath(target, inflictor, source) || P_MobjWasRemoved(target))
|
||||
return;
|
||||
|
||||
// SRB2kart
|
||||
// I wish I knew a better way to do this
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (!P_MobjWasRemoved(target->target) && target->target->player && !P_MobjWasRemoved(target->target->player->mo))
|
||||
#else
|
||||
if (target->target && target->target->player && target->target->player->mo)
|
||||
#endif
|
||||
{
|
||||
if (target->target->player->kartstuff[k_eggmanheld] && target->type == MT_EGGMANITEM_SHIELD)
|
||||
target->target->player->kartstuff[k_eggmanheld] = 0;
|
||||
@@ -1517,7 +1483,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
{
|
||||
if (target->movedir != 0 && target->movedir < (UINT16)target->target->player->kartstuff[k_itemamount])
|
||||
{
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (!P_MobjWasRemoved(target->target->hnext))
|
||||
#else
|
||||
if (target->target->hnext)
|
||||
#endif
|
||||
K_KillBananaChain(target->target->hnext, inflictor, source);
|
||||
|
||||
target->target->player->kartstuff[k_itemamount] = 0;
|
||||
@@ -1546,14 +1516,60 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
P_SetTarget(&target->target->hnext, NULL);
|
||||
}
|
||||
}
|
||||
// Above block does not clean up rocket sneakers when a player dies, so we need to do it here target->target is null when using rocket sneakers
|
||||
}
|
||||
|
||||
|
||||
/** Kills an object.
|
||||
*
|
||||
* \param target The victim.
|
||||
* \param inflictor The attack weapon. May be NULL (environmental damage).
|
||||
* \param source The attacker. May be NULL.
|
||||
* \todo Cleanup, refactor, split up.
|
||||
* \sa P_DamageMobj
|
||||
*/
|
||||
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
{
|
||||
mobjtype_t item;
|
||||
mobj_t *mo;
|
||||
int ms;
|
||||
|
||||
if (target->flags & (MF_ENEMY|MF_BOSS))
|
||||
target->momx = target->momy = target->momz = 0;
|
||||
|
||||
// SRB2kart
|
||||
if (target->type != MT_PLAYER
|
||||
&& !(target->flags & MF_MONITOR)
|
||||
&& !(target->type == MT_ORBINAUT || target->type == MT_ORBINAUT_SHIELD
|
||||
|| target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD
|
||||
|| target->type == MT_BANANA || target->type == MT_BANANA_SHIELD
|
||||
|| target->type == MT_EGGMANITEM || target->type == MT_EGGMANITEM_SHIELD
|
||||
|| target->type == MT_BALLHOG || target->type == MT_SPB)) // kart dead items
|
||||
target->flags |= MF_NOGRAVITY; // Don't drop Tails 03-08-2000
|
||||
else
|
||||
target->flags &= ~MF_NOGRAVITY; // lose it if you for whatever reason have it, I'm looking at you shields
|
||||
//
|
||||
|
||||
if (target->flags2 & MF2_NIGHTSPULL)
|
||||
P_SetTarget(&target->tracer, NULL);
|
||||
|
||||
// dead target is no more shootable
|
||||
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.
|
||||
|
||||
if (LUA_HookMobjDeath(target, inflictor, source) || P_MobjWasRemoved(target))
|
||||
return;
|
||||
|
||||
P_UpdateRemovedOrbital(target, inflictor, source);
|
||||
|
||||
if (target->player)
|
||||
{
|
||||
// Above block does not clean up rocket sneakers when a player dies, so we need to do it here target->target is null when using rocket sneakers
|
||||
K_DropRocketSneaker(target->player);
|
||||
|
||||
// Let EVERYONE know what happened to a player! 01-29-2002 Tails
|
||||
if (target->player && !target->player->spectator)
|
||||
{
|
||||
target->flags2 &= ~MF2_DONTDRAW;
|
||||
// Let EVERYONE know what happened to a player! 01-29-2002 Tails
|
||||
if (!target->player->spectator)
|
||||
target->flags2 &= ~MF2_DONTDRAW;
|
||||
}
|
||||
|
||||
// if killed by a player
|
||||
@@ -1563,6 +1579,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
{
|
||||
P_SetTarget(&target->target, source);
|
||||
source->player->numboxes++;
|
||||
|
||||
if (cv_itemrespawn.value && (netgame || multiplayer))
|
||||
{
|
||||
target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation
|
||||
@@ -1580,35 +1597,41 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
|
||||
target->player->playerstate = PST_DEAD;
|
||||
|
||||
if (cv_fading.value && P_IsLocalPlayer(target->player))
|
||||
if (P_IsLocalPlayer(target->player))
|
||||
{
|
||||
if (netgame || multiplayer)
|
||||
ms = cv_respawntime.value * 1000;
|
||||
else
|
||||
ms = 1000;
|
||||
if (cv_fading.value)
|
||||
{
|
||||
if (netgame || multiplayer)
|
||||
ms = cv_respawntime.value * 1000;
|
||||
else
|
||||
ms = 1000;
|
||||
|
||||
/*
|
||||
If the time spent with the music paused is less than half
|
||||
a second, continue playing the song (just mute it).
|
||||
*/
|
||||
if ((ms - cv_respawnfademusicout.value) < 500)
|
||||
S_FadeMusic(0, cv_respawnfademusicout.value);
|
||||
else
|
||||
S_FadeOutStopMusic(cv_respawnfademusicout.value);
|
||||
}
|
||||
/*
|
||||
* If the time spent with the music paused is less than half
|
||||
* a second, continue playing the song (just mute it).
|
||||
*/
|
||||
if ((ms - cv_respawnfademusicout.value) < 500)
|
||||
S_FadeMusic(0, cv_respawnfademusicout.value);
|
||||
else
|
||||
S_FadeOutStopMusic(cv_respawnfademusicout.value);
|
||||
}
|
||||
|
||||
for (UINT8 i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (target->player == P_GetLocalPlayerForNum(i))
|
||||
if (target->player == &players[consoleplayer])
|
||||
{
|
||||
// don't die in auto map,
|
||||
// switch view prior to dying
|
||||
if (i == 0 && automapactive)
|
||||
if (automapactive)
|
||||
AM_Stop();
|
||||
}
|
||||
|
||||
// added : 22-02-98: recenter view for next life...
|
||||
localaiming[i] = 0;
|
||||
break;
|
||||
for (UINT8 i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (target->player == P_GetLocalPlayerForNum(i))
|
||||
{
|
||||
// added : 22-02-98: recenter view for next life...
|
||||
localaiming[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1678,7 +1701,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
else
|
||||
prandom = P_RandomKey(5); // No placable object, just use a random number.
|
||||
|
||||
switch(prandom)
|
||||
switch (prandom)
|
||||
{
|
||||
default: item = MT_BUNNY; break;
|
||||
case 1: item = MT_BIRD; break;
|
||||
@@ -2222,16 +2245,26 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
return false;
|
||||
|
||||
// well no clue but this may happen ig
|
||||
if (!target || (target->health <= 0))
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (P_MobjWasRemoved(target))
|
||||
#else
|
||||
if (!target)
|
||||
#endif
|
||||
return false;
|
||||
|
||||
if (target->health <= 0)
|
||||
return false;
|
||||
|
||||
// Spectator handling
|
||||
if (netgame)
|
||||
{
|
||||
if (damage == DMG_SPECTATOR && target->player && target->player->spectator)
|
||||
damage = DMG_INSTAKILL;
|
||||
else if (target->player && target->player->spectator)
|
||||
return false;
|
||||
if (target->player && target->player->spectator)
|
||||
{
|
||||
if (damage == DMG_SPECTATOR)
|
||||
damage = DMG_INSTAKILL;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source && source->player && source->player->spectator)
|
||||
return false;
|
||||
@@ -2337,6 +2370,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
{
|
||||
if (source == target)
|
||||
return false; // Don't hit yourself with your own paraloop, baka
|
||||
|
||||
if (source && source->player && !cv_friendlyfire.value
|
||||
&& (gametype == GT_COOP
|
||||
|| (G_GametypeHasTeams() && target->player->ctfteam == source->player->ctfteam)))
|
||||
@@ -2386,7 +2420,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
|
||||
else if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->powers[pw_flashing])
|
||||
{
|
||||
if (!force) // shoulddamage bypasses all of that.
|
||||
if (!force) // shoulddamage bypasses all of that.
|
||||
{
|
||||
K_DoInstashield(player);
|
||||
return false;
|
||||
|
||||
+83
-8
@@ -719,11 +719,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
if (thing->type != MT_PLAYER)
|
||||
return true;
|
||||
|
||||
if (thing->player && thing->player->powers[pw_flashing])
|
||||
return true;
|
||||
|
||||
if (thing->type == MT_PLAYER && thing->player)
|
||||
if (thing->player)
|
||||
{
|
||||
if (thing->player->powers[pw_flashing])
|
||||
return true;
|
||||
|
||||
if (tmthing->state == &states[S_MINEEXPLOSION1])
|
||||
K_ExplodePlayer(thing->player, tmthing->target, tmthing);
|
||||
else
|
||||
@@ -1077,6 +1077,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
thing->momy -= FixedMul(PUSHACCEL, thing->scale);
|
||||
tmthing->momy += FixedMul(PUSHACCEL, thing->scale);
|
||||
}
|
||||
|
||||
if (tmthing->momx > 0 && tmthing->momx > FixedMul(4*FRACUNIT, thing->scale)
|
||||
&& tmthing->momx > thing->momx)
|
||||
{
|
||||
@@ -1094,6 +1095,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
thing->momx = FixedMul(thing->info->speed, thing->scale);
|
||||
else if (thing->momx < -FixedMul(thing->info->speed, thing->scale))
|
||||
thing->momx = -FixedMul(thing->info->speed, thing->scale);
|
||||
|
||||
if (thing->momy > FixedMul(thing->info->speed, thing->scale))
|
||||
thing->momy = FixedMul(thing->info->speed, thing->scale);
|
||||
else if (thing->momy < -FixedMul(thing->info->speed, thing->scale))
|
||||
@@ -1105,6 +1107,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
tmthing->momx = FixedMul(4*FRACUNIT, thing->scale);
|
||||
else if (tmthing->momx < FixedMul(-4*FRACUNIT, thing->scale))
|
||||
tmthing->momx = FixedMul(-4*FRACUNIT, thing->scale);
|
||||
|
||||
if (tmthing->momy > FixedMul(4*FRACUNIT, thing->scale))
|
||||
tmthing->momy = FixedMul(4*FRACUNIT, thing->scale);
|
||||
else if (tmthing->momy < FixedMul(-4*FRACUNIT, thing->scale))
|
||||
@@ -1126,6 +1129,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
P_TouchSpecialThing(thing, tmthing, true); // can remove thing
|
||||
return true;
|
||||
}
|
||||
|
||||
// check again for special pickup
|
||||
if (tmthing->flags & MF_SPECIAL && thing->player)
|
||||
{
|
||||
@@ -1575,13 +1579,13 @@ static boolean PIT_CheckLine(line_t *ld)
|
||||
tmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT] ||
|
||||
tmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] ||
|
||||
tmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
|
||||
return true;
|
||||
return true; // didn't hit it
|
||||
|
||||
if (ld->polyobj && !(ld->polyobj->flags & POF_SOLID))
|
||||
return true;
|
||||
|
||||
if (P_BoxOnLineSide(tmbbox, ld) != -1)
|
||||
return true;
|
||||
return true; // didn't hit it
|
||||
|
||||
if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag.
|
||||
{
|
||||
@@ -2371,8 +2375,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
fixed_t tryx = thing->x;
|
||||
fixed_t tryy = thing->y;
|
||||
fixed_t radius = thing->radius;
|
||||
fixed_t thingtop ;//= thing->z + thing->height;
|
||||
fixed_t thingtop;//= thing->z + thing->height;
|
||||
fixed_t startingonground = P_IsObjectOnGround(thing);
|
||||
fixed_t stairjank = 0;
|
||||
pslope_t *oldslope = thing->standingslope;
|
||||
INT32 special = -1;
|
||||
floatok = false;
|
||||
|
||||
@@ -2422,7 +2428,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
|
||||
if (thing->player)
|
||||
{
|
||||
if (special == -1)
|
||||
if (special == -1) // this should use the target coords not the ones were started with, but cant fix that for compat reasons!
|
||||
special = GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1);
|
||||
|
||||
// If using type Section1:13, double the maxstep.
|
||||
@@ -2446,11 +2452,19 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
|
||||
thingtop = thing->z + thing->height;
|
||||
|
||||
const boolean flipped =
|
||||
(thing->eflags & MFE_VERTICALFLIP) != 0;
|
||||
|
||||
// Step up
|
||||
if (thing->z < tmfloorz)
|
||||
{
|
||||
if (tmfloorz - thing->z <= maxstep)
|
||||
{
|
||||
if (maxstep > 0 && !flipped)
|
||||
{
|
||||
stairjank = (tmfloorz - thing->z);
|
||||
}
|
||||
|
||||
thing->z = thing->floorz = tmfloorz;
|
||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
@@ -2463,6 +2477,11 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
{
|
||||
if (thingtop - tmceilingz <= maxstep)
|
||||
{
|
||||
if (maxstep > 0 && flipped)
|
||||
{
|
||||
stairjank = (thingtop - tmceilingz);
|
||||
}
|
||||
|
||||
thing->z = ( thing->ceilingz = tmceilingz ) - thing->height;
|
||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
@@ -2479,11 +2498,21 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
|
||||
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
|
||||
{
|
||||
if (flipped)
|
||||
{
|
||||
stairjank = (tmceilingz - thingtop);
|
||||
}
|
||||
|
||||
thing->z = (thing->ceilingz = tmceilingz) - thing->height;
|
||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
|
||||
{
|
||||
if (!flipped)
|
||||
{
|
||||
stairjank = (thing->z - tmfloorz);
|
||||
}
|
||||
|
||||
thing->z = thing->floorz = tmfloorz;
|
||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
@@ -2559,6 +2588,52 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
else // don't set standingslope if you're not going to clip against it
|
||||
thing->standingslope = NULL;
|
||||
|
||||
/* FIXME: slope step down (even up) has some false
|
||||
positives, so just ignore them entirely. */
|
||||
if (stairjank && !oldslope && !thing->standingslope && thing->player && !thing->player->spectator)
|
||||
{
|
||||
/* use a shorter sound if not two tics have passed
|
||||
* since the last step */
|
||||
//S_ReducedVFXSound(thing, (thing->player->stairjank >= 16 ? sfx_s23b : sfx_s268), NULL);
|
||||
//S_StartSound(thing, (thing->player->stairjank >= 16 ? sfx_s23b : sfx_s268));
|
||||
// sound does not work out all that well for kart maps
|
||||
|
||||
// best i can do...
|
||||
if (cv_stairjanksfx.value)
|
||||
S_StartSoundAtVolume(thing, (thing->player->stairjank >= 8 ? sfx_s23b : sfx_s268), 192); // dont blast this at full volume lul
|
||||
|
||||
//if (!thing->player->stairjank)
|
||||
{
|
||||
// 90 degrees to direction you're facing
|
||||
fixed_t dirx = -FINESINE(thing->angle>>ANGLETOFINESHIFT);
|
||||
fixed_t diry = FINECOSINE(thing->angle>>ANGLETOFINESHIFT);
|
||||
fixed_t offset = thing->radius;
|
||||
|
||||
if (leveltime % 8 < 4)
|
||||
{
|
||||
dirx = -dirx;
|
||||
diry = -diry;
|
||||
}
|
||||
|
||||
mobj_t * spark = P_SpawnMobj(thing->x + FixedMul(dirx, offset), thing->y + FixedMul(diry, offset), thing->z, MT_DRIFTDUST);
|
||||
spark->momx = FixedMul(dirx, FRACUNIT) + (6 + ((int)leveltime % 5))*(thing->momx)/10;
|
||||
spark->momy = FixedMul(diry, FRACUNIT) + (6 + ((int)leveltime % 5))*(thing->momy)/10;
|
||||
spark->momz = 5*FRACUNIT;
|
||||
spark->scale = mapobjectscale/5;
|
||||
spark->destscale = mapobjectscale/2;
|
||||
spark->islocal = true;
|
||||
//spark->fuse = 9;
|
||||
spark->color = SKINCOLOR_WHITE;
|
||||
//spark->cusval = K_StairJankFlip(ANGLE_90);
|
||||
P_SetTarget(&spark->target, thing);
|
||||
//P_SetTarget(&spark->owner, thing);
|
||||
//spark->renderflags |= RF_REDUCEVFX;
|
||||
}
|
||||
|
||||
thing->player->stairjank = 9;
|
||||
//thing->player->stairjank = 17;
|
||||
}
|
||||
|
||||
thing->x = x;
|
||||
thing->y = y;
|
||||
|
||||
|
||||
+9
-2
@@ -242,7 +242,7 @@ void P_CameraLineOpening(line_t *linedef)
|
||||
sector_t *back;
|
||||
fixed_t frontfloor, frontceiling, backfloor, backceiling;
|
||||
|
||||
if (linedef->sidenum[1] == 0xffff)
|
||||
if (linedef->sidenum[1] == NO_INDEX)
|
||||
{
|
||||
// single sided line
|
||||
openrange = 0;
|
||||
@@ -398,7 +398,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||
{
|
||||
sector_t *front, *back;
|
||||
|
||||
if (linedef->sidenum[1] == 0xffff)
|
||||
if (linedef->sidenum[1] == NO_INDEX)
|
||||
{
|
||||
// single sided line
|
||||
openrange = 0;
|
||||
@@ -972,6 +972,10 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
|
||||
// First index is really empty, so +1 it.
|
||||
for (list = blockmaplump + offset + 1; *list != -1; list++)
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
if (*list < 0 || (UINT32)*list >= numlines)
|
||||
I_Error("P_BlockLinesIterator: index >= numlines");
|
||||
#endif
|
||||
ld = &lines[*list];
|
||||
|
||||
if (ld->validcount == validcount)
|
||||
@@ -1000,11 +1004,13 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *))
|
||||
for (mobj = blocklinks[y*bmapwidth + x]; mobj; mobj = bnext)
|
||||
{
|
||||
P_SetTarget(&bnext, mobj->bnext); // We want to note our reference to bnext here incase it is MF_NOTHINK and gets removed!
|
||||
|
||||
if (!func(mobj))
|
||||
{
|
||||
P_SetTarget(&bnext, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (P_MobjWasRemoved(tmthing) // func just popped our tmthing, cannot continue.
|
||||
|| (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue.
|
||||
{
|
||||
@@ -1012,6 +1018,7 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
P_SetTarget(&bnext, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
+188
-139
@@ -1249,7 +1249,6 @@ static void P_PushableCheckBustables(mobj_t *mo)
|
||||
if (rover->master->frontsector->crumblestate)
|
||||
continue;
|
||||
|
||||
topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
|
||||
bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
|
||||
|
||||
// Height checks
|
||||
@@ -1261,29 +1260,34 @@ static void P_PushableCheckBustables(mobj_t *mo)
|
||||
if (mo->z+mo->height > bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->flags & FF_SPINBUST)
|
||||
{
|
||||
if (mo->z+mo->momz > topheight)
|
||||
continue;
|
||||
|
||||
if (mo->z+mo->height < bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->flags & FF_SHATTER)
|
||||
{
|
||||
if (mo->z+mo->momz > topheight)
|
||||
continue;
|
||||
|
||||
if (mo->z+mo->momz + mo->height < bottomheight)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo->z >= topheight)
|
||||
continue;
|
||||
topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
|
||||
|
||||
if (mo->z+mo->height < bottomheight)
|
||||
continue;
|
||||
if (rover->flags & FF_SPINBUST)
|
||||
{
|
||||
if (mo->z+mo->momz > topheight)
|
||||
continue;
|
||||
|
||||
if (mo->z+mo->height < bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->flags & FF_SHATTER)
|
||||
{
|
||||
if (mo->z+mo->momz > topheight)
|
||||
continue;
|
||||
|
||||
if (mo->z+mo->momz + mo->height < bottomheight)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo->z >= topheight)
|
||||
continue;
|
||||
|
||||
if (mo->z+mo->height < bottomheight)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
EV_CrumbleChain(node->m_sector, rover);
|
||||
@@ -2950,7 +2954,8 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||
if ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= FixedMul(mobj->info->height, mobj->scale)>>1)
|
||||
return;
|
||||
|
||||
if ((mobj->eflags & MFE_GOOWATER || wasingoo)) { // Decide what happens to your momentum when you enter/leave goopy water.
|
||||
if ((mobj->eflags & MFE_GOOWATER || wasingoo)) // Decide what happens to your momentum when you enter/leave goopy water.
|
||||
{
|
||||
if (P_MobjFlip(mobj)*mobj->momz < 0) // You are entering the goo?
|
||||
mobj->momz = FixedMul(mobj->momz, FixedDiv(2*FRACUNIT, 5*FRACUNIT)); // kill momentum significantly, to make the goo feel thick.
|
||||
}
|
||||
@@ -2964,6 +2969,7 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||
{
|
||||
// Spawn a splash
|
||||
mobj_t *splish;
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[MT_SPLISH].height, mobj->scale), MT_SPLISH);
|
||||
@@ -2972,6 +2978,7 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||
}
|
||||
else
|
||||
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, MT_SPLISH);
|
||||
|
||||
splish->destscale = mobj->scale;
|
||||
P_SetScale(splish, mobj->scale);
|
||||
}
|
||||
@@ -3372,7 +3379,11 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
||||
I_Assert(mobj->player != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mobj));
|
||||
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
#else
|
||||
if (!mobj)
|
||||
#endif
|
||||
return;
|
||||
|
||||
P_MobjCheckWater(mobj);
|
||||
@@ -5161,9 +5172,9 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||
{
|
||||
// Stunned after vector form
|
||||
if (mobj->movedir > ANGLE_180)
|
||||
mobj->angle -= FixedAngle(FixedMul(AngleFixed(InvAngle(mobj->movedir)),FixedDiv(mobj->reactiontime<<FRACBITS,24<<FRACBITS)));
|
||||
mobj->angle -= FixedAngle(FixedMul(AngleFixed(InvAngle(mobj->movedir)), FixedDiv(mobj->reactiontime<<FRACBITS,24<<FRACBITS)));
|
||||
else
|
||||
mobj->angle += FixedAngle(FixedMul(AngleFixed(mobj->movedir),FixedDiv(mobj->reactiontime<<FRACBITS,24<<FRACBITS)));
|
||||
mobj->angle += FixedAngle(FixedMul(AngleFixed(mobj->movedir), FixedDiv(mobj->reactiontime<<FRACBITS,24<<FRACBITS)));
|
||||
|
||||
mobj->reactiontime--;
|
||||
|
||||
@@ -5205,99 +5216,99 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||
// It's time to attack! What are we gonna do?!
|
||||
switch(mobj->movecount)
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
// Fly up and prepare for an attack!
|
||||
// We have to charge up first, so let's go up into the air
|
||||
P_SetMobjState(mobj, mobj->info->raisestate);
|
||||
if (mobj->floorz >= mobj->target->floorz)
|
||||
mobj->watertop = mobj->floorz + 256*FRACUNIT;
|
||||
else
|
||||
mobj->watertop = mobj->target->floorz + 256*FRACUNIT;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
{
|
||||
// Okay, we're up? Good, time to gather energy...
|
||||
if (mobj->health > mobj->info->damage)
|
||||
{ // No more bubble if we're broken (pinch phase)
|
||||
mobj_t *shield = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_MSSHIELD_FRONT);
|
||||
P_SetTarget(&mobj->tracer, shield);
|
||||
P_SetTarget(&shield->target, mobj);
|
||||
}
|
||||
else
|
||||
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
|
||||
mobj->fuse = 4*TICRATE;
|
||||
mobj->flags |= MF_PAIN;
|
||||
if (mobj->info->attacksound)
|
||||
S_StartSound(mobj, mobj->info->attacksound);
|
||||
A_FaceTarget(mobj);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
// We're all charged and ready now! Unleash the fury!!
|
||||
if (mobj->health > mobj->info->damage)
|
||||
{
|
||||
mobj_t *removemobj = mobj->tracer;
|
||||
P_SetTarget(&mobj->tracer, mobj->hnext);
|
||||
P_RemoveMobj(removemobj);
|
||||
}
|
||||
if (mobj->health <= mobj->info->damage)
|
||||
{
|
||||
// Attack 1: Pinball dash!
|
||||
if (mobj->health == 1)
|
||||
mobj->movedir = 0;
|
||||
case 0:
|
||||
default:
|
||||
// Fly up and prepare for an attack!
|
||||
// We have to charge up first, so let's go up into the air
|
||||
P_SetMobjState(mobj, mobj->info->raisestate);
|
||||
if (mobj->floorz >= mobj->target->floorz)
|
||||
mobj->watertop = mobj->floorz + 256*FRACUNIT;
|
||||
else
|
||||
mobj->movedir = 2;
|
||||
if (mobj->info->seesound)
|
||||
S_StartSound(mobj, mobj->info->seesound);
|
||||
P_SetMobjState(mobj, mobj->info->seestate);
|
||||
if (mobj->movedir == 2)
|
||||
mobj->threshold = 16; // bounce 16 times
|
||||
else
|
||||
mobj->threshold = 32; // bounce 32 times
|
||||
mobj->watertop = mobj->target->floorz + 16*FRACUNIT;
|
||||
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
|
||||
}
|
||||
else
|
||||
mobj->watertop = mobj->target->floorz + 256*FRACUNIT;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
{
|
||||
// Attack 2: Energy shot!
|
||||
mobj->movedir = 1;
|
||||
|
||||
if (mobj->health >= 8)
|
||||
mobj->extravalue1 = 0;
|
||||
else if (mobj->health >= 5)
|
||||
mobj->extravalue1 = 2;
|
||||
else if (mobj->health >= 4)
|
||||
mobj->extravalue1 = 1;
|
||||
else
|
||||
mobj->extravalue1 = 3;
|
||||
|
||||
switch(mobj->extravalue1)
|
||||
{
|
||||
case 0: // shoot once
|
||||
case 2: // spread-shot
|
||||
default:
|
||||
mobj->threshold = 2;
|
||||
break;
|
||||
case 1: // shoot 3 times
|
||||
mobj->threshold = 3*2;
|
||||
break;
|
||||
case 3: // shoot like a goddamn machinegun
|
||||
mobj->threshold = 8*2;
|
||||
break;
|
||||
// Okay, we're up? Good, time to gather energy...
|
||||
if (mobj->health > mobj->info->damage)
|
||||
{ // No more bubble if we're broken (pinch phase)
|
||||
mobj_t *shield = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_MSSHIELD_FRONT);
|
||||
P_SetTarget(&mobj->tracer, shield);
|
||||
P_SetTarget(&shield->target, mobj);
|
||||
}
|
||||
else
|
||||
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
|
||||
mobj->fuse = 4*TICRATE;
|
||||
mobj->flags |= MF_PAIN;
|
||||
if (mobj->info->attacksound)
|
||||
S_StartSound(mobj, mobj->info->attacksound);
|
||||
A_FaceTarget(mobj);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Return to idle.
|
||||
mobj->watertop = mobj->target->floorz + 32*FRACUNIT;
|
||||
P_SetMobjState(mobj, mobj->info->spawnstate);
|
||||
mobj->flags &= ~MF_PAIN;
|
||||
mobj->fuse = 10*TICRATE;
|
||||
break;
|
||||
case 2:
|
||||
// We're all charged and ready now! Unleash the fury!!
|
||||
if (mobj->health > mobj->info->damage)
|
||||
{
|
||||
mobj_t *removemobj = mobj->tracer;
|
||||
P_SetTarget(&mobj->tracer, mobj->hnext);
|
||||
P_RemoveMobj(removemobj);
|
||||
}
|
||||
if (mobj->health <= mobj->info->damage)
|
||||
{
|
||||
// Attack 1: Pinball dash!
|
||||
if (mobj->health == 1)
|
||||
mobj->movedir = 0;
|
||||
else
|
||||
mobj->movedir = 2;
|
||||
if (mobj->info->seesound)
|
||||
S_StartSound(mobj, mobj->info->seesound);
|
||||
P_SetMobjState(mobj, mobj->info->seestate);
|
||||
if (mobj->movedir == 2)
|
||||
mobj->threshold = 16; // bounce 16 times
|
||||
else
|
||||
mobj->threshold = 32; // bounce 32 times
|
||||
mobj->watertop = mobj->target->floorz + 16*FRACUNIT;
|
||||
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Attack 2: Energy shot!
|
||||
mobj->movedir = 1;
|
||||
|
||||
if (mobj->health >= 8)
|
||||
mobj->extravalue1 = 0;
|
||||
else if (mobj->health >= 5)
|
||||
mobj->extravalue1 = 2;
|
||||
else if (mobj->health >= 4)
|
||||
mobj->extravalue1 = 1;
|
||||
else
|
||||
mobj->extravalue1 = 3;
|
||||
|
||||
switch (mobj->extravalue1)
|
||||
{
|
||||
case 0: // shoot once
|
||||
case 2: // spread-shot
|
||||
default:
|
||||
mobj->threshold = 2;
|
||||
break;
|
||||
case 1: // shoot 3 times
|
||||
mobj->threshold = 3*2;
|
||||
break;
|
||||
case 3: // shoot like a goddamn machinegun
|
||||
mobj->threshold = 8*2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Return to idle.
|
||||
mobj->watertop = mobj->target->floorz + 32*FRACUNIT;
|
||||
P_SetMobjState(mobj, mobj->info->spawnstate);
|
||||
mobj->flags &= ~MF_PAIN;
|
||||
mobj->fuse = 10*TICRATE;
|
||||
break;
|
||||
}
|
||||
mobj->movecount++;
|
||||
mobj->movecount %= 4;
|
||||
@@ -5315,6 +5326,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||
// Face your target
|
||||
angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); // absolute angle
|
||||
angle = (angle-mobj->angle); // relative angle
|
||||
|
||||
if (angle < ANGLE_180)
|
||||
mobj->angle += angle/8;
|
||||
else
|
||||
@@ -5326,18 +5338,19 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||
|| mobj->target->player->powers[pw_invulnerability]
|
||||
|| mobj->target->player->powers[pw_super]))
|
||||
danger = false;
|
||||
if (mobj->target->x+mobj->target->radius+abs(mobj->target->momx*2) < mobj->x-mobj->radius)
|
||||
else if (mobj->target->x+mobj->target->radius+abs(mobj->target->momx*2) < mobj->x-mobj->radius)
|
||||
danger = false;
|
||||
if (mobj->target->x-mobj->target->radius-abs(mobj->target->momx*2) > mobj->x+mobj->radius)
|
||||
else if (mobj->target->x-mobj->target->radius-abs(mobj->target->momx*2) > mobj->x+mobj->radius)
|
||||
danger = false;
|
||||
if (mobj->target->y+mobj->target->radius+abs(mobj->target->momy*2) < mobj->y-mobj->radius)
|
||||
else if (mobj->target->y+mobj->target->radius+abs(mobj->target->momy*2) < mobj->y-mobj->radius)
|
||||
danger = false;
|
||||
if (mobj->target->y-mobj->target->radius-abs(mobj->target->momy*2) > mobj->y+mobj->radius)
|
||||
else if (mobj->target->y-mobj->target->radius-abs(mobj->target->momy*2) > mobj->y+mobj->radius)
|
||||
danger = false;
|
||||
if (mobj->target->z+mobj->target->height+mobj->target->momz*2 < mobj->z)
|
||||
else if (mobj->target->z+mobj->target->height+mobj->target->momz*2 < mobj->z)
|
||||
danger = false;
|
||||
if (mobj->target->z+mobj->target->momz*2 > mobj->z+mobj->height)
|
||||
else if (mobj->target->z+mobj->target->momz*2 > mobj->z+mobj->height)
|
||||
danger = false;
|
||||
|
||||
if (danger)
|
||||
{
|
||||
// An incoming attack is detected! What should we do?!
|
||||
@@ -5345,21 +5358,27 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||
mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS)));
|
||||
if (P_RandomChance(FRACUNIT/2))
|
||||
mobj->movedir = InvAngle(mobj->movedir);
|
||||
|
||||
mobj->threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))>>FRACBITS);
|
||||
|
||||
if (mobj->info->activesound)
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
if (mobj->info->painchance)
|
||||
P_SetMobjState(mobj, mobj->info->painchance);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Move normally: Approach the player using normal thrust and simulated friction.
|
||||
dist = P_AproxDistance(mobj->x-mobj->target->x, mobj->y-mobj->target->y);
|
||||
|
||||
P_Thrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), -3*FRACUNIT/8);
|
||||
|
||||
if (dist < 64*FRACUNIT)
|
||||
P_Thrust(mobj, mobj->angle, -4*FRACUNIT);
|
||||
else if (dist > 180*FRACUNIT)
|
||||
P_Thrust(mobj, mobj->angle, FRACUNIT);
|
||||
|
||||
mobj->momz += P_AproxDistance(mobj->momx, mobj->momy)/12; // Move up higher the faster you're going.
|
||||
}
|
||||
}
|
||||
@@ -5614,7 +5633,11 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale)
|
||||
player_t *player;
|
||||
fixed_t oldscale;
|
||||
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
#else
|
||||
if (!mobj)
|
||||
#endif
|
||||
return;
|
||||
|
||||
oldscale = mobj->scale; //keep for adjusting stuff below
|
||||
@@ -6853,11 +6876,9 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
|
||||
case MT_BANANA:
|
||||
if (cv_bananthrowroll.value)
|
||||
{
|
||||
//mobj->angle -= spin;
|
||||
if (cv_bananthrowroll.value == 1 && K_CheckSlopeRollDist(mobj))
|
||||
mobj->sloperoll += (angle_t)FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h); // im lazy but this makes sure the banan goes back to upright when it lands lmao
|
||||
else if (cv_bananthrowroll.value == 2)
|
||||
mobj->rollangle += (angle_t)FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h);
|
||||
const angle_t speen = (angle_t)FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h);
|
||||
//mobj->angle -= speen;
|
||||
mobj->rollangle += speen;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case MT_ORBINAUT:
|
||||
@@ -7047,7 +7068,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||
}
|
||||
|
||||
P_InstaThrust(mobj, mobj->angle, finalspeed);
|
||||
|
||||
|
||||
if (grounded)
|
||||
{
|
||||
sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj);
|
||||
@@ -7167,21 +7188,23 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||
}
|
||||
case MT_BANANA:
|
||||
case MT_EGGMANITEM:
|
||||
if (cv_bananthrowroll.value && !P_IsObjectOnGround(mobj))
|
||||
{
|
||||
boolean grounded = P_IsObjectOnGround(mobj);
|
||||
|
||||
if (cv_bananthrowroll.value && !grounded)
|
||||
{
|
||||
// tilt n tumble
|
||||
//mobj->angle += spin;
|
||||
|
||||
if (cv_bananthrowroll.value == 1 && K_CheckSlopeRollDist(mobj))
|
||||
mobj->sloperoll -= (angle_t)FixedMul(FixedDiv(mobj->momz, 8 * mobj->scale), ANGLE_67h); // im lazy but this makes sure the banan goes back to upright when it lands lmao
|
||||
else if (cv_bananthrowroll.value == 2)
|
||||
mobj->rollangle -= (angle_t)FixedMul(FixedDiv(mobj->momz, 8 * mobj->scale), ANGLE_67h);
|
||||
const angle_t speen = (angle_t)FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h);
|
||||
//mobj->angle += speen;
|
||||
mobj->rollangle -= speen;
|
||||
}
|
||||
|
||||
mobj->friction = ORIG_FRICTION/4;
|
||||
|
||||
if (mobj->momx || mobj->momy)
|
||||
P_SpawnGhostMobj(mobj);
|
||||
if (P_IsObjectOnGround(mobj) && mobj->health > 1)
|
||||
|
||||
if (grounded && mobj->health > 1)
|
||||
{
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
mobj->momx = mobj->momy = 0;
|
||||
@@ -7192,7 +7215,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||
|
||||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
|
||||
break;
|
||||
}
|
||||
case MT_SPB:
|
||||
indirectitemcooldown = 20*TICRATE;
|
||||
/* FALLTHRU */
|
||||
@@ -8663,14 +8688,15 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||
{
|
||||
const angle_t fa = (i*FINEANGLES/16) & FINEMASK;
|
||||
ns = FixedMul(64 * FRACUNIT, mobj->scale);
|
||||
x = mobj->x + FixedMul(FINESINE(fa),ns);
|
||||
y = mobj->y + FixedMul(FINECOSINE(fa),ns);
|
||||
x = mobj->x + FixedMul(FINESINE(fa), ns);
|
||||
y = mobj->y + FixedMul(FINECOSINE(fa), ns);
|
||||
|
||||
mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE);
|
||||
ns = FixedMul(16 * FRACUNIT, mobj->scale);
|
||||
mo2->momx = FixedMul(FINESINE(fa),ns);
|
||||
mo2->momy = FixedMul(FINECOSINE(fa),ns);
|
||||
mo2->momx = FixedMul(FINESINE(fa), ns);
|
||||
mo2->momy = FixedMul(FINECOSINE(fa), ns);
|
||||
}
|
||||
|
||||
z -= FixedMul(32*FRACUNIT, mobj->scale);
|
||||
}
|
||||
P_SetMobjState(mobj, mobj->info->deathstate);
|
||||
@@ -8864,9 +8890,9 @@ static void P_IceBlockFuseThink(mobj_t *mobj)
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
mobj_t *debris = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_DEBRIS);
|
||||
debris->angle = FixedAngle(P_RandomRange(0,360)<<FRACBITS);
|
||||
P_InstaThrust(debris, debris->angle, P_RandomRange(3,18)*(FRACUNIT/4));
|
||||
debris->momz = P_RandomRange(4,8)<<FRACBITS;
|
||||
debris->angle = FixedAngle(P_RandomRange(0, 360)<<FRACBITS);
|
||||
P_InstaThrust(debris, debris->angle, P_RandomRange(3, 18)*(FRACUNIT/4));
|
||||
debris->momz = P_RandomRange(4, 8)<<FRACBITS;
|
||||
if (!i) // kinda hacky :V
|
||||
S_StartSound(debris, sfx_s3k82);
|
||||
}
|
||||
@@ -8962,7 +8988,11 @@ static boolean P_FuseThink(mobj_t *mobj)
|
||||
static boolean P_MobjPushableThink(mobj_t *mobj)
|
||||
{
|
||||
// would be cool if we could use P_MobjWasRemoved Zzz...
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
#else
|
||||
if (!mobj)
|
||||
#endif
|
||||
return false;
|
||||
|
||||
P_MobjCheckWater(mobj);
|
||||
@@ -9167,6 +9197,14 @@ void P_MobjThinker(mobj_t *mobj)
|
||||
|| P_WeaponOrPanel(mobj->type))
|
||||
{
|
||||
P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly
|
||||
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (P_MobjWasRemoved(mobj)) // anything that calls checkposition can be lethal
|
||||
#else
|
||||
if (!mobj) // anything that calls checkposition can be lethal
|
||||
#endif
|
||||
return;
|
||||
|
||||
P_ButteredSlope(mobj);
|
||||
}
|
||||
|
||||
@@ -9192,6 +9230,13 @@ void P_MobjThinker(mobj_t *mobj)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
#else
|
||||
if (!mobj)
|
||||
#endif
|
||||
return; // obligatory paranoia check
|
||||
|
||||
// Can end up here if a player dies.
|
||||
P_CycleMobjState(mobj);
|
||||
|
||||
@@ -9249,7 +9294,11 @@ void P_PushableThinker(mobj_t *mobj)
|
||||
|
||||
I_Assert(!P_MobjWasRemoved(mobj));
|
||||
|
||||
#ifndef COMPAT_VANILLA
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
#else
|
||||
if (!mobj)
|
||||
#endif
|
||||
return;
|
||||
|
||||
sec = mobj->subsector->sector;
|
||||
|
||||
@@ -298,6 +298,7 @@ typedef struct mobj_s
|
||||
angle_t angle, pitch, roll; // orientation
|
||||
angle_t old_angle, old_pitch, old_roll; // orientation interpolation
|
||||
angle_t rollangle;
|
||||
angle_t temprollangle; // same as rollangle but resets each tic, idk either man. // cba exposing this to lua either
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
UINT16 anim_duration; // for FF_ANIMATE states
|
||||
|
||||
+11
-6
@@ -691,7 +691,7 @@ static void ArchiveLines(savebuffer_t *save)
|
||||
if (spawnli->special == 321 || spawnli->special == 322) // only reason li->callcount would be non-zero is if either of these are involved
|
||||
diff |= LD_CLLCOUNT;
|
||||
|
||||
if (li->sidenum[0] != 0xffff)
|
||||
if (li->sidenum[0] != NO_INDEX)
|
||||
{
|
||||
si = &sides[li->sidenum[0]];
|
||||
spawnsi = &spawnsides[li->sidenum[0]];
|
||||
@@ -706,7 +706,8 @@ static void ArchiveLines(savebuffer_t *save)
|
||||
if (si->midtexture != spawnsi->midtexture)
|
||||
diff |= LD_S1MIDTEX;
|
||||
}
|
||||
if (li->sidenum[1] != 0xffff)
|
||||
|
||||
if (li->sidenum[1] != NO_INDEX)
|
||||
{
|
||||
si = &sides[li->sidenum[1]];
|
||||
spawnsi = &spawnsides[li->sidenum[1]];
|
||||
@@ -786,6 +787,7 @@ static void UnArchiveFFloors(savebuffer_t *save, const sector_t *ss)
|
||||
I_Error("Sector does not have any ffloors!");
|
||||
|
||||
fflr_i = READUINT16(save->p); // get first modified ffloor's number ready
|
||||
|
||||
for (;;) // for some reason the usual for (rover = x; ...) thing doesn't work here?
|
||||
{
|
||||
if (fflr_i == 0xffff) // end of modified ffloors list, let's stop already
|
||||
@@ -3057,7 +3059,7 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save)
|
||||
break;
|
||||
|
||||
default:
|
||||
I_Error("P_UnarchiveSpecials: Unknown tclass %d in savegame", tclass);
|
||||
I_Error("P_NetUnArchiveThinkers: Unknown tclass %d in savegame", tclass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3168,7 +3170,7 @@ FUNCINLINE static ATTRINLINE void P_UnArchivePolyObjects(savebuffer_t *save)
|
||||
numSavedPolys = READINT32(save->p);
|
||||
|
||||
if (numSavedPolys != numPolyObjects)
|
||||
I_Error("P_UnArchivePolyObjects: polyobj count inconsistency\n");
|
||||
I_Error("P_UnArchivePolyObjects: polyobj count inconsistency (expected %d, got %d)\n", numPolyObjects, numSavedPolys);
|
||||
|
||||
for (i = 0; i < numSavedPolys; ++i)
|
||||
P_UnArchivePolyObj(save, &PolyObjects[i]);
|
||||
@@ -3510,7 +3512,7 @@ static void P_ReloadSaveLevelData(void)
|
||||
li->firsttag = spawnli->firsttag;
|
||||
li->nexttag = spawnli->nexttag;
|
||||
|
||||
if (li->sidenum[0] != 0xffff)
|
||||
if (li->sidenum[0] != NO_INDEX)
|
||||
{
|
||||
si = &sides[li->sidenum[0]];
|
||||
spawnsi = &spawnsides[li->sidenum[0]];
|
||||
@@ -3521,7 +3523,7 @@ static void P_ReloadSaveLevelData(void)
|
||||
si->midtexture = spawnsi->midtexture;
|
||||
}
|
||||
|
||||
if (li->sidenum[1] != 0xffff)
|
||||
if (li->sidenum[1] != NO_INDEX)
|
||||
{
|
||||
si = &sides[li->sidenum[1]];
|
||||
spawnsi = &spawnsides[li->sidenum[1]];
|
||||
@@ -3588,8 +3590,11 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
|
||||
if (!P_SetupLevel(true, reloading))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n"));
|
||||
P_FreeCorruptMapWarnings();
|
||||
return false;
|
||||
}
|
||||
|
||||
P_PrintCorruptMapWarnings();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+366
-127
@@ -188,6 +188,57 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
|
||||
I_Error("Invalid or corrupt map.\nLook in log file or text console for technical details.");
|
||||
}
|
||||
|
||||
static char **mapwarnings = NULL;
|
||||
static size_t nummapwarnings = 0;
|
||||
|
||||
// collect map errors we can fix clientside
|
||||
// we then can print em when the map finishes loading
|
||||
// so they actually appear and raise awareness shits fucked
|
||||
// see G_DoLoadLevel as to why :chaosleep:
|
||||
static void CorruptMapWarning(const char *msg)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
// just error out
|
||||
I_Error("%sThis WILL crash Vanilla clients!\n", msg);
|
||||
#endif
|
||||
nummapwarnings++;
|
||||
mapwarnings = Z_Realloc(mapwarnings, nummapwarnings * sizeof(*mapwarnings), PU_STATIC, NULL);
|
||||
mapwarnings[nummapwarnings-1] = Z_StrDup(msg);
|
||||
}
|
||||
|
||||
void P_PrintCorruptMapWarnings(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!nummapwarnings)
|
||||
return;
|
||||
|
||||
for (i = 0; i < nummapwarnings; i++)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "%sAttempting to fix... This WILL crash Vanilla clients!\n", mapwarnings[i]);
|
||||
}
|
||||
|
||||
P_FreeCorruptMapWarnings();
|
||||
}
|
||||
|
||||
void P_FreeCorruptMapWarnings(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!nummapwarnings)
|
||||
return;
|
||||
|
||||
for (i = 0; i < nummapwarnings; i++)
|
||||
{
|
||||
Z_Free(mapwarnings[i]);
|
||||
mapwarnings[i] = NULL;
|
||||
}
|
||||
|
||||
Z_Free(mapwarnings);
|
||||
mapwarnings = NULL;
|
||||
nummapwarnings = 0;
|
||||
}
|
||||
|
||||
#define NUMLAPS_DEFAULT 3
|
||||
|
||||
static void P_ClearMapHeaderLighting(mapheader_lighting_t *lighting)
|
||||
@@ -405,10 +456,10 @@ static void P_SetupDirectionalLight(void)
|
||||
|
||||
if (gamemap != oldmap || encoremode != oldencore || reinitmaplight)
|
||||
{
|
||||
lighting->light_contrast = M_RandomRange(0, 58);
|
||||
lighting->light_contrast = (UINT8)M_RandomRange(0, 58);
|
||||
lighting->sprite_backlight = 0;
|
||||
lighting->use_light_angle = M_RandomRange(0, 1); // either on or off
|
||||
lighting->light_angle = M_RandomRange(-382, 382);
|
||||
lighting->use_light_angle = (boolean)M_RandomRange(0, 1); // either on or off
|
||||
lighting->light_angle = (angle_t)M_RandomRange(-382, 382);
|
||||
|
||||
reinitmaplight = false;
|
||||
}
|
||||
@@ -437,8 +488,39 @@ static void P_LoadSegs(UINT8 *data)
|
||||
|
||||
for (i = 0; i < numsegs; i++, li++, ml++)
|
||||
{
|
||||
li->v1 = &vertexes[SHORT(ml->v1)];
|
||||
li->v2 = &vertexes[SHORT(ml->v2)];
|
||||
INT16 v1, v2;
|
||||
|
||||
v1 = SHORT(ml->v1);
|
||||
v2 = SHORT(ml->v2);
|
||||
|
||||
// e6y
|
||||
// check and fix wrong references to non-existent vertexes
|
||||
// see e1m9 @ NIVELES.WAD
|
||||
// http://www.doomworld.com/idgames/index.php?id=12647
|
||||
if ((unsigned)v1 >= numvertexes || (unsigned)v2 >= numvertexes)
|
||||
{
|
||||
if ((unsigned)v1 >= numvertexes)
|
||||
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v1));
|
||||
if ((unsigned)v2 >= numvertexes)
|
||||
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v2));
|
||||
|
||||
if (li->sidedef == &sides[li->linedef->sidenum[0]])
|
||||
{
|
||||
li->v1 = lines[ml->linedef].v1;
|
||||
li->v2 = lines[ml->linedef].v2;
|
||||
}
|
||||
else
|
||||
{
|
||||
li->v1 = lines[ml->linedef].v2;
|
||||
li->v2 = lines[ml->linedef].v1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
li->v1 = &vertexes[v1];
|
||||
li->v2 = &vertexes[v2];
|
||||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
@@ -455,14 +537,59 @@ static void P_LoadSegs(UINT8 *data)
|
||||
li->angle = (SHORT(ml->angle))<<FRACBITS;
|
||||
li->offset = (SHORT(ml->offset))<<FRACBITS;
|
||||
rawlinedef = SHORT(ml->linedef);
|
||||
|
||||
//e6y: check for wrong indexes
|
||||
if ((unsigned)rawlinedef >= numlines)
|
||||
{
|
||||
I_Error("P_LoadSegs: seg %s references a non-existent linedef %d", sizeu1(i), (unsigned)rawlinedef);
|
||||
}
|
||||
|
||||
ldef = &lines[rawlinedef];
|
||||
li->linedef = ldef;
|
||||
li->side = rawside = SHORT(ml->side);
|
||||
rawside = SHORT(ml->side);
|
||||
|
||||
//e6y: fix wrong side index
|
||||
if (rawside != 0 && rawside != 1)
|
||||
{
|
||||
CorruptMapWarning(va("P_LoadSegs: seg %s contains wrong side index %d.\n", sizeu1(i), rawside));
|
||||
rawside = 1;
|
||||
}
|
||||
|
||||
//e6y: check for wrong indexes
|
||||
if (ldef->sidenum[rawside] >= numsides)
|
||||
{
|
||||
I_Error("P_LoadSegs: linedef %d for seg %s references a non-existent sidedef %d", rawlinedef, sizeu1(i), ldef->sidenum[rawside]);
|
||||
}
|
||||
|
||||
li->side = rawside;
|
||||
|
||||
li->sidedef = &sides[ldef->sidenum[rawside]];
|
||||
li->frontsector = sides[ldef->sidenum[rawside]].sector;
|
||||
|
||||
/* cph 2006/09/30 - our frontsector can be the second side of the
|
||||
* linedef, so must check for NO_INDEX in case we are incorrectly
|
||||
* referencing the back of a 1S line */
|
||||
if (ldef->sidenum[rawside] == NO_INDEX)
|
||||
{
|
||||
CorruptMapWarning(va("P_LoadSegs: front of seg %s has no sidedef\n", sizeu1(i)));
|
||||
li->frontsector = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
li->frontsector = sides[ldef->sidenum[rawside]].sector;
|
||||
}
|
||||
|
||||
if (ldef->flags & ML_TWOSIDED)
|
||||
li->backsector = sides[ldef->sidenum[rawside^1]].sector;
|
||||
{
|
||||
if (ldef->sidenum[rawside^1] == NO_INDEX)
|
||||
{
|
||||
CorruptMapWarning(va("P_LoadSegs: back of seg %s has no sidedef while being marked as double sided\n", sizeu1(i)));
|
||||
li->backsector = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
li->backsector = sides[ldef->sidenum[rawside^1]].sector;
|
||||
}
|
||||
}
|
||||
|
||||
P_UpdateSegLightOffset(li);
|
||||
}
|
||||
@@ -738,7 +865,33 @@ static void P_LoadNodes(UINT8 *data)
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
no->children[j] = SHORT(mn->children[j]);
|
||||
UINT16 child;
|
||||
|
||||
child = SHORT(mn->children[j]);
|
||||
|
||||
if (child & NF_SUBSECTOR)
|
||||
{
|
||||
// Convert to extended type
|
||||
child &= ~NF_SUBSECTOR;
|
||||
|
||||
// haleyjd 11/06/10: check for invalid subsector reference
|
||||
if (child >= numsubsectors)
|
||||
{
|
||||
CorruptMapWarning(va("P_LoadNodes: BSP tree %s references invalid subsector %d\n", sizeu1(i), child));
|
||||
child = 0;
|
||||
}
|
||||
|
||||
child |= NF_SUBSECTOR;
|
||||
}
|
||||
else if (child >= numnodes)
|
||||
{
|
||||
CorruptMapWarning(va("P_LoadNodes: BSP node %s references invalid node.\n", sizeu1(i)));
|
||||
//I_Error("P_LoadNodes: BSP node %d references invalid node %d.\n", sizeu1(i), Index(((node_t *)no->children[j])));
|
||||
child = 0;
|
||||
}
|
||||
|
||||
no->children[j] = child;
|
||||
|
||||
for (k = 0; k < 4; k++)
|
||||
no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
|
||||
}
|
||||
@@ -1001,9 +1154,9 @@ static void P_InitializeLinedef(line_t *ld)
|
||||
// cph 2002/07/20 - these errors are fatal if not fixed, so apply them
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides)
|
||||
if (ld->sidenum[j] != NO_INDEX && ld->sidenum[j] >= (UINT16)numsides)
|
||||
{
|
||||
ld->sidenum[j] = 0xffff;
|
||||
ld->sidenum[j] = NO_INDEX;
|
||||
CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has out-of-range sidedef number\n", sizeu1((size_t)(ld - lines)));
|
||||
}
|
||||
}
|
||||
@@ -1011,23 +1164,24 @@ static void P_InitializeLinedef(line_t *ld)
|
||||
ld->firsttag = ld->nexttag = -1;
|
||||
|
||||
// killough 11/98: fix common wad errors (missing sidedefs):
|
||||
if (ld->sidenum[0] == 0xffff)
|
||||
if (ld->sidenum[0] == NO_INDEX)
|
||||
{
|
||||
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
|
||||
// cph - print a warning about the bug
|
||||
CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s missing first sidedef\n", sizeu1((size_t)(ld - lines)));
|
||||
}
|
||||
|
||||
if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED))
|
||||
if ((ld->sidenum[1] == NO_INDEX) && (ld->flags & ML_TWOSIDED))
|
||||
{
|
||||
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
|
||||
// cph - print a warning about the bug
|
||||
CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1((size_t)(ld - lines)));
|
||||
}
|
||||
|
||||
if (ld->sidenum[0] != 0xffff && ld->special)
|
||||
// killough 4/4/98: support special sidedef interpretation below
|
||||
if (ld->sidenum[0] != NO_INDEX && ld->special)
|
||||
sides[ld->sidenum[0]].special = ld->special;
|
||||
if (ld->sidenum[1] != 0xffff && ld->special)
|
||||
if (ld->sidenum[1] != NO_INDEX && ld->special)
|
||||
sides[ld->sidenum[1]].special = ld->special;
|
||||
}
|
||||
|
||||
@@ -1060,10 +1214,10 @@ static void P_LoadLineDefs2(void)
|
||||
for (; i--; ld++)
|
||||
{
|
||||
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
|
||||
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : NULL;
|
||||
ld->backsector = ld->sidenum[1] != NO_INDEX ? sides[ld->sidenum[1]].sector : NULL;
|
||||
|
||||
// Repeat count for midtexture
|
||||
if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff))
|
||||
if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != NO_INDEX))
|
||||
{
|
||||
sides[ld->sidenum[0]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) >> 12);
|
||||
sides[ld->sidenum[0]].textureoffset = (((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) & 2047) << FRACBITS;
|
||||
@@ -1079,13 +1233,13 @@ static void P_LoadLineDefs2(void)
|
||||
{
|
||||
size_t len = strlen(sides[ld->sidenum[0]].text)+1;
|
||||
|
||||
if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text)
|
||||
if (ld->sidenum[1] != NO_INDEX && sides[ld->sidenum[1]].text)
|
||||
len += strlen(sides[ld->sidenum[1]].text);
|
||||
|
||||
ld->text = Z_Malloc(len, PU_LEVEL, NULL);
|
||||
memcpy(ld->text, sides[ld->sidenum[0]].text, strlen(sides[ld->sidenum[0]].text)+1);
|
||||
|
||||
if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text)
|
||||
if (ld->sidenum[1] != NO_INDEX && sides[ld->sidenum[1]].text)
|
||||
memcpy(ld->text+strlen(ld->text)+1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text)+1);
|
||||
}
|
||||
break;
|
||||
@@ -1747,16 +1901,11 @@ static boolean P_LoadRawBlockMap(UINT8 *data, size_t count)
|
||||
// http://www.doomworld.com/idgames/index.php?id=12935
|
||||
if (!P_VerifyBlockMap(count))
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
I_Error("P_LoadBlockMap: erroneous BLOCKMAP lump may cause crashes.\n");
|
||||
#endif
|
||||
CONS_Alert(CONS_ERROR, "P_LoadBlockMap: erroneous BLOCKMAP lump may cause crashes.\n");
|
||||
|
||||
//Z_Free(blockmaplump);
|
||||
//blockmaplump = NULL;
|
||||
//return false; // ideally we would just let the game rebuild the blockmap
|
||||
// but this has a chance of desynching vanilla clients
|
||||
// not sure whats worse honestly and i do not want to decide that :chaosleep:
|
||||
CorruptMapWarning(va("P_LoadBlockMap: corrupted or invalid BLOCKMAP lump! Check the log for more information.\n"));
|
||||
// vanilla WILL crash here anyways so just rebuild it ourselves
|
||||
Z_Free(blockmaplump);
|
||||
blockmaplump = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// clear out mobj chains
|
||||
@@ -1793,22 +1942,35 @@ static void P_GroupLines(void)
|
||||
for (i = 0; i < numsubsectors; i++, ss++)
|
||||
{
|
||||
if (ss->firstline >= numsegs)
|
||||
{
|
||||
CorruptMapError(va("P_GroupLines: ss->firstline invalid "
|
||||
"(subsector %s, firstline refers to %d of %s)", sizeu1(i), ss->firstline,
|
||||
sizeu2(numsegs)));
|
||||
}
|
||||
|
||||
seg = &segs[ss->firstline];
|
||||
sidei = (size_t)(seg->sidedef - sides);
|
||||
|
||||
if (!seg->sidedef)
|
||||
{
|
||||
CorruptMapError(va("P_GroupLines: seg->sidedef is NULL "
|
||||
"(subsector %s, firstline is %d)", sizeu1(i), ss->firstline));
|
||||
}
|
||||
|
||||
if (seg->sidedef - sides < 0 || seg->sidedef - sides > (UINT16)numsides)
|
||||
{
|
||||
CorruptMapError(va("P_GroupLines: seg->sidedef refers to sidedef %s of %s "
|
||||
"(subsector %s, firstline is %d)", sizeu1(sidei), sizeu2(numsides),
|
||||
sizeu3(i), ss->firstline));
|
||||
}
|
||||
|
||||
if (!seg->sidedef->sector)
|
||||
{
|
||||
CorruptMapError(va("P_GroupLines: seg->sidedef->sector is NULL "
|
||||
"(subsector %s, firstline is %d, sidedef is %s)", sizeu1(i), ss->firstline,
|
||||
sizeu1(sidei)));
|
||||
}
|
||||
|
||||
ss->sector = seg->sidedef->sector;
|
||||
}
|
||||
|
||||
@@ -1886,11 +2048,16 @@ static void P_LoadReject(UINT8 *data, size_t rejectsize)
|
||||
{
|
||||
if (rejectsize < neededsize)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
I_Error("REJECT is %s byte%s too small. REJECT might be invalid and crash vanilla clients!\n", sizeu1(neededsize - rejectsize), (neededsize - rejectsize) == 1 ? "" : "s");
|
||||
#endif
|
||||
CONS_Alert(CONS_ERROR, "REJECT is %s byte%s too small. REJECT might be invalid and crash vanilla clients!\n", sizeu1(neededsize - rejectsize), (neededsize - rejectsize) == 1 ? "" : "s");
|
||||
CorruptMapWarning(va("P_LoadReject: REJECT is %s byte%s too small. REJECT might be invalid!\n", sizeu1(neededsize - rejectsize), (neededsize - rejectsize) == 1 ? "" : "s"));
|
||||
#ifdef COMPAT_VANILLA
|
||||
// we can pad this and somewhat prevent desyncs
|
||||
// probs not cool if the reject is from a completely different map
|
||||
// but whatever
|
||||
allocsize = neededsize;
|
||||
#else
|
||||
rejectmatrix = NULL;
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
rejectmatrix = Z_Calloc(allocsize, PU_LEVEL, NULL); // allocate memory for the reject matrix
|
||||
@@ -2329,7 +2496,9 @@ static void P_LoadRecordGhosts(void)
|
||||
if (!gpath)
|
||||
return;
|
||||
|
||||
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
|
||||
const char *mapname = G_BuildMapName(gamemap);
|
||||
|
||||
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, mapname);
|
||||
|
||||
// Best Time ghost
|
||||
if (cv_ghost_besttime.value)
|
||||
@@ -2379,9 +2548,10 @@ static void P_LoadRecordGhosts(void)
|
||||
{
|
||||
lumpnum_t l;
|
||||
UINT8 j = 1;
|
||||
while (j <= 99 && (l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(gamemap),j))) != LUMPERROR)
|
||||
|
||||
while (j <= 99 && (l = W_CheckNumForName(va("%sS%02u", mapname, j))) != LUMPERROR)
|
||||
{
|
||||
G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),j));
|
||||
G_AddGhost(va("%sS%02u", mapname, j));
|
||||
j++;
|
||||
}
|
||||
}
|
||||
@@ -2389,6 +2559,31 @@ static void P_LoadRecordGhosts(void)
|
||||
free(gpath);
|
||||
}
|
||||
|
||||
static void P_ResetSpawnpoints(void)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||
|
||||
// reset the player starts
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
playerstarts[i] = NULL;
|
||||
redctfstarts[i] = NULL;
|
||||
bluectfstarts[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_DM_STARTS; i++)
|
||||
{
|
||||
deathmatchstarts[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
skyboxmo[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void P_InitCamera(void)
|
||||
{
|
||||
INT32 i;
|
||||
@@ -2398,6 +2593,7 @@ static void P_InitCamera(void)
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
camera[i].postimg = 0;
|
||||
P_SetupCamera(&camera[i]);
|
||||
}
|
||||
|
||||
@@ -2423,10 +2619,12 @@ static void P_InitMinimapInfo(void)
|
||||
Patch_Free(minimapinfo.minimap_pic);
|
||||
minimapinfo.minimap_pic = NULL;
|
||||
|
||||
lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap)));
|
||||
const char *mapname = G_BuildMapName(gamemap);
|
||||
|
||||
lumpnum = W_CheckNumForName(va("%sR", mapname));
|
||||
|
||||
if (lumpnum != LUMPERROR)
|
||||
minimapinfo.minimap_pic = W_CachePatchName(va("%sR", G_BuildMapName(gamemap)), PU_PATCH);
|
||||
minimapinfo.minimap_pic = W_CachePatchName(va("%sR", mapname), PU_PATCH);
|
||||
|
||||
minimapinfo.min_x = bsp->bbox[0][BOXLEFT];
|
||||
minimapinfo.max_x = bsp->bbox[0][BOXRIGHT];
|
||||
@@ -2495,10 +2693,14 @@ static boolean P_RunSpecialWipe(boolean reloadinggamestate)
|
||||
{
|
||||
// Cancel all d_main.c fadeouts (keep fade in though).
|
||||
if (reloadinggamestate)
|
||||
{
|
||||
wipegamestate = gamestate; // Don't fade if reloading the gamestate
|
||||
return false;
|
||||
}
|
||||
|
||||
// Encore mode fade to pink to white
|
||||
// This is handled BEFORE sounds are stopped.
|
||||
else if (encoremode && !prevencoremode && !demo.rewinding)
|
||||
if (encoremode && !prevencoremode && !demo.rewinding)
|
||||
{
|
||||
tic_t locstarttime, endtime, nowtime;
|
||||
|
||||
@@ -2532,6 +2734,8 @@ static boolean P_RunSpecialWipe(boolean reloadinggamestate)
|
||||
// Hold on white for extra effect.
|
||||
while (nowtime < endtime)
|
||||
{
|
||||
I_HandleInterrupt();
|
||||
|
||||
// wait loop
|
||||
while (!((nowtime = I_GetTime()) - lastwipetic))
|
||||
{
|
||||
@@ -2554,6 +2758,69 @@ static boolean P_RunSpecialWipe(boolean reloadinggamestate)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void P_InitTagGametype(void)
|
||||
{
|
||||
UINT8 i;
|
||||
INT32 realnumplayers = 0;
|
||||
INT32 playersactive[MAXPLAYERS];
|
||||
|
||||
//I just realized how problematic this code can be.
|
||||
//D_NumPlayers() will not always cover the scope of the netgame.
|
||||
//What if one player is node 0 and the other node 31?
|
||||
//The solution? Make a temp array of all players that are currently playing and pick from them.
|
||||
//Future todo? When a player leaves, shift all nodes down so D_NumPlayers() can be used as intended?
|
||||
//Also, you'd never have to loop through all 32 players slots to find anything ever again.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator)
|
||||
{
|
||||
playersactive[realnumplayers] = i; //stores the player's node in the array.
|
||||
realnumplayers++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!realnumplayers) // this should also fix the dedicated crash bug. You only pick a player if one exists to be picked.
|
||||
{
|
||||
CONS_Printf(M_GetText("No player currently available to become IT. Awaiting available players.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
i = P_RandomKey(realnumplayers);
|
||||
players[playersactive[i]].pflags |= PF_TAGIT; //choose our initial tagger before map starts.
|
||||
|
||||
// Taken and modified from G_DoReborn()
|
||||
// Remove the player so he can respawn elsewhere.
|
||||
// first dissasociate the corpse
|
||||
if (players[playersactive[i]].mo)
|
||||
P_RemoveMobj(players[playersactive[i]].mo);
|
||||
|
||||
G_SpawnPlayer(playersactive[i], false); //respawn the lucky player in his dedicated spawn location.
|
||||
}
|
||||
|
||||
static void P_InitGametype(void)
|
||||
{
|
||||
if (modeattacking == ATTACKING_RECORD && !demo.playback)
|
||||
P_LoadRecordGhosts();
|
||||
|
||||
if (G_RaceGametype() && server)
|
||||
{
|
||||
INT32 numLaps;
|
||||
const mapheader_t *mapheader = mapheaderinfo[gamemap - 1];
|
||||
|
||||
if ((netgame || multiplayer) && cv_basenumlaps.value &&
|
||||
(!(mapheader->levelflags & LF_SECTIONRACE) || (mapheader->numlaps > cv_basenumlaps.value)))
|
||||
numLaps = cv_basenumlaps.value;
|
||||
else
|
||||
numLaps = mapheader->numlaps;
|
||||
|
||||
CV_StealthSetValue(&cv_numlaps, numLaps);
|
||||
}
|
||||
else if (G_TagGametype())
|
||||
{
|
||||
P_InitTagGametype();
|
||||
}
|
||||
}
|
||||
|
||||
static void P_SetupPlayer(void)
|
||||
{
|
||||
INT32 i;
|
||||
@@ -2567,76 +2834,27 @@ static void P_SetupPlayer(void)
|
||||
// Start players with pity shields if possible
|
||||
players[i].pity = -1;
|
||||
|
||||
players[i].mo = NULL;
|
||||
|
||||
if (!G_RaceGametype())
|
||||
{
|
||||
players[i].mo = NULL;
|
||||
G_DoReborn(i);
|
||||
}
|
||||
else // gametype is GT_COOP or GT_RACE
|
||||
{
|
||||
players[i].mo = NULL;
|
||||
G_SpawnPlayer(i, (players[i].starposttime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modeattacking == ATTACKING_RECORD && !demo.playback)
|
||||
P_LoadRecordGhosts();
|
||||
|
||||
if (G_TagGametype())
|
||||
{
|
||||
INT32 realnumplayers = 0;
|
||||
INT32 playersactive[MAXPLAYERS];
|
||||
|
||||
//I just realized how problematic this code can be.
|
||||
//D_NumPlayers() will not always cover the scope of the netgame.
|
||||
//What if one player is node 0 and the other node 31?
|
||||
//The solution? Make a temp array of all players that are currently playing and pick from them.
|
||||
//Future todo? When a player leaves, shift all nodes down so D_NumPlayers() can be used as intended?
|
||||
//Also, you'd never have to loop through all 32 players slots to find anything ever again.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator)
|
||||
{
|
||||
playersactive[realnumplayers] = i; //stores the player's node in the array.
|
||||
realnumplayers++;
|
||||
}
|
||||
}
|
||||
|
||||
if (realnumplayers) // this should also fix the dedicated crash bug. You only pick a player if one exists to be picked.
|
||||
{
|
||||
i = P_RandomKey(realnumplayers);
|
||||
players[playersactive[i]].pflags |= PF_TAGIT; //choose our initial tagger before map starts.
|
||||
|
||||
// Taken and modified from G_DoReborn()
|
||||
// Remove the player so he can respawn elsewhere.
|
||||
// first dissasociate the corpse
|
||||
if (players[playersactive[i]].mo)
|
||||
P_RemoveMobj(players[playersactive[i]].mo);
|
||||
|
||||
G_SpawnPlayer(playersactive[i], false); //respawn the lucky player in his dedicated spawn location.
|
||||
}
|
||||
else
|
||||
CONS_Printf(M_GetText("No player currently available to become IT. Awaiting available players.\n"));
|
||||
|
||||
}
|
||||
else if (G_RaceGametype() && server)
|
||||
{
|
||||
INT32 numLaps = ((netgame || multiplayer) && cv_basenumlaps.value
|
||||
&& (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
||||
|| (mapheaderinfo[gamemap - 1]->numlaps > cv_basenumlaps.value)))
|
||||
? cv_basenumlaps.value
|
||||
: mapheaderinfo[gamemap - 1]->numlaps;
|
||||
|
||||
CV_StealthSetValue(&cv_numlaps, numLaps);
|
||||
}
|
||||
P_InitGametype();
|
||||
|
||||
// Start recording replay in multiplayer with a temp filename
|
||||
// Ensure dedis only record a replay if there is a player at the start of the map, otherwise we get invalid replays!
|
||||
if (!demo.playback && multiplayer && D_NumPlayers())
|
||||
{
|
||||
static char buf[256];
|
||||
sprintf(buf, "replay"PATHSEP"online"PATHSEP"%d-%s", (int) (time(NULL)), G_BuildMapName(gamemap));
|
||||
sprintf(buf, "replay"PATHSEP"online"PATHSEP"%d-%s", (int)(time(NULL)), G_BuildMapName(gamemap));
|
||||
|
||||
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
|
||||
I_mkdir(va("%s"PATHSEP"replay"PATHSEP"online", srb2home), 0755);
|
||||
@@ -2738,9 +2956,10 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
// 99% of the things already did, so.
|
||||
// Map header should always be in place at this point
|
||||
INT32 i;
|
||||
UINT8 levelfadecol;
|
||||
boolean ranspecialwipe = false;
|
||||
lumpnum_t encoreLump = LUMPERROR;
|
||||
UINT8 levelfadecol;
|
||||
const mapheader_t *mapheader = mapheaderinfo[gamemap - 1];
|
||||
|
||||
|
||||
midgamejoin = fromnetsave; // makes dynslopes run in P_Ticker to avoid synch issues and other stuff
|
||||
@@ -2748,7 +2967,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
levelloading = true;
|
||||
|
||||
// This is needed. Don't touch.
|
||||
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
|
||||
maptol = mapheader->typeoflevel;
|
||||
|
||||
CON_Drawer(); // let the user know what we are going to do
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
@@ -2759,17 +2978,17 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
// Clear CECHO messages
|
||||
HU_ClearCEcho();
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->runsoc[0] != '#')
|
||||
P_RunSOC(mapheaderinfo[gamemap-1]->runsoc);
|
||||
if (mapheader->runsoc[0] != '#')
|
||||
P_RunSOC(mapheader->runsoc);
|
||||
|
||||
if (cv_runscripts.value && mapheaderinfo[gamemap-1]->scriptname[0] != '#')
|
||||
P_RunLevelScript(mapheaderinfo[gamemap-1]->scriptname);
|
||||
if (cv_runscripts.value && mapheader->scriptname[0] != '#')
|
||||
P_RunLevelScript(mapheader->scriptname);
|
||||
|
||||
P_LevelInitStuff(reloadinggamestate);
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'
|
||||
&& atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255)
|
||||
P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter);
|
||||
if (mapheader->forcecharacter[0] != '\0'
|
||||
&& atoi(mapheader->forcecharacter) != 255)
|
||||
P_ForceCharacter(mapheader->forcecharacter);
|
||||
|
||||
// Initial height of PointOfView
|
||||
// will be set by player think.
|
||||
@@ -2819,10 +3038,10 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
char tx[64];
|
||||
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
|
||||
snprintf(tx, 63, "%s%s%s",
|
||||
mapheaderinfo[gamemap-1]->lvlttl,
|
||||
(strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->zonttl) : // SRB2kart
|
||||
((mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " Zone"),
|
||||
(strlen(mapheaderinfo[gamemap-1]->actnum) > 0) ? va(", Act %s",mapheaderinfo[gamemap-1]->actnum) : "");
|
||||
mapheader->lvlttl,
|
||||
(strlen(mapheader->zonttl) > 0) ? va(" %s",mapheader->zonttl) : // SRB2kart
|
||||
((mapheader->levelflags & LF_NOZONE) ? "" : " Zone"),
|
||||
(strlen(mapheader->actnum) > 0) ? va(", Act %s",mapheader->actnum) : "");
|
||||
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
|
||||
I_UpdateNoVsync();
|
||||
}*/
|
||||
@@ -2841,20 +3060,16 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
curmapvirt = vres_GetMap(lastloadedmaplumpnum);
|
||||
|
||||
encoreLump = W_CheckNumForName(va("%s%c", maplumpname, (encoremode ? 'E' : 'T')));
|
||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette, encoreLump);
|
||||
R_ReInitColormaps(mapheader->palette, encoreLump);
|
||||
|
||||
CON_SetupBackColormap();
|
||||
|
||||
// SRB2 determines the sky texture to be used depending on the map header.
|
||||
P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true);
|
||||
P_SetupLevelSky(mapheader->skynum, true);
|
||||
|
||||
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||
P_ResetSpawnpoints();
|
||||
|
||||
// reset the player starts
|
||||
memset(playerstarts, 0, sizeof(playerstarts));
|
||||
memset(skyboxmo, 0, sizeof(skyboxmo));
|
||||
|
||||
P_MapStart();
|
||||
P_MapStart(); // tmthing can be used starting from this point
|
||||
|
||||
P_LoadMapFromFile();
|
||||
|
||||
@@ -2874,7 +3089,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
if (!playerstarts[numcoopstarts])
|
||||
break;
|
||||
|
||||
globalweather = mapheaderinfo[gamemap-1]->weather;
|
||||
globalweather = mapheader->weather;
|
||||
|
||||
// set up world state
|
||||
P_SpawnSpecials(fromnetsave, reloadinggamestate);
|
||||
@@ -2921,7 +3136,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
// clear special respawning que
|
||||
iquehead = iquetail = 0;
|
||||
|
||||
P_MapEnd();
|
||||
P_MapEnd(); // tmthing is no longer needed from this point onwards
|
||||
|
||||
// Remove the loading shit from the screen
|
||||
if (rendermode != render_none && !reloadinggamestate)
|
||||
@@ -2952,9 +3167,15 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
savedata.lives = 0;
|
||||
}
|
||||
|
||||
// assume the skybox is visible on level load.
|
||||
skyVisible = true;
|
||||
memset(skyVisiblePerPlayer, true, sizeof(skyVisiblePerPlayer));
|
||||
if (!reloadinggamestate)
|
||||
{
|
||||
// assume the skybox is visible on level load.
|
||||
skyVisible = true;
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
skyVisiblePerPlayer[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fromnetsave) // uglier hack
|
||||
{ // to make a newly loaded level start on the second frame.
|
||||
@@ -2974,14 +3195,18 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
LUA_HookInt(gamemap, HOOK(MapLoad));
|
||||
}
|
||||
|
||||
if (rendermode != render_none && !reloadinggamestate)
|
||||
// reloading gamestate, stop here.
|
||||
if (reloadinggamestate)
|
||||
return true;
|
||||
|
||||
G_AddMapToBuffer(gamemap-1);
|
||||
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
R_ResetViewInterpolation(0);
|
||||
R_UpdateMobjInterpolators();
|
||||
}
|
||||
|
||||
G_AddMapToBuffer(gamemap-1);
|
||||
|
||||
G_ResetDeviceLED();
|
||||
|
||||
return true;
|
||||
@@ -3162,6 +3387,17 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
|
||||
sreplaces = mreplaces = digmreplaces = 0;
|
||||
|
||||
if (local)
|
||||
{
|
||||
// check if someone tries to load maps locally lol
|
||||
// do this here so we can skip loading the file anyways
|
||||
if (W_CheckAutoLoadContainsMap(wadfilename))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "addilelocal: locally added file %s contains map data, this WILL cause crashes and desynchs! not added.\n", wadfilename);
|
||||
return UINT16_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
if ((numlumps = W_InitFile(wadfilename, local, false)) == INT16_MAX)
|
||||
{
|
||||
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||
@@ -3192,12 +3428,15 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
allvotereplaced = true;
|
||||
}
|
||||
|
||||
if (!devparm && sreplaces)
|
||||
CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces));
|
||||
if (!devparm && mreplaces)
|
||||
CONS_Printf(M_GetText("%s midi musics ignored\n"), sizeu1(mreplaces));
|
||||
if (!devparm && digmreplaces)
|
||||
CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces));
|
||||
if (!devparm)
|
||||
{
|
||||
if (sreplaces)
|
||||
CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces));
|
||||
if (mreplaces)
|
||||
CONS_Printf(M_GetText("%s midi musics ignored\n"), sizeu1(mreplaces));
|
||||
if (digmreplaces)
|
||||
CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces));
|
||||
}
|
||||
|
||||
if (!mapsadded)
|
||||
CONS_Printf(M_GetText("No maps added\n"));
|
||||
|
||||
@@ -114,6 +114,9 @@ size_t P_PrecacheLevelFlats(void);
|
||||
|
||||
void P_AllocMapHeader(INT16 i);
|
||||
|
||||
void P_PrintCorruptMapWarnings(void);
|
||||
void P_FreeCorruptMapWarnings(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@@ -901,6 +901,11 @@ void P_SlopeLaunch(mobj_t *mo)
|
||||
|
||||
//CONS_Printf("Launched off of slope.\n");
|
||||
mo->standingslope = NULL;
|
||||
|
||||
if (mo->player)
|
||||
{
|
||||
mo->player->stairjank = 0; // fuck you
|
||||
}
|
||||
}
|
||||
|
||||
// Function to help handle landing on slopes
|
||||
|
||||
+18
-13
@@ -538,6 +538,7 @@ static sector_t *getNextSector(line_t *line, sector_t *sec)
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return line->frontsector;
|
||||
}
|
||||
|
||||
@@ -568,6 +569,7 @@ fixed_t P_FindLowestFloorSurrounding(sector_t *sec)
|
||||
if (other->floorheight < floorh)
|
||||
floorh = other->floorheight;
|
||||
}
|
||||
|
||||
return floorh;
|
||||
}
|
||||
|
||||
@@ -889,7 +891,7 @@ static boolean PolyDoor(line_t *line)
|
||||
pdd.angle = line->angle; // angle of motion
|
||||
pdd.distance = sides[line->sidenum[0]].rowoffset;
|
||||
|
||||
if (line->sidenum[1] != 0xffff)
|
||||
if (line->sidenum[1] != NO_INDEX)
|
||||
pdd.delay = sides[line->sidenum[1]].textureoffset >> FRACBITS; // delay in tics
|
||||
else
|
||||
pdd.delay = 0;
|
||||
@@ -899,7 +901,7 @@ static boolean PolyDoor(line_t *line)
|
||||
pdd.speed = sides[line->sidenum[0]].textureoffset >> FRACBITS; // angular speed
|
||||
pdd.distance = sides[line->sidenum[0]].rowoffset >> FRACBITS; // angular distance
|
||||
|
||||
if (line->sidenum[1] != 0xffff)
|
||||
if (line->sidenum[1] != NO_INDEX)
|
||||
pdd.delay = sides[line->sidenum[1]].textureoffset >> FRACBITS; // delay in tics
|
||||
else
|
||||
pdd.delay = 0;
|
||||
@@ -1180,7 +1182,7 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max)
|
||||
for (i = 0; i < sector->linecount; i++)
|
||||
{
|
||||
line = sector->lines[i];
|
||||
check = getNextSector(line,sector);
|
||||
check = getNextSector(line, sector);
|
||||
|
||||
if (!check)
|
||||
continue;
|
||||
@@ -1989,8 +1991,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||
INT32 position = (INT32)max(sides[line->sidenum[0]].midtexture, 0);
|
||||
UINT32 prefadems = (UINT32)max(sides[line->sidenum[0]].textureoffset >> FRACBITS, 0);
|
||||
UINT32 postfadems = (UINT32)max(sides[line->sidenum[0]].rowoffset >> FRACBITS, 0);
|
||||
UINT8 fadetarget = (UINT8)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].textureoffset >> FRACBITS : 0, 0);
|
||||
INT16 fadesource = (INT16)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].rowoffset >> FRACBITS : -1, -1);
|
||||
UINT8 fadetarget = (UINT8)max((line->sidenum[1] != NO_INDEX) ? sides[line->sidenum[1]].textureoffset >> FRACBITS : 0, 0);
|
||||
INT16 fadesource = (INT16)max((line->sidenum[1] != NO_INDEX) ? sides[line->sidenum[1]].rowoffset >> FRACBITS : -1, -1);
|
||||
|
||||
// Seek offset from current song position
|
||||
if (line->flags & ML_EFFECT1)
|
||||
@@ -2098,7 +2100,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||
ffloor_t *rover;
|
||||
boolean foundit = false;
|
||||
|
||||
for(rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag != line->tag)
|
||||
continue;
|
||||
@@ -2504,7 +2506,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||
|
||||
var1 = sides[line->sidenum[0]].toptexture; //(line->dx>>FRACBITS)-1;
|
||||
|
||||
if (line->sidenum[1] != 0xffff && line->flags & ML_BLOCKMONSTERS) // read power from back sidedef
|
||||
if (line->sidenum[1] != NO_INDEX && line->flags & ML_BLOCKMONSTERS) // read power from back sidedef
|
||||
var2 = sides[line->sidenum[1]].toptexture;
|
||||
else if (line->flags & ML_NOCLIMB) // 'Infinite'
|
||||
var2 = UINT16_MAX;
|
||||
@@ -2633,7 +2635,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||
if (always || this->bottomtexture)
|
||||
this->bottomtexture = set->bottomtexture;
|
||||
|
||||
if (lines[linenum].sidenum[1] == 0xffff)
|
||||
if (lines[linenum].sidenum[1] == NO_INDEX)
|
||||
continue; // One-sided stops here.
|
||||
|
||||
// Back side
|
||||
@@ -2682,7 +2684,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||
sector_t *sec;
|
||||
mobj_t *thing;
|
||||
|
||||
if (line->sidenum[1] != 0xffff)
|
||||
if (line->sidenum[1] != NO_INDEX)
|
||||
state = (statenum_t)sides[line->sidenum[1]].toptexture;
|
||||
|
||||
while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
|
||||
@@ -2988,10 +2990,10 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, section) != number)
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, section) != number)
|
||||
continue;
|
||||
|
||||
topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector);
|
||||
@@ -4609,11 +4611,13 @@ void P_UpdateSpecials(void)
|
||||
// POINT LIMIT
|
||||
P_CheckPointLimit();
|
||||
|
||||
#ifdef COMPAT_VANILLA
|
||||
// Dynamic slopeness
|
||||
// we run this here only when not joined midrace
|
||||
// for vanilla compat reasons :chaosleep:
|
||||
if (!midgamejoin)
|
||||
P_RunDynamicSlopes();
|
||||
#endif
|
||||
|
||||
P_UpdateAnimFlats();
|
||||
}
|
||||
@@ -5484,6 +5488,7 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
|
||||
if ((lines[i].flags & (ML_NOSONIC|ML_NOTAILS)) != (ML_NOSONIC|ML_NOTAILS)) // If you can do something...
|
||||
{
|
||||
angle_t flatangle = InvAngle(lines[i].angle);
|
||||
|
||||
fixed_t xoffs;
|
||||
fixed_t yoffs;
|
||||
|
||||
@@ -6056,7 +6061,7 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
|
||||
break;
|
||||
|
||||
case 259: // Make-Your-Own FOF!
|
||||
if (lines[i].sidenum[1] != 0xffff)
|
||||
if (lines[i].sidenum[1] != NO_INDEX)
|
||||
{
|
||||
UINT8 *data;
|
||||
UINT16 b;
|
||||
@@ -6785,7 +6790,7 @@ static void P_SpawnScrollers(void)
|
||||
case 506:
|
||||
s = lines[i].sidenum[1];
|
||||
|
||||
if (s != 0xffff)
|
||||
if (s != NO_INDEX)
|
||||
Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, lines[i].sidenum[0], accel, 0);
|
||||
else
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line special 506 (line #%s) missing 2nd side!\n", sizeu1(i));
|
||||
|
||||
+9
-1
@@ -38,6 +38,8 @@
|
||||
#include "i_video.h" // rendermode
|
||||
#include "m_perfstats.h"
|
||||
|
||||
#include "lua_profile.h"
|
||||
|
||||
// Object place
|
||||
#include "m_cheat.h"
|
||||
|
||||
@@ -622,6 +624,8 @@ void P_Ticker(boolean run)
|
||||
}
|
||||
}
|
||||
|
||||
LUA_ResetTicTimers();
|
||||
|
||||
ps_lua_mobjhooks.value.i = 0;
|
||||
ps_checkposition_calls.value.i = 0;
|
||||
|
||||
@@ -629,6 +633,7 @@ void P_Ticker(boolean run)
|
||||
LUA_HookPreThinkFrame();
|
||||
PS_STOP_TIMING(ps_lua_prethinkframe_time);
|
||||
|
||||
// OK! Now that we got all of that sorted, players can think!
|
||||
PS_START_TIMING(ps_playerthink_time);
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
@@ -646,7 +651,9 @@ void P_Ticker(boolean run)
|
||||
if (run)
|
||||
{
|
||||
// Dynamic slopeness
|
||||
#ifdef COMPAT_VANILLA
|
||||
if (midgamejoin) // only run here if we joined midgame to fix some desynchs
|
||||
#endif
|
||||
P_RunDynamicSlopes();
|
||||
|
||||
PS_START_TIMING(ps_thinkertime);
|
||||
@@ -673,6 +680,7 @@ void P_Ticker(boolean run)
|
||||
PS_STOP_TIMING(ps_lua_thinkframe_time);
|
||||
}
|
||||
|
||||
// Run shield positioning
|
||||
P_RunOverlays();
|
||||
P_RunShadows();
|
||||
|
||||
@@ -794,7 +802,7 @@ void P_Ticker(boolean run)
|
||||
if (!player->mo)
|
||||
continue;
|
||||
|
||||
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
|
||||
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
|
||||
|
||||
if (skyVisiblePerPlayer[i] && skybox)
|
||||
{
|
||||
|
||||
+7
-1
@@ -1206,6 +1206,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
||||
ghost->pitch = mobj->pitch;
|
||||
ghost->roll = mobj->roll;
|
||||
ghost->rollangle = mobj->rollangle;
|
||||
ghost->temprollangle = mobj->temprollangle;
|
||||
ghost->sloperoll = mobj->sloperoll;
|
||||
ghost->slopepitch = mobj->slopepitch;
|
||||
|
||||
@@ -3739,7 +3740,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||
fixed_t f1, f2;
|
||||
|
||||
// We probably shouldn't move the camera if there is no player or player mobj somehow
|
||||
if (!player || !player->mo)
|
||||
if (!player || P_MobjWasRemoved(player->mo))
|
||||
return true;
|
||||
|
||||
// This can happen when joining
|
||||
@@ -5089,6 +5090,11 @@ void P_PlayerThink(player_t *player)
|
||||
player->squishdance.time = 0;
|
||||
}
|
||||
|
||||
if (player->stairjank > 0)
|
||||
{
|
||||
player->stairjank--;
|
||||
}
|
||||
|
||||
// Flash player after being hit.
|
||||
if (!(player->kartstuff[k_hyudorotimer] // SRB2kart - fixes Hyudoro not flashing when it should.
|
||||
|| player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either.
|
||||
|
||||
+1
-1
@@ -430,7 +430,7 @@ typedef struct line_s
|
||||
INT16 tag;
|
||||
|
||||
// Visual appearance: sidedefs.
|
||||
UINT16 sidenum[2]; // sidenum[1] will be 0xffff if one-sided
|
||||
UINT16 sidenum[2]; // sidenum[1] will be NO_INDEX if one-sided
|
||||
fixed_t alpha; // translucency
|
||||
UINT8 blendmode; // blendmode
|
||||
|
||||
|
||||
@@ -807,6 +807,7 @@ void R_ResetMobjInterpolationState(mobj_t *mobj)
|
||||
mobj->spriteyscale = mobj->realyscale;
|
||||
mobj->spritexoffset = mobj->realxoffset;
|
||||
mobj->spriteyoffset = mobj->realyoffset;
|
||||
mobj->temprollangle = 0;
|
||||
|
||||
mobj->resetinterp = false;
|
||||
}
|
||||
|
||||
+4
-1
@@ -188,6 +188,7 @@ consvar_t cv_flipcammode = {"flipcammode", "Displayplayer", CV_SAVE, flipcammod
|
||||
consvar_t cv_shadow = {"shadow", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_shadowoffs = {"offsetshadows", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_skydome = {"skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_ffloorclip = {"r_ffloorclip", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_spriteclip = {"r_spriteclip", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_softcyancut = {"softwarecyancut", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -1564,6 +1565,7 @@ void R_RegisterEngineStuff(void)
|
||||
CV_RegisterVar(&cv_shadow);
|
||||
CV_RegisterVar(&cv_shadowoffs);
|
||||
CV_RegisterVar(&cv_skybox);
|
||||
CV_RegisterVar(&cv_skydome);
|
||||
CV_RegisterVar(&cv_ffloorclip);
|
||||
CV_RegisterVar(&cv_spriteclip);
|
||||
CV_RegisterVar(&cv_secbright);
|
||||
@@ -1598,7 +1600,8 @@ void R_RegisterEngineStuff(void)
|
||||
CV_RegisterVar(&cv_sliptideroll);
|
||||
CV_RegisterVar(&cv_sloperolldist);
|
||||
CV_RegisterVar(&cv_sparkroll);
|
||||
CV_RegisterVar(&cv_spinoutroll);
|
||||
CV_RegisterVar(&cv_stairjank);
|
||||
CV_RegisterVar(&cv_stairjanksfx);
|
||||
|
||||
CV_RegisterVar(&cv_showhud);
|
||||
CV_RegisterVar(&cv_translucenthud);
|
||||
|
||||
@@ -213,6 +213,7 @@ extern consvar_t cv_translucency;
|
||||
extern consvar_t cv_drawdist, cv_drawdist_precip, cv_lessprecip;
|
||||
extern consvar_t cv_fov, cv_fovchange;
|
||||
extern consvar_t cv_skybox;
|
||||
extern consvar_t cv_skydome;
|
||||
extern consvar_t cv_tailspickup;
|
||||
extern consvar_t cv_maxinterpdist;
|
||||
extern consvar_t cv_playerfade;
|
||||
|
||||
+6
-3
@@ -785,6 +785,8 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*skycolfunc)(drawcolumndata_t*),
|
||||
drawcolumndata_t dc = {};
|
||||
const INT32 texture = texturetranslation[skytexture];
|
||||
|
||||
const boolean skydome = cv_skydome.value != 0;
|
||||
|
||||
// Reset column drawer function (note: couldn't we just call colfuncs[BASEDRAWFUNC] directly?)
|
||||
// (that is, unless we'll need to switch drawers in future for some reason)
|
||||
R_SetColumnFunc(BASEDRAWFUNC);
|
||||
@@ -830,8 +832,8 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*skycolfunc)(drawcolumndata_t*),
|
||||
|
||||
INT32 angle = (pl->viewangle + xtoviewangle[x + i])>>ANGLETOSKYSHIFT;
|
||||
angle -= (skytextureoffset >> FRACBITS);
|
||||
|
||||
dc.iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x + i]>>ANGLETOFINESHIFT));
|
||||
if (skydome)
|
||||
dc.iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x + i]>>ANGLETOFINESHIFT));
|
||||
dc.x = x + i;
|
||||
dc.source = R_GetColumn(texture, -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
|
||||
|
||||
@@ -866,7 +868,8 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*skycolfunc)(drawcolumndata_t*),
|
||||
INT32 angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
|
||||
angle -= (skytextureoffset >> FRACBITS);
|
||||
|
||||
dc.iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT));
|
||||
if (skydome)
|
||||
dc.iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT));
|
||||
dc.x = x;
|
||||
dc.source =
|
||||
R_GetColumn(texturetranslation[skytexture], -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
|
||||
|
||||
+19
-14
@@ -311,6 +311,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
|
||||
{
|
||||
rw_scalestep = drawseg->scalestep;
|
||||
spryscale = drawseg->scale1 + (x1 - drawseg->x1)*rw_scalestep;
|
||||
|
||||
if (dc->numlights)
|
||||
{ // reset all lights to their starting heights
|
||||
for (i = 0; i < dc->numlights; i++)
|
||||
@@ -435,6 +436,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
|
||||
windowtop = windowbottom + 1;
|
||||
set_colormap_below_light();
|
||||
}
|
||||
|
||||
windowbottom = realbot;
|
||||
if (windowtop < windowbottom)
|
||||
colfunc_2s(dc, col);
|
||||
@@ -2204,7 +2206,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
topremap = (encoremap && !(curline->linedef->flags & ML_TFERLINE));
|
||||
|
||||
if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM))
|
||||
&& linedef->sidenum[1] != 0xffff)
|
||||
&& linedef->sidenum[1] != NO_INDEX)
|
||||
{
|
||||
// Special case... use offsets from 2nd side but only if it has a texture.
|
||||
side_t *def = &sides[linedef->sidenum[1]];
|
||||
@@ -2615,8 +2617,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
|
||||
auto set_topstep_normal = [&]
|
||||
{
|
||||
topstep = -FixedMul (rw_scalestep, worldtop);
|
||||
topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
|
||||
topstep = -FixedMul(rw_scalestep, worldtop);
|
||||
topfrac = (centeryfrac>>4) - FixedMul(worldtop, rw_scale);
|
||||
};
|
||||
|
||||
// untextured seg
|
||||
@@ -2625,7 +2627,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
const bool tophigh = (worldhigh <= worldtop && worldhighslope <= worldtopslope);
|
||||
|
||||
// if we cant see the goddamn skyplane, well there wont be any skybox
|
||||
// we could kill skyVisible instead, but i want to keep the performance improvemnts it yields
|
||||
// we could kill skyVisible instead, but i want to keep the performance improvements it yields
|
||||
// so we do this absolute trash
|
||||
if ((tophigh
|
||||
&& (frontsector->floorpic != skyflatnum && frontsector->ceilingpic != skyflatnum)) // try to guess if its a "window"
|
||||
@@ -2637,14 +2639,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
// this is an attempt to fix issues with textureless single sided lines drawing nothing where they should just draw sky instead
|
||||
if (tophigh && !backsector && frontsector->ceilingpic == skyflatnum)
|
||||
{
|
||||
topstep = -FixedMul (rw_scalestep, worldbottom);
|
||||
topfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
|
||||
|
||||
// account for slopes to try and get rid of sharp edges from the black void
|
||||
if (frontsector->f_slope || (backsector && backsector->f_slope))
|
||||
{
|
||||
topstep = -FixedMul (rw_scalestep, worldbottomslope);
|
||||
topfrac = (centeryfrac>>4) - FixedMul (worldbottomslope, rw_scale);
|
||||
topstep = -FixedMul(rw_scalestep, worldbottomslope);
|
||||
topfrac = (centeryfrac>>4) - FixedMul(worldbottomslope, rw_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
topstep = -FixedMul(rw_scalestep, worldbottom);
|
||||
topfrac = (centeryfrac>>4) - FixedMul(worldbottom, rw_scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2653,18 +2657,18 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
else
|
||||
set_topstep_normal();
|
||||
|
||||
bottomstep = -FixedMul (rw_scalestep, worldbottom);
|
||||
bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
|
||||
bottomstep = -FixedMul(rw_scalestep, worldbottom);
|
||||
bottomfrac = (centeryfrac>>4) - FixedMul(worldbottom, rw_scale);
|
||||
|
||||
if (frontsector->c_slope)
|
||||
{
|
||||
fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2);
|
||||
fixed_t topfracend = (centeryfrac>>4) - FixedMul(worldtopslope, ds_p->scale2);
|
||||
topstep = (topfracend-topfrac)/(range);
|
||||
}
|
||||
|
||||
if (frontsector->f_slope)
|
||||
{
|
||||
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2);
|
||||
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul(worldbottomslope, ds_p->scale2);
|
||||
bottomstep = (bottomfracend-bottomfrac)/(range);
|
||||
}
|
||||
}
|
||||
@@ -2782,7 +2786,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
|
||||
if (bottomtexture)
|
||||
{
|
||||
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2);
|
||||
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul(worldlowslope, ds_p->scale2);
|
||||
|
||||
pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
|
||||
pixlowstep = (bottomfracend-pixlow)/(range);
|
||||
@@ -3045,6 +3049,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
ds_p->silhouette |= SIL_BOTTOM;
|
||||
ds_p->bsilheight = backsector->f_slope ? INT32_MAX : backsector->floorheight;
|
||||
}
|
||||
|
||||
if (!(ds_p->silhouette & SIL_TOP))
|
||||
{
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, f
|
||||
// set the splat
|
||||
splat->patch = W_GetNumForName(patchname);
|
||||
sectorside ^= 1;
|
||||
if (wallline->sidenum[sectorside] != 0xffff)
|
||||
if (wallline->sidenum[sectorside] != NO_INDEX)
|
||||
{
|
||||
backsector = sides[wallline->sidenum[sectorside]].sector;
|
||||
|
||||
|
||||
+6
-4
@@ -1276,7 +1276,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
#ifdef ROTSPRITE
|
||||
// determine here if sprite should rotate for optimization
|
||||
const boolean sliprollrotate = (cv_sliptideroll.value && (thing->player && thing->player->sliproll));
|
||||
const boolean shouldrotate = (interp.sloperoll || interp.slopepitch || interp.roll || interp.pitch || thing->rollangle || sliprollrotate);
|
||||
const boolean shouldrotate = (interp.sloperoll || interp.slopepitch || interp.roll || interp.pitch || thing->rollangle || thing->temprollangle || sliprollrotate);
|
||||
#endif
|
||||
|
||||
sprskin = K_GetMobjSkin(thing);
|
||||
@@ -1376,16 +1376,18 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
#ifdef ROTSPRITE
|
||||
if (shouldrotate)
|
||||
{
|
||||
const fixed_t thingrollangle = (thing->rollangle - thing->temprollangle);
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
if (ang >= ANGLE_180)
|
||||
{
|
||||
// Makes Software act much more sane like OpenGL
|
||||
rollangle = InvAngle(thing->rollangle);
|
||||
rollangle = InvAngle(thingrollangle);
|
||||
}
|
||||
else
|
||||
{
|
||||
rollangle = thing->rollangle;
|
||||
rollangle = thingrollangle;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1393,7 +1395,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
// this is very messy, but it on-the-fly calculates rotations for all the
|
||||
// pitch and roll variables
|
||||
pitchnroll = R_RotationAngle(ang, camang, &interp);
|
||||
rollangle = thing->rollangle;
|
||||
rollangle = thingrollangle;
|
||||
}
|
||||
|
||||
if (rollangle || pitchnroll || sliprollrotate)
|
||||
|
||||
@@ -937,6 +937,7 @@ static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source,
|
||||
listener_t listensource;
|
||||
INT32 i;
|
||||
|
||||
// e6y
|
||||
if (!listener)
|
||||
return false;
|
||||
|
||||
@@ -2038,6 +2039,10 @@ static boolean S_SkipIntroMusic(void)
|
||||
if (!cv_skipintromusic.value)
|
||||
return false;
|
||||
|
||||
// dont skip if we disabled music, weird? but this would skip sounds that play on map start as well otherwise
|
||||
if (music_disabled)
|
||||
return false;
|
||||
|
||||
// check if menu music is playing, otherwise it may continue playing
|
||||
if (fasticmp(music.name, "titles"))
|
||||
return false;
|
||||
@@ -2049,6 +2054,11 @@ static boolean S_SkipIntroMusic(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
// without sound there wont be any intro playing
|
||||
if (sound_disabled)
|
||||
return true;
|
||||
// yes i sometimes play with only music but no sound
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+13
-1
@@ -2718,6 +2718,7 @@ void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *st
|
||||
INT32 charflags = 0;
|
||||
const UINT8 *colormap = NULL;
|
||||
INT32 spacewidth = 2, charwidth = 0;
|
||||
|
||||
INT32 lowercase = (option & V_ALLOWLOWERCASE);
|
||||
option &= ~V_FLIP; // which is also shared with V_ALLOWLOWERCASE...
|
||||
|
||||
@@ -2738,6 +2739,7 @@ void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *st
|
||||
scrwidth *= vid.dup;
|
||||
|
||||
charflags = (option & V_CHARCOLORMASK);
|
||||
colormap = V_GetStringColormap(charflags);
|
||||
|
||||
switch (option & V_SPACINGMASK)
|
||||
{
|
||||
@@ -2762,7 +2764,11 @@ void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *st
|
||||
{
|
||||
// manually set flags override color codes
|
||||
if (!(option & V_CHARCOLORMASK))
|
||||
{
|
||||
charflags = ((*ch & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK;
|
||||
colormap = V_GetStringColormap(charflags);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2806,7 +2812,6 @@ void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *st
|
||||
continue;
|
||||
}
|
||||
|
||||
colormap = V_GetStringColormap(charflags);
|
||||
V_DrawFixedPatch(cx + (center<<FRACBITS), cy, FRACUNIT/2, option, hu_font[c], colormap);
|
||||
cx += w<<FRACBITS;
|
||||
}
|
||||
@@ -2818,6 +2823,13 @@ void V_DrawCenteredSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const
|
||||
V_DrawSmallStringAtFixed(x, y, option, string);
|
||||
}
|
||||
|
||||
void V_DrawRightAlignedSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
||||
{
|
||||
x -= V_SmallStringWidth(string, option)<<FRACBITS;
|
||||
V_DrawSmallStringAtFixed(x, y, option, string);
|
||||
}
|
||||
|
||||
// Draws a thin string at a fixed_t location.
|
||||
void V_DrawThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
||||
{
|
||||
fixed_t cx = x, cy = y;
|
||||
|
||||
@@ -252,6 +252,7 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
||||
|
||||
void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
void V_DrawCenteredSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
|
||||
void V_DrawThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
|
||||
|
||||
+86
-29
@@ -123,6 +123,9 @@ static const char pat_end[] = {0x50, 0x4b, 0x05, 0x06, 0x00};
|
||||
UINT16 numwadfiles = 0; // number of active wadfiles
|
||||
wadfile_t *wadfiles[MAX_WADFILES] = {}; // 0 to numwadfiles-1 are valid
|
||||
|
||||
// use strnlen as some lump names may not be null terminated
|
||||
#define CHECKMAPMARKER(name) (memcmp(name, "MAP", 3) == 0 && strnlen(name, 8) == 5)
|
||||
|
||||
// W_Shutdown
|
||||
// Closes all of the WAD files before quitting
|
||||
// If not done on a Mac then open wad files
|
||||
@@ -2392,7 +2395,7 @@ static int W_NameStartsWith(const char *name, lumpchecklist_t *checklist)
|
||||
}
|
||||
|
||||
// Checks if file contains at least one lump which name starts with one of strings in checklist
|
||||
static int W_CheckWADContains(FILE *fp, lumpchecklist_t *checklist)
|
||||
static int W_CheckWADContainsEx(FILE *fp, lumpchecklist_t *checklist, boolean checkmap)
|
||||
{
|
||||
size_t i, j;
|
||||
// if we're here it's a WAD file
|
||||
@@ -2433,13 +2436,29 @@ static int W_CheckWADContains(FILE *fp, lumpchecklist_t *checklist)
|
||||
if (!strncmp(lumpinfo.name, sprnames[j], 4)) // Sprites
|
||||
continue;
|
||||
|
||||
if (W_NameStartsWith(lumpinfo.name, checklist))
|
||||
if (checkmap)
|
||||
{
|
||||
if (CHECKMAPMARKER(lumpinfo.name))
|
||||
return true;
|
||||
}
|
||||
else if (W_NameStartsWith(lumpinfo.name, checklist))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist)
|
||||
static int W_CheckWADContains(FILE *fp, lumpchecklist_t *checklist)
|
||||
{
|
||||
return W_CheckWADContainsEx(fp, checklist, false);
|
||||
}
|
||||
|
||||
static int W_CheckWADContainsMap(FILE *fp)
|
||||
{
|
||||
return W_CheckWADContainsEx(fp, NULL, true);
|
||||
}
|
||||
|
||||
static int W_CheckPK3ContainsEx(FILE *fp, lumpchecklist_t *checklist, boolean checkmap)
|
||||
{
|
||||
zend_t zend;
|
||||
zlentry_t zlentry;
|
||||
@@ -2513,13 +2532,23 @@ static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist)
|
||||
memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
|
||||
strncpy(lumpname, trimname, min(8, dotpos - trimname));
|
||||
|
||||
if (W_NameStartsWith(lumpname, checklist))
|
||||
if (checkmap)
|
||||
{
|
||||
if (CHECKMAPMARKER(lumpname))
|
||||
return true;
|
||||
}
|
||||
else if (W_NameStartsWith(lumpname, checklist))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (W_NameStartsWith(fullname, checklist))
|
||||
if (checkmap)
|
||||
{
|
||||
if (CHECKMAPMARKER(fullname))
|
||||
return true;
|
||||
}
|
||||
else if (W_NameStartsWith(fullname, checklist))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -2561,12 +2590,24 @@ static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist)
|
||||
}
|
||||
}
|
||||
|
||||
static int W_CheckFileContains(const char *filename, lumpchecklist_t *checklist)
|
||||
static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist)
|
||||
{
|
||||
return W_CheckPK3ContainsEx(fp, checklist, false);
|
||||
}
|
||||
|
||||
static int W_CheckPK3ContainsMap(FILE *fp)
|
||||
{
|
||||
return W_CheckPK3ContainsEx(fp, NULL, true);
|
||||
}
|
||||
|
||||
static int W_CheckFileContainsEx(const char *filename, lumpchecklist_t *checklist, boolean checkmap)
|
||||
{
|
||||
FILE *handle;
|
||||
int contains = false;
|
||||
|
||||
if (!checklist)
|
||||
// if we just check for maps this will be NULL
|
||||
// hacky but i dont care
|
||||
if (!checklist && !checkmap)
|
||||
I_Error("No checklist for %s\n", filename);
|
||||
|
||||
// open wad file
|
||||
@@ -2577,27 +2618,41 @@ static int W_CheckFileContains(const char *filename, lumpchecklist_t *checklist)
|
||||
|
||||
if (type == RET_PK3)
|
||||
{
|
||||
contains = W_CheckPK3Contains(handle, checklist);
|
||||
if (checkmap)
|
||||
contains = W_CheckPK3ContainsMap(handle);
|
||||
else
|
||||
contains = W_CheckPK3Contains(handle, checklist);
|
||||
}
|
||||
else if (type == RET_WAD)
|
||||
{
|
||||
contains = W_CheckWADContains(handle, checklist);
|
||||
if (checkmap)
|
||||
contains = W_CheckWADContainsMap(handle);
|
||||
else
|
||||
contains = W_CheckWADContains(handle, checklist);
|
||||
}
|
||||
|
||||
fclose(handle);
|
||||
return contains;
|
||||
}
|
||||
|
||||
static int W_CheckFileContains(const char *filename, lumpchecklist_t *checklist)
|
||||
{
|
||||
return W_CheckFileContainsEx(filename, checklist, false);
|
||||
}
|
||||
|
||||
static int W_CheckFileContainsMap(const char *filename)
|
||||
{
|
||||
return W_CheckFileContainsEx(filename, NULL, true);
|
||||
}
|
||||
|
||||
// kinda stupid but we cant just check for any lump containing "MAP"
|
||||
// we have to explicitly check if its MAP and 5 characters long
|
||||
// the more correct way would be checking inside wad files nested within pk3´s
|
||||
// and check the presence of actual map data like SSECTORS or something
|
||||
// but man i cannot be assed to rework shit for that
|
||||
int W_CheckAutoLoadContainsMap(const char *filename)
|
||||
{
|
||||
// for now this checks for map marker
|
||||
static lumpchecklist_t autoloadblacklist[] =
|
||||
{
|
||||
{"MAP", 3},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
return W_CheckFileContains(filename, autoloadblacklist);
|
||||
return W_CheckFileContainsMap(filename);
|
||||
}
|
||||
|
||||
int W_CheckPostLoadList(const char *filename)
|
||||
@@ -2676,8 +2731,9 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
||||
vlumps[i].size = vsizecache[realentry];
|
||||
|
||||
const char *name = (fileinfo + realentry)->name;
|
||||
I_Assert(name != NULL);
|
||||
|
||||
if (strnlen(name, 8) == 5 && memcmp(name, "MAP", 3) == 0)
|
||||
if (CHECKMAPMARKER(name))
|
||||
{
|
||||
numlumps--; // We skip map marker, so 1 of entries becomes empty
|
||||
continue; // This will skip i++ so we will write to same entry
|
||||
@@ -2686,9 +2742,7 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
||||
// Play it safe with the name in this case.
|
||||
memcpy(vlumps[i].name, name, 8);
|
||||
vlumps[i].name[8] = '\0';
|
||||
vlumps[i].data = (UINT8 *)(
|
||||
Z_Malloc(vlumps[i].size, PU_LEVEL, NULL) // This is memory inefficient, sorry about that.
|
||||
);
|
||||
vlumps[i].data = (UINT8 *)(Z_Malloc(vlumps[i].size, PU_LEVEL, NULL)); // This is memory inefficient, sorry about that.
|
||||
memcpy(vlumps[i].data, wadData + LONG((fileinfo + realentry)->filepos), vlumps[i].size);
|
||||
i++;
|
||||
}
|
||||
@@ -2698,15 +2752,19 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Count number of lumps until the end of resource OR up until next "MAPXX" lump.
|
||||
// Count number of lumps until the end of resource OR up until next 0-length lump OR up until next "MAPXX" lump.
|
||||
lumpnum_t lumppos = lumpnum + 1;
|
||||
for (i = LUMPNUM(lumppos); i < wadfiles[WADFILENUM(lumpnum)]->numlumps; i++, lumppos++, numlumps++)
|
||||
{
|
||||
const char *name = W_CheckNameForNum(lumppos);
|
||||
if (name == NULL)
|
||||
continue;
|
||||
if (W_LumpLength(lumppos) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (memcmp(name, "MAP", 3) == 0 || W_LumpLength(lumppos) == 0)
|
||||
const char *name = W_CheckNameForNum(lumppos);
|
||||
I_Assert(name != NULL);
|
||||
|
||||
if (CHECKMAPMARKER(name))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -2721,10 +2779,9 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
||||
{
|
||||
// Check if it is map marker. It is not always first lump sadly, so we need to expect it anywhere
|
||||
const char *name = W_CheckNameForNum(lumpnum);
|
||||
if (name == NULL)
|
||||
continue;
|
||||
I_Assert(name != NULL);
|
||||
|
||||
if (strlen(name) == 5 && memcmp(name, "MAP", 3) == 0)
|
||||
if (CHECKMAPMARKER(name))
|
||||
{
|
||||
--i; // Decrement so on next iteration we write on same i, so we don't leave corrupted vlumps entry
|
||||
numlumps--; // Just so we don't try to access the leftover vlumps entry
|
||||
|
||||
Reference in new issue
Block a user