Please disclose if any significant portion of your mod was created 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 RcinelLevel v0.1.0
plugins/RcinelLevel.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("RcinelLevel")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+1b2a1c8b0a146554782021c339da76413b01997d")] [assembly: AssemblyProduct("RcinelLevel")] [assembly: AssemblyTitle("RcinelLevel")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Rcinel.Level { internal sealed class Controls : IDisposable { private const float MeasureInterval = 0.5f; private const float AimDistance = 60f; private const string StoneName = "$item_stone"; private static readonly int GroundMask = LayerMask.GetMask(new string[1] { "terrain" }); private static readonly int AnythingMask = LayerMask.GetMask(new string[6] { "terrain", "piece", "piece_nonsolid", "static_solid", "Default", "Default_small" }); private readonly Settings _settings; private readonly ManualLogSource _logger; private readonly Frame _frame = new Frame(); private readonly FrameView _view = new FrameView(); private readonly Readout _readout = new Readout(); private readonly ReachOverlay _overlay; private Measurement? _measurement; private int _measuredRevision = -1; private float _measuredAt; private (float Fill, int Stone)? _nextStroke; private float _plannedAt; private Player? _player; private ZNet? _session; private int _savedRevision = -1; public static Controls? Current { get; private set; } public Frame Frame => _frame; public float? LockedDepth { get { if (!_frame.Pinned || !_frame.DepthLocked) { return null; } return Target; } } private float? Target => _frame.ManualHeight ?? _frame.PinnedBalance ?? _measurement?.Balance; private string TargetSource { get { if (!_frame.ManualHeight.HasValue) { if (!_frame.PinnedBalance.HasValue) { return "probe"; } return "probe, at pinning"; } return "by hand"; } } public Controls(Settings settings, ManualLogSource logger) { _settings = settings; _logger = logger; _overlay = new ReachOverlay(logger); Current = this; settings.Reloaded += ToolHints.Invalidate; } public void Update() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Invalid comparison between Unknown and I4 //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) ScrollPatch.Suppress = false; ToolHints.Current = null; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { Hide(); return; } KeepFrame(localPlayer); bool flag = Items.IsProbe(((Humanoid)localPlayer).GetLeftItem()); bool flag2 = Items.IsLevelHoe(((Humanoid)localPlayer).GetRightItem()); int num; if (LockedDepth.HasValue) { ItemData rightItem = ((Humanoid)localPlayer).GetRightItem(); num = ((rightItem != null && (int)rightItem.m_shared.m_skillType == 12) ? 1 : 0); } else { num = 0; } bool flag3 = (byte)num != 0; if (!flag && !flag2 && !flag3) { Hide(); return; } _frame.Limit(_settings.MaxRadius.Value); MoatSizes.Depth = _settings.MoatDepth.Value; if (TakesInput() && (flag || flag2)) { HandleInput(flag); } if (flag && !_frame.Pinned) { Vector3? val = Aim(GroundMask); if (val.HasValue) { Vector3 valueOrDefault = val.GetValueOrDefault(); _frame.MoveTo(valueOrDefault); } } if (_frame.Revision != _measuredRevision || Time.time - _measuredAt > 0.5f) { Measure(); } if (!_frame.Placed) { _view.Hide(); _readout.Show("Hold the ground probe and aim at the ground to frame an area."); return; } (int, int, int, int)? brush = (flag2 ? Brush(localPlayer) : (((int, int, int, int)?)null)); if (brush.HasValue) { (int, int, int, int) valueOrDefault2 = brush.GetValueOrDefault(); float? target = Target; if (target.HasValue) { float valueOrDefault3 = target.GetValueOrDefault(); if (Time.time - _plannedAt > 0.25f) { (List<(int, int, int, float)>, float, int, List<(int, int, float)>) tuple = Stroke.Plan(_frame, valueOrDefault2, valueOrDefault3, _settings.StoneCost.Value, _settings.FreeDepth.Value, DevModes.Dig); _nextStroke = (tuple.Item2, tuple.Item3); _plannedAt = Time.time; } } } _view.Show(_frame, Target, brush); if (flag) { Measurement? measurement = _measurement; if (measurement.HasValue) { Measurement valueOrDefault4 = measurement.GetValueOrDefault(); _overlay.Show(valueOrDefault4); goto IL_0265; } } _overlay.Hide(); goto IL_0265; IL_0265: _readout.Show(Describe(flag, flag2, flag3, localPlayer)); ToolHints.Current = ((flag || flag2) ? Hints(flag, flag2) : null); } private void KeepFrame(Player player) { World world = ZNet.World; if (world == null) { return; } if (ZNet.instance != _session) { _session = ZNet.instance; DevModes.Reset(); } string key = $"RcinelLevel.Frame.{world.m_uid}"; if (player != _player) { _player = player; if (player.m_customData.TryGetValue(key, out var value) && !_frame.Load(value)) { _logger.LogWarning((object)("The saved frame for this world couldn't be read and was dropped: " + value)); } _savedRevision = _frame.Revision; } else if (_frame.Placed && _frame.Revision != _savedRevision) { player.m_customData[key] = _frame.Save(); _savedRevision = _frame.Revision; } } private List<(string[] Keys, string Label)> Hints(bool probe, bool hoe) { //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) List<(string[], string)> list = new List<(string[], string)>(); if (hoe) { list.Add((new string[1] { ZInput.instance.GetBoundKeyString("Attack", false) }, "Fill")); } if (probe) { list.Add((new string[1] { KeyName(_settings.CycleShape.Value) }, "Shape")); list.Add((new string[1] { KeyName(_settings.PinFrame.Value) }, _frame.Pinned ? "Unpin" : "Pin")); list.Add((new string[1] { KeyName(_settings.LockDepth.Value) }, _frame.DepthLocked ? "Unlock pickaxe" : "Lock pickaxe")); List<(string[], string)> list2 = list; string[] item = new string[1] { KeyName(_settings.CycleMoat.Value) }; list2.Add((item, "Moat: " + MoatName(_frame.Moat switch { MoatKind.None => MoatKind.Rustic, MoatKind.Rustic => MoatKind.Drawbridge, _ => MoatKind.None, }))); } list.Add((new string[2] { KeyName(_settings.ResizeModifier.Value), "Wheel" }, "Size")); list.Add((new string[2] { KeyName(_settings.HeightModifier.Value), "Wheel" }, "Height")); list.Add((new string[1] { KeyName(_settings.PickHeight.Value) }, "Take height")); list.Add((new string[1] { KeyName(_settings.ResetHeight.Value) }, "Probe height")); return list; } private static string MoatName(MoatKind kind) { return kind switch { MoatKind.Rustic => Localization.instance.Localize("$piece_drawbridge_log"), MoatKind.Drawbridge => Localization.instance.Localize("$piece_drawbridge"), _ => "none", }; } private unsafe static string KeyName(KeyCode key) { string text = ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); if (text.StartsWith("Alpha", StringComparison.Ordinal) && text.Length == 6) { return text.Substring(5); } StringBuilder stringBuilder = new StringBuilder(); string text2 = text; foreach (char c in text2) { if (char.IsUpper(c) && stringBuilder.Length > 0) { stringBuilder.Append(' '); } stringBuilder.Append(c); } return stringBuilder.ToString(); } public void LevelAt(Vector3 point) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (!_frame.Placed) { ((Character)localPlayer).Message((MessageType)2, "Frame an area with the ground probe first.", 0, (Sprite)null, false); return; } if (!_frame.Pinned) { Measure(); _frame.SetPinned(pinned: true, _measurement?.Balance); ((Character)localPlayer).Message((MessageType)1, "Frame pinned", 0, (Sprite)null, false); } float? target = Target; if (target.HasValue) { float valueOrDefault = target.GetValueOrDefault(); (int, int, int, int) tuple = BrushBounds(point); if (!Reachable(Mathf.RoundToInt(point.x), Mathf.RoundToInt(point.z)) && TerrainTiles.Cover(tuple, Reachable).Count == 0) { ((Character)localPlayer).Message((MessageType)2, "Aim inside the frame.", 0, (Sprite)null, false); return; } var (list, num, num2, list2) = Stroke.Plan(_frame, tuple, valueOrDefault, _settings.StoneCost.Value, _settings.FreeDepth.Value, DevModes.Dig); if (list.Count == 0 && list2.Count == 0) { if (!DevModes.Dig && HighestUnder(tuple) > valueOrDefault + 0.25f) { ((Character)localPlayer).Message((MessageType)2, "Nothing here lies below the target. Dig with the pickaxe.", 0, (Sprite)null, false); } return; } if (num2 > 0 && !localPlayer.NoCostCheat() && !DevModes.NoStone) { Inventory inventory = ((Humanoid)localPlayer).GetInventory(); int num3 = inventory.CountItems("$item_stone", -1, true); if (num3 < num2) { ((Character)localPlayer).Message((MessageType)2, $"This needs {num2} stone, you have {num3}.", 0, (Sprite)null, false); return; } inventory.RemoveItem("$item_stone", num2, -1, true); } ((MonoBehaviour)RcinelLevelPlugin.Instance).StartCoroutine(TerrainTiles.Level(list, _settings.OpsPerFrame.Value, list2)); _plannedAt = 0f; _logger.LogDebug((object)$"Filling {num:0.0} m³ around ({Mathf.RoundToInt(point.x)}, {Mathf.RoundToInt(point.z)}) to {valueOrDefault:0.00} m for {num2} stone with {list.Count} terrain edits."); } else { ((Character)localPlayer).Message((MessageType)2, "The ground under the frame isn't loaded yet.", 0, (Sprite)null, false); } bool Reachable(int x, int z) { if (!_frame.Contains(x, z)) { if (DevModes.Dig) { return _frame.InMoat(x, z); } return false; } return true; } } public void Dispose() { Hide(); if (Current == this) { Current = null; } } private void Measure() { _measurement = (_frame.Placed ? Probe.Measure(_frame, Target) : ((Measurement?)null)); _measuredRevision = _frame.Revision; _measuredAt = Time.time; } private void HandleInput(bool probe) { //IL_000b: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) bool flag = Keys.Held(_settings.ResizeModifier.Value); bool flag2 = Keys.Held(_settings.HeightModifier.Value); ScrollPatch.Suppress = flag || flag2; if (probe && Keys.Pressed(_settings.CycleShape.Value)) { _frame.CycleShape(); } if (probe && Keys.Pressed(_settings.LockDepth.Value)) { if (!_frame.Pinned && _frame.Placed) { Measure(); _frame.SetPinned(pinned: true, _measurement?.Balance); } _frame.SetDepthLocked(!_frame.DepthLocked); } if (probe && Keys.Pressed(_settings.CycleMoat.Value)) { _frame.CycleMoat(); } if (probe && Keys.Pressed(_settings.PinFrame.Value)) { if (_frame.Pinned) { _frame.SetPinned(pinned: false, null); } else { Vector3? val = Aim(GroundMask); if (val.HasValue) { Vector3 valueOrDefault = val.GetValueOrDefault(); _frame.MoveTo(valueOrDefault); Measure(); _frame.SetPinned(pinned: true, _measurement?.Balance); } } } float num = (ScrollPatch.Suppress ? ScrollPatch.Read() : 0f); if (num != 0f) { int num2 = ((num > 0f) ? 1 : (-1)); if (flag) { _frame.Resize(num2, Facing(), _settings.MaxRadius.Value); } else { float? target = Target; if (target.HasValue) { float valueOrDefault2 = target.GetValueOrDefault(); _frame.SetManualHeight(valueOrDefault2 + (float)num2 * _settings.HeightStep.Value); } } } if (Keys.Pressed(_settings.PickHeight.Value)) { Vector3? val = Aim(AnythingMask); if (val.HasValue) { Vector3 valueOrDefault3 = val.GetValueOrDefault(); _frame.SetManualHeight(valueOrDefault3.y); } } if (Keys.Pressed(_settings.ResetHeight.Value)) { _frame.SetManualHeight(null); Measure(); _frame.Remeasured(_measurement?.Balance); } } private (int MinX, int MinZ, int MaxX, int MaxZ)? Brush(Player player) { //IL_0045: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) GameObject placementGhost = player.m_placementGhost; if ((Object)(object)placementGhost != (Object)null && placementGhost.activeSelf) { return BrushBounds(placementGhost.transform.position); } Vector3? val = Aim(GroundMask); if (val.HasValue) { Vector3 valueOrDefault = val.GetValueOrDefault(); return BrushBounds(valueOrDefault); } return null; } private float HighestUnder((int MinX, int MinZ, int MaxX, int MaxZ) brush) { float num = float.MinValue; for (int i = brush.MinZ; i <= brush.MaxZ; i++) { var (j, _, _, _) = brush; for (; j <= brush.MaxX; j++) { if (_frame.Contains(j, i)) { (float, float)? tuple2 = Probe.At(j, i); if (tuple2.HasValue) { num = Math.Max(num, tuple2.GetValueOrDefault().Item1); } } } } return num; } private (int MinX, int MinZ, int MaxX, int MaxZ) BrushBounds(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.RoundToInt(point.x); int num2 = Mathf.RoundToInt(point.z); int value = _settings.HoeBrush.Value; return (MinX: num - value, MinZ: num2 - value, MaxX: num + value, MaxZ: num2 + value); } private string Describe(bool probe, bool hoe, bool pickaxe, Player player) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(probe ? "Ground probe" : (hoe ? "Level hoe" : "Pickaxe")).Append(" · ").Append(_frame.Describe()) .Append(" · ") .Append(_frame.Pinned ? "pinned" : "follows your aim"); if (_frame.DepthLocked) { float? target = Target; if (target.HasValue) { float valueOrDefault = target.GetValueOrDefault(); stringBuilder.Append($" · pickaxe locked at {valueOrDefault:0.00} m"); } } if (_frame.Moat != MoatKind.None) { stringBuilder.Append($" · moat {_frame.MoatWidth} m ({MoatName(_frame.Moat)})"); } if (DevModes.NoStone || DevModes.Dig) { stringBuilder.Append(" · dev:").Append(DevModes.NoStone ? " no stone" : "").Append(DevModes.Dig ? " dig" : ""); } stringBuilder.AppendLine(); Measurement? measurement = _measurement; Measurement valueOrDefault2; if (measurement.HasValue) { valueOrDefault2 = measurement.GetValueOrDefault(); float? target = Target; if (target.HasValue) { float valueOrDefault3 = target.GetValueOrDefault(); stringBuilder.Append($"Target {valueOrDefault3:0.00} m ({TargetSource})").Append($" · dig {valueOrDefault2.Cut:0} m³ · fill {valueOrDefault2.Fill:0} m³"); if (_frame.Moat != MoatKind.None) { stringBuilder.AppendLine().Append($"Moat {_frame.MoatWidth} m wide, floor {valueOrDefault3 - MoatSizes.Depth:0.00} m ({MoatSizes.Depth:0.#} m deep): dig {valueOrDefault2.MoatDig:0} m³"); if (valueOrDefault2.MoatTooDeep > 0) { stringBuilder.Append($" · {valueOrDefault2.MoatTooDeep} m² can't be dug that deep (red)"); } } if (valueOrDefault2.OutOfReach > 0) { stringBuilder.AppendLine().Append($"Beyond the game's ±{8f:0} m limit (red on the ground):"); if (valueOrDefault2.TooLow > 0) { stringBuilder.Append($" {valueOrDefault2.TooLow} m² can't be raised that far"); } if (valueOrDefault2.TooHigh > 0) { stringBuilder.Append((valueOrDefault2.TooLow > 0) ? "," : string.Empty).Append($" {valueOrDefault2.TooHigh} m² can't be dug that deep"); } } if (hoe) { (float, int)? nextStroke = _nextStroke; if (nextStroke.HasValue) { (float, int) valueOrDefault4 = nextStroke.GetValueOrDefault(); int num = 2 * _settings.HoeBrush.Value + 1; int num2 = ((!DevModes.NoStone && !player.NoCostCheat()) ? valueOrDefault4.Item2 : 0); stringBuilder.AppendLine().Append($"Next stroke ({num} × {num} m): fill {valueOrDefault4.Item1:0.0} m³ for {num2} stone").Append(string.Format(" · you carry {0}", ((Humanoid)player).GetInventory().CountItems("$item_stone", -1, true))); goto IL_03d8; } } stringBuilder.AppendLine().Append($"Probe now: balance {valueOrDefault2.Balance:0.00} m · ground {valueOrDefault2.Lowest:0.0} to {valueOrDefault2.Highest:0.0} m"); goto IL_03d8; } } stringBuilder.Append("The ground under the frame isn't loaded yet."); goto IL_0424; IL_0424: return stringBuilder.ToString(); IL_03d8: if (valueOrDefault2.Loaded < valueOrDefault2.Expected) { stringBuilder.Append($" · only {100 * valueOrDefault2.Loaded / Math.Max(1, valueOrDefault2.Expected)}% of the frame is loaded, the rest is too far away"); } goto IL_0424; } private void Hide() { _view.Hide(); _overlay.Hide(); _readout.Hide(); } private static Vector3 Facing() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)GameCamera.instance != (Object)null)) { return Vector3.forward; } return ((Component)GameCamera.instance).transform.forward; } private static Vector3? Aim(int mask) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } RaycastHit val = default(RaycastHit); if (!Physics.Raycast(new Ray(((Component)instance).transform.position, ((Component)instance).transform.forward), ref val, 60f, mask)) { return null; } return ((RaycastHit)(ref val)).point; } private static bool TakesInput() { if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible() && !TextInput.IsVisible() && !Minimap.IsOpen() && !StoreGui.IsVisible()) { return !Hud.IsPieceSelectionVisible(); } return false; } } internal static class DevModes { public static bool NoStone { get; set; } public static bool Dig { get; set; } public static void Reset() { NoStone = (Dig = false); } public static void Register() { CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new NoStoneCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new DigCommand()); } internal static bool Next(bool now, string[] args) { if (args.Length == 0) { return !now; } bool result; switch (args[0]) { case "1": case "on": case "true": result = true; break; default: result = false; break; } return result; } } internal abstract class DevCommand : ConsoleCommand { public override bool IsCheat => true; public override List<string> CommandOptionList() { return new List<string>(2) { "on", "off" }; } public override void Run(string[] args, Terminal context) { bool flag = Apply(args); context.AddString(((ConsoleCommand)this).Name + ": " + (flag ? "on" : "off") + " until you leave the world."); } protected abstract bool Apply(string[] args); } internal sealed class NoStoneCommand : DevCommand { public override string Name => "rcinellevel_nostone"; public override string Help => "[on|off] The level hoe raises ground without taking stone, for this session."; protected override bool Apply(string[] args) { return DevModes.NoStone = DevModes.Next(DevModes.NoStone, args); } } internal sealed class DigCommand : DevCommand { public override string Name => "rcinellevel_dig"; public override string Help => "[on|off] The level hoe also lowers ground above the target, for this session."; protected override bool Apply(string[] args) { return DevModes.Dig = DevModes.Next(DevModes.Dig, args); } } internal enum FrameShape { Circle, Square, Rectangle } internal enum MoatKind { None, Rustic, Drawbridge } internal static class MoatSizes { public static int RusticWidth { get; set; } = 4; public static int DrawbridgeWidth { get; set; } = 8; public static float Depth { get; set; } = 3f; public static int Width(MoatKind kind) { return kind switch { MoatKind.Rustic => RusticWidth, MoatKind.Drawbridge => DrawbridgeWidth, _ => 0, }; } } internal sealed class Frame { private static readonly CultureInfo Inv = CultureInfo.InvariantCulture; public FrameShape Shape { get; private set; } = FrameShape.Square; public int CenterX { get; private set; } public int CenterZ { get; private set; } public int Radius { get; private set; } = 4; public int North { get; private set; } = 4; public int East { get; private set; } = 4; public int South { get; private set; } = 4; public int West { get; private set; } = 4; public bool Placed { get; private set; } public bool Pinned { get; private set; } public float? PinnedBalance { get; private set; } public bool DepthLocked { get; private set; } public MoatKind Moat { get; private set; } public int MoatWidth => MoatSizes.Width(Moat); public (int MinX, int MinZ, int MaxX, int MaxZ) OuterBounds { get { (int MinX, int MinZ, int MaxX, int MaxZ) bounds = Bounds; int item = bounds.MinX; int item2 = bounds.MinZ; int item3 = bounds.MaxX; int item4 = bounds.MaxZ; int moatWidth = MoatWidth; return (MinX: item - moatWidth, MinZ: item2 - moatWidth, MaxX: item3 + moatWidth, MaxZ: item4 + moatWidth); } } public float? ManualHeight { get; private set; } public int Revision { get; private set; } public (int MinX, int MinZ, int MaxX, int MaxZ) Bounds { get { if (Shape != FrameShape.Rectangle) { return (MinX: CenterX - Radius, MinZ: CenterZ - Radius, MaxX: CenterX + Radius, MaxZ: CenterZ + Radius); } return (MinX: CenterX - West, MinZ: CenterZ - South, MaxX: CenterX + East, MaxZ: CenterZ + North); } } public void CycleMoat() { Moat = Moat switch { MoatKind.None => MoatKind.Rustic, MoatKind.Rustic => MoatKind.Drawbridge, _ => MoatKind.None, }; Revision++; } public bool InMoat(int x, int z) { int moatWidth = MoatWidth; if (moatWidth == 0 || Contains(x, z)) { return false; } if (Shape == FrameShape.Circle) { float num = x - CenterX; float num2 = z - CenterZ; float num3 = (float)Radius + 0.5f + (float)moatWidth; return num * num + num2 * num2 <= num3 * num3; } var (num4, num5, num6, num7) = OuterBounds; if (x >= num4 && x <= num6 && z >= num5) { return z <= num7; } return false; } public void CycleShape() { Shape = Shape switch { FrameShape.Circle => FrameShape.Square, FrameShape.Square => FrameShape.Rectangle, _ => FrameShape.Circle, }; if (Shape == FrameShape.Rectangle) { int num = (West = Radius); int num2 = (South = num); int north = (East = num2); North = north; } Revision++; } public void MoveTo(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.RoundToInt(point.x); int num2 = Mathf.RoundToInt(point.z); if (!Placed || num != CenterX || num2 != CenterZ) { CenterX = num; CenterZ = num2; Placed = true; Revision++; } } public void SetPinned(bool pinned, float? balance) { Pinned = pinned; PinnedBalance = (pinned ? balance : ((float?)null)); DepthLocked &= pinned; Revision++; } public void SetDepthLocked(bool locked) { DepthLocked = locked && Pinned; Revision++; } public void Remeasured(float? balance) { if (Pinned) { PinnedBalance = balance; } Revision++; } public void Resize(int step, Vector3 facing, int maxRadius) { //IL_0023: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (Shape != FrameShape.Rectangle) { Radius = Mathf.Clamp(Radius + step, 1, maxRadius); } else if (Mathf.Abs(facing.x) > Mathf.Abs(facing.z)) { if (facing.x > 0f) { East = Mathf.Clamp(East + step, 0, 2 * maxRadius - West); } else { West = Mathf.Clamp(West + step, 0, 2 * maxRadius - East); } } else if (facing.z > 0f) { North = Mathf.Clamp(North + step, 0, 2 * maxRadius - South); } else { South = Mathf.Clamp(South + step, 0, 2 * maxRadius - North); } Revision++; } public void Limit(int maxRadius) { (int, int, int, int, int) valueTuple = (Radius, North, East, South, West); Radius = Mathf.Min(Radius, maxRadius); North = Mathf.Min(North, 2 * maxRadius); South = Mathf.Min(South, 2 * maxRadius - North); East = Mathf.Min(East, 2 * maxRadius); West = Mathf.Min(West, 2 * maxRadius - East); (int, int, int, int, int) tuple = valueTuple; int radius = Radius; int north = North; int east = East; int south = South; int west = West; if (tuple.Item1 != radius || tuple.Item2 != north || tuple.Item3 != east || tuple.Item4 != south || tuple.Item5 != west) { Revision++; } } public void SetManualHeight(float? height) { ManualHeight = height; Revision++; } public bool Contains(int x, int z) { var (num, num2, num3, num4) = Bounds; if (x < num || x > num3 || z < num2 || z > num4) { return false; } if (Shape != FrameShape.Circle) { return true; } float num5 = x - CenterX; float num6 = z - CenterZ; return num5 * num5 + num6 * num6 <= ((float)Radius + 0.5f) * ((float)Radius + 0.5f); } public IEnumerable<(int X, int Z)> Vertices() { (int, int, int, int) bounds = Bounds; int minX = bounds.Item1; int item = bounds.Item2; int maxX = bounds.Item3; int maxZ = bounds.Item4; for (int z = item; z <= maxZ; z++) { for (int x = minX; x <= maxX; x++) { if (Contains(x, z)) { yield return (X: x, Z: z); } } } } public string Save() { return string.Join(";", "2", ((int)Shape).ToString(Inv), CenterX.ToString(Inv), CenterZ.ToString(Inv), Radius.ToString(Inv), North.ToString(Inv), East.ToString(Inv), South.ToString(Inv), West.ToString(Inv), Pinned ? "1" : "0", PinnedBalance?.ToString("R", Inv) ?? "", ManualHeight?.ToString("R", Inv) ?? "", DepthLocked ? "1" : "0", ((int)Moat).ToString(Inv)); } public bool Load(string text) { string[] array = text.Split(new char[1] { ';' }); if ((array.Length != 13 || !(array[0] == "1")) && (array.Length != 14 || !(array[0] == "2"))) { return false; } try { FrameShape frameShape = (FrameShape)int.Parse(array[1], Inv); int num = int.Parse(array[2], Inv); int num2 = int.Parse(array[3], Inv); int num3 = int.Parse(array[4], Inv); int num4 = int.Parse(array[5], Inv); int num5 = int.Parse(array[6], Inv); int num6 = int.Parse(array[7], Inv); int num7 = int.Parse(array[8], Inv); float? num8 = ((array[10].Length > 0) ? new float?(float.Parse(array[10], Inv)) : ((float?)null)); float? manualHeight = ((array[11].Length > 0) ? new float?(float.Parse(array[11], Inv)) : ((float?)null)); FrameShape shape = frameShape; int centerX = num; int centerZ = num2; int radius = num3; int north = num4; int east = num5; int south = num6; int west = num7; Shape = shape; CenterX = centerX; CenterZ = centerZ; Radius = radius; North = north; East = east; South = south; West = west; Pinned = array[9] == "1"; PinnedBalance = (Pinned ? num8 : ((float?)null)); ManualHeight = manualHeight; DepthLocked = Pinned && array[12] == "1"; Moat = ((array.Length == 14) ? ((MoatKind)int.Parse(array[13], Inv)) : MoatKind.None); Placed = true; Revision++; return true; } catch (FormatException) { return false; } } public string Describe() { var (num, num2, num3, num4) = Bounds; return Shape switch { FrameShape.Circle => $"Circle Ø {2 * Radius + 1} m", FrameShape.Square => $"Square {2 * Radius + 1} × {2 * Radius + 1} m", _ => $"Rectangle {num3 - num + 1} (E–W) × {num4 - num2 + 1} (N–S) m", }; } } internal readonly record struct Measurement(float Balance, float Cut, float Fill, int TooLow, int TooHigh, int Loaded, int Expected, float Lowest, float Highest, int MinX, int MinZ, float[,] Heights, IReadOnlyList<(int X, int Z)> Unreachable, float MoatDig, int MoatTooDeep) { public int OutOfReach => TooLow + TooHigh; } internal static class Probe { public const float MaxChange = 8f; public static (float Height, float Generated)? At(int x, int z) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor((float)x, 0f, (float)z); float num = default(float); if (!Heightmap.GetHeight(val, ref num)) { return null; } TerrainComp val2 = TerrainComp.FindTerrainCompiler(val); if (val2 == null || val2.m_levelDelta == null || val2.m_hmap == null) { return (num, num); } int num2 = default(int); int num3 = default(int); val2.m_hmap.WorldToVertex(val, ref num2, ref num3); int num4 = val2.m_width + 1; if (num2 < 0 || num3 < 0 || num2 >= num4 || num3 >= num4) { return (num, num); } int num5 = num3 * num4 + num2; return (num, num - val2.m_levelDelta[num5] - val2.m_smoothDelta[num5]); } public static Measurement? Measure(Frame frame, float? target) { (int, int, int, int) outerBounds = frame.OuterBounds; int minX = outerBounds.Item1; int minZ = outerBounds.Item2; int maxX = outerBounds.Item3; int maxZ = outerBounds.Item4; int num = maxX - minX + 1; int num2 = maxZ - minZ + 1; int num3 = 0; for (int i = minZ; i <= maxZ; i++) { for (int j = minX; j <= maxX; j++) { if (frame.Contains(j, i) || frame.InMoat(j, i)) { num3++; } } } bool[,] seen = new bool[num, num2]; float[,] grid = new float[num, num2]; for (int k = 0; k < num2; k++) { for (int l = 0; l < num; l++) { grid[l, k] = float.NaN; } } List<(int X, int Z, float Height, float Generated)> heights = new List<(int, int, float, float)>(num3); List<(int X, int Z, float Height, float Generated)> moat = new List<(int, int, float, float)>(); foreach (Heightmap s_heightmap in Heightmap.s_heightmaps) { Read(s_heightmap); } if (heights.Count == 0) { return null; } double num4 = 0.0; float num5 = float.MaxValue; float num6 = float.MinValue; foreach (var item8 in heights) { float item = item8.Height; num4 += (double)item; num5 = Math.Min(num5, item); num6 = Math.Max(num6, item); } float num7 = (float)(num4 / (double)heights.Count); float num8 = target ?? num7; float num9 = 0f; float num10 = 0f; int num11 = 0; int num12 = 0; List<(int, int)> list = new List<(int, int)>(); foreach (var (item2, item3, num13, num14) in heights) { if (num13 > num8) { num9 += num13 - num8; } else { num10 += num8 - num13; } if (num8 - num14 > 8.01f) { num11++; list.Add((item2, item3)); } else if (num14 - num8 > 8.01f) { num12++; list.Add((item2, item3)); } } float num15 = 0f; int num16 = 0; float num17 = num8 - MoatSizes.Depth; foreach (var item9 in moat) { int item4 = item9.X; int item5 = item9.Z; float item6 = item9.Height; float item7 = item9.Generated; num15 += Math.Max(0f, item6 - Math.Max(num17, item7 - 8f)); if (item7 - num17 > 8.01f) { num16++; list.Add((item4, item5)); } } return new Measurement(num7, num9, num10, num11, num12, heights.Count + moat.Count, num3, num5, num6, minX, minZ, grid, list, num15, num16); void Read(Heightmap heightmap) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)heightmap == (Object)null) && heightmap.m_heights.Count != 0 && Mathf.Approximately(heightmap.m_scale, 1f)) { Vector3 position = ((Component)heightmap).transform.position; int num18 = heightmap.m_width + 1; int num19 = heightmap.m_width / 2; int num20 = Mathf.RoundToInt(position.x) - num19; int num21 = Mathf.RoundToInt(position.z) - num19; int num22 = Math.Max(0, minX - num20); int num23 = Math.Min(num18 - 1, maxX - num20); int num24 = Math.Max(0, minZ - num21); int num25 = Math.Min(num18 - 1, maxZ - num21); if (num22 <= num23 && num24 <= num25) { TerrainComp val = TerrainComp.FindTerrainCompiler(position); if ((Object)(object)val != (Object)null && ((Object)(object)val.m_hmap != (Object)(object)heightmap || val.m_levelDelta == null)) { val = null; } for (int m = num24; m <= num25; m++) { for (int n = num22; n <= num23; n++) { int num26 = num20 + n; int num27 = num21 + m; if (!seen[num26 - minX, num27 - minZ]) { bool flag = frame.Contains(num26, num27); if (flag || frame.InMoat(num26, num27)) { seen[num26 - minX, num27 - minZ] = true; int num28 = m * num18 + n; float num29 = heightmap.m_heights[num28] + position.y; float num30 = ((val == null) ? 0f : (val.m_levelDelta[num28] + val.m_smoothDelta[num28])); (flag ? heights : moat).Add((num26, num27, num29, num29 - num30)); grid[num26 - minX, num27 - minZ] = num29; } } } } } } } } } internal sealed class FrameView { private const float Spacing = 1f; private const int MaxSegments = 400; private static readonly Color TargetTint = new Color(0.45f, 0.85f, 1f, 1f); private static readonly Color BrushTint = new Color(1f, 0.55f, 0.2f, 1f); private static readonly Color MoatTint = new Color(0.25f, 0.45f, 1f, 1f); private readonly List<GameObject> _ground = new List<GameObject>(); private readonly List<GameObject> _target = new List<GameObject>(); private readonly List<GameObject> _brush = new List<GameObject>(); private readonly List<GameObject> _moat = new List<GameObject>(); private readonly List<(Vector3 Point, Vector3 Tangent)> _outline = new List<(Vector3, Vector3)>(); private GameObject? _root; private int _drawnRevision = -1; private float _drawnAt; private float? _drawnTarget; private (int, int, int, int)? _drawnBrush; private static readonly int GroundMask = LayerMask.GetMask(new string[1] { "terrain" }); public void Show(Frame frame, float? target, (int MinX, int MinZ, int MaxX, int MaxZ)? brush) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null) { _root = new GameObject("RcinelLevel frame"); _ground.Clear(); _target.Clear(); _brush.Clear(); _moat.Clear(); _drawnRevision = -1; } _root.SetActive(true); if (frame.Revision == _drawnRevision && Nullable.Equals(target, _drawnTarget) && Time.time - _drawnAt < 0.5f) { if (!Nullable.Equals<(int, int, int, int)>(brush, _drawnBrush)) { DrawBrush(frame, target, brush); } return; } _drawnRevision = frame.Revision; _drawnTarget = target; _drawnAt = Time.time; Outline(frame); RaycastHit val = default(RaycastHit); Draw(_ground, null, (Vector3 point) => (!Physics.Raycast(point + Vector3.up * 500f, Vector3.down, ref val, 1000f, GroundMask)) ? ((float?)null) : new float?(((RaycastHit)(ref val)).point.y)); Draw(_target, TargetTint, (Vector3 _) => target); DrawMoat(frame); DrawBrush(frame, target, brush); } private void DrawMoat(Frame frame) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) _outline.Clear(); if (frame.Moat != MoatKind.None) { if (frame.Shape == FrameShape.Circle) { Circle(frame.CenterX, frame.CenterZ, (float)frame.Radius + 0.5f + (float)frame.MoatWidth); } else { Rectangle(frame.OuterBounds); } } RaycastHit val = default(RaycastHit); Draw(_moat, MoatTint, (Vector3 point) => (!Physics.Raycast(point + Vector3.up * 500f, Vector3.down, ref val, 1000f, GroundMask)) ? ((float?)null) : new float?(((RaycastHit)(ref val)).point.y)); } private void DrawBrush(Frame frame, float? target, (int MinX, int MinZ, int MaxX, int MaxZ)? brush) { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) _drawnBrush = brush; _outline.Clear(); if (brush.HasValue) { (int, int, int, int) valueOrDefault = brush.GetValueOrDefault(); if (target.HasValue) { (int MinX, int MinZ, int MaxX, int MaxZ) bounds = frame.Bounds; int item = bounds.MinX; int item2 = bounds.MinZ; int item3 = bounds.MaxX; int item4 = bounds.MaxZ; (int, int, int, int) bounds2 = (Math.Max(valueOrDefault.Item1, item), Math.Max(valueOrDefault.Item2, item2), Math.Min(valueOrDefault.Item3, item3), Math.Min(valueOrDefault.Item4, item4)); if (bounds2.Item1 <= bounds2.Item3 && bounds2.Item2 <= bounds2.Item4) { Rectangle(bounds2); } } } Draw(_brush, BrushTint, (Vector3 _) => target); } public void Hide() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } private void Outline(Frame frame) { _outline.Clear(); if (frame.Shape == FrameShape.Circle) { Circle(frame.CenterX, frame.CenterZ, (float)frame.Radius + 0.5f); } else { Rectangle(frame.Bounds); } } private void Circle(int centerX, int centerZ, float radius) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp(Mathf.CeilToInt((float)Math.PI * 2f * radius / 1f), 8, 400); Vector3 item = default(Vector3); for (int i = 0; i < num; i++) { float num2 = (float)Math.PI * 2f * (float)i / (float)num; ((Vector3)(ref item))..ctor((float)centerX + Mathf.Sin(num2) * radius, 0f, (float)centerZ + Mathf.Cos(num2) * radius); _outline.Add((item, new Vector3(Mathf.Cos(num2), 0f, 0f - Mathf.Sin(num2)))); } } private void Rectangle((int MinX, int MinZ, int MaxX, int MaxZ) bounds) { //IL_007c: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) (int MinX, int MinZ, int MaxX, int MaxZ) tuple = bounds; int item = tuple.MinX; int item2 = tuple.MinZ; int item3 = tuple.MaxX; int item4 = tuple.MaxZ; float num = (float)item - 0.5f; float num2 = (float)item3 + 0.5f; float num3 = (float)item2 - 0.5f; float num4 = (float)item4 + 0.5f; float spacing = Mathf.Max(1f, 2f * (num2 - num + num4 - num3) / 400f); Edge(new Vector3(num, 0f, num3), new Vector3(num2, 0f, num3)); Edge(new Vector3(num2, 0f, num3), new Vector3(num2, 0f, num4)); Edge(new Vector3(num2, 0f, num4), new Vector3(num, 0f, num4)); Edge(new Vector3(num, 0f, num4), new Vector3(num, 0f, num3)); void Edge(Vector3 from, Vector3 to) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) float num5 = Vector3.Distance(from, to); int num6 = Mathf.Max(1, Mathf.RoundToInt(num5 / spacing)); Vector3 val = to - from; Vector3 normalized = ((Vector3)(ref val)).normalized; for (int i = 0; i < num6; i++) { _outline.Add((Vector3.Lerp(from, to, ((float)i + 0.5f) / (float)num6), normalized)); } } } private void Draw(List<GameObject> pool, Color? tint, Func<Vector3, float?> height) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) while (pool.Count < _outline.Count) { pool.Add(MakeSegment(tint)); } for (int i = 0; i < pool.Count; i++) { GameObject val = pool[i]; if (i < _outline.Count) { float? num = height(_outline[i].Point); if (num.HasValue) { float valueOrDefault = num.GetValueOrDefault(); var (val2, val3) = _outline[i]; val.SetActive(true); val.transform.SetPositionAndRotation(new Vector3(val2.x, valueOrDefault, val2.z), Quaternion.LookRotation(val3, Vector3.up)); continue; } } val.SetActive(false); } } private GameObject MakeSegment(Color? tint) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) GameObject val; if ((Object)(object)Items.SegmentPrefab != (Object)null) { val = Object.Instantiate<GameObject>(Items.SegmentPrefab, _root.transform); } else { val = GameObject.CreatePrimitive((PrimitiveType)3); Object.Destroy((Object)(object)val.GetComponent<Collider>()); val.transform.SetParent(_root.transform, false); val.transform.localScale = new Vector3(0.05f, 0.05f, 0.6f); } if (tint.HasValue) { Color valueOrDefault = tint.GetValueOrDefault(); Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material material = componentsInChildren[i].material; if (material.HasProperty("_Color")) { material.color = valueOrDefault; } if (material.HasProperty("_EmissionColor")) { material.SetColor("_EmissionColor", valueOrDefault); } } } return val; } } internal sealed class Readout { private static readonly Color Orange = new Color(1f, 0.63f, 0.24f, 1f); private Text? _text; public void Show(string text) { if (!((Object)(object)_text == (Object)null) || Create()) { ((Component)_text).gameObject.SetActive(true); _text.text = text; } } public void Hide() { if ((Object)(object)_text != (Object)null) { ((Component)_text).gameObject.SetActive(false); } } private bool Create() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0060: Unknown result type (might be due to invalid IL or missing references) GameObject customGUIFront = GUIManager.CustomGUIFront; if ((Object)(object)customGUIFront == (Object)null) { return false; } GameObject val = GUIManager.Instance.CreateText(string.Empty, customGUIFront.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -120f), GUIManager.Instance.AveriaSerifBold, 18, Orange, true, Color.black, 1100f, 140f, false); _text = val.GetComponent<Text>(); _text.alignment = (TextAnchor)1; _text.supportRichText = true; ((Graphic)_text).raycastTarget = false; return true; } } internal static class Items { public const string ProbePrefab = "RcinelLevel_Probe"; public const string HoePrefab = "RcinelLevel_LevelHoe"; public const string PiecePrefab = "RcinelLevel_Level"; public const string PieceTableName = "_RcinelLevelHoePieceTable"; public const string ModelName = "rcinellevel_model"; private static PluginFiles _files; private static Settings _settings; private static ManualLogSource _logger; private static Mesh? _probeMesh; private static Mesh? _hoeMesh; private static Texture2D? _atlas; private static Sprite? _probeIcon; private static Sprite? _hoeIcon; public static GameObject? SegmentPrefab { get; private set; } public static void Prepare(PluginFiles files, Settings settings, ManualLogSource logger) { _files = files; _settings = settings; _logger = logger; _probeMesh = files.LoadMesh("probe.obj"); _hoeMesh = files.LoadMesh("level-hoe.obj"); _atlas = files.LoadTexture("models", "atlas.png"); _probeIcon = files.LoadSprite("probe-128.png"); _hoeIcon = files.LoadSprite("level-hoe-128.png"); settings.Reloaded += ApplyModelPlacement; } public static bool IsProbe(ItemData? item) { return item?.m_shared.m_name == "$item_rcinellevel_probe"; } public static bool IsLevelHoe(ItemData? item) { return item?.m_shared.m_name == "$item_rcinellevel_levelhoe"; } public static void Create() { PrefabManager.OnVanillaPrefabsAvailable -= Create; try { Material[]? material = MakeMaterials(); CreateTiles(); MeasureStoneCost(); MeasureDrawbridges(); CreateProbe(material); CreatePieceTableAndPiece(); CreateHoe(material); GameObject prefab = PrefabManager.Instance.GetPrefab("piece_workbench"); SegmentPrefab = ((prefab == null) ? null : prefab.GetComponentInChildren<CircleProjector>(true)?.m_prefab); if (SegmentPrefab == null) { _logger.LogWarning((object)"The workbench's range ring wasn't found, so the frame is drawn without it."); } } catch (Exception arg) { _logger.LogError((object)$"Creating RcinelLevel's items failed, the tools won't be available: {arg}"); } } private static Material[]? MakeMaterials() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = PrefabManager.Instance.GetPrefab("Hoe"); Transform obj = ((prefab != null) ? prefab.transform.Find("attach/visual") : null); object obj2; if (obj == null) { obj2 = null; } else { Transform obj3 = obj.Find("handle"); obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<MeshRenderer>() : null); } MeshRenderer val = (MeshRenderer)obj2; object obj4; if (obj == null) { obj4 = null; } else { Transform obj5 = obj.Find("blade"); obj4 = ((obj5 != null) ? ((Component)obj5).GetComponent<MeshRenderer>() : null); } MeshRenderer val2 = (MeshRenderer)obj4; if (val == null || val2 == null || _atlas == null) { _logger.LogWarning((object)"No materials for the models (game hoe or atlas missing); the game's own models stay."); return null; } Material val3 = new Material(((Renderer)val).sharedMaterial) { name = "rcinellevel_atlas", mainTexture = (Texture)(object)_atlas, mainTextureScale = Vector2.one, mainTextureOffset = Vector2.zero }; string[] array = new string[5] { "_BumpMap", "_MetallicGlossMap", "_EmissionMap", "_DetailAlbedoMap", "_DetailNormalMap" }; foreach (string text in array) { if (val3.HasProperty(text)) { val3.SetTexture(text, (Texture)null); } } if (val3.HasProperty("_Color")) { val3.color = Color.white; } return (Material[]?)(object)new Material[2] { val3, ((Renderer)val2).sharedMaterial }; } private static void CreateTiles() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Expected O, but got Unknown //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown GameObject prefab = PrefabManager.Instance.GetPrefab("mud_road_v2"); TerrainOp val = ((prefab != null) ? prefab.GetComponent<TerrainOp>() : null); if (val == null) { throw new InvalidOperationException("the game's level-ground piece (mud_road_v2) wasn't found"); } Settings settings = val.m_settings; _logger.LogInfo((object)$"Game's level ground: level {settings.m_level} r {settings.m_levelRadius} square {settings.m_square} offset {settings.m_levelOffset}, smooth {settings.m_smooth} r {settings.m_smoothRadius}, paint {settings.m_paintCleared} {settings.m_paintType} r {settings.m_paintRadius}"); int[] radii = TerrainTiles.Radii; foreach (int num in radii) { GameObject val2 = PrefabManager.Instance.CreateClonedPrefab(TerrainTiles.PrefabName(num), ((Component)val).gameObject); Object.DestroyImmediate((Object)(object)val2.GetComponent<Piece>()); foreach (Transform item in val2.transform) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } TerrainOp component = val2.GetComponent<TerrainOp>(); Settings settings2 = component.m_settings; settings2.m_level = true; settings2.m_levelRadius = num; settings2.m_square = true; settings2.m_levelOffset = 0f; settings2.m_raise = false; settings2.m_smooth = false; settings2.m_paintCleared = false; component.m_onPlacedEffect = new EffectList(); component.m_spawnOnPlaced = null; TerrainTiles.Prefabs[num] = component; } GameObject val3 = PrefabManager.Instance.CreateClonedPrefab("RcinelLevel_Paint", ((Component)val).gameObject); Object.DestroyImmediate((Object)(object)val3.GetComponent<Piece>()); foreach (Transform item2 in val3.transform) { Object.DestroyImmediate((Object)(object)((Component)item2).gameObject); } TerrainOp component2 = val3.GetComponent<TerrainOp>(); Settings settings3 = component2.m_settings; settings3.m_level = (settings3.m_raise = (settings3.m_smooth = false)); settings3.m_paintCleared = true; settings3.m_paintType = (PaintType)0; settings3.m_paintRadius = 1f; settings3.m_paintStrength = 1f; settings3.m_paintExp = 0.1f; settings3.m_paintCurve = null; settings3.m_paintHeightCheck = false; settings3.m_addMedianMax = 0f; settings3.m_centerMultiplicationFactor = 0f; settings3.m_pointMultiplicationFactor = 0f; settings3.m_rotation = (settings3.m_sides = false); component2.m_onPlacedEffect = new EffectList(); component2.m_spawnOnPlaced = null; TerrainTiles.Paint = component2; ObjectDB instance = ObjectDB.instance; if (instance != null) { instance.UpdateRegisters(); } } private static void MeasureStoneCost() { GameObject prefab = PrefabManager.Instance.GetPrefab("Hoe"); PieceTable val = ((prefab == null) ? null : prefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces); foreach (GameObject item in (val == null) ? new List<GameObject>() : val.m_pieces) { TerrainOp val2 = (((Object)(object)item == (Object)null) ? null : item.GetComponent<TerrainOp>()); if (val2 == null || !val2.m_settings.m_raise || val2.m_settings.m_raiseDelta <= 0f) { continue; } int num = 0; Requirement[] array = item.GetComponent<Piece>()?.m_resources ?? Array.Empty<Requirement>(); foreach (Requirement val3 in array) { if ((Object)(object)val3.m_resItem != (Object)null && ((Object)val3.m_resItem).name == "Stone") { num += val3.m_amount; } } Settings settings = val2.m_settings; int num2 = Mathf.CeilToInt(settings.m_raiseRadius); float num3 = 0f; for (int j = -num2; j <= num2; j++) { for (int k = -num2; k <= num2; k++) { float num4 = Mathf.Sqrt((float)(k * k + j * j)); if (settings.m_square || !(num4 > settings.m_raiseRadius)) { float num5 = ((settings.m_square || settings.m_raisePower <= 0f) ? 1f : Mathf.Pow(1f - num4 / settings.m_raiseRadius, settings.m_raisePower)); num3 += settings.m_raiseDelta * num5; } } } if (num > 0 && num3 > 0f) { Stroke.StonePerCubicMetre = (float)num / num3; _logger.LogInfo((object)$"The game's {((Object)item).name}: {num} stone for {num3:0.00} m³ (radius {settings.m_raiseRadius}, delta {settings.m_raiseDelta}, power {settings.m_raisePower}), so {Stroke.StonePerCubicMetre:0.00} stone per m³."); return; } } _logger.LogWarning((object)$"The game's Raise ground wasn't found; the level hoe charges {Stroke.StonePerCubicMetre} stone per m³."); } private static void MeasureDrawbridges() { MoatSizes.RusticWidth = Width("piece_drawbridge_log") ?? MoatSizes.RusticWidth; MoatSizes.DrawbridgeWidth = Width("piece_drawbridge") ?? MoatSizes.DrawbridgeWidth; _logger.LogInfo((object)$"Moat widths: {MoatSizes.RusticWidth} m for the Rustic Drawbridge, {MoatSizes.DrawbridgeWidth} m for the Drawbridge."); static int? Width(string name) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = PrefabManager.Instance.GetPrefab(name); Transform val = ((prefab != null) ? prefab.transform.Find("door") : null); object obj; if (val == null) { obj = null; } else { Transform obj2 = val.Find("collider"); obj = ((obj2 != null) ? ((Component)obj2).GetComponent<BoxCollider>() : null); } BoxCollider val2 = (BoxCollider)obj; if (val == null || val2 == null) { _logger.LogWarning((object)("The deck of " + name + " wasn't found; its moat width stays at the default.")); return null; } Transform transform = ((Component)val2).transform; float num = val.localPosition.x + transform.localPosition.x + transform.localScale.x * (val2.center.x + val2.size.x / 2f); if (!(num > 2.5f)) { return null; } return Mathf.FloorToInt(num - 1.5f); } } private static void CreateProbe(Material[]? material) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) ItemConfig val = new ItemConfig(); val.Name = "$item_rcinellevel_probe"; val.Description = "$item_rcinellevel_probe_description"; val.CraftingStation = CraftingStations.Workbench; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("Wood", 2, 0, true), new RequirementConfig("Flint", 2, 0, true), new RequirementConfig("Resin", 1, 0, true) }; val.Icons = (Sprite[])(object)((_probeIcon == null) ? null : new Sprite[1] { _probeIcon }); CustomItem val2 = new CustomItem("RcinelLevel_Probe", "Torch", val); Transform obj = val2.ItemPrefab.transform.Find("attach"); Transform val3 = ((obj != null) ? obj.Find("equiped") : null); if (val3 != null) { Object.DestroyImmediate((Object)(object)((Component)val3).gameObject); } ReplaceModel(obj, (obj != null) ? obj.Find("model") : null, _probeMesh, material, _settings.ProbePosition.Value, _settings.ProbeRotation.Value); SharedData shared = val2.ItemDrop.m_itemData.m_shared; shared.m_itemType = (ItemType)5; shared.m_animationState = (AnimationState)6; shared.m_attachOverride = (ItemType)0; shared.m_useDurability = false; shared.m_durabilityDrain = 0f; shared.m_damages = default(DamageTypes); shared.m_blockPower = 0f; shared.m_deflectionForce = 0f; shared.m_timedBlockBonus = 1f; shared.m_equipStatusEffect = null; shared.m_maxStackSize = 1; shared.m_weight = 1f; ItemManager.Instance.AddItem(val2); } private static void CreatePieceTableAndPiece() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown PieceManager.Instance.AddPieceTable(new CustomPieceTable("_RcinelLevelHoePieceTable", new PieceTableConfig { CanRemovePieces = false })); CustomPiece val = new CustomPiece("RcinelLevel_Level", "mud_road_v2", new PieceConfig { Name = "$piece_rcinellevel_level", Description = "$piece_rcinellevel_level_description", PieceTable = "_RcinelLevelHoePieceTable", Icon = _hoeIcon }); Object.DestroyImmediate((Object)(object)val.PiecePrefab.GetComponent<TerrainOp>()); val.PiecePrefab.AddComponent<LevelAction>(); val.Piece.m_canRotate = false; PieceManager.Instance.AddPiece(val); } private static void CreateHoe(Material[]? material) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) ItemConfig val = new ItemConfig(); val.Name = "$item_rcinellevel_levelhoe"; val.Description = "$item_rcinellevel_levelhoe_description"; val.CraftingStation = CraftingStations.Workbench; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("Hoe", 1, 0, false), new RequirementConfig("Flint", 4, 2, true), new RequirementConfig("LeatherScraps", 2, 1, true) }; val.Icons = (Sprite[])(object)((_hoeIcon == null) ? null : new Sprite[1] { _hoeIcon }); CustomItem val2 = new CustomItem("RcinelLevel_LevelHoe", "Hoe", val); Transform val3 = val2.ItemPrefab.transform.Find("attach/visual"); string[] array = new string[2] { "blade", "handle" }; foreach (string text in array) { if (val3 != null) { Transform obj = val3.Find(text); if (obj != null) { ((Component)obj).gameObject.SetActive(false); } } } ReplaceModel(val3, null, _hoeMesh, material, _settings.HoePosition.Value, _settings.HoeRotation.Value); PieceTable pieceTable = PieceManager.Instance.GetPieceTable("_RcinelLevelHoePieceTable"); SharedData shared = val2.ItemDrop.m_itemData.m_shared; shared.m_buildPieces = pieceTable; shared.m_maxQuality = 4; shared.m_durabilityPerLevel = 50f; ItemManager.Instance.AddItem(val2); } private static void ReplaceModel(Transform? parent, Transform? old, Mesh? mesh, Material[]? material, Vector3 position, Vector3 rotation) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (parent == null || mesh == null || material == null) { _logger.LogWarning((object)("Keeping the game's model under " + (((parent != null) ? ((Object)parent).name : null) ?? "(missing)") + ": no mesh or material.")); return; } if (old != null) { ((Component)old).gameObject.SetActive(false); } GameObject val = new GameObject("rcinellevel_model"); val.transform.SetParent(parent, false); val.transform.localPosition = position; val.transform.localEulerAngles = rotation; val.AddComponent<MeshFilter>().sharedMesh = mesh; ((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterials = material; } private static void ApplyModelPlacement() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) Place(PrefabManager.Instance.GetPrefab("RcinelLevel_Probe"), _settings.ProbePosition.Value, _settings.ProbeRotation.Value); Place(PrefabManager.Instance.GetPrefab("RcinelLevel_LevelHoe"), _settings.HoePosition.Value, _settings.HoeRotation.Value); Player localPlayer = Player.m_localPlayer; if (localPlayer == null) { return; } MeshFilter[] componentsInChildren = ((Component)localPlayer).GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if (!(((Object)val).name != "rcinellevel_model")) { bool flag = (Object)(object)val.sharedMesh == (Object)(object)_probeMesh; ((Component)val).transform.localPosition = (flag ? _settings.ProbePosition.Value : _settings.HoePosition.Value); ((Component)val).transform.localEulerAngles = (flag ? _settings.ProbeRotation.Value : _settings.HoeRotation.Value); } } static void Place(GameObject? prefab, Vector3 position, Vector3 rotation) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) MeshFilter[] array = ((prefab == null) ? Array.Empty<MeshFilter>() : prefab.GetComponentsInChildren<MeshFilter>(true)); foreach (MeshFilter val2 in array) { if (((Object)val2).name == "rcinellevel_model") { ((Component)val2).transform.localPosition = position; ((Component)val2).transform.localEulerAngles = rotation; } } } } } internal static class Keys { private static readonly Dictionary<KeyCode, KeyControl?> ByLayout = new Dictionary<KeyCode, KeyControl>(); private static string? _layout; public static bool Held(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0) { KeyControl val = Find(key); if (val == null) { return ZInput.GetKey(key, false); } return ((ButtonControl)val).isPressed; } return false; } public static bool Pressed(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0) { KeyControl val = Find(key); if (val == null) { return ZInput.GetKeyDown(key, false); } return ((ButtonControl)val).wasPressedThisFrame; } return false; } private static KeyControl? Find(KeyCode key) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current != null) { string text = Character(key); if (text != null) { if (current.keyboardLayout != _layout) { _layout = current.keyboardLayout; ByLayout.Clear(); } if (!ByLayout.TryGetValue(key, out KeyControl value)) { value = current.FindKeyOnCurrentKeyboardLayout(text); ByLayout[key] = value; } return value; } } return null; } private static string? Character(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((int)key >= 97) { if ((int)key <= 122) { return ((char)(97 + (key - 97))).ToString(); } } else if ((int)key >= 48 && (int)key <= 57) { return ((char)(48 + (key - 48))).ToString(); } return null; } } internal static class TerrainTiles { public static readonly int[] Radii = new int[4] { 4, 2, 1, 0 }; public static readonly Dictionary<int, TerrainOp> Prefabs = new Dictionary<int, TerrainOp>(); public const string PaintName = "RcinelLevel_Paint"; public static TerrainOp? Paint { get; set; } public static string PrefabName(int radius) { return $"RcinelLevel_LevelTile{radius}"; } public static List<(int X, int Z, int Radius)> Cover((int MinX, int MinZ, int MaxX, int MaxZ) bounds, Func<int, int, bool> inside) { (int MinX, int MinZ, int MaxX, int MaxZ) tuple = bounds; int item = tuple.MinX; int item2 = tuple.MinZ; int item3 = tuple.MaxX; int item4 = tuple.MaxZ; int num = item3 - item + 1; int num2 = item4 - item2 + 1; if (num <= 0 || num2 <= 0) { return new List<(int, int, int)>(); } bool[,] free = new bool[num, num2]; for (int i = 0; i < num2; i++) { for (int j = 0; j < num; j++) { free[j, i] = inside(j + item, i + item2); } } List<(int, int, int)> list = new List<(int, int, int)>(); int[] radii = Radii; foreach (int num3 in radii) { for (int l = num3; l < num2 - num3; l++) { for (int m = num3; m < num - num3; m++) { if (!AllFree(m, l, num3)) { continue; } list.Add((m + item, l + item2, num3)); for (int n = -num3; n <= num3; n++) { for (int num4 = -num3; num4 <= num3; num4++) { free[m + num4, l + n] = false; } } } } } return list; bool AllFree(int gx, int gz, int num6) { for (int num5 = -num6; num5 <= num6; num5++) { for (int num7 = -num6; num7 <= num6; num7++) { if (!free[gx + num7, gz + num5]) { return false; } } } return true; } } public static IEnumerator Level(List<(int X, int Z, int Radius, float Height)> tiles, int perFrame, List<(int X, int Z, float Height)>? paint = null) { int placed = 0; foreach (var (num, num2, key, num3) in tiles) { if (Prefabs.TryGetValue(key, out TerrainOp value)) { Object.Instantiate<GameObject>(((Component)value).gameObject, new Vector3((float)num, num3, (float)num2), Quaternion.identity); int num4 = placed + 1; placed = num4; if (num4 % perFrame == 0) { yield return null; } } } if (paint == null || Paint == null) { yield break; } foreach (var (num5, num6, num7) in paint) { Object.Instantiate<GameObject>(((Component)Paint).gameObject, new Vector3((float)num5, num7, (float)num6), Quaternion.identity); int num4 = placed + 1; placed = num4; if (num4 % perFrame == 0) { yield return null; } } } public static bool IsTile(TerrainOp op) { if (!((Object)op).name.StartsWith("RcinelLevel_LevelTile", StringComparison.Ordinal)) { return ((Object)op).name.StartsWith("RcinelLevel_Paint", StringComparison.Ordinal); } return true; } } internal static class Stroke { public const float NearTarget = 0.25f; public static float StonePerCubicMetre { get; set; } = 1f; public static (List<(int X, int Z, int Radius, float Height)> Tiles, float Fill, int Stone, List<(int X, int Z, float Height)> Paint) Plan(Frame frame, (int MinX, int MinZ, int MaxX, int MaxZ) brush, float target, float costFactor, float freeDepth, bool dig = false) { Dictionary<(int, int), float> raise = new Dictionary<(int, int), float>(); HashSet<(int, int)> lower = new HashSet<(int, int)>(); List<(int, int, float)> list = new List<(int, int, float)>(); List<(int, int, float)> list2 = new List<(int, int, float)>(); for (int i = brush.MinZ; i <= brush.MaxZ; i++) { var (j, _, _, _) = brush; for (; j <= brush.MaxX; j++) { (float, float)? tuple2; if (dig && frame.InMoat(j, i)) { tuple2 = Probe.At(j, i); if (tuple2.HasValue) { (float, float) valueOrDefault = tuple2.GetValueOrDefault(); float num = Math.Max(target - MoatSizes.Depth, valueOrDefault.Item2 - 8f); if (valueOrDefault.Item1 - num > 0.02f) { list.Add((j, i, num)); list2.Add((j, i, num)); } continue; } } if (!frame.Contains(j, i)) { continue; } tuple2 = Probe.At(j, i); if (tuple2.HasValue) { (float, float) valueOrDefault2 = tuple2.GetValueOrDefault(); float num2 = Math.Min(target, valueOrDefault2.Item2 + 8f); if (num2 - valueOrDefault2.Item1 > 0.02f) { raise[(j, i)] = num2 - valueOrDefault2.Item1; list2.Add((j, i, num2)); } else if (dig && valueOrDefault2.Item1 - Math.Max(target, valueOrDefault2.Item2 - 8f) > 0.02f) { lower.Add((j, i)); list2.Add((j, i, target)); } else if (valueOrDefault2.Item1 - target <= 0.25f) { list2.Add((j, i, valueOrDefault2.Item1)); } } } } float num3 = 0f; float num4 = 0f; foreach (float value in raise.Values) { num3 += value; num4 += Math.Max(0f, value - freeDepth); } List<(int, int, int, float)> list3 = new List<(int, int, int, float)>(); foreach (var (item, item2, item3) in TerrainTiles.Cover(brush, (int x, int z) => raise.ContainsKey((x, z)) || lower.Contains((x, z)))) { list3.Add((item, item2, item3, target)); } foreach (var (item4, item5, item6) in list) { list3.Add((item4, item5, 0, item6)); } return (Tiles: list3, Fill: num3, Stone: Mathf.CeilToInt(num4 * StonePerCubicMetre * costFactor - 0.001f), Paint: list2); } } internal static class DepthLock { public static bool TakeOver(TerrainOp op) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Invalid comparison between Unknown and I4 //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) if (!TerrainOp.m_forceDisableTerrainOps && !TerrainTiles.IsTile(op)) { float? num = Controls.Current?.LockedDepth; if (num.HasValue) { float valueOrDefault = num.GetValueOrDefault(); Settings settings = op.m_settings; Player localPlayer = Player.m_localPlayer; if (settings.m_raise && !(settings.m_raiseDelta >= 0f) && !settings.m_level && !((Object)(object)localPlayer == (Object)null)) { ItemData rightItem = ((Humanoid)localPlayer).GetRightItem(); if (rightItem != null && (int)rightItem.m_shared.m_skillType == 12) { Frame frame = Controls.Current.Frame; Vector3 position = ((Component)op).transform.position; float raiseRadius = settings.m_raiseRadius; int num2 = Mathf.CeilToInt(raiseRadius); int num3 = Mathf.RoundToInt(position.x); int num4 = Mathf.RoundToInt(position.z); bool flag = false; for (int i = num4 - num2; i <= num4 + num2; i++) { if (flag) { break; } for (int j = num3 - num2; j <= num3 + num2; j++) { if (flag) { break; } flag = frame.Contains(j, i) || frame.InMoat(j, i); } } if (!flag) { return false; } List<(int, int, int, float)> list = new List<(int, int, int, float)>(); List<(int, int, float)> list2 = new List<(int, int, float)>(); for (int k = num4 - num2; k <= num4 + num2; k++) { for (int l = num3 - num2; l <= num3 + num2; l++) { float num5 = 1f; if (!settings.m_square) { float num6 = Vector2.Distance(new Vector2((float)num3, (float)num4), new Vector2((float)l, (float)k)); if (num6 > raiseRadius) { continue; } if (settings.m_raisePower > 0f) { num5 = Mathf.Pow(1f - num6 / raiseRadius, settings.m_raisePower); } } bool flag2 = frame.Contains(l, k); if (!flag2 && !frame.InMoat(l, k)) { continue; } (float, float)? tuple = Probe.At(l, k); if (tuple.HasValue) { (float, float) valueOrDefault2 = tuple.GetValueOrDefault(); float num7 = Math.Max(position.y + settings.m_raiseDelta * num5, flag2 ? valueOrDefault : (valueOrDefault - MoatSizes.Depth)); if (num7 < valueOrDefault2.Item1 - 0.01f) { list.Add((l, k, 0, num7)); list2.Add((l, k, num7)); } } } } ((MonoBehaviour)RcinelLevelPlugin.Instance).StartCoroutine(TerrainTiles.Level(list, int.MaxValue, list2)); op.OnPlaced(); Object.Destroy((Object)(object)((Component)op).gameObject); return true; } } return false; } } return false; } } internal sealed class LevelAction : MonoBehaviour { private void Awake() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!TerrainOp.m_forceDisableTerrainOps) { Controls.Current?.LevelAt(((Component)this).transform.position); Object.Destroy((Object)(object)((Component)this).gameObject); } } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] internal static class TwoToolsPatch { private static void Prefix(Humanoid __instance, ItemData item, out (ItemData? Left, ItemData? Right) __state) { __state = (Left: null, Right: null); if (Items.IsLevelHoe(item) && Items.IsProbe(__instance.m_leftItem)) { __state = (Left: __instance.m_leftItem, Right: null); __instance.m_leftItem = null; } else if (Items.IsProbe(item) && Items.IsLevelHoe(__instance.m_rightItem)) { __state = (Left: null, Right: __instance.m_rightItem); __instance.m_rightItem = null; } } private static void Postfix(Humanoid __instance, (ItemData? Left, ItemData? Right) __state) { if (__state.Left != null || __state.Right != null) { if (__state.Left != null && __instance.m_leftItem == null) { (__instance.m_leftItem, _) = __state; } if (__state.Right != null && __instance.m_rightItem == null) { __instance.m_rightItem = __state.Right; } __instance.SetupEquipment(); } } } [HarmonyPatch(typeof(ObjectDB), "UpdateRegisters")] internal static class RegisterTilesPatch { private static void Prefix(ObjectDB __instance) { foreach (TerrainOp value in TerrainTiles.Prefabs.Values) { Add(value); } Add(TerrainTiles.Paint); void Add(TerrainOp? op) { if ((Object)(object)op != (Object)null && !__instance.m_terrainOps.Contains(op)) { __instance.m_terrainOps.Add(op); } } } } [HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")] internal static class ScrollPatch { private static bool _reading; public static bool Suppress { get; set; } public static float Read() { _reading = true; try { return ZInput.GetMouseScrollWheel(); } finally { _reading = false; } } private static void Postfix(ref float __result) { if (Suppress && !_reading) { __result = 0f; } } } [HarmonyPatch(typeof(TerrainOp), "Awake")] internal static class DepthLockPatch { private static bool Prefix(TerrainOp __instance) { return !DepthLock.TakeOver(__instance); } } [HarmonyPatch(typeof(Player), "UpdateBuildGuiInput")] internal static class NoBuildMenuPatch { private static bool Prefix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { return !Items.IsLevelHoe(((Humanoid)__instance).GetRightItem()); } return true; } } [HarmonyPatch(typeof(Hud), "UpdateBuild")] internal static class NoPieceBoxPatch { private static GameObject[]? _hidden; private static void Postfix(Hud __instance, Player player) { bool flag = (Object)(object)player == (Object)(object)Player.m_localPlayer && Items.IsLevelHoe(((Humanoid)player).GetRightItem()) && ((Character)player).InPlaceMode(); GameObject[] array = _hidden ?? (_hidden = Find(__instance)); foreach (GameObject val in array) { if ((Object)(object)val != (Object)null && val.activeSelf == flag) { val.SetActive(!flag); } } } private static GameObject[] Find(Hud hud) { Transform[] array = (Transform[])(object)new Transform[3] { hud.m_buildSelection.transform, hud.m_pieceDescription.transform, ((Component)hud.m_buildIcon).transform }; Transform val = array[0]; while ((Object)(object)val.parent != (Object)null && (Object)(object)val.parent != (Object)(object)hud.m_buildHud.transform) { val = val.parent; } if ((Object)(object)val.parent == (Object)null || !array[1].IsChildOf(val) || !array[2].IsChildOf(val)) { val = null; } Transform val2 = (((Object)(object)hud.m_pieceSelectionWindow != (Object)null) ? hud.m_pieceSelectionWindow.transform : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)hud.m_buildHud.transform) && (!((Object)(object)val2 != (Object)null) || !val2.IsChildOf(val))) { return (GameObject[])(object)new GameObject[1] { ((Component)val).gameObject }; } List<GameObject> list = new List<GameObject>(); list.Add(((Component)array[0]).gameObject); list.Add(((Component)array[1]).gameObject); list.Add(((Component)array[2]).gameObject); list.AddRange(hud.m_requirementItems); return list.ToArray(); } } internal sealed class PluginFiles(string directory, ManualLogSource logger) { public Mesh? LoadMesh(string name) { return Load(Path.Combine(directory, "models", name), (string path) => ObjMesh.Read(path, Path.GetFileNameWithoutExtension(path))); } public Texture2D? LoadTexture(string folder, string name) { return Load(Path.Combine(directory, folder, name), (Func<string, Texture2D>)delegate(string path) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true) { name = Path.GetFileNameWithoutExtension(path) }; if (!AssetUtils.LoadImage(val, File.ReadAllBytes(path))) { throw new InvalidDataException("not a PNG Unity can read"); } ((Texture)val).wrapMode = (TextureWrapMode)1; return val; }); } public Sprite? LoadSprite(string name) { //IL_0029: 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) Texture2D val = LoadTexture("icons", name); if (val != null) { return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } return null; } private T? Load<T>(string path, Func<string, T> read) where T : class { try { return read(path); } catch (Exception ex) { logger.LogError((object)("Couldn't load " + path + ": " + ex.Message)); return null; } } } internal static class ObjMesh { public static Mesh Read(string path, string name) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) List<Vector3> positions = new List<Vector3>(); List<Vector2> uvs = new List<Vector2>(); List<Vector3> normals = new List<Vector3>(); Dictionary<(int, int, int), int> corners = new Dictionary<(int, int, int), int>(); List<Vector3> vertices = new List<Vector3>(); List<Vector2> vertexUvs = new List<Vector2>(); List<Vector3> vertexNormals = new List<Vector3>(); List<int>[] array = new List<int>[2] { new List<int>(), new List<int>() }; int num = 0; foreach (string item in File.ReadLines(path)) { string[] array2 = item.Trim().Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 0) { continue; } switch (array2[0]) { case "v": positions.Add(new Vector3(0f - Float(array2[1]), Float(array2[2]), Float(array2[3]))); break; case "vt": uvs.Add(new Vector2(Float(array2[1]), Float(array2[2]))); break; case "vn": normals.Add(new Vector3(0f - Float(array2[1]), Float(array2[2]), Float(array2[3]))); break; case "usemtl": num = ((array2.Length > 1 && array2[1] == "stone") ? 1 : 0); break; case "f": if (array2.Length != 4) { throw new InvalidDataException($"only triangles are read, but a face has {array2.Length - 1} corners"); } array[num].Add(Corner(array2[1])); array[num].Add(Corner(array2[3])); array[num].Add(Corner(array2[2])); break; } } if (array[0].Count + array[1].Count == 0) { throw new InvalidDataException("no faces"); } Mesh val = new Mesh { name = name, subMeshCount = 2 }; val.SetVertices(vertices); val.SetUVs(0, vertexUvs); val.SetNormals(vertexNormals); val.SetTriangles(array[0], 0); val.SetTriangles(array[1], 1); val.RecalculateBounds(); val.RecalculateTangents(); return val; int Corner(string text) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) string[] ids = text.Split(new char[1] { '/' }); (int, int, int) key = (Index(ids, 0), Index(ids, 1), Index(ids, 2)); if (!corners.TryGetValue(key, out var value)) { value = vertices.Count; corners[key] = value; vertices.Add(positions[key.Item1]); vertexUvs.Add((key.Item2 >= 0) ? uvs[key.Item2] : Vector2.zero); vertexNormals.Add((key.Item3 >= 0) ? normals[key.Item3] : Vector3.up); } return value; } } private static int Index(string[] ids, int slot) { if (slot >= ids.Length || ids[slot].Length <= 0) { return -1; } return int.Parse(ids[slot], CultureInfo.InvariantCulture) - 1; } private static float Float(string text) { return float.Parse(text, NumberStyles.Float, CultureInfo.InvariantCulture); } } [BepInPlugin("io.github.codeisnotevil.rcinellevel", "RcinelLevel", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class RcinelLevelPlugin : BaseUnityPlugin { public const string Guid = "io.github.codeisnotevil.rcinellevel"; public const string Name = "RcinelLevel"; public const string Version = "0.1.0"; private Controls? _controls; internal static RcinelLevelPlugin Instance { get; private set; } internal Settings Settings { get; private set; } private void Awake() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) Instance = this; Settings = new Settings(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); PluginFiles files = new PluginFiles(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), ((BaseUnityPlugin)this).Logger); Texts.Register(); DevModes.Register(); Items.Prepare(files, Settings, ((BaseUnityPlugin)this).Logger); PrefabManager.OnVanillaPrefabsAvailable += Items.Create; new Harmony("io.github.codeisnotevil.rcinellevel").PatchAll(typeof(RcinelLevelPlugin).Assembly); _controls = new Controls(Settings, ((BaseUnityPlugin)this).Logger); Game.isModded = true; } private void Update() { Settings.ReloadIfChanged(); _controls?.Update(); } private void OnDestroy() { _controls?.Dispose(); Settings.Dispose(); } } internal sealed class ReachOverlay(ManualLogSource logger) { private const float Lift = 0.08f; private static readonly Color Warning = new Color(0.9f, 0.12f, 0.06f, 0.38f); private GameObject? _root; private Mesh? _mesh; private bool _noShader; private Measurement? _shown; public void Show(Measurement measurement) { if (measurement.Unreachable.Count == 0) { Hide(); } else if (Ready()) { _root.SetActive(true); Measurement? shown = _shown; if (!shown.HasValue || shown.GetValueOrDefault().Unreachable != measurement.Unreachable) { _shown = measurement; Build(measurement); } } } public void Hide() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } private bool Ready() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown if ((Object)(object)_root != (Object)null) { return true; } if (_noShader) { return false; } Shader val = null; string[] array = new string[3] { "Sprites/Default", "UI/Default", "Hidden/Internal-Colored" }; for (int i = 0; i < array.Length; i++) { val = Shader.Find(array[i]); if ((Object)(object)val != (Object)null) { break; } } if ((Object)(object)val == (Object)null) { _noShader = true; logger.LogWarning((object)"No transparent built-in shader was found, so the probe shows no red overlay."); return false; } _root = new GameObject("RcinelLevel reach overlay"); _mesh = new Mesh { name = "rcinellevel_reach", indexFormat = (IndexFormat)1 }; _mesh.MarkDynamic(); _root.AddComponent<MeshFilter>().sharedMesh = _mesh; MeshRender