Merge branch 'next' into patch-1

This commit is contained in:
frozenLake 2017-01-11 10:49:37 -05:00 committed by GitHub
commit d865877ca2
26 changed files with 568 additions and 406 deletions

View file

@ -868,12 +868,13 @@ static inline void resynch_write_others(resynchend_pak *rst)
{
UINT8 i;
rst->ingame = rst->ctfteam = 0;
rst->ingame = 0;
for (i = 0; i < MAXPLAYERS; ++i)
{
if (!playeringame[i])
{
rst->ctfteam[i] = 0;
rst->score[i] = 0;
rst->numboxes[i] = 0;
rst->totalring[i] = 0;
@ -883,11 +884,8 @@ static inline void resynch_write_others(resynchend_pak *rst)
}
if (!players[i].spectator)
{
rst->ingame |= (1<<i);
if (players[i].ctfteam > 1)
rst->ctfteam |= (1<<i);
}
rst->ctfteam[i] = (INT32)LONG(players[i].ctfteam);
rst->score[i] = (UINT32)LONG(players[i].score);
rst->numboxes[i] = SHORT(players[i].numboxes);
rst->totalring[i] = SHORT(players[i].totalring);
@ -897,28 +895,18 @@ static inline void resynch_write_others(resynchend_pak *rst)
// endian safeness
rst->ingame = (UINT32)LONG(rst->ingame);
rst->ctfteam = (UINT32)LONG(rst->ctfteam);
}
static inline void resynch_read_others(resynchend_pak *p)
{
UINT8 i;
UINT32 loc_ingame = (UINT32)LONG(p->ingame);
UINT32 loc_ctfteam = (UINT32)LONG(p->ctfteam);
for (i = 0; i < MAXPLAYERS; ++i)
{
// We don't care if they're in the game or not, just write all the data.
if (loc_ingame & (1<<i))
{
players[i].spectator = false;
players[i].ctfteam = (loc_ctfteam & (1<<i)) ? 2 : 1;
}
else
{
players[i].spectator = true;
players[i].ctfteam = 0;
}
players[i].spectator = !(loc_ingame & i<<i);
players[i].ctfteam = (INT32)LONG(p->ctfteam[i]); // no, 0 does not mean spectator, at least not in Match
players[i].score = (UINT32)LONG(p->score[i]);
players[i].numboxes = SHORT(p->numboxes[i]);
players[i].totalring = SHORT(p->totalring[i]);

View file

@ -133,7 +133,7 @@ typedef struct
fixed_t flagz[2];
UINT32 ingame; // Spectator bit for each player
UINT32 ctfteam; // If not spectator, then which team?
INT32 ctfteam[MAXPLAYERS]; // Which team? (can't be 1 bit, since in regular Match there are no teams)
// Resynch game scores and the like all at once
UINT32 score[MAXPLAYERS]; // Everyone's score

View file

@ -3989,7 +3989,7 @@ static void Command_Archivetest_f(void)
}
// assign mobjnum
i = 0;
i = 1;
for (th = thinkercap.next; th != &thinkercap; th = th->next)
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
((mobj_t *)th)->mobjnum = i++;
@ -4091,8 +4091,7 @@ static void Skin_OnChange(void)
if (!Playing())
return; // do whatever you want
if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player.
&& (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CONTINUING))
if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
{
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return;

View file

@ -45,7 +45,7 @@
#include "hw_md2.h"
#define R_FAKEFLOORS
//#define HWPRECIP
#define HWPRECIP
#define SORTING
//#define POLYSKY
@ -1558,6 +1558,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
if (gr_backsector)
{
INT32 gr_toptexture, gr_bottomtexture;
// two sided line
if (gr_backsector->heightsec != -1)
{
@ -1608,19 +1609,22 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
#endif
}
gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture);
gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture);
// check TOP TEXTURE
if ((
#ifdef ESLOPE
worldhighslope < worldtopslope ||
#endif
worldhigh < worldtop
) && texturetranslation[gr_sidedef->toptexture])
) && gr_toptexture)
{
if (drawtextured)
{
fixed_t texturevpegtop; // top
grTex = HWR_GetTexture(texturetranslation[gr_sidedef->toptexture]);
grTex = HWR_GetTexture(gr_toptexture);
// PEGGING
if (gr_linedef->flags & ML_DONTPEGTOP)
@ -1638,7 +1642,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
texturevpegtop += gr_sidedef->rowoffset;
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
texturevpegtop %= SHORT(textures[texturetranslation[gr_sidedef->toptexture]]->height)<<FRACBITS;
texturevpegtop %= SHORT(textures[gr_toptexture]->height)<<FRACBITS;
wallVerts[3].t = wallVerts[2].t = texturevpegtop * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpegtop + gr_frontsector->ceilingheight - gr_backsector->ceilingheight) * grTex->scaleY;
@ -1683,9 +1687,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
#endif
if (gr_frontsector->numlights)
HWR_SplitWall(gr_frontsector, wallVerts, texturetranslation[gr_sidedef->toptexture], &Surf, FF_CUTSOLIDS);
HWR_SplitWall(gr_frontsector, wallVerts, gr_toptexture, &Surf, FF_CUTSOLIDS);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, texturetranslation[gr_sidedef->toptexture], PF_Environment, false, lightnum, colormap);
HWR_AddTransparentWall(wallVerts, &Surf, gr_toptexture, PF_Environment, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
}
@ -1695,13 +1699,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
#ifdef ESLOPE
worldlowslope > worldbottomslope ||
#endif
worldlow > worldbottom) && texturetranslation[gr_sidedef->bottomtexture]) //only if VISIBLE!!!
worldlow > worldbottom) && gr_bottomtexture) //only if VISIBLE!!!
{
if (drawtextured)
{
fixed_t texturevpegbottom = 0; // bottom
grTex = HWR_GetTexture(texturetranslation[gr_sidedef->bottomtexture]);
grTex = HWR_GetTexture(gr_bottomtexture);
// PEGGING
#ifdef ESLOPE
@ -1721,7 +1725,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
texturevpegbottom += gr_sidedef->rowoffset;
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
texturevpegbottom %= SHORT(textures[texturetranslation[gr_sidedef->bottomtexture]]->height)<<FRACBITS;
texturevpegbottom %= SHORT(textures[gr_bottomtexture]->height)<<FRACBITS;
wallVerts[3].t = wallVerts[2].t = texturevpegbottom * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + gr_backsector->floorheight - gr_frontsector->floorheight) * grTex->scaleY;
@ -1766,13 +1770,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
#endif
if (gr_frontsector->numlights)
HWR_SplitWall(gr_frontsector, wallVerts, texturetranslation[gr_sidedef->bottomtexture], &Surf, FF_CUTSOLIDS);
HWR_SplitWall(gr_frontsector, wallVerts, gr_bottomtexture, &Surf, FF_CUTSOLIDS);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, texturetranslation[gr_sidedef->bottomtexture], PF_Environment, false, lightnum, colormap);
HWR_AddTransparentWall(wallVerts, &Surf, gr_bottomtexture, PF_Environment, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
}
gr_midtexture = texturetranslation[gr_sidedef->midtexture];
gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture);
if (gr_midtexture)
{
FBITFIELD blendmode;
@ -2134,7 +2138,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
else
{
// Single sided line... Deal only with the middletexture (if one exists)
gr_midtexture = texturetranslation[gr_sidedef->midtexture];
gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture);
if (gr_midtexture)
{
if (drawtextured)
@ -2232,13 +2236,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
continue;
texnum = texturetranslation[sides[rover->master->sidenum[0]].midtexture];
texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture);
if (rover->master->flags & ML_TFERLINE)
{
size_t linenum = gr_curline->linedef-gr_backsector->lines[0];
newline = rover->master->frontsector->lines[0] + linenum;
texnum = texturetranslation[sides[newline->sidenum[0]].midtexture];
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture);
}
#ifdef ESLOPE
@ -2366,13 +2370,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
continue;
texnum = texturetranslation[sides[rover->master->sidenum[0]].midtexture];
texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture);
if (rover->master->flags & ML_TFERLINE)
{
size_t linenum = gr_curline->linedef-gr_backsector->lines[0];
newline = rover->master->frontsector->lines[0] + linenum;
texnum = texturetranslation[sides[newline->sidenum[0]].midtexture];
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture);
}
#ifdef ESLOPE //backsides
h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight;
@ -4401,7 +4405,6 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
FOutVector *wv;
GLPatch_t *gpatch; // sprite patch converted to hardware
FSurfaceInfo Surf;
sector_t *sector;
if (!spr->mobj)
return;
@ -4455,19 +4458,38 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
//Hurdler: 25/04/2000: now support colormap in hardware mode
HWR_GetMappedPatch(gpatch, spr->colormap);
sector = spr->mobj->subsector->sector;
if (sector->ffloors)
// colormap test
{
ffloor_t *caster = sector->lightlist[R_GetPlaneLight(sector, spr->mobj->z, false)].caster;
sector = caster ? &sectors[caster->secnum] : sector;
sector_t *sector = spr->mobj->subsector->sector;
UINT8 lightlevel = 255;
extracolormap_t *colormap = sector->extra_colormap;
if (sector->numlights)
{
INT32 light;
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel;
if (sector->lightlist[light].extra_colormap)
colormap = sector->lightlist[light].extra_colormap;
}
else
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel;
if (sector->extra_colormap)
colormap = sector->extra_colormap;
}
// sprite lighting by modulating the RGB components
if (sector->extra_colormap)
Surf.FlatColor.rgba = HWR_Lighting(spr->sectorlight,sector->extra_colormap->rgba,sector->extra_colormap->fadergba, false, false);
if (colormap)
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false);
else
Surf.FlatColor.rgba = HWR_Lighting(spr->sectorlight,NORMALFOG,FADEFOG, false, false);
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
}
if (spr->mobj->flags2 & MF2_SHADOW)
{
@ -5289,6 +5311,11 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
//
vis = HWR_NewVisSprite();
vis->x1 = x1;
#if 0
vis->x2 = x2;
#else
(void)x2;
#endif
vis->x2 = tx;
vis->tz = tz;
vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
@ -5301,7 +5328,6 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
// set top/bottom coords
vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset) - gr_viewz;
vis->sectorlight = 0xff;
vis->precip = true;
}
#endif

View file

@ -369,6 +369,8 @@ static int libd_drawScaled(lua_State *L)
x = luaL_checkinteger(L, 1);
y = luaL_checkinteger(L, 2);
scale = luaL_checkinteger(L, 3);
if (scale < 0)
return luaL_error(L, "negative scale");
patch = *((patch_t **)luaL_checkudata(L, 4, META_PATCH));
flags = luaL_optinteger(L, 5, 0);
if (!lua_isnoneornil(L, 6))

View file

@ -348,22 +348,12 @@ static int sector_get(lua_State *L)
case sector_ceilingheight:
lua_pushfixed(L, sector->ceilingheight);
return 1;
case sector_floorpic: { // floorpic
levelflat_t *levelflat;
INT16 i;
for (i = 0, levelflat = levelflats; i != sector->floorpic; i++, levelflat++)
;
lua_pushlstring(L, levelflat->name, 8);
case sector_floorpic: // floorpic
lua_pushlstring(L, levelflats[sector->floorpic].name, 8);
return 1;
}
case sector_ceilingpic: { // ceilingpic
levelflat_t *levelflat;
INT16 i;
for (i = 0, levelflat = levelflats; i != sector->ceilingpic; i++, levelflat++)
;
lua_pushlstring(L, levelflat->name, 8);
case sector_ceilingpic: // ceilingpic
lua_pushlstring(L, levelflats[sector->ceilingpic].name, 8);
return 1;
}
case sector_lightlevel:
lua_pushinteger(L, sector->lightlevel);
return 1;
@ -400,46 +390,6 @@ static int sector_get(lua_State *L)
return 0;
}
// help function for P_LoadSectors, find a flat in the active wad files,
// allocate an id for it, and set the levelflat (to speedup search)
//
static INT32 P_AddLevelFlatRuntime(const char *flatname)
{
size_t i;
levelflat_t *levelflat = levelflats;
//
// first scan through the already found flats
//
for (i = 0; i < numlevelflats; i++, levelflat++)
if (strnicmp(levelflat->name,flatname,8)==0)
break;
// that flat was already found in the level, return the id
if (i == numlevelflats)
{
// allocate new flat memory
levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL);
levelflat = levelflats+i;
// store the name
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
strupr(levelflat->name);
// store the flat lump number
levelflat->lumpnum = R_GetFlatNumForName(flatname);
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
#endif
numlevelflats++;
}
// level flat id
return (INT32)i;
}
static int sector_set(lua_State *L)
{
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));

View file

@ -452,7 +452,7 @@ void Command_RTeleport_f(void)
else
inty = 0;
ss = R_PointInSubsector(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT);
ss = R_IsPointInSubsector(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT);
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
{
CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n"));

View file

@ -248,9 +248,16 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedFloor(fixed_t x)
{
const fixed_t a = abs(x); //absolute of x
const fixed_t i = (a>>FRACBITS)<<FRACBITS; // cut out the fractional part
const fixed_t f = i-a; // cut out the integral part
const fixed_t f = a-i; // cut out the integral part
if (f == 0)
return x;
if (x != INT32_MIN)
return x-f; // return largest integral value not greater than argument
{ // return rounded down to nearest whole number
if (x > 0)
return x-f;
else
return x-(FRACUNIT-f);
}
return INT32_MIN;
}
@ -266,7 +273,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedTrunc(fixed_t x)
{
const fixed_t a = abs(x); //absolute of x
const fixed_t i = (a>>FRACBITS)<<FRACBITS; // cut out the fractional part
const fixed_t f = i-a; // cut out the integral part
const fixed_t f = a-i; // cut out the integral part
if (x != INT32_MIN)
{ // return rounded to nearest whole number, towards zero
if (x > 0)
@ -289,11 +296,18 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedCeil(fixed_t x)
{
const fixed_t a = abs(x); //absolute of x
const fixed_t i = (a>>FRACBITS)<<FRACBITS; // cut out the fractional part
const fixed_t f = i-a; // cut out the integral part
const fixed_t f = a-i; // cut out the integral part
if (f == 0)
return x;
if (x == INT32_MIN)
return INT32_MIN;
else if (x < FixedFloor(INT32_MAX))
return x+(FRACUNIT-f); // return smallest integral value not less than argument
{ // return rounded up to nearest whole number
if (x > 0)
return x+(FRACUNIT-f);
else
return x+f;
}
return INT32_MAX;
}
@ -309,7 +323,9 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x)
{
const fixed_t a = abs(x); //absolute of x
const fixed_t i = (a>>FRACBITS)<<FRACBITS; // cut out the fractional part
const fixed_t f = i-a; // cut out the integral part
const fixed_t f = a-i; // cut out the integral part
if (f == 0)
return x;
if (x == INT32_MIN)
return INT32_MIN;
else if (x < FixedFloor(INT32_MAX))

View file

@ -1675,6 +1675,7 @@ char *M_GetToken(const char *inputString)
|| stringToUse[startPos] == '\r'
|| stringToUse[startPos] == '\n'
|| stringToUse[startPos] == '\0'
|| stringToUse[startPos] == '"' // we're treating this as whitespace because SLADE likes adding it for no good reason
|| inComment != 0)
&& startPos < stringLength)
{
@ -1742,6 +1743,7 @@ char *M_GetToken(const char *inputString)
&& stringToUse[endPos] != ','
&& stringToUse[endPos] != '{'
&& stringToUse[endPos] != '}'
&& stringToUse[endPos] != '"' // see above
&& inComment == 0)
&& endPos < stringLength)
{

View file

@ -985,18 +985,24 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
}
topz = thing->z - FixedMul(FRACUNIT, thing->scale);
topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
// block only when jumping not high enough,
// (dont climb max. 24units while already in air)
// if not in air, let P_TryMove() decide if it's not too high
// since return false doesn't handle momentum properly,
// we lie to P_TryMove() so it's always too high
if (tmthing->player && tmthing->z + tmthing->height > topz
&& tmthing->z + tmthing->height < tmthing->ceilingz)
return false; // block while in air
if (thing->flags & MF_SPRING)
{
tmfloorz = tmceilingz = INT32_MIN; // block while in air
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
tmfloorthing = thing; // needed for side collision
}
else if (thing->flags & MF_SPRING)
;
else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height)
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
{
tmceilingz = topz;
#ifdef ESLOPE
@ -1022,17 +1028,24 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
}
topz = thing->z + thing->height + FixedMul(FRACUNIT, thing->scale);
topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
// block only when jumping not high enough,
// (dont climb max. 24units while already in air)
// if not in air, let P_TryMove() decide if it's not too high
if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz)
return false; // block while in air
if (thing->flags & MF_SPRING)
// since return false doesn't handle momentum properly,
// we lie to P_TryMove() so it's always too high
if (tmthing->player && tmthing->z < topz
&& tmthing->z > tmthing->floorz)
{
tmfloorz = tmceilingz = INT32_MAX; // block while in air
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
tmfloorthing = thing; // needed for side collision
}
else if (thing->flags & MF_SPRING)
;
else if (topz > tmfloorz && tmthing->z >= thing->z)
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
{
tmfloorz = topz;
#ifdef ESLOPE

View file

@ -572,9 +572,11 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
side_t *side = &sides[linedef->sidenum[0]];
fixed_t textop, texbottom, texheight;
fixed_t texmid, delta1, delta2;
INT32 texnum = R_GetTextureNum(side->midtexture); // make sure the texture is actually valid
if (texnum) {
// Get the midtexture's height
texheight = textures[texturetranslation[side->midtexture]]->height << FRACBITS;
texheight = textures[texnum]->height << FRACBITS;
// Set texbottom and textop to the Z coordinates of the texture's boundaries
#if 0 // #ifdef POLYOBJECTS
@ -619,6 +621,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
openbottom = textop;
}
}
}
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors

View file

@ -2017,13 +2017,13 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
if (topheight > mo->floorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM)
&& ((P_MobjFlip(mo)*mo->momz > 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference)
&& ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference)
{
mo->floorz = topheight;
}
if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
&& !(rover->flags & FF_PLATFORM)
&& ((P_MobjFlip(mo)*mo->momz > 0) || (!(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below
&& ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below
{
mo->ceilingz = bottomheight;
}
@ -4436,7 +4436,7 @@ static void P_Boss4MoveSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz)
{
INT32 s;
mobj_t *base = mobj, *seg;
fixed_t dist, bz = (mobj->spawnpoint->z+16)<<FRACBITS;
fixed_t dist, bz = mobj->watertop+(16<<FRACBITS);
while ((base = base->tracer))
{
for (seg = base, dist = 172*FRACUNIT, s = 9; seg; seg = seg->hnext, dist += 124*FRACUNIT, --s)
@ -4450,7 +4450,7 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz)
{
INT32 s;
mobj_t *base = mobj, *seg;
fixed_t dist, bz = (mobj->spawnpoint->z+16)<<FRACBITS;
fixed_t dist, bz = mobj->watertop+(16<<FRACBITS);
while ((base = base->tracer))
{
for (seg = base, dist = 112*FRACUNIT, s = 9; seg; seg = seg->hnext, dist += 132*FRACUNIT, --s)
@ -4566,7 +4566,7 @@ static void P_Boss4Thinker(mobj_t *mobj)
INT32 i, arm;
mobj_t *seg, *base = mobj;
// First frame init, spawn all the things.
mobj->spawnpoint->z = mobj->z>>FRACBITS;
mobj->watertop = mobj->z;
z = mobj->z + mobj->height/2 - mobjinfo[MT_EGGMOBILE4_MACE].height/2;
for (arm = 0; arm <3 ; arm++)
{
@ -4622,7 +4622,7 @@ static void P_Boss4Thinker(mobj_t *mobj)
case 3:
{
fixed_t z;
if (mobj->z < (mobj->spawnpoint->z+512)<<FRACBITS)
if (mobj->z < mobj->watertop+(512<<FRACBITS))
mobj->momz = 8*FRACUNIT;
else
{
@ -4631,7 +4631,7 @@ static void P_Boss4Thinker(mobj_t *mobj)
}
mobj->movecount += 400<<(FRACBITS>>1);
mobj->movecount %= 360*FRACUNIT;
z = mobj->z - (mobj->spawnpoint->z<<FRACBITS) - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2;
z = mobj->z - mobj->watertop - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2;
if (z < 0) // We haven't risen high enough to pull the spikeballs along yet
P_Boss4MoveSpikeballs(mobj, FixedAngle(mobj->movecount), 0); // So don't pull the spikeballs along yet.
else
@ -4641,13 +4641,13 @@ static void P_Boss4Thinker(mobj_t *mobj)
// Pinch phase!
case 4:
{
if (mobj->z < (mobj->spawnpoint->z+512+128*(mobj->info->damage-mobj->health))<<FRACBITS)
if (mobj->z < (mobj->watertop + ((512+128*(mobj->info->damage-mobj->health))<<FRACBITS)))
mobj->momz = 8*FRACUNIT;
else
mobj->momz = 0;
mobj->movecount += (800+800*(mobj->info->damage-mobj->health))<<(FRACBITS>>1);
mobj->movecount %= 360*FRACUNIT;
P_Boss4PinchSpikeballs(mobj, FixedAngle(mobj->movecount), mobj->z - (mobj->spawnpoint->z<<FRACBITS) - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2);
P_Boss4PinchSpikeballs(mobj, FixedAngle(mobj->movecount), mobj->z - mobj->watertop - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2);
if (!mobj->target || !mobj->target->health)
P_SupermanLook4Players(mobj);
@ -6048,6 +6048,8 @@ void P_RunOverlays(void)
P_UnsetThingPosition(mo);
mo->x = destx;
mo->y = desty;
mo->radius = mo->target->radius;
mo->height = mo->target->height;
if (mo->eflags & MFE_VERTICALFLIP)
mo->z = (mo->target->z + mo->target->height - mo->height) - zoffs;
else
@ -7683,6 +7685,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
if (mobj->type == MT_UNIDUS)
mobj->z -= FixedMul(mobj->info->mass, mobj->scale);
// defaults onground
if (mobj->z + mobj->height == mobj->ceilingz)
mobj->eflags |= MFE_ONGROUND;
}
else
mobj->z = z;

View file

@ -460,6 +460,7 @@ static void P_NetUnArchivePlayers(void)
#define SD_TAG 0x10
#define SD_FLOORANG 0x20
#define SD_CEILANG 0x40
#define SD_TAGLIST 0x80
#define LD_FLAG 0x01
#define LD_SPECIAL 0x02
@ -509,10 +510,9 @@ static void P_NetArchiveWorld(void)
//
// flats
//
// P_AddLevelFlat should not add but just return the number
if (ss->floorpic != P_AddLevelFlat(ms->floorpic, levelflats))
if (ss->floorpic != P_CheckLevelFlat(ms->floorpic))
diff |= SD_FLOORPIC;
if (ss->ceilingpic != P_AddLevelFlat(ms->ceilingpic, levelflats))
if (ss->ceilingpic != P_CheckLevelFlat(ms->ceilingpic))
diff |= SD_CEILPIC;
if (ss->lightlevel != SHORT(ms->lightlevel))
@ -535,6 +535,8 @@ static void P_NetArchiveWorld(void)
if (ss->tag != SHORT(ms->tag))
diff2 |= SD_TAG;
if (ss->nexttag != ss->spawn_nexttag || ss->firsttag != ss->spawn_firsttag)
diff2 |= SD_TAGLIST;
// Check if any of the sector's FOFs differ from how they spawned
if (ss->ffloors)
@ -582,16 +584,17 @@ static void P_NetArchiveWorld(void)
WRITEFIXED(put, ss->ceiling_xoffs);
if (diff2 & SD_CYOFFS)
WRITEFIXED(put, ss->ceiling_yoffs);
if (diff2 & SD_TAG)
{
if (diff2 & SD_TAG) // save only the tag
WRITEINT16(put, ss->tag);
WRITEINT32(put, ss->firsttag);
WRITEINT32(put, ss->nexttag);
}
if (diff2 & SD_FLOORANG)
WRITEANGLE(put, ss->floorpic_angle);
if (diff2 & SD_CEILANG)
WRITEANGLE(put, ss->ceilingpic_angle);
if (diff2 & SD_TAGLIST) // save both firsttag and nexttag
{ // either of these could be changed even if tag isn't
WRITEINT32(put, ss->firsttag);
WRITEINT32(put, ss->nexttag);
}
// 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
@ -752,12 +755,12 @@ static void P_NetUnArchiveWorld(void)
sectors[i].ceilingheight = READFIXED(get);
if (diff & SD_FLOORPIC)
{
sectors[i].floorpic = P_AddLevelFlat((char *)get, levelflats);
sectors[i].floorpic = P_AddLevelFlatRuntime((char *)get);
get += 8;
}
if (diff & SD_CEILPIC)
{
sectors[i].ceilingpic = P_AddLevelFlat((char *)get, levelflats);
sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)get);
get += 8;
}
if (diff & SD_LIGHT)
@ -774,12 +777,11 @@ static void P_NetUnArchiveWorld(void)
if (diff2 & SD_CYOFFS)
sectors[i].ceiling_yoffs = READFIXED(get);
if (diff2 & SD_TAG)
sectors[i].tag = READINT16(get); // DON'T use P_ChangeSectorTag
if (diff2 & SD_TAGLIST)
{
INT16 tag;
tag = READINT16(get);
sectors[i].firsttag = READINT32(get);
sectors[i].nexttag = READINT32(get);
P_ChangeSectorTag(i, tag);
}
if (diff2 & SD_FLOORANG)
sectors[i].floorpic_angle = READANGLE(get);
@ -2607,6 +2609,7 @@ static void P_NetUnArchiveThinkers(void)
thinker_t *next;
UINT8 tclass;
UINT8 restoreNum = false;
UINT32 i;
if (READUINT32(save_p) != ARCHIVEBLOCK_THINKERS)
I_Error("Bad $$$.sav at archive block Thinkers");
@ -2627,6 +2630,12 @@ static void P_NetUnArchiveThinkers(void)
iquetail = iquehead = 0;
P_InitThinkers();
// clear sector thinker pointers so they don't point to non-existant thinkers for all of eternity
for (i = 0; i < numsectors; i++)
{
sectors[i].floordata = sectors[i].ceilingdata = sectors[i].lightingdata = NULL;
}
// read in saved thinkers
for (;;)
{
@ -3285,7 +3294,7 @@ void P_SaveNetGame(void)
{
thinker_t *th;
mobj_t *mobj;
INT32 i = 0;
INT32 i = 1; // don't start from 0, it'd be confused with a blank pointer otherwise
CV_SaveNetVars(&save_p);
P_NetArchiveMisc();

View file

@ -574,6 +574,69 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
return (INT32)i;
}
// help function for Lua and $$$.sav reading
// same as P_AddLevelFlat, except this is not setup so we must realloc levelflats to fit in the new flat
// no longer a static func in lua_maplib.c because p_saveg.c also needs it
//
INT32 P_AddLevelFlatRuntime(const char *flatname)
{
size_t i;
levelflat_t *levelflat = levelflats;
//
// first scan through the already found flats
//
for (i = 0; i < numlevelflats; i++, levelflat++)
if (strnicmp(levelflat->name,flatname,8)==0)
break;
// that flat was already found in the level, return the id
if (i == numlevelflats)
{
// allocate new flat memory
levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL);
levelflat = levelflats+i;
// store the name
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
strupr(levelflat->name);
// store the flat lump number
levelflat->lumpnum = R_GetFlatNumForName(flatname);
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
#endif
numlevelflats++;
}
// level flat id
return (INT32)i;
}
// help function for $$$.sav checking
// this simply returns the flat # for the name given
//
INT32 P_CheckLevelFlat(const char *flatname)
{
size_t i;
levelflat_t *levelflat = levelflats;
//
// scan through the already found flats
//
for (i = 0; i < numlevelflats; i++, levelflat++)
if (strnicmp(levelflat->name,flatname,8)==0)
break;
if (i == numlevelflats)
return 0; // ??? flat was not found, this should not happen!
// level flat id
return (INT32)i;
}
static void P_LoadSectors(lumpnum_t lumpnum)
{
UINT8 *data;
@ -614,6 +677,7 @@ static void P_LoadSectors(lumpnum_t lumpnum)
ss->special = SHORT(ms->special);
ss->tag = SHORT(ms->tag);
ss->nexttag = ss->firsttag = -1;
ss->spawn_nexttag = ss->spawn_firsttag = -1;
memset(&ss->soundorg, 0, sizeof(ss->soundorg));
ss->validcount = 0;
@ -2587,10 +2651,6 @@ boolean P_SetupLevel(boolean skipprecip)
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette);
CON_SetupBackColormap();
// now part of level loading since in future each level may have
// its own anim texture sequences, switches etc.
P_InitPicAnims();
// SRB2 determines the sky texture to be used depending on the map header.
P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true);
@ -3001,6 +3061,9 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
else
R_FlushTextureCache(); // just reload it from file
// Reload ANIMATED / ANIMDEFS
P_InitPicAnims();
// Flush and reload HUD graphics
ST_UnloadGraphics();
HU_LoadGraphics();

View file

@ -47,6 +47,8 @@ typedef struct
extern size_t numlevelflats;
extern levelflat_t *levelflats;
INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat);
INT32 P_AddLevelFlatRuntime(const char *flatname);
INT32 P_CheckLevelFlat(const char *flatname);
extern size_t nummapthings;
extern mapthing_t *mapthings;

View file

@ -221,8 +221,8 @@ static animdef_t harddefs[] =
static animdef_t *animdefs = NULL;
// A prototype; here instead of p_spec.h, so they're "private"
void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i);
void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i);
void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum);
void P_ParseAnimationDefintion(SINT8 istexture);
/** Sets up texture and flat animations.
*
@ -232,24 +232,21 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i);
* Issues an error if any animation cycles are invalid.
*
* \sa P_FindAnimatedFlat, P_SetupLevelFlatAnims
* \author Steven McGranahan (original), Shadow Hog (had to rewrite it to handle multiple WADs)
* \author Steven McGranahan (original), Shadow Hog (had to rewrite it to handle multiple WADs), JTE (had to rewrite it to handle multiple WADs _correctly_)
*/
void P_InitPicAnims(void)
{
// Init animation
INT32 i; // Position in the animdefs array
INT32 w; // WAD
UINT8 *wadAnimdefs; // not to be confused with animdefs, the combined total of every ANIMATED lump in every WAD, or ANIMDEFS, the ZDoom lump I intend to implement later
UINT8 *animatedLump;
UINT8 *currentPos;
size_t i;
I_Assert(animdefs == NULL);
if (W_CheckNumForName("ANIMATED") != LUMPERROR || W_CheckNumForName("ANIMDEFS") != LUMPERROR)
{
if (animdefs)
{
Z_Free(animdefs);
animdefs = NULL;
}
for (w = 0, i = 0, maxanims = 0; w < numwadfiles; w++)
for (w = numwadfiles-1, maxanims = 0; w >= 0; w--)
{
UINT16 animatedLumpNum;
UINT16 animdefsLumpNum;
@ -258,20 +255,20 @@ void P_InitPicAnims(void)
animatedLumpNum = W_CheckNumForNamePwad("ANIMATED", w, 0);
if (animatedLumpNum != INT16_MAX)
{
wadAnimdefs = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC);
animatedLump = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC);
// Get the number of animations in the file
for (currentPos = wadAnimdefs; *currentPos != UINT8_MAX; maxanims++, currentPos+=23);
i = maxanims;
for (currentPos = animatedLump; *currentPos != UINT8_MAX; maxanims++, currentPos+=23);
// Resize animdefs (or if it hasn't been created, create it)
animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL);
// Sanity check it
if (!animdefs) {
if (!animdefs)
I_Error("Not enough free memory for ANIMATED data");
}
// Populate the new array
for (currentPos = wadAnimdefs; *currentPos != UINT8_MAX; i++, currentPos+=23)
for (currentPos = animatedLump; *currentPos != UINT8_MAX; i++, currentPos+=23)
{
M_Memcpy(&(animdefs[i].istexture), currentPos, 1); // istexture, 1 byte
M_Memcpy(animdefs[i].endname, (currentPos + 1), 9); // endname, 9 bytes
@ -279,15 +276,13 @@ void P_InitPicAnims(void)
M_Memcpy(&(animdefs[i].speed), (currentPos + 19), 4); // speed, 4 bytes
}
Z_Free(wadAnimdefs);
Z_Free(animatedLump);
}
// Now find ANIMDEFS
animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0);
if (animdefsLumpNum != INT16_MAX)
{
P_ParseANIMDEFSLump(w, animdefsLumpNum, &i);
}
P_ParseANIMDEFSLump(w, animdefsLumpNum);
}
// Define the last one
animdefs[maxanims].istexture = -1;
@ -347,16 +342,20 @@ void P_InitPicAnims(void)
lastanim->istexture = -1;
R_ClearTextureNumCache(false);
// Clear animdefs now that we're done with it.
// We'll only be using anims from now on.
if (animdefs != harddefs)
Z_ChangeTag(animdefs, PU_CACHE);
Z_Free(animdefs);
animdefs = NULL;
}
void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i)
void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum)
{
char *animdefsLump;
size_t animdefsLumpLength;
char *animdefsText;
char *animdefsToken;
char *p;
// Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll
// need to make a space of memory where I can ensure that it will terminate
@ -376,18 +375,19 @@ void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i)
Z_Free(animdefsLump);
// Now, let's start parsing this thing
animdefsToken = M_GetToken(animdefsText);
p = animdefsText;
animdefsToken = M_GetToken(p);
while (animdefsToken != NULL)
{
if (stricmp(animdefsToken, "TEXTURE") == 0)
{
Z_Free(animdefsToken);
P_ParseAnimationDefintion(1, i);
P_ParseAnimationDefintion(1);
}
else if (stricmp(animdefsToken, "FLAT") == 0)
{
Z_Free(animdefsToken);
P_ParseAnimationDefintion(0, i);
P_ParseAnimationDefintion(0);
}
else if (stricmp(animdefsToken, "OSCILLATE") == 0)
{
@ -398,23 +398,22 @@ void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i)
{
I_Error("Error parsing ANIMDEFS lump: Expected \"TEXTURE\" or \"FLAT\", got \"%s\"",animdefsToken);
}
animdefsToken = M_GetToken(NULL);
// parse next line
while (*p != '\0' && *p != '\n') ++p;
if (*p == '\n') ++p;
animdefsToken = M_GetToken(p);
}
Z_Free(animdefsToken);
Z_Free((void *)animdefsText);
}
void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i)
void P_ParseAnimationDefintion(SINT8 istexture)
{
char *animdefsToken;
size_t animdefsTokenLength;
char *endPos;
INT32 animSpeed;
// Increase the size to make room for the new animation definition
maxanims++;
animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL);
animdefs[*i].istexture = istexture;
size_t i;
// Startname
animdefsToken = M_GetToken(NULL);
@ -448,14 +447,39 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i)
{
I_Error("Error parsing ANIMDEFS lump: lump name \"%s\" exceeds 8 characters", animdefsToken);
}
strncpy(animdefs[*i].startname, animdefsToken, 9);
// Search for existing animdef
for (i = 0; i < maxanims; i++)
if (stricmp(animdefsToken, animdefs[i].startname) == 0)
{
//CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken);
// If we weren't parsing in reverse order, we would `break` here and parse the new data into the existing slot we found.
// Instead, we're just going to skip parsing the rest of this line entirely.
Z_Free(animdefsToken);
return;
}
// Not found
if (i == maxanims)
{
// Increase the size to make room for the new animation definition
maxanims++;
animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL);
strncpy(animdefs[i].startname, animdefsToken, 9);
}
// animdefs[i].startname is now set to animdefsToken either way.
Z_Free(animdefsToken);
// set texture type
animdefs[i].istexture = istexture;
// "RANGE"
animdefsToken = M_GetToken(NULL);
if (animdefsToken == NULL)
{
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"RANGE\" after \"%s\"'s startname should be", animdefs[*i].startname);
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"RANGE\" after \"%s\"'s startname should be", animdefs[i].startname);
}
if (stricmp(animdefsToken, "ALLOWDECALS") == 0)
{
@ -470,7 +494,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i)
}
if (stricmp(animdefsToken, "RANGE") != 0)
{
I_Error("Error parsing ANIMDEFS lump: Expected \"RANGE\" after \"%s\"'s startname, got \"%s\"", animdefs[*i].startname, animdefsToken);
I_Error("Error parsing ANIMDEFS lump: Expected \"RANGE\" after \"%s\"'s startname, got \"%s\"", animdefs[i].startname, animdefsToken);
}
Z_Free(animdefsToken);
@ -478,21 +502,21 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i)
animdefsToken = M_GetToken(NULL);
if (animdefsToken == NULL)
{
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s end texture/flat name should be", animdefs[*i].startname);
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s end texture/flat name should be", animdefs[i].startname);
}
animdefsTokenLength = strlen(animdefsToken);
if (animdefsTokenLength>8)
{
I_Error("Error parsing ANIMDEFS lump: lump name \"%s\" exceeds 8 characters", animdefsToken);
}
strncpy(animdefs[*i].endname, animdefsToken, 9);
strncpy(animdefs[i].endname, animdefsToken, 9);
Z_Free(animdefsToken);
// "TICS"
animdefsToken = M_GetToken(NULL);
if (animdefsToken == NULL)
{
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s \"TICS\" should be", animdefs[*i].startname);
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s \"TICS\" should be", animdefs[i].startname);
}
if (stricmp(animdefsToken, "RAND") == 0)
{
@ -501,7 +525,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i)
}
if (stricmp(animdefsToken, "TICS") != 0)
{
I_Error("Error parsing ANIMDEFS lump: Expected \"TICS\" in animation definition for \"%s\", got \"%s\"", animdefs[*i].startname, animdefsToken);
I_Error("Error parsing ANIMDEFS lump: Expected \"TICS\" in animation definition for \"%s\", got \"%s\"", animdefs[i].startname, animdefsToken);
}
Z_Free(animdefsToken);
@ -509,7 +533,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i)
animdefsToken = M_GetToken(NULL);
if (animdefsToken == NULL)
{
I_Error("Error parsing TEXTURES lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[*i].startname);
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[i].startname);
}
endPos = NULL;
#ifndef AVOID_ERRNO
@ -523,13 +547,10 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i)
#endif
|| animSpeed < 0) // Number is not positive
{
I_Error("Error parsing TEXTURES lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[*i].startname, animdefsToken);
I_Error("Error parsing ANIMDEFS lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[i].startname, animdefsToken);
}
animdefs[*i].speed = animSpeed;
animdefs[i].speed = animSpeed;
Z_Free(animdefsToken);
// Increment i before we go, so this doesn't cause issues later
(*i)++;
}
@ -1498,6 +1519,8 @@ static inline void P_InitTagLists(void)
size_t j = (unsigned)sectors[i].tag % numsectors;
sectors[i].nexttag = sectors[j].firsttag;
sectors[j].firsttag = (INT32)i;
sectors[i].spawn_nexttag = sectors[i].nexttag;
sectors[j].spawn_firsttag = sectors[j].firsttag;
}
for (i = numlines - 1; i != (size_t)-1; i--)
@ -5321,6 +5344,10 @@ void T_LaserFlash(laserthink_t *flash)
&& thing->flags & MF_BOSS)
continue; // Don't hurt bosses
// Don't endlessly kill egg guard shields (or anything else for that matter)
if (thing->health <= 0)
continue;
top = P_GetSpecialTopZ(thing, sourcesec, sector);
bottom = P_GetSpecialBottomZ(thing, sourcesec, sector);
@ -7428,7 +7455,7 @@ void T_Pusher(pusher_t *p)
}
else
{
if (top < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1)))
if (top < thing->z || bottom > (thing->z + (thing->height >> 1)))
continue;
if (thing->z + thing->height > top)
touching = true;

