Merge remote-tracking branch 'origin/next' into hooklib-refactor

This commit is contained in:
James R 2020-12-12 02:02:38 -08:00
commit 2778cc3ce9
31 changed files with 432 additions and 173 deletions

View file

@ -686,6 +686,15 @@ static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
}
static void codeunaryarith (FuncState *fs, OpCode op, expdesc *e) {
expdesc e2;
e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
if (op == OP_LEN || !isnumeral(e))
luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
codearith(fs, op, e, &e2);
}
static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
expdesc *e2) {
int o1 = luaK_exp2RK(fs, e1);
@ -703,27 +712,11 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
expdesc e2;
e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
switch (op) {
case OPR_MINUS: {
if (!isnumeral(e))
luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
codearith(fs, OP_UNM, e, &e2);
break;
}
case OPR_BNOT: {
if (e->k == VK)
luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
codearith(fs, OP_BNOT, e, &e2);
break;
}
case OPR_MINUS: codeunaryarith(fs, OP_UNM, e); break;
case OPR_BNOT: codeunaryarith(fs, OP_BNOT, e); break;
case OPR_NOT: codenot(fs, e); break;
case OPR_LEN: {
luaK_exp2anyreg(fs, e); /* cannot operate on constants */
codearith(fs, OP_LEN, e, &e2);
break;
}
case OPR_LEN: codeunaryarith(fs, OP_LEN, e); break;
default: lua_assert(0);
}
}

View file

@ -2258,11 +2258,15 @@ void D_SaveBan(void)
size_t i;
banreason_t *reasonlist = reasonhead;
const char *address, *mask;
const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt");
if (!reasonhead)
{
remove(path);
return;
}
f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "w");
f = fopen(path, "w");
if (!f)
{
@ -2306,16 +2310,14 @@ static void Ban_Add(const char *reason)
reasontail = reasonlist;
}
static void Command_ClearBans(void)
static void Ban_Clear(void)
{
banreason_t *temp;
if (!I_ClearBans)
return;
I_ClearBans();
D_SaveBan();
reasontail = NULL;
while (reasonhead)
{
temp = reasonhead->next;
@ -2325,6 +2327,15 @@ static void Command_ClearBans(void)
}
}
static void Command_ClearBans(void)
{
if (!I_ClearBans)
return;
Ban_Clear();
D_SaveBan();
}
static void Ban_Load_File(boolean warning)
{
FILE *f;
@ -2332,6 +2343,9 @@ static void Ban_Load_File(boolean warning)
const char *address, *mask;
char buffer[MAX_WADPATH];
if (!I_ClearBans)
return;
f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r");
if (!f)
@ -2341,13 +2355,7 @@ static void Ban_Load_File(boolean warning)
return;
}
if (I_ClearBans)
Command_ClearBans();
else
{
fclose(f);
return;
}
Ban_Clear();
for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++)
{
@ -3024,8 +3032,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
if (pnum == consoleplayer)
{
if (Playing())
LUA_Hook(GameQuit);
LUAh_GameQuit(false);
#ifdef DUMPCONSISTENCY
if (msg == KICK_MSG_CON_FAIL) SV_SavedGame();
#endif
@ -3725,8 +3732,7 @@ static void HandleConnect(SINT8 node)
static void HandleShutdown(SINT8 node)
{
(void)node;
if (Playing())
LUA_Hook(GameQuit);
LUAh_GameQuit(false);
D_QuitNetGame();
CL_Reset();
D_StartTitle();
@ -3741,8 +3747,7 @@ static void HandleShutdown(SINT8 node)
static void HandleTimeout(SINT8 node)
{
(void)node;
if (Playing())
LUA_Hook(GameQuit);
LUAh_GameQuit(false);
D_QuitNetGame();
CL_Reset();
D_StartTitle();

View file

@ -998,7 +998,7 @@ static void IdentifyVersion(void)
#define MUSICTEST(str) \
{\
const char *musicpath = va(pandf,srb2waddir,str);\
int ms = W_VerifyNMUSlumps(musicpath); \
int ms = W_VerifyNMUSlumps(musicpath, false); \
if (ms == 1) \
D_AddFile(startupwadfiles, musicpath); \
else if (ms == 0) \
@ -1187,11 +1187,7 @@ void D_SRB2Main(void)
const char *s = M_GetNextParm();
if (s) // Check for NULL?
{
if (!W_VerifyNMUSlumps(s))
G_SetGameModified(true);
D_AddFile(startuppwads, s);
}
}
}
}

View file

@ -3294,7 +3294,13 @@ static void Command_Addfile(void)
if (!isprint(fn[i]) || fn[i] == ';')
return;
musiconly = W_VerifyNMUSlumps(fn);
musiconly = W_VerifyNMUSlumps(fn, false);
if (musiconly == -1)
{
addedfiles[numfilesadded++] = fn;
continue;
}
if (!musiconly)
{
@ -3606,8 +3612,7 @@ static void Command_Playintro_f(void)
*/
FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void)
{
if (Playing())
LUA_Hook(GameQuit);
LUAh_GameQuit(true);
I_Quit();
}
@ -4269,8 +4274,7 @@ void Command_ExitGame_f(void)
{
INT32 i;
if (Playing())
LUA_Hook(GameQuit);
LUAh_GameQuit(false);
D_QuitNetGame();
CL_Reset();

View file

@ -51,7 +51,7 @@ typedef enum
SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER)
SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super
SF_NOSUPERJUMPBOOST = 1<<17, // Disable the jump boost given while super (i.e. Knuckles)
SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles)
SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles)
// free up to and including 1<<31
} skinflags_t;

