Game.Pathfind.PathNode
Assembly: Assembly-CSharp
Namespace: Game.Pathfind
Type: struct
Base: System.ValueType
Implements: IEquatable
Summary:
PathNode is a compact, value-type representation of a pathfinding node used by the game's pathfinding system. It packs an owner Entity index, lane/segment indices, an optional curve position (quantized), and a "secondary" flag into a single 64-bit field (m_SearchKey). The struct provides convenience constructors, bit-manipulation helpers, comparisons that can ignore curve position, and serialization support.
Fields
-
private const float FLOAT_TO_INT = 32767f
Used to quantize a floating-point curve position into a 15-bit integer range (0..32767). -
private const float INT_TO_FLOAT = 3.051851E-05f
Reciprocal of FLOAT_TO_INT (≈ 1 / 32767). Used to convert the stored integer back to a float curve position. -
private const ulong CURVEPOS_INCLUDE = 2147418112uL
(0x7FFF0000) Mask corresponding to the curve-position bits. Useful when extracting or comparing the stored curve position. -
private const ulong CURVEPOS_EXCLUDE = 18446744071562133503uL
(0xFFFFFFFF8000FFFF) Mask used to clear the curve-position bits while preserving other parts of the key. -
private const ulong SECONDARY_NODE = 2147483648uL
(0x80000000) Bit mask for the secondary-node flag (stored in the low 32 bits, bit 31). -
private ulong m_SearchKey
The packed 64-bit storage. Layout (low-to-high within low 32 bits): - bits 0..15: lane index (ushort)
- bits 8..15: segment index (byte) (note: overlaps within low 16 bits with lane index's high byte)
- bits 16..30: quantized curve-position (15 bits)
- bit 31: secondary flag
- high 32 bits: owner Entity.Index (int) The constructors and accessors read/write fields by shifting & masking this value.
Properties
- None (no public C# properties defined). The struct exposes getters and mutators via methods.
Constructors
-
public PathNode(Entity owner, byte laneIndex, byte segmentIndex)
Creates a node with given owner, laneIndex (stored in low byte), segmentIndex (stored at <<8). Curve position and secondary flag are unset. -
public PathNode(Entity owner, byte laneIndex, byte segmentIndex, float curvePosition)
Stores owner, laneIndex, segmentIndex and quantizes curvePosition into the 15-bit field (curvePosition * 32767f, truncated) stored at bits <<16. -
public PathNode(Entity owner, ushort laneIndex, float curvePosition)
Stores owner and a full 16-bit laneIndex, plus the quantized curve position. -
public PathNode(Entity owner, ushort laneIndex)
Stores owner and full 16-bit laneIndex; no curve position. -
public PathNode(PathTarget pathTarget)
Constructs from a PathTarget (uses pathTarget.m_Entity.Index as owner and pathTarget.m_Delta as curve position, quantized). -
public PathNode(PathNode pathNode, float curvePosition)
Copies an existing PathNode but replaces the curve-position with the provided float (quantized). Preserves the secondary flag and other fields. -
public PathNode(PathNode pathNode, bool secondaryNode)
Copies an existing PathNode but sets or clears the secondary flag according to secondaryNode.
Notes: - Quantized curve positions expect values in the range that maps correctly into 0..32767. Values outside this range may be truncated or clipped by the cast to integer.
Methods
-
public bool IsSecondary()
Returns true if the secondary flag (0x80000000 in the low 32 bits) is set. -
public bool Equals(PathNode other)
IEquatable implementation: returns true when the entire packed key (m_SearchKey) matches exactly. -
public bool EqualsIgnoreCurvePos(PathNode other)
Compares two nodes ignoring the quantized curve-position bits. The comparison preserves the secondary flag and other fields; only curve-position bits are masked out. -
public bool OwnerEquals(PathNode other)
Returns true if both nodes have the same owner Entity.Index (compares the high 32 bits). -
public override int GetHashCode()
Returns the hash code of the packed m_SearchKey. -
public PathNode StripCurvePos()
Returns a copy of this PathNode with the curve-position bits cleared (curve pos removed), preserving other fields. -
public void ReplaceOwner(Entity oldOwner, Entity newOwner)
If this node's owner equals oldOwner.Index, replaces it with newOwner.Index while preserving the lower 32 bits. -
public void SetOwner(Entity newOwner)
Unconditionally replaces the owner part of the packed key with newOwner.Index. -
public void SetSegmentIndex(byte segmentIndex)
Sets the segment index (stored at bits <<8) while preserving other low-32-bit data. -
public float GetCurvePos()
Extracts the quantized curve position (bits 16..30), converts to float by multiplying by INT_TO_FLOAT (≈ 1/32767f) and returns it. -
public int GetOwnerIndex()
Returns the integer owner index (high 32 bits). -
public ushort GetLaneIndex()
Returns the stored lane index (low 16 bits returned as ushort). -
public bool GetOrder(PathNode other)
Returns true if this node should be ordered after the given other node when ordering by the packed key (i.e., compares m_SearchKey values). -
public int GetCurvePosOrder(PathNode other)
Returns the signed difference between this node's raw curve-position integer bits and the other's. Useful for ordering by curve position only. -
public void Serialize<TWriter>(TWriter writer) where TWriter : IWriter
Writes the owner Entity (as an Entity struct with Index set) and the lower 32 bits (uint) to the writer. Uses writer.Write(value, ignoreVersion: true) for the Entity and then writer.Write((uint)value2). -
public void Deserialize<TReader>(TReader reader) where TReader : IReader
Reads an Entity and a uint from reader and reconstructs m_SearchKey = ((long)value.Index << 32) | value2. -
public int GetStride(Context context)
Implements IStrideSerializable: returns 8 (bytes) as the stride/size used for serialization of the packed node.
Notes: - Serialization stores the owner index and the low 32-bit word (lane/segment/curvepos/secondary) so the full packed state can be reconstructed. - The struct relies on bit masks and shifts; modifying the bit layout would require updates to all related masks and methods.
Usage Example
// Example usages of PathNode
Entity entity = new Entity { Index = 12345 };
// Create a node with owner, lane (byte), segment (byte) and curve position (0..1 range)
PathNode node = new PathNode(entity, laneIndex: 3, segmentIndex: 1, curvePosition: 0.5f);
// Check curve position and secondary flag
float curve = node.GetCurvePos();
bool secondary = node.IsSecondary();
// Create a copy with a new curve position
PathNode nodeWithNewCurve = new PathNode(node, curvePosition: 0.75f);
// Strip curve position
PathNode stripped = node.StripCurvePos();
// Replace owner if matches
Entity newOwner = new Entity { Index = 54321 };
node.ReplaceOwner(entity, newOwner);
// Serialize / Deserialize (pseudo-code, depends on available IWriter/IReader)
using (var writer = /* obtain writer */)
{
node.Serialize(writer);
}
using (var reader = /* obtain reader */)
{
PathNode readNode = default;
readNode.Deserialize(reader);
}
If you need, I can also provide a visual diagram of the m_SearchKey bit layout, or generate helper extension methods (e.g., safe curve-position clamping) for your mod code.