using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("BottomlessChest.Logic")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BottomlessChest.Logic")] [assembly: AssemblyTitle("BottomlessChest.Logic")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } } namespace BottomlessChest.Logic { public readonly struct GridPos : IEquatable { public int X { get; } public int Y { get; } public GridPos(int x, int y) { X = x; Y = y; } public bool Equals(GridPos other) { if (X == other.X) { return Y == other.Y; } return false; } public override bool Equals(object obj) { if (obj is GridPos other) { return Equals(other); } return false; } public override int GetHashCode() { return (X * 397) ^ Y; } public override string ToString() { return $"({X}, {Y})"; } } public static class GridPacker { public static GridPos PositionOf(int index, int width) { RequirePositiveWidth(width); return new GridPos(index % width, index / width); } public static int RowsNeeded(int count, int width) { RequirePositiveWidth(width); if (count > 0) { return (count - 1) / width + 1; } return 0; } public static int RowsForChest(int count, int width, int minRows) { RequirePositiveWidth(width); int num = RowsNeeded(count, width) + 1; int num2 = ((minRows < 1) ? 1 : minRows); if (num <= num2) { return num2; } return num; } public static bool LayoutFitsWindow(IReadOnlyList positions, int width, int rows) { RequirePositiveWidth(width); if (rows < 1 || positions == null) { return false; } if (positions.Count > width * rows) { return false; } HashSet hashSet = new HashSet(); foreach (GridPos position in positions) { if (position.X < 0 || position.X >= width || position.Y < 0 || position.Y >= rows) { return false; } if (!hashSet.Add(position.Y * width + position.X)) { return false; } } return true; } private static void RequirePositiveWidth(int width) { if (width <= 0) { throw new ArgumentOutOfRangeException("width", width, "Grid width must be at least 1."); } } } public interface IStorableItem { string ItemId { get; } string DisplayName { get; } string SearchKey { get; } ItemKind Kind { get; } int Stack { get; } int MaxStackSize { get; } int Quality { get; } int Variant { get; } string CustomData { get; } } public enum ItemKind { Unknown, Material, Food, Weapon, Armor, Ammo, Tool, Trophy, Misc } public sealed class ItemOrdering : IComparer { public static ItemOrdering ByName { get; } = new ItemOrdering(); public int Compare(IStorableItem a, IStorableItem b) { if (a == b) { return 0; } if (a == null) { return -1; } if (b == null) { return 1; } int num = string.CompareOrdinal(a.SearchKey ?? string.Empty, b.SearchKey ?? string.Empty); if (num != 0) { return num; } int num2 = b.Quality.CompareTo(a.Quality); if (num2 != 0) { return num2; } return b.Stack.CompareTo(a.Stack); } } public sealed class ItemQuery { private static readonly Dictionary KindTokens = new Dictionary(StringComparer.Ordinal) { { "@material", ItemKind.Material }, { "@food", ItemKind.Food }, { "@weapon", ItemKind.Weapon }, { "@armor", ItemKind.Armor }, { "@ammo", ItemKind.Ammo }, { "@tool", ItemKind.Tool }, { "@trophy", ItemKind.Trophy }, { "@misc", ItemKind.Misc } }; private readonly List _textTerms; private readonly List _kindTerms; public bool IsEmpty { get { if (_textTerms.Count == 0) { return _kindTerms.Count == 0; } return false; } } private ItemQuery(List textTerms, List kindTerms) { _textTerms = textTerms; _kindTerms = kindTerms; } public static ItemQuery Parse(string query) { List list = new List(); List list2 = new List(); if (!string.IsNullOrWhiteSpace(query)) { string[] array = query.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = TextKey.Of(array[i]); if (text.Length != 0) { if (KindTokens.TryGetValue(text, out var value)) { list2.Add(value); } else { list.Add(text); } } } } return new ItemQuery(list, list2); } public bool Matches(IStorableItem item) { if (IsEmpty) { return true; } if (_kindTerms.Count > 0 && !_kindTerms.Contains(item.Kind)) { return false; } if (_textTerms.Count == 0) { return true; } string text = item.SearchKey ?? string.Empty; foreach (string textTerm in _textTerms) { if (text.IndexOf(textTerm, StringComparison.Ordinal) < 0) { return false; } } return true; } } public sealed class StackPolicy { public bool Unlimited { get; } public int Multiplier { get; } public StackPolicy(bool unlimited, int multiplier) { Unlimited = unlimited; Multiplier = multiplier; } } public static class StackRules { public static bool CanMerge(IStorableItem a, IStorableItem b) { if (a == null || b == null) { return false; } if (a.MaxStackSize <= 1 || b.MaxStackSize <= 1) { return false; } if (string.Equals(a.ItemId, b.ItemId, StringComparison.Ordinal) && a.Quality == b.Quality && a.Variant == b.Variant) { return string.Equals(a.CustomData ?? string.Empty, b.CustomData ?? string.Empty, StringComparison.Ordinal); } return false; } public static int EffectiveStackLimit(IStorableItem item, StackPolicy policy) { if (policy.Unlimited) { return int.MaxValue; } long num = (long)item.MaxStackSize * (long)policy.Multiplier; if (num < item.MaxStackSize) { return item.MaxStackSize; } if (num <= int.MaxValue) { return (int)num; } return int.MaxValue; } public static IReadOnlyList SplitForExit(int stack, int maxStackSize) { if (maxStackSize <= 0) { throw new ArgumentOutOfRangeException("maxStackSize", maxStackSize, "Stack ceiling must be at least 1."); } List list = new List(); int num = stack; while (num > 0) { int num2 = Math.Min(num, maxStackSize); list.Add(num2); num -= num2; } return list; } } public static class TextKey { public static string Of(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } string text = value.Normalize(NormalizationForm.FormD); StringBuilder stringBuilder = new StringBuilder(text.Length); string text2 = text; foreach (char c in text2) { if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark) { stringBuilder.Append(c); } } return stringBuilder.ToString().Normalize(NormalizationForm.FormC).ToLowerInvariant(); } } }