Module:HatchMinistryNarrative

From MicrasWiki
Jump to navigationJump to search

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