private int TryFall(Vector3i _blockPos, BlockValue _blockValue) { int k = 0; Vector3i pos = Vectors.Copy(_blockPos); int y0 = pos.y; for (k = 1; k <= gravity; k++) { pos.y = y0 - k; BlockValue below = GameManager.Instance.World.GetBlock(pos); if (below.Equals(BlockValue.Air) || IsEmpty(below.Block)) { } else { k = k - 1; break; } } pos.y = y0 - k; // There was a gap and < len : insert at new pos if (k > 0 && k < gravity) { GameManager.Instance.World.SetBlockRPC(pos, _blockValue); } // There was a gap : delete initial if (k > 0) { GameManager.Instance.World.SetBlockRPC(_blockPos, BlockValue.Air); } return(k); // -> true if if it felt // int mdom = _myBlockValue.damage; // this.DamageBlock(GameManager.Instance.World, 0, _myBlockPos, _myBlockValue, 10, -1, false, false); }
public static void Exec(Vector3i _blockPosition) { try { if (_blockPosition != null) { BlockValue _blockValue = GameManager.Instance.World.GetBlock(_blockPosition); Block _block = _blockValue.Block; if (_block is BlockSleepingBag || _block.IsDecoration || _block.IsPlant() || _block.isMultiBlock || _blockValue.Equals(BlockValue.Air)) { return; } else { GameManager.Instance.World.SetBlockRPC(_blockPosition, BlockValue.Air); if (OutputLog) { Log.Out(string.Format("[SERVERTOOLS] Falling block removed at position {0}", _blockPosition)); } } } } catch (Exception e) { Log.Out(string.Format("[SERVERTOOLS] Error in FallingBlocks.Exec: {0}", e.Message)); } }
//private static void LightBlocks(Vector3i p3, Vector3i size, bool isOn, Dictionary<long, Chunk> modifiedChunks) //{ // const int clrIdx = 0; // for (var j = 0; j < size.y; j++) // { // for (var i = 0; i < size.x; i++) // { // for (var k = 0; k < size.z; k++) // { // var p5 = new Vector3i(i + p3.x, j + p3.y, k + p3.z); // var blockValue = GameManager.Instance.World.GetBlock(clrIdx, p5); // if (blockValue.Block is BlockLight) // { // blockValue.meta = (byte)((blockValue.meta & -3) | (!isOn ? 0 : 2)); // } // } // } // } // Reload(modifiedChunks); //} private static void SetBlocks(int clrIdx, Vector3i p0, Vector3i size, BlockValue bvNew, bool searchAll) { var world = GameManager.Instance.World; var chunkCluster = world.ChunkClusters[clrIdx]; sbyte density = 1; if (Options.ContainsKey("d")) { if (sbyte.TryParse(Options["d"], out density)) { SendOutput($"Using density {density}"); } } var textureFull = 0L; if (Options.ContainsKey("t")) { if (!byte.TryParse(Options["t"], out var texture)) { SendOutput("Unable to parse texture index"); return; } if (BlockTextureData.list[texture] == null) { SendOutput($"Unknown texture index {texture}"); return; } var num = 0L; for (var face = 0; face < 6; face++) { var num2 = face * 8; num &= ~(255L << num2); num |= (long)(texture & 255) << num2; } textureFull = num; } for (var j = 0; j < size.y; j++) { for (var i = 0; i < size.x; i++) { for (var k = 0; k < size.z; k++) { var p5 = new Vector3i(p0.x + i, p0.y + j, p0.z + k); var bvCurrent = world.GetBlock(p5); if (Options.ContainsKey("delmulti") && (!searchAll || bvNew.type != bvCurrent.type)) { continue; } //REMOVE PARENT OF MULTIDIM if (bvCurrent.Block.isMultiBlock && bvCurrent.ischild) { var parentPos = bvCurrent.Block.multiBlockPos.GetParentPos(p5, bvCurrent); var parent = chunkCluster.GetBlock(parentPos); if (parent.ischild || parent.type != bvCurrent.type) { continue; } chunkCluster.SetBlock(parentPos, BlockValue.Air, false, false); } if (Options.ContainsKey("delmulti")) { continue; } //REMOVE LCB's if (bvCurrent.Block.IndexName == "lpblock") { GameManager.Instance.persistentPlayers.RemoveLandProtectionBlock(new Vector3i(p5.x, p5.y, p5.z)); } //todo: move to a chunk request and then process all blocks on that chunk var chunkSync = world.GetChunkFromWorldPos(p5.x, p5.y, p5.z) as Chunk; if (bvNew.Equals(BlockValue.Air)) { density = MarchingCubes.DensityAir; if (world.GetTerrainHeight(p5.x, p5.z) > p5.y) { chunkSync?.SetTerrainHeight(p5.x & 15, p5.z & 15, (byte)p5.y); } } else if (bvNew.Block.shape.IsTerrain()) { density = MarchingCubes.DensityTerrain; if (world.GetTerrainHeight(p5.x, p5.z) < p5.y) { chunkSync?.SetTerrainHeight(p5.x & 15, p5.z & 15, (byte)p5.y); } } else { //SET TEXTURE world.ChunkClusters[clrIdx].SetTextureFull(p5, textureFull); } //SET BLOCK world.ChunkClusters[clrIdx].SetBlock(p5, true, bvNew, true, density, false, false); } } } }
private static void SwapBlocks(Vector3i p3, Vector3i size, BlockValue newbv, string blockname, Dictionary <long, Chunk> modifiedChunks) { var targetbv = int.TryParse(blockname, out var blockId) ? Block.GetBlockValue(blockId) : Block.GetBlockValue(blockname); 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; } const int clrIdx = 0; var counter = 0; 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++) { sbyte density = 1; if (Options.ContainsKey("d")) { if (sbyte.TryParse(Options["d"], out density)) { SendOutput($"Using density {density}"); } } else { if (newbv.Equals(BlockValue.Air)) { density = MarchingCubes.DensityAir; } else if (newbv.Block.shape.IsTerrain()) { density = MarchingCubes.DensityTerrain; } } var textureFull = 0L; if (Options.ContainsKey("t")) { if (!byte.TryParse(Options["t"], out var texture)) { SendOutput("Unable to parse texture index"); return; } if (BlockTextureData.list[texture] == null) { SendOutput($"Unknown texture index {texture}"); return; } var num = 0L; for (var face = 0; face < 6; face++) { var num2 = face * 8; num &= ~(255L << num2); num |= (long)(texture & 255) << num2; } textureFull = num; } 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(modifiedChunks); }
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); }
public static void Multiple(IList <Vector3i> _blocks) { try { if (_blocks != null && _blocks.Count > 0) { int _count = 0; for (int i = 0; i < _blocks.Count; i++) { BlockValue _blockValue = GameManager.Instance.World.GetBlock(_blocks[i]); Block _block = _blockValue.Block; if (_block is BlockSleepingBag || _block.IsDecoration || _block.IsPlant() || _block.isMultiBlock || _blockValue.Equals(BlockValue.Air)) { continue; } else { GameManager.Instance.World.SetBlockRPC(_blocks[i], BlockValue.Air); _count++; } } if (OutputLog && _count >= Max_Blocks) { EntityPlayer _closestPlayer = GameManager.Instance.World.GetClosestPlayer(_blocks[0].x, _blocks[0].y, _blocks[0].z, -1, 75); if (_closestPlayer != null) { Log.Out(string.Format("[SERVERTOOLS] Removed {0} falling blocks at {1}. The closest player entity id was {2} named {3} @ {4}", _count, _blocks[0], _closestPlayer.entityId, _closestPlayer.EntityName, _closestPlayer.position)); } else { Log.Out(string.Format("[SERVERTOOLS] Removed {0} falling blocks at {1}. No players were located near by", _count, _blocks[0])); } } } } catch (Exception e) { Log.Out(string.Format("[SERVERTOOLS] Error in FallingBlocks.Exec: {0}", e.Message)); } }
public override void Execute(List <string> _params, CommandSenderInfo _senderInfo) { try { if (_params.Count != 1 && _params.Count != 2) { SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Wrong number of arguments, expected 1 or 2, found {0}", _params.Count)); return; } if (_senderInfo.RemoteClientInfo == null) { SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] No client info found. Join the server as a client before using this command")); return; } World _world = GameManager.Instance.World; if (_world.Players.dict.ContainsKey(_senderInfo.RemoteClientInfo.entityId)) { EntityPlayer _player = _world.Players.dict[_senderInfo.RemoteClientInfo.entityId]; if (_player != null) { Vector3i _playerPos = new Vector3i(_player.position); if (_params[0].ToLower() == "save") { if (_player.position.y < 3) { SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Your position is too low. Unable to generate blocks at this world height")); return; } if (!Vectors.ContainsKey(_player.entityId)) { Vector3i[] _vectors = new Vector3i[2]; _vectors[0] = _playerPos; Vectors.Add(_player.entityId, _vectors); SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Set corner 1 to your position: {0}", _playerPos)); return; } else { Vectors.TryGetValue(_player.entityId, out Vector3i[] _vectors); _vectors[1] = _playerPos; Vectors[_player.entityId] = _vectors; SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Set corner 2 to your position: {0}", _playerPos)); return; } } else if (_params[0].ToLower().Equals("cancel")) { if (Vectors.ContainsKey(_senderInfo.RemoteClientInfo.entityId)) { Vectors.Remove(_senderInfo.RemoteClientInfo.entityId); SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Cancelled your saved corner positions")); return; } else { SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] You have no saved corner positions")); return; } } else if (_params[0].ToLower().Equals("undo")) { if (Undo.ContainsKey(_senderInfo.RemoteClientInfo.playerId)) { Undo.TryGetValue(_senderInfo.RemoteClientInfo.playerId, out Dictionary <Vector3i, BlockValue> _undo); foreach (var _block in _undo) { if (!_world.IsChunkAreaLoaded(_block.Key.x, _block.Key.y, _block.Key.z)) { SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Area is not loaded. Unable to undo maze blocks")); return; } } foreach (var _block in _undo) { GameManager.Instance.World.SetBlockRPC(_block.Key, _block.Value); } Thread.Sleep(1000); foreach (var _block in _undo) { BlockValue _newBlockValue = _world.GetBlock(_block.Key); if (!_newBlockValue.Equals(_block.Value)) { GameManager.Instance.World.SetBlockRPC(_block.Key, _block.Value); } } Undo.Remove(_senderInfo.RemoteClientInfo.playerId); SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] The blocks you last spawned have been set to their original value")); return; } else { SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] You have not spawned any blocks. Unable to undo")); return; } } else { Block _block = Block.GetBlockByName(_params[0], false); if (_block != null) { bool _fallingBlocks = FallingBlocks.IsEnabled; FallingBlocks.IsEnabled = true; BlockValue _blockValue = Block.GetBlockValue(_params[0]); if (Vectors.ContainsKey(_senderInfo.RemoteClientInfo.entityId)) { Vectors.TryGetValue(_senderInfo.RemoteClientInfo.entityId, out Vector3i[] _vectors); int _vectorPointX1 = _vectors[0].x, _vectorPointX2 = _vectors[1].x, _vectorPointY1 = _vectors[0].y, _vectorPointY2 = _vectors[1].y, _vectorPointZ1 = _vectors[0].z, _vectorPointZ2 = _vectors[1].z; Dictionary <Vector3i, BlockValue> _undo = new Dictionary <Vector3i, BlockValue>(); if (_vectorPointX2 < _vectorPointX1) { _vectorPointX1 = _vectors[1].x; _vectorPointX2 = _vectors[0].x; } if (_vectorPointY2 < _vectorPointY1) { _vectorPointY1 = _vectors[1].y; _vectorPointY2 = _vectors[0].y; } if (_vectorPointZ2 < _vectorPointZ1) { _vectorPointZ1 = _vectors[1].z; _vectorPointZ2 = _vectors[0].z; } for (int x = _vectorPointX1; x <= _vectorPointX2; x++) { for (int z = _vectorPointZ1; z <= _vectorPointZ2; z++) { for (int y = _vectorPointY1; y <= _vectorPointY2; y++) { Vector3i _processVector = new Vector3i(x, y, z); if (!_world.IsChunkAreaLoaded(_processVector.x, _processVector.y, _processVector.z)) { SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] The blocks you are trying to spawn are outside of a loaded chunk area. Unable to spawn block")); return; } BlockValue _oldBlockValue = _world.GetBlock(_processVector); _undo.Add(_processVector, _oldBlockValue); GameManager.Instance.World.SetBlockRPC(_processVector, _blockValue); } } } if (Undo.ContainsKey(_senderInfo.RemoteClientInfo.playerId)) { Undo[_senderInfo.RemoteClientInfo.playerId] = _undo; } else { Undo.Add(_senderInfo.RemoteClientInfo.playerId, _undo); } Thread.Sleep(1000); for (int x = _vectorPointX1; x <= _vectorPointX2; x++) { for (int z = _vectorPointZ1; z <= _vectorPointZ2; z++) { for (int y = _vectorPointY1; y <= _vectorPointY2; y++) { Vector3i _processVector = new Vector3i(x, y, z); BlockValue _newBlockValue = _world.GetBlock(_processVector); if (!_newBlockValue.Equals(_blockValue)) { GameManager.Instance.World.SetBlockRPC(_processVector, _blockValue); } } } } SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Spawned active block. Double check integrity of block before continuing")); } else { Dictionary <Vector3i, BlockValue> _undo = new Dictionary <Vector3i, BlockValue>(); BlockValue _oldBlockValue = _world.GetBlock(_playerPos); if (Undo.ContainsKey(_senderInfo.RemoteClientInfo.playerId)) { _undo.Add(_playerPos, _oldBlockValue); Undo[_senderInfo.RemoteClientInfo.playerId] = _undo; } else { _undo.Add(_playerPos, _oldBlockValue); Undo.Add(_senderInfo.RemoteClientInfo.playerId, _undo); } GameManager.Instance.World.SetBlockRPC(_playerPos, _blockValue); Thread.Sleep(1000); BlockValue _newBlockValue = _world.GetBlock(_playerPos); if (!_newBlockValue.Equals(_blockValue)) { GameManager.Instance.World.SetBlockRPC(_playerPos, _blockValue); } SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Spawned active block. Double check integrity of block before continuing")); } FallingBlocks.IsEnabled = _fallingBlocks; } else { SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Unable to spawn block. Could not find block name: {0}", _params[0])); return; } } } else { SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Unable to locate player data for current position")); return; } } else { SdtdConsole.Instance.Output(string.Format("[SERVERTOOLS] Unable to locate player data for current position")); return; } } catch (Exception e) { Log.Out(string.Format("[SERVERTOOLS] Error in SpawnActiveBlocks.Execute: {0}", e.Message)); } }
private static void SetBlock(World world, Vector3i pos, BlockValue targetbv) { sbyte density = 0; if (Options.ContainsKey("d") && sbyte.TryParse(Options["d"], out density)) { SendOutput($"Using density {density}"); } byte texture = 0; if (Options.ContainsKey("t")) { if (!byte.TryParse(Options["t"], out texture)) { SendOutput("Unable to parse texture index"); return; } if (BlockTextureData.list[texture] == null) { SendOutput($"Unknown texture index {texture}"); return; } SendOutput($"Using texture '{BlockTextureData.GetDataByTextureID(texture)?.Name}'"); } if (Options.ContainsKey("delmulti")) { return; } var bvCurrent = world.GetBlock(pos); //REMOVE PARENT OF MULTIDIM if (bvCurrent.Block.isMultiBlock && bvCurrent.ischild) { var parentPos = bvCurrent.Block.multiBlockPos.GetParentPos(pos, bvCurrent); var parent = world.GetBlock(parentPos); if (parent.ischild || parent.type != bvCurrent.type) { return; } world.ChunkClusters[0].SetBlock(parentPos, BlockValue.Air, false, false); } if (Options.ContainsKey("delmulti")) { return; } //REMOVE LCB's if (bvCurrent.Block.IndexName == "lpblock") { GameManager.Instance.persistentPlayers.RemoveLandProtectionBlock(pos); } var chunkSync = world.GetChunkFromWorldPos(pos.x, pos.y, pos.z) as Chunk; if (targetbv.Equals(BlockValue.Air)) { density = MarchingCubes.DensityAir; if (world.GetTerrainHeight(pos.x, pos.z) > pos.y) { chunkSync?.SetTerrainHeight(pos.x & 15, pos.z & 15, (byte)pos.y); } } else if (targetbv.Block.shape.IsTerrain()) { density = MarchingCubes.DensityTerrain; if (world.GetTerrainHeight(pos.x, pos.z) < pos.y) { chunkSync?.SetTerrainHeight(pos.x & 15, pos.z & 15, (byte)pos.y); } } else { //SET TEXTURE GameManager.Instance.SetBlockTextureServer(pos, BlockFace.None, texture, -1); } //SET BLOCK world.SetBlockRPC(pos, targetbv, density); }