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:
sanjinpepic
2026-08-16 20:31:46 +02:00
parent d03d2af5f8
commit 70b9def0b0
2 changed files with 33 additions and 1 deletions
+7 -1
View File
@@ -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)