Keine Bearbeitungszusammenfassung |
Keine Bearbeitungszusammenfassung |
||
(12 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 11: | Zeile 11: | ||
local Elements = {"Impact", "Puncture", "Slash", "Heat", "Cold", "Toxin", "Electricity", "Blast", "Corrosive", "Radiation", "Magnetic", "Gas", "Viral"} |
local Elements = {"Impact", "Puncture", "Slash", "Heat", "Cold", "Toxin", "Electricity", "Blast", "Corrosive", "Radiation", "Magnetic", "Gas", "Viral"} |
||
local Physical = {"Impact", "Puncture", "Slash"} |
local Physical = {"Impact", "Puncture", "Slash"} |
||
− | local UseDefaultList = {"NOISELEVEL", "AMMOTYPE", "MAXAMMO", "DISPOSITION", "CHANNELMULT"} |
+ | local UseDefaultList = {"NOISELEVEL", "AMMOTYPE", "MAXAMMO", "DISPOSITION", "CHANNELMULT", "HEADSHOTMULTIPLIER"} |
local VariantList = {"Prime", "Prisma", "Wraith", "Vandal", "Vaykor", "Synoid", "Telos", "Secura", "Sancti", "Rakta", "Mara", "MK1"} |
local VariantList = {"Prime", "Prisma", "Wraith", "Vandal", "Vaykor", "Synoid", "Telos", "Secura", "Sancti", "Rakta", "Mara", "MK1"} |
||
Zeile 630: | Zeile 630: | ||
local resString = "" |
local resString = "" |
||
for i, pol in pairs(Weapon.Polarities) do |
for i, pol in pairs(Weapon.Polarities) do |
||
− | + | local tempPol = Icon._Pol(pol) |
|
+ | if tempPol == "<span style=\"color:red;\">Invalid</span>" and Weapon.Name == "Exalted Blade" then |
||
+ | resString = resString..pol |
||
+ | else |
||
+ | resString = resString..tempPol |
||
+ | end |
||
end |
end |
||
return resString |
return resString |
||
Zeile 656: | Zeile 661: | ||
end |
end |
||
+ | local polarity = '' |
||
⚫ | |||
+ | local link = '' |
||
+ | if Weapon.Class ~= "Exalted Weapon" then |
||
+ | polarity = " ("..Icon._Pol(stance.Polarity)..")" |
||
+ | link = "[["..Icon.Deutsch(stance.Name).."]]" |
||
+ | else |
||
⚫ | |||
+ | end |
||
+ | |||
+ | result = result..link..polarity |
||
--result = result.."<span class=\"mod-tooltip\" data-param=\""..stance.Name.."\" style=\"white-space:pre\">[["..stance.Name.."]]</span>".." ("..Icon._Pol(stance.Polarity)..")" |
--result = result.."<span class=\"mod-tooltip\" data-param=\""..stance.Name.."\" style=\"white-space:pre\">[["..stance.Name.."]]</span>".." ("..Icon._Pol(stance.Polarity)..")" |
||
--If this is a PvP Stance, add the disclaimer |
--If this is a PvP Stance, add the disclaimer |
||
Zeile 728: | Zeile 742: | ||
r = string.gsub(Attack.Accuracy,"%.","%,") |
r = string.gsub(Attack.Accuracy,"%.","%,") |
||
return r |
return r |
||
− | elseif(Attack == Weapon.NormalAttack |
+ | elseif(Attack == Weapon.NormalAttack) then |
− | + | if(Weapon.Accuracy ~= nil) then |
|
− | + | r = string.gsub(Weapon.Accuracy,"%.","%,") |
|
+ | return r |
||
+ | else |
||
+ | return Weapon.Accuracy |
||
+ | end |
||
elseif giveDefault then |
elseif giveDefault then |
||
return 0 |
return 0 |
||
Zeile 848: | Zeile 866: | ||
elseif(ValName == "DAMAGEBIAS") then |
elseif(ValName == "DAMAGEBIAS") then |
||
if(Shared.tableCount(Attack.Damage) <= 3) then |
if(Shared.tableCount(Attack.Damage) <= 3) then |
||
− | + | if (GetDamageBiasString(Attack, nil, nil, giveDefault)~=nil) then |
|
+ | return GetDamageBiasString(Attack, nil, nil, giveDefault) |
||
+ | else |
||
+ | return "" |
||
+ | end |
||
else |
else |
||
− | if(asString) then |
+ | if(asString or giveDefault) then |
return "" |
return "" |
||
else |
else |
||
Zeile 943: | Zeile 965: | ||
if (giveDefault) then |
if (giveDefault) then |
||
returnVal = 0 |
returnVal = 0 |
||
+ | else |
||
+ | return nil |
||
+ | end |
||
+ | elseif(ValName == "HEADSHOTMULTIPLIER") then |
||
+ | --search in current attack, then normal, and finally fall back on base weapon value if for some reason that exists |
||
+ | if(Attack.HeadshotMultiplier ~= nil) then |
||
+ | if(asString) then |
||
+ | return asMultiplier(Attack.HeadshotMultiplier) |
||
+ | else |
||
+ | return Attack.HeadshotMultiplier |
||
+ | end |
||
+ | end |
||
+ | if(hasAttack(Weapon, "Normal")) then |
||
+ | local normAtt = getAttack(Weapon, "Normal") |
||
+ | if(normAtt.HeadshotMultiplier ~= nil) then |
||
+ | if(asString) then |
||
+ | return asMultiplier(normAtt.HeadshotMultiplier) |
||
+ | else |
||
+ | return normAtt.HeadshotMultiplier |
||
+ | end |
||
+ | end |
||
+ | end |
||
+ | if(Weapon.HeadshotMultiplier ~= nil) then |
||
+ | if(asString) then |
||
+ | return asMultiplier(Weapon.HeadshotMultiplier) |
||
+ | else |
||
+ | return Weapon.HeadshotMultiplier |
||
+ | end |
||
+ | end |
||
+ | if giveDefault then |
||
+ | if(Weapon.Type ~= nil) then |
||
+ | --Setting multiplier based on default for each weapon type |
||
+ | if(Weapon.Type == "Secondary") then |
||
+ | if(Weapon.Class == "Shotgun Sidearm") then |
||
+ | return '1.2x' |
||
+ | elseif(Weapon.Class == "Crossbow" or Weapon.Class == "Thrown") then |
||
+ | return '1.5x' |
||
+ | else |
||
+ | if(Weapon.Trigger == 'Auto') then |
||
+ | return '1.2x' |
||
+ | else |
||
+ | return '1.5x' |
||
+ | end |
||
+ | end |
||
+ | elseif(Weapon.Type == "Primary") then |
||
+ | if(Weapon.Class == "Shotgun") then |
||
+ | return "1.2x" |
||
+ | elseif(Weapon.Class == "Bow") then |
||
+ | return "2.0x" |
||
+ | elseif(Weapon.Class == "Sniper Rifle") then |
||
+ | return "1.4x" |
||
+ | elseif(Weapon.Class == "Launcher") then |
||
+ | return "1.0x" |
||
+ | else |
||
+ | if(Weapon.Trigger == "Auto") then |
||
+ | return '1.2x' |
||
+ | else |
||
+ | return '1.5x' |
||
+ | end |
||
+ | end |
||
+ | end |
||
+ | end |
||
else |
else |
||
return nil |
return nil |
||
Zeile 1.294: | Zeile 1.378: | ||
if(Weapon.Disposition ~= nil) then |
if(Weapon.Disposition ~= nil) then |
||
if(asString) then |
if(asString) then |
||
− | return Icon._Dis(Weapon.Disposition) |
+ | return Icon._Dis(Weapon.Disposition)..' <div style="display:inline; position:relative; bottom:2px">('..Weapon.Disposition..')</div>' |
else |
else |
||
return Weapon.Disposition |
return Weapon.Disposition |
||
Zeile 1.300: | Zeile 1.384: | ||
elseif giveDefault then |
elseif giveDefault then |
||
if(asString) then |
if(asString) then |
||
− | return " |
+ | return "Unbekannt" |
else |
else |
||
return 0 |
return 0 |
||
Zeile 2.281: | Zeile 2.365: | ||
result = result..buildCompareString(Weapon1.Magazine, Weapon2.Magazine, "Magazin", 0, " Schuss", {"Größeres", "Kleineres"}) |
result = result..buildCompareString(Weapon1.Magazine, Weapon2.Magazine, "Magazin", 0, " Schuss", {"Größeres", "Kleineres"}) |
||
result = result..buildCompareString(Weapon1.MaxAmmo, Weapon2.MaxAmmo, "max. Munitionskapazität", 0, " Schuss", {"Größere", "Kleinere"}) |
result = result..buildCompareString(Weapon1.MaxAmmo, Weapon2.MaxAmmo, "max. Munitionskapazität", 0, " Schuss", {"Größere", "Kleinere"}) |
||
+ | --If this is a weapon that regenerates ammo, flip the comparison |
||
⚫ | |||
+ | if (Weapon1.ReloadStyle ~= nil and Weapon1.ReloadStyle == "Regenerate") then |
||
+ | result = result..buildCompareString(Weapon1.Reload, Weapon2.Reload, "Nachladegeschw.", 2, " s", {"Schnellere", "Langsamere"}) |
||
+ | else |
||
⚫ | |||
+ | end |
||
result = result..buildCompareString(Weapon1.Spool, Weapon2.Spool, "Anlaufzeit", 0, " Schuss", {"Langsamere", "Schnellere"}) |
result = result..buildCompareString(Weapon1.Spool, Weapon2.Spool, "Anlaufzeit", 0, " Schuss", {"Langsamere", "Schnellere"}) |
||
+ | local Acc1 = getValue(Weapon1, "Accuracy") |
||
⚫ | |||
+ | local Acc2 = getValue(Weapon2, "Accuracy") |
||
⚫ | |||
⚫ | |||
⚫ | |||
end |
end |
||
Zeile 2.344: | Zeile 2.435: | ||
end |
end |
||
result = result..buildCompareString(Att1.FireRate, Att2.FireRate, "Angriffsgeschw.", 2, "", {"Höhere", "Niedrigere"}) |
result = result..buildCompareString(Att1.FireRate, Att2.FireRate, "Angriffsgeschw.", 2, "", {"Höhere", "Niedrigere"}) |
||
− | result = result..buildCompareString(Icon._Pol(Weapon1.StancePolarity), Icon._Pol(Weapon2.StancePolarity), " |
+ | result = result..buildCompareString(Icon._Pol(Weapon1.StancePolarity), Icon._Pol(Weapon2.StancePolarity), "Haltungspolarität", nil, nil, {"Unterschiedliche", "Unterschiedliche"}) |
result = result..buildCompareString(getValue(Weapon1, "ChannelMult", true), getValue(Weapon2, "ChannelMult", true), "Kanalisierungs-Multiplikator", 1, "x", {"Larger", "Smaller"}) |
result = result..buildCompareString(getValue(Weapon1, "ChannelMult", true), getValue(Weapon2, "ChannelMult", true), "Kanalisierungs-Multiplikator", 1, "x", {"Larger", "Smaller"}) |
||
Zeile 2.413: | Zeile 2.504: | ||
if(p.isMelee(Weapon1)) then |
if(p.isMelee(Weapon1)) then |
||
− | return buildMeleeComparisonString(Weapon1, Weapon2).."[[ |
+ | return buildMeleeComparisonString(Weapon1, Weapon2).."[[Kategorie:Automatischer Vergleich]]" |
else |
else |
||
return buildGunComparisonString(Weapon1, Weapon2).."[[Kategorie:Automatischer Vergleich]]" |
return buildGunComparisonString(Weapon1, Weapon2).."[[Kategorie:Automatischer Vergleich]]" |
||
Zeile 2.978: | Zeile 3.069: | ||
end |
end |
||
-- mw.log(tRows) |
-- mw.log(tRows) |
||
− | return tHeader..tRows.."\n|}[[ |
+ | return tHeader..tRows.."\n|}[[Kategorie:Automatischer Vergleich]]" |
end |
end |
||
Version vom 29. Januar 2019, 11:12 Uhr
Die Dokumentation für dieses Modul kann unter Modul:Weapons/Doku erstellt werden
--This will eventually contain data for various weapons --For use in automating assorted wiki functions and to reduce the number of updates needed -- • local p = {} local WeaponData = mw.loadData( 'Module:Weapons/data' ) local ConclaveData = mw.loadData( 'Module:Weapons/Conclave/data' ) local Icon = require( "Module:Icon" ) local Shared = require( "Module:Shared" ) local Elements = {"Impact", "Puncture", "Slash", "Heat", "Cold", "Toxin", "Electricity", "Blast", "Corrosive", "Radiation", "Magnetic", "Gas", "Viral"} local Physical = {"Impact", "Puncture", "Slash"} local UseDefaultList = {"NOISELEVEL", "AMMOTYPE", "MAXAMMO", "DISPOSITION", "CHANNELMULT", "HEADSHOTMULTIPLIER"} local VariantList = {"Prime", "Prisma", "Wraith", "Vandal", "Vaykor", "Synoid", "Telos", "Secura", "Sancti", "Rakta", "Mara", "MK1"} function p.doPlural(Text, Value) if(tonumber(Value) == 1) then Text = string.gsub(Text, "(<.+>)", "") else Text = string.gsub(Text, "<(.+)>", "%1") end return Text end function p.isVariant(WeapName) for i, var in pairs(VariantList) do if(string.find(WeapName, var)) then local baseName = string.gsub(WeapName, ' ?'..var..' ?-?', '') return true, var, baseName end end return false, 'Base', WeapName end function p.buildName(BaseName, Variant) if(Variant == nil or Variant == 'Base' or Variant == '') then return BaseName elseif(Variant == 'Prime' or Variant == 'Wraith' or Variant == 'Vandal') then return BaseName..' '..Variant elseif(Variant == "MK1") then return "MK1-"..BaseName else return Variant..' '..BaseName end end --It's a bit of a mess, but this is for compressing a list with variants --So if a list has Braton, Braton Prime, and MK1-Braton it'll list as -- Braton (MK1, Prime) function p.shortLinkList(Weapons) --First grabbing all the pieces and stashing them in a table local baseNames = {} for key, weap in Shared.skpairs(Weapons) do local isVar, varType, baseName = p.isVariant(weap.Name) if(baseNames[baseName] == nil) then baseNames[baseName] = {} end table.insert(baseNames[baseName], varType) end --Then the fun part: Pulling the table together local result = {} for baseName, variants in Shared.skpairs(baseNames) do --So first, check if 'Base' is in the list --Because if it isn't, list all variants separately if(Shared.contains(variants, "Base")) then table.sort(variants) --First, get the basic version local thisRow = '[['..baseName.."]]" --then, if there are variants... if(Shared.tableCount(variants) > 1) then --List them in parentheses one at a time thisRow = thisRow..' (' local count = 0 for i, varName in pairs(variants) do if(varName ~= 'Base') then if(count > 0) then thisRow = thisRow..', ' end thisRow = thisRow..'[['..p.buildName(baseName, varName)..'|'..varName..']]' count = count + 1 end end thisRow = thisRow..')' end table.insert(result, thisRow) else for i, varName in pairs(variants) do table.insert(result, '[['..p.buildName(baseName, varName)..']]') end end end return result end function p.getWeapon(WeapName) local weapon = WeaponData["Weapons"][WeapName] if weapon ~= nil and weapon.Name == WeapName then return weapon else for key, Weapon in Shared.skpairs(WeaponData["Weapons"]) do if(Weapon.Name == WeapName or key == WeapName) then return Weapon end end end return nil end local function checkWeapon(weap, weapName) if weap == nil or type(weap) ~= 'table' then return p.getWeapon(weapName) elseif type(weap) == 'table' then return weap end end function p.weaponExists(frame) local weapName = frame.args ~= nil and frame.args[1] or nil return p._weaponExists(weapName) end function p._weaponExists(weapName, weap) local weap = checkWeapon(weap, weapName) if weapName == 'Dark Split-Sword' then return true elseif weap then return true end if weapName == nil then return 'Enter weapon name.' elseif weap == nil then return 'No weapon '..weapName..' found.' end end function p.getLink(weapName, weap) local weap = checkWeapon(weap, weapName) exists = p._weaponExists(weapName, weap) if weapName == "Dark Split-Sword" then return "Dark Split-Sword" elseif exists == true then local temp = weap.Link if temp then return temp else return weap.Name end elseif weapName == nil then return false else return false end end function p.weaponTooltipText(frame) local weapName = frame.args ~= nil and frame.args[1] local weap = checkWeapon(weap, weapName) local link = p.getLink(weapName, weap) local linkText = '' if link == weapName then linkText = '[['..link..']]' elseif link then linkText = '[['..link..'|'..weapName..']]' else linkText = '[['..weapName..']]' end if link ~= false then return '<span class="weapon-tooltip" data-param="'..weapName..'">'..' '..linkText..'</span>' else return '<span style="color:red;">{{[[Template:Weapon|Weapon]]}}</span> "'..weapName..'" not found[[Category:Weapon '..'Tooltip error]]' end end function p.getConclaveWeapon(WeapName) for key, Weapon in Shared.skpairs(ConclaveData["Weapons"]) do if(Weapon.Name == WeapName or key == WeapName) then return Weapon end end return nil end function p.isMelee(frame) if(frame == nil) then return nil end local Weapon = frame.args ~= nil and frame.args[1] or frame if(type(Weapon) == "string") then Weapon = p.getWeapon(Weapon) end if(Weapon == nil) then return nil end if(Weapon.Type ~= nil and (Weapon.Type == "Melee" or Weapon.Type == "Arch-Melee")) then return "yes" end return nil end function p.isArchwing(frame) if(frame == nil) then return nil end local Weapon = frame.args ~= nil and frame.args[1] or frame if(type(Weapon) == "string") then Weapon = p.getWeapon(Weapon) end if(Weapon == nil) then return nil end if(Weapon.Type ~= nil and (Weapon.Type == "Arch-Gun" or Weapon.Type == "Arch-Melee")) then return "yes" end return nil end local function getAttack(Weapon, AttackType) if(Weapon == nil or AttackType == nil) then return nil elseif(type(Weapon) == "string") then Weapon = p.getWeapon(Weapon) end AttackType = string.upper(AttackType) if (AttackType == nil or AttackType == "NORMAL" or AttackType == "NORMALATTACK") then if(Weapon.NormalAttack ~= nil) then return Weapon.NormalAttack elseif(Weapon.Damage ~= nil) then return Weapon else return nil end elseif(AttackType == "CHARGE" or AttackType == "CHARGEATTACK") then return Weapon.ChargeAttack elseif(AttackType == "AREA" or AttackType == "AREAATTACK") then return Weapon.AreaAttack elseif(AttackType == "SECONDARYAREA" or AttackType == "SECONDARYAREAATTACK") then return Weapon.SecondaryAreaAttack elseif(AttackType == "THROW" or AttackType == "THROWATTACK") then return Weapon.ThrowAttack elseif(AttackType == "CHARGEDTHROW" or AttackType == "CHARGEDTHROWATTACK") then return Weapon.ChargedThrowAttack elseif(AttackType == "SECONDARY" or AttackType == "SECONDARYATTACK") then return Weapon.SecondaryAttack else return nil end end local function hasAttack(Weapon, AttackType) if(getAttack(Weapon, AttackType) ~= nil) then return true else return nil end end function p.hasAttack(frame) local WeapName = frame.args[1] local AttackName = frame.args[2] if(WeapName == nil) then return "ERROR: No weapon name" elseif(AttackName == nil) then AttackName = "Normal" end local Weapon = p.getWeapon(WeapName) if(Weapon == nil) then return "ERROR: No weapon "..WeapName.." found" end return hasAttack(Weapon, AttackName) end function hasMultipleTypes(Attack) local typeCount = 0 if(Attack ~= nil and Attack.Damage ~= nil) then for key, dmg in Shared.skpairs(Attack.Damage) do if(dmg > 0) then typeCount = typeCount + 1 end end end if(typeCount > 1) then return "yes" else return nil end end function p.hasMultipleTypes(frame) local WeapName = frame.args[1] local AttackName = frame.args[2] if(AttackName == nil) then AttackName = "Normal" end local attack = getAttack(WeapName, AttackName) return hasMultipleTypes(attack) end function p.attackLoop(Weapon) if(Weapon == nil) then return function() return nil end end local aType = "Normal" local iterator = function() if(aType == "Normal") then local attack = getAttack(Weapon, aType) aType = "Charge" if attack ~= nil and attack.Damage ~= nil then return "Normal", attack end end if(aType == "Charge") then local attack = getAttack(Weapon, aType) aType = "Area" if attack ~= nil and attack.Damage ~= nil then return "Charge", attack end end if(aType == "Area") then local attack = getAttack(Weapon, aType) aType = "SecondaryArea" if attack ~= nil and attack.Damage ~= nil then return "Area", attack end end if(aType == "SecondaryArea") then local attack = getAttack(Weapon, aType) aType = "Secondary" if attack ~= nil and attack.Damage ~= nil then return "SecondaryArea", attack end end if(aType == "Secondary") then local attack = getAttack(Weapon, aType) aType = "Throw" if attack ~= nil and attack.Damage ~= nil then return "Secondary", attack end end if(aType == "Throw") then local attack = getAttack(Weapon, aType) aType = "ChargedThrow" if attack ~= nil and attack.Damage ~= nil then return "Throw", attack end end if(aType == "ChargedThrow") then local attack = getAttack(Weapon, aType) aType = "end" if attack ~= nil and attack.Damage ~= nil then return "ChargedThrow", attack end end return nil end return iterator end function p.getStance(StanceName) for i, Stance in pairs(WeaponData["Stances"]) do if(Stance.Name == StanceName) then return Stance end end return nil end local function getAugments(Weapon) local name = Weapon.Name ~= nil and Weapon.Name or Weapon local augments = {} for i, Augment in pairs(WeaponData["Augments"]) do for j, WeapName in pairs(Augment.Weapons) do if(WeapName == name) then table.insert(augments, Augment) end end end return augments end local function getFamily(FamilyName) local familyMembers = {} for i, Weapon in Shared.skpairs(WeaponData["Weapons"]) do if(Weapon.Family == FamilyName) then table.insert(familyMembers, Weapon) end end return familyMembers end local function linkMeleeClass(weapClass) if(weapClass == nil) then return nil else return "[[:Kategorie:"..Icon.Deutsch(weapClass).."|"..Icon.Deutsch(weapClass).."]]" end end --Returns all melee weapons. --If weapType is not nil, only grab for a specific type --For example, if weapType is "Nikana", only pull Nikanas local function getMeleeWeapons(weapClass, PvP) local weaps = {} local weapClasses = {} if(weapClass ~= nil) then weapClasses = Shared.splitString(weapClass, ',') end for i, weap in Shared.skpairs(WeaponData["Weapons"]) do if((weap.Ignore == nil or not weap.Ignore) and weap.Type ~= nil and weap.Type == "Melee") then local classMatch = (weapClass == nil or Shared.contains(weapClasses, weap.Class)) local pvpMatch = (PvP == nil or (PvP and weap.Conclave ~= nil and weap.Conclave)) if (classMatch and pvpMatch) then table.insert(weaps, weap) end end end return weaps end --As above, but for Conclave stats local function getConclaveMeleeWeapons(weapClass, PvP) local weaps = {} local weapClasses = {} if(weapClass ~= nil) then weapClasses = Shared.splitString(weapClass, ',') end for i, weap in Shared.skpairs(ConclaveData["Weapons"]) do if((weap.Ignore == nil or not weap.Ignore) and weap.Type ~= nil and weap.Type == "Melee") then local classMatch = (weapClass == nil or Shared.contains(weapClasses, weap.Class)) local pvpMatch = (PvP == nil or (PvP and weap.Conclave ~= nil and weap.Conclave)) if (classMatch and pvpMatch) then table.insert(weaps, weap) end end end return weaps end --Learning new things... Trying to allow sending in an arbitrary function function p.getWeapons(validateFunction) local weaps = {} for i, weap in Shared.skpairs(WeaponData["Weapons"]) do if((weap.Ignore == nil or not weap.Ignore) and validateFunction(weap)) then table.insert(weaps, weap) end end return weaps end --Same as getWeapons, but for Conclave data function p.getConclaveWeapons(validateFunction) local weaps = {} for i, weap in Shared.skpairs(ConclaveData["Weapons"]) do if((weap.Ignore == nil or not weap.Ignore) and validateFunction(weap)) then table.insert(weaps, weap) end end return weaps end local function asPercent(val, digits) if(digits == nil) then digits = 2 end if(val == nil) then val = 0 end local result = val * 100 return string.gsub(Shared.round(result, digits), "%.", "%,").."%" end local function asMultiplier(val) if(val == nil) then return "1,0x" end return string.gsub(Shared.round(val, 2, 1), "%.", "%,").."x" end --Returns all melee weapons. --If weapType is not nil, only grab for a specific type --For example, if weapType is "Nikana", only pull Nikanas local function getStances(weapType, pvpOnly, weapName) local stances = {} if weapType ~= "Exalted Weapon" then for i, stance in Shared.skpairs(WeaponData["Stances"]) do local classMatch = (weapType == nil or weapType == stance.Class) local pvpMatch = (pvpOnly ~= nil and pvpOnly) or (stance.PvP == nil or not stance.PvP) if (classMatch and pvpMatch) then table.insert(stances, stance) end end else for i, stance in Shared.skpairs(WeaponData["Stances"]) do local nameMatch = (weapName == nil or weapName == stance.Weapon) if nameMatch then table.insert(stances, stance) end end end return stances end local function HasTrait(Weapon, Trait) if(Trait == nil or Weapon.Traits == nil) then return false end for i, theTrait in pairs(Weapon.Traits) do if(theTrait == Trait) then return true end end return false end --If Type is not nil, get damage weapon deals of that type --If it deals no damage of that type, return 0 instead of nil --It Type is nil, return total damage local function GetDamage(Attack, Type, ByPellet) if(ByPellet == nil) then ByPellet = false end if(Attack == nil or Attack.Damage == nil) then return 0 end local pCount = 1 if(ByPellet and Attack.PelletCount ~= nil) then pCount = Attack.PelletCount end if(Type == nil) then local total = 0 for i, d in Shared.skpairs(Attack.Damage) do total = total + d end return total / pCount else if(Type == "Physical") then local Impact = Attack.Damage["Impact"] ~= nil and Attack.Damage["Impact"] or 0 local Puncture = Attack.Damage["Puncture"] ~= nil and Attack.Damage["Puncture"] or 0 local Slash = Attack.Damage["Slash"] ~= nil and Attack.Damage["Slash"] or 0 return (Impact + Puncture + Slash) / pCount elseif(Type == "Element") then for dType, dmg in Shared.skpairs(Attack.Damage) do if(not Shared.contains(Physical, dType) or dmg <= 0) then return dmg / pCount end end return 0 elseif(Attack.Damage[Type] == nil) then return 0 else return Attack.Damage[Type] / pCount end end end --Returns the damage string as it's formatted in a comparison row --So instead of '0', returns '-', and appends the icon for an element if necessary local function GetDamageString(Attack, Type, ByPellet) if(ByPellet == nil) then ByPellet = false end if(Attack == nil or Attack.Damage == nil) then return "" end local pCount = 1 if(ByPellet and Attack.PelletCount ~= nil) then pCount = Attack.PelletCount end if(Type == nil) then if(not hasMultipleTypes(Attack)) then for key, val in pairs(Attack.Damage) do if(val > 0) then return Icon._Proc(key).." "..Shared.round(val / pCount, 2) end end return "" else r = string.gsub(Shared.round(GetDamage(Attack, nil, ByPellet), {2, 1}), "%.", "%,") return r end else local thisVal = GetDamage(Attack, Type, ByPellet) if(thisVal == 0) then return "" else r = string.gsub(Shared.round(thisVal, {2, 1}), "%.", "%,") return r end end end local function GetDamageBias(Attack, IncludeSingle) if(IncludeSingle == nil) then IncludeSingle = false end if(Attack.Damage ~= nil and Shared.tableCount(Attack.Damage) > 0) then local total = 0 local bestDmg = 0 local bestElement = nil local count = 0 for Element, Dmg in pairs(Attack.Damage) do if(Dmg > bestDmg) then bestDmg = Dmg bestElement = Element end total = total + Dmg if(Dmg > 0) then count = count + 1 end end --Make sure there are two damage instances that are above zero --Exception for physical damage types if(count > 1 or (IncludeSingle and count > 0)) then return (bestDmg / total), bestElement else return nil end else return nil end end --If the attack has at least two damage types, -- Returns something like "58.3% Slash" --If it doesn't, returns nil local function GetDamageBiasString(Attack, HideType, ShowText, IncludeSingle, Color) if(HideType == nil) then HideType = false end if(ShowText == nil) then ShowText = "" end if(IncludeSingle == nil) then IncludeSingle = false end local bestPercent, bestElement = GetDamageBias(Attack, IncludeSingle) if(bestPercent ~= nil) then local result = asPercent(bestPercent, 0) if(not HideType) then result = Icon._Proc(bestElement, ShowText, Color).." "..result end return result else return nil end end function p.GetPolarityString(Weapon) if(Weapon.Polarities == nil or type(Weapon.Polarities) ~= "table" or Shared.tableCount(Weapon.Polarities) == 0) then return "Keine" else local resString = "" for i, pol in pairs(Weapon.Polarities) do local tempPol = Icon._Pol(pol) if tempPol == "<span style=\"color:red;\">Invalid</span>" and Weapon.Name == "Exalted Blade" then resString = resString..pol else resString = resString..tempPol end end return resString end end local function GetStancePolarity(Weapon) if(Weapon.StancePolarity == nil or Weapon.StancePolarity == "None") then return "Keine" else return Icon._Pol(Weapon.StancePolarity) end end local function getWeaponStanceList(Weapon) if(Weapon == nil or Weapon.Type ~= "Melee") then return nil end local stances = getStances(Weapon.Class, Weapon.Conclave, Weapon.Name) local result = "" for i, stance in pairs(stances) do if (string.len(result) > 0) then result = result.."<br/>" end local polarity = '' local link = '' if Weapon.Class ~= "Exalted Weapon" then polarity = " ("..Icon._Pol(stance.Polarity)..")" link = "[["..Icon.Deutsch(stance.Name).."]]" else link = "[["..Icon.Deutsch(stance.Link)..'|'..Icon.Deutsch(stance.Name).."]]" end result = result..link..polarity --result = result.."<span class=\"mod-tooltip\" data-param=\""..stance.Name.."\" style=\"white-space:pre\">[["..stance.Name.."]]</span>".." ("..Icon._Pol(stance.Polarity)..")" --If this is a PvP Stance, add the disclaimer if(stance.PvP ~= nil and stance.PvP) then result = result.." (Nur PvP)" end end return result end local function getAttackValue(Weapon, Attack, ValName, giveDefault, asString, forTable) if(giveDefault == nil) then giveDefault = false end if(asString == nil) then asString = false end if(forTable == nil) then forTable = false end if(Attack == nil) then if(asString) then return "" else return nil end end regularVal = Shared.titleCase(string.sub(ValName, 1, 1), string.sub(ValName, 2)) ValName = string.upper(ValName) if(ValName == "DAMAGE") then if(Attack.Damage ~= nil) then if(asString) then return GetDamageString(Attack, nil) else return GetDamage(Attack) end elseif giveDefault then return 0 else return nil end elseif(ValName == "DAMAGEPLUS") then if(Attack.Damage ~= nil) then if(asString) then if(hasMultipleTypes(Attack)) then return GetDamageString(Attack, nil).." ("..GetDamageBiasString(Attack, nil, "")..")" else return GetDamageString(Attack, nil) end else return GetDamage(Attack) end elseif giveDefault then return 0 else return nil end elseif(Shared.contains(Elements, regularVal) or ValName == "PHYSICAL" or ValName == "ELEMENT") then if(Attack.Damage ~= nil) then if(asString) then if(hasMultipleTypes(Attack)) then return GetDamageString(Attack, regularVal) else return nil end else return GetDamage(Attack, regularVal) end elseif giveDefault then return 0 else return nil end elseif(ValName == "ACCURACY") then if(Attack.Accuracy ~= nil) then r = string.gsub(Attack.Accuracy,"%.","%,") return r elseif(Attack == Weapon.NormalAttack) then if(Weapon.Accuracy ~= nil) then r = string.gsub(Weapon.Accuracy,"%.","%,") return r else return Weapon.Accuracy end elseif giveDefault then return 0 else return nil end elseif(ValName == "ATTACKNAME") then if(Attack.AttackName ~= nil) then return Icon.Deutsch(Attack.AttackName) elseif(giveDefault) then return "" else return nil end elseif(ValName == "AMMOCOST") then if(Attack.AmmoCost ~= nil) then if(asString) then return Attack.AmmoCost.." Munition pro Schuss" else return Attack.AmmoCost end elseif(giveDefault) then return 1 else return nil end elseif(ValName == "BURSTCOUNT") then if(Attack.BurstCount ~= nil) then if(asString) then local result = Attack.BurstCount.." Schuss" local dmg = GetDamage(Attack) * Attack.BurstCount return result.." ("..string.gsub(Shared.round(dmg, 2, 1),"%.","%,").." Gesamtsch.)" else return Attack.BurstCount end elseif giveDefault then return 0 else return nil end elseif(ValName == "BURSTFIRERATE") then if(Attack.BurstFireRate ~= nil) then return Attack.BurstFireRate elseif giveDefault then return 0 else return nil end elseif(ValName == "CHARGETIME") then if(Attack.ChargeTime ~= nil) then if(asString) then return string.gsub(Shared.round(Attack.ChargeTime, 2, 1),"%.","%,").." s" else return Attack.ChargeTime end elseif giveDefault then return 0 else return nil end elseif(ValName == "CRITCHANCE") then -- note there is getValue version --search in current attack, then normal, if(Attack.CritChance ~= nil) then if(asString) then return asPercent(Attack.CritChance) else return Attack.CritChance end end if(hasAttack(Weapon, "Normal")) then local normAtt = getAttack(Weapon, "Normal") if(normAtt.CritChance ~= nil) then if(asString) then return asPercent(normAtt.CritChance) else return normAtt.CritChance end end end if giveDefault then if(asString) then return asPercent(0) else return 0 end else return nil end elseif(ValName == "CRITMULTIPLIER") then -- note there is getValue version --search in current attack, then normal, if(Attack.CritMultiplier ~= nil) then if(asString) then return asMultiplier(Attack.CritMultiplier) else return Attack.CritMultiplier end end if(hasAttack(Weapon, "Normal")) then local normAtt = getAttack(Weapon, "Normal") if(normAtt.CritMultiplier ~= nil) then if(asString) then return asMultiplier(normAtt.CritMultiplier) else return normAtt.CritMultiplier end end end if giveDefault then if(asString) then return asMultiplier(0) else return 0 end else return nil end elseif(ValName == "DAMAGEBIAS") then if(Shared.tableCount(Attack.Damage) <= 3) then if (GetDamageBiasString(Attack, nil, nil, giveDefault)~=nil) then return GetDamageBiasString(Attack, nil, nil, giveDefault) else return "" end else if(asString or giveDefault) then return "" else return nil end end elseif(ValName == "BULLETTYPE") then if(Attack.ShotType ~= nil) then return Icon.Deutsch(Attack.ShotType) elseif(giveDefault) then return "Unknown" else return nil end elseif(ValName == "DURATION") then if(Attack.Duration ~= nil) then if(asString) then return Shared.round(Attack.Duration, 1, 0).." s" else return Attack.Duration end elseif giveDefault then return 0 else return nil end elseif(ValName == "ELEMENTTYPE") then if(Attack.Damage ~= nil) then for dType, dmg in Shared.skpairs(Attack.Damage) do if(not Shared.contains(Physical, dType) or dmg <= 0) then if(asString) then return Icon._Proc(dType) else return dType end end end elseif asString then return "" else return nil end elseif(ValName =="ELEMENTTYPENAME") then if(Attack.Damage ~= nil) then for dType, dmg in Shared.skpairs(Attack.Damage) do if(not Shared.contains(Physical, dType) or dmg <= 0) then return dType end end elseif asString then return "" else return nil end elseif(ValName == "FALLOFF") then if(Attack.Falloff ~= nil) then local falloffText = "Voller Schaden bis "..string.gsub(Shared.round(Attack.Falloff.StartRange, 2, 1),"%.","%,").." m" falloffText = falloffText.."<br/>Min. Schaden bei "..string.gsub(Shared.round(Attack.Falloff.EndRange, 2, 1),"%.","%,").." m" if(Attack.Falloff.Reduction ~= nil) then falloffText = falloffText.."<br/>"..asPercent(Attack.Falloff.Reduction).." max. Reduktion" end return falloffText else return nil end elseif(ValName == "FIRERATE") then --search in current attack, then normal, then weapon supertable local returnVal = 0 if(Attack.FireRate ~= nil) then returnVal = Attack.FireRate elseif(hasAttack(Weapon, "Normal")) then local normAtt = getAttack(Weapon, "Normal") if(normAtt.FireRate ~= nil) then returnVal = normAtt.FireRate end elseif(Weapon.FireRate ~= nil) then returnVal = Weapon.FireRate end if(asString) then if(Weapon.Type ~= nil and Weapon.Type ~= "Melee" and Weapon.Type ~= "Arch-Melee") then if(forTable) then return string.gsub(Shared.round(returnVal, {3, 1}),"%.","%,")--.." SpS" else return string.gsub(Shared.round(returnVal, {3, 1}),"%.","%,").." Schuss pro Sekunde" end else r = string.gsub(Shared.round(returnVal, {3, 1}),"%.","%,") return r end else return returnVal end if (giveDefault) then returnVal = 0 else return nil end elseif(ValName == "HEADSHOTMULTIPLIER") then --search in current attack, then normal, and finally fall back on base weapon value if for some reason that exists if(Attack.HeadshotMultiplier ~= nil) then if(asString) then return asMultiplier(Attack.HeadshotMultiplier) else return Attack.HeadshotMultiplier end end if(hasAttack(Weapon, "Normal")) then local normAtt = getAttack(Weapon, "Normal") if(normAtt.HeadshotMultiplier ~= nil) then if(asString) then return asMultiplier(normAtt.HeadshotMultiplier) else return normAtt.HeadshotMultiplier end end end if(Weapon.HeadshotMultiplier ~= nil) then if(asString) then return asMultiplier(Weapon.HeadshotMultiplier) else return Weapon.HeadshotMultiplier end end if giveDefault then if(Weapon.Type ~= nil) then --Setting multiplier based on default for each weapon type if(Weapon.Type == "Secondary") then if(Weapon.Class == "Shotgun Sidearm") then return '1.2x' elseif(Weapon.Class == "Crossbow" or Weapon.Class == "Thrown") then return '1.5x' else if(Weapon.Trigger == 'Auto') then return '1.2x' else return '1.5x' end end elseif(Weapon.Type == "Primary") then if(Weapon.Class == "Shotgun") then return "1.2x" elseif(Weapon.Class == "Bow") then return "2.0x" elseif(Weapon.Class == "Sniper Rifle") then return "1.4x" elseif(Weapon.Class == "Launcher") then return "1.0x" else if(Weapon.Trigger == "Auto") then return '1.2x' else return '1.5x' end end end end else return nil end elseif(ValName == "NOISELEVEL") then if(Attack.NoiseLevel ~= nil) then return Icon.Deutsch(Attack.NoiseLevel) else return nil end elseif(ValName == "PELLETCOUNT") then if(Attack.PelletCount ~= nil) then if(asString) then if(Attack.PelletName ~= nil) then return Attack.PelletCount.." "..Attack.PelletName.."e" else return Attack.PelletCount.." Projektile" end else return Attack.PelletCount end elseif giveDefault then return 0 else return nil end elseif(ValName == "PELLETDAMAGE") then if(Attack.PelletCount ~= nil) then local result = GetDamageString(Attack, nil, true) if(Attack.PelletName ~= nil) then return result.." pro "..string.lower(Attack.PelletName) else return result.." pro Projektil" end else return nil end elseif(ValName == "PELLETNAME") then if(Attack.PelletCount ~= nil) then if(Attack.PelletName ~= nil) then return Attack.PelletName else return "Projektil" end else return nil end elseif(ValName == "PELLETPLUS") then if(Attack.PelletCount ~= nil) then local result = Attack.PelletCount.." (" result = string.gsub(result..Shared.round(GetDamage(Attack, nil, true), 2, 1),"%.","%,") if(Attack.PelletName ~= nil) then return result.." Schaden p. "..Icon.Deutsch(Attack.PelletName)..")" else return result.." Schaden p. Projektil)" end else return nil end elseif(ValName == "PROJECTILESPEED") then if(Attack.ShotSpeed ~= nil) then if(asString) then return Attack.ShotSpeed.." m/s" else return Attack.ShotSpeed end elseif(giveDefault) then if(asString) then return "0 m/s" else return 0 end else return nil end elseif(ValName == "PUNCHTHROUGH") then if(Attack.PunchThrough ~= nil) then if(asString) then return string.gsub(Shared.round(Attack.PunchThrough, 2, 1),"%.","%,").." m" else return Attack.PunchThrough end elseif giveDefault then if(asString) then return "0 m" else return 0 end else return nil end elseif(ValName == "RADIUS") then if(Attack.Radius ~= nil) then if(asString) then return string.gsub(Shared.round(Attack.Radius, 2, 1),"%.","%,").." m" else return Attack.Radius end elseif giveDefault then if(asString) then return "0 m" else return 0 end else return nil end elseif(ValName == "RANGE") then if(Attack.Range ~= nil) then if(asString) then return Attack.Range.." m" else return Attack.Range end elseif(giveDefault) then if(asString) then return "0 m" else return 0 end else return nil end elseif(ValName == "RELOAD") then --man screw you too Fusilai if(Attack.Reload ~= nil) then if(asString) then return string.gsub(Shared.round(Attack.Reload, 2, 1),"%.","%,").." s" else return Attack.Reload end elseif giveDefault then return 0 else return nil end elseif(ValName == "SPOOL") then if(Attack.Spool ~= nil) then if(asString) then return Attack.Spool.." Schuss" else return Attack.Spool end else return nil end elseif(ValName == "STANCES") then return getWeaponStanceList(Weapon) elseif(ValName == "STATUSCHANCE") then -- search in current attck, then normal if(Attack.StatusChance ~= nil) then if(asString) then return asPercent(Attack.StatusChance) else return Attack.StatusChance end end if(hasAttack(Weapon, "Normal")) then local normAtt = getAttack(Weapon, "Normal") if(normAtt.StatusChance ~= nil) then if(asString) then return asPercent(normAtt.StatusChance) else return normAtt.StatusChance end end end if giveDefault then if(asString) then return asPercent(0) else return 0 end else return nil end elseif(ValName == "TRIGGER") then -- use getValue for tables -- search in current attack, then weapon supertable if(Attack.Trigger ~= nil) then return Icon.Deutsch(Attack.Trigger) end if(Weapon.Trigger ~= nil) then return Icon.Deutsch(Weapon.Trigger) end if giveDefault then return "Unbekannt" else return nil end else return "ERROR: No such value "..ValName end end local function getValue(Weapon, ValName, giveDefault, asString, forTable) if(giveDefault == nil) then giveDefault = false end if(asString == nil) then asString = false end if(forTable == nil) then forTable = false end if(type(ValName) == "table") then local VName1 = string.upper(ValName[1]) local VName2 = string.upper(ValName[2]) if(VName1 == nil or VName2 == nil) then return nil end if(VName1 == "ATTACK" or VName1 == "NORMALATTACK" or VName1 == "NORMAL") then return getAttackValue(Weapon, getAttack(Weapon, "Normal"), VName2, giveDefault, asString, forTable) elseif(VName1 == "AREA" or VName1 == "AREAATTACK") then return getAttackValue(Weapon, getAttack(Weapon, "Area"), VName2, giveDefault, asString, forTable) elseif(VName1 == "SECONDARYAREA" or VName1 == "SECONDARYAREAATTACK") then return getAttackValue(Weapon, getAttack(Weapon, "SecondaryArea"), VName2, giveDefault, asString, forTable) elseif(VName1 == "CHARGE" or VName1 == "CHARGEATTACK") then return getAttackValue(Weapon, getAttack(Weapon, "Charge"), VName2, giveDefault, asString, forTable) elseif(VName1 == "CHARGEDTHROW" or VName1 == "CHARGEDTHROWATTACK") then return getAttackValue(Weapon, getAttack(Weapon, "ChargedThrow"), VName2, giveDefault, asString, forTable) elseif(VName1 == "THROW" or VName1 == "THROWATTACK") then return getAttackValue(Weapon, getAttack(Weapon, "Throw"), VName2, giveDefault, asString, forTable) elseif(VName1 == "SECONDARY" or VName1 == "SECONDARYATTACK") then return getAttackValue(Weapon, getAttack(Weapon, "Secondary"), VName2, giveDefault, asString, forTable) else return "ERROR: No such attack '"..VName1.."'" end end ValName = string.upper(ValName) if(ValName == "NAME") then if(Weapon.Name ~= nil) then if(forTable) then return "[["..Icon.Deutsch(Weapon.Name).."]]" else return Weapon.Name end elseif giveDefault then return "" else return nil end elseif(ValName == "AMMOTYPE") then if(Weapon.AmmoType ~= nil) then return Weapon.AmmoType elseif giveDefault then if(Weapon.Type ~= nil) then if(Weapon.Type == "Secondary") then return "Pistole" elseif(Weapon.Type == "Primary") then if(Weapon.Class == nil or Weapon.Class == "Rifle") then return "Gewehr" elseif(Weapon.Class == "Shotgun") then return "Schrotflinte" elseif(Weapon.Class == "Bow") then return "Bogen" elseif(Weapon.Class == "Sniper Rifle" or Weapon.Class == "Launcher") then return "Scharfschütze" end end end else return nil end elseif(ValName == "AUGMENT") then local augments = getAugments(Weapon) if(Shared.tableCount(augments) > 0) then local AugString = "" for i, Aug in pairs(augments) do if(i>1) then AugString = AugString.."<br/>" end AugString = AugString.."[["..Icon.Deutsch(Aug.Name).."]]" end return AugString else return nil end elseif(ValName == "BLOCKRESIST") then if(Weapon.Class ~= nil) then if(Weapon.Type == "Melee") then if(Weapon.BlockResist ~= nil) then if(asString) then return asPercent(Weapon.BlockResist) else return Weapon.BlockResist end elseif(Weapon.Class == "Claws" or Weapon.Class == "Dagger" or Weapon.Class == "Dual Daggers" or Weapon.Class == "Glaive" or Weapon.Class == "Nunchaku" or Weapon.Class == "Rapier" or Weapon.Class == "Sparring" or Weapon.Class == "Tonfa" or Weapon.Class == "Whip") then if(asString) then return "35%" else return .35 end elseif(Weapon.Class == "Blade and Whip" or Weapon.Class == "Dual Swords" or Weapon.Class == "Fist" or Weapon.Class == "Gunblade" or Weapon.Class == "Staff" or Weapon.Class == "Sword") then if(asString) then return "60%" else return .6 end elseif(Weapon.Class == "Hammer" or Weapon.Class == "Heavy Blade" or Weapon.Class == "Machete" or Weapon.Class == "Nikana" or Weapon.Class == "Polearm" or Weapon.Class == "Scythe" or Weapon.Class == "Sword and Shield") then if(asString) then return "85%" else return .85 end end else return "" end else return "" end elseif(ValName == "CHANNELMULT") then if(Weapon.ChannelMult ~= nil) then if(asString) then return asMultiplier(Weapon.ChannelMult) else return Weapon.ChannelMult end elseif giveDefault and (Weapon.Type ~= nil and Weapon.Type == "Melee") then if(asString) then return "1,5x" else return 1.5 end else return nil end elseif(ValName == "CLASS") then if(Weapon.Class ~= nil) then if(asString and Weapon.Type == "Melee") then return Icon.Deutsch(Weapon.Class) --return "[[:Kategorie:"..Icon.Deutsch(Weapon.Class).."|"..Icon.Deutsch(Weapon.Class).."]]" else return Icon.Deutsch(Weapon.Class) end elseif giveDefault then return "" else return nil end elseif(ValName == "CONCLAVE") then if(Weapon.Conclave ~= nil) then if(asString) then if(Weapon.Conclave) then return "Yes" else return "No" end else return Weapon.Conclave end elseif giveDefault then return false else return nil end elseif(ValName == "DISPOSITION") then if(Weapon.Type ~= nil and (Weapon.Type == "Arch-Gun" or Weapon.Type == "Arch-Melee") or Weapon.Type == "Emplacement") then return nil end if(Weapon.Disposition ~= nil) then if(asString) then return Icon._Dis(Weapon.Disposition)..' <div style="display:inline; position:relative; bottom:2px">('..Weapon.Disposition..')</div>' else return Weapon.Disposition end elseif giveDefault then if(asString) then return "Unbekannt" else return 0 end else return nil end elseif(ValName == "FAMILY") then if(Weapon.Family ~= nil) then if(asString) then if(Weapon.Family ~= nil) then local FamilyString = "" local Family = getFamily(Weapon.Family) for i, Weap in pairs(Family) do if(Weap.Name ~= Weapon.Name) then if(string.len(FamilyString) > 0) then FamilyString = FamilyString.."<br/>" end FamilyString = FamilyString.."[["..Icon.Deutsch(Weap.Name).."]]" end end return FamilyString end else return Weapon.Family end elseif giveDefault then return "" else return nil end elseif(ValName == "FINISHERDAMAGE") then if(Weapon.FinisherDamage ~= nil) then if(asString) then return Shared.round(Weapon.FinisherDamage, 2, 1) else return Weapon.FinisherDamage end elseif giveDefault then return 0 else return nil end elseif(ValName == "IMAGE") then if(Weapon.Image ~= nil) then return Weapon.Image elseif giveDefault then return "Panel.png" else return nil end elseif(ValName == "INTRODUCED") then if(Weapon.Introduced ~= nil) then return Weapon.Introduced elseif giveDefault then return "" else return nil end elseif(ValName == "JUMPATTACK") then if(Weapon.JumpAttack ~= nil) then if(asString) then if(Weapon.JumpElement ~= nil) then return Icon._Proc(Weapon.JumpElement).." "..string.gsub(Shared.round(Weapon.JumpAttack, 2, 1),"%.","%,") else r = string.gsub(Shared.round(Weapon.JumpAttack, 2, 1),"%.","%,") return r end else return Weapon.JumpAttack end elseif giveDefault then return 0 else return nil end elseif(ValName == "JUMPELEMENT") then if(Weapon.JumpElement ~= nil) then return Weapon.JumpElement elseif giveDefault then return "" else return nil end elseif(ValName == "JUMPRADIUS") then if(Weapon.JumpRadius ~= nil) then if(asString) then r = string.gsub(Shared.round(Weapon.JumpRadius, 2, 1),"%.","%,").." m" return r else return Weapon.JumpRadius end elseif giveDefault then return 0 else return nil end elseif(ValName == "MAGAZINE") then if(Weapon.Magazine ~= nil) then if(asString) then if (forTable) then return Weapon.Magazine else return Weapon.Magazine.." Schuss pro Magazin" end else return Weapon.Magazine end elseif giveDefault then if(asString) then return "0 Schuss pro Magazin" else return 0 end else return nil end elseif(ValName == "MASTERY") then if(Weapon.Mastery ~= nil) then return Weapon.Mastery elseif giveDefault then return 0 else return nil end elseif(ValName == "MAXAMMO") then local returnVal = 0 if(Weapon.MaxAmmo ~= nil) then returnVal = Weapon.MaxAmmo elseif giveDefault then if(Weapon.Type ~= nil) then if(Weapon.Type == "Secondary") then returnVal = 210 elseif(Weapon.Type == "Primary") then if(Weapon.Class == nil or Weapon.Class == "Rifle") then returnVal = 540 elseif(Weapon.Class == "Shotgun") then returnVal = 120 elseif(Weapon.Class == "Bow" or Weapon.Class == "Sniper Rifle") then returnVal = 72 end end end else return nil end if(asString) then if(returnVal > 0) then return returnVal.." Schuss" else return nil end else if(returnVal > 0) then return returnVal else return nil end end elseif(ValName == "NOISELEVEL") then if(Weapon.NoiseLevel ~= nil) then return Icon.Deutsch(Weapon.NoiseLevel) elseif giveDefault then if(Weapon.Type ~= nil and Weapon.Type ~= "Melee" and Weapon.Type ~= "Arch-Melee") then if(Weapon.Class ~= nil and (Weapon.Class == "Bow" or Weapon.Class == "Thrown")) then return "Leise" else return "Alarmierend" end else return nil end else return nil end elseif(ValName == "POLARITIES") then if(Weapon.Polarities ~= nil and type(Weapon.Polarities) == "table") then if(asString) then return p.GetPolarityString(Weapon) else return Weapon.Polarities end elseif giveDefault then if(asString) then return "Keine" else return {} end else return nil end elseif(ValName == "RELOAD") then if(Weapon.Reload ~= nil) then if(asString) then if(Weapon.ReloadStyle ~= nil) then if(Weapon.ReloadStyle == "ByRound" and Weapon.Magazine ~= nil) then local result = string.gsub(Shared.round(Weapon.Reload / Weapon.Magazine, 2, 1),"%.","%,").." Sek. pro Kugel" result = result.." ("..string.gsub(Shared.round(Weapon.Reload, 2, 1),"%.","%,").."s gesamt)" if(forTable) then result = string.gsub(Shared.round(Weapon.Reload, 2, 1),"%.","%,").." s" end return result elseif(Weapon.ReloadStyle == "Regenerate") then local result = string.gsub(Shared.round(Weapon.Reload, 2, 1),"%.","%,").." Kugeln pro Sek." if(Weapon.Magazine ~= nil) then result = result.." ("..string.gsub(Shared.round(Weapon.Magazine / Weapon.Reload, 2, 1),"%.","%,").."s gesamt)" if(forTable) then result=string.gsub(Shared.round(Weapon.Magazine / Weapon.Reload, 2, 1),"%.","%,").." s" end end return result end end return string.gsub(Shared.round(Weapon.Reload, 2, 1),"%.","%,").." s" else return Weapon.Reload end elseif giveDefault then return 0 else return nil end elseif(ValName == "SLIDEATTACK") then if(Weapon.SlideAttack ~= nil) then if(asString) then if(Weapon.SlideElement ~= nil) then return Icon._Proc(Weapon.SlideElement).." "..string.gsub(Shared.round(Weapon.SlideAttack, 2, 1),"%.","%,") else r = string.gsub(Shared.round(Weapon.SlideAttack, 2, 1),"%.","%,") return r end else return Weapon.SlideAttack end elseif giveDefault then return 0 else return nil end elseif(ValName == "SLIDEELEMENT") then if(Weapon.SlideElement ~= nil) then return Weapon.SlideElement elseif giveDefault then return "" else return nil end elseif(ValName == "SNIPERCOMBORESET") then if(Weapon.SniperComboReset ~= nil) then if(asString) then return string.gsub(Shared.round(Weapon.SniperComboReset, 2, 1),"%.","%,").." s" else return Weapon.SniperComboReset end elseif giveDefault then return 0 else return nil end elseif(ValName == "SNIPERCOMBOMIN") then if(Weapon.SniperComboMin ~= nil) then if(asString) then return Weapon.SniperComboMin.." Schüsse" else return Weapon.SniperComboMin end elseif giveDefault then return 0 else return nil end elseif(ValName == "STAGGER") then if(Weapon.Stagger ~= nil) then return Weapon.Stagger elseif giveDefault then return "No" else return nil end elseif(ValName == "STANCEPOLARITY") then if(Weapon.StancePolarity ~= nil) then if(asString) then return Icon._Pol(Weapon.StancePolarity) else return Weapon.StancePolarity end elseif giveDefault then return "None" else return nil end elseif(ValName == "SYNDICATEEFFECT") then if(Weapon.SyndicateEffect ~= nil) then if(asString) then return "[["..Icon.Deutsch(Weapon.SyndicateEffect).."]]" else return Weapon.SyndicateEffect end else return nil end elseif(ValName == "TRAITS") then if(Weapon.Traits ~= nil) then return Weapon.Traits elseif giveDefault then return {} else return nil end elseif(ValName == "TRIGGER") then -- Note there is a specific version for each attack in getAttackValue if(Weapon.Trigger ~= nil) then if (forTable) then -- return chargetime and burstcount only in tables local trigger = Weapon.Trigger if(trigger == "Charge") then local cTime = getAttackValue(Weapon, getAttack(Weapon,"Charge"), "ChargeTime", false) if(cTime ~= nil) then return Icon.Deutsch(trigger).." ("..Shared.round(cTime, 2, 1).."s)" else return Icon.Deutsch(trigger) end elseif(trigger == "Burst") then local bCount = getAttackValue(Weapon, getAttack(Weapon,"Normal"), "BurstCount", false) if(bCount ~= nil) then return Icon.Deutsch(trigger).." ("..bCount..")" else return Icon.Deutsch(trigger) end else return Icon.Deutsch(trigger) end else return Icon.Deutsch(Weapon.Trigger) end elseif giveDefault then return "Unbekannt" else return nil end elseif(ValName == "CRITCHANCE") then -- Note there is a specific version for each attack in getAttackValue -- search in charge attck, then normal, then secondary if still null local returnVal=0 local Attack={} if(hasAttack(Weapon, "Charge")) then local chargAtt = getAttack(Weapon, "Charge") if(chargAtt.CritChance ~= nil) then returnVal=chargAtt.CritChance Attack=chargAtt end end if(hasAttack(Weapon, "Normal") and returnVal ==0) then local normAtt = getAttack(Weapon, "Normal") if(normAtt.CritChance ~= nil) then returnVal=normAtt.CritChance Attack=normAtt end end if(hasAttack(Weapon, "Secondary") and returnVal ==0) then local secAtt = getAttack(Weapon, "Secondary") if(secAtt.CritChance ~= nil) then returnVal=secAtt.CritChance Attack=secAtt end end if(asString and returnVal ~= 0) then return asPercent(returnVal) else return returnVal end if giveDefault then return 0 else return nil end elseif(ValName == "CRITMULTIPLIER") then--Note there is a specific version for each attack in getAttackValue -- search in charge attck, then normal, then secondary if still null local returnVal=0 local Attack={} if(hasAttack(Weapon, "Charge")) then local chargAtt = getAttack(Weapon, "Charge") if(chargAtt.CritMultiplier ~= nil) then returnVal=chargAtt.CritMultiplier Attack=chargAtt end end if(hasAttack(Weapon, "Normal") and returnVal ==0) then local normAtt = getAttack(Weapon, "Normal") if(normAtt.CritMultiplier ~= nil) then returnVal=normAtt.CritMultiplier Attack=normAtt end end if(hasAttack(Weapon, "Secondary") and returnVal ==0) then local secAtt = getAttack(Weapon, "Secondary") if(secAtt.CritMultiplier ~= nil) then returnVal=secAtt.CritMultiplier Attack=secAtt end end if(asString and returnVal ~= 0) then return asMultiplier(returnVal) else return returnVal end if giveDefault then return 0 else return nil end elseif(ValName == "FIRERATE") then -- Note there is a specific version for each attack in getAttackValue -- search in global weapon then normal attck, then charge, then secondary if still null local returnVal=0 local Attack={} if(Weapon.FireRate ~= nil) then returnVal = Weapon.FireRate end if(hasAttack(Weapon, "Normal") and returnVal ==0) then local normAtt = getAttack(Weapon, "Normal") if(normAtt.FireRate ~= nil) then returnVal=normAtt.FireRate Attack=normAtt end end if(hasAttack(Weapon, "Charge") and returnVal ==0) then local chargAtt = getAttack(Weapon, "Charge") if(chargAtt.FireRate ~= nil) then returnVal=chargAtt.FireRate Attack=chargAtt end end if(hasAttack(Weapon, "Secondary") and returnVal ==0) then local secAtt = getAttack(Weapon, "Secondary") if(secAtt.FireRate ~= nil) then returnVal=secAtt.FireRate Attack=secAtt end end if(asString and returnVal ~= 0) then if(Weapon.Type ~= nil and Weapon.Type ~= "Melee" and Weapon.Type ~= "Arch-Melee") then if(forTable) then return string.gsub(Shared.round(returnVal, {3, 1}),"%.","%,")--.." SpS" else return string.gsub(Shared.round(returnVal, {3, 1}),"%.","%,").." Schuss pro Sekunde" end else return string.gsub(Shared.round(returnVal, {3, 1}),"%.","%,") end else return returnVal end if giveDefault then return 0 else return nil end elseif(ValName == "STATUSCHANCE") then -- Note there is a specific version for each attack in getAttackValue -- search in charge attck, then normal, then secondary if still null local returnVal=0 local Attack={} if(hasAttack(Weapon, "Charge")) then local chargAtt = getAttack(Weapon, "Charge") if(chargAtt.StatusChance ~= nil) then returnVal=chargAtt.StatusChance Attack=chargAtt end end if(hasAttack(Weapon, "Normal") and returnVal ==0) then local normAtt = getAttack(Weapon, "Normal") if(normAtt.StatusChance ~= nil) then returnVal=normAtt.StatusChance Attack=normAtt end end if(hasAttack(Weapon, "Secondary") and returnVal ==0) then local secAtt = getAttack(Weapon, "Secondary") if(secAtt.StatusChance ~= nil) then returnVal=secAtt.StatusChance Attack=secAtt end end if(asString and returnVal ~= 0) then return asPercent(returnVal) else return returnVal end if giveDefault then return 0 else return nil end elseif(ValName == "TYPE") then if(Weapon.Type ~= nil) then return Icon.Deutsch(Weapon.Type) elseif giveDefault then return "" else return nil end elseif(ValName == "USERS") then if(Weapon.Users ~= nil) then if(asString) then local result = "" for i, str in pairs(Weapon.Users) do mw.log(i, str) if(i > 1) then result = result..'<br/>' end result = result..Icon.Deutsch(str) end return result else return Weapon.Users end elseif giveDefault then return {} else return nil end elseif(ValName == "WALLATTACK") then if(Weapon.WallAttack ~= nil) then if(asString) then if(Weapon.WallElement ~= nil) then return Icon._Proc(Weapon.WallElement).." "..string.gsub(Shared.round(Weapon.WallAttack, 2, 1),"%.","%,") else r = string.gsub(Shared.round(Weapon.WallAttack, 2, 1),"%.","%,") return r end else return Weapon.WallAttack end elseif giveDefault then return 0 else return nil end elseif(ValName == "WALLELEMENT") then if(Weapon.WallElement ~= nil) then return Weapon.WallElement elseif giveDefault then return "" else return nil end elseif(ValName == "ZOOM") then if(Weapon.Zoom ~= nil) then if(asString) then local result = "" for i, str in pairs(Weapon.Zoom) do if(i > 1) then result = result..'<br/>' end result = result..Icon.Deutsch(str) end return result else return Weapon.Zoom end else return nil end elseif(ValName == "SPECIALFSPEED") then -- to show we can put very special keywords... if wanted if(Weapon.Name == "Drakgoon") then if(asString) then return "bounce: 25 m/s" else return 25 end elseif(getAttackValue(Weapon,getAttack(Weapon,"Area"),"PROJECTILESPEED")~=nil) then if(asString) then return getAttackValue(Weapon,getAttack(Weapon,"Area"),"PROJECTILESPEED",true,true) else return getAttackValue(Weapon,getAttack(Weapon,"Area"),"PROJECTILESPEED") end elseif(getAttackValue(Weapon,getAttack(Weapon,"Secondary"),"PROJECTILESPEED")~=nil) then if(asString) then return getAttackValue(Weapon,getAttack(Weapon,"Secondary"),"PROJECTILESPEED",true,true) else return getAttackValue(Weapon,getAttack(Weapon,"Secondary"),"PROJECTILESPEED") end elseif(giveDefault) then if(asString) then return "0 m/s" else return 0 end else return nil end else --if everything failed (and it should NOT) try in the getAttackValue return getAttackValue(Weapon, getAttack(Weapon, "Normal"), ValName, giveDefault, asString) end end function p.getValue(frame) local WeapName = frame.args[1] local ValName1 = frame.args[2] local ValName2 = frame.args[3] local AsString = frame.args["Raw"] == nil if(WeapName == nil) then return "" elseif(ValName1 == nil) then return "ERROR: No value selected" end local theWeap = p.getWeapon(WeapName) if(theWeap == nil) then return "" end local vName local useDefault if(ValName2 == nil or ValName2 == "") then vName = ValName1 useDefault = Shared.contains(UseDefaultList, string.upper(ValName1)) else vName = {ValName1, ValName2} useDefault = Shared.contains(UseDefaultList, string.upper(ValName2)) end return getValue(theWeap, vName, useDefault, AsString) end function p.getConclaveValue(frame) local WeapName = frame.args[1] local ValName1 = frame.args[2] local ValName2 = frame.args[3] if(WeapName == nil) then return "" elseif(ValName1 == nil) then return "ERROR: No value selected" end local theWeap = p.getConclaveWeapon(WeapName) if(theWeap == nil) then return "" end local vName local useDefault if(ValName2 == nil or ValName2 == "") then vName = ValName1 useDefault = Shared.contains(UseDefaultList, string.upper(ValName1)) else vName = {ValName1, ValName2} useDefault = Shared.contains(UseDefaultList, string.upper(ValName2)) end return getValue(theWeap, vName, useDefault, true) end local function buildInfoboxRow(Label, Text, Collapse, Digits, Addon) local result = "" if(Collapse == nil) then Collapse = false elseif(Collapse == 1) then Collapse = true end if(Text ~= nil) then result = '<div style="margin-left:-3px;" ' if(Collapse) then result = result..'class="Infobox_Collapsible"' end result = result..'>' result = result..'\n{| style="width:100%;"' result = result..'\n|-' result = result..'\n| class="left" | <span style="white-space:nowrap;">' result = result.."'''"..Label.."'''" result = result..'</span>' result = result..'\n| class="right" | ' if(Digits == nil) then result = result..Text else result = result..Shared.round(Text, Digits) end if(Addon ~= nil) then result = result..p.doPlural(Addon, Text) end result = result..'\n|}' result = result..'\n</div>' end return result end --Returns a list of weapons for a stance --Adds a ✓ if the weapon matches the polarity function p.getStanceWeaponList(frame) local StanceName = frame.args ~= nil and frame.args[1] or frame local Stance = p.getStance(StanceName) if(Stance == nil) then return "ERROR: "..StanceName.." not found" end local weaps = getMeleeWeapons(Stance.Class, Stance.PvP) local result = "" for i, weap in Shared.skpairs(weaps) do if (string.len(result) > 0) then result = result.."\n" end result = result.."*[["..Icon.Deutsch(weap.Name).."]]" if(weap.StancePolarity == Stance.Polarity) then result = result.." ✓" end end return result end --Returns a list of stances for a weapon --Adds the polarity for each stance function p.getWeaponStanceList(frame) local WeaponName = frame.args ~= nil and frame.args[1] or frame local Weapon = getWeapon(WeaponName) if(Weapon == nil) then return "ERROR: "..WeaponName.." not found" end return getWeaponStanceList(Weapon) end function p.getStanceGallery(frame) local StanceType = frame.args ~= nil and frame.args[1] or frame local Stances = getStances(StanceType, true) local result = "=="..StanceType.." [[Stance|Stance Mods]]==" result = result..'\n{| style="margin:auto;text-align:center;"' local nameRow = '' for i, Stance in pairs(Stances) do local theImage = Stance.Image ~= nil and Stance.Image or "Panel.png" if((i - 1) % 4 == 0) then result = result..nameRow..'\n|-' nameRow = '\n|-' end result = result..'\n| style="width:165px" |[[File:'..Stance.Image..'|150px|link='..Stance.Name..']]' nameRow = nameRow..'\n| style="vertical-align: text-top;" |[['..Stance.Name..']]' if(Stance.PvP ~= nil and Stance.PvP) then nameRow = nameRow..'<br/>([[Conclave]] only)' end end result = result..nameRow result = result..'\n|}' return result end local function getWeaponGallery(Weapons) local result = '{| style="margin:auto;text-align:center;"' local nameRow = '' for i, Weapon in pairs(Weapons) do local theImage = Weapon.Image ~= nil and Weapon.Image or "Panel.png" if((i - 1) % 4 == 0) then result = result..nameRow..'\n|-' nameRow = '\n|-' end result = result..'\n| style="width:165px" |[[File:'..theImage..'|150px|link='..Weapon.Name..']]' nameRow = nameRow..'\n| style="vertical-align: text-top;" |[['..Weapon.Name..']]' end result = result..nameRow result = result..'\n|}' return result end function p.getMeleeWeaponGallery(frame) local Type = frame.args ~= nil and frame.args[1] or frame if(Type == nil) then return "" end local WeapArray = getMeleeWeapons(Type) local result = "=="..Type.." Weapons==\n" result = result..getWeaponGallery(WeapArray) return result end function p.getWeaponCount(frame) local Type = frame.args ~= nil and frame.args[1] or frame local getFullList = frame.args ~= nil and frame.args[2] local count = 0 local fullList = "" for i, val in Shared.skpairs(WeaponData["Weapons"]) do if(not Shared.contains(WeaponData["IgnoreInCount"], i)) then if(Type == nil or Type == "") then count = count + 1 if(getFullList ~= nil) then fullList = fullList..'\n# '..val.Name end elseif(Type == "Warframe") then if(val.Type == "Primary" or val.Type == "Secondary" or val.Type == "Melee") then count = count + 1 if(getFullList ~= nil) then fullList = fullList..'\n# '..val.Name end end elseif(Type == "Archwing") then if(val.Type == "Arch-Gun" or val.Type == "Arch-Melee") then count = count + 1 if(getFullList ~= nil) then fullList = fullList..'\n# '..val.Name end end else if(val.Type == Type) then count = count + 1 if(getFullList ~= nil) then fullList = fullList..'\n# '..val.Name end end end end end if(getFullList ~= nil) then return fullList end return count end function getSecondaryCategory(weapon) local class = getValue(weapon, "Class", true) if(class == Icon.Deutsch("Thrown")) then return "Thrown" elseif(class == Icon.Deutsch("Dual Shotguns") or class == Icon.Deutsch("Shotgun Sidearm")) then return "Shotgun" else local trigger = getValue(weapon, "Trigger", true) if(trigger == Icon.Deutsch("Semi-Auto") or trigger == Icon.Deutsch("Burst")) then return "Semi-Auto" elseif(trigger == Icon.Deutsch("Auto") or trigger == Icon.Deutsch("Auto-Spool")) then return "Auto" end end return "Other" end function getPrimaryCategory(weapon) local class = getValue(weapon, "Class", true) if(class == Icon.Deutsch("Shotgun")) then return "Shotgun" elseif(class == Icon.Deutsch("Bow")) then return "Bow" elseif(class == Icon.Deutsch("Sniper Rifle")) then return "Sniper" elseif(class == Icon.Deutsch("Rifle")) then local trigger = getValue(weapon, "Trigger", true) if(trigger == Icon.Deutsch("Semi-Auto") or trigger == Icon.Deutsch("Burst")) then return "Semi-Auto" elseif(trigger == Icon.Deutsch("Auto") or trigger == Icon.Deutsch("Auto-Spool")) then return "Auto" end end return "Other" end function p.getPolarityTable() local tHeader = "" tHeader = tHeader..'\n{| style="width: 100%; border-collapse: collapse; cellpadding: 2" border="1"' tHeader = tHeader..'\n! colspan="2" |Primary Weapons' tHeader = tHeader..'\n! colspan="2" |Secondary Weapons' tHeader = tHeader..'\n! colspan="2" |Melee Weapons' local tRows = "" local Melees = p.getWeapons(function(x) return p.isMelee(x) and Shared.tableCount(getValue(x, "Polarities", true)) > 0 end) local Pistols = p.getWeapons(function(x) return x.Type == "Secondary" and Shared.tableCount(getValue(x, "Polarities", true)) > 0 end) local Primaries = p.getWeapons(function(x) return (x.Type == "Primary") and Shared.tableCount(getValue(x, "Polarities", true)) > 0 end) local ACount = Shared.tableCount(Melees) local maxLen = ACount local BCount = Shared.tableCount(Pistols) if(BCount > maxLen) then maxLen = BCount end local CCount = Shared.tableCount(Primaries) if(CCount > maxLen) then maxLen = CCount end for i=1, maxLen, 1 do tRows = tRows.."\n|-" if(i <= CCount) then tRows = tRows.."\n|[["..Primaries[i].Name.."]]||"..p.GetPolarityString(Primaries[i]) else tRows = tRows.."\n| ||" end if(i <= BCount) then tRows = tRows.."\n|[["..Pistols[i].Name.."]]||"..p.GetPolarityString(Pistols[i]) else tRows = tRows.."\n| ||" end if(i <= ACount) then tRows = tRows.."\n|[["..Melees[i].Name.."]]||"..p.GetPolarityString(Melees[i]) else tRows = tRows.."\n| ||" end end return tHeader..tRows.."\n|}" end function buildCompareString(Val1, Val2, ValName, Digits, Addon, Words, Start) if(Val1 == nil or Val2 == nil) then return "" end local V1Str = Val1 local V2Str = Val2 if(Digits ~= nil) then local didWork, rowStr = pcall(Shared.round, Val1, Digits) if(didWork) then V1Str = string.gsub(rowStr,"%.","%,") local didWork, rowStr = pcall(Shared.round, Val2, Digits) if(didWork) then V2Str = string.gsub(rowStr,"%.","%,") else mw.log("Failed to round "..Val2) end else mw.log("Failed to round "..Val1) end end if(Addon ~= nil) then V1Str = V1Str..p.doPlural(Addon, Val1) V2Str = V2Str..p.doPlural(Addon, Val2) end local bigWord = Words ~= nil and Words[1] or "Höherer" local smallWord = Words ~= nil and Words[2] or "Niedrigerer" local start = Start ~= nil and Start or "\n**" if(Val1 > Val2) then return start.." "..bigWord.." "..ValName.." ("..V1Str.." vs. "..V2Str..")" elseif(Val2 > Val1) then return start.." "..smallWord.." "..ValName.." ("..V1Str.." vs. "..V2Str..")" else return "" end end function buildGunComparisonString(Weapon1, Weapon2) local result = "* "..Icon.Deutsch(Weapon1.Name)..", verglichen mit [["..Icon.Deutsch(Weapon2.Name).."]]:" if(hasAttack(Weapon1, "Normal") and hasAttack(Weapon2, "Normal")) then local Att1 = getAttack(Weapon1, "Normal") local Att2 = getAttack(Weapon2, "Normal") local dmgString = "" dmgString = dmgString..buildCompareString(GetDamage(Att1), GetDamage(Att2), "Basisschaden", {2, 1}, nil, {"Mehr", "Weniger"}) dmgString = dmgString..buildCompareString(Att1.Damage["Impact"], Att2.Damage["Impact"], Icon._Proc("Impact", "text").."schaden", {2, 1}, nil, {"Höherer", "Geringerer"}, "\n***") dmgString = dmgString..buildCompareString(Att1.Damage["Puncture"], Att2.Damage["Puncture"], Icon._Proc("Puncture", "text").."schaden", {2, 1}, nil, {"Höherer", "Geringerer"}, "\n***") dmgString = dmgString..buildCompareString(Att1.Damage["Slash"], Att2.Damage["Slash"], Icon._Proc("Slash", "text").."schaden", {2, 1}, nil, {"Höherer", "Geringerer"}, "\n***") if(string.len(dmgString) > 0 and GetDamage(Att1) == GetDamage(Att2)) then dmgString = "\n**Gleicher Basisschaden, but different composition:"..dmgString end result = result..dmgString end if(hasAttack(Weapon1, "Charge")and hasAttack(Weapon2, "Charge")) then result = result..buildCompareString(GetDamage(Weapon1.ChargeAttack), GetDamage(Weapon2.ChargeAttack), "aufgeladener Schaden", {2, 1}) result = result..buildCompareString(getValue(Weapon1, {"Charge", "ChargeTime"}), getValue(Weapon2, {"Charge", "ChargeTime"}), "Aufladegeschw.", {2, 1}, " s", {"Langsamere", "Schnellere"}) end if(hasAttack(Weapon1, "Area") and hasAttack(Weapon2, "Area")) then result = result..buildCompareString(GetDamage(Weapon1.AreaAttack), GetDamage(Weapon2.AreaAttack), "Flächenschaden", {2, 1}) end if(hasAttack(Weapon1, "Secondary") and hasAttack(Weapon2, "Secondary")) then result = result..buildCompareString(GetDamage(Weapon1.SecondaryAttack), GetDamage(Weapon2.SecondaryAttack), "secondary attack damage", {2, 1}) end if(hasAttack(Weapon1, "Normal") and hasAttack(Weapon2, "Normal") ) then local Att1 = getAttack(Weapon1, "Normal") local Att2 = getAttack(Weapon2, "Normal") if(Att1.CritChance ~= nil and Att2.CritChance ~= nil) then result = result..buildCompareString((Att1.CritChance * 100), (Att2.CritChance * 100), "Krit. Chance", 2, "%", {"Höhere", "Niedrigere"}) end result = result..buildCompareString(Att1.CritMultiplier, Att2.CritMultiplier, "Krit. Multiplikator", 2, "x", {"Höherer", "Niedrigerer"}) if(Att1.StatusChance ~= nil and Att2.StatusChance ~= nil) then result = result..buildCompareString((Att1.StatusChance * 100), (Att2.StatusChance * 100), "Status Chance", 2, "%", {"Höhere", "Niedrigere"}) end result = result..buildCompareString(Att1.FireRate, Att2.FireRate, "Feuerrate", 2, " Schuss/Sek.", {"Bessere", "Schlechtere"}) --Handling Damage Falloff if(Att1.Falloff ~= nil and Att2.Falloff == nil) then result = result.."\n** "..Att1.Falloff.StartRange.."m - "..Att1.Falloff.EndRange.."m damage falloff" if(Att1.Falloff.Reduction ~= nil) then result = result.." with up to "..(Att1.Falloff.Reduction * 100).."% damage reduction" end elseif(Att2.Falloff ~= nil and Att1.Falloff == nil) then result = result.."\n** No "..Att2.Falloff.StartRange.."m - "..Att2.Falloff.EndRange.."m damage falloff" if(Att2.Falloff.Reduction ~= nil) then result = result.." with up to "..(Att2.Falloff.Reduction * 100).."% damage reduction" end elseif(Att1.Falloff ~= nil and Att2.Falloff ~= nil) then result = result..buildCompareString(Att1.Falloff.StartRange, Att2.Falloff.StartRange, "Reichweite bevor Schadensabfall startet", 2, "m", {"Längere", "Kürzere"}) result = result..buildCompareString(Att1.Falloff.EndRange, Att2.Falloff.EndRange, "Reichweite bevor Schadensabfall endet", 2, "m", {"Längere", "Kürzere"}) if(Att1.Falloff.Reduction ~= nil and Att2.Falloff.Reduction ~= nil) then result = result..buildCompareString(Att1.Falloff.Reduction * 100, Att2.Falloff.Reduction * 100, "max. Schadensreduktion durch Schadensabfall", 2, "%", {"Höhere", "Niedrigere"}) end end end result = result..buildCompareString(Weapon1.Magazine, Weapon2.Magazine, "Magazin", 0, " Schuss", {"Größeres", "Kleineres"}) result = result..buildCompareString(Weapon1.MaxAmmo, Weapon2.MaxAmmo, "max. Munitionskapazität", 0, " Schuss", {"Größere", "Kleinere"}) --If this is a weapon that regenerates ammo, flip the comparison if (Weapon1.ReloadStyle ~= nil and Weapon1.ReloadStyle == "Regenerate") then result = result..buildCompareString(Weapon1.Reload, Weapon2.Reload, "Nachladegeschw.", 2, " s", {"Schnellere", "Langsamere"}) else result = result..buildCompareString(Weapon1.Reload, Weapon2.Reload, "Nachladegeschw.", 2, " s", {"Langsamere", "Schnellere"}) end result = result..buildCompareString(Weapon1.Spool, Weapon2.Spool, "Anlaufzeit", 0, " Schuss", {"Langsamere", "Schnellere"}) local Acc1 = getValue(Weapon1, "Accuracy") local Acc2 = getValue(Weapon2, "Accuracy") if(type(Acc1) == "number" and type(Acc2) == "number") then result = result..buildCompareString(Acc1, Acc2, "Genauigkeit", 0, nil, {"Höhere", "Geringere"}) end --Handling Syndicate radial effects if(Weapon1.SyndicateEffect ~= nil and Weapon2.SyndicateEffect == nil) then result = result.."\n** Inklusive [["..Icon.Deutsch(Weapon1.SyndicateEffect).."]] Syndikat-Effekt" elseif(Weapon2.SyndicateEffect ~= nil and Weapon1.SyndicateEffect == nil) then result = result.."\n** Das Fehlen eines [["..Icon.Deutsch(Weapon2.SyndicateEffect).."]] Syndikat-Effekts" elseif(Weapon1.SyndicateEffect ~= nil and Weapon2.SyndicateEffect ~= nil and Weapon1.SyndicateEffect ~= Weapon2.SyndicateEffect2) then result = result.."\n** Unterschiedliche [[Syndikate|Syndikat Effekte]]: [["..Icon.Deutsch(Weapon1.SyndicateEffect).."]] vs. [["..Icon.Deutsch(Weapon2.SyndicateEffect).."]]" end --Handling Polarities local Pol1 = Weapon1.Polarities ~= nil and Weapon1.Polarities or {} local Pol2 = Weapon2.Polarities ~= nil and Weapon2.Polarities or {} local count1 = Shared.tableCount(Pol1) local count2 = Shared.tableCount(Pol2) local isDifferent = count1 ~= count2 if(not isDifferent and count1 > 0) then table.sort(Pol1, function(x, y) return x < y end) table.sort(Pol2, function(x, y) return x < y end) for i, pol in pairs(Pol1) do if(pol ~= Pol2[i]) then isDifferent = true end end end if(isDifferent) then result = result.."\n** Unterschiedliche Polaritäten ("..p.GetPolarityString(Weapon1).." vs. "..p.GetPolarityString(Weapon2)..")" end result = result..buildCompareString(Weapon1.Mastery, Weapon2.Mastery, "[[Meisterschaft|Meisterschaftsrang]] benötigt", 0) return result end function buildMeleeComparisonString(Weapon1, Weapon2) local result = "* "..Icon.Deutsch(Weapon1.Name)..", verglichen mit [["..Icon.Deutsch(Weapon2.Name).."]]:" local dmgString = "" local Att1 = getAttack(Weapon1, "Normal") local Att2 = getAttack(Weapon2, "Normal") dmgString = dmgString..buildCompareString(GetDamage(Att1), GetDamage(Att2), "Basisschaden", {2, 1}) dmgString = dmgString..buildCompareString(Att1.Damage["Impact"], Att2.Damage["Impact"], Icon._Proc("Impact", "text").."schaden", {2, 1}, nil, {"Höherer", "Geringerer"}, "\n***") dmgString = dmgString..buildCompareString(Att1.Damage["Puncture"], Att2.Damage["Puncture"], Icon._Proc("Puncture", "text").."schaden", {2, 1}, nil, {"Höherer", "Geringerer"}, "\n***") dmgString = dmgString..buildCompareString(Att1.Damage["Slash"], Att2.Damage["Slash"], Icon._Proc("Slash", "text").."schaden", {2, 1}, nil, {"Höherer", "Geringerer"}, "\n***") if(string.len(dmgString) > 0 and GetDamage(Att1) == GetDamage(Att2)) then dmgString = "\n**Gleicher Basisschaden, aber andere Zusammensetzung:"..dmgString end result = result..dmgString if(Att1.CritChance ~= nil and Att2.CritChance ~= nil) then result = result..buildCompareString((Att1.CritChance * 100), (Att2.CritChance * 100), "Krit. Chance", 2, "%", {"Höhere", "Niedrigere"}) end result = result..buildCompareString(Att1.CritMultiplier, Att2.CritMultiplier, "Krit. Multiplikator", {2, 1}, "x") if(Att1.StatusChance ~= nil and Att2.StatusChance ~= nil) then result = result..buildCompareString((Att1.StatusChance * 100), (Att2.StatusChance * 100), "Status Chance", 2, "%", {"Höhere", "Niedrigere"}) end result = result..buildCompareString(Att1.FireRate, Att2.FireRate, "Angriffsgeschw.", 2, "", {"Höhere", "Niedrigere"}) result = result..buildCompareString(Icon._Pol(Weapon1.StancePolarity), Icon._Pol(Weapon2.StancePolarity), "Haltungspolarität", nil, nil, {"Unterschiedliche", "Unterschiedliche"}) result = result..buildCompareString(getValue(Weapon1, "ChannelMult", true), getValue(Weapon2, "ChannelMult", true), "Kanalisierungs-Multiplikator", 1, "x", {"Larger", "Smaller"}) --Handling Polarities local Pol1 = Weapon1.Polarities ~= nil and Weapon1.Polarities or {} local Pol2 = Weapon2.Polarities ~= nil and Weapon2.Polarities or {} local count1 = Shared.tableCount(Pol1) local count2 = Shared.tableCount(Pol2) local isDifferent = count1 ~= count2 if(not isDifferent and count1 > 0) then table.sort(Pol1, function(x, y) return x < y end) table.sort(Pol2, function(x, y) return x < y end) for i, pol in pairs(Pol1) do if(pol ~= Pol2[i]) then isDifferent = true end end end if(isDifferent) then result = result.."\n** Unterschiedliche Polaritäten ("..p.GetPolarityString(Weapon1).." vs. "..p.GetPolarityString(Weapon2)..")" end result = result..buildCompareString(Weapon1.Mastery, Weapon2.Mastery, "[[Meisterschaft|Meisterschaftsrang]] benötigt", 0) return result end function p.buildComparison(frame) local WeapName1 = frame.args[1] local WeapName2 = frame.args[2] if(WeapName1 == nil or WeapName2 == nil) then return '<span style="color:red">ERROR: Must compare two weapons</span>' end local Weapon1 = p.getWeapon(WeapName1) if(Weapon1 == nil) then return '<span style="color:red">ERROR: Could not find '..WeapName1..'</span>' end local Weapon2 = p.getWeapon(WeapName2) if(Weapon2 == nil) then return '<span style="color:red">ERROR: Could not find '..WeapName2..'</span>' end if(p.isMelee(Weapon1)) then return buildMeleeComparisonString(Weapon1, Weapon2).."[[Kategorie:Automatischer Vergleich]]" else return buildGunComparisonString(Weapon1, Weapon2).."[[Kategorie:Automatischer Vergleich]]" end end function p.buildConclaveComparison(frame) local WeapName1 = frame.args[1] local WeapName2 = frame.args[2] if(WeapName1 == nil or WeapName2 == nil) then return '<span style="color:red">ERROR: Must compare two weapons</span>' end local Weapon1 = p.getConclaveWeapon(WeapName1) if(Weapon1 == nil) then return '<span style="color:red">ERROR: Could not find '..WeapName1..'</span>' end local Weapon2 = p.getConclaveWeapon(WeapName2) if(Weapon2 == nil) then return '<span style="color:red">ERROR: Could not find '..WeapName2..'</span>' end if(p.isMelee(Weapon1)) then return buildMeleeComparisonString(Weapon1, Weapon2).."[[Kategorie:Automatischer Vergleich]]" else return buildGunComparisonString(Weapon1, Weapon2).."[[Kategorie:Automatischer Vergleich]]" end end function p.buildFamilyComparison(frame) local WeapName = frame.args ~= nil and frame.args[1] or frame if(WeapName == nil) then return '<span style="color:red">ERROR: Must provide a Weapon name</span>' end local Weapon = p.getWeapon(WeapName) if(Weapon == nil) then return '<span style="color:red">ERROR: Could not find '..WeapName1..'</span>' end if(Weapon.Family == nil) then return '<span style="color:red">ERROR: '..WeapName..' doesn\'t have a family</span>' end local relatives = getFamily(Weapon.Family) local result = {} for i, NewWeapon in pairs(relatives) do if(WeapName ~= NewWeapon.Name) then if(p.isMelee(NewWeapon)) then table.insert(result, buildMeleeComparisonString(Weapon, NewWeapon)) else table.insert(result, buildGunComparisonString(Weapon, NewWeapon)) end end end return table.concat(result, "\n") end function p.buildAutoboxCategories(frame) local WeapName = frame.args ~= nil and frame.args[1] or frame local Weapon = p.getWeapon(WeapName) local result = "[[Kategorie:Automatische Waffen Box]][[Kategorie:Waffen]]" if(Weapon == nil) then return "" elseif(Weapon.IgnoreCategories ~= nil and Weapon.IgnoreCategories) then return "" end if(Weapon.Type ~= nil) then if(Weapon.Type == "Arch-Melee") then result = result.."[[Kategorie:".."Archwing Nahkampf]]" elseif(Weapon.Type == "Arch-Gun") then result = result.."[[Kategorie:".."Archwing Gewehre]]" else result= result.."[[Kategorie:"..Icon.Deutsch(Weapon.Type).."waffen]]" end end if(Weapon.Class ~= nil) then if(Weapon.Class == "Rifle") then result = result.."[[Kategorie:".."Gewehre]]" elseif(Weapon.Class == "Thrown") then result = result.."[[Kategorie:".."Wurfwaffen]]" elseif(Weapon.Class == "Pistol") then result = result.."[[Kategorie:".."Pistolen]]" elseif(Weapon.Class == "Shotgun") then result = result.."[[Kategorie:".."Schrotflinten]]" elseif(Weapon.Class == "Dual Shotgun") then result = result.."[[Kategorie:".."Doppel-Schrotflinten]]" elseif(Weapon.Class == "Hammer") then result = result.."[[Kategorie:".."Hämmer]]" elseif(Weapon.Class == "Dual Pistols") then result = result.."[[Kategorie:".."Doppelpistolen]]" elseif(Weapon.Class == "Speargun") then result = result.."[[Kategorie:".."Speerwaffen]]" elseif(Weapon.Class == "Polearm") then result = result.."[[Kategorie:".."Stangenwaffen]]" elseif(Weapon.Class == "Bow") then result = result.."[[Kategorie:".."Bögen]]" elseif(Weapon.Class == "Tonfa") then result = result.."[[Kategorie:".."Tonfas]]" elseif(Weapon.Class == "Dagger") then result = result.."[[Kategorie:".."Dolche]]" elseif(Weapon.Class == "Nikana") then result = result.."[[Kategorie:".."Nikanas]]" elseif(Weapon.Class == "Machete") then result = result.."[[Kategorie:".."Macheten]]" elseif(Weapon.Class == "Rapier") then result = result.."[[Kategorie:".."Rapiere]]" elseif(Weapon.Class == "Dual Daggers") then result = result.."[[Kategorie:".."Doppeldolche]]" elseif(Weapon.Class == "Scythe") then result = result.."[[Kategorie:".."Sensen]]" elseif(Weapon.Class == "Staff") then result = result.."[[Kategorie:".."Stäbe]]" else result = result.."[[Kategorie:"..Icon.Deutsch(Weapon.Class).."]]" end end local augments = getAugments(Weapon) if(Shared.tableCount(augments) > 0) then result = result.."[[Kategorie:Augment Mods]]" end if(HasTrait(Weapon, "Prime")) then result = result.."[[Kategorie:Prime]][[Kategorie:Prime Waffen]]" if(HasTrait(Weapon, "Never Vaulted")) then result = result.."[[Kategorie:Noch Nie Im Vault]]" elseif(HasTrait(Weapon, "Vaulted")) then result = result.."[[Kategorie:Im Vault]]" end end if(HasTrait(Weapon, "Grineer")) then result = result.."[[Kategorie:Grineer Waffen]]" elseif(HasTrait(Weapon, "Corpus")) then result = result.."[[Kategorie:Corpus Waffen]]" elseif(HasTrait(Weapon, "Infested")) then result = result.."[[Kategorie:Befallene Waffen]]" elseif(HasTrait(Weapon, "Tenno")) then result = result.."[[Kategorie:Tenno Waffen]]" end local attack = nil if(hasAttack(Weapon, "Normal")) then attack = getAttack(Weapon, "Normal") elseif(hasAttack(Weapon, "Charge")) then attack = getAttack(Weapon, "Charge") end if(attack ~= nil) then local bestPercent, bestElement = GetDamageBias(attack) if(bestElement == "Impact" or bestElement == "Puncture" or bestElement == "Slash") then if(bestPercent > .38) then result = result.."[[Kategorie:"..Icon.Deutsch(bestElement).."schaden-Waffen]]" else result = result.."[[Kategorie:Ausbalancierte Physisschaden-Waffen]]" end end for key, value in Shared.skpairs(attack.Damage) do if(key ~= "Impact" and key ~= "Puncture" and key ~= "Slash") then result = result.."[[Kategorie:"..Icon.Deutsch(key).."schaden-Waffen]]" end end end if(hasAttack(Weapon, "Secondary")) then result = result.."[[Kategorie:Waffen mit ".."Zweit".."funktion]]" end return result end function p.buildAugmentTable(frame) local result = "" result = result..'\n{|class="listtable sortable" style="width:100%;"' result = result..'\n|-' result = result..'\n! Name' result = result..'\n! Category' result = result..'\n! Source' result = result..'\n! Weapon' for i, Augment in pairs(WeaponData["Augments"]) do local thisStr = "\n|-" thisStr = thisStr.."\n| [["..Augment.Name.."]]" thisStr = thisStr.."\n| "..Augment.Category thisStr = thisStr.."\n| [["..Augment.Source.."]]" thisStr = thisStr.."\n| " for i, weap in pairs(Augment.Weapons) do if(i>1) then thisStr = thisStr.."<br/>" end thisStr = thisStr.."[["..weap.."]]" end result = result..thisStr end result = result..'\n|}' return result end function noNil(val, default) if(val ~= nil) then return val else if(default ~= nil) then return default else return "" end end end function p.buildDamageTypeTable(frame) local DamageType = frame.args ~= nil and frame.args[1] or frame local Weapons = {} local WeapArray = p.getWeapons(function(x) local Dmg, Element if (hasAttack(x, "Normal")) then Dmg, Element = GetDamageBias(getAttack(x, "Normal"), true) elseif(hasAttack(x, "Charge")) then Dmg, Element = GetDamageBias(getAttack(x, "Charge"), true) else return false end return Element == DamageType end) local procString = Icon._Proc(DamageType,'text') local procShort = Icon._Proc(DamageType) local result = "" local tHeader = '{|class = "listtable sortable" style="margin:auto;"' tHeader = tHeader..'\n|-' tHeader = tHeader..'\n!Name' tHeader = tHeader..'\n!Type' tHeader = tHeader..'\n!Class' tHeader = tHeader..'\n!'..procString tHeader = tHeader..'\n!'..procShort..'%' local tRows = "" for i, Weapon in pairs(WeapArray) do local thisRow = '\n|-\n|' thisRow = thisRow.."[["..Icon.Deutsch(Weapon.Name).."]]||"..Icon.Deutsch(Weapon.Type).."|| "..getValue(Weapon, "Class", true, true) if(hasAttack(Weapon, "Normal")) then thisRow = thisRow.."||"..getValue(Weapon, {"Normal", DamageType}).."||"..getValue(Weapon, {"Normal", "DamageBias"}, true) elseif(hasAttack(Weapon, "Charge")) then thisRow = thisRow.."||"..getValue(Weapon, {"Charge", DamageType}).."||"..getValue(Weapon, {"Charge", "DamageBias"}, true) end tRows = tRows..thisRow end result = tHeader..tRows.."\n|}" return result end function p.buildWeaponByMasteryRank(frame) local MasteryRank local MRTable = {} for i, Weapon in Shared.skpairs(WeaponData["Weapons"]) do if(Weapon.Mastery ~= nil) then if(MRTable[Weapon.Mastery] == nil) then MRTable[Weapon.Mastery] = {} end if(MRTable[Weapon.Mastery][Weapon.Type] == nil) then MRTable[Weapon.Mastery][Weapon.Type] = {} end table.insert(MRTable[Weapon.Mastery][Weapon.Type], Weapon) end end local result = "" for i, TypeTable in Shared.skpairs(MRTable) do local thisTable = "\n==Mastery Rank "..i.." Required==" if(i == 0) then thisTable = "==No Mastery Rank Required==" end thisTable = thisTable..'\n{| style="width:80%;margin:auto"' thisTable = thisTable..'\n|-\n| style="vertical-align:top;width:33%;" |' if(TypeTable["Primary"] ~= nil and Shared.tableCount(TypeTable["Primary"]) > 0) then thisTable = thisTable.."\n===Primary===" local tempList = p.shortLinkList(TypeTable["Primary"]) for i, text in pairs(tempList) do thisTable = thisTable.."\n* "..text end end thisTable = thisTable..'\n| style="vertical-align:top;width:33%;" |' if(TypeTable["Secondary"] ~= nil and Shared.tableCount(TypeTable["Secondary"]) > 0) then thisTable = thisTable.."\n===Secondary===" local tempList = p.shortLinkList(TypeTable["Secondary"]) for i, text in pairs(tempList) do thisTable = thisTable.."\n* "..text end end thisTable = thisTable..'\n| style="vertical-align:top;width:33%;" |' if(TypeTable["Melee"] ~= nil and Shared.tableCount(TypeTable["Melee"]) > 0) then thisTable = thisTable.."\n===Melee===" local tempList = p.shortLinkList(TypeTable["Melee"]) for i, text in pairs(tempList) do thisTable = thisTable.."\n* "..text end end thisTable = thisTable.."\n|}" result = result..thisTable end return result end function p.getMasteryShortList(frame) local WeaponType = frame.args[1] local MasteryRank = tonumber(frame.args[2]) local weapArray = p.getWeapons(function(x) if(x.Type ~= nil and x.Mastery ~= nil) then return x.Type == WeaponType and x.Mastery == MasteryRank else return false end end) local result = "" local shortList = p.shortLinkList(weapArray) for i, pair in Shared.skpairs(shortList) do if(string.len(result) > 0) then result = result.." • " end result = result..pair end return result end function p.getRivenDispositionList(frame) local WeaponType = frame.args[1] local Disposition = tonumber(frame.args[2]) local weapArray = p.getWeapons(function(x) if(x.Type ~= nil and x.Disposition ~= nil) then return (string.upper(WeaponType) == "ALL" or x.Type == WeaponType) and x.Disposition == Disposition else return false end end) local result = "" local shortList = p.shortLinkList(weapArray) for i, pair in Shared.skpairs(shortList) do result = result..'\n* '..pair end return result end function p.getRivenDispositionTable(frame) local WeaponType = frame.args[1] local result = '{| class="article-table" border="0" cellpadding="1" cellspacing="1" style="width: 100%"' result = result..'\n|-' for i = 5, 1, -1 do result = result..'\n! scope="col" style="text-align:center;"|'..Icon._Dis(i) end result = result..'\n|-' for i = 5, 1, -1 do result = result..'\n| style="vertical-align:top" |' result = result..p.getRivenDispositionList({args = {WeaponType, i}}) end result = result..'\n|}' return result end function p.getConclaveList(frame) local WeaponType = frame.args[1] local weapArray = p.getWeapons(function(x) if(x.Type ~= nil and x.Conclave ~= nil) then return x.Type == WeaponType and x.Conclave else return false end end) local result = "" local shortList = p.shortLinkList(weapArray) for i, pair in Shared.skpairs(shortList) do result = result..'\n* '..pair end return result end --Runs a bunch of things to quickly check if anything broke function p.checkForBugs(frame) return p.buildComparison({args = {"Lato", "Lato Prime"}})..p.buildComparison({args = {"Glaive", "Glaive Prime"}})..p.getMeleeComparisonTable({})..p.getSecondaryComparisonTable({}) end function p.checkElements(frame) local result = "wyrd" for key, theWeap in Shared.skpairs(WeaponData["Weapons"]) do for attName, Attack in p.attackLoop(theWeap) do local elementCount = 0 if(Attack.Damage ~= nil) then for element, dmg in Shared.skpairs(Attack.Damage) do if(not Shared.contains(Physical, element)) then elementCount = elementCount + 1 end end else result = result.."\n"..key.." attempted to loop the "..attName.." attack" end if(elementCount > 1) then result = result.."\n"..key.." has "..elementCount.." elements in its "..attName.." attack" end end end return result end function p.checkForMissingData(frame) local result = "" for key, weapon in Shared.skpairs(WeaponData["Weapons"]) do if(weapon.Name == nil) then result = result.."\n"..key.." does not have a Name" end if(weapon.Image == nil) then result = result.."\n"..key.." does not have an Image" end if(weapon.Mastery == nil) then result = result.."\n"..key.." does not have Mastery" end if(weapon.Disposition == nil and p.isArchwing(weapon) == nil) then result = result.."\n"..key.." does not have Disposition" end if(weapon.Type == nil) then result = result.."\n"..key.." does not have a Type" end if(weapon.Class == nil and p.isArchwing(weapon) == nil) then result = result.."\n"..key.." does not have a Class" end if(weapon.NormalAttack ~= nil and weapon.NormalAttack.Damage == nil) then result = result.."\n"..key.." does not do Normal Attacks" end end if (result == "") then result = "All weapons complete based on this test" end return result end function p.buildTunaWeaponTable(frame) local Category = frame.args ~= nil and frame.args[1] or frame local Weapons = p.getWeapons( function(x) return getValue(x, "Type", true) == Category end) local result = '{| style="margin:auto;text-align:center;"' local i = 0 for key, Weapon in Shared.skpairs(Weapons) do i = i + 1 local theImage = Weapon.Image ~= nil and Weapon.Image or "Panel.png" if((i - 1) % 7 == 0) then result = result..'\n|-' end result = result..'\n| style="width:85px" |[[File:'..Weapon.Name..'.png|70px]]' end result = result..'\n|}' return result end -- and we are back... new table building functions ! local function BuildCompRow(Head, Weapon, UseCompDisplay) --User:Falterfire 6/12/18 - Adding new Comparison Display functionality -- Toggled with a variable, which is false if not specified if UseCompDisplay == nil then UseCompDisplay = false end local styleString = ""--"border: 1px solid lightgray;" local td = '' local result = '' local ValNameZ = nil local ValName = nil --User:Faltefire 6/12/18 - By default, use old version of code if not UseCompDisplay or Weapon.ComparisonDisplay == nil then local attName = "" if(hasAttack(Weapon, "Charge")) then attName = "Charge" elseif(hasAttack(Weapon, "Normal")) then attName = "Normal" else return "" end result = '\n|-\n|' for i, Hline in ipairs(Head) do ValName = Hline[1] if(type(ValName) == "table" and ValName[1]=="default") then ValName = {attName, ValName[2]} elseif(type(ValName) == "table") then ValName = {ValName[1], ValName[2]} end if(i == 1) then td = '' else td='||' end if(getValue(Weapon, ValName)~=nil) then --Add a data sort value if requested if(Hline[2]) then result = result..td..'data-sort-value="'..getValue(Weapon, ValName)..'" style="'..styleString..'"|'..getValue(Weapon, ValName, true, true, true) else result = result..td..'style="'..styleString..'"|'..getValue(Weapon, ValName, true, true, true) end else result = result..td..'style = "'..styleString..'"|'.."n.v." end end else --User:Faltefire 6/12/18 - Swap to new version if ComparisonDisplay is set for this weapon and UseCompDisplay is true for i, row in pairs(Weapon.ComparisonDisplay) do local attCount = Shared.tableCount(row.Attacks) if attCount > 0 then local rowText = '\n|-\n|' local attName = row.Attacks[1] for j, Hline in ipairs(Head) do ValName = Hline[1] local KeyName = '' --If we're using the ComparisonDisplay, we're overriding the attempt to shunt to a different attack --So always use attName + ValName, with one two exceptions: Damage and Name are overridden if(type(ValName) == "table") then ValName = {attName, ValName[2]} KeyName = string.upper(ValName[2]) else KeyName = string.upper(ValName) end if(j == 1) then td = '' else td='||' end if KeyName == 'NAME' then local rowName = string.gsub(row.Name, "%[NAME%]", Icon.Deutsch(Weapon.Name)) rowName = string.gsub(rowName, "Uncharged", "Ungeladen") rowName = string.gsub(rowName, "Charged", "Geladen") --Replace the default name with the name from ComparisonDisplay rowText = rowText..td..'style="'..styleString..'"|[['..Icon.Deutsch(Weapon.Name)..'|'..rowName..']]' elseif KeyName == 'DAMAGE' then --For damage, go with the listed attack if attCount == 1 then rowText = rowText..td..'data-sort-value="'..getValue(Weapon, {attName, "Damage"})..'" style="'..styleString..'"|'..getValue(Weapon, {attName, "Damage"}, true, true, true) else --If multiple attacks are listed, show the combined damage local attDmg = 0 for k, att in pairs(row.Attacks) do mw.log(att) attDmg = attDmg + getValue(Weapon, {att, "Damage"}) end rowText = rowText..td..'data-sort-value="'..attDmg..'" style="'..styleString..'"|'..attDmg end else if(getValue(Weapon, ValName) ~= nil) then --Add a data sort value if requested if(Hline[2]) then rowText = rowText..td..'data-sort-value="'..getValue(Weapon, ValName)..'" style="'..styleString..'"|'..getValue(Weapon, ValName, true, true, true) else rowText = rowText..td..'style="'..styleString..'"|'..getValue(Weapon, ValName, true, true, true) end else rowText = rowText..td..'style = "'..styleString..'"|'.."n.v." end end end result = result..rowText end end end return result end local function BuildCompTable(Head, Weapons, UseCompDisplay) local styleString = "border: 1px solid black;border-collapse: collapse;" local tHeader = "" tHeader = tHeader..'\n{| cellpadding="1" cellspacing="0" class="listtable sortable" style="font-size:11px;"' for i, Hline in ipairs(Head) do if(Hline[2] == true) then tHeader = tHeader..'\n! data-sort-type="number" style="'..styleString..'"|'..Hline[3]..'' else tHeader = tHeader..'\n! style="'..styleString..'"|'..Hline[3]..'' end end -- mw.log(tHeader) local tRows = "" for i, Weap in pairs(Weapons) do rowStr = BuildCompRow(Head, Weap, UseCompDisplay) tRows = tRows..rowStr end -- mw.log(tRows) return tHeader..tRows.."\n|}[[Kategorie:Automatischer Vergleich]]" end function p.getCompTableGuns(frame) local Catt = frame.args ~= nil and frame.args[1] local Type = frame.args ~= nil and frame.args[2] or nil if(Type == "All") then Type = nil end local WeapArray = {} if(Catt == "Primary") then WeapArray = p.getWeapons(function(x) if(getValue(x, "Type", true) == Icon.Deutsch("Primary")) then if(Type ~= nil) then return getPrimaryCategory(x) == Type else return true end end return false end) local count = 0 --for _ in pairs(WeapArray) do count = count + 1 end -- return "\n Error :"..count elseif(Catt == "Secondary") then WeapArray = p.getWeapons(function(x) if(getValue(x, "Type", true) == Icon.Deutsch("Secondary")) then if(Type ~= nil) then return getSecondaryCategory(x) == Type else return true end end return false end) elseif(Catt == "Sentinel") then WeapArray = p.getWeapons(function(x) return getValue(x, "Type", true) == Icon.Deutsch("Sentinel") end) else return "\n Error : Wrong Class (use Primary, Secondary, or Sentinel) [[Category:Invalid Comp Table]]" end local Head={{"Name",false,"Name"}} -- better if Name is always the first column !!! table.insert(Head,{"Trigger",false,"Abzug"}) table.insert(Head,{{"default","Damage"},true,"Schaden"}) table.insert(Head,{{"default", "CritChance"},true,"Krit. Chance"}) table.insert(Head,{{"default", "CritMultiplier"},true,"Krit. Schaden"}) table.insert(Head,{{"default", "StatusChance"},true,"Status Chance"}) table.insert(Head,{{"default","BulletType"},false,"Projektil"}) table.insert(Head,{{"default", "FireRate"},true,"Feuer-rate"}) table.insert(Head,{"Magazine",true,"Magazin-größe"}) table.insert(Head,{"Reload",true,"Nach-laden"}) table.insert(Head,{"Mastery",true,"Rang"}) table.insert(Head,{"Disposition",true,"Disposition"}) return BuildCompTable(Head, WeapArray, true) end function p.getCompTableConclaveGuns(frame) local Catt = frame.args ~= nil and frame.args[1] local Type = frame.args ~= nil and frame.args[2] or nil if(Type == "All") then Type = nil end local WeapArray = {} if(Catt == "Primary") then WeapArray = p.getConclaveWeapons(function(x) if(getValue(x, "Type", true) == "Primary") then if(Type ~= nil) then return getPrimaryCategory(x) == Type else return true end end return false end) elseif(Catt == "Secondary") then WeapArray = p.getConclaveWeapons(function(x) if(getValue(x, "Type", true) == "Secondary") then if(Type ~= nil) then return getSecondaryCategory(x) == Type else return true end end return false end) else return "\n Error : Wrong Class (use Primary or Secondary) [[Category:Invalid Comp Table]]" end local Head={{"Name",false,"Name"}} -- better if Name is always the first column !!! table.insert(Head,{"Trigger",false,"Abzug"}) table.insert(Head,{{"default","Damage"},true,"Schaden"}) table.insert(Head,{"CritChance",true,"Krit. Chance"}) table.insert(Head,{"CritMultiplier",true,"Krit. Schaden"}) table.insert(Head,{"StatusChance",true,"Status Chance"}) table.insert(Head,{{"default","BulletType"},false,"Projektil"}) table.insert(Head,{"FireRate",true,"Feuer-rate"}) table.insert(Head,{"Magazine",true,"Magazin-größe"}) table.insert(Head,{"Reload",true,"Nach-laden"}) table.insert(Head,{"Mastery",true,"Rang"}) table.insert(Head,{"Disposition",true,"[[Riven Mods#Disposition|Disposition]]"}) return BuildCompTable(Head,WeapArray) end function p.getCompTableArchGuns(frame) local WeapArray = {} WeapArray = p.getWeapons(function(x) return getValue(x, "Type", true) == Icon.Deutsch("Arch-Gun") end) local Head={{"Name",false,"Name"}} -- better if Name is always the first column !!! table.insert(Head,{"Trigger",false,"Abzug"}) table.insert(Head,{{"default","Damage"},true,"Schaden"}) table.insert(Head,{"CritChance",true,"Krit. Chance"}) table.insert(Head,{"CritMultiplier",true,"Krit. Schaden"}) table.insert(Head,{"StatusChance",true,"Status Chance"}) table.insert(Head,{{"default","BulletType"},false,"Projektil"}) table.insert(Head,{"FireRate",true,"Feuer-rate"}) table.insert(Head,{"Magazine",true,"Magazin-größe"}) table.insert(Head,{"Reload",true,"Nach-laden"}) table.insert(Head,{"Mastery",true,"Rang"}) return BuildCompTable(Head,WeapArray) end function p.getCompTableMelees(frame) --Changed formatting, now only takes type since only class handled is Melee --Keeping old formatting to avoid breaking pages local Type = frame.args ~= nil and frame.args[2] or nil if(Type == nil) then Type = frame.args ~= nil and frame.args[1] or nil end if(Type == "All") then Type = nil end local WeapArray = {} WeapArray = getMeleeWeapons(Type) local addClass = Type == nil or Shared.contains(Type, ",") local Head={{"Name",false,"Name"}} -- better if Name is always the first column !!! table.insert(Head,{"Class",false,"Typ"}) table.insert(Head,{{"Normal","Damage"},true,"Schaden"}) table.insert(Head,{"SlideAttack",true,"Wirbel-attacke"}) table.insert(Head,{{"default","FireRate"},true,"Angriffs-geschw."}) table.insert(Head,{"CritChance",true,"Krit. Chance"}) table.insert(Head,{"CritMultiplier",true,"Krit. Schaden"}) table.insert(Head,{"StatusChance",true,"Status Chance"}) table.insert(Head,{"Mastery",true,"Rang"}) table.insert(Head,{"STANCEPOLARITY",false,"Haltung"}) table.insert(Head,{"Disposition",true,"[[Riven Mods#Disposition|Disposition]]"}) for k, v in pairs(Head[1]) do mw.log(k, v) end return BuildCompTable(Head,WeapArray) end --As above, but for conclave function p.getCompTableConclaveMelees(frame) local Type = frame.args ~= nil and frame.args[1] or nil if(Type == "All") then Type = nil end local WeapArray = {} WeapArray = getConclaveMeleeWeapons(Type) local addClass = Type == nil or Shared.contains(Type, ",") local Head={{"Name",false,"Name"}} -- better if Name is always the first column !!! table.insert(Head,{"Class",false,"Type"}) table.insert(Head,{{"Normal","Damage"},true,"Schaden"}) table.insert(Head,{"SlideAttack",true,"Wirbel-attacke"}) table.insert(Head,{{"default","FireRate"},true,"Angriffs-geschw."}) table.insert(Head,{"CritChance",true,"Krit. Chance"}) table.insert(Head,{"CritMultiplier",true,"Krit. Schaden"}) table.insert(Head,{"StatusChance",true,"Status Chance"}) table.insert(Head,{"Mastery",true,"Rang"}) table.insert(Head,{"STANCEPOLARITY",false,"Haltung"}) table.insert(Head,{"Disposition",true,"[[Riven Mods#Disposition|Disposition]]"}) for k, v in pairs(Head[1]) do mw.log(k, v) end return BuildCompTable(Head,WeapArray) end function p.getCompTableArchMelees(frame) local WeapArray = {} WeapArray = p.getWeapons(function(x) return getValue(x, "Type", true) == Icon.Deutsch("Arch-Melee") end) local Head={{"Name",false,"Name"}} -- better if Name is always the first column !!! table.insert(Head,{{"Normal","Damage"},true,"Schaden"}) table.insert(Head,{"SlideAttack",true,"Wirbel-attacke"}) table.insert(Head,{{"default","FireRate"},true,"Angriffs-geschw."}) table.insert(Head,{"CritChance",true,"Krit. Chance"}) table.insert(Head,{"CritMultiplier",true,"Krit. Schaden"}) table.insert(Head,{"StatusChance",true,"Status Chance"}) table.insert(Head,{"Mastery",true,"Rang"}) for k, v in pairs(Head[1]) do mw.log(k, v) end return BuildCompTable(Head,WeapArray) end function p.getCompTableSpeedGuns(frame) local Catt = frame.args ~= nil and frame.args[1] local Type = frame.args ~= nil and frame.args[2] or nil if(Type == "All") then Type = nil end local WeapArray = {} if(Catt == "Primary") then WeapArray = p.getWeapons(function(x) if(getValue(x, "Type", true) == "Primary") then if(Type ~= nil) then return getPrimaryCategory(x) == Type else return true end end return false end) elseif(Catt == "Secondary") then WeapArray = p.getWeapons(function(x) if(getValue(x, "Type", true) == "Secondary") then if(Type ~= nil) then return getSecondaryCategory(x) == Type else return true end end return false end) elseif(Catt == "Sentinel") then WeapArray = p.getWeapons(function(x) return getValue(x, "Type", true) == "Sentinel" end) elseif(Catt == "Arch-Gun") then WeapArray = p.getWeapons(function(x) return getValue(x, "Type", true) == "Arch-Gun" end) else return "\n Error : Wrong Class (use Primary, Secondary, Sentinel, or Arch-Gun) [[Category:Invalid Comp Table]]" end -- special sorting for projectile weapons local WeapArray2 = {} for k, Weapon in ipairs(WeapArray) do local attName = "" if(hasAttack(Weapon, "Charge")) then attName = "Charge" elseif(hasAttack(Weapon, "Normal")) then attName = "Normal" else return "" end if(getValue(Weapon,{attName, "BulletType"}, false) == "Projectile") then table.insert(WeapArray2, Weapon) elseif(getValue(Weapon,{"Area", "BulletType"}, false) == "Projectile") then table.insert(WeapArray2, Weapon) elseif(getValue(Weapon,{"Secondary", "BulletType"}, false) == "Projectile") then table.insert(WeapArray2, Weapon) elseif (getValue(Weapon,{attName, "BulletType"}, false) == "Thrown") then table.insert(WeapArray2, Weapon) end end local Head={{"Name",false,"Name"}} -- better if Name is always the first column !!! table.insert(Head,{"Class",false,"Type"}) table.insert(Head,{{"Normal","PROJECTILESPEED"},true,"Flight Speed"}) table.insert(Head,{{"Charge","PROJECTILESPEED"},true,"Charge Flight Speed"}) table.insert(Head,{"SPECIALFSPEED",true,"Alt-Fire / Special"}) return BuildCompTable(Head,WeapArray2) end function p.getCompTableSpeedMelees(frame) local Catt = frame.args ~= nil and frame.args[1] local Type = frame.args ~= nil and frame.args[2] or nil if(Type == "All") then Type = nil end local WeapArray = {} if(Catt == "Melee") then WeapArray = getMeleeWeapons(Type) local addClass = Type == nil or Shared.contains(Type, ",") elseif(Catt == "Arch-Melee") then WeapArray = p.getWeapons(function(x) return getValue(x, "Type", true) == "Arch-Melee" end) else return "\n Error : Wrong Class (use Melee or Arch-Melee) [[Category:Invalid Comp Table]]" end -- special sorting for projectile weapons ONLY WORKS FOR GLAIVE TYPE MELEE WEAPONS !!! local WeapArray2 = {} for k, Weapon in ipairs(WeapArray) do if (getValue(Weapon,{"Normal", "BulletType"}, false) == "Thrown") then table.insert(WeapArray2, Weapon) end end local Head={{"Name",false,"Name"}} -- better if Name is always the first column !!! table.insert(Head,{{"Normal","PROJECTILESPEED"},true,"Flight Speed"}) table.insert(Head,{"SPECIALFSPEED",true,"Special"}) return BuildCompTable(Head,WeapArray2) end function p.weaponTooltip(frame) local weapName = frame.args ~= nil and frame.args[1] --there's no "Dark Split-Sword" in m:weapons/data -> setting name to dual sword variant if weapName == 'Dark Split-Sword' then weapName = 'Dark Split-Sword (Dual Swords)' end local Title = frame.args[2] local A2Name = nil local A2Value = nil local C1Name = nil local C1Value = nil local C1Toggle = nil local C2Name = nil local C2Value = nil local titleText = '' local hasCharged = false local attackType = 'Normal' local IPSCounter = 0 local attack = nil local attackText = '' local space = ' ' local attackBiasText = '' if weapName == nil then return nil end local Weapon = p.getWeapon(weapName) if Weapon == nil then return 'No weapon '..weapName..' found.' end --for weapons which have no max ammo local typeExceptions = {"Sentinel","Emplacement","Arch-Gun","Gear"} local ammoException = nil if Shared.contains(typeExceptions, Weapon.Type) or Weapon.Class == "Exalted Weapon" then ammoException = true end local function Value(valueName, asString, forTable) if(asString == nil) then asString = false end if(forTable == nil) then forTable = false end return getValue(Weapon, valueName, true, asString, forTable) end local isMelee = p.isMelee(Weapon) == "yes" --mw.log(isMelee) local chargedExceptions = {"Tiberon Prime", "Kohm", "Kohmak", "Twin Kohmak", "Stug"} -- weapons which have a charged attack but normal attack values are used for the tooltip local secondaryExceptions = {"Penta", "Carmine Penta", "Secura Penta"} local areaExceptions = {"Ogris", "Zarr", "Tonkor", "Kulstar", "Angstrum", "Prisma Angstrum"} local secondaryAreaExceptions ={"Lenz"} if isMelee ~= true then if Shared.contains(chargedExceptions, weapName) ~= true and Value({"Charge","AttackName"}) ~= nil then hasCharged = true attackType = 'Charge' end if Shared.contains(secondaryExceptions, weapName) then attackType = 'Secondary' elseif Shared.contains(areaExceptions, weapName) then attackType = 'Area' elseif Shared.contains(secondaryAreaExceptions, weapName) then attackType = 'SecondaryArea' end end --mw.log(hasCharged) --mw.log(attackType) attack = getAttack(Weapon, attackType) local count = 0 for type, dmg in Shared.skpairs(attack.Damage) do if count == 0 then attackText = '\n| style=\"padding-right:2px;\" |'..Icon._Proc(type,'','white')..space..dmg count = count + 1 else attackText = attackText..'|| style=\"padding-right:4px;\" |'..Icon._Proc(type,'','white')..space..dmg end end if(hasMultipleTypes(attack)) then attackBiasText = '\n| colspan=4 |'..GetDamageString(attack, nil).." ("..GetDamageBiasString(attack,nil,'',nil,'white')..")" end if isMelee == true then A2Name = 'Type' A2Value = 'Class' C1Name = 'Atk. Speed' C1Value = 'FireRate' C1Toggle = true C2Name = 'Block Resist.' C2Value = 'BlockResist' else A2Name = 'Trigger' A2Value = 'Trigger' C2Name = 'Noise' C2Value = 'NoiseLevel' if hasCharged == true then C1Name = 'Charge Time' if weapName == "Staticor" then C1Value = {'Area','ChargeTime'} else C1Value = {'Charge','ChargeTime'} end C1Toggle = true else C1Name = 'Fire Rate' C1Value = 'FireRate' end end local function Link(linkName) local spanStart = '<span class=\"LinkText\">' local spanEnd = '</span>' return spanStart..linkName..spanEnd end local zeroPadding = '\n| style=\"padding:0px;\" |' local newRow = '\n|-' local spacer = '\n| class=\"Spacer\" |' local halfTable = '\n| class=\"TableHalf\" |' local dataText = '\n{| class=\"Data\" style=\"font-size:12px;\"' local dataTextCenter = '\n{| class=\"Data\" style=\"font-size:12px; text-align:center;\"' local tableEnd = '\n|}' local image = '\n| class=\"Image\" style=\"height:120px;\" | [[File:'..Value("Image")..'|160px]]' if Title then titleText = newRow..'\n! class=\"Title\"|'..Value("Name")..newRow..spacer end --creating the table local result = '{| class=\"Sub\"'..newRow..image..newRow..spacer..newRow..zeroPadding result = result..dataText..newRow result = result..halfTable..Link("Slot")..space..Value("Type")..halfTable..Link(A2Name)..space..Value(A2Value)..tableEnd result = result..newRow..spacer..titleText..newRow..zeroPadding result = result..dataTextCenter..newRow..attackText if(attackBiasText ~= '') then result = result..newRow..attackBiasText end result = result..tableEnd result = result..newRow..spacer..newRow..zeroPadding..dataText..newRow..halfTable..Link("Crit")..space..Value("CritChance",true)..' | '..Value("CritMultiplier",true)..halfTable..Link("Status")..space..Value("StatusChance",true) result = result..newRow..halfTable..Link(C1Name)..space..Value(C1Value,C1Toggle)..halfTable..Link(C2Name)..space..Value(C2Value) --if not melee and not fishing spear => reload and ammo stats if not isMelee and Weapon.Type ~= "Gear" then result = result..newRow..halfTable..Link("Reload")..space..Value("Reload", true, true)..halfTable..Link("Ammo")..space..Value("Magazine") --if has max ammo => add max ammo stat if ammoException == nil then result = result..'/'..Value("MaxAmmo") end end result = result..tableEnd..tableEnd return result end function p.test(WeapName) local Weapon = p.getWeapon(WeapName) return BuildGunComparisonDisplay(Weapon) end return p