From b09f963e71064644f93a880beb107e1afdaef6c8 Mon Sep 17 00:00:00 2001 From: Auros Nexus Date: Tue, 26 Oct 2021 18:34:37 -0400 Subject: [PATCH] Example: FailOnSaberClash --- .../FailOnSaberClashCoreInstaller.cs | 12 ------ .../Installers/FailPlayerInstaller.cs | 21 ++++++++++ .../Managers/ClashFailManager.cs | 39 +++++++++++++++++++ [1] FailOnSaberClash/Plugin.cs | 8 ++-- [1] FailOnSaberClash/README.md | 13 +++++++ [1] FailOnSaberClash/manifest.json | 11 +++--- 6 files changed, 83 insertions(+), 21 deletions(-) delete mode 100644 [1] FailOnSaberClash/Installers/FailOnSaberClashCoreInstaller.cs create mode 100644 [1] FailOnSaberClash/Installers/FailPlayerInstaller.cs create mode 100644 [1] FailOnSaberClash/Managers/ClashFailManager.cs create mode 100644 [1] FailOnSaberClash/README.md diff --git a/[1] FailOnSaberClash/Installers/FailOnSaberClashCoreInstaller.cs b/[1] FailOnSaberClash/Installers/FailOnSaberClashCoreInstaller.cs deleted file mode 100644 index 7cad730..0000000 --- a/[1] FailOnSaberClash/Installers/FailOnSaberClashCoreInstaller.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Zenject; - -namespace FailOnSaberClash.Installers -{ - internal class FailOnSaberClashCoreInstaller : Installer - { - public override void InstallBindings() - { - - } - } -} \ No newline at end of file diff --git a/[1] FailOnSaberClash/Installers/FailPlayerInstaller.cs b/[1] FailOnSaberClash/Installers/FailPlayerInstaller.cs new file mode 100644 index 0000000..f0c8a1b --- /dev/null +++ b/[1] FailOnSaberClash/Installers/FailPlayerInstaller.cs @@ -0,0 +1,21 @@ +using FailOnSaberClash.Managers; +using Zenject; + +namespace FailOnSaberClash.Installers +{ + // This is our installer. It is one of the ways we can communicate to Zenject what to run and how to instantiate our classes. + internal class FailPlayerInstaller : Installer + { + public override void InstallBindings() + { + // We are registering our manager class so it can work when the player is in a level. Let's break down what's happening here. + + // Container | We access the current container. This is defined in one of the base classes that Installer inherits. + // BindInterfacesTo | We tell the container to bind the type (ClashFailManager)'s interfaces (ITickable) to the container. + // Zenject now knows that it's an ITickable and will call it's Tick method, allowing us to run code every frame. + // AsSingle() | This registers it as a single instance inside this container. Meaning, you can ensure that only one of this object will exist at a time. + + Container.BindInterfacesTo().AsSingle(); + } + } +} \ No newline at end of file diff --git a/[1] FailOnSaberClash/Managers/ClashFailManager.cs b/[1] FailOnSaberClash/Managers/ClashFailManager.cs new file mode 100644 index 0000000..eb1f8e5 --- /dev/null +++ b/[1] FailOnSaberClash/Managers/ClashFailManager.cs @@ -0,0 +1,39 @@ +using System; +using UnityEngine; +using Zenject; + +namespace FailOnSaberClash.Managers +{ + // We inherit ITickable so we can process stuff each frame. This is very similar to the player loop Update() + // method in Unity, and they should be treated similarly. + internal class ClashFailManager : ITickable + { + private readonly SaberClashChecker _saberClashChecker; + private readonly StandardLevelGameplayManager _standardLevelGameplayManager; + + // The SaberClashChecker is a class the base game uses to... well... detect saber clashes. By putting it in the constructor + // of this class, we are saying that this class has a dependency on the SaberClashChecker. Zenject recognizes this and when instantiating + // our class, will fill all the dependencies in the constructor. To get a list of dependencies from the base game that you can use, go to https://container.project-sira.tech + // + // The same logic above can be applied to the StandardLevelGameplayManager + public ClashFailManager(SaberClashChecker saberClashChecker, StandardLevelGameplayManager standardLevelGameplayManager) + { + // We store the SaberClashChecker and StandardLevelGameplayManager in their own private variable within our class so we can use them elsewhere. + _saberClashChecker = saberClashChecker; + _standardLevelGameplayManager = standardLevelGameplayManager; + } + + // This method gets called every frame. Similar to Update(), you shouldn't do expensive operations inside of this method. + public void Tick() + { + // This is where we check to see if the sabers are clashing. The base game uses this method to calculate where + // to spawn the sparkle effects. We can ALSO use it to fail the level when they class. + if (_saberClashChecker.AreSabersClashing(out Vector3 _)) + { + // We want to emulate what happens when you fail a level, so + // we call a method which triggers the level failed sequence. + _standardLevelGameplayManager.HandleGameEnergyDidReach0(); + } + } + } +} \ No newline at end of file diff --git a/[1] FailOnSaberClash/Plugin.cs b/[1] FailOnSaberClash/Plugin.cs index 4dd59f1..4a15b0c 100644 --- a/[1] FailOnSaberClash/Plugin.cs +++ b/[1] FailOnSaberClash/Plugin.cs @@ -1,7 +1,6 @@ using FailOnSaberClash.Installers; using IPA; using SiraUtil.Zenject; -using IPALogger = IPA.Logging.Logger; namespace FailOnSaberClash { @@ -9,10 +8,11 @@ namespace FailOnSaberClash public class Plugin { [Init] - public Plugin(IPALogger logger, Zenjector zenjector) + public Plugin(Zenjector zenjector) { - zenjector.UseLogger(logger); - zenjector.Install(Location.App); + // We will install it into the Standard Player (Solo and Party mode). + // We don't want to touch campaigns, multiplayer, or the tutorial. + zenjector.Install(Location.StandardPlayer); } } } \ No newline at end of file diff --git a/[1] FailOnSaberClash/README.md b/[1] FailOnSaberClash/README.md new file mode 100644 index 0000000..6f62f5c --- /dev/null +++ b/[1] FailOnSaberClash/README.md @@ -0,0 +1,13 @@ +# Fail on Saber Clash + +Complexity: Simple + +Made on Beat Saber Version: 1.18.2 + +Made on SiraUtil Version: 3.0.0 + +Authored by: [Auros](https://github.com/Auros) + +## Description + +This tutorial goes over the very basic example of how you can leverage using Zenject within a Beat Saber mod. This mod/example causes the current player to fail the level when their sabers "clash" (touch each other). diff --git a/[1] FailOnSaberClash/manifest.json b/[1] FailOnSaberClash/manifest.json index 3903a3b..11c8d4c 100644 --- a/[1] FailOnSaberClash/manifest.json +++ b/[1] FailOnSaberClash/manifest.json @@ -2,11 +2,12 @@ "$schema": "https://raw.githubusercontent.com/bsmg/BSIPA-MetadataFileSchema/master/Schema.json", "id": "FailOnSaberClash", "name": "FailOnSaberClash", - "author": "auros", - "version": "3.0.0", - "description": "", - "gameVersion": "1.18.1", + "author": "SIRA", + "version": "1.0.0", + "description": "Fails the level when the sabers touch.", + "gameVersion": "1.18.2", "dependsOn": { - "BSIPA": "^4.2.0" + "BSIPA": "^4.2.0", + "SiraUtil": "^3.0.0" } } \ No newline at end of file