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(); }