sub_806F370

This commit is contained in:
DizzyEggg 2024-11-05 10:54:24 +01:00
parent 8a88429b87
commit 3dc536c92c
3 changed files with 163 additions and 1218 deletions

File diff suppressed because it is too large Load Diff

View File

@ -249,7 +249,6 @@ SECTIONS {
src/code_806CD90.o(.text);
src/type_effectiveness.o(.text);
src/code_806E8B0.o(.text);
asm/code_806E8B0.o(.text);
src/code_806FDF4.o(.text);
src/status_checks.o(.text);
src/dungeon_movement.o(.text);

View File

@ -145,12 +145,15 @@ extern void sub_800A34C(struct unkStruct_80943A8 *param_1, struct unkStruct_8094
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_800A2F0(const struct unkStruct_80943A8*, const 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 void HandleDealingDamage(Entity *attacker, Entity *target, struct DamageStruct *dmgStruct, bool32 isFalseSwipe, bool32 giveExp, s16 arg4, bool32 arg8, s32 argC);
extern void sub_80457DC(Entity *);
extern const s32 gUnknown_80F504C[];
extern const s32 gUnknown_80F50A0[];
extern const s16 gUnknown_810AC60;
extern const s16 gUnknown_810AC68;
extern const s16 gUnknown_810AC64;
@ -166,41 +169,39 @@ 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)
static inline void SetDamageOne(struct DamageStruct *dmgStruct, u8 moveType)
{
dmgStruct->dmg = 1;
dmgStruct->residualDmgType = 0;
dmgStruct->typeEffectiveness = EFFECTIVENESS_NEUTRAL;
dmgStruct->type = moveType;
dmgStruct->isCrit = FALSE;
dmgStruct->unkE = 0;
dmgStruct->unkF = 0;
}
void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, s32 movePower, s32 critChance, struct DamageStruct *dmgStruct, s32 arg8, u16 moveId, bool8 arg_10)
{
EntityInfo *attackerInfo = GetEntInfo(attacker);
EntityInfo *targetInfo = GetEntInfo(target);
bool32 physicalMove = (IsTypePhysical(moveType) != FALSE);
s32 splitIndex = (!IsTypePhysical(moveType)) ? 1 : 0;
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;
SetDamageOne(dmgStruct, moveType);
}
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;
SetDamageOne(dmgStruct, moveType);
}
else {
s32 atkStatStage, defStatStage;
s32 atkStatCalc, defStatCalc;
s32 statCalc;
s32 atkStat, defStat;
s32 rand;
s32 r6;
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;
@ -213,9 +214,9 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
dmgStruct->type = moveType;
gDungeon->unk134.unk134 = moveType;
gDungeon->unk134.unk138 = physicalMove;
gDungeon->unk134.unk138 = splitIndex;
atkStatStage = attackerInfo->offensiveStages[physicalMove];
atkStatStage = attackerInfo->offensiveStages[splitIndex];
if (arg_10 && moveType == TYPE_FIRE) {
atkStatStage += attackerInfo->flashFireBoost;
gDungeon->unk134.unk140[2] = attackerInfo->flashFireBoost;
@ -234,13 +235,13 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
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;
gDungeon->unk134.unk140[0] = attackerInfo->atk[splitIndex] + movePower;
statCalc = s24_8_mul((attackerInfo->atk[splitIndex] + movePower) * 256, gUnknown_80F504C[atkStatStage]);
statCalc = s24_8_mul(statCalc, attackerInfo->offensiveMultipliers[splitIndex]);
atkStat = statCalc / 256;
defStatStage = targetInfo->defensiveStages[physicalMove];
if (targetInfo->charging.chargingStatus == STATUS_SKULL_BASH) {
defStatStage = targetInfo->defensiveStages[splitIndex];
if (splitIndex == 0 && targetInfo->charging.chargingStatus == STATUS_SKULL_BASH) {
gDungeon->unk134.unk17A = 1;
defStatStage++;
}
@ -250,7 +251,7 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
if (targetInfo->apparentID == MONSTER_DEOXYS_DEFENSE) {
defStatStage += 2;
}
if (attackerInfo->apparentID == MONSTER_DEOXYS_SPEED) {
if (targetInfo->apparentID == MONSTER_DEOXYS_SPEED) {
defStatStage -= 2;
}
@ -258,13 +259,13 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
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;
gDungeon->unk134.unk140[1] = targetInfo->def[splitIndex];
statCalc = s24_8_mul((targetInfo->def[splitIndex]) * 256, gUnknown_80F50A0[defStatStage]);
statCalc = s24_8_mul(statCalc, targetInfo->defensiveMultipliers[splitIndex]);
defStat = statCalc / 256;
rand = DungeonRandInt(100);
if (physicalMove) {
if (splitIndex == 0) {
if (HasHeldItem(attacker, ITEM_POWER_BAND)) {
atkStat += gUnknown_810AC60;
gDungeon->unk134.unk160 += gUnknown_810AC60;
@ -304,16 +305,16 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
sub_800A020(&unkSp1, atkStat - defStat);
sub_800A020(&unkSp2, 8);
sub_800A3F0(&unkSp1, &unkSp1, &unkSp2);
if (attackerInfo->isNotTeamMember) {
sub_800A020(&unkSp2, attackerInfo->teamIndex);
if (!attackerInfo->isNotTeamMember) {
sub_800A020(&unkSp2, attackerInfo->level);
unkSp3.s0 = 0;
unkSp3.s4 = 0xAAAA;
sub_800A34C(&unkSp2, &unkSp2, &unkSp3);
r6 = (attackerInfo->teamIndex * 2) / 3;
r6 = (attackerInfo->level * 2) / 3;
}
else {
unkAtkStat2 = attackerInfo->atk[physicalMove];
unkDefStat2 = 1;
s32 unkAtkStat2 = attackerInfo->atk[splitIndex];
s32 unkDefStat2 = 1;
sub_806E8B0(attacker, target, moveType, &unkAtkStat2, &unkDefStat2, rand);
sub_800A020(&unkSp2, unkAtkStat2);
sub_800A020(&unkSp3, 3);
@ -322,7 +323,7 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
}
sub_800A6D0(&unkSp4, &unkSp1, &unkSp2);
gDungeon->unk134.unk140[5] = r6;
gDungeon->unk134.unk140[6] = sub_800A048(&unkSp1);
gDungeon->unk134.unk140[6] = sub_800A048(&unkSp4);
unkSp5 = unkSp4;
unkSp7 = unkSp4;
sub_800A34C(&unkSp5, &unkSp5, &unkSp5);
@ -334,11 +335,12 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
sub_800A020(&unkSp6, defStat);
sub_800A6F0(&unkSp7, &unkSp7, &unkSp6);
sub_800A020(&unkSp6, 10);
sub_800A6D0(&unkSp8, &unkSp5, &unkSp6);
sub_800A6D0(&unkSp7, &unkSp7, &unkSp6);
sub_800A6D0(&unkSp8, &unkSp5, &unkSp7);
if (sub_800A2F0(&gUnknown_8106F24, &unkSp8)) {
unkSp8 = gUnknown_8106F24;
}
if (sub_800A2F0(&gUnknown_8106F04, &unkSp8)) {
if (sub_800A2F0(&unkSp8, &gUnknown_8106F04)) {
unkSp8 = gUnknown_8106F04;
}
r5 = sub_806E100(&unkSp9, attacker, target, moveType, dmgStruct);
@ -356,19 +358,30 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
}
}
}
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;
if (arg_10) {
if (splitIndex == 0 && targetInfo->protection.protectionStatus == STATUS_REFLECT) {
sub_8041B74(target);
sub_800A34C(&unkSp9, &unkSp9, &gUnknown_8106F1C);
gDungeon->unk134.unk166 = 1;
}
if (splitIndex == 1 && 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;
s32 critOdds;
if (attackerInfo->isNotTeamMember) {
critOdds = 0;
}
else {
critOdds = critChance;
}
if (attackerInfo->moveStatus.moveStatus == STATUS_FOCUS_ENERGY) {
critOdds = 999;
gDungeon->unk134.unk168 = 1;
@ -378,12 +391,12 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
critOdds += gUnknown_80F4DAE;
gDungeon->unk134.unk164 = 1;
}
if (HasHeldItem(attacker, ITEM_PATSY_BAND)) {
if (HasHeldItem(target, ITEM_PATSY_BAND)) {
critOdds += gUnknown_80F4DAE;
gDungeon->unk134.unk165 = 1;
}
if (r5 && IQSkillIsEnabled(attacker, IQ_TYPE_ADVANTAGE_MASTER)) {
critOdds += gUnknown_80F4DB0;
critOdds = gUnknown_80F4DB0;
gDungeon->unk134.unk169 = 1;
}
}
@ -395,9 +408,22 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
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);
{
// Ugly hack needed to match
#ifdef NONMATCHING
s32 arg8_Match;
#else
register s32 arg8_Match asm("r2");
#endif // NONMATCHING
gDungeon->unk134.unk15C = arg8_Match = arg8;
ASM_MATCH_TRICK(arg8);
sub_800A088(&unkSp10, arg8_Match);
sub_800A34C(&unkSp8, &unkSp8, &unkSp10);
}
// ALSO needed to match. unk694 chosen randomly and it worked with matching.
ASM_MATCH_TRICK(gDungeon->unk694);
gDungeon->unk134.unk150 = sub_800A048(&unkSp8);
{
s32 rnd = DungeonRandInt(0x4000);
@ -406,8 +432,10 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
}
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) {
@ -415,3 +443,81 @@ void sub_806EAF4(Entity *attacker, Entity *target, u8 moveType, u32 movePower, u
}
}
}
void sub_806F2BC(Entity *attacker, Entity *target, u8 moveType, s32 a2, struct DamageStruct *dmgStruct)
{
struct unkStruct_80943A8 unkSp1;
struct unkStruct_80943A8 unkSp2;
s32 a2New = a2;
if (a2New <= 0) a2New = 1;
if (a2New > 999) a2New = 999;
dmgStruct->type = moveType;
sub_806E100(&unkSp1, attacker, target, moveType, dmgStruct);
sub_800A020(&unkSp2, a2New);
sub_800A34C(&unkSp2, &unkSp2, &unkSp1);
dmgStruct->dmg = sub_800A048(&unkSp2);
dmgStruct->residualDmgType = 0;
}
void DealDamageToEntity(Entity *entity, s32 dmg, s32 r6, s16 r4)
{
Entity spEntity;
struct DamageStruct dmgStruct;
s32 r4_ = r4;
sub_80457DC(&spEntity);
dmgStruct.dmg = dmg;
dmgStruct.typeEffectiveness = EFFECTIVENESS_NEUTRAL;
dmgStruct.type = TYPE_NONE;
dmgStruct.residualDmgType = r6;
dmgStruct.isCrit = FALSE;
dmgStruct.unkE = 0;
dmgStruct.unkF = 0;
HandleDealingDamage(&spEntity, entity, &dmgStruct, FALSE, FALSE, r4_, FALSE, 0);
}
extern const s32 gUnknown_80F54B4[NUM_EFFECTIVENESS][NUM_EFFECTIVENESS];
void sub_806F370(Entity *pokemon, Entity *target, s32 dmg, s32 r9, u8 *arg_0, u8 moveType, s16 arg_8, s32 arg_C, s32 arg_10, s32 arg_14)
{
s32 i;
struct DamageStruct dmgStruct;
s32 arg_8_ = arg_8;
s32 dmgNew = dmg;
dmgStruct.typeEffectiveness = EFFECTIVENESS_NEUTRAL;
dmgStruct.residualDmgType = arg_C;
dmgStruct.type = moveType;
dmgStruct.isCrit = FALSE;
dmgStruct.unkE = 0;
if (moveType != TYPE_NONE) {
s32 typeEffectiveness[2];
EntityInfo *targetInfo = GetEntInfo(target);
for (i = 0; i < 2; i++) {
s32 effectiv = gTypeEffectivenessChart[moveType][targetInfo->types[i]];
typeEffectiveness[i] = effectiv;
}
if (HasAbility(target, ABILITY_WONDER_GUARD)) {
if (gUnknown_80F54B4[typeEffectiveness[0]][typeEffectiveness[1]] != EFFECTIVENESS_SUPER) {
dmgNew = 0;
}
}
}
dmgStruct.dmg = dmgNew;
if (dmgNew == 0) {
dmgStruct.unkF = 1;
}
else {
dmgStruct.unkF = 0;
}
HandleDealingDamage(pokemon, target, &dmgStruct, FALSE, r9, arg_8_, arg_10, arg_14);
if (arg_0 != NULL) {
*arg_0 = dmgStruct.unkF;
}
}
//