more refactoring, and better npc worth calculation

This commit is contained in:
Lilian Jónsdóttir 2020-08-25 00:05:17 -07:00
parent c00fb8b4ea
commit 184bbf7379
6 changed files with 82 additions and 35 deletions

View file

@ -29,7 +29,12 @@ this.runtimeData = {
-- cells marked as public
publicHouses = {},
-- homes picked for NPCs
homes = {byName = {}, byCell = {}},
homes = {
-- used for caching homes to avoid reiterating NPCs
byName = {},
-- used for checking when entering wandering NPC's house, will probably remove
byCell = {}
},
-- NPCs who have been moved
movedNPCs = {},
-- positions that haven't been used

View file

@ -34,6 +34,7 @@ return {
["Caldera, Nedhelas' House"] = {position = {-235.15, 3.21, -123.42}, orientation = {0.00, 0.00, 1.77}}
},
-- todo: find a way to pick this with code instead
-- positions picked from a list for public houses
cells = {
-- {{{ Vvardenfell

View file

@ -1,42 +1,15 @@
-- handles creation of runtime data tables
local common = require("celediel.NPCsGoHome.common")
local config = require("celediel.NPCsGoHome.config").getConfig()
local interop = require("celediel.NPCsGoHome.interop")
local positions = require("celediel.NPCsGoHome.data.positions")
local config = require("celediel.NPCsGoHome.config").getConfig()
local evaluators = require("celediel.NPCsGoHome.functions.npcEvaluators")
local zeroVector = tes3vector3.new(0, 0, 0)
local function log(level, ...) if config.logLevel >= level then common.log(...) end end
local this = {}
-- {{{ npc evaluators
-- NPCs barter gold + value of all inventory items
this.calculateNPCWorth = function(npc, merchantCell)
local worth = npc.object.barterGold
local obj = npc.baseObject and npc.baseObject or npc.object
if npc.object.inventory then
for _, item in pairs(npc.object.inventory) do worth = worth + (item.object.value or 0) end
end
if merchantCell then -- if we pass a cell argument
for box in merchantCell:iterateReferences(tes3.objectType.container) do -- loop over each container
if box.inventory then -- if it's not empty
for item in tes3.iterate(box.inventory) do -- loop over its items
if obj:tradesItemType(item.objectType) then -- if the NPC sells that type
worth = worth + item.object.value -- add its value to the NPCs total value
end
end
end
end
end
return worth
end
-- }}}
this.createHomedNPCTableEntry = function(npc, home, startingPlace, isHome, position, orientation)
if npc.object and (npc.object.name == nil or npc.object.name == "") then return end
@ -51,7 +24,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 common.runtimeData.positions[id] then
elseif not table.empty(common.runtimeData.positions[id]) then
local choice, index = table.choice(common.runtimeData.positions[id])
pos = choice.position
ori = choice.orientation
@ -84,7 +57,7 @@ this.createHomedNPCTableEntry = function(npc, home, startingPlace, isHome, posit
ogOrientation = ogOrientation, -- tes3vector3
homePosition = pickedPosition, -- tes3vector3
homeOrientation = pickedOrientation, -- tes3vector3
worth = this.calculateNPCWorth(npc) -- int
worth = evaluators.calculateNPCWorth(npc) -- int
}
common.runtimeData.homes.byName[npc.object.name] = entry
@ -103,9 +76,9 @@ this.createPublicHouseTableEntry = function(publicCell, proprietor, city, name)
-- cell worth is combined worth of all NPCs
for innard in publicCell:iterateReferences(tes3.objectType.npc) do
if innard == proprietor then
worth = worth + this.calculateNPCWorth(innard, publicCell)
worth = worth + evaluators.calculateNPCWorth(innard, publicCell).total
else
worth = worth + this.calculateNPCWorth(innard)
worth = worth + evaluators.calculateNPCWorth(innard).total
end
end

View file

@ -0,0 +1,46 @@
-- handles evalutating NPCs
local this = {}
-- NPCs barter gold + value of all inventory items
this.calculateNPCWorth = function(npc, merchantCell)
-- start with this
local worth = {barter = npc.object.barterGold, equipment = 0, inventory = 0}
-- add currently equipped items
if npc.object.equipment then
for _, item in pairs(npc.object.equipment) do
worth.equipment = worth.equipment + (item.object.value or 0)
end
end
-- add items in inventory
if npc.object.inventory then
for _, item in pairs(npc.object.inventory) do
worth.inventory = worth.inventory + (item.object.value or 0)
end
end
-- calculate value of objects sold by NPC in the cell, and add it to barter
if merchantCell then -- if we pass a cell argument
for box in merchantCell:iterateReferences(tes3.objectType.container) do -- loop over each container
if box.inventory then -- if it's not empty
for item in tes3.iterate(box.inventory) do -- loop over its items
if npc.object:tradesItemType(item.objectType) then -- if the NPC sells that type
worth.barter = worth.barter + item.object.value -- add its value to the NPCs total value
end
end
end
end
end
-- caculate the total
local total = 0
for _, v in pairs(worth) do total = total + v end
-- then add it to the table
worth.total = total
return worth
end
return this

View file

@ -20,6 +20,7 @@ this.updatePositions = function(cell)
end
end
-- todo: make this recursive?
this.searchCellsForPositions = function()
for _, cell in pairs(tes3.getActiveCells()) do
-- check active cells
@ -107,6 +108,11 @@ this.putNPCsBack = function()
orientation = data.ogPlace
})
end
-- reset loaded position data
common.runtimeData.positions = {}
this.searchCellsForPositions()
interop.setRuntimeData(common.runtimeData)
end

View file

@ -3,7 +3,6 @@
local config = require("celediel.NPCsGoHome.config").getConfig()
local common = require("celediel.NPCsGoHome.common")
local checks = require("celediel.NPCsGoHome.functions.checks")
local housing = require("celediel.NPCsGoHome.functions.housing")
local processors = require("celediel.NPCsGoHome.functions.processors")
-- }}}
@ -159,6 +158,20 @@ local function onCellChanged(e)
checkEnteredPublicHouse(e.cell, common.split(e.cell.name, ",")[1])
end
end
-- debug events
local function onKeyDown(e)
-- if alt log runtimeData
if e.isAltDown then
-- log(common.logLevels.small, common.inspect(common.runtimeData))
log(common.logLevels.none, json.encode(common.runtimeData, { indent = true }))
end
-- if ctrl log position data formattet for positions.lua
if e.isControlDown then
log(common.logLevels.none, "{position = %s, orientation = %s,", tes3.player.position, tes3.player.orientation)
end
end
-- }}}
-- {{{ init
@ -175,6 +188,9 @@ local function onInitialized()
event.register("cellChanged", onCellChanged)
event.register("activate", onActivated)
-- debug events
event.register("keyDown", onKeyDown, { filter = tes3.scanCode.c } )
log(common.logLevels.none, "Successfully initialized")
end