View file

@ -2280,14 +2280,13 @@ static void P_DoClimbing(player_t *player)
fixed_t platy;
subsector_t *glidesector;
boolean climb = true;
boolean onesided = ((player->lastsidehit != -1 && player->lastlinehit != -1) && !(lines[player->lastlinehit].backsector));
platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
platy = P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy);
glidesector = R_IsPointInSubsector(player->mo->x + platx, player->mo->y + platy);
if (onesided || glidesector->sector != player->mo->subsector->sector)
if (!glidesector || glidesector->sector != player->mo->subsector->sector)
{
boolean floorclimb = false;
boolean thrust = false;
@ -2295,7 +2294,7 @@ static void P_DoClimbing(player_t *player)
boolean skyclimber = false;
fixed_t floorheight, ceilingheight; // ESLOPE
if (onesided)
if (!glidesector)
floorclimb = true;
else
{
@ -7058,7 +7057,6 @@ static void P_DoZoomTube(player_t *player)
mobj_t *waypoint = NULL;
fixed_t dist;
boolean reverse;
fixed_t speedx,speedy,speedz;
player->mo->height = P_GetPlayerSpinHeight(player);
@ -7079,17 +7077,17 @@ static void P_DoZoomTube(player_t *player)
if (dist < 1)
dist = 1;
speedx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
speedz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed));
player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed));
// Calculate the distance between the player and the waypoint
// 'dist' already equals this.
// Will the player be FURTHER away if the momx/momy/momz is added to
// his current coordinates, or closer? (shift down to fracunits to avoid approximation errors)
if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - player->mo->z - speedz)>>FRACBITS)
// Will the player go past the waypoint?
if (speed > dist)
{
speed -= dist;
// If further away, set XYZ of player to waypoint location
P_UnsetThingPosition(player->mo);
player->mo->x = player->mo->tracer->x;
@ -7129,14 +7127,9 @@ static void P_DoZoomTube(player_t *player)
{
CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health);
// calculate MOMX/MOMY/MOMZ for next waypoint
// change angle
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y);
P_SetTarget(&player->mo->tracer, waypoint);
if (player == &players[consoleplayer])
localangle = player->mo->angle;
else if (player == &players[secondarydisplayplayer])
localangle2 = player->mo->angle;
// calculate MOMX/MOMY/MOMZ for next waypoint
// change slope
dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z);
@ -7147,22 +7140,14 @@ static void P_DoZoomTube(player_t *player)
player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed));
P_SetTarget(&player->mo->tracer, waypoint);
}
else
{
P_SetTarget(&player->mo->tracer, NULL); // Else, we just let him fly.
P_SetTarget(&player->mo->tracer, NULL); // Else, we just let them fly.
CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n");
}
}
else
{
player->mo->momx = speedx;
player->mo->momy = speedy;
player->mo->momz = speedz;
}
// change angle
if (player->mo->tracer)
@ -7190,24 +7175,10 @@ static void P_DoRopeHang(player_t *player)
mobj_t *mo2;
mobj_t *waypoint = NULL;
fixed_t dist;
fixed_t speedx,speedy,speedz;
fixed_t playerz;
player->mo->height = P_GetPlayerHeight(player);
if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope
{
P_SetTarget(&player->mo->tracer, NULL);
player->pflags |= PF_JUMPED;
player->pflags &= ~PF_ROPEHANG;
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
return;
}
// Play the 'clink' sound only if the player is moving.
if (!(leveltime & 7) && player->speed)
S_StartSound(player->mo, sfx_s3k55);
@ -7224,9 +7195,22 @@ static void P_DoRopeHang(player_t *player)
if (dist < 1)
dist = 1;
speedx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
speedz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed));
player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed));
if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope
{
P_SetTarget(&player->mo->tracer, NULL);
player->pflags |= PF_JUMPED;
player->pflags &= ~PF_ROPEHANG;
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
return;
}
// If not allowed to move, we're done here.
if (!speed)
@ -7235,15 +7219,16 @@ static void P_DoRopeHang(player_t *player)
// Calculate the distance between the player and the waypoint
// 'dist' already equals this.
// Will the player be FURTHER away if the momx/momy/momz is added to
// his current coordinates, or closer? (shift down to fracunits to avoid approximation errors)
if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - playerz - speedz)>>FRACBITS)
// Will the player go past the waypoint?
if (speed > dist)
{
speed -= dist;
// If further away, set XYZ of player to waypoint location
P_UnsetThingPosition(player->mo);
player->mo->x = player->mo->tracer->x;
player->mo->y = player->mo->tracer->y;
player->mo->z = player->mo->tracer->z - player->mo->height;
playerz = player->mo->tracer->z;
P_SetThingPosition(player->mo);
CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n");
@ -7299,6 +7284,8 @@ static void P_DoRopeHang(player_t *player)
{
CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health);
P_SetTarget(&player->mo->tracer, waypoint);
// calculate MOMX/MOMY/MOMZ for next waypoint
// change slope
dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz);
@ -7309,8 +7296,6 @@ static void P_DoRopeHang(player_t *player)
player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed));
P_SetTarget(&player->mo->tracer, waypoint);
}
else
{
@ -7329,12 +7314,6 @@ static void P_DoRopeHang(player_t *player)
CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found!\n");
}
}
else
{
player->mo->momx = speedx;
player->mo->momy = speedy;
player->mo->momz = speedz;
}
}
#if 0

