public bool Interact(IPlayer player)
        {
            bool sneaking = player.WorldData.EntityControls.Sneak;

            if (sneaking)
            {
                int ic = structure.InCompleteBlockCount(Api.World, Pos);

                if (ic == 0)
                {
                    structure.ClearHighlights(Api.World, player);
                    return(true);
                }
                else
                {
                    structure.HighlightIncompleteParts(Api.World, player, Pos);
                    capi?.TriggerIngameError(this, "incomplete", Lang.Get("Structure is not complete, make sure the immediate area around the block is clear."));
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
        public bool Interact(IPlayer byPlayer, bool preferThis)
        {
            bool sneaking = byPlayer.WorldData.EntityControls.Sneak;

            int      damagedTiles    = 0;
            int      wrongTiles      = 0;
            int      incompleteCount = 0;
            BlockPos posMain         = Pos;

            // set up incompleteCount (etc) for both orientations and pick whichever is more complete
            if (sneaking)
            {
                int ic    = 0;
                int icOpp = int.MaxValue;
                int dt    = 0;
                int wt    = 0;
                int dtOpp = 0;
                int wtOpp = 0;

                ic = ms.InCompleteBlockCount(Api.World, Pos,
                                             (haveBlock, wantLoc) => { if (haveBlock.FirstCodePart() == "refractorybricks" && haveBlock.Variant["state"] == "damaged")
                                                                       {
                                                                           dt++;
                                                                       }
                                                                       else
                                                                       {
                                                                           wt++;
                                                                       } }
                                             );
                if (ic > 0 && blockScs.IsCompleteCoffin(Pos))
                {
                    icOpp = msOpp.InCompleteBlockCount(Api.World, Pos.AddCopy(blockScs.Orientation.Opposite),
                                                       (haveBlock, wantLoc) => { if (haveBlock.FirstCodePart() == "refractorybricks" && haveBlock.Variant["state"] == "damaged")
                                                                                 {
                                                                                     dtOpp++;
                                                                                 }
                                                                                 else
                                                                                 {
                                                                                     wtOpp++;
                                                                                 } }
                                                       );
                }

                // This logic aims to figure out which structure to show - if one is almost complete (3 wrong tiles or less) that one will be shown; preferThis has a preference if both are equally incomplete (newly placed stonecoffin) or if one is not much more complete than the other (allows for building errors of 1-3 tiles before the shown structure flips)
                if (wtOpp <= 3 && wt < wtOpp || wtOpp > 3 && wt < wtOpp - 3 || preferThis && wt <= wtOpp || preferThis && wt > 3 && wt <= wtOpp + 3)
                {
                    incompleteCount = ic;
                    damagedTiles    = dt;
                    wrongTiles      = wt;
                    if (ic > 0)
                    {
                        msHighlighted = ms;
                    }
                }
                else
                {
                    incompleteCount = icOpp;
                    damagedTiles    = dtOpp;
                    wrongTiles      = wtOpp;
                    msHighlighted   = msOpp;
                    posMain         = Pos.AddCopy(blockScs.Orientation.Opposite);
                }
            }

            if (sneaking && incompleteCount > 0)
            {
                if (wrongTiles > 0 && damagedTiles > 0)
                {
                    capi?.TriggerIngameError(this, "incomplete", Lang.Get("Structure is not complete, {0} blocks are missing or wrong, {1} tiles are damaged!", wrongTiles, damagedTiles));
                }
                else
                {
                    if (wrongTiles > 0)
                    {
                        capi?.TriggerIngameError(this, "incomplete", Lang.Get("Structure is not complete, {0} blocks are missing or wrong!", wrongTiles));
                    }
                    else
                    {
                        if (damagedTiles == 1)
                        {
                            capi?.TriggerIngameError(this, "incomplete", Lang.Get("Structure is not complete, {0} tile is damaged!", damagedTiles));
                        }
                        else
                        {
                            capi?.TriggerIngameError(this, "incomplete", Lang.Get("Structure is not complete, {0} tiles are damaged!", damagedTiles));
                        }
                    }
                }

                if (Api.Side == EnumAppSide.Client)
                {
                    msHighlighted.HighlightIncompleteParts(Api.World, byPlayer, posMain);
                }
                return(false);
            }
            else
            {
                if (Api.Side == EnumAppSide.Client)
                {
                    msHighlighted?.ClearHighlights(Api.World, byPlayer);
                }
            }

            if (!sneaking)
            {
                return(false);
            }

            if (!blockScs.IsCompleteCoffin(Pos))
            {
                capi?.TriggerIngameError(this, "incomplete", Lang.Get("Cannot fill an incomplete coffin, place the other half first"));
                return(false);
            }

            ItemSlot slot = byPlayer.InventoryManager.ActiveHotbarSlot;


            if (!slot.Empty)
            {
                if (IngotCount / 4 >= CoalLayerCount)
                {
                    return(AddCoal(slot));
                }
                else
                {
                    return(AddIngot(slot));
                }
            }

            return(true);
        }