| Line 5: |
Line 5: |
| | -- generalize equipment/enemy iterators | | -- generalize equipment/enemy iterators |
| | | | |
| − | local U = require('Module:Utils') | + | local U = require('Module:Core') |
| − | local EquipmentData = require('Module:EquipmentData') | + | local Equipment = require('Module:Equipment') |
| − | local CollectionEquipment = require('Module:Collection/Equipment') | + | local Ship = require('Module:Ship') |
| | + | local CollectionShips = require('Module:Collection/Ships') |
| | + | local CollectionEquipment = require('Module:Data/Equipment') |
| | local EnemyShip = require('Module:EnemyShip') | | local EnemyShip = require('Module:EnemyShip') |
| | local CollectionEnemy = require('Module:Collection/EnemyShips') | | local CollectionEnemy = require('Module:Collection/EnemyShips') |
| Line 34: |
Line 36: |
| | function numberKey(name, context, n, default) | | function numberKey(name, context, n, default) |
| | return context and tonumber(context[name .. (n and tostring(n) or '')]) or default | | return context and tonumber(context[name .. (n and tostring(n) or '')]) or default |
| | + | end |
| | + | |
| | + | -- * Ship iterators. |
| | + | |
| | + | function Iterator.shipsByNo(context) |
| | + | local extra = stringKey('extra', context) |
| | + | local function prefix(i) |
| | + | if extra then |
| | + | i = i + 1300 |
| | + | end |
| | + | if (i - 1) % 10 == 0 then |
| | + | local key = 'key' .. i |
| | + | context['custom_row_' .. key .. '_content'] = string.format('==No.%d-%d==', i, i - 1 + 10) |
| | + | return '!' .. key |
| | + | end |
| | + | end |
| | + | local collection = U.ifilter(require('Module:Collection/ShipsByNo'), function(e) |
| | + | if extra then |
| | + | return e.no >= 1301 |
| | + | else |
| | + | return e.no < 1301 |
| | + | end |
| | + | end) |
| | + | local i = 0 |
| | + | local current |
| | + | local prefixFlag = true |
| | + | return { |
| | + | next = function() |
| | + | i = i + 1 |
| | + | local e = collection[i] |
| | + | if e then |
| | + | local prefixValue = prefix(i) |
| | + | if prefixFlag and prefixValue then |
| | + | i = i - 1 |
| | + | current = prefixValue |
| | + | prefixFlag = false |
| | + | else |
| | + | current = e.name or '-' |
| | + | prefixFlag = true |
| | + | end |
| | + | return true |
| | + | end |
| | + | return false |
| | + | end, |
| | + | current = function() |
| | + | return current |
| | + | end, |
| | + | } |
| | + | end |
| | + | |
| | + | function Iterator.shipsBy(context, n, pred, pre, nItems) |
| | + | local predKey = stringKey('pred', context, n) |
| | + | local pred2 |
| | + | if predKey then |
| | + | pred2 = function(e) |
| | + | local obj = Ship(e._name) |
| | + | return obj[predKey](obj) |
| | + | end |
| | + | end |
| | + | local preCollection |
| | + | local collectionKey = stringKey('collection', context, n) |
| | + | if collectionKey then |
| | + | local _, CollectionData = U.requireModule(string.format("Collection/%s", collectionKey)) |
| | + | preCollection = U.icopy(CollectionData) |
| | + | else |
| | + | preCollection = U.icopy(CollectionShips) |
| | + | end |
| | + | |
| | + | local allowedRemodels = context['allowedRemodels'] |
| | + | local listBase = (context['listBase'] == 'true') |
| | + | local collection = {} |
| | + | local index = 1 |
| | + | for i = 1, #preCollection do |
| | + | local _, CollectionData = U.requireModule(string.format("Data/Ship/%s", preCollection[i])) |
| | + | if _ and CollectionData then |
| | + | for j,v in pairs(CollectionData) do |
| | + | if v._suffix then |
| | + | if (allowedRemodels == nil or allowedRemodels[v._suffix]) then |
| | + | local fullName = string.format("%s/%s", v._name, v._suffix) |
| | + | collection[index] = v |
| | + | collection[index]._fullName = fullName |
| | + | index = index + 1 |
| | + | end |
| | + | elseif v._id then |
| | + | if v._remodel_from or (v._name and listBase) then |
| | + | collection[index] = v |
| | + | collection[index]._fullName = v._name |
| | + | index = index + 1 |
| | + | end |
| | + | end |
| | + | end |
| | + | end |
| | + | end |
| | + | |
| | + | local sortKey = stringKey('sort', context, n) |
| | + | if sortKey then |
| | + | table.sort(collection, function(a, b) |
| | + | if a[sortKey] and b[sortKey] and a[sortKey] ~= b[sortKey] then |
| | + | return a[sortKey] < b[sortKey] |
| | + | elseif a._id == b._id then |
| | + | return a._api_id < b._api_id |
| | + | else |
| | + | return a._id < b._id |
| | + | end |
| | + | end) |
| | + | end |
| | + | |
| | + | local i = 1 |
| | + | local current = nil |
| | + | local preFlag = true |
| | + | local nCollection = nItems == true and #collection or nItems or #collection |
| | + | return { |
| | + | next = function() |
| | + | for _ = i, nCollection do |
| | + | local e |
| | + | if nItems then |
| | + | e = U.ifindBy(collection, function(e) return e._id == i end) or { _id = i } |
| | + | else |
| | + | e = collection[i] |
| | + | end |
| | + | if (pred and not pred(e, i)) or (pred2 and not pred2(e, i)) then |
| | + | i = i + 1 |
| | + | else |
| | + | if pre and preFlag then |
| | + | local value = pre(e, i) |
| | + | if value then |
| | + | current = value |
| | + | preFlag = false |
| | + | return true |
| | + | end |
| | + | end |
| | + | current = e._fullName |
| | + | if nItems and not current then |
| | + | current = '-' |
| | + | end |
| | + | i = i + 1 |
| | + | preFlag = true |
| | + | return true |
| | + | end |
| | + | end |
| | + | current = nil |
| | + | return false |
| | + | end, |
| | + | current = function() |
| | + | return current |
| | + | end, |
| | + | } |
| | + | end |
| | + | |
| | + | function Iterator.shipsByType(context, n) |
| | + | local type = numberKey('type', context, n) |
| | + | return Iterator.shipsBy(context, n, function(e) |
| | + | return type == nil or e._type == type |
| | + | end) |
| | + | end |
| | + | |
| | + | function Iterator.shipsByTrueId(context, n) |
| | + | local from = numberKey('from', context, n, 1) |
| | + | local to = numberKey('to', context, n, 1500) |
| | + | return Iterator.shipsBy(context, n, function(e) |
| | + | if e._true_id then |
| | + | return e._true_id >= from and e._true_id <= to |
| | + | else |
| | + | return e._id >= from and e._id <= to |
| | + | end |
| | + | end) |
| | end | | end |
| | | | |
| | -- * Equipment iterators. | | -- * Equipment iterators. |
| | | | |
| − | function Iterator.equipmentBy(context, n, pred, pre) | + | function Iterator.equipmentBy(context, n, pred, pre, nItems) |
| | local predKey = stringKey('pred', context, n) | | local predKey = stringKey('pred', context, n) |
| | + | local pred2 |
| | if predKey then | | if predKey then |
| − | pred = function(e) | + | pred2 = function(e) |
| − | local obj = EquipmentData(e) | + | local obj = Equipment(e._name) |
| | return obj[predKey](obj) | | return obj[predKey](obj) |
| | end | | end |
| Line 49: |
Line 218: |
| | local collectionKey = stringKey('collection', context, n) | | local collectionKey = stringKey('collection', context, n) |
| | if collectionKey then | | if collectionKey then |
| − | local _, CollectionData = U.requireModule(string.format("Collection/%s", collectionKey)) | + | local _, CollectionData = U.requireModule(collectionKey == 'Equipment' and 'Data/Equipment' or string.format("Collection/%s", collectionKey)) |
| | collection = U.icopy(CollectionData) | | collection = U.icopy(CollectionData) |
| | else | | else |
| Line 67: |
Line 236: |
| | local current = nil | | local current = nil |
| | local preFlag = true | | local preFlag = true |
| | + | local nCollection = nItems == true and #collection or nItems or #collection |
| | return { | | return { |
| | next = function() | | next = function() |
| − | for _ = i, #collection do | + | for _ = i, nCollection do |
| − | local e = collection[i] | + | local e |
| − | if pred(e, i) then | + | if nItems then |
| | + | e = U.ifindBy(collection, function(e) return e._id == i end) or { _id = i } |
| | + | else |
| | + | e = collection[i] |
| | + | end |
| | + | if pred and not pred(e, i) or pred2 and not pred2(e, i) then |
| | + | i = i + 1 |
| | + | else |
| | if pre and preFlag then | | if pre and preFlag then |
| | local value = pre(e, i) | | local value = pre(e, i) |
| Line 81: |
Line 258: |
| | end | | end |
| | current = e._name | | current = e._name |
| | + | if nItems and not current then |
| | + | current = '-' |
| | + | end |
| | i = i + 1 | | i = i + 1 |
| | preFlag = true | | preFlag = true |
| | return true | | return true |
| | end | | end |
| − | i = i + 1
| |
| | end | | end |
| | current = nil | | current = nil |
| Line 98: |
Line 277: |
| | function Iterator.equipmentById(context, n) | | function Iterator.equipmentById(context, n) |
| | local from = numberKey('from', context, n, 1) | | local from = numberKey('from', context, n, 1) |
| − | local to = numberKey('to', context, n, 500) | + | local to = numberKey('to', context, n, 1500) |
| | return Iterator.equipmentBy(context, n, function(e) | | return Iterator.equipmentBy(context, n, function(e) |
| | return e._id >= from and e._id <= to | | return e._id >= from and e._id <= to |
| Line 106: |
Line 285: |
| | function Iterator.equipmentByIdWithHeaders(context, n) | | function Iterator.equipmentByIdWithHeaders(context, n) |
| | local from = numberKey('from', context, n, 1) | | local from = numberKey('from', context, n, 1) |
| − | local to = numberKey('to', context, n, 500) | + | local to = numberKey('to', context, n, 1500) |
| | local prevMod = 0 | | local prevMod = 0 |
| | return Iterator.equipmentBy( | | return Iterator.equipmentBy( |
| Line 117: |
Line 296: |
| | if currentMod <= prevMod then | | if currentMod <= prevMod then |
| | prevMod = currentMod | | prevMod = currentMod |
| − | return "!#No " .. U.pad(e._id - currentMod, 3, "0") .. " - " .. U.pad(e._id - currentMod + 9, 3, "0") | + | local title = string.format("No. %s - %s", U.pad(e._id - currentMod, 3, "0"), U.pad(e._id - currentMod + 9, 3, "0")) |
| | + | return string.format("!#[[Equipment#%s|%s]]", title, title) |
| | else | | else |
| | prevMod = currentMod | | prevMod = currentMod |
| Line 123: |
Line 303: |
| | end | | end |
| | end | | end |
| | + | ) |
| | + | end |
| | + | |
| | + | function Iterator.equipmentByIdWithEmptyWithHeaders(context, n) |
| | + | local from = numberKey('from', context, n, 1) |
| | + | local to = numberKey('to', context, n, 1500) |
| | + | local prevMod = 0 |
| | + | local nItems = (math.floor(U.ilast(CollectionEquipment)._id / 10) + 1) * 10 |
| | + | return Iterator.equipmentBy( |
| | + | context, n, |
| | + | function(e) |
| | + | return e._id >= from and e._id <= to |
| | + | end, |
| | + | function(e) |
| | + | local currentMod = (e._id - 1) % 10 |
| | + | if currentMod <= prevMod then |
| | + | prevMod = currentMod |
| | + | local title = string.format("No. %s - %s", U.pad(e._id - currentMod, 3, "0"), U.pad(e._id - currentMod + 9, 3, "0")) |
| | + | return string.format("!#[[Equipment#%s|%s]]", title, title) |
| | + | else |
| | + | prevMod = currentMod |
| | + | return false |
| | + | end |
| | + | end, |
| | + | nItems |
| | ) | | ) |
| | end | | end |
| Line 130: |
Line 335: |
| | return Iterator.equipmentBy(context, n, function(e) | | return Iterator.equipmentBy(context, n, function(e) |
| | return e._type == type | | return e._type == type |
| | + | end) |
| | + | end |
| | + | |
| | + | function Iterator.equipmentByIcon(context, n) |
| | + | return Iterator.equipmentBy(context, n, function(e) |
| | + | return e._icon == numberKey('icon', context, n) |
| | end) | | end) |
| | end | | end |
| Line 144: |
Line 355: |
| | | | |
| | function Iterator.enemiesBy(context, n, pred, pre) | | function Iterator.enemiesBy(context, n, pred, pre) |
| − | local collection = U.imap(CollectionEnemy, function(name) | + | local base_ids = {} |
| − | return EnemyShip(name)
| + | local collection = U.imap(CollectionEnemy, function(name, i) |
| | + | local obj = EnemyShip(name) |
| | + | if not base_ids[obj:base_name()] then |
| | + | base_ids[obj:base_name()] = i |
| | + | end |
| | + | return obj |
| | end) | | end) |
| | table.sort(collection, function(a, b) | | table.sort(collection, function(a, b) |
| − | local ai = U.ifind(CollectionEnemy, a:base_name()) | + | local ai = base_ids[a:base_name()] |
| − | local bi = U.ifind(CollectionEnemy, b:base_name()) | + | local bi = base_ids[b:base_name()] |
| | if ai and bi and ai ~= bi then | | if ai and bi and ai ~= bi then |
| | return ai < bi | | return ai < bi |
| | + | elseif a._id and b._id and a._id ~= b._id then |
| | + | return a._id < b._id |
| | else | | else |
| − | return a._id < b._id
| + | return false |
| | end | | end |
| | end) | | end) |
| Line 199: |
Line 417: |
| | | | |
| | local selectInstallation = stringKey('installation', context, n, ''):lower() | | local selectInstallation = stringKey('installation', context, n, ''):lower() |
| − | local predInstallation = function(e) | + | local predInstallation = selectInstallation == 'yes' and |
| − | if selectInstallation == 'yes' then
| + | function(e) return e._speed == 0 end |
| − | return e._speed == 0
| + | or selectInstallation == 'no' and |
| − | elseif selectInstallation == 'no' then | + | function(e) return e._speed ~=0 end |
| − | return e._speed ~= 0
| + | or |
| − | else | + | function(e) return true end |
| − | return true
| |
| − | end
| |
| − | end
| |
| | | | |
| | local selectBoss = stringKey('boss', context, n, ''):lower() | | local selectBoss = stringKey('boss', context, n, ''):lower() |
| − | local predBoss = function(e) | + | |
| − | if selectBoss == 'yes' then
| + | local predBoss = selectBoss == 'yes' and |
| − | return e._back <= -11
| + | function(e) return e._boss ~= false and (e._boss == true or (e._back or -11) <= -11) end |
| − | elseif selectBoss == 'no' then | + | or selectBoss == 'no' and |
| − | return e._back >= -10
| + | function(e) return e._boss ~= true and (e._boss == false or (e._back or -11) >= -10) end |
| − | else | + | or |
| − | return true
| + | function(e) return true end |
| − | end
| |
| − | end
| |
| | | | |
| | return Iterator.enemiesBy(context, n, function(e) | | return Iterator.enemiesBy(context, n, function(e) |
| − | return (e:type() == type or type == 0) | + | return e._hp -- skip unimplemented units |
| − | and e._hp -- skip unimplemented units
| + | and (e:type() == type |
| | + | or type == 0 |
| | + | or type < 0 and e:type() ~= -type) -- skip SS-typed bosses |
| | and predInstallation(e) | | and predInstallation(e) |
| | and predBoss(e) | | and predBoss(e) |
| Line 239: |
Line 454: |
| | mw.log() | | mw.log() |
| | end | | end |
| − | testIterator('equipmentById', { from = '11', to = '20' }) | + | |
| − | testIterator('equipmentByIdWithHeaders', { from = '1', to = '30' }) | + | --testIterator('shipsByType', { type = '11', sort = '_class' , listBase = 'true'}) |
| − | testIterator('equipmentByType', { type = '2' }) | + | --testIterator('shipsByType', { sort = '_name'}) |
| − | testIterator('equipmentByType', { type = '1', sort = '_icon' }) | + | --testIterator('shipsByTrueId', { sort = '_id', from = '1', to = '20', listBase = 'true'}) |
| − | testIterator('equipmentByTypeAndIcon', { type = '1', icon = '16' }) | + | --testIterator('shipsBy', { pred = 'is_auxiliary' , sort = '_name'}) |
| − | testIterator('equipmentBy', { pred = 'is_large_caliber_main_gun', sort = '_type' }) | + | |
| − | testIterator('enemiesByType', { type = '2' }) | + | --testIterator('equipmentById', { from = '11', to = '20' }) |
| | + | --testIterator('equipmentByIdWithHeaders', { from = '1', to = '30' }) |
| | + | --testIterator('equipmentByType', { type = '2' }) |
| | + | --testIterator('equipmentByType', { type = '1', sort = '_icon' }) |
| | + | --testIterator('equipmentByTypeAndIcon', { type = '1', icon = '16' }) |
| | + | --testIterator('equipmentBy', { pred = 'is_large_caliber_main_gun', sort = '_type' }) |
| | + | |
| | + | testIterator('enemiesByType', { type = '8' }) |
| | end | | end |
| | -- p.test() | | -- p.test() |
| | | | |
| | return Iterator | | return Iterator |