pmd-sky/include/dungeon_mode.h
AnonymousRandomPerson a78c571138 Decomped sub_0205C75C
Decomped by @slaw-22
2026-03-19 21:10:54 -04:00

1310 lines
59 KiB
C

#ifndef PMDSKY_DUNGEON_MODE_H
#define PMDSKY_DUNGEON_MODE_H
#include "direction.h"
#include "enums.h"
#include "graphics.h"
#include "item.h"
#include "mission.h"
#include "move.h"
#include "util.h"
#define NUM_PICKED_IQ_SKILLS 3
#define MAX_MON_MOVES 4
#define STRUGGLE_MOVE_INDEX 4
#define STAT_MULTIPLIER_THRESHOLD 0.249 // one tick less than 0.25
#define DEFAULT_STAT_STAGE 10
#define MAX_STAT_STAGE 20
#define MAX_SPEED_STAGE 4
#define MAX_HP_LIMIT 999
#define NUM_SPEED_COUNTERS 5
#define MAX_STOCKPILE_STAGE 3
#define NUM_STATS_PER_CATEGORY 2
#define NUM_PREV_POS 4
#define STAT_STAGE_ATK 0
#define STAT_STAGE_SP_ATK 1
#define STAT_STAGE_DEF 0
#define STAT_STAGE_SP_DEF 1
#define STAT_STAGE_ACCURACY 0
#define STAT_STAGE_EVASION 1
// Used in various contexts, like with entity positions in the dungeon
struct position {
s16 x;
s16 y;
};
// Used to indicate the pixel position of an entity. Values are shifted 8 bits to the left, so they
// are probably decimal numbers instead.
struct pixel_position {
u32 x;
u32 y;
};
// Monster stat modifier info
struct monster_stat_modifiers {
// Stages go from 0-20 inclusive, with normal being 10
s16 offensive_stages[NUM_STATS_PER_CATEGORY]; // 0x0: {atk, sp_atk}
s16 defensive_stages[NUM_STATS_PER_CATEGORY]; // 0x4: {def, sp_def}
s16 hit_chance_stages[NUM_STATS_PER_CATEGORY]; // 0x8: {accuracy, evasion}
s16 flash_fire_boost; // 0xC: can be 0, 1, or 2
u8 field_0xe;
u8 field_0xf;
// Some moves like Screech affect the damage calculation differently than, e.g., Leer
// 0x10: binary fixed-point (8 fraction bits), {atk, sp_atk}; from Charm, Memento, etc.
fx32_8 offensive_multipliers[NUM_STATS_PER_CATEGORY];
// 0x18: binary fixed-point (8 fraction bits), {def, sp_def}; from Screech, etc.
fx32_8 defensive_multipliers[NUM_STATS_PER_CATEGORY];
};
// A bitfield where every bit controls one of the icons that can appear on top of a monster's sprite
// to represent status effects. If multiple bits are set, the shown icon cycles through them.
struct status_icon_flags {
bool8 f_sleepless : 1; // Blue eye blinking yellow
bool8 f_burn : 1; // Red flame
bool8 f_poison : 1; // White skull
bool8 f_toxic : 1; // Purple skull
bool8 f_confused : 1; // Yellow birds
bool8 f_cowering : 1; // 2 green lines in circle (same as whiffer)
bool8 f_taunt : 1; // Fist icon
bool8 f_encore : 1; // Blue exclamation mark (same as low HP)
// Blue shield with white sparks. Also for counter, mini counter, mist,
// metal burst, aqua ring, and lucky chant
bool8 f_reflect : 1;
bool8 f_safeguard : 1; // Pink shield. Also for mirror coat
bool8 f_light_screen : 1; // Golden shield. Also for magic coat
bool8 f_protect : 1; // Green shield. Also for mirror move and vital throw
bool8 f_endure : 1; // Blue shield with red sparks
bool8 f_low_hp : 1; // Blue exclamation mark (same as encore)
bool8 f_curse : 1; // Red skull
bool8 f_embargo : 1; // Yellow exclamation mark. Also for gastro acid and snatch
bool8 f_sure_shot : 1; // Blue sword blinking yellow
bool8 f_whiffer : 1; // 2 green lines in circle (same as cowering)
bool8 f_set_damage : 1; // Blue sword blinking red
bool8 f_focus_energy : 1; // Red sword blinking yellow
bool8 f_blinded : 1; // Blue eye with an X
bool8 f_cross_eyed : 1; // Blue question mark
bool8 f_eyedrops : 1; // Blue eye blinking yellow with a circular wave
bool8 f_muzzled : 1; // Blinking red cross
bool8 f_grudge : 1; // Purple shield
bool8 f_exposed : 1; // Blue eye blinking red with a circular wave
bool8 f_sleep : 1; // Red Z's
bool8 f_lowered_stat : 1; // Yellow arrow pointing down
bool8 f_heal_block : 1; // Blinking green cross
bool8 f_miracle_eye : 1; // Blinking orange cross
bool8 f_red_exclamation_mark : 1; // Probably unused
bool8 f_magnet_rise : 1; // Purple arrow pointing up
// The following 4 bytes appear to have a different meaning, maybe they are intended to
// represent icons that are always displayed and do not cycle (inferred from the difference
// between the ice block and the other icons). Except for the first bit, the others do not
// seem to have an effect, but the code stores the full 4 bytes as a bitwise OR of some of the
// flags (see UpdateStatusIconBitfield).
bool8 f_freeze : 1; // Ice block
u8 flags_unk2 : 7;
u8 field_0x5;
u8 field_0x6;
u8 field_0x7;
};
// Stores a parameter for an action taken by a monster
struct action_parameter {
// 0x0: Metadata for the action.
// E.g., this is the monster index when taking an action on a monster, the move index when
// using a move or a union item_index value when using an item.
u8 action_use_idx;
struct position item_pos; // 0x2: Position of the item to use when using an item on the floor
};
// Contains data used to describe an action taken by a monster.
struct action_data {
enum action action_id; // 0x0: Action ID
u8 direction; // 0x2: Direction in which the action will be performed
struct action_parameter action_parameters[2]; // 0x4: Parameters for the action
// 0x10: Position of the target that the Pokémon wants throw an item at.
struct position item_target_position;
};
struct sleep_class_status {
// 0x0: If non-zero, the corresponding status in status_sleep_id is active.
enum status_sleep_id sleep;
u8 sleep_turns; // 0x1: Turns left for the status in statuses::sleep
};
struct burn_class_status
{
enum status_burn_id burn; // 0x0: STATUS_BURN if 1
u8 burn_turns; // 0x1: Turns left for the status in statuses::burn
// 0x2: Turns left until residual damage for the status in statuses::burn, if applicable
u8 burn_damage_countdown;
// 0x3: The number of times the statuses::burn_damage_countdown has reached 0. Only used
// when badly poisoned. Determines how much damage the badly poisoned status condition
// will deal. There is no noticable difference because the table this value is looked up
// on is filled with 0x6
u8 badly_poisoned_damage_count;
};
struct frozen_class_status {
// 0x0: If non-zero, the corresponding status in status_frozen_id is active.
enum status_frozen_id freeze;
// 0x4: Controls the animation that plays when taking damage from the constriction status.
// For some reason this is initalized to 0x22 (34)? Which is the animation used by
// the exclusive item Nether Veil.
u32 constriction_animation;
u8 freeze_turns; // 0x8: Turns left for the status in statuses::freeze
// 0x9: Turns left until residual damage for the status in statuses::freeze, if applicable
u8 freeze_damage_countdown;
};
struct cringe_class_status {
// 0x0: If non-zero, the corresponding status in status_cringe_id is active.
enum status_cringe_id cringe;
u8 cringe_turns; // 0x1: Turns left for the status in statuses::cringe
};
struct bide_class_status {
// 0x0: If non-zero, the corresponding status in status_two_turn_id is active.
enum status_two_turn_id bide;
u8 bide_turns; // 0x1: Turns left for the status in statuses::bide
u8 bide_move_slot; // 0x2: Slot in the user's move list
};
struct reflect_class_status {
enum status_reflect_id reflect; // 0x0: STATUS_REFLECT if 1
u8 reflect_turns; // 0x1: Turns left for the status in statuses::reflect
// 0x2: Turns left until residual healing for the status in statuses::reflect, if applicable
u8 reflect_damage_countdown;
};
struct curse_class_status {
// 0x0: If non-zero, the corresponding status in status_curse_id is active.
enum status_curse_id curse;
// 0x1: Set to monster::is_not_team_member of the attacker (the one causing the decoy status).
u8 curse_applier_non_team_member_flag;
// 0x2: Set to 1 on a Pokemon when inflicted with the Decoy status.
u8 dec;
u8 curse_turns; // 0x3: Turns left for the status in statuses::curse
// 0x4: Turns left until residual damage for the status in statuses::curse, if applicable
u8 curse_damage_countdown;
};
struct leech_seed_class_status {
enum status_leech_seed_id leech_seed; // 0x0: STATUS_LEECH_SEED if 1
// 0x4: Used to track the statuses::statuses_unique_id of the relevant monster for
// statuses like Leech Seed and Destiny Bond.
u32 statuses_applier_id;
// 0x8: Index into entity_table_hdr::monster_slot_ptrs in the dungeon that the user
// (drainer) is held.
u8 leech_seed_source_monster_index;
u8 leech_seed_turns; // 0x9: Turns left for the status in statuses::leech_seed
// 0xA: Turns left until residual damage for the status in statuses::leech_seed, if applicable.
// Behaves weirdly without an afflictor
u8 leech_seed_damage_countdown;
};
struct sure_shot_class_status {
enum status_sure_shot_id sure_shot; // 0x0: STATUS_SURE_SHOT if 1
u8 sure_shot_turns; // 0x1: Turns left for the status in statuses::sure_shot
};
struct long_toss_class_status {
enum status_long_toss_id status; // 0x0: STATUS_LONG_TOSS if 1
};
struct invisible_class_status
{
enum status_invisible_id status; // 0x0: STATUS_INVISIBLE if 1
u8 turns; // 0x1: Turns left for the status in statuses::invisible
};
struct blinker_class_status {
enum status_blinker_id blinded; // 0x0: STATUS_BLINKER if 1
u8 blinded_turns; // 0x1: Turns left for the status in statuses::blinded
};
struct iq_skill_flags
{
u32 flags[NUM_PICKED_IQ_SKILLS]; /* 0x0 */
};
struct moves
{
struct move moves[MAX_MON_MOVES]; // 0x0
u8 struggle_move_flags; // 0x18
};
struct ai_target
{
enum ai_objective ai_objective; // 0x0
bool8 ai_not_next_to_target; // 0x1: This NPC monster is not next to its current target
bool8 ai_targeting_enemy; // 0x2: This NPC monster is targeting an enemy monster
bool8 ai_turning_around; // 0x3: This NPC monster has decided to turn around
// 0x4: entity::spawn_genid of the entity currently being targeted
u16 ai_target_spawn_genid;
struct entity* ai_target; // 0x8: Current or most recent AI target
u8 field_0xc;
u8 field_0xd;
u8 field_0xe;
u8 field_0xf;
struct position ai_target_pos; // 0x10: Position of the entity currently being targeted
};
// Monster info
struct monster {
// 0x0: flags: 2-byte bitfield
u16 flags;
s16 id; // 0x2:
s16 apparent_id; // 0x4: What's outwardly displayed if Transformed
bool8 is_not_team_member; // 0x6: true for enemies and allied NPCs that aren't on the team
bool8 is_team_leader; // 0x7
// 0x8: An ally is an NPC that isn't a normal team member, e.g. for story boss battles
bool8 is_ally;
enum shopkeeper_mode shopkeeper; // 0x9
u8 level; // 0xA
u8 field_0xb;
s16 team_index; // 0xC: In order by team lineup
s16 iq; // 0xE
s16 hp; // 0x10: Current HP
s16 max_hp_stat; // 0x12: Add to max_hp_boost for the actual max HP
u8 field_0x14;
u8 field_0x15;
s16 max_hp_boost; // 0x16: From Life Seeds, Sitrus Berries, etc.
u8 field_0x18;
u8 field_0x19;
u8 offensive_stats[2]; // 0x1A: {atk, sp_atk}
u8 defensive_stats[2]; // 0x1C: {def, sp_def}
u8 field_0x1e;
u8 field_0x1f;
s32 exp; // 0x20: Total Exp. Points
struct monster_stat_modifiers stat_modifiers; // 0x24
s16 hidden_power_base_power; // 0x44
enum type_id hidden_power_type; // 0x46
u8 field_0x47;
enum dungeon_id joined_at : 8; // 0x48: Also used as a unique identifier for special monsters
u8 joined_at_floor; // 0x49: Floor number of recruitment. 0 for special recruits
struct action_data action; // 0x4A: Determines the action the monster will take on this turn
enum type_id types[2]; // 0x5E
enum ability_id abilities[2]; // 0x60
struct item held_item; // 0x62
// 0x68: Previous held item. Used for whenever taking the X-Ray Specs or Y-Ray Specs on or off
// in order to update the camera and minimap. Changed to held_item.id after checking.
enum item_id previous_held_item_id;
// Previous position data is used by the AI
struct position prev_pos[NUM_PREV_POS]; // 0x6A: Position X turns ago
struct ai_target ai_target; // 0x7A
// 0x90: Work array while updating skills in the menu. Same meaning as iq_skill_flags.
struct iq_skill_flags iq_skill_menu_flags;
// 0x9C: First 9 bytes contain bitfield data; the rest is presumably padding.
// Bitvector. See enum iq_skill_id for the meaning of each bit.
struct iq_skill_flags iq_skill_flags;
enum tactic_id tactic; // 0xA8
// 0xA9
bool8 roost;
// 0xAA: The typing in entity::types before the flying type is removed for statuses::roost
// and restored to entity::types after statuses::roost ends.
enum type_id original_types[2];
// 0xAC: The move id to be used if statuses::bide is 1.
u8 bide_move_id;
u8 field_0xad;
u8 field_0xae;
u8 field_0xaf;
// 0xB0: Unique number given to the monster when spawning to differentiate it from other
// monsters and to properly keep track of a monster. Likely used because a monster could be
// spawned into the same slot as an old monster and using a pointer alone could cause some
// issues. Used for Leech Seed, Destiny Bond, Storm Drain, Lightning Rod (probably more).
u32 unique_id;
// 0xB4: Unique number between the wrapped and wrapping target to connect them.
u32 wrap_pair_unique_id;
// 0xB8: Tracks the damage taken to deal when bide status ends. Max 0x3E7 (999).
u32 bide_damage_tally;
enum monster_behavior monster_behavior; // 0xBC
struct sleep_class_status sleep_class_status; // 0xBD
struct burn_class_status burn_class_status; // 0xBF
struct frozen_class_status frozen_class_status; // 0xC4
struct cringe_class_status cringe_class_status; // 0xD0
struct bide_class_status bide_class_status; // 0xD2
struct reflect_class_status reflect_class_status; // 0xD5
struct curse_class_status curse_class_status; // 0xD8
struct leech_seed_class_status leech_seed_class_status; // 0xE0
struct sure_shot_class_status sure_shot_class_status; // 0xEC
struct long_toss_class_status long_toss_class_status; // 0xEE
struct invisible_class_status invisible_class_status; // 0xEF
struct blinker_class_status blinker_class_status; // 0xF1
bool8 muzzled; // 0xF3: STATUS_MUZZLED if 1
u8 muzzled_turns; // 0xF4: Turns left for the status in statuses::muzzled
bool8 miracle_eye; // 0xF5: STATUS_MIRACLE_EYE if 1
u8 miracle_eye_turns; // 0xF6: Turns left for the status in statuses::miracle_eye
bool8 magnet_rise; // 0xF7: STATUS_MAGNET_RISE if 1
u8 magnet_rise_turns; // 0xF8: Turns left for the status in statuses::magnet_rise
bool8 power_ears; // 0xF9: STATUS_POWER_EARS
bool8 scanning; // 0xFA: STATUS_SCANNING
bool8 stair_spotter; // 0xFB: STATUS_STAIR_SPOTTER
// 0xFC: Set when initally spawning a team member with the ability Pickup.
bool8 pickup_flag;
bool8 grudge; // 0xFD: STATUS_GRUDGE
bool8 exposed; // 0xFE: STATUS_EXPOSED (Foresight/Odor Sleuth)
bool8 type_changed; // 0xFF: Flag for if the monster's type has been changed
bool8 boss_flag; // 0x100: Seems to be true for boss monsters
// 0x101: Appears to be a flag for when a monster increasces their speed. Maybe only used
// by the RunLeaderTurn function to know if the leader has changed their speed stage partway
// through the function?
u8 unk_sped_up_tracker;
// 0x102: Maybe related to being a team member and new recruit? Set to 1 in TryRecruit
// and 0 in SpawnTeam. Also checked in EnemyEvolution to be 0 before evolving. Maybe to
// prevent a recently recruited ally from evolving after and or to add a monster to the
// assembly after the completion of a dungeon?
u8 field_0x102;
#ifndef JAPAN
// 0x103: Possibly a flag while in action. Could also be a flag to cause the burn from
// lava, heal a burn from water, and decrease hunger in the walls.
bool8 in_action;
#endif
// 0x104: STATUS_TERRIFIED, interestingly, appears to use 0x1 for the Foe-Fear Orb but
// 0x2 for the ability Stench. The distinction only seems to exist for the game to use
// a special message for when terrified from stench ends.
u8 terrified;
u8 terrified_turns; // 0x105: Turns left for the terrified status
u8 perish_song_turns; // 0x106: Turns left before Perish Song takes effect
// 0x107: Increases progressively while the No-Slip Cap is held. Capped at 0x13
// Used to calculate the chance of an item becoming sticky, resets to 0 when that happens
u8 no_slip_cap_counter;
// 0x108: Determines how much experience the monster will reward after being defeated
// 0 = 0.5x, 1 = 1.0x, 2 = 1.5x
u8 exp_yield;
// 0x109: Appears to be set when the held item of the monster is going to be used?
bool8 use_held_item;
// 0x10A: Is initalized to 0x63 (99). Changing it from this value causes the monster to
// begin rendering differently? For example, it causes entity::0xB3 to be 1 and forces
// entity::0x28 to be 0.
u8 field_0x10a;
// 0x10B: Flag for two-turn moves that haven't concluded yet. This is also a graphical flag.
// A value of 1 mean "high up" (Fly/Bounce). A value of 2 means some other condition like
// Dig, Shadow Force, etc. Other values are treated as invalid. Also used for the move
// Seismic Toss when throwing up the target.
u8 two_turn_move_invincible;
// 0x10C: Related to handling AI when a decoy is present on the floor?
// Seems to only be 0, 1, 2
u8 decoy_ai_tracker;
#ifndef JAPAN
u8 field_0x10d;
u8 field_0x10e;
u8 field_0x10f;
#endif
// 0x110: 1 means normal. 0 means half speed. 2, 3, and 4 mean 2x, 3x, and 4x speed.
s32 speed_stage;
// Each counter ticks down to 0 turn by turn. The current speed_stage is calculated as:
// min(max({# nonzero speed_up_counters} - {# nonzero speed_down_counters}, 0), 4)
u8 speed_up_counters[5]; // 0x114
u8 speed_down_counters[5]; // 0x119
u8 stockpile_stage; // 0x11E: Goes from 0-3. STATUS_STOCKPILING if nonzero
u8 field_0x11f;
// 0x120: If zero, when the monster is standing in a room, the AI will make it head towards a
// random exit. If nonzero, the monster will instead move in a random direction every turn.
s32 random_movement;
struct moves moves; // 0x124
struct fixed_point belly; // 0x146
struct fixed_point max_belly; // 0x14A:
// 0x14E: If true and the monster is an ally, the AI will skip it. False for enemies.
bool8 ai_ally_skip;
bool8 ai_next_to_target; // 0x14F: This NPC monster is next to its current target
// 0x150: Set if monster::is_team_leader is true and belly is empty.
bool8 famished;
bool8 waiting;
// 0x152: Seems to be true if the monster has already acted this turn: attacked, used an item,
// or seemingly anything other than moving/resting. Also true when the monster faints.
bool8 already_acted;
// 0x153: True if this enemy should evolve. It is not enough to set this flag to evolve
// an enemy monster. You also need to set dungeon::should_enemy_evolve.
bool8 should_evolve;
// 0x154: True if using a charged move. Changed together with statuses::bide.
bool8 using_charged_move;
// 0x155: True if the target attacked a Pokemon that has STATUS_GRUDGE.
bool8 hit_grudge_monster;
u8 field_0x156; // 0 when the monster faints
u8 field_0x157;
// 0x158: General-purpose bitflags tracking different bits of volatile state.
// Together with prev_state_bitflags, this is typically used to determine whether
// to log a message on a state change.
u16 state_flags;
// 0x15A: The previous value of state_bitflags before the last update
u16 prev_state_flags;
// 0x15C: Appears to control if flash fire should activate.
bool8 apply_flash_fire_boost;
// 0x15D: Appears to be a counter for how many times rollout has hit. Likely to be able to
// determine how much extra damage consecutive rollout hits should deal.
u8 rollout_hit_counter;
// 0x15E: If true, the monster is warped after completing its move.
bool8 memento_warp_flag;
// 0x15F: If true, the monster's special attack is dropped after the completing its move.
bool8 overheat_special_attack_drop_flag;
// 0x160: If true, the monster's shadow is drawn. This value is initalized to 1 for every
// monster except Diglett and Dugtrio.
bool8 display_shadow;
// 0x161: If true, prevents giving items to this monster. Might have a broader meaning,
// such as whether the monster is a guest pokémon.
bool8 cannot_give_items;
// 0x162: Related to using a move and either missing or fainting. Set to 1 right before
// the function for a move is called and set to 0 (sometimes) in ApplyDamage. Gets set
// when the monster faints sometimes with field 0x156. When false, causes random
// outcomes with the monster to fail.
bool8 field_0x162;
// 0x163: Related to controlling the number of attacks per move use. Possibly to account
// for two-turn moves?
bool8 field_0x163;
bool8 took_damage_flag; // 0x164: Set after the monster took damage.
// 0x165: Appears to be some sort of validity check? Where 0 is valid and 1 is invalid.
// HandleFaint sets this number to 1. Also set to 1 if IsMonsterIdInNormalRange is false.
bool8 field_0x165;
// 0x166: Set after the monster attacks (true if the attack missed, false otherwise). If true
// when the monster attacks, Practice Swinger will activate.
bool8 practice_swinger_flag;
// 0x167: Set to true when the monster receives a critical hit. If true when the monster
// attacks, Anger Point will activate. Set to false after the monster attacks.
bool8 anger_point_flag;
u8 field_0x168;
u8 field_0x169;
// 0x16A: When not DIR_NONE, monster will turn in the specified direction and
// its AI will be forced to target the tile next to it in that direction.
// Used to prevent bosses from turning towards team members the moment the boss fight
// starts (which would override their intended starting facing direction).
enum direction_id force_turn : 8;
u8 field_0x16b;
u8 field_0x16c;
u8 field_0x16d;
u8 field_0x16e;
u8 field_0x16f;
// 0x170: Set to make the monster disappear when using the move U-turn.
bool8 uturn_hide_monster_flag;
// 0x171: Some kind of visual flag? Gets set to 0 temporarily when changing Shaymin form
// or when using the Gone Pebble? Also hardcoded to be set to 0 for monsters that generally
// tend to float? Otherwise 1?
bool8 field_0x171;
// 0x172: Set when the leader and falling through a pitfall trap.
bool8 pitfall_trap_flag_0x172;
// 0x173: Some kind of visual flag?
bool8 field_0x173;
// 0x174: Set when the leader and falling through a pitfall trap.
bool8 pitfall_trap_flag_0x174;
u8 field_0x175;
u8 field_0x176;
// 0x177: Appears to be the direction for using sleep talk? Set to DIR_NONE when awake.
enum direction_id sleep_talk_direction : 8;
// 0x178: Appears to be the direction for using snore? Set to DIR_NONE when awake.
enum direction_id snore_direction : 8;
// 0x179: Seems to be set to 4 when the monster initally throws something and probably
// related to direction somehow. Checked in a loop for every monster.
u8 field_0x179;
// 0x17A: Somehow related to sprite size?
u8 field_0x17a;
// 0x17B: Somehow related to sprite size?
u8 field_0x17b;
u8 field_0x17c;
u8 field_0x17d;
struct position target_pos; // 0x17E: The AI's target's position on screen
struct position pixel_pos; // 0x182: The monster's graphical position on screen?
u8 field_0x186;
u8 field_0x187;
u8 field_0x188;
u8 field_0x189;
u8 field_0x18a;
u8 field_0x18b;
// 0x18C: Bitflags that cause non-damaging exclusive items to trigger on the
// attacker after they have completed their move. For example, the Eclipse Robe
// (Darkrai exclusive item) may afflict attacking enemies with the nightmare
// status condition. (Only uses first 21 bits).
u32 exclusive_item_trigger_bitflags;
// 0x190: Appears to be related to the item name of the exclusive item that
// caused the effect to trigger.
s16 field_0x190;
// 0x192: Bitflags that cause non-damaging abilities to trigger on the attacker
// after they have completed their move. Abilites like magnet pull, cute charm,
// static, and flame body. (Only uses first 11 bits). One exception is the move
// Rapid Spin which sets one of the flags for the user.
u16 contact_ability_trigger_bitflags;
u8 field_0x194;
u8 field_0x195;
u8 field_0x196;
u8 field_0x197;
u8 field_0x198;
u8 field_0x199;
u8 field_0x19a;
u8 field_0x19b;
struct position pos; // 0x19C: Mirror of the position on the entity struct
u8 field_0x1a0;
u8 field_0x1a1;
u8 field_0x1a2;
u8 field_0x1a3;
u8 field_0x1a4;
u8 field_0x1a5;
u8 field_0x1a6;
u8 field_0x1a7;
u8 field_0x1a8;
u8 field_0x1a9;
u8 field_0x1aa;
u8 field_0x1ab;
u8 field_0x1ac;
u8 field_0x1ad;
u8 field_0x1ae;
u8 field_0x1af;
u8 field_0x1b0;
u8 field_0x1b1;
u8 field_0x1b2;
u8 field_0x1b3;
u16 walk_anim_frames_left; // 0x1B4: Number of frames left in walking animation?
u8 field_0x1b6;
u8 field_0x1b7;
u8 field_0x1b8;
u8 field_0x1b9;
u8 field_0x1ba;
u8 field_0x1bb;
u8 field_0x1bc;
u8 field_0x1bd;
u8 field_0x1be;
u8 field_0x1bf;
u8 field_0x1c0;
u8 field_0x1c1;
u8 field_0x1c2;
u8 field_0x1c3;
u8 field_0x1c4;
u8 field_0x1c5;
u8 field_0x1c6;
u8 field_0x1c7;
u8 field_0x1c8;
u8 field_0x1c9;
u8 field_0x1ca;
u8 field_0x1cb;
u8 field_0x1cc;
u8 field_0x1cd;
u8 field_0x1ce;
u8 field_0x1cf;
u8 field_0x1d0;
u8 field_0x1d1;
u8 field_0x1d2;
u8 field_0x1d3;
u8 field_0x1d4;
u8 field_0x1d5;
u8 field_0x1d6;
u8 field_0x1d7;
u8 field_0x1d8;
u8 field_0x1d9;
u8 field_0x1da;
u8 field_0x1db;
u8 field_0x1dc;
u8 field_0x1dd;
u8 field_0x1de;
u8 field_0x1df;
u8 field_0x1e0;
u8 field_0x1e1;
u8 field_0x1e2;
u8 field_0x1e3;
u8 field_0x1e4;
u8 field_0x1e5;
u8 field_0x1e6;
u8 field_0x1e7;
u8 field_0x1e8;
u8 field_0x1e9;
u8 field_0x1ea;
u8 field_0x1eb;
u8 field_0x1ec;
u8 field_0x1ed;
u8 field_0x1ee;
u8 field_0x1ef;
u8 field_0x1f0;
u8 field_0x1f1;
u8 field_0x1f2;
u8 field_0x1f3;
u8 field_0x1f4;
u8 field_0x1f5;
u8 field_0x1f6;
u8 field_0x1f7;
u8 field_0x1f8;
u8 field_0x1f9;
u8 field_0x1fa;
u8 field_0x1fb;
u8 field_0x1fc;
u8 field_0x1fd;
u8 field_0x1fe;
u8 field_0x1ff;
u8 field_0x200;
u8 field_0x201;
u8 field_0x202;
u8 field_0x203;
u8 field_0x204;
u8 field_0x205;
u8 field_0x206;
u8 field_0x207;
u8 field_0x208;
u8 field_0x209;
u8 field_0x20a;
u8 field_0x20b;
u8 field_0x20c;
u8 field_0x20d;
u8 field_0x20e;
u8 field_0x20f;
u8 hp_fractional; // 0x210: 200 * fractional_part(HP)
u8 field_0x211;
// 0x212: When a Pokémon can pass through walls in a hallway, this counts up to 200 before the Pokémon turns in a random direction.
s16 mobile_turn_timer;
// 0x214: Somehow related to gaining exp through a joy ribbon. Set to 0 after
// gaining or losing a level. Also checked and set to 0 when an enemy evolves.
// Maybe for a specific scenario of leveling up with exp from a joy ribbon?
u32 unk_exp_tracker;
// 0x218: Status icons displayed on top of the monster's sprite
struct status_icon_flags status_icons;
// 0x220: Seems to be related in some way to shadow size and being a water tileset. So
// probably controls when the ripple effect when standing on water.
u8 water_shadow_ripple_tracker;
// 0x221: Set if the current move being used was copied by Me First
bool8 me_first_flag;
u8 field_0x222;
u8 field_0x223;
// Stat boosts from exclusive items with EXCLUSIVE_EFF_STAT_BOOST
u8 exclusive_item_offense_boosts[2]; // 0x224: {atk, sp_atk}
u8 exclusive_item_defense_boosts[2]; // 0x226: {def, sp_def}
// 0x228: Bitvector. See enum exclusive_item_effect_id for the meaning of each bit
u32 exclusive_item_effect_flags[5];
// 0x23C: Initialized to 0. Probably menu related only, seems to be set to true through the
// menu.
bool8 field_0x23c;
// 0x23F: When reviving a monster, temporarily set to true. Probably a visual indicator
// of some kind?
bool8 unk_revive_visual_tracker;
// 0x23E: Gets set to 0 before using an attack and gets set to 1 in LevelUp. Seems to stop
// the rest of the attacks (ie from Swift Swim) from continuing. Possibly to avoid the
// the monster leveling up and trying to use a move that was just overwritten by a new move?
u8 field_0x23e;
// 0x23F: Gets set to 1 when the move used won't use up any PP. Used to check if the
// monster should lose extra PP from the ability Pressure.
bool8 should_not_lose_pp;
};
// Entity type. This is used to tag generic entity pointers.
enum entity_type {
ENTITY_NOTHING = 0,
ENTITY_MONSTER = 1,
ENTITY_TRAP = 2,
ENTITY_ITEM = 3,
ENTITY_HIDDEN_STAIRS = 5,
// Used when a temporary instance of this struct is created to pass it to some
// function that requires it as a parameter
ENTITY_TEMPORARY = 6,
ENTITY_PAD = 0xffffffff, // To Force on 32 bits
};
// Generic entity data
struct entity {
enum entity_type type; // 0x0
struct position pos; // 0x4
struct position prev_pos; // 0x8
struct pixel_position pixel_pos; // 0xC
struct pixel_position pixel_pos_mirror; // 0x14: Monsters only?
// 0x1C: Graphical parameter for evelation above the ground. Last byte behaves weirdly.
s32 elevation;
u8 is_visible; // 0x20: For traps/hidden stairs
u8 field_0x21;
// 0x22: If true, the sprite will be shown with a certain degree of transparency
u8 transparent;
// 0x23: Seems to be the animation frame counter for the 10-frame "shuffle" animation that
// plays at the end of a walk sequence
u8 end_walk_anim_frame;
u8 field_0x24;
u8 room_idx; // 0x25: Index of the room a monster is in. 0xFF for hall
// 0x26: Unique index for each monster that spawns. Starts at 0xA for the leader, and each
// subsequent monster to spawn is assigned the next number (0xB, 0xC, ...)
u16 spawn_genid;
u8 field_0x28;
u8 field_0x29;
u8 field_0x2a;
u8 field_0x2b;
struct animation_control anim_ctrl;
u16 sprite_index; // 0xA8
u8 field_0xaa;
u8 field_0xab;
u8 field_0xac;
u8 field_0xad;
u8 animation_group_id; // 0xAE
u8 animation_group_id_mirror; // 0xAF
u8 animation_id; // 0xB0
u8 animation_id_mirror0; // 0xB1
u8 field_0xb2;
u8 field_0xb3;
void* info; // 0xB4: Points to info struct for monster/item/trap
};
// Used in menus and the post-dungeon summary.
struct monster_summary {
enum monster_id id; // 0x0
u8 monster_name[10]; // 0x2
u8 field_0xC;
u8 field_0xD;
u8 field_0xE;
u8 field_0xF;
u8 field_0x10;
u8 field_0x11;
u8 field_0x12;
u8 field_0x13;
u8 field_0x14;
u8 field_0x15;
enum type_id types[2]; // 0x16
enum ability_id abilities[2]; // 0x18
enum dungeon_id joined_at; // 0x1A
u8 joined_at_floor; // 0x1B
struct item held_item; // 0x1C
u8 field_0x22;
u8 field_0x23;
s32 hp; // 0x24: Current HP
s32 max_hp; // 0x28: Actual max HP (hp + hp boost)
u32 level; // 0x2C
s32 exp; // 0x30
u8 offensive_stats[2]; // 0x34: {atk, sp_atk}
u8 defensive_stats[2]; // 0x36: {def, sp_def}
bool8 is_team_leader; // 0x38
u8 attack_boost; // 0x39: from things like Power Band, Munch Belt
u8 special_attack_boost; // 0x3A
u8 defense_boost; // 0x3B
u8 special_defense_boost; // 0x3C
u8 field_0x3D;
s16 iq; // 0x3E
u8 field_0x40;
u8 field_0x41;
// 0x42: Level upon first evolution. Set to 0 in dungeon mode.
u8 level_at_first_evo;
// 0x43: Level upon first evolution. Set to 0 in dungeon mode.
u8 level_at_second_evo;
// 0x44: Evolution status. In ground_mode, accounts for luminous spring being unlocked.
u8 evo_status;
bool8 inflicted_with_gastro_acid; // 0x45
u8 field_0x46;
u8 field_0x47;
u32 iq_skill_flags[3]; // 0x48
enum tactic_id tactic; // 0x54
u8 field_0x55;
u8 field_0x56;
u8 field_0x57;
// 0x58: Appears to be a list of all the currently inflicted statues in their enum form. The
// last entry (30th) appears to always be STATUS_NONE to serve as a terminator for the list.
// While in ground mode, it's always filled with STATUS_NONE.
enum status_id active_statuses[30];
u16 _padding_0x76;
};
// Info about a mission destination floor
struct mission_destination_info {
bool8 is_destination_floor; // 0x0: Whether or not the current floor is a mission destination
enum mission_type type; // 0x1:
// 0x2: The meaning of this field depends on the type field; see union mission_subtype.
u8 subtype;
// 0x3: The index of the mission in the job list?
u8 mission_job_list_idx;
// 0x4: Item to retrieve, if this is an item-retrieval mission
enum item_id item_to_retrieve;
enum item_id item_to_deliver; // 0x6: Item to deliver to the client, if relevant
enum item_id special_target_item; // 0x8: For Sealed Chamber and Treasure Memo missions
enum monster_id client; // 0xA: The client on the mission listing
enum monster_id rescue_target; // 0xC: The monster to be rescued
// 0xE: Usually just the target to defeat. If an outlaw has minions, the monster IDs will be
// listed in subsequent entries. Note that there can be multiple minions of the same species,
// which is not reflected here.
enum monster_id enemy_species[3];
u8 n_enemy_species; // 0x14: Length of the preceding array
u8 field_0x15;
// 0x16: Fixed room ID of the destination floor, if relevant
// (e.g., Chambers, Challenge Letters, etc.)
enum fixed_room_id fixed_room_id;
// 0x17: Related to missions where you have to obtain an item? Possibly related to the item
// being picked up and/or destroyed?
bool8 unk_mission_item_tracker1;
u8 field_0x18;
u8 field_0x19;
// 0x1A: Related to missions where you have to obtain an item? Possibly related to the item
// being picked up and/or destroyed?
bool8 unk_mission_item_tracker2;
// 0x1B: Will be set after the target enemy has been defeated.
// If there are minions, this flag applies just to the main outlaw.
bool8 target_enemy_is_defeated;
};
// Contains data about a monster that spawns in a dungeon
struct monster_spawn_entry {
u16 level_mult_512; // 0x0: Spawn level << 9
// 0x2: Incremental spawn weight of this entry for normal spawns
u16 incremental_spawn_weight;
// 0x4: Incremental spawn weight of this entry for monster house spawns
u16 incremental_spawn_weight_monster_house;
// 0x6: Monster id. Depending on where this struct is used, it can have values above 600
// to list secondary gender entries.
enum monster_id id;
};
// Dungeon floor properties
struct floor_properties {
enum floor_layout layout; // 0x0
// 0x1: Affects the number of rooms to be generated. If it's positive, a slight random variation
// (between -2 and +1) is applied to the value (the final value must be at least 1). If it's
// negative, its absolute value is used without adding a random variation.
s8 room_density;
u8 tileset; // 0x2
// 0x3: Indexes into the music ID table in overlay 10 to determine the floor's music track.
// See the relevant descriptions in the overlay 10 symbols for more information.
u8 music_table_idx;
enum weather_id weather; // 0x4
// 0x5: Controls how many connections will be made between grid cells
u8 floor_connectivity;
// 0x6: Controls how many enemies will be spawned. If 0, no enemies will spawn, even as the
// player walks.
// The final value will be 0 in the special case that density is 0. Otherwise, the final value
// will be randomized between density / 2 and density - 1, but no lower than 1.
// The code seems to imply that the value was meant to be signed, since it contains a section
// that takes the absolute value of the density while skipping the random variation, similar to
// room_density.
u8 enemy_density;
u8 kecleon_shop_spawn_chance; // 0x7: Percentage chance from 0-100
u8 monster_house_spawn_chance; // 0x8: Percentage chance from 0-100
u8 maze_room_chance; // 0x9: Percentage chance from 0-100
u8 sticky_item_chance; // 0xA
// 0xB: Whether or not dead ends are allowed in the floor layout. If false, dead ends will be
// corrected during floor generation (or rather, they should be, but the implementation is
// buggy)
bool8 allow_dead_ends;
// 0xC: Maximum number of secondary structures that can be generated on the floor
u8 max_secondary_structures;
// 0xD: room_flags: 1-byte bitfield
u8 room_flags;
// bool8 f_secondary_structures : 1; // Whether secondary structures are allowed
// u8 room_flags_unk1 : 1;
// bool8 f_room_imperfections : 1; // Whether room imperfections are allowed
// u8 room_flags_unk3 : 5;
u8 field_0xe;
u8 item_density; // 0xF: Controls how many items will be spawned
u8 trap_density; // 0x10: Controls how many traps will be spawned
u8 floor_number; // 0x11: The current floor number within the overall dungeon
enum fixed_room_id fixed_room_id; // 0x12
u8 extra_hallways; // 0x13: Number of extra hallways to generate
u8 buried_item_density; // 0x14: Controls how many buried items (in walls) will be spawned
// 0x15: Controls how much secondary terrain (water, lava, and this actually applies to chasms
// too) will be spawned
u8 secondary_terrain_density;
// 0x16: Vision range (in tiles) when standing on a hallway.
// A value of 0 means no limit, a value > 0 enables darkness on the floor.
u8 visibility_range;
u8 max_money_amount_div_5; // 0x17: 1/5 the maximum amount for Poké spawns
// 0x18: Chance of an item spawning on each tile in a Kecleon shop
enum shop_item_positions shop_item_positions;
// 0x19: Chance that a Monster House will be an itemless one
u8 itemless_monster_house_chance;
// 0x1A: Values are shifted relative to enum hidden_stairs_type.
// 0 means HIDDEN_STAIRS_SECRET_BAZAAR, 1 means HIDDEN_STAIRS_SECRET_ROOM, and
// 255 still means HIDDEN_STAIRS_RANDOM_SECRET_BAZAAR_OR_SECRET_ROOM.
u8 hidden_stairs_type;
u8 hidden_stairs_spawn_chance; // 0x1B
u8 enemy_iq; // 0x1C: IQ stat of enemies
u8 iq_booster_value; // 0x1E: IQ increase from the IQ booster item upon entering the floor
};
// Contains the data required to display a tile on the minimap
struct minimap_display_tile {
u32 field_0x0;
u32 field_0x4;
u32 field_0x8;
u32 field_0x0C;
u32 field_0x10;
u32 field_0x14;
u32 field_0x18;
u32 field_0x1C;
u32 field_0x20;
u32 field_0x24;
u32 field_0x28;
u32 field_0x2C;
u32 field_0x30;
u32 field_0x34;
u32 field_0x38;
u32 field_0x3C;
};
// Contains the graphical representation of minimap tiles
struct minimap_display_data {
// 0x0: Matrix that contains tile display data. Each chunk of 4x4 tiles shares
// a single entry in this matrix. (To calculate which entry corresponds to a
// given (x,y) coordinate, simply divide both x and y by 2 and drop decimals)
struct minimap_display_tile tile_matrix_1[16][28];
// 0x7000: Another matrix just like the first one
struct minimap_display_tile tile_matrix_2[16][28];
// 0xE000: Weird byte matrix.
// The code that initializes this matrix fills 56 bytes
// per row, which seems like an oversight.
// On top of that, starting at 0xE1C0 there's a pointer table that gets overwritten every time
// this matrix is rebuilt, only to be restored later. There's probably
// an union involved somewhere, but right now there's not enough information
// to know where exactly.
u8 field_0xE000[32][28];
u8 overwritten_extra_bytes[28]; // 0xE380
u32 field_0xE39C[41]; // 0xE39C: Array of pointers
u32 field_0xE440;
u8 field_0xE444;
u8 field_0xE445;
u8 field_0xE446;
u8 field_0xE447;
u8 field_0xE448;
// Padding?
u8 field_0xE449;
u8 field_0xE44A;
u8 field_0xE44B;
};
// Struct that seems to hold data related to the map, the camera and the touchscreen numbers
struct display_data {
struct position camera_pos; // 0x0: Position of the tile the camera is currently pointing to
// 0x4: Copy of 0x0. Used to detect changes in the camera's position.
struct position camera_pos_mirror;
// 0x8: Pixel position of the tile the camera is currently pointing to
struct position camera_pixel_pos;
struct position camera_pixel_pos_mirror; // 0xC: Mirror of 0x8
// 0x10: Entity currently being pointed by the camera, mostly used to
// control rendering of the dungeon, GUI, minimap, etc.
struct entity* camera_target;
// 0x14: Appears to be used to determine the offset to render the screen from normal when
// shaking.
u32 screen_shake_offset;
// 0x18: Appears to be the intensity value for when the screen shakes. Decremented by
// 0x1 until 0x0.
u32 screen_shake_intensity;
// 0x1C: Appears to be the value to set to display_data::screen_shake_intensity when it
// reaches 0x0. (This number is usually 0x0 so the screen stops shaking after.)
u32 screen_shake_intensity_reset;
u8 field_0x20; // 0x20: Initialized to 0x3.
// 0x21: Same as floor_properties::visibility_range
// Affects the number of map tiles around the player's position that get marked as
// "visited" while exploring, as well as how far away you can see enemies under non-illuminated
// conditions (outside of this range, enemies will not be visible on screen).
u8 visibility_range;
// 0x22: True if the pokémon currently pointed by the camera has
// the status_id::STATUS_BLINKER effect
bool8 blinded;
// 0x23: True after using a Luminous Orb or in floors where darkness is forcefully disabled
bool8 luminous;
// 0x24: If false and luminous is false as well, darkness will be displayed graphically.
// This is set in dungeons that aren't naturally dark, and also in some fixed room floors.
bool8 natural_lighting;
// 0x25: True if the pokémon currently pointed by the camera has the Map Surveyor IQ skill
// active
bool8 map_surveyor;
// 0x26: True if enemies should be shown on the map.
// Seems to be a dependent property computed as
// (leader has Power Ears status OR leader has X-Ray Specs equipped).
// This is NOT affected by the luminous flag.
bool8 can_see_enemies;
// 0x27: True if items are being shown on the map. Similar to can_see_enemies.
bool8 can_see_items;
// 0x28: True if traps are being shown on the map. Similar to can_see_enemies.
bool8 can_see_traps;
// 0x29: True if the pokémon currently pointed by the camera has the
// status_id::STATUS_CROSS_EYED effect.
// Causes all entities to be displayed as green circles on the map.
bool8 hallucinating;
bool8 can_see_stairs; // 0x2A: True if stairs are being shown on the map
u8 field_0x2B; // 0x2B: Initialized to 0
u8 field_0x2C;
bool8 darkness; // 0x2D: True if there's darkness on the floor
u8 field_0x2E; // 0x2E: Initialized to 1
// 0x2F: True if the leader is being pointed by the camera right now. If false, UI digits will
// be displayed in green.
bool8 leader_pointed;
u8 field_0x30; // 0x30: Initialized to 1
// 0x31: Set to 1 when losing in a dungeon. Seems to cause display_data::0x38 to
// display_data::leader_max_hp_touch_screen to become 0xFFFF (-1).
bool8 unk_fade_to_black_tracker;
u8 field_0x32; // 0x32: Initialized to 0
u8 field_0x33; // 0x33: Initialized to 0
u8 field_0x34; // 0x34: Is used, related to lighting?
bool8 team_menu_or_grid; // 0x35: True when the team menu is opened or while Y is being held
// Derived from internal direction in leader info block
enum direction_id leader_target_direction; // 0x36
enum direction_id leader_target_direction_mirror; // 0x37
u16 field_0x38; // 0x38: Initialized to 0xFFFF (-1).
u16 field_0x3A; // 0x3A: Initialized to 0xFFFF (-1).
s16 floor_touch_screen; // 0x3C: Floor number displayed on the touch screen
s16 leader_level_touch_screen; // 0x3E: Leader's level displayed on the touch screen
s16 leader_hp_touch_screen; // 0x40: Leader's current HP displayed on the touch screen
s16 leader_max_hp_touch_screen; // 0x42: Leader's max HP displayed on the touch screen
u16 field_0x44;
// Padding?
u8 field_0x46;
u8 field_0x47;
};
enum spawn_flags
{
SPAWN_FLAG_STAIRS = 1 << 0, // x1 - This tile has the stairs.
SPAWN_FLAG_ITEM = 1 << 1, // x2 - This tile has an item on it.
SPAWN_FLAG_TRAP = 1 << 2, // x4 - This tile has a trap on it.
SPAWN_FLAG_MONSTER = 1 << 3, // x8 - This tile has a monster on it.
SPAWN_FLAG_SPECIAL_TILE = 1 << 4, // x10 - This is a special tile, such as for Kecleon Shops, items, and traps.
SPAWN_FLAG_UNK5 = 1 << 5, // 0x20 - Not fully understood field relating to Secondary Structures. Set to true for all tiles in secondary structure rooms except for Cross or Dot rooms.
SPAWN_FLAG_UNK6 = 1 << 6, // 0x40 - Not fully understood field. In the dungeon algorithm, it is set to true on a Warp tile.
SPAWN_FLAG_UNK7 = 1 << 7, // 0x80 - Not fully understood field. In the dungeon algorithm, it is set to true for all tiles in a Divider secondary structure room.
};
// These flags seem to occupy the same memory location, so the meaning is context-dependent.
union spawn_or_visibility_flags {
u16 spawn;
// bool8 f_stairs : 1;
// bool8 f_item : 1;
// bool8 f_trap : 1;
// bool8 f_monster : 1;
// u8 spawn_flags_unk4 : 4;
// u8 spawn_flags_unk8 : 8;
u16 visibility;
// If f_revealed == true and f_visited == false, the tile will appear as gray on the map.
// This happens, e.g., when a Luminous Orb is used.
// bool8 f_revealed : 1; // Revealed on the map.
// bool8 f_visited : 1; // Visited by the player
// u8 visibility_flags_unk2 : 6;
// u8 visibility_flags_unk8 : 8;
};
// Information about the rooms on the current floor
struct room_data {
u8 room_id;
u8 field_0x1; // Initialized to 0
struct position bottom_right_corner; // 0x2
struct position top_left_corner; // 0x6
u8 field_0xa; // Doesn't get initialized, likely padding
u8 field_0xb; // Doesn't get initialized, likely padding
u32 field_0xc; // Initialized to (bottom_right_corner.x - 1) * 0x1C
u32 field_0x10; // Initialized to (bottom_right_corner.y - 1) * 0x1C
u32 field_0x14; // Initialized to (top_left_corner.x + 1) * 0x1C
u32 field_0x18; // Initialized to (top_left_corner.y + 1) * 0x1C
};
// Tile data
struct tile {
// 0x0: terrain_flags: 2-byte bitfield
u16 terrain_flags;
// enum terrain_type terrain_type : 2;
// This tile can be corner-cut when walking. Seemingly only used during dungeon generation.
// bool f_corner_cuttable : 1;
// Includes room tiles right next to a hallway, and branching points within corridors.
// Only applies to natural halls, not ones made by Absolute Mover, not "hallways" made of
// secondary terrain, etc. Used by the AI for navigation.
// bool f_natural_junction : 1;
// This tile is impassable, even with Absolute Mover/Mobile Scarf. Used for the map border,
// key chamber walls, walls in boss battle rooms, etc.
// bool f_impassable_wall : 1;
// bool f_in_kecleon_shop : 1; // In a Kecleon Shop
// bool f_in_monster_house : 1; // In a Monster House
// bool terrain_flags_unk7 : 1;
// Cannot be broken by Absolute Mover. Set naturally on key doors.
// bool f_unbreakable : 1;
// Tile is any type of "stairs" (normal stairs, Hidden Stairs, Warp Zone)
// bool f_stairs : 1;
// bool terrain_flags_unk10 : 1;
// bool f_key_door : 1; // Tile is a key door
// bool f_key_door_key_locked : 1; // Key door is locked and requires a Key to open
// Key door is locked and requires an escort to open (for Sealed Chamber missions)
// bool f_key_door_escort_locked : 1;
// bool terrain_flags_unk14 : 1;
// Tile is open terrain but unreachable from the stairs spawn point. Only set during dungeon
// generation.
// bool f_unreachable_from_stairs : 1;
// 0x2: Seems to be used for spawning entities during dungeon generation, and for visibility
// during dungeon play
union spawn_or_visibility_flags spawn_or_visibility_flags;
u16 texture_id; // 0x4: Maybe? Changing this causes the tile texture to change
u8 field_0x6;
// 0x7: Room index. 0xFF if not in a room, 0xFE on junctions during map generation (it gets set
// to 0xFF later).
u8 room;
// 0x8: Where a monster standing on this tile is allowed to move.
// Each element is a bitflag that corresponds to one of the first four values of
// enum mobility_type. Each bit in the bitflag corresponds to the values of enum direction,
// where 1 means a monster with that mobility type is allowed to walk in that direction.
u8 walkable_neighbor_flags[4];
struct entity* monster; // 0xC: Pointer to a monster on this tile, if any
// 0x10: Pointer to an entity other than a monster on this tile (item/trap)
struct entity* object;
};
// Trap info
struct trap {
enum trap_id id;
// If 0 or 2, the trap will activate only when a team member steps on it. If 1, the trap will
// activate only when an enemy steps on it. Naturally, this seems to be 0 for traps and 2 for
// Wonder Tiles
u8 team;
// 0x2: flags: 1-byte bitfield
//u8 flags;
bool8 f_unbreakable : 1; // If true, the trap can't be broken (for example, using a Trapbust Orb)
u8 flags_unk1 : 7;
u8 field_0x3;
};
// Struct that contains some data used when spawning new enemies
struct enemy_spawn_stats {
enum monster_id id; // 0x0
u16 level; // 0x2
// 0x4: Spawn moves. Useless since each individual enemy gets its own when spawning.
enum move_id moves[4];
u16 max_hp; // 0xC
u8 atk; // 0xE
u8 def; // 0xF
u8 sp_atk; // 0x10
u8 sp_def; // 0x11
};
// Contains the necessary information to spawn a Kecleon shopkeeper.
struct spawned_shopkeeper_data {
enum monster_id monster_id; // 0x0: The id of the monster to spawn
enum monster_behavior behavior; // 0x2: NPC behavior of the monster
bool8 valid; // 0x3: Indicates that this spawn data is valid
u8 pos_x; // 0x4
u8 pos_y; // 0x5
};
// Appears to contain diagnostic information related to the damage calculation routines.
struct damage_calc_diag {
enum type_id move_type; // 0x0: The type of the last move used
u8 field_0x1;
u8 field_0x2;
u8 field_0x3;
enum move_category move_category; // 0x4: The category of the last move used
// 0x8: The type matchup of the last move used against the individual types of the defender
enum type_matchup move_indiv_type_matchups[2];
// 0xA: The modified offensive stat stage of the attacker for the last move used
u8 offensive_stat_stage;
// 0xB: The modified defensive stat stage of the defender for the last move used
u8 defensive_stat_stage;
// 0xC: The base offensive stat of the attacker for the last move used
u16 offensive_stat;
// 0xE: The base defensive stat of the defender for the last move used
u16 defensive_stat;
// 0x10: The Flash Fire boost of the attacker when a Fire move was last used
u16 flash_fire_boost;
// 0x12: The modified offense value calculated for the attacker for the last move used,
// prior to being clamped between 0 and 999
u16 offense_calc;
// 0x14: The modified defense value calculated for the defender for the last move used
u16 defense_calc;
u16 attacker_level; // 0x16: The level of the attacker for the last move used
// 0x18: The intermediate quantity in the damage calculation called "AT" in debug logging,
// which corresponds to: round[ min(max(offense_calc, 0), 999) + power_calc ],
// where power_calc is a modified move power calculated as (intermediate rounding omitted):
// GetMovePower(...) * (offensive stat stage multipliers) * (offensive multipliers)
u16 damage_calc_at;
// 0x1A: An identical copy of defense_calc. This is probably a relic of development,
// when the final defense contribution to the damage formula might have been a different
// quantity computed from defense_calc, like how damage_calc_at is computed
// from offense_calc
u16 damage_calc_def;
// 0x1C: The intermediate quantity in the damage calculation called "FLV" in debug logging
// (effective level?), which corresponds to: round[ (offense_calc - defense_calc)/8 + level ]
u16 damage_calc_flv;
u8 field_0x1e;
u8 field_0x1f;
// 0x20: The result of the damage calculation after multiplying the base value by multipliers,
// but before applying random variation. There are also a couple stray multipliers applied
// after this result, including multipliers specific to the projectile move (the static 50%,
// and the Power Pitcher multiplier) and the Air Blade multiplier.
s32 damage_calc;
// 0x24: The intermediate quantity in the damage calculation resulting from the "base" damage
// calculation: the sum of the power, attack, defense, and level terms, modified by the
// non-team-member multiplier if relevant, and clamped between 1 and 999.
s32 damage_calc_base;
// 0x28: The random multiplier applied to the result of the damage calculation, as a
// percentage (so the actual factor, multiplied by 100), rounded to an integer.
s32 damage_calc_random_mult_pct;
// 0x2C: The calculated "static" damage multiplier applied to the output of the base damage
// calculation. "Static" in the sense that this part of the multiplier doesn't depend on
// variables like type-based effects, critical hits, and Reflect/Light Screen. Factors in
// the static damage multiplier include the argument to CalcDamage, the multiplier due to
// monster::me_first_flag, Reckless, and Iron Fist.
s32 static_damage_mult;
// 0x30: The net number of attack boosts to an attacker due to a Power Band or Munch Belt.
// It seems like there's a bug in the code; aura bows do not contribute to this field.
s8 item_atk_modifier;
// 0x31: The net number of special attack boosts to an attacker due to a Special Band,
// Munch Belt, or aura bow. It seems like there's a bug in the code; physical attack boosts
// from aura bows also contribute to this field.
s8 item_sp_atk_modifier;
// 0x32: The net number of offense boosts to an attacker due to Download, Rivalry,
// Flower Gift, and Solar Power
s8 ability_offense_modifier;
// 0x33: The net number of defense boosts to a defender due to Flower Gift
s8 ability_defense_modifier;
// 0x34: The net number of offense boosts to an attacker due to Aggressor, Defender, and
// Practice Swinger
s8 iq_skill_offense_modifier;
// 0x35: The net number of defense boosts to a defender due to Counter Basher, Aggressor, and
// Defender
s8 iq_skill_defense_modifier;
// 0x36: The net number of defense boosts to a defender due to a Def Scarf or aura bow.
// It seems like there's a bug in the code; special defense boosts from aura bows also
// contribute to this field.
s8 item_def_modifier;
// 0x37: The net number of special defense boosts to a defender due to a Zinc Band.
// It seems like there's a bug in the code; aura bows do not contribute to this field.
s8 item_sp_def_modifier;
// 0x38: Whether or not Scope Lens or Sharpshooter boosted the critical hit rate of a move
bool8 scope_lens_or_sharpshooter_activated;
// 0x39: Whether or not the Patsy Band boosted the critical hit rate of a move
bool8 patsy_band_activated;
// 0x3A: Whether or not Reflect or the Time Shield halved the damage from a physical move
bool8 half_physical_damage_activated;
// 0x3B: Whether or not Light Screen or the Aqua Mantle halved the damage from a special move
bool8 half_special_damage_activated;
// 0x3C: Whether or not the Enhanced critical-hit rate status maxed out the critical hit rate
// of a move
bool8 focus_energy_activated;
// 0x3D: Whether or not Type-Advantage Master boosted the critical hit rate of a move
bool8 type_advantage_master_activated;
// 0x3E: Whether or not a non-Normal-type move was dampened by Cloudy weather
bool8 cloudy_drop_activated;
// 0x3F: Whether or not a Fire or Water move was affected by Rainy weather
bool8 rain_multiplier_activated;
// 0x40: Whether or not a Fire or Water move was affected by Sunny weather
bool8 sunny_multiplier_activated;
// 0x41: Whether or a Fire move was dampened by Thick Fat or Heatproof
bool8 fire_move_ability_drop_activated;
// 0x42: Whether or not Flash Fire was activated at some point for Fire immunity
bool8 flash_fire_activated;
// 0x43: Whether or not Levitate was activated at some point for Ground immunity
bool8 levitate_activated;
bool8 torrent_boost_activated; // 0x44: Whether or not a Water move was boosted by Torrent
bool8 overgrow_boost_activated; // 0x45: Whether or not a Grass move was boosted by Overgrow
bool8 swarm_boost_activated; // 0x46: Whether or not a Bug move was boosted by Swarm
// 0x47: Whether or not a Fire move was boosted by either Blaze or Dry Skin
bool8 fire_move_ability_boost_activated;
// 0x48: Whether or not Scrappy was activated at some point to bypass immunity
bool8 scrappy_activated;
// 0x49: Whether or not Super Luck boosted the critical hit rate for a move
bool8 super_luck_activated;
// 0x4A: Whether or not Sniper boosted the critical hit damage multiplier for a move
bool8 sniper_activated;
bool8 stab_boost_activated; // 0x4B: Whether or not STAB was activated for a move
// 0x4C: Whether or not an Electric move was dampened by either Mud Sport or Fog
bool8 electric_move_dampened;
// 0x4D: Whether or not Water Sport was activated by a Fire move
bool8 water_sport_drop_activated;
bool8 charge_boost_activated; // 0x4E: Whether or not Charge was activated by an Electric move
u8 field_0x4f;
// 0x50: Whether or not a Ghost type's immunity to Normal/Fighting was activated at some point
bool8 ghost_immunity_activated;
// 0x51: Whether or not a defender took less damage due to the Charging Skull Bash status
bool8 skull_bash_defense_boost_activated;
u8 field_0x52;
u8 field_0x53;
};
#endif //PMDSKY_DUNGEON_MODE_H