This commit is contained in:
Christoph Oelckers 2016-01-03 11:32:39 +01:00
commit 772a572431
4 changed files with 181 additions and 50 deletions

View file

@ -2224,6 +2224,154 @@ 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 ((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.
@ -2271,49 +2419,19 @@ void AM_drawWalls (bool allmap)
AM_drawMline(&l, AMColors.SecretWallColor);
else
AM_drawMline(&l, AMColors.WallColor);
}
else if (lines[i].locknumber > 0 && AMColors.displayLocks)
{ // [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))
}
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,16 +2446,9 @@ void AM_drawWalls (bool allmap)
AM_drawMline (&l, AMColors.LockedColor); // locked special
}
}
else if (am_showtriggerlines && AMColors.isValid(AMColors.SpecialWallColor)
&& LineSpecialsInfo[lines[i].special] != NULL
&& LineSpecialsInfo[lines[i].special]->max_args >= 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
}

View file

@ -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::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
{
if (special &&
((triggerer->player && !(flags & MF_FRIENDLY)) ||
((flags & MF_AMBUSH) && (triggerer->flags2 & MF2_MCROSS)) ||
((flags2 & MF2_DORMANT) && (triggerer->flags2 & MF2_PCROSS))))
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);
};

View file

@ -83,8 +83,8 @@ static FRandom pr_gunshot ("GunShot");
static const FGenericButtons ButtonChecks[] =
{
{ WRF_AllowReload, WF_WEAPONZOOMOK, BT_ZOOM, NAME_Zoom },
{ WRF_AllowZoom, WF_WEAPONRELOADOK, BT_RELOAD, NAME_Reload },
{ WRF_AllowZoom, WF_WEAPONZOOMOK, BT_ZOOM, NAME_Zoom },
{ WRF_AllowReload, WF_WEAPONRELOADOK, BT_RELOAD, NAME_Reload },
{ WRF_AllowUser1, WF_USER1OK, BT_USER1, NAME_User1 },
{ WRF_AllowUser2, WF_USER2OK, BT_USER2, NAME_User2 },
{ WRF_AllowUser3, WF_USER3OK, BT_USER3, NAME_User3 },

View file

@ -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;