예제 #1
0
        /**
         * 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);
            }
        }
예제 #2
0
 private void RpcUpdateTile(int x, int y, TileDefinition definition)
 {
     if (!isServer)
     {
         InternalUpdateTile(x, y, definition);
     }
 }
예제 #3
0
        /**
         * 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);
        }
예제 #4
0
        /*
         * 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);
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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");
            }
        }
예제 #8
0
파일: TileManager.cs 프로젝트: soyboi/SS3D
        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);
        }
예제 #9
0
        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());
            }
        }
예제 #10
0
        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());
        }
예제 #11
0
        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);
            }
        }
예제 #12
0
파일: TileManager.cs 프로젝트: soyboi/SS3D
        // 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());
                }
            }
        }
예제 #13
0
        public void UpdateTile(Vector3 position, TileDefinition tileInfo)
        {
            var index = GetIndexAt(position);

            UpdateTile(index.x, index.y, tileInfo);
        }
예제 #14
0
 private void CmdUpdateTile(int x, int y, TileDefinition definition) => tileManager.UpdateTile(x, y, definition);
예제 #15
0
        public void UpdateTile(TileObject tile, TileDefinition definition)
        {
            var pos = tileManager.GetIndexAt(tile.transform.position);

            CmdUpdateTile(pos.x, pos.y, definition);
        }
예제 #16
0
        public void CreateTile(Vector3 position, TileDefinition definition)
        {
            var index = GetIndexAt(position);

            CreateTile(index.x, index.y, definition);
        }
예제 #17
0
 public void CreateTile(int x, int y, TileDefinition definition) => InternalCreateTile(x, y, definition);
예제 #18
0
        // 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);
        }
예제 #19
0
 public void EditorUpdateTile(int x, int y, TileDefinition definition) => InternalUpdateTile(x, y, definition);
예제 #20
0
        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);
        }