-
Active Member
Originally Posted by
betenner
Hi enigma, any update for 2.3.0.33414?
Meanwhile I uploaded updated Enigma.D3 to patch 2.3 according to previous posts here:
https://www.dropbox.com/s/fk93jqgwi0...3_2.3.zip?dl=0
Everything seems to work except for obtaining BloodShards count :P
-
Legendary
Originally Posted by
CrEEzz
I get second value

Is this some kind of a bug in Enigma.D3?
For a "FastAttribGroup" there are 2 maps with attributes. I'm not quite certain what the difference is (but I believe it has something to do with client-calculated attributes). The EnumerateAttributes call yields the results of both those maps. Reading a specific attribute will use either one of the maps based on a flag and if the first one is null or not. It could be that they changed how this works or that I got it wrong from start.
Oh, and I updated SVN yesterday, just too lazy to write it. Like I wrote previously though, I'm currently refactoring a few things, so don't get too attached to the structure or APIs as they will keep changing.
Last edited by enigma32; 09-14-2015 at 01:28 PM.
-
Post Thanks / Like - 1 Thanks
HI5 (1 members gave Thanks to enigma32 for this useful post)
-
Active Member
Originally Posted by
enigma32
It could be that they changed how this works or that I got it wrong from start.
It was happening at least from patch 2.0.
-
Active Member
Originally Posted by
CrEEzz
It was happening at least from patch 2.0.
I did some testing and took any legendary weapon, then I changed attributes enumeration metod to this (removing reading one of maps) and dumped all attributes:
Code:
public static IEnumerable<Map<int, AttributeValue>.Entry> EnumerateAttributes(this ActorCommonData acd)
{
var groupId = acd.x120_FastAttribGroupId;
var group = FastAttrib.Instance.x54_Groups[(short)groupId];
if (group != null)
{
//var smallMap = group.x00C_PtrMap;
//if ((group.x004_Flags & 4) != 0 && smallMap != null)
//{
// foreach (var bucket in smallMap.x10_Buckets)
// {
// var immutableBucket = bucket.Dereference();
// while (immutableBucket != null)
// {
// immutableBucket.TakeSnapshot();
// yield return immutableBucket;
// immutableBucket = immutableBucket.x00_Next;
// }
// }
//}
var map = group.x010_Map;
if (map != null)
{
foreach (var bucket in map.x10_Buckets)
{
var immutableBucket = bucket.Dereference();
while (immutableBucket != null)
{
immutableBucket.TakeSnapshot();
yield return immutableBucket;
immutableBucket = immutableBucket.x00_Next;
}
}
}
}
yield break;
}
as a result i still got duplicated attributes values (smallMap was null) O_o. Just to verify I commented out dumping from second map and then I got nothing. So all duplicated attributes reside in one map. However when you read attribute value using AttributeHelper.TryGetAttributeValue you read from specific bucket (based on hash value), unfortunately this bucket contains wrong value. In case of other attribute like PowerDamagePercentBonus there is no value at all. So I dumped keys as well and there is what i got:
Code:
525 25101 0 0x00000 Damage_Weapon_Min_Total_MainHand 1420 <- this is proper value
525 525 0 0x00000 Damage_Weapon_Min_Total_MainHand 353
what is interesting is that 25101 is 0x620D while 525 is 0x020D.
Edit: In case of "missing" power bonus this looks like this:
Code:
1174 0x12113496 18 0x00012 Power_Damage_Percent_Bonus 0,13
key is 0x12113496.
Last edited by CrEEzz; 09-15-2015 at 12:40 PM.
-
Post Thanks / Like - 1 Thanks
HI5 (1 members gave Thanks to CrEEzz for this useful post)
-
Legendary
Ah, think I misunderstood your first post. The "ID" is 2 parts, the attribute id and a "modifier", as such:
Code:
public struct AttributeKey {
public int Value;
public AttributeId Id { get { return (AttributeId)(Value & 0xFFF); } set { Value = (int)((Value & 0xFFFFF000) + (int)value); } }
public int Modifier { get { return Value >> 12; } set { Value = (Value & 0x00000FFF) + (value << 12); } }
public override string ToString()
{
return Id + " mod: " + Modifier;
}
public override int GetHashCode()
{
return unchecked((int)(Value ^ (Value >> 12)));
}
}
The modifier value can something like a PowerSNO or a value representing a damage type. So for you min-damage, the one with 0x620D is actually the same attribute as 0x20D, but with a different modifier, 6 as in Holy I believe. The combination is the key used in the hash map. I hope this answers your question
-
Active Member
You are absolutely right. There was shift error in dump function (24 instead of 12) here is correct version
Code:
var attribDescriptors = Engine.Current.AttributeDescriptors;
var q = acd.EnumerateAttributes().Select(a => new { Id = a.x04_Key & 0xFFF, Mod = a.x04_Key >> 12, Value = a.x08_Value, Descriptor = attribDescriptors.Single(d => d.x00_Id == (a.x04_Key & 0xFFF)) }).Where(a => a.Descriptor.x10_DataType == 1 ? (a.Value.Int32 == filter_value_int) : (Math.Abs(a.Value.Single - filter_value_float) < float_tolerance));
string str = string.Join(Environment.NewLine, q.Select(a => string.Join("\t",
a.Id,
a.Mod == 0xFFFFF ? "-1" : a.Mod.ToString(),
"0x" + a.Mod.ToString("X8").Substring(3),
a.Descriptor.x1C_Name,
a.Descriptor.x10_DataType == 1 ? a.Value.Int32 : a.Value.Single)));
Last edited by CrEEzz; 10-01-2015 at 09:33 AM.
-
Member
Looks like quite an extensive project, great work!
Without looking in depth at your code yet, would it help with creating a program that can read buffs beyond the 8 icon limit Blizzard has put on them during gameplay?
Seems like a nice small program to work on to get to know your code.
-
Legendary
Originally Posted by
chillzilla
Looks like quite an extensive project, great work!
Without looking in depth at your code yet, would it help with creating a program that can read buffs beyond the 8 icon limit Blizzard has put on them during gameplay?
Seems like a nice small program to work on to get to know your code.
Thanks! And to answer your question; yes it would.
-
Legendary
-
Master Sergeant
Anyone know how item pickup is handled and what functions it uses?
-
Active Member
I've got a question. I'm trying to keep track of encountered elites thus I need somehow distinguish them so I tried using ActorCommonData.Id but when i move away from given elite and come back it changes (probably cause its visual element is respawned). Same thing is with ActorCommonData.ActorId and ActorCommonData.AnnId (whatever it is). So I tried getting actual actor id using Enigma.D3.Actor.Container[(short)acd.x08C_ActorId].x000_Id but it changes as well :/ Is there any kind of ID that remaines unchanged? Or is there a better way to check is two ACD represents the same actor?
-
Legendary
Originally Posted by
CrEEzz
I've got a question. I'm trying to keep track of encountered elites thus I need somehow distinguish them so I tried using ActorCommonData.Id but when i move away from given elite and come back it changes (probably cause its visual element is respawned). Same thing is with ActorCommonData.ActorId and ActorCommonData.AnnId (whatever it is). So I tried getting actual actor id using Enigma.D3.Actor.Container[(short)acd.x08C_ActorId].x000_Id but it changes as well :/ Is there any kind of ID that remaines unchanged? Or is there a better way to check is two ACD represents the same actor?
On ACD you have something called ANN ID. This is the ID server uses and stays the same even if an actor is "rediscovered".
-
Active Member
Originally Posted by
enigma32
On ACD you have something called ANN ID. This is the ID server uses and stays the same even if an actor is "rediscovered".
Hey. I double checked AnnId and it actually remains the same when You move away from actor, but when You move away too far like (2 screens) and move back to it AnnId is different :/ I checked it on elite monsters and was dumping their ACD x088_AnnId.
Last edited by CrEEzz; 09-30-2015 at 02:11 AM.
-
Legendary
That's a shame :C Maybe the lower 16-bits remains the same though if you're lucky.
-
Active Member
Originally Posted by
bastiflew
Could you post updated list of powers?