Port over thwomp thinker changes manually, to avoid merge conflicts

This commit is contained in:
MascaraSnake 2020-04-25 09:20:53 +02:00
parent 1d3aa7129a
commit 0ab01cd4b2
4 changed files with 197 additions and 151 deletions

View file

@ -11,7 +11,6 @@
/// \file p_floor.c
/// \brief Floor animation, elevators
#include "dehacked.h"
#include "doomdef.h"
#include "doomstat.h"
#include "m_random.h"
@ -1266,156 +1265,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
thwomp->speed = thwomp->sourceline->args[2] << (FRACBITS - 3);
res = T_MovePlane
(
thwomp->sector, // sector
thwomp->speed, // speed
thwomp->floorwasheight, // dest
0, // crush
0, // floor or ceiling (0 for floor)
thwomp->direction // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
thwomp->sector, // sector
thwomp->speed, // speed
thwomp->ceilingwasheight, // dest
0, // crush
1, // floor or ceiling (1 for 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;
thwomp->speed = thwomp->sourceline->args[1] << (FRACBITS - 3);
res = T_MovePlane
(
thwomp->sector, // sector
thwomp->speed, // speed
P_FloorzAtPos(thwompx, thwompy, thwomp->sector->floorheight,
thwomp->sector->ceilingheight - thwomp->sector->floorheight), // dest
0, // crush
0, // floor or ceiling (0 for floor)
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
0, // crush
1, // floor or ceiling (1 for ceiling)
thwomp->direction // direction
);
if (res == pastdest)
{
mobj_t *mp = (void *)&actionsector->soundorg;
if (!rover || (rover->flags & FF_EXISTS))
{
sfxenum_t sound = (thwomp->sourceline->stringargs[0]) ? get_number(thwomp->sourceline->stringargs[0]) : sfx_thwomp;
S_StartSound(mp, sound);
}
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;
@ -1426,13 +1343,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
0, // ceiling?
thwomp->direction // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
thwomp->sector, // sector
speed, // speed
thwomp->ceilingstartheight, // dest
false, // crush
1, // 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
0, // 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
1, // 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
}
//

View file

@ -1745,6 +1745,27 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
WRITEUINT32(save_p, SaveSector(ht->sector));
}
//
// 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);
}
//
// SaveCeilingThinker
//
@ -2308,7 +2329,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)
@ -2856,6 +2877,27 @@ static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeili
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;
}
//
// LoadCeilingThinker
//
@ -3522,7 +3564,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

@ -15,6 +15,7 @@
/// utility functions, etc.
/// Line Tag handling. Line and Sector triggers.
#include "dehacked.h"
#include "doomdef.h"
#include "g_game.h"
#include "p_local.h"
@ -6133,12 +6134,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.
@ -6152,21 +6148,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 = thwomp->sourceline->args[1] << (FRACBITS - 3);
thwomp->retractspeed = thwomp->sourceline->args[2] << (FRACBITS - 3);
thwomp->direction = 0;
thwomp->floorstartheight = sec->floorheight;
thwomp->ceilingstartheight = sec->ceilingheight;
thwomp->delay = 1;
thwomp->tag = actionsector->tag;
thwomp->sound = (thwomp->sourceline->stringargs[0]) ? get_number(thwomp->sourceline->stringargs[0]) : 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

@ -383,6 +383,21 @@ typedef struct
sector_t *sector; // Sector the thinker is from
} levelspecthink_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;
#define ELEVATORSPEED (FRACUNIT*4)
#define FLOORSPEED (FRACUNIT)
@ -418,7 +433,7 @@ void T_MarioBlock(levelspecthink_t *block);
void T_SpikeSector(levelspecthink_t *spikes);
void T_FloatSector(levelspecthink_t *floater);
void T_MarioBlockChecker(levelspecthink_t *block);
void T_ThwompSector(levelspecthink_t *thwomp);
void T_ThwompSector(thwomp_t *thwomp);
void T_NoEnemiesSector(levelspecthink_t *nobaddies);
void T_EachTimeThinker(levelspecthink_t *eachtime);
void T_CameraScanner(elevator_t *elevator);