Merge branch 'master' of http://git.magicalgirl.moe/STJr/SRB2Internal.git into shield-actions

# Conflicts:
#	src/p_map.c
This commit is contained in:
toasterbabe 2016-10-11 16:25:24 +01:00
commit d25e908b80
18 changed files with 504 additions and 180 deletions

View file

@ -6597,7 +6597,7 @@ static const char *const MOBJFLAG_LIST[] = {
"SHOOTABLE", "SHOOTABLE",
"NOSECTOR", "NOSECTOR",
"NOBLOCKMAP", "NOBLOCKMAP",
"AMBUSH", "PAPERCOLLISION",
"PUSHABLE", "PUSHABLE",
"BOSS", "BOSS",
"SPAWNCEILING", "SPAWNCEILING",
@ -6654,6 +6654,8 @@ static const char *const MOBJFLAG2_LIST[] = {
"BOSSNOTRAP", // No Egg Trap after boss "BOSSNOTRAP", // No Egg Trap after boss
"BOSSFLEE", // Boss is fleeing! "BOSSFLEE", // Boss is fleeing!
"BOSSDEAD", // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) "BOSSDEAD", // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.)
"AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH
"LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
NULL NULL
}; };
@ -6977,9 +6979,13 @@ struct {
// Frame settings // Frame settings
{"FF_FRAMEMASK",FF_FRAMEMASK}, {"FF_FRAMEMASK",FF_FRAMEMASK},
{"FF_VERTICALFLIP",FF_VERTICALFLIP},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_SPR2ENDSTATE",FF_SPR2ENDSTATE}, {"FF_SPR2ENDSTATE",FF_SPR2ENDSTATE},
{"FF_MIDDLESTARTCHANCE",FF_MIDDLESTARTCHANCE}, {"FF_SPR2MIDSTART",FF_SPR2MIDSTART},
{"FF_ANIMATE",FF_ANIMATE}, {"FF_ANIMATE",FF_ANIMATE},
{"FF_RANDOMANIM",FF_RANDOMANIM},
{"FF_GLOBALANIM",FF_GLOBALANIM},
{"FF_FULLBRIGHT",FF_FULLBRIGHT}, {"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_TRANSMASK",FF_TRANSMASK}, {"FF_TRANSMASK",FF_TRANSMASK},
{"FF_TRANSSHIFT",FF_TRANSSHIFT}, {"FF_TRANSSHIFT",FF_TRANSSHIFT},

View file

@ -536,4 +536,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// \note You should leave this enabled unless you're working with a future SRB2 version. /// \note You should leave this enabled unless you're working with a future SRB2 version.
#define MUSICSLOT_COMPATIBILITY #define MUSICSLOT_COMPATIBILITY
/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
//#define PAPER_COLLISIONCORRECTION
#endif // __DOOMDEF__ #endif // __DOOMDEF__

View file

@ -5621,7 +5621,7 @@ boolean G_CheckDemoStatus(void)
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file.
#endif #endif
saved = FIL_WriteFile(demoname, demobuffer, demo_p - demobuffer); // finally output the file. saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file.
free(demobuffer); free(demobuffer);
demorecording = false; demorecording = false;

View file

@ -5040,6 +5040,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
size_t lumpoff; size_t lumpoff;
unsigned rot; unsigned rot;
UINT8 flip; UINT8 flip;
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
angle_t ang; angle_t ang;
INT32 heightsec, phs; INT32 heightsec, phs;
@ -5139,7 +5141,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale; tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale;
x2 = gr_windowcenterx + (tx * gr_centerx / tz); x2 = gr_windowcenterx + (tx * gr_centerx / tz);
if (thing->eflags & MFE_VERTICALFLIP) if (vflip)
{ {
gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale; gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale;
gzt = gz + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height) * this_scale; gzt = gz + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height) * this_scale;
@ -5216,10 +5218,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
//CONS_Debug(DBG_RENDER, "------------------\nH: sprite : %d\nH: frame : %x\nH: type : %d\nH: sname : %s\n\n", //CONS_Debug(DBG_RENDER, "------------------\nH: sprite : %d\nH: frame : %x\nH: type : %d\nH: sname : %s\n\n",
// thing->sprite, thing->frame, thing->type, sprnames[thing->sprite]); // thing->sprite, thing->frame, thing->type, sprnames[thing->sprite]);
if (thing->eflags & MFE_VERTICALFLIP) vis->vflip = vflip;
vis->vflip = true;
else
vis->vflip = false;
vis->precip = false; vis->precip = false;
} }

View file

@ -1349,7 +1349,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
UINT32 durs = spr->mobj->state->tics; UINT32 durs = spr->mobj->state->tics;
UINT32 tics = spr->mobj->tics; UINT32 tics = spr->mobj->tics;
md2_frame_t *curr, *next = NULL; md2_frame_t *curr, *next = NULL;
const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP); const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP));
spritedef_t *sprdef; spritedef_t *sprdef;
spriteframe_t *sprframe; spriteframe_t *sprframe;
float finalscale; float finalscale;
@ -1464,7 +1464,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
p.x = FIXED_TO_FLOAT(spr->mobj->x); p.x = FIXED_TO_FLOAT(spr->mobj->x);
p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset; p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset;
if (spr->mobj->eflags & MFE_VERTICALFLIP) if (flip)
p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height);
else else
p.z = FIXED_TO_FLOAT(spr->mobj->z); p.z = FIXED_TO_FLOAT(spr->mobj->z);

View file

