ref: 44377acb2ae9ffe42d9ac4876c30672739359e5b
parent: 28097be25ca8054476c6f377ba23d41d79b4c409
author: xCrystal <rgr.crystal@gmail.com>
date: Tue Oct 21 15:21:13 EDT 2014
Rename labels and add more commentary to AI stuff
--- a/battle/ai/scoring.asm
+++ b/battle/ai/scoring.asm
@@ -1,5 +1,5 @@
AIScoring_RedStatus: ; 38591
-; Don't use status-only moves if the player can't be statused.
+; Handle the AI of status-only moves and moves with special effects
ld hl, Buffer1 - 1
ld de, EnemyMonMoves
@@ -19,15 +19,19 @@
ld a, [wEnemyMoveStruct + MOVE_EFFECT]
ld c, a
+; Dismiss moves with special effects if they are
+; useless or not a good choice right now.
+; For example, healing moves, weather moves, Dream Eater...
push hl
push de
push bc
- callba Function2c41a
+ callba AISpecialEffects
pop bc
pop de
pop hl
jr nz, .discourage
+; Dismiss status-only moves if the player can't be statused.
ld a, [wEnemyMoveStruct + MOVE_EFFECT]
push hl
push de
@@ -45,6 +49,7 @@
and a
jr nz, .discourage
+; Dismiss Safeguard if it's already active
ld a, [PlayerScreens]
bit SCREENS_SAFEGUARD, a
jr z, .checkmove
@@ -65,7 +70,9 @@
AIScoring_RedStatMods: ; 385e0
-; Use stat-modifying moves on turn 1.
+; 50% chance to greatly encourage stat-up moves during enemy's first turn
+; 50% chance to greatly encourage stat-down moves during player's first turn
+; Almost 90% chance to greatly discourage stat-modifying moves otherwise
ld hl, Buffer1 - 1
ld de, EnemyMonMoves
@@ -699,7 +706,7 @@
; ...or player's evasion level has been rasied three or more stages
ld a, [PlayerEvaLevel]
cp $a
- ret c
+ ret c
.asm_38954
call Function39521
@@ -929,6 +936,7 @@
AIScoring_LightScreen:
AIScoring_Reflect: ; 38a54
; Over 90% chance to discourage this move unless enemy's HP is full
+
call AICheckEnemyMaxHP
ret c
call Random
@@ -2956,7 +2964,9 @@
AIScoring_Aggressive: ; 39369
-; Use whatever does the most damage.
+; Discourage all damaging moves but the one that does the most damage.
+; If no damaging move deals damage to the player (immune),
+; no move will be discouraged
; Figure out which attack does the most damage and put it in c.
ld hl, EnemyMonMoves
@@ -2984,6 +2994,7 @@
pop de
pop hl
+; Update current move if damage is highest so far
ld a, [CurDamage + 1]
cp e
ld a, [CurDamage]
@@ -3019,6 +3030,7 @@
cp EnemyMonMovesEnd - EnemyMonMoves + 1
jr z, .done
+; Ignore this move if it is the highest damaging one
cp c
ld a, [de]
inc de
@@ -3027,15 +3039,17 @@
call AIGetEnemyMove
+; Ignore this move if its power is 0 or 1
ld a, [wEnemyMoveStruct + MOVE_POWER]
cp 2
jr c, .checkmove2
+; Ignore this move if it is reckless
push hl
push de
push bc
ld a, [wEnemyMoveStruct + MOVE_EFFECT]
- ld hl, .aggressivemoves
+ ld hl, .recklessmoves
ld de, 1
call IsInArray
pop bc
@@ -3043,6 +3057,7 @@
pop hl
jr c, .checkmove2
+; If we made it this far, discourage this move
inc [hl]
jr .checkmove2
@@ -3049,7 +3064,7 @@
.done
ret
-.aggressivemoves
+.recklessmoves
db EFFECT_EXPLOSION
db EFFECT_RAMPAGE
db EFFECT_MULTI_HIT
@@ -3293,6 +3308,8 @@
AIGetEnemyMove: ; 39508
+; Load attributes of move a into ram
+
push hl
push de
push bc
--- a/main.asm
+++ b/main.asm
@@ -41681,11 +41681,13 @@
-Function2c41a: ; 2c41a (b:441a)
-; More move AI.
+AISpecialEffects: ; 2c41a (b:441a)
+; Specific AI for certain move effects
+; Return z if the move is a good choice
+; Return nz if the move is a bad choice
ld a, c
ld de, 3
- ld hl, Unknown_2c42c
+ ld hl, SpecialEffectMoves
call IsInArray
jp nc, Function2c545
inc hl
@@ -41695,7 +41697,7 @@
jp [hl]
; 2c42c (b:442c)
-Unknown_2c42c: ; 2c42c
+SpecialEffectMoves: ; 2c42c
dbw EFFECT_DREAM_EATER, Function2c524
dbw EFFECT_HEAL, Function2c539
dbw EFFECT_LIGHT_SCREEN, Function2c487
@@ -47148,7 +47150,7 @@
ld a, c
cp 16 ; up to 16 scoring layers
- jr z, .asm_4415e
+ jr z, .DecrementScores
push bc
ld d, $e ; BANK(TrainerAI)
@@ -47177,27 +47179,36 @@
jr .CheckLayer
-.asm_4415e
+; Decrement the scores of all moves one by one until one reaches 0
+; If the Pokemon has no moves, the game will loop indefinitely
+.DecrementScores
ld hl, Buffer1
ld de, EnemyMonMoves
ld c, EnemyMonMovesEnd - EnemyMonMoves
-.asm_44166
+
+.DecrementNextScore
ld a, [de]
inc de
and a
- jr z, .asm_4415e
+ jr z, .DecrementScores
+ ; We are done whenever a score reaches 0
dec [hl]
- jr z, .asm_44174
+ jr z, .PickLowestScoreMoves
+ ; If we just decremented the fourth move's score, go back to the first move
inc hl
dec c
- jr z, .asm_4415e
+ jr z, .DecrementScores
- jr .asm_44166
+ jr .DecrementNextScore
-.asm_44174
+; In order to avoid bias towards the moves located first in memory, increment the scores
+; that were decremented one more time than the rest (in case there was a tie)
+; This means that the minimum score will be 1
+.PickLowestScoreMoves
ld a, c
+
.asm_44175
inc [hl]
dec hl
@@ -47208,11 +47219,15 @@
ld hl, Buffer1
ld de, EnemyMonMoves
ld c, NUM_MOVES
+
+; Give a score of 0 to a blank move
.asm_44184
ld a, [de]
and a
jr nz, .asm_44189
- ld [hl], a
+ ld [hl], a
+
+; Disregard the move if its score is not 1
.asm_44189
ld a, [hl]
dec a
@@ -47220,6 +47235,7 @@
xor a
ld [hli], a
jr .asm_44193
+
.asm_44191
ld a, [de]
ld [hli], a
@@ -47228,7 +47244,8 @@
dec c
jr nz, .asm_44184
-.asm_44197
+; Randomly choose one of the moves with a score of 1
+.ChooseMove
ld hl, Buffer1
call Random
and 3
@@ -47237,7 +47254,7 @@
add hl, bc
ld a, [hl]
and a
- jr z, .asm_44197
+ jr z, .ChooseMove
ld [CurEnemyMove], a
ld a, c