Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 58 additions & 10 deletions scripts/field/VineScanner.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ end

function VineScanner:setup()
self.vineSystem = g_currentMission.vineSystem
self.orchardRows = {}
end

function VineScanner:foundVines()
Expand Down Expand Up @@ -43,6 +44,7 @@ end
---@return table|nil closest vine node
---@return Placeable|nil closest placeable
function VineScanner:getVineNodesOnField(vertices, tx, tz, isCustomField)
self.orchardRows = {}
if vertices == nil or next(vertices) == nil or tx == nil or tz == nil then
self.lines = nil
self.width = nil
Expand All @@ -61,14 +63,17 @@ function VineScanner:getVineNodesOnField(vertices, tx, tz, isCustomField)
for node, placeable in pairs(self.vineSystem.nodes) do
x, _, z = getWorldTranslation(node)
if CpMathUtil.isPointInPolygon(vertices, x, z) then
segment = self:getVineSegmentIxForNode(node, placeable.spec_vine.vineSegments)
table.insert(vineSegments, segment)
dist = MathUtil.vector2Length(x-tx, z-tz)
if dist < closestDist then
closestSegment = self:getVineSegmentIxForNode(node, placeable.spec_vine.vineSegments)
closestPlaceable = placeable
closestNode = node
closestDist = dist
local placeableSegments = self:getVineSegmentsAndWidth(placeable)
segment = placeableSegments and self:getVineSegmentIxForNode(node, placeableSegments)
if segment then
table.insert(vineSegments, segment)
dist = MathUtil.vector2Length(x-tx, z-tz)
if dist < closestDist then
closestSegment = segment
closestPlaceable = placeable
closestNode = node
closestDist = dist
end
end
end
end
Expand Down Expand Up @@ -147,7 +152,8 @@ function VineScanner:findVineNodesInField(vertices, tx, tz, isCustomField)


self.lines = newLines
self.width = closestPlaceable.spec_vine.width
local _, width = self:getVineSegmentsAndWidth(closestPlaceable)
self.width = width

self:debug("Found %d number of lines for a width of %.2f", #self.lines, self.width)

Expand Down Expand Up @@ -189,7 +195,7 @@ end
---@return table right lines
function VineScanner:separateIntoColumns(lines, closestNode)
local placeable = self.vineSystem.nodes[closestNode]
local width = placeable.spec_vine.width
local _, width = self:getVineSegmentsAndWidth(placeable)
local columnsLeft = {}
local columnsRight = {}
--- Left columns
Expand Down Expand Up @@ -407,6 +413,48 @@ function VineScanner:getLines()
return self.lines
end

--- Gets the vine segments and the row spacing of a placeable in the vine system.
--- The coffee plantation of the Beans & Alpacas DLC has no spec_vine, its fence segments
--- hold the vine nodes and the spacing comes from getOrchardRowSpacing().
--- These are converted into the spec_vine layout once per scan.
---@param placeable table
---@return table|nil vine segments
---@return number|nil row spacing
function VineScanner:getVineSegmentsAndWidth(placeable)
if placeable.spec_vine then
return placeable.spec_vine.vineSegments, placeable.spec_vine.width
end
self.orchardRows = self.orchardRows or {}
local rows = self.orchardRows[placeable]
if rows == nil then
rows = {}
self.orchardRows[placeable] = rows
local fence = placeable.getFence and placeable:getFence()
local width = placeable.getOrchardRowSpacing and placeable:getOrchardRowSpacing()
if fence == nil or type(fence.segments) ~= "table" or type(width) ~= "number" or width <= 0 then
self:debug("Placeable of type %s in the vine system has no vine rows, ignoring it.", tostring(placeable.typeName))
return
end
local vineSegments = {}
for _, fenceSegment in ipairs(fence.segments) do
if fenceSegment.vineNodes and fenceSegment.getStartPos and fenceSegment.getEndPos then
local x1, _, z1 = fenceSegment:getStartPos()
local x2, _, z2 = fenceSegment:getEndPos()
if x1 and z1 and x2 and z2 then
local nodes = {}
for node, _ in pairs(fenceSegment.vineNodes) do
table.insert(nodes, {node = node})
end
vineSegments[{x1 = x1, z1 = z1, x2 = x2, z2 = z2}] = nodes
end
end
end
rows.vineSegments = vineSegments
rows.width = width
end
return rows.vineSegments, rows.width
end

--- Gets a segment for a vine node.
function VineScanner:getVineSegmentIxForNode(node, vineSegments)
for segment, nodes in pairs(vineSegments) do
Expand Down