mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 00:10:56 +02:00
Skip the gym leader TM hand-over when the bag is full
The originals run GiveItem before printing the received texts, and when the bag can't hold the TM they print a make-room line instead and leave EVENT_GOT_TM* unset, so talking to the leader again retries the give. The victory reward path added the TM straight into the inventory, so a full bag went to 21/20. Route the gym TM give through Bag.add, split the TM lines out of the victory dialogue table into tmPre/tmDialogue/noRoom, and port the beaten-leader middle branch that re-runs the ReceiveTM script. Saves that already hold the TM without the flag count as received so they don't collect a second copy. Refs #797
This commit is contained in:
+37
-14
@@ -18,6 +18,26 @@ local M = {
|
||||
VIRIDIAN_GYM = { city = "VIRIDIAN CITY", leader = "GIOVANNI", badge = "EARTHBADGE" },
|
||||
}
|
||||
|
||||
-- The originals' middle branch shared by every leader's text_asm: beaten
|
||||
-- but EVENT_GOT_TM* unset means the bag was full when the victory script
|
||||
-- ran GiveItem, so talking to the leader re-runs the ReceiveTM script.
|
||||
-- Returns true when the retry took over the talk. A save from before
|
||||
-- #797 already holds the TM without the flag; treat the owned TM as
|
||||
-- received so those saves fall through to the advice text instead of
|
||||
-- collecting a second copy.
|
||||
local function retryTmGive(game, ow, victoryKey, done)
|
||||
local reward = require("data.scripts.victories")[victoryKey]
|
||||
if not (reward and reward.gotFlag) then return false end
|
||||
if game.save.flags[reward.gotFlag] then return false end
|
||||
local owned = game.save.inventory and game.save.inventory[reward.item] or 0
|
||||
if owned > 0 then
|
||||
game.save.flags[reward.gotFlag] = true
|
||||
return false
|
||||
end
|
||||
ow:offerGymTm(reward, done)
|
||||
return true
|
||||
end
|
||||
|
||||
-- scripts/PewterGym.asm PewterGymBrockText (text_asm): CheckEvent
|
||||
-- EVENT_BEAT_BROCK branches his dialogue. Before the badge he prints
|
||||
-- _PewterGymBrockPreBattleText and engages the leader battle
|
||||
@@ -25,12 +45,14 @@ local M = {
|
||||
-- badge/TM34 rewards and EVENT_BEAT_BROCK come from
|
||||
-- data/scripts/victories.lua OPP_BROCK#1). After the badge his
|
||||
-- .afterBeat branch prints _PewterGymBrockPostBattleAdviceText ("Go to
|
||||
-- the GYM in CERULEAN..."). The original's middle branch (beat but
|
||||
-- TM34 not yet handed over, CheckEventReuseA EVENT_GOT_TM34) is
|
||||
-- unreachable in the port: the TM is granted with the victory.
|
||||
-- the GYM in CERULEAN..."). The middle branch (beat but TM34 not yet
|
||||
-- handed over, CheckEventReuseA EVENT_GOT_TM34 -> call
|
||||
-- PewterGymScriptReceiveTM34) retries the TM give when the bag was full
|
||||
-- at the victory (#797).
|
||||
M.PEWTER_GYM.talk = {
|
||||
TEXT_PEWTERGYM_BROCK = function(game, ow, npc, done)
|
||||
if game.save.flags.EVENT_BEAT_BROCK then
|
||||
if retryTmGive(game, ow, "OPP_BROCK#1", done) then return end
|
||||
local TextBox = require("src.render.TextBox")
|
||||
game.stack:push(TextBox.new(game,
|
||||
game.data.text._PewterGymBrockPostBattleAdviceText
|
||||
@@ -48,16 +70,17 @@ M.PEWTER_GYM.talk = {
|
||||
-- (engageTrainer shows that same pre-battle text via resolveText; the
|
||||
-- badge/TM rewards and the beat flag come from data/scripts/victories.lua)
|
||||
-- -- and once beaten print the post-battle advice text. As with Brock,
|
||||
-- the originals' middle branch (beaten but the TM not yet handed over,
|
||||
-- CheckEventReuseA EVENT_GOT_TM*) is unreachable in the port: the TM is
|
||||
-- granted with the victory.
|
||||
-- the middle branch (beaten but the TM not yet handed over,
|
||||
-- CheckEventReuseA EVENT_GOT_TM*) retries the TM give when the bag was
|
||||
-- full at the victory.
|
||||
-- afterAdvice, when given, takes over `done`: it is handed (game, ow, npc,
|
||||
-- done) and must call done() itself once whatever it's doing (e.g. a fade
|
||||
-- around a HideObject) finishes, rather than having it invoked
|
||||
-- automatically. Only Giovanni's farewell uses this.
|
||||
local function leaderTalk(beatFlag, adviceLabel, fallback, afterAdvice)
|
||||
local function leaderTalk(beatFlag, adviceLabel, fallback, afterAdvice, victoryKey)
|
||||
return function(game, ow, npc, done)
|
||||
if game.save.flags[beatFlag] then
|
||||
if victoryKey and retryTmGive(game, ow, victoryKey, done) then return end
|
||||
local TextBox = require("src.render.TextBox")
|
||||
local finish = done
|
||||
if afterAdvice then
|
||||
@@ -79,42 +102,42 @@ end
|
||||
M.CERULEAN_GYM.talk = {
|
||||
TEXT_CERULEANGYM_MISTY = leaderTalk("EVENT_BEAT_MISTY",
|
||||
"_CeruleanGymMistyTM11ExplanationText",
|
||||
"TM11 teaches\nBUBBLEBEAM!"),
|
||||
"TM11 teaches\nBUBBLEBEAM!", nil, "OPP_MISTY#1"),
|
||||
}
|
||||
|
||||
-- scripts/VermilionGym.asm VermilionGymLTSurgeText .got_tm24_already
|
||||
M.VERMILION_GYM.talk = {
|
||||
TEXT_VERMILIONGYM_LT_SURGE = leaderTalk("EVENT_BEAT_LT_SURGE",
|
||||
"_VermilionGymLTSurgePostBattleAdviceText",
|
||||
"A little word of\nadvice, kid!"),
|
||||
"A little word of\nadvice, kid!", nil, "OPP_LT_SURGE#1"),
|
||||
}
|
||||
|
||||
-- scripts/CeladonGym.asm CeladonGymErikaText .afterBeat
|
||||
M.CELADON_GYM.talk = {
|
||||
TEXT_CELADONGYM_ERIKA = leaderTalk("EVENT_BEAT_ERIKA",
|
||||
"_CeladonGymErikaPostBattleAdviceText",
|
||||
"You are cataloging\nPOKéMON? I must\nsay I'm impressed."),
|
||||
"You are cataloging\nPOKéMON? I must\nsay I'm impressed.", nil, "OPP_ERIKA#1"),
|
||||
}
|
||||
|
||||
-- scripts/FuchsiaGym.asm FuchsiaGymKogaText .afterBeat
|
||||
M.FUCHSIA_GYM.talk = {
|
||||
TEXT_FUCHSIAGYM_KOGA = leaderTalk("EVENT_BEAT_KOGA",
|
||||
"_FuchsiaGymKogaPostBattleAdviceText",
|
||||
"When afflicted by\nTOXIC, POKéMON\nsuffer more and\nmore as battle\nprogresses!"),
|
||||
"When afflicted by\nTOXIC, POKéMON\nsuffer more and\nmore as battle\nprogresses!", nil, "OPP_KOGA#1"),
|
||||
}
|
||||
|
||||
-- scripts/SaffronGym.asm SaffronGymSabrinaText .afterBeat
|
||||
M.SAFFRON_GYM.talk = {
|
||||
TEXT_SAFFRONGYM_SABRINA = leaderTalk("EVENT_BEAT_SABRINA",
|
||||
"_SaffronGymSabrinaPostBattleAdviceText",
|
||||
"Everyone has\npsychic power!\nPeople just don't\nrealize it!"),
|
||||
"Everyone has\npsychic power!\nPeople just don't\nrealize it!", nil, "OPP_SABRINA#1"),
|
||||
}
|
||||
|
||||
-- scripts/CinnabarGym.asm CinnabarGymBlaineText .afterBeat
|
||||
M.CINNABAR_GYM.talk = {
|
||||
TEXT_CINNABARGYM_BLAINE = leaderTalk("EVENT_BEAT_BLAINE",
|
||||
"_CinnabarGymBlainePostBattleAdviceText",
|
||||
"FIRE BLAST is the\nultimate fire\ntechnique!"),
|
||||
"FIRE BLAST is the\nultimate fire\ntechnique!", nil, "OPP_BLAINE#1"),
|
||||
}
|
||||
|
||||
-- scripts/ViridianGym.asm ViridianGymGiovanniText .afterBeat: after the
|
||||
@@ -142,7 +165,7 @@ M.VIRIDIAN_GYM.talk = {
|
||||
"VIRIDIAN_GYM", "VIRIDIANGYM_GIOVANNI")
|
||||
end
|
||||
end, done))
|
||||
end),
|
||||
end, "OPP_GIOVANNI#3"),
|
||||
}
|
||||
|
||||
return M
|
||||
|
||||
@@ -18,6 +18,16 @@
|
||||
-- script). Leaders are not def_trainers entries, so engageTrainer has
|
||||
-- no header.won -- checkVictoryRewards shows this chain instead of a
|
||||
-- synthetic "received badge/TM" stub.
|
||||
--
|
||||
-- Gym entries split the TM hand-over out of `dialogue`, mirroring the
|
||||
-- originals' GiveItem check (`call GiveItem` / `jr nc, .BagFull`):
|
||||
-- `tmPre` is the ReceiveTM script's lead-in (badge info / "Wait! Take
|
||||
-- this!"), shown at the victory and again when a beaten leader retries
|
||||
-- the hand-over; `tmDialogue` shows only when the TM actually goes in
|
||||
-- the bag; `noRoom` is the "make room" line shown instead when the bag
|
||||
-- is full; `gotFlag` (pokered's EVENT_GOT_TM*) is set only on a
|
||||
-- successful give, which is what makes the leader's talk script retry
|
||||
-- later (gyms.lua).
|
||||
|
||||
local function range(prefix, first, last)
|
||||
local t = {}
|
||||
@@ -33,6 +43,8 @@ return {
|
||||
-- escort NPC and the first Route 22 rival stay gone after the badge.
|
||||
["OPP_BROCK#1"] = { badge = "BOULDERBADGE", flag = "EVENT_BEAT_BROCK",
|
||||
item = "TM_BIDE",
|
||||
gotFlag = "EVENT_GOT_TM34",
|
||||
noRoom = "_PewterGymTM34NoRoomText",
|
||||
deactivate = { "EVENT_BEAT_PEWTER_GYM_TRAINER_0" },
|
||||
hide = {
|
||||
{ "PEWTER_CITY", "PEWTERCITY_YOUNGSTER" },
|
||||
@@ -41,69 +53,99 @@ return {
|
||||
dialogue = {
|
||||
"_PewterGymBrockReceivedBoulderBadgeText",
|
||||
"_PewterGymBrockBoulderBadgeInfoText",
|
||||
"_PewterGymBrockWaitTakeThisText",
|
||||
},
|
||||
tmPre = { "_PewterGymBrockWaitTakeThisText" },
|
||||
tmDialogue = {
|
||||
"_PewterGymReceivedTM34Text",
|
||||
"_TM34ExplanationText",
|
||||
} },
|
||||
["OPP_MISTY#1"] = { badge = "CASCADEBADGE", flag = "EVENT_BEAT_MISTY",
|
||||
item = "TM_BUBBLEBEAM",
|
||||
gotFlag = "EVENT_GOT_TM11",
|
||||
noRoom = "_CeruleanGymMistyTM11NoRoomText",
|
||||
deactivate = range("EVENT_BEAT_CERULEAN_GYM_TRAINER_", 0, 1),
|
||||
dialogue = {
|
||||
"_CeruleanGymMistyReceivedCascadeBadgeText",
|
||||
"_CeruleanGymMistyCascadeBadgeInfoText",
|
||||
},
|
||||
tmPre = { "_CeruleanGymMistyCascadeBadgeInfoText" },
|
||||
tmDialogue = {
|
||||
"_CeruleanGymMistyReceivedTM11Text",
|
||||
} },
|
||||
["OPP_LT_SURGE#1"] = { badge = "THUNDERBADGE", flag = "EVENT_BEAT_LT_SURGE",
|
||||
item = "TM_THUNDERBOLT",
|
||||
gotFlag = "EVENT_GOT_TM24",
|
||||
noRoom = "_VermilionGymLTSurgeTM24NoRoomText",
|
||||
deactivate = range("EVENT_BEAT_VERMILION_GYM_TRAINER_", 0, 2),
|
||||
dialogue = {
|
||||
"_VermilionGymLTSurgeReceivedThunderBadgeText",
|
||||
"_VermilionGymLTSurgeThunderBadgeInfoText",
|
||||
},
|
||||
tmPre = { "_VermilionGymLTSurgeThunderBadgeInfoText" },
|
||||
tmDialogue = {
|
||||
"_VermilionGymLTSurgeReceivedTM24Text",
|
||||
"_TM24ExplanationText",
|
||||
} },
|
||||
["OPP_ERIKA#1"] = { badge = "RAINBOWBADGE", flag = "EVENT_BEAT_ERIKA",
|
||||
item = "TM_MEGA_DRAIN",
|
||||
gotFlag = "EVENT_GOT_TM21",
|
||||
noRoom = "_CeladonGymTM21NoRoomText",
|
||||
deactivate = range("EVENT_BEAT_CELADON_GYM_TRAINER_", 0, 6),
|
||||
dialogue = {
|
||||
"_CeladonGymErikaReceivedRainbowBadgeText",
|
||||
"_CeladonGymRainbowBadgeInfoText",
|
||||
},
|
||||
tmPre = { "_CeladonGymRainbowBadgeInfoText" },
|
||||
tmDialogue = {
|
||||
"_CeladonGymReceivedTM21Text",
|
||||
"_TM21ExplanationText",
|
||||
} },
|
||||
["OPP_KOGA#1"] = { badge = "SOULBADGE", flag = "EVENT_BEAT_KOGA",
|
||||
item = "TM_TOXIC",
|
||||
gotFlag = "EVENT_GOT_TM06",
|
||||
noRoom = "_FuchsiaGymKogaTM06NoRoomText",
|
||||
deactivate = range("EVENT_BEAT_FUCHSIA_GYM_TRAINER_", 0, 5),
|
||||
dialogue = {
|
||||
"_FuchsiaGymKogaReceivedSoulBadgeText",
|
||||
"_FuchsiaGymKogaSoulBadgeInfoText",
|
||||
},
|
||||
tmPre = { "_FuchsiaGymKogaSoulBadgeInfoText" },
|
||||
tmDialogue = {
|
||||
"_FuchsiaGymKogaReceivedTM06Text",
|
||||
"_FuchsiaGymKogaTM06ExplanationText",
|
||||
} },
|
||||
["OPP_SABRINA#1"] = { badge = "MARSHBADGE", flag = "EVENT_BEAT_SABRINA",
|
||||
item = "TM_PSYWAVE",
|
||||
gotFlag = "EVENT_GOT_TM46",
|
||||
noRoom = "_SaffronGymSabrinaTM46NoRoomText",
|
||||
deactivate = range("EVENT_BEAT_SAFFRON_GYM_TRAINER_", 0, 6),
|
||||
dialogue = {
|
||||
"_SaffronGymSabrinaReceivedMarshBadgeText",
|
||||
"_SaffronGymSabrinaMarshBadgeInfoText",
|
||||
},
|
||||
tmPre = { "_SaffronGymSabrinaMarshBadgeInfoText" },
|
||||
tmDialogue = {
|
||||
"_SaffronGymSabrinaReceivedTM46Text",
|
||||
"_TM46ExplanationText",
|
||||
} },
|
||||
["OPP_BLAINE#1"] = { badge = "VOLCANOBADGE", flag = "EVENT_BEAT_BLAINE",
|
||||
item = "TM_FIRE_BLAST",
|
||||
gotFlag = "EVENT_GOT_TM38",
|
||||
noRoom = "_CinnabarGymBlaineTM38NoRoomText",
|
||||
deactivate = range("EVENT_BEAT_CINNABAR_GYM_TRAINER_", 0, 6),
|
||||
dialogue = {
|
||||
"_CinnabarGymBlaineReceivedVolcanoBadgeText",
|
||||
"_CinnabarGymBlaineVolcanoBadgeInfoText",
|
||||
},
|
||||
tmPre = { "_CinnabarGymBlaineVolcanoBadgeInfoText" },
|
||||
tmDialogue = {
|
||||
"_CinnabarGymBlaineReceivedTM38Text",
|
||||
"_CinnabarGymBlaineTM38ExplanationText",
|
||||
} },
|
||||
["OPP_GIOVANNI#3"] = { badge = "EARTHBADGE", flag = "EVENT_BEAT_GIOVANNI",
|
||||
item = "TM_FISSURE",
|
||||
gotFlag = "EVENT_GOT_TM27",
|
||||
noRoom = "_ViridianGymGiovanniTM27NoRoomText",
|
||||
deactivate = range("EVENT_BEAT_VIRIDIAN_GYM_TRAINER_", 0, 7),
|
||||
dialogue = {
|
||||
"_ViridianGymGiovanniReceivedEarthBadgeText",
|
||||
"_ViridianGymGiovanniEarthBadgeInfoText",
|
||||
},
|
||||
tmPre = { "_ViridianGymGiovanniEarthBadgeInfoText" },
|
||||
tmDialogue = {
|
||||
"_ViridianGymGiovanniReceivedTM27Text",
|
||||
"_ViridianGymGiovanniTM27ExplanationText",
|
||||
} },
|
||||
|
||||
@@ -234,8 +234,12 @@ What was ported from pokered's engine code and where it came from.
|
||||
pre-battle text and engages the leader battle (badge/TM via
|
||||
data/scripts/victories.lua); post-badge talk prints the leader's
|
||||
post-battle advice text (Misty's is her TM11 explanation). The
|
||||
originals' middle branch (beaten but TM not handed over) is
|
||||
unreachable since the TM is granted with the victory. Giovanni's
|
||||
originals' middle branch (beaten but TM not handed over,
|
||||
CheckEventReuseA EVENT_GOT_TM*) is ported too: the victory's GiveItem
|
||||
goes through the bag's capacity check, a full bag shows the leader's
|
||||
"make room" text instead of the received lines and leaves
|
||||
EVENT_GOT_TM* unset, and talking to the leader re-runs the ReceiveTM
|
||||
script until the TM goes in (#797). Giovanni's
|
||||
farewell (`ViridianGymGiovanniText` .afterBeat) hides him inside a
|
||||
fade-to-black/fade-in Transition matching ViridianGym.asm's
|
||||
GBFadeOutToBlack → HideObject → GBFadeInFromBlack, persisted
|
||||
|
||||
@@ -3003,6 +3003,22 @@ function OverworldState:engageTrainer(npc, onDone)
|
||||
end))
|
||||
end
|
||||
|
||||
-- Shared GiveItem step for the victory rewards (pokered home/give.asm):
|
||||
-- the item goes through the bag's capacity check, and only a successful
|
||||
-- add sets the reward's gotFlag (EVENT_GOT_TM*) and copies the item name
|
||||
-- into wStringBuffer for the "{RAM:wStringBuffer}" received texts.
|
||||
local function giveVictoryItem(reward)
|
||||
if not require("src.inventory.Bag").add(Game.save, reward.item, 1, Game.data) then
|
||||
return false
|
||||
end
|
||||
if reward.gotFlag then
|
||||
Game.save.flags[reward.gotFlag] = true
|
||||
end
|
||||
local idef = Game.data.items[reward.item]
|
||||
Game.stringBuffer = idef and idef.name or reward.item
|
||||
return true
|
||||
end
|
||||
|
||||
-- Badges/items awarded after specific battles (data/scripts/victories.lua).
|
||||
-- `deactivate` retires unfought gym/dojo trainers the way the originals'
|
||||
-- SetEvent / SetEventRange do after the leader victory.
|
||||
@@ -3031,12 +3047,13 @@ function OverworldState:checkVictoryRewards(trainerClass, partyIndex)
|
||||
if reward.badge then
|
||||
Game.save.inventory[reward.badge] = 1
|
||||
end
|
||||
local tmGiven = false
|
||||
if reward.item then
|
||||
local inv = Game.save.inventory
|
||||
inv[reward.item] = (inv[reward.item] or 0) + 1
|
||||
local idef = Game.data.items[reward.item]
|
||||
-- GiveItem -> CopyToStringBuffer for "{RAM:wStringBuffer}" received texts
|
||||
Game.stringBuffer = idef and idef.name or reward.item
|
||||
-- pokered GiveItem (home/give.asm): AddItemToInventory first, and a
|
||||
-- full bag (jr nc, .BagFull) skips the received lines for the "make
|
||||
-- room" text, leaving EVENT_GOT_TM* unset so the leader's talk script
|
||||
-- retries the hand-over later (offerGymTm via gyms.lua)
|
||||
tmGiven = giveVictoryItem(reward)
|
||||
end
|
||||
local lines = {}
|
||||
if reward.dialogue then
|
||||
@@ -3046,13 +3063,29 @@ function OverworldState:checkVictoryRewards(trainerClass, partyIndex)
|
||||
table.insert(lines, text[label])
|
||||
end
|
||||
end
|
||||
if reward.item then
|
||||
for _, label in ipairs(reward.tmPre or {}) do
|
||||
if text[label] and text[label] ~= "" then
|
||||
table.insert(lines, text[label])
|
||||
end
|
||||
end
|
||||
if tmGiven then
|
||||
for _, label in ipairs(reward.tmDialogue or {}) do
|
||||
if text[label] and text[label] ~= "" then
|
||||
table.insert(lines, text[label])
|
||||
end
|
||||
end
|
||||
elseif reward.noRoom and text[reward.noRoom] and text[reward.noRoom] ~= "" then
|
||||
table.insert(lines, text[reward.noRoom])
|
||||
end
|
||||
end
|
||||
elseif reward.badge or reward.item then
|
||||
if reward.badge then
|
||||
local name = Game.data.items[reward.badge] and Game.data.items[reward.badge].name
|
||||
or reward.badge
|
||||
table.insert(lines, Strings("%s received\nthe %s!", Game.save.player.name, name))
|
||||
end
|
||||
if reward.item then
|
||||
if tmGiven then
|
||||
local name = Game.stringBuffer or reward.item
|
||||
table.insert(lines, Strings("%s received\n%s!", Game.save.player.name, name))
|
||||
end
|
||||
@@ -3063,6 +3096,33 @@ function OverworldState:checkVictoryRewards(trainerClass, partyIndex)
|
||||
self:runVictoryHook()
|
||||
end
|
||||
|
||||
-- A beaten leader re-running their ReceiveTM script when the bag was full
|
||||
-- at the victory (pokered's middle branch, e.g. PewterGymBrockText
|
||||
-- CheckEventReuseA EVENT_GOT_TM34 -> call PewterGymScriptReceiveTM34).
|
||||
-- The script's lead-in lines (tmPre: badge info / "Wait! Take this!")
|
||||
-- show again, then the same GiveItem check decides between the received
|
||||
-- lines and the "make room" text.
|
||||
function OverworldState:offerGymTm(reward, done)
|
||||
local text = Game.data.text or {}
|
||||
local lines = {}
|
||||
local function addLine(label)
|
||||
if label and text[label] and text[label] ~= "" then
|
||||
table.insert(lines, text[label])
|
||||
end
|
||||
end
|
||||
for _, label in ipairs(reward.tmPre or {}) do addLine(label) end
|
||||
if giveVictoryItem(reward) then
|
||||
for _, label in ipairs(reward.tmDialogue or {}) do addLine(label) end
|
||||
else
|
||||
addLine(reward.noRoom)
|
||||
end
|
||||
if #lines > 0 then
|
||||
Game.stack:push(TextBox.new(Game, table.concat(lines, "\f"), done))
|
||||
elseif done then
|
||||
done()
|
||||
end
|
||||
end
|
||||
|
||||
-- pokered reloads the map after every battle, re-running the map
|
||||
-- script (e.g. LoreleiShowOrHideExitBlock); this hook is the port's
|
||||
-- equivalent so seals/toggles refresh without leaving the map
|
||||
|
||||
+60
-4
@@ -183,7 +183,7 @@ do
|
||||
new = function(game, text, done) return { text = text, onDone = done } end,
|
||||
}
|
||||
|
||||
local function driveLeader(mapId, textConst, beatFlag)
|
||||
local function driveLeader(mapId, textConst, beatFlag, gotFlag)
|
||||
local pushed, engaged
|
||||
local game = {
|
||||
save = { flags = {} },
|
||||
@@ -198,6 +198,9 @@ do
|
||||
mapId .. " leader talk (no badge) engages the leader battle")
|
||||
engaged, pushed = nil, nil
|
||||
game.save.flags[beatFlag] = true
|
||||
-- the advice/farewell branch is pokered's .afterBeat, reached only
|
||||
-- once EVENT_GOT_TM* is set (the TM went into the bag)
|
||||
if gotFlag then game.save.flags[gotFlag] = true end
|
||||
local state = {}
|
||||
script(game, ow, { def = {} }, function() state.doneCalled = true end)
|
||||
check(pushed and not engaged,
|
||||
@@ -206,17 +209,17 @@ do
|
||||
end
|
||||
|
||||
local _, box = driveLeader("CERULEAN_GYM", "TEXT_CERULEANGYM_MISTY",
|
||||
"EVENT_BEAT_MISTY")
|
||||
"EVENT_BEAT_MISTY", "EVENT_GOT_TM11")
|
||||
eq(box and box.text, Data.text._CeruleanGymMistyTM11ExplanationText,
|
||||
"Misty (beaten) shows the TM11 explanation text")
|
||||
|
||||
_, box = driveLeader("CINNABAR_GYM", "TEXT_CINNABARGYM_BLAINE",
|
||||
"EVENT_BEAT_BLAINE")
|
||||
"EVENT_BEAT_BLAINE", "EVENT_GOT_TM38")
|
||||
eq(box and box.text, Data.text._CinnabarGymBlainePostBattleAdviceText,
|
||||
"Blaine (beaten) shows his post-battle advice text")
|
||||
|
||||
local game, gbox, state = driveLeader("VIRIDIAN_GYM", "TEXT_VIRIDIANGYM_GIOVANNI",
|
||||
"EVENT_BEAT_GIOVANNI")
|
||||
"EVENT_BEAT_GIOVANNI", "EVENT_GOT_TM27")
|
||||
eq(gbox and gbox.text, Data.text._ViridianGymGiovanniPostBattleAdviceText,
|
||||
"Giovanni (beaten) shows his farewell text")
|
||||
|
||||
@@ -392,6 +395,59 @@ do
|
||||
check(cinnabarNpc and ow:trainerDefeated(cinnabarNpc),
|
||||
"unfought Cinnabar trainer is defeated via seeded header event")
|
||||
|
||||
-- #797: a full bag at the victory skips the TM hand-over (pokered's
|
||||
-- `call GiveItem` / `jr nc, .BagFull`): badge and beat flag still land,
|
||||
-- but EVENT_GOT_TM34 stays unset and the "make room" line replaces the
|
||||
-- received/explanation texts. Talking to Brock afterwards re-runs the
|
||||
-- ReceiveTM script and grants the TM once there is room.
|
||||
while Game.stack:top() do Game.stack:pop() end
|
||||
Game.save = SaveData.newGame()
|
||||
Game.save.flags = {}
|
||||
Game.save.inventory = {}
|
||||
Game.save.defeatedTrainers = {}
|
||||
local Bag = require("src.inventory.Bag")
|
||||
for i = 1, Bag.capacity(Data) do
|
||||
Bag.add(Game.save, "FULLBAG_" .. i, 1, Data)
|
||||
end
|
||||
eq(Bag.slots(Game.save), Bag.capacity(Data), "bag is full before Brock")
|
||||
Game.stack:push(OW, "PEWTER_GYM", 4, 13, "up")
|
||||
ow = Game.stack:top()
|
||||
ow:checkVictoryRewards("OPP_BROCK", 1)
|
||||
local fullBagText = stackedDialogue()
|
||||
check(Game.save.flags.EVENT_BEAT_BROCK,
|
||||
"full bag: Brock victory still sets EVENT_BEAT_BROCK")
|
||||
check(Game.save.inventory.BOULDERBADGE == 1,
|
||||
"full bag: Brock victory still awards BOULDERBADGE")
|
||||
check(not Game.save.flags.EVENT_GOT_TM34,
|
||||
"full bag: EVENT_GOT_TM34 stays unset (bag_full branch)")
|
||||
check(Game.save.inventory.TM_BIDE == nil,
|
||||
"full bag: TM34 is not forced into the bag")
|
||||
check(fullBagText:find("room", 1, true) ~= nil,
|
||||
"full bag: victory dialogue shows Brock's make-room line")
|
||||
check(fullBagText:find("BIDE", 1, true) == nil,
|
||||
"full bag: received/explanation texts are skipped")
|
||||
|
||||
-- make room, then talk to Brock: the middle branch re-runs ReceiveTM34
|
||||
while Game.stack:top() do Game.stack:pop() end
|
||||
Bag.remove(Game.save, "FULLBAG_1", 1)
|
||||
local brockTalk = init.talkScript("PEWTER_GYM", "TEXT_PEWTERGYM_BROCK")
|
||||
check(brockTalk ~= nil, "Brock's talk script is registered")
|
||||
brockTalk(Game, ow, { def = {} }, function() end)
|
||||
local retryText = stackedDialogue()
|
||||
check(retryText:find("Wait!", 1, true) ~= nil,
|
||||
"retry: ReceiveTM34 lead-in (Wait! Take this!) shows again")
|
||||
check(retryText:find("BIDE", 1, true) ~= nil,
|
||||
"retry: received/explanation texts show once the TM fits")
|
||||
eq(Game.save.inventory.TM_BIDE, 1, "retry: TM34 goes into the bag")
|
||||
check(Game.save.flags.EVENT_GOT_TM34, "retry: EVENT_GOT_TM34 is set")
|
||||
|
||||
-- once the TM is handed over, Brock falls back to his advice text
|
||||
while Game.stack:top() do Game.stack:pop() end
|
||||
brockTalk(Game, ow, { def = {} }, function() end)
|
||||
local adviceText = stackedDialogue()
|
||||
check(adviceText:find("CERULEAN", 1, true) ~= nil,
|
||||
"after the TM: Brock shows his post-battle advice text")
|
||||
|
||||
while Game.stack:top() do Game.stack:pop() end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user