diff --git a/Extensions.cs b/Extensions.cs new file mode 100644 index 0000000..3d61265 --- /dev/null +++ b/Extensions.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace SandSpace +{ + public static class Extensions + { + public static float Distance (this Vector3 vector1, Vector3 vector2) + { + return (vector1 - vector2).magnitude; + } + + public static T RemoveFirst (this List list) + { + if (list == null || list.Count == 0) + return default; + + var index = 0; + var result = list[index]; + list.RemoveAt (index); + + return result; + } + + public static T RemoveLast (this List list) + { + if (list == null || list.Count == 0) + return default; + + var index = list.Count - 1; + var result = list[index]; + list.RemoveAt (index); + + return result; + } + } +} diff --git a/Patches/BigShipsPatches.cs b/Patches/BigShipsPatches.cs index 2e810b2..7d47564 100644 --- a/Patches/BigShipsPatches.cs +++ b/Patches/BigShipsPatches.cs @@ -10,7 +10,7 @@ internal static class Engine_GetDrag_Patch { internal static void Postfix (ref float __result) { - __result = __result * SandSpaceMod.Settings.engineDragMult; + __result = __result * SandSpaceMod.Settings.engineLinearDragMult; } } @@ -20,7 +20,7 @@ internal static class Engine_GetRotateAngularDrag_Patch { internal static void Postfix (ref float __result) { - __result = __result * SandSpaceMod.Settings.engineRotateDragMult; + __result = __result * SandSpaceMod.Settings.engineAngularDragMult; } } } diff --git a/Patches/ResourcesPatces.cs b/Patches/ResourcesPatces.cs index eff1ac2..1fde8a4 100644 --- a/Patches/ResourcesPatces.cs +++ b/Patches/ResourcesPatces.cs @@ -8,7 +8,7 @@ internal class ResourcesPatces // Патч с настройкой колличества Реза добываемого с астероидов internal static class PickupRez_OnPickedUp_Patch { - internal static bool Prefix (ref PickupRez __instance) + internal static bool Prefix (ref PickupRez __instance, ref PickupGrabber grabber) { var newValue = __instance.pickupOverrideValue; if (newValue > 0) @@ -22,6 +22,12 @@ internal static bool Prefix (ref PickupRez __instance) { newValue = Mathf.FloorToInt (newValue * SandSpaceMod.Settings.rezGlobalDropMult); } + if (SandSpaceMod.Settings.rezDropMultFromLevel) + { + var playerLevel = grabber.GetShipControls ().GetBattleEntity ().GetCurrentLevel (); + newValue *= playerLevel; + } + __instance.pickupOverrideValue = newValue; return true; diff --git a/Patches/ShipPartsPatches.cs b/Patches/ShipPartsPatches.cs index ba73956..91a0adb 100644 --- a/Patches/ShipPartsPatches.cs +++ b/Patches/ShipPartsPatches.cs @@ -1,7 +1,10 @@ -using HarmonyLib; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Emit; +using HarmonyLib; using UnityEngine; -namespace SandSpace.Patches +namespace SandSpace { internal class ShipPartsPatches { @@ -18,5 +21,31 @@ private static void Postfix (ref ItemBuildInfo __instance, ref int __result) __result = Mathf.FloorToInt (__result * SandSpaceMod.Settings.shipPartsBoosterMult); } } + + // Фикс цены деталей при изменении множителя характеристик + //[HarmonyPatch (typeof (ShipPartDatabase), nameof (ShipPartDatabase.GetBuildInfoScrapPrice))] + internal static class ShipPartDatabase_GetBuildInfoScrapPrice_Patch + { + internal static IEnumerable Transpiler (IEnumerable instructions) + { + var codes = new List(instructions); + + for (var i = 0; i < codes.Count; i++) + { + if (codes[i].opcode == OpCodes.Ldloc_S && + ((LocalBuilder)codes[i].operand).LocalIndex == 5 && + codes[i + 1].opcode == OpCodes.Add && + codes[i + 2].opcode == OpCodes.Stloc_S && + ((LocalBuilder)codes[i + 2].operand).LocalIndex == 9) + { + codes[i].opcode = OpCodes.Nop; + codes[i + 1].opcode = OpCodes.Nop; + break; + } + } + + return codes.AsEnumerable (); + } + } } } diff --git a/Patches/StrikeCraftPatches.cs b/Patches/StrikeCraftPatches.cs index ded90d8..9512e42 100644 --- a/Patches/StrikeCraftPatches.cs +++ b/Patches/StrikeCraftPatches.cs @@ -1,6 +1,6 @@ using HarmonyLib; -namespace SandSpace.Patches +namespace SandSpace { internal class StrikeCraftPatches { diff --git a/README.md b/README.md index 117c853..f9947a3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # SandSpace -This is a mod for the game "SPAZ 2" which uses the Unity Mod Manager to work. +This is a mod for the game "SPAZ 2" which uses the Unity Mod Manager to work. (final version) ## Features - Changing number of active hangars @@ -8,12 +8,8 @@ This is a mod for the game "SPAZ 2" which uses the Unity Mod Manager to work. - Changing perk bonuses after max player level - Changing the strength and size of explosions - Changing amount of Rez drop from asteroids -- Sandbox settings menu for company mode (need new game) - -## In developing (maybe) -- Block rarity bonus settings -- Add more turrets to support ships depending on their size -- Add more turrets to blocks +- Changing block bonus stats from rarity +- Sandbox settings menu when starting new campaign ## Installation - Mod requires [Unity Mod Manager](https://www.nexusmods.com/site/mods/21) to work. diff --git a/SandSpace.csproj b/SandSpace.csproj index 91c62a4..9c55590 100644 --- a/SandSpace.csproj +++ b/SandSpace.csproj @@ -1,84 +1,25 @@ - - - + - Debug - AnyCPU - {4BFDFA3C-6EA6-4BB7-B82A-B6C55ECF1DE5} - Library - Properties - SandSpace SandSpace - v3.5 - 512 - true - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\ - TRACE - prompt - 4 + False + net35 + $(SolutionDir)bin\ + false + false - - ..\lib\0Harmony.dll - False - - - ..\lib\Assembly-CSharp.dll - False - - - False - ..\lib\Newtonsoft.Json.dll - False - - - - ..\lib\UnityEngine.dll - False - - - ..\lib\UnityEngine.UI.dll - False - - - ..\lib\UnityModManager.dll - False + + false - - - - - - - - - - - - - - - - - - - - - copy /Y "$(TargetDir)$(ProjectName).dll" "D:\Steam\steamapps\common\SPAZ2\Mods\SandSpace\$(ProjectName).dll" + copy /Y "$(OutputPath)$(AssemblyName).dll" "D:\Steam\steamapps\common\SPAZ2\Mods\SandSpace\$(AssemblyName).dll" + AnyCPU + + + portable + + + portable - \ No newline at end of file + \ No newline at end of file diff --git a/SandSpaceMod.cs b/SandSpaceMod.cs index 4122bf6..c153faf 100644 --- a/SandSpaceMod.cs +++ b/SandSpaceMod.cs @@ -8,7 +8,7 @@ namespace SandSpace { public class SandSpaceMod { - public const string version = "0.5.1"; + public const string version = "0.5.2"; public static UnityModManager.ModEntry ModEntry { get; private set; } public static Settings Settings { get; private set; } @@ -99,6 +99,12 @@ private static void DynamicPathes () transpiler: new HarmonyMethod (typeof (NewGamePatches.SinglePlayerMenu_windowFunc_Patch), "Transpiler") ); } + + if (Settings.enablePartCostPatch) + Harmony.Patch ( + AccessTools.Method (typeof (ShipPartDatabase), nameof (ShipPartDatabase.GetBuildInfoScrapPrice)), + transpiler: new HarmonyMethod (typeof (ShipPartsPatches.ShipPartDatabase_GetBuildInfoScrapPrice_Patch), "Transpiler") + ); } private static void ReloadHarmonyPatches () diff --git a/Settings.cs b/Settings.cs index a6b7db7..d4e79fa 100644 --- a/Settings.cs +++ b/Settings.cs @@ -82,7 +82,7 @@ public class Settings : UnityModManager.ModSettings, IDrawable public bool enableShockwaveExplosionsPatch = true; [Draw ("┣━ Change size by multiplier", Min = 0.01, Max = 1000, VisibleOn = "enableShockwaveExplosionsPatch|true")] - public float hazardsShockwaveSizeMult = 8.0f; + public float hazardsShockwaveSizeMult = 4.0f; [Draw ("┣━ Change damage by multiplier", Min = 0.01, Max = 1000, VisibleOn = "enableShockwaveExplosionsPatch|true")] public float hazardsShockwaveDamageMult = 0.2f; @@ -99,7 +99,10 @@ public class Settings : UnityModManager.ModSettings, IDrawable public float rezMinDropMult = 1.0f; [Draw ("┣━━ Max amount of Rez from asteroids multiplier", Min = 0.01, Max = 1000, VisibleOn = "enableRezDropPatch|true")] - public float rezMaxDropMult = 5.0f; + public float rezMaxDropMult = 2.0f; + + [Draw ("┣━━ Enable player level as multiplier of Rez from asteroids")] + public bool rezDropMultFromLevel = false; [Draw ("┗━━ Global multiplier of Rez drop", Min = 0.01, Max = 1000, VisibleOn = "enableRezDropPatch|true")] public float rezGlobalDropMult = 1.0f; @@ -111,22 +114,25 @@ public class Settings : UnityModManager.ModSettings, IDrawable [Header ("┏ Experimental"), Space (25f)] - [Draw ("┣━━ Enable sandbox settings menu for company mode (need new game)")] + [Draw ("┣━━ Enable sandbox settings menu when starting new campaign")] public bool enableSandboxCampaign = false; - [Draw ("┣━━ Drag factor in outer space", Min = 0.01, Max = 1000)] - public float engineDragMult = 0.5f; + [Draw ("┣━━ Linear drag factor in outer space", Min = 0.01, Max = 1000)] + public float engineLinearDragMult = 0.75f; - [Draw ("┣━━ Rotation drag factor in outer space", Min = 0.01, Max = 1000)] - public float engineRotateDragMult = 1.0f; + [Draw ("┣━━ Angular drag factor in outer space", Min = 0.01, Max = 1000)] + public float engineAngularDragMult = 1.0f; - [Draw ("┣━━ Extra stats multiplier for ship parts", Min = 0.01, Max = 1000)] + [Draw ("┣━━ Extra stats multiplier from rarity for ship parts", Min = 0.01, Max = 1000)] public float shipPartsBoosterMult = 1.0f; - [Draw ("┣━━ Extra stats multiplier for station parts", Min = 0.01, Max = 1000)] + [Draw ("┣━━ Extra stats multiplier from rarity for station parts", Min = 0.01, Max = 1000)] public float stationPartsBoosterMult = 1.0f; - [Draw ("┗━━ Extra stats multiplier for strike crafts depending their skill", Min = 0.01, Max = 1000)] + [Draw ("┣━━ Enable price fix for ship parts if applyed extra stats multiplier")] + public bool enablePartCostPatch = false; + + [Draw ("┗━━ Extra stats multiplier from rarity for strike crafts", Min = 0.01, Max = 1000)] public float strikeCraftsStrengthMult = 1.0f; public override void Save (UnityModManager.ModEntry modEntry) @@ -202,6 +208,14 @@ private void SetDefaults () rezMaxDropMult = def.rezMaxDropMult; rezGlobalDropMult = def.rezGlobalDropMult; + enableSandboxCampaign = def.enableSandboxCampaign; + engineLinearDragMult = def.engineLinearDragMult; + engineAngularDragMult = def.engineAngularDragMult; + shipPartsBoosterMult = def.shipPartsBoosterMult; + stationPartsBoosterMult = def.stationPartsBoosterMult; + enablePartCostPatch = def.enablePartCostPatch; + strikeCraftsStrengthMult = def.strikeCraftsStrengthMult; + PerkPatches.SetDefaults (); } } diff --git a/WeaponMountsTests.cs b/WeaponMountsTests.cs new file mode 100644 index 0000000..1708bba --- /dev/null +++ b/WeaponMountsTests.cs @@ -0,0 +1,165 @@ +using System.Collections.Generic; +using System.IO; +using System.Text; +using UnityEngine; + +namespace SandSpace +{ + internal static class WeaponMountsTests + { + //MountConfigManager - хранит пресеты MountPicker под конкретный тип орудий + //MountPicker - хранит точки позиций маунтов + //MountPrefabLinker - точка для маунта + + internal static void AddSynergyMounts () + { + var shipPartDatabase = GameManager.GetShipPartDatabase (); + + //AddSynergyMountsForPrefabs (shipPartDatabase); + AddSynergyMountsForReal (shipPartDatabase); + } + + internal static void AddSynergyMountsForPrefabs (ShipPartDatabase shipPartDatabase) + { + var partTypeDictionary = PatchingExtension.GetPrivateFieldValue>> (shipPartDatabase, "partTypeDictionary"); + var partClassDictionary = PatchingExtension.GetPrivateFieldValue>> (shipPartDatabase, "partClassDictionary"); + + var wings = new List (); + wings.AddRange (partTypeDictionary[ItemType.LEFT_WING]); + wings.AddRange (partTypeDictionary[ItemType.RIGHT_WING]); + + foreach (var wing in wings) + { + if (wing.myAttacherCount != 3) + continue; + + RemakeAllPickersToMaxLinkers (wing); + //AddSynergyPicker (wing); + } + } + + internal static void AddSynergyMountsForReal (ShipPartDatabase shipPartDatabase) + { + var partTypeDictionary = PatchingExtension.GetPrivateFieldValue> (shipPartDatabase, "realPartPrefabs"); + + var wings = new List (); + + foreach (var part in partTypeDictionary) + { + if ((part.myType == ItemType.LEFT_WING || part.myType == ItemType.RIGHT_WING) && part.myAttacherCount == 3) + wings.Add (part); + } + + foreach (var wing in wings) + { + RemakeAllPickersToMaxLinkers (wing); + //AddSynergyPicker (wing); + } + } + + internal static void RemakeAllPickersToMaxLinkers (ItemInfo part) + { + var mountConfig = part.GetMountConfigManager (); + + var mountPickers = mountConfig.GetComponentsInChildren (); + + var allLinkersPositions = GetAllLinkersPositions (mountPickers); + + var nextPickerIdx = mountPickers.Length; + + foreach (var mountPicker in mountPickers) + { + var mountLinkers = mountPicker.GetComponentsInChildren (); + + var nextLinkerIdx = mountLinkers.Length; + + var linkerPrefab = mountLinkers[0]; + + var newLinkerName = linkerPrefab.name; + + var newLinkerPositions = new List (allLinkersPositions); + + foreach (var mountLinker in mountLinkers) + { + mountLinker.transform.localPosition = newLinkerPositions.RemoveFirst (); + } + + foreach (var newLinkerPosition in newLinkerPositions) + { + var newLinker = GameObject.Instantiate (linkerPrefab); + newLinker.transform.SetParent (mountPicker.transform); + newLinker.transform.localPosition = newLinkerPosition; + newLinker.name = newLinkerName; + newLinker.uniqueIndex = nextLinkerIdx++; + newLinker.mountType = linkerPrefab.mountType; + } + } + } + + internal static void AddSynergyPicker (ItemInfo part) + { + var mountConfig = part.GetMountConfigManager (); + + var mountPickers = mountConfig.GetComponentsInChildren (); + + var allLinkersPositions = GetAllLinkersPositions (mountPickers); + + var linkerPrefab = mountPickers[0].transform.GetChild (0).GetComponent (); + + var synergyPicker = new GameObject ().AddComponent (); + synergyPicker.transform.SetParent (mountConfig.transform); + synergyPicker.name = "Synergy"; + synergyPicker.uniqueIndex = 0; + + var nextLinkerIdx = 0; + + foreach (var newLinkerPosition in allLinkersPositions) + { + var newLinker = GameObject.Instantiate (linkerPrefab); + newLinker.transform.SetParent (synergyPicker.transform); + newLinker.transform.localPosition = newLinkerPosition; + newLinker.name = $"Linker-{nextLinkerIdx}"; + newLinker.uniqueIndex = nextLinkerIdx++; + newLinker.mountType = MountDatabaseType.COUNT; + } + } + + internal static List GetAllLinkersPositions (MountPicker[] mountPickers) + { + var allLinkersPositions = new List (); + + var firstLinkers = mountPickers[0].GetComponentsInChildren (); + foreach (var firstLinker in firstLinkers) + { + allLinkersPositions.Add (firstLinker.transform.localPosition); + } + + foreach (var mountPicker in mountPickers) + { + var mountLinkers = mountPicker.GetComponentsInChildren (); + + var cacheLinkersPositions = new List (); + + foreach (var mountLinker in mountLinkers) + { + var far = true; + + foreach (var allLinkersPosition in allLinkersPositions) + { + if (allLinkersPosition.Distance (mountLinker.transform.localPosition) > 1f) + continue; + + far = false; + break; + } + + if (far) cacheLinkersPositions.Add (mountLinker.transform.localPosition); + } + + allLinkersPositions.AddRange (cacheLinkersPositions); + } + + return allLinkersPositions; + } + } +}