Resource icon

MyStats - Modernized Player Statistics Dashboard 2.0.0

Author
Feng
Downloads
19
Views
334
First release
Last update

Ratings

0.00 star(s) 0 ratings
No permission to download Join the discussion

More resources from Feng

Requirements
ServUO 57.3
No other file dependencies
MyStats is a modernized Quality of Life (QoL) dashboard built off older statistic gumps, redesigned to give players a clean, easy-to-read overview of their character's true capabilities.

Players can access the dashboard at any time by typing [mystats in-game.

Core Features & Sections:

  • Attributes & Vitals: Displays Str, Dex, Int, alongside current and max HP, Stamina, and Mana.
  • Color-Coded Resistances: Shows Physical, Fire, Cold, Poison, and Energy resistances with matching color highlights.
  • Combat & Magic Ratings: Fully utilizes AOS Attributes to pull accurate combat stats (HCI, DCI, DI, SSI, Luck) and magic stats (SDI, LRC, FC, FCR, LMC).
  • Regeneration & Misc: Tracks HP/Stam/Mana regen rates, alongside Fame, Karma, and Weight limits.
  • Live Syncing: Includes a refresh button in the top right corner to instantly update stats without needing to close and reopen the gump.
The True Skills Filter:Older stat gumps often clutter the UI by displaying the Human "Jack of All Trades" 20.0 passive skill bonus. This modernized gump includes a specific check (if (sk.Base > 0)) to ensure that the menu only displays skills the player has actually invested real points into. It neatly organizes up to 24 active skills into a two-column layout.

Installation:Simply drop the code below into a new .cs file in your custom scripts folder, or copy and paste it directly.

C#:
Expand Collapse Copy
using System;
using System.Collections.Generic;
using Server;
using Server.Commands;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Network;

namespace Server.Gumps
{
    public class MyStatsCommand
    {
        public static void Initialize()
        {
            CommandSystem.Register("mystats", AccessLevel.Player, new CommandEventHandler(MyStats_OnCommand));
        }

        [Usage("mystats")]
        [Description("Opens the Player Statistics dashboard.")]
        public static void MyStats_OnCommand(CommandEventArgs e)
        {
            Mobile from = e.Mobile;
            if (from == null || from.Deleted) return;

            from.CloseGump(typeof(PlayerStatsGump));
            from.SendGump(new PlayerStatsGump(from));
        }
    }

    public class PlayerStatsGump : Gump
    {
        private Mobile m_From;

        // Color Constants
        private const int C_YELLOW = 2213;
        private const int C_WHITE = 2036;
        private const int C_RED = 1258;
        private const int C_BLUE = 1264;
        private const int C_GREEN = 1270;
        private const int C_PURPLE = 1276;
        private const int C_GREY = 2401;

        public PlayerStatsGump(Mobile from) : base(50, 50)
        {
            m_From = from;
            AddGumpLayout();
        }

        public void AddGumpLayout()
        {
            int width = 640;
            int height = 850;

            AddPage(0);
            AddBackground(0, 0, width, height, 9200);
            AddImageTiled(10, 10, width - 20, height - 20, 2624);
            AddAlphaRegion(10, 10, width - 20, height - 20);

            // --- HEADER ---
            // Name (Centered Top)
            AddHtml(0, 25, width, 25, ColorAndCenter("#FFCC00", m_From.Name), false, false);

            // Top Right Buttons
            AddButton(width - 75, 21, 4005, 4007, 1, GumpButtonType.Reply, 0); // Sync Button
            AddButton(width - 40, 20, 0xFB1, 0xFB3, 0, GumpButtonType.Reply, 0); // Close Button


            // --- ATTRIBUTES ---
            // Aligned Left (30) and Right (340)
            int attrY = 55;
           
            AddLabel(30, attrY, C_YELLOW, "Attributes");

            DrawStat(30, attrY + 25, "Strength", m_From.Str.ToString());
            DrawStat(340, attrY + 25, "Hit Points", m_From.Hits + " / " + m_From.HitsMax);
           
            DrawStat(30, attrY + 50, "Dexterity", m_From.Dex.ToString());
            DrawStat(340, attrY + 50, "Stamina", m_From.Stam + " / " + m_From.StamMax);
           
            DrawStat(30, attrY + 75, "Intelligence", m_From.Int.ToString());
            DrawStat(340, attrY + 75, "Mana", m_From.Mana + " / " + m_From.ManaMax);


            // --- RESISTANCES ---
            int resY = 175;
            DrawDivider(20, resY - 5, width - 40);
            AddLabel(30, resY + 5, C_YELLOW, "Resistances");
           
            DrawResistBox(130, resY + 5, "Physical", m_From.PhysicalResistance, C_GREY);
            DrawResistBox(230, resY + 5, "Fire", m_From.FireResistance, C_RED);
            DrawResistBox(330, resY + 5, "Cold", m_From.ColdResistance, C_BLUE);
            DrawResistBox(430, resY + 5, "Poison", m_From.PoisonResistance, C_GREEN);
            DrawResistBox(530, resY + 5, "Energy", m_From.EnergyResistance, C_PURPLE);


            // --- RATINGS (Combat & Magic) ---
            int colY = 220;
            DrawDivider(20, colY - 5, width - 40);
            AddLabel(30, colY + 5, C_YELLOW, "Combat Ratings");
            AddLabel(340, colY + 5, C_YELLOW, "Magic Ratings");

            // AOS Fetches
            int hci = AosAttributes.GetValue(m_From, AosAttribute.AttackChance);
            int dci = AosAttributes.GetValue(m_From, AosAttribute.DefendChance);
            int di = AosAttributes.GetValue(m_From, AosAttribute.WeaponDamage);
            int ssi = AosAttributes.GetValue(m_From, AosAttribute.WeaponSpeed);
            int sdi = AosAttributes.GetValue(m_From, AosAttribute.SpellDamage);
            int lmc = AosAttributes.GetValue(m_From, AosAttribute.LowerManaCost);
            int lrc = AosAttributes.GetValue(m_From, AosAttribute.LowerRegCost);
            int fc = AosAttributes.GetValue(m_From, AosAttribute.CastSpeed);
            int fcr = AosAttributes.GetValue(m_From, AosAttribute.CastRecovery);

            // Left Side: Combat
            DrawStat(30, colY + 30, "HCI", hci + "%");
            DrawStat(30, colY + 50, "DCI", dci + "%");
            DrawStat(30, colY + 70, "DI", di + "%");
            DrawStat(30, colY + 90, "SSI", ssi + "%");
            DrawStat(30, colY + 110, "LUCK", AosAttributes.GetValue(m_From, AosAttribute.Luck).ToString());

            // Right Side: Magic
            DrawStat(340, colY + 30, "SDI", sdi + "%");
            DrawStat(340, colY + 50, "LRC", lrc + "%");
            DrawStat(340, colY + 70, "FC", fc.ToString());
            DrawStat(340, colY + 90, "FCR", fcr.ToString());
            DrawStat(340, colY + 110, "LMC", lmc + "%");


            // --- REGENERATION & MISC ---
            int regenY = colY + 160;
           
            AddLabel(30, regenY + 5, C_YELLOW, "Regenerations");
            DrawStat(30, regenY + 30, "HP Regen", AosAttributes.GetValue(m_From, AosAttribute.RegenHits).ToString());
            DrawStat(30, regenY + 50, "Stam Regen", AosAttributes.GetValue(m_From, AosAttribute.RegenStam).ToString());
            DrawStat(30, regenY + 70, "Mana Regen", AosAttributes.GetValue(m_From, AosAttribute.RegenMana).ToString());

            // Miscellaneous Section
            AddLabel(340, regenY + 5, C_YELLOW, "Miscellaneous");
            DrawStat(340, regenY + 30, "Fame", m_From.Fame.ToString());
            DrawStat(340, regenY + 50, "Karma", m_From.Karma.ToString());
            DrawStat(340, regenY + 70, "Weight", m_From.TotalWeight + " / " + m_From.MaxWeight);


            // --- SKILL LIST ---
            int skillY = regenY + 110;
            DrawDivider(20, skillY - 5, width - 40);
            AddLabel(30, skillY + 5, C_YELLOW, "Skills");

            // 2-Column Logic
            int count = 0;
            int startX = 30;
            int startY = skillY + 30;
            int rowSpacing = 25;
            int maxPerCol = 12; 

            for (int i = 0; i < m_From.Skills.Length; i++)
            {
                Skill sk = m_From.Skills[i];
               
                // FIX: Only show if Base > 0 (Ignores Human 20.0 Passive)
                if (sk.Base > 0)
                {
                    int col = count / maxPerCol;
                    int row = count % maxPerCol;

                    if (col >= 2) break;

                    int xPos = (col == 0) ? startX : 340;
                    int yPos = startY + (row * rowSpacing);

                    string val = sk.Value.ToString("F1") + "/" + sk.Cap.ToString("F1");
                   
                    AddLabel(xPos, yPos, C_WHITE, sk.Name);
                    AddLabel(xPos + 130, yPos, C_WHITE, val);

                    count++;
                }
            }
        }

        // --- HELPERS ---

        private string ColorAndCenter(string color, string text)
        {
            return String.Format("<BASEFONT COLOR={0}><CENTER>{1}</CENTER></BASEFONT>", color, text);
        }

        private void DrawResistBox(int x, int y, string name, int val, int color)
        {
            AddLabel(x, y, C_WHITE, name);
            AddLabel(x + 55, y, color, val + "%");
        }

        private void DrawStat(int x, int y, string name, string val)
        {
            AddLabel(x, y, C_WHITE, name);
            AddLabel(x + 130, y, C_WHITE, val);
        }

        private void DrawDivider(int x, int y, int width)
        {
            AddImageTiled(x, y, width, 2, 9264);
        }

        public override void OnResponse(NetState sender, RelayInfo info)
        {
            if (info.ButtonID == 1) // Refresh
            {
                m_From.SendGump(new PlayerStatsGump(m_From));
            }
        }
    }
}
  • MyStats.jpg
    MyStats.jpg
    294.4 KB · Views: 164
  • Like
Reactions: unblest

Latest Updates

  1. Player Stats Dashboard v2.0 (Enhanced Attribute Tracking)

    This update brings a significant overhaul to the visual layout and data accuracy of the Player...

Donations

Total amount
$50.00
Goal
$500.00

Shards

Back