kep-hack/scripts/BattleTent.asm
Martha Schilling ef62d0a43f would you believe me if i told you this still isnt done
in the middle of a breakdown here but i'm committing this because I don't wanna have an overwhelming number of changed files like the Big One

- Fixed a bug where an item couldn't be picked up in Mt. Moon Crater

- Gave new cries to Leafeon, Glaceon, Perrserker, Gentlarva, Carapthor, Gorotora, Magnezone, Tangrowth, Tricules, Magmortar and Meltan. Pupal and Lickilicky also got new cries but they'll probably be changed later

- Changed Citrine's map slightly for hopefully the final time, removing the tall grass to allow the Old Man Glitch to work there

- Brought Pokemon Tower 5F back for some reason

- Moved the Rocket Grunt on Silph 11F closer to the Omegadge door

- 'Fixed' a warp issue on Faraway Island, can definitely be improved though

- Gave Gapdos 10 more base special because i forgot the first time

- Fixed a typo in Hitmontop's dex entry

- Fixed some inconsistencies in Gao and Gorotora's movesets

- Added the unused ice tiles to Seafoam Islands and Garnet Cavern (credit to Vortiene)

- Added a stats page to the Pokedex that displays base stats and the type of caught Pokemon (again, credit to Vortiene)

- Made Sandshrew more common in Mt. Moon

- Improved the 'already caught' icon

- uncapitalised all new instances of "trainer" in the text to make it more consistent

- HOPEFULLY fixed the issue where the SS Anne still couldn't be reboarded
2023-11-20 11:00:20 +00:00

855 lines
15 KiB
NASM

