mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-26 07:21:22 +02:00
CLOSES #1474, CLOSES #1475, CLOSES #1477, CLOSES #1482, CLOSES #1512, CLOSES #1516, CLOSES #1558, CLOSES #1569, CLOSES #1578, CLOSES #1579
This commit is contained in:
@@ -2969,6 +2969,25 @@ function OverworldState:openPC(onDone)
|
||||
})
|
||||
end
|
||||
|
||||
-- PKMN LEAGUE sits between PROF.OAK's PC and LOG OFF once wNumHoFTeams
|
||||
-- is nonzero (engine/pokemon/bills_pc.asm:5, :49)
|
||||
if #(Game.save.hallOfFame or {}) > 0 then
|
||||
table.insert(items, {
|
||||
label = Strings("<PK><MN>LEAGUE"),
|
||||
keepOpen = true,
|
||||
onSelect = function()
|
||||
-- pc.asm PKMNLeague plays SFX_ENTER_PC, then PKMNLeaguePC prints
|
||||
-- AccessedHoFPCText (engine/menus/pc.asm:67, league_pc.asm:2)
|
||||
require("src.core.Sound").play(Game.data, "Enter_PC")
|
||||
Game.stack:push(TextBox.new(Game,
|
||||
romText(Game.data, "_AccessedHoFPCText",
|
||||
"Accessed POKéMON\nLEAGUE's site.\fAccessed the HALL\nOF FAME List."),
|
||||
function() Screens.push(Game, "LeaguePC") end))
|
||||
done()
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
local hooked = Runtime.call("ui.pc.items", sameItems, Game, items)
|
||||
if type(hooked) == "table" then
|
||||
items = hooked
|
||||
@@ -3366,7 +3385,8 @@ function OverworldState:engageTrainer(npc, onDone, endBattleText, skipBattleText
|
||||
-- checkVictoryRewards pushes the badge/prize box and starts the map's
|
||||
-- onVictory script UNDER whatever runs next, so the player still sees
|
||||
-- EndBattle (now inside the battle), then the reward, then AfterBattle
|
||||
self:checkVictoryRewards(d.trainerClass, d.trainerParty)
|
||||
self:checkVictoryRewards(d.trainerClass, d.trainerParty,
|
||||
endBattleText ~= nil)
|
||||
self:afterBattle(result, battle)
|
||||
if onDone then onDone() end
|
||||
else
|
||||
@@ -3477,7 +3497,10 @@ end
|
||||
-- SetEvent / SetEventRange do after the leader victory.
|
||||
-- `hide` is { { mapId, objName }, ... } -- HideObject on those toggles
|
||||
-- (e.g. Brock victory clears PEWTERCITY_YOUNGSTER / ROUTE22_RIVAL1).
|
||||
function OverworldState:checkVictoryRewards(trainerClass, partyIndex)
|
||||
-- `shownOnBattleScreen`: `dialogue` already rode the battle screen as the
|
||||
-- armed end-battle line (scripts/CeruleanGym.asm:113)
|
||||
function OverworldState:checkVictoryRewards(trainerClass, partyIndex,
|
||||
shownOnBattleScreen)
|
||||
local victories = require("data.scripts.victories")
|
||||
local reward = victories[trainerClass .. "#" .. tostring(partyIndex or 1)]
|
||||
if not reward then return self:runVictoryHook() end
|
||||
@@ -3510,7 +3533,9 @@ function OverworldState:checkVictoryRewards(trainerClass, partyIndex)
|
||||
end
|
||||
local chain = rewardChain()
|
||||
if reward.dialogue then
|
||||
chain.add(reward.dialogue, reward.badgeSound)
|
||||
if not shownOnBattleScreen then
|
||||
chain.add(reward.dialogue, reward.badgeSound)
|
||||
end
|
||||
if reward.item then
|
||||
chain.add(reward.tmPre)
|
||||
if tmGiven then
|
||||
@@ -4423,7 +4448,8 @@ function OverworldState:restoreBattleContinuation(battle, origin)
|
||||
if result == "win" then
|
||||
game.save.defeatedTrainers[origin.npcId] = true
|
||||
if origin.event then game.save.flags[origin.event] = true end
|
||||
self:checkVictoryRewards(battle.oppClass, battle.partyIndex)
|
||||
self:checkVictoryRewards(battle.oppClass, battle.partyIndex,
|
||||
battle.endBattleText ~= nil)
|
||||
end
|
||||
self:afterBattle(result, battle)
|
||||
self.engaging = false
|
||||
|
||||
@@ -391,15 +391,19 @@ end
|
||||
-- Gen 2 moveset lives in `levelMoves` (EvosAttacks). So every scripted gift,
|
||||
-- the STARTER included, arrived knowing nothing: FIGHT listed no moves and the
|
||||
-- battle had no legal action left in it.
|
||||
local function givePokeMon(data, speciesIndex, level, itemIndex)
|
||||
local function givePokeMon(data, speciesIndex, level, itemIndex, opts)
|
||||
local id = speciesByIndex(data.pokemon, speciesIndex)
|
||||
if not id then return nil end
|
||||
return Mon.new(data, id, level or 5, {
|
||||
item = itemIndex and itemIndex ~= 0
|
||||
and itemByIndex(data.items, itemIndex) or nil,
|
||||
nickname = opts and opts.nickname or nil,
|
||||
})
|
||||
end
|
||||
|
||||
-- GivePoke's trainer arm (engine/pokemon/move_mon.asm:1698-1736)
|
||||
local RANDY_OT_ID = 1001
|
||||
|
||||
local function loadGenerated(path)
|
||||
-- Same NX gold/ fallback Game2 uses. World:load is what surfaces
|
||||
-- "Gold cache incomplete" when maps.lua is invisible at the unprefixed path.
|
||||
@@ -997,13 +1001,18 @@ function World:load()
|
||||
setStringBuffer = function(value)
|
||||
if self.game then self.game.stringBuffer = value end
|
||||
end,
|
||||
givePoke = function(speciesIndex, level, item)
|
||||
givePoke = function(speciesIndex, level, item, opts)
|
||||
local data = self.game and self.game.data
|
||||
local save = self.game and self.game.save
|
||||
if not (data and save) then return end
|
||||
save.party = save.party or {}
|
||||
local mon = givePokeMon(data, speciesIndex, level, item)
|
||||
local mon = givePokeMon(data, speciesIndex, level, item, opts)
|
||||
if mon then
|
||||
if opts and opts.otName then
|
||||
mon.ot = opts.otName
|
||||
mon.otName = opts.otName
|
||||
mon.otId = RANDY_OT_ID
|
||||
end
|
||||
-- GivePoke -> TryAddMonToParty -> AddPartyMon (move_mon.asm:44-56, :143-149).
|
||||
Mon.stampOT(save, mon)
|
||||
Party.add(save.party, mon)
|
||||
@@ -1458,13 +1467,11 @@ function World:mapSceneOf(group, mapNum)
|
||||
end
|
||||
|
||||
-- wTimeOfDay (constants/ram_constants.asm): MORN_F 0, DAY_F 1, NITE_F 2,
|
||||
-- DARKNESS_F 3. Palettes.daytimeFor has already resolved the clock and the
|
||||
-- map's own PALETTE_* override into one of four names, so this is a rename
|
||||
-- rather than a second clock.
|
||||
-- DARKNESS_F 3, off the RTC hour (engine/tilesets/timeofday_pals.asm:5-11)
|
||||
local TIME_OF_DAY_ID = { MORN = 0, DAY = 1, NITE = 2, DARK = 3 }
|
||||
|
||||
function World:timeOfDayId()
|
||||
return TIME_OF_DAY_ID[self.daytime or "DAY"] or 1
|
||||
return TIME_OF_DAY_ID[self.tod or self.daytime or "DAY"] or 1
|
||||
end
|
||||
|
||||
-- GetWeekday -> wCurDay, which the RTC counts SUNDAY 0 .. SATURDAY 6 -- the
|
||||
@@ -4369,6 +4376,8 @@ function World:useFieldItem(itemId)
|
||||
if itemId == "SACRED_ASH" then return self:useSacredAsh() end
|
||||
if itemId == "ESCAPE_ROPE" then return self:useEscapeRope(itemId) end
|
||||
if itemId == "SQUIRTBOTTLE" then return self:useSquirtbottle() end
|
||||
-- CoinCaseEffect (engine/items/item_effects.asm:2243).
|
||||
if itemId == "COIN_CASE" then return "coin_case", self:coins() end
|
||||
if REPEL_STEPS[itemId] then return self:useRepel(itemId) end
|
||||
if TROPHY_BOXES[itemId] then return self:openTrophyBox(itemId) end
|
||||
if not World.isRod(itemId, items) then return nil end
|
||||
@@ -5802,7 +5811,9 @@ function World:battleMusicContext(opts)
|
||||
members = trainer and trainer.classId and members
|
||||
and members[trainer.classId] or nil,
|
||||
landmark = self.map and self.map.def and self.map.def.landmark,
|
||||
daytime = self.daytime,
|
||||
-- PlayBattleMusic reads wTimeOfDay (engine/battle/start_battle.asm:24),
|
||||
-- not the map's pinned palette set.
|
||||
daytime = self.tod,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -5999,6 +6010,18 @@ function World:startBattle(opts, onDone)
|
||||
return true
|
||||
end
|
||||
|
||||
-- wWinTextPointer / wLossTextPointer (home/trainers.asm:120), overwritten by
|
||||
-- `winlosstext` (engine/overworld/scripting.asm:651)
|
||||
function World:trainerWinLossText()
|
||||
local vm = self.vm
|
||||
if not vm then return nil, nil end
|
||||
local obj = vm.trainerObject or {}
|
||||
local text = self.text or {}
|
||||
local winKey = vm.winTextOverride or obj.winText
|
||||
local lossKey = vm.lossTextOverride or obj.lossText
|
||||
return winKey and text[winKey] or nil, lossKey and text[lossKey] or nil
|
||||
end
|
||||
|
||||
-- `startbattle` from a script: a trainer record (class + member) or a
|
||||
-- loadwildmon pair. The VM is parked on the yield until onDone fires, so the
|
||||
-- rest of the trainer script (flag set, after-battle text) runs on return.
|
||||
@@ -6057,6 +6080,9 @@ function World:startScriptedBattle(record, wild, onDone)
|
||||
attributes = record.attributes,
|
||||
items = record.items,
|
||||
}
|
||||
-- wWinTextPointer / wLossTextPointer, read by PrintWinLossText on the
|
||||
-- battle screen (home/trainers.asm:230) (#1512)
|
||||
opts.trainer.winText, opts.trainer.lossText = self:trainerWinLossText()
|
||||
elseif wild and wild.species then
|
||||
local id, def = speciesByIndex(data and data.pokemon, wild.species)
|
||||
-- InitEnemyMon `.NotRoaming` / BATTLETYPE.FORCESHINY: the DV pair is
|
||||
@@ -9194,8 +9220,10 @@ function World:stepContext()
|
||||
local def = self.map and self.map.def
|
||||
return {
|
||||
data = self.game and self.game.data,
|
||||
-- CheckTime reads wTimeOfDay (engine/events/checktime.asm:2), so the
|
||||
-- caller windows follow the clock even inside a pinned-palette room.
|
||||
phone = {
|
||||
map = def, maps = self.maps, daytime = self.daytime,
|
||||
map = def, maps = self.maps, daytime = self.tod,
|
||||
clock = self.game and self.game.clock,
|
||||
},
|
||||
-- GetMapPhoneService: zero means the map HAS service, which maps.lua has
|
||||
|
||||
Reference in New Issue
Block a user