minor fixes and more clarification
This commit is contained in:
parent
969097eada
commit
31bec61095
|
@ -16,7 +16,10 @@ local updateTimer
|
||||||
|
|
||||||
-- NPC homes
|
-- NPC homes
|
||||||
local publicHouses = {}
|
local publicHouses = {}
|
||||||
local homes = {byName = {}, byCell = {}}
|
local homes = {
|
||||||
|
byName = {}, -- used to ensure duplicate homes are not created
|
||||||
|
byCell = {} -- used for cellChange events
|
||||||
|
}
|
||||||
|
|
||||||
-- city name if cell.name is nil
|
-- city name if cell.name is nil
|
||||||
local wilderness = "Wilderness"
|
local wilderness = "Wilderness"
|
||||||
|
@ -54,6 +57,15 @@ local function checkModdedCell(cellId)
|
||||||
return id
|
return id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function isInteriorCell(cell)
|
||||||
|
if not cell then return end
|
||||||
|
|
||||||
|
log(common.logLevels.large, "Cell %s: interior: %s, behaves as exterior: %s therefore returning %s",
|
||||||
|
cell.id, cell.isInterior, cell.behavesAsExterior, cell.isInterior and not cell.behavesAsExterior)
|
||||||
|
|
||||||
|
return cell.isInterior and not cell.behavesAsExterior
|
||||||
|
end
|
||||||
|
|
||||||
-- patented by Merlord
|
-- patented by Merlord
|
||||||
local yeet = function(reference)
|
local yeet = function(reference)
|
||||||
-- tes3.positionCell({reference = reference, position = {0, 0, 10000}})
|
-- tes3.positionCell({reference = reference, position = {0, 0, 10000}})
|
||||||
|
@ -91,6 +103,7 @@ end
|
||||||
-- NPCs barter gold + value of all inventory items
|
-- NPCs barter gold + value of all inventory items
|
||||||
local function calculateNPCWorth(npc, merchantCell)
|
local function calculateNPCWorth(npc, merchantCell)
|
||||||
local worth = npc.object.barterGold
|
local worth = npc.object.barterGold
|
||||||
|
local obj = npc.baseObject and npc.baseObject or npc.object
|
||||||
|
|
||||||
if npc.object.inventory then
|
if npc.object.inventory then
|
||||||
for _, item in pairs(npc.object.inventory) do worth = worth + (item.object.value or 0) end
|
for _, item in pairs(npc.object.inventory) do worth = worth + (item.object.value or 0) end
|
||||||
|
@ -100,7 +113,7 @@ local function calculateNPCWorth(npc, merchantCell)
|
||||||
for box in merchantCell:iterateReferences(tes3.objectType.container) do -- loop over each container
|
for box in merchantCell:iterateReferences(tes3.objectType.container) do -- loop over each container
|
||||||
if box.inventory then -- if it's not empty
|
if box.inventory then -- if it's not empty
|
||||||
for item in tes3.iterate(box.inventory) do -- loop over its items
|
for item in tes3.iterate(box.inventory) do -- loop over its items
|
||||||
if npc.object.baseObject:tradesItemType(item.objectType) then -- if the NPC sells that type
|
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
|
worth = worth + item.object.value -- add its value to the NPCs total value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -187,14 +200,15 @@ end
|
||||||
|
|
||||||
local function createHomedNPCTableEntry(npc, home, startingPlace, isHome, position, orientation)
|
local function createHomedNPCTableEntry(npc, home, startingPlace, isHome, position, orientation)
|
||||||
if npc.object and (npc.object.name == nil or npc.object.name == "") then return end
|
if npc.object and (npc.object.name == nil or npc.object.name == "") then return end
|
||||||
log(common.logLevels.medium, "Found %s for %s: %s... adding it to in memory table...",
|
|
||||||
isHome and "home" or "public house", npc.object.name, home.id)
|
|
||||||
|
|
||||||
local pickedPosition, pickedOrientation, pos, ori
|
local pickedPosition, pickedOrientation, pos, ori
|
||||||
|
|
||||||
-- mod support for different positions in cells
|
-- mod support for different positions in cells
|
||||||
local id = checkModdedCell(home.id)
|
local id = 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)
|
||||||
|
|
||||||
if isHome and positions.npcs[npc.object.name] then
|
if isHome and positions.npcs[npc.object.name] then
|
||||||
pos = positions.npcs[npc.object.name].position
|
pos = positions.npcs[npc.object.name].position
|
||||||
ori = positions.npcs[npc.object.name].orientation
|
ori = positions.npcs[npc.object.name].orientation
|
||||||
|
@ -334,7 +348,7 @@ local function fargothCheck()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function isIgnoredNPC(npc)
|
local function isIgnoredNPC(npc)
|
||||||
local obj = npc.object.baseObject and npc.object.baseObject or npc.object
|
local obj = npc.baseObject and npc.baseObject or npc.object
|
||||||
|
|
||||||
-- ignore dead, attack on sight NPCs, and vampires
|
-- ignore dead, attack on sight NPCs, and vampires
|
||||||
local isDead = false
|
local isDead = false
|
||||||
|
@ -351,7 +365,7 @@ local function isIgnoredNPC(npc)
|
||||||
isVampire = obj.head.vampiric and true or false -- don't set a reference ... is bool even a reference type??
|
isVampire = obj.head.vampiric and true or false -- don't set a reference ... is bool even a reference type??
|
||||||
end
|
end
|
||||||
|
|
||||||
local isFargothActive = obj.id == "fargoth" and fargothCheck() or false
|
local isFargothActive = obj.id:match("fargoth") and fargothCheck() or false
|
||||||
|
|
||||||
-- todo: non mwscript version of this
|
-- todo: non mwscript version of this
|
||||||
local isWerewolf = mwscript.getSpellEffects({reference = npc, spell = "werewolf vision"})
|
local isWerewolf = mwscript.getSpellEffects({reference = npc, spell = "werewolf vision"})
|
||||||
|
@ -363,7 +377,7 @@ local function isIgnoredNPC(npc)
|
||||||
obj.name, npc.object.id, npc.object.baseObject and npc.object.baseObject.id or "nil", --
|
obj.name, npc.object.id, npc.object.baseObject and npc.object.baseObject.id or "nil", --
|
||||||
config.ignored[string.lower(obj.id)], obj.sourceMod, config.ignored[string.lower(obj.sourceMod)], --
|
config.ignored[string.lower(obj.id)], obj.sourceMod, config.ignored[string.lower(obj.sourceMod)], --
|
||||||
obj.isGuard, isDead, isVampire, isWerewolf, (obj.class and obj.class.id == "Dreamers"), --
|
obj.isGuard, isDead, isVampire, isWerewolf, (obj.class and obj.class.id == "Dreamers"), --
|
||||||
followers[obj.id], isHostile, obj.id == "fargoth" and "fargoth:" or "", obj.id == "fargoth" and isFargothActive or "")
|
followers[obj.id], isHostile, obj.id:match("fargoth") and "fargoth:" or "", obj.id:match("fargoth") and isFargothActive or "")
|
||||||
|
|
||||||
return config.ignored[string.lower(obj.id)] or --
|
return config.ignored[string.lower(obj.id)] or --
|
||||||
config.ignored[string.lower(obj.sourceMod)] or --
|
config.ignored[string.lower(obj.sourceMod)] or --
|
||||||
|
@ -380,6 +394,9 @@ end
|
||||||
-- checks NPC class and faction in cells for block list and adds to publicHouse list
|
-- checks NPC class and faction in cells for block list and adds to publicHouse list
|
||||||
-- todo: rewrite this
|
-- todo: rewrite this
|
||||||
local function isPublicHouse(cell)
|
local function isPublicHouse(cell)
|
||||||
|
-- only interior cells are public "houses"
|
||||||
|
if not isInteriorCell(cell) then return false end
|
||||||
|
|
||||||
local typeOfPub = pickPublicHouseType(cell.name)
|
local typeOfPub = pickPublicHouseType(cell.name)
|
||||||
local city, publicHouseName
|
local city, publicHouseName
|
||||||
|
|
||||||
|
@ -464,7 +481,7 @@ local function isIgnoredDoor(door, homeCellId)
|
||||||
for npc in door.destination.cell:iterateReferences(tes3.objectType.npc) do
|
for npc in door.destination.cell:iterateReferences(tes3.objectType.npc) do
|
||||||
if not isIgnoredNPC(npc) then
|
if not isIgnoredNPC(npc) then
|
||||||
hasOccupants = true
|
hasOccupants = true
|
||||||
-- break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -488,15 +505,6 @@ local function isIgnoredCell(cell)
|
||||||
return config.ignored[cell.id] or config.ignored[cell.sourceMod] -- or wilderness
|
return config.ignored[cell.id] or config.ignored[cell.sourceMod] -- or wilderness
|
||||||
end
|
end
|
||||||
|
|
||||||
local function isInteriorCell(cell)
|
|
||||||
if not cell then return end
|
|
||||||
|
|
||||||
log(common.logLevels.large, "Cell: interior: %s, behaves as exterior: %s therefore returning %s", cell.isInterior,
|
|
||||||
cell.behavesAsExterior, cell.isInterior and not cell.behavesAsExterior)
|
|
||||||
|
|
||||||
return cell.isInterior and not cell.behavesAsExterior
|
|
||||||
end
|
|
||||||
|
|
||||||
local function isCantonCell(cellName)
|
local function isCantonCell(cellName)
|
||||||
for _, str in pairs(waistworks) do if cellName:match(str) then return true end end
|
for _, str in pairs(waistworks) do if cellName:match(str) then return true end end
|
||||||
return false
|
return false
|
||||||
|
@ -521,13 +529,18 @@ end
|
||||||
|
|
||||||
-- travel agents, their steeds, and argonians stick around
|
-- travel agents, their steeds, and argonians stick around
|
||||||
local function isBadWeatherNPC(npc)
|
local function isBadWeatherNPC(npc)
|
||||||
if not npc.object then return end
|
local obj = npc.baseObject and npc.baseObject or npc.object
|
||||||
|
if not obj then return end
|
||||||
|
|
||||||
log(common.logLevels.large, "NPC Inclement Weather: %s is %s, %s", npc.object.name, npc.object.class.name,
|
log(common.logLevels.large, "NPC Inclement Weather: %s is %s, %s", npc.object.name, npc.object.class.name,
|
||||||
npc.object.race.id)
|
npc.object.race.id)
|
||||||
|
|
||||||
return npc.object.class.name == "Caravaner" or npc.object.class.name == "Gondolier" or npc.object.race.id ==
|
-- todo: better detection of NPCs who offer travel services
|
||||||
"Argonian"
|
-- found a rogue "shipmaster" in molag mar
|
||||||
|
return obj.class.name == "Caravaner" or
|
||||||
|
obj.class.name == "Gondolier" or
|
||||||
|
obj.class.name == "Shipmaster" or
|
||||||
|
obj.race.id == "Argonian"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- }}}
|
-- }}}
|
||||||
|
@ -539,7 +552,7 @@ local function checkEnteredNPCHome(cell)
|
||||||
if home then
|
if home then
|
||||||
local msg = string.format("Entering home of %s, %s", home.name, home.homeName)
|
local msg = string.format("Entering home of %s, %s", home.name, home.homeName)
|
||||||
log(common.logLevels.small, msg)
|
log(common.logLevels.small, msg)
|
||||||
message(msg)
|
-- message(msg) -- this one is mostly for debugging, so it doesn't need to be shown
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -553,7 +566,7 @@ local function checkEnteredPublicHouse(cell, city)
|
||||||
publicHouse.name, common.vowel(typeOfPub), typeOfPub:gsub("s$", ""), publicHouse.city,
|
publicHouse.name, common.vowel(typeOfPub), typeOfPub:gsub("s$", ""), publicHouse.city,
|
||||||
publicHouse.proprietor.object.name, publicHouse.proprietor.object.class)
|
publicHouse.proprietor.object.name, publicHouse.proprietor.object.class)
|
||||||
log(common.logLevels.small, msg)
|
log(common.logLevels.small, msg)
|
||||||
message(msg)
|
message(msg) -- this one is more informative, and not entirely for debugging, and reminiscent of Daggerfall's messages
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -616,6 +629,9 @@ end
|
||||||
|
|
||||||
-- search in a specific cell for moved NPCs
|
-- search in a specific cell for moved NPCs
|
||||||
local function checkForMovedNPCs(cell)
|
local function checkForMovedNPCs(cell)
|
||||||
|
-- NPCs don't get moved to exterior cells, so no need to check them for moved NPCs
|
||||||
|
if not isInteriorCell(cell) then return end
|
||||||
|
|
||||||
log(common.logLevels.medium, "Looking for moved NPCs in cell %s", cell.id)
|
log(common.logLevels.medium, "Looking for moved NPCs in cell %s", cell.id)
|
||||||
for npc in cell:iterateReferences(tes3.objectType.npc) do
|
for npc in cell:iterateReferences(tes3.objectType.npc) do
|
||||||
if npc.data and npc.data.NPCsGoHome then
|
if npc.data and npc.data.NPCsGoHome then
|
||||||
|
@ -641,7 +657,7 @@ local function processNPCs(cell)
|
||||||
-- todo: move this check somewhere else, so that disabled NPCs will be re-enabled even if the option is off
|
-- todo: move this check somewhere else, so that disabled NPCs will be re-enabled even if the option is off
|
||||||
if not config.disableNPCs then return end
|
if not config.disableNPCs then return end
|
||||||
|
|
||||||
log(common.logLevels.small, "Applying changes to NPCs in %s", cell.id)
|
log(common.logLevels.small, "Looking for NPCs to process in cell:%s", cell.id)
|
||||||
|
|
||||||
-- iterate NPCs in the cell, move them to their homes, and keep track of moved NPCs so we can move them back later
|
-- iterate NPCs in the cell, move them to their homes, and keep track of moved NPCs so we can move them back later
|
||||||
for npc in cell:iterateReferences(tes3.objectType.npc) do
|
for npc in cell:iterateReferences(tes3.objectType.npc) do
|
||||||
|
@ -696,7 +712,7 @@ end
|
||||||
local function processSiltStriders(cell)
|
local function processSiltStriders(cell)
|
||||||
if not config.disableNPCs then return end
|
if not config.disableNPCs then return end
|
||||||
|
|
||||||
log(common.logLevels.small, "Applying changes to silt striders in %s", cell.name)
|
log(common.logLevels.small, "Looking for silt striders to process in cell:%s", cell.name)
|
||||||
for activator in cell:iterateReferences(tes3.objectType.activator) do
|
for activator in cell:iterateReferences(tes3.objectType.activator) do
|
||||||
log(common.logLevels.large, "Is %s a silt strider??", activator.object.id)
|
log(common.logLevels.large, "Is %s a silt strider??", activator.object.id)
|
||||||
if activator.object.id:match("siltstrider") then
|
if activator.object.id:match("siltstrider") then
|
||||||
|
@ -723,7 +739,7 @@ end
|
||||||
local function processDoors(cell)
|
local function processDoors(cell)
|
||||||
if not config.lockDoors then return end
|
if not config.lockDoors then return end
|
||||||
|
|
||||||
log(common.logLevels.small, "Applying changes to doors in %s", cell.id)
|
log(common.logLevels.small, "Looking for doors to process in cell:%s", cell.id)
|
||||||
|
|
||||||
for door in cell:iterateReferences(tes3.objectType.door) do
|
for door in cell:iterateReferences(tes3.objectType.door) do
|
||||||
if not door.data.NPCsGoHome then door.data.NPCsGoHome = {} end
|
if not door.data.NPCsGoHome then door.data.NPCsGoHome = {} end
|
||||||
|
@ -747,7 +763,7 @@ local function processDoors(cell)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- only unlock doors that we locked before
|
-- only unlock doors that we locked before
|
||||||
if door.data.NPCsGoHome and door.data.NPCsGoHome.modified then
|
if door.data.NPCsGoHome.modified then
|
||||||
door.data.NPCsGoHome.modified = false
|
door.data.NPCsGoHome.modified = false
|
||||||
|
|
||||||
tes3.setLockLevel({reference = door, level = 0})
|
tes3.setLockLevel({reference = door, level = 0})
|
||||||
|
@ -768,12 +784,7 @@ local function applyChanges(cell)
|
||||||
|
|
||||||
-- build our followers list
|
-- build our followers list
|
||||||
for friend in tes3.iterate(tes3.mobilePlayer.friendlyActors) do
|
for friend in tes3.iterate(tes3.mobilePlayer.friendlyActors) do
|
||||||
local obj
|
local obj = friend.baseObject and friend.baseObject or friend.object
|
||||||
if friend.object.baseObject then
|
|
||||||
obj = friend.object.baseObject
|
|
||||||
else
|
|
||||||
obj = friend.object
|
|
||||||
end
|
|
||||||
|
|
||||||
if friend ~= tes3.mobilePlayer then
|
if friend ~= tes3.mobilePlayer then
|
||||||
followers[obj.id] = true
|
followers[obj.id] = true
|
||||||
|
|
Loading…
Reference in a new issue