Module:HatchMinistryNarrative: Difference between revisions

From MicrasWiki
Jump to navigationJump to search
NewZimiaGov (talk | contribs)
Created page with "local p = {} local ops = require("Module:HatchMinistryDailyOps") local cal = require("Module:BassaridianCalendar") local function cityLink(name) return string.format("%s", name, name) end local function captainLink(data) local page = string.format("Captain_%s_%s", data.captain.first, data.captain.last) if data.captain.nick and tostring(data.captain.nick) ~= "" then return string.format("[[%s|Captain %s ''‘%s..."
 
NewZimiaGov (talk | contribs)
No edit summary
 
(One intermediate revision by the same user not shown)
Line 2: Line 2:


local ops = require("Module:HatchMinistryDailyOps")
local ops = require("Module:HatchMinistryDailyOps")
local cal = require("Module:BassaridianCalendar")


local function cityLink(name)
local function cityLink(name)
Line 16: Line 15:
end
end


local function sevPhrase(sev)
local function sevPhrase(sev, captainName)
   sev = tostring(sev or ""):lower()
   sev = tostring(sev or ""):lower()
  if captainName == "ayshe temirkhan" then
    if sev == "red" then
      return "under a red enforcement posture"
    elseif sev == "yellow" then
      return "under a tightened yellow enforcement posture"
    end
    return "under a green but watchful enforcement posture"
  end
   if sev == "red" then
   if sev == "red" then
     return "under a red operations posture"
     return "under a red operations posture"
Line 26: Line 34:
end
end


local function domainPhrase(domain)
local function domainPhrase(domain, captainName)
   domain = tostring(domain or ""):lower()
   domain = tostring(domain or ""):lower()
  if captainName == "ayshe temirkhan" then
    if domain == "rail" then
      return "directing rail-domain corridor operations"
    elseif domain == "sea" then
      return "directing sea-domain corridor operations"
    end
    return "directing corridor operations"
  end
   if domain == "rail" then
   if domain == "rail" then
     return "rail-domain operations"
     return "conducting rail-domain operations"
   elseif domain == "sea" then
   elseif domain == "sea" then
     return "sea-domain operations"
     return "conducting sea-domain operations"
   end
   end
   return "corridor operations"
   return "conducting corridor operations"
end
end


local function weatherSentence(weather)
local function expandTask(task, captainName)
   if not weather or not weather.alert then
  task = mw.text.trim(tostring(task or ""))
   if task == "" then
     return ""
     return ""
   end
   end


   local label = weather.alert.label or "Green"
   if captainName == "ayshe temirkhan" then
  local hazard = weather.alert.hazard or weather.condition or ""
    local t = mw.ustring.lower(task)
   local condition = weather.condition or ""
    local pieces = {}
 
    if t:find("seal") then
      table.insert(pieces, "close seal scrutiny and aggressive registry verification")
    end
    if t:find("diversion") or t:find("shadow") then
      table.insert(pieces, "suppression of shadow transfers and suspected diversion chains")
    end
    if t:find("crowd") or t:find("platform") or t:find("queue") then
      table.insert(pieces, "platform pressure and controlled station clearing under enforcement conditions")
    end
    if t:find("smuggl") then
      table.insert(pieces, "counter-smuggling sweeps and selective freight detention")
    end
    if t:find("yard") or t:find("intermodal") then
      table.insert(pieces, "predatory inspection work across yards, sidings, and transfer points")
    end
    if t:find("manifest") or t:find("ledger") or t:find("registry") then
      table.insert(pieces, "hard-line manifest scrutiny and punitive registry control")
    end
    if t:find("maintenance") then
      table.insert(pieces, "escorted control over rail access and maintenance movement")
    end
 
    if #pieces == 0 then
      return "Her reported activity centers on " .. task .. "."
    end
 
    return "Her reported activity centers on " .. table.concat(pieces, ", ") .. "."
  end
 
   return "The day’s activity centers on " .. task .. "."
end


   if label == "Green" and condition == "" and hazard == "" then
local function weatherSentence(weather, captainName)
   if not weather or not weather.alert then
     return ""
     return ""
   end
   end


   local bits = {}
   local label = tostring(weather.alert.label or "")
   if label and label ~= "" then
  local hazard = tostring(weather.alert.hazard or "")
     table.insert(bits, label .. " weather posture")
  local condition = tostring(weather.condition or "")
 
  local desc = hazard
  if desc == "" then desc = condition end
  if desc == "" then return "" end
 
   if captainName == "ayshe temirkhan" then
     return string.format(
      " Local weather conditions remain a meaningful factor, with %s conditions reinforcing tighter movement control, harsher release windows, and greater suspicion toward delay, congestion, and low-visibility disruptions.",
      desc
    )
   end
   end
   if hazard and hazard ~= "" then
 
     table.insert(bits, hazard)
   return string.format(
  elseif condition and condition ~= "" then
    " Local weather conditions are reported as %s%s.",
    table.insert(bits, condition)
     desc,
    (label ~= "" and (" under a " .. label .. " weather posture") or "")
  )
end
 
local function rotationSentence(data, captainName)
  if not tonumber(data.dayInBlock) or not tonumber(data.blockLen) then
    return ""
   end
   end


   if #bits == 0 then
   if captainName == "ayshe temirkhan" then
     return ""
     return string.format(
      " She is on day %d of a %d-day rotational block, though in practice her rotation is understood less as routine patrol than as sustained pressure along the Caledonian line.",
      tonumber(data.dayInBlock),
      tonumber(data.blockLen)
    )
   end
   end


   return " Local weather conditions are reported as " .. table.concat(bits, ", ") .. "."
   return string.format(
    " This places the captain on day %d of a %d-day rotational block within the wider Hatch Ministry security circuit.",
    tonumber(data.dayInBlock),
    tonumber(data.blockLen)
  )
end
end


local function taskSentence(task)
local function captainSpecificClosing(data, captainName)
  task = tostring(task or "")
   if captainName ~= "ayshe temirkhan" then
   if task == "" then
     return ""
     return ""
   end
   end
   return " Her reported activity for the day centers on " .. mw.text.trim(task) .. "."
 
  local station = tostring(data.station or "")
  local stationLink = cityLink(station)
 
   return " The effect is less that of ordinary rail security than of deliberate corridor pressure, consistent with Temirkhan’s reputation for turning administrative irregularity, suspect freight, and station disorder into opportunities for seizure, intimidation, and exemplary enforcement at " .. stationLink .. "."
end
end


function p.captainParagraph(frame)
function p.captainParagraph(frame)
   local args = (frame and frame.args) or {}
   local args = (frame and frame.args) or {}
   local captain = args.captain
   local captain = mw.text.trim(tostring(args.captain or ""))
   local year = args.year
   if captain == "" then
   local day = args.day
    return "No captain specified."
   end


   local data = ops.getCaptainAssignmentData(captain, year, day)
   local data = ops.getCaptainAssignmentData(captain, args.year, args.day)
   if not data then
   if not data then
     return "No matching captain assignment could be found."
     return "No matching captain assignment could be found."
   end
   end


   local calPart = ""
   local captainLower = mw.ustring.lower(captain)
  if data.calendar and data.calendar ~= "" then
    calPart = string.format(" (%s)", data.calendar)
  end


   local parts = {}
   local intro = string.format(
 
    "On %d/%d PSSC, %s is operating out of %s, away from the captain’s home base in %s, %s and %s along the Caledonian reaches of the [[Trans-Morovian Express]].",
  table.insert(
    data.day,
    parts,
    data.year,
    string.format(
    captainLink(data),
      "On %d/%d PSSC%s, %s is operating out of %s, away from her home base in %s, %s and conducting %s along the Caledonian reaches of the [[Trans-Morovian Express]].",
    cityLink(data.station),
      data.day,
    cityLink(data.home),
      data.year,
    sevPhrase(data.severity, captainLower),
      calPart,
    domainPhrase(data.domain, captainLower)
      captainLink(data),
      cityLink(data.station),
      cityLink(data.home),
      sevPhrase(data.severity),
      domainPhrase(data.domain)
    )
   )
   )


   local taskPart = taskSentence(data.task)
   local taskPart = expandTask(data.task, captainLower)
   if taskPart ~= "" then
   local rotationPart = rotationSentence(data, captainLower)
    table.insert(parts, taskPart)
  local weatherPart = weatherSentence(data.weather, captainLower)
   end
   local closingPart = captainSpecificClosing(data, captainLower)


   if tonumber(data.dayInBlock) and tonumber(data.blockLen) then
  local out = {intro}
    table.insert(
   if taskPart ~= "" then table.insert(out, taskPart) end
      parts,
  if rotationPart ~= "" then table.insert(out, rotationPart) end
      string.format(
   if weatherPart ~= "" then table.insert(out, weatherPart) end
        "This places her on day %d of a %d-day rotational block within the wider Hatch Ministry security circuit.",
   if closingPart ~= "" then table.insert(out, closingPart) end
        tonumber(data.dayInBlock),
        tonumber(data.blockLen)
      )
    )
  end
 
   local wxPart = weatherSentence(data.weather)
   if wxPart ~= "" then
    table.insert(parts, wxPart)
  end


   return table.concat(parts, " ")
   return table.concat(out, " ")
end
end


return p
return p

Latest revision as of 17:22, 28 March 2026

Documentation for this module may be created at Module:HatchMinistryNarrative/doc

local p = {}

local ops = require("Module:HatchMinistryDailyOps")

local function cityLink(name)
  return string.format("[[List_of_cities_in_Bassaridia_Vaeringheim#%s|%s]]", name, name)
end

local function captainLink(data)
  local page = string.format("Captain_%s_%s", data.captain.first, data.captain.last)
  if data.captain.nick and tostring(data.captain.nick) ~= "" then
    return string.format("[[%s|Captain %s ''‘%s’'' %s]]", page, data.captain.first, data.captain.nick, data.captain.last)
  end
  return string.format("[[%s|Captain %s %s]]", page, data.captain.first, data.captain.last)
end

local function sevPhrase(sev, captainName)
  sev = tostring(sev or ""):lower()
  if captainName == "ayshe temirkhan" then
    if sev == "red" then
      return "under a red enforcement posture"
    elseif sev == "yellow" then
      return "under a tightened yellow enforcement posture"
    end
    return "under a green but watchful enforcement posture"
  end

  if sev == "red" then
    return "under a red operations posture"
  elseif sev == "yellow" then
    return "under a yellow operations posture"
  end
  return "under a green operations posture"
end

local function domainPhrase(domain, captainName)
  domain = tostring(domain or ""):lower()
  if captainName == "ayshe temirkhan" then
    if domain == "rail" then
      return "directing rail-domain corridor operations"
    elseif domain == "sea" then
      return "directing sea-domain corridor operations"
    end
    return "directing corridor operations"
  end

  if domain == "rail" then
    return "conducting rail-domain operations"
  elseif domain == "sea" then
    return "conducting sea-domain operations"
  end
  return "conducting corridor operations"
end

local function expandTask(task, captainName)
  task = mw.text.trim(tostring(task or ""))
  if task == "" then
    return ""
  end

  if captainName == "ayshe temirkhan" then
    local t = mw.ustring.lower(task)
    local pieces = {}

    if t:find("seal") then
      table.insert(pieces, "close seal scrutiny and aggressive registry verification")
    end
    if t:find("diversion") or t:find("shadow") then
      table.insert(pieces, "suppression of shadow transfers and suspected diversion chains")
    end
    if t:find("crowd") or t:find("platform") or t:find("queue") then
      table.insert(pieces, "platform pressure and controlled station clearing under enforcement conditions")
    end
    if t:find("smuggl") then
      table.insert(pieces, "counter-smuggling sweeps and selective freight detention")
    end
    if t:find("yard") or t:find("intermodal") then
      table.insert(pieces, "predatory inspection work across yards, sidings, and transfer points")
    end
    if t:find("manifest") or t:find("ledger") or t:find("registry") then
      table.insert(pieces, "hard-line manifest scrutiny and punitive registry control")
    end
    if t:find("maintenance") then
      table.insert(pieces, "escorted control over rail access and maintenance movement")
    end

    if #pieces == 0 then
      return "Her reported activity centers on " .. task .. "."
    end

    return "Her reported activity centers on " .. table.concat(pieces, ", ") .. "."
  end

  return "The day’s activity centers on " .. task .. "."
end

local function weatherSentence(weather, captainName)
  if not weather or not weather.alert then
    return ""
  end

  local label = tostring(weather.alert.label or "")
  local hazard = tostring(weather.alert.hazard or "")
  local condition = tostring(weather.condition or "")

  local desc = hazard
  if desc == "" then desc = condition end
  if desc == "" then return "" end

  if captainName == "ayshe temirkhan" then
    return string.format(
      " Local weather conditions remain a meaningful factor, with %s conditions reinforcing tighter movement control, harsher release windows, and greater suspicion toward delay, congestion, and low-visibility disruptions.",
      desc
    )
  end

  return string.format(
    " Local weather conditions are reported as %s%s.",
    desc,
    (label ~= "" and (" under a " .. label .. " weather posture") or "")
  )
end

local function rotationSentence(data, captainName)
  if not tonumber(data.dayInBlock) or not tonumber(data.blockLen) then
    return ""
  end

  if captainName == "ayshe temirkhan" then
    return string.format(
      " She is on day %d of a %d-day rotational block, though in practice her rotation is understood less as routine patrol than as sustained pressure along the Caledonian line.",
      tonumber(data.dayInBlock),
      tonumber(data.blockLen)
    )
  end

  return string.format(
    " This places the captain on day %d of a %d-day rotational block within the wider Hatch Ministry security circuit.",
    tonumber(data.dayInBlock),
    tonumber(data.blockLen)
  )
end

local function captainSpecificClosing(data, captainName)
  if captainName ~= "ayshe temirkhan" then
    return ""
  end

  local station = tostring(data.station or "")
  local stationLink = cityLink(station)

  return " The effect is less that of ordinary rail security than of deliberate corridor pressure, consistent with Temirkhan’s reputation for turning administrative irregularity, suspect freight, and station disorder into opportunities for seizure, intimidation, and exemplary enforcement at " .. stationLink .. "."
end

function p.captainParagraph(frame)
  local args = (frame and frame.args) or {}
  local captain = mw.text.trim(tostring(args.captain or ""))
  if captain == "" then
    return "No captain specified."
  end

  local data = ops.getCaptainAssignmentData(captain, args.year, args.day)
  if not data then
    return "No matching captain assignment could be found."
  end

  local captainLower = mw.ustring.lower(captain)

  local intro = string.format(
    "On %d/%d PSSC, %s is operating out of %s, away from the captain’s home base in %s, %s and %s along the Caledonian reaches of the [[Trans-Morovian Express]].",
    data.day,
    data.year,
    captainLink(data),
    cityLink(data.station),
    cityLink(data.home),
    sevPhrase(data.severity, captainLower),
    domainPhrase(data.domain, captainLower)
  )

  local taskPart = expandTask(data.task, captainLower)
  local rotationPart = rotationSentence(data, captainLower)
  local weatherPart = weatherSentence(data.weather, captainLower)
  local closingPart = captainSpecificClosing(data, captainLower)

  local out = {intro}
  if taskPart ~= "" then table.insert(out, taskPart) end
  if rotationPart ~= "" then table.insert(out, rotationPart) end
  if weatherPart ~= "" then table.insert(out, weatherPart) end
  if closingPart ~= "" then table.insert(out, closingPart) end

  return table.concat(out, " ")
end

return p