View file

@ -4331,6 +4331,7 @@ const char *const MOBJFLAG2_LIST[] = {
"AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH
"LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
"SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use)
"SPLAT", // Object is a splat
NULL
};
@ -4794,6 +4795,7 @@ struct int_const_s const INT_CONST[] = {
// fixed_t constants, from m_fixed.h
{"FRACUNIT",FRACUNIT},
{"FU" ,FRACUNIT},
{"FRACBITS",FRACBITS},
// doomdef.h constants
@ -4871,6 +4873,36 @@ struct int_const_s const INT_CONST[] = {
{"tr_trans90",tr_trans90},
{"NUMTRANSMAPS",NUMTRANSMAPS},
// Alpha styles (blend modes)
{"AST_COPY",AST_COPY},
{"AST_TRANSLUCENT",AST_TRANSLUCENT},
{"AST_ADD",AST_ADD},
{"AST_SUBTRACT",AST_SUBTRACT},
{"AST_REVERSESUBTRACT",AST_REVERSESUBTRACT},
{"AST_MODULATE",AST_MODULATE},
{"AST_OVERLAY",AST_OVERLAY},
// Render flags
{"RF_HORIZONTALFLIP",RF_HORIZONTALFLIP},
{"RF_VERTICALFLIP",RF_VERTICALFLIP},
{"RF_ABSOLUTEOFFSETS",RF_ABSOLUTEOFFSETS},
{"RF_FLIPOFFSETS",RF_FLIPOFFSETS},
{"RF_SPLATMASK",RF_SPLATMASK},
{"RF_SLOPESPLAT",RF_SLOPESPLAT},
{"RF_OBJECTSLOPESPLAT",RF_OBJECTSLOPESPLAT},
{"RF_NOSPLATBILLBOARD",RF_NOSPLATBILLBOARD},
{"RF_NOSPLATROLLANGLE",RF_NOSPLATROLLANGLE},
{"RF_BLENDMASK",RF_BLENDMASK},
{"RF_FULLBRIGHT",RF_FULLBRIGHT},
{"RF_FULLDARK",RF_FULLDARK},
{"RF_NOCOLORMAPS",RF_NOCOLORMAPS},
{"RF_SPRITETYPEMASK",RF_SPRITETYPEMASK},
{"RF_PAPERSPRITE",RF_PAPERSPRITE},
{"RF_FLOORSPRITE",RF_FLOORSPRITE},
{"RF_SHADOWDRAW",RF_SHADOWDRAW},
{"RF_SHADOWEFFECTS",RF_SHADOWEFFECTS},
{"RF_DROPSHADOW",RF_DROPSHADOW},
// Level flags
{"LF_SCRIPTISFILE",LF_SCRIPTISFILE},
{"LF_SPEEDMUSIC",LF_SPEEDMUSIC},

View file

@ -59,6 +59,12 @@ ATTRINLINE static FUNCINLINE char myfget_color(MYFILE *f)
if (c >= '0' && c <= '9')
return 0x80+(c-'0');
c = tolower(c);
if (c >= 'a' && c <= 'f')
return 0x80+10+(c-'a');
return 0x80; // Unhandled -- default to no color
}

View file

@ -2232,8 +2232,35 @@ void G_Ticker(boolean run)
// Costs a life to retry ... unless the player in question is dead already, or you haven't even touched the first starpost in marathon run.
if (marathonmode && gamemap == spmarathon_start && !players[consoleplayer].starposttime)
{
player_t *p = &players[consoleplayer];
marathonmode |= MA_INIT;
marathontime = 0;
numgameovers = tokenlist = token = 0;
countdown = countdown2 = exitfadestarted = 0;
p->playerstate = PST_REBORN;
p->starpostx = p->starposty = p->starpostz = 0;
p->lives = startinglivesbalance[0];
p->continues = 1;
p->score = 0;
// The latter two should clear by themselves, but just in case
p->pflags &= ~(PF_TAGIT|PF_GAMETYPEOVER|PF_FULLSTASIS);
// Clear cheatcodes too, just in case.
p->pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS);
p->xtralife = 0;
// Reset unlockable triggers
unlocktriggers = 0;
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
}
else if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES)
players[consoleplayer].lives -= 1;

View file

@ -506,13 +506,13 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
v[0].s = v[3].s = ((sx)/(float)(gpatch->width))*hwrPatch->max_s;
if (sx + w > gpatch->width)
v[2].s = v[1].s = hwrPatch->max_s;
v[2].s = v[1].s = hwrPatch->max_s - ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s;
else
v[2].s = v[1].s = ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s;
v[0].t = v[1].t = ((sy)/(float)(gpatch->height))*hwrPatch->max_t;
if (sy + h > gpatch->height)
v[2].t = v[3].t = hwrPatch->max_t;
v[2].t = v[3].t = hwrPatch->max_t - ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t;
else
v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t;

View file

@ -6458,8 +6458,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_fizzle, // deathsound
10*FRACUNIT, // speed
48*FRACUNIT, // radius
160*FRACUNIT, // height
24*FRACUNIT, // radius
80*FRACUNIT, // height
0, // display offset
DMG_ELECTRIC, // mass
1, // damage

View file

@ -163,6 +163,8 @@ static const struct {
{META_SKIN, "skin_t"},
{META_POWERS, "player_t.powers"},
{META_SOUNDSID, "skin_t.soundsid"},
{META_SKINSPRITES, "skin_t.sprites"},
{META_SKINSPRITESLIST, "skin_t.sprites[]"},
{META_VERTEX, "vertex_t"},
{META_LINE, "line_t"},

View file

@ -896,8 +896,10 @@ static int libd_getColormap(lua_State *L)
else if (lua_type(L, 1) == LUA_TNUMBER) // skin number
{
skinnum = (INT32)luaL_checkinteger(L, 1);
if (skinnum < TC_BLINK || skinnum >= MAXSKINS)
return luaL_error(L, "skin number %d is out of range (%d - %d)", skinnum, TC_BLINK, MAXSKINS-1);
if (skinnum >= MAXSKINS)
return luaL_error(L, "skin number %d is out of range (>%d)", skinnum, MAXSKINS-1);
else if (skinnum < 0 && skinnum > TC_DEFAULT)
return luaL_error(L, "translation colormap index is out of range");
}
else // skin name
{

View file

@ -35,6 +35,8 @@ extern lua_State *gL;
#define META_SKIN "SKIN_T*"
#define META_POWERS "PLAYER_T*POWERS"
#define META_SOUNDSID "SKIN_T*SOUNDSID"
#define META_SKINSPRITES "SKIN_T*SPRITES"
#define META_SKINSPRITESLIST "SKIN_T*SPRITES[]"
#define META_VERTEX "VERTEX_T*"
#define META_LINE "LINE_T*"

View file

@ -2189,6 +2189,8 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->levelflags);
else if (fastcmp(field,"menuflags"))
lua_pushinteger(L, header->menuflags);
else if (fastcmp(field,"selectheading"))
lua_pushstring(L, header->selectheading);
else if (fastcmp(field,"startrings"))
lua_pushinteger(L, header->startrings);
else if (fastcmp(field, "sstimer"))

View file

@ -192,18 +192,30 @@ static luaL_Reg lib[] = {
{"cos", lib_finecosine},
{"tan", lib_finetangent},
{"FixedAngle", lib_fixedangle},
{"fixangle" , lib_fixedangle},
{"AngleFixed", lib_anglefixed},
{"anglefix" , lib_anglefixed},
{"InvAngle", lib_invangle},
{"FixedMul", lib_fixedmul},
{"fixmul" , lib_fixedmul},
{"FixedInt", lib_fixedint},
{"fixint" , lib_fixedint},
{"FixedDiv", lib_fixeddiv},
{"fixdiv" , lib_fixeddiv},
{"FixedRem", lib_fixedrem},
{"fixrem" , lib_fixedrem},
{"FixedSqrt", lib_fixedsqrt},
{"fixsqrt" , lib_fixedsqrt},
{"FixedHypot", lib_fixedhypot},
{"fixhypot" , lib_fixedhypot},
{"FixedFloor", lib_fixedfloor},
{"fixfloor" , lib_fixedfloor},
{"FixedTrunc", lib_fixedtrunc},
{"fixtrunc" , lib_fixedtrunc},
{"FixedCeil", lib_fixedceil},
{"fixceil" , lib_fixedceil},
{"FixedRound", lib_fixedround},
{"fixround" , lib_fixedround},
{"GetSecSpecial", lib_getsecspecial},
{"All7Emeralds", lib_all7emeralds},
{"ColorOpposite", lib_coloropposite},

View file

@ -158,6 +158,10 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->flashpal);
else if (fastcmp(field,"skincolor"))
lua_pushinteger(L, plr->skincolor);
else if (fastcmp(field,"skin"))
lua_pushinteger(L, plr->skin);
else if (fastcmp(field,"availabilities"))
lua_pushinteger(L, plr->availabilities);
else if (fastcmp(field,"score"))
lua_pushinteger(L, plr->score);
else if (fastcmp(field,"dashspeed"))
@ -469,6 +473,10 @@ static int player_set(lua_State *L)
return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, numskincolors-1);
plr->skincolor = newcolor;
}
else if (fastcmp(field,"skin"))
return NOSET;
else if (fastcmp(field,"availabilities"))
return NOSET;
else if (fastcmp(field,"score"))
plr->score = (UINT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"dashspeed"))

View file

