Merge branch 'udmf-next' into udmf-thingargs

# Conflicts:
#	src/p_setup.c
This commit is contained in:
Nev3r 2020-04-22 08:58:40 +02:00
commit 188ad67c58
35 changed files with 770 additions and 907 deletions

View file

@ -15,7 +15,7 @@
* Oogaland
* Rob
* Shadow Hog
* Spherallic
* sphere
* SRB2-Playah
* SSNTails
* SteelT
@ -738,12 +738,6 @@ linedeftypes
flags2text = "[1] Use control sector tag";
flags64text = "[6] No sound effect";
}
65
{
title = "Bridge Thinker <disabled>";
prefix = "(65)";
}
}
polyobject
@ -2214,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";
}

View file

@ -1630,7 +1630,7 @@ udmf
4 = "Subtract light G";
8 = "Subtract light B";
16 = "Subtract light A";
32 = "Subtract light R";
32 = "Subtract fade R";
64 = "Subtract fade G";
128 = "Subtract fade B";
256 = "Subtract fade A";
@ -1670,7 +1670,7 @@ udmf
4 = "Subtract light G";
8 = "Subtract light B";
16 = "Subtract light A";
32 = "Subtract light R";
32 = "Subtract fade R";
64 = "Subtract fade G";
128 = "Subtract fade B";
256 = "Subtract fade A";

View file

@ -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)

View file

@ -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

View file

@ -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();

View file

@ -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"))
{

View file

@ -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
@ -201,11 +203,12 @@ typedef struct
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];

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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 ? &sectors[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);
}
}

View file

@ -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;

View file

@ -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

View file

@ -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;
@ -453,6 +463,11 @@ static int mobj_set(lua_State *L)
localangle = mo->angle;
else if (mo->player == &players[secondarydisplayplayer])
localangle2 = mo->angle;
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);
@ -807,10 +822,16 @@ 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"))
@ -856,10 +877,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"))

View file

@ -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

View file

@ -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);

View file

@ -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));

View file

@ -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

View file

@ -397,7 +397,7 @@ typedef struct
UINT8 numemeralds;
UINT8 numgameovers;
INT32 lives;
INT32 continues;
INT32 continuescore;
INT32 gamemap;
} saveinfo_t;

View file

@ -26,19 +26,6 @@
// FLOORS
// ==========================================================================
//
// Mini-P_IsObjectOnGroundIn for T_MovePlane hack
//
static inline boolean P_MobjReadyToMove(mobj_t *mo, sector_t *sec, boolean sectorisffloor, boolean sectorisquicksand)
{
if (sectorisquicksand)
return (mo->z > sec->floorheight && mo->z < sec->ceilingheight);
else if (!!(mo->flags & MF_SPAWNCEILING) ^ !!(mo->eflags & MFE_VERTICALFLIP))
return ((sectorisffloor) ? (mo->z+mo->height != sec->floorheight) : (mo->z+mo->height != sec->ceilingheight));
else
return ((sectorisffloor) ? (mo->z != sec->ceilingheight) : (mo->z != sec->floorheight));
}
//
// Move a plane (floor or ceiling) and check for crushing
//
@ -48,14 +35,6 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus
boolean flag;
fixed_t lastpos;
fixed_t destheight; // used to keep floors/ceilings from moving through each other
// Stuff used for mobj hacks.
INT32 secnum = -1;
mobj_t *mo = NULL;
sector_t *sec = NULL;
ffloor_t *rover = NULL;
boolean sectorisffloor = false;
boolean sectorisquicksand = false;
sector->moved = true;
switch (floorOrCeiling)
@ -193,83 +172,6 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus
break;
}
// Hack for buggy mobjs to move by gravity with moving planes.
if (sector->tagline)
sectorisffloor = true;
// Optimization condition. If the sector is not an FOF, declare sec as the main sector outside of the loop.
if (!sectorisffloor)
sec = sector;
// Optimization condition. Only run the logic if there is any Things in the sector.
if (sectorisffloor || sec->thinglist)
{
// If this is an FOF being checked, check all the affected sectors for moving mobjs.
while ((sectorisffloor ? (secnum = P_FindSectorFromLineTag(sector->tagline, secnum)) : (secnum = 1)) >= 0)
{
if (sectorisffloor)
{
// Get actual sector from the list of sectors.
sec = &sectors[secnum];
// Can't use P_InQuicksand because it will return the incorrect result
// because of checking for heights.
for (rover = sec->ffloors; rover; rover = rover->next)
{
if (rover->target == sec && (rover->flags & FF_QUICKSAND))
{
sectorisquicksand = true;
break;
}
}
}
for (mo = sec->thinglist; mo; mo = mo->snext)
{
// The object should be ready to move as defined by this function.
if (!P_MobjReadyToMove(mo, sec, sectorisffloor, sectorisquicksand))
continue;
// The object should not be moving at all.
if (mo->momx || mo->momy || mo->momz)
continue;
// These objects will be affected by this condition.
switch (mo->type)
{
case MT_GOOP: // Egg Slimer's goop objects
case MT_SPINFIRE: // Elemental Shield flame balls
case MT_SPIKE: // Floor Spike
// Is the object hang from the ceiling?
// In that case, swap the planes used.
// verticalflip inverts
if (!!(mo->flags & MF_SPAWNCEILING) ^ !!(mo->eflags & MFE_VERTICALFLIP))
{
if (sectorisffloor && !sectorisquicksand)
mo->z = mo->ceilingz - mo->height;
else
mo->z = mo->ceilingz = mo->subsector->sector->ceilingheight - mo->height;
}
else
{
if (sectorisffloor && !sectorisquicksand)
mo->z = mo->floorz;
else
mo->z = mo->floorz = mo->subsector->sector->floorheight;
}
break;
// Kill warnings...
default:
break;
}
}
// Break from loop if there is no FOFs to check.
if (!sectorisffloor)
break;
}
}
return ok;
}
@ -1275,478 +1177,6 @@ void T_FloatSector(levelspecthink_t *floater)
}
}
//
// T_BridgeThinker
//
// Kind of like T_RaiseSector,
// but spreads out across
// multiple FOFs at varying
// intensity.
//
void T_BridgeThinker(levelspecthink_t *bridge)
{
msecnode_t *node;
mobj_t *thing;
sector_t *sector;
sector_t *controlsec = NULL;
INT32 i, k;
INT16 j;
boolean playeronme = false;
fixed_t ceilingdestination = 0, floordestination = 0;
result_e res = 0;
#define ORIGFLOORHEIGHT (bridge->vars[0])
#define ORIGCEILINGHEIGHT (bridge->vars[1])
#define BASESPEED (bridge->vars[2])
#define CURSPEED (bridge->vars[3])
#define STARTTAG ((INT16)bridge->vars[4])
#define ENDTAG ((INT16)bridge->vars[5])
#define DIRECTION (bridge->vars[8])
#define SAGAMT (8*FRACUNIT)
fixed_t lowceilheight = ORIGCEILINGHEIGHT - SAGAMT;
fixed_t lowfloorheight = ORIGFLOORHEIGHT - SAGAMT;
#define LOWCEILINGHEIGHT (lowceilheight)
#define LOWFLOORHEIGHT (lowfloorheight)
#define STARTCONTROLTAG (ENDTAG + 1)
#define ENDCONTROLTAG (ENDTAG + (ENDTAG - STARTTAG) + 1)
// Is someone standing on it?
for (j = STARTTAG; j <= ENDTAG; j++)
{
for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;)
{
sector = &sectors[i];
// Nab the control sector that this sector belongs to.
k = P_FindSectorFromTag((INT16)(j + (ENDTAG-STARTTAG) + 1), -1);
if (k == -1)
break;
controlsec = &sectors[k];
// Is a player standing on me?
for (node = sector->touching_thinglist; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
if (!thing->player)
continue;
if (!(thing->z == controlsec->ceilingheight))
continue;
playeronme = true;
goto wegotit; // Just take the first one?
}
}
}
wegotit:
if (playeronme)
{
// Lower controlsec like a regular T_RaiseSector
// Set the heights of all the other control sectors to
// be a gradient of this height toward the edges
}
else
{
// Raise controlsec like a regular T_RaiseSector
// Set the heights of all the other control sectors to
// be a gradient of this height toward the edges.
}
if (playeronme && controlsec)
{
INT32 dist;
bridge->sector = controlsec;
CURSPEED = BASESPEED;
{
// Translate tags to - 0 + range
/*so you have a number in [min, max].
let range = max - min, subtract min
from your number to get [0, range].
subtract range/2 to get [-range/2, range/2].
take absolute value and get [0, range/2] where
lower number = closer to midpoint. divide by
range/2 to get [0, 1]. subtract that number
from 1 to get [0, 1] with higher number = closer
to midpoint. multiply this by max sag amount*/
INT32 midpoint = STARTCONTROLTAG + ((ENDCONTROLTAG-STARTCONTROLTAG) + 1)/2;
// INT32 tagstart = STARTTAG - midpoint;
// INT32 tagend = ENDTAG - midpoint;
// CONS_Debug(DBG_GAMELOGIC, "tagstart is %d, tagend is %d\n", tagstart, tagend);
// Sag is adjusted by how close you are to the center
dist = ((ENDCONTROLTAG - STARTCONTROLTAG))/2 - abs(bridge->sector->tag - midpoint);
// CONS_Debug(DBG_GAMELOGIC, "Dist is %d\n", dist);
LOWCEILINGHEIGHT -= (SAGAMT) * dist;
LOWFLOORHEIGHT -= (SAGAMT) * dist;
}
// go down
if (bridge->sector->ceilingheight <= LOWCEILINGHEIGHT)
{
bridge->sector->floorheight = LOWCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight);
bridge->sector->ceilingheight = LOWCEILINGHEIGHT;
bridge->sector->ceilspeed = 0;
bridge->sector->floorspeed = 0;
goto dorest;
}
DIRECTION = -1;
ceilingdestination = LOWCEILINGHEIGHT;
floordestination = LOWFLOORHEIGHT;
if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT)
< (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight))
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the bottom
CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
else
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the top
CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
// CONS_Debug(DBG_GAMELOGIC, "Curspeed is %d\n", CURSPEED>>FRACBITS);
res = T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
ceilingdestination, // dest
0, // crush
1, // floor or ceiling (1 for ceiling)
DIRECTION // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
floordestination, // dest
0, // crush
0, // floor or ceiling (0 for floor)
DIRECTION // direction
);
bridge->sector->ceilspeed = 42;
bridge->sector->floorspeed = CURSPEED*DIRECTION;
dorest:
// Adjust joined sector heights
{
sector_t *sourcesec = bridge->sector;
INT32 divisor = sourcesec->tag - ENDTAG + 1;
fixed_t heightdiff = ORIGCEILINGHEIGHT - sourcesec->ceilingheight;
fixed_t interval;
INT32 plusplusme = 0;
if (divisor > 0)
{
interval = heightdiff/divisor;
// CONS_Debug(DBG_GAMELOGIC, "interval is %d\n", interval>>FRACBITS);
// TODO: Use T_MovePlane
for (j = (INT16)(ENDTAG+1); j <= sourcesec->tag; j++, plusplusme++)
{
for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;)
{
if (sectors[i].ceilingheight >= sourcesec->ceilingheight)
{
sectors[i].ceilingheight = ORIGCEILINGHEIGHT - (interval*plusplusme);
sectors[i].floorheight = ORIGFLOORHEIGHT - (interval*plusplusme);
}
else // Do the regular rise
{
bridge->sector = &sectors[i];
CURSPEED = BASESPEED/2;
// rise back up
if (bridge->sector->ceilingheight >= ORIGCEILINGHEIGHT)
{
bridge->sector->floorheight = ORIGCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight);
bridge->sector->ceilingheight = ORIGCEILINGHEIGHT;
bridge->sector->ceilspeed = 0;
bridge->sector->floorspeed = 0;
continue;
}
DIRECTION = 1;
ceilingdestination = ORIGCEILINGHEIGHT;
floordestination = ORIGFLOORHEIGHT;
// CONS_Debug(DBG_GAMELOGIC, "ceildest: %d, floordest: %d\n", ceilingdestination>>FRACBITS, floordestination>>FRACBITS);
if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT)
< (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight))
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the bottom
CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
else
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the top
CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
res = T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
ceilingdestination, // dest
0, // crush
1, // floor or ceiling (1 for ceiling)
DIRECTION // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
floordestination, // dest
0, // crush
0, // floor or ceiling (0 for floor)
DIRECTION // direction
);
bridge->sector->ceilspeed = 42;
bridge->sector->floorspeed = CURSPEED*DIRECTION;
}
}
}
}
// Now the other side
divisor = ENDTAG + (ENDTAG-STARTTAG) + 1;
divisor -= sourcesec->tag;
if (divisor > 0)
{
interval = heightdiff/divisor;
plusplusme = 0;
// CONS_Debug(DBG_GAMELOGIC, "interval2 is %d\n", interval>>FRACBITS);
for (j = (INT16)(sourcesec->tag+1); j <= ENDTAG + (ENDTAG-STARTTAG) + 1; j++, plusplusme++)
{
for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;)
{
if (sectors[i].ceilingheight >= sourcesec->ceilingheight)
{
sectors[i].ceilingheight = sourcesec->ceilingheight + (interval*plusplusme);
sectors[i].floorheight = sourcesec->floorheight + (interval*plusplusme);
}
else // Do the regular rise
{
bridge->sector = &sectors[i];
CURSPEED = BASESPEED/2;
// rise back up
if (bridge->sector->ceilingheight >= ORIGCEILINGHEIGHT)
{
bridge->sector->floorheight = ORIGCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight);
bridge->sector->ceilingheight = ORIGCEILINGHEIGHT;
bridge->sector->ceilspeed = 0;
bridge->sector->floorspeed = 0;
continue;
}
DIRECTION = 1;
ceilingdestination = ORIGCEILINGHEIGHT;
floordestination = ORIGFLOORHEIGHT;
// CONS_Debug(DBG_GAMELOGIC, "ceildest: %d, floordest: %d\n", ceilingdestination>>FRACBITS, floordestination>>FRACBITS);
if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT)
< (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight))
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the bottom
CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
else
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the top
CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
res = T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
ceilingdestination, // dest
0, // crush
1, // floor or ceiling (1 for ceiling)
DIRECTION // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
floordestination, // dest
0, // crush
0, // floor or ceiling (0 for floor)
DIRECTION // direction
);
bridge->sector->ceilspeed = 42;
bridge->sector->floorspeed = CURSPEED*DIRECTION;
}
}
}
}
}
// for (i = -1; (i = P_FindSectorFromTag(bridge->sourceline->tag, i)) >= 0 ;)
// P_RecalcPrecipInSector(&sectors[i]);
}
else
{
// Iterate control sectors
for (j = (INT16)(ENDTAG+1); j <= (ENDTAG+(ENDTAG-STARTTAG)+1); j++)
{
for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;)
{
bridge->sector = &sectors[i];
CURSPEED = BASESPEED/2;
// rise back up
if (bridge->sector->ceilingheight >= ORIGCEILINGHEIGHT)
{
bridge->sector->floorheight = ORIGCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight);
bridge->sector->ceilingheight = ORIGCEILINGHEIGHT;
bridge->sector->ceilspeed = 0;
bridge->sector->floorspeed = 0;
continue;
}
DIRECTION = 1;
ceilingdestination = ORIGCEILINGHEIGHT;
floordestination = ORIGFLOORHEIGHT;
// CONS_Debug(DBG_GAMELOGIC, "ceildest: %d, floordest: %d\n", ceilingdestination>>FRACBITS, floordestination>>FRACBITS);
if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT)
< (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight))
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the bottom
CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
else
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the top
CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
res = T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
ceilingdestination, // dest
0, // crush
1, // floor or ceiling (1 for ceiling)
DIRECTION // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
floordestination, // dest
0, // crush
0, // floor or ceiling (0 for floor)
DIRECTION // direction
);
bridge->sector->ceilspeed = 42;
bridge->sector->floorspeed = CURSPEED*DIRECTION;
}
}
// Update precip
}
#undef SAGAMT
#undef LOWFLOORHEIGHT
#undef LOWCEILINGHEIGHT
#undef ORIGFLOORHEIGHT
#undef ORIGCEILINGHEIGHT
#undef BASESPEED
#undef CURSPEED
#undef STARTTAG
#undef ENDTAG
#undef DIRECTION
}
static mobj_t *SearchMarioNode(msecnode_t *node)
{
mobj_t *thing = NULL;

View file

@ -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
{

View file

@ -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)
static 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,10 +11627,10 @@ 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)
@ -11701,7 +11701,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 +13077,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 +13185,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 +13330,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 +13388,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++)
{

View file

@ -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

View file

@ -787,8 +787,13 @@ static boolean P_AreStringArgsEqual(const line_t *li, const line_t *spawnli)
{
UINT8 i;
for (i = 0; i < NUMLINESTRINGARGS; i++)
{
if (!li->stringargs[i])
return !spawnli->stringargs[i];
if (strcmp(li->stringargs[i], spawnli->stringargs[i]))
return false;
}
return true;
}
@ -1356,7 +1361,6 @@ typedef enum
tc_marioblockchecker,
tc_spikesector,
tc_floatsector,
tc_bridgethinker,
tc_crushceiling,
tc_scroll,
tc_friction,
@ -1447,7 +1451,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)
@ -1629,6 +1635,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)
{
@ -2372,11 +2380,6 @@ static void P_NetArchiveThinkers(void)
SaveSpecialLevelThinker(th, tc_floatsector);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_BridgeThinker)
{
SaveSpecialLevelThinker(th, tc_bridgethinker);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_LaserFlash)
{
SaveLaserThinker(th, tc_laserflash);
@ -2650,12 +2653,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)
{
@ -3568,10 +3575,6 @@ static void P_NetUnArchiveThinkers(void)
th = LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0);
break;
case tc_bridgethinker:
th = LoadSpecialLevelThinker((actionf_p1)T_BridgeThinker, 3);
break;
case tc_laserflash:
th = LoadLaserThinker((actionf_p1)T_LaserFlash);
break;

