Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Join the Playtest on Steam Now: SpiritVale

Module:GameInfo/Skills: Difference between revisions

From SpiritVale Wiki
No edit summary
Tags: Mobile edit Mobile web edit
No edit summary
Tags: Mobile edit Mobile web edit
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
-- Module:GameInfo/Skills
-- Module:GameInfo/Skills
-- Phase 4.1 — Final native-first rendering (schema 1 + schema 2)
-- Phase 4.2 — Final native-first rendering (schema 1 + schema 2)
--
--
-- Notes:
-- Notes:
Line 6: Line 6:
-- - Interactivity is provided by sitewide popup systems in Common.js.
-- - Interactivity is provided by sitewide popup systems in Common.js.
-- - Schema 2 is the primary layout target; schema 1 remains supported.
-- - Schema 2 is the primary layout target; schema 1 remains supported.
-- - Mechanics / keywords are JSON-driven; the renderer does not infer future
--  mechanic definition tokens from labels.


local p = {}
local p = {}
Line 55: Line 57:


local _CORE_ORDER = {
local _CORE_ORDER = {
{ field = "cost",      label = "Cost",      def_tok = "Cast|Cost" },
{ field = "cost",      label = "Cost",      def_tok = "Skill|Cost" },
{ field = "cast_time", label = "Cast Time", def_tok = "Cast|Cast Time" },
{ field = "cast_time", label = "Cast Time", def_tok = "Skill|CastTime" },
{ field = "cooldown",  label = "Cooldown",  def_tok = "Cast|Cooldown" },
{ field = "cooldown",  label = "Cooldown",  def_tok = "Skill|Cooldown" },
{ field = "range",    label = "Range",    def_tok = "Cast|Range" },
{ field = "range",    label = "Range",    def_tok = "Skill|Range" },
{ field = "area",      label = "Area",      def_tok = "Cast|Area" },
{ field = "area",      label = "Area",      def_tok = "Skill|Area" },
{ field = "duration",  label = "Duration",  def_tok = "Cast|Duration" },
{ field = "duration",  label = "Duration",  def_tok = "Skill|Duration" },
}
}


Line 90: Line 92:
s = s:gsub("[^%w]+", "-"):gsub("%-+", "-"):gsub("^%-", ""):gsub("%-$", "")
s = s:gsub("[^%w]+", "-"):gsub("%-+", "-"):gsub("^%-", ""):gsub("%-$", "")
if s == "" then s = "item" end
if s == "" then s = "item" end
return s
end
local function _humanize_key(s)
s = _trim(s)
if s == "" then return "" end
if s:find("%s") then return s end
s = s:gsub("([A-Z]+)([A-Z][a-z])", "%1 %2")
s = s:gsub("([a-z0-9])([A-Z])", "%1 %2")
return s
return s
end
end
Line 258: Line 269:


local _, key = _split_def_token(s)
local _, key = _split_def_token(s)
if key then return key end
if key then return _humanize_key(key) end
return s
return s
end
end
Line 606: Line 617:
local s = _trim(it)
local s = _trim(it)
if s == "" then return nil end
if s == "" then return nil end
return { text = s }
return { text = s, page = s }
end
end


Line 615: Line 626:
if text == "" then return nil end
if text == "" then return nil end
local page = _safe_str(it.page or "", "")
local page = _safe_str(it.page or "", "")
if page == "" then page = text end
local suffix = _safe_str(it.suffix or "", "")
local suffix = _safe_str(it.suffix or "", "")
return { text = text, page = (page ~= "" and page or nil), suffix = (suffix ~= "" and suffix or nil) }
return { text = text, page = (page ~= "" and page or nil), suffix = (suffix ~= "" and suffix or nil) }
Line 1,080: Line 1,092:
fld = _safe_tbl(fld)
fld = _safe_tbl(fld)
local active = _value_has_content(fld.value)
local active = _value_has_content(fld.value)
local resolved_label = _safe_str(fld.label or fld.key, spec.label)
local resolved_tok = _safe_str(fld.label_wt or fld.def_wt, spec.def_tok)


local pill = parent:tag("div")
local pill = parent:tag("div")
Line 1,089: Line 1,103:
:addClass("sv-hover-lift")
:addClass("sv-hover-lift")
:attr("data-core-key", spec.field)
:attr("data-core-key", spec.field)
:attr("aria-label", spec.label)
:attr("aria-label", resolved_label)


