Merge branch 'thinker-cleanup' into 'next'

Plane movement thinker cleanup

See merge request STJr/SRB2!880
This commit is contained in:
Monster Iestyn 2020-04-24 14:30:52 -04:00
commit d1d006a1a7
9 changed files with 968 additions and 1132 deletions

View File

@ -47,8 +47,7 @@ void T_MoveCeiling(ceiling_t *ceiling)
case 0: // IN STASIS
break;
case 1: // UP
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false,
1, ceiling->direction);
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
if (ceiling->type == bounceCeiling)
{
@ -159,8 +158,7 @@ void T_MoveCeiling(ceiling_t *ceiling)
break;
case -1: // DOWN
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight,
ceiling->crush, 1, ceiling->direction);
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
if (ceiling->type == bounceCeiling)
{
@ -314,11 +312,10 @@ void T_CrushCeiling(ceiling_t *ceiling)
if (ceiling->type == crushBothOnce)
{
// Move the floor
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, 0, -ceiling->direction);
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, false, -ceiling->direction);
}
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight,
false, 1, ceiling->direction);
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
if (res == pastdest)
{
@ -357,11 +354,10 @@ void T_CrushCeiling(ceiling_t *ceiling)
if (ceiling->type == crushBothOnce)
{
// Move the floor
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, 0, -ceiling->direction);
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, false, -ceiling->direction);
}
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight,
ceiling->crush, 1, ceiling->direction);
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
if (res == pastdest)
{

File diff suppressed because it is too large Load Diff

View File

@ -1691,7 +1691,7 @@ static void P_PushableCheckBustables(mobj_t *mo)
// Needs ML_EFFECT4 flag for pushables to break it
if (!(rover->master->flags & ML_EFFECT4)) continue;
if (!rover->master->frontsector->crumblestate)
if (rover->master->frontsector->crumblestate == CRUMBLE_NONE)
{
topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);

View File

@ -1280,7 +1280,6 @@ typedef enum
tc_startcrumble,
tc_marioblock,
tc_marioblockchecker,
tc_spikesector,
tc_floatsector,
tc_crushceiling,
tc_scroll,
@ -1648,22 +1647,151 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
}
//
// SaveSpecialLevelThinker
// SaveNoEnemiesThinker
//
// Saves a levelspecthink_t thinker
// Saves a noenemies_t thinker
//
static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type)
{
const levelspecthink_t *ht = (const void *)th;
size_t i;
const noenemies_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
}
//
// SaveBounceCheeseThinker
//
// Saves a bouncecheese_t thinker
//
static void SaveBounceCheeseThinker(const thinker_t *th, const UINT8 type)
{
const bouncecheese_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
for (i = 0; i < 16; i++)
{
WRITEFIXED(save_p, ht->vars[i]); //var[16]
WRITEFIXED(save_p, ht->var2s[i]); //var[16]
}
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEFIXED(save_p, ht->speed);
WRITEFIXED(save_p, ht->distance);
WRITEFIXED(save_p, ht->floorwasheight);
WRITEFIXED(save_p, ht->ceilingwasheight);
WRITECHAR(save_p, ht->low);
}
//
// SaveContinuousFallThinker
//
// Saves a continuousfall_t thinker
//
static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type)
{
const continuousfall_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEFIXED(save_p, ht->speed);
WRITEINT32(save_p, ht->direction);
WRITEFIXED(save_p, ht->floorstartheight);
WRITEFIXED(save_p, ht->ceilingstartheight);
WRITEFIXED(save_p, ht->destheight);
}
//
// SaveMarioBlockThinker
//
// Saves a mariothink_t thinker
//
static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type)
{
const mariothink_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEFIXED(save_p, ht->speed);
WRITEINT32(save_p, ht->direction);
WRITEFIXED(save_p, ht->floorstartheight);
WRITEFIXED(save_p, ht->ceilingstartheight);
WRITEINT16(save_p, ht->tag);
}
//
// SaveMarioCheckThinker
//
// Saves a mariocheck_t thinker
//
static void SaveMarioCheckThinker(const thinker_t *th, const UINT8 type)
{
const mariocheck_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
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);
}
//
// SaveFloatThinker
//
// Saves a floatthink_t thinker
//
static void SaveFloatThinker(const thinker_t *th, const UINT8 type)
{
const floatthink_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT16(save_p, ht->tag);
}
// SaveEachTimeThinker
//
// Loads a eachtime_t from a save game
//
static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type)
{
const eachtime_t *ht = (const void *)th;
size_t i;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
for (i = 0; i < MAXPLAYERS; i++)
{
WRITECHAR(save_p, ht->playersInArea[i]);
WRITECHAR(save_p, ht->playersOnArea[i]);
}
WRITECHAR(save_p, ht->triggerOnExit);
}
// 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->ceilingbottom);
WRITEFIXED(save_p, ht->ceilingtop);
WRITEFIXED(save_p, ht->basespeed);
WRITEFIXED(save_p, ht->extraspeed);
WRITEUINT8(save_p, ht->shaketimer);
WRITEUINT8(save_p, ht->flags);
}
//
@ -2224,27 +2352,27 @@ static void P_NetArchiveThinkers(void)
}
else if (th->function.acp1 == (actionf_p1)T_ContinuousFalling)
{
SaveSpecialLevelThinker(th, tc_continuousfalling);
SaveContinuousFallThinker(th, tc_continuousfalling);
continue;
}
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)
{
SaveSpecialLevelThinker(th, tc_noenemies);
SaveNoEnemiesThinker(th, tc_noenemies);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_EachTimeThinker)
{
SaveSpecialLevelThinker(th, tc_eachtime);
SaveEachTimeThinker(th, tc_eachtime);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_RaiseSector)
{
SaveSpecialLevelThinker(th, tc_raisesector);
SaveRaiseThinker(th, tc_raisesector);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_CameraScanner)
@ -2269,7 +2397,7 @@ static void P_NetArchiveThinkers(void)
}
else if (th->function.acp1 == (actionf_p1)T_BounceCheese)
{
SaveSpecialLevelThinker(th, tc_bouncecheese);
SaveBounceCheeseThinker(th, tc_bouncecheese);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_StartCrumble)
@ -2279,22 +2407,17 @@ static void P_NetArchiveThinkers(void)
}
else if (th->function.acp1 == (actionf_p1)T_MarioBlock)
{
SaveSpecialLevelThinker(th, tc_marioblock);
SaveMarioBlockThinker(th, tc_marioblock);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker)
{
SaveSpecialLevelThinker(th, tc_marioblockchecker);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_SpikeSector)
{
SaveSpecialLevelThinker(th, tc_spikesector);
SaveMarioCheckThinker(th, tc_marioblockchecker);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_FloatSector)
{
SaveSpecialLevelThinker(th, tc_floatsector);
SaveFloatThinker(th, tc_floatsector);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_LaserFlash)
@ -2742,38 +2865,153 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
return &mobj->thinker;
}
// LoadNoEnemiesThinker
//
// LoadSpecialLevelThinker
// Loads a noenemies_t from a save game
//
// Loads a levelspecthink_t from a save game
//
// floorOrCeiling:
// 0 - Don't set
// 1 - Floor Only
// 2 - Ceiling Only
// 3 - Both
//
static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling)
static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker)
{
levelspecthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
size_t i;
noenemies_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sourceline = LoadLine(READUINT32(save_p));
return &ht->thinker;
}
// LoadBounceCheeseThinker
//
// Loads a bouncecheese_t from a save game
//
static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker)
{
bouncecheese_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
for (i = 0; i < 16; i++)
{
ht->vars[i] = READFIXED(save_p); //var[16]
ht->var2s[i] = READFIXED(save_p); //var[16]
}
ht->sourceline = LoadLine(READUINT32(save_p));
ht->sector = LoadSector(READUINT32(save_p));
ht->speed = READFIXED(save_p);
ht->distance = READFIXED(save_p);
ht->floorwasheight = READFIXED(save_p);
ht->ceilingwasheight = READFIXED(save_p);
ht->low = READCHAR(save_p);
return &ht->thinker;
}
if (ht->sector)
// LoadContinuousFallThinker
//
// Loads a continuousfall_t from a save game
//
static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker)
{
continuousfall_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->speed = READFIXED(save_p);
ht->direction = READINT32(save_p);
ht->floorstartheight = READFIXED(save_p);
ht->ceilingstartheight = READFIXED(save_p);
ht->destheight = READFIXED(save_p);
return &ht->thinker;
}
// LoadMarioBlockThinker
//
// Loads a mariothink_t from a save game
//
static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker)
{
mariothink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->speed = READFIXED(save_p);
ht->direction = READINT32(save_p);
ht->floorstartheight = READFIXED(save_p);
ht->ceilingstartheight = READFIXED(save_p);
ht->tag = READINT16(save_p);
return &ht->thinker;
}
// LoadMarioCheckThinker
//
// Loads a mariocheck_t from a save game
//
static thinker_t* LoadMarioCheckThinker(actionf_p1 thinker)
{
mariocheck_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));
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
//
static thinker_t* LoadFloatThinker(actionf_p1 thinker)
{
floatthink_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->tag = READINT16(save_p);
return &ht->thinker;
}
// LoadEachTimeThinker
//
// Loads a eachtime_t from a save game
//
static thinker_t* LoadEachTimeThinker(actionf_p1 thinker)
{
size_t i;
eachtime_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sourceline = LoadLine(READUINT32(save_p));
for (i = 0; i < MAXPLAYERS; i++)
{
if (floorOrCeiling & 2)
ht->sector->ceilingdata = ht;
if (floorOrCeiling & 1)
ht->sector->floordata = ht;
ht->playersInArea[i] = READCHAR(save_p);
ht->playersOnArea[i] = READCHAR(save_p);
}
ht->triggerOnExit = READCHAR(save_p);
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->ceilingbottom = READFIXED(save_p);
ht->ceilingtop = READFIXED(save_p);
ht->basespeed = READFIXED(save_p);
ht->extraspeed = READFIXED(save_p);
ht->shaketimer = READUINT8(save_p);
ht->flags = READUINT8(save_p);
return &ht->thinker;
}
@ -3439,23 +3677,23 @@ static void P_NetUnArchiveThinkers(void)
break;
case tc_continuousfalling:
th = LoadSpecialLevelThinker((actionf_p1)T_ContinuousFalling, 3);
th = LoadContinuousFallThinker((actionf_p1)T_ContinuousFalling);
break;
case tc_thwomp:
th = LoadSpecialLevelThinker((actionf_p1)T_ThwompSector, 3);
th = LoadThwompThinker((actionf_p1)T_ThwompSector);
break;
case tc_noenemies:
th = LoadSpecialLevelThinker((actionf_p1)T_NoEnemiesSector, 0);
th = LoadNoEnemiesThinker((actionf_p1)T_NoEnemiesSector);
break;
case tc_eachtime:
th = LoadSpecialLevelThinker((actionf_p1)T_EachTimeThinker, 0);
th = LoadEachTimeThinker((actionf_p1)T_EachTimeThinker);
break;
case tc_raisesector:
th = LoadSpecialLevelThinker((actionf_p1)T_RaiseSector, 0);
th = LoadRaiseThinker((actionf_p1)T_RaiseSector);
break;
/// \todo rewrite all the code that uses an elevator_t but isn't an elevator
@ -3465,7 +3703,7 @@ static void P_NetUnArchiveThinkers(void)
break;
case tc_bouncecheese:
th = LoadSpecialLevelThinker((actionf_p1)T_BounceCheese, 2);
th = LoadBounceCheeseThinker((actionf_p1)T_BounceCheese);
break;
case tc_startcrumble:
@ -3473,19 +3711,15 @@ static void P_NetUnArchiveThinkers(void)
break;
case tc_marioblock:
th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3);
th = LoadMarioBlockThinker((actionf_p1)T_MarioBlock);
break;
case tc_marioblockchecker:
th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0);
break;
case tc_spikesector:
th = LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0);
th = LoadMarioCheckThinker((actionf_p1)T_MarioBlockChecker);
break;
case tc_floatsector:
th = LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0);
th = LoadFloatThinker((actionf_p1)T_FloatSector);
break;
case tc_laserflash:

