/// <summary>
        /// Returns true if all chunks that belong to the given area master chunk, extended by the given value, are currently loaded.
        /// </summary>
        /// <param name="areaMasterChunk">The area master chunk to use as basis</param>
        /// <param name="extendBy">Number of chunks to extend the check area in all directions, additionally to the 5x5 area master</param>
        private bool AllChunksLoaded([NotNull] Chunk areaMasterChunk, int extendBy)
        {
            if (World.ChunkCache == null)
            {
                return(false);
            }

            if (!areaMasterChunk.IsAreaMaster())
            {
                throw new ArgumentException("Given chunk is not an area master chunk.", nameof(areaMasterChunk));
            }

            lock (World.ChunkCache.GetSyncRoot())
            {
                for (int x = areaMasterChunk.X - extendBy; x < areaMasterChunk.X + Chunk.cAreaMasterSizeChunks + extendBy; x++)
                {
                    for (int z = areaMasterChunk.Z - extendBy; z < areaMasterChunk.Z + Chunk.cAreaMasterSizeChunks + extendBy; z++)
                    {
                        if (!World.ChunkCache.ContainsChunkSync(WorldChunkCache.MakeChunkKey(x, z, areaMasterChunk.ClrIdx)))
                        {
                            return(false);
                        }
                    }
                }
            }
            return(true);
        }
Example #2
0
        public static bool Prefix(long _key, bool _bDisplayed)
        {
            if (DistantTerrain.Instance == null)
            {
                return(true);
            }

            ChunkCluster chunkCluster = GameManager.Instance.World.ChunkClusters[0];

            if (chunkCluster == null)
            {
                return(true);
            }

            if (!GameManager.IsSplatMapAvailable())
            {
                Chunk chunkSync = chunkCluster.GetChunkSync(_key);
                if (_bDisplayed && chunkSync != null && chunkSync.NeedsOnlyCollisionMesh)
                {
                    return(true);
                }

                DistantTerrain.Instance.ActivateChunk(WorldChunkCache.extractX(_key), WorldChunkCache.extractZ(_key), !_bDisplayed);
                return(false);
            }
            return(true);
        }
Example #3
0
        public static bool Execute(ClientInfo sender, List <string> arguments)
        {
            World          world        = GameManager.Instance.World;
            EntityPlayer   entityPlayer = world.Players.dict[sender.entityId];
            Vector3        position     = entityPlayer.position;
            PrefabInstance prefab       = world.GetPOIAtPosition(position);

            // If no arguments just show POI info
            if (arguments.Count == 0)
            {
                if (prefab == null)
                {
                    ChatManager.Message(sender, "[FF0000]No POI found!");
                }
                else
                {
                    ChatManager.Message(sender, string.Format("[FFCC00]POI: [DDDDDD]{0}", prefab.name));
                }
                return(false);
            }

            // Fix everything around player
            int num  = World.toChunkXZ((int)position.x) - 1;
            int num2 = World.toChunkXZ((int)position.z) - 1;
            int num3 = num + 2;
            int num4 = num2 + 2;

            HashSetLong hashSetLong = new HashSetLong();

            for (int k = num; k <= num3; k++)
            {
                for (int l2 = num2; l2 <= num4; l2++)
                {
                    hashSetLong.Add(WorldChunkCache.MakeChunkKey(k, l2));
                }
            }

            ChunkCluster chunkCache = world.ChunkCache;
            ChunkProviderGenerateWorld chunkProviderGenerateWorld = world.ChunkCache.ChunkProvider as ChunkProviderGenerateWorld;

            foreach (long key in hashSetLong)
            {
                if (!chunkProviderGenerateWorld.GenerateSingleChunk(chunkCache, key, true))
                {
                    ChatManager.Message(sender, string.Format("Failed regenerating chunk at position {0}/{1}", WorldChunkCache.extractX(key) << 4, WorldChunkCache.extractZ(key) << 4));
                }
            }

            world.m_ChunkManager.ResendChunksToClients(hashSetLong);

            if (prefab != null)
            {
                prefab.Reset(world);
            }

            ChatManager.Message(sender, "[44FF44]Reseted");
            return(false);
        }
Example #4
0
        private void DoReload()
        {
            if (Params.Count != 5 && Params.Count != 3)
            {
                SendOutput("Incorrect params count for reload");
                SendOutput(GetHelp());

                return;
            }

            int cx;
            int cy;
            int cz;
            int cw;

            if (Params.Count == 3)
            {
                if (!int.TryParse(Params[1], out cx) || !int.TryParse(Params[2], out cy))
                {
                    SendOutput("Unable to parse chunk co-ords from params");
                    SendOutput(GetHelp());

                    return;
                }
                cz = cx;
                cw = cy;
            }
            else
            {
                if (!int.TryParse(Params[1], out cx) || !int.TryParse(Params[2], out cy) ||
                    !int.TryParse(Params[3], out cz) || !int.TryParse(Params[4], out cw))
                {
                    SendOutput("Unable to parse chunk co-ords from params");
                    SendOutput(GetHelp());

                    return;
                }
            }

            var x1 = Math.Min(cx, cz);
            var x2 = Math.Max(cx, cz);
            var z1 = Math.Min(cy, cw);
            var z2 = Math.Max(cy, cw);

            var chunks = new Dictionary <long, Chunk>();

            for (var x = x1; x <= x2; x++)
            {
                for (var z = z1; z <= z2; z++)
                {
                    var chunkKey = WorldChunkCache.MakeChunkKey(x, z);
                    chunks[chunkKey] = null;
                }
            }
            var count = BCChunks.ReloadForClients(chunks);

            SendOutput($"Chunks reloaded for {count} clients in area: {x1},{z1} to {x2},{z2}");
        }
Example #5
0
        /// <summary>
        /// Returns all chunk keys that are located (also partly) in the given area.
        /// </summary>
        /// <param name="pos1">South-West corner of area; y is ignored</param>
        /// <param name="pos2">North-East corner of area; y is ignored</param>
        /// <param name="expand">Allows expanding (or with negative value contracting) the area by the given number of chunks.
        /// For example with +1 it returns also neighbouring chunks.</param>
        /// <returns>Collection of chunk keys; chunks may or may not be loaded</returns>
        private static ICollection <long> GetChunksForArea(Vector3i pos1, Vector3i pos2, int expand = 0)
        {
            expand *= Constants.ChunkSize; // expand is now in blocks
            var chunkKeys = new List <long>();

            for (var x = pos1.x - expand; x <= pos2.x + expand; x += Constants.ChunkSize)
            {
                for (var z = pos1.z - expand; z <= pos2.z + expand; z += Constants.ChunkSize)
                {
                    chunkKeys.Add(WorldChunkCache.MakeChunkKey(World.toChunkXZ(x), World.toChunkXZ(z)));
                }
            }
            return(chunkKeys);
        }
Example #6
0
        private static bool GetChunkKey(World world, out long chunkKey)
        {
            chunkKey = long.MinValue;

            switch (Params.Count)
            {
            case 3:
            {
                if (!int.TryParse(Params[1], out var x) || !int.TryParse(Params[2], out var z))
                {
                    SendOutput("Unable to parse x z for numbers");

                    return(false);
                }

                chunkKey = WorldChunkCache.MakeChunkKey(x, z);

                return(true);
            }

            default:
            {
                if (SenderInfo.RemoteClientInfo == null)
                {
                    SendOutput("Unable to get location from player position");

                    return(false);
                }

                var entityId = SenderInfo.RemoteClientInfo.entityId;
                if (!world.Players.dict.ContainsKey(entityId))
                {
                    SendOutput("Unable to get location from player position");

                    return(false);
                }

                var ep = world.Players.dict[entityId];
                chunkKey = WorldChunkCache.MakeChunkKey((int)Math.Floor(ep.position.x) >> 4, (int)Math.Floor(ep.position.z) >> 4);

                return(true);
            }
            }
        }
