Line 1: |
Line 1: |
| local BaseData = require('Module:BaseData') | | local BaseData = require('Module:BaseData') |
| + | local Artist = require('Module:Artist') |
| local Ship = require('Module:Ship') | | local Ship = require('Module:Ship') |
| + | local VoiceActor = require('Module:VoiceActor') |
| local Formatting = require('Module:Formatting') | | local Formatting = require('Module:Formatting') |
| | | |
− | local format = require('Module:StringOperations').format | + | local U = require('Module:Core') |
| + | local format = U.format |
| | | |
| local ShipMetaKai = BaseData{ | | local ShipMetaKai = BaseData{ |
− | _template = [[{|class="${table_class}" style="float: right;" | + | _template = [[{|class="${table_class}" |
| |- | | |- |
− | !colspan=2|${name} ${japanese_name} | + | !class="infobox-kai-header-major" colspan=2|${name}<div style="float:right;margin-right:5px">${edit_link}</div> |
| |- | | |- |
| !Class | | !Class |
Line 22: |
Line 25: |
| |${availability} | | |${availability} |
| |- | | |- |
− | !Implemented on | + | !Implementation |
| |${implementation_date} | | |${implementation_date} |
| |}]], | | |}]], |
− | _voice_actor_header = "[[Glossary#List of Vessels by Japanese Voice Actresses|Seiyuu]]", | + | _flat_template = [[{|class="${table_class}" |
− | _artist_header = "[[Glossary#List of Vessels by Artist|Artist]]",
| + | |- |
− | _class_template = "[[:Category:${ship_class}|]]",
| + | !class="infobox-kai-header-major" colspan=4|${name}<div style="float:right;margin-right:5px">${edit_link}</div> |
− | _normal_construction_label = "Normal",
| + | |- |
− | _large_ship_construction_label = "LSC",
| + | !${voice_actor_header} |
− | _buildable_label = "Construction",
| + | |${voice_actor} |
− | _drop_label = "Drop",
| + | !Availability |
− | _details_template = " ${details}",
| + | |${availability} |
− | _event_reward_label = "Event Reward",
| + | |- |
− | _event_drop_label = "Event Drop",
| + | !${artist_header} |
− | _node_name_template = "${world}-${map}-${node}",
| + | |${artist} |
− | _node_formation_template = "-${formation}",
| + | !Implementation |
− | _event_node_name_template = "${year} ${quarter} E-${map}-${node}",
| + | |${implementation_date} |
− | _quarters = {
| + | |}]], |
− | [1] = "Winter",
| + | _ship_data_documentation = "Template:ShipDataDocumentation/EditIntro", |
− | [4] = "Spring",
| + | _edit_link_text = "Edit", |
− | [7] = "Summer",
| + | _voice_actor_header = "[[Glossary#List of Vessels by Japanese Voice Actresses|Seiyuu]]", |
− | [10] = "Fall",
| + | _artist_header = "[[Glossary#List of Vessels by Artist|Artist]]", |
| + | _class_template = "[[:Category:${ship_class}|${ship_class}]]", |
| + | _name_template = "${name} ${japanese_name}", |
| + | _person_template = "${name} (${japanese_name})", |
| + | _normal_construction_label = "[[Construction#Building_recipes|Normal]]", |
| + | _large_ship_construction_label = "[[Construction#Large_Ship_Construction_Recipe|LSC]]", |
| + | _buildable_label = "Construction", |
| + | _drop_label = "Drop", |
| + | _details_template = " (${details})", |
| + | _event_reward_label = "[[Template:Event_Drop|Event Reward]]", |
| + | _event_drop_label = "[[Template:Event_Drop|Event Drop]]", |
| + | _node_name_template = "${world}-${map} ${node}", |
| + | _node_formation_template = "-${formation}", |
| + | _event_node_name_template = "${year} ${quarter} E-${map} ${node}", |
| + | _event_map_name_template = "${year} ${quarter} E-${map}", |
| + | _date_template = "${year}/${month:2}/${day:2}", |
| + | _all_nodes_symbol = "*", |
| + | _max_drops_before_collapsible = 6, |
| + | _quarters = { |
| + | [1] = "Winter", |
| + | [4] = "Spring", |
| + | [7] = "Summer", |
| + | [10] = "Fall", |
| + | [12] = "Christmas", |
| }, | | }, |
| _difficulties = { | | _difficulties = { |
Line 51: |
Line 77: |
| }, | | }, |
| _fields = { | | _fields = { |
− | "name", | + | "edit_link", |
− | "class",
| + | "name", |
− | "voice_actor",
| + | "class", |
− | "artist",
| + | "voice_actor", |
− | "availability",
| + | "artist", |
− | "implementation_date",
| + | "availability", |
| + | "implementation_date", |
| }, | | }, |
| } | | } |
Line 64: |
Line 91: |
| _args = args, | | _args = args, |
| }:create_infobox() | | }:create_infobox() |
| + | end |
| + | |
| + | function ShipMetaKai:edit_link() |
| + | self._vars.edit_link = Formatting:format_edit_link(self._ship_data_module, self._edit_link_text, self._ship_data_documentation) |
| end | | end |
| | | |
| function ShipMetaKai:name() | | function ShipMetaKai:name() |
− | self._vars.name = Formatting:format_stat(self._ship:name())
| + | self._vars.name = Formatting:format_stat(self._ship:name()) |
− | self._vars.japanese_name = tostring(Formatting:japanese_text(Formatting:format_stat(self._ship:japanese_name())))
| + | local japanese_name = Formatting:format_stat(self._ship:japanese_name()) |
| + | if japanese_name ~= self._vars.name then |
| + | self._vars.name = format{self._name_template, name = self._vars.name, japanese_name = tostring(Formatting:japanese_text(japanese_name))} |
| + | end |
| end | | end |
| | | |
| function ShipMetaKai:class() | | function ShipMetaKai:class() |
− | local ship_class = self._ship:class()
| + | local ship_class = self._ship:class() |
− | if ship_class then
| + | if ship_class then |
− | self._vars.class = format{self._class_template, ship_class = ship_class:name()}
| + | self._vars.class = format{self._class_template, ship_class = ship_class:name()} |
− | end
| + | end |
| end | | end |
| | | |
| function ShipMetaKai:voice_actor() | | function ShipMetaKai:voice_actor() |
− | self._vars.voice_actor = Formatting:format_stat(self._ship:voice_actor())
| + | self._vars.voice_actor = self:person(VoiceActor(self._ship:voice_actor())) |
| end | | end |
| | | |
| function ShipMetaKai:artist() | | function ShipMetaKai:artist() |
− | self._vars.artist = Formatting:format_stat(self._ship:artist())
| + | self._vars.artist = self:person(Artist(self._ship:artist())) |
| + | end |
| + | |
| + | function ShipMetaKai:person(person) |
| + | local link, japanese_name, reading = Formatting:format_external_link(person:link()), person:japanese_name(), person:reading() |
| + | if japanese_name == false then |
| + | return link |
| + | elseif reading == false then |
| + | japanese_name = tostring(Formatting:japanese_text(Formatting:format_stat(person:japanese_name()))) |
| + | else |
| + | japanese_name = tostring(Formatting:japanese_text(Formatting:format_stat(person:japanese_name()), Formatting:format_stat(person:reading()))) |
| + | end |
| + | return format{self._person_template, name = Formatting:format_external_link(person:link()), japanese_name = japanese_name} |
| end | | end |
| + | |
| + | local custom_quest_links = { |
| + | ["5A05"] = "Partials/Updates/2018_April_23rd#5A05" |
| + | } |
| | | |
| function ShipMetaKai:availability() | | function ShipMetaKai:availability() |
− | local availability = self._ship:availability()
| + | local availability = self._ship:availability() |
− | local result = {}
| + | local result = {} |
− | for _, method in ipairs(availability) do
| + | local buildable = false |
− | if method == "buildable" then
| + | if self._ship:buildable() then |
− | local details = {}
| + | buildable = {self._normal_construction_label} |
− | if availability.buildable.normal then
| + | end |
− | table.insert(details, self._normal_construction_label)
| + | if self._ship:buildable_lsc() then |
− | end
| + | buildable = buildable or {} |
− | if availability.buildable.lsc then
| + | table.insert(buildable, self._large_ship_construction_label) |
− | table.insert(details, self._large_ship_construction_label)
| + | end |
− | end
| + | if buildable then |
− | if #details > 0 then
| + | table.insert(result, self._buildable_label .. format{self._details_template, details = table.concat(buildable, ", ")}) |
− | details = format{self._details_template, details = table.concat(details, ", ")}
| + | end |
− | else
| + | if availability and availability.quest then |
− | details = ""
| + | table.insert(result, "Quest: " .. U.ijoin(U.imap(availability.quest, function(label) |
− | end
| + | return string.format("[[%s|%s]]", custom_quest_links[label] or string.format("Quests#%s", label), label) |
− | table.insert(result, self._buildable_label .. details)
| + | end), ", ")) |
− | elseif method == "drop" then | + | end |
− | local details = {}
| + | for _, method in ipairs(availability or {}) do |
− | if availability.drop then
| + | if method == "drop" then |
− | for _, node in availability.drop do
| + | local details = {} |
− | local node_name = format{self._node_name_template, world = node[1], map = node[2], node = node[3]}
| + | if availability.drop then |
− | if #node == 4 then | + | for _, drop in ipairs(availability.drop) do |
− | node_name = node_name .. format{self._node_formation_template, formation = node[4]} | + | local nodes, complex |
| + | if type(drop[3]) == "table" then |
| + | nodes = drop[3] |
| + | elseif drop[3] == true then |
| + | nodes = {self._all_nodes_symbol} |
| + | else |
| + | nodes = {drop[3]} |
| end | | end |
− | table.insert(details, node_name)
| + | for _, node in ipairs(nodes) do |
− | end
| + | local node_name = format{self._node_name_template, world = drop[1], map = drop[2], node = node} |
− | end
| + | if #drop == 4 then |
− | if #details > 0 then
| + | node_name = node_name .. format{self._node_formation_template, formation = complex and drop[4][node] or drop[4]} |
− | details = format{self._details_template, details = table.concat(details, ", ")}
| + | end |
− | else
| + | table.insert(details, node_name) |
− | details = ""
| |
− | end
| |
− | table.insert(result, self._drop_label .. details)
| |
− | elseif method == "event_reward" then
| |
− | local details = {}
| |
− | if availability.event_reward then
| |
− | for _, map in availability.event_reward do
| |
− | local map_name = format{self._map_name_template, year = map[1], quarter = self._quarters[node[2]], map = map[3]}
| |
− | if #map == 4 then
| |
− | map_name = map_name .. format{self._details_template, details = self._difficulties[map[4]]}
| |
− | end
| |
− | table.insert(details, map_name)
| |
− | end
| |
− | end
| |
− | if #details > 0 then
| |
− | details = format{self._details_template, details = table.concat(details, ", ")}
| |
− | else
| |
− | details = ""
| |
− | end
| |
− | table.insert(result, self._event_reward_label .. details)
| |
− | elseif method == "event_drop" then
| |
− | local details = {}
| |
− | if availability.event_drop then
| |
− | for _, node in availability.drop do
| |
− | local node_name = format{self._event_node_name_template, year = node[1], quarter = self._quarters[node[2]], map = node[3], node = node[4]}
| |
− | if #node == 5 then
| |
− | node_name = node_name .. format{self._node_formation_template, formation = node[5]}
| |
| end | | end |
− | table.insert(details, node_name)
| + | end |
− | end
| + | end |
− | end
| + | local details_len = #details |
− | if #details > 0 then
| + | if details_len > 0 then |
− | details = format{self._details_template, details = table.concat(details, ", ")}
| + | details = format{self._details_template, details = table.concat(details, ", ")} |
− | else
| + | if details_len > self._max_drops_before_collapsible then |
− | details = ""
| + | table.insert(result, tostring(mw.html.create("div"):addClass("mw-collapsible"):addClass("mw-collapsed"):wikitext(self._drop_label):tag("div"):addClass("mw-collapsible-content"):wikitext(details):allDone())) |
− | end
| + | else |
− | table.insert(result, self._event_drop_label .. details)
| + | table.insert(result, self._drop_label .. details) |
− | end
| + | end |
− | end
| + | else |
− | self._vars.availability = table.concat(result, "<br/>")
| + | table.insert(result, self._drop_label) |
| + | end |
| + | elseif method == "event_reward" then |
| + | local details, current_event_details = {}, {} |
| + | if availability.event_reward then |
| + | for _, map in ipairs(availability.event_reward) do |
| + | local map_name = format{self._event_map_name_template, year = map[1], quarter = self._quarters[map[2]], map = map[3]} |
| + | if #map == 4 then |
| + | map_name = map_name .. format{self._details_template, details = self._difficulties[map[4]]} |
| + | end |
| + | table.insert(details, map_name) |
| + | if map[1] == 2016 and map[2] == 7 then |
| + | table.insert(current_event_details, map_name) |
| + | end |
| + | end |
| + | end |
| + | if #details > 0 and self._detailed_availability then |
| + | details = format{self._details_template, details = table.concat(details, ", ")} |
| + | elseif #current_event_details > 0 then |
| + | details = format{self._details_template, details = table.concat(current_event_details, ", ")} |
| + | else |
| + | details = "" |
| + | end |
| + | table.insert(result, self._event_reward_label .. details) |
| + | elseif method == "event_drop" then |
| + | local details, current_event_details = {}, {} |
| + | if availability.event_drop then |
| + | for _, drop in ipairs(availability.event_drop) do |
| + | local nodes, complex |
| + | if type(drop[4]) == "table" then |
| + | nodes = drop[4] |
| + | elseif drop[4] == true then |
| + | nodes = {self._all_nodes_symbol} |
| + | else |
| + | nodes = {drop[4]} |
| + | end |
| + | for _, node in ipairs(nodes) do |
| + | local node_name = format{self._event_node_name_template, year = drop[1], quarter = self._quarters[drop[2]], map = drop[3], node = node} |
| + | if #drop == 5 then |
| + | node_name = node_name .. format{self._node_formation_template, formation = complex and drop[5][node] or drop[5]} |
| + | end |
| + | table.insert(details, node_name) |
| + | if drop[1] == 2016 and drop[2] == 7 then |
| + | table.insert(current_event_details, map_name) |
| + | end |
| + | end |
| + | end |
| + | end |
| + | local details_len = #details |
| + | if details_len > 0 and self._detailed_availability then |
| + | details = format{self._details_template, details = table.concat(details, ", ")} |
| + | if details_len > self._max_drops_before_collapsible then |
| + | table.insert(result, tostring(mw.html.create("div"):addClass("mw-collapsible"):addClass("mw-collapsed"):wikitext(self._event_drop_label):tag("div"):addClass("mw-collapsible-content"):wikitext(details):allDone())) |
| + | else |
| + | table.insert(result, self._event_drop_label .. details) |
| + | end |
| + | elseif #current_event_details > 0 then |
| + | current_event_details = format{self._details_template, details = table.concat(current_event_details, ", ")} |
| + | table.insert(result, self._event_drop_label .. current_event_details) |
| + | else |
| + | table.insert(result, self._event_drop_label) |
| + | end |
| + | end |
| + | end |
| + | self._vars.availability = table.concat(result, "<br/>") |
| end | | end |
| | | |
| function ShipMetaKai:implementation_date() | | function ShipMetaKai:implementation_date() |
− | local implementation_date = self._ship:implementation_date()
| + | local form = self._ship |
− | self._vars.implementation_date = format{self._date_template, year = implementation_date[1], month = implementation_date[2], day = implementation_date[3]}
| + | local next_form = form._remodel_to |
| + | local i = 1 |
| + | local data = {} |
| + | local forms = {} |
| + | if form._implementation_date then |
| + | data[format{ |
| + | self._date_template, |
| + | year = form._implementation_date[1], |
| + | month = form._implementation_date[2], |
| + | day = form._implementation_date[3] |
| + | }] = { "Base" } |
| + | end |
| + | while next_form and not forms[next_form] and i < 10 do |
| + | forms[next_form] = true |
| + | form = Ship(next_form) |
| + | if form._implementation_date then |
| + | local d = format{ |
| + | self._date_template, |
| + | year = form._implementation_date[1], |
| + | month = form._implementation_date[2], |
| + | day = form._implementation_date[3] |
| + | } |
| + | local name = form:suffix() and form:suffix() ~= "" and form:suffix() or form:name() |
| + | data[d] = data[d] or {} |
| + | table.insert(data[d], name) |
| + | end |
| + | next_form = form._remodel_to |
| + | i = i + 1 |
| + | end |
| + | local dates = U.isort(U.keys(data)) |
| + | self._vars.implementation_date = #dates == 0 and "??" or #dates == 1 and dates[1] or U.ijoin(U.imap(dates, function (d) |
| + | return string.format("%s (%s)", d, U.ijoin(data[d], ", ")) |
| + | end), "<br>") |
| end | | end |
| | | |
Line 179: |
Line 304: |
| function ShipMetaKai:create_infobox_prep() | | function ShipMetaKai:create_infobox_prep() |
| self._vars = {} | | self._vars = {} |
− | local table_classes = {"wikitable"} | + | local table_classes = {"infobox", "infobox-kai"} |
| if self._args.classes then | | if self._args.classes then |
| table.insert(table_classes, self._args.classes) | | table.insert(table_classes, self._args.classes) |
Line 199: |
Line 324: |
| self[field](self) | | self[field](self) |
| end | | end |
− | return format(self._template, self._vars) | + | return format(self._args.thin and self._template or self._flat_template, self._vars) |
| end | | end |
| | | |
Line 213: |
Line 338: |
| return self:format_template() | | return self:format_template() |
| end | | end |
| + | |
| + | function ShipMetaKai.test() |
| + | mw.log(ShipMetaKai:Infobox({ "Ayanami" })) |
| + | mw.log(ShipMetaKai:Infobox({ "U-511" })) |
| + | mw.log(ShipMetaKai:Infobox({ "Zuikaku" })) |
| + | end |
| + | -- p.test() |
| | | |
| return ShipMetaKai | | return ShipMetaKai |