mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-20 19:02:34 +00:00
Merge remote-tracking branch 'origin/next' into hooklib-refactor
This commit is contained in:
commit
2778cc3ce9
31 changed files with 432 additions and 173 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
27
src/g_game.c
27
src/g_game.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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*"
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
20
src/p_map.c
20
src/p_map.c
|
@ -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))
|
||||
{
|
||||
|
|
24
src/p_mobj.c
24
src/p_mobj.c
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
14
src/p_spec.c
14
src/p_spec.c
|
@ -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);
|
||||
|
|
67
src/p_user.c
67
src/p_user.c
|
@ -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
|
||||
|
|
18
src/r_draw.h
18
src/r_draw.h
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
130
src/w_wad.c
130
src/w_wad.c
|
@ -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.
|
||||
|
|
|
@ -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__
|
||||
|
|
Loading…
Reference in a new issue