|
|
(7 intermediate revisions by one other user not shown) |
Line 1: |
Line 1: |
| --Module that constructs tables for all things that can affect Player Modifiers
| |
| --This includes Agility, Equipment, Pets, Prayers, and Constellations right now
| |
|
| |
|
| local p = {}
| |
|
| |
| local Constants = require('Module:Constants')
| |
| local Shared = require('Module:Shared')
| |
| local Pets = require('Module:Pets')
| |
| local Items = require('Module:Items')
| |
| local Skills = require('Module:Skills')
| |
| local Agility = require('Module:Skills/Agility')
| |
| local Prayer = require('Module:Prayer')
| |
| local Shop = require('Module:Shop')
| |
| local Icons = require('Module:Icons')
| |
| local GameData = require('Module:GameData')
| |
| local Township = require('Module:GauTest/Township')
| |
|
| |
| --First up, functions to get all the things in a category that have a given modifier:
| |
| function p.getModifierValue(modifiers, modifier, skill, getOpposites)
| |
| --Sometimes nil modifier sets will get here, which is fine. Just return 0 immediately
| |
| if modifiers == nil then
| |
| return 0
| |
| end
| |
|
| |
| --Make sure we have the skillID and not the name
| |
| if skill ~= nil then
| |
| if skill == '' then
| |
| skill = nil
| |
| elseif Constants.getSkillID(skill) ~= nil then
| |
| -- skill is a skill name
| |
| skill = Constants.getSkillID(skill)
| |
| elseif Constants.getSkillName(skill) == nil then
| |
| -- skill is neither a skill name or ID
| |
| return 0
| |
| end
| |
| end
| |
|
| |
| --By default, attempt to add the increased and decreased prefixes to the modifier
| |
| --But if getOpposites is false, only look for an exact match
| |
|
| |
| local mods = {}
| |
| if getOpposites == nil or getOpposites then
| |
| mods.inc = 'increased'..modifier
| |
| mods.dec = 'decreased'..modifier
| |
| else
| |
| mods.inc = modifier
| |
| end
| |
|
| |
| local magnitude = { inc = 0, dec = 0 }
| |
| for modType, modName in pairs(mods) do
| |
| if modifiers[modName] ~= nil then
| |
| local valueArray = nil
| |
| if type(modifiers[modName]) ~= 'table' then
| |
| valueArray = {modifiers[modName]}
| |
| else
| |
| valueArray = modifiers[modName]
| |
| end
| |
|
| |
| for i, subVal in ipairs(valueArray) do
| |
| if type(subVal) == 'table' then
| |
| if subVal.skillID ~= nil then
| |
| -- Modifier value is skill specific
| |
| if skill == nil or skill == '' or subVal.skillID == skill then
| |
| magnitude[modType] = magnitude[modType] + subVal.value
| |
| end
| |
| else
| |
| -- Modifier value is a table of two numbers representing a range. Take the largest value
| |
| magnitude[modType] = magnitude[modType] + (subVal[2] or 0)
| |
| end
| |
| else
| |
| magnitude[modType] = magnitude[modType] + subVal
| |
| end
| |
| end
| |
| end
| |
| end
| |
|
| |
| return magnitude.inc - magnitude.dec
| |
| end
| |
|
| |
| function p.getItemsWithModifier(modifiers, skill, getOpposites)
| |
| if type(modifiers) == 'string' then
| |
| modifiers = {modifiers}
| |
| end
| |
| local itemList = Items.getItems(
| |
| function(item)
| |
| if item.golbinRaidExclusive ~= nil and item.golbinRaidExclusive then
| |
| return false
| |
| elseif item.modifiers == nil or Shared.tableIsEmpty(item.modifiers) then
| |
| return false
| |
| end
| |
| for i, mod in ipairs(modifiers) do
| |
| if p.getModifierValue(item.modifiers, mod, skill, getOpposites) ~= 0 then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end)
| |
| return itemList
| |
| end
| |
|
| |
| function p.getObstaclesWithModifier(modifiers, skill, getOpposites)
| |
| if type(modifiers) == 'string' then
| |
| modifiers = {modifiers}
| |
| end
| |
| local obstList = Agility.getObstacles(
| |
| function(obst)
| |
| for i, mod in ipairs(modifiers) do
| |
| if p.getModifierValue(obst.modifiers, mod, skill, getOpposites) ~= 0 then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end)
| |
| return obstList
| |
| end
| |
|
| |
| function p.getConstellationsWithModifier(modifiers, skill, getOpposites)
| |
| if type(modifiers) == 'string' then
| |
| modifiers = {modifiers}
| |
| end
| |
| local consList = Skills.getConstellations(
| |
| function(cons)
| |
| local consMods = Skills._buildAstrologyModifierArray(cons, 1, true, true, true, true)
| |
| for i, modifier in ipairs(modifiers) do
| |
| if p.getModifierValue(consMods, modifier, skill, getOpposites) ~= 0 then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end)
| |
| return consList
| |
| end
| |
|
| |
| function p.getPillarsWithModifier(modifiers, skill, getOpposites)
| |
| if type(modifiers) == 'string' then
| |
| modifiers = {modifiers}
| |
| end
| |
| local pillarList = Agility.getPillars(
| |
| function(pillar)
| |
| for i, mod in ipairs(modifiers) do
| |
| if p.getModifierValue(pillar.modifiers, mod, skill, getOpposites) ~= 0 then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end)
| |
| return pillarList
| |
| end
| |
|
| |
| function p.getPetsWithModifier(modifiers, skill, getOpposites)
| |
| if type(modifiers) == 'string' then
| |
| modifiers = {modifiers}
| |
| end
| |
| local petList = Pets.getPets(
| |
| function(pet)
| |
| for i, mod in ipairs(modifiers) do
| |
| if p.getModifierValue(pet.modifiers, mod, skill, getOpposites) ~= 0 then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end)
| |
| return petList
| |
| end
| |
|
| |
| function p.getPrayersWithModifier(modifiers, skill, getOpposites)
| |
| if type(modifiers) == 'string' then
| |
| modifiers = {modifiers}
| |
| end
| |
| local prayerList = Prayer.getPrayers(
| |
| function(prayer)
| |
| for i, mod in ipairs(modifiers) do
| |
| if p.getModifierValue(prayer.modifiers, mod, skill, getOpposites) ~= 0 then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end)
| |
| return prayerList
| |
| end
| |
|
| |
| function p.getUpgradesWithModifier(modifiers, skill, getOpposites)
| |
| if type(modifiers) == 'string' then
| |
| modifiers = {modifiers}
| |
| end
| |
| local upgradeList = Shop.getPurchases(
| |
| function(purchase)
| |
| if purchase.category == 'melvorD:GolbinRaid' then
| |
| return false
| |
| end
| |
| for i, mod in ipairs(modifiers) do
| |
| if p.getModifierValue(purchase.contains.modifiers, mod, skill, getOpposites) ~= 0 then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end)
| |
| return upgradeList
| |
| end
| |
|
| |
| function p.getTownshipBuildingsWithModifier(modifiers, skill, getOpposites)
| |
| if type(modifiers) == 'string' then
| |
| modifiers = {modifiers}
| |
| end
| |
| local buildingList = GameData.getEntities(GameData.skillData.Township.buildings,
| |
| function(building)
| |
| for i, mod in ipairs(modifiers) do
| |
| if p.getModifierValue(building.modifiers, mod, skill, getOpposites) ~= 0 then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end
| |
| )
| |
| return buildingList
| |
| end
| |
|
| |
| function p.getTownshipWorshipsWithModifier(modifiers, skill, getOpposites)
| |
| if type(modifiers) == 'string' then
| |
| modifiers = {modifiers}
| |
| end
| |
| local worshipList = GameData.getEntities(Township.GetSplitWorship(),
| |
| function(worship)
| |
| for i, mod in ipairs(modifiers) do
| |
| if p.getModifierValue(worship.modifiers, mod, skill, getOpposites) ~= 0 then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end
| |
| )
| |
| return worshipList
| |
| end
| |
|
| |
|
| |
| function p._getModifierTable(modifiers, skill, columnName, getOpposites, displayOtherMods, maxOtherMods, townshipBuildingName)
| |
| local modifierNames = {}
| |
| if type(modifiers) == 'string' then
| |
| modifiers = {modifiers}
| |
| end
| |
| for i, modifier in pairs(modifiers) do
| |
| if getOpposites then
| |
| table.insert(modifierNames, 'increased'..modifier)
| |
| table.insert(modifierNames, 'decreased'..modifier)
| |
| else
| |
| table.insert(modifierNames, modifier)
| |
| end
| |
| end
| |
|
| |
| local hasOtherModifiers = false
| |
| local modifierCount = Shared.tableCount(modifiers)
| |
|
| |
| if skill ~= nil then
| |
| if skill == '' then
| |
| skill = nil
| |
| elseif Constants.getSkillID(skill) ~= nil then
| |
| -- skill is a skill name
| |
| skill = Constants.getSkillID(skill)
| |
| elseif Constants.getSkillName(skill) == nil then
| |
| -- skill is neither a skill name or ID
| |
| return 'ERROR: Failed to find a skill ID for ' .. skill .. '[[Category:Pages with script errors]]'
| |
| end
| |
| end
| |
|
| |
| local getModText =
| |
| function(modifiers)
| |
| local modTextArray = { ["visible"] = {}, ["overflow"] = {} }
| |
| local otherModCount = 0
| |
| local mainModText = {}
| |
| for modName, modValue in Shared.skpairs(modifiers) do
| |
| local includedMod = Shared.contains(modifierNames, modName)
| |
| local valueArray = nil
| |
| if type(modValue) ~= 'table' then
| |
| valueArray = {modValue}
| |
| else
| |
| valueArray = modValue
| |
| end
| |
|
| |
| for j, subVal in ipairs(valueArray) do
| |
| local includeInMainText = includedMod
| |
| if type(subVal) == 'table' and subVal.skillID ~= nil then
| |
| -- Modifier value is skill specific
| |
| if includeInMainText then
| |
| -- If the skill doesn't match then don't include in the main text
| |
| includeInMainText = skill == nil or skill == '' or subVal.skillID == skill
| |
| end
| |
| subVal = {subVal}
| |
| end
| |
|
| |
| if includeInMainText then
| |
| table.insert(mainModText, Constants._getModifierText(modName, subVal))
| |
| else
| |
| otherModCount = otherModCount + 1
| |
| local key = ((maxOtherMods == nil or otherModCount <= maxOtherMods) and 'visible') or 'overflow'
| |
| table.insert(modTextArray[key], Constants._getModifierText(modName, subVal))
| |
| end
| |
| end
| |
| end
| |
|
| |
| local overflowModCount = Shared.tableCount(modTextArray['overflow'])
| |
| if overflowModCount == 1 then
| |
| table.insert(modTextArray['visible'], modTextArray['overflow'][1])
| |
| end
| |
| local otherModText = {table.concat(modTextArray['visible'], '<br/>')}
| |
|
| |
| if overflowModCount > 1 then
| |
| -- Number of other modifiers for the object exceed the specified maximum
| |
| table.insert(otherModText, '<br/><span class="mw-collapsible mw-collapsed" ')
| |
| table.insert(otherModText, 'data-expandtext="Show ' .. Shared.formatnum(overflowModCount) .. ' more modifiers", data-collapsetext="Hide">')
| |
| table.insert(otherModText, table.concat(modTextArray['overflow'], '<br/>') .. '</span>')
| |
| end
| |
| return table.concat(mainModText, '<br/>'), table.concat(otherModText)
| |
| end
| |
|
| |
| local tableArray = {}
| |
| --Going through each type of thing to add to the array
| |
| local itemList = p.getItemsWithModifier(modifiers, skill, getOpposites)
| |
| for i, item in ipairs(itemList) do
| |
| local row = {}
| |
| row.name = item.name
| |
| row.icon = Icons.Icon({item.name, type='item'})
| |
| row.type = 'Item'
| |
| --For equipment, show the slot they go in
| |
| if item.validSlots ~= nil then
| |
| row.type = row.type..' ('..table.concat(Shared.clone(item.validSlots), ', ')..')'
| |
| end
| |
| local totalVal = 0
| |
| for i, mod in pairs(modifiers) do
| |
| totalVal = totalVal + p.getModifierValue(item.modifiers, mod, skill, getOpposites)
| |
| end
| |
| row.val = totalVal
| |
|
| |
| row.modifierText, row.otherModifiers = getModText(item.modifiers)
| |
|
| |
| if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
| |
| hasOtherModifiers = true
| |
| end
| |
|
| |
| table.insert(tableArray, row)
| |
| end
| |
|
| |
| local petList = p.getPetsWithModifier(modifiers, skill, getOpposites)
| |
| for i, pet in Shared.skpairs(petList) do
| |
| local row = {}
| |
| row.name = pet.name
| |
| row.icon = Icons.Icon({pet.name, type='pet'})
| |
| row.type = '[[Pets|Pet]]'
| |
| local totalVal = 0
| |
| for i, mod in pairs(modifiers) do
| |
| totalVal = totalVal + p.getModifierValue(pet.modifiers, mod, skill, getOpposites)
| |
| end
| |
| row.val = totalVal
| |
|
| |
| row.modifierText, row.otherModifiers = getModText(pet.modifiers)
| |
|
| |
| if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
| |
| hasOtherModifiers = true
| |
| end
| |
|
| |
| table.insert(tableArray, row)
| |
| end
| |
|
| |
| local obstList = p.getObstaclesWithModifier(modifiers, skill, getOpposites)
| |
| for i, obst in Shared.skpairs(obstList) do
| |
| local row = {}
| |
| row.name = obst.name
| |
| row.icon = Icons.Icon({'Agility', obst.name, type='skill'})
| |
| row.type = '[[Agility#Obstacles|Agility Obstacle '..tostring(tonumber(obst.category)+1)..']]'
| |
| local totalVal = 0
| |
| for i, mod in pairs(modifiers) do
| |
| totalVal = totalVal + p.getModifierValue(obst.modifiers, mod, skill, getOpposites)
| |
| end
| |
| row.val = totalVal
| |
|
| |
| row.modifierText, row.otherModifiers = getModText(obst.modifiers)
| |
|
| |
| if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
| |
| hasOtherModifiers = true
| |
| end
| |
|
| |
| table.insert(tableArray, row)
| |
| end
| |
|
| |
| local pillarList = p.getPillarsWithModifier(modifiers, skill, getOpposites)
| |
| for i, pillar in ipairs(pillarList) do
| |
| local row = {}
| |
| row.name = pillar.name
| |
| row.icon = Icons.Icon({'Agility', pillar.name, type='skill'})
| |
| row.type = '[[Agility#Passive Pillars|Agility Pillar]]'
| |
| local totalVal = 0
| |
| for i, mod in pairs(modifiers) do
| |
| totalVal = totalVal + p.getModifierValue(pillar.modifiers, mod, skill, getOpposites)
| |
| end
| |
| row.val = totalVal
| |
|
| |
| row.modifierText, row.otherModifiers = getModText(pillar.modifiers)
| |
|
| |
| if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
| |
| hasOtherModifiers = true
| |
| end
| |
|
| |
| table.insert(tableArray, row)
| |
| end
| |
|
| |
| local prayerList = p.getPrayersWithModifier(modifiers, skill, getOpposites)
| |
| for i, prayer in ipairs(prayerList) do
| |
| local row = {}
| |
| row.name = prayer.name
| |
| row.icon = Icons.Icon({prayer.name, type='prayer'})
| |
| row.type = [[Prayer]]
| |
| local totalVal = 0
| |
| for i, mod in ipairs(modifiers) do
| |
| totalVal = totalVal + p.getModifierValue(prayer.modifiers, mod, skill, getOpposites)
| |
| end
| |
| row.val = totalVal
| |
|
| |
| row.modifierText, row.otherModifiers = getModText(prayer.modifiers)
| |
|
| |
| if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
| |
| hasOtherModifiers = true
| |
| end
| |
|
| |
| table.insert(tableArray, row)
| |
| end
| |
|
| |
| local upgradeList = p.getUpgradesWithModifier(modifiers, skill, getOpposites)
| |
| for i, upgrade in ipairs(upgradeList) do
| |
| local row = {}
| |
| row.name = Shop._getPurchaseName(upgrade)
| |
| row.icon = Icons.Icon({row.name, type='upgrade'})
| |
| row.type = '[[Shop|Upgrade]]'
| |
| local totalVal = 0
| |
| for i, mod in pairs(modifiers) do
| |
| totalVal = totalVal + p.getModifierValue(upgrade.contains.modifiers, mod, skill, getOpposites)
| |
| end
| |
| row.val = totalVal
| |
|
| |
| row.modifierText, row.otherModifiers = getModText(upgrade.contains.modifiers)
| |
|
| |
| if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
| |
| hasOtherModifiers = true
| |
| end
| |
|
| |
| table.insert(tableArray, row)
| |
| end
| |
|
| |
| local constellationList = p.getConstellationsWithModifier(modifiers, skill, getOpposites)
| |
| for i, cons in ipairs(constellationList) do
| |
| local row = {}
| |
| row.name = cons.name
| |
| row.icon = Icons.Icon({cons.name, type='constellation'})
| |
| row.type = '[[Astrology#Constellations|Constellation]]'
| |
| row.val = 15 -- Assume highest possible, the range is 1 to 15 inclusive
| |
|
| |
| local modList = Skills._buildAstrologyModifierArray(cons, nil, true, true, true, true)
| |
| row.modifierText, row.otherModifiers = getModText(modList)
| |
|
| |
| if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
| |
| hasOtherModifiers = true
| |
| end
| |
|
| |
| table.insert(tableArray, row)
| |
| end
| |
|
| |
| -- Special biomeModifiers for Township buildings
| |
| if townshipBuildingName ~= nil then
| |
| local building = Township._GetBuildingByName(townshipBuildingName)
| |
| for _, biome in ipairs(building.biomeModifiers) do
| |
| local biomename = GameData.getEntityByID(GameData.skillData.Township.biomes, biome.biomeID).name
| |
| local row = {}
| |
| row.name = GameData.getEntityByID(GameData.skillData.Township.biomes, biome.biomeID).name
| |
| row.icon = Icons.Icon({row.name, link='Biome', img='Township', type='skill'})
| |
| row.type = 'Biome'
| |
| row.val = biome.value
| |
| local color = biome.value < 0 and 'red' or 'green'
| |
| row.modifierText = '<span style="color:'..color..'">'..Shared.numStrWithSign(biome.value)..'% Production for this Building</span>'
| |
| row.otherModifiers = ''
| |
|
| |
| if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
| |
| hasOtherModifiers = true
| |
| end
| |
|
| |
| table.insert(tableArray, row)
| |
| end
| |
| end
| |
|
| |
| local buildingList = p.getTownshipBuildingsWithModifier(modifiers, skill, getOpposites)
| |
| for i, building in ipairs(buildingList) do
| |
| local row = {}
| |
| row.name = building.name
| |
| row.icon = Icons.Icon({building.name, type='building'})
| |
| row.type = 'Building'
| |
|
| |
| local totalVal = 0
| |
| for i, mod in pairs(modifiers) do
| |
| totalVal = totalVal + p.getModifierValue(building.modifiers, mod, skill, getOpposites)
| |
| end
| |
| row.val = totalVal
| |
|
| |
| row.modifierText, row.otherModifiers = getModText(building.modifiers)
| |
|
| |
| if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
| |
| hasOtherModifiers = true
| |
| end
| |
|
| |
| table.insert(tableArray, row)
| |
| end
| |
|
| |
| local worshipList = p.getTownshipWorshipsWithModifier(modifiers, skill, getOpposites)
| |
| for i, worship in ipairs(worshipList) do
| |
| local row = {}
| |
| row.name = worship.namePercent
| |
| row.icon = Icons.Icon({worship.namePercent , img=worship.statueName, link=worship.name, type='building'})
| |
| row.type = 'Worship'
| |
|
| |
| local totalVal = 0
| |
| for i, mod in pairs(modifiers) do
| |
| totalVal = totalVal + p.getModifierValue(worship.modifiers, mod, skill, getOpposites)
| |
| end
| |
| row.val = totalVal
| |
|
| |
| row.modifierText, row.otherModifiers = getModText(worship.modifiers)
| |
|
| |
| if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
| |
| hasOtherModifiers = true
| |
| end
| |
|
| |
| table.insert(tableArray, row)
| |
| end
| |
|
| |
| local result = '{| class="wikitable sortable stickyHeader"'
| |
| result = result..'\r\n|- class="headerRow-0"'
| |
| result = result..'\r\n!Source!!Type!!'..columnName
| |
| if hasOtherModifiers and displayOtherMods then result = result..'!!Other Modifiers' end
| |
|
| |
| --Sort by value if only one modifier was passed in
| |
| --Otherwise sort alphabetically by type, then name
| |
| table.sort(tableArray, function(a, b)
| |
| if modifierCount == 1 and a.val ~= b.val then
| |
| return a.val > b.val
| |
| elseif a.type ~= b.type then
| |
| return a.type < b.type
| |
| else
| |
| return a.name < b.name
| |
| end
| |
| end)
| |
| for i, row in ipairs(tableArray) do
| |
| result = result..'\r\n|-'
| |
| result = result..'\r\n|data-sort-value="'..row.name..'"|'..row.icon
| |
| result = result..'||'..row.type..'||data-sort-value="'..row.val..'"| '..row.modifierText
| |
| if hasOtherModifiers and displayOtherMods then
| |
| result = result..'|| '..row.otherModifiers
| |
| end
| |
| end
| |
|
| |
| result = result..'\r\n|}'
| |
| return result
| |
| end
| |
|
| |
| function p.getModifierTable(frame)
| |
| local modifier = frame.args ~= nil and frame.args[1] or frame[1]
| |
| local skill = frame.args ~= nil and frame.args.skill or frame.skill
| |
| local columnName = frame.args ~= nil and frame.args[2] or frame[2]
| |
| local getOpposites = frame.args ~= nil and frame.args[3] or frame[3]
| |
| local displayOtherMods = frame.args ~= nil and frame.args.displayOtherMods or frame.displayOtherMods
| |
| local maxOtherMods = frame.args ~= nil and tonumber(frame.args.maxOtherMods) or 5
| |
| local townshipBuildingName = frame.args ~= nil and frame.args.townshipBuildingName or frame.townshipBuildingName
| |
|
| |
|
| |
| if Shared.contains(modifier, ',') then
| |
| modifier = Shared.splitString(modifier, ',')
| |
| end
| |
|
| |
| if getOpposites ~= nil then
| |
| getOpposites = string.upper(getOpposites) ~= 'FALSE'
| |
| else
| |
| getOpposites = true
| |
| end
| |
|
| |
| if displayOtherMods ~= nil then
| |
| displayOtherMods = string.upper(displayOtherMods) ~= 'FALSE'
| |
| else
| |
| displayOtherMods = true
| |
| end
| |
|
| |
| return p._getModifierTable(modifier, skill, columnName, getOpposites, displayOtherMods, maxOtherMods, townshipBuildingName)
| |
| end
| |
|
| |
| -- Automatically generates the list of modifiers for the target entity
| |
| function p.getTownshipModifierTable(frame)
| |
| local name = frame.args ~= nil and frame.args[1] or frame[1]
| |
| local type = frame.args ~= nil and frame.args.type or frame.type
| |
|
| |
| local modifier = Township.GetModifiers(name, type)
| |
|
| |
| if frame.args == nil then
| |
| frame[1] = modifier
| |
| else
| |
| frame.args[1] = modifier
| |
| end
| |
|
| |
| if type == 'building' then
| |
| if frame.args == nil then
| |
| frame.townshipBuildingName = name
| |
| else
| |
| frame.args.townshipBuildingName = name
| |
| end
| |
| end
| |
|
| |
| return p.getModifierTable(frame)
| |
| end
| |
|
| |
|
| |
| return p
| |