Exemple #1
0
        internal void OnUseOver(IPlayer byPlayer, Vec3i voxelPos, BlockFacing facing, bool mouseBreakMode)
        {
            if (voxelPos == null)
            {
                didBeginUse = Math.Max(didBeginUse, didBeginUse - 1);
                return;
            }

            // Send a custom network packet for server side, because
            // serverside blockselection index is inaccurate
            if (api.Side == EnumAppSide.Client)
            {
                SendUseOverPacket(byPlayer, voxelPos, facing, mouseBreakMode);
            }


            IItemSlot slot = byPlayer.InventoryManager.ActiveHotbarSlot;

            if (slot.Itemstack == null || !CanWorkCurrent)
            {
                didBeginUse = Math.Max(didBeginUse, didBeginUse - 1);
                return;
            }
            int toolMode = slot.Itemstack.Collectible.GetToolMode(slot, byPlayer, new BlockSelection()
            {
                Position = pos
            });

            float       yaw         = GameMath.Mod(byPlayer.Entity.Pos.Yaw, 2 * GameMath.PI);
            BlockFacing towardsFace = BlockFacing.HorizontalFromAngle(yaw);



            if (didBeginUse > 0)
            {
                bool didmodify = false;

                if (toolMode == 3)
                {
                    if (!mouseBreakMode)
                    {
                        didmodify = OnCopyLayer();
                    }
                    else
                    {
                        toolMode = 1;
                    }
                }

                if (toolMode != 3)
                {
                    didmodify = mouseBreakMode ? OnRemove(voxelPos, facing, toolMode) : OnAdd(voxelPos, facing, toolMode);
                }


                if (didmodify && api.Side == EnumAppSide.Client)
                {
                    api.World.PlaySoundAt(new AssetLocation("sounds/player/clayform.ogg"), byPlayer, null, true, 8);
                }

                RegenMeshAndSelectionBoxes();
                api.World.BlockAccessor.MarkBlockDirty(pos);
                api.World.BlockAccessor.MarkBlockEntityDirty(pos);

                if (!HasAnyVoxel())
                {
                    AvailableVoxels = 0;
                    workItemStack   = null;
                    didBeginUse     = 0;
                    return;
                }
            }

            didBeginUse = Math.Max(didBeginUse, didBeginUse - 1);
            CheckIfFinished(byPlayer);
            MarkDirty();
        }
        public override bool TryPlaceBlock(IWorldAccessor world, IPlayer byPlayer, ItemStack itemstack, BlockSelection blockSel, ref EnumHandling handling, ref string failureCode)
        {
            handling = EnumHandling.PreventDefault;

            AssetLocation blockCode = null;

            if (rotateSides)
            {
                // Simple 6 state rotator.

                if (facing == "block")
                {
                    var x = Math.Abs(blockSel.HitPosition.X - 0.5);
                    var y = Math.Abs(blockSel.HitPosition.Y - 0.5);
                    var z = Math.Abs(blockSel.HitPosition.Z - 0.5);
                    switch (blockSel.Face.Axis)
                    {
                    case EnumAxis.X:
                        if (z < 0.3 && y < 0.3)
                        {
                            blockCode = block.CodeWithParts(blockSel.Face.GetOpposite().Code);
                        }
                        else if (z > y)
                        {
                            blockCode = block.CodeWithParts(blockSel.HitPosition.Z < 0.5 ? "north" : "south");
                        }
                        else
                        {
                            blockCode = block.CodeWithParts(blockSel.HitPosition.Y < 0.5 ? "down" : "up");
                        }
                        break;

                    case EnumAxis.Y:
                        if (z < 0.3 && x < 0.3)
                        {
                            blockCode = block.CodeWithParts(blockSel.Face.GetOpposite().Code);
                        }
                        else if (z > x)
                        {
                            blockCode = block.CodeWithParts(blockSel.HitPosition.Z < 0.5 ? "north" : "south");
                        }
                        else
                        {
                            blockCode = block.CodeWithParts(blockSel.HitPosition.X < 0.5 ? "west" : "east");
                        }
                        break;

                    case EnumAxis.Z:
                        if (x < 0.3 && y < 0.3)
                        {
                            blockCode = block.CodeWithParts(blockSel.Face.GetOpposite().Code);
                        }
                        else if (x > y)
                        {
                            blockCode = block.CodeWithParts(blockSel.HitPosition.X < 0.5 ? "west" : "east");
                        }
                        else
                        {
                            blockCode = block.CodeWithParts(blockSel.HitPosition.Y < 0.5 ? "down" : "up");
                        }
                        break;
                    }
                }
                else
                {
                    if (blockSel.Face.IsVertical)
                    {
                        blockCode = block.CodeWithParts(blockSel.Face.GetOpposite().Code);
                    }
                    else
                    {
                        blockCode = block.CodeWithParts(BlockFacing.HorizontalFromAngle(byPlayer.Entity.Pos.Yaw).Code);
                    }
                }
            }
            else if (rotateH || rotateV)
            {
                // Complex 4/8/16 state rotator.
                string h = "north";
                string v = "up";
                if (blockSel.Face.IsVertical)
                {
                    v = blockSel.Face.Code;
                    h = BlockFacing.HorizontalFromAngle(byPlayer.Entity.Pos.Yaw).Code;
                }
                else if (rotateV4)
                {
                    if (facing == "block")
                    {
                        h = blockSel.Face.GetOpposite().Code;
                    }
                    else
                    {
                        // Default to player facing.
                        h = BlockFacing.HorizontalFromAngle(byPlayer.Entity.Pos.Yaw).Code;
                    }
                    switch (blockSel.Face.Axis)
                    {
                    case EnumAxis.X:
                        // Find the axis farther from the center.
                        if (Math.Abs(blockSel.HitPosition.Z - 0.5) > Math.Abs(blockSel.HitPosition.Y - 0.5))
                        {
                            v = blockSel.HitPosition.Z < 0.5 ? "left" : "right";
                        }
                        else
                        {
                            v = blockSel.HitPosition.Y < 0.5 ? "up" : "down";
                        }
                        break;

                    case EnumAxis.Z:
                        if (Math.Abs(blockSel.HitPosition.X - 0.5) > Math.Abs(blockSel.HitPosition.Y - 0.5))
                        {
                            v = blockSel.HitPosition.X < 0.5 ? "left" : "right";
                        }
                        else
                        {
                            v = blockSel.HitPosition.Y < 0.5 ? "up" : "down";
                        }
                        break;
                    }
                }
                else
                {
                    v = blockSel.HitPosition.Y < 0.5 ? "up" : "down";
                }

                if (rotateH && rotateV)
                {
                    blockCode = block.CodeWithParts(v, h);
                }
                else if (rotateH)
                {
                    blockCode = block.CodeWithParts(h);
                }
                else if (rotateV)
                {
                    blockCode = block.CodeWithParts(v);
                }
            }

            if (blockCode == null)
            {
                blockCode = this.block.Code;
            }

            Block orientedBlock = world.BlockAccessor.GetBlock(blockCode);

            if (orientedBlock.IsSuitablePosition(world, blockSel.Position, ref failureCode))
            {
                world.BlockAccessor.SetBlock(orientedBlock.BlockId, blockSel.Position);
                return(true);
            }

            return(false);
        }
        internal void OnUseOver(IPlayer byPlayer, Vec3i voxelPos, BlockSelection blockSel)
        {
            if (voxelPos == null)
            {
                return;
            }

            // Send a custom network packet for server side, because
            // serverside blockselection index is inaccurate
            if (api.Side == EnumAppSide.Client)
            {
                SendUseOverPacket(byPlayer, voxelPos);
            }


            ItemSlot slot = byPlayer.InventoryManager.ActiveHotbarSlot;

            if (slot.Itemstack == null || !CanWorkCurrent)
            {
                return;
            }
            int toolMode = slot.Itemstack.Collectible.GetToolMode(slot, byPlayer, blockSel);

            float       yaw         = GameMath.Mod(byPlayer.Entity.Pos.Yaw, 2 * GameMath.PI);
            BlockFacing towardsFace = BlockFacing.HorizontalFromAngle(yaw);


            float temp = workItemStack.Collectible.GetTemperature(api.World, workItemStack);

            if (Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z])
            {
                if (temp > 800)
                {
                    bigMetalSparks.minPos    = pos.ToVec3d().AddCopy(voxelPos.X / 16f, voxelPos.Y / 16f + 0.0625f, voxelPos.Z / 16f);
                    bigMetalSparks.glowLevel = (byte)GameMath.Clamp((int)(temp - 770) / 3, 32, 128);
                    byPlayer.Entity.World.SpawnParticles(bigMetalSparks, byPlayer);

                    smallMetalSparks.minPos      = pos.ToVec3d().AddCopy(voxelPos.X / 16f, voxelPos.Y / 16f + 0.0625f, voxelPos.Z / 16f);
                    smallMetalSparks.glowLevel   = (byte)GameMath.Clamp((int)(temp - 770) / 3, 32, 128);
                    smallMetalSparks.model       = EnumParticleModel.Quad;
                    smallMetalSparks.lifeLength  = 0.03f;
                    smallMetalSparks.minVelocity = new Vec3f(-1f, 1f, -1f);
                    smallMetalSparks.addVelocity = new Vec3f(2f, 2f, 2f);
                    smallMetalSparks.minQuantity = 4;
                    smallMetalSparks.addQuantity = 6;
                    smallMetalSparks.minSize     = 0.1f;
                    smallMetalSparks.maxSize     = 0.1f;
                    smallMetalSparks.SizeEvolve  = new EvolvingNatFloat(EnumTransformFunction.LINEAR, -0.1f);
                    byPlayer.Entity.World.SpawnParticles(smallMetalSparks, byPlayer);
                }


                switch (toolMode)
                {
                case 0: OnHit(voxelPos); break;

                case 1: OnUpset(voxelPos, BlockFacing.NORTH.FaceWhenRotatedBy(0, yaw - GameMath.PIHALF, 0)); break;

                case 2: OnUpset(voxelPos, BlockFacing.EAST.FaceWhenRotatedBy(0, yaw - GameMath.PIHALF, 0)); break;

                case 3: OnUpset(voxelPos, BlockFacing.SOUTH.FaceWhenRotatedBy(0, yaw - GameMath.PIHALF, 0)); break;

                case 4: OnUpset(voxelPos, BlockFacing.WEST.FaceWhenRotatedBy(0, yaw - GameMath.PIHALF, 0)); break;

                case 5: OnSplit(voxelPos); break;
                }

                RegenMeshAndSelectionBoxes();
                api.World.BlockAccessor.MarkBlockDirty(pos);
                api.World.BlockAccessor.MarkBlockEntityDirty(pos);
                slot.Itemstack.Collectible.DamageItem(api.World, byPlayer.Entity, slot);

                if (!HasAnyVoxel())
                {
                    AvailableVoxels = 0;
                    workItemStack   = null;
                    return;
                }
            }

            CheckIfFinished(byPlayer);
            MarkDirty();
        }
        public override bool TryPlaceBlock(IWorldAccessor world, IPlayer byPlayer, ItemStack itemstack, BlockSelection blockSel, ref EnumHandling handling, ref string failureCode)
        {
            handling = EnumHandling.PreventDefault;
            AssetLocation blockCode = null;
            Block         orientedBlock;

            EnumSlabPlaceMode mode = itemstack.Attributes == null ? EnumSlabPlaceMode.Auto : (EnumSlabPlaceMode)itemstack.Attributes.GetInt("slabPlaceMode", 0);

            if (mode == EnumSlabPlaceMode.Horizontal)
            {
                string side = blockSel.HitPosition.Y < 0.5 ? "down" : "up";
                if (blockSel.Face.IsVertical)
                {
                    side = blockSel.Face.Opposite.Code;
                }

                blockCode     = block.CodeWithVariant("rot", side);
                orientedBlock = world.BlockAccessor.GetBlock(blockCode);
                if (orientedBlock.CanPlaceBlock(world, byPlayer, blockSel, ref failureCode))
                {
                    world.BlockAccessor.SetBlock(orientedBlock.BlockId, blockSel.Position);
                    return(true);
                }
                return(false);
            }

            if (mode == EnumSlabPlaceMode.Vertical)
            {
                BlockFacing[] hv   = Block.SuggestedHVOrientation(byPlayer, blockSel);
                string        side = hv[0].Code;
                if (blockSel.Face.IsHorizontal)
                {
                    side = blockSel.Face.Opposite.Code;
                }

                blockCode = block.CodeWithVariant("rot", side);

                orientedBlock = world.BlockAccessor.GetBlock(blockCode);
                if (orientedBlock.CanPlaceBlock(world, byPlayer, blockSel, ref failureCode))
                {
                    world.BlockAccessor.SetBlock(orientedBlock.BlockId, blockSel.Position);
                    return(true);
                }
                return(false);
            }


            if (rotateSides)
            {
                // Simple 6 state rotator.

                if (facing == "block")
                {
                    var x = Math.Abs(blockSel.HitPosition.X - 0.5);
                    var y = Math.Abs(blockSel.HitPosition.Y - 0.5);
                    var z = Math.Abs(blockSel.HitPosition.Z - 0.5);
                    switch (blockSel.Face.Axis)
                    {
                    case EnumAxis.X:
                        if (z < 0.3 && y < 0.3)
                        {
                            blockCode = block.CodeWithVariant("rot", blockSel.Face.Opposite.Code);
                        }
                        else if (z > y)
                        {
                            blockCode = block.CodeWithVariant("rot", blockSel.HitPosition.Z < 0.5 ? "north" : "south");
                        }
                        else
                        {
                            blockCode = block.CodeWithVariant("rot", blockSel.HitPosition.Y < 0.5 ? "down" : "up");
                        }
                        break;

                    case EnumAxis.Y:
                        if (z < 0.3 && x < 0.3)
                        {
                            blockCode = block.CodeWithVariant("rot", blockSel.Face.Opposite.Code);
                        }
                        else if (z > x)
                        {
                            blockCode = block.CodeWithVariant("rot", blockSel.HitPosition.Z < 0.5 ? "north" : "south");
                        }
                        else
                        {
                            blockCode = block.CodeWithVariant("rot", blockSel.HitPosition.X < 0.5 ? "west" : "east");
                        }
                        break;

                    case EnumAxis.Z:
                        if (x < 0.3 && y < 0.3)
                        {
                            blockCode = block.CodeWithVariant("rot", blockSel.Face.Opposite.Code);
                        }
                        else if (x > y)
                        {
                            blockCode = block.CodeWithVariant("rot", blockSel.HitPosition.X < 0.5 ? "west" : "east");
                        }
                        else
                        {
                            blockCode = block.CodeWithVariant("rot", blockSel.HitPosition.Y < 0.5 ? "down" : "up");
                        }
                        break;
                    }
                }
                else
                {
                    if (blockSel.Face.IsVertical)
                    {
                        blockCode = block.CodeWithVariant("rot", blockSel.Face.Opposite.Code);
                    }
                    else
                    {
                        blockCode = block.CodeWithVariant("rot", BlockFacing.HorizontalFromAngle(byPlayer.Entity.Pos.Yaw).Code);
                    }
                }
            }
            else if (rotateH || rotateV)
            {
                // Complex 4/8/16 state rotator.
                string h = "north";
                string v = "up";
                if (blockSel.Face.IsVertical)
                {
                    v = blockSel.Face.Code;
                    h = BlockFacing.HorizontalFromAngle(byPlayer.Entity.Pos.Yaw).Code;
                }
                else if (rotateV4)
                {
                    if (facing == "block")
                    {
                        h = blockSel.Face.Opposite.Code;
                    }
                    else
                    {
                        // Default to player facing.
                        h = BlockFacing.HorizontalFromAngle(byPlayer.Entity.Pos.Yaw).Code;
                    }
                    switch (blockSel.Face.Axis)
                    {
                    case EnumAxis.X:
                        // Find the axis farther from the center.
                        if (Math.Abs(blockSel.HitPosition.Z - 0.5) > Math.Abs(blockSel.HitPosition.Y - 0.5))
                        {
                            v = blockSel.HitPosition.Z < 0.5 ? "left" : "right";
                        }
                        else
                        {
                            v = blockSel.HitPosition.Y < 0.5 ? "up" : "down";
                        }
                        break;

                    case EnumAxis.Z:
                        if (Math.Abs(blockSel.HitPosition.X - 0.5) > Math.Abs(blockSel.HitPosition.Y - 0.5))
                        {
                            v = blockSel.HitPosition.X < 0.5 ? "left" : "right";
                        }
                        else
                        {
                            v = blockSel.HitPosition.Y < 0.5 ? "up" : "down";
                        }
                        break;
                    }
                }
                else
                {
                    v = blockSel.HitPosition.Y < 0.5 ? "up" : "down";
                }

                if (rotateH && rotateV)
                {
                    blockCode = block.CodeWithVariants(new string[] { "v", "rot" }, new string[] { v, h });
                }
                else if (rotateH)
                {
                    blockCode = block.CodeWithVariant("rot", h);
                }
                else if (rotateV)
                {
                    blockCode = block.CodeWithVariant("rot", v);
                }
            }

            if (blockCode == null)
            {
                blockCode = this.block.Code;
            }

            orientedBlock = world.BlockAccessor.GetBlock(blockCode);
            if (orientedBlock.CanPlaceBlock(world, byPlayer, blockSel, ref failureCode))
            {
                world.BlockAccessor.SetBlock(orientedBlock.BlockId, blockSel.Position);
                return(true);
            }

            return(false);
        }
        internal void OnUseOver(IPlayer byPlayer, Vec3i voxelPos, BlockFacing facing, bool mouseMode)
        {
            if (voxelPos == null)
            {
                // DidBeginUse = Math.Max(0, DidBeginUse - 1);
                return;
            }

            // Send a custom network packet for server side, because
            // serverside blockselection index is inaccurate
            if (api.Side == EnumAppSide.Client)
            {
                SendUseOverPacket(byPlayer, voxelPos, facing, mouseMode);
            }

            ItemSlot slot = byPlayer.InventoryManager.ActiveHotbarSlot;

            if (slot.Itemstack == null)
            {
                //      DidBeginUse = Math.Max(0, DidBeginUse - 1);
                return;
            }

            int toolMode = slot.Itemstack.Collectible.GetToolMode(slot, byPlayer, new BlockSelection()
            {
                Position = pos
            });

            float       yaw         = GameMath.Mod(byPlayer.Entity.Pos.Yaw, 2 * GameMath.PI);
            BlockFacing towardsFace = BlockFacing.HorizontalFromAngle(yaw);


            //if (DidBeginUse > 0)
            {
                bool didRemove = mouseMode && OnRemove(voxelPos, facing, toolMode, byPlayer);

                if (mouseMode && (didRemove || Voxels[voxelPos.X, voxelPos.Z]))
                {
                    api.World.PlaySoundAt(new AssetLocation("sounds/player/knap" + (api.World.Rand.Next(2) > 0 ? 1 : 2)), lastRemovedLocalPos.X, lastRemovedLocalPos.Y, lastRemovedLocalPos.Z, byPlayer, true, 12, 1);
                }

                if (didRemove)
                {
                    //byPlayer.Entity.GetBehavior<EntityBehaviorHunger>()?.ConsumeSaturation(1f);
                }

                if (didRemove && api.Side == EnumAppSide.Client)
                {
                    Random rnd = api.World.Rand;
                    for (int i = 0; i < 3; i++)
                    {
                        api.World.SpawnParticles(new SimpleParticleProperties()
                        {
                            minQuantity = 1,
                            addQuantity = 2,
                            color       = BaseMaterial.Collectible.GetRandomColor(api as ICoreClientAPI, BaseMaterial),
                            minPos      = new Vec3d(lastRemovedLocalPos.X, lastRemovedLocalPos.Y + 1 / 16f + 0.01f, lastRemovedLocalPos.Z),
                            addPos      = new Vec3d(1 / 16f, 0.01f, 1 / 16f),
                            minVelocity = new Vec3f(0, 1, 0),
                            addVelocity = new Vec3f(
                                4 * ((float)rnd.NextDouble() - 0.5f),
                                1 * ((float)rnd.NextDouble() - 0.5f),
                                4 * ((float)rnd.NextDouble() - 0.5f)
                                ),
                            lifeLength    = 0.2f,
                            gravityEffect = 1f,
                            minSize       = 0.1f,
                            maxSize       = 0.4f,
                            model         = EnumParticleModel.Cube,
                            SizeEvolve    = new EvolvingNatFloat(EnumTransformFunction.LINEAR, -0.15f)
                        });
                    }
                }



                RegenMeshAndSelectionBoxes();
                api.World.BlockAccessor.MarkBlockDirty(pos);
                api.World.BlockAccessor.MarkBlockEntityDirty(pos);

                if (!HasAnyVoxel())
                {
                    api.World.BlockAccessor.SetBlock(0, pos);
                    return;
                }
            }

            // DidBeginUse = Math.Max(0, DidBeginUse - 1);
            CheckIfFinished(byPlayer);
            MarkDirty();
        }