Changes

no edit summary
Line 3: Line 3:  
local Ship
 
local Ship
 
local ShipClass = require('Module:ShipClass')
 
local ShipClass = require('Module:ShipClass')
 +
local dropData
 +
local sortIds = require("Module:DropList/Sort")
    
local BaseData = require("Module:BaseData")
 
local BaseData = require("Module:BaseData")
Line 10: Line 12:     
--Return the full name of the ship.
 
--Return the full name of the ship.
function ShipData:name()
+
function ShipData:name(sep)
 +
    sep = sep or " "
 
local suffix = self:display_suffix()
 
local suffix = self:display_suffix()
if suffix then
+
if suffix and suffix ~= "" then
return self:base_name() .. " " .. suffix
+
return self:base_name() .. sep .. suffix
 
else
 
else
 
return self:base_name()
 
return self:base_name()
Line 22: Line 25:  
--Differs from name() for some boss enemies that have a legacy role suffix,
 
--Differs from name() for some boss enemies that have a legacy role suffix,
 
--which isn't shown for unique_name().
 
--which isn't shown for unique_name().
function ShipData:unique_name()
+
function ShipData:unique_name(sep)
 +
    sep = sep or " "
 
local suffix = self:suffix()
 
local suffix = self:suffix()
if suffix then
+
if suffix and suffix ~= "" then
return self:base_name() .. " " .. self:suffix()
+
return self:base_name() .. sep .. self:suffix()
 
else
 
else
 
return self:base_name()
 
return self:base_name()
Line 38: Line 42:  
end
 
end
 
return self:base_name()
 
return self:base_name()
 +
end
 +
 +
function ShipData:lua_name()
 +
local key = self._key
 +
if key and key ~= "" then
 +
return self:base_name() .. "/" .. key
 +
else
 +
return self:base_name()
 +
end
 
end
 
end
   Line 61: Line 74:  
function ShipData:link()
 
function ShipData:link()
 
if self._page then
 
if self._page then
return self._page, self:name()
+
return self._page, self:unique_name()
else
+
elseif self._seasonal then
return self:name()
+
    return self:base_link()
 +
    elseif self._vita then
 +
        return string.format('KanColle Kai:%s', self:base_link()), self:unique_name()
 +
    else
 +
return self:unique_name()
 
end
 
end
 
end
 
end
Line 99: Line 116:  
function ShipData:reading_nick()
 
function ShipData:reading_nick()
 
return self._reading_nick
 
return self._reading_nick
 +
end
 +
 +
function ShipData:wikipedia()
 +
return self._wikipedia
 
end
 
end
   Line 111: Line 132:  
function ShipData:true_id()
 
function ShipData:true_id()
 
return self._true_id
 
return self._true_id
 +
end
 +
 +
function ShipData:sort_id()
 +
return sortIds[self._api_id] or 0
 
end
 
end
   Line 135: Line 160:  
function ShipData:type()
 
function ShipData:type()
 
return self._type
 
return self._type
 +
end
 +
 +
function ShipData:code()
 +
return Formatting:format_ship_code(self._type)
 +
end
 +
 +
function ShipData:formatted_type()
 +
return Formatting:format_ship_type(self._type)
 +
end
 +
 +
function ShipData:is_battleship()
 +
return self._type == 8 or self._type == 9 or self._type == 10 or self._type == 12
 +
end
 +
 +
function ShipData:is_carrier()
 +
return self._type == 7 or self._type == 11 or self._type == 18
 +
end
 +
 +
function ShipData:is_auxiliary()
 +
return self._type == 22 or self._type == 16 or self._type == 17 or self._type == 19 or self._type == 20
 +
end
 +
 +
function ShipData:is_submarine()
 +
return self._type == 13 or self._type == 14
 +
end
 +
 +
function ShipData:is_CL()
 +
return self._type == 3 or self._type == 4 or self._type == 21
 +
end
 +
 +
function ShipData:is_CA()
 +
return self._type == 5 or self._type == 6
 
end
 
end
   Line 145: Line 202:  
end
 
end
   −
function ShipData:card()
+
function ShipData:simple_naming()
 +
return self._simple_naming
 +
end
 +
 
 +
function ShipData:card(hd)
 
if self._card ~= nil then
 
if self._card ~= nil then
 
return self._card
 
return self._card
 
elseif self._card_reference then
 
elseif self._card_reference then
 
Ship = Ship or require(self._constructor_module)
 
Ship = Ship or require(self._constructor_module)
return Ship:create_from_reference(self._card_reference, self):card()
+
return Ship:create_from_reference(self._card_reference, self):card(hd)
 
end
 
end
api_id = self:api_id()
+
local api_id, simple_naming = self:api_id(), self:simple_naming()
if api_id then
+
if not api_id and not self:type() then
return Formatting:ship_card(api_id, self:unique_name(), self:type(), self._card_extension)
+
    return Formatting:ship_card(nil, self:unique_name(), nil, self._card_extension, true, hd)
 +
elseif api_id or simple_naming then
 +
return Formatting:ship_card(api_id, self:unique_name(), self:type(), self._card_extension, simple_naming, hd)
 
end
 
end
return self._card
   
end
 
end
   −
function ShipData:card_damaged()
+
function ShipData:card_damaged(hd)
 
if self._card_damaged ~= nil then
 
if self._card_damaged ~= nil then
 
return self._card_damaged
 
return self._card_damaged
 
elseif self._card_damaged_reference then
 
elseif self._card_damaged_reference then
 
Ship = Ship or require(self._constructor_module)
 
Ship = Ship or require(self._constructor_module)
return Ship:create_from_reference(self._card_damaged_reference, self):card_damaged()
+
return Ship:create_from_reference(self._card_damaged_reference, self):card_damaged(hd)
 
end
 
end
api_id = self:api_id()
+
local api_id, simple_naming = self:api_id(), self:simple_naming()
if api_id then
+
if not api_id and not self:type() then
return Formatting:ship_card_damaged(api_id, self:unique_name(), self:type(), self._card_damaged_extension)
+
    return Formatting:ship_card_damaged(nil, self:unique_name(), nil, self._card_damaged_extension, true, hd)
 +
elseif api_id or simple_naming then
 +
return Formatting:ship_card_damaged(api_id, self:unique_name(), self:type(), self._card_damaged_extension, simple_naming, hd)
 
end
 
end
return self._card_damaged
   
end
 
end
   −
function ShipData:battle_card()
+
function ShipData:battle_card(hd)
 
if self._battle_card ~= nil then
 
if self._battle_card ~= nil then
 
return self._battle_card
 
return self._battle_card
 
elseif self._battle_card_reference then
 
elseif self._battle_card_reference then
 
Ship = Ship or require(self._constructor_module)
 
Ship = Ship or require(self._constructor_module)
return Ship:create_from_reference(self._battle_card_reference, self):battle_card()
+
return Ship:create_from_reference(self._battle_card_reference, self):battle_card(hd)
 
end
 
end
 
api_id = self:api_id()
 
api_id = self:api_id()
if api_id then
+
if api_id or hd then
return Formatting:ship_battle_card(api_id, self:unique_name(), self:type(), self._battle_card_extension)
+
return Formatting:ship_battle_card(api_id, self:unique_name(), self:type(), self._battle_card_extension, false, hd)
 
end
 
end
 
return self._battle_card
 
return self._battle_card
Line 191: Line 254:  
end
 
end
   −
function ShipData:battle_card_damaged()
+
function ShipData:battle_card_damaged(hd)
 
if self._battle_card_damaged ~= nil then
 
if self._battle_card_damaged ~= nil then
 
return self._battle_card_damaged
 
return self._battle_card_damaged
 
elseif self._battle_card_damaged_reference then
 
elseif self._battle_card_damaged_reference then
 
Ship = Ship or require(self._constructor_module)
 
Ship = Ship or require(self._constructor_module)
return Ship:create_from_reference(self._battle_card_damaged_reference, self):battle_card_damaged()
+
return Ship:create_from_reference(self._battle_card_damaged_reference, self):battle_card_damaged(hd)
 
end
 
end
 
api_id = self:api_id()
 
api_id = self:api_id()
if api_id then
+
if api_id or hd then
return Formatting:ship_battle_card_damaged(api_id, self:unique_name(), self:type(), self._battle_card_damaged_extension)
+
    if self._can_debuff and api_id > 1500 then
 +
            return string.format("Enemy Banner %s Debuffed.png", self:unique_name():gsub("- Damaged", "Damaged"))
 +
        end
 +
return Formatting:ship_battle_card_damaged(api_id, self:unique_name(), self:type(), self._battle_card_damaged_extension, false, hd)
 
end
 
end
 
return self._battle_card_damaged
 
return self._battle_card_damaged
 
end
 
end
   −
function ShipData:cg()
+
function ShipData:cg(hd)
 
if self._cg ~= nil then
 
if self._cg ~= nil then
 
return self._cg
 
return self._cg
 
elseif self._cg_reference then
 
elseif self._cg_reference then
 
Ship = Ship or require(self._constructor_module)
 
Ship = Ship or require(self._constructor_module)
return Ship:create_from_reference(self._cg_reference, self):cg()
+
return Ship:create_from_reference(self._cg_reference, self):cg(hd)
end
+
else
api_id = self:api_id()
+
    local api_id, simple_naming = self:api_id(), self:simple_naming()
if api_id then
+
    if not api_id and not self:type() then
return Formatting:ship_cg(api_id, self:unique_name(), self:type(), self._cg_extension)
+
        return Formatting:ship_cg(nil, self:unique_name(), nil, self._cg_extension, true, hd)
end
+
    elseif api_id or simple_naming then
return self._cg
+
    return Formatting:ship_cg(api_id, self:unique_name(), self:type(), self._cg_extension, simple_naming, hd)
 +
    end
 +
    end
 
end
 
end
   −
function ShipData:cg_damaged()
+
function ShipData:cg_damaged(hd)
 
if self._cg_damaged ~= nil then
 
if self._cg_damaged ~= nil then
 
return self._cg_damaged
 
return self._cg_damaged
 
elseif self._cg_damaged_reference then
 
elseif self._cg_damaged_reference then
 
Ship = Ship or require(self._constructor_module)
 
Ship = Ship or require(self._constructor_module)
return Ship:create_from_reference(self._cg_damaged_reference, self):cg_damaged()
+
return Ship:create_from_reference(self._cg_damaged_reference, self):cg_damaged(hd)
 +
else
 +
    local api_id, simple_naming = self:api_id(), self:simple_naming()
 +
    if not api_id and not self:type() then
 +
        return Formatting:ship_cg_damaged(nil, self:unique_name(), nil, self._cg_damaged_extension, true, hd)
 +
    elseif api_id or simple_naming then
 +
        if self._can_debuff and api_id > 1500 then
 +
                return string.format("Enemy Full %s Debuffed.png", self:unique_name():gsub("- Damaged", "Damaged"))
 +
        end
 +
    return Formatting:ship_cg_damaged(api_id, self:unique_name(), self:type(), self._cg_damaged_extension, simple_naming, hd)
 +
    end
 
end
 
end
api_id = self:api_id()
+
end
if api_id then
+
 
return Formatting:ship_cg_damaged(api_id, self:unique_name(), self:type(), self._cg_damaged_extension)
+
function ShipData:accuracy()
end
+
return self._accuracy
return self._cg_damaged
+
end
 +
 
 +
function ShipData:morale()
 +
return self._morale
 
end
 
end
   Line 245: Line 326:  
end
 
end
   −
function ShipData:hp_leveled()
+
function ShipData:hp_mod()
 +
    local hp = self:hp()
 +
    local hp_max = self:hp_max()
 +
    return hp and hp_max and math.min(2, hp_max - hp)
 +
end
 +
 
 +
function ShipData:hp_mod_married()
 +
    local hp = self:hp_married()
 +
    local hp_max = self:hp_max()
 +
    return hp and hp_max and math.min(2, hp_max - hp)
 +
end
 +
 
 +
-- min(hp_max, hp + [4, 4, 4, 5, 6, 7, 7, 8, 8, 9][Math.floor(hp / 10)])
 +
function ShipData:hp_married()
 +
local bonuses = {
 +
[0] = 4,
 +
[1] = 4,
 +
[2] = 4,
 +
[3] = 5,
 +
[4] = 6,
 +
[5] = 7,
 +
[6] = 7,
 +
[7] = 8,
 +
[8] = 8,
 +
[9] = 9,
 +
}
 +
    local exceptions = {
 +
[131] = true, -- Yamato
 +
[143] = true, -- Musashi
 +
[163] = true, -- Maruyu
 +
-- [402] = true, -- Maruyu Kai (is +4, 7 -> 11)
 +
[171] = true, -- Bismarck
 +
[172] = true, -- Bismarck Kai
 +
[173] = true, -- Bismarck zwei
 +
[178] = true, -- Bismarck drei
 +
[275] = true, -- Nagato Kai
 +
[276] = true, -- Mutsu Kai
 +
[352] = true, -- Hayasui Kai
 +
[441] = true, -- Littorio
 +
[442] = true, -- Roma
 +
[446] = true, -- Italia
 +
[447] = true, -- Roma Kai
 +
[541] = true, -- Nagato Kai Ni
 +
}
 
local hp = self:hp()
 
local hp = self:hp()
if self._level and self._level > 100 then
+
local hp_max = self:hp_max()
return math.floor((self:hp_max() - hp) * (self._level - 99) / 51 + hp)
+
if not hp or not hp_max then
 +
return nil
 +
end
 +
-- not using exceptions should work as well
 +
if exceptions[self:api_id()] then
 +
return hp_max
 +
else
 +
local bonus = bonuses[math.floor(hp / 10)]
 +
if bonus then
 +
return math.min(hp_max, hp + bonus)
 +
else
 +
return nil
 +
end
 
end
 
end
return hp
   
end
 
end
   Line 397: Line 532:  
function ShipData:buildable_lsc()
 
function ShipData:buildable_lsc()
 
return self._buildable_lsc
 
return self._buildable_lsc
 +
end
 +
 +
function ShipData:buildable_or()
 +
return self._buildable or self._buildable_lsc
 +
end
 +
 +
function ShipData:buildable_and()
 +
return self._buildable and self._buildable_lsc
 
end
 
end
    
function ShipData:build_time()
 
function ShipData:build_time()
 
return self._build_time
 
return self._build_time
 +
end
 +
 +
local function prepareDropData()
 +
if not dropData then
 +
dropData = require('Module:Data/ShipDrop')
 +
end
 +
end
 +
 +
function ShipData:dropable()
 +
prepareDropData()
 +
return dropData[self._name] and true or false
 
end
 
end
   Line 416: Line 570:     
function ShipData:remodel_cost()
 
function ShipData:remodel_cost()
return {fuel = false, ammo = self._remodel_ammo, steel = self._remodel_steel, bauxite = false, devmat = self._remodel_development_material, screw = false}
+
return {
 +
    fuel = false,
 +
    ammo = self._remodel_ammo,
 +
    steel = self._remodel_steel,
 +
    bauxite = false,
 +
    devmat = self._remodel_development_material,
 +
    conmat = self._remodel_construction_material or false,
 +
    screw = self._remodel_screw or false,
 +
    }
 
end
 
end
   Line 425: Line 587:  
function ShipData:remodel_catapult()
 
function ShipData:remodel_catapult()
 
return self._remodel_catapult
 
return self._remodel_catapult
 +
end
 +
 +
function ShipData:remodel_report()
 +
return self._remodel_report
 +
end
 +
 +
function ShipData:remodel_gunmat()
 +
return self._remodel_gunmat
 +
end
 +
 +
function ShipData:remodel_airmat()
 +
return self._remodel_airmat
 +
end
 +
 +
function ShipData:remodel_armament()
 +
return self._remodel_armament
 +
end
 +
 +
function ShipData:remodel_development_material()
 +
return self._remodel_development_material
 +
end
 +
 +
function ShipData:remodel_construction_material()
 +
return self._remodel_construction_material
 +
end
 +
 +
function ShipData:remodel_screw()
 +
return self._remodel_screw
 
end
 
end
   Line 432: Line 622:     
