Module:GauTest/Township: Difference between revisions

no edit summary
No edit summary
No edit summary
 
(44 intermediate revisions by the same user not shown)
Line 3: Line 3:
local GameData = require('Module:GameData')
local GameData = require('Module:GameData')
local Constants = require('Module:Constants')
local Constants = require('Module:Constants')


local p = {}
local p = {}
Line 10: Line 9:
p.Township = Township
p.Township = Township


-- Returns the namespace name (eventually we should use an icon)
function p.PLACEHOLDER_NAMESPACE_ICON(namespace)
local namespaces = {
melvorD = 'Demo',
melvorF = 'Full',
melvorTotH = 'TotH'
}
return namespaces[namespace]
end


-- Returns the recipe for the item of a desired skill.
-- Returns the recipe for the item of a desired skill.
Line 79: Line 69:
-- Get a sorted list of all the resources
-- Get a sorted list of all the resources
local resources = GameData.sortByOrderTable(Township.resources, Township.resourceDisplayOrder[1].ids)
local resources = GameData.sortByOrderTable(Township.resources, Township.resourceDisplayOrder)
resources = Shared.clone(resources)
resources = Shared.clone(resources)
return resources
return resources
end
-- Returns a sorted list of all Township buildings
function p._SortedBuildings()
return GameData.sortByOrderTable(Township.buildings, Township.buildingDisplayOrder)
end
end


Line 123: Line 118:
end
end
local function matchClothing(item)
local function matchClothing(item)
local valid_tiers = {'Leather', 'Hard Leather', 'Dragonhide', 'Elderwood', 'Revenant', 'Carrion'}
return item.id == 'melvorD:Green_Dragonhide' or item.id == 'melvorD:Blue_Dragonhide' or item.id == 'melvorD:Red_Dragonhide' or item.id == 'melvorD:Black_Dragonhide' or item.id == 'melvorF:Elder_Dragonhide'
for _, tier in ipairs(valid_tiers) do
if item.tier == tier then
return true
end
end
return false
end
end


Line 158: Line 147:
for _, item in ipairs(resource.itemConversions) do
for _, item in ipairs(resource.itemConversions) do
item.toTownship = math.max(math.floor(1000/(item.healsFor*10)), 2)
item.toTownship = math.max(math.floor(1000/(item.healsFor*10)), 2)
item.fromTownship = item.healsFor*5*6
item.fromTownship = item.healsFor*5*6*5
end
end
elseif resource.id == 'melvorF:Planks' then
elseif resource.id == 'melvorF:Planks' then
Line 202: Line 191:
table.insert(ret_resource, '\r\n!Item')
table.insert(ret_resource, '\r\n!Item')
table.insert(ret_resource, '\r\n!Name')
table.insert(ret_resource, '\r\n!Name')
table.insert(ret_resource, '\r\n!DLC')
table.insert(ret_resource, '\r\n!Level')
table.insert(ret_resource, '\r\n!Level')
table.insert(ret_resource, '\r\n!Give To')
table.insert(ret_resource, '\r\n!Give To')
Line 246: Line 234:
table.insert(ret_resource, '\r\n|style="text-align:center"|'..Icons.Icon({item.name, type='item', size='50', notext=true}))
table.insert(ret_resource, '\r\n|style="text-align:center"|'..Icons.Icon({item.name, type='item', size='50', notext=true}))
-- Name
-- Name
table.insert(ret_resource, '\r\n|style="text-align:left"|'..Icons.Icon({item.name, type='item', noicon=true}))
table.insert(ret_resource, '\r\n|style="text-align:left"|'..Icons.getExpansionIcon(item.id)..Icons.Icon({item.name, type='item', noicon=true}))
-- DLC
local item_namespace, item_localid = GameData.getLocalID(item.id)
table.insert(ret_resource, '\r\n|style="text-align:center"|'..p.PLACEHOLDER_NAMESPACE_ICON(item_namespace))
-- Level
-- Level
if required_level == nil then
if required_level == nil then
Line 281: Line 266:
end
end


