using System; using Random = System.Random; namespace GeometryTD.Definition { public readonly struct InventoryGenerationRandomContext { public InventoryGenerationRandomContext( int runSeed, int nodeSequenceIndex, InventoryTagSourceType sourceType, int localOrdinal) { RunSeed = runSeed; NodeSequenceIndex = nodeSequenceIndex; SourceType = sourceType; LocalOrdinal = localOrdinal; } public int RunSeed { get; } public int NodeSequenceIndex { get; } public InventoryTagSourceType SourceType { get; } public int LocalOrdinal { get; } public Random CreateRandom() { return new Random(BuildSeed()); } public long CreateStableItemInstanceId() { long normalizedSource = ((long)Math.Max(0, (int)SourceType) + 1L) << 48; long normalizedSequence = ((long)Math.Max(0, NodeSequenceIndex) + 1L) << 24; long normalizedOrdinal = (uint)(Math.Max(0, LocalOrdinal) + 1); return normalizedSource | normalizedSequence | normalizedOrdinal; } public InventoryTagRandomContext CreateTagRandomContext(int configId) { return SourceType switch { InventoryTagSourceType.Shop => InventoryTagRandomContext.CreateShop(RunSeed, NodeSequenceIndex, LocalOrdinal, configId), InventoryTagSourceType.Reward => InventoryTagRandomContext.CreateReward(RunSeed, NodeSequenceIndex, LocalOrdinal, configId), InventoryTagSourceType.Event => InventoryTagRandomContext.CreateEvent(RunSeed, NodeSequenceIndex, LocalOrdinal, configId), _ => InventoryTagRandomContext.CreateDrop(RunSeed, NodeSequenceIndex, LocalOrdinal, configId) }; } private int BuildSeed() { unchecked { int seed = 17; seed = seed * 31 + RunSeed; seed = seed * 31 + NodeSequenceIndex; seed = seed * 31 + (int)SourceType; seed = seed * 31 + LocalOrdinal; return seed; } } } }