Merge branch 'nightsplus-le' into 'master'

NiGHTS Linedef Executor Triggers

Closes #102

See merge request STJr/SRB2Internal!142
This commit is contained in:
Digiku 2018-09-02 18:10:50 -04:00
commit 01314b6674
5 changed files with 249 additions and 3 deletions

View File

@ -1126,6 +1126,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
// Respawn rings and items
P_ReloadRings();
}
P_RunNightsLapExecutors(pl->mo);
}
droneobj->extravalue1 = pl->flyangle;
droneobj->extravalue2 = (INT32)leveltime + TICRATE;

View File

@ -8775,7 +8775,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
nummaprings = -1; // no perfect bonus, rings are free
break;
case MT_EGGCAPSULE:
mobj->extravalue1 = -1; // timer for how long a player has been at the capsule
mobj->extravalue1 = -1; // sphere timer for how long a player has been at the capsule
mobj->extravalue2 = -1; // tic timer for how long a player has been at the capsule
break;
case MT_REDTEAMRING:
mobj->color = skincolor_redteam;

View File

@ -1375,6 +1375,67 @@ void P_ChangeSectorTag(UINT32 sector, INT16 newtag)
}
}
//
// P_RunNightserizeExecutors
//
void P_RunNightserizeExecutors(mobj_t *actor)
{
size_t i;
for (i = 0; i < numlines; i++)
{
if (lines[i].special == 323 || lines[i].special == 324)
P_RunTriggerLinedef(&lines[i], actor, NULL);
}
}
//
// P_RunDeNightserizeExecutors
//
void P_RunDeNightserizeExecutors(mobj_t *actor)
{
size_t i;
for (i = 0; i < numlines; i++)
{
if (lines[i].special == 325 || lines[i].special == 326)
P_RunTriggerLinedef(&lines[i], actor, NULL);
}
}
//
// P_RunNightsLapExecutors
//
void P_RunNightsLapExecutors(mobj_t *actor)
{
size_t i;
for (i = 0; i < numlines; i++)
{
if (lines[i].special == 327 || lines[i].special == 328)
P_RunTriggerLinedef(&lines[i], actor, NULL);
}
}
//
// P_RunNightsCapsuleTouchExecutors
//
void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres)
{
size_t i;
for (i = 0; i < numlines; i++)
{
if ((lines[i].special == 329 || lines[i].special == 330)
&& ((entering && (lines[i].flags & ML_TFERLINE))
|| (!entering && !(lines[i].flags & ML_TFERLINE)))
&& ((lines[i].flags & ML_DONTPEGTOP)
|| (enoughspheres && !(lines[i].flags & ML_BOUNCY))
|| (!enoughspheres && (lines[i].flags & ML_BOUNCY))))
P_RunTriggerLinedef(&lines[i], actor, NULL);
}
}
/** Hashes the sector tags across the sectors and linedefs.
*
* \sa P_FindSectorFromTag, P_ChangeSectorTag
@ -1458,6 +1519,145 @@ static void P_AddExecutorDelay(line_t *line, mobj_t *mobj, sector_t *sector)
P_AddThinker(&e->thinker);
}
/** Used by P_RunTriggerLinedef to check a NiGHTS trigger linedef's conditions
*
* \param triggerline Trigger linedef to check conditions for; should NEVER be NULL.
* \param actor Object initiating the action; should not be NULL.
* \sa P_RunTriggerLinedef
*/
static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor)
{
INT16 specialtype = triggerline->special;
size_t i;
UINT8 inputmare = max(0, min(255, sides[triggerline->sidenum[0]].textureoffset>>FRACBITS));
UINT8 inputlap = max(0, min(255, sides[triggerline->sidenum[0]].rowoffset>>FRACBITS));
boolean ltemare = triggerline->flags & ML_NOCLIMB;
boolean gtemare = triggerline->flags & ML_BLOCKMONSTERS;
boolean ltelap = triggerline->flags & ML_EFFECT1;
boolean gtelap = triggerline->flags & ML_EFFECT2;
boolean lapfrombonustime = triggerline->flags & ML_EFFECT3;
boolean perglobalinverse = triggerline->flags & ML_DONTPEGBOTTOM;
boolean perglobal = !(triggerline->flags & ML_EFFECT4) && !perglobalinverse;
boolean donomares = triggerline->flags & ML_BOUNCY; // nightserize: run at end of level (no mares)
boolean fromnonights = triggerline->flags & ML_TFERLINE; // nightserize: from non-nights // denightserize: all players no nights
boolean fromnights = triggerline->flags & ML_DONTPEGTOP; // nightserize: from nights // denightserize: >0 players are nights
UINT8 currentmare = UINT8_MAX;
UINT8 currentlap = UINT8_MAX;
// Do early returns for Nightserize
if (specialtype >= 323 && specialtype <= 324)
{
// run only when no mares are found
if (donomares && P_FindLowestMare() != UINT8_MAX)
return false;
// run only if there is a mare present
if (!donomares && P_FindLowestMare() == UINT8_MAX)
return false;
// run only if player is nightserizing from non-nights
if (fromnonights)
{
if (!actor->player)
return false;
else if (actor->player->powers[pw_carry] == CR_NIGHTSMODE)
return false;
}
// run only if player is nightserizing from nights
else if (fromnights)
{
if (!actor->player)
return false;
else if (actor->player->powers[pw_carry] != CR_NIGHTSMODE)
return false;
}
}
// Get current mare and lap (and check early return for DeNightserize)
if (perglobal || perglobalinverse
|| (specialtype >= 325 && specialtype <= 326 && (fromnonights || fromnights)))
{
UINT8 playersarenights = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
// denightserize: run only if all players are not nights
if (specialtype >= 325 && specialtype <= 326 && fromnonights
&& players[i].powers[pw_carry] == CR_NIGHTSMODE)
return false;
// count number of nights players for denightserize return
if (specialtype >= 325 && specialtype <= 326 && fromnights
&& players[i].powers[pw_carry] == CR_NIGHTSMODE)
playersarenights++;
UINT8 lap = lapfrombonustime ? players[i].marebonuslap : players[i].marelap;
// get highest mare/lap of players
if (perglobal)
{
if (players[i].mare > currentmare || currentmare == UINT8_MAX)
{
currentmare = players[i].mare;
currentlap = UINT8_MAX;
}
if (players[i].mare == currentmare
&& (lap > currentlap || currentlap == UINT8_MAX))
currentlap = lap;
}
// get lowest mare/lap of players
else if (perglobalinverse)
{
if (players[i].mare < currentmare || currentmare == UINT8_MAX)
{
currentmare = players[i].mare;
currentlap = UINT8_MAX;
}
if (players[i].mare == currentmare
&& (lap < currentlap || currentlap == UINT8_MAX))
currentlap = lap;
}
}
// denightserize: run only if >0 players are nights
if (specialtype >= 325 && specialtype <= 326 && fromnights
&& playersarenights < 1)
return false;
}
// get current mare/lap from triggering player
else if (!perglobal && !perglobalinverse)
{
if (!actor->player)
return false;
currentmare = actor->player->mare;
currentlap = lapfrombonustime ? actor->player->marebonuslap : actor->player->marelap;
}
if (lapfrombonustime && !currentlap)
return false; // special case: player->marebonuslap is 0 until passing through on bonus time. Don't trigger lines looking for inputlap 0.
// Compare current mare/lap to input mare/lap based on rules
if (!(specialtype >= 323 && specialtype <= 324 && donomares) // don't return false if donomares and we got this far
&& ((ltemare && currentmare > inputmare)
|| (gtemare && currentmare < inputmare)
|| (!ltemare && !gtemare && currentmare != inputmare)
|| (ltelap && currentlap > inputlap)
|| (gtelap && currentlap < inputlap)
|| (!ltelap && !gtelap && currentlap != inputlap))
)
return false;
return true;
}
/** Used by P_LinedefExecute to check a trigger linedef's conditions
* The linedef executor specials in the trigger linedef's sector are run if all conditions are met.
* Return false cancels P_LinedefExecute, this happens if a condition is not met.
@ -1668,6 +1868,18 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
return false;
}
break;
case 323: // nightserize - each time
case 324: // nightserize - once
case 325: // denightserize - each time
case 326: // denightserize - once
case 327: // nights lap - each time
case 328: // nights lap - once
case 329: // nights egg capsule touch - each time
case 330: // nights egg capsule touch - once
if (!P_CheckNightsTriggerLine(triggerline, actor))
return false;
break;
default:
break;
}
@ -1796,6 +2008,10 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|| specialtype == 318 // Unlockable trigger - Once
|| specialtype == 320 // Unlockable - Once
|| specialtype == 321 || specialtype == 322 // Trigger on X calls - Continuous + Each Time
|| specialtype == 324 // Nightserize - Once
|| specialtype == 326 // DeNightserize - Once
|| specialtype == 328 // Nights lap - Once
|| specialtype == 330 // Nights Bonus Time - Once
|| specialtype == 399) // Level Load
triggerline->special = 0; // Clear it out
@ -6419,6 +6635,17 @@ void P_SpawnSpecials(INT32 fromnetsave)
}
break;
// NiGHTS trigger executors
case 323:
case 324:
case 325:
case 326:
case 327:
case 328:
case 329:
case 330:
break;
case 399: // Linedef execute on map load
// This is handled in P_RunLevelLoadExecutors.
break;

View File

@ -66,6 +66,10 @@ void P_SwitchWeather(INT32 weathernum);
boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller);
void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller);
void P_ChangeSectorTag(UINT32 sector, INT16 newtag);
void P_RunNightserizeExecutors(mobj_t *actor);
void P_RunDeNightserizeExecutors(mobj_t *actor);
void P_RunNightsLapExecutors(mobj_t *actor);
void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres);
ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id);

View File

@ -631,6 +631,8 @@ static void P_DeNightserizePlayer(player_t *player)
// Restore from drowning music
P_RestoreMusic(player);
P_RunDeNightserizeExecutors(player->mo);
}
//
@ -790,6 +792,9 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
(player->flyangle > 90 && player->flyangle < 270 ? ANGLE_90 : -ANGLE_90)
: (player->flyangle > 90 && player->flyangle < 270 ? -ANGLE_90 : ANGLE_90));
// Do this before setting CR_NIGHTSMODE so we can tell if player was non-NiGHTS
P_RunNightserizeExecutors(player->mo);
player->powers[pw_carry] = CR_NIGHTSMODE;
}
@ -5952,6 +5957,8 @@ static void P_DoNiGHTSCapsule(player_t *player)
{
INT32 i;
player->capsule->extravalue2++; // tic counter
if (abs(player->mo->x-player->capsule->x) <= 2*FRACUNIT)
{
P_UnsetThingPosition(player->mo);
@ -6013,6 +6020,9 @@ static void P_DoNiGHTSCapsule(player_t *player)
}
}
if (player->capsule->extravalue2 <= 0 && player->capsule->health > 0)
P_RunNightsCapsuleTouchExecutors(player->mo, true, player->spheres >= player->capsule->health); // run capsule entrance executors
// Time to blow it up!
if (player->mo->x == player->capsule->x
&& player->mo->y == player->capsule->y
@ -6036,7 +6046,7 @@ static void P_DoNiGHTSCapsule(player_t *player)
player->capsule->flags &= ~MF_NOGRAVITY;
player->capsule->momz = 5*FRACUNIT;
player->capsule->reactiontime = 0;
player->capsule->extravalue1 = -1;
player->capsule->extravalue1 = player->capsule->extravalue2 = -1;
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && !player->exiting && players[i].mare == player->mare)
@ -6105,6 +6115,7 @@ static void P_DoNiGHTSCapsule(player_t *player)
P_SetTarget(&players[i].capsule, NULL); // Remove capsule from everyone now that it is dead!
S_StartScreamSound(player->mo, sfx_ngdone);
P_SwitchSpheresBonusMode(true);
P_RunNightsCapsuleTouchExecutors(player->mo, false, true); // run capsule exit executors, and we destroyed it
}
}
else
@ -6113,7 +6124,8 @@ static void P_DoNiGHTSCapsule(player_t *player)
player->texttimer = 4*TICRATE;
player->textvar = 3; // Get more rings!
player->capsule->reactiontime = 0;
player->capsule->extravalue1 = -1;
player->capsule->extravalue1 = player->capsule->extravalue2 = -1;
P_RunNightsCapsuleTouchExecutors(player->mo, false, false); // run capsule exit executors, and we lacked rings
}
}
else