public override void RenderTo(ICoreClientAPI capi, double x, double y) { float size = (float)GuiElement.scaled(25); float pad = (float)GuiElement.scaled(10); if (Texture == null) { Recompose(capi); } scissorBounds.fixedX = (pad + x - size / 2) / RuntimeEnv.GUIScale; scissorBounds.fixedY = (y - size / 2) / RuntimeEnv.GUIScale; scissorBounds.CalcWorldBounds(); if (scissorBounds.InnerWidth <= 0 || scissorBounds.InnerHeight <= 0) { return; } capi.Render.PushScissor(scissorBounds, true); capi.Render.RenderItemstackToGui(dummySlot, x + pad + size / 2, y + size / 2, 100, size, ColorUtil.WhiteArgb, true, false, false); capi.Render.PopScissor(); capi.Render.Render2DTexturePremultipliedAlpha( Texture.TextureId, (x + size + GuiElement.scaled(25)), y + size / 4 - GuiElement.scaled(3), Texture.Width, Texture.Height, 50 ); }
public override void OnMouseMove(MouseEvent args) { base.OnMouseMove(args); if (SingleComposer != null && SingleComposer.Bounds.PointInside(args.X, args.Y)) { double x = args.X - SingleComposer.Bounds.absX; double y = args.Y - SingleComposer.Bounds.absY - GuiElement.scaled(30); // no idea why the 30 :/ //Console.WriteLine("{0}/{1}", args.X, args.Y); StringBuilder hoverText = new StringBuilder(); mapElem.TranslateViewPosToWorldPos(new Vec2f((float)x, (float)y), ref hoveredWorldPos); hoveredWorldPos.Y++; //BlockPos pos = capi.World.Player.Entity.Pos.AsBlockPos; double yAbs = hoveredWorldPos.Y; hoveredWorldPos.Sub(capi.World.DefaultSpawnPosition.AsBlockPos); hoveredWorldPos.Y = yAbs; hoverText.AppendLine(string.Format("{0}, {1}, {2}", (int)hoveredWorldPos.X, (int)hoveredWorldPos.Y, (int)hoveredWorldPos.Z)); foreach (MapComponent cmp in mapComponents) { cmp.OnMouseMove(args, mapElem, hoverText); } string text = hoverText.ToString().TrimEnd(); hoverTextElem.SetNewText(text); } }
private void OnBgDraw(Context ctx, ImageSurface surface, ElementBounds currentBounds) { double top = 30; // Arrow Right ctx.Save(); Matrix m = ctx.Matrix; m.Translate(GuiElement.scaled(63), GuiElement.scaled(top + 2)); m.Scale(GuiElement.scaled(0.6), GuiElement.scaled(0.6)); ctx.Matrix = m; capi.Gui.Icons.DrawArrowRight(ctx, 2); double dx = inputGrindTime / maxGrindTime; ctx.Rectangle(GuiElement.scaled(5), 0, GuiElement.scaled(125 * dx), GuiElement.scaled(100)); ctx.Clip(); LinearGradient gradient = new LinearGradient(0, 0, GuiElement.scaled(200), 0); gradient.AddColorStop(0, new Color(0, 0.4, 0, 1)); gradient.AddColorStop(1, new Color(0.2, 0.6, 0.2, 1)); ctx.SetSource(gradient); capi.Gui.Icons.DrawArrowRight(ctx, 0, false, false); gradient.Dispose(); ctx.Restore(); }
public override void RenderInteractiveElements(float deltaTime) { int mx = api.Input.MouseX; int my = api.Input.MouseY; bool inbounds = Bounds.ParentBounds.PointInside(mx, my); double posY = insideBounds.absY; double ypad = GuiElement.scaled(unscalledYPad); foreach (IFlatListItem element in Elements) { if (!element.Visible) { continue; } float y = (float)(5 + Bounds.absY + posY); if (inbounds && mx > Bounds.absX && mx <= Bounds.absX + Bounds.InnerWidth && my >= y - ypad && my <= y + scaled(unscaledCellHeight) - ypad) { api.Render.Render2DLoadedTexture(hoverOverlayTexture, (float)Bounds.absX, y - (float)ypad); } if (posY > -50 && posY < Bounds.OuterHeight + 50) { element.RenderTo(api, Bounds.absX, y); } posY += scaled(unscaledCellHeight + unscaledCellSpacing); } }
public override void OnRenderGUI(float deltaTime) { base.OnRenderGUI(deltaTime); capi.Render.GlPushMatrix(); if (focused) { capi.Render.GlTranslate(0, 0, 150); } double pad = GuiElement.scaled(GuiElementItemSlotGridBase.unscaledSlotPadding); capi.Render.RenderEntityToGui( deltaTime, capi.World.Player.Entity, insetSlotBounds.renderX + pad - 20, insetSlotBounds.renderY + pad, 120, yaw, (float)GuiElement.scaled(140), ColorUtil.WhiteArgb); capi.Render.GlPopMatrix(); }
public override void OnMapOpenedClient() { int size = (int)GuiElement.scaled(32); if (ownTexture == null) { ImageSurface surface = new ImageSurface(Format.Argb32, size, size); Context ctx = new Context(surface); ctx.SetSourceRGBA(0, 0, 0, 0); ctx.Paint(); capi.Gui.Icons.DrawMapPlayer(ctx, 0, 0, size, size, new double[] { 0, 0, 0, 1 }, new double[] { 1, 1, 1, 1 }); ownTexture = new LoadedTexture(capi, capi.Gui.LoadCairoTexture(surface, false), size / 2, size / 2); ctx.Dispose(); surface.Dispose(); } if (otherTexture == null) { ImageSurface surface = new ImageSurface(Format.Argb32, size, size); Context ctx = new Context(surface); ctx.SetSourceRGBA(0, 0, 0, 0); ctx.Paint(); capi.Gui.Icons.DrawMapPlayer(ctx, 0, 0, size, size, new double[] { 0.3, 0.3, 0.3, 1 }, new double[] { 0.7, 0.7, 0.7, 1 }); otherTexture = new LoadedTexture(capi, capi.Gui.LoadCairoTexture(surface, false), size / 2, size / 2); ctx.Dispose(); surface.Dispose(); } foreach (IPlayer player in capi.World.AllOnlinePlayers) { EntityMapComponent cmp; if (MapComps.TryGetValue(player, out cmp)) { cmp?.Dispose(); MapComps.Remove(player); } if (player.Entity == null) { capi.World.Logger.Warning("Can't add player {0} to world map, missing entity :<", player.PlayerUID); continue; } if (capi.World.Config.GetBool("mapHideOtherPlayers", false) && player.PlayerUID != capi.World.Player.PlayerUID) { continue; } cmp = new EntityMapComponent(capi, player == capi.World.Player ? ownTexture : otherTexture, player.Entity); MapComps[player] = cmp; } }
private void onDrawColorRect(Context ctx, ImageSurface surface, ElementBounds currentBounds) { ctx.Rectangle(0, 0, GuiElement.scaled(25), GuiElement.scaled(25)); ctx.SetSourceRGBA(ColorUtil.ToRGBADoubles(color)); ctx.FillPreserve(); ctx.SetSourceRGBA(GuiStyle.DialogBorderColor); ctx.Stroke(); }
public override void OnRenderGUI(float deltaTime) { base.OnRenderGUI(deltaTime); capi.Render.GlPushMatrix(); if (focused) { capi.Render.GlTranslate(0, 0, 150); } capi.Render.GlRotate(-14, 1, 0, 0); mat.Identity(); mat.RotateXDeg(-14); Vec4f lightRot = mat.TransformVector(lighPos); double pad = GuiElement.scaled(GuiElementItemSlotGridBase.unscaledSlotPadding); capi.Render.CurrentActiveShader.Uniform("lightPosition", new Vec3f(lightRot.X, lightRot.Y, lightRot.Z)); capi.Render.PushScissor(insetSlotBounds); if (curTab == 0) { capi.Render.RenderEntityToGui( deltaTime, capi.World.Player.Entity, insetSlotBounds.renderX + pad - GuiElement.scaled(195) * charZoom + GuiElement.scaled(115 * (1 - charZoom)), insetSlotBounds.renderY + pad - GuiElement.scaled(10 + 30 * (1 - charZoom)), (float)GuiElement.scaled(230), yaw, (float)GuiElement.scaled(330 * charZoom), ColorUtil.WhiteArgb); } else { capi.Render.RenderEntityToGui( deltaTime, capi.World.Player.Entity, insetSlotBounds.renderX + pad - GuiElement.scaled(95), insetSlotBounds.renderY + pad - GuiElement.scaled(35), (float)GuiElement.scaled(230), yaw, (float)GuiElement.scaled(180), ColorUtil.WhiteArgb); } capi.Render.PopScissor(); capi.Render.CurrentActiveShader.Uniform("lightPosition", new Vec3f(1, -1, 0).Normalize()); capi.Render.GlPopMatrix(); }
private void OnBgDraw(Context ctx, ImageSurface surface, ElementBounds currentBounds) { double top = cookingSlotsSlotBounds.fixedHeight + cookingSlotsSlotBounds.fixedY; // 1. Fire ctx.Save(); Matrix m = ctx.Matrix; m.Translate(GuiElement.scaled(5), GuiElement.scaled(53 + top)); m.Scale(GuiElement.scaled(0.25), GuiElement.scaled(0.25)); ctx.Matrix = m; capi.Gui.Icons.DrawFlame(ctx); double dy = 210 - 210 * (Attributes.GetFloat("fuelBurnTime", 0) / Attributes.GetFloat("maxFuelBurnTime", 1)); ctx.Rectangle(0, dy, 200, 210 - dy); ctx.Clip(); LinearGradient gradient = new LinearGradient(0, GuiElement.scaled(250), 0, 0); gradient.AddColorStop(0, new Color(1, 1, 0, 1)); gradient.AddColorStop(1, new Color(1, 0, 0, 1)); ctx.SetSource(gradient); capi.Gui.Icons.DrawFlame(ctx, 0, false, false); gradient.Dispose(); ctx.Restore(); // 2. Arrow Right ctx.Save(); m = ctx.Matrix; m.Translate(GuiElement.scaled(63), GuiElement.scaled(top + 2)); m.Scale(GuiElement.scaled(0.6), GuiElement.scaled(0.6)); ctx.Matrix = m; capi.Gui.Icons.DrawArrowRight(ctx, 2); double cookingRel = Attributes.GetFloat("oreCookingTime") / Attributes.GetFloat("maxOreCookingTime", 1); ctx.Rectangle(5, 0, 125 * cookingRel, 100); ctx.Clip(); gradient = new LinearGradient(0, 0, 200, 0); gradient.AddColorStop(0, new Color(0, 0.4, 0, 1)); gradient.AddColorStop(1, new Color(0.2, 0.6, 0.2, 1)); ctx.SetSource(gradient); capi.Gui.Icons.DrawArrowRight(ctx, 0, false, false); gradient.Dispose(); ctx.Restore(); }
// override class in order to allow the rendering of two textures public override void RenderTo(ICoreClientAPI capi, double x, double y) { double posX = GuiElement.scaled(10.0); double posY = GuiElement.scaled(25.0); if (this.Texture != null) { capi.Render.Render2DTexturePremultipliedAlpha(this.Texture.TextureId, x + posX, y + posY / 4.0 - 3.0, this.Texture.Width, this.Texture.Height); } if (this.textTexture == null) { Recompose(capi); } capi.Render.Render2DTexturePremultipliedAlpha(this.textTexture.TextureId, x + posX + 50, y + posY / 4.0 - 3.0, this.textTexture.Width, this.textTexture.Height); }
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(); } }
private bool onClickItem(int page) { currentLoreItemIndex = page; this.page = 0; CairoFont font = CairoFont.WhiteDetailText().WithFontSize(17).WithLineHeightMultiplier(1.15f); TextDrawUtil prober = new TextDrawUtil(); StringBuilder fulltext = new StringBuilder(); JournalEntry entry = journalitems[currentLoreItemIndex]; for (int p = 0; p < entry.Chapters.Count; p++) { if (p > 0) { fulltext.AppendLine(); } fulltext.Append(Lang.Get(entry.Chapters[p].Text)); } pages = Paginate(fulltext.ToString(), font, GuiElement.scaled(629), GuiElement.scaled(450)); double elemToDlgPad = GuiStyle.ElementToDialogPadding; ElementBounds textBounds = ElementBounds.Fixed(0, 0, 630, 450); ElementBounds dialogBounds = textBounds.ForkBoundingParent(elemToDlgPad, elemToDlgPad + 20, elemToDlgPad, elemToDlgPad + 30).WithAlignment(EnumDialogArea.LeftMiddle); dialogBounds.fixedX = 350; Composers["loreItem"] = capi.Gui .CreateCompo("loreItem", dialogBounds) .AddShadedDialogBG(ElementBounds.Fill, true) .AddDialogTitleBar(Lang.Get(journalitems[page].Title), CloseIconPressedLoreItem) .AddRichtext(pages[0], font, textBounds, "page") .AddDynamicText("1 / " + pages.Length, CairoFont.WhiteSmallishText().WithOrientation(EnumTextOrientation.Center), ElementBounds.Fixed(250, 500, 100, 30), "currentpage") .AddButton(Lang.Get("Previous Page"), OnPrevPage, ElementBounds.Fixed(17, 500, 100, 23).WithFixedPadding(10, 4), CairoFont.WhiteSmallishText()) .AddButton(Lang.Get("Next Page"), OnNextPage, ElementBounds.Fixed(520, 500, 100, 23).WithFixedPadding(10, 4), CairoFont.WhiteSmallishText()) .Compose() ; return(true); }
public override void OnMouseUpOnElement(ICoreClientAPI api, MouseEvent args) { if (!Bounds.ParentBounds.PointInside(args.X, args.Y)) { return; } if (!wasMouseDownOnElement) { return; } wasMouseDownOnElement = false; int i = 0; int mx = api.Input.MouseX; int my = api.Input.MouseY; double posY = insideBounds.absY; foreach (IFlatListItem element in Elements) { if (!element.Visible) { i++; continue; } float y = (float)(5 + Bounds.absY + posY); double ypad = GuiElement.scaled(unscalledYPad); if (mx > Bounds.absX && mx <= Bounds.absX + Bounds.InnerWidth && my >= y - ypad && my <= y + scaled(unscaledCellHeight) - ypad) { api.Gui.PlaySound("menubutton_press"); onLeftClick?.Invoke(i); args.Handled = true; return; } posY += scaled(unscaledCellHeight + unscaledCellSpacing); i++; } }
private bool onClickItem(int i) { currentLoreItemIndex = i; page = 0; CairoFont font = CairoFont.WhiteDetailText().WithFontSize(17); TextSizeProber prober = new TextSizeProber(); StringBuilder fulltext = new StringBuilder(); for (int p = 0; p < journalitems[currentLoreItemIndex].Pieces.Length; p++) { if (p > 0) { fulltext.AppendLine(); } fulltext.Append(journalitems[currentLoreItemIndex].Pieces[p]); } pages = Paginate(fulltext, font, GuiElement.scaled(629), GuiElement.scaled(450), 1.15); double elemToDlgPad = ElementGeometrics.ElementToDialogPadding; ElementBounds textBounds = ElementBounds.Fixed(0, 0, 630, 450); ElementBounds dialogBounds = textBounds.ForkBoundingParent(elemToDlgPad, elemToDlgPad + 20, elemToDlgPad, elemToDlgPad + 30).WithAlignment(EnumDialogArea.LeftMiddle); dialogBounds.fixedX = 350; DialogComposers["loreItem"] = capi.Gui .CreateCompo("loreItem", dialogBounds, false) .AddDialogBG(ElementBounds.Fill, true) .AddDialogTitleBar(journalitems[i].Title, CloseIconPressedLoreItem) .AddDynamicText(pages[0], font, EnumTextOrientation.Left, textBounds, 1.15f, "page") .AddDynamicText("1 / " + pages.Length, CairoFont.WhiteSmallishText(), EnumTextOrientation.Center, ElementBounds.Fixed(250, 500, 100, 30), 1, "currentpage") .AddButton("Previous Page", OnPrevPage, ElementBounds.Fixed(17, 500, 100, 23).WithFixedPadding(10, 4), CairoFont.WhiteSmallishText()) .AddButton("Next Page", OnNextPage, ElementBounds.Fixed(520, 500, 100, 23).WithFixedPadding(10, 4), CairoFont.WhiteSmallishText()) .Compose() ; return(true); }
public override void RenderTo(ICoreClientAPI capi, double x, double y) { float size = (float)GuiElement.scaled(25); float pad = (float)GuiElement.scaled(10); if (Texture == null) { Recompose(capi); } capi.Render.Render2DTexturePremultipliedAlpha( Texture.TextureId, (x + pad), y + size / 4 - 3, Texture.Width, Texture.Height, 50 ); }
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(); } }
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 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 override void RenderTo(ICoreClientAPI capi, double x, double y) { float size = (float)GuiElement.scaled(25); float pad = (float)GuiElement.scaled(10); int index = (int)((capi.ElapsedMilliseconds / 1000) % Stacks.Count); dummySlot.Itemstack = Stacks[index]; capi.Render.RenderItemstackToGui(dummySlot, x + pad + size / 2, y + size / 2, 100, size, ColorUtil.WhiteArgb, true, false, false); if (Texture == null) { Texture = new TextTextureUtil(capi).GenTextTexture(Name, CairoFont.WhiteSmallText()); } capi.Render.Render2DTexturePremultipliedAlpha( Texture.TextureId, (x + size + GuiElement.scaled(25)), y + size / 4 - 3, Texture.Width, Texture.Height, 50 ); }
public override void ComposeElements(Context ctxStatic, ImageSurface surfaceStatic) { insideBounds = new ElementBounds().WithFixedPadding(unscaledCellSpacing).WithEmptyParent(); insideBounds.CalcWorldBounds(); CalcTotalHeight(); Bounds.CalcWorldBounds(); ImageSurface surface = new ImageSurface(Format.Argb32, (int)Bounds.InnerWidth, (int)GuiElement.scaled(unscaledCellHeight)); Context ctx = new Context(surface); ctx.SetSourceRGBA(1, 1, 1, 0.5); ctx.Paint(); generateTexture(surface, ref hoverOverlayTexture); ctx.Dispose(); surface.Dispose(); }
void loadWorldPos(double mouseX, double mouseY, ref Vec3d worldPos) { double x = mouseX - SingleComposer.Bounds.absX; double y = mouseY - SingleComposer.Bounds.absY - (dialogType == EnumDialogType.Dialog ? GuiElement.scaled(30) : 0); // no idea why the 30 :/ mapElem.TranslateViewPosToWorldPos(new Vec2f((float)x, (float)y), ref worldPos); worldPos.Y++; }
public override void OnLoaded(ICoreAPI api) { paintableOnBlockMaterials = new EnumBlockMaterial[onmaterialsStrTmp.Length]; for (int i = 0; i < onmaterialsStrTmp.Length; i++) { if (onmaterialsStrTmp[i] == null) { continue; } try { paintableOnBlockMaterials[i] = (EnumBlockMaterial)Enum.Parse(typeof(EnumBlockMaterial), onmaterialsStrTmp[i]); } catch (Exception) { api.Logger.Warning("ArtPigment behavior for collectible {0}, paintable on material {1} is not a valid block material, will default to stone", collObj.Code, onmaterialsStrTmp[i]); paintableOnBlockMaterials[i] = EnumBlockMaterial.Stone; } } onmaterialsStrTmp = null; var capi = api as ICoreClientAPI; foreach (var loc in decorCodesTmp) { if (loc.Path.Contains("*")) { Block[] blocks = api.World.SearchBlocks(loc); foreach (var block in blocks) { decorBlocks.Add(block); //Console.WriteLine("\"/bir remapq " + block.Code.ToShortString() + " drawnart"+block.Variant["material"]+"-1-" + block.Variant["row"] +"-" + block.Variant["col"] + " force\","); } if (blocks.Length == 0) { api.Logger.Warning("ArtPigment behavior for collectible {0}, decor {1}, no such block using this wildcard found", collObj.Code, loc); } } else { Block block = api.World.GetBlock(loc); if (block == null) { api.Logger.Warning("ArtPigment behavior for collectible {0}, decor {1} is not a loaded block", collObj.Code, loc); } else { decorBlocks.Add(block); } } } if (api.Side == EnumAppSide.Client) { if (decorBlocks.Count > 0) { BakedCompositeTexture tex = decorBlocks[0].Textures["up"].Baked; texPos = capi.BlockTextureAtlas.Positions[tex.TextureSubId]; } else { texPos = capi.BlockTextureAtlas.UnknownTexturePosition; } } AssetLocation blockCode = collObj.Code; toolModes = new SkillItem[decorBlocks.Count]; for (int i = 0; i < toolModes.Length; i++) { toolModes[i] = new SkillItem() { Code = blockCode.CopyWithPath("art" + i), // Unique code, it doesn't really matter what it is Linebreak = i % GlobalConstants.CaveArtColsPerRow == 0, Name = "", // No name - alternatively each icon could be given a name? But discussed in meeting on 6/6/21 and decided it is better for players to assign their own meanings to the icons Data = decorBlocks[i], RenderHandler = (AssetLocation code, float dt, double atPosX, double atPosY) => { float wdt = (float)GuiElement.scaled(GuiElementPassiveItemSlot.unscaledSlotSize); string id = code.Path.Substring(3); capi.Render.Render2DTexture(meshes[int.Parse(id)], texPos.atlasTextureId, (float)atPosX, (float)atPosY, wdt, wdt); } }; } if (capi != null) { meshes = new MeshRef[decorBlocks.Count]; for (int i = 0; i < meshes.Length; i++) { MeshData mesh = genMesh(i); meshes[i] = capi.Render.UploadMesh(mesh); } } }
public void Init() { var descBounds = ElementBounds.Fixed(0, 30, 400, 80); ElementBounds bgBounds = ElementBounds.Fill.WithFixedPadding(GuiStyle.ElementToDialogPadding); bgBounds.BothSizing = ElementSizing.FitToChildren; dialogBounds = ElementStdBounds .AutosizedMainDialog.WithAlignment(EnumDialogArea.CenterMiddle) .WithFixedAlignmentOffset(-GuiStyle.DialogToScreenPadding, 0); bgBounds.verticalSizing = ElementSizing.FitToChildren; bgBounds.horizontalSizing = ElementSizing.Fixed; bgBounds.fixedWidth = 300; #region Text var deliveryCosts = auctionSys.DeliveryCostsByDistance(traderEntity.Pos.XYZ, auction.SrcAuctioneerEntityPos); RichTextComponentBase[] stackComps = new RichTextComponentBase[] { new ItemstackTextComponent(capi, auction.ItemStack, 60, 10), new RichTextComponent(capi, auction.ItemStack.GetName() + "\r\n", CairoFont.WhiteSmallText()) }; stackComps = stackComps.Append(VtmlUtil.Richtextify(capi, auction.ItemStack.GetDescription(capi.World, new DummySlot(auction.ItemStack)), CairoFont.WhiteDetailText())); var font = CairoFont.WhiteDetailText(); double fl = font.UnscaledFontsize; ItemStack gearStack = auctionSys.SingleCurrencyStack; var deliveryCostComps = new RichTextComponentBase[] { new RichTextComponent(capi, Lang.Get("Delivery: {0}", deliveryCosts), font) { PaddingRight = 10, VerticalAlign = EnumVerticalAlign.Top }, new ItemstackTextComponent(capi, gearStack, fl * 2.5f, 0, EnumFloat.Inline) { VerticalAlign = EnumVerticalAlign.Top, offX = -GuiElement.scaled(fl * 0.5f), offY = -GuiElement.scaled(fl * 0.75f) } }; RichTextComponentBase[] totalCostComps = new RichTextComponentBase[] { new RichTextComponent(capi, Lang.Get("Total Cost: {0}", auction.Price + deliveryCosts), font) { PaddingRight = 10, VerticalAlign = EnumVerticalAlign.Top }, new ItemstackTextComponent(capi, gearStack, fl * 2.5f, 0, EnumFloat.Inline) { VerticalAlign = EnumVerticalAlign.Top, offX = -GuiElement.scaled(fl * 0.5f), offY = -GuiElement.scaled(fl * 0.75f) } }; #endregion Composers["confirmauctionpurchase"] = capi.Gui .CreateCompo("tradercreateauction-" + buyerEntity.EntityId, dialogBounds) .AddShadedDialogBG(bgBounds, true) .AddDialogTitleBar(Lang.Get("Purchase this item?"), OnCreateAuctionClose) .BeginChildElements(bgBounds) .AddRichtext(stackComps, descBounds, "itemstack") ; var ri = Composers["confirmauctionpurchase"].GetRichtext("itemstack"); ri.BeforeCalcBounds(); double y = Math.Max(110, descBounds.fixedHeight + 20); ElementBounds deliverySwitchBounds = ElementBounds.Fixed(0, y, 35, 25); ElementBounds deliveryTextBounds = ElementBounds.Fixed(0, y + 3, 250, 25).FixedRightOf(deliverySwitchBounds, 0); ElementBounds deliveryCostBounds = ElementBounds.Fixed(0, 0, 200, 30).FixedUnder(deliveryTextBounds, 20); ElementBounds totalCostBounds = ElementBounds.Fixed(0, 0, 150, 30).FixedUnder(deliveryCostBounds, 0); ElementBounds leftButton = ElementBounds.Fixed(EnumDialogArea.LeftFixed, 0, 0, 0, 0).WithFixedPadding(8, 5).FixedUnder(totalCostBounds, 15); ElementBounds rightButton = ElementBounds.Fixed(EnumDialogArea.RightFixed, 0, 0, 0, 0).WithFixedPadding(8, 5).FixedUnder(totalCostBounds, 15); Composers["confirmauctionpurchase"] .AddSwitch(onDeliveryModeChanged, deliverySwitchBounds, "delivery", 25) .AddStaticText(Lang.Get("Deliver to current trader"), CairoFont.WhiteSmallText(), deliveryTextBounds) .AddRichtext(deliveryCostComps, deliveryCostBounds, "deliveryCost") .AddRichtext(totalCostComps, totalCostBounds, "totalCost") .AddSmallButton(Lang.Get("Cancel"), OnCancel, leftButton) .AddSmallButton(Lang.Get("Purchase"), OnPurchase, rightButton, EnumButtonStyle.Normal, EnumTextOrientation.Left, "buysellButton") .EndChildElements() .Compose() ; Composers["confirmauctionpurchase"].GetSwitch("delivery").On = true; }
static void Richtextify(ICoreClientAPI capi, VtmlToken token, ref List <RichTextComponentBase> elems, Stack <CairoFont> fontStack, Action <LinkTextComponent> didClickLink) { if (token is VtmlTagToken) { VtmlTagToken tagToken = token as VtmlTagToken; switch (tagToken.Name) { case "br": elems.Add(new RichTextComponent(capi, "\r\n", fontStack.Peek())); break; case "i": CairoFont font = fontStack.Peek().Clone(); font.Slant = FontSlant.Italic; fontStack.Push(font); foreach (var val in tagToken.ChildElements) { Richtextify(capi, val, ref elems, fontStack, didClickLink); } fontStack.Pop(); break; case "a": LinkTextComponent cmp = new LinkTextComponent(capi, tagToken.ContentText, fontStack.Peek(), didClickLink); tagToken.Attributes.TryGetValue("href", out cmp.Href); elems.Add(cmp); break; case "icon": string iconName; tagToken.Attributes.TryGetValue("name", out iconName); IconComponent iconcmp = new IconComponent(capi, iconName, fontStack.Peek()); elems.Add(iconcmp); break; case "itemstack": string code; string type; float size = (float)fontStack.Peek().GetFontExtents().Height; EnumFloat floatType = EnumFloat.Inline; string floattypestr; if (tagToken.Attributes.TryGetValue("floattype", out floattypestr)) { if (!Enum.TryParse(floattypestr, out floatType)) { floatType = EnumFloat.Inline; } } tagToken.Attributes.TryGetValue("code", out code); if (!tagToken.Attributes.TryGetValue("type", out type)) { type = "block"; } ItemStack stack; if (type == "item") { stack = new ItemStack(capi.World.GetItem(new AssetLocation(code))); } else { stack = new ItemStack(capi.World.GetBlock(new AssetLocation(code))); } float sizemul = 1f; if (tagToken.Attributes.TryGetValue("rsize", out var sizemulstr)) { sizemul = sizemulstr.ToFloat(); } SlideshowItemstackTextComponent stckcmp = new SlideshowItemstackTextComponent(capi, new ItemStack[] { stack }, size / RuntimeEnv.GUIScale, floatType); stckcmp.renderSize *= sizemul; stckcmp.VerticalAlign = EnumVerticalAlign.Middle; if (tagToken.Attributes.TryGetValue("offx", out var offxstr)) { stckcmp.offX = GuiElement.scaled(offxstr.ToFloat(0)); } if (tagToken.Attributes.TryGetValue("offy", out var offystr)) { stckcmp.offY = GuiElement.scaled(offystr.ToFloat(0)); } elems.Add(stckcmp); break; case "font": fontStack.Push(getFont(tagToken, fontStack)); foreach (var val in tagToken.ChildElements) { Richtextify(capi, val, ref elems, fontStack, didClickLink); } fontStack.Pop(); break; case "clear": elems.Add(new ClearFloatTextComponent(capi)); break; case "strong": fontStack.Push(fontStack.Peek().Clone().WithWeight(Cairo.FontWeight.Bold)); foreach (var val in tagToken.ChildElements) { Richtextify(capi, val, ref elems, fontStack, didClickLink); } fontStack.Pop(); break; } if (tagToken.Name != null && TagConverters.ContainsKey(tagToken.Name)) { RichTextComponentBase elem = TagConverters[tagToken.Name](capi, tagToken, fontStack, didClickLink); if (elem != null) { elems.Add(elem); } } } else { VtmlTextToken textToken = token as VtmlTextToken; elems.Add(new RichTextComponent(capi, textToken.Text, fontStack.Peek())); } }