Jump to content

PST: CRE


Displacer

Recommended Posts

I believe objects get five levels, yes, but I don't believe these fields have anything to do with that. Conveniently, the field does appear to be stored as a nested object reference instead of five separate values. E.g., LastAttackerOf(LastHelp(NearestEnemyOf(LastSeenBy(Myself)))) stored as Myself, LastSeenBy, NearestEnemyOf, LastHelp, LastAttackerOf.

 

On disk, these should never, ever be nonzero (not that anything bad would happen, but they just won't ever be saved with any value here unless you screw something up). There was something where the ChangeAIType() action or the related effect could set these values when passed nonsense parameters, and you can see that they appear to be Object.ids refs, but it's unknown what these are here for.

 

There shouldn't be a limit to how many matches a single object can get picked up for (if you go down the list of Object.ids, the engine should be able to match every single one that applies to a single target object). The engine does keep track of some "sticky" objects (LastTrigger, LastHitBy, etc.) for every single AI object, but these fields aren't even suitable for that, and those associations never ever ever get saved (they exist solely in memory).

Link to comment

Yea, I'm still building the creature struct as it appears in memory, so I'm only in the load and build struct part of the code. Any information such as this will help.

 

The real advantage will be after I get the complete memory struct figured out (0x5000 + bytes, I have about 0x1000 of it finished). I can then scan the entire code for references to this struct and know exactly how each and every byte is used. One interesting thing is with all the ids entries from 0x311 - 0x31F, there are 3 copies of these bytes loaded into the struct. I'm just guessing but one would be the original, the second would be the current, but I don't know what the third would be used for.

Link to comment

Quick note for anyone that wants to explore how the creature data is used now (even though the memory struct isn't finished), here's what to do:

 

First thing is how to get the pointer to the creature struct. The function to do this is sub_5A4864. This is what you need to search for in the disassembled exe (this is how the functions are named in IDA, yours may be different but it should use the address of the function which is 0x5A4864). Its called like this:

 

lea     eax, [ebp+var_38]
push    eax
mov     ecx, [ebp+var_30]
push    ecx
mov     ecx, [ebp+var_7C]
call    sub_5A4864

 

The important thing in the above code is var_38, which could be any var. After the call to sub_5A4864, var_38 (or whatever var its calling it with) will contain the pointer to the creature struct in memory. You can then use my creature memory struct listed here to see what is going on in that section of code. For instance the above code is used. Then you see this:

 

mov ecx [var_38]
mov eax [ecx+0x541]

 

eax now contains the creature's fire resistance (0x541 from my creature struct) so anything that acts on eax is acting on the fire resistance.

 

Again the struct isn't finished, but you can use it to explore what I have now. Remember I'll be updating the struct as I find new stuff.

Link to comment

0x253c

0x2568

 

These are the main effect lists on a .cre

 

Example of usage:

004BFFA8 6A FF push 0FFh

004BFFAA 8B 55 FC mov edx,dword ptr [ebp-4]

004BFFAD 52 push edx

004BFFAE 6A 3F push 3Fh ;;infravision opcode

004BFFB0 8B 4D 08 mov ecx,dword ptr [ebp+8]

004BFFB3 81 C1 3C 25 00 00 add ecx,253Ch

004BFFB9 E8 50 EA 00 00 call 004CEA0E ;;remove element from list

 

This would remove the infravision opcode.

 

 

0xd0e - no idea, used by soul exodus opcode (0xd1)

Link to comment

Huh, well maybe they had intended to save the data, and decided against it and forgot to remove the restoration code.

 

Edit: or maybe that function is used in-game as well as on load, to just clear the list as you're playing. I'll need to look into it a bit more...

Link to comment
Ok.

 

Speaking of effect opcode, there's another one, 0xD4 that's not listed in the IESDP. It seems to be handled differently than the others.

 

I think 0xd4 and above are handled equally :) --> assertion crash

 

Tell me if i'm mistaken, just test 0xf8 (arbitrary number over d4), it will have the same execution path as 0xd4 had.

Link to comment
Ok.

 

Speaking of effect opcode, there's another one, 0xD4 that's not listed in the IESDP. It seems to be handled differently than the others.

 

I think 0xd4 and above are handled equally :) --> assertion crash

 

Tell me if i'm mistaken, just test 0xf8 (arbitrary number over d4), it will have the same execution path as 0xd4 had.

 

Doesn't look like it, it does a compare and jumps to a assert if it is over 0xD4, 0xD4 has a valid listing in the jump table and its own section of code. It looks like it was a last minute addition because there is an assert in its code, but it's disabled. I'll see if I can plug this into a cre and run it just to be sure though. You can see the compare and jump table at 0x4A5C67, 0xD4 would be the last entry in the jump table.

 

EDIT: Just tried it in game and it does not cause a crash, but I can't tell what the effect is, nothing that shows anyway. Guess it'll need to be traced through...

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...