public bool ExchangePossible(Exchange exchange, ItemSlot slot, out ItemSlot exchangeSlot, out ItemSlot emptySlot) { exchangeSlot = null; emptySlot = null; ItemSlot _exchangeSlot = new DummySlot(); if (slot.Itemstack == null || exchange.Input == null || exchange.Output == null) { return(false); } foreach (var val in inventory) { if (val.Empty) { emptySlot = val; break; } } if (emptySlot != null && inventory.Any(a => { if (a.Itemstack?.StackSize >= exchange.Output?.StackSize && (a.Itemstack?.Collectible?.Code?.ToString() == exchange.Output?.Collectible?.Code?.ToString() && a.Itemstack?.StackSize >= exchange.Output?.StackSize)) { _exchangeSlot = a; return(true); } return(false); }) && exchange?.Input?.StackSize <= slot?.Itemstack?.StackSize && exchange?.Input?.Collectible?.Code == slot?.Itemstack?.Collectible?.Code) { exchangeSlot = _exchangeSlot; return(exchangeSlot != null); } return(false); }
public override void OnBlockInteractStop(float secondsUsed, IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel) { if (!PlacedBlockEating) { base.OnBlockInteractStop(secondsUsed, world, byPlayer, blockSel); } if (!byPlayer.Entity.Controls.Sneak) { return; } BlockEntityMeal bemeal = world.BlockAccessor.GetBlockEntity(blockSel.Position) as BlockEntityMeal; ItemStack stack = OnPickBlock(world, blockSel.Position); DummySlot dummySlot = new DummySlot(stack, bemeal.inventory); dummySlot.MarkedDirty += () => true; if (tryFinishEatMeal(secondsUsed, dummySlot, byPlayer.Entity, false)) { float servingsLeft = GetQuantityServings(world, stack); if (bemeal.QuantityServings <= 0) { Block block = world.GetBlock(new AssetLocation(Attributes["eatenBlock"].AsString())); world.BlockAccessor.SetBlock(block.BlockId, blockSel.Position); } else { bemeal.QuantityServings = servingsLeft; bemeal.MarkDirty(true); } } }
public bool OnContainedInteractStart(BlockEntityContainer be, ItemSlot slot, IPlayer byPlayer, BlockSelection blockSel) { var targetSlot = byPlayer.InventoryManager.ActiveHotbarSlot; if (targetSlot.Empty) { return(false); } if ((targetSlot.Itemstack.Collectible.Attributes?.IsTrue("mealContainer") == true || targetSlot.Itemstack.Block is IBlockMealContainer) && GetServings(api.World, slot.Itemstack) > 0) { if (targetSlot.StackSize > 1) { targetSlot = new DummySlot(targetSlot.TakeOut(1)); byPlayer.InventoryManager.ActiveHotbarSlot.MarkDirty(); ServeIntoStack(targetSlot, slot, api.World); if (!byPlayer.InventoryManager.TryGiveItemstack(targetSlot.Itemstack, true)) { api.World.SpawnItemEntity(targetSlot.Itemstack, byPlayer.Entity.ServerPos.XYZ); } } else { ServeIntoStack(targetSlot, slot, api.World); } slot.MarkDirty(); be.MarkDirty(true); return(true); } return(false); }
public static ItemSlot GetDummySlotForFirstPerishableStack(IWorldAccessor world, ItemStack[] stacks, Entity forEntity, InventoryBase slotInventory) { ItemStack stack = null; if (stacks != null) { for (int i = 0; i < stacks.Length; i++) { if (stacks[i] != null) { TransitionableProperties[] props = stacks[i].Collectible.GetTransitionableProperties(world, stacks[i], forEntity); if (props != null && props.Length > 0) { stack = stacks[i]; break; } } } } DummySlot slot = new DummySlot(stack, slotInventory); slot.MarkedDirty += () => true; return(slot); }
public override void GetHeldItemInfo(ItemSlot inSlot, StringBuilder dsc, IWorldAccessor world, bool withDebugInfo) { base.GetHeldItemInfo(inSlot, dsc, world, withDebugInfo); CookingRecipe recipe = GetMealRecipe(world, inSlot.Itemstack); float servings = inSlot.Itemstack.Attributes.GetFloat("quantityServings"); ItemStack[] stacks = GetContents(world, inSlot.Itemstack); DummySlot firstContentItemSlot = new DummySlot(stacks != null && stacks.Length > 0 ? stacks[0] : null, inSlot.Inventory); if (recipe != null) { if (servings == 1) { dsc.AppendLine(Lang.Get("{0} serving of {1}", Math.Round(servings, 1), recipe.GetOutputName(world, stacks))); } else { dsc.AppendLine(Lang.Get("{0} servings of {1}", Math.Round(servings, 1), recipe.GetOutputName(world, stacks))); } } BlockMeal mealblock = api.World.GetBlock(new AssetLocation("bowl-meal")) as BlockMeal; string nutriFacts = mealblock.GetContentNutritionFacts(api.World, inSlot, stacks, null); if (nutriFacts != null) { dsc.AppendLine(nutriFacts); } firstContentItemSlot.Itemstack?.Collectible.AppendPerishableInfoText(firstContentItemSlot, dsc, world); }
public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel) { if (!PlacedBlockEating) { return(base.OnBlockInteractStart(world, byPlayer, blockSel)); } ItemStack stack = OnPickBlock(world, blockSel.Position); if (!byPlayer.Entity.Controls.Sneak) { if (byPlayer.InventoryManager.TryGiveItemstack(stack, true)) { world.BlockAccessor.SetBlock(0, blockSel.Position); world.PlaySoundAt(Sounds.Place, byPlayer, byPlayer); return(true); } return(false); } BlockEntityMeal bemeal = world.BlockAccessor.GetBlockEntity(blockSel.Position) as BlockEntityMeal; DummySlot dummySlot = new DummySlot(stack, bemeal.inventory); dummySlot.MarkedDirty += () => true; return(tryPlacedBeginEatMeal(dummySlot, byPlayer)); }
public bool Exchange(IPlayer byPlayer) { if (Api.Side.IsServer()) { foreach (var val in Exchanges) { ItemSlot active = byPlayer.InventoryManager.ActiveHotbarSlot; if (ExchangePossible(val, active, out ItemSlot exchangeSlot, out ItemSlot emptySlot)) { if (active.TryPutInto(Api.World, emptySlot, val.Input.StackSize) == val.Input.StackSize) { DummySlot dummy = new DummySlot(); if (exchangeSlot.TryPutInto(Api.World, dummy, val.Output.StackSize) == val.Output.StackSize) { if (!byPlayer.InventoryManager.TryGiveItemstack(dummy.Itemstack)) { byPlayer.Entity.World.SpawnItemEntity(dummy.Itemstack, Pos.ToVec3d()); } Api.World.PlaySoundAt(AssetLocation.Create("sounds/effect/cashregister"), Pos.X, Pos.Y, Pos.Z); inventory.Sort(Api, EnumSortMode.ID); return(true); } } } } } else { return(true); } return(false); }
public override bool TryGiveItemStack(ItemStack itemstack) { if (itemstack == null || itemstack.StackSize == 0) { return(false); } ItemSlot dummySlot = new DummySlot(null); dummySlot.Itemstack = itemstack.Clone(); ItemStackMoveOperation op = new ItemStackMoveOperation(World, EnumMouseButton.Left, 0, EnumMergePriority.AutoMerge, itemstack.StackSize); WeightedSlot wslot = inv.GetBestSuitedSlot(dummySlot, new List <ItemSlot>()); if (wslot.weight > 0) { dummySlot.TryPutInto(wslot.slot, ref op); itemstack.StackSize -= op.MovedQuantity; WatchedAttributes.MarkAllDirty(); return(op.MovedQuantity > 0); } return(false); }
public override string GetPlacedBlockInfo(IWorldAccessor world, BlockPos pos, IPlayer forPlayer) { BlockEntityCrock becrock = world.BlockAccessor.GetBlockEntity(pos) as BlockEntityCrock; if (becrock == null) { return(null); } BlockMeal mealblock = world.GetBlock(new AssetLocation("bowl-meal")) as BlockMeal; CookingRecipe recipe = world.CookingRecipes.FirstOrDefault((rec) => becrock.RecipeCode == rec.Code); ItemStack[] stacks = becrock.inventory.Where(slot => !slot.Empty).Select(slot => slot.Itemstack).ToArray(); if (stacks == null || stacks.Length == 0) { return("Empty"); } StringBuilder dsc = new StringBuilder(); if (recipe != null) { DummySlot firstContentItemSlot = new DummySlot(stacks != null && stacks.Length > 0 ? stacks[0] : null, becrock.inventory); if (recipe != null) { dsc.AppendLine(recipe.GetOutputName(world, stacks).UcFirst()); } string facts = mealblock.GetContentNutritionFacts(world, new DummySlot(OnPickBlock(world, pos)), null); if (facts != null) { dsc.Append(facts); } firstContentItemSlot.Itemstack?.Collectible.AppendPerishableInfoText(firstContentItemSlot, dsc, world); } else { dsc.AppendLine("Contents:"); foreach (var stack in stacks) { if (stack == null) { continue; } dsc.AppendLine(stack.StackSize + "x " + stack.GetName()); } becrock.inventory[0].Itemstack.Collectible.AppendPerishableInfoText(becrock.inventory[0], dsc, api.World); } return(dsc.ToString()); }
public GuiHandbookItemStackPage(ICoreClientAPI capi, ItemStack stack) { this.Stack = stack; unspoilableInventory = new CreativeInventoryTab(1, "not-used", null); dummySlot = new DummySlot(stack, unspoilableInventory); TextCache = stack.GetName() + " " + stack.GetDescription(capi.World, dummySlot, false); }
public ItemstackTextComponent(ICoreClientAPI capi, ItemStack itemstack, double size, double sidePadding = 0, EnumFloat floatType = EnumFloat.Left, Common.Action <ItemStack> onStackClicked = null) : base(capi) { slot = new DummySlot(itemstack); this.onStackClicked = onStackClicked; this.Float = floatType; this.size = size; this.BoundsPerLine = new LineRectangled[] { new LineRectangled(0, 0, size + sidePadding, size) }; //PaddingRight = 0; }
public static FoodNutritionProperties[] GetContentNutritionProperties(IWorldAccessor world, ItemSlot inSlot, ItemStack[] contentStacks, EntityAgent forEntity, bool mulWithStacksize = false, float nutritionMul = 1, float healthMul = 1) { List <FoodNutritionProperties> foodProps = new List <FoodNutritionProperties>(); if (contentStacks == null) { return(foodProps.ToArray()); } for (int i = 0; i < contentStacks.Length; i++) { if (contentStacks[i] == null) { continue; } CollectibleObject obj = contentStacks[i].Collectible; FoodNutritionProperties stackProps; if (obj.CombustibleProps != null && obj.CombustibleProps.SmeltedStack != null) { stackProps = obj.CombustibleProps.SmeltedStack.ResolvedItemstack.Collectible.GetNutritionProperties(world, obj.CombustibleProps.SmeltedStack.ResolvedItemstack, forEntity); } else { stackProps = obj.GetNutritionProperties(world, contentStacks[i], forEntity); } if (obj.Attributes?["nutritionPropsWhenInMeal"].Exists == true) { stackProps = obj.Attributes?["nutritionPropsWhenInMeal"].AsObject <FoodNutritionProperties>(); } if (stackProps == null) { continue; } float mul = mulWithStacksize ? contentStacks[i].StackSize : 1; FoodNutritionProperties props = stackProps.Clone(); DummySlot slot = new DummySlot(contentStacks[i], inSlot.Inventory); TransitionState state = contentStacks[i].Collectible.UpdateAndGetTransitionState(world, slot, EnumTransitionType.Perish); float spoilState = state != null ? state.TransitionLevel : 0; float satLossMul = GlobalConstants.FoodSpoilageSatLossMul(spoilState, slot.Itemstack, forEntity); float healthLoss = GlobalConstants.FoodSpoilageHealthLossMul(spoilState, slot.Itemstack, forEntity); props.Satiety *= satLossMul * nutritionMul * mul; props.Health *= healthLoss * healthMul * mul; foodProps.Add(props); } return(foodProps.ToArray()); }
public GuiHandbookItemStackPage(ICoreClientAPI capi, ItemStack stack) { this.Stack = stack; unspoilableInventory = new CreativeInventoryTab(1, "not-used", null); dummySlot = new DummySlot(stack, unspoilableInventory); TextCacheTitle = stack.GetName(); TextCacheAll = stack.GetName() + " " + stack.GetDescription(capi.World, dummySlot, false); isDuplicate = stack.Collectible.Attributes?["handbook"]?["isDuplicate"].AsBool(false) == true; }
public GuiElementHandbookListWithTooltips( ICoreClientAPI capi, ElementBounds bounds, Vintagestory.API.Common.Action <int> onLeftClick, List <GuiHandbookPage> elements = null ) : base(capi, bounds, onLeftClick, elements) { tooltipProvider = new ItemstackComponentBase(capi); dummySlot = new DummySlot(); }
public override TransitionState[] UpdateAndGetTransitionStates(IWorldAccessor world, ItemSlot inslot) { ItemStack[] stacks = GetContents(world, inslot.Itemstack); for (int i = 0; stacks != null && i < stacks.Length; i++) { DummySlot slot = null; if (inslot.Inventory == null) { DummyInventory dummyInv = new DummyInventory(api); //slot = new DummySlot(stacks != null && stacks.Length > 0 ? stacks[0] : null, dummyInv); - this seems wrong...? slot = new DummySlot(stacks[i], dummyInv); dummyInv.OnAcquireTransitionSpeed = (transType, stack, mul) => { return(mul * GetContainingTransitionModifierContained(world, slot, transType)); }; stacks[i]?.Collectible.UpdateAndGetTransitionStates(world, slot); } else { slot = new DummySlot(stacks[i], inslot.Inventory); var pref = inslot.Inventory.OnAcquireTransitionSpeed; inslot.Inventory.OnAcquireTransitionSpeed = (EnumTransitionType transType, ItemStack stack, float mulByConfig) => { float mul = mulByConfig; if (pref != null) { mul = pref(transType, stack, mulByConfig); } return(GetContainingTransitionModifierContained(world, inslot, transType) * mul); //return mulByConfig * GetContainingTransitionModifierContained(world, slot, transType); - doesn't work for sealed crocks }; slot.MarkedDirty += () => { inslot.Inventory.DidModifyItemSlot(inslot); return(true); }; stacks[i]?.Collectible.UpdateAndGetTransitionStates(world, slot); if (slot.Itemstack == null) { stacks[i] = null; } inslot.Inventory.OnAcquireTransitionSpeed = pref; } } SetContents(inslot.Itemstack, stacks); return(base.UpdateAndGetTransitionStates(world, inslot)); }
public ItemstackTextComponent(ICoreClientAPI capi, ItemStack itemstack, double size, double rightSidePadding = 0, EnumFloat floatType = EnumFloat.Left, Action <ItemStack> onStackClicked = null) : base(capi) { size = GuiElement.scaled(size); slot = new DummySlot(itemstack); this.onStackClicked = onStackClicked; this.Float = floatType; this.size = size; this.BoundsPerLine = new LineRectangled[] { new LineRectangled(0, 0, size, size) }; PaddingRight = GuiElement.scaled(rightSidePadding); }
public string GetContentNutritionFacts(IWorldAccessor world, ItemSlot inSlotorFirstSlot, ItemStack[] contentStacks, EntityAgent forEntity, bool mulWithStacksize = false) { FoodNutritionProperties[] props = GetContentNutritionProperties(world, inSlotorFirstSlot, contentStacks, forEntity); Dictionary <EnumFoodCategory, float> totalSaturation = new Dictionary <EnumFoodCategory, float>(); float totalHealth = 0; for (int i = 0; i < props.Length; i++) { FoodNutritionProperties prop = props[i]; if (prop == null) { continue; } float sat = 0; totalSaturation.TryGetValue(prop.FoodCategory, out sat); DummySlot slot = new DummySlot(contentStacks[i], inSlotorFirstSlot.Inventory); TransitionState state = contentStacks[i].Collectible.UpdateAndGetTransitionState(api.World, slot, EnumTransitionType.Perish); float spoilState = state != null ? state.TransitionLevel : 0; float mul = mulWithStacksize ? contentStacks[i].StackSize : 1; float satLossMul = GlobalConstants.FoodSpoilageSatLossMul(spoilState, slot.Itemstack, forEntity); float healthLossMul = GlobalConstants.FoodSpoilageHealthLossMul(spoilState, slot.Itemstack, forEntity); totalHealth += prop.Health * healthLossMul * mul; totalSaturation[prop.FoodCategory] = (sat + prop.Satiety * satLossMul) * mul; } StringBuilder sb = new StringBuilder(); sb.AppendLine(Lang.Get("Nutrition Facts")); foreach (var val in totalSaturation) { sb.AppendLine("- " + Lang.Get("" + val.Key) + ": " + Math.Round(val.Value) + " sat."); } if (totalHealth != 0) { sb.AppendLine("- " + Lang.Get("Health: {0}{1} hp", totalHealth > 0 ? "+" : "", totalHealth)); } return(sb.ToString()); }
public static void Sort(this IInventory activeInv, ICoreAPI api, EnumSortMode mode) { if (api == null || activeInv == null) { return; } string name = activeInv.ClassName; if (name == "basket" || name == "chest" || name == "hotbar" || name == "backpack") { List <ItemStack> objects = activeInv.SortArr(mode); for (int j = 0; j < activeInv.Count; j++) { if (activeInv[j] is ItemSlotOffhand) { continue; } if (activeInv[j].Itemstack != null) { if (activeInv[j].Itemstack.Attributes["backpack"] != null) { continue; } activeInv[j].TakeOutWhole(); } for (int o = objects.Count; o-- > 0;) { ItemStackMoveOperation op = new ItemStackMoveOperation(api.World, EnumMouseButton.Left, 0, EnumMergePriority.AutoMerge, 1); DummySlot slot = new DummySlot(objects[o]); slot.TryPutInto(activeInv[j], ref op); if (op.MovedQuantity > 0) { objects.RemoveAt(o); } else { break; } } } } }
public override void OnInteract(EntityAgent byEntity, ItemSlot itemslot, Vec3d hitPosition, EnumInteractMode mode, ref EnumHandling handled) { if (itemslot.Itemstack == null) { return; } if (itemslot.Itemstack.Block is BlockBucket) { handled = EnumHandling.PreventDefault; ItemStack milkstack = new ItemStack(milk, RemainingLiters); BlockBucket bucket = itemslot.Itemstack.Block as BlockBucket; ItemStack contents = bucket.GetContent(byEntity.World, itemslot.Itemstack); if ((contents == null || contents.Item == milk) && RemainingLiters > 0) { if (contents?.StackSize != null && contents.StackSize / milkProps.ItemsPerLitre >= bucket.CapacityLitres) { return; } DummySlot slot = new DummySlot(itemslot.TakeOut(1)); int taken = bucket.TryPutContent(byEntity.World, slot.Itemstack, milkstack, 1); if (taken > 0) { RemainingLiters -= taken; if (byEntity.World.Side == EnumAppSide.Client) { byEntity.World.SpawnCubeParticles(entity.Pos.XYZ + new Vec3d(0, 0.5, 0), milkstack, 0.3f, 4, 0.5f, (byEntity as EntityPlayer)?.Player); } if (id == 0 && RemainingLiters < defaultvalue) { if (NextTimeMilkable == 0) { NextTimeMilkable = GetNextTimeMilkable(); } id = entity.World.RegisterGameTickListener(MilkListener, 1000); } byEntity.TryGiveItemStack(slot.Itemstack); itemslot.MarkDirty(); } } } base.OnInteract(byEntity, itemslot, hitPosition, mode, ref handled); }
public AuctionCellEntry(ICoreClientAPI capi, ElementBounds bounds, Auction auction, Action <int> onClick) : base(capi, bounds) { iconSize = (float)scaled(unscaledIconSize); dummySlot = new DummySlot(auction.ItemStack); this.onClick = onClick; this.auction = auction; CairoFont font = CairoFont.WhiteDetailText(); double offY = (unScaledCellHeight - font.UnscaledFontsize) / 2; scissorBounds = ElementBounds.FixedSize(unscaledIconSize, unscaledIconSize).WithParent(Bounds); var stackNameTextBounds = ElementBounds.Fixed(0, offY, 270, 25).WithParent(Bounds).FixedRightOf(scissorBounds, 10); var priceTextBounds = ElementBounds.Fixed(0, offY, 75, 25).WithParent(Bounds).FixedRightOf(stackNameTextBounds, 10); var expireTextBounds = ElementBounds.Fixed(0, 0, 160, 25).WithParent(Bounds).FixedRightOf(priceTextBounds, 10); var sellerTextBounds = ElementBounds.Fixed(0, offY, 110, 25).WithParent(Bounds).FixedRightOf(expireTextBounds, 10); stackNameTextElem = new GuiElementRichtext(capi, VtmlUtil.Richtextify(capi, dummySlot.Itemstack.GetName(), font), stackNameTextBounds); double fl = font.UnscaledFontsize; ItemStack gearStack = capi.ModLoader.GetModSystem <ModSystemAuction>().SingleCurrencyStack; var comps = new RichTextComponentBase[] { new RichTextComponent(capi, "" + auction.Price, font) { PaddingRight = 10, VerticalAlign = EnumVerticalAlign.Top }, new ItemstackTextComponent(capi, gearStack, fl * 2.5f, 0, EnumFloat.Inline) { VerticalAlign = EnumVerticalAlign.Top, offX = -scaled(fl * 0.5f), offY = -scaled(fl * 0.75f) } }; priceTextElem = new GuiElementRichtext(capi, comps, priceTextBounds); expireTextElem = new GuiElementRichtext(capi, VtmlUtil.Richtextify(capi, prevExpireText = auction.GetExpireText(capi), font.Clone().WithFontSize(14)), expireTextBounds); expireTextElem.BeforeCalcBounds(); expireTextBounds.fixedY = 5 + (25 - expireTextElem.TotalHeight / RuntimeEnv.GUIScale) / 2; sellerTextElem = new GuiElementRichtext(capi, VtmlUtil.Richtextify(capi, auction.SellerName, font.Clone().WithOrientation(EnumTextOrientation.Right)), sellerTextBounds); hoverTexture = new LoadedTexture(capi); }
public GuiDialogBlockEntityRecipeSelector(string DialogTitle, ItemStack[] recipeOutputs, Action <int> onSelectedRecipe, Action onCancelSelect, BlockPos blockEntityPos, ICoreClientAPI capi) : base(DialogTitle, capi) { this.blockEntityPos = blockEntityPos; this.onSelectedRecipe = onSelectedRecipe; this.onCancelSelect = onCancelSelect; skillItems = new List <SkillItem>(); double size = GuiElementPassiveItemSlot.unscaledSlotSize + GuiElementItemSlotGrid.unscaledSlotPadding; for (int i = 0; i < recipeOutputs.Length; i++) { ItemStack stack = recipeOutputs[i]; ItemSlot dummySlot = new DummySlot(stack); string key = GetCraftDescKey(stack); string desc = Lang.GetMatching(key); if (desc == key) { desc = ""; } skillItems.Add(new SkillItem() { Code = stack.Collectible.Code.Clone(), Name = stack.GetName(), Description = desc, RenderHandler = (AssetLocation code, float dt, double posX, double posY) => { // No idea why the weird offset and size multiplier double scsize = GuiElement.scaled(size - 5); capi.Render.RenderItemstackToGui(dummySlot, posX + scsize / 2, posY + scsize / 2, 100, (float)GuiElement.scaled(GuiElementPassiveItemSlot.unscaledItemSize), ColorUtil.WhiteArgb); } }); } SetupDialog(); }
public override void GetHeldItemInfo(ItemSlot inSlot, StringBuilder dsc, IWorldAccessor world, bool withDebugInfo) { base.GetHeldItemInfo(inSlot, dsc, world, withDebugInfo); CookingRecipe recipe = GetCookingRecipe(world, inSlot.Itemstack); ItemStack[] stacks = GetContents(world, inSlot.Itemstack); DummySlot firstContentItemSlot = new DummySlot(stacks != null && stacks.Length > 0 ? stacks[0] : null); float servings = GetQuantityServings(world, inSlot.Itemstack); if (recipe != null) { if (Math.Round(servings, 1) < 0.05) { dsc.AppendLine(Lang.Get("<5% serving of {1}", recipe.GetOutputName(world, stacks).UcFirst())); } else { dsc.AppendLine(Lang.Get("{0} serving of {1}", Math.Round(servings, 1), recipe.GetOutputName(world, stacks).UcFirst())); } } else { if (stacks != null && stacks.Length > 0) { dsc.AppendLine(stacks[0].StackSize + "x " + stacks[0].GetName()); } } string facts = GetContentNutritionFacts(world, inSlot, null, true); if (facts != null) { dsc.Append(facts); } firstContentItemSlot.Itemstack?.Collectible.AppendPerishableInfoText(firstContentItemSlot, dsc, world); }
public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel) { ItemStack stack = OnPickBlock(world, blockSel.Position); if (!byPlayer.Entity.Controls.Sneak) { if (byPlayer.InventoryManager.TryGiveItemstack(stack, true)) { world.BlockAccessor.SetBlock(0, blockSel.Position); world.PlaySoundAt(this.Sounds.Place, byPlayer, byPlayer); return(true); } return(false); } BlockEntityMeal bemeal = world.BlockAccessor.GetBlockEntity(blockSel.Position) as BlockEntityMeal; DummySlot dummySlot = new DummySlot(stack, bemeal.inventory); dummySlot.MarkedDirty += () => true; if (GetContentNutritionProperties(world, dummySlot, byPlayer.Entity) != null) { world.RegisterCallback((dt) => { if (byPlayer.Entity.Controls.HandUse == EnumHandInteract.BlockInteract) { byPlayer.Entity.PlayEntitySound("eat", byPlayer); } }, 500); byPlayer.Entity.StartAnimation("eat"); return(true); } return(false); }
public override void OnBlockInteractStop(float secondsUsed, IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel) { if (!byPlayer.Entity.Controls.Sneak) { return; } ItemStack stack = OnPickBlock(world, blockSel.Position); if (world.Side == EnumAppSide.Server && secondsUsed >= 1.45f) { BlockEntityMeal bemeal = world.BlockAccessor.GetBlockEntity(blockSel.Position) as BlockEntityMeal; DummySlot dummySlot = new DummySlot(stack, bemeal.inventory); dummySlot.MarkedDirty += () => true; ItemStack[] contents = GetNonEmptyContents(world, stack); if (contents.Length > 0) { float servingsLeft = Consume(world, byPlayer, dummySlot, contents, GetQuantityServings(world, stack), GetRecipeCode(world, stack) == null); bemeal.QuantityServings = servingsLeft; } else { bemeal.QuantityServings = 0; } if (bemeal.QuantityServings <= 0) { Block block = world.GetBlock(new AssetLocation(Attributes["eatenBlock"].AsString())); world.BlockAccessor.SetBlock(block.BlockId, blockSel.Position); } else { bemeal.MarkDirty(true); } } }
public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel) { int stage = Stage; ItemStack stack = byPlayer.InventoryManager.ActiveHotbarSlot?.Itemstack; if (stage == 5) { BlockEntityFirepit bef = world.BlockAccessor.GetBlockEntity(blockSel.Position) as BlockEntityFirepit; if (bef != null && stack != null && byPlayer.Entity.Controls.Sneak) { if (stack.Collectible.CombustibleProps != null && stack.Collectible.CombustibleProps.MeltingPoint > 0) { ItemStackMoveOperation op = new ItemStackMoveOperation(world, EnumMouseButton.Button1, 0, EnumMergePriority.DirectMerge, 1); byPlayer.InventoryManager.ActiveHotbarSlot.TryPutInto(bef.inputSlot, ref op); if (op.MovedQuantity > 0) { return(true); } } if (stack.Collectible.CombustibleProps != null && stack.Collectible.CombustibleProps.BurnTemperature > 0) { ItemStackMoveOperation op = new ItemStackMoveOperation(world, EnumMouseButton.Button1, 0, EnumMergePriority.DirectMerge, 1); byPlayer.InventoryManager.ActiveHotbarSlot.TryPutInto(bef.fuelSlot, ref op); if (op.MovedQuantity > 0) { return(true); } } } if (stack?.Collectible is BlockBowl && (stack.Collectible as BlockBowl)?.BowlContentItemCode() == null && stack.Collectible.Attributes?["mealContainer"].AsBool() == true) { ItemSlot potSlot = null; if (bef?.inputStack?.Collectible is CookedContainerFix) { potSlot = bef.inputSlot; } if (bef?.outputStack?.Collectible is CookedContainerFix) { potSlot = bef.outputSlot; } if (potSlot != null) { CookedContainerFix blockPot = potSlot.Itemstack.Collectible as CookedContainerFix; ItemSlot targetSlot = byPlayer.InventoryManager.ActiveHotbarSlot; if (byPlayer.InventoryManager.ActiveHotbarSlot.StackSize > 1) { targetSlot = new DummySlot(targetSlot.TakeOut(1)); byPlayer.InventoryManager.ActiveHotbarSlot.MarkDirty(); blockPot.ServeIntoBowlStack(targetSlot, potSlot, world); if (!byPlayer.InventoryManager.TryGiveItemstack(targetSlot.Itemstack, true)) { world.SpawnItemEntity(targetSlot.Itemstack, byPlayer.Entity.ServerPos.XYZ); } } else { blockPot.ServeIntoBowlStack(targetSlot, potSlot, world); } } return(true); } return(base.OnBlockInteractStart(world, byPlayer, blockSel)); } if (stack != null && TryConstruct(world, blockSel.Position, stack.Collectible, byPlayer)) { if (byPlayer != null && byPlayer.WorldData.CurrentGameMode != EnumGameMode.Creative) { byPlayer.InventoryManager.ActiveHotbarSlot.TakeOut(1); } return(true); } return(false); }
public override void GetHeldItemInfo(ItemSlot inSlot, StringBuilder dsc, IWorldAccessor world, bool withDebugInfo) { base.GetHeldItemInfo(inSlot, dsc, world, withDebugInfo); BlockMeal mealblock = world.GetBlock(new AssetLocation("bowl-meal")) as BlockMeal; CookingRecipe recipe = GetCookingRecipe(world, inSlot.Itemstack); ItemStack[] stacks = GetContents(world, inSlot.Itemstack); if (stacks == null || stacks.Length == 0) { dsc.AppendLine("Empty"); return; } DummySlot firstContentItemSlot = new DummySlot(stacks != null && stacks.Length > 0 ? stacks[0] : null); if (recipe != null) { double servings = inSlot.Itemstack.Attributes.GetDecimal("quantityServings"); if (recipe != null) { if (servings == 1) { dsc.AppendLine(Lang.Get("{0} serving of {1}", servings, recipe.GetOutputName(world, stacks))); } else { dsc.AppendLine(Lang.Get("{0} servings of {1}", servings, recipe.GetOutputName(world, stacks))); } } string facts = mealblock.GetContentNutritionFacts(world, inSlot, null); if (facts != null) { dsc.Append(facts); } } else { dsc.AppendLine("Contents:"); foreach (var stack in stacks) { if (stack == null) { continue; } dsc.AppendLine(stack.StackSize + "x " + stack.GetName()); } } firstContentItemSlot.Itemstack?.Collectible.AppendPerishableInfoText(firstContentItemSlot, dsc, world); if (inSlot.Itemstack.Attributes.GetBool("sealed")) { dsc.AppendLine(Lang.Get("Sealed.")); } }
protected virtual void IncrementallyBake(float dt, int slotIndex) { ItemSlot slot = Inventory[slotIndex]; OvenItemData bakeData = bakingData[slotIndex]; float targetTemp = bakeData.BrowningPoint; if (targetTemp == 0) { targetTemp = 160f; //prevents any possible divide by zero } float diff = bakeData.temp / targetTemp; float timeFactor = bakeData.TimeToBake; if (timeFactor == 0) { timeFactor = 1; //prevents any possible divide by zero } float delta = GameMath.Clamp((int)diff, 1, 30) * dt / timeFactor; float currentLevel = bakeData.BakedLevel; if (bakeData.temp > targetTemp) { currentLevel = bakeData.BakedLevel + delta; bakeData.BakedLevel = currentLevel; } var bakeProps = BakingProperties.ReadFrom(slot.Itemstack); float levelFrom = bakeProps?.LevelFrom ?? 0f; float levelTo = bakeProps?.LevelTo ?? 1f; float startHeightMul = bakeProps?.StartScaleY ?? 1f; float endHeightMul = bakeProps?.EndScaleY ?? 1f; float progress = GameMath.Clamp((currentLevel - levelFrom) / (levelTo - levelFrom), 0, 1); float heightMul = GameMath.Mix(startHeightMul, endHeightMul, progress); float nowHeightMulStaged = (int)(heightMul * BakingStageThreshold) / (float)BakingStageThreshold; bool reDraw = nowHeightMulStaged != bakeData.CurHeightMul; bakeData.CurHeightMul = nowHeightMulStaged; // see if increasing the partBaked by delta, has moved this stack up to the next "bakedStage", i.e. a different item if (currentLevel > levelTo) { float nowTemp = bakeData.temp; string resultCode = bakeProps?.ResultCode; if (resultCode != null) { ItemStack resultStack = null; if (slot.Itemstack.Class == EnumItemClass.Block) { Block block = Api.World.GetBlock(new AssetLocation(resultCode)); if (block != null) { resultStack = new ItemStack(block); } } else { Item item = Api.World.GetItem(new AssetLocation(resultCode)); if (item != null) { resultStack = new ItemStack(item); } } if (resultStack != null) { var collObjCb = ovenInv[slotIndex].Itemstack.Collectible as IBakeableCallback; if (collObjCb != null) { collObjCb.OnBaked(ovenInv[slotIndex].Itemstack, resultStack); } ovenInv[slotIndex].Itemstack = resultStack; bakingData[slotIndex] = new OvenItemData(resultStack); bakingData[slotIndex].temp = nowTemp; reDraw = true; } } else { // Allow the oven also to 'smelt' low-temperature bakeable items which do not have specific baking properties ItemSlot result = new DummySlot(null); if (slot.Itemstack.Collectible.CanSmelt(Api.World, ovenInv, slot.Itemstack, null)) { slot.Itemstack.Collectible.DoSmelt(Api.World, ovenInv, ovenInv[slotIndex], result); if (!result.Empty) { ovenInv[slotIndex].Itemstack = result.Itemstack; bakingData[slotIndex] = new OvenItemData(result.Itemstack); bakingData[slotIndex].temp = nowTemp; reDraw = true; } } } } if (reDraw) { updateMesh(slotIndex); MarkDirty(true); } }
/// <summary> Draw all the elements that go in the dialog. </summary> private void SetupDialog() { // Make the dialog centered and resize automatically ElementBounds dialogBounds = ElementStdBounds .AutosizedMainDialog .WithAlignment(EnumDialogArea.CenterMiddle); // Background boundaries. Make it fit the metal slots. ElementBounds bgBounds = ElementBounds .Fill .WithFixedPadding(GuiStyle.ElementToDialogPadding); bgBounds.BothSizing = ElementSizing.FitToChildren; // Create the boundaries for each metal slot, then assign them as children of the background. ElementBounds[] metalBounds = new ElementBounds[MistModSystem.METALS.Length]; for (int i = 0; i < MistModSystem.METALS.Length; i++) { metalBounds[i] = BoundsForIndex(i / 2, i % 2 == 1); } bgBounds.WithChildren(metalBounds); // Create the boundaries for the decoration image. ElementBounds decoBounds = ElementBounds.Fixed(0, 40, 420, 405); // Create the boundaries for the text indicating which metal is selected. ElementBounds metalText = ElementBounds.Fixed( OriginX - (200 / 2) + 18, OriginY - (25 / 2), 200, 25); ElementBounds metalAmount = ElementBounds.Fixed( OriginX - (200 / 2) + 18, OriginY - (25 / 2) + 20, 200, 25); // Lastly, create the dialog SingleComposer = capi.Gui.CreateCompo("metalSelector", dialogBounds) .AddShadedDialogBG(bgBounds) // Draw background .AddDialogTitleBar("Select allomantic metal", OnTitleBarCloseClicked) // Draw title. .AddImageBG(decoBounds, "gui/backgrounds/metalselector.png") // Draw decoration. .AddDynamicText( "Metal", CairoFont.WhiteSmallText(), EnumTextOrientation.Center, metalText, "metalText") // Draw metal name. .AddDynamicText( "Amount", CairoFont.WhiteSmallText(), EnumTextOrientation.Center, metalAmount, "metalAmount"); // Draw metal amount. // Iterate to create the slot for this metal. for (int i = 0; i < MistModSystem.METALS.Length; i++) { // Create a dummy slot of the item that will be displayed. AssetLocation itemLocation = AssetLocation.Create( DisplayItemCode + MistModSystem.METALS[i]); Item item = capi.World.GetItem(itemLocation); ItemStack stack = new ItemStack(item, 1); ItemSlot dummySlot = new DummySlot(stack); // Create a single-element dictionary to store the skill item. Dictionary <int, SkillItem> skillItems = new Dictionary <int, SkillItem>(); skillItems.Add(0, new SkillItem() { Code = itemLocation, Name = MistModSystem.METALS[i], Description = "Select " + MistModSystem.METALS[i], RenderHandler = (AssetLocation code, float dt, double posX, double posY) => { // No idea why the weird offset and size multiplier //double scsize = GuiElement.scaled(SlotSize - 5); //capi.Render.RenderItemstackToGui( // dummySlot, // posX + scsize/2, // posY + scsize / 2, // 100, // (float)GuiElement.scaled(GuiElementPassiveItemSlot.unscaledItemSize), // ColorUtil.WhiteArgb); } }); // Add the skill item to the UI. var j = i; SingleComposer = SingleComposer.AddSkillItemGrid( skillItems, 1, 1, delegate(int a) { SelectMetal(j); }, metalBounds[i], "skill-" + MistModSystem.METALS[i]); // Add a text to easily tell which metal is being selected. SingleComposer = SingleComposer.AddHoverText( MistModSystem.METALS[i], CairoFont.WhiteSmallishText(), 150, metalBounds[i]); } // Compose the dialog after all changes have been made. SingleComposer = SingleComposer.Compose(); }