Skip to content

Commit

Permalink
docs(VTrigger): add documentation for zCTrigger
Browse files Browse the repository at this point in the history
  • Loading branch information
lmichaelis committed Jan 3, 2024
1 parent 314671b commit 5010ee9
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 10 deletions.
157 changes: 157 additions & 0 deletions docs/engine/objects/zCTrigger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# zCTrigger

!!! abstract inline end "Quick Infos"
**Type:** Virtual Object<br/>
**Format Name:** ZenGin Archive<br/>
**File Extension:** `.ZEN`<br/>
**Class Name:** `zCTrigger`<br/>
**Version Identifiers:**<br />
— Gothic I: `47105`<br/>
— Gothic II: `47105`<br/>
**ZenKit Class:** `VTrigger`

VObject to process and relay specific filtered events. When a `zCTrigger` receives an `OnTrigger`, `OnDamage`, or
`OnTouch` event it checks whether the event source (an [`oCNpc`](oCNpc.md), the player or another VObject) should
be acknowledged (see [`respondToNPC`](#respondToNPC), [`respondToPC`](#respondToPC) and
[`respondToObject`](#respondToObject) respectively). It then verifies if it should react to the specific event by
checking the [`reactToOnTrigger`](#reactToOnTrigger), [`reactToOnDamage`](#reactToOnDamage) and
[`reactToOnTouch`](#reactToOnTouch) properties. If both checks succeed, an `OnTrigger` event is sent to the
[`triggerTarget`](#triggerTarget). `zCTrigger` objects can be enabled and disabled by firing `OnEnable`, `OnDisable`
and `OnToggleEnabled` events at them.

!!! note
The `respondTo{Object,PC,NPC,VobName}` properties are logically linked by and "or" expression.

<ul class="sp-list">
<li class="sp-type"><a href="../zCVob/">zCVob</a></li>
<li class="sp-type">
<span>zCTrigger</span>
<ul class="sp-list">
<li class="sp-string"><a href="#triggerTarget">triggerTarget</a> = ""</li>
<li class="sp-folder">
<span>Trigger</span>
<ul class="sp-list">
<li class="sp-folder">
<span>ActivationFilter</span>
<ul class="sp-list">
<li class="sp-bool"><a href="#reactToOnTrigger">reactToOnTrigger</a> = TRUE</li>
<li class="sp-bool"><a href="#reactToOnTouch">reactToOnTouch</a> = TRUE</li>
<li class="sp-bool"><a href="#reactToOnDamage">reactToOnDamage</a> = TRUE</li>
<li class="sp-bool"><a href="#respondToObject">respondToObject</a> = TRUE</li>
<li class="sp-bool"><a href="#respondToPC">respondToPC</a> = TRUE</li>
<li class="sp-bool"><a href="#respondToNPC">respondToNPC</a> = TRUE</li>
<li class="sp-bool"><a href="#startEnabled">startEnabled</a> = TRUE</li>
<li class="sp-string"><a href="#respondToVobName">respondToVobName</a> = ""</li>
<li class="sp-int"><a href="#numCanBeActivated">numCanBeActivated</a> = -1</li>
<li class="sp-float"><a href="#retriggerWaitSec">retriggerWaitSec</a> = 0</li>
<li class="sp-float"><a href="#damageThreshold">damageThreshold</a> = 0</li>
</ul>
</li>
<li class="sp-folder">
<span>FireBehavior</span>
<ul class="sp-list">
<li class="sp-float"><a href="#fireDelaySec">fireDelaySec</a> = 0</li>
<li class="sp-bool"><a href="#sendUntrigger">sendUntrigger</a> = TRUE</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>

## Properties

<a name="triggerTarget" class="t-str"></a> `triggerTarget`

: The name of VObject to send `OnTrigger` and `OnUntrigger` events to after processing.

<a name="reactToOnTrigger" class="t-bool"></a> `reactToOnTrigger`

: Whether this trigger should react to `OnTrigger` events.

* `TRUE` — Do react to `OnTrigger` events by sending an `OnTrigger` message to the [`triggerTarget`](#triggerTarget)
If [`sendUntrigger`](#sendUntrigger) is set to `TRUE`, also sends an `OnUntrigger` event to the [`triggerTarget`](#triggerTarget)
if the trigger receives an `OnUntrigger` event.
* `FALSE` — Ignore `OnTrigger` events.

<a name="reactToOnTouch" class="t-bool"></a> `reactToOnTouch`

: Whether this trigger should react to `OnTouch` events.

* `TRUE` — Do react to `OnTouch` events by sending an `OnTrigger` message to the [`triggerTarget`](#triggerTarget)
If [`sendUntrigger`](#sendUntrigger) is set to `TRUE`, also sends an `OnUntrigger` event to the [`triggerTarget`](#triggerTarget)
if the trigger receives an `OnUntouch` event.
* `FALSE` — Ignore `OnTouch` events.

<a name="reactToOnDamage" class="t-bool"></a> `reactToOnDamage`

: Whether this trigger should react to `OnDamage` events.

* `TRUE` — Do react to `OnDamage` events by sending an `OnTrigger` message to the [`triggerTarget`](#triggerTarget)
* `FALSE` — Ignore `OnDamage` events.

<a name="respondToObject" class="t-bool"></a> `respondToObject`

: Whether this trigger should process events coming from inanimate objects.

* `TRUE` — Do process events from inanimate objects.
* `FALSE` — Ignore events from inanimate objects.

<a name="respondToPC" class="t-bool"></a> `respondToPC`

: Whether this trigger should process events coming from the player.

* `TRUE` — Do process events from the player.
* `FALSE` — Ignore events from the player.

<a name="respondToNPC" class="t-bool"></a> `respondToNPC`

: Whether this trigger should process events coming from NPCs.

* `TRUE` — Do process events from NPCs.
* `FALSE` — Ignore events from NPCs.

<a name="startEnabled" class="t-bool"></a> `startEnabled`

: Determines whether the trigger is initially enabled. Enabled triggers will process incoming events and send
outgoing events while disabled triggers do not. Triggers can be activated and deactivated at runtime by sending
them `OnEnable`, `OnDisable` or `OnToggleEnabled` events.

* `TRUE` — Enable the trigger when the world is loaded.
* `FALSE` — Do not enable the trigger when the world is loaded.

<a name="respondToVobName" class="t-str"></a> `respondToVobName`

: Whether this trigger should process events coming from VObjects with this name. If empty, match no VObject
name directly.

<a name="numCanBeActivated" class="t-int"></a> `numCanBeActivated`

: The number of times the trigger will process incoming events. If set to `-1` the trigger will process
an infinite number of events.

<a name="retriggerWaitSec" class="t-float"></a> `retriggerWaitSec`

: The number of seconds that have to elapse after processing an event before the trigger will process additional events.
All events received by the trigger during that time are ignored.

<a name="damageThreshold" class="t-float"></a> `damageThreshold`

: The amount of damage which must be dealt for the trigger to react to an `OnDamage` event.

<a name="fireDelaySec" class="t-float"></a> `fireDelaySec`

: The number of seconds to wait before emitting the `OnTrigger` event after processing.

<a name="sendUntrigger" class="t-bool"></a> `sendUntrigger`

: Whether to send and `OnUntrigger` event to the [`triggerTarget`](#triggerTarget) after the trigger receives an
`OnUntrigger` or `OnUntouch` event. Only fires the `OnUntrigger` event if [`reactToOnTrigger`](#reactToOnTrigger)
and [`reactToOnTouch`](#reactToOnTouch) are set to `TRUE` respectively.


## Sources

The help file for the Spacer, found [here](https://wiki.worldofgothic.de/doku.php?id=spacer:hilfedatei) and the
Russian-language knowledge accumulator [gothic-library.ru](http://www.gothic-library.ru/publ/class_zctrigger/1-1-0-529).
98 changes: 88 additions & 10 deletions include/zenkit/vobs/Trigger.hh
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,95 @@ namespace zenkit {
random ZKREM("renamed to TriggerBatchMode::RANDOM") = RANDOM,
};

/// \brief A basic trigger VOb which does something upon the player interacting with it.
/// \brief VObject to process and relay specific filtered events.
///
/// When a `zCTrigger` receives an `OnTrigger`, `OnDamage`, or `OnTouch` event it checks whether the event
/// source (an VNpc, the player or another VObject) should be acknowledged (see #respond_to_npc, #respond_to_pc
/// and #respond_to_object respectively). It then verifies if it should react to the specific event by checking
/// the #react_to_on_trigger, #react_to_on_touch and #react_to_on_damage properties. If both checks succeed, an
/// `OnTrigger` event is sent to the #target. `zCTrigger` objects can be enabled and disabled by firing `OnEnable`,
/// `OnDisable` and `OnToggleEnabled` events at them.
///
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/
struct VTrigger : VirtualObject {
ZK_OBJECT(ObjectType::zCTrigger);

public:
/// \brief The name of VObject to send `OnTrigger` and `OnUntrigger` events to after processing.
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#triggerTarget
std::string target;
std::uint8_t flags;
std::uint8_t filter_flags;

std::uint8_t ZKREM("replaced by `start_enabled` and `send_untrigger`") flags;

/// \brief Determines whether the trigger is initially enabled.
///
/// Enabled triggers will process incoming events and send outgoing events while disabled triggers do not.
/// Triggers can be activated and deactivated at runtime by sending them `OnEnable`, `OnDisable` or
/// `OnToggleEnabled` events.
///
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#startEnabled
bool start_enabled;

/// \brief Whether to send and `OnUntrigger` event to the #target after the trigger receives an
/// `OnUntrigger` or `OnUntouch` event.
///
/// Only fires the `OnUntrigger` event if #react_to_on_trigger and #react_to_on_touch are set
/// to `TRUE` respectively.
///
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#sendUntrigger
bool send_untrigger;

std::uint8_t ZKREM("replaced by `react_to_*` and `respond_to_*`") filter_flags;

/// \brief Whether this trigger should react to `OnTrigger` events.
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#reactToOnTrigger
bool react_to_on_trigger;

/// \brief Whether this trigger should react to `OnTouch` events.
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#reactToOnTouch
bool react_to_on_touch;

/// \brief Whether this trigger should react to `OnDamage` events.
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#reactToOnDamage
bool react_to_on_damage;

/// \brief Whether this trigger should process events coming from inanimate objects.
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#respondToObject
bool respond_to_object;

/// \brief Whether this trigger should process events coming from the player.
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#respondToPC
bool respond_to_pc;

/// \brief Whether this trigger should process events coming from NPCs.
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#respondToNPC
bool respond_to_npc;

/// \brief Whether this trigger should process events coming from VObjects with this name.
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#respondToVobName
std::string vob_target;

/// \brief The number of times the trigger will process incoming events.
///
/// If set to `-1` the trigger will process an infinite number of events.
///
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#numCanBeActivated
std::int32_t max_activation_count;

/// \brief The number of seconds that have to elapse after processing an event before the trigger will
/// process additional events.
///
/// All events received by the trigger during that time are ignored.
///
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#retriggerWaitSec
float retrigger_delay_sec;

/// \brief The amount of damage which must be dealt for the trigger to react to an `OnDamage` event.
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#damageThreshold
float damage_threshold;

/// \brief The number of seconds to wait before emitting the `OnTrigger` event after processing.
/// \see https://zk.gothickit.dev/engine/objects/zCTrigger/#fireDelaySec
float fire_delay_sec;

// Save-game only variables
Expand All @@ -87,17 +164,18 @@ namespace zenkit {
std::shared_ptr<Object> s_other_vob {nullptr};
bool s_is_enabled {true};

/// \brief Parses a trigger VOb the given *ZenGin* archive.
/// \param[out] obj The object to read.
/// \param[in,out] ctx The archive reader to read from.
/// \note After this function returns the position of \p ctx will be at the end of the parsed object.
/// \throws ParserError if parsing fails.
/// \see vob::parse
/// \see trigger::parse
ZKREM("use ::load()") ZKAPI static void parse(VTrigger& obj, ReadArchive& ctx, GameVersion version);

/// \brief Load this object from the given archive.
/// \param r The archive to read from;
/// \param version The version of the game the object was made for.
ZKAPI void load(ReadArchive& r, GameVersion version) override;

/// \brief Save this object to the given archive.
/// \param w The archive to save to.
/// \param version The version of the game to save for.
ZKAPI void save(WriteArchive& w, GameVersion version) const override;

[[nodiscard]] ZKAPI uint16_t get_version_identifier(GameVersion game) const override;
};

Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ nav:
- 'zCMoverControler': 'engine/objects/zCMoverController.md'
- 'zCPFXControler': 'engine/objects/zCPFXControler.md'
- 'zCTouchDamage': 'engine/objects/zCTouchDamage.md'
- 'zCTrigger': 'engine/objects/zCTrigger.md'
- 'oCItem': 'engine/objects/oCItem.md'
- 'zCVisual': 'engine/objects/zCVisual.md'
- 'zCDecal': 'engine/objects/zCDecal.md'
Expand Down
9 changes: 9 additions & 0 deletions src/vobs/Trigger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ namespace zenkit {
this->damage_threshold = r.read_float(); // damageThreshold
this->fire_delay_sec = r.read_float(); // fireDelaySec

this->start_enabled = this->flags & 1; // startEnabled
this->send_untrigger = (this->flags & 4) >> 2; // sendUntrigger
this->react_to_on_trigger = this->filter_flags & 1; // reactToOnTrigger
this->react_to_on_touch = (this->filter_flags & 2) >> 1; // reactToOnTouch
this->react_to_on_damage = (this->filter_flags & 4) >> 2; // reactToOnDamage
this->respond_to_object = (this->filter_flags & 8) >> 3; // respondToObject
this->respond_to_pc = (this->filter_flags & 16) >> 4; // respondToPC
this->respond_to_npc = (this->filter_flags & 32) >> 5; // respondToNPC

this->s_count_can_be_activated = this->max_activation_count;

if (r.is_save_game()) {
Expand Down

0 comments on commit 5010ee9

Please sign in to comment.