全站通知:

模块:Crop Growth Calendars

来自星露谷物语维基
跳到导航 跳到搜索

当前模块的原作者是 Horizon98,感谢原作者。

[ 查看 | 编辑 | 历史 | 刷新 ]上述文档的内容来自模块:Crop Growth Calendars/doc
local cache = require "mw.ext.LuaCache"
local KEY_PREFIX = "Crop Growth Calendars"
local EXP_TIME = 172800
local p = {}
local private = {}
local Helper = require("Module:Helper")
local ID = require("Module:ID")
local Name = require("Module:Name")
local data = Helper.LazyLoad('Module:Crops/data')

----------main function----------
function p.calendar(frame)
	-- input args
    local rawArgs = frame.args
    local args = {}
    for k, v in pairs(rawArgs) do
        if type(v) == 'string' and not v:match('%S') then
            v = nil
        end
        args[k] = v
    end
    
    local name = args.name
    local cacheKey = KEY_PREFIX .. name
    if (cache.get(cacheKey)) then
    	local result = cache.get(cacheKey)
    	return result
    end

    local size = tonumber(args.size) or 36
    local speedIncrease = tonumber(args.increase) or 0
    local season = args.season
    local irrigation = args.irrigation
    local mode = args.mode
    local title = args.title
    local stageImage = args.image1 or (name and (name .. ' Stage') or nil)
    local cropImage = args.image2 or name
    

    ----------Dictionary----------
    Dictionary = {
        ['speedGro'] = '[[生长激素]]',
        ['deluxeSpeedGro'] = '[[高级生长激素]]',
        ['hyperSpeedGro'] = '[[顶级生长激素]]',
        ['agriculturist'] = '农业学家',

        ['monday'] = '一',
        ['tuesday'] = '二',
        ['wednesday'] = '三',
        ['thursday'] = '四',
        ['friday'] = '五',
        ['saturday'] = '六',
        ['sunday'] = '日',
        ['spring'] = '春季',
        ['summer'] = '夏季',
        ['fall'] = '秋季',
        ['winter'] = '冬季',

        ['collapsibleTable1'] = '[[耕种#耕种技能|农业学家]]和生长激素的对比',
        ['collapsibleTable1Unirrigated'] = '农业学家和生长激素的对比 - 普通',
        ['collapsibleTable2Irrigated'] = '农业学家和生长激素的对比 - 临近水域',
        ['regular'] = '无职业加成',
        ['note'] = '提示:职业为[[技能#耕种|农业学家]]并且没有使用任何肥料时,生长日历与此表格一致。',
        ['dayOne'] = ' 1 日',
        ['base'] = '无任何加成',
        ['irrigated'] = ' - 临近水域',
        ['unirrigated'] = ' - 普通',
        ['ifPlantOn'] = '(如果在',
        ['closeParen'] = '种植)'
    }

    ----------crops' data----------
    -- Get crop data from new format

    local id = ID.id {args = {name}}
    if id:sub(1, 3) == "(O)" then id = id:sub(4) end

    -- Find crop seed ID by HarvestItemId
    local seedId = nil
    for cropKey, cropInfo in pairs(data) do
        if cropInfo['HarvestItemId'] == id then
            seedId = cropKey
            break
        end
    end

    local eng = Name.reverse_name {args = {name}}
    if eng ~= '' then
    	name = eng
    	stageImage = args.image1 or (name and (name .. ' Stage') or nil)
    	cropImage = args.image2 or name
    end

    -- Use the found seed ID or fall back to original name
    local cropLookupKey = seedId or name
    local cropData = data[cropLookupKey]
    if not cropData then
        error("Crop data not found for harvest item ID: " .. id ..
                  " (original name: " .. name .. ")")
    end

    local phaseDays = cropData['DaysInPhase']
    if not season then
        -- Convert seasons to lowercase for compatibility
        season = {}
        for i, s in ipairs(cropData['Seasons']) do
            season[i] = string.lower(s)
        end
    else
        season = mw.text.split(season, " ")
    end
    local regrowth = cropData['RegrowDays']

    -- When mode = 'base', only return base wikitable
    if mode == 'base' then
        return p.month(name, size, phaseDays, regrowth, speedIncrease, season,
                       '', stageImage, cropImage, title)
    end

    ----------cropCalendars begin (irrigation='yes')---------- 
    local cropCalendars = ''
    -- whether the crop can be irrigated or not
    if irrigation == 'yes' then

        -- Base form
        cropCalendars = cropCalendars .. '<table><tr><td>' ..
                            p.month(name, '', phaseDays, regrowth, 0, season,
                                    'no', stageImage, cropImage) .. '</td><td>' ..
                            p.month(name, '', phaseDays, regrowth, 0, season,
                                    'yes', stageImage, cropImage) ..
                            '</td></tr></table>' ..

            -- Agriculturist and Speed-Gro Comparison - Unirrigated
                            '<table class=\"wikitable roundedborder mw-collapsible mw-collapsed\" style="text-align:center;\">' ..
                            '<tr><th colspan=\"4\" style=\"min-width:450px; min-height:40px;\">' ..
                            Dictionary['collapsibleTable1Unirrigated'] ..
                            '</th></tr>' .. '<tr>' ..
                            '<th></th><th>[[File:Speed-Gro.png|24px|link=]] ' ..
                            Dictionary['speedGro'] .. '</th>' ..
                            '<th>[[File:Deluxe Speed-Gro.png|24px|link=]] ' ..
                            Dictionary['deluxeSpeedGro'] .. '</th>' ..
                            '<th>[[File:Hyper Speed-Gro.png|24px|link=]] ' ..
                            Dictionary['hyperSpeedGro'] .. '</th>' ..
                            '</tr><tr>' ..
                            '<th rowspan=\"2\" style=\"max-width: 2em; padding: 0;\"><div>' ..
                            Dictionary['regular'] .. '</div></th>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.1,
                                    season, 'no', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.25,
                                    season, 'no', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.33,
                                    season, 'no', stageImage, cropImage) ..
                            '</td>' .. '</tr>' .. '<tr>' ..
                            '<td colspan=\"3\" style=\"background-color: transparent; padding: 0 0 0 8px; text-align: left; font-size: smaller; border: 0;\">*' ..
                            Dictionary['note'] .. '</td>' .. '</tr>' .. '<tr>' ..
                            '<th style=\"max-width: 2em; padding: 0;\"><div>[[File:Agriculturist.png|24px|link=]] ' ..
                            Dictionary['agriculturist'] .. '</div></th>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.2,
                                    season, 'no', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.35,
                                    season, 'no', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\"|>' ..
                            p.month(name, size, phaseDays, regrowth, 0.43,
                                    season, 'no', stageImage, cropImage) ..
                            '</td>' .. '</tr></table>' ..

            -- Agriculturist and Speed-Gro Comparison - Irrigated
                            '<table class=\"wikitable roundedborder mw-collapsible mw-collapsed\" style="text-align:center;\">' ..
                            '<tr><th colspan=\"4\" style=\"min-width:450px; min-height:40px;\">' ..
                            Dictionary['collapsibleTable2Irrigated'] ..
                            '</th></tr>' .. '<tr>' ..
                            '<th></th><th>[[File:Speed-Gro.png|24px|link=]] ' ..
                            Dictionary['speedGro'] .. '</th>' ..
                            '<th>[[File:Deluxe Speed-Gro.png|24px|link=]] ' ..
                            Dictionary['deluxeSpeedGro'] .. '</th>' ..
                            '<th>[[File:Hyper Speed-Gro.png|24px|link=]] ' ..
                            Dictionary['hyperSpeedGro'] .. '</th>' ..
                            '</tr><tr>' ..
                            '<th rowspan=\"2\" style=\"max-width: 2em; padding: 0;\"><div>' ..
                            Dictionary['regular'] .. '</div></th>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.1,
                                    season, 'yes', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.25,
                                    season, 'yes', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.33,
                                    season, 'yes', stageImage, cropImage) ..
                            '</td>' .. '</tr>' .. '<tr>' ..
                            '<td colspan=\"3\" style=\"background-color: transparent; padding: 0 0 0 8px; text-align: left; font-size: smaller; border: 0;\">*' ..
                            Dictionary['note'] .. '</td>' .. '</tr>' .. '<tr>' ..
                            '<th style=\"max-width: 2em; padding: 0;\"><div>[[File:Agriculturist.png|24px|link=]] ' ..
                            Dictionary['agriculturist'] .. '</div></th>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.2,
                                    season, 'yes', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.35,
                                    season, 'yes', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\"|>' ..
                            p.month(name, size, phaseDays, regrowth, 0.43,
                                    season, 'yes', stageImage, cropImage) ..
                            '</td>' .. '</tr></table>'

        ----------cropCalendars begin (irrigation=default)----------
        -- Base form
    else
        cropCalendars = cropCalendars ..
                            p.month(name, '', phaseDays, regrowth, 0, season,
                                    '', stageImage, cropImage) ..
                            '<table class=\"wikitable roundedborder mw-collapsible mw-collapsed\" style="text-align:center;\">' ..
                            '<tr><th colspan=\"4\" style=\"min-width:450px; min-height:40px;\">' ..
                            Dictionary['collapsibleTable1'] .. '</th></tr>' ..
                            '<tr>' ..
                            '<th></th><th>[[File:Speed-Gro.png|24px|link=]] ' ..
                            Dictionary['speedGro'] .. '</th>' ..
                            '<th>[[File:Deluxe Speed-Gro.png|24px|link=]] ' ..
                            Dictionary['deluxeSpeedGro'] .. '</th>' ..
                            '<th>[[File:Hyper Speed-Gro.png|24px|link=]] ' ..
                            Dictionary['hyperSpeedGro'] .. '</th>' ..
                            '</tr><tr>' ..
                            '<th rowspan=\"2\" style=\"max-width: 2em; padding: 0;\"><div>' ..
                            Dictionary['regular'] .. '</div></th>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.1,
                                    season, '', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.25,
                                    season, '', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.33,
                                    season, '', stageImage, cropImage) ..
                            '</td>' .. '</tr>' .. '<tr>' ..
                            '<td colspan=\"3\" style=\"background-color: transparent; padding: 0 0 0 8px; text-align: left; font-size: smaller; border: 0;\">*' ..
                            Dictionary['note'] .. '</td>' .. '</tr>' .. '<tr>' ..
                            '<th style=\"max-width: 2em; padding: 0;\"><div>[[File:Agriculturist.png|24px|link=]] ' ..
                            Dictionary['agriculturist'] .. '</div></th>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.2,
                                    season, '', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\">' ..
                            p.month(name, size, phaseDays, regrowth, 0.35,
                                    season, '', stageImage, cropImage) ..
                            '</td>' ..
                            '<td style=\"background-color: transparent; border: 0; vertical-align: top;\"|>' ..
                            p.month(name, size, phaseDays, regrowth, 0.43,
                                    season, '', stageImage, cropImage) ..
                            '</td>' .. '</tr></table>'
    end
    ----------cropCalendars end---------- 
	cache.set(cacheKey, cropCalendars)
    return cropCalendars
end

----------return given crop's calendar (only one table each time)----------
function p.month(name, size, phaseDays, regrowth, speedIncrease, season,
                 irrigation, stageImage, cropImage, ...)
    local phaseDays = private.copy(phaseDays)
    local season = private.copy(season)
    -- whether input title
    local title = ''
    if ... then title = ... end

    -- define sizeString used in image, e.g. sizeString = '|36px'
    -- define cellWidth used in wikitable
    local sizeString = ''
    local cellWidth = '48px'
    if size ~= '' then
        sizeString = '|' .. size .. 'px'
        cellWidth = size .. 'px'
    end

    local totalDaysOfCropGrowth = 0
    -- only support 2 seasons because of layout. Display 1 season when crop can't regrow.
    if #season > 2 or regrowth == -1 then season = season[1] end
    -- speedIncrease + 0.25 when irragated
    speedIncreaseInitial = speedIncrease
    if irrigation == 'yes' then speedIncrease = speedIncrease + 0.25 end

    -- calculate total days of crop growth (phaseDays is already a number array)
    for i = 1, #phaseDays, 1 do
        totalDaysOfCropGrowth = totalDaysOfCropGrowth + phaseDays[i]
    end
    local daysToRemove = math.ceil(totalDaysOfCropGrowth * speedIncrease)

    -- Unexpected result in C# when using floating-point arithmetic, see Talk:Crop Growth Calendars
    -- Only consider totalDaysOfCropGrowth <=28 and (speedIncrease = 0.1,0.2,0.25,0.35,0.45,0.5,0.6, 0.33,0.43,0.68)
    if speedIncrease == 0.1 then
        for key, value in pairs {10, 20} do
            if totalDaysOfCropGrowth == value then
                daysToRemove = daysToRemove + 1
                break
            end
        end
    elseif speedIncrease == 0.2 then
        for key, value in pairs {5, 10, 15, 20, 25} do
            if totalDaysOfCropGrowth == value then
                daysToRemove = daysToRemove + 1
                break
            end
        end
    elseif speedIncrease == 0.6 then
        for key, value in pairs {5, 10, 15, 20, 25} do
            if totalDaysOfCropGrowth == value then
                daysToRemove = daysToRemove + 1
                break
            end
        end
    end

    -- calculate phaseDays after speedIncrease
    local tries = 0
    -- special:misnamed crop images, e.g. Green Bean, Hops. 
    -- Delete the 0 cell before removing and add them back after removing
    local phaseZero = 0
    for i = 1, #phaseDays, 1 do
        if phaseDays[i] == 0 then
            phaseZero = i
            table.remove(phaseDays, i)
            break
        end
    end
    -- Calculate. ConcernApe's C# code doesn't consider phaseDay[i] = 0. 
    -- So the following code doesn't consider this situation, too.
    -- e.g. phaseDays = {1,1,2,3,3} (Grape), speedIncrease = 0.43.
    -- After removing, it becomes {1,-1,1,2,2}. Totalday is 1+1+2+2=6. And actually it is 6 days in  the game. 
    -- However, if speedIncrease = 0.43, it should be 5 days {1,0,0,2,2}
    while daysToRemove > 0 and tries < 3 do
        for i = 1, #phaseDays, 1 do
            if i > 1 or phaseDays[i] > 1 then
                phaseDays[i] = phaseDays[i] - 1
                daysToRemove = daysToRemove - 1
            end
            if daysToRemove <= 0 then break end
        end
        tries = tries + 1
    end
    -- Add back
    if phaseZero ~= 0 then table.insert(phaseDays, phaseZero, 0) end

    -- 2-month days picture
    local picList = {}
    local daysLeft = 56
    local circulateOrNot = ''
    while daysLeft > 0 do
        -- Crops which are reseeded should skip Day 1
        if daysLeft < 56 and circulateOrNot ~= 'yes' then
            phaseDays[1] = phaseDays[1] - 1
            circulateOrNot = 'yes'
        end
        for stage = 1, #phaseDays, 1 do
            for stageDay = 1, phaseDays[stage], 1 do
                -- special: File:Hot_Pepper_Stage_4b.png
                if name == 'Hot Pepper' and stage == 5 then
                    table.insert(picList,
                                 '[[File:' .. stageImage .. ' 4b.png' ..
                                     sizeString .. '|center|link=]]')
                else
                    table.insert(picList,
                                 '[[File:' .. stageImage .. ' ' .. stage ..
                                     '.png' .. sizeString .. '|center|link=]]')
                end
                daysLeft = daysLeft - 1
                if daysLeft == 0 then break end
            end
            if daysLeft == 0 then break end
        end
        if daysLeft == 0 then break end
        table.insert(picList, '[[File:' .. cropImage .. '.png' .. sizeString ..
                         '|center|link=]]')
        daysLeft = daysLeft - 1
        if daysLeft == 0 then break end
        if regrowth ~= -1 then
            local stageRegrowth = #phaseDays + 2
            while daysLeft > 0 do
                for regrowthDays = 1, regrowth - 1, 1 do
                    -- special: File:Hot_Pepper_Stage_6.png
                    if name == 'Hot Pepper' then
                        table.insert(picList, '[[File:' .. stageImage ..
                                         ' 6.png' .. sizeString ..
                                         '|center|link=]]')
                    else
                        table.insert(picList,
                                     '[[File:' .. stageImage .. ' ' ..
                                         stageRegrowth .. '.png' .. sizeString ..
                                         '|center|link=]]')
                    end
                    daysLeft = daysLeft - 1
                    if daysLeft == 0 then break end
                end
                if daysLeft == 0 then break end
                table.insert(picList, '[[File:' .. cropImage .. '.png' ..
                                 sizeString .. '|center|link=]]')
                daysLeft = daysLeft - 1
            end
        end
    end

    -- table title relating to speedIncrease (10% and 0% are special)
    if title == '' then
        if speedIncreaseInitial == 0.1 or speedIncreaseInitial == 0 then
            if speedIncreaseInitial == 0 then
                title = title .. Dictionary['base']
            else
                title = '10%*'
            end
        else
            title = tostring(speedIncreaseInitial * 100) .. '%'
        end
    end

    -- irrigation
    if irrigation == 'yes' then title = title .. Dictionary['irrigated'] end
    if irrigation == 'no' then title = title .. Dictionary['unirrigated'] end

    -- wikitable's header row
    local wikitableTitle = '' ..
                               '<table class=\"wikitable roundedborder\" style="text-align:center;\">' ..
                               '<tr>' .. '<th colspan=\"7\">' .. title ..
                               '</th>' .. '</tr>'

    -- calendar season 1
    local wikitable1 = '' .. '<tr>' .. '<th style=\"width: ' .. cellWidth ..
                           ';\">' .. Dictionary['monday'] .. '</th>' ..
                           '<th style=\"width: ' .. cellWidth .. ';\">' ..
                           Dictionary['tuesday'] .. '</th>' ..
                           '<th style=\"width: ' .. cellWidth .. ';\">' ..
                           Dictionary['wednesday'] .. '</th>' ..
                           '<th style=\"width: ' .. cellWidth .. ';\">' ..
                           Dictionary['thursday'] .. '</th>' ..
                           '<th style=\"width: ' .. cellWidth .. ';\">' ..
                           Dictionary['friday'] .. '</th>' ..
                           '<th style=\"width: ' .. cellWidth .. ';\">' ..
                           Dictionary['saturday'] .. '</th>' ..
                           '<th style=\"width: ' .. cellWidth .. ';\">' ..
                           Dictionary['sunday'] .. '</th>'
    -- crops images
    for i = 1, 28, 1 do
        -- another row
        if math.fmod(i, 7) == 1 then
            wikitable1 = wikitable1 .. '</tr><tr>'
        end
        wikitable1 = wikitable1 .. '<td>' .. picList[i] .. '</td>'
    end
    wikitable1 = wikitable1 .. '</tr>'

    local wikitable2 = ''
    -- special:calendar season 2
    if #season == 2 then
        wikitable2 =
            wikitable2 .. '<tr>' .. '<th style=\"width: ' .. cellWidth .. ';\">' ..
                Dictionary['monday'] .. '</th>' .. '<th style=\"width: ' ..
                cellWidth .. ';\">' .. Dictionary['tuesday'] .. '</th>' ..
                '<th style=\"width: ' .. cellWidth .. ';\">' ..
                Dictionary['wednesday'] .. '</th>' .. '<th style=\"width: ' ..
                cellWidth .. ';\">' .. Dictionary['thursday'] .. '</th>' ..
                '<th style=\"width: ' .. cellWidth .. ';\">' ..
                Dictionary['friday'] .. '</th>' .. '<th style=\"width: ' ..
                cellWidth .. ';\">' .. Dictionary['saturday'] .. '</th>' ..
                '<th style=\"width: ' .. cellWidth .. ';\">' ..
                Dictionary['sunday'] .. '</th>'
        -- crops images
        for i = 29, 56, 1 do
            -- another row
            if math.fmod(i, 7) == 1 then
                wikitable2 = wikitable2 .. '</tr><tr>'
            end
            wikitable2 = wikitable2 .. '<td>' .. picList[i] .. '</td>'
        end
        wikitable2 = wikitable2 .. '</tr>'
    end

    local wikitable = ''
    -- 1 or 2 tables to output
    if #season == 2 then
        -- horizontal or vertical tables
        if speedIncrease == 0 then
            local wikitableTitle2 = '' ..
                                        '<table class=\"wikitable roundedborder\" style="text-align:center;\">' ..
                                        '<tr>' .. '<th colspan=\"7\">' ..
                                        Dictionary['base'] .. ' - ' ..
                                        Dictionary[season[2]] ..
                                        Dictionary['ifPlantOn'] ..
                                        Dictionary[season[1]] ..
                                        Dictionary['dayOne'] ..
                                        Dictionary['closeParen'] .. '</th>' ..
                                        '</tr>'
            wikitable = wikitable .. '<table><tr><td>' .. wikitableTitle ..
                            wikitable1 .. '</table></td><td>' .. wikitableTitle2 ..
                            wikitable2 .. '</table></td></tr></table>'
        else
            wikitable = wikitable .. wikitableTitle .. '<tr>' ..
                            '<th colspan=\"7\">' .. Dictionary[season[1]] ..
                            '</th>' .. '</tr>' .. wikitable1 .. '<tr>' ..
                            '<th colspan=\"7\">' .. Dictionary[season[2]] ..
                            '</th>' .. '</tr>' .. wikitable2 .. '</table>'
        end
    else
        wikitable = wikitable .. wikitableTitle .. wikitable1 .. '</table>'
    end
    return wikitable
end

----------clone tables----------
function private.copy(t)
    local t2 = {}
    for k, v in pairs(t) do t2[k] = v end
    return t2
end

return p