function ShipData:remodel_to_cost()
 
function ShipData:remodel_to_cost()
return {fuel = false, ammo = self._remodel_to_ammo, steel = self._remodel_to_steel, bauxite = false, devmat = self._remodel_to_development_material, screw = false}
+
return {
 +
    fuel = false,
 +
    ammo = self._remodel_to_ammo,
 +
    steel = self._remodel_to_steel,
 +
    bauxite = false,
 +
    devmat = self._remodel_to_development_material,
 +
    conmat = self._remodel_to_construction_material or false,
 +
    screw = self._remodel_to_screw or false,
 +
    }
 
end
 
end
   Line 441: Line 639:  
function ShipData:remodel_to_catapult()
 
function ShipData:remodel_to_catapult()
 
return self._remodel_to_catapult
 
return self._remodel_to_catapult
 +
end
 +
 +
function ShipData:remodel_to_report()
 +
return self._remodel_to_report
 +
end
 +
 +
function ShipData:remodel_to_gunmat()
 +
return self._remodel_to_gunmat
 +
end
 +
 +
function ShipData:remodel_to_airmat()
 +
return self._remodel_to_airmat
 
end
 
end
   Line 448: Line 658:     
function ShipData:scrap()
 
function ShipData:scrap()
return {fuel = self._scrap_fuel, ammo = self._scrap_ammo, steel = self._scrap_steel, bauxite = self._scrap_baux, devmat = false, screw = false}
+
return {fuel = self._scrap_fuel, ammo = self._scrap_ammo, steel = self._scrap_steel, bauxite = self._scrap_baux, devmat = false, conmat = false, screw = false}
 
end
 
end
   Line 475: Line 685:  
if type(equipment_slot.equipment) == "string" then
 
if type(equipment_slot.equipment) == "string" then
 
self:_prepare_Equipment()
 
self:_prepare_Equipment()
equipment_slot.equipment = Equipment(equipment_slot.equipment)
+
equipment_slot.equipment = Equipment(equipment_slot.equipment, self._enemy)
 
end
 
end
return equipment_slot.equipment, equipment_slot.size, equipment_slot.estimation
+
return equipment_slot.equipment, equipment_slot.size, equipment_slot.estimation, equipment_slot.stars
 
end
 
end
 
end
 
end
Line 515: Line 725:  
function ShipData:speed()
 
function ShipData:speed()
 
return self._speed
 
return self._speed
 +
end
 +
 +
function ShipData:formatted_speed()
 +
return Formatting:format_speed(self._speed)
 
end
 
end
   Line 521: Line 735:  
end
 
end
   −
function ShipData:air_power()
+
function ShipData:formatted_range()
 +
return Formatting:format_range(self._range)
 +
end
 +
 
 +
function ShipData:equipment_armor()
 +
    local armor = 0
 +
    for i = 1, self:slots_length() or 0 do
 +
        local equipment = self:slot(i)
 +
        if equipment then
 +
            armor = armor + (equipment:armor() or 0)
 +
        end
 +
    end
 +
    return armor
 +
end
 +
 
 +
function ShipData:air_power(count_recons)
 +
    if self._air_power then
 +
        return self._air_power
 +
    end
 
     local air_power = 0
 
     local air_power = 0
     for i = 1, self:slots_length() or 0 do
+
    local slots_length = self:slots_length()
 +
    if not slots_length then
 +
        air_power = self._as_rating
 +
    end
 +
     for i = 1, slots_length or 0 do
 
         local slot_equipment, slot_space = self:slot(i)
 
         local slot_equipment, slot_space = self:slot(i)
 
         if slot_equipment == nil or slot_space == nil then
 
         if slot_equipment == nil or slot_space == nil then
Line 537: Line 773:  
                 slot_equipment_type == 7 or  
 
                 slot_equipment_type == 7 or  
 
                 slot_equipment_type == 8 or  
 
                 slot_equipment_type == 8 or  
                 slot_equipment_type == 11) then
