569 | function Bale:applyBaleAttributes(attributes) |
570 | self:setOwnerFarmId(attributes.farmId or AccessHandler.EVERYONE) |
571 | |
572 | self:setFillLevel(attributes.fillLevel or self.fillLevel) |
573 | if attributes.fillTypeName ~= nil then |
574 | local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(attributes.fillTypeName) |
575 | self:setFillType(fillTypeIndex or self.fillType) |
576 | elseif attributes.fillType ~= nil then |
577 | self:setFillType(attributes.fillType) |
578 | end |
579 | |
580 | self:setWrapTextures(attributes.wrapDiffuse, attributes.wrapNormal) |
581 | |
582 | self:setWrappingState(attributes.wrappingState, false) |
583 | self:setColor(unpack(attributes.wrappingColor)) |
584 | |
585 | self.baleValueScale = attributes.baleValueScale or self.baleValueScale |
586 | self.isMissionBale = Utils.getNoNil(attributes.isMissionBale, self.isMissionBale) |
587 | |
588 | if self.isServer then |
589 | if attributes.isFermenting then |
590 | local fillTypeInfo = self:getFillTypeInfo(self.fillType) |
591 | if fillTypeInfo ~= nil and fillTypeInfo.fermenting ~= nil then |
592 | local maxTime = fillTypeInfo.fermenting.time * (24 * 60 * 60 * 1000) -- days / months |
593 | |
594 | -- while bale is produced from a mission field we ferment instantly so it can be sold directly |
595 | if self.isMissionBale then |
596 | maxTime = 0 |
597 | end |
598 | |
599 | g_baleManager:registerFermentation(self, attributes.fermentationTime, maxTime) |
600 | self.isFermenting = true |
601 | self:raiseDirtyFlags(self.fermentingDirtyFlag) |
602 | end |
603 | end |
604 | end |
605 | |
606 | return true |
607 | end |
1149 | function Bale.createDummyBale(xmlFilename, fillTypeIndex) |
1150 | local xmlFile = XMLFile.load("TempBale", xmlFilename, BaleManager.baleXMLSchema) |
1151 | |
1152 | local baleId, baleRoot, sharedLoadRequestId |
1153 | local i3dFilename = xmlFile:getValue("bale.filename") |
1154 | if i3dFilename ~= nil then |
1155 | local _, baseDirectory = Utils.getModNameAndBaseDirectory(xmlFilename) |
1156 | i3dFilename = Utils.getFilename(i3dFilename, baseDirectory) |
1157 | |
1158 | baleRoot, sharedLoadRequestId = g_i3DManager:loadSharedI3DFile(i3dFilename, false, false) |
1159 | if baleRoot ~= 0 then |
1160 | baleId = getChildAt(baleRoot, 0) |
1161 | setRigidBodyType(baleId, RigidBodyType.NONE) |
1162 | unlink(baleId) |
1163 | |
1164 | local fillTypes = {} |
1165 | Bale.loadFillTypesFromXML(fillTypes, xmlFile, baseDirectory) |
1166 | Bale.setFillTypeTextures(baleId, fillTypes, fillTypeIndex) |
1167 | local meshes = Bale.loadVisualMeshesFromXML(baleId, xmlFile, baseDirectory) |
1168 | Bale.updateVisualMeshVisibility(meshes, fillTypeIndex, false) |
1169 | |
1170 | delete(baleRoot) |
1171 | end |
1172 | end |
1173 | |
1174 | xmlFile:delete() |
1175 | |
1176 | return baleId, sharedLoadRequestId |
1177 | end |
89 | function Bale:delete() |
90 | if self.sharedLoadRequestId ~= nil then |
91 | g_i3DManager:releaseSharedI3DFile(self.sharedLoadRequestId) |
92 | self.sharedLoadRequestId = nil |
93 | end |
94 | |
95 | g_currentMission.activatableObjectsSystem:removeActivatable(self.activatable) |
96 | |
97 | if self.isFermenting then |
98 | g_baleManager:removeFermentation(self) |
99 | end |
100 | |
101 | self:setBaleAIObstacle(false) |
102 | |
103 | g_currentMission.slotSystem:removeLimitedObject(SlotSystem.LIMITED_OBJECT_BALE, self) |
104 | |
105 | unregisterObjectClassName(self) |
106 | g_currentMission.itemSystem:removeItemToSave(self) |
107 | Bale:superClass().delete(self) |
108 | end |
1109 | function Bale:doDensityMapItemAreaUpdate(func, target, ...) |
1110 | local gridSize = 0.25 |
1111 | if self.isRoundbale then |
1112 | local x, _, z = getWorldTranslation(self.nodeId) |
1113 | |
1114 | local sizeFactor = 0.4 -- using 40% since it's applied with rounding mode inclusive |
1115 | local x0, z0 = x + self.width * sizeFactor, z + self.width * sizeFactor |
1116 | local x1, z1 = x - self.width * sizeFactor, z + self.width * sizeFactor |
1117 | local x2, z2 = x + self.width * sizeFactor, z - self.width * sizeFactor |
1118 | |
1119 | func(target, x0 + gridSize, z0 + gridSize, x1 + gridSize, z1 + gridSize, x2 + gridSize, z2 + gridSize, ...) |
1120 | else |
1121 | local sizeFactor = 0.4 -- using 40% since it's applied with rounding mode inclusive |
1122 | local x0, _, z0 = localToWorld(self.nodeId, self.width * sizeFactor, self.height * sizeFactor, self.length * sizeFactor) |
1123 | local x1, _, z1 = localToWorld(self.nodeId, -self.width * sizeFactor, -self.height * sizeFactor, self.length * sizeFactor) |
1124 | local x2, _, z2 = localToWorld(self.nodeId, self.width * sizeFactor, self.height * sizeFactor, -self.length * sizeFactor) |
1125 | |
1126 | func(target, x0 + gridSize, z0 + gridSize, x1 + gridSize, z1 + gridSize, x2 + gridSize, z2 + gridSize, ...) |
1127 | end |
1128 | end |
544 | function Bale:getBaleAttributes() |
545 | local attributes = {} |
546 | |
547 | attributes.xmlFilename = self.xmlFilename |
548 | attributes.farmId = self:getOwnerFarmId() |
549 | attributes.fillLevel = self.fillLevel |
550 | attributes.fillType = self.fillType |
551 | attributes.wrapDiffuse = self.wrapDiffuse |
552 | attributes.wrapNormal = self.wrapNormal |
553 | attributes.supportsWrapping = self.supportsWrapping |
554 | attributes.wrappingState = self.wrappingState |
555 | attributes.wrappingColor = self.wrappingColor |
556 | attributes.baleValueScale = self.baleValueScale |
557 | attributes.isMissionBale = self.isMissionBale |
558 | |
559 | attributes.isFermenting = self.isFermenting |
560 | if self.isFermenting then |
561 | attributes.fermentationTime = g_baleManager:getFermentationTime(self) or 0 |
562 | end |
563 | |
564 | return attributes |
565 | end |
430 | function Bale:loadBaleAttributesFromXML(xmlFile) |
431 | local triggerId = xmlFile:getValue("bale.mountableObject#triggerNode", nil, self.nodeId) |
432 | local forceAcceleration = xmlFile:getValue("bale.mountableObject#forceAcceleration", 4) |
433 | local forceLimitScale = xmlFile:getValue("bale.mountableObject#forceLimitScale", 1) |
434 | local axisFreeY = xmlFile:getValue("bale.mountableObject#axisFreeY", false) |
435 | local axisFreeX = xmlFile:getValue("bale.mountableObject#axisFreeX", false) |
436 | self:setMountableObjectAttributes(triggerId, forceAcceleration, forceLimitScale, axisFreeY, axisFreeX) |
437 | |
438 | self.fillTypes = {} |
439 | Bale.loadFillTypesFromXML(self.fillTypes, xmlFile, self.baseDirectory) |
440 | |
441 | self.isRoundbale = xmlFile:getValue("bale.size#isRoundbale", true) |
442 | self.width = MathUtil.round(xmlFile:getValue("bale.size#width", 0), 2) |
443 | self.height = MathUtil.round(xmlFile:getValue("bale.size#height", 0), 2) |
444 | self.length = MathUtil.round(xmlFile:getValue("bale.size#length", 0), 2) |
445 | self.diameter = MathUtil.round(xmlFile:getValue("bale.size#diameter", 0), 2) |
446 | |
447 | self.centerOffsetX, self.centerOffsetY, self.centerOffsetZ = 0, 0, 0 |
448 | |
449 | self.uvId = xmlFile:getValue("bale.uvId", "DEFAULT") |
450 | |
451 | self.meshes, self.tensionBeltMeshes = Bale.loadVisualMeshesFromXML(self.nodeId, xmlFile, self.baseDirectory) |
452 | |
453 | return true |
454 | end |
514 | function Bale.loadBaleAttributesFromXMLFile(attributes, xmlFile, key, resetVehicles) |
515 | attributes.farmId = xmlFile:getValue(key .. "#farmId", AccessHandler.EVERYONE) |
516 | attributes.fillLevel = xmlFile:getValue(key.."#fillLevel") |
517 | attributes.fillTypeName = xmlFile:getValue(key.."#fillType") |
518 | |
519 | local wrapDiffuse = xmlFile:getValue(key..".textures#wrapDiffuse") |
520 | if wrapDiffuse ~= nil then |
521 | attributes.wrapDiffuse = NetworkUtil.convertFromNetworkFilename(wrapDiffuse) |
522 | end |
523 | |
524 | local wrapNormal = xmlFile:getValue(key..".textures#wrapNormal") |
525 | if wrapNormal ~= nil then |
526 | attributes.wrapNormal = NetworkUtil.convertFromNetworkFilename(wrapNormal) |
527 | end |
528 | |
529 | attributes.isFermenting = xmlFile:getValue(key..".fermentation#isFermenting", false) |
530 | attributes.fermentationTime = xmlFile:getValue(key..".fermentation#time", 0) |
531 | |
532 | attributes.wrappingState = xmlFile:getValue(key.."#wrappingState", 0) |
533 | attributes.wrappingColor = xmlFile:getValue(key.."#wrappingColor", {1, 1, 1, 1}, true) |
534 | |
535 | attributes.baleValueScale = xmlFile:getValue(key.."#valueScale", 1) |
536 | |
537 | attributes.isMissionBale = xmlFile:getValue(key.."#isMissionBale", false) |
538 | |
539 | return true |
540 | end |
1184 | function Bale.loadFillTypesFromXML(fillTypes, xmlFile, baseDirectory) |
1185 | xmlFile:iterate("bale.fillTypes.fillType", function(index, key) |
1186 | local fillTypeName = xmlFile:getValue(key .. "#name") |
1187 | local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeName) |
1188 | if fillTypeIndex ~= nil then |
1189 | local fillTypeInfo = {} |
1190 | fillTypeInfo.fillTypeIndex = fillTypeIndex |
1191 | fillTypeInfo.capacity = xmlFile:getValue(key .. "#capacity", 1000) |
1192 | fillTypeInfo.mass = xmlFile:getValue(key .. "#mass", 500) / 1000 |
1193 | fillTypeInfo.forceAcceleration = xmlFile:getValue(key .. "#forceAcceleration") |
1194 | fillTypeInfo.supportsWrapping = xmlFile:getValue(key .. "#supportsWrapping", false) |
1195 | |
1196 | local diffuseFilename = xmlFile:getValue(key .. ".diffuse#filename") |
1197 | if diffuseFilename ~= nil then |
1198 | fillTypeInfo.diffuseFilename = Utils.getFilename(diffuseFilename, baseDirectory) |
1199 | end |
1200 | local normalFilename = xmlFile:getValue(key .. ".normal#filename") |
1201 | if normalFilename ~= nil then |
1202 | fillTypeInfo.normalFilename = Utils.getFilename(normalFilename, baseDirectory) |
1203 | end |
1204 | local specularFilename = xmlFile:getValue(key .. ".specular#filename") |
1205 | if specularFilename ~= nil then |
1206 | fillTypeInfo.specularFilename = Utils.getFilename(specularFilename, baseDirectory) |
1207 | end |
1208 | local alphaFilename = xmlFile:getValue(key .. ".alpha#filename") |
1209 | if alphaFilename ~= nil then |
1210 | fillTypeInfo.alphaFilename = Utils.getFilename(alphaFilename, baseDirectory) |
1211 | end |
1212 | |
1213 | local outputFillTypeName = xmlFile:getValue(key .. ".fermenting#outputFillType") |
1214 | local outputFillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(outputFillTypeName) |
1215 | if outputFillTypeIndex ~= nil then |
1216 | fillTypeInfo.fermenting = {} |
1217 | fillTypeInfo.fermenting.outputFillTypeIndex = outputFillTypeIndex |
1218 | fillTypeInfo.fermenting.requiresWrapping = xmlFile:getValue(key .. ".fermenting#requiresWrapping", true) |
1219 | fillTypeInfo.fermenting.time = xmlFile:getValue(key .. ".fermenting#time", 0) |
1220 | end |
1221 | |
1222 | table.insert(fillTypes, fillTypeInfo) |
1223 | end |
1224 | end) |
1225 | end |
392 | function Bale:loadFromConfigXML(xmlFilename, x, y, z, rx, ry, rz) |
393 | if xmlFilename == nil or not fileExists(xmlFilename) then |
394 | return false |
395 | end |
396 | |
397 | local xmlFile = XMLFile.load("TempBale", xmlFilename, BaleManager.baleXMLSchema) |
398 | |
399 | self.xmlFilename = xmlFilename |
400 | self.customEnvironment, self.baseDirectory = Utils.getModNameAndBaseDirectory(self.xmlFilename) |
401 | |
402 | self.i3dFilename = xmlFile:getValue("bale.filename") |
403 | if self.i3dFilename ~= nil then |
404 | self.i3dFilename = Utils.getFilename(self.i3dFilename, self.baseDirectory) |
405 | |
406 | self:createNode(self.i3dFilename) |
407 | |
408 | if x ~= nil and y ~= nil and z ~= nil and ry ~= nil and ry ~= nil and rz ~= nil then |
409 | setTranslation(self.nodeId, x, y, z) |
410 | setRotation(self.nodeId, rx, ry, rz) |
411 | end |
412 | |
413 | if not self:loadBaleAttributesFromXML(xmlFile) then |
414 | return false |
415 | end |
416 | end |
417 | |
418 | xmlFile:delete() |
419 | |
420 | g_currentMission.itemSystem:addItemToSave(self) |
421 | |
422 | self:setBaleAIObstacle(true) |
423 | |
424 | return true |
425 | end |
484 | function Bale:loadFromXMLFile(xmlFile, key, resetVehicles) |
485 | local x, y, z = xmlFile:getValue(key.."#position") |
486 | local rx, ry, rz = xmlFile:getValue(key.."#rotation") |
487 | if x == nil or y == nil or z == nil or rx == nil or ry == nil or rz == nil then |
488 | return false |
489 | end |
490 | |
491 | local xmlFilename = xmlFile:getValue(key.."#filename") |
492 | if xmlFilename == nil then |
493 | return false |
494 | end |
495 | |
496 | xmlFilename = NetworkUtil.convertFromNetworkFilename(xmlFilename) |
497 | if not fileExists(xmlFilename) then |
498 | return false |
499 | end |
500 | |
501 | if not self:loadFromConfigXML(xmlFilename, x, y, z, rx, ry, rz) then |
502 | return false |
503 | end |
504 | |
505 | local attributes = {} |
506 | Bale.loadBaleAttributesFromXMLFile(attributes, xmlFile, key, resetVehicles) |
507 | self:applyBaleAttributes(attributes) |
508 | |
509 | return true |
510 | end |
1286 | function Bale.loadVisualMeshesFromXML(rootNode, xmlFile, baseDirectory) |
1287 | local meshes = {} |
1288 | local tensionBeltMeshes = {} |
1289 | xmlFile:iterate("bale.baleMeshes.baleMesh", function(index, key) |
1290 | local meshData = {} |
1291 | meshData.node = xmlFile:getValue(key .. "#node", nil, rootNode) |
1292 | meshData.supportsWrapping = xmlFile:getValue(key .. "#supportsWrapping", true) |
1293 | |
1294 | local fillTypeNames = xmlFile:getValue(key .. "#fillTypes") |
1295 | meshData.fillTypes = g_fillTypeManager:getFillTypesByNames(fillTypeNames) |
1296 | |
1297 | meshData.fillTypeVisibility = true |
1298 | |
1299 | meshData.isTensionBeltMesh = xmlFile:getValue(key .. "#isTensionBeltMesh", false) |
1300 | if meshData.isTensionBeltMesh then |
1301 | table.insert(tensionBeltMeshes, meshData.node) |
1302 | end |
1303 | |
1304 | table.insert(meshes, meshData) |
1305 | end) |
1306 | |
1307 | return meshes, tensionBeltMeshes |
1308 | end |
295 | function Bale:mount(object, node, x,y,z, rx,ry,rz) |
296 | Bale:superClass().mount(self, object, node, x,y,z, rx,ry,rz) |
297 | g_currentMission.itemSystem:removeItemToSave(self) |
298 | self:setBaleAIObstacle(false) |
299 | end |
323 | function Bale:mountKinematic(object, node, x,y,z, rx,ry,rz) |
324 | Bale:superClass().mountKinematic(self, object, node, x,y,z, rx,ry,rz) |
325 | g_currentMission.itemSystem:removeItemToSave(self) |
326 | self:setBaleAIObstacle(false) |
327 | end |
43 | function Bale.new(isServer, isClient, customMt) |
44 | local self = MountableObject.new(isServer, isClient, customMt or Bale_mt) |
45 | |
46 | self.forcedClipDistance = 300 |
47 | registerObjectClassName(self, "Bale") |
48 | |
49 | self.fillType = FillType.STRAW |
50 | self.fillLevel = 0 |
51 | |
52 | self.supportsWrapping = false |
53 | self.wrappingState = 0 |
54 | self.wrappingColor = {1, 1, 1, 1} |
55 | |
56 | self.baleValueScale = 1 |
57 | self.defaultMass = 0.25 |
58 | |
59 | self.isFermenting = false |
60 | self.fermentingPercentage = 0 |
61 | |
62 | self.canBeSold = true |
63 | self.allowPickup = true |
64 | |
65 | self.isMissionBale = false |
66 | |
67 | self.activatable = BaleActivatable.new(self) |
68 | |
69 | self.fillTypeDirtyFlag = self:getNextDirtyFlag() |
70 | self.fillLevelDirtyFlag = self:getNextDirtyFlag() |
71 | |
72 | self.texturesDirtyFlag = self:getNextDirtyFlag() |
73 | |
74 | self.wrapStateDirtyFlag = self:getNextDirtyFlag() |
75 | self.wrapColorDirtyFlag = self:getNextDirtyFlag() |
76 | |
77 | self.fermentingDirtyFlag = self:getNextDirtyFlag() |
78 | |
79 | self.obstacleNodeId = nil |
80 | self.sharedLoadRequestId = nil |
81 | |
82 | g_currentMission.slotSystem:addLimitedObject(SlotSystem.LIMITED_OBJECT_BALE, self) |
83 | |
84 | return self |
85 | end |
208 | function Bale:readStream(streamId, connection) |
209 | local xmlFilename = NetworkUtil.convertFromNetworkFilename(streamReadString(streamId)) |
210 | if self.nodeId == 0 then |
211 | self:loadFromConfigXML(xmlFilename) |
212 | end |
213 | |
214 | local fillLevel = streamReadFloat32(streamId) |
215 | self:setFillLevel(fillLevel) |
216 | |
217 | local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
218 | self:setFillType(fillType) |
219 | |
220 | if streamReadBool(streamId) then |
221 | local wrapDiffuse = NetworkUtil.convertFromNetworkFilename(streamReadString(streamId)) |
222 | self:setWrapTextures(wrapDiffuse, nil) |
223 | end |
224 | |
225 | if streamReadBool(streamId) then |
226 | local wrapNormal = NetworkUtil.convertFromNetworkFilename(streamReadString(streamId)) |
227 | self:setWrapTextures(nil, wrapNormal) |
228 | end |
229 | |
230 | Bale:superClass().readStream(self, streamId, connection) |
231 | g_currentMission.itemSystem:addItemToSave(self) |
232 | |
233 | self.baleValueScale = streamReadFloat32(streamId) |
234 | |
235 | self:setWrappingState(streamReadUInt8(streamId) / 255, false) |
236 | |
237 | local r = streamReadFloat32(streamId) |
238 | local g = streamReadFloat32(streamId) |
239 | local b = streamReadFloat32(streamId) |
240 | local a = streamReadFloat32(streamId) |
241 | self:setColor(r, g, b, a) |
242 | |
243 | self.isFermenting = streamReadBool(streamId) |
244 | if self.isFermenting then |
245 | self.fermentingPercentage = streamReadUInt8(streamId) / 255 |
246 | else |
247 | self.fermentingPercentage = 0 |
248 | end |
249 | end |
115 | function Bale:readUpdateStream(streamId, timestamp, connection) |
116 | if connection:getIsServer() then |
117 | if streamReadBool(streamId) then |
118 | local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
119 | self:setFillType(fillType) |
120 | end |
121 | |
122 | if streamReadBool(streamId) then |
123 | self:setFillLevel(streamReadFloat32(streamId)) |
124 | end |
125 | |
126 | if streamReadBool(streamId) then |
127 | if streamReadBool(streamId) then |
128 | local wrapDiffuse = NetworkUtil.convertFromNetworkFilename(streamReadString(streamId)) |
129 | self:setWrapTextures(wrapDiffuse, nil) |
130 | end |
131 | |
132 | if streamReadBool(streamId) then |
133 | local wrapNormal = NetworkUtil.convertFromNetworkFilename(streamReadString(streamId)) |
134 | self:setWrapTextures(nil, wrapNormal) |
135 | end |
136 | end |
137 | |
138 | if streamReadBool(streamId) then |
139 | self:setWrappingState(streamReadUInt8(streamId) / 255, false) |
140 | end |
141 | |
142 | if streamReadBool(streamId) then |
143 | local r = streamReadFloat32(streamId) |
144 | local g = streamReadFloat32(streamId) |
145 | local b = streamReadFloat32(streamId) |
146 | local a = streamReadFloat32(streamId) |
147 | self:setColor(r, g, b, a) |
148 | end |
149 | |
150 | if streamReadBool(streamId) then |
151 | self.isFermenting = streamReadBool(streamId) |
152 | self.fermentingPercentage = streamReadUInt8(streamId) / 255 |
153 | end |
154 | end |
155 | |
156 | Bale:superClass().readUpdateStream(self, streamId, timestamp, connection) |
157 | end |
611 | function Bale:saveToXMLFile(xmlFile, key) |
612 | local x, y, z = getTranslation(self.nodeId) |
613 | local xRot, yRot, zRot = getRotation(self.nodeId) |
614 | |
615 | xmlFile:setValue(key.."#filename", HTMLUtil.encodeToHTML(NetworkUtil.convertToNetworkFilename(self.xmlFilename))) |
616 | xmlFile:setValue(key.."#position", x, y, z) |
617 | xmlFile:setValue(key.."#rotation", xRot, yRot, zRot) |
618 | xmlFile:setValue(key.."#valueScale", self.baleValueScale) |
619 | xmlFile:setValue(key.."#fillLevel", self.fillLevel) |
620 | xmlFile:setValue(key.."#fillType", g_fillTypeManager:getFillTypeNameByIndex(self.fillType)) |
621 | xmlFile:setValue(key.."#farmId", self:getOwnerFarmId()) |
622 | xmlFile:setValue(key.."#isMissionBale", self.isMissionBale) |
623 | |
624 | xmlFile:setValue(key.."#wrappingState", self.wrappingState) |
625 | xmlFile:setValue(key.."#wrappingColor", self.wrappingColor[1], self.wrappingColor[2], self.wrappingColor[3], self.wrappingColor[4]) |
626 | |
627 | if self.wrapDiffuse ~= nil then |
628 | xmlFile:setValue(key..".textures#wrapDiffuse", HTMLUtil.encodeToHTML(NetworkUtil.convertToNetworkFilename(self.wrapDiffuse))) |
629 | end |
630 | if self.wrapNormal ~= nil then |
631 | xmlFile:setValue(key..".textures#wrapNormal", HTMLUtil.encodeToHTML(NetworkUtil.convertToNetworkFilename(self.wrapNormal))) |
632 | end |
633 | |
634 | if self.isFermenting then |
635 | xmlFile:setValue(key..".fermentation#isFermenting", true) |
636 | xmlFile:setValue(key..".fermentation#time", g_baleManager:getFermentationTime(self)) |
637 | end |
638 | end |
358 | function Bale:setBaleAIObstacle(isActive) |
359 | if isActive and self.obstacleNodeId == nil then |
360 | g_currentMission.aiSystem:addObstacle(self.nodeId, nil, nil, nil, nil, nil, nil, nil) |
361 | self.obstacleNodeId = self.nodeId |
362 | elseif not isActive and self.obstacleNodeId ~= nil then |
363 | g_currentMission.aiSystem:removeObstacle(self.obstacleNodeId) |
364 | self.obstacleNodeId = nil |
365 | end |
366 | end |
1078 | function Bale.setBaleMeshVisibilityCut(baleMesh, node, axis, direction, recursively) |
1079 | if getHasShaderParameter(baleMesh, "visibilityXZ") then |
1080 | local sx, sy, sz, sw = getShaderParameter(baleMesh, "visibilityXZ") |
1081 | local x, _, z = localToLocal(node, baleMesh, 0, 0, 0) |
1082 | |
1083 | if axis == 1 then |
1084 | if direction > 0 then |
1085 | sx = x |
1086 | else |
1087 | sy = x |
1088 | end |
1089 | else |
1090 | if direction > 0 then |
1091 | sz = z |
1092 | else |
1093 | sw = z |
1094 | end |
1095 | end |
1096 | |
1097 | setShaderParameter(baleMesh, "visibilityXZ", sx, sy, sz, sw, false) |
1098 | end |
1099 | |
1100 | if recursively then |
1101 | for i=1, getNumOfChildren(baleMesh) do |
1102 | Bale.setBaleMeshVisibilityCut(getChildAt(baleMesh, i-1), node, axis, direction, recursively) |
1103 | end |
1104 | end |
1105 | end |
900 | function Bale:setColor(r, g, b, a) |
901 | r, g, b, a = r or 1, g or 1, b or 1, a or 1 |
902 | |
903 | if r ~= self.wrappingColor[1] |
904 | or g ~= self.wrappingColor[2] |
905 | or b ~= self.wrappingColor[3] |
906 | or a ~= self.wrappingColor[4] then |
907 | if self.isServer then |
908 | self:raiseDirtyFlags(self.wrapColorDirtyFlag) |
909 | end |
910 | |
911 | self.wrappingColor[1] = r |
912 | self.wrappingColor[2] = g |
913 | self.wrappingColor[3] = b |
914 | self.wrappingColor[4] = a |
915 | |
916 | for i=1, #self.meshes do |
917 | local meshData = self.meshes[i] |
918 | if getHasShaderParameter(meshData.node, "colorScale") then |
919 | setShaderParameter(meshData.node, "colorScale", r, g, b, a, false) |
920 | end |
921 | end |
922 | end |
923 | end |
698 | function Bale:setFillType(fillTypeIndex, fillBale) |
699 | Bale.setFillTypeTextures(self.nodeId, self.fillTypes, fillTypeIndex) |
700 | self.fillType = fillTypeIndex |
701 | |
702 | self.supportsWrapping = false |
703 | |
704 | local fillTypeInfo = self:getFillTypeInfo(self.fillType) |
705 | if fillTypeInfo ~= nil then |
706 | self.supportsWrapping = fillTypeInfo.supportsWrapping |
707 | setMass(self.nodeId, fillTypeInfo.mass) |
708 | self.defaultMass = fillTypeInfo.mass |
709 | |
710 | if self.isServer then |
711 | if fillTypeInfo.forceAcceleration ~= nil then |
712 | self:setMountableObjectAttributes(nil, fillTypeInfo.forceAcceleration, self.dynamicMountForceLimitScale, self.dynamicMountSingleAxisFreeY, self.dynamicMountSingleAxisFreeX) |
713 | end |
714 | |
715 | if fillTypeInfo.fermenting ~= nil then |
716 | if not fillTypeInfo.fermenting.requiresWrapping then |
717 | if self.isFermenting then |
718 | g_baleManager:removeFermentation(self) |
719 | end |
720 | |
721 | local maxTime = fillTypeInfo.fermenting.time * (24 * 60 * 60 * 1000) -- days / months |
722 | g_baleManager:registerFermentation(self, 0, maxTime) |
723 | self.isFermenting = true |
724 | self:raiseDirtyFlags(self.fermentingDirtyFlag) |
725 | end |
726 | end |
727 | end |
728 | |
729 | if fillBale == true then |
730 | self:setFillLevel(fillTypeInfo.capacity) |
731 | end |
732 | end |
733 | |
734 | Bale.updateVisualMeshVisibility(self.meshes, self.fillType, self.wrappingState ~= 0) |
735 | |
736 | if self.isServer then |
737 | self:raiseDirtyFlags(self.fillTypeDirtyFlag) |
738 | end |
739 | end |
1245 | function Bale.setFillTypeTexturesForNode(nodeId, fillTypeInfo) |
1246 | local numChildren = getNumOfChildren(nodeId) |
1247 | for i=1, numChildren do |
1248 | Bale.setFillTypeTexturesForNode(getChildAt(nodeId, i - 1), fillTypeInfo) |
1249 | end |
1250 | |
1251 | if getHasClassId(nodeId, ClassIds.SHAPE) then |
1252 | local materialId = getMaterial(nodeId, 0) |
1253 | if materialId ~= 0 then |
1254 | local shaderFilename = getMaterialCustomShaderFilename(materialId) |
1255 | if shaderFilename:contains("silageBaleShader") then |
1256 | local oldWrappingState, _, _, _ = getShaderParameter(nodeId, "wrappingState") |
1257 | local oldWrapR, oldWrapG, oldWrapB, oldWrapA = getShaderParameter(nodeId, "colorScale") |
1258 | if fillTypeInfo.diffuseFilename ~= nil then |
1259 | materialId = setMaterialDiffuseMapFromFile(materialId, fillTypeInfo.diffuseFilename, true, true, false) |
1260 | end |
1261 | if fillTypeInfo.normalFilename ~= nil then |
1262 | materialId = setMaterialNormalMapFromFile(materialId, fillTypeInfo.normalFilename, true, false, false) |
1263 | end |
1264 | if fillTypeInfo.specularFilename ~= nil then |
1265 | materialId = setMaterialGlossMapFromFile(materialId, fillTypeInfo.specularFilename, true, true, false) |
1266 | end |
1267 | if fillTypeInfo.alphaFilename ~= nil then |
1268 | materialId = setMaterialCustomMapFromFile(materialId, "alphaMap", fillTypeInfo.alphaFilename, true, false, false) |
1269 | end |
1270 | |
1271 | setMaterial(nodeId, materialId, 0) |
1272 | setShaderParameter(nodeId, "wrappingState", oldWrappingState, 0, 0, 0, false) |
1273 | setShaderParameter(nodeId, "colorScale", oldWrapR, oldWrapG, oldWrapB, oldWrapA, false) |
1274 | end |
1275 | end |
1276 | end |
1277 | end |
804 | function Bale:setWrappingState(wrappingState, updateFermentation) |
805 | if self.isServer then |
806 | if self.wrappingState ~= wrappingState then |
807 | self:raiseDirtyFlags(self.wrapStateDirtyFlag) |
808 | end |
809 | end |
810 | |
811 | self.wrappingState = wrappingState |
812 | |
813 | for i=1, #self.meshes do |
814 | local meshData = self.meshes[i] |
815 | local visibility = (meshData.supportsWrapping or wrappingState == 0) and meshData.fillTypeVisibility |
816 | setVisibility(meshData.node, visibility) |
817 | |
818 | if visibility then |
819 | setShaderParameter(meshData.node, "wrappingState", self.wrappingState, 0, 0, 0, false) |
820 | end |
821 | end |
822 | |
823 | if self.isServer then |
824 | if updateFermentation ~= false then |
825 | if self.wrappingState >= 1 then |
826 | local fillTypeInfo = self:getFillTypeInfo(self.fillType) |
827 | if fillTypeInfo ~= nil and fillTypeInfo.fermenting ~= nil then |
828 | if fillTypeInfo.fermenting.requiresWrapping then |
829 | if not self.isFermenting then |
830 | local maxTime = fillTypeInfo.fermenting.time * (24 * 60 * 60 * 1000) -- days / months |
831 | |
832 | -- while bale is produced from a mission field we ferment instantly so it can be sold directly |
833 | if self.isMissionBale then |
834 | maxTime = 0 |
835 | end |
836 | |
837 | g_baleManager:registerFermentation(self, 0, maxTime) |
838 | self.isFermenting = true |
839 | self:raiseDirtyFlags(self.fermentingDirtyFlag) |
840 | end |
841 | end |
842 | end |
843 | end |
844 | end |
845 | end |
846 | |
847 | if wrappingState > 0 then |
848 | g_currentMission.activatableObjectsSystem:addActivatable(self.activatable) |
849 | else |
850 | g_currentMission.activatableObjectsSystem:removeActivatable(self.activatable) |
851 | end |
852 | end |
858 | function Bale:setWrapTextures(diffuse, normal) |
859 | self.wrapDiffuse = diffuse or self.wrapDiffuse |
860 | self.wrapNormal = normal or self.wrapNormal |
861 | |
862 | for i=1, #self.meshes do |
863 | local meshData = self.meshes[i] |
864 | local materialId = getMaterial(meshData.node, 0) |
865 | |
866 | if self.wrapDiffuse ~= nil then |
867 | if fileExists(self.wrapDiffuse) then |
868 | materialId = setMaterialCustomMapFromFile(materialId, "wrapDiffuseMap", self.wrapDiffuse, false, true, false) |
869 | else |
870 | Logging.warning("Unknown bale wrapping texture '%s'. Using default texture.", self.wrapDiffuse) |
871 | end |
872 | end |
873 | if self.wrapNormal ~= nil then |
874 | if fileExists(self.wrapNormal) then |
875 | materialId = setMaterialCustomMapFromFile(materialId, "wrapNormalMap", self.wrapNormal, false, false, false) |
876 | else |
877 | Logging.warning("Unknown bale wrapping texture '%s'. Using default texture.", self.wrapNormal) |
878 | end |
879 | end |
880 | |
881 | setMaterial(meshData.node, materialId, 0) |
882 | |
883 | setShaderParameter(meshData.node, "wrappingState", self.wrappingState, 0, 0, 0, false) |
884 | setShaderParameter(meshData.node, "colorScale", self.wrappingColor[1], self.wrappingColor[2], self.wrappingColor[3], self.wrappingColor[4], false) |
885 | end |
886 | |
887 | if self.isServer then |
888 | if diffuse ~= nil or normal ~= nil then |
889 | self:raiseDirtyFlags(self.texturesDirtyFlag) |
890 | end |
891 | end |
892 | end |
1132 | function Bale:showInfo(box) |
1133 | local fillType = self:getFillType() |
1134 | local fillLevel = self:getFillLevel() |
1135 | local fillTypeDesc = g_fillTypeManager:getFillTypeByIndex(fillType) |
1136 | box:addLine(fillTypeDesc.title, g_i18n:formatVolume(fillLevel, 0)) |
1137 | if self:getIsFermenting() then |
1138 | box:addLine(g_i18n:getText("info_fermenting"), string.format("%d%%", self:getFermentingPercentage() * 100)) |
1139 | end |
1140 | box:addLine(g_i18n:getText("infohud_mass"), g_i18n:formatMass(self:getMass())) |
1141 | end |
1315 | function Bale.updateVisualMeshVisibility(meshes, fillTypeIndex, isWrapped) |
1316 | for i=1, #meshes do |
1317 | local meshData = meshes[i] |
1318 | if meshData.fillTypes ~= nil and #meshData.fillTypes > 0 then |
1319 | setVisibility(meshData.node, false) |
1320 | meshData.fillTypeVisibility = false |
1321 | for j=1, #meshData.fillTypes do |
1322 | if meshData.fillTypes[j] == fillTypeIndex then |
1323 | if meshData.supportsWrapping or not isWrapped then |
1324 | setVisibility(meshData.node, true) |
1325 | end |
1326 | meshData.fillTypeVisibility = true |
1327 | |
1328 | break |
1329 | end |
1330 | end |
1331 | end |
1332 | end |
1333 | end |
255 | function Bale:writeStream(streamId, connection) |
256 | streamWriteString(streamId, NetworkUtil.convertToNetworkFilename(self.xmlFilename)) |
257 | |
258 | streamWriteFloat32(streamId, self.fillLevel) |
259 | streamWriteUIntN(streamId, self.fillType, FillTypeManager.SEND_NUM_BITS) |
260 | |
261 | if streamWriteBool(streamId, self.wrapDiffuse ~= nil) then |
262 | streamWriteString(streamId, NetworkUtil.convertToNetworkFilename(self.wrapDiffuse)) |
263 | end |
264 | |
265 | if streamWriteBool(streamId, self.wrapNormal ~= nil) then |
266 | streamWriteString(streamId, NetworkUtil.convertToNetworkFilename(self.wrapNormal)) |
267 | end |
268 | |
269 | Bale:superClass().writeStream(self, streamId, connection) |
270 | |
271 | streamWriteFloat32(streamId, self.baleValueScale) |
272 | |
273 | streamWriteUInt8(streamId, MathUtil.clamp(self.wrappingState*255, 0, 255)) |
274 | |
275 | streamWriteFloat32(streamId, self.wrappingColor[1]) |
276 | streamWriteFloat32(streamId, self.wrappingColor[2]) |
277 | streamWriteFloat32(streamId, self.wrappingColor[3]) |
278 | streamWriteFloat32(streamId, self.wrappingColor[4]) |
279 | |
280 | if streamWriteBool(streamId, self.isFermenting) then |
281 | streamWriteUInt8(streamId, MathUtil.clamp(self.fermentingPercentage * 255, 0, 255)) |
282 | end |
283 | end |
164 | function Bale:writeUpdateStream(streamId, connection, dirtyMask) |
165 | if not connection:getIsServer() then |
166 | if streamWriteBool(streamId, bitAND(dirtyMask, self.fillTypeDirtyFlag) ~= 0) then |
167 | streamWriteUIntN(streamId, self.fillType, FillTypeManager.SEND_NUM_BITS) |
168 | end |
169 | |
170 | if streamWriteBool(streamId, bitAND(dirtyMask, self.fillLevelDirtyFlag) ~= 0) then |
171 | streamWriteFloat32(streamId, self.fillLevel) |
172 | end |
173 | |
174 | if streamWriteBool(streamId, bitAND(dirtyMask, self.texturesDirtyFlag) ~= 0) then |
175 | if streamWriteBool(streamId, self.wrapDiffuse ~= nil) then |
176 | streamWriteString(streamId, NetworkUtil.convertToNetworkFilename(self.wrapDiffuse)) |
177 | end |
178 | |
179 | if streamWriteBool(streamId, self.wrapNormal ~= nil) then |
180 | streamWriteString(streamId, NetworkUtil.convertToNetworkFilename(self.wrapNormal)) |
181 | end |
182 | end |
183 | |
184 | if streamWriteBool(streamId, bitAND(dirtyMask, self.wrapStateDirtyFlag) ~= 0) then |
185 | streamWriteUInt8(streamId, MathUtil.clamp(self.wrappingState*255, 0, 255)) |
186 | end |
187 | |
188 | if streamWriteBool(streamId, bitAND(dirtyMask, self.wrapColorDirtyFlag) ~= 0) then |
189 | streamWriteFloat32(streamId, self.wrappingColor[1]) |
190 | streamWriteFloat32(streamId, self.wrappingColor[2]) |
191 | streamWriteFloat32(streamId, self.wrappingColor[3]) |
192 | streamWriteFloat32(streamId, self.wrappingColor[4]) |
193 | end |
194 | |
195 | if streamWriteBool(streamId, bitAND(dirtyMask, self.fermentingDirtyFlag) ~= 0) then |
196 | streamWriteBool(streamId, self.isFermenting) |
197 | streamWriteUInt8(streamId, MathUtil.clamp(self.fermentingPercentage * 255, 0, 255)) |
198 | end |
199 | end |
200 | |
201 | Bale:superClass().writeUpdateStream(self, streamId, connection, dirtyMask) |
202 | end |