示例#1
0
    /**
     * This happens when the block is placed in the world.
     */

    public override void PlaceBlock(WorldBase _world, BlockPlacement.Result _result, EntityAlive _ea)
    {
        Block block = Block.list[_result.blockValue.type];

        if (block.shape.IsTerrain())
        {
            _world.SetBlockRPC(_result.clrIdx, _result.blockPos, _result.blockValue, this.Density);
        }
        else if (!block.IsTerrainDecoration)
        {
            _world.SetBlockRPC(_result.clrIdx, _result.blockPos, _result.blockValue, MarchingCubes.DensityAir);
        }
        else
        {
            _world.SetBlockRPC(_result.clrIdx, _result.blockPos, _result.blockValue);
        }

        TileEntityBlockTransformer tileEntityBlockTransformer = _world.GetTileEntity(_result.clrIdx, _result.blockPos) as TileEntityBlockTransformer;

        if (tileEntityBlockTransformer == null)
        {
            Log.Warning("Failed to create tile entity");
            return;
        }
        if (_ea != null && _ea.entityType == EntityType.Player)
        {
            tileEntityBlockTransformer.bPlayerStorage   = true;
            tileEntityBlockTransformer.worldTimeTouched = _world.GetWorldTime();
            tileEntityBlockTransformer.SetEmpty();
        }
        Log.Out("Created successfullly.");
    }
    public void CheckForSpawn(WorldBase _world, int _clrIdx, Vector3i _blockPos, BlockValue _blockValue)
    {
        if (string.IsNullOrEmpty(SpawnGroup))
        {
            Debug.Log("Spawner does not have a SpawnGroup property set: " + this.GetBlockName());
            return;
        }

        if (_blockValue.meta2 == 0)
        {
            int    ClassID   = 0;
            int    EntityID  = EntityGroups.GetRandomFromGroup(this.SpawnGroup, ref ClassID);
            Entity NewEntity = EntityFactory.CreateEntity(EntityID, _blockPos.ToVector3() + Vector3.up) as Entity;
            if (NewEntity)
            {
                NewEntity.SetSpawnerSource(EnumSpawnerSource.Dynamic);
                GameManager.Instance.World.SpawnEntityInWorld(NewEntity);
                if (Task == "Stay")
                {
                    EntityUtilities.SetCurrentOrder(NewEntity.entityId, EntityUtilities.Orders.Stay);
                }
                if (Task == "Patrol")
                {
                    EntityUtilities.SetCurrentOrder(NewEntity.entityId, EntityUtilities.Orders.Patrol);
                }
                if (Task == "Wander")
                {
                    EntityUtilities.SetCurrentOrder(NewEntity.entityId, EntityUtilities.Orders.Wander);
                }

                _blockValue.meta2 = (byte)1;
                _world.SetBlockRPC(_clrIdx, _blockPos, _blockValue);
            }
        }
    }
示例#3
0
        private static void RepairBlock(WorldBase world, Vector3i pos)
        {
            var blockValue = world.GetBlock(pos);

            if (blockValue.Equals(BlockValue.Air))
            {
                SendOutput($"Target block is air @ {pos}");

                return;
            }

            var d = blockValue.damage;

            if (d > 0)
            {
                SendOutput($"Target block not damaged @ {pos}");

                return;
            }

            blockValue.damage = 0;
            world.SetBlockRPC(pos, blockValue);

            SendOutput($"Repairing block for '{d}' damage @ {pos}");
        }
示例#4
0
    public override bool OnBlockActivated(int _indexInBlockActivationCommands, WorldBase _world, int _cIdx,
                                          Vector3i _blockPos, BlockValue _blockValue, EntityAlive _player)
    {
        if (_blockValue.ischild)
        {
            Vector3i   parentPos = Block.list[_blockValue.type].multiBlockPos.GetParentPos(_blockPos, _blockValue);
            BlockValue block     = _world.GetBlock(parentPos);
            return(this.OnBlockActivated(_indexInBlockActivationCommands, _world, _cIdx, parentPos, block, _player));
        }
        TileEntitySign tileEntitySign = _world.GetTileEntity(_cIdx, _blockPos) as TileEntitySign;

        if (tileEntitySign == null)
        {
            return(false);
        }
        switch (_indexInBlockActivationCommands)
        {
        case 0:
            if (GameManager.Instance.IsEditMode() || !tileEntitySign.IsLocked() || tileEntitySign.IsUserAllowed(GamePrefs.GetString(EnumGamePrefs.PlayerId)))
            {
                return(this.OnBlockActivated(_world, _cIdx, _blockPos, _blockValue, _player));
            }
            Manager.BroadcastPlayByLocalPlayer(_blockPos.ToVector3() + Vector3.one * 0.5f, "Misc/locked");
            return(false);

        case 1:
            tileEntitySign.SetLocked(true);
            Manager.BroadcastPlayByLocalPlayer(_blockPos.ToVector3() + Vector3.one * 0.5f, "Misc/locking");
            GameManager.ShowTooltip(_player as EntityPlayerLocal, "containerLocked");
            return(true);

        case 2:
            tileEntitySign.SetLocked(false);
            Manager.BroadcastPlayByLocalPlayer(_blockPos.ToVector3() + Vector3.one * 0.5f, "Misc/unlocking");
            GameManager.ShowTooltip(_player as EntityPlayerLocal, "containerUnlocked");
            return(true);

        case 3:
            XUiC_KeypadWindow.Open(LocalPlayerUI.GetUIForPlayer(_player as EntityPlayerLocal), tileEntitySign);
            return(true);

        case 4:
            LocalPlayerUI uiforPlayer = LocalPlayerUI.GetUIForPlayer(_player as EntityPlayerLocal);
            ItemStack     itemStack   = new ItemStack(_blockValue.ToItemValue(), 1);
            if (!uiforPlayer.xui.PlayerInventory.AddItem(itemStack))
            {
                uiforPlayer.xui.PlayerInventory.DropItem(itemStack);
            }
            _world.SetBlockRPC(_cIdx, _blockPos, BlockValue.Air);

            return(true);

        default:
            return(false);
        }
    }
示例#5
0
    public override void OnBlockLoaded(WorldBase _world, int _clrIdx, Vector3i _blockPos, BlockValue _blockValue)
    {
        BlockEntityData _ebcd = _world.ChunkClusters[_clrIdx].GetBlockEntity(_blockPos);

        if (!_blockValue.ischild)
        {
            this.shape.OnBlockLoaded(_world, _clrIdx, _blockPos, _blockValue);
            _blockValue.meta = (byte)(_blockValue.meta & ~(1 << 0));
            _blockValue.meta = (byte)(_blockValue.meta & ~(1 << 1));
            _blockValue.meta = (byte)(_blockValue.meta & ~(1 << 2));
            _blockValue.meta = (byte)(_blockValue.meta & ~(1 << 3));
            _world.SetBlockRPC(_blockPos, _blockValue);

            _blockValue.meta = (byte)(_blockValue.meta | (0 << 0));
            _blockValue.meta = (byte)(_blockValue.meta | (0 << 1));
            _blockValue.meta = (byte)(_blockValue.meta | (0 << 2));
            _blockValue.meta = (byte)(_blockValue.meta | (0 << 3));
            _world.SetBlockRPC(_blockPos, _blockValue);
        }
    }
示例#6
0
        private static void SetMeta(int metaIdx, WorldBase world, Vector3i pos)
        {
            byte meta = 0;

            if (Options.ContainsKey("meta"))
            {
                if (!byte.TryParse(Options["meta"], out meta))
                {
                    SendOutput($"Unable to parse meta '{Options["meta"]}'");

                    return;
                }
            }

            var blockValue = world.GetBlock(pos);

            if (blockValue.Equals(BlockValue.Air))
            {
                SendOutput($"Target block is air @ {pos}");

                return;
            }
            if (blockValue.ischild)
            {
                SendOutput($"Target child block can't be set @ {pos} - Parent@ {blockValue.parentx},{blockValue.parenty},{blockValue.parentz}");

                return;
            }

            var m = blockValue.meta;

            switch (metaIdx)
            {
            case 1:
                blockValue.meta = meta;
                break;

            case 2:
                blockValue.meta2 = meta;
                break;

            case 3:
                blockValue.meta3 = meta;
                break;

            default:
                return;
            }
            world.SetBlockRPC(pos, blockValue);

            SendOutput($"Changing meta{metaIdx} on block from '{m}' to '{meta}' @ {pos}");
        }
示例#7
0
 // custom function to operate the trap. If it is resulting from a collision "fireTrap" will be true, if its player interaction it will be false.
 private void OperateTrap(WorldBase _world, int _clrIdx, Vector3i _blockPos, BlockValue _blockValue, Entity _entity,
                          bool fireTrap)
 {
     // here's where we do operation actions. This will only run if the originator is alive!
     if (!_entity.IsAlive())
     {
         return;
     }
     if (fireTrap)
     {
         // if the operation results from block collision, we will try to "open" the trap.
         // but only if it's not already opened (waiting for reset)
         if (!BlockTrapTutorial.IsTrapFired(_blockValue.meta))
         {
             #region Fire trap;
             // I will be using the bit 0, and set it to 1 here. This will let everyone know that the trap is open (waiting for reset)
             _blockValue.meta = (byte)(_blockValue.meta | (1 << 0));
             // as soon as we "commit" this information, all clients will be informed and the correct animations will play
             _world.SetBlockRPC(_clrIdx, _blockPos, _blockValue);
             #endregion ;
         }
     }
     else
     {
         // if the operation results from player interaction (reseting the trap)
         if (BlockTrapTutorial.IsTrapFired(_blockValue.meta))
         {
             #region Reset trap;
             // I will be using the bit 0, and reset it to 0. This will let everyone know that the trap is ready and will fire if collided.
             _blockValue.meta = (byte)(_blockValue.meta & ~(1 << 0));
             // as soon as we "commit" this information, all clients will be informed and the correct animations will play
             _world.SetBlockRPC(_clrIdx, _blockPos, _blockValue);
             #endregion ;
         }
     }
 }
示例#8
0
 public override void OnBlockAdded(WorldBase _world, Chunk _chunk, Vector3i _blockPos, BlockValue _blockValue)
 {
     if (_blockValue.ischild)
     {
         return;
     }
     this.shape.OnBlockAdded(_world, _chunk, _blockPos, _blockValue);
     _blockValue.meta = (byte)(_blockValue.meta | (0 << 0));
     _world.SetBlockRPC(_blockPos, _blockValue);
     xmlLoaded = false;
     if (this.isMultiBlock)
     {
         this.multiBlockPos.AddChilds(_world, _chunk.ClrIdx, _blockPos, _blockValue);
     }
 }
示例#9
0
 public override void OnBlockAdded(WorldBase _world, Chunk _chunk, Vector3i _blockPos, BlockValue _blockValue)
 {
     if (_blockValue.ischild)
     {
         return;
     }
     this.shape.OnBlockAdded(_world, _chunk, _blockPos, _blockValue);
     _blockValue.meta = (byte)(_blockValue.meta | (0 << 0));
     _blockValue.meta = (byte)(_blockValue.meta | (0 << 1));
     _blockValue.meta = (byte)(_blockValue.meta | (0 << 2));
     _blockValue.meta = (byte)(_blockValue.meta | (0 << 3));
     _world.SetBlockRPC(_blockPos, _blockValue);
     DisplayChatAreaText("Press Keypad 8 while looking at the screen for CCTV control instructions.");
     if (this.isMultiBlock)
     {
         this.multiBlockPos.AddChilds(_world, _chunk.ClrIdx, _blockPos, _blockValue);
     }
 }
示例#10
0
        private static void SetRotation(WorldBase world, Vector3i pos)
        {
            byte rotation = 0;

            if (Options.ContainsKey("rot"))
            {
                if (!byte.TryParse(Options["rot"], out rotation))
                {
                    SendOutput($"Unable to parse rotation '{Options["rot"]}'");

                    return;
                }
            }

            var blockValue = world.GetBlock(pos);

            if (blockValue.Equals(BlockValue.Air))
            {
                SendOutput($"Target block is air @ {pos}");

                return;
            }
            if (blockValue.ischild)
            {
                SendOutput($"Target child block can't be rotated @ {pos} - Parent@ {blockValue.parentx},{blockValue.parenty},{blockValue.parentz}");

                return;
            }
            if (!blockValue.Block.shape.IsRotatable)
            {
                SendOutput($"Target block can't be rotated @ {pos}");

                return;
            }

            var r = blockValue.rotation;

            blockValue.rotation = rotation;
            world.SetBlockRPC(pos, blockValue);

            SendOutput($"Changing rotation on block from '{r}' to '{rotation}' @ {pos}");
        }
