Hugagug

Initiate
ServUO Version
Publish Unknown
Ultima Expansion
Endless Journey
I did have this working a bit better before and it would track another player moving in real time. The radar gump 'openradar is an empty version of the mini-map meant to be stacked on the old one. For testing you may need to toggle that command after joining party.

There's a central dot that shows your location. Other players up to X tiles away get their own dot with their names over it. Not working at all is the quest tracking arrows to point towards a player if they're out of range.

I've tried adding console messages before along with +134 to reference the middle of the gump. Now that middle spot always 'just works' now. Code to pay attention to would be in #region problematic math.

C#:
using System;
using Server;
using Server.Items;
using Server.Network;
using Server.Mobiles;
using Server.SkillHandlers; //tracking arrow
using Server.Engines.PartySystem;
using System.Collections;
using System.Collections.Generic;
using Server.Gumps;
using Server.Commands;

namespace Server.Gumps
{
    public class PartyRadarGump : Gump
    {
        public static void Initialize()
        {
            CommandSystem.Register( "ShowRadar", AccessLevel.Player, new CommandEventHandler( ShowRadar_OnCommand ) );
            CommandSystem.Register( "Radar", AccessLevel.Player, new CommandEventHandler( ShowRadar_OnCommand ) );
        }
       
        [Usage( "ShowRadar" )]
        public static void ShowRadar_OnCommand( CommandEventArgs e )
        {
            if ( e.Mobile != null )
            {
                if ( !e.Mobile.HasGump( typeof( PartyRadarGump ) ) )
                    e.Mobile.SendGump( new PartyRadarGump( e.Mobile, e.Mobile ) );
                else if ( e.Mobile.HasGump( typeof( PartyRadarGump ) ) )
                {
                    //Gump gump = e.Mobile.GetGump( typeof( PartyRadarGump ) );
                    e.Mobile.CloseGump( typeof( PartyRadarGump ) );
                }
            }
        }
       
        public PartyRadarGump( Mobile from, Mobile pm ) : base( 5, 5 )
        {
            int gumpX = 0; // Default X value
            int gumpY = 0; // Default Y value

            int minY = 15; // Minimum Radar Y value - needs to be verified
            int maxY = 20; //Maximum Radar Y value - needs to be verified

            int minX = 15; // Minimum Radar X value - needs to be verified
            int maxX = 20; // Maximum Radar X value - needs to be verified

            //Base Gump Objects
            AddPage( 0 );
            AddImage( 0, 0, 9006 );
            AddImage( 134, 134, 1209 );

            //Positioning of Icon gumps on radar
            Party p = Engines.PartySystem.Party.Get( from );
            if ( p == null )
                return;

            foreach ( PartyMemberInfo mi in p.Members )
            {
                PlayerMobile pl = mi.Mobile as PlayerMobile;

                if ( pl != from )
                {
                    gumpX = 0;
                    gumpY = 0;

                    #region problematic math
                    /*Point3D myLoc = new Point3D( from.X, from.Y, from.Z);
                    Point3D theirLoc = new Point3D( pl.X, pl.Y, pl.Z);

                    double distanceX = Math.Sqrt(Math.Pow(theirLoc.X - myLoc.X, 2) ); // calculate distance from player to party member on X axis
                    double distanceY = Math.Sqrt(Math.Pow(theirLoc.Y - myLoc.Y, 2) ); // calculate distance from player to party member on Y axis

                    if ( pl.X < from.X )
                        gumpX = (134 - (Convert.ToInt32(distanceX))); // converts (center of gump - distance between players to integer = X Axis
                    else
                        gumpX = (134 + Convert.ToInt32(distanceX)); // converts (center of gump - distance between players to integer = X Axis

                    if (pl.Y < from.Y )
                        gumpY = (134 - (Convert.ToInt32(distanceY))); // converts (center of gump - distance between players to integer = Y Axis
                    else
                        gumpY = (134 + Convert.ToInt32(distanceY)); // converts (center of gump - distance between players to integer = Y Axis
                    */
                    //======================================================
                    //Tecmo revision
                    //======================================================
                    // Calculate distance between the two points
                    Point3D myLoc = new Point3D(from.X, from.Y, from.Z);
                    Point3D theirLoc = new Point3D(pl.X, pl.Y, pl.Z);

                    // Calculate axis-aligned distances
                    double distanceX = theirLoc.X - myLoc.X;
                    double distanceY = theirLoc.Y - myLoc.Y;

                    gumpX = (distanceX == 0) ? 134 : 134 + (int)distanceX;
                    gumpY = (distanceY == 0) ? 134 : 134 + (int)distanceY;
                    //======================================================

                    #endregion where my coffee at

                    /*if ( pl == p.Leader) // Add a blue 'dot' for party leader
                    {
                   
                        if ( gumpX < minX )
                            gumpX = minX;
                        else if ( gumpX > maxX )
                            gumpX = maxX;
                       
                        if ( gumpY < minY )
                            gumpY = minY;
                        else if ( gumpY > maxY )
                            gumpY = maxY;

                        AddImage( gumpX, gumpY, 2361, 0x489 ); // Add a blue 'dot' for party leader
                        AddLabel( (gumpX - 12), (gumpY -17), 0x489, pl.Name ); // Add party leader's name above dot
                    }
                    else
                    {
                        if ( gumpX < minX )
                            gumpX = minX;
                        else if ( gumpX > maxX )
                            gumpX = maxX;
                       
                        if ( gumpY < minY )
                            gumpY = minY;
                        else if ( gumpY > maxY )
                            gumpY = maxY;

                        AddImage( gumpX, gumpY, 2361, 0x559 ); // Add a green 'dot' for party member
                        AddLabel( (gumpX - 12), (gumpY - 17), 0x559, pl.Name ); // Add party member's name above dot
                    }*/

                    //======================================================
                    //Tecmo revision
                    //======================================================
                    // Clamp gumpX and gumpY to the min and max bounds
                    gumpX = Math.Max(minX, Math.Min(gumpX, maxX));
                    gumpY = Math.Max(minY, Math.Min(gumpY, maxY));

                    // Determine the color and image for the party member (blue for leader, green for others)
                    int dotColor = (pl == p.Leader) ? 0x489 : 0x559;
                    int dotImage = (pl == p.Leader) ? 2361 : 2361; // Same image ID for both, just color changes

                    // Add the image and label
                    AddImage(gumpX, gumpY, dotImage, dotColor); // Add dot with appropriate color
                    AddLabel(gumpX - 12, gumpY - 17, dotColor, pl.Name); // Add party member's name above dot
                                                                         //======================================================



                    /*if ( pm.InRange ( from, 30 ) ) // display indication arrow until player is within 30 tiles
                    {
                        if ( from.QuestArrow != null ) // stop arrow tracking for members within range
                            from.QuestArrow.Stop();
                    }
                    else
                    {
                        if ( pm.InRange( from, 200 ) && pm.Map == from.Map)
                            from.QuestArrow = new TrackArrow( from, pm, 200 ); // uses arrow from Tracking to indicate direction of member outside of radar
                        else if ( from.QuestArrow != null ) // stop arrow tracking if too far out of range or different map
                            from.QuestArrow.Stop();
                    }*/

                    //======================================================
                    //Tecmo revision
                    //======================================================
                    // Check if within 30 tiles range
                    if (pm.InRange(from, 30))
                    {
                        // Stop arrow tracking if within 30 tiles
                        from.QuestArrow?.Stop();
                    }
                    else
                    {
                        // Start or stop arrow tracking based on conditions
                        if (pm.InRange(from, 200) && pm.Map == from.Map)
                            from.QuestArrow = new TrackArrow(from, pm, 200); // Start tracking if within 200 tiles and same map
                        else
                            from.QuestArrow?.Stop(); // Stop tracking if out of range or different map
                    }
                    //======================================================
                }
            }

            GumpTimer gumpTimer = new GumpTimer( from, pm );
            gumpTimer.Start();
        }
    }

    public class GumpTimer : Timer
    {
        private Mobile m_From, m_Target;
        private int m_LastX, m_LastY;
        private bool m_Showing;

        public GumpTimer( Mobile from, Mobile member ) : base( TimeSpan.FromSeconds( 0.5 ))
        {
            m_From = from;
            m_Target = member;
        }

        protected override void OnTick()
        {
            if ( m_From == null || m_Target == null || m_Target.NetState == null || m_From.NetState == null || m_From.Deleted || m_Target.Deleted || m_From.Map != m_Target.Map )
            {
                return;
            }

            Party p = Engines.PartySystem.Party.Get( m_From );
            if ( p != null )
            {
                //Refresh Gump
                m_From.CloseGump( typeof (PartyRadarGump));

                NetState ns = m_From.NetState;
                if (ns != null)
                {
                    List<Gump> gumps = new List<Gump>( ns.Gumps );
                       
                    for ( int i = 0; i < gumps.Count; ++i )
                    {
                        if (gumps[i].GetType() == typeof(PartyRadarGump) )
                        {
                            ns.RemoveGump(i);
                        }
                    }

                }
               
                //if (! m_From.HasGump( typeof( PartyRadarGump)))
                //{
                //}
            }
            else
                return; // just to make testing this POC
           
            PartyRadarGump pr = new PartyRadarGump( m_From, m_Target );
            m_From.SendGump( pr ); // Custom Radar Gump
            Stop(); // Either we use one timer to rule them all or just prevent stacking infinitely this round.
        }
    }
}
 

Attachments

  • 123image.png
    123image.png
    30.2 KB · Views: 5
  • Party Radar Gump (1).cs
    8.8 KB · Views: 0
Just a note, ClassicUO supports showing guild and party members on the world map, so if you're using that client, this kind of feature would be redundant.

Anyway, the issue here is bounding, there is no "clipping" for the circular shape of the mini-map, it still thinks everything should be displayed within a rectangle.

You need to ignore anything that is further away than the radius of the circle from the center point, which is also the range at which the quest arrow should be turned on.
 

Active Shards

Donations

Total amount
$80.00
Goal
$1,000.00
Back