After in-depth analysis of the CON format, I have these modifications to make:
- BYTE[0x202] unused
- WORD unknown // is either CCCC, 0000, 2C2C or 4D00
-
- DWORD block_offset // always 524 / 0x20C
- DWORD lua_offset
-
- DWORD init_count // always 1
- DWORD init_offset // always 16 / 0x10
- DWORD dialog_count
- DWORD dialog_offset // always 100 / 0x64
-
- // NPC INIT BLOCK
- DWORD init_lookuptable // always 4
- DWORD entry_id // always 0
- DWORD Command // always 3
- DWORD Data // always 0
- BYTE[0x20] condition_function // always "TA_checkRepeat"
- BYTE[0x20] reward_function // always a nullstring
- DWORD str_id // referenced LTB entry always says "Root", though the actual number might vary
-
- // DIALOG BLOCKS
- DWORD[dialog_count] dialog_lookuptable // contains offsets to each dialog
- : FOREACH (dialog_count)
- DWORD block_size
- DWORD entry_count
- :XOR( ( (BYTE)entry_count % 2 == 0 ) ? (BYTE)block_size : (BYTE)entry_count )
- DWORD[entry_count] entry_lookuptable // contains offsets to each dialog entry
- : FOREACH (entry_count)
- DWORD entry_id
- DWORD Command
- DWORD Data
- BYTE[0x20] condition_function
- BYTE[0x20] reward_function
- DWORD str_id
- : ENDFOR
- : ENDXOR
- : ENDFOR
-
- // LUA CODE BLOCK
- DWORD code_len
- :XOR( (code_len % 2) ? code_len & 0xFF: (lua_offset+4+code_len) & 0xFF )
- BYTE[code_len] lua_data
- : ENDXOR
As you can see, the init block always has only one entry, whose contents are constant. I also corrected block_count to dialog_count, and updated the XOR key for the Lua code block, as it was slightly off in Brett's original format. All assertions have been checked with a script and show 100% consistency in an Evo client. Hope this helps.