-- modifiers associated with specific biomes
-- Gets the associated skill of a resource by id
local biome_data = {
local resource_skill = {
['melvorF:Grasslands'] = {modifiers = {'increasedTownshipGrasslandsProduction', 'decreasedTownshipGrasslandsProduction'}},
['melvorF:GP'] = {skill = nil},
['melvorF:Forest'] = {modifiers = {'increasedTownshipForestProduction', 'decreasedTownshipForestProduction'}},
['melvorF:Food'] = {skill = 'melvorD:Cooking'},
['melvorF:Desert'] = {modifiers = {'increasedTownshipDesertProduction', 'decreasedTownshipDesertProduction'}},
['melvorF:Wood'] = {skill = 'melvorD:Woodcutting'},
['melvorF:Water'] = {modifiers = {'increasedTownshipWaterProduction', 'decreasedTownshipWaterProduction'}},
['melvorF:Stone'] = {skill = 'melvorD:Mining'},
['melvorF:Swamp'] = {modifiers = {'increasedTownshipSwampProduction', 'decreasedTownshipSwampProduction'}},
['melvorF:Ore'] = {skill = 'melvorD:Mining'},
['melvorF:Arid_Plains'] = {modifiers = {'increasedTownshipAridPlainsProduction', 'decreasedTownshipAridPlainsProduction'}},
['melvorF:Coal'] = {skill = 'melvorD:Mining'},
['melvorF:Mountains'] = {modifiers = {'increasedTownshipMountainsProduction', 'decreasedTownshipMountainsProduction'}},
['melvorF:Bar'] = {skill = 'melvorD:Smithing'},
['melvorF:Valley'] = {modifiers = {'increasedTownshipValleyProduction', 'decreasedTownshipValleyProduction'}},
['melvorF:Herbs'] = {skill = 'melvorD:Farming'},
['melvorF:Jungle'] = {modifiers = {'increasedTownshipJungleProduction', 'decreasedTownshipJungleProduction'}},
['melvorF:Rune_Essence'] = {skill = 'melvorD:Mining'},
['melvorF:Snowlands'] = {modifiers = {'increasedTownshipSnowlandsProduction', 'decreasedTownshipSnowlandsProduction', 'increasedTownshipCoalUsage', 'decreasedTownshipCoalUsage'}},
['melvorF:Leather'] = {skill = nil},
}
['melvorF:Potions'] = {skill = 'melvorD:Herblore'},
 
['melvorF:Planks'] = {skill = 'melvorD:Woodcutting'},
-- modifiers associated with specific buildings or resources
['melvorF:Clothing'] = {skill = nil}
local unique_modifiers = {
['melvorF:Fishermans_Dock'] = {modifiers = {'increasedTownshipFishingDockProduction', 'decreasedTownshipFishingDockProduction'}},
['melvorF:Fishermans_Pier'] = {modifiers = {'increasedTownshipFishingDockProduction', 'decreasedTownshipFishingDockProduction'}},
['melvorF:Fishermans_Port'] = {modifiers = {'increasedTownshipFishingDockProduction', 'decreasedTownshipFishingDockProduction'}},
['melvorTotH:Fishermans_Estate'] = {modifiers = {'increasedTownshipFishingDockProduction', 'decreasedTownshipFishingDockProduction'}},
['melvorF:Magic_Emporium'] = {modifiers = {'increasedTownshipMagicEmporiumProduction', 'decreasedTownshipMagicEmporiumProduction'}},
['melvorF:Orchard'] = {modifiers = {'increasedTownshipOrchardProduction', 'decreasedTownshipOrchardProduction'}},
['melvorF:Farmland'] = {modifiers = {'increasedTownshipFarmProduction', 'decreasedTownshipFarmProduction'}},
['melvorF:Mill'] = {modifiers = {'increasedTownshipFarmProduction', 'decreasedTownshipFarmProduction'}},
['melvorF:Plantation'] = {modifiers = {'increasedTownshipFarmProduction', 'decreasedTownshipFarmProduction'}},
['melvorTotH:Farming_Estate'] = {modifiers = {'increasedTownshipFarmProduction', 'decreasedTownshipFarmProduction'}},
['melvorF:Woodcutters_Camp'] = {modifiers = {'increasedTownshipWoodcuttingProduction', 'decreasedTownshipWoodcuttingProduction'}},
['melvorF:Logging_Camp'] = {modifiers = {'increasedTownshipWoodcuttingProduction', 'decreasedTownshipWoodcuttingProduction'}},
['melvorF:Forestry_Camp'] = {modifiers = {'increasedTownshipWoodcuttingProduction', 'decreasedTownshipWoodcuttingProduction'}},
['melvorTotH:Forestry_Estate'] = {modifiers = {'increasedTownshipWoodcuttingProduction', 'decreasedTownshipWoodcuttingProduction'}},
['melvorF:Blacksmiths_Smithy'] = {modifiers = {'increasedTownshipBlacksmithProduction', 'decreasedTownshipBlacksmithProduction'}},
['melvorF:Blacksmiths_Forge'] = {modifiers = {'increasedTownshipBlacksmithProduction', 'decreasedTownshipBlacksmithProduction'}},
['melvorF:Blacksmiths_Workshop'] = {modifiers = {'increasedTownshipBlacksmithProduction', 'decreasedTownshipBlacksmithProduction'}},
['melvorTotH:Blacksmiths_Estate'] = {modifiers = {'increasedTownshipBlacksmithProduction', 'decreasedTownshipBlacksmithProduction'}},
['melvorF:Food'] = {modifiers = {'increasedTownshipFoodUsage', 'decreasedTownshipFoodUsage'}},
-- Absolute delta so doesn't apply to buildings
population = {modifiers = {'increasedTownshipPopulationCap', 'decreasedTownshipPopulationCap'}},
}
 
p.stats = {
happiness = {name='Happiness', modifiers = {'increasedTownshipHappiness', 'decreasedTownshipHappiness', 'increasedTownshipBuildingHappinessPenalties', 'decreasedTownshipBuildingHappinessPenalties'}},
education = {name='Education', modifiers = {'increasedTownshipEducation', 'decreasedTownshipEducation'}},
health = {name='Health', modifiers = {'increasedTownshipHealth', 'decreasedTownshipHealth'}},
storage = {name='Storage', modifiers = {'increasedTownshipMaxStorage', 'decreasedTownshipMaxStorage'}},
deadStorage = {name='Dead Storage', modifiers = {'increasedTownshipDeadStorage', 'decreasedTownshipDeadStorage'}},
population = {name='Population', modifiers = {}}, -- see unique_modifiers
}
 
-- Special modifiers
local special_modifiers = {
['all_buildings'] = {modifiers={'increasedTownshipBuildingCost', 'decreasedTownshipBuildingCost'}},
['all_production'] = {modifiers={'increasedTownshipResourceProduction', 'decreasedTownshipResourceProduction'}}, --Includes GP production as well
['unused'] = {modifiers = {'townshipDisableHunting'}},
}
 
-- skill -> The Skill used to produce the Trader's tradeable items
-- modifiers -> For buildings that produce this resource, the modifiers to search for.
local resource_info = {
['melvorF:GP'] = {skill = nil, modifiers={'increasedTownshipGPProduction', 'decreasedTownshipGPProduction', 'increasedTownshipTaxPerCitizen', 'decreasedTownshipTaxPerCitizen'}},
['melvorF:Food'] = {skill = 'melvorD:Cooking', modifiers={'increasedTownshipFoodProduction', 'decreasedTownshipFoodProduction'}},
['melvorF:Wood'] = {skill = 'melvorD:Woodcutting', modifiers={'increasedTownshipWoodProduction', 'decreasedTownshipWoodProduction'}},
['melvorF:Stone'] = {skill = 'melvorD:Mining', modifiers={'increasedTownshipStoneProduction', 'decreasedTownshipStoneProduction'}},
['melvorF:Ore'] = {skill = 'melvorD:Mining', modifiers={'increasedTownshipOreProduction', 'decreasedTownshipOreProduction'}},
['melvorF:Coal'] = {skill = 'melvorD:Mining', modifiers={'increasedTownshipCoalProduction', 'decreasedTownshipCoalProduction', 'TownshipCoalUsage'}},
['melvorF:Bar'] = {skill = 'melvorD:Smithing', modifiers={'increasedTownshipBarProduction', 'decreasedTownshipBarProduction'}},
['melvorF:Herbs'] = {skill = 'melvorD:Farming', modifiers={'increasedTownshipHerbProduction', 'decreasedTownshipHerbProduction'}},
['melvorF:Rune_Essence'] = {skill = 'melvorD:Mining', modifiers={'increasedTownshipRuneEssenceProduction', 'decreasedTownshipRuneEssenceProduction'}},
['melvorF:Leather'] = {skill = nil, modifiers={'increasedTownshipLeatherProduction', 'decreasedTownshipLeatherProduction'}},
['melvorF:Potions'] = {skill = 'melvorD:Herblore', modifiers={'increasedTownshipPotionProduction', 'decreasedTownshipPotionProduction'}},
['melvorF:Planks'] = {skill = 'melvorD:Woodcutting', modifiers={'increasedTownshipPlankProduction', 'decreasedTownshipPlankProduction'}},
['melvorF:Clothing'] = {skill = 'melvorD:Crafting', modifiers={'increasedTownshipClothingProduction', 'decreasedTownshipClothingProduction'}},
}
}
-- Gets a list of target modifiers based on the building name
function p._GetBuildingModifiers(building)
local modifiers = {}
local newModifiers = nil
local function addModifiers(_newModifiers)
if newModifiers ~= nil then
for _, newModifier in pairs(_newModifiers.modifiers) do
table.insert(modifiers, newModifier)
end
end
end
-- Unique ID modifiers
newModifiers = unique_modifiers[building.id]
addModifiers(newModifiers)
-- Building modifiers
newModifiers = special_modifiers.all_buildings
addModifiers(newModifiers)
-- Production modifiers
local anyProduction = false
for _, resource in ipairs(building.provides.resources) do
anyProduction = true
newModifiers = resource_info[resource.id]
addModifiers(newModifiers)
end
if anyProduction == true then
newModifiers = special_modifiers.all_production
addModifiers(newModifiers)
end
-- Benefit modifiers
for statid, stat in pairs(p.stats) do
if building.provides[statid] ~= nil and building.provides[statid] ~= 0 then
addModifiers(stat)
end
end
return modifiers
end
-- Gets a list of target modifiers based on a resource id
function p._GetResourceModifiers(resource_id)
local modifiers = {}
local newModifiers = nil
local function addModifiers(_newModifiers)
if newModifiers ~= nil then
for _, newModifier in pairs(_newModifiers.modifiers) do
table.insert(modifiers, newModifier)
end
end
end
-- Unique ID modifiers
newModifiers = unique_modifiers[resource_id]
addModifiers(newModifiers)
-- Production
newModifiers = special_modifiers.all_production
addModifiers(newModifiers)
-- Resource modifiers
newModifiers = resource_info[resource_id]
addModifiers(newModifiers)
return modifiers
end
-- Gets a list of target modifiers based on a stat id
function p._GetStatModifiers(stat_id)
local modifiers = {}
local newModifiers = nil
local function addModifiers(_newModifiers)
if newModifiers ~= nil then
for _, newModifier in pairs(_newModifiers.modifiers) do
table.insert(modifiers, newModifier)
end
end
end
-- Unique ID modifiers
newModifiers = unique_modifiers[stat_id]
addModifiers(newModifiers)
-- Production
newModifiers = p.stats[stat_id]
addModifiers(newModifiers)
return modifiers
end
-- Gets a list of target modifiers based on a biome id. Does not include buildings' biomeModifiers
function p._GetBiomeModifiers(biome_id)
local modifiers = {}
local newModifiers = nil
local function addModifiers(_newModifiers)
if newModifiers ~= nil then
for _, newModifier in pairs(_newModifiers.modifiers) do
table.insert(modifiers, newModifier)
end
end
end
-- Unique ID modifiers
newModifiers = biome_data[biome_id]
addModifiers(newModifiers)
return modifiers
end
-- Gets the modifiers for the specified entity
function p.GetModifiers(name, type)
if type == 'building' then
return p._GetBuildingModifiers(p._GetBuildingByName(name))
end
if type == 'resource' then
return p._GetResourceModifiers(p._GetResourceByName(name).id)
end
if type == 'stat' then
for key, stat in pairs(p.stats) do
if stat.name == name then
return p._GetStatModifiers(key)
end
end
end
if type == 'biome' then
local biome = GameData.getEntityByName(Township.biomes, name)
return p._GetBiomeModifiers(biome.id)
end
end
function p._GetResourceSkill(id)
function p._GetResourceSkill(id)
return resource_info[id].skill
return resource_skill[id].skill
end
end


-- Gets a Township building by ID, e.g. melvorF:Hunters_Cabin
-- Gets a Township building by ID, e.g. melvorF:Hunters_Cabin
function p._GetBuildingByID(id)
function p._GetBuildingByID(id)
return GameData.getEntityByID(Township.buildings, id)
-- Check for the special statue case
if id == 'melvorF:Statues' then
local building = Shared.clone(GameData.getEntityByID(Township.buildings, id))
building.name = 'Statue of Worship'
return building
else
return GameData.getEntityByID(Township.buildings, id)
end
end
end


-- Gets a Township building by name, e.g. Hunters Cabin
-- Gets a Township building by name, e.g. Hunters Cabin
function p._GetBuildingByName(name)
function p._GetBuildingByName(name)
return GameData.getEntityByName(Township.buildings, name)
-- Check for the special statue case
if name == 'Statues' then
name = 'Statue of Worship'
end
local STATUE_OF = 'Statue of '
if string.sub(name, 1, string.len(STATUE_OF)) == STATUE_OF then
local building = Shared.clone(GameData.getEntityByID(Township.buildings, 'melvorF:Statues'))
building.name = name
return building
else
return GameData.getEntityByName(Township.buildings, name)
end
end
end


Line 582: Line 385:
-- Biomes
-- Biomes
table.insert(ret, '\r\n|-\r\n| <b>Biomes:</b><br><ul>')
table.insert(ret, '\r\n|-\r\n| <b>Biomes:</b>')
for _, biomeid in ipairs(building.biomes) do
for _, biomeid in ipairs(building.biomes) do
local biomename = GameData.getEntityByID(Township.biomes, biomeid).name
local biomename = GameData.getEntityByID(Township.biomes, biomeid).name
Line 593: Line 396:
local color = modifier.value < 0 and 'red' or 'green'
local color = modifier.value < 0 and 'red' or 'green'
local modifier_value = Shared.numStrWithSign(modifier.value)
local modifier_value = Shared.numStrWithSign(modifier.value)
table.insert(ret, '<li style="color:'..color..'"><b>'..biomename..' ('..modifier_value..'%)</b></li>')
table.insert(ret, '<br>'..Icons.Icon({biomename, type='biome', notext=true, nolink=true})..' <span style="color:'..color..'"><b>'..biomename..' ('..modifier_value..'%)</b></span>')
else
else
table.insert(ret, '<li>'..biomename..'</li>')
table.insert(ret, '<br>'..Icons.Icon({biomename, type='biome', notext=true, nolink=true})..' <span>'..biomename..'</span>')
end
end
end
end
Line 645: Line 448:
function p._GetBuildingBenefits(building)
function p._GetBuildingBenefits(building)
local benefits = {}
local benefits = {}
for statid, stat in pairs(p.stats) do
local stats = {
if building.provides[statid] ~= nil and building.provides[statid] ~= 0 then
population = 'Population',
local quantity = building.provides[statid]
happiness = 'Happiness',
education = 'Education',
storage = 'Storage',
deadStorage = 'Dead Storage',
worship = 'Worship'
}
for key, stat in pairs(stats) do
if building.provides[key] ~= nil and building.provides[key] ~= 0 then
local quantity = building.provides[key]
if quantity < 0 then
if quantity < 0 then
quantity = '<span style="color:red">'..quantity..'</span>'
quantity = '<span style="color:red">'..quantity..'</span>'
Line 653: Line 464:
quantity = Shared.numStrWithSign(quantity)
quantity = Shared.numStrWithSign(quantity)
end
end
table.insert(benefits, Icons.Icon({stat.name, type='township', notext=true})..'&nbsp;'..quantity)
table.insert(benefits, Icons.Icon({stat, type='township', notext=true})..'&nbsp;'..quantity)
end
end
end
end
Line 696: Line 507:
function p._GetResourceByID(id)
function p._GetResourceByID(id)
return GameData.getEntityByID(p.resources, id)
return GameData.getEntityByID(p.resources, id)
end
-- Gets a resource from name
function p._GetResourceByName(name)
return GameData.getEntityByName(p.resources, name)
end
end


-- Gets text for only the biomes that have a modifier for a building
-- Gets text for only the biomes that have a modifier for a building
function p._GetBuildingBiomeModifiers(building)
function p._GetBiomeModifiers(building)
local biomeRet = {}
local biomeRet = {}
for _, biome in ipairs(building.biomeModifiers) do
for _, biome in ipairs(building.biomeModifiers) do
Line 710: Line 516:
local color = biome.value < 0 and 'red' or 'green'
local color = biome.value < 0 and 'red' or 'green'
local biome_value = Shared.numStrWithSign(biome.value)
local biome_value = Shared.numStrWithSign(biome.value)
table.insert(biomeRet, '<li style="color:'..color..'">'..biomename..' ('..biome_value..'%)</li>')
table.insert(biomeRet, Icons.Icon({biomename, type='biome', notext=true, nolink=true})..' <span style="color:'..color..'">'..biomename..' ('..biome_value..'%)</span>')
end
end
if #biomeRet == 0 then
if #biomeRet == 0 then
return nil
return nil
end
end
return '<ul>'..table.concat(biomeRet)..'</ul>'
return table.concat(biomeRet, '<br>')
end
end


Line 793: Line 599:
BuildOptionalRow('\r\n|-\r\n! Benefits\r\n|', p._GetBuildingBenefits)
BuildOptionalRow('\r\n|-\r\n! Benefits\r\n|', p._GetBuildingBenefits)
BuildOptionalRow('\r\n|-\r\n! Base Production per '..Icons.Icon({'Workers', type='township', notext=true})..'\r\n|', p._GetBuildingBaseProduction)
BuildOptionalRow('\r\n|-\r\n! Base Production per '..Icons.Icon({'Workers', type='township', notext=true})..'\r\n|', p._GetBuildingBaseProduction)
BuildOptionalRow('\r\n|-\r\n! Biome Production Modifiers\r\n|', p._GetBuildingBiomeModifiers)
BuildOptionalRow('\r\n|-\r\n! Biome Production Modifiers\r\n|', p._GetBiomeModifiers)


-- End
-- End
Line 846: Line 652:
end
end


-- Splits each worship formatted each tier separately to check modifiers more easily
-- Generates a table showing which buildings can be built in which biomes
function p.GetSplitWorship()
-- Skips upgraded buildings
local out = {}
function p.GetBuildingBiomeTable()
for _, _worship in ipairs(Township.worships) do
-- Setup the table
local worship = Shared.clone(_worship)
local ret = {}
worship.namePercent = worship.name..' (0%)'
table.insert(ret, '\r\n{| class="wikitable sortable" style="text-align:center"')
table.insert(out, worship)
table.insert(ret, '\r\n!Building')
for i, checkpoint in ipairs(worship.checkpoints) do
worship = Shared.clone(_worship)
-- Make a biomeModifiers table that will keep track of the bonus of each building
worship.namePercent = worship.name..' ('..Township.worshipCheckpoints[i]..'%)'
-- At the same time, make the output table header
worship.modifiers = checkpoint
local biomeModifiersMaster = {}
table.insert(out, worship)
for _, biome in ipairs(Township.biomes) do
table.insert(ret, '\r\n!'..Icons.Icon({biome.name, type='biome', notext=true, nolink=true})..'<br>'..biome.name)
biomeModifiersMaster[biome.id] = false
end
for _, _building in ipairs(p._SortedBuildings()) do
-- Fix melvorF:Statues
local building = p._GetBuildingByID(_building.id)
-- Skip upgraded buildings
local downgrade = p._GetBuildingDowngrade(building)
if downgrade == nil then
-- Let's populate the biome habitability data
local biomeModifiers = Shared.clone(biomeModifiersMaster)
-- Set all valid biomes to 0
for _, biomeid in ipairs(building.biomes) do
biomeModifiers[biomeid] = 0
end
-- Then add the biome modifier values
for _, biomeModifier in ipairs(building.biomeModifiers) do
biomeModifiers[biomeModifier.biomeID] = biomeModifier.value
end
-- Let's build the row
table.insert(ret, '\r\n|-')
table.insert(ret, '\r\n!data-sort-value="'..building.name..'" style="text-align:left"|'..Icons.Icon({building.name, type='building'}))
for _, biome in ipairs(Township.biomes) do
local modifier = biomeModifiers[biome.id]
if modifier then
if modifier == 0 then
-- Buildable but no bonuses
table.insert(ret, '\r\n|class="table-na"|+0%')
else
-- Bonus or penalty
local class = modifier < 0 and 'table-negative' or 'table-positive'
local modifier_value = Shared.numStrWithSign(modifier)
table.insert(ret, '\r\n|class="'..class..'"|<b>'..modifier_value..'%</b>')
end
else
-- Invalid biome
table.insert(ret, '\r\n|style="border:0px"|')
end
end
end
end
table.insert(ret, '\r\n|}')
return table.concat(ret)
end
 
 
-- Generates a table showing all the maps and the number of biomes
-- Skips upgraded buildings
function p.GetMapTable()
-- Setup the table
local ret = {}
table.insert(ret, '\r\n{| class="wikitable sortable" style="text-align:center"')
table.insert(ret, '\r\n!Map')
-- Make two table that will keep track of the max/min amount of land for each biome
-- At the same time, make the output table header
local biomeMax = {}
local biomeMin = {}
for _, biome in ipairs(Township.biomes) do
table.insert(ret, '\r\n!'..Icons.Icon({biome.name, type='biome', notext=true, nolink=true})..'<br>'..biome.name)
biomeMax[biome.id] = -1
biomeMin[biome.id] = Township.maxTownSize + 1
end
-- Find the min and max amount for each biome
for _, map in ipairs(Township.maps) do
for _, biome in ipairs(map.biomes) do
biomeMax[biome.biomeID] = math.max(biomeMax[biome.biomeID], biome.count)
biomeMin[biome.biomeID] = math.min(biomeMin[biome.biomeID], biome.count)
end
end
-- Draw all the map rows
for _, map in ipairs(Township.maps) do
table.insert(ret, '\r\n|-')
table.insert(ret, '\r\n!style="text-align:left"|'..map.name)
for _, biome in ipairs(map.biomes) do
-- Color the cell if min or max value
local max = biomeMax[biome.biomeID]
local min = biomeMin[biome.biomeID]
local count = biome.count
local class = count == max and 'table-positive' or count == min and 'table-negative' or ''
-- Insert cell
table.insert(ret, '\r\n|class="'..class..'"|'..count)
end
end
table.insert(ret, '\r\n|}')
return table.concat(ret)
end
 
