View previous topic :: View next topic |
Author |
Message |
MaxRock
Joined: 24 Jan 2008 Posts: 196
|
Posted: Thu Apr 07, 2011 18:57 Post subject: FindObjectByTagOrdinal |
|
|
Can anybody figure out how the FindObjectByTagOrdinal function works?
I know it's the "internal" version of GetObjectByTag and it loops through the object LookupTable array but the way it does it gives me a headache.
My issue is with SetTag from nwnx_funcs. I'm able to change the tag in the lookuptable and the item, but afterwards GetObjectByTag cannot find it anymore. Yet when I override FindObjectByTagOrdinal with my own loop it finds the tab and object just fine.
Since I don't know all the members of CLookupTableObject, I suppose the secret is somewhere in those unknown members.
Here's what I have:
Code: |
struct CLookupTableObject_s {
char Tag[32];
char fill[4]; //FF FF FF FF
uint32_t unknown_1;
uint32_t unknown_2;
uint32_t tag_len1; //includes the terminator
uint32_t unknown_4;
uint32_t tag_len2; //not sure why there is a second length
uint32_t unknown_6;
uint32_t unknown_7;
CGenericObject *pObject;
uint32_t obj_oid;
};
|
Some insight would be greatly appreaciated |
|
Back to top |
|
|
motu99
Joined: 24 Sep 2007 Posts: 16
|
Posted: Thu Apr 07, 2011 21:22 Post subject: Re: FindObjectByTagOrdinal |
|
|
IMO CLookupTableObject is much simpler than what you posted:
Code: |
struct CLookupTableObject_s {
char sTag[64];
uint32_t NotKnownToMe; (could be: CGenericObject *pObject;)
nwn_objid_t oID;
};
|
By looking at the disassembly in IDA, I am quite sure that
Code: |
FindObjectByTagOrdinal(CExoString& TagToSearchFor, unsigned long nthOccurenceOfTag)
|
i) first does a
Code: |
StringLeft(TagToSearchFor, 64)
|
on the supplied tag
ii) then does (I believe) a binary search within the the sorted Array of CLookupTableObject entries, returning the address of the first CLookupTableObject entry that matches TagToSearchFor
iii) then adds nthOccurenceOfTag (times 72) to the address, checks if the respective entry is within the array-bounds and that the selected entry still refers to the correct tag
iv) if all conditions in iii) are met it returns oID of the selected entry, otherwise 0x7F000000. |
|
Back to top |
|
|
MaxRock
Joined: 24 Jan 2008 Posts: 196
|
Posted: Thu Apr 07, 2011 22:13 Post subject: |
|
|
Ah, thank you! I didn't take into account the array is sorted.
Of course I can probably get around the whole issue by simply calling RemoveObjectFromLookupTable and AddObjectToLookupTable with the new tag. |
|
Back to top |
|
|
MaxRock
Joined: 24 Jan 2008 Posts: 196
|
Posted: Thu Apr 07, 2011 22:27 Post subject: |
|
|
Yup, that did it. And my instance dungeons' area transitions are working |
|
Back to top |
|
|
|