don't move multiple NPCs into the same spot
This commit is contained in:
parent
4ed6648ca8
commit
ec2a570b30
|
@ -29,6 +29,8 @@ this.runtimeData = {
|
|||
},
|
||||
-- NPCs who have been moved
|
||||
movedNPCs = {},
|
||||
-- positions that haven't been used
|
||||
positions = {},
|
||||
-- player companions
|
||||
followers = {}
|
||||
}
|
||||
|
@ -73,6 +75,22 @@ this.pickPublicHouseType = function(cell)
|
|||
return this.publicHouseTypes.inns
|
||||
end
|
||||
end
|
||||
|
||||
this.checkModdedCell = function(cellId)
|
||||
local id
|
||||
|
||||
if cellId == "Balmora, South Wall Cornerclub" and tes3.isModActive("South Wall.ESP") then
|
||||
id = "Balmora, South Wall Den Of Iniquity"
|
||||
elseif cellId == "Balmora, Eight Plates" and tes3.isModActive("Eight Plates.esp") then
|
||||
id = "Balmora, Seedy Eight Plates"
|
||||
elseif cellId == "Hla Oad, Fatleg's Drop Off" and tes3.isModActive("Clean DR115_TheDropoff_HlaOadDocks.ESP") then
|
||||
id = "Hla Oad, The Drop Off"
|
||||
else
|
||||
id = cellId
|
||||
end
|
||||
|
||||
return id
|
||||
end
|
||||
-- }}}
|
||||
|
||||
return this
|
||||
|
|
|
@ -37,29 +37,13 @@ end
|
|||
|
||||
-- }}}
|
||||
|
||||
this.checkModdedCell = function(cellId)
|
||||
local id
|
||||
|
||||
if cellId == "Balmora, South Wall Cornerclub" and tes3.isModActive("South Wall.ESP") then
|
||||
id = "Balmora, South Wall Den Of Iniquity"
|
||||
elseif cellId == "Balmora, Eight Plates" and tes3.isModActive("Eight Plates.esp") then
|
||||
id = "Balmora, Seedy Eight Plates"
|
||||
elseif cellId == "Hla Oad, Fatleg's Drop Off" and tes3.isModActive("Clean DR115_TheDropoff_HlaOadDocks.ESP") then
|
||||
id = "Hla Oad, The Drop Off"
|
||||
else
|
||||
id = cellId
|
||||
end
|
||||
|
||||
return id
|
||||
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
|
||||
|
||||
local pickedPosition, pickedOrientation, pos, ori
|
||||
|
||||
-- mod support for different positions in cells
|
||||
local id = this.checkModdedCell(home.id)
|
||||
local id = common.checkModdedCell(home.id)
|
||||
|
||||
log(common.logLevels.medium, "Found %s for %s: %s... adding it to in memory table...",
|
||||
isHome and "home" or "public house", npc.object.name, id)
|
||||
|
@ -67,22 +51,21 @@ 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
|
||||
-- pickedPosition = positions.npcs[npc.object.name] and tes3vector3.new(p[1], p[2], p[3]) or zeroVector:copy()
|
||||
-- pickedOrientation = positions.npcs[npc.object.name] and tes3vector3.new(o[1], o[2], o[3]) or zeroVector:copy()
|
||||
elseif positions.cells[id] then
|
||||
pos = table.choice(positions.cells[id]).position
|
||||
ori = table.choice(positions.cells[id]).orientation
|
||||
-- pickedPosition = positions.cells[id] and tes3vector3.new(p[1], p[2], p[3]) or zeroVector:copy()
|
||||
-- pickedOrientation = positions.cells[id] and tes3vector3.new(o[1], o[2], o[3]) or zeroVector:copy()
|
||||
-- pickedPosition = tes3vector3.new(p[1], p[2], p[3])
|
||||
-- pickedOrientation = tes3vector3.new(o[1], o[2], o[3])
|
||||
-- elseif positions.cells[id] then
|
||||
elseif common.runtimeData.positions[id] then
|
||||
-- pos = table.choice(positions.cells[id]).position
|
||||
-- ori = table.choice(positions.cells[id]).orientation
|
||||
local choice, index = table.choice(common.runtimeData.positions[id])
|
||||
pos = choice.position
|
||||
ori = choice.orientation
|
||||
table.remove(common.runtimeData.positions[id], index)
|
||||
else
|
||||
pos = {0,0,0}
|
||||
ori = {0,0,0}
|
||||
-- pickedPosition = zeroVector:copy()
|
||||
-- pickedOrientation = zeroVector:copy()
|
||||
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])
|
||||
|
||||
|
|
|
@ -45,7 +45,8 @@ 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
|
||||
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 npc's faction and proprietor's faction match, pick that one
|
||||
if npc.object.faction == data.proprietor.object.faction then
|
||||
|
@ -78,8 +79,6 @@ this.pickHomeForNPC = function(cell, npc)
|
|||
for _, str in pairs(contextualNPCs) do if npc.object.id:match(str) then return end end
|
||||
|
||||
-- time to pick the "home"
|
||||
local picked = nil
|
||||
|
||||
local name = npc.object.name
|
||||
local city = common.split(cell.name, ",")[1]
|
||||
for door in cell:iterateReferences(tes3.objectType.door) do
|
||||
|
@ -88,11 +87,9 @@ this.pickHomeForNPC = function(cell, npc)
|
|||
|
||||
-- essentially, if npc full name, or surname matches the cell name
|
||||
if dest.id:match(name) or this.livesInManor(dest.name, name) then
|
||||
if common.runtimeData.homes.byName[name] then -- already have a home, don't create the table dataTables again
|
||||
picked = common.runtimeData.homes.byName[name]
|
||||
else
|
||||
picked = dataTables.createHomedNPCTableEntry(npc, dest, cell, true)
|
||||
end
|
||||
-- already have a home, don't create the table dataTables again
|
||||
return common.runtimeData.homes.byName[name] and common.runtimeData.homes.byName[name] or
|
||||
dataTables.createHomedNPCTableEntry(npc, dest, cell, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -102,21 +99,23 @@ this.pickHomeForNPC = function(cell, npc)
|
|||
log(common.logLevels.medium, "Didn't find a home for %s, trying inns", npc.object.name)
|
||||
local dest = this.pickPublicHouseForNPC(npc, city)
|
||||
|
||||
if dest then picked = dataTables.createHomedNPCTableEntry(npc, dest, cell, false) end
|
||||
if dest then return dataTables.createHomedNPCTableEntry(npc, dest, cell, false) end
|
||||
|
||||
-- if nothing was found, then we'll settle on Canton works cell, if the cell is a Canton
|
||||
if checks.isCantonCell(cell) then
|
||||
if common.runtimeData.publicHouses[city] and common.runtimeData.publicHouses[city][common.publicHouseTypes.cantonworks] then
|
||||
if common.runtimeData.publicHouses[city] and
|
||||
common.runtimeData.publicHouses[city][common.publicHouseTypes.cantonworks] then
|
||||
-- todo: maybe poorer NPCs in canalworks, others in waistworks ?
|
||||
local canton = table.choice(common.runtimeData.publicHouses[city][common.publicHouseTypes.cantonworks])
|
||||
log(common.logLevels.medium, "Picking works %s, %s for %s", canton.city, canton.name, npc.object.name)
|
||||
|
||||
if canton then picked = dataTables.createHomedNPCTableEntry(npc, canton.cell, cell, false) end
|
||||
if canton then return dataTables.createHomedNPCTableEntry(npc, canton.cell, cell, false) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return picked
|
||||
-- didn't find anything
|
||||
return nil
|
||||
end
|
||||
|
||||
return this
|
||||
|
|
|
@ -5,11 +5,40 @@ local checks = require("celediel.NPCsGoHome.functions.checks")
|
|||
local interop = require("celediel.NPCsGoHome.interop")
|
||||
local housing = require("celediel.NPCsGoHome.functions.housing")
|
||||
local dataTables = require("celediel.NPCsGoHome.functions.dataTables")
|
||||
local positions = require("celediel.NPCsGoHome.data.positions")
|
||||
|
||||
local function log(level, ...) if config.logLevel >= level then common.log(...) end end
|
||||
|
||||
local this = {}
|
||||
|
||||
this.updatePositions = function(cell)
|
||||
local id = cell.id
|
||||
-- update runtime positions in cell, but don't overwrite loaded positions
|
||||
if not common.runtimeData.positions[id] and positions.cells[id] then
|
||||
common.runtimeData.positions[id] = {}
|
||||
for _, data in pairs(positions.cells[id]) do
|
||||
table.insert(common.runtimeData.positions[id], data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
this.searchCellsForPositions = function()
|
||||
for _, cell in pairs(tes3.getActiveCells()) do
|
||||
-- check active cells
|
||||
this.updatePositions(cell)
|
||||
for door in cell:iterateReferences(tes3.objectType.door) do
|
||||
if door.destination then
|
||||
-- then check cells attached to active cells
|
||||
this.updatePositions(door.destination.cell)
|
||||
-- one more time
|
||||
for internalDoor in door.destination.cell:iterateReferences(tes3.objectType.door) do
|
||||
if internalDoor.destination then this.updatePositions(internalDoor.destination.cell) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- search in a specific cell for moved NPCs
|
||||
this.checkForMovedNPCs = function(cell)
|
||||
-- NPCs don't get moved to exterior cells, so no need to check them for moved NPCs
|
||||
|
|
|
@ -91,6 +91,7 @@ local function updateCells()
|
|||
log(common.logLevels.medium, "Updating active cells!")
|
||||
|
||||
followers = buildFollowerList()
|
||||
processors.searchCellsForPositions()
|
||||
|
||||
for _, cell in pairs(tes3.getActiveCells()) do
|
||||
log(common.logLevels.large, "Applying changes to cell %s", cell.id)
|
||||
|
|
|
@ -16,6 +16,7 @@ ignored class or faction will not be locked, or have its NPCS disabled.
|
|||
* NPC "homes"
|
||||
* Outside NPCs who have homes are currently paired with the inside cell of their home
|
||||
* Other NPCs are configurably paired with local public houses (Inns, temples, and guildhalls of their faction)
|
||||
* Moved NPCs persist on save/load
|
||||
|
||||
## WIP ##
|
||||
|
||||
|
@ -28,4 +29,9 @@ ignored class or faction will not be locked, or have its NPCS disabled.
|
|||
## TODO ##
|
||||
|
||||
* move non-faction NPCs who don't have homes to temples or inns based on their "worth"
|
||||
* pick temple for the poorest NPCs, or classed inns based on NPC/inn "worth"
|
||||
* pick temple for the poorest NPCs, or classed inns based on NPC/inn "worth"
|
||||
|
||||
## Known issues ##
|
||||
|
||||
* If NPCs in a town are moved, and the player moves far away from that town before they're moved back, then
|
||||
saves and reloads, those NPCs will probably stay moved.
|
Loading…
Reference in a new issue