diff --git a/README.md b/README.md index 32b5e98b..f7cfbc62 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Submerged is a mod for Among Us which adds a new map into the game. Click to expand [![Submerged Trailer](http://img.youtube.com/vi/gAX_mDOX4Pc/0.jpg)](http://www.youtube.com/watch?v=gAX_mDOX4Pc "Submerged Trailer") - + [See the trailer on YouTube](http://www.youtube.com/watch?v=gAX_mDOX4Pc) ![Screenshot 1](./.github/Images/Screenshot-1.png) @@ -38,26 +38,27 @@ Submerged is compatible with desktop releases of Among Us. This includes Steam, The table below lists the most recent Submerged release for each Among Us version after `v2022.3.29` (for desktop platforms only). The changelog for each version can be found under the [Releases](https://github.com/SubmergedAmongUs/Submerged/releases) tab. -| Among Us Version | Submerged Version | Links | -|:-:|:-:|:-:| -| `v2023.11.28` | `v2023.11.29` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2023.11.29/) | -| `v2023.10.24` | `v2023.11.2` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2023.11.2/) | -| `v2023.7.12`
`v2023.7.11` | `v2023.8.2` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2023.8.2/) | -| `v2023.6.27`
`v2023.6.13`
`v2023.3.28`
`v2023.2.28`
`v2022.12.14`
`v2022.12.8` | Unavailable | - | -| `v2022.10.25` | `v2022.10.26` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2022.10.26/) | -| `v2022.10.18` | Unavailable | - | -| `v2022.9.20`
`v2022.8.25`
`v2022.8.24`
`v2022.8.23` | `v2022.8.26` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2022.8.26/) | -| `v2022.7.12`
`v2022.6.21` | `v2022.6.23` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2022.6.23/) | -| `v2022.4.19`
`v2022.3.29` | `v2022.6.12` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2022.6.12/) | +| Among Us Version | Submerged Version | Links | +|:---------------------------------------------------------------------------------------------:|:-----------------:|:-----------------------------------------------------------------------------------:| +| `v2024.3.5` | `v2024.3.24` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2024.3.24/) | +| `v2023.11.28` | `v2023.11.29` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2023.11.29/) | +| `v2023.10.24` | `v2023.11.2` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2023.11.2/) | +| `v2023.7.12`
`v2023.7.11` | `v2023.8.2` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2023.8.2/) | +| `v2023.6.27`
`v2023.6.13`
`v2023.3.28`
`v2023.2.28`
`v2022.12.14`
`v2022.12.8` | Unavailable | - | +| `v2022.10.25` | `v2022.10.26` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2022.10.26/) | +| `v2022.10.18` | Unavailable | - | +| `v2022.9.20`
`v2022.8.25`
`v2022.8.24`
`v2022.8.23` | `v2022.8.26` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2022.8.26/) | +| `v2022.7.12`
`v2022.6.21` | `v2022.6.23` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2022.6.23/) | +| `v2022.4.19`
`v2022.3.29` | `v2022.6.12` | [Download](https://github.com/SubmergedAmongUs/Submerged/releases/tag/v2022.6.12/) | # Dependencies Submerged depends on the following mods and modding tools in order to function properly: -| Mod | Version | -|-|:-:| -| [BepInEx](https://builds.bepinex.dev/projects/bepinex_be) (IL2CPP-win-x86) | `v6.0.0-be.671` | -| [Reactor](https://github.com/nuclearpowered/reactor) | `v2.2.0` | +| Mod | Version | +|----------------------------------------------------------------------------|:---------------:| +| [BepInEx](https://builds.bepinex.dev/projects/bepinex_be) (IL2CPP-win-x86) | `v6.0.0-be.688` | +| [Reactor](https://github.com/nuclearpowered/reactor) | `v2.2.0` | # Installation @@ -72,7 +73,6 @@ This mod has been tested and works with the Steam, Epic and itch.io versions of 1. Download the correct ZIP [release](#releases) based on your Among Us version. 2. Navigate to your Among Us installation directory. 3. Extract the downloaded files there. Ensure that the `BepInEx` folder is located in the same folder as the `Among Us.exe` file (Check screenshot below). - ![Folder Structure](./.github/Images/Folder-Structure.png) 4. Run the game (Please note that the first launch might take some time). @@ -83,24 +83,24 @@ Alternatively, if you are already using other mods or already have BepInEx insta Submerged is available in the languages listed below. If you would like to help translate Submerged to one of the languages listed below or want to correct a translation, please [open an issue](https://github.com/SubmergedAmongUs/Submerged/issues/new/choose/) or contact us at `submergedamongus@gmail.com`. -| Language | ❔ | Status | -|-|:-:|:-:| -| English | ✅ | - | -| Deutsch | ✅ | Fully Translated | -| Français | ✅ | Fully Translated | -| Nederlands | ✅ | Fully Translated | -| Português (Brasil) | ✅ | Fully Translated | -| Русский | ✅ | Fully Translated | -| 日本語 | ✅ | Fully Translated | -| 简体中文 | ✅ | Fully Translated | -| 繁體中文 | ✅ | Fully Translated | -| Español | 🟡 | Partially Translated | -| Bisaya | ❌ | Not Translated | -| Español (Latinoamérica) | ❌ | Not Translated
(Using Español) | -| Gaeilge | ❌ | Not Translated | -| Italiano | ❌ | Not Translated | -| Português | ❌ | Not Translated | -| 한국어 | ❌ | Not Translated | +| Language | ❔ | Status | +|-------------------------|:--:|:---------------------------------:| +| English | ✅ | - | +| Deutsch | ✅ | Fully Translated | +| Français | ✅ | Fully Translated | +| Italiano | ✅ | Fully Translated | +| Nederlands | ✅ | Fully Translated | +| Português (Brasil) | ✅ | Fully Translated | +| Русский | ✅ | Fully Translated | +| 日本語 | ✅ | Fully Translated | +| 简体中文 | ✅ | Fully Translated | +| 繁體中文 | ✅ | Fully Translated | +| Español | 🟡 | Partially Translated | +| Bisaya | ❌ | Not Translated | +| Español (Latinoamérica) | ❌ | Not Translated
(Using Español) | +| Gaeilge | ❌ | Not Translated | +| Português | ❌ | Not Translated | +| 한국어 | ❌ | Not Translated | # Compatibility @@ -156,6 +156,7 @@ For business inquiries, please contact us at `submergedamongus@gmail.com`. - [ItsNiceCraft](https://bento.me/itsnicecraft) - Deutsch - [MissJukebox](https://www.twitch.tv/missjukebox/) - Español - Monid73 - Русский + - [PENGUN](https://youtube.com/@PENGUINWITHGUN) - Italiano - [RevoLou](https://twitter.com/Psyco_Lou/) - Português do Brasil - RobinRMC - Nederlands - [SPRLC](https://twitter.com/SuperLanceur) - Français diff --git a/Submerged.sln b/Submerged.sln index 9d86415e..6456a372 100644 --- a/Submerged.sln +++ b/Submerged.sln @@ -3,11 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30804.86 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution Files", "{5819678E-32DB-4841-A4F9-89ECE2AE8ADA}" -ProjectSection(SolutionItems) = preProject - nuget.config = nuget.config -EndProjectSection -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Submerged", "Submerged\Submerged.csproj", "{13ACAAD7-C0BE-468C-8710-14C77F7C24BA}" EndProject Global diff --git a/Submerged/BaseGame/BaseGameCodeAttribute.cs b/Submerged/BaseGame/BaseGameCodeAttribute.cs index 83b44cf0..197463cd 100644 --- a/Submerged/BaseGame/BaseGameCodeAttribute.cs +++ b/Submerged/BaseGame/BaseGameCodeAttribute.cs @@ -5,8 +5,7 @@ namespace Submerged.BaseGame; public enum LastChecked { // ReSharper disable InconsistentNaming - v2023_10_24, - v2023_11_28 + v2024_3_5 // ReSharper restore InconsistentNaming } diff --git a/Submerged/BaseGame/Extensions/Minigame.cs b/Submerged/BaseGame/Extensions/Minigame.cs index acf7194f..1b93df58 100644 --- a/Submerged/BaseGame/Extensions/Minigame.cs +++ b/Submerged/BaseGame/Extensions/Minigame.cs @@ -4,7 +4,7 @@ namespace Submerged.BaseGame.Extensions; public static class MinigameExtensions { - [BaseGameCode(LastChecked.v2023_10_24, "Entire method is copied from base game because we can't call it from the base pointer since that causes an infinite loop.")] + [BaseGameCode(LastChecked.v2024_3_5, "Entire method is copied from base game because we can't call it from the base pointer since that causes an infinite loop.")] public static void BaseClose(this Minigame self) { bool isComplete; diff --git a/Submerged/BaseGame/Interfaces/IDoorMinigame.cs b/Submerged/BaseGame/Interfaces/IDoorMinigame.cs index 0e173f92..4cd37e08 100644 --- a/Submerged/BaseGame/Interfaces/IDoorMinigame.cs +++ b/Submerged/BaseGame/Interfaces/IDoorMinigame.cs @@ -1,11 +1,9 @@ -using Hazel; - -namespace Submerged.BaseGame.Interfaces; +namespace Submerged.BaseGame.Interfaces; // ReSharper disable once InconsistentNaming public sealed partial class AU { - [BaseGameCode(LastChecked.v2023_11_28)] + [BaseGameCode(LastChecked.v2024_3_5)] public interface IDoorMinigame { [UsedImplicitly] diff --git a/Submerged/BaseGame/Interfaces/ISystemType.cs b/Submerged/BaseGame/Interfaces/ISystemType.cs index 048fa82f..462ae056 100644 --- a/Submerged/BaseGame/Interfaces/ISystemType.cs +++ b/Submerged/BaseGame/Interfaces/ISystemType.cs @@ -5,7 +5,7 @@ namespace Submerged.BaseGame.Interfaces; // ReSharper disable once InconsistentNaming public sealed partial class AU { - [BaseGameCode(LastChecked.v2023_10_24)] + [BaseGameCode(LastChecked.v2024_3_5)] public interface ISystemType { [UsedImplicitly] diff --git a/Submerged/BaseGame/Interfaces/IUsable.cs b/Submerged/BaseGame/Interfaces/IUsable.cs index 78e24243..fb531114 100644 --- a/Submerged/BaseGame/Interfaces/IUsable.cs +++ b/Submerged/BaseGame/Interfaces/IUsable.cs @@ -3,7 +3,7 @@ // ReSharper disable once InconsistentNaming public sealed partial class AU { - [BaseGameCode(LastChecked.v2023_10_24)] + [BaseGameCode(LastChecked.v2024_3_5)] public interface IUsable { [UsedImplicitly] diff --git a/Submerged/BaseGame/Patches/AirshipUploadGame.cs b/Submerged/BaseGame/Patches/AirshipUploadGame.cs index b8e30a2d..8eb82c9c 100644 --- a/Submerged/BaseGame/Patches/AirshipUploadGame.cs +++ b/Submerged/BaseGame/Patches/AirshipUploadGame.cs @@ -8,7 +8,7 @@ public static class AirshipUploadGameUpdatePatches { [HarmonyPatch(typeof(AirshipUploadGame), nameof(AirshipUploadGame.Update))] [HarmonyPrefix] - [BaseGameCode(LastChecked.v2023_10_24, "Patching the method with it's own code because C# > C++")] + [BaseGameCode(LastChecked.v2024_3_5, "Patching the method with it's own code because C# > C++")] public static void Prefix(AirshipUploadGame __instance, out bool __runOriginal) { __runOriginal = false; diff --git a/Submerged/BaseGame/Patches/ExileController.cs b/Submerged/BaseGame/Patches/ExileController.cs deleted file mode 100644 index 7ed1545f..00000000 --- a/Submerged/BaseGame/Patches/ExileController.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using System.Linq; -using System.Reflection; -using HarmonyLib; -using Submerged.Extensions; - -namespace Submerged.BaseGame.Patches; - -[HarmonyPatch] -public static class ExileControllerPatches -{ - [UsedImplicitly] - public static void DisablePrefixWarningForHarmonyId(string id) - { - _allowedPrefixPatches.Add(id); - } - - private static readonly SCG.HashSet _allowedPrefixPatches = [SubmergedPlugin.Id]; - - public static void ExileController_Begin(ExileController self, GameData.PlayerInfo exiled, bool tie) - { - if (self.specialInputHandler != null) - { - self.specialInputHandler.disableVirtualCursor = true; - } - - ExileController.Instance = self; - ControllerManager.Instance.CloseAndResetAll(); - self.exiled = exiled; - self.Text.gameObject.SetActive(false); - self.Text.text = string.Empty; - int num = GameData.Instance.AllPlayers.Count(p => p.Role.IsImpostor && !p.IsDead && !p.Disconnected); - - if (exiled != null) - { - int num2 = GameData.Instance.AllPlayers.Count(p => p.Role.IsImpostor); - - if (!GameManager.Instance.LogicOptions.GetConfirmImpostor()) - { - self.completeString = TranslationController.Instance.GetString(StringNames.ExileTextNonConfirm, exiled.PlayerName); - } - else if (exiled.Role.IsImpostor) - { - if (num2 > 1) - { - self.completeString = TranslationController.Instance.GetString(StringNames.ExileTextPP, exiled.PlayerName); - } - else - { - self.completeString = TranslationController.Instance.GetString(StringNames.ExileTextSP, exiled.PlayerName); - } - } - else if (num2 > 1) - { - self.completeString = TranslationController.Instance.GetString(StringNames.ExileTextPN, exiled.PlayerName); - } - else - { - self.completeString = TranslationController.Instance.GetString(StringNames.ExileTextSN, exiled.PlayerName); - } - - self.Player.UpdateFromEitherPlayerDataOrCache(exiled, - PlayerOutfitType.Default, - PlayerMaterial.MaskType.Exile, - false, - new Action(() => - { - SkinViewData skin = ShipStatus.Instance.CosmeticsCache.GetSkin(exiled.Outfits[PlayerOutfitType.Default].SkinId); - - if (self.useIdleAnim) - { - self.Player.FixSkinSprite(skin.IdleFrame); - return; - } - - self.Player.FixSkinSprite(skin.EjectFrame); - })); - self.Player.ToggleName(false); - - if (!self.useIdleAnim) - { - self.Player.SetCustomHatPosition(self.exileHatPosition); - self.Player.SetCustomVisorPosition(self.exileVisorPosition); - } - - if (exiled.Role.IsImpostor) - { - num--; - } - } - else - { - if (tie) - { - self.completeString = TranslationController.Instance.GetString(StringNames.NoExileTie); - } - else - { - self.completeString = TranslationController.Instance.GetString(StringNames.NoExileSkip); - } - - self.Player.gameObject.SetActive(false); - } - - if (num == 1) - { - self.ImpostorText.text = TranslationController.Instance.GetString(StringNames.ImpostorsRemainS, num); - } - else - { - self.ImpostorText.text = TranslationController.Instance.GetString(StringNames.ImpostorsRemainP, num); - } - - self.StartCoroutine(self.Animate()); - } - - [HarmonyPatch(typeof(ExileController), nameof(ExileController.Begin))] - [HarmonyPrefix] - [BaseGameCode(LastChecked.v2023_10_24, "Sometimes the text doesn't show up. We have no idea why so instead we just patch the method with its own code to fix it :)")] - public static bool BeginPatch(ExileController __instance, MethodInfo __originalMethod, GameData.PlayerInfo exiled, bool tie) - { - HarmonyLib.Patches patchInfo = Harmony.GetPatchInfo(__originalMethod); - - Patch prefix = patchInfo.Prefixes.FirstOrDefault(p => p.PatchMethod.ReturnType == typeof(bool) && !_allowedPrefixPatches.Contains(p.owner)); - if (prefix != null) - { - Fatal($"A prefix patch returning bool was detected on ExileController.Begin! Be aware that Submerged also patches this method with a prefix that returns false, so this might lead to issues. Harmony ID at fault: {prefix.owner}"); - Fatal("In order to ensure compatibility, Submerged will disable its own patch on this method, however this might lead to issues when displaying the Submerged exile cutscene!!!"); - Fatal("In order to fix this, when Submerged is installed please patch Submerged.BaseGame.Patches.ExileControllerPatches.ExileController_Begin instead of ExileController.Begin, with the same patch. (Note that ExileController is the first argument of the method, not the __instance)"); - Fatal($"If you know what you are doing and want to remove this warning, call Submerged.BaseGame.Patches.ExileControllerPatches.DisablePrefixWarningForHarmonyId(\"{prefix.owner}\");"); - return true; - } - - ExileController_Begin(__instance, exiled, tie); - - return false; - } - - private static int Count(this ICG.List list, Predicate predicate) where T : CppObject - { - int count = 0; - - foreach (T item in list.GetFastEnumerator()) - { - if (predicate(item)) count++; - } - - return count; - } -} diff --git a/Submerged/BaseGame/Patches/TextTranslatorTMP.cs b/Submerged/BaseGame/Patches/TextTranslatorTMP.cs index de467ca1..36929350 100644 --- a/Submerged/BaseGame/Patches/TextTranslatorTMP.cs +++ b/Submerged/BaseGame/Patches/TextTranslatorTMP.cs @@ -8,7 +8,7 @@ public static class TextTranslatorTMPPatches { [HarmonyPatch(typeof(TextTranslatorTMP), nameof(TextTranslatorTMP.ResetText))] [HarmonyPrefix] - [BaseGameCode(LastChecked.v2023_10_24, "We are patching this with its own code to get rid of inlining that ruins our translation patches")] + [BaseGameCode(LastChecked.v2024_3_5, "We are patching this with its own code to get rid of inlining that ruins our translation patches")] public static void ResetTextPatch(TextTranslatorTMP __instance, out bool __runOriginal) { __runOriginal = false; diff --git a/Submerged/Debugging/Patches/GameTestingPatches.cs b/Submerged/Debugging/Patches/GameTestingPatches.cs index c41ab3e6..48aec3d4 100644 --- a/Submerged/Debugging/Patches/GameTestingPatches.cs +++ b/Submerged/Debugging/Patches/GameTestingPatches.cs @@ -26,4 +26,12 @@ public static void PreventBanPatch(out bool __result) [HarmonyPrefix] [HarmonyPriority(Priority.First)] public static bool StopGameEndingPatch() => false; + + [HarmonyPatch(typeof(AprilFoolsMode), nameof(AprilFoolsMode.ShouldShowAprilFoolsToggle))] + [HarmonyPrefix] + public static bool EnableAprilFoolsTogglePatch(out bool __result) + { + __result = true; + return false; + } } diff --git a/Submerged/Enums/CustomSystemTypes.cs b/Submerged/Enums/CustomSystemTypes.cs index 3772b00c..13f3bd2a 100644 --- a/Submerged/Enums/CustomSystemTypes.cs +++ b/Submerged/Enums/CustomSystemTypes.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace Submerged.Enums; diff --git a/Submerged/ExileCutscene/Patches/BaseGameResolvingPatches.cs b/Submerged/ExileCutscene/Patches/BaseGameResolvingPatches.cs index 22932854..af43e4c4 100644 --- a/Submerged/ExileCutscene/Patches/BaseGameResolvingPatches.cs +++ b/Submerged/ExileCutscene/Patches/BaseGameResolvingPatches.cs @@ -6,6 +6,16 @@ namespace Submerged.ExileCutscene.Patches; [HarmonyPatch] public static class BaseGameResolvingPatches { + public static string LastExileText { get; private set; } + + [HarmonyPatch(typeof(ExileController), nameof(ExileController.Begin))] + [HarmonyPostfix, HarmonyPriority(Priority.Last)] + public static void GetTextPatch(ExileController __instance) + { + LastExileText = __instance.completeString; + Message("Grabbing " + __instance + " from ExileController"); + } + [HarmonyPatch(typeof(ExileController), nameof(ExileController.Begin))] [HarmonyPrefix] public static void ResolvePlayerPatch(ExileController __instance) diff --git a/Submerged/ExileCutscene/SubmergedExileController.cs b/Submerged/ExileCutscene/SubmergedExileController.cs index 49923af9..13c820ad 100644 --- a/Submerged/ExileCutscene/SubmergedExileController.cs +++ b/Submerged/ExileCutscene/SubmergedExileController.cs @@ -5,6 +5,7 @@ using PowerTools; using Reactor.Utilities.Attributes; using Submerged.BaseGame; +using Submerged.ExileCutscene.Patches; using Submerged.Systems.BoxCat; using UnityEngine; @@ -150,7 +151,9 @@ private IEnumerator HandleText() const float TEXT_DUR = 2f; int previousValue = 0; - string completeStr = completeString; + string completeStr = BaseGameResolvingPatches.LastExileText; + + Warning("Displaying SubmergedExileController text: " + completeStr); for (float t = 0; t < TEXT_DUR; t += Time.deltaTime) { @@ -192,7 +195,7 @@ private IEnumerator HandleText() // CLeanup this WrapUpAndSpawn method [HideFromIl2Cpp] - [BaseGameCode(LastChecked.v2023_10_24, "Similar to AirshipExileController.WrapUpAndSpawn")] + [BaseGameCode(LastChecked.v2024_3_5, "Similar to AirshipExileController.WrapUpAndSpawn")] public IEnumerator WrapUpAndSpawn() { if (exiled != null) diff --git a/Submerged/Extensions/ComponentExtensions.cs b/Submerged/Extensions/ComponentExtensions.cs index 4991d784..65993c67 100644 --- a/Submerged/Extensions/ComponentExtensions.cs +++ b/Submerged/Extensions/ComponentExtensions.cs @@ -20,9 +20,10 @@ private static Dictionary RegisteredTypes foreach (Type type in Assembly.GetExecutingAssembly().GetTypes()) { - RegisterInIl2CppAttribute attribute = type.GetCustomAttribute(); + RegisterInIl2CppAttribute registerAttribute = type.GetCustomAttribute(); + ObsoleteAttribute obsoleteAttribute = type.GetCustomAttribute(); - if (attribute != null) + if (registerAttribute != null && obsoleteAttribute == null) { _registeredTypes[type.Name] = type; } @@ -34,6 +35,7 @@ private static Dictionary RegisteredTypes public static T EnsureComponent(this GameObject obj) where T : Component => obj.GetComponent() ?? obj.AddComponent(); - [Obsolete("This should eventualy disappear from the codebase.")] + public static Component EnsureComponent(this GameObject obj, Type type) => obj.GetComponent(Il2CppType.From(type)) ?? obj.AddComponent(Il2CppType.From(type)); + public static Component AddInjectedComponentByName(this GameObject obj, string typeName) => obj.AddComponent(Il2CppType.From(RegisteredTypes[typeName])); } diff --git a/Submerged/Extensions/SpriteRendererExtensions.cs b/Submerged/Extensions/SpriteRendererExtensions.cs new file mode 100644 index 00000000..c65482c9 --- /dev/null +++ b/Submerged/Extensions/SpriteRendererExtensions.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +namespace Submerged.Extensions; + +public static class SpriteRendererExtensions +{ + public static void SetColorAlpha(this SpriteRenderer rend, float alpha) + { + Color color = rend.color; + color.a = alpha; + rend.color = color; + } +} diff --git a/Submerged/Floors/Objects/DeadBodyShadowRenderer.cs b/Submerged/Floors/Objects/DeadBodyShadowRenderer.cs new file mode 100644 index 00000000..ff707adc --- /dev/null +++ b/Submerged/Floors/Objects/DeadBodyShadowRenderer.cs @@ -0,0 +1,13 @@ +using Reactor.Utilities.Attributes; +using UnityEngine; + +namespace Submerged.Floors.Objects; + +[RegisterInIl2Cpp] +public class DeadBodyShadowRenderer(nint ptr) : RelativeShadowRenderer(ptr) +{ + protected override void Start() + { + gameObject.layer = LayerMask.NameToLayer("Players"); + } +} diff --git a/Submerged/Floors/Objects/GenericShadowBehaviour.cs b/Submerged/Floors/Objects/GenericShadowBehaviour.cs new file mode 100644 index 00000000..295bcb99 --- /dev/null +++ b/Submerged/Floors/Objects/GenericShadowBehaviour.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Il2CppInterop.Runtime; +using Reactor.Utilities.Attributes; +using Submerged.Extensions; +using Submerged.Map; +using UnityEngine; + +namespace Submerged.Floors.Objects; + +[RegisterInIl2Cpp] +public sealed class GenericShadowBehaviour(nint ptr) : MonoBehaviour(ptr) +{ + public static List> ShadowTypeOverrides { get; set; } = []; + + static GenericShadowBehaviour() + { + ShadowTypeOverrides.Add(obj => obj.gameObject.GetComponentInParent(true) ? typeof(LongPlayerShadowRenderer) : null); + ShadowTypeOverrides.Add(obj => obj.gameObject.GetComponent() ? typeof(DeadBodyShadowRenderer) : null); + } + + private void Start() + { + // Without this, the fake shadow objects on the "Water" layer (4) will be seen by the main camera. + Camera.main!.cullingMask = 1073969927; // yay magic numbers + + GameObject shadowParent = new($"Submerged Shadow ({name})"); + CreateShadowsRecursively(transform, shadowParent.transform); + + shadowParent.transform.SetParent(transform); + } + + private static void CreateShadowsRecursively(Transform currentObject, Transform currentShadow, bool isRoot = true) + { + Type targetRendererType = ShadowTypeOverrides.Select(func => func(currentObject)).FirstOrDefault(type => type != null, defaultValue: typeof(RelativeShadowRenderer)); + RelativeShadowRenderer rend = currentShadow.gameObject.AddComponent(Il2CppType.From(targetRendererType)).Cast(); + + rend.isRoot = isRoot; + rend.target = currentObject; + rend.replacementSprites = SubmarineStatus.instance.GetReplacementShadowSprites(currentObject.name); + + foreach (Transform child in currentObject.GetChildren()) + { + GameObject shadowObj = new($"Submerged Shadow ({child.name})"); + shadowObj.transform.SetParent(currentShadow); + CreateShadowsRecursively(child, shadowObj.transform, false); + } + } +} diff --git a/Submerged/Floors/Objects/LongPlayerShadowRenderer.cs b/Submerged/Floors/Objects/LongPlayerShadowRenderer.cs new file mode 100644 index 00000000..8ceb772d --- /dev/null +++ b/Submerged/Floors/Objects/LongPlayerShadowRenderer.cs @@ -0,0 +1,40 @@ +using Reactor.Utilities.Attributes; +using UnityEngine; + +namespace Submerged.Floors.Objects; + +[RegisterInIl2Cpp] +public class LongPlayerShadowRenderer(nint ptr) : RelativeShadowRenderer(ptr) +{ + public LongBoiPlayerBody body; + + protected override void Start() + { + base.Start(); + body = target.GetComponentsInParent(true)[0]; + body.gameObject.layer = LayerMask.NameToLayer("Players"); + } + + protected override void LateUpdate() + { + base.LateUpdate(); + + if (targetRenderer) + { + switch (targetRenderer.name) + { + case "LongNeck": + shadowRenderer.size = new Vector2(targetRenderer.size.x, 1.1f); + break; + + case "ForegroundNeck": + shadowRenderer.size = new Vector2(targetRenderer.size.x, 1.7f); + break; + + case "LongHead": + shadowRenderer.transform.localPosition = new Vector3(shadowRenderer.transform.localPosition.x, body.neckSprite.transform.localPosition.y + 2.79f, shadowRenderer.transform.localPosition.z); + break; + } + } + } +} diff --git a/Submerged/Floors/Objects/RelativeShadowRenderer.cs b/Submerged/Floors/Objects/RelativeShadowRenderer.cs new file mode 100644 index 00000000..830dac2f --- /dev/null +++ b/Submerged/Floors/Objects/RelativeShadowRenderer.cs @@ -0,0 +1,92 @@ +using System.Collections.Generic; +using System.Linq; +using BepInEx.Unity.IL2CPP.Utils; +using Il2CppInterop.Runtime.Attributes; +using Reactor.Utilities.Attributes; +using Submerged.Extensions; +using UnityEngine; + +namespace Submerged.Floors.Objects; + +[RegisterInIl2Cpp] +public class RelativeShadowRenderer(nint ptr) : MonoBehaviour(ptr) +{ + public Transform target; + public SpriteRenderer targetRenderer; + + public bool isRoot; + public Sprite[] replacementSprites; + public SpriteRenderer shadowRenderer; + + private readonly Dictionary _cachedSprites = []; + + protected virtual void Awake() + { + gameObject.layer = 4; + } + + protected virtual void Start() + { + shadowRenderer = gameObject.AddComponent(); + this.StartCoroutine(UpdateTargetRenderer()); + } + + protected virtual void LateUpdate() + { + if (isRoot) + { + transform.localPosition = new Vector3(-0.04f, 0, 0); // slight offset in the shadow idk why + transform.localScale = Vector3.one; + transform.localRotation = Quaternion.identity; + } + else + { + transform.localPosition = target.transform.localPosition; + transform.localScale = target.transform.localScale; + transform.localRotation = target.transform.localRotation; + } + + if (targetRenderer) + { + shadowRenderer.enabled = targetRenderer.enabled && targetRenderer.gameObject.activeInHierarchy; + shadowRenderer.sprite = GetReplacementSprite(targetRenderer.sprite); + shadowRenderer.SetColorAlpha(targetRenderer.color.a); + shadowRenderer.flipX = targetRenderer.flipX; + shadowRenderer.flipY = targetRenderer.flipY; + shadowRenderer.size = targetRenderer.size; + shadowRenderer.drawMode = targetRenderer.drawMode; + shadowRenderer.tileMode = targetRenderer.tileMode; + shadowRenderer.adaptiveModeThreshold = targetRenderer.adaptiveModeThreshold; + } + } + + protected virtual Sprite GetReplacementSprite(Sprite spriteToGet) + { + if (!spriteToGet) return null; + + if (_cachedSprites.TryGetValue(spriteToGet, out Sprite cachedShadowSprite) && cachedShadowSprite) + { + return cachedShadowSprite; + } + + string spriteName = spriteToGet.name; + Sprite newShadowSprite = replacementSprites.FirstOrDefault(s => s.name == spriteName); + + if (newShadowSprite) + { + _cachedSprites[spriteToGet] = newShadowSprite; + return newShadowSprite; + } + + return spriteToGet; + } + + [HideFromIl2Cpp] + // ReSharper disable once FunctionRecursiveOnAllPaths + private IEnumerator UpdateTargetRenderer() + { + targetRenderer = target.GetComponent(); + yield return new WaitForSeconds(1); + yield return UpdateTargetRenderer(); + } +} diff --git a/Submerged/Floors/Objects/SubmergedDeadBody.cs b/Submerged/Floors/Objects/SubmergedDeadBody.cs deleted file mode 100644 index 0c5dbc85..00000000 --- a/Submerged/Floors/Objects/SubmergedDeadBody.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Linq; -using PowerTools; -using Reactor.Utilities.Attributes; -using UnityEngine; - -namespace Submerged.Floors.Objects; - -[RegisterInIl2Cpp] -public sealed class SubmergedDeadBody(nint ptr) : MonoBehaviour(ptr) -{ - public DeadBody parent; - public SpriteRenderer shadowRenderer; - public SpriteAnim bodyAnim; - - private void Awake() - { - parent = GetComponent(); - bodyAnim = parent.bodyRenderers.First().GetComponent(); - } - - private void Start() - { - parent.bodyRenderers.First().gameObject.layer = 8; - - shadowRenderer = new GameObject("Submerged Shadow") { layer = 4 }.AddComponent(); - Transform shadowRendererTransform = shadowRenderer.transform; - shadowRendererTransform.parent = transform; - shadowRendererTransform.localPosition = bodyAnim.transform.localPosition; - shadowRendererTransform.localScale = new Vector3(0.5f, 0.5f, 1f); - } - - private void Update() - { - if (bodyAnim.IsPlaying()) - { - shadowRenderer.sprite = parent.bodyRenderers.First().sprite; - } - } -} diff --git a/Submerged/IL2CPP/InteropPatches.cs b/Submerged/IL2CPP/InteropPatches.cs index 015efe0e..7bb65150 100644 --- a/Submerged/IL2CPP/InteropPatches.cs +++ b/Submerged/IL2CPP/InteropPatches.cs @@ -21,7 +21,7 @@ public static class InteropPatches { private static readonly Harmony _harmony = new(nameof(InteropPatches)); - public static void Initialize() + internal static void Initialize() { _harmony.PatchAll(typeof(InteropPatches)); } diff --git a/Submerged/KillAnimation/Patches/OxygenDeathAnimationPatches.cs b/Submerged/KillAnimation/Patches/OxygenDeathAnimationPatches.cs index 7acf5d11..a08d07a6 100644 --- a/Submerged/KillAnimation/Patches/OxygenDeathAnimationPatches.cs +++ b/Submerged/KillAnimation/Patches/OxygenDeathAnimationPatches.cs @@ -51,7 +51,7 @@ private static OverlayKillAnimation OxygenDeath [HarmonyPrefix] public static bool ShowOxygenKillAnimationPatch(KillOverlay __instance, [HarmonyArgument(0)] GameData.PlayerInfo killer, [HarmonyArgument(1)] GameData.PlayerInfo victim) { - if (killer.PlayerId != victim.PlayerId || !IsOxygenDeath || Constants.ShouldHorseAround()) return true; + if (killer.PlayerId != victim.PlayerId || !IsOxygenDeath || AprilFoolsMode.ShouldHorseAround() || AprilFoolsMode.ShouldLongAround()) return true; __instance.ShowKillAnimation(OxygenDeath, killer, victim); diff --git a/Submerged/Localization/Patches/SatelliteLoadPatches.cs b/Submerged/Localization/Patches/SatelliteLoadPatches.cs index 0807d3eb..e71fd647 100644 --- a/Submerged/Localization/Patches/SatelliteLoadPatches.cs +++ b/Submerged/Localization/Patches/SatelliteLoadPatches.cs @@ -1,4 +1,4 @@ -using System.Globalization; +using System.Globalization; using System.Reflection; using HarmonyLib; using ResourceEmbedderCompilerGenerated; diff --git a/Submerged/Localization/Strings/General.it.resx b/Submerged/Localization/Strings/General.it.resx new file mode 100644 index 00000000..59929c1f --- /dev/null +++ b/Submerged/Localization/Strings/General.it.resx @@ -0,0 +1,46 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + Arte Aggiuntiva + + + Artisti + + + Sviluppatori + + + Design Mappa + + + Capo Proggetto + + + Supporto Tecnico + + + Traduttori + + + Impossibile iniziare la partita, poiché i seguenti giocatori non hanno Submerged: + + + Errore caricamento dati Submerged. Riavvia il gioco. +Se il problema persiste, reinstalla Submerged o segnala l'errore su GitHub. + + \ No newline at end of file diff --git a/Submerged/Localization/Strings/Locations.it.resx b/Submerged/Localization/Strings/Locations.it.resx new file mode 100644 index 00000000..4b89608e --- /dev/null +++ b/Submerged/Localization/Strings/Locations.it.resx @@ -0,0 +1,60 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + Stiva + + + Centrale + + + Centrale Inferiore + + + Centrale Superiore + + + Livello inferiore + + + Livello Superiore + + + Ascensore + + + Ascensore Tecnica + + + Filtrazione + + + Lobby + + + Lobby Inferiore + + + Lobby Superiore + + + Osservatorio + + + Ricerca + + \ No newline at end of file diff --git a/Submerged/Localization/Strings/Tasks.it.resx b/Submerged/Localization/Strings/Tasks.it.resx new file mode 100644 index 00000000..68686a54 --- /dev/null +++ b/Submerged/Localization/Strings/Tasks.it.resx @@ -0,0 +1,285 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + ATTIVO + + + DISABILITATE + + + RIPARANDO + + + Pulisci Vetro + + + Pulisci Animali + + + Riattiva Reattore + + + RPM:{0}​ + + + Diagnosi Ascensori + + + DIAGNOSI + + + Distribuisci Acqua + + + Dare Da Mangiare Al Pesce + + + Individua Creatura + + + Pesce Supporto Morale + + + Individua Attività Vulcanica + + + Stratovulcano Conico +Altezza: 2,377 Metri +Stato: Attivo +Rischio: Basso + + + Stratovulcano Conico +Altezza: 2,377 Metri +Stato: Attivo +Rischio: IMMINENTE + + + Pranzo Forno A Micronde + + + Tempo: {0}s +Nota per se: + +Prendi quando + finisce il timer + + + Ricorda Di Pulire Dopo l'Utilizzo + + - Verde + & Lime + + + Non Mangiare La Mia Fetta Di pizza! + - Rosa + + + {0}:{1}​ + + + Pulisci Pozzanghere + + + Ossigena Piante + + + Pulisci Foglie + + + Compra Colazione + + + OFFERTE: + + + Riconnetti Tubature + + + <b><size=125%>ALTA</size> +PRESSIONE</b> + + + Registra Informazioni Del Radar Di Navigazione + + + Messagio Ricevuto. + + + Entra Coordinate Del Radar Di Navigazione + + + Ricevimento Messaggio... + + + Riattiva Elettricità + + + Riordina Libri + + + <size=125%>A</size>cquari e cosa sono + + + <size=125%>B</size>rodo Etnico + + + <size=125%>C</size>reature di Caverne + + + <size=125%>E</size>sotica Vita Marina + + + <size=125%>F</size>riggendo Nemo + + + <size=125%>I</size>ctiologia 101 + + + <size=125%>J</size>immy Il Pesciolone + + + <size=125%>L</size>eggereper Amongussini + + + <size=125%>M</size>angrovie tutto il +Lunedì + + + <size=125%>N</size>autico Viaggio + + + <size=125%>O</size>rnitorinchi Da Cucinare + + + <size=125%>P</size>rovare A Nuotare! + + + <size=125%>S</size>e Non Sai Che Fare Durante Un Sabotaggio + + + <size=125%>V</size>iaggi Perfetti + + + <size=125%>X</size>ilofoni Migliori + + + Prendi Mascgera Ossigeno + + + Spara Carichi Subacquei + + + Carichi Rimanenti: {0} + + + Metti In Ordine Equipaghiamento Scuba + + + Caricamento... ({0}/{1}) + + + Giocatori Pronti: {0}/{1} + + + Aspwttando I Giocatori... + + + Aspettando I Giocatori... ({0}s) + + + Aspettando L'Impostore... ({0}s) + + + Tempo Rimanente: {0}s + + + Trova lo Squalo Balena + + + In Vista {0}s + + + Invisibile {0}s + + + Stabilizza Livello Dell'Acqua + + + Attiva Sommergibile + + + MOTORI AUSILIARI + + + SISTEMI ESTERNI + + + MOTORI PRINCIPALE + + + SCUDI + + + Status: Attivo + + + Status: Inattivo + + + Stato: Accensione... + + + ARMI + + + Stabilizza Battito + + + Velocità + + + {0} +BPM​ + + + Stato: {0} + + + Irregolare + + + Stabilizzando + + + Stabile + + + <u>Note Paziente</u> + +Normal +Heart Rate: +{0} - {1} BPM + + + Traccia Manta Ray + + + Tracciando: {0}% + + diff --git a/Submerged/Map/Patches/AddSubmergedComponentsPatches.cs b/Submerged/Map/Patches/AddSubmergedComponentsPatches.cs index 08d98bd3..64029734 100644 --- a/Submerged/Map/Patches/AddSubmergedComponentsPatches.cs +++ b/Submerged/Map/Patches/AddSubmergedComponentsPatches.cs @@ -28,7 +28,7 @@ public static void AddDeadBodyComponentPatch(PlayerControl __instance) if (body) { - body.gameObject.AddComponent(); + body.gameObject.AddComponent(); body.gameObject.AddComponent(); } } diff --git a/Submerged/Map/Patches/HideAndSeekPatches.cs b/Submerged/Map/Patches/HideAndSeekPatches.cs index b7a09427..7432040d 100644 --- a/Submerged/Map/Patches/HideAndSeekPatches.cs +++ b/Submerged/Map/Patches/HideAndSeekPatches.cs @@ -2,7 +2,7 @@ using HarmonyLib; using Submerged.Extensions; using Submerged.Systems.Elevator; -using IntroCutscene_CoBegin = IntroCutscene._CoBegin_d__33; +using IntroCutscene_CoBegin = IntroCutscene._CoBegin_d__35; namespace Submerged.Map.Patches; @@ -29,7 +29,7 @@ public static void DisableConsolesPatch() SubmarineStatus.instance.elevators.Do(e => { e.system.tandemSystemType = default; - e.system.upperDeckIsTargetFloor = !SubmergedHnSManager.CurrentGameIsOnUpperDeck; + e.system.upperDeckIsTargetFloor = SubmergedHnSManager.CurrentGameIsOnUpperDeck; }); } diff --git a/Submerged/Map/Patches/PreventMoveDuringIntroPatches.cs b/Submerged/Map/Patches/PreventMoveDuringIntroPatches.cs index ebdfa928..65d42241 100644 --- a/Submerged/Map/Patches/PreventMoveDuringIntroPatches.cs +++ b/Submerged/Map/Patches/PreventMoveDuringIntroPatches.cs @@ -1,6 +1,6 @@ using HarmonyLib; using Submerged.Extensions; -using IntroCutscene_CoBegin = IntroCutscene._CoBegin_d__33; +using IntroCutscene_CoBegin = IntroCutscene._CoBegin_d__35; namespace Submerged.Map.Patches; diff --git a/Submerged/Map/SubmarineStatus.cs b/Submerged/Map/SubmarineStatus.cs index 8f950870..b72c06d7 100644 --- a/Submerged/Map/SubmarineStatus.cs +++ b/Submerged/Map/SubmarineStatus.cs @@ -32,7 +32,6 @@ public sealed class SubmarineStatus(nint intPtr) : MonoBehaviour(intPtr) public static SubmarineStatus instance; public ShipStatus normalShip; - public MinigameProperties minigameProperties; public List elevators = []; public bool shakeOverridden; public GameObject vitalsPanel; @@ -43,6 +42,9 @@ public sealed class SubmarineStatus(nint intPtr) : MonoBehaviour(intPtr) public AudioSource powerUpSound; public SwitchSystem switchSystem; + public MinigameProperties minigameProperties; + public Tilemap2 aprilFoolsShadowSpritesHolder; + private float _ventTransitionTimer; private static float CrewLightMod => GameOptionsManager.Instance.CurrentGameOptions.GetFloat(FloatOptionNames.CrewLightMod); @@ -68,6 +70,7 @@ public void Awake() minigameProperties = gameObject.AddComponent(); minigameProperties.Awake(); DestroyImmediate(GetComponent()); + aprilFoolsShadowSpritesHolder = transform.Find("MinigameProperties/April Fools Shadow Sprites").GetComponent(); ResolveTaskMinigames(normalShip.CommonTasks); ResolveTaskMinigames(normalShip.LongTasks); @@ -76,6 +79,7 @@ public void Awake() ResolveSystemConsoleMinigames(normalShip.GetComponentsInChildren()); ResolveDoorMinigames(); ResolveExileController(); + ResolveCooldownConsoles(normalShip.AllConsoles); normalShip.CommonTasks[0].Arrow = normalShip.CommonTasks[0].gameObject.GetComponentInChildren(); @@ -137,17 +141,7 @@ public void Awake() private void Start() { - if (!TutorialManager.InstanceExists) - { - foreach (PlayerControl player in FindObjectsOfType()) - { - player.gameObject.EnsureComponent().playerControl = player; - } - } - else - { - this.StartCoroutine(CoAddShadows()); - } + this.StartCoroutine(CoAddShadows()); } private void Update() @@ -251,13 +245,13 @@ private void OnDestroy() } [HideFromIl2Cpp] - private IEnumerator CoAddShadows() + private static IEnumerator CoAddShadows() { while (!PlayerControl.LocalPlayer) yield return null; foreach (PlayerControl player in FindObjectsOfType()) { - player.gameObject.EnsureComponent().playerControl = player; + player.transform.Find("BodyForms").gameObject.EnsureComponent(); } } @@ -371,6 +365,16 @@ public float GetSabotagedLightRadiusAndPlaySounds(bool isImpostor) return Mathf.Lerp(0, normalShip.MinLightRadius, Mathf.Clamp01(adjustedamount)) * CrewLightMod; } + [HideFromIl2Cpp] + public Sprite[] GetReplacementShadowSprites(string objectName) + { + return objectName switch + { + "Horse" or "LongBoiBody" or "LongSeekerBody" => aprilFoolsShadowSpritesHolder.sprites, + _ => minigameProperties.sprites + }; + } + #region Resolve Stuff private void ResolveBaseGameMinigame(TaskTypes taskType, ShipStatus from) @@ -470,7 +474,7 @@ private void ResolveTaskMinigames(Il2CppReferenceArray tasks) where T : Pl } [HideFromIl2Cpp] - private void ResolveSystemConsoleMinigames(SystemConsole[] consoles) + private void ResolveSystemConsoleMinigames(IEnumerable consoles) { List<(SystemConsole console, GameObject minigameObject)> consoleMinigames = []; IEnumerable filteredConsoles = consoles.Where(c => c.MinigamePrefab && c.MinigamePrefab.GetComponent()); @@ -562,6 +566,30 @@ private void ResolveDoorMinigames() } } + [HideFromIl2Cpp] + private void ResolveCooldownConsoles(IEnumerable consoles) + { + foreach (Console console in consoles) + { + if (console == null || !console.name.Contains("-CooldownConsole-")) continue; + + CooldownConsole cooldownConsole = console.gameObject.AddComponent(); + cooldownConsole.usableDistance = console.usableDistance; + cooldownConsole.ConsoleId = console.ConsoleId; + cooldownConsole.onlyFromBelow = console.onlyFromBelow; + cooldownConsole.onlySameRoom = console.onlySameRoom; + cooldownConsole.checkWalls = console.checkWalls; + cooldownConsole.GhostsIgnored = console.GhostsIgnored; + cooldownConsole.AllowImpostor = console.AllowImpostor; + cooldownConsole.Room = console.Room; + cooldownConsole.TaskTypes = console.TaskTypes; + cooldownConsole.ValidTasks = console.ValidTasks; + cooldownConsole.Image = console.Image; + + DestroyImmediate(console); + } + } + #endregion private static IEnumerable GetAllTasks(ShipStatus ship) diff --git a/Submerged/Minigames/CustomMinigames/OxygenateSeaPlants/DataStructures/CoralCell.cs b/Submerged/Minigames/CustomMinigames/OxygenateSeaPlants/DataStructures/CoralCell.cs index 682c5c16..ddaa48ca 100644 --- a/Submerged/Minigames/CustomMinigames/OxygenateSeaPlants/DataStructures/CoralCell.cs +++ b/Submerged/Minigames/CustomMinigames/OxygenateSeaPlants/DataStructures/CoralCell.cs @@ -1,9 +1,4 @@ -using System.Collections.Generic; -using Submerged.Extensions; -using Submerged.Minigames.CustomMinigames.OxygenateSeaPlants.Enums; -using UnityEngine; - -namespace Submerged.Minigames.CustomMinigames.OxygenateSeaPlants.DataStructures; +namespace Submerged.Minigames.CustomMinigames.OxygenateSeaPlants.DataStructures; public sealed class CoralCell { diff --git a/Submerged/Minigames/CustomMinigames/OxygenateSeaPlants/OxygenateCoralMinigame.cs b/Submerged/Minigames/CustomMinigames/OxygenateSeaPlants/OxygenateCoralMinigame.cs index 56d57973..d0c8765d 100644 --- a/Submerged/Minigames/CustomMinigames/OxygenateSeaPlants/OxygenateCoralMinigame.cs +++ b/Submerged/Minigames/CustomMinigames/OxygenateSeaPlants/OxygenateCoralMinigame.cs @@ -9,6 +9,7 @@ using Submerged.Extensions; using Submerged.Minigames.CustomMinigames.OxygenateSeaPlants.DataStructures; using Submerged.Minigames.CustomMinigames.OxygenateSeaPlants.MonoBehaviours; +using Submerged.Minigames.MonoBehaviours; using UnityEngine; namespace Submerged.Minigames.CustomMinigames.OxygenateSeaPlants; @@ -374,7 +375,8 @@ private static void DoAroundPoint(T[,] arr, (int initialX, int initialY) poin public override void Close() { - MyNormTask.Cast().timer = 3; + CooldownConsole cc = Console.Cast(); + cc.CoolDown = cc.MaxCoolDown; this.BaseClose(); } diff --git a/Submerged/Minigames/CustomMinigames/PurchaseBreakfast/PurchaseBreakfastMinigame.cs b/Submerged/Minigames/CustomMinigames/PurchaseBreakfast/PurchaseBreakfastMinigame.cs index f143ee5f..a86ddf56 100644 --- a/Submerged/Minigames/CustomMinigames/PurchaseBreakfast/PurchaseBreakfastMinigame.cs +++ b/Submerged/Minigames/CustomMinigames/PurchaseBreakfast/PurchaseBreakfastMinigame.cs @@ -542,7 +542,8 @@ public static List ShuffleWithRandomCopy(List list, SystemRandom random public override void Close() { - MyNormTask.Cast().timer = 3; + CooldownConsole cc = Console.Cast(); + cc.CoolDown = cc.MaxCoolDown; this.BaseClose(); } } diff --git a/Submerged/Minigames/CustomMinigames/SpotWhaleShark/WhaleSharkTask.cs b/Submerged/Minigames/CustomMinigames/SpotWhaleShark/WhaleSharkTask.cs index d0a4f2c7..e764b2ec 100644 --- a/Submerged/Minigames/CustomMinigames/SpotWhaleShark/WhaleSharkTask.cs +++ b/Submerged/Minigames/CustomMinigames/SpotWhaleShark/WhaleSharkTask.cs @@ -48,7 +48,7 @@ public override void FixedUpdate() } } - [BaseGameCode(LastChecked.v2023_10_24, "Part of this method comes from NormalPlayerTask.AppendTaskText")] + [BaseGameCode(LastChecked.v2024_3_5, "Part of this method comes from NormalPlayerTask.AppendTaskText")] public override void AppendTaskText(StringBuilder sb) { bool canComplete = CanComplete(PlayerControl.LocalPlayer); diff --git a/Submerged/Minigames/MonoBehaviours/CooldownConsole.cs b/Submerged/Minigames/MonoBehaviours/CooldownConsole.cs new file mode 100644 index 00000000..bcb7735d --- /dev/null +++ b/Submerged/Minigames/MonoBehaviours/CooldownConsole.cs @@ -0,0 +1,21 @@ +using Reactor.Utilities.Attributes; +using Submerged.BaseGame.Interfaces; +using UnityEngine; + +namespace Submerged.Minigames.MonoBehaviours; + +[RegisterInIl2Cpp(typeof(IUsableCoolDown))] +public sealed class CooldownConsole(nint ptr) : Console(ptr), AU.IUsableCoolDown +{ + public float CoolDown { get; set; } + public float MaxCoolDown { get; set; } = 3; + + public bool IsCoolingDown() => CoolDown > 0; + + private void Update() + { + CoolDown = Mathf.Max(0, CoolDown - Time.deltaTime); + } + + public override float PercentCool => CoolDown / MaxCoolDown; +} diff --git a/Submerged/Minigames/Patches/Minigame_Patches.cs b/Submerged/Minigames/Patches/Minigame_Patches.cs index 9e8bf269..79a3495b 100644 --- a/Submerged/Minigames/Patches/Minigame_Patches.cs +++ b/Submerged/Minigames/Patches/Minigame_Patches.cs @@ -2,9 +2,10 @@ namespace Submerged.Minigames.Patches; -[HarmonyPatch(typeof(Minigame), nameof(Minigame.Begin))] +[HarmonyPatch] public static class MinigameBeginPatch { + [HarmonyPatch(typeof(Minigame), nameof(Minigame.Begin))] [HarmonyPrefix] public static void Prefix(Minigame __instance) { diff --git a/Submerged/Minigames/CustomMinigames/CooldownPlayerTask.cs b/Submerged/Obsolete/CooldownPlayerTask.cs similarity index 52% rename from Submerged/Minigames/CustomMinigames/CooldownPlayerTask.cs rename to Submerged/Obsolete/CooldownPlayerTask.cs index f0babf0d..4be65d7b 100644 --- a/Submerged/Minigames/CustomMinigames/CooldownPlayerTask.cs +++ b/Submerged/Obsolete/CooldownPlayerTask.cs @@ -5,9 +5,11 @@ using Submerged.BaseGame; using UnityEngine; +// ReSharper disable all + namespace Submerged.Minigames.CustomMinigames; -// TODO: change this to cooldown consoles or something idk +[Obsolete("This class has been replaced by CooldownConsole and might be removed in a future update. It is recommended to stop using it and instead switch to CooldownConsole, or a custom component implementing IUsableCoolDown.")] [RegisterInIl2Cpp] public sealed class CooldownPlayerTask(nint ptr) : NormalPlayerTask(ptr) { @@ -15,6 +17,12 @@ public sealed class CooldownPlayerTask(nint ptr) : NormalPlayerTask(ptr) private void Awake() { + Warning("CooldownPlayerTask is no longer used in Submerged and might be removed in a future update. Please use CooldownConsole instead, or implement your own IUsableCoolDown!"); + Warning("CooldownPlayerTask is no longer used in Submerged and might be removed in a future update. Please use CooldownConsole instead, or implement your own IUsableCoolDown!"); + Warning("CooldownPlayerTask is no longer used in Submerged and might be removed in a future update. Please use CooldownConsole instead, or implement your own IUsableCoolDown!"); + Warning("CooldownPlayerTask is no longer used in Submerged and might be removed in a future update. Please use CooldownConsole instead, or implement your own IUsableCoolDown!"); + Warning("CooldownPlayerTask is no longer used in Submerged and might be removed in a future update. Please use CooldownConsole instead, or implement your own IUsableCoolDown!"); + MaxStep = 1; } @@ -42,14 +50,14 @@ public override void AppendTaskText(StringBuilder sb) sb.Append(""); } - [BaseGameCode(LastChecked.v2023_10_24, "Default switch case of NormalPlayerTask.ValidConsole, none of the other cases apply")] + [BaseGameCode(LastChecked.v2024_3_5, "Default switch case of NormalPlayerTask.ValidConsole, none of the other cases apply")] private bool BaseValidConsole(Console console) { return console.TaskTypes.Any(tt => tt == TaskType) || console.ValidTasks.Any(set => TaskType == set.taskType && set.taskStep.Contains(taskStep)); } - [BaseGameCode(LastChecked.v2023_10_24, "NormalPlayerTask.AppendTaskText with steps and timer conditions removed because they are never met")] + [BaseGameCode(LastChecked.v2024_3_5, "NormalPlayerTask.AppendTaskText with steps and timer conditions removed because they are never met")] private void BaseAppendTaskText(StringBuilder sb) { if (IsComplete) sb.Append(""); diff --git a/Submerged/Obsolete/ExileController.cs b/Submerged/Obsolete/ExileController.cs new file mode 100644 index 00000000..6dd92b46 --- /dev/null +++ b/Submerged/Obsolete/ExileController.cs @@ -0,0 +1,31 @@ +using System; +using System.Reflection; + +// ReSharper disable all + +namespace Submerged.BaseGame.Patches; + +[Obsolete("Submerged no longer prefix patches ExileController.Begin. You do not need to worry about special compatibility when patching.", true)] +public static class ExileControllerPatches +{ + [Obsolete("Submerged no longer prefix patches ExileController.Begin. You do not need to worry about special compatibility when patching.", true)] + public static void DisablePrefixWarningForHarmonyId(string id) + { + Error("Submerged no longer prefix patches ExileController.Begin. You do not need to worry about special compatibility when patching."); + Error("Submerged no longer prefix patches ExileController.Begin. You do not need to worry about special compatibility when patching."); + Error("Submerged no longer prefix patches ExileController.Begin. You do not need to worry about special compatibility when patching."); + Error("Submerged no longer prefix patches ExileController.Begin. You do not need to worry about special compatibility when patching."); + Error("Submerged no longer prefix patches ExileController.Begin. You do not need to worry about special compatibility when patching."); + } + + [Obsolete("Submerged no longer prefix patches ExileController.Begin. You do not need to worry about special compatibility when patching.", true)] + public static void ExileController_Begin(ExileController self, GameData.PlayerInfo exiled, bool tie) + { + } + + [Obsolete("Submerged no longer prefix patches ExileController.Begin. You do not need to worry about special compatibility when patching.", true)] + public static bool BeginPatch(ExileController __instance, MethodInfo __originalMethod, GameData.PlayerInfo exiled, bool tie) + { + return false; + } +} diff --git a/Submerged/Floors/Objects/PlayerShadowBehaviour.cs b/Submerged/Obsolete/PlayerShadowBehaviour.cs similarity index 61% rename from Submerged/Floors/Objects/PlayerShadowBehaviour.cs rename to Submerged/Obsolete/PlayerShadowBehaviour.cs index 68cc7796..9bd077c2 100644 --- a/Submerged/Floors/Objects/PlayerShadowBehaviour.cs +++ b/Submerged/Obsolete/PlayerShadowBehaviour.cs @@ -1,12 +1,16 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Reactor.Utilities.Attributes; using Submerged.Map; using UnityEngine; +// ReSharper disable all + namespace Submerged.Floors.Objects; [RegisterInIl2Cpp] +[Obsolete("This component is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead.")] public sealed class PlayerShadowBehaviour(nint ptr) : MonoBehaviour(ptr) { public GameObject shadowObj; @@ -20,12 +24,18 @@ public sealed class PlayerShadowBehaviour(nint ptr) : MonoBehaviour(ptr) public void Start() { + Warning("PlayerShadowBehaviour is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead!"); + Warning("PlayerShadowBehaviour is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead!"); + Warning("PlayerShadowBehaviour is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead!"); + Warning("PlayerShadowBehaviour is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead!"); + Warning("PlayerShadowBehaviour is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead!"); + Camera.main!.cullingMask = 1073969927; // yay magic numbers shadowObj = new GameObject("Submerged Shadow") { layer = 4 }; shadowRend = shadowObj.AddComponent(); shadowObj.transform.parent = transform; shadowObj.transform.localPosition = Vector3.zero; - shadowObj.transform.localScale = Constants.ShouldHorseAround() ? new Vector3(0.6734f * 0.5f, 0.6734f * 0.5f, 1f) : new Vector3(0.5f, 0.5f, 1f); + shadowObj.transform.localScale = AprilFoolsMode.ShouldHorseAround() ? new Vector3(0.6734f * 0.5f, 0.6734f * 0.5f, 1f) : new Vector3(0.5f, 0.5f, 1f); shadowColor = shadowRend.color; sprites = SubmarineStatus.instance.minigameProperties.sprites; diff --git a/Submerged/Obsolete/SubmergedDeadBody.cs b/Submerged/Obsolete/SubmergedDeadBody.cs new file mode 100644 index 00000000..a59dedd5 --- /dev/null +++ b/Submerged/Obsolete/SubmergedDeadBody.cs @@ -0,0 +1,49 @@ +using System; +using System.Linq; +using PowerTools; +using Reactor.Utilities.Attributes; +using UnityEngine; + +// ReSharper disable all + +namespace Submerged.Floors.Objects; + +[RegisterInIl2Cpp] +[Obsolete("This component is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead.")] +public sealed class SubmergedDeadBody(nint ptr) : MonoBehaviour(ptr) +{ + public DeadBody parent; + public SpriteRenderer shadowRenderer; + public SpriteAnim bodyAnim; + + private void Awake() + { + Warning("SubmergedDeadBody is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead!"); + Warning("SubmergedDeadBody is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead!"); + Warning("SubmergedDeadBody is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead!"); + Warning("SubmergedDeadBody is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead!"); + Warning("SubmergedDeadBody is no longer used in Submerged and might be removed in a future update. Please use GenericShadowBehaviour instead!"); + + parent = GetComponent(); + bodyAnim = parent.bodyRenderers.First().GetComponent(); + } + + private void Start() + { + parent.bodyRenderers.First().gameObject.layer = LayerMask.NameToLayer("Players"); + + shadowRenderer = new GameObject("Submerged Shadow") { layer = 4 }.AddComponent(); + Transform shadowRendererTransform = shadowRenderer.transform; + shadowRendererTransform.parent = transform; + shadowRendererTransform.localPosition = bodyAnim.transform.localPosition; + shadowRendererTransform.localScale = new Vector3(0.5f, 0.5f, 1f); + } + + private void Update() + { + if (bodyAnim.IsPlaying()) + { + shadowRenderer.sprite = parent.bodyRenderers.First().sprite; + } + } +} diff --git a/Submerged/Resources/AssetBundles/submerged b/Submerged/Resources/AssetBundles/submerged index 744f872c..63b408f1 100644 Binary files a/Submerged/Resources/AssetBundles/submerged and b/Submerged/Resources/AssetBundles/submerged differ diff --git a/Submerged/SpawnIn/SubmarineSelectSpawn.cs b/Submerged/SpawnIn/SubmarineSelectSpawn.cs index 0023f1b4..88152b60 100644 --- a/Submerged/SpawnIn/SubmarineSelectSpawn.cs +++ b/Submerged/SpawnIn/SubmarineSelectSpawn.cs @@ -404,7 +404,7 @@ protected virtual IEnumerator DoPreAnimationLogicWhenFloorClicked() yield break; } - [BaseGameCode(LastChecked.v2023_10_24, "Part of this method is from ExileController.ReEnableGameplay")] + [BaseGameCode(LastChecked.v2024_3_5, "Part of this method is from ExileController.ReEnableGameplay")] private void Cleanup(bool unfade = true) { if (unfade) HudManager.Instance.StartCoroutine(HudManager.Instance.CoFadeFullScreen(Color.black, Color.clear)); diff --git a/Submerged/Submerged.csproj b/Submerged/Submerged.csproj index 542516e2..e716304b 100644 --- a/Submerged/Submerged.csproj +++ b/Submerged/Submerged.csproj @@ -1,6 +1,6 @@ - + - 2023.11.29 + 2024.3.24 Submerged Team git https://github.com/SubmergedAmongUs/Submerged @@ -17,7 +17,7 @@ - + diff --git a/Submerged/UI/CreditsScreenManager.cs b/Submerged/UI/CreditsScreenManager.cs index 539f932c..388da19a 100644 --- a/Submerged/UI/CreditsScreenManager.cs +++ b/Submerged/UI/CreditsScreenManager.cs @@ -9,7 +9,7 @@ namespace Submerged.UI; public sealed class CreditsScreenManager(nint ptr) : MonoBehaviour(ptr) { private const string TRANSLATORS = "DekoKiyo (日本語), ItsNiceCraft (Deutsch), MissJukebox (Español),\n" + - "Monid73 (Русский), RevoLou (Português do Brasil), RobinRMC (Nederlands),\n" + + "Monid73 (Русский), PENGUN (Italiano), RevoLou (Português do Brasil), RobinRMC (Nederlands),\n" + "SPRLC (Français), ねろちゃん (日本語), 阿龍DragonTw (繁體中文), 黑客Hecker (简体中文)"; public void Awake() diff --git a/Submerged/UI/Patches/MapSelectButtonPatches.cs b/Submerged/UI/Patches/MapSelectButtonPatches.cs index 4410ba8b..90e1ebe9 100644 --- a/Submerged/UI/Patches/MapSelectButtonPatches.cs +++ b/Submerged/UI/Patches/MapSelectButtonPatches.cs @@ -37,6 +37,7 @@ public static void AdjustFreeplayMenuPatch(FreeplayPopover __instance) submergedButton.name = "SubmergedButton"; submergedButton.map = CustomMapNames.Submerged; submergedButton.GetComponent().sprite = ResourceManager.spriteCache["Logo"]; + submergedButton.OnPressEvent = fungleButton.OnPressEvent; fungleButton.transform.position = new Vector3(__instance.buttons[0].transform.position.x, fungleButton.transform.position.y, fungleButton.transform.position.z); submergedButton.transform.position = new Vector3(__instance.buttons[1].transform.position.x, fungleButton.transform.position.y, fungleButton.transform.position.z); diff --git a/Submerged/UI/Patches/VersionShowerPatches.cs b/Submerged/UI/Patches/VersionShowerPatches.cs index 877eedee..5b495f8a 100644 --- a/Submerged/UI/Patches/VersionShowerPatches.cs +++ b/Submerged/UI/Patches/VersionShowerPatches.cs @@ -10,6 +10,7 @@ public static class VersionShowerPatches [HarmonyPriority(Priority.Last)] public static void PingTrackerPatch(PingTracker __instance) { - __instance.text.text += $"\n{SubmergedPlugin.VersionText}"; + if (!__instance.text.text.EndsWith("\n")) __instance.text.text += "\n"; + __instance.text.text += $"{SubmergedPlugin.VersionText}"; } } diff --git a/Submerged/Vents/Patches/HideAndSeekPatches.cs b/Submerged/Vents/Patches/HideAndSeekPatches.cs index 14e08233..adfa880e 100644 --- a/Submerged/Vents/Patches/HideAndSeekPatches.cs +++ b/Submerged/Vents/Patches/HideAndSeekPatches.cs @@ -1,6 +1,5 @@ using HarmonyLib; using Submerged.Extensions; -using IntroCutscene_CoBegin = IntroCutscene._CoBegin_d__33; using static Submerged.Vents.VentPatchData; namespace Submerged.Vents.Patches; diff --git a/nuget.config b/nuget.config index ab24e8a0..1af36ff0 100644 --- a/nuget.config +++ b/nuget.config @@ -1,4 +1,4 @@ - + @@ -7,4 +7,4 @@ - \ No newline at end of file +