mirror of
https://github.com/pret/pmd-sky.git
synced 2026-04-25 15:42:34 -05:00
Merge pull request #121 from AnonymousRandomPerson/main
Some checks failed
build / build (push) Has been cancelled
Some checks failed
build / build (push) Has been cancelled
Decomped GetAiUseItemProbability
This commit is contained in:
commit
a37596a92b
|
|
@ -1,69 +1,70 @@
|
|||
#pragma once
|
||||
.public _020A1894
|
||||
.public AbilityIsActiveVeneer
|
||||
.public ATK_STAT_IDX
|
||||
.public AbilityIsActiveVeneer
|
||||
.public BoostIQ
|
||||
.public BoostOffensiveStat
|
||||
.public CalcDamageFixedNoCategory
|
||||
.public CanSeeInvisibleMonsters
|
||||
.public CeilFixedPoint
|
||||
.public ChangeDungeonMusic
|
||||
.public ChangeShayminForme
|
||||
.public CheckVariousStatuses2
|
||||
.public ClearMonsterActionFields
|
||||
.public DetermineAllMonsterShadow
|
||||
.public DetermineTileWalkableNeighbors
|
||||
.public DIRECTIONS_XY
|
||||
.public DUNGEON_PTR
|
||||
.public DirectoryFileMngr_OpenDirectoryFile
|
||||
.public DisplayMessage2
|
||||
.public DUNGEON_PTR
|
||||
.public DungeonRandInt
|
||||
.public DungeonRandOutcome__022EAB20
|
||||
.public EAT_ITEM_EFFECT_IGNORE_LIST
|
||||
.public EndBurnClassStatus
|
||||
.public EndFrozenClassStatus
|
||||
.public EnsureCanStandCurrentTile
|
||||
.public EntityIsValid__0231CBC8
|
||||
.public EntityIsValid__0231EDD8
|
||||
.public FemaleToMaleForm
|
||||
.public GetActiveTeamMember
|
||||
.public GetApparentWeather
|
||||
.public GetDoughSeedFlag
|
||||
.public GetItemMoveId16
|
||||
.public GetMaxPp
|
||||
.public GetMobilityType
|
||||
.public GetMoveBasePower
|
||||
.public GetMoveCategory
|
||||
.public GetMoveMaxGinsengBoost
|
||||
.public GetPerformanceFlagWithChecks
|
||||
.public GetTile
|
||||
.public GetTileSafe
|
||||
.public GetTreatmentBetweenMonsters
|
||||
.public GetWeatherColorTable
|
||||
.public GINSENG_CHANCE_3
|
||||
.public GUMMI_BELLY_RESTORE_TABLE
|
||||
.public GUMMI_IQ_STRING_IDS
|
||||
.public GUMMI_LIKE_STRING_IDS
|
||||
.public GetActiveTeamMember
|
||||
.public GetApparentWeather
|
||||
.public GetDoughSeedFlag
|
||||
.public GetItemMoveId16
|
||||
.public GetMoveBasePower
|
||||
.public GetMoveMaxGinsengBoost
|
||||
.public GetPerformanceFlagWithChecks
|
||||
.public GetWeatherColorTable
|
||||
.public HandleMovesMenuWrapper0
|
||||
.public HandleMovesMenuWrapper1
|
||||
.public HandleSir0Translation
|
||||
.public InitMove
|
||||
.public IQ_GUMMI_GAIN_TABLE
|
||||
.public IqSkillIsEnabled
|
||||
.public IsBlinded
|
||||
.public IsCurrentFixedRoomBossFight
|
||||
.public IsEdible
|
||||
.public IsExperienceLocked
|
||||
.public IsFullFloorFixedRoom
|
||||
.public IsHM
|
||||
.public IsItemValidVeneer
|
||||
.public LogMessageByIdWithPopup
|
||||
.public LogMessageByIdWithPopupCheckUser
|
||||
.public LogMessageByIdWithPopupCheckUserTarget
|
||||
.public LowerDefensiveStat
|
||||
.public LowerOffensiveStat
|
||||
.public MonsterHasNegativeStatus
|
||||
.public MusicTableIdxToMusicId
|
||||
.public RemoveUsedItem
|
||||
.public RestoreAllMovePP
|
||||
.public SPATK_STAT_IDX
|
||||
.public SetDoughSeedFlag
|
||||
.public SetMonsterActionFields
|
||||
.public ShouldDisplayEntityWrapper
|
||||
.public SubstitutePlaceholderStringTags
|
||||
.public TryDecreaseBelly
|
||||
.public TryIncreaseBelly
|
||||
.public TryInflictBurnStatus
|
||||
.public TryInflictEndureStatus
|
||||
.public TryInflictParalysisStatus
|
||||
.public TryInflictPoisonedStatus
|
||||
.public TryInflictShadowHoldStatus
|
||||
.public TryWarp
|
||||
.public UnloadFile
|
||||
.public UpdateMinimap
|
||||
.public WONDER_GUMMI_IQ_GAIN
|
||||
.public YesNoMenu
|
||||
.public _020A1894
|
||||
.public ov10_022C44CC
|
||||
.public ov10_022C44E8
|
||||
.public ov10_022C45D4
|
||||
|
|
@ -76,7 +77,6 @@
|
|||
.public ov29_022DD828
|
||||
.public ov29_022DE47C
|
||||
.public ov29_022DE608
|
||||
.public ov29_022E0378
|
||||
.public ov29_022E5AE4
|
||||
.public ov29_022E5BD8
|
||||
.public ov29_022EA370
|
||||
|
|
@ -94,18 +94,13 @@
|
|||
.public ov29_022F085C
|
||||
.public ov29_022F8830
|
||||
.public ov29_022F9C34
|
||||
.public ov29_022F9C74
|
||||
.public ov29_022FA02C
|
||||
.public ov29_022FBA54
|
||||
.public ov29_023008DC
|
||||
.public ov29_023009A0
|
||||
.public ov29_023021F0
|
||||
.public ov29_023038D4
|
||||
.public ov29_02305814
|
||||
.public ov29_0233665C
|
||||
.public ov29_0233785C
|
||||
.public ov29_02339FF4
|
||||
.public ov29_0233FB1C
|
||||
.public ov29_02344B44
|
||||
.public ov29_0234B084
|
||||
.public ov29_0234B09C
|
||||
|
|
@ -118,26 +113,5 @@
|
|||
.public ov31_02386204
|
||||
.public ov31_02386308
|
||||
.public ov31_023877EC
|
||||
.public RemoveUsedItem
|
||||
.public RestoreAllMovePP
|
||||
.public SetDoughSeedFlag
|
||||
.public SetMonsterActionFields
|
||||
.public ShouldDisplayEntityWrapper
|
||||
.public SPATK_STAT_IDX
|
||||
.public StairsAlwaysReachable
|
||||
.public sub_02050FF8
|
||||
.public sub_02053D1C
|
||||
.public SubstitutePlaceholderStringTags
|
||||
.public TryDecreaseBelly
|
||||
.public TryIncreaseBelly
|
||||
.public TryInflictBurnStatus
|
||||
.public TryInflictEndureStatus
|
||||
.public TryInflictParalysisStatus
|
||||
.public TryInflictPoisonedStatus
|
||||
.public TryInflictShadowHoldStatus
|
||||
.public TryWarp
|
||||
.public UnloadFile
|
||||
.public UpdateMinimap
|
||||
.public UpdateTrapsVisibility
|
||||
.public WONDER_GUMMI_IQ_GAIN
|
||||
.public YesNoMenu
|
||||
|
|
|
|||
27
asm/include/overlay_29_0231E8F0.inc
Normal file
27
asm/include/overlay_29_0231E8F0.inc
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
.public DIRECTIONS_XY
|
||||
.public DUNGEON_PTR
|
||||
.public DetermineAllMonsterShadow
|
||||
.public DetermineTileWalkableNeighbors
|
||||
.public EAT_ITEM_EFFECT_IGNORE_LIST
|
||||
.public EnsureCanStandCurrentTile
|
||||
.public EntityIsValid__0231EDD8
|
||||
.public GetMaxPp
|
||||
.public GetMoveCategory
|
||||
.public GetTile
|
||||
.public GetTileSafe
|
||||
.public GetTreatmentBetweenMonsters
|
||||
.public InitMove
|
||||
.public IsFullFloorFixedRoom
|
||||
.public IsItemValidVeneer
|
||||
.public LogMessageByIdWithPopupCheckUser
|
||||
.public StairsAlwaysReachable
|
||||
.public UpdateMinimap
|
||||
.public UpdateTrapsVisibility
|
||||
.public ov29_022E0378
|
||||
.public ov29_022EA370
|
||||
.public ov29_022F9C74
|
||||
.public ov29_02305814
|
||||
.public ov29_0233665C
|
||||
.public ov29_0233785C
|
||||
.public ov29_0233FB1C
|
||||
File diff suppressed because it is too large
Load Diff
392
asm/overlay_29_0231E8F0.s
Normal file
392
asm/overlay_29_0231E8F0.s
Normal file
|
|
@ -0,0 +1,392 @@
|
|||
.include "asm/macros.inc"
|
||||
.include "overlay_29_0231E8F0.inc"
|
||||
|
||||
.text
|
||||
|
||||
arm_func_start IsAdjacentToEnemy
|
||||
IsAdjacentToEnemy: ; 0x0231E8F0
|
||||
stmdb sp!, {r4, r5, r6, r7, r8, sb, sl, lr}
|
||||
mov r5, #0
|
||||
mov sl, #1
|
||||
mov r6, r0
|
||||
mov sb, r5
|
||||
mov r8, r5
|
||||
mov r7, sl
|
||||
ldr r4, _0231E98C ; =DIRECTIONS_XY
|
||||
b _0231E97C
|
||||
_0231E914:
|
||||
mov r1, r5, lsl #2
|
||||
add r0, r4, r5, lsl #2
|
||||
ldrsh ip, [r6, #4]
|
||||
ldrsh r3, [r4, r1]
|
||||
ldrsh r2, [r6, #6]
|
||||
ldrsh r1, [r0, #2]
|
||||
add r0, ip, r3
|
||||
add r1, r2, r1
|
||||
bl GetTile
|
||||
ldr r1, [r0, #0xc]
|
||||
cmp r1, #0
|
||||
beq _0231E978
|
||||
ldr r0, [r1]
|
||||
cmp r0, #0
|
||||
moveq r0, sl
|
||||
movne r0, sb
|
||||
cmp r0, #1
|
||||
beq _0231E978
|
||||
mov r0, r6
|
||||
mov r2, r8
|
||||
mov r3, r7
|
||||
bl GetTreatmentBetweenMonsters
|
||||
cmp r0, #1
|
||||
moveq r0, #1
|
||||
ldmeqia sp!, {r4, r5, r6, r7, r8, sb, sl, pc}
|
||||
_0231E978:
|
||||
add r5, r5, #1
|
||||
_0231E97C:
|
||||
cmp r5, #8
|
||||
blt _0231E914
|
||||
mov r0, #0
|
||||
ldmia sp!, {r4, r5, r6, r7, r8, sb, sl, pc}
|
||||
.align 2, 0
|
||||
_0231E98C: .word DIRECTIONS_XY
|
||||
arm_func_end IsAdjacentToEnemy
|
||||
|
||||
arm_func_start ShouldTryEatItem
|
||||
ShouldTryEatItem: ; 0x0231E990
|
||||
stmdb sp!, {r4, lr}
|
||||
mov r4, r0
|
||||
cmp r4, #0x45
|
||||
blt _0231E9A8
|
||||
cmp r4, #0x8a
|
||||
ble _0231E9B0
|
||||
_0231E9A8:
|
||||
mov r0, #0
|
||||
ldmia sp!, {r4, pc}
|
||||
_0231E9B0:
|
||||
bl IsItemValidVeneer
|
||||
cmp r0, #0
|
||||
moveq r0, #0
|
||||
ldmeqia sp!, {r4, pc}
|
||||
ldr r0, _0231E9EC ; =EAT_ITEM_EFFECT_IGNORE_LIST
|
||||
b _0231E9D8
|
||||
_0231E9C8:
|
||||
cmp r4, r1
|
||||
moveq r0, #0
|
||||
ldmeqia sp!, {r4, pc}
|
||||
add r0, r0, #2
|
||||
_0231E9D8:
|
||||
ldrsh r1, [r0]
|
||||
cmp r1, #0
|
||||
bne _0231E9C8
|
||||
mov r0, #1
|
||||
ldmia sp!, {r4, pc}
|
||||
.align 2, 0
|
||||
_0231E9EC: .word EAT_ITEM_EFFECT_IGNORE_LIST
|
||||
arm_func_end ShouldTryEatItem
|
||||
|
||||
arm_func_start GetMaxPpWrapper
|
||||
GetMaxPpWrapper: ; 0x0231E9F0
|
||||
stmdb sp!, {r3, lr}
|
||||
bl GetMaxPp
|
||||
mov r0, r0, lsl #0x10
|
||||
mov r0, r0, asr #0x10
|
||||
ldmia sp!, {r3, pc}
|
||||
arm_func_end GetMaxPpWrapper
|
||||
|
||||
arm_func_start ov29_0231EA04
|
||||
ov29_0231EA04: ; 0x0231EA04
|
||||
ldr ip, _0231EA14 ; =InitMove
|
||||
mov r0, r1
|
||||
mov r1, r2
|
||||
bx ip
|
||||
.align 2, 0
|
||||
_0231EA14: .word InitMove
|
||||
arm_func_end ov29_0231EA04
|
||||
|
||||
arm_func_start MoveIsNotPhysical
|
||||
MoveIsNotPhysical: ; 0x0231EA18
|
||||
stmdb sp!, {r3, lr}
|
||||
bl GetMoveCategory
|
||||
cmp r0, #0
|
||||
moveq r0, #0
|
||||
movne r0, #1
|
||||
ldmia sp!, {r3, pc}
|
||||
arm_func_end MoveIsNotPhysical
|
||||
|
||||
arm_func_start CategoryIsNotPhysical
|
||||
CategoryIsNotPhysical: ; 0x0231EA30
|
||||
cmp r0, #0
|
||||
moveq r0, #0
|
||||
movne r0, #1
|
||||
bx lr
|
||||
arm_func_end CategoryIsNotPhysical
|
||||
|
||||
arm_func_start ov29_0231EA40
|
||||
ov29_0231EA40: ; 0x0231EA40
|
||||
#ifdef JAPAN
|
||||
#define OV29_0231EA40_OFFSET -0xA4
|
||||
#else
|
||||
#define OV29_0231EA40_OFFSET 0
|
||||
#endif
|
||||
stmdb sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, lr}
|
||||
mov sl, r0
|
||||
bl IsFullFloorFixedRoom
|
||||
cmp r0, #0
|
||||
bne _0231EA80
|
||||
ldr r0, _0231EDC8 ; =DUNGEON_PTR
|
||||
ldr r0, [r0]
|
||||
add r1, r0, #0x4000
|
||||
ldrsh r0, [r1, #0xd4 + OV29_0231EA40_OFFSET]
|
||||
sub r2, r0, #0x1a
|
||||
mov r2, r2, lsl #0x10
|
||||
mov r2, r2, asr #0x10
|
||||
mov r2, r2, lsl #0x10
|
||||
mov r2, r2, lsr #0x10
|
||||
cmp r2, #1
|
||||
bhi _0231EA90
|
||||
_0231EA80:
|
||||
ldr r1, _0231EDCC ; =0x00000E01
|
||||
mov r0, sl
|
||||
bl LogMessageByIdWithPopupCheckUser
|
||||
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc}
|
||||
_0231EA90:
|
||||
ldrb r2, [r1, #0xc4 + OV29_0231EA40_OFFSET]
|
||||
cmp r2, #0
|
||||
beq _0231EAAC
|
||||
ldr r1, _0231EDD0 ; =0x00000DFF
|
||||
mov r0, sl
|
||||
bl LogMessageByIdWithPopupCheckUser
|
||||
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc}
|
||||
_0231EAAC:
|
||||
ldrb r1, [r1, #0xc7 + OV29_0231EA40_OFFSET]
|
||||
cmp r1, #0
|
||||
beq _0231EAC8
|
||||
mov r0, sl
|
||||
#ifdef JAPAN
|
||||
mov r1, #0xb40
|
||||
#else
|
||||
mov r1, #0xe00
|
||||
#endif
|
||||
bl LogMessageByIdWithPopupCheckUser
|
||||
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc}
|
||||
_0231EAC8:
|
||||
bl ov29_022E0378
|
||||
cmp r0, #0
|
||||
movne r7, #3
|
||||
moveq r7, #2
|
||||
mov r6, #0
|
||||
mov sb, #1
|
||||
_0231EAE0:
|
||||
ldr fp, _0231EDC8 ; =DUNGEON_PTR
|
||||
mov r5, #1
|
||||
mov r4, #0
|
||||
_0231EAEC:
|
||||
mov r0, sb
|
||||
mov r1, r5
|
||||
mov r8, #0
|
||||
bl GetTileSafe
|
||||
ldrh r1, [r0]
|
||||
bic r1, r1, #0x400
|
||||
strh r1, [r0]
|
||||
strb r4, [r0, #7]
|
||||
ldrh r1, [r0]
|
||||
tst r1, #0x10
|
||||
bne _0231EBCC
|
||||
tst r1, #0x100
|
||||
bne _0231EBCC
|
||||
ldrh r1, [r0, #2]
|
||||
orr r1, r1, #3
|
||||
strh r1, [r0, #2]
|
||||
ldrh r1, [r0]
|
||||
bic r1, r1, #8
|
||||
strh r1, [r0]
|
||||
ldrh r1, [r0]
|
||||
tst r1, #0x40
|
||||
ldrh r1, [r0]
|
||||
movne r6, #1
|
||||
and r2, r1, #3
|
||||
cmp r2, #2
|
||||
cmpne r2, #3
|
||||
beq _0231EBCC
|
||||
cmp sb, #1
|
||||
cmpne r5, #1
|
||||
cmpne sb, #0x36
|
||||
cmpne r5, #0x1e
|
||||
bne _0231EB84
|
||||
ldr r1, [r0, #0x10]
|
||||
cmp r1, #0
|
||||
ldreq r1, [fp]
|
||||
ldreqb r1, [r1, #0x78f]
|
||||
cmpeq r1, #0
|
||||
moveq r8, #1
|
||||
_0231EB84:
|
||||
cmp r8, #0
|
||||
beq _0231EBA8
|
||||
ldrh r1, [r0]
|
||||
bic r1, r1, #3
|
||||
strh r1, [r0]
|
||||
ldrh r1, [r0]
|
||||
orr r1, r1, r7
|
||||
strh r1, [r0]
|
||||
b _0231EBCC
|
||||
_0231EBA8:
|
||||
cmp r2, #1
|
||||
beq _0231EBCC
|
||||
ldrh r1, [r0]
|
||||
bic r1, r1, #3
|
||||
strh r1, [r0]
|
||||
ldrh r1, [r0]
|
||||
orr r1, r1, #1
|
||||
orr r1, r1, #0x400
|
||||
strh r1, [r0]
|
||||
_0231EBCC:
|
||||
add r5, r5, #1
|
||||
cmp r5, #0x1f
|
||||
blt _0231EAEC
|
||||
add sb, sb, #1
|
||||
cmp sb, #0x37
|
||||
blt _0231EAE0
|
||||
ldr r0, _0231EDC8 ; =DUNGEON_PTR
|
||||
mov r2, #1
|
||||
ldr r0, [r0]
|
||||
add r1, r0, #0xcc00
|
||||
ldrsh r0, [r1, #0xe4 + OV29_0231EA40_OFFSET]
|
||||
ldrsh r1, [r1, #0xe6 + OV29_0231EA40_OFFSET]
|
||||
bl StairsAlwaysReachable
|
||||
cmp r0, #0
|
||||
beq _0231EC64
|
||||
mov r5, #0
|
||||
mov r4, r5
|
||||
_0231EC10:
|
||||
mov r8, r4
|
||||
_0231EC14:
|
||||
mov r0, r5
|
||||
mov r1, r8
|
||||
bl GetTileSafe
|
||||
ldrh r1, [r0]
|
||||
tst r1, #0x100
|
||||
bne _0231EC4C
|
||||
tst r1, #0x400
|
||||
beq _0231EC4C
|
||||
tst r1, #0x8000
|
||||
bicne r1, r1, #3
|
||||
strneh r1, [r0]
|
||||
ldrneh r1, [r0]
|
||||
orrne r1, r1, r7
|
||||
strneh r1, [r0]
|
||||
_0231EC4C:
|
||||
add r8, r8, #1
|
||||
cmp r8, #0x20
|
||||
blt _0231EC14
|
||||
add r5, r5, #1
|
||||
cmp r5, #0x38
|
||||
blt _0231EC10
|
||||
_0231EC64:
|
||||
cmp r6, #0
|
||||
ldrne r0, _0231EDC8 ; =DUNGEON_PTR
|
||||
mov r5, #0
|
||||
ldrne r0, [r0]
|
||||
movne r1, #0
|
||||
addne r0, r0, #0x4000
|
||||
strneb r1, [r0, #0xc9 + OV29_0231EA40_OFFSET]
|
||||
mov r4, r5
|
||||
_0231EC84:
|
||||
mov r7, r4
|
||||
_0231EC88:
|
||||
cmp r6, #0
|
||||
beq _0231ECA8
|
||||
mov r0, r5
|
||||
mov r1, r7
|
||||
bl GetTileSafe
|
||||
ldrh r1, [r0]
|
||||
orr r1, r1, #0x40
|
||||
strh r1, [r0]
|
||||
_0231ECA8:
|
||||
mov r0, r5
|
||||
mov r1, r7
|
||||
bl DetermineTileWalkableNeighbors
|
||||
add r7, r7, #1
|
||||
cmp r7, #0x20
|
||||
blt _0231EC88
|
||||
add r5, r5, #1
|
||||
cmp r5, #0x38
|
||||
blt _0231EC84
|
||||
ldr r4, _0231EDC8 ; =DUNGEON_PTR
|
||||
mov r5, #0
|
||||
_0231ECD4:
|
||||
ldr r0, [r4]
|
||||
add r0, r0, r5, lsl #2
|
||||
add r0, r0, #0x12000
|
||||
ldr r6, [r0, #0xb78 + OV29_0231EA40_OFFSET]
|
||||
mov r0, r6
|
||||
bl EntityIsValid__0231EDD8
|
||||
cmp r0, #0
|
||||
beq _0231ED08
|
||||
ldrsh r0, [r6, #4]
|
||||
ldrsh r1, [r6, #6]
|
||||
bl GetTile
|
||||
ldrb r0, [r0, #7]
|
||||
strb r0, [r6, #0x25]
|
||||
_0231ED08:
|
||||
add r5, r5, #1
|
||||
cmp r5, #0x14
|
||||
blt _0231ECD4
|
||||
bl ov29_0233FB1C
|
||||
bl ov29_0233785C
|
||||
bl ov29_0233665C
|
||||
bl DetermineAllMonsterShadow
|
||||
bl UpdateMinimap
|
||||
bl UpdateTrapsVisibility
|
||||
ldr r1, _0231EDD4 ; =0x00000DFE
|
||||
mov r0, sl
|
||||
bl LogMessageByIdWithPopupCheckUser
|
||||
mov r0, #0x28
|
||||
mov r1, #0x2b
|
||||
bl ov29_022EA370
|
||||
mov r0, sl
|
||||
mov r1, #1
|
||||
bl ov29_02305814
|
||||
ldr r4, _0231EDC8 ; =DUNGEON_PTR
|
||||
mov r6, #0
|
||||
_0231ED58:
|
||||
ldr r0, [r4]
|
||||
add r0, r0, r6, lsl #2
|
||||
add r0, r0, #0x12000
|
||||
ldr r5, [r0, #0xb78 + OV29_0231EA40_OFFSET]
|
||||
mov r0, r5
|
||||
bl EntityIsValid__0231EDD8
|
||||
cmp r0, #0
|
||||
beq _0231ED98
|
||||
mov r0, r5
|
||||
bl ov29_022F9C74
|
||||
mov r0, r5
|
||||
bl EntityIsValid__0231EDD8
|
||||
cmp r0, #0
|
||||
beq _0231ED98
|
||||
mov r0, r5
|
||||
bl EnsureCanStandCurrentTile
|
||||
_0231ED98:
|
||||
add r6, r6, #1
|
||||
cmp r6, #0x14
|
||||
blt _0231ED58
|
||||
ldr r0, _0231EDC8 ; =DUNGEON_PTR
|
||||
mov r3, #1
|
||||
ldr r1, [r0]
|
||||
mov r0, #0x14
|
||||
add r2, r1, #0x4000
|
||||
mov r1, #0x2b
|
||||
strb r3, [r2, #0xc4 + OV29_0231EA40_OFFSET]
|
||||
bl ov29_022EA370
|
||||
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc}
|
||||
.align 2, 0
|
||||
_0231EDC8: .word DUNGEON_PTR
|
||||
#ifdef JAPAN
|
||||
_0231EDCC: .word 0x00000B41
|
||||
_0231EDD0: .word 0x00000B3F
|
||||
_0231EDD4: .word 0x00000B3E
|
||||
#else
|
||||
_0231EDCC: .word 0x00000E01
|
||||
_0231EDD0: .word 0x00000DFF
|
||||
_0231EDD4: .word 0x00000DFE
|
||||
#endif
|
||||
arm_func_end ov29_0231EA40
|
||||
8
include/dungeon_ai_item_weight.h
Normal file
8
include/dungeon_ai_item_weight.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef PMDSKY_DUNGEON_AI_ITEM_WEIGHT_H
|
||||
#define PMDSKY_DUNGEON_AI_ITEM_WEIGHT_H
|
||||
|
||||
#include "dungeon_mode.h"
|
||||
|
||||
u32 GetAiUseItemProbability(struct entity *item_consumer, struct item *item, u32 flags);
|
||||
|
||||
#endif //PMDSKY_DUNGEON_AI_ITEM_WEIGHT_H
|
||||
|
|
@ -9,6 +9,8 @@
|
|||
#include "util.h"
|
||||
|
||||
#define NUM_PICKED_IQ_SKILLS 3
|
||||
#define MAX_MON_MOVES 4
|
||||
#define MAX_SPEED_STAGE 4
|
||||
|
||||
// Used in various contexts, like with entity positions in the dungeon
|
||||
struct position {
|
||||
|
|
@ -114,6 +116,19 @@ struct sleep_class_status {
|
|||
u8 sleep_turns; // 0x1: Turns left for the status in statuses::sleep
|
||||
};
|
||||
|
||||
struct burn_class_status
|
||||
{
|
||||
enum status_burn_id burn; // 0x0: STATUS_BURN if 1
|
||||
u8 burn_turns; // 0x1: Turns left for the status in statuses::burn
|
||||
// 0x2: Turns left until residual damage for the status in statuses::burn, if applicable
|
||||
u8 burn_damage_countdown;
|
||||
// 0x3: The number of times the statuses::burn_damage_countdown has reached 0. Only used
|
||||
// when badly poisoned. Determines how much damage the badly poisoned status condition
|
||||
// will deal. There is no noticable difference because the table this value is looked up
|
||||
// on is filled with 0x6
|
||||
u8 badly_poisoned_damage_count;
|
||||
};
|
||||
|
||||
struct frozen_class_status {
|
||||
// 0x0: If non-zero, the corresponding status in status_frozen_id is active.
|
||||
enum status_frozen_id freeze;
|
||||
|
|
@ -139,6 +154,13 @@ struct bide_class_status {
|
|||
u8 bide_move_slot; // 0x2: Slot in the user's move list
|
||||
};
|
||||
|
||||
struct reflect_class_status {
|
||||
u8 reflect; // 0x0: STATUS_REFLECT if 1
|
||||
u8 reflect_turns; // 0x1: Turns left for the status in statuses::reflect
|
||||
// 0x2: Turns left until residual healing for the status in statuses::reflect, if applicable
|
||||
u8 reflect_damage_countdown;
|
||||
};
|
||||
|
||||
struct curse_class_status {
|
||||
// 0x0: If non-zero, the corresponding status in status_curse_id is active.
|
||||
enum status_curse_id curse;
|
||||
|
|
@ -171,13 +193,19 @@ struct iq_skill_flags
|
|||
u32 flags[NUM_PICKED_IQ_SKILLS]; /* 0x0 */
|
||||
};
|
||||
|
||||
struct moves
|
||||
{
|
||||
struct move moves[MAX_MON_MOVES]; // 0x0
|
||||
u8 struggle_move_flags; // 0x18
|
||||
};
|
||||
|
||||
// Monster info
|
||||
struct monster {
|
||||
// 0x0: flags: 2-byte bitfield
|
||||
u16 flags;
|
||||
|
||||
enum monster_id id; // 0x2:
|
||||
enum monster_id apparent_id : 16; // 0x4: What's outwardly displayed if Transformed
|
||||
s16 id; // 0x2:
|
||||
s16 apparent_id; // 0x4: What's outwardly displayed if Transformed
|
||||
bool8 is_not_team_member; // 0x6: true for enemies and allied NPCs that aren't on the team
|
||||
bool8 is_team_leader; // 0x7
|
||||
// 0x8: An ally is an NPC that isn't a normal team member, e.g. for story boss battles
|
||||
|
|
@ -261,22 +289,11 @@ struct monster {
|
|||
u32 bide_damage_tally;
|
||||
enum monster_behavior monster_behavior : 8; // 0xBC
|
||||
struct sleep_class_status sleep_class_status; // 0xBD
|
||||
u8 burn; // 0xBF: STATUS_BURN if 1
|
||||
u8 burn_turns; // 0xC0: Turns left for the status in statuses::burn
|
||||
// 0xC1: Turns left until residual damage for the status in statuses::burn, if applicable
|
||||
u8 burn_damage_countdown;
|
||||
// 0xC2: The number of times the statuses::burn_damage_countdown has reached 0. Only used
|
||||
// when badly poisoned. Determines how much damage the badly poisoned status condition
|
||||
// will deal. There is no noticable difference because the table this value is looked up
|
||||
// on is filled with 0x6
|
||||
u8 badly_poisoned_damage_count;
|
||||
struct burn_class_status burn_class_status; // 0xBF
|
||||
struct frozen_class_status frozen_class_status; // 0xC4
|
||||
struct cringe_class_status cringe_class_status; // 0xD0
|
||||
struct bide_class_status bide_class_status; // 0xD2
|
||||
u8 reflect; // 0xD5: STATUS_REFLECT if 1
|
||||
u8 reflect_turns; // 0xD6: Turns left for the status in statuses::reflect
|
||||
// 0xD7: Turns left until residual healing for the status in statuses::reflect, if applicable
|
||||
u8 reflect_damage_countdown;
|
||||
struct reflect_class_status reflect_class_status; // 0xD5
|
||||
struct curse_class_status curse_class_status; // 0xD8
|
||||
u8 leech_seed; // 0xE0: STATUS_LEECH_SEED if 1
|
||||
u8 field_0xe1;
|
||||
|
|
@ -371,9 +388,7 @@ struct monster {
|
|||
// 0x120: If zero, when the monster is standing in a room, the AI will make it head towards a
|
||||
// random exit. If nonzero, the monster will instead move in a random direction every turn.
|
||||
s32 random_movement;
|
||||
struct move moves[4]; // 0x124
|
||||
u8 move_flags; // 0x144: 1-byte bitfield
|
||||
u8 field_0x145;
|
||||
struct moves moves; // 0x124
|
||||
struct fixed_point belly; // 0x146
|
||||
struct fixed_point max_belly; // 0x14A:
|
||||
// 0x14E: If true and the monster is an ally, the AI will skip it. False for enemies.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// Monster move info
|
||||
struct move {
|
||||
// 0x0: flags: 1-byte bitfield
|
||||
u8 flags;
|
||||
u8 flags0;
|
||||
// bool8 f_exists : 1; // This move will show up in the move list
|
||||
// bool8 f_subsequent_in_link_chain : 1; // This move is in a link chain, but not the first move
|
||||
// bool8 f_enabled_for_ai : 1; // AI can use this move
|
||||
|
|
|
|||
|
|
@ -19,4 +19,6 @@ static inline bool8 ItemExists(u8 flags)
|
|||
return !!(flags & ITEM_FLAG_EXISTS);
|
||||
}
|
||||
|
||||
#define ENTITY_POISONED(entity_info)((entity_info->burn_class_status.burn == STATUS_BURN_POISONED || entity_info->burn_class_status.burn == STATUS_BURN_BADLY_POISONED))
|
||||
|
||||
#endif // PMDSKY_DUNGEON_UTIL_STATIC_H
|
||||
|
|
@ -2313,6 +2313,7 @@ enum status_invisible_id {
|
|||
STATUS_INVISIBLE_INVISIBLE = 1,
|
||||
STATUS_INVISIBLE_TRANSFORMED = 2,
|
||||
STATUS_INVISIBLE_MOBILE = 3,
|
||||
STATUS_INVISIBLE_SLIP = 4,
|
||||
};
|
||||
|
||||
enum status_blinker_id {
|
||||
|
|
@ -2899,4 +2900,28 @@ enum movement_flag
|
|||
MOVEMENT_FLAG_SWAPPING_PLACES_PETRIFIED_ALLY = 1 << 15, // Set if the Pokémon is petrified and the leader cures them by swapping places.
|
||||
};
|
||||
|
||||
enum move_flag
|
||||
{
|
||||
MOVE_FLAG_EXISTS = 1 << 0,
|
||||
MOVE_FLAG_SUBSEQUENT_IN_LINK_CHAIN = 1 << 1, // This move is linked with the previous move in the Pokémon's moveset.
|
||||
MOVE_FLAG_ENABLED_FOR_AI = 1 << 2, // Enabled for the AI to use.
|
||||
MOVE_FLAG_SET = 1 << 3, // This move can be triggered by pressing L+A instead of having to go to the move menu.
|
||||
MOVE_FLAG_LAST_USED = 1 << 4, // The most recent move used by the Pokémon.
|
||||
MOVE_FLAG_DISABLED = 1 << 5, // Disabled by an effect like Taunt.
|
||||
MOVE_FLAG_INTERNAL_MARKER = 1 << 7 // Possibly some kind of flag used internally to mark a move and find it again
|
||||
};
|
||||
|
||||
// Mobility types for monsters
|
||||
enum mobility_type {
|
||||
MOBILITY_NORMAL = 0,
|
||||
// This is unused within the monster data in monster.md, but is probably used in dungeons
|
||||
// with a meaning that's dependent on what the secondary terrain type is
|
||||
// (either MOBILITY_LAVA or MOBILITY_WATER).
|
||||
MOBILITY_SECONDARY = 1,
|
||||
MOBILITY_HOVERING = 2,
|
||||
MOBILITY_INTANGIBLE = 3,
|
||||
MOBILITY_LAVA = 4,
|
||||
MOBILITY_WATER = 5,
|
||||
};
|
||||
|
||||
#endif //PMDSKY_ENUMS_H
|
||||
|
|
|
|||
|
|
@ -34,4 +34,10 @@ struct fixed_point {
|
|||
// Compares two numbers and return the minimum
|
||||
#define MIN(A, B) ((A > B) ? B : A)
|
||||
|
||||
// Same as MIN macro but as a static inline, since the macro doesn't match in some places.
|
||||
static inline s32 Min(s32 a, s32 b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
#endif //PMDSKY_UTIL_H
|
||||
|
|
|
|||
2
main.lsf
2
main.lsf
|
|
@ -370,6 +370,8 @@ Overlay OVY_29
|
|||
Object asm/overlay_29_0231B33C.o
|
||||
Object src/overlay_29_0231CBC8.o
|
||||
Object asm/overlay_29_0231CBEC.o
|
||||
Object src/dungeon_ai_item_weight.o
|
||||
Object asm/overlay_29_0231E8F0.o
|
||||
Object src/overlay_29_0231EDD8.o
|
||||
Object asm/overlay_29_0231EDFC.o
|
||||
Object src/overlay_29_0231F570.o
|
||||
|
|
|
|||
370
src/dungeon_ai_item_weight.c
Normal file
370
src/dungeon_ai_item_weight.c
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
#include "dungeon_ai_item_weight.h"
|
||||
#include "dungeon_pokemon_attributes_1.h"
|
||||
#include "dungeon_statuses.h"
|
||||
#include "dungeon_util_static.h"
|
||||
#include "main_02054BE0.h"
|
||||
#include "util.h"
|
||||
|
||||
extern s32 CeilFixedPoint(struct fixed_point val_fp);
|
||||
extern bool8 IsAdjacentToEnemy(struct entity *entity);
|
||||
extern u8 GetMaxPpWrapper(struct move *move);
|
||||
extern bool8 MonsterHasNegativeStatus(struct entity *monster, bool8 check_held_item);
|
||||
extern enum mobility_type GetMobilityType(s16 monster_id);
|
||||
|
||||
u32 GetAiUseItemProbability(struct entity *item_consumer, struct item *item, u32 flags)
|
||||
{
|
||||
u32 item_weight = 0;
|
||||
struct monster *pokemon_info = GetEntInfo(item_consumer);
|
||||
bool8 target_other = (flags & 1) != 0;
|
||||
bool8 target_ally = (flags & 2) != 0;
|
||||
switch (item->id)
|
||||
{
|
||||
case ITEM_STICK:
|
||||
case ITEM_IRON_THORN:
|
||||
case ITEM_SILVER_SPIKE:
|
||||
case ITEM_GOLD_FANG:
|
||||
case ITEM_CACNEA_SPIKE:
|
||||
case ITEM_CORSOLA_TWIG:
|
||||
case ITEM_GRAVELEROCK:
|
||||
case ITEM_GEO_PEBBLE:
|
||||
case ITEM_GOLD_THORN:
|
||||
case ITEM_RARE_FOSSIL:
|
||||
if (target_other)
|
||||
item_weight = 70;
|
||||
break;
|
||||
case ITEM_DIET_RIBBON:
|
||||
if (target_other && CeilFixedPoint(pokemon_info->belly) > 0)
|
||||
return 50;
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_WHIFF_SPECS:
|
||||
case ITEM_NO_AIM_SCOPE:
|
||||
if (target_other)
|
||||
return 50;
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_PATSY_BAND:
|
||||
item_weight = 40;
|
||||
break;
|
||||
case ITEM_ORAN_BERRY:
|
||||
case ITEM_SITRUS_BERRY:
|
||||
s32 pokemon_max_hp = pokemon_info->max_hp_stat + pokemon_info->max_hp_boost;
|
||||
if (pokemon_info->hp < Min(999, pokemon_max_hp) && pokemon_info->hp <= Min(999, pokemon_max_hp) / 4)
|
||||
{
|
||||
if (!target_other)
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 100;
|
||||
else
|
||||
item_weight = 50;
|
||||
else
|
||||
item_weight = 50;
|
||||
}
|
||||
break;
|
||||
case ITEM_MIX_ELIXIR:
|
||||
case ITEM_MAX_ELIXIR:
|
||||
bool8 can_use_elixir = TRUE;
|
||||
if (item->id == ITEM_MIX_ELIXIR && pokemon_info->apparent_id != MONSTER_LINOONE && pokemon_info->apparent_id != MONSTER_LINOONE_SECONDARY)
|
||||
can_use_elixir = FALSE;
|
||||
if (can_use_elixir)
|
||||
{
|
||||
item_weight = 0;
|
||||
for (s32 i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
bool8 move_exists;
|
||||
struct move *move = &pokemon_info->moves.moves[i];
|
||||
if (move->flags0 & MOVE_FLAG_EXISTS)
|
||||
move_exists = TRUE;
|
||||
else
|
||||
move_exists = FALSE;
|
||||
if (move_exists)
|
||||
{
|
||||
if (move->pp == 0)
|
||||
item_weight += 30;
|
||||
|
||||
if (move->pp != GetMaxPpWrapper(move))
|
||||
item_weight += 6;
|
||||
}
|
||||
}
|
||||
item_weight = Min(item_weight, 99);
|
||||
}
|
||||
break;
|
||||
case ITEM_HEAL_SEED:
|
||||
case ITEM_GABITE_SCALE:
|
||||
if (MonsterHasNegativeStatus(item_consumer, TRUE))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_PROTEIN:
|
||||
if (pokemon_info->offensive_stats[0] >= 250)
|
||||
item_weight = 0;
|
||||
else
|
||||
item_weight = 100;
|
||||
break;
|
||||
case ITEM_CALCIUM:
|
||||
if (pokemon_info->offensive_stats[1] >= 250)
|
||||
item_weight = 0;
|
||||
else
|
||||
item_weight = 100;
|
||||
break;
|
||||
case ITEM_IRON:
|
||||
if (pokemon_info->defensive_stats[0] >= 250)
|
||||
item_weight = 0;
|
||||
else
|
||||
item_weight = 100;
|
||||
break;
|
||||
case ITEM_ZINC:
|
||||
if (pokemon_info->defensive_stats[1] >= 250)
|
||||
item_weight = 0;
|
||||
else
|
||||
item_weight = 100;
|
||||
break;
|
||||
case ITEM_LIFE_SEED:
|
||||
if (target_other)
|
||||
item_weight = 0;
|
||||
else if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 10;
|
||||
else
|
||||
item_weight = 100;
|
||||
break;
|
||||
case ITEM_EYEDROP_SEED:
|
||||
if (CanSeeInvisibleMonsters(item_consumer))
|
||||
return 0;
|
||||
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 5;
|
||||
break;
|
||||
case ITEM_QUICK_SEED:
|
||||
if (GetEntInfo(item_consumer)->speed_stage > MAX_SPEED_STAGE - 1)
|
||||
return 0;
|
||||
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 5;
|
||||
break;
|
||||
case ITEM_X_EYE_SEED:
|
||||
if (pokemon_info->blinker_class_status.blinded == STATUS_BLINKER_CROSS_EYED)
|
||||
return 0;
|
||||
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 5;
|
||||
break;
|
||||
case ITEM_CHERI_BERRY:
|
||||
if (pokemon_info->burn_class_status.burn != STATUS_BURN_PARALYSIS)
|
||||
return 0;
|
||||
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 30;
|
||||
break;
|
||||
case ITEM_TOTTER_SEED:
|
||||
if (pokemon_info->cringe_class_status.cringe == STATUS_CRINGE_CONFUSED)
|
||||
return 0;
|
||||
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 15;
|
||||
break;
|
||||
case ITEM_PECHA_BERRY:
|
||||
if (!ENTITY_POISONED(pokemon_info))
|
||||
return 0;
|
||||
|
||||
else if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 100;
|
||||
else
|
||||
item_weight = 50;
|
||||
break;
|
||||
case ITEM_BLINKER_SEED:
|
||||
if (IsBlinded(item_consumer, TRUE))
|
||||
return 0;
|
||||
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 5;
|
||||
break;
|
||||
case ITEM_WARP_SEED:
|
||||
if (!target_ally)
|
||||
{
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 40;
|
||||
else
|
||||
item_weight = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 pokemon_max_hp = pokemon_info->max_hp_stat + pokemon_info->max_hp_boost;
|
||||
if (pokemon_info->hp < Min(999, pokemon_max_hp) && pokemon_info->hp < 20)
|
||||
{
|
||||
if (!target_other)
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 100;
|
||||
else
|
||||
item_weight = 50;
|
||||
else
|
||||
item_weight = 50;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ITEM_SLEEP_SEED:
|
||||
if (pokemon_info->sleep_class_status.sleep == STATUS_SLEEP_SLEEP)
|
||||
return 0;
|
||||
if (pokemon_info->sleep_class_status.sleep == STATUS_SLEEP_NAPPING)
|
||||
return 0;
|
||||
if (pokemon_info->sleep_class_status.sleep == STATUS_SLEEP_NIGHTMARE)
|
||||
return 0;
|
||||
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 5;
|
||||
break;
|
||||
case ITEM_CHESTO_BERRY:
|
||||
if (pokemon_info->sleep_class_status.sleep == STATUS_SLEEPLESS)
|
||||
return 0;
|
||||
item_weight = 5;
|
||||
break;
|
||||
case ITEM_JOY_SEED:
|
||||
if (pokemon_info->level < 99)
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_GINSENG:
|
||||
item_weight = 80;
|
||||
break;
|
||||
case ITEM_RAWST_BERRY:
|
||||
if (pokemon_info->burn_class_status.burn == STATUS_BURN_BURN)
|
||||
return 50;
|
||||
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_HUNGER_SEED:
|
||||
if (CeilFixedPoint(pokemon_info->belly) > 0)
|
||||
return 50;
|
||||
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_DOOM_SEED:
|
||||
if (pokemon_info->level > 1)
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_STUN_SEED:
|
||||
if (pokemon_info->frozen_class_status.freeze == STATUS_FROZEN_PETRIFIED)
|
||||
return 0;
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 5;
|
||||
break;
|
||||
case ITEM_BLAST_SEED:
|
||||
if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 30;
|
||||
break;
|
||||
case ITEM_DOUGH_SEED:
|
||||
if (pokemon_info->is_not_team_member)
|
||||
item_weight = 0;
|
||||
else
|
||||
item_weight = 100;
|
||||
break;
|
||||
case ITEM_SLIP_SEED:
|
||||
enum mobility_type mobility_type = GetMobilityType(pokemon_info->id);
|
||||
bool8 can_use_slip_seed = mobility_type == MOBILITY_NORMAL || mobility_type == MOBILITY_LAVA;
|
||||
if (!can_use_slip_seed || pokemon_info->invisible_class_status.status == STATUS_INVISIBLE_SLIP)
|
||||
item_weight = 0;
|
||||
else if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 10;
|
||||
else
|
||||
item_weight = 100;
|
||||
break;
|
||||
case ITEM_GONE_PEBBLE:
|
||||
if (pokemon_info->reflect_class_status.reflect == STATUS_REFLECT_ENDURING)
|
||||
item_weight = 0;
|
||||
else if (IsAdjacentToEnemy(item_consumer))
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_VILE_SEED:
|
||||
if (target_other)
|
||||
item_weight = 70;
|
||||
else
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_VIOLENT_SEED:
|
||||
if (pokemon_info->stat_modifiers.offensive_stages[1] >= 20)
|
||||
item_weight = 0;
|
||||
else
|
||||
item_weight = 80;
|
||||
break;
|
||||
case ITEM_VANISH_SEED:
|
||||
if (pokemon_info->invisible_class_status.status != STATUS_INVISIBLE_INVISIBLE)
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_GRAVELYROCK:
|
||||
// BUG: FemaleToMaleForm is called, but the return value isn't used.
|
||||
// This means the AI only uses Gravelyrocks on male Bonsly/Sudowoodo, ignoring female ones.
|
||||
FemaleToMaleForm(pokemon_info->apparent_id);
|
||||
if (pokemon_info->apparent_id == MONSTER_BONSLY || pokemon_info->apparent_id == MONSTER_SUDOWOODO)
|
||||
{
|
||||
if (target_other)
|
||||
item_weight = 70;
|
||||
else
|
||||
item_weight = 100;
|
||||
}
|
||||
break;
|
||||
case ITEM_APPLE:
|
||||
case ITEM_BIG_APPLE:
|
||||
case ITEM_HUGE_APPLE:
|
||||
if (CeilFixedPoint(pokemon_info->belly) < 10)
|
||||
return 100;
|
||||
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_GRIMY_FOOD:
|
||||
item_weight = 30;
|
||||
break;
|
||||
case ITEM_ROLLCALL_ORB:
|
||||
if (target_other)
|
||||
item_weight = 0;
|
||||
else
|
||||
item_weight = 20;
|
||||
break;
|
||||
case ITEM_Y_RAY_SPECS:
|
||||
case ITEM_GAGGLE_SPECS:
|
||||
case ITEM_VIA_SEED:
|
||||
case ITEM_OREN_BERRY:
|
||||
case ITEM_WANDER_GUMMI:
|
||||
if (target_other)
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 0;
|
||||
break;
|
||||
case ITEM_DROPEYE_SEED:
|
||||
if (pokemon_info->blinker_class_status.blinded != STATUS_BLINKER_DROPEYE)
|
||||
{
|
||||
if (target_other)
|
||||
item_weight = 80;
|
||||
else
|
||||
item_weight = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
item_weight = 0;
|
||||
break;
|
||||
}
|
||||
return item_weight;
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#include "dungeon_ai_items.h"
|
||||
#include "dg_random.h"
|
||||
#include "direction.h"
|
||||
#include "dungeon_ai_item_weight.h"
|
||||
#include "dungeon_ai_items_1.h"
|
||||
#include "dungeon_capabilities_1.h"
|
||||
#include "dungeon_map_access.h"
|
||||
|
|
@ -24,7 +25,6 @@ extern bool8 TestItemAiFlag(s16 item_id, s32 flag);
|
|||
extern void GetPossibleAiArcItemTargets(struct entity *user, struct item *item, struct position positions[], bool8 always_add_position);
|
||||
extern s32 GetDirectionTowardsPosition(struct position *origin, struct position *target);
|
||||
extern struct item *GetItemInfo(struct entity *item_entity);
|
||||
extern u32 GetAiUseItemProbability(struct entity *item_consumer, struct item *item, u32 flags);
|
||||
extern bool8 MonsterCanThrowItems(struct monster *monster);
|
||||
|
||||
bool8 EntityIsValid__0230E8F0(struct entity *entity)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "dungeon.h"
|
||||
#include "dungeon_ai_attack.h"
|
||||
#include "dungeon_ai_attack_1.h"
|
||||
#include "dungeon_ai_item_weight.h"
|
||||
#include "dungeon_ai_items.h"
|
||||
#include "dungeon_ai_targeting_1.h"
|
||||
#include "dungeon_util_static.h"
|
||||
|
|
@ -16,8 +17,6 @@
|
|||
extern s32 AI_THROWN_ITEM_ACTION_CHOICE_COUNT;
|
||||
extern struct dungeon *DUNGEON_PTR[];
|
||||
|
||||
extern u32 GetAiUseItemProbability(struct entity *item_consumer, struct item *item, u32 flags);
|
||||
|
||||
void GetPossibleAiThrownItemDirections(struct entity *entity, s32 ally_or_enemy, struct item *item, bool8 always_add)
|
||||
{
|
||||
AI_THROWN_ITEM_ACTION_CHOICE_COUNT = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user