@ -474,8 +474,8 @@ enum playersprite free_spr2 = SPR2_FIRSTFREESLOT;
state_t states[NUMSTATES] = state_t states[NUMSTATES] =
{ {
// frame is masked through FF_FRAMEMASK // frame is masked through FF_FRAMEMASK
// FF_ANIMATE (0x4000) makes simple state animations (var1 #frames, var2 tic delay) // FF_ANIMATE makes simple state animations (var1 #frames, var2 tic delay)
// FF_FULLBRIGHT (0x8000) activates the fullbright colormap // FF_FULLBRIGHT activates the fullbright colormap
// use FF_TRANS10 - FF_TRANS90 for easy translucency // use FF_TRANS10 - FF_TRANS90 for easy translucency
// (or tr_trans10<<FF_TRANSSHIFT if you want to make it hard on yourself) // (or tr_trans10<<FF_TRANSSHIFT if you want to make it hard on yourself)
@ -1392,7 +1392,7 @@ state_t states[NUMSTATES] =
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30|11, 1, {NULL}, 0, 0, S_MSSHIELD_F1}, // S_MSSHIELD_F12 {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30|11, 1, {NULL}, 0, 0, S_MSSHIELD_F1}, // S_MSSHIELD_F12
// Ring // Ring
{SPR_RING, FF_ANIMATE, -1, {NULL}, 23, 1, S_RING}, // S_RING {SPR_RING, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_RING}, // S_RING
// Blue Sphere Replacement for special stages // Blue Sphere Replacement for special stages
{SPR_BBAL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEBALL {SPR_BBAL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEBALL
@ -1408,7 +1408,7 @@ state_t states[NUMSTATES] =
{SPR_GWLR, 2, 1, {NULL}, 0, 0, S_GRAVWELLRED}, // S_GRAVWELLRED3 {SPR_GWLR, 2, 1, {NULL}, 0, 0, S_GRAVWELLRED}, // S_GRAVWELLRED3
// Individual Team Rings (now with shield attracting action! =P) // Individual Team Rings (now with shield attracting action! =P)
{SPR_TRNG, FF_ANIMATE, -1, {NULL}, 23, 1, S_TEAMRING}, // S_TEAMRING1 {SPR_TRNG, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_TEAMRING}, // S_TEAMRING1
// Special Stage Token // Special Stage Token
{SPR_EMMY, FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 6, 2, S_EMMY}, // S_EMMY {SPR_EMMY, FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 6, 2, S_EMMY}, // S_EMMY
@ -2297,7 +2297,7 @@ state_t states[NUMSTATES] =
// Extra Large Bubble goes POP! // Extra Large Bubble goes POP!
{SPR_BUBL, 5, 16, {NULL}, 0, 0, S_NULL}, // S_POP1 {SPR_BUBL, 5, 16, {NULL}, 0, 0, S_NULL}, // S_POP1
{SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_MIDDLESTARTCHANCE, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP {SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_RANDOMANIM, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP
{SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1 {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1
{SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50|1, 2, {NULL}, 0, 0, S_FOG3}, // S_FOG2 {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50|1, 2, {NULL}, 0, 0, S_FOG3}, // S_FOG2
@ -2366,16 +2366,16 @@ state_t states[NUMSTATES] =
{SPR_RRNG, FF_FULLBRIGHT|6, 1, {A_ThrownRing}, 0, 0, S_RRNG1}, // S_RRNG7 {SPR_RRNG, FF_FULLBRIGHT|6, 1, {A_ThrownRing}, 0, 0, S_RRNG1}, // S_RRNG7
// Weapon Ring Ammo // Weapon Ring Ammo
{SPR_RNGB, FF_ANIMATE, -1, {NULL}, 34, 1, S_BOUNCERINGAMMO}, // S_BOUNCERINGAMMO {SPR_RNGB, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_BOUNCERINGAMMO}, // S_BOUNCERINGAMMO
{SPR_RNGR, FF_ANIMATE, -1, {NULL}, 34, 1, S_RAILRINGAMMO}, // S_RAILRINGAMMO {SPR_RNGR, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_RAILRINGAMMO}, // S_RAILRINGAMMO
{SPR_RNGI, FF_ANIMATE, -1, {NULL}, 34, 1, S_INFINITYRINGAMMO}, // S_INFINITYRINGAMMO {SPR_RNGI, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_INFINITYRINGAMMO}, // S_INFINITYRINGAMMO
{SPR_RNGA, FF_ANIMATE, -1, {NULL}, 34, 1, S_AUTOMATICRINGAMMO}, // S_AUTOMATICRINGAMMO {SPR_RNGA, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_AUTOMATICRINGAMMO}, // S_AUTOMATICRINGAMMO
{SPR_RNGE, FF_ANIMATE, -1, {NULL}, 34, 1, S_EXPLOSIONRINGAMMO}, // S_EXPLOSIONRINGAMMO {SPR_RNGE, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_EXPLOSIONRINGAMMO}, // S_EXPLOSIONRINGAMMO
{SPR_RNGS, FF_ANIMATE, -1, {NULL}, 34, 1, S_SCATTERRINGAMMO}, // S_SCATTERRINGAMMO {SPR_RNGS, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_SCATTERRINGAMMO}, // S_SCATTERRINGAMMO
{SPR_RNGG, FF_ANIMATE, -1, {NULL}, 34, 1, S_GRENADERINGAMMO}, // S_GRENADERINGAMMO {SPR_RNGG, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_GRENADERINGAMMO}, // S_GRENADERINGAMMO
// Bounce Ring Pickup // Bounce Ring Pickup
{SPR_PIKB, FF_ANIMATE, -1, {NULL}, 15, 1, S_BOUNCEPICKUP}, // S_BOUNCEPICKUP {SPR_PIKB, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_BOUNCEPICKUP}, // S_BOUNCEPICKUP
{SPR_PIKB, 0, 1, {NULL}, 0, 0, S_BOUNCEPICKUPFADE2}, // S_BOUNCEPICKUPFADE1 {SPR_PIKB, 0, 1, {NULL}, 0, 0, S_BOUNCEPICKUPFADE2}, // S_BOUNCEPICKUPFADE1
{SPR_PIKB, 2, 1, {NULL}, 0, 0, S_BOUNCEPICKUPFADE3}, // S_BOUNCEPICKUPFADE2 {SPR_PIKB, 2, 1, {NULL}, 0, 0, S_BOUNCEPICKUPFADE3}, // S_BOUNCEPICKUPFADE2
@ -2387,7 +2387,7 @@ state_t states[NUMSTATES] =
{SPR_PIKB, 14, 1, {NULL}, 0, 0, S_BOUNCEPICKUPFADE1}, // S_BOUNCEPICKUPFADE8 {SPR_PIKB, 14, 1, {NULL}, 0, 0, S_BOUNCEPICKUPFADE1}, // S_BOUNCEPICKUPFADE8
// Rail Ring Pickup // Rail Ring Pickup
{SPR_PIKR, FF_ANIMATE, -1, {NULL}, 15, 1, S_RAILPICKUP}, // S_RAILPICKUP {SPR_PIKR, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_RAILPICKUP}, // S_RAILPICKUP
{SPR_PIKR, 0, 1, {NULL}, 0, 0, S_RAILPICKUPFADE2}, // S_RAILPICKUPFADE1 {SPR_PIKR, 0, 1, {NULL}, 0, 0, S_RAILPICKUPFADE2}, // S_RAILPICKUPFADE1
{SPR_PIKR, 2, 1, {NULL}, 0, 0, S_RAILPICKUPFADE3}, // S_RAILPICKUPFADE2 {SPR_PIKR, 2, 1, {NULL}, 0, 0, S_RAILPICKUPFADE3}, // S_RAILPICKUPFADE2
@ -2399,7 +2399,7 @@ state_t states[NUMSTATES] =
{SPR_PIKR, 14, 1, {NULL}, 0, 0, S_RAILPICKUPFADE1}, // S_RAILPICKUPFADE8 {SPR_PIKR, 14, 1, {NULL}, 0, 0, S_RAILPICKUPFADE1}, // S_RAILPICKUPFADE8
// Auto Ring Pickup // Auto Ring Pickup
{SPR_PIKA, FF_ANIMATE, -1, {NULL}, 15, 1, S_AUTOPICKUP}, // S_AUTOPICKUP {SPR_PIKA, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_AUTOPICKUP}, // S_AUTOPICKUP
{SPR_PIKA, 0, 1, {NULL}, 0, 0, S_AUTOPICKUPFADE2}, // S_AUTOPICKUPFADE1 {SPR_PIKA, 0, 1, {NULL}, 0, 0, S_AUTOPICKUPFADE2}, // S_AUTOPICKUPFADE1
{SPR_PIKA, 2, 1, {NULL}, 0, 0, S_AUTOPICKUPFADE3}, // S_AUTOPICKUPFADE2 {SPR_PIKA, 2, 1, {NULL}, 0, 0, S_AUTOPICKUPFADE3}, // S_AUTOPICKUPFADE2
@ -2411,7 +2411,7 @@ state_t states[NUMSTATES] =
{SPR_PIKA, 14, 1, {NULL}, 0, 0, S_AUTOPICKUPFADE1}, // S_AUTOPICKUPFADE8 {SPR_PIKA, 14, 1, {NULL}, 0, 0, S_AUTOPICKUPFADE1}, // S_AUTOPICKUPFADE8
// Explode Ring Pickup // Explode Ring Pickup
{SPR_PIKE, FF_ANIMATE, -1, {NULL}, 15, 1, S_EXPLODEPICKUP}, // S_EXPLODEPICKUP {SPR_PIKE, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_EXPLODEPICKUP}, // S_EXPLODEPICKUP
{SPR_PIKE, 0, 1, {NULL}, 0, 0, S_EXPLODEPICKUPFADE2}, // S_EXPLODEPICKUPFADE1 {SPR_PIKE, 0, 1, {NULL}, 0, 0, S_EXPLODEPICKUPFADE2}, // S_EXPLODEPICKUPFADE1
{SPR_PIKE, 2, 1, {NULL}, 0, 0, S_EXPLODEPICKUPFADE3}, // S_EXPLODEPICKUPFADE2 {SPR_PIKE, 2, 1, {NULL}, 0, 0, S_EXPLODEPICKUPFADE3}, // S_EXPLODEPICKUPFADE2
@ -2423,7 +2423,7 @@ state_t states[NUMSTATES] =
{SPR_PIKE, 14, 1, {NULL}, 0, 0, S_EXPLODEPICKUPFADE1}, // S_EXPLODEPICKUPFADE8 {SPR_PIKE, 14, 1, {NULL}, 0, 0, S_EXPLODEPICKUPFADE1}, // S_EXPLODEPICKUPFADE8
// Scatter Ring Pickup // Scatter Ring Pickup
{SPR_PIKS, FF_ANIMATE, -1, {NULL}, 15, 1, S_SCATTERPICKUP}, // S_SCATTERPICKUP {SPR_PIKS, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_SCATTERPICKUP}, // S_SCATTERPICKUP
{SPR_PIKS, 0, 1, {NULL}, 0, 0, S_SCATTERPICKUPFADE2}, // S_SCATTERPICKUPFADE1 {SPR_PIKS, 0, 1, {NULL}, 0, 0, S_SCATTERPICKUPFADE2}, // S_SCATTERPICKUPFADE1
{SPR_PIKS, 2, 1, {NULL}, 0, 0, S_SCATTERPICKUPFADE3}, // S_SCATTERPICKUPFADE2 {SPR_PIKS, 2, 1, {NULL}, 0, 0, S_SCATTERPICKUPFADE3}, // S_SCATTERPICKUPFADE2
@ -2435,7 +2435,7 @@ state_t states[NUMSTATES] =
{SPR_PIKS, 14, 1, {NULL}, 0, 0, S_SCATTERPICKUPFADE1}, // S_SCATTERPICKUPFADE8 {SPR_PIKS, 14, 1, {NULL}, 0, 0, S_SCATTERPICKUPFADE1}, // S_SCATTERPICKUPFADE8
// Grenade Ring Pickup // Grenade Ring Pickup
{SPR_PIKG, FF_ANIMATE, -1, {NULL}, 15, 1, S_GRENADEPICKUP}, // S_GRENADEPICKUP {SPR_PIKG, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_GRENADEPICKUP}, // S_GRENADEPICKUP
{SPR_PIKG, 0, 1, {NULL}, 0, 0, S_GRENADEPICKUPFADE2}, // S_GRENADEPICKUPFADE1 {SPR_PIKG, 0, 1, {NULL}, 0, 0, S_GRENADEPICKUPFADE2}, // S_GRENADEPICKUPFADE1
{SPR_PIKG, 2, 1, {NULL}, 0, 0, S_GRENADEPICKUPFADE3}, // S_GRENADEPICKUPFADE2 {SPR_PIKG, 2, 1, {NULL}, 0, 0, S_GRENADEPICKUPFADE3}, // S_GRENADEPICKUPFADE2
@ -2756,22 +2756,22 @@ state_t states[NUMSTATES] =
{SPR_NULL, 0, 1, {A_RockSpawn}, 0, 0, S_ROCKSPAWN}, // S_ROCKSPAWN {SPR_NULL, 0, 1, {A_RockSpawn}, 0, 0, S_ROCKSPAWN}, // S_ROCKSPAWN
{SPR_ROIA, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEA}, // S_ROCKCRUMBLEA {SPR_ROIA, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEA}, // S_ROCKCRUMBLEA
{SPR_ROIB, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEB}, // S_ROCKCRUMBLEB {SPR_ROIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEB}, // S_ROCKCRUMBLEB
{SPR_ROIC, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEC}, // S_ROCKCRUMBLEC {SPR_ROIC, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEC}, // S_ROCKCRUMBLEC
{SPR_ROID, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLED}, // S_ROCKCRUMBLED {SPR_ROID, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLED}, // S_ROCKCRUMBLED
{SPR_ROIE, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEE}, // S_ROCKCRUMBLEE {SPR_ROIE, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEE}, // S_ROCKCRUMBLEE
{SPR_ROIF, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEF}, // S_ROCKCRUMBLEF {SPR_ROIF, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEF}, // S_ROCKCRUMBLEF
{SPR_ROIG, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEG}, // S_ROCKCRUMBLEG {SPR_ROIG, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEG}, // S_ROCKCRUMBLEG
{SPR_ROIH, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEH}, // S_ROCKCRUMBLEH {SPR_ROIH, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEH}, // S_ROCKCRUMBLEH
{SPR_ROII, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEI}, // S_ROCKCRUMBLEI {SPR_ROII, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEI}, // S_ROCKCRUMBLEI
{SPR_ROIJ, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEJ}, // S_ROCKCRUMBLEJ {SPR_ROIJ, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEJ}, // S_ROCKCRUMBLEJ
{SPR_ROIK, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEK}, // S_ROCKCRUMBLEK {SPR_ROIK, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEK}, // S_ROCKCRUMBLEK
{SPR_ROIL, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEL}, // S_ROCKCRUMBLEL {SPR_ROIL, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEL}, // S_ROCKCRUMBLEL
{SPR_ROIM, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEM}, // S_ROCKCRUMBLEM {SPR_ROIM, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEM}, // S_ROCKCRUMBLEM
{SPR_ROIN, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEN}, // S_ROCKCRUMBLEN {SPR_ROIN, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEN}, // S_ROCKCRUMBLEN
{SPR_ROIO, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEO}, // S_ROCKCRUMBLEO {SPR_ROIO, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEO}, // S_ROCKCRUMBLEO
{SPR_ROIP, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEP}, // S_ROCKCRUMBLEP {SPR_ROIP, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_ROCKCRUMBLEP}, // S_ROCKCRUMBLEP
{SPR_SRBA, 0, 5, {A_Look}, 0, 0, S_SRB1_CRAWLA1}, // S_SRB1_CRAWLA1 {SPR_SRBA, 0, 5, {A_Look}, 0, 0, S_SRB1_CRAWLA1}, // S_SRB1_CRAWLA1
{SPR_SRBA, 0, 3, {A_Chase}, 0, 0, S_SRB1_CRAWLA3}, // S_SRB1_CRAWLA2 {SPR_SRBA, 0, 3, {A_Chase}, 0, 0, S_SRB1_CRAWLA3}, // S_SRB1_CRAWLA2
@ -5613,7 +5613,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
32*FRACUNIT, // height 32*FRACUNIT, // height
0, // display offset 0, // display offset
0, // mass 0, // mass
16*FRACUNIT, // damage 36*FRACUNIT, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags
S_YHORIZ2 // raisestate S_YHORIZ2 // raisestate
@ -5640,7 +5640,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
32*FRACUNIT, // height 32*FRACUNIT, // height
0, // display offset 0, // display offset
0, // mass 0, // mass
64*FRACUNIT, // damage 72*FRACUNIT, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags
S_RHORIZ2 // raisestate S_RHORIZ2 // raisestate

View file

@ -1054,7 +1054,7 @@ void OP_NightsObjectplace(player_t *player)
if (!OP_HeightOkay(player, false)) if (!OP_HeightOkay(player, false))
return; return;
if (player->mo->target->flags & MF_AMBUSH) if (player->mo->target->flags2 & MF2_AMBUSH)
angle = (UINT16)player->anotherflyangle; angle = (UINT16)player->anotherflyangle;
else else
{ {

View file

@ -3538,7 +3538,7 @@ void A_BubbleSpawn(mobj_t *actor)
} }
actor->flags2 &= ~MF2_DONTDRAW; actor->flags2 &= ~MF2_DONTDRAW;
if (!(actor->flags & MF_AMBUSH)) if (!(actor->flags2 & MF2_AMBUSH))
{ {
// Quick! Look through players! // Quick! Look through players!
// Don't spawn bubbles unless a player is relatively close by (var2). // Don't spawn bubbles unless a player is relatively close by (var2).
@ -3586,7 +3586,7 @@ void A_FanBubbleSpawn(mobj_t *actor)
if (!(actor->eflags & MFE_UNDERWATER)) if (!(actor->eflags & MFE_UNDERWATER))
return; return;
if (!(actor->flags & MF_AMBUSH)) if (!(actor->flags2 & MF2_AMBUSH))
{ {
// Quick! Look through players! // Quick! Look through players!
// Don't spawn bubbles unless a player is relatively close by (var2). // Don't spawn bubbles unless a player is relatively close by (var2).
@ -4153,7 +4153,7 @@ void A_JetChase(mobj_t *actor)
return; return;
#endif #endif
if (actor->flags & MF_AMBUSH) if (actor->flags2 & MF2_AMBUSH)
return; return;
if (actor->z >= actor->waterbottom && actor->watertop > actor->floorz if (actor->z >= actor->waterbottom && actor->watertop > actor->floorz
@ -5046,7 +5046,7 @@ void A_SlingAppear(mobj_t *actor)
if (firsttime) if (firsttime)
{ {
// This is the outermost link in the chain // This is the outermost link in the chain
spawnee->flags |= MF_AMBUSH; spawnee->flags2 |= MF2_AMBUSH;
firsttime = false; firsttime = false;
} }
@ -6029,7 +6029,7 @@ void A_Boss2Chase(mobj_t *actor)
{ {
actor->watertop = -actor->watertop; actor->watertop = -actor->watertop;
actor->extravalue1 = 18; actor->extravalue1 = 18;
if (actor->flags & MF_AMBUSH) if (actor->flags2 & MF2_AMBUSH)
actor->extravalue1 -= (actor->info->spawnhealth - actor->health)*2; actor->extravalue1 -= (actor->info->spawnhealth - actor->health)*2;
actor->extravalue2 = actor->extravalue1; actor->extravalue2 = actor->extravalue1;
} }
@ -6055,7 +6055,7 @@ void A_Boss2Chase(mobj_t *actor)
else else
{ {
// Only speed up if you have the 'Deaf' flag. // Only speed up if you have the 'Deaf' flag.
if (actor->flags & MF_AMBUSH) if (actor->flags2 & MF2_AMBUSH)
speedvar = actor->health; speedvar = actor->health;
else else
speedvar = actor->info->spawnhealth; speedvar = actor->info->spawnhealth;
@ -6646,7 +6646,7 @@ void A_BuzzFly(mobj_t *actor)
if (LUA_CallAction("A_BuzzFly", actor)) if (LUA_CallAction("A_BuzzFly", actor))
return; return;
#endif #endif
if (actor->flags & MF_AMBUSH) if (actor->flags2 & MF2_AMBUSH)
return; return;
if (actor->reactiontime) if (actor->reactiontime)
@ -6786,7 +6786,7 @@ void A_GuardChase(mobj_t *actor)
return; // got a new target return; // got a new target
// chase towards player // chase towards player
if (--actor->movecount < 0 || !P_Move(actor, (actor->flags & MF_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed))
{ {
P_NewChaseDir(actor); P_NewChaseDir(actor);
actor->movecount += 5; // Increase tics before change in direction allowed. actor->movecount += 5; // Increase tics before change in direction allowed.

View file

@ -1340,7 +1340,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
case MT_SMALLMACECHAIN: case MT_SMALLMACECHAIN:
case MT_BIGMACECHAIN: case MT_BIGMACECHAIN:
// Is this the last link in the chain? // Is this the last link in the chain?
if (toucher->momz > 0 || !(special->flags & MF_AMBUSH) if (toucher->momz > 0 || !(special->flags2 & MF2_AMBUSH)
|| (player->powers[pw_carry])) || (player->powers[pw_carry]))
return; return;

View file

@ -115,6 +115,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
fixed_t offx, offy; fixed_t offx, offy;
fixed_t vertispeed = spring->info->mass; fixed_t vertispeed = spring->info->mass;
fixed_t horizspeed = spring->info->damage; fixed_t horizspeed = spring->info->damage;
UINT8 jumping, secondjump;
if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
return false; return false;
@ -203,25 +204,30 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
} }
pflags = object->player->pflags & (PF_JUMPED|PF_SPINNING|PF_THOKKED|PF_SHIELDABILITY); // I still need these. pflags = object->player->pflags & (PF_JUMPED|PF_SPINNING|PF_THOKKED|PF_SHIELDABILITY); // I still need these.
jumping = object->player->jumping;
secondjump = object->player->secondjump;
P_ResetPlayer(object->player); P_ResetPlayer(object->player);
if (P_MobjFlip(object)*vertispeed > 0) if (spring->info->painchance)
{
object->player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(object, S_PLAY_JUMP);
}
else if (P_MobjFlip(object)*vertispeed > 0)
P_SetPlayerMobjState(object, S_PLAY_SPRING); P_SetPlayerMobjState(object, S_PLAY_SPRING);
else if (P_MobjFlip(object)*vertispeed < 0) else if (P_MobjFlip(object)*vertispeed < 0)
P_SetPlayerMobjState(object, S_PLAY_FALL); P_SetPlayerMobjState(object, S_PLAY_FALL);
else // horizontal spring else // horizontal spring
{ {
if (pflags & (PF_JUMPED|PF_SPINNING) && (object->player->panim == PA_ROLL || object->player->panim == PA_JUMP || object->player->panim == PA_FALL)) if (pflags & (PF_JUMPED|PF_SPINNING) && (object->player->panim == PA_ROLL || object->player->panim == PA_JUMP || object->player->panim == PA_FALL))
object->player->pflags = pflags; {
object->player->pflags |= pflags;
object->player->jumping = jumping;
object->player->secondjump = secondjump;
}
else else
P_SetPlayerMobjState(object, S_PLAY_WALK); P_SetPlayerMobjState(object, S_PLAY_WALK);
} }
if (spring->info->painchance)
{
object->player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(object, S_PLAY_JUMP);
}
} }
return true; return true;
} }
@ -501,6 +507,74 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
return true; // didn't hit it return true; // didn't hit it
if (thing->flags & MF_PAPERCOLLISION) // CAUTION! Very easy to get stuck inside MF_SOLID objects. Giving the player MF_PAPERCOLLISION is a bad idea unless you know what you're doing.
{
fixed_t cosradius, sinradius;
vertex_t v1, v2; // fake vertexes
line_t junk; // fake linedef
cosradius = FixedMul(thing->radius, FINECOSINE(thing->angle>>ANGLETOFINESHIFT));
sinradius = FixedMul(thing->radius, FINESINE(thing->angle>>ANGLETOFINESHIFT));
v1.x = thing->x - cosradius;
v1.y = thing->y - sinradius;
v2.x = thing->x + cosradius;
v2.y = thing->y + sinradius;
junk.v1 = &v1;
junk.v2 = &v2;
junk.dx = v2.x - v1.x;
junk.dy = v2.y - v1.y;
if (tmthing->flags & MF_PAPERCOLLISION) // more strenuous checking to prevent clipping issues
{
INT32 check1, check2, check3, check4;
cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT));
sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT));
check1 = P_PointOnLineSide(tmx - cosradius, tmy - sinradius, &junk);
check2 = P_PointOnLineSide(tmx + cosradius, tmy + sinradius, &junk);
check3 = P_PointOnLineSide(tmx + tmthing->momx - cosradius, tmy + tmthing->momy - sinradius, &junk);
check4 = P_PointOnLineSide(tmx + tmthing->momx + cosradius, tmy + tmthing->momy + sinradius, &junk);
if ((check1 == check2) && (check2 == check3) && (check3 == check4))
return true; // the line doesn't cross between collider's start or end
}
else
{
if ((P_PointOnLineSide(tmx - tmthing->radius, tmy - tmthing->radius, &junk)
== P_PointOnLineSide(tmx + tmthing->radius, tmy + tmthing->radius, &junk))
&& (P_PointOnLineSide(tmx + tmthing->radius, tmy - tmthing->radius, &junk)
== P_PointOnLineSide(tmx - tmthing->radius, tmy + tmthing->radius, &junk)))
return true; // the line doesn't cross between either pair of opposite corners
}
}
else if (tmthing->flags & MF_PAPERCOLLISION)
{
fixed_t cosradius, sinradius;
vertex_t v1, v2; // fake vertexes
line_t junk; // fake linedef
cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT));
sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT));
v1.x = tmx - cosradius;
v1.y = tmy - sinradius;
v2.x = tmx + cosradius;
v2.y = tmy + sinradius;
junk.v1 = &v1;
junk.v2 = &v2;
junk.dx = v2.x - v1.x;
junk.dy = v2.y - v1.y;
// no need to check whether thing has MF_PAPERCOLLISION, since checked above
if ((P_PointOnLineSide(thing->x - thing->radius, thing->y - thing->radius, &junk)
== P_PointOnLineSide(thing->x + thing->radius, thing->y + thing->radius, &junk))
&& (P_PointOnLineSide(thing->x + thing->radius, thing->y - thing->radius, &junk)
== P_PointOnLineSide(thing->x - thing->radius, thing->y + thing->radius, &junk)))
return true; // the line doesn't cross between either pair of opposite corners
}
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
{ {
UINT8 shouldCollide = LUAh_MobjCollide(thing, tmthing); // checks hook for thing's type UINT8 shouldCollide = LUAh_MobjCollide(thing, tmthing); // checks hook for thing's type
@ -1181,6 +1255,32 @@ static boolean PIT_CheckLine(line_t *ld)
if (P_BoxOnLineSide(tmbbox, ld) != -1) if (P_BoxOnLineSide(tmbbox, ld) != -1)
return true; return true;
if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag.
{
fixed_t cosradius, sinradius;
cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT));
sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT));
if (P_PointOnLineSide(tmx - cosradius, tmy - sinradius, ld)
== P_PointOnLineSide(tmx + cosradius, tmy + sinradius, ld))
return true; // the line doesn't cross between collider's start or end
#ifdef PAPER_COLLISIONCORRECTION
{
fixed_t dist;
vertex_t result;
angle_t langle;
P_ClosestPointOnLine(tmx, tmy, ld, &result);
langle = R_PointToAngle2(ld->v1->x, ld->v1->y, ld->v2->x, ld->v2->y);
langle += ANGLE_90*(P_PointOnLineSide(tmx, tmy, ld) ? -1 : 1);
dist = abs(FixedMul(tmthing->radius, FINECOSINE((tmthing->angle - langle)>>ANGLETOFINESHIFT)));
cosradius = FixedMul(dist, FINECOSINE(langle>>ANGLETOFINESHIFT));
sinradius = FixedMul(dist, FINESINE(langle>>ANGLETOFINESHIFT));
tmthing->flags |= MF_NOCLIP;
P_TeleportMove(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z);
tmthing->flags &= ~MF_NOCLIP;
}
#endif
}
// A line has been hit // A line has been hit
// The moving thing's destination position will cross // The moving thing's destination position will cross

View file

@ -81,6 +81,36 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum)
actioncachehead.prev = newaction; actioncachehead.prev = newaction;
} }
//
// P_SetupStateAnimation
//
FUNCINLINE static ATTRINLINE void P_SetupStateAnimation(mobj_t *mobj, state_t *st)
{
if (!(st->frame & FF_ANIMATE))
return;
if (st->var1 == 0 || st->var2 == 0)
{
mobj->frame &= ~FF_ANIMATE;
return; // Crash/stupidity prevention
}
mobj->anim_duration = (UINT16)st->var2;
if (st->frame & FF_GLOBALANIM)
{
// Attempt to account for the pre-ticker for objects spawned on load
if (!leveltime) return;
mobj->anim_duration -= (leveltime + 2) % st->var2; // Duration synced to timer
mobj->frame += ((leveltime + 2) / st->var2) % (st->var1 + 1); // Frame synced to timer (duration taken into account)
}
else if (st->frame & FF_RANDOMANIM)
{
mobj->frame += P_RandomKey(st->var1 + 1); // Random starting frame
mobj->anim_duration -= P_RandomKey(st->var2); // Random duration for first frame
}
}
// //
// P_CycleStateAnimation // P_CycleStateAnimation
// //
@ -588,7 +618,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
} }
else if (mobj->sprite2 != spr2) else if (mobj->sprite2 != spr2)
{ {
if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2)) if ((st->frame & FF_SPR2MIDSTART) && numframes && P_RandomChance(FRACUNIT/2))
frame = numframes/2; frame = numframes/2;
else else
frame = 0; frame = 0;
@ -621,8 +651,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
{ {
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; mobj->frame = st->frame;
if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) P_SetupStateAnimation(mobj, st);
mobj->frame += P_RandomKey(st->var1+1);
} }
// Modified handling. // Modified handling.
@ -689,7 +718,6 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
st = &states[state]; st = &states[state];
mobj->state = st; mobj->state = st;
mobj->tics = st->tics; mobj->tics = st->tics;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
// Player animations // Player animations
if (st->sprite == SPR_PLAY) if (st->sprite == SPR_PLAY)
@ -714,7 +742,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
} }
else if (mobj->sprite2 != spr2) else if (mobj->sprite2 != spr2)
{ {
if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2)) if ((st->frame & FF_SPR2MIDSTART) && numframes && P_RandomChance(FRACUNIT/2))
frame = numframes/2; frame = numframes/2;
else else
frame = 0; frame = 0;
@ -736,8 +764,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
{ {
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; mobj->frame = st->frame;
if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) P_SetupStateAnimation(mobj, st);
mobj->frame += P_RandomKey(st->var1+1);
} }
// Modified handling. // Modified handling.
@ -792,7 +819,7 @@ boolean P_SetMobjStateNF(mobj_t *mobj, statenum_t state)
mobj->tics = st->tics; mobj->tics = st->tics;
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set P_SetupStateAnimation(mobj, st);
return true; return true;
} }
@ -811,7 +838,7 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state)
mobj->tics = st->tics; mobj->tics = st->tics;
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set P_SetupStateAnimation((mobj_t*)mobj, st);
return true; return true;
} }
@ -1858,7 +1885,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
mo->momx = player->cmomx; mo->momx = player->cmomx;
mo->momy = player->cmomy; mo->momy = player->cmomy;
} }
else else if (!(mo->eflags & MFE_SPRUNG))
{ {
if (oldx == mo->x && oldy == mo->y) // didn't go anywhere if (oldx == mo->x && oldy == mo->y) // didn't go anywhere
{ {
@ -2843,7 +2870,7 @@ static boolean P_ZMovement(mobj_t *mo)
&& abs(mom.y) < FixedMul(STOPSPEED, mo->scale) && abs(mom.y) < FixedMul(STOPSPEED, mo->scale)
&& abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale))
{ {
if (mo->flags & MF_AMBUSH) if (mo->flags2 & MF2_AMBUSH)
{ {
// If deafed, give the tumbleweed another random kick if it runs out of steam. // If deafed, give the tumbleweed another random kick if it runs out of steam.
mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale);
@ -6827,7 +6854,7 @@ void P_MobjThinker(mobj_t *mobj)
flame->angle = mobj->angle; flame->angle = mobj->angle;
if (mobj->flags & MF_AMBUSH) // Wave up and down instead of side-to-side if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side
flame->momz = mobj->fuse << (FRACBITS-2); flame->momz = mobj->fuse << (FRACBITS-2);
else else
flame->angle += FixedAngle(mobj->fuse*FRACUNIT); flame->angle += FixedAngle(mobj->fuse*FRACUNIT);
@ -6862,7 +6889,7 @@ void P_MobjThinker(mobj_t *mobj)
strength -= ((20*FRACUNIT)/16)*mobj->movedir; strength -= ((20*FRACUNIT)/16)*mobj->movedir;
// If deaf'd, the object spawns on the ceiling. // If deaf'd, the object spawns on the ceiling.
if (mobj->flags & MF_AMBUSH) if (mobj->flags2 & MF2_AMBUSH)
{ {
mobj->z = mobj->ceilingz-mobj->height; mobj->z = mobj->ceilingz-mobj->height;
flame->momz = -strength; flame->momz = -strength;
@ -7666,7 +7693,7 @@ void P_MobjThinker(mobj_t *mobj)
{ {
// Special case for ALL monitors. // Special case for ALL monitors.
// If a box's speed is nonzero, it's allowed to respawn as a WRM/SRM. // If a box's speed is nonzero, it's allowed to respawn as a WRM/SRM.
if (mobj->info->speed != 0 && (mobj->flags & MF_AMBUSH || mobj->flags2 & MF2_STRONGBOX)) if (mobj->info->speed != 0 && (mobj->flags2 & (MF2_AMBUSH|MF2_STRONGBOX)))
{ {
mobjtype_t spawnchance[64]; mobjtype_t spawnchance[64];
INT32 numchoices = 0, i = 0; INT32 numchoices = 0, i = 0;
@ -7693,21 +7720,12 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
i = P_RandomKey(numchoices); // Gotta love those random numbers! i = P_RandomKey(numchoices); // Gotta love those random numbers!
newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]); newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]);
// If the monitor respawns randomly, transfer the flag.
if (mobj->flags & MF_AMBUSH)
newmobj->flags |= MF_AMBUSH;
// Transfer flags2 (strongbox, objectflip)
newmobj->flags2 = mobj->flags2;
} }
else else
{
newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type);
// Transfer flags2 (strongbox, objectflip) // Transfer flags2 (ambush, strongbox, objectflip)
newmobj->flags2 = mobj->flags2; newmobj->flags2 = mobj->flags2;
}
P_RemoveMobj(mobj); // make sure they disappear P_RemoveMobj(mobj); // make sure they disappear
return; return;
} }
@ -8079,7 +8097,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->tics = st->tics; mobj->tics = st->tics;
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set P_SetupStateAnimation(mobj, st);
mobj->friction = ORIG_FRICTION; mobj->friction = ORIG_FRICTION;
@ -8305,7 +8323,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
mobj->tics = st->tics; mobj->tics = st->tics;
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set P_SetupStateAnimation((mobj_t*)mobj, st);
// set subsector and/or block links // set subsector and/or block links
P_SetPrecipitationThingPosition(mobj); P_SetPrecipitationThingPosition(mobj);
@ -9585,7 +9603,7 @@ ML_NOCLIMB : Direction not controllable
if (firsttime) if (firsttime)
{ {
// This is the outermost link in the chain // This is the outermost link in the chain
spawnee->flags |= MF_AMBUSH; spawnee->flags2 |= MF2_AMBUSH;
firsttime = false; firsttime = false;
} }
@ -9657,7 +9675,7 @@ ML_NOCLIMB : Direction not controllable
{ {
// Inverted if uppermost bit is set // Inverted if uppermost bit is set
if (mthing->angle & 16384) if (mthing->angle & 16384)
mobj->flags |= MF_AMBUSH; mobj->flags2 |= MF2_AMBUSH;
if (mthing->angle > 0) if (mthing->angle > 0)
mobj->radius = (mthing->angle & 16383)*FRACUNIT; mobj->radius = (mthing->angle & 16383)*FRACUNIT;
@ -9829,7 +9847,7 @@ ML_NOCLIMB : Direction not controllable
{ {
// flag for strong/weak random boxes // flag for strong/weak random boxes
// any monitor with nonzero speed is allowed to respawn like this // any monitor with nonzero speed is allowed to respawn like this
mobj->flags |= MF_AMBUSH; mobj->flags2 |= MF2_AMBUSH;
} }
else if (mthing->type != mobjinfo[MT_AXIS].doomednum && else if (mthing->type != mobjinfo[MT_AXIS].doomednum &&
@ -9837,7 +9855,7 @@ ML_NOCLIMB : Direction not controllable
mthing->type != mobjinfo[MT_AXISTRANSFERLINE].doomednum && mthing->type != mobjinfo[MT_AXISTRANSFERLINE].doomednum &&
mthing->type != mobjinfo[MT_NIGHTSBUMPER].doomednum && mthing->type != mobjinfo[MT_NIGHTSBUMPER].doomednum &&
mthing->type != mobjinfo[MT_STARPOST].doomednum) mthing->type != mobjinfo[MT_STARPOST].doomednum)
mobj->flags |= MF_AMBUSH; mobj->flags2 |= MF2_AMBUSH;
} }
if (mthing->options & MTF_OBJECTSPECIAL) if (mthing->options & MTF_OBJECTSPECIAL)
@ -10174,7 +10192,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
P_SetMobjState(mobj, mobj->info->seestate); P_SetMobjState(mobj, mobj->info->seestate);
mobj->angle = FixedAngle(mthing->angle*FRACUNIT); mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
mobj->flags |= MF_AMBUSH; mobj->flags2 |= MF2_AMBUSH;
mthing->mobj = mobj; mthing->mobj = mobj;
} }
// All manners of rings and coins // All manners of rings and coins
@ -10248,7 +10266,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
} }
mobj->angle = FixedAngle(mthing->angle*FRACUNIT); mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
mobj->flags |= MF_AMBUSH; mobj->flags2 |= MF2_AMBUSH;
mthing->mobj = mobj; mthing->mobj = mobj;
} }
// *** // ***
@ -10304,7 +10322,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
mobj->angle = FixedAngle(mthing->angle*FRACUNIT); mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
if (mthing->options & MTF_AMBUSH) if (mthing->options & MTF_AMBUSH)
mobj->flags |= MF_AMBUSH; mobj->flags2 |= MF2_AMBUSH;
} }
} }
// Diagonal rings (handles both types) // Diagonal rings (handles both types)
@ -10362,7 +10380,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
mobj->angle = FixedAngle(mthing->angle*FRACUNIT); mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
if (mthing->options & MTF_AMBUSH) if (mthing->options & MTF_AMBUSH)
mobj->flags |= MF_AMBUSH; mobj->flags2 |= MF2_AMBUSH;
} }
} }
// Rings of items (all six of them) // Rings of items (all six of them)

View file

@ -107,8 +107,8 @@ typedef enum
MF_NOSECTOR = 1<<3, MF_NOSECTOR = 1<<3,
// Don't use the blocklinks (inert but displayable) // Don't use the blocklinks (inert but displayable)
MF_NOBLOCKMAP = 1<<4, MF_NOBLOCKMAP = 1<<4,
// Not to be activated by sound, deaf monster. // Thin, paper-like collision bound (for visual equivalent, see FF_PAPERSPRITE)
MF_AMBUSH = 1<<5, MF_PAPERCOLLISION = 1<<5,
// You can push this object. It can activate switches and things by pushing it on top. // You can push this object. It can activate switches and things by pushing it on top.
MF_PUSHABLE = 1<<6, MF_PUSHABLE = 1<<6,
// Object is a boss. // Object is a boss.
@ -151,10 +151,9 @@ typedef enum
MF_PAIN = 1<<24, MF_PAIN = 1<<24,
// This mobj will stick to any surface or solid object it touches. // This mobj will stick to any surface or solid object it touches.
MF_STICKY = 1<<25, MF_STICKY = 1<<25,
// NiGHTS hidden item. Goes to seestate and turns MF_SPECIAL when paralooped. // NiGHTS hidden item. Goes to seestate and turns MF_SPECIAL when paralooped.
MF_NIGHTSITEM = 1<<26, MF_NIGHTSITEM = 1<<26,
// for chase camera, don't be blocked by things (partial clipping) // for chase camera, don't be blocked by things (partial clipping)
// (need comma at end of this for SOC editor)
MF_NOCLIPTHING = 1<<27, MF_NOCLIPTHING = 1<<27,
// Missile bounces like a grenade. // Missile bounces like a grenade.
MF_GRENADEBOUNCE = 1<<28, MF_GRENADEBOUNCE = 1<<28,
@ -192,6 +191,8 @@ typedef enum
MF2_BOSSNOTRAP = 1<<24, // No Egg Trap after boss MF2_BOSSNOTRAP = 1<<24, // No Egg Trap after boss
MF2_BOSSFLEE = 1<<25, // Boss is fleeing! MF2_BOSSFLEE = 1<<25, // Boss is fleeing!
MF2_BOSSDEAD = 1<<26, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) MF2_BOSSDEAD = 1<<26, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.)
MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH
MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
// free: to and including 1<<31 // free: to and including 1<<31
} mobjflag2_t; } mobjflag2_t;

