diff --git a/data/scripts/story2.lua b/data/scripts/story2.lua index 2501b199..643c615e 100644 --- a/data/scripts/story2.lua +++ b/data/scripts/story2.lua @@ -285,7 +285,7 @@ M.PALLET_TOWN = { if oak then oak.facing = x == 10 and "right" or "left" end hold(2, nil, function() local battle = BattleState.newWild(game, "PIKACHU", 5) - battle:makeOldManDemo("PROF.OAK") + battle:makeOldManDemo("oak") battle.onFinish = function() afterPikaBattle() end diff --git a/src/battle/BattleState.lua b/src/battle/BattleState.lua index f5d6a3c8..38839c28 100644 --- a/src/battle/BattleState.lua +++ b/src/battle/BattleState.lua @@ -1038,8 +1038,7 @@ end -- scripted cursor hovers FIGHT, hops to ITEM and forces the item menu -- (one POKé BALL x50). Nothing is kept. -- Yellow's Pallet intro (BATTLE_TYPE_PIKACHU) is the same simulated --- script under "PROF.OAK" (pokeyellow core.asm .profOakName), so the --- displayed thrower name is a parameter. +-- script under .profOakName (pokeyellow core.asm:2117). -- The throw catches everywhere except Yellow's FIRST Viridian training. -- ItemUseBall's .oldManBattle branch checks EVENT_INITIAL_CATCH_TRAINING -- and, when it is set, stores anim data $63 in place of the $43 capture @@ -1049,16 +1048,13 @@ end -- closely!" demo resets the event before its battle -- (ViridianCityOldManStartCatchTrainingScript), so only the initial -- tutorial passes failThrow -- it stands in for that event (#636). -function BattleState:makeOldManDemo(name, failThrow) +function BattleState:makeOldManDemo(kind, failThrow) self.demo = true - self.demoName = name or Strings("OLD MAN") + -- pokeyellow engine/battle/core.asm:2109-2121 + self.oakDemo = kind == "oak" + self.demoName = self.data.text[self.oakDemo and "DisplayBattleMenu.profOakName" + or "DisplayBattleMenu.oldManName"] self.demoFails = failThrow and true or false - -- LoadPlayerBackPic and DisplayBattleMenu split on the same wBattleType: - -- BATTLE_TYPE_OLD_MAN gets .oldManName + OldManPicBack, BATTLE_TYPE_PIKACHU - -- gets .profOakName + ProfOakPicBack (pokeyellow core.asm). The thrower - -- name the caller passes IS that distinction here, so it picks the pic too - -- -- data/scripts/story2.lua is the only site that names PROF.OAK (#557). - self.oakDemo = name == "PROF.OAK" -- Yellow's Pallet intro runs this before the player owns any mon -- (BATTLE_TYPE_PIKACHU precedes the lab gift), so newWild flagged the -- battle dead for lack of a party. The demo never sends out, draws, or @@ -2790,7 +2786,7 @@ function BattleState:oldManThrow() self.result = "run" -- nothing is kept; wBattleResult only ends the demo -- engine/items/item_effects.asm:148 self:sayAuto(self:romText("_ItemUseText001", "%s used\n%s!", - self.demoName or Strings("OLD MAN"), self.data.items.POKE_BALL.name)) + self.demoName, self.data.items.POKE_BALL.name)) self:act(function() -- ItemUseBall's beat before the toss chain (like throwBall) self.nextInsert = (self.nextInsert or 0) + 1 diff --git a/src/import/CacheContract.lua b/src/import/CacheContract.lua index 18ea9520..5b576150 100644 --- a/src/import/CacheContract.lua +++ b/src/import/CacheContract.lua @@ -8,8 +8,8 @@ local GameVersion = require("src.core.GameVersion") local CacheContract = {} --- engine/battle/animations.asm:2418 -CacheContract.FORMAT = "rom-cache-v12-gen1:" +-- engine/battle/animations.asm:2418, engine/battle/core.asm:2051 +CacheContract.FORMAT = "rom-cache-v13-gen1:" CacheContract.VERSION_FORMAT = { -- v11: Gen 2 maps carry their object list's ROM address, which a .sav -- export re-anchoring a save onto another map writes back into @@ -22,8 +22,8 @@ CacheContract.VERSION_FORMAT = { crystal = "rom-cache-v15-crystal6:", -- engine/overworld/map_sprites.asm:181, engine/battle/animations.asm:2600 -- data/pikachu/pikachu_pic_animation.asm:340, engine/movie/title.asm:76 - -- engine/pikachu/pikachu_pic_animation.asm:412 - yellow = "rom-cache-v12-yellow4:", + -- engine/pikachu/pikachu_pic_animation.asm:412, engine/battle/core.asm:2135-2138 + yellow = "rom-cache-v12-yellow5:", -- v8: M4A tracks retain reachable patterns and explicit entry offsets. firered = "rom-cache-v25-firered:", leafgreen = "rom-cache-v10-leafgreen:", diff --git a/src/import/RomExtractor.lua b/src/import/RomExtractor.lua index 6a51398a..37f82511 100644 --- a/src/import/RomExtractor.lua +++ b/src/import/RomExtractor.lua @@ -1523,6 +1523,13 @@ function RomExtractor:extractText() self:symbol(label), metadata.dynamic[label] or {}) self:tick("Dialogue", index, #metadata.labels) end + -- pokered engine/battle/core.asm:2051, pokeyellow engine/battle/core.asm:2135-2138 + for _, label in ipairs({ "DisplayBattleMenu.oldManName", "DisplayBattleMenu.profOakName" }) do + if label == "DisplayBattleMenu.oldManName" or self.symbols[label] then + local s = self:symbol(label) + texts[label] = self.rom:readString(s.bank, s.address, self.manifest.charmap) + end + end local trainerHeaders = {} for mapLabel, headers in pairs(metadata.trainerHeaders) do local converted = {} diff --git a/tests/drivers/blue_ball_toss_sound_sync_2611.lua b/tests/drivers/blue_ball_toss_sound_sync_2611.lua index d283c0cc..6d9d43ae 100644 --- a/tests/drivers/blue_ball_toss_sound_sync_2611.lua +++ b/tests/drivers/blue_ball_toss_sound_sync_2611.lua @@ -53,7 +53,7 @@ return function(game) or BattleState.newWild(game, "DITTO", 10) b.onFinish = function() end b.catchAttempt = function() return false, 0 end - if kind == "oldman" then b:makeOldManDemo("OLD MAN", false) end + if kind == "oldman" then b:makeOldManDemo(nil, false) end if kind == "safari" then b:makeSafari({ balls = 30, steps = 500 }) end ow:pushBattle(b) assert(waitFor(function() return b.phase == "menu" end, 2500, true), diff --git a/tests/drivers/fixed_extended_world_bag_overlay_test.lua b/tests/drivers/fixed_extended_world_bag_overlay_test.lua index 95855569..009c7f54 100644 --- a/tests/drivers/fixed_extended_world_bag_overlay_test.lua +++ b/tests/drivers/fixed_extended_world_bag_overlay_test.lua @@ -20,7 +20,7 @@ return function(game) U.wait(30) local demo = BattleState.newWild(game, "CHARMANDER", 5) - demo:makeOldManDemo("PROF.OAK") + demo:makeOldManDemo("oak") demo.onFinish = function() end game.overworld:pushBattle(demo) diff --git a/tests/drivers/oak_pikapic_bug557_bug561_test.lua b/tests/drivers/oak_pikapic_bug557_bug561_test.lua index 55ef760b..b28546fc 100644 --- a/tests/drivers/oak_pikapic_bug557_bug561_test.lua +++ b/tests/drivers/oak_pikapic_bug557_bug561_test.lua @@ -55,7 +55,7 @@ return function(game) check("it is Oak's pic, not the old man's", backPath == PROF_BACK) local battle = BattleState.newWild(game, "PIKACHU", 5) - battle:makeOldManDemo("PROF.OAK") + battle:makeOldManDemo("oak") check("the thrower is named PROF.OAK", battle.demoName == "PROF.OAK") check("the battle asks for the BATTLE_TYPE_PIKACHU back pic", battle.oakDemo == true) diff --git a/tests/drivers/oldman_yellow_bug636_test.lua b/tests/drivers/oldman_yellow_bug636_test.lua index ddf36ede..24441570 100644 --- a/tests/drivers/oldman_yellow_bug636_test.lua +++ b/tests/drivers/oldman_yellow_bug636_test.lua @@ -61,7 +61,7 @@ return function(game) local probe = BattleState.newWild(game, (om and om.species) or "RATTATA", (om and om.level) or 5) probe:makeOldManDemo(nil, true) - check("makeOldManDemo(name, true) sets demoFails", probe.demoFails == true) + check("makeOldManDemo(nil, true) sets demoFails", probe.demoFails == true) probe:makeOldManDemo(nil, false) check("and without it the demo still catches, for Red and the reruns", probe.demoFails == false) diff --git a/tests/drivers/yellow_oak_catch_pacing_2817.lua b/tests/drivers/yellow_oak_catch_pacing_2817.lua index b9bae259..de3369f2 100644 --- a/tests/drivers/yellow_oak_catch_pacing_2817.lua +++ b/tests/drivers/yellow_oak_catch_pacing_2817.lua @@ -24,7 +24,7 @@ return function(game) U.wait(10) local battle = BattleState.newWild(game, "PIKACHU", 5) - battle:makeOldManDemo("PROF.OAK") + battle:makeOldManDemo("oak") local menuFrames, cursorItemAt = 0, nil local clearedDuringWait = nil diff --git a/tests/engine/yellow_oak_back_pikapic.lua b/tests/engine/yellow_oak_back_pikapic.lua index abefb2cf..a5218934 100644 --- a/tests/engine/yellow_oak_back_pikapic.lua +++ b/tests/engine/yellow_oak_back_pikapic.lua @@ -4,7 +4,7 @@ -- loads OldManPicBack for BATTLE_TYPE_OLD_MAN but ProfOakPicBack for -- BATTLE_TYPE_PIKACHU, the Pallet Town catch scene, and DisplayBattleMenu -- splits the displayed thrower name on the same wBattleType. The port --- carries that split as makeOldManDemo's name argument. +-- carries that split as makeOldManDemo's kind argument. -- -- #561: TalkToPikachu's framed portrait draws the chosen PikaPicAnimScript's -- own base frame (data/pikachu/pikachu_pic_animation.asm), not the battle @@ -59,12 +59,16 @@ T.eq(Sprites.playerPath(nil, "back", { demo = true, oakDemo = true }), -- makeOldManDemo only fills fields when a player battler already exists, so -- a stub with one stays clear of Pokemon.new and the fixture dataset. -local oak = { player = true } -BattleState.makeOldManDemo(oak, "PROF.OAK") +local names = { text = { + ["DisplayBattleMenu.oldManName"] = "OLD MAN", + ["DisplayBattleMenu.profOakName"] = "PROF.OAK", +} } +local oak = { player = true, data = names } +BattleState.makeOldManDemo(oak, "oak") T.eq(oak.demoName, "PROF.OAK", "the Yellow demo names PROF.OAK as the thrower") T.eq(oak.oakDemo, true, "and asks for his back pic") -local oldMan = { player = true } +local oldMan = { player = true, data = names } BattleState.makeOldManDemo(oldMan) T.eq(oldMan.demoName, "OLD MAN", "the unnamed demo is still the old man") T.eq(oldMan.oakDemo, false, "and does not reach for Oak's pic") @@ -114,6 +118,9 @@ end T.check(extractor:find('self.symbols["ProfOakPicBack"]', 1, true) ~= nil, "the extractor gates Oak's back pic on the ProfOakPicBack symbol") requireSymbols({ "ProfOakPicBack" }, "#557") +requireSymbols({ "DisplayBattleMenu.profOakName" }, "#557 thrower name") +T.check(yellowManifest:find('"DisplayBattleMenu.oldManName"', 1, true) ~= nil, + "rom_manifest_yellow.json carries DisplayBattleMenu.oldManName") local PikachuPicExtractor = require("src.import.PikachuPicExtractor") local pikapic = PikachuPicExtractor.symbolNames() diff --git a/tests/parity_J.lua b/tests/parity_J.lua index c1d7f9b2..3a85e3e0 100644 --- a/tests/parity_J.lua +++ b/tests/parity_J.lua @@ -499,7 +499,7 @@ do } fg.save.party = { Pokemon.new(Data, "BULBASAUR", 20) } local demo = BattleState.newWild(fg, "PIKACHU", 5) - demo:makeOldManDemo("PROF.OAK") + demo:makeOldManDemo("oak") stack:push(demo) demo:enter() for _ = 1, 300 do diff --git a/tools/make_rom_manifest.py b/tools/make_rom_manifest.py index 67bee150..af0ef8dc 100755 --- a/tools/make_rom_manifest.py +++ b/tools/make_rom_manifest.py @@ -537,6 +537,7 @@ DIRECT_SYMBOLS = { "BugIconFrame2", "CircleTile", "CryData", + "DisplayBattleMenu.oldManName", "DoorTileIDPointers", "ED_Tile", "EvosMovesPointerTable", diff --git a/tools/make_yellow_manifest.py b/tools/make_yellow_manifest.py index a7f2a05a..4542e02b 100755 --- a/tools/make_yellow_manifest.py +++ b/tools/make_yellow_manifest.py @@ -85,6 +85,7 @@ YELLOW_EXTRA_SYMBOLS = ( "YellowIntroCloudGFX", "PikachuCriesPointerTable", "CGBBasePalettes", + "DisplayBattleMenu.profOakName", # Jessie & James share the ROCKET trainer class but battle behind their # own pic (home/trainers2.asm IsFightingJessieJames) (#439) "JessieJamesPic", diff --git a/tools/rom_manifest.json b/tools/rom_manifest.json index 0fdef36f..e8ac6f53 100644 --- a/tools/rom_manifest.json +++ b/tools/rom_manifest.json @@ -20198,6 +20198,10 @@ 24, 24418 ], + "DisplayBattleMenu.oldManName": [ + 15, + 20242 + ], "DittoPicBack": [ 11, 17853 diff --git a/tools/rom_manifest_blue.json b/tools/rom_manifest_blue.json index f49cfccc..221611c3 100644 --- a/tools/rom_manifest_blue.json +++ b/tools/rom_manifest_blue.json @@ -20175,6 +20175,10 @@ 24, 24418 ], + "DisplayBattleMenu.oldManName": [ + 15, + 20242 + ], "DittoPicBack": [ 11, 17853 diff --git a/tools/rom_manifest_yellow.json b/tools/rom_manifest_yellow.json index a7c993ce..1bf224c3 100644 --- a/tools/rom_manifest_yellow.json +++ b/tools/rom_manifest_yellow.json @@ -21333,6 +21333,14 @@ 24, 24441 ], + "DisplayBattleMenu.oldManName": [ + 15, + 20455 + ], + "DisplayBattleMenu.profOakName": [ + 15, + 20463 + ], "DittoPicBack": [ 11, 17853