Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BetterCreative v1.5.0
plugins\BetterCreative\BetterCreative.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Better Creative Mode")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BetterCreative")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("1.5.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.5.0.0")] namespace Heinermann { public class SimplePiece { public string Name { get; set; } public string PieceTable { get; set; } public string Category { get; set; } public string CraftingStation { get; set; } public Dictionary<string, int> Requirements { get; set; } = new Dictionary<string, int>(); public PieceConfig PieceConfig() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown return new PieceConfig { Name = "$heinermann_" + Name, PieceTable = PieceTable, Category = Category, CraftingStation = CraftingStation, Description = "$heinermann_" + Name + "_desc", Requirements = ((IEnumerable<KeyValuePair<string, int>>)Requirements).Select((Func<KeyValuePair<string, int>, RequirementConfig>)((KeyValuePair<string, int> item) => new RequirementConfig(item.Key, item.Value, 0, true))).ToArray() }; } } public static class PieceUtil { private static Sprite CreateIcon(GameObject prefab) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return RenderManager.Instance.Render(prefab, RenderManager.IsometricRotation); } public static void AddPieces(AssetBundle bundle, IEnumerable<SimplePiece> pieces) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown foreach (SimplePiece piece in pieces) { GameObject val = bundle.LoadAsset<GameObject>("heinermann_" + piece.Name); if ((Object)(object)val == (Object)null) { Logger.LogError((object)("Failed to load asset: heinermann_" + piece.Name)); continue; } PieceConfig val2 = piece.PieceConfig(); Piece component = val.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { if ((Object)(object)component.m_icon == (Object)null) { component.m_icon = CreateIcon(val); } val2.Icon = component.m_icon; } else { val2.Icon = CreateIcon(val); } PieceManager.Instance.AddPiece(new CustomPiece(val, true, piece.PieceConfig())); } } } public static class UnityExtensions { public static T GetOrAddComponent<T>(this GameObject go) where T : Component { T val = go.GetComponent<T>(); if ((Object)(object)val == (Object)null) { val = go.AddComponent<T>(); } return val; } public static void DestroyComponent<T>(this GameObject go) where T : Component { T[] componentsInChildren = go.GetComponentsInChildren<T>(); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } } public static bool HasAnyComponent(this GameObject go, params string[] componentNames) { return componentNames.Any((string component) => (Object)(object)go.GetComponent(component) != (Object)null); } public static bool HasAnyComponentInChildren(this GameObject go, params Type[] components) { return components.Any((Type component) => (Object)(object)go.GetComponentInChildren(component, true) != (Object)null); } public static bool HasAllComponents(this GameObject go, params string[] componentNames) { return componentNames.All((string component) => (Object)(object)go.GetComponent(component) != (Object)null); } public static bool ContainsAny(this string str, params string[] substrings) { return substrings.Any((string s) => str.Contains(s)); } } } namespace Heinermann.BetterCreative { public static class Configs { private const string CommandStates = "Command States"; public static ConfigEntry<bool> DevCommands; public static ConfigEntry<bool> NoCost; public static ConfigEntry<bool> God; public static ConfigEntry<bool> Ghost; public static ConfigEntry<bool> DebugMode; private const string Improvements = "Improvements"; public static ConfigEntry<bool> UnlimitedStamina; public static ConfigEntry<bool> AllPrefabs; public static ConfigEntry<bool> UnrestrictedPlacement; public static ConfigEntry<bool> NoPieceDrops; public static ConfigEntry<bool> NoPieceDelay; public static ConfigEntry<bool> NoDurabilityDrain; public static ConfigEntry<bool> NoEncumbered; public static ConfigEntry<bool> NoUnlockMsg; public static ConfigEntry<int> DeleteRange; private const string Hotkeys = "Hotkeys"; public static ConfigEntry<KeyboardShortcut> KeyUndo1; public static ConfigEntry<KeyboardShortcut> KeyUndo2; public static ConfigEntry<KeyboardShortcut> KeyRedo1; public static ConfigEntry<KeyboardShortcut> KeyRedo2; public static ConfigEntry<KeyboardShortcut> KeyDelete1; public static ConfigEntry<KeyboardShortcut> KeyDelete2; public static void Init(ConfigFile config) { //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) DevCommands = config.Bind<bool>("Command States", "devcommands", true, "Enable devcommands automatically. Required for other commands to function."); NoCost = config.Bind<bool>("Command States", "nocost", true, "No build cost, unlocks everything."); God = config.Bind<bool>("Command States", "god", true, "Makes it so you don't take damage from monsters."); Ghost = config.Bind<bool>("Command States", "ghost", true, "Prevents mobs from seeing you."); DebugMode = config.Bind<bool>("Command States", "debugmode", true, "Enables fly mode and debug hotkeys."); UnlimitedStamina = config.Bind<bool>("Improvements", "Unlimited Stamina", true, "Can always perform stamina actions regardless of stamina amount."); AllPrefabs = config.Bind<bool>("Improvements", "All Prefabs", true, "Allow placement of all functional prefabs. (Requires restart to take effect)"); UnrestrictedPlacement = config.Bind<bool>("Improvements", "Unrestricted Placement", true, "Allow unrestricted placements (no collision, campfire on wood, etc). Note: Disabling this won't allow placement of some objects. (Requires restart to take effect)"); NoPieceDrops = config.Bind<bool>("Improvements", "No Piece Drops", true, "Don't drop materials when pieces are destroyed."); NoPieceDelay = config.Bind<bool>("Improvements", "No Placement Delay", true, "No cooldowns for the hammer, cultivator, or hoe. (Requires restart to take effect)"); NoDurabilityDrain = config.Bind<bool>("Improvements", "No Durability Drain", true, "Tools don't lose durability. (Requires restart to take effect)"); NoEncumbered = config.Bind<bool>("Improvements", "No Encumbered", true, "No effect when surpassing maximum carry weight"); NoUnlockMsg = config.Bind<bool>("Improvements", "No Unlock Messages", true, "No popup message when unlocking a recipe"); DeleteRange = config.Bind<int>("Improvements", "Delete Range", 5, "Range to delete objects with the delete key. This is the radius from the placement ghost's center."); KeyboardShortcut val = default(KeyboardShortcut); ((KeyboardShortcut)(ref val))..ctor((KeyCode)122, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }); KeyUndo1 = config.Bind<KeyboardShortcut>("Hotkeys", "Undo", val, "Warning: default (ctrl+z) conflicts with sneak and fly."); KeyUndo2 = config.Bind<KeyboardShortcut>("Hotkeys", "Undo (alt)", KeyboardShortcut.Empty, "Alternative."); KeyboardShortcut val2 = default(KeyboardShortcut); ((KeyboardShortcut)(ref val2))..ctor((KeyCode)122, (KeyCode[])(object)new KeyCode[2] { (KeyCode)306, (KeyCode)304 }); KeyboardShortcut val3 = default(KeyboardShortcut); ((KeyboardShortcut)(ref val3))..ctor((KeyCode)121, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }); KeyRedo1 = config.Bind<KeyboardShortcut>("Hotkeys", "Redo", val2, "Warning: default (ctrl+shift+z) conflicts with sneak and fly."); KeyRedo2 = config.Bind<KeyboardShortcut>("Hotkeys", "Redo (alt)", val3, "Alternative."); KeyDelete1 = config.Bind<KeyboardShortcut>("Hotkeys", "Delete", new KeyboardShortcut((KeyCode)127, Array.Empty<KeyCode>()), "Destroys all prefabs that match the currently selected piece in the area."); KeyDelete2 = config.Bind<KeyboardShortcut>("Hotkeys", "Delete (alt)", KeyboardShortcut.Empty, (ConfigDescription)null); } } [HarmonyPatch] internal static class Patches { [HarmonyPatch(typeof(Player), "SetupPlacementGhost")] private class PlayerSetupPlacementGhost { private static void Prefix(Player __instance) { if ((Object)(object)GetSelectedPrefab(__instance) != (Object)null) { settingUpPlacementGhost = true; } } private static void Postfix() { settingUpPlacementGhost = false; } } [HarmonyPatch(typeof(Player), "RemovePiece")] private class OnRemovePiece { private static bool Prefix(Player __instance, ref bool __result, ref int ___m_removeRayMask) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) inRemovePiece = true; Piece val = null; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(((Component)GameCamera.instance).transform.position, ((Component)GameCamera.instance).transform.forward, ref val2, 50f, ___m_removeRayMask) && Vector3.Distance(((RaycastHit)(ref val2)).point, ((Character)__instance).m_eye.position) < __instance.m_maxPlaceDistance) { val = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Piece>(); if ((Object)(object)val == (Object)null && Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponent("Heightmap"))) { val = TerrainModifier.FindClosestModifierPieceInRange(((RaycastHit)(ref val2)).point, 2.5f); } } if (Configs.UnrestrictedPlacement.Value && Object.op_Implicit((Object)(object)val)) { WearNTear component = ((Component)val).GetComponent<WearNTear>(); if (Object.op_Implicit((Object)(object)component)) { component.Remove(); } else { ((Component)val).GetComponent<ZNetView>().ClaimOwnership(); val.DropResources((HitData)null); ZNetScene.instance.Destroy(((Component)val).gameObject); } __result = true; return false; } return true; } private static void Postfix() { inRemovePiece = false; } } private static bool settingUpPlacementGhost; private static bool inRemovePiece; public static GameObject lastPlacementGhost; public static GameObject GetSelectedPrefab(Player player) { if (player == null) { return null; } Piece selectedPiece = player.GetSelectedPiece(); if (selectedPiece == null) { return null; } return ((Component)selectedPiece).gameObject; } [HarmonyPatch(typeof(Piece), "SetCreator")] [HarmonyPrefix] private static void PieceSetCreatorPrefix(long uid, Piece __instance) { UndoHelper.Create(((Component)__instance).gameObject); Container component = ((Component)__instance).GetComponent<Container>(); if (Object.op_Implicit((Object)(object)component) && (component.m_autoDestroyEmpty || Object.op_Implicit((Object)(object)((Component)__instance).GetComponent("TombStone")))) { component.GetInventory().AddItem(PrefabManager.Instance.GetPrefab("Wood"), 1); } ZNetView component2 = ((Component)__instance).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component2) && !component2.m_persistent) { component2.m_persistent = true; if (component2.GetZDO() != null) { component2.GetZDO().Persistent = true; } ZSyncTransform orAddComponent = ((Component)__instance).gameObject.GetOrAddComponent<ZSyncTransform>(); orAddComponent.m_syncPosition = true; orAddComponent.m_syncRotation = true; } } [HarmonyPatch(typeof(Player), "IsEncumbered")] [HarmonyPrefix] private static bool PlayerIsEncumberedPrefix(ref bool __result) { if (Configs.NoEncumbered.Value) { __result = false; return false; } return true; } [HarmonyPatch(typeof(Object), "Internal_CloneSingle", new Type[] { typeof(Object) })] [HarmonyPrefix] private static bool ObjectInstantiate1Prefix(ref Object __result, Object data) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown if (settingUpPlacementGhost) { settingUpPlacementGhost = false; if (Prefabs.AddedPrefabs.Contains(data.name)) { Logger.LogInfo((object)("Setting up placement ghost for " + data.name)); GameObject val = new GameObject(); val.SetActive(false); Object val2 = Object.Instantiate(data, val.transform, false); Prefabs.PrepareGhostPrefab((GameObject)(object)((val2 is GameObject) ? val2 : null)); __result = Object.Instantiate(val2); Object.DestroyImmediate((Object)(object)val); return false; } } return true; } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] [HarmonyPostfix] private static void PlayerUpdatePlacementGhostPostfix(ref GameObject ___m_placementGhost, ref int ___m_placementStatus) { lastPlacementGhost = ___m_placementGhost; if (Configs.UnrestrictedPlacement.Value && Object.op_Implicit((Object)(object)___m_placementGhost)) { ___m_placementStatus = 0; ___m_placementGhost.GetComponent<Piece>().SetInvalidPlacementHeightlight(false); } } [HarmonyPatch(typeof(Piece), "DropResources")] [HarmonyPrefix] private static bool DropPieceResourcesPrefix() { return !Configs.NoPieceDrops.Value; } [HarmonyPatch(typeof(ZNetScene), "Destroy")] [HarmonyPrefix] private static void ZNetSceneDestroyPrefix(GameObject go) { if (inRemovePiece) { UndoHelper.Remove(go); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] [HarmonyPrefix] private static void ObjectDBAwakePrefix() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name == "main") { BetterCreative.ModifyItems(); if (Configs.AllPrefabs.Value) { Prefabs.FindAndRegisterPrefabs(); } } } [HarmonyPatch(typeof(Player), "HaveStamina")] [HarmonyPrefix] private static bool HaveStaminaPrefix(ref bool __result) { if (Configs.UnlimitedStamina.Value) { __result = true; return false; } return true; } [HarmonyPatch(typeof(Player), "ShowTutorial")] [HarmonyPrefix] private static bool ShowTutorialPrefix(string name, bool force) { return false; } [HarmonyPatch(typeof(MessageHud), "QueueUnlockMsg")] [HarmonyPrefix] private static bool MessageHudQueueUnlockMessagePrefix(Sprite icon, string topic, string description) { return !Configs.NoUnlockMsg.Value; } [HarmonyPatch(typeof(Player), "SetLocalPlayer")] [HarmonyPostfix] private static void SetLocalPlayerPostfix(Player __instance) { if (Configs.DevCommands.Value && Object.op_Implicit((Object)(object)__instance)) { if (!((Terminal)Console.instance).IsCheatsEnabled()) { ((Terminal)Console.instance).TryRunCommand("devcommands", true, true); } if (Configs.DebugMode.Value) { Player.m_debugMode = true; } if (Configs.God.Value) { __instance.SetGodMode(true); } if (Configs.Ghost.Value) { __instance.SetGhostMode(true); } if (Configs.NoCost.Value && !__instance.NoCostCheat()) { __instance.ToggleNoPlacementCost(); } if (Configs.NoPieceDelay.Value) { __instance.m_placeDelay = 0f; } } } [HarmonyPatch(typeof(ZNetView), "Awake")] [HarmonyPrefix] private static bool ZNetViewAwakePrefix(ZNetView __instance) { if (ZNetView.m_useInitZDO && ZNetView.m_initZDO == null) { Logger.LogWarning((object)("Double ZNetview when initializing object " + ((Object)__instance).name + "; OVERRIDE: Deleting the " + ((Object)__instance).name + " gameobject")); ZNetScene.instance.Destroy(((Component)__instance).gameObject); return false; } return true; } } internal static class Prefabs { public static HashSet<string> AddedPrefabs = new HashSet<string>(); private static HashSet<string> pieceNameCache = null; private static readonly HashSet<string> IgnoredPrefabs = new HashSet<string> { "Player", "Valkyrie", "HelmetOdin", "CapeOdin", "CastleKit_pot03", "Ravens", "TERRAIN_TEST", "PlaceMarker", "Circle_section" }; private const int NumPiecesPerPage = 90; private static Dictionary<string, int> itemCounts = new Dictionary<string, int> { { "Extended", 0 }, { "Pickable", 0 }, { "NPCs", 0 }, { "Spawners", 0 }, { "Vegetation", 0 }, { "Furniture", 90 }, { "Building", 90 }, { "Destructible", 0 }, { "Other", 0 } }; private static readonly HashSet<string> unrestrictedExceptions = new HashSet<string> { "horizontal_web", "tunnel_web", "dragoneggcup", "SmokeBall", "HeathRockPillar", "MountainGraveStone01", "Rock_7", "demister_ball" }; private static readonly HashSet<string> restrictedExceptions = new HashSet<string> { "Pickable_SurtlingCoreStand" }; private static HashSet<string> GetPieceNames() { if (pieceNameCache == null) { pieceNameCache = new HashSet<string>(from piece in Resources.FindObjectsOfTypeAll<PieceTable>().SelectMany((PieceTable pieceTable) => pieceTable.m_pieces) select ((Object)piece).name); } return pieceNameCache; } private static bool ShouldIgnorePrefab(GameObject prefab) { HashSet<string> pieceNames = GetPieceNames(); if (!prefab.HasAnyComponentInChildren(typeof(Collider), typeof(Renderer), typeof(CreatureSpawner), typeof(SpawnArea))) { return true; } if (!prefab.HasAnyComponent("Projectile", "TimedDestruction", "Ragdoll", "LocationProxy", "Gibber", "MineRock5", "FishingFloat", "Smoke", "TeleportAbility") && (!prefab.HasAnyComponent("ItemDrop") || prefab.HasAnyComponent("Fish")) && (!prefab.HasAnyComponent("Aoe") || prefab.HasAnyComponent("Collider", "MeshCollider", "WearNTear")) && !((Object)prefab).name.StartsWith("vfx_") && !((Object)prefab).name.StartsWith("sfx_") && !((Object)prefab).name.StartsWith("fx_") && !((Object)prefab).name.StartsWith("_") && !((Object)prefab).name.EndsWith("_aoe") && !IgnoredPrefabs.Contains(((Object)prefab).name)) { return pieceNames.Contains(((Object)prefab).name); } return true; } private static string GetPrefabCategory(GameObject prefab) { //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Invalid comparison between Unknown and I4 Destructible component = prefab.GetComponent<Destructible>(); string text = "Extended"; if (prefab.HasAnyComponent("Pickable", "PickableItem")) { text = "Pickable"; } else if (prefab.HasAnyComponent("Humanoid", "Character", "Leviathan", "RandomFlyingBird", "Fish", "Trader", "Odin", "Valkyrie", "Player")) { text = "NPCs"; } else if (prefab.HasAnyComponent("CreatureSpawner", "SpawnArea", "TriggerSpawner")) { text = "Spawners"; } else if (((Object)prefab).name.ContainsAny("Bush", "Root", "root", "shrub", "stubbe", "vines", "SwampTree") || prefab.HasAnyComponent("TreeBase", "TreeLog") || (component != null && (int)component.m_destructibleType == 2)) { text = "Vegetation"; } else if (prefab.HasAnyComponent("ArmorStand", "Container", "Fireplace") || ((Object)prefab).name.ContainsAny("groundtorch", "brazier", "cloth_hanging", "banner", "table", "chair", "sign", "bed")) { text = "Furniture"; } else if (prefab.HasAnyComponent("WearNTear", "Door")) { text = "Building"; } else if (prefab.HasAnyComponent("Destructible", "MineRock")) { text = "Destructible"; } else if (Object.op_Implicit((Object)(object)prefab.GetComponent("ZNetView"))) { text = "Other"; } int num = itemCounts[text] / 90 + 1; itemCounts[text]++; if (num > 1) { return $"{text} {num}"; } return text; } private static void ModifyPiece(Piece piece) { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)piece == (Object)null)) { piece.m_enabled = true; piece.m_canBeRemoved = true; if (((Component)piece).gameObject.HasAnyComponent("Character", "Pickable", "PickableItem", "Odin", "RandomFlyingBird", "Fish", "TombStone") || unrestrictedExceptions.Contains(((Object)piece).name)) { piece.m_clipEverything = !restrictedExceptions.Contains(((Object)piece).name); } piece.m_groundPiece = false; piece.m_groundOnly = false; piece.m_noInWater = false; piece.m_notOnWood = false; piece.m_notOnTiltingSurface = false; piece.m_notOnFloor = false; piece.m_allowedInDungeons = true; piece.m_onlyInTeleportArea = false; piece.m_inCeilingOnly = false; piece.m_cultivatedGroundOnly = false; piece.m_onlyInBiome = (Biome)0; piece.m_allowRotatedOverlap = true; } } private static void InitPieceData(GameObject prefab) { if ((Object)(object)prefab.GetComponent<Piece>() == (Object)null) { ModifyPiece(prefab.AddComponent<Piece>()); } } private static bool SpriteIsBlank(Sprite sprite) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Color[] pixels = sprite.texture.GetPixels(); for (int i = 0; i < pixels.Length; i++) { if (pixels[i].a != 0f) { return false; } } return true; } private static Sprite CreatePrefabIcon(GameObject prefab) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) Sprite val = RenderManager.Instance.Render(prefab, RenderManager.IsometricRotation); if ((Object)(object)val == (Object)null) { GameObject val2 = prefab.GetComponent<CreatureSpawner>()?.m_creaturePrefab; if ((Object)(object)val2 != (Object)null) { val = RenderManager.Instance.Render(val2, RenderManager.IsometricRotation); } } if ((Object)(object)val == (Object)null) { RandomItem[] array = prefab.GetComponent<PickableItem>()?.m_randomItemPrefabs; if (array != null && array.Length != 0) { ItemDrop itemPrefab = array[0].m_itemPrefab; GameObject val3 = ((itemPrefab != null) ? ((Component)itemPrefab).gameObject : null); if ((Object)(object)val3 != (Object)null) { val = RenderManager.Instance.Render(val3, RenderManager.IsometricRotation); } } } if (!((Object)(object)val == (Object)null)) { SpriteIsBlank(val); } return val; } public static void PrepareGhostPrefab(GameObject ghost) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) ghost.DestroyComponent<CharacterDrop>(); Component[] componentsInChildren = ghost.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if (!(val is Piece) && !(val is Collider) && !(val is Renderer) && !(val is Transform) && !(val is ZNetView) && !(val is Rigidbody) && !(val is MeshFilter) && !(val is LODGroup) && !(val is PickableItem) && !(val is Canvas) && !(val is CanvasRenderer) && !(val is UIBehaviour) && !(val is WearNTear)) { Object.DestroyImmediate((Object)(object)val); } } Bounds val2 = default(Bounds); Renderer[] componentsInChildren2 = ghost.GetComponentsInChildren<Renderer>(); foreach (Renderer val3 in componentsInChildren2) { ((Bounds)(ref val2)).Encapsulate(val3.bounds); } BoxCollider obj = ghost.AddComponent<BoxCollider>(); obj.center = ((Bounds)(ref val2)).center; obj.size = ((Bounds)(ref val2)).size; } private static string GetPrefabFriendlyName(GameObject prefab) { HoverText component = prefab.GetComponent<HoverText>(); if (Object.op_Implicit((Object)(object)component)) { return component.m_text; } ItemDrop component2 = prefab.GetComponent<ItemDrop>(); if (Object.op_Implicit((Object)(object)component2)) { return component2.m_itemData.m_shared.m_name; } Character component3 = prefab.GetComponent<Character>(); if (Object.op_Implicit((Object)(object)component3)) { return component3.m_name; } RuneStone component4 = prefab.GetComponent<RuneStone>(); if (Object.op_Implicit((Object)(object)component4)) { return component4.m_name; } ItemStand component5 = prefab.GetComponent<ItemStand>(); if (Object.op_Implicit((Object)(object)component5)) { return component5.m_name; } MineRock component6 = prefab.GetComponent<MineRock>(); if (Object.op_Implicit((Object)(object)component6)) { return component6.m_name; } Pickable component7 = prefab.GetComponent<Pickable>(); if (Object.op_Implicit((Object)(object)component7)) { return GetPrefabFriendlyName(component7.m_itemPrefab); } CreatureSpawner component8 = prefab.GetComponent<CreatureSpawner>(); if (Object.op_Implicit((Object)(object)component8)) { return GetPrefabFriendlyName(component8.m_creaturePrefab); } SpawnArea component9 = prefab.GetComponent<SpawnArea>(); if (Object.op_Implicit((Object)(object)component9) && component9.m_prefabs.Count > 0) { return GetPrefabFriendlyName(component9.m_prefabs[0].m_prefab); } Piece component10 = prefab.GetComponent<Piece>(); if (Object.op_Implicit((Object)(object)component10) && !string.IsNullOrEmpty(component10.m_name)) { return component10.m_name; } return ((Object)prefab).name; } private static bool EnsureNoDuplicateZNetView(GameObject prefab) { ZNetView[] components = prefab.GetComponents<ZNetView>(); for (int i = 1; i < components.Length; i++) { Object.DestroyImmediate((Object)(object)components[i]); } return components.Length <= 1; } private static void CreatePrefabPiece(GameObject prefab) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown if (EnsureNoDuplicateZNetView(prefab)) { InitPieceData(prefab); PieceConfig val = new PieceConfig { Name = ((Object)prefab).name, Description = GetPrefabFriendlyName(prefab), PieceTable = "_HammerPieceTable", Category = GetPrefabCategory(prefab), AllowedInDungeons = true, Icon = CreatePrefabIcon(prefab) }; CustomPiece val2 = new CustomPiece(prefab, true, val); PieceManager.Instance.AddPiece(val2); AddedPrefabs.Add(((Object)prefab).name); } } private static void OnVanillaLocationsAvailable() { } public static void FindAndRegisterPrefabs() { (from go in ZNetScene.instance.m_prefabs where (Object)(object)go.transform.parent == (Object)null && !ShouldIgnorePrefab(go) orderby ((Object)go).name select go).ToList().ForEach(CreatePrefabPiece); ZoneManager.OnVanillaLocationsAvailable += OnVanillaLocationsAvailable; } } [BepInPlugin("com.heinermann.bettercreative", "BetterCreative", "1.5.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal class BetterCreative : BaseUnityPlugin { public const string PluginGUID = "com.heinermann.bettercreative"; public const string PluginName = "BetterCreative"; public const string PluginVersion = "1.5.0"; private readonly Harmony harmony = new Harmony("com.heinermann.bettercreative"); public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization(); private void Awake() { Game.isModded = true; Configs.Init(((BaseUnityPlugin)this).Config); Console.SetConsoleEnabled(true); PieceManager.Instance.GetPieceTables(); harmony.PatchAll(); } public static void ShowHUDMessage(string msg) { Logger.LogInfo((object)msg); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, msg, 0, (Sprite)null); } } private void KeyDeletePressed() { GameObject selectedPrefab = Patches.GetSelectedPrefab(Player.m_localPlayer); if ((Object)(object)selectedPrefab == (Object)null) { return; } GameObject ghost = Patches.lastPlacementGhost; if (!((Object)(object)ghost == (Object)null)) { string matchPattern = "^" + Regex.Escape(((Object)selectedPrefab).name) + "(\\(Clone\\))?$"; float sqrRadius = Configs.DeleteRange.Value * Configs.DeleteRange.Value; List<GameObject> list = (from inst in AccessTools.FieldRefAccess<ZNetScene, Dictionary<ZDO, ZNetView>>(ZNetScene.instance, "m_instances").Values.Where((ZNetView inst) => Regex.IsMatch(((Object)inst).name, matchPattern)).Where(delegate(ZNetView inst) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)inst).transform.position - ghost.transform.position; return ((Vector3)(ref val)).sqrMagnitude <= sqrRadius; }) select ((Component)inst).gameObject).ToList(); UndoHelper.Remove((IEnumerable<GameObject>)list); list.ForEach((Action<GameObject>)ZNetScene.instance.Destroy); ShowHUDMessage($"Deleted {list.Count} Objects"); } } private bool InLoadingScreen() { if (!((Object)(object)Player.m_localPlayer == (Object)null)) { return ((Character)Player.m_localPlayer).IsTeleporting(); } return true; } private void Update() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ZNetScene.instance) || InLoadingScreen()) { return; } KeyboardShortcut value = Configs.KeyUndo1.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { value = Configs.KeyUndo2.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { value = Configs.KeyRedo1.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { value = Configs.KeyRedo2.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { value = Configs.KeyDelete1.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { value = Configs.KeyDelete2.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { return; } } KeyDeletePressed(); return; } } UndoHelper.Redo(); return; } } UndoHelper.Undo(); } public static GameObject PlacePiece(GameObject prefab, Vector3 position, Quaternion rotation) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) TerrainModifier.SetTriggerOnPlaced(true); GameObject obj = Object.Instantiate<GameObject>(prefab, position, rotation); TerrainModifier.SetTriggerOnPlaced(false); CraftingStation componentInChildren = obj.GetComponentInChildren<CraftingStation>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { Player.m_localPlayer.AddKnownStation(componentInChildren); } Piece component = obj.GetComponent<Piece>(); if (component != null) { component.SetCreator(Player.m_localPlayer.GetPlayerID()); } PrivateArea component2 = obj.GetComponent<PrivateArea>(); if (component2 != null) { component2.Setup(Game.instance.GetPlayerProfile().GetName()); } WearNTear component3 = obj.GetComponent<WearNTear>(); if (component3 != null) { component3.OnPlaced(); return obj; } return obj; } public static void ModifyItems() { if (!Configs.NoDurabilityDrain.Value) { return; } foreach (GameObject item in ObjectDB.instance.m_items) { ItemDrop component = item.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { component.m_itemData.m_shared.m_useDurabilityDrain = 0f; } } } } internal static class UndoHelper { public static void Remove(IEnumerable<GameObject> objects) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown List<GameObject> list = objects.ToList(); List<ZDO> list2 = (from zdo in list.Select(delegate(GameObject obj) { ZNetView component = obj.GetComponent<ZNetView>(); return (component == null) ? null : component.GetZDO(); }) where zdo != null select zdo).ToList(); if (list2.Any()) { Logger.LogInfo((object)$"Removing {list2.Count} objects"); UndoRemove val = new UndoRemove((IEnumerable<ZDO>)list2); UndoManager.Instance.Add("BetterCreative", (IUndoAction)(object)val); } else if (list.Any()) { Logger.LogWarning((object)$"No ZDOs associated with {list.Count} deleted objects"); } } public static void Remove(GameObject obj) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown ZNetView component = obj.GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val != null) { Logger.LogInfo((object)("Removing " + ((Object)obj).name)); UndoRemove val2 = new UndoRemove((IEnumerable<ZDO>)(object)new ZDO[1] { val }); UndoManager.Instance.Add("BetterCreative", (IUndoAction)(object)val2); } else { Logger.LogWarning((object)("No ZDO associated with " + ((Object)obj).name)); } } public static void Create(IEnumerable<GameObject> objects) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown List<GameObject> list = objects.ToList(); List<ZDO> list2 = (from zdo in list.Select(delegate(GameObject obj) { ZNetView component = obj.GetComponent<ZNetView>(); return (component == null) ? null : component.GetZDO(); }) where zdo != null select zdo).ToList(); if (list2.Any()) { Logger.LogInfo((object)$"Creating {list2.Count} objects"); UndoCreate val = new UndoCreate((IEnumerable<ZDO>)list2); UndoManager.Instance.Add("BetterCreative", (IUndoAction)(object)val); } else if (list.Any()) { Logger.LogWarning((object)$"No ZDOs associated with {list.Count} created objects"); } } public static void Create(GameObject obj) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown ZNetView component = obj.GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val != null) { Logger.LogInfo((object)("Creating " + ((Object)obj).name)); UndoCreate val2 = new UndoCreate((IEnumerable<ZDO>)(object)new ZDO[1] { val }); UndoManager.Instance.Add("BetterCreative", (IUndoAction)(object)val2); } else { Logger.LogWarning((object)("No ZDO associated with " + ((Object)obj).name)); } } public static void Undo() { UndoManager.Instance.Undo("BetterCreative"); } public static void Redo() { UndoManager.Instance.Redo("BetterCreative"); } } }