Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Text;
- using Vintagestory.API.MathTools;
- namespace Vintagestory.Essentials
- {
- [Flags]
- public enum ProperNeighbor : byte
- {
- None = 0,
- // FACINGS
- East = 0b110000, // +X
- West = 0b100000, // -X
- Up = 0b001100, // +Y
- Down = 0b001000, // -Y
- South = 0b000011, // +Z
- North = 0b000010, // -Z
- // CARDINALS
- SouthEast = South | East, // +X +Z
- SouthWest = South | West, // -X +Z
- NorthEast = North | East, // +X -Z
- NorthWest = North | West, // -X -Z
- // ALL_AXIS_PLANES
- UpEast = Up | East , // +X +Y
- UpWest = Up | West , // -X +Y
- UpSouth = Up | South, // +Z +Y
- UpNorth = Up | North, // -Z +Y
- DownEast = Down | East , // +X -Y
- DownWest = Down | West , // -X -Y
- DownSouth = Down | South, // +Z -Y
- DownNorth = Down | North, // -Z -Y
- // ALL
- UpSouthEast = Up | South | East, // +X +Y +Z
- UpSouthWest = Up | South | West, // -X +Y +Z
- UpNorthEast = Up | North | East, // +X +Y -Z
- UpNorthWest = Up | North | West, // -X +Y -Z
- DownSouthEast = Down | South | East, // +X -Y +Z
- DownSouthWest = Down | South | West, // -X -Y +Z
- DownNorthEast = Down | North | East, // +X -Y -Z
- DownNorthWest = Down | North | West, // -X -Y -Z
- }
- public static class ProperNeighborHelper
- {
- public static readonly ImmutableSet<ProperNeighbor> HORIZONTALS =
- new ImmutableSet<ProperNeighbor>(
- ProperNeighbor.East, ProperNeighbor.West,
- ProperNeighbor.South, ProperNeighbor.North);
- public static readonly ImmutableSet<ProperNeighbor> VERTICALS =
- new ImmutableSet<ProperNeighbor>(ProperNeighbor.Up, ProperNeighbor.Down);
- public static readonly ImmutableSet<ProperNeighbor> FACINGS =
- new ImmutableSet<ProperNeighbor>(HORIZONTALS, VERTICALS);
- public static readonly ImmutableSet<ProperNeighbor> CARDINALS =
- new ImmutableSet<ProperNeighbor>(HORIZONTALS,
- ProperNeighbor.SouthEast, ProperNeighbor.SouthWest,
- ProperNeighbor.NorthEast, ProperNeighbor.NorthWest);
- public static readonly ImmutableSet<ProperNeighbor> ALL_AXIS_PLANES =
- new ImmutableSet<ProperNeighbor>(FACINGS,
- ProperNeighbor.SouthEast, ProperNeighbor.SouthWest,
- ProperNeighbor.NorthEast, ProperNeighbor.NorthWest,
- ProperNeighbor.UpEast , ProperNeighbor.UpWest ,
- ProperNeighbor.UpSouth , ProperNeighbor.UpNorth ,
- ProperNeighbor.DownEast , ProperNeighbor.DownWest ,
- ProperNeighbor.DownSouth, ProperNeighbor.DownNorth);
- public static readonly ImmutableSet<ProperNeighbor> ALL =
- new ImmutableSet<ProperNeighbor>(ALL_AXIS_PLANES,
- ProperNeighbor.UpSouthEast, ProperNeighbor.UpSouthWest,
- ProperNeighbor.UpNorthEast, ProperNeighbor.UpNorthWest,
- ProperNeighbor.DownSouthEast, ProperNeighbor.DownSouthWest,
- ProperNeighbor.DownNorthEast, ProperNeighbor.DownNorthWest);
- public static ProperNeighbor fromAxis(EnumAxis axis, int v)
- {
- if ((v < -1) || (v > 1))
- throw new ArgumentOutOfRangeException(nameof(v), $"v must be within (-1, 1), is {v}");
- switch (axis) {
- case EnumAxis.X: return (v > 0) ? ProperNeighbor.East : ProperNeighbor.West;
- case EnumAxis.Y: return (v > 0) ? ProperNeighbor.Up : ProperNeighbor.Down;
- case EnumAxis.Z: return (v > 0) ? ProperNeighbor.South : ProperNeighbor.North;
- default: return ProperNeighbor.None;
- }
- }
- public static EnumAxis getAxis(this ProperNeighbor self)
- {
- switch (self) {
- case ProperNeighbor.East : return EnumAxis.X;
- case ProperNeighbor.West : return EnumAxis.X;
- case ProperNeighbor.Up : return EnumAxis.Y;
- case ProperNeighbor.Down : return EnumAxis.Y;
- case ProperNeighbor.South : return EnumAxis.Z;
- case ProperNeighbor.North : return EnumAxis.Z;
- default: throw new ArgumentException(nameof(self), $"{self} is not one of FACINGS");
- }
- }
- public static ProperNeighbor fromOffset(int x, int y, int z)
- {
- ProperNeighbor neighbor = ProperNeighbor.None;
- if (x != 0) {
- if (x == 1) neighbor |= ProperNeighbor.East;
- else if (x == -1) neighbor |= ProperNeighbor.West;
- else throw new ArgumentOutOfRangeException(nameof(x), $"x must be within (-1, 1), is {x}");
- }
- if (y != 0) {
- if (y == 1) neighbor |= ProperNeighbor.Up;
- else if (y == -1) neighbor |= ProperNeighbor.Down;
- else throw new ArgumentOutOfRangeException(nameof(y), $"y must be within (-1, 1), is {y}");
- }
- if (z != 0) {
- if (z == 1) neighbor |= ProperNeighbor.South;
- else if (z == -1) neighbor |= ProperNeighbor.North;
- else throw new ArgumentOutOfRangeException(nameof(z), $"z must be within (-1, 1), is {z}");
- }
- return neighbor;
- // Alternative implementation:
- // if ((x < -1) || (x > 1)) throw new ArgumentOutOfRangeException(nameof(x), "x must be within (-1, 1)");
- // if ((y < -1) || (y > 1)) throw new ArgumentOutOfRangeException(nameof(y), "y must be within (-1, 1)");
- // if ((z < -1) || (z > 1)) throw new ArgumentOutOfRangeException(nameof(z), "z must be within (-1, 1)");
- // return ((x != 0) ? ((x > 0) ? ProperNeighbor.East : ProperNeighbor.West ) : 0)
- // | ((y != 0) ? ((y > 0) ? ProperNeighbor.Up : ProperNeighbor.Down ) : 0)
- // | ((z != 0) ? ((z > 0) ? ProperNeighbor.South : ProperNeighbor.North) : 0);
- }
- private const int X_SET_BIT = 0b100000, X_VALUE_BIT = 0b010000;
- private const int Y_SET_BIT = 0b001000, Y_VALUE_BIT = 0b000100;
- private const int Z_SET_BIT = 0b000010, Z_VALUE_BIT = 0b000001;
- public static void getOffset(this ProperNeighbor self,
- out int x, out int y, out int z)
- {
- x = (((int)self & X_SET_BIT) != 0) ? ((((int)self & X_VALUE_BIT) != 0) ? 1 : -1) : 0;
- y = (((int)self & Y_SET_BIT) != 0) ? ((((int)self & Y_VALUE_BIT) != 0) ? 1 : -1) : 0;
- z = (((int)self & Z_SET_BIT) != 0) ? ((((int)self & Z_VALUE_BIT) != 0) ? 1 : -1) : 0;
- }
- public static ProperPos toProperPos(this ProperNeighbor self)
- {
- self.getOffset(out var x, out var y, out var z);
- return new ProperPos(x, y, z);
- }
- public static Vec3i toVec3i(this ProperNeighbor self)
- {
- self.getOffset(out var x, out var y, out var z);
- return new Vec3i(x, y, z);
- }
- public static bool isNone(this ProperNeighbor self)
- => (self == ProperNeighbor.None);
- public static bool isHorizontal(this ProperNeighbor self)
- => HORIZONTALS.Contains(self);
- public static bool isVertical(this ProperNeighbor self)
- => VERTICALS.Contains(self);
- public static bool isCardinal(this ProperNeighbor self)
- => CARDINALS.Contains(self);
- public static bool isFacing(this ProperNeighbor self)
- => FACINGS.Contains(self);
- public static bool isValid(this ProperNeighbor self)
- => ALL.Contains(self);
- public static string ToShortString(this ProperNeighbor self)
- {
- if (!self.isValid()) return "-";
- var sb = new StringBuilder(3);
- foreach (var chr in self.ToString())
- if ((chr >= 'A') && (chr <= 'Z')) // ASCII IsUpper
- sb.Append(chr + 0x20); // ASCII ToUpper
- return sb.ToString();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement