public override void OnLoaded(ICoreAPI api)
        {
            base.OnLoaded(api);

            harvestedStack?.Resolve(api.World, string.Format("harvestedStack of block {0}", block.Code));

            harvestedBlock = api.World.GetBlock(harvestedBlockCode);
            if (harvestedBlock == null)
            {
                api.World.Logger.Warning("Unable to resolve harvested block code '{0}' for block {1}. Will ignore.", harvestedBlockCode, block.Code);
            }
        }
        public void SetHarvested(IPlayer byPlayer, float dropQuantityMultiplier = 1f)
        {
            //entity.World.Logger.Debug("setharvested begin " + entity.World.Side);

            if (entity.WatchedAttributes.GetBool("harvested", false))
            {
                return;
            }

            entity.WatchedAttributes.SetBool("harvested", true);

            if (entity.World.Side == EnumAppSide.Client)
            {
                return;
            }


            if (!entity.Attributes.GetBool("isMechanical", false))
            {
                dropQuantityMultiplier *= byPlayer.Entity.Stats.GetBlended("animalLootDropRate");
            }


            List <ItemStack> todrop = new List <ItemStack>();


            for (int i = 0; i < jsonDrops.Length; i++)
            {
                BlockDropItemStack dstack = jsonDrops[i];
                if (dstack.Tool != null && (byPlayer == null || dstack.Tool != byPlayer.InventoryManager.ActiveTool))
                {
                    continue;
                }

                dstack.Resolve(entity.World, "BehaviorHarvestable");

                float extraMul = 1f;
                if (dstack.DropModbyStat != null)
                {
                    // If the stat does not exist, then GetBlended returns 1 \o/
                    extraMul = byPlayer.Entity.Stats.GetBlended(dstack.DropModbyStat);
                }

                ItemStack stack = dstack.GetNextItemStack(this.dropQuantityMultiplier * dropQuantityMultiplier * extraMul);

                if (stack == null)
                {
                    continue;
                }

                if (stack.Collectible.NutritionProps != null || stack.Collectible.CombustibleProps?.SmeltedStack?.ResolvedItemstack?.Collectible?.NutritionProps != null)
                {
                    float weightedStackSize = stack.StackSize * AnimalWeight;
                    float fraction          = weightedStackSize - (int)weightedStackSize;
                    stack.StackSize = (int)weightedStackSize + (entity.World.Rand.NextDouble() > fraction ? 1 : 0);
                }

                if (stack.StackSize == 0)
                {
                    continue;
                }

                todrop.Add(stack);
                if (dstack.LastDrop)
                {
                    break;
                }
            }

            //entity.World.Logger.Debug("setharvested drops resolved");

            ItemStack[] resolvedDrops = todrop.ToArray();

            TreeAttribute tree = new TreeAttribute();

            for (int i = 0; i < resolvedDrops.Length; i++)
            {
                inv[i].Itemstack = resolvedDrops[i];

                //entity.World.Logger.Debug("drop {0} is {1}", i, resolvedDrops[i]?.GetName());
            }

            inv.ToTreeAttributes(tree);
            entity.WatchedAttributes["harvestableInv"] = tree;
            entity.WatchedAttributes.MarkPathDirty("harvestableInv");
            entity.WatchedAttributes.MarkPathDirty("harvested");

            if (entity.World.Side == EnumAppSide.Server)
            {
                entity.World.BlockAccessor.GetChunkAtBlockPos(entity.ServerPos.AsBlockPos).MarkModified();
            }

            //entity.World.Logger.Debug("setharvested done");
        }