DopingControl 0.7.0
This commit is contained in:
+154
@@ -0,0 +1,154 @@
|
||||
-- DopingControl core/demo.lua
|
||||
-- Demo mode: the showcase view. It reuses test mode's simulated raid
|
||||
-- (DC_Sim.buildStore -- no second roster exists) and lays its OWN
|
||||
-- expectation table on top so ALL SIX school protection columns
|
||||
-- (FR/FrR/NR/SR/HR/AR) are visible at once.
|
||||
--
|
||||
-- Two hard rules, both of them the reason this file exists at all:
|
||||
--
|
||||
-- 1. The demo layer NEVER writes into db.expectations. Live, five of the
|
||||
-- six school columns ship with no seed entry (data/expectations.lua)
|
||||
-- and are therefore hidden -- that is a deliberate default, and a
|
||||
-- screenshot mode must not rewrite the user's saved matrix to get its
|
||||
-- picture. BuildDemoExpectations deep-copies every line it starts
|
||||
-- from, so no table is ever shared with the DB either.
|
||||
-- 2. Demo state is TRANSIENT -- DC.demoMode / DC.demoExpectations live in
|
||||
-- memory only and are gone after a reload. Deliberately unlike
|
||||
-- db.testMode (which is persisted): the same treatment DC.simRoles
|
||||
-- gets in core/roles.lua, and the BulwarkFrame /bf demo pattern.
|
||||
--
|
||||
-- Why the columns must be forced per (role, class) and not per role: the
|
||||
-- model resolves a row through expect[role][class] and falls back to the
|
||||
-- DC.DEFAULT_EXPECT ROLE line whenever that class line is missing
|
||||
-- (core/model.lua, expectLine) -- a partially filled demo table would fall
|
||||
-- back into the seed and silently lose the school columns again. The same
|
||||
-- fallback drives the dynamic-column check (anyClassExpects), so an
|
||||
-- incomplete layer would also drop the columns from the header.
|
||||
--
|
||||
-- FR is forced too, although the seed already ships it true for all five
|
||||
-- roles: the user may have unchecked it, and "all six schools" is the
|
||||
-- point of the mode.
|
||||
--
|
||||
-- Pure Lua 5.0, no WoW API -- dofile-loadable offline.
|
||||
|
||||
DopingControl = DopingControl or {}
|
||||
local DC = DopingControl
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Transient state (NEVER SavedVariables -- see rule 2 above).
|
||||
-- ------------------------------------------------------------------
|
||||
DC.demoMode = false
|
||||
DC.demoExpectations = nil
|
||||
|
||||
-- DC.demoMode is the demo half of DC.SimOwnsStore (core/config.lua) -- the
|
||||
-- predicate every scan gate asks. It deliberately lives in config.lua, not
|
||||
-- here: config.lua loads second, ahead of every gate, so a broken demo
|
||||
-- module can never take TEST mode's protection down with it.
|
||||
|
||||
-- The six school protection columns of the consumables slot table
|
||||
-- (data/consumables.lua). FR is the only one with a seed entry.
|
||||
DC.DEMO_SCHOOL_SLOTS = { "FR", "FrR", "NR", "SR", "HR", "AR" }
|
||||
|
||||
local function forceSchools(line)
|
||||
local n = table.getn(DC.DEMO_SCHOOL_SLOTS)
|
||||
for i = 1, n do
|
||||
line[DC.DEMO_SCHOOL_SLOTS[i]] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- DC.BuildDemoExpectations(db) -> demo table (also cached in
|
||||
-- DC.demoExpectations)
|
||||
--
|
||||
-- Shape is exactly the live one -- demo[role][class][slotId] -- built per
|
||||
-- (role, performing class) over DC_Roles.ROLE_CLASSES, so it can be handed
|
||||
-- to DC_Model.build in place of db.expectations without any special case
|
||||
-- in the model.
|
||||
--
|
||||
-- Source per class line, in order: the user's saved line, else the
|
||||
-- DC.DEFAULT_EXPECT seed line -- deep-copied either way, then the six
|
||||
-- school slots forced on. A legacy old-shape role line (booleans directly
|
||||
-- under [role], migrated away by DC.EnsureExpectations at ADDON_LOADED)
|
||||
-- is not a table per class and therefore falls back to the seed; demo mode
|
||||
-- showing seed defaults for one session is acceptable, writing into the DB
|
||||
-- to avoid it is not.
|
||||
-- ------------------------------------------------------------------
|
||||
function DC.BuildDemoExpectations(db)
|
||||
local src = db and db.expectations
|
||||
local out = {}
|
||||
local nRoles = table.getn(DC.ROLES)
|
||||
for r = 1, nRoles do
|
||||
local role = DC.ROLES[r]
|
||||
local seedLine = (DC.DEFAULT_EXPECT and DC.DEFAULT_EXPECT[role]) or {}
|
||||
local savedByClass = src and src[role]
|
||||
local classes = (DC_Roles and DC_Roles.ROLE_CLASSES
|
||||
and DC_Roles.ROLE_CLASSES[role]) or {}
|
||||
local nClasses = table.getn(classes)
|
||||
if nClasses > 0 then
|
||||
local byClass = {}
|
||||
for c = 1, nClasses do
|
||||
local cls = classes[c]
|
||||
local saved = savedByClass and savedByClass[cls]
|
||||
local line
|
||||
if type(saved) == "table" then
|
||||
line = DC.DeepCopy(saved)
|
||||
else
|
||||
line = DC.DeepCopy(seedLine)
|
||||
end
|
||||
forceSchools(line)
|
||||
byClass[cls] = line
|
||||
end
|
||||
out[role] = byClass
|
||||
else
|
||||
-- defensive: without DC_Roles there is no class domain to fill,
|
||||
-- so emit the legacy role x slot line (the model falls back to
|
||||
-- the seed for the cells, but the header tooltip and any
|
||||
-- legacy reader still see the schools)
|
||||
local line = DC.DeepCopy(seedLine)
|
||||
forceSchools(line)
|
||||
out[role] = line
|
||||
end
|
||||
end
|
||||
DC.demoExpectations = out
|
||||
return out
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- DC.SetDemoMode(v) -- the switch behind /dc demo and the options button.
|
||||
-- Mirrors DC.SetTestMode (core/init.lua) but touches no SavedVariables.
|
||||
--
|
||||
-- Store handling: entering demo mode swaps in the simulated raid. Leaving
|
||||
-- it hands the store back to the REAL scan -- unless db.testMode is on,
|
||||
-- which owns the simulated store on its own account and must not be kicked
|
||||
-- out of it. DC.SetTestMode mirrors that in the other direction, so neither
|
||||
-- mode can empty the other's showcase; both ask DC.SimOwnsStore
|
||||
-- (core/config.lua), which is also what every scan gate now asks instead
|
||||
-- of db.testMode.
|
||||
-- ------------------------------------------------------------------
|
||||
function DC.SetDemoMode(v)
|
||||
local db = DC.db or DopingControlDB
|
||||
if v then
|
||||
DC.demoMode = true
|
||||
DC.BuildDemoExpectations(db)
|
||||
if DC_Sim and DC_Sim.buildStore then
|
||||
-- buildStore() also refills the transient DC.simRoles -- do NOT
|
||||
-- wipe them afterwards (see DC.SetTestMode)
|
||||
DC.store = DC_Sim.buildStore()
|
||||
end
|
||||
else
|
||||
DC.demoMode = false
|
||||
DC.demoExpectations = nil
|
||||
if not (db and db.testMode) then
|
||||
DC.store = { players = {}, source = "scan" }
|
||||
if DC_Scan and DC_Scan.Start then
|
||||
DC_Scan.Start(true) -- leaving demo mode: immediate rescan
|
||||
end
|
||||
end
|
||||
end
|
||||
if DC_Matrix and DC_Matrix.Refresh then
|
||||
DC_Matrix.Refresh()
|
||||
end
|
||||
if DC_Options and DC_Options.Refresh then
|
||||
DC_Options.Refresh() -- relabels the options button when it is open
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user