Compare commits

...

5 Commits

Author SHA1 Message Date
bryanthaboi 25d241f12c Merge pull request #456 from johnjohto/fix-yellow-npc-trades
Fix Yellow NPC trades
2026-07-30 11:26:56 -04:00
johnjohto 7b208043b9 Fix Yellow NPC trades 2026-07-30 10:17:30 -04:00
johnjohto 26dfad0682 Merge remote-tracking branch 'upstream/main' 2026-07-30 10:13:03 -04:00
johnjohto d3010dc060 Merge pull request #1 from johnjohto/fuchsia-swamp-trainer-support
Support custom trainer palettes and base portraits
2026-07-29 23:52:41 -04:00
johnjohto 53e1a535dd Support custom trainer palettes and base portraits 2026-07-29 23:51:10 -04:00
5 changed files with 111 additions and 27 deletions
+23
View File
@@ -38,6 +38,22 @@ local CONSTANT_DEFAULTS = {
},
}
-- data/events/trades.asm in Pokemon Yellow has its own TradeMons table.
-- Old Yellow imports were built from the Red manifest, so correct that
-- table after loading as well as in the fixed import manifest below.
local YELLOW_TRADES = {
{ give = "LICKITUNG", get = "DUGTRIO", dialogset = 1, nickname = "GURIO" },
{ give = "CLEFAIRY", get = "MR_MIME", dialogset = 1, nickname = "MILES" },
{ give = "BUTTERFREE", get = "BEEDRILL", dialogset = 3, nickname = "STINGER" },
{ give = "KANGASKHAN", get = "MUK", dialogset = 1, nickname = "STICKY" },
{ give = "MEW", get = "MEW", dialogset = 3, nickname = "BART" },
{ give = "TANGELA", get = "PARASECT", dialogset = 1, nickname = "SPIKE" },
{ give = "PIDGEOT", get = "PIDGEOT", dialogset = 2, nickname = "MARTY" },
{ give = "GOLDUCK", get = "RHYDON", dialogset = 2, nickname = "BUFFY" },
{ give = "GROWLITHE", get = "DEWGONG", dialogset = 3, nickname = "CEZANNE" },
{ give = "CUBONE", get = "MACHOKE", dialogset = 3, nickname = "RICKY" },
}
-- field.boot is the total-conversion override point for the new game; the
-- values match what SaveData.newGame and the Oak speech used to inline.
local BOOT_DEFAULTS = {
@@ -58,6 +74,12 @@ local function copy(value)
return out
end
function Data:applyVersionedFieldData()
if require("src.core.GameVersion").isYellow() then
self.field.trades = copy(YELLOW_TRADES)
end
end
-- Fills only what the cache is missing, so an importer that learns to
-- stamp one of these keys silently takes over from the engine.
function Data:seedDefaults()
@@ -77,6 +99,7 @@ function Data:seedDefaults()
if constants.dexDigits == nil then
constants.dexDigits = math.max(3, #tostring(constants.dexSize))
end
self:applyVersionedFieldData()
local boot = self.field.boot
if boot == nil then
boot = {}
+59
View File
@@ -0,0 +1,59 @@
-- Pokemon Yellow has a different TradeMons table from Red and Blue.
-- The import manifest must agree, and Data:seedDefaults repairs Yellow
-- caches made before that manifest carried the Yellow table (#453).
package.path = "./?.lua;./?/init.lua;" .. package.path
if not _G.love then _G.love = require("tests.love_stub") end
local Data = require("src.core.Data")
if not (Data.field and Data.field.trades) then Data:load() end
local GameVersion = require("src.core.GameVersion")
local S = require("tests.harness").suite("parity Yellow trades")
local check, eq = S.check, S.eq
local oldVersion = GameVersion.get()
local oldTrades = {}
for i, trade in ipairs(Data.field.trades) do
oldTrades[i] = {}
for key, value in pairs(trade) do oldTrades[i][key] = value end
end
GameVersion.set("yellow")
Data:applyVersionedFieldData()
local expected = {
{ "LICKITUNG", "DUGTRIO", "GURIO" },
{ "CLEFAIRY", "MR_MIME", "MILES" },
{ "BUTTERFREE", "BEEDRILL", "STINGER" },
{ "KANGASKHAN", "MUK", "STICKY" },
{ "MEW", "MEW", "BART" },
{ "TANGELA", "PARASECT", "SPIKE" },
{ "PIDGEOT", "PIDGEOT", "MARTY" },
{ "GOLDUCK", "RHYDON", "BUFFY" },
{ "GROWLITHE", "DEWGONG", "CEZANNE" },
{ "CUBONE", "MACHOKE", "RICKY" },
}
local manifestFile = assert(io.open("tools/rom_manifest_yellow.json", "r"))
local manifest = manifestFile:read("*a")
manifestFile:close()
eq(#Data.field.trades, #expected, "Yellow has ten in-game trade rows")
for i, want in ipairs(expected) do
local got = Data.field.trades[i]
check(got.give == want[1] and got.get == want[2] and got.nickname == want[3],
("Yellow trade %d is %s for %s (%s)"):format(i, want[1], want[2], want[3]))
local row = ('"get": "%s",%%s+"give": "%s",%%s+"nickname": "%s"')
:format(want[2], want[1], want[3])
check(manifest:find(row) ~= nil,
("Yellow manifest carries trade %d"):format(i))
end
local ricky = Data.field.trades[10]
check(ricky.give == "CUBONE" and ricky.get == "MACHOKE",
"the Underground Path trade is Cubone for Machoke")
Data.field.trades = oldTrades
GameVersion.set(oldVersion)
return S:finish()
+1
View File
@@ -3277,6 +3277,7 @@ runSuites(orderedGlob("tests/parity_*.lua", {
"tests/parity_flavor.lua", "tests/parity_trainer_sight.lua",
"tests/parity_static.lua", "tests/parity_trashcans.lua",
"tests/parity_hof.lua", "tests/parity_trade_gift.lua",
"tests/parity_yellow_trades.lua",
"tests/parity_intro.lua", "tests/parity_tilt.lua",
"tests/parity_gbcfx.lua",
}))
+1
View File
@@ -382,6 +382,7 @@ def derive(red, pokeyellow, symbols_path):
except SystemExit as exc:
print(f"warning: parse_credits failed ({exc}); keeping Red credits")
# TODO: hand-author a Yellow credits banner if pret layout drifts.
yellow["field"]["trades"] = field.parse_trades(pokeyellow)
finally:
util.ASM_DEFINES = saved
+27 -27
View File
@@ -10552,63 +10552,63 @@
"trades": [
{
"dialogset": 1,
"get": "NIDORINA",
"give": "NIDORINO",
"nickname": "TERRY"
"get": "DUGTRIO",
"give": "LICKITUNG",
"nickname": "GURIO"
},
{
"dialogset": 1,
"get": "MR_MIME",
"give": "ABRA",
"nickname": "MARCEL"
"give": "CLEFAIRY",
"nickname": "MILES"
},
{
"dialogset": 3,
"get": "BEEDRILL",
"give": "BUTTERFREE",
"nickname": "CHIKUCHIKU"
"nickname": "STINGER"
},
{
"dialogset": 1,
"get": "SEEL",
"give": "PONYTA",
"nickname": "SAILOR"
"get": "MUK",
"give": "KANGASKHAN",
"nickname": "STICKY"
},
{
"dialogset": 3,
"get": "FARFETCHD",
"give": "SPEAROW",
"nickname": "DUX"
"get": "MEW",
"give": "MEW",
"nickname": "BART"
},
{
"dialogset": 1,
"get": "LICKITUNG",
"give": "SLOWBRO",
"nickname": "MARC"
"get": "PARASECT",
"give": "TANGELA",
"nickname": "SPIKE"
},
{
"dialogset": 2,
"get": "JYNX",
"give": "POLIWHIRL",
"nickname": "LOLA"
"get": "PIDGEOT",
"give": "PIDGEOT",
"nickname": "MARTY"
},
{
"dialogset": 2,
"get": "ELECTRODE",
"give": "RAICHU",
"nickname": "DORIS"
"get": "RHYDON",
"give": "GOLDUCK",
"nickname": "BUFFY"
},
{
"dialogset": 3,
"get": "TANGELA",
"give": "VENONAT",
"nickname": "CRINKLES"
"get": "DEWGONG",
"give": "GROWLITHE",
"nickname": "CEZANNE"
},
{
"dialogset": 3,
"get": "NIDORAN_F",
"give": "NIDORAN_M",
"nickname": "SPOT"
"get": "MACHOKE",
"give": "CUBONE",
"nickname": "RICKY"
}
],
"warpCarpets": {