diff --git a/AlterraWeaponry/AlterraWeaponry.csproj b/AlterraWeaponry/AlterraWeaponry.csproj index 3f77afd..41cc3c3 100644 --- a/AlterraWeaponry/AlterraWeaponry.csproj +++ b/AlterraWeaponry/AlterraWeaponry.csproj @@ -35,17 +35,17 @@ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'BZ|AnyCPU' "> <OutputPath>bin\BZ\</OutputPath> <PlatformTarget>AnyCPU</PlatformTarget> + <DefineConstants>BZ; BELOWZERO; BELOW_ZERO;</DefineConstants> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'SN1|AnyCPU' "> <OutputPath>bin\SN1\</OutputPath> + <DefineConstants>SN1; SN; SUBNAUTICA;</DefineConstants> </PropertyGroup> <ItemGroup> <Reference Include="0Harmony"> <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\BepInEx\core\0Harmony.dll</HintPath> </Reference> - <Reference Include="Assembly-CSharp"> - <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\SubnauticaZero_Data\Managed\Assembly-CSharp.dll</HintPath> - </Reference> <Reference Include="Assembly-CSharp-firstpass"> <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\SubnauticaZero_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath> </Reference> @@ -55,20 +55,29 @@ <Reference Include="BepInEx"> <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\BepInEx\core\BepInEx.dll</HintPath> </Reference> + <Reference Include="CuddleLibs"> + <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\BepInEx\plugins\CuddleLibs\CuddleLibs.dll</HintPath> + </Reference> <Reference Include="FMODUnity"> <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\SubnauticaZero_Data\Managed\FMODUnity.dll</HintPath> </Reference> - <Reference Include="SMLHelper"> - <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\QMods\SMLHelper_BZ\SMLHelper.dll</HintPath> + <Reference Include="Nautilus"> + <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\BepInEx\plugins\Nautilus\Nautilus.dll</HintPath> </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> + <Reference Include="System.IO.Compression" /> + <Reference Include="System.IO.Compression.FileSystem" /> <Reference Include="System.Xml.Linq" /> <Reference Include="System.Data.DataSetExtensions" /> <Reference Include="Microsoft.CSharp" /> <Reference Include="System.Data" /> <Reference Include="System.Net.Http" /> <Reference Include="System.Xml" /> + <Reference Include="Unity.Addressables, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\SubnauticaZero_Data\Managed\Unity.Addressables.dll</HintPath> + </Reference> <Reference Include="Unity.TextMeshPro"> <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\SubnauticaZero_Data\Managed\Unity.TextMeshPro.dll</HintPath> </Reference> @@ -103,39 +112,32 @@ </Reference> </ItemGroup> <ItemGroup> - <Compile Include="behaviours\CustomTriggerEventAssigner.cs" /> - <Compile Include="behaviours\ZapFunctionalityBehaviour.cs" /> - <Compile Include="items\PrawnSelfDefenseModule.cs" /> - <Compile Include="patches\ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs" /> - <Compile Include="patches\GameSettings_SaveAsync_Patch.cs" /> - <Compile Include="patches\SeamothTorpedo_OnEnergyDepleted_Patch.cs" /> - <Compile Include="patches\Vehicle_ChargeModule_Patch.cs" /> - <Compile Include="patches\Vehicle_GetSlotCharge_Patch.cs" /> - <Compile Include="patches\Vehicle_OnUpgradeModuleChange_Patch.cs" /> - <Compile Include="patches\Vehicle_OnUpgradeModuleUse_Patch.cs" /> - <Compile Include="utils\ExplosiveTorpedoInitializer.cs" /> - <Compile Include="behaviours\TorpedoExplosionBehaviour.cs" /> + <Compile Include="Behaviours\CustomTriggerEventAssigner.cs" /> + <Compile Include="Behaviours\ZapFunctionalityBehaviour.cs" /> + <Compile Include="Items\PrawnSelfDefenseModule.cs" /> + <Compile Include="Patches\ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs" /> + <Compile Include="Patches\SeamothTorpedo_OnEnergyDepleted_Patch.cs" /> + <Compile Include="Utils\ExplosiveTorpedoInitializer.cs" /> + <Compile Include="Behaviours\TorpedoExplosionBehaviour.cs" /> <Compile Include="Global.cs" /> - <Compile Include="items\BlackPowder.cs" /> - <Compile Include="items\Coal.cs" /> - <Compile Include="items\ExplosiveTorpedo.cs" /> + <Compile Include="Items\BlackPowder.cs" /> + <Compile Include="Items\Coal.cs" /> + <Compile Include="Items\ExplosiveTorpedo.cs" /> <Compile Include="Main.cs" /> - <Compile Include="patches\ItemGoalTracker_Start_Patch.cs" /> - <Compile Include="patches\uGUISceneLoading_End_Patch.cs" /> - <Compile Include="patches\Vehicle_Awake_Patch.cs" /> + <Compile Include="Patches\ItemGoalTracker_Start_Patch.cs" /> + <Compile Include="Patches\uGUISceneLoading_End_Patch.cs" /> + <Compile Include="Patches\Vehicle_Awake_Patch.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="utils\LanguagesHandler.cs" /> + <Compile Include="Utils\GlobalInitializer.cs" /> + <Compile Include="Utils\LanguagesHandler.cs" /> + <Compile Include="Utils\Options.cs" /> + <Compile Include="Utils\ResourcesCacheManager.cs" /> </ItemGroup> <ItemGroup /> <ItemGroup> - <Content Include="assets\Coal.png" /> - <Content Include="assets\ExplosiveTorpedo.png" /> - <Content Include="assets\first_lethal_weapon_message.mp3" /> - <Content Include="assets\first_lethal_weapon_message.ogg" /> - <Content Include="assets\PrawnPerimeterDefense.png" /> - <Content Include="assets\prawn_shield.png" /> - <Content Include="assets\xenoworx_pda_presentation.mp3" /> <Content Include="Localizations.xml" /> + <None Include="Sounds\AudioClip.FirstLethalMessage.wav" /> + <None Include="Sounds\AudioClip.PWAPresentation.wav" /> </ItemGroup> <ItemGroup> <None Include="mod.json" /> @@ -145,6 +147,7 @@ <PostBuildEvent>mkdir "$(SubnauticaRootPath)\BepInEx\plugins\AlterraWeaponry" copy /Y "$(TargetPath)" "$(SubnauticaRootPath)\BepInEx\plugins\AlterraWeaponry\" copy /Y "$(ProjectDir)\alterraweaponry.assets" "$(SubnauticaRootPath)\BepInEx\plugins\AlterraWeaponry\" +copy /Y "$(ProjectDir)\alterraweaponry.assets.meta" "$(SubnauticaRootPath)\BepInEx\plugins\AlterraWeaponry\" copy /Y "$(ProjectDir)\Localizations.xml" "$(SubnauticaRootPath)\BepInEx\plugins\AlterraWeaponry\"</PostBuildEvent> </PropertyGroup> </Project> \ No newline at end of file diff --git a/AlterraWeaponry/Global.cs b/AlterraWeaponry/Global.cs index f31dbb0..e76c13a 100644 --- a/AlterraWeaponry/Global.cs +++ b/AlterraWeaponry/Global.cs @@ -15,22 +15,24 @@ global using BepInEx.Bootstrap; global using BepInEx.Configuration; global using BepInEx.Logging; -global using SMLHelper.V2.Assets; -global using SMLHelper.V2.Commands; -global using SMLHelper.V2.Crafting; -global using SMLHelper.V2.FMod; -global using SMLHelper.V2.FMod.Interfaces; -global using SMLHelper.V2.Interfaces; -global using SMLHelper.V2.Json; -global using SMLHelper.V2.Json.Attributes; -global using SMLHelper.V2.Json.Converters; -global using SMLHelper.V2.Json.ExtensionMethods; -global using SMLHelper.V2.Json.Interfaces; -global using SMLHelper.V2.Handlers; -global using SMLHelper.V2.MonoBehaviours; -global using SMLHelper.V2.Options; -global using SMLHelper.V2.Options.Attributes; -global using SMLHelper.V2.Utility; +global using Nautilus.Assets; +global using Nautilus.Assets.Gadgets; +global using Nautilus.Assets.PrefabTemplates; +global using Nautilus.Commands; +global using Nautilus.Crafting; +global using Nautilus.Extensions; +global using Nautilus.FMod; +global using Nautilus.FMod.Interfaces; +global using Nautilus.Handlers; +global using Nautilus.Json; +global using Nautilus.Json.Attributes; +global using Nautilus.Json.Converters; +global using Nautilus.Json.ExtensionMethods; +global using Nautilus.Json.Interfaces; +global using Nautilus.Options; +global using Nautilus.Options.Attributes; +global using Nautilus.Utility; +global using Nautilus.Utility.MaterialModifiers; global using HarmonyLib; global using HarmonyLib.Public; global using HarmonyLib.Public.Patching; @@ -44,9 +46,17 @@ global using UWE; global using UWE.Timeline; global using UWEScript; +global using FMOD; // LOCAL -global using VELD.AlterraWeaponry.items; -global using VELD.AlterraWeaponry.patches; -global using VELD.AlterraWeaponry.utils; -global using VELD.AlterraWeaponry.behaviours; \ No newline at end of file +global using VELD.AlterraWeaponry.Items; +global using VELD.AlterraWeaponry.Patches; +global using VELD.AlterraWeaponry.Utils; +global using VELD.AlterraWeaponry.Behaviours; + +// MY LIBS +global using CuddleLibs; +global using CuddleLibs.Assets; +global using CuddleLibs.Assets.Gadgets; +global using CuddleLibs.Interfaces; +global using CuddleLibs.Utility; \ No newline at end of file diff --git a/AlterraWeaponry/Localizations.xml b/AlterraWeaponry/Localizations.xml index 31f34ac..bc9ee12 100644 Binary files a/AlterraWeaponry/Localizations.xml and b/AlterraWeaponry/Localizations.xml differ diff --git a/AlterraWeaponry/Main.cs b/AlterraWeaponry/Main.cs index adc4003..3dbce59 100644 --- a/AlterraWeaponry/Main.cs +++ b/AlterraWeaponry/Main.cs @@ -4,149 +4,68 @@ public class Main : BaseUnityPlugin { // MOD INFO - private const string modName = "Alterra Weaponry"; - private const string modGUID = "com.VELD.AlterraWeaponry"; - private const string modVers = "1.0.3"; + internal const string modName = "Alterra Weaponry"; + internal const string modGUID = "com.VELD.AlterraWeaponry"; + internal const string modVers = "1.0.5"; + internal const string modLongVers = "1.0.5.1"; // BepInEx/Harmony/Unity private static readonly Harmony harmony = new(modGUID); public static ManualLogSource logger; // STORY GOALS -#if BZ - internal static StoryGoal AWPresentationGoal = new("Log_PDA_Goal_AWPresentation", Story.GoalType.PDA, 0f) { playInCreative = true, playInCinematics = false, delay = 8f }; -#endif + internal static StoryGoal AWPresentationGoal; + internal static ItemGoal AWFirstLethal; - public static readonly AssetBundle assets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "alterraweaponry.assets")); + public static ResourcesCacheManager AssetsCache { get; private set; } + internal static Options Options { get; } = OptionsPanelHandler.RegisterModOptions<Options>(); private void Awake() { logger = Logger; + try + { + AssetsCache = ResourcesCacheManager.LoadResources(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "alterraweaponry.assets")); + } + catch (Exception ex) + { + logger.LogFatal($"Fatal error occured: Unable to load resources to cache.\n{ex}"); + } logger.LogInfo($"{modName} {modVers} started patching."); harmony.PatchAll(); logger.LogInfo($"{modName} {modVers} harmony patched."); - - Coal coal = new(); - BlackPowder blackPowder = new(); - ExplosiveTorpedo explosiveTorpedo = new(); - PrawnSelfDefenseModule prawnSelfDefenseModule = new(); - - coal.Patch(); - blackPowder.Patch(); - explosiveTorpedo.Patch(); - prawnSelfDefenseModule.Patch(); - - logger.LogInfo($"{modName} {modVers} items registered."); - - LanguagesHandler.LanguagePatch(); + LanguagesHandler.GlobalPatch(); logger.LogInfo($"{modName} {modVers} languages lines patched."); - - RegisterPDAEncyEntries(); + GlobalInitializer.PatchPDAEncyEntries(); logger.LogInfo($"{modName} {modVers} PDA encyclopedia entries registered."); - RegisterPDALogs(); + GlobalInitializer.PatchGoals(); + logger.LogInfo($"{modName} {modVers} PDA goals initialized."); + GlobalInitializer.PatchPDALogs(); logger.LogInfo($"{modName} {modVers} PDA logs registered."); - } - - private void Update() - { - if(UnityInput.Current.GetKeyDown(KeyCode.P)) + ModDatabankHandler.RegisterMod(new ModDatabankHandler.ModData() { - logger.LogInfo("Should play audio."); - GameObject cameraObject = Camera.main.gameObject; - AudioSource audioSource = cameraObject.GetComponent<AudioSource>(); - audioSource.clip = Main.assets.LoadAsset<AudioClip>("AudioClip.PWAPresentation"); - audioSource.Play(); - logger.LogInfo("Should have played an audio."); - } - } - - private static void RegisterPDALogs() - { - // Load audio clips - logger.LogInfo($"{modName} {modVers} Loading audio clips..."); -#if BZ - AudioClip AWPresentationAudioClip = assets.LoadAsset<AudioClip>("pwa_presentation_message"); - AudioClip AWFirstLethalAudioClip = assets.LoadAsset<AudioClip>("first_lethal_message"); -#endif - logger.LogInfo($"{modName} {modVers} Audio clips loaded!"); - - logger.LogInfo($"{modName} {modVers} Registering PDA Logs..."); - - // Presentation PDA log "Hello xenoworker 91802..." -#if BZ - CustomSoundHandler.RegisterCustomSound(AWPresentationGoal.key, AWPresentationAudioClip, AudioUtils.BusPaths.PDAVoice); - FMODAsset presentation = ScriptableObject.CreateInstance<FMODAsset>(); - presentation.path = AWPresentationGoal.key; - presentation.id = AWPresentationGoal.key; - PDALogHandler.AddCustomEntry( - AWPresentationGoal.key, - "Subtitles_AWPresentation", - sound: presentation - ); -#endif + guid = modGUID, + version = modVers, + image = AssetsCache.GetAsset<Texture2D>("ModLogo"), + name = "Alterra Weaponry", + desc = "Since the return of the Aurora survivor, Alterra secretely added a few weapons blueprints.\nThis information is kept confidential, by using the PWA (Personal Weaponry Assistance) you agree the Alterra's NDA (Non-Divulgation Accord)." + }); -// First lethal weapon PDA log "A lethal weapon have been detected into your inventory..." -#if BZ - CustomSoundHandler.RegisterCustomSound("Log_PDA_Goal_FirstLethal", AWFirstLethalAudioClip, AudioUtils.BusPaths.PDAVoice); - FMODAsset firstLethal = ScriptableObject.CreateInstance<FMODAsset>(); - firstLethal.path = "Log_PDA_Goal_FirstLethal"; - firstLethal.id = "Log_PDA_Goal_FirstLethal"; - PDALogHandler.AddCustomEntry( - "Log_PDA_Goal_FirstLethal", - "Subtitles_AWFirstLethal", - sound: firstLethal - ); -#endif - } + Coal coal = new(); + coal.Patch(); - private static void RegisterPDAEncyEntries() - { - // Register AWModInfo entry - PDAEncyclopediaHandler.AddCustomEntry(new() - { - key = "AWModInfo", - kind = PDAEncyclopedia.EntryData.Kind.Encyclopedia, - nodes = new[] { "Meta" }, - path = "Meta", - unlocked = true, - }); + BlackPowder blackPowder = new(); + blackPowder.Patch(); - // Explosive torpedoes entry -#if BZ - PDAEncyclopediaHandler.AddCustomEntry(new() - { - key = "ExplosiveTorpedo", - kind = PDAEncyclopedia.EntryData.Kind.Encyclopedia, - nodes = new[] { "Tech", "Weaponry" }, - path = "Tech/Weaponry", - unlocked = false, - }); -#endif + ExplosiveTorpedo explosiveTorpedo = new(); + explosiveTorpedo.Patch(); - // Prawn laser arm entry -#if BZ - PDAEncyclopediaHandler.AddCustomEntry(new() - { - key = "PrawnLaserArm", - kind = PDAEncyclopedia.EntryData.Kind.Encyclopedia, - nodes = new[] { "Tech", "Weaponry" }, - path = "Tech/Weaponry", - unlocked = false, - }); -#endif + PrawnSelfDefenseModule prawnSelfDefenseModule = new(); + prawnSelfDefenseModule.Patch(); - // Prawn Self Defense Module -#if BZ - PDAEncyclopediaHandler.AddCustomEntry(new() - { - key = "PrawnDefensePerimeter", - kind = PDAEncyclopedia.EntryData.Kind.Encyclopedia, - nodes = new[] { "Tech", "Modules" }, - path = "Tech/Modules", - unlocked = false, - }); -#endif + logger.LogInfo($"{modName} {modVers} items registered."); } + } diff --git a/AlterraWeaponry/Properties/AssemblyInfo.cs b/AlterraWeaponry/Properties/AssemblyInfo.cs index df41b7f..ad51016 100644 --- a/AlterraWeaponry/Properties/AssemblyInfo.cs +++ b/AlterraWeaponry/Properties/AssemblyInfo.cs @@ -1,7 +1,6 @@ using System.Resources; -using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using VELD.AlterraWeaponry; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -33,6 +32,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.3.0")] -[assembly: AssemblyFileVersion("1.0.3.0")] +[assembly: AssemblyVersion(Main.modVers)] +[assembly: AssemblyFileVersion(Main.modLongVers)] [assembly: NeutralResourcesLanguage("en")] diff --git a/AlterraWeaponry/Sounds/AudioClip.FirstLethalMessage.wav b/AlterraWeaponry/Sounds/AudioClip.FirstLethalMessage.wav new file mode 100644 index 0000000..d5bd667 Binary files /dev/null and b/AlterraWeaponry/Sounds/AudioClip.FirstLethalMessage.wav differ diff --git a/AlterraWeaponry/Sounds/AudioClip.PWAPresentation.wav b/AlterraWeaponry/Sounds/AudioClip.PWAPresentation.wav new file mode 100644 index 0000000..419fe2b Binary files /dev/null and b/AlterraWeaponry/Sounds/AudioClip.PWAPresentation.wav differ diff --git a/AlterraWeaponry/Sounds/AudioClip.UnderwaterExplosionFX.ogg b/AlterraWeaponry/Sounds/AudioClip.UnderwaterExplosionFX.ogg new file mode 100644 index 0000000..eed8eed Binary files /dev/null and b/AlterraWeaponry/Sounds/AudioClip.UnderwaterExplosionFX.ogg differ diff --git a/AlterraWeaponry/Utils/ResourcesCacheManager.cs b/AlterraWeaponry/Utils/ResourcesCacheManager.cs new file mode 100644 index 0000000..8847658 --- /dev/null +++ b/AlterraWeaponry/Utils/ResourcesCacheManager.cs @@ -0,0 +1,213 @@ +namespace VELD.AlterraWeaponry.Utils; + +public class ResourcesCacheManager +{ + private static readonly List<string> ResourcesNames = new() + { + "AudioClip.FirstLethalMessage", + "AudioClip.PWAPresentation", + "GameObject.BlackPowder", + "GameObject.CustomEventTrigger", + "Material.BlackPowder", + "Mesh.BlackPowder", + "Sprite.BlackPowder", + "Sprite.Coal", + "Sprite.ExplosiveTorpedo", + "Sprite.PrawnSelfDefenseModule", + "Sprite.PrawnShieldModule", + "Sprite.UpgradePopup", + "Texture2D.BlackPowder", + "Texture2D.BlackPowder_normal", + "Texture2D.BlackPowder_spec", + "Texture2D.Coal", + "Texture2D.Coal_illum", + "Texture2D.Coal_normals", + "Texture2D.Coal_spec", + "Texture2D.ModLogo" + }; + + private static readonly Dictionary<string, string[]> ResourcesPaths = new() + { + { "AudioClip", new[] { "AudioClips" } }, + { "GameObject", new[] { "GameObjects" } }, + { "Material", new[] { "Materials" } }, + { "Mesh", new[] { "Meshes" } }, + { "Sprite", new[] { "Sprites" } }, + { "Texture2D", new[] { "Textures2D" } } + }; + + public static UnityEngine.Object[] RawResources; + + public Dictionary<string, AudioClip> CachedAudioClips { get; private set; } = new(); + public Dictionary<string, GameObject> CachedPrefabs { get; private set; } = new(); + public Dictionary<string, Material> CachedMaterials { get; private set; } = new(); + public Dictionary<string, Mesh> CachedMeshes { get; private set; } = new(); + public Dictionary<string, Sprite> CachedSprites { get; private set; } = new(); + public Dictionary<string, Texture2D> CachedTextures { get; private set; } = new(); + public ResourcesCacheManager() { } + + public static ResourcesCacheManager LoadResources(string path) + { + Main.logger.LogInfo("Loading assetbundle..."); + var bundle = AssetBundle.LoadFromFile(path) ?? throw new IOException($"Provided path '{path}' does not contain any assetbundle."); + RawResources = bundle.LoadAllAssets(); + var rm = new ResourcesCacheManager(); + + Main.logger.LogInfo("Loaded bundle, encaching..."); + + foreach (string resName in ResourcesNames) + { + Main.logger.LogInfo($"Trying to encache asset {resName}..."); + var assetName = resName.Split('.').Last(); + var assetType = resName.Split('.').First(); + try + { + UnityEngine.Object asset; + switch(true) + { + case true when assetType == "AudioClip": + asset = bundle.LoadAsset<AudioClip>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle."); + rm.CachedAudioClips.Add(assetName, asset as AudioClip); + Main.logger.LogInfo($"Added {resName} to rm.CachedAudioClips."); + break; + case true when assetType == "GameObject" || assetType == "Prefab": + asset = bundle.LoadAsset<GameObject>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle."); + rm.CachedPrefabs.Add(assetName, asset as GameObject); + Main.logger.LogInfo($"Added {resName} to rm.CachedPrefabs."); + break; + case true when assetType == "Material": + asset = bundle.LoadAsset<Material>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle."); + rm.CachedMaterials.Add(assetName, asset as Material); + Main.logger.LogInfo($"Added {resName} to rm.CachedMaterials."); + break; + case true when assetType == "Mesh": + asset = bundle.LoadAsset<Mesh>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle."); + rm.CachedMeshes.Add(assetName, asset as Mesh); + Main.logger.LogInfo($"Added {resName} to rm.CachedMeshes."); + break; + case true when assetType == "Sprite": + asset = bundle.LoadAsset<Sprite>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle."); + rm.CachedSprites.Add(assetName, asset as Sprite); + Main.logger.LogInfo($"Added {resName} to rm.CachedSprites."); + break; + case true when assetType == "Texture2D": + asset = bundle.LoadAsset<Texture2D>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle."); + rm.CachedTextures.Add(assetName, asset as Texture2D); + Main.logger.LogInfo($"Added {resName} to rm.CachedTextures."); + break; + default: + throw new Exception("The type of the asset is incorrect."); + } + Main.logger.LogInfo($"Encached {resName} to key {assetName} and in {assetType}'s cache."); + } + catch(Exception ex) + { + Main.logger.LogFatal($"A fatal error has ocurred when loading the resources.\n{ex}"); + } + } + var str = new StringBuilder(); + str.AppendLine("RESOURCES CACHE MANAGER: CACHED CONTENTS:"); + str.AppendLine(" "); + str.AppendLine("rm.CachedAudioClips = ["); + foreach(var asset in rm.CachedAudioClips) + str.AppendLine($"\t{asset}"); + str.AppendLine("]"); + str.AppendLine(" "); + str.AppendLine("rm.CachedPrefabs = ["); + foreach(var asset in rm.CachedPrefabs) + str.AppendLine($"\t{asset}"); + str.AppendLine("]"); + str.AppendLine(" "); + str.AppendLine("rm.CachedMaterials = ["); + foreach (var asset in rm.CachedMaterials) + str.AppendLine($"\t{asset}"); + str.AppendLine("]"); + str.AppendLine(" "); + str.AppendLine("rm.CachedMeshes = ["); + foreach (var asset in rm.CachedMeshes) + str.AppendLine($"\t{asset}"); + str.AppendLine("]"); + str.AppendLine(" "); + str.AppendLine("rm.CachedSprites = ["); + foreach (var asset in rm.CachedSprites) + str.AppendLine($"\t{asset}"); + str.AppendLine("]"); + str.AppendLine(" "); + str.AppendLine("rm.CachedTextures = ["); + foreach (var asset in rm.CachedTextures) + str.AppendLine($"\t{asset}"); + str.AppendLine("]"); + str.AppendLine(" "); + Main.logger.LogDebug(str.ToString()); + Main.logger.LogInfo("Encached all assets."); + return rm; + } + + /// <summary> + /// Gets a resource in the AssetsCache cache. + /// <para>You better use <see cref="TryGetAsset{T}(string, out T)"/>.</para> + /// </summary> + /// <typeparam name="T">Type of the item to find.</typeparam> + /// <param name="name">Name of the asset to find.</param> + /// <returns>A reference to the instance of the asset, or an error if nothing have been found.</returns> + /// <exception cref="ArgumentException">If the provided type is not a valid UnityEngine.Object or is not supported.</exception> + public T GetAsset<T>(string name) where T : UnityEngine.Object + { + Main.logger.LogDebug($"Getting the asset {typeof(T).Name}.{name}..."); + UnityEngine.Object result = true switch + { + true when typeof(T) == typeof(AudioClip) => CachedAudioClips[name], + true when typeof(T) == typeof(GameObject) => CachedPrefabs[name], + true when typeof(T) == typeof(Material) => CachedMaterials[name], + true when typeof(T) == typeof(Mesh) => CachedMeshes[name], + true when typeof(T) == typeof(Sprite) => CachedSprites[name], + true when typeof(T) == typeof(Texture2D) => CachedTextures[name], + _ => throw new ArgumentException("The type of T is not recognized as an UnityEngine.Object class or subclass, or it is not supported."), + }; + Main.logger.LogDebug($"Asset found: {((T)result).GetType().Name} '{name}'"); + + return result as T; + } + + /// <summary> + /// Try to get an asset from the resourcescache. + /// </summary> + /// <typeparam name="T">Type of the resource to find.</typeparam> + /// <param name="name">Name of the resource to find.</param> + /// <param name="result">Asset found. Null if not found.</param> + /// <returns>True if the item have been found, otherwise false.</returns> + /// <exception cref="ArgumentException">If the provided type is not a valid UnityEngine.Object or not supported.</exception> + public bool TryGetAsset<T>(string name, out T result) where T : UnityEngine.Object + { + bool res; + switch(true) + { + case true when typeof(T) == typeof(AudioClip): + res = CachedAudioClips.TryGetValue(name, out var audio); + result = audio as T; + return res; + case true when typeof(T) == typeof(GameObject): + res = CachedPrefabs.TryGetValue(name, out var gameObject); + result = gameObject as T; + return res; + case true when typeof(T) == typeof(Material): + res = CachedMaterials.TryGetValue(name, out var material); + result = material as T; + return res; + case true when typeof(T) == typeof(Mesh): + res = CachedMeshes.TryGetValue(name, out var mesh); + result = mesh as T; + return res; + case true when typeof(T) == typeof(Sprite): + res = CachedSprites.TryGetValue(name, out var sprite); + result = sprite as T; + return res; + case true when typeof(T) == typeof(Texture2D): + res = CachedTextures.TryGetValue(name, out var texture); + result = texture as T; + return res; + default: + throw new ArgumentException("Type of T is not a valid UnityEngine.Object, or is not supported."); + } + } +} diff --git a/AlterraWeaponry/alterraweaponry.assets b/AlterraWeaponry/alterraweaponry.assets index 31c067a..cef3bd2 100644 Binary files a/AlterraWeaponry/alterraweaponry.assets and b/AlterraWeaponry/alterraweaponry.assets differ diff --git a/AlterraWeaponry/assets/Coal.png b/AlterraWeaponry/assets/Coal.png deleted file mode 100644 index 8436d67..0000000 Binary files a/AlterraWeaponry/assets/Coal.png and /dev/null differ diff --git a/AlterraWeaponry/assets/ExplosiveTorpedo.png b/AlterraWeaponry/assets/ExplosiveTorpedo.png deleted file mode 100644 index e2ab1f1..0000000 Binary files a/AlterraWeaponry/assets/ExplosiveTorpedo.png and /dev/null differ diff --git a/AlterraWeaponry/assets/PrawnPerimeterDefense.png b/AlterraWeaponry/assets/PrawnPerimeterDefense.png deleted file mode 100644 index 2b4f6d7..0000000 Binary files a/AlterraWeaponry/assets/PrawnPerimeterDefense.png and /dev/null differ diff --git a/AlterraWeaponry/assets/Texture2D/crashfish_powder_01.png b/AlterraWeaponry/assets/Texture2D/crashfish_powder_01.png deleted file mode 100644 index 602a1c1..0000000 Binary files a/AlterraWeaponry/assets/Texture2D/crashfish_powder_01.png and /dev/null differ diff --git a/AlterraWeaponry/assets/Texture2D/crashfish_powder_normal.png b/AlterraWeaponry/assets/Texture2D/crashfish_powder_normal.png deleted file mode 100644 index 3c19475..0000000 Binary files a/AlterraWeaponry/assets/Texture2D/crashfish_powder_normal.png and /dev/null differ diff --git a/AlterraWeaponry/assets/Texture2D/crashfish_powder_spec.png b/AlterraWeaponry/assets/Texture2D/crashfish_powder_spec.png deleted file mode 100644 index 315fa65..0000000 Binary files a/AlterraWeaponry/assets/Texture2D/crashfish_powder_spec.png and /dev/null differ diff --git a/AlterraWeaponry/assets/crashpowder.png b/AlterraWeaponry/assets/crashpowder.png deleted file mode 100644 index eabfb92..0000000 Binary files a/AlterraWeaponry/assets/crashpowder.png and /dev/null differ diff --git a/AlterraWeaponry/assets/first_lethal_message.ogg b/AlterraWeaponry/assets/first_lethal_message.ogg deleted file mode 100644 index 1542af3..0000000 Binary files a/AlterraWeaponry/assets/first_lethal_message.ogg and /dev/null differ diff --git a/AlterraWeaponry/assets/prawn_shield.png b/AlterraWeaponry/assets/prawn_shield.png deleted file mode 100644 index 8aac9fc..0000000 Binary files a/AlterraWeaponry/assets/prawn_shield.png and /dev/null differ diff --git a/AlterraWeaponry/assets/pwa_presentation.ogg b/AlterraWeaponry/assets/pwa_presentation.ogg deleted file mode 100644 index b11c962..0000000 Binary files a/AlterraWeaponry/assets/pwa_presentation.ogg and /dev/null differ diff --git a/AlterraWeaponry/behaviours/CustomTriggerEventAssigner.cs b/AlterraWeaponry/behaviours/CustomTriggerEventAssigner.cs index 355ee5d..addfa1d 100644 --- a/AlterraWeaponry/behaviours/CustomTriggerEventAssigner.cs +++ b/AlterraWeaponry/behaviours/CustomTriggerEventAssigner.cs @@ -1,4 +1,4 @@ -namespace VELD.AlterraWeaponry.behaviours; +namespace VELD.AlterraWeaponry.Behaviours; public class CustomTriggerStoryGoalAssigner : MonoBehaviour { diff --git a/AlterraWeaponry/behaviours/TorpedoExplosionBehaviour.cs b/AlterraWeaponry/behaviours/TorpedoExplosionBehaviour.cs index dc96411..b3883d6 100644 --- a/AlterraWeaponry/behaviours/TorpedoExplosionBehaviour.cs +++ b/AlterraWeaponry/behaviours/TorpedoExplosionBehaviour.cs @@ -1,17 +1,62 @@ -namespace VELD.AlterraWeaponry.behaviours; +namespace VELD.AlterraWeaponry.Behaviours; public class TorpedoExplosionBehaviour : MonoBehaviour { + public void Awake() + { + } + public void Start() { - DamageSystem.RadiusDamage(250f, base.gameObject.transform.position, 5f, DamageType.Explosive, base.gameObject); -#if BZ - Utils.PlayOneShotPS(GameObject.Instantiate(new VFXMeteor().gameObject).GetComponent<VFXMeteor>().impactPrefab, base.gameObject.transform.position, base.gameObject.transform.rotation, null); -#else - Utils.PlayOneShotPS(GameObject.Instantiate(new LavaLizard().gameObject).GetComponent<LavaLiazardRangedAttack>().attackStartFXcontrol.emitters[0].fx, base.gameObject.transform.position, base.gameObject.transform.rotation, null); + Main.logger.LogInfo("Releasing explosion !"); + DamageSystem.RadiusDamage((250f * Main.Options.dmgMultiplier), gameObject.transform.position, 10f, DamageType.Explosive, gameObject); +#if BELOWZERO + try + { + var vfxMeteor = detonationPrefab.GetComponent<VFXMeteor>(); + if (vfxMeteor.impactPrefab == null) + throw new Exception("vfxMeteor.impactPerfab is null."); + global::Utils.PlayOneShotPS(vfxMeteor.impactPrefab, gameObject.transform.position, gameObject.transform.rotation); + if (vfxMeteor.meteorCrashOSSound == null) + throw new Exception("vfxMeteor.meteorCrashOSSound is null."); + VFXWeatherManager.PlayOneShotSound(vfxMeteor.meteorCrashOSSound, gameObject.transform.position, 8f, Array.Empty<VFXWeatherManager.FmodParameter>()); + } + catch(Exception e) + { + Main.logger.LogError($"An error has occured while exploding the torpedo.\n{e}"); + } +#elif SUBNAUTICA + global::Utils.PlayOneShotPS(GameObject.Instantiate<LavaLizard>(new LavaLizard()).GetComponent<LavaLiazardRangedAttack>().attackStartFXcontrol.emitters[0].fx, base.gameObject.transform.position, base.gameObject.transform.rotation, null); #endif - UnityEngine.Object.Destroy(base.gameObject); + Destroy(gameObject); + Main.logger.LogInfo("Exploded !!!"); } - public static GameObject detonationEffectPrefab; + public static GameObject detonationPrefab; + + public static IEnumerator SetupDetonationPrefabAsync() + { + Main.logger.LogInfo($"{typeof(TorpedoExplosionBehaviour).FullName}: Setting up detonation prefab for explosive torpedo..."); + if (detonationPrefab != null) + { + Main.logger.LogInfo($"{typeof(TorpedoExplosionBehaviour).FullName}: vfxMeteor is already defined."); + yield break; + } + + GameObject prefab; + +#if BELOWZERO + prefab = VFXWeatherManager.main.meteorController.closeUpPrefab; + + if(prefab.GetComponent<VFXMeteor>() == null) + { + Main.logger.LogError($"{typeof(TorpedoExplosionBehaviour).FullName}: No VFXMeteor found in the closeupPrefab."); + yield break; + } +#endif + + yield return prefab; + detonationPrefab = prefab; + Main.logger.LogInfo($"{typeof(TorpedoExplosionBehaviour).FullName}: Detonation prefab set up."); + } } diff --git a/AlterraWeaponry/behaviours/ZapFunctionalityBehaviour.cs b/AlterraWeaponry/behaviours/ZapFunctionalityBehaviour.cs index 5d44a0a..a6f960b 100644 --- a/AlterraWeaponry/behaviours/ZapFunctionalityBehaviour.cs +++ b/AlterraWeaponry/behaviours/ZapFunctionalityBehaviour.cs @@ -1,4 +1,4 @@ -namespace VELD.AlterraWeaponry.behaviours; +namespace VELD.AlterraWeaponry.Behaviours; internal class ZapFunctionalityBehaviour : MonoBehaviour // Thanks to ECM and PrimeSonic 👌 { @@ -9,10 +9,16 @@ internal class ZapFunctionalityBehaviour : MonoBehaviour // Thanks to ECM and Pr public float Overcharge { get; private set; } public float OverchargeScalar { get; private set; } - public static IEnumerator UpdateDefensePrefab() + private void Awake() { - if (seamothElectricalDefensePrefab) yield break; + if(seamothElectricalDefensePrefab == null) + CoroutineHost.StartCoroutine(UpdateDefensePrefab()); + } + public static IEnumerator UpdateDefensePrefab() + { + if (seamothElectricalDefensePrefab is not null) yield break; + Main.logger.LogDebug("Updating defense prefab for ZapFunctionalityBehaviour.ElectricalDefensePrefab."); var task = CraftData.GetPrefabForTechTypeAsync(TechType.SeaTruck); yield return task; var prefab = task.GetResult(); @@ -20,18 +26,20 @@ public static IEnumerator UpdateDefensePrefab() if (prefab == null) yield break; seamothElectricalDefensePrefab = prefab.GetComponent<SeaTruckUpgrades>().electricalDefensePrefab; + Main.logger.LogDebug("Done !"); } - public bool Zap(Vehicle vehicle, int usedSlotID) + public bool Zap(Vehicle vehicle, int usedSlotID, float charge, float chargeScalar) { + Main.logger.LogInfo("Preparing the zap..."); if (vehicle == null) return false; - float charge = vehicle.quickSlotCharge[usedSlotID]; - float slotCharge = vehicle.GetSlotCharge(usedSlotID); + Main.logger.LogInfo("Should zap."); this.Overcharge = charge; - this.OverchargeScalar = slotCharge; - CoroutineHost.StartCoroutine(UpdateDefensePrefab()); + this.OverchargeScalar = chargeScalar; + Main.logger.LogInfo("Settings set, it should be zapping."); + Main.logger.LogInfo("Executing Zap in radius.."); ZapRadius(vehicle); return true; } @@ -39,9 +47,11 @@ public bool Zap(Vehicle vehicle, int usedSlotID) private void ZapRadius(Vehicle vehicle) { - GameObject gameObject = Utils.SpawnZeroedAt(ElectricalDefensePrefab, vehicle.transform, false); + GameObject gameObject = global::Utils.SpawnZeroedAt(ElectricalDefensePrefab, vehicle.transform, false); ElectricalDefense defenseComponent = gameObject.GetComponent<ElectricalDefense>(); defenseComponent.charge = this.Overcharge; defenseComponent.chargeScalar = this.OverchargeScalar; + defenseComponent.damage *= Main.Options.dmgMultiplier; + Main.logger.LogInfo("Should have zapped !"); } } diff --git a/AlterraWeaponry/items/BlackPowder.cs b/AlterraWeaponry/items/BlackPowder.cs index c3adab4..ac62a82 100644 --- a/AlterraWeaponry/items/BlackPowder.cs +++ b/AlterraWeaponry/items/BlackPowder.cs @@ -1,66 +1,86 @@ -namespace VELD.AlterraWeaponry.items; +namespace VELD.AlterraWeaponry.Items; -internal class BlackPowder : Craftable +internal class BlackPowder { - public static GameObject AssetPrefab = Main.assets.LoadAsset<GameObject>("GameObject.BlackPowder"); - public static GameObject prefab; - public static TechType techType { get; private set; } = 0; + public static string ClassID = "BlackPowder"; + public static TechType TechType { get; private set; } = 0; - public BlackPowder() : base("BlackPowder", "BlackPowder", "Tooltip_BlackPowder") + + public static GameObject AssetPrefab = Main.AssetsCache.GetAsset<GameObject>("BlackPowder"); + public PrefabInfo Info { get; private set; } + + public BlackPowder() { - OnFinishedPatching += () => - { - techType = TechType; - }; + Main.logger.LogDebug("Loading BlackPowder prefab info"); + if (!Main.AssetsCache.TryGetAsset("BlackPowder", out Sprite icon)) + Main.logger.LogError("Unable to load BlackPowder sprite from cache."); + + this.Info = PrefabInfo + .WithTechType(classId: ClassID, displayName: null, description: null, unlockAtStart: true, techTypeOwner: Assembly.GetExecutingAssembly()) + .WithIcon(icon) + .WithSizeInInventory(new(1, 1)); + TechType = this.Info.TechType; + Main.logger.LogDebug("Loaded BlackPowder prefab info and assigned TechType"); } - public override TechCategory CategoryForPDA => TechCategory.AdvancedMaterials; - public override TechGroup GroupForPDA => TechGroup.Resources; - public override TechType RequiredForUnlock => Coal.techType; - public override float CraftingTime => 2.5f; - public override CraftTree.Type FabricatorType => CraftTree.Type.Fabricator; - public override Vector2int SizeInInventory => new(1, 1); - public override string[] StepsToFabricatorTab => new string[] { "Resources", "AdvancedMaterials"}; - protected override RecipeData GetBlueprintRecipe() + + public void Patch() { - return new() + Main.logger.LogDebug("Loading BlackPowder recipe"); + RecipeData recipe = new() { craftAmount = 1, Ingredients = new() { - new(Coal.techType, 1), + new(Coal.TechType, 1), new(TechType.Sulphur, 1), new(TechType.JeweledDiskPiece, 3) } }; + + Main.logger.LogDebug("Loaded BlackPowder recipe, loading custom prefab..."); + + CustomPrefab customPrefab = new(this.Info); + + customPrefab.SetGameObject(SetupGameObject()); + customPrefab.SetUnlock(Coal.TechType) + .WithCompoundTechsForUnlock(new() + { + TechType.CreepvinePiece, + TechType.Sulphur + }) + .WithPdaGroupCategoryBefore(TechGroup.Resources, TechCategory.AdvancedMaterials, TechType.HydrochloricAcid); + customPrefab.SetEquipment(EquipmentType.None); + customPrefab.SetRecipe(recipe) + .WithCraftingTime(2.5f) + .WithFabricatorType(CraftTree.Type.Fabricator) + .WithStepsToFabricatorTab("Resources", "BasicMaterials"); + + customPrefab.Register(); + + Main.logger.LogDebug("Loaded and registered BlackPowder prefab."); } - protected override Sprite GetItemSprite() - { - return Main.assets.LoadAsset<Sprite>("Sprite.BlackPowder"); - } - public override GameObject GetGameObject() + + /// <summary> + /// Setup the game object + /// </summary> + /// <returns>The modified asset prefab</returns> + public GameObject SetupGameObject() { - bool flag = !prefab; - if (flag) + Main.logger.LogDebug("Setting up BlackPowder GameObject."); + Main.logger.LogDebug("Setting shaders."); + var renderer = AssetPrefab.EnsureComponent<MeshRenderer>(); + foreach(var mat in renderer.materials) { - prefab = Main.assets.LoadAsset<GameObject>("GameObject.BlackPowder"); - Pickupable pickupable = prefab.AddComponent<Pickupable>(); - pickupable.overrideTechType = base.TechType; - PrefabIdentifier prefabIdentifier = prefab.AddComponent<PrefabIdentifier>(); - prefabIdentifier.ClassId = base.ClassID; - prefabIdentifier.name = base.ClassID; - prefab.AddComponent<WorldForces>(); - prefab.AddComponent<LargeWorldEntity>(); - TechTag techTag = prefab.AddComponent<TechTag>(); - techTag.type = base.TechType; + if (Main.AssetsCache.TryGetAsset("BlackPowder", out Texture2D albedo)) + mat.SetTexture(ShaderPropertyID._MainTex, albedo); + + if(Main.AssetsCache.TryGetAsset("BlackPowder_spec", out Texture2D speculars)) + mat.SetTexture(ShaderPropertyID._SpecTex, speculars); + + if(Main.AssetsCache.TryGetAsset("BlackPowder_normals", out Texture2D normals)) + mat.SetTexture(ShaderPropertyID._NormalsTex, normals); } - prefab.SetActive(true); - GameObject go = UnityEngine.Object.Instantiate<GameObject>(prefab); - return go; - } - public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject) - { - gameObject.Set(this.GetGameObject()); - yield return null; - yield break; + MaterialUtils.ApplySNShaders(AssetPrefab); + return AssetPrefab; } } diff --git a/AlterraWeaponry/items/Coal.cs b/AlterraWeaponry/items/Coal.cs index cefc37f..b1bd0f2 100644 --- a/AlterraWeaponry/items/Coal.cs +++ b/AlterraWeaponry/items/Coal.cs @@ -1,28 +1,32 @@ -namespace VELD.AlterraWeaponry.items; +namespace VELD.AlterraWeaponry.Items; -internal class Coal : Craftable +internal class Coal { - public static GameObject prefab; - public static TechType techType { get; private set; } = 0; + public static string ClassID = "Coal"; + public static TechType TechType { get; private set; } = 0; - public Coal() : base ("Coal", "Coal", "Tooltip_Coal") + + public PrefabInfo Info { get; private set; } + + public Coal() { - OnFinishedPatching += () => - { - techType = TechType; - }; + Main.logger.LogDebug("Loading Coal go info"); + if (!Main.AssetsCache.TryGetAsset("Coal", out Sprite icon)) + Main.logger.LogError("Unable to load Coal Sprite from cache."); + + this.Info = PrefabInfo + .WithTechType(classId: ClassID, displayName: null, description: null, unlockAtStart: true, techTypeOwner: Assembly.GetExecutingAssembly()) + .WithIcon(icon) + .WithSizeInInventory(new(1, 1)); + + TechType = this.Info.TechType; + Main.logger.LogDebug("Loaded Coal go and assigned techType"); } - public override CraftTree.Type FabricatorType => CraftTree.Type.Fabricator; - public override TechCategory CategoryForPDA => TechCategory.BasicMaterials; - public override TechGroup GroupForPDA => TechGroup.Resources; - public override Vector2int SizeInInventory => new(1, 1); - public override float CraftingTime => 3f; - public override bool UnlockedAtStart => true; - public override string[] StepsToFabricatorTab => new string[] { "Resources", "BasicMaterials" }; - protected override RecipeData GetBlueprintRecipe() + public void Patch() { - return new() + Main.logger.LogDebug("Setting Coal recipe"); + RecipeData recipe = new() { craftAmount = 4, Ingredients = new() @@ -30,24 +34,51 @@ protected override RecipeData GetBlueprintRecipe() new(TechType.CreepvinePiece, 1) } }; - } - protected override Sprite GetItemSprite() - { - return Main.assets.LoadAsset<Sprite>("Sprite.Coal"); - } - public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject) - { - if (prefab == null) + + Main.logger.LogDebug("Recipe set, now patching go."); + + CustomPrefab customPrefab = new(this.Info); + PrefabTemplate clone = new CloneTemplate(this.Info, TechType.Sulphur) { - CoroutineTask<GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.Titanium); - yield return task; + ModifyPrefab = (go) => + { + var renderer = go.GetComponentInChildren<MeshRenderer>(); + foreach(var mat in renderer.materials) + { + if (Main.AssetsCache.TryGetAsset("Coal", out Texture2D albedo)) + mat.SetTexture(ShaderPropertyID._MainTex, albedo); - prefab = GameObject.Instantiate(task.GetResult()); - } + if (Main.AssetsCache.TryGetAsset("Coal_spec", out Texture2D specular)) + mat.SetTexture(ShaderPropertyID._SpecTex, specular); - GameObject go = GameObject.Instantiate(prefab); - gameObject.Set(go); - } + if (Main.AssetsCache.TryGetAsset("Coal_illum", out Texture2D illumination)) + mat.SetTexture(ShaderPropertyID._Illum, illumination); + } + var vfxFabricating = go.EnsureComponent<VFXFabricating>(); + MaterialUtils.ApplySNShaders(go); + } + }; + customPrefab.SetGameObject(clone); + customPrefab.SetUnlock(TechType.CreepvinePiece) + .WithPdaGroupCategoryBefore(TechGroup.Resources, TechCategory.BasicMaterials); + customPrefab.SetEquipment(EquipmentType.None); + customPrefab.SetRecipe(recipe) + .WithCraftingTime(4f) + .WithFabricatorType(CraftTree.Type.Fabricator) + .WithStepsToFabricatorTab("Resources", "BasicMaterials"); + + customPrefab.SetOutcropDrop( + new(TechType.LimestoneChunk, 0.408f), + new(TechType.BreakableGold, 0.159f), + new(TechType.BreakableSilver, 0.118f) + ); + + customPrefab.Register(); + + BaseBioReactor.charge.Add(TechType, 560f); + + Main.logger.LogDebug("Prefab loaded and registered for Coal."); + } } diff --git a/AlterraWeaponry/items/ExplosiveTorpedo.cs b/AlterraWeaponry/items/ExplosiveTorpedo.cs index b1ee7b1..05dc4e0 100644 --- a/AlterraWeaponry/items/ExplosiveTorpedo.cs +++ b/AlterraWeaponry/items/ExplosiveTorpedo.cs @@ -1,53 +1,54 @@ -namespace VELD.AlterraWeaponry.items; +namespace VELD.AlterraWeaponry.Items; -internal class ExplosiveTorpedo : Craftable +internal class ExplosiveTorpedo { + public static string ClassID = "ExplosiveTorpedo"; + public static TechType TechType { get; private set; } = 0; + + public static GameObject prefab; - public static TechType techType { get; private set; } = 0; + public PrefabInfo Info { get; private set; } - public ExplosiveTorpedo() : base("ExplosiveTorpedo", "ExplosiveTorpedo", "Tooltip_ExplosiveTorpedo") + public ExplosiveTorpedo() { - OnFinishedPatching += () => - { - techType = TechType; - }; + if (!Main.AssetsCache.TryGetAsset("ExplosiveTorpedo", out Sprite icon)) + Main.logger.LogError("Unable to load ExplosiveTorpedo Sprite from cache."); + + Info = PrefabInfo + .WithTechType(classId: ClassID, displayName: null, description: null, techTypeOwner: Assembly.GetExecutingAssembly()) + .WithSizeInInventory(new(1, 1)) + .WithIcon(icon); + + TechType = Info.TechType; } - public override TechCategory CategoryForPDA => TechCategory.VehicleUpgrades; - public override TechType RequiredForUnlock => TechType.ExosuitTorpedoArmModule; - public override float CraftingTime => 3f; - public override CraftTree.Type FabricatorType => CraftTree.Type.Fabricator; - public override TechGroup GroupForPDA => TechGroup.VehicleUpgrades; - public override Vector2int SizeInInventory => new(1, 1); - public override string[] StepsToFabricatorTab => new string[] { "Upgrades", "ExosuitUpgrades" }; - public override string DiscoverMessage => "Discover_LethalWeapon"; - protected override RecipeData GetBlueprintRecipe() + public void Patch() { - return new() + RecipeData recipe = new() { craftAmount = 2, Ingredients = new() { - new(BlackPowder.techType, 2), - new(TechType.Titanium, 1), + new(BlackPowder.TechType, 2), + new(TechType.Titanium, 1) } }; - } - protected override Sprite GetItemSprite() - { - return Main.assets.LoadAsset<Sprite>("Sprite.ExplosiveTorpedo"); - } - public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject) - { - if (prefab == null) - { - CoroutineTask<GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.WhirlpoolTorpedo); - yield return task; - prefab = GameObject.Instantiate(task.GetResult()); - } + CustomPrefab customPrefab = new(Info); + CloneTemplate clone = new(Info, TechType.GasTorpedo); + + customPrefab.SetGameObject(clone); + if (!Main.AssetsCache.TryGetAsset("UpgradePopup", out Sprite popupSprite)) + Main.logger.LogError("Unable to load UpgradePopup sprite from cache."); + customPrefab.SetUnlock(BlackPowder.TechType) + .WithEncyclopediaEntry("Tech/Weaponry", popupSprite) + .WithPdaGroupCategoryAfter(TechGroup.VehicleUpgrades, TechCategory.VehicleUpgrades, TechType.GasTorpedo); + customPrefab.SetEquipment(EquipmentType.None); + customPrefab.SetRecipe(recipe) + .WithCraftingTime(3f) + .WithFabricatorType(CraftTree.Type.Fabricator) + .WithStepsToFabricatorTab("Upgrades", "ExosuitUpgrades"); - GameObject go = GameObject.Instantiate(prefab); - gameObject.Set(go); + customPrefab.Register(); } } diff --git a/AlterraWeaponry/items/PrawnSelfDefenseModule.cs b/AlterraWeaponry/items/PrawnSelfDefenseModule.cs index 94afc35..151f76a 100644 --- a/AlterraWeaponry/items/PrawnSelfDefenseModule.cs +++ b/AlterraWeaponry/items/PrawnSelfDefenseModule.cs @@ -1,34 +1,35 @@ -namespace VELD.AlterraWeaponry.items; +namespace VELD.AlterraWeaponry.Items; -public class PrawnSelfDefenseModule : Equipable +public class PrawnSelfDefenseModule { + public const float maxCharge = 10f; + public const float energyCost = 5f; + public const float cooldown = 5f; + + public static string ClassID = "PrawnSelfDefenseModule"; + public static TechType TechType { get; private set; } = 0; + + public static GameObject prefab; - public static float maxCharge = 10f; - public static float energyCost = 5f; - public static float cooldown = 5f; - public static TechType techType { get; private set; } = 0; + public PrefabInfo Info { get; private set; } - public PrawnSelfDefenseModule() : base("PrawnSelfDefenseModule", "PrawnSelfDefenseModule", "Tooltip_PrawnSelfDefenseModule") + public PrawnSelfDefenseModule() { - OnFinishedPatching += () => - { - techType = TechType; - }; + if (!Main.AssetsCache.TryGetAsset("PrawnSelfDefenseModule", out Sprite icon)) + Main.logger.LogError("Unable to load PrawnSelfDefenseModule sprite from cache."); + + Info = PrefabInfo + .WithTechType(classId: ClassID, displayName: null, description: null, techTypeOwner: Assembly.GetExecutingAssembly()) + .WithSizeInInventory(new(1, 1)) + .WithIcon(icon); + + TechType = this.Info.TechType; + } - public override TechCategory CategoryForPDA => TechCategory.VehicleUpgrades; - public override float CraftingTime => 3f; - public override EquipmentType EquipmentType => EquipmentType.ExosuitModule; - public override CraftTree.Type FabricatorType => CraftTree.Type.Fabricator; - public override int FragmentsToScan => 1; - public override TechGroup GroupForPDA => TechGroup.VehicleUpgrades; - public override QuickSlotType QuickSlotType => QuickSlotType.Chargeable; - public override TechType RequiredForUnlock => TechType.SeaTruckUpgradePerimeterDefense; - public override Vector2int SizeInInventory => new(1, 1); - public override string[] StepsToFabricatorTab => new string[] { "Upgrades", "ExosuitUpgrades" }; - protected override RecipeData GetBlueprintRecipe() + public void Patch() { - return new() + RecipeData recipe = new() { craftAmount = 1, Ingredients = new() @@ -39,22 +40,57 @@ protected override RecipeData GetBlueprintRecipe() new(TechType.Polyaniline, 1) } }; - } - protected override Sprite GetItemSprite() - { - return Main.assets.LoadAsset<Sprite>("Sprite.PrawnSelfDefenseModule"); - } - public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject) - { - if (prefab == null) - { - CoroutineTask<GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.SeaTruckUpgradePerimeterDefense); - yield return task; - prefab = GameObject.Instantiate(task.GetResult()); - } + CustomPrefab customPrefab = new(this.Info); + CloneTemplate clone = new(this.Info, TechType.SeaTruckUpgradePerimeterDefense); + + customPrefab.SetGameObject(clone); + + if (!Main.AssetsCache.TryGetAsset("UpgradePopup", out Sprite popupSprite)) + Main.logger.LogError("Unable to load UpgradePopup sprite from cache."); + + customPrefab.SetUnlock(TechType.Polyaniline) + .WithEncyclopediaEntry("Tech/Weaponry", popupSprite) + .WithPdaGroupCategoryAfter(TechGroup.VehicleUpgrades, TechCategory.VehicleUpgrades, TechType.ExosuitThermalReactorModule); + customPrefab.SetVehicleUpgradeModule(EquipmentType.ExosuitModule, QuickSlotType.Chargeable) + .WithEnergyCost(energyCost) + .WithMaxCharge(maxCharge) + .WithCooldown(5f) + .WithOnModuleAdded((Vehicle instance, int slotID) => + { + if (!instance.gameObject.TryGetComponent(out ZapFunctionalityBehaviour defMono)) + instance.gameObject.EnsureComponent<ZapFunctionalityBehaviour>(); + else + Main.logger.LogWarning("For some reason, the defense mono was already existing on the prawn although the upgrade was not equipped."); + }) + .WithOnModuleRemoved((Vehicle instance, int slotID) => + { + if (instance.gameObject.TryGetComponent(out ZapFunctionalityBehaviour defMono)) + UnityEngine.Object.Destroy(defMono); + else + Main.logger.LogWarning("For some reason, the defense mono was no existing on Prawn although the upgrade was equipped."); + }) + .WithOnModuleUsed((Vehicle instance, int slotID, float charge, float chargeScalar) => + { + if (!instance.gameObject.TryGetComponent(out ZapFunctionalityBehaviour defenseMono)) + defenseMono = instance.gameObject.EnsureComponent<ZapFunctionalityBehaviour>(); + Main.logger.LogInfo("Zapping !"); + try + { + defenseMono.Zap(instance, slotID, charge, chargeScalar); + } + catch (Exception e) + { + Main.logger.LogError($"Cannot use the defense mono.\nError:"); + Main.logger.LogError(e); + } + Main.logger.LogInfo("Zapped !"); + }); + customPrefab.SetRecipe(recipe) + .WithCraftingTime(2.5f) + .WithFabricatorType(CraftTree.Type.Fabricator) + .WithStepsToFabricatorTab("Upgrades", "ExosuitUpgrades"); - GameObject go = GameObject.Instantiate(prefab); - gameObject.Set(go); + customPrefab.Register(); } } diff --git a/AlterraWeaponry/patches/ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs b/AlterraWeaponry/patches/ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs index c712a05..13d14bb 100644 --- a/AlterraWeaponry/patches/ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs +++ b/AlterraWeaponry/patches/ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs @@ -1,15 +1,24 @@ -namespace VELD.AlterraWeaponry.patches; +namespace VELD.AlterraWeaponry.Patches; [HarmonyPatch(typeof(ExosuitTorpedoArm))] public class ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch // Thanks to Grimm The Second ! { [HarmonyPrefix] - [HarmonyPatch(nameof(ExosuitTorpedoArm.OnOpenTorpedoStorage))] - public static void OpenTorpedoStorageExternal(ExosuitTorpedoArm __instance) + [HarmonyPatch(typeof(ExosuitTorpedoArm), nameof(ExosuitTorpedoArm.OpenTorpedoStorageExternal))] + private static void OpenTorpedoStorageExternal(ExosuitTorpedoArm __instance) { - __instance.container.allowedTech.AddRange(new TechType[] + try { - ExplosiveTorpedo.techType - }); + Main.logger.LogDebug("Trying to open PRAWN torpedo arm. Adding TechType: " + ExplosiveTorpedo.TechType); + __instance.container.allowedTech.AddRange(new[] + { + ExplosiveTorpedo.TechType + }); + Main.logger.LogDebug("Added torpedo techtypes to PRAWN torpedo arm container filter."); + } + catch(Exception e) + { + Main.logger.LogDebug(e); + } } } diff --git a/AlterraWeaponry/patches/GameSettings_SaveAsync_Patch.cs b/AlterraWeaponry/patches/GameSettings_SaveAsync_Patch.cs deleted file mode 100644 index 664b076..0000000 --- a/AlterraWeaponry/patches/GameSettings_SaveAsync_Patch.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace VELD.AlterraWeaponry.patches; - -[HarmonyPatch(typeof(GameSettings))] -public class GameSettings_SaveAsync_Patch -{ - [HarmonyPostfix] - [HarmonyPatch(nameof(GameSettings.SaveAsync))] - public static void SaveAsync(GameSettings.OnSaveDelegate onSave) - { - LanguagesHandler.LanguagePatch(); - } -} diff --git a/AlterraWeaponry/patches/ItemGoalTracker_Start_Patch.cs b/AlterraWeaponry/patches/ItemGoalTracker_Start_Patch.cs index b0f116b..ed0364b 100644 --- a/AlterraWeaponry/patches/ItemGoalTracker_Start_Patch.cs +++ b/AlterraWeaponry/patches/ItemGoalTracker_Start_Patch.cs @@ -1,4 +1,4 @@ -namespace VELD.AlterraWeaponry.patches; +namespace VELD.AlterraWeaponry.Patches; [HarmonyPatch(typeof(ItemGoalTracker))] internal class ItemGoalTracker_Start_Patch @@ -9,18 +9,18 @@ public static void Start(ItemGoalTracker __instance) { List<TechType> techTypes = new() { - ExplosiveTorpedo.techType, - //PrawnLaserArm.techType, + ExplosiveTorpedo.TechType, + //PrawnLaserArm.TechType, }; - var goals = __instance.goalData.goals; + ItemGoal[] goals = __instance.goalData.goals; foreach (TechType techType in techTypes) { - var goal = new ItemGoal() + ItemGoal goal = new ItemGoal() { techType = techType, goalType = Story.GoalType.PDA, - key = "Log_PDA_Goal_FirstLethal", + key = "AWFirstLethal", playInCreative = true, playInCinematics = false, }; @@ -30,14 +30,16 @@ public static void Start(ItemGoalTracker __instance) foreach (TechType techType in techTypes) { - var goal = new ItemGoal() + ItemGoal goal = new ItemGoal() { techType = techType, goalType = Story.GoalType.Encyclopedia, - key = $"Ency_PDA_Goal_{nameof(techType)}", + key = $"Ency_{nameof(techType)}", playInCreative = true, playInCinematics = false, }; + + goals = goals.AddItem(goal).ToArray(); } __instance.goalData.goals = goals; diff --git a/AlterraWeaponry/patches/SeamothTorpedo_OnEnergyDepleted_Patch.cs b/AlterraWeaponry/patches/SeamothTorpedo_OnEnergyDepleted_Patch.cs index e45e426..850c6a4 100644 --- a/AlterraWeaponry/patches/SeamothTorpedo_OnEnergyDepleted_Patch.cs +++ b/AlterraWeaponry/patches/SeamothTorpedo_OnEnergyDepleted_Patch.cs @@ -1,4 +1,4 @@ -namespace VELD.AlterraWeaponry.patches; +namespace VELD.AlterraWeaponry.Patches; [HarmonyPatch(typeof(SeamothTorpedo))] public class SeamothTorpedo_OnEnergyDepleted_Patch // Thanks to Grimm The Second ! @@ -7,6 +7,6 @@ public class SeamothTorpedo_OnEnergyDepleted_Patch // Thanks to Grimm The Second [HarmonyPatch(nameof(SeamothTorpedo.OnEnergyDepleted))] public static bool OnEnergyDepleted(SeamothTorpedo __instance) { - return __instance.enabled; + return __instance._active; } } diff --git a/AlterraWeaponry/patches/Vehicle_Awake_Patch.cs b/AlterraWeaponry/patches/Vehicle_Awake_Patch.cs index d8c491f..7bef415 100644 --- a/AlterraWeaponry/patches/Vehicle_Awake_Patch.cs +++ b/AlterraWeaponry/patches/Vehicle_Awake_Patch.cs @@ -1,4 +1,4 @@ -namespace VELD.AlterraWeaponry.patches; +namespace VELD.AlterraWeaponry.Patches; [HarmonyPatch(typeof(Vehicle))] public class Vehicle_Awake_Patch // Thanks to Grimm The Second ! @@ -7,16 +7,15 @@ public class Vehicle_Awake_Patch // Thanks to Grimm The Second ! [HarmonyPatch(nameof(Vehicle.Awake))] public static void Awake(Vehicle __instance) { - bool flag = ExplosiveTorpedoInitializer.torpedoType == null; - if(flag) + if(ExplosiveTorpedoInitializer.torpedoType == null) { - TorpedoType torpedoType = Enumerable.FirstOrDefault<TorpedoType>(__instance.torpedoTypes, (TorpedoType type) => type.techType == TechType.GasTorpedo); - GameObject prefab = (torpedoType != null) ? torpedoType.prefab : null; + TorpedoType torpedoType = Enumerable.FirstOrDefault(__instance.torpedoTypes, (TorpedoType type) => type.techType == TechType.GasTorpedo); + GameObject prefab = torpedoType?.prefab; ExplosiveTorpedoInitializer.InitPrefab(prefab); } - __instance.torpedoTypes = __instance.torpedoTypes.ToArray().AddRangeToArray(new[] + __instance.torpedoTypes = CollectionExtensions.AddRangeToArray(__instance.torpedoTypes, new[] { ExplosiveTorpedoInitializer.torpedoType - }); + }).ToArray(); } } diff --git a/AlterraWeaponry/patches/Vehicle_ChargeModule_Patch.cs b/AlterraWeaponry/patches/Vehicle_ChargeModule_Patch.cs deleted file mode 100644 index a96e1f2..0000000 --- a/AlterraWeaponry/patches/Vehicle_ChargeModule_Patch.cs +++ /dev/null @@ -1,41 +0,0 @@ - - -namespace VELD.AlterraWeaponry.patches; - -[HarmonyPatch(typeof(Vehicle))] -public class Vehicle_ChargeModule_Patch -{ - [HarmonyPrefix] - [HarmonyPatch(nameof(Vehicle.ChargeModule))] - public static bool ChargeModule(Vehicle __instance, TechType techType, int slotID) - { - float num = __instance.quickSlotCharge[slotID]; - float maxCharge = TechData.GetMaxCharge(techType); - - // TEMP CODE WAITING FOR SMLHELPER UPDATE - if(techType == PrawnSelfDefenseModule.techType) - maxCharge = PrawnSelfDefenseModule.maxCharge; - - float num2; - TechData.GetEnergyCost(techType, out num2); - - // TEMP CODE WAITING FOR SMLHELPER UPDATE - if (techType == PrawnSelfDefenseModule.techType) - num2 = PrawnSelfDefenseModule.energyCost; - - float num3 = num2 * Time.deltaTime; - float num4 = maxCharge - num; - bool flag = num3 >= num4; - float b = flag ? Mathf.Max(0f, num4) : num3; - int num6; - float num5 = Mathf.Min(__instance.energyInterface.TotalCanProvide(out num6), b); - __instance.ConsumeEnergy(num5); - __instance.quickSlotCharge[slotID] = __instance.quickSlotCharge[slotID] + num5; - if (__instance.quickSlotCharge[slotID] > 0f && (flag || num5 == 0f)) - { - __instance.OnUpgradeModuleUse(techType, slotID); - __instance.quickSlotCharge[slotID] = 0f; - } - return false; - } -} diff --git a/AlterraWeaponry/patches/Vehicle_GetSlotCharge_Patch.cs b/AlterraWeaponry/patches/Vehicle_GetSlotCharge_Patch.cs deleted file mode 100644 index 8289dff..0000000 --- a/AlterraWeaponry/patches/Vehicle_GetSlotCharge_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace VELD.AlterraWeaponry.patches; - - -[HarmonyPatch(typeof(Vehicle))] -internal class Vehicle_GetSlotCharge_Patch -{ - [HarmonyPrefix] - [HarmonyPatch(nameof(Vehicle.GetSlotCharge))] - public static bool GetSlotCharge(Vehicle __instance, int slotID, ref float __result) - { - if (slotID < 0 || slotID >= __instance.slotIDs.Length) - { - __result = 1f; - return false; - } - TechType techType; - QuickSlotType quickSlotType = __instance.GetQuickSlotType(slotID, out techType); - if (quickSlotType == QuickSlotType.Chargeable || quickSlotType == QuickSlotType.SelectableChargeable) - { - float maxCharge = TechData.GetMaxCharge(techType); - - // TEMPORARY PATCH, WAITING FOR AN SMLHELPER UPDATE - bool flag = techType == PrawnSelfDefenseModule.techType; - if (flag) - maxCharge = PrawnSelfDefenseModule.maxCharge; - - if (maxCharge > 0f) - { - __result = __instance.quickSlotCharge[slotID] / maxCharge; - Main.logger.LogInfo($"Slot charge: {__result}"); - return false; - } - } - __result = 1f; - return false; - } -} diff --git a/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleChange_Patch.cs b/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleChange_Patch.cs deleted file mode 100644 index 0f1d831..0000000 --- a/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleChange_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace VELD.AlterraWeaponry.patches; - -[HarmonyPatch(typeof(Vehicle))] -internal class Vehicle_OnUpgradeModuleChange_Patch -{ - [HarmonyPostfix] - [HarmonyPatch(nameof(Vehicle.OnUpgradeModuleChange))] - public static void OnUpgradeModuleChange(TechType techType, bool added, Vehicle __instance) - { - if(techType == PrawnSelfDefenseModule.techType) - { - if(added) - { - Main.logger.LogInfo("Adding component ZapFunctionality to Vehicle."); - __instance.gameObject.AddComponent<ZapFunctionalityBehaviour>(); - Main.logger.LogInfo("Added successfully ZapFunctionality to Vehicle."); - } - else - { - __instance.TryGetComponent<ZapFunctionalityBehaviour>(out ZapFunctionalityBehaviour defenseMono); - if (defenseMono != null) - UnityEngine.Object.Destroy(defenseMono); - } - } - } -} diff --git a/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleUse_Patch.cs b/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleUse_Patch.cs deleted file mode 100644 index a555f97..0000000 --- a/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleUse_Patch.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace VELD.AlterraWeaponry.patches; - -[HarmonyPatch(typeof(Vehicle))] -public class Vehicle_OnUpgradeModuleUse_Patch -{ - [HarmonyPostfix] - [HarmonyPatch(nameof(Vehicle.OnUpgradeModuleUse))] - public static void OnUpgradeModuleUse(TechType techType, int slotID, Vehicle __instance) - { - if(__instance is not Exosuit) - return; - - - bool flag = true; - float num = 0f; - if (techType == PrawnSelfDefenseModule.techType) - { - if (!__instance.TryGetComponent(out ZapFunctionalityBehaviour defenseMono)) - return; - defenseMono.Zap(__instance, slotID); - num = PrawnSelfDefenseModule.cooldown; - } - if (flag) - { - __instance.quickSlotTimeUsed[slotID] = Time.time; - __instance.quickSlotCooldown[slotID] = num; - } - } -} diff --git a/AlterraWeaponry/patches/uGUISceneLoading_End_Patch.cs b/AlterraWeaponry/patches/uGUISceneLoading_End_Patch.cs index 1a55cd6..d10ddcd 100644 --- a/AlterraWeaponry/patches/uGUISceneLoading_End_Patch.cs +++ b/AlterraWeaponry/patches/uGUISceneLoading_End_Patch.cs @@ -1,13 +1,14 @@ -namespace VELD.AlterraWeaponry.patches; +namespace VELD.AlterraWeaponry.Patches; [HarmonyPatch(typeof(uGUI_SceneLoading))] public class uGUISceneLoading_End_Patch { - [HarmonyPrefix] + [HarmonyPostfix] [HarmonyPatch(nameof(uGUI_SceneLoading.End))] - public static void End(bool fade) + public static void End(uGUI_SceneLoading __instance, bool fade) { Main.logger.LogInfo("Triggered LoadingScene end."); + //if(StoryGoalManager.main.OnGoalComplete(Main.AWPresentationGoal.key)) Main.AWPresentationGoal.Trigger(); Main.logger.LogInfo("Should play or have played AWPresentationGoal."); } diff --git a/AlterraWeaponry/utils/ExplosiveTorpedoInitializer.cs b/AlterraWeaponry/utils/ExplosiveTorpedoInitializer.cs index 4691f6a..bac3dbf 100644 --- a/AlterraWeaponry/utils/ExplosiveTorpedoInitializer.cs +++ b/AlterraWeaponry/utils/ExplosiveTorpedoInitializer.cs @@ -1,4 +1,4 @@ -namespace VELD.AlterraWeaponry.behaviours; +namespace VELD.AlterraWeaponry.Utils; internal class ExplosiveTorpedoInitializer // Thanks to Grimm The Second ! { @@ -6,29 +6,35 @@ internal class ExplosiveTorpedoInitializer // Thanks to Grimm The Second ! public static void InitPrefab(GameObject prefab) { - bool flag = torpedoType != null; - if(!flag) + if(torpedoType == null) { - bool flag2 = !prefab; - if(flag2) + if(!prefab) { Main.logger.LogError("ExplosiveTorpedoBehaviour.InitPrefab() -> invalid prefab for torpedo."); } else { - GameObject go = new GameObject("TorpedoExplosion", new Type[] + try { - typeof(TorpedoExplosionBehaviour) - }); - ModPrefabCache.AddPrefab(go, false); - GameObject go2 = ModPrefabCache.AddPrefabCopy(prefab, false); - go2.GetComponent<SeamothTorpedo>().explosionPrefab = go; - go2.GetComponent<SeamothTorpedo>().homingTorpedo = true; - torpedoType = new() + CoroutineHost.StartCoroutine(TorpedoExplosionBehaviour.SetupDetonationPrefabAsync()); + Main.logger.LogInfo("Initializing TorpedoExplosionBehaviour TorpedoExplosion prefab..."); + GameObject go = new("TorpedoExplosion", new Type[] + { + typeof(TorpedoExplosionBehaviour) + }); + ModPrefabCache.AddPrefab(go); + prefab.GetComponent<SeamothTorpedo>().explosionPrefab = go; + prefab.GetComponent<SeamothTorpedo>().homingTorpedo = true; + torpedoType = new() + { + techType = ExplosiveTorpedo.TechType, + prefab = prefab + }; + } + catch(Exception ex) { - techType = ExplosiveTorpedo.techType, - prefab = go2 - }; + Main.logger.LogError($"An error has occured while initializing torpedo prefab.\n{ex}"); + } } } } diff --git a/AlterraWeaponry/utils/GlobalInitializer.cs b/AlterraWeaponry/utils/GlobalInitializer.cs new file mode 100644 index 0000000..783c3c1 --- /dev/null +++ b/AlterraWeaponry/utils/GlobalInitializer.cs @@ -0,0 +1,138 @@ +namespace VELD.AlterraWeaponry.Utils; + +internal class GlobalInitializer +{ + internal static string AudiosPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Sounds"); + internal static void PatchGoals() + { + + Main.AWPresentationGoal = new("PWAPresentation", Story.GoalType.PDA, 8f) + { + playInCreative = true, + playInCinematics = false, + checkPlayerSafety = true, + delay = 15f + }; + + Nautilus.Handlers.StoryGoalHandler.RegisterCustomEvent(Main.AWPresentationGoal.key, () => + { + Main.logger.LogInfo("Played PWAPresentation goal."); + }); + + Main.AWFirstLethal = Nautilus.Handlers.StoryGoalHandler.RegisterItemGoal("AWFirstLethal", Story.GoalType.PDA, ExplosiveTorpedo.TechType, 3f); + + Nautilus.Handlers.StoryGoalHandler.RegisterCustomEvent("AWFirstLethal", () => + { + Main.logger.LogInfo("Revealing the WeaponsAuthorization PDA ency entry."); + try + { + PDAEncyclopedia.Reveal("Ency_WeaponsAuthorization", true); + } + catch(Exception ex) + { + Main.logger.LogError(ex.ToString()); + } + + try + { + PDAEncyclopedia.Reveal("WeaponsAuthoriazation", true); + } + catch (Exception ex) + { + Main.logger.LogError(ex.ToString()); + } + }); + } + + internal static void PatchPDALogs() + { + Main.logger.LogInfo($"{Main.modName} {Main.modVers} Registering PDA Logs..."); + + // Presentation PDA log "Hello xenoworker 91802..." + if(Main.AssetsCache.TryGetAsset("PWAPresentation", out AudioClip PWAPresentation)) + { + Main.logger.LogInfo("PWAPresentation audio message is being registered."); + if(Main.Options.allowDialogs) + { + Sound sound = AudioUtils.CreateSound(PWAPresentation, AudioUtils.StandardSoundModes_Stream); + CustomSoundHandler.RegisterCustomSound("PWAPresAudio", sound, AudioUtils.BusPaths.PDAVoice); + FMODAsset fmodAsset = AudioUtils.GetFmodAsset("PWAPresAudio"); + PDAHandler.AddLogEntry( + Main.AWPresentationGoal.key, + "Subtitles_AWPresentation", + sound: fmodAsset, + SpriteManager.Get(SpriteManager.Group.Log, "Pda") + ); + } + else + { + PDAHandler.AddLogEntry( + Main.AWPresentationGoal.key, + "Subtitles_AWPresentation", + sound: null, + SpriteManager.Get(SpriteManager.Group.Log, "Pda") + ); + } + } + + // First lethal weapon PDA log "A lethal weapon have been detected into your inventory..." + if(Main.AssetsCache.TryGetAsset("FirstLethalMessage", out AudioClip AWFirstLethal)) + { + Main.logger.LogInfo("AWFirstLethal audio message is being registered."); + if(Main.Options.allowDialogs) + { + Sound sound = AudioUtils.CreateSound(AWFirstLethal, AudioUtils.StandardSoundModes_Stream); + CustomSoundHandler.RegisterCustomSound("FirstLethalMessage", sound, AudioUtils.BusPaths.PDAVoice); + FMODAsset fmodAsset = AudioUtils.GetFmodAsset("FirstLethalMessage"); + PDAHandler.AddLogEntry( + key: "AWFirstLethal", + languageKey: "Subtitles_AWFirstLethal", + sound: fmodAsset, + SpriteManager.Get(SpriteManager.Group.Log, "Pda") + ); + } + else + { + PDAHandler.AddLogEntry( + key: "AWFirstLethal", + languageKey: "Subtitles_AWFirstLethal", + sound: null, + SpriteManager.Get(SpriteManager.Group.Log, "Pda") + ); + } + Main.logger.LogInfo("AWFirstLethal registered successfully."); + + } + + Main.logger.LogInfo($"{Main.modName} {Main.modVers} Registered PDA logs!"); + } + + internal static void PatchPDAEncyEntries() + { + // Register AWModInfo entry + PDAHandler.AddEncyclopediaEntry( + "AWModInfo", + "Meta", + null, + null, + unlockSound: PDAHandler.UnlockBasic + ); + + // Prawn laser arm entry + PDAHandler.AddEncyclopediaEntry( + "PrawnLaserArm", + "Tech/Weaponry", + null, + null, + unlockSound: PDAHandler.UnlockBasic + ); + + PDAHandler.AddEncyclopediaEntry( + "WeaponsAuthorization", + "Tech/Weaponry", + null, + null, + unlockSound: PDAHandler.UnlockImportant + ); + } +} diff --git a/AlterraWeaponry/utils/LanguagesHandler.cs b/AlterraWeaponry/utils/LanguagesHandler.cs index dc4ce23..5ccaa9d 100644 --- a/AlterraWeaponry/utils/LanguagesHandler.cs +++ b/AlterraWeaponry/utils/LanguagesHandler.cs @@ -1,4 +1,4 @@ -namespace VELD.AlterraWeaponry.utils +namespace VELD.AlterraWeaponry.Utils { namespace LocalizationHandler { @@ -39,7 +39,7 @@ public static void LanguagePatch() Main.logger.LogInfo("Starting patching the languages !"); XmlSerializer serializer = new(typeof(LocalizationHandler.LocalizationPackages)); - FileStream fs = new(Path.Combine(ModPath, filename), FileMode.Open); + FileStream fs = new(Path.Combine(ModPath, filename), FileMode.Open, FileAccess.Read); LocalizationHandler.LocalizationPackages lps; Main.logger.LogInfo(Language.main.GetCurrentLanguage()); @@ -56,7 +56,7 @@ public static void LanguagePatch() if (Language.main.Get(text.key) != null) { LanguageHandler.SetLanguageLine(text.key, text.value); - Main.logger.LogInfo($"Patched key {text.key} with text '{(text.value.Length > 50 ? text.value.Substring(50) : text.value)}'"); + Main.logger.LogInfo($"Patched key {text.key} with text '{(text.value.Length > 50 ? text.value.Substring(0, 50) + "..." : text.value)}'"); } else { @@ -65,5 +65,29 @@ public static void LanguagePatch() } Main.logger.LogInfo("Language patching done."); } + + public static void GlobalPatch() + { + Main.logger.LogInfo("Starting global patching..."); + XmlSerializer serializer = new(typeof(LocalizationHandler.LocalizationPackages)); + + FileStream fs = new(Path.Combine(ModPath, filename), FileMode.Open, FileAccess.Read); + LocalizationHandler.LocalizationPackages lps; + + lps = (LocalizationHandler.LocalizationPackages)serializer.Deserialize(fs); + + foreach (LocalizationHandler.LocalizationPackage locpack in lps.Localizations) + { + Main.logger.LogInfo(locpack.Lang); + + foreach(LocalizationHandler.Text text in locpack.Texts) + { + if (string.IsNullOrEmpty(text.value)) + continue; + LanguageHandler.SetLanguageLine(text.key, text.value, locpack.Lang); + Main.logger.LogInfo($"Patched key {text.key} with text '{(text.value.Length > 50 ? text.value.Substring(0, 50) + "..." : text.value)}'"); + } + } + } } } diff --git a/AlterraWeaponry/utils/Options.cs b/AlterraWeaponry/utils/Options.cs new file mode 100644 index 0000000..bae28ee --- /dev/null +++ b/AlterraWeaponry/utils/Options.cs @@ -0,0 +1,13 @@ +namespace VELD.AlterraWeaponry.Utils; + +[Menu("Alterra Weaponry")] +public class Options : Nautilus.Json.ConfigFile +{ + + [Toggle(LabelLanguageId = "Options.AW_DialogsBool", TooltipLanguageId = "Options.AW_DialogsBool.Tooltip", Order = 0)] + public bool allowDialogs = true; + + [Slider(Min = 0.05f, Max = 24.00f, Step = 0.05f, Format = "x{0:F2}", + LabelLanguageId = "Options.AW_dmgMultiplier", TooltipLanguageId = "Options.AW_dmgMultiplier.Tooltip", Order = 1)] + public float dmgMultiplier = 1.0f; +} diff --git a/README.md b/README.md index 0fdf421..89983c9 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,9 @@ Main weapons: - **Unity 2019.4.36f1**: Bundling the assets ### Dependencies -- **SMLHelper 2.14.1** -- **BepInEx** (Latest) +- [**Nautilus v1.0.0-pre.16+**](https://github.com/SubnauticaModding/Nautilus/releases) +- [**CuddleLibs v1.0.1+**](https://github.com/VELD-Dev/CuddleLibs) +- [**Tobey's BepInEx Pack**](https://github.com/toebeann/BepInEx.Subnautica/releases) This C# project is using **.NET 4.7.2** and **C# 11.0**.