/** * Updates every tile in the tilemap */ private void UpdateAllTileAdjacencies() { // Once they are all made go through and update all adjacencies. var adjacentTiles = new TileDefinition[8]; foreach (var item in tiles) { int x = (int)(item.Key & 0xffff); int y = (int)(item.Key >> 32); // Find each adjacent tile and put into a map for (Direction direction = Direction.North; direction <= Direction.NorthWest; direction++) { // Take the cardinal direction, but use it in negative, so direction means the direction from OTHER to the just updated tile. var modifier = DirectionHelper.ToCardinalVector(direction); if (y + modifier.Item2 < 0 || x + modifier.Item1 < 0) { adjacentTiles[(int)direction] = TileDefinition.NullObject; } ulong otherKey = GetKey(x + modifier.Item1, y + modifier.Item2); if (tiles.ContainsKey(otherKey)) { adjacentTiles[(int)direction] = tiles[otherKey].Tile; } else { adjacentTiles[(int)direction] = TileDefinition.NullObject; } } item.Value.UpdateAllAdjacencies(adjacentTiles); } }
private void RpcUpdateTile(int x, int y, TileDefinition definition) { if (!isServer) { InternalUpdateTile(x, y, definition); } }
/** * Call UpdateSingleAdjacency on every tile adjacent to the provided one. * * Returns adjacent tiles which may be used to update the central tile */ private TileDefinition[] GetAndUpdateAdjacentTiles(int x, int y, TileDefinition tileInfo) { TileDefinition[] adjacents = new TileDefinition[8]; // Then go for each adjacent and update for (Direction direction = Direction.North; direction <= Direction.NorthWest; direction++) { // Take the cardinal direction, but use it in negative, so direction means the direction from OTHER to the just updated tile. var modifier = DirectionHelper.ToCardinalVector(direction); if (y + modifier.Item2 < 0 || x + modifier.Item1 < 0) { continue; } ulong otherKey = GetKey(x + modifier.Item1, y + modifier.Item2); if (tiles.ContainsKey(otherKey)) { adjacents[(int)direction] = tiles[otherKey].Tile; tiles[otherKey].UpdateSingleAdjacency(DirectionHelper.GetOpposite(direction), tileInfo); } } return(adjacents); }
/* * The internals contain the actual logic of the above functions. They aren't put in the * public method as the public method needs to have warnings when not called from server */ private void InternalCreateTile(int x, int y, TileDefinition definition) { ulong key = GetKey(x, y); if (tiles.ContainsKey(key)) { var message = "Tried to create tile that already exists at position" + GetPosition(x, y).ToString() + ", index [" + x.ToString() + ", " + y.ToString() + "]"; Debug.LogError(message); throw new Exception(message); } var tileObject = SpawnTileObject(x, y); tiles[key] = tileObject; tileObject.Tile = definition; var adjacents = GetAndUpdateAdjacentTiles(x, y, definition); tileObject.UpdateAllAdjacencies(adjacents); // Run on every client. if (Application.isPlaying && isServer) { RpcCreateTile(x, y, definition); } }
public Fixture GetFixtureAtLayerIndex(int index) { int offsetFloor = TileDefinition.GetTileFixtureLayerSize(); int offsetWall = TileDefinition.GetWallFixtureLayerSize(); int offsetTotal = offsetFloor + offsetWall + TileDefinition.GetFloorFixtureLayerSize(); if (index < offsetFloor) { // We are a Tile fixture return(GetTileFixtureAtLayer((TileFixtureLayers)index)); } else if (index >= offsetFloor && index < offsetWall) { // We are a Wall fixture return(GetWallFixtureAtLayer((WallFixtureLayers)(index - offsetFloor))); } else if (index >= offsetWall && index < offsetTotal) { // We are a Floor fixture return(GetFloorFixtureAtLayer((FloorFixtureLayers)(index - offsetFloor - offsetWall))); } else { Debug.LogError("Requesting out of index Fixture"); } return(null); }
public static TileDefinition ReadNetworkableTileDefinition(this NetworkReader reader) { TileDefinition tileDefinition = new TileDefinition(); string turfName = reader.ReadString(); string fixtureName = reader.ReadString(); if (!string.IsNullOrEmpty(turfName)) { tileDefinition.turf = turfs.FirstOrDefault(turf => turf.name == turfName); if (tileDefinition.turf == null) { Debug.LogError($"Network recieved turf with name {turfName} could not be found"); } } if (!string.IsNullOrEmpty(fixtureName)) { tileDefinition.fixture = fixtures.FirstOrDefault(fixture => fixture.name == fixtureName); if (tileDefinition.fixture == null) { Debug.LogError($"Network recieved fixture with name {fixtureName} could not be found"); } } // If the boolean is false, subStates should be null. if (reader.ReadBoolean()) { using (var stream = new MemoryStream(reader.ReadBytesAndSize())) { tileDefinition.subStates = new BinaryFormatter().Deserialize(stream) as object[]; } } return(tileDefinition); }
public void SetFixtureAtIndex(Fixture fixture, int index) { int offsetFloor = TileDefinition.GetTileFixtureLayerSize(); int offsetWall = TileDefinition.GetWallFixtureLayerSize(); int offsetTotal = offsetFloor + offsetWall + TileDefinition.GetFloorFixtureLayerSize(); if (index < offsetFloor) { // We are a Tile fixture SetTileFixtureAtLayer((TileFixture)fixture, (TileFixtureLayers)index); } else if (index >= offsetFloor && index < (offsetFloor + offsetWall)) { // We are a Wall fixture SetWallFixtureAtLayer((WallFixture)fixture, (WallFixtureLayers)(index - offsetFloor)); } else if (index >= (offsetFloor + offsetWall) && index < offsetTotal) { // We are a Floor fixture SetFloorFixtureAtLayer((FloorFixture)fixture, (FloorFixtureLayers)(index - offsetFloor - offsetWall)); } else { Debug.LogError("Requesting out of index Fixture"); } }
public static TileDefinition ReadNetworkableTileDefinition(this NetworkReader reader) { TileDefinition tileDefinition = new TileDefinition(); tileDefinition.fixtures = new Fixture[TileDefinition.GetFixtureLayerSize()]; var layers = (FixtureLayers[])Enum.GetValues(typeof(FixtureLayers)); // Read plenum string plenumName = reader.ReadString(); if (!string.IsNullOrEmpty(plenumName)) { tileDefinition.plenum = plenums.FirstOrDefault(plenum => plenum.name == plenumName); if (tileDefinition.plenum == null) { Debug.LogError($"Network recieved plenum with name {plenumName} could not be found"); } } // Read turf string turfName = reader.ReadString(); if (!string.IsNullOrEmpty(turfName)) { tileDefinition.turf = turfs.FirstOrDefault(turf => turf.name == turfName); if (tileDefinition.turf == null) { Debug.LogError($"Network recieved turf with name {turfName} could not be found"); } } // Read fixtures foreach (FixtureLayers layer in layers) { string fixtureName = reader.ReadString(); if (!string.IsNullOrEmpty(fixtureName)) { tileDefinition.fixtures[(int)layer] = fixtures.FirstOrDefault(fixture => fixture.name == fixtureName); if (tileDefinition.fixtures[(int)layer] == null) { Debug.LogError($"Network recieved fixture with name {fixtureName} could not be found"); } } } // If the boolean is false, subStates should be null. if (reader.ReadBoolean()) { using (var stream = new MemoryStream(reader.ReadBytesAndSize())) { tileDefinition.subStates = new BinaryFormatter().Deserialize(stream) as object[]; } } // TODO: Should substates be initialized to null array? return(tileDefinition); }
public static void WriteNetworkableTileDefinition(this NetworkWriter writer, TileDefinition definition) { writer.WriteString(definition.turf?.name ?? ""); writer.WriteString(definition.fixture?.name ?? ""); // Use C# serializer to serialize the object array, cos the Mirror one isn't powerful enough. // Can't serialize null values so put a boolean indicating array presence first writer.WriteBoolean(definition.subStates != null); if (definition.subStates == null) { return; } using (var stream = new MemoryStream()) { new BinaryFormatter().Serialize(stream, definition.subStates); writer.WriteBytesAndSize(stream.ToArray()); } }
public Fixture[] GetAllFixtures() { List <Fixture> fixtures = new List <Fixture>(); foreach (TileFixtureLayers layer in TileDefinition.GetTileFixtureLayerNames()) { fixtures.Add(GetTileFixtureAtLayer(layer)); } foreach (WallFixtureLayers layer in TileDefinition.GetWallFixtureLayerNames()) { fixtures.Add(GetWallFixtureAtLayer(layer)); } foreach (FloorFixtureLayers layer in TileDefinition.GetFloorFixtureLayerNames()) { fixtures.Add(GetFloorFixtureAtLayer(layer)); } return(fixtures.ToArray()); }
private void InternalUpdateTile(int x, int y, TileDefinition definition) { ulong key = GetKey(x, y); if (!tiles.ContainsKey(key)) { throw new Exception("Tried to update tile that doesn't exist at position" + GetPosition(x, y).ToString() + ", index [" + x.ToString() + ", " + y.ToString() + "]"); } var obj = tiles[key]; obj.Tile = definition; var adjacents = GetAndUpdateAdjacentTiles(x, y, definition); obj.UpdateAllAdjacencies(adjacents); if (Application.isPlaying && isServer) { RpcUpdateTile(x, y, definition); } }
// TODO: This could be made more efficient. Especially when the subStates are all nulls. public static void WriteNetworkableTileDefinition(this NetworkWriter writer, TileDefinition definition) { // Write plenum writer.WriteString(definition.plenum?.name ?? ""); // Write turf writer.WriteString(definition.turf?.name ?? ""); // Write all fixtures foreach (Fixture fixture in definition.fixtures) { if (fixture) { writer.WriteString(fixture.name ?? ""); } else { writer.WriteString(""); } } // Use C# serializer to serialize the object array, cos the Mirror one isn't powerful enough. // Can't serialize null values so put a boolean indicating array presence first if (definition.subStates == null || definition.subStates.All(obj => obj == null)) { writer.WriteBoolean(false); } else { writer.WriteBoolean(true); using (var stream = new MemoryStream()) { new BinaryFormatter().Serialize(stream, definition.subStates); writer.WriteBytesAndSize(stream.ToArray()); } } }
public void UpdateTile(Vector3 position, TileDefinition tileInfo) { var index = GetIndexAt(position); UpdateTile(index.x, index.y, tileInfo); }
private void CmdUpdateTile(int x, int y, TileDefinition definition) => tileManager.UpdateTile(x, y, definition);
public void UpdateTile(TileObject tile, TileDefinition definition) { var pos = tileManager.GetIndexAt(tile.transform.position); CmdUpdateTile(pos.x, pos.y, definition); }
public void CreateTile(Vector3 position, TileDefinition definition) { var index = GetIndexAt(position); CreateTile(index.x, index.y, definition); }
public void CreateTile(int x, int y, TileDefinition definition) => InternalCreateTile(x, y, definition);
// Remove the selection if the option is impossible // For example: tables cannot be build in walls, or wall fixtures cannot be build on floors public static TileDefinition ValidateFixtures(TileDefinition tileDefinition) { bool altered = false; string reason = ""; // If lattice, remove tile fixtures if (tileDefinition.plenum.name.Contains("Lattice")) { foreach (TileFixtureLayers layer in TileDefinition.GetTileFixtureLayerNames()) { if (tileDefinition.fixtures.GetTileFixtureAtLayer(layer) != null) { altered = true; tileDefinition.fixtures.SetTileFixtureAtLayer(null, layer); } } if (altered) { reason += "Lattices do not support any wall/floor fixture.\n"; } } if (((tileDefinition.turf != null && tileDefinition.turf.isWall) || tileDefinition.turf == null) && tileDefinition.plenum.name.Contains("Lattice")) { // Remove floor fixtures foreach (FloorFixtureLayers layer in TileDefinition.GetFloorFixtureLayerNames()) { if (tileDefinition.fixtures.GetFloorFixtureAtLayer(layer) != null) { altered = true; reason += "Cannot set a floor fixture on lattice.\n"; Debug.Log("Cannot set a floor fixture on lattice"); tileDefinition.fixtures.SetFloorFixtureAtLayer(null, layer); } } } if ((tileDefinition.turf != null && !tileDefinition.turf.isWall) || tileDefinition.turf == null || tileDefinition.plenum.name.Contains("Lattice")) { // Remove wall fixtures foreach (WallFixtureLayers layer in TileDefinition.GetWallFixtureLayerNames()) { if (tileDefinition.fixtures.GetWallFixtureAtLayer(layer) != null) { altered = true; reason += "Cannot set a wall fixture when there is no wall.\n"; Debug.Log("Cannot set a wall fixture when there is no wall"); } tileDefinition.fixtures.SetWallFixtureAtLayer(null, layer); } } // Prevent low wall mounts on glass walls and reinforced glass walls if (tileDefinition.turf != null && tileDefinition.turf.isWall && tileDefinition.turf.name.Contains("GlassWall")) { foreach (WallFixtureLayers layer in TileDefinition.GetWallFixtureLayerNames()) { if (layer == WallFixtureLayers.LowWallNorth || layer == WallFixtureLayers.LowWallEast || layer == WallFixtureLayers.LowWallSouth || layer == WallFixtureLayers.LowWallWest) { if (tileDefinition.fixtures.GetWallFixtureAtLayer(layer) != null) { altered = true; reason += "Glass walls do not allow low wall fixtures.\n"; tileDefinition.fixtures.SetWallFixtureAtLayer(null, layer); } } } } // Restrict pipes to their own layer TileFixture pipe = tileDefinition.fixtures.GetTileFixtureAtLayer(TileFixtureLayers.Pipe1); if (pipe != null && !pipe.name.Contains("1")) { altered = true; tileDefinition.fixtures.SetTileFixtureAtLayer(null, TileFixtureLayers.Pipe1); } pipe = tileDefinition.fixtures.GetTileFixtureAtLayer(TileFixtureLayers.Pipe2); if (pipe != null && !pipe.name.Contains("2")) { altered = true; tileDefinition.fixtures.SetTileFixtureAtLayer(null, TileFixtureLayers.Pipe2); } pipe = tileDefinition.fixtures.GetTileFixtureAtLayer(TileFixtureLayers.Pipe3); if (pipe != null && !pipe.name.Contains("3")) { altered = true; tileDefinition.fixtures.SetTileFixtureAtLayer(null, TileFixtureLayers.Pipe3); } #if UNITY_EDITOR if (altered) { EditorUtility.DisplayDialog("Fixture combination", "Invalid because of the following: \n\n" + reason + "\n" + "Definition has been reset.", "ok"); } #endif return(tileDefinition); }
public void EditorUpdateTile(int x, int y, TileDefinition definition) => InternalUpdateTile(x, y, definition);
public static TileDefinition ReadNetworkableTileDefinition(this NetworkReader reader) { TileDefinition tileDefinition = new TileDefinition(); tileDefinition.fixtures = new FixturesContainer(); // Read plenum string plenumName = reader.ReadString(); if (!string.IsNullOrEmpty(plenumName)) { tileDefinition.plenum = plenums.FirstOrDefault(plenum => plenum.name == plenumName); if (tileDefinition.plenum == null) { Debug.LogError($"Network recieved plenum with name {plenumName} could not be found"); } } // Read turf string turfName = reader.ReadString(); if (!string.IsNullOrEmpty(turfName)) { tileDefinition.turf = turfs.FirstOrDefault(turf => turf.name == turfName); if (tileDefinition.turf == null) { Debug.LogError($"Network recieved turf with name {turfName} could not be found"); } } // Read tile fixtures foreach (TileFixtureLayers layer in TileDefinition.GetTileFixtureLayerNames()) { string fixtureName = reader.ReadString(); if (!string.IsNullOrEmpty(fixtureName)) { TileFixture tf = (TileFixture)fixtures.FirstOrDefault(fixture => fixture.name == fixtureName); tileDefinition.fixtures.SetTileFixtureAtLayer(tf, layer); if (tf == null) { Debug.LogError($"Network recieved fixture with name {fixtureName} could not be found"); } } } // Read wall fixtures foreach (WallFixtureLayers layer in TileDefinition.GetWallFixtureLayerNames()) { string fixtureName = reader.ReadString(); if (!string.IsNullOrEmpty(fixtureName)) { WallFixture wf = (WallFixture)fixtures.FirstOrDefault(fixture => fixture.name == fixtureName); tileDefinition.fixtures.SetWallFixtureAtLayer(wf, layer); if (wf == null) { Debug.LogError($"Network recieved fixture with name {fixtureName} could not be found"); } } } // Read floor fixtures foreach (FloorFixtureLayers layer in TileDefinition.GetFloorFixtureLayerNames()) { string fixtureName = reader.ReadString(); if (!string.IsNullOrEmpty(fixtureName)) { FloorFixture ff = (FloorFixture)fixtures.FirstOrDefault(fixture => fixture.name == fixtureName); tileDefinition.fixtures.SetFloorFixtureAtLayer(ff, layer); if (ff == null) { Debug.LogError($"Network recieved fixture with name {fixtureName} could not be found"); } } } // If the boolean is false, subStates should be null. if (reader.ReadBoolean()) { using (var stream = new MemoryStream(reader.ReadBytesAndSize())) { tileDefinition.subStates = new BinaryFormatter().Deserialize(stream) as object[]; } } // TODO: Should substates be initialized to null array? return(tileDefinition); }