pill:addClass(active and "is-active" or "is-inactive")
pill:addClass(active and "is-active" or "is-inactive")
Line 1,106: Line 1,120:
pill:tag("div")
pill:tag("div")
:addClass("sv_skill_scaling__core-label")
:addClass("sv_skill_scaling__core-label")
:wikitext(mw.text.nowiki(spec.label))
:wikitext(mw.text.nowiki(resolved_label))


_build_hitbox(pill, "sv_skill_scaling__core-hit", frame, spec.def_tok)
_build_hitbox(pill, "sv_skill_scaling__core-hit", frame, resolved_tok)
end
end


Line 1,192: Line 1,206:
local function _normalize_modifier_spec(item)
local function _normalize_modifier_spec(item)
item = _safe_tbl(item)
item = _safe_tbl(item)
local label_tok = _safe_str(item.label_wt or item.label or item.key or "", "")
local explicit_tok = _safe_str(item.label_wt or item.def_wt, "")
local label_text = _safe_str(item.label or item.key or item.text, "")
if label_text == "" and explicit_tok ~= "" then
label_text = _display_text_from_token(explicit_tok)
end
return {
return {
label_tok = label_tok,
label_tok = explicit_tok,
label_text = _display_text_from_token(label_tok),
label_text = label_text,
value = item.value,
value = item.value,
}
}
Line 1,234: Line 1,252:
end
end


local function _build_keyword_pill(frame, parent, pill_text)
local function _normalize_keyword_spec(item)
pill_text = _trim(pill_text)
if type(item) == "string" then
if pill_text == "" then return end
local tok = _safe_str(item, "")
local label = tok
if _has_pipe(tok) then
label = _display_text_from_token(tok)
end
return {
label_tok = (_has_pipe(tok) and tok or ""),
label_text = label,
}
end
 
item = _safe_tbl(item)
local tok = _safe_str(item.label_wt or item.def_wt, "")
local label = _safe_str(item.label or item.text or item.key, "")
if label == "" and tok ~= "" then
label = _display_text_from_token(tok)
end
return {
label_tok = tok,
label_text = label,
}
end


local has_def = _has_pipe(pill_text)
local function _build_keyword_pill(frame, parent, item)
local spec = _normalize_keyword_spec(item)
local display_text = _safe_str(spec.label_text, "")
local hit_tok = _safe_str(spec.label_tok, "")
if display_text == "" then return end
 
local has_def = _has_pipe(hit_tok)
local pill = parent:tag("span")
local pill = parent:tag("span")
:addClass("sv-pill")
:addClass("sv-pill")
Line 1,248: Line 1,293:
pill:tag("span")
pill:tag("span")
:addClass("sv-mech-keyword-pill__label")
:addClass("sv-mech-keyword-pill__label")
:wikitext(mw.text.nowiki(_display_text_from_token(pill_text)))
:wikitext(mw.text.nowiki(display_text))


if has_def then
if has_def then
_build_hitbox(pill, "sv-mech-keyword-pill__hit", frame, pill_text)
_build_hitbox(pill, "sv-mech-keyword-pill__hit", frame, hit_tok)
end
end
end
end
Line 1,439: Line 1,484:


if #mechanics_mods == 0 and #mechanics_keywords == 0 then
if #mechanics_mods == 0 and #mechanics_keywords == 0 then
panel:tag("div")
:addClass("sv-tile")
:addClass("sv-tab-empty")
:wikitext("—")
end
end
do
local panel = panels:tag("div")
:addClass("sv-tabpanel")
:addClass("sv-hidden")
:attr("role", "tabpanel")
:attr("data-panel", "effects")
:attr("hidden", "hidden")
if #effects_cards > 0 then
local grid = panel:tag("div"):addClass("sv-ref-grid")
for _, card in ipairs(effects_cards) do
render_ref_card(grid, card)
end
else
panel:tag("div")
panel:tag("div")
:addClass("sv-tile")
:addClass("sv-tile")
Line 1,515: Line 1,581:
local function _build_req_users_native(root_id, requirements_map, users_map)
local function _build_req_users_native(root_id, requirements_map, users_map)
local req_groups = _map_to_groups(requirements_map, { "Skills", "Weapon Types", "Stances" })
local req_groups = _map_to_groups(requirements_map, { "Skills", "Weapon Types", "Stances" })
local usr_groups = _map_to_groups(users_map,        { "Classes", "Summons" })
local usr_groups = _map_to_groups(users_map,        { "Classes", "Monsters", "Summons" })


local req_box, req_n = _build_grouped_disclose(root_id, "req", "Requirements", req_groups)
local req_box, req_n = _build_grouped_disclose(root_id, "req", "Requirements", req_groups)