From d318611246b26cd0948414da07432d21e4def939 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:31:47 -0500 Subject: [PATCH 01/23] Initial commit --- .gitattributes | 2 + .gitignore | 398 +++++++++++++++++++++++++++++++++++++++++++++++++ LICENSE | 21 +++ README.md | 2 + 4 files changed, 423 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..426d76d --- /dev/null +++ b/.gitignore @@ -0,0 +1,398 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4480281 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 NotAKidoS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c7c9708 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# PropUndoButton + press z to undo prop From 66943235c1f3166f272fea6c22cc0657b1056251 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:34:08 -0500 Subject: [PATCH 02/23] init --- PropUndoButton/Main.cs | 147 ++++++++++++++++++++++ PropUndoButton/PropUndoButton.csproj | 50 ++++++++ PropUndoButton/PropUndoButton.sln | 25 ++++ PropUndoButton/Properties/AssemblyInfo.cs | 32 +++++ PropUndoButton/SFX/sfx_spawn.wav | Bin 0 -> 15476 bytes PropUndoButton/SFX/sfx_undo.wav | Bin 0 -> 12496 bytes PropUndoButton/SFX/sfx_warn.wav | Bin 0 -> 12684 bytes PropUndoButton/format.json | 23 ++++ 8 files changed, 277 insertions(+) create mode 100644 PropUndoButton/Main.cs create mode 100644 PropUndoButton/PropUndoButton.csproj create mode 100644 PropUndoButton/PropUndoButton.sln create mode 100644 PropUndoButton/Properties/AssemblyInfo.cs create mode 100644 PropUndoButton/SFX/sfx_spawn.wav create mode 100644 PropUndoButton/SFX/sfx_undo.wav create mode 100644 PropUndoButton/SFX/sfx_warn.wav create mode 100644 PropUndoButton/format.json diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs new file mode 100644 index 0000000..2d8bb3e --- /dev/null +++ b/PropUndoButton/Main.cs @@ -0,0 +1,147 @@ +using ABI_RC.Core.AudioEffects; +using ABI_RC.Core.Savior; +using ABI_RC.Core.Util; +using MelonLoader; +using System.Reflection; +using UnityEngine; + +namespace NAK.Melons.UndoPropButton; + +// https://pixabay.com/sound-effects/selection-sounds-73225/ + +public class PropUndoButton : MelonMod +{ + private static readonly MelonPreferences_Category Category = + MelonPreferences.CreateCategory(nameof(PropUndoButton)); + + public static readonly MelonPreferences_Entry EntryEnabled = + Category.CreateEntry("Enabled", true, description: "Toggle Undo Prop Button."); + + public static readonly MelonPreferences_Entry EntryUseSFX = + Category.CreateEntry("Use SFX", true, description: "Enable or disable undo SFX."); + + // audio clip names, InterfaceAudio adds "PropUndo_" prefix + public const string sfx_spawn = "PropUndo_sfx_spawn"; + public const string sfx_undo = "PropUndo_sfx_undo"; + public const string sfx_warn = "PropUndo_sfx_warn"; + + public override void OnInitializeMelon() + { + HarmonyInstance.Patch( // prop spawn sfx + typeof(CVRSyncHelper).GetMethod(nameof(CVRSyncHelper.SpawnProp)), + null, + new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnSpawnProp), BindingFlags.NonPublic | BindingFlags.Static)) + ); + HarmonyInstance.Patch( // desktop input patch so we don't run in menus/gui + typeof(InputModuleMouseKeyboard).GetMethod(nameof(InputModuleMouseKeyboard.UpdateInput)), + null, + new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnUpdateInput), BindingFlags.NonPublic | BindingFlags.Static)) + ); + SetupDefaultAudioClips(); + } + + private void SetupDefaultAudioClips() + { + // PropUndo and audio folders do not exist, create them if dont exist yet + string path = Application.streamingAssetsPath + "/Cohtml/UIResources/GameUI/mods/PropUndo/audio/"; + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + LoggerInstance.Msg("Created PropUndo/audio directory!"); + } + + // copy embedded resources to this folder if they do not exist + string[] clipNames = { "sfx_spawn.wav", "sfx_undo.wav", "sfx_warn.wav" }; + foreach (string clipName in clipNames) + { + string clipPath = Path.Combine(path, clipName); + if (!File.Exists(clipPath)) + { + // read the clip data from embedded resources + byte[] clipData = null; + string resourceName = "PropUndoButton.SFX." + clipName; + using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) + { + clipData = new byte[stream.Length]; + stream.Read(clipData, 0, clipData.Length); + } + + // write the clip data to the file + using (FileStream fileStream = new FileStream(clipPath, FileMode.CreateNew)) + { + fileStream.Write(clipData, 0, clipData.Length); + } + + LoggerInstance.Msg("Placed missing sfx in audio folder: " + clipName); + } + } + } + + private static void OnUpdateInput() + { + if (Input.GetKeyDown(KeyCode.Z)) + { + DeleteLatestSpawnable(); + } + } + + private static void OnSpawnProp() + { + if (!EntryEnabled.Value) return; + + if (!MetaPort.Instance.worldAllowProps || !MetaPort.Instance.settings.GetSettingsBool("ContentFilterPropsEnabled", false)) + { + PlayAudioModule(sfx_warn); + return; + } + + if (GetAllProps().Count >= 20) + { + PlayAudioModule(sfx_warn); + return; + } + + PlayAudioModule(sfx_spawn); + } + + private static void DeleteLatestSpawnable() + { + if (!EntryEnabled.Value) return; + + var propData = GetLatestProp(); + + if (propData == null) + { + PlayAudioModule(sfx_warn); + return; + } + + if (propData.Spawnable == null) + { + propData.Recycle(); + // what should i do here? + return; + } + + propData.Spawnable.Delete(); + PlayAudioModule(sfx_undo); + } + + private static void PlayAudioModule(string module) + { + if (!EntryUseSFX.Value) return; + InterfaceAudio.PlayModule(module); + } + + private static CVRSyncHelper.PropData GetLatestProp() + { + // should already be sorted by spawn order + return CVRSyncHelper.Props.LastOrDefault((CVRSyncHelper.PropData match) => match.SpawnedBy == MetaPort.Instance.ownerId); + } + + private static List GetAllProps() + { + // im not storing the count because there is good chance itll desync from server + return CVRSyncHelper.Props.FindAll((CVRSyncHelper.PropData match) => match.SpawnedBy == MetaPort.Instance.ownerId); + } +} \ No newline at end of file diff --git a/PropUndoButton/PropUndoButton.csproj b/PropUndoButton/PropUndoButton.csproj new file mode 100644 index 0000000..fda9805 --- /dev/null +++ b/PropUndoButton/PropUndoButton.csproj @@ -0,0 +1,50 @@ + + + + + net472 + enable + latest + false + True + + + + + + + + + + + + + + + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\0Harmony.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll + + + + + + + + + diff --git a/PropUndoButton/PropUndoButton.sln b/PropUndoButton/PropUndoButton.sln new file mode 100644 index 0000000..0d15d70 --- /dev/null +++ b/PropUndoButton/PropUndoButton.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32630.192 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PropUndoButton", "PropUndoButton.csproj", "{240E33F2-E4DD-458D-8E79-96073872CE65}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {240E33F2-E4DD-458D-8E79-96073872CE65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {240E33F2-E4DD-458D-8E79-96073872CE65}.Debug|Any CPU.Build.0 = Debug|Any CPU + {240E33F2-E4DD-458D-8E79-96073872CE65}.Release|Any CPU.ActiveCfg = Release|Any CPU + {240E33F2-E4DD-458D-8E79-96073872CE65}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C8F281CB-C5D8-4C4B-A7F6-9F1702C436EB} + EndGlobalSection +EndGlobal diff --git a/PropUndoButton/Properties/AssemblyInfo.cs b/PropUndoButton/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..0249734 --- /dev/null +++ b/PropUndoButton/Properties/AssemblyInfo.cs @@ -0,0 +1,32 @@ +using NAK.Melons.UndoPropButton.Properties; +using MelonLoader; +using System.Reflection; + + +[assembly: AssemblyVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyTitle(nameof(NAK.Melons.UndoPropButton))] +[assembly: AssemblyCompany(AssemblyInfoParams.Author)] +[assembly: AssemblyProduct(nameof(NAK.Melons.UndoPropButton))] + +[assembly: MelonInfo( + typeof(NAK.Melons.UndoPropButton.PropUndoButton), + nameof(NAK.Melons.UndoPropButton), + AssemblyInfoParams.Version, + AssemblyInfoParams.Author, + downloadLink: "https://github.com/NotAKidOnSteam/UndoPropButton" +)] + +[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")] +[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] +[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)] +[assembly: MelonOptionalDependencies("BTKUILib")] +[assembly: HarmonyDontPatchAll] + +namespace NAK.Melons.UndoPropButton.Properties; +internal static class AssemblyInfoParams +{ + public const string Version = "1.0.0"; + public const string Author = "NotAKidoS"; +} \ No newline at end of file diff --git a/PropUndoButton/SFX/sfx_spawn.wav b/PropUndoButton/SFX/sfx_spawn.wav new file mode 100644 index 0000000000000000000000000000000000000000..069a4789a2f72c8bfd66b09f9faf9c6d5fbd49d0 GIT binary patch literal 15476 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 literal 0 HcmV?d00001 diff --git a/PropUndoButton/SFX/sfx_warn.wav b/PropUndoButton/SFX/sfx_warn.wav new file mode 100644 index 0000000000000000000000000000000000000000..d27b30a451056551de1b0a0d0022fb835645bbc1 GIT binary patch literal 12684 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 K5Gz_FO#cT(1n5Bk literal 0 HcmV?d00001 diff --git a/PropUndoButton/format.json b/PropUndoButton/format.json new file mode 100644 index 0000000..b243e12 --- /dev/null +++ b/PropUndoButton/format.json @@ -0,0 +1,23 @@ +{ + "_id": -1, + "name": "PropUndoButton", + "modversion": "1.0.0", + "gameversion": "2022r170", + "loaderversion": "0.5.7", + "modtype": "Mod", + "author": "NotAKidoS", + "description": "Press Z to undo latest spawned prop. Includes SFX for prop spawn, undo, and warning, which can be disabled in settings.", + "searchtags": [ + "prop", + "undo", + "bind", + "button" + ], + "requirements": [ + "None" + ], + "downloadlink": "https://github.com/NotAKidOnSteam/PropUndoButton/releases/download/v1.0.0/PropUndoButton.dll", + "sourcelink": "https://github.com/NotAKidOnSteam/PropUndoButton/", + "changelog": "- Initial Release", + "embedcolor": "#00FFFF" +} \ No newline at end of file From 471fb940968ff184c25dbd058e24ecad972c2ab6 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:36:58 -0500 Subject: [PATCH 03/23] Update README.md --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c7c9708..fac1fef 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,16 @@ # PropUndoButton - press z to undo prop + +Press Z to undo latest spawned prop. Includes optional SFX for prop spawn, undo, and warning, which can be disabled in settings. + +You can replace the sfx in `"ChilloutVR\ChilloutVR_Data\StreamingAssets\Cohtml\UIResources\GameUI\mods\PropUndo\audio"`. + +--- + +Here is the block of text where I tell you this mod is not affiliated or endorsed by ABI. +https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games + +> This mod is an independent creation and is not affiliated with, supported by or approved by Alpha Blend Interactive. + +> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use. + +> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive. From bf5ca8f82354f9dd048f6f0207a1a46696c1ccd7 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:40:48 -0500 Subject: [PATCH 04/23] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fac1fef..343c678 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ Press Z to undo latest spawned prop. Includes optional SFX for prop spawn, undo, and warning, which can be disabled in settings. You can replace the sfx in `"ChilloutVR\ChilloutVR_Data\StreamingAssets\Cohtml\UIResources\GameUI\mods\PropUndo\audio"`. + +https://user-images.githubusercontent.com/37721153/231351589-07f794f3-f542-4cb4-b034-5c1902f86758.mp4 --- From c02b74b13bbce18df8fb39f8caccf0f47797c672 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:45:07 -0500 Subject: [PATCH 05/23] Update format.json --- PropUndoButton/format.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PropUndoButton/format.json b/PropUndoButton/format.json index b243e12..fa4d906 100644 --- a/PropUndoButton/format.json +++ b/PropUndoButton/format.json @@ -6,7 +6,7 @@ "loaderversion": "0.5.7", "modtype": "Mod", "author": "NotAKidoS", - "description": "Press Z to undo latest spawned prop. Includes SFX for prop spawn, undo, and warning, which can be disabled in settings.", + "description": "Press Z to undo latest spawned prop. Includes optional SFX for prop spawn, undo, and warning, which can be disabled in settings.\n\nYou can replace the sfx in 'ChilloutVR\\ChilloutVR_Data\\StreamingAssets\\Cohtml\\UIResources\\GameUI\\mods\\PropUndo\\audio'.", "searchtags": [ "prop", "undo", From d87d4487aae8a7e6c411ef73826f6a0aa668e0b2 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:47:42 -0500 Subject: [PATCH 06/23] fix name --- PropUndoButton/Main.cs | 2 +- PropUndoButton/Properties/AssemblyInfo.cs | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index 2d8bb3e..105616a 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -5,7 +5,7 @@ using MelonLoader; using System.Reflection; using UnityEngine; -namespace NAK.Melons.UndoPropButton; +namespace NAK.Melons.PropUndoButton; // https://pixabay.com/sound-effects/selection-sounds-73225/ diff --git a/PropUndoButton/Properties/AssemblyInfo.cs b/PropUndoButton/Properties/AssemblyInfo.cs index 0249734..fc06330 100644 --- a/PropUndoButton/Properties/AssemblyInfo.cs +++ b/PropUndoButton/Properties/AssemblyInfo.cs @@ -1,18 +1,17 @@ -using NAK.Melons.UndoPropButton.Properties; +using NAK.Melons.PropUndoButton.Properties; using MelonLoader; using System.Reflection; - [assembly: AssemblyVersion(AssemblyInfoParams.Version)] [assembly: AssemblyFileVersion(AssemblyInfoParams.Version)] [assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)] -[assembly: AssemblyTitle(nameof(NAK.Melons.UndoPropButton))] +[assembly: AssemblyTitle(nameof(NAK.Melons.PropUndoButton))] [assembly: AssemblyCompany(AssemblyInfoParams.Author)] -[assembly: AssemblyProduct(nameof(NAK.Melons.UndoPropButton))] +[assembly: AssemblyProduct(nameof(NAK.Melons.PropUndoButton))] [assembly: MelonInfo( - typeof(NAK.Melons.UndoPropButton.PropUndoButton), - nameof(NAK.Melons.UndoPropButton), + typeof(NAK.Melons.PropUndoButton.PropUndoButton), + nameof(NAK.Melons.PropUndoButton), AssemblyInfoParams.Version, AssemblyInfoParams.Author, downloadLink: "https://github.com/NotAKidOnSteam/UndoPropButton" @@ -24,7 +23,7 @@ using System.Reflection; [assembly: MelonOptionalDependencies("BTKUILib")] [assembly: HarmonyDontPatchAll] -namespace NAK.Melons.UndoPropButton.Properties; +namespace NAK.Melons.PropUndoButton.Properties; internal static class AssemblyInfoParams { public const string Version = "1.0.0"; From 2c029b1452a6b47db8fdde8dbee144ddfb3d720f Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Wed, 12 Apr 2023 03:06:46 -0500 Subject: [PATCH 07/23] add redo button --- PropUndoButton/Main.cs | 141 ++++++++++++++++++++-- PropUndoButton/PropUndoButton.csproj | 5 + PropUndoButton/Properties/AssemblyInfo.cs | 3 +- PropUndoButton/SFX/sfx_redo.wav | Bin 0 -> 14464 bytes PropUndoButton/format.json | 6 +- 5 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 PropUndoButton/SFX/sfx_redo.wav diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index 105616a..7dc2791 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -1,6 +1,9 @@ using ABI_RC.Core.AudioEffects; +using ABI_RC.Core.Networking; using ABI_RC.Core.Savior; +using ABI_RC.Core.UI; using ABI_RC.Core.Util; +using DarkRift; using MelonLoader; using System.Reflection; using UnityEngine; @@ -11,6 +14,8 @@ namespace NAK.Melons.PropUndoButton; public class PropUndoButton : MelonMod { + public static List deletedProps = new List(); + private static readonly MelonPreferences_Category Category = MelonPreferences.CreateCategory(nameof(PropUndoButton)); @@ -23,19 +28,22 @@ public class PropUndoButton : MelonMod // audio clip names, InterfaceAudio adds "PropUndo_" prefix public const string sfx_spawn = "PropUndo_sfx_spawn"; public const string sfx_undo = "PropUndo_sfx_undo"; + public const string sfx_redo = "PropUndo_sfx_redo"; public const string sfx_warn = "PropUndo_sfx_warn"; public override void OnInitializeMelon() { HarmonyInstance.Patch( // prop spawn sfx typeof(CVRSyncHelper).GetMethod(nameof(CVRSyncHelper.SpawnProp)), - null, - new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnSpawnProp), BindingFlags.NonPublic | BindingFlags.Static)) + postfix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnSpawnProp), BindingFlags.NonPublic | BindingFlags.Static)) + ); + HarmonyInstance.Patch( // prop delete sfx + typeof(CVRSyncHelper).GetMethod(nameof(CVRSyncHelper.DeletePropByInstanceId)), + postfix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnDeletePropByInstanceId), BindingFlags.NonPublic | BindingFlags.Static)) ); HarmonyInstance.Patch( // desktop input patch so we don't run in menus/gui typeof(InputModuleMouseKeyboard).GetMethod(nameof(InputModuleMouseKeyboard.UpdateInput)), - null, - new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnUpdateInput), BindingFlags.NonPublic | BindingFlags.Static)) + postfix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnUpdateInput), BindingFlags.NonPublic | BindingFlags.Static)) ); SetupDefaultAudioClips(); } @@ -51,7 +59,7 @@ public class PropUndoButton : MelonMod } // copy embedded resources to this folder if they do not exist - string[] clipNames = { "sfx_spawn.wav", "sfx_undo.wav", "sfx_warn.wav" }; + string[] clipNames = { "sfx_spawn.wav", "sfx_undo.wav", "sfx_redo.wav", "sfx_warn.wav" }; foreach (string clipName in clipNames) { string clipPath = Path.Combine(path, clipName); @@ -79,9 +87,16 @@ public class PropUndoButton : MelonMod private static void OnUpdateInput() { - if (Input.GetKeyDown(KeyCode.Z)) + if (Input.GetKey(KeyCode.LeftControl)) { - DeleteLatestSpawnable(); + if (Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.Z)) + { + RedoProp(); + } + else if (Input.GetKeyDown(KeyCode.Z)) + { + UndoProp(); + } } } @@ -95,7 +110,8 @@ public class PropUndoButton : MelonMod return; } - if (GetAllProps().Count >= 20) + // might need to touch + if (IsAtPropLimit()) { PlayAudioModule(sfx_warn); return; @@ -104,12 +120,26 @@ public class PropUndoButton : MelonMod PlayAudioModule(sfx_spawn); } - private static void DeleteLatestSpawnable() + private static void OnDeletePropByInstanceId(string instanceId) + { + if (string.IsNullOrEmpty(instanceId)) return; + + CVRSyncHelper.PropData propData = GetPropByInstanceId(instanceId); + if (propData == null) return; + + // Add the spawned prop to the history of deleted props + if (deletedProps.Count >= 5) deletedProps.RemoveAt(0); // Remove the oldest item + DeletedProp deletedProp = new DeletedProp(propData.ObjectId, propData.Spawnable.transform.position, propData.Spawnable.transform.rotation); + deletedProps.Add(deletedProp); + + PlayAudioModule(sfx_undo); + } + + private static void UndoProp() { if (!EntryEnabled.Value) return; var propData = GetLatestProp(); - if (propData == null) { PlayAudioModule(sfx_warn); @@ -124,15 +154,86 @@ public class PropUndoButton : MelonMod } propData.Spawnable.Delete(); - PlayAudioModule(sfx_undo); } - private static void PlayAudioModule(string module) + public static void RedoProp() + { + int index = deletedProps.Count - 1; + if (index < 0 || index >= deletedProps.Count || IsAtPropLimit()) + { + PlayAudioModule(sfx_warn); + return; + } + + DeletedProp deletedProp = deletedProps[index]; + if (Time.time - deletedProp.timeDeleted <= 60) // only allow redo of prop spawned in last minute + { + if (AttemptRedoProp(deletedProp.propGuid, deletedProp.position, deletedProp.rotation)) + { + deletedProps.RemoveAt(index); + PlayAudioModule(sfx_redo); + return; + } + } + + PlayAudioModule(sfx_warn); + } + + // original spawn prop method does not let you specify rotation + public static bool AttemptRedoProp(string propGuid, Vector3 position, Quaternion quaternion) + { + if (MetaPort.Instance.worldAllowProps + && MetaPort.Instance.settings.GetSettingsBool("ContentFilterPropsEnabled", false) + && NetworkManager.Instance.GameNetwork.ConnectionState == ConnectionState.Connected) + { + using (DarkRiftWriter darkRiftWriter = DarkRiftWriter.Create()) + { + darkRiftWriter.Write(propGuid); + darkRiftWriter.Write(position.x); + darkRiftWriter.Write(position.y); + darkRiftWriter.Write(position.z); + darkRiftWriter.Write(0f); + darkRiftWriter.Write(quaternion.eulerAngles.y); + darkRiftWriter.Write(0f); + darkRiftWriter.Write(1f); + darkRiftWriter.Write(1f); + darkRiftWriter.Write(1f); + darkRiftWriter.Write(0f); + using (Message message = Message.Create(10050, darkRiftWriter)) + { + NetworkManager.Instance.GameNetwork.SendMessage(message, SendMode.Reliable); + } + return true; + } + } + else + { + if (!MetaPort.Instance.worldAllowProps) + { + CohtmlHud.Instance.ViewDropText("Props are not allowed in this world", ""); + } + return false; + } + } + + public static void PlayAudioModule(string module) { if (!EntryUseSFX.Value) return; InterfaceAudio.PlayModule(module); } + public static bool IsAtPropLimit() + { + // might need rework + return GetAllProps().Count >= 20; + } + + private static CVRSyncHelper.PropData GetPropByInstanceId(string instanceId) + { + // find prop by instance id and if it is ours + return CVRSyncHelper.Props.Find((CVRSyncHelper.PropData match) => (match.InstanceId == instanceId && match.SpawnedBy == MetaPort.Instance.ownerId)); + } + private static CVRSyncHelper.PropData GetLatestProp() { // should already be sorted by spawn order @@ -144,4 +245,20 @@ public class PropUndoButton : MelonMod // im not storing the count because there is good chance itll desync from server return CVRSyncHelper.Props.FindAll((CVRSyncHelper.PropData match) => match.SpawnedBy == MetaPort.Instance.ownerId); } + + public class DeletedProp + { + public string propGuid; + public Vector3 position; + public Quaternion rotation; + public float timeDeleted; + + public DeletedProp(string propGuid, Vector3 position, Quaternion rotation) + { + this.propGuid = propGuid; + this.position = position; + this.rotation = rotation; + this.timeDeleted = Time.time; + } + } } \ No newline at end of file diff --git a/PropUndoButton/PropUndoButton.csproj b/PropUndoButton/PropUndoButton.csproj index fda9805..e6a31c9 100644 --- a/PropUndoButton/PropUndoButton.csproj +++ b/PropUndoButton/PropUndoButton.csproj @@ -10,12 +10,14 @@ + + @@ -31,6 +33,9 @@ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll + + ..\..\..\_ManagedLibs\DarkRift.dll + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll diff --git a/PropUndoButton/Properties/AssemblyInfo.cs b/PropUndoButton/Properties/AssemblyInfo.cs index fc06330..a20c993 100644 --- a/PropUndoButton/Properties/AssemblyInfo.cs +++ b/PropUndoButton/Properties/AssemblyInfo.cs @@ -20,12 +20,11 @@ using System.Reflection; [assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")] [assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] [assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)] -[assembly: MelonOptionalDependencies("BTKUILib")] [assembly: HarmonyDontPatchAll] namespace NAK.Melons.PropUndoButton.Properties; internal static class AssemblyInfoParams { - public const string Version = "1.0.0"; + public const string Version = "1.0.1"; public const string Author = "NotAKidoS"; } \ No newline at end of file diff --git a/PropUndoButton/SFX/sfx_redo.wav b/PropUndoButton/SFX/sfx_redo.wav new file mode 100644 index 0000000000000000000000000000000000000000..cdc632a44ff1576ad9139ea8baaf87bef6b47ab7 GIT binary patch literal 14464 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 Date: Wed, 12 Apr 2023 03:25:45 -0500 Subject: [PATCH 08/23] clear redo list on world change --- PropUndoButton/Main.cs | 14 ++++++++++++-- PropUndoButton/PropUndoButton.csproj | 14 +++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index 7dc2791..d3f1506 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -1,4 +1,5 @@ -using ABI_RC.Core.AudioEffects; +using ABI.CCK.Components; +using ABI_RC.Core.AudioEffects; using ABI_RC.Core.Networking; using ABI_RC.Core.Savior; using ABI_RC.Core.UI; @@ -37,7 +38,7 @@ public class PropUndoButton : MelonMod typeof(CVRSyncHelper).GetMethod(nameof(CVRSyncHelper.SpawnProp)), postfix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnSpawnProp), BindingFlags.NonPublic | BindingFlags.Static)) ); - HarmonyInstance.Patch( // prop delete sfx + HarmonyInstance.Patch( // prop delete sfx, log for possible redo typeof(CVRSyncHelper).GetMethod(nameof(CVRSyncHelper.DeletePropByInstanceId)), postfix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnDeletePropByInstanceId), BindingFlags.NonPublic | BindingFlags.Static)) ); @@ -45,6 +46,10 @@ public class PropUndoButton : MelonMod typeof(InputModuleMouseKeyboard).GetMethod(nameof(InputModuleMouseKeyboard.UpdateInput)), postfix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnUpdateInput), BindingFlags.NonPublic | BindingFlags.Static)) ); + HarmonyInstance.Patch( // clear redo list on world change + typeof(CVRWorld).GetMethod(nameof(CVRWorld.ConfigureWorld)), + postfix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnWorldLoad), BindingFlags.NonPublic | BindingFlags.Static)) + ); SetupDefaultAudioClips(); } @@ -135,6 +140,11 @@ public class PropUndoButton : MelonMod PlayAudioModule(sfx_undo); } + private static void OnWorldLoad() + { + deletedProps.Clear(); + } + private static void UndoProp() { if (!EntryEnabled.Value) return; diff --git a/PropUndoButton/PropUndoButton.csproj b/PropUndoButton/PropUndoButton.csproj index e6a31c9..3b1889c 100644 --- a/PropUndoButton/PropUndoButton.csproj +++ b/PropUndoButton/PropUndoButton.csproj @@ -25,25 +25,25 @@ - C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\0Harmony.dll + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\0Harmony.dll - C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Assembly-CSharp.dll - C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\Assembly-CSharp-firstpass.dll - ..\..\..\_ManagedLibs\DarkRift.dll + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\DarkRift.dll - C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\MelonLoader.dll - C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.CoreModule.dll - C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll + C:\Users\krist\Documents\GitHub\_ChilloutVR Modding\_ManagedLibs\UnityEngine.InputLegacyModule.dll From a202f6f9878f0b27b60cd6c5a02f6e49bc9f285f Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:39:50 -0500 Subject: [PATCH 09/23] fix up redo --- PropUndoButton/Main.cs | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index d3f1506..db3ff1f 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -32,8 +32,15 @@ public class PropUndoButton : MelonMod public const string sfx_redo = "PropUndo_sfx_redo"; public const string sfx_warn = "PropUndo_sfx_warn"; + public const int redoHistoryLimit = 5; // amount that can be in history at once + public const int redoTimeoutLimit = 60; // seconds + public override void OnInitializeMelon() { + HarmonyInstance.Patch( // delete all props in reverse order for redo + typeof(CVRSyncHelper).GetMethod(nameof(CVRSyncHelper.DeleteMyProps)), + prefix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnDeleteMyProps), BindingFlags.NonPublic | BindingFlags.Static)) + ); HarmonyInstance.Patch( // prop spawn sfx typeof(CVRSyncHelper).GetMethod(nameof(CVRSyncHelper.SpawnProp)), postfix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnSpawnProp), BindingFlags.NonPublic | BindingFlags.Static)) @@ -109,7 +116,9 @@ public class PropUndoButton : MelonMod { if (!EntryEnabled.Value) return; - if (!MetaPort.Instance.worldAllowProps || !MetaPort.Instance.settings.GetSettingsBool("ContentFilterPropsEnabled", false)) + if (!MetaPort.Instance.worldAllowProps + || !MetaPort.Instance.settings.GetSettingsBool("ContentFilterPropsEnabled", false) + || NetworkManager.Instance.GameNetwork.ConnectionState != ConnectionState.Connected) { PlayAudioModule(sfx_warn); return; @@ -133,7 +142,7 @@ public class PropUndoButton : MelonMod if (propData == null) return; // Add the spawned prop to the history of deleted props - if (deletedProps.Count >= 5) deletedProps.RemoveAt(0); // Remove the oldest item + if (deletedProps.Count >= redoHistoryLimit) deletedProps.RemoveAt(0); // Remove the oldest item DeletedProp deletedProp = new DeletedProp(propData.ObjectId, propData.Spawnable.transform.position, propData.Spawnable.transform.rotation); deletedProps.Add(deletedProp); @@ -145,6 +154,27 @@ public class PropUndoButton : MelonMod deletedProps.Clear(); } + // delete in reverse order for undo to work as expected + private static bool OnDeleteMyProps() + { + List propsList = GetAllProps(); + + for (int i = propsList.Count - 1; i >= 0; i--) + { + CVRSyncHelper.PropData propData = propsList[i]; + + if (propData.Spawnable == null) + { + propData.Recycle(); + continue; + } + + propData.Spawnable.Delete(); + } + + return false; + } + private static void UndoProp() { if (!EntryEnabled.Value) return; @@ -176,7 +206,7 @@ public class PropUndoButton : MelonMod } DeletedProp deletedProp = deletedProps[index]; - if (Time.time - deletedProp.timeDeleted <= 60) // only allow redo of prop spawned in last minute + if (Time.time - deletedProp.timeDeleted <= redoTimeoutLimit) // only allow redo of prop spawned in last minute { if (AttemptRedoProp(deletedProp.propGuid, deletedProp.position, deletedProp.rotation)) { From 652348157afbff61f4fed595c3a8cb17788744fa Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Wed, 12 Apr 2023 15:36:37 -0500 Subject: [PATCH 10/23] add spawn height offset --- PropUndoButton/Main.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index db3ff1f..d31b5dc 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -143,7 +143,12 @@ public class PropUndoButton : MelonMod // Add the spawned prop to the history of deleted props if (deletedProps.Count >= redoHistoryLimit) deletedProps.RemoveAt(0); // Remove the oldest item - DeletedProp deletedProp = new DeletedProp(propData.ObjectId, propData.Spawnable.transform.position, propData.Spawnable.transform.rotation); + + // offset spawn height so game can account for it later + Vector3 position = propData.Spawnable.transform.position; + position.y -= propData.Spawnable.spawnHeight; + + DeletedProp deletedProp = new DeletedProp(propData.ObjectId, position, propData.Spawnable.transform.rotation); deletedProps.Add(deletedProp); PlayAudioModule(sfx_undo); From e2121e4535ee08980b96070ca1f95aa63515661c Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Wed, 12 Apr 2023 15:48:32 -0500 Subject: [PATCH 11/23] touch up limits --- PropUndoButton/Main.cs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index d31b5dc..20a8609 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -32,9 +32,9 @@ public class PropUndoButton : MelonMod public const string sfx_redo = "PropUndo_sfx_redo"; public const string sfx_warn = "PropUndo_sfx_warn"; - public const int redoHistoryLimit = 5; // amount that can be in history at once - public const int redoTimeoutLimit = 60; // seconds - + public const int redoHistoryLimit = 20; // amount that can be in history at once + public const int redoTimeoutLimit = 120; // seconds + public override void OnInitializeMelon() { HarmonyInstance.Patch( // delete all props in reverse order for redo @@ -144,11 +144,7 @@ public class PropUndoButton : MelonMod // Add the spawned prop to the history of deleted props if (deletedProps.Count >= redoHistoryLimit) deletedProps.RemoveAt(0); // Remove the oldest item - // offset spawn height so game can account for it later - Vector3 position = propData.Spawnable.transform.position; - position.y -= propData.Spawnable.spawnHeight; - - DeletedProp deletedProp = new DeletedProp(propData.ObjectId, position, propData.Spawnable.transform.rotation); + DeletedProp deletedProp = new DeletedProp(propData); deletedProps.Add(deletedProp); PlayAudioModule(sfx_undo); @@ -298,12 +294,17 @@ public class PropUndoButton : MelonMod public Quaternion rotation; public float timeDeleted; - public DeletedProp(string propGuid, Vector3 position, Quaternion rotation) + public DeletedProp(CVRSyncHelper.PropData propData) { - this.propGuid = propGuid; + // Offset spawn height so game can account for it later + Transform spawnable = propData.Spawnable.transform; + Vector3 position = spawnable.position; + position.y -= propData.Spawnable.spawnHeight; + + propGuid = propData.ObjectId; this.position = position; - this.rotation = rotation; - this.timeDeleted = Time.time; + rotation = spawnable.rotation; + timeDeleted = Time.time; } } } \ No newline at end of file From 01a336d8817337f9ad94c96580ee4d6c094481f4 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 16:30:07 -0500 Subject: [PATCH 12/23] cleanup, disable sfx by default, adjust volume Cleaned up code & disabled SFX by default. Also adjusted the preceived volume of the sfx clips in audacity to hopefully be equal to the existing UI sounds. --- PropUndoButton/Main.cs | 140 ++++++++++++++----------------- PropUndoButton/SFX/sfx_redo.wav | Bin 14464 -> 14464 bytes PropUndoButton/SFX/sfx_spawn.wav | Bin 15476 -> 15476 bytes PropUndoButton/SFX/sfx_undo.wav | Bin 12496 -> 12496 bytes PropUndoButton/SFX/sfx_warn.wav | Bin 12684 -> 12684 bytes 5 files changed, 64 insertions(+), 76 deletions(-) diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index 20a8609..9498515 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -2,7 +2,6 @@ using ABI_RC.Core.AudioEffects; using ABI_RC.Core.Networking; using ABI_RC.Core.Savior; -using ABI_RC.Core.UI; using ABI_RC.Core.Util; using DarkRift; using MelonLoader; @@ -24,7 +23,7 @@ public class PropUndoButton : MelonMod Category.CreateEntry("Enabled", true, description: "Toggle Undo Prop Button."); public static readonly MelonPreferences_Entry EntryUseSFX = - Category.CreateEntry("Use SFX", true, description: "Enable or disable undo SFX."); + Category.CreateEntry("Use SFX", false, description: "Toggle audio queues for prop spawn, undo, redo, or warning."); // audio clip names, InterfaceAudio adds "PropUndo_" prefix public const string sfx_spawn = "PropUndo_sfx_spawn"; @@ -34,7 +33,7 @@ public class PropUndoButton : MelonMod public const int redoHistoryLimit = 20; // amount that can be in history at once public const int redoTimeoutLimit = 120; // seconds - + public override void OnInitializeMelon() { HarmonyInstance.Patch( // delete all props in reverse order for redo @@ -57,6 +56,7 @@ public class PropUndoButton : MelonMod typeof(CVRWorld).GetMethod(nameof(CVRWorld.ConfigureWorld)), postfix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnWorldLoad), BindingFlags.NonPublic | BindingFlags.Static)) ); + SetupDefaultAudioClips(); } @@ -97,8 +97,12 @@ public class PropUndoButton : MelonMod } } + private static void OnWorldLoad() => deletedProps.Clear(); + private static void OnUpdateInput() { + if (!EntryEnabled.Value) return; + if (Input.GetKey(KeyCode.LeftControl)) { if (Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.Z)) @@ -116,16 +120,7 @@ public class PropUndoButton : MelonMod { if (!EntryEnabled.Value) return; - if (!MetaPort.Instance.worldAllowProps - || !MetaPort.Instance.settings.GetSettingsBool("ContentFilterPropsEnabled", false) - || NetworkManager.Instance.GameNetwork.ConnectionState != ConnectionState.Connected) - { - PlayAudioModule(sfx_warn); - return; - } - - // might need to touch - if (IsAtPropLimit()) + if (!IsPropSpawnAllowed() || IsAtPropLimit()) { PlayAudioModule(sfx_warn); return; @@ -136,29 +131,30 @@ public class PropUndoButton : MelonMod private static void OnDeletePropByInstanceId(string instanceId) { - if (string.IsNullOrEmpty(instanceId)) return; + if (!EntryEnabled.Value || string.IsNullOrEmpty(instanceId)) return; - CVRSyncHelper.PropData propData = GetPropByInstanceId(instanceId); + var propData = GetPropByInstanceIdAndOwnerId(instanceId); if (propData == null) return; - // Add the spawned prop to the history of deleted props - if (deletedProps.Count >= redoHistoryLimit) deletedProps.RemoveAt(0); // Remove the oldest item - - DeletedProp deletedProp = new DeletedProp(propData); - deletedProps.Add(deletedProp); - + AddDeletedProp(propData); PlayAudioModule(sfx_undo); } - private static void OnWorldLoad() + private static void AddDeletedProp(CVRSyncHelper.PropData propData) { - deletedProps.Clear(); + if (deletedProps.Count >= redoHistoryLimit) + deletedProps.RemoveAt(0); + + DeletedProp deletedProp = new DeletedProp(propData); + deletedProps.Add(deletedProp); } // delete in reverse order for undo to work as expected private static bool OnDeleteMyProps() { - List propsList = GetAllProps(); + if (!EntryEnabled.Value) return true; + + List propsList = GetAllPropsByOwnerId(); for (int i = propsList.Count - 1; i >= 0; i--) { @@ -178,9 +174,7 @@ public class PropUndoButton : MelonMod private static void UndoProp() { - if (!EntryEnabled.Value) return; - - var propData = GetLatestProp(); + var propData = GetLatestPropByOwnerId(); if (propData == null) { PlayAudioModule(sfx_warn); @@ -190,7 +184,6 @@ public class PropUndoButton : MelonMod if (propData.Spawnable == null) { propData.Recycle(); - // what should i do here? return; } @@ -206,8 +199,9 @@ public class PropUndoButton : MelonMod return; } + // only allow redo of prop spawned in last minute DeletedProp deletedProp = deletedProps[index]; - if (Time.time - deletedProp.timeDeleted <= redoTimeoutLimit) // only allow redo of prop spawned in last minute + if (Time.time - deletedProp.timeDeleted <= redoTimeoutLimit) { if (AttemptRedoProp(deletedProp.propGuid, deletedProp.position, deletedProp.rotation)) { @@ -221,77 +215,71 @@ public class PropUndoButton : MelonMod } // original spawn prop method does not let you specify rotation - public static bool AttemptRedoProp(string propGuid, Vector3 position, Quaternion quaternion) + public static bool AttemptRedoProp(string propGuid, Vector3 position, Vector3 rotation) { - if (MetaPort.Instance.worldAllowProps - && MetaPort.Instance.settings.GetSettingsBool("ContentFilterPropsEnabled", false) - && NetworkManager.Instance.GameNetwork.ConnectionState == ConnectionState.Connected) + if (!IsPropSpawnAllowed()) return false; + + using (DarkRiftWriter darkRiftWriter = DarkRiftWriter.Create()) { - using (DarkRiftWriter darkRiftWriter = DarkRiftWriter.Create()) + darkRiftWriter.Write(propGuid); + darkRiftWriter.Write(position.x); + darkRiftWriter.Write(position.y); + darkRiftWriter.Write(position.z); + darkRiftWriter.Write(rotation.x); + darkRiftWriter.Write(rotation.y); + darkRiftWriter.Write(rotation.z); + darkRiftWriter.Write(1f); + darkRiftWriter.Write(1f); + darkRiftWriter.Write(1f); + darkRiftWriter.Write(0f); + using (Message message = Message.Create(10050, darkRiftWriter)) { - darkRiftWriter.Write(propGuid); - darkRiftWriter.Write(position.x); - darkRiftWriter.Write(position.y); - darkRiftWriter.Write(position.z); - darkRiftWriter.Write(0f); - darkRiftWriter.Write(quaternion.eulerAngles.y); - darkRiftWriter.Write(0f); - darkRiftWriter.Write(1f); - darkRiftWriter.Write(1f); - darkRiftWriter.Write(1f); - darkRiftWriter.Write(0f); - using (Message message = Message.Create(10050, darkRiftWriter)) - { - NetworkManager.Instance.GameNetwork.SendMessage(message, SendMode.Reliable); - } - return true; + NetworkManager.Instance.GameNetwork.SendMessage(message, SendMode.Reliable); } } - else - { - if (!MetaPort.Instance.worldAllowProps) - { - CohtmlHud.Instance.ViewDropText("Props are not allowed in this world", ""); - } - return false; - } + return true; } public static void PlayAudioModule(string module) { - if (!EntryUseSFX.Value) return; - InterfaceAudio.PlayModule(module); + if (EntryUseSFX.Value) + { + InterfaceAudio.PlayModule(module); + } } - public static bool IsAtPropLimit() + private static bool IsPropSpawnAllowed() { - // might need rework - return GetAllProps().Count >= 20; + return MetaPort.Instance.worldAllowProps + && MetaPort.Instance.settings.GetSettingsBool("ContentFilterPropsEnabled", false) + && NetworkManager.Instance.GameNetwork.ConnectionState == ConnectionState.Connected; } - private static CVRSyncHelper.PropData GetPropByInstanceId(string instanceId) + public static bool IsAtPropLimit(int limit = 20) { - // find prop by instance id and if it is ours - return CVRSyncHelper.Props.Find((CVRSyncHelper.PropData match) => (match.InstanceId == instanceId && match.SpawnedBy == MetaPort.Instance.ownerId)); + return GetAllPropsByOwnerId().Count >= limit; } - private static CVRSyncHelper.PropData GetLatestProp() + private static CVRSyncHelper.PropData GetPropByInstanceIdAndOwnerId(string instanceId) { - // should already be sorted by spawn order - return CVRSyncHelper.Props.LastOrDefault((CVRSyncHelper.PropData match) => match.SpawnedBy == MetaPort.Instance.ownerId); + return CVRSyncHelper.Props.Find(propData => propData.InstanceId == instanceId && propData.SpawnedBy == MetaPort.Instance.ownerId); } - private static List GetAllProps() + private static CVRSyncHelper.PropData GetLatestPropByOwnerId() { - // im not storing the count because there is good chance itll desync from server - return CVRSyncHelper.Props.FindAll((CVRSyncHelper.PropData match) => match.SpawnedBy == MetaPort.Instance.ownerId); + return CVRSyncHelper.Props.LastOrDefault(propData => propData.SpawnedBy == MetaPort.Instance.ownerId); + } + + private static List GetAllPropsByOwnerId() + { + return CVRSyncHelper.Props.FindAll(propData => propData.SpawnedBy == MetaPort.Instance.ownerId); } public class DeletedProp { public string propGuid; public Vector3 position; - public Quaternion rotation; + public Vector3 rotation; public float timeDeleted; public DeletedProp(CVRSyncHelper.PropData propData) @@ -301,10 +289,10 @@ public class PropUndoButton : MelonMod Vector3 position = spawnable.position; position.y -= propData.Spawnable.spawnHeight; - propGuid = propData.ObjectId; + this.propGuid = propData.ObjectId; this.position = position; - rotation = spawnable.rotation; - timeDeleted = Time.time; + this.rotation = spawnable.rotation.eulerAngles; + this.timeDeleted = Time.time; } } } \ No newline at end of file diff --git a/PropUndoButton/SFX/sfx_redo.wav b/PropUndoButton/SFX/sfx_redo.wav index cdc632a44ff1576ad9139ea8baaf87bef6b47ab7..9bc7f673180551e716a6184b524bc865489435a6 100644 GIT binary patch literal 14464 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 LkhA2Qh3WqQ&Sg{2 literal 15476 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 f%qFaZIP2iQZbBOUDT8=Ax(dz4s- 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 diff --git a/PropUndoButton/SFX/sfx_warn.wav b/PropUndoButton/SFX/sfx_warn.wav index d27b30a451056551de1b0a0d0022fb835645bbc1..676c6b94643a4783556c541ca0d49c34c136a632 100644 GIT binary patch literal 12684 zcmZu%3!F{$_W$k2dCr-cW0=7(m{EwUQnzlY2+@OdNu+M_CZzI6@+uTPyd^y(c|>wU z=po{!k}jnviZKsnhIyWubLPDE-oO9)p4IN?e*R~D&e{9y{rj!oTHp0u>-RhRclzJm ztJnNaLJaCQu;=KZYIN25^RAk>DoCR$47zR~wM1`dQ4`vf#0Zz`<8jqLM?*W-3w!WlO9YK5NH@k1 z!lWbjv27+(FS7@$)hPWs-*sC#rL=^ zTh5=X9b*9<^iQ@yAI3*XpvLF{U2X%94YJ+w$B57c~U?~JR&f%&;Gw7kNwvO!+#zP*5Dp`+Lm%;ffBB9d||20 zH@=Fy?7iIzZ5dgO?%6B^-iRF7A*GYfW7N-)K!OqC5p2f59`v`PYyL3`#sjaIyC(5R z`;#lM1IRL);+I7WEVCK^SL7K*n;DKj>|;ym3%!!@gl#rQ5Dz0U68i{TaGw!XiPP|o zZDY@^1Qr+}P6)svAZhEgnFt>)#|>=32wFlHGK8Z9%zzkPurS#Naj@eIl%SdOg4<(c z#>nPBM;LwVS2F78!|`O^GR8?Op&MhcMvgAfM2y%&XhqEN4gK&9ejxAT3BTfmB(!jh z!Kce}+_r^d!am^K_L6H((jr8kM`VA19@=v5!3yT0A!B3>>JFI5_8`MKKFmE>4SVon zmg0zSY$4}^LRA6PK~HGov62z7<3)<;1q?2?1<2qkY(!kZDOeBQV{FtxobeI1V0>XO_9FVrJq7_htkDUKD(zt^c#^(7UmS_Q+pc(ks zM@9p-pfwOP$p_$wJ4tLYF50k9@C`oN`VmhTjTld02(JH$ zK;FU!R65ReMgsU?WavjU88?gpzJL|b4Ijc3CFBNb0FKZGFBn05gBBnPZ*YX47!CJu zmCvD@&wz(THCQKx#K}wa0EeB4*09_~Z`h1B_>Ln!aUCr&l1F%{J+5jZnm~=zB<`TT z!&XP4wMs28BD8^#@D%vj9A++nF+h+l))HD_EwUS9f+?`nNh2dd+!9%cUO?F++=;hF zRyq>b5CNVk*e91rA)9?7jaoSA=p~IV>Zwq_6gp>5VI6FSm#{4v8%Znz>o}v~2hQrr z7u2#);vSfQcARlh86niIL>pWMmtyn{v4|w%3S_{6D8*Bwd#Fk10n5>k`y)4jS(NUh zZgJj%Wy}cVJn{{B0Nm5aAK;KenAoiIlE2W)6^(NRvlMs|Nw5rz$2rD|&>MDz$p+Y6 zPh!xxbuvKrqV!oq_Y8WYTHp@Q3lj?H8IeJ&z z+GK5vK30FsG1f8LIomnMHODo}J<~nOGsSaw*cuf|v9(^Flk zAz#3^+xMyO0p9@M=P941)O#ad-K%-?-DlkETpL}joh_VC=u`Bq>ig>V;;8uC`pjBu ztTl$kM#PH3=fdMc6GNM7*VS&R-d5eBvU%mcOJ81^TlQSp<0TVI^3R_+zqoi=@uZ?B zi#{scUKlP27tAS`RWP|=YQg4$_Y1T_t?=W*U4@T~Mn$-yVRe)0{(-)MHFaz2qM=x5Vq|>ebnI;GQS)K5P@b1V)koD5y+j}E z8tgjbIpev}_YdFnv}tKO{k#0%Wqg}a)u^UXbyj882Tis$c_90r+4;@RH@h*XQ_kWR zOIsXk`D4ost=6_0n>#VLCbvBI(Yz6Pzvi9DyO>v=w=eIDyjgj3^32?L?&#bxxj(i# z-m0MG*_L0oIMQN8&f=V_ns;n|H2X+)pQe4A&S^Ze@w=HDGB-ASui-}xwl{b`eN+1M z)ETL_rrexT>#ldd@7&<*rT5ZHlrm+$oG0_l*5;Ae;n>8;laUtn&FhQmF4TP-_$aWx z`u*z7l^ZITm#->6bn!nI8+NzR4r3#*IYDt@YHV$l*+Pz#m9Kw+@(Qc-D9`|};n zFTC*51+7$+E-71C*7j1~rP}gf`PY?SSMI4M3G5DhT(_(4MCj*GO}ILo9?OVzH@X^+ zSre?4Vww0@-K`$ekLpFvVyARVx9K&!XMN{cJ<50uz8{V1OE%Vi^ zWm)GM|K2#OX?D{F*}m-Z?CR`Q%~m$+*1UW3Q_W8|zal3ur*}@DoQFt8<&4Z}o6|mL zZ}UCPZ)o1R`SxZXHVb7(vfbIvY^AB%G|;%F@$symvL#z~H)n)g1{Q367{ARv!*W!*51c zN3V-tA3tN9G3Huxtt-S8;=js&mGRmHO*kxlsdKrrsk^cJP0!mN(`$O~_x1B_OWmG& zF|8y`^XqmHJ{tn{p3Gf!sD&wL?MWGa~>8x3!CwBZj88#Zjv@VboaGj3~eTZ8WY?*4A+x2HEw zYm!#vEAXvL*^n~QJJhRsT%Jv?b*?VX?#@&CNqx9BQVS_TWwv-uWXN>+p1IMy!{}z5 zjGc)&A-R)x)ZW zSCv&>tejo>Y^A5tU-@mt{))8~?^mp@SW)qO#k`7lNQx_pDzYjYS3X4&sjRP@U-e>D zv+C^X!z6Flyi+qZ@Km6G?E|&<*7d0y9DFD^Av7*Dw|-vz*6@enl1OpHA8QnQAl^Uz znz70_Wu7)$%I5MB@u*m*ysP}Ko>jB;CVEdtFUJJu1m|n66|VQ(8{Hc{>pg3{YrSuz zyq+?`H_F!`^{UiRYJKX;v{h-X(_5ymO<$j$>(B8|@IUE)-@nmcMWQrN8bthIf1SVH zf7XB6|B`=^zqh}azbd^heQNqs>F3f4(;i40khVQ_M{1R?(%074&Nn3G(UeKviQajh zmpre#m%3kZEpyFxKJR?mG0ibjAF21$dTQ6JozzstuV9|IV3k_mnctcFj4zCx@tyJQ zu^q83(aq6=k%N&_;Zxy?`pWt?^;g!94UG+L3~malL0LDsZd%>N+LGEawPS0W)Hbc% zAJ`X|M3~(l7!^D^Fy%ifEqyt@r+kxq>wNF}j`+U!)socvLcUVpC8|Qd`#$mQ^*!sG>g(yd z$5)YZDPOOkcocfDEOrruXP3p}Ona`%nyPVObHm9FE?ADn(?y7O*FAIA)`Ws9~= zJE{Jp8j4ifC|4+bXr6sqPLu1bcdeu5F*9yNjn2lc#*^`hg!jiWcTA7>K+_-SxkaC`8x;3vWT z!7qcw!J=S;P=nANB+Ei8LYG3Np)U2^>UY)etZy4`7k-E2`pET>{gHi4eAfJjb+Z++g4PbXQ$8Uc7wwgf$_1rRS*pIK_9pIBX?5Bv zeTClHajWB7$2X24&LPfHl80UYa-DYl;=0A%)xFxi(j9b%-Pd?Jda!m_?^);B@A=Y` zPg3eB@th?&yT@J>psHvgmbX- zLFa!RM;%=qw>du2cj|uKr%%&nXuqq!s@JJEs7sY4N|mS*cZ$2kdvc95Elm!w9<=tF z2hA(ZT=Qk)Rl|y#@u%XG;uW#-*reFxSST8dE{ZOWwvD!n9*KM#nGu;4xi)f5q&i#^ z-XA^?UKU;)ekMFUJTg2YJTN>cJeLa)^OJNh|xICeTbPPcP_^M2>s&b7{S z&a+Oh%j@dyx`QGx*frbroNJ-$CD&rt%dS^l%V`BS-8IoQ*>$I@hpVM4*Hz=JcJ6lW zaZV>`@4U)++VPv?MaK({){ZM2hx9}GV3Ja;l+c~2nQB~pS$#$Isj2ER!q~55C@X0G zZa}h1z9F+@hJ4dnYqhmnSs$1?%-hXd%Ri0 zLvoVlwm0?F`h)sIdQ-izepoxA&CzCS?X|14U({3TEOiE1k*gk34k;r@bdt4Vt>{Kl zC=28aIZNismU6#!z#40fu~JDsG544w&CzBPGt2z1anx97ETEaP2W7FxI37O{2kuYD zpCRn;rPaU<@uu-6aaY_Kj}jm22)ke`L}&3>O57c99&Z`HDSl&oV0=(~Cdo#U(yp()c9zQspu64lw$#$Ar|B0cUSDeep~x-KhG`?Tj@s2) zy;`U4QTM8|)oJSA)y`^E2`Sqs-eZ)}N{-S(`9=IJ7Km3wS8=PTrQc9nu z&E!wk57sNzVq(u-me)$Lj+sZzrRGX=xH-gZXLc}6BJWY-C*$A7X5&R;k@2MQn9u~qZ?fLE%1Ex1SIDt)yxb}`$&0d5b`b5v1Tj&3KvE&f zMLVUPGK^%6@{V#`IYu?atKLL)ag6$yx`^Zp^>bp{8C9w=sw<7P>$GdM+q5oPf0Bnu zMiOqr=yNoE4$uZ`1GRoyXS&~s+GS`BHG}HFS;~^n)K6#@Sgnp%$EiKk+f~1ssTM2e z6wJlXD$|u-B2NGbsNA8l((QlT!WKY?E>c%g^91RPnueKYqYm4=sb&S^ZPI{nl zoxDkolEbK?y(N#xZ|N7e5Lb(iVg$)zu|#|=z9O8fL@VM>FXc{UGRf=8YUQBvrBXn1 zqaJ;@EbuLwxR|)^s>KpWajXu}V=L)Lt%hVT1rjr260qP*a zv#Z)hZLg-QDQcBcOF45)`B3>tSx7QQ8KvB;+^RHD8YvgVC9-B8W!URtoERx?A`biM z2}7|gmY>K^q%GyY5dX8k2HPY&7-AN2qgd@EJYQGdQWhxll<~?F$^fOGauZ22stTqsMS(ag zz7PkAxo?P>WYt4rptzZAY)lfQXDC0*6SOMYLA7qFd`eD|{YY*g$s#c!XYi>Q)JBZfb2jkg}LhFA}f^r6afC*jqdnM-%3D$h`hNr@OeqzqB|D0eBhDP0t-8JjDa^ia#A z1Sz7YMLu!%fcQ7b5@PO5F^epEgw|_!iocOyJrSm-R0T4h*zt|rMiqIPTqS3cXT#-a z*+=#!Pj8m3$m>k19nuoAnvgh8c>ipjB*eeBzO=ruKBe~#T3P+u`j8OYM!0RDJjb`q z^tprX@3!{Qs^F0I4fQ%A9Mlp69h9`3FgF64Z*PNnRy+hhzuIS0q1?6p_@B#DyWegh>O!oE}Ih zc_i(K=k4k9Z_2gG)pU+yd!=pSdJCl`F*939qxN3KMI4nPAgV>NI4^!7`I=-m#dDKb zPq;1@^ThL16DEjEXC0Rp})` z-DxJ9Qnap=SJV2dv%FQ_O?vN_gJ_iDG~N{XJdOMsS@51*Pu6@Y50RXaztI}v5kX^+FGEqqtsNNtxAzYC;MLY^|m_xtP#BN%i47nn4c8FXeX1#t(_dYvek) zn*3ZuHDjS%Ky%=8w5FROpC)5jz9L_s zH?n;d)zdc#zYUZxTjj?zzwRRejz5r`plVehi)1OS$!ci+jSy$?^xaL*f&HQpS>K58 zZ6#Wh{Eg=5Ys9t0zFyxQklfMbbU7a_vDHZXsQ_By@Hn9$rn-UR*^_q}otaTM#Q-5{6lV9vq2Okxp+f zJt@at0q@jcXTqST+`)w9b>u@e)wMc$myuM_3{pynmrvw~d%`yBll4?e>P z*q1$n0W*#=zW-7LO~bM%8nIK#dxcC`4P9@quMo)`9Quogl) zw8BoPpuHG{c1Czt3HwILeRWuboiXeT@s2z8`LTz{SlBl3ju=}BOYwr`Xa)Nj16XeV zV}>!at>AqV-cjQ{e)PglkBudrlBE~{XV8r^jDwf0A1$~Yd!PL80-_6VfC3`PC}5wB z@r0$U3uEx!6YjDF+?vO>t>Ce+FUkKMVRWHCXg;(GD+Q zgL96OjXPbWw)mDjB9_QG>~Vrk%m}s%BV&INM~nu`u=fg{K*QyFY)1W6KYPc$u}=tp z5NF`SQT=OsW(~5&<`>3ce9(iv=6`U(Kehs_2Ts^wL{>9z*lwGR&!3&d4*ZQ`2e46X0rwG4Xi;d_yd*zO2&^7#fY#I-m=Z8 zEIcOOtN}KRQDW#nKG+McZ@?e=pjsP*_ z2r4>uLk#T-ZRf}3=y29^M3~p`)2_s@6_|6~v9rsrJDlg>6D&hN+h1tqYQ|R? zBbz4}A8l%a+T6qbLOS#*J-cbUDNDPXi}uu`32pMqR`1KPn+AFr$yUXIqAGfC9&sxr?Yl3;vrC`!j!S z+qv>H136n!!O@;)dyYFau@1XNBFF5?#dvU}ZPsJdWGvB=>jEMH8}0aW9kKa(Ii{=u z@rHl!pVtxWKX`~cu$i+5Ex8gT=PR~}ab^p6&H+NU4X~awjk#>c5?VNlwtsYiUdiY} z3y|j=$3583|3PKHm=Sh#?Y8KJ%u3EQsK($D&p(VUXOcZfChcaQV6&aw|NqgRtL=;h z3z##o68`fX$KTj1_5>c;^9HYhct&NUIeNf>Z2;=%0ob`Szs6XTyQ>?dsJ+yoNf zCTBDF!Dw^swe#1G2iIqgG8lpvXEN6>UWM@5GN}jp(K^Wmjv{lA=NVYcYfJXV){Sq; zT9O#>FCS=Uw_w~51-qhQ1m*yHob-xY;5&TcdD7+$;>5Eq@a4F`cCMv%y<;Y^SIH4E z9x!42`G_{mFplr#9Ax{sKPL%4D<8=wvNuwTisxsEdm z%ryHR>LfA7iIS)9?ZAMx0{{Ugbqw)X% literal 12684 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 K5Gz_FO#cT(1n5Bk From b6d061e74096b00c9fdc0c463b86631095d5f3ad Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 17:52:16 -0500 Subject: [PATCH 13/23] lower volume even more, fix prop ghosts --- PropUndoButton/Main.cs | 42 ++++++++++++++++++++----------- PropUndoButton/SFX/sfx_redo.wav | Bin 14464 -> 14464 bytes PropUndoButton/SFX/sfx_spawn.wav | Bin 15476 -> 15476 bytes PropUndoButton/SFX/sfx_undo.wav | Bin 12496 -> 12496 bytes PropUndoButton/SFX/sfx_warn.wav | Bin 12684 -> 12684 bytes 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index 9498515..c831b1a 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -159,14 +159,7 @@ public class PropUndoButton : MelonMod for (int i = propsList.Count - 1; i >= 0; i--) { CVRSyncHelper.PropData propData = propsList[i]; - - if (propData.Spawnable == null) - { - propData.Recycle(); - continue; - } - - propData.Spawnable.Delete(); + SafeDeleteProp(propData); } return false; @@ -181,13 +174,7 @@ public class PropUndoButton : MelonMod return; } - if (propData.Spawnable == null) - { - propData.Recycle(); - return; - } - - propData.Spawnable.Delete(); + SafeDeleteProp(propData); } public static void RedoProp() @@ -248,6 +235,31 @@ public class PropUndoButton : MelonMod } } + private static void SafeDeleteProp(CVRSyncHelper.PropData propData) + { + //fixes getting props stuck in limbo state if spawn & delete fast + if (propData.Spawnable == null && propData.Wrapper != null) + { + UnityEngine.Object.DestroyImmediate(propData.Wrapper); + propData.Recycle(); + } + else if (propData.Spawnable != null) + { + propData.Spawnable.Delete(); + } + + //if an undo attempt is made right after spawning a prop, the + //spawnable & wrapper will both be null, so the delete request + //will be ignored- same with Delete All button in Menu now + + //so the bug causing props to get stuck is due to the propData + //being wiped before the prop spawnable & wrapper were created + + //i am unsure if i should attempt an undo of second in line prop, + //just in case some issue happens and causes the mod to lock up here. + //It should be fine though, as reloading world should clear propData...? + } + private static bool IsPropSpawnAllowed() { return MetaPort.Instance.worldAllowProps diff --git a/PropUndoButton/SFX/sfx_redo.wav b/PropUndoButton/SFX/sfx_redo.wav index 9bc7f673180551e716a6184b524bc865489435a6..41bb0cf72db44033d546c49546cc8a443e22bd3c 100644 GIT binary patch literal 14464 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 KC1da!ZTueu5~L3R literal 14464 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 LkhA2Qh3WqQ&Sg{2 diff --git a/PropUndoButton/SFX/sfx_undo.wav b/PropUndoButton/SFX/sfx_undo.wav index bd47619f2a1993b5fd68c27b5a3b4ab83ca75571..84f0cf76689a522d2f107897a4e300517cbb7d4b 100644 GIT binary patch literal 12496 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 literal 12496 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

cNnw)kn%~ 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 From e94cc78dfa2eef914af14307ee087802fc67bbed Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 18:00:43 -0500 Subject: [PATCH 14/23] add more sound queues --- PropUndoButton/Main.cs | 13 ++++++++++++- PropUndoButton/PropUndoButton.csproj | 2 ++ PropUndoButton/SFX/sfx_deny.wav | Bin 0 -> 12496 bytes 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 PropUndoButton/SFX/sfx_deny.wav diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index c831b1a..5ab8ddc 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -30,6 +30,7 @@ public class PropUndoButton : MelonMod public const string sfx_undo = "PropUndo_sfx_undo"; public const string sfx_redo = "PropUndo_sfx_redo"; public const string sfx_warn = "PropUndo_sfx_warn"; + public const string sfx_deny = "PropUndo_sfx_deny"; public const int redoHistoryLimit = 20; // amount that can be in history at once public const int redoTimeoutLimit = 120; // seconds @@ -71,7 +72,7 @@ public class PropUndoButton : MelonMod } // copy embedded resources to this folder if they do not exist - string[] clipNames = { "sfx_spawn.wav", "sfx_undo.wav", "sfx_redo.wav", "sfx_warn.wav" }; + string[] clipNames = { "sfx_spawn.wav", "sfx_undo.wav", "sfx_redo.wav", "sfx_warn.wav", "sfx_deny.wav" }; foreach (string clipName in clipNames) { string clipPath = Path.Combine(path, clipName); @@ -156,6 +157,12 @@ public class PropUndoButton : MelonMod List propsList = GetAllPropsByOwnerId(); + if (propsList.Count == 0) + { + PlayAudioModule(sfx_warn); + return false; + } + for (int i = propsList.Count - 1; i >= 0; i--) { CVRSyncHelper.PropData propData = propsList[i]; @@ -247,6 +254,10 @@ public class PropUndoButton : MelonMod { propData.Spawnable.Delete(); } + else + { + PlayAudioModule(sfx_deny); + } //if an undo attempt is made right after spawning a prop, the //spawnable & wrapper will both be null, so the delete request diff --git a/PropUndoButton/PropUndoButton.csproj b/PropUndoButton/PropUndoButton.csproj index 3b1889c..76fb8b1 100644 --- a/PropUndoButton/PropUndoButton.csproj +++ b/PropUndoButton/PropUndoButton.csproj @@ -10,6 +10,7 @@ + @@ -17,6 +18,7 @@ + diff --git a/PropUndoButton/SFX/sfx_deny.wav b/PropUndoButton/SFX/sfx_deny.wav new file mode 100644 index 0000000000000000000000000000000000000000..0a8b4ba9ff7fe4d682e9d1e0e8eb77df657b446c GIT binary patch literal 12496 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 Date: Thu, 13 Apr 2023 18:11:02 -0500 Subject: [PATCH 15/23] Update format.json --- PropUndoButton/format.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PropUndoButton/format.json b/PropUndoButton/format.json index 8643aa7..244b981 100644 --- a/PropUndoButton/format.json +++ b/PropUndoButton/format.json @@ -1,12 +1,12 @@ { - "_id": -1, + "_id": 147, "name": "PropUndoButton", "modversion": "1.0.1", "gameversion": "2022r170", "loaderversion": "0.5.7", "modtype": "Mod", "author": "NotAKidoS", - "description": "Press Z to undo latest spawned prop. Includes optional SFX for prop spawn, undo, and warning, which can be disabled in settings.\n\nYou can replace the sfx in 'ChilloutVR\\ChilloutVR_Data\\StreamingAssets\\Cohtml\\UIResources\\GameUI\\mods\\PropUndo\\audio'.", + "description": "CTRL+Z to undo latest spawned prop. CTRL+SHIFT+Z to redo deleted prop.\nIncludes optional SFX for prop spawn, undo, redo, warn, and deny, which can be enabled in settings.\n\nYou can replace the sfx in 'ChilloutVR\\ChilloutVR_Data\\StreamingAssets\\Cohtml\\UIResources\\GameUI\\mods\\PropUndo\\audio'.", "searchtags": [ "prop", "undo", @@ -18,6 +18,6 @@ ], "downloadlink": "https://github.com/NotAKidOnSteam/PropUndoButton/releases/download/v1.0.1/PropUndoButton.dll", "sourcelink": "https://github.com/NotAKidOnSteam/PropUndoButton/", - "changelog": "- Initial Release\n- Added redo button.", + "changelog": "- Initial Release\n- Added redo button.\n- Disabled SFX by default.\n- Lowered SFX volume to match existing UI sounds.", "embedcolor": "#00FFFF" } \ No newline at end of file From b1749af6ca0387ffdfd1900b62b3c40ec93cb7fe Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 18:32:21 -0500 Subject: [PATCH 16/23] fixed warn/deny sound usage, enabled sfx by default again --- PropUndoButton/Main.cs | 27 +++++++++++++-------------- PropUndoButton/format.json | 2 +- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index 5ab8ddc..33c3b0b 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -23,7 +23,7 @@ public class PropUndoButton : MelonMod Category.CreateEntry("Enabled", true, description: "Toggle Undo Prop Button."); public static readonly MelonPreferences_Entry EntryUseSFX = - Category.CreateEntry("Use SFX", false, description: "Toggle audio queues for prop spawn, undo, redo, or warning."); + Category.CreateEntry("Use SFX", true, description: "Toggle audio queues for prop spawn, undo, redo, and warning."); // audio clip names, InterfaceAudio adds "PropUndo_" prefix public const string sfx_spawn = "PropUndo_sfx_spawn"; @@ -123,7 +123,7 @@ public class PropUndoButton : MelonMod if (!IsPropSpawnAllowed() || IsAtPropLimit()) { - PlayAudioModule(sfx_warn); + PlayAudioModule(sfx_deny); return; } @@ -187,32 +187,32 @@ public class PropUndoButton : MelonMod public static void RedoProp() { int index = deletedProps.Count - 1; - if (index < 0 || index >= deletedProps.Count || IsAtPropLimit()) + if (index < 0) { PlayAudioModule(sfx_warn); return; } + if (!IsPropSpawnAllowed() || IsAtPropLimit()) + { + PlayAudioModule(sfx_deny); + return; + } + // only allow redo of prop spawned in last minute DeletedProp deletedProp = deletedProps[index]; if (Time.time - deletedProp.timeDeleted <= redoTimeoutLimit) { - if (AttemptRedoProp(deletedProp.propGuid, deletedProp.position, deletedProp.rotation)) - { - deletedProps.RemoveAt(index); - PlayAudioModule(sfx_redo); - return; - } + SendRedoProp(deletedProp.propGuid, deletedProp.position, deletedProp.rotation); + PlayAudioModule(sfx_redo); } - PlayAudioModule(sfx_warn); + deletedProps.RemoveAt(index); } // original spawn prop method does not let you specify rotation - public static bool AttemptRedoProp(string propGuid, Vector3 position, Vector3 rotation) + public static void SendRedoProp(string propGuid, Vector3 position, Vector3 rotation) { - if (!IsPropSpawnAllowed()) return false; - using (DarkRiftWriter darkRiftWriter = DarkRiftWriter.Create()) { darkRiftWriter.Write(propGuid); @@ -231,7 +231,6 @@ public class PropUndoButton : MelonMod NetworkManager.Instance.GameNetwork.SendMessage(message, SendMode.Reliable); } } - return true; } public static void PlayAudioModule(string module) diff --git a/PropUndoButton/format.json b/PropUndoButton/format.json index 244b981..02d3b81 100644 --- a/PropUndoButton/format.json +++ b/PropUndoButton/format.json @@ -18,6 +18,6 @@ ], "downloadlink": "https://github.com/NotAKidOnSteam/PropUndoButton/releases/download/v1.0.1/PropUndoButton.dll", "sourcelink": "https://github.com/NotAKidOnSteam/PropUndoButton/", - "changelog": "- Initial Release\n- Added redo button.\n- Disabled SFX by default.\n- Lowered SFX volume to match existing UI sounds.", + "changelog": "- Initial Release\n- Added redo button.\n- Mitigated issue of props getting stuck locally if deleting them before they fully spawn.\n- Lowered SFX volume to match existing UI sounds.", "embedcolor": "#00FFFF" } \ No newline at end of file From 57024e6bab76697a82a230d7ade1ef804c725182 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 18:34:52 -0500 Subject: [PATCH 17/23] Update format.json --- PropUndoButton/format.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PropUndoButton/format.json b/PropUndoButton/format.json index 02d3b81..e9cc453 100644 --- a/PropUndoButton/format.json +++ b/PropUndoButton/format.json @@ -6,7 +6,7 @@ "loaderversion": "0.5.7", "modtype": "Mod", "author": "NotAKidoS", - "description": "CTRL+Z to undo latest spawned prop. CTRL+SHIFT+Z to redo deleted prop.\nIncludes optional SFX for prop spawn, undo, redo, warn, and deny, which can be enabled in settings.\n\nYou can replace the sfx in 'ChilloutVR\\ChilloutVR_Data\\StreamingAssets\\Cohtml\\UIResources\\GameUI\\mods\\PropUndo\\audio'.", + "description": "**CTRL+Z** to undo latest spawned prop. **CTRL+SHIFT+Z** to redo deleted prop.\nIncludes optional SFX for prop spawn, undo, redo, warn, and deny, which can be disabled in settings.\n\nYou can replace the sfx in 'ChilloutVR\\ChilloutVR_Data\\StreamingAssets\\Cohtml\\UIResources\\GameUI\\mods\\PropUndo\\audio'.", "searchtags": [ "prop", "undo", From df51d421aa16a0067c4c1351257d05fc005fe399 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 18:48:58 -0500 Subject: [PATCH 18/23] Patch DeleteAllProps, reverse order --- PropUndoButton/Main.cs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index 33c3b0b..8a98e48 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -37,10 +37,14 @@ public class PropUndoButton : MelonMod public override void OnInitializeMelon() { - HarmonyInstance.Patch( // delete all props in reverse order for redo + HarmonyInstance.Patch( // delete my props in reverse order for redo typeof(CVRSyncHelper).GetMethod(nameof(CVRSyncHelper.DeleteMyProps)), prefix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnDeleteMyProps), BindingFlags.NonPublic | BindingFlags.Static)) ); + HarmonyInstance.Patch( // delete all props in reverse order for redo + typeof(CVRSyncHelper).GetMethod(nameof(CVRSyncHelper.DeleteAllProps)), + prefix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnDeleteAllProps), BindingFlags.NonPublic | BindingFlags.Static)) + ); HarmonyInstance.Patch( // prop spawn sfx typeof(CVRSyncHelper).GetMethod(nameof(CVRSyncHelper.SpawnProp)), postfix: new HarmonyLib.HarmonyMethod(typeof(PropUndoButton).GetMethod(nameof(OnSpawnProp), BindingFlags.NonPublic | BindingFlags.Static)) @@ -172,6 +176,27 @@ public class PropUndoButton : MelonMod return false; } + // delete in reverse order for undo to work as expected + private static bool OnDeleteAllProps() + { + if (!EntryEnabled.Value) return true; + + CVRSyncHelper.PropData[] propsList = CVRSyncHelper.Props.ToArray(); + if (propsList.Length == 0) + { + PlayAudioModule(sfx_warn); + return false; + } + + for (int i = propsList.Length - 1; i >= 0; i--) + { + CVRSyncHelper.PropData propData = propsList[i]; + SafeDeleteProp(propData); + } + + return false; + } + private static void UndoProp() { var propData = GetLatestPropByOwnerId(); From e990a8581e42a0f65b8cb1df4165fbd2743671e8 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 19:11:50 -0500 Subject: [PATCH 19/23] mmm --- PropUndoButton/Main.cs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/PropUndoButton/Main.cs b/PropUndoButton/Main.cs index 8a98e48..34dc00f 100644 --- a/PropUndoButton/Main.cs +++ b/PropUndoButton/Main.cs @@ -191,9 +191,9 @@ public class PropUndoButton : MelonMod for (int i = propsList.Length - 1; i >= 0; i--) { CVRSyncHelper.PropData propData = propsList[i]; - SafeDeleteProp(propData); + DeleteProp(propData); } - + return false; } @@ -229,10 +229,15 @@ public class PropUndoButton : MelonMod if (Time.time - deletedProp.timeDeleted <= redoTimeoutLimit) { SendRedoProp(deletedProp.propGuid, deletedProp.position, deletedProp.rotation); + deletedProps.RemoveAt(index); PlayAudioModule(sfx_redo); } - - deletedProps.RemoveAt(index); + else + { + // if latest prop is too old, same with rest + deletedProps.Clear(); + PlayAudioModule(sfx_warn); + } } // original spawn prop method does not let you specify rotation @@ -266,6 +271,20 @@ public class PropUndoButton : MelonMod } } + private static void DeleteProp(CVRSyncHelper.PropData propData) + { + if (propData.Spawnable != null) + { + propData.Spawnable.Delete(); + } + else + { + if (propData.Wrapper != null) + UnityEngine.Object.DestroyImmediate(propData.Wrapper); + propData.Recycle(); + } + } + private static void SafeDeleteProp(CVRSyncHelper.PropData propData) { //fixes getting props stuck in limbo state if spawn & delete fast From 7bf6c6e56065b1058e32a5c688a4a97ff73bdac5 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 19:14:21 -0500 Subject: [PATCH 20/23] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 343c678..9624ea0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # PropUndoButton -Press Z to undo latest spawned prop. Includes optional SFX for prop spawn, undo, and warning, which can be disabled in settings. +**CTRL+Z** to undo latest spawned prop. **CTRL+SHIFT+Z** to redo deleted prop. + +Includes optional SFX for prop spawn, undo, redo, warn, and deny, which can be disabled in settings. You can replace the sfx in `"ChilloutVR\ChilloutVR_Data\StreamingAssets\Cohtml\UIResources\GameUI\mods\PropUndo\audio"`. From 2746b890a5f3977e76300117845ecb11d3069a87 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 20:58:55 -0500 Subject: [PATCH 21/23] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9624ea0..e079991 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ You can replace the sfx in `"ChilloutVR\ChilloutVR_Data\StreamingAssets\Cohtml\U https://user-images.githubusercontent.com/37721153/231351589-07f794f3-f542-4cb4-b034-5c1902f86758.mp4 +##Relevant Feedback Posts: +https://feedback.abinteractive.net/p/z-for-undo-in-game + --- Here is the block of text where I tell you this mod is not affiliated or endorsed by ABI. From f883c85aa9a3cca560af204311d205bcd88e5f26 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 20:59:07 -0500 Subject: [PATCH 22/23] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e079991..9d7b13b 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ You can replace the sfx in `"ChilloutVR\ChilloutVR_Data\StreamingAssets\Cohtml\U https://user-images.githubusercontent.com/37721153/231351589-07f794f3-f542-4cb4-b034-5c1902f86758.mp4 -##Relevant Feedback Posts: +## Relevant Feedback Posts: https://feedback.abinteractive.net/p/z-for-undo-in-game --- From adb0b5fc0e2c8b36a4dbc6676daf99feaffa4241 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 13 Apr 2023 21:00:04 -0500 Subject: [PATCH 23/23] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d7b13b..f20371d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ https://user-images.githubusercontent.com/37721153/231351589-07f794f3-f542-4cb4- ## Relevant Feedback Posts: https://feedback.abinteractive.net/p/z-for-undo-in-game ---- +--- Here is the block of text where I tell you this mod is not affiliated or endorsed by ABI. https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games