From 609cdbf3a56d600092a39cfefdcaa3be1f5d0cac Mon Sep 17 00:00:00 2001 From: Pierre Ziegler Date: Sat, 5 Sep 2020 20:03:50 +0200 Subject: [PATCH 1/2] Added: contoller support & configuration --- .vscode/settings.json | 6 +- CHANGELOG.md | 8 ++ CaptainShotgunModesPlugin.cs | 216 ++++++++++++++++++++++++++++++----- DPad.cs | 61 ++++++++++ README.md | 53 ++++++++- VERSION | 2 +- 6 files changed, 312 insertions(+), 34 deletions(-) create mode 100644 DPad.cs diff --git a/.vscode/settings.json b/.vscode/settings.json index 23268fb..fc66b01 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,8 @@ { "cSpell.words": [ "bepis", - "thunderstore" + "captainshotgunmodes", + "thunderstore", + "userstorm" ] -} \ No newline at end of file +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 54d0f77..af05dc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.0] - 2020-9-5 +### Added +- Controller support (tested with xbox 360 controller) +- Cycle through modes with mouse wheel or DPad +- Configuration for default mode and enable/disable modes selection +- README.md information about cycle through logic and controller support +- README.md Config and example config + ## [1.0.0] - 2020-8-30 ### Added - All project files (GitHub) diff --git a/CaptainShotgunModesPlugin.cs b/CaptainShotgunModesPlugin.cs index 6f39795..a66ce92 100644 --- a/CaptainShotgunModesPlugin.cs +++ b/CaptainShotgunModesPlugin.cs @@ -1,45 +1,66 @@ -using BepInEx; +using System; +using BepInEx; +using BepInEx.Configuration; using UnityEngine; using EntityStates.Captain.Weapon; using R2API.Utils; using RoR2.UI; using RoR2; +using On_ChargeCaptainShotgun = On.EntityStates.Captain.Weapon.ChargeCaptainShotgun; namespace CaptainShotgunModes { - enum FireMode { Normal, Auto, AutoCharge } + enum FireMode { Normal, Auto, AutoCharge, Count } [BepInDependency("com.bepis.r2api", BepInDependency.DependencyFlags.HardDependency)] [BepInPlugin("de.userstorm.captainshotgunmodes", "CaptainShotgunModes", "{VERSION}")] public class CaptainShotgunModesPlugin : BaseUnityPlugin { + public static ConfigEntry DefaultMode { get; set; } + public static ConfigEntry EnableModeSelectionWithNumberKeys { get; set; } + public static ConfigEntry EnableModeSelectionWithMouseWheel { get; set; } + public static ConfigEntry EnableModeSelectionWithDPad { get; set; } + private FireMode fireMode = FireMode.Normal; private float fixedAge = 0; - public void FixedUpdateHook( - On.EntityStates.Captain.Weapon.ChargeCaptainShotgun.orig_FixedUpdate orig, - ChargeCaptainShotgun self - ) + private void SingleFireMode(On_ChargeCaptainShotgun.orig_FixedUpdate orig, ChargeCaptainShotgun self) { - fixedAge += Time.fixedDeltaTime; + orig.Invoke(self); - if (fireMode.Equals(FireMode.Normal)) + if (self.GetFieldValue("released")) { - orig.Invoke(self); + fixedAge = 0; + } + } - if (self.GetFieldValue("released")) { - fixedAge = 0; - } + private void AutoFireMode(On_ChargeCaptainShotgun.orig_FixedUpdate orig, ChargeCaptainShotgun self) + { + var didFire = false; + var released = self.GetFieldValue("released"); - return; + if (!released) + { + didFire = true; + fixedAge = 0; + self.SetFieldValue("released", true); + } + + orig.Invoke(self); + + if (didFire) + { + self.SetFieldValue("released", false); } + } - bool didFire = false; - bool charge = fireMode.Equals(FireMode.AutoCharge); - bool released = self.GetFieldValue("released"); - float chargeDuration = self.GetFieldValue("chargeDuration"); + private void AutoFireChargeMode(On_ChargeCaptainShotgun.orig_FixedUpdate orig, ChargeCaptainShotgun self) + { + var didFire = false; + var released = self.GetFieldValue("released"); + var chargeDuration = self.GetFieldValue("chargeDuration"); - if (!released && (!charge || (charge && fixedAge >= chargeDuration))) + if (!released && fixedAge >= chargeDuration) { didFire = true; fixedAge = 0; @@ -54,16 +75,55 @@ ChargeCaptainShotgun self } } + private void CycleFireMode (bool forward = true) + { + FireMode newFireMode = fireMode + (forward ? 1 : -1); + + if (newFireMode == FireMode.Count) + { + newFireMode = FireMode.Normal; + } + + if ((int)newFireMode == -1) + { + newFireMode = FireMode.Count - 1; + } + + fireMode = newFireMode; + } + + public void FixedUpdateHook(On_ChargeCaptainShotgun.orig_FixedUpdate orig, ChargeCaptainShotgun self) + { + fixedAge += Time.fixedDeltaTime; + + switch (fireMode) + { + case FireMode.Normal: + SingleFireMode(orig, self); + break; + case FireMode.Auto: + AutoFireMode(orig, self); + break; + case FireMode.AutoCharge: + AutoFireChargeMode(orig, self); + break; + default: + // fallback to single fire mode + SingleFireMode(orig, self); + break; + } + } + public void UpdateHook(On.RoR2.UI.SkillIcon.orig_Update orig, SkillIcon self) { orig.Invoke(self); - if (self.targetSkill && self.targetSkillSlot.Equals(SkillSlot.Primary)) + if (self.targetSkill && self.targetSkillSlot == SkillSlot.Primary) { - SurvivorIndex survivorIndex = - SurvivorCatalog.GetSurvivorIndexFromBodyIndex(self.targetSkill.characterBody.bodyIndex); + int bodyIndex = self.targetSkill.characterBody.bodyIndex; + SurvivorIndex survivorIndex = SurvivorCatalog.GetSurvivorIndexFromBodyIndex(bodyIndex); - if (survivorIndex.Equals(SurvivorIndex.Captain)) + if (survivorIndex == SurvivorIndex.Captain) { self.stockText.gameObject.SetActive(true); self.stockText.fontSize = 12f; @@ -72,35 +132,135 @@ public void UpdateHook(On.RoR2.UI.SkillIcon.orig_Update orig, SkillIcon self) } } - public void Awake() + private void InitConfig() { - On.EntityStates.Captain.Weapon.ChargeCaptainShotgun.FixedUpdate += FixedUpdateHook; - On.RoR2.UI.SkillIcon.Update += UpdateHook; + DefaultMode = Config.Bind( + "Settings", + "DefaultMode", + "Normal", + "The mode that is selected on game start. Modes: Normal, Auto, AutoCharge" + ); + + EnableModeSelectionWithNumberKeys = Config.Bind( + "Settings", + "EnableModeSelectionWithNumberKeys", + true, + "When set to true modes can be selected using the number keys" + ); + + EnableModeSelectionWithMouseWheel = Config.Bind( + "Settings", + "EnableModeSelectionWithMouseWheel", + true, + "When set to true modes can be cycled through using the mouse wheel" + ); + + + EnableModeSelectionWithDPad = Config.Bind( + "Settings", + "EnableModeSelectionWithDPad", + true, + "When set to true modes can be cycled through using the DPad (controller)" + ); } - public void Update() + private void HandleConfig() { + try + { + fireMode = (FireMode)Enum.Parse(typeof(FireMode), DefaultMode.Value); + } + catch (Exception) + { + fireMode = FireMode.Normal; + } + } + + private void SelectFireModeWithNumberKeys() { + if (!EnableModeSelectionWithNumberKeys.Value) { + return; + } + if (Input.GetKeyDown(KeyCode.Alpha1)) { fireMode = FireMode.Normal; + + return; } if (Input.GetKeyDown(KeyCode.Alpha2)) { fireMode = FireMode.Auto; + + return; } if (Input.GetKeyDown(KeyCode.Alpha3)) { fireMode = FireMode.AutoCharge; } + } + + private void SelectFireModeWithMouseWheel() { + if (!EnableModeSelectionWithMouseWheel.Value) { + return; + } + + float wheel = Input.GetAxis("Mouse ScrollWheel"); + + if (wheel == 0) { + return; + } + + // scroll down => forward; scroll up => backward + CycleFireMode(wheel < 0f); + } + + private void SelectFireModeWithDPad() + { + if (!EnableModeSelectionWithDPad.Value) { + return; + } + + if (DPad.GetInputDown(DPadInput.Right) || DPad.GetInputDown(DPadInput.Down)) + { + CycleFireMode(); + + return; + } + + if (DPad.GetInputDown(DPadInput.Left) || DPad.GetInputDown(DPadInput.Up)) + { + CycleFireMode(false); + } + } + + private void SelectFireMode() + { + SelectFireModeWithNumberKeys(); + SelectFireModeWithMouseWheel(); + SelectFireModeWithDPad(); + } + + public void Awake() + { + InitConfig(); + HandleConfig(); + + On_ChargeCaptainShotgun.FixedUpdate += FixedUpdateHook; + On.RoR2.UI.SkillIcon.Update += UpdateHook; + } + + public void Update() + { + DPad.Update(); - // TODO: add gamepad button to cycle through fire modes + SelectFireMode(); } public void OnDestroy() { - On.EntityStates.Captain.Weapon.ChargeCaptainShotgun.FixedUpdate -= FixedUpdateHook; + On_ChargeCaptainShotgun.FixedUpdate -= FixedUpdateHook; On.RoR2.UI.SkillIcon.Update -= UpdateHook; } } diff --git a/DPad.cs b/DPad.cs new file mode 100644 index 0000000..cdea579 --- /dev/null +++ b/DPad.cs @@ -0,0 +1,61 @@ +using UnityEngine; + +namespace CaptainShotgunModes +{ + enum DPadInput { Left, Right, Up, Down, Count } + enum DPadAxis { Horizontal, Vertical, Count } + + class DPad + { + private static bool[] inputDownList = new bool [(int)DPadInput.Count]; + private static bool[] inputUpList = new bool [(int)DPadInput.Count]; + private static float[] axisValueList = new float [(int)DPadAxis.Count]; + + public static void Update() + { + // TODO: this might only work with xbox 360 and xbox one contollers + float horizontal = Input.GetAxis("Joy1Axis6"); + float vertical = Input.GetAxis("Joy1Axis7"); + + inputDownList[(int)DPadInput.Left] = horizontal < 0f && axisValueList[(int)DPadAxis.Horizontal] == 0f; + inputDownList[(int)DPadInput.Right] = horizontal > 0f && axisValueList[(int)DPadAxis.Horizontal] == 0f; + inputDownList[(int)DPadInput.Up] = vertical > 0f && axisValueList[(int)DPadAxis.Vertical] == 0f; + inputDownList[(int)DPadInput.Down] = vertical < 0f && axisValueList[(int)DPadAxis.Vertical] == 0f; + + inputUpList[(int)DPadInput.Left] = horizontal == 0f && axisValueList[(int)DPadAxis.Horizontal] < 0f; + inputUpList[(int)DPadInput.Right] = horizontal == 0f && axisValueList[(int)DPadAxis.Horizontal] > 0f; + inputUpList[(int)DPadInput.Up] = vertical == 0f && axisValueList[(int)DPadAxis.Vertical] > 0f; + inputUpList[(int)DPadInput.Down] = vertical == 0f && axisValueList[(int)DPadAxis.Vertical] < 0f; + + axisValueList[(int)DPadAxis.Horizontal] = horizontal; + axisValueList[(int)DPadAxis.Vertical] = vertical; + } + + public static bool GetInputDown(DPadInput input) + { + if (input < 0 || input >= DPadInput.Count) { + return false; + } + + return inputDownList[(int)input]; + } + + public static bool GetInputUp(DPadInput input) + { + if (input < 0 || input >= DPadInput.Count) { + return false; + } + + return inputUpList[(int)input]; + } + + public static float GetAxis(DPadAxis axis) + { + if (axis < 0 || axis >= DPadAxis.Count) { + return 0f; + } + + return axisValueList[(int)axis]; + } + } +} diff --git a/README.md b/README.md index 0aa57da..99612fc 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,11 @@ ## Description -This mod allows you to choose between 3 firing modes for the captain's shotgun: Normal, Auto and AutoCharge. With both auto modes you can just hold down the fire key and don´t have to spam it. +This mod allows you to choose between 3 firing modes for the captain's shotgun: `Normal`, `Auto` and `AutoCharge`. +With both auto modes you can just hold down the fire key and don´t have to spam it. -The modes can be selected using the number keys `1`, `2` and `3`. The current mode is displayed above the primary skill icon. +The modes can be selected using the number keys `1`, `2` and `3`, or cycled through using the `mouse wheel` or [DPad](https://en.wikipedia.org/wiki/D-pad). +The current mode is displayed above the primary skill icon. ## Modes @@ -14,7 +16,52 @@ The modes can be selected using the number keys `1`, `2` and `3`. The current mo | Auto | 2 | Automatically fires as long as the fire key is pressed. | ![auto](https://raw.githubusercontent.com/Vl4dimyr/CaptainShotgunModes/master/images/sc_auto.jpg) | AutoCharge | 3 | Automatically fires after charging as long as the fire key is pressed. | ![auto_charge](https://raw.githubusercontent.com/Vl4dimyr/CaptainShotgunModes/master/images/sc_auto_charge.jpg) -> I will add controller support if enough players want it! [let me know](https://github.com/Vl4dimyr/CaptainShotgunModes/issues/1). +### Cycle through modes + +| Direction | Actions | +|-----------|-----------------------------------------| +| Forward | Mouse Wheel Down, DPad Right, DPad Down | +| Backward | Mouse Wheel Up, DPad Left, DPad Up | + +> I did add controller support because enough players wanted it! [see](https://github.com/Vl4dimyr/CaptainShotgunModes/issues/1). + +> Currently this is only tested with a xbox 360 controller (xbox one should work too). + +## Config + +The config file (`\BepInEx\config\de.userstorm.captainshotgunmodes.cfg`) will be crated automatically when the mod is loaded. +You need to restart the game for changes to apply in game. + +### Example config + +The example config keeps only mode selection with number keys enabled and sets the default mode to `Auto`. + +```ini +## Settings file was created by plugin CaptainShotgunModes v1.1.0 +## Plugin GUID: de.userstorm.captainshotgunmodes + +[Settings] + +## The mode that is selected on game start. Modes: Normal, Auto, AutoCharge +# Setting type: String +# Default value: Normal +DefaultMode = Auto + +## When set to true modes can be selected using the number keys +# Setting type: Boolean +# Default value: true +EnableModeSelectionWithNumberKeys = true + +## When set to true modes can be cycled through using the mouse wheel +# Setting type: Boolean +# Default value: true +EnableModeSelectionWithMouseWheel = false + +## When set to true modes can be cycled through using the DPad (controller) +# Setting type: Boolean +# Default value: true +EnableModeSelectionWithDPad = false +``` ## Manual Install diff --git a/VERSION b/VERSION index cada1ac..0698a2c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.1 +1.1.0 From aaee007c0f9515fa5de4f2874503bb9ce082068f Mon Sep 17 00:00:00 2001 From: Pierre Ziegler Date: Sat, 5 Sep 2020 20:10:20 +0200 Subject: [PATCH 2/2] Changed: order of functions --- CaptainShotgunModesPlugin.cs | 82 ++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/CaptainShotgunModesPlugin.cs b/CaptainShotgunModesPlugin.cs index a66ce92..95f4b83 100644 --- a/CaptainShotgunModesPlugin.cs +++ b/CaptainShotgunModesPlugin.cs @@ -92,46 +92,6 @@ private void CycleFireMode (bool forward = true) fireMode = newFireMode; } - public void FixedUpdateHook(On_ChargeCaptainShotgun.orig_FixedUpdate orig, ChargeCaptainShotgun self) - { - fixedAge += Time.fixedDeltaTime; - - switch (fireMode) - { - case FireMode.Normal: - SingleFireMode(orig, self); - break; - case FireMode.Auto: - AutoFireMode(orig, self); - break; - case FireMode.AutoCharge: - AutoFireChargeMode(orig, self); - break; - default: - // fallback to single fire mode - SingleFireMode(orig, self); - break; - } - } - - public void UpdateHook(On.RoR2.UI.SkillIcon.orig_Update orig, SkillIcon self) - { - orig.Invoke(self); - - if (self.targetSkill && self.targetSkillSlot == SkillSlot.Primary) - { - int bodyIndex = self.targetSkill.characterBody.bodyIndex; - SurvivorIndex survivorIndex = SurvivorCatalog.GetSurvivorIndexFromBodyIndex(bodyIndex); - - if (survivorIndex == SurvivorIndex.Captain) - { - self.stockText.gameObject.SetActive(true); - self.stockText.fontSize = 12f; - self.stockText.SetText(fireMode.ToString()); - } - } - } - private void InitConfig() { DefaultMode = Config.Bind( @@ -216,7 +176,7 @@ private void SelectFireModeWithMouseWheel() { CycleFireMode(wheel < 0f); } - private void SelectFireModeWithDPad() + private void SelectFireModeWithDPad() { if (!EnableModeSelectionWithDPad.Value) { return; @@ -242,6 +202,46 @@ private void SelectFireMode() SelectFireModeWithDPad(); } + public void FixedUpdateHook(On_ChargeCaptainShotgun.orig_FixedUpdate orig, ChargeCaptainShotgun self) + { + fixedAge += Time.fixedDeltaTime; + + switch (fireMode) + { + case FireMode.Normal: + SingleFireMode(orig, self); + break; + case FireMode.Auto: + AutoFireMode(orig, self); + break; + case FireMode.AutoCharge: + AutoFireChargeMode(orig, self); + break; + default: + // fallback to single fire mode + SingleFireMode(orig, self); + break; + } + } + + public void UpdateHook(On.RoR2.UI.SkillIcon.orig_Update orig, SkillIcon self) + { + orig.Invoke(self); + + if (self.targetSkill && self.targetSkillSlot == SkillSlot.Primary) + { + int bodyIndex = self.targetSkill.characterBody.bodyIndex; + SurvivorIndex survivorIndex = SurvivorCatalog.GetSurvivorIndexFromBodyIndex(bodyIndex); + + if (survivorIndex == SurvivorIndex.Captain) + { + self.stockText.gameObject.SetActive(true); + self.stockText.fontSize = 12f; + self.stockText.SetText(fireMode.ToString()); + } + } + } + public void Awake() { InitConfig();