-- Returns a row containing a task given a title and a task table
function p._GetTaskRow(title, task)
local ret = {}
-- If has description, we will need to rowspan the title by 2, and insert a description with colspan 2
local hasDescription = false
if task.description ~= nil then
hasDescription = true
end
local titlespan = hasDescription == true and 'rowspan="2"|' or ''
-- Title
table.insert(ret, '\r\n|-')
table.insert(ret, '\r\n!'..titlespan..title)
-- Description
if hasDescription then
table.insert(ret, '\r\n|colspan="2"|'..task.description)
table.insert(ret, '\r\n|-')
end
-- Requirements
table.insert(ret, '\r\n|')
local requirements = {}
for _, item in ipairs(task.goals.items) do
local itemname = GameData.getEntityByID('items', item.id).name
table.insert(requirements, Shared.formatnum(item.quantity)..' '..Icons.Icon({itemname, type='item'}))
end
for _, monster in ipairs(task.goals.monsters) do
local monstername = GameData.getEntityByID('monsters', monster.id).name
table.insert(requirements, Shared.formatnum(monster.quantity)..' '..Icons.Icon({monstername, type='monster'}))
end
for _, skill in ipairs(task.goals.skillXP) do
local skillname = GameData.getSkillData(skill.id).name
table.insert(requirements, Shared.formatnum(skill.quantity)..' '..Icons.Icon({skillname, type='skill'})..' XP')
end
for _, building in ipairs(task.goals.buildings) do
local buildingname = p._GetBuildingByID(building.id).name
table.insert(requirements, Shared.formatnum(building.quantity)..' '..Icons.Icon({buildingname, type='building'}))
end
-- We don't check tasks.requirements (so far it's only used to enumerate the Tutorial tasks so you only see 1 at a time)
table.insert(ret, table.concat(requirements, '<br>'))
-- Rewards
table.insert(ret, '\r\n|')
local rewards = {}
if task.rewards.gp ~= 0 then
table.insert(rewards, Icons.GP(task.rewards.gp))
end
if task.rewards.slayerCoins ~= 0 then
table.insert(rewards, Icons.SC(task.rewards.slayerCoins))
end
for _, item in ipairs(task.rewards.items) do
local itemname = GameData.getEntityByID('items', item.id).name
table.insert(rewards, Shared.formatnum(item.quantity)..' '..Icons.Icon({itemname, type='item'}))
end
for _, skill in ipairs(task.rewards.skillXP) do
local skillname = GameData.getSkillData(skill.id).name
table.insert(rewards, Shared.formatnum(skill.quantity)..' '..Icons.Icon({skillname, type='skill'})..' XP')
end
for _, townshipResource in ipairs(task.rewards.townshipResources) do
local resourcename = p._GetResourceByID(townshipResource.id).name
table.insert(rewards, Shared.formatnum(townshipResource.quantity)..' '..Icons.Icon({resourcename, type='resource'}))
end
table.insert(ret, table.concat(rewards, '<br>'))
return table.concat(ret)
end
 
