mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- fixed use of multiple sector actions in the same sector.
The entire setup was quite broken with each item using its own activation result and the ones of the subsequent items in the list as the return value. This rendered the STANDSTILL check in the main function totally unpredictable because the value it depended on could come from any item in the list. Changed it so that the main dispatcher function is part of sector_t and does the stepping through the list iteratively instead of letting each item recursively call its successor and let this function decide for each item alone whether it should be removed. The broken setup also had the effect that any MusicChanger would trigger all following SecActEnter specials right on msp start.
This commit is contained in:
parent
cf39af0642
commit
1400f401e7
9 changed files with 67 additions and 40 deletions
|
@ -94,26 +94,9 @@ void ASectorAction::Deactivate (AActor *source)
|
|||
flags2 |= MF2_DORMANT; // Projectiles can trigger
|
||||
}
|
||||
|
||||
bool ASectorAction::TriggerAction(AActor *triggerer, int activationType)
|
||||
{
|
||||
if (DoTriggerAction(triggerer, activationType))
|
||||
{
|
||||
if (flags4 & MF4_STANDSTILL)
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ASectorAction::DoTriggerAction (AActor *triggerer, int activationType)
|
||||
{
|
||||
bool didit = (activationType & health) ? CheckTrigger(triggerer) : false;
|
||||
|
||||
if (tracer != NULL)
|
||||
return didit | barrier_cast<ASectorAction *>(tracer)->DoTriggerAction (triggerer, activationType);
|
||||
else
|
||||
return didit;
|
||||
return (activationType & health) ? CheckTrigger(triggerer) : false;
|
||||
}
|
||||
|
||||
bool ASectorAction::CanTrigger (AActor *triggerer) const
|
||||
|
|
|
@ -369,7 +369,7 @@ bool P_CheckFor3DFloorHit(AActor * mo, double z)
|
|||
{
|
||||
if (fabs(z - rover->top.plane->ZatPoint(mo)) < EQUAL_EPSILON)
|
||||
{
|
||||
rover->model->SecActTarget->TriggerAction (mo, SECSPAC_HitFloor);
|
||||
rover->model->TriggerSectorActions (mo, SECSPAC_HitFloor);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -395,7 +395,7 @@ bool P_CheckFor3DCeilingHit(AActor * mo, double z)
|
|||
{
|
||||
if(fabs(z - rover->bottom.plane->ZatPoint(mo)) < EQUAL_EPSILON)
|
||||
{
|
||||
rover->model->SecActTarget->TriggerAction (mo, SECSPAC_HitCeiling);
|
||||
rover->model->TriggerSectorActions (mo, SECSPAC_HitCeiling);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -713,7 +713,7 @@ bool P_Move (AActor *actor)
|
|||
if (actor->floorsector->SecActTarget != NULL &&
|
||||
actor->floorz == actor->floorsector->floorplane.ZatPoint(actor->PosRelative(actor->floorsector)))
|
||||
{
|
||||
actor->floorsector->SecActTarget->TriggerAction(actor, SECSPAC_HitFloor);
|
||||
actor->floorsector->TriggerSectorActions(actor, SECSPAC_HitFloor);
|
||||
}
|
||||
P_CheckFor3DFloorHit(actor, actor->Z());
|
||||
}
|
||||
|
|
|
@ -2616,11 +2616,11 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
|
|||
|
||||
if (!oldAboveFakeFloor && eyez > fakez)
|
||||
{ // View went above fake floor
|
||||
newsec->SecActTarget->TriggerAction(thing, SECSPAC_EyesSurface);
|
||||
newsec->TriggerSectorActions(thing, SECSPAC_EyesSurface);
|
||||
}
|
||||
else if (oldAboveFakeFloor && eyez <= fakez)
|
||||
{ // View went below fake floor
|
||||
newsec->SecActTarget->TriggerAction(thing, SECSPAC_EyesDive);
|
||||
newsec->TriggerSectorActions(thing, SECSPAC_EyesDive);
|
||||
}
|
||||
|
||||
if (!(hs->MoreFlags & SECF_FAKEFLOORONLY))
|
||||
|
@ -2628,11 +2628,11 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
|
|||
fakez = hs->ceilingplane.ZatPoint(pos);
|
||||
if (!oldAboveFakeCeiling && eyez > fakez)
|
||||
{ // View went above fake ceiling
|
||||
newsec->SecActTarget->TriggerAction(thing, SECSPAC_EyesAboveC);
|
||||
newsec->TriggerSectorActions(thing, SECSPAC_EyesAboveC);
|
||||
}
|
||||
else if (oldAboveFakeCeiling && eyez <= fakez)
|
||||
{ // View went below fake ceiling
|
||||
newsec->SecActTarget->TriggerAction(thing, SECSPAC_EyesBelowC);
|
||||
newsec->TriggerSectorActions(thing, SECSPAC_EyesBelowC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5304,7 +5304,7 @@ bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end,
|
|||
|
||||
sec = usething->Sector;
|
||||
|
||||
if (sec->SecActTarget && sec->SecActTarget->TriggerAction(usething, SECSPAC_Use))
|
||||
if (sec->SecActTarget && sec->TriggerSectorActions(usething, SECSPAC_Use))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -5313,7 +5313,7 @@ bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end,
|
|||
in->d.line->frontsector : in->d.line->backsector;
|
||||
|
||||
if (sec != NULL && sec->SecActTarget &&
|
||||
sec->SecActTarget->TriggerAction(usething, SECSPAC_UseWall))
|
||||
sec->TriggerSectorActions(usething, SECSPAC_UseWall))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -5434,7 +5434,7 @@ void P_UseLines(player_t *player)
|
|||
sector_t *sec = player->mo->Sector;
|
||||
int spac = SECSPAC_Use;
|
||||
if (foundline) spac |= SECSPAC_UseWall;
|
||||
if ((!sec->SecActTarget || !sec->SecActTarget->TriggerAction(player->mo, spac)) &&
|
||||
if ((!sec->SecActTarget || !sec->TriggerSectorActions(player->mo, spac)) &&
|
||||
P_NoWayTraverse(player->mo, start, end))
|
||||
{
|
||||
S_Sound(player->mo, CHAN_VOICE, "*usefail", 1, ATTN_IDLE);
|
||||
|
|
|
@ -2810,7 +2810,7 @@ void P_ZMovement (AActor *mo, double oldfloorz)
|
|||
mo->Sector->SecActTarget != NULL &&
|
||||
mo->Sector->floorplane.ZatPoint(mo) == mo->floorz)
|
||||
{ // [RH] Let the sector do something to the actor
|
||||
mo->Sector->SecActTarget->TriggerAction (mo, SECSPAC_HitFloor);
|
||||
mo->Sector->TriggerSectorActions (mo, SECSPAC_HitFloor);
|
||||
}
|
||||
P_CheckFor3DFloorHit(mo, mo->floorz);
|
||||
// [RH] Need to recheck this because the sector action might have
|
||||
|
@ -2913,7 +2913,7 @@ void P_ZMovement (AActor *mo, double oldfloorz)
|
|||
mo->Sector->SecActTarget != NULL &&
|
||||
mo->Sector->ceilingplane.ZatPoint(mo) == mo->ceilingz)
|
||||
{ // [RH] Let the sector do something to the actor
|
||||
mo->Sector->SecActTarget->TriggerAction (mo, SECSPAC_HitCeiling);
|
||||
mo->Sector->TriggerSectorActions (mo, SECSPAC_HitCeiling);
|
||||
}
|
||||
P_CheckFor3DCeilingHit(mo, mo->ceilingz);
|
||||
// [RH] Need to recheck this because the sector action might have
|
||||
|
@ -2981,7 +2981,7 @@ void P_CheckFakeFloorTriggers (AActor *mo, double oldz, bool oldz_has_viewheight
|
|||
|
||||
if (oldz > waterz && mo->Z() <= waterz)
|
||||
{ // Feet hit fake floor
|
||||
sec->SecActTarget->TriggerAction (mo, SECSPAC_HitFakeFloor);
|
||||
sec->TriggerSectorActions (mo, SECSPAC_HitFakeFloor);
|
||||
}
|
||||
|
||||
newz = mo->Z() + viewheight;
|
||||
|
@ -2992,11 +2992,11 @@ void P_CheckFakeFloorTriggers (AActor *mo, double oldz, bool oldz_has_viewheight
|
|||
|
||||
if (oldz <= waterz && newz > waterz)
|
||||
{ // View went above fake floor
|
||||
sec->SecActTarget->TriggerAction (mo, SECSPAC_EyesSurface);
|
||||
sec->TriggerSectorActions (mo, SECSPAC_EyesSurface);
|
||||
}
|
||||
else if (oldz > waterz && newz <= waterz)
|
||||
{ // View went below fake floor
|
||||
sec->SecActTarget->TriggerAction (mo, SECSPAC_EyesDive);
|
||||
sec->TriggerSectorActions (mo, SECSPAC_EyesDive);
|
||||
}
|
||||
|
||||
if (!(hs->MoreFlags & SECF_FAKEFLOORONLY))
|
||||
|
@ -3004,11 +3004,11 @@ void P_CheckFakeFloorTriggers (AActor *mo, double oldz, bool oldz_has_viewheight
|
|||
waterz = hs->ceilingplane.ZatPoint(mo);
|
||||
if (oldz <= waterz && newz > waterz)
|
||||
{ // View went above fake ceiling
|
||||
sec->SecActTarget->TriggerAction (mo, SECSPAC_EyesAboveC);
|
||||
sec->TriggerSectorActions (mo, SECSPAC_EyesAboveC);
|
||||
}
|
||||
else if (oldz > waterz && newz <= waterz)
|
||||
{ // View went below fake ceiling
|
||||
sec->SecActTarget->TriggerAction (mo, SECSPAC_EyesBelowC);
|
||||
sec->TriggerSectorActions (mo, SECSPAC_EyesBelowC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4353,7 +4353,7 @@ void AActor::CheckSectorTransition(sector_t *oldsec)
|
|||
{
|
||||
if (oldsec->SecActTarget != NULL)
|
||||
{
|
||||
oldsec->SecActTarget->TriggerAction(this, SECSPAC_Exit);
|
||||
oldsec->TriggerSectorActions(this, SECSPAC_Exit);
|
||||
}
|
||||
if (Sector->SecActTarget != NULL)
|
||||
{
|
||||
|
@ -4370,7 +4370,7 @@ void AActor::CheckSectorTransition(sector_t *oldsec)
|
|||
{
|
||||
act |= SECSPAC_HitFakeFloor;
|
||||
}
|
||||
Sector->SecActTarget->TriggerAction(this, act);
|
||||
Sector->TriggerSectorActions(this, act);
|
||||
}
|
||||
if (Z() == floorz)
|
||||
{
|
||||
|
|
|
@ -1446,6 +1446,49 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt)
|
|||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool sector_t::TriggerSectorActions(AActor *thing, int activation)
|
||||
{
|
||||
auto act = SecActTarget;
|
||||
bool res = false;
|
||||
|
||||
while (act != nullptr)
|
||||
{
|
||||
AActor *next = act->tracer;
|
||||
|
||||
bool didit = act->DoTriggerAction(thing, activation);
|
||||
if (didit)
|
||||
{
|
||||
if (act->flags4 & MF4_STANDSTILL)
|
||||
{
|
||||
act->Destroy();
|
||||
}
|
||||
}
|
||||
act = static_cast<ASectorAction*>(next);
|
||||
res |= didit;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Sector, TriggerSectorActions)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
|
||||
PARAM_OBJECT(thing, AActor);
|
||||
PARAM_INT(activation);
|
||||
ACTION_RETURN_BOOL(self->TriggerSectorActions(thing, activation));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Sector, PointInSector)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
|
|
|
@ -287,7 +287,6 @@ public:
|
|||
void BeginPlay ();
|
||||
void Activate (AActor *source);
|
||||
void Deactivate (AActor *source);
|
||||
bool TriggerAction(AActor *triggerer, int activationType);
|
||||
bool CanTrigger (AActor *triggerer) const;
|
||||
bool IsActivatedByUse() const;
|
||||
virtual bool DoTriggerAction(AActor *triggerer, int activationType);
|
||||
|
@ -674,6 +673,7 @@ public:
|
|||
int GetCeilingLight () const;
|
||||
sector_t *GetHeightSec() const;
|
||||
double GetFriction(int plane = sector_t::floor, double *movefac = NULL) const;
|
||||
bool TriggerSectorActions(AActor *thing, int activation);
|
||||
|
||||
DInterpolation *SetInterpolation(int position, bool attach);
|
||||
|
||||
|
|
|
@ -2483,7 +2483,7 @@ bool AMusicChanger::DoTriggerAction (AActor *triggerer, int activationType)
|
|||
triggerer->player->MUSINFOtics = 30;
|
||||
}
|
||||
}
|
||||
return tracer == nullptr? false : barrier_cast<ASectorAction *>(tracer)->DoTriggerAction(triggerer, activationType);
|
||||
return false;
|
||||
}
|
||||
|
||||
void AMusicChanger::PostBeginPlay()
|
||||
|
@ -2495,7 +2495,7 @@ void AMusicChanger::PostBeginPlay()
|
|||
{
|
||||
if (playeringame[i] && players[i].mo && players[i].mo->Sector == this->Sector)
|
||||
{
|
||||
TriggerAction(players[i].mo, SECSPAC_Enter);
|
||||
DoTriggerAction(players[i].mo, SECSPAC_Enter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -508,6 +508,7 @@ struct Sector native
|
|||
native int GetOppositePortalGroup(int plane);
|
||||
native double CenterFloor();
|
||||
native double CenterCeiling();
|
||||
native bool TriggerSectorActions(Actor thing, int activation);
|
||||
|
||||
native int MoveFloor(double speed, double dest, int crush, int direction, bool hexencrush, bool instant = false);
|
||||
native int MoveCeiling(double speed, double dest, int crush, int direction, bool hexencrush);
|
||||
|
|
Loading…
Reference in a new issue