From 2f027504b6716f35739038eb3073fedc9c1a86d1 Mon Sep 17 00:00:00 2001 From: Teemu Piippo Date: Sat, 12 Sep 2015 04:47:49 +0300 Subject: [PATCH 1/3] Show sector action boundaries on the automap like line specials are. --- src/am_map.cpp | 154 +++++++++++++++++++++++++------- src/g_shared/a_sectoraction.cpp | 23 ++++- src/r_defs.h | 5 ++ 3 files changed, 148 insertions(+), 34 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 045d485890..3430d3182d 100644 --- a/src/am_map.cpp +++ b/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(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 } diff --git a/src/g_shared/a_sectoraction.cpp b/src/g_shared/a_sectoraction.cpp index 570818e194..bb582dd284 100644 --- a/src/g_shared/a_sectoraction.cpp +++ b/src/g_shared/a_sectoraction.cpp @@ -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); }; diff --git a/src/r_defs.h b/src/r_defs.h index afda92089d..ff69577835 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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; From 67a7f48ca3cdd8c6e83a58c27dba6fd3f31fbbac Mon Sep 17 00:00:00 2001 From: Teemu Piippo Date: Sat, 12 Sep 2015 14:02:07 +0300 Subject: [PATCH 2/3] Handle locknumber in boundary checks, check for FS_Execute --- src/am_map.cpp | 56 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 3430d3182d..279deb8a45 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2323,21 +2323,50 @@ bool AM_isTriggerBoundary (line_t& line) 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); + 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 (lockptr && result) - *lockptr = (special==Door_LockedRaise || special==Door_Animated) ? args[3] : args[4]; + 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; } @@ -2389,18 +2418,7 @@ 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 (AM_isTeleportBoundary(lines[i]) && AMColors.isValid(AMColors.IntraTeleportColor)) { // intra-level teleporters AM_drawMline(&l, AMColors.IntraTeleportColor); From 69fd0e6eb484fddd4a55333b4fa74377c6e0e992 Mon Sep 17 00:00:00 2001 From: Teemu Piippo Date: Sat, 12 Sep 2015 14:07:40 +0300 Subject: [PATCH 3/3] Stylistical coherence.. --- src/am_map.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 279deb8a45..16fd671115 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2247,7 +2247,7 @@ bool AM_checkSectorActions (sector_t *sector, bool (*function)(int, int *), int // [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) +bool AM_checkSpecialBoundary (line_t &line, bool (*function)(int, int *), int *specialptr = NULL, int **argsptr = NULL) { if (specialptr == NULL) { @@ -2257,7 +2257,7 @@ bool AM_checkSpecialBoundary (line_t &line, bool (*function)(int, int*), int *sp if (argsptr == NULL) { - static int* sink; + static int *sink; argsptr = &sink; } @@ -2279,7 +2279,7 @@ bool AM_checkSpecialBoundary (line_t &line, bool (*function)(int, int*), int *sp return (line.backsector && AM_checkSectorActions(line.backsector, function, specialptr, argsptr, false)); } -bool AM_isTeleportSpecial (int special, int*) +bool AM_isTeleportSpecial (int special, int *) { return (special == Teleport || special == Teleport_NoFog || @@ -2287,12 +2287,12 @@ bool AM_isTeleportSpecial (int special, int*) special == Teleport_Line); } -bool AM_isTeleportBoundary (line_t& line) +bool AM_isTeleportBoundary (line_t &line) { return AM_checkSpecialBoundary(line, &AM_isTeleportSpecial); } -bool AM_isExitSpecial (int special, int*) +bool AM_isExitSpecial (int special, int *) { return (special == Teleport_NewMap || special == Teleport_EndGame || @@ -2305,7 +2305,7 @@ bool AM_isExitBoundary (line_t& line) return AM_checkSpecialBoundary(line, &AM_isExitSpecial); } -bool AM_isTriggerSpecial (int special, int*) +bool AM_isTriggerSpecial (int special, int *) { return special != 0 && special != Door_Open @@ -2316,7 +2316,7 @@ bool AM_isTriggerSpecial (int special, int*) && special != Generic_Door; } -bool AM_isTriggerBoundary (line_t& line) +bool AM_isTriggerBoundary (line_t &line) { return AM_checkSpecialBoundary(line, &AM_isTriggerSpecial); }