View file

@ -873,7 +873,6 @@ static void P_InitializeSector(sector_t *ss)
ss->linecount = 0;
ss->lines = NULL;
ss->tagline = NULL;
ss->ffloors = NULL;
ss->attached = NULL;
@ -941,6 +940,8 @@ static void P_LoadSectors(UINT8 *data)
ss->floorpic_angle = ss->ceilingpic_angle = 0;
ss->colormap_protected = false;
P_InitializeSector(ss);
}
}
@ -1125,9 +1126,11 @@ static void P_LoadSidedefs(UINT8 *data)
case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:)
// SoM: R_CreateColormap will only create a colormap in software mode...
// Perhaps we should just call it instead of doing the calculations here.
sd->colormap_data = R_CreateColormap(msd->toptexture, msd->midtexture,
msd->bottomtexture);
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
if (!udmf)
{
sd->colormap_data = R_CreateColormapFromLinedef(msd->toptexture, msd->midtexture, msd->bottomtexture);
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
}
break;
case 413: // Change music
@ -1278,9 +1281,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;
@ -1385,6 +1390,19 @@ static void ParseTextmapVertexParameter(UINT32 i, char *param, char *val)
}
}
typedef struct textmap_colormap_s {
boolean used;
INT32 lightcolor;
UINT8 lightalpha;
INT32 fadecolor;
UINT8 fadealpha;
UINT8 fadestart;
UINT8 fadeend;
UINT8 flags;
} textmap_colormap_t;
textmap_colormap_t textmap_colormap = { false, 0, 25, 0, 25, 0, 31, 0 };
static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val)
{
if (fastcmp(param, "heightfloor"))
@ -1413,6 +1431,48 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val)
sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val)));
else if (fastcmp(param, "rotationceiling"))
sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val)));
else if (fastcmp(param, "lightcolor"))
{
textmap_colormap.used = true;
textmap_colormap.lightcolor = atol(val);
}
else if (fastcmp(param, "lightalpha"))
{
textmap_colormap.used = true;
textmap_colormap.lightalpha = atol(val);
}
else if (fastcmp(param, "fadecolor"))
{
textmap_colormap.used = true;
textmap_colormap.fadecolor = atol(val);
}
else if (fastcmp(param, "fadealpha"))
{
textmap_colormap.used = true;
textmap_colormap.fadealpha = atol(val);
}
else if (fastcmp(param, "fadestart"))
{
textmap_colormap.used = true;
textmap_colormap.fadestart = atol(val);
}
else if (fastcmp(param, "fadeend"))
{
textmap_colormap.used = true;
textmap_colormap.fadeend = atol(val);
}
else if (fastcmp(param, "colormapfog") && fastcmp("true", val))
{
textmap_colormap.used = true;
textmap_colormap.flags |= CMF_FOG;
}
else if (fastcmp(param, "colormapfadesprites") && fastcmp("true", val))
{
textmap_colormap.used = true;
textmap_colormap.flags |= CMF_FADEFULLBRIGHTSPRITES;
}
else if (fastcmp(param, "colormapprotected") && fastcmp("true", val))
sectors[i].colormap_protected = true;
}
static void ParseTextmapSidedefParameter(UINT32 i, char *param, char *val)
@ -1512,9 +1572,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;
@ -1602,6 +1667,14 @@ static void TextmapFixFlatOffsets(sector_t *sec)
}
}
static INT32 P_ColorToRGBA(INT32 color, UINT8 alpha)
{
UINT8 r = (color >> 16) & 0xFF;
UINT8 g = (color >> 8) & 0xFF;
UINT8 b = color & 0xFF;
return R_PutRgbaRGBA(r, g, b, alpha);
}
/** Loads the textmap data, after obtaining the elements count and allocating their respective space.
*/
static void P_LoadTextmap(void)
@ -1655,8 +1728,24 @@ static void P_LoadTextmap(void)
sc->floorpic_angle = sc->ceilingpic_angle = 0;
sc->colormap_protected = false;
textmap_colormap.used = false;
textmap_colormap.lightcolor = 0;
textmap_colormap.lightalpha = 25;
textmap_colormap.fadecolor = 0;
textmap_colormap.fadealpha = 25;
textmap_colormap.fadestart = 0;
textmap_colormap.fadeend = 31;
textmap_colormap.flags = 0;
TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter);
P_InitializeSector(sc);
if (textmap_colormap.used)
{
INT32 rgba = P_ColorToRGBA(textmap_colormap.lightcolor, textmap_colormap.lightalpha);
INT32 fadergba = P_ColorToRGBA(textmap_colormap.fadecolor, textmap_colormap.fadealpha);
sc->extra_colormap = sc->spawn_extra_colormap = R_CreateColormap(rgba, fadergba, textmap_colormap.fadestart, textmap_colormap.fadeend, textmap_colormap.flags);
}
TextmapFixFlatOffsets(sc);
}
@ -1713,6 +1802,7 @@ static void P_LoadTextmap(void)
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));
@ -1731,9 +1821,9 @@ static void P_ProcessLinedefsAfterSidedefs(void)
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
// Compile linedef 'text' from both sidedefs 'text' for appropriate specials.
switch (ld->special)
{
// Compile linedef 'text' from both sidedefs 'text' for appropriate specials.
case 331: // Trigger linedef executor: Skin - Continuous
case 332: // Trigger linedef executor: Skin - Each time
case 333: // Trigger linedef executor: Skin - Once
@ -1749,6 +1839,41 @@ static void P_ProcessLinedefsAfterSidedefs(void)
M_Memcpy(ld->text + strlen(ld->text) + 1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text) + 1);
}
break;
case 447: // Change colormap
case 455: // Fade colormap
if (udmf)
break;
if (ld->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets)
{
extracolormap_t *exc = R_CopyColormap(sides[ld->sidenum[0]].colormap_data, false);
INT16 alpha = max(min(sides[ld->sidenum[0]].textureoffset >> FRACBITS, 25), -25);
INT16 fadealpha = max(min(sides[ld->sidenum[0]].rowoffset >> FRACBITS, 25), -25);
// If alpha is negative, set "subtract alpha" flag and store absolute value
if (alpha < 0)
{
alpha *= -1;
ld->args[2] |= TMCF_SUBLIGHTA;
}
if (fadealpha < 0)
{
fadealpha *= -1;
ld->args[2] |= TMCF_SUBFADEA;
}
exc->rgba = R_GetRgbaRGB(exc->rgba) + R_PutRgbaA(alpha);
exc->fadergba = R_GetRgbaRGB(exc->fadergba) + R_PutRgbaA(fadealpha);
if (!(sides[ld->sidenum[0]].colormap_data = R_GetColormapFromList(exc)))
{
exc->colormap = R_CreateLightTable(exc);
R_AddColormapToList(exc);
sides[ld->sidenum[0]].colormap_data = exc;
}
else
Z_Free(exc);
}
break;
}
}
}
@ -2712,6 +2837,48 @@ static void P_ConvertBinaryMap(void)
else
CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in the front texture fields)\n", sizeu1(i));
break;
case 447: //Change colormap
lines[i].args[0] = lines[i].tag;
if (lines[i].flags & ML_EFFECT3)
lines[i].args[2] |= TMCF_RELATIVE;
if (lines[i].flags & ML_EFFECT1)
lines[i].args[2] |= TMCF_SUBLIGHTR|TMCF_SUBFADER;
if (lines[i].flags & ML_NOCLIMB)
lines[i].args[2] |= TMCF_SUBLIGHTG|TMCF_SUBFADEG;
if (lines[i].flags & ML_EFFECT2)
lines[i].args[2] |= TMCF_SUBLIGHTB|TMCF_SUBFADEB;
break;
case 455: //Fade colormap
{
INT32 speed = (INT32)((((lines[i].flags & ML_DONTPEGBOTTOM) || !sides[lines[i].sidenum[0]].rowoffset) && lines[i].sidenum[1] != 0xFFFF) ?
abs(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS)
: abs(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS));
lines[i].args[0] = lines[i].tag;
if (lines[i].flags & ML_EFFECT4)
lines[i].args[2] = speed;
else
lines[i].args[2] = (256 + speed - 1)/speed;
if (lines[i].flags & ML_EFFECT3)
lines[i].args[3] |= TMCF_RELATIVE;
if (lines[i].flags & ML_EFFECT1)
lines[i].args[3] |= TMCF_SUBLIGHTR|TMCF_SUBFADER;
if (lines[i].flags & ML_NOCLIMB)
lines[i].args[3] |= TMCF_SUBLIGHTG|TMCF_SUBFADEG;
if (lines[i].flags & ML_EFFECT2)
lines[i].args[3] |= TMCF_SUBLIGHTB|TMCF_SUBFADEB;
if (lines[i].flags & ML_BOUNCY)
lines[i].args[3] |= TMCF_FROMBLACK;
if (lines[i].flags & ML_EFFECT5)
lines[i].args[3] |= TMCF_OVERRIDE;
break;
}
case 456: //Stop fading colormap
lines[i].args[0] = lines[i].tag;
break;
case 606: //Colormap
lines[i].args[0] = lines[i].tag;
break;
case 700: //Slope front sector floor
case 701: //Slope front sector ceiling
case 702: //Slope front sector floor and ceiling
@ -2726,13 +2893,13 @@ static void P_ConvertBinaryMap(void)
boolean frontceil = (lines[i].special == 701 || lines[i].special == 702 || lines[i].special == 713);
boolean backceil = (lines[i].special == 711 || lines[i].special == 712 || lines[i].special == 703);
lines[i].args[0] = backfloor ? 2 : (frontfloor ? 1 : 0);
lines[i].args[1] = backceil ? 2 : (frontceil ? 1 : 0);
lines[i].args[0] = backfloor ? TMS_BACK : (frontfloor ? TMS_FRONT : TMS_NONE);
lines[i].args[1] = backceil ? TMS_BACK : (frontceil ? TMS_FRONT : TMS_NONE);
if (lines[i].flags & ML_NETONLY)
lines[i].args[2] |= SL_NOPHYSICS;
lines[i].args[2] |= TMSL_NOPHYSICS;
if (lines[i].flags & ML_NONET)
lines[i].args[2] |= SL_DYNAMIC;
lines[i].args[2] |= TMSL_DYNAMIC;
lines[i].special = 700;
break;
@ -2743,13 +2910,13 @@ static void P_ConvertBinaryMap(void)
case 715: //Slope back sector ceiling by 3 tagged vertices
{
if (lines[i].special == 704)
lines[i].args[0] = 0;
lines[i].args[0] = TMSP_FRONTFLOOR;
else if (lines[i].special == 705)
lines[i].args[0] = 1;
lines[i].args[0] = TMSP_FRONTCEILING;
else if (lines[i].special == 714)
lines[i].args[0] = 2;
lines[i].args[0] = TMSP_BACKFLOOR;
else if (lines[i].special == 715)
lines[i].args[0] = 3;
lines[i].args[0] = TMSP_BACKCEILING;
lines[i].args[1] = lines[i].tag;
@ -2772,9 +2939,9 @@ static void P_ConvertBinaryMap(void)
}
if (lines[i].flags & ML_NETONLY)
lines[i].args[4] |= SL_NOPHYSICS;
lines[i].args[4] |= TMSL_NOPHYSICS;
if (lines[i].flags & ML_NONET)
lines[i].args[4] |= SL_DYNAMIC;
lines[i].args[4] |= TMSL_DYNAMIC;
lines[i].special = 704;
break;

