public D3ActorCommonData(MemoryReader memReader, uint ptr, byte[] data) { this.Pointer = ptr; this.AcdID = BitConverter.ToInt32(data, 0); this.ModelName = ProcessUtils.AsciiBytesToString(data, 4, 128); this.SnoID = BitConverter.ToInt32(data, 0x90); this.GBType = BitConverter.ToInt32(data, 0xB0); this.GBID = BitConverter.ToUInt32(data, 0xB4); this.Direction = new Vector2f(data, 0xC8); this.Pos1 = new Vector3f(data, 0xD0); this.Pos2 = new Vector3f(data, 0xE0); this.WorldID = BitConverter.ToUInt32(data, 0x108); this.SceneID = BitConverter.ToUInt32(data, 0x10C); this.OwnerID = BitConverter.ToInt32(data, 0x110); this.Placement = BitConverter.ToInt32(data, 0x114); this.InventoryX = BitConverter.ToInt32(data, 0x118); this.InventoryY = BitConverter.ToInt32(data, 0x11C); this.AttributesID1 = BitConverter.ToUInt32(data, 0x120); this.AttributesID2 = BitConverter.ToUInt32(data, 0x124); uint attributesPtr1 = memReader.IDToPtr(memReader.pAttributes, Offsets.SIZEOF_ATTRIBUTE, AttributesID1); //uint attributesPtr2 = memReader.IDToPtr(memReader.pAttributes, Offsets.SIZEOF_ATTRIBUTE, AttributesID2); Attributes = memReader.GetAttributes(attributesPtr1); // Merge in any additional attributes (haven't seen any yet in practice) //D3AttributeMap attributes2 = memReader.GetAttributes(attributesPtr2); //foreach (var kvp in attributes2) // Attributes[kvp.Key] = kvp.Value; }
/// <summary> /// Fetch all attributes associated with a given actor /// </summary> /// <param name="attributesPtr">Pointer to an attributes container</param> public D3AttributeMap GetAttributes(uint attributesPtr) { uint v0 = ReadUInt(attributesPtr + 16); uint p0 = ReadUInt(v0 + 8); int capacity = ReadInt(v0 + Offsets.ATTRIB_SLOTCOUNT_OFFSET); int count = ReadInt(v0 + Offsets.ATTRIB_COUNT_OFFSET); D3AttributeMap attributes = new D3AttributeMap(count); uint basePtr; uint ptr; byte[] attribData; uint attribID; #region TeamID-only Optimization if (count == 1) { ptr = ReadUInt(p0 + 0x29C); if (ptr != 0) { attribData = ReadBytes(ptr + 4, 8); attribID = BitConverter.ToUInt32(attribData, 0); if ((attribID & 0xFFF) == D3Attribute.TeamID.ID) { attributes[D3Attribute.TeamID] = new D3AttributeValue(BitConverter.ToInt32(attribData, 4)); return(attributes); } } } #endregion TeamID-only Optimization byte[] data = ReadBytes(p0, 4 * capacity); int curCount = 0; unsafe { fixed(byte *bytePtr = data) { uint *ptrs = (uint *)bytePtr; for (int i = 0; i < capacity; i++) { basePtr = *(ptrs + i); if (basePtr != 0) { ptr = basePtr; while (ptr != 0) { attribData = ReadBytes(ptr, 12); ptr = BitConverter.ToUInt32(attribData, 0); attribID = BitConverter.ToUInt32(attribData, 4); if (attribID != Offsets.INVALID) { D3Attribute attrib = D3Attribute.AttributesMap[attribID & 0xFFF]; attributes[attribID] = (attrib.IsInteger) ? new D3AttributeValue(BitConverter.ToInt32(attribData, 8)) : new D3AttributeValue(BitConverter.ToSingle(attribData, 8)); if (++curCount == count) { return(attributes); } } } } } } } return(attributes); }