using 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");
}
}
}