-- Returns all the tasks of a given category
function p.GetTaskTable(frame)
local category = frame.args ~= nil and frame.args[1] or frame
local categoryname = GameData.getEntityByID(Township.taskCategories, category).name
local taskcount = 0
local ret = {}
table.insert(ret, '\r\n{| class="wikitable lighttable" style="text-align:left"')
table.insert(ret, '\r\n!Task')
table.insert(ret, '\r\n!Requirements')
table.insert(ret, '\r\n!Rewards')
for _, task in ipairs(Township.tasks) do
-- Filter out other categories
if task.category == category then
taskcount = taskcount + 1
local title = categoryname..' '..taskcount
table.insert(ret, p._GetTaskRow(title, task))
end
end
table.insert(ret, '\r\n|}')
return table.concat(ret)
end
 
-- Returns a table containing all the tasks that reference an item or monster
-- e.g. p.GetTaskReferenceTable({'Chicken Coop', 'dungeon'})
-- name = item or monster name
-- type = 'item' or 'monster' or 'dungeon'
function p.GetTaskReferenceTable(frame)
-- Returns a set containing all the desired IDs
local function GetReferenceIDs(referenceName, referenceType)
local IDs = {}
if referenceType == 'dungeon' then
-- We get the tasks associated with all monsters in the dungeon
local monsters = GameData.getEntityByName('dungeons', referenceName).monsterIDs
for _, monster in ipairs(monsters) do
IDs[monster] = true
end
end
if referenceType == 'item' then
IDs[GameData.getEntityByName('items', referenceName).id] = true
end
if referenceType == 'monster' then
IDs[GameData.getEntityByName('monsters', referenceName).id] = true
end
return IDs
end
-- For a task, returns where to search for the desired IDs, given the type
local function GetGetSearchTables(referenceType)
local function searchItems(task)
return {task.goals.items, task.rewards.items}
end
local function searchMonsters(task)
return {task.goals.monsters}
end
-- item -> searchItems; monster or dungeon -> searchMonsters
return referenceType == 'item' and searchItems or searchMonsters
end
local args = frame.args ~= nil and frame.args or frame
local referenceName = Shared.fixPagename(args[1])
local referenceType = args[2]
local referenceIDs = GetReferenceIDs(referenceName, referenceType)
-- GetSearchTables = function searchItems/Monsters(task)
local GetSearchTables = GetGetSearchTables(referenceType)
 