+
                 slot_equipment_type == 11 or
 +
                slot_equipment_type == 47 or
 +
                count_recons and slot_equipment_type == 10) then
 
                 air_power = air_power +  
 
                 air_power = air_power +  
 
                   math.floor(math.sqrt(slot_space) * slot_equipment_aa)
 
                   math.floor(math.sqrt(slot_space) * slot_equipment_aa)
Line 548: Line 786:  
     end
 
     end
 
     return air_power
 
     return air_power
 +
end
 +
 +
function ShipData:has_lbas_ha_bomber()
 +
    for i = 1, self:slots_length() or 0 do
 +
        local equipment = self:slot(i)
 +
        if equipment and equipment:is_lbas_ha_bomber() then
 +
            return true
 +
        end
 +
    end
 +
    return false
 +
end
 +
 +
function ShipData:air_power_estimation(count_recons)
 +
    return self._air_power_estimation
 
end
 
end
   Line 560: Line 812:  
function ShipData:night_bombing()
 
function ShipData:night_bombing()
 
return self._night_bombing
 
return self._night_bombing
 +
end
 +
 +
function ShipData:night_aviation_personnel()
 +
return self._night_aviation_personnel
 
end
 
end
   Line 602: Line 858:  
--nil = unknown.
 
--nil = unknown.
 
--Otherwise a table with obtainment methods under numeric keys and optional detailed data under the obtainment method key.
 
--Otherwise a table with obtainment methods under numeric keys and optional detailed data under the obtainment method key.
--E.g. {"buildable", "drop", "event_reward", "event_drop",  
+
--E.g. {"drop", "event_reward", "event_drop",  
 
--      drop = {{1/*world*/, 4/*map*/, "B"/*node*/, 3/*formation (optional)*/}, {3, 2, "A"}},
 
--      drop = {{1/*world*/, 4/*map*/, "B"/*node*/, 3/*formation (optional)*/}, {3, 2, "A"}},
 
--      event_reward = {{2016/*year*/, 4/*1 = winter, 4 = spring, 7 = summer, 10 = fall*/, 5/*map*/}},
 
--      event_reward = {{2016/*year*/, 4/*1 = winter, 4 = spring, 7 = summer, 10 = fall*/, 5/*map*/}},
Line 612: Line 868:  
return Ship:create_from_reference(self:remodel_from(), self):availability()
 
return Ship:create_from_reference(self:remodel_from(), self):availability()
 
else
 
else
    local availability = self._availability or {}
+
    return self._availability
    local buildable = false
  −
    if self:buildable() then
  −
        buildable = true
  −
        availability.buildable = availability.buildable or {}
  −
        availability.buildable.normal = true
  −
    end
  −
    if self:buildable_lsc() then
  −
        buildable = true
  −
        availability.buildable = availability.buildable or {}
  −
        availability.buildable.lsc = true
  −
    end
  −
    if buildable then
  −
        table.insert(availability, 1, "buildable")
  −
    end
  −
    if #availability == 0 then
  −
        return self._availability
  −
    end
  −
        return availability
   
end
 
end
 
end
 
end
   −
--The implementation date for this ship. A 3-tuple of year, month, day (JST) as a table, or nil if unknown.
  −
--EXPERIMENTAL, DO NOT USE. Spec for this feature may rapidly change.
   
function ShipData:implementation_date()
 
function ShipData:implementation_date()
 
if self._implementation_date ~= nil then
 
if self._implementation_date ~= nil then
Line 644: Line 880:  
end
 
end
 
     return self._implementation_date
 
     return self._implementation_date
 +
end
 +
 +
function ShipData:implementation_date_string()
 +
local date = self:implementation_date()
 +
    return not date and "??" or string.format("%s/%s/%s", date[1], date[2] < 10 and "0" .. date[2] or date[2], date[3] < 10 and "0" .. date[3] or date[3])
 
end
 
end
   Line 654: Line 895:  
function ShipData:create(ship)
 
function ShipData:create(ship)
 
ship = ship or {}
 
ship = ship or {}
if ship._class then
+
-- apparently wikia (mediawiki?) can have shared state between invokes
 +
if type(ship._class) == 'string' then
 
ship._class = ShipClass(ship._class)
 
ship._class = ShipClass(ship._class)
 
end
 
end
cssedit, gkautomate
6,928

edits