Table of Contents
This tutorial will demonstrate how to make all Weakness values "+20" instead of "x2" and all Resistance values "-20" instead of "-30". Neither Weakness nor Resistance has been constant throughout the course of the Pokémon Trading Card Game, and for a significant portion of the game, Resistance was reduced from "-30" to "-20". If you are designing a game based around a different era of the TCG, or if you simply wish to have the game be less subject to completely one-sided matches, you may wish to adjust the modifiers for Weakness and/or Resistance. Fortunately, this isn't a difficult change to make.
Contents
1. Editing the Main Damage Calculation Functions
Weakness and Resistance is actually applied during one of two functions, both of which can be found in src/home/duel.asm. (Except in poketcg_v2, where ApplyDamageModifiers_DamageToTarget was moved to src/engine/duel/core.asm.) Weakness is calculated in the original game by shifting all of the bits in the damage value to the left. Since each bit is one power of 2 higher than the previous one, this is an easy way to double the damage value. For example, converting 30 to binary gives you %00011110, converting 60 gives you %00111100, and converting 120 gives you %01111000. Resistance is a little easier to understand, as it simply adds "-30" to the amount of damage being done; in algebra, this is equivalent to subtracting 30. In all of the functions that we will be updating, we'll change the -30 in the Resistance sections to -20, and the Weakness instructions will be replaced with a copy of the original Resistance instructions (substituting -30 with 20).
Let's start off by applying the aforementioned changes to ApplyDamageModifiers_DamageToTarget.
ApplyDamageModifiers_DamageToTarget::
...
and b
jr z, .not_weak
- sla e
- rl d
+ ld hl, 20
+ add hl, de
+ ld e, l
+ ld d, h
ld hl, wDamageEffectiveness
set WEAKNESS, [hl]
.not_weak
call SwapTurn
call GetArenaCardResistance
call SwapTurn
and b
jr z, .check_pluspower_and_defender ; jump if not resistant
- ld hl, -30
+ ld hl, -20
add hl, de
ld e, l
ld d, h
...
Then, scroll down, and apply those changes to ApplyDamageModifiers_DamageToSelf.
ApplyDamageModifiers_DamageToSelf::
...
and b
jr z, .not_weak
- sla e
- rl d
+ ld hl, 20
+ add hl, de
+ ld e, l
+ ld d, h
ld hl, wDamageEffectiveness
set WEAKNESS, [hl]
.not_weak
call GetArenaCardResistance
and b
jr z, .not_resistant
- ld hl, -30
+ ld hl, -20
add hl, de
ld e, l
ld d, h
...
2. Updating the AI Logic
The game will run with just the first step completed, but the AI still assumes that Weakness is x2 and Resistance is -30. We should fix that if we want the computer opponents to make sensible decisions.
Begin by opening src/engine/duel/ai/damage_calculation.asm, and apply the changes from Step 1 to CalculateDamage_VersusDefendingPokemon.
CalculateDamage_VersusDefendingPokemon:
...
jr z, .not_weak
; double de
- sla e
- rl d
+ ld hl, 20
+ add hl, de
+ ld e, l
+ ld d, h
.not_weak
; handle resistance
call SwapTurn
call GetArenaCardResistance
call SwapTurn
and b
jr z, .not_resistant
- ld hl, -30
+ ld hl, -20
add hl, de
ld e, l
ld d, h
...
Then, scroll down to CalculateDamage_FromDefendingPokemon and repeat.
CalculateDamage_FromDefendingPokemon:
...
jr z, .not_weak
; double de
- sla e
- rl d
+ ld hl, 20
+ add hl, de
+ ld e, l
+ ld d, h
.not_weak
; handle resistance
...
and b
jr z, .not_resistant
- ld hl, -30
+ ld hl, -20
add hl, de
ld e, l
ld d, h
...
While there isn't a dedicated AI function for estimating recoil damage being done to the Attacking Pokémon, there is still a small calculation that is made during AIDecide_Defender2 (AIDecide_Defender_Phase14 in poketcg_v2), so open src/engine/duel/ai/trainer_cards.asm and scroll down to the relevant function. The actual code is a little different because it's handling all of the math with 8-bit registers (rather than 16-bit register pairs), but it works more or less the same way as the previous functions.
AIDecide_Defender2:
...
and b
pop de
jr z, .check_resist
- sla d
+ ld a, d
+ add 20
+ ld d, a
; subtract 30 from recoil damage if card resists its own color.
; if this yields a negative number, return no carry.
.check_resist
push de
call GetArenaCardColor
call TranslateColorToWR
ld b, a
call GetArenaCardResistance
and b
pop de
jr z, .subtract
ld a, d
- sub 30
+ sub 20
jr c, .no_carry
ld d, a
...
That completes all of the changes that will need to be made to the game's engine, but you might also want to search the game's text files (found in src/text) for "Weakness" and/or "Resistance" and update any references to the old modifiers.