diff --git a/include/structs/dungeon_entity.h b/include/structs/dungeon_entity.h index f395a81e5..92cf0a06b 100644 --- a/include/structs/dungeon_entity.h +++ b/include/structs/dungeon_entity.h @@ -38,9 +38,9 @@ typedef struct ActionContainer /* 0x0 */ u16 action; /* 0x2 */ u8 direction; u8 fill3; - // Additional parameter alongside actionIndex. Used for things like indicating which move a PokĂ©mon should use from its moveset. + // Additional parameter alongside actionIndex. Used for things like indicating which move a Pokémon should use from its moveset. /* 0x4 */ unkStruct_8044CC8 unk4[2]; - // Position of the target that the PokĂ©mon wants throw an item at. + // Position of the target that the Pokémon wants throw an item at. /* 0x14 */ Position itemTargetPosition; } ActionContainer; @@ -101,7 +101,7 @@ typedef struct Charging { /* 0x0 */ u8 chargingStatus; /* 0x1 */ u8 chargingStatusTurns; - /* 0x2 */ u8 chargingStatusMoveIndex; // The position of the move in the PokĂ©mon's moveset that triggered the status. + /* 0x2 */ u8 chargingStatusMoveIndex; // The position of the move in the Pokémon's moveset that triggered the status. } Charging; typedef struct Protection @@ -113,7 +113,7 @@ typedef struct Protection typedef struct Waiting { /* 0xC8 */ u8 waitingStatus; - /* 0xC9 */ bool8 enemyDecoy; // True if the PokĂ©mon is a decoy and a wild PokĂ©mon (i.e., not an allied PokĂ©mon). + /* 0xC9 */ bool8 enemyDecoy; // True if the Pokémon is a decoy and a wild Pokémon (i.e., not an allied Pokémon). u8 unkCA; /* 0xCB */ u8 waitingStatusTurns; /* 0xCC */ u8 curseDamageCountdown; @@ -162,10 +162,10 @@ typedef struct Unk_Entity_x184 { /* 0x184 - 0x0 */ Position previousTargetMovePosition1; /* 0x188 - 0x4 */ Position32 previousTargetMovePosition2; - /* 0x190 - 0xC */ s32 lastMoveDirection; // The last direction that the PokĂ©mon moved in. - // Number of tiles that the PokĂ©mon moved last, multiplied by 0x100. + /* 0x190 - 0xC */ s32 lastMoveDirection; // The last direction that the Pokémon moved in. + // Number of tiles that the Pokémon moved last, multiplied by 0x100. /* 0x194 - 0x10*/ Position32 lastMoveIncrement; - /* 0x19C - 0x18 */ s16 walkAnimFramesLeft; // Set when the PokĂ©mon starts moving, and counts down until the PokĂ©mon's walk animation stops. + /* 0x19C - 0x18 */ s16 walkAnimFramesLeft; // Set when the Pokémon starts moving, and counts down until the Pokémon's walk animation stops. /* 0x19e - 0x1a */ u8 unk1A; } Unk_Entity_x184 ; @@ -178,14 +178,14 @@ typedef struct Moves // size: 0x208 typedef struct EntityInfo { - // This has different purposes for PokĂ©mon, items, and traps. + // This has different purposes for Pokémon, items, and traps. // Pokemon: MovementFlag // Items: ItemFlag // Traps: TrapType /* 0x0 */ u16 flags; - /* 0x2 */ s16 id; // PokĂ©mon species or item ID. - // Everything from here on only applies to PokĂ©mon. - /* 0x4 */ s16 apparentID; // Shows a different PokĂ©mon when using Transform. + /* 0x2 */ s16 id; // Pokémon species or item ID. + // Everything from here on only applies to Pokémon. + /* 0x4 */ s16 apparentID; // Shows a different Pokémon when using Transform. /* 0x6 */ bool8 isNotTeamMember; /* 0x7 */ bool8 isTeamLeader; /* 0x8 */ u8 shopkeeper; @@ -196,10 +196,8 @@ typedef struct EntityInfo /* 0x10 */ s16 maxHPStat; // Bosses have higher HP than normal for their level. This is the max HP they would normally have given their level. /* 0x12 */ s16 originalHP; - /* 0x14 */ u8 atk; - /* 0x15 */ u8 spAtk; - /* 0x16 */ u8 def; - /* 0x17 */ u8 spDef; + /* 0x14 */ u8 atk[2]; // Index 0 is Attack. Index 1 is Special Attack. + /* 0x16 */ u8 def[2]; // Index 0 is Defense. Index 1 is Special Defense. /* 0x18 */ u32 exp; // Temporary stat boosts/drops from effects like Growl or Swords Dance. // These start at 10 and are in the range [1, 19]. @@ -209,7 +207,7 @@ typedef struct EntityInfo /* 0x20 */ s16 defensiveStages[2]; // Index 0 is accuracy. Index 1 is evasion. /* 0x24 */ s16 hitChanceStages[2]; - // // When a Fire-type move is used on a PokĂ©mon with Flash Fire, this value increases the power of the PokĂ©mon's Fire-type moves. + // // When a Fire-type move is used on a Pokémon with Flash Fire, this value increases the power of the Pokémon's Fire-type moves. /* 0x28 */ s16 flashFireBoost; // These start at 0x1000, and are halved by certain moves like Screech to lower the corresponding stat. // Index 0 is Attack. Index 1 is Special Attack. @@ -260,32 +258,32 @@ typedef struct EntityInfo /* 0xF7 */ bool8 bossFlag; /* 0xF8 */ bool8 speedStageChanged; // Toggled when pokemon is movement speed is sped up /* 0xF9 */ u8 unkF9; - /* 0xFA */ u8 terrifiedTurns; // Doubles as a bool for whether the PokĂ©mon is terrified. + /* 0xFA */ u8 terrifiedTurns; // Doubles as a bool for whether the Pokémon is terrified. /* 0xFB */ u8 expMultiplier; // Set to true if the player makes a teammate use their held item. // This is done by going to the teammate's held item in the toolbox and selecting "Use". /* 0xFC */ bool8 useHeldItem; - /* 0xFD */ u8 perishSongTurns; // When this reaches 0, the PokĂ©mon faints from Perish Song. Doubles as a bool for whether the PokĂ©mon is afflicted by Perish Song. + /* 0xFD */ u8 perishSongTurns; // When this reaches 0, the Pokémon faints from Perish Song. Doubles as a bool for whether the Pokémon is afflicted by Perish Song. u8 unkFE; u8 unkFF; - /* 0x100 */ u8 targetingDecoy; // If the PokĂ©mon is targeting a decoy, this indicates whether the decoy target is a team or wild PokĂ©mon. + /* 0x100 */ u8 targetingDecoy; // If the Pokémon is targeting a decoy, this indicates whether the decoy target is a team or wild Pokémon. /* 0x104 */ s32 speedStage; - // The turn counter for movement speed up/down is split into five timers each. Multiple timers are used if the PokĂ©mon is affected by multiple + // The turn counter for movement speed up/down is split into five timers each. Multiple timers are used if the Pokémon is affected by multiple // speed-up/slow effects at once, like using Agility twice. /* 0x108 */ u8 speedUpCounters[NUM_SPEED_COUNTERS]; /* 0x10D */ u8 speedDownCounters[NUM_SPEED_COUNTERS]; /* 0x112 */ u8 stockpileStage; /* 0x113 */ u8 unk113; - // When non-zero, an AI PokĂ©mon will move in a random direction every turn when it is a room. - // There is a chance of this flag being set when a wild PokĂ©mon spawns. The chance depends on the dungeon's randomMovementChance. + // When non-zero, an AI Pokémon will move in a random direction every turn when it is a room. + // There is a chance of this flag being set when a wild Pokémon spawns. The chance depends on the dungeon's randomMovementChance. /* 0x114 */ u32 moveRandomly; /* 0x118 */ Moves moves; /* 0x13C */ FixedPoint belly; /* 0x140 */ FixedPoint maxBelly; - /* 0x144 */ bool8 aiNextToTarget; // True if an AI PokĂ©mon is following another PokĂ©mon and is already adjacent to them. - /* 0x145 */ bool8 recalculateFollow; // Used by the AI to defer a movement decision until after all other PokĂ©mon have moved. + /* 0x144 */ bool8 aiNextToTarget; // True if an AI Pokémon is following another Pokémon and is already adjacent to them. + /* 0x145 */ bool8 recalculateFollow; // Used by the AI to defer a movement decision until after all other Pokémon have moved. /* 0x146 */ u8 unk146; - /* 0x147 */ bool8 waiting; // True if an AI PokĂ©mon decided to do nothing this turn. + /* 0x147 */ bool8 waiting; // True if an AI Pokémon decided to do nothing this turn. /* 0x148 */ bool8 attacking; /* 0x149 */ u8 unk149; /* 0x14A */ u8 unk14A; @@ -326,13 +324,13 @@ typedef struct EntityInfo /* 0x1F4 */ s16 numMoveTiles; // Number of tiles to move in a turn. Can be greater than 1 if the user's movement speed is boosted. /* 0x1F6 */ s16 notMoving; /* 0x1F8 */ s16 unk1F8; - /* 0x1FA */ s16 mobileTurnTimer; // 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. + /* 0x1FA */ s16 mobileTurnTimer; // 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. /* 0x1FC */ u32 expGainedInTurn; // Used to accumulate experience when multiple enemies are defeated in one turn. /* 0x200 */ u32 statusIcons; u8 unk204; } EntityInfo; -// size: 0x74 | Used for PokĂ©mon, items, and traps. +// size: 0x74 | Used for Pokémon, items, and traps. typedef struct Entity { /* 0x0 */ u32 type; @@ -343,13 +341,13 @@ typedef struct Entity /* 0xC */ Position32 pixelPos; /* 0x14 */ Position32 prevPixelPos; s32 unk1C; - /* 0x20 */ bool8 isVisible; // Turned off when a PokĂ©mon faints. + /* 0x20 */ bool8 isVisible; // Turned off when a Pokémon faints. u8 fill21; u8 unk22; u8 fill23; u8 unk24; /* 0x25 */ u8 room; - // The global spawn index counter starts at 10. Each PokĂ©mon that spawns increments the counter and + // The global spawn index counter starts at 10. Each Pokémon that spawns increments the counter and // gets assigned the current counter value as its spawn index. /* 0x26 */ u16 spawnGenID; /* 0x28 */ struct axObject axObj; @@ -370,7 +368,7 @@ enum MovementFlag MOVEMENT_FLAG_SWAPPING_PLACES = 1 << 5, MOVEMENT_FLAG_WALKING = 1 << 9, MOVEMENT_FLAG_UNK_14 = 1 << 14, - MOVEMENT_FLAG_SWAPPING_PLACES_PETRIFIED_ALLY = 1 << 15 // Set if the PokĂ©mon is petrified and the leader cures them by swapping places. + MOVEMENT_FLAG_SWAPPING_PLACES_PETRIFIED_ALLY = 1 << 15 // Set if the Pokémon is petrified and the leader cures them by swapping places. }; enum AbilityEffectFlags @@ -421,7 +419,7 @@ enum ClientType enum VisualFlag { // Set if Run Away's visual effect (green smoke cloud) has been triggered on this floor. - // Prevents the effect from showing again if the PokĂ©mon stops running away and then starts running away again. + // Prevents the effect from showing again if the Pokémon stops running away and then starts running away again. VISUAL_FLAG_RUN_AWAY = 2 }; diff --git a/src/code_8069D4C.c b/src/code_8069D4C.c index 2ef7cdac6..08a1a25e5 100644 --- a/src/code_8069D4C.c +++ b/src/code_8069D4C.c @@ -33,10 +33,10 @@ void sub_8069D4C(struct unkStruct_8069D4C *r0, Entity *target) GetPokemonLevelData(&leveldata, info->id, info->level); r0->exp = leveldata.expRequired; - r0->offense.att[0] = info->atk; - r0->offense.att[1] = info->spAtk; - r0->offense.def[0] = info->def; - r0->offense.def[1] = info->spDef; + r0->offense.att[0] = info->atk[0]; + r0->offense.att[1] = info->atk[1]; + r0->offense.def[0] = info->def[0]; + r0->offense.def[1] = info->def[1]; r0->heldItem = info->heldItem; memcpy(r0->moves.moves, info->moves.moves, sizeof(r0->moves)); r0->belly = info->belly; diff --git a/src/code_806E8B0.c b/src/code_806E8B0.c index c00a53ce3..2eef6af38 100644 --- a/src/code_806E8B0.c +++ b/src/code_806E8B0.c @@ -5,6 +5,21 @@ #include "status_checks_1.h" #include "text_util.h" #include "dungeon_message.h" +#include "string_format.h" +#include "type_effectiveness.h" +#include "constants/move_id.h" +#include "constants/monster.h" +#include "constants/status.h" +#include "constants/type.h" +#include "constants/iq_skill.h" +#include "math.h" +#include "number_util.h" +#include "status.h" +#include "type_chart.h" +#include "dungeon_random.h" +#include "code_8045A00.h" +#include "dungeon_items.h" +#include "structs/str_damage.h" extern u8 *gUnknown_80FEE04[]; extern u8 *gUnknown_80FEE2C[]; @@ -121,3 +136,282 @@ void sub_806E8B0(Entity * pokemon, Entity * target, u8 param_3, s32 *param_4, s3 *param_5 = *param_5 / sp_0x8; } } + +extern void sub_806F500(void); +extern void sub_800A020(struct unkStruct_80943A8 *param_1, u32 param_2); +extern void sub_800A3F0(struct unkStruct_80943A8 *param_1, struct unkStruct_80943A8 *param_2, struct unkStruct_80943A8 *); +extern void sub_800A6D0(struct unkStruct_80943A8 *param_1, struct unkStruct_80943A8 *param_2, struct unkStruct_80943A8 *); +extern void sub_800A34C(struct unkStruct_80943A8 *param_1, struct unkStruct_80943A8 *param_2, const struct unkStruct_80943A8 *param3); +extern void sub_800A6F0(struct unkStruct_80943A8 *param_1, struct unkStruct_80943A8 *param_2, struct unkStruct_80943A8 *param3); +extern void sub_800A088(struct unkStruct_80943A8 *param_1, u32 param_2); +extern u32 sub_800A048(struct unkStruct_80943A8 *param_1); +extern bool8 sub_800A2F0(const struct unkStruct_80943A8*, struct unkStruct_80943A8*); +extern bool8 sub_806E100(struct unkStruct_80943A8 *param_1, Entity *pokemon, Entity *target, u8 type, struct DamageStruct *dmgStruct); +extern void sub_8041B74(Entity *pokemon); +extern void sub_8041B5C(Entity *pokemon); + +extern const s32 gUnknown_80F504C[]; +extern const s16 gUnknown_810AC60; +extern const s16 gUnknown_810AC68; +extern const s16 gUnknown_810AC64; +extern const s16 gUnknown_810AC66; +extern const s16 gUnknown_810AC68; +extern const s16 gUnknown_810AC62; +extern const s16 gUnknown_80F4DAE; +extern const s16 gUnknown_80F4DB0; +extern const struct unkStruct_80943A8 gUnknown_8106F24; +extern const struct unkStruct_80943A8 gUnknown_8106F04; +extern const struct unkStruct_80943A8 gUnknown_8106F1C; +extern const struct unkStruct_80943A8 gUnknown_8106F14; +extern const u8 *const gUnknown_80FAE00; +extern const u8 *const gUnknown_80FADD8; + +void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u32 critChance, struct DamageStruct *dmgStruct, u32 arg_8, u16 moveId, bool8 arg_10) +{ + EntityInfo *attackerInfo = GetEntInfo(attacker); + EntityInfo *targetInfo = GetEntInfo(target); + bool32 physicalMove = (IsTypePhysical(moveType) != FALSE); + + sub_806F500(); + if (!attackerInfo->isTeamLeader && FixedPointToInt(attackerInfo->belly) == 0) { + dmgStruct->dmg = 1; + dmgStruct->residualDmgType = 0; + dmgStruct->typeEffectiveness = EFFECTIVENESS_NEUTRAL; + dmgStruct->type = moveType; + dmgStruct->isCrit = FALSE; + dmgStruct->unkE = 0; + dmgStruct->unkF = 0; + } + else if (moveId == MOVE_REGULAR_ATTACK && HasAbility(target, ABILITY_WONDER_GUARD)) { + dmgStruct->dmg = 1; + dmgStruct->residualDmgType = 0; + dmgStruct->typeEffectiveness = EFFECTIVENESS_NEUTRAL; + dmgStruct->type = moveType; + dmgStruct->isCrit = FALSE; + dmgStruct->unkE = 0; + dmgStruct->unkF = 0; + } + else { + s32 atkStatStage, defStatStage; + s32 atkStatCalc, defStatCalc; + s32 atkStat, defStat; + s32 rand; + struct unkStruct_80943A8 unkSp1; + struct unkStruct_80943A8 unkSp2; + struct unkStruct_80943A8 unkSp3; + s32 r6; + s32 unkAtkStat2, unkDefStat2; + struct unkStruct_80943A8 unkSp4; + struct unkStruct_80943A8 unkSp5; + struct unkStruct_80943A8 unkSp6; + struct unkStruct_80943A8 unkSp7; + struct unkStruct_80943A8 unkSp8; + struct unkStruct_80943A8 unkSp9; + struct unkStruct_80943A8 unkSp10; + struct unkStruct_80943A8 unkSp11; + bool8 r5; + + dmgStruct->type = moveType; + gDungeon->unk134.unk134 = moveType; + gDungeon->unk134.unk138 = physicalMove; + + atkStatStage = attackerInfo->offensiveStages[physicalMove]; + if (arg_10 && moveType == TYPE_FIRE) { + atkStatStage += attackerInfo->flashFireBoost; + gDungeon->unk134.unk140[2] = attackerInfo->flashFireBoost; + } + if (attackerInfo->apparentID == MONSTER_DEOXYS_ATTACK) { + atkStatStage += 2; + } + if (attackerInfo->apparentID == MONSTER_DEOXYS_DEFENSE) { + atkStatStage -= 2; + } + if (attackerInfo->apparentID == MONSTER_DEOXYS_SPEED) { + atkStatStage -= 2; + } + + if (atkStatStage < 0) atkStatStage = 0; + if (atkStatStage > 20) atkStatStage = 20; + + gDungeon->unk134.unk13E[0] = atkStatStage; + gDungeon->unk134.unk140[0] = attackerInfo->atk[physicalMove] + movePower; + atkStatCalc = s24_8_mul((attackerInfo->atk[physicalMove] + movePower) * 256, gUnknown_80F504C[atkStatStage]); + atkStatCalc = s24_8_mul(atkStatCalc, attackerInfo->offensiveMultipliers[physicalMove]); + atkStat = atkStatCalc / 8; + + defStatStage = targetInfo->defensiveStages[physicalMove]; + if (targetInfo->charging.chargingStatus == STATUS_SKULL_BASH) { + gDungeon->unk134.unk17A = 1; + defStatStage++; + } + if (targetInfo->apparentID == MONSTER_DEOXYS_ATTACK) { + defStatStage -= 2; + } + if (targetInfo->apparentID == MONSTER_DEOXYS_DEFENSE) { + defStatStage += 2; + } + if (attackerInfo->apparentID == MONSTER_DEOXYS_SPEED) { + defStatStage -= 2; + } + + if (defStatStage < 0) defStatStage = 0; + if (defStatStage > 20) defStatStage = 20; + + gDungeon->unk134.unk13E[1] = defStatStage; + gDungeon->unk134.unk140[1] = targetInfo->def[physicalMove]; + defStatCalc = s24_8_mul((targetInfo->def[physicalMove]) * 256, gUnknown_80F504C[defStatStage]); + defStatCalc = s24_8_mul(defStatCalc, targetInfo->defensiveMultipliers[physicalMove]); + defStat = defStatCalc / 8; + + rand = DungeonRandInt(100); + if (physicalMove) { + if (HasHeldItem(attacker, ITEM_POWER_BAND)) { + atkStat += gUnknown_810AC60; + gDungeon->unk134.unk160 += gUnknown_810AC60; + } + if (HasHeldItem(attacker, ITEM_MUNCH_BELT)) { + atkStat += gUnknown_810AC68; + gDungeon->unk134.unk160 += gUnknown_810AC68; + } + if (arg_10 && HasHeldItem(target, ITEM_DEF_SCARF)) { + defStat += gUnknown_810AC64; + gDungeon->unk134.unk162 += gUnknown_810AC64; + } + } + else { + if (arg_10 && HasHeldItem(target, ITEM_ZINC_BAND)) { + defStat += gUnknown_810AC66; + gDungeon->unk134.unk163 += gUnknown_810AC66; + } + if (HasHeldItem(attacker, ITEM_SPECIAL_BAND)) { + atkStat += gUnknown_810AC62; + gDungeon->unk134.unk161 += gUnknown_810AC62; + } + if (HasHeldItem(attacker, ITEM_MUNCH_BELT)) { + atkStat += gUnknown_810AC68; + gDungeon->unk134.unk161 += gUnknown_810AC68; + } + } + + gDungeon->unk134.unk140[3] = atkStat; + gDungeon->unk134.unk140[4] = defStat; + if (atkStat < 0) atkStat = 0; + if (atkStat >= 999) atkStat = 999; + + attackerInfo->previousVisualFlags &= ~(0x100); + attackerInfo->visualFlags &= ~(0x100); + sub_806E8B0(attacker, target, moveType, &atkStat, &defStat, rand); + sub_800A020(&unkSp1, atkStat - defStat); + sub_800A020(&unkSp2, 8); + sub_800A3F0(&unkSp1, &unkSp1, &unkSp2); + if (attackerInfo->isNotTeamMember) { + sub_800A020(&unkSp2, attackerInfo->teamIndex); + unkSp3.s0 = 0; + unkSp3.s4 = 0xAAAA; + sub_800A34C(&unkSp2, &unkSp2, &unkSp3); + r6 = (attackerInfo->teamIndex * 2) / 3; + } + else { + unkAtkStat2 = attackerInfo->atk[physicalMove]; + unkDefStat2 = 1; + sub_806E8B0(attacker, target, moveType, &unkAtkStat2, &unkDefStat2, rand); + sub_800A020(&unkSp2, unkAtkStat2); + sub_800A020(&unkSp3, 3); + sub_800A3F0(&unkSp2, &unkSp2, &unkSp3); + r6 = unkAtkStat2 / 3; + } + sub_800A6D0(&unkSp4, &unkSp1, &unkSp2); + gDungeon->unk134.unk140[5] = r6; + gDungeon->unk134.unk140[6] = sub_800A048(&unkSp1); + unkSp5 = unkSp4; + unkSp7 = unkSp4; + sub_800A34C(&unkSp5, &unkSp5, &unkSp5); + unkSp6.s0 = 0; + unkSp6.s4 = 0xCCC; + sub_800A34C(&unkSp5, &unkSp5, &unkSp6); + sub_800A020(&unkSp6, 2); + sub_800A34C(&unkSp7, &unkSp7, &unkSp6); + sub_800A020(&unkSp6, defStat); + sub_800A6F0(&unkSp7, &unkSp7, &unkSp6); + sub_800A020(&unkSp6, 10); + sub_800A6D0(&unkSp8, &unkSp5, &unkSp6); + if (sub_800A2F0(&gUnknown_8106F24, &unkSp8)) { + unkSp8 = gUnknown_8106F24; + } + if (sub_800A2F0(&gUnknown_8106F04, &unkSp8)) { + unkSp8 = gUnknown_8106F04; + } + r5 = sub_806E100(&unkSp9, attacker, target, moveType, dmgStruct); + + if (moveType == TYPE_FIRE) { + s32 flashFireStatus = GetFlashFireStatus(target); + if (flashFireStatus != FLASH_FIRE_STATUS_NONE && targetInfo->unk152 == 0 && arg_10) { + targetInfo->unk152 = 1; + SetMessageArgument(gFormatBuffer_Monsters[1], target, 0); + if (flashFireStatus == FLASH_FIRE_STATUS_MAXED) { + TryDisplayDungeonLoggableMessage3(attacker, target, gUnknown_80FAE00); // Fire moves won't become stronger! + } + else { + TryDisplayDungeonLoggableMessage3(attacker, target, gUnknown_80FADD8); // m1 used Flash Fire to absorb fire! + } + } + } + if (arg_10 && !physicalMove && targetInfo->protection.protectionStatus == STATUS_REFLECT) { + sub_8041B74(target); + sub_800A34C(&unkSp9, &unkSp9, &gUnknown_8106F1C); + gDungeon->unk134.unk166 = 1; + } + if (arg_10 && physicalMove == TRUE && targetInfo->protection.protectionStatus == STATUS_LIGHT_SCREEN) { + sub_8041B5C(target); + sub_800A34C(&unkSp9, &unkSp9, &gUnknown_8106F1C); + gDungeon->unk134.unk167 = 1; + } + // Check crit + if (!HasAbility(target, ABILITY_BATTLE_ARMOR) && !HasAbility(target, ABILITY_SHELL_ARMOR)) { + s32 critOdds = (attackerInfo->isNotTeamMember) ? critChance : 0; + if (attackerInfo->moveStatus.moveStatus == STATUS_FOCUS_ENERGY) { + critOdds = 999; + gDungeon->unk134.unk168 = 1; + } + else { + if (HasHeldItem(attacker, ITEM_SCOPE_LENS)) { + critOdds += gUnknown_80F4DAE; + gDungeon->unk134.unk164 = 1; + } + if (HasHeldItem(attacker, ITEM_PATSY_BAND)) { + critOdds += gUnknown_80F4DAE; + gDungeon->unk134.unk165 = 1; + } + if (r5 && IQSkillIsEnabled(attacker, IQ_TYPE_ADVANTAGE_MASTER)) { + critOdds += gUnknown_80F4DB0; + gDungeon->unk134.unk169 = 1; + } + } + if (DungeonRandInt(100) < critOdds) { + sub_800A34C(&unkSp9, &unkSp9, &gUnknown_8106F14); + dmgStruct->isCrit = TRUE; + } + } + + gDungeon->unk134.unk154 = sub_800A048(&unkSp8); + sub_800A34C(&unkSp8, &unkSp8, &unkSp9); + gDungeon->unk134.unk15C = arg_8; + sub_800A088(&unkSp10, arg_8); + sub_800A34C(&unkSp8, &unkSp8, &unkSp10); + gDungeon->unk134.unk150 = sub_800A048(&unkSp8); + { + s32 rnd = DungeonRandInt(0x4000); + unkSp9.s0 = 0; + unkSp9.s4 = 0xE000 + rnd; + } + sub_800A34C(&unkSp8, &unkSp8, &unkSp9); + sub_800A020(&unkSp11, 100); + sub_800A34C(&unkSp9, &unkSp11, &unkSp9); + gDungeon->unk134.unk158 = sub_800A048(&unkSp9); + dmgStruct->dmg = sub_800A048(&unkSp8); + dmgStruct->residualDmgType = 0; + if (dmgStruct->dmg == 0) { + dmgStruct->isCrit = FALSE; + } + } +} diff --git a/src/code_80718D8.c b/src/code_80718D8.c index 4865f5e23..264fefc83 100644 --- a/src/code_80718D8.c +++ b/src/code_80718D8.c @@ -514,10 +514,10 @@ void sub_8072008(Entity *pokemon, Entity *target, s32 level, u8 param_4, u8 para GetAvailTacticsforLvl_Bool(tacticsBuffer1,info->level); } maxHP = info->maxHPStat; - atk[0] = info->atk; - atk[1] = info->spAtk; - def[0] = info->def; - def[1] = info->spDef; + atk[0] = info->atk[0]; + atk[1] = info->atk[1]; + def[0] = info->def[0]; + def[1] = info->def[1]; if (!IsClientOrTeamBase(info->joinedAt.joinedAt)) { newLevel = info->level + level; if (99 < newLevel) { @@ -529,10 +529,10 @@ void sub_8072008(Entity *pokemon, Entity *target, s32 level, u8 param_4, u8 para flag |= (sub_80723D0(pokemon,target,param_4,param_5)); if ((flag != 0) && (!info->isNotTeamMember)) { gFormatArgs[0] = info->maxHPStat - maxHP; - gFormatArgs[1] = info->atk - atk[0]; - gFormatArgs[2] = info->def - def[0]; - gFormatArgs[3] = info->spAtk - atk[1]; - gFormatArgs[4] = info->spDef - def[1]; + gFormatArgs[1] = info->atk[0] - atk[0]; + gFormatArgs[2] = info->def[0] - def[0]; + gFormatArgs[3] = info->atk[1] - atk[1]; + gFormatArgs[4] = info->def[1] - def[1]; if (param_4 != 0) { sub_807218C(target); } @@ -734,10 +734,10 @@ bool8 sub_80723D0(Entity *pokemon, Entity *target, u8 param_3, u8 param_4) info->HP = info->maxHPStat; } - gUnknown_202F31C[0] = info->atk; - gUnknown_202F31C[1] = info->spAtk; - gUnknown_202F324[0] = info->def; - gUnknown_202F324[1] = info->spDef; + gUnknown_202F31C[0] = info->atk[0]; + gUnknown_202F31C[1] = info->atk[1]; + gUnknown_202F324[0] = info->def[0]; + gUnknown_202F324[1] = info->def[1]; gUnknown_202F31C[0] += leveldata.gainAtt; gUnknown_202F31C[1] += leveldata.gainSPAtt; @@ -757,10 +757,10 @@ bool8 sub_80723D0(Entity *pokemon, Entity *target, u8 param_3, u8 param_4) LoadIQSkills(target); sub_8079764(target); - info->atk = gUnknown_202F31C[0]; - info->spAtk = gUnknown_202F31C[1]; - info->def = gUnknown_202F324[0]; - info->spDef = gUnknown_202F324[1]; + info->atk[0] = gUnknown_202F31C[0]; + info->atk[1] = gUnknown_202F31C[1]; + info->def[0] = gUnknown_202F324[0]; + info->def[1] = gUnknown_202F324[1]; sub_8072778(pokemon, target, param_3, param_4); } @@ -828,10 +828,10 @@ bool8 sub_80725A4(Entity *pokemon, Entity *target) info->HP = info->maxHPStat; } - gUnknown_202F31C[0] = info->atk; - gUnknown_202F31C[1] = info->spAtk; - gUnknown_202F324[0] = info->def; - gUnknown_202F324[1] = info->spDef; + gUnknown_202F31C[0] = info->atk[0]; + gUnknown_202F31C[1] = info->atk[1]; + gUnknown_202F324[0] = info->def[0]; + gUnknown_202F324[1] = info->def[1]; gUnknown_202F31C[0] -= leveldata.gainAtt; gUnknown_202F31C[1] -= leveldata.gainSPAtt; @@ -851,10 +851,10 @@ bool8 sub_80725A4(Entity *pokemon, Entity *target) LoadIQSkills(target); sub_8079764(target); - info->atk = gUnknown_202F31C[0]; - info->spAtk = gUnknown_202F31C[1]; - info->def = gUnknown_202F324[0]; - info->spDef = gUnknown_202F324[1]; + info->atk[0] = gUnknown_202F31C[0]; + info->atk[1] = gUnknown_202F31C[1]; + info->def[0] = gUnknown_202F324[0]; + info->def[1] = gUnknown_202F324[1]; } } diff --git a/src/code_8077274_1.c b/src/code_8077274_1.c index e05731587..85b2235c4 100644 --- a/src/code_8077274_1.c +++ b/src/code_8077274_1.c @@ -508,14 +508,14 @@ void RaiseAtkStatTarget(Entity * pokemon, Entity *target, s32 increment) SetMessageArgument(gFormatBuffer_Monsters[0],target,0); entityInfo = GetEntInfo(target); - oldStat = entityInfo->atk; + oldStat = entityInfo->atk[0]; oldStat1 = oldStat; - newStat = entityInfo->atk + increment; + newStat = entityInfo->atk[0] + increment; if (0xfe < newStat) { newStat = 0xff; } - entityInfo->atk = newStat; + entityInfo->atk[0] = newStat; if (oldStat1 < (u8)newStat) { sub_8041E60(target); TryDisplayDungeonLoggableMessage3(pokemon,target,*gUnknown_80FC33C); @@ -538,14 +538,14 @@ void RaiseSpAtkStatTarget(Entity * pokemon, Entity *target, s32 increment) SetMessageArgument(gFormatBuffer_Monsters[0],target,0); entityInfo = GetEntInfo(target); - oldStat = entityInfo->spAtk; + oldStat = entityInfo->atk[1]; oldStat1 = oldStat; - newStat = entityInfo->spAtk + increment; + newStat = entityInfo->atk[1] + increment; if (0xfe < newStat) { newStat = 0xff; } - entityInfo->spAtk = newStat; + entityInfo->atk[1] = newStat; if (oldStat1 < (u8)newStat) { sub_8041E74(target); TryDisplayDungeonLoggableMessage3(pokemon,target,*gUnknown_80FC388); @@ -568,14 +568,14 @@ void RaiseDefStatTarget(Entity * pokemon, Entity *target, s32 increment) SetMessageArgument(gFormatBuffer_Monsters[0],target,0); entityInfo = GetEntInfo(target); - oldStat = entityInfo->def; + oldStat = entityInfo->def[0]; oldStat1 = oldStat; - newStat = entityInfo->def + increment; + newStat = entityInfo->def[0] + increment; if (0xfe < newStat) { newStat = 0xff; } - entityInfo->def = newStat; + entityInfo->def[0] = newStat; if (oldStat1 < (u8)newStat) { sub_8041E84(target); TryDisplayDungeonLoggableMessage3(pokemon,target,*gUnknown_80FC3D8); @@ -598,14 +598,14 @@ void RaiseSpDefStatTarget(Entity * pokemon, Entity *target, s32 increment) SetMessageArgument(gFormatBuffer_Monsters[0],target,0); entityInfo = GetEntInfo(target); - oldStat = entityInfo->spDef; + oldStat = entityInfo->def[1]; oldStat1 = oldStat; - newStat = entityInfo->spDef + increment; + newStat = entityInfo->def[1] + increment; if (0xfe < newStat) { newStat = 0xff; } - entityInfo->spDef = newStat; + entityInfo->def[1] = newStat; if (oldStat1 < (u8)newStat) { sub_8041E94(target); TryDisplayDungeonLoggableMessage3(pokemon,target,*gUnknown_80FC428); diff --git a/src/dungeon_ai_item_weight.c b/src/dungeon_ai_item_weight.c index be795c30b..7c2a404fe 100644 --- a/src/dungeon_ai_item_weight.c +++ b/src/dungeon_ai_item_weight.c @@ -111,7 +111,7 @@ u32 GetAIUseItemProbability(Entity *targetPokemon, Item *item, u32 itemTargetFla } break; case ITEM_PROTEIN: - if (pokemonInfo->atk > 249) + if (pokemonInfo->atk[0] > 249) { itemWeight = 0; } @@ -121,7 +121,7 @@ u32 GetAIUseItemProbability(Entity *targetPokemon, Item *item, u32 itemTargetFla } break; case ITEM_CALCIUM: - if (pokemonInfo->spAtk > 249) + if (pokemonInfo->atk[1] > 249) { itemWeight = 0; } @@ -131,7 +131,7 @@ u32 GetAIUseItemProbability(Entity *targetPokemon, Item *item, u32 itemTargetFla } break; case ITEM_IRON: - if (pokemonInfo->def > 249) + if (pokemonInfo->def[0] > 249) { itemWeight = 0; } @@ -141,7 +141,7 @@ u32 GetAIUseItemProbability(Entity *targetPokemon, Item *item, u32 itemTargetFla } break; case ITEM_ZINC: - if (pokemonInfo->spDef > 249) + if (pokemonInfo->def[1] > 249) { itemWeight = 0; } diff --git a/src/dungeon_move.c b/src/dungeon_move.c index 7c3e23925..59dda3312 100644 --- a/src/dungeon_move.c +++ b/src/dungeon_move.c @@ -622,7 +622,6 @@ static void UseMoveAgainstTargets(Entity **targetsArray, Entity *attacker, Move case MOVE_JUMP_KICK: sub_8059E54(attacker, currTarget, move, itemId, 1); break; - } if (sub_8044B28()) diff --git a/src/dungeon_music.c b/src/dungeon_music.c index d81f044c7..2ddedd72b 100644 --- a/src/dungeon_music.c +++ b/src/dungeon_music.c @@ -58,10 +58,10 @@ void sub_8083AB0(s16 param_0, Entity * target, Entity * entity) temp->exp = entityInfo->exp; temp->level = entityInfo->level; temp->maxHPStat = entityInfo->maxHPStat; - temp->atk = entityInfo->atk; - temp->spAtk = entityInfo->spAtk; - temp->def = entityInfo->def; - temp->spDef = entityInfo->spDef; + temp->atk = entityInfo->atk[0]; + temp->spAtk = entityInfo->atk[1]; + temp->def = entityInfo->def[0]; + temp->spDef = entityInfo->def[1]; temp->dungeonLocation = gDungeon->dungeonLocation; attackPtr = &temp->attBoost; *attackPtr = 0; diff --git a/src/trap_1.c b/src/trap_1.c index 26f7f947b..4f0357931 100644 --- a/src/trap_1.c +++ b/src/trap_1.c @@ -333,10 +333,10 @@ void SaveEntity(unkStruct_8094924 *param_1, Entity *param_2) sub_8083048(param_1,info->HP); sub_8083048(param_1,info->maxHPStat); sub_8083048(param_1,info->originalHP); - sub_8083060(param_1,info->atk); - sub_8083060(param_1,info->spAtk); - sub_8083060(param_1,info->def); - sub_8083060(param_1,info->spDef); + sub_8083060(param_1,info->atk[0]); + sub_8083060(param_1,info->atk[1]); + sub_8083060(param_1,info->def[0]); + sub_8083060(param_1,info->def[1]); sub_8083078(param_1,info->exp); sub_8083048(param_1,info->offensiveStages[0]); sub_8083048(param_1,info->offensiveStages[1]);