View file

@ -859,6 +859,7 @@ static void R_Subsector(size_t num)
static sector_t tempsec; // Deep water hack
extracolormap_t *floorcolormap;
extracolormap_t *ceilingcolormap;
fixed_t floorcenterz, ceilingcenterz;
#ifdef RANGECHECK
if (num >= numsubsectors)
@ -879,6 +880,18 @@ static void R_Subsector(size_t num)
floorcolormap = ceilingcolormap = frontsector->extra_colormap;
floorcenterz =
#ifdef ESLOPE
frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->floorheight;
ceilingcenterz =
#ifdef ESLOPE
frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->ceilingheight;
// Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps.
if (frontsector->ffloors)
{
@ -891,19 +904,11 @@ static void R_Subsector(size_t num)
sub->sector->moved = frontsector->moved = false;
}
light = R_GetPlaneLight(frontsector,
#ifdef ESLOPE
frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->floorheight, false);
light = R_GetPlaneLight(frontsector, floorcenterz, false);
if (frontsector->floorlightsec == -1)
floorlightlevel = *frontsector->lightlist[light].lightlevel;
floorcolormap = frontsector->lightlist[light].extra_colormap;
light = R_GetPlaneLight(frontsector,
#ifdef ESLOPE
frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->ceilingheight, false);
light = R_GetPlaneLight(frontsector, ceilingcenterz, false);
if (frontsector->ceilinglightsec == -1)
ceilinglightlevel = *frontsector->lightlist[light].lightlevel;
ceilingcolormap = frontsector->lightlist[light].extra_colormap;
@ -920,6 +925,9 @@ static void R_Subsector(size_t num)
{
floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel,
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
#ifdef ESLOPE
, frontsector->f_slope
#endif
@ -939,6 +947,9 @@ static void R_Subsector(size_t num)
ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic,
ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle,
ceilingcolormap, NULL
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
#ifdef ESLOPE
, frontsector->c_slope
#endif
@ -956,7 +967,7 @@ static void R_Subsector(size_t num)
if (frontsector->ffloors)
{
ffloor_t *rover;
fixed_t heightcheck, planecenterz, floorcenterz, ceilingcenterz;
fixed_t heightcheck, planecenterz;
for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next)
{
@ -975,18 +986,6 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
floorcenterz =
#ifdef ESLOPE
frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->floorheight;
ceilingcenterz =
#ifdef ESLOPE
frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->ceilingheight;
heightcheck =
#ifdef ESLOPE
*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) :
@ -1009,6 +1008,9 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
*rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
#ifdef ESLOPE
, *rover->b_slope
#endif
@ -1052,6 +1054,9 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
frontsector->lightlist[light].extra_colormap, rover
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
#ifdef ESLOPE
, *rover->t_slope
#endif
@ -1093,8 +1098,8 @@ static void R_Subsector(size_t num)
polysec = po->lines[0]->backsector;
ffloor[numffloors].plane = NULL;
if (polysec->floorheight <= frontsector->ceilingheight
&& polysec->floorheight >= frontsector->floorheight
if (polysec->floorheight <= ceilingcenterz
&& polysec->floorheight >= floorcenterz
&& (viewz < polysec->floorheight))
{
fixed_t xoff, yoff;
@ -1118,11 +1123,13 @@ static void R_Subsector(size_t num)
polysec->floorpic_angle-po->angle,
NULL,
NULL
#ifdef POLYOBJECTS_PLANES
, po
#endif
#ifdef ESLOPE
, NULL // will ffloors be slopable eventually?
#endif
);
//ffloor[numffloors].plane->polyobj = po;
ffloor[numffloors].height = polysec->floorheight;
ffloor[numffloors].polyobj = po;
@ -1139,8 +1146,8 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = NULL;
if (polysec->ceilingheight >= frontsector->floorheight
&& polysec->ceilingheight <= frontsector->ceilingheight
if (polysec->ceilingheight >= floorcenterz
&& polysec->ceilingheight <= ceilingcenterz
&& (viewz > polysec->ceilingheight))
{
fixed_t xoff, yoff;
@ -1162,11 +1169,13 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle,
NULL, NULL
#ifdef POLYOBJECTS_PLANES
, po
#endif
#ifdef ESLOPE
, NULL // will ffloors be slopable eventually?
#endif
);
//ffloor[numffloors].plane->polyobj = po;
ffloor[numffloors].polyobj = po;
ffloor[numffloors].height = polysec->ceilingheight;

View file

@ -303,6 +303,32 @@ done:
return blocktex;
}
//
// R_GetTextureNum
//
// Returns the actual texture id that we should use.
// This can either be texnum, the current frame for texnum's anim (if animated),
// or 0 if not valid.
//
INT32 R_GetTextureNum(INT32 texnum)
{
if (texnum < 0 || texnum >= numtextures)
return 0;
return texturetranslation[texnum];
}
//
// R_CheckTextureCache
//
// Use this if you need to make sure the texture is cached before R_GetColumn calls
// e.g.: midtextures and FOF walls
//
void R_CheckTextureCache(INT32 tex)
{
if (!texturecache[tex])
R_GenerateTexture(tex);
}
//
// R_GetColumn
//
@ -1499,6 +1525,9 @@ void R_InitData(void)
CONS_Printf("R_LoadTextures()...\n");
R_LoadTextures();
CONS_Printf("P_InitPicAnims()...\n");
P_InitPicAnims();
CONS_Printf("R_InitSprites()...\n");
R_InitSpriteLumps();
R_InitSprites();

View file

@ -65,6 +65,9 @@ extern CV_PossibleValue_t Color_cons_t[];
void R_LoadTextures(void);
void R_FlushTextureCache(void);
INT32 R_GetTextureNum(INT32 texnum);
void R_CheckTextureCache(INT32 tex);
// Retrieve column data for span blitting.
UINT8 *R_GetColumn(fixed_t tex, INT32 col);

View file

@ -203,6 +203,7 @@ typedef struct r_lightlist_s
fixed_t heightstep;
fixed_t botheight;
fixed_t botheightstep;
fixed_t startheight; // for repeating midtextures
INT16 lightlevel;
extracolormap_t *extra_colormap;
lighttable_t *rcolormap;
@ -383,6 +384,7 @@ typedef struct sector_s
#endif
// these are saved for netgames, so do not let Lua touch these!
INT32 spawn_nexttag, spawn_firsttag; // the actual nexttag/firsttag values may differ if the sector's tag was changed
// offsets sector spawned with (via linedef type 7)
fixed_t spawn_flr_xoffs, spawn_flr_yoffs;

View file

@ -708,7 +708,7 @@ subsector_t *R_PointInSubsector(fixed_t x, fixed_t y)
}
//
// R_IsPointInSubsector, same as above but returns 0 if not in subsector - this does not work in opengl because of polyvertex_t
// R_IsPointInSubsector, same as above but returns 0 if not in subsector
//
subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
{
@ -732,7 +732,8 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
ret = &subsectors[nodenum & ~NF_SUBSECTOR];
for (i = 0; i < ret->numlines; i++)
if (R_PointOnSegSide(x, y, &segs[ret->firstline + i]))
//if (R_PointOnSegSide(x, y, &segs[ret->firstline + i])) -- breaks in ogl because polyvertex_t cast over vertex pointers
if (P_PointOnLineSide(x, y, segs[ret->firstline + i].linedef) != segs[ret->firstline + i].side)
return 0;
return ret;

View file

@ -431,6 +431,9 @@ static visplane_t *new_visplane(unsigned hash)
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap,
ffloor_t *pfloor
#ifdef POLYOBJECTS_PLANES
, polyobj_t *polyobj
#endif
#ifdef ESLOPE
, pslope_t *slope
#endif
@ -470,6 +473,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
#ifdef POLYOBJECTS_PLANES
if (check->polyobj && pfloor)
continue;
if (polyobj != check->polyobj)
continue;
#endif
if (height == check->height && picnum == check->picnum
&& lightlevel == check->lightlevel
@ -504,7 +509,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
check->viewangle = viewangle;
check->plangle = plangle;
#ifdef POLYOBJECTS_PLANES
check->polyobj = NULL;
check->polyobj = polyobj;
#endif
#ifdef ESLOPE
check->slope = slope;
@ -719,7 +724,11 @@ void R_DrawPlanes(void)
continue;
}
if (pl->ffloor != NULL)
if (pl->ffloor != NULL
#ifdef POLYOBJECTS_PLANES
|| pl->polyobj != NULL
#endif
)
continue;
R_DrawSinglePlane(pl);

View file

@ -97,6 +97,9 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2);
void R_DrawPlanes(void);
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle,
extracolormap_t *planecolormap, ffloor_t *ffloor
#ifdef POLYOBJECTS_PLANES
, polyobj_t *polyobj
#endif
#ifdef ESLOPE
, pslope_t *slope
#endif

View file

@ -300,7 +300,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
curline = ds->curline;
frontsector = curline->frontsector;
backsector = curline->backsector;
texnum = texturetranslation[curline->sidedef->midtexture];
texnum = R_GetTextureNum(curline->sidedef->midtexture);
windowbottom = windowtop = sprbotscreen = INT32_MAX;
// hack translucent linedef types (900-909 for transtables 1-9)
@ -344,6 +344,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
rw_scalestep = ds->scalestep;
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
// Texture must be cached before setting colfunc_2s,
// otherwise texture[texnum]->holes may be false when it shouldn't be
R_CheckTextureCache(texnum);
// handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
// are not stored per-column with post info in SRB2
if (textures[texnum]->holes)
@ -391,6 +394,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale);
rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz));
#endif
rlight->startheight = rlight->height; // keep starting value here to reset for each repeat
rlight->lightlevel = *light->lightlevel;
rlight->extra_colormap = light->extra_colormap;
rlight->flags = light->flags;
@ -484,6 +488,14 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{
rw_scalestep = ds->scalestep;
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
if (dc_numlights)
{ // reset all lights to their starting heights
for (i = 0; i < dc_numlights; i++)
{
rlight = &dc_lightlist[i];
rlight->height = rlight->startheight;
}
}
}
#ifndef ESLOPE
@ -740,7 +752,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
curline = ds->curline;
backsector = pfloor->target;
frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector;
texnum = texturetranslation[sides[pfloor->master->sidenum[0]].midtexture];
texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture);
colfunc = wallcolfunc;
@ -748,7 +760,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{
size_t linenum = curline->linedef-backsector->lines[0];
newline = pfloor->master->frontsector->lines[0] + linenum;
texnum = texturetranslation[sides[newline->sidenum[0]].midtexture];
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture);
}
if (pfloor->flags & FF_TRANSLUCENT)
@ -968,6 +980,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
dc_texturemid += offsetvalue;
// Texture must be cached before setting colfunc_2s,
// otherwise texture[texnum]->holes may be false when it shouldn't be
R_CheckTextureCache(texnum);
//faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
// are not stored per-column with post info anymore in Doom Legacy
if (textures[texnum]->holes)
@ -1878,14 +1893,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (!backsector)
{
fixed_t texheight;
// single sided line
midtexture = texturetranslation[sidedef->midtexture];
midtexture = R_GetTextureNum(sidedef->midtexture);
texheight = textureheight[midtexture];
// a single sided line is terminal, so it must mark ends
markfloor = markceiling = true;
#ifdef ESLOPE
if (linedef->flags & ML_EFFECT2) {
if (linedef->flags & ML_DONTPEGBOTTOM)
rw_midtexturemid = frontsector->floorheight + textureheight[sidedef->midtexture] - viewz;
rw_midtexturemid = frontsector->floorheight + texheight - viewz;
else
rw_midtexturemid = frontsector->ceilingheight - viewz;
}
@ -1894,10 +1911,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (linedef->flags & ML_DONTPEGBOTTOM)
{
#ifdef ESLOPE
rw_midtexturemid = worldbottom + textureheight[sidedef->midtexture];
rw_midtexturemid = worldbottom + texheight;
rw_midtextureslide = floorfrontslide;
#else
vtop = frontsector->floorheight + textureheight[sidedef->midtexture];
vtop = frontsector->floorheight + texheight;
// bottom of texture at bottom
rw_midtexturemid = vtop - viewz;
#endif
@ -2129,17 +2146,24 @@ void R_StoreWallRange(INT32 start, INT32 stop)
#endif
)
{
fixed_t texheight;
// top texture
if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM))
&& linedef->sidenum[1] != 0xffff)
{
// Special case... use offsets from 2nd side but only if it has a texture.
side_t *def = &sides[linedef->sidenum[1]];
toptexture = texturetranslation[def->toptexture];
toptexture = R_GetTextureNum(def->toptexture);
if (!toptexture) //Second side has no texture, use the first side's instead.
toptexture = texturetranslation[sidedef->toptexture];
toptexture = R_GetTextureNum(sidedef->toptexture);
texheight = textureheight[toptexture];
}
else
{
toptexture = R_GetTextureNum(sidedef->toptexture);
texheight = textureheight[toptexture];
}
#ifdef ESLOPE
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
if (linedef->flags & ML_DONTPEGTOP)
@ -2159,48 +2183,15 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else
{
#ifdef ESLOPE
rw_toptexturemid = worldhigh + textureheight[def->toptexture];
rw_toptexturemid = worldhigh + texheight;
rw_toptextureslide = ceilingbackslide;
#else
vtop = backsector->ceilingheight + textureheight[def->toptexture];
vtop = backsector->ceilingheight + texheight;
// bottom of texture
rw_toptexturemid = vtop - viewz;
#endif
}
}
else
{
toptexture = texturetranslation[sidedef->toptexture];
#ifdef ESLOPE
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
if (linedef->flags & ML_DONTPEGTOP)
rw_toptexturemid = frontsector->ceilingheight - viewz;
else
rw_toptexturemid = backsector->ceilingheight - viewz;
} else
#endif
if (linedef->flags & ML_DONTPEGTOP)
{
// top of texture at top
rw_toptexturemid = worldtop;
#ifdef ESLOPE
rw_toptextureslide = ceilingfrontslide;
#endif
}
else
{
#ifdef ESLOPE
rw_toptexturemid = worldhigh + textureheight[sidedef->toptexture];
rw_toptextureslide = ceilingbackslide;
#else
vtop = backsector->ceilingheight + textureheight[sidedef->toptexture];
// bottom of texture
rw_toptexturemid = vtop - viewz;
#endif
}
}
}
// check BOTTOM TEXTURE
if (worldlow > worldbottom
#ifdef ESLOPE
@ -2209,7 +2200,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
) //seulement si VISIBLE!!!
{
// bottom texture
bottomtexture = texturetranslation[sidedef->bottomtexture];
bottomtexture = R_GetTextureNum(sidedef->bottomtexture);
#ifdef ESLOPE
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
@ -2494,7 +2485,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->numthicksides = numthicksides = i;
}
if (sidedef->midtexture)
if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures)
{
// masked midtexture
if (!ds_p->thicksidecol)
@ -3101,12 +3092,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (maskedtexture && !(ds_p->silhouette & SIL_TOP))
{
ds_p->silhouette |= SIL_TOP;
ds_p->tsilheight = sidedef->midtexture ? INT32_MIN: INT32_MAX;
ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN: INT32_MAX;
}
if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM))
{
ds_p->silhouette |= SIL_BOTTOM;
ds_p->bsilheight = sidedef->midtexture ? INT32_MAX: INT32_MIN;
ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN;
}
ds_p++;
}

View file

@ -1699,21 +1699,25 @@ static void R_CreateDrawNodes(void)
entry->ffloor = ds->thicksides[i];
}
}
if (ds->maskedtexturecol)
{
#ifdef POLYOBJECTS_PLANES
// Check for a polyobject plane, but only if this is a front line
if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) {
// Put it in!
plane = ds->curline->polyseg->visplane;
R_PlaneBounds(plane);
if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low)
;
else {
// Put it in!
entry = R_CreateDrawNode(&nodehead);
entry->plane = ds->curline->polyseg->visplane;
entry->plane = plane;
entry->seg = ds;
ds->curline->polyseg->visplane->polyobj = ds->curline->polyseg;
}
ds->curline->polyseg->visplane = NULL;
}
#endif
if (ds->maskedtexturecol)
{
entry = R_CreateDrawNode(&nodehead);
entry->seg = ds;
}
@ -1756,6 +1760,29 @@ static void R_CreateDrawNodes(void)
}
}
#ifdef POLYOBJECTS_PLANES
// find all the remaining polyobject planes and add them on the end of the list
// probably this is a terrible idea if we wanted them to be sorted properly
// but it works getting them in for now
for (i = 0; i < numPolyObjects; i++)
{
if (!PolyObjects[i].visplane)
continue;
plane = PolyObjects[i].visplane;
R_PlaneBounds(plane);
if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low)
{
PolyObjects[i].visplane = NULL;
continue;
}
entry = R_CreateDrawNode(&nodehead);
entry->plane = plane;
// note: no seg is set, for what should be obvious reasons
PolyObjects[i].visplane = NULL;
}
#endif
if (visspritecount == 0)
return;
@ -1812,6 +1839,8 @@ static void R_CreateDrawNodes(void)
if (x1 < r2->plane->minx) x1 = r2->plane->minx;
if (x2 > r2->plane->maxx) x2 = r2->plane->maxx;
if (r2->seg) // if no seg set, assume the whole thing is in front or something stupid
{
for (i = x1; i <= x2; i++)
{
if (r2->seg->frontscale[i] > rover->scale)
@ -1819,6 +1848,7 @@ static void R_CreateDrawNodes(void)
}
if (i > x2)
continue;
}
entry = R_CreateDrawNode(NULL);
(entry->prev = r2->prev)->next = entry;