Added nonmatching for ChooseAiMove

This commit is contained in:
AnonymousRandomPerson 2025-06-10 21:52:21 -04:00
parent 138eab6151
commit 4c9dabf8de
24 changed files with 617 additions and 358 deletions

View File

@ -1,4 +1,5 @@
#pragma once
.public _01FF8120
.public _02099724
.public _02099734
.public _02099744
@ -6,90 +7,19 @@
.public _02099784
.public _02099E44
.public _020A2CF8
.public _0229AFC0
.public _0229AFCC
.public _0229AFE4
.public _0229B004
.public _0229B0E0
.public _0229B0E8
.public _0229B0F0
.public _0229B0F8
.public _0229B110
.public _0229B114
.public _0229B21C
.public _0229B220
.public _0229B248
.public _0229F248
.public _022A3248
.public _022A3538
.public _022A353C
.public _022A3554
.public _022A35E8
.public _022A3614
.public _022A3620
.public _022A362C
.public _022A3644
.public _022A3658
.public _022A3670
.public _022A3698
.public _022A369C
.public _022A36C4
.public _022A37A0
.public _022A37A4
.public _022A37AC
.public _022A37AD
.public _022A37AE
.public _022A37AF
.public _022A37B0
.public _022A37B6
.public _022A37B7
.public _022A37B8
.public _022A37B9
.public _022A37BA
.public _022A37BC
.public _022A37BE
.public _022A37CC
.public _022A37D0
.public _022A37D4
.public _022A37D8
.public _022A37EC
.public _022A37ED
.public _022A37EE
.public _022A37EF
.public _022A37F0
.public _022A37F1
.public _022A37F2
.public _022A37F3
.public _022A37F4
.public _022A37F5
.public _022A37F6
.public _022A37F7
.public _022A37F8
.public _022A37F9
.public _022A37FA
.public _022A37FB
.public _022A37FC
.public _022A37FD
.public _022A37FE
.public _022A37FF
.public _022A3800
.public _022A3801
.public _022A3802
.public _022A3803
.public _022A3804
.public _022A3805
.public _022A3806
.public _022A88F0
.public _022A88FC
.public _022B966C
.public _022B966C
.public _022B99D0
.public AbilityIsActiveVeneer
.public abs
.public AI_CONFUSED_ATTACK_CHANCE
.public AI_REGULAR_ATTACK_WEIGHTS
.public AiConsiderMove
.public AreMovesEnabled
.public CanAiMonsterMoveInDirection
.public CanAiUseMove
.public CannotAttack
.public CanSeeTarget
.public CanTargetEntity
.public CanTargetPosition
@ -102,14 +32,12 @@
.public DungeonRandOutcome__022EAB20
.public EnableIrqFlag
.public EntityIsValid__0230827C
.public EntityIsValid__02319F8C
.public G3_MultMtx43
.public GeomSetTexImageParam
.public GeomSetVertexCoord16
.public GetAllBaseForms
.public GetChebyshevDistance
.public GetDirectionTowardsPosition
.public GetEntityMoveTargetAndRange
.public GetItemInfo
.public GetMoveAiWeight
.public GetMoveTypeForMonster
@ -124,28 +52,20 @@
.public IqSkillIsEnabled
.public IsBagFull
.public IsChargingTwoTurnMove
.public IsMonster__0231A9D4
.public IsMonsterCornered
.public IsTacticSet
.public MemcpyFast
.public MemsetFast
.public MONSTER_DATA_TABLE_PTR
.public OS_IRQTable
.public ov10_022C4580
.public ov10_022C4900
.public ov29_022E935C
.public ov29_022EBC74
.public ov29_022FBDF0
.public ov29_022FBE04
.public ov29_022FF908
.public ov29_02300DCC
.public ov29_02301498
.public ov29_02301594
.public ov29_02302200
.public ov29_023082C4
.public ov29_0231985C
.public ov29_0231A460
.public ov29_0231B008
.public ov29_02338350
.public ov29_02348D00
.public ov29_0235177C
@ -154,6 +74,8 @@
.public Rgb8ToRgb5
.public SetActionPassTurnOrWalk
.public SetActionRegularAttack
.public SetActionStruggle
.public SetActionUseMoveAi
.public SetActionUseMoveAi
.public SetIrqFlag
.public SetMonsterActionFields
@ -169,12 +91,11 @@
.public sub_0207A300
.public sub_0207A324
.public sub_02080EF0
.public sub_02080EF0
.public sub_02080F30
.public sub_02080F30
.public TOUCHSCREEN_STATUS
.public TargetRegularAttack
.public TRIG_TABLE
.public TryAddTargetToAiTargetList
.public UpdateAiTargetPos
.public UpdateAiTargetPos
.public UpdateAiTargetPos
.public UpdateWindow
.public WINDOW_LIST

View File

@ -0,0 +1,14 @@
#pragma once
.public AbilityIsActiveVeneer
.public CanSeeTarget
.public DUNGEON_PTR
.public EntityIsValid__02319F8C
.public GetEntityMoveTargetAndRange
.public GetMoveTypeForMonster
.public GetTreatmentBetweenMonsters
.public InitMove
.public IsMonster__0231A9D4
.public TryAddTargetToAiTargetList
.public _01FFB654
.public ov29_0231985C
.public ov29_0231B008

View File

@ -46,7 +46,7 @@
.public ov29_022FBD08
.public ov29_022FEDBC
.public ov29_022FEFC8
.public ov29_02300DCC
.public CannotAttack
.public ov29_02304D20
.public ov29_023085DC
.public ov29_0230F140

View File

@ -10,5 +10,5 @@
.public TickStatusTurnCounter
.public ov29_022E56A0
.public ov29_022FAA04
.public ov29_02300DCC
.public CannotAttack
.public ov29_02322374

View File

@ -65,7 +65,7 @@
.public ov29_022F2FE4
.public ov29_022F42F8
.public ov29_022FB718
.public ov29_02300DCC
.public CannotAttack
.public ov29_02307BDC
.public ov29_02322374
.public ov29_02337E2C

View File

@ -49,7 +49,7 @@
.public ov29_022FAA04
.public ov29_022FBAB4
.public ov29_0230040C
.public ov29_02300DCC
.public CannotAttack
.public ov29_02304B14
.public ov29_02318D58
.public ov29_02321288

View File

@ -397,7 +397,7 @@
.public ov29_023007DC
.public ov29_02300D50
.public ov29_02300DC0
.public ov29_02300DCC
.public CannotAttack
.public ov29_02301C2C
.public ov29_02304A48
.public ov29_02304C3C

View File

