Merge branch 'lightfade-ticbased' into 'master'

Linedef Exec 420: Fade Lighting add duration timing

See merge request STJr/SRB2Internal!186
This commit is contained in:
Digiku 2018-09-16 08:24:09 -04:00
commit 7aedb8d035
5 changed files with 84 additions and 58 deletions

View file

@ -1809,9 +1809,10 @@ static int lib_pFadeLight(lua_State *L)
INT16 tag = (INT16)luaL_checkinteger(L, 1); INT16 tag = (INT16)luaL_checkinteger(L, 1);
INT32 destvalue = (INT32)luaL_checkinteger(L, 2); INT32 destvalue = (INT32)luaL_checkinteger(L, 2);
INT32 speed = (INT32)luaL_checkinteger(L, 3); INT32 speed = (INT32)luaL_checkinteger(L, 3);
boolean ticbased = lua_optboolean(L, 4);
NOHUD NOHUD
INLEVEL INLEVEL
P_FadeLight(tag, destvalue, speed); P_FadeLight(tag, destvalue, speed, ticbased);
return 0; return 0;
} }

View file

@ -322,40 +322,61 @@ glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector,
return g; return g;
} }
/** Fades all the lights in sectors with a particular tag to a new /** Fades all the lights in specified sector to a new
* value. * value.
* *
* \param tag Tag to look for sectors by. * \param sector Target sector
* \param destvalue The final light value in these sectors. * \param destvalue The final light value in these sectors.
* \param speed Speed of the fade; the change to the ligh * \param speed If tic-based: total duration of effect.
* If speed-based: Speed of the fade; the change to the ligh
* level in each sector per tic. * level in each sector per tic.
* \todo Calculate speed better so that it is possible to specify * \param ticbased Use a specific duration for the fade, defined by speed
* the time for completion of the fade, and all lights fade
* in this time regardless of initial values.
* \sa T_LightFade * \sa T_LightFade
*/ */
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed) void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean ticbased)
{
lightlevel_t *ll;
P_RemoveLighting(sector); // remove the old lighting effect first
if ((ticbased && !speed) || sector->lightlevel == destvalue) // set immediately
{
sector->lightlevel = destvalue;
return;
}
ll = Z_Calloc(sizeof (*ll), PU_LEVSPEC, NULL);
ll->thinker.function.acp1 = (actionf_p1)T_LightFade;
sector->lightingdata = ll; // set it to the lightlevel_t
P_AddThinker(&ll->thinker); // add thinker
ll->sector = sector;
ll->sourcelevel = sector->lightlevel;
ll->destlevel = destvalue;
ll->fixedcurlevel = sector->lightlevel<<FRACBITS;
if (ticbased)
{
// Speed means duration.
ll->timer = abs(speed);
ll->fixedpertic = FixedDiv((destvalue<<FRACBITS) - ll->fixedcurlevel, speed<<FRACBITS);
}
else
{
// Speed means increment per tic (literally speed).
ll->timer = FixedDiv((destvalue<<FRACBITS) - ll->fixedcurlevel, speed<<FRACBITS)>>FRACBITS;
ll->fixedpertic = speed<<FRACBITS;
}
}
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased)
{ {
INT32 i; INT32 i;
lightlevel_t *ll;
sector_t *sector;
// search all sectors for ones with tag // search all sectors for ones with tag
for (i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0 ;) for (i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0 ;)
{ P_FadeLightBySector(&sectors[i], destvalue, speed, ticbased);
sector = &sectors[i];
P_RemoveLighting(sector); // remove the old lighting effect first
ll = Z_Calloc(sizeof (*ll), PU_LEVSPEC, NULL);
ll->thinker.function.acp1 = (actionf_p1)T_LightFade;
sector->lightingdata = ll; // set it to the lightlevel_t
P_AddThinker(&ll->thinker); // add thinker
ll->sector = sector;
ll->destlevel = destvalue;
ll->speed = speed;
}
} }
/** Fades the light level in a sector to a new value. /** Fades the light level in a sector to a new value.
@ -365,30 +386,13 @@ void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed)
*/ */
void T_LightFade(lightlevel_t *ll) void T_LightFade(lightlevel_t *ll)
{ {
if (ll->sector->lightlevel < ll->destlevel) if (--ll->timer <= 0)
{ {
// increase the lightlevel ll->sector->lightlevel = ll->destlevel; // set to dest lightlevel
if (ll->sector->lightlevel + ll->speed >= ll->destlevel) P_RemoveLighting(ll->sector); // clear lightingdata, remove thinker
{ return;
// stop changing light level
ll->sector->lightlevel = (INT16)ll->destlevel; // set to dest lightlevel
P_RemoveLighting(ll->sector); // clear lightingdata, remove thinker
}
else
ll->sector->lightlevel = (INT16)(ll->sector->lightlevel + (INT16)ll->speed); // move lightlevel
} }
else
{
// decrease lightlevel
if (ll->sector->lightlevel - ll->speed <= ll->destlevel)
{
// stop changing light level
ll->sector->lightlevel = (INT16)ll->destlevel; // set to dest lightlevel
P_RemoveLighting(ll->sector); // clear lightingdata, remove thinker ll->fixedcurlevel = ll->fixedcurlevel + ll->fixedpertic;
} ll->sector->lightlevel = (ll->fixedcurlevel)>>FRACBITS;
else
ll->sector->lightlevel = (INT16)(ll->sector->lightlevel - (INT16)ll->speed); // move lightlevel
}
} }

