diff --git a/CHANGELOG.md b/CHANGELOG.md index 7964174..5b66657 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1,6 @@ -- Added more events \ No newline at end of file +- Added more events. +- Allow binding keybind config to panel visibility. +- Added `clearpickups` command (removes all pickups in a radius). +- Fixed some inputs not working sometimes. +- Various bug fixes. +- SUI improvements. \ No newline at end of file diff --git a/README.md b/README.md index cff3d37..464cada 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@

+

diff --git a/RedLoader/Utils/Observable.cs b/RedLoader/Utils/Observable.cs index 8ecdf55..855e9a4 100644 --- a/RedLoader/Utils/Observable.cs +++ b/RedLoader/Utils/Observable.cs @@ -40,7 +40,7 @@ public T Value get => _value; set { - if (_value.Equals(value)) + if ((_value == null && value == null) || (_value != null && _value.Equals(value))) { return; } diff --git a/Resources/README_TEMPLATE.md b/Resources/README_TEMPLATE.md index 4453bdd..2b73f15 100644 --- a/Resources/README_TEMPLATE.md +++ b/Resources/README_TEMPLATE.md @@ -4,6 +4,7 @@

+

diff --git a/SonsGameManager/Core.cs b/SonsGameManager/Core.cs index 652d1c9..dd812a9 100644 --- a/SonsGameManager/Core.cs +++ b/SonsGameManager/Core.cs @@ -89,7 +89,7 @@ protected override void OnGameStart() Log("======= GAME STARTED ========"); // -- Enable debug console -- - DebugConsole.Instance.enabled = true; + //DebugConsole.Instance.enabled = true; DebugConsole.SetCheatsAllowed(true); DebugConsole.Instance.SetBlockConsole(false); diff --git a/SonsGameManager/DebugCommands.cs b/SonsGameManager/DebugCommands.cs index bb84cc6..3f48700 100644 --- a/SonsGameManager/DebugCommands.cs +++ b/SonsGameManager/DebugCommands.cs @@ -1,7 +1,9 @@ using System.Text; using AdvancedTerrainGrass; +using Endnight.Utilities; using RedLoader; using RedLoader.Utils; +using Sons.Ai.Vail.Inventory; using Sons.Characters; using Sons.Construction.GRABS; using Sons.Gameplay; @@ -104,6 +106,27 @@ private void NoForestCommand(string args) PathologicalGames.PoolManager.Pools["SmallTree"].gameObject.SetActive(!isActive); } + /// + /// Clears all pickups in a radius + /// + /// + /// clearpickups + [DebugCommand("clearpickups")] + private void ClearPickupsCommand(string args) + { + if(!float.TryParse(args, out var radius)) + radius = 5f; + + var pickups = Resources.FindObjectsOfTypeAll(); + foreach (var pickup in pickups) + { + if (Vector3.Distance(ActiveWorldLocation.Position, pickup.transform.position) > radius) + continue; + + UnityEngine.Object.Destroy(pickup.gameObject); + } + } + /// /// Go to a pickup by name (picks the first one that contains the name). Useful for finding story items. /// diff --git a/SonsGameManager/SonsGameManager.xml b/SonsGameManager/SonsGameManager.xml index 77e7e79..22915a3 100644 --- a/SonsGameManager/SonsGameManager.xml +++ b/SonsGameManager/SonsGameManager.xml @@ -115,6 +115,13 @@ noforest + + + Clears all pickups in a radius + + + clearpickups + Go to a pickup by name (picks the first one that contains the name). Useful for finding story items. diff --git a/SonsSdk/CustomState.cs b/SonsSdk/CustomState.cs new file mode 100644 index 0000000..d2933ac --- /dev/null +++ b/SonsSdk/CustomState.cs @@ -0,0 +1,54 @@ +using RedLoader; +using UnityEngine.InputSystem; + +namespace SonsSdk; + +public abstract class CustomState +{ + public bool IsActive { get; private set; } + + protected InputAction[] ActionsToDisable; + + protected CustomState() {} + + protected CustomState(InputAction[] actionsToDisable) + { + ActionsToDisable = actionsToDisable; + } + + public void Start() + { + if(ActionsToDisable != null) + foreach (var action in ActionsToDisable) + action.Disable(); + + OnStart(); + GlobalEvents.OnUpdate.Subscribe(OnUpdateInternal); + IsActive = true; + } + + public void End() + { + IsActive = false; + GlobalEvents.OnUpdate.Subscribe(OnUpdateInternal); + OnEnd(); + + if(ActionsToDisable != null) + foreach (var action in ActionsToDisable) + action.Enable(); + } + + private void OnUpdateInternal() + { + if(!IsActive) + return; + + OnUpdate(); + } + + protected abstract void OnStart(); + + protected abstract void OnEnd(); + + protected abstract void OnUpdate(); +} \ No newline at end of file diff --git a/SonsSdk/PreviewBox.cs b/SonsSdk/PreviewBox.cs new file mode 100644 index 0000000..3816f00 --- /dev/null +++ b/SonsSdk/PreviewBox.cs @@ -0,0 +1,64 @@ +using Shapes; +using UnityEngine; + +namespace SonsSdk; + +public class PreviewBox : IDisposable +{ + public GameObject Container; + public Transform Transform; + public Cuboid Cube; + + public bool IsActive { get; private set; } + + public PreviewBox() + { + Container = new GameObject("PreviewBox"); + Transform = Container.transform; + Cube = Container.AddComponent(); + + IsActive = true; + } + + public PreviewBox(Color color) : this() + { + SetColor(color); + } + + public PreviewBox SetColor(Color color) + { + Cube.Color = color; + return this; + } + + public void Set(Vector3 pos, Vector3 size) + { + Transform.SetPositionAndRotation(pos, Quaternion.identity); + Transform.localScale = size; + } + + public void Set(Vector3 pos, Vector3 size, Quaternion rot) + { + Transform.SetPositionAndRotation(pos, rot); + Transform.localScale = size; + } + + public void SetActive(bool active) + { + if (active && !IsActive) + { + Container.SetActive(true); + IsActive = true; + } + else if (!active && IsActive) + { + Container.SetActive(false); + IsActive = false; + } + } + + public void Dispose() + { + Container.TryDestroy(); + } +} \ No newline at end of file diff --git a/SonsSdk/SUI/SContainerOptions.cs b/SonsSdk/SUI/SContainerOptions.cs index 34130bb..8c49f82 100644 --- a/SonsSdk/SUI/SContainerOptions.cs +++ b/SonsSdk/SUI/SContainerOptions.cs @@ -12,6 +12,9 @@ public SContainerOptions(GameObject root) : base(root) protected override void VisibilityObservalbleChanged(bool value) { + if(InvertVisibility) + value = !value; + if (_observableTogglesGameObject) { if(value == Root.activeSelf) @@ -34,9 +37,28 @@ protected override void VisibilityObservalbleChanged(bool value) /// The observable boolean value to bind to. /// Whether to toggle the GameObject's active state based on the observable value or the canvasgroup alpha. public SContainerOptions BindVisibility(Observable observable, bool toggleGameObject) + { + UnbindVisibility(); + + InvertVisibility = false; + VisibilityObservable = observable; + _observableTogglesGameObject = toggleGameObject; + observable.OnValueChanged += VisibilityObservalbleChanged; + VisibilityObservalbleChanged(observable.Value); + + return this; + } + + /// + /// Binds the visibility of the container to an observable boolean value. + /// + /// The observable boolean value to bind to. + /// Whether to toggle the GameObject's active state based on the observable value or the canvasgroup alpha. + public SContainerOptions BindVisibilityInverted(Observable observable, bool toggleGameObject) { UnbindVisibility(); + InvertVisibility = true; VisibilityObservable = observable; _observableTogglesGameObject = toggleGameObject; observable.OnValueChanged += VisibilityObservalbleChanged; diff --git a/SonsSdk/SUI/SPanelOptions.cs b/SonsSdk/SUI/SPanelOptions.cs index 8d460e9..ceb34e6 100644 --- a/SonsSdk/SUI/SPanelOptions.cs +++ b/SonsSdk/SUI/SPanelOptions.cs @@ -1,11 +1,40 @@ -using UnityEngine; +using RedLoader; +using SonsSdk; +using UnityEngine; namespace SUI; public class SPanelOptions : SContainerOptions { public string Id { get; internal set; } + + private bool _closeOnKeyRelease; + public SPanelOptions(GameObject root) : base(root) { } + + public SPanelOptions BindKeyConfig(KeybindConfigEntry keybind, bool closeOnKeyRelease = false) + { + _closeOnKeyRelease = closeOnKeyRelease; + keybind.Notify(KeyPressed, KeyReleased); + return this; + } + + private void KeyPressed() + { + if (_closeOnKeyRelease) + { + Active(true); + return; + } + + Toggle(); + } + + private void KeyReleased() + { + if(_closeOnKeyRelease) + Active(false); + } } \ No newline at end of file diff --git a/SonsSdk/SUI/SUiElement.cs b/SonsSdk/SUI/SUiElement.cs index c741cae..1dda302 100644 --- a/SonsSdk/SUI/SUiElement.cs +++ b/SonsSdk/SUI/SUiElement.cs @@ -74,12 +74,16 @@ public class SUiElement : SUiElement protected TooltipInfo TooltipInfo; protected Observable VisibilityObservable; + protected bool InvertVisibility; public SUiElement(GameObject root) : base(root) { } protected virtual void VisibilityObservalbleChanged(bool value) { + if (InvertVisibility) + value = !value; + if(value == Root.activeSelf) return; @@ -93,7 +97,24 @@ protected virtual void VisibilityObservalbleChanged(bool value) public T BindVisibility(Observable observable) { UnbindVisibility(); + + InvertVisibility = false; + VisibilityObservable = observable; + observable.OnValueChanged += VisibilityObservalbleChanged; + VisibilityObservalbleChanged(observable.Value); + return (T)(object)this; + } + + /// + /// Binds the visibility of the container to an observable boolean value. + /// + /// The observable boolean value to bind to. + public T BindVisibilityInverted(Observable observable) + { + UnbindVisibility(); + + InvertVisibility = true; VisibilityObservable = observable; observable.OnValueChanged += VisibilityObservalbleChanged; VisibilityObservalbleChanged(observable.Value); @@ -543,9 +564,35 @@ public T Pivot(float? x = null, float? y = null) RectTransform.pivot = pivot; return (T)(object)this; } + + /// + /// A shortcut to set the pivot to (0,1) and anchor to top left. + /// + /// + public T TopLeft() + { + RectTransform.anchorMin = new Vector2(0, 1); + RectTransform.anchorMax = new Vector2(0, 1); + RectTransform.pivot = new Vector2(0, 1); + return (T)(object)this; + } + + /// + /// A shortcut to set the pivot to (0,1) and anchor to top left. + /// Additionally sets the position (with the y value negated). + /// This might be easier for users coming from web dev or frameworks like Imgui. + /// + /// + public T TopLeft(float x, float y) + { + TopLeft(); + Position(x, -y); + return (T)(object)this; + } /// /// Sets the aspect ratio mode for the objects's aspect ratio fitter. + /// Adds an aspect ratio fitter if none is present. /// /// The aspect ratio mode to apply. public T AspectRatio(AspectRatioFitter.AspectMode mode) diff --git a/SonsSdk/SonsSdk.csproj b/SonsSdk/SonsSdk.csproj index e373b5a..7b35ea1 100644 --- a/SonsSdk/SonsSdk.csproj +++ b/SonsSdk/SonsSdk.csproj @@ -65,6 +65,9 @@ F:\SteamLibrary\steamapps\common\Sons Of The Forest\_RedLoader\Game\Newtonsoft.Json.dll + + F:\SteamLibrary\steamapps\common\Sons Of The Forest\_RedLoader\Game\ShapesRuntime.dll + $(GamePath)\$(ProjectAlias)\Game\Sons.dll @@ -197,7 +200,6 @@ - diff --git a/docfx_project/articles/installing-mods.md b/docfx_project/articles/installing-mods.md index e9c2701..e31eaca 100644 --- a/docfx_project/articles/installing-mods.md +++ b/docfx_project/articles/installing-mods.md @@ -1,9 +1,10 @@ # Installing Mods -To install mods you can use the Mod Manager found [here](https://github.com/ToniMacaroni/RedManager). +To install mods you can use the Mod Manager found [here](https://github.com/ToniMacaroni/RedManager). + If you instead want to manually install mods do the following: 1) Download the mod zip. -2) Extract the the contents of the zip into your `Sons Of The Forest/Mods` folder. +2) Extract the the contents of the zip into your `Sons Of The Forest` folder. After that you should have a .dll file and a folder with the same name inside your Mods directory. \ No newline at end of file diff --git a/docs/articles/installing-mods.html b/docs/articles/installing-mods.html index e92edf1..b452b90 100644 --- a/docs/articles/installing-mods.html +++ b/docs/articles/installing-mods.html @@ -92,11 +92,11 @@

Search Results for

Installing Mods

-

To install mods you can use the Mod Manager found here.
-If you instead want to manually install mods do the following:

+

To install mods you can use the Mod Manager found here.

+

If you instead want to manually install mods do the following:

  1. Download the mod zip.
  2. -
  3. Extract the the contents of the zip into your Sons Of The Forest/Mods folder.
  4. +
  5. Extract the the contents of the zip into your Sons Of The Forest folder.

After that you should have a .dll file and a folder with the same name inside your Mods directory.

diff --git a/docs/index.json b/docs/index.json index 80979ef..e3af97f 100644 --- a/docs/index.json +++ b/docs/index.json @@ -1172,7 +1172,7 @@ "articles/installing-mods.html": { "href": "articles/installing-mods.html", "title": "Installing Mods | RedLoader Docs", - "keywords": "Installing Mods To install mods you can use the Mod Manager found here. If you instead want to manually install mods do the following: Download the mod zip. Extract the the contents of the zip into your Sons Of The Forest/Mods folder. After that you should have a .dll file and a folder with the same name inside your Mods directory." + "keywords": "Installing Mods To install mods you can use the Mod Manager found here. If you instead want to manually install mods do the following: Download the mod zip. Extract the the contents of the zip into your Sons Of The Forest folder. After that you should have a .dll file and a folder with the same name inside your Mods directory." }, "articles/loader-features.html": { "href": "articles/loader-features.html",