mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-17 11:11:10 +02:00
Make Mon.syncIdentity's shiny recompute monotonic
syncIdentity unconditionally recomputed mon.shiny from the mon's DVs, overwriting whatever was there. It is wired into refreshStats, which SummaryMenu.new calls on every menu open, so a forced shiny -- Mon.new's opts.shiny path, DVs that do not themselves read as shiny -- got un-shinied the moment the summary screen opened, even though opts.shiny already wins over shiny.roll at construction for exactly this case (a scripted shiny is the cart overriding the roll, not a roll to be hooked). mon.shiny now only ever gets PROMOTED by the DV check, never demoted: `mon.shiny or Mon.isShiny(...)`. A naturally shiny mon and a plain one are unaffected -- the DV check still runs and still decides the first time -- and a mon whose DVs are edited to justify shininess later still promotes normally; only an already-true shiny stops being able to flip back to false on a later refresh.
This commit is contained in:
@@ -112,7 +112,13 @@ function Mon.syncIdentity(mon, data)
|
||||
if mon.dvs then
|
||||
mon.gender = Mon.gender(def, mon.dvs,
|
||||
{ species = mon.species, level = mon.level })
|
||||
mon.shiny = Mon.isShiny(mon.dvs,
|
||||
-- shiny is monotonic once true, the same as opts.shiny winning over
|
||||
-- shiny.roll at Mon.new: a forced shiny (the scripted-shiny path, DVs
|
||||
-- that do not themselves read as shiny) must not un-shiny the moment
|
||||
-- this runs again, and it runs on every SummaryMenu open via
|
||||
-- refreshStats. A mon not already shiny still promotes normally if
|
||||
-- its DVs justify it, e.g. after an edit.
|
||||
mon.shiny = mon.shiny or Mon.isShiny(mon.dvs,
|
||||
{ species = mon.species, def = def, level = mon.level })
|
||||
if mon.species == Unown.SPECIES then
|
||||
mon.unownLetter = Unown.letterFromDVs(mon.dvs)
|
||||
|
||||
@@ -468,6 +468,32 @@ do
|
||||
T.eq(forced.shiny, true, "opts.shiny still wins over shiny.roll")
|
||||
end)
|
||||
|
||||
-- Mon.syncIdentity (wired into refreshStats, which SummaryMenu.new calls
|
||||
-- on every menu open) used to recompute mon.shiny from DVs unconditionally,
|
||||
-- so opening the summary screen on a forced shiny -- one whose DVs do not
|
||||
-- happen to match the natural pattern -- un-shinied it the moment the menu
|
||||
-- opened. shiny is monotonic once true: a natural roll or a forced one
|
||||
-- both stay shiny through any later refresh, the way opts.shiny already
|
||||
-- wins at construction.
|
||||
do
|
||||
local forced = Mon.new(DATA, "SEEDMON", 5, { dvs = plainDvs, shiny = true })
|
||||
T.eq(forced.shiny, true, "still shiny straight out of Mon.new")
|
||||
Mon.syncIdentity(forced, DATA)
|
||||
T.eq(forced.shiny, true, "syncIdentity does not clobber a forced shiny")
|
||||
Mon.refreshStats(forced, DATA)
|
||||
T.eq(forced.shiny, true,
|
||||
"refreshStats (SummaryMenu.new's call) does not either")
|
||||
|
||||
-- the natural cases are unaffected: DVs that read shiny stay shiny,
|
||||
-- DVs that do not stay plain
|
||||
local natural = Mon.new(DATA, "SEEDMON", 5, { dvs = shinyDvs })
|
||||
Mon.syncIdentity(natural, DATA)
|
||||
T.eq(natural.shiny, true, "a naturally shiny mon still reads shiny")
|
||||
local plain = Mon.new(DATA, "SEEDMON", 5, { dvs = plainDvs })
|
||||
Mon.syncIdentity(plain, DATA)
|
||||
T.eq(plain.shiny, false, "a plain mon is not promoted to shiny")
|
||||
end
|
||||
|
||||
local genderCtx
|
||||
withHook("gender.roll", function(nextFn, ctx)
|
||||
genderCtx = ctx
|
||||
|
||||
Reference in New Issue
Block a user