Module:ImprovementTableKai/Sandbox

local BaseTable = require('Module:BaseTable') local Equipment = require('Module:Equipment') local Formatting = require('Module:Formatting') local ResourceIcons = require('Module:ResourceIcons') local Ship = require('Module:Ship')

local format = require('Module:StringInterpolation').format

local ImprovementTableKai = BaseTable{ _item_class = Equipment, _header_template = ${resources} ! style="text-align: center; padding: 5px;" | ★ ! style="text-align: center; padding: 5px;" | ${devmat} ! style="text-align: center; padding: 5px;" | ${screw} ! class="multi-toggle-target-improvementtablekai-day-Sunday" style="text-align: center; padding: 5px;" | S ! class="multi-toggle-target-improvementtablekai-day-Monday" style="text-align: center; padding: 5px;" | M ! class="multi-toggle-target-improvementtablekai-day-Tuesday" style="text-align: center; padding: 5px;" | T ! class="multi-toggle-target-improvementtablekai-day-Wednesday" style="text-align: center; padding: 5px;" | W ! class="multi-toggle-target-improvementtablekai-day-Thursday" style="text-align: center; padding: 5px;" | T ! class="multi-toggle-target-improvementtablekai-day-Friday" style="text-align: center; padding: 5px;" | F ! class="multi-toggle-target-improvementtablekai-day-Saturday" style="text-align: center; padding: 5px;" | S ! style="text-align: center; padding: 5px;" | Helper Ship, _column_cell_templates = { ["!"] = ${values.value}, name = ${values.name} ${values.icon} ${values.japanese_name} },	_columns = { "input_output", "improvement_level", "development_material", "improvement_material", "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "helper_ships", },	_improvement_brackets = { 0,		6,		10	},	_caption_template = ${icon}${name} ${edit_link} , _name_custom_row_template = ${icon}${name}: ${resources} ${edit_link}  , _custom_row_class = "custom-row multi-toggle-target-improvementtablekai-day", _edit_link_text = "Edit", _equipment_data_documentation = "Template:EquipmentDataDocumentation/EditIntro", _basic_resources_label = "Improvement Cost: ", _consumed_equipment_label = " Consumes: ${list} ", _produced_equipment_label = " Produces: 1x ${icon}${name}${stars} ", _produced_equipment_stars_template = "★+${stars}", _extended_initial_template = "${initial} ${extension} ", _equipment_item = "${count}x ${icon}${name}", _material_cell_content = "${normal}/${slider}", _unavailable_color = "#f99", _available_color = "#aaebaa", _small_icon_size = "24x24px", _combined_names_template = "${text} (${combined_text}) ", _required_ship_category_template = "Category:Equipment that can be improved with ${ship_name} as helper ship", _consumed_equip_category_template = "Category:Equipment that consume ${equip_name} during improvement", _single_screw_improvement_category = "Category:Equipment that can be improved using only one improvement material", _detail_toggle =  .. ' Filter by day: Show all  ' .. ' Sunday Sunday  ' .. ' Monday Monday  ' .. ' Tuesday Tuesday  ' .. ' Wednesday Wednesday  ' .. ' Thursday Thursday  ' .. ' Friday Friday  ' .. ' Saturday Saturday  ' .. ' ',	_day_of_week_class_prefix = "multi-toggle-target-improvementtablekai-day-", }

ImprovementTableKai._column_cell_templates["!"] = ImprovementTableKai._column_cell_templates["!"] .. ImprovementTableKai._detail_toggle

function ImprovementTableKai:create_items_post self._custom_rows = {} local result = {} if #self._items == 1 then self._single_item = true end for item_index, item in ipairs(self._items) do		if type(item) ~= "string" then local products = item:improvement_products local edit_link = Formatting:format_edit_link(Equipment:get_module(self._args[item_index]), self._edit_link_text, self._equipment_data_documentation) if self._single_item then self._title_row = format{self._caption_template, icon = Formatting:format_image{Formatting:format_equipment_icon(item:icon)}, name = Formatting:format_link(item:link), edit_link = edit_link, }			else self._custom_rows[item:name] = {content = format{self._name_custom_row_template, colspan = #self._columns, classes = self._custom_row_class, icon = Formatting:format_image{Formatting:format_equipment_icon(item:icon)}, name = Formatting:format_link(item:link), resources = Formatting:format_resources(item:improvement_resources or {devmat = false, screw = false}), edit_link = edit_link, }, row = {classes = {}}} --The classes table will be mutated by this item's various rows as a set of css classes for the multi toggle. table.insert(result, item:name) end if products then for _, product in ipairs(products) do					local ships = item:improvement_ships(product) local availability = {} local ship_data = {} for _, ship in ipairs(ships) do						availability[ship] = item:improvement_availability(product, ship) if type(ship) == "string" then ship_data[ship] = Ship(ship) if self._single_item and self._args.categories then self._ships = self._ships or {} self._ships[ship] = ship_data[ship] end end end local combined_ships = {} local indexes_to_delete = {} local ship_names = {} for index, ship in ipairs(ships) do						if ship ~= true and ship ~= false then local remodel_from = ship_data[ship]:remodel_from if ship_data[remodel_from] then local identical = true for day, possible in pairs(availability[ship]) do									if availability[remodel_from][day] ~= possible then identical = false end end if identical then table.insert(indexes_to_delete, index) -- The text to add when combining with a less remodelled form. local combined_name if ship_data[remodel_from]:base_name == ship_data[ship]:base_name then -- The ship has the same base name as the preceding form, -- so we only need to add the suffix. combined_name = ship_data[ship]:display_suffix else -- The ship has a different base name as the preceding form, -- so we need to add the full name. combined_name = ship_data[ship]:name end -- Find the most basic form while combined_ships[remodel_from] do										remodel_from = combined_ships[remodel_from] end -- Leave a marker that we combined this form with another form combined_ships[ship] = remodel_from -- Prevent nil errors if not ship_names[remodel_from] then ship_names[remodel_from] = {} end -- Add the combine text to a table so it can be displayed with the most basic form later table.insert(ship_names[remodel_from], combined_name) if ship_names[ship] then -- If this form has had other forms combined with it, add those forms' text too -- This order of operations should keep the combined text readable. for _, suffix in ipairs(ship_names[ship]) do											table.insert(ship_names[remodel_from], suffix) end ship_names[ship] = nil end end end end end table.sort(indexes_to_delete, function(a,b) return a > b end) for _, index in ipairs(indexes_to_delete) do						table.remove(ships, index) end

local group = {} for index, ship in ipairs(ships) do						if ship ~= true and ship ~= false then table.insert(group, index) end end local initials = self:create_initials(ships, ship_data, group)

for _, stars in ipairs(item:improvement_brackets(product)) do						table.insert(result, {item = item, classes = self._single_item and {} or self._custom_rows[item:name].row.classes, product = product, stars = stars, ships = ships, ship_data = ship_data, ship_names = ship_names, initials = initials, availability = availability, resources = item:improvement_resources(false, product, stars), resources_x = item:improvement_resources(true, product, stars)}) end end else table.insert(result, {item = item, classes = self._single_item and {} or self._custom_rows[item:name].row.classes}) end else table.insert(result, item) end end self._items = result end

function ImprovementTableKai:create_initials(ships, ship_data, group, initials, place, force_significance) place = place or 1 initials = initials or {} local subgroup_index = 1 local forced_groups = {} local new_initials = {} local subgroups = {} local previous_initial = nil local max_place = 0 local significant = force_significance or place == 1 for _, ship_index in ipairs(group) do		local name = ship_data[ships[ship_index]]:name max_place = math.max(max_place, #name) local initial = false if #name >= place then initial = mw.ustring.sub(name, place, place) end new_initials[ship_index] = initial if previous_initial == nil then previous_initial = initial elseif initial ~= previous_initial then previous_initial = initial significant = true subgroup_index = subgroup_index + 1 end if initial == " " then forced_groups[subgroup_index] = true end if not subgroups[subgroup_index] then subgroups[subgroup_index] = {} end table.insert(subgroups[subgroup_index], ship_index) end if significant then for _, ship_index in pairs(group) do			if not initials[ship_index] then initials[ship_index] = new_initials[ship_index] elseif new_initials[ship_index] then initials[ship_index] = initials[ship_index] .. new_initials[ship_index] end end end if place < max_place then for subgroup_index, subgroup in ipairs(subgroups) do			if forced_groups[subgroup_index] then initials = self:create_initials(ships, ship_data, subgroup, initials, place + 1, true) elseif #subgroup > 1 then initials = self:create_initials(ships, ship_data, subgroup, initials, place + 1) end end end return initials end

function ImprovementTableKai:input_output(row_data) local value = "-" if row_data.resources then local result = {} local consumed_equipment_table = row_data.resources.equipment or {} if row_data.resources.equipment == nil then consumed_equipment_table[false] = false end local consumed_equipment = {} for equip, count in pairs(consumed_equipment_table) do			local equipment if equip ~= true then if equip == false then equipment = Equipment else equipment = Equipment(equip) end else equipment = row_data.item end if self._single_item and self._args.categories and equip ~= false then self._consumed_equipment = self._consumed_equipment or {} self._consumed_equipment[equip == true and equipment:name or equip] = equipment end table.insert(consumed_equipment, format{self._equipment_item, count = count or Formatting:format_stat(nil), icon = Formatting:format_image{Formatting:format_equipment_icon_simple(equipment:icon), size = self._small_icon_size}, name = equip == true and Formatting:format_stat(equipment:name) or Formatting:format_link(equipment:link)}) end if #consumed_equipment > 0 then table.insert(result, format{self._consumed_equipment_label, list = table.concat(consumed_equipment, " ")}) end if row_data.stars == self._improvement_brackets[#self._improvement_brackets] and row_data.product then local product = Equipment(row_data.product) local stars = row_data.item:improvement_product_initial_level(row_data.product) table.insert(result, format{self._produced_equipment_label, 					icon = Formatting:format_image{Formatting:format_equipment_icon_simple(product:icon), size = self._small_icon_size}, 					name = Formatting:format_link(product:link),					stars = stars and format{self._produced_equipment_stars_template, stars = stars} or ""				}) end if #result > 0 then value = table.concat(result, " ") end end return {values = {value = value}, bg_color = self._transparent, text_align = self._center_align} end

function ImprovementTableKai:improvement_level(row_data) return {values = {value = row_data.stars or "-"}, bg_color = self._transparent, text_align = self._center_align} end

function ImprovementTableKai:development_material(row_data) if row_data.resources then return {values = {value = format{self._material_cell_content, normal = Formatting:format_stat(row_data.resources.devmat), slider = Formatting:format_stat(row_data.resources_x.devmat)}}, bg_color = self._transparent, text_align = self._center_align} else return {values = {value = "-"}, bg_color = self._transparent, text_align = self._center_align} end end

function ImprovementTableKai:improvement_material(row_data) if row_data.resources then if self._single_item and self._args.categories and row_data.resources.screw == 1 then self._single_screw_improvement = true end return {values = {value = format{self._material_cell_content, normal = Formatting:format_stat(row_data.resources.screw), slider = Formatting:format_stat(row_data.resources_x.screw)}}, bg_color = self._transparent, text_align = self._center_align} else return {values = {value = "-"}, bg_color = self._transparent, text_align = self._center_align} end end

function ImprovementTableKai:sunday(row_data) return self:availability(row_data, "Sunday") end

function ImprovementTableKai:monday(row_data) return self:availability(row_data, "Monday") end

function ImprovementTableKai:tuesday(row_data) return self:availability(row_data, "Tuesday") end

function ImprovementTableKai:wednesday(row_data) return self:availability(row_data, "Wednesday") end

function ImprovementTableKai:thursday(row_data) return self:availability(row_data, "Thursday") end

function ImprovementTableKai:friday(row_data) return self:availability(row_data, "Friday") end

function ImprovementTableKai:saturday(row_data) return self:availability(row_data, "Saturday") end

function ImprovementTableKai:availability(row_data, day) local availability = {} local available = false local bg_color = self._transparent if row_data.ships then for index, ship in ipairs(row_data.ships) do			local local_availability = row_data.availability[ship][day] if local_availability ~= false then available = true local ship_initial if local_availability == nil then ship_initial = "?" else if ship == true then ship_initial = "✓" elseif ship == false then ship_initial = "_" else ship_initial = row_data.initials[index] if #ship_initial > 1 then ship_initial = format{self._extended_initial_template, initial = mw.ustring.sub(ship_initial, 1, 1), extension = mw.ustring.sub(ship_initial, 2)} end end bg_color = self._available_color end table.insert(availability, ship_initial) else table.insert(availability, " ") end end end local day_of_week_class = self._day_of_week_class_prefix .. day if not available then bg_color = self._unavailable_color elseif not self._single_item then row_data.classes[day_of_week_class] = true end --values.ships is not displayed in the table (cell template string doesn't ask for ships). --It is included in order to keep availability cells from merging when helper ships cells were split. --This was only observed to occur when no ship had availability for a certain day across multiple improvement paths. return {values = {value = available and table.concat(availability, " ") or "✗", ships = row_data.ships}, classes = day_of_week_class, bg_color = bg_color, text_align = self._center_align} end

function ImprovementTableKai:helper_ships(row_data) local ships = {} if row_data.ships then for index, ship in ipairs(row_data.ships) do			if ship == false then table.insert(ships, "??") elseif ship ~= true then link, text, section = row_data.ship_data[ship]:link if row_data.ship_names[ship] then text = format{self._combined_names_template, text = text or link, combined_text = table.concat(row_data.ship_names[ship], "/")} end table.insert(ships, Formatting:format_link(link, text, section)) else table.insert(ships, "Any") end end end return {values = {value = table.concat(ships, " ")}, bg_color = self._transparent, text_align = self._center_align} end

function ImprovementTableKai:row(row_data) --This gets rendered in start_rows return {classes = row_data.classes} end

function ImprovementTableKai:start_rows --Render class string for normal rows for index, row_values in ipairs(self._data_rows) do		if type(row_values) == "table" then if row_values._row and row_values._row.classes then --create list from set local classes = {} for key, _ in pairs(row_values._row.classes) do					table.insert(classes, key) end --create class string row_values._row.classes = table.concat(classes, " ") end end end --Render class string for custom rows for key, value in pairs(self._custom_rows) do		--create list from set local classes = {} for key, _ in pairs(value.row.classes) do			table.insert(classes, key) end --create class string value.row.classes = table.concat(classes, " ") end if self._single_item then self._rows = {self._table_start, self._title_row, self._header} elseif #self._data_rows > 0 and type(self._data_rows[1]) ~= "table" then self._rows = {format{self._detail_toggle, colspan = #self._columns}, self._table_start} else self._rows = {self._table_start, self._header} end end

function ImprovementTableKai:create_table_prep self._header_icons = { devmat = ResourceIcons.devmat, screw = ResourceIcons.screw, }	for key, value in pairs(self._header_icons) do		self._header_icons[key] = Formatting:format_image{value, caption = Formatting:format_resource_name(key)} end end

function ImprovementTableKai:create_header if self._single_item then self._header_icons.resources = self._basic_resources_label .. Formatting:format_resources(self._items[1].item:improvement_resources or {devmat = false, screw = false}) else self._header_icons.resources = "" end self._header = format(self._header_template, self._header_icons) end

function ImprovementTableKai:finish_rows if not self._single_item then table.insert(self._rows, self._row_starter) table.insert(self._rows, self._header_bottom or self._header) end table.insert(self._rows, self._table_end) end

function ImprovementTableKai:post_process if self._single_item and self._args.categories then local categories = {} local ships_index = {} for ship, ship_data in pairs(self._ships or {}) do           table.insert(ships_index, ship) end table.sort(ships_index) for _, ship in ipairs(ships_index) do           table.insert(categories, Formatting:format_link(format{self._required_ship_category_template, ship_name = self._ships[ship]:name})) end local equip_index = {} for equip, equip_data in pairs(self._consumed_equipment or {}) do           table.insert(equip_index, equip) end table.sort(equip_index) for _, equip in ipairs(equip_index) do           table.insert(categories, Formatting:format_link(format{self._consumed_equip_category_template, equip_name = self._consumed_equipment[equip]:common_name})) end if self._single_screw_improvement then table.insert(categories, Formatting:format_link(self._single_screw_improvement_category)) end self._result = self._result .. table.concat(categories) end end

ImprovementTableKai.create_data_rows = ImprovementTableKai.create_data_rows_merge_vertical

return ImprovementTableKai