View file

@ -250,14 +250,14 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
vector2_t direction;
fixed_t nx, ny, dz, extent;
boolean frontfloor = line->args[0] == 1;
boolean backfloor = line->args[0] == 2;
boolean frontceil = line->args[1] == 1;
boolean backceil = line->args[1] == 2;
boolean frontfloor = line->args[0] == TMS_FRONT;
boolean backfloor = line->args[0] == TMS_BACK;
boolean frontceil = line->args[1] == TMS_FRONT;
boolean backceil = line->args[1] == TMS_BACK;
UINT8 flags = 0; // Slope flags
if (line->args[2] & 1)
if (line->args[2] & TMSL_NOPHYSICS)
flags |= SL_NOPHYSICS;
if (line->args[2] & 2)
if (line->args[2] & TMSL_DYNAMIC)
flags |= SL_DYNAMIC;
if(!frontfloor && !backfloor && !frontceil && !backceil)
@ -464,26 +464,26 @@ static void line_SpawnViaMapthingVertexes(const int linenum, const boolean spawn
UINT16 tag2 = line->args[2];
UINT16 tag3 = line->args[3];
UINT8 flags = 0; // Slope flags
if (line->args[4] & 1)
if (line->args[4] & TMSL_NOPHYSICS)
flags |= SL_NOPHYSICS;
if (line->args[4] & 2)
if (line->args[4] & TMSL_DYNAMIC)
flags |= SL_DYNAMIC;
switch(line->args[0])
{
case 0:
case TMSP_FRONTFLOOR:
slopetoset = &line->frontsector->f_slope;
side = &sides[line->sidenum[0]];
break;
case 1:
case TMSP_FRONTCEILING:
slopetoset = &line->frontsector->c_slope;
side = &sides[line->sidenum[0]];
break;
case 2:
case TMSP_BACKFLOOR:
slopetoset = &line->backsector->f_slope;
side = &sides[line->sidenum[1]];
break;
case 3:
case TMSP_BACKCEILING:
slopetoset = &line->backsector->c_slope;
side = &sides[line->sidenum[1]];
default:
@ -605,13 +605,13 @@ void P_CopySectorSlope(line_t *line)
setback |= P_SetSlopeFromTag(bsec, line->args[2], false);
setback |= P_SetSlopeFromTag(bsec, line->args[3], true);
if (line->args[4] & 1)
if (line->args[4] & TMSC_FRONTTOBACKFLOOR)
setback |= P_CopySlope(&bsec->f_slope, fsec->f_slope);
if (line->args[4] & 2)
if (line->args[4] & TMSC_BACKTOFRONTFLOOR)
setfront |= P_CopySlope(&fsec->f_slope, bsec->f_slope);
if (line->args[4] & 4)
if (line->args[4] & TMSC_FRONTTOBACKCEILING)
setback |= P_CopySlope(&bsec->c_slope, fsec->c_slope);
if (line->args[4] & 8)
if (line->args[4] & TMSC_BACKTOFRONTCEILING)
setfront |= P_CopySlope(&fsec->c_slope, bsec->c_slope);
}

View file

@ -18,6 +18,35 @@
extern pslope_t *slopelist;
extern UINT16 slopecount;
typedef enum
{
TMSP_FRONTFLOOR,
TMSP_FRONTCEILING,
TMSP_BACKFLOOR,
TMSP_BACKCEILING,
} textmapslopeplane_t;
typedef enum
{
TMSC_FRONTTOBACKFLOOR = 1,
TMSC_BACKTOFRONTFLOOR = 1<<1,
TMSC_FRONTTOBACKCEILING = 1<<2,
TMSC_BACKTOFRONTCEILING = 1<<3,
} textmapslopecopy_t;
typedef enum
{
TMS_NONE,
TMS_FRONT,
TMS_BACK,
} textmapside_t;
typedef enum
{
TMSL_NOPHYSICS = 1,
TMSL_DYNAMIC = 2,
} textmapslopeflags_t;
void P_LinkSlopeThinkers (void);
void P_CalculateSlopeNormal(pslope_t *slope);

View file

@ -2041,7 +2041,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
INT32 triggercolor = (INT32)sides[triggerline->sidenum[0]].toptexture;
UINT8 color = (actor->player ? actor->player->powers[pw_dye] : actor->color);
boolean invert = (triggerline->flags & ML_NOCLIMB ? true : false);
if (invert ^ (triggercolor != color))
return false;
}
@ -3505,46 +3505,53 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
// Except it is activated by linedef executor, not level load
// This could even override existing colormaps I believe
// -- Monster Iestyn 14/06/18
for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;)
{
extracolormap_t *source;
if (!udmf)
source = sides[line->sidenum[0]].colormap_data;
else
{
if (!line->args[1])
source = line->frontsector->extra_colormap;
else
{
INT32 sourcesec = P_FindSectorFromTag(line->args[1], -1);
if (sourcesec == -1)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 447 Executor: Can't find sector with source colormap (tag %d)!\n", line->args[1]);
return;
}
source = sectors[sourcesec].extra_colormap;
}
}
for (secnum = -1; (secnum = P_FindSectorFromTag(line->args[0], secnum)) >= 0;)
{
if (sectors[secnum].colormap_protected)
continue;
P_ResetColormapFader(&sectors[secnum]);
if (line->flags & ML_EFFECT3) // relative calc
if (line->args[2] & TMCF_RELATIVE)
{
extracolormap_t *exc = R_AddColormaps(
(line->flags & ML_TFERLINE) && line->sidenum[1] != 0xFFFF ?
sides[line->sidenum[1]].colormap_data : sectors[secnum].extra_colormap, // use back colormap instead of target sector
sides[line->sidenum[0]].colormap_data,
line->flags & ML_EFFECT1, // subtract R
line->flags & ML_NOCLIMB, // subtract G
line->flags & ML_EFFECT2, // subtract B
false, // subtract A (no flag for this, just pass negative alpha)
line->flags & ML_EFFECT1, // subtract FadeR
line->flags & ML_NOCLIMB, // subtract FadeG
line->flags & ML_EFFECT2, // subtract FadeB
false, // subtract FadeA (no flag for this, just pass negative alpha)
false, // subtract FadeStart (we ran out of flags)
false, // subtract FadeEnd (we ran out of flags)
false, // ignore Flags (we ran out of flags)
line->flags & ML_DONTPEGBOTTOM,
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].textureoffset >> FRACBITS) : 0,
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].rowoffset >> FRACBITS) : 0,
false);
extracolormap_t *target = (!udmf && (line->flags & ML_TFERLINE) && line->sidenum[1] != 0xFFFF) ?
sides[line->sidenum[1]].colormap_data : sectors[secnum].extra_colormap; // use back colormap instead of target sector
if (!(sectors[secnum].extra_colormap = R_GetColormapFromList(exc)))
{
exc->colormap = R_CreateLightTable(exc);
R_AddColormapToList(exc);
sectors[secnum].extra_colormap = exc;
}
else
Z_Free(exc);
}
else if (line->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets)
{
extracolormap_t *exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false);
exc->rgba = R_GetRgbaRGB(exc->rgba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].textureoffset >> FRACBITS, 25), 0));
exc->fadergba = R_GetRgbaRGB(exc->fadergba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].rowoffset >> FRACBITS, 25), 0));
extracolormap_t *exc = R_AddColormaps(
target,
source,
line->args[2] & TMCF_SUBLIGHTR,
line->args[2] & TMCF_SUBLIGHTG,
line->args[2] & TMCF_SUBLIGHTB,
line->args[2] & TMCF_SUBLIGHTA,
line->args[2] & TMCF_SUBFADER,
line->args[2] & TMCF_SUBFADEG,
line->args[2] & TMCF_SUBFADEB,
line->args[2] & TMCF_SUBFADEA,
line->args[2] & TMCF_SUBFADESTART,
line->args[2] & TMCF_SUBFADEEND,
line->args[2] & TMCF_IGNOREFLAGS,
false);
if (!(sectors[secnum].extra_colormap = R_GetColormapFromList(exc)))
{
@ -3556,10 +3563,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
Z_Free(exc);
}
else
sectors[secnum].extra_colormap = sides[line->sidenum[0]].colormap_data;
sectors[secnum].extra_colormap = source;
}
break;
}
case 448: // Change skybox viewpoint/centerpoint
if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB))
{
@ -3833,15 +3840,35 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
}
case 455: // Fade colormap
for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;)
{
extracolormap_t *dest;
if (!udmf)
dest = sides[line->sidenum[0]].colormap_data;
else
{
if (!line->args[1])
dest = line->frontsector->extra_colormap;
else
{
INT32 destsec = P_FindSectorFromTag(line->args[1], -1);
if (destsec == -1)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 455 Executor: Can't find sector with destination colormap (tag %d)!\n", line->args[1]);
return;
}
dest = sectors[destsec].extra_colormap;
}
}
for (secnum = -1; (secnum = P_FindSectorFromTag(line->args[0], secnum)) >= 0;)
{
extracolormap_t *source_exc, *dest_exc, *exc;
INT32 speed = (INT32)((line->flags & ML_DONTPEGBOTTOM) || !sides[line->sidenum[0]].rowoffset) && line->sidenum[1] != 0xFFFF ?
abs(sides[line->sidenum[1]].rowoffset >> FRACBITS)
: abs(sides[line->sidenum[0]].rowoffset >> FRACBITS);
// Prevent continuous execs from interfering on an existing fade
if (!(line->flags & ML_EFFECT5)
if (sectors[secnum].colormap_protected)
continue;
// Don't interrupt ongoing fade
if (!(line->args[3] & TMCF_OVERRIDE)
&& sectors[secnum].fadecolormapdata)
//&& ((fadecolormap_t*)sectors[secnum].fadecolormapdata)->timer > (ticbased ? 2 : speed*2))
{
@ -3849,19 +3876,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
continue;
}
if (line->flags & ML_TFERLINE) // use back colormap instead of target sector
if (!udmf && (line->flags & ML_TFERLINE)) // use back colormap instead of target sector
sectors[secnum].extra_colormap = (line->sidenum[1] != 0xFFFF) ?
sides[line->sidenum[1]].colormap_data : NULL;
sides[line->sidenum[1]].colormap_data : NULL;
exc = sectors[secnum].extra_colormap;
if (!(line->flags & ML_BOUNCY) // BOUNCY: Do not override fade from default rgba
&& !R_CheckDefaultColormap(sides[line->sidenum[0]].colormap_data, true, false, false)
if (!(line->args[3] & TMCF_FROMBLACK) // Override fade from default rgba
&& !R_CheckDefaultColormap(dest, true, false, false)
&& R_CheckDefaultColormap(exc, true, false, false))
{
exc = R_CopyColormap(exc, false);
exc->rgba = R_GetRgbaRGB(sides[line->sidenum[0]].colormap_data->rgba) + R_PutRgbaA(R_GetRgbaA(exc->rgba));
//exc->fadergba = R_GetRgbaRGB(sides[line->sidenum[0]].colormap_data->rgba) + R_PutRgbaA(R_GetRgbaA(exc->fadergba));
exc->rgba = R_GetRgbaRGB(dest->rgba) + R_PutRgbaA(R_GetRgbaA(exc->rgba));
//exc->fadergba = R_GetRgbaRGB(dest->rgba) + R_PutRgbaA(R_GetRgbaA(exc->fadergba));
if (!(source_exc = R_GetColormapFromList(exc)))
{
@ -3877,35 +3904,26 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
else
source_exc = exc ? exc : R_GetDefaultColormap();
if (line->flags & ML_EFFECT3) // relative calc
if (line->args[3] & TMCF_RELATIVE)
{
exc = R_AddColormaps(
source_exc,
sides[line->sidenum[0]].colormap_data,
line->flags & ML_EFFECT1, // subtract R
line->flags & ML_NOCLIMB, // subtract G
line->flags & ML_EFFECT2, // subtract B
false, // subtract A (no flag for this, just pass negative alpha)
line->flags & ML_EFFECT1, // subtract FadeR
line->flags & ML_NOCLIMB, // subtract FadeG
line->flags & ML_EFFECT2, // subtract FadeB
false, // subtract FadeA (no flag for this, just pass negative alpha)
false, // subtract FadeStart (we ran out of flags)
false, // subtract FadeEnd (we ran out of flags)
false, // ignore Flags (we ran out of flags)
line->flags & ML_DONTPEGBOTTOM,
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].textureoffset >> FRACBITS) : 0,
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].rowoffset >> FRACBITS) : 0,
dest,
line->args[3] & TMCF_SUBLIGHTR,
line->args[3] & TMCF_SUBLIGHTG,
line->args[3] & TMCF_SUBLIGHTB,
line->args[3] & TMCF_SUBLIGHTA,
line->args[3] & TMCF_SUBFADER,
line->args[3] & TMCF_SUBFADEG,
line->args[3] & TMCF_SUBFADEB,
line->args[3] & TMCF_SUBFADEA,
line->args[3] & TMCF_SUBFADESTART,
line->args[3] & TMCF_SUBFADEEND,
line->args[3] & TMCF_IGNOREFLAGS,
false);
}
else if (line->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets)
{
exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false);
exc->rgba = R_GetRgbaRGB(exc->rgba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].textureoffset >> FRACBITS, 25), 0));
exc->fadergba = R_GetRgbaRGB(exc->fadergba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].rowoffset >> FRACBITS, 25), 0));
}
else
exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false);
exc = R_CopyColormap(dest, false);
if (!(dest_exc = R_GetColormapFromList(exc)))
{
@ -3916,13 +3934,13 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
else
Z_Free(exc);
Add_ColormapFader(&sectors[secnum], source_exc, dest_exc, (line->flags & ML_EFFECT4), // tic-based timing
speed);
Add_ColormapFader(&sectors[secnum], source_exc, dest_exc, true, // tic-based timing
line->args[2]);
}
break;
}
case 456: // Stop fade colormap
for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;)
for (secnum = -1; (secnum = P_FindSectorFromTag(line->args[0], secnum)) >= 0 ;)
P_ResetColormapFader(&sectors[secnum]);
break;
@ -4027,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);
}
@ -4050,23 +4072,23 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
}
}
break;
case 463: // Dye object
{
INT32 color = sides[line->sidenum[0]].toptexture;
if (mo)
{
if (color < 0 || color >= MAXTRANSLATIONS)
return;
var1 = 0;
var2 = color;
A_Dye(mo);
}
}
break;
#ifdef POLYOBJECTS
case 480: // Polyobj_DoorSlide
case 481: // Polyobj_DoorSwing
@ -5772,8 +5794,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
sec2->floorheight = tempceiling;
}
sec2->tagline = master;
if (sec2->numattached == 0)
{
sec2->attached = Z_Malloc(sizeof (*sec2->attached) * sec2->maxattached, PU_STATIC, NULL);
@ -5975,39 +5995,6 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
floater->sourceline = sourceline;
}
/** Adds a bridge thinker.
* Bridge thinkers cause a group of FOFs to behave like
* a bridge made up of pieces, that bows under weight.
*
* \param sec Control sector.
* \sa P_SpawnSpecials, T_BridgeThinker
* \author SSNTails <http://www.ssntails.org>
*/
/*
static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec)
{
levelspecthink_t *bridge;
// create an initialize new thinker
bridge = Z_Calloc(sizeof (*bridge), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &bridge->thinker);
bridge->thinker.function.acp1 = (actionf_p1)T_BridgeThinker;
bridge->sector = sec;
bridge->vars[0] = sourceline->frontsector->floorheight;
bridge->vars[1] = sourceline->frontsector->ceilingheight;
bridge->vars[2] = P_AproxDistance(sourceline->dx, sourceline->dy); // Speed
bridge->vars[2] = FixedDiv(bridge->vars[2], 16*FRACUNIT);
bridge->vars[3] = bridge->vars[2];
// Start tag and end tag are TARGET SECTORS, not CONTROL SECTORS
// Control sector tags should be End_Tag + (End_Tag - Start_Tag)
bridge->vars[4] = sourceline->tag; // Start tag
bridge->vars[5] = (sides[sourceline->sidenum[0]].textureoffset>>FRACBITS); // End tag
}
*/
/**
* Adds a plane displacement thinker.
* Whenever the "control" sector moves,
@ -6753,13 +6740,6 @@ void P_SpawnSpecials(boolean fromnetsave)
}
break;
case 65: // Bridge Thinker
/*
// Disable this until it's working right!
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
P_AddBridgeThinker(&lines[i], &sectors[s]);*/
break;
case 66: // Displace floor by front sector
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB));
@ -7287,7 +7267,7 @@ void P_SpawnSpecials(boolean fromnetsave)
case 331:
case 333:
break;
// Object dye executors
case 334:
case 336:
@ -7423,8 +7403,32 @@ void P_SpawnSpecials(boolean fromnetsave)
break;
case 606: // HACK! Copy colormaps. Just plain colormaps.
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = sides[lines[i].sidenum[0]].colormap_data;
for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0], s)) >= 0;)
{
extracolormap_t *exc;
if (sectors[s].colormap_protected)
continue;
if (!udmf)
exc = sides[lines[i].sidenum[0]].colormap_data;
else
{
if (!lines[i].args[1])
exc = lines[i].frontsector->extra_colormap;
else
{
INT32 sourcesec = P_FindSectorFromTag(lines[i].args[1], -1);
if (sourcesec == -1)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 606: Can't find sector with source colormap (tag %d)!\n", lines[i].args[1]);
return;
}
exc = sectors[sourcesec].extra_colormap;
}
}
sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = exc;
}
break;
default:
@ -8361,7 +8365,7 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor
d->destlightlevel = -1;
// Set a separate thinker for colormap fading
if (docolormap && !(rover->flags & FF_NOSHADE) && sectors[rover->secnum].spawn_extra_colormap)
if (docolormap && !(rover->flags & FF_NOSHADE) && sectors[rover->secnum].spawn_extra_colormap && !sectors[rover->secnum].colormap_protected)
{
extracolormap_t *dest_exc,
*source_exc = sectors[rover->secnum].extra_colormap ? sectors[rover->secnum].extra_colormap : R_GetDefaultColormap();

View file

@ -354,7 +354,6 @@ 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_BridgeThinker(levelspecthink_t *bridge);
void T_MarioBlockChecker(levelspecthink_t *block);
void T_ThwompSector(levelspecthink_t *thwomp);
void T_NoEnemiesSector(levelspecthink_t *nobaddies);

View file

@ -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;
@ -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

View file

@ -2043,7 +2043,7 @@ extracolormap_t *R_ColormapForName(char *name)
#endif
//
// R_CreateColormap
// R_CreateColormapFromLinedef
//
// This is a more GL friendly way of doing colormaps: Specify colormap
// data in a special linedef's texture areas and use that to generate
@ -2182,10 +2182,8 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
return lighttable;
}
extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3)
{
extracolormap_t *extra_colormap, *exc;
// default values
UINT8 cr = 0, cg = 0, cb = 0, ca = 0, cfr = 0, cfg = 0, cfb = 0, cfa = 25;
UINT32 fadestart = 0, fadeend = 31;
@ -2308,6 +2306,13 @@ extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
rgba = R_PutRgbaRGBA(cr, cg, cb, ca);
fadergba = R_PutRgbaRGBA(cfr, cfg, cfb, cfa);
return R_CreateColormap(rgba, fadergba, fadestart, fadeend, flags);
}
extracolormap_t *R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags)
{
extracolormap_t *extra_colormap;
// Did we just make a default colormap?
#ifdef EXTRACOLORMAPLUMPS
if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, flags, LUMPERROR))
@ -2319,17 +2324,16 @@ extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
// Look for existing colormaps
#ifdef EXTRACOLORMAPLUMPS
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags, LUMPERROR);
extra_colormap = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags, LUMPERROR);
#else
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags);
extra_colormap = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags);
#endif
if (exc)
return exc;
if (extra_colormap)
return extra_colormap;
CONS_Debug(DBG_RENDER, "Creating Colormap: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n",
cr, cg, cb, ca, cfr, cfg, cfb, cfa);
CONS_Debug(DBG_RENDER, "Creating Colormap: rgba(%x) fadergba(%x)\n", rgba, fadergba);
extra_colormap = Z_Calloc(sizeof (*extra_colormap), PU_LEVEL, NULL);
extra_colormap = Z_Calloc(sizeof(*extra_colormap), PU_LEVEL, NULL);
extra_colormap->fadestart = (UINT16)fadestart;
extra_colormap->fadeend = (UINT16)fadeend;
@ -2361,7 +2365,6 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex
boolean subR, boolean subG, boolean subB, boolean subA,
boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA,
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFlags,
boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha,
boolean lighttable)
{
INT16 red, green, blue, alpha;
@ -2397,7 +2400,7 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex
* R_GetRgbaB(exc_addend->rgba)
, 255), 0);
alpha = useAltAlpha ? altAlpha : R_GetRgbaA(exc_addend->rgba);
alpha = R_GetRgbaA(exc_addend->rgba);
alpha = max(min(R_GetRgbaA(exc_augend->rgba) + (subA ? -1 : 1) * alpha, 25), 0);
exc_augend->rgba = R_PutRgbaRGBA(red, green, blue, alpha);
@ -2424,8 +2427,8 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex
* R_GetRgbaB(exc_addend->fadergba)
, 255), 0);
alpha = useAltAlpha ? altFadeAlpha : R_GetRgbaA(exc_addend->fadergba);
if (alpha == 25 && !useAltAlpha && !R_GetRgbaRGB(exc_addend->fadergba))
alpha = R_GetRgbaA(exc_addend->fadergba);
if (alpha == 25 && !R_GetRgbaRGB(exc_addend->fadergba))
alpha = 0; // HACK: fadergba A defaults at 25, so don't add anything in this case
alpha = max(min(R_GetRgbaA(exc_augend->fadergba) + (subFadeA ? -1 : 1) * alpha, 25), 0);

