summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--constants/battle_constants.asm11
-rw-r--r--data/battle/critical_hit_chances.asm8
-rw-r--r--data/moves/critical_hit_moves.asm9
-rw-r--r--data/moves/grammar.asm101
-rw-r--r--engine/battle/effect_commands.asm1221
-rw-r--r--engine/battle/move_effects/triple_kick.asm34
-rw-r--r--engine/battle/used_move_text.asm235
-rwxr-xr-xengine/items/item_effects.asm18
-rw-r--r--main.asm62
-rw-r--r--pokegold.link9
-rw-r--r--pokesilver.link9
-rw-r--r--wram.asm48
12 files changed, 1707 insertions, 58 deletions
diff --git a/constants/battle_constants.asm b/constants/battle_constants.asm
index a53a7100..2c5e6b83 100644
--- a/constants/battle_constants.asm
+++ b/constants/battle_constants.asm
@@ -231,10 +231,17 @@ SUBSTATUS_CURLED EQU 0
const BATTLEACTION_A
const BATTLEACTION_B
const BATTLEACTION_C
- const BATTLEACTION_D
- const BATTLEACTION_E
+ const BATTLEACTION_SKIPTURN
+ const BATTLEACTION_STRUGGLE
const BATTLEACTION_FORFEIT
+; wBattlePlayerAction
+ const_def
+ const BATTLEPLAYERACTION_USEMOVE
+ const BATTLEPLAYERACTION_USEITEM
+ const BATTLEPLAYERACTION_SWITCH
+
+; wBattleResult
const_def
const WIN
const LOSE
diff --git a/data/battle/critical_hit_chances.asm b/data/battle/critical_hit_chances.asm
new file mode 100644
index 00000000..0128f1a1
--- /dev/null
+++ b/data/battle/critical_hit_chances.asm
@@ -0,0 +1,8 @@
+CriticalHitChances:
+ db 7 percent ; 0
+ db 12 percent + 2 ; +1
+ db 25 percent + 1 ; +2
+ db 33 percent + 1 ; +3
+ db 50 percent + 1 ; +4
+ db 50 percent + 1 ; +5
+ db 50 percent + 1 ; +6
diff --git a/data/moves/critical_hit_moves.asm b/data/moves/critical_hit_moves.asm
new file mode 100644
index 00000000..4a473057
--- /dev/null
+++ b/data/moves/critical_hit_moves.asm
@@ -0,0 +1,9 @@
+CriticalHitMoves:
+ db KARATE_CHOP
+ db RAZOR_WIND
+ db RAZOR_LEAF
+ db CRABHAMMER
+ db SLASH
+ db AEROBLAST
+ db CROSS_CHOP
+ db -1
diff --git a/data/moves/grammar.asm b/data/moves/grammar.asm
new file mode 100644
index 00000000..f2474808
--- /dev/null
+++ b/data/moves/grammar.asm
@@ -0,0 +1,101 @@
+; Used by GetMoveGrammar (see engine/battle/used_move_text.asm)
+; Each move is given an identifier for what usedmovetext to use (0-4).
+; Made redundant in English localization, where all are just "[mon]¯used [move]!"
+
+MoveGrammar:
+; 0: originally "[mon]の¯[move]¯つかった!" ("[mon]¯used¯[move]!")
+ db SWORDS_DANCE
+ db GROWTH
+ db STRENGTH
+ db HARDEN
+ db MINIMIZE
+ db SMOKESCREEN
+ db WITHDRAW
+ db DEFENSE_CURL
+ db EGG_BOMB
+ db SMOG
+ db BONE_CLUB
+ db FLASH
+ db SPLASH
+ db ACID_ARMOR
+ db BONEMERANG
+ db REST
+ db SHARPEN
+ db SUBSTITUTE
+ db MIND_READER
+ db SNORE
+ db PROTECT
+ db SPIKES
+ db ENDURE
+ db ROLLOUT
+ db SWAGGER
+ db SLEEP_TALK
+ db HIDDEN_POWER
+ db PSYCH_UP
+ db EXTREMESPEED
+ db 0 ; end set
+
+; 1: originally "[mon]の¯[move]した!" ("[mon]¯did [move]!")
+ db RECOVER
+ db TELEPORT
+ db BIDE
+ db SELFDESTRUCT
+ db AMNESIA
+ db FLAIL
+ db 0 ; end set
+
+; 2: originally "[mon]の¯[move]¯した!" ("[mon]¯did¯[move]!")
+ db MEDITATE
+ db AGILITY
+ db MIMIC
+ db DOUBLE_TEAM
+ db BARRAGE
+ db TRANSFORM
+ db STRUGGLE
+ db SCARY_FACE
+ db 0 ; end set
+
+; 3: originally "[mon]の¯[move] こうげき!" ("[mon]'s¯[move] attack!")
+ db POUND
+ db SCRATCH
+ db VICEGRIP
+ db WING_ATTACK
+ db FLY
+ db BIND
+ db SLAM
+ db HORN_ATTACK
+ db WRAP
+ db THRASH
+ db TAIL_WHIP
+ db LEER
+ db BITE
+ db GROWL
+ db ROAR
+ db SING
+ db PECK
+ db ABSORB
+ db STRING_SHOT
+ db EARTHQUAKE
+ db FISSURE
+ db DIG
+ db TOXIC
+ db SCREECH
+ db METRONOME
+ db LICK
+ db CLAMP
+ db CONSTRICT
+ db POISON_GAS
+ db BUBBLE
+ db SLASH
+ db SPIDER_WEB
+ db NIGHTMARE
+ db CURSE
+ db FORESIGHT
+ db CHARM
+ db ATTRACT
+ db ROCK_SMASH
+ db 0 ; end set
+
+; 4: originally "[mon]の¯[move]!" ("[mon]'s¯[move]!")
+; Any move not listed above uses this grammar.
+ db -1 ; end
diff --git a/engine/battle/effect_commands.asm b/engine/battle/effect_commands.asm
new file mode 100644
index 00000000..023730ac
--- /dev/null
+++ b/engine/battle/effect_commands.asm
@@ -0,0 +1,1221 @@
+DoPlayerTurn:
+; Read in and execute the player's move effects for this turn.
+ call SetPlayerTurn
+
+ ld a, [wBattlePlayerAction]
+ and a ; BATTLEPLAYERACTION_USEMOVE?
+ ret nz
+
+ xor a
+ ld [wTurnEnded], a
+
+ ; Effect command checkturn is called for every move.
+ call CheckTurn
+
+ ld a, [wTurnEnded]
+ and a
+ ret nz
+
+ call UpdateMoveData
+ jr DoMove
+
+DoEnemyTurn:
+; Read in and execute the enemy's move effects for this turn.
+ call SetEnemyTurn
+
+ ld a, [wLinkMode]
+ and a
+ jr z, .do_it
+
+ ld a, [wBattleAction]
+ cp BATTLEACTION_STRUGGLE
+ jr z, .do_it
+ cp BATTLEACTION_SWITCH1
+ ret nc
+
+.do_it
+ xor a
+ ld [wTurnEnded], a
+
+ ; Effect command checkturn is called for every move.
+ call CheckTurn
+
+ ld a, [wTurnEnded]
+ and a
+ ret nz
+
+ call UpdateMoveData
+
+ ; fallthrough
+
+DoMove:
+; Get the user's move effect.
+ ld a, BATTLE_VARS_MOVE_EFFECT
+ call GetBattleVar
+ ld c, a
+ ld b, 0
+ ld hl, MoveEffectsPointers
+ add hl, bc
+ add hl, bc
+ ld a, BANK(MoveEffectsPointers)
+ call GetFarHalfword
+
+ ld de, wBattleScriptBuffer
+
+.GetMoveEffect:
+ ld a, BANK(MoveEffects)
+ call GetFarByte
+ inc hl
+ ld [de], a
+ inc de
+ cp endmove_command
+ jr nz, .GetMoveEffect
+
+; Start at the first command.
+ ld hl, wBattleScriptBuffer
+ ld a, l
+ ld [wBattleScriptBufferAddress], a
+ ld a, h
+ ld [wBattleScriptBufferAddress + 1], a
+
+.ReadMoveEffectCommand:
+; ld a, [wBattleScriptBufferAddress++]
+ ld a, [wBattleScriptBufferAddress]
+ ld l, a
+ ld a, [wBattleScriptBufferAddress + 1]
+ ld h, a
+
+ ld a, [hli]
+
+ push af
+ ld a, l
+ ld [wBattleScriptBufferAddress], a
+ ld a, h
+ ld [wBattleScriptBufferAddress + 1], a
+ pop af
+
+; endturn_command (-2) is used to terminate branches without ending the read cycle.
+ cp endturn_command
+ ret nc
+
+; The rest of the commands (01-af) are read from BattleCommandPointers.
+ push bc
+ dec a
+ ld c, a
+ ld b, 0
+ ld hl, BattleCommandPointers
+ add hl, bc
+ add hl, bc
+ pop bc
+
+ ld a, BANK(BattleCommandPointers)
+ call GetFarHalfword
+
+ call .DoMoveEffectCommand
+
+ jr .ReadMoveEffectCommand
+
+.DoMoveEffectCommand:
+ jp hl
+
+CheckTurn:
+BattleCommand_CheckTurn:
+; checkturn
+
+; Repurposed as hardcoded turn handling. Useless as a command.
+
+; Move $ff immediately ends the turn.
+ ld a, BATTLE_VARS_MOVE
+ call GetBattleVar
+ inc a
+ jp z, EndTurn
+
+ xor a
+ ld [wAttackMissed], a
+ ld [wEffectFailed], a
+ ld [wKickCounter], a
+ ld [wAlreadyDisobeyed], a
+ ld [wAlreadyFailed], a
+ ld [wSomeoneIsRampaging], a
+
+ ld a, EFFECTIVE
+ ld [wTypeModifier], a
+
+ ldh a, [hBattleTurn]
+ and a
+ jp nz, CheckEnemyTurn
+
+CheckPlayerTurn:
+ ld hl, wPlayerSubStatus4
+ bit SUBSTATUS_RECHARGE, [hl]
+ jr z, .no_recharge
+
+ res SUBSTATUS_RECHARGE, [hl]
+ ld hl, MustRechargeText
+ call StdBattleTextbox
+ call CantMove
+ jp EndTurn
+
+.no_recharge
+
+ ld hl, wBattleMonStatus
+ ld a, [hl]
+ and SLP
+ jr z, .not_asleep
+
+ dec a
+ ld [wBattleMonStatus], a
+ and SLP
+ jr z, .woke_up
+
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_SLP
+ call FarPlayBattleAnimation
+ jr .fast_asleep
+
+.woke_up
+ ld hl, WokeUpText
+ call StdBattleTextbox
+ call CantMove
+ call UpdateBattleMonInParty
+ ld hl, UpdatePlayerHUD
+ call CallBattleCore
+ ld a, $1
+ ldh [hBGMapMode], a
+ ld hl, wPlayerSubStatus1
+ res SUBSTATUS_NIGHTMARE, [hl]
+ jr .not_asleep
+
+.fast_asleep
+ ld hl, FastAsleepText
+ call StdBattleTextbox
+
+ ; Snore and Sleep Talk bypass sleep.
+ ld a, [wCurPlayerMove]
+ cp SNORE
+ jr z, .not_asleep
+ cp SLEEP_TALK
+ jr z, .not_asleep
+
+ call CantMove
+ jp EndTurn
+
+.not_asleep
+
+ ld hl, wBattleMonStatus
+ bit FRZ, [hl]
+ jr z, .not_frozen
+
+ ; Flame Wheel and Sacred Fire thaw the user.
+ ld a, [wCurPlayerMove]
+ cp FLAME_WHEEL
+ jr z, .not_frozen
+ cp SACRED_FIRE
+ jr z, .not_frozen
+
+ ld hl, FrozenSolidText
+ call StdBattleTextbox
+
+ call CantMove
+ jp EndTurn
+
+.not_frozen
+
+ ld hl, wPlayerSubStatus3
+ bit SUBSTATUS_FLINCHED, [hl]
+ jr z, .not_flinched
+
+ res SUBSTATUS_FLINCHED, [hl]
+ ld hl, FlinchedText
+ call StdBattleTextbox
+
+ call CantMove
+ jp EndTurn
+
+.not_flinched
+
+ ld hl, wPlayerDisableCount
+ ld a, [hl]
+ and a
+ jr z, .not_disabled
+
+ dec a
+ ld [hl], a
+ and $f
+ jr nz, .not_disabled
+
+ ld [hl], a
+ ld [wDisabledMove], a
+ ld hl, DisabledNoMoreText
+ call StdBattleTextbox
+
+.not_disabled
+
+ ld a, [wPlayerSubStatus3]
+ add a
+ jr nc, .not_confused
+ ld hl, wPlayerConfuseCount
+ dec [hl]
+ jr nz, .confused
+
+ ld hl, wPlayerSubStatus3
+ res SUBSTATUS_CONFUSED, [hl]
+ ld hl, ConfusedNoMoreText
+ call StdBattleTextbox
+ jr .not_confused
+
+.confused
+ ld hl, IsConfusedText
+ call StdBattleTextbox
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_CONFUSED
+ call FarPlayBattleAnimation
+
+ ; 50% chance of hitting itself
+ call BattleRandom
+ cp 50 percent + 1
+ jr nc, .not_confused
+
+ ; clear confusion-dependent substatus
+ ld hl, wPlayerSubStatus3
+ ld a, [hl]
+ and 1 << SUBSTATUS_CONFUSED
+ ld [hl], a
+
+ call HitConfusion
+ call CantMove
+ jp EndTurn
+
+.not_confused
+
+ ld a, [wPlayerSubStatus1]
+ add a ; bit SUBSTATUS_ATTRACT
+ jr nc, .not_infatuated
+
+ ld hl, InLoveWithText
+ call StdBattleTextbox
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_IN_LOVE
+ call FarPlayBattleAnimation
+
+ ; 50% chance of infatuation
+ call BattleRandom
+ cp 50 percent + 1
+ jr c, .not_infatuated
+
+ ld hl, InfatuationText
+ call StdBattleTextbox
+ call CantMove
+ jp EndTurn
+
+.not_infatuated
+
+ ; We can't disable a move that doesn't exist.
+ ld a, [wDisabledMove]
+ and a
+ jr z, .no_disabled_move
+
+ ; Are we using the disabled move?
+ ld hl, wCurPlayerMove
+ cp [hl]
+ jr nz, .no_disabled_move
+
+ call MoveDisabled
+ call CantMove
+ jp EndTurn
+
+.no_disabled_move
+
+ ld hl, wBattleMonStatus
+ bit PAR, [hl]
+ ret z
+
+ ; 25% chance to be fully paralyzed
+ call BattleRandom
+ cp 25 percent
+ ret nc
+
+ ld hl, FullyParalyzedText
+ call StdBattleTextbox
+ call CantMove
+ jp EndTurn
+
+CantMove:
+ ld a, BATTLE_VARS_SUBSTATUS1
+ call GetBattleVarAddr
+ res SUBSTATUS_ROLLOUT, [hl]
+
+ ld a, BATTLE_VARS_SUBSTATUS3
+ call GetBattleVarAddr
+ ld a, [hl]
+ and $ff ^ (1 << SUBSTATUS_BIDE | 1 << SUBSTATUS_RAMPAGE | 1 << SUBSTATUS_CHARGED)
+ ld [hl], a
+
+ call ResetFuryCutterCount
+
+ ld a, BATTLE_VARS_MOVE_ANIM
+ call GetBattleVar
+ cp FLY
+ jr z, .fly_dig
+
+ cp DIG
+ ret nz
+
+.fly_dig
+ res SUBSTATUS_UNDERGROUND, [hl]
+ res SUBSTATUS_FLYING, [hl]
+ jp AppearUserRaiseSub
+
+OpponentCantMove:
+ call BattleCommand_SwitchTurn
+ call CantMove
+ jp BattleCommand_SwitchTurn
+
+CheckEnemyTurn:
+ ld hl, wEnemySubStatus4
+ bit SUBSTATUS_RECHARGE, [hl]
+ jr z, .no_recharge
+
+ res SUBSTATUS_RECHARGE, [hl]
+ ld hl, MustRechargeText
+ call StdBattleTextbox
+ call CantMove
+ jp EndTurn
+
+.no_recharge
+
+ ld hl, wEnemyMonStatus
+ ld a, [hl]
+ and SLP
+ jr z, .not_asleep
+
+ dec a
+ ld [wEnemyMonStatus], a
+ and a
+ jr z, .woke_up
+
+ ld hl, FastAsleepText
+ call StdBattleTextbox
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_SLP
+ call FarPlayBattleAnimation
+ jr .fast_asleep
+
+.woke_up
+ ld hl, WokeUpText
+ call StdBattleTextbox
+ call CantMove
+ call UpdateEnemyMonInParty
+ ld hl, UpdateEnemyHUD
+ call CallBattleCore
+ ld a, $1
+ ldh [hBGMapMode], a
+ ld hl, wEnemySubStatus1
+ res SUBSTATUS_NIGHTMARE, [hl]
+ jr .not_asleep
+
+.fast_asleep
+ ; Snore and Sleep Talk bypass sleep.
+ ld a, [wCurEnemyMove]
+ cp SNORE
+ jr z, .not_asleep
+ cp SLEEP_TALK
+ jr z, .not_asleep
+ call CantMove
+ jp EndTurn
+
+.not_asleep
+
+ ld hl, wEnemyMonStatus
+ bit FRZ, [hl]
+ jr z, .not_frozen
+
+ ; Flame Wheel and Sacred Fire thaw the user.
+ ld a, [wCurEnemyMove]
+ cp FLAME_WHEEL
+ jr z, .not_frozen
+ cp SACRED_FIRE
+ jr z, .not_frozen
+
+ ld hl, FrozenSolidText
+ call StdBattleTextbox
+ call CantMove
+ jp EndTurn
+
+.not_frozen
+
+ ld hl, wEnemySubStatus3
+ bit SUBSTATUS_FLINCHED, [hl]
+ jr z, .not_flinched
+
+ res SUBSTATUS_FLINCHED, [hl]
+ ld hl, FlinchedText
+ call StdBattleTextbox
+
+ call CantMove
+ jp EndTurn
+
+.not_flinched
+
+ ld hl, wEnemyDisableCount
+ ld a, [hl]
+ and a
+ jr z, .not_disabled
+
+ dec a
+ ld [hl], a
+ and $f
+ jr nz, .not_disabled
+
+ ld [hl], a
+ ld [wEnemyDisabledMove], a
+
+ ld hl, DisabledNoMoreText
+ call StdBattleTextbox
+
+.not_disabled
+
+ ld a, [wEnemySubStatus3]
+ add a ; bit SUBSTATUS_CONFUSED
+ jr nc, .not_confused
+
+ ld hl, wEnemyConfuseCount
+ dec [hl]
+ jr nz, .confused
+
+ ld hl, wEnemySubStatus3
+ res SUBSTATUS_CONFUSED, [hl]
+ ld hl, ConfusedNoMoreText
+ call StdBattleTextbox
+ jr .not_confused
+
+.confused
+ ld hl, IsConfusedText
+ call StdBattleTextbox
+
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_CONFUSED
+ call FarPlayBattleAnimation
+
+ ; 50% chance of hitting itself
+ call BattleRandom
+ cp 50 percent + 1
+ jr nc, .not_confused
+
+ ; clear confusion-dependent substatus
+ ld hl, wEnemySubStatus3
+ ld a, [hl]
+ and 1 << SUBSTATUS_CONFUSED
+ ld [hl], a
+
+ ld hl, HurtItselfText
+ call StdBattleTextbox
+
+ call HitSelfInConfusion
+ call BattleCommand_DamageCalc
+ call BattleCommand_LowerSub
+
+ xor a
+ ld [wNumHits], a
+
+ ; Flicker the monster pic unless flying or underground.
+ ld de, ANIM_HIT_CONFUSION
+ ld a, BATTLE_VARS_SUBSTATUS3_OPP
+ call GetBattleVar
+ and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
+ call z, PlayFXAnimID
+
+ ld c, TRUE
+ call DoEnemyDamage
+ call BattleCommand_RaiseSub
+ call CantMove
+ jp EndTurn
+
+.not_confused
+
+ ld a, [wEnemySubStatus1]
+ add a ; bit SUBSTATUS_ATTRACT
+ jr nc, .not_infatuated
+
+ ld hl, InLoveWithText
+ call StdBattleTextbox
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_IN_LOVE
+ call FarPlayBattleAnimation
+
+ ; 50% chance of infatuation
+ call BattleRandom
+ cp 50 percent + 1
+ jr c, .not_infatuated
+
+ ld hl, InfatuationText
+ call StdBattleTextbox
+ call CantMove
+ jp EndTurn
+
+.not_infatuated
+
+ ; We can't disable a move that doesn't exist.
+ ld a, [wEnemyDisabledMove]
+ and a
+ jr z, .no_disabled_move
+
+ ; Are we using the disabled move?
+ ld hl, wCurEnemyMove
+ cp [hl]
+ jr nz, .no_disabled_move
+
+ call MoveDisabled
+
+ call CantMove
+ jp EndTurn
+
+.no_disabled_move
+
+ ld hl, wEnemyMonStatus
+ bit PAR, [hl]
+ ret z
+
+ ; 25% chance to be fully paralyzed
+ call BattleRandom
+ cp 25 percent
+ ret nc
+
+ ld hl, FullyParalyzedText
+ call StdBattleTextbox
+ call CantMove
+
+ ; fallthrough
+
+EndTurn:
+ ld a, $1
+ ld [wTurnEnded], a
+ jp ResetDamage
+
+MoveDisabled:
+ ; Make sure any charged moves fail
+ ld a, BATTLE_VARS_SUBSTATUS3
+ call GetBattleVarAddr
+ res SUBSTATUS_CHARGED, [hl]
+
+ ld a, BATTLE_VARS_MOVE
+ call GetBattleVar
+ ld [wNamedObjectIndexBuffer], a
+ call GetMoveName
+
+ ld hl, DisabledMoveText
+ jp StdBattleTextbox
+
+HitConfusion:
+ ld hl, HurtItselfText
+ call StdBattleTextbox
+
+ xor a
+ ld [wCriticalHit], a
+
+ call HitSelfInConfusion
+ call BattleCommand_DamageCalc
+ call BattleCommand_LowerSub
+
+ xor a
+ ld [wNumHits], a
+
+ ; Flicker the monster pic unless flying or underground.
+ ld de, ANIM_HIT_CONFUSION
+ ld a, BATTLE_VARS_SUBSTATUS3_OPP
+ call GetBattleVar
+ and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
+ call z, PlayFXAnimID
+
+ ld hl, UpdatePlayerHUD
+ call CallBattleCore
+ ld a, $1
+ ldh [hBGMapMode], a
+ ld c, TRUE
+ call DoPlayerDamage
+ jp BattleCommand_RaiseSub
+
+BattleCommand_CheckObedience:
+; checkobedience
+
+ ; Enemy can't disobey
+ ldh a, [hBattleTurn]
+ and a
+ ret nz
+
+ call CheckUserIsCharging
+ ret nz
+
+ ; If we've already checked this turn
+ ld a, [wAlreadyDisobeyed]
+ and a
+ ret nz
+
+ xor a
+ ld [wAlreadyDisobeyed], a
+
+ ; No obedience in link battles
+ ; (since no handling exists for enemy)
+ ld a, [wLinkMode]
+ and a
+ ret nz
+
+ ; If the monster's id doesn't match the player's,
+ ; some conditions need to be met.
+ ld a, MON_ID
+ call BattlePartyAttr
+
+ ld a, [wPlayerID]
+ cp [hl]
+ jr nz, .obeylevel
+ inc hl
+ ld a, [wPlayerID + 1]
+ cp [hl]
+ ret z
+
+.obeylevel
+ ; The maximum obedience level is constrained by owned badges:
+ ld hl, wJohtoBadges
+
+ ; risingbadge
+ bit RISINGBADGE, [hl]
+ ld a, MAX_LEVEL + 1
+ jr nz, .getlevel
+
+ ; stormbadge
+ bit STORMBADGE, [hl]
+ ld a, 70
+ jr nz, .getlevel
+
+ ; fogbadge
+ bit FOGBADGE, [hl]
+ ld a, 50
+ jr nz, .getlevel
+
+ ; hivebadge
+ bit HIVEBADGE, [hl]
+ ld a, 30
+ jr nz, .getlevel
+
+ ; no badges
+ ld a, 10
+
+.getlevel
+; c = obedience level
+; d = monster level
+; b = c + d
+
+ ld b, a
+ ld c, a
+
+ ld a, [wBattleMonLevel]
+ ld d, a
+
+ add b
+ ld b, a
+
+; No overflow (this should never happen)
+ jr nc, .checklevel
+ ld b, $ff
+
+.checklevel
+; If the monster's level is lower than the obedience level, it will obey.
+ ld a, c
+ cp d
+ ret nc
+
+; Random number from 0 to obedience level + monster level
+.rand1
+ call BattleRandom
+ swap a
+ cp b
+ jr nc, .rand1
+
+; The higher above the obedience level the monster is,
+; the more likely it is to disobey.
+ cp c
+ ret c
+
+; Sleep-only moves have separate handling, and a higher chance of
+; being ignored. Lazy monsters like their sleep.
+ call IgnoreSleepOnly
+ ret c
+
+; Another random number from 0 to obedience level + monster level
+.rand2
+ call BattleRandom
+ cp b
+ jr nc, .rand2
+
+; A second chance.
+ cp c
+ jr c, .UseInstead
+
+; No hope of using a move now.
+
+; b = number of levels the monster is above the obedience level
+ ld a, d
+ sub c
+ ld b, a
+
+; The chance of napping is the difference out of 256.
+ call BattleRandom
+ swap a
+ sub b
+ jr c, .Nap
+
+; The chance of not hitting itself is the same.
+ cp b
+ jr nc, .DoNothing
+
+ ld hl, WontObeyText
+ call StdBattleTextbox
+ call HitConfusion
+ jp .EndDisobedience
+
+.Nap:
+ call BattleRandom
+ add a
+ swap a
+ and SLP
+ jr z, .Nap
+
+ ld [wBattleMonStatus], a
+
+ ld hl, BeganToNapText
+ jr .Print
+
+.DoNothing:
+ ; 4 random choices
+ call BattleRandom
+ and %11
+
+ ld hl, LoafingAroundText
+ and a ; 0
+ jr z, .Print
+
+ ld hl, WontObeyText
+ dec a ; 1
+ jr z, .Print
+
+ ld hl, TurnedAwayText
+ dec a ; 2
+ jr z, .Print
+
+ ld hl, IgnoredOrdersText
+
+.Print:
+ call StdBattleTextbox
+ jp .EndDisobedience
+
+.UseInstead:
+; Can't use another move if the monster only has one!
+ ld a, [wBattleMonMoves + 1]
+ and a
+ jr z, .DoNothing
+
+; Don't bother trying to handle Disable.
+ ld a, [wDisabledMove]
+ and a
+ jr nz, .DoNothing
+
+ ld hl, wBattleMonPP
+ ld de, wBattleMonMoves
+ ld b, 0
+ ld c, NUM_MOVES
+
+.GetTotalPP:
+ ld a, [hli]
+ and PP_MASK
+ add b
+ ld b, a
+
+ dec c
+ jr z, .CheckMovePP
+
+; Stop at undefined moves.
+ inc de
+ ld a, [de]
+ and a
+ jr nz, .GetTotalPP
+
+.CheckMovePP:
+ ld hl, wBattleMonPP
+ ld a, [wCurMoveNum]
+ ld e, a
+ ld d, 0
+ add hl, de
+
+; Can't use another move if only one move has PP.
+ ld a, [hl]
+ and PP_MASK
+ cp b
+ jr z, .DoNothing
+
+; Make sure we can actually use the move once we get there.
+ ld a, 1
+ ld [wAlreadyDisobeyed], a
+
+ ld a, [w2DMenuNumRows]
+ ld b, a
+
+; Save the move we originally picked for afterward.
+ ld a, [wCurMoveNum]
+ ld c, a
+ push af
+
+.RandomMove:
+ call BattleRandom
+ maskbits NUM_MOVES
+
+ cp b
+ jr nc, .RandomMove
+
+; Not the move we were trying to use.
+ cp c
+ jr z, .RandomMove
+
+; Make sure it has PP.
+ ld [wCurMoveNum], a
+ ld hl, wBattleMonPP
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld a, [hl]
+ and PP_MASK
+ jr z, .RandomMove
+
+; Use it.
+ ld a, [wCurMoveNum]
+ ld c, a
+ ld b, 0
+ ld hl, wBattleMonMoves
+ add hl, bc
+ ld a, [hl]
+ ld [wCurPlayerMove], a
+
+ call SetPlayerTurn
+ call UpdateMoveData
+ call DoMove
+
+; Restore original move choice.
+ pop af
+ ld [wCurMoveNum], a
+
+.EndDisobedience:
+ xor a
+ ld [wLastPlayerMove], a
+ ld [wLastPlayerCounterMove], a
+
+ ; Break Encore too.
+ ld hl, wPlayerSubStatus5
+ res SUBSTATUS_ENCORED, [hl]
+ xor a
+ ld [wPlayerEncoreCount], a
+
+ jp EndMoveEffect
+
+IgnoreSleepOnly:
+ ld a, BATTLE_VARS_MOVE_ANIM
+ call GetBattleVar
+
+ ; Snore and Sleep Talk bypass sleep.
+ cp SNORE
+ jr z, .CheckSleep
+ cp SLEEP_TALK
+ jr z, .CheckSleep
+ and a
+ ret
+
+.CheckSleep:
+ ld a, BATTLE_VARS_STATUS
+ call GetBattleVar
+ and SLP
+ ret z
+
+; 'ignored orders…sleeping!'
+ ld hl, IgnoredSleepingText
+ call StdBattleTextbox
+
+ call EndMoveEffect
+
+ scf
+ ret
+
+INCLUDE "engine/battle/used_move_text.asm"
+
+BattleCommand_DoTurn:
+ call CheckUserIsCharging
+ ret nz
+
+ ld hl, wBattleMonPP
+ ld de, wPlayerSubStatus3
+ ld bc, wPlayerTurnsTaken
+
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .proceed
+
+ ld hl, wEnemyMonPP
+ ld de, wEnemySubStatus3
+ ld bc, wEnemyTurnsTaken
+
+.proceed
+
+; If we've gotten this far, this counts as a turn.
+ ld a, [bc]
+ inc a
+ ld [bc], a
+
+ ld a, BATTLE_VARS_MOVE
+ call GetBattleVar
+ cp STRUGGLE
+ ret z
+
+ ld a, [de]
+ and 1 << SUBSTATUS_IN_LOOP | 1 << SUBSTATUS_RAMPAGE | 1 << SUBSTATUS_BIDE
+ ret nz
+
+ call .consume_pp
+ ld a, b
+ and a
+ jp nz, EndMoveEffect
+
+ ; SubStatus5
+ inc de
+ inc de
+
+ ld a, [de]
+ bit SUBSTATUS_TRANSFORMED, a
+ ret nz
+
+ ldh a, [hBattleTurn]
+ and a
+
+ ld hl, wPartyMon1PP
+ ld a, [wCurBattleMon]
+ jr z, .player
+
+; mimic this part entirely if wildbattle
+ ld a, [wBattleMode]
+ dec a
+ jr z, .wild
+
+ ld hl, wOTPartyMon1PP
+ ld a, [wCurOTMon]
+
+.player
+ call GetPartyLocation
+ push hl
+ call CheckMimicUsed
+ pop hl
+ ret c
+
+.consume_pp
+ ldh a, [hBattleTurn]
+ and a
+ ld a, [wCurMoveNum]
+ jr z, .okay
+ ld a, [wCurEnemyMoveNum]
+
+.okay
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ and PP_MASK
+ jr z, .out_of_pp
+ dec [hl]
+ ld b, 0
+ ret
+
+.wild
+ ld hl, wEnemyMonMoves
+ ld a, [wCurEnemyMoveNum]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ cp MIMIC
+ jr z, .mimic
+ ld hl, wWildMonMoves
+ add hl, bc
+ ld a, [hl]
+ cp MIMIC
+ ret z
+
+.mimic
+ ld hl, wWildMonPP
+ call .consume_pp
+ ret
+
+.out_of_pp
+ call BattleCommand_MoveDelay
+; 'has no pp left for [move]'
+ ld hl, HasNoPPLeftText
+; get move effect
+ ld a, BATTLE_VARS_MOVE_EFFECT
+ call GetBattleVar
+; continuous?
+ cp EFFECT_RAZOR_WIND
+ jr z, .print
+
+ cp EFFECT_SKY_ATTACK
+ jr z, .print
+
+ cp EFFECT_SKULL_BASH
+ jr z, .print
+
+ cp EFFECT_SOLARBEAM
+ jr z, .print
+
+ cp EFFECT_FLY
+ jr z, .print
+
+ cp EFFECT_ROLLOUT
+ jr z, .print
+
+ cp EFFECT_BIDE
+ jr z, .print
+
+ cp EFFECT_RAMPAGE
+ jr z, .print
+
+; 'but no pp is left for the move'
+ ld hl, NoPPLeftText
+.print
+ call StdBattleTextbox
+ ld b, 1
+ ret
+
+CheckMimicUsed:
+ ldh a, [hBattleTurn]
+ and a
+ ld a, [wCurMoveNum]
+ jr z, .player
+ ld a, [wCurEnemyMoveNum]
+
+.player
+ ld c, a
+ ld a, MON_MOVES
+ call UserPartyAttr
+
+ ld a, BATTLE_VARS_MOVE
+ call GetBattleVar
+ cp MIMIC
+ jr z, .mimic
+;
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ cp MIMIC
+ jr nz, .mimic
+
+ scf
+ ret
+
+.mimic
+ and a
+ ret
+
+BattleCommand_Critical:
+; critical
+
+; Determine whether this attack's hit will be critical.
+
+ xor a
+ ld [wCriticalHit], a
+
+ ld a, BATTLE_VARS_MOVE_POWER
+ call GetBattleVar
+ and a
+ ret z
+
+ ldh a, [hBattleTurn]
+ and a
+ ld hl, wEnemyMonItem
+ ld a, [wEnemyMonSpecies]
+ jr nz, .Item
+ ld hl, wBattleMonItem
+ ld a, [wBattleMonSpecies]
+
+.Item:
+ ld c, 0
+
+ cp CHANSEY
+ jr nz, .Farfetchd
+ ld a, [hl]
+ cp LUCKY_PUNCH
+ jr nz, .FocusEnergy
+
+; +2 critical level
+ ld c, 2
+ jr .Tally
+
+.Farfetchd:
+ cp FARFETCH_D
+ jr nz, .FocusEnergy
+ ld a, [hl]
+ cp STICK
+ jr nz, .FocusEnergy
+
+; +2 critical level
+ ld c, 2
+ jr .Tally
+
+.FocusEnergy:
+ ld a, BATTLE_VARS_SUBSTATUS4
+ call GetBattleVar
+ bit SUBSTATUS_FOCUS_ENERGY, a
+ jr z, .CheckCritical
+
+; +1 critical level
+ inc c
+
+.CheckCritical:
+ ld a, BATTLE_VARS_MOVE_ANIM
+ call GetBattleVar
+ ld de, 1
+ ld hl, CriticalHitMoves
+ push bc
+ call IsInArray
+ pop bc
+ jr nc, .ScopeLens
+
+; +2 critical level
+ inc c
+ inc c
+
+.ScopeLens:
+ push bc
+ call GetUserItem
+ ld a, b
+ cp HELD_CRITICAL_UP ; Increased critical chance. Only Scope Lens has this.
+ pop bc
+ jr nz, .Tally
+
+; +1 critical level
+ inc c
+
+.Tally:
+ ld hl, CriticalHitChances
+ ld b, 0
+ add hl, bc
+ call BattleRandom
+ cp [hl]
+ ret nc
+ ld a, 1
+ ld [wCriticalHit], a
+ ret
+
+INCLUDE "data/moves/critical_hit_moves.asm"
+
+INCLUDE "data/battle/critical_hit_chances.asm"
+
+INCLUDE "engine/battle/move_effects/triple_kick.asm"
diff --git a/engine/battle/move_effects/triple_kick.asm b/engine/battle/move_effects/triple_kick.asm
new file mode 100644
index 00000000..e41044c9
--- /dev/null
+++ b/engine/battle/move_effects/triple_kick.asm
@@ -0,0 +1,34 @@
+BattleCommand_TripleKick:
+; triplekick
+
+ ld a, [wKickCounter]
+ ld b, a
+ inc b
+ ld hl, wCurDamage + 1
+ ld a, [hld]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+.next_kick
+ dec b
+ ret z
+ ld a, [hl]
+ add e
+ ld [hld], a
+ ld a, [hl]
+ adc d
+ ld [hli], a
+
+; No overflow.
+ jr nc, .next_kick
+ ld a, $ff
+ ld [hld], a
+ ld [hl], a
+ ret
+
+BattleCommand_KickCounter:
+; kickcounter
+
+ ld hl, wKickCounter
+ inc [hl]
+ ret
diff --git a/engine/battle/used_move_text.asm b/engine/battle/used_move_text.asm
new file mode 100644
index 00000000..5b148ab5
--- /dev/null
+++ b/engine/battle/used_move_text.asm
@@ -0,0 +1,235 @@
+BattleCommand_UsedMoveText:
+; battle command 03
+ ld hl, UsedMoveText
+ call PrintText
+ jp WaitBGMap
+
+UsedMoveText:
+; this is a stream of text and asm from 105db9 to 105ef6
+ text_far _ActorNameText
+ text_asm
+ ldh a, [hBattleTurn]
+ and a
+ jr nz, .start
+
+ ld a, [wPlayerMoveStruct + MOVE_ANIM]
+ call UpdateUsedMoves
+
+.start
+ ld a, BATTLE_VARS_LAST_MOVE
+ call GetBattleVarAddr
+ ld d, h
+ ld e, l
+
+ ld a, BATTLE_VARS_LAST_COUNTER_MOVE
+ call GetBattleVarAddr
+
+ ld a, BATTLE_VARS_MOVE_ANIM
+ call GetBattleVar
+ ld [wMoveGrammar], a
+
+ call CheckUserIsCharging
+ jr nz, .grammar
+
+ ; update last move
+ ld a, [wMoveGrammar]
+ ld [hl], a
+ ld [de], a
+
+.grammar
+ call GetMoveGrammar ; convert move id to grammar index
+
+; everything except 'CheckObedience' made redundant in localization
+
+ ; check obedience
+ ld a, [wAlreadyDisobeyed]
+ and a
+ ld hl, UsedMove2Text
+ ret nz
+
+ ; check move grammar
+ ld a, [wMoveGrammar]
+ cp $3
+ ld hl, UsedMove2Text
+ ret c
+ ld hl, UsedMove1Text
+ ret
+
+UsedMove1Text:
+ text_far _UsedMove1Text
+ text_asm
+ jr UsedMoveText_CheckObedience
+
+UsedMove2Text:
+ text_far _UsedMove2Text
+ text_asm
+UsedMoveText_CheckObedience:
+; check obedience
+ ld a, [wAlreadyDisobeyed]
+ and a
+ jr z, .GetMoveNameText
+; print "instead,"
+ ld hl, .UsedInsteadText
+ ret
+
+.UsedInsteadText:
+ text_far _UsedInsteadText
+ text_asm
+.GetMoveNameText:
+ ld hl, MoveNameText
+ ret
+
+MoveNameText:
+ text_far _MoveNameText
+ text_asm
+; get start address
+ ld hl, .endusedmovetexts
+
+; get move id
+ ld a, [wMoveGrammar]
+
+; 2-byte pointer
+ add a
+
+; seek
+ push bc
+ ld b, 0
+ ld c, a
+ add hl, bc
+ pop bc
+
+; get pointer to usedmovetext ender
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ret
+
+.endusedmovetexts
+; entries correspond to MoveGrammar sets
+ dw EndUsedMove1Text
+ dw EndUsedMove2Text
+ dw EndUsedMove3Text
+ dw EndUsedMove4Text
+ dw EndUsedMove5Text
+
+EndUsedMove1Text:
+ text_far _EndUsedMove1Text
+ text_end
+
+EndUsedMove2Text:
+ text_far _EndUsedMove2Text
+ text_end
+
+EndUsedMove3Text:
+ text_far _EndUsedMove3Text
+ text_end
+
+EndUsedMove4Text:
+ text_far _EndUsedMove4Text
+ text_end
+
+EndUsedMove5Text:
+ text_far _EndUsedMove5Text
+ text_end
+
+GetMoveGrammar:
+; store move grammar type in wMoveGrammar
+
+ push bc
+; wMoveGrammar contains move id
+ ld a, [wMoveGrammar]
+ ld c, a ; move id
+ ld b, 0 ; grammar index
+
+; read grammar table
+ ld hl, MoveGrammar
+.loop
+ ld a, [hli]
+; end of table?
+ cp -1
+ jr z, .end
+; match?
+ cp c
+ jr z, .end
+; advance grammar type at 0
+ and a
+ jr nz, .loop
+; next grammar type
+ inc b
+ jr .loop
+
+.end
+; wMoveGrammar now contains move grammar
+ ld a, b
+ ld [wMoveGrammar], a
+
+; we're done
+ pop bc
+ ret
+
+INCLUDE "data/moves/grammar.asm"
+
+CheckUserIsCharging:
+ ldh a, [hBattleTurn]
+ and a
+ ld a, [wPlayerCharging] ; player
+ jr z, .end
+ ld a, [wEnemyCharging] ; enemy
+.end
+ and a
+ ret
+
+UpdateUsedMoves:
+; append move a to wPlayerUsedMoves unless it has already been used
+
+ push bc
+; start of list
+ ld hl, wPlayerUsedMoves
+; get move id
+ ld b, a
+; next count
+ ld c, NUM_MOVES
+
+.loop
+; get move from the list
+ ld a, [hli]
+; not used yet?
+ and a
+ jr z, .add
+; already used?
+ cp b
+ jr z, .quit
+; next byte
+ dec c
+ jr nz, .loop
+
+; if the list is full and the move hasn't already been used
+; shift the list back one byte, deleting the first move used
+; this can occur with struggle or a new learned move
+ ld hl, wPlayerUsedMoves + 1
+; 1 = 2
+ ld a, [hld]
+ ld [hli], a
+; 2 = 3
+ inc hl
+ ld a, [hld]
+ ld [hli], a
+; 3 = 4
+ inc hl
+ ld a, [hld]
+ ld [hl], a
+; 4 = new move
+ ld a, b
+ ld [wPlayerUsedMoves + 3], a
+ jr .quit
+
+.add
+; go back to the byte we just inced from
+ dec hl
+; add the new move
+ ld [hl], b
+
+.quit
+; list updated
+ pop bc
+ ret
diff --git a/engine/items/item_effects.asm b/engine/items/item_effects.asm
index f50f7fda..8d694eac 100755
--- a/engine/items/item_effects.asm
+++ b/engine/items/item_effects.asm
@@ -387,7 +387,7 @@ UltraBall: ; e926
jr c, .asm_ea34
ld a, $5
.asm_ea34
- ld [wcb67], a
+ ld [wBattleAnimParam], a
ld de, ANIM_THROW_POKE_BALL
ld a, e
ld [wcf3e], a
@@ -396,7 +396,7 @@ UltraBall: ; e926
xor a
ldh [hBattleTurn], a
ld [wBuffer2], a
- ld [wcf46], a
+ ld [wNumHits], a
predef PlayBattleAnim
ld a, [wWildMon]
and a
@@ -2018,8 +2018,8 @@ XSpeed: ; f515
ld b, [hl]
xor a
ldh [hBattleTurn], a
- ld [wcb45], a
- ld [wcbeb], a
+ ld [wAttackMissed], a
+ ld [wEffectFailed], a
farcall RaiseStat
call WaitSFX
farcall BattleCommand_StatUpMessage
@@ -2178,10 +2178,10 @@ PPUp: ; f606 (3:7606)
ld hl, Text_RestoreThePPOfWhichMove
.asm_f62e
call PrintText
- ld a, [wcfc7]
+ ld a, [wCurMoveNum]
push af
xor a
- ld [wcfc7], a
+ ld [wCurMoveNum], a
ld a, $2
ld [wd11f], a
ld a, $f
@@ -2189,7 +2189,7 @@ PPUp: ; f606 (3:7606)
rst FarCall
pop bc
ld a, b
- ld [wcfc7], a
+ ld [wCurMoveNum], a
jr nz, .asm_f60c
ld hl, wPartyMon1Moves
ld bc, $30
@@ -2541,9 +2541,9 @@ Functionf7e7: ; f7e7 (3:77e7)
ld a, d
ld [wcf3f], a
xor a
- ld [wcb67], a
+ ld [wBattleAnimParam], a
ldh [hBattleTurn], a
- ld [wcf46], a
+ ld [wNumHits], a
predef PlayBattleAnim
ld hl, Text_BlockedTheBall
call PrintText
diff --git a/main.asm b/main.asm
index b58c5d65..010e79b4 100644
--- a/main.asm
+++ b/main.asm
@@ -275,8 +275,10 @@ PrintMoveDesc::
SECTION "bankc", ROMX
dr $30000, $33d81
-SECTION "bankd", ROMX
- dr $34000, $34822
+
+SECTION "Effect Commands", ROMX
+
+INCLUDE "engine/battle/effect_commands.asm"
BattleCommand_Stab:
dr $34822, $34918
BattleCheckTypeMatchup::
@@ -284,14 +286,34 @@ BattleCheckTypeMatchup::
CheckTypeMatchup::
dr $34923, $3499e
INCLUDE "engine/battle/ai/switch.asm"
- dr $34d01, $3553d
-
+ dr $34d01, $3503e
+
+BattleCommand_LowerSub:
+ dr $3503e, $3514e
+BattleCommand_SwitchTurn:
+ dr $3514e, $35155
+BattleCommand_RaiseSub:
+ dr $35155, $353f5
+EndMoveEffect:
+ dr $353f5, $3553d
EnemyAttackDamage::
- dr $3553d, $35753
+ dr $3553d, $3571e
+HitSelfInConfusion:
+ dr $3571e, $35753
BattleCommand_DamageCalc::
dr $35753, $35868
BattleCommand_ConstantDamage::
- dr $35868, $36313
+ dr $35868, $35e3c
+FarPlayBattleAnimation:
+ dr $35e3c, $35e44
+PlayFXAnimID:
+ dr $35e44, $35e58
+DoEnemyDamage:
+ dr $35e58, $35eba
+DoPlayerDamage:
+ dr $35eba, $35f7c
+UpdateMoveData:
+ dr $35f7c, $36313
RaiseStat:
dr $36313, $364d7
@@ -300,25 +322,37 @@ BattleCommand_StatUpMessage:
BattleCommand_StatUpFailText:
dr $3656b, $366f6
CalcPlayerStats:
- dr $366f6, $378f4
+ dr $366f6, $378bd
+ResetFuryCutterCount:
+ dr $378bd, $378f4
CheckOppositeGender:
- dr $378f4, $37e9b
+ dr $378f4, $37e7d
+GetUserItem:
+ dr $37e7d, $37e9b
GetItemHeldEffect:
- dr $37e9b, $37f6c
+ dr $37e9b, $37f3e
+CallBattleCore:
+ dr $37f3e, $37f4b
+BattleCommand_MoveDelay:
+ dr $37f4b, $37f6c
GetMoveAttr:
dr $37f6c, $37f86
GetMoveByte:
- dr $37f86, $37fa0
+ dr $37f86, $37f99
+AppearUserRaiseSub:
+ dr $37f99, $37fa0
-SECTION "banke", ROMX
+
+SECTION "Enemy Trainers", ROMX
INCLUDE "engine/battle/ai/items.asm"
INCLUDE "engine/battle/ai/scoring.asm"
INCLUDE "engine/battle/read_trainer_attributes.asm"
INCLUDE "engine/battle/read_trainer_party.asm"
-SECTION "bankf", ROMX
+
+SECTION "Battle Core", ROMX
dr $3c000, $3c551
FleeMons::
dr $3c551, $3d39f
@@ -360,7 +394,9 @@ GetEnemyMonFrontpic::
StartBattle::
dr $3f2c7, $3f55d
Function3f55d:
- dr $3f55d, $3fe9b
+ dr $3f55d, $3fd3d
+BattleCommandPointers:
+ dr $3fd3d, $3fe9b
SECTION "bank10", ROMX
diff --git a/pokegold.link b/pokegold.link
index 159bac95..ecbf1577 100644
--- a/pokegold.link
+++ b/pokegold.link
@@ -63,14 +63,11 @@ ROMX $0c
org $4000
"bankc"
ROMX $0d
- org $4000
- "bankd"
+ "Effect Commands"
ROMX $0e
- org $4000
- "banke"
+ "Enemy Trainers"
ROMX $0f
- org $4000
- "bankf"
+ "Battle Core"
ROMX $10
org $4000
"bank10"
diff --git a/pokesilver.link b/pokesilver.link
index 159bac95..ecbf1577 100644
--- a/pokesilver.link
+++ b/pokesilver.link
@@ -63,14 +63,11 @@ ROMX $0c
org $4000
"bankc"
ROMX $0d
- org $4000
- "bankd"
+ "Effect Commands"
ROMX $0e
- org $4000
- "banke"
+ "Enemy Trainers"
ROMX $0f
- org $4000
- "bankf"
+ "Battle Core"
ROMX $10
org $4000
"bank10"
diff --git a/wram.asm b/wram.asm
index 4f28ee6e..f9feb64b 100644
--- a/wram.asm
+++ b/wram.asm
@@ -1677,9 +1677,9 @@ wcb3f:: ds 1 ; cb3f
wcb40:: ds 1 ; cb40
wCurOTMon:: ds 1 ; cb41
wcb42:: ds 1 ; cb42
-wcb43:: ds 1 ; cb43
-wcb44:: ds 1 ; cb44
-wcb45:: ds 1 ; cb45
+wTypeModifier:: db ; cb43
+wCriticalHit:: db ; cb44
+wAttackMissed:: db ; cb45
wPlayerSubStatus1:: ds 1 ; cb46
wPlayerSubStatus2:: ds 1 ; cb47
wPlayerSubStatus3:: ds 1 ; cb48
@@ -1691,17 +1691,17 @@ wEnemySubStatus3:: ds 1 ; cb4d
wEnemySubStatus4:: ds 1 ; cb4e
wEnemySubStatus5:: ds 1 ; cb4f
wPlayerRolloutCount:: db ; cb50
-wcb51:: ds 1 ; cb51
+wPlayerConfuseCount:: db ; cb51
wcb52:: ds 1 ; cb52
wPlayerDisableCount:: db ; cb53
-wcb54:: ds 1 ; cb54
+wPlayerEncoreCount:: db ; cb54
wcb55:: ds 1 ; cb55
wPlayerFuryCutterCount:: db ; cb56
wcb57:: ds 1 ; cb57
wcb58:: ds 1 ; cb58
wEnemyConfuseCount:: db ; cb59
wEnemyToxicCount:: db ; cb5a
-wcb5b:: ds 1 ; cb5b
+wEnemyDisableCount:: db ; cb5b
wcb5c:: ds 1 ; cb5c
wEnemyPerishCount:: db ; cb5d
wEnemyFuryCutterCount:: db ; cb5e
@@ -1716,8 +1716,10 @@ wBattleReward::
wcb64:: ds 1 ; cb64
wcb65:: ds 1 ; cb65
wcb66:: ds 1 ; cb66
-wcb67:: ds 1 ; cb67
-wcb68:: ds 1 ; cb68
+wKickCounter:: ; cb67
+wBattleAnimParam::
+ db
+wBattleScriptBuffer:: db ; cb68
wcb69:: ds 1 ; cb69
wcb6a:: ds 1 ; cb6a
wcb6b:: ds 1 ; cb6b
@@ -1757,9 +1759,8 @@ wcb8c:: ds 1 ; cb8c
wcb8d:: ds 1 ; cb8d
wcb8e:: ds 1 ; cb8e
wcb8f:: ds 1 ; cb8f
-wcb90:: ds 1 ; cb90
-wcb91:: ds 1 ; cb91
-wcb92:: ds 1 ; cb92
+wBattleScriptBufferAddress:: dw ; cb90
+wTurnEnded:: db ; cb92
wcb93:: ds 1 ; cb93
wcb94:: ds 1 ; cb94
wcb95:: ds 1 ; cb95
@@ -1822,7 +1823,7 @@ wcbce:: ds 1 ; cbce
wcbcf:: ds 1 ; cbcf
wcbd0:: ds 1 ; cbd0
wcbd1:: ds 1 ; cbd1
-wcbd2:: ds 1 ; cbd2
+wAlreadyDisobeyed:: db ; cbd2
wDisabledMove:: db ; cbd3
wEnemyDisabledMove:: db ; cbd4
wcbd5:: ds 1 ; cbd5
@@ -1832,7 +1833,7 @@ wLastPlayerCounterMove:: db ; cbd6
wLastEnemyCounterMove:: db ; cbd7
wcbd8:: ds 1 ; cbd8
-wcbd9:: ds 1 ; cbd9
+wAlreadyFailed:: db ; cbd9
wcbda:: ds 1 ; cbda
wcbdb:: ds 1 ; cbdb
wPlayerMinimized:: db ; cbdc
@@ -1850,7 +1851,7 @@ wcbe7:: ds 1 ; cbe7
wBattleWeather:: db ; cbe8
wcbe9:: ds 1 ; cbe9
wcbea:: ds 1 ; cbea
-wcbeb:: ds 1 ; cbeb
+wEffectFailed:: db ; cbeb
wcbec:: ds 1 ; cbec
wEnemyGoesFirst:: db ; cbed
wcbee:: ds 1 ; cbee
@@ -1888,8 +1889,8 @@ wcc0c:: ds 1 ; cc0c
wcc0d:: ds 1 ; cc0d
wPlayerWrapCount:: db ; cc0e
wEnemyWrapCount:: db ; cc0f
-wcc10:: ds 1 ; cc10
-wcc11:: ds 1 ; cc11
+wPlayerCharging:: db ; cc10
+wEnemyCharging:: db ; cc11
wcc12:: ds 1 ; cc12
wWildMonMoves:: ds 1 ; cc13
wOverworldMapEnd::
@@ -1897,7 +1898,7 @@ wOverworldMapEnd::
wWildMonPP:: ds NUM_MOVES ; cc17
wcc1b:: ds 1 ; cc1b
-wcc1c:: ds 1 ; cc1c
+wSomeoneIsRampaging:: db ; cc1c
wcc1d:: ds 1 ; cc1d
wcc1e:: ds 1 ; cc1e
wcc1f:: ds 1 ; cc1f
@@ -2110,8 +2111,10 @@ wce4d:: ds 1 ; ce4d
wce4e:: ds 1 ; ce4e
wce4f:: ds 1 ; ce4f
wce50:: ds 1 ; ce50
-wOtherPlayerLinkMode:: ds 1 ; ce51
-wOtherPlayerLinkAction:: ds 1 ; ce52
+wOtherPlayerLinkMode:: db ; ce51
+wOtherPlayerLinkAction:: ; ce52
+wBattleAction::
+ db
wce53:: ds 1 ; ce53
wce54:: ds 1 ; ce54
wce55:: ds 1 ; ce55
@@ -2497,7 +2500,7 @@ wcf42:: ds 1 ; cf42
wBGP:: ds 1
wOBP0:: ds 1
wOPB1:: ds 1
-wcf46:: ds 1 ; cf46
+wNumHits:: db ; cf46
wcf47:: ds 1 ; cf47
wMonOrItemNameBuffer:: ds 1 ; cf48
wcf49:: ds 1 ; cf49
@@ -2545,8 +2548,8 @@ wStringBuffer5:: ds 19 ; cfb7
NEXTU
ds 13
wBattleMenuCursorBuffer:: dw ; cfc4
-wCurBattleMon:: ds 1 ; cfc6
-wcfc7:: ds 1 ; cfc7
+wCurBattleMon:: db ; cfc6
+wCurMoveNum:: db; cfc7
wcfc8:: ds 1 ; cfc8
wPartyMenuCursor:: ds 1 ; cfc9
ENDU
@@ -2582,6 +2585,7 @@ wNumMoves:: ds 1 ; cfe3
wFieldMoveSucceeded::
wItemEffectSucceeded::
+wBattlePlayerAction::
db ; cfe4
wVramState:: ds 1