Changed ability_data, class_data and item_data scripts
Identified more fields in ClassData Identified more elements Decompiled class_data functions
This commit is contained in:
parent
7c766d07f9
commit
053f0d5cda
|
|
@ -21,6 +21,7 @@ typedef struct {
|
|||
/* 0x18 */ u16 cur_hp;
|
||||
/* 0x1A */ Element element;
|
||||
/* 0x1B */ u8 field_0x1b;
|
||||
|
||||
/* 0x1C */ u16 strength;
|
||||
/* 0x1E */ u16 vitality;
|
||||
/* 0x20 */ u16 intelligence;
|
||||
|
|
@ -28,12 +29,17 @@ typedef struct {
|
|||
/* 0x24 */ u16 agility;
|
||||
// DEX affects melee and special attacks, as well as accuracy.
|
||||
/* 0x26 */ u16 dexterity;
|
||||
|
||||
/* 0x28 */ u8 field_0x28[3];
|
||||
/* 0x2B */ u16 item_upper_left;
|
||||
/* 0x2D */ u16 item_upper_right;
|
||||
/* 0x2F */ u16 item_lower_left;
|
||||
/* 0x31 */ u16 item_lower_right;
|
||||
/* 0x33 */ u8 field_0x33[0x5];
|
||||
/* 0x33 */ u8 field_0x33;
|
||||
/* 0x34 */ s8 field_0x34;
|
||||
/* 0x35 */ u8 field_0x35;
|
||||
/* 0x36 */ u8 field_0x36;
|
||||
/* 0x37 */ u8 field_0x37;
|
||||
} CharacterSlot; // size:0x38
|
||||
|
||||
#endif // __CHARACTER_H__
|
||||
|
|
@ -321,11 +321,15 @@ extern Element ability_get_element(u8 index, u16 arg1, u16 arg2, s32 arg3, u16
|
|||
extern u16 func_8016FA34(u16, u16, u16, u16);
|
||||
extern u16 func_8016FB50(u16, u16, u16, u16);
|
||||
|
||||
#define RANK_NONE 0
|
||||
#define RANK_UNIT_LEADER 1
|
||||
#define RANK_LEGION_LEADER 2
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ char* name;
|
||||
/* 0x04 */ u8 field_0x4;
|
||||
/* 0x05 */ u8 field_0x5;
|
||||
/* 0x06 */ u8 field_0x6;
|
||||
/* 0x05 */ u8 gender;
|
||||
/* 0x06 */ u8 leadership_rank;
|
||||
/* 0x07 */ u8 field_0x7;
|
||||
/* 0x08 */ u16 field_0x8;
|
||||
/* 0x0a */ u8 field_0xa;
|
||||
|
|
@ -360,18 +364,27 @@ typedef struct {
|
|||
/* 0x2b */ u8 field_0x2b;
|
||||
/* 0x2c */ u8 field_0x2c;
|
||||
/* 0x2d */ u8 field_0x2d;
|
||||
/* 0x2e */ u16 field_0x2e;
|
||||
|
||||
/* 0x30 */ u16 field_0x30;
|
||||
/* 0x32 */ u16 field_0x32;
|
||||
/* 0x34 */ u16 field_0x34;
|
||||
/* 0x2e */ u16 item_upper_left;
|
||||
/* 0x30 */ u16 item_upper_right;
|
||||
/* 0x32 */ u16 item_lower_left;
|
||||
/* 0x34 */ u16 item_lower_right;
|
||||
|
||||
/* 0x36 */ u8 field_0x36;
|
||||
/* 0x37 */ u8 field_0x37;
|
||||
/* 0x38 */ u8 field_0x38;
|
||||
/* 0x39 */ u8 field_0x39;
|
||||
/* 0x3a */ u8 field_0x3a;
|
||||
/* 0x3b */ u8 field_0x3b;
|
||||
/* 0x3c */ u8 field_0x3c;
|
||||
|
||||
// The ability which is used when the unit is placed in the front row.
|
||||
/* 0x37 */ u8 ability_front;
|
||||
// The amount of hits the unit performs when placed in the front row.
|
||||
/* 0x38 */ u8 ability_front_hitcount;
|
||||
// The ability which is used when the unit is placed in the middle row.
|
||||
/* 0x39 */ u8 ability_middle;
|
||||
// The amount of hits the unit performs when placed in the middle row.
|
||||
/* 0x3a */ u8 ability_middle_hitcount;
|
||||
// The ability which is used when the unit is placed in the back row.
|
||||
/* 0x3b */ u8 ability_back;
|
||||
// The amount of hits the unit performs when placed in the back row.
|
||||
/* 0x3c */ u8 ability_back_hitcount;
|
||||
|
||||
/* 0x3d */ u8 field_0x3d;
|
||||
/* 0x3e */ u8 field_0x3e;
|
||||
/* 0x3f */ u8 field_0x3f;
|
||||
|
|
@ -383,11 +396,26 @@ typedef struct {
|
|||
/* 0x44 */ u8 field_0x44;
|
||||
/* 0x45 */ u8 field_0x45;
|
||||
/* 0x46 */ u8 field_0x46;
|
||||
/* 0x47 */ u8 field_0x47;
|
||||
/* 0x47 */ u8 max_items;
|
||||
} ClassData; // size:0x48
|
||||
|
||||
extern ClassData CLASS_DATA[];
|
||||
|
||||
extern ItemId class_get_item_lower_right(u8 arg0, u8 arg1);
|
||||
extern char* class_get_ability_front_name(u8 arg0, u8 arg1);
|
||||
extern char* class_get_ability_middle_name(u8 arg0, u8 arg1);
|
||||
extern char* class_get_ability_back_name(u8 arg0, u8 arg1);
|
||||
extern char* class_get_name(u8 arg0, u8 arg1);
|
||||
|
||||
extern struct {
|
||||
/* 0x0 */ u8 field_0x0;
|
||||
/* 0x1 */ u8 field_0x1;
|
||||
/* 0x2 */ u8 field_0x2;
|
||||
/* 0x3 */ u8 field_0x3;
|
||||
/* 0x4 */ u8 field_0x4;
|
||||
/* 0x5 */ u8 field_0x5;
|
||||
} D_8018ECE4[]; // size:0x6
|
||||
|
||||
extern musConfig __MUS_CONFIG_8010A710;
|
||||
|
||||
#endif
|
||||
|
|
@ -12,6 +12,14 @@ typedef u8 Element;
|
|||
#define ELEMENT_WATER 4
|
||||
#define ELEMENT_VIRTUE 5
|
||||
#define ELEMENT_BANE 6
|
||||
#define ELEMENT_DRAKONITE 7
|
||||
#define ELEMENT_VARIABLE 8
|
||||
#define ELEMENT_WIND_FLAME 9
|
||||
#define ELEMENT_FLAME_WIND 10
|
||||
#define ELEMENT_EARTH_FLAME 11
|
||||
#define ELEMENT_WATER_EARTH 12
|
||||
#define ELEMENT_WIND_BANE 13
|
||||
#define ELEMENT_FLAME_BANE 14
|
||||
|
||||
#define ELEMENT_UNKNOWN_0x10 16
|
||||
|
||||
|
|
|
|||
173
src/item.c
173
src/item.c
|
|
@ -60,43 +60,178 @@ INCLUDE_ASM(const s32, "item", func_8016DB30);
|
|||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DB84);
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DBD8);
|
||||
/* 43AD8 8016DBD8 */
|
||||
u8 class_get_field_0x2c(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].field_0x2c;
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DC2C);
|
||||
return CLASS_DATA[arg1].field_0x2c;
|
||||
}
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DC80);
|
||||
/* 43B2C 8016DC2C */
|
||||
u8 class_get_ability_front(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].ability_front;
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DCD4);
|
||||
return CLASS_DATA[arg1].ability_front;
|
||||
}
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DD20);
|
||||
/* 43B80 8016DC80 */
|
||||
u8 class_get_ability_front_hitcount(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].ability_front_hitcount;
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DD74);
|
||||
return CLASS_DATA[arg1].ability_front_hitcount;
|
||||
}
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DDC8);
|
||||
/* 43BD4 8016DCD4 */
|
||||
u8 class_get_ability_middle(u8 arg0, u8 arg1) {
|
||||
s32 var_v0;
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DE1C);
|
||||
if (CLASS_DATA[arg0].field_0x45 != arg1) {
|
||||
var_v0 = arg1 * 9;
|
||||
} else {
|
||||
var_v0 = CLASS_DATA[arg0].field_0x45 * 9;
|
||||
}
|
||||
return *(&CLASS_DATA->ability_middle + (var_v0 * 8));
|
||||
}
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DE70);
|
||||
/* 43C20 8016DD20 */
|
||||
u8 class_get_ability_middle_hitcount(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].ability_middle_hitcount;
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DEC4);
|
||||
return CLASS_DATA[arg1].ability_middle_hitcount;
|
||||
}
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DF18);
|
||||
/* 43C74 8016DD74 */
|
||||
u8 class_get_ability_back(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].ability_back;
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DF88);
|
||||
return CLASS_DATA[arg1].ability_back;
|
||||
}
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016DFDC);
|
||||
/* 43CC8 8016DDC8 */
|
||||
u8 class_get_ability_back_hitcount(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].ability_back_hitcount;
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016E030);
|
||||
return CLASS_DATA[arg1].ability_back_hitcount;
|
||||
}
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016E084);
|
||||
/* 43D1C 8016DE1C */
|
||||
u8 class_get_field_0x4(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].field_0x4;
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016E0D8);
|
||||
return CLASS_DATA[arg1].field_0x4;
|
||||
}
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016E140);
|
||||
/* 43D70 8016DE70 */
|
||||
u8 class_get_gender(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].gender;
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016E174);
|
||||
return CLASS_DATA[arg1].gender;
|
||||
}
|
||||
|
||||
/* 43DC4 8016DEC4 */
|
||||
u8 class_get_leadership_rank(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].leadership_rank;
|
||||
|
||||
return CLASS_DATA[arg1].leadership_rank;
|
||||
}
|
||||
|
||||
/* 43E18 8016DF18 */
|
||||
u8 class_get_global_flag(u8 arg0, u8 arg1) {
|
||||
u8 var_a1;
|
||||
|
||||
var_a1 = arg1;
|
||||
if (D_8018ECE4[arg0].field_0x0 & 0x80) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == var_a1) {
|
||||
var_a1 = arg0;
|
||||
}
|
||||
}
|
||||
return D_8018ECE4[var_a1].field_0x0 & 0x3F;
|
||||
}
|
||||
|
||||
/* 43E88 8016DF88 */
|
||||
ItemId class_get_item_upper_left(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].item_upper_left;
|
||||
|
||||
return CLASS_DATA[arg1].item_upper_left;
|
||||
}
|
||||
|
||||
/* 43EDC 8016DFDC */
|
||||
ItemId class_get_item_upper_right(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].item_upper_right;
|
||||
|
||||
return CLASS_DATA[arg1].item_upper_right;
|
||||
}
|
||||
|
||||
/* 43F30 8016E030 */
|
||||
ItemId class_get_item_lower_left(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].item_lower_left;
|
||||
|
||||
return CLASS_DATA[arg1].item_lower_left;
|
||||
}
|
||||
|
||||
/* 43F84 8016E084 */
|
||||
ItemId class_get_item_lower_right(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].item_lower_right;
|
||||
|
||||
return CLASS_DATA[arg1].item_lower_right;
|
||||
}
|
||||
|
||||
/* 43FD8 8016E0D8 */
|
||||
char* class_get_ability_front_name(u8 arg0, u8 arg1) {
|
||||
u8 var_v0;
|
||||
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1) {
|
||||
var_v0 = CLASS_DATA[arg0].ability_front;
|
||||
} else {
|
||||
var_v0 = CLASS_DATA[arg1].ability_front;
|
||||
}
|
||||
|
||||
return ability_get_name(var_v0);
|
||||
}
|
||||
|
||||
/* 44040 8016E140 */
|
||||
char* class_get_ability_middle_name(u8 arg0, u8 arg1) {
|
||||
// Possible a C macro wrapping?
|
||||
do {
|
||||
char* ret = ability_get_name(CLASS_DATA[arg1].ability_middle);
|
||||
return ret;
|
||||
} while(0);
|
||||
}
|
||||
|
||||
/* 44074 8016E174 */
|
||||
char* class_get_ability_back_name(u8 arg0, u8 arg1) {
|
||||
u8 var_v0;
|
||||
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1) {
|
||||
var_v0 = CLASS_DATA[arg0].ability_back;
|
||||
} else {
|
||||
var_v0 = CLASS_DATA[arg1].ability_back;
|
||||
}
|
||||
|
||||
return ability_get_name(var_v0);
|
||||
}
|
||||
|
||||
/* 440DC 8016E1DC */
|
||||
char* class_get_name(u8 arg0, u8 arg1) {
|
||||
if (CLASS_DATA[arg0].field_0x45 == arg1)
|
||||
return CLASS_DATA[arg0].name;
|
||||
|
||||
return CLASS_DATA[arg1].name;
|
||||
}
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016E1DC);
|
||||
|
||||
INCLUDE_ASM(const s32, "item", func_8016E230);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,16 @@
|
|||
// Set by calls to bzero
|
||||
D_80193BC0 = 0x80193BC0; // size:0x15E0
|
||||
D_801971F0 = 0x801971F0; // size:0x4E2
|
||||
D_801969B8 = 0x801969B8; // size:0x6E
|
||||
D_80190F80 = 0x80190F80; // size:0x16C
|
||||
D_80196B00 = 0x80196B00; // size:0x458
|
||||
D_80193AB0 = 0x80193AB0; // size:0xA
|
||||
D_801977D8 = 0x801977D8; // size:0x1E
|
||||
D_80197710 = 0x80197710; // size:0x64
|
||||
D_80196A58 = 0x80196A58; // size:0x94
|
||||
|
||||
DEFAULT_BATTALION_NAME = 0x80190EFC; // rom:0x66DFC type:asciz
|
||||
|
||||
STR_SERIFU_POSITION_X_ERROR = 0x8019E20C; // rom:0xEAF8C type:asciz
|
||||
|
||||
STR_IS_THE_NAME_ACCEPTABLE = 0x8018FDC4; // rom:0x65CC4 type:asciz
|
||||
|
|
@ -26,10 +39,35 @@ STR_ELEMENT_VIRTUE = 0x8018768C; // rom:0x5D58C type:asciz
|
|||
STR_ELEMENT_BANE = 0x80187694; // rom:0x5D594 type:asciz
|
||||
STR_ELEMENT_DRAKONITE = 0x8018769C; // rom:0x5D59C type:asciz
|
||||
STR_ELEMENT_VARIABLE = 0x801876A8; // rom:0x5D5A8 type:asciz
|
||||
STR_ELEMENT_WIND_FLAME = 0x801876B4; // rom:0x5D5B4 type:asciz
|
||||
STR_ELEMENT_FLAME_WIND = 0x801876C0; // rom:0x5D5C0 type:asciz
|
||||
STR_ELEMENT_EARTH_FLAME = 0x801876CC; // rom:0x5D5CC type:asciz
|
||||
STR_ELEMENT_WATER_EARTH = 0x801876D8; // rom:0x5D5D8 type:asciz
|
||||
STR_ELEMENT_WIND_BANE = 0x801876E4; // rom:0x5D5E4 type:asciz
|
||||
STR_ELEMENT_FlAME_BANE = 0x801876F0; // rom:0x5D5F0 type:asciz
|
||||
|
||||
D_80187BD4 = 0x80187BD4; // rom:0x5DAD4 type:u32
|
||||
|
||||
CLASS_DATA = 0x80187C14; // rom:0x5DB14 size:0x48 type:u32
|
||||
class_get_field_0x2c = 0x8016DBD8; // rom:0x43AD8
|
||||
class_get_ability_front = 0x8016DC2C; // rom:0x43B2C
|
||||
class_get_ability_front_hitcount = 0x8016DC80; // rom:0x43B80
|
||||
class_get_ability_middle = 0x8016DCD4; // rom:0x43BD4
|
||||
class_get_ability_middle_hitcount = 0x8016DD20; // rom:0x43C20
|
||||
class_get_ability_back = 0x8016DD74; // rom:0x43C74
|
||||
class_get_ability_back_hitcount = 0x8016DDC8; // rom:0x43CC8
|
||||
class_get_field_0x4 = 0x8016DE1C; // rom:0x43D1C
|
||||
class_get_gender = 0x8016DE70; // rom:0x43D70
|
||||
class_get_leadership_rank = 0x8016DEC4; // rom:0x43DC4
|
||||
class_get_global_flag = 0x8016DF18; // rom:0x43E18
|
||||
class_get_item_upper_left = 0x8016DF88; // rom:0x43E88
|
||||
class_get_item_upper_right = 0x8016DFDC; // rom:0x43EDC
|
||||
class_get_item_lower_left = 0x8016E030; // rom:0x43F30
|
||||
class_get_item_lower_right = 0x8016E084; // rom:0x43F84
|
||||
class_get_ability_front_name = 0x8016E0D8; // rom:0x43FD8
|
||||
class_get_ability_middle_name = 0x8016E140; // rom:0x44040
|
||||
class_get_ability_back_name = 0x8016E174; // rom:0x44074
|
||||
class_get_name = 0x8016E1DC; // rom:0x440DC
|
||||
|
||||
ITEM_TYPE_NAMES = 0x802130A4; // rom:0x164214 type:char*
|
||||
FORMATION_COMMAND_NAMES = 0x8021315C; // rom:0x1642CC type:char*
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ def read_ability(index):
|
|||
|
||||
return unpack_from(ABILITY_FORMAT, read_rom(ability_start, ability_end))
|
||||
|
||||
for i in range(1, 130):
|
||||
MAX_ABILITIES = 162
|
||||
for i in range(1, MAX_ABILITIES):
|
||||
|
||||
(name_vaddr, field_0x0, element, field_0x2, field_0x3, field_0x4,
|
||||
field_0x5, field_0x6, field_0x7, field_0x8, field_0x9,
|
||||
|
|
@ -25,6 +26,6 @@ for i in range(1, 130):
|
|||
name_addr_diff = (name_vaddr - NAME_VADDR_START) + NAME_ADDR_START
|
||||
name = read_rom(name_addr_diff, name_addr_diff + 32).split(b'\0', 1)[0]
|
||||
|
||||
print(f"{name}:\t", (field_0x0, field_0x2, field_0x3, field_0x4, field_0x5,
|
||||
print(f"{name} ({i}):\t", (field_0x0, field_0x2, field_0x3, field_0x4, field_0x5,
|
||||
field_0x6, field_0x7, field_0x8, field_0x9, field_0xa,
|
||||
field_0xb))
|
||||
|
|
@ -1,27 +1,112 @@
|
|||
from ob import read_rom, ELEMENT_NAME
|
||||
|
||||
from struct import unpack_from
|
||||
from struct import unpack_from, calcsize
|
||||
from typing import NamedTuple
|
||||
import textwrap
|
||||
|
||||
import item_data
|
||||
|
||||
NAME_VADDR_START = 0x8016AF80
|
||||
NAME_ADDR_START = 0x40E80
|
||||
|
||||
CLASS_DATA = 0x5DB14
|
||||
CLASS_FORMAT = '>IBBBBHBBHBBHBBHBBHBBHBBHBBBBBBBBBBBBHHHHBBBBBBBBBBBBBBBBBB'
|
||||
|
||||
class ClassData(NamedTuple):
|
||||
name: int
|
||||
field_0x4: int
|
||||
gender: int
|
||||
# None, Unit Leader, Legion Leader
|
||||
leadership_rank: int
|
||||
field_0x7: int
|
||||
field_0x8: int
|
||||
field_0xa: int
|
||||
field_0xb: int
|
||||
field_0xc: int
|
||||
field_0xe: int
|
||||
field_0xf: int
|
||||
field_0x10: int
|
||||
field_0x12: int
|
||||
field_0x13: int
|
||||
field_0x14: int
|
||||
field_0x16: int
|
||||
field_0x17: int
|
||||
field_0x18: int
|
||||
field_0x1a: int
|
||||
field_0x1b: int
|
||||
field_0x1c: int
|
||||
field_0x1e: int
|
||||
field_0x1f: int
|
||||
field_0x20: int
|
||||
field_0x22: int
|
||||
field_0x23: int
|
||||
field_0x24: int
|
||||
field_0x25: int
|
||||
field_0x26: int
|
||||
field_0x27: int
|
||||
field_0x28: int
|
||||
field_0x29: int
|
||||
field_0x2a: int
|
||||
field_0x2b: int
|
||||
field_0x2c: int
|
||||
field_0x2d: int
|
||||
|
||||
item_upper_left: int
|
||||
item_upper_right: int
|
||||
item_lower_left: int
|
||||
item_lower_right: int
|
||||
|
||||
field_0x36: int
|
||||
|
||||
ability_front: int
|
||||
ability_front_hits: int
|
||||
ability_middle: int
|
||||
ability_middle_hits: int
|
||||
ability_back: int
|
||||
ability_back_hits: int
|
||||
|
||||
field_0x3d: int
|
||||
field_0x3e: int
|
||||
field_0x3f: int
|
||||
field_0x40: int
|
||||
field_0x41: int
|
||||
field_0x42: int
|
||||
field_0x43: int
|
||||
field_0x44: int
|
||||
field_0x45: int
|
||||
field_0x46: int
|
||||
|
||||
max_items: int
|
||||
|
||||
def read_class(index):
|
||||
CLASS_SIZE = 0x48
|
||||
CLASS_FORMAT = '>IH'
|
||||
|
||||
class_start = CLASS_DATA + (index * CLASS_SIZE)
|
||||
class_end = class_start + CLASS_SIZE
|
||||
|
||||
return unpack_from(CLASS_FORMAT, read_rom(class_start, class_end))
|
||||
return ClassData(*unpack_from(CLASS_FORMAT, read_rom(class_start, class_end)))
|
||||
|
||||
for i in range(1, 10):
|
||||
if __name__ == "__main__":
|
||||
MAX_CLASSES = 165
|
||||
for i in range(1, MAX_CLASSES):
|
||||
class_data = read_class(i)
|
||||
|
||||
(name_vaddr, rest) = read_class(i)
|
||||
|
||||
name_addr_diff = (name_vaddr - NAME_VADDR_START) + NAME_ADDR_START
|
||||
name_addr_diff = (class_data.name - NAME_VADDR_START) + NAME_ADDR_START
|
||||
name = read_rom(name_addr_diff, name_addr_diff + 32).split(b'\0', 1)[0]
|
||||
|
||||
print(f"{name}:\t")
|
||||
print(rest)
|
||||
print(f"Class= {name} ({i})\t")
|
||||
print(f"ItemUpperLeft= {item_data.item_get_name(item_data.item_read(class_data.item_upper_left).name)}")
|
||||
print(f"ItemUpperRight= {item_data.item_get_name(item_data.item_read(class_data.item_upper_right).name)}")
|
||||
print(f"ItemLowerLeft= {item_data.item_get_name(item_data.item_read(class_data.item_lower_left).name)}")
|
||||
print(f"ItemLowerRight= {item_data.item_get_name(item_data.item_read(class_data.item_lower_right).name)}")
|
||||
|
||||
unidentified = []
|
||||
for val in class_data._fields:
|
||||
if val.startswith("field_"):
|
||||
unidentified.append(f"{val}: {getattr(class_data, val)}")
|
||||
|
||||
print("Unidentified fields: ")
|
||||
print("\n".join(unidentified), end="")
|
||||
print()
|
||||
print("-----------------------------------------")
|
||||
print()
|
||||
|
|
|
|||
|
|
@ -1,21 +1,48 @@
|
|||
from ob import read_rom, ELEMENT_NAME, get_element_name
|
||||
|
||||
from struct import unpack_from, calcsize
|
||||
from typing import NamedTuple
|
||||
|
||||
NAME_VADDR_START = 0x8016AF80
|
||||
NAME_ADDR_START = 0x40E80
|
||||
OVERLAY_VADDR_START = 0x8016AF80
|
||||
OVERLAY_ADDR_START = 0x40E80
|
||||
|
||||
ITEM_FORMAT = '>IBBBBHbbbbbbbbbbbbbBBBBBBBBB'
|
||||
ITEM_SIZE = 0x20
|
||||
|
||||
def read_item(index):
|
||||
ITEM_SIZE = 0x20
|
||||
class ItemData(NamedTuple):
|
||||
name: int
|
||||
item_type: int
|
||||
element: int
|
||||
field_0x2: int
|
||||
field_0x3: int
|
||||
field_0x4: int
|
||||
strength: int
|
||||
intelligence: int
|
||||
agility: int
|
||||
dexterity: int
|
||||
vitality: int
|
||||
mem : int
|
||||
field_0xc: int
|
||||
res_strike: int
|
||||
res_wind: int
|
||||
res_fire: int
|
||||
res_earth: int
|
||||
res_water: int
|
||||
res_holy: int
|
||||
res_dark: int
|
||||
field_0x18: int
|
||||
field_0x19: int
|
||||
field_0x1a: int
|
||||
field_0x1b: int
|
||||
field_0x1c: int
|
||||
field_0x1d: int
|
||||
field_0x1e: int
|
||||
field_0x1f: int
|
||||
|
||||
item_start = 0x6230C + (index * ITEM_SIZE)
|
||||
item_end = item_start + ITEM_SIZE
|
||||
|
||||
return unpack_from(ITEM_FORMAT, read_rom(item_start, item_end))
|
||||
|
||||
print(f"Length: 0x{calcsize(ITEM_FORMAT):X}")
|
||||
def item_get_name(ptr):
|
||||
# Read the name from the ROM
|
||||
name_addr_diff = (ptr - OVERLAY_VADDR_START) + OVERLAY_ADDR_START
|
||||
return read_rom(name_addr_diff, name_addr_diff + 32).split(b'\0', 1)[0]
|
||||
|
||||
ITEM_TYPE_NAME = {
|
||||
0: "None",
|
||||
|
|
@ -48,41 +75,45 @@ ITEM_TYPE_NAME = {
|
|||
255: "Invalid"
|
||||
}
|
||||
|
||||
for i in range(0, 279):
|
||||
# print(f"Item {i}:")
|
||||
(name_vaddr, item_type, element, field_0x2, field_0x3, field_0x4,
|
||||
strength, intelligence, agility, dexterity, vitality,
|
||||
mem, *rest) = read_item(i)
|
||||
def item_get_type_name(item_type):
|
||||
return ITEM_TYPE_NAME[item_type] if item_type in ITEM_TYPE_NAME else f"Unknown({item_type})"
|
||||
|
||||
name_addr_diff = (name_vaddr - NAME_VADDR_START) + NAME_ADDR_START
|
||||
name = read_rom(name_addr_diff, name_addr_diff + 32).split(b'\0', 1)[0]
|
||||
def item_read(index):
|
||||
item_start = 0x6230C + (index * ITEM_SIZE)
|
||||
item_end = item_start + ITEM_SIZE
|
||||
|
||||
(field_0xc, res_strike, res_wind, res_fire, res_earth, res_water,
|
||||
res_holy, res_dark, *rest) = rest
|
||||
return ItemData(*unpack_from(ITEM_FORMAT, read_rom(item_start, item_end)))
|
||||
|
||||
rest = (field_0xc, *rest)
|
||||
|
||||
type_str = ITEM_TYPE_NAME[item_type] if item_type in ITEM_TYPE_NAME else f"Unknown({item_type})"
|
||||
if __name__ == "__main__":
|
||||
MAX_ITEM = 279
|
||||
for i in range(0, 5):
|
||||
item = item_read(i)
|
||||
|
||||
print(f"Name: {name} ({i})")
|
||||
print(f"Type: {type_str}")
|
||||
print(f"Element: {get_element_name(element)}")
|
||||
print(f"STR: \t{strength} \tMEN: \t{mem}")
|
||||
print(f"VIT: \t{vitality} \tAGI: \t{agility}")
|
||||
print(f"INT: \t{intelligence} \tDEX: \t{dexterity}")
|
||||
print(f"Name: {item_get_name(item.name)} ({i})")
|
||||
print(f"Type: {item_get_type_name(item.item_type)}")
|
||||
print(f"Element: {get_element_name(item.element)}")
|
||||
print(f"STR: \t{item.strength} \tMEN: \t{item.mem}")
|
||||
print(f"VIT: \t{item.vitality} \tAGI: \t{item.agility}")
|
||||
print(f"INT: \t{item.intelligence} \tDEX: \t{item.dexterity}")
|
||||
print()
|
||||
print(f"RES STRIKE: \t{res_strike}")
|
||||
print(f"RES WIND: \t{res_wind}")
|
||||
print(f"RES FIRE: \t{res_fire}")
|
||||
print(f"RES EARTH: \t{res_earth}")
|
||||
print(f"RES WATER: \t{res_water}")
|
||||
print(f"RES HOLY: \t{res_holy}")
|
||||
print(f"RES DARK: \t{res_dark}")
|
||||
print(f"RES STRIKE: \t{item.res_strike}")
|
||||
print(f"RES WIND: \t{item.res_wind}")
|
||||
print(f"RES FIRE: \t{item.res_fire}")
|
||||
print(f"RES EARTH: \t{item.res_earth}")
|
||||
print(f"RES WATER: \t{item.res_water}")
|
||||
print(f"RES HOLY: \t{item.res_holy}")
|
||||
print(f"RES DARK: \t{item.res_dark}")
|
||||
|
||||
for val in rest:
|
||||
print(f"{val:X}")
|
||||
unidentified = []
|
||||
for val in item._fields:
|
||||
if val.startswith("field_"):
|
||||
unidentified.append(f"{val}: {getattr(item, val)}")
|
||||
|
||||
print("Unidentified fields: ")
|
||||
print(", ".join(unidentified), end="")
|
||||
print()
|
||||
|
||||
print("-------------------------------------------")
|
||||
print()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue