private static void Reload(Dictionary <long, Chunk> modifiedChunks) { if (!(Options.ContainsKey("noreload") || Options.ContainsKey("nr"))) { BCChunks.ReloadForClients(modifiedChunks); } }
private static void FillBlocks(Vector3i p3, Vector3i size, BlockValue bv, string search, Dictionary <long, Chunk> modifiedChunks) { const int clrIdx = 0; if (Block.list[bv.type] == null) { SendOutput("Unable to find block by id or name"); return; } SetBlocks(clrIdx, p3, size, bv, search == "*"); if (Options.ContainsKey("delmulti")) { SendOutput($@"Removed multidim blocks @ {p3} to {p3 + size}"); } else { SendOutput($@"Inserting block '{Block.list[bv.type].GetBlockName()}' @ {p3} to {p3 + size}"); SendOutput("Use bc-wblock /undo to revert the changes"); } //RELOAD CHUNKS BCChunks.ReloadForClients(modifiedChunks); }
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}"); }
public static void InsertPrefab(Prefab prefab, int x, int y, int z, Vector3i pos) { var world = GameManager.Instance.World; if (world == null) { return; } if (prefab == null) { SendOutput("No Prefab loaded."); return; } //GET AFFECTED CHUNKS var modifiedChunks = new Dictionary <long, Chunk>(); for (var cx = -1; cx <= prefab.size.x + 16; cx = cx + 16) { for (var cz = -1; cz <= prefab.size.z + 16; cz = cz + 16) { var chunk = world.GetChunkFromWorldPos(x + cx, y, z + cz) as Chunk; if (chunk == null) { // todo: generate and observe chunks required SendOutput("Unable to load chunk for prefab @ " + (x + cx) + "," + (z + cz)); } else { if (modifiedChunks.ContainsKey(chunk.Key)) { continue; } modifiedChunks.Add(chunk.Key, chunk); } } } //INSERT PREFAB //todo: set owner CopyIntoLocal(prefab, world, pos); //prefab.CopyIntoLocal(world.ChunkCache, pos, true, true); //RELOAD CHUNKS BCChunks.ReloadForClients(modifiedChunks); }
public static void InsertPrefab(World world, Prefab prefab, Vector3i pos) { if (prefab == null) { SendOutput("No Prefab loaded."); return; } //GET AFFECTED CHUNKS var modifiedChunks = new Dictionary <long, Chunk>(); for (var cx = -1; cx <= prefab.size.x + 16; cx = cx + 16) { for (var cz = -1; cz <= prefab.size.z + 16; cz = cz + 16) { if (world.GetChunkFromWorldPos(pos.x + cx, 0, pos.z + cz) is Chunk chunk) { if (modifiedChunks.ContainsKey(chunk.Key)) { continue; } modifiedChunks.Add(chunk.Key, chunk); } else { SendOutput($"Unable to load chunk for prefab @ {pos.x + cx},{pos.z + cz}"); } } } //INSERT PREFAB CopyIntoLocal(world, prefab, pos); //RELOAD CHUNKS if (!(Options.ContainsKey("noreload") || Options.ContainsKey("nr"))) { BCChunks.ReloadForClients(modifiedChunks); } }
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; } }
private static void SwapBlocks(Vector3i p3, Vector3i size, BlockValue newbv, string blockname, Dictionary <long, Chunk> modifiedChunks) { var targetbv = int.TryParse(blockname, out int blockId) ? Block.GetBlockValue(blockId) : Block.GetBlockValue(blockname); const int clrIdx = 0; var counter = 0; var block1 = Block.list[targetbv.type]; if (block1 == null) { SendOutput("Unable to find target block by id or name"); return; } var block2 = Block.list[newbv.type]; if (block2 == null) { SendOutput("Unable to find replacement block by id or name"); return; } var world = GameManager.Instance.World; for (var i = 0; i < size.x; i++) { for (var j = 0; j < size.y; j++) { for (var k = 0; k < size.z; k++) { //todo: sbyte density = 1; var textureFull = 0L; if (newbv.Equals(BlockValue.Air)) { density = MarchingCubes.DensityAir; } else if (newbv.Block.shape.IsTerrain()) { density = MarchingCubes.DensityTerrain; } var p5 = new Vector3i(i + p3.x, j + p3.y, k + p3.z); if (world.GetBlock(p5).Block.GetBlockName() != block1.GetBlockName()) { continue; } world.ChunkClusters[clrIdx].SetBlock(p5, true, newbv, false, density, false, false); world.ChunkClusters[clrIdx].SetTextureFull(p5, textureFull); counter++; } } } SendOutput($@"Replaced {counter} '{block1.GetBlockName()}' blocks with '{block2.GetBlockName()}' @ {p3} to {p3 + size}"); SendOutput("Use bc-wblock /undo to revert the changes"); //RELOAD CHUNKS BCChunks.ReloadForClients(modifiedChunks); }
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 } }); } }