View file

@ -146,13 +146,31 @@ boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgb
boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams);
extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap);
typedef enum
{
TMCF_RELATIVE = 1,
TMCF_SUBLIGHTR = 1<<1,
TMCF_SUBLIGHTG = 1<<2,
TMCF_SUBLIGHTB = 1<<3,
TMCF_SUBLIGHTA = 1<<4,
TMCF_SUBFADER = 1<<5,
TMCF_SUBFADEG = 1<<6,
TMCF_SUBFADEB = 1<<7,
TMCF_SUBFADEA = 1<<8,
TMCF_SUBFADESTART = 1<<9,
TMCF_SUBFADEEND = 1<<10,
TMCF_IGNOREFLAGS = 1<<11,
TMCF_FROMBLACK = 1<<12,
TMCF_OVERRIDE = 1<<13,
} textmapcolormapflags_t;
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap);
extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3);
extracolormap_t * R_CreateColormapFromLinedef(char *p1, char *p2, char *p3);
extracolormap_t* R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags);
extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend,
boolean subR, boolean subG, boolean subB, boolean subA,
boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA,
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFlags,
boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha,
boolean lighttable);
#ifdef EXTRACOLORMAPLUMPS
extracolormap_t *R_ColormapForName(char *name);

View file

@ -328,11 +328,6 @@ typedef struct sector_s
size_t linecount;
struct line_s **lines; // [linecount] size
// Hack: store special line tagging to some sectors
// to efficiently help work around bugs by directly
// referencing the specific line that the problem happens in.
// (used in T_MovePlane mobj physics)
struct line_s *tagline;
// Improved fake floor hack
ffloor_t *ffloors;
@ -346,6 +341,7 @@ typedef struct sector_s
// per-sector colormaps!
extracolormap_t *extra_colormap;
boolean colormap_protected;
#ifdef HWRENDER // ----- for special tricks with HW renderer -----
boolean pseudoSector;

View file

@ -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;