Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add directionality to walls #5118

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from

Conversation

kwvanderlinde
Copy link
Collaborator

@kwvanderlinde kwvanderlinde commented Dec 20, 2024

Identify the Bug or Feature request

Resolves #5080

Description of the Change

Walls can have one of these enumerated directions:

  • Left
  • Right
  • Both

An arrow indicates to the user what the direction of the wall is. If there is no arrow, the direction is Both.

Walls can also have overrides applies for different types of "vision" blocking (sights, lights, and auras):

  • SameDirection (default) means that blocking for this type works in the same direction as the wall.
  • ReverseDirection means that blocking for this type works opposite to the wall's direction (no effect if wall direction is Both).
  • ForceBoth means that blocking for this type works as if the wall's direction is Both.
  • Disabled means that blocking for this type is disabled for this wall.

Movement blocking does not support directionality yet as there are extra complexities for it that would go way beyond this change. But it support has been added for the ForceBoth and Disabled options, with ForceBoth being the default for movement blocking.

The way the user modifies these properties is through a new control panel:
image
This control panel with show the properties of the currently selected wall (if there is one). When drawing new walls, the properties set in the control panel will be applied to the new walls.

The XML for walls includes the new information as child elements of the <wall> elements, e.g.:

<wall from="8A647D10EE1B4AFA8BEF4B93AEFB624D" to="E3A964F13221428582E491AB3D3D3764">
  <direction>Left</direction>
  <movementDirection>Disabled</movementDirection>
  <sightDirection>SameDirection</sightDirection>
  <lightDirection>ReverseDirection</lightDirection>
  <auraDirection>ForceBoth</auraDirection>
</wall>

There is some code maintenance as well. The biggest point here is that Vertex and Wall are more basic values - they don't depend on their parent WallTopology, and can be more easily constructed and serialized. This makes the private VertexInternal and WallInternal obsolete and they have been removed. Wall and Vertex have also been moved out of the WallTopology class just to make it less busy.

Possible Drawbacks

Merging behaviour regarding direction modifiers for sights, lights, and auras could be a bit surprising with the various case work in play.

Documentation Notes

Walls can have one of these directions:

  • Left
  • Right
  • Both

If "Both", the wall blocks in both directions. If "Left" or "Right" the wall only blocks in that particular direction. The interpretation of "Left" and "Right" depends on the heading of the wall, i.e., which one of the wall's endpoints is the start of the wall and which one is the end of the wall. To make the direction clear to the user, an arrow is drawn through the wall to indicate the direction:
image

To support different directional effects, sights, lights, and auras can be configured to override the wall direction. In this example, a directional wall models a one-way mirror:
image
The Troll is unable to see out of the room due to the wall's direction:
image
But the Elf is able to see into the room through the one-way mirror:
image
Also notice that the orange light inside the room is allowed through the wall beccause the Light option is set to "Reverse Direction".

This next example represents a cliff face, with a Troll at the bottom and an Elf at the top. As in the previous example, the Elf and see the Troll, but the Troll can't see the Elf. But this time the Troll's light is not allowed through the wall to illuminate the top of the cliff, because the Light option is set to "Same Direction".
image

Release Notes

  • Added directions to walls, with ability for sights, lights, and auras to modify the direction.

This change is Reviewable

@kwvanderlinde kwvanderlinde self-assigned this Dec 20, 2024
@kwvanderlinde kwvanderlinde added the feature Adding functionality that adds value label Dec 20, 2024
Each wall can have a main direction (`Left`, `Right`) or be bidirectional (`Both`). Relative to the main direction,
specific uses (`Sight`, `Light`, `Aura`) can be configured to respect the main direction (`SameDirection`), work in the
opposite direction (`ReverseDirection`), ignore directionality and be bidirectional (`ForceBoth`) or ignore the wall
entirely (`Disabled`). Movement also supports the `ForceBoth` and `Disabled` cases, but does not support direction
itself and so does not have the `SameDirection` and `ReverseDirection` cases.

Internally, the representation of walls got more complicated, but a future change will work to reduce that
again. `WallInternal` now sports a mutable `WallData` that is capable of being overwritten and merged with `WallData`
from other walls. Individual walls can have their data be updated through the new `UpdateWallMessage` message. The
`WallData` is what carries the directional information for the wall.

A new control panel gives access to changing wall properties. The currently selected wall will have its state reflected
in the control panel, and modifying the values there will update the wall. When drawing a new wall, the current values
from the control panel will be applied.

The XML for walls has been extended to store the wall's direction and modifiers as child elements.
There is no more distinction between the public `Wall` and `Vertex` types vs the private `WallInternal` and
`VertexInternal` types. Everything now works with `Wall` and `Vertex` directly, and `Wall` and `Vertex` are now pretty
plain data types. The cost of this is the `Wall` cannot directly reference `Vertex`, so looking up the endpoints
requires going through the source `Walltopology`. On the plus side, it is now easier to manipulate and create `Vertex`
and `Wall` without having to involve the `WallTopology` at all.

`WallData` is now `Wall.Data` and is opaque to callers (all members are private). This allows it to be read, stored, and
restored, but cannot be directly manipulated by callers. Callers instead have to use the `Wall` itself to manipulate its
data.
This means we don't need the `reverse` parameter in `Wall.mergeDataFrom()`, and some case work can be reduced in that
method.
This avoids having to worry about whether a `Wall.Data` that is passed around might be unexpected modified. Instead, the
`Wall` itself can replace its `Wall.Data` completely when needed.

Also add merging methods to each of `Direction`, `DirectionModifier`, and `MovementDirectionModifier` so that
`Wall.Data.merge()` is much easier to read.
@kwvanderlinde kwvanderlinde force-pushed the feature/5080-wall-directionality branch 3 times, most recently from 90051d8 to 7f93feb Compare December 24, 2024 08:46
A bar is placed near the source vertex, and an arrow head is placed near the target vertex.

Additionally, these new decorations along with the directional arrow are not drawn if the wall is so small relative to
the vertex handles that it wouldn't be visible.
@kwvanderlinde kwvanderlinde force-pushed the feature/5080-wall-directionality branch from 7f93feb to d306f20 Compare December 24, 2024 08:49
@kwvanderlinde kwvanderlinde marked this pull request as ready for review December 25, 2024 00:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Adding functionality that adds value
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature]: Add directionality to walls for vision
1 participant