Beispiel #1
0
        public override void OnHeldInteractStart(ItemSlot itemslot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handling)
        {
            if (blockSel != null && byEntity.World.BlockAccessor.GetBlock(blockSel.Position) is BlockDisplayCase)
            {
                handling = EnumHandHandling.NotHandled;
                return;
            }

            bool knappable          = itemslot.Itemstack.Collectible.Attributes != null && itemslot.Itemstack.Collectible.Attributes["knappable"].AsBool(false);
            bool haveKnappableStone = false;

            IPlayer byPlayer = (byEntity as EntityPlayer)?.Player;

            if (byEntity.Controls.Sneak && blockSel != null)
            {
                Block block = byEntity.World.BlockAccessor.GetBlock(blockSel.Position);
                haveKnappableStone =
                    block.Code.Path.StartsWith("loosestones") &&
                    block.FirstCodePart(1).Equals(itemslot.Itemstack.Collectible.FirstCodePart(1))
                ;
            }

            if (haveKnappableStone)
            {
                if (!knappable)
                {
                    if (byEntity.World.Side == EnumAppSide.Client)
                    {
                        (this.api as ICoreClientAPI).TriggerIngameError(this, "toosoft", Lang.Get("This type of stone is too soft to be used for knapping."));
                    }
                    return;
                }

                if (!byEntity.World.Claims.TryAccess(byPlayer, blockSel.Position, EnumBlockAccessFlags.Use))
                {
                    itemslot.MarkDirty();
                    return;
                }

                IWorldAccessor world         = byEntity.World;
                Block          knappingBlock = world.GetBlock(new AssetLocation("knappingsurface"));
                if (knappingBlock == null)
                {
                    return;
                }

                string failCode = "";

                BlockPos pos = blockSel.Position;
                knappingBlock.CanPlaceBlock(world, byPlayer, blockSel, ref failCode);

                if (failCode == "entityintersecting")
                {
                    bool selfBlocked   = false;
                    bool entityBlocked = world.GetIntersectingEntities(pos, knappingBlock.GetCollisionBoxes(world.BlockAccessor, pos), e => { selfBlocked = e == byEntity; return(!(e is EntityItem)); }).Length != 0;

                    string err =
                        entityBlocked ?
                        (selfBlocked ? Lang.Get("Cannot place a knapping surface here, too close to you") : Lang.Get("Cannot place a knapping surface here, to close to another player or creature.")) :
                        Lang.Get("Cannot place a knapping surface here")
                    ;

                    (api as ICoreClientAPI).TriggerIngameError(this, "cantplace", err);

                    return;
                }

                world.BlockAccessor.SetBlock(knappingBlock.BlockId, pos);
                world.BlockAccessor.TriggerNeighbourBlockUpdate(blockSel.Position);

                if (knappingBlock.Sounds != null)
                {
                    world.PlaySoundAt(knappingBlock.Sounds.Place, blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z);
                }

                BlockEntityKnappingSurface bec = world.BlockAccessor.GetBlockEntity(pos) as BlockEntityKnappingSurface;
                if (bec != null)
                {
                    bec.BaseMaterial           = itemslot.Itemstack.Clone();
                    bec.BaseMaterial.StackSize = 1;

                    if (byEntity.World is IClientWorldAccessor)
                    {
                        bec.OpenDialog(world as IClientWorldAccessor, pos, itemslot.Itemstack);
                    }
                }
                //itemslot.Take(1);

                handling = EnumHandHandling.PreventDefault;
                byEntity.Attributes.SetInt("aimingCancel", 1);
                return;
            }

            if (blockSel != null && byEntity?.World != null && byEntity.Controls.Sneak)
            {
                IWorldAccessor world = byEntity.World;
                Block          block = world.GetBlock(CodeWithPath("loosestones-" + LastCodePart() + "-free"));
                if (block == null)
                {
                    block = world.GetBlock(CodeWithPath("loosestones-" + LastCodePart(1) + "-" + LastCodePart(0) + "-free"));
                }
                if (block == null)
                {
                    return;
                }

                if (!world.BlockAccessor.GetBlock(blockSel.Position).SideSolid[BlockFacing.UP.Index])
                {
                    return;
                }

                BlockPos       targetpos = blockSel.Position.AddCopy(blockSel.Face);
                BlockSelection placeSel  = blockSel.Clone();
                placeSel.Position  = targetpos;
                placeSel.DidOffset = true;
                string error = "";

                if (!block.TryPlaceBlock(world, byPlayer, itemslot.Itemstack, placeSel, ref error))
                {
                    if (api.Side == EnumAppSide.Client)
                    {
                        (api as ICoreClientAPI).TriggerIngameError(this, "cantplace", Lang.Get("placefailure-" + error));
                    }
                    return;
                }

                world.BlockAccessor.TriggerNeighbourBlockUpdate(blockSel.Position);

                if (block.Sounds != null)
                {
                    world.PlaySoundAt(block.Sounds.Place, blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z);
                }

                itemslot.Itemstack.StackSize--;

                handling = EnumHandHandling.PreventDefault;
                byEntity.Attributes.SetInt("aimingCancel", 1);
                return;
            }

            if (byEntity.Controls.Sneak)
            {
                return;
            }


            // Not ideal to code the aiming controls this way. Needs an elegant solution - maybe an event bus?
            byEntity.Attributes.SetInt("aiming", 1);
            byEntity.Attributes.SetInt("aimingCancel", 0);
            byEntity.StartAnimation("aim");

            handling = EnumHandHandling.PreventDefault;
        }
        public override void OnHeldInteractStart(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handling)
        {
            IPlayer byPlayer = null;

            if (byEntity is EntityPlayer)
            {
                byPlayer = byEntity.World.PlayerByUid(((EntityPlayer)byEntity).PlayerUID);
            }


            if (byEntity.Controls.Sneak && blockSel != null)
            {
                IWorldAccessor world         = byEntity.World;
                Block          knappingBlock = world.GetBlock(new AssetLocation("knappingsurface"));
                if (knappingBlock == null)
                {
                    return;
                }

                Block block = world.BlockAccessor.GetBlock(blockSel.Position);
                if (!block.CanAttachBlockAt(byEntity.World.BlockAccessor, knappingBlock, blockSel.Position, BlockFacing.UP))
                {
                    if (api.Side == EnumAppSide.Client)
                    {
                        (api as ICoreClientAPI).TriggerIngameError(this, "cantplace", Lang.Get("Cannot place a knapping surface here"));
                    }
                    return;
                }

                BlockPos pos = blockSel.Position.AddCopy(blockSel.Face);
                if (!world.BlockAccessor.GetBlock(pos).IsReplacableBy(knappingBlock))
                {
                    return;
                }

                BlockSelection placeSel = blockSel.Clone();
                placeSel.Position  = pos;
                placeSel.DidOffset = true;
                string useless = "";

                if (!knappingBlock.TryPlaceBlock(world, byPlayer, slot.Itemstack, placeSel, ref useless))
                {
                    if (api.Side == EnumAppSide.Client)
                    {
                        bool selfBlocked   = false;
                        bool entityBlocked = world.GetIntersectingEntities(pos, knappingBlock.GetCollisionBoxes(world.BlockAccessor, pos), e => { selfBlocked = e == byEntity; return(!(e is EntityItem)); }).Length != 0;

                        string err =
                            entityBlocked ?
                            (selfBlocked ? Lang.Get("Cannot place a knapping surface here, too close to you") : Lang.Get("Cannot place a knapping surface here, to close to another player or creature.")) :
                            Lang.Get("Cannot place a knapping surface here")
                        ;

                        (api as ICoreClientAPI).TriggerIngameError(this, "cantplace", err);
                    }

                    return;
                }

                world.BlockAccessor.TriggerNeighbourBlockUpdate(pos);

                if (knappingBlock.Sounds != null)
                {
                    world.PlaySoundAt(knappingBlock.Sounds.Place, pos.X, pos.Y, pos.Z);
                }

                BlockEntityKnappingSurface bec = world.BlockAccessor.GetBlockEntity(pos) as BlockEntityKnappingSurface;
                if (bec != null)
                {
                    bec.BaseMaterial           = slot.Itemstack.Clone();
                    bec.BaseMaterial.StackSize = 1;

                    if (byEntity.World is IClientWorldAccessor)
                    {
                        bec.OpenDialog(world as IClientWorldAccessor, pos, slot.Itemstack);
                    }
                }

                slot.TakeOut(1);

                handling = EnumHandHandling.PreventDefaultAction;
                return;
            }

            base.OnHeldInteractStart(slot, byEntity, blockSel, entitySel, firstEvent, ref handling);
        }