Merge pull request #13 from PlagueVonKarma/BattleTentPort

Battle Tent Port
This commit is contained in:
Llinos Evans 2023-05-14 20:39:13 +01:00 committed by GitHub
commit 3894953698
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 1385 additions and 22 deletions

View file

@ -312,6 +312,7 @@ Credits
* dannye33 - Assisting with crysaudio implementation
* erosunica - Assistance with developing Celadon University & Citrine City, plus sources for various subjects.
* Chatot4444 - Assisting with gym scaling code
* Enigami - Reworking the Battle Tent's RestoreTeam code to make it work properly
* ZumiIsawhat? - Restorations of beta OST
* FrenchOrange - Reconstructions of various overworld beta sprites.
* Helix Chamber, RacieBeep, loumilouminosus, Orchid, GBCRetro, & catstorm26 - Prototype Pokémon sprites

View file

@ -220,11 +220,11 @@ DEF FIRST_INDOOR_MAP EQU const_value
map_const DIGLETTS_CAVE, 20, 18 ; $C6
map_const VICTORY_ROAD_3F, 15, 9 ; $C7
map_const ROCKET_HIDEOUT_B1F, 15, 14 ; $C8
map_const ROCKET_HIDEOUT_B2F, 15, 14 ; $C9 - Currently unused
map_const ROCKET_HIDEOUT_B3F, 15, 14 ; $CA - Currently unused
map_const ROCKET_HIDEOUT_B4F, 15, 12 ; $CB - Currently unused
map_const ROCKET_HIDEOUT_ELEVATOR, 3, 4 ; $CC - Currently unused
map_const CITRINE_MART, 4, 4 ; $CD - was UNUSED_MAP_CC
map_const ROCKET_HIDEOUT_B2F, 15, 14 ; $C9
map_const ROCKET_HIDEOUT_B3F, 15, 14 ; $CA
map_const ROCKET_HIDEOUT_B4F, 15, 12 ; $CB
map_const ROCKET_HIDEOUT_ELEVATOR, 3, 4 ; $CC
map_const CITRINE_MART, 4, 4 ; $CD - was UNUSED_MAP_CC
map_const GARNET_CAVERN_1F, 15, 9 ; $CE - was UNUSED_MAP_CD
map_const GARNET_CAVERN_B1F, 15, 9 ; $CF - was UNUSED_MAP_CE
map_const SILPH_CO_2F, 15, 9 ; $D0
@ -267,8 +267,9 @@ DEF FIRST_INDOOR_MAP EQU const_value
map_const LORELEIS_ROOM, 5, 6 ; $F5
map_const BRUNOS_ROOM, 5, 6 ; $F6
map_const AGATHAS_ROOM, 5, 6 ; $F7
map_const ROCK_TUNNEL_B1F, 20, 18 ; $E9 - Switched with CINNABAR_VOLCANO_FLOORS
map_const ROCK_TUNNEL_B1F, 20, 18 ; $F8 - Switched with CINNABAR_VOLCANO_FLOORS
map_const GIOVANNIS_ROOM, 11, 14 ; $F9
map_const BATTLE_TENT, 5, 10 ; $FA
DEF NUM_MAPS EQU const_value
; Indoor maps, such as houses, use this as the Map ID in their exit warps

View file

@ -85,6 +85,7 @@ HiddenObjectMaps:
db ROUTE_4
db CELADON_UNIVERSITY_POKECENTER
db CITRINE_POKECENTER
db BATTLE_TENT
db -1 ; end
HiddenObjectPointers:
@ -175,6 +176,7 @@ HiddenObjectPointers:
dw Route4HiddenObjects
dw CeladonUniversityPokecenterHiddenObjects
dw CitrinePokecenterHiddenObjects
dw BattleTentHiddenObjects
MACRO hidden_object
db \2 ; y coord
@ -634,3 +636,7 @@ CeruleanCityHiddenObjects:
Route4HiddenObjects:
hidden_object 40, 3, GREAT_BALL, HiddenItems
db -1 ; end
BattleTentHiddenObjects:
hidden_object 9, 16, SPRITE_FACING_UP, OpenPokemonCenterPC
db -1

View file

@ -76,7 +76,7 @@ ItemPrices::
bcd3 0 ; LIFT_KEY
bcd3 0 ; EXP_ALL
bcd3 0 ; was OLD_ROD, now CANDY_SACK. Plan to be one-of-a-kind, so 0 to discourage sale a la Master Ball.
bcd3 5000 ; was GOOD_ROD, now BOTTLE_CAP. Sells for 5000 in SV.
bcd3 9800 ; was GOOD_ROD, now BOTTLE_CAP. Sells for 5000 in SV, but making it in-line with the Stat Exp items feels right.
bcd3 0 ; SUPER_ROD
bcd3 0 ; PP_UP
bcd3 0 ; ETHER

View file

@ -0,0 +1,2 @@
map_header BattleTent, BATTLE_TENT, CLUB, 0
end_map_header

View file

@ -253,6 +253,7 @@ MapHSPointers:
dw NoHS
dw NoHS
dw GiovannisRoomHS
dw NoHS
assert_table_length NUM_MAPS
dw -1 ; end

View file

@ -251,4 +251,5 @@ MapHeaderBanks::
db BANK(AgathasRoom_h)
db BANK(RockTunnelB1F_h)
db BANK(GiovannisRoom_h)
db BANK(BattleTent_h)
assert_table_length NUM_MAPS

View file

@ -251,4 +251,5 @@ MapHeaderPointers::
dw AgathasRoom_h
dw RockTunnelB1F_h
dw GiovannisRoom_h
dw BattleTent_h
assert_table_length NUM_MAPS

View file

@ -0,0 +1,17 @@
BattleTent_Object: ; 0x1dd9b (size=38)
db $e ; border block
def_warp_events
warp_event 2, 19, CITRINE_CITY, 6
warp_event 3, 19, CITRINE_CITY, 6
def_bg_events
def_object_events
object_event 2, 14, SPRITE_WAITER, STAY, DOWN, 1 ; person
object_event 7, 14, SPRITE_CLERK, STAY, DOWN, 2 ; person
object_event 2, 4, SPRITE_WAITER, STAY, RIGHT, 3 ; person
object_event 10, 4, SPRITE_YOUNGSTER, STAY, LEFT, 4 ; person
def_warps_to BATTLE_TENT

View file

@ -7,6 +7,7 @@ CitrineCity_Object:
warp_event 15, 17, CITRINE_POKECENTER, 1
warp_event 15, 27, CITRINE_MART, 1
warp_event 22, 5, GARNET_CAVERN_1F, 1
warp_event 11, 7, BATTLE_TENT, 1
warp_event 35, 31, VERMILION_CITY, 6
warp_event 35, 30, VERMILION_CITY, 6

View file

@ -250,4 +250,5 @@ MapSongBanks::
db MUSIC_POKEMON_TOWER, 0 ; AGATHAS_ROOM
db MUSIC_DUNGEON3, 0 ; ROCK_TUNNEL_B1F
db MUSIC_DUNGEON2, 0 ; GIOVANNIS_ROOM
db MUSIC_GYM, 0 ; BATTLE_TENT
assert_table_length NUM_MAPS

View file

@ -126,4 +126,5 @@ InternalMapEntries:
internal_map AGATHAS_ROOM, 0, 2, PokemonLeagueName
internal_map ROCK_TUNNEL_B1F, 14, 3, RockTunnelName
internal_map GIOVANNIS_ROOM, 2, 8, ViridianCityName
internal_map BATTLE_TENT, 7, 9, CitrineCityName
db -1 ; end

View file

@ -53,4 +53,5 @@ TownMapOrder:
db BRUNSWICK_TRAIL
db CELESTE_HILL
db FARAWAY_ISLAND_OUTSIDE
db BATTLE_TENT
TownMapOrderEnd:

View file

@ -250,6 +250,7 @@ WildDataPointers:
dw NothingWildMons
dw RockTunnelB1FWildMons
dw NothingWildMons
dw NothingWildMons ; battle tent
assert_table_length NUM_MAPS
dw -1 ; end

View file

@ -836,6 +836,9 @@ FaintEnemyPokemon:
call SaveScreenTilesToBuffer1
xor a
ld [wBattleResult], a
ld a, [wCurMap]
cp BATTLE_TENT
ret z ; one of Battle Tower's rules
ld b, EXP_ALL
call IsItemInBag
push af
@ -961,6 +964,9 @@ TrainerBattleVictory:
ld c, 40
call DelayFrames
call PrintEndBattleText
ld a, [wCurMap]
cp BATTLE_TENT
ret z ; We will give it later ;)
; win money
ld hl, MoneyForWinningText
call PrintText
@ -1161,7 +1167,27 @@ HandlePlayerBlackOut:
ld [wIsTrainerBattle], a
ld a, [wLinkState]
cp LINK_STATE_BATTLING
jr z, .notRival1Battle
jp z, .notRival1Battle
; This is a scripted loss mechanic from a pret tutorial, adapted to the Battle Tent.
; This is necessary so you don't get booted out of the tent and have your Pokemon de-levelled.
ld a, [wCurMap]
cp BATTLE_TENT
jr nz, .notThatTrainer
hlcoord 0, 0
lb bc, 8, 21
call ClearScreenArea
call ScrollTrainerPicAfterBattle
ld c, 40
call DelayFrames
ld hl, StupidBattleTentFix
call PrintText
ld a, [wCurMap]
cp BATTLE_TENT ; MAP ID can be found in constants\map_constants.asm
ret
.notThatTrainer
ld a, [wCurOpponent]
cp OPP_RIVAL1
jr nz, .notRival1Battle
@ -2189,13 +2215,16 @@ DisplayBattleMenu::
.throwSafariBallWasSelected
ld a, SAFARI_BALL
ld [wcf91], a
jr UseBagItem
jp UseBagItem
.upperLeftMenuItemWasNotSelected ; a menu item other than the upper left item was selected
cp $2
jp nz, PartyMenuOrRockOrRun
; either the bag (normal battle) or bait (safari battle) was selected
ld a, [wCurMap]
cp BATTLE_TENT
jr z, .battletent
ld a, [wLinkState]
cp LINK_STATE_BATTLING
jr nz, .notLinkBattle
@ -2205,6 +2234,11 @@ DisplayBattleMenu::
call PrintText
jp DisplayBattleMenu
.battletent
ld hl, ItemsCantBeUsedHereText
call PrintText
jp DisplayBattleMenu
.notLinkBattle
call SaveScreenTilesToBuffer2
ld a, [wBattleType]
@ -6286,6 +6320,8 @@ LoadEnemyMonData:
ld de, wEnemyMonNick
ld bc, NAME_LENGTH
call CopyData
cp BATTLE_TENT
jr z, .skipSeenFlagAdding ; one of Battle Tower's rules
ld a, [wEnemyMonSpecies2]
ld [wd11e], a
predef IndexToPokedex
@ -6305,6 +6341,14 @@ LoadEnemyMonData:
ld a, $7 ; default stat mod
ld b, NUM_STAT_MODS ; number of stat mods
ld hl, wEnemyMonStatMods
.skipSeenFlagAdding
ld hl, wEnemyMonLevel
ld de, wEnemyMonUnmodifiedLevel
ld bc, $b
call CopyData
ld a, $7 ; default stat mod
ld b, $8 ; number of stat mods
ld hl, wEnemyMonStatMods
.statModLoop
ld [hli], a
dec b
@ -7100,3 +7144,10 @@ LoadMonBackPic:
ldh a, [hLoadedROMBank]
ld b, a
jp CopyVideoData
; I struggled a lot in making this generate the text.
; This is the best compromise I can come up with right now.
StupidBattleTentFix:
text "Oops! Better"
line "luck next time!"
prompt

View file

@ -14,7 +14,15 @@ ReadTrainer:
dec a
ld [hl], a
; check if we are in battle tent since we need a random pokemon data
ld a,[wCurMap]
cp BATTLE_TENT
jr nz, .notBT
farcall ReadBattleTentTrainer
jp .FinishUp
; get the pointer to trainer data for this class
.notBT
ld a, [wTrainerClass] ; get trainer class
dec a
add a

View file

@ -286,14 +286,15 @@ INCLUDE "engine/battle/read_trainer_party.asm"
INCLUDE "data/trainers/special_moves.asm"
INCLUDE "data/trainers/parties.asm"
;INCLUDE "data/trainers/scaled_parties.asm"
;INCLUDE "data/trainers/rival_parties.asm"
TrainerAI:
and a
ld a, [wIsInBattle]
dec a
ret z ; if not a trainer, we're done here
ld a, [wCurMap]
cp BATTLE_TENT
ret z ; if we are in battle tent, we are done
ld a, [wLinkState]
cp LINK_STATE_BATTLING
ret z ; if in a link battle, we're done as well

370
engine/battletentdata.asm Normal file
View file

@ -0,0 +1,370 @@
;btlibs
; afters are farcallable for core.asm
BTLib1:
db "ready@@@@"
db "prepared@"
db "excited@@"
db "hyped@@@@"
BTLib2:
db "go@@@@@"
db "do it@@"
db "battle@"
db "rock@@@"
BTLib3::
db "Oh no@@@@@"
db "Argh no@@@"
db "Oh well@@@"
db "My streak@"
BTLib4::
db "game@@@"
db "battle@"
db "play@@@"
db "job@@@@"
BTBeforeBattlePtrTable:
dw BTBeforeBattleTemplate1
dw BTBeforeBattleTemplate2
dw BTBeforeBattleTemplate3
dw BTBeforeBattleTemplate4
dw BTBeforeBattleTemplate5
dw BTBeforeBattleTemplate6
dw BTBeforeBattleTemplate7
dw BTBeforeBattleTemplate8
BTAfterBattlePtrTable::
dw BTAfterBattleTemplate1
dw BTAfterBattleTemplate2
dw BTAfterBattleTemplate3
dw BTAfterBattleTemplate4
dw BTAfterBattleTemplate5
dw BTAfterBattleTemplate6
dw BTAfterBattleTemplate7
dw BTAfterBattleTemplate8
BTBeforeBattleTemplate1:
text "I'm @"
text_ram wStringBuffer1
text "!"
done
BTBeforeBattleTemplate2:
text "Get @"
text_ram wStringBuffer1
text "!"
done
BTBeforeBattleTemplate3:
text "Let's @"
text_ram wStringBuffer2
text "!"
done
BTBeforeBattleTemplate4:
text "I'm @"
text_ram wStringBuffer1
db 0
line "for this!"
para "Let's @"
text_ram wStringBuffer2
text "!"
done
BTBeforeBattleTemplate5:
text "Here I come!"
line "Let's @"
text_ram wStringBuffer2
text "!"
done
BTBeforeBattleTemplate6:
text "Let's @"
text_ram wStringBuffer2
db 0
line "together!"
done
BTBeforeBattleTemplate7:
text "I'm waiting for"
line "a while now."
para "Let's @"
text_ram wStringBuffer2
text "!"
done
BTBeforeBattleTemplate8:
text "Well, I'm"
line "@"
text_ram wStringBuffer1
text " now."
para "Let's @"
text_ram wStringBuffer2
text "."
done
BTAfterBattleTemplate1::
text "@"
text_ram wStringBuffer1
text "!"
para "Oh man.."
prompt
BTAfterBattleTemplate2::
text "@"
text_ram wStringBuffer1
text "!"
prompt
BTAfterBattleTemplate3::
text "@"
text_ram wStringBuffer1
text "!"
line "Good @"
text_ram wStringBuffer2
text "!"
prompt
BTAfterBattleTemplate4::
text "That was a nice"
line "@"
text_ram wStringBuffer2
text "!"
prompt
BTAfterBattleTemplate5::
text "I did the best"
line "I could."
para "I have no"
line "regrets!"
prompt
BTAfterBattleTemplate6::
text "@"
text_ram wStringBuffer1
text "!"
line "Nice @"
text_ram wStringBuffer2
text "!"
prompt
BTAfterBattleTemplate7::
text "That was a nice"
line "@"
text_ram wStringBuffer2
text ","
cont "don't you think?"
prompt
BTAfterBattleTemplate8::
text "Awesome"
line "@"
text_ram wStringBuffer2
text "!"
para "Shall we do this"
line "again?"
prompt
;data
BTTrainerClassList::
; structure:
; common - has 2 entries each in order to make the entire list exactly 32
db YOUNGSTER, SPRITE_YOUNGSTER, 0
db YOUNGSTER, SPRITE_YOUNGSTER, 0
db JR_TRAINER_M, SPRITE_COOLTRAINER_M, 0
db JR_TRAINER_M, SPRITE_COOLTRAINER_M, 0
db JR_TRAINER_F, SPRITE_COOLTRAINER_F, 0
db JR_TRAINER_F, SPRITE_COOLTRAINER_F, 0
db COOLTRAINER_M, SPRITE_COOLTRAINER_M, 9
db COOLTRAINER_M, SPRITE_COOLTRAINER_M, 9
db COOLTRAINER_F, SPRITE_COOLTRAINER_F, 9
db COOLTRAINER_F, SPRITE_COOLTRAINER_F, 9
; uncommon
db BUG_CATCHER, SPRITE_YOUNGSTER, 1
db LASS, SPRITE_COOLTRAINER_F, 7
db HIKER, SPRITE_HIKER, 2
db SAILOR, SPRITE_SAILOR, 3
db POKEMANIAC, SPRITE_SUPER_NERD, 0
db SUPER_NERD, SPRITE_SUPER_NERD, 0
db BURGLAR, SPRITE_SUPER_NERD, 0
db ENGINEER, SPRITE_SUPER_NERD, 4
db FISHER, SPRITE_FISHER, 3
db CUE_BALL, SPRITE_HIKER, 0
db COOLTRAINER_F, SPRITE_COOLTRAINER_F, 0
db BEAUTY, SPRITE_BEAUTY, 7
db PSYCHIC_TR, SPRITE_YOUNGSTER, 5
db ROCKER, SPRITE_ROCKER, 4
db JUGGLER, SPRITE_ROCKER, 5
db TAMER, SPRITE_ROCKER, 0
db BIRD_KEEPER, SPRITE_COOLTRAINER_M, 6
db BLACKBELT, SPRITE_HIKER, 2
db SCIENTIST, SPRITE_SCIENTIST, 8
db FIREFIGHTER, SPRITE_FISHER, 0
db JACK, SPRITE_SCIENTIST, 8
db CHANNELER, SPRITE_CHANNELER, 8
BTMonList::
; List of 'mons, grouped in 8 roughly by types
; Normal+Bug set
db TAUROS
db PERSIAN
db TRAMPEL
db SNORLAX
db BUTTERFREE
db PURAKKUSU
db SCIZOR
db PARASECT
; Rock+Fighting set
db GYAOON
db KABUTOPS
db RHYPERIOR
db ARCANINE_H
db HITMONTOP
db TAUROS_P
db POLIWRATH
db HITMONLEE
; Water set
db JABETTA
db CLOYSTER
db LAPRAS
db GYARADOS
db BLASTOISE
db JAGG
db POLITOED
db PENDRAKEN
; Electric+Fire set
db JOLTEON
db ZAPDOS
db GOROCHU
db SANDY_SHOCKS
db CHARIZARD
db NINETALES
db MAGMORTAR
db MOLTRES
; Psychic+Ice set
db ALAKAZAM
db SLOWBRO
db STARMIE
db EXEGGUTOR
db ARTICUNO
db JYNX
db NINETALES_A
db MR_RIME
; Flying+Fire set
db MADAAMU
db AERODACTYL
db DRAGONITE
db DODRIO
db MAROWAK_A
db FLAREON
db RAPIDASH
db TAUROS_PB
; Normal+Grass set
db DEER
db CHANSEY
db KANGASKHAN
db RATICATE_A
db TANGROWTH
db CACTUS
db TSUBOMITTO
db VICTREEBEL
; Ghost+Ground+Poison set
db STEELIX
db GUARDIA
db GOLEM
db GENGAR
db ANNIHILAPE
db CROBAT
db NIDOKING
db TENTACRUEL
; Normal+Dragon set
db PORYGON2
db PORYGONZ
db CLEFABLE
db RATICATE
db CROCKY
db EXEGGUTOR_A
db CRYITHAN
db KINGDRA
;engine
ReadBattleTentTrainer::
ld a, 50
ld [wCurEnemyLVL],a
ld a, [wBTClass]
ld hl, BTTrainerClassList + 2 ; Team selector
ld bc, 3
call AddNTimes
ld a, [hl]
and a
jr z, .anyTeam
dec a
ld hl, BTMonList
ld bc, 8
call AddNTimes ; now hl points to the specific team
ld b, 3
.SpecificTeam
push hl
push bc
call Random
and 7
ld b, 0
ld c, a
add hl, bc
ld a, [hl]
ld [wcf91],a
ld a,1
ld [wMonDataLocation],a
call AddPartyMon
pop bc
pop hl
dec b
jr nz, .SpecificTeam
ret
.anyTeam
ld hl, BTMonList
ld b, 3
.anyTeamLoop
push hl
push bc
call Random
and 63
ld c, a ; max = 63
ld a, [hRandomSub]
bit 7, a
jr z, .skipinc
inc c ; max = 64
.skipinc
and 7
add c
ld c, a ; max = 71
ld b, 0
add hl, bc
ld a, [hl]
ld [wcf91],a
ld a,1
ld [wMonDataLocation],a
call AddPartyMon
pop bc
pop hl
dec b
jr nz, .anyTeamLoop
ret

View file

@ -22,12 +22,12 @@ SetIshiharaTeam:
IshiharaTeam:
db EXEGGUTOR_A, 90
db ONIX, 90
db PINSIR, 90
db PURAKKUSU, 90
db TRAMPEL, 90
IF DEF(_DEBUG)
db DITTO, 50
db SCYTHER, 50
db SCYTHER, 50
db TAUROS_PB, 50
db SNORLAX, 50
db TANGROWTH, 50
ENDC
db -1 ; end
@ -71,8 +71,9 @@ IF DEF(_DEBUG)
ld [hl], a
; Jolteon (Pokemon 3) gets Thunderbolt.
; Adjusted for Trampel
ld hl, wPartyMon3Moves + 3
ld a, THUNDERBOLT
ld a, EARTHQUAKE
ld [hl], a
ld hl, wPartyMon3PP + 3
ld a, 15

View file

@ -62,7 +62,9 @@ RedrawPartyMenu_::
cp TMHM_PARTY_MENU
jr z, .teachMoveMenu
cp EVO_STONE_PARTY_MENU
jr z, .evolutionStoneMenu
jp z, .evolutionStoneMenu ; battle tent stuff
cp a, $06
jr z, .battleTentMenu
push hl
ld bc, 14 ; 14 columns to the right
add hl, bc
@ -97,6 +99,11 @@ RedrawPartyMenu_::
add hl, bc
call PlaceString
pop hl
.placeMoveLearnabilityString2
push hl
add hl,bc
call PlaceString
pop hl
.printLevel
ld bc, 10 ; move 10 columns to the right
add hl, bc
@ -113,6 +120,38 @@ RedrawPartyMenu_::
db "ABLE@"
.notAbleToLearnMoveText
db "NOT ABLE@"
;battletent
.battleTentMenu
ld a, [wWhichPokemon]
inc a
ld b, a
ld a, [wBTOrder]
and $7
cp b
ld de,.BTFirstText
jr z,.placeMoveLearnabilityString
ld a, [wBTOrder]
swap a
and $7
cp b
ld de,.BTSecondText
jr z,.placeMoveLearnabilityString
ld a, [wBTOrder+1]
cp b
ld de,.BTThirdText
jr z,.placeMoveLearnabilityString
ld de,.BTNotEnteredText
ld bc,20 + 6
jr .placeMoveLearnabilityString2
.BTNotEnteredText
db "NOT ENTERED@"
.BTFirstText
db "FIRST@"
.BTSecondText
db "SECOND@"
.BTThirdText
db "THIRD@"
;bt end
.evolutionStoneMenu
push hl
ld hl, EvosMovesPointerTable
@ -165,7 +204,7 @@ RedrawPartyMenu_::
add hl, bc
call PlaceString
pop hl
jr .printLevel
jp .printLevel
.ableToEvolveText
db "ABLE@"
.notAbleToEvolveText
@ -235,6 +274,7 @@ PartyMenuMessagePointers:
dw PartyMenuUseTMText
dw PartyMenuSwapMonText
dw PartyMenuItemUseText
dw PartyMenuBattleTentText
PartyMenuNormalText:
text_far _PartyMenuNormalText
@ -256,6 +296,10 @@ PartyMenuSwapMonText:
text_far _PartyMenuSwapMonText
text_end
PartyMenuBattleTentText: ; 12e93 (4:6e93)
text_far _PartyMenuBattleTentText
text_end
PotionText:
text_far _PotionText
text_end

View file

@ -366,6 +366,8 @@ OverworldLoopLessDelay::
ld a, [wCurMap]
cp OAKS_LAB
jp z, .noFaintCheck ; no blacking out if the player lost to the rival in Oak's lab
cp BATTLE_TENT
jp z, .noFaintCheck
callfar AnyPartyAlive
ld a, d
and a

View file

@ -362,3 +362,8 @@ SECTION "Engine Spillover", ROMX
INCLUDE "engine/menus/item_descriptions.asm"
INCLUDE "engine/items/tm_prices.asm"
_PartyMenuBattleTentText::
text "Select which"
line "#MON to enter?"
done

View file

@ -989,6 +989,7 @@ INCLUDE "scripts/PokemonTower2F.asm"
INCLUDE "data/maps/objects/PokemonTower2F.asm"
PokemonTower2F_Blocks: INCBIN "maps/PokemonTower2F.blk"
; Removed for the Battle Tent.
INCLUDE "data/maps/headers/PokemonTower3F.asm"
INCLUDE "scripts/PokemonTower3F.asm"
INCLUDE "data/maps/objects/PokemonTower3F.asm"
@ -1370,3 +1371,8 @@ INCLUDE "data/maps/headers/GarnetCavern2F.asm"
INCLUDE "scripts/GarnetCavern2F.asm"
INCLUDE "data/maps/objects/GarnetCavern2F.asm"
GarnetCavern2F_Blocks: INCBIN "maps/GarnetCavern2F.blk"
INCLUDE "data/maps/headers/BattleTent.asm"
INCLUDE "data/maps/objects/BattleTent.asm"
INCLUDE "scripts/BattleTent.asm"
BattleTent_Blocks: INCBIN "maps/BattleTent.blk"

15
maps/BattleTent.blk Normal file
View file

@ -0,0 +1,15 @@


!"#







View file

@ -2099,11 +2099,25 @@ wSeafoamIslandsB3FCurScript:: db
wRoute23CurScript:: db
wSeafoamIslandsB4FCurScript:: db
wRoute18Gate1FCurScript:: db
ds 6
wBattleTentCurScript:: db
ds 5
wGameProgressFlagsEnd::
UNION
ds 128
; Surely this position will not cause any issues at all.
;battle tent data
wBTOrder:: dw
wBTStreakCnt:: db
wBTClass:: db
wBTDataEnd::
wStringBuffer1:: ; cf5f
ds 16 + 1
wStringBuffer2:: ; cf70
ds 16 + 1
wStringBuffer3:: ; cf81
ds 9 + 1
;end BT wram
ds 79
NEXTU
wChannel7:: channel_struct wChannel7
wChannel8:: channel_struct wChannel8

811
scripts/BattleTent.asm Normal file
View file

@ -0,0 +1,811 @@
; 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
BattleTentGuy2:
db $8
ld a, [wBTStreakCnt]
and a
ld hl, BattleTentGuy2_Streak
jr nz, .skip
inc a
ld [wBTStreakCnt], a
ld hl, BattleTentGuy2_Init
jr .skip2
.skip
cp 11
jr nz, .skip2
ld hl, BattleTentGuy2_Win
.skip2
call PrintText
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!"
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
BattleTentGuy2_Streak:
text "Opponent No.@" ; could be a №?
text_decimal wBTStreakCnt, 1, 2
text_start
line "is up next."
para "Good luck!"
done
BattleTentGuy2_Win:
text "Congratulations!"
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"

View file

@ -24,7 +24,7 @@ _CitrineShopSignText::
done
_CitrineCityTower::
text "BATTLE TOWER"
text "BATTLE TENT"
line "Test your mettle!"
done