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); }
public override void OnHeldInteractStart(IItemSlot itemslot, IEntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, ref EnumHandHandling handHandling) { if (blockSel == null || byEntity.Controls.Sneak) { return; } IPlayer byPlayer = (byEntity as EntityPlayer)?.Player; Block targetedBlock = byEntity.World.BlockAccessor.GetBlock(blockSel.Position); if (targetedBlock.HasBehavior(typeof(BlockBehaviorLiquidContainer), true)) { if (!byEntity.World.TestPlayerAccessBlock(byPlayer, blockSel.Position, EnumBlockAccessFlags.Use)) { return; } BlockBehaviorLiquidContainer bh = targetedBlock.GetBehavior(typeof(BlockBehaviorLiquidContainer), true) as BlockBehaviorLiquidContainer; if (bh.OnInteractWithBucket(itemslot, byEntity, blockSel)) { handHandling = EnumHandHandling.PreventDefaultAction; return; } } if (!byEntity.World.TestPlayerAccessBlock(byPlayer, blockSel.Position, EnumBlockAccessFlags.BuildOrBreak)) { return; } ItemStack contentStack = GetContent(byEntity.World, itemslot.Itemstack); bool isEmpty = contentStack == null; if (!TryFillBucketFromBlock(itemslot, byEntity, blockSel.Position)) { BlockBucket targetBucket = targetedBlock as BlockBucket; if (targetBucket != null) { if (targetBucket.TryAddContent(byEntity.World, blockSel.Position, contentStack, 1) > 0) { TryTakeContent(byEntity.World, itemslot.Itemstack, 1); WaterTightContainableProps props = GetContentProps(byEntity.World, itemslot.Itemstack); byEntity.World.PlaySoundAt(props.FillSpillSound, blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z, byPlayer); } } else { SpillContents(itemslot, byEntity, blockSel); } } // Prevent placing on normal use handHandling = EnumHandHandling.PreventDefaultAction; }
public override void TryMergeStacks(ItemStackMergeOperation op) { op.MovableQuantity = GetMergableQuantity(op.SinkSlot.Itemstack, op.SourceSlot.Itemstack); if (op.MovableQuantity == 0) { return; } if (!op.SinkSlot.CanTakeFrom(op.SourceSlot)) { return; } ItemStack sinkContent = GetContent(op.World, op.SinkSlot.Itemstack); ItemStack sourceContent = GetContent(op.World, op.SourceSlot.Itemstack); if (sinkContent == null && sourceContent == null) { base.TryMergeStacks(op); return; } if (sinkContent == null || sourceContent == null) { op.MovableQuantity = 0; return; } if (!sinkContent.Equals(op.World, sourceContent, GlobalConstants.IgnoredStackAttributes)) { op.MovableQuantity = 0; return; } WaterTightContainableProps props = GetStackProps(sourceContent); float maxItems = BucketCapacityLitres * props.ItemsPerLitre; int sourceEmptySpace = (int)(maxItems - (float)sourceContent.StackSize / props.ItemsPerLitre); int sinkEmptySpace = (int)(maxItems - (float)sinkContent.StackSize / props.ItemsPerLitre); if (sourceEmptySpace == 0 && sinkEmptySpace == 0) { // Full buckets are not stackable op.MovableQuantity = 0; //base.TryMergeStacks(op); return; } if (op.CurrentPriority == EnumMergePriority.DirectMerge) { int moved = TryAddContent(op.World, op.SinkSlot.Itemstack, sinkContent, sourceContent.StackSize); TryTakeContent(op.World, op.SourceSlot.Itemstack, moved); op.SourceSlot.MarkDirty(); op.SinkSlot.MarkDirty(); } op.MovableQuantity = 0; return; }
public MeshData GenMesh(ICoreClientAPI capi, ItemStack contentStack, BlockPos forBlockPos = null) { Shape shape = capi.Assets.TryGet("shapes/block/wood/bucket/empty.json").ToObject <Shape>(); MeshData bucketmesh; capi.Tesselator.TesselateShape(this, shape, out bucketmesh); if (contentStack != null) { WaterTightContainableProps props = GetInContainerProps(contentStack); ContainerTextureSource contentSource = new ContainerTextureSource(capi, contentStack, props.Texture); shape = capi.Assets.TryGet("shapes/block/wood/bucket/contents.json").ToObject <Shape>(); MeshData contentMesh; capi.Tesselator.TesselateShape("bucket", shape, out contentMesh, contentSource, new Vec3f(Shape.rotateX, Shape.rotateY, Shape.rotateZ)); contentMesh.Translate(0, GameMath.Min(7 / 16f, contentStack.StackSize / props.ItemsPerLitre * 0.7f / 16f), 0); if (props.ClimateColorMap != null) { int col = capi.World.ApplyColorMapOnRgba(props.ClimateColorMap, null, ColorUtil.WhiteArgb, 196, 128, false); if (forBlockPos != null) { col = capi.World.ApplyColorMapOnRgba(props.ClimateColorMap, null, ColorUtil.WhiteArgb, forBlockPos.X, forBlockPos.Y, forBlockPos.Z, false); } byte[] rgba = ColorUtil.ToBGRABytes(col); for (int i = 0; i < contentMesh.Rgba.Length; i++) { contentMesh.Rgba[i] = (byte)((contentMesh.Rgba[i] * rgba[i % 4]) / 255); } } for (int i = 0; i < contentMesh.Flags.Length; i++) { contentMesh.Flags[i] = contentMesh.Flags[i] & ~(1 << 12); // Remove water waving flag } bucketmesh.AddMeshData(contentMesh); // Water flags if (forBlockPos != null) { bucketmesh.CustomInts = new CustomMeshDataPartInt(bucketmesh.FlagsCount); bucketmesh.CustomInts.Count = bucketmesh.FlagsCount; bucketmesh.CustomInts.Values.Fill(0x4000000); // light foam only bucketmesh.CustomFloats = new CustomMeshDataPartFloat(bucketmesh.FlagsCount * 2); bucketmesh.CustomFloats.Count = bucketmesh.FlagsCount * 2; } } return(bucketmesh); }
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); }
/// <summary> /// Fill level in litres. From 0...BucketCapacity. From a placed bucket block /// </summary> /// <param name="world"></param> /// <param name="bucketStack"></param> /// <returns></returns> public float GetCurrentLitres(IWorldAccessor world, BlockPos pos) { WaterTightContainableProps props = GetContentProps(world, pos); if (props == null) { return(0); } return(GetContent(world, pos).StackSize / props.ItemsPerLitre); }
/// <summary> /// Fill level in litres. From 0...BucketCapacity /// </summary> /// <param name="world"></param> /// <param name="bucketStack"></param> /// <returns></returns> public float GetCurrentLitres(IWorldAccessor world, ItemStack bucketStack) { WaterTightContainableProps props = GetContentProps(world, bucketStack); if (props == null) { return(0); } return(GetContent(world, bucketStack).StackSize / props.ItemsPerLitre); }
protected MeshData getContentMesh(ItemStack stack, BlockPos forBlockPos, string shapefilename) { ICoreClientAPI capi = api as ICoreClientAPI; WaterTightContainableProps props = GetContainableProps(stack); ITexPositionSource contentSource; float fillHeight; if (props != null) { contentSource = new ContainerTextureSource(capi, stack, props.Texture); fillHeight = GameMath.Min(1f, stack.StackSize / props.ItemsPerLitre / Math.Max(50, props.MaxStackSize)) * 10f / 16f; if (props.Texture == null) { return(null); } } else { contentSource = getContentTexture(capi, stack, out fillHeight); } if (stack != null && contentSource != null) { Shape shape = capi.Assets.TryGet("shapes/block/wood/barrel/" + shapefilename).ToObject <Shape>(); MeshData contentMesh; capi.Tesselator.TesselateShape("barrel", shape, out contentMesh, contentSource, new Vec3f(Shape.rotateX, Shape.rotateY, Shape.rotateZ)); contentMesh.Translate(0, fillHeight, 0); if (props?.ClimateColorMap != null) { int col = capi.World.ApplyColorMapOnRgba(props.ClimateColorMap, null, ColorUtil.WhiteArgb, 196, 128, false); if (forBlockPos != null) { col = capi.World.ApplyColorMapOnRgba(props.ClimateColorMap, null, ColorUtil.WhiteArgb, forBlockPos.X, forBlockPos.Y, forBlockPos.Z, false); } byte[] rgba = ColorUtil.ToBGRABytes(col); for (int i = 0; i < contentMesh.Rgba.Length; i++) { contentMesh.Rgba[i] = (byte)((contentMesh.Rgba[i] * rgba[i % 4]) / 255); } } return(contentMesh); } return(null); }
/// <summary> /// Tries to put as much items/liquid as possible into a placed container and returns it how much items it actually moved /// </summary> /// <param name="world"></param> /// <param name="pos"></param> /// <param name="quantity"></param> public virtual int TryPutContent(IWorldAccessor world, BlockPos pos, ItemStack contentStack, int quantity) { if (contentStack == null) { return(0); } float availItems = contentStack.StackSize; ItemStack stack = GetContent(world, pos); if (stack == null) { WaterTightContainableProps props = GetInContainerProps(contentStack); if (props == null || !props.Containable) { return(0); } float maxItems = CapacityLitres * props.ItemsPerLitre; int placeableItems = (int)GameMath.Min(quantity, maxItems, availItems); ItemStack placedstack = contentStack.Clone(); placedstack.StackSize = Math.Min(quantity, placeableItems); SetContent(world, pos, placedstack); return(Math.Min(quantity, placeableItems)); } else { if (!stack.Equals(world, contentStack, GlobalConstants.IgnoredStackAttributes)) { return(0); } WaterTightContainableProps props = GetContentProps(world, pos); float maxItems = CapacityLitres * props.ItemsPerLitre; int placeableItems = (int)Math.Min(availItems, maxItems - (float)stack.StackSize); stack.StackSize += Math.Min(placeableItems, quantity); world.BlockAccessor.GetBlockEntity(pos).MarkDirty(true); (world.BlockAccessor.GetBlockEntity(pos) as BlockEntityContainer).Inventory[GetContainerSlotId(world, pos)].MarkDirty(); return(Math.Min(placeableItems, quantity)); } }
public void TryFillBucketFromBlock(EntityItem byEntityItem, BlockPos pos) { IWorldAccessor world = byEntityItem.World; Block block = world.BlockAccessor.GetBlock(pos); if (block.Attributes?["waterTightContainerProps"].Exists == false) { return; } WaterTightContainableProps props = block.Attributes?["waterTightContainerProps"].AsObject <WaterTightContainableProps>(); if (props?.WhenFilled == null || !props.Containable) { return; } if (props.WhenFilled.Stack.ResolvedItemstack == null) { props.WhenFilled.Stack.Resolve(world, "blockbucket"); } ItemStack whenFilledStack = props.WhenFilled.Stack.ResolvedItemstack; ItemStack contentStack = GetContent(world, byEntityItem.Itemstack); bool canFill = contentStack == null || (contentStack.Equals(world, whenFilledStack, GlobalConstants.IgnoredStackAttributes) && GetCurrentLitres(world, byEntityItem.Itemstack) < BucketCapacityLitres); if (!canFill) { return; } whenFilledStack.StackSize = (int)(props.ItemsPerLitre * BucketCapacityLitres); ItemStack fullBucketStack = new ItemStack(this); SetContent(fullBucketStack, whenFilledStack); if (byEntityItem.Itemstack.StackSize <= 1) { byEntityItem.Itemstack = fullBucketStack; } else { byEntityItem.Itemstack.StackSize--; world.SpawnItemEntity(fullBucketStack, byEntityItem.LocalPos.XYZ); } world.PlaySoundAt(props.FillSpillSound, pos.X, pos.Y, pos.Z, null); }
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); }
/// <summary> /// Tries to place in items/liquid and returns actually inserted quantity /// </summary> /// <param name="world"></param> /// <param name="containerStack"></param> /// <param name="desiredItems"></param> /// <returns></returns> public virtual int TryPutContent(IWorldAccessor world, ItemStack containerStack, ItemStack contentStack, int desiredItems) { if (contentStack == null) { return(0); } ItemStack stack = GetContent(world, containerStack); int availItems = contentStack.StackSize; ILiquidSink sink = containerStack.Collectible as ILiquidSink; if (stack == null) { WaterTightContainableProps props = GetInContainerProps(contentStack); if (props == null || !props.Containable) { return(0); } int placeableItems = (int)(sink.CapacityLitres * props.ItemsPerLitre); ItemStack placedstack = contentStack.Clone(); placedstack.StackSize = GameMath.Min(availItems, desiredItems, placeableItems); SetContent(containerStack, placedstack); return(Math.Min(desiredItems, placeableItems)); } else { if (!stack.Equals(world, contentStack, GlobalConstants.IgnoredStackAttributes)) { return(0); } WaterTightContainableProps props = GetContentProps(world, containerStack); float maxItems = sink.CapacityLitres * props.ItemsPerLitre; int placeableItems = (int)(maxItems - (float)stack.StackSize / props.ItemsPerLitre); stack.StackSize += Math.Min(placeableItems, desiredItems); return(Math.Min(placeableItems, desiredItems)); } }
public override void OnHeldInteractStart(ItemSlot itemslot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handHandling) { if (blockSel == null || byEntity.Controls.Sneak) { base.OnHeldInteractStart(itemslot, byEntity, blockSel, entitySel, firstEvent, ref handHandling); return; } IPlayer byPlayer = (byEntity as EntityPlayer)?.Player; ItemStack contentStack = GetContent(byEntity.World, itemslot.Itemstack); Block targetedBlock = byEntity.World.BlockAccessor.GetBlock(blockSel.Position); if (!byEntity.World.Claims.TryAccess(byPlayer, blockSel.Position, EnumBlockAccessFlags.BuildOrBreak)) { byEntity.World.BlockAccessor.MarkBlockDirty(blockSel.Position.AddCopy(blockSel.Face)); byPlayer?.InventoryManager.ActiveHotbarSlot?.MarkDirty(); return; } if (!TryFillFromBlock(itemslot, byEntity, blockSel.Position)) { BlockBucket targetBucket = targetedBlock as BlockBucket; if (targetBucket != null) { WaterTightContainableProps props = GetContentProps(byEntity.World, itemslot.Itemstack); if (targetBucket.TryPutContent(byEntity.World, blockSel.Position, contentStack, 1) > 0) { TryTakeContent(byEntity.World, itemslot.Itemstack, 1); byEntity.World.PlaySoundAt(props.FillSpillSound, blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z, byPlayer); } } else { if (byEntity.Controls.Sprint) { SpillContents(itemslot, byEntity, blockSel); } } } // Prevent placing on normal use handHandling = EnumHandHandling.PreventDefaultAction; }
public MeshData GenMesh(ICoreClientAPI capi, ItemStack contentStack, BlockPos forBlockPos = null) { Shape shape = capi.Assets.TryGet("shapes/block/wood/bucket/empty.json").ToObject <Shape>(); MeshData bucketmesh; capi.Tesselator.TesselateShape(this, shape, out bucketmesh); if (contentStack != null) { WaterTightContainableProps props = GetStackProps(contentStack); Block contentBlock = capi.World.GetBlock(props.BlockTextureSource); if (contentBlock == null) { return(bucketmesh); } BucketTextureSource contentSource = new BucketTextureSource(capi, contentStack, contentBlock); shape = capi.Assets.TryGet("shapes/block/wood/bucket/contents.json").ToObject <Shape>(); MeshData contentMesh; capi.Tesselator.TesselateShape("bucket", shape, out contentMesh, contentSource, new Vec3f(Shape.rotateX, Shape.rotateY, Shape.rotateZ)); contentMesh.Translate(0, GameMath.Min(7 / 16f, contentStack.StackSize / props.ItemsPerLitre * 0.7f / 16f), 0); if (contentBlock.TintIndex > 0) { int col = capi.ApplyColorTintOnRgba(contentBlock.TintIndex, ColorUtil.WhiteArgb, 196, 128, false); if (forBlockPos != null) { col = capi.ApplyColorTintOnRgba(contentBlock.TintIndex, ColorUtil.WhiteArgb, forBlockPos.X, forBlockPos.Y, forBlockPos.Z, false); } byte[] rgba = ColorUtil.ToBGRABytes(col); for (int i = 0; i < contentMesh.Rgba.Length; i++) { contentMesh.Rgba[i] = (byte)((contentMesh.Rgba[i] * rgba[i % 4]) / 255); } } bucketmesh.AddMeshData(contentMesh); } return(bucketmesh); }
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); }
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(); } }
/// <summary> /// Tries to put as much items/liquid as possible into a placed bucket and returns it how much items it actually moved /// </summary> /// <param name="world"></param> /// <param name="pos"></param> /// <param name="quantity"></param> public int TryAddContent(IWorldAccessor world, BlockPos pos, ItemStack contentStack, int quantity) { ItemStack stack = GetContent(world, pos); if (stack == null) { WaterTightContainableProps props = GetStackProps(contentStack); if (props == null || !props.Containable) { return(0); } float maxItems = BucketCapacityLitres * props.ItemsPerLitre; int placeableItems = (int)(maxItems - (float)contentStack.StackSize / props.ItemsPerLitre); ItemStack placedstack = contentStack.Clone(); placedstack.StackSize = Math.Min(quantity, placeableItems); SetContent(world, pos, placedstack); return(Math.Min(quantity, placeableItems)); } else { if (!stack.Equals(world, contentStack, GlobalConstants.IgnoredStackAttributes)) { return(0); } WaterTightContainableProps props = GetContentProps(world, pos); float maxItems = BucketCapacityLitres * props.ItemsPerLitre; int placeableItems = (int)(maxItems - (float)stack.StackSize); stack.StackSize += Math.Min(placeableItems, quantity); world.BlockAccessor.GetBlockEntity(pos).MarkDirty(true); return(Math.Min(placeableItems, quantity)); } }
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); } }
protected MeshData getContentMesh(ItemStack stack, BlockPos forBlockPos, string shapefilename) { ICoreClientAPI capi = api as ICoreClientAPI; WaterTightContainableProps props = GetStackProps(stack); ITexPositionSource contentSource = null; float fillHeight = 0; if (props != null) { contentSource = new ContainerTextureSource(capi, stack, props.Texture); fillHeight = GameMath.Min(10 / 16f, 0.2f * stack.StackSize / props.ItemsPerLitre / 16f); } else { JsonObject obj = stack?.ItemAttributes?["inContainerTexture"]; if (obj != null && obj.Exists) { contentSource = new ContainerTextureSource(capi, stack, obj.AsObject <CompositeTexture>()); fillHeight = GameMath.Min(10 / 16f, 0.7f * stack.StackSize / stack.Collectible.MaxStackSize); } else { if (stack?.Block != null && (stack.Block.DrawType == EnumDrawType.Cube || stack.Block.Shape.Base.Path.Contains("basic/cube"))) { contentSource = new BlockTopTextureSource(capi, stack.Block); fillHeight = GameMath.Min(10 / 16f, 0.7f * 1); } } } if (stack != null && contentSource != null) { Shape shape = capi.Assets.TryGet("shapes/block/wood/barrel/" + shapefilename).ToObject <Shape>(); MeshData contentMesh; capi.Tesselator.TesselateShape("barrel", shape, out contentMesh, contentSource, new Vec3f(Shape.rotateX, Shape.rotateY, Shape.rotateZ)); contentMesh.Translate(0, fillHeight, 0); if (props != null && props.TintIndex > 0) { int col = capi.ApplyColorTintOnRgba(props.TintIndex, ColorUtil.WhiteArgb, 196, 128, false); if (forBlockPos != null) { col = capi.ApplyColorTintOnRgba(props.TintIndex, ColorUtil.WhiteArgb, forBlockPos.X, forBlockPos.Y, forBlockPos.Z, false); } byte[] rgba = ColorUtil.ToBGRABytes(col); for (int i = 0; i < contentMesh.Rgba.Length; i++) { contentMesh.Rgba[i] = (byte)((contentMesh.Rgba[i] * rgba[i % 4]) / 255); } } return(contentMesh); } return(null); }
public override bool CanHold(ItemSlot itemstackFromSourceSlot) { WaterTightContainableProps props = BlockLiquidContainerBase.GetInContainerProps(itemstackFromSourceSlot.Itemstack); return(props != null); }
private bool SpillContents(IItemSlot bucketSlot, IEntityAgent byEntity, BlockSelection blockSel) { BlockPos pos = blockSel.Position; IPlayer byPlayer = (byEntity as EntityPlayer)?.Player; IBlockAccessor blockAcc = byEntity.World.BlockAccessor; BlockPos secondPos = blockSel.Position.AddCopy(blockSel.Face); WaterTightContainableProps props = GetContentProps(byEntity.World, bucketSlot.Itemstack); if (props == null || !props.AllowSpill || props.WhenSpilled == null) { return(false); } if (props.WhenSpilled.Action == WaterTightContainableProps.EnumSpilledAction.PlaceBlock) { Block waterBlock = byEntity.World.GetBlock(props.WhenSpilled.Stack.Code); if (props.WhenSpilled.StackByFillLevel != null) { float currentlitres = GetCurrentLitres(byEntity.World, bucketSlot.Itemstack); JsonItemStack fillLevelStack = null; props.WhenSpilled.StackByFillLevel.TryGetValue((int)currentlitres, out fillLevelStack); if (fillLevelStack != null) { waterBlock = byEntity.World.GetBlock(fillLevelStack.Code); } } if (blockAcc.GetBlock(pos).Replaceable >= 6000) { blockAcc.SetBlock(waterBlock.BlockId, pos); blockAcc.MarkBlockDirty(pos); } else { if (blockAcc.GetBlock(secondPos).Replaceable >= 6000) { blockAcc.SetBlock(waterBlock.BlockId, secondPos); blockAcc.MarkBlockDirty(secondPos); } else { return(false); } } } if (props.WhenSpilled.Action == WaterTightContainableProps.EnumSpilledAction.DropContents) { props.WhenSpilled.Stack.Resolve(byEntity.World, "bucketspill"); ItemStack stack = props.WhenSpilled.Stack.ResolvedItemstack.Clone(); stack.StackSize = (int)(props.ItemsPerLitre * GetContent(byEntity.World, bucketSlot.Itemstack).StackSize); byEntity.World.SpawnItemEntity(stack, blockSel.Position.ToVec3d().Add(blockSel.HitPosition)); } ItemStack emptyBucketStack = new ItemStack(this); if (bucketSlot.Itemstack.StackSize <= 1) { bucketSlot.Itemstack = emptyBucketStack; bucketSlot.MarkDirty(); } else { bucketSlot.TakeOut(1); if (!byPlayer.InventoryManager.TryGiveItemstack(emptyBucketStack, true)) { byEntity.World.SpawnItemEntity(emptyBucketStack, byEntity.LocalPos.XYZ); } } byEntity.World.PlaySoundAt(props.FillSpillSound, pos.X, pos.Y, pos.Z, byPlayer); return(true); }
public bool TryFillBucketFromBlock(IItemSlot itemslot, IEntityAgent byEntity, BlockPos pos) { IPlayer byPlayer = (byEntity as EntityPlayer)?.Player; IBlockAccessor blockAcc = byEntity.World.BlockAccessor; Block block = blockAcc.GetBlock(pos); if (block.Attributes?["waterTightContainerProps"].Exists == false) { return(false); } WaterTightContainableProps props = block.Attributes?["waterTightContainerProps"]?.AsObject <WaterTightContainableProps>(); if (props?.WhenFilled == null || !props.Containable) { return(false); } props.WhenFilled.Stack.Resolve(byEntity.World, "blockbucket"); ItemStack contentStack = GetContent(byEntity.World, itemslot.Itemstack); if (contentStack != null && contentStack.Equals(props.WhenFilled.Stack.ResolvedItemstack)) { SetContent(itemslot.Itemstack, contentStack); itemslot.MarkDirty(); return(true); } // Is full if (contentStack != null && contentStack.StackSize == (int)(props.ItemsPerLitre * BucketCapacityLitres)) { return(false); } contentStack = props.WhenFilled.Stack.ResolvedItemstack.Clone(); contentStack.StackSize = (int)(props.ItemsPerLitre * BucketCapacityLitres); ItemStack fullBucketStack = new ItemStack(this); SetContent(fullBucketStack, contentStack); if (itemslot.Itemstack.StackSize <= 1) { itemslot.Itemstack = fullBucketStack; } else { itemslot.TakeOut(1); if (!byPlayer.InventoryManager.TryGiveItemstack(fullBucketStack, true)) { byEntity.World.SpawnItemEntity(fullBucketStack, byEntity.LocalPos.XYZ); } } itemslot.MarkDirty(); byEntity.World.PlaySoundAt(props.FillSpillSound, pos.X, pos.Y, pos.Z, byPlayer); return(true); }