@ -21,7 +21,6 @@
enum skin {
skin_valid = 0,
skin_name,
skin_spritedef,
skin_wadnum,
skin_flags,
skin_realname,
@ -54,12 +53,12 @@ enum skin {
skin_contspeed,
skin_contangle,
skin_soundsid,
skin_availability
skin_availability,
skin_sprites
};
static const char *const skin_opt[] = {
"valid",
"name",
"spritedef",
"wadnum",
"flags",
"realname",
@ -93,6 +92,7 @@ static const char *const skin_opt[] = {
"contangle",
"soundsid",
"availability",
"sprites",
NULL};
#define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field])
@ -113,8 +113,6 @@ static int skin_get(lua_State *L)
case skin_name:
lua_pushstring(L, skin->name);
break;
case skin_spritedef:
return UNIMPLEMENTED;
case skin_wadnum:
// !!WARNING!! May differ between clients due to music wads, therefore NOT NETWORK SAFE
return UNIMPLEMENTED;
@ -214,6 +212,9 @@ static int skin_get(lua_State *L)
case skin_availability:
lua_pushinteger(L, skin->availability);
break;
case skin_sprites:
LUA_PushLightUserdata(L, skin->sprites, META_SKINSPRITES);
break;
}
return 1;
}
@ -324,6 +325,49 @@ static int soundsid_num(lua_State *L)
return 1;
}
enum spritesopt {
numframes = 0
};
static const char *const sprites_opt[] = {
"numframes",
NULL};
// skin.sprites[i] -> sprites[i]
static int lib_getSkinSprite(lua_State *L)
{
spritedef_t *sprites = (spritedef_t *)luaL_checkudata(L, 1, META_SKINSPRITES);
playersprite_t i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMPLAYERSPRITES*2)
return luaL_error(L, LUA_QL("skin_t") " field 'sprites' index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1);
LUA_PushLightUserdata(L, &sprites[i], META_SKINSPRITESLIST);
return 1;
}
// #skin.sprites -> NUMPLAYERSPRITES*2
static int lib_numSkinsSprites(lua_State *L)
{
lua_pushinteger(L, NUMPLAYERSPRITES*2);
return 1;
}
static int sprite_get(lua_State *L)
{
spritedef_t *sprite = (spritedef_t *)luaL_checkudata(L, 1, META_SKINSPRITESLIST);
enum spritesopt field = luaL_checkoption(L, 2, NULL, sprites_opt);
switch (field)
{
case numframes:
lua_pushinteger(L, sprite->numframes);
break;
}
return 1;
}
int LUA_SkinLib(lua_State *L)
{
luaL_newmetatable(L, META_SKIN);
@ -345,6 +389,19 @@ int LUA_SkinLib(lua_State *L)
lua_setfield(L, -2, "__len");
lua_pop(L,1);
luaL_newmetatable(L, META_SKINSPRITES);
lua_pushcfunction(L, lib_getSkinSprite);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_numSkinsSprites);
lua_setfield(L, -2, "__len");
lua_pop(L,1);
luaL_newmetatable(L, META_SKINSPRITESLIST);
lua_pushcfunction(L, sprite_get);
lua_setfield(L, -2, "__index");
lua_pop(L,1);
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getSkin);

View file

