Merge branch 'musicplus-core' into musicplus-feature-postboss

This commit is contained in:
mazmazz 2018-09-19 18:53:46 -04:00
commit 1c314833db
11 changed files with 826 additions and 18 deletions

View file

@ -1207,8 +1207,10 @@ static void readlevelheader(MYFILE *f, INT32 num)
else if (fastcmp(word2, "NORMAL")) i = 0;
else if (fastcmp(word2, "BOSS")) i = 1;
else if (fastcmp(word2, "ERZ3")) i = 2;
else if (fastcmp(word2, "NIGHTS")) i = 3;
else if (fastcmp(word2, "NIGHTSLINK")) i = 4;
if (i >= -1 && i <= 2) // -1 for no bonus. Max is 2.
if (i >= -1 && i <= 4) // -1 for no bonus. Max is 4.
mapheaderinfo[num-1]->bonustype = (SINT8)i;
else
deh_warning("Level header %d: invalid bonus type number %d", num, i);

View file

@ -3313,12 +3313,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
}
else if (player->powers[pw_carry] == CR_NIGHTSFALL)
{
if (player->spheres > 0)
{
damage = player->spheres;
P_RingDamage(player, inflictor, source, damage, damagetype, true);
damage = 0;
}
// always damage so we can recoil upon losing points
damage = player->spheres;
P_RingDamage(player, inflictor, source, damage, damagetype, true);
damage = 0;
}
else if (player->rings > 0) // No shield but have rings.
{

View file

@ -23,7 +23,7 @@
*
* \param sector The sector to remove effects from.
*/
static void P_RemoveLighting(sector_t *sector)
void P_RemoveLighting(sector_t *sector)
{
if (sector->lightingdata)
{

View file

@ -1291,6 +1291,7 @@ typedef enum
tc_noenemies,
tc_eachtime,
tc_disappear,
tc_fade,
tc_fadecolormap,
tc_planedisplace,
#ifdef POLYOBJECTS
@ -1907,6 +1908,34 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type)
WRITEINT32(save_p, ht->exists);
}
//
// SaveFadeThinker
//
// Saves a fade_t thinker
//
static void SaveFadeThinker(const thinker_t *th, const UINT8 type)
{
const fade_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, CheckAddNetColormapToList(ht->dest_exc));
WRITEUINT32(save_p, ht->sectornum);
WRITEUINT32(save_p, ht->ffloornum);
WRITEINT32(save_p, ht->alpha);
WRITEINT16(save_p, ht->sourcevalue);
WRITEINT16(save_p, ht->destvalue);
WRITEINT16(save_p, ht->destlightlevel);
WRITEINT16(save_p, ht->speed);
WRITEUINT8(save_p, (UINT8)ht->ticbased);
WRITEINT32(save_p, ht->timer);
WRITEUINT8(save_p, ht->doexists);
WRITEUINT8(save_p, ht->dotranslucent);
WRITEUINT8(save_p, ht->dolighting);
WRITEUINT8(save_p, ht->docolormap);
WRITEUINT8(save_p, ht->docollision);
WRITEUINT8(save_p, ht->doghostfade);
WRITEUINT8(save_p, ht->exactalpha);
}
//
// SaveFadeColormapThinker
//
@ -2245,12 +2274,16 @@ static void P_NetArchiveThinkers(void)
SaveDisappearThinker(th, tc_disappear);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_Fade)
{
SaveFadeThinker(th, tc_fade);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_FadeColormap)
{
SaveFadeColormapThinker(th, tc_fadecolormap);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace)
{
SavePlaneDisplaceThinker(th, tc_planedisplace);
@ -2973,6 +3006,52 @@ static inline void LoadDisappearThinker(actionf_p1 thinker)
}
//
// LoadFadeThinker
//
// Loads a fade_t thinker
//
static inline void LoadFadeThinker(actionf_p1 thinker)
{
sector_t *ss;
fade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->dest_exc = GetNetColormapFromList(READUINT32(save_p));
ht->sectornum = READUINT32(save_p);
ht->ffloornum = READUINT32(save_p);
ht->alpha = READINT32(save_p);
ht->sourcevalue = READINT16(save_p);
ht->destvalue = READINT16(save_p);
ht->destlightlevel = READINT16(save_p);
ht->speed = READINT16(save_p);
ht->ticbased = (boolean)READUINT8(save_p);
ht->timer = READINT32(save_p);
ht->doexists = READUINT8(save_p);
ht->dotranslucent = READUINT8(save_p);
ht->dolighting = READUINT8(save_p);
ht->docolormap = READUINT8(save_p);
ht->docollision = READUINT8(save_p);
ht->doghostfade = READUINT8(save_p);
ht->exactalpha = READUINT8(save_p);
ss = LoadSector(ht->sectornum);
if (ss)
{
size_t j = 0; // ss->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc
ffloor_t *rover;
for (rover = ss->ffloors; rover; rover = rover->next)
{
if (j == ht->ffloornum)
{
ht->rover = rover;
rover->fadingdata = ht;
break;
}
j++;
}
}
P_AddThinker(&ht->thinker);
}
// LoadFadeColormapThinker
//
// Loads a fadecolormap_t from a save game
@ -3319,6 +3398,10 @@ static void P_NetUnArchiveThinkers(void)
LoadDisappearThinker((actionf_p1)T_Disappear);
break;
case tc_fade:
LoadFadeThinker((actionf_p1)T_Fade);
break;
case tc_fadecolormap:
LoadFadeColormapThinker((actionf_p1)T_FadeColormap);
break;

