mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-25 05:11:04 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
bb355b3a78
3 changed files with 179 additions and 48 deletions
199
src/am_map.cpp
199
src/am_map.cpp
|
@ -2224,6 +2224,154 @@ bool AM_Check3DFloors(line_t *line)
|
||||||
return false;
|
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 ((line.activation & SPAC_PlayerActivate) && (*function)(line.special, line.args))
|
||||||
|
{
|
||||||
|
*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 LineSpecialsInfo[special] != NULL
|
||||||
|
&& LineSpecialsInfo[special]->max_args >= 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)
|
||||||
|
|| (special == FS_Execute && args[2] != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AM_isLockBoundary (line_t &line, int *lockptr = NULL)
|
||||||
|
{
|
||||||
|
if (lockptr == NULL)
|
||||||
|
{
|
||||||
|
static int sink;
|
||||||
|
lockptr = &sink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.locknumber)
|
||||||
|
{
|
||||||
|
*lockptr = line.locknumber;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int special;
|
||||||
|
int *args;
|
||||||
|
bool result = AM_checkSpecialBoundary(line, &AM_isLockSpecial, &special, &args);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
switch (special)
|
||||||
|
{
|
||||||
|
case FS_Execute:
|
||||||
|
*lockptr = args[2];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Door_Animated:
|
||||||
|
case Door_LockedRaise:
|
||||||
|
*lockptr = args[3];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
*lockptr = args[4];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//
|
//
|
||||||
// Determines visible lines, draws them.
|
// Determines visible lines, draws them.
|
||||||
|
@ -2271,49 +2419,19 @@ void AM_drawWalls (bool allmap)
|
||||||
AM_drawMline(&l, AMColors.SecretWallColor);
|
AM_drawMline(&l, AMColors.SecretWallColor);
|
||||||
else
|
else
|
||||||
AM_drawMline(&l, AMColors.WallColor);
|
AM_drawMline(&l, AMColors.WallColor);
|
||||||
}
|
}
|
||||||
else if (lines[i].locknumber > 0 && AMColors.displayLocks)
|
else if (AM_isTeleportBoundary(lines[i]) && AMColors.isValid(AMColors.IntraTeleportColor))
|
||||||
{ // [Dusk] specials w/ locknumbers
|
|
||||||
lock = lines[i].locknumber;
|
|
||||||
color = P_GetMapColorForLock(lock);
|
|
||||||
|
|
||||||
AMColor c;
|
|
||||||
if (color >= 0) c.FromRGB(RPART(color), GPART(color), BPART(color));
|
|
||||||
else c = AMColors[AMColors.LockedColor];
|
|
||||||
|
|
||||||
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))
|
|
||||||
{ // intra-level teleporters
|
{ // intra-level teleporters
|
||||||
AM_drawMline(&l, AMColors.IntraTeleportColor);
|
AM_drawMline(&l, AMColors.IntraTeleportColor);
|
||||||
}
|
}
|
||||||
else if ((lines[i].special == Teleport_NewMap ||
|
else if (AM_isExitBoundary(lines[i]) && AMColors.isValid(AMColors.InterTeleportColor))
|
||||||
lines[i].special == Teleport_EndGame ||
|
|
||||||
lines[i].special == Exit_Normal ||
|
|
||||||
lines[i].special == Exit_Secret) &&
|
|
||||||
AMColors.isValid(AMColors.InterTeleportColor))
|
|
||||||
{ // inter-level/game-ending teleporters
|
{ // inter-level/game-ending teleporters
|
||||||
AM_drawMline(&l, AMColors.InterTeleportColor);
|
AM_drawMline(&l, AMColors.InterTeleportColor);
|
||||||
}
|
}
|
||||||
else if (lines[i].special == Door_LockedRaise ||
|
else if (AM_isLockBoundary(lines[i], &lock))
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
if (AMColors.displayLocks)
|
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);
|
color = P_GetMapColorForLock(lock);
|
||||||
|
|
||||||
AMColor c;
|
AMColor c;
|
||||||
|
@ -2328,16 +2446,9 @@ void AM_drawWalls (bool allmap)
|
||||||
AM_drawMline (&l, AMColors.LockedColor); // locked special
|
AM_drawMline (&l, AMColors.LockedColor); // locked special
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (am_showtriggerlines && AMColors.isValid(AMColors.SpecialWallColor)
|
else if (am_showtriggerlines
|
||||||
&& LineSpecialsInfo[lines[i].special] != NULL
|
&& AMColors.isValid(AMColors.SpecialWallColor)
|
||||||
&& LineSpecialsInfo[lines[i].special]->max_args >= 0
|
&& AM_isTriggerBoundary(lines[i]))
|
||||||
&& 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))
|
|
||||||
{
|
{
|
||||||
AM_drawMline(&l, AMColors.SpecialWallColor); // wall with special non-door action the player can do
|
AM_drawMline(&l, AMColors.SpecialWallColor); // wall with special non-door action the player can do
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,14 @@
|
||||||
|
|
||||||
IMPLEMENT_CLASS (ASectorAction)
|
IMPLEMENT_CLASS (ASectorAction)
|
||||||
|
|
||||||
|
ASectorAction::ASectorAction (bool activatedByUse) :
|
||||||
|
ActivatedByUse (activatedByUse) {}
|
||||||
|
|
||||||
|
bool ASectorAction::IsActivatedByUse() const
|
||||||
|
{
|
||||||
|
return ActivatedByUse;
|
||||||
|
}
|
||||||
|
|
||||||
void ASectorAction::Destroy ()
|
void ASectorAction::Destroy ()
|
||||||
{
|
{
|
||||||
// Remove ourself from this sector's list of actions
|
// Remove ourself from this sector's list of actions
|
||||||
|
@ -102,12 +110,17 @@ bool ASectorAction::DoTriggerAction (AActor *triggerer, int activationType)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ASectorAction::CanTrigger (AActor *triggerer) const
|
||||||
|
{
|
||||||
|
return special &&
|
||||||
|
((triggerer->player && !(flags & MF_FRIENDLY)) ||
|
||||||
|
((flags & MF_AMBUSH) && (triggerer->flags2 & MF2_MCROSS)) ||
|
||||||
|
((flags2 & MF2_DORMANT) && (triggerer->flags2 & MF2_PCROSS)));
|
||||||
|
}
|
||||||
|
|
||||||
bool ASectorAction::CheckTrigger (AActor *triggerer) const
|
bool ASectorAction::CheckTrigger (AActor *triggerer) const
|
||||||
{
|
{
|
||||||
if (special &&
|
if (CanTrigger(triggerer))
|
||||||
((triggerer->player && !(flags & MF_FRIENDLY)) ||
|
|
||||||
((flags & MF_AMBUSH) && (triggerer->flags2 & MF2_MCROSS)) ||
|
|
||||||
((flags2 & MF2_DORMANT) && (triggerer->flags2 & MF2_PCROSS))))
|
|
||||||
{
|
{
|
||||||
bool res = !!P_ExecuteSpecial(special, NULL, triggerer, false, args[0], args[1],
|
bool res = !!P_ExecuteSpecial(special, NULL, triggerer, false, args[0], args[1],
|
||||||
args[2], args[3], args[4]);
|
args[2], args[3], args[4]);
|
||||||
|
@ -196,6 +209,7 @@ class ASecActUse : public ASectorAction
|
||||||
{
|
{
|
||||||
DECLARE_CLASS (ASecActUse, ASectorAction)
|
DECLARE_CLASS (ASecActUse, ASectorAction)
|
||||||
public:
|
public:
|
||||||
|
ASecActUse() : ASectorAction (true) {}
|
||||||
bool DoTriggerAction (AActor *triggerer, int activationType);
|
bool DoTriggerAction (AActor *triggerer, int activationType);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -214,6 +228,7 @@ class ASecActUseWall : public ASectorAction
|
||||||
{
|
{
|
||||||
DECLARE_CLASS (ASecActUseWall, ASectorAction)
|
DECLARE_CLASS (ASecActUseWall, ASectorAction)
|
||||||
public:
|
public:
|
||||||
|
ASecActUseWall() : ASectorAction (true) {}
|
||||||
bool DoTriggerAction (AActor *triggerer, int activationType);
|
bool DoTriggerAction (AActor *triggerer, int activationType);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -225,14 +225,19 @@ class ASectorAction : public AActor
|
||||||
{
|
{
|
||||||
DECLARE_CLASS (ASectorAction, AActor)
|
DECLARE_CLASS (ASectorAction, AActor)
|
||||||
public:
|
public:
|
||||||
|
ASectorAction (bool activatedByUse = false);
|
||||||
void Destroy ();
|
void Destroy ();
|
||||||
void BeginPlay ();
|
void BeginPlay ();
|
||||||
void Activate (AActor *source);
|
void Activate (AActor *source);
|
||||||
void Deactivate (AActor *source);
|
void Deactivate (AActor *source);
|
||||||
bool TriggerAction(AActor *triggerer, int activationType);
|
bool TriggerAction(AActor *triggerer, int activationType);
|
||||||
|
bool CanTrigger (AActor *triggerer) const;
|
||||||
|
bool IsActivatedByUse() const;
|
||||||
protected:
|
protected:
|
||||||
virtual bool DoTriggerAction(AActor *triggerer, int activationType);
|
virtual bool DoTriggerAction(AActor *triggerer, int activationType);
|
||||||
bool CheckTrigger(AActor *triggerer) const;
|
bool CheckTrigger(AActor *triggerer) const;
|
||||||
|
private:
|
||||||
|
bool ActivatedByUse;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ASkyViewpoint;
|
class ASkyViewpoint;
|
||||||
|
|
Loading…
Reference in a new issue