View File

@ -846,7 +846,7 @@ static void P_InitializeSector(sector_t *ss)
ss->camsec = -1;
ss->floorlightsec = ss->ceilinglightsec = -1;
ss->crumblestate = 0;
ss->crumblestate = CRUMBLE_NONE;
ss->touching_thinglist = NULL;

View File

@ -114,12 +114,11 @@ static void P_ResetColormapFader(sector_t *sector);
static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc,
boolean ticbased, INT32 duration);
static void P_AddBlockThinker(sector_t *sec, line_t *sourceline);
static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline);
static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline);
//static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec);
static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers);
static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer);
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee, UINT8 reverse);
@ -4450,7 +4449,8 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_ELECTRIC);
break;
case 5: // Spikes
// Don't do anything. In Soviet Russia, spikes find you.
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPIKE);
break;
case 6: // Death Pit (Camera Mod)
case 7: // Death Pit (No Camera Mod)
@ -5758,7 +5758,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
thinker_t *th;
friction_t *f;
pusher_t *p;
levelspecthink_t *lst;
size_t sec2num;
size_t i;
@ -5859,16 +5858,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
else if (th == &thlist[THINK_MAIN])
break;
// Should this FOF have spikeness?
if (th->function.acp1 == (actionf_p1)T_SpikeSector)
{
lst = (levelspecthink_t *)th;
if (lst->sector == sec2)
P_AddSpikeThinker(sec, (INT32)sec2num);
}
// Should this FOF have friction?
else if(th->function.acp1 == (actionf_p1)T_Friction)
if(th->function.acp1 == (actionf_p1)T_Friction)
{
f = (friction_t *)th;
@ -5915,7 +5906,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
}
if ((flags & FF_CRUMBLE))
sec2->crumblestate = 1;
sec2->crumblestate = CRUMBLE_WAIT;
if ((flags & FF_FLOATBOB))
{
@ -5932,28 +5923,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
// SPECIAL SPAWNING
//
/** Adds a spike thinker.
* Sector type Section1:5 will result in this effect.
*
* \param sec Sector in which to add the thinker.
* \param referrer If != sec, then we're dealing with a FOF
* \sa P_SpawnSpecials, T_SpikeSector
* \author SSNTails <http://www.ssntails.org>
*/
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer)
{
levelspecthink_t *spikes;
// create and initialize new thinker
spikes = Z_Calloc(sizeof (*spikes), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &spikes->thinker);
spikes->thinker.function.acp1 = (actionf_p1)T_SpikeSector;
spikes->sector = sec;
spikes->vars[0] = referrer;
}
/** Adds a float thinker.
* Float thinkers cause solid 3Dfloors to float on water.
*
@ -5962,9 +5931,9 @@ static void P_AddSpikeThinker(sector_t *sec, INT32 referrer)
* \sa P_SpawnSpecials, T_FloatSector
* \author SSNTails <http://www.ssntails.org>
*/
static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline)
{
levelspecthink_t *floater;
floatthink_t *floater;
// create and initialize new thinker
floater = Z_Calloc(sizeof (*floater), PU_LEVSPEC, NULL);
@ -5973,7 +5942,7 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
floater->thinker.function.acp1 = (actionf_p1)T_FloatSector;
floater->sector = sec;
floater->vars[0] = tag;
floater->tag = (INT16)tag;
floater->sourceline = sourceline;
}
@ -6018,7 +5987,7 @@ static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control,
*/
static void P_AddBlockThinker(sector_t *sec, line_t *sourceline)
{
levelspecthink_t *block;
mariocheck_t *block;
// create and initialize new elevator thinker
block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL);
@ -6044,85 +6013,52 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline)
* \sa P_SpawnSpecials, T_RaiseSector
* \author SSNTails <http://www.ssntails.org>
*/
static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline)
static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, boolean lower, boolean spindash)
{
levelspecthink_t *raise;
raise_t *raise;
raise = Z_Calloc(sizeof (*raise), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &raise->thinker);
raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector;
if (sourceline->flags & ML_BLOCKMONSTERS)
raise->vars[0] = 1;
else
raise->vars[0] = 0;
// set up the fields
raise->sourceline = sourceline;
raise->sector = sec;
// Require a spindash to activate
if (sourceline->flags & ML_NOCLIMB)
raise->vars[1] = 1;
else
raise->vars[1] = 0;
raise->ceilingtop = P_FindHighestCeilingSurrounding(sec);
raise->ceilingbottom = P_FindLowestCeilingSurrounding(sec);
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->basespeed = FixedDiv(P_AproxDistance(sourceline->dx, sourceline->dy), 4*FRACUNIT);
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;
if (lower)
raise->flags |= RF_REVERSE;
if (spindash)
raise->flags |= RF_SPINDASH;
}
static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic)
static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean raise, boolean spindash, boolean dynamic)
{
levelspecthink_t *airbob;
raise_t *airbob;
airbob = Z_Calloc(sizeof (*airbob), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &airbob->thinker);
airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector;
// set up the fields
airbob->sourceline = sourceline;
airbob->sector = sec;
// Require a spindash to activate
if (sourceline->flags & ML_NOCLIMB)
airbob->vars[1] = 1;
else
airbob->vars[1] = 0;
airbob->ceilingtop = sec->ceilingheight;
airbob->ceilingbottom = sec->ceilingheight - dist;
airbob->vars[2] = FRACUNIT;
airbob->basespeed = FRACUNIT;
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)
airbob->vars[0] = 1;
else
airbob->vars[0] = 0;
airbob->vars[5] = sec->ceilingheight;
airbob->vars[4] = airbob->vars[5]
- (sec->ceilingheight - sec->floorheight);
airbob->vars[9] = dynamic ? 1 : 0;
airbob->sourceline = sourceline;
if (!raise)
airbob->flags |= RF_REVERSE;
if (spindash)
airbob->flags |= RF_SPINDASH;
if (dynamic)
airbob->flags |= RF_DYNAMIC;
}
/** Adds a thwomp thinker.
@ -6136,12 +6072,7 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boo
*/
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.
@ -6155,34 +6086,33 @@ 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.
* If not, a linedef executor is run once.
*
* \param sec Control sector.
* \param sourceline Control linedef.
* \sa P_SpawnSpecials, T_NoEnemiesSector
* \author SSNTails <http://www.ssntails.org>
*/
static inline void P_AddNoEnemiesThinker(sector_t *sec, line_t *sourceline)
static inline void P_AddNoEnemiesThinker(line_t *sourceline)
{
levelspecthink_t *nobaddies;
noenemies_t *nobaddies;
// create and initialize new thinker
nobaddies = Z_Calloc(sizeof (*nobaddies), PU_LEVSPEC, NULL);
@ -6190,21 +6120,19 @@ static inline void P_AddNoEnemiesThinker(sector_t *sec, line_t *sourceline)
nobaddies->thinker.function.acp1 = (actionf_p1)T_NoEnemiesSector;
nobaddies->sector = sec;
nobaddies->sourceline = sourceline;
}
/** Adds a thinker for Each-Time linedef executors. A linedef executor is run
* only when a player enters the area and doesn't run again until they re-enter.
*
* \param sec Control sector that contains the lines of executors we will want to run.
* \param sourceline Control linedef.
* \sa P_SpawnSpecials, T_EachTimeThinker
* \author SSNTails <http://www.ssntails.org>
*/
static void P_AddEachTimeThinker(sector_t *sec, line_t *sourceline)
static void P_AddEachTimeThinker(line_t *sourceline)
{
levelspecthink_t *eachtime;
eachtime_t *eachtime;
// create and initialize new thinker
eachtime = Z_Calloc(sizeof (*eachtime), PU_LEVSPEC, NULL);
@ -6212,8 +6140,8 @@ static void P_AddEachTimeThinker(sector_t *sec, line_t *sourceline)
eachtime->thinker.function.acp1 = (actionf_p1)T_EachTimeThinker;
eachtime->sector = sec;
eachtime->sourceline = sourceline;
eachtime->triggerOnExit = !!(sourceline->flags & ML_BOUNCY);
}
/** Adds a camera scanner.
@ -6440,9 +6368,11 @@ void P_SpawnSpecials(boolean fromnetsave)
switch(GETSECSPECIAL(sector->special, 1))
{
case 5: // Spikes
P_AddSpikeThinker(sector, (INT32)(sector-sectors));
//Terrible hack to replace an even worse hack:
//Spike damage automatically sets SF_TRIGGERSPECIAL_TOUCH.
//Yes, this also affects other specials on the same sector. Sorry.
sector->flags |= SF_TRIGGERSPECIAL_TOUCH;
break;
case 15: // Bouncy sector
CheckForBouncySector = true;
break;
@ -6488,9 +6418,7 @@ void P_SpawnSpecials(boolean fromnetsave)
// Firstly, find out how many there are in each sector
for (th = thlist[THINK_MAIN].next; th != &thlist[THINK_MAIN]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)T_SpikeSector)
secthinkers[((levelspecthink_t *)th)->sector - sectors].count++;
else if (th->function.acp1 == (actionf_p1)T_Friction)
if (th->function.acp1 == (actionf_p1)T_Friction)
secthinkers[((friction_t *)th)->affectee].count++;
else if (th->function.acp1 == (actionf_p1)T_Pusher)
secthinkers[((pusher_t *)th)->affectee].count++;
@ -6510,9 +6438,7 @@ void P_SpawnSpecials(boolean fromnetsave)
{
size_t secnum = (size_t)-1;
if (th->function.acp1 == (actionf_p1)T_SpikeSector)
secnum = ((levelspecthink_t *)th)->sector - sectors;
else if (th->function.acp1 == (actionf_p1)T_Friction)
if (th->function.acp1 == (actionf_p1)T_Friction)
secnum = ((friction_t *)th)->affectee;
else if (th->function.acp1 == (actionf_p1)T_Pusher)
secnum = ((pusher_t *)th)->affectee;
@ -6925,18 +6851,20 @@ void P_SpawnSpecials(boolean fromnetsave)
case 150: // Air bobbing platform
case 151: // Adjustable air bobbing platform
{
fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : P_AproxDistance(lines[i].dx, lines[i].dy);
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
lines[i].flags |= ML_BLOCKMONSTERS;
P_AddAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151), false);
P_AddAirbob(lines[i].frontsector, lines + i, dist, false, !!(lines[i].flags & ML_NOCLIMB), false);
break;
}
case 152: // Adjustable air bobbing platform in reverse
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false);
break;
case 153: // Dynamic Sinking Platform
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
lines[i].flags |= ML_BLOCKMONSTERS;
P_AddAirbob(lines[i].frontsector, lines + i, false, true);
P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true);
break;
case 160: // Float/bob platform
@ -6986,15 +6914,13 @@ void P_SpawnSpecials(boolean fromnetsave)
case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers);
lines[i].flags |= ML_BLOCKMONSTERS;
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false);
break;
case 177: // Air bobbing platform that will crumble and bob on
// the water when it falls and hits, then never return
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers);
lines[i].flags |= ML_BLOCKMONSTERS;
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false);
break;
case 178: // Crumbling platform that will float when it hits water
@ -7007,28 +6933,27 @@ void P_SpawnSpecials(boolean fromnetsave)
case 180: // Air bobbing platform that will crumble
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers);
lines[i].flags |= ML_BLOCKMONSTERS;
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false);
break;
case 190: // Rising Platform FOF (solid, opaque, shadows)
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
break;
case 191: // Rising Platform FOF (solid, opaque, no shadows)
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_CUTLEVEL, secthinkers);
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
break;
case 192: // Rising Platform TL block: FOF (solid, translucent)
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA, secthinkers);
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
break;
case 193: // Rising Platform FOF (solid, invisible)
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_NOSHADE, secthinkers);
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
break;
case 194: // Rising Platform 'Platform' - You can jump up through it
@ -7038,7 +6963,7 @@ void P_SpawnSpecials(boolean fromnetsave)
ffloorflags |= FF_NOSHADE;
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
break;
case 195: // Rising Platform Translucent "platform"
@ -7048,7 +6973,7 @@ void P_SpawnSpecials(boolean fromnetsave)
ffloorflags |= FF_NOSHADE;
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
break;
case 200: // Double light effect
@ -7197,14 +7122,12 @@ void P_SpawnSpecials(boolean fromnetsave)
case 312:
case 332:
case 335:
sec = sides[*lines[i].sidenum].sector - sectors;
P_AddEachTimeThinker(&sectors[sec], &lines[i]);
P_AddEachTimeThinker(&lines[i]);
break;
// No More Enemies Linedef Exec
case 313:
sec = sides[*lines[i].sidenum].sector - sectors;
P_AddNoEnemiesThinker(&sectors[sec], &lines[i]);
P_AddNoEnemiesThinker(&lines[i]);
break;
// Pushable linedef executors (count # of pushables)
@ -7228,10 +7151,7 @@ void P_SpawnSpecials(boolean fromnetsave)
else
lines[i].callcount = sides[lines[i].sidenum[0]].textureoffset>>FRACBITS;
if (lines[i].special == 322) // Each time
{
sec = sides[*lines[i].sidenum].sector - sectors;
P_AddEachTimeThinker(&sectors[sec], &lines[i]);
}
P_AddEachTimeThinker(&lines[i]);
break;
// NiGHTS trigger executors

View File

@ -314,11 +314,101 @@ typedef struct
typedef struct
{
thinker_t thinker;
fixed_t vars[16]; // Misc. variables
fixed_t var2s[16]; // Second misc variables buffer.
line_t *sourceline; // Source line of the thinker
sector_t *sector; // Sector the thinker is from
} levelspecthink_t;
} noenemies_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
fixed_t speed;
INT32 direction;
fixed_t floorstartheight;
fixed_t ceilingstartheight;
fixed_t destheight;
} continuousfall_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
fixed_t speed;
fixed_t distance;
fixed_t floorwasheight;
fixed_t ceilingwasheight;
boolean low;
} bouncecheese_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
fixed_t speed;
INT32 direction;
fixed_t floorstartheight;
fixed_t ceilingstartheight;
INT16 tag;
} mariothink_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
} mariocheck_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;
line_t *sourceline;
sector_t *sector;
INT16 tag;
} floatthink_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline; // Source line of the thinker
boolean playersInArea[MAXPLAYERS];
boolean playersOnArea[MAXPLAYERS];
boolean triggerOnExit;
} eachtime_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 ceilingbottom;
fixed_t ceilingtop;
fixed_t basespeed;
fixed_t extraspeed; //For dynamically sinking platform
UINT8 shaketimer; //For dynamically sinking platform
UINT8 flags;
} raise_t;
#define ELEVATORSPEED (FRACUNIT*4)
#define FLOORSPEED (FRACUNIT)
@ -331,35 +421,34 @@ typedef enum
} result_e;
result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush,
INT32 floorOrCeiling, INT32 direction);
INT32 EV_DoFloor(line_t *line, floor_e floortype);
INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed);
boolean ceiling, INT32 direction);
void EV_DoFloor(line_t *line, floor_e floortype);
void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed);
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover);
INT32 EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
// Some other special 3dfloor types
INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover,
boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn);
INT32 EV_DoContinuousFall(sector_t *sec, sector_t *pbacksector, fixed_t spd, boolean backwards);
void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards);
INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
void T_MoveFloor(floormove_t *movefloor);
void T_MoveElevator(elevator_t *elevator);
void T_ContinuousFalling(levelspecthink_t *faller);
void T_BounceCheese(levelspecthink_t *bouncer);
void T_ContinuousFalling(continuousfall_t *faller);
void T_BounceCheese(bouncecheese_t *bouncer);
void T_StartCrumble(elevator_t *elevator);
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_NoEnemiesSector(levelspecthink_t *nobaddies);
void T_EachTimeThinker(levelspecthink_t *eachtime);
void T_MarioBlock(mariothink_t *block);
void T_FloatSector(floatthink_t *floater);
void T_MarioBlockChecker(mariocheck_t *block);
void T_ThwompSector(thwomp_t *thwomp);
void T_NoEnemiesSector(noenemies_t *nobaddies);
void T_EachTimeThinker(eachtime_t *eachtime);
void T_CameraScanner(elevator_t *elevator);
void T_RaiseSector(levelspecthink_t *sraise);
void T_RaiseSector(raise_t *raise);
typedef struct
{

View File

@ -2566,7 +2566,7 @@ static void P_CheckBustableBlocks(player_t *player)
{
if (!(rover->flags & FF_EXISTS)) continue;
if ((rover->flags & FF_BUSTUP)/* && !rover->master->frontsector->crumblestate*/)
if ((rover->flags & FF_BUSTUP)/* && rover->master->frontsector->crumblestate == CRUMBLE_NONE*/)
{
// If it's an FF_SHATTER, you can break it just by touching it.
if (rover->flags & FF_SHATTER)
@ -12213,7 +12213,7 @@ void P_PlayerThink(player_t *player)
player->powers[pw_nocontrol]--;
else
player->powers[pw_nocontrol] = 0;
//pw_super acts as a timer now
if (player->powers[pw_super]
&& (player->mo->state < &states[S_PLAY_SUPER_TRANS1]

View File

@ -277,6 +277,16 @@ typedef enum
SF_INVERTPRECIP = 1<<4,
} sectorflags_t;
typedef enum
{
CRUMBLE_NONE, // No crumble thinker
CRUMBLE_WAIT, // Don't float on water because this is supposed to wait for a crumble
CRUMBLE_ACTIVATED, // Crumble thinker activated, but hasn't fallen yet
CRUMBLE_FALL, // Crumble thinker is falling
CRUMBLE_RESTORE, // Crumble thinker is about to restore to original position
} crumblestate_t;
//
// The SECTORS record, at runtime.
// Stores things/mobjs.