View file

@ -683,6 +683,7 @@ static void P_LoadRawSectors(UINT8 *data, size_t i)
ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats);
ss->lightlevel = SHORT(ms->lightlevel);
ss->spawn_lightlevel = SHORT(ms->lightlevel);
ss->special = SHORT(ms->special);
ss->tag = SHORT(ms->tag);
ss->nexttag = ss->firsttag = -1;

View file

@ -103,6 +103,15 @@ static void P_SpawnFriction(void);
static void P_SpawnPushers(void);
static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t *source, INT32 affectee, INT32 referrer, INT32 exclusive, INT32 slider); //SoM: 3/9/2000
static void Add_MasterDisappearer(tic_t appeartime, tic_t disappeartime, tic_t offset, INT32 line, INT32 sourceline);
static void P_ResetFakeFloorFader(ffloor_t *rover, fade_t *data, boolean finalize);
#define P_RemoveFakeFloorFader(l) P_ResetFakeFloorFader(l, NULL, false);
static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destvalue, INT16 speed, boolean ticbased, INT32 *timer,
boolean doexists, boolean dotranslucent, boolean dolighting, boolean docolormap,
boolean docollision, boolean doghostfade, boolean exactalpha);
static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloornum,
INT16 destvalue, INT16 speed, boolean ticbased, boolean relative,
boolean doexists, boolean dotranslucent, boolean dolighting, boolean docolormap,
boolean docollision, boolean doghostfade, boolean exactalpha);
static void P_ResetColormapFader(sector_t *sector);
static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc,
boolean ticbased, INT32 duration);
@ -3472,6 +3481,186 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
break;
}
case 452: // Set FOF alpha
{
INT16 destvalue = line->sidenum[1] != 0xffff ?
(INT16)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : (INT16)(P_AproxDistance(line->dx, line->dy)>>FRACBITS);
INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS);
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
sector_t *sec; // Sector that the FOF is visible in
ffloor_t *rover; // FOF that we are going to operate
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
{
sec = sectors + secnum;
if (!sec->ffloors)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 452 Executor: Target sector #%d has no FOFs.\n", secnum);
return;
}
for (rover = sec->ffloors; rover; rover = rover->next)
{
if (rover->master->frontsector->tag == foftag)
break;
}
if (!rover)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 452 Executor: Can't find a FOF control sector with tag %d\n", foftag);
return;
}
// If fading an invisible FOF whose render flags we did not yet set,
// initialize its alpha to 1
// for relative alpha calc
if (!(line->flags & ML_NOCLIMB) && // do translucent
(rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE
!(rover->spawnflags & FF_RENDERSIDES) &&
!(rover->spawnflags & FF_RENDERPLANES) &&
!(rover->flags & FF_RENDERALL))
rover->alpha = 1;
P_RemoveFakeFloorFader(rover);
P_FadeFakeFloor(rover,
rover->alpha,
max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)),
0, // set alpha immediately
false, NULL, // tic-based logic
false, // do not handle FF_EXISTS
!(line->flags & ML_NOCLIMB), // handle FF_TRANSLUCENT
false, // do not handle lighting
false, // do not handle colormap
false, // do not handle collision
false, // do not do ghost fade (no collision during fade)
true); // use exact alpha values (for opengl)
}
break;
}
case 453: // Fade FOF
{
INT16 destvalue = line->sidenum[1] != 0xffff ?
(INT16)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : (INT16)(line->dx>>FRACBITS);
INT16 speed = line->sidenum[1] != 0xffff ?
(INT16)(abs(sides[line->sidenum[1]].rowoffset>>FRACBITS)) : (INT16)(abs(line->dy)>>FRACBITS);
INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS);
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
sector_t *sec; // Sector that the FOF is visible in
ffloor_t *rover; // FOF that we are going to operate
size_t j = 0; // sec->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
{
sec = sectors + secnum;
if (!sec->ffloors)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Target sector #%d has no FOFs.\n", secnum);
return;
}
for (rover = sec->ffloors; rover; rover = rover->next)
{
if (rover->master->frontsector->tag == foftag)
break;
j++;
}
if (!rover)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Can't find a FOF control sector with tag %d\n", foftag);
return;
}
// Prevent continuous execs from interfering on an existing fade
if (!(line->flags & ML_EFFECT5)
&& rover->fadingdata)
//&& ((fade_t*)rover->fadingdata)->timer > (ticbased ? 2 : speed*2))
{
CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Fade FOF thinker already exists, timer: %d\n", ((fade_t*)rover->fadingdata)->timer);
continue;
}
if (speed > 0)
P_AddFakeFloorFader(rover, secnum, j,
destvalue,
speed,
(line->flags & ML_EFFECT4), // tic-based logic
(line->flags & ML_EFFECT3), // Relative destvalue
!(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS
!(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT
!(line->flags & ML_EFFECT2), // do not handle lighting
!(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags)
!(line->flags & ML_BOUNCY), // do not handle collision
(line->flags & ML_EFFECT1), // do ghost fade (no collision during fade)
(line->flags & ML_TFERLINE)); // use exact alpha values (for opengl)
else
{
// If fading an invisible FOF whose render flags we did not yet set,
// initialize its alpha to 1
// for relative alpha calc
if (!(line->flags & ML_NOCLIMB) && // do translucent
(rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE
!(rover->spawnflags & FF_RENDERSIDES) &&
!(rover->spawnflags & FF_RENDERPLANES) &&
!(rover->flags & FF_RENDERALL))
rover->alpha = 1;
P_RemoveFakeFloorFader(rover);
P_FadeFakeFloor(rover,
rover->alpha,
max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)),
0, // set alpha immediately
false, NULL, // tic-based logic
!(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS
!(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT
!(line->flags & ML_EFFECT2), // do not handle lighting
!(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags)
!(line->flags & ML_BOUNCY), // do not handle collision
(line->flags & ML_EFFECT1), // do ghost fade (no collision during fade)
(line->flags & ML_TFERLINE)); // use exact alpha values (for opengl)
}
}
break;
}
case 454: // Stop fading FOF
{
INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS);
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
sector_t *sec; // Sector that the FOF is visible in
ffloor_t *rover; // FOF that we are going to operate
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
{
sec = sectors + secnum;
if (!sec->ffloors)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 454 Executor: Target sector #%d has no FOFs.\n", secnum);
return;
}
for (rover = sec->ffloors; rover; rover = rover->next)
{
if (rover->master->frontsector->tag == foftag)
break;
}
if (!rover)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 454 Executor: Can't find a FOF control sector with tag %d\n", foftag);
return;
}
P_ResetFakeFloorFader(rover, NULL,
!(line->flags & ML_BLOCKMONSTERS)); // do not finalize collision flags
}
break;
}
case 455: // Fade colormap
for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;)
{
@ -5414,7 +5603,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
ffloor->spawnflags = ffloor->flags = flags;
ffloor->master = master;
ffloor->norender = INFTICS;
ffloor->fadingdata = NULL;
// Scan the thinkers to check for special conditions applying to this FOF.
// If we have thinkers sorted by sector, just check the relevant ones;
@ -7581,6 +7770,458 @@ void T_Disappear(disappear_t *d)
}
}
/** Removes fadingdata from FOF control sector
*
* \param line line to search for target faders
* \param data pointer to set new fadingdata to. Can be NULL to erase.
*/
static void P_ResetFakeFloorFader(ffloor_t *rover, fade_t *data, boolean finalize)
{
fade_t *fadingdata = (fade_t *)rover->fadingdata;
// find any existing thinkers and remove them, then replace with new data
if (fadingdata != data)
{
if (fadingdata)
{
if (finalize)
P_FadeFakeFloor(rover,
fadingdata->sourcevalue,
fadingdata->alpha >= fadingdata->destvalue ?
fadingdata->alpha - 1 : // trigger fade-out finish
fadingdata->alpha + 1, // trigger fade-in finish
0,
fadingdata->ticbased,
&fadingdata->timer,
fadingdata->doexists,
fadingdata->dotranslucent,
fadingdata->dolighting,
fadingdata->docolormap,
fadingdata->docollision,
fadingdata->doghostfade,
fadingdata->exactalpha);
rover->alpha = fadingdata->alpha;
if (fadingdata->dolighting)
P_RemoveLighting(&sectors[rover->secnum]);
if (fadingdata->docolormap)
P_ResetColormapFader(&sectors[rover->secnum]);
P_RemoveThinker(&fadingdata->thinker);
}
rover->fadingdata = data;
}
}
static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destvalue, INT16 speed, boolean ticbased, INT32 *timer,
boolean doexists, boolean dotranslucent, boolean dolighting, boolean docolormap,
boolean docollision, boolean doghostfade, boolean exactalpha)
{
boolean stillfading = false;
INT32 alpha;
fade_t *fadingdata = (fade_t *)rover->fadingdata;
(void)docolormap; // *shrug* maybe we can use this in the future. For now, let's be consistent with our other function params
if (rover->master->special == 258) // Laser block
return false;
// If fading an invisible FOF whose render flags we did not yet set,
// initialize its alpha to 1
if (dotranslucent &&
(rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE
!(rover->flags & FF_FOG) && // do not include fog
!(rover->spawnflags & FF_RENDERSIDES) &&
!(rover->spawnflags & FF_RENDERPLANES) &&
!(rover->flags & FF_RENDERALL))
rover->alpha = 1;
if (fadingdata)
alpha = fadingdata->alpha;
else
alpha = rover->alpha;
// routines specific to fade in and fade out
if (!ticbased && alpha == destvalue)
return stillfading;
else if (alpha > destvalue) // fade out
{
// finish fading out
if (speed < 1 || (!ticbased && alpha - speed <= destvalue + speed) ||
(ticbased && (--(*timer) <= 0 || alpha <= destvalue)))
{
alpha = destvalue;
if (docollision)
{
if (rover->spawnflags & FF_SOLID)
rover->flags &= ~FF_SOLID;
if (rover->spawnflags & FF_SWIMMABLE)
rover->flags &= ~FF_SWIMMABLE;
if (rover->spawnflags & FF_QUICKSAND)
rover->flags &= ~FF_QUICKSAND;
if (rover->spawnflags & FF_BUSTUP)
rover->flags &= ~FF_BUSTUP;
if (rover->spawnflags & FF_MARIO)
rover->flags &= ~FF_MARIO;
}
}
else // continue fading out
{
if (!ticbased)
alpha -= speed;
else
{
INT16 delta = abs(destvalue - sourcevalue);
fixed_t factor = min(FixedDiv(speed - (*timer), speed), 1*FRACUNIT);
alpha = max(min(alpha, sourcevalue - (INT16)FixedMul(delta, factor)), destvalue);
}
stillfading = true;
}
}
else // fade in
{
// finish fading in
if (speed < 1 || (!ticbased && alpha + speed >= destvalue - speed) ||
(ticbased && (--(*timer) <= 0 || alpha >= destvalue)))
{
alpha = destvalue;
if (docollision)
{
if (rover->spawnflags & FF_SOLID)
rover->flags |= FF_SOLID;
if (rover->spawnflags & FF_SWIMMABLE)
rover->flags |= FF_SWIMMABLE;
if (rover->spawnflags & FF_QUICKSAND)
rover->flags |= FF_QUICKSAND;
if (rover->spawnflags & FF_BUSTUP)
rover->flags |= FF_BUSTUP;
if (rover->spawnflags & FF_MARIO)
rover->flags |= FF_MARIO;
}
}
else // continue fading in
{
if (!ticbased)
alpha += speed;
else
{
INT16 delta = abs(destvalue - sourcevalue);
fixed_t factor = min(FixedDiv(speed - (*timer), speed), 1*FRACUNIT);
alpha = min(max(alpha, sourcevalue + (INT16)FixedMul(delta, factor)), destvalue);
}
stillfading = true;
}
}
// routines common to both fade in and fade out
if (!stillfading)
{
if (doexists && !(rover->spawnflags & FF_BUSTUP))
{
if (alpha <= 1)
rover->flags &= ~FF_EXISTS;
else
rover->flags |= FF_EXISTS;
// Re-render lighting at end of fade
if (dolighting && !(rover->spawnflags & FF_NOSHADE) && !(rover->flags & FF_EXISTS))
rover->target->moved = true;
}
if (dotranslucent && !(rover->flags & FF_FOG))
{
if (alpha >= 256)
{
if (!(rover->flags & FF_CUTSOLIDS) &&
(rover->spawnflags & FF_CUTSOLIDS))
{
rover->flags |= FF_CUTSOLIDS;
rover->target->moved = true;
}
rover->flags &= ~FF_TRANSLUCENT;
}
else
{
rover->flags |= FF_TRANSLUCENT;
if ((rover->flags & FF_CUTSOLIDS) &&
(rover->spawnflags & FF_CUTSOLIDS))
{
rover->flags &= ~FF_CUTSOLIDS;
rover->target->moved = true;
}
}
if ((rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE
!(rover->spawnflags & FF_RENDERSIDES) &&
!(rover->spawnflags & FF_RENDERPLANES))
{
if (rover->alpha > 1)
rover->flags |= FF_RENDERALL;
else
rover->flags &= ~FF_RENDERALL;
}
}
}
else
{
if (doexists && !(rover->spawnflags & FF_BUSTUP))
{
// Re-render lighting if we haven't yet set FF_EXISTS (beginning of fade)
if (dolighting && !(rover->spawnflags & FF_NOSHADE) && !(rover->flags & FF_EXISTS))
rover->target->moved = true;
rover->flags |= FF_EXISTS;
}
if (dotranslucent && !(rover->flags & FF_FOG))
{
rover->flags |= FF_TRANSLUCENT;
if ((rover->flags & FF_CUTSOLIDS) &&
(rover->spawnflags & FF_CUTSOLIDS))
{
rover->flags &= ~FF_CUTSOLIDS;
rover->target->moved = true;
}
if ((rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE
!(rover->spawnflags & FF_RENDERSIDES) &&
!(rover->spawnflags & FF_RENDERPLANES))
rover->flags |= FF_RENDERALL;
}
if (docollision)
{
if (doghostfade) // remove collision flags during fade
{
if (rover->spawnflags & FF_SOLID)
rover->flags &= ~FF_SOLID;
if (rover->spawnflags & FF_SWIMMABLE)
rover->flags &= ~FF_SWIMMABLE;
if (rover->spawnflags & FF_QUICKSAND)
rover->flags &= ~FF_QUICKSAND;
if (rover->spawnflags & FF_BUSTUP)
rover->flags &= ~FF_BUSTUP;
if (rover->spawnflags & FF_MARIO)
rover->flags &= ~FF_MARIO;
}
else // keep collision during fade
{
if (rover->spawnflags & FF_SOLID)
rover->flags |= FF_SOLID;
if (rover->spawnflags & FF_SWIMMABLE)
rover->flags |= FF_SWIMMABLE;
if (rover->spawnflags & FF_QUICKSAND)
rover->flags |= FF_QUICKSAND;
if (rover->spawnflags & FF_BUSTUP)
rover->flags |= FF_BUSTUP;
if (rover->spawnflags & FF_MARIO)
rover->flags |= FF_MARIO;
}
}
}
if (!(rover->flags & FF_FOG)) // don't set FOG alpha
{
if (!stillfading || exactalpha)
rover->alpha = alpha;
else // clamp fadingdata->alpha to software's alpha levels
{
if (alpha < 12)
rover->alpha = destvalue < 12 ? destvalue : 1; // Don't even draw it
else if (alpha < 38)
rover->alpha = destvalue >= 12 && destvalue < 38 ? destvalue : 25;
else if (alpha < 64)
rover->alpha = destvalue >=38 && destvalue < 64 ? destvalue : 51;
else if (alpha < 89)
rover->alpha = destvalue >= 64 && destvalue < 89 ? destvalue : 76;
else if (alpha < 115)
rover->alpha = destvalue >= 89 && destvalue < 115 ? destvalue : 102;
else if (alpha < 140)
rover->alpha = destvalue >= 115 && destvalue < 140 ? destvalue : 128;
else if (alpha < 166)
rover->alpha = destvalue >= 140 && destvalue < 166 ? destvalue : 154;
else if (alpha < 192)
rover->alpha = destvalue >= 166 && destvalue < 192 ? destvalue : 179;
else if (alpha < 217)
rover->alpha = destvalue >= 192 && destvalue < 217 ? destvalue : 204;
else if (alpha < 243)
rover->alpha = destvalue >= 217 && destvalue < 243 ? destvalue : 230;
else // Opaque
rover->alpha = destvalue >= 243 ? destvalue : 256;
}
}
if (fadingdata)
fadingdata->alpha = alpha;
return stillfading;
}
/** Adds fake floor fader thinker.
*
* \param destvalue transparency value to fade to
* \param speed speed to fade by
* \param ticbased tic-based logic, speed = duration
* \param relative Destvalue is relative to rover->alpha
* \param doexists handle FF_EXISTS
* \param dotranslucent handle FF_TRANSLUCENT
* \param dolighting fade FOF light
* \param docollision handle interactive flags
* \param doghostfade no interactive flags during fading
* \param exactalpha use exact alpha values (opengl)
*/
static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloornum,
INT16 destvalue, INT16 speed, boolean ticbased, boolean relative,
boolean doexists, boolean dotranslucent, boolean dolighting, boolean docolormap,
boolean docollision, boolean doghostfade, boolean exactalpha)
{
fade_t *d;
// If fading an invisible FOF whose render flags we did not yet set,
// initialize its alpha to 1
if (dotranslucent &&
(rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE
!(rover->spawnflags & FF_RENDERSIDES) &&
!(rover->spawnflags & FF_RENDERPLANES) &&
!(rover->flags & FF_RENDERALL))
rover->alpha = 1;
// already equal, nothing to do
if (rover->alpha == max(1, min(256, relative ? rover->alpha + destvalue : destvalue)))
return;
d = Z_Malloc(sizeof *d, PU_LEVSPEC, NULL);
d->thinker.function.acp1 = (actionf_p1)T_Fade;
d->rover = rover;
d->sectornum = (UINT32)sectornum;
d->ffloornum = (UINT32)ffloornum;
d->alpha = d->sourcevalue = rover->alpha;
d->destvalue = max(1, min(256, relative ? rover->alpha + destvalue : destvalue)); // ffloor->alpha is 1-256
if (ticbased)
{
d->ticbased = true;
d->timer = d->speed = abs(speed); // use d->speed as total duration
}
else
{
d->ticbased = false;
d->speed = max(1, speed); // minimum speed 1/tic // if speed < 1, alpha is set immediately in thinker
d->timer = -1;
}
d->doexists = doexists;
d->dotranslucent = dotranslucent;
d->dolighting = dolighting;
d->docolormap = docolormap;
d->docollision = docollision;
d->doghostfade = doghostfade;
d->exactalpha = exactalpha;
// find any existing thinkers and remove them, then replace with new data
P_ResetFakeFloorFader(rover, d, false);
// Set a separate thinker for shadow fading
if (dolighting && !(rover->flags & FF_NOSHADE))
{
UINT16 lightdelta = abs(sectors[rover->secnum].spawn_lightlevel - rover->target->lightlevel);
fixed_t alphapercent = min(FixedDiv(d->destvalue, rover->spawnalpha), 1*FRACUNIT); // don't make darker than spawn_lightlevel
fixed_t adjustedlightdelta = FixedMul(lightdelta, alphapercent);
if (rover->target->lightlevel >= sectors[rover->secnum].spawn_lightlevel) // fading out, get lighter
d->destlightlevel = rover->target->lightlevel - adjustedlightdelta;
else // fading in, get darker
d->destlightlevel = rover->target->lightlevel + adjustedlightdelta;
P_FadeLightBySector(&sectors[rover->secnum],
d->destlightlevel,
ticbased ? d->timer :
FixedFloor(FixedDiv(abs(d->destvalue - d->alpha), d->speed))/FRACUNIT,
true);
}
else
d->destlightlevel = -1;
// Set a separate thinker for colormap fading
if (docolormap && !(rover->flags & FF_NOSHADE) && sectors[rover->secnum].spawn_extra_colormap)
{
extracolormap_t *dest_exc,
*source_exc = sectors[rover->secnum].extra_colormap ? sectors[rover->secnum].extra_colormap : R_GetDefaultColormap();
INT32 colordelta = R_GetRgbaA(sectors[rover->secnum].spawn_extra_colormap->rgba); // alpha is from 0
fixed_t alphapercent = min(FixedDiv(d->destvalue, rover->spawnalpha), 1*FRACUNIT); // don't make darker than spawn_lightlevel
fixed_t adjustedcolordelta = FixedMul(colordelta, alphapercent);
INT32 coloralpha;
coloralpha = adjustedcolordelta;
dest_exc = R_CopyColormap(sectors[rover->secnum].spawn_extra_colormap, false);
dest_exc->rgba = R_GetRgbaRGB(dest_exc->rgba) + R_PutRgbaA(coloralpha);
if (!(d->dest_exc = R_GetColormapFromList(dest_exc)))
{
dest_exc->colormap = R_CreateLightTable(dest_exc);
R_AddColormapToList(dest_exc);
d->dest_exc = dest_exc;
}
else
Z_Free(dest_exc);
// If fading from 0, set source_exc rgb same to dest_exc
if (!R_CheckDefaultColormap(d->dest_exc, true, false, false)
&& R_CheckDefaultColormap(source_exc, true, false, false))
{
extracolormap_t *exc = R_CopyColormap(source_exc, false);
exc->rgba = R_GetRgbaRGB(d->dest_exc->rgba) + R_PutRgbaA(R_GetRgbaA(source_exc->rgba));
exc->fadergba = R_GetRgbaRGB(d->dest_exc->rgba) + R_PutRgbaA(R_GetRgbaA(source_exc->fadergba));
if (!(source_exc = R_GetColormapFromList(exc)))
{
exc->colormap = R_CreateLightTable(exc);
R_AddColormapToList(exc);
source_exc = exc;
}
else
Z_Free(exc);
}
Add_ColormapFader(&sectors[rover->secnum], source_exc, d->dest_exc, true,
ticbased ? d->timer :
FixedFloor(FixedDiv(abs(d->destvalue - d->alpha), d->speed))/FRACUNIT);
}
P_AddThinker(&d->thinker);
}
/** Makes a FOF fade
*
* \param d Fade thinker.
* \sa P_AddFakeFloorFader
*/
void T_Fade(fade_t *d)
{
if (d->rover && !P_FadeFakeFloor(d->rover, d->sourcevalue, d->destvalue, d->speed, d->ticbased, &d->timer,
d->doexists, d->dotranslucent, d->dolighting, d->docolormap, d->docollision, d->doghostfade, d->exactalpha))
{
// Finalize lighting, copypasta from P_AddFakeFloorFader
if (d->dolighting && !(d->rover->flags & FF_NOSHADE) && d->destlightlevel > -1)
sectors[d->rover->secnum].lightlevel = d->destlightlevel;
// Finalize colormap
if (d->docolormap && !(d->rover->flags & FF_NOSHADE) && sectors[d->rover->secnum].spawn_extra_colormap)
sectors[d->rover->secnum].extra_colormap = d->dest_exc;
P_RemoveFakeFloorFader(d->rover);
}
}
static void P_ResetColormapFader(sector_t *sector)
{
if (sector->fadecolormapdata)

View file

@ -150,6 +150,8 @@ typedef struct
#define FASTDARK 15
#define SLOWDARK 35
void P_RemoveLighting(sector_t *sector);
void T_FireFlicker(fireflicker_t *flick);
fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxsector, INT32 length);
void T_LightningFlash(lightflash_t *flash);
@ -459,6 +461,32 @@ typedef struct
void T_Disappear(disappear_t *d);
// Model for fading FOFs
typedef struct
{
thinker_t thinker; ///< Thinker structure for effect.
ffloor_t *rover; ///< Target ffloor
extracolormap_t *dest_exc; ///< Colormap to fade to
UINT32 sectornum; ///< Number of ffloor target sector
UINT32 ffloornum; ///< Number of ffloor of target sector
INT32 alpha; ///< Internal alpha counter
INT16 sourcevalue; ///< Transparency value to fade from
INT16 destvalue; ///< Transparency value to fade to
INT16 destlightlevel; ///< Light level to fade to
INT16 speed; ///< Speed to fade by
boolean ticbased; ///< Tic-based logic toggle
INT32 timer; ///< Timer for tic-based logic
boolean doexists; ///< Handle FF_EXISTS
boolean dotranslucent; ///< Handle FF_TRANSLUCENT
boolean dolighting; ///< Handle shadows and light blocks
boolean docolormap; ///< Handle colormaps
boolean docollision; ///< Handle interactive flags
boolean doghostfade; ///< No interactive flags during fading
boolean exactalpha; ///< Use exact alpha values (opengl)
} fade_t;
void T_Fade(fade_t *d);
// Model for fading colormaps
typedef struct

View file

@ -596,10 +596,6 @@ static void P_DeNightserizePlayer(player_t *player)
else if (player == &players[secondarydisplayplayer])
localaiming2 = 0;
// If you screwed up, kiss your score and ring bonus goodbye.
player->marescore = 0;
player->rings = 0;
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
// If in a special stage, add some preliminary exit time.
@ -611,6 +607,11 @@ static void P_DeNightserizePlayer(player_t *player)
players[i].nightstime = 1; // force everyone else to fall too.
player->exiting = 3*TICRATE;
stagefailed = true; // NIGHT OVER
// If you screwed up, kiss your score and ring bonus goodbye.
// But only do this in special stage (and instakill!) In regular stages, wait til we hit the ground.
player->marescore = player->spheres =\
player->rings = 0;
}
// Check to see if the player should be killed.
@ -624,7 +625,11 @@ static void P_DeNightserizePlayer(player_t *player)
continue;
if (mo2->flags2 & MF2_AMBUSH)
{
player->marescore = player->spheres =\
player->rings = 0;
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
}
break;
}
@ -7077,8 +7082,14 @@ static void P_MovePlayer(player_t *player)
if (playeringame[i])
players[i].exiting = (14*TICRATE)/5 + 1;
}
else if (player->spheres > 0)
else {
// Damage whether or not we have spheres, as player should recoil upon losing points
P_DamageMobj(player->mo, NULL, NULL, 1, 0);
// Now deduct our mare score!
player->marescore = player->spheres =\
player->rings = 0;
}
player->powers[pw_carry] = CR_NONE;
}
}

