• Welcome to the Kancolle Wiki!
  • If you have any questions regarding site content, account registration, etc., please visit the KanColle Wiki Discord

Module:EliteShipsKai

From Kancolle Wiki
Revision as of 09:40, 17 February 2015 by com>Ckwng (Add function to break rowspan and to add headers in the middle of the table)
Jump to navigation Jump to search

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

local ResourceIcons = require('Module:ResourceIcons')
local StatIcons = require('Module:StatIcons')
local MiscIcons = require('Module:MiscIcons')
local Ship = require('Module:Ship')
local Formatting = require('Module:Formatting')
local format = require('Module:StringInterpolation').format

local EliteShipsKai = {
	_table_start = [[{| class="wikitable"]],
	_row_starter = "|-",
	_header_template = [[!No.
!Name
!Class
! style="white-space:nowrap;" | ${remodel_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: lightcoral;" | ${firepower_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: lightskyblue;" | ${torpedo_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: sandybrown;" | ${aa_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: #9C8FEE;" | ${asw_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: aquamarine;" | ${los_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: palegreen;" | ${luck_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: pink;" | ${hp_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: #F2E279;" | ${armor_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: violet;" | ${evasion_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: #72E6E6;" | ${speed_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: silver;" | ${aircraft_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: forestgreen;" | ${fuel_icon}
! style="width: 30px; text-align: center; vertical-align: middle; background-color: darkgoldenrod;" | ${ammo_icon}
! style="text-align:left;" | Notes]],
	_column_cell_templates = {
		name = [[| colspan="1" rowspan="${rowspan}" style="text-align:center; background-color: ${bg_color}" | ${value.link} ${value.japanese_name}]],
		luck = [[| colspan="1" rowspan="${rowspan}" style="text-align:center; background-color: ${bg_color}" | ${value.luck}(${value.luck_max})]],
	},
	_columns = {
		"id",
		"name",
		"class",
		"remodel",
		"firepower",
		"torpedo",
		"aa",
		"asw",
		"los",
		"luck",
		"hp",
		"armor",
		"evasion",
		"speed",
		"aircraft",
		"fuel",
		"ammo",
		"notes",
	},
	_cell_color = {
		firepower = "#F0C0C0",
		torpedo = "#C0E4FA",
		aa = "#F4CAA6",
		asw = "#C5BEEE",
		los = "#CCFFEE",
		luck = "#C9FBC9",
		hp = "#FFD9DF",
		armor = "#F2ECC2",
		evasion = "#EEBEEE",
		speed = "#B8E6E6",
		aircraft = "#D9D9D9",
		fuel = "#94E094",
		ammo = "palegoldenrod"
	},
	_good_stat_color = "yellow",
	_outstanding_stat_color = "lime",
	_cell = [[| colspan="1" rowspan="${rowspan}" style="text-align:center; background-color: ${bg_color}" | ${value.value}]],
	_table_end = [[|}]],
	_rowspan_suffix = "_rowspan",
	_bg_color_suffix = "_bg_color",
	_outstanding_suffix = "_outstanding",
	_good_suffix = "_good",
	_operator_suffix = "_operator",
	_notes_suffix = "_notes",
	_transparent = "transparent",
	_emphasis_template = "''${value}''",
	_operators = {
		["<"] = function(x,y) return x < y end,
		[">"] = function(x,y) return x > y end,
	}
}

function EliteShipsKai:get_bg_color(default, value, operator, outstanding, good)
	if not value then
		return default or self._transparent
	end
	local comparison = self._operators[operator or ">"]
	if outstanding and comparison(value, tonumber(outstanding)) then
		return self._outstanding_stat_color
	elseif good and comparison(value, tonumber(good)) then
		return self._good_stat_color
	else
		return default or self._transparent
	end
end

function EliteShipsKai:get_emphasis(value, formatted, operator, good)
	local comparison = self._operators[operator or ">"]
	if value and good and comparison(value, tonumber(good)) then
		return format{self._emphasis_template, value = formatted}
	end
	return formatted
end

function EliteShipsKai:name(ship)
	return {values = {link = Formatting:format_link(ship:link()), japanese_name = ship:japanese_name()}, bg_color = self._transparent}
end

function EliteShipsKai:id(ship)
	return {values = {value = ship:id()}, bg_color = self._transparent}
end

function EliteShipsKai:class(ship)
	return {values = {value = ship:class():base_name()}, bg_color = self._transparent}
end

function EliteShipsKai:remodel(ship, args)
	local remodel_level = ship:remodel_level()
	return {values = {value = Formatting:format_stat(remodel_level)}, bg_color = self:get_bg_color(self._cell_color.remodel, remodel_level, args.remodel_level_operator, args.remodel_level_outstanding, args.remodel_level_good)}
end

function EliteShipsKai:firepower(ship, args)
	local firepower_max = ship:firepower_max()
	return {values = {value = Formatting:format_stat(firepower_max)}, bg_color = self:get_bg_color(self._cell_color.firepower, firepower_max, args.firepower_operator, args.firepower_outstanding, args.firepower_good)}
end

function EliteShipsKai:torpedo(ship, args)
	local torpedo_max = ship:torpedo_max()
	return {values = {value = Formatting:format_stat(torpedo_max)}, bg_color = self:get_bg_color(self._cell_color.torpedo, torpedo_max, args.torpedo_operator, args.torpedo_outstanding, args.torpedo_good)}
end

function EliteShipsKai:aa(ship, args)
	local aa_max = ship:aa_max()
	return {values = {value = Formatting:format_stat(aa_max)}, bg_color = self:get_bg_color(self._cell_color.aa, aa_max, args.aa_operator, args.aa_outstanding, args.aa_good)}
end

function EliteShipsKai:asw(ship, args)
	local asw_max = ship:asw_max()
	return {values = {value = Formatting:format_stat(asw_max)}, bg_color = self:get_bg_color(self._cell_color.asw, asw_max, args.asw_operator, args.asw_outstanding, args.asw_good)}
end

function EliteShipsKai:los(ship, args)
	local los_max = ship:los_max()
	return {values = {value = Formatting:format_stat(los_max)}, bg_color = self:get_bg_color(self._cell_color.los, los_max, args.los_operator, args.los_outstanding, args.los_good)}
end

function EliteShipsKai:luck(ship, args)
	local luck = ship:luck()
	local luck_max = ship:luck_max()
	return {values = {luck = Formatting:format_stat(luck), luck_max = self:get_emphasis(luck_max, Formatting:format_stat(luck_max), args.luck_max_operator, args.luck_max_good)}, bg_color = self:get_bg_color(self._cell_color.luck, luck, args.luck_operator, args.luck_outstanding, args.luck_good)}
end

function EliteShipsKai:hp(ship, args)
	local hp = ship:hp()
	return {values = {value = Formatting:format_stat(hp)}, bg_color = self:get_bg_color(self._cell_color.hp, hp, args.hp_operator, args.hp_outstanding, args.hp_good)}
end

function EliteShipsKai:armor(ship, args)
	local armor_max = ship:armor_max()
	return {values = {value = Formatting:format_stat(armor_max)}, bg_color = self:get_bg_color(self._cell_color.armor, armor_max, args.armor_operator, args.armor_outstanding, args.armor_good)}
end

function EliteShipsKai:evasion(ship, args)
	local evasion_max = ship:evasion_max()
	return {values = {value = Formatting:format_stat(evasion_max)}, bg_color = self:get_bg_color(self._cell_color.evasion, evasion_max, args.evasion_operator, args.evasion_outstanding, args.evasion_good)}
end

function EliteShipsKai:speed(ship, args)
	local speed = ship:speed()
	return {values = {value = Formatting:format_speed(speed)}, bg_color = self:get_bg_color(self._cell_color.speed, speed, args.speed_operator, args.speed_outstanding, args.speed_good)}
end

function EliteShipsKai:aircraft(ship, args)
	local aircraft = ship:total_space()
	local slots = {}
	if aircraft > 0 then
		for i = 1, ship:slots() do
			_, size = ship:slot(i)
			table.insert(slots, self:get_emphasis(size, Formatting:format_stat(size), args.aircraft_slot_operator, args.aircraft_slot_good))
		end
	end
	return {values = {value = Formatting:format_detailed_aircraft(aircraft, slots)}, bg_color = self:get_bg_color(self._cell_color.aircraft, aircraft, args.aircraft_operator, args.aircraft_outstanding, args.aircraft_good)}
end

function EliteShipsKai:fuel(ship, args)
	local fuel = ship:fuel()
	return {values = {value = Formatting:format_stat(fuel)}, bg_color = self:get_bg_color(self._cell_color.fuel, fuel, args.fuel_operator, args.fuel_outstanding, args.fuel_good)}
end

function EliteShipsKai:ammo(ship, args)
	local ammo = ship:ammo()
	return {values = {value = Formatting:format_stat(ammo)}, bg_color = self:get_bg_color(self._cell_color.ammo, ammo, args.ammo_operator, args.ammo_outstanding, args.ammo_good)}
end

function EliteShipsKai:notes(ship, args)
	return {values = {value = args.notes[ship] or ""}, bg_color = self._transparent}
end

function EliteShipsKai:compare_values(val1, val2)
	if #val1 == #val2 then
		for value_type, value in pairs(val1) do
			if value ~= val2[value_type] then
				return false
			end
		end
	else
		return false
	end
	return true
end

function EliteShipsKai:Table(args)
	--Process requested ships
	local ships = {}
	args.notes = {}
	for index, ship_name in ipairs(args) do
		if ship_name == "-" then
			ships[index] = "break"
		elseif ship_name == "#" then
			ships[index] = "header"
		else
			local split = mw.ustring.find(ship_name, '/')
			local ship_base_name, ship_suffix
			if split == nil then
				ship_base_name = ship_name
			else
				ship_base_name = mw.ustring.sub(ship_name, 1, split - 1)
				ship_suffix = mw.ustring.sub(ship_name, split + 1, -1)
			end
			local ship = Ship:create(ship_base_name, ship_suffix)
			ships[index] = ship
			args.notes[ship] = args[ship_name .. self._notes_suffix]
		end
	end

	local header_icons = {
		remodel_icon = MiscIcons.remodel, 
		firepower_icon = StatIcons.firepower, 
		torpedo_icon = StatIcons.torpedo, 
		aa_icon = StatIcons.aa, 
		asw_icon = StatIcons.asw, 
		los_icon = StatIcons.los, 
		luck_icon = StatIcons.luck, 
		hp_icon = StatIcons.hp, 
		armor_icon = StatIcons.armor,
		evasion_icon = StatIcons.evasion,
		speed_icon = StatIcons.speed,
		aircraft_icon = StatIcons.aircraft,
		fuel_icon = ResourceIcons.fuel,
		ammo_icon = ResourceIcons.ammo,
	}
	for key, value in pairs(header_icons) do
		header_icons[key] = Formatting:format_image(value)
	end
	local header = format(self._header_template, header_icons)

	local rows = {self._table_start, header}

	local data_rows = {}
	for index, ship in ipairs(ships) do
		local row_values
		if type(ship) == "string" then
			row_values = ship
		else
			row_values = {}
			for _, column in ipairs(self._columns) do
				row_values[column] = self[column](self, ship, args)
			end
			if index > 1 then
				for _, column in ipairs(self._columns) do
					for i=index-1,1,-1 do
						local previous_row = data_rows[i]
						local previous_row_type = type(previous_row) ~= "string"
						local previous_cell = previous_row_type and previous_row[column] or false
						if previous_cell then
							if self:compare_values(row_values[column].values, previous_cell.values) then
								previous_cell.rowspan = previous_cell.rowspan + 1
								row_values[column] = nil
							else
								row_values[column].rowspan = 1
							end
							break
						elseif not previous_row_type then
							row_values[column].rowspan = 1
						end
					end
				end
			else
				for _, column in ipairs(self._columns) do
					row_values[column].rowspan = 1
				end
			end
		end

		table.insert(data_rows, row_values)
	end

	for index, row_values in ipairs(data_rows) do
		if row_values ~= "break" then
			table.insert(rows, self._row_starter)
			if row_values == "header" then
				table.insert(rows, header)
			else
				for _, column in ipairs(self._columns) do
					if row_values[column] then
						table.insert(rows, format{self._column_cell_templates[column] or self._cell, value = row_values[column].values, rowspan = row_values[column].rowspan, bg_color = row_values[column].bg_color})
					end
				end
			end
		end
	end

	table.insert(rows, self._row_starter)
	table.insert(rows, header)
	table.insert(rows, self._table_end)
	return table.concat(rows, "\n")
end

return EliteShipsKai