Skip to content

Commit

Permalink
Add "Find Subjects" button to painting menu
Browse files Browse the repository at this point in the history
Fix occasional crash when painting from inventory

Add cell and region filters to painting interops
  • Loading branch information
jhaakma committed Jul 26, 2024
1 parent 9f5a9b7 commit f1eb571
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 85 deletions.
2 changes: 1 addition & 1 deletion Data Files/MWSE/mods/mer/joyOfPainting/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ config.skillProgress = {
}
---Configs for subject mechanics
config.subject = {
MINIMUM_PRESENCE = 0.01,
MINIMUM_PRESENCE = 0.005,
MINIMUM_VISIBILITY = 0.1,
}

Expand Down
58 changes: 43 additions & 15 deletions Data Files/MWSE/mods/mer/joyOfPainting/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ Interop.Subject = require("mer.joyOfPainting.items.Subject")
---

---@class JOP.Interop.paintingFilter
---@field reference tes3reference? (Default: tes3.player) The reference to check for a painting
---@field objectId string? If provided, checks for a painting with a subject with the specified objectId
---@field subjectIds string[]? If provided, checks for a painting with the specified subjectIds
---@field artStyle string? If provided, only checks for paintings with the specified artStyle
---@field canvasType "paper"|"canvas" If provided, only checks for paintings with the specified canvasType
---@field reference tes3reference? (Default: tes3.player) The reference to check for a painting
---@field cellId string? If provided, only checks for paintings in the specified cell
---@field regionId string? If provided, only checks for paintings in the specified region


---Check if the itemData is a painting
Expand All @@ -44,6 +46,46 @@ local function isPainting(item, itemData, e)
end
end

--Check artStyle
if e.artStyle then
if painting.data.artStyle ~= e.artStyle then
return false
end
end

--Check canvasType
if e.canvasType then
if e.canvasType ~= painting:getCanvasType() then
return false
end
end

--Check cell/region
local location = painting.data.location
if e.cellId or e.regionId then
logger:debug("Checking location")
if type(location) == "table" then
if e.cellId then
logger:debug("Checking cellId %s", e.cellId)
if location.cellId ~= e.cellId:lower() then
logger:debug("CellId doesn't match")
return false
end
end
if e.regionId then
logger:debug("Checking regionId %s", e.regionId)
if location.regionId ~= e.regionId:lower() then
logger:debug("RegionId doesn't match")
return false
end
end
else
logger:debug("No location data")
return false
end
logger:debug("Location matches")
end

--Check subjectIds
if e.subjectIds then
logger:debug("Checking subjectIds")
Expand Down Expand Up @@ -71,20 +113,6 @@ local function isPainting(item, itemData, e)
end
end

--Check artStyle
if e.artStyle then
if painting.data.artStyle ~= e.artStyle then
return false
end
end

--Check canvasType
if e.canvasType then
if e.canvasType ~= painting:getCanvasType() then
return false
end
end

return true
end

Expand Down
30 changes: 23 additions & 7 deletions Data Files/MWSE/mods/mer/joyOfPainting/interops/subject.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
local Subject = require("mer.joyOfPainting.items.Subject")
local Subject = require("mer.joyOfPainting").Subject