local function checkTask(task)
local function checkID(entry)
return referenceIDs[entry.id] ~= nil
end
for _, searchTable in ipairs(GetSearchTables(task)) do
-- Check to see if the table contains any of the IDs in referenceIDs
if searchTable[1] ~= nil then -- Make sure table is not empty
if #GameData.getEntities(searchTable, checkID) ~= 0 then -- Make sure we have at least 1 match
return true
end
end
end
return false
end
-- Find all tasks that contain the desired ids
local tasks = GameData.getEntities(Township.tasks, checkTask)
if #tasks == 0 then
return ''
end
-- Build the table
local ret = {}
table.insert(ret, '==Tasks==')
table.insert(ret, '\r\n{| class="wikitable" style="text-align:left"')
table.insert(ret, '\r\n!Task')
table.insert(ret, '\r\n!Requirements')
table.insert(ret, '\r\n!Rewards')
for _, task in ipairs(tasks) do
local categoryname = GameData.getEntityByID(Township.taskCategories, task.category).name
local title = '[[Township/Tasks#'..categoryname..'|'..categoryname..']]'
table.insert(ret, p._GetTaskRow(title, task))
end
table.insert(ret, '\r\n|}')
return table.concat(ret)
end
 
function p.GetWorshipTable()
local function GetCheckpointCell(checkpoint)
return '\r\n|-\r\n!'..checkpoint..'%<br>'..(checkpoint*Township.maxWorship/100)..'/'..Township.maxWorship
end
local ret = {}
table.insert(ret, '\r\n{| class="wikitable" style="text-align:left"')
table.insert(ret, '\r\n!'..Icons.Icon({'Worship', type='township', nolink=true}))
-- Names
for _, worship in ipairs(Township.worships) do
if worship.isHidden == false then
table.insert(ret, '\r\n!'..Icons.Icon({worship.name, type='monster', size=50})..Icons.Icon({'Statue of '..worship.name, type='building', size=50, notext=true}))
end
end
-- Requirements
-- Hard-coded because there's only 1 requirement
table.insert(ret, '\r\n|-\r\n!Requirements')
local requirements = {
['melvorF:Bane'] = 'Completion of<br>'..Icons.Icon({'Impending Darkness Event', type='dungeon'})
}
for _, worship in ipairs(Township.worships) do
if worship.isHidden == false then
local requirement = requirements[worship.id] ~= nil and requirements[worship.id] or 'None'
table.insert(ret, '\r\n|style="text-align:center|'..requirement)
end
end
-- Base modifiers
table.insert(ret, GetCheckpointCell(0))
for _, worship in ipairs(Township.worships) do
mw.logObject(worship.isHidden == false)
if worship.isHidden == false then
table.insert(ret, '\r\n|'..Constants.getModifiersText(worship.modifiers))
end
end
end
end
return out
-- Checkpoint modifiers
for i, checkpoint in ipairs(Township.worshipCheckpoints) do
table.insert(ret, GetCheckpointCell(checkpoint))
for _, worship in ipairs(Township.worships) do
if worship.isHidden == false then
table.insert(ret, '\r\n|'..Constants.getModifiersText(worship.checkpoints[i]))
end
end
end
 
-- Total sum
table.insert(ret, '\r\n|-\r\n!Total')
for _, worship in ipairs(Township.worships) do
if worship.isHidden == false then
local modifiers = Shared.clone(worship.modifiers)
for _, checkpoint in ipairs(worship.checkpoints) do
for modifier, magnitude in pairs(checkpoint) do
local swappedModifier = string.sub(modifier, 1, string.len('increased')) == 'increased' and string.gsub(modifier, 'increased', 'decreased') or string.gsub(modifier, 'decreased', 'increased')
-- The modifier already exists, so we add the two modifiers together
if modifiers[modifier] ~= nil then
modifiers[modifier] = modifiers[modifier] + magnitude
-- The inverse modifier already exists, so we subtract the negative value of the new modifier
elseif modifiers[swappedModifier] ~= nil then
modifiers[swappedModifier] = modifiers[swappedModifier] - magnitude
-- The modifier does not exist, so create the modifier
else
modifiers[modifier] = magnitude
end
end
end
table.insert(ret, '\r\n|'..Constants.getModifiersText(modifiers))
end
end
table.insert(ret, '\r\n|}')
return table.concat(ret)
end
end


return p
return p
572

edits