; This is a port of the Battle Tent from TPP Anniversary.
; Specifically, the version from here: https://github.com/CameruptQDX/PF-Roaming-Red/
; For KEP, we use the Trainers aren't Pokemon implementation from pret's tutorial, but the original Battle Tent didn't, as it didn't add any new Pokemon beyond 190. Because of this, we have to have a scripted loss script in engine/core's HandlePlayerBlackout function, and home/overworld's OverworldLoop.notCinnabarGym function. We also have to "force" the trainer battle to trigger in this file.
; Also, for some reason, battletentdata.asm didn't work properly without an INCLUDE. I cut my losses and slapped it in here, works fine anyway.
BattleTent_Script:
call EnableAutoTextBoxDrawing
ld hl, BattleTent_ScriptPointers
ld a, [wBattleTentCurScript]
jp CallFunctionInTable
BattleTent_ScriptPointers:
dw BattleTent_Normal
dw BattleTent_GuyWalking
dw BattleTent_PlayerWalking
dw BattleTent_InitPhase
dw BattleTent_PrepareEnemy
dw BattleTent_InitBattle
dw BattleTent_AfterBattle
dw BattleTent_Heal
dw BattleTent_PlayerWalkBack
dw BattleTent_Final
BattleTent_TextPointers:
dw BattleTentGuy
dw BattleTentMart
dw BattleTentGuy2
dw BattleTentTrainer
dw BattleTentGuy2_Heal
dw BattleTentGuy_After
BattleTent_LoadTeam:
ld a, [wBoxCount]
ld d, a
push de
ld a, [wPartyCount]
ld b, a
ld a, [wBTOrder+1]
swap a
or b
swap a
ld [wBTOrder+1], a
; deposit all party 'mons into the box
.depoloop
push bc
xor a
ld [wWhichPokemon], a
ld [wMonDataLocation], a
call LoadMonData
ld a, 1
ld [wRemoveMonFromBox], a
call MoveMon
xor a
ld [wRemoveMonFromBox], a
call RemovePokemon
pop bc
dec b
jr nz, .depoloop
; copy the selected 'mons from the box
ld a, 2
ld [wMonDataLocation], a
; first
pop de
push de
ld a, [wBTOrder]
and $7
dec a
add d
ld [wWhichPokemon], a
call LoadMonData
xor a
ld [wRemoveMonFromBox], a
call MoveMon
; second
pop de
push de
ld a, [wBTOrder]
swap a
and $7
dec a
add d
ld [wWhichPokemon], a
call LoadMonData
xor a
ld [wRemoveMonFromBox], a
call MoveMon
; third
pop de
ld a, [wBTOrder+1]
and $7
dec a
add d
ld [wWhichPokemon], a
call LoadMonData
xor a
ld [wRemoveMonFromBox], a
call MoveMon
; limit party 'mons to lv. 50
ld hl, wPartyMon1Level
ld de, wPartyMon2Level - wPartyMon1Level
ld b, 0
.lvloop
ld a, [hl]
cp 50
jr c, .lvskip
push bc
push de
ld a, 50
ld [hl], a
ld [wCurEnemyLVL], a
push hl
ld de, wPartyMon1BoxLevel - wPartyMon1Level
add hl, de
ld [hl], a
pop hl
ld a, b
ld [wWhichPokemon], a
xor a
ld [wMonDataLocation], a
push hl
call LoadMonData
pop hl
push hl
ld bc, wPartyMon1MaxHP - wPartyMon1Level
add hl, bc
ld d,h
ld e,l ; de now points to stats
ld bc,-18
add hl,bc ; hl now points to byte 3 of experience
ld b,1
call CalcStats ; recalculate stats
ld d, 50
farcall CalcExperience ; calculate experience for next level and store it at $ff96
pop hl
push hl
ld bc, wPartyMon1Exp - wPartyMon1Level
add hl,bc ; hl now points to experience
; update experience to minimum for new level
ld a,[$ff96]
ld [hli],a
ld a,[$ff97]
ld [hli],a
ld a,[$ff98]
ld [hl],a
pop hl
push hl
ld bc, wPartyMon1HP - wPartyMon1Level
add hl,bc
ld d, h
ld e, l
ld bc, wPartyMon1MaxHP - wPartyMon1HP
add hl,bc
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
pop hl
pop de
pop bc
.lvskip
add hl, de
inc b
ld a, b
cp 3
jr nz, .lvloop
predef HealParty ; in case the player enters a team of fainted 'mon
BattleTent_Normal:
ret
BattleTent_RestoreTeam:
ld b, 3
; remove the current 3 team
; The original Battle Tent's removeloop effectively didn't work, so Enigami replaced it with one that does.
; However, it results in the need for compromises with box functionality.
; We don't know how the code in the port managed to function - it's possible the streamed version was different.
.removeloop
push bc
xor a
ld [wRemoveMonFromBox], a
ld [wWhichPokemon], a
call RemovePokemon
pop bc
dec b
jr nz, .removeloop
ld a, [wBoxCount]
ld b, a
ld c, 0
; withdraw all party 'mons from the box
.withdloop
push bc
ld a, c
ld [wWhichPokemon], a
ld a, 2
ld [wMonDataLocation], a ; dammit FailFish
call LoadMonData
xor a
ld [wRemoveMonFromBox], a
call MoveMon
ld a, $1
ld [wRemoveMonFromBox], a
call RemovePokemon
pop bc
dec b
jr nz, .withdloop
ret
BattleTent_GuyWalking:
ld a, [wFontLoaded] ; is the text box still open?
and a
ret nz
ld a, $ff
ld [wJoyIgnore], a
ld a, $a
ld [wNewTileBlockID], a
ld bc, $702
predef ReplaceTileBlock
ld a, SFX_TINK
call PlaySound
ld c, 30
call DelayFrames
ld a, 2
ld [wBattleTentCurScript], a
ret
BattleTent_PlayerWalking:
ld hl, wSimulatedJoypadStatesEnd
ld de, BattleTentMovement_1
call DecodeRLEList
dec a
ld [wSimulatedJoypadStatesIndex], a
call StartSimulatingJoypadStates
ld a, 3
ld [wBattleTentCurScript], a
ret
BattleTent_InitPhase:
ld a, [wSimulatedJoypadStatesIndex]
and a
ret nz
ld a, $fc
ld [wJoyIgnore], a
ld a, 2
ld [wPlayerMovingDirection], a
call Delay3
ld a, 3
ld [$ff8c], a
call DisplayTextID
ld a, $ff
ld [wJoyIgnore], a
ld a, [wBTStreakCnt]
cp 11
ld a, 4
jr nz, .skip
ld a, 8 ; TEH URN!
.skip
ld [wBattleTentCurScript], a
ret
BattleTent_PrepareEnemy:
ld a, [wFontLoaded] ; is the text box still open?
and a
ret nz
ld a, $ff
ld [wJoyIgnore], a
call Random
and $1f
ld [wBTClass], a
ld hl, BTTrainerClassList + 1
ld bc, 3
call AddNTimes
ld a, [hl] ; get the trainer's sprite
ld [wSpriteStateData1 + $40], a
; this will make the game blink
call DisableLCD
farcall InitMapSprites
call EnableLCD
ld a, $4
ld [$ff8c], a
ld de, BattleTentMovement_2
call MoveSprite
ld a, 1
ld [wPlayerMovingDirection], a
ld a, 5
ld [wBattleTentCurScript], a
ret
BattleTent_InitBattle:
ld a, [wNPCNumScriptedSteps]
and a
ret nz
ld a, $fc
ld [wJoyIgnore], a
ld a, 4
ld [$ff8c], a
call DisplayTextID
call Delay3
ld hl, wd72d
set 6, [hl]
set 7, [hl]
ld hl, BattleTentTrainer_After
ld de, BattleTentTrainer_After
call SaveEndBattleTextPointers
ld a, [wBTClass]
ld hl, BTTrainerClassList
ld bc, 3
call AddNTimes
ld a, [hl] ; get trainer class
add $c8
ld [wCurOpponent], a
xor a
ld [wTrainerNo], a
ld [hJoyHeld], a
ld [wJoyIgnore], a
ld a, 6
ld [wBattleTentCurScript], a
ret
BattleTent_AfterBattle:
ld a, $ff
ld [wJoyIgnore], a
ld a, $4
ld [$ff8c], a
ld de, BattleTentMovement_3
call MoveSprite
ld a, 7
ld [wBattleTentCurScript], a
ret
BattleTent_Heal:
ld a, [wNPCNumScriptedSteps]
and a
ret nz
ld a, [wBattleResult]
cp 1
jr nz, .stillTehUrn
; rip
ld a, 8
ld [wBattleTentCurScript], a
ret
.stillTehUrn
ld hl, wBTStreakCnt
inc [hl]
ld a, 2
ld [wPlayerMovingDirection], a
call Delay3
ld a, [hl]
cp 11
jr z, .skip ; No need to heal the party, let's just say that the player wins
predef HealParty
ld a, $fc
ld [wJoyIgnore], a
ld a, 5
ld [$ff8c], a
call DisplayTextID
.skip
ld a, 3
ld [wBattleTentCurScript], a
ret
BattleTent_PlayerWalkBack:
ld a, $ff
ld [wJoyIgnore], a
ld a, $a
ld [wNewTileBlockID], a
ld bc, $702
predef ReplaceTileBlock
ld hl, wSimulatedJoypadStatesEnd
ld de, BattleTentMovement_4
call DecodeRLEList
dec a
ld [wSimulatedJoypadStatesIndex], a
call StartSimulatingJoypadStates
ld a, 9
ld [wBattleTentCurScript], a
ret
BattleTent_Final:
ld a, [wSimulatedJoypadStatesIndex]
and a
ret nz
ld a, 8
ld [wPlayerMovingDirection], a
call Delay3
ld a, $7
ld [wNewTileBlockID], a
ld bc, $702
predef ReplaceTileBlock
ld a, SFX_TINK
call PlaySound
ld a, $fc
ld [wJoyIgnore], a
ld a, 6
ld [$ff8c], a
call DisplayTextID
xor a
ld [wJoyIgnore], a
ld [wBattleTentCurScript], a
ret
; Movements
BattleTentMovement_1:
db D_UP, $02
db D_LEFT, $01
db D_UP, $0a
db D_RIGHT, $02
db $FF
BattleTentMovement_2:
db $80, $80, $80, $80, $ff
BattleTentMovement_3:
db $c0, $c0, $c0, $c0, $ff
BattleTentMovement_4:
db D_LEFT, $02
db D_DOWN, $0a
db D_RIGHT, $01
db D_DOWN, $02
db $FF
; Text scripts
BattleTentGuy:
db $8
ld hl, BattleTentWelcome
call PrintText
call YesNoChoice
ld a, [wCurrentMenuItem]
and a
jr nz, .seeya
; party check
ld a, [wPartyCount]
cp 3
ld hl, BattleTentNotEnough
jr c, .finalskip
; box space check
; Due to the way the loops have changed, and the weird old function, the Battle Tent now requires a free box to work.
ld a, [wBoxCount]
cp 1
ld hl, BattleTentNoBoxTmp
jr c, .skip2
.finalskip
call PrintText
.seeya
ld hl, BattleTentSeeYouAgain
call PrintText
jp TextScriptEnd
.skip2
ld hl, BattleTentPlsSel
call PrintText
xor a
ld [wUpdateSpritesEnabled], a
call SaveScreenTilesToBuffer2
.partymenuloop
ld a, $6
ld [wPartyMenuTypeOrMessageID],a ; changed label from original
call DisplayPartyMenu
ld hl, wBTOrder
jr nc, .monchosen
xor a
ld [hli], a
ld [hl], a
call GBPalWhiteOutWithDelay3
call RestoreScreenTilesAndReloadTilePatterns
call LoadGBPal
jr .seeya
.monchosen
ld a, [wWhichPokemon]
inc a
ld b, a
ld a, [hl]
and $7
cp b
jr z, .deselfirst
cp 0
jr nz, .skipfirst
ld a, b
ld [hl], a
jr .partymenuloop
.deselfirst
ld a, [hli]
swap a
and $7
ld b, a
ld a, [hl]
and $7
swap a
or b
ld b, a
xor a
ld [hld], a
ld a, b
ld [hl], a
jr .partymenuloop
.skipfirst
ld a, [hl]
swap a
and $7
cp b
jr z, .deselsecond
cp 0
jr nz, .skipsecond
ld a, [hl]
and $7
swap b
or b
ld [hl], a
jr .partymenuloop
.deselsecond
ld a, [hli]
and $7
ld b, a
ld a, [hld]
and $7
swap a
or b
ld [hli], a
xor a
ld [hl], a
jr .partymenuloop
.skipsecond
inc hl
ld a, [hl]
and $7
cp b
jr z, .deselthird
cp 0
jr z, .skipthird
ld hl, BattleTentNoMoreThan3
call PrintText
jp .partymenuloop
.deselthird
xor a
ld [hl], a
jp .partymenuloop
.skipthird
ld a, b
ld [hl], a
push hl
ld hl, wd730
set 6,[hl] ; turn off letter printing delay
call ClearScreen
farcall RedrawPartyMenu_
ld hl, BattleTentConfirm
call PrintText
call YesNoChoice
pop hl
ld a, [wCurrentMenuItem]
and a
jp nz, .partymenuloop
call GBPalWhiteOutWithDelay3
call RestoreScreenTilesAndReloadTilePatterns
call LoadGBPal
ld hl, BattleTentPleaseWait
call PrintText
call BattleTent_LoadTeam
ld hl, BattleTentLetsGo
call PrintText
ld a, 1
ld [wBattleTentCurScript], a
jp TextScriptEnd
BTReward:
db $03,$00,$00
BattleTentGuy_After:
db $8
ld a, [wBTStreakCnt]
cp 11
ld hl, BattleTentLost
jr nz, .skip ; Not Teh Urn BibleThump
ld a, $03 ; NO REVERTING THIS CODE PIGU IM SICK OF YOU BREAKING IT!
ldh [$9f], a
ld a, $00
ldh [$a1], a
ld a, $00
ldh [$a0], a
ld hl, $ffa1
ld de, wPlayerMoney + 2
ld c, $3
predef AddBCDPredef
ld hl, BattleTentWon
.skip
call PrintText
ld hl, BattleTentPleaseWait
call PrintText
call BattleTent_RestoreTeam
; clear up all variables
xor a
ld hl, wBTOrder
ld bc, wBTDataEnd - wBTOrder
call FillMemory
ld hl, BattleTentSeeYouAgain
call PrintText
jp TextScriptEnd
; The Battle Tent has a new progression system for two reasons:
; 1) The battles are all trainer-based now, so money is given after battle.
; 2) wBTStreakCnt would not increment properly for unknown reasons, making it infinite.
; Thus, now the player can constantly battle and abandon the challenge when they want.
; Arguably a better system, but I do wish the counter incremented...
BattleTentGuy2:
db $8
ld a, [wBTStreakCnt] ; The streak counter is still used for message continuity.
and a
; Old System
; ld hl, BattleTentGuy2_Streak
; jr nz, .skip
; inc a
; ld [wBTStreakCnt], a
; ld hl, BattleTentGuy2_Init
; jr .skip2
;.skip
; cp 11
; jr nz, .skip2
; New System
ld hl, BattleTentGuy2_Streak ; The message has been changed appropriately down below.
jr z, .skip2
xor a ; The D-Pad is locked at this point, so blank out wJoyIgnore to allow manual option selection.
ld [wJoyIgnore], a
ld hl, BattleTentGuy2_Continue ; Continue prompt.
call PrintText
call YesNoChoice
ld a, [wCurrentMenuItem]
and a
jr nz, .refused ; If 0, move to refused.
.cont
ld hl, BattleTentGuy2_Init ; Load the next battle.
; fallthrough
.skip2 ; This handles BattleTentGuy2_Streak and BattleTentGuy2_Init at once.
call PrintText
jr .done
.refused
ld hl, BattleTentGuy2_Win
call PrintText
ld a, 9 ; Load BattleTent_PlayerWalkBack, which takes it from here.
ld [wBattleTentCurScript], a ; For some reason, this isn't working properly, even if jp'd.
; fallthrough
.done
jp TextScriptEnd
BattleTentTrainer:
db $8
call Random
and $3
ld hl, BTLib1
ld bc, 9
call AddNTimes
ld de, wStringBuffer1
call CopyData
ld a, [hRandomAdd]
swap a
and $3
ld hl, BTLib2
ld bc, 7
call AddNTimes
ld de, wStringBuffer2
call CopyData
ld a, [hRandomSub]
and $7
ld hl, BTBeforeBattlePtrTable
ld bc, 2
call AddNTimes
ld a, [hli]
ld e, a
ld a, [hl]
ld d, a
ld l, e
ld h, d
call PrintText
ld hl, wd72d
set 6, [hl]
set 7, [hl]
ld a, 1
ld [wIsTrainerBattle], a
jp TextScriptEnd
BattleTentTrainer_After:
db $8
call Random
and $3
ld hl, BTLib3
ld bc, 10
call AddNTimes
ld de, wStringBuffer1
call CopyData
ld a, [hRandomAdd]
swap a
and $3
ld hl, BTLib4
ld bc, 7
call AddNTimes
ld de, wStringBuffer2
call CopyData
ld a, [hRandomSub]
and $7
ld hl, BTAfterBattlePtrTable
ld bc, 2
call AddNTimes
ld a, [hli]
ld e, a
ld a, [hl]
ld d, a
ld l, e
ld h, d
call PrintText
jp TextScriptEnd
BattleTentWelcome:
text "Welcome to the"
line "BATTLE TENT!"
para "Here, trainers"
line "from far and"
cont "wide come to"
;cont "face a gauntlet"
;cont "of 10 trainers!"
cont "spar against"
cont "one another!"
;para "If you win them"
;line "all, you win"
;cont "a prize!"
para "Would you like"
line "to participate?"
prompt
BattleTentNotEnough:
text "..whoops! You don't"
line "have enough"
cont "#MON that"
cont "follow the rules!"
prompt
BattleTentNoBoxTmp:
text "..whoops! your"
line "current #MON"
cont "BOX needs to"
cont "be empty!"
para "We need to"
line "store all of your"
cont "party's #MON"
cont "into a BOX."
para "Try changing"
line "or emptying it."
prompt
BattleTentPlsSel:
text "Please select the"
line "#MON you wish"
cont "to enter."
prompt
BattleTentNoMoreThan3:
text "No more than three"
line "#MON may enter!"
prompt
BattleTentConfirm:
text "Are you okay with"
line "these choices?"
prompt
BattleTentPleaseWait:
text "Please wait…"
done
BattleTentLetsGo:
text "Alright, this way."
done
BattleTentWon:
text "Wow! You finally"
line "did it!"
para "Here is the"
line "reward!"
para $52, " received"
line "¥30000!"
prompt
BattleTentLost:
text "It's a shame that"
line "you lost."
cont "Try again later!"
prompt
BattleTentSeeYouAgain:
text_far _PokemonCenterFarewellText
db "@"
BattleTentGuy2_Init:
text "Your battle will"
line "begin soon."
para "Good luck!"
done
; Cut in favour of a different system.
BattleTentGuy2_Streak:
; text "Opponent No.@" ; could be a №?
; text_decimal wBTStreakCnt, 1, 2
; text_start
; line "is up next."
; para "Good luck!"
; done
text "Here comes a"
line "new challenger!" ; I really like fighting games.
done
BattleTentGuy2_Continue:
text "Congratulations!"
para "Do you want to"
line "continue?"
prompt
BattleTentGuy2_Win:
;text "Congratulations!"
text "Well done!"
;para "You have defeated"
;line "all 10 opponents!"
para "Please go back to"
line "the counter to"
cont "claim your prize!"
done
BattleTentGuy2_Heal:
text "Your #MON will"
line "be restored to"
cont "full health."
done
; Battle Tent
BattleTentMart::
script_mart FULL_RESTORE, MAX_REVIVE, FULL_HEAL, BOTTLE_CAP, POKE_DOLL, X_ATTACK, X_DEFEND, X_SPEED, X_SPECIAL, GUARD_SPEC
INCLUDE "engine/battletentdata.asm"