diff --git a/constants/trainer_data_constants.asm b/constants/trainer_data_constants.asm index 1bbd3d6d3..2d80dacce 100644 --- a/constants/trainer_data_constants.asm +++ b/constants/trainer_data_constants.asm @@ -44,6 +44,7 @@ DEF CONTEXT_USE EQU 1 << CONTEXT_USE_F const TRAINERTYPE_MOVES_F ; 0 const TRAINERTYPE_ITEM_F ; 1 const TRAINERTYPE_VARIABLE_F ; 3 + const TRAINERTYPE_DVS_F ; 4 ; Trainer party types (see data/trainers/parties.asm) DEF TRAINERTYPE_NORMAL EQU 0 @@ -51,4 +52,7 @@ DEF TRAINERTYPE_MOVES EQU 1 << TRAINERTYPE_MOVES_F DEF TRAINERTYPE_ITEM EQU 1 << TRAINERTYPE_ITEM_F DEF TRAINERTYPE_ITEM_MOVES EQU TRAINERTYPE_MOVES | TRAINERTYPE_ITEM DEF TRAINERTYPE_VARIABLE EQU 1 << TRAINERTYPE_VARIABLE_F +DEF TRAINERTYPE_DVS EQU 1 << TRAINERTYPE_DVS_F + +DEF PERFECT_DV EQU $11 ; treated as $FF in enemy party data diff --git a/data/trainers/parties.asm b/data/trainers/parties.asm index 5753e401c..696a24fdc 100644 --- a/data/trainers/parties.asm +++ b/data/trainers/parties.asm @@ -41,13 +41,13 @@ FalknerGroup: db $fe ; delimiter ;Challenge Mode - db TRAINERTYPE_ITEM | TRAINERTYPE_MOVES - db 68, NOCTOWL, QUICK_CLAW, NIGHTMARE, HYPNOSIS, SHADOW_BALL, WING_ATTACK - db 70, TOGETIC, BRIGHTPOWDER, SWEET_KISS, TRI_ATTACK, SUBSTITUTE, BATON_PASS - db 72, FEAROW, FOCUS_BAND, DRILL_PECK, HYPER_BEAM, MUD_SLAP, SWAGGER - db 72, XATU, LUM_BERRY, GIGA_DRAIN, PSYCHIC_M, MUD_SLAP, THUNDER_WAVE - db 74, DODRIO, SCOPE_LENS, TRI_ATTACK, DRILL_PECK, JUMP_KICK, SWORDS_DANCE - db 76, PIDGEOT, SITRUS_BERRY, DOUBLE_EDGE, MUD_SLAP, SKY_ATTACK, STEEL_WING + db TRAINERTYPE_DVS | TRAINERTYPE_ITEM | TRAINERTYPE_MOVES + db 68, NOCTOWL, $fe, $ff, QUICK_CLAW, HIDDEN_POWER, NO_MOVE, NO_MOVE, NO_MOVE + db 70, TOGETIC, $ff, $ff, BRIGHTPOWDER, SWEET_KISS, TRI_ATTACK, SUBSTITUTE, BATON_PASS + db 72, FEAROW, $ff, $ff, FOCUS_BAND, DRILL_PECK, HYPER_BEAM, MUD_SLAP, SWAGGER + db 72, XATU, $ff, $ff, LUM_BERRY, GIGA_DRAIN, PSYCHIC_M, MUD_SLAP, THUNDER_WAVE + db 74, DODRIO, $ff, $ff, SCOPE_LENS, TRI_ATTACK, DRILL_PECK, JUMP_KICK, SWORDS_DANCE + db 76, PIDGEOT, $ff, $ff, SITRUS_BERRY, DOUBLE_EDGE, MUD_SLAP, SKY_ATTACK, STEEL_WING db -1 ; end diff --git a/engine/battle/core.asm b/engine/battle/core.asm index b9eb73a81..91b213db1 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -6383,16 +6383,20 @@ LoadEnemyMon: jp .Happiness .InitDVs: -; Trainer DVs - -; All trainers have preset DVs, determined by class -; See GetTrainerDVs for more on that - farcall GetTrainerDVs -; These are the DVs we'll use if we're actually in a trainer battle ld a, [wBattleMode] dec a - jr nz, .UpdateDVs + jr z, .WildDVs + +; Trainer DVs + ld a, [wCurPartyMon] + ld hl, wOTPartyMon1DVs + call GetPartyLocation + ld b, [hl] + inc hl + ld c, [hl] + jr .UpdateDVs +.WildDVs: ; Wild DVs ; Here's where the fun starts diff --git a/engine/battle/read_trainer_party.asm b/engine/battle/read_trainer_party.asm index 4398ea4f1..b9aad8cbc 100644 --- a/engine/battle/read_trainer_party.asm +++ b/engine/battle/read_trainer_party.asm @@ -120,6 +120,36 @@ ReadTrainerPartyPieces: predef TryAddMonToParty pop hl +; dvs? + ld a, [wOtherTrainerType] + bit TRAINERTYPE_DVS_F, a + jr z, .no_dvs + + push hl + ld a, [wOTPartyCount] + dec a + ld hl, wOTPartyMon1DVs + call GetPartyLocation + ld d, h + ld e, l + pop hl + +; When reading DVs, treat PERFECT_DV as $ff + ld a, [hli] + cp PERFECT_DV + jr nz, .atk_def_dv_nonzero + ld a, $ff +.atk_def_dv_nonzero + ld [de], a + inc de + ld a, [hli] + cp PERFECT_DV + jr nz, .spd_spc_dv_nonzero + ld a, $ff +.spd_spc_dv_nonzero + ld [de], a +.no_dvs + ; item? ld a, [wOtherTrainerType] bit TRAINERTYPE_ITEM_F, a @@ -202,6 +232,44 @@ ReadTrainerPartyPieces: pop hl .no_moves +; Custom DVs affect stats, so recalculate them after TryAddMonToParty + ld a, [wOtherTrainerType] + and TRAINERTYPE_DVS + jr z, .no_stat_recalc + + push hl + + ld a, [wOTPartyCount] + dec a + ld hl, wOTPartyMon1MaxHP + call GetPartyLocation + ld d, h + ld e, l + + ld a, [wOTPartyCount] + dec a + ld hl, wOTPartyMon1StatExp - 1 + call GetPartyLocation + +; recalculate stats + ld b, TRUE + push de + predef CalcMonStats + pop hl + +; copy max HP to current HP + inc hl + ld c, [hl] + dec hl + ld b, [hl] + dec hl + ld [hl], c + dec hl + ld [hl], b + + pop hl +.no_stat_recalc + jp .loop ComputeTrainerReward: diff --git a/engine/overworld/wildmons.asm b/engine/overworld/wildmons.asm index dcdc63cc8..2e91441f0 100644 --- a/engine/overworld/wildmons.asm +++ b/engine/overworld/wildmons.asm @@ -1076,6 +1076,12 @@ RandomPhoneMon: ; c = mon length ; All trainers use 2 bytes for level and species ld c, 2 +; TRAINERTYPE_DVS uses 2 more bytes + bit TRAINERTYPE_DVS_F, b + jr z, .no_dvs + inc c + inc c +.no_dvs ; TRAINERTYPE_ITEM uses 1 more byte bit TRAINERTYPE_ITEM_F, b jr z, .no_item