Refactor T_ThwompSector

This commit is contained in:
MascaraSnake 2020-04-18 10:26:03 +02:00
parent 29d33f0a93
commit 08f1e03e79
4 changed files with 196 additions and 175 deletions

View File

@ -1104,164 +1104,74 @@ void T_MarioBlockChecker(levelspecthink_t *block)
}
}
static boolean P_IsPlayerValid(size_t playernum)
{
if (!playeringame[playernum])
return false;
if (!players[playernum].mo)
return false;
if (players[playernum].mo->health <= 0)
return false;
if (players[playernum].spectator)
return false;
return true;
}
// This is the Thwomp's 'brain'. It looks around for players nearby, and if
// it finds any, **SMASH**!!! Muahahhaa....
void T_ThwompSector(levelspecthink_t *thwomp)
void T_ThwompSector(thwomp_t *thwomp)
{
#define speed vars[1]
#define direction vars[2]
#define distance vars[3]
#define floorwasheight vars[4]
#define ceilingwasheight vars[5]
fixed_t thwompx, thwompy;
sector_t *actionsector;
ffloor_t *rover = NULL;
INT32 secnum;
fixed_t speed;
// If you just crashed down, wait a second before coming back up.
if (--thwomp->distance > 0)
{
sides[thwomp->sourceline->sidenum[0]].midtexture = sides[thwomp->sourceline->sidenum[0]].bottomtexture;
if (--thwomp->delay > 0)
return;
}
// Just find the first sector with the tag.
// Doesn't work with multiple sectors that have different floor/ceiling heights.
secnum = P_FindSectorFromTag((INT16)thwomp->vars[0], -1);
secnum = P_FindSectorFromTag(thwomp->tag, -1);
if (secnum > 0)
{
actionsector = &sectors[secnum];
// Look for thwomp FFloor
for (rover = actionsector->ffloors; rover; rover = rover->next)
{
if (rover->master == thwomp->sourceline)
break;
}
}
else
if (secnum <= 0)
return; // Bad bad bad!
actionsector = &sectors[secnum];
// Look for thwomp FOF
for (rover = actionsector->ffloors; rover; rover = rover->next)
{
if (rover->master == thwomp->sourceline)
break;
}
if (!rover)
return; // Didn't find any FOFs, so bail out
thwompx = actionsector->soundorg.x;
thwompy = actionsector->soundorg.y;
if (thwomp->direction > 0) // Moving back up..
if (thwomp->direction == 0) // Not going anywhere, so look for players.
{
result_e res = 0;
// Set the texture from the lower one (normal)
sides[thwomp->sourceline->sidenum[0]].midtexture = sides[thwomp->sourceline->sidenum[0]].bottomtexture;
/// \note this should only have to be done once, but is already done repeatedly, above
if (thwomp->sourceline->flags & ML_EFFECT5)
thwomp->speed = thwomp->sourceline->dx/8;
else
thwomp->speed = 2*FRACUNIT;
res = T_MovePlane
(
thwomp->sector, // sector
thwomp->speed, // speed
thwomp->floorwasheight, // dest
false, // crush
false, // ceiling?
thwomp->direction // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
thwomp->sector, // sector
thwomp->speed, // speed
thwomp->ceilingwasheight, // dest
false, // crush
true, // ceiling?
thwomp->direction // direction
);
if (res == pastdest)
thwomp->direction = 0; // stop moving
thwomp->sector->ceilspeed = 42;
thwomp->sector->floorspeed = thwomp->speed*thwomp->direction;
}
else if (thwomp->direction < 0) // Crashing down!
{
result_e res = 0;
// Set the texture from the upper one (angry)
sides[thwomp->sourceline->sidenum[0]].midtexture = sides[thwomp->sourceline->sidenum[0]].toptexture;
if (thwomp->sourceline->flags & ML_EFFECT5)
thwomp->speed = thwomp->sourceline->dy/8;
else
thwomp->speed = 10*FRACUNIT;
res = T_MovePlane
(
thwomp->sector, // sector
thwomp->speed, // speed
P_FloorzAtPos(thwompx, thwompy, thwomp->sector->floorheight,
thwomp->sector->ceilingheight - thwomp->sector->floorheight), // dest
false, // crush
false, // ceiling?
thwomp->direction // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
thwomp->sector, // sector
thwomp->speed, // speed
P_FloorzAtPos(thwompx, thwompy, thwomp->sector->floorheight,
thwomp->sector->ceilingheight
- (thwomp->sector->floorheight + thwomp->speed))
+ (thwomp->sector->ceilingheight
- (thwomp->sector->floorheight + thwomp->speed/2)), // dest
false, // crush
true, // ceiling?
thwomp->direction // direction
);
if (res == pastdest)
{
mobj_t *mp = (void *)&actionsector->soundorg;
if (!rover || (rover->flags & FF_EXISTS))
{
if (thwomp->sourceline->flags & ML_EFFECT4)
S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS);
else
S_StartSound(mp, sfx_thwomp);
}
thwomp->direction = 1; // start heading back up
thwomp->distance = TICRATE; // but only after a small delay
}
thwomp->sector->ceilspeed = 42;
thwomp->sector->floorspeed = thwomp->speed*thwomp->direction;
}
else // Not going anywhere, so look for players.
{
if (!rover || (rover->flags & FF_EXISTS))
if (rover->flags & FF_EXISTS)
{
UINT8 i;
// scan the players to find victims!
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (players[i].spectator)
continue;
if (!players[i].mo)
continue;
if (!players[i].mo->health)
if (!P_IsPlayerValid(i))
continue;
if (players[i].mo->z > thwomp->sector->ceilingheight)
continue;
if (P_AproxDistance(thwompx - players[i].mo->x, thwompy - players[i].mo->y) > 96 * FRACUNIT)
if (P_AproxDistance(thwompx - players[i].mo->x, thwompy - players[i].mo->y) > 96*FRACUNIT)
continue;
thwomp->direction = -1;
@ -1272,13 +1182,89 @@ void T_ThwompSector(levelspecthink_t *thwomp)
thwomp->sector->ceilspeed = 0;
thwomp->sector->floorspeed = 0;
}
else
{
result_e res = 0;
if (thwomp->direction > 0) //Moving back up..
{
// Set the texture from the lower one (normal)
sides[thwomp->sourceline->sidenum[0]].midtexture = sides[thwomp->sourceline->sidenum[0]].bottomtexture;
speed = thwomp->retractspeed;
res = T_MovePlane
(
thwomp->sector, // sector
speed, // speed
thwomp->floorstartheight, // dest
false, // crush
false, // ceiling?
thwomp->direction // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
thwomp->sector, // sector
speed, // speed
thwomp->ceilingstartheight, // dest
false, // crush
true, // ceiling?
thwomp->direction // direction
);
if (res == pastdest)
thwomp->direction = 0; // stop moving
}
else // Crashing down!
{
// Set the texture from the upper one (angry)
sides[thwomp->sourceline->sidenum[0]].midtexture = sides[thwomp->sourceline->sidenum[0]].toptexture;
speed = thwomp->crushspeed;
res = T_MovePlane
(
thwomp->sector, // sector
speed, // speed
P_FloorzAtPos(thwompx, thwompy, thwomp->sector->floorheight,
thwomp->sector->ceilingheight - thwomp->sector->floorheight), // dest
false, // crush
false, // ceiling?
thwomp->direction // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
thwomp->sector, // sector
speed, // speed
P_FloorzAtPos(thwompx, thwompy, thwomp->sector->floorheight,
thwomp->sector->ceilingheight
- (thwomp->sector->floorheight + speed))
+ (thwomp->sector->ceilingheight
- (thwomp->sector->floorheight + speed/2)), // dest
false, // crush
true, // ceiling?
thwomp->direction // direction
);
if (res == pastdest)
{
if (rover->flags & FF_EXISTS)
S_StartSound((void *)&actionsector->soundorg, thwomp->sound);
thwomp->direction = 1; // start heading back up
thwomp->delay = TICRATE; // but only after a small delay
}
}
thwomp->sector->ceilspeed = 42;
thwomp->sector->floorspeed = speed*thwomp->direction;
}
P_RecalcPrecipInSector(actionsector);
#undef speed
#undef direction
#undef distance
#undef floorwasheight
#undef ceilingwasheight
}
static boolean T_SectorHasEnemies(sector_t *sec)
@ -1375,23 +1361,6 @@ static boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec)
return false;
}
static boolean P_IsPlayerValid(size_t playernum)
{
if (!playeringame[playernum])
return false;
if (!players[playernum].mo)
return false;
if (players[playernum].mo->health <= 0)
return false;
if (players[playernum].spectator)
return false;
return true;
}
static boolean P_IsMobjTouchingSector(mobj_t *mo, sector_t *sec)
{
msecnode_t *node;

View File

@ -1704,6 +1704,27 @@ static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type)
WRITEINT16(save_p, ht->tag);
}
//
// SaveThwompThinker
//
// Saves a thwomp_t thinker
//
static void SaveThwompThinker(const thinker_t *th, const UINT8 type)
{
const thwomp_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->crushspeed);
WRITEFIXED(save_p, ht->retractspeed);
WRITEINT32(save_p, ht->direction);
WRITEFIXED(save_p, ht->floorstartheight);
WRITEFIXED(save_p, ht->ceilingstartheight);
WRITEINT32(save_p, ht->delay);
WRITEINT16(save_p, ht->tag);
WRITEUINT16(save_p, ht->sound);
}
//
// SaveFloatThinker
//
@ -2317,7 +2338,7 @@ static void P_NetArchiveThinkers(void)
}
else if (th->function.acp1 == (actionf_p1)T_ThwompSector)
{
SaveSpecialLevelThinker(th, tc_thwomp);
SaveThwompThinker(th, tc_thwomp);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_NoEnemiesSector)
@ -2906,6 +2927,27 @@ static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker)
return &ht->thinker;
}
// LoadThwompThinker
//
// Loads a thwomp_t from a save game
//
static thinker_t* LoadThwompThinker(actionf_p1 thinker)
{
thwomp_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->crushspeed = READFIXED(save_p);
ht->retractspeed = READFIXED(save_p);
ht->direction = READINT32(save_p);
ht->floorstartheight = READFIXED(save_p);
ht->ceilingstartheight = READFIXED(save_p);
ht->delay = READINT32(save_p);
ht->tag = READINT16(save_p);
ht->sound = READUINT16(save_p);
return &ht->thinker;
}
// LoadFloatThinker
//
// Loads a floatthink_t from a save game
@ -3624,7 +3666,7 @@ static void P_NetUnArchiveThinkers(void)
break;
case tc_thwomp:
th = LoadSpecialLevelThinker((actionf_p1)T_ThwompSector, 3);
th = LoadThwompThinker((actionf_p1)T_ThwompSector);
break;
case tc_noenemies:

View File

@ -6068,12 +6068,7 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean
*/
static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, line_t *sourceline)
{
#define speed vars[1]
#define direction vars[2]
#define distance vars[3]
#define floorwasheight vars[4]
#define ceilingwasheight vars[5]
levelspecthink_t *thwomp;
thwomp_t *thwomp;
// You *probably* already have a thwomp in this sector. If you've combined it with something
// else that uses the floordata/ceilingdata, you must be weird.
@ -6087,21 +6082,21 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin
thwomp->thinker.function.acp1 = (actionf_p1)T_ThwompSector;
// set up the fields according to the type of elevator action
thwomp->sector = sec;
thwomp->vars[0] = actionsector->tag;
thwomp->floorwasheight = thwomp->sector->floorheight;
thwomp->ceilingwasheight = thwomp->sector->ceilingheight;
thwomp->direction = 0;
thwomp->distance = 1;
thwomp->sourceline = sourceline;
thwomp->sector->floordata = thwomp;
thwomp->sector->ceilingdata = thwomp;
return;
#undef speed
#undef direction
#undef distance
#undef floorwasheight
#undef ceilingwasheight
thwomp->sector = sec;
thwomp->crushspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dy >> 3 : 10*FRACUNIT;
thwomp->retractspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dx >> 3 : 2*FRACUNIT;
thwomp->direction = 0;
thwomp->floorstartheight = sec->floorheight;
thwomp->ceilingstartheight = sec->ceilingheight;
thwomp->delay = 1;
thwomp->tag = actionsector->tag;
thwomp->sound = (sourceline->flags & ML_EFFECT4) ? sides[sourceline->sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp;
sec->floordata = thwomp;
sec->ceilingdata = thwomp;
// Start with 'resting' texture
sides[sourceline->sidenum[0]].midtexture = sides[sourceline->sidenum[0]].bottomtexture;
}
/** Adds a thinker which checks if any MF_ENEMY objects with health are in the defined area.

View File

@ -348,6 +348,21 @@ typedef struct
INT16 tag;
} mariothink_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
fixed_t crushspeed;
fixed_t retractspeed;
INT32 direction;
fixed_t floorstartheight;
fixed_t ceilingstartheight;
INT32 delay;
INT16 tag;
UINT16 sound;
} thwomp_t;
typedef struct
{
thinker_t thinker;
@ -419,7 +434,7 @@ void T_StartCrumble(elevator_t *elevator);
void T_MarioBlock(mariothink_t *block);
void T_FloatSector(floatthink_t *floater);
void T_MarioBlockChecker(levelspecthink_t *block);
void T_ThwompSector(levelspecthink_t *thwomp);
void T_ThwompSector(thwomp_t *thwomp);
void T_NoEnemiesSector(noenemies_t *nobaddies);
void T_EachTimeThinker(eachtime_t *eachtime);
void T_CameraScanner(elevator_t *elevator);