示例#11
0
        private static void SetDensity(WorldBase world, Vector3i pos)
        {
            sbyte density = 1;

            if (Options.ContainsKey("d"))
            {
                if (sbyte.TryParse(Options["d"], out density))
                {
                    SendOutput($"Using density {density}");
                }
            }

            var blockValue = world.GetBlock(pos);

            if (blockValue.Equals(BlockValue.Air))
            {
                SendOutput($"Target block is air @ {pos}");

                return;
            }
            if (blockValue.ischild)
            {
                SendOutput($"Target block is a child block @ {pos} - Parent@ {blockValue.parentx},{blockValue.parenty},{blockValue.parentz}");

                return;
            }

            var d = world.GetDensity(0, pos);

            if (d == density)
            {
                SendOutput($"No change in density @ {pos}");

                return;
            }

            world.SetBlockRPC(pos, blockValue, density);
            SendOutput($"Changing density on block from '{d}' to '{density}' @ {pos}");
        }
    public override bool OnBlockActivated(WorldBase _world, int _cIdx, Vector3i _blockPos, BlockValue _blockValue, EntityAlive _player)
    {
        if (!Stopped(_blockValue.meta2) || WasLooted(_blockValue.meta2))
        {
            return(false);
        }

        var lootable = false;

        if (Properties.Values.ContainsKey(PropLootable) && !bool.TryParse(Properties.Values[PropLootable], out lootable))
        {
            Debug.Log("Unable to parse " + PropLootable + " as a bool in " + _blockValue.Block.GetBlockName());
        }
        if (!lootable)
        {
            return(false);
        }

        _blockValue.meta2 = (byte)(_blockValue.meta2 | (1 << 2));
        _world.SetBlockRPC(_cIdx, _blockPos, _blockValue);

        return(base.OnBlockActivated(_world, _cIdx, _blockPos, _blockValue, _player));
    }
示例#13
0
        private static void UpgradeBlock(WorldBase world, Vector3i pos)
        {
            var blockValue        = world.GetBlock(pos);
            var upgradeBlockValue = blockValue.Block.UpgradeBlock;

            if (upgradeBlockValue.Equals(BlockValue.Air))
            {
                SendOutput($"Target block has no upgrade @ {pos}");

                return;
            }
            if (blockValue.ischild)
            {
                SendOutput($"Can't upgrade a child block @ {pos} - Parent@ {blockValue.parentx},{blockValue.parenty},{blockValue.parentz}");

                return;
            }

            upgradeBlockValue.rotation = blockValue.rotation;
            world.SetBlockRPC(pos, upgradeBlockValue);

            SendOutput($"Upgrading block from '{blockValue.Block.GetBlockName()}' to '{upgradeBlockValue.Block.GetBlockName()}' @ {pos}");
        }
示例#14
0
    public override bool OnBlockActivated(WorldBase _world, int _clrIdx, Vector3i _blockPos, BlockValue _blockValue, EntityAlive _player)
    {
        BlockEntityData _ebcd = _world.ChunkClusters[_clrIdx].GetBlockEntity(_blockPos);

        if (!BlockCCTVScreen.Screen0(_blockValue.meta) && !BlockCCTVScreen.Screen1(_blockValue.meta) && !BlockCCTVScreen.Screen2(_blockValue.meta) && !BlockCCTVScreen.Screen3(_blockValue.meta))
        {
            return(false);
        }
        else
        {
            screen0Mesh.enabled = false;
            screen1Mesh.enabled = false;
            screen2Mesh.enabled = false;
            screen3Mesh.enabled = false;
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 0));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 1));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 2));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 3));
            _world.SetBlockRPC(_blockPos, _blockValue);
            ForceScreens(_blockPos, _blockValue, _ebcd);
            return(false);
        }
    }