@ -6937,8 +6937,7 @@ static void M_SelectableClearMenus(INT32 choice)
static void M_UltimateCheat(INT32 choice)
{
(void)choice;
if (Playing())
LUA_Hook(GameQuit);
LUAh_GameQuit(true);
I_Quit();
}
@ -13372,8 +13371,7 @@ void M_QuitResponse(INT32 ch)
if (ch != 'y' && ch != KEY_ENTER)
return;
if (Playing())
LUA_Hook(GameQuit);
LUAh_GameQuit(true);
if (!(netgame || cv_debug))
{
S_ResetCaptions();

View file

@ -3924,6 +3924,10 @@ void A_BossDeath(mobj_t *mo)
}
else
{
// Initialize my junk
junk.tags.tags = NULL;
junk.tags.count = 0;
// Bring the egg trap up to the surface
// Incredibly shitty code ahead
Tag_FSet(&junk.tags, LE_CAPSULE0);
@ -4053,6 +4057,10 @@ bossjustdie:
}
case MT_KOOPA:
{
// Initialize my junk
junk.tags.tags = NULL;
junk.tags.count = 0;
Tag_FSet(&junk.tags, LE_KOOPA);
EV_DoCeiling(&junk, raiseToHighest);
return;

View file

@ -1388,6 +1388,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (player->bot)
return;
// Initialize my junk
junk.tags.tags = NULL;
junk.tags.count = 0;
Tag_FSet(&junk.tags, LE_AXE);
EV_DoElevator(&junk, bridgeFall, false);

View file

@ -982,7 +982,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_SALOONDOOR && tmthing->player)
{
mobj_t *ref = (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)) ? tmthing->tracer : tmthing;
if ((thing->flags2 & MF2_AMBUSH) || ref != tmthing)
if (((thing->flags2 & MF2_AMBUSH) && (tmthing->z <= thing->z + thing->height) && (tmthing->z + tmthing->height >= thing->z))
|| ref != tmthing)
{
fixed_t dm = min(FixedHypot(ref->momx, ref->momy), 16*FRACUNIT);
angle_t ang = R_PointToAngle2(0, 0, ref->momx, ref->momy) - thing->angle;
@ -995,7 +996,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_SALOONDOORCENTER && tmthing->player)
{
if ((thing->flags2 & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)))
if (((thing->flags2 & MF2_AMBUSH) && (tmthing->z <= thing->z + thing->height) && (tmthing->z + tmthing->height >= thing->z))
|| (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)))
return true;
}
@ -3443,9 +3445,17 @@ static boolean PTR_SlideTraverse(intercept_t *in)
P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector);
}
if (slidemo->player && slidemo->player->charability == CA_GLIDEANDCLIMB
&& (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing))
PTR_GlideClimbTraverse(li);
if (slidemo->player)
{
if (slidemo->player->charability == CA_GLIDEANDCLIMB
&& (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing))
PTR_GlideClimbTraverse(li);
else
{
slidemo->player->lastsidehit = li->sidenum[P_PointOnLineSide(slidemo->x, slidemo->y, li)];
slidemo->player->lastlinehit = (INT16)(li - lines);
}
}
if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing))
{

View file

@ -3366,7 +3366,7 @@ void P_MobjCheckWater(mobj_t *mobj)
}
// skipping stone!
if (p && (p->charability2 == CA2_SPINDASH) && p->speed/2 > abs(mobj->momz)
if (p && p->speed/2 > abs(mobj->momz)
&& ((p->pflags & (PF_SPINNING|PF_JUMPED)) == PF_SPINNING)
&& ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop)
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom)))
@ -5654,14 +5654,10 @@ static void P_Boss9Thinker(mobj_t *mobj)
if (P_RandomRange(1,(dist>>FRACBITS)/16) == 1)
break;
}
if (spawner)
if (spawner && dist)
{
mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER);
if (dist == 0)
missile->fuse = 0;
else
missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy));
missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy));
if (missile->fuse > mobj->fuse)
P_RemoveMobj(missile);
@ -7937,7 +7933,7 @@ static boolean P_MobjPushableThink(mobj_t *mobj)
P_PushableThinker(mobj);
// Extinguish fire objects in water. (Yes, it's extraordinarily rare to have a pushable flame object, but Brak uses such a case.)
if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL
if ((mobj->flags & MF_FIRE) && !(mobj->eflags & MFE_TOUCHLAVA)
&& (mobj->eflags & (MFE_UNDERWATER | MFE_TOUCHWATER)))
{
P_KillMobj(mobj, NULL, NULL, 0);
@ -9651,6 +9647,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
break;
}
case MT_SALOONDOOR:
if (!mobj->tracer) // Door center is gone or not spawned?
{
P_RemoveMobj(mobj); // Die
return false;
}
P_SaloonDoorThink(mobj);
break;
case MT_MINECARTSPAWNER:
@ -9705,7 +9707,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_MobjCheckWater(mobj);
// Extinguish fire objects in water
if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL
if ((mobj->flags & MF_FIRE) && !(mobj->eflags & MFE_TOUCHLAVA)
&& (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
{
P_KillMobj(mobj, NULL, NULL, 0);
@ -11396,6 +11398,10 @@ void P_SpawnPlayer(INT32 playernum)
p->normalspeed = skins[p->skin].normalspeed;
p->jumpfactor = skins[p->skin].jumpfactor;
}
// Clear lastlinehit and lastsidehit
p->lastsidehit = -1;
p->lastlinehit = -1;
//awayview stuff
p->awayviewmobj = NULL;

View file

@ -1621,6 +1621,14 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val)
P_SetLinedefV1(i, atol(val));
else if (fastcmp(param, "v2"))
P_SetLinedefV2(i, atol(val));
else if (strlen(param) == 7 && fastncmp(param, "arg", 3) && fastncmp(param + 4, "str", 3))
{
size_t argnum = param[3] - '0';
if (argnum >= NUMLINESTRINGARGS)
return;
lines[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(lines[i].stringargs[argnum], val, strlen(val) + 1);
}
else if (fastncmp(param, "arg", 3) && strlen(param) > 3)
{
size_t argnum = atol(param + 3);
@ -1628,14 +1636,6 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val)
return;
lines[i].args[argnum] = atol(val);
}
else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9)
{
size_t argnum = param[9] - '0';
if (argnum >= NUMLINESTRINGARGS)
return;
lines[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(lines[i].stringargs[argnum], val, strlen(val) + 1);
}
else if (fastcmp(param, "sidefront"))
lines[i].sidenum[0] = atol(val);
else if (fastcmp(param, "sideback"))
@ -1720,6 +1720,14 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
else if (fastcmp(param, "ambush") && fastcmp("true", val))
mapthings[i].options |= MTF_AMBUSH;
else if (strlen(param) == 7 && fastncmp(param, "arg", 3) && fastncmp(param + 4, "str", 3))
{
size_t argnum = param[3] - '0';
if (argnum >= NUMMAPTHINGSTRINGARGS)
return;
mapthings[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(mapthings[i].stringargs[argnum], val, strlen(val) + 1);
}
else if (fastncmp(param, "arg", 3) && strlen(param) > 3)
{
size_t argnum = atol(param + 3);
@ -1727,14 +1735,6 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
return;
mapthings[i].args[argnum] = atol(val);
}
else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9)
{
size_t argnum = param[9] - '0';
if (argnum >= NUMMAPTHINGSTRINGARGS)
return;
mapthings[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(mapthings[i].stringargs[argnum], val, strlen(val) + 1);
}
}
/** From a given position table, run a specified parser function through a {}-encapsuled text.

View file

@ -4420,15 +4420,19 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
// clear the special so you can't push the button twice.
sector->special = 0;
// Initialize my junk
junk.tags.tags = NULL;
junk.tags.count = 0;
// Move the button down
Tag_FSet(&junk.tags, 680);
Tag_FSet(&junk.tags, LE_CAPSULE0);
EV_DoElevator(&junk, elevateDown, false);
// Open the top FOF
Tag_FSet(&junk.tags, 681);
Tag_FSet(&junk.tags, LE_CAPSULE1);
EV_DoFloor(&junk, raiseFloorToNearestFast);
// Open the bottom FOF
Tag_FSet(&junk.tags, 682);
Tag_FSet(&junk.tags, LE_CAPSULE2);
EV_DoCeiling(&junk, lowerToLowestFast);
// Mark all players with the time to exit thingy!
@ -4503,7 +4507,7 @@ DoneSection2:
P_InstaThrust(player->mo, player->mo->angle, linespeed);
if ((lines[i].flags & ML_EFFECT5) && (player->charability2 == CA2_SPINDASH)) // Roll!
if (lines[i].flags & ML_EFFECT5) // Roll!
{
if (!(player->pflags & PF_SPINNING))
player->pflags |= PF_SPINNING;
@ -4669,7 +4673,7 @@ DoneSection2:
break;
case 7: // Make player spin
if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH))
if (!(player->pflags & PF_SPINNING))
{
player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);

View file

@ -1341,7 +1341,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
// Transformation animation
P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1);
if (giverings)
if (giverings && player->rings < 50)
player->rings = 50;
// Just in case.
@ -1491,10 +1491,10 @@ void P_PlayLivesJingle(player_t *player)
if (player && !P_IsLocalPlayer(player))
return;
if (use1upSound || cv_1upsound.value)
S_StartSound(NULL, sfx_oneup);
else if (mariomode)
if (mariomode)
S_StartSound(NULL, sfx_marioa);
else if (use1upSound || cv_1upsound.value)
S_StartSound(NULL, sfx_oneup);
else
{
P_PlayJingle(player, JT_1UP);
@ -2329,7 +2329,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
P_MobjCheckWater(player->mo);
if (player->pflags & PF_SPINNING)
{
if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH))
if (!(player->pflags & PF_STARTDASH) && player->panim != PA_ROLL && player->panim != PA_ETC
&& player->panim != PA_ABILITY && player->panim != PA_ABILITY2)
{
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_spin);
@ -4524,6 +4525,9 @@ void P_DoJump(player_t *player, boolean soundandstate)
player->mo->eflags &= ~MFE_APPLYPMOMZ;
player->pflags |= P_GetJumpFlags(player);;
if (player->charflags & SF_NOJUMPDAMAGE)
player->pflags &= ~PF_SPINNING;
if (soundandstate)
{
@ -8605,12 +8609,6 @@ void P_MovePlayer(player_t *player)
player->climbing--;
}
if (!player->climbing)
{
player->lastsidehit = -1;
player->lastlinehit = -1;
}
// Make sure you're not teetering when you shouldn't be.
if (player->panim == PA_EDGE
&& (player->mo->momx || player->mo->momy || player->mo->momz))
@ -8635,6 +8633,7 @@ void P_MovePlayer(player_t *player)
P_DoFiring(player, cmd);
{
boolean atspinheight = false;
fixed_t oldheight = player->mo->height;
// Less height while spinning. Good for spinning under things...?
@ -8644,32 +8643,35 @@ void P_MovePlayer(player_t *player)
|| player->powers[pw_tailsfly] || player->pflags & PF_GLIDING
|| (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING)
|| (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED))
{
player->mo->height = P_GetPlayerSpinHeight(player);
atspinheight = true;
}
else
player->mo->height = P_GetPlayerHeight(player);
if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling
player->mo->z -= player->mo->height - oldheight;
}
// Crush test...
if ((player->mo->ceilingz - player->mo->floorz < player->mo->height)
&& !(player->mo->flags & MF_NOCLIP))
{
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SPINNING))
// Crush test...
if ((player->mo->ceilingz - player->mo->floorz < player->mo->height)
&& !(player->mo->flags & MF_NOCLIP))
{
player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
}
else if (player->mo->ceilingz - player->mo->floorz < player->mo->height)
{
if ((netgame || multiplayer) && player->spectator)
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators
else
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED);
if (!atspinheight)
{
player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
}
else if (player->mo->ceilingz - player->mo->floorz < player->mo->height)
{
if ((netgame || multiplayer) && player->spectator)
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators
else
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED);
if (player->playerstate == PST_DEAD)
return;
if (player->playerstate == PST_DEAD)
return;
}
}
}
@ -12578,13 +12580,16 @@ void P_PlayerAfterThink(player_t *player)
player->powers[pw_carry] = CR_NONE;
else
{
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true);
if (tails->player)
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true);
else
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->angle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->angle, 4*FRACUNIT), true);
player->mo->momx = tails->momx;
player->mo->momy = tails->momy;
player->mo->momz = tails->momz;
}
if (G_CoopGametype() && (!tails->player || tails->player->bot != 1))
if (G_CoopGametype() && tails->player && tails->player->bot != 1)
{
player->mo->angle = tails->angle;
@ -12599,7 +12604,7 @@ void P_PlayerAfterThink(player_t *player)
{
if (player->mo->state-states != S_PLAY_RIDE)
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
if ((tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER))
if (tails->player && (tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER))
tails->player->powers[pw_tailsfly] = 0;
}
else

View file

@ -106,13 +106,17 @@ extern lumpnum_t viewborderlump[8];
#define GTC_CACHE 1
#define TC_DEFAULT -1
#define TC_BOSS -2
#define TC_METALSONIC -3 // For Metal Sonic battle
#define TC_ALLWHITE -4 // For Cy-Brak-demon
#define TC_RAINBOW -5 // For single colour
#define TC_BLINK -6 // For item blinking, according to kart
#define TC_DASHMODE -7 // For Metal Sonic's dashmode
enum
{
TC_BOSS = INT8_MIN,
TC_METALSONIC, // For Metal Sonic battle
TC_ALLWHITE, // For Cy-Brak-demon
TC_RAINBOW, // For single colour
TC_BLINK, // For item blinking, according to kart
TC_DASHMODE, // For Metal Sonic's dashmode
TC_DEFAULT
};
// Custom player skin translation
// Initialize color translation tables, for player rendering etc.

View file

@ -540,7 +540,7 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor)
// Polyobjects have no ffloors, and they're handled in the conditional above.
if (pfloor->ffloor != NULL)
return (pfloor->ffloor->flags & FF_TRANSLUCENT);
return (pfloor->ffloor->flags & (FF_TRANSLUCENT|FF_FOG));
return false;
}
@ -1191,7 +1191,7 @@ static void R_RenderSegLoop (void)
// Lactozilla: Cull part of the column by the 3D floor if it can't be seen
// "bottom" is the top pixel of the floor column
if (ffbottom >= bottom-1 && R_FFloorCanClip(&ffloor[i]))
if (ffbottom >= bottom-1 && R_FFloorCanClip(&ffloor[i]) && !curline->polyseg)
{
rw_floormarked = true;
floorclip[rw_x] = fftop;
@ -1239,7 +1239,7 @@ static void R_RenderSegLoop (void)
// Lactozilla: Cull part of the column by the 3D floor if it can't be seen
// "top" is the height of the ceiling column
if (fftop <= top+1 && R_FFloorCanClip(&ffloor[i]))
if (fftop <= top+1 && R_FFloorCanClip(&ffloor[i]) && !curline->polyseg)
{
rw_ceilingmarked = true;
ceilingclip[rw_x] = ffbottom;

View file

@ -511,6 +511,9 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
GETFLAG(MULTIABILITY)
GETFLAG(NONIGHTSROTATION)
GETFLAG(NONIGHTSSUPER)
GETFLAG(NOSUPERSPRITES)
GETFLAG(NOSUPERJUMPBOOST)
GETFLAG(CANBUSTWALLS)
#undef GETFLAG
else // let's check if it's a sound, otherwise error out

View file

@ -1057,8 +1057,7 @@ void I_GetEvent(void)
M_SetupJoystickMenu(0);
break;
case SDL_QUIT:
if (Playing())
LUA_Hook(GameQuit);
LUAh_GameQuit(true);
I_Quit();
break;
}

View file

@ -66,6 +66,7 @@
#include "p_setup.h" // P_ScanThings
#endif
#include "m_misc.h" // M_MapNumber
#include "g_game.h" // G_SetGameModified
#ifdef HWRENDER
#include "hardware/hw_main.h"
@ -683,9 +684,9 @@ static UINT16 W_InitFileError (const char *filename, boolean exitworthy)
if (exitworthy)
{
#ifdef _DEBUG
CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
CONS_Error(va("%s was not found or not valid.\nCheck the log for more details.\n", filename));
#else
I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
I_Error("%s was not found or not valid.\nCheck the log for more details.\n", filename);
#endif
}
else
@ -716,7 +717,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
#endif
size_t packetsize;
UINT8 md5sum[16];
boolean important;
int important;
if (!(refreshdirmenu & REFRESHDIR_ADDFILE))
refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier
@ -746,10 +747,18 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
if ((handle = W_OpenWadFile(&filename, true)) == NULL)
return W_InitFileError(filename, startup);
important = W_VerifyNMUSlumps(filename, startup);
if (important == -1)
{
fclose(handle);
return INT16_MAX;
}
// Check if wad files will overflow fileneededbuffer. Only the filename part
// is send in the packet; cf.
// see PutFileNeeded in d_netfil.c
if ((important = !W_VerifyNMUSlumps(filename)))
if ((important = !important))
{
packetsize = packetsizetally + nameonlylength(filename) + 22;
@ -811,6 +820,9 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
return W_InitFileError(filename, startup);
}
if (important && !mainfile)
G_SetGameModified(true);
//
// link wad file to search files
//
@ -1919,8 +1931,16 @@ static lumpchecklist_t folderblacklist[] =
static int
W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
{
int verified = true;
zend_t zend;
zentry_t zentry;
zlentry_t zlentry;
long file_size;/* size of zip file */
long data_size;/* size of data inside zip file */
long old_position;
UINT16 numlumps;
size_t i;
@ -1936,6 +1956,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
// Central directory bullshit
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
if (!ResFindSignature(fp, pat_end, max(0, ftell(fp) - (22 + 65536))))
return true;
@ -1943,6 +1965,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
if (fread(&zend, 1, sizeof zend, fp) < sizeof zend)
return true;
data_size = sizeof zend;
numlumps = zend.entries;
fseek(fp, zend.cdiroffset, SEEK_SET);
@ -1957,40 +1981,79 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
if (memcmp(zentry.signature, pat_central, 4))
return true;
fullname = malloc(zentry.namelen + 1);
if (fgets(fullname, zentry.namelen + 1, fp) != fullname)
return true;
// Strip away file address and extension for the 8char name.
if ((trimname = strrchr(fullname, '/')) != 0)
trimname++;
else
trimname = fullname; // Care taken for root files.
if (*trimname) // Ignore directories, well kinda
if (verified == true)
{
if ((dotpos = strrchr(trimname, '.')) == 0)
dotpos = fullname + strlen(fullname); // Watch for files without extension.
fullname = malloc(zentry.namelen + 1);
if (fgets(fullname, zentry.namelen + 1, fp) != fullname)
return true;
memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
strncpy(lumpname, trimname, min(8, dotpos - trimname));
// Strip away file address and extension for the 8char name.
if ((trimname = strrchr(fullname, '/')) != 0)
trimname++;
else
trimname = fullname; // Care taken for root files.
if (! W_VerifyName(lumpname, checklist, status))
return false;
if (*trimname) // Ignore directories, well kinda
{
if ((dotpos = strrchr(trimname, '.')) == 0)
dotpos = fullname + strlen(fullname); // Watch for files without extension.
// Check for directories next, if it's blacklisted it will return false
if (W_VerifyName(fullname, folderblacklist, status))
return false;
memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
strncpy(lumpname, trimname, min(8, dotpos - trimname));
if (! W_VerifyName(lumpname, checklist, status))
verified = false;
// Check for directories next, if it's blacklisted it will return false
else if (W_VerifyName(fullname, folderblacklist, status))
verified = false;
}
free(fullname);
// skip and ignore comments/extra fields
if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
return true;
}
else
{
if (fseek(fp, zentry.namelen + zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
return true;
}
free(fullname);
data_size +=
sizeof zentry + zentry.namelen + zentry.xtralen + zentry.commlen;
// skip and ignore comments/extra fields
if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
old_position = ftell(fp);
if (fseek(fp, zentry.offset, SEEK_SET) != 0)
return true;
if (fread(&zlentry, 1, sizeof(zlentry_t), fp) < sizeof (zlentry_t))
return true;
data_size +=
sizeof zlentry + zlentry.namelen + zlentry.xtralen + zlentry.compsize;
fseek(fp, old_position, SEEK_SET);
}
return true;
if (data_size < file_size)
{
const char * error = "ZIP file has holes (%ld extra bytes)\n";
CONS_Alert(CONS_ERROR, error, (file_size - data_size));
return -1;
}
else if (data_size > file_size)
{
const char * error = "Reported size of ZIP file contents exceeds file size (%ld extra bytes)\n";
CONS_Alert(CONS_ERROR, error, (data_size - file_size));
return -1;
}
else
{
return verified;
}
}
// Note: This never opens lumps themselves and therefore doesn't have to
@ -2029,12 +2092,13 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
* be sent.
*
* \param filename Filename of the wad to check.
* \param exit_on_error Whether to exit upon file error.
* \return 1 if file contains only music/sound lumps, 0 if it contains other
* stuff (maps, sprites, dehacked lumps, and so on). -1 if there no
* file exists with that filename
* \author Alam Arias
*/
int W_VerifyNMUSlumps(const char *filename)
int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error)
{
// MIDI, MOD/S3M/IT/XM/OGG/MP3/WAV, WAVE SFX
// ENDOOM text and palette lumps
@ -2108,7 +2172,13 @@ int W_VerifyNMUSlumps(const char *filename)
{NULL, 0},
};
return W_VerifyFile(filename, NMUSlist, false);
int status = W_VerifyFile(filename, NMUSlist, false);
if (status == -1)
W_InitFileError(filename, exit_on_error);
return status;
}
/** \brief Generates a virtual resource used for level data loading.

View file

@ -206,6 +206,6 @@ void W_UnlockCachedPatch(void *patch);
void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5);
int W_VerifyNMUSlumps(const char *filename);
int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error);
#endif // __W_WAD__