-
Legendary
Before I lure anyone too far down the rabbit hole with MemoryModel, let me just explain what I'm trying to do with ApplicationModel.
The MemoryModel project is good at describing the structure of types (both 32-bit and 64-bit) and in some capacity how to use them (e.g. enumeration of collections). It's not very good at explaining how the data can be used, and how it fits together. That's what I want the ApplicationModel to do. That and taking care of the Read/Acquire/Collect part in a Read->React program loop which is the most sane way to implement a program based on Enigma.D3. While property reads on a MemoryObject being live is cool, its usefulness in a real application is limited, not very efficient, and promotes race conditions. The ApplicationModel will provide highly efficient caches (as in fast to update) for commonly used objects and track what objects are added or removed from containers.
But back to the first goal of ApplicationModel, explaining how to use the data and how it fits together. I realized I'll need to add an abstraction layer, with types not related to their memory representation. E.g. does the data for a Player really be spread out in a PlayerData, Actor and an ACD structure, and then some "attributes" read in a special way? It's not exactly intuitive how and where to find the data. So that's what I'm working on at the moment, figuring out what types are needed, methods, properties and how to connect everything in a more "what you see on the screen" structured API.
-
Post Thanks / Like - 2 Thanks
d2k2,
johnbl (2 members gave Thanks to enigma32 for this useful post)
-
Active Member
Originally Posted by
enigma32
Before I lure anyone too far down the rabbit hole with MemoryModel, let me just explain what I'm trying to do with ApplicationModel.
The MemoryModel project is good at describing the structure of types (both 32-bit and 64-bit) and in some capacity how to use them (e.g. enumeration of collections). It's not very good at explaining how the data can be used, and how it fits together. That's what I want the ApplicationModel to do. That and taking care of the Read/Acquire/Collect part in a Read->React program loop which is the most sane way to implement a program based on Enigma.D3. While property reads on a MemoryObject being live is cool, its usefulness in a real application is limited, not very efficient, and promotes race conditions. The ApplicationModel will provide highly efficient caches (as in fast to update) for commonly used objects and track what objects are added or removed from containers.
But back to the first goal of ApplicationModel, explaining how to use the data and how it fits together. I realized I'll need to add an abstraction layer, with types not related to their memory representation. E.g. does the data for a Player really be spread out in a PlayerData, Actor and an ACD structure, and then some "attributes" read in a special way? It's not exactly intuitive how and where to find the data. So that's what I'm working on at the moment, figuring out what types are needed, methods, properties and how to connect everything in a more "what you see on the screen" structured API.
Good to see you keep working on your Framework. I really like the idea to add an aditional abstraction layer which allows you the Framework to use in an intuitive way. I dont really know how to continue with the d3helper project. D3.Memory will not be updated anymore, which is understandable, due to its complex structure. D3.MemoryModel doesnt have the functions i need. Probably i give up first and wait what ApplicationModel will bring in future. But if it helps i will continue trying to port from D3.Memory to D3.MemoryModel just to find out what is missing in D3.MemoryModel.
-
Active Member
How can i read the Location as String (for example "New Tristram") from my partymembers?
-
Legendary
Originally Posted by
d2k2
How can i read the Location as String (for example "New Tristram") from my partymembers?
I created it as an issue (question/enhancement) Reading Location as string for PartyMembers * Issue #13 * Enigma32/Enigma.D3 * GitHub
-
Post Thanks / Like - 1 Thanks
d2k2 (1 members gave Thanks to enigma32 for this useful post)
-
Contributor
I can't use the C language. Can I use ApplicationModel. in other languages?
-
Active Member
Hi Enigma,
i have another Question. I am still strying to port my project to MemoryModel.
What does LocalActorCommonData mean. is this the container of the the player itself?
In D3.Memory you can get it like this.
var localACD = ActorCommonData.Local;
How i get the "local ACD" with the MemoryModel?
--
what is ActorCommonData.x08C_ActorId in MemoryModel.Core.ACD ?
--
What about the UXHelper?
i guess i can not Use this one with MemoryModel?
UXHelper.GetControl<UXIcon>(...)
Last edited by d2k2; 07-10-2017 at 09:24 AM.
-
Legendary
Originally Posted by
SeaDragon
I can't use the C language. Can I use ApplicationModel. in other languages?
What can you use then? Asking for this Language binding - Wikipedia ?
Originally Posted by
d2k2
Hi Enigma,
i have another Question. I am still strying to port my project to MemoryModel.
What does LocalActorCommonData mean. is this the container of the the player itself?
In D3.Memory you can get it like this.
How i get the "local ACD" with the MemoryModel?
--
what is ActorCommonData.x08C_ActorId in MemoryModel.Core.ACD ?
--
What about the UXHelper?
i guess i can not Use this one with MemoryModel?
From the Local (as in who client controls) PlayerData, there is a reference to an Actor instance and ACD (ActorCommonData) instance.
Each game object has an ACD afaik, and each game object you can see in the 3D World has an Actor as well (some might have an invisible Actor).
The Local ACD is the one the Local PlayerData links to.
The Local Actor is the one the Local PlayerData links to.
Code:
var localPlayerData = ctx.DataSegment.ObjectManager.PlayerDataManager[ctx.DataSegment.ObjectManager.Player.LocalPlayerIndex];
var localACD = ctx.DataSegment.ObjectManager.ACDManager.ActorCommonData[(short)localPlayerData.ACDID];
var localActor = ctx.DataSegment.ObjectManager.Actors[(short)localPlayerData.ActorID];
The ACD also links to its Actor (if on exists) and the Actor links to its ACD.
So far, I've not found a use case where Actor provides something the ACD doesn't already have. That's why I haven't added ActorID to ACD.
----
UI code in MemoryModel is still very limited. Without the Map containing all controls, there is pretty much nothing you can do yet.
-
Post Thanks / Like - 1 Thanks
d2k2 (1 members gave Thanks to enigma32 for this useful post)
-
Member
hi i need gbid of necromancer class cant find it
-
Active Member
Originally Posted by
enigma32
What can you use then? Asking for this
Language binding - Wikipedia ?
From the Local (as in who client controls) PlayerData, there is a reference to an Actor instance and ACD (ActorCommonData) instance.
Each game object has an ACD afaik, and each game object you can see in the 3D World has an Actor as well (some might have an invisible Actor).
The Local ACD is the one the Local PlayerData links to.
The Local Actor is the one the Local PlayerData links to.
Code:
var localPlayerData = ctx.DataSegment.ObjectManager.PlayerDataManager[ctx.DataSegment.ObjectManager.Player.LocalPlayerIndex];
var localACD = ctx.DataSegment.ObjectManager.ACDManager.ActorCommonData[(short)localPlayerData.ACDID];
var localActor = ctx.DataSegment.ObjectManager.Actors[(short)localPlayerData.ActorID];
The ACD also links to its Actor (if on exists) and the Actor links to its ACD.
So far, I've not found a use case where Actor provides something the ACD doesn't already have. That's why I haven't added ActorID to ACD.
----
UI code in MemoryModel is still very limited. Without the Map containing all controls, there is pretty much nothing you can do yet.
Thx a lot. That will help me. The reading of UXControl items is important to port my project to MemoryModel. I would need following functions:
Code:
UXControl uxcontrol = UXHelper.GetControl<UXControl>("name.of.control");
bool isControlVisible = uxcontrol.isVisible();
UIRect rect = uxcontrol.UIRect.TranslateToClientRect(ClientWidth, ClientHeight);
string text = uxcontrol.getText(); //from UXLabel
-
Legendary
Originally Posted by
d2k2
Thx a lot. That will help me. The reading of UXControl items is important to port my project to MemoryModel. I would need following functions:
Code:
UXControl uxcontrol = UXHelper.GetControl<UXControl>("name.of.control");
bool isControlVisible = uxcontrol.isVisible();
UIRect rect = uxcontrol.UIRect.TranslateToClientRect(ClientWidth, ClientHeight);
string text = uxcontrol.getText(); //from UXLabel
You can now do the first part.
Code:
var map = ctx.DataSegment.ObjectManager.UIManager.PtrControlsMap.Dereference();
var control = map["name.of.control"]
-
Active Member
How can i access for example the items on Ground (Loot) over the MemoryModel or ApplicationModel?
see Enigma.D3/Game.cs at master * Enigma32/Enigma.D3 * GitHub
is it currently only possible over using ApplicationSnapshot? Or is there a direct way to read Items over the MemoryContext?
Can you give examples?
-
Legendary
Originally Posted by
d2k2
How can i access for example the items on Ground (Loot) over the MemoryModel or ApplicationModel?
see
Enigma.D3/Game.cs at master * Enigma32/Enigma.D3 * GitHub
is it currently only possible over using ApplicationSnapshot? Or is there a direct way to read Items over the MemoryContext?
Can you give examples?
ApplicationModel
Code:
var ctx = MemoryContext.FromProcess();
var snapshot = new ApplicationSnapshot(ctx);
snapshot.Update();
var loot = snapshot.Game.Loot;
MemoryModel
Code:
var ctx = MemoryContext.FromProcess();
var acds = ctx.DataSegment.ObjectManager.ACDManager.ActorCommonData.Where(x => x.ID != -1);
var items = acds.Where(x => x.ActorType == ActorType.Item);
var loot = items.Where(x => (int)x.ItemLocation == -1);
-
Post Thanks / Like - 2 Thanks
d2k2,
levelmax (2 members gave Thanks to enigma32 for this useful post)
-
Active Member
since latest commit i can not use the AttributeHelper Methods any more.
d3helper used the AttributeId to read the AttributeValue. How i can do it now?
Code:
public static double GetAttributeValue(this Enigma.D3.MemoryModel.Core.ACD acd, Enigma.D3.Enums.AttributeId attribId, int modifier = -1)
{
return Enigma.D3.ApplicationModel.AttributeHelper.GetAttributeValue(acd, attribId, modifier);
}
public static IEnumerable<KeyValuePair<int, Enigma.D3.AttributeModel.AttributeValue>> EnumerateAttributes(this Enigma.D3.MemoryModel.Core.ACD acd)
{
return Enigma.D3.ApplicationModel.AttributeHelper.EnumerateAttributes(acd);
}
I need a function to read the AttributeValue (as double) from ACD by AttributeId.
And i need a function to enumerate all attributes of an ACD (see example here D3Helper.Public/T_ACD.cs at MemoryModel * d2k2-git/D3Helper.Public * GitHub)
Last edited by d2k2; 07-12-2017 at 07:07 AM.
-
Legendary
I'm confused. You're talking about a class from Memory project.
You've been converting to MemoryModel project.
You paste (pseudo?) code with namespace ApplicationModel.
If there is a problem in Memory project I need more details. It should still work as before.
I will move AttributeReader to MemoryModel so that you can do something like this (with modifications)
Code:
var descriptor = ctx.DataSegment.AttributeDescriptors[(int)AttributeId.Strength]; // info on data type, default value
AttributeValue value;
AttributeReader.Instance.TryGetAttributeValue(acd.FastAttribGroupID, AttributeId.Strength, -1, out value); // use default value if return = false
In ApplicationModel you can do
Code:
var snapshot = new ApplicationSnapshot(ctx);
snapshot.Update();
var str = (double)snapshot.Game.Player.Read(Attributes.Strength); // cast to double since you wanted that
I'll add one that returns all, and I'll add a "universal" one that returns double and takes Id+Modifier as arguments.
I'm going to need a better name for the method.. ReadAttribute, GetAttribute, GetAttributeValue, GetValue? Any winner?
-
Legendary
Originally Posted by
enigma32
I'll add one that returns all, and I'll add a "universal" one that returns double and takes Id+Modifier as arguments.
I'm going to need a better name for the method.. ReadAttribute, GetAttribute, GetAttributeValue, GetValue? Any winner?
Now you have some more options
Code:
var snapshot = new ApplicationSnapshot(ctx);snapshot.Update();
var str = (double)snapshot.Game.Player.GetAttributeValue(Attributes.Strength); // cast to double since you wanted that
var str2 = snapshot.Game.Player.GetAttributeValue(AttributeId.Strength);
var attributes = snapshot.Game.Player.GetAttributes();