J
JWP
Guest
Hehe, looks nice! Now you can deal all of the damage in the world 
Update to the Monster structure:
Note, the offsets listed are for the first struct in the array, they are usually referenced with address + (208*monster_id) - the unknown padding is mostly in sizes of 8 so it's easy to replace it when I find out what some values are.
Code: [Select]
I'd imagine that the struct above is referenced all over the battle code, so I'm trying to decipher as much of it as I can so that understanding what other battle functions do will be a lot easier.
I've found that generally the ID of the monsters is 3, 4 and 5 (no idea what happens with 8 monster battles yet), so the first monster you fight will have its parameters at 0x1D27D80 rather than 0x1D27B10. It looks like it stores most of the parameters for the monsters that you're fighting, all I need now is to finish decoding it
.
There's a bunch of interesting things I didn't know about the AI code, you have to be careful with some opcodes because you can override bits of memory that you shouldn't - which could lead to some random crashes.
opcode 0x0E is used to set a variable as mentioned by random_npc, there's a special case where the immediate is 0xCB which causes the variable to be assigned the value of last attacker instead of the immediate - it appears that 0xCB is treated as a special case in quite a few opcodes.
After further investigation, it seems there are 2 sets of variables DC-E3 (which are stored in the struct above) and 60-67 (which are stored separately - I assume these are global for the battle).
It looks like bad things would happen if you used opcode 0x0E to write outside the range DC-E3 but there's no constraint checking!
The 71 byte structure I mentioned before contains a series of multipliers for stats (str, mag etc.) which default to 10 (1x multiplier) among some other things that I haven't identified.
Notes on opcode 0x04 - Targeting:
the final form of this in the function is a bit mask to represent which enemies are targeted, looking at the code I can see the following:
0xC8: 0000 0000 0000 1000 //self (it just shifts 1 left by the monster id - this represents and id of 3)
0xC9: //random enemy - probably one of the first 3 bits is set
0xCA: //??
0xCB: //last attacker - does 1 << the value in it's struct (see struct above)
0xCC: 1000 0000 0000 0111 //all enemies
0xCD: 1000 0000 1111 1000 //all allies
0xCE: 1000 0000 1111 1111 //everyone?
0xCF: //random ally
0xD0: 1010 0000 0000 0111 //something to do with enemies
0xD1: //?? does 1 << the value in 0x1D28DFB
0xDC-0xE3: //does 1 << the value in the corresponding variable
Update to the Monster structure:
Note, the offsets listed are for the first struct in the array, they are usually referenced with address + (208*monster_id) - the unknown padding is mostly in sizes of 8 so it's easy to replace it when I find out what some values are.
Code: [Select]
Code:
//0x1D27B10#pragma pack(push, 1)struct Character{ BYTE **monster_info; //0x1D27B10 - could just be used for the name but points to section 7 of a loaded dat file BYTE unk[8]; //0x1D27B14 BYTE status; //0x1D27B1C - MSB - reflect / shell / protect / regen / stop / slow / haste / ? - LSB BYTE unk1[3]; //0x1D27B1D DWORD unkdword1D27B20; //0x1D27B20 - used in opcode 0x24 DWORD unkdword1D27B24; //0x1D27B24 - used in opcode 0x24 DWORD currentHP; //0x1D27B28 DWORD maxHP; //0x1D27B2C BYTE unk2_0[4]; //0x1D27B30 DWORD localVars[8]; //0x1D27B34 - DC to E3 - base address used is 0x1D277C4 WORD unkwordarr1D27B54[6]; //0x1D27B54 at least 6 items, changed by opcode 2D BYTE unk3_0[4]; //0x1D27B60 WORD unkword1D27B64[16]; //0x1D27B64 DWORD unkdword1D27B84[3]; //0x1D27B84 BYTE status1; //0x1D27B90 MSB - ? / zombie / berserk / ? / ? / ? / ? / ? - LSB BYTE unk4[7]; //0x1D27B91 BYTE lastAttacker; //0x1D27B98 - used in opcode 0x0E case 0xCB - 0, 1 or 2 for SeeD 3+ for monsters BYTE unk5_0[7]; //0x1D27B99 - this whole section of unknowns looks to be status resistances BYTE unk5_1[8]; //0x1D27BA0 BYTE unk5_2[8]; //0x1D27BA8 BYTE unk5_3[8]; //0x1D27BB0 BYTE unk5_4[8]; //0x1D27BB8 BYTE unk5_5[8]; //0x1D27BC0 BYTE unkbyte1D27BC8; //0x1D27BC8 used in case 0x2A BYTE unk6[3]; //0x1D27BC9 BYTE lvl; //0x1D27BCB BYTE str; //0x1D27BCC BYTE vit; //0x1D27BCD BYTE mag; //0x1D27BCE BYTE spr; //0x1D27BCF BYTE spd; //0x1D27BD0 BYTE luck; //0x1D27BD1 BYTE eva; //0x1D27BD2 BYTE unk7[12];};#pragma pack(pop)
I've found that generally the ID of the monsters is 3, 4 and 5 (no idea what happens with 8 monster battles yet), so the first monster you fight will have its parameters at 0x1D27D80 rather than 0x1D27B10. It looks like it stores most of the parameters for the monsters that you're fighting, all I need now is to finish decoding it
There's a bunch of interesting things I didn't know about the AI code, you have to be careful with some opcodes because you can override bits of memory that you shouldn't - which could lead to some random crashes.
opcode 0x0E is used to set a variable as mentioned by random_npc, there's a special case where the immediate is 0xCB which causes the variable to be assigned the value of last attacker instead of the immediate - it appears that 0xCB is treated as a special case in quite a few opcodes.
After further investigation, it seems there are 2 sets of variables DC-E3 (which are stored in the struct above) and 60-67 (which are stored separately - I assume these are global for the battle).
It looks like bad things would happen if you used opcode 0x0E to write outside the range DC-E3 but there's no constraint checking!
The 71 byte structure I mentioned before contains a series of multipliers for stats (str, mag etc.) which default to 10 (1x multiplier) among some other things that I haven't identified.
Notes on opcode 0x04 - Targeting:
the final form of this in the function is a bit mask to represent which enemies are targeted, looking at the code I can see the following:
0xC8: 0000 0000 0000 1000 //self (it just shifts 1 left by the monster id - this represents and id of 3)
0xC9: //random enemy - probably one of the first 3 bits is set
0xCA: //??
0xCB: //last attacker - does 1 << the value in it's struct (see struct above)
0xCC: 1000 0000 0000 0111 //all enemies
0xCD: 1000 0000 1111 1000 //all allies
0xCE: 1000 0000 1111 1111 //everyone?
0xCF: //random ally
0xD0: 1010 0000 0000 0111 //something to do with enemies
0xD1: //?? does 1 << the value in 0x1D28DFB
0xDC-0xE3: //does 1 << the value in the corresponding variable
Last edited: