-
Notifications
You must be signed in to change notification settings - Fork 93
Adjust Weakness and Resistance Modifiers
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.
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
...
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.