76 | function Leveler:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
77 | local spec = self.spec_leveler |
78 | |
79 | if self.isClient then |
80 | local fillType = self:getFillUnitFillType(spec.fillUnitIndex) |
81 | local fillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex) |
82 | local visible = fillLevel > 2*g_densityMapHeightManager:getMinValidLiterValue(fillType) |
83 | if visible and fillType ~= FillType.UNKNOWN then |
84 | g_effectManager:setFillType(spec.effects, fillType) |
85 | g_effectManager:startEffects(spec.effects) |
86 | |
87 | local fillPercentage = fillLevel / self:getFillUnitCapacity(spec.fillUnitIndex) |
88 | for _, effect in pairs(spec.effects) do |
89 | effect:setFillLevel(fillPercentage) |
90 | effect:setLastVehicleSpeed(self.movingDirection * self:getLastSpeed()) |
91 | end |
92 | else |
93 | g_effectManager:stopEffects(spec.effects) |
94 | end |
95 | end |
96 | |
97 | if self.isServer then |
98 | for _, levelerNode in pairs(spec.nodes) do |
99 | local x0,y0,z0 = localToWorld(levelerNode.node, -levelerNode.width, 0, levelerNode.maxDropDirOffset) |
100 | local x1,y1,z1 = localToWorld(levelerNode.node, levelerNode.width, 0, levelerNode.maxDropDirOffset) |
101 | if not g_farmlandManager:getIsOwnedByFarmAtWorldPosition(self:getOwnerFarmId(), x0, z0) or |
102 | not g_farmlandManager:getIsOwnedByFarmAtWorldPosition(self:getOwnerFarmId(), x1, z1) then |
103 | break |
104 | end |
105 | |
106 | local pickedUpFillLevel = 0 |
107 | local fillType = self:getFillUnitFillType(spec.fillUnitIndex) |
108 | local fillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex) |
109 | |
110 | if fillType == FillType.UNKNOWN or fillLevel < g_densityMapHeightManager:getMinValidLiterValue(fillType) + 0.001 then |
111 | local newFillType = DensityMapHeightUtil.getFillTypeAtLine(x0,y0,z0, x1,y1,z1, 0.5*levelerNode.maxDropDirOffset) |
112 | if newFillType ~= FillType.UNKNOWN and newFillType ~= fillType then |
113 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -math.huge) |
114 | fillType = newFillType |
115 | end |
116 | end |
117 | local heightType = g_densityMapHeightManager:getDensityMapHeightTypeByFillTypeIndex(fillType) |
118 | |
119 | if fillType ~= FillType.UNKNOWN and heightType ~= nil then |
120 | local innerRadius = 0 |
121 | local outerRadius = DensityMapHeightUtil.getDefaultMaxRadius(fillType) |
122 | local capacity = self:getFillUnitCapacity(spec.fillUnitIndex) |
123 | |
124 | -- pick up at node |
125 | if self:getIsLevelerPickupNodeActive(levelerNode) then |
126 | if spec.pickUpDirection == self.movingDirection then |
127 | local sx,sy,sz = localToWorld(levelerNode.node, -levelerNode.width, 0, 0) |
128 | local ex,ey,ez = localToWorld(levelerNode.node, levelerNode.width, 0, 0) |
129 | |
130 | fillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex) |
131 | local delta = -(capacity-fillLevel) |
132 | local numHeightLimitChecks = levelerNode.numHeightLimitChecks |
133 | if numHeightLimitChecks > 0 then |
134 | local movementY = 0 |
135 | for i=0,numHeightLimitChecks do |
136 | local t = i/numHeightLimitChecks |
137 | local xi = sx + (ex-sx)*t |
138 | local yi = sy + (ey-sy)*t |
139 | local zi = sz + (ez-sz)*t |
140 | local hi = DensityMapHeightUtil.getHeightAtWorldPos(xi,yi,zi) |
141 | movementY = math.max(movementY, hi-0.05 - yi) -- limit to 5cm below surface |
142 | end |
143 | if movementY > 0 then |
144 | sy = sy+movementY |
145 | ey = ey+movementY |
146 | end |
147 | end |
148 | |
149 | levelerNode.lastPickUp, levelerNode.lineOffsetPickUp = DensityMapHeightUtil.tipToGroundAroundLine(self, delta, fillType, sx,sy-0.1,sz, ex,ey-0.1,ez, innerRadius, outerRadius, levelerNode.lineOffsetPickUp, true, nil) |
150 | |
151 | if levelerNode.lastPickUp < 0 then |
152 | levelerNode.lastPickUp = levelerNode.lastPickUp + spec.litersToPickup |
153 | spec.litersToPickup = 0 |
154 | |
155 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -levelerNode.lastPickUp, fillType, ToolType.UNDEFINED, nil) |
156 | pickedUpFillLevel = levelerNode.lastPickUp |
157 | end |
158 | end |
159 | end |
160 | |
161 | -- drop at node |
162 | fillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex) |
163 | if fillLevel > 0 then |
164 | local f = (fillLevel/capacity) |
165 | local width = MathUtil.lerp(levelerNode.minDropWidth, levelerNode.maxDropWidth, f) |
166 | |
167 | local sx,sy,sz = localToWorld(levelerNode.node, -width, 0, 0) |
168 | local ex,ey,ez = localToWorld(levelerNode.node, width, 0, 0) |
169 | |
170 | local yOffset = -0.1 -0.05 |
171 | |
172 | levelerNode.lastDrop1, levelerNode.lineOffsetDrop1 = DensityMapHeightUtil.tipToGroundAroundLine(self, fillLevel, fillType, sx,sy+yOffset,sz, ex,ey+yOffset,ez, innerRadius, outerRadius, levelerNode.lineOffsetDrop1, true, tipOcclusionAreas) |
173 | if levelerNode.lastDrop1 > 0 then |
174 | local leftOver = fillLevel - levelerNode.lastDrop1 |
175 | if leftOver <= g_densityMapHeightManager:getMinValidLiterValue(fillType) then |
176 | levelerNode.lastDrop1 = fillLevel |
177 | spec.litersToPickup = spec.litersToPickup + leftOver |
178 | end |
179 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -levelerNode.lastDrop1, fillType, ToolType.UNDEFINED, nil) |
180 | end |
181 | end |
182 | |
183 | -- drop further at front |
184 | fillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex) |
185 | |
186 | if fillLevel > 0 then |
187 | local f = (fillLevel/capacity) |
188 | local width = MathUtil.lerp(levelerNode.minDropWidth, levelerNode.maxDropWidth, f) |
189 | |
190 | local yOffset = MathUtil.lerp(levelerNode.minDropHeight, levelerNode.maxDropHeight, f) |
191 | |
192 | local sx,sy,sz = localToWorld(levelerNode.node, -width, 0, 0) |
193 | local ex,ey,ez = localToWorld(levelerNode.node, width, 0, 0) |
194 | local dx,dy,dz = localDirectionToWorld(levelerNode.node, 0, 0, 1) |
195 | |
196 | local backOffset = -outerRadius * spec.pickUpDirection * 1.5 |
197 | local backLen = MathUtil.lerp(levelerNode.minDropDirOffset, levelerNode.maxDropDirOffset, f) - backOffset |
198 | |
199 | local backX,backY,backZ = dx*backOffset,dy*backOffset,dz*backOffset |
200 | dx,dy,dz = dx*backLen,dy*backLen,dz*backLen |
201 | |
202 | local terrainHeightUpdater = g_densityMapHeightManager:getTerrainDetailHeightUpdater() |
203 | if terrainHeightUpdater ~= nil then |
204 | addDensityMapHeightOcclusionArea(terrainHeightUpdater, sx+backX,sy+backY,sz+backZ, ex-sx,ey-sy,ez-sz, dx, dy, dz, true) |
205 | if width < levelerNode.width-0.05 then |
206 | -- fully block left and right of the inner block area |
207 | local sx2,sy2,sz2 = localToWorld(levelerNode.node, -levelerNode.width, 0, 0) |
208 | local ex2,ey2,ez2 = localToWorld(levelerNode.node, levelerNode.width, 0, 0) |
209 | |
210 | addDensityMapHeightOcclusionArea(terrainHeightUpdater, sx2+backX,sy2+backY,sz2+backZ, sx-sx2,sy-sy2,sz-sz2, dx, dy, dz, false) |
211 | addDensityMapHeightOcclusionArea(terrainHeightUpdater, ex +backX,ey +backY,ez +backZ, ex2-ex,ey2-ey,ez2-ez, dx, dy, dz, false) |
212 | end |
213 | end |
214 | |
215 | levelerNode.lastDrop2, levelerNode.lineOffsetDrop2 = DensityMapHeightUtil.tipToGroundAroundLine(self, fillLevel, fillType, sx,sy+yOffset,sz, ex,ey+yOffset,ez, 0, outerRadius, levelerNode.lineOffsetDrop2, true, nil) |
216 | if levelerNode.lastDrop2 > 0 then |
217 | local leftOver = fillLevel - levelerNode.lastDrop2 |
218 | if leftOver <= g_densityMapHeightManager:getMinValidLiterValue(fillType) then |
219 | levelerNode.lastDrop2 = fillLevel |
220 | spec.litersToPickup = spec.litersToPickup + leftOver |
221 | end |
222 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -levelerNode.lastDrop2, fillType, ToolType.UNDEFINED, nil) |
223 | end |
224 | end |
225 | end |
226 | |
227 | -- call fill level changed callack to inform bunker silo about change |
228 | if pickedUpFillLevel < 0 and fillType ~= FillType.UNKNOWN then |
229 | self:notifiyBunkerSilo(pickedUpFillLevel, fillType) |
230 | end |
231 | end |
232 | end |
233 | end |