better logging and such
This commit is contained in:
parent
79f5f394b9
commit
8a640d07f3
|
@ -1,5 +1,3 @@
|
|||
local inspect = require("inspect")
|
||||
|
||||
local this = {}
|
||||
|
||||
-- {{{ Variables and such
|
||||
|
@ -65,11 +63,6 @@ end
|
|||
|
||||
this.log = function(...) mwse.log("[%s] %s", this.modName, string.format(...)) end
|
||||
|
||||
this.inspect = function(thing)
|
||||
this.log("Inspecting a %s", thing)
|
||||
this.log(inspect(thing))
|
||||
end
|
||||
|
||||
this.vowel = function(str)
|
||||
local s = string.sub(str, 1, 1)
|
||||
local n = ""
|
||||
|
@ -89,7 +82,6 @@ this.keyOfLargestValue = function(t)
|
|||
picked = key
|
||||
end
|
||||
end
|
||||
-- return largest == 0 and nil or largest
|
||||
return picked
|
||||
end
|
||||
|
||||
|
|
|
@ -4,49 +4,59 @@ local npcEvaluators = require("celediel.NPCsGoHome.functions.npcEvaluators")
|
|||
|
||||
local this = {}
|
||||
|
||||
-- todo: logging
|
||||
local function log(level, ...) if config.logLevel >= level then common.log(...) end end
|
||||
|
||||
this.calculateCellWorth = function(cell, proprietor)
|
||||
-- cell worth is combined worth of all NPCs
|
||||
this.calculateCellWorth = function(cell, proprietor)
|
||||
local worth = 0
|
||||
|
||||
local msg = "breakdown:\n"
|
||||
for innard in cell:iterateReferences(tes3.objectType.npc) do
|
||||
worth = worth + npcEvaluators.calculateNPCWorth(innard, innard == proprietor and cell or nil).total
|
||||
local total = npcEvaluators.calculateNPCWorth(innard, innard == proprietor and cell or nil).total
|
||||
worth = worth + total
|
||||
msg = msg .. string.format("%s worth:%s, ", innard.object.name, total)
|
||||
end
|
||||
|
||||
log(common.logLevels.medium, "Calculated worth of %s for cell %s", worth, cell.id)
|
||||
log(common.logLevels.large, msg:sub(1, #msg - 2)) -- strip off last ", "
|
||||
return worth
|
||||
end
|
||||
|
||||
-- iterate NPCs in the cell, if configured amount of the population is any one
|
||||
-- faction, that's the cell's faction, otherwise, cell doesn't have a faction.
|
||||
this.pickCellFaction = function(cell)
|
||||
-- iterate NPCs in the cell, if 2/3 the population is any one faction,
|
||||
-- that's the cell's faction, otherwise, cell doesn't have a faction.
|
||||
local npcs = {majorityFactions = {}, allFactions = {}, total = 0}
|
||||
|
||||
-- count all the npcs with factions
|
||||
for npc in cell:iterateReferences(tes3.objectType.npc) do
|
||||
local faction = npc.object.faction
|
||||
|
||||
if faction then
|
||||
if not npcs.allFactions[faction] then npcs.allFactions[faction] = {total = 0, percentage = 0} end
|
||||
if not npcs.allFactions[faction.id] then npcs.allFactions[faction.id] = {total = 0, percentage = 0} end
|
||||
|
||||
if not npcs.allFactions[faction].master or npcs.allFactions[faction].master.object.factionIndex <
|
||||
npc.object.factionIndex then npcs.allFactions[faction].master = npc end
|
||||
if not npcs.allFactions[faction.id].master or npcs.allFactions[faction.id].master.object.factionIndex <
|
||||
npc.object.factionIndex then npcs.allFactions[faction.id].master = npc end
|
||||
|
||||
npcs.allFactions[faction].total = npcs.allFactions[faction].total + 1
|
||||
npcs.allFactions[faction.id].total = npcs.allFactions[faction.id].total + 1
|
||||
end
|
||||
|
||||
npcs.total = npcs.total + 1
|
||||
end
|
||||
|
||||
for faction, info in pairs(npcs.allFactions) do
|
||||
-- pick out all the factions that make up a percentage of the cell greater than the configured value
|
||||
-- as long as the cell passes the minimum requirement check
|
||||
for id, info in pairs(npcs.allFactions) do
|
||||
info.percentage = (info.total / npcs.total) * 100
|
||||
if info.percentage >= config.factionIgnorePercentage then
|
||||
-- return faction.id
|
||||
npcs.majorityFactions[faction] = info.percentage
|
||||
if info.percentage >= config.factionIgnorePercentage and npcs.total >= config.minimumOccupancy then
|
||||
npcs.majorityFactions[id] = info.percentage
|
||||
end
|
||||
end
|
||||
|
||||
-- no faction
|
||||
return table.empty(npcs.majorityFactions) and "none" or common.keyOfLargestValue(npcs.majorityFactions)
|
||||
-- from the majority values, return the faction with the largest percentage, or "none"
|
||||
local picked = common.keyOfLargestValue(npcs.majorityFactions)
|
||||
log(common.logLevels.medium, "Picked faction %s for cell %s", picked, cell.id)
|
||||
log(common.logLevels.large, "breakdown:\n%s", json.encode(npcs, {indent = true}))
|
||||
return picked
|
||||
end
|
||||
|
||||
return this
|
||||
|
|
|
@ -109,6 +109,8 @@ this.isIgnoredNPC = function(npc)
|
|||
local isDead = false
|
||||
local isHostile = false
|
||||
local isVampire = false
|
||||
-- some TR "Hired Guards" aren't actually "guards", ignore them as well
|
||||
local isGuard = obj.isGuard or (obj.name:lower():match("guard") and true or false)
|
||||
|
||||
if npc.mobile then
|
||||
if npc.mobile.health.current <= 0 or npc.mobile.isDead then isDead = true end
|
||||
|
@ -132,13 +134,13 @@ this.isIgnoredNPC = function(npc)
|
|||
"guard:%s dead:%s vampire:%s werewolf:%s dreamer:%s follower:%s hostile:%s %s%s"), --
|
||||
obj.name, npc.object.id, npc.object.baseObject and npc.object.baseObject.id or "nil", --
|
||||
config.ignored[obj.id:lower()], obj.sourceMod, config.ignored[obj.sourceMod:lower()], --
|
||||
obj.isGuard, isDead, isVampire, isWerewolf, (obj.class and obj.class.id == "Dreamers"), --
|
||||
isGuard, isDead, isVampire, isWerewolf, (obj.class and obj.class.id == "Dreamers"), --
|
||||
common.runtimeData.followers[npc.object.id], isHostile, obj.id:match("fargoth") and "fargoth:" or "", --
|
||||
obj.id:match("fargoth") and isFargothActive or "")
|
||||
|
||||
return config.ignored[obj.id:lower()] or --
|
||||
config.ignored[obj.sourceMod:lower()] or --
|
||||
obj.isGuard or --
|
||||
isGuard or --
|
||||
isFargothActive or --
|
||||
isDead or -- don't move dead NPCS
|
||||
isHostile or --
|
||||
|
@ -166,8 +168,6 @@ this.isPublicHouse = function(cell)
|
|||
if not this.isInteriorCell(cell) then return false end
|
||||
|
||||
-- gather some data about the cell
|
||||
local worth = cellEvaluators.calculateCellWorth(cell)
|
||||
local faction = cellEvaluators.pickCellFaction(cell)
|
||||
local typeOfPub = common.pickPublicHouseType(cell)
|
||||
local city, publicHouseName
|
||||
|
||||
|
@ -187,7 +187,9 @@ this.isPublicHouse = function(cell)
|
|||
|
||||
-- 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
|
||||
dataTables.createPublicHouseTableEntry(cell, nil, city, publicHouseName, worth, faction)
|
||||
dataTables.createPublicHouseTableEntry(cell, nil, city, publicHouseName,
|
||||
cellEvaluators.calculateCellWorth(cell),
|
||||
cellEvaluators.pickCellFaction(cell))
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -199,7 +201,9 @@ this.isPublicHouse = function(cell)
|
|||
log(common.logLevels.medium, "NPC:\'%s\' of class:\'%s\' made %s public", npc.object.name,
|
||||
npc.object.class and npc.object.class.id or "none", cell.name)
|
||||
|
||||
dataTables.createPublicHouseTableEntry(cell, npc, city, publicHouseName, worth, faction)
|
||||
dataTables.createPublicHouseTableEntry(cell, npc, city, publicHouseName,
|
||||
cellEvaluators.calculateCellWorth(cell),
|
||||
cellEvaluators.pickCellFaction(cell))
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -232,7 +236,9 @@ this.isPublicHouse = function(cell)
|
|||
config.factionIgnorePercentage then
|
||||
log(common.logLevels.medium, "%s is %s%% faction %s, marking public.", cell.name, info.percentage, faction)
|
||||
|
||||
dataTables.createPublicHouseTableEntry(cell, npcs.factions[faction].master, city, publicHouseName, worth, faction)
|
||||
dataTables.createPublicHouseTableEntry(cell, npcs.factions[faction].master, city, publicHouseName,
|
||||
cellEvaluators.calculateCellWorth(cell),
|
||||
cellEvaluators.pickCellFaction(cell))
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
@ -281,17 +287,18 @@ end
|
|||
|
||||
-- AT NIGHT
|
||||
this.checkTime = function()
|
||||
log(common.logLevels.large, "Current time is %s, things are closed between %s and %s",
|
||||
tes3.worldController.hour.value, config.closeTime, config.openTime)
|
||||
return tes3.worldController.hour.value >= config.closeTime or tes3.worldController.hour.value <= config.openTime
|
||||
local night = tes3.worldController.hour.value >= config.closeTime or tes3.worldController.hour.value <= config.openTime
|
||||
log(common.logLevels.large, "Current time is %.2f (%snight), things are closed between %s and %s",
|
||||
tes3.worldController.hour.value, night and "" or "not ", config.closeTime, config.openTime)
|
||||
return night
|
||||
end
|
||||
|
||||
-- inclement weather
|
||||
this.checkWeather = function(cell)
|
||||
if not cell.region then return end
|
||||
|
||||
log(common.logLevels.large, "Weather: %s >= %s == %s", cell.region.weather.index, config.worstWeather,
|
||||
cell.region.weather.index >= config.worstWeather)
|
||||
log(common.logLevels.large, "Weather: current:%s >= configured worst:%s == %s", cell.region.weather.index,
|
||||
config.worstWeather, cell.region.weather.index >= config.worstWeather)
|
||||
|
||||
return cell.region.weather.index >= config.worstWeather
|
||||
end
|
||||
|
|
|
@ -25,7 +25,7 @@ this.createHomedNPCTableEntry = function(npc, home, startingPlace, isHome, posit
|
|||
if isHome and positions.npcs[npc.object.name] then
|
||||
pos = positions.npcs[npc.object.name].position
|
||||
ori = positions.npcs[npc.object.name].orientation
|
||||
elseif not table.empty(common.runtimeData.positions[id]) then
|
||||
elseif common.runtimeData.positions[id] and not table.empty(common.runtimeData.positions[id]) then
|
||||
-- pick a random position out of the positions in memory
|
||||
local choice, index = table.choice(common.runtimeData.positions[id])
|
||||
pos = choice.position
|
||||
|
@ -36,11 +36,11 @@ this.createHomedNPCTableEntry = function(npc, home, startingPlace, isHome, posit
|
|||
ori = {0, 0, 0}
|
||||
end
|
||||
|
||||
log(common.logLevels.large, "Settled on position:%s, orientation:%s for %s in %s", pos, ori, npc.object.name, id)
|
||||
|
||||
pickedPosition = tes3vector3.new(pos[1], pos[2], pos[3])
|
||||
pickedOrientation = tes3vector3.new(ori[1], ori[2], ori[3])
|
||||
|
||||
log(common.logLevels.large, "Settled on position:%s, orientation:%s for %s in %s", pickedPosition, pickedOrientation, npc.object.name, id)
|
||||
|
||||
local ogPosition = position and (tes3vector3.new(position.x, position.y, position.z)) or
|
||||
(npc.position and npc.position:copy() or zeroVector:copy())
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
-- handles evaluating NPCs
|
||||
local common = require("celediel.NPCsGoHome.common")
|
||||
local config = require("celediel.NPCsGoHome.config").getConfig()
|
||||
|
||||
local this = {}
|
||||
|
||||
|
@ -41,6 +42,7 @@ this.calculateNPCWorth = function(npc, merchantCell)
|
|||
-- calculate the total
|
||||
local total = 0
|
||||
for _, v in pairs(worth) do total = total + v end
|
||||
log(common.logLevels.medium, "Calculated worth of %s for %s", total, npc.object.name)
|
||||
|
||||
-- then add it to the table
|
||||
worth.total = total
|
||||
|
|
|
@ -125,9 +125,6 @@ this.processNPCs = function(cell)
|
|||
for npc in cell:iterateReferences(tes3.objectType.npc) do
|
||||
-- for npc, _ in pairs(cellsInMemory[cell].npcs) do
|
||||
if not checks.isIgnoredNPC(npc) then
|
||||
log(common.logLevels.large, "People change")
|
||||
-- if not npc.data.NPCsGoHome then npc.data.NPCsGoHome = {} end
|
||||
|
||||
-- find NPC homes
|
||||
local npcHome = config.moveNPCs and housing.pickHomeForNPC(cell, npc) or nil
|
||||
|
||||
|
@ -163,8 +160,7 @@ this.processNPCs = function(cell)
|
|||
end
|
||||
|
||||
-- now put NPCs back
|
||||
-- if not (checks.checkTime() or checks.checkWeather(cell)) and #movedNPCs > 0 then putNPCsBack() end
|
||||
if not (checks.checkTime() or checks.checkWeather(cell)) then this.putNPCsBack() end
|
||||
if not (checks.checkTime() or checks.checkWeather(cell)) and #common.runtimeData.movedNPCs > 0 then this.putNPCsBack() end
|
||||
end
|
||||
|
||||
this.processSiltStriders = function(cell)
|
||||
|
|
|
@ -16,7 +16,8 @@ local category = page:createCategory(common.modName)
|
|||
|
||||
category:createDropdown({
|
||||
label = "Debug log level",
|
||||
description = [[Enable this if you want to flood mwse.log with nonsense. Even small is huge.]],
|
||||
description = "Enable this if you want to flood mwse.log with nonsense. Even small is huge." ..
|
||||
"Large in Old Ebonheart spits out 16k lines each update. Don't pick that option.",
|
||||
options = {
|
||||
{label = "None", value = common.logLevels.none},
|
||||
{label = "Small", value = common.logLevels.small},
|
||||
|
|
Loading…
Reference in a new issue