I said a few days ago that I was tinkering with the disassembly project for gen 1, and from time to time I come across beautiful stuff I previously had never read about.
The finding of the day is the bit of code that checks if a move is super effective and if the move has STAB, to be more specific, the beginning of the routine, which looks like this1:
; function to adjust the base damage of an attack to account for type effectiveness
AdjustDamageForMoveType:
; values for player turn
ld hl, wBattleMonType
ld a, [hli]
ld b, a ; b = type 1 of attacker
ld c, [hl] ; c = type 2 of attacker
ld hl, wEnemyMonType
ld a, [hli]
ld d, a ; d = type 1 of defender
ld e, [hl] ; e = type 2 of defender
ld a, [wPlayerMoveType]
ld [wMoveType], a
ldh a, [hWhoseTurn]
and a
jr z, .next
; values for enemy turn
ld hl, wEnemyMonType
ld a, [hli]
ld b, a ; b = type 1 of attacker
ld c, [hl] ; c = type 2 of attacker
ld hl, wBattleMonType
ld a, [hli]
ld d, a ; d = type 1 of defender
ld e, [hl] ; e = type 2 of defender
ld a, [wEnemyMoveType]
ld [wMoveType], a
.next
; [...]
If you're not familiar with assembly code for the GameBoy, here's a rough pseudocode translation:
AdjustDamageForMoveType(){
var attackerType1 = player'sMonType1
var attackerType2 = player'sMonType2
var defenderType1 = enemy'sMonType1
var defenderType2 = enemy'sMonType2
var attackType = player'sAttackType
if (currentTurn == enemy'sTurn){
attackerType1 = enemy'sMonType1
attackerType2 = enemy'sMonType2
defenderType1 = player'sMonType1
defenderType2 = player'sMonType2
attackType = enemy'sAttackType
}
// [...]
}
Yes. The game is loading into the 5 different registers your types, the enemy's and your move's; and then it checks for whether it is even your turn to begin with. And if it is not, it loads them again in the correct order (alongside the correct type for the move). From memory. Instead of, you know, checking whose turn it is before doing anything so that the game doesn't waste 20 CPU cycles2 half of the times it checks for the damage calculation.
I know this is extremely far from this game's biggest coding sin, I just happened to come across the function while trying to implement a half-assed Tera Blast (where the move's type becomes your primary type), and found it hilarious.
-
https://github.com/pret/pokered/blob/master/engine/battle/core.asm#L5200
-
0.00476 milliseconds