View file

@ -184,6 +184,8 @@ typedef struct ffloor_s
// these are saved for netgames, so do not let Lua touch these!
ffloortype_e spawnflags; // flags the 3D floor spawned with
INT32 spawnalpha; // alpha the 3D floor spawned with
void *fadingdata; // fading FOF thinker
} ffloor_t;
@ -389,6 +391,9 @@ typedef struct sector_s
boolean hasslope; // The sector, or one of its visible FOFs, contains a slope
#endif
// for fade thinker
INT16 spawn_lightlevel;
// 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

View file

@ -519,6 +519,10 @@ static void do_fading_callback()
static void count_music_bytes(int chan, void *stream, int len, void *udata)
{
(void)chan;
(void)stream;
(void)udata;
if (!music || I_SongType() == MU_GME || I_SongType() == MU_MOD || I_SongType() == MU_MID)
return;
music_bytes += len;
@ -538,6 +542,8 @@ static void music_loop(void)
static UINT32 music_fade(UINT32 interval, void *param)
{
(void)param;
if (!is_fading ||
internal_volume == fading_target ||
fading_duration == 0)
@ -885,6 +891,7 @@ boolean I_LoadSong(char *data, size_t len)
)
I_UnloadSong();
// always do this whether or not a music already exists
var_cleanup();
#ifdef HAVE_LIBGME

View file

@ -1750,6 +1750,26 @@ static void Y_SetRingBonus(player_t *player, y_bonus_t *bstruct)
bstruct->points = max(0, (player->rings) * 100);
}
//
// Y_SetNightsBonus
//
static void Y_SetNightsBonus(player_t *player, y_bonus_t *bstruct)
{
strncpy(bstruct->patch, "YB_NIGHT", sizeof(bstruct->patch));
bstruct->display = true;
bstruct->points = player->totalmarescore;
}
//
// Y_SetLapBonus
//
static void Y_SetLapBonus(player_t *player, y_bonus_t *bstruct)
{
strncpy(bstruct->patch, "YB_LAP", sizeof(bstruct->patch));
bstruct->display = true;
bstruct->points = max(0, player->totalmarebonuslap * 1000);
}
//
// Y_SetLinkBonus
//
@ -1811,7 +1831,7 @@ static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct)
// This list can be extended in the future with SOC/Lua, perhaps.
typedef void (*bonus_f)(player_t *, y_bonus_t *);
bonus_f bonuses_list[4][4] = {
bonus_f bonuses_list[6][4] = {
{
Y_SetNullBonus,
Y_SetNullBonus,
@ -1836,6 +1856,18 @@ bonus_f bonuses_list[4][4] = {
Y_SetRingBonus,
Y_SetPerfectBonus,
},
{
Y_SetNullBonus,
Y_SetNightsBonus,
Y_SetLapBonus,
Y_SetNullBonus,
},
{
Y_SetNullBonus,
Y_SetLinkBonus,
Y_SetLapBonus,
Y_SetNullBonus,
},
};
@ -1911,8 +1943,8 @@ static void Y_AwardSpecialStageBonus(void)
if (!playeringame[i] || players[i].lives < 1) // not active or game over
Y_SetNullBonus(&players[i], &localbonus);
else if (maptol & TOL_NIGHTS) // Link instead of Rings
Y_SetLinkBonus(&players[i], &localbonus);
else if (maptol & TOL_NIGHTS) // Mare score instead of Rings
Y_SetNightsBonus(&players[i], &localbonus);
else
Y_SetRingBonus(&players[i], &localbonus);
players[i].score += localbonus.points;