| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- using Content.Shared.Arcade;
- using System.Linq;
- namespace Content.Server.Arcade.BlockGame;
- public sealed partial class BlockGame
- {
- /// <summary>
- /// The set of types of game pieces that exist.
- /// Used as templates when creating pieces for the game.
- /// </summary>
- private readonly BlockGamePieceType[] _allBlockGamePieces;
- /// <summary>
- /// The set of types of game pieces that exist.
- /// Used to generate the templates used when creating pieces for the game.
- /// </summary>
- private enum BlockGamePieceType
- {
- I,
- L,
- LInverted,
- S,
- SInverted,
- T,
- O
- }
- /// <summary>
- /// The set of possible rotations for the game pieces.
- /// </summary>
- private enum BlockGamePieceRotation
- {
- North,
- East,
- South,
- West
- }
- /// <summary>
- /// A static extension for the rotations that allows rotating through the possible rotations.
- /// </summary>
- private static BlockGamePieceRotation Next(BlockGamePieceRotation rotation, bool inverted)
- {
- return rotation switch
- {
- BlockGamePieceRotation.North => inverted ? BlockGamePieceRotation.West : BlockGamePieceRotation.East,
- BlockGamePieceRotation.East => inverted ? BlockGamePieceRotation.North : BlockGamePieceRotation.South,
- BlockGamePieceRotation.South => inverted ? BlockGamePieceRotation.East : BlockGamePieceRotation.West,
- BlockGamePieceRotation.West => inverted ? BlockGamePieceRotation.South : BlockGamePieceRotation.North,
- _ => throw new ArgumentOutOfRangeException(nameof(rotation), rotation, null)
- };
- }
- /// <summary>
- /// A static extension for the rotations that allows rotating through the possible rotations.
- /// </summary>
- private struct BlockGamePiece
- {
- /// <summary>
- /// Where all of the blocks that make up this piece are located relative to the origin of the piece.
- /// </summary>
- public Vector2i[] Offsets;
- /// <summary>
- /// The color of all of the blocks that make up this piece.
- /// </summary>
- private BlockGameBlock.BlockGameBlockColor _gameBlockColor;
- /// <summary>
- /// Whether or not the block should be able to rotate about its origin.
- /// </summary>
- public bool CanSpin;
- /// <summary>
- /// Generates a list of the positions of each block comprising this game piece in worldspace.
- /// </summary>
- /// <param name="center">The position of the game piece in worldspace.</param>
- /// <param name="rotation">The rotation of the game piece in worldspace.</param>
- public readonly Vector2i[] Positions(Vector2i center, BlockGamePieceRotation rotation)
- {
- return RotatedOffsets(rotation).Select(v => center + v).ToArray();
- }
- /// <summary>
- /// Gets the relative position of each block comprising this piece given a rotation.
- /// </summary>
- /// <param name="rotation">The rotation to be applied to the local position of the blocks in this piece.</param>
- private readonly Vector2i[] RotatedOffsets(BlockGamePieceRotation rotation)
- {
- var rotatedOffsets = (Vector2i[]) Offsets.Clone();
- //until i find a better algo
- var amount = rotation switch
- {
- BlockGamePieceRotation.North => 0,
- BlockGamePieceRotation.East => 1,
- BlockGamePieceRotation.South => 2,
- BlockGamePieceRotation.West => 3,
- _ => 0
- };
- for (var i = 0; i < amount; i++)
- {
- for (var j = 0; j < rotatedOffsets.Length; j++)
- {
- rotatedOffsets[j] = rotatedOffsets[j].Rotate90DegreesAsOffset();
- }
- }
- return rotatedOffsets;
- }
- /// <summary>
- /// Gets a list of all of the blocks comprising this piece in worldspace.
- /// </summary>
- /// <param name="center">The position of the game piece in worldspace.</param>
- /// <param name="rotation">The rotation of the game piece in worldspace.</param>
- public readonly BlockGameBlock[] Blocks(Vector2i center, BlockGamePieceRotation rotation)
- {
- var positions = Positions(center, rotation);
- var result = new BlockGameBlock[positions.Length];
- var i = 0;
- foreach (var position in positions)
- {
- result[i++] = position.ToBlockGameBlock(_gameBlockColor);
- }
- return result;
- }
- /// <summary>
- /// Gets a list of all of the blocks comprising this piece in worldspace.
- /// Used to generate the held piece/next piece preview images.
- /// </summary>
- public readonly BlockGameBlock[] BlocksForPreview()
- {
- var xOffset = 0;
- var yOffset = 0;
- foreach (var offset in Offsets)
- {
- if (offset.X < xOffset)
- xOffset = offset.X;
- if (offset.Y < yOffset)
- yOffset = offset.Y;
- }
- return Blocks(new Vector2i(-xOffset, -yOffset), BlockGamePieceRotation.North);
- }
- /// <summary>
- /// Generates a game piece for a given type of game piece.
- /// See <see cref="BlockGamePieceType"/> for the available options.
- /// </summary>
- /// <param name="type">The type of game piece to generate.</param>
- public static BlockGamePiece GetPiece(BlockGamePieceType type)
- {
- //switch statement, hardcoded offsets
- return type switch
- {
- BlockGamePieceType.I => new BlockGamePiece
- {
- Offsets = new[]
- {
- new Vector2i(0, -1), new Vector2i(0, 0), new Vector2i(0, 1), new Vector2i(0, 2),
- },
- _gameBlockColor = BlockGameBlock.BlockGameBlockColor.LightBlue,
- CanSpin = true
- },
- BlockGamePieceType.L => new BlockGamePiece
- {
- Offsets = new[]
- {
- new Vector2i(0, -1), new Vector2i(0, 0), new Vector2i(0, 1), new Vector2i(1, 1),
- },
- _gameBlockColor = BlockGameBlock.BlockGameBlockColor.Orange,
- CanSpin = true
- },
- BlockGamePieceType.LInverted => new BlockGamePiece
- {
- Offsets = new[]
- {
- new Vector2i(0, -1), new Vector2i(0, 0), new Vector2i(-1, 1),
- new Vector2i(0, 1),
- },
- _gameBlockColor = BlockGameBlock.BlockGameBlockColor.Blue,
- CanSpin = true
- },
- BlockGamePieceType.S => new BlockGamePiece
- {
- Offsets = new[]
- {
- new Vector2i(0, -1), new Vector2i(1, -1), new Vector2i(-1, 0),
- new Vector2i(0, 0),
- },
- _gameBlockColor = BlockGameBlock.BlockGameBlockColor.Green,
- CanSpin = true
- },
- BlockGamePieceType.SInverted => new BlockGamePiece
- {
- Offsets = new[]
- {
- new Vector2i(-1, -1), new Vector2i(0, -1), new Vector2i(0, 0),
- new Vector2i(1, 0),
- },
- _gameBlockColor = BlockGameBlock.BlockGameBlockColor.Red,
- CanSpin = true
- },
- BlockGamePieceType.T => new BlockGamePiece
- {
- Offsets = new[]
- {
- new Vector2i(0, -1),
- new Vector2i(-1, 0), new Vector2i(0, 0), new Vector2i(1, 0),
- },
- _gameBlockColor = BlockGameBlock.BlockGameBlockColor.Purple,
- CanSpin = true
- },
- BlockGamePieceType.O => new BlockGamePiece
- {
- Offsets = new[]
- {
- new Vector2i(0, -1), new Vector2i(1, -1), new Vector2i(0, 0),
- new Vector2i(1, 0),
- },
- _gameBlockColor = BlockGameBlock.BlockGameBlockColor.Yellow,
- CanSpin = false
- },
- _ => new BlockGamePiece
- {
- Offsets = new[]
- {
- new Vector2i(0, 0)
- }
- },
- };
- }
- }
- }
|