Merge pull request #149 from Chesyon/main
Some checks are pending
build / build (push) Waiting to run

Decomped GetMonsterDisplayNameType & GetMonsterName
This commit is contained in:
AnonymousRandomPerson
2025-07-14 23:57:32 -04:00
committed by GitHub
6 changed files with 149 additions and 200 deletions

View File

@@ -3,6 +3,8 @@
.public DUNGEON_PTR
.public GetActiveTeamMember
.public GetExplorerMazeMonster
.public GetMonsterDisplayNameType
.public GetMonsterName
.public GetName
.public GetNameRaw
.public GetNameWithGender

View File

@@ -1,206 +1,8 @@
.include "asm/macros.inc"
.include "overlay_29_02300108.inc"
.include "overlay_29_0230027C.inc"
.text
#ifndef JAPAN
arm_func_start GetMonsterDisplayNameType
GetMonsterDisplayNameType: ; 0x02300108
ldr r1, _02300160 ; =DUNGEON_PTR
ldr r1, [r1]
add r1, r1, #0x1a000
ldrb r2, [r1, #0x23e]
cmp r2, #0
ldreqb r2, [r1, #0x245]
cmpeq r2, #0
bne _0230013C
ldrb r1, [r1, #0x244]
cmp r1, #0
ldreqb r1, [r0, #0xef]
cmpeq r1, #1
bne _0230014C
_0230013C:
ldrb r1, [r0, #6]
cmp r1, #0
movne r0, #1
bxne lr
_0230014C:
ldrb r0, [r0, #0xd8]
cmp r0, #2
moveq r0, #2
movne r0, #0
bx lr
.align 2, 0
_02300160: .word DUNGEON_PTR
arm_func_end GetMonsterDisplayNameType
#endif
arm_func_start GetMonsterName
GetMonsterName: ; 0x02300164
#ifdef JAPAN
stmdb sp!, {r4, lr}
ldr r2, _02301678 ; =DUNGEON_PTR
mov r4, r0
ldr r0, [r2]
add r0, r0, #0x1a000
ldrb r2, [r0, #0x19a]
cmp r2, #0
ldreqb r2, [r0, #0x1a1]
cmpeq r2, #0
bne _02301574
ldrb r0, [r0, #0x1a0]
cmp r0, #0
ldreqb r0, [r1, #0xef]
cmpeq r0, #1
bne _02300190
_02301574:
ldrb r0, [r1, #6]
cmp r0, #0
beq _02300190
ldr r1, _02300274 ; =0x00000C34
mov r0, r4
bl CopyStringFromId
ldmia sp!, {r4, pc}
_02300190:
ldrb r0, [r1, #0xd8]
#else
stmdb sp!, {r3, r4, r5, lr}
mov r4, r1
mov r5, r0
mov r0, r4
bl GetMonsterDisplayNameType
cmp r0, #1
bne _02300190
ldr r1, _02300274 ; =0x00000C34
mov r0, r5
bl CopyStringFromId
ldmia sp!, {r3, r4, r5, pc}
_02300190:
#endif
cmp r0, #2
bne _023001A8
ldr r1, _02300278 ; =0x00000C32
#ifdef JAPAN
mov r0, r4
bl CopyStringFromId
ldmia sp!, {r4, pc}
_023001A8:
ldrb r0, [r1, #6]
cmp r0, #0
beq _0230025C
ldrb r0, [r1, #0xbc]
#else
mov r0, r5
bl CopyStringFromId
ldmia sp!, {r3, r4, r5, pc}
_023001A8:
ldrb r0, [r4, #6]
cmp r0, #0
beq _0230025C
ldrb r0, [r4, #0xbc]
#endif
cmp r0, #0xb
bne _023001DC
mov r0, #0
bl GetExplorerMazeMonster
mov r1, r0
#ifdef JAPAN
mov r0, r4
mov r2, #0x4e
bl sub_02056084
ldmia sp!, {r4, pc}
#else
mov r0, r5
mov r2, #0x4e
bl sub_02056084
ldmia sp!, {r3, r4, r5, pc}
#endif
_023001DC:
cmp r0, #0xc
bne _02300200
mov r0, #1
bl GetExplorerMazeMonster
mov r1, r0
#ifdef JAPAN
mov r0, r4
mov r2, #0x4e
bl sub_02056084
ldmia sp!, {r4, pc}
#else
mov r0, r5
mov r2, #0x4e
bl sub_02056084
ldmia sp!, {r3, r4, r5, pc}
#endif
_02300200:
cmp r0, #0xd
bne _02300224
mov r0, #2
bl GetExplorerMazeMonster
mov r1, r0
#ifdef JAPAN
mov r0, r4
mov r2, #0x4e
bl sub_02056084
ldmia sp!, {r4, pc}
#else
mov r0, r5
mov r2, #0x4e
bl sub_02056084
ldmia sp!, {r3, r4, r5, pc}
#endif
_02300224:
cmp r0, #0xe
bne _02300248
mov r0, #3
bl GetExplorerMazeMonster
mov r1, r0
#ifdef JAPAN
mov r0, r4
mov r2, #0x4e
bl sub_02056084
ldmia sp!, {r4, pc}
_02300248:
ldrsh r1, [r1, #4]
mov r0, r4
mov r2, #0x4e
bl GetNameWithGender
ldmia sp!, {r4, pc}
_0230025C:
ldrsh r0, [r1, #0xc]
bl GetActiveTeamMember
mov r1, r0
mov r0, r4
bl sub_020585B4
ldmia sp!, {r4, pc}
.align 2, 0
_02301678: .word DUNGEON_PTR
_02300274: .word 0x00000973
_02300278: .word 0x00000971
#else
mov r0, r5
mov r2, #0x4e
bl sub_02056084
ldmia sp!, {r3, r4, r5, pc}
_02300248:
ldrsh r1, [r4, #4]
mov r0, r5
mov r2, #0x4e
bl GetNameWithGender
ldmia sp!, {r3, r4, r5, pc}
_0230025C:
ldrsh r0, [r4, #0xc]
bl GetActiveTeamMember
mov r1, r0
mov r0, r5
bl sub_020585B4
ldmia sp!, {r3, r4, r5, pc}
.align 2, 0
_02300274: .word 0x00000C34
_02300278: .word 0x00000C32
#endif
arm_func_end GetMonsterName
arm_func_start ov29_0230027C
ov29_0230027C: ; 0x0230027C
stmdb sp!, {r4, lr}

88
include/common.h Normal file
View File

@@ -0,0 +1,88 @@
#ifndef PMDSKY_COMMON_H
#define PMDSKY_COMMON_H
#include "item.h"
#include "move.h"
struct ground_move {
// 0x0: flags: 1-byte bitfield
// See move::flags0 for details
u8 f_exists : 1;
u8 f_subsequent_in_link_chain : 1;
u8 f_enabled_for_ai : 1;
u8 f_set : 1;
u8 f_last_used : 1; // unconfirmed, but probably the same as struct move
u8 f_disabled : 1;
u8 flags_unk6 : 2;
u8 field_0x1; // Probably padding since it doesn't get initialized
u16 id; // 0x2
u8 ginseng; // 0x4: Ginseng boost
u16 field_0x5; // Probably padding since it doesn't get initialized
};
struct ground_monster {
u8 is_valid; // 0x0: True if the entry is valid
s8 level; // 0x1: Monster level
u8 joined_at; // 0x2
u8 joined_at_floor; // 0x3: See struct monster::joined_at_floor
u16 id; // 0x4: Monster ID
s8 level_at_first_evo; // 0x6: Level upon first evolution, or 0 if not applicable
s8 level_at_second_evo; // 0x7: Level upon second evolution, or 0 if not applicable
u16 iq; // 0x8
u16 max_hp; // 0xA
u8 offensive_stats[2]; // 0xC: {atk, sp_atk}
u8 defensive_stats[2]; // 0xE: {def, sp_def}
s32 exp; // 0x10
// 0x14: Bitvector that keeps track of which IQ skills the monster has enabled.
// See enum iq_skill_id for the meaning of each bit.
u32 iq_skill_flags[3];
u8 tactic; // 0x20
u8 field_0x21;
struct ground_move moves[4]; // 0x22
char name[10]; // 0x3A: Display name of the monster
};
// Stores information about active team members, including those from special episodes.
// A lot of the fields seem to be analogous to fields on struct monster.
struct team_member {
// 0x0: flags: 1-byte bitfield
u8 f_is_valid : 1;
u8 flags_unk1 : 7;
u8 is_leader; // 0x1
u8 level; // 0x2
u8 joined_at; // 0x3
u8 joined_at_floor; // 0x4
u8 field_0x5;
u16 iq; // 0x6
s16 member_index; // 0x8: Index in the list of all team members (not just the active ones)
s16 team_index; // 0xA: In order by team lineup
u16 id; // 0xC
u16 current_hp; // 0xE
u16 max_hp; // 0x10
u8 offensive_stats[2]; // 0x12: {atk, sp_atk}
u8 defensive_stats[2]; // 0x14: {def, sp_def}
u8 field_0x16;
u8 field_0x17;
s32 exp; // 0x18
struct move moves[4]; // 0x1C
u8 field_0x3C;
u8 field_0x3D;
struct item held_item; // 0x3E
s16 belly; // 0x44: Integer part
s16 belly_thousandths; // 0x46
s16 max_belly; // 0x48: Integer part
s16 max_belly_thousandths; // 0x4A
// 0x4C: Bitvector that keeps track of which IQ skills the monster has enabled.
// See enum iq_skill_id for the meaning of each bit.
u32 iq_skill_flags[3];
u8 tactic; // 0x58
u8 field_0x59;
s16 hidden_power_base_power; // 0x5A
u8 hidden_power_type; // 0x5C
u8 field_0x5D; // Gets copied to monster->field_0x47.
char name[10]; // 0x5E: Display name of the monster
};
#endif

View File

@@ -2,8 +2,21 @@
#define PMDSKY_OVERLAY_29_023000E4_H
#include "dungeon_mode.h"
#include "dungeon.h"
#include "common.h"
#include "main_0202593C.h"
// Checks if an entity pointer points to a valid entity (not entity type 0, which represents no entity).
bool8 EntityIsValid__023000E4(struct entity *entity);
#ifndef JAPAN
// Used when determining how a monster's name should be displayed.
enum display_name_type {
DISPLAY_NAME_NORMAL = 0, // Display the name as usual
DISPLAY_NAME_UNKNOWN = 1, // Display "(?)"
DISPLAY_NAME_DECOY = 2, // Display "Decoy"
};
enum display_name_type GetMonsterDisplayNameType(struct monster *monster);
#endif
void GetMonsterName(char *buffer, struct monster *target_info);
#endif //PMDSKY_OVERLAY_29_023000E4_H

View File

@@ -352,7 +352,7 @@ Overlay OVY_29
Object src/overlay_29_022FFF28.o
Object asm/overlay_29_022FFF4C.o
Object src/overlay_29_023000E4.o
Object asm/overlay_29_02300108.o
Object asm/overlay_29_0230027C.o
Object src/dungeon_logic.o
Object src/dungeon_logic_1.o
Object asm/overlay_29_023007A8.o

View File

@@ -7,3 +7,47 @@ bool8 EntityIsValid__023000E4(struct entity *entity)
return entity->type != ENTITY_NOTHING;
}
extern struct dungeon *DUNGEON_PTR[];
#ifndef JAPAN
enum display_name_type GetMonsterDisplayNameType(struct monster *monster) {
struct dungeon *dungeon = DUNGEON_PTR[0];
if ( dungeon->display_data.blinded || dungeon->display_data.hallucinating || (!dungeon->display_data.can_see_traps && (monster->invisible_class_status.status == 1))) {
if (monster->is_not_team_member) return DISPLAY_NAME_UNKNOWN;
}
if (monster->curse_class_status.curse == STATUS_CURSE_DECOY) return DISPLAY_NAME_DECOY;
return DISPLAY_NAME_NORMAL;
}
#endif
extern void GetNameWithGender(char *dst, s16 monster_id, char color_id);
extern struct ground_monster *GetExplorerMazeMonster(u8 entry_number);
extern void sub_02056084(char *dst, struct ground_monster *ground_monster, u8 unk);
extern void sub_020585B4(char *dst, struct team_member *team_member);
extern struct team_member *GetActiveTeamMember(int roster_idx);
void GetMonsterName(char *buffer, struct monster *target_info) {
#ifndef JAPAN
int display_name_type = GetMonsterDisplayNameType(target_info);
if (display_name_type == DISPLAY_NAME_UNKNOWN) CopyStringFromId(buffer, 3124);
else if (display_name_type == DISPLAY_NAME_DECOY) CopyStringFromId(buffer, 3122);
#else
struct dungeon *dungeon = DUNGEON_PTR[0];
if ( dungeon->display_data.blinded || dungeon->display_data.hallucinating || (!dungeon->display_data.can_see_traps && (target_info->invisible_class_status.status == 1))) {
if (target_info->is_not_team_member) {
CopyStringFromId(buffer, 2419);
return;
}
}
if (target_info->curse_class_status.curse == STATUS_CURSE_DECOY) CopyStringFromId(buffer, 2417);
#endif
else if (target_info->is_not_team_member) {
enum monster_behavior behavior = target_info->monster_behavior;
if (behavior == BEHAVIOR_EXPLORER_MAZE_1) sub_02056084(buffer, GetExplorerMazeMonster(0), 0x4e);
else if (behavior == BEHAVIOR_EXPLORER_MAZE_2) sub_02056084(buffer, GetExplorerMazeMonster(1), 0x4e);
else if (behavior == BEHAVIOR_EXPLORER_MAZE_3) sub_02056084(buffer, GetExplorerMazeMonster(2), 0x4e);
else if (behavior == BEHAVIOR_EXPLORER_MAZE_4) sub_02056084(buffer, GetExplorerMazeMonster(3), 0x4e);
else GetNameWithGender(buffer, target_info->apparent_id, 'N');
}
else sub_020585B4(buffer, GetActiveTeamMember(target_info->team_index));
}