[3.3.3a] Faction Comparisons & Other Info menu

User Tag List

Results 1 to 6 of 6
  1. #1
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [3.3.3a] Faction Comparisons & Other Info

    Just saw a post in the dump thread for 3.3.3a about asking how to compare factions.

    A while ago we actually stopped using UnitReaction in favor of a 'local' comparison method. This allows us to compare factions 'out of process' fairly easily.

    I won't bore you with the details; so here's the WoWFaction class that handles most of it.

    Code:
        public class WoWFaction
        {
            private readonly FactionTemplateDbcRecord _template;
            private FactionDbcRecord _record;
            
            public WoWFaction(int id, bool isTemplate = true)
            {
                Id = id;
                if (IsValid)
                {
                    if (isTemplate)
                    {
                        _template = OnyxWoW.Db[ClientDb.FactionTemplate].GetRow(id).GetStruct<FactionTemplateDbcRecord>();
                        _record = OnyxWoW.Db[ClientDb.Faction].GetRow(_template.FactionId).GetStruct<FactionDbcRecord>();
                    }
                    else
                    {
                        _record = OnyxWoW.Db[ClientDb.Faction].GetRow(id).GetStruct<FactionDbcRecord>();
                    }
                }
            }
    
            public int Id { get; private set; }
            public string Name { get { return _record.Name; } }
            public string Description { get { return _record.Description; } }
            public WoWFaction ParentFaction { get { return new WoWFaction(_record.ParentFaction, false); } }
            public bool IsValid { get { return Id != 0; } }
    
            public WoWUnitRelation RelationTo(WoWFaction other)
            {
                return CompareFactions(this, other);
            }
    
            public static WoWUnitRelation CompareFactions(WoWFaction factionA, WoWFaction factionB)
            {
                FactionTemplateDbcRecord atmpl = factionA._template;
                FactionTemplateDbcRecord btmpl = factionB._template;
    
                if ((btmpl.FightSupport & atmpl.HostileMask) != 0)
                {
                    return (WoWUnitRelation) 1;
                }
    
                for (int i = 0; i < 4; i++)
                {
                    if (atmpl.EnemyFactions[i] == btmpl.Id)
                    {
                        return (WoWUnitRelation) 1;
                    }
                    if (atmpl.EnemyFactions[i] == 0)
                    {
                        break;
                    }
                }
    
                if ((btmpl.FightSupport & atmpl.FriendlyMask) != 0)
                {
                    return (WoWUnitRelation) 4;
                }
    
                for (int i = 0; i < 4; i++)
                {
                    if (atmpl.FriendlyFactions[i] == btmpl.Id)
                    {
                        return (WoWUnitRelation) 4;
                    }
                    if (atmpl.FriendlyFactions[i] == 0)
                    {
                        break;
                    }
                }
    
                if ((atmpl.FightSupport & btmpl.FriendlyMask) != 0)
                {
                    return (WoWUnitRelation) 4;
                }
    
                for (int i = 0; i < 4; i++)
                {
                    if (btmpl.FriendlyFactions[i] == atmpl.Id)
                    {
                        return (WoWUnitRelation) 4;
                    }
                    if (btmpl.FriendlyFactions[i] == 0)
                    {
                        break;
                    }
                }
    
                return (WoWUnitRelation) (~(byte) ((uint) atmpl.FactionFlags >> 12) & 2 | 1);
            }
    
            public override string ToString()
            {
                if (!IsValid)
                {
                    return "N/A";
                }
                return Name + ", Parent: " + ParentFaction;
            }
    
            #region Nested type: FactionDbcRecord
    
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
            private struct FactionDbcRecord
            {
                public int Id;
                private int _unk0;
                public int Allied;
                public int AtWar;
                private int _unk1;
                private int _unk2;
                private int _unk3;
                private int _unk4;
                private int _unk5;
                private int _unk6;
                public int Reputation;
                public int Mod1;
                public int Mod2;
                public int Mod3;
                private int _unk7;
                private int _unk8;
                private int _unk9;
                private int _unk10;
                public int ParentFaction;
    
                // 4 unknowns added recently. Cba to figure out what they're for
                // since I have no use for them!
                private int _unk11;
                private int _unk12;
                private int _unk13;
                private int _unk14;
    
                [MarshalAs(UnmanagedType.LPStr)]
                public string Name;
    
                [MarshalAs(UnmanagedType.LPStr)]
                public string Description;
            }
    
            #endregion
    
            #region Nested type: FactionTemplateDbcRecord
    
            [StructLayout(LayoutKind.Sequential)]
            private struct FactionTemplateDbcRecord
            {
                public int Id;
                public int FactionId;
                public int FactionFlags;
                public int FightSupport;
                public int FriendlyMask;
                public int HostileMask;
    
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
                public int[] EnemyFactions;
    
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
                public int[] FriendlyFactions;
            }
    
            #endregion
        }
    And more importantly; the actual comparison method (it's almost line-for-line taken from WoW, and yes, it does work.)

    Code:
            public static WoWUnitRelation CompareFactions(WoWFaction factionA, WoWFaction factionB)
            {
                FactionTemplateDbcRecord atmpl = factionA._template;
                FactionTemplateDbcRecord btmpl = factionB._template;
    
                if ((btmpl.FightSupport & atmpl.HostileMask) != 0)
                {
                    return (WoWUnitRelation) 1;
                }
    
                for (int i = 0; i < 4; i++)
                {
                    if (atmpl.EnemyFactions[i] == btmpl.Id)
                    {
                        return (WoWUnitRelation) 1;
                    }
                    if (atmpl.EnemyFactions[i] == 0)
                    {
                        break;
                    }
                }
    
                if ((btmpl.FightSupport & atmpl.FriendlyMask) != 0)
                {
                    return (WoWUnitRelation) 4;
                }
    
                for (int i = 0; i < 4; i++)
                {
                    if (atmpl.FriendlyFactions[i] == btmpl.Id)
                    {
                        return (WoWUnitRelation) 4;
                    }
                    if (atmpl.FriendlyFactions[i] == 0)
                    {
                        break;
                    }
                }
    
                if ((atmpl.FightSupport & btmpl.FriendlyMask) != 0)
                {
                    return (WoWUnitRelation) 4;
                }
    
                for (int i = 0; i < 4; i++)
                {
                    if (btmpl.FriendlyFactions[i] == atmpl.Id)
                    {
                        return (WoWUnitRelation) 4;
                    }
                    if (btmpl.FriendlyFactions[i] == 0)
                    {
                        break;
                    }
                }
    
                return (WoWUnitRelation) (~(byte) ((uint) atmpl.FactionFlags >> 12) & 2 | 1);
            }

    [3.3.3a] Faction Comparisons &amp; Other Info
  2. #2
    miceiken's Avatar Contributor Authenticator enabled
    Reputation
    209
    Join Date
    Dec 2007
    Posts
    401
    Thanks G/R
    7/9
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for this!

  3. #3
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks!!!! I was literally reversing CGUnit_C__UnitReaction and trying to find the CompareFactionHash when you posted this
    https://tanaris4.com

  4. #4
    meediamarkt05's Avatar Private
    Reputation
    1
    Join Date
    Oct 2009
    Posts
    7
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    which computer language is this?

  5. #5
    miceiken's Avatar Contributor Authenticator enabled
    Reputation
    209
    Join Date
    Dec 2007
    Posts
    401
    Thanks G/R
    7/9
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It's C#. (flr)

  6. #6
    miceiken's Avatar Contributor Authenticator enabled
    Reputation
    209
    Join Date
    Dec 2007
    Posts
    401
    Thanks G/R
    7/9
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So I've been trying to figure this out for a while: C# | public static WoWUnitRelation - Miceiken - gNQXfxpu - Pastebin.com -- btmpl is null (crashing on line 47)
    I've debugged and made sure both factions are okay:
    Code:
    var myFaction = new WoWFaction(Me.Faction);
    var tFaction = new WoWFaction(Me.Target.Faction);
    Log.Output("Relation M -> T: {0}", myFaction.RelationTo(tFaction));
    (My faction being 2 and target being 16 (I've tried several others too))
    I don't see what's wrong here.

    EDIT: Actually I noticed that sometimes atmpl is null, sometimes btmpl is null and sometimes both are null.
    Last edited by miceiken; 04-10-2010 at 12:06 PM.

Similar Threads

  1. Get target name (and other info) in Wow 3.3.5a
    By Breket in forum WoW Memory Editing
    Replies: 2
    Last Post: 11-11-2013, 12:52 AM
  2. Faction attacking each other
    By Iaccidentallytwink in forum WoW EMU Questions & Requests
    Replies: 4
    Last Post: 05-26-2009, 02:32 AM
  3. Walk into other faction citys without getting pvp flagged
    By Dullface in forum World of Warcraft Exploits
    Replies: 8
    Last Post: 09-12-2006, 10:48 AM
  4. Info on taking Ragnaros (And other MC general info)
    By Cush in forum World of Warcraft Guides
    Replies: 4
    Last Post: 05-28-2006, 03:53 AM
All times are GMT -5. The time now is 08:11 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search