示例#1
0
        public override string GetPlacedBlockInfo(IWorldAccessor world, BlockPos pos, IPlayer forPlayer)
        {
            string text = "";

            float litres = GetCurrentLitres(pos);

            if (litres <= 0)
            {
                text = "";
            }

            BlockEntityCauld becauld = world.BlockAccessor.GetBlockEntity(pos) as BlockEntityCauld;

            if (becauld != null)
            {
                ItemSlot outslot = becauld.Inventory[5];
                ItemSlot inslot  = becauld.Inventory[6];
                if (text.Length > 0)
                {
                    text += "\n";
                }
                else
                {
                    text += Lang.Get("Contents:");
                }
                if (inslot.Empty && outslot.Empty)
                {
                    text += "\nEmpty";
                }
                else
                {
                    if (!outslot.Empty)
                    {
                        WaterTightContainableProps outprops = BlockLiquidContainerBase.GetContainableProps(outslot.Itemstack);
                        text += "\n" + Lang.Get("Potion out: {0} Litres of {1}", outslot.Itemstack.StackSize / outprops.ItemsPerLitre, outslot.Itemstack.GetName());
                    }

                    if (!inslot.Empty)
                    {
                        WaterTightContainableProps inprops = BlockLiquidContainerBase.GetContainableProps(inslot.Itemstack);
                        text += "\n" + Lang.Get("Potion in: {0} Litres of {1}", becauld.Inventory[6].Itemstack.StackSize / inprops.ItemsPerLitre, becauld.Inventory[6].Itemstack.GetName());
                    }
                    if (becauld.isFull)
                    {
                        text += "\nEmpty output to mix new potions";
                    }
                }
            }


            return(text);
        }
        protected override void ActivateSlotRightClick(ItemSlot sourceSlot, ref ItemStackMoveOperation op)
        {
            ItemSlotLiquidOnly liquidSlot = inventory[1] as ItemSlotLiquidOnly;
            IWorldAccessor     world      = inventory.Api.World;

            if (sourceSlot?.Itemstack?.Collectible is ILiquidSink sink && !liquidSlot.Empty && sink.AllowHeldLiquidTransfer)
            {
                ItemStack liqSlotStack         = liquidSlot.Itemstack;
                var       curTargetLiquidStack = sink.GetContent(sourceSlot.Itemstack);

                bool liquidstackable = curTargetLiquidStack == null || liqSlotStack.Equals(world, curTargetLiquidStack, GlobalConstants.IgnoredStackAttributes);

                if (liquidstackable)
                {
                    var lprops = BlockLiquidContainerBase.GetContainableProps(liqSlotStack);

                    float curSourceLitres = liqSlotStack.StackSize / lprops.ItemsPerLitre;
                    float curTargetLitres = sink.GetCurrentLitres(sourceSlot.Itemstack);

                    float toMoveLitres = op.CtrlDown ? sink.TransferSizeLitres : (sink.CapacityLitres - curTargetLitres);

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

                    if (toMoveLitres > 0)
                    {
                        op.MovedQuantity = sink.TryPutLiquid(sourceSlot.Itemstack, liqSlotStack, toMoveLitres / sourceSlot.StackSize);

                        liquidSlot.Itemstack.StackSize -= op.MovedQuantity * sourceSlot.StackSize;
                        if (liquidSlot.Itemstack.StackSize <= 0)
                        {
                            liquidSlot.Itemstack = null;
                        }
                        liquidSlot.MarkDirty();
                        sourceSlot.MarkDirty();

                        var pos = op.ActingPlayer?.Entity?.Pos;
                        if (pos != null)
                        {
                            op.World.PlaySoundAt(lprops.PourSound, pos.X, pos.Y, pos.Z);
                        }
                    }
                }

                return;
            }

            base.ActivateSlotRightClick(sourceSlot, ref op);
        }
示例#3
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);
        }
        private void fullnessMeterDraw(Context ctx, ImageSurface surface, ElementBounds currentBounds)
        {
            ItemSlot liquidSlot = Inventory[1]; // Water ID Slot

            if (liquidSlot.Empty)
            {
                return;
            }

            BlockEntitySingleSink besink = capi.World.BlockAccessor.GetBlockEntity(BlockEntityPosition) as BlockEntitySingleSink;
            float itemsPerLitre          = 1f;
            int   capacity = besink.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();
            }
        }
示例#5
0
        private void fullnessMeterDraw(Context ctx, ImageSurface surface, ElementBounds currentBounds)
        {
            ItemSlot liquidSlot = Inventory[6] as ItemSlot;

            if (liquidSlot.Empty)
            {
                return;
            }

            BlockEntityCauld becauld       = capi.World.BlockAccessor.GetBlockEntity(BlockEntityPosition) as BlockEntityCauld;
            float            itemsPerLitre = 1f;
            int capacity = becauld.capacityLitres;

            WaterTightContainableProps props = BlockLiquidContainerBase.GetContainableProps(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);

            CompositeTexture tex = props?.Texture ?? liquidSlot.Itemstack.Collectible.Attributes?["inContainerTexture"].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, true, false, tex.Alpha);

                ctx.Restore();
            }
        }
示例#6
0
        public override void OnItemSlotModified(ItemStack stack)
        {
            base.OnItemSlotModified(stack);

            if (itemstack == null)
            {
                return;
            }

            ItemSlotLiquidOnly liquidSlot = inventory[1] as ItemSlotLiquidOnly;

            bool stackable = !liquidSlot.Empty && liquidSlot.Itemstack.Equals(inventory.Api.World, itemstack, GlobalConstants.IgnoredStackAttributes);

            if (stackable)
            {
                int remaining = liquidSlot.Itemstack.Collectible.MaxStackSize - liquidSlot.Itemstack.StackSize;

                WaterTightContainableProps props = BlockLiquidContainerBase.GetInContainerProps(liquidSlot.Itemstack);
                if (props != null)
                {
                    int max         = (int)(liquidSlot.CapacityLitres * props.ItemsPerLitre);
                    int maxOverride = props.MaxStackSize;  //allows 64 rot to be placed in barrel
                    remaining = Math.Max(max, maxOverride) - liquidSlot.Itemstack.StackSize;
                }

                int moved = GameMath.Clamp(itemstack.StackSize, 0, remaining);
                liquidSlot.Itemstack.StackSize += moved;

                itemstack.StackSize -= moved;
                if (itemstack.StackSize <= 0)
                {
                    itemstack = null;
                }

                liquidSlot.MarkDirty();
                MarkDirty();
                return;
            }

            if (itemstack.Collectible.Attributes?.IsTrue("barrelMoveToLiquidSlot") == true || itemstack.Collectible.Attributes?["waterTightContainerProps"].Exists == true)
            {
                if (stackable)
                {
                    int remainingspace = itemstack.Collectible.MaxStackSize - liquidSlot.StackSize;
                    int movableq       = Math.Min(itemstack.StackSize, remainingspace);

                    liquidSlot.Itemstack.StackSize += movableq;
                    this.itemstack.StackSize       -= movableq;
                    if (StackSize <= 0)
                    {
                        itemstack = null;
                    }

                    MarkDirty();
                    liquidSlot.MarkDirty();
                    return;
                }
                if (liquidSlot.Empty)
                {
                    liquidSlot.Itemstack = this.itemstack.Clone();
                    this.itemstack       = null;
                    MarkDirty();
                    liquidSlot.MarkDirty();
                }
            }

            return;
        }
        protected override void ActivateSlotLeftClick(ItemSlot sourceSlot, ref ItemStackMoveOperation op)
        {
            if (sourceSlot.Empty)
            {
                base.ActivateSlotLeftClick(sourceSlot, ref op);
                return;
            }

            IWorldAccessor world = inventory.Api.World;

            if (sourceSlot.Itemstack.Collectible is ILiquidSource source && source.AllowHeldLiquidTransfer)
            {
                ItemSlotLiquidOnly liquidSlot = inventory[1] as ItemSlotLiquidOnly;

                ItemStack bucketContents = source.GetContent(sourceSlot.Itemstack);
                bool      stackable      = !liquidSlot.Empty && liquidSlot.Itemstack.Equals(world, bucketContents, GlobalConstants.IgnoredStackAttributes);

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

                    var lprops = BlockLiquidContainerBase.GetContainableProps(bucketContents);

                    float toMoveLitres    = op.CtrlDown ? source.TransferSizeLitres : source.CapacityLitres;
                    float curSourceLitres = bucketContents.StackSize / lprops.ItemsPerLitre * bucketStack.StackSize;
                    float curDestLitres   = liquidSlot.StackSize / lprops.ItemsPerLitre;

                    // Cap by source amount
                    toMoveLitres = Math.Min(toMoveLitres, curSourceLitres);
                    // Cap by target capacity
                    toMoveLitres = Math.Min(toMoveLitres, liquidSlot.CapacityLitres - curDestLitres);

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

                        takenContentStack.StackSize *= bucketStack.StackSize;
                        takenContentStack.StackSize += liquidSlot.StackSize;

                        liquidSlot.Itemstack = takenContentStack;
                        liquidSlot.MarkDirty();
                        op.MovedQuantity = moveQuantity;

                        var pos = op.ActingPlayer?.Entity?.Pos;
                        if (pos != null)
                        {
                            op.World.PlaySoundAt(lprops.FillSound, pos.X, pos.Y, pos.Z);
                        }
                    }

                    return;
                }

                return;
            }



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

            if (contentItemCode != null)
            {
                ItemSlot liquidSlot = inventory[1];

                ItemStack contentStack = new ItemStack(world.GetItem(new AssetLocation(contentItemCode)));
                bool      stackable    = !liquidSlot.Empty && liquidSlot.Itemstack.Equals(world, contentStack, GlobalConstants.IgnoredStackAttributes);

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

                    liquidSlot.MarkDirty();

                    ItemStack bowlStack = new ItemStack(world.GetBlock(new AssetLocation(sourceSlot.Itemstack.ItemAttributes["emptiedBlockCode"].AsString())));
                    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;
            }

            base.ActivateSlotLeftClick(sourceSlot, ref op);
        }
示例#8
0
        string getContentsText()
        {
            string contents = "Contents:";

            if (Inventory[0].Empty && Inventory[1].Empty && Inventory[2].Empty && Inventory[3].Empty && Inventory[4].Empty && Inventory[5].Empty && Inventory[6].Empty)
            {
                contents += "\nNone.";
            }
            else
            {
                BlockEntityCauld becauld = capi.World.BlockAccessor.GetBlockEntity(BlockEntityPosition) as BlockEntityCauld;
                if (!Inventory[6].Empty)
                {
                    ItemStack stack = Inventory[6].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 ? "Potion in: {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[5].Empty)
                {
                    ItemStack stack = Inventory[5].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 ? "Potion out: {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());
                    }
                }

                Dictionary <string, float> essencesDic   = new Dictionary <string, float>();
                Dictionary <string, float> maxEssenceDic = new Dictionary <string, float>();
                try
                {
                    IAsset maxEssences = capi.Assets.TryGet("alchemy:config/essences.json");
                    if (maxEssences != null)
                    {
                        maxEssenceDic = maxEssences.ToObject <Dictionary <string, float> >();
                    }
                }
                catch (Exception e)
                {
                    capi.World.Logger.Error("Failed loading potion effects for potion {0}. Will ignore. Exception: {1}", e);
                }
                for (int i = 0; i < 5; i++)
                {
                    if (!Inventory[i].Empty)
                    {
                        JsonObject essences = Inventory[i].Itemstack.ItemAttributes?["potionessences"];
                        foreach (var essence in maxEssenceDic.Keys.ToList())
                        {
                            if (essences[essence].Exists)
                            {
                                if (!essencesDic.ContainsKey(essence))
                                {
                                    essencesDic.Add(essence, 0);
                                }
                                essencesDic[essence] = (essencesDic[essence] + essences[essence].AsFloat() < maxEssenceDic[essence]) ? essencesDic[essence] += essences[essence].AsFloat() : maxEssenceDic[essence];
                                if (essencesDic[essence] == 0.0f)
                                {
                                    essencesDic.Remove(essence);
                                }
                            }
                        }
                    }
                }
                foreach (var essence in essencesDic.Keys.ToList())
                {
                    if (essence == "duration")
                    {
                        contents += "\n" + Lang.Get("increased duration by {0}", essencesDic[essence]);
                    }
                    else
                    {
                        contents += "\n" + Lang.Get("{0} units of {1} essence", essencesDic[essence], essence);
                    }
                }
                if (!Inventory[5].Empty)
                {
                    contents += "\n\nEmpty output to mix different new potions";
                }
            }

            return(contents);
        }
示例#9
0
        //Is there such thing as minimum litre amount? Can I dynamcally change colour and can I have a ghost item?
        public void MixCauld()
        {
            if (!inventory[6].Empty)
            {
                if (inventory[6].Itemstack.StackSize < 8)
                {
                    return;
                }
                float strongEffect;
                if (inventory[6].Itemstack.MatchesSearchText(Api.World, "Potion tea"))
                {
                    strongEffect = 1;
                }
                else if (inventory[6].Itemstack.MatchesSearchText(Api.World, "Aqua Vitae"))
                {
                    strongEffect = 2;
                }
                else
                {
                    return;
                }
                int canMix  = 0;
                int isEmpty = 0;
                Dictionary <string, float> essencesDic = new Dictionary <string, float>();
                for (int i = 0; i < 5; i++)
                {
                    if (!inventory[i].Empty)
                    {
                        JsonObject essences = inventory[i].Itemstack.ItemAttributes?["potionessences"];
                        //Api.Logger.Debug("{0}, {1}", inventory[i].Itemstack.Item.Code.ToShortString(), inventory[i].Itemstack.ItemAttributes.ToString());
                        if (inventory[i].Itemstack.ItemAttributes["potionessences"].KeyExists(inventory[i].Itemstack.Collectible.Code.ToShortString()))
                        {
                            essences = inventory[i].Itemstack.ItemAttributes?["potionessences"][inventory[i].Itemstack.Collectible.Code.ToShortString()];
                        }
                        bool hasEss = false;
                        foreach (var essence in maxEssenceDic.Keys.ToList())
                        {
                            if (essences[essence].Exists)
                            {
                                if (!essencesDic.ContainsKey(essence))
                                {
                                    essencesDic.Add(essence, 0);
                                }
                                essencesDic[essence] = (essencesDic[essence] + essences[essence].AsFloat() < maxEssenceDic[essence]) ? essencesDic[essence] += essences[essence].AsFloat() : maxEssenceDic[essence];
                                if (essencesDic[essence] == 0.0f)
                                {
                                    essencesDic.Remove(essence);
                                }
                                hasEss = true;
                            }
                        }
                        if (hasEss)
                        {
                            canMix += 1;
                        }
                    }
                    else
                    {
                        isEmpty += 1;
                    }
                }
                JsonObject baseEssences = inventory[6].Itemstack.ItemAttributes?["potionessences"];

                foreach (var essence in maxEssenceDic.Keys.ToList())
                {
                    if (baseEssences[essence].Exists)
                    {
                        if (!essencesDic.ContainsKey(essence))
                        {
                            essencesDic.Add(essence, 0);
                        }
                        essencesDic[essence] = (essencesDic[essence] + baseEssences[essence].AsFloat() < maxEssenceDic[essence]) ? essencesDic[essence] += baseEssences[essence].AsFloat() : maxEssenceDic[essence];
                        if (essencesDic[essence] == 0.0f)
                        {
                            essencesDic.Remove(essence);
                        }
                    }
                }
                canMix += isEmpty;
                if (canMix >= 5 && isEmpty < 5)
                {
                    if (!inventory[5].Empty)
                    {
                        ITreeAttribute outputEssences = Inventory[5].Itemstack.Attributes;
                        foreach (var essence in maxEssenceDic.Keys.ToList())
                        {
                            if (outputEssences.TryGetFloat("potion" + essence) != null)
                            {
                                if (!essencesDic.TryGetValue(essence, out float value))
                                {
                                    return;
                                }
                                else if (!(Math.Abs(essencesDic[essence] - outputEssences.GetFloat("potion" + essence)) < 1e-7))
                                {
                                    return;
                                }
                            }
                            else if (essencesDic.TryGetValue(essence, out float value))
                            {
                                return;
                            }
                        }
                    }

                    for (int i = 0; i <= 4; i++)
                    {
                        if (!inventory[i].Empty)
                        {
                            if (inventory[i].Itemstack.Collectible.IsLiquid())
                            {
                                var srcProps = BlockLiquidContainerBase.GetContainableProps(inventory[0].Itemstack);
                                int liquid   = (int)(inventory[0].Itemstack.StackSize / srcProps?.ItemsPerLitre) * 25;
                                inventory[i].TakeOut(liquid);
                            }
                            else
                            {
                                inventory[i].TakeOut(1);
                            }
                        }
                    }
                    //investigate litres change in ItemSlotWaterTight.cs and ItemsPerLitre
                    inventory[6].TakeOut(8);
                    if (inventory[5].Empty)
                    {
                        inventory[5].Itemstack = new ItemStack(Api.World.GetItem(new AssetLocation("alchemy:potionportion")), 8);
                        foreach (var essence in maxEssenceDic.Keys.ToList())
                        {
                            float value;
                            if (essencesDic.TryGetValue(essence, out value))
                            {
                                inventory[5].Itemstack.Attributes.SetFloat("potion" + essence, (float)Math.Round(value * strongEffect, 2));
                            }
                        }
                    }
                    else
                    {
                        inventory[5].Itemstack.StackSize += 8;
                    }
                    if (Api?.Side == EnumAppSide.Server)
                    {
                        MarkDirty(true);
                        Api.World.BlockAccessor.MarkBlockEntityDirty(Pos);
                    }
                    invDialog?.UpdateContents();
                    if (Api?.Side == EnumAppSide.Client)
                    {
                        currentMesh = GenMesh();
                        MarkDirty(true);
                    }
                    return;
                }
            }
        }