public static class NodeExtensions { /// /// Similar to , but throws a /// if the node at the given /// path does not exist, or a if /// it is not of the correct type. /// public static T GetNodeOrThrow(this Node self, NodePath path) where T : class { var result = self.GetNodeOrNull(path); if (result == null) throw new InvalidOperationException( $"Node at '{path}' not found"); if (result is not T resultOfType) throw new InvalidCastException( $"Node at '{path}' is {result.GetType()}, expected {typeof(T)}"); return resultOfType; } /// /// Finds the first parent of this node that is of /// type or null if not found. /// public static T FindParentOrNull(this Node self) where T : class { while ((self = self.GetParent()) != null) if (self is T result) return result; return null; } /// /// Finds the first parent of this node that is of type /// or throws a if not found. /// public static T FindParentOrThrow(this Node self) where T : class => self.FindParentOrNull() ?? throw new InvalidOperationException( $"No parent node of type {typeof(T)} found in hierarchy of '{self.GetPath()}'"); /// Returns whether the current peer has authority over this node. public static bool IsAuthority(this Node self) => self.Multiplayer.GetUniqueId() == self.GetMultiplayerAuthority(); }