![]() |
VOOZH | about |
{{DropTable}} instead.{{DropsLine}}
localp={} localpageTitle=mw.title.getCurrentTitle() localpageTitleString=pageTitle.fullText localnamespace=pageTitle.nsText localfileNamespace=mw.site.namespaces[6].name locallang=mw.language.getContentLanguage() locali18n={ playerKillRef="Dropped only when kill credit is given to the player", playerKillRefName="player-kill", playerKillYes="yes", playerKillNo="no", versionJavaOnly="Only in Java Edition", versionBedrockOnly="Only in Bedrock Edition", versionBoth="both", imageIconPrefix="Invicon ", blankImageName="Air", -- Placeholders will automatically be replaced with: imageName, pageTitleString, itemName, quantity imageAltText="$1: $2 drops $3 with quantity $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", smwRollChance="Roll chance", smwRollChanceText="Roll chance text", smwRollChanceNote="Roll chance note", smwItemName="Item name", smwDropJSON="Drop JSON" } -- format a number for printing functionp.formatNum(number) ifnumberthen returnlang:formatNum(tonumber(string.format("%.2f",number))) end return'' end functionp.quantityText(quantity,low,high,chance) localtext=quantity iflowandhighthen iflow>highthen low,high=high,low end iflow==highthen text=low else text=low..'–'..high end end ifchanceandchance~=0andchance~=100then text=text..' ('..p.formatNum(chance)..'%)' end returntostring(text) end functionp.main(frame) returnp._main(frame:getParent().args) end -- Generates a row in the drops table functionp._main(args) localversion=args.versionori18n.versionBoth localimageName=args.image localname=args.nameor'' localnameLink=args.namelinkorname localnameNote=args.namenote localquantity=args.quantityor1 locallootingQuantity=args.lootingquantityor0 localquantityLimit=args.quantitylimit-- Corresponds to "limit" in datapacks. Only used by strays in vanilla je (up to 1.20.2) localdropChance=args.dropchanceor100 dropChance=string.gsub(dropChance,'%%','') dropChance=tonumber(dropChance)-- gsub returns 2 vars, so we have to split up the gsub and tonumber locallootingChance=args.lootingchanceor0 lootingChance=string.gsub(lootingChance,'%%','') lootingChance=tonumber(lootingChance)-- gsub returns 2 vars, so we have to split up the gsub and tonumber localplayerKillRequired=args.playerkillori18n.playerKillNo localrollChance=args.rollchanceor1 localrollChanceNote=args.rollchancenote -- 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)ortonumber(quantity) highQuantity=tonumber(highQuantity)ortonumber(quantity) iflowQuantity>highQuantitythen lowQuantity,highQuantity=highQuantity,lowQuantity end -- setup: looting quantity local_,_,lootingLowQuantity,lootingHighQuantity=string.find(lootingQuantity,'(%-?%d+)%-(%-?%d+)') lootingLowQuantity=tonumber(lootingLowQuantity)ortonumber(lootingQuantity) lootingHighQuantity=tonumber(lootingHighQuantity)ortonumber(lootingQuantity) iflootingLowQuantity>lootingHighQuantitythen lootingLowQuantity,lootingHighQuantity=lootingHighQuantity,lootingLowQuantity end -- quantity scaling with looting locallooting1Low=lowQuantity locallooting2Low=lowQuantity locallooting3Low=lowQuantity iflootingHighQuantity>lootingLowQuantitythen looting1Low=lowQuantity+lootingLowQuantity looting2Low=looting1Low+lootingLowQuantity looting3Low=looting2Low+lootingLowQuantity end locallooting1High=highQuantity+lootingHighQuantity locallooting2High=looting1High+lootingHighQuantity locallooting3High=looting2High+lootingHighQuantity -- dropChance scaling with looting. incompatible with a lowQuantity <= 0 and quantityLimit, since that calculates its own non-linear scaling locallooting1Chance,looting2Chance,looting3Chance ifdropChance~=0andlootingChance~=0then 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. ifhighQuantity>lowQuantityandlowQuantity<0then 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. ifquantityLimitthen ifhighQuantity>lowQuantitythen 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) ifhighQuantityandhighQuantity>quantityLimitthenhighQuantity=quantityLimitend iflooting1Highandlooting1High>quantityLimitthenlooting1High=quantityLimitend iflooting2Highandlooting2High>quantityLimitthenlooting2High=quantityLimitend iflooting3Highandlooting3High>quantityLimitthenlooting3High=quantityLimitend end -- setup: image -- Generate file name from item name ifimageNamethen ifimageName==''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 localimage=mw.ustring.format('[[%s:%s|link=%s|alt=%s|32x32px|class=pixel-image]]',fileNamespace,imageName,nameLink,i18n.imageAltText) :gsub("$1",imageName) :gsub("$2",pageTitleString) :gsub("$3",name) :gsub("$4",quantity) -- item image localret=mw.html.create('tr') :css('text-align','center') -- image :tag('td') :addClass('sprite-image') :css('min-width','32px') :wikitext(image) :done() -- item name localnameTagString=name ifnameLink~=''then nameTagString=string.format('[[%s|%s]]',nameLink,name) end localnameTag=ret:tag('td') :css('text-align','left') :wikitext(nameTagString) ifversion=='je'then nameTag:wikitext(mw.getCurrentFrame():extensionTag{name='sub',content='(JE)',args={title=i18n.versionJavaOnly,style='cursor:help; margin-left:3px;'}}) elseifversion=='be'then nameTag:wikitext(mw.getCurrentFrame():extensionTag{name='sub',content='(BE)',args={title=i18n.versionBedrockOnly,style='cursor:help; margin-left:3px;'}}) end ifnameNotethen nameTag:wikitext(mw.getCurrentFrame():extensionTag{name='ref',content=nameNote,args={group='d'}}) end -- roll chance localrollChanceText=rollChance ifrollChance==1then ifdropChance==100then rollChanceText="100%" else rollChanceText=p.formatNum(dropChance)..'%–'..p.formatNum(looting3Chance)..'%' end end localrollChanceTag=ret:tag('td'):wikitext(rollChanceText) ifplayerKillRequired==i18n.playerKillYesthen rollChanceTag:wikitext(mw.getCurrentFrame():extensionTag{name='ref',content=i18n.playerKillRef,args={group='d',name=i18n.playerKillRefName}}) end ifrollChanceNotethen rollChanceTag:wikitext(mw.getCurrentFrame():extensionTag{name='ref',content=rollChanceNote,args={group='d'}}) 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 localonMain=false ifnamespace==''ornamespace==mw.site.namespaces[4].namethen onMain=true end ifonMainthen localsmw_sub={} localdroppedFrom=pageTitleString localsubname=i18n.smwSubnamePrefix..'_'..name..'_'..quantity localsmw_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.smwRollChance]=rollChance, [i18n.smwRollChanceText]=rollChanceText, [i18n.smwRollChanceNote]=rollChanceNote } mw.logObject(smw_json) localsmw_sub={-- the actual SMW sub-object [i18n.smwItemName]=name, [i18n.smwDroppedFrom]=droppedFrom, [i18n.smwDropJSON]=mw.text.jsonEncode(smw_json) } end returntostring(ret) end returnp