mirror of
https://github.com/pret/pmd-sky.git
synced 2026-09-28 21:31:17 -05:00
Decomp CalcDamage; damage_calc_diag's move_category is 4 bytes, its modifiers unsigned
CalcDamage (0x0230BBAC, 1290 instructions) is the damage formula: stat
stages, item/ability/IQ-skill modifiers, the fixed-point base formula,
CalcTypeBasedDamageEffects, critical hits, Reflect/Light Screen and the
final multipliers, with its diagnostics in DUNGEON_PTR->last_damage_calc.
It is the first of 26 functions in asm/overlay_29_0230BBAC.s and a rodata
object precedes that object in main.lsf, so extract_function.py splits
rather than merges: the function lands in src/overlay_29_0230BBAC.c with
include/overlay_29_0230BBAC.h, the other 25 move to
asm/overlay_29_0230D088.{s,inc}, and main.lsf lists both objects where it
listed one.
struct damage_calc_diag modelled move_category as a 1-byte enum plus
field_0x5/0x6/0x7 padding (3fc6d8bd). Retail writes that field with a
4-byte str (0x0230BDC8) and reads the eight modifier bytes at 0x30..0x37
unsigned (ldrb at 24 sites), so move_category becomes s32 - the struct
stays 0x54 bytes - and the modifiers become u8 (they were s8). No other
source in the tree reads these members. Both deviate from pmdsky-debug's
declarations; the reasoning note linked from the PR has the evidence.
Region handling follows the neighbouring files: six
DefenderAbilityIsActive__0230A940 calls take three arguments under JAPAN,
and message ids C53/C54/C55/C57/C58 and DC1 are file-scope defines at
US - 0x2C1 under JAPAN. One difference is real source: the defense-side
apparent_id 0x211/0x218 checks compare the attacker's apparent_id under
JAPAN (the JP-only ldrsh r1, [r6, #4]). EU is identical to US.
The 17 callees that are still asm are declared extern in the .c with
prototypes read off their own asm, as the sibling files do. The spelling
of the ability-multiply block (an s32 calc[2] local, two temps and three
volatile s32 * pointers) is match-derived, each element removing one
measured compiler obstacle; the reasoning note explains it.
Authored by Claude (Fable 5.1) under human direction. Confirmed by
matching builds of all three regions: build/pmdsky.us/pmdsky.us.nds: OK,
build/pmdsky.eu/pmdsky.eu.nds: OK, build/pmdsky.jp/pmdsky.jp.nds: OK,
each also passing main.sha1, filesystem.sha1 and arm7.sha1.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -1,100 +0,0 @@
|
||||
#pragma once
|
||||
.public _s32_div_f
|
||||
.public AbilityIsActiveVeneer
|
||||
.public AddFixedPoint64
|
||||
.public AdvanceFrame
|
||||
.public AIR_BLADE_DAMAGE_MULTIPLIER
|
||||
.public ApplyDamageAndEffects
|
||||
.public AURA_BOW_STAT_BOOST
|
||||
.public AuraBowIsActive
|
||||
.public CalcTypeBasedDamageEffects
|
||||
.public CeilFixedPoint
|
||||
.public ClampedLn
|
||||
.public CreateTemporaryEntity
|
||||
.public DAMAGE_FORMULA_AT_PREFACTOR
|
||||
.public DAMAGE_FORMULA_CONSTANT_SHIFT
|
||||
.public DAMAGE_FORMULA_DEF_PREFACTOR
|
||||
.public DAMAGE_FORMULA_FLV_DEFICIT_DIVISOR
|
||||
.public DAMAGE_FORMULA_FLV_SHIFT
|
||||
.public DAMAGE_FORMULA_LN_ARG_PREFACTOR
|
||||
.public DAMAGE_FORMULA_LN_PREFACTOR
|
||||
.public DAMAGE_FORMULA_MAX_BASE
|
||||
.public DAMAGE_FORMULA_MIN_BASE
|
||||
.public DAMAGE_FORMULA_NON_TEAM_MEMBER_MODIFIER
|
||||
.public DAMAGE_MULTIPLIER_0_5
|
||||
.public DAMAGE_MULTIPLIER_1_5
|
||||
.public DAMAGE_MULTIPLIER_2
|
||||
.public Debug_Print0
|
||||
.public DEF_SCARF_STAT_BOOST
|
||||
.public DefenderAbilityIsActive__0230A940
|
||||
.public DEFENSIVE_STAT_STAGE_MULTIPLIERS
|
||||
.public DivideFixedPoint64
|
||||
.public DUNGEON_PTR
|
||||
.public DungeonRandInt
|
||||
.public EntityIsValid__02308FBC
|
||||
.public ExclusiveItemDefenseBoost
|
||||
.public ExclusiveItemEffectIsActive__0230A9B8
|
||||
.public ExclusiveItemEffectIsActiveWithLogging
|
||||
.public ExclusiveItemOffenseBoost
|
||||
.public FixedPoint32To64
|
||||
.public FixedPoint64CmpLt
|
||||
.public FixedPoint64ToInt
|
||||
.public FixedRoomIsSubstituteRoom
|
||||
.public FlashFireShouldActivate
|
||||
.public GendersEqualNotGenderless
|
||||
.public GendersNotEqualNotGenderless
|
||||
.public GenerateStandardItem
|
||||
.public GetApparentWeather
|
||||
.public GetEquivItemIndex
|
||||
.public GetItemAtIdx
|
||||
.public GetMonsterGenderVeneer
|
||||
.public GetMoveCategory
|
||||
.public GetTypeMatchup
|
||||
.public IntToFixedPoint64
|
||||
.public IqSkillIsEnabled
|
||||
.public IsMonster__0230A994
|
||||
.public IsPunchMove
|
||||
.public IsRecoilMove
|
||||
.public IsRegularAttackOrProjectile
|
||||
.public ItemIsActive__0230A9DC
|
||||
.public LogMessageByIdWithPopupCheckUserTarget
|
||||
.public ME_FIRST_MULTIPLIER
|
||||
.public MemZero
|
||||
.public MonsterHasNegativeStatus
|
||||
.public MonsterIsType
|
||||
.public MoveIsNotPhysical
|
||||
.public MultiplyByFixedPoint
|
||||
.public MultiplyFixedPoint64
|
||||
.public MUNCH_BELT_STAT_BOOST
|
||||
.public NearbyAllyIqSkillIsEnabled
|
||||
.public OFFENSIVE_STAT_STAGE_MULTIPLIERS
|
||||
.public OtherMonsterAbilityIsActive
|
||||
.public ov10_022BF964
|
||||
.public ov10_022C45B4
|
||||
.public ov29_02352838
|
||||
.public ov29_02352894
|
||||
.public ov29_02352984
|
||||
.public ov29_02352990
|
||||
.public ov29_0235299C
|
||||
.public ov29_023535D4
|
||||
.public PlayEffectAnimation0x171
|
||||
.public PlayEffectAnimation0x171Full
|
||||
.public PlayEffectAnimation0x18E
|
||||
.public PlayEffectAnimation0x1A9__022E6130
|
||||
.public PlayEffectAnimation0x1A9__022E617C
|
||||
.public PlayEffectAnimationEntity
|
||||
.public PointCameraToMonster
|
||||
.public POWER_BAND_STAT_BOOST
|
||||
.public POWER_PITCHER_DAMAGE_MULTIPLIER
|
||||
.public ResetDamageData
|
||||
.public RoundUpDiv256
|
||||
.public SCOPE_LENS_CRIT_RATE_BOOST
|
||||
.public SetItemAcquired
|
||||
.public SPECIAL_BAND_STAT_BOOST
|
||||
.public SubstitutePlaceholderStringTags
|
||||
.public SUPER_LUCK_CRIT_RATE_BOOST
|
||||
.public TerminateEffectWrapper
|
||||
.public TYPE_ADVANTAGE_MASTER_CRIT_RATE
|
||||
.public TYPE_MATCHUP_COMBINATOR_TABLE
|
||||
.public UpdateStateFlags
|
||||
.public ZINC_BAND_STAT_BOOST
|
||||
37
asm/include/overlay_29_0230D088.inc
Normal file
37
asm/include/overlay_29_0230D088.inc
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
.public AbilityIsActiveVeneer
|
||||
.public AdvanceFrame
|
||||
.public ApplyDamageAndEffects
|
||||
.public CalcTypeBasedDamageEffects
|
||||
.public CreateTemporaryEntity
|
||||
.public DUNGEON_PTR
|
||||
.public DefenderAbilityIsActive__0230A940
|
||||
.public DungeonRandInt
|
||||
.public EntityIsValid__02308FBC
|
||||
.public FixedPoint64ToInt
|
||||
.public GendersNotEqualNotGenderless
|
||||
.public GenerateStandardItem
|
||||
.public GetEquivItemIndex
|
||||
.public GetItemAtIdx
|
||||
.public GetTypeMatchup
|
||||
.public IntToFixedPoint64
|
||||
.public IqSkillIsEnabled
|
||||
.public IsMonster__0230A994
|
||||
.public LogMessageByIdWithPopupCheckUserTarget
|
||||
.public MemZero
|
||||
.public MonsterIsType
|
||||
.public MultiplyByFixedPoint
|
||||
.public MultiplyFixedPoint64
|
||||
.public POWER_PITCHER_DAMAGE_MULTIPLIER
|
||||
.public PlayEffectAnimationEntity
|
||||
.public PointCameraToMonster
|
||||
.public ResetDamageData
|
||||
.public RoundUpDiv256
|
||||
.public SetItemAcquired
|
||||
.public SubstitutePlaceholderStringTags
|
||||
.public TYPE_MATCHUP_COMBINATOR_TABLE
|
||||
.public TerminateEffectWrapper
|
||||
.public ov10_022BF964
|
||||
.public ov10_022C45B4
|
||||
.public ov29_02352894
|
||||
.public ov29_023535D4
|
||||
File diff suppressed because it is too large
Load Diff
845
asm/overlay_29_0230D088.s
Normal file
845
asm/overlay_29_0230D088.s
Normal file
@@ -0,0 +1,845 @@
|
||||
.include "asm/macros.inc"
|
||||
.include "overlay_29_0230D088.inc"
|
||||
|
||||
.text
|
||||
|
||||
arm_func_start ov29_0230D088
|
||||
ov29_0230D088: ; 0x0230D088
|
||||
stmdb sp!, {r4, r5, lr}
|
||||
sub sp, sp, #0x1c
|
||||
ldr r5, [sp, #0x2c]
|
||||
ldr r4, [sp, #0x28]
|
||||
mov lr, r0
|
||||
strb r2, [r5, #0xc]
|
||||
cmp r4, #1
|
||||
strb r3, [r5, #0xd]
|
||||
mov ip, r1
|
||||
str r2, [sp]
|
||||
mov r2, ip
|
||||
ldr r0, _0230D118 ; =0x000003E7
|
||||
movlt r4, #1
|
||||
cmp r4, r0
|
||||
movgt r4, r0
|
||||
add r0, sp, #0x14
|
||||
mov r1, lr
|
||||
mov r3, r4
|
||||
str r5, [sp, #4]
|
||||
mov ip, #0
|
||||
str ip, [sp, #8]
|
||||
bl CalcTypeBasedDamageEffects
|
||||
add r0, sp, #0xc
|
||||
mov r1, r4
|
||||
bl IntToFixedPoint64
|
||||
add r0, sp, #0xc
|
||||
add r2, sp, #0x14
|
||||
mov r1, r0
|
||||
bl MultiplyFixedPoint64
|
||||
add r0, sp, #0xc
|
||||
bl FixedPoint64ToInt
|
||||
str r0, [r5]
|
||||
mov r0, #0
|
||||
str r0, [r5, #4]
|
||||
add sp, sp, #0x1c
|
||||
ldmia sp!, {r4, r5, pc}
|
||||
.align 2, 0
|
||||
_0230D118: .word 0x000003E7
|
||||
arm_func_end ov29_0230D088
|
||||
|
||||
arm_func_start ApplyDamageAndEffectsWrapper
|
||||
ApplyDamageAndEffectsWrapper: ; 0x0230D11C
|
||||
stmdb sp!, {r4, r5, r6, r7, lr}
|
||||
sub sp, sp, #0xdc
|
||||
mov r7, r0
|
||||
add r0, sp, #0x10
|
||||
mov r6, r1
|
||||
mov r5, r2
|
||||
mov r4, r3
|
||||
bl ResetDamageData
|
||||
add r0, sp, #0x24
|
||||
bl CreateTemporaryEntity
|
||||
mov r3, #0
|
||||
mov r0, #2
|
||||
str r0, [sp, #0x18]
|
||||
str r6, [sp, #0x10]
|
||||
str r5, [sp, #0x14]
|
||||
strb r3, [sp, #0x1c]
|
||||
strb r3, [sp, #0x1e]
|
||||
strb r3, [sp, #0x1f]
|
||||
strb r3, [sp, #0x20]
|
||||
stmia sp, {r3, r4}
|
||||
str r3, [sp, #8]
|
||||
mov r1, r7
|
||||
add r0, sp, #0x24
|
||||
add r2, sp, #0x10
|
||||
str r3, [sp, #0xc]
|
||||
bl ApplyDamageAndEffects
|
||||
add sp, sp, #0xdc
|
||||
ldmia sp!, {r4, r5, r6, r7, pc}
|
||||
arm_func_end ApplyDamageAndEffectsWrapper
|
||||
|
||||
arm_func_start CalcRecoilDamageFixed
|
||||
CalcRecoilDamageFixed: ; 0x0230D18C
|
||||
stmdb sp!, {r4, r5, r6, r7, lr}
|
||||
sub sp, sp, #0x1c
|
||||
mov r7, r0
|
||||
mov r6, r1
|
||||
mov r5, r2
|
||||
mov r4, r3
|
||||
bl EntityIsValid__02308FBC
|
||||
cmp r0, #0
|
||||
beq _0230D238
|
||||
ldr r0, [r7]
|
||||
cmp r0, #1
|
||||
bne _0230D1F0
|
||||
ldr r0, [r7, #0xb4]
|
||||
ldrsh r0, [r0, #0x10]
|
||||
cmp r0, #0
|
||||
beq _0230D238
|
||||
mov r0, r7
|
||||
mov r1, #0x5c
|
||||
bl AbilityIsActiveVeneer
|
||||
cmp r0, #0
|
||||
beq _0230D1F0
|
||||
mov r0, r6, lsl #8
|
||||
mov r1, #0x180
|
||||
bl MultiplyByFixedPoint
|
||||
mov r6, r0, asr #8
|
||||
_0230D1F0:
|
||||
ldrb r1, [sp, #0x34]
|
||||
str r4, [sp]
|
||||
ldrsh r0, [sp, #0x38]
|
||||
str r1, [sp, #4]
|
||||
mov r1, #3
|
||||
str r1, [sp, #8]
|
||||
ldr r1, [sp, #0x3c]
|
||||
str r0, [sp, #0xc]
|
||||
ldr r0, [sp, #0x40]
|
||||
str r1, [sp, #0x10]
|
||||
ldr r4, [sp, #0x44]
|
||||
str r0, [sp, #0x14]
|
||||
mov r0, r7
|
||||
mov r1, r7
|
||||
mov r2, r6
|
||||
mov r3, r5
|
||||
str r4, [sp, #0x18]
|
||||
bl CalcDamageFixed
|
||||
_0230D238:
|
||||
add sp, sp, #0x1c
|
||||
ldmia sp!, {r4, r5, r6, r7, pc}
|
||||
arm_func_end CalcRecoilDamageFixed
|
||||
|
||||
arm_func_start CalcDamageFixed
|
||||
CalcDamageFixed: ; 0x0230D240
|
||||
stmdb sp!, {r3, r4, r5, r6, r7, r8, sb, sl, lr}
|
||||
sub sp, sp, #0x2c
|
||||
mov sl, r0
|
||||
add r0, sp, #0x18
|
||||
mov sb, r1
|
||||
mov r8, r2
|
||||
mov r7, r3
|
||||
ldr r6, [sp, #0x54]
|
||||
bl ResetDamageData
|
||||
mov r5, #0
|
||||
ldrb r0, [sp, #0x58]
|
||||
ldr r1, [sp, #0x60]
|
||||
mov r2, #2
|
||||
str r2, [sp, #0x20]
|
||||
str r1, [sp, #0x1c]
|
||||
strb r6, [sp, #0x24]
|
||||
strb r5, [sp, #0x26]
|
||||
strb r5, [sp, #0x27]
|
||||
strb r0, [sp, #0x25]
|
||||
cmp r6, #0
|
||||
beq _0230D2F8
|
||||
add r4, sp, #0x10
|
||||
_0230D298:
|
||||
mov r2, r5, lsl #0x10
|
||||
mov r0, sl
|
||||
mov r1, sb
|
||||
mov r3, r6
|
||||
mov r2, r2, asr #0x10
|
||||
bl GetTypeMatchup
|
||||
str r0, [r4, r5, lsl #2]
|
||||
add r5, r5, #1
|
||||
cmp r5, #2
|
||||
blt _0230D298
|
||||
mov r0, sl
|
||||
mov r1, sb
|
||||
mov r2, #0x35
|
||||
#ifndef JAPAN
|
||||
mov r3, #1
|
||||
#endif
|
||||
bl DefenderAbilityIsActive__0230A940
|
||||
cmp r0, #0
|
||||
beq _0230D2F8
|
||||
ldr r2, [sp, #0x10]
|
||||
ldr r0, _0230D39C ; =TYPE_MATCHUP_COMBINATOR_TABLE
|
||||
ldr r1, [sp, #0x14]
|
||||
add r0, r0, r2, lsl #4
|
||||
ldr r0, [r0, r1, lsl #2]
|
||||
cmp r0, #3
|
||||
movne r8, #0
|
||||
_0230D2F8:
|
||||
ldrsh r1, [sp, #0x5c]
|
||||
ldr r0, _0230D3A0 ; =0x00000256
|
||||
mov r8, r8, lsl #8
|
||||
cmp r1, r0
|
||||
bne _0230D334
|
||||
mov r0, sl
|
||||
mov r1, #0x2f
|
||||
bl IqSkillIsEnabled
|
||||
cmp r0, #0
|
||||
beq _0230D334
|
||||
ldr r1, _0230D3A4 ; =POWER_PITCHER_DAMAGE_MULTIPLIER
|
||||
mov r0, r8
|
||||
ldr r1, [r1]
|
||||
bl MultiplyByFixedPoint
|
||||
mov r8, r0
|
||||
_0230D334:
|
||||
mov r0, r8
|
||||
bl RoundUpDiv256
|
||||
str r0, [sp, #0x18]
|
||||
cmp r8, #0
|
||||
moveq r0, #1
|
||||
streqb r0, [sp, #0x28]
|
||||
movne r0, #0
|
||||
strneb r0, [sp, #0x28]
|
||||
ldrsh r1, [sp, #0x5c]
|
||||
str r7, [sp]
|
||||
ldr r0, [sp, #0x64]
|
||||
str r1, [sp, #4]
|
||||
str r0, [sp, #8]
|
||||
ldr r4, [sp, #0x68]
|
||||
add r2, sp, #0x18
|
||||
mov r0, sl
|
||||
mov r1, sb
|
||||
mov r3, #0
|
||||
str r4, [sp, #0xc]
|
||||
bl ApplyDamageAndEffects
|
||||
ldr r1, [sp, #0x50]
|
||||
cmp r1, #0
|
||||
ldrneb r0, [sp, #0x28]
|
||||
strneb r0, [r1]
|
||||
add sp, sp, #0x2c
|
||||
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, pc}
|
||||
.align 2, 0
|
||||
_0230D39C: .word TYPE_MATCHUP_COMBINATOR_TABLE
|
||||
_0230D3A0: .word 0x00000256
|
||||
_0230D3A4: .word POWER_PITCHER_DAMAGE_MULTIPLIER
|
||||
arm_func_end CalcDamageFixed
|
||||
|
||||
arm_func_start CalcDamageFixedNoCategory
|
||||
CalcDamageFixedNoCategory: ; 0x0230D3A8
|
||||
stmdb sp!, {lr}
|
||||
sub sp, sp, #0x1c
|
||||
ldr lr, [sp, #0x20]
|
||||
ldrb ip, [sp, #0x24]
|
||||
str lr, [sp]
|
||||
ldrsh lr, [sp, #0x28]
|
||||
str ip, [sp, #4]
|
||||
mov ip, #3
|
||||
str ip, [sp, #8]
|
||||
ldr ip, [sp, #0x2c]
|
||||
str lr, [sp, #0xc]
|
||||
ldr lr, [sp, #0x30]
|
||||
str ip, [sp, #0x10]
|
||||
ldr ip, [sp, #0x34]
|
||||
str lr, [sp, #0x14]
|
||||
str ip, [sp, #0x18]
|
||||
bl CalcDamageFixed
|
||||
add sp, sp, #0x1c
|
||||
ldmia sp!, {pc}
|
||||
arm_func_end CalcDamageFixedNoCategory
|
||||
|
||||
arm_func_start CalcDamageFixedWrapper
|
||||
CalcDamageFixedWrapper: ; 0x0230D3F4
|
||||
stmdb sp!, {lr}
|
||||
sub sp, sp, #0x1c
|
||||
ldr ip, [sp, #0x20]
|
||||
ldrb lr, [sp, #0x24]
|
||||
str ip, [sp]
|
||||
ldrb ip, [sp, #0x28]
|
||||
str lr, [sp, #4]
|
||||
ldrsh lr, [sp, #0x2c]
|
||||
str ip, [sp, #8]
|
||||
ldr ip, [sp, #0x30]
|
||||
str lr, [sp, #0xc]
|
||||
ldr lr, [sp, #0x34]
|
||||
str ip, [sp, #0x10]
|
||||
ldr ip, [sp, #0x38]
|
||||
str lr, [sp, #0x14]
|
||||
str ip, [sp, #0x18]
|
||||
bl CalcDamageFixed
|
||||
add sp, sp, #0x1c
|
||||
ldmia sp!, {pc}
|
||||
arm_func_end CalcDamageFixedWrapper
|
||||
|
||||
arm_func_start UpdateShopkeeperModeAfterAttack
|
||||
UpdateShopkeeperModeAfterAttack: ; 0x0230D440
|
||||
ldr r2, [r1, #0xb4]
|
||||
ldrb r1, [r2, #9]
|
||||
cmp r1, #0
|
||||
bxeq lr
|
||||
ldr r1, [r0]
|
||||
cmp r1, #1
|
||||
bxne lr
|
||||
ldr r0, [r0, #0xb4]
|
||||
ldrb r0, [r0, #6]
|
||||
cmp r0, #0
|
||||
movne r0, #2
|
||||
strneb r0, [r2, #9]
|
||||
moveq r0, #3
|
||||
streqb r0, [r2, #9]
|
||||
bx lr
|
||||
arm_func_end UpdateShopkeeperModeAfterAttack
|
||||
|
||||
arm_func_start UpdateShopkeeperModeAfterTrap
|
||||
UpdateShopkeeperModeAfterTrap: ; 0x0230D47C
|
||||
ldr r2, [r0, #0xb4]
|
||||
ldrb r0, [r2, #9]
|
||||
cmp r0, #0
|
||||
bxeq lr
|
||||
cmp r1, #0
|
||||
movne r0, #2
|
||||
strneb r0, [r2, #9]
|
||||
moveq r0, #3
|
||||
streqb r0, [r2, #9]
|
||||
bx lr
|
||||
arm_func_end UpdateShopkeeperModeAfterTrap
|
||||
|
||||
arm_func_start ov29_0230D4A4
|
||||
ov29_0230D4A4: ; 0x0230D4A4
|
||||
stmdb sp!, {r3, r4, r5, r6, r7, lr}
|
||||
mov r6, r1
|
||||
mov r7, r0
|
||||
mov r0, r6
|
||||
mov r1, #0xe
|
||||
mov r5, r2
|
||||
ldr r4, [r6, #0xb4]
|
||||
bl MonsterIsType
|
||||
cmp r0, #0
|
||||
beq _0230D4E8
|
||||
cmp r5, #1
|
||||
cmpne r5, #7
|
||||
bne _0230D4E8
|
||||
ldrb r0, [r4, #0xfe]
|
||||
cmp r0, #0
|
||||
moveq r0, #0
|
||||
ldmeqia sp!, {r3, r4, r5, r6, r7, pc}
|
||||
_0230D4E8:
|
||||
mov r4, #0
|
||||
b _0230D518
|
||||
_0230D4F0:
|
||||
mov r2, r4, lsl #0x10
|
||||
mov r0, r7
|
||||
mov r1, r6
|
||||
mov r3, r5
|
||||
mov r2, r2, asr #0x10
|
||||
bl GetTypeMatchup
|
||||
cmp r0, #0
|
||||
moveq r0, #0
|
||||
ldmeqia sp!, {r3, r4, r5, r6, r7, pc}
|
||||
add r4, r4, #1
|
||||
_0230D518:
|
||||
cmp r4, #2
|
||||
blt _0230D4F0
|
||||
mov r0, #1
|
||||
ldmia sp!, {r3, r4, r5, r6, r7, pc}
|
||||
arm_func_end ov29_0230D4A4
|
||||
|
||||
arm_func_start ResetDamageCalcDiagnostics
|
||||
ResetDamageCalcDiagnostics: ; 0x0230D528
|
||||
stmdb sp!, {r3, r4, r5, lr}
|
||||
ldr r0, _0230D614 ; =DUNGEON_PTR
|
||||
mov r1, #0x54
|
||||
ldr r4, [r0]
|
||||
add r5, r4, #0x184
|
||||
mov r0, r5
|
||||
bl MemZero
|
||||
mov r1, #0
|
||||
strb r1, [r4, #0x184]
|
||||
str r1, [r5, #4]
|
||||
strb r1, [r5, #8]
|
||||
strb r1, [r5, #9]
|
||||
mov r0, #0xa
|
||||
strb r0, [r5, #0xa]
|
||||
strb r0, [r5, #0xb]
|
||||
mov r0, #1
|
||||
strh r0, [r5, #0xc]
|
||||
strh r0, [r5, #0xe]
|
||||
strh r1, [r5, #0x10]
|
||||
strh r1, [r5, #0x14]
|
||||
strh r1, [r5, #0x12]
|
||||
strh r1, [r5, #0x16]
|
||||
strh r1, [r5, #0x1c]
|
||||
str r1, [r5, #0x20]
|
||||
str r1, [r5, #0x28]
|
||||
str r1, [r5, #0x2c]
|
||||
strb r1, [r5, #0x30]
|
||||
strb r1, [r5, #0x31]
|
||||
strb r1, [r5, #0x36]
|
||||
strb r1, [r5, #0x37]
|
||||
strb r1, [r5, #0x34]
|
||||
strb r1, [r5, #0x35]
|
||||
strb r1, [r5, #0x38]
|
||||
strb r1, [r5, #0x39]
|
||||
strb r1, [r5, #0x3a]
|
||||
strb r1, [r5, #0x3b]
|
||||
strb r1, [r5, #0x3c]
|
||||
strb r1, [r5, #0x3d]
|
||||
strb r1, [r5, #0x3e]
|
||||
strb r1, [r5, #0x40]
|
||||
strb r1, [r5, #0x3f]
|
||||
strb r1, [r5, #0x41]
|
||||
strb r1, [r5, #0x42]
|
||||
strb r1, [r5, #0x43]
|
||||
strb r1, [r5, #0x44]
|
||||
strb r1, [r5, #0x45]
|
||||
strb r1, [r5, #0x46]
|
||||
strb r1, [r5, #0x47]
|
||||
strb r1, [r5, #0x48]
|
||||
strb r1, [r5, #0x4b]
|
||||
strb r1, [r5, #0x4c]
|
||||
strb r1, [r5, #0x4d]
|
||||
strb r1, [r5, #0x4e]
|
||||
strb r1, [r5, #0x4f]
|
||||
strb r1, [r5, #0x50]
|
||||
strb r1, [r5, #0x51]
|
||||
strb r1, [r5, #0x32]
|
||||
strb r1, [r5, #0x33]
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
.align 2, 0
|
||||
_0230D614: .word DUNGEON_PTR
|
||||
arm_func_end ResetDamageCalcDiagnostics
|
||||
|
||||
arm_func_start ov29_0230D618
|
||||
ov29_0230D618: ; 0x0230D618
|
||||
ldr r1, _0230D624 ; =ov29_02352894
|
||||
ldr r0, [r1, r0, lsl #2]
|
||||
bx lr
|
||||
.align 2, 0
|
||||
_0230D624: .word ov29_02352894
|
||||
arm_func_end ov29_0230D618
|
||||
|
||||
arm_func_start ov29_0230D628
|
||||
ov29_0230D628: ; 0x0230D628
|
||||
stmdb sp!, {r3, lr}
|
||||
ldr r1, _0230D650 ; =DUNGEON_PTR
|
||||
ldr r1, [r1]
|
||||
add r1, r1, #0x1a000
|
||||
#ifdef JAPAN
|
||||
ldr r1, [r1, #0x188]
|
||||
#else
|
||||
ldr r1, [r1, #0x22c]
|
||||
#endif
|
||||
cmp r1, r0
|
||||
ldmneia sp!, {r3, pc}
|
||||
mov r1, #1
|
||||
bl PointCameraToMonster
|
||||
ldmia sp!, {r3, pc}
|
||||
.align 2, 0
|
||||
_0230D650: .word DUNGEON_PTR
|
||||
arm_func_end ov29_0230D628
|
||||
|
||||
arm_func_start IsEitherMonsterInvalid
|
||||
IsEitherMonsterInvalid: ; 0x0230D654
|
||||
stmdb sp!, {r4, lr}
|
||||
mov r4, r1
|
||||
bl EntityIsValid__02308FBC
|
||||
cmp r0, #0
|
||||
beq _0230D678
|
||||
mov r0, r4
|
||||
bl EntityIsValid__02308FBC
|
||||
cmp r0, #0
|
||||
bne _0230D680
|
||||
_0230D678:
|
||||
mov r0, #1
|
||||
ldmia sp!, {r4, pc}
|
||||
_0230D680:
|
||||
mov r0, #0
|
||||
ldmia sp!, {r4, pc}
|
||||
arm_func_end IsEitherMonsterInvalid
|
||||
|
||||
arm_func_start ov29_0230D688
|
||||
ov29_0230D688: ; 0x0230D688
|
||||
stmdb sp!, {r4, lr}
|
||||
sub sp, sp, #8
|
||||
mov r4, r0
|
||||
ldrh r3, [r4]
|
||||
mov r1, #0x55
|
||||
mov r2, #2
|
||||
strh r3, [sp]
|
||||
ldrh r3, [r4, #2]
|
||||
strh r3, [sp, #2]
|
||||
ldrh r3, [r4, #4]
|
||||
strh r3, [sp, #4]
|
||||
bl GenerateStandardItem
|
||||
mov r0, r4
|
||||
bl SetItemAcquired
|
||||
ldrb r0, [sp, #1]
|
||||
strb r0, [r4, #1]
|
||||
cmp r0, #0
|
||||
beq _0230D6FC
|
||||
add r0, sp, #0
|
||||
bl GetEquivItemIndex
|
||||
cmp r0, #0
|
||||
blt _0230D6FC
|
||||
bl GetItemAtIdx
|
||||
ldrh r1, [r4]
|
||||
strh r1, [r0]
|
||||
ldrh r1, [r4, #2]
|
||||
strh r1, [r0, #2]
|
||||
ldrh r1, [r4, #4]
|
||||
strh r1, [r0, #4]
|
||||
_0230D6FC:
|
||||
add sp, sp, #8
|
||||
ldmia sp!, {r4, pc}
|
||||
arm_func_end ov29_0230D688
|
||||
|
||||
arm_func_start ov29_0230D704
|
||||
ov29_0230D704: ; 0x0230D704
|
||||
mov r0, #0
|
||||
bx lr
|
||||
arm_func_end ov29_0230D704
|
||||
|
||||
arm_func_start ov29_0230D70C
|
||||
ov29_0230D70C: ; 0x0230D70C
|
||||
stmdb sp!, {r3, lr}
|
||||
mov r0, #0x64
|
||||
bl DungeonRandInt
|
||||
ldr r1, _0230D734 ; =ov10_022C45B4
|
||||
ldrsh r1, [r1]
|
||||
cmp r0, r1
|
||||
movlt r0, #1
|
||||
movge r0, #0
|
||||
and r0, r0, #0xff
|
||||
ldmia sp!, {r3, pc}
|
||||
.align 2, 0
|
||||
_0230D734: .word ov10_022C45B4
|
||||
arm_func_end ov29_0230D70C
|
||||
|
||||
arm_func_start ov29_0230D738
|
||||
ov29_0230D738: ; 0x0230D738
|
||||
stmdb sp!, {r3, lr}
|
||||
cmp r2, #0
|
||||
bne _0230D760
|
||||
mov r0, #0x64
|
||||
bl DungeonRandInt
|
||||
ldr r1, _0230D768 ; =ov10_022C45B4
|
||||
ldrsh r1, [r1]
|
||||
cmp r0, r1
|
||||
movlt r0, #1
|
||||
ldmltia sp!, {r3, pc}
|
||||
_0230D760:
|
||||
mov r0, #0
|
||||
ldmia sp!, {r3, pc}
|
||||
.align 2, 0
|
||||
_0230D768: .word ov10_022C45B4
|
||||
arm_func_end ov29_0230D738
|
||||
|
||||
arm_func_start ov29_0230D76C
|
||||
ov29_0230D76C: ; 0x0230D76C
|
||||
stmdb sp!, {r4, r5, r6, lr}
|
||||
mov r6, r0
|
||||
mov r5, r1
|
||||
mov r4, r2
|
||||
bl IsMonster__0230A994
|
||||
cmp r0, #0
|
||||
beq _0230D798
|
||||
mov r0, r5
|
||||
bl IsMonster__0230A994
|
||||
cmp r0, #0
|
||||
bne _0230D7A0
|
||||
_0230D798:
|
||||
mov r0, #0
|
||||
ldmia sp!, {r4, r5, r6, pc}
|
||||
_0230D7A0:
|
||||
ldr r0, [r6, #0xb4]
|
||||
ldr r1, [r5, #0xb4]
|
||||
ldrsh r0, [r0, #2]
|
||||
ldrsh r1, [r1, #2]
|
||||
bl GendersNotEqualNotGenderless
|
||||
cmp r0, #0
|
||||
moveq r0, #0
|
||||
ldmeqia sp!, {r4, r5, r6, pc}
|
||||
mov r0, r6
|
||||
mov r1, r5
|
||||
mov r2, r4
|
||||
bl ov29_0230D738
|
||||
ldmia sp!, {r4, r5, r6, pc}
|
||||
arm_func_end ov29_0230D76C
|
||||
|
||||
arm_func_start ov29_0230D7D4
|
||||
ov29_0230D7D4: ; 0x0230D7D4
|
||||
stmdb sp!, {r3, r4, r5, lr}
|
||||
sub sp, sp, #0x10
|
||||
ldr r2, _0230D870 ; =ov29_023535D4
|
||||
mvn r1, #0
|
||||
ldrsh r3, [r2]
|
||||
mov r4, r0
|
||||
cmp r3, r1
|
||||
beq _0230D808
|
||||
ldrsh r0, [r2]
|
||||
bl TerminateEffectWrapper
|
||||
ldr r0, _0230D870 ; =ov29_023535D4
|
||||
mvn r1, #0
|
||||
strh r1, [r0]
|
||||
_0230D808:
|
||||
mov r2, #0
|
||||
mov r1, #1
|
||||
str r2, [sp]
|
||||
stmib sp, {r1, r2}
|
||||
mov r0, r4
|
||||
rsb r1, r1, #0x2b8
|
||||
mov r3, #3
|
||||
str r2, [sp, #0xc]
|
||||
bl PlayEffectAnimationEntity
|
||||
mov r0, r0, lsl #0x10
|
||||
mov r5, r0, asr #0x10
|
||||
mvn r0, #0
|
||||
cmp r5, r0
|
||||
beq _0230D868
|
||||
mov r4, #0x18
|
||||
b _0230D850
|
||||
_0230D848:
|
||||
mov r0, r4
|
||||
bl AdvanceFrame
|
||||
_0230D850:
|
||||
mov r0, r5
|
||||
bl ov10_022BF964
|
||||
cmp r0, #0
|
||||
bne _0230D848
|
||||
mov r0, r5
|
||||
bl TerminateEffectWrapper
|
||||
_0230D868:
|
||||
add sp, sp, #0x10
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
.align 2, 0
|
||||
_0230D870: .word ov29_023535D4
|
||||
arm_func_end ov29_0230D7D4
|
||||
|
||||
arm_func_start SwapDefensiveStages
|
||||
SwapDefensiveStages: ; 0x0230D874
|
||||
stmdb sp!, {r3, r4, r5, lr}
|
||||
mov r5, r0
|
||||
mov r4, r1
|
||||
ldr lr, [r5, #0xb4]
|
||||
ldr ip, [r4, #0xb4]
|
||||
ldrsh r3, [lr, #0x28]
|
||||
ldrsh r1, [lr, #0x2a]
|
||||
ldrsh r0, [ip, #0x28]
|
||||
cmp r2, #0
|
||||
strh r0, [lr, #0x28]
|
||||
ldrsh r0, [ip, #0x2a]
|
||||
strh r0, [lr, #0x2a]
|
||||
strh r3, [ip, #0x28]
|
||||
strh r1, [ip, #0x2a]
|
||||
ldmeqia sp!, {r3, r4, r5, pc}
|
||||
mov r0, #0
|
||||
mov r1, r5
|
||||
mov r2, r0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
mov r1, r4
|
||||
mov r0, #1
|
||||
mov r2, #0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
ldr r2, _0230D8E4 ; =0x00000F2D
|
||||
mov r0, r5
|
||||
mov r1, r4
|
||||
bl LogMessageByIdWithPopupCheckUserTarget
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
.align 2, 0
|
||||
#ifdef JAPAN
|
||||
_0230D8E4: .word 0x00002494
|
||||
#else
|
||||
_0230D8E4: .word 0x00000F2D
|
||||
#endif
|
||||
arm_func_end SwapDefensiveStages
|
||||
|
||||
arm_func_start SwapDefensiveMultipliers
|
||||
SwapDefensiveMultipliers: ; 0x0230D8E8
|
||||
stmdb sp!, {r3, r4, r5, lr}
|
||||
mov r5, r0
|
||||
mov r4, r1
|
||||
ldr lr, [r5, #0xb4]
|
||||
ldr ip, [r4, #0xb4]
|
||||
ldr r3, [lr, #0x3c]
|
||||
ldr r1, [lr, #0x40]
|
||||
ldr r0, [ip, #0x3c]
|
||||
cmp r2, #0
|
||||
str r0, [lr, #0x3c]
|
||||
ldr r0, [ip, #0x40]
|
||||
str r0, [lr, #0x40]
|
||||
str r3, [ip, #0x3c]
|
||||
str r1, [ip, #0x40]
|
||||
ldmeqia sp!, {r3, r4, r5, pc}
|
||||
mov r0, #0
|
||||
mov r1, r5
|
||||
mov r2, r0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
mov r1, r4
|
||||
mov r0, #1
|
||||
mov r2, #0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
ldr r2, _0230D958 ; =0x00000F2E
|
||||
mov r0, r5
|
||||
mov r1, r4
|
||||
bl LogMessageByIdWithPopupCheckUserTarget
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
.align 2, 0
|
||||
#ifdef JAPAN
|
||||
_0230D958: .word 0x00002495
|
||||
#else
|
||||
_0230D958: .word 0x00000F2E
|
||||
#endif
|
||||
arm_func_end SwapDefensiveMultipliers
|
||||
|
||||
arm_func_start SwapOffensiveStages
|
||||
SwapOffensiveStages: ; 0x0230D95C
|
||||
stmdb sp!, {r3, r4, r5, lr}
|
||||
mov r5, r0
|
||||
mov r4, r1
|
||||
ldr lr, [r5, #0xb4]
|
||||
ldr ip, [r4, #0xb4]
|
||||
ldrsh r3, [lr, #0x24]
|
||||
ldrsh r1, [lr, #0x26]
|
||||
ldrsh r0, [ip, #0x24]
|
||||
cmp r2, #0
|
||||
strh r0, [lr, #0x24]
|
||||
ldrsh r0, [ip, #0x26]
|
||||
strh r0, [lr, #0x26]
|
||||
strh r3, [ip, #0x24]
|
||||
strh r1, [ip, #0x26]
|
||||
ldmeqia sp!, {r3, r4, r5, pc}
|
||||
mov r0, #0
|
||||
mov r1, r5
|
||||
mov r2, r0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
mov r1, r4
|
||||
mov r0, #1
|
||||
mov r2, #0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
ldr r2, _0230D9CC ; =0x00000F2B
|
||||
mov r0, r5
|
||||
mov r1, r4
|
||||
bl LogMessageByIdWithPopupCheckUserTarget
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
.align 2, 0
|
||||
#ifdef JAPAN
|
||||
_0230D9CC: .word 0x00002492
|
||||
#else
|
||||
_0230D9CC: .word 0x00000F2B
|
||||
#endif
|
||||
arm_func_end SwapOffensiveStages
|
||||
|
||||
arm_func_start SwapOffensiveMultipliers
|
||||
SwapOffensiveMultipliers: ; 0x0230D9D0
|
||||
stmdb sp!, {r3, r4, r5, lr}
|
||||
mov r5, r0
|
||||
mov r4, r1
|
||||
ldr lr, [r5, #0xb4]
|
||||
ldr ip, [r4, #0xb4]
|
||||
ldr r3, [lr, #0x34]
|
||||
ldr r1, [lr, #0x38]
|
||||
ldr r0, [ip, #0x34]
|
||||
cmp r2, #0
|
||||
str r0, [lr, #0x34]
|
||||
ldr r0, [ip, #0x38]
|
||||
str r0, [lr, #0x38]
|
||||
str r3, [ip, #0x34]
|
||||
str r1, [ip, #0x38]
|
||||
ldmeqia sp!, {r3, r4, r5, pc}
|
||||
mov r0, #0
|
||||
mov r1, r5
|
||||
mov r2, r0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
mov r1, r4
|
||||
mov r0, #1
|
||||
mov r2, #0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
ldr r2, _0230DA40 ; =0x00000F2C
|
||||
mov r0, r5
|
||||
mov r1, r4
|
||||
bl LogMessageByIdWithPopupCheckUserTarget
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
.align 2, 0
|
||||
#ifdef JAPAN
|
||||
_0230DA40: .word 0x00002493
|
||||
#else
|
||||
_0230DA40: .word 0x00000F2C
|
||||
#endif
|
||||
arm_func_end SwapOffensiveMultipliers
|
||||
|
||||
arm_func_start SwapHitChanceStages
|
||||
SwapHitChanceStages: ; 0x0230DA44
|
||||
stmdb sp!, {r3, r4, r5, lr}
|
||||
mov r5, r0
|
||||
mov r4, r1
|
||||
ldr lr, [r5, #0xb4]
|
||||
ldr ip, [r4, #0xb4]
|
||||
ldrsh r3, [lr, #0x2c]
|
||||
ldrsh r1, [lr, #0x2e]
|
||||
ldrsh r0, [ip, #0x2c]
|
||||
cmp r2, #0
|
||||
strh r0, [lr, #0x2c]
|
||||
ldrsh r0, [ip, #0x2e]
|
||||
strh r0, [lr, #0x2e]
|
||||
strh r3, [ip, #0x2c]
|
||||
strh r1, [ip, #0x2e]
|
||||
ldmeqia sp!, {r3, r4, r5, pc}
|
||||
mov r0, #0
|
||||
mov r1, r5
|
||||
mov r2, r0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
mov r1, r4
|
||||
mov r0, #1
|
||||
mov r2, #0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
ldr r2, _0230DAB4 ; =0x00000F2F
|
||||
mov r0, r5
|
||||
mov r1, r4
|
||||
bl LogMessageByIdWithPopupCheckUserTarget
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
.align 2, 0
|
||||
#ifdef JAPAN
|
||||
_0230DAB4: .word 0x00002496
|
||||
#else
|
||||
_0230DAB4: .word 0x00000F2F
|
||||
#endif
|
||||
arm_func_end SwapHitChanceStages
|
||||
|
||||
arm_func_start SwapUserAtkAndDefModifiers
|
||||
SwapUserAtkAndDefModifiers: ; 0x0230DAB8
|
||||
stmdb sp!, {r3, r4, r5, lr}
|
||||
mov r5, r0
|
||||
ldr ip, [r5, #0xb4]
|
||||
mov r4, r1
|
||||
ldrsh r1, [ip, #0x24]
|
||||
ldr r3, [ip, #0x34]
|
||||
ldr r0, [ip, #0x3c]
|
||||
cmp r2, #0
|
||||
str r0, [ip, #0x34]
|
||||
ldrsh r0, [ip, #0x28]
|
||||
strh r0, [ip, #0x24]
|
||||
str r3, [ip, #0x3c]
|
||||
strh r1, [ip, #0x28]
|
||||
ldmeqia sp!, {r3, r4, r5, pc}
|
||||
mov r0, #0
|
||||
mov r1, r5
|
||||
mov r2, r0
|
||||
bl SubstitutePlaceholderStringTags
|
||||
#ifdef JAPAN
|
||||
ldr r2, _0230F050 ; =0x00002497
|
||||
mov r0, r5
|
||||
mov r1, r4
|
||||
#else
|
||||
mov r0, r5
|
||||
mov r1, r4
|
||||
mov r2, #0xf30
|
||||
#endif
|
||||
bl LogMessageByIdWithPopupCheckUserTarget
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
#ifdef JAPAN
|
||||
_0230F050: .word 0x00002497
|
||||
#endif
|
||||
arm_func_end SwapUserAtkAndDefModifiers
|
||||
@@ -1165,10 +1165,7 @@ struct damage_calc_diag {
|
||||
u8 field_0x1;
|
||||
u8 field_0x2;
|
||||
u8 field_0x3;
|
||||
enum move_category move_category; // 0x4: The category of the last move used
|
||||
u8 field_0x5;
|
||||
u8 field_0x6;
|
||||
u8 field_0x7;
|
||||
s32 move_category;
|
||||
// 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
|
||||
@@ -1222,29 +1219,29 @@ struct damage_calc_diag {
|
||||
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;
|
||||
u8 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;
|
||||
u8 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;
|
||||
u8 ability_offense_modifier;
|
||||
// 0x33: The net number of defense boosts to a defender due to Flower Gift
|
||||
s8 ability_defense_modifier;
|
||||
u8 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;
|
||||
u8 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;
|
||||
u8 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;
|
||||
u8 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;
|
||||
u8 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
|
||||
|
||||
12
include/overlay_29_0230BBAC.h
Normal file
12
include/overlay_29_0230BBAC.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef PMDSKY_OVERLAY_29_0230BBAC_H
|
||||
#define PMDSKY_OVERLAY_29_0230BBAC_H
|
||||
|
||||
#include "dungeon_mode.h"
|
||||
#include "enums.h"
|
||||
#include "overlay_29_02308FBC.h"
|
||||
|
||||
void CalcDamage(struct entity *attacker, struct entity *defender, enum type_id attack_type,
|
||||
s32 power, s32 crit_chance, struct unk_02308FE0 *damage_out,
|
||||
s32 damage_mult, enum move_id move_id, s32 a9);
|
||||
|
||||
#endif
|
||||
3
main.lsf
3
main.lsf
@@ -977,7 +977,8 @@ Overlay OVY_29
|
||||
Object src/type_effectiveness.o
|
||||
Object src/dungeon_damage.o
|
||||
Object asm/overlay_29_rodata_02352894.o
|
||||
Object asm/overlay_29_0230BBAC.o
|
||||
Object src/overlay_29_0230BBAC.o
|
||||
Object asm/overlay_29_0230D088.o
|
||||
Object src/dungeon_recruitment.o
|
||||
Object asm/overlay_29_0230E064.o
|
||||
Object src/overlay_29_0230E578.o
|
||||
|
||||
734
src/overlay_29_0230BBAC.c
Normal file
734
src/overlay_29_0230BBAC.c
Normal file
@@ -0,0 +1,734 @@
|
||||
#include "overlay_29_0230BBAC.h"
|
||||
#include "debug.h"
|
||||
#include "dg_random.h"
|
||||
#include "dungeon.h"
|
||||
#include "dungeon_logic.h"
|
||||
#include "dungeon_pokemon_attributes.h"
|
||||
#include "dungeon_pokemon_attributes_1.h"
|
||||
#include "dungeon_util_static.h"
|
||||
#include "enums.h"
|
||||
#include "item.h"
|
||||
#include "main_02001894.h"
|
||||
#include "main_02001A54.h"
|
||||
#include "main_02001BB4.h"
|
||||
#include "main_02001CD4.h"
|
||||
#include "main_02014CEC.h"
|
||||
#include "main_0201514C.h"
|
||||
#include "main_02054DC4.h"
|
||||
#include "move_orb_effects.h"
|
||||
#include "number_util.h"
|
||||
#include "overlay_29_022E3F20.h"
|
||||
#include "overlay_29_022E406C.h"
|
||||
#include "overlay_29_0230A994.h"
|
||||
#include "overlay_29_0230A9DC.h"
|
||||
#include "run_dungeon_1.h"
|
||||
#include "type_effectiveness.h"
|
||||
#include "weather.h"
|
||||
|
||||
extern struct dungeon *DUNGEON_PTR;
|
||||
extern u8 GetMonsterGenderVeneer(s16 monster_id);
|
||||
extern u8 ExclusiveItemOffenseBoost(struct entity *entity, s32 idx);
|
||||
extern u8 ExclusiveItemDefenseBoost(struct entity *entity, s32 idx);
|
||||
extern int MoveIsNotPhysical(enum move_id move_id);
|
||||
extern bool8 NearbyAllyIqSkillIsEnabled(struct entity *entity, enum iq_skill_id iq_skill);
|
||||
extern s32 FixedPoint64ToInt(struct fixed_point_64 *x);
|
||||
extern void AddFixedPoint64(struct fixed_point_64 *out, struct fixed_point_64 *a, struct fixed_point_64 *b);
|
||||
extern void ClampedLn(struct fixed_point_64 *out, s32 x);
|
||||
extern int IsRecoilMove(enum move_id move_id);
|
||||
extern void PlayEffectAnimation0x1A9__022E6130(struct entity *entity);
|
||||
extern void PlayEffectAnimation0x1A9__022E617C(struct entity *entity);
|
||||
extern void PlayEffectAnimation0x18E(struct entity *entity);
|
||||
extern bool8 AuraBowIsActive(struct entity *entity);
|
||||
extern bool8 FixedPoint64CmpLt(const struct fixed_point_64 *a, const struct fixed_point_64 *b);
|
||||
extern void DivideFixedPoint64(struct fixed_point_64 *out, struct fixed_point_64 *a, struct fixed_point_64 *b);
|
||||
extern void ResetDamageCalcDiagnostics(void);
|
||||
extern bool8 OtherMonsterAbilityIsActive(struct entity *entity, enum ability_id ability_id);
|
||||
extern void MultiplyFixedPoint64(struct fixed_point_64 *out, const struct fixed_point_64 *a, const struct fixed_point_64 *b);
|
||||
extern void LogMessageByIdWithPopupCheckUserTarget(struct entity *user, struct entity *target, u32 message_id);
|
||||
extern bool8 UpdateStateFlags(struct monster *info, s32 flag, bool8 value);
|
||||
extern void ResetDamageData(struct unk_02308FE0 *damage_data);
|
||||
extern void SubstitutePlaceholderStringTags(s32 string_id, struct entity *entity, u32 param_3);
|
||||
extern bool8 ExclusiveItemEffectIsActiveWithLogging(struct entity *user, struct entity *target, bool8 should_log, s32 message_id, enum exclusive_item_effect_id effect_id);
|
||||
extern const u8 ov29_02352984[];
|
||||
extern const u8 ov29_02352990[];
|
||||
extern const u8 ov29_0235299C[];
|
||||
extern const s32 ov29_02352838[];
|
||||
extern const s16 AURA_BOW_STAT_BOOST;
|
||||
extern const s16 DEF_SCARF_STAT_BOOST;
|
||||
extern const s16 MUNCH_BELT_STAT_BOOST;
|
||||
extern const s16 POWER_BAND_STAT_BOOST;
|
||||
extern const s16 SPECIAL_BAND_STAT_BOOST;
|
||||
extern const s16 ZINC_BAND_STAT_BOOST;
|
||||
extern const s16 SCOPE_LENS_CRIT_RATE_BOOST;
|
||||
extern const s16 SUPER_LUCK_CRIT_RATE_BOOST;
|
||||
extern const s16 TYPE_ADVANTAGE_MASTER_CRIT_RATE;
|
||||
extern const s32 AIR_BLADE_DAMAGE_MULTIPLIER;
|
||||
extern const s32 ME_FIRST_MULTIPLIER;
|
||||
extern const s32 POWER_PITCHER_DAMAGE_MULTIPLIER;
|
||||
extern const s32 DAMAGE_FORMULA_AT_PREFACTOR;
|
||||
extern const s32 DAMAGE_FORMULA_CONSTANT_SHIFT;
|
||||
extern const s32 DAMAGE_FORMULA_DEF_PREFACTOR;
|
||||
extern const s32 DAMAGE_FORMULA_FLV_DEFICIT_DIVISOR;
|
||||
extern const s32 DAMAGE_FORMULA_FLV_SHIFT;
|
||||
extern const s32 DAMAGE_FORMULA_LN_ARG_PREFACTOR;
|
||||
extern const s32 DAMAGE_FORMULA_LN_PREFACTOR;
|
||||
extern const s32 DAMAGE_FORMULA_NON_TEAM_MEMBER_MODIFIER;
|
||||
extern const s32 OFFENSIVE_STAT_STAGE_MULTIPLIERS[21];
|
||||
extern const s32 DEFENSIVE_STAT_STAGE_MULTIPLIERS[21];
|
||||
extern const struct fixed_point_64 DAMAGE_FORMULA_MAX_BASE;
|
||||
extern const struct fixed_point_64 DAMAGE_FORMULA_MIN_BASE;
|
||||
extern const struct fixed_point_64 DAMAGE_MULTIPLIER_0_5;
|
||||
extern const struct fixed_point_64 DAMAGE_MULTIPLIER_1_5;
|
||||
extern const struct fixed_point_64 DAMAGE_MULTIPLIER_2;
|
||||
|
||||
#ifdef JAPAN
|
||||
#define MESSAGE_C53 0x992
|
||||
#define MESSAGE_C54 0x993
|
||||
#define MESSAGE_C55 0x994
|
||||
#define MESSAGE_C57 0x996
|
||||
#define MESSAGE_C58 0x997
|
||||
#define MESSAGE_DC1 0xB01
|
||||
#else
|
||||
#define MESSAGE_C53 0xC53
|
||||
#define MESSAGE_C54 0xC54
|
||||
#define MESSAGE_C55 0xC55
|
||||
#define MESSAGE_C57 0xC57
|
||||
#define MESSAGE_C58 0xC58
|
||||
#define MESSAGE_DC1 0xDC1
|
||||
#endif
|
||||
|
||||
void CalcDamage(struct entity *attacker, struct entity *defender, enum type_id attack_type,
|
||||
s32 power, s32 crit_chance, struct unk_02308FE0 *damage_out,
|
||||
s32 damage_mult, enum move_id move_id, s32 a9)
|
||||
{
|
||||
struct fixed_point_64 type_mult;
|
||||
struct fixed_point_64 base;
|
||||
struct fixed_point_64 flv_fp;
|
||||
struct fixed_point_64 at_fp;
|
||||
struct fixed_point_64 def_fp;
|
||||
s32 calc[2];
|
||||
struct fixed_point_64 tmp2;
|
||||
struct fixed_point_64 tmp;
|
||||
struct fixed_point_64 scratch;
|
||||
struct fixed_point_64 tmp3;
|
||||
struct fixed_point_64 mult_fp;
|
||||
struct fixed_point_64 ln_fp;
|
||||
struct fixed_point_64 mult32_fp;
|
||||
struct fixed_point_64 hundred_fp;
|
||||
struct monster *amon;
|
||||
struct monster *dmon;
|
||||
bool8 has_status;
|
||||
s32 off_stage;
|
||||
s32 ability_roll;
|
||||
s32 off_mult;
|
||||
s32 def_mult;
|
||||
bool8 has_status2;
|
||||
bool8 has_status3;
|
||||
s32 not_physical2;
|
||||
s32 def_ability_div;
|
||||
s32 def_ability_mult;
|
||||
s32 dv;
|
||||
s32 p;
|
||||
struct monster *info;
|
||||
struct monster *info2;
|
||||
int dmult;
|
||||
s32 not_physical;
|
||||
s32 is_team_member;
|
||||
s32 def_stage;
|
||||
s32 off_ability_mult;
|
||||
s32 off_ability_div;
|
||||
s32 off_mod;
|
||||
s32 def_mod;
|
||||
bool8 boosted;
|
||||
s32 type_boosted;
|
||||
s32 rate;
|
||||
s32 flash;
|
||||
volatile s32 *po;
|
||||
volatile s32 *po2;
|
||||
volatile s32 *pd;
|
||||
struct damage_calc_diag *diag;
|
||||
|
||||
amon = GetEntInfo(attacker);
|
||||
dmon = GetEntInfo(defender);
|
||||
dmult = damage_mult;
|
||||
diag = &DUNGEON_PTR->last_damage_calc;
|
||||
ResetDamageData(damage_out);
|
||||
|
||||
if (amon->me_first_flag) {
|
||||
dmult = MultiplyByFixedPoint(dmult, ME_FIRST_MULTIPLIER);
|
||||
}
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_RECKLESS) && IsRecoilMove(move_id)) {
|
||||
dmult = dmult * 3 / 2;
|
||||
}
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_IRON_FIST) && IsPunchMove(move_id)) {
|
||||
dmult = MultiplyByFixedPoint(dmult, 0x180);
|
||||
}
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_NORMALIZE)) {
|
||||
attack_type = TYPE_NORMAL;
|
||||
}
|
||||
if (move_id == 0x1D3) {
|
||||
attack_type = amon->types[0];
|
||||
}
|
||||
not_physical = MoveIsNotPhysical(move_id);
|
||||
ResetDamageCalcDiagnostics();
|
||||
|
||||
if (!amon->is_team_leader && CeilFixedPoint(amon->belly) == 0) {
|
||||
damage_out->field_0x0 = 1;
|
||||
damage_out->field_0x4 = 0;
|
||||
damage_out->field_0x8 = MATCHUP_NEUTRAL;
|
||||
damage_out->field_0xc = attack_type;
|
||||
damage_out->field_0xd = GetMoveCategory(move_id);
|
||||
damage_out->field_0xe = FALSE;
|
||||
damage_out->field_0xf = FALSE;
|
||||
damage_out->field_0x10 = FALSE;
|
||||
return;
|
||||
}
|
||||
#ifdef JAPAN
|
||||
if (move_id == 0x163
|
||||
&& DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_WONDER_GUARD)) {
|
||||
#else
|
||||
if (move_id == 0x163
|
||||
&& DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_WONDER_GUARD, TRUE)) {
|
||||
#endif
|
||||
damage_out->field_0x0 = 1;
|
||||
damage_out->field_0x4 = 0;
|
||||
damage_out->field_0x8 = MATCHUP_NEUTRAL;
|
||||
damage_out->field_0xc = attack_type;
|
||||
damage_out->field_0xd = GetMoveCategory(move_id);
|
||||
damage_out->field_0xe = FALSE;
|
||||
damage_out->field_0xf = FALSE;
|
||||
damage_out->field_0x10 = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
damage_out->field_0xc = attack_type;
|
||||
damage_out->field_0xd = GetMoveCategory(move_id);
|
||||
diag->move_type = attack_type;
|
||||
off_mod = 0;
|
||||
def_mod = 0;
|
||||
diag->move_category = not_physical;
|
||||
off_mult = amon->stat_modifiers.offensive_multipliers[not_physical];
|
||||
def_mult = dmon->stat_modifiers.defensive_multipliers[not_physical];
|
||||
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_DOWNLOAD)) {
|
||||
if (dmon->defensive_stats[0] >= dmon->defensive_stats[1]) {
|
||||
if (not_physical == 1) {
|
||||
off_mod++;
|
||||
diag->ability_offense_modifier++;
|
||||
}
|
||||
} else if (not_physical == 0) {
|
||||
off_mod++;
|
||||
diag->ability_offense_modifier++;
|
||||
}
|
||||
}
|
||||
|
||||
off_stage = amon->stat_modifiers.offensive_stages[not_physical];
|
||||
if (a9) {
|
||||
if (attack_type == TYPE_FIRE) {
|
||||
s16 boost = amon->stat_modifiers.flash_fire_boost;
|
||||
diag->flash_fire_boost = boost;
|
||||
off_mod += boost;
|
||||
}
|
||||
}
|
||||
|
||||
if (IqSkillIsEnabled(attacker, IQ_AGGRESSOR)) {
|
||||
off_mod++;
|
||||
diag->iq_skill_offense_modifier++;
|
||||
}
|
||||
if (IqSkillIsEnabled(attacker, IQ_DEFENDER)) {
|
||||
off_mod--;
|
||||
diag->iq_skill_offense_modifier--;
|
||||
}
|
||||
if (IqSkillIsEnabled(attacker, IQ_PRACTICE_SWINGER) && amon->practice_swinger_flag) {
|
||||
off_mod++;
|
||||
diag->iq_skill_offense_modifier++;
|
||||
}
|
||||
if (NearbyAllyIqSkillIsEnabled(attacker, IQ_CHEERLEADER)) {
|
||||
off_mod++;
|
||||
}
|
||||
|
||||
if (not_physical == 0) {
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_RIVALRY)) {
|
||||
if (GendersEqualNotGenderless(amon->apparent_id, dmon->apparent_id)) {
|
||||
off_mod++;
|
||||
diag->ability_offense_modifier++;
|
||||
} else if (GetMonsterGenderVeneer(amon->apparent_id) != 3
|
||||
&& GetMonsterGenderVeneer(dmon->apparent_id) != 3) {
|
||||
off_mod--;
|
||||
diag->ability_offense_modifier--;
|
||||
}
|
||||
}
|
||||
if (GetApparentWeather(attacker) == WEATHER_SUNNY
|
||||
&& (AbilityIsActiveVeneer(attacker, ABILITY_FLOWER_GIFT)
|
||||
|| OtherMonsterAbilityIsActive(attacker, ABILITY_FLOWER_GIFT))) {
|
||||
off_mod++;
|
||||
diag->ability_offense_modifier++;
|
||||
}
|
||||
} else {
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_SOLAR_POWER)
|
||||
&& GetApparentWeather(attacker) == WEATHER_SUNNY) {
|
||||
off_mod += 2;
|
||||
diag->ability_offense_modifier += 2;
|
||||
}
|
||||
if (GetApparentWeather(defender) == WEATHER_SUNNY
|
||||
&& (AbilityIsActiveVeneer(defender, ABILITY_FLOWER_GIFT)
|
||||
|| OtherMonsterAbilityIsActive(defender, ABILITY_FLOWER_GIFT))) {
|
||||
def_mod++;
|
||||
diag->ability_defense_modifier++;
|
||||
}
|
||||
if (GetApparentWeather(defender) == WEATHER_SANDSTORM
|
||||
&& (dmon->types[0] == TYPE_ROCK || dmon->types[1] == TYPE_ROCK)) {
|
||||
def_mod += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (amon->apparent_id == 0x1A3) {
|
||||
off_mod += 2;
|
||||
}
|
||||
if (amon->apparent_id == 0x1A4) {
|
||||
off_mod -= 2;
|
||||
}
|
||||
if (amon->apparent_id == 0x1A5) {
|
||||
off_mod -= 2;
|
||||
}
|
||||
if (amon->apparent_id == 0x211) {
|
||||
off_mod -= 2;
|
||||
} else if (amon->apparent_id == 0x218) {
|
||||
off_mod += 2;
|
||||
}
|
||||
|
||||
off_stage += off_mod;
|
||||
if (amon->anger_point_flag && AbilityIsActiveVeneer(attacker, ABILITY_ANGER_POINT)) {
|
||||
off_stage = 20;
|
||||
}
|
||||
|
||||
def_stage = dmon->stat_modifiers.defensive_stages[not_physical];
|
||||
if (not_physical == 0) {
|
||||
if (dmon->bide_class_status.bide == 6) {
|
||||
diag->skull_bash_defense_boost_activated = TRUE;
|
||||
def_mod++;
|
||||
}
|
||||
if (IqSkillIsEnabled(defender, IQ_COUNTER_BASHER)) {
|
||||
def_mod--;
|
||||
diag->iq_skill_defense_modifier--;
|
||||
}
|
||||
}
|
||||
if (IqSkillIsEnabled(defender, IQ_AGGRESSOR)) {
|
||||
def_mod--;
|
||||
diag->iq_skill_defense_modifier--;
|
||||
}
|
||||
if (IqSkillIsEnabled(defender, IQ_DEFENDER)) {
|
||||
def_mod++;
|
||||
diag->iq_skill_defense_modifier++;
|
||||
}
|
||||
if (dmon->apparent_id == 0x1A3) {
|
||||
def_mod -= 2;
|
||||
}
|
||||
if (dmon->apparent_id == 0x1A4) {
|
||||
def_mod += 2;
|
||||
}
|
||||
if (dmon->apparent_id == 0x1A5) {
|
||||
def_mod -= 2;
|
||||
}
|
||||
#ifdef JAPAN
|
||||
if (amon->apparent_id == 0x211) {
|
||||
def_mod += 2;
|
||||
} else if (amon->apparent_id == 0x218) {
|
||||
def_mod -= 2;
|
||||
}
|
||||
#else
|
||||
if (dmon->apparent_id == 0x211) {
|
||||
def_mod += 2;
|
||||
} else if (dmon->apparent_id == 0x218) {
|
||||
def_mod -= 2;
|
||||
}
|
||||
#endif
|
||||
def_stage += def_mod;
|
||||
|
||||
if (move_id == 0x1BD) {
|
||||
s16 sum = 0;
|
||||
|
||||
if (dmon->stat_modifiers.offensive_stages[0] > 10) {
|
||||
sum += dmon->stat_modifiers.offensive_stages[0] - 10;
|
||||
}
|
||||
if (dmon->stat_modifiers.defensive_stages[0] > 10) {
|
||||
sum += dmon->stat_modifiers.defensive_stages[0] - 10;
|
||||
}
|
||||
if (dmon->stat_modifiers.offensive_stages[1] > 10) {
|
||||
sum += dmon->stat_modifiers.offensive_stages[1] - 10;
|
||||
}
|
||||
if (dmon->stat_modifiers.defensive_stages[1] > 10) {
|
||||
sum += dmon->stat_modifiers.defensive_stages[1] - 10;
|
||||
}
|
||||
off_stage += sum;
|
||||
}
|
||||
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_UNAWARE)) {
|
||||
def_stage = 10;
|
||||
def_mult = 0x100;
|
||||
#ifdef JAPAN
|
||||
} else if (DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_UNAWARE)) {
|
||||
#else
|
||||
} else if (DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_UNAWARE, TRUE)) {
|
||||
#endif
|
||||
off_stage = 10;
|
||||
off_mult = 0x100;
|
||||
}
|
||||
|
||||
if (off_stage < 0) {
|
||||
off_stage = 0;
|
||||
}
|
||||
if (off_stage > 20) {
|
||||
off_stage = 20;
|
||||
}
|
||||
diag->offensive_stat_stage = off_stage;
|
||||
diag->offensive_stat = amon->offensive_stats[not_physical];
|
||||
calc[0] = MultiplyByFixedPoint(
|
||||
MultiplyByFixedPoint(amon->offensive_stats[not_physical] << 8,
|
||||
OFFENSIVE_STAT_STAGE_MULTIPLIERS[off_stage]),
|
||||
off_mult) >> 8;
|
||||
|
||||
if (def_stage < 0) {
|
||||
def_stage = 0;
|
||||
}
|
||||
if (def_stage > 20) {
|
||||
def_stage = 20;
|
||||
}
|
||||
diag->defensive_stat_stage = def_stage;
|
||||
diag->defensive_stat = dmon->defensive_stats[not_physical];
|
||||
calc[1] = MultiplyByFixedPoint(
|
||||
MultiplyByFixedPoint(dmon->defensive_stats[not_physical] << 8,
|
||||
DEFENSIVE_STAT_STAGE_MULTIPLIERS[def_stage]),
|
||||
def_mult) >> 8;
|
||||
|
||||
if (!amon->is_not_team_member) {
|
||||
calc[0] += ExclusiveItemOffenseBoost(attacker, not_physical);
|
||||
}
|
||||
if (!dmon->is_not_team_member) {
|
||||
calc[1] += ExclusiveItemDefenseBoost(defender, not_physical);
|
||||
}
|
||||
|
||||
if (not_physical == 0) {
|
||||
if (ItemIsActive__0230A9DC(attacker, ITEM_POWER_BAND)) {
|
||||
calc[0] += POWER_BAND_STAT_BOOST;
|
||||
diag->item_atk_modifier += POWER_BAND_STAT_BOOST;
|
||||
}
|
||||
if (ItemIsActive__0230A9DC(attacker, ITEM_MUNCH_BELT)) {
|
||||
calc[0] += MUNCH_BELT_STAT_BOOST;
|
||||
diag->item_atk_modifier += MUNCH_BELT_STAT_BOOST;
|
||||
}
|
||||
if (AuraBowIsActive(attacker)) {
|
||||
calc[0] += AURA_BOW_STAT_BOOST;
|
||||
diag->item_sp_atk_modifier += AURA_BOW_STAT_BOOST;
|
||||
}
|
||||
if (a9) {
|
||||
if (ItemIsActive__0230A9DC(defender, ITEM_DEF_SCARF)) {
|
||||
calc[1] += DEF_SCARF_STAT_BOOST;
|
||||
diag->item_def_modifier += DEF_SCARF_STAT_BOOST;
|
||||
}
|
||||
if (AuraBowIsActive(defender)) {
|
||||
calc[1] += AURA_BOW_STAT_BOOST;
|
||||
diag->item_def_modifier += AURA_BOW_STAT_BOOST;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (a9) {
|
||||
if (ItemIsActive__0230A9DC(defender, ITEM_ZINC_BAND)) {
|
||||
calc[1] += ZINC_BAND_STAT_BOOST;
|
||||
diag->item_sp_def_modifier += ZINC_BAND_STAT_BOOST;
|
||||
}
|
||||
if (AuraBowIsActive(defender)) {
|
||||
calc[1] += AURA_BOW_STAT_BOOST;
|
||||
diag->item_def_modifier += AURA_BOW_STAT_BOOST;
|
||||
}
|
||||
}
|
||||
if (ItemIsActive__0230A9DC(attacker, ITEM_SPECIAL_BAND)) {
|
||||
calc[0] += SPECIAL_BAND_STAT_BOOST;
|
||||
diag->item_sp_atk_modifier += SPECIAL_BAND_STAT_BOOST;
|
||||
}
|
||||
if (ItemIsActive__0230A9DC(attacker, ITEM_MUNCH_BELT)) {
|
||||
calc[0] += MUNCH_BELT_STAT_BOOST;
|
||||
diag->item_sp_atk_modifier += MUNCH_BELT_STAT_BOOST;
|
||||
}
|
||||
if (AuraBowIsActive(defender)) {
|
||||
calc[0] += AURA_BOW_STAT_BOOST;
|
||||
diag->item_sp_atk_modifier += AURA_BOW_STAT_BOOST;
|
||||
}
|
||||
}
|
||||
|
||||
po = &calc[0];
|
||||
po2 = &calc[0];
|
||||
FixedPoint32To64(&at_fp,
|
||||
MultiplyByFixedPoint(MultiplyByFixedPoint(power << 8,
|
||||
OFFENSIVE_STAT_STAGE_MULTIPLIERS[off_stage]),
|
||||
off_mult));
|
||||
ability_roll = DungeonRandInt(100);
|
||||
amon->prev_state_flags &= ~0x100;
|
||||
amon->state_flags &= ~0x100;
|
||||
off_ability_mult = 1;
|
||||
off_ability_div = 1;
|
||||
def_ability_mult = 1;
|
||||
def_ability_div = 1;
|
||||
|
||||
not_physical2 = MoveIsNotPhysical(move_id);
|
||||
if (not_physical2 == 0 && AbilityIsActiveVeneer(attacker, ABILITY_GUTS)) {
|
||||
info = attacker->info;
|
||||
has_status = MonsterHasNegativeStatus(attacker, TRUE);
|
||||
boosted = UpdateStateFlags(info, 1, has_status);
|
||||
if (has_status) {
|
||||
off_ability_mult <<= 1;
|
||||
}
|
||||
if (boosted) {
|
||||
PlayEffectAnimation0x1A9__022E6130(attacker);
|
||||
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C53);
|
||||
}
|
||||
}
|
||||
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_HUGE_POWER)
|
||||
|| AbilityIsActiveVeneer(attacker, ABILITY_PURE_POWER)) {
|
||||
info = attacker->info;
|
||||
has_status2 = (ability_roll < 0x21 && not_physical2 == 0);
|
||||
boosted = UpdateStateFlags(info, 0x100, has_status2);
|
||||
if (has_status2) {
|
||||
off_ability_mult += off_ability_mult * 2;
|
||||
off_ability_div <<= 1;
|
||||
}
|
||||
if (boosted) {
|
||||
PlayEffectAnimation0x1A9__022E617C(attacker);
|
||||
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C54);
|
||||
}
|
||||
}
|
||||
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_HUSTLE) && not_physical2 == 0) {
|
||||
off_ability_mult += off_ability_mult * 2;
|
||||
off_ability_div <<= 1;
|
||||
}
|
||||
|
||||
is_team_member = !((struct monster *)attacker->info)->is_not_team_member;
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_PLUS) && not_physical2 == 1
|
||||
&& DUNGEON_PTR->minus_is_active[is_team_member]) {
|
||||
off_ability_mult = off_ability_mult * 16 - off_ability_mult;
|
||||
off_ability_div *= 10;
|
||||
}
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_MINUS) && not_physical2 == 1
|
||||
&& DUNGEON_PTR->plus_is_active[is_team_member]) {
|
||||
off_ability_mult = off_ability_mult * 16 - off_ability_mult;
|
||||
off_ability_div *= 10;
|
||||
}
|
||||
|
||||
#ifdef JAPAN
|
||||
if (DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_INTIMIDATE)
|
||||
&& not_physical2 == 0) {
|
||||
#else
|
||||
if (DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_INTIMIDATE, TRUE)
|
||||
&& not_physical2 == 0) {
|
||||
#endif
|
||||
off_ability_mult <<= 2;
|
||||
off_ability_div += off_ability_div * 4;
|
||||
}
|
||||
#ifdef JAPAN
|
||||
if (DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_MARVEL_SCALE)
|
||||
&& not_physical2 == 0) {
|
||||
#else
|
||||
if (DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_MARVEL_SCALE, TRUE)
|
||||
&& not_physical2 == 0) {
|
||||
#endif
|
||||
info2 = defender->info;
|
||||
has_status3 = MonsterHasNegativeStatus(defender, TRUE);
|
||||
boosted = UpdateStateFlags(info2, 8, has_status3);
|
||||
if (has_status3) {
|
||||
def_ability_mult = def_ability_mult * 3;
|
||||
def_ability_div <<= 1;
|
||||
}
|
||||
if (boosted) {
|
||||
PlayEffectAnimation0x18E(defender);
|
||||
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C55);
|
||||
}
|
||||
}
|
||||
|
||||
pd = &calc[1];
|
||||
p = *po * off_ability_mult;
|
||||
dv = *pd;
|
||||
*pd = dv * def_ability_mult;
|
||||
*po2 = p;
|
||||
if (off_ability_div != 1) {
|
||||
*po2 = p / off_ability_div;
|
||||
}
|
||||
if (def_ability_div != 1) {
|
||||
pd = &calc[1];
|
||||
*pd = *pd / def_ability_div;
|
||||
}
|
||||
|
||||
diag->offense_calc = calc[0];
|
||||
diag->defense_calc = calc[1];
|
||||
if (calc[0] < 0) {
|
||||
calc[0] = 0;
|
||||
}
|
||||
if (calc[0] >= 999) {
|
||||
calc[0] = 999;
|
||||
}
|
||||
diag->damage_calc_def = calc[1];
|
||||
IntToFixedPoint64(&def_fp, calc[1]);
|
||||
IntToFixedPoint64(&tmp2, calc[0] - calc[1]);
|
||||
FixedPoint32To64(&tmp, DAMAGE_FORMULA_FLV_DEFICIT_DIVISOR);
|
||||
DivideFixedPoint64(&tmp2, &tmp2, &tmp);
|
||||
IntToFixedPoint64(&tmp, amon->level);
|
||||
AddFixedPoint64(&flv_fp, &tmp, &tmp2);
|
||||
IntToFixedPoint64(&tmp, calc[0]);
|
||||
AddFixedPoint64(&at_fp, &at_fp, &tmp);
|
||||
diag->damage_calc_at = FixedPoint64ToInt(&at_fp);
|
||||
diag->attacker_level = amon->level;
|
||||
diag->damage_calc_flv = FixedPoint64ToInt(&flv_fp);
|
||||
Debug_Print0(ov29_02352984, FixedPoint64ToInt(&flv_fp));
|
||||
Debug_Print0(ov29_02352990, FixedPoint64ToInt(&at_fp));
|
||||
Debug_Print0(ov29_0235299C, FixedPoint64ToInt(&def_fp));
|
||||
|
||||
FixedPoint32To64(&tmp3, DAMAGE_FORMULA_AT_PREFACTOR);
|
||||
MultiplyFixedPoint64(&tmp3, &at_fp, &tmp3);
|
||||
FixedPoint32To64(&mult_fp, DAMAGE_FORMULA_DEF_PREFACTOR);
|
||||
MultiplyFixedPoint64(&mult_fp, &def_fp, &mult_fp);
|
||||
FixedPoint32To64(&scratch, DAMAGE_FORMULA_FLV_SHIFT);
|
||||
AddFixedPoint64(&ln_fp, &flv_fp, &scratch);
|
||||
FixedPoint32To64(&scratch, DAMAGE_FORMULA_LN_ARG_PREFACTOR);
|
||||
MultiplyFixedPoint64(&ln_fp, &ln_fp, &scratch);
|
||||
ClampedLn(&ln_fp, FixedPoint64ToInt(&ln_fp));
|
||||
FixedPoint32To64(&scratch, DAMAGE_FORMULA_LN_PREFACTOR);
|
||||
MultiplyFixedPoint64(&ln_fp, &ln_fp, &scratch);
|
||||
AddFixedPoint64(&base, &mult_fp, &tmp3);
|
||||
AddFixedPoint64(&base, &base, &ln_fp);
|
||||
FixedPoint32To64(&scratch, DAMAGE_FORMULA_CONSTANT_SHIFT);
|
||||
AddFixedPoint64(&base, &base, &scratch);
|
||||
|
||||
if (!FixedRoomIsSubstituteRoom() && amon->is_not_team_member) {
|
||||
FixedPoint32To64(&scratch, DAMAGE_FORMULA_NON_TEAM_MEMBER_MODIFIER);
|
||||
DivideFixedPoint64(&base, &base, &scratch);
|
||||
}
|
||||
|
||||
if (FixedPoint64CmpLt(&DAMAGE_FORMULA_MAX_BASE, &base)) {
|
||||
base.lower = ((const struct fixed_point_64 *)&ov29_02352838[13])->lower;
|
||||
base.upper = ((const struct fixed_point_64 *)&ov29_02352838[13])->upper;
|
||||
}
|
||||
if (FixedPoint64CmpLt(&base, &DAMAGE_FORMULA_MIN_BASE)) {
|
||||
base.lower = ((const struct fixed_point_64 *)&ov29_02352838[17])->lower;
|
||||
base.upper = ((const struct fixed_point_64 *)&ov29_02352838[17])->upper;
|
||||
}
|
||||
|
||||
type_boosted = CalcTypeBasedDamageEffects(&type_mult, attacker, defender, power, attack_type,
|
||||
damage_out, IsRegularAttackOrProjectile(move_id) != 0);
|
||||
|
||||
if (attack_type == TYPE_FIRE) {
|
||||
flash = FlashFireShouldActivate(attacker, defender);
|
||||
if (flash && !dmon->apply_flash_fire_boost && a9) {
|
||||
dmon->apply_flash_fire_boost = TRUE;
|
||||
SubstitutePlaceholderStringTags(1, defender, 0);
|
||||
if (flash == 1) {
|
||||
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C58);
|
||||
} else {
|
||||
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C57);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (a9 && !ExclusiveItemEffectIsActive__0230A9B8(attacker, EXCLUSIVE_EFF_BYPASS_REFLECT_LIGHT_SCREEN)) {
|
||||
if (not_physical == 0) {
|
||||
if ((move_id != 0x48 && dmon->reflect_class_status.reflect == 1)
|
||||
|| ExclusiveItemEffectIsActive__0230A9B8(defender, EXCLUSIVE_EFF_HALVED_PHYSICAL_DAMAGE)) {
|
||||
PlayEffectAnimation0x171(defender);
|
||||
MultiplyFixedPoint64(&type_mult, &type_mult, &DAMAGE_MULTIPLIER_0_5);
|
||||
diag->half_physical_damage_activated = TRUE;
|
||||
}
|
||||
}
|
||||
if (not_physical == 1
|
||||
&& (dmon->reflect_class_status.reflect == 3
|
||||
|| ExclusiveItemEffectIsActive__0230A9B8(defender, EXCLUSIVE_EFF_HALVED_SPECIAL_DAMAGE))) {
|
||||
PlayEffectAnimation0x171Full(defender);
|
||||
MultiplyFixedPoint64(&type_mult, &type_mult, &DAMAGE_MULTIPLIER_0_5);
|
||||
diag->half_special_damage_activated = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JAPAN
|
||||
if (dmon->reflect_class_status.reflect != 0x11
|
||||
&& !DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_BATTLE_ARMOR)
|
||||
&& !DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_SHELL_ARMOR)
|
||||
&& !IqSkillIsEnabled(defender, IQ_CRITICAL_DODGER)) {
|
||||
#else
|
||||
if (dmon->reflect_class_status.reflect != 0x11
|
||||
&& !DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_BATTLE_ARMOR, TRUE)
|
||||
&& !DefenderAbilityIsActive__0230A940(attacker, defender, ABILITY_SHELL_ARMOR, TRUE)
|
||||
&& !IqSkillIsEnabled(defender, IQ_CRITICAL_DODGER)) {
|
||||
#endif
|
||||
if (GetMonsterGenderVeneer(amon->id) == 2) {
|
||||
rate = crit_chance;
|
||||
} else {
|
||||
rate = crit_chance + crit_chance / 2;
|
||||
}
|
||||
if (amon->sure_shot_class_status.sure_shot == 4) {
|
||||
rate = 999;
|
||||
diag->focus_energy_activated = TRUE;
|
||||
} else {
|
||||
if (ItemIsActive__0230A9DC(attacker, ITEM_SCOPE_LENS)
|
||||
|| IqSkillIsEnabled(attacker, IQ_SHARPSHOOTER)) {
|
||||
diag->scope_lens_or_sharpshooter_activated = TRUE;
|
||||
rate += SCOPE_LENS_CRIT_RATE_BOOST;
|
||||
}
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_SUPER_LUCK)) {
|
||||
diag->super_luck_activated = TRUE;
|
||||
rate += SUPER_LUCK_CRIT_RATE_BOOST;
|
||||
}
|
||||
if (ItemIsActive__0230A9DC(defender, ITEM_PATSY_BAND)) {
|
||||
diag->patsy_band_activated = TRUE;
|
||||
rate += SCOPE_LENS_CRIT_RATE_BOOST;
|
||||
}
|
||||
if (type_boosted && IqSkillIsEnabled(attacker, IQ_TYPE_ADVANTAGE_MASTER)) {
|
||||
diag->type_advantage_master_activated = TRUE;
|
||||
rate = TYPE_ADVANTAGE_MASTER_CRIT_RATE;
|
||||
}
|
||||
}
|
||||
if (DungeonRandInt(100) < rate
|
||||
&& !ExclusiveItemEffectIsActiveWithLogging(attacker, defender, TRUE, MESSAGE_DC1, EXCLUSIVE_EFF_NO_CRITICAL_HITS)) {
|
||||
damage_out->field_0xe = TRUE;
|
||||
if (AbilityIsActiveVeneer(attacker, ABILITY_SNIPER)) {
|
||||
MultiplyFixedPoint64(&type_mult, &type_mult, &DAMAGE_MULTIPLIER_2);
|
||||
diag->sniper_activated = TRUE;
|
||||
} else {
|
||||
MultiplyFixedPoint64(&type_mult, &type_mult, &DAMAGE_MULTIPLIER_1_5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
diag->damage_calc_base = FixedPoint64ToInt(&base);
|
||||
MultiplyFixedPoint64(&base, &base, &type_mult);
|
||||
diag->static_damage_mult = dmult;
|
||||
FixedPoint32To64(&mult32_fp, dmult);
|
||||
MultiplyFixedPoint64(&base, &base, &mult32_fp);
|
||||
diag->damage_calc = FixedPoint64ToInt(&base);
|
||||
|
||||
type_mult.lower = DungeonRandInt(0x4000);
|
||||
type_mult.upper = 0;
|
||||
type_mult.lower += 0xE000;
|
||||
MultiplyFixedPoint64(&base, &base, &type_mult);
|
||||
IntToFixedPoint64(&hundred_fp, 100);
|
||||
MultiplyFixedPoint64(&type_mult, &hundred_fp, &type_mult);
|
||||
diag->damage_calc_random_mult_pct = FixedPoint64ToInt(&type_mult);
|
||||
damage_out->field_0x0 = FixedPoint64ToInt(&base);
|
||||
|
||||
if (move_id == 0x195) {
|
||||
damage_out->field_0x0 = RoundUpDiv256(MultiplyByFixedPoint(damage_out->field_0x0 << 8, 0x80));
|
||||
}
|
||||
if (move_id == 0x195 && IqSkillIsEnabled(attacker, IQ_POWER_PITCHER)) {
|
||||
damage_out->field_0x0 = RoundUpDiv256(
|
||||
MultiplyByFixedPoint(damage_out->field_0x0 << 8, POWER_PITCHER_DAMAGE_MULTIPLIER));
|
||||
}
|
||||
if (damage_out->field_0x0 > 0
|
||||
&& ExclusiveItemEffectIsActive__0230A9B8(attacker, EXCLUSIVE_EFF_DAMAGE_BOOST_50_PCT)) {
|
||||
damage_out->field_0x0 = RoundUpDiv256(
|
||||
MultiplyByFixedPoint(damage_out->field_0x0 << 8, AIR_BLADE_DAMAGE_MULTIPLIER));
|
||||
}
|
||||
|
||||
damage_out->field_0x4 = 0;
|
||||
if (damage_out->field_0x0 == 0) {
|
||||
damage_out->field_0xe = FALSE;
|
||||
}
|
||||
dmon->anger_point_flag = damage_out->field_0xe;
|
||||
}
|
||||
Reference in New Issue
Block a user