新 Minecarft Wiki 1周年!
|
「モジュール:DropsLine」の版間の差分
ナビゲーションに移動
検索に移動
追加された内容 削除された内容
Lukes20129 (トーク | 投稿記録) |
The Non Useful (トーク | 投稿記録) 細編集の要約なし |
||
188行目: | 188行目: | ||
end |
end |
||
local image = mw.ustring.format('[[%s:%s|link=%s|alt=%s|32x32px|class=pixel-image]]', fileNamespace, imageName, nameLink, i18n.imageAltText) |
local image = mw.ustring.format('[[%s:%s|link=%s|alt=%s|32x32px|class=pixel-image]]', fileNamespace, imageName, autolink.invlink(nameLink, 'nolink'), i18n.imageAltText) |
||
:gsub("$1", imageName) |
:gsub("$1", imageName) |
||
:gsub("$2", pageTitleString) |
:gsub("$2", pageTitleString) |
2024年9月25日 (水) 23:22時点における最新版
local p = {}
local pageTitle = mw.title.getCurrentTitle()
local pageTitleString = pageTitle.fullText
local namespace = pageTitle.nsText
local fileNamespace = mw.site.namespaces[6].name
local lang = mw.language.getContentLanguage()
local autolink = require( 'モジュール:Autolink' )
local i18n = {
playerKillRef = "プレイヤーおよび飼いならしたオオカミが倒した場合のみドロップ",
playerKillRefName = "player-kill",
enchantedRef = "[[エンチャント]]されていることがある",
enchantedRefName = "enchanted",
equippedRef = "対象が装備している場合のみ",
equippedRefName = "equipped",
refYes = "yes",
refNo = "no",
versionJavaOnly = "Java Editionのみ",
versionBedrockOnly = "Bedrock Editionのみ",
versionBoth = "both",
imageIconPrefix = "Invicon ",
blankImageName = "Air",
-- Placeholders will automatically be replaced with: imageName, pageTitleString, itemName, quantity
imageAltText = "$1: $2は$3を$4個ドロップします",
-- SMW properties
smwSubnamePrefix = "DROP",
smwDroppedFrom = "Dropped from",
smwVersion = "Version",
smwDroppedItem = "Dropped item",
smwDroppedItemNote = "Dropped item note",
smwQuantity = "Quantity",
smwQuantityText = "Quantity text",
smwLootingQuantity = "Looting quantity",
smwDropChance = "Drop chance",
smwLootingChance = "Looting chance",
smwPlayerKillRequired = "Player kill required",
smwCanBeEnchanted = "Can Be Enchanted",
smwRollChance = "Roll chance",
smwRollChanceText = "Roll chance text",
smwRollChanceNote = "Roll chance note",
smwItemName = "Item name",
smwDropJSON = "Drop JSON",
smwUpcoming = "Upcoming",
smwUntil = "Until"
}
-- format a number for printing
function p.formatNum(number)
if number then
return lang:formatNum(tonumber(string.format("%.2f", number)))
end
return ''
end
function p.quantityText(quantity, low, high, chance)
local text = quantity
if low and high then
if low > high then
low, high = high, low
end
if low == high then
text = low
else
text = low .. '–' .. high
end
end
if chance and chance ~= 0 and chance ~= 100 then
text = text .. ' (' .. p.formatNum(chance) .. '%)'
end
return tostring(text)
end
function p.main(frame)
return p._main(frame:getParent().args)
end
-- Generates a row in the drops table
function p._main(args)
local version = args.version or i18n.versionBoth
local imageName = args.image
local name = args.name or ''
local nameLink = args.namelink or name
local nameNote = args.namenote
local quantity = args.quantity or 1
local lootingQuantity = args.lootingquantity or 0
local quantityLimit = args.quantitylimit -- Corresponds to "limit" in datapacks. Only used by strays in vanilla je (up to 1.20.2)
local dropChance = args.dropchance or 100
dropChance = string.gsub(dropChance, '%%', '')
dropChance = tonumber(dropChance) -- gsub returns 2 vars, so we have to split up the gsub and tonumber
local lootingChance = args.lootingchance or 0
lootingChance = string.gsub(lootingChance, '%%', '')
lootingChance = tonumber(lootingChance) -- gsub returns 2 vars, so we have to split up the gsub and tonumber
local playerKillRequired = args.playerkill or i18n.refNo
local enchanted = args.enchanted or i18n.refNo
local equipped = args.equipped or i18n.refNo
local rollChance = args.rollchance or 1
local rollChanceNote = args.rollchancenote
local upcver = args.upcver or ''
local untilver = args.untilver or ''
-- setup: quantity. Quantity is needed for the image selection of experience orbs, so we do the setup here.
local _, _, lowQuantity, highQuantity = string.find(quantity, '(%-?%d+)%-(%-?%d+)')
lowQuantity = tonumber(lowQuantity) or tonumber(quantity)
highQuantity = tonumber(highQuantity) or tonumber(quantity)
if lowQuantity > highQuantity then
lowQuantity, highQuantity = highQuantity, lowQuantity
end
-- setup: looting quantity
local _, _, lootingLowQuantity, lootingHighQuantity = string.find(lootingQuantity, '(%-?%d+)%-(%-?%d+)')
lootingLowQuantity = tonumber(lootingLowQuantity) or tonumber(lootingQuantity)
lootingHighQuantity = tonumber(lootingHighQuantity) or tonumber(lootingQuantity)
if lootingLowQuantity > lootingHighQuantity then
lootingLowQuantity, lootingHighQuantity = lootingHighQuantity, lootingLowQuantity
end
-- quantity scaling with looting
local looting1Low = lowQuantity
local looting2Low = lowQuantity
local looting3Low = lowQuantity
if lootingHighQuantity > lootingLowQuantity then
looting1Low = lowQuantity + lootingLowQuantity
looting2Low = looting1Low + lootingLowQuantity
looting3Low = looting2Low + lootingLowQuantity
end
local looting1High = highQuantity + lootingHighQuantity
local looting2High = looting1High + lootingHighQuantity
local looting3High = looting2High + lootingHighQuantity
-- dropChance scaling with looting. incompatible with a lowQuantity <= 0 and quantityLimit, since that calculates its own non-linear scaling
local looting1Chance, looting2Chance, looting3Chance
if dropChance ~= 0 and lootingChance ~= 0 then
looting1Chance = dropChance + lootingChance
looting2Chance = looting1Chance + lootingChance
looting3Chance = looting2Chance + lootingChance
end
-- A few vanilla mobs use negative lower bounds for their quantity rolls to fake a lower dropChance.
-- This behavior is unintuitive so we translate it to a [0-n] bounds with a (k%) of dropping
-- This isn't a linear scaling for the looting levels, so we cannot reuse the already set values.
if highQuantity > lowQuantity and lowQuantity < 0 then
dropChance = (highQuantity / ((highQuantity - lowQuantity) + 1)) * 100
looting1Chance = (looting1High / ((looting1High - looting1Low) + 1)) * 100
looting2Chance = (looting2High / ((looting2High - looting2Low) + 1)) * 100
looting3Chance = (looting3High / ((looting3High - looting3Low) + 1)) * 100
lowQuantity = 1
looting1Low = 1
looting2Low = 1
looting3Low = 1
end
-- Quantity limit is really weird and does rounding so only 0-0.45 maps to 0, while 0.5-1 maps to one.
-- So every +1 to the range is actually +50% to the count that is above 0.
-- its only used for strays, and the formula would be different for anything that has a different range
-- so this is just hard coded to work for strays.
if quantityLimit then
if highQuantity > lowQuantity then
dropChance = (highQuantity / ((highQuantity - lowQuantity) + 1)) * 100
looting1Chance = (math.pow(2, 1 + 1) - 1) / (math.pow(2, 1 + 1)) * 100
looting2Chance = (math.pow(2, 2 + 1) - 1) / (math.pow(2, 2 + 1)) * 100
looting3Chance = (math.pow(2, 3 + 1) - 1) / (math.pow(2, 3 + 1)) * 100
lowQuantity = 1
looting1Low = 1
looting2Low = 1
looting3Low = 1
end
quantityLimit = tonumber(quantityLimit)
if highQuantity and highQuantity > quantityLimit then highQuantity = quantityLimit end
if looting1High and looting1High > quantityLimit then looting1High = quantityLimit end
if looting2High and looting2High > quantityLimit then looting2High = quantityLimit end
if looting3High and looting3High > quantityLimit then looting3High = quantityLimit end
end
-- setup: image
-- Generate file name from item name
if imageName then
if imageName == '' then -- if its blank, use a blank image
imageName = i18n.imageIconPrefix .. i18n.blankImageName .. '.png'
end
else
imageName = i18n.imageIconPrefix .. name .. '.png' -- Auto generate an image from the drop name
end
local image = mw.ustring.format('[[%s:%s|link=%s|alt=%s|32x32px|class=pixel-image]]', fileNamespace, imageName, autolink.invlink(nameLink, 'nolink'), i18n.imageAltText)
:gsub("$1", imageName)
:gsub("$2", pageTitleString)
:gsub("$3", name)
:gsub("$4", quantity)
-- item image
local ret = mw.html.create('tr')
:css('text-align', 'center')
-- image
:tag('td')
:addClass('sprite-image')
:css('min-width', '32px')
:wikitext(image)
:done()
-- item name
local nameTagString = autolink.invlink( name, 'nolink' )
if nameLink ~= '' then
nameTagString = string.format('[[%s|%s]]', autolink.invlink( nameLink, 'nolink' ), autolink.invlink( name, 'nolink' ) )
end
local nameTag = ret:tag('td')
:css('text-align', 'left')
:wikitext(nameTagString)
if version == 'je' then
nameTag:wikitext(mw.getCurrentFrame():extensionTag{ name='sub', content='(JE)', args = {title=i18n.versionJavaOnly, style='cursor:help; margin-left:3px;'} })
elseif version == 'be' then
nameTag:wikitext(mw.getCurrentFrame():extensionTag{ name='sub', content='(BE)', args = {title=i18n.versionBedrockOnly, style='cursor:help; margin-left:3px;'} })
end
if nameNote then
nameTag:wikitext(mw.getCurrentFrame():extensionTag{ name='ref', content=nameNote, args = {group='ドロップ'}})
end
if enchanted == i18n.refYes then
nameTag:wikitext(mw.getCurrentFrame():extensionTag{ name='ref', content=i18n.enchantedRef, args = {group='ドロップ', name=i18n.enchantedRefName}})
end
-- roll chance
local rollChanceText = rollChance
if rollChance == 1 then
if dropChance == 100 then
rollChanceText = "100%"
else
rollChanceText = p.formatNum(dropChance) .. '%–' .. p.formatNum(looting3Chance) .. '%'
end
end
local rollChanceTag = ret:tag('td'):wikitext(rollChanceText)
if playerKillRequired == i18n.refYes then
rollChanceTag:wikitext(mw.getCurrentFrame():extensionTag{ name='ref', content=i18n.playerKillRef, args = {group='ドロップ', name=i18n.playerKillRefName}})
end
if equipped == i18n.refYes then
rollChanceTag:wikitext(mw.getCurrentFrame():extensionTag{ name='ref', content=i18n.equippedRef, args = {group='ドロップ', name=i18n.equippedRefName}})
end
if rollChanceNote then
rollChanceTag:wikitext(mw.getCurrentFrame():extensionTag{ name='ref', content=rollChanceNote, args = {group='ドロップ'}})
end
if upcver ~= '' then
rollChanceTag:wikitext(mw.getCurrentFrame():expandTemplate{ title = 'upcoming', args = { upcver } })
end
if untilver ~= '' then
rollChanceTag:wikitext(mw.getCurrentFrame():expandTemplate{ title = 'until', args = { untilver } })
end
-- quantity text
ret:tag('td'):wikitext(p.quantityText(quantity, lowQuantity, highQuantity, dropChance)):done()
ret:tag('td'):wikitext(p.quantityText(quantity, looting1Low, looting1High, looting1Chance)):done()
ret:tag('td'):wikitext(p.quantityText(quantity, looting2Low, looting2High, looting2Chance)):done()
ret:tag('td'):wikitext(p.quantityText(quantity, looting3Low, looting3High, looting3Chance)):done()
ret:done()
-- Put data into SMW
-- The only top level params that are needed is stuff that would be used as selectors
-- everything else is put into a json blob for flexibility
local onMain = false
if namespace == '' or namespace == mw.site.namespaces[4].name then
onMain = true
end
if onMain then
local smw_sub = {}
local droppedFrom = pageTitleString
local subname = i18n.smwSubnamePrefix .. '_' .. name .. '_' .. quantity
local smw_json = {
[i18n.smwDroppedFrom] = droppedFrom,
[i18n.smwVersion] = version,
[i18n.smwDroppedItem] = name,
[i18n.smwDroppedItemNote] = nameNote,
[i18n.smwQuantity] = quantity,
[i18n.smwQuantityText] = {
p.quantityText(quantity, lowQuantity, highQuantity, dropChance),
p.quantityText(quantity, looting1Low, looting1High, looting1Chance),
p.quantityText(quantity, looting2Low, looting2High, looting2Chance),
p.quantityText(quantity, looting3Low, looting3High, looting3Chance)
},
[i18n.smwLootingQuantity] = lootingQuantity,
[i18n.smwDropChance] = dropChance,
[i18n.smwLootingChance] = lootingChance,
[i18n.smwPlayerKillRequired] = playerKillRequired,
[i18n.smwCanBeEnchanted] = enchanted,
[i18n.smwRollChance] = rollChance,
[i18n.smwRollChanceText] = rollChanceText,
[i18n.smwRollChanceNote] = rollChanceNote,
[i18n.smwUpcoming] = upcver,
[i18n.smwUntil] = untilver
}
mw.logObject(smw_json)
local smw_sub = { -- the actual SMW sub-object
[i18n.smwItemName] = name,
[i18n.smwDroppedFrom] = droppedFrom,
[i18n.smwDropJSON] = mw.text.jsonEncode(smw_json)
}
mw.smw.subobject(smw_sub, subname)
end
return tostring(ret)
end
return p