Example #7
0
        public override void Process()
        {
            if (Params.Count != 2)
            {
                SendOutput(GetHelp());

                return;
            }

            if (!int.TryParse(Params[0], out var x))
            {
                SendOutput("x was not a number");

                return;
            }
            if (!int.TryParse(Params[1], out var z))
            {
                SendOutput("z was not a number");

                return;
            }

            if (GameManager.Instance.World == null)
            {
                SendOutput("The world isn't loaded");

                return;
            }

            var world = GameManager.Instance.World;

            var x2 = World.toChunkXZ(x);
            var z2 = World.toChunkXZ(z);

            var   i     = 0;
            Chunk chunk = null;

            world.ChunkCache.ChunkProvider.RequestChunk(x2, z2);
            var chunkKey = WorldChunkCache.MakeChunkKey(x2, z2);

            while (i < 100)
            {
                chunk = world.GetChunkSync(chunkKey) as Chunk;
                if (chunk != null)
                {
                    break;
                }
                System.Threading.Thread.Sleep(10);
                i++;
            }
            //todo: allow for /timeout to increase limit?

            if (chunk == null)
            {
                SendOutput("Unable to get chunk");

                return;
            }

            var heights = new List <string>();

            if (Options.ContainsKey("ch"))
            {
                for (var x3 = 0; x3 < 16; x3++)
                {
                    for (var z3 = 0; z3 < 16; z3++)
                    {
                        heights.Add(chunk.GetHeight(x3, z3).ToString());
                    }
                }
                SendOutput("ChunkHeights:" + string.Join(",", heights.ToArray()));
            }
            else
            {
                var cx = x & 15;
                var cz = z & 15;
                if (Options.ContainsKey("ph"))
                {
                    SendOutput("PointHeight:" + chunk.GetHeight(cx, cz));
                }
                else
                {
                    if (chunk.FindSpawnPointAtXZ(cx, cz, out var y, 15, 0, 3, 251, true))
                    {
                        SendOutput("SpawnPoint:" + x + " " + y + " " + z);
                    }
Example #8
0
        public override void Process()
        {
            if (Params.Count == 0)
            {
                SendOutput(GetHelp());

                return;
            }

            var world = GameManager.Instance.World;

            if (world == null)
            {
                return;
            }

            switch (Params[0])
            {
            //case "region":
            //  {
            //    var chunkCache = world.ChunkCache;
            //    if (!(chunkCache.ChunkProvider is ChunkProviderGenerateWorld chunkProvider))
            //    {
            //      SendOutput("Unable to load chunk provider");

            //      return;
            //    }

            //    var field = typeof(ChunkProviderGenerateWorld).GetField("m_regionFileManager", BindingFlags.NonPublic | BindingFlags.Instance);
            //    var rfm = (RegionFileManager)field?.GetValue(chunkProvider);
            //    if (rfm == null)
            //    {
            //      SendOutput("Region Manager is null");

            //      return;
            //    }

            //    if (!int.TryParse(Params[1], out var cx) || !int.TryParse(Params[2], out var cz))
            //    {
            //      SendOutput("Unable to parse cx or cz as numbers");

            //      return;
            //    }

            //    var chunkKey = WorldChunkCache.MakeChunkKey(cx, cz);
            //    //do stuff
            //    rfm.RemoveChunkSync(chunkKey);

            //    break;
            //  }
            case "chunk":
            {
                //CHUNK - Resets the chunk to the original state it was created in
                if (Params.Count != 3)
                {
                    SendOutput("Incorrect Params");
                    SendOutput(GetHelp());

                    return;
                }

                if (!int.TryParse(Params[1], out var cx) || !int.TryParse(Params[2], out var cz))
                {
                    SendOutput("Unable to parse cx or cz as numbers");

                    return;
                }
                var chunkKey = WorldChunkCache.MakeChunkKey(cx, cz);

                //todo: make unloaded chunk option
                //todo: deferred load
                var chunkCache = world.ChunkCache;
                if (!(chunkCache.ChunkProvider is ChunkProviderGenerateWorld chunkProvider))
                {
                    SendOutput("Unable to load chunk provider");

                    return;
                }
                //todo: deferred load
                var chunkSync = chunkCache.GetChunkSync(chunkKey);
                if (chunkSync == null)
                {
                    SendOutput("Chunk not loaded");

                    return;
                }

                //create reset chunk
                var chunk = MemoryPools.PoolChunks.AllocSync(true);
                if (chunk == null)
                {
                    SendOutput("Couldn't allocate chunk from memory pool");

                    return;
                }

                chunk.X = cx;
                chunk.Z = cz;

                if (!(chunkProvider.GetTerrainGenerator() is TerrainGeneratorWithBiomeResource terrainGenerator))
                {
                    SendOutput("Couldn't load terrain generator");

                    return;
                }

                var random = Utils.RandomFromSeedOnPos(cx, cz, world.Seed);
                terrainGenerator.GenerateTerrain(world, chunk, random);
                chunk.NeedsDecoration       = true;
                chunk.NeedsLightCalculation = true;
                DoPrefabDecorations(world, chunkProvider, chunk, random);
                DeEntityDecoration(world, chunkProvider, chunk, random);
                DoSpawnerDecorations(world, chunkProvider, chunk, random);

                //UPDATE CHUNK
                var syncRoot = chunkCache.GetSyncRoot();
                lock (syncRoot)
                {
                    //remove old chunk
                    if (chunkCache.ContainsChunkSync(chunkKey))
                    {
                        chunkCache.RemoveChunkSync(chunkKey);
                    }

                    if (chunkCache.ContainsChunkSync(chunk.Key))
                    {
                        SendOutput("Reset chunk still exists in chunk cache");

                        return;
                    }

                    if (!chunkCache.AddChunkSync(chunk))
                    {
                        MemoryPools.PoolChunks.FreeSync(chunk);
                        SendOutput("Unable to add new chunk to cache");

                        return;
                    }
                }
                var decorateWithNeigbours = typeof(ChunkProviderGenerateWorld).GetMethod(_decorateFunction, BindingFlags.NonPublic | BindingFlags.Instance);
                if (decorateWithNeigbours == null)
                {
                    SendOutput("Couldn't access method for DecorateWithNeigbours");

                    return;
                }
                decorateWithNeigbours.Invoke(chunkProvider, new object[] { chunk });

                chunk.InProgressRegeneration = false;
                chunk.NeedsCopying           = true;
                chunk.isModified             = true;

                SendOutput($"Chunk reset @ {cx},{cz}");
                Log.Out($"{Config.ModPrefix} Chunk reset @ {cx},{cz}");

                //RELOAD CHUNKS
                if (!(Options.ContainsKey("noreload") || Options.ContainsKey("nr")))
                {
                    BCChunks.ReloadForClients(new Dictionary <long, Chunk> {
                            { chunkKey, chunk }
                        });
                }
                break;
            }

            //case "player":
            //  {
            //    //resets the player by kicking them if online and then backing up player files before deleting
            //    break;
            //  }

            default:
                SendOutput(GetHelp());
                break;
            }
        }
Example #9
0
        internal static void PlayerSpawnedInWorld(ClientInfo player, RespawnType respawnReason, Vector3i _pos)
        {
            string   pId         = player.playerId;
            ModState playerState = VariableContainer.GetPlayerState(pId);
            World    world       = GameManager.Instance.World;

            if (respawnReason.Equals(RespawnType.Died))
            {
                if (playerState.Equals(ModState.RECONNECTING_TO_GAME) || playerState.Equals(ModState.IN_GAME) || playerState.Equals(ModState.START_GAME))
                {
                    if (playerState.Equals(ModState.RECONNECTING_TO_GAME))
                    {
                        Team.Member member = new Team.Member
                        {
                            entityId = player.entityId,
                            nick     = player.playerName,
                            pId      = pId
                        };

                        VariableContainer.SetPlayerState(pId, ModState.IN_GAME);
                        TeamMaker.AddPlayerToTeam(member, VariableContainer.GetPlayerLastTeam(pId));
                    }

                    // Has no items, teleport to team spawn and give items
                    Map     map   = VariableContainer.GetMap(VariableContainer.selectedMap);
                    Vector3 spawn = TeamMaker.GetPlayerTeam(pId).spawn;

                    Log.Out(string.Format("Spawn for {0} is {1}", player.playerName, spawn.ToString()));

                    // Find random spor around spawn
                    Vector3 destination = Vector3.zero;
                    //if (!world.GetRandomSpawnPositionMinMaxToPosition(spawn, 0, 2, 2, false, out destination, true))
                    // {
                    destination = spawn;
                    //}

                    player.SendPackage(NetPackageManager.GetPackage <NetPackageTeleportPlayer>().Setup(destination, null, false));

                    // ReGen
                    // Rebuild terrain around spawn
                    if (!refubrishedCords.Contains(spawn))
                    {
                        // But only once
                        refubrishedCords.Add(spawn);

                        PrefabInstance prefab = GameManager.Instance.World.GetPOIAtPosition(spawn);

                        int num  = World.toChunkXZ((int)spawn.x) - 1;
                        int num2 = World.toChunkXZ((int)spawn.z) - 1;
                        int num3 = num + 2;
                        int num4 = num2 + 2;

                        HashSetLong hashSetLong = new HashSetLong();
                        for (int k = num; k <= num3; k++)
                        {
                            for (int l2 = num2; l2 <= num4; l2++)
                            {
                                hashSetLong.Add(WorldChunkCache.MakeChunkKey(k, l2));
                            }
                        }

                        ChunkCluster chunkCache = world.ChunkCache;
                        ChunkProviderGenerateWorld chunkProviderGenerateWorld = world.ChunkCache.ChunkProvider as ChunkProviderGenerateWorld;

                        foreach (long key in hashSetLong)
                        {
                            if (!chunkProviderGenerateWorld.GenerateSingleChunk(chunkCache, key, true))
                            {
                                ChatManager.Message(player, string.Format("[FF4136]Failed regenerating chunk at position [FF851B]{0}[FF4136]/[FF851B]{1}", WorldChunkCache.extractX(key) << 4, WorldChunkCache.extractZ(key) << 4));
                            }
                        }

                        world.m_ChunkManager.ResendChunksToClients(hashSetLong);

                        if (prefab != null)
                        {
                            prefab.Reset(world);
                        }
                    }

                    // Give items
                    ClassManager.ApplyClass(player);

                    if (VariableContainer.GetPlayerState(pId).Equals(ModState.START_GAME))
                    {
                        VariableContainer.SetPlayerState(pId, ModState.IN_GAME);
                    }
                    else
                    {
                        HandleDiedInGame(player);
                    }
                    return;
                }
                else
                {
                    VariableContainer.SetPlayerState(pId, ModState.IN_LOBBY);
                    player.SendPackage(NetPackageManager.GetPackage <NetPackageTeleportPlayer>().Setup(VariableContainer.GetLobbyPosition(), null, false));
                    return;
                }
            }

            if (respawnReason.Equals(RespawnType.Teleport))
            {
                return;
            }

            if (VariableContainer.GetPlayerState(pId).Equals(ModState.RECONNECTING_TO_GAME))
            {
                // Have to kill reconected player
                Log.Out("Killing bc of reconnect: " + player.playerName);
                world.Players.dict[player.entityId].DamageEntity(new DamageSource(EnumDamageSource.Internal, EnumDamageTypes.Suicide), 99999, false, 1f);
                return;
            }

            if (VariableContainer.selectedMap == "null")
            {
                VariableContainer.SetPlayerState(pId, ModState.IN_LOBBY);
                player.SendPackage(NetPackageManager.GetPackage <NetPackageTeleportPlayer>().Setup(VariableContainer.GetLobbyPosition(), null, false));
            }
        }
Example #10
0
        public static Dictionary <long, Chunk> GetAffectedChunks(BCMCmdArea command, World world)
        {
            var modifiedChunks = new Dictionary <long, Chunk>();

            var timeout = 2000;

            if (command.Opts.ContainsKey("timeout"))
            {
                if (command.Opts["timeout"] != null)
                {
                    int.TryParse(command.Opts["timeout"], out timeout);
                }
            }

            ChunkObserver(command, world, timeout / 2000);

            //request any unloaded chunks in area
            for (var x = command.ChunkBounds.x; x <= command.ChunkBounds.z; x++)
            {
                for (var z = command.ChunkBounds.y; z <= command.ChunkBounds.w; z++)
                {
                    var chunkKey = WorldChunkCache.MakeChunkKey(x, z);
                    modifiedChunks.Add(chunkKey, null);
                }
            }

            var chunkCount = (command.ChunkBounds.z - command.ChunkBounds.x + 1) * (command.ChunkBounds.w - command.ChunkBounds.y + 1);
            var count      = 0;
            var sw         = Stopwatch.StartNew();

            while (count < chunkCount && sw.ElapsedMilliseconds < timeout)
            {
                for (var x = command.ChunkBounds.x; x <= command.ChunkBounds.z; x++)
                {
                    for (var z = command.ChunkBounds.y; z <= command.ChunkBounds.w; z++)
                    {
                        //check if already in list
                        var chunkKey = WorldChunkCache.MakeChunkKey(x, z);
                        if (modifiedChunks.ContainsKey(chunkKey) && modifiedChunks[chunkKey] != null)
                        {
                            continue;
                        }

                        //check if chunk has loaded
                        if (!world.ChunkCache.ContainsChunkSync(chunkKey))
                        {
                            continue;
                        }

                        modifiedChunks[chunkKey] = world.GetChunkSync(chunkKey) as Chunk;
                        if (modifiedChunks[chunkKey] != null)
                        {
                            count++;
                        }
                    }
                }
            }

            sw.Stop();

            if (count < chunkCount)
            {
                BCCommandAbstract.SendOutput($"Unable to load {chunkCount - count}/{chunkCount} chunks");

                return(null);
            }

            BCCommandAbstract.SendOutput($"Loading {chunkCount} chunks took {Math.Round(sw.ElapsedMilliseconds / 1000f, 2)} seconds");

            return(modifiedChunks);
        }
Example #11
0
        protected override void Process()
        {
            if (!BCUtils.CheckWorld(out var world))
            {
                return;
            }

            //Resets the chunk to the original state it was created in
            if (Params.Count != 2)
            {
                SendOutput("Incorrect Params");
                SendOutput(GetHelp());

                return;
            }

            if (!int.TryParse(Params[0], out var cx) || !int.TryParse(Params[1], out var cz))
            {
                SendOutput("Unable to parse cx or cz as numbers");

                return;
            }
            var chunkKey = WorldChunkCache.MakeChunkKey(cx, cz);

            //todo: make unloaded chunk option
            //todo: deferred load
            var chunkCache = world.ChunkCache;

            if (!(chunkCache.ChunkProvider is ChunkProviderGenerateWorld chunkProvider))
            {
                SendOutput("Unable to load chunk provider");

                return;
            }
            //todo: deferred load
            var chunkSync = chunkCache.GetChunkSync(chunkKey);

            if (chunkSync == null)
            {
                SendOutput("Chunk not loaded");

                return;
            }

            //create reset chunk
            var chunk = MemoryPools.PoolChunks.AllocSync(true);

            if (chunk == null)
            {
                SendOutput("Couldn't allocate chunk from memory pool");

                return;
            }

            chunk.X = cx;
            chunk.Z = cz;

            if (!(chunkProvider.GetTerrainGenerator() is TerrainGeneratorWithBiomeResource terrainGenerator))
            {
                SendOutput("Couldn't load terrain generator");

                return;
            }

            var random = Utils.RandomFromSeedOnPos(cx, cz, world.Seed);

            terrainGenerator.GenerateTerrain(world, chunk, random);
            chunk.NeedsDecoration       = true;
            chunk.NeedsLightCalculation = true;
            DoPrefabDecorations(world, chunkProvider, chunk, random);
            DoEntityDecoration(world, chunkProvider, chunk, random);
            DoSpawnerDecorations(world, chunkProvider, chunk, random);

            //UPDATE CHUNK
            var syncRoot = chunkCache.GetSyncRoot();

            lock (syncRoot)
            {
                //todo: instead of remove and add, generate the chunk then use regular setblockrpc calls to update chunk blocks
                //remove old chunk
                if (chunkCache.ContainsChunkSync(chunkKey))
                {
                    chunkCache.RemoveChunkSync(chunkKey);
                }

                if (chunkCache.ContainsChunkSync(chunk.Key))
                {
                    SendOutput("Reset chunk still exists in chunk cache");

                    return;
                }

                if (!chunkCache.AddChunkSync(chunk))
                {
                    MemoryPools.PoolChunks.FreeSync(chunk);
                    SendOutput("Unable to add new chunk to cache");

                    return;
                }
            }


            var decorateWithNeigbours = typeof(ChunkProviderGenerateWorld).GetMethod(_decorateFunction, BindingFlags.NonPublic | BindingFlags.Instance);

            if (decorateWithNeigbours == null)
            {
                SendOutput("Couldn't access method for DecorateWithNeigbours");

                return;
            }
            decorateWithNeigbours.Invoke(chunkProvider, new object[] { chunk });

            chunk.InProgressRegeneration = false;
            chunk.NeedsCopying           = true;
            chunk.isModified             = true;

            SendOutput($"Chunk reset @ {cx},{cz}");
            Log.Out($"{Config.ModPrefix} Chunk reset @ {cx},{cz}");

            //RELOAD CHUNKS
            if (!(Options.ContainsKey("noreload") || Options.ContainsKey("nr")))
            {
                BCChunks.ReloadForClients(new Dictionary <long, Chunk> {
                    { chunkKey, chunk }
                });
            }
        }
Example #12
0
 public static Vector2xz ChunkKeyToChunkXZ(long chunkKey)
 {
     return(new Vector2xz(WorldChunkCache.extractX(chunkKey), WorldChunkCache.extractZ(chunkKey)));
 }