mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-24 21:31:46 +00:00
Merge branch 'udmf-next' into udmf-fofs-mkii
# Conflicts: # src/p_floor.c # src/p_spec.c # src/p_spec.h
This commit is contained in:
commit
e00531ed9c
40 changed files with 1253 additions and 1091 deletions
|
@ -15,7 +15,7 @@
|
|||
* Oogaland
|
||||
* Rob
|
||||
* Shadow Hog
|
||||
* Spherallic
|
||||
* sphere
|
||||
* SRB2-Playah
|
||||
* SSNTails
|
||||
* SteelT
|
||||
|
@ -2208,6 +2208,7 @@ linedeftypes
|
|||
title = "Spawn Object";
|
||||
prefix = "(461)";
|
||||
flags8text = "[3] Set delay by backside sector";
|
||||
flags32text = "[5] Use line angle for object";
|
||||
flags64text = "[6] Spawn inside a range";
|
||||
}
|
||||
|
||||
|
@ -3899,6 +3900,8 @@ thingtypes
|
|||
{
|
||||
title = "Emerald Hunt Location";
|
||||
sprite = "SHRDA0";
|
||||
flags8height = 24;
|
||||
flags8text = "[8] Float";
|
||||
}
|
||||
321
|
||||
{
|
||||
|
|
|
@ -80,7 +80,7 @@ static boolean joyaxis2_default = false;
|
|||
static INT32 joyaxis_count = 0;
|
||||
static INT32 joyaxis2_count = 0;
|
||||
|
||||
#define COM_BUF_SIZE 8192 // command buffer size
|
||||
#define COM_BUF_SIZE (32<<10) // command buffer size
|
||||
#define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases
|
||||
|
||||
static INT32 com_wait; // one command per frame (for cmd sequences)
|
||||
|
|
|
@ -20,12 +20,9 @@
|
|||
#include "d_player.h"
|
||||
|
||||
/*
|
||||
The 'packet version' may be used with packets whose
|
||||
format is expected to change between versions.
|
||||
|
||||
This version is independent of the mod name, and standard
|
||||
version and subversion. It should only account for the
|
||||
basic fields of the packet, and change infrequently.
|
||||
The 'packet version' is used to distinguish packet formats.
|
||||
This version is independent of VERSION and SUBVERSION. Different
|
||||
applications may follow different packet versions.
|
||||
*/
|
||||
#define PACKETVERSION 3
|
||||
|
||||
|
|
51
src/d_main.c
51
src/d_main.c
|
@ -876,6 +876,40 @@ static inline void D_CleanFile(void)
|
|||
}
|
||||
}
|
||||
|
||||
///\brief Checks if a netgame URL is being handled, and changes working directory to the EXE's if so.
|
||||
/// Done because browsers (at least, Firefox on Windows) launch the game from the browser's directory, which causes problems.
|
||||
static void ChangeDirForUrlHandler(void)
|
||||
{
|
||||
// URL handlers are opened by web browsers (at least Firefox) from the browser's working directory, not the game's stored directory,
|
||||
// so chdir to that directory unless overridden.
|
||||
if (M_GetUrlProtocolArg() != NULL && !M_CheckParm("-nochdir"))
|
||||
{
|
||||
size_t i;
|
||||
|
||||
CONS_Printf("%s connect links load game files from the SRB2 application's stored directory. Switching to ", SERVER_URL_PROTOCOL);
|
||||
strlcpy(srb2path, myargv[0], sizeof(srb2path));
|
||||
|
||||
// Get just the directory, minus the EXE name
|
||||
for (i = strlen(srb2path)-1; i > 0; i--)
|
||||
{
|
||||
if (srb2path[i] == '/' || srb2path[i] == '\\')
|
||||
{
|
||||
srb2path[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CONS_Printf("%s\n", srb2path);
|
||||
|
||||
#if defined (_WIN32)
|
||||
SetCurrentDirectoryA(srb2path);
|
||||
#else
|
||||
if (chdir(srb2path) == -1)
|
||||
I_OutputMsg("Couldn't change working directory\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// Identify the SRB2 version, and IWAD file to use.
|
||||
// ==========================================================================
|
||||
|
@ -1064,6 +1098,9 @@ void D_SRB2Main(void)
|
|||
// Test Dehacked lists
|
||||
DEH_Check();
|
||||
|
||||
// Netgame URL special case: change working dir to EXE folder.
|
||||
ChangeDirForUrlHandler();
|
||||
|
||||
// identify the main IWAD file to use
|
||||
IdentifyVersion();
|
||||
|
||||
|
@ -1149,9 +1186,15 @@ void D_SRB2Main(void)
|
|||
if (M_CheckParm("-password") && M_IsNextParm())
|
||||
D_SetPassword(M_GetNextParm());
|
||||
|
||||
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
|
||||
Z_Init();
|
||||
|
||||
// Do this up here so that WADs loaded through the command line can use ExecCfg
|
||||
COM_Init();
|
||||
|
||||
// add any files specified on the command line with -file wadfile
|
||||
// to the wad list
|
||||
if (!(M_CheckParm("-connect") && !M_CheckParm("-server")))
|
||||
if (!((M_GetUrlProtocolArg() || M_CheckParm("-connect")) && !M_CheckParm("-server")))
|
||||
{
|
||||
if (M_CheckParm("-file"))
|
||||
{
|
||||
|
@ -1176,9 +1219,6 @@ void D_SRB2Main(void)
|
|||
if (M_CheckParm("-server") || dedicated)
|
||||
netgame = server = true;
|
||||
|
||||
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
|
||||
Z_Init();
|
||||
|
||||
// adapt tables to SRB2's needs, including extra slots for dehacked file support
|
||||
P_PatchInfoTables();
|
||||
|
||||
|
@ -1186,7 +1226,7 @@ void D_SRB2Main(void)
|
|||
M_InitMenuPresTables();
|
||||
|
||||
// init title screen display params
|
||||
if (M_CheckParm("-connect"))
|
||||
if (M_GetUrlProtocolArg() || M_CheckParm("-connect"))
|
||||
F_InitMenuPresValues();
|
||||
|
||||
//---------------------------------------------------- READY TIME
|
||||
|
@ -1250,7 +1290,6 @@ void D_SRB2Main(void)
|
|||
CONS_Printf("HU_Init(): Setting up heads up display.\n");
|
||||
HU_Init();
|
||||
|
||||
COM_Init();
|
||||
CON_Init();
|
||||
|
||||
D_RegisterServerCommands();
|
||||
|
|
|
@ -3881,7 +3881,26 @@ static void readmaincfg(MYFILE *f)
|
|||
value = atoi(word2); // used for numerical settings
|
||||
|
||||
if (fastcmp(word, "EXECCFG"))
|
||||
COM_BufAddText(va("exec %s\n", word2));
|
||||
{
|
||||
if (strchr(word2, '.'))
|
||||
COM_BufAddText(va("exec %s\n", word2));
|
||||
else
|
||||
{
|
||||
lumpnum_t lumpnum;
|
||||
char newname[9];
|
||||
|
||||
strncpy(newname, word2, 8);
|
||||
|
||||
newname[8] = '\0';
|
||||
|
||||
lumpnum = W_CheckNumForName(newname);
|
||||
|
||||
if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0)
|
||||
CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname);
|
||||
else
|
||||
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
|
||||
}
|
||||
}
|
||||
|
||||
else if (fastcmp(word, "SPSTAGE_START"))
|
||||
{
|
||||
|
@ -4123,6 +4142,10 @@ static void readmaincfg(MYFILE *f)
|
|||
{
|
||||
maxXtraLife = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "USECONTINUES"))
|
||||
{
|
||||
useContinues = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
|
||||
else if (fastcmp(word, "GAMEDATA"))
|
||||
{
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
// Some global defines, that configure the game.
|
||||
#include "doomdef.h"
|
||||
|
||||
#include "m_fixed.h" // See the mapthing_t scale.
|
||||
|
||||
//
|
||||
// Map level types.
|
||||
// The following data structures define the persistent format
|
||||
|
@ -193,17 +195,24 @@ typedef struct
|
|||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#define NUMMAPTHINGARGS 6
|
||||
#define NUMMAPTHINGSTRINGARGS 2
|
||||
|
||||
// Thing definition, position, orientation and type,
|
||||
// plus visibility flags and attributes.
|
||||
typedef struct
|
||||
{
|
||||
INT16 x, y;
|
||||
INT16 angle;
|
||||
INT16 angle, pitch, roll;
|
||||
UINT16 type;
|
||||
UINT16 options;
|
||||
INT16 z;
|
||||
UINT8 extrainfo;
|
||||
fixed_t scale;
|
||||
INT16 tag;
|
||||
INT32 args[NUMMAPTHINGARGS];
|
||||
char *stringargs[NUMMAPTHINGSTRINGARGS];
|
||||
|
||||
struct mobj_s *mobj;
|
||||
} mapthing_t;
|
||||
|
||||
|
|
|
@ -150,6 +150,9 @@ extern char logfilename[1024];
|
|||
// Otherwise we can't force updates!
|
||||
#endif
|
||||
|
||||
/* A custom URL protocol for server links. */
|
||||
#define SERVER_URL_PROTOCOL "srb2://"
|
||||
|
||||
// Does this version require an added patch file?
|
||||
// Comment or uncomment this as necessary.
|
||||
#define USE_PATCH_DTA
|
||||
|
|
|
@ -575,6 +575,8 @@ extern UINT8 creditscutscene;
|
|||
|
||||
extern UINT8 use1upSound;
|
||||
extern UINT8 maxXtraLife; // Max extra lives from rings
|
||||
extern UINT8 useContinues;
|
||||
#define continuesInSession (!multiplayer && (useContinues || ultimatemode || !(cursaveslot > 0)))
|
||||
|
||||
extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations
|
||||
|
||||
|
|
|
@ -3618,7 +3618,7 @@ void F_StartContinue(void)
|
|||
{
|
||||
I_Assert(!netgame && !multiplayer);
|
||||
|
||||
if (players[consoleplayer].continues <= 0)
|
||||
if (continuesInSession && players[consoleplayer].continues <= 0)
|
||||
{
|
||||
Command_ExitGame_f();
|
||||
return;
|
||||
|
@ -3725,7 +3725,9 @@ void F_ContinueDrawer(void)
|
|||
}
|
||||
|
||||
// Draw the continue markers! Show continues.
|
||||
if (ncontinues > 10)
|
||||
if (!continuesInSession)
|
||||
;
|
||||
else if (ncontinues > 10)
|
||||
{
|
||||
if (!(continuetime & 1) || continuetime > 17)
|
||||
V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
|
||||
|
|
|
@ -219,6 +219,7 @@ UINT8 ammoremovaltics = 2*TICRATE;
|
|||
|
||||
UINT8 use1upSound = 0;
|
||||
UINT8 maxXtraLife = 2; // Max extra lives from rings
|
||||
UINT8 useContinues = 0; // Set to 1 to enable continues outside of no-save scenarioes
|
||||
|
||||
UINT8 introtoplay;
|
||||
UINT8 creditscutscene;
|
||||
|
@ -3859,7 +3860,8 @@ static void G_DoContinued(void)
|
|||
I_Assert(!netgame && !multiplayer);
|
||||
I_Assert(pl->continues > 0);
|
||||
|
||||
pl->continues--;
|
||||
if (pl->continues)
|
||||
pl->continues--;
|
||||
|
||||
// Reset score
|
||||
pl->score = 0;
|
||||
|
|
|
@ -467,7 +467,7 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this c
|
|||
// -----------------+
|
||||
// HWR_RenderPlane : Render a floor or ceiling convex polygon
|
||||
// -----------------+
|
||||
static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
|
||||
static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
|
||||
FBITFIELD PolyFlags, INT32 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap)
|
||||
{
|
||||
polyvertex_t * pv;
|
||||
|
@ -489,8 +489,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
|||
static FOutVector *planeVerts = NULL;
|
||||
static UINT16 numAllocedPlaneVerts = 0;
|
||||
|
||||
(void)sector; ///@TODO remove shitty unused variable
|
||||
|
||||
// no convex poly were generated for this subsector
|
||||
if (!xsub->planepoly)
|
||||
return;
|
||||
|
@ -587,8 +585,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
|||
flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatheight);
|
||||
|
||||
// transform
|
||||
v3d = planeVerts;
|
||||
|
||||
if (FOFsector != NULL)
|
||||
{
|
||||
if (!isceiling) // it's a floor
|
||||
|
@ -631,44 +627,43 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
|||
flatyref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
|
||||
}
|
||||
|
||||
for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++)
|
||||
{
|
||||
// Hurdler: add scrolling texture on floor/ceiling
|
||||
if (texflat)
|
||||
{
|
||||
v3d->sow = (float)(pv->x / fflatwidth) + scrollx;
|
||||
v3d->tow = -(float)(pv->y / fflatheight) + scrolly;
|
||||
}
|
||||
else
|
||||
{
|
||||
v3d->sow = (float)((pv->x / fflatwidth) - flatxref + scrollx);
|
||||
v3d->tow = (float)(flatyref - (pv->y / fflatheight) + scrolly);
|
||||
}
|
||||
#define SETUP3DVERT(vert, vx, vy) {\
|
||||
/* Hurdler: add scrolling texture on floor/ceiling */\
|
||||
if (texflat)\
|
||||
{\
|
||||
vert->sow = (float)((vx) / fflatwidth) + scrollx;\
|
||||
vert->tow = -(float)((vy) / fflatheight) + scrolly;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
vert->sow = (float)(((vx) / fflatwidth) - flatxref + scrollx);\
|
||||
vert->tow = (float)(flatyref - ((vy) / fflatheight) + scrolly);\
|
||||
}\
|
||||
\
|
||||
/* Need to rotate before translate */\
|
||||
if (angle) /* Only needs to be done if there's an altered angle */\
|
||||
{\
|
||||
tempxsow = FLOAT_TO_FIXED(vert->sow);\
|
||||
tempytow = FLOAT_TO_FIXED(vert->tow);\
|
||||
if (texflat)\
|
||||
tempytow = -tempytow;\
|
||||
vert->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));\
|
||||
vert->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));\
|
||||
}\
|
||||
\
|
||||
vert->x = (vx);\
|
||||
vert->y = height;\
|
||||
vert->z = (vy);\
|
||||
\
|
||||
if (slope)\
|
||||
{\
|
||||
fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\
|
||||
vert->y = FIXED_TO_FLOAT(fixedheight);\
|
||||
}\
|
||||
}
|
||||
|
||||
// Need to rotate before translate
|
||||
if (angle) // Only needs to be done if there's an altered angle
|
||||
{
|
||||
tempxsow = FLOAT_TO_FIXED(v3d->sow);
|
||||
tempytow = FLOAT_TO_FIXED(v3d->tow);
|
||||
if (texflat)
|
||||
tempytow = -tempytow;
|
||||
v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
|
||||
v3d->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
|
||||
}
|
||||
|
||||
//v3d->sow = (float)(v3d->sow - flatxref + scrollx);
|
||||
//v3d->tow = (float)(flatyref - v3d->tow + scrolly);
|
||||
|
||||
v3d->x = pv->x;
|
||||
v3d->y = height;
|
||||
v3d->z = pv->y;
|
||||
|
||||
if (slope)
|
||||
{
|
||||
fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED(pv->x), FLOAT_TO_FIXED(pv->y));
|
||||
v3d->y = FIXED_TO_FLOAT(fixedheight);
|
||||
}
|
||||
}
|
||||
for (i = 0, v3d = planeVerts; i < nrPlaneVerts; i++,v3d++,pv++)
|
||||
SETUP3DVERT(v3d, pv->x, pv->y);
|
||||
|
||||
// only useful for flat coloured triangles
|
||||
//Surf.FlatColor = 0xff804020;
|
||||
|
@ -679,36 +674,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
|||
Surf.FlatColor.s.red = Surf.FlatColor.s.green =
|
||||
Surf.FlatColor.s.blue = LightLevelToLum(lightlevel); // Don't take from the frontsector, or the game will crash
|
||||
|
||||
#if 0 // no colormap test
|
||||
// colormap test
|
||||
if (gr_frontsector)
|
||||
{
|
||||
sector_t *psector = gr_frontsector;
|
||||
|
||||
if (slope)
|
||||
fixedheight = P_GetZAt(slope, psector->soundorg.x, psector->soundorg.y);
|
||||
|
||||
if (psector->ffloors)
|
||||
{
|
||||
ffloor_t *caster = psector->lightlist[R_GetPlaneLight(psector, fixedheight, false)].caster;
|
||||
psector = caster ? §ors[caster->secnum] : psector;
|
||||
|
||||
if (caster)
|
||||
{
|
||||
lightlevel = psector->lightlevel;
|
||||
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = LightLevelToLum(lightlevel);
|
||||
}
|
||||
}
|
||||
if (psector->extra_colormap)
|
||||
Surf.FlatColor.rgba = HWR_Lighting(lightlevel,psector->extra_colormap->rgba,psector->extra_colormap->fadergba, false, true);
|
||||
else
|
||||
Surf.FlatColor.rgba = HWR_Lighting(lightlevel,NORMALFOG,FADEFOG, false, true);
|
||||
}
|
||||
else
|
||||
Surf.FlatColor.rgba = HWR_Lighting(lightlevel,NORMALFOG,FADEFOG, false, true);
|
||||
|
||||
#endif // NOPE
|
||||
|
||||
if (planecolormap)
|
||||
{
|
||||
if (fogplane)
|
||||
|
@ -734,6 +699,79 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
|||
|
||||
HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags);
|
||||
|
||||
if (subsector)
|
||||
{
|
||||
// Horizon lines
|
||||
FOutVector horizonpts[6];
|
||||
float dist, vx, vy;
|
||||
float x1, y1, xd, yd;
|
||||
UINT8 numplanes, j;
|
||||
vertex_t v; // For determining the closest distance from the line to the camera, to split render planes for minimum distortion;
|
||||
|
||||
const float renderdist = 27000.0f; // How far out to properly render the plane
|
||||
const float farrenderdist = 32768.0f; // From here, raise plane to horizon level to fill in the line with some texture distortion
|
||||
|
||||
seg_t *line = &segs[subsector->firstline];
|
||||
|
||||
for (i = 0; i < subsector->numlines; i++, line++)
|
||||
{
|
||||
if (!line->glseg && line->linedef->special == HORIZONSPECIAL && R_PointOnSegSide(dup_viewx, dup_viewy, line) == 0)
|
||||
{
|
||||
P_ClosestPointOnLine(viewx, viewy, line->linedef, &v);
|
||||
dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y));
|
||||
|
||||
x1 = ((polyvertex_t *)line->pv1)->x;
|
||||
y1 = ((polyvertex_t *)line->pv1)->y;
|
||||
xd = ((polyvertex_t *)line->pv2)->x - x1;
|
||||
yd = ((polyvertex_t *)line->pv2)->y - y1;
|
||||
|
||||
// Based on the seg length and the distance from the line, split horizon into multiple poly sets to reduce distortion
|
||||
dist = sqrtf((xd*xd) + (yd*yd)) / dist / 16.0f;
|
||||
if (dist > 100.0f)
|
||||
numplanes = 100;
|
||||
else
|
||||
numplanes = (UINT8)dist + 1;
|
||||
|
||||
for (j = 0; j < numplanes; j++)
|
||||
{
|
||||
// Left side
|
||||
vx = x1 + xd * j / numplanes;
|
||||
vy = y1 + yd * j / numplanes;
|
||||
SETUP3DVERT((&horizonpts[1]), vx, vy);
|
||||
|
||||
dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2));
|
||||
vx = (vx - gr_viewx) * renderdist / dist + gr_viewx;
|
||||
vy = (vy - gr_viewy) * renderdist / dist + gr_viewy;
|
||||
SETUP3DVERT((&horizonpts[0]), vx, vy);
|
||||
|
||||
// Right side
|
||||
vx = x1 + xd * (j+1) / numplanes;
|
||||
vy = y1 + yd * (j+1) / numplanes;
|
||||
SETUP3DVERT((&horizonpts[2]), vx, vy);
|
||||
|
||||
dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2));
|
||||
vx = (vx - gr_viewx) * renderdist / dist + gr_viewx;
|
||||
vy = (vy - gr_viewy) * renderdist / dist + gr_viewy;
|
||||
SETUP3DVERT((&horizonpts[3]), vx, vy);
|
||||
|
||||
// Horizon fills
|
||||
vx = (horizonpts[0].x - gr_viewx) * farrenderdist / renderdist + gr_viewx;
|
||||
vy = (horizonpts[0].z - gr_viewy) * farrenderdist / renderdist + gr_viewy;
|
||||
SETUP3DVERT((&horizonpts[5]), vx, vy);
|
||||
horizonpts[5].y = gr_viewz;
|
||||
|
||||
vx = (horizonpts[3].x - gr_viewx) * farrenderdist / renderdist + gr_viewx;
|
||||
vy = (horizonpts[3].z - gr_viewy) * farrenderdist / renderdist + gr_viewy;
|
||||
SETUP3DVERT((&horizonpts[4]), vx, vy);
|
||||
horizonpts[4].y = gr_viewz;
|
||||
|
||||
// Draw
|
||||
HWD.pfnDrawPolygon(&Surf, horizonpts, 6, PolyFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ALAM_LIGHTING
|
||||
// add here code for dynamic lighting on planes
|
||||
HWR_PlaneLighting(planeVerts, nrPlaneVerts);
|
||||
|
@ -3339,7 +3377,7 @@ static void HWR_Subsector(size_t num)
|
|||
if (sub->validcount != validcount)
|
||||
{
|
||||
HWR_GetLevelFlat(&levelflats[gr_frontsector->floorpic]);
|
||||
HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], false,
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], false,
|
||||
// Hack to make things continue to work around slopes.
|
||||
locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight,
|
||||
// We now return you to your regularly scheduled rendering.
|
||||
|
@ -3361,7 +3399,7 @@ static void HWR_Subsector(size_t num)
|
|||
if (sub->validcount != validcount)
|
||||
{
|
||||
HWR_GetLevelFlat(&levelflats[gr_frontsector->ceilingpic]);
|
||||
HWR_RenderPlane(NULL, &extrasubsectors[num], true,
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], true,
|
||||
// Hack to make things continue to work around slopes.
|
||||
locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight,
|
||||
// We now return you to your regularly scheduled rendering.
|
||||
|
@ -3453,7 +3491,7 @@ static void HWR_Subsector(size_t num)
|
|||
{
|
||||
HWR_GetLevelFlat(&levelflats[*rover->bottompic]);
|
||||
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
||||
HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
|
||||
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
}
|
||||
|
@ -3515,7 +3553,7 @@ static void HWR_Subsector(size_t num)
|
|||
{
|
||||
HWR_GetLevelFlat(&levelflats[*rover->toppic]);
|
||||
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
||||
HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
|
||||
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1478,7 +1478,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
|
|||
|
||||
// rotation pivot
|
||||
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
|
||||
p.centery = FIXED_TO_FLOAT(spr->mobj->height/2);
|
||||
p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2));
|
||||
|
||||
// rotation axis
|
||||
if (sprinfo->available)
|
||||
|
@ -1490,6 +1490,9 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
|
|||
p.rollflip = 1;
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
p.rollflip = -1;
|
||||
|
||||
if (flip)
|
||||
p.rollflip *= -1;
|
||||
}
|
||||
|
||||
p.anglex = 0.0f;
|
||||
|
|
|
@ -1423,6 +1423,7 @@ static void SOCK_ClearBans(void)
|
|||
boolean I_InitTcpNetwork(void)
|
||||
{
|
||||
char serverhostname[255];
|
||||
const char *urlparam = NULL;
|
||||
boolean ret = false;
|
||||
// initilize the OS's TCP/IP stack
|
||||
if (!I_InitTcpDriver())
|
||||
|
@ -1476,10 +1477,12 @@ boolean I_InitTcpNetwork(void)
|
|||
|
||||
ret = true;
|
||||
}
|
||||
else if (M_CheckParm("-connect"))
|
||||
else if ((urlparam = M_GetUrlProtocolArg()) != NULL || M_CheckParm("-connect"))
|
||||
{
|
||||
if (M_IsNextParm())
|
||||
strcpy(serverhostname, M_GetNextParm());
|
||||
if (urlparam != NULL)
|
||||
strlcpy(serverhostname, urlparam, sizeof(serverhostname));
|
||||
else if (M_IsNextParm())
|
||||
strlcpy(serverhostname, M_GetNextParm(), sizeof(serverhostname));
|
||||
else
|
||||
serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it
|
||||
|
||||
|
|
|
@ -175,6 +175,9 @@ static const struct {
|
|||
{META_SIDENUM, "line_t.sidenum"},
|
||||
{META_LINEARGS, "line_t.args"},
|
||||
{META_LINESTRINGARGS, "line_t.stringargs"},
|
||||
|
||||
{META_THINGARGS, "mapthing.args"},
|
||||
{META_THINGSTRINGARGS, "mapthing.stringargs"},
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
{META_NODEBBOX, "node_t.bbox"},
|
||||
{META_NODECHILDREN, "node_t.children"},
|
||||
|
|
|
@ -1631,7 +1631,6 @@ int LUA_InfoLib(lua_State *L)
|
|||
lua_pushcfunction(L, lib_spriteinfolen);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "spriteinfo");
|
||||
|
||||
luaL_newmetatable(L, META_LUABANKS);
|
||||
|
|
|
@ -54,6 +54,8 @@ extern lua_State *gL;
|
|||
#define META_SIDENUM "LINE_T*SIDENUM"
|
||||
#define META_LINEARGS "LINE_T*ARGS"
|
||||
#define META_LINESTRINGARGS "LINE_T*STRINGARGS"
|
||||
#define META_THINGARGS "MAPTHING_T*ARGS"
|
||||
#define META_THINGSTRINGARGS "MAPTHING_T*STRINGARGS"
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
#define META_NODEBBOX "NODE_T*BBOX"
|
||||
#define META_NODECHILDREN "NODE_T*CHILDREN"
|
||||
|
|
|
@ -31,6 +31,8 @@ enum mobj_e {
|
|||
mobj_snext,
|
||||
mobj_sprev,
|
||||
mobj_angle,
|
||||
mobj_pitch,
|
||||
mobj_roll,
|
||||
mobj_rollangle,
|
||||
mobj_sprite,
|
||||
mobj_frame,
|
||||
|
@ -97,6 +99,8 @@ static const char *const mobj_opt[] = {
|
|||
"snext",
|
||||
"sprev",
|
||||
"angle",
|
||||
"pitch",
|
||||
"roll",
|
||||
"rollangle",
|
||||
"sprite",
|
||||
"frame",
|
||||
|
@ -198,6 +202,12 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_angle:
|
||||
lua_pushangle(L, mo->angle);
|
||||
break;
|
||||
case mobj_pitch:
|
||||
lua_pushangle(L, mo->pitch);
|
||||
break;
|
||||
case mobj_roll:
|
||||
lua_pushangle(L, mo->roll);
|
||||
break;
|
||||
case mobj_rollangle:
|
||||
lua_pushangle(L, mo->rollangle);
|
||||
break;
|
||||
|
@ -454,6 +464,12 @@ static int mobj_set(lua_State *L)
|
|||
else if (mo->player == &players[secondarydisplayplayer])
|
||||
localangle2 = mo->angle;
|
||||
break;
|
||||
case mobj_pitch:
|
||||
mo->pitch = luaL_checkangle(L, 3);
|
||||
break;
|
||||
case mobj_roll:
|
||||
mo->roll = luaL_checkangle(L, 3);
|
||||
break;
|
||||
case mobj_rollangle:
|
||||
mo->rollangle = luaL_checkangle(L, 3);
|
||||
break;
|
||||
|
@ -746,6 +762,42 @@ static int mobj_set(lua_State *L)
|
|||
#undef NOSETPOS
|
||||
#undef NOFIELD
|
||||
|
||||
// args, i -> args[i]
|
||||
static int thingargs_get(lua_State *L)
|
||||
{
|
||||
INT32 *args = *((INT32**)luaL_checkudata(L, 1, META_THINGARGS));
|
||||
int i = luaL_checkinteger(L, 2);
|
||||
if (i < 0 || i >= NUMMAPTHINGARGS)
|
||||
return luaL_error(L, LUA_QL("mapthing_t.args") " index cannot be %d", i);
|
||||
lua_pushinteger(L, args[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// #args -> NUMMAPTHINGARGS
|
||||
static int thingargs_len(lua_State* L)
|
||||
{
|
||||
lua_pushinteger(L, NUMMAPTHINGARGS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// stringargs, i -> stringargs[i]
|
||||
static int thingstringargs_get(lua_State *L)
|
||||
{
|
||||
char **stringargs = *((char***)luaL_checkudata(L, 1, META_THINGSTRINGARGS));
|
||||
int i = luaL_checkinteger(L, 2);
|
||||
if (i < 0 || i >= NUMMAPTHINGSTRINGARGS)
|
||||
return luaL_error(L, LUA_QL("mapthing_t.stringargs") " index cannot be %d", i);
|
||||
lua_pushstring(L, stringargs[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// #stringargs -> NUMMAPTHINGSTRINGARGS
|
||||
static int thingstringargs_len(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, NUMMAPTHINGSTRINGARGS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mapthing_get(lua_State *L)
|
||||
{
|
||||
mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING));
|
||||
|
@ -771,16 +823,32 @@ static int mapthing_get(lua_State *L)
|
|||
number = mt->y;
|
||||
else if(fastcmp(field,"angle"))
|
||||
number = mt->angle;
|
||||
else if(fastcmp(field,"pitch"))
|
||||
number = mt->pitch;
|
||||
else if(fastcmp(field,"roll"))
|
||||
number = mt->roll;
|
||||
else if(fastcmp(field,"type"))
|
||||
number = mt->type;
|
||||
else if(fastcmp(field,"options"))
|
||||
number = mt->options;
|
||||
else if(fastcmp(field,"scale"))
|
||||
number = mt->scale;
|
||||
else if(fastcmp(field,"z"))
|
||||
number = mt->z;
|
||||
else if(fastcmp(field,"extrainfo"))
|
||||
number = mt->extrainfo;
|
||||
else if(fastcmp(field,"tag"))
|
||||
number = mt->tag;
|
||||
else if(fastcmp(field,"args"))
|
||||
{
|
||||
LUA_PushUserdata(L, mt->args, META_THINGARGS);
|
||||
return 1;
|
||||
}
|
||||
else if(fastcmp(field,"stringargs"))
|
||||
{
|
||||
LUA_PushUserdata(L, mt->stringargs, META_THINGSTRINGARGS);
|
||||
return 1;
|
||||
}
|
||||
else if(fastcmp(field,"mobj")) {
|
||||
LUA_PushUserdata(L, mt->mobj, META_MOBJ);
|
||||
return 1;
|
||||
|
@ -810,10 +878,16 @@ static int mapthing_set(lua_State *L)
|
|||
mt->y = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"angle"))
|
||||
mt->angle = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"pitch"))
|
||||
mt->pitch = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"roll"))
|
||||
mt->roll = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"type"))
|
||||
mt->type = (UINT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"options"))
|
||||
mt->options = (UINT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"scale"))
|
||||
mt->scale = luaL_checkfixed(L, 3);
|
||||
else if(fastcmp(field,"z"))
|
||||
mt->z = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"extrainfo"))
|
||||
|
@ -891,6 +965,22 @@ int LUA_MobjLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L,1);
|
||||
|
||||
luaL_newmetatable(L, META_THINGARGS);
|
||||
lua_pushcfunction(L, thingargs_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, thingargs_len);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_THINGSTRINGARGS);
|
||||
lua_pushcfunction(L, thingstringargs_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, thingstringargs_len);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_MAPTHING);
|
||||
lua_pushcfunction(L, mapthing_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
|
|
@ -444,9 +444,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
|
|||
else // If it's not a .lua file, copy the lump name in too.
|
||||
{
|
||||
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
|
||||
len += 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
||||
len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
|
||||
name = malloc(len+1);
|
||||
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->name2);
|
||||
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
|
||||
name[len] = '\0';
|
||||
}
|
||||
|
||||
|
|
19
src/m_argv.c
19
src/m_argv.c
|
@ -34,6 +34,25 @@ boolean myargmalloc = false;
|
|||
*/
|
||||
static INT32 found;
|
||||
|
||||
/** \brief Parses a server URL (such as srb2://127.0.0.1) as may be passed to the game via a web browser, etc.
|
||||
|
||||
\return the contents of the URL after the protocol (a server to join), or NULL if not found
|
||||
*/
|
||||
const char *M_GetUrlProtocolArg(void)
|
||||
{
|
||||
INT32 i;
|
||||
const size_t len = strlen(SERVER_URL_PROTOCOL);
|
||||
|
||||
for (i = 1; i < myargc; i++)
|
||||
{
|
||||
if (strlen(myargv[i]) > len && !strnicmp(myargv[i], SERVER_URL_PROTOCOL, len))
|
||||
{
|
||||
return &myargv[i][len];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief The M_CheckParm function
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@ extern INT32 myargc;
|
|||
extern char **myargv;
|
||||
extern boolean myargmalloc;
|
||||
|
||||
// Looks for an srb2:// (or similar) URL passed in as an argument and returns the IP to connect to if found.
|
||||
const char *M_GetUrlProtocolArg(void);
|
||||
|
||||
// Returns the position of the given parameter in the arg list (0 if not found).
|
||||
INT32 M_CheckParm(const char *check);
|
||||
|
||||
|
|
|
@ -934,6 +934,12 @@ void Command_Setcontinues_f(void)
|
|||
REQUIRE_NOULTIMATE;
|
||||
REQUIRE_PANDORA;
|
||||
|
||||
if (!continuesInSession)
|
||||
{
|
||||
CONS_Printf(M_GetText("This session does not use continues.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (COM_Argc() > 1)
|
||||
{
|
||||
INT32 numcontinues = atoi(COM_Argv(1));
|
||||
|
|
84
src/m_menu.c
84
src/m_menu.c
|
@ -6728,6 +6728,7 @@ static void M_PandorasBox(INT32 choice)
|
|||
else
|
||||
CV_StealthSetValue(&cv_dummylives, max(players[consoleplayer].lives, 1));
|
||||
CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues);
|
||||
SR_PandorasBox[3].status = (continuesInSession) ? (IT_STRING | IT_CVAR) : (IT_GRAYEDOUT);
|
||||
SR_PandorasBox[6].status = (players[consoleplayer].charflags & SF_SUPER) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL);
|
||||
SR_PandorasBox[7].status = (emeralds == ((EMERALD7)*2)-1) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL);
|
||||
M_SetupNextMenu(&SR_PandoraDef);
|
||||
|
@ -6744,7 +6745,7 @@ static boolean M_ExitPandorasBox(void)
|
|||
}
|
||||
if (cv_dummylives.value != players[consoleplayer].lives)
|
||||
COM_ImmedExecute(va("setlives %d", cv_dummylives.value));
|
||||
if (cv_dummycontinues.value != players[consoleplayer].continues)
|
||||
if (continuesInSession && cv_dummycontinues.value != players[consoleplayer].continues)
|
||||
COM_ImmedExecute(va("setcontinues %d", cv_dummycontinues.value));
|
||||
return true;
|
||||
}
|
||||
|
@ -8264,9 +8265,19 @@ static void M_DrawLoadGameData(void)
|
|||
V_DrawRightAlignedThinString(x + 79, y, V_YELLOWMAP, savegameinfo[savetodraw].levelname);
|
||||
}
|
||||
|
||||
if ((savegameinfo[savetodraw].lives == -42)
|
||||
|| (savegameinfo[savetodraw].lives == -666))
|
||||
if (savegameinfo[savetodraw].lives == -42)
|
||||
{
|
||||
if (!useContinues)
|
||||
V_DrawRightAlignedThinString(x + 80, y+1+60+16, V_GRAYMAP, "00000000");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (savegameinfo[savetodraw].lives == -666)
|
||||
{
|
||||
if (!useContinues)
|
||||
V_DrawRightAlignedThinString(x + 80, y+1+60+16, V_REDMAP, "????????");
|
||||
continue;
|
||||
}
|
||||
|
||||
y += 64;
|
||||
|
||||
|
@ -8283,7 +8294,7 @@ static void M_DrawLoadGameData(void)
|
|||
|
||||
y -= 4;
|
||||
|
||||
// character heads, lives, and continues
|
||||
// character heads, lives, and continues/score
|
||||
{
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
|
@ -8334,10 +8345,14 @@ skipbot:
|
|||
skipsign:
|
||||
y += 16;
|
||||
|
||||
tempx = x + 10;
|
||||
if (savegameinfo[savetodraw].lives != INFLIVES
|
||||
&& savegameinfo[savetodraw].lives > 9)
|
||||
tempx -= 4;
|
||||
tempx = x;
|
||||
if (useContinues)
|
||||
{
|
||||
tempx += 10;
|
||||
if (savegameinfo[savetodraw].lives != INFLIVES
|
||||
&& savegameinfo[savetodraw].lives > 9)
|
||||
tempx -= 4;
|
||||
}
|
||||
|
||||
if (!charskin) // shut up compiler
|
||||
goto skiplife;
|
||||
|
@ -8367,22 +8382,45 @@ skiplife:
|
|||
else
|
||||
V_DrawString(tempx, y, 0, va("%d", savegameinfo[savetodraw].lives));
|
||||
|
||||
tempx = x + 47;
|
||||
if (savegameinfo[savetodraw].continues > 9)
|
||||
tempx -= 4;
|
||||
|
||||
// continues
|
||||
if (savegameinfo[savetodraw].continues > 0)
|
||||
if (!useContinues)
|
||||
{
|
||||
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_PATCH));
|
||||
V_DrawScaledPatch(tempx + 9, y + 2, 0, patch);
|
||||
V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continues));
|
||||
INT32 workingscorenum = savegameinfo[savetodraw].continuescore;
|
||||
char workingscorestr[11] = " 000000000\0";
|
||||
SINT8 j = 9;
|
||||
// Change the above two lines if MAXSCORE ever changes from 8 digits long.
|
||||
workingscorestr[0] = '\x86'; // done here instead of in initialiser 'cuz compiler complains
|
||||
if (!workingscorenum)
|
||||
j--; // just so ONE digit is not greyed out
|
||||
else
|
||||
{
|
||||
while (workingscorenum)
|
||||
{
|
||||
workingscorestr[j--] = '0' + (workingscorenum % 10);
|
||||
workingscorenum /= 10;
|
||||
}
|
||||
}
|
||||
workingscorestr[j] = (savegameinfo[savetodraw].continuescore == MAXSCORE) ? '\x83' : '\x80';
|
||||
V_DrawRightAlignedThinString(x + 80, y+1, 0, workingscorestr);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_PATCH));
|
||||
V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_PATCH));
|
||||
V_DrawString(tempx + 16, y, V_GRAYMAP, "0");
|
||||
tempx = x + 47;
|
||||
if (savegameinfo[savetodraw].continuescore > 9)
|
||||
tempx -= 4;
|
||||
|
||||
// continues
|
||||
if (savegameinfo[savetodraw].continuescore > 0)
|
||||
{
|
||||
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_PATCH));
|
||||
V_DrawScaledPatch(tempx + 9, y + 2, 0, patch);
|
||||
V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continuescore));
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_PATCH));
|
||||
V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_PATCH));
|
||||
V_DrawString(tempx + 16, y, V_GRAYMAP, "0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8515,9 +8553,11 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
|||
CHECKPOS
|
||||
savegameinfo[slot].lives = READSINT8(save_p); // lives
|
||||
CHECKPOS
|
||||
(void)READINT32(save_p); // Score
|
||||
savegameinfo[slot].continuescore = READINT32(save_p); // score
|
||||
CHECKPOS
|
||||
savegameinfo[slot].continues = READINT32(save_p); // continues
|
||||
fake = READINT32(save_p); // continues
|
||||
if (useContinues)
|
||||
savegameinfo[slot].continuescore = fake;
|
||||
|
||||
// File end marker check
|
||||
CHECKPOS
|
||||
|
|
|
@ -397,7 +397,7 @@ typedef struct
|
|||
UINT8 numemeralds;
|
||||
UINT8 numgameovers;
|
||||
INT32 lives;
|
||||
INT32 continues;
|
||||
INT32 continuescore;
|
||||
INT32 gamemap;
|
||||
} saveinfo_t;
|
||||
|
||||
|
|
|
@ -47,8 +47,7 @@ void T_MoveCeiling(ceiling_t *ceiling)
|
|||
case 0: // IN STASIS
|
||||
break;
|
||||
case 1: // UP
|
||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false,
|
||||
1, ceiling->direction);
|
||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
|
||||
|
||||
if (ceiling->type == bounceCeiling)
|
||||
{
|
||||
|
@ -159,8 +158,7 @@ void T_MoveCeiling(ceiling_t *ceiling)
|
|||
break;
|
||||
|
||||
case -1: // DOWN
|
||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight,
|
||||
ceiling->crush, 1, ceiling->direction);
|
||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
|
||||
|
||||
if (ceiling->type == bounceCeiling)
|
||||
{
|
||||
|
@ -314,11 +312,10 @@ void T_CrushCeiling(ceiling_t *ceiling)
|
|||
if (ceiling->type == crushBothOnce)
|
||||
{
|
||||
// Move the floor
|
||||
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, 0, -ceiling->direction);
|
||||
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, false, -ceiling->direction);
|
||||
}
|
||||
|
||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight,
|
||||
false, 1, ceiling->direction);
|
||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
|
||||
|
||||
if (res == pastdest)
|
||||
{
|
||||
|
@ -357,11 +354,10 @@ void T_CrushCeiling(ceiling_t *ceiling)
|
|||
if (ceiling->type == crushBothOnce)
|
||||
{
|
||||
// Move the floor
|
||||
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, 0, -ceiling->direction);
|
||||
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, false, -ceiling->direction);
|
||||
}
|
||||
|
||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight,
|
||||
ceiling->crush, 1, ceiling->direction);
|
||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
|
||||
|
||||
if (res == pastdest)
|
||||
{
|
||||
|
|
941
src/p_floor.c
941
src/p_floor.c
File diff suppressed because it is too large
Load diff
|
@ -633,7 +633,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
if (ALL7EMERALDS(emeralds)) // Got all 7
|
||||
{
|
||||
if (!(netgame || multiplayer))
|
||||
if (continuesInSession)
|
||||
{
|
||||
player->continues += 1;
|
||||
player->gotcontinue = true;
|
||||
|
@ -643,7 +643,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
S_StartSound(toucher, sfx_chchng);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_GiveCoopLives(player, 1, true); // if continues are disabled, a life is a reasonable substitute
|
||||
S_StartSound(toucher, sfx_chchng);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
25
src/p_mobj.c
25
src/p_mobj.c
|
@ -1691,7 +1691,7 @@ static void P_PushableCheckBustables(mobj_t *mo)
|
|||
// Bustable by pushables?
|
||||
if (!(rover->master->args[3] & TMFB_PUSHABLES)) continue;
|
||||
|
||||
if (!rover->master->frontsector->crumblestate)
|
||||
if (rover->master->frontsector->crumblestate == CRUMBLE_NONE)
|
||||
{
|
||||
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);
|
||||
|
@ -11616,7 +11616,7 @@ void P_MovePlayerToStarpost(INT32 playernum)
|
|||
mapthing_t *huntemeralds[MAXHUNTEMERALDS];
|
||||
INT32 numhuntemeralds;
|
||||
|
||||
static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip)
|
||||
fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip, const fixed_t scale)
|
||||
{
|
||||
const subsector_t *ss = R_PointInSubsector(x, y);
|
||||
|
||||
|
@ -11627,13 +11627,13 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x,
|
|||
// Establish height.
|
||||
if (flip)
|
||||
return (ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : ss->sector->ceilingheight)
|
||||
- offset - mobjinfo[mobjtype].height;
|
||||
- FixedMul(scale, offset + mobjinfo[mobjtype].height);
|
||||
else
|
||||
return (ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : ss->sector->floorheight)
|
||||
+ offset;
|
||||
+ FixedMul(scale, offset);
|
||||
}
|
||||
|
||||
static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y)
|
||||
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y)
|
||||
{
|
||||
fixed_t offset = mthing->z << FRACBITS;
|
||||
boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP));
|
||||
|
@ -11673,6 +11673,7 @@ static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthin
|
|||
|
||||
// Ring-like items, may float additional units with MTF_AMBUSH.
|
||||
case MT_SPIKEBALL:
|
||||
case MT_EMERHUNT:
|
||||
case MT_EMERALDSPAWN:
|
||||
case MT_TOKEN:
|
||||
case MT_EMBLEM:
|
||||
|
@ -11701,7 +11702,7 @@ static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthin
|
|||
return ONFLOORZ;
|
||||
}
|
||||
|
||||
return P_GetMobjSpawnHeight(mobjtype, x, y, offset, flip);
|
||||
return P_GetMobjSpawnHeight(mobjtype, x, y, offset, flip, mthing->scale);
|
||||
}
|
||||
|
||||
static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
|
||||
|
@ -13077,12 +13078,18 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
|
|||
mobj = P_SpawnMobj(x, y, z, i);
|
||||
mobj->spawnpoint = mthing;
|
||||
|
||||
P_SetScale(mobj, mthing->scale);
|
||||
mobj->destscale = mthing->scale;
|
||||
|
||||
if (!P_SetupSpawnedMapThing(mthing, mobj, &doangle))
|
||||
return mobj;
|
||||
|
||||
if (doangle)
|
||||
mobj->angle = FixedAngle(mthing->angle << FRACBITS);
|
||||
|
||||
mobj->pitch = FixedAngle(mthing->pitch << FRACBITS);
|
||||
mobj->roll = FixedAngle(mthing->roll << FRACBITS);
|
||||
|
||||
mthing->mobj = mobj;
|
||||
|
||||
// ignore MTF_ flags and return early
|
||||
|
@ -13179,7 +13186,7 @@ static void P_SpawnHoopInternal(mapthing_t *mthing, INT32 hoopsize, fixed_t size
|
|||
TVector v, *res;
|
||||
fixed_t x = mthing->x << FRACBITS;
|
||||
fixed_t y = mthing->y << FRACBITS;
|
||||
fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, false);
|
||||
fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, false, mthing->scale);
|
||||
|
||||
hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER);
|
||||
hoopcenter->spawnpoint = mthing;
|
||||
|
@ -13324,7 +13331,7 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numi
|
|||
itemtypes[r] = P_GetMobjtypeSubstitute(&dummything, itemtypes[r]);
|
||||
}
|
||||
}
|
||||
z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, mthing->options & MTF_OBJECTFLIP);
|
||||
z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, mthing->options & MTF_OBJECTFLIP, mthing->scale);
|
||||
|
||||
for (r = 0; r < numitems; r++)
|
||||
{
|
||||
|
@ -13382,7 +13389,7 @@ static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 n
|
|||
itemtypes[i] = P_GetMobjtypeSubstitute(&dummything, itemtypes[i]);
|
||||
}
|
||||
}
|
||||
z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, false);
|
||||
z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, false, mthing->scale);
|
||||
|
||||
for (i = 0; i < numitems; i++)
|
||||
{
|
||||
|
|
|
@ -278,7 +278,7 @@ typedef struct mobj_s
|
|||
struct mobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr
|
||||
|
||||
// More drawing info: to determine current sprite.
|
||||
angle_t angle; // orientation
|
||||
angle_t angle, pitch, roll; // orientation
|
||||
angle_t rollangle;
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
|
@ -398,7 +398,7 @@ typedef struct precipmobj_s
|
|||
struct precipmobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr
|
||||
|
||||
// More drawing info: to determine current sprite.
|
||||
angle_t angle; // orientation
|
||||
angle_t angle, pitch, roll; // orientation
|
||||
angle_t rollangle;
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
|
@ -451,6 +451,9 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing);
|
|||
void P_MovePlayerToStarpost(INT32 playernum);
|
||||
void P_AfterPlayerSpawn(INT32 playernum);
|
||||
|
||||
fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip, const fixed_t scale);
|
||||
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y);
|
||||
|
||||
mobj_t *P_SpawnMapThing(mapthing_t *mthing);
|
||||
void P_SpawnHoop(mapthing_t *mthing);
|
||||
void P_SetBonusTime(mobj_t *mobj);
|
||||
|
|
288
src/p_saveg.c
288
src/p_saveg.c
|
@ -755,6 +755,7 @@ static void P_NetUnArchiveColormaps(void)
|
|||
// diff3 flags
|
||||
#define SD_TAGLIST 0x01
|
||||
#define SD_COLORMAP 0x02
|
||||
#define SD_CRUMBLESTATE 0x04
|
||||
|
||||
#define LD_FLAG 0x01
|
||||
#define LD_SPECIAL 0x02
|
||||
|
@ -861,6 +862,8 @@ static void P_NetArchiveWorld(void)
|
|||
|
||||
if (ss->extra_colormap != spawnss->extra_colormap)
|
||||
diff3 |= SD_COLORMAP;
|
||||
if (ss->crumblestate)
|
||||
diff3 |= SD_CRUMBLESTATE;
|
||||
|
||||
// Check if any of the sector's FOFs differ from how they spawned
|
||||
if (ss->ffloors)
|
||||
|
@ -928,6 +931,8 @@ static void P_NetArchiveWorld(void)
|
|||
if (diff3 & SD_COLORMAP)
|
||||
WRITEUINT32(put, CheckAddNetColormapToList(ss->extra_colormap));
|
||||
// returns existing index if already added, or appends to net_colormaps and returns new index
|
||||
if (diff3 & SD_CRUMBLESTATE)
|
||||
WRITEINT32(put, ss->crumblestate);
|
||||
|
||||
// Special case: save the stats of all modified ffloors along with their ffloor "number"s
|
||||
// we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed
|
||||
|
@ -1164,6 +1169,8 @@ static void P_NetUnArchiveWorld(void)
|
|||
|
||||
if (diff3 & SD_COLORMAP)
|
||||
sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get));
|
||||
if (diff3 & SD_CRUMBLESTATE)
|
||||
sectors[i].crumblestate = READINT32(get);
|
||||
|
||||
if (diff & SD_FFLOORS)
|
||||
{
|
||||
|
@ -1359,7 +1366,6 @@ typedef enum
|
|||
tc_startcrumble,
|
||||
tc_marioblock,
|
||||
tc_marioblockchecker,
|
||||
tc_spikesector,
|
||||
tc_floatsector,
|
||||
tc_crushceiling,
|
||||
tc_scroll,
|
||||
|
@ -1451,7 +1457,9 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
|
||||
if ((mobj->x != mobj->spawnpoint->x << FRACBITS) ||
|
||||
(mobj->y != mobj->spawnpoint->y << FRACBITS) ||
|
||||
(mobj->angle != FixedAngle(mobj->spawnpoint->angle*FRACUNIT)))
|
||||
(mobj->angle != FixedAngle(mobj->spawnpoint->angle*FRACUNIT)) ||
|
||||
(mobj->pitch != FixedAngle(mobj->spawnpoint->pitch*FRACUNIT)) ||
|
||||
(mobj->roll != FixedAngle(mobj->spawnpoint->roll*FRACUNIT)) )
|
||||
diff |= MD_POS;
|
||||
|
||||
if (mobj->info->doomednum != mobj->spawnpoint->type)
|
||||
|
@ -1633,6 +1641,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEFIXED(save_p, mobj->x);
|
||||
WRITEFIXED(save_p, mobj->y);
|
||||
WRITEANGLE(save_p, mobj->angle);
|
||||
WRITEANGLE(save_p, mobj->pitch);
|
||||
WRITEANGLE(save_p, mobj->roll);
|
||||
}
|
||||
if (diff & MD_MOM)
|
||||
{
|
||||
|
@ -1727,20 +1737,78 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
}
|
||||
|
||||
//
|
||||
// SaveSpecialLevelThinker
|
||||
// SaveNoEnemiesThinker
|
||||
//
|
||||
// Saves a levelspecthink_t thinker
|
||||
// Saves a noenemies_t thinker
|
||||
//
|
||||
static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
|
||||
static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type)
|
||||
{
|
||||
const levelspecthink_t *ht = (const void *)th;
|
||||
size_t i;
|
||||
const noenemies_t *ht = (const void *)th;
|
||||
WRITEUINT8(save_p, type);
|
||||
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||
}
|
||||
|
||||
//
|
||||
// SaveBounceCheeseThinker
|
||||
//
|
||||
// Saves a bouncecheese_t thinker
|
||||
//
|
||||
static void SaveBounceCheeseThinker(const thinker_t *th, const UINT8 type)
|
||||
{
|
||||
const bouncecheese_t *ht = (const void *)th;
|
||||
WRITEUINT8(save_p, type);
|
||||
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||
WRITEFIXED(save_p, ht->speed);
|
||||
WRITEFIXED(save_p, ht->distance);
|
||||
WRITEFIXED(save_p, ht->floorwasheight);
|
||||
WRITEFIXED(save_p, ht->ceilingwasheight);
|
||||
WRITECHAR(save_p, ht->low);
|
||||
}
|
||||
|
||||
//
|
||||
// SaveContinuousFallThinker
|
||||
//
|
||||
// Saves a continuousfall_t thinker
|
||||
//
|
||||
static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type)
|
||||
{
|
||||
const continuousfall_t *ht = (const void *)th;
|
||||
WRITEUINT8(save_p, type);
|
||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||
WRITEFIXED(save_p, ht->speed);
|
||||
WRITEINT32(save_p, ht->direction);
|
||||
WRITEFIXED(save_p, ht->floorstartheight);
|
||||
WRITEFIXED(save_p, ht->ceilingstartheight);
|
||||
WRITEFIXED(save_p, ht->destheight);
|
||||
}
|
||||
|
||||
//
|
||||
// SaveMarioBlockThinker
|
||||
//
|
||||
// Saves a mariothink_t thinker
|
||||
//
|
||||
static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type)
|
||||
{
|
||||
const mariothink_t *ht = (const void *)th;
|
||||
WRITEUINT8(save_p, type);
|
||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||
WRITEFIXED(save_p, ht->speed);
|
||||
WRITEINT32(save_p, ht->direction);
|
||||
WRITEFIXED(save_p, ht->floorstartheight);
|
||||
WRITEFIXED(save_p, ht->ceilingstartheight);
|
||||
WRITEINT16(save_p, ht->tag);
|
||||
}
|
||||
|
||||
//
|
||||
// SaveMarioCheckThinker
|
||||
//
|
||||
// Saves a mariocheck_t thinker
|
||||
//
|
||||
static void SaveMarioCheckThinker(const thinker_t *th, const UINT8 type)
|
||||
{
|
||||
const mariocheck_t *ht = (const void *)th;
|
||||
WRITEUINT8(save_p, type);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
WRITEFIXED(save_p, ht->vars[i]); //var[16]
|
||||
WRITEFIXED(save_p, ht->var2s[i]); //var[16]
|
||||
}
|
||||
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||
}
|
||||
|
@ -1766,6 +1834,38 @@ static void SaveThwompThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEUINT16(save_p, ht->sound);
|
||||
}
|
||||
|
||||
//
|
||||
// SaveFloatThinker
|
||||
//
|
||||
// Saves a floatthink_t thinker
|
||||
//
|
||||
static void SaveFloatThinker(const thinker_t *th, const UINT8 type)
|
||||
{
|
||||
const floatthink_t *ht = (const void *)th;
|
||||
WRITEUINT8(save_p, type);
|
||||
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||
WRITEINT16(save_p, ht->tag);
|
||||
}
|
||||
|
||||
// SaveEachTimeThinker
|
||||
//
|
||||
// Loads a eachtime_t from a save game
|
||||
//
|
||||
static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type)
|
||||
{
|
||||
const eachtime_t *ht = (const void *)th;
|
||||
size_t i;
|
||||
WRITEUINT8(save_p, type);
|
||||
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
WRITECHAR(save_p, ht->playersInArea[i]);
|
||||
WRITECHAR(save_p, ht->playersOnArea[i]);
|
||||
}
|
||||
WRITECHAR(save_p, ht->triggerOnExit);
|
||||
}
|
||||
|
||||
// SaveRaiseThinker
|
||||
//
|
||||
// Saves a raise_t thinker
|
||||
|
@ -2342,7 +2442,7 @@ static void P_NetArchiveThinkers(void)
|
|||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_ContinuousFalling)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_continuousfalling);
|
||||
SaveContinuousFallThinker(th, tc_continuousfalling);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_ThwompSector)
|
||||
|
@ -2352,12 +2452,12 @@ static void P_NetArchiveThinkers(void)
|
|||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_NoEnemiesSector)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_noenemies);
|
||||
SaveNoEnemiesThinker(th, tc_noenemies);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_EachTimeThinker)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_eachtime);
|
||||
SaveEachTimeThinker(th, tc_eachtime);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_RaiseSector)
|
||||
|
@ -2387,7 +2487,7 @@ static void P_NetArchiveThinkers(void)
|
|||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_BounceCheese)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_bouncecheese);
|
||||
SaveBounceCheeseThinker(th, tc_bouncecheese);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_StartCrumble)
|
||||
|
@ -2397,22 +2497,17 @@ static void P_NetArchiveThinkers(void)
|
|||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_MarioBlock)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_marioblock);
|
||||
SaveMarioBlockThinker(th, tc_marioblock);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_marioblockchecker);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_spikesector);
|
||||
SaveMarioCheckThinker(th, tc_marioblockchecker);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_FloatSector)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_floatsector);
|
||||
SaveFloatThinker(th, tc_floatsector);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_LaserFlash)
|
||||
|
@ -2688,12 +2783,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
mobj->x = READFIXED(save_p);
|
||||
mobj->y = READFIXED(save_p);
|
||||
mobj->angle = READANGLE(save_p);
|
||||
mobj->pitch = READANGLE(save_p);
|
||||
mobj->roll = READANGLE(save_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->x = mobj->spawnpoint->x << FRACBITS;
|
||||
mobj->y = mobj->spawnpoint->y << FRACBITS;
|
||||
mobj->angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT);
|
||||
mobj->pitch = FixedAngle(mobj->spawnpoint->pitch*FRACUNIT);
|
||||
mobj->roll = FixedAngle(mobj->spawnpoint->roll*FRACUNIT);
|
||||
}
|
||||
if (diff & MD_MOM)
|
||||
{
|
||||
|
@ -2860,38 +2959,80 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
return &mobj->thinker;
|
||||
}
|
||||
|
||||
// LoadNoEnemiesThinker
|
||||
//
|
||||
// LoadSpecialLevelThinker
|
||||
// Loads a noenemies_t from a save game
|
||||
//
|
||||
// Loads a levelspecthink_t from a save game
|
||||
//
|
||||
// floorOrCeiling:
|
||||
// 0 - Don't set
|
||||
// 1 - Floor Only
|
||||
// 2 - Ceiling Only
|
||||
// 3 - Both
|
||||
//
|
||||
static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling)
|
||||
static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker)
|
||||
{
|
||||
levelspecthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
size_t i;
|
||||
noenemies_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||
return &ht->thinker;
|
||||
}
|
||||
|
||||
// LoadBounceCheeseThinker
|
||||
//
|
||||
// Loads a bouncecheese_t from a save game
|
||||
//
|
||||
static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker)
|
||||
{
|
||||
bouncecheese_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
ht->vars[i] = READFIXED(save_p); //var[16]
|
||||
ht->var2s[i] = READFIXED(save_p); //var[16]
|
||||
}
|
||||
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||
ht->sector = LoadSector(READUINT32(save_p));
|
||||
ht->speed = READFIXED(save_p);
|
||||
ht->distance = READFIXED(save_p);
|
||||
ht->floorwasheight = READFIXED(save_p);
|
||||
ht->ceilingwasheight = READFIXED(save_p);
|
||||
ht->low = READCHAR(save_p);
|
||||
return &ht->thinker;
|
||||
}
|
||||
|
||||
if (ht->sector)
|
||||
{
|
||||
if (floorOrCeiling & 2)
|
||||
ht->sector->ceilingdata = ht;
|
||||
if (floorOrCeiling & 1)
|
||||
ht->sector->floordata = ht;
|
||||
}
|
||||
// LoadContinuousFallThinker
|
||||
//
|
||||
// Loads a continuousfall_t from a save game
|
||||
//
|
||||
static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker)
|
||||
{
|
||||
continuousfall_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
ht->sector = LoadSector(READUINT32(save_p));
|
||||
ht->speed = READFIXED(save_p);
|
||||
ht->direction = READINT32(save_p);
|
||||
ht->floorstartheight = READFIXED(save_p);
|
||||
ht->ceilingstartheight = READFIXED(save_p);
|
||||
ht->destheight = READFIXED(save_p);
|
||||
return &ht->thinker;
|
||||
}
|
||||
|
||||
// LoadMarioBlockThinker
|
||||
//
|
||||
// Loads a mariothink_t from a save game
|
||||
//
|
||||
static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker)
|
||||
{
|
||||
mariothink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
ht->sector = LoadSector(READUINT32(save_p));
|
||||
ht->speed = READFIXED(save_p);
|
||||
ht->direction = READINT32(save_p);
|
||||
ht->floorstartheight = READFIXED(save_p);
|
||||
ht->ceilingstartheight = READFIXED(save_p);
|
||||
ht->tag = READINT16(save_p);
|
||||
return &ht->thinker;
|
||||
}
|
||||
|
||||
// LoadMarioCheckThinker
|
||||
//
|
||||
// Loads a mariocheck_t from a save game
|
||||
//
|
||||
static thinker_t* LoadMarioCheckThinker(actionf_p1 thinker)
|
||||
{
|
||||
mariocheck_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||
ht->sector = LoadSector(READUINT32(save_p));
|
||||
return &ht->thinker;
|
||||
}
|
||||
|
||||
|
@ -2916,6 +3057,39 @@ static thinker_t* LoadThwompThinker(actionf_p1 thinker)
|
|||
return &ht->thinker;
|
||||
}
|
||||
|
||||
// LoadFloatThinker
|
||||
//
|
||||
// Loads a floatthink_t from a save game
|
||||
//
|
||||
static thinker_t* LoadFloatThinker(actionf_p1 thinker)
|
||||
{
|
||||
floatthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||
ht->sector = LoadSector(READUINT32(save_p));
|
||||
ht->tag = READINT16(save_p);
|
||||
return &ht->thinker;
|
||||
}
|
||||
|
||||
// LoadEachTimeThinker
|
||||
//
|
||||
// Loads a eachtime_t from a save game
|
||||
//
|
||||
static thinker_t* LoadEachTimeThinker(actionf_p1 thinker)
|
||||
{
|
||||
size_t i;
|
||||
eachtime_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
ht->playersInArea[i] = READCHAR(save_p);
|
||||
ht->playersOnArea[i] = READCHAR(save_p);
|
||||
}
|
||||
ht->triggerOnExit = READCHAR(save_p);
|
||||
return &ht->thinker;
|
||||
}
|
||||
|
||||
// LoadRaiseThinker
|
||||
//
|
||||
// Loads a raise_t from a save game
|
||||
|
@ -3597,7 +3771,7 @@ static void P_NetUnArchiveThinkers(void)
|
|||
break;
|
||||
|
||||
case tc_continuousfalling:
|
||||
th = LoadSpecialLevelThinker((actionf_p1)T_ContinuousFalling, 3);
|
||||
th = LoadContinuousFallThinker((actionf_p1)T_ContinuousFalling);
|
||||
break;
|
||||
|
||||
case tc_thwomp:
|
||||
|
@ -3605,11 +3779,11 @@ static void P_NetUnArchiveThinkers(void)
|
|||
break;
|
||||
|
||||
case tc_noenemies:
|
||||
th = LoadSpecialLevelThinker((actionf_p1)T_NoEnemiesSector, 0);
|
||||
th = LoadNoEnemiesThinker((actionf_p1)T_NoEnemiesSector);
|
||||
break;
|
||||
|
||||
case tc_eachtime:
|
||||
th = LoadSpecialLevelThinker((actionf_p1)T_EachTimeThinker, 0);
|
||||
th = LoadEachTimeThinker((actionf_p1)T_EachTimeThinker);
|
||||
break;
|
||||
|
||||
case tc_raisesector:
|
||||
|
@ -3623,7 +3797,7 @@ static void P_NetUnArchiveThinkers(void)
|
|||
break;
|
||||
|
||||
case tc_bouncecheese:
|
||||
th = LoadSpecialLevelThinker((actionf_p1)T_BounceCheese, 2);
|
||||
th = LoadBounceCheeseThinker((actionf_p1)T_BounceCheese);
|
||||
break;
|
||||
|
||||
case tc_startcrumble:
|
||||
|
@ -3631,19 +3805,15 @@ static void P_NetUnArchiveThinkers(void)
|
|||
break;
|
||||
|
||||
case tc_marioblock:
|
||||
th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3);
|
||||
th = LoadMarioBlockThinker((actionf_p1)T_MarioBlock);
|
||||
break;
|
||||
|
||||
case tc_marioblockchecker:
|
||||
th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0);
|
||||
break;
|
||||
|
||||
case tc_spikesector:
|
||||
th = LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0);
|
||||
th = LoadMarioCheckThinker((actionf_p1)T_MarioBlockChecker);
|
||||
break;
|
||||
|
||||
case tc_floatsector:
|
||||
th = LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0);
|
||||
th = LoadFloatThinker((actionf_p1)T_FloatSector);
|
||||
break;
|
||||
|
||||
case tc_laserflash:
|
||||
|
|
|
@ -694,47 +694,27 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
|
|||
|
||||
static void P_SpawnEmeraldHunt(void)
|
||||
{
|
||||
INT32 emer1, emer2, emer3;
|
||||
INT32 timeout = 0; // keeps from getting stuck
|
||||
INT32 emer[3], num[MAXHUNTEMERALDS], i, randomkey;
|
||||
fixed_t x, y, z;
|
||||
|
||||
emer1 = emer2 = emer3 = 0;
|
||||
for (i = 0; i < numhuntemeralds; i++)
|
||||
num[i] = i;
|
||||
|
||||
//increment spawn numbers because zero is valid.
|
||||
emer1 = (P_RandomKey(numhuntemeralds)) + 1;
|
||||
while (timeout++ < 100)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
emer2 = (P_RandomKey(numhuntemeralds)) + 1;
|
||||
// generate random index, shuffle afterwards
|
||||
randomkey = P_RandomKey(numhuntemeralds--);
|
||||
emer[i] = num[randomkey];
|
||||
num[randomkey] = num[numhuntemeralds];
|
||||
num[numhuntemeralds] = emer[i];
|
||||
|
||||
if (emer2 != emer1)
|
||||
break;
|
||||
// spawn emerald
|
||||
x = huntemeralds[emer[i]]->x<<FRACBITS;
|
||||
y = huntemeralds[emer[i]]->y<<FRACBITS;
|
||||
z = P_GetMapThingSpawnHeight(MT_EMERHUNT, huntemeralds[emer[i]], x, y);
|
||||
P_SetMobjStateNF(P_SpawnMobj(x, y, z, MT_EMERHUNT),
|
||||
mobjinfo[MT_EMERHUNT].spawnstate+i);
|
||||
}
|
||||
|
||||
timeout = 0;
|
||||
while (timeout++ < 100)
|
||||
{
|
||||
emer3 = (P_RandomKey(numhuntemeralds)) + 1;
|
||||
|
||||
if (emer3 != emer2 && emer3 != emer1)
|
||||
break;
|
||||
}
|
||||
|
||||
//decrement spawn values to the actual number because zero is valid.
|
||||
if (emer1--)
|
||||
P_SpawnMobj(huntemeralds[emer1]->x<<FRACBITS,
|
||||
huntemeralds[emer1]->y<<FRACBITS,
|
||||
huntemeralds[emer1]->z<<FRACBITS, MT_EMERHUNT);
|
||||
|
||||
if (emer2--)
|
||||
P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer2]->x<<FRACBITS,
|
||||
huntemeralds[emer2]->y<<FRACBITS,
|
||||
huntemeralds[emer2]->z<<FRACBITS, MT_EMERHUNT),
|
||||
mobjinfo[MT_EMERHUNT].spawnstate+1);
|
||||
|
||||
if (emer3--)
|
||||
P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer3]->x<<FRACBITS,
|
||||
huntemeralds[emer3]->y<<FRACBITS,
|
||||
huntemeralds[emer3]->z<<FRACBITS, MT_EMERHUNT),
|
||||
mobjinfo[MT_EMERHUNT].spawnstate+2);
|
||||
}
|
||||
|
||||
static void P_SpawnMapThings(boolean spawnemblems)
|
||||
|
@ -867,7 +847,7 @@ static void P_InitializeSector(sector_t *ss)
|
|||
ss->camsec = -1;
|
||||
|
||||
ss->floorlightsec = ss->ceilinglightsec = -1;
|
||||
ss->crumblestate = 0;
|
||||
ss->crumblestate = CRUMBLE_NONE;
|
||||
|
||||
ss->touching_thinglist = NULL;
|
||||
|
||||
|
@ -1281,7 +1261,11 @@ static void P_LoadThings(UINT8 *data)
|
|||
mt->type = READUINT16(data);
|
||||
mt->options = READUINT16(data);
|
||||
mt->extrainfo = (UINT8)(mt->type >> 12);
|
||||
mt->scale = FRACUNIT;
|
||||
mt->tag = 0;
|
||||
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
|
||||
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
|
||||
mt->pitch = mt->roll = 0;
|
||||
|
||||
mt->type &= 4095;
|
||||
|
||||
|
@ -1568,9 +1552,14 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
|
|||
mapthings[i].z = atol(val);
|
||||
else if (fastcmp(param, "angle"))
|
||||
mapthings[i].angle = atol(val);
|
||||
else if (fastcmp(param, "pitch"))
|
||||
mapthings[i].pitch = atol(val);
|
||||
else if (fastcmp(param, "roll"))
|
||||
mapthings[i].roll = atol(val);
|
||||
else if (fastcmp(param, "type"))
|
||||
mapthings[i].type = atol(val);
|
||||
|
||||
else if (fastcmp(param, "scale") || fastcmp(param, "scalex") || fastcmp(param, "scaley"))
|
||||
mapthings[i].scale = FLOAT_TO_FIXED(atof(val));
|
||||
// Flags
|
||||
else if (fastcmp(param, "extra") && fastcmp("true", val))
|
||||
mapthings[i].options |= MTF_EXTRA;
|
||||
|
@ -1580,6 +1569,22 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
|
|||
mapthings[i].options |= MTF_OBJECTSPECIAL;
|
||||
else if (fastcmp(param, "ambush") && fastcmp("true", val))
|
||||
mapthings[i].options |= MTF_AMBUSH;
|
||||
|
||||
else if (fastncmp(param, "arg", 3) && strlen(param) > 3)
|
||||
{
|
||||
size_t argnum = atol(param + 3);
|
||||
if (argnum >= NUMMAPTHINGARGS)
|
||||
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.
|
||||
|
@ -1772,12 +1777,15 @@ static void P_LoadTextmap(void)
|
|||
{
|
||||
// Defaults.
|
||||
mt->x = mt->y = 0;
|
||||
mt->angle = 0;
|
||||
mt->angle = mt->pitch = mt->roll = 0;
|
||||
mt->type = 0;
|
||||
mt->options = 0;
|
||||
mt->z = 0;
|
||||
mt->extrainfo = 0;
|
||||
mt->scale = FRACUNIT;
|
||||
mt->tag = 0;
|
||||
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
|
||||
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
|
||||
mt->mobj = NULL;
|
||||
|
||||
TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter);
|
||||
|
@ -4381,12 +4389,12 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l
|
|||
{
|
||||
UINT16 numlumps = *pnumlumps;
|
||||
size_t i = *pi;
|
||||
if (!stricmp(lumpinfo->name2, folName))
|
||||
if (!stricmp(lumpinfo->fullname, folName))
|
||||
{
|
||||
lumpinfo++;
|
||||
*start = ++i;
|
||||
for (; i < numlumps; i++, lumpinfo++)
|
||||
if (strnicmp(lumpinfo->name2, folName, strlen(folName)))
|
||||
if (strnicmp(lumpinfo->fullname, folName, strlen(folName)))
|
||||
break;
|
||||
lumpinfo--;
|
||||
*end = i-- - *start;
|
||||
|
|
131
src/p_spec.c
131
src/p_spec.c
|
@ -115,12 +115,11 @@ static void P_ResetColormapFader(sector_t *sector);
|
|||
static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc,
|
||||
boolean ticbased, INT32 duration);
|
||||
static void P_AddBlockThinker(sector_t *sec, line_t *sourceline);
|
||||
static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline);
|
||||
static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline);
|
||||
//static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec);
|
||||
static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers);
|
||||
static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
|
||||
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
|
||||
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer);
|
||||
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee, UINT8 reverse);
|
||||
|
||||
|
||||
|
@ -4046,7 +4045,11 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
|
||||
mobj = P_SpawnMobj(x, y, z, type);
|
||||
if (mobj)
|
||||
{
|
||||
if (line->flags & ML_EFFECT1)
|
||||
mobj->angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y);
|
||||
CONS_Debug(DBG_GAMELOGIC, "Linedef Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", line->special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow.
|
||||
}
|
||||
else
|
||||
CONS_Alert(CONS_ERROR,"Linedef Type %d - Spawn Object: Object did not spawn!\n", line->special);
|
||||
}
|
||||
|
@ -4465,7 +4468,8 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_ELECTRIC);
|
||||
break;
|
||||
case 5: // Spikes
|
||||
// Don't do anything. In Soviet Russia, spikes find you.
|
||||
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPIKE);
|
||||
break;
|
||||
case 6: // Death Pit (Camera Mod)
|
||||
case 7: // Death Pit (No Camera Mod)
|
||||
|
@ -5773,7 +5777,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
|||
thinker_t *th;
|
||||
friction_t *f;
|
||||
pusher_t *p;
|
||||
levelspecthink_t *lst;
|
||||
size_t sec2num;
|
||||
size_t i;
|
||||
|
||||
|
@ -5875,16 +5878,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
|||
else if (th == &thlist[THINK_MAIN])
|
||||
break;
|
||||
|
||||
// Should this FOF have spikeness?
|
||||
if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
||||
{
|
||||
lst = (levelspecthink_t *)th;
|
||||
|
||||
if (lst->sector == sec2)
|
||||
P_AddSpikeThinker(sec, (INT32)sec2num);
|
||||
}
|
||||
// Should this FOF have friction?
|
||||
else if(th->function.acp1 == (actionf_p1)T_Friction)
|
||||
if(th->function.acp1 == (actionf_p1)T_Friction)
|
||||
{
|
||||
f = (friction_t *)th;
|
||||
|
||||
|
@ -5921,7 +5916,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
|||
}
|
||||
|
||||
if ((flags & FF_CRUMBLE))
|
||||
sec2->crumblestate = 1;
|
||||
sec2->crumblestate = CRUMBLE_WAIT;
|
||||
|
||||
if ((flags & FF_FLOATBOB))
|
||||
{
|
||||
|
@ -5938,28 +5933,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
|||
// SPECIAL SPAWNING
|
||||
//
|
||||
|
||||
/** Adds a spike thinker.
|
||||
* Sector type Section1:5 will result in this effect.
|
||||
*
|
||||
* \param sec Sector in which to add the thinker.
|
||||
* \param referrer If != sec, then we're dealing with a FOF
|
||||
* \sa P_SpawnSpecials, T_SpikeSector
|
||||
* \author SSNTails <http://www.ssntails.org>
|
||||
*/
|
||||
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer)
|
||||
{
|
||||
levelspecthink_t *spikes;
|
||||
|
||||
// create and initialize new thinker
|
||||
spikes = Z_Calloc(sizeof (*spikes), PU_LEVSPEC, NULL);
|
||||
P_AddThinker(THINK_MAIN, &spikes->thinker);
|
||||
|
||||
spikes->thinker.function.acp1 = (actionf_p1)T_SpikeSector;
|
||||
|
||||
spikes->sector = sec;
|
||||
spikes->vars[0] = referrer;
|
||||
}
|
||||
|
||||
/** Adds a float thinker.
|
||||
* Float thinkers cause solid 3Dfloors to float on water.
|
||||
*
|
||||
|
@ -5968,9 +5941,9 @@ static void P_AddSpikeThinker(sector_t *sec, INT32 referrer)
|
|||
* \sa P_SpawnSpecials, T_FloatSector
|
||||
* \author SSNTails <http://www.ssntails.org>
|
||||
*/
|
||||
static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
|
||||
static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline)
|
||||
{
|
||||
levelspecthink_t *floater;
|
||||
floatthink_t *floater;
|
||||
|
||||
// create and initialize new thinker
|
||||
floater = Z_Calloc(sizeof (*floater), PU_LEVSPEC, NULL);
|
||||
|
@ -5979,7 +5952,7 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
|
|||
floater->thinker.function.acp1 = (actionf_p1)T_FloatSector;
|
||||
|
||||
floater->sector = sec;
|
||||
floater->vars[0] = tag;
|
||||
floater->tag = (INT16)tag;
|
||||
floater->sourceline = sourceline;
|
||||
}
|
||||
|
||||
|
@ -6024,7 +5997,7 @@ static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control,
|
|||
*/
|
||||
static void P_AddBlockThinker(sector_t *sec, line_t *sourceline)
|
||||
{
|
||||
levelspecthink_t *block;
|
||||
mariocheck_t *block;
|
||||
|
||||
// create and initialize new elevator thinker
|
||||
block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL);
|
||||
|
@ -6059,7 +6032,6 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, boolean lower,
|
|||
|
||||
raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector;
|
||||
|
||||
// set up the fields
|
||||
raise->sourceline = sourceline;
|
||||
raise->sector = sec;
|
||||
|
||||
|
@ -6076,37 +6048,27 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, boolean lower,
|
|||
|
||||
static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean raise, boolean spindash, boolean dynamic)
|
||||
{
|
||||
levelspecthink_t *airbob;
|
||||
raise_t *airbob;
|
||||
|
||||
airbob = Z_Calloc(sizeof (*airbob), PU_LEVSPEC, NULL);
|
||||
P_AddThinker(THINK_MAIN, &airbob->thinker);
|
||||
|
||||
airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector;
|
||||
|
||||
// set up the fields
|
||||
airbob->sourceline = sourceline;
|
||||
airbob->sector = sec;
|
||||
|
||||
// Require a spindash to activate
|
||||
airbob->vars[1] = spindash ? 1 : 0;
|
||||
airbob->ceilingtop = sec->ceilingheight;
|
||||
airbob->ceilingbottom = sec->ceilingheight - dist;
|
||||
|
||||
airbob->vars[2] = FRACUNIT;
|
||||
airbob->basespeed = FRACUNIT;
|
||||
|
||||
airbob->vars[7] = airbob->sector->ceilingheight - dist;
|
||||
|
||||
airbob->vars[6] = airbob->vars[7]
|
||||
- (sec->ceilingheight - sec->floorheight);
|
||||
|
||||
airbob->vars[3] = airbob->vars[2];
|
||||
|
||||
airbob->vars[0] = raise ? 0 : 1;
|
||||
|
||||
airbob->vars[5] = sec->ceilingheight;
|
||||
airbob->vars[4] = airbob->vars[5]
|
||||
- (sec->ceilingheight - sec->floorheight);
|
||||
|
||||
airbob->vars[9] = dynamic ? 1 : 0;
|
||||
|
||||
airbob->sourceline = sourceline;
|
||||
if (!raise)
|
||||
airbob->flags |= RF_REVERSE;
|
||||
if (spindash)
|
||||
airbob->flags |= RF_SPINDASH;
|
||||
if (dynamic)
|
||||
airbob->flags |= RF_DYNAMIC;
|
||||
}
|
||||
|
||||
/** Adds a thwomp thinker.
|
||||
|
@ -6136,14 +6098,14 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin
|
|||
// set up the fields according to the type of elevator action
|
||||
thwomp->sourceline = sourceline;
|
||||
thwomp->sector = sec;
|
||||
thwomp->crushspeed = thwomp->sourceline->args[1] << (FRACBITS - 3);
|
||||
thwomp->retractspeed = thwomp->sourceline->args[2] << (FRACBITS - 3);
|
||||
thwomp->crushspeed = sourceline->args[1] << (FRACBITS - 3);
|
||||
thwomp->retractspeed = sourceline->args[2] << (FRACBITS - 3);
|
||||
thwomp->direction = 0;
|
||||
thwomp->floorstartheight = sec->floorheight;
|
||||
thwomp->ceilingstartheight = sec->ceilingheight;
|
||||
thwomp->delay = 1;
|
||||
thwomp->tag = actionsector->tag;
|
||||
thwomp->sound = (thwomp->sourceline->stringargs[0]) ? get_number(thwomp->sourceline->stringargs[0]) : sfx_thwomp;
|
||||
thwomp->sound = (sourceline->stringargs[0]) ? get_number(sourceline->stringargs[0]) : sfx_thwomp;
|
||||
|
||||
sec->floordata = thwomp;
|
||||
sec->ceilingdata = thwomp;
|
||||
|
@ -6154,14 +6116,13 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin
|
|||
/** Adds a thinker which checks if any MF_ENEMY objects with health are in the defined area.
|
||||
* If not, a linedef executor is run once.
|
||||
*
|
||||
* \param sec Control sector.
|
||||
* \param sourceline Control linedef.
|
||||
* \sa P_SpawnSpecials, T_NoEnemiesSector
|
||||
* \author SSNTails <http://www.ssntails.org>
|
||||
*/
|
||||
static inline void P_AddNoEnemiesThinker(sector_t *sec, line_t *sourceline)
|
||||
static inline void P_AddNoEnemiesThinker(line_t *sourceline)
|
||||
{
|
||||
levelspecthink_t *nobaddies;
|
||||
noenemies_t *nobaddies;
|
||||
|
||||
// create and initialize new thinker
|
||||
nobaddies = Z_Calloc(sizeof (*nobaddies), PU_LEVSPEC, NULL);
|
||||
|
@ -6169,21 +6130,19 @@ static inline void P_AddNoEnemiesThinker(sector_t *sec, line_t *sourceline)
|
|||
|
||||
nobaddies->thinker.function.acp1 = (actionf_p1)T_NoEnemiesSector;
|
||||
|
||||
nobaddies->sector = sec;
|
||||
nobaddies->sourceline = sourceline;
|
||||
}
|
||||
|
||||
/** Adds a thinker for Each-Time linedef executors. A linedef executor is run
|
||||
* only when a player enters the area and doesn't run again until they re-enter.
|
||||
*
|
||||
* \param sec Control sector that contains the lines of executors we will want to run.
|
||||
* \param sourceline Control linedef.
|
||||
* \sa P_SpawnSpecials, T_EachTimeThinker
|
||||
* \author SSNTails <http://www.ssntails.org>
|
||||
*/
|
||||
static void P_AddEachTimeThinker(sector_t *sec, line_t *sourceline)
|
||||
static void P_AddEachTimeThinker(line_t *sourceline)
|
||||
{
|
||||
levelspecthink_t *eachtime;
|
||||
eachtime_t *eachtime;
|
||||
|
||||
// create and initialize new thinker
|
||||
eachtime = Z_Calloc(sizeof (*eachtime), PU_LEVSPEC, NULL);
|
||||
|
@ -6191,8 +6150,8 @@ static void P_AddEachTimeThinker(sector_t *sec, line_t *sourceline)
|
|||
|
||||
eachtime->thinker.function.acp1 = (actionf_p1)T_EachTimeThinker;
|
||||
|
||||
eachtime->sector = sec;
|
||||
eachtime->sourceline = sourceline;
|
||||
eachtime->triggerOnExit = !!(sourceline->flags & ML_BOUNCY);
|
||||
}
|
||||
|
||||
/** Adds a camera scanner.
|
||||
|
@ -6419,7 +6378,10 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
switch(GETSECSPECIAL(sector->special, 1))
|
||||
{
|
||||
case 5: // Spikes
|
||||
P_AddSpikeThinker(sector, (INT32)(sector-sectors));
|
||||
//Terrible hack to replace an even worse hack:
|
||||
//Spike damage automatically sets SF_TRIGGERSPECIAL_TOUCH.
|
||||
//Yes, this also affects other specials on the same sector. Sorry.
|
||||
sector->flags |= SF_TRIGGERSPECIAL_TOUCH;
|
||||
break;
|
||||
|
||||
case 15: // Bouncy sector
|
||||
|
@ -6467,9 +6429,7 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
// Firstly, find out how many there are in each sector
|
||||
for (th = thlist[THINK_MAIN].next; th != &thlist[THINK_MAIN]; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
||||
secthinkers[((levelspecthink_t *)th)->sector - sectors].count++;
|
||||
else if (th->function.acp1 == (actionf_p1)T_Friction)
|
||||
if (th->function.acp1 == (actionf_p1)T_Friction)
|
||||
secthinkers[((friction_t *)th)->affectee].count++;
|
||||
else if (th->function.acp1 == (actionf_p1)T_Pusher)
|
||||
secthinkers[((pusher_t *)th)->affectee].count++;
|
||||
|
@ -6489,9 +6449,7 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
{
|
||||
size_t secnum = (size_t)-1;
|
||||
|
||||
if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
||||
secnum = ((levelspecthink_t *)th)->sector - sectors;
|
||||
else if (th->function.acp1 == (actionf_p1)T_Friction)
|
||||
if (th->function.acp1 == (actionf_p1)T_Friction)
|
||||
secnum = ((friction_t *)th)->affectee;
|
||||
else if (th->function.acp1 == (actionf_p1)T_Pusher)
|
||||
secnum = ((pusher_t *)th)->affectee;
|
||||
|
@ -6779,7 +6737,7 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
case 150: // Air bobbing platform
|
||||
case 151: // Adjustable air bobbing platform
|
||||
{
|
||||
fixed_t dist = (lines[i].special == 151) ? P_AproxDistance(lines[i].dx, lines[i].dy) : 16*FRACUNIT;
|
||||
fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : P_AproxDistance(lines[i].dx, lines[i].dy);
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, dist, false, !!(lines[i].flags & ML_NOCLIMB), false);
|
||||
break;
|
||||
|
@ -7031,14 +6989,12 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
case 312:
|
||||
case 332:
|
||||
case 335:
|
||||
sec = sides[*lines[i].sidenum].sector - sectors;
|
||||
P_AddEachTimeThinker(§ors[sec], &lines[i]);
|
||||
P_AddEachTimeThinker(&lines[i]);
|
||||
break;
|
||||
|
||||
// No More Enemies Linedef Exec
|
||||
case 313:
|
||||
sec = sides[*lines[i].sidenum].sector - sectors;
|
||||
P_AddNoEnemiesThinker(§ors[sec], &lines[i]);
|
||||
P_AddNoEnemiesThinker(&lines[i]);
|
||||
break;
|
||||
|
||||
// Pushable linedef executors (count # of pushables)
|
||||
|
@ -7062,10 +7018,7 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
else
|
||||
lines[i].callcount = sides[lines[i].sidenum[0]].textureoffset>>FRACBITS;
|
||||
if (lines[i].special == 322) // Each time
|
||||
{
|
||||
sec = sides[*lines[i].sidenum].sector - sectors;
|
||||
P_AddEachTimeThinker(§ors[sec], &lines[i]);
|
||||
}
|
||||
P_AddEachTimeThinker(&lines[i]);
|
||||
break;
|
||||
|
||||
// NiGHTS trigger executors
|
||||
|
|
90
src/p_spec.h
90
src/p_spec.h
|
@ -377,11 +377,49 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
fixed_t vars[16]; // Misc. variables
|
||||
fixed_t var2s[16]; // Second misc variables buffer.
|
||||
line_t *sourceline; // Source line of the thinker
|
||||
sector_t *sector; // Sector the thinker is from
|
||||
} levelspecthink_t;
|
||||
} noenemies_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
fixed_t speed;
|
||||
INT32 direction;
|
||||
fixed_t floorstartheight;
|
||||
fixed_t ceilingstartheight;
|
||||
fixed_t destheight;
|
||||
} continuousfall_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
line_t *sourceline;
|
||||
sector_t *sector;
|
||||
fixed_t speed;
|
||||
fixed_t distance;
|
||||
fixed_t floorwasheight;
|
||||
fixed_t ceilingwasheight;
|
||||
boolean low;
|
||||
} bouncecheese_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
fixed_t speed;
|
||||
INT32 direction;
|
||||
fixed_t floorstartheight;
|
||||
fixed_t ceilingstartheight;
|
||||
INT16 tag;
|
||||
} mariothink_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
line_t *sourceline;
|
||||
sector_t *sector;
|
||||
} mariocheck_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -398,6 +436,23 @@ typedef struct
|
|||
UINT16 sound;
|
||||
} thwomp_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
line_t *sourceline;
|
||||
sector_t *sector;
|
||||
INT16 tag;
|
||||
} floatthink_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
line_t *sourceline; // Source line of the thinker
|
||||
boolean playersInArea[MAXPLAYERS];
|
||||
boolean playersOnArea[MAXPLAYERS];
|
||||
boolean triggerOnExit;
|
||||
} eachtime_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RF_REVERSE = 1, //Lower when stood on
|
||||
|
@ -429,33 +484,32 @@ typedef enum
|
|||
} result_e;
|
||||
|
||||
result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush,
|
||||
INT32 floorOrCeiling, INT32 direction);
|
||||
INT32 EV_DoFloor(line_t *line, floor_e floortype);
|
||||
INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed);
|
||||
boolean ceiling, INT32 direction);
|
||||
void EV_DoFloor(line_t *line, floor_e floortype);
|
||||
void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed);
|
||||
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover);
|
||||
INT32 EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
|
||||
void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
|
||||
|
||||
// Some other special 3dfloor types
|
||||
INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover,
|
||||
boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn);
|
||||
|
||||
INT32 EV_DoContinuousFall(sector_t *sec, sector_t *pbacksector, fixed_t spd, boolean backwards);
|
||||
void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards);
|
||||
|
||||
INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
|
||||
void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
|
||||
|
||||
void T_MoveFloor(floormove_t *movefloor);
|
||||
|
||||
void T_MoveElevator(elevator_t *elevator);
|
||||
void T_ContinuousFalling(levelspecthink_t *faller);
|
||||
void T_BounceCheese(levelspecthink_t *bouncer);
|
||||
void T_ContinuousFalling(continuousfall_t *faller);
|
||||
void T_BounceCheese(bouncecheese_t *bouncer);
|
||||
void T_StartCrumble(elevator_t *elevator);
|
||||
void T_MarioBlock(levelspecthink_t *block);
|
||||
void T_SpikeSector(levelspecthink_t *spikes);
|
||||
void T_FloatSector(levelspecthink_t *floater);
|
||||
void T_MarioBlockChecker(levelspecthink_t *block);
|
||||
void T_MarioBlock(mariothink_t *block);
|
||||
void T_FloatSector(floatthink_t *floater);
|
||||
void T_MarioBlockChecker(mariocheck_t *block);
|
||||
void T_ThwompSector(thwomp_t *thwomp);
|
||||
void T_NoEnemiesSector(levelspecthink_t *nobaddies);
|
||||
void T_EachTimeThinker(levelspecthink_t *eachtime);
|
||||
void T_NoEnemiesSector(noenemies_t *nobaddies);
|
||||
void T_EachTimeThinker(eachtime_t *eachtime);
|
||||
void T_CameraScanner(elevator_t *elevator);
|
||||
void T_RaiseSector(raise_t *raise);
|
||||
|
||||
|
|
|
@ -1388,7 +1388,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
|
|||
|
||||
// Continues are worthless in netgames.
|
||||
// If that stops being the case uncomment this.
|
||||
/* if (!ultimatemode && players[i].marescore > 50000
|
||||
/* if (!ultimatemode && continuesInSession && players[i].marescore > 50000
|
||||
&& oldscore < 50000)
|
||||
{
|
||||
players[i].continues += 1;
|
||||
|
@ -1408,7 +1408,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
|
|||
else
|
||||
player->marescore = MAXSCORE;
|
||||
|
||||
if (!ultimatemode && !(netgame || multiplayer) && G_IsSpecialStage(gamemap)
|
||||
if (!ultimatemode && continuesInSession && G_IsSpecialStage(gamemap)
|
||||
&& player->marescore >= 50000 && oldscore < 50000)
|
||||
{
|
||||
player->continues += 1;
|
||||
|
@ -2566,7 +2566,7 @@ static void P_CheckBustableBlocks(player_t *player)
|
|||
{
|
||||
if (!(rover->flags & FF_EXISTS)) continue;
|
||||
|
||||
if ((rover->flags & FF_BUSTUP)/* && !rover->master->frontsector->crumblestate*/)
|
||||
if ((rover->flags & FF_BUSTUP)/* && rover->master->frontsector->crumblestate == CRUMBLE_NONE*/)
|
||||
{
|
||||
// If it's an FF_SHATTER, you can break it just by touching it.
|
||||
if (rover->flags & FF_SHATTER)
|
||||
|
@ -9543,7 +9543,7 @@ static void P_DeathThink(player_t *player)
|
|||
// continue logic
|
||||
if (!(netgame || multiplayer) && player->lives <= 0)
|
||||
{
|
||||
if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_USE || cmd->buttons & BT_JUMP) && player->continues > 0)
|
||||
if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_USE || cmd->buttons & BT_JUMP) && (!continuesInSession || player->continues > 0))
|
||||
G_UseContinue();
|
||||
else if (player->deadtimer >= gameovertics)
|
||||
G_UseContinue(); // Even if we don't have one this handles ending the game
|
||||
|
|
10
src/r_defs.h
10
src/r_defs.h
|
@ -277,6 +277,16 @@ typedef enum
|
|||
SF_INVERTPRECIP = 1<<4,
|
||||
} sectorflags_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CRUMBLE_NONE, // No crumble thinker
|
||||
CRUMBLE_WAIT, // Don't float on water because this is supposed to wait for a crumble
|
||||
CRUMBLE_ACTIVATED, // Crumble thinker activated, but hasn't fallen yet
|
||||
CRUMBLE_FALL, // Crumble thinker is falling
|
||||
CRUMBLE_RESTORE, // Crumble thinker is about to restore to original position
|
||||
} crumblestate_t;
|
||||
|
||||
//
|
||||
// The SECTORS record, at runtime.
|
||||
// Stores things/mobjs.
|
||||
|
|
22
src/r_segs.c
22
src/r_segs.c
|
@ -236,14 +236,13 @@ static void R_DrawWallSplats(void)
|
|||
// way we don't have to store extra post_t info with each column for
|
||||
// multi-patch textures. They are not normally needed as multi-patch
|
||||
// textures don't have holes in it. At least not for now.
|
||||
static INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height
|
||||
|
||||
static void R_Render2sidedMultiPatchColumn(column_t *column)
|
||||
{
|
||||
INT32 topscreen, bottomscreen;
|
||||
|
||||
topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall
|
||||
bottomscreen = topscreen + spryscale * column2s_length;
|
||||
bottomscreen = topscreen + spryscale * lengthcol;
|
||||
|
||||
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||
|
@ -275,13 +274,6 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
|
|||
}
|
||||
}
|
||||
|
||||
// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value
|
||||
// uses column2s_length for texture->height as above
|
||||
static void R_DrawFlippedMaskedSegColumn(column_t *column)
|
||||
{
|
||||
R_DrawFlippedMaskedColumn(column, column2s_length);
|
||||
}
|
||||
|
||||
transnum_t R_GetLinedefTransTable(fixed_t alpha)
|
||||
{
|
||||
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
|
||||
|
@ -354,8 +346,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
{
|
||||
if (textures[texnum]->flip & 2) // vertically flipped?
|
||||
{
|
||||
colfunc_2s = R_DrawFlippedMaskedSegColumn;
|
||||
column2s_length = textures[texnum]->height;
|
||||
colfunc_2s = R_DrawFlippedMaskedColumn;
|
||||
lengthcol = textures[texnum]->height;
|
||||
}
|
||||
else
|
||||
colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
|
||||
|
@ -363,7 +355,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
else
|
||||
{
|
||||
colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info)
|
||||
column2s_length = textures[texnum]->height;
|
||||
lengthcol = textures[texnum]->height;
|
||||
}
|
||||
|
||||
// Setup lighting based on the presence/lack-of 3D floors.
|
||||
|
@ -693,7 +685,7 @@ static void R_DrawRepeatMaskedColumn(column_t *col)
|
|||
static void R_DrawRepeatFlippedMaskedColumn(column_t *col)
|
||||
{
|
||||
do {
|
||||
R_DrawFlippedMaskedColumn(col, column2s_length);
|
||||
R_DrawFlippedMaskedColumn(col);
|
||||
sprtopscreen += dc_texheight*spryscale;
|
||||
} while (sprtopscreen < sprbotscreen);
|
||||
}
|
||||
|
@ -988,7 +980,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
if (textures[texnum]->flip & 2) // vertically flipped?
|
||||
{
|
||||
colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
|
||||
column2s_length = textures[texnum]->height;
|
||||
lengthcol = textures[texnum]->height;
|
||||
}
|
||||
else
|
||||
colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture
|
||||
|
@ -996,7 +988,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
else
|
||||
{
|
||||
colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info)
|
||||
column2s_length = textures[texnum]->height;
|
||||
lengthcol = textures[texnum]->height;
|
||||
}
|
||||
|
||||
// Set heights according to plane, or slope, whichever
|
||||
|
|
|
@ -639,10 +639,10 @@ void R_DrawMaskedColumn(column_t *column)
|
|||
dc_yl = mceilingclip[dc_x]+1;
|
||||
if (dc_yl < 0)
|
||||
dc_yl = 0;
|
||||
if (dc_yh >= vid.height)
|
||||
if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop
|
||||
dc_yh = vid.height - 1;
|
||||
|
||||
if (dc_yl <= dc_yh && dc_yl < vid.height && dc_yh > 0)
|
||||
if (dc_yl <= dc_yh && dc_yh > 0)
|
||||
{
|
||||
dc_source = (UINT8 *)column + 3;
|
||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
|
@ -653,15 +653,10 @@ void R_DrawMaskedColumn(column_t *column)
|
|||
// quick fix... something more proper should be done!!!
|
||||
if (ylookup[dc_yl])
|
||||
colfunc();
|
||||
else if (colfunc == colfuncs[COLDRAWFUNC_BASE])
|
||||
{
|
||||
static INT32 first = 1;
|
||||
if (first)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "WARNING: avoiding a crash in %s %d\n", __FILE__, __LINE__);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
else
|
||||
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
|
||||
#endif
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
}
|
||||
|
@ -669,7 +664,9 @@ void R_DrawMaskedColumn(column_t *column)
|
|||
dc_texturemid = basetexturemid;
|
||||
}
|
||||
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
||||
INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height
|
||||
|
||||
void R_DrawFlippedMaskedColumn(column_t *column)
|
||||
{
|
||||
INT32 topscreen;
|
||||
INT32 bottomscreen;
|
||||
|
@ -685,7 +682,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
|||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
topdelta = texheight-column->length-topdelta;
|
||||
topdelta = lengthcol-column->length-topdelta;
|
||||
topscreen = sprtopscreen + spryscale*topdelta;
|
||||
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*column->length
|
||||
: sprbotscreen + spryscale*column->length;
|
||||
|
@ -707,10 +704,10 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
|||
dc_yl = mceilingclip[dc_x]+1;
|
||||
if (dc_yl < 0)
|
||||
dc_yl = 0;
|
||||
if (dc_yh >= vid.height)
|
||||
if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop
|
||||
dc_yh = vid.height - 1;
|
||||
|
||||
if (dc_yl <= dc_yh && dc_yl < vid.height && dc_yh > 0)
|
||||
if (dc_yl <= dc_yh && dc_yh > 0)
|
||||
{
|
||||
dc_source = ZZ_Alloc(column->length);
|
||||
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
|
||||
|
@ -720,15 +717,10 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
|||
// Still drawn by R_DrawColumn.
|
||||
if (ylookup[dc_yl])
|
||||
colfunc();
|
||||
else if (colfunc == colfuncs[COLDRAWFUNC_BASE])
|
||||
{
|
||||
static INT32 first = 1;
|
||||
if (first)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "WARNING: avoiding a crash in %s %d\n", __FILE__, __LINE__);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
else
|
||||
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
|
||||
#endif
|
||||
Z_Free(dc_source);
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
|
@ -744,7 +736,9 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
|||
static void R_DrawVisSprite(vissprite_t *vis)
|
||||
{
|
||||
column_t *column;
|
||||
void (*localcolfunc)(column_t *);
|
||||
INT32 texturecolumn;
|
||||
INT32 pwidth;
|
||||
fixed_t frac;
|
||||
patch_t *patch = vis->patch;
|
||||
fixed_t this_scale = vis->mobj->scale;
|
||||
|
@ -893,50 +887,52 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
if (vis->x2 >= vid.width)
|
||||
vis->x2 = vid.width-1;
|
||||
|
||||
localcolfunc = (vis->cut & SC_VFLIP) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn;
|
||||
lengthcol = patch->height;
|
||||
|
||||
// Split drawing loops for paper and non-paper to reduce conditional checks per sprite
|
||||
if (vis->scalestep)
|
||||
{
|
||||
// Papersprite drawing loop
|
||||
pwidth = SHORT(patch->width);
|
||||
|
||||
// Papersprite drawing loop
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep)
|
||||
{
|
||||
angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF;
|
||||
texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale;
|
||||
|
||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
||||
if (texturecolumn < 0 || texturecolumn >= pwidth)
|
||||
continue;
|
||||
|
||||
if (vis->xiscale < 0) // Flipped sprite
|
||||
texturecolumn = SHORT(patch->width) - 1 - texturecolumn;
|
||||
texturecolumn = pwidth - 1 - texturecolumn;
|
||||
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||
|
||||
if (vis->cut & SC_VFLIP)
|
||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||
else
|
||||
R_DrawMaskedColumn(column);
|
||||
localcolfunc (column);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
pwidth = SHORT(patch->width);
|
||||
#endif
|
||||
|
||||
// Non-paper drawing loop
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
||||
if (texturecolumn < 0 || texturecolumn >= pwidth)
|
||||
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||
#else
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
if (vis->cut & SC_VFLIP)
|
||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||
else
|
||||
R_DrawMaskedColumn(column);
|
||||
localcolfunc (column);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,9 +44,10 @@ extern fixed_t sprtopscreen;
|
|||
extern fixed_t sprbotscreen;
|
||||
extern fixed_t windowtop;
|
||||
extern fixed_t windowbottom;
|
||||
extern INT32 lengthcol;
|
||||
|
||||
void R_DrawMaskedColumn(column_t *column);
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight);
|
||||
void R_DrawFlippedMaskedColumn(column_t *column);
|
||||
|
||||
// ----------------
|
||||
// SPRITE RENDERING
|
||||
|
|
95
src/w_wad.c
95
src/w_wad.c
|
@ -92,7 +92,7 @@ typedef struct
|
|||
|
||||
typedef struct lumpnum_cache_s
|
||||
{
|
||||
char lumpname[8];
|
||||
char lumpname[32];
|
||||
lumpnum_t lumpnum;
|
||||
} lumpnum_cache_t;
|
||||
|
||||
|
@ -114,13 +114,18 @@ void W_Shutdown(void)
|
|||
{
|
||||
while (numwadfiles--)
|
||||
{
|
||||
fclose(wadfiles[numwadfiles]->handle);
|
||||
Z_Free(wadfiles[numwadfiles]->filename);
|
||||
while (wadfiles[numwadfiles]->numlumps--)
|
||||
Z_Free(wadfiles[numwadfiles]->lumpinfo[wadfiles[numwadfiles]->numlumps].name2);
|
||||
wadfile_t *wad = wadfiles[numwadfiles];
|
||||
|
||||
Z_Free(wadfiles[numwadfiles]->lumpinfo);
|
||||
Z_Free(wadfiles[numwadfiles]);
|
||||
fclose(wad->handle);
|
||||
Z_Free(wad->filename);
|
||||
while (wad->numlumps--)
|
||||
{
|
||||
Z_Free(wad->lumpinfo[wad->numlumps].longname);
|
||||
Z_Free(wad->lumpinfo[wad->numlumps].fullname);
|
||||
}
|
||||
|
||||
Z_Free(wad->lumpinfo);
|
||||
Z_Free(wad);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,9 +211,9 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
|
|||
for(; posStart < posEnd; posStart++)
|
||||
{
|
||||
lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart];
|
||||
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
||||
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
|
||||
char *name = malloc(length + 1);
|
||||
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
|
||||
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname);
|
||||
name[length] = '\0';
|
||||
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
|
||||
DEH_LoadDehackedLumpPwad(wadnum, posStart, mainfile);
|
||||
|
@ -235,9 +240,9 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile)
|
|||
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
|
||||
if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
|
||||
{ // shameless copy+paste of code from LUA_LoadLump
|
||||
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
||||
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
|
||||
char *name = malloc(length + 1);
|
||||
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
|
||||
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname);
|
||||
name[length] = '\0';
|
||||
|
||||
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
|
||||
|
@ -339,10 +344,17 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const
|
|||
lumpinfo->size = ftell(handle);
|
||||
fseek(handle, 0, SEEK_SET);
|
||||
strcpy(lumpinfo->name, lumpname);
|
||||
|
||||
// Allocate the lump's long name.
|
||||
lumpinfo->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strcpy(lumpinfo->longname, lumpname);
|
||||
lumpinfo->longname[8] = '\0';
|
||||
|
||||
// Allocate the lump's full name.
|
||||
lumpinfo->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strcpy(lumpinfo->name2, lumpname);
|
||||
lumpinfo->name2[8] = '\0';
|
||||
lumpinfo->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strcpy(lumpinfo->fullname, lumpname);
|
||||
lumpinfo->fullname[8] = '\0';
|
||||
|
||||
*numlumps = 1;
|
||||
return lumpinfo;
|
||||
}
|
||||
|
@ -429,10 +441,16 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
|
|||
lump_p->compression = CM_NOCOMPRESSION;
|
||||
memset(lump_p->name, 0x00, 9);
|
||||
strncpy(lump_p->name, fileinfo->name, 8);
|
||||
|
||||
// Allocate the lump's long name.
|
||||
lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strncpy(lump_p->longname, fileinfo->name, 8);
|
||||
lump_p->longname[8] = '\0';
|
||||
|
||||
// Allocate the lump's full name.
|
||||
lump_p->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strncpy(lump_p->name2, fileinfo->name, 8);
|
||||
lump_p->name2[8] = '\0';
|
||||
lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strncpy(lump_p->fullname, fileinfo->name, 8);
|
||||
lump_p->fullname[8] = '\0';
|
||||
}
|
||||
free(fileinfov);
|
||||
*nlmp = numlumps;
|
||||
|
@ -598,8 +616,11 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
|
|||
memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
|
||||
strncpy(lump_p->name, trimname, min(8, dotpos - trimname));
|
||||
|
||||
lump_p->name2 = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL);
|
||||
strncpy(lump_p->name2, fullname, zentry.namelen);
|
||||
lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL);
|
||||
strlcpy(lump_p->longname, trimname, dotpos - trimname + 1);
|
||||
|
||||
lump_p->fullname = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL);
|
||||
strncpy(lump_p->fullname, fullname, zentry.namelen);
|
||||
|
||||
free(fullname);
|
||||
|
||||
|
@ -637,7 +658,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
|
|||
// skip and ignore comments/extra fields
|
||||
if ((fseek(handle, lump_p->position, SEEK_SET) != 0) || (fread(&zlentry, 1, sizeof(zlentry_t), handle) < sizeof(zlentry_t)))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Local headers for lump %s are corrupt\n", lump_p->name2);
|
||||
CONS_Alert(CONS_ERROR, "Local headers for lump %s are corrupt\n", lump_p->fullname);
|
||||
Z_Free(lumpinfo);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -901,16 +922,14 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum)
|
|||
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||
{
|
||||
UINT16 i;
|
||||
static char uname[9];
|
||||
|
||||
memset(uname, 0x00, sizeof uname);
|
||||
strncpy(uname, name, 8);
|
||||
uname[8] = 0;
|
||||
strupr(uname);
|
||||
static char uname[256 + 1];
|
||||
|
||||
if (!TestValidLump(wad,0))
|
||||
return INT16_MAX;
|
||||
|
||||
strlcpy(uname, name, sizeof uname);
|
||||
strupr(uname);
|
||||
|
||||
//
|
||||
// scan forward
|
||||
// start at 'startlump', useful parameter when there are multiple
|
||||
|
@ -920,7 +939,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
|||
{
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
if (memcmp(lump_p->name,uname,8) == 0)
|
||||
if (!strcmp(lump_p->longname, uname))
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -947,10 +966,10 @@ UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlum
|
|||
name_length = strlen(name);
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (strnicmp(name, lump_p->name2, name_length) == 0)
|
||||
if (strnicmp(name, lump_p->fullname, name_length) == 0)
|
||||
{
|
||||
/* SLADE is special and puts a single directory entry. Skip that. */
|
||||
if (strlen(lump_p->name2) == name_length)
|
||||
if (strlen(lump_p->fullname) == name_length)
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
@ -967,7 +986,7 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
|
|||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (strnicmp(name, lump_p->name2, strlen(name)))
|
||||
if (strnicmp(name, lump_p->fullname, strlen(name)))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
|
@ -981,7 +1000,7 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
|||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (!strnicmp(name, lump_p->name2, strlen(name)))
|
||||
if (!strnicmp(name, lump_p->fullname, strlen(name)))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
@ -1006,7 +1025,7 @@ lumpnum_t W_CheckNumForName(const char *name)
|
|||
// most recent entries first
|
||||
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
|
||||
{
|
||||
if (strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0)
|
||||
if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0)
|
||||
{
|
||||
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
|
||||
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
||||
|
@ -1026,7 +1045,7 @@ lumpnum_t W_CheckNumForName(const char *name)
|
|||
{
|
||||
// Update the cache.
|
||||
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
|
||||
strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8);
|
||||
strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32);
|
||||
lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check;
|
||||
|
||||
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
||||
|
@ -1151,7 +1170,7 @@ boolean W_IsLumpWad(lumpnum_t lumpnum)
|
|||
{
|
||||
if (wadfiles[WADFILENUM(lumpnum)]->type == RET_PK3)
|
||||
{
|
||||
const char *lumpfullName = (wadfiles[WADFILENUM(lumpnum)]->lumpinfo + LUMPNUM(lumpnum))->name2;
|
||||
const char *lumpfullName = (wadfiles[WADFILENUM(lumpnum)]->lumpinfo + LUMPNUM(lumpnum))->fullname;
|
||||
|
||||
if (strlen(lumpfullName) < 4)
|
||||
return false; // can't possibly be a WAD can it?
|
||||
|
@ -1169,7 +1188,7 @@ boolean W_IsLumpFolder(UINT16 wad, UINT16 lump)
|
|||
{
|
||||
if (wadfiles[wad]->type == RET_PK3)
|
||||
{
|
||||
const char *name = wadfiles[wad]->lumpinfo[lump].name2;
|
||||
const char *name = wadfiles[wad]->lumpinfo[lump].fullname;
|
||||
|
||||
return (name[strlen(name)-1] == '/'); // folders end in '/'
|
||||
}
|
||||
|
@ -1247,7 +1266,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
{
|
||||
size_t bytesread = fread(dest, 1, size, handle);
|
||||
if (R_IsLumpPNG((UINT8 *)dest, bytesread))
|
||||
W_ThrowPNGError(l->name2, wadfiles[wad]->filename);
|
||||
W_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
|
||||
return bytesread;
|
||||
}
|
||||
#else
|
||||
|
@ -1289,7 +1308,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
Z_Free(decData);
|
||||
#ifdef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)dest, size))
|
||||
W_ThrowPNGError(l->name2, wadfiles[wad]->filename);
|
||||
W_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
|
||||
#endif
|
||||
return size;
|
||||
#else
|
||||
|
@ -1352,7 +1371,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
|
||||
#ifdef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)dest, size))
|
||||
W_ThrowPNGError(l->name2, wadfiles[wad]->filename);
|
||||
W_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
|
|
@ -66,9 +66,10 @@ typedef struct
|
|||
{
|
||||
unsigned long position; // filelump_t filepos
|
||||
unsigned long disksize; // filelump_t size
|
||||
char name[9]; // filelump_t name[]
|
||||
char *name2; // Used by PK3s. Dynamically allocated name.
|
||||
size_t size; // real (uncompressed) size
|
||||
char name[9]; // filelump_t name[] e.g. "LongEntr"
|
||||
char *longname; // e.g. "LongEntryName"
|
||||
char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension"
|
||||
size_t size; // real (uncompressed) size
|
||||
compmethod compression; // lump compression method
|
||||
} lumpinfo_t;
|
||||
|
||||
|
|
|
@ -564,7 +564,7 @@ dontdrawbg:
|
|||
V_DrawTallNum(BASEVIDWIDTH + xoffset4 - 68, 125+yoffset, 0, data.spec.score);
|
||||
|
||||
// Draw continues!
|
||||
if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay
|
||||
if (continuesInSession /* && (data.spec.continues & 0x80) */) // Always draw when continues are a thing
|
||||
{
|
||||
UINT8 continues = data.spec.continues & 0x7F;
|
||||
|
||||
|
|
Loading…
Reference in a new issue