Make T_RaiseSector use its own thinker struct instead of levelspecthink_t

This commit is contained in:
MascaraSnake 2020-04-17 09:58:53 +02:00
parent 464ecc01a4
commit d0c473c9ae
4 changed files with 163 additions and 121 deletions

View file

@ -1847,7 +1847,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
// Rises up to its topmost position when a // Rises up to its topmost position when a
// player steps on it. Lowers otherwise. // player steps on it. Lowers otherwise.
// //
void T_RaiseSector(levelspecthink_t *raise) void T_RaiseSector(raise_t *raise)
{ {
msecnode_t *node; msecnode_t *node;
mobj_t *thing; mobj_t *thing;
@ -1877,7 +1877,7 @@ void T_RaiseSector(levelspecthink_t *raise)
continue; continue;
// Option to require spindashing. // Option to require spindashing.
if (raise->vars[1] && !(thing->player->pflags & PF_STARTDASH)) if (raise->flags & RF_SPINDASH && !(thing->player->pflags & PF_STARTDASH))
continue; continue;
if (!(thing->z == P_GetSpecialTopZ(thing, raise->sector, sector))) if (!(thing->z == P_GetSpecialTopZ(thing, raise->sector, sector)))
@ -1888,43 +1888,43 @@ void T_RaiseSector(levelspecthink_t *raise)
} }
} }
if (raise->vars[9]) // Dynamically Sinking Platform^tm if (raise->flags & RF_DYNAMIC) // Dynamically Sinking Platform^tm
{ {
#define shaketime 10 #define shaketime 10
if (raise->vars[11] > shaketime) // State: moving if (raise->shaketimer > shaketime) // State: moving
{ {
if (playeronme) // If player is standing on the platform, accelerate if (playeronme) // If player is standing on the platform, accelerate
{ {
raise->vars[10] += (FRACUNIT >> 5); raise->extraspeed += (FRACUNIT >> 5);
} }
else // otherwise, decelerate until inflection else // otherwise, decelerate until inflection
{ {
raise->vars[10] -= FRACUNIT >> 3; raise->extraspeed -= FRACUNIT >> 3;
if (raise->vars[10] <= 0) // inflection! if (raise->extraspeed <= 0) // inflection!
{ {
raise->vars[10] = 0; raise->extraspeed = 0;
raise->vars[11] = 0; // allow the shake to occur again (fucks over players attempting to jump-cheese) raise->shaketimer = 0; // allow the shake to occur again (fucks over players attempting to jump-cheese)
} }
} }
active = raise->vars[10] > 0; active = raise->extraspeed > 0;
} }
else // State: shaking else // State: shaking
{ {
if (playeronme || raise->vars[11]) if (playeronme || raise->shaketimer)
{ {
active = true; active = true;
if (++raise->vars[11] > shaketime) if (++raise->shaketimer > shaketime)
{ {
if (playeronme) if (playeronme)
raise->vars[10] = FRACUNIT >> 5; raise->extraspeed = FRACUNIT >> 5;
else else
raise->vars[10] = FRACUNIT << 1; raise->extraspeed = FRACUNIT << 1;
} }
else else
{ {
raise->vars[10] = ((shaketime/2) - raise->vars[11]) << FRACBITS; raise->extraspeed = ((shaketime/2) - raise->shaketimer) << FRACBITS;
if (raise->vars[10] < -raise->vars[2]/2) if (raise->extraspeed < -raise->basespeed/2)
raise->vars[10] = -raise->vars[2]/2; raise->extraspeed = -raise->basespeed/2;
} }
} }
} }
@ -1935,123 +1935,123 @@ void T_RaiseSector(levelspecthink_t *raise)
if (active) if (active)
{ {
raise->vars[3] = raise->vars[2]; raise->speed = raise->basespeed;
if (raise->vars[0] == 1) if (raise->flags & RF_REVERSE)
{ {
if (raise->sector->ceilingheight <= raise->vars[7]) if (raise->sector->ceilingheight <= raise->ceilingbottom)
{ {
raise->sector->floorheight = raise->vars[7] - (raise->sector->ceilingheight - raise->sector->floorheight); raise->sector->floorheight = raise->ceilingbottom - (raise->sector->ceilingheight - raise->sector->floorheight);
raise->sector->ceilingheight = raise->vars[7]; raise->sector->ceilingheight = raise->ceilingbottom;
raise->sector->ceilspeed = 0; raise->sector->ceilspeed = 0;
raise->sector->floorspeed = 0; raise->sector->floorspeed = 0;
return; return;
} }
raise->vars[8] = -1; raise->direction = -1;
ceilingdestination = raise->vars[7]; ceilingdestination = raise->ceilingbottom;
floordestination = raise->vars[6]; floordestination = raise->floorbottom;
} }
else // elevateUp else // elevateUp
{ {
if (raise->sector->ceilingheight >= raise->vars[5]) if (raise->sector->ceilingheight >= raise->ceilingtop)
{ {
raise->sector->floorheight = raise->vars[5] - (raise->sector->ceilingheight - raise->sector->floorheight); raise->sector->floorheight = raise->ceilingtop - (raise->sector->ceilingheight - raise->sector->floorheight);
raise->sector->ceilingheight = raise->vars[5]; raise->sector->ceilingheight = raise->ceilingtop;
raise->sector->ceilspeed = 0; raise->sector->ceilspeed = 0;
raise->sector->floorspeed = 0; raise->sector->floorspeed = 0;
return; return;
} }
raise->vars[8] = 1; raise->direction = 1;
ceilingdestination = raise->vars[5]; ceilingdestination = raise->ceilingtop;
floordestination = raise->vars[4]; floordestination = raise->floortop;
} }
} }
else else
{ {
raise->vars[3] = raise->vars[2]/2; raise->speed = raise->basespeed/2;
if (raise->vars[0] == 1) if (raise->flags & RF_REVERSE)
{ {
if (raise->sector->ceilingheight >= raise->vars[5]) if (raise->sector->ceilingheight >= raise->ceilingtop)
{ {
raise->sector->floorheight = raise->vars[5] - (raise->sector->ceilingheight - raise->sector->floorheight); raise->sector->floorheight = raise->ceilingtop - (raise->sector->ceilingheight - raise->sector->floorheight);
raise->sector->ceilingheight = raise->vars[5]; raise->sector->ceilingheight = raise->ceilingtop;
raise->sector->ceilspeed = 0; raise->sector->ceilspeed = 0;
raise->sector->floorspeed = 0; raise->sector->floorspeed = 0;
return; return;
} }
raise->vars[8] = 1; raise->direction = 1;
ceilingdestination = raise->vars[5]; ceilingdestination = raise->ceilingtop;
floordestination = raise->vars[4]; floordestination = raise->floortop;
} }
else // elevateUp else // elevateUp
{ {
if (raise->sector->ceilingheight <= raise->vars[7]) if (raise->sector->ceilingheight <= raise->ceilingbottom)
{ {
raise->sector->floorheight = raise->vars[7] - (raise->sector->ceilingheight - raise->sector->floorheight); raise->sector->floorheight = raise->ceilingbottom - (raise->sector->ceilingheight - raise->sector->floorheight);
raise->sector->ceilingheight = raise->vars[7]; raise->sector->ceilingheight = raise->ceilingbottom;
raise->sector->ceilspeed = 0; raise->sector->ceilspeed = 0;
raise->sector->floorspeed = 0; raise->sector->floorspeed = 0;
return; return;
} }
raise->vars[8] = -1; raise->direction = -1;
ceilingdestination = raise->vars[7]; ceilingdestination = raise->ceilingbottom;
floordestination = raise->vars[6]; floordestination = raise->floorbottom;
} }
} }
if ((raise->sector->ceilingheight - raise->vars[7]) if ((raise->sector->ceilingheight - raise->ceilingbottom)
< (raise->vars[5] - raise->sector->ceilingheight)) < (raise->ceilingtop - raise->sector->ceilingheight))
{ {
fixed_t origspeed = raise->vars[3]; fixed_t origspeed = raise->speed;
// Slow down as you get closer to the bottom // Slow down as you get closer to the bottom
raise->vars[3] = FixedMul(raise->vars[3],FixedDiv(raise->sector->ceilingheight - raise->vars[7], (raise->vars[5] - raise->vars[7])>>5)); raise->speed = FixedMul(raise->speed,FixedDiv(raise->sector->ceilingheight - raise->ceilingbottom, (raise->ceilingtop - raise->ceilingbottom)>>5));
if (raise->vars[3] <= origspeed/16) if (raise->speed <= origspeed/16)
raise->vars[3] = origspeed/16; raise->speed = origspeed/16;
else if (raise->vars[3] > origspeed) else if (raise->speed > origspeed)
raise->vars[3] = origspeed; raise->speed = origspeed;
} }
else else
{ {
fixed_t origspeed = raise->vars[3]; fixed_t origspeed = raise->speed;
// Slow down as you get closer to the top // Slow down as you get closer to the top
raise->vars[3] = FixedMul(raise->vars[3],FixedDiv(raise->vars[5] - raise->sector->ceilingheight, (raise->vars[5] - raise->vars[7])>>5)); raise->speed = FixedMul(raise->speed,FixedDiv(raise->ceilingtop - raise->sector->ceilingheight, (raise->ceilingtop - raise->ceilingbottom)>>5));
if (raise->vars[3] <= origspeed/16) if (raise->speed <= origspeed/16)
raise->vars[3] = origspeed/16; raise->speed = origspeed/16;
else if (raise->vars[3] > origspeed) else if (raise->speed > origspeed)
raise->vars[3] = origspeed; raise->speed = origspeed;
} }
raise->vars[3] += raise->vars[10]; raise->speed += raise->extraspeed;
res = T_MovePlane res = T_MovePlane
( (
raise->sector, // sector raise->sector, // sector
raise->vars[3], // speed raise->speed, // speed
ceilingdestination, // dest ceilingdestination, // dest
0, // crush 0, // crush
1, // floor or ceiling (1 for ceiling) 1, // floor or ceiling (1 for ceiling)
raise->vars[8] // direction raise->direction // direction
); );
if (res == ok || res == pastdest) if (res == ok || res == pastdest)
T_MovePlane T_MovePlane
( (
raise->sector, // sector raise->sector, // sector
raise->vars[3], // speed raise->speed, // speed
floordestination, // dest floordestination, // dest
0, // crush 0, // crush
0, // floor or ceiling (0 for floor) 0, // floor or ceiling (0 for floor)
raise->vars[8] // direction raise->direction // direction
); );
raise->sector->ceilspeed = 42; raise->sector->ceilspeed = 42;
raise->sector->floorspeed = raise->vars[3]*raise->vars[8]; raise->sector->floorspeed = raise->speed*raise->direction;
for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;)
P_RecalcPrecipInSector(&sectors[i]); P_RecalcPrecipInSector(&sectors[i]);

View file

@ -1659,6 +1659,28 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEUINT32(save_p, SaveSector(ht->sector));
} }
// SaveRaiseThinker
//
// Saves a raise_t thinker
//
static void SaveRaiseThinker(const thinker_t *th, const UINT8 type)
{
const raise_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEFIXED(save_p, ht->floorbottom);
WRITEFIXED(save_p, ht->ceilingbottom);
WRITEFIXED(save_p, ht->floortop);
WRITEFIXED(save_p, ht->ceilingtop);
WRITEFIXED(save_p, ht->basespeed);
WRITEFIXED(save_p, ht->speed);
WRITEINT32(save_p, ht->direction);
WRITEFIXED(save_p, ht->extraspeed);
WRITEUINT8(save_p, ht->shaketimer);
WRITEUINT8(save_p, ht->flags);
}
// //
// SaveCeilingThinker // SaveCeilingThinker
// //
@ -2237,7 +2259,7 @@ static void P_NetArchiveThinkers(void)
} }
else if (th->function.acp1 == (actionf_p1)T_RaiseSector) else if (th->function.acp1 == (actionf_p1)T_RaiseSector)
{ {
SaveSpecialLevelThinker(th, tc_raisesector); SaveRaiseThinker(th, tc_raisesector);
continue; continue;
} }
else if (th->function.acp1 == (actionf_p1)T_CameraScanner) else if (th->function.acp1 == (actionf_p1)T_CameraScanner)
@ -2770,6 +2792,29 @@ static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeili
return &ht->thinker; return &ht->thinker;
} }
// LoadRaiseThinker
//
// Loads a raise_t from a save game
//
static thinker_t* LoadRaiseThinker(actionf_p1 thinker)
{
raise_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sourceline = LoadLine(READUINT32(save_p));
ht->sector = LoadSector(READUINT32(save_p));
ht->floorbottom = READFIXED(save_p);
ht->ceilingbottom = READFIXED(save_p);
ht->floortop = READFIXED(save_p);
ht->ceilingtop = READFIXED(save_p);
ht->basespeed = READFIXED(save_p);
ht->speed = READFIXED(save_p);
ht->direction = READINT32(save_p);
ht->extraspeed = READFIXED(save_p);
ht->shaketimer = READUINT8(save_p);
ht->flags = READUINT8(save_p);
return &ht->thinker;
}
// //
// LoadCeilingThinker // LoadCeilingThinker
// //
@ -3448,7 +3493,7 @@ static void P_NetUnArchiveThinkers(void)
break; break;
case tc_raisesector: case tc_raisesector:
th = LoadSpecialLevelThinker((actionf_p1)T_RaiseSector, 0); th = LoadRaiseThinker((actionf_p1)T_RaiseSector);
break; break;
/// \todo rewrite all the code that uses an elevator_t but isn't an elevator /// \todo rewrite all the code that uses an elevator_t but isn't an elevator

View file

@ -6042,83 +6042,56 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline)
*/ */
static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline) static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline)
{ {
levelspecthink_t *raise; raise_t *raise;
raise = Z_Calloc(sizeof (*raise), PU_LEVSPEC, NULL); raise = Z_Calloc(sizeof (*raise), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &raise->thinker); P_AddThinker(THINK_MAIN, &raise->thinker);
raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector; raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector;
if (sourceline->flags & ML_BLOCKMONSTERS) raise->sourceline = sourceline;
raise->vars[0] = 1;
else
raise->vars[0] = 0;
// set up the fields
raise->sector = sec; raise->sector = sec;
// Require a spindash to activate raise->ceilingtop = P_FindHighestCeilingSurrounding(sec);
raise->floortop = raise->ceilingtop - (sec->ceilingheight - sec->floorheight);
raise->ceilingbottom = P_FindLowestCeilingSurrounding(sec);
raise->floorbottom = raise->ceilingbottom - (sec->ceilingheight - sec->floorheight);
raise->basespeed = FixedDiv(P_AproxDistance(sourceline->dx, sourceline->dy), 4*FRACUNIT);
raise->speed = raise->basespeed;
if (sourceline->flags & ML_BLOCKMONSTERS)
raise->flags |= RF_REVERSE;
if (sourceline->flags & ML_NOCLIMB) if (sourceline->flags & ML_NOCLIMB)
raise->vars[1] = 1; raise->flags |= RF_SPINDASH;
else
raise->vars[1] = 0;
raise->vars[2] = P_AproxDistance(sourceline->dx, sourceline->dy);
raise->vars[2] = FixedDiv(raise->vars[2], 4*FRACUNIT);
raise->vars[3] = raise->vars[2];
raise->vars[5] = P_FindHighestCeilingSurrounding(sec);
raise->vars[4] = raise->vars[5]
- (sec->ceilingheight - sec->floorheight);
raise->vars[7] = P_FindLowestCeilingSurrounding(sec);
raise->vars[6] = raise->vars[7]
- (sec->ceilingheight - sec->floorheight);
raise->sourceline = sourceline;
} }
static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic) static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic)
{ {
levelspecthink_t *airbob; raise_t *airbob;
airbob = Z_Calloc(sizeof (*airbob), PU_LEVSPEC, NULL); airbob = Z_Calloc(sizeof (*airbob), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &airbob->thinker); P_AddThinker(THINK_MAIN, &airbob->thinker);
airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector; airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector;
// set up the fields airbob->sourceline = sourceline;
airbob->sector = sec; airbob->sector = sec;
// Require a spindash to activate airbob->ceilingtop = sec->ceilingheight;
if (sourceline->flags & ML_NOCLIMB) airbob->floortop = airbob->ceilingtop - (sec->ceilingheight - sec->floorheight);
airbob->vars[1] = 1; airbob->ceilingbottom = sec->ceilingheight - (noadjust ? 16*FRACUNIT : P_AproxDistance(sourceline->dx, sourceline->dy));
else airbob->floorbottom = airbob->ceilingbottom - (sec->ceilingheight - sec->floorheight);
airbob->vars[1] = 0;
airbob->vars[2] = FRACUNIT; airbob->basespeed = FRACUNIT;
airbob->speed = airbob->basespeed;
if (noadjust)
airbob->vars[7] = airbob->sector->ceilingheight-16*FRACUNIT;
else
airbob->vars[7] = airbob->sector->ceilingheight - P_AproxDistance(sourceline->dx, sourceline->dy);
airbob->vars[6] = airbob->vars[7]
- (sec->ceilingheight - sec->floorheight);
airbob->vars[3] = airbob->vars[2];
if (sourceline->flags & ML_BLOCKMONSTERS) if (sourceline->flags & ML_BLOCKMONSTERS)
airbob->vars[0] = 1; airbob->flags |= RF_REVERSE;
else if (sourceline->flags & ML_NOCLIMB)
airbob->vars[0] = 0; airbob->flags |= RF_SPINDASH;
if (dynamic)
airbob->vars[5] = sec->ceilingheight; airbob->flags |= RF_DYNAMIC;
airbob->vars[4] = airbob->vars[5]
- (sec->ceilingheight - sec->floorheight);
airbob->vars[9] = dynamic ? 1 : 0;
airbob->sourceline = sourceline;
} }
/** Adds a thwomp thinker. /** Adds a thwomp thinker.

View file

@ -320,6 +320,30 @@ typedef struct
sector_t *sector; // Sector the thinker is from sector_t *sector; // Sector the thinker is from
} levelspecthink_t; } levelspecthink_t;
typedef enum
{
RF_REVERSE = 1, //Lower when stood on
RF_SPINDASH = 1<<1, //Require spindash to move
RF_DYNAMIC = 1<<2, //Dynamically sinking platform
} raiseflag_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
fixed_t floorbottom;
fixed_t ceilingbottom;
fixed_t floortop;
fixed_t ceilingtop;
fixed_t basespeed;
fixed_t speed;
INT32 direction; //1 = up, -1 = down
fixed_t extraspeed; //For dynamically sinking platform
UINT8 shaketimer; //For dynamically sinking platform
UINT8 flags;
} raise_t;
#define ELEVATORSPEED (FRACUNIT*4) #define ELEVATORSPEED (FRACUNIT*4)
#define FLOORSPEED (FRACUNIT) #define FLOORSPEED (FRACUNIT)
@ -359,7 +383,7 @@ void T_ThwompSector(levelspecthink_t *thwomp);
void T_NoEnemiesSector(levelspecthink_t *nobaddies); void T_NoEnemiesSector(levelspecthink_t *nobaddies);
void T_EachTimeThinker(levelspecthink_t *eachtime); void T_EachTimeThinker(levelspecthink_t *eachtime);
void T_CameraScanner(elevator_t *elevator); void T_CameraScanner(elevator_t *elevator);
void T_RaiseSector(levelspecthink_t *sraise); void T_RaiseSector(raise_t *raise);
typedef struct typedef struct
{ {