Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checking the hostility of enemies #10

Closed
ghost opened this issue Jan 9, 2017 · 10 comments
Closed

Checking the hostility of enemies #10

ghost opened this issue Jan 9, 2017 · 10 comments

Comments

@ghost
Copy link

ghost commented Jan 9, 2017

Mobs throughout the game have different icons to their nameplates indicating whether they are hostile and attack on sight or whether they are neutral until attacked. These icons can be seen here:

Hostility Icons

So far I was only able to determine whether my target is a NPC / PC / Monster / EObj (market boards, placards, etc.) but not its hostility. I guess that this is a property that hasn't been scanned and made available in the code yet. It would actually suffice to know whether the target is passive or aggresive - the rank doesn't actually matter. Do you think you might add this as well?

And slightly offtopic: since I finally got the library to work for my private project I guess I'll stumble upon few more things every now and then I'd like to see added like the check for the hostility. Do you want me to continue creating issues for them?

@vekien
Copy link
Contributor

vekien commented Jan 9, 2017

Hello,

I don't think requesting a bunch of parameters will help, it might feel overwhelming. You could do one issue per actor type: NPC, Enemy, Player and then list of missing stuff or broken stuff.

If you know how to use CE it will help a lot trying to find the positions. Otherwise it's a lot of work and usually it depends on the needs (eg I have no need for Hostility, so I'm unlikely to go hunting for it XD)

@ghost
Copy link
Author

ghost commented Jan 9, 2017

I guess I'll open categorized issues once I find out that I really want something added to it.

Actually I tried using CE a year ago which was absurdly difficult in the first place. 😞 Especially when searching for something that is encoded as a number instead of a raw string.

But I'll give it another try after looking through the library code to see how the Json signature data is actually used to find the structures and see whether I can find something salavagable or useful at all.

@EmperorArthur Since you had some offsets on the app repo posted already, I took the liberty of mentioning you if you can share something as well 😄

@vekien
Copy link
Contributor

vekien commented Jan 9, 2017

Finding numbers you know are super easy (map ids, health, etc), finding states are difficult, it's 1 or 0. You can load the memory from a signature and then work up as an offset would be signature +X, think of it as a class and the variables are +X lines down, then you just watch the values go from 0 to 1, common values are grouped usually.

@ghost
Copy link
Author

ghost commented Jan 10, 2017

@viion Do you mind having a look at this line. I just noticed this randomly but I am struggling to find the right memory address to try it out live to find out what is saved there.

@EmperorArthur
Copy link

Here's a Cheat Engine lua script to help you along in your debugging. It dumps all the data about an actor to a binary file. So you can easily compare it to other actors. You could go through the world using this script and dump all the creatures, while keeping an excell sheet of if they have the mark or not.

You'll need to edit it by hand, and it takes raw memory values. The other thing to be aware of is, I'm not sure the exact length of an ActorEntity, so I guessed.

actorDump.txt

@ghost
Copy link
Author

ghost commented Jan 11, 2017

@EmperorArthur Tha API over at http://xivapp.com/api/structures/TargetInfo?patchVersion=latest&platform=x86 returns that the TargetInfo struct is most likely about 9200 bytes long. The source code mentiones here that it was 0x3F40 = 16192 bytes long.

I will try to experiment with your script later this evening once I come back home. This will definitely help me get started better since there is literally no other forums or source where people are sharing information on that topic.

EDIT Don't mind the first number (9200) since I mistook TargetInfo with ActorEntity.

@ghost
Copy link
Author

ghost commented Jan 11, 2017

@EmperorArthur Just another update - I guess you used the lua file to find 64bit offsets? Since there are no 64bit addresses shared thus far in the API of the app I guess I'd have to find the base address for 32bit target data since your entered 0x468D2340 is apparently a 64bit address, isn't it?

@EmperorArthur
Copy link

EmperorArthur commented Jan 11, 2017

Yeah, that script explicitly references ffxiv_dx11.exe

0x468D2340 is actually something I should have removed. It was the start of the my ActorEntity data.

What I provided is a crude base for dumping memory regions via CheatEngine. Basically, you search for an entity's name in CheatEngine and subtract 48 from the resulting memory address to find the start of the ActorEntity struct. Then, you copy that address into actorDump.

I could probably automate some of this, but I whipped this up for you pretty quickly. It's my first LUA program ever, and I didn't want to get too complicated too quickly.

@ghost
Copy link
Author

ghost commented Jan 12, 2017

I have some news - sorry if you happen to be flooded with mails due to my posts all the time. 😃

First I have added quality of life additions to the script of @EmperorArthur which you can see in my gist. Basically if you add the pointer described by [[[X + 7] + 6C]] where X is the addresse of the TARGET signature and name it ActorEntityBase you can export a dump of the structure with only two clicks and you can easily switch targets and don't have to update the address in the code manually. It even suggests the filename based on your selected target. Expect unexpected behaviour without target though!

To the second news. I have dumped about twenty structures and sorted them based on whether the targets were marked passive or aggressive. I wrote a C# script that compares all passive dumps and stores all offsets where the passive dumps had the very same byte and that did the same with the aggressive dumps. Afterwards the script was searching for the same offsets in both resulting collections that had a different value. - My idea was that all passive enemies had a number X at a particular offset where all aggressive enemies had a number Y at the same offset.

To my surprise I had 635 results from which I could quickly deduce with trial and error that the offset 0x1372 looks the most appealing to me. This was correct for various difficulty level 1 enemies and even bosses I had tested. At the moment I am running around to find some ranked enemies to see whether it matches their stance as well.

The value was 0 for passive or evading enemies while it was usually 1 for aggresive enemies. Sometimes when they were in combat with someone else and not the player it was a different non-zero number. Something similiar actually happens with Chocobos which are swapping their behavior every now and then.


EDIT: I noticed something very odd about the game and how it handles monsters and NPCs. A short version of my code that returns whether something is aggressive, neutral (passive monster) or something else (NPCs, PCs, interactibles, ...) looks something like this:

public Color ReactionColor
    =>
        (_targetEntity?.IsAggressive ?? false)
            ? Color.FromRgb(222, 95, 95)
            : (_targetEntity?.TypeID ?? 0) == (Entity.Type?["Monster"] ?? 0)
                ? Color.FromRgb(218, 197, 92)
                : Color.FromRgb(75, 175, 76);

This worked well until I noticed that there are some NPC which can fight as well and therefore their Type is Monster. They are distinguished by a green/yellow healthbar when being targeted. Thus I had to introduce a property IsPacifist which was luckily already indicated in the source code. I guess it will be more useful to change the Type assignment line to take the value into consideration and to assign NPC instead of Monster in those cases. Anyways for the time being the check looks more or less like this:

public Color ReactionColor
    =>
        (_targetEntity?.IsAggressive ?? false)
            ? Color.FromRgb(222, 95, 95)
            : (_targetEntity?.TypeID ?? 0) == (Entity.Type?["Monster"] ?? 0) &&
              (!_targetEntity?.IsPacifist ?? false)
                ? Color.FromRgb(218, 197, 92)
                : Color.FromRgb(75, 175, 76);

@ghost
Copy link
Author

ghost commented Jan 21, 2017

So after deducing the data for my collection in issue #12 I noticed how this behaves. Please refer to the section Action Bits for more information even though the 32 bit offset is different and I haven't verified whther it is still my proposed 0x1372.

I'll be closing this issue for the time being.

@ghost ghost closed this as completed Jan 21, 2017
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants