Instead of passing a bare `int` named `secret_flag`, define it as an
`enum class : uint8_t` to name the two special values.
Rework the passing of this value, to deal with some confusing
inconsistencies when reading the code.
Before this change:
In D1:
- Multiplayer will always go to the secret level, regardless of which
exit door the player used.
In D2:
- Flying through a D1 secret exit in multiplayer shows the on-HUD error
"Secret Level Teleporter disabled in multiplayer!", and does not exit
the level. This is at best confusing, and at worst dangerous, since
D1 secret exits are only available during the countdown, so the player
has little time to realize that the normal exit must be used instead.
- Like D1, multiplayer will request to go to the secret level regardless
of the exit used. Unlike D1, the caller ignores the flag and always
advances to the next regular level.
After this change:
- No observable differences for the player in-game. The questionable D2
secret exit handling for D1 is retained.
- The code makes clearer that secret exits do not work in D2
multiplayer, by way of `#if defined(DXX_BUILD_DESCENT_I)` guarding the
existence of the parameter and all updates to it.
v29_trigger and v30_trigger define a field `time`. v29_trigger never
initializes it. v30_trigger initializes it from the uninitialized
v29_trigger in legacy mode, and from a file field otherwise. No program
logic ever reads this member, so remove it.
The latter more clearly shows that the code flow will not proceed past
this point while the menu is open. This conversion sets the stage for
later changes to make these menus asynchronous.
Define separate enum values for rotation data in both the high bits,
where it is usually kept, and the low bits, where it is sometimes used
for math or comparisons.
Define an enum value to represent the composite of the index and the
rotation, since the composite is not suitable for use as an array
subscript. Add helper functions to extract the component pieces.
This block previously was used to clear TRIGGER_ON, but that change was
removed because TRIGGER_ON was a write-only flag. This block is now
useless, so remove it. This should also fix an obscure crash reported
by AlumiuN.
AlumiuN proposed adding a test that seg->children[side] is still valid,
but since the logic to execute would be useless even when the test
succeeds, it is simpler to remove this code entirely.
Reported-by: AlumiuN <https://github.com/dxx-rebirth/dxx-rebirth/issues/515>
Suggested-by: AlumiuN <https://github.com/dxx-rebirth/dxx-rebirth/pull/518#issue-443277182>
Use an enum class to prevent implicit conversion between trigger
behavior flags and other integers. Fix up various resulting breaks,
which look like bugs:
- Descent 2 editor mode could modify trigger::flags, but used
TRIGGER_FLAG_* values, which specify the actions for a Descent 1
trigger when it executes, not the behavior properties for a trigger.
- Adding a trigger set its flags to 0, then cleared all flags except
TRIGGER_ON. Since the flags were just set to 0, the mask operation is
useless. Remove it.
- trigger_turn_all_ON cleared all flags except TRIGGER_ON. This seems
to be completely wrong. Change it to remove
trigger_behavior_flags::disabled. Descent 1 has no (working) support
for disabling triggers, so make trigger_turn_all_ON exclusive to
Descent 2.
- wall_restore_all would enable TRIGGER_ON in both games. Descent 1
never reads TRIGGER_ON. Descent 2 uses this field for trigger
behavior flags, and TRIGGER_ON is not a behavior flag.
- For Descent 1 builds, remove the modification of the field.
- For Descent 2 builds, change it to clear
trigger_behavior_flags::disabled.
Move it to a structure. Make all the modifiers methods. Change all
callers of those methods to pass the structure. This makes the stuck
object handling free of direct access to global game data.