---@type JOP.Subject.registerSubjectParams[]
local subjects = {
{
id = "fargoth",
objectIds = {"fargoth"},
},
--Subjects by objectType
{
id = "npc",
requirements = function(e)
Expand All @@ -18,14 +15,33 @@ local subjects = {
return e.reference.baseObject.objectType == tes3.objectType.creature
end
},
{
id = "activator",
requirements = function(e)
return e.reference.baseObject.objectType == tes3.objectType.activator
and e.reference.object.name ~= nil
and e.reference.object.name ~= ""
end
},

--Points of Interest
{
id = "lighthouse",
name = "Lighthouse",
objectIds = {"ex_common_lighthouse"},
},
{
id = "a_siltstrider",
objectIds = {"a_siltstrider"},
id = "skar",
name = "Skar",
objectIds = {"ex_ar_01"},
},
{
id = "dwarventower",
name = "Dwarven Tower",
objectIds = {
"ex_dwrv_ruin_tower00",
"AB_Ex_DwrvTower00Intact",
},
}
}

Expand Down
2 changes: 1 addition & 1 deletion Data Files/MWSE/mods/mer/joyOfPainting/items/Easel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ function Easel:paint(artStyle)
if self:getCanvasConfig() then
timer.delayOneFrame(function()
PhotoMenu:new{
getCanvasConfig = function()
getCanvasConfig = function(_)
return self:getCanvasConfig()
end,
artStyle = config.artStyles[artStyle],
Expand Down
38 changes: 22 additions & 16 deletions Data Files/MWSE/mods/mer/joyOfPainting/items/Painting.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ local meshService = require("mer.joyOfPainting.services.MeshService")
---| '"canvas"'

---@class JOP.Painting.location
---@field cellId string
---@field cellName string
---@field position tes3vector3
---@field cellId string?
---@field regionId string?
---@field cellName string?
---@field position tes3vector3?

---@class JOP.Painting.data
---@field canvasId string
---@field canvasType string
---@field paintingId string
---@field paintingTexture string
---@field paintingName string
---@field location JOP.Painting.location
---@field location JOP.Painting.location | string
---@field artStyle string The name of the artStyle
---@field subjects table<string, JOP.SubjectService.Result>

Expand Down Expand Up @@ -132,13 +133,22 @@ function Painting:new(e)
local painting = setmetatable({}, self)
logger:assert(e.reference ~= nil or e.item ~= nil,
"Painting:new() requires either a reference or an item")

painting.reference = e.reference
painting.item = e.item or e.reference.object
painting.dataHolder = e.itemData or e.reference
painting.id = painting.item.id:lower()

local safeRef
if e.reference then
safeRef = tes3.makeSafeObjectHandle(e.reference)
end

-- reference data
painting.data = setmetatable({}, {
__index = function(_, k)
if safeRef and not safeRef:valid() then return end

if painting.reference then
if not painting.reference.supportsLuaData then
return nil
Expand All @@ -154,6 +164,7 @@ function Painting:new(e)
return painting.dataHolder.data.joyOfPainting[k]
end,
__newindex = function(_, k, v)
if safeRef and not safeRef:valid() then return end
if painting.reference then
logger:debug("Setting data field %s from reference %s", k, painting.reference.id)
if not painting.reference.supportsLuaData then
Expand Down Expand Up @@ -258,10 +269,10 @@ function Painting:clearCanvas()
end

---comment
---@param location JOP.Painting.location
---@param subjects table<string, JOP.SubjectService.Result>
---@param location string|JOP.Painting.location
---@param results table<string, JOP.SubjectService.Result>
---@return string
function Painting.createTooltipText(location, subjects)
function Painting.createTooltipText(location, results)
--legacy paintings with string location
if type(location) == "string" then
location = {
Expand All @@ -270,16 +281,11 @@ function Painting.createTooltipText(location, subjects)
end

local message = string.format("Location: %s", location.cellName)
if subjects then
if results and table.size(results) > 0 then
message = message .. "\nSubjects:"
for objectId, result in pairs(subjects) do
for subjectId in pairs(result.subjectIds) do
local subject = Subject.getSubject(subjectId)
if subject then
message = string.format("%s\n - %s", message, subject.getName{ objectId = objectId })
break
end
end
local subjectNames = Subject.getSubjectNames(results)
for subjectName in pairs(subjectNames) do
message = message .. "\n - " .. subjectName
end
end
return message
Expand Down
17 changes: 17 additions & 0 deletions Data Files/MWSE/mods/mer/joyOfPainting/items/Subject.lua
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,28 @@ function Subject.registerSubject(e)
end
end


function Subject.getSubject(id)
return config.subjects[id:lower()]
end


---@param results table<string, JOP.SubjectService.Result>
---@return table<string, boolean>
function Subject.getSubjectNames(results)
local subjectNames = {}
for objectId, result in pairs(results) do
for subjectId in pairs(result.subjectIds) do
local subject = Subject.getSubject(subjectId)
if subject then
subjectNames[subject.getName{ objectId = objectId }] = true
break
end
end
end
return subjectNames
end


---Get a list of subjects this reference is valid for
---@param reference tes3reference
Expand Down
Loading

0 comments on commit f1eb571

Please sign in to comment.
  翻译: