Jump to content

Get WoWPlayer Realm


Recommended Posts

Just my luck, but in an LFR I did today I had a tank and dps with the same name, but different server.

 

I use a lua script to get the name of the tanks and then grab the WoWPlayer instance by the name. This kinda broke and my healer was prioritizing the DPS over the Tank because the DPS was closer.

 

I can get the realm easily enough with the lua script (GetUnitName("raid\ .. groupindex, true); returns [name]-[realm] or [name] if the player is on the same server), but I don't see a property in the WoWPlayer class to get the realm name for that player.

 

Is there any way to get the WoWPlayer's realm if they are on a different realm?

 

Edit: Or if there's a way to get the WoWPlayer instance from the raid/party unit name (raid1, raid2, party1, party2, etc) then I could make that work.

Link to comment
Share on other sites

Yeah my lua is pretty similar, but my problem was with the WowPlayer object and not being able to get the realm name from the WowPlayer instance. Here's the code I'm using to get the tank names:

 var lua = new[]
        {
            "partyTanks = \"\";",
            "for groupindex = 1,GetNumGroupMembers() do",
            "   if IsInRaid() then",
            "	    local role = UnitGroupRolesAssigned(\"raid\" .. groupindex);",
            "		if role == \"TANK\" then",
            // "		    local name = GetUnitName(\"raid\" .. groupindex, true);",
            "			local name, realm = UnitName(\"raid\" .. groupindex);",
            "			partyTanks  = partyTanks ..  name .. \",\";",
            "		end",
            "   elseif IsInGroup() then",
            "	    local role = UnitGroupRolesAssigned(\"party\" .. groupindex)",
            "		if role == \"TANK\" then",
            //  "		    local name = GetUnitName(\"party\" .. groupindex, true);",
            "			local name, realm = UnitName(\"party\" .. groupindex);",
            "			partyTanks = name;",
            "			return;   ",
            "		end",
            "   end",
            "end ",
        };

        var val = Lua.LuaDoString(lua, "partyTanks");
        if (string.IsNullOrWhiteSpace(val))
        {
            Logging.WriteFight("No tanks found!");
            return new List<string>();
        }
        var tankNames = val.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); //Remove last comma and empty entries if raid.
        Logging.WriteDebug("Tanks: " + string.Join(", ", tankNames));
        return tankNames;

 

 

And here's the code I use to find the WoWPlayer instance for the tank(s):

List<WoWPlayer> tankList = Party.GetPartyHomeAndInstance().Where(m => tankNames.Contains(m.Name)).ToList();

 

Note: My Fight Class is in full CS.

 

Let's say I have 2 people from different realms in my cross-realm raid: Steve-Kel'Thuzad who is a tank and Steve-Frostwolf who is a DPS.

 

The lua code to get the tank will return back "Steve", "Steve (*)", or "Steve-Kel'Thuzad" depending on which lua function you use to get the unit name. The 3 common ones are:

  • local name, realm = UnitName(unit); //Steve
  • local name = GetUnitName(unit); //Steve (*)
  • local name = GetUnitName(unit, true); //Steve-Kel'Thuzad

 

The problem comes here...

  • Steve-Kel'Thuzad's WoWPlayer instance returns "Steve" for WowPlayer.Name
  • Steve-Frostwolf's WoWPlayer instance ALSO returns "Steve" for WoWPlayer.Name

 

Now, when I use Party.GetPartyHomeAndInstance().Where(m => tankNames.Contains(m.Name)), I will get the following results:

  • local name, realm = UnitName(unit); //Steve
    • 2 instances of WoWPlayer
  • local name = GetUnitName(unit); //Steve (*)
    • 0 intstances of WoWPlayer
  • local name = GetUnitName(unit, true); //Steve-Kel'Thuzad
    • 0 instances of WoWPlayer

 

While it's quite rare to get 2 people with the same name in a CRZ group, it does happen, and when it does it breaks healing profiles completely. With Blizz becoming more and more crazy for CRZ, I won't be surprised it I'm not the only one who's ran into this issue.

 

What would be perfect is WoWPlayer properties to get the CRZ name and/or realm.

 

So, for instance, WoWPlayer.CrossRealmName would return [name]-[realm] if the player is on another realm and [name] if the player is on the same realm as me.

 

 

I hope this was easy to understand. I live in the states and it's pretty late here lol.

Link to comment
Share on other sites

I have added WowUnit.Guid128 , you can compare it with http://wow.gamepedia.com/API_UnitGUID.

Sample (not tested) (work in wrobot for wod and legion):

    public static List<WoWPlayer> GetTanks()
    {
        var r = new List<WoWPlayer>();

        var lua = @"local partyTanks = '';
                    for groupindex = 1,GetNumGroupMembers() do
                       if IsInRaid() then
	                        local role = UnitGroupRolesAssigned('raid' .. groupindex);
		                    if role == 'TANK' then
			                    local guid = UnitGUID('raid' .. groupindex);
			                    partyTanks  = partyTanks ..  guid .. ';';
		                    end
                       elseif IsInGroup() then
	                        local role = UnitGroupRolesAssigned('party' .. groupindex)
		                    if role == 'TANK' then
			                    local guid = UnitGUID('party' .. groupindex);
			                    partyTanks  = partyTanks ..  guid .. ';';
		                    end
                       end
                    end
                    return partyTanks;
                    ";

        var val = Lua.LuaDoString<string>(lua);
        if (string.IsNullOrWhiteSpace(val))
            return r; // no tank

        var tanksGUID = val.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
        if (tanksGUID.Length <= 0)
            return r;

        foreach (var p in Party.GetPartyHomeAndInstance())
        {
            if (!p.IsValid)
                continue;

            foreach (var guid in tanksGUID)
            {
                if (string.IsNullOrWhiteSpace(guid))
                    continue;

                if (p.Guid128.ToString().ToLower() == guid.Trim().ToLower())
                    r.Add(new WoWPlayer(p.GetBaseAddress));
            }
        }

        return r;
    }

 

Link to comment
Share on other sites

Other same (not tested):

    public enum GroupRoles
    {
        NONE,
        TANK,
        HEALER,
        DAMAGER
    }
    public static List<WoWPlayer> GetMembersByRoles(GroupRoles role)
    {
        var r = new List<WoWPlayer>();

        var lua = @"local retMembers = '';
                    for groupindex = 1,GetNumGroupMembers() do
                       if IsInRaid() then
	                        local role = UnitGroupRolesAssigned('raid' .. groupindex);
		                    if role == '"+ role + @"' then
			                    local guid = UnitGUID('raid' .. groupindex);
			                    retMembers  = retMembers ..  guid .. ';';
		                    end
                       elseif IsInGroup() then
	                        local role = UnitGroupRolesAssigned('party' .. groupindex)
		                    if role == '" + role + @"' then
			                    local guid = UnitGUID('party' .. groupindex);
			                    retMembers  = retMembers ..  guid .. ';';
		                    end
                       end
                    end
                    return retMembers;
                    ";

        var val = Lua.LuaDoString<string>(lua);
        if (string.IsNullOrWhiteSpace(val))
            return r; // no tank

        var membersGUID = val.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
        if (membersGUID.Length <= 0)
            return r;

        foreach (var p in Party.GetPartyHomeAndInstance())
        {
            if (!p.IsValid)
                continue;

            foreach (var guid in membersGUID)
            {
                if (string.IsNullOrWhiteSpace(guid))
                    continue;

                if (p.Guid128.ToString().ToLower() == guid.Trim().ToLower())
                    r.Add(new WoWPlayer(p.GetBaseAddress));
            }
        }

        return r;
    }

 

Link to comment
Share on other sites

7 hours ago, BetterSister said:

Wanna tell us too? :blink:

I'm basically doing what Droidz is doing. Using the GUIDs to get make sure the user is correct.

 

 

 

 

This code is tested and should work (I modified it to return any role, but I'll test again and make sure). Here's my code:

 public enum Roles
    {
        TANK,
        HEALER,
        DAMAGER
    }


    public static List<string> GetGUIDsByRole(Roles role)
    {
        
        string lua =       
           @"guids = """";
            for groupindex = 1,GetNumGroupMembers() do
               if IsInRaid() then
                  local role = UnitGroupRolesAssigned(""raid"" .. groupindex);
                  if role == ""{0}"" then
                     local name = UnitGUID(""raid"" .. groupindex);
                     guids  = guids ..  name .. "" "";
                  end
               elseif IsInGroup() then
                  local role = UnitGroupRolesAssigned(""party"" .. groupindex)
                  if role == ""{0}"" then
                     local name = UnitGUID(""party"" .. groupindex);
                     guids = name;
                     return;   
                  end
               end
            end ";

        var val = Lua.LuaDoString(string.Format(lua, role), "guids");
        if (string.IsNullOrWhiteSpace(val))
        {
            Logging.WriteFight("No tanks found!");
            return new List<string>();
        }
        var tankNames = val.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
        return tankNames;
    }

 

 

 

And Here's where I map them to units:

public static List<WoWPlayer> GetPartyMembersByRole(Roles role, Vector3 positionCenter, int maxHealthPercent = 100, float maxDistance = float.MaxValue, bool orderByHealth = true)
        {
            var guids = GetGUIDsByRole(role);
            if (guids.Count == 0)
                return new List<WoWPlayer>();
        
            var units = Party.GetPartyHomeAndInstance().Where(m => guids.Contains(m.Guid128.ToString()) && m.IsValid && m.IsAlive && m.HealthPercent < maxHealthPercent && m.Position.DistanceTo(positionCenter) <= maxDistance);

            if (orderByHealth)
                units = units.OrderBy(p => p.HealthPercent);

            return units.ToList();
        }

 

 

 

 

 

This issue would also break SpellManager.CastSpellByNameOn(), so I do this to get the full/CRZ name when casting a heal:

public static string GetCRZName(WoWUnit unit)
    {
        if (!(unit is WoWPlayer))
            return unit.Name;
        string lua = @"class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(UnitGUID(""{0}""));
                    if(realm ~= nil and realm ~= """") then   
                       name = name .. ""-"" .. realm;
                    end";

        var name = Lua.LuaDoString(string.Format(lua, unit.Guid128.ToString()), "name");
        return name;
    } 


public static async Task<bool> CastHeal(Spell spell, WoWUnit unit, bool reqs, bool ignoreUsable = false)
    {
        if (!reqs) return false;
        string myspell = spell.Name;
        if (!spell.KnownSpell) return false;
        if (!spell.IsSpellUsable && !ignoreUsable) return false;
        if (SpellManager.GetSpellCooldownTimeLeft(myspell) > 0) return false;
        try
        {
            
            SpellManager.CastSpellByNameOn(myspell, GetCRZName(unit));
            if (LastLog != myspell)
            {
                Logging.WriteFight(myspell);
                LastLog = myspell;
            }
            await Task.Delay(Usefuls.Latency);
            return true;
        }
        catch (Exception e) { Logging.WriteFight("CastOn: " + myspell + " " + e.ToString()); }
        return false;
    }

 

 

Note: I check to see if realm is nil or empty because realm isn't returned if the player is on the same realm. I also check to make sure the WoWUnit is a player before executing the code because it will error out otherwise.

Link to comment
Share on other sites

  • 1 month later...

It's too complicated for me :)

 

Let's assume i want to 

				SpellManager.CastSpellByNameOn(spell.Name, ObjectManager.Me.Name);

this is not functionning this way

How do i achieve this?

 

Why do i ask this question, because

Interact.InteractGameObject(partyMember.GetBaseAddress, true);

do a interrupt movement, and i cant cast instant spell without a little stop when i run, its very frustating :) when there is a lot of aoe under my feet and i want to heal instant cast

Link to comment
Share on other sites

28 minutes ago, AudreyH said:

It's too complicated for me :)

 

Let's assume i want to 


				SpellManager.CastSpellByNameOn(spell.Name, ObjectManager.Me.Name);

this is not functionning this way

How do i achieve this?

 

Why do i ask this question, because


Interact.InteractGameObject(partyMember.GetBaseAddress, true);

do a interrupt movement, and i cant cast instant spell without a little stop when i run, its very frustating :) when there is a lot of aoe under my feet and i want to heal instant cast

In CastSpellByNameOn you need to put lua unit id (not unit name)

To don't stop move, you can try:

Interact.InteractGameObject(partyMember.GetBaseAddress, false, true);

 

Link to comment
Share on other sites

In CastSpellByNameOn you need to put lua unit id (not unit name)

I understand this, i forgot about "partyMember.Guid128", i will search on this

 

Interact.InteractGameObject(partyMember.GetBaseAddress, false, true);

It's ok, i didn't realize there was more option lol

 

Thxs Droidz

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...