Merge branch 'master' of https://git.touhou.dev/Texel/WinterJamSnowman
This commit is contained in:
commit
bcd48fa061
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: a5a1671f2bf6f9341b8ec7fc994dcc9e
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 9583f386cfcb0aa489cef79c2fe974d0
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
|
@ -79,7 +79,7 @@ MonoBehaviour:
|
||||||
value: 0
|
value: 0
|
||||||
saturation:
|
saturation:
|
||||||
overrideState: 1
|
overrideState: 1
|
||||||
value: 30
|
value: 20
|
||||||
brightness:
|
brightness:
|
||||||
overrideState: 0
|
overrideState: 0
|
||||||
value: 0
|
value: 0
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 295ac802c88cd48448df9ecb56c7fb04
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: eb26112da6fce9c4ca2610cb953c66e6
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 7bdec22f29afa8245899160b77f09c8f
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: e8e3cbd1de7025044a7a92113d6e88f0
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: bf45ed03d77ae9144849c5d0c914a13d
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
|
@ -15,10 +15,24 @@ using BoardData = System.Collections.Generic.List<System.Collections.Generic.Lis
|
||||||
// Tile Stack is the vertical list of tiles
|
// Tile Stack is the vertical list of tiles
|
||||||
using TileStack = System.Collections.Generic.List<TileInfo>;
|
using TileStack = System.Collections.Generic.List<TileInfo>;
|
||||||
|
|
||||||
#region Board Logic
|
using Cluster = System.Collections.Generic.List<(int x, int y)>;
|
||||||
|
|
||||||
|
#region Gameboard Class
|
||||||
public class GameBoard : EntityBase, IAutoSerialize, IAutoDeserialize {
|
public class GameBoard : EntityBase, IAutoSerialize, IAutoDeserialize {
|
||||||
public BoardState board = new BoardState();
|
public BoardState board = new BoardState();
|
||||||
|
|
||||||
|
GameBoardDrawer _drawer;
|
||||||
|
public GameBoardDrawer drawer {
|
||||||
|
get {
|
||||||
|
if (_drawer) return _drawer;
|
||||||
|
return _drawer = GetComponent<GameBoardDrawer>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BreakFX(int x, int y) {
|
||||||
|
drawer[x, y]?.OnBreakFX();
|
||||||
|
}
|
||||||
|
|
||||||
public override void Deserialize(Hashtable h) {
|
public override void Deserialize(Hashtable h) {
|
||||||
base.Serialize(h);
|
base.Serialize(h);
|
||||||
if (h.TryGetValue('b', out var hashedBoard))
|
if (h.TryGetValue('b', out var hashedBoard))
|
||||||
|
@ -35,17 +49,12 @@ public class GameBoard : EntityBase, IAutoSerialize, IAutoDeserialize {
|
||||||
// Short form for random tiles
|
// Short form for random tiles
|
||||||
TileInfo Random => TileInfo.Random(Options);
|
TileInfo Random => TileInfo.Random(Options);
|
||||||
|
|
||||||
|
// Unit testing!
|
||||||
[ContextMenu("Test board")]
|
[ContextMenu("Test board")]
|
||||||
public void TestBoard() {
|
public void TestBoard() {
|
||||||
board = new BoardState();
|
board = new BoardState();
|
||||||
/*board[0] = new TileStack(new[] {
|
|
||||||
new TileInfo(1),
|
|
||||||
new TileInfo(10),
|
|
||||||
new TileInfo(100),
|
|
||||||
new TileInfo(1000),
|
|
||||||
});*/
|
|
||||||
for(int i = 0; i < BoardState.BoardWidth; ++i) {
|
for(int i = 0; i < BoardState.BoardWidth; ++i) {
|
||||||
board[i] = new TileStack(new[] { Random, Random, Random });
|
board[i] = new TileStack(new[] { Random, Random, Random, Random, Random, Random });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +63,19 @@ public class GameBoard : EntityBase, IAutoSerialize, IAutoDeserialize {
|
||||||
board = BoardState.Copy(board);
|
board = BoardState.Copy(board);
|
||||||
Debug.Log(board.ToString());
|
Debug.Log(board.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ContextMenu("Recursive Sim")]
|
||||||
|
void RecursiveSim() => board = board.SimulateRecursive(this, out _);
|
||||||
|
|
||||||
|
[ContextMenu("Activate")]
|
||||||
|
public void Activate() => board = board.Activate(out _);
|
||||||
|
|
||||||
|
[ContextMenu("Break Pending")]
|
||||||
|
public void BreakPending() => board = board.BreakPending(this, Application.isPlaying);
|
||||||
|
|
||||||
|
[ContextMenu("Collapse")]
|
||||||
|
public void Collapse() => board = board.Collapse();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -64,7 +86,7 @@ public enum TileColor : byte {
|
||||||
Empty = 0, // Used for ID'ing air by color alone
|
Empty = 0, // Used for ID'ing air by color alone
|
||||||
|
|
||||||
Red = 1,
|
Red = 1,
|
||||||
Blue = 2,
|
Yellow = 2,
|
||||||
Green = 3,
|
Green = 3,
|
||||||
Pink = 4,
|
Pink = 4,
|
||||||
Purple = 5,
|
Purple = 5,
|
||||||
|
@ -85,7 +107,7 @@ public enum TileDetail : byte { // Gets cast to byte a lot
|
||||||
Air = 0x0, // None and Air as aliases
|
Air = 0x0, // None and Air as aliases
|
||||||
Normal = 0x1, // Flag that tile exists
|
Normal = 0x1, // Flag that tile exists
|
||||||
Pending = 0x2, // State for active in combo but not cleared
|
Pending = 0x2, // State for active in combo but not cleared
|
||||||
//Damaged = 0x04, // Used for Tanuki and Ice -- Actually unneccessary by replacement setup
|
Exploded = 0x04, // State for a block that is being exploded
|
||||||
Dropped = 0x08, // Flag for tiles that were just dropped, for smears
|
Dropped = 0x08, // Flag for tiles that were just dropped, for smears
|
||||||
Fairy = 0x10, // do not clear air under this
|
Fairy = 0x10, // do not clear air under this
|
||||||
Poofed = 0x20, // Drawn as a cloud, freshly removed
|
Poofed = 0x20, // Drawn as a cloud, freshly removed
|
||||||
|
@ -137,16 +159,40 @@ public class TileInfo {
|
||||||
data = ti.data; // More delicious garbage
|
data = ti.data; // More delicious garbage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool SameAs(TileInfo a, TileInfo b) {
|
||||||
|
if (a.color != b.color) return false;
|
||||||
|
|
||||||
|
// Internal flags we don't consider for if a tile is the same
|
||||||
|
var irrelevant = TileDetail.Dropped | TileDetail.Poofed | TileDetail.Pending | TileDetail.Exploded;
|
||||||
|
if ((a.detail & ~irrelevant) != (b.detail & ~irrelevant))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TileInfo SetFalling(bool fall) {
|
||||||
|
detail &= ~TileDetail.Dropped;
|
||||||
|
if (fall) detail |= TileDetail.Dropped;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public TileInfo AsTanuki() {
|
public TileInfo AsTanuki() {
|
||||||
detail &= TileDetail.Tanuki;
|
detail |= TileDetail.Tanuki;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileInfo AsIce() {
|
public TileInfo AsIce() {
|
||||||
detail &= TileDetail.Ice;
|
detail |= TileDetail.Ice;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TileInfo SetPending() {
|
||||||
|
detail |= TileDetail.Pending;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isPending => (detail & TileDetail.Pending) != 0;
|
||||||
|
|
||||||
public TileInfo BreakTile(params TileColor[] options) {
|
public TileInfo BreakTile(params TileColor[] options) {
|
||||||
var d = detail;
|
var d = detail;
|
||||||
|
|
||||||
|
@ -165,22 +211,35 @@ public class TileInfo {
|
||||||
|
|
||||||
// Make and return a new air tile
|
// Make and return a new air tile
|
||||||
public static TileInfo Air => new TileInfo(0); // Just air
|
public static TileInfo Air => new TileInfo(0); // Just air
|
||||||
public bool isAir => data == 0;
|
public bool isAir {
|
||||||
|
get {
|
||||||
|
if (color == TileColor.Empty) return true;
|
||||||
|
return SameAs(this, Air);
|
||||||
|
//var irrelevant = TileDetail.Dropped | TileDetail.Poofed | TileDetail.Pending | TileDetail.Exploded;
|
||||||
|
//var maskedDetail = (byte)detail & ~irrelevant;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static implicit operator int(TileInfo ti) => ti.data;
|
public static implicit operator int(TileInfo ti) => ti.data;
|
||||||
public static explicit operator TileInfo(int i) => new TileInfo(i);
|
public static explicit operator TileInfo(int i) => new TileInfo(i);
|
||||||
|
|
||||||
public bool CombosWith(TileInfo other) => CombosWith(color);
|
public bool CombosWith(TileInfo other) {
|
||||||
|
if (other == null) return false;
|
||||||
|
return CombosWith(other.color);
|
||||||
|
}
|
||||||
public bool CombosWith(TileColor c) {
|
public bool CombosWith(TileColor c) {
|
||||||
if (c == 0) return false; // nothing combos with air
|
if (c == 0) return false; // nothing combos with air
|
||||||
if (color == 0) return false; // Also don't combo with us if we're air
|
if (color == 0) return false; // Also don't combo with us if we're air
|
||||||
|
|
||||||
|
if (c == color && (byte)c < 200) return true;
|
||||||
|
|
||||||
if ((byte)c < 200) // If it's a simple color block
|
if ((byte)c < 200) // If it's a simple color block
|
||||||
return c == color; // just match if it matches our own color
|
return c == color; // just match if it matches our own color
|
||||||
|
|
||||||
switch (c) { // Special handling for wildcard
|
switch (c) { // Special handling for wildcard
|
||||||
case TileColor.Wildcard:
|
case TileColor.Wildcard:
|
||||||
if ((byte)color < 200) return true; // If we are a simple block
|
//if ((byte)color < 200) return true; // If we are a simple block
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// room for more weird custom magic logic?
|
// room for more weird custom magic logic?
|
||||||
|
@ -192,11 +251,372 @@ public class TileInfo {
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Board Logic
|
||||||
|
|
||||||
|
public static class BoardLogic {
|
||||||
|
// return height of tallest column
|
||||||
|
public static int TallestStack(this BoardState bs)
|
||||||
|
=> bs.state.Max(t => t.Count);
|
||||||
|
|
||||||
|
|
||||||
|
// Get a tile from a stack padded with nulls
|
||||||
|
public static TileInfo NullPadded(this TileStack ts, int row) {
|
||||||
|
if (row < 0) return null;
|
||||||
|
if (row >= ts.Count) return null;
|
||||||
|
|
||||||
|
return ts[row];
|
||||||
|
}
|
||||||
|
// Get the tile from the stack padded with air
|
||||||
|
public static TileInfo Padded(this TileStack ts, int row)
|
||||||
|
=> ts.NullPadded(row) ?? TileInfo.Air;
|
||||||
|
|
||||||
|
public static void ChangeTile(this TileStack ts, int row, TileInfo ti) {
|
||||||
|
if (row < 0) return;
|
||||||
|
if (row >= ts.Count) return;
|
||||||
|
ts[row] = ti;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool StackHasMatches(this TileStack ts) {
|
||||||
|
// Check up the length of the column for a match 3
|
||||||
|
for (int y = 0; y < ts.Count; ++y) {
|
||||||
|
var at = ts[y];
|
||||||
|
var match = at.CombosWith(ts.Padded(y + 1)) && at.CombosWith(ts.Padded(y + 2));
|
||||||
|
if (match) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<TileInfo> Neighbors(this BoardState bs, int x, int y) {
|
||||||
|
var self = bs.tile(x, y);
|
||||||
|
var neighborsWithNull =
|
||||||
|
new[] {
|
||||||
|
bs.tile(x + 1, y),
|
||||||
|
bs.tile(x - 1, y),
|
||||||
|
bs.tile(x, y + 1),
|
||||||
|
bs.tile(x, y - 1) };
|
||||||
|
|
||||||
|
return neighborsWithNull.Where(t => t != null).Where(t => t != self);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<TileInfo> ComboAdjacents(this BoardState bs, int x, int y) {
|
||||||
|
var neighbors = bs.Neighbors(x, y);
|
||||||
|
var self = bs.tile(x, y);
|
||||||
|
|
||||||
|
return neighbors.Where(ti => ti.CombosWith(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<(int x, int y)> MatchingAdjacentCoordinates(this BoardState bs, (int x, int y) p) {
|
||||||
|
var matches = new List<(int x, int y)>();
|
||||||
|
var self = bs.TileAtPoint(p);
|
||||||
|
|
||||||
|
// HACK return empty set if self is null
|
||||||
|
if (self == null) return new (int x, int y)[] { };
|
||||||
|
|
||||||
|
var (x, y) = p;
|
||||||
|
|
||||||
|
if (self.CombosWith(bs.tile(p.x + 1, p.y)))
|
||||||
|
matches.Add((x+1, y));
|
||||||
|
if (self.CombosWith(bs.tile(p.x - 1, p.y)))
|
||||||
|
matches.Add((x-1, y));
|
||||||
|
if (self.CombosWith(bs.tile(p.x, p.y + 1)))
|
||||||
|
matches.Add((x, y+1));
|
||||||
|
if (self.CombosWith(bs.tile(p.x, p.y - 1)))
|
||||||
|
matches.Add((x, y-1));
|
||||||
|
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Cluster Clusterize(this BoardState bs, int x, int y) {
|
||||||
|
var at = bs.tile(x, y);
|
||||||
|
if (at == null) return null;
|
||||||
|
|
||||||
|
List<(int x, int y)> OpenSet, ClosedSet;
|
||||||
|
OpenSet = new List<(int x, int y)>();
|
||||||
|
ClosedSet = new List<(int x, int y)>();
|
||||||
|
|
||||||
|
ClosedSet.Add((x, y));
|
||||||
|
OpenSet.AddRange(bs.MatchingAdjacentCoordinates((x, y)));
|
||||||
|
|
||||||
|
while (OpenSet.Count > 0) {
|
||||||
|
var element = OpenSet[0];
|
||||||
|
OpenSet.RemoveAt(0);
|
||||||
|
|
||||||
|
ClosedSet.Add(element);
|
||||||
|
|
||||||
|
var matches = bs.MatchingAdjacentCoordinates(element);
|
||||||
|
foreach (var match in matches) {
|
||||||
|
if (ClosedSet.Contains(match))
|
||||||
|
continue;
|
||||||
|
OpenSet.Add(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ClosedSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] MatchingNeighbors(this TileStack ts, int y) {
|
||||||
|
var self = ts[y];
|
||||||
|
if (self == null) goto Empty;
|
||||||
|
if (self.isAir) goto Empty;
|
||||||
|
|
||||||
|
var above = ts.NullPadded(y + 1);
|
||||||
|
var below = ts.NullPadded(y - 1);
|
||||||
|
|
||||||
|
bool aboveMatch = false;
|
||||||
|
bool belowMatch = false;
|
||||||
|
|
||||||
|
if (above != null && TileInfo.SameAs(self, above))
|
||||||
|
aboveMatch = true;
|
||||||
|
|
||||||
|
if (below != null && TileInfo.SameAs(self, below))
|
||||||
|
belowMatch = true;
|
||||||
|
|
||||||
|
if (aboveMatch && belowMatch)
|
||||||
|
return new[] {y+1, y-1};
|
||||||
|
if (aboveMatch)
|
||||||
|
return new[] { y + 1 };
|
||||||
|
if (belowMatch)
|
||||||
|
return new[] { y - 1 };
|
||||||
|
|
||||||
|
Empty:
|
||||||
|
return new int[] { };
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Cluster ClusterizeVertical(this BoardState bs, int x, int y) {
|
||||||
|
var stack = bs[x];
|
||||||
|
|
||||||
|
if (stack == null) return null;
|
||||||
|
if (y >= stack.Count) return null;
|
||||||
|
|
||||||
|
var self = stack[y];
|
||||||
|
|
||||||
|
if (self == null) return null;
|
||||||
|
if (self.isAir) return null;
|
||||||
|
|
||||||
|
var OpenSet = new List<int>();
|
||||||
|
var ClosedSet = new List<int>(new[] { y });
|
||||||
|
|
||||||
|
OpenSet.AddRange(stack.MatchingNeighbors(y));
|
||||||
|
|
||||||
|
while (OpenSet.Count > 0) {
|
||||||
|
var element = OpenSet[0];
|
||||||
|
OpenSet.RemoveAt(0);
|
||||||
|
|
||||||
|
ClosedSet.Add(element);
|
||||||
|
var matches = stack.MatchingNeighbors(element);
|
||||||
|
|
||||||
|
foreach(var match in matches) {
|
||||||
|
if (ClosedSet.Contains(match))
|
||||||
|
continue;
|
||||||
|
OpenSet.Add(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand back out to (x, y) from the list of y's
|
||||||
|
return ClosedSet.Select(e => (x, e)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BoardState Collapse(this BoardState bs) {
|
||||||
|
// TODO: Proper support for fairy blocks
|
||||||
|
|
||||||
|
for (int x = 0; x < bs.state.Count; ++x) {
|
||||||
|
var col = bs[x];
|
||||||
|
|
||||||
|
bool foundAir = false;
|
||||||
|
for (int i = 0; i < col.Count; ++i) {
|
||||||
|
col[i] = col[i].SetFalling(foundAir);
|
||||||
|
if (col[i].isAir) foundAir = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, pad to length with air
|
||||||
|
while (col.Count < BoardState.BoardHeight)
|
||||||
|
col.Add(TileInfo.Air);
|
||||||
|
|
||||||
|
// Create an unlinked copy
|
||||||
|
var oldCol = col.Copy();
|
||||||
|
// Remove all air tiles
|
||||||
|
col.RemoveAll(t => t.isAir);
|
||||||
|
|
||||||
|
// Repad with air
|
||||||
|
while (col.Count < BoardState.BoardHeight)
|
||||||
|
col.Add(TileInfo.Air);
|
||||||
|
|
||||||
|
// TODO: Better falling logic
|
||||||
|
|
||||||
|
// Set the falling flag for drawing
|
||||||
|
/*for(int i = 0; i < col.Count; ++i) {
|
||||||
|
// Set the falling flag if we match
|
||||||
|
col[i] = col[i].SetFalling(i > lowestAir);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BoardState Place(this BoardState bs,Move m) {
|
||||||
|
var state = bs.SelfCopy();
|
||||||
|
|
||||||
|
var (first, second, third) = m.triplet;
|
||||||
|
|
||||||
|
// FIXME SetAtPoint is shite and doesn't work good??
|
||||||
|
|
||||||
|
state.SetAtPoint(m.location, first);
|
||||||
|
state.SetAtPoint(m.locationB, second);
|
||||||
|
state.SetAtPoint(m.locationC, third);
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set all matches tiledetails to pending
|
||||||
|
public static BoardState Activate(this BoardState bs, out int activations) {
|
||||||
|
activations = 0;
|
||||||
|
|
||||||
|
var expandedClusters = new List<Cluster>();
|
||||||
|
|
||||||
|
// First, determine if any column contains a match
|
||||||
|
for (int x = 0; x < bs.state.Count; ++x) {
|
||||||
|
var col = bs[x];
|
||||||
|
|
||||||
|
// Exit if there is no match in the column
|
||||||
|
if (!col.StackHasMatches())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We know there is a match in the column, get the coordinates of all valid clusters
|
||||||
|
var validBlobs = new List<Cluster>();
|
||||||
|
|
||||||
|
for (int y = 0; y < col.Count; ++y) {
|
||||||
|
var stackClusters = bs.ClusterizeVertical(x, y);
|
||||||
|
if (stackClusters != null && stackClusters.Count >= 3) {
|
||||||
|
validBlobs.Add(stackClusters);
|
||||||
|
} else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand matches horizontally to matches
|
||||||
|
foreach(var cluster in validBlobs) {
|
||||||
|
foreach(var point in cluster) {
|
||||||
|
expandedClusters.Add(bs.Clusterize(point.x,point.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(var cluster in expandedClusters) {
|
||||||
|
foreach(var point in cluster) {
|
||||||
|
var at = bs.TileAtPoint(point);
|
||||||
|
if (at == null || at.isPending)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
at.SetPending();
|
||||||
|
activations += 1; // Increment the activation counter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BoardState BreakPending(this BoardState bs, GameBoard gb, bool sendCallbacks = false) {
|
||||||
|
var broken = new Cluster();
|
||||||
|
for(int x = 0; x < bs.state.Count; ++x) {
|
||||||
|
var col = bs[x];
|
||||||
|
for (int y = 0; y < col.Count; ++y) {
|
||||||
|
var at = bs.tile(x, y);
|
||||||
|
|
||||||
|
if (at.isAir) continue; // Skip air
|
||||||
|
|
||||||
|
if (at.isPending) {
|
||||||
|
broken.Add((x, y));
|
||||||
|
|
||||||
|
if (sendCallbacks)
|
||||||
|
gb.BreakFX(x, y);
|
||||||
|
|
||||||
|
var brokenForm = at.BreakTile(gb.Options);
|
||||||
|
|
||||||
|
col[y] = brokenForm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break FX callbacks
|
||||||
|
if (Application.isPlaying && sendCallbacks)
|
||||||
|
foreach (var broke in broken)
|
||||||
|
gb.BreakFX(broke.x, broke.y);
|
||||||
|
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate the eventual outcome of this board
|
||||||
|
// Note this is NOT deterministic because of how random tiles break
|
||||||
|
public static BoardState SimulateRecursive(this BoardState bs, GameBoard gb, out int activations) {
|
||||||
|
activations = 0;
|
||||||
|
|
||||||
|
// Iterations for the current step
|
||||||
|
int stepActivations = 0;
|
||||||
|
do {
|
||||||
|
bs = bs.Collapse().Activate(out stepActivations).BreakPending(gb);
|
||||||
|
activations += stepActivations;
|
||||||
|
// Repeat until no new tiles activate
|
||||||
|
Debug.LogFormat("Processed {0} activations", stepActivations);
|
||||||
|
} while (stepActivations > 0);
|
||||||
|
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a copy of a column
|
||||||
|
static TileStack Copy(this TileStack ts) {
|
||||||
|
var intform = ts.Select(tile => (int)tile);
|
||||||
|
return intform.Select(tile => (TileInfo)tile).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (int x, int y) ToPair(this MoveDir md) {
|
||||||
|
switch(md) {
|
||||||
|
case MoveDir.Left:
|
||||||
|
return (-1, 0);
|
||||||
|
case MoveDir.Right:
|
||||||
|
return (1, 0);
|
||||||
|
case MoveDir.Up:
|
||||||
|
return (0, 1);
|
||||||
|
case MoveDir.Down:
|
||||||
|
return (0, -1);
|
||||||
|
default:
|
||||||
|
return (0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region moves
|
||||||
|
|
||||||
|
public enum MoveDir { None, Left, Right, Up, Down }
|
||||||
|
|
||||||
|
public class Move {
|
||||||
|
public (TileInfo first, TileInfo second, TileInfo third) triplet;
|
||||||
|
public (int x, int y) location;
|
||||||
|
|
||||||
|
public MoveDir first, second;
|
||||||
|
|
||||||
|
public (int x, int y) locationB {
|
||||||
|
get {
|
||||||
|
var (x, y) = first.ToPair();
|
||||||
|
return (location.x + x, location.y + y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public (int x, int y) locationC {
|
||||||
|
get {
|
||||||
|
var (x, y) = second.ToPair();
|
||||||
|
return (locationB.x + x, locationB.y + y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region BoardStates
|
#region BoardStates
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class BoardState {
|
public class BoardState {
|
||||||
public static readonly int BoardWidth = 4, BoardHeight = 9;
|
public static readonly int BoardWidth = 6, BoardHeight = 12;
|
||||||
// Top THREE rows of board are the placement zone
|
// Top THREE rows of board are the placement zone
|
||||||
|
|
||||||
// Internal state of the board, as a list
|
// Internal state of the board, as a list
|
||||||
|
@ -214,11 +634,30 @@ public class BoardState {
|
||||||
public bool TryCol(int col, out TileStack ts) {
|
public bool TryCol(int col, out TileStack ts) {
|
||||||
ts = null;
|
ts = null;
|
||||||
if (col < 0) return false;
|
if (col < 0) return false;
|
||||||
if (col > state.Count) return false;
|
if (col >= state.Count) return false;
|
||||||
ts = this[col];
|
ts = this[col];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public bool TileAt(int x, int y, out TileInfo ti) {
|
|
||||||
|
public TileInfo TileAtPoint((int x, int y) p) {
|
||||||
|
if (TryCol(p.x, out var col))
|
||||||
|
return col.NullPadded(p.y);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAtPoint((int x, int y) p, TileInfo tile) {
|
||||||
|
if (TryCol(p.x, out var col)) {
|
||||||
|
col.ChangeTile(p.x, tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the tile at a position with null if it's not valid
|
||||||
|
public TileInfo tile(int x, int y) {
|
||||||
|
TryTileAt(x, y, out var ti);
|
||||||
|
return ti;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryTileAt(int x, int y, out TileInfo ti) {
|
||||||
ti = null;
|
ti = null;
|
||||||
|
|
||||||
if (y < 0) return false; // fail out if asking for negative y coords
|
if (y < 0) return false; // fail out if asking for negative y coords
|
||||||
|
|
|
@ -32,6 +32,17 @@ public class GameBoardDrawer : MonoBehaviour {
|
||||||
|
|
||||||
List<List<TileDrawer>> TileDrawers;
|
List<List<TileDrawer>> TileDrawers;
|
||||||
|
|
||||||
|
// Get the Offset for an X/Y coord
|
||||||
|
public Vector3 Position(int x, int y) {
|
||||||
|
return new Vector3(x, y) * TileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TileDrawer this[int x, int y] {
|
||||||
|
get {
|
||||||
|
return TileDrawers[x][y];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public float TileSize = 0.5f;
|
public float TileSize = 0.5f;
|
||||||
|
|
||||||
void ValidateDrawers() {
|
void ValidateDrawers() {
|
||||||
|
@ -64,12 +75,26 @@ public class GameBoardDrawer : MonoBehaviour {
|
||||||
|
|
||||||
for (int x = 0; x < TileDrawers.Count; ++x) {
|
for (int x = 0; x < TileDrawers.Count; ++x) {
|
||||||
var col = TileDrawers[x];
|
var col = TileDrawers[x];
|
||||||
|
|
||||||
for (int y = 0; y < col.Count; ++y) {
|
for (int y = 0; y < col.Count; ++y) {
|
||||||
var tile = col[y];
|
var tile = col[y];
|
||||||
|
|
||||||
|
tile.board = gameBoard;
|
||||||
|
tile.xCoord = x;
|
||||||
|
tile.yCoord = y;
|
||||||
|
|
||||||
|
if (tile.board) {
|
||||||
|
var amt = tile.board.board.ClusterizeVertical(x, y);
|
||||||
|
|
||||||
|
if (amt != null) {
|
||||||
|
tile.amountInStack = amt.Count;
|
||||||
|
tile.stackedBelow = amt.Count(point => y > point.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var tileT = tile.transform;
|
var tileT = tile.transform;
|
||||||
tileT.localPosition = new Vector3(x, y) * TileSize;
|
tileT.localPosition = new Vector3(x, y, -y) * TileSize;
|
||||||
if (boardState.TileAt(x, y,out TileInfo ti)) {
|
if (boardState.TryTileAt(x, y,out TileInfo ti)) {
|
||||||
tile.toDraw = ti;
|
tile.toDraw = ti;
|
||||||
} else {
|
} else {
|
||||||
tile.toDraw = TileInfo.Air;
|
tile.toDraw = TileInfo.Air;
|
||||||
|
@ -93,6 +118,8 @@ public class GameBoardDrawer : MonoBehaviour {
|
||||||
foreach(var td in children) {
|
foreach(var td in children) {
|
||||||
DestroyImmediate(td.gameObject);
|
DestroyImmediate(td.gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TileDrawers = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update() {
|
void Update() {
|
||||||
|
|
|
@ -153,7 +153,7 @@ MonoBehaviour:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
TilePrefab: {fileID: 6929433238081324627, guid: 2d35555d89dd5e94fb9527d52c616c11,
|
TilePrefab: {fileID: 6929433238081324627, guid: 2d35555d89dd5e94fb9527d52c616c11,
|
||||||
type: 3}
|
type: 3}
|
||||||
TileSize: 0.5
|
TileSize: 1
|
||||||
--- !u!114 &20737163
|
--- !u!114 &20737163
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -168,7 +168,7 @@ MonoBehaviour:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
EntityID: 0
|
EntityID: 0
|
||||||
authorityID: -1
|
authorityID: -1
|
||||||
Options: 01020304
|
Options: 05020304
|
||||||
--- !u!4 &20737164
|
--- !u!4 &20737164
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -183,6 +183,194 @@ Transform:
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_RootOrder: 1
|
m_RootOrder: 1
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!1001 &122171322
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 5781547240168325573, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: PostProcessingObj
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_RootOrder
|
||||||
|
value: 3
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 0.14437793
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: -0.09988037
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: -86.22787
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 6561464763569930962, guid: bdd4386fa58e67142a500ae58dfb8f30,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: bdd4386fa58e67142a500ae58dfb8f30, type: 3}
|
||||||
|
--- !u!1001 &505291072
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 5701687554350559536, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: PaperTextureOverlay
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_Pivot.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_Pivot.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_RootOrder
|
||||||
|
value: 2
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_AnchorMax.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_AnchorMax.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_AnchorMin.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_AnchorMin.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_SizeDelta.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_SizeDelta.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_AnchoredPosition.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_AnchoredPosition.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 5701687554350559540, guid: ea69c30046595724aa7abcecd81deb32,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: ea69c30046595724aa7abcecd81deb32, type: 3}
|
||||||
--- !u!1 &1062404885
|
--- !u!1 &1062404885
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -194,6 +382,7 @@ GameObject:
|
||||||
- component: {fileID: 1062404888}
|
- component: {fileID: 1062404888}
|
||||||
- component: {fileID: 1062404887}
|
- component: {fileID: 1062404887}
|
||||||
- component: {fileID: 1062404886}
|
- component: {fileID: 1062404886}
|
||||||
|
- component: {fileID: 1062404889}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: Main Camera
|
m_Name: Main Camera
|
||||||
m_TagString: MainCamera
|
m_TagString: MainCamera
|
||||||
|
@ -219,7 +408,7 @@ Camera:
|
||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_ClearFlags: 1
|
m_ClearFlags: 1
|
||||||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
m_BackGroundColor: {r: 0.73333335, g: 0.69411767, b: 0.9568628, a: 0}
|
||||||
m_projectionMatrixMode: 1
|
m_projectionMatrixMode: 1
|
||||||
m_GateFitMode: 2
|
m_GateFitMode: 2
|
||||||
m_FOVAxisMode: 0
|
m_FOVAxisMode: 0
|
||||||
|
@ -259,10 +448,70 @@ Transform:
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 1062404885}
|
m_GameObject: {fileID: 1062404885}
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 2.2195444, y: 6.629975, z: -16.29866}
|
m_LocalPosition: {x: 5.16, y: 0, z: -27.14}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_RootOrder: 0
|
m_RootOrder: 0
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &1062404889
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1062404885}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 948f4100a11a5c24981795d21301da5c, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
volumeTrigger: {fileID: 1062404888}
|
||||||
|
volumeLayer:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 512
|
||||||
|
stopNaNPropagation: 1
|
||||||
|
finalBlitToCameraTarget: 0
|
||||||
|
antialiasingMode: 0
|
||||||
|
temporalAntialiasing:
|
||||||
|
jitterSpread: 0.75
|
||||||
|
sharpness: 0.25
|
||||||
|
stationaryBlending: 0.95
|
||||||
|
motionBlending: 0.85
|
||||||
|
subpixelMorphologicalAntialiasing:
|
||||||
|
quality: 2
|
||||||
|
fastApproximateAntialiasing:
|
||||||
|
fastMode: 0
|
||||||
|
keepAlpha: 0
|
||||||
|
fog:
|
||||||
|
enabled: 1
|
||||||
|
excludeSkybox: 1
|
||||||
|
debugLayer:
|
||||||
|
lightMeter:
|
||||||
|
width: 512
|
||||||
|
height: 256
|
||||||
|
showCurves: 1
|
||||||
|
histogram:
|
||||||
|
width: 512
|
||||||
|
height: 256
|
||||||
|
channel: 3
|
||||||
|
waveform:
|
||||||
|
exposure: 0.12
|
||||||
|
height: 256
|
||||||
|
vectorscope:
|
||||||
|
size: 256
|
||||||
|
exposure: 0.12
|
||||||
|
overlaySettings:
|
||||||
|
linearDepth: 0
|
||||||
|
motionColorIntensity: 4
|
||||||
|
motionGridSize: 64
|
||||||
|
colorBlindnessType: 0
|
||||||
|
colorBlindnessStrength: 1
|
||||||
|
m_Resources: {fileID: 11400000, guid: d82512f9c8e5d4a4d938b575d47f88d4, type: 2}
|
||||||
|
m_ShowToolkit: 0
|
||||||
|
m_ShowCustomSorter: 1
|
||||||
|
breakBeforeColorGrading: 0
|
||||||
|
m_BeforeTransparentBundles: []
|
||||||
|
m_BeforeStackBundles: []
|
||||||
|
m_AfterStackBundles: []
|
||||||
|
|
|
@ -13,12 +13,8 @@ MonoBehaviour:
|
||||||
m_Name: GreenTiles
|
m_Name: GreenTiles
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
color: 3
|
color: 3
|
||||||
Generic: {fileID: -6936698821596298334, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
Generic: {fileID: 21300000, guid: 9566535b9396c87478e4136306d2b403, type: 3}
|
||||||
type: 3}
|
TopOfStack: {fileID: 21300000, guid: 140777d948797cb40af3dc7395ed71ee, type: 3}
|
||||||
TopOfStack: {fileID: 6772703886551230350, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
SecondFromTop: {fileID: 21300000, guid: 348d7f7284aa1664d8aa79701899ff7b, type: 3}
|
||||||
type: 3}
|
ThirdOrLower: {fileID: 21300000, guid: a4cbdd75e62afa74cb38d3c8753cb92b, type: 3}
|
||||||
SecondFromTop: {fileID: -6218849779353356174, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
|
||||||
type: 3}
|
|
||||||
ThirdOrLower: {fileID: 4496032024674485847, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
|
||||||
type: 3}
|
|
||||||
Puff: {fileID: 8143975012507443829, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
Puff: {fileID: 8143975012507443829, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
||||||
|
|
|
@ -13,11 +13,8 @@ MonoBehaviour:
|
||||||
m_Name: PinkTiles
|
m_Name: PinkTiles
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
color: 4
|
color: 4
|
||||||
Generic: {fileID: 4141482394071947919, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
Generic: {fileID: 21300000, guid: 1b97e1e3f1b18d34f8c777342f256647, type: 3}
|
||||||
TopOfStack: {fileID: 4445955820842774327, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
TopOfStack: {fileID: 21300000, guid: 3e5c55736df32154eaccf5510d384607, type: 3}
|
||||||
type: 3}
|
SecondFromTop: {fileID: 21300000, guid: 0c4002562d486634ea5849d207859268, type: 3}
|
||||||
SecondFromTop: {fileID: -8603880206502384168, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
ThirdOrLower: {fileID: 21300000, guid: 47ebbb6720c25c74793be75e54de86a1, type: 3}
|
||||||
type: 3}
|
|
||||||
ThirdOrLower: {fileID: 7082931030690222455, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
|
||||||
type: 3}
|
|
||||||
Puff: {fileID: -3766147651135259226, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
Puff: {fileID: -3766147651135259226, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
||||||
|
|
|
@ -13,12 +13,8 @@ MonoBehaviour:
|
||||||
m_Name: PurpleTiles
|
m_Name: PurpleTiles
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
color: 5
|
color: 5
|
||||||
Generic: {fileID: -7185840347270642116, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
Generic: {fileID: 21300000, guid: fd410fcb15200c24b8e224bd43d9b34e, type: 3}
|
||||||
type: 3}
|
TopOfStack: {fileID: 21300000, guid: 01ebca9ab57daed44817d6874413894c, type: 3}
|
||||||
TopOfStack: {fileID: -6426366480920576982, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
SecondFromTop: {fileID: 21300000, guid: 6db51e61120de314eae63fbbc695c36a, type: 3}
|
||||||
type: 3}
|
ThirdOrLower: {fileID: 21300000, guid: 2d454fbd08c411f4396875af4c1904ed, type: 3}
|
||||||
SecondFromTop: {fileID: 2523502825781429886, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
|
||||||
type: 3}
|
|
||||||
ThirdOrLower: {fileID: 4109463514366588313, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
|
||||||
type: 3}
|
|
||||||
Puff: {fileID: -316062629822355126, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
Puff: {fileID: -316062629822355126, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
||||||
|
|
|
@ -10,7 +10,7 @@ MonoBehaviour:
|
||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
m_EditorHideFlags: 0
|
m_EditorHideFlags: 0
|
||||||
m_Script: {fileID: 11500000, guid: fb5a560c08dbb0c4480cebd43af4d199, type: 3}
|
m_Script: {fileID: 11500000, guid: fb5a560c08dbb0c4480cebd43af4d199, type: 3}
|
||||||
m_Name: RedTiles
|
m_Name: RedTiles-Unused
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
color: 1
|
color: 1
|
||||||
Generic: {fileID: -8095011478633053862, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
Generic: {fileID: -8095011478633053862, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
|
@ -10,14 +10,11 @@ MonoBehaviour:
|
||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
m_EditorHideFlags: 0
|
m_EditorHideFlags: 0
|
||||||
m_Script: {fileID: 11500000, guid: fb5a560c08dbb0c4480cebd43af4d199, type: 3}
|
m_Script: {fileID: 11500000, guid: fb5a560c08dbb0c4480cebd43af4d199, type: 3}
|
||||||
m_Name: BlueTiles
|
m_Name: YellowTiles
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
color: 2
|
color: 2
|
||||||
Generic: {fileID: 3099831667949783345, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
Generic: {fileID: 21300000, guid: d583fe4b25f546e4d95c78f04db4199f, type: 3}
|
||||||
TopOfStack: {fileID: -1032256510885150944, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
TopOfStack: {fileID: 21300000, guid: a738f6c420ba63347b26f1c9de9c6e25, type: 3}
|
||||||
type: 3}
|
SecondFromTop: {fileID: 21300000, guid: 6a16bb885cf35b241a6335e8dd39530a, type: 3}
|
||||||
SecondFromTop: {fileID: -8030095101517931983, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
ThirdOrLower: {fileID: 21300000, guid: 27a7c767ef7e75247acff9391d1fe434, type: 3}
|
||||||
type: 3}
|
|
||||||
ThirdOrLower: {fileID: 7642638768051401269, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
|
||||||
type: 3}
|
|
||||||
Puff: {fileID: 6779516872222990126, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
Puff: {fileID: 6779516872222990126, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
|
@ -18,18 +18,15 @@ MonoBehaviour:
|
||||||
- {fileID: 11400000, guid: 196941731704d204f885aa54cbb5b8bf, type: 2}
|
- {fileID: 11400000, guid: 196941731704d204f885aa54cbb5b8bf, type: 2}
|
||||||
- {fileID: 11400000, guid: 23186780cfc3a1347acd561444139cc7, type: 2}
|
- {fileID: 11400000, guid: 23186780cfc3a1347acd561444139cc7, type: 2}
|
||||||
- {fileID: 11400000, guid: 0922e1e6b1ed5124ca13b943384610ee, type: 2}
|
- {fileID: 11400000, guid: 0922e1e6b1ed5124ca13b943384610ee, type: 2}
|
||||||
IceOverlay: {fileID: -5160244557152387853, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
IceOverlay: {fileID: 21300000, guid: 0c2a57034be842040bacf04045786b0d, type: 3}
|
||||||
type: 3}
|
FairyUnderlay: {fileID: 21300000, guid: acf1dd9a34148b3468417c36b62aac52, type: 3}
|
||||||
FairyUnderlay: {fileID: -5868263060078136879, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
Tanuki: {fileID: 21300000, guid: 442974598bf95ca4596b9db79b82ca71, type: 3}
|
||||||
type: 3}
|
Rock: {fileID: 21300000, guid: 67c5c125cfa5558468d3b69f8d7c175c, type: 3}
|
||||||
Tanuki: {fileID: 3630433040384085778, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
Seal: {fileID: 21300000, guid: a347288d47d726c4a93402f569dc9b41, type: 3}
|
||||||
Rock: {fileID: -7609849284663780198, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
Bomb: {fileID: 21300000, guid: 6e09953987bbbfc458d5c643f17c2737, type: 3}
|
||||||
Seal: {fileID: -2297644416909811431, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
Dynamite: {fileID: 21300000, guid: c5ee0016dc8866e408bb21bb418601cd, type: 3}
|
||||||
Bomb: {fileID: -6920159131614611936, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
|
||||||
Dynamite: {fileID: 5530267107363011928, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
|
||||||
type: 3}
|
|
||||||
Mystery: {fileID: -4610881938015499699, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
Mystery: {fileID: -4610881938015499699, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
||||||
type: 3}
|
type: 3}
|
||||||
Spark: {fileID: -4610881938015499699, guid: ba7046a7d637abc4ba486e3e9e4fcfd3, type: 3}
|
Spark: {fileID: 21300000, guid: cb007da673cac344fa5b62e18ad37492, type: 3}
|
||||||
Explosion: {fileID: -4610881938015499699, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
Explosion: {fileID: -4610881938015499699, guid: ba7046a7d637abc4ba486e3e9e4fcfd3,
|
||||||
type: 3}
|
type: 3}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
[ExecuteAlways]
|
[ExecuteAlways]
|
||||||
|
@ -8,11 +9,36 @@ public class TileDrawer : MonoBehaviour {
|
||||||
public TileSetInfo tsi;
|
public TileSetInfo tsi;
|
||||||
public TileInfo toDraw;
|
public TileInfo toDraw;
|
||||||
|
|
||||||
|
[Header("Internally Managed")]
|
||||||
|
public GameBoard board; // Gameboard associated with us
|
||||||
|
public int xCoord, yCoord;
|
||||||
|
|
||||||
[Header("Tile Info Testing")]
|
[Header("Tile Info Testing")]
|
||||||
//[EnumFlag] No idea why this isn't working anymore whatever
|
//[EnumFlag] No idea why this isn't working anymore whatever
|
||||||
public TileDetail detail = TileDetail.Normal;
|
public TileDetail detail = TileDetail.Normal;
|
||||||
public TileColor color;
|
public TileColor color;
|
||||||
|
|
||||||
|
// TODO Use this FX hook
|
||||||
|
// This is called BEFORE the tile detail is updated
|
||||||
|
public void OnBreakFX() {
|
||||||
|
// Texel - Little test diagonal debug line :)
|
||||||
|
Debug.DrawLine(
|
||||||
|
transform.TransformPoint(new Vector3(1, 1)),
|
||||||
|
transform.TransformPoint(new Vector3(-1, -1)),
|
||||||
|
Color.red,
|
||||||
|
1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updated while the tile state is pending, that is, ready to be removed
|
||||||
|
public void UpdatePending() {
|
||||||
|
// Stacks warble at similar frequency, columns independently
|
||||||
|
float phaseOffset = 0.8f * xCoord + 0.03f * yCoord;
|
||||||
|
float warbleSpeed = 8f;
|
||||||
|
// Warble 5% of scale
|
||||||
|
float warble = Mathf.Sin((Time.time + phaseOffset) * warbleSpeed) * 0.05f;
|
||||||
|
transform.localScale = new Vector3(1 + warble, 1 - warble, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void OnValidate() {
|
void OnValidate() {
|
||||||
if (toDraw == null) {
|
if (toDraw == null) {
|
||||||
toDraw = new TileInfo(color,detail);
|
toDraw = new TileInfo(color,detail);
|
||||||
|
@ -87,7 +113,7 @@ public class TileDrawer : MonoBehaviour {
|
||||||
|
|
||||||
// Shift smeared sub-sprite to position
|
// Shift smeared sub-sprite to position
|
||||||
layer.transform.localPosition =
|
layer.transform.localPosition =
|
||||||
new Vector3(0, delta * SmearDistance, 0);
|
new Vector3(0, delta * SmearDistance, i * 0.001f * SmearSteps);
|
||||||
|
|
||||||
// Set the smear opacity
|
// Set the smear opacity
|
||||||
var layerOpacity = opacity * opacityShift * (1 - delta);
|
var layerOpacity = opacity * opacityShift * (1 - delta);
|
||||||
|
@ -139,10 +165,24 @@ public class TileDrawer : MonoBehaviour {
|
||||||
if (!tsi) return;
|
if (!tsi) return;
|
||||||
if (toDraw == null) return;
|
if (toDraw == null) return;
|
||||||
|
|
||||||
|
// Higher tiles draw in front
|
||||||
|
//var t = transform;
|
||||||
|
//t.LeanSetPosZ(-t.position.y);
|
||||||
|
|
||||||
// Copy the data from the TileInfo reference to local enums
|
// Copy the data from the TileInfo reference to local enums
|
||||||
color = toDraw.color;
|
color = toDraw.color;
|
||||||
detail = toDraw.detail;
|
detail = toDraw.detail;
|
||||||
|
|
||||||
|
// Set the drop smear visibility
|
||||||
|
// Fade out over time when playing
|
||||||
|
if (detail.HasFlag(TileDetail.Dropped)){
|
||||||
|
smearOpacity = 1f;
|
||||||
|
} else {
|
||||||
|
smearOpacity = !Application.isPlaying ?
|
||||||
|
0f :
|
||||||
|
Mathf.MoveTowards(smearOpacity,0f,Time.deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
var sr = GetComponent<SpriteRenderer>();
|
var sr = GetComponent<SpriteRenderer>();
|
||||||
if (!sr) sr = gameObject.AddComponent<SpriteRenderer>();
|
if (!sr) sr = gameObject.AddComponent<SpriteRenderer>();
|
||||||
|
|
||||||
|
@ -154,7 +194,7 @@ public class TileDrawer : MonoBehaviour {
|
||||||
if (deets != null) {
|
if (deets != null) {
|
||||||
sprite = deets.Generic;
|
sprite = deets.Generic;
|
||||||
// Base of stack
|
// Base of stack
|
||||||
if (amountInStack != 0) {
|
if (amountInStack > 2) {
|
||||||
sprite = deets.ThirdOrLower;
|
sprite = deets.ThirdOrLower;
|
||||||
if (stackedBelow == 1)
|
if (stackedBelow == 1)
|
||||||
sprite = deets.SecondFromTop;
|
sprite = deets.SecondFromTop;
|
||||||
|
@ -162,10 +202,17 @@ public class TileDrawer : MonoBehaviour {
|
||||||
sprite = deets.TopOfStack;
|
sprite = deets.TopOfStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// non-snowman-y states
|
// non-snowman-y states
|
||||||
if (detail.HasFlag(TileDetail.Poofed))
|
if (detail.HasFlag(TileDetail.Poofed))
|
||||||
sprite = deets.Puff;
|
sprite = deets.Puff;
|
||||||
|
|
||||||
|
if (Application.isPlaying)
|
||||||
|
if (detail.HasFlag(TileDetail.Pending)) {
|
||||||
|
UpdatePending();
|
||||||
|
} else {
|
||||||
|
transform.localScale = Vector3.one;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// no matching TileObject data
|
// no matching TileObject data
|
||||||
switch (color) {
|
switch (color) {
|
||||||
|
|
Loading…
Reference in New Issue