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 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); }
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); } }
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; } } }
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); }
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)); } }
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); } }
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); } }
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); }
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); }
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()); }
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(); } }
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); }
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(); }
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); } }
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); }
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); }
public override bool CanHold(ItemSlot itemstackFromSourceSlot) { WaterTightContainableProps props = BlockLiquidContainerBase.GetInContainerProps(itemstackFromSourceSlot.Itemstack); return(props != null); }
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); }