View file

@ -1559,8 +1559,11 @@ static void SaveLightlevelThinker(const thinker_t *th, const UINT8 type)
const lightlevel_t *ht = (const void *)th; const lightlevel_t *ht = (const void *)th;
WRITEUINT8(save_p, type); WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT32(save_p, ht->destlevel); WRITEINT16(save_p, ht->sourcelevel);
WRITEINT32(save_p, ht->speed); WRITEINT16(save_p, ht->destlevel);
WRITEFIXED(save_p, ht->fixedcurlevel);
WRITEFIXED(save_p, ht->fixedpertic);
WRITEINT32(save_p, ht->timer);
} }
// //
@ -2532,8 +2535,11 @@ static inline void LoadLightlevelThinker(actionf_p1 thinker)
lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker; ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p)); ht->sector = LoadSector(READUINT32(save_p));
ht->destlevel = READINT32(save_p); ht->sourcelevel = READINT16(save_p);
ht->speed = READINT32(save_p); ht->destlevel = READINT16(save_p);
ht->fixedcurlevel = READFIXED(save_p);
ht->fixedpertic = READFIXED(save_p);
ht->timer = READINT32(save_p);
if (ht->sector) if (ht->sector)
ht->sector->lightingdata = ht; ht->sector->lightingdata = ht;
P_AddThinker(&ht->thinker); P_AddThinker(&ht->thinker);

View file

@ -2778,7 +2778,16 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
break; break;
case 420: // Fade light levels in tagged sectors to new value case 420: // Fade light levels in tagged sectors to new value
P_FadeLight(line->tag, line->frontsector->lightlevel, P_AproxDistance(line->dx, line->dy)>>FRACBITS); P_FadeLight(line->tag,
(line->flags & ML_DONTPEGBOTTOM) ? max(sides[line->sidenum[0]].textureoffset>>FRACBITS, 0) : line->frontsector->lightlevel,
// failsafe: if user specifies Back Y Offset and NOT Front Y Offset, use the Back Offset
// to be consistent with other light and fade specials
(line->flags & ML_DONTPEGBOTTOM) ?
((line->sidenum[1] != 0xFFFF && !(sides[line->sidenum[0]].rowoffset>>FRACBITS)) ?
max(min(sides[line->sidenum[1]].rowoffset>>FRACBITS, 255), 0)
: max(min(sides[line->sidenum[0]].rowoffset>>FRACBITS, 255), 0))
: abs(P_AproxDistance(line->dx, line->dy))>>FRACBITS,
(line->flags & ML_EFFECT4));
break; break;
case 421: // Stop lighting effect in tagged sectors case 421: // Stop lighting effect in tagged sectors

View file

@ -134,10 +134,15 @@ typedef struct
*/ */
typedef struct typedef struct
{ {
thinker_t thinker; ///< Thinker in use for the effect. thinker_t thinker; ///< Thinker in use for the effect.
sector_t *sector; ///< Sector where action is taking place. sector_t *sector; ///< Sector where action is taking place.
INT32 destlevel; ///< Light level we're fading to. INT16 sourcelevel; ///< Light level we're fading from.
INT32 speed; ///< Speed at which to change light level. INT16 destlevel; ///< Light level we're fading to.
fixed_t fixedcurlevel; ///< Fixed point for current light level.
fixed_t fixedpertic; ///< Fixed point for increment per tic.
// The reason for those two above to be fixed point is to deal with decimal values that would otherwise get trimmed away.
INT32 timer; ///< Internal timer.
} lightlevel_t; } lightlevel_t;
#define GLOWSPEED 8 #define GLOWSPEED 8
@ -156,7 +161,8 @@ strobe_t * P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector
void T_Glow(glow_t *g); void T_Glow(glow_t *g);
glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, INT32 length); glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, INT32 length);
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed); void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean ticbased);
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased);
void T_LightFade(lightlevel_t *ll); void T_LightFade(lightlevel_t *ll);
typedef enum typedef enum