示例#15
0
    public override string GetActivationText(WorldBase _world, BlockValue _blockValue, int _clrIdx, Vector3i _blockPos,
                                             EntityAlive _entityFocusing)
    {
        BlockEntityData _ebcd = _world.ChunkClusters[_clrIdx].GetBlockEntity(_blockPos);

        //GameObjects
        screenOBJ_0 = _ebcd.transform.FindChild("TV/TVScreen1").gameObject;
        screenOBJ_1 = _ebcd.transform.FindChild("TV/TVScreen2").gameObject;
        screenOBJ_2 = _ebcd.transform.FindChild("TV/TVScreen3").gameObject;
        screenOBJ_3 = _ebcd.transform.FindChild("TV/TVScreen4").gameObject;
        //MeshRenderers
        screen0Mesh = screenOBJ_0.GetComponent <MeshRenderer>();
        screen1Mesh = screenOBJ_1.GetComponent <MeshRenderer>();
        screen2Mesh = screenOBJ_2.GetComponent <MeshRenderer>();
        screen3Mesh = screenOBJ_3.GetComponent <MeshRenderer>();
        ForceScreens(_blockPos, _blockValue, _ebcd);
        if (Input.GetKeyUp(KeyCode.Keypad1))
        {
            screen0Mesh.enabled = true;
            screen1Mesh.enabled = false;
            screen2Mesh.enabled = false;
            screen3Mesh.enabled = false;
            _blockValue.meta    = (byte)(_blockValue.meta | (1 << 0));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 1));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 2));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 3));
            _world.SetBlockRPC(_blockPos, _blockValue);
            return("");
        }


        if (Input.GetKeyUp(KeyCode.Keypad2))
        {
            screen0Mesh.enabled = false;
            screen1Mesh.enabled = true;
            screen2Mesh.enabled = false;
            screen3Mesh.enabled = false;
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 0));
            _blockValue.meta    = (byte)(_blockValue.meta | (1 << 1));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 2));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 3));
            _world.SetBlockRPC(_blockPos, _blockValue);
            return("");
        }


        if (Input.GetKeyUp(KeyCode.Keypad3))
        {
            screen0Mesh.enabled = false;
            screen1Mesh.enabled = false;
            screen2Mesh.enabled = true;
            screen3Mesh.enabled = false;
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 0));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 1));
            _blockValue.meta    = (byte)(_blockValue.meta | (1 << 2));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 3));
            _world.SetBlockRPC(_blockPos, _blockValue);
            return("");
        }


        if (Input.GetKeyUp(KeyCode.Keypad4))
        {
            screen0Mesh.enabled = false;
            screen1Mesh.enabled = false;
            screen2Mesh.enabled = false;
            screen3Mesh.enabled = true;
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 0));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 1));
            _blockValue.meta    = (byte)(_blockValue.meta & ~(1 << 2));
            _blockValue.meta    = (byte)(_blockValue.meta | (1 << 3));
            _world.SetBlockRPC(_blockPos, _blockValue);
            return("");
        }
        if (Input.GetKeyUp(KeyCode.Keypad8))
        {
            DisplayChatAreaText("Turn the screen on by selecting a channel with numpad 1, 2, 3 or 4. You can pan the camera left and right using the arrow keys.");
            DisplayChatAreaText("Press E while looking at the screen to turn off the screen and all cams.");
            DisplayChatAreaText("Notes: In order to reduce frame rate loss only one camera is turned on at any time and all cameras are turned of when the screen is off.");
            DisplayChatAreaText("For this reason it's best to have only one screen turned on at a time.");
            return("");
        }
        if (!BlockCCTVScreen.Screen0(_blockValue.meta) && !BlockCCTVScreen.Screen1(_blockValue.meta) && !BlockCCTVScreen.Screen2(_blockValue.meta) && !BlockCCTVScreen.Screen3(_blockValue.meta))
        {
            return("To Turn On Select A Channel Using The NumPad.");
        }
        else
        {
            return("");
        }
    }
    public override int OnBlockDamaged(WorldBase _world, int _clrIdx, Vector3i _blockPos, BlockValue _blockValue, int _damagePoints, int _entityIdThatDamaged, bool _bUseHarvestTool, bool _bByPassMaxDamage, int _recDepth)
    {
        var chunkCluster = _world.ChunkClusters[_clrIdx];

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

        if (isMultiBlock && _blockValue.ischild)
        {
            var parentPos = multiBlockPos.GetParentPos(_blockPos, _blockValue);
            var block     = chunkCluster.GetBlock(parentPos);

            if (block.ischild)
            {
                Debug.Log("Block on position " + parentPos + " should be a parent but is not!");
            }

            return(block.ischild ? 0 : list[block.type].OnBlockDamaged(_world, _clrIdx, parentPos, block, _damagePoints, _entityIdThatDamaged, false, _bByPassMaxDamage, 0));
        }

        var d   = _blockValue.damage;
        var max = list[_blockValue.type].MaxDamage;

        if (d >= max || d + _damagePoints < max)
        {
            return(base.OnBlockDamaged(_world, _clrIdx, _blockPos, _blockValue, _damagePoints, _entityIdThatDamaged, _bUseHarvestTool, _bByPassMaxDamage, _recDepth));
        }

        chunkCluster.InvokeOnBlockDamagedDelegates(_blockPos, _blockValue, _damagePoints, _entityIdThatDamaged);

        if (!Stopped(_blockValue.meta2))
        {
            _blockValue.damage = 0;
            _blockValue.meta2  = (byte)(_blockValue.meta2 | (1 << 1));

            _world.SetBlockRPC(_clrIdx, _blockPos, _blockValue);
            return(0);
        }

        if (!OnBlockDestroyedBy(_world, _clrIdx, _blockPos, _blockValue, _entityIdThatDamaged, _bUseHarvestTool))
        {
            return(max);
        }

        SpawnDestroyParticleEffect(_world, _blockValue, _blockPos, _world.GetLightBrightness(_blockPos + new Vector3i(0, 1, 0)), GetColorForSide(_blockValue, BlockFace.Top), _entityIdThatDamaged);

        if (DowngradeBlock.type == 0)
        {
            _world.SetBlockRPC(_clrIdx, _blockPos, BlockValue.Air);

            //todo: should this be 0? seems a bug to return the old types max damage
            return(list[_blockValue.type].MaxDamage);
        }

        //todo:update to include paint and density?
        var downgrade = DowngradeBlock;

        downgrade.rotation = _blockValue.rotation;
        downgrade.meta     = _blockValue.meta;
        if (list[downgrade.type].shape.IsTerrain())
        {
            _world.SetBlockRPC(_clrIdx, _blockPos, downgrade, list[downgrade.type].Density);
        }
        else
        {
            _world.SetBlockRPC(_clrIdx, _blockPos, downgrade);
        }

        return(list[_blockValue.type].MaxDamage);
    }
示例#17
0
        private static void DamageBlock(WorldBase world, Vector3i pos)
        {
            var damageMin = 0;
            var damageMax = 0;

            if (Options.ContainsKey("d"))
            {
                if (Options["d"].IndexOf(",", StringComparison.InvariantCulture) > -1)
                {
                    var dRange = Options["d"].Split(',');
                    if (dRange.Length != 2)
                    {
                        SendOutput("Unable to parse damage values");

                        return;
                    }

                    if (!int.TryParse(dRange[0], out damageMin))
                    {
                        SendOutput("Unable to parse damage min value");

                        return;
                    }

                    if (!int.TryParse(dRange[1], out damageMax))
                    {
                        SendOutput("Unable to parse damage max value");

                        return;
                    }
                }
                else
                {
                    if (!int.TryParse(Options["d"], out damageMin))
                    {
                        SendOutput("Unable to parse damage value");

                        return;
                    }
                }
            }

            var blockValue = world.GetBlock(pos);

            if (blockValue.Equals(BlockValue.Air))
            {
                return;
            }

            var max    = blockValue.Block.blockMaterial.MaxDamage;
            var impact = damageMax != 0 ? UnityEngine.Random.Range(damageMin, damageMax) : damageMin;
            var damage = impact + blockValue.damage;

            if (Options.ContainsKey("nobreak"))
            {
                blockValue.damage = Math.Min(damage, max - 1);
            }
            else if (Options.ContainsKey("overkill"))
            {
                if (damage >= max)
                {
                    var downgradeBlock = blockValue.Block.DowngradeBlock;
                    while (damage >= max)
                    {
                        downgradeBlock          = blockValue.Block.DowngradeBlock;
                        damage                 -= max;
                        max                     = downgradeBlock.Block.blockMaterial.MaxDamage;
                        downgradeBlock.rotation = blockValue.rotation;
                        blockValue              = downgradeBlock;
                    }
                    blockValue.damage = damage;

                    SendOutput($"Damaging block for {-impact} caused downgrade to '{downgradeBlock.Block.GetBlockName()}' @ {pos}");
                }
                else
                {
                    blockValue.damage = damage;
                }
            }
            else
            {
                //needs to downgrade if damage > max, no overflow damage
                if (damage >= max)
                {
                    var downgrade = blockValue.Block.DowngradeBlock;
                    SendOutput($"Damaging block for {-impact} caused downgrade to '{downgrade.Block.GetBlockName()}' @ {pos}");
                    downgrade.rotation = blockValue.rotation;
                    blockValue         = downgrade;
                }
                else
                {
                    blockValue.damage = damage;
                }
            }

            world.SetBlockRPC(pos, blockValue);
            if (!blockValue.Equals(BlockValue.Air))
            {
                SendOutput($"Damaging block for '{-impact}' leaving {blockValue.Block.blockMaterial.MaxDamage - blockValue.damage}/{blockValue.Block.blockMaterial.MaxDamage} @ {pos}");
            }
        }