@ -4133,9 +4133,13 @@ sub_01FFB62C: ; 0x01FFB62C
strh r2, [r3, #0x80]
bx lr
arm_func_end sub_01FFB62C
.global _01FFB654
_01FFB654:
.byte 0x05, 0x03, 0x00, 0x00
; https://decomp.me/scratch/zg7V6
#ifndef NONMATCHING
arm_func_start ChooseAiMove
ChooseAiMove: ; 0x01FFB658
#ifdef JAPAN
@ -4160,7 +4164,7 @@ ChooseAiMove: ; 0x01FFB658
beq _01FFBD0C
mov r0, sl
mov r1, #0
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
bne _01FFBD0C
mov r0, sl
@ -4185,7 +4189,7 @@ _01FFB6CC:
ldrb r0, [r7, #0xd0]
cmp r0, #2
bne _01FFB700
ldr r0, _01FFBD18 ; =ov10_022C4580
ldr r0, _01FFBD18 ; =AI_CONFUSED_ATTACK_CHANCE
ldrsh r0, [r0]
bl DungeonRandOutcome__022EAB20
cmp r0, #0
@ -4279,7 +4283,7 @@ _01FFB7F8:
beq _01FFBD0C
ldrb r1, [sp, #0x1d]
add r0, r7, #0x4a
bl ov29_022EBC74
bl SetActionStruggle
mov r0, sl
bl UpdateAiTargetPos
b _01FFBD0C
@ -4464,7 +4468,7 @@ _01FFBA7C:
movne r0, #2
strne r0, [sp, #0x40]
ldreq r0, [sp]
ldreq r1, _01FFBD1C ; =ov10_022C4900
ldreq r1, _01FFBD1C ; =AI_REGULAR_ATTACK_WEIGHTS
moveq r0, r0, lsl #1
ldreqsh r0, [r1, r0]
streq r0, [sp, #0x40]
@ -4533,7 +4537,7 @@ _01FFBB80:
add r1, sp, #0x10
mov r0, sl
mov r2, r6
bl ov29_0231A460
bl TargetRegularAttack
mov fp, r0
_01FFBBD8:
cmp r6, #0
@ -4548,7 +4552,7 @@ _01FFBBD8:
add r1, sp, #0x10
mov r0, sl
mov r2, #1
bl ov29_0231A460
bl TargetRegularAttack
mov fp, r0
_01FFBC10:
mov r8, #0
@ -4628,239 +4632,7 @@ _01FFBD0C:
ldmia sp!, {r4, r5, r6, r7, r8, sb, sl, fp, pc}
.align 2, 0
_01FFBD14: .word DUNGEON_PTR
_01FFBD18: .word ov10_022C4580
_01FFBD1C: .word ov10_022C4900
_01FFBD18: .word AI_CONFUSED_ATTACK_CHANCE
_01FFBD1C: .word AI_REGULAR_ATTACK_WEIGHTS
arm_func_end ChooseAiMove
arm_func_start sub_01FFBD20
sub_01FFBD20: ; 0x01FFBD20
stmdb sp!, {r3, r4, r5, r6, r7, lr}
mov r6, r1
mov r7, r0
mov r0, r6
bl IsMonster__0231A9D4
cmp r0, #0
ldmeqia sp!, {r3, r4, r5, r6, r7, pc}
ldr r5, [r6, #0xb4]
ldrb r0, [r5, #6]
cmp r0, #0
beq _01FFBD5C
ldrb r0, [r5, #8]
cmp r0, #0
moveq r3, #1
beq _01FFBD60
_01FFBD5C:
mov r3, #0
_01FFBD60:
ldr r1, _01FFBDF0 ; =DUNGEON_PTR
mov r0, r6
ldr r2, [r1]
mov r1, #0x32
#ifdef JAPAN
add r2, r2, #0x1840
add r2, r2, #0x18000
#else
add r2, r2, #0xe4
add r2, r2, #0x19800
#endif
add r4, r2, r3, lsl #4
bl AbilityIsActiveVeneer
cmp r0, #0
beq _01FFBDB0
ldr r0, [r4]
cmp r0, #0
bne _01FFBDB0
mov r0, r7
mov r1, r6
bl sub_01FFBF78
cmp r0, #0
strne r6, [r4]
ldrne r0, [r5, #0xb0]
strne r0, [r4, #4]
_01FFBDB0:
mov r0, r6
mov r1, #0x7a
bl AbilityIsActiveVeneer
cmp r0, #0
ldmeqia sp!, {r3, r4, r5, r6, r7, pc}
ldr r0, [r4, #8]
cmp r0, #0
ldmneia sp!, {r3, r4, r5, r6, r7, pc}
mov r0, r7
mov r1, r6
bl sub_01FFBF78
cmp r0, #0
strne r6, [r4, #8]
ldrne r0, [r5, #0xb0]
strne r0, [r4, #0xc]
ldmia sp!, {r3, r4, r5, r6, r7, pc}
.align 2, 0
_01FFBDF0: .word DUNGEON_PTR
arm_func_end sub_01FFBD20
arm_func_start sub_01FFBDF4
sub_01FFBDF4: ; 0x01FFBDF4
stmdb sp!, {r3, r4, r5, r6, r7, lr}
mov r7, r0
bl ov29_0231B008
mov r0, r7
bl EntityIsValid__02319F8C
cmp r0, #0
ldmeqia sp!, {r3, r4, r5, r6, r7, pc}
ldr r4, _01FFBE58 ; =DUNGEON_PTR
mov r5, #0
_01FFBE18:
ldr r0, [r4]
add r0, r0, r5, lsl #2
add r0, r0, #0x12000
#ifdef JAPAN
ldr r6, [r0, #0xad4]
#else
ldr r6, [r0, #0xb78]
#endif
mov r0, r6
bl EntityIsValid__02319F8C
cmp r0, #0
cmpne r7, r6
beq _01FFBE48
mov r0, r7
mov r1, r6
bl sub_01FFBD20
_01FFBE48:
add r5, r5, #1
cmp r5, #0x14
blt _01FFBE18
ldmia sp!, {r3, r4, r5, r6, r7, pc}
.align 2, 0
_01FFBE58: .word DUNGEON_PTR
arm_func_end sub_01FFBDF4
arm_func_start LightningRodStormDrainCheck
LightningRodStormDrainCheck: ; 0x01FFBE5C
stmdb sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, lr}
mov sl, r0
mov sb, r1
mov r8, r2
mov r7, r3
mov r5, #0
ldr r4, _01FFBF70 ; =_01FFB654
ldr fp, _01FFBF74 ; =DUNGEON_PTR
b _01FFBF60
_01FFBE80:
ldr r1, [fp]
mov r0, sl
#ifdef JAPAN
add r1, r1, #0x1840
add r1, r1, #0x18000
#else
add r1, r1, #0xe4
add r1, r1, #0x19800
#endif
add r6, r1, r5, lsl #4
mov r1, #0x53
bl AbilityIsActiveVeneer
cmp r0, #0
bne _01FFBF5C
mov r0, sl
mov r1, r8
bl GetMoveTypeForMonster
ldrb r1, [r4, r7]
cmp r1, r0
bne _01FFBF5C
mov r0, sl
mov r1, r8
mov r2, #0
bl GetEntityMoveTargetAndRange
and r0, r0, #0xf0
cmp r0, #0x70
beq _01FFBF5C
ldr r0, [r6, r7, lsl #3]
bl IsMonster__0231A9D4
cmp r0, #0
beq _01FFBF4C
ldr r0, [r6, r7, lsl #3]
add r1, r6, r7, lsl #3
ldr r2, [r1, #4]
ldr r1, [r0, #0xb4]
ldr r1, [r1, #0xb0]
cmp r2, r1
bne _01FFBF4C
mov r1, sl
mov r2, #1
mov r3, #0
bl GetTreatmentBetweenMonsters
cmp r0, #1
bne _01FFBF4C
ldr r0, [sb, #0xb4]
ldr r2, [r6, r7, lsl #3]
#ifdef JAPAN
ldrb r0, [r0, #0x10a]
ldr r1, [r2, #0xb4]
cmp r0, #0
ldreqb r0, [r1, #0x10a]
#else
ldrb r0, [r0, #0x10b]
ldr r1, [r2, #0xb4]
cmp r0, #0
ldreqb r0, [r1, #0x10b]
#endif
cmpeq r0, #0
beq _01FFBF44
cmp sb, r2
bne _01FFBF4C
_01FFBF44:
mov r0, #1
b _01FFBF50
_01FFBF4C:
mov r0, #0
_01FFBF50:
cmp r0, #0
ldrne r0, [r6, r7, lsl #3]
ldmneia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc}
_01FFBF5C:
add r5, r5, #1
_01FFBF60:
cmp r5, #2
blt _01FFBE80
mov r0, #0
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc}
.align 2, 0
_01FFBF70: .word _01FFB654
_01FFBF74: .word DUNGEON_PTR
arm_func_end LightningRodStormDrainCheck
arm_func_start sub_01FFBF78
sub_01FFBF78: ; 0x01FFBF78
stmdb sp!, {r4, r5, r6, lr}
sub sp, sp, #0x10
mov r6, r0
mov r5, r1
mov r4, #0
bl ov29_0231985C
mov r0, r6
mov r1, r5
bl CanSeeTarget
cmp r0, #0
beq _01FFBFD8
add r0, sp, #8
mov r1, r4
bl InitMove
add r0, sp, #8
str r0, [sp]
mov ip, #1
mov r2, r6
mov r3, r5
mov r0, r4
mov r1, #0x30
str ip, [sp, #4]
bl TryAddTargetToAiTargetList
mov r4, r0
_01FFBFD8:
cmp r4, #0
movne r0, #1
moveq r0, #0
and r0, r0, #0xff
add sp, sp, #0x10
ldmia sp!, {r4, r5, r6, pc}
arm_func_end sub_01FFBF78
; 0x01FFBFF0

237
asm/itcm_01FFBD20.s Normal file
View File

@ -0,0 +1,237 @@
.include "asm/macros.inc"
.include "itcm_01FFBD20.inc"
.section .itcm,4,1,4
arm_func_start sub_01FFBD20
sub_01FFBD20: ; 0x01FFBD20
stmdb sp!, {r3, r4, r5, r6, r7, lr}
mov r6, r1
mov r7, r0
mov r0, r6
bl IsMonster__0231A9D4
cmp r0, #0
ldmeqia sp!, {r3, r4, r5, r6, r7, pc}
ldr r5, [r6, #0xb4]
ldrb r0, [r5, #6]
cmp r0, #0
beq _01FFBD5C
ldrb r0, [r5, #8]
cmp r0, #0
moveq r3, #1
beq _01FFBD60
_01FFBD5C:
mov r3, #0
_01FFBD60:
ldr r1, _01FFBDF0 ; =DUNGEON_PTR
mov r0, r6
ldr r2, [r1]
mov r1, #0x32
#ifdef JAPAN
add r2, r2, #0x1840
add r2, r2, #0x18000
#else
add r2, r2, #0xe4
add r2, r2, #0x19800
#endif
add r4, r2, r3, lsl #4
bl AbilityIsActiveVeneer
cmp r0, #0
beq _01FFBDB0
ldr r0, [r4]
cmp r0, #0
bne _01FFBDB0
mov r0, r7
mov r1, r6
bl sub_01FFBF78
cmp r0, #0
strne r6, [r4]
ldrne r0, [r5, #0xb0]
strne r0, [r4, #4]
_01FFBDB0:
mov r0, r6
mov r1, #0x7a
bl AbilityIsActiveVeneer
cmp r0, #0
ldmeqia sp!, {r3, r4, r5, r6, r7, pc}
ldr r0, [r4, #8]
cmp r0, #0
ldmneia sp!, {r3, r4, r5, r6, r7, pc}
mov r0, r7
mov r1, r6
bl sub_01FFBF78
cmp r0, #0
strne r6, [r4, #8]
ldrne r0, [r5, #0xb0]
strne r0, [r4, #0xc]
ldmia sp!, {r3, r4, r5, r6, r7, pc}
.align 2, 0
_01FFBDF0: .word DUNGEON_PTR
arm_func_end sub_01FFBD20
arm_func_start sub_01FFBDF4
sub_01FFBDF4: ; 0x01FFBDF4
stmdb sp!, {r3, r4, r5, r6, r7, lr}
mov r7, r0
bl ov29_0231B008
mov r0, r7
bl EntityIsValid__02319F8C
cmp r0, #0
ldmeqia sp!, {r3, r4, r5, r6, r7, pc}
ldr r4, _01FFBE58 ; =DUNGEON_PTR
mov r5, #0
_01FFBE18:
ldr r0, [r4]
add r0, r0, r5, lsl #2
add r0, r0, #0x12000
#ifdef JAPAN
ldr r6, [r0, #0xad4]
#else
ldr r6, [r0, #0xb78]
#endif
mov r0, r6
bl EntityIsValid__02319F8C
cmp r0, #0
cmpne r7, r6
beq _01FFBE48
mov r0, r7
mov r1, r6
bl sub_01FFBD20
_01FFBE48:
add r5, r5, #1
cmp r5, #0x14
blt _01FFBE18
ldmia sp!, {r3, r4, r5, r6, r7, pc}
.align 2, 0
_01FFBE58: .word DUNGEON_PTR
arm_func_end sub_01FFBDF4
arm_func_start LightningRodStormDrainCheck
LightningRodStormDrainCheck: ; 0x01FFBE5C
stmdb sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, lr}
mov sl, r0
mov sb, r1
mov r8, r2
mov r7, r3
mov r5, #0
ldr r4, _01FFBF70 ; =_01FFB654
ldr fp, _01FFBF74 ; =DUNGEON_PTR
b _01FFBF60
_01FFBE80:
ldr r1, [fp]
mov r0, sl
#ifdef JAPAN
add r1, r1, #0x1840
add r1, r1, #0x18000
#else
add r1, r1, #0xe4
add r1, r1, #0x19800
#endif
add r6, r1, r5, lsl #4
mov r1, #0x53
bl AbilityIsActiveVeneer
cmp r0, #0
bne _01FFBF5C
mov r0, sl
mov r1, r8
bl GetMoveTypeForMonster
ldrb r1, [r4, r7]
cmp r1, r0
bne _01FFBF5C
mov r0, sl
mov r1, r8
mov r2, #0
bl GetEntityMoveTargetAndRange
and r0, r0, #0xf0
cmp r0, #0x70
beq _01FFBF5C
ldr r0, [r6, r7, lsl #3]
bl IsMonster__0231A9D4
cmp r0, #0
beq _01FFBF4C
ldr r0, [r6, r7, lsl #3]
add r1, r6, r7, lsl #3
ldr r2, [r1, #4]
ldr r1, [r0, #0xb4]
ldr r1, [r1, #0xb0]
cmp r2, r1
bne _01FFBF4C
mov r1, sl
mov r2, #1
mov r3, #0
bl GetTreatmentBetweenMonsters
cmp r0, #1
bne _01FFBF4C
ldr r0, [sb, #0xb4]
ldr r2, [r6, r7, lsl #3]
#ifdef JAPAN
ldrb r0, [r0, #0x10a]
ldr r1, [r2, #0xb4]
cmp r0, #0
ldreqb r0, [r1, #0x10a]
#else
ldrb r0, [r0, #0x10b]
ldr r1, [r2, #0xb4]
cmp r0, #0
ldreqb r0, [r1, #0x10b]
#endif
cmpeq r0, #0
beq _01FFBF44
cmp sb, r2
bne _01FFBF4C
_01FFBF44:
mov r0, #1
b _01FFBF50
_01FFBF4C:
mov r0, #0
_01FFBF50:
cmp r0, #0
ldrne r0, [r6, r7, lsl #3]
ldmneia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc}
_01FFBF5C:
add r5, r5, #1
_01FFBF60:
cmp r5, #2
blt _01FFBE80
mov r0, #0
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc}
.align 2, 0
_01FFBF70: .word _01FFB654
_01FFBF74: .word DUNGEON_PTR
arm_func_end LightningRodStormDrainCheck
arm_func_start sub_01FFBF78
sub_01FFBF78: ; 0x01FFBF78
stmdb sp!, {r4, r5, r6, lr}
sub sp, sp, #0x10
mov r6, r0
mov r5, r1
mov r4, #0
bl ov29_0231985C
mov r0, r6
mov r1, r5
bl CanSeeTarget
cmp r0, #0
beq _01FFBFD8
add r0, sp, #8
mov r1, r4
bl InitMove
add r0, sp, #8
str r0, [sp]
mov ip, #1
mov r2, r6
mov r3, r5
mov r0, r4
mov r1, #0x30
str ip, [sp, #4]
bl TryAddTargetToAiTargetList
mov r4, r0
_01FFBFD8:
cmp r4, #0
movne r0, #1
moveq r0, #0
and r0, r0, #0xff
add sp, sp, #0x10
ldmia sp!, {r4, r5, r6, pc}
arm_func_end sub_01FFBF78
; 0x01FFBFF0

View File

@ -2473,8 +2473,8 @@ RAIN_ABILITY_BONUS_REGEN:
.global ov10_022C457C
ov10_022C457C:
.byte 0x03, 0x00, 0x00, 0x00
.global ov10_022C4580
ov10_022C4580:
.global AI_CONFUSED_ATTACK_CHANCE
AI_CONFUSED_ATTACK_CHANCE:
.byte 0x46, 0x00, 0x00, 0x00
.global ov10_022C4584
ov10_022C4584:
@ -3121,8 +3121,8 @@ ov10_022C48EC:
.global ov10_022C48F4
ov10_022C48F4:
.byte 0x7C, 0x05, 0x79, 0x05, 0x7A, 0x05, 0x7B, 0x05, 0x00, 0x00, 0x00, 0x00
.global ov10_022C4900
ov10_022C4900:
.global AI_REGULAR_ATTACK_WEIGHTS
AI_REGULAR_ATTACK_WEIGHTS:
.byte 0x64, 0x00, 0x14, 0x00
.byte 0x1E, 0x00, 0x28, 0x00, 0x32, 0x00, 0x00, 0x00
.global ov10_022C490C

View File

@ -707,8 +707,8 @@ SetActionRegularAttack: ; 0x022EBC50
ldmia sp!, {r3, r4, r5, pc}
arm_func_end SetActionRegularAttack
arm_func_start ov29_022EBC74
ov29_022EBC74: ; 0x022EBC74
arm_func_start SetActionStruggle
SetActionStruggle: ; 0x022EBC74
stmdb sp!, {r3, r4, r5, lr}
mov r4, r1
mov r1, #0x17
@ -718,7 +718,7 @@ ov29_022EBC74: ; 0x022EBC74
andne r0, r4, #7
strneb r0, [r5, #2]
ldmia sp!, {r3, r4, r5, pc}
arm_func_end ov29_022EBC74
arm_func_end SetActionStruggle
arm_func_start SetActionUseMovePlayer
SetActionUseMovePlayer: ; 0x022EBC98

View File

@ -49,7 +49,7 @@ _022FEF54:
_022FEF64:
mov r0, r6
mov r1, #0
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
beq _022FEF94
mov r0, r6
@ -684,7 +684,7 @@ _022FE528:
_022FE538:
mov r0, sb
mov r1, #0
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
beq _022FE568
mov r0, sb

View File

@ -33,7 +33,7 @@ _022FEDC8:
beq _022FEFA4
mov r0, r7
mov r1, #1
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
movne r0, #0xff
strneb r0, [r8, #0x177 + OV29_022FEDBC_OFFSET]
@ -193,7 +193,7 @@ _022FEFD4:
beq _022FF14C
mov r0, r8
mov r1, #1
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
movne r0, #0xff
strneb r0, [sl, #0x178 + OV29_022FEFC8_OFFSET]

View File

@ -67,8 +67,8 @@ ov29_02300DC0: ; 0x02300DC0
_02300DC8: .word ov29_02300D50
arm_func_end ov29_02300DC0
arm_func_start ov29_02300DCC
ov29_02300DCC: ; 0x02300DCC
arm_func_start CannotAttack
CannotAttack: ; 0x02300DCC
stmdb sp!, {r3, lr}
cmp r1, #0
ldr r2, [r0, #0xb4]
@ -113,4 +113,4 @@ _02300DF4:
moveq r0, #0
and r0, r0, #0xff
ldmia sp!, {r3, pc}
arm_func_end ov29_02300DCC
arm_func_end CannotAttack

View File

@ -1469,7 +1469,7 @@ _02310E9C:
bne _02310F70
mov r0, r5
mov r1, #0
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
bne _02310F70
mov r0, r5

View File

@ -342,8 +342,8 @@ _0231A454:
_0231A45C: .word DUNGEON_PTR
arm_func_end ov29_0231A364
arm_func_start ov29_0231A460
ov29_0231A460: ; 0x0231A460
arm_func_start TargetRegularAttack
TargetRegularAttack: ; 0x0231A460
stmdb sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, lr}
sub sp, sp, #0x48
mov sl, r0
@ -504,4 +504,4 @@ _0231A688:
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc}
.align 2, 0
_0231A690: .word DIRECTIONS_XY
arm_func_end ov29_0231A460
arm_func_end TargetRegularAttack

View File

@ -129,13 +129,13 @@ _023215D8:
bne _02321620
mov r0, sl
mov r1, #1
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
bne _02321888
b _02321620
_02321610:
mov r1, #0
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
bne _02321888
_02321620:
@ -1479,14 +1479,14 @@ _02322824:
bne _02322860
mov r0, r6
mov r1, #1
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
bne _02322C98
b _02322860
_0232284C:
mov r0, r6
mov r1, #0
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
bne _02322C98
_02322860:

View File

@ -191,7 +191,7 @@ _0232EAD0:
_0232EAEC:
mov r0, r4
mov r1, #0
bl ov29_02300DCC
bl CannotAttack
cmp r0, #0
bne _0232ED9C
mov r0, sb

15
include/dungeon_ai_itcm.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef PMDSKY_DUNGEON_AI_ITCM_H
#define PMDSKY_DUNGEON_AI_ITCM_H
#include "dungeon_mode.h"
struct ai_possible_move
{
bool8 can_be_used;
u8 direction;
s32 weight;
};
void ChooseAiMove(struct entity *monster);
#endif //PMDSKY_DUNGEON_AI_ITCM_H

View File

@ -19,6 +19,11 @@ static inline bool8 ItemExists(u8 flags)
return !!(flags & ITEM_FLAG_EXISTS);
}
static inline bool8 MoveExists(struct move *move)
{
return move->flags0 & MOVE_FLAG_EXISTS ? TRUE : FALSE;
}
#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

View File

@ -80,6 +80,8 @@ Autoload ITCM
{
Address 0x01FF8000
Object asm/itcm.o (.itcm)
Object src/dungeon_ai_itcm.o (.itcm)
Object asm/itcm_01FFBD20.o (.itcm)
}
Autoload DTCM

View File

@ -2,6 +2,7 @@
#include "dg_random.h"
#include "direction.h"
#include "dungeon_action.h"
#include "dungeon_ai_itcm.h"
#include "dungeon_ai_items.h"
#include "dungeon_capabilities_1.h"
#include "dungeon_pokemon_attributes.h"
@ -26,7 +27,6 @@ extern struct dungeon *DUNGEON_PTR[];
extern void EndFrozenClassStatus(struct entity *user, struct entity *target, bool8 log);
extern void SubstitutePlaceholderStringTags(u8 *string_id, struct entity *entity, u32 param_3);
extern void LogMessageByIdWithPopupCheckUser(struct entity *user, u32 message_id);
extern void ChooseAiMove(struct entity *monster);
extern bool8 GetCanMoveFlag(s16 monster_id);
extern void AiMovement(struct entity *monster, bool8 show_run_away_effect);

293
src/dungeon_ai_itcm.c Normal file
View File

@ -0,0 +1,293 @@
#include "dungeon_ai_itcm.h"
#include "dg_random.h"
#include "direction.h"
#include "dungeon_action.h"
#include "dungeon_pokemon_attributes.h"
#include "dungeon_pokemon_attributes_1.h"
#include "dungeon_util_static.h"
#define REGULAR_ATTACK_INDEX 4
extern const s16 AI_CONFUSED_ATTACK_CHANCE;
extern const s16 AI_REGULAR_ATTACK_WEIGHTS[5];
extern struct dungeon *DUNGEON_PTR[];
extern bool8 AreMovesEnabled(enum fixed_room_id fixed_room_id);
extern bool8 CannotAttack(struct entity *pokemon, bool8 skip_sleep);
extern u32 ShouldMonsterRunAwayVariation(struct entity *monster, u32 param_2);
extern bool8 IsMonsterCornered(struct entity *monster);
extern bool8 IsChargingTwoTurnMove(struct entity *user, struct move *move);
extern void SetActionUseMoveAi(struct action_data *monster_action, s16 move_index, u8 direction);
extern void UpdateAiTargetPos(struct entity *monster);
extern void InitMove(struct move *move, enum move_id move_id);
extern u32 AiConsiderMove(struct ai_possible_move *ai_possible_move, struct entity *monster, struct move *move);
extern bool8 ov29_02338350(struct entity *monster);
extern bool8 TargetRegularAttack(struct entity *pokemon, u32 *target_dir, bool8 check_petrified);
extern void SetActionRegularAttack(struct action_data *monster_action, u8 direction);
extern void SetActionStruggle(struct action_data *monster_action, u8 direction);
extern bool8 CanAiUseMove(struct entity *monster, u32 move_index, bool8 extra_checks);
extern enum type_id GetMoveTypeForMonster(struct entity *entity, struct move *move);
extern u8 GetMoveAiWeight(struct move *move);
// https://decomp.me/scratch/zg7V6
#ifdef NONMATCHING
void ChooseAiMove(struct entity *monster)
{
struct monster *pokemon_info = GetEntInfo(monster);
if (!AreMovesEnabled(DUNGEON_PTR[0]->gen_info.fixed_room_id) ||
CannotAttack(monster, FALSE) ||
ShouldMonsterRunAwayVariation(monster, TRUE) ||
GetEntInfo(monster)->monster_behavior == BEHAVIOR_FLEEING_OUTLAW && IsMonsterCornered(monster) ||
IsTacticSet(monster, TACTIC_KEEP_YOUR_DISTANCE) ||
(pokemon_info->cringe_class_status.cringe == STATUS_CRINGE_CONFUSED && DungeonRandOutcome__022EAB20(AI_CONFUSED_ATTACK_CHANCE)))
return;
int i;
if (pokemon_info->bide_class_status.bide != STATUS_TWO_TURN_NONE)
{
for (i = 0; i < MAX_MON_MOVES; i++)
{
struct move *move = &pokemon_info->moves.moves[i];
if (MoveExists(move) &&
IsChargingTwoTurnMove(monster, move) &&
pokemon_info->bide_class_status.bide_move_slot == i)
{
s32 j;
for (j = i; j > 0; j--)
{
if (!(pokemon_info->moves.moves[j].flags0 & MOVE_FLAG_SUBSEQUENT_IN_LINK_CHAIN))
break;
}
SetActionUseMoveAi(&pokemon_info->action, j, pokemon_info->action.direction);
UpdateAiTargetPos(monster);
return;
}
}
}
struct move *moves = pokemon_info->moves.moves;
s32 total_pp = 0;
bool8 has_exclusive_move_user = FALSE;
s32 num_usable_moves = 0;
struct move *move;
for (i = 0; i < MAX_MON_MOVES; i++)
{
move = &moves[i];
if (!MoveExists(&moves[i]))
continue;
if (move->flags0 & MOVE_FLAG_ENABLED_FOR_AI)
num_usable_moves++;
total_pp += move->pp;
}
struct ai_possible_move ai_possible_move[MAX_MON_MOVES + 1];
if (total_pp == 0)
{
struct move struggle;
InitMove(&struggle, MOVE_STRUGGLE);
AiConsiderMove(&ai_possible_move[0], monster, &struggle);
if (ai_possible_move[0].can_be_used)
{
SetActionStruggle(&pokemon_info->action, ai_possible_move[0].direction);
UpdateAiTargetPos(monster);
}
return;
}
s32 regular_attack_target_dir;
bool8 has_weak_type_picker = IqSkillIsEnabled(monster, IQ_WEAK_TYPE_PICKER);
has_exclusive_move_user = IqSkillIsEnabled(monster, IQ_EXCLUSIVE_MOVE_USER) != FALSE;
s32 total_weight = 0;
bool8 will_not_unlink_move[MAX_MON_MOVES];
for (i = 0; i < MAX_MON_MOVES; i++)
{
will_not_unlink_move[i] = TRUE;
}
if (has_exclusive_move_user)
{
s32 min_pp = 99;
s32 linked_move_start_index = 0;
// Linked moves unlink if any move in the chain runs out of PP.
// The AI avoids this by not using linked moves if any move in the chain has 1 PP left.
// This requires a separate check from the 0-PP check used for unlinked moves.
for (i = 0; i < MAX_MON_MOVES; i++)
{
moves = pokemon_info->moves.moves;
move = &moves[i];
if (!MoveExists(&moves[i]))
break;
if (i != 0 && !(move->flags0 & MOVE_FLAG_SUBSEQUENT_IN_LINK_CHAIN))
{
if (linked_move_start_index + 1 < i && min_pp < 2)
{
for (s32 j = linked_move_start_index; j < i; j++)
{
will_not_unlink_move[j] = FALSE;
}
}
min_pp = move->pp;
linked_move_start_index = i;
}
else if (move->pp >= min_pp)
min_pp = move->pp;
}
if (linked_move_start_index + 1 < i && min_pp < 2)
{
for (s32 j = linked_move_start_index; j < i; j++)
{
will_not_unlink_move[j] = FALSE;
}
}
}
for (i = 0; i < MAX_MON_MOVES; i++)
{
ai_possible_move[i].can_be_used = FALSE;
struct move *moves = pokemon_info->moves.moves;
move = &moves[i];
if (!MoveExists(move))
continue;
if (will_not_unlink_move[i] &&
CanAiUseMove(monster, i, has_exclusive_move_user) &&
move->flags0 & MOVE_FLAG_ENABLED_FOR_AI)
{
ai_possible_move[i].can_be_used = TRUE;
if (pokemon_info->bide_class_status.bide == STATUS_TWO_TURN_CHARGING)
{
if (move->id == MOVE_CHARGE)
{
ai_possible_move[i].weight = 0;
continue;
}
else if (GetMoveTypeForMonster(monster, move) == TYPE_ELECTRIC)
ai_possible_move[i].weight = GetMoveAiWeight(move);
else
ai_possible_move[i].weight = 1;
}
else if (has_weak_type_picker)
ai_possible_move[i].weight = AiConsiderMove(&ai_possible_move[i], monster, &pokemon_info->moves.moves[i]);
else
ai_possible_move[i].weight = GetMoveAiWeight(move);
total_weight += ai_possible_move[i].weight;
}
}
ai_possible_move[REGULAR_ATTACK_INDEX].weight = 0;
if (!IqSkillIsEnabled(monster, IQ_EXCLUSIVE_MOVE_USER) && pokemon_info->bide_class_status.bide != STATUS_TWO_TURN_CHARGING)
{
ai_possible_move[REGULAR_ATTACK_INDEX].can_be_used = TRUE;
if (pokemon_info->bide_class_status.bide == STATUS_TWO_TURN_CHARGING)
// Never reached? Charge already skips the regular attack in the outer block.
ai_possible_move[REGULAR_ATTACK_INDEX].weight = 1;
else if (has_weak_type_picker)
ai_possible_move[REGULAR_ATTACK_INDEX].weight = 2;
else
ai_possible_move[REGULAR_ATTACK_INDEX].weight = AI_REGULAR_ATTACK_WEIGHTS[num_usable_moves];
total_weight += ai_possible_move[REGULAR_ATTACK_INDEX].weight;
}
if (has_weak_type_picker)
{
s32 max_weight = 0;
total_weight = 0;
for (i = 0; i < MAX_MON_MOVES + 1; i++)
{
if (!ai_possible_move[i].can_be_used)
ai_possible_move[i].weight = 0;
else if (max_weight < ai_possible_move[i].weight)
max_weight = ai_possible_move[i].weight;
}
for (i = 0; i < MAX_MON_MOVES + 1; i++)
{
if (ai_possible_move[i].can_be_used)
{
if (max_weight != ai_possible_move[i].weight)
// Only the move(s) with the highest weight can be used, instead of a weighted random.
// This has the side effect of making the AI use a STAB ranged move consistently when at a distance.
ai_possible_move[i].weight = 0;
total_weight += ai_possible_move[i].weight;
}
}
}
if (total_weight == 0)
return;
s32 random_weight = DungeonRandInt(total_weight);
bool8 can_target_regular_attack;
s32 weight_counter = 0;
bool8 has_stall = FALSE;
if (AbilityIsActiveVeneer(monster, ABILITY_STALL) && !ov29_02338350(monster))
{
has_stall = TRUE;
can_target_regular_attack = TargetRegularAttack(monster, &regular_attack_target_dir, TRUE);
}
if (!has_stall)
{
if (!IqSkillIsEnabled(monster, IQ_EXCLUSIVE_MOVE_USER))
can_target_regular_attack = TargetRegularAttack(monster, &regular_attack_target_dir, TRUE);
else
{
can_target_regular_attack = FALSE;
regular_attack_target_dir = DIR_DOWN;
}
}
for (i = 0; i < REGULAR_ATTACK_INDEX + 1; i++)
{
if (ai_possible_move[i].can_be_used && ai_possible_move[i].weight != 0)
{
weight_counter += ai_possible_move[i].weight;
if (weight_counter >= random_weight)
{
if (has_stall || i == REGULAR_ATTACK_INDEX)
{
if (can_target_regular_attack)
{
SetActionRegularAttack(&pokemon_info->action, regular_attack_target_dir);
UpdateAiTargetPos(monster);
}
else
break;
}
else
{
AiConsiderMove(&ai_possible_move[i], monster, &pokemon_info->moves.moves[i]);
if (ai_possible_move[i].can_be_used)
{
s32 j;
for (j = i; j > 0; j--)
{
if (!(pokemon_info->moves.moves[j].flags0 & MOVE_FLAG_SUBSEQUENT_IN_LINK_CHAIN))
break;
}
SetActionUseMoveAi(&pokemon_info->action, j, ai_possible_move[i].direction);
UpdateAiTargetPos(monster);
}
else
break;
}
return;
}
}
}
if (can_target_regular_attack)
{
SetActionRegularAttack(&pokemon_info->action, regular_attack_target_dir);
UpdateAiTargetPos(monster);
}
}
#endif

View File

@ -1,6 +1,7 @@
#include "status_checks.h"
#include "dg_random.h"
#include "dungeon_action.h"
#include "dungeon_ai_itcm.h"
#include "dungeon_logic_3.h"
#include "dungeon_statuses.h"
#include "dungeon_util_static.h"
@ -20,7 +21,6 @@
extern void SubstitutePlaceholderStringTags(u8 *string_id, struct entity *entity, u32 param_3);
extern void LogMessageByIdWithPopupCheckUser(struct entity *user, u32 message_id);
extern void ChooseAiMove(struct entity *monster);
bool8 HasStatusThatPreventsActing(struct entity *monster)
{