mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-15 16:51:31 +00:00
Show sector action boundaries on the automap like line specials are.
This commit is contained in:
parent
890233d5fe
commit
2f027504b6
3 changed files with 148 additions and 34 deletions
154
src/am_map.cpp
154
src/am_map.cpp
|
@ -2224,6 +2224,124 @@ bool AM_Check3DFloors(line_t *line)
|
|||
return false;
|
||||
}
|
||||
|
||||
// [TP] Check whether a sector can trigger a special that satisfies the provided function.
|
||||
// If found, specialptr and argsptr will be filled by the special and the arguments
|
||||
// If needUseActivated is true, the special must be activated by use.
|
||||
bool AM_checkSectorActions (sector_t *sector, bool (*function)(int, int *), int *specialptr, int **argsptr, bool needUseActivated)
|
||||
{
|
||||
for (ASectorAction* action = sector->SecActTarget; action; action = barrier_cast<ASectorAction *>(action->tracer))
|
||||
{
|
||||
if ((action->IsActivatedByUse() || false == needUseActivated)
|
||||
&& (*function)(action->special, action->args)
|
||||
&& action->CanTrigger (players[consoleplayer].mo))
|
||||
{
|
||||
*specialptr = action->special;
|
||||
*argsptr = action->args;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// [TP] Check whether there's a boundary on the provided line for a special that satisfies the provided function.
|
||||
// It's a boundary if the line can activate the special or the line's bordering sectors can activate it.
|
||||
// If found, specialptr and argsptr will be filled with special and args if given.
|
||||
bool AM_checkSpecialBoundary (line_t &line, bool (*function)(int, int*), int *specialptr = NULL, int **argsptr = NULL)
|
||||
{
|
||||
if (specialptr == NULL)
|
||||
{
|
||||
static int sink;
|
||||
specialptr = &sink;
|
||||
}
|
||||
|
||||
if (argsptr == NULL)
|
||||
{
|
||||
static int* sink;
|
||||
argsptr = &sink;
|
||||
}
|
||||
|
||||
// Check if the line special qualifies for this
|
||||
if ((*function)(line.special, line.args) && (line.activation & SPAC_PlayerActivate))
|
||||
{
|
||||
*specialptr = line.special;
|
||||
*argsptr = line.args;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check sector actions in the line's front sector -- the action has to be use-activated in order to
|
||||
// show up if this is a one-sided line, because the player cannot trigger sector actions by crossing
|
||||
// a one-sided line (since that's impossible, duh).
|
||||
if (AM_checkSectorActions(line.frontsector, function, specialptr, argsptr, line.backsector == NULL))
|
||||
return true;
|
||||
|
||||
// If it has a back sector, check sector actions in that.
|
||||
return (line.backsector && AM_checkSectorActions(line.backsector, function, specialptr, argsptr, false));
|
||||
}
|
||||
|
||||
bool AM_isTeleportSpecial (int special, int*)
|
||||
{
|
||||
return (special == Teleport ||
|
||||
special == Teleport_NoFog ||
|
||||
special == Teleport_ZombieChanger ||
|
||||
special == Teleport_Line);
|
||||
}
|
||||
|
||||
bool AM_isTeleportBoundary (line_t& line)
|
||||
{
|
||||
return AM_checkSpecialBoundary(line, &AM_isTeleportSpecial);
|
||||
}
|
||||
|
||||
bool AM_isExitSpecial (int special, int*)
|
||||
{
|
||||
return (special == Teleport_NewMap ||
|
||||
special == Teleport_EndGame ||
|
||||
special == Exit_Normal ||
|
||||
special == Exit_Secret);
|
||||
}
|
||||
|
||||
bool AM_isExitBoundary (line_t& line)
|
||||
{
|
||||
return AM_checkSpecialBoundary(line, &AM_isExitSpecial);
|
||||
}
|
||||
|
||||
bool AM_isTriggerSpecial (int special, int*)
|
||||
{
|
||||
return special != 0
|
||||
&& special != Door_Open
|
||||
&& special != Door_Close
|
||||
&& special != Door_CloseWaitOpen
|
||||
&& special != Door_Raise
|
||||
&& special != Door_Animated
|
||||
&& special != Generic_Door;
|
||||
}
|
||||
|
||||
bool AM_isTriggerBoundary (line_t& line)
|
||||
{
|
||||
return AM_checkSpecialBoundary(line, &AM_isTriggerSpecial);
|
||||
}
|
||||
|
||||
bool AM_isLockSpecial (int special, int* args)
|
||||
{
|
||||
return special == Door_LockedRaise ||
|
||||
special == ACS_LockedExecute ||
|
||||
special == ACS_LockedExecuteDoor ||
|
||||
(special == Door_Animated && args[3] != 0) ||
|
||||
(special == Generic_Door && args[4] != 0);
|
||||
}
|
||||
|
||||
bool AM_isLockBoundary (line_t &line, int *lockptr = NULL)
|
||||
{
|
||||
int special;
|
||||
int *args;
|
||||
bool result = AM_checkSpecialBoundary(line, &AM_isLockSpecial, &special, &args);
|
||||
|
||||
if (lockptr && result)
|
||||
*lockptr = (special==Door_LockedRaise || special==Door_Animated) ? args[3] : args[4];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Determines visible lines, draws them.
|
||||
|
@ -2283,37 +2401,18 @@ void AM_drawWalls (bool allmap)
|
|||
|
||||
AM_drawMline (&l, c);
|
||||
}
|
||||
else if ((lines[i].special == Teleport ||
|
||||
lines[i].special == Teleport_NoFog ||
|
||||
lines[i].special == Teleport_ZombieChanger ||
|
||||
lines[i].special == Teleport_Line) &&
|
||||
(lines[i].activation & SPAC_PlayerActivate) &&
|
||||
AMColors.isValid(AMColors.IntraTeleportColor))
|
||||
else if (AM_isTeleportBoundary(lines[i]) && AMColors.isValid(AMColors.IntraTeleportColor))
|
||||
{ // intra-level teleporters
|
||||
AM_drawMline(&l, AMColors.IntraTeleportColor);
|
||||
}
|
||||
else if ((lines[i].special == Teleport_NewMap ||
|
||||
lines[i].special == Teleport_EndGame ||
|
||||
lines[i].special == Exit_Normal ||
|
||||
lines[i].special == Exit_Secret) &&
|
||||
AMColors.isValid(AMColors.InterTeleportColor))
|
||||
else if (AM_isExitBoundary(lines[i]) && AMColors.isValid(AMColors.InterTeleportColor))
|
||||
{ // inter-level/game-ending teleporters
|
||||
AM_drawMline(&l, AMColors.InterTeleportColor);
|
||||
}
|
||||
else if (lines[i].special == Door_LockedRaise ||
|
||||
lines[i].special == ACS_LockedExecute ||
|
||||
lines[i].special == ACS_LockedExecuteDoor ||
|
||||
(lines[i].special == Door_Animated && lines[i].args[3] != 0) ||
|
||||
(lines[i].special == Generic_Door && lines[i].args[4] != 0))
|
||||
else if (AM_isLockBoundary(lines[i], &lock))
|
||||
{
|
||||
if (AMColors.displayLocks)
|
||||
{
|
||||
int P_GetMapColorForLock(int lock);
|
||||
|
||||
if (lines[i].special==Door_LockedRaise || lines[i].special==Door_Animated)
|
||||
lock=lines[i].args[3];
|
||||
else lock=lines[i].args[4];
|
||||
|
||||
color = P_GetMapColorForLock(lock);
|
||||
|
||||
AMColor c;
|
||||
|
@ -2328,14 +2427,9 @@ void AM_drawWalls (bool allmap)
|
|||
AM_drawMline (&l, AMColors.LockedColor); // locked special
|
||||
}
|
||||
}
|
||||
else if (am_showtriggerlines && AMColors.isValid(AMColors.SpecialWallColor) && lines[i].special != 0
|
||||
&& lines[i].special != Door_Open
|
||||
&& lines[i].special != Door_Close
|
||||
&& lines[i].special != Door_CloseWaitOpen
|
||||
&& lines[i].special != Door_Raise
|
||||
&& lines[i].special != Door_Animated
|
||||
&& lines[i].special != Generic_Door
|
||||
&& (lines[i].activation & SPAC_PlayerActivate))
|
||||
else if (am_showtriggerlines
|
||||
&& AMColors.isValid(AMColors.SpecialWallColor)
|
||||
&& AM_isTriggerBoundary(lines[i]))
|
||||
{
|
||||
AM_drawMline(&l, AMColors.SpecialWallColor); // wall with special non-door action the player can do
|
||||
}
|
||||
|
|
|
@ -39,6 +39,14 @@
|
|||
|
||||
IMPLEMENT_CLASS (ASectorAction)
|
||||
|
||||
ASectorAction::ASectorAction (bool activatedByUse) :
|
||||
ActivatedByUse (activatedByUse) {}
|
||||
|
||||
bool ASectorAction::IsActivatedByUse() const
|
||||
{
|
||||
return ActivatedByUse;
|
||||
}
|
||||
|
||||
void ASectorAction::Destroy ()
|
||||
{
|
||||
// Remove ourself from this sector's list of actions
|
||||
|
@ -102,12 +110,17 @@ bool ASectorAction::DoTriggerAction (AActor *triggerer, int activationType)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ASectorAction::CheckTrigger (AActor *triggerer) const
|
||||
bool ASectorAction::CanTrigger (AActor *triggerer) const
|
||||
{
|
||||
if (special &&
|
||||
return special &&
|
||||
((triggerer->player && !(flags & MF_FRIENDLY)) ||
|
||||
((flags & MF_AMBUSH) && (triggerer->flags2 & MF2_MCROSS)) ||
|
||||
((flags2 & MF2_DORMANT) && (triggerer->flags2 & MF2_PCROSS))))
|
||||
((flags2 & MF2_DORMANT) && (triggerer->flags2 & MF2_PCROSS)));
|
||||
}
|
||||
|
||||
bool ASectorAction::CheckTrigger (AActor *triggerer) const
|
||||
{
|
||||
if (CanTrigger(triggerer))
|
||||
{
|
||||
bool res = !!P_ExecuteSpecial(special, NULL, triggerer, false, args[0], args[1],
|
||||
args[2], args[3], args[4]);
|
||||
|
@ -196,6 +209,7 @@ class ASecActUse : public ASectorAction
|
|||
{
|
||||
DECLARE_CLASS (ASecActUse, ASectorAction)
|
||||
public:
|
||||
ASecActUse() : ASectorAction (true) {}
|
||||
bool DoTriggerAction (AActor *triggerer, int activationType);
|
||||
};
|
||||
|
||||
|
@ -214,6 +228,7 @@ class ASecActUseWall : public ASectorAction
|
|||
{
|
||||
DECLARE_CLASS (ASecActUseWall, ASectorAction)
|
||||
public:
|
||||
ASecActUseWall() : ASectorAction (true) {}
|
||||
bool DoTriggerAction (AActor *triggerer, int activationType);
|
||||
};
|
||||
|
||||
|
|
|
@ -194,14 +194,19 @@ class ASectorAction : public AActor
|
|||
{
|
||||
DECLARE_CLASS (ASectorAction, AActor)
|
||||
public:
|
||||
ASectorAction (bool activatedByUse = false);
|
||||
void Destroy ();
|
||||
void BeginPlay ();
|
||||
void Activate (AActor *source);
|
||||
void Deactivate (AActor *source);
|
||||
bool TriggerAction(AActor *triggerer, int activationType);
|
||||
bool CanTrigger (AActor *triggerer) const;
|
||||
bool IsActivatedByUse() const;
|
||||
protected:
|
||||
virtual bool DoTriggerAction(AActor *triggerer, int activationType);
|
||||
bool CheckTrigger(AActor *triggerer) const;
|
||||
private:
|
||||
bool ActivatedByUse;
|
||||
};
|
||||
|
||||
class ASkyViewpoint;
|
||||
|
|
Loading…
Reference in a new issue