View file

@ -37,14 +37,12 @@
/// \brief Frame flags: only the frame number - 0 to 511 (Frames from 0 to 63, Sprite2 number uses full range) /// \brief Frame flags: only the frame number - 0 to 511 (Frames from 0 to 63, Sprite2 number uses full range)
#define FF_FRAMEMASK 0x1ff #define FF_FRAMEMASK 0x1ff
/// \brief Frame flags: A change of state at the end of Sprite2 animation
/// \brief Frame flags - SPR2: A change of state at the end of Sprite2 animation
#define FF_SPR2ENDSTATE 0x1000 #define FF_SPR2ENDSTATE 0x1000
/// \brief Frame flags: 50% of starting in middle of animation (Sprite2 and FF_ANIMATE) /// \brief Frame flags - SPR2: 50% of starting in middle of Sprite2 animation
#define FF_MIDDLESTARTCHANCE 0x2000 #define FF_SPR2MIDSTART 0x2000
/// \brief Frame flags: Simple stateless animation
#define FF_ANIMATE 0x4000
/// \brief Frame flags: frame always appears full bright
#define FF_FULLBRIGHT 0x8000
/// \brief Frame flags: 0 = no trans(opaque), 1-15 = transl. table /// \brief Frame flags: 0 = no trans(opaque), 1-15 = transl. table
#define FF_TRANSMASK 0xf0000 #define FF_TRANSMASK 0xf0000
/// \brief shift for FF_TRANSMASK /// \brief shift for FF_TRANSMASK
@ -60,6 +58,20 @@
#define FF_TRANS80 (tr_trans80<<FF_TRANSSHIFT) #define FF_TRANS80 (tr_trans80<<FF_TRANSSHIFT)
#define FF_TRANS90 (tr_trans90<<FF_TRANSSHIFT) #define FF_TRANS90 (tr_trans90<<FF_TRANSSHIFT)
/// \brief Frame flags: frame always appears full bright
#define FF_FULLBRIGHT 0x00100000
/// \brief Frame flags: Flip sprite vertically (relative to what it should be for its gravity)
#define FF_VERTICALFLIP 0x00200000
/// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION)
#define FF_PAPERSPRITE 0x00400000
/// \brief Frame flags - Animate: Simple stateless animation
#define FF_ANIMATE 0x01000000
/// \brief Frame flags - Animate: Start at a random place in the animation (mutually exclusive with below)
#define FF_RANDOMANIM 0x02000000
/// \brief Frame flags - Animate: Sync animation to global timer (mutually exclusive with above)
#define FF_GLOBALANIM 0x04000000
/** \brief translucency tables /** \brief translucency tables
\todo add another asm routine which use the fg and bg indexes in the \todo add another asm routine which use the fg and bg indexes in the

View file

@ -625,7 +625,7 @@ static void P_DeNightserizePlayer(player_t *player)
if (!(mo2->type == MT_NIGHTSDRONE)) if (!(mo2->type == MT_NIGHTSDRONE))
continue; continue;
if (mo2->flags & MF_AMBUSH) if (mo2->flags2 & MF2_AMBUSH)
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL); P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
break; break;
@ -5051,7 +5051,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
boolean transfer1last = false; boolean transfer1last = false;
boolean transfer2last = false; boolean transfer2last = false;
vertex_t vertices[4]; vertex_t vertices[4];
fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags & MF_AMBUSH ? -1 : 1); fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags2 & MF2_AMBUSH ? -1 : 1);
// Find next waypoint // Find next waypoint
for (th = thinkercap.next; th != &thinkercap; th = th->next) for (th = thinkercap.next; th != &thinkercap; th = th->next)
@ -5728,7 +5728,7 @@ static void P_NiGHTSMovement(player_t *player)
// The 'ambush' flag says you should rotate // The 'ambush' flag says you should rotate
// the other way around the axis. // the other way around the axis.
if (player->mo->target->flags & MF_AMBUSH) if (player->mo->target->flags2 & MF2_AMBUSH)
backwardaxis = true; backwardaxis = true;
player->angle_pos = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y); player->angle_pos = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y);
@ -8141,7 +8141,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
} }
else if (player->mo->target) else if (player->mo->target)
{ {
if (player->mo->target->flags & MF_AMBUSH) if (player->mo->target->flags2 & MF2_AMBUSH)
angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y); angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y);
else else
angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->target->x, player->mo->target->y); angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->target->x, player->mo->target->y);

View file

@ -709,6 +709,7 @@ void R_DrawPlanes(void)
if (dc_yl <= dc_yh) if (dc_yl <= dc_yh)
{ {
angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT));
dc_x = x; dc_x = x;
dc_source = dc_source =
R_GetColumn(texturetranslation[skytexture], R_GetColumn(texturetranslation[skytexture],

View file

@ -728,6 +728,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// Render FOF sides kinda like normal sides, with the frac and step and everything // Render FOF sides kinda like normal sides, with the frac and step and everything
// NOTE: INT64 instead of fixed_t because overflow concerns // NOTE: INT64 instead of fixed_t because overflow concerns
INT64 top_frac, top_step, bottom_frac, bottom_step; INT64 top_frac, top_step, bottom_frac, bottom_step;
// skew FOF walls with slopes?
boolean slopeskew = false;
fixed_t ffloortextureslide = 0;
INT32 oldx = -1;
fixed_t left_top, left_bottom; // needed here for slope skewing
pslope_t *skewslope = NULL;
#endif #endif
void (*colfunc_2s) (column_t *); void (*colfunc_2s) (column_t *);
@ -951,21 +957,71 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
mceilingclip = ds->sprtopclip; mceilingclip = ds->sprtopclip;
dc_texheight = textureheight[texnum]>>FRACBITS; dc_texheight = textureheight[texnum]>>FRACBITS;
#ifdef ESLOPE
// calculate both left ends
if (*pfloor->t_slope)
left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
else
left_top = *pfloor->topheight - viewz;
if (*pfloor->b_slope)
left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
else
left_bottom = *pfloor->bottomheight - viewz;
skewslope = *pfloor->t_slope; // skew using top slope by default
if (newline)
{
if (newline->flags & ML_DONTPEGTOP)
slopeskew = true;
}
else if (pfloor->master->flags & ML_DONTPEGTOP)
slopeskew = true;
if (slopeskew)
dc_texturemid = left_top;
else
#endif
dc_texturemid = *pfloor->topheight - viewz; dc_texturemid = *pfloor->topheight - viewz;
if (newline) if (newline)
{ {
offsetvalue = sides[newline->sidenum[0]].rowoffset; offsetvalue = sides[newline->sidenum[0]].rowoffset;
if (newline->flags & ML_DONTPEGBOTTOM) if (newline->flags & ML_DONTPEGBOTTOM)
{
#ifdef ESLOPE
skewslope = *pfloor->b_slope; // skew using bottom slope
if (slopeskew)
dc_texturemid = left_bottom;
else
#endif
offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; offsetvalue -= *pfloor->topheight - *pfloor->bottomheight;
}
} }
else else
{ {
offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset;
if (curline->linedef->flags & ML_DONTPEGBOTTOM) if (curline->linedef->flags & ML_DONTPEGBOTTOM)
{
#ifdef ESLOPE
skewslope = *pfloor->b_slope; // skew using bottom slope
if (slopeskew)
dc_texturemid = left_bottom;
else
#endif
offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; offsetvalue -= *pfloor->topheight - *pfloor->bottomheight;
}
} }
#ifdef ESLOPE
if (slopeskew)
{
angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
if (skewslope)
ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT));
}
#endif
dc_texturemid += offsetvalue; dc_texturemid += offsetvalue;
//faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
@ -981,23 +1037,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
#ifdef ESLOPE #ifdef ESLOPE
// Set heights according to plane, or slope, whichever // Set heights according to plane, or slope, whichever
{ {
fixed_t left_top, right_top, left_bottom, right_bottom; fixed_t right_top, right_bottom;
// calculate right ends now
if (*pfloor->t_slope) if (*pfloor->t_slope)
{
left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz;
}
else else
left_top = right_top = *pfloor->topheight - viewz; right_top = *pfloor->topheight - viewz;
if (*pfloor->b_slope) if (*pfloor->b_slope)
{
left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz;
}
else else
left_bottom = right_bottom = *pfloor->bottomheight - viewz; right_bottom = *pfloor->bottomheight - viewz;
// using INT64 to avoid 32bit overflow // using INT64 to avoid 32bit overflow
top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS);
@ -1021,6 +1072,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{ {
if (maskedtexturecol[dc_x] != INT16_MAX) if (maskedtexturecol[dc_x] != INT16_MAX)
{ {
#ifdef ESLOPE
if (ffloortextureslide) { // skew FOF walls
if (oldx != -1)
dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])<<FRACBITS);
oldx = dc_x;
}
#endif
// SoM: New code does not rely on R_DrawColumnShadowed_8 which // SoM: New code does not rely on R_DrawColumnShadowed_8 which
// will (hopefully) put less strain on the stack. // will (hopefully) put less strain on the stack.
if (dc_numlights) if (dc_numlights)
@ -2622,22 +2680,27 @@ void R_StoreWallRange(INT32 start, INT32 stop)
worldbottomslope >>= 4; worldbottomslope >>= 4;
#endif #endif
topstep = -FixedMul (rw_scalestep, worldtop); if (linedef->special == 41) { // HORIZON LINES
topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); topstep = bottomstep = 0;
topfrac = bottomfrac = (centeryfrac>>4);
} else {
topstep = -FixedMul (rw_scalestep, worldtop);
topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
bottomstep = -FixedMul (rw_scalestep,worldbottom); bottomstep = -FixedMul (rw_scalestep,worldbottom);
bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
#ifdef ESLOPE #ifdef ESLOPE
if (frontsector->c_slope) { if (frontsector->c_slope) {
fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2);
topstep = (topfracend-topfrac)/(range); topstep = (topfracend-topfrac)/(range);
} }
if (frontsector->f_slope) { if (frontsector->f_slope) {
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2);
bottomstep = (bottomfracend-bottomfrac)/(range); bottomstep = (bottomfracend-bottomfrac)/(range);
} }
#endif #endif
}
dc_numlights = 0; dc_numlights = 0;

View file

@ -808,11 +808,18 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (overflow_test < 0) overflow_test = -overflow_test; if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // fixed point mult would overflow if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // fixed point mult would overflow
if (vis->scalestep) // handles right edge too
{
overflow_test = (INT64)centeryfrac - (((INT64)vis->texturemid*(vis->scale + (vis->scalestep*(vis->x2 - vis->x1))))>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto
}
colfunc = basecolfunc; // hack: this isn't resetting properly somewhere. colfunc = basecolfunc; // hack: this isn't resetting properly somewhere.
dc_colormap = vis->colormap; dc_colormap = vis->colormap;
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
{ {
// translate green skin to another color // translate certain pixels to white
colfunc = transcolfunc; colfunc = transcolfunc;
if (vis->mobj->type == MT_CYBRAKDEMON) if (vis->mobj->type == MT_CYBRAKDEMON)
dc_translation = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE); dc_translation = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
@ -868,13 +875,10 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (!dc_colormap) if (!dc_colormap)
dc_colormap = colormaps; dc_colormap = colormaps;
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
dc_texturemid = vis->texturemid; dc_texturemid = vis->texturemid;
dc_texheight = 0; dc_texheight = 0;
frac = vis->startfrac; frac = vis->startfrac;
spryscale = vis->scale;
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
windowtop = windowbottom = sprbotscreen = INT32_MAX; windowtop = windowbottom = sprbotscreen = INT32_MAX;
if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES)
@ -886,28 +890,29 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (!vis->isScaled) if (!vis->isScaled)
{ {
vis->scale = FixedMul(vis->scale, this_scale); vis->scale = FixedMul(vis->scale, this_scale);
spryscale = vis->scale; vis->scalestep = FixedMul(vis->scalestep, this_scale);
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
vis->xiscale = FixedDiv(vis->xiscale,this_scale); vis->xiscale = FixedDiv(vis->xiscale,this_scale);
vis->isScaled = true; vis->isScaled = true;
} }
dc_texturemid = FixedDiv(dc_texturemid,this_scale); dc_texturemid = FixedDiv(dc_texturemid,this_scale);
}
//Oh lordy, mercy me. Don't freak out if sprites go offscreen! spryscale = vis->scale;
/*if (vis->xiscale > 0)
frac = FixedDiv(frac, this_scale);
else if (vis->x1 <= 0)
frac = (vis->x1 - vis->x2) * vis->xiscale;*/
if (!(vis->scalestep))
{
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
//dc_hires = 1; dc_iscale = FixedDiv(FRACUNIT, vis->scale);
} }
x1 = vis->x1; x1 = vis->x1;
x2 = vis->x2; x2 = vis->x2;
if (vis->x1 < 0) if (vis->x1 < 0)
{
spryscale += vis->scalestep*(-vis->x1);
vis->x1 = 0; vis->x1 = 0;
}
if (vis->x2 >= vid.width) if (vis->x2 >= vid.width)
vis->x2 = vid.width-1; vis->x2 = vid.width-1;
@ -915,6 +920,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
{ {
#ifdef RANGECHECK #ifdef RANGECHECK
texturecolumn = frac>>FRACBITS; texturecolumn = frac>>FRACBITS;
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
@ -923,10 +929,16 @@ static void R_DrawVisSprite(vissprite_t *vis)
#else #else
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
#endif #endif
if (vis->scalestep)
{
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
dc_iscale = (0xffffffffu / (unsigned)spryscale);
}
if (vis->vflip) if (vis->vflip)
R_DrawFlippedMaskedColumn(column, patch->height); R_DrawFlippedMaskedColumn(column, patch->height);
else else
R_DrawMaskedColumn(column); R_DrawMaskedColumn(column);
spryscale += vis->scalestep;
} }
colfunc = basecolfunc; colfunc = basecolfunc;
@ -1021,7 +1033,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
if (testheight <= sprite->gz) if (testheight <= sprite->gz)
return; return;
cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS); cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->sortscale))>>FRACBITS);
if (cutfrac < 0) if (cutfrac < 0)
continue; continue;
if (cutfrac > viewheight) if (cutfrac > viewheight)
@ -1094,7 +1106,7 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t tr_x, tr_y; fixed_t tr_x, tr_y;
fixed_t gxt, gyt; fixed_t gxt, gyt;
fixed_t tx, tz; fixed_t tx, tz;
fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
INT32 x1, x2; INT32 x1, x2;
@ -1104,13 +1116,19 @@ static void R_ProjectSprite(mobj_t *thing)
size_t rot; size_t rot;
UINT8 flip; UINT8 flip;
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
INT32 lindex; INT32 lindex;
vissprite_t *vis; vissprite_t *vis;
angle_t ang; angle_t ang = 0; // compiler complaints
fixed_t iscale; fixed_t iscale;
fixed_t scalestep;
fixed_t offset, offset2;
boolean papersprite = !!(thing->frame & FF_PAPERSPRITE);
INT32 dispoffset = thing->info->dispoffset;
//SoM: 3/17/2000 //SoM: 3/17/2000
fixed_t gz, gzt; fixed_t gz, gzt;
@ -1118,6 +1136,8 @@ static void R_ProjectSprite(mobj_t *thing)
INT32 light = 0; INT32 light = 0;
fixed_t this_scale = thing->scale; fixed_t this_scale = thing->scale;
fixed_t ang_scale = FRACUNIT;
// transform the origin point // transform the origin point
tr_x = thing->x - viewx; tr_x = thing->x - viewx;
tr_y = thing->y - viewy; tr_y = thing->y - viewy;
@ -1128,7 +1148,7 @@ static void R_ProjectSprite(mobj_t *thing)
tz = gxt-gyt; tz = gxt-gyt;
// thing is behind view plane? // thing is behind view plane?
if (tz < FixedMul(MINZ, this_scale)) if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
return; return;
gxt = -FixedMul(tr_x, viewsin); gxt = -FixedMul(tr_x, viewsin);
@ -1141,7 +1161,7 @@ static void R_ProjectSprite(mobj_t *thing)
// aspect ratio stuff // aspect ratio stuff
xscale = FixedDiv(projection, tz); xscale = FixedDiv(projection, tz);
yscale = FixedDiv(projectiony, tz); sortscale = FixedDiv(projectiony, tz);
// decide which patch to use for sprite relative to player // decide which patch to use for sprite relative to player
#ifdef RANGECHECK #ifdef RANGECHECK
@ -1188,6 +1208,13 @@ static void R_ProjectSprite(mobj_t *thing)
I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite);
#endif #endif
if (sprframe->rotate != SRF_SINGLE || papersprite)
{
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
if (papersprite)
ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT));
}
if (sprframe->rotate == SRF_SINGLE) if (sprframe->rotate == SRF_SINGLE)
{ {
// use single rotation for all views // use single rotation for all views
@ -1198,7 +1225,7 @@ static void R_ProjectSprite(mobj_t *thing)
else else
{ {
// choose a different rotation based on player view // choose a different rotation based on player view
ang = R_PointToAngle (thing->x, thing->y) - thing->angle; //ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
rot = 6; // F7 slot rot = 6; // F7 slot
@ -1219,22 +1246,112 @@ static void R_ProjectSprite(mobj_t *thing)
// calculate edges of the shape // calculate edges of the shape
if (flip) if (flip)
tx -= FixedMul(spritecachedinfo[lump].width-spritecachedinfo[lump].offset, this_scale); offset = spritecachedinfo[lump].offset - spritecachedinfo[lump].width;
else else
tx -= FixedMul(spritecachedinfo[lump].offset, this_scale); offset = -spritecachedinfo[lump].offset;
offset = FixedMul(offset, this_scale);
tx += FixedMul(offset, ang_scale);
x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS;
// off the right side? // off the right side?
if (x1 > viewwidth) if (x1 > viewwidth)
return; return;
tx += FixedMul(spritecachedinfo[lump].width, this_scale); offset2 = FixedMul(spritecachedinfo[lump].width, this_scale);
tx += FixedMul(offset2, ang_scale);
x2 = ((centerxfrac + FixedMul (tx,xscale)) >>FRACBITS) - 1; x2 = ((centerxfrac + FixedMul (tx,xscale)) >>FRACBITS) - 1;
// off the left side // off the left side
if (x2 < 0) if (x2 < 0)
return; return;
if (papersprite)
{
fixed_t yscale2, cosmul, sinmul, tz2;
INT32 range;
if (ang >= ANGLE_180)
{
offset *= -1;
offset2 *= -1;
}
cosmul = FINECOSINE(thing->angle>>ANGLETOFINESHIFT);
sinmul = FINESINE(thing->angle>>ANGLETOFINESHIFT);
tr_x += FixedMul(offset, cosmul);
tr_y += FixedMul(offset, sinmul);
gxt = FixedMul(tr_x, viewcos);
gyt = -FixedMul(tr_y, viewsin);
tz = gxt-gyt;
yscale = FixedDiv(projectiony, tz);
if (yscale < 64) return; // Fix some funky visuals
tr_x += FixedMul(offset2, cosmul);
tr_y += FixedMul(offset2, sinmul);
gxt = FixedMul(tr_x, viewcos);
gyt = -FixedMul(tr_y, viewsin);
tz2 = gxt-gyt;
yscale2 = FixedDiv(projectiony, tz2);
if (yscale2 < 64) return; // ditto
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
return;
if (x2 > x1)
range = (x2 - x1);
else
range = 1;
scalestep = (yscale2 - yscale)/range;
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
// sortscale = max(yscale, yscale2);
// sortscale = min(yscale, yscale2);
}
else
{
scalestep = 0;
yscale = sortscale;
}
xscale = FixedMul(xscale, ang_scale);
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
{
fixed_t linkscale;
#if 0 // support for chains of linkdraw - probably not network safe to modify mobjs during rendering
mobj_t *link, *link2;
for (link = thing->tracer; (link->tracer && (link->flags2 & MF2_LINKDRAW)); link = link->tracer)
link->flags2 &= ~MF2_LINKDRAW; // to prevent infinite loops, otherwise would just be a ;
for (link2 = thing->tracer; (link2->tracer && (link2 != link)); link2 = link2->tracer)
link->flags2 |= MF2_LINKDRAW; // only needed for correction of the above
if (link->flags2 & MF2_LINKDRAW)
link->flags2 &= ~MF2_LINKDRAW; // let's try and make sure this doesn't happen again...
tr_x = link->x - viewx;
tr_y = link->y - viewy;
#else
tr_x = thing->tracer->x - viewx;
tr_y = thing->tracer->y - viewy;
#endif
gxt = FixedMul(tr_x, viewcos);
gyt = -FixedMul(tr_y, viewsin);
tz = gxt-gyt;
linkscale = FixedDiv(projectiony, tz);
if (tz < FixedMul(MINZ, this_scale))
return;
if (sortscale < linkscale)
dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0)
sortscale = linkscale; // now make sure it's linked
}
// PORTAL SPRITE CLIPPING // PORTAL SPRITE CLIPPING
if (portalrender) if (portalrender)
{ {
@ -1246,7 +1363,7 @@ static void R_ProjectSprite(mobj_t *thing)
} }
//SoM: 3/17/2000: Disregard sprites that are out of view.. //SoM: 3/17/2000: Disregard sprites that are out of view..
if (thing->eflags & MFE_VERTICALFLIP) if (vflip)
{ {
// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned. // When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course. // sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
@ -1316,7 +1433,8 @@ static void R_ProjectSprite(mobj_t *thing)
vis->heightsec = heightsec; //SoM: 3/17/2000 vis->heightsec = heightsec; //SoM: 3/17/2000
vis->mobjflags = thing->flags; vis->mobjflags = thing->flags;
vis->scale = yscale; //<<detailshift; vis->scale = yscale; //<<detailshift;
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15 vis->sortscale = sortscale;
vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15
vis->gx = thing->x; vis->gx = thing->x;
vis->gy = thing->y; vis->gy = thing->y;
vis->gz = gz; vis->gz = gz;
@ -1325,6 +1443,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->pz = thing->z; vis->pz = thing->z;
vis->pzt = vis->pz + vis->thingheight; vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = vis->gzt - viewz; vis->texturemid = vis->gzt - viewz;
vis->scalestep = scalestep;
vis->mobj = thing; // Easy access! Tails 06-07-2002 vis->mobj = thing; // Easy access! Tails 06-07-2002
@ -1342,8 +1461,8 @@ static void R_ProjectSprite(mobj_t *thing)
vis->xscale = xscale; //SoM: 4/17/2000 vis->xscale = xscale; //SoM: 4/17/2000
vis->sector = thing->subsector->sector; vis->sector = thing->subsector->sector;
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, yscale))>>FRACBITS); vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS);
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, yscale))>>FRACBITS); vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS);
vis->cut = SC_NONE; vis->cut = SC_NONE;
if (thing->subsector->sector->numlights) if (thing->subsector->sector->numlights)
vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap; vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap;
@ -1364,7 +1483,10 @@ static void R_ProjectSprite(mobj_t *thing)
} }
if (vis->x1 > x1) if (vis->x1 > x1)
{
vis->startfrac += FixedDiv(vis->xiscale, this_scale)*(vis->x1-x1); vis->startfrac += FixedDiv(vis->xiscale, this_scale)*(vis->x1-x1);
vis->scale += scalestep*(vis->x1 - x1);
}
//Fab: lumppat is the lump number of the patch to use, this is different //Fab: lumppat is the lump number of the patch to use, this is different
// than lumpid for sprites-in-pwad : the graphics are patched // than lumpid for sprites-in-pwad : the graphics are patched
@ -1402,10 +1524,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->precip = false; vis->precip = false;
if (thing->eflags & MFE_VERTICALFLIP) vis->vflip = vflip;
vis->vflip = true;
else
vis->vflip = false;
vis->isScaled = false; vis->isScaled = false;
@ -1523,7 +1642,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
// store information in a vissprite // store information in a vissprite
vis = R_NewVisSprite(); vis = R_NewVisSprite();
vis->scale = yscale; //<<detailshift; vis->scale = vis->sortscale = yscale; //<<detailshift;
vis->dispoffset = 0; // Monster Iestyn: 23/11/15 vis->dispoffset = 0; // Monster Iestyn: 23/11/15
vis->gx = thing->x; vis->gx = thing->x;
vis->gy = thing->y; vis->gy = thing->y;
@ -1533,6 +1652,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->pz = thing->z; vis->pz = thing->z;
vis->pzt = vis->pz + vis->thingheight; vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = vis->gzt - viewz; vis->texturemid = vis->gzt - viewz;
vis->scalestep = 0;
vis->x1 = x1 < 0 ? 0 : x1; vis->x1 = x1 < 0 ? 0 : x1;
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
@ -1711,14 +1831,14 @@ void R_SortVisSprites(void)
bestscale = bestdispoffset = INT32_MAX; bestscale = bestdispoffset = INT32_MAX;
for (ds = unsorted.next; ds != &unsorted; ds = ds->next) for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
{ {
if (ds->scale < bestscale) if (ds->sortscale < bestscale)
{ {
bestscale = ds->scale; bestscale = ds->sortscale;
bestdispoffset = ds->dispoffset; bestdispoffset = ds->dispoffset;
best = ds; best = ds;
} }
// order visprites of same scale by dispoffset, smallest first // order visprites of same scale by dispoffset, smallest first
else if (ds->scale == bestscale && ds->dispoffset < bestdispoffset) else if (ds->sortscale == bestscale && ds->dispoffset < bestdispoffset)
{ {
bestdispoffset = ds->dispoffset; bestdispoffset = ds->dispoffset;
best = ds; best = ds;
@ -1880,7 +2000,7 @@ static void R_CreateDrawNodes(void)
for (i = x1; i <= x2; i++) for (i = x1; i <= x2; i++)
{ {
if (r2->seg->frontscale[i] > rover->scale) if (r2->seg->frontscale[i] > rover->sortscale)
break; break;
} }
if (i > x2) if (i > x2)
@ -1899,10 +2019,10 @@ static void R_CreateDrawNodes(void)
continue; continue;
scale = r2->thickseg->scale1 > r2->thickseg->scale2 ? r2->thickseg->scale1 : r2->thickseg->scale2; scale = r2->thickseg->scale1 > r2->thickseg->scale2 ? r2->thickseg->scale1 : r2->thickseg->scale2;
if (scale <= rover->scale) if (scale <= rover->sortscale)
continue; continue;
scale = r2->thickseg->scale1 + (r2->thickseg->scalestep * (sintersect - r2->thickseg->x1)); scale = r2->thickseg->scale1 + (r2->thickseg->scalestep * (sintersect - r2->thickseg->x1));
if (scale <= rover->scale) if (scale <= rover->sortscale)
continue; continue;
#ifdef ESLOPE #ifdef ESLOPE
@ -1952,11 +2072,11 @@ static void R_CreateDrawNodes(void)
continue; continue;
scale = r2->seg->scale1 > r2->seg->scale2 ? r2->seg->scale1 : r2->seg->scale2; scale = r2->seg->scale1 > r2->seg->scale2 ? r2->seg->scale1 : r2->seg->scale2;
if (scale <= rover->scale) if (scale <= rover->sortscale)
continue; continue;
scale = r2->seg->scale1 + (r2->seg->scalestep * (sintersect - r2->seg->x1)); scale = r2->seg->scale1 + (r2->seg->scalestep * (sintersect - r2->seg->x1));
if (rover->scale < scale) if (rover->sortscale < scale)
{ {
entry = R_CreateDrawNode(NULL); entry = R_CreateDrawNode(NULL);
(entry->prev = r2->prev)->next = entry; (entry->prev = r2->prev)->next = entry;
@ -1972,8 +2092,8 @@ static void R_CreateDrawNodes(void)
if (r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt) if (r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt)
continue; continue;
if (r2->sprite->scale > rover->scale if (r2->sprite->sortscale > rover->sortscale
|| (r2->sprite->scale == rover->scale && r2->sprite->dispoffset > rover->dispoffset)) || (r2->sprite->sortscale == rover->sortscale && r2->sprite->dispoffset > rover->dispoffset))
{ {
entry = R_CreateDrawNode(NULL); entry = R_CreateDrawNode(NULL);
(entry->prev = r2->prev)->next = entry; (entry->prev = r2->prev)->next = entry;
@ -2126,8 +2246,8 @@ void R_ClipSprites(void)
scale = ds->scale2; scale = ds->scale2;
} }
if (scale < spr->scale || if (scale < spr->sortscale ||
(lowscale < spr->scale && (lowscale < spr->sortscale &&
!R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) !R_PointOnSegSide (spr->gx, spr->gy, ds->curline)))
{ {
// masked mid texture? // masked mid texture?
@ -2178,7 +2298,7 @@ void R_ClipSprites(void)
fixed_t mh, h; fixed_t mh, h;
INT32 phs = viewplayer->mo->subsector->sector->heightsec; INT32 phs = viewplayer->mo->subsector->sector->heightsec;
if ((mh = sectors[spr->heightsec].floorheight) > spr->gz && if ((mh = sectors[spr->heightsec].floorheight) > spr->gz &&
(h = centeryfrac - FixedMul(mh -= viewz, spr->scale)) >= 0 && (h = centeryfrac - FixedMul(mh -= viewz, spr->sortscale)) >= 0 &&
(h >>= FRACBITS) < viewheight) (h >>= FRACBITS) < viewheight)
{ {
if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight)) if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight))
@ -2196,7 +2316,7 @@ void R_ClipSprites(void)
} }
if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt && if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt &&
(h = centeryfrac - FixedMul(mh-viewz, spr->scale)) >= 0 && (h = centeryfrac - FixedMul(mh-viewz, spr->sortscale)) >= 0 &&
(h >>= FRACBITS) < viewheight) (h >>= FRACBITS) < viewheight)
{ {
if (phs != -1 && viewz >= sectors[phs].ceilingheight) if (phs != -1 && viewz >= sectors[phs].ceilingheight)

View file

@ -149,7 +149,8 @@ typedef struct vissprite_s
fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors
fixed_t startfrac; // horizontal position of x1 fixed_t startfrac; // horizontal position of x1
fixed_t scale; fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW
fixed_t scalestep; // only for paper sprites, 0 otherwise
fixed_t xiscale; // negative if flipped fixed_t xiscale; // negative if flipped
fixed_t texturemid; fixed_t texturemid;