diff --git a/MWSE/mods/celediel/NPCsGoHome/common.lua b/MWSE/mods/celediel/NPCsGoHome/common.lua index 22034cf..e42af3a 100644 --- a/MWSE/mods/celediel/NPCsGoHome/common.lua +++ b/MWSE/mods/celediel/NPCsGoHome/common.lua @@ -18,25 +18,20 @@ this.publicHouseTypes = { inns = "Inns", guildhalls = "Guildhalls", temples = "Temples", - houses = "Houses", + homes = "Homes", cantonworks = "Cantonworks" } - --- Canton string matches --- move NPCs into waistworks -this.waistworks = "[Ww]aistworks" --- don't lock canalworks -this.canalworks = "[Cc]analworks" --- doors to underworks should be ignored --- but NPCs in underworks should not be disabled -this.underworks = "[Uu]nderworks" - -- }}} -- {{{ Filled at runtime this.runtimeData = { -- cells marked as public - publicHouses = {}, + publicHouses = { + -- used for caching public houses to avoid reiterating NPCs + byName = {}, + -- used for picking cells to move NPCs to + byType = {} + }, -- homes picked for NPCs homes = { -- used for caching homes to avoid reiterating NPCs @@ -94,14 +89,15 @@ end -- todo: pick this better this.pickPublicHouseType = function(cell) - if cell.id:match("Guild") then + local id = cell.id:lower() + if id:match("guild") then return this.publicHouseTypes.guildhalls - elseif cell.id:match("Temple") then + elseif id:match("temple") then return this.publicHouseTypes.temples - elseif cell.id:match(this.canalworks) or cell.id:match(this.waistworks) then + elseif id:match("canalworks") or cell.id:match("waistworks") then return this.publicHouseTypes.cantonworks - -- elseif cell.id:match("House") then - -- return publicHouseTypes.houses + elseif id:match("house") or id:match("manor") or id:match("tower") then + return this.publicHouseTypes.homes else return this.publicHouseTypes.inns end @@ -125,7 +121,8 @@ end this.isCantonWorksCell = function(cell) -- for _, str in pairs(waistworks) do if cell.id:match(str) then return true end end - return cell.id:match(this.waistworks) or cell.id:match(this.canalworks) or cell.id:match(this.underworks) + local id = cell.id:lower() + return id:match("waistworks") or id:match("canalworks") or id:match("underworks") end this.isCantonCell = function(cell) diff --git a/MWSE/mods/celediel/NPCsGoHome/functions/checks.lua b/MWSE/mods/celediel/NPCsGoHome/functions/checks.lua index 1251bbb..aca8eb3 100644 --- a/MWSE/mods/celediel/NPCsGoHome/functions/checks.lua +++ b/MWSE/mods/celediel/NPCsGoHome/functions/checks.lua @@ -172,7 +172,6 @@ this.isPublicHouse = function(cell) if not this.isInteriorCell(cell) then return false end -- gather some data about the cell - local typeOfPub = common.pickPublicHouseType(cell) local city, publicHouseName if cell.name and string.match(cell.name, ",") then @@ -184,16 +183,16 @@ this.isPublicHouse = function(cell) end -- don't iterate NPCs in the cell if we've already marked it public - if common.runtimeData.publicHouses[city] and - (common.runtimeData.publicHouses[city][typeOfPub] and common.runtimeData.publicHouses[city][typeOfPub][cell.id]) then + if common.runtimeData.publicHouses.byName[city] and common.runtimeData.publicHouses.byName[city][cell.id] then return true end -- if it's a waistworks cell, it's public, with no proprietor - if config.waistWorks == common.waist.public and cell.id:match(common.waistworks) then + if config.waistWorks == common.waist.public and cell.id:match("waistworks") then dataTables.createPublicHouseTableEntry(cell, nil, city, publicHouseName, cellEvaluators.calculateCellWorth(cell), - cellEvaluators.pickCellFaction(cell)) + cellEvaluators.pickCellFaction(cell), + common.publicHouseTypes.cantonworks) return true end @@ -236,7 +235,8 @@ this.isPublicHouse = function(cell) master.object.name, master.object.class) dataTables.createPublicHouseTableEntry(cell, master, city, publicHouseName, cellEvaluators.calculateCellWorth(cell), - cellEvaluators.pickCellFaction(cell)) + cellEvaluators.pickCellFaction(cell), + common.publicHouseTypes.temples) return true end @@ -254,12 +254,16 @@ this.isPublicHouse = function(cell) if (config.ignored[faction:lower()] or info.playerJoined) and (npcs.total >= config.minimumOccupancy or faction == "Blades") and (info.percentage >= config.factionIgnorePercentage) then - log(common.logLevels.medium, "[CHECKS] %s is %s%% faction %s, marking public.", cell.name, info.percentage, - faction) + log(common.logLevels.medium, "[CHECKS] %s is %s%% faction %s, marking public.", cell.name, info.percentage, faction) + + -- try id based categorization, but fallback on guildhall + local type = common.pickPublicHouseType(cell) + if type == common.publicHouseTypes.inns then type = common.publicHouseTypes.guildhalls end dataTables.createPublicHouseTableEntry(cell, npcs.factions[faction].master, city, publicHouseName, cellEvaluators.calculateCellWorth(cell), - cellEvaluators.pickCellFaction(cell)) + cellEvaluators.pickCellFaction(cell), + common.publicHouseTypes.guildhalls) return true end end diff --git a/MWSE/mods/celediel/NPCsGoHome/functions/dataTables.lua b/MWSE/mods/celediel/NPCsGoHome/functions/dataTables.lua index d70a0c1..4ea9d18 100644 --- a/MWSE/mods/celediel/NPCsGoHome/functions/dataTables.lua +++ b/MWSE/mods/celediel/NPCsGoHome/functions/dataTables.lua @@ -75,21 +75,25 @@ this.createPublicHouseTableEntry = function(publicCell, proprietor, city, name, local proprietorName = proprietor and proprietor.object.name or "no one" - if not common.runtimeData.publicHouses[city] then common.runtimeData.publicHouses[city] = {} end - if not common.runtimeData.publicHouses[city][typeOfPub] then - common.runtimeData.publicHouses[city][typeOfPub] = {} - end + local data = { + name = name, + city = city, + cell = publicCell, + type = type, + proprietor = proprietor, + proprietorName = proprietorName, + worth = cellWorth, + faction = cellFaction + } - common.runtimeData.publicHouses[city][typeOfPub][publicCell.id] = - { - name = name, - city = city, - cell = publicCell, - proprietor = proprietor, - proprietorName = proprietorName, - worth = cellWorth, - faction = cellFaction - } + -- create by type + if not common.runtimeData.publicHouses.byType[city] then common.runtimeData.publicHouses.byType[city] = {} end + if not common.runtimeData.publicHouses.byType[city][typeOfPub] then common.runtimeData.publicHouses.byType[city][typeOfPub] = {} end + common.runtimeData.publicHouses.byType[city][typeOfPub][publicCell.id] = data + + -- create by name + if not common.runtimeData.publicHouses.byName[city] then common.runtimeData.publicHouses.byName[city] = {} end + common.runtimeData.publicHouses.byName[city][publicCell.id] = data interop.setRuntimeData(common.runtimeData) end diff --git a/MWSE/mods/celediel/NPCsGoHome/functions/housing.lua b/MWSE/mods/celediel/NPCsGoHome/functions/housing.lua index ee7d786..a8ca517 100644 --- a/MWSE/mods/celediel/NPCsGoHome/functions/housing.lua +++ b/MWSE/mods/celediel/NPCsGoHome/functions/housing.lua @@ -33,8 +33,8 @@ this.pickInnForNPC = function(npc, city) -- temple for commoners and the poorest people -- but for now pick one at random - if common.runtimeData.publicHouses[city] and common.runtimeData.publicHouses[city][common.publicHouseTypes.inns] then - local choice = table.choice(common.runtimeData.publicHouses[city][common.publicHouseTypes.inns]) + if common.runtimeData.publicHouses.byType[city] and common.runtimeData.publicHouses.byType[city][common.publicHouseTypes.inns] then + local choice = table.choice(common.runtimeData.publicHouses.byType[city][common.publicHouseTypes.inns]) if not choice then return nil end log(common.logLevels.medium, "[HOUSING] Picking inn %s, %s for %s", choice.city, choice.name, npc.object.name) return choice.cell @@ -43,9 +43,9 @@ end this.pickPublicHouseForNPC = function(npc, city) -- look for wandering guild members - if common.runtimeData.publicHouses[city] and - common.runtimeData.publicHouses[city][common.publicHouseTypes.guildhalls] then - for _, data in pairs(common.runtimeData.publicHouses[city][common.publicHouseTypes.guildhalls]) do + if common.runtimeData.publicHouses.byType[city] and + common.runtimeData.publicHouses.byType[city][common.publicHouseTypes.guildhalls] then + for _, data in pairs(common.runtimeData.publicHouses.byType[city][common.publicHouseTypes.guildhalls]) do -- if npc's faction and proprietor's faction match, pick that one if npc.object.faction == data.proprietor.object.faction then log(common.logLevels.medium, "[HOUSING] Picking %s for %s based on faction", data.cell.id, npc.object.name) @@ -55,8 +55,8 @@ this.pickPublicHouseForNPC = function(npc, city) end -- temple members go to the temple - if common.runtimeData.publicHouses[city] and common.runtimeData.publicHouses[city][common.publicHouseTypes.temples] then - for _, data in pairs(common.runtimeData.publicHouses[city][common.publicHouseTypes.temples]) do + if common.runtimeData.publicHouses.byType[city] and common.runtimeData.publicHouses.byType[city][common.publicHouseTypes.temples] then + for _, data in pairs(common.runtimeData.publicHouses.byType[city][common.publicHouseTypes.temples]) do if npc.object.faction == data.proprietor.object.faction then log(common.logLevels.medium, "[HOUSING] Picking temple %s for %s based on faction", data.cell.id, npc.object.name) return data.cell @@ -101,9 +101,9 @@ this.pickHomeForNPC = function(cell, npc) -- if nothing was found, then we'll settle on Canton works cell, if the cell is a Canton if common.isCantonCell(cell) then - if common.runtimeData.publicHouses[city] and - common.runtimeData.publicHouses[city][common.publicHouseTypes.cantonworks] then - local canton = table.choice(common.runtimeData.publicHouses[city][common.publicHouseTypes.cantonworks]) + if common.runtimeData.publicHouses.byType[city] and + common.runtimeData.publicHouses.byType[city][common.publicHouseTypes.cantonworks] then + local canton = table.choice(common.runtimeData.publicHouses.byType[city][common.publicHouseTypes.cantonworks]) log(common.logLevels.medium, "[HOUSING] Picking works %s, %s for %s", canton.city, canton.name, npc.object.name) if canton then return dataTables.createHomedNPCTableEntry(npc, canton.cell, cell, false) end diff --git a/MWSE/mods/celediel/NPCsGoHome/main.lua b/MWSE/mods/celediel/NPCsGoHome/main.lua index d865ad7..ecca8e2 100644 --- a/MWSE/mods/celediel/NPCsGoHome/main.lua +++ b/MWSE/mods/celediel/NPCsGoHome/main.lua @@ -45,8 +45,7 @@ end local function checkEnteredPublicHouse(cell, city) local typeOfPub = common.pickPublicHouseType(cell) - local publicHouse = common.runtimeData.publicHouses[city] and - (common.runtimeData.publicHouses[city][typeOfPub] and common.runtimeData.publicHouses[city][typeOfPub][cell.name]) + local publicHouse = common.runtimeData.publicHouses.byName[city] and common.runtimeData.publicHouses.byName[city][cell.id] if publicHouse then local msg = string.format("Entering public space %s, a%s %s in the town of %s.", publicHouse.name,