CLOSES #2649, CLOSES #2650, CLOSES #2652, CLOSES #2653, CLOSES #2654, CLOSES #2657, CLOSES #2658, CLOSES #2659, CLOSES #2660, CLOSES #2662, CLOSES #2664, CLOSES #2665, CLOSES #2666, CLOSES #2669, CLOSES #2671, CLOSES #2672, CLOSES #2674, CLOSES #2676, CLOSES #2682, CLOSES #2683, CLOSES #2684, CLOSES #2685, CLOSES #2686, CLOSES #2687, CLOSES #2688, CLOSES #2689

CLOSES #2649, CLOSES #2650, CLOSES #2652, CLOSES #2653, CLOSES #2654, CLOSES #2657, CLOSES #2658, CLOSES #2659, CLOSES #2660, CLOSES #2662, CLOSES #2664, CLOSES #2665, CLOSES #2666, CLOSES #2669, CLOSES #2671, CLOSES #2672, CLOSES #2674, CLOSES #2676, CLOSES #2682, CLOSES #2683, CLOSES #2684, CLOSES #2685, CLOSES #2686, CLOSES #2687, CLOSES #2688, CLOSES #2689
This commit is contained in:
bryanthaboi
2026-10-05 11:06:01 -04:00
parent 160895c6bb
commit 72f2294d8d
110 changed files with 8042 additions and 694 deletions
+5 -25
View File
@@ -1,31 +1,11 @@
-- Route 23's badge-gate guards (pokered scripts/Route23.asm). Each
-- guard/swimmer stands beside the staircase to Victory Road and, when
-- talked to, checks whether the player holds the badge matching that
-- step; the automatic walk-into-the-guard blocking script
-- (Route23DefaultScript / Route23CheckForBadgeScript) is not ported
-- here -- only the talk-triggered text_asm bodies, which share that
-- same subroutine (Route23CheckForBadgeScript) and text
-- (Route23YouDontHaveTheBadgeYetText / Route23OhThatIsTheBadgeText,
-- pokered/text/Route23.asm _Route23YouDontHaveTheBadgeYetText /
-- _Route23OhThatIsTheBadgeText). Once shown the badge, pokered sets
-- EVENT_PASSED_<BADGE>_CHECK so the walk-through gate (when ported)
-- won't re-ask; we mirror that with set_flag for fidelity even though
-- no onStep gate currently reads it.
-- scripts/Route23.asm:153
local M = {}
-- rows: check_item(badge) -> have it? show "Oh! That is the X!" and
-- set EVENT_PASSED_X_CHECK : show "You don't have the X yet!"
-- scripts/Route23.asm:195
local function badgeGuard(badge, passFlag)
local subs = { RAM = badge }
return {
{ "check_item", badge }, -- 1
{ "jump_if_true", 5 }, -- 2
{ "show_text", "_Route23YouDontHaveTheBadgeYetText", subs }, -- 3
{ "jump", 7 }, -- 4 (end)
{ "show_text", "_Route23OhThatIsTheBadgeText", subs }, -- 5
{ "set_flag", passFlag }, -- 6
}
return function(game, ow, npc, done)
ow:route23BadgeCheck(badge, passFlag, done)
end
end
-- Route23SetVictoryRoadBoulders (pokered scripts/Route23.asm:8): every entry
+9 -8
View File
@@ -34,18 +34,19 @@ local function starterBall(askText, species, choseFlag, ownBall,
{ species = species, forceOwned = true } }, -- 5
{ "ask", askText }, -- 6
{ "jump_if_false", "end" }, -- 7
-- scripts/OaksLab.asm:919
{ "show_text", "_OaksLabMonEnergeticText" }, -- 8
-- scripts/OaksLab.asm:918
{ "hide_object", "OAKS_LAB", ownBall }, -- 8
-- scripts/OaksLab.asm:921
{ "show_text", "_OaksLabMonEnergeticText" }, -- 9
-- OaksLab.asm: ReceivedMon (sound_get_key_item) then AddPartyMon; the
-- jingle fires once the box has typed and holds it (#668)
{ "text_sound", "Get_Key_Item" }, -- 9
{ "show_text", "_OaksLabReceivedMonText", { RAM = species } }, -- 10
{ "give_pokemon", species, 5 }, -- 11
{ "set_flag", "EVENT_GOT_STARTER" }, -- 12
{ "set_flag", choseFlag }, -- 13
{ "text_sound", "Get_Key_Item" }, -- 10
{ "show_text", "_OaksLabReceivedMonText", { RAM = species } }, -- 11
{ "give_pokemon", species, 5 }, -- 12
{ "set_flag", "EVENT_GOT_STARTER" }, -- 13
-- POKé BALLs come later, at OaksLabOak1Text's .give_poke_balls beat
-- once the Route 22 rival is beaten (see TEXT_OAKSLAB_OAK1 below)
{ "hide_object", "OAKS_LAB", ownBall }, -- 14
{ "set_flag", choseFlag }, -- 14
-- the rival walks to the countering ball (around the furniture)
{ "move_npc_to", 1, rivalBallX, 4 }, -- 15
{ "face_object", 1, "up" }, -- 16
+7 -5
View File
@@ -1061,7 +1061,8 @@ M.VICTORY_ROAD_3F = {
-- pokered forces the fight on map entry: Agatha's victory arms
-- SCRIPT_CHAMPIONSROOM_PLAYER_ENTERS (scripts/AgathasRoom.asm), and
-- ChampionsRoomPlayerEntersScript then runs RivalEntrance_RLEMovement
-- (up 1, right 1, up 3) before ChampionsRoomRivalReadyToBattleScript.
-- (played back to front: up 3, right 1, up 1) before
-- ChampionsRoomRivalReadyToBattleScript.
-- The rival object has no trainer header / sight range, so without that
-- entrance script the player can walk past (issue #99). We arm on the
-- run flag instead of Agatha's victory bit: same observable effect for
@@ -1090,6 +1091,7 @@ local championsRoomRivalScript = {
-- playBattle("final") then no-ops on the same song, so the theme stays
-- continuous into the fight
{ "play_music", "Music_FinalBattle" }, -- 5
{ "save_end_battle_text", "_RivalDefeatedText" }, -- scripts/ChampionsRoom.asm:65
{ "rival_battle", "OPP_RIVAL3", 1 }, -- 6
-- losing halts here; the numeric target this replaced pointed at the
-- closing warp, which inducted a player who had just lost the fight (#704)
@@ -1098,8 +1100,7 @@ local championsRoomRivalScript = {
{ "set_flag", "EVENT_BEAT_CHAMPION_RIVAL" }, -- 9
-- ChampionsRoomRivalDefeatedScript re-displays TEXT_CHAMPIONSROOM_RIVAL,
-- whose text_asm takes the EVENT_BEAT_CHAMPION_RIVAL branch =
-- _ChampionsRoomRivalAfterBattleText (the in-battle _RivalDefeatedText
-- is the port's generic "<PLAYER> defeated BLUE!" engine line instead).
-- _ChampionsRoomRivalAfterBattleText.
{ "show_text", "_ChampionsRoomRivalAfterBattleText" }, -- 10
-- ChampionsRoomOakArrivesScript: Music_Cities1AlternateTempo
-- (Cities1, kept into HALL_OF_FAME like BIT_NO_MAP_MUSIC after
@@ -1153,10 +1154,11 @@ M.CHAMPIONS_ROOM = {
end
-- RivalEntrance_RLEMovement, then the battle/Oak script (queued
-- separately so talk-script jump indices stay 1-based as written).
-- home/overworld.asm:1844
ow:queueScript({
{ "move_player", "up", 1 },
{ "move_player", "right", 1 },
{ "move_player", "up", 3 },
{ "move_player", "right", 1 },
{ "move_player", "up", 1 },
})
ow:queueScript(championsRoomRivalScript, { npc = rival })
end,
+35 -33
View File
@@ -867,20 +867,19 @@ M.SAFFRON_CITY = {
-- -------------------------------------------------------------------
local function e4ExitSeal(flag, closedBlock, openBlock, dontRunText, autoFlag)
local function door(game, ow)
ow:replaceBlock(2, 0, game.save.flags[flag] and openBlock or closedBlock)
end
local seal = function(game, ow)
local open = game.save.flags[flag]
ow:replaceBlock(2, 0, open and openBlock or closedBlock)
door(game, ow)
-- the auto walk-in on first (south) entry (LoreleiScriptWalkIntoRoom)
if autoFlag and not game.save.flags[autoFlag] and ow.player.cellY >= 10 then
game.save.flags[autoFlag] = true
ow:scriptMove(ow.player, "up", 6)
end
end
-- onVictory re-runs the seal so the door opens right after the
-- battle, like pokered's post-battle map reload
return {
onEnter = seal,
onVictory = seal,
-- retreating toward the entrance gets "Don't run away!" and a
-- shove back up (the entrance coords rows in each room script)
onStep = function(game, ow, x, y)
@@ -892,14 +891,14 @@ local function e4ExitSeal(flag, closedBlock, openBlock, dontRunText, autoFlag)
end))
return true
end,
}
}, door
end
-- Lorelei/Bruno/Agatha EndBattleScript (pokered): EndTrainerBattle then
-- DisplayTextID -> TalkToTrainer, which prints the AfterBattle text on a
-- win. engageTrainer only shows the won line, so wrap talk like Lance /
-- Game Corner Rocket and push header.after immediately after a win.
local function e4LeaderTalk(afterLabel)
local function e4LeaderTalk(afterLabel, door)
return function(game, ow, npc, done)
done = done or function() end
if ow:trainerDefeated(npc) then
@@ -912,26 +911,33 @@ local function e4LeaderTalk(afterLabel)
done()
return
end
-- scripts/AgathasRoom.asm:2
local function reopen()
door(game, ow)
done()
end
local after = text(game)[afterLabel]
if after then push(game, after, done) else done() end
if after then push(game, after, reopen) else reopen() end
end)
end
end
M.LORELEIS_ROOM = e4ExitSeal("EVENT_BEAT_LORELEIS_ROOM_TRAINER_0", 0x24, 0x05,
local loreleiDoor, brunoDoor, agathaDoor
M.LORELEIS_ROOM, loreleiDoor = e4ExitSeal("EVENT_BEAT_LORELEIS_ROOM_TRAINER_0", 0x24, 0x05,
"_LoreleisRoomLoreleiDontRunAwayText", "EVENT_AUTOWALKED_INTO_LORELEIS_ROOM")
M.LORELEIS_ROOM.talk = {
TEXT_LORELEISROOM_LORELEI = e4LeaderTalk("_LoreleisRoomLoreleiAfterBattleText"),
TEXT_LORELEISROOM_LORELEI = e4LeaderTalk("_LoreleisRoomLoreleiAfterBattleText",
loreleiDoor),
}
M.BRUNOS_ROOM = e4ExitSeal("EVENT_BEAT_BRUNOS_ROOM_TRAINER_0", 0x24, 0x05,
M.BRUNOS_ROOM, brunoDoor = e4ExitSeal("EVENT_BEAT_BRUNOS_ROOM_TRAINER_0", 0x24, 0x05,
"_BrunosRoomBrunoDontRunAwayText", "EVENT_AUTOWALKED_INTO_BRUNOS_ROOM")
M.BRUNOS_ROOM.talk = {
TEXT_BRUNOSROOM_BRUNO = e4LeaderTalk("_BrunoAfterBattleText"),
TEXT_BRUNOSROOM_BRUNO = e4LeaderTalk("_BrunoAfterBattleText", brunoDoor),
}
M.AGATHAS_ROOM = e4ExitSeal("EVENT_BEAT_AGATHAS_ROOM_TRAINER_0", 0x3b, 0x0e,
M.AGATHAS_ROOM, agathaDoor = e4ExitSeal("EVENT_BEAT_AGATHAS_ROOM_TRAINER_0", 0x3b, 0x0e,
"_AgathasRoomAgathaDontRunAwayText", "EVENT_AUTOWALKED_INTO_AGATHAS_ROOM")
M.AGATHAS_ROOM.talk = {
TEXT_AGATHASROOM_AGATHA = e4LeaderTalk("_AgathaAfterBattleText"),
TEXT_AGATHASROOM_AGATHA = e4LeaderTalk("_AgathaAfterBattleText", agathaDoor),
}
-- -------------------------------------------------------------------
@@ -953,21 +959,15 @@ M.AGATHAS_ROOM.talk = {
-- (5,11)/(6,11) the doorway -> CheckAndSetEvent
-- EVENT_LANCES_ROOM_LOCK_DOOR: first crossing seals
-- the door behind the player with SFX_GO_INSIDE
-- (24,16) the entrance staircase -> WalkToLance: an auto-walk
-- landing on (6,11). Vanilla WalkToLance_RLEList is
-- up 12 / left 12 / down 7 / left 6 and skips collision
-- through void tiles; our camera follows that literally
-- and briefly shows the empty upper chamber (reads as
-- "Gary's room"). We keep the same landing cell but
-- route along the open-door floor corridor instead.
-- (24,16) the entrance staircase -> WalkToLance
-- -------------------------------------------------------------------
-- Floor corridor (24,16) -> (6,11) with EVENT_LANCES_ROOM_LOCK_DOOR
-- unset (entrance blocks $31/$32). Exposed for parity tests.
local LANCE_WALK_IN = {
{ "down", 2 }, { "left", 6 }, { "down", 5 }, { "left", 10 },
{ "up", 9 }, { "left", 2 }, { "up", 3 },
}
-- scripts/LancesRoom.asm:111
-- home/overworld.asm:1845
local function lanceWalkInRoute(yellow)
return { { "left", 6 }, { "down", 7 }, { "left", 12 }, { "up", yellow and 13 or 12 } }
end
local LANCE_WALK_IN = lanceWalkInRoute(false)
local function lanceEntranceBlocks(game, ow)
local locked = game.save.flags.EVENT_LANCES_ROOM_LOCK_DOOR
@@ -983,15 +983,17 @@ local function lanceLockDoor(game, ow)
end
local function lanceWalkIn(game, ow)
local route = lanceWalkInRoute(require("src.core.GameVersion").isYellow())
local i = 0
local function step()
i = i + 1
local seg = LANCE_WALK_IN[i]
local seg = route[i]
if not seg then
-- lands on (6,11); vanilla's per-frame coord poll then locks the
-- door at once. scriptMove landings do not fire onStep, so lock
-- here.
lanceLockDoor(game, ow)
-- scripts/LancesRoom.asm:82
local p = ow.player
if (p.cellX == 5 or p.cellX == 6) and p.cellY == 11 then
lanceLockDoor(game, ow)
end
return
end
ow:scriptMove(ow.player, seg[1], seg[2], step)
@@ -1001,6 +1003,7 @@ end
M.LANCES_ROOM = {
walkInRoute = LANCE_WALK_IN,
walkInRouteFor = lanceWalkInRoute,
onEnter = function(game, ow)
lanceEntranceBlocks(game, ow)
-- the warp arrival lands ON the staircase trigger, and onStep only
@@ -1019,7 +1022,6 @@ M.LANCES_ROOM = {
if npc.def and npc.def.name == "LANCESROOM_LANCE" then lance = npc break end
end
if not lance or ow:trainerDefeated(lance) then return false end
lance:facePlayer(ow.player)
-- LancesRoomLanceEndBattleScript DisplayTextID -> TalkToTrainer
-- after-battle text (rival became champion first). engageTrainer
-- only shows the won line, so push the after text on a win.