Code:
namespace ..
{
class FactionInterpreter
{
private const uint FACTION_START_INDEX = 0xA37330;
private const uint FACTION_POINTER = 0xA37340;
private const uint FACTION_TOTAL = 0xA3732C;
const uint HOSTILE_OFFSET_1 = 0x14;
const uint HOSTILE_OFFSET_2 = 0x0C;
const uint FRIENDLY_OFFSET_1 = 0x10;
const uint FRIENDLY_OFFSET_2 = 0x0C;
public static Reaction GetReaction(uint mobFaction)
{
//todo: fix
return FindReactionFromFactions(0, mobFaction);
}
public static Reaction GetReaction(uint localFaction, uint mobFaction)
{
if (localFaction < 1 || mobFaction < 1)
{
return Reaction.Missing;
}
return FindReactionFromFactions(localFaction, mobFaction);
}
public static Reaction GetReaction(WoWObject localObj, WoWObject mobObj)
{
if (((Unit)localObj).Faction < 1 || ((Unit)mobObj).Faction < 1)
{
return Reaction.Missing;
}
return FindReactionFromFactions(((Unit)localObj).Faction, ((Unit)mobObj).Faction);
}
private static Reaction FindReactionFromFactions(uint localFaction, uint mobFaction)
{
uint startIndex = (uint)ProcessIO.ReadInt(FACTION_START_INDEX);
uint totalFactions = (uint)ProcessIO.ReadInt(FACTION_TOTAL);
uint factionStartPoint = (uint)ProcessIO.ReadInt(FACTION_POINTER);
uint? localHash = null;
uint? mobHash = null;
Reaction reaction;
if (localFaction >= startIndex && localFaction < totalFactions)
{
if (mobFaction >= startIndex && mobFaction < totalFactions)
{
localHash = factionStartPoint + ((localFaction - startIndex) * 4);
mobHash = factionStartPoint + ((mobFaction - startIndex) * 4);
}
}
if (localHash != null && mobHash != null)
{
reaction = CompareFactionHash(localHash, mobHash);
}
else
{
reaction = Reaction.Unknown;
}
return reaction;
}
private static bool TestBits(uint lBitAddr, uint rBitAddr)
{
uint lBitParam = (uint)ProcessIO.ReadInt(lBitAddr);
uint rBitParam = (uint)ProcessIO.ReadInt(rBitAddr);
if ((lBitParam & rBitParam) != 0) return true;
return false;
}
private static bool HashCompare(int hashIndex, int hashCompare, byte[] localBitHash, int mobHashCheck)
{
const int HASH_INDEX_INC = 4;
hashCompare = BitConverter.ToInt32(localBitHash, hashIndex);
for (uint i = 0; i < 4; i++)
{
if (hashCompare == mobHashCheck)
return true;
hashIndex += HASH_INDEX_INC;
hashCompare = BitConverter.ToInt32(localBitHash, hashIndex);
if (hashCompare == 0)
break;
}
return false;
}
private static Reaction CompareFactionHash(uint? hash1, uint? hash2)
{
int localHashCheck = 0;
int mobHashCheck = 0;
int hashCompare = 0;
byte[] localBitHash = ProcessIO.ReadBytes((uint)hash1, 64);
byte[] mobBitHash = ProcessIO.ReadBytes((uint)hash2, 64);
localHashCheck = BitConverter.ToInt32(localBitHash, 0x04);
mobHashCheck = BitConverter.ToInt32(mobBitHash, 0x04);
if (TestBits((uint)BitConverter.ToInt32(localBitHash, 0) + HOSTILE_OFFSET_1,
(uint)BitConverter.ToInt32(mobBitHash, 0) + HOSTILE_OFFSET_2))
return Reaction.Hostile;
if (HashCompare(0x18, hashCompare, localBitHash, mobHashCheck))
return Reaction.Hostile;
if (TestBits((uint)BitConverter.ToInt32(localBitHash, 0) + FRIENDLY_OFFSET_1,
(uint)BitConverter.ToInt32(mobBitHash, 0) + FRIENDLY_OFFSET_2))
return Reaction.Friendly;
if (HashCompare(0x28, hashCompare, localBitHash, mobHashCheck))
return Reaction.Friendly;
if (TestBits((uint)BitConverter.ToInt32(localBitHash, 0) + FRIENDLY_OFFSET_1,
(uint)BitConverter.ToInt32(mobBitHash, 0) + FRIENDLY_OFFSET_2))
return Reaction.Friendly;
if (HashCompare(0x28, hashCompare, localBitHash, mobHashCheck))
return Reaction.Friendly;
return Reaction.Neutral;
}
}
public enum Reaction
{
Unknown = -1,
Hostile = 1,
Neutral = 3,
Friendly = 4,
Missing = -2
}
}
That's what I'm currently using.