From ec61a039b8481c3e55ef077d89a920aecc29d07d Mon Sep 17 00:00:00 2001 From: Llinos Evans <36418502+PlagueVonKarma@users.noreply.github.com> Date: Sat, 13 May 2023 02:50:31 +0100 Subject: [PATCH] Battle Tent Port This is...most of the stuff necessary for the Battle Tent to work. I've faithfully restored most things so far, including doing a few grammar tweaks. Main issue is that we get a really strange softlock when the Pokemon selection menu comes up. Not sure why, but point is, it can't progress to the next bit for debugging like this. Committing now to ask for assistance. --- constants/map_constants.asm | 13 +- data/events/hidden_objects.asm | 6 + data/maps/headers/BattleTent.asm | 2 + data/maps/hide_show_data.asm | 1 + data/maps/map_header_banks.asm | 1 + data/maps/map_header_pointers.asm | 1 + data/maps/objects/BattleTent.asm | 17 + data/maps/objects/CitrineCity.asm | 1 + data/maps/songs.asm | 1 + data/maps/town_map_entries.asm | 1 + data/maps/town_map_order.asm | 1 + data/wild/grass_water.asm | 1 + engine/battle/core.asm | 26 +- engine/battle/read_trainer_party.asm | 8 + engine/battle/trainer_ai.asm | 5 +- engine/battletentdata.asm | 369 ++++++++++++ engine/debug/debug_party.asm | 10 +- engine/menus/party_menu.asm | 47 +- main.asm | 6 + maps.asm | 6 + maps/BattleTent.blk | 15 + ram/wram.asm | 18 +- scripts/BattleTent.asm | 802 +++++++++++++++++++++++++++ 23 files changed, 1340 insertions(+), 18 deletions(-) create mode 100644 data/maps/headers/BattleTent.asm create mode 100644 data/maps/objects/BattleTent.asm create mode 100644 engine/battletentdata.asm create mode 100644 maps/BattleTent.blk create mode 100644 scripts/BattleTent.asm diff --git a/constants/map_constants.asm b/constants/map_constants.asm index 372ae7ed..8bd6a215 100644 --- a/constants/map_constants.asm +++ b/constants/map_constants.asm @@ -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 diff --git a/data/events/hidden_objects.asm b/data/events/hidden_objects.asm index 15996c40..fc44eab3 100644 --- a/data/events/hidden_objects.asm +++ b/data/events/hidden_objects.asm @@ -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 diff --git a/data/maps/headers/BattleTent.asm b/data/maps/headers/BattleTent.asm new file mode 100644 index 00000000..04451358 --- /dev/null +++ b/data/maps/headers/BattleTent.asm @@ -0,0 +1,2 @@ + map_header BattleTent, BATTLE_TENT, CLUB, 0 + end_map_header \ No newline at end of file diff --git a/data/maps/hide_show_data.asm b/data/maps/hide_show_data.asm index dce42648..3af95eaf 100644 --- a/data/maps/hide_show_data.asm +++ b/data/maps/hide_show_data.asm @@ -253,6 +253,7 @@ MapHSPointers: dw NoHS dw NoHS dw GiovannisRoomHS + dw NoHS assert_table_length NUM_MAPS dw -1 ; end diff --git a/data/maps/map_header_banks.asm b/data/maps/map_header_banks.asm index 3002f426..0f638f4e 100644 --- a/data/maps/map_header_banks.asm +++ b/data/maps/map_header_banks.asm @@ -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 diff --git a/data/maps/map_header_pointers.asm b/data/maps/map_header_pointers.asm index b90601fa..e553cf96 100644 --- a/data/maps/map_header_pointers.asm +++ b/data/maps/map_header_pointers.asm @@ -251,4 +251,5 @@ MapHeaderPointers:: dw AgathasRoom_h dw RockTunnelB1F_h dw GiovannisRoom_h + dw BattleTent_h assert_table_length NUM_MAPS diff --git a/data/maps/objects/BattleTent.asm b/data/maps/objects/BattleTent.asm new file mode 100644 index 00000000..2fd81867 --- /dev/null +++ b/data/maps/objects/BattleTent.asm @@ -0,0 +1,17 @@ +BattleTent_Object: ; 0x1dd9b (size=38) + db $e ; border block + + def_warp_events + warp_event 3, 19, CITRINE_CITY, 6 + warp_event 2, 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 9, 4, SPRITE_YOUNGSTER, STAY, LEFT, 4 ; person + + + def_warps_to BATTLE_TENT \ No newline at end of file diff --git a/data/maps/objects/CitrineCity.asm b/data/maps/objects/CitrineCity.asm index 060d1f60..ba945470 100644 --- a/data/maps/objects/CitrineCity.asm +++ b/data/maps/objects/CitrineCity.asm @@ -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 diff --git a/data/maps/songs.asm b/data/maps/songs.asm index e1cd5d93..875a1eff 100644 --- a/data/maps/songs.asm +++ b/data/maps/songs.asm @@ -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_INDIGO_PLATEAU, 0 ; BATTLE_TENT assert_table_length NUM_MAPS diff --git a/data/maps/town_map_entries.asm b/data/maps/town_map_entries.asm index 8e115a06..10eef54c 100644 --- a/data/maps/town_map_entries.asm +++ b/data/maps/town_map_entries.asm @@ -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 diff --git a/data/maps/town_map_order.asm b/data/maps/town_map_order.asm index 1148d5df..bf2e055c 100644 --- a/data/maps/town_map_order.asm +++ b/data/maps/town_map_order.asm @@ -53,4 +53,5 @@ TownMapOrder: db BRUNSWICK_TRAIL db CELESTE_HILL db FARAWAY_ISLAND_OUTSIDE + db BATTLE_TENT TownMapOrderEnd: diff --git a/data/wild/grass_water.asm b/data/wild/grass_water.asm index 9fa6c5f7..b75bdb9a 100644 --- a/data/wild/grass_water.asm +++ b/data/wild/grass_water.asm @@ -250,6 +250,7 @@ WildDataPointers: dw NothingWildMons dw RockTunnelB1FWildMons dw NothingWildMons + dw NothingWildMons ; battle tent assert_table_length NUM_MAPS dw -1 ; end diff --git a/engine/battle/core.asm b/engine/battle/core.asm index ce83e160..65721975 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -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 @@ -2189,13 +2195,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 +2214,11 @@ DisplayBattleMenu:: call PrintText jp DisplayBattleMenu +.battletent + ld hl, ItemsCantBeUsedHereText + call PrintText + jp DisplayBattleMenu + .notLinkBattle call SaveScreenTilesToBuffer2 ld a, [wBattleType] @@ -6286,6 +6300,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 +6321,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 diff --git a/engine/battle/read_trainer_party.asm b/engine/battle/read_trainer_party.asm index 841e72dd..be19f121 100644 --- a/engine/battle/read_trainer_party.asm +++ b/engine/battle/read_trainer_party.asm @@ -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 diff --git a/engine/battle/trainer_ai.asm b/engine/battle/trainer_ai.asm index 36a9e956..a9b9342c 100644 --- a/engine/battle/trainer_ai.asm +++ b/engine/battle/trainer_ai.asm @@ -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 diff --git a/engine/battletentdata.asm b/engine/battletentdata.asm new file mode 100644 index 00000000..68264105 --- /dev/null +++ b/engine/battletentdata.asm @@ -0,0 +1,369 @@ +;btlibs +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 GAMBLER, SPRITE_GAMBLER, 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_COOLTRAINER_M, 0 + db JACK, SPRITE_BALDING_GUY, 0 + 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 \ No newline at end of file diff --git a/engine/debug/debug_party.asm b/engine/debug/debug_party.asm index 067171e4..4001981c 100644 --- a/engine/debug/debug_party.asm +++ b/engine/debug/debug_party.asm @@ -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 diff --git a/engine/menus/party_menu.asm b/engine/menus/party_menu.asm index f3f2f276..91dfe4f2 100644 --- a/engine/menus/party_menu.asm +++ b/engine/menus/party_menu.asm @@ -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,37 @@ RedrawPartyMenu_:: db "ABLE@" .notAbleToLearnMoveText db "NOT ABLE@" +.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 +203,7 @@ RedrawPartyMenu_:: add hl, bc call PlaceString pop hl - jr .printLevel + jp .printLevel .ableToEvolveText db "ABLE@" .notAbleToEvolveText @@ -235,6 +273,7 @@ PartyMenuMessagePointers: dw PartyMenuUseTMText dw PartyMenuSwapMonText dw PartyMenuItemUseText + dw PartyMenuBattleTentText PartyMenuNormalText: text_far _PartyMenuNormalText @@ -256,6 +295,10 @@ PartyMenuSwapMonText: text_far _PartyMenuSwapMonText text_end +PartyMenuBattleTentText: ; 12e93 (4:6e93) + text_far _PartyMenuBattleTentText + db "@" + PotionText: text_far _PotionText text_end diff --git a/main.asm b/main.asm index 033e37d6..f0ebf5c8 100644 --- a/main.asm +++ b/main.asm @@ -362,3 +362,9 @@ SECTION "Engine Spillover", ROMX INCLUDE "engine/menus/item_descriptions.asm" INCLUDE "engine/items/tm_prices.asm" +INCLUDE "engine/battletentdata.asm" + +_PartyMenuBattleTentText:: + text "Select which" + line "#MON to enter?" + done diff --git a/maps.asm b/maps.asm index 59913d49..d6aa5c4f 100644 --- a/maps.asm +++ b/maps.asm @@ -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" diff --git a/maps/BattleTent.blk b/maps/BattleTent.blk new file mode 100644 index 00000000..a066fd1c --- /dev/null +++ b/maps/BattleTent.blk @@ -0,0 +1,15 @@ + + + !"# + + + + + + + + + + + + diff --git a/ram/wram.asm b/ram/wram.asm index 29fed38a..11020c03 100644 --- a/ram/wram.asm +++ b/ram/wram.asm @@ -405,10 +405,23 @@ wSlotMachineSevenAndBarModeChance:: db ; ROM back to return to when the player is done with the slot machine wSlotMachineSavedROMBank:: db +;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 + ; Move Buffer stuff for Mateo's code wMoveBuffer:: wRelearnableMoves:: - ds 164 + ds 115 ; Try not to use this stack. ; A good amount of space is needed to store data for the move relearner. ; If it's like, 2, it'll lag like crazy and show garbage from elsewhere. @@ -2099,7 +2112,8 @@ wSeafoamIslandsB3FCurScript:: db wRoute23CurScript:: db wSeafoamIslandsB4FCurScript:: db wRoute18Gate1FCurScript:: db - ds 6 +wBattleTentCurScript:: db + ds 5 wGameProgressFlagsEnd:: UNION diff --git a/scripts/BattleTent.asm b/scripts/BattleTent.asm new file mode 100644 index 00000000..a8baaee3 --- /dev/null +++ b/scripts/BattleTent.asm @@ -0,0 +1,802 @@ +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 +.removeloop + push bc + xor a + ld [wRemoveMonFromBox], a + ld [wWhichPokemon], a + call RemovePokemon + pop bc + dec b + jr nz, .removeloop + ld a, [wBTOrder+1] + swap a + and $7 + ld b, a + ld a, [wBoxCount] + sub b + ld c, a + +; 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 + ld a, [wPartyCount] + ld b, a + ld a, [wBoxCount] + add b + cp MONS_PER_BOX + 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 + 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 does not" + cont "have enough" + cont "space!" + + para "We need to" + line "store all of your" + cont "party's #MON" + cont "into the 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. @" + text_decimal wBTStreakCnt, 1, 2 + db $0 + 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 POTION, SUPER_POTION, HYPER_POTION, REVIVE, FULL_HEAL, POKE_DOLL, X_ATTACK, X_DEFEND, X_SPEED, X_SPECIAL + \ No newline at end of file