Ejemplo n.º 1
0
        public override void OnGroundIdle(EntityItem entityItem)
        {
            entityItem.Die(EnumDespawnReason.Removed);

            if (entityItem.World.Side == EnumAppSide.Server)
            {
                Vec3d pos = entityItem.ServerPos.XYZ;

                WaterTightContainableProps props = BlockLiquidContainerBase.GetContainableProps(entityItem.Itemstack);
                float litres = (float)entityItem.Itemstack.StackSize / props.ItemsPerLitre;

                entityItem.World.SpawnCubeParticles(pos, entityItem.Itemstack, 0.75f, Math.Min(100, (int)(2 * litres)), 0.45f);
                entityItem.World.PlaySoundAt(new AssetLocation("sounds/environment/smallsplash"), (float)pos.X, (float)pos.Y, (float)pos.Z, null);

                BlockEntityFarmland bef = api.World.BlockAccessor.GetBlockEntity(pos.AsBlockPos) as BlockEntityFarmland;
                if (bef != null)
                {
                    bef.WaterFarmland(Height.ToInt() / 6f, false);
                    bef.MarkDirty(true);
                }
            }



            base.OnGroundIdle(entityItem);
        }
Ejemplo n.º 2
0
        public override float GetMeltingDuration(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot)
        {
            float duration = 0;

            ItemStack[] stacks = GetCookingStacks(cookingSlotsProvider, false);
            for (int i = 0; i < stacks.Length; i++)
            {
                var stack       = stacks[i];
                int portionSize = stack.StackSize;

                if (stack.Collectible?.CombustibleProps == null)
                {
                    if (stack.Collectible.Attributes?["waterTightContainerProps"].Exists == true)
                    {
                        var props = BlockLiquidContainerBase.GetContainableProps(stack);
                        portionSize = (int)(stack.StackSize / props.ItemsPerLitre);
                    }

                    duration += 20 * portionSize;
                    continue;
                }

                float singleDuration = stack.Collectible.GetMeltingDuration(world, cookingSlotsProvider, inputSlot);
                duration += singleDuration * portionSize / stack.Collectible.CombustibleProps.SmeltedRatio;
            }

            duration = Math.Max(40, duration / 3);

            return(duration);
        }
Ejemplo n.º 3
0
        private void onTick100msServer(float dt)
        {
            if (MashSlot.Empty)
            {
                return;
            }

            var    juiceProps = getJuiceableProps(mashStack);
            double totalHours = Api.World.Calendar.TotalHours;

            double squeezeRel       = mashStack.Attributes.GetDouble("squeezeRel", 1);
            double litresToTransfer = Math.Min(juiceableLitresLeft, (totalHours - lastLiquidTransferTotalHours) * 50f);

            if (Api.Side == EnumAppSide.Server && squeezeRel < 1 && !squeezeSoundPlayed && juiceableLitresLeft > 0)
            {
                Api.World.PlaySoundAt(new AssetLocation("sounds/player/wetclothsqueeze.ogg"), Pos.X + 0.5, Pos.Y + 0.5, Pos.Z + 0.5, null, false);
                squeezeSoundPlayed = true;
            }

            if (Api.Side == EnumAppSide.Server && squeezeRel < 1 && totalHours - lastLiquidTransferTotalHours > 0.01)
            {
                ItemStack liquidStack = juiceProps.LiquidStack.ResolvedItemstack;
                liquidStack.StackSize = 999999;
                BlockLiquidContainerBase cntBlock = BucketSlot?.Itemstack?.Collectible as BlockLiquidContainerBase;

                if (cntBlock != null && litresToTransfer > 0)
                {
                    cntBlock.TryPutLiquid(BucketSlot.Itemstack, liquidStack, (float)litresToTransfer);
                }

                juiceableLitresLeft         -= (float)litresToTransfer;
                juiceableLitresTransfered   += (float)litresToTransfer;
                lastLiquidTransferTotalHours = totalHours;
                MarkDirty(true);
            }

            if (juiceableLitresLeft <= 0.01)
            {
                // Fugly hack to fix rounding errors
                BlockLiquidContainerBase cntBlock = BucketSlot?.Itemstack?.Collectible as BlockLiquidContainerBase;
                if (cntBlock != null)
                {
                    float litres = cntBlock.GetCurrentLitres(BucketSlot.Itemstack);
                    cntBlock.SetCurrentLitres(BucketSlot.Itemstack, (float)Math.Round(10 * litres) / 10f);
                }

                UnregisterGameTickListener(listenerId);
                listenerId = 0;

                int stacksize = GameMath.RoundRandom(Api.World.Rand, (float)juiceableLitresTransfered);
                mashStack.Attributes.RemoveAttribute("juiceableLitresTransfered");
                mashStack.Attributes.RemoveAttribute("juiceableLitresLeft");
                mashStack.StackSize = (int)(stacksize * juiceProps.PressedDryRatio);

                MarkDirty(true);
            }
        }
Ejemplo n.º 4
0
        private void FindMatchingRecipe()
        {
            ItemStack[] inputstacks = new ItemStack[] { inventory[0].Itemstack, inventory[1].Itemstack };
            CurrentRecipe = null;

            foreach (var recipe in api.World.BarrelRecipes)
            {
                int outsize;


                if (recipe.Matches(api.World, inputstacks, out outsize))
                {
                    ignoreChange = true;

                    if (recipe.SealHours > 0)
                    {
                        CurrentRecipe  = recipe;
                        CurrentOutSize = outsize;
                    }
                    else
                    {
                        ItemStack mixedStack = recipe.Output.ResolvedItemstack.Clone();
                        mixedStack.StackSize = outsize;

                        if (BlockLiquidContainerBase.GetStackProps(mixedStack) != null)
                        {
                            inventory[0].Itemstack = null;
                            inventory[1].Itemstack = mixedStack;
                        }
                        else
                        {
                            inventory[1].Itemstack = null;
                            inventory[0].Itemstack = mixedStack;
                        }


                        inventory[0].MarkDirty();
                        inventory[1].MarkDirty();
                        MarkDirty(true);
                        api.World.BlockAccessor.MarkBlockEntityDirty(pos);
                    }


                    invDialog?.UpdateContents();
                    if (api?.Side == EnumAppSide.Client)
                    {
                        currentMesh = GenMesh();
                        MarkDirty(true);
                    }

                    ignoreChange = false;
                    return;
                }
            }
        }
Ejemplo n.º 5
0
        string getContentsText()
        {
            string contents = "Contents:";

            if (Inventory[0].Empty && Inventory[1].Empty)
            {
                contents += "\nNone.";
            }
            else
            {
                if (!Inventory[1].Empty)
                {
                    ItemStack stack = Inventory[1].Itemstack;
                    WaterTightContainableProps props = BlockLiquidContainerBase.GetContainableProps(stack);

                    if (props != null)
                    {
                        string incontainername = Lang.Get("incontainer-" + stack.Class.ToString().ToLowerInvariant() + "-" + stack.Collectible.Code.Path);
                        contents += "\n" + Lang.Get(props.MaxStackSize > 0 ? "{0}x of {1}" : "{0} litres of {1}", (float)stack.StackSize / props.ItemsPerLitre, incontainername);
                    }
                    else
                    {
                        contents += "\n" + Lang.Get("{0}x of {1}", stack.StackSize, stack.GetName());
                    }
                }

                if (!Inventory[0].Empty)
                {
                    ItemStack stack = Inventory[0].Itemstack;
                    contents += "\n" + Lang.Get("{0}x of {1}", stack.StackSize, stack.GetName());
                }

                BlockEntityBarrel bebarrel = capi.World.BlockAccessor.GetBlockEntity(BlockEntityPosition) as BlockEntityBarrel;
                if (bebarrel.CurrentRecipe != null)
                {
                    ItemStack outStack = bebarrel.CurrentRecipe.Output.ResolvedItemstack;
                    WaterTightContainableProps props = BlockLiquidContainerBase.GetContainableProps(outStack);

                    string timeText = bebarrel.CurrentRecipe.SealHours > 24 ? Lang.Get("{0} days", Math.Round(bebarrel.CurrentRecipe.SealHours / capi.World.Calendar.HoursPerDay, 1)) : Lang.Get("{0} hours", bebarrel.CurrentRecipe.SealHours);

                    if (props != null)
                    {
                        string incontainername = Lang.Get("incontainer-" + outStack.Class.ToString().ToLowerInvariant() + "-" + outStack.Collectible.Code.Path);
                        float  litres          = (float)bebarrel.CurrentOutSize / props.ItemsPerLitre;
                        contents += "\n\n" + Lang.Get("Will turn into {0} litres of {1} after {2} of sealing.", litres, incontainername, timeText);
                    }
                    else
                    {
                        contents += "\n\n" + Lang.Get("Will turn into {0}x {1} after {2} of sealing.", bebarrel.CurrentOutSize, outStack.GetName(), timeText);
                    }
                }
            }

            return(contents);
        }
Ejemplo n.º 6
0
        public override void OnLoaded(ICoreAPI api)
        {
            base.OnLoaded(api);
            this.api = api;

            lcblock = block as BlockLiquidContainerBase;
            if (lcblock == null)
            {
                throw new InvalidOperationException(string.Format("Block with code {0} has behavior MilkingContainer, but its block class does not inherit from BlockLiquidContainerBase, which is required", block.Code));
            }
        }
Ejemplo n.º 7
0
        private void OnEvery3Second(float dt)
        {
            if (!inventory[0].Empty && CurrentRecipe == null)
            {
                FindMatchingRecipe();
            }

            if (CurrentRecipe != null && Sealed && CurrentRecipe.SealHours > 0)
            {
                if (api.World.Calendar.TotalHours - SealedSinceTotalHours > CurrentRecipe.SealHours)
                {
                    ItemStack mixedStack = CurrentRecipe.Output.ResolvedItemstack.Clone();
                    mixedStack.StackSize = CurrentOutSize;

                    // Carry over freshness
                    TransitionableProperties perishProps = mixedStack.Collectible.GetTransitionableProperties(api.World, mixedStack, null)?[0];

                    if (perishProps != null)
                    {
                        ItemSlot[] slots = new ItemSlot[inventory.Count];
                        for (int i = 0; i < inventory.Count; i++)
                        {
                            slots[i] = inventory[i];
                        }
                        BlockCookingContainer.CarryOverFreshness(api, slots, new ItemStack[] { mixedStack }, perishProps);
                    }

                    if (BlockLiquidContainerBase.GetStackProps(mixedStack) != null)
                    {
                        inventory[0].Itemstack = null;
                        inventory[1].Itemstack = mixedStack;
                    }
                    else
                    {
                        inventory[1].Itemstack = null;
                        inventory[0].Itemstack = mixedStack;
                    }



                    inventory[0].MarkDirty();
                    inventory[1].MarkDirty();

                    MarkDirty(true);
                    api.World.BlockAccessor.MarkBlockEntityDirty(pos);
                    Sealed = false;
                }
            }
            else
            {
                Sealed = false;
                MarkDirty(true);
            }
        }
Ejemplo n.º 8
0
        public override void GetBlockInfo(IPlayer forPlayer, StringBuilder dsc)
        {
            base.GetBlockInfo(forPlayer, dsc);

            if (!BucketSlot.Empty)
            {
                BlockLiquidContainerBase block = BucketSlot.Itemstack.Collectible as BlockLiquidContainerBase;
                dsc.Append("Bucket: ");
                block.GetContentInfo(BucketSlot, dsc, Api.World);
            }
        }
Ejemplo n.º 9
0
        public override void OnHeldInteractStart(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handHandling)
        {
            if (blockSel != null)
            {
                BlockEntityBarrel beba = api.World.BlockAccessor.GetBlockEntity(blockSel.Position) as BlockEntityBarrel;

                var liqslot = beba?.Inventory[1];

                if (beba != null && !liqslot.Empty)
                {
                    if (liqslot.Itemstack.Item?.Code?.Path == "cottagecheeseportion")
                    {
                        var   props     = BlockLiquidContainerBase.GetContainableProps(liqslot.Itemstack);
                        float curLitres = liqslot.Itemstack.StackSize / props.ItemsPerLitre;

                        if (curLitres < 25)
                        {
                            (api as ICoreClientAPI)?.TriggerIngameError(this, "notenough", Lang.Get("Need at least 25 litres to create a roll of cheese"));
                            handHandling = EnumHandHandling.PreventDefault;
                            return;
                        }

                        if (api.World.Side == EnumAppSide.Server)
                        {
                            ItemStack ccStack = beba.Inventory[1].TakeOut((int)(25 * props.ItemsPerLitre));

                            BlockCheeseCurdsBundle block = api.World.GetBlock(new AssetLocation("curdbundle")) as BlockCheeseCurdsBundle;
                            ItemStack bundleStack        = new ItemStack(block);
                            block.SetContents(bundleStack, ccStack);

                            slot.TakeOut(1);
                            slot.MarkDirty();

                            beba.MarkDirty(true);

                            if (!byEntity.TryGiveItemStack(bundleStack))
                            {
                                api.World.SpawnItemEntity(bundleStack, byEntity.Pos.XYZ.AddCopy(0, 0.5, 0));
                            }
                        }

                        handHandling = EnumHandHandling.PreventDefault;
                        return;
                    }
                }
            }

            base.OnHeldInteractStart(slot, byEntity, blockSel, entitySel, firstEvent, ref handHandling);
        }
Ejemplo n.º 10
0
        public override void OnGroundIdle(EntityItem entityItem)
        {
            entityItem.Die(EnumDespawnReason.Removed);

            if (entityItem.World.Side == EnumAppSide.Server)
            {
                WaterTightContainableProps props = BlockLiquidContainerBase.GetContainableProps(entityItem.Itemstack);
                float litres = (float)entityItem.Itemstack.StackSize / props.ItemsPerLitre;

                entityItem.World.SpawnCubeParticles(entityItem.SidedPos.XYZ, entityItem.Itemstack, 0.75f, (int)(litres * 2), 0.45f);
                entityItem.World.PlaySoundAt(new AssetLocation("sounds/environment/smallsplash"), (float)entityItem.SidedPos.X, (float)entityItem.SidedPos.Y, (float)entityItem.SidedPos.Z, null);
            }


            base.OnGroundIdle(entityItem);
        }
Ejemplo n.º 11
0
        public override string GetPlacedBlockInfo(IWorldAccessor world, BlockPos pos, IPlayer forPlayer)
        {
            StringBuilder dsc = new StringBuilder();

            dsc.AppendLine(base.GetPlacedBlockInfo(world, pos, forPlayer));

            BlockEntityCondenser be = world.BlockAccessor.GetBlockEntity(pos) as BlockEntityCondenser;

            if (be?.Inventory[1].Empty == false)
            {
                BlockLiquidContainerBase block = be.Inventory[1].Itemstack.Collectible as BlockLiquidContainerBase;
                dsc.Append("Bucket: ");
                block.GetContentInfo(be.Inventory[1], dsc, world);
            }

            return(dsc.ToString());
        }
Ejemplo n.º 12
0
        public override bool CanTakeFrom(ItemSlot sourceSlot, EnumMergePriority priority = EnumMergePriority.AutoMerge)
        {
            if (inventory?.PutLocked == true)
            {
                return(false);
            }

            ItemStack sourceStack = sourceSlot.Itemstack;

            if (sourceStack == null)
            {
                return(false);
            }

            WaterTightContainableProps props = BlockLiquidContainerBase.GetInContainerProps(sourceStack);

            return(props != null && (itemstack == null || itemstack.Collectible.GetMergableQuantity(itemstack, sourceStack, priority) > 0) && RemainingSlotSpace > 0);
        }
Ejemplo n.º 13
0
        private void fullnessMeterDraw(Context ctx, ImageSurface surface, ElementBounds currentBounds)
        {
            ItemSlot liquidSlot = Inventory[1];

            if (liquidSlot.Empty)
            {
                return;
            }

            BlockEntityBarrel bebarrel      = capi.World.BlockAccessor.GetBlockEntity(BlockEntityPosition) as BlockEntityBarrel;
            float             itemsPerLitre = 1f;
            int capacity = bebarrel.CapacityLitres;

            WaterTightContainableProps props = BlockLiquidContainerBase.GetInContainerProps(liquidSlot.Itemstack);

            if (props != null)
            {
                itemsPerLitre = props.ItemsPerLitre;
                capacity      = Math.Max(capacity, props.MaxStackSize);
            }

            float fullnessRelative = liquidSlot.StackSize / itemsPerLitre / capacity;

            double offY = (1 - fullnessRelative) * currentBounds.InnerHeight;

            ctx.Rectangle(0, offY, currentBounds.InnerWidth, currentBounds.InnerHeight - offY);
            //ctx.SetSourceRGBA(ravg/255.0, gavg / 255.0, bavg / 255.0, aavg / 255.0);
            //ctx.Fill();

            CompositeTexture tex = liquidSlot.Itemstack.Collectible.Attributes?["waterTightContainerProps"]?["texture"]?.AsObject <CompositeTexture>(null, liquidSlot.Itemstack.Collectible.Code.Domain);

            if (tex != null)
            {
                ctx.Save();
                Matrix m = ctx.Matrix;
                m.Scale(GuiElement.scaled(3), GuiElement.scaled(3));
                ctx.Matrix = m;

                AssetLocation loc = tex.Base.Clone().WithPathAppendixOnce(".png");
                GuiElement.fillWithPattern(capi, ctx, loc.Path, true, false);

                ctx.Restore();
            }
        }
Ejemplo n.º 14
0
        public override void OnHeldInteractStart(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handHandling)
        {
            if (blockSel == null)
            {
                base.OnHeldInteractStart(slot, byEntity, blockSel, entitySel, firstEvent, ref handHandling);
                return;
            }

            BlockLiquidContainerBase blockLiqContainer = byEntity.World.BlockAccessor.GetBlock(blockSel.Position) as BlockLiquidContainerBase;
            string contents = BowlContentItemCode();

            if (blockLiqContainer != null)
            {
                if (contents == null)
                {
                    ItemStack stack = blockLiqContainer.GetContent(byEntity.World, blockSel.Position);
                    if (stack != null && ContentBlockForContents(stack.Collectible.Code.Path) != null)
                    {
                        InsertIntoBowl(slot, byEntity, stack.Collectible.Code.Path);
                        blockLiqContainer.TryTakeContent(byEntity.World, blockSel.Position, 1);
                    }
                }
                else
                {
                    ItemStack stack = blockLiqContainer.GetContent(byEntity.World, blockSel.Position);
                    if (stack == null || stack.Collectible.Code.Equals(new AssetLocation(BowlContentItemCode())))
                    {
                        Item contentItem = byEntity.World.GetItem(new AssetLocation(BowlContentItemCode()));
                        if (blockLiqContainer.TryPutContent(byEntity.World, blockSel.Position, new ItemStack(contentItem), 1) > 0)
                        {
                            EmptyOutBowl(slot, byEntity);
                        }
                    }
                }

                handHandling = EnumHandHandling.PreventDefaultAction;
                return;
            }

            handHandling = EnumHandHandling.PreventDefault;

            base.OnHeldInteractStart(slot, byEntity, blockSel, entitySel, firstEvent, ref handHandling);
        }
Ejemplo n.º 15
0
        public void MilkingComplete(ItemSlot slot, EntityAgent byEntity)
        {
            lastMilkedTotalHours = entity.World.Calendar.TotalHours;
            entity.WatchedAttributes.SetFloat("lastMilkedTotalHours", (float)lastMilkedTotalHours);

            BlockLiquidContainerBase lcblock = slot.Itemstack.Collectible as BlockLiquidContainerBase;

            if (lcblock == null)
            {
                return;
            }

            if (entity.World.Side == EnumAppSide.Server)
            {
                ItemStack contentStack = new ItemStack(byEntity.World.GetItem(new AssetLocation("milkportion")));
                contentStack.StackSize = 999999;

                if (slot.Itemstack.StackSize == 1)
                {
                    lcblock.TryPutLiquid(slot.Itemstack, contentStack, yieldLitres);
                }
                else
                {
                    ItemStack containerStack = slot.TakeOut(1);
                    lcblock.TryPutLiquid(containerStack, contentStack, yieldLitres);

                    if (!byEntity.TryGiveItemStack(containerStack))
                    {
                        byEntity.World.SpawnItemEntity(containerStack, byEntity.Pos.XYZ.Add(0, 0.5, 0));
                    }
                }

                slot.MarkDirty();
            }

            milkSound?.Stop();
            milkSound?.Dispose();
        }
Ejemplo n.º 16
0
        public void RenderLiquidItemStackGui(ItemSlot inSlot, ItemRenderInfo renderInfo, Matrixf modelMat, double posX, double posY, double posZ, float size, int color, bool rotate = false, bool showStackSize = true)
        {
            ItemStack itemstack = inSlot.Itemstack;

            WaterTightContainableProps props = BlockLiquidContainerBase.GetContainableProps(itemstack);

            capi.Render.RenderMesh(renderInfo.ModelRef);


            if (showStackSize)
            {
                float  litreFloat = (float)itemstack.StackSize / props.ItemsPerLitre;
                string litres;
                if (litreFloat < 0.1)
                {
                    litres = Lang.Get("{0} mL", (int)(litreFloat * 1000));
                }
                else
                {
                    litres = Lang.Get("{0:0.##} L", litreFloat);
                }

                float mul = size / (float)GuiElement.scaled(32 * 0.8f);

                var texttex = GetOrCreateLitreTexture(litres, size, mul);

                capi.Render.GlToggleBlend(true, EnumBlendMode.PremultipliedAlpha);

                capi.Render.Render2DLoadedTexture(texttex,
                                                  (int)(posX + size + 1 - texttex.Width - GuiElement.scaled(1)),
                                                  (int)(posY + size - texttex.Height + mul * GuiElement.scaled(3) - GuiElement.scaled(5)),
                                                  (int)posZ + 60
                                                  );

                capi.Render.GlToggleBlend(true, EnumBlendMode.Standard);
            }
        }
Ejemplo n.º 17
0
        public bool Resolve(IWorldAccessor world, string sourceForErrorLogging)
        {
            bool ok = true;

            for (int i = 0; i < Ingredients.Length; i++)
            {
                var  ingred = Ingredients[i];
                bool iOk    = ingred.Resolve(world, sourceForErrorLogging);
                ok &= iOk;

                if (iOk)
                {
                    var lprops = BlockLiquidContainerBase.GetContainableProps(ingred.ResolvedItemstack);
                    if (lprops != null)
                    {
                        if (ingred.Litres < 0)
                        {
                            if (ingred.Quantity > 0)
                            {
                                world.Logger.Warning("Barrel recipe {0}, ingredient {1} does not define a litres attribute but a quantity, will assume quantity=litres for backwards compatibility.", sourceForErrorLogging, ingred.Code);
                                ingred.Litres        = ingred.Quantity;
                                ingred.ConsumeLitres = ingred.ConsumeQuantity;
                            }
                            else
                            {
                                ingred.Litres = 1;
                            }
                        }

                        ingred.Quantity = (int)(lprops.ItemsPerLitre * ingred.Litres);
                        if (ingred.ConsumeLitres != null)
                        {
                            ingred.ConsumeQuantity = (int)(lprops.ItemsPerLitre * ingred.ConsumeLitres);
                        }
                    }
                }
            }

            ok &= Output.Resolve(world, sourceForErrorLogging);

            if (ok)
            {
                var lprops = BlockLiquidContainerBase.GetContainableProps(Output.ResolvedItemstack);
                if (lprops != null)
                {
                    if (Output.Litres < 0)
                    {
                        if (Output.Quantity > 0)
                        {
                            world.Logger.Warning("Barrel recipe {0}, output {1} does not define a litres attribute but a stacksize, will assume stacksize=litres for backwards compatibility.", sourceForErrorLogging, Output.Code);
                            Output.Litres = Output.Quantity;
                        }
                        else
                        {
                            Output.Litres = 1;
                        }
                    }

                    Output.Quantity = (int)(lprops.ItemsPerLitre * Output.Litres);
                }
            }

            return(ok);
        }
Ejemplo n.º 18
0
        public bool Matches(ItemStack[] inputStacks, ref int quantityServings)
        {
            List <ItemStack> inputStacksList = new List <ItemStack>(inputStacks);
            List <CookingRecipeIngredient> ingredientList = new List <CookingRecipeIngredient>(Ingredients);

            int totalOutputQuantity = 99999;

            int[] curQuantities = new int[ingredientList.Count];
            for (int i = 0; i < curQuantities.Length; i++)
            {
                curQuantities[i] = 0;
            }

            while (inputStacksList.Count > 0)
            {
                ItemStack inputStack = inputStacksList[0];
                inputStacksList.RemoveAt(0);
                if (inputStack == null)
                {
                    continue;
                }

                bool found = false;
                for (int i = 0; i < ingredientList.Count; i++)
                {
                    CookingRecipeIngredient ingred = ingredientList[i];

                    if (ingred.Matches(inputStack))
                    {
                        if (curQuantities[i] >= ingred.MaxQuantity)
                        {
                            continue;
                        }

                        totalOutputQuantity = Math.Min(totalOutputQuantity, inputStack.StackSize);
                        curQuantities[i]++;
                        found = true;
                        break;
                    }
                }

                // This input stack does not fit in this cooking recipe
                if (!found)
                {
                    return(false);
                }
            }

            // Any required ingredients left?
            for (int i = 0; i < ingredientList.Count; i++)
            {
                if (curQuantities[i] < ingredientList[i].MinQuantity)
                {
                    return(false);
                }
            }

            quantityServings = totalOutputQuantity;

            // Too many ingredients?
            for (int i = 0; i < inputStacks.Length; i++)
            {
                var stack = inputStacks[i];
                if (stack == null)
                {
                    continue;
                }

                int qportions = stack.StackSize;

                if (stack.Collectible.Attributes?["waterTightContainerProps"].Exists == true)
                {
                    var props = BlockLiquidContainerBase.GetContainableProps(stack);
                    qportions = (int)(stack.StackSize / props.ItemsPerLitre / GetIngrendientFor(stack).PortionSizeLitres);
                }

                if (qportions != quantityServings)
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 19
0
        public override bool CanHold(ItemSlot itemstackFromSourceSlot)
        {
            WaterTightContainableProps props = BlockLiquidContainerBase.GetInContainerProps(itemstackFromSourceSlot.Itemstack);

            return(props != null);
        }
Ejemplo n.º 20
0
        public override void OnHeldInteractStart(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handHandling)
        {
            if (blockSel == null)
            {
                base.OnHeldInteractStart(slot, byEntity, blockSel, entitySel, firstEvent, ref handHandling);
                return;
            }

            BlockLiquidContainerBase blockLiqContainer = byEntity.World.BlockAccessor.GetBlock(blockSel.Position) as BlockLiquidContainerBase;
            IPlayer player = (byEntity as EntityPlayer)?.Player;

            string contents = BowlContentItemCode();

            if (blockLiqContainer != null)
            {
                if (contents == null)
                {
                    ItemStack stack = blockLiqContainer.GetContent(byEntity.World, blockSel.Position);
                    if (stack != null && ContentBlockForContents(stack.Collectible.Code.Path) != null)
                    {
                        InsertIntoBowl(slot, byEntity, stack.Collectible.Code.Path);
                        blockLiqContainer.TryTakeContent(byEntity.World, blockSel.Position, 1);
                    }

                    BlockEntityContainer bebarrel = api.World.BlockAccessor.GetBlockEntity(blockSel.Position) as BlockEntityContainer;
                    if (bebarrel != null && bebarrel.Inventory.Count > 0)
                    {
                        stack = bebarrel.Inventory[0].Itemstack;

                        if (stack != null && stack.Collectible.Attributes["crockable"].AsBool() == true)
                        {
                            Block     mealblock = api.World.GetBlock(AssetLocation.Create(slot.Itemstack.Collectible.Attributes["mealBlockCode"].AsString(), slot.Itemstack.Collectible.Code.Domain));
                            ItemStack mealstack = new ItemStack(mealblock);
                            mealstack.StackSize = 1;

                            (mealblock as IBlockMealContainer).SetContents(null, mealstack, new ItemStack[] { bebarrel.Inventory[0].TakeOut(4) }, 1);

                            if (slot.StackSize == 1)
                            {
                                slot.Itemstack = mealstack;
                            }
                            else
                            {
                                slot.TakeOut(1);
                                if (!player.InventoryManager.TryGiveItemstack(mealstack, true))
                                {
                                    api.World.SpawnItemEntity(mealstack, byEntity.Pos.XYZ.Add(0.5, 0.5, 0.5));
                                }
                            }
                            slot.MarkDirty();

                            bebarrel.MarkDirty(true);
                        }
                    }
                }
                else
                {
                    ItemStack stack = blockLiqContainer.GetContent(byEntity.World, blockSel.Position);
                    if (stack == null || stack.Collectible.Code.Equals(new AssetLocation(BowlContentItemCode())))
                    {
                        Item contentItem = byEntity.World.GetItem(new AssetLocation(BowlContentItemCode()));
                        if (blockLiqContainer.TryPutContent(byEntity.World, blockSel.Position, new ItemStack(contentItem), 1) > 0)
                        {
                            EmptyOutBowl(slot, byEntity);
                        }
                    }
                }

                handHandling = EnumHandHandling.PreventDefaultAction;
                return;
            }


            handHandling = EnumHandHandling.PreventDefault;

            base.OnHeldInteractStart(slot, byEntity, blockSel, entitySel, firstEvent, ref handHandling);
        }
        protected override void ActivateSlotLeftClick(ItemSlot sourceSlot, ref ItemStackMoveOperation op)
        {
            IWorldAccessor           world       = inventory.Api.World;
            BlockLiquidContainerBase liqCntBlock = sourceSlot.Itemstack?.Block as BlockLiquidContainerBase;

            if (liqCntBlock != null)
            {
                ItemStack contentStack = liqCntBlock.GetContent(sourceSlot.Itemstack);
                var       liqProps     = BlockLiquidContainerBase.GetContainableProps(contentStack);

                bool stackable = !Empty && itemstack.Equals(world, contentStack, GlobalConstants.IgnoredStackAttributes);

                if ((Empty || stackable) && contentStack != null)
                {
                    ItemStack bucketStack = sourceSlot.Itemstack;

                    float toMoveLitres  = (op?.ActingPlayer?.Entity.Controls.Sneak ?? false) ? liqCntBlock.CapacityLitres : liqCntBlock.TransferSizeLitres;
                    float curDestLitres = StackSize / liqProps.ItemsPerLitre;
                    float curSrcLitres  = contentStack.StackSize / liqProps.ItemsPerLitre;

                    toMoveLitres = Math.Min(toMoveLitres, curSrcLitres);

                    toMoveLitres *= bucketStack.StackSize;
                    toMoveLitres  = Math.Min(toMoveLitres, capacityLitres - curDestLitres);

                    if (toMoveLitres > 0)
                    {
                        int       moveQuantity      = (int)(liqProps.ItemsPerLitre * toMoveLitres);
                        ItemStack takenContentStack = liqCntBlock.TryTakeContent(bucketStack, moveQuantity / bucketStack.StackSize);

                        takenContentStack.StackSize *= bucketStack.StackSize;
                        takenContentStack.StackSize += StackSize;
                        this.itemstack = takenContentStack;
                        MarkDirty();
                        op.MovedQuantity = moveQuantity;
                    }
                }

                return;
            }

            string contentItemCode = sourceSlot.Itemstack?.ItemAttributes?["contentItemCode"].AsString();

            if (contentItemCode != null)
            {
                ItemStack contentStack = new ItemStack(world.GetItem(AssetLocation.Create(contentItemCode, sourceSlot.Itemstack.Collectible.Code.Domain)));
                bool      stackable    = !Empty && itemstack.Equals(world, contentStack, GlobalConstants.IgnoredStackAttributes);

                if ((Empty || stackable) && contentStack != null)
                {
                    if (stackable)
                    {
                        this.itemstack.StackSize++;
                    }
                    else
                    {
                        this.itemstack = contentStack;
                    }

                    MarkDirty();
                    ItemStack bowlStack = new ItemStack(world.GetBlock(AssetLocation.Create(sourceSlot.Itemstack.ItemAttributes["emptiedBlockCode"].AsString(), sourceSlot.Itemstack.Collectible.Code.Domain)));
                    if (sourceSlot.StackSize == 1)
                    {
                        sourceSlot.Itemstack = bowlStack;
                    }
                    else
                    {
                        sourceSlot.Itemstack.StackSize--;
                        if (!op.ActingPlayer.InventoryManager.TryGiveItemstack(bowlStack))
                        {
                            world.SpawnItemEntity(bowlStack, op.ActingPlayer.Entity.Pos.XYZ);
                        }
                    }
                    sourceSlot.MarkDirty();
                }

                return;
            }

            if (sourceSlot.Itemstack?.ItemAttributes?["contentItem2BlockCodes"].Exists == true)
            {
                return;
            }

            base.ActivateSlotLeftClick(sourceSlot, ref op);
        }
        protected override void ActivateSlotRightClick(ItemSlot sourceSlot, ref ItemStackMoveOperation op)
        {
            IWorldAccessor           world       = inventory.Api.World;
            BlockLiquidContainerBase liqCntBlock = sourceSlot.Itemstack?.Block as BlockLiquidContainerBase;

            if (liqCntBlock != null)
            {
                if (Empty)
                {
                    return;
                }

                ItemStack contentStack = liqCntBlock.GetContent(sourceSlot.Itemstack);

                float toMoveLitres    = op.ShiftDown ? liqCntBlock.CapacityLitres : liqCntBlock.TransferSizeLitres;
                var   srcProps        = BlockLiquidContainerBase.GetContainableProps(Itemstack);
                float availableLitres = StackSize / (srcProps?.ItemsPerLitre ?? 1);

                toMoveLitres  = Math.Min(toMoveLitres, availableLitres);
                toMoveLitres *= sourceSlot.Itemstack.StackSize;

                if (contentStack == null)
                {
                    int moved = liqCntBlock.TryPutLiquid(sourceSlot.Itemstack, Itemstack, toMoveLitres / sourceSlot.Itemstack.StackSize);
                    TakeOut(moved * sourceSlot.Itemstack.StackSize);
                    MarkDirty();
                }
                else
                {
                    if (itemstack.Equals(world, contentStack, GlobalConstants.IgnoredStackAttributes))
                    {
                        int moved = liqCntBlock.TryPutLiquid(sourceSlot.Itemstack, liqCntBlock.GetContent(sourceSlot.Itemstack), toMoveLitres / sourceSlot.Itemstack.StackSize);
                        TakeOut(moved * sourceSlot.Itemstack.StackSize);
                        MarkDirty();
                        return;
                    }
                }

                return;
            }


            if (itemstack != null && sourceSlot.Itemstack?.ItemAttributes?["contentItem2BlockCodes"].Exists == true)
            {
                string outBlockCode = sourceSlot.Itemstack.ItemAttributes["contentItem2BlockCodes"][itemstack.Collectible.Code.ToShortString()].AsString();

                if (outBlockCode != null)
                {
                    ItemStack outBlockStack = new ItemStack(world.GetBlock(AssetLocation.Create(outBlockCode, sourceSlot.Itemstack.Collectible.Code.Domain)));

                    if (sourceSlot.StackSize == 1)
                    {
                        sourceSlot.Itemstack = outBlockStack;
                    }
                    else
                    {
                        sourceSlot.Itemstack.StackSize--;
                        if (!op.ActingPlayer.InventoryManager.TryGiveItemstack(outBlockStack))
                        {
                            world.SpawnItemEntity(outBlockStack, op.ActingPlayer.Entity.Pos.XYZ);
                        }
                    }

                    sourceSlot.MarkDirty();
                    TakeOut(1);
                }

                return;
            }

            if (sourceSlot.Itemstack?.ItemAttributes?["contentItem2BlockCodes"].Exists == true || sourceSlot.Itemstack?.ItemAttributes?["contentItemCode"].AsString() != null)
            {
                return;
            }

            base.ActivateSlotRightClick(sourceSlot, ref op);
        }