using Cairo; using System; using System.Collections.Generic; using Vintagestory.API.Client; using Vintagestory.API.Common; using Vintagestory.API.Config; [ assembly: ModInfo( "Big Stack Fix", "bigstackfix", Description = "I fix big stacks and I cannot lie", Authors = new []{"Memespren"}, Version = "1.0.0") ] namespace bigstackfix { public class BigItemStackRenderer : ModSystem { ICoreClientAPI capi; Dictionary bigStackTextures; CairoFont stackSizeFont; public override void StartClientSide(ICoreClientAPI api) { capi = api; stackSizeFont = CairoFont.WhiteSmallText().WithFontSize((float)GuiStyle.DetailFontSize); stackSizeFont.FontWeight = FontWeight.Bold; stackSizeFont.Color = new double[] { 1, 1, 1, 1 }; stackSizeFont.StrokeColor = new double[] { 0, 0, 0, 1 }; stackSizeFont.StrokeWidth = RuntimeEnv.GUIScale;// + 0.25; bigStackTextures = new Dictionary(); api.Settings.AddWatcher("guiScale", (newvalue) => { stackSizeFont.StrokeWidth = newvalue;// + 0.25; foreach (var val in bigStackTextures) { val.Value.Dispose(); } bigStackTextures.Clear(); }); api.Event.LeaveWorld += Event_LeaveWorld; api.Event.LevelFinalize += Event_LevelFinalize; } private void Event_LevelFinalize() { foreach (var obj in capi.World.Collectibles) { if(obj.Attributes?["waterTightContainerProps"].Exists == true) continue; else capi.Event.RegisterItemstackRenderer(obj, (inSlot, renderInfo, modelMat, posX, posY, posZ, size, color, rotate, showStackSize) => RenderItemStackGui(inSlot, renderInfo, modelMat, posX, posY, posZ, size, color, rotate, showStackSize), EnumItemRenderTarget.Gui); } } private void Event_LeaveWorld() { foreach (var val in bigStackTextures) { val.Value.Dispose(); } bigStackTextures.Clear(); } public void RenderItemStackGui(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; capi.Render.RenderMesh(renderInfo.ModelRef); if (showStackSize) { string text; int count = itemstack.StackSize; if (count >= 100000) text = (count/1000f).ToString("F0") + "k"; else if (count >= 10000) text = (count/1000f).ToString("F1") + "k"; else if (count >= 1000) text = (count/1000f).ToString("F2") + "k"; else if (count > 1) text = count.ToString(); else text = ""; float mul = size / (float)GuiElement.scaled(32 * 0.65f); var texttex = GetOrCreateTexture(text, 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 LoadedTexture GetOrCreateTexture(string text, float size, float fontSizeMultiplier = 1f) { string key = text + "-" + fontSizeMultiplier + "-1"; if (!bigStackTextures.TryGetValue(key, out var texture)) { CairoFont font = stackSizeFont.Clone(); font.UnscaledFontsize *= fontSizeMultiplier; double width = font.GetTextExtents(text).Width; double ratio = Math.Min(1, 1.5f * size / width); font.UnscaledFontsize *= ratio; return bigStackTextures[key] = capi.Gui.TextTexture.GenTextTexture(text, font); } return texture; } } }