Script v1.7.1.0
- AI
- Animals
- Contracts
- Debug
- Economy
- Effects
- Events
- Farms
- GUI
- Handtools
- I3d
- Materials
- Misc
- Objects
- Placeables
- Player
- Shop
- Sounds
- Specializations
- Triggers
- Utils
- Vehicles
- Weather
Engine v1.7.1.0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- XML
- general
Foundation Reference
Baler
DescriptionSpecialization for balers allowing to pickup swaths and create physical bale objectsFunctions
- actionEventUnloading
- createBale
- doCheckSpeedLimit
- dropBale
- finishBale
- getCanBeSelected
- getCanBeTurnedOn
- getCanUnloadUnfinishedBale
- getConsumingLoad
- getDefaultSpeedLimit
- getIsFoldAllowed
- getIsSpeedRotatingPartActive
- getIsWorkAreaActive
- getTimeFromLevel
- initSpecialization
- isUnloadingAllowed
- loadSpeedRotatingPartFromXML
- moveBale
- moveBales
- onDeactivate
- onDelete
- onEndWorkAreaProcessing
- onFillUnitFillLevelChanged
- onLoad
- onLoadFinished
- onPostLoad
- onReadStream
- onReadUpdateStream
- onRegisterActionEvents
- onStartWorkAreaProcessing
- onTurnedOff
- onTurnedOn
- onUpdate
- onUpdateTick
- onWriteStream
- onWriteUpdateStream
- prerequisitesPresent
- processBalerArea
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
- saveToXMLFile
- setBaleTime
- setIsUnloadingBale
actionEventUnloading
DescriptionDefinitionactionEventUnloading()Code
1221 | function Baler.actionEventUnloading(self, actionName, inputValue, callbackState, isAnalog) |
1222 | local spec = self.spec_baler |
1223 | if self:isUnloadingAllowed() then |
1224 | if spec.baleUnloadAnimationName ~= nil or spec.allowsBaleUnloading then |
1225 | if spec.unloadingState == Baler.UNLOADING_CLOSED then |
1226 | if table.getn(spec.bales) > 0 or self:getCanUnloadUnfinishedBale() then |
1227 | self:setIsUnloadingBale(true) |
1228 | end |
1229 | elseif spec.unloadingState == Baler.UNLOADING_OPEN then |
1230 | if spec.baleUnloadAnimationName ~= nil then |
1231 | self:setIsUnloadingBale(false) |
1232 | end |
1233 | end |
1234 | end |
1235 | end |
1236 | end |
createBale
DescriptionDefinitioncreateBale()Code
892 | function Baler:createBale(baleFillType, fillLevel) |
893 | local spec = self.spec_baler |
894 | |
895 | if spec.knotingAnimation ~= nil then |
896 | self:playAnimation(spec.knotingAnimation, spec.knotingAnimationSpeed, nil, true) |
897 | end |
898 | |
899 | self:deleteDummyBale() |
900 | |
901 | local t = spec.baleTypes[spec.currentBaleTypeId] |
902 | local baleType = g_baleTypeManager:getBale(baleFillType, t.isRoundBale, t.width, t.height, t.length, t.diameter) |
903 | |
904 | local bale = {} |
905 | bale.filename = baleType.filename |
906 | bale.time = 0 |
907 | bale.fillType = baleFillType |
908 | bale.fillLevel = fillLevel |
909 | |
910 | if spec.baleUnloadAnimationName ~= nil then |
911 | local baleRoot = g_i3DManager:loadSharedI3DFile(baleType.filename, nil, false, false) |
912 | local baleId = getChildAt(baleRoot, 0) |
913 | link(spec.baleAnimRoot, baleId) |
914 | delete(baleRoot) |
915 | bale.id = baleId |
916 | end |
917 | |
918 | if self.isServer and spec.baleUnloadAnimationName == nil then |
919 | local x, y, z = getWorldTranslation(spec.baleAnimRoot) |
920 | local rx, ry, rz = getWorldRotation(spec.baleAnimRoot) |
921 | |
922 | local baleJointNode = createTransformGroup("BaleJointTG") |
923 | link(spec.baleAnimRoot, baleJointNode) |
924 | |
925 | if spec.customCreateBaleTime ~= nil then |
926 | local v = spec.baleAnimCurve:get(spec.customCreateBaleTime) |
927 | setTranslation(baleJointNode, v[1], v[2], v[3]) |
928 | setRotation(baleJointNode, v[4], v[5], v[6]) |
929 | |
930 | x, y, z = localToWorld(spec.baleAnimRoot, v[1], v[2], v[3]) |
931 | rx, ry, rz = localRotationToWorld(spec.baleAnimRoot, v[4], v[5], v[6]) |
932 | |
933 | spec.customCreateBaleTime = nil |
934 | else |
935 | setTranslation(baleJointNode, 0, 0, 0) |
936 | setRotation(baleJointNode, 0, 0, 0) |
937 | end |
938 | |
939 | local baleObject = Bale:new(self.isServer, self.isClient) |
940 | baleObject:load(bale.filename, x,y,z,rx,ry,rz, bale.fillLevel) |
941 | baleObject:setOwnerFarmId(self:getActiveFarm(), true) |
942 | baleObject:register() |
943 | baleObject:setCanBeSold(false) |
944 | |
945 | local constr = JointConstructor:new() |
946 | constr:setActors(spec.baleAnimRootComponent, baleObject.nodeId) |
947 | constr:setJointTransforms(baleJointNode, baleObject.nodeId) |
948 | for i=1, 3 do |
949 | constr:setRotationLimit(i-1, 0, 0) |
950 | constr:setTranslationLimit(i-1, true, 0, 0) |
951 | end |
952 | constr:setEnableCollision(false) |
953 | local baleJointIndex = constr:finalize() |
954 | |
955 | g_currentMission:removeItemToSave(baleObject) |
956 | |
957 | bale.baleJointNode = baleJointNode |
958 | bale.baleJointIndex = baleJointIndex |
959 | bale.baleObject = baleObject |
960 | end |
961 | |
962 | table.insert(spec.bales, bale) |
963 | end |
doCheckSpeedLimit
DescriptionDefinitiondoCheckSpeedLimit()Code
743 | function Baler:doCheckSpeedLimit(superFunc) |
744 | return superFunc(self) or (self:getIsTurnedOn() and self:getIsLowered()) |
745 | end |
dropBale
DescriptionDefinitiondropBale()Code
967 | function Baler:dropBale(baleIndex) |
968 | local spec = self.spec_baler |
969 | |
970 | local bale = spec.bales[baleIndex] |
971 | |
972 | if self.isServer then |
973 | local baleObject |
974 | |
975 | if bale.baleJointIndex ~= nil then |
976 | baleObject = bale.baleObject |
977 | removeJoint(bale.baleJointIndex) |
978 | delete(bale.baleJointNode) |
979 | g_currentMission:addItemToSave(bale.baleObject) |
980 | else |
981 | baleObject = Bale:new(self.isServer, self.isClient) |
982 | local x,y,z = getWorldTranslation(bale.id) |
983 | local rx,ry,rz = getWorldRotation(bale.id) |
984 | baleObject:load(bale.filename, x,y,z,rx,ry,rz, bale.fillLevel) |
985 | baleObject:setOwnerFarmId(self:getActiveFarm(), true) |
986 | baleObject:register() |
987 | end |
988 | |
989 | if spec.lastBaleFillLevel ~= nil and #spec.bales == 1 then |
990 | baleObject:setFillLevel(spec.lastBaleFillLevel) |
991 | spec.lastBaleFillLevel = nil |
992 | end |
993 | |
994 | baleObject:setCanBeSold(true) |
995 | |
996 | if baleObject.nodeId ~= nil then |
997 | -- release bale |
998 | local x,y,z = getWorldTranslation(baleObject.nodeId) |
999 | local vx,vy,vz = getVelocityAtWorldPos(spec.baleAnimRootComponent, x,y,z) |
1000 | setLinearVelocity(baleObject.nodeId, vx,vy,vz) |
1001 | end |
1002 | |
1003 | g_farmManager:updateFarmStats(self:getLastTouchedFarmlandFarmId(), "baleCount", 1) |
1004 | end |
1005 | |
1006 | if bale.id ~= nil and entityExists(bale.id) then |
1007 | delete(bale.id) |
1008 | bale.id = nil |
1009 | g_i3DManager:releaseSharedI3DFile(bale.filename, nil, true) |
1010 | end |
1011 | |
1012 | table.remove(spec.bales, baleIndex) |
1013 | end |
finishBale
DescriptionDefinitionfinishBale()Code
869 | function Baler:finishBale() |
870 | local spec = self.spec_baler |
871 | if spec.baleTypes ~= nil then |
872 | local fillTypeIndex = self:getFillUnitFillType(spec.fillUnitIndex) |
873 | if spec.baleAnimCurve ~= nil then |
874 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -math.huge, fillTypeIndex, ToolType.UNDEFINED) |
875 | |
876 | self:createBale(fillTypeIndex, self:getFillUnitCapacity(spec.fillUnitIndex)) |
877 | |
878 | local numBales = table.getn(spec.bales) |
879 | local bale = spec.bales[numBales] |
880 | |
881 | -- note: spec.bales[numBales] can not be accessed anymore since the bale might be dropped already |
882 | g_server:broadcastEvent(BalerCreateBaleEvent:new(self, fillTypeIndex, bale.time), nil, nil, self) |
883 | elseif spec.baleUnloadAnimationName ~= nil then |
884 | self:createBale(fillTypeIndex, self:getFillUnitCapacity(spec.fillUnitIndex)) |
885 | g_server:broadcastEvent(BalerCreateBaleEvent:new(self, fillTypeIndex, 0), nil, nil, self) |
886 | end |
887 | end |
888 | end |
getCanBeSelected
DescriptionDefinitiongetCanBeSelected()Code
1123 | function Baler:getCanBeSelected(superFunc) |
1124 | return true |
1125 | end |
getCanBeTurnedOn
DescriptionDefinitiongetCanBeTurnedOn()Code
1045 | function Baler:getCanBeTurnedOn(superFunc) |
1046 | local spec = self.spec_baler |
1047 | |
1048 | if spec.isBaleUnloading then |
1049 | return false |
1050 | end |
1051 | |
1052 | return superFunc(self) |
1053 | end |
getCanUnloadUnfinishedBale
DescriptionDefinitiongetCanUnloadUnfinishedBale()Code
1038 | function Baler:getCanUnloadUnfinishedBale() |
1039 | local spec = self.spec_baler |
1040 | return spec.canUnloadUnfinishedBale and self:getFillUnitFillLevel(spec.fillUnitIndex) > spec.unfinishedBaleThreshold |
1041 | end |
getConsumingLoad
DescriptionDefinitiongetConsumingLoad()Code
1112 | function Baler:getConsumingLoad(superFunc) |
1113 | local value, count = superFunc(self) |
1114 | |
1115 | local spec = self.spec_baler |
1116 | local loadPercentage = spec.pickUpLitersBuffer:get(1000) / spec.maxPickupLitersPerSecond |
1117 | |
1118 | return value+loadPercentage, count+1 |
1119 | end |
getDefaultSpeedLimit
DescriptionDefinitiongetDefaultSpeedLimit()Code
1079 | function Baler.getDefaultSpeedLimit() |
1080 | return 25 |
1081 | end |
getIsFoldAllowed
DescriptionDefinitiongetIsFoldAllowed()Code
618 | function Baler:getIsFoldAllowed(superFunc, direction, onAiTurnOn) |
619 | local spec = self.spec_baler |
620 | |
621 | if table.getn(spec.bales) > 0 and self:getFillUnitFillLevel(spec.fillUnitIndex) > spec.baleFoldThreshold then |
622 | return false |
623 | end |
624 | |
625 | if table.getn(spec.bales) > 1 then |
626 | return false |
627 | end |
628 | |
629 | if self:getIsTurnedOn() then |
630 | return false |
631 | end |
632 | |
633 | return superFunc(self, direction, onAiTurnOn) |
634 | end |
getIsSpeedRotatingPartActive
DescriptionDefinitiongetIsSpeedRotatingPartActive()Code
1065 | function Baler:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart) |
1066 | local spec = self.spec_baler |
1067 | |
1068 | if speedRotatingPart.rotateOnlyIfFillLevelIncreased ~= nil then |
1069 | if speedRotatingPart.rotateOnlyIfFillLevelIncreased and spec.lastAreaBiggerZeroTime == 0 then |
1070 | return false |
1071 | end |
1072 | end |
1073 | |
1074 | return superFunc(self, speedRotatingPart) |
1075 | end |
getIsWorkAreaActive
DescriptionDefinitiongetIsWorkAreaActive()Code
1085 | function Baler:getIsWorkAreaActive(superFunc, workArea) |
1086 | local spec = self.spec_baler |
1087 | |
1088 | if not g_currentMission:getCanAddLimitedObject(FSBaseMission.LIMITED_OBJECT_TYPE_BALE) and self:getIsTurnedOn() then |
1089 | g_currentMission:showBlinkingWarning(g_i18n:getText("warning_tooManyBales"), 500) |
1090 | return false |
1091 | end |
1092 | |
1093 | if self:getFillUnitFreeCapacity(spec.fillUnitIndex) == 0 then |
1094 | return false |
1095 | end |
1096 | |
1097 | if self.allowPickingUp ~= nil and not self:allowPickingUp() then |
1098 | return false |
1099 | end |
1100 | |
1101 | if spec.baleUnloadAnimationName ~= nil then |
1102 | if table.getn(spec.bales) > 0 or spec.unloadingState ~= Baler.UNLOADING_CLOSED then |
1103 | return false |
1104 | end |
1105 | end |
1106 | |
1107 | return superFunc(self, workArea) |
1108 | end |
getTimeFromLevel
DescriptionDefinitiongetTimeFromLevel()Code
805 | function Baler:getTimeFromLevel(level) |
806 | local spec = self.spec_baler |
807 | |
808 | -- level = capacity -> time = firstBaleMarker |
809 | -- level = 0 -> time = 0 |
810 | if spec.firstBaleMarker ~= nil then |
811 | return level / self:getFillUnitCapacity(spec.fillUnitIndex) * spec.firstBaleMarker |
812 | end |
813 | return 0 |
814 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
24 | function Baler.initSpecialization() |
25 | g_workAreaTypeManager:addWorkAreaType("baler", false) |
26 | end |
isUnloadingAllowed
DescriptionDefinitionisUnloadingAllowed()Code
749 | function Baler:isUnloadingAllowed() |
750 | local spec = self.spec_baler |
751 | |
752 | if self.spec_baleWrapper == nil then |
753 | return not spec.allowsBaleUnloading or (spec.allowsBaleUnloading and not self:getIsTurnedOn() and not spec.isBaleUnloading) |
754 | end |
755 | |
756 | return self:allowsGrabbingBale() |
757 | end |
loadSpeedRotatingPartFromXML
DescriptionDefinitionloadSpeedRotatingPartFromXML()Code
1057 | function Baler:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key) |
1058 | speedRotatingPart.rotateOnlyIfFillLevelIncreased = Utils.getNoNil(getXMLBool(xmlFile, key .. "#rotateOnlyIfFillLevelIncreased"), false) |
1059 | |
1060 | return superFunc(self, speedRotatingPart, xmlFile, key) |
1061 | end |
moveBale
DescriptionDefinitionmoveBale()Code
828 | function Baler:moveBale(i, dt, noEventSend) |
829 | local spec = self.spec_baler |
830 | |
831 | local bale = spec.bales[i] |
832 | self:setBaleTime(i, bale.time + dt, noEventSend) |
833 | end |
moveBales
DescriptionDefinitionmoveBales()Code
818 | function Baler:moveBales(dt) |
819 | local spec = self.spec_baler |
820 | |
821 | for i=table.getn(spec.bales), 1, -1 do |
822 | self:moveBale(i, dt) |
823 | end |
824 | end |
onDeactivate
DescriptionDefinitiononDeactivate()Code
638 | function Baler:onDeactivate() |
639 | local spec = self.spec_baler |
640 | |
641 | if self.isClient then |
642 | g_effectManager:stopEffects(spec.fillEffects) |
643 | g_soundManager:stopSamples(spec.samples) |
644 | end |
645 | end |
onDelete
DescriptionDefinitiononDelete()Code
311 | function Baler:onDelete() |
312 | local spec = self.spec_baler |
313 | |
314 | -- if the baler was sold we drop the bales |
315 | if self.isReconfigurating == nil or not self.isReconfigurating then |
316 | for k, _ in pairs(spec.bales) do |
317 | self:dropBale(k) |
318 | end |
319 | end |
320 | |
321 | self:deleteDummyBale() |
322 | |
323 | if self.isClient then |
324 | g_soundManager:deleteSamples(spec.samples) |
325 | g_effectManager:deleteEffects(spec.fillEffects) |
326 | g_animationManager:deleteAnimations(spec.animationNodes) |
327 | g_animationManager:deleteAnimations(spec.unloadAnimationNodes) |
328 | end |
329 | end |
onEndWorkAreaProcessing
DescriptionDefinitiononEndWorkAreaProcessing()Code
1188 | function Baler:onEndWorkAreaProcessing(dt, hasProcessed) |
1189 | local spec = self.spec_baler |
1190 | |
1191 | if self.isServer then |
1192 | local pickedUpLiters = spec.workAreaParameters.lastPickedUpLiters |
1193 | local pickedUpFillType = spec.workAreaParameters.lastPickedUpFillType |
1194 | if pickedUpLiters > 0 then |
1195 | spec.lastAreaBiggerZero = true |
1196 | if spec.lastAreaBiggerZero ~= spec.lastAreaBiggerZeroSent then |
1197 | self:raiseDirtyFlags(spec.dirtyFlag) |
1198 | spec.lastAreaBiggerZeroSent = spec.lastAreaBiggerZero |
1199 | end |
1200 | |
1201 | local deltaLevel = pickedUpLiters * spec.fillScale |
1202 | |
1203 | if spec.baleUnloadAnimationName == nil then |
1204 | -- move all bales |
1205 | local deltaTime = self:getTimeFromLevel(deltaLevel) |
1206 | self:moveBales(deltaTime) |
1207 | end |
1208 | |
1209 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, deltaLevel, pickedUpFillType, ToolType.UNDEFINED) |
1210 | end |
1211 | |
1212 | if spec.fillEffectType ~= spec.fillEffectTypeSent then |
1213 | spec.fillEffectTypeSent = spec.fillEffectType |
1214 | self:raiseDirtyFlags(spec.dirtyFlag) |
1215 | end |
1216 | end |
1217 | end |
onFillUnitFillLevelChanged
DescriptionDefinitiononFillUnitFillLevelChanged()Code
649 | function Baler:onFillUnitFillLevelChanged(fillUnitIndex, fillLevelDelta, fillTypeIndex, toolType, fillPositionData, appliedDelta) |
650 | local spec = self.spec_baler |
651 | |
652 | if fillUnitIndex == spec.fillUnitIndex then |
653 | local fillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex) |
654 | local capacity = self:getFillUnitCapacity(spec.fillUnitIndex) |
655 | |
656 | if spec.dummyBale.baleNode ~= nil and fillLevel > 0 and fillLevel < capacity and (spec.dummyBale.currentBale == nil or spec.dummyBale.currentBaleFillType ~= fillTypeIndex) then |
657 | if spec.dummyBale.currentBale ~= nil then |
658 | self:deleteDummyBale() |
659 | end |
660 | |
661 | local t = spec.baleTypes[spec.currentBaleTypeId] |
662 | local baleType = g_baleTypeManager:getBale(fillTypeIndex, t.isRoundBale, t.width, t.height, t.length, t.diameter) |
663 | |
664 | self:createDummyBale(baleType, fillTypeIndex) |
665 | end |
666 | |
667 | if spec.dummyBale.currentBale ~= nil then |
668 | local percentage = fillLevel / capacity |
669 | local x = 1 |
670 | local y = getUserAttribute(spec.dummyBale.currentBale, "isRoundbale") and percentage or 1 |
671 | local z = percentage |
672 | |
673 | if spec.baleScaleComponent ~= nil then |
674 | x, y, z = 1, 1, 1 |
675 | for axis, value in ipairs(spec.baleScaleComponent) do |
676 | if value > 0 then |
677 | if axis == 1 then |
678 | x = percentage |
679 | elseif axis == 2 then |
680 | y = percentage |
681 | else |
682 | z= percentage |
683 | end |
684 | end |
685 | end |
686 | end |
687 | |
688 | setScale(spec.dummyBale.scaleNode, x, y, z) |
689 | end |
690 | |
691 | -- create bale |
692 | if self.isServer then |
693 | if self:getFillUnitFreeCapacity(spec.fillUnitIndex) <= 0 then |
694 | if self.isAddedToPhysics then |
695 | self:finishBale() |
696 | else |
697 | -- if the baler is not added to physic (e.g. on load) we create the bale delayed, so we can mount it directly |
698 | spec.createBaleNextFrame = true |
699 | end |
700 | |
701 | spec.fillUnitOverflowFillLevel = fillLevelDelta - appliedDelta |
702 | else |
703 | -- fill level that is too much for the last bale will be added to the next bale (independent of the filltype) |
704 | if spec.fillUnitOverflowFillLevel > 0 then |
705 | if fillLevelDelta > 0 then |
706 | local overflow = spec.fillUnitOverflowFillLevel |
707 | spec.fillUnitOverflowFillLevel = 0 |
708 | overflow = overflow - self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, overflow, fillTypeIndex, toolType) |
709 | spec.fillUnitOverflowFillLevel = overflow |
710 | end |
711 | end |
712 | end |
713 | end |
714 | end |
715 | end |
onLoad
DescriptionDefinitiononLoad()Code
92 | function Baler:onLoad(savegame) |
93 | local spec = self.spec_baler |
94 | |
95 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.fillScale#value", "vehicle.baler#fillScale") --FS15 to FS17 |
96 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnedOnRotationNodes.turnedOnRotationNode#type", "vehicle.baler.animationNodes.animationNode", "baler") --FS17 to FS19 |
97 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baler.balingAnimation#name", "vehicle.turnOnVehicle.turnedOnAnimation#name") --FS17 to FS19 |
98 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baler.fillParticleSystems", "vehicle.baler.fillEffect with effectClass 'ParticleEffect'") --FS17 to FS19 |
99 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baler.uvScrollParts.uvScrollPart", "vehicle.baler.animationNodes.animationNode") --FS17 to FS19 |
100 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baler.balerAlarm", "vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration.fillUnits.fillUnit.alarmTriggers.alarmTrigger.alarmSound") --FS17 to FS19 |
101 | |
102 | spec.fillScale = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler#fillScale"), 1) |
103 | spec.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#fillUnitIndex"), 1) |
104 | |
105 | local firstBaleMarker = getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#firstBaleMarker") |
106 | if firstBaleMarker ~= nil then |
107 | local baleAnimCurve = AnimCurve:new(linearInterpolatorN) |
108 | local keyI = 0 |
109 | while true do |
110 | local key = string.format("vehicle.baler.baleAnimation.key(%d)", keyI) |
111 | local t = getXMLFloat(self.xmlFile, key.."#time") |
112 | local x,y,z = StringUtil.getVectorFromString(getXMLString(self.xmlFile, key.."#pos")) |
113 | if x == nil or y == nil or z == nil then |
114 | break |
115 | end |
116 | local rx, ry, rz = StringUtil.getVectorFromString(getXMLString(self.xmlFile, key.."#rot")) |
117 | rx = math.rad(Utils.getNoNil(rx, 0)) |
118 | ry = math.rad(Utils.getNoNil(ry, 0)) |
119 | rz = math.rad(Utils.getNoNil(rz, 0)) |
120 | baleAnimCurve:addKeyframe({x, y, z, rx, ry, rz, time = t}) |
121 | keyI = keyI +1 |
122 | end |
123 | if keyI > 0 then |
124 | spec.baleAnimCurve = baleAnimCurve |
125 | spec.firstBaleMarker = firstBaleMarker |
126 | end |
127 | end |
128 | |
129 | spec.baleAnimRoot, spec.baleAnimRootComponent = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#node"), self.i3dMappings) |
130 | if spec.baleAnimRoot == nil then |
131 | spec.baleAnimRoot = self.components[1].node |
132 | spec.baleAnimRootComponent = self.components[1].node |
133 | end |
134 | |
135 | -- there is no standard bale animation, load the unload animation (for round baler) |
136 | if spec.firstBaleMarker == nil then |
137 | local unloadAnimationName = getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#unloadAnimationName") |
138 | local closeAnimationName = getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#closeAnimationName") |
139 | if unloadAnimationName ~= nil and closeAnimationName ~= nil then |
140 | if self.getAnimationExists ~= nil then |
141 | if self:getAnimationExists(unloadAnimationName) and self:getAnimationExists(closeAnimationName) then |
142 | spec.baleUnloadAnimationName = unloadAnimationName |
143 | spec.baleUnloadAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#unloadAnimationSpeed"), 1) |
144 | |
145 | spec.baleCloseAnimationName = closeAnimationName |
146 | spec.baleCloseAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#closeAnimationSpeed"), 1) |
147 | |
148 | spec.automaticDrop = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.baler.baleAnimation#automaticDrop"), false) |
149 | |
150 | spec.baleDropAnimTime = getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#baleDropAnimTime") |
151 | if spec.baleDropAnimTime == nil then |
152 | spec.baleDropAnimTime = self:getAnimationDuration(spec.baleUnloadAnimationName) |
153 | else |
154 | spec.baleDropAnimTime = spec.baleDropAnimTime * 1000 |
155 | end |
156 | |
157 | spec.baleScaleComponent = StringUtil.getVectorNFromString(getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#baleScaleComponent"), 3) |
158 | else |
159 | g_logManager:xmlError(self.configFileName, "Failed to find unload animations '%s' and '%s'.", unloadAnimationName, closeAnimationName) |
160 | end |
161 | else |
162 | g_logManager:xmlError(self.configFileName, "Baler unload animations require AnimatedVehicle specialization.") |
163 | end |
164 | end |
165 | end |
166 | |
167 | spec.baleTypes = {} |
168 | local i = 0 |
169 | while true do |
170 | local key = string.format("vehicle.baler.baleTypes.baleType(%d)", i) |
171 | if not hasXMLProperty(self.xmlFile, key) then |
172 | break |
173 | end |
174 | local isRoundBale = Utils.getNoNil(getXMLBool(self.xmlFile, key.."#isRoundBale"), false) |
175 | local width = MathUtil.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#width"), 1.2), 2) |
176 | local height = MathUtil.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#height"), 0.9), 2) |
177 | local length = MathUtil.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#length"), 2.4), 2) |
178 | local diameter = MathUtil.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#diameter"), 1.8), 2) |
179 | table.insert(spec.baleTypes, {isRoundBale=isRoundBale, width=width, height=height, length=length, diameter=diameter}) |
180 | i = i + 1 |
181 | end |
182 | spec.currentBaleTypeId = 1 |
183 | |
184 | if table.getn(spec.baleTypes) == 0 then |
185 | g_logManager:xmlError(self.configFileName, "No baleTypes definded for baler.") |
186 | spec.baleTypes = nil |
187 | end |
188 | |
189 | spec.unfinishedBaleThreshold = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#unfinishedBaleThreshold"), 2000) |
190 | spec.canUnloadUnfinishedBale = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.baler#canUnloadUnfinishedBale"), false) |
191 | spec.lastBaleFillLevel = nil |
192 | |
193 | if self.isClient then |
194 | spec.samples = {} |
195 | spec.samples.work = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.baler.sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
196 | spec.samples.eject = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.baler.sounds", "eject", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
197 | spec.samples.door = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.baler.sounds", "door", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) |
198 | spec.samples.knotCleaning = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.baler.sounds", "knotCleaning", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) |
199 | |
200 | spec.knotCleaningTimer = 10000 |
201 | spec.knotCleaningTime = 120000 |
202 | |
203 | spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.baler.animationNodes", self.components, self, self.i3dMappings) |
204 | spec.unloadAnimationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.baler.unloadAnimationNodes", self.components, self, self.i3dMappings) |
205 | spec.fillEffects = g_effectManager:loadEffect(self.xmlFile, "vehicle.baler.fillEffect", self.components, self, self.i3dMappings) |
206 | spec.fillEffectType = FillType.UNKNOWN |
207 | |
208 | spec.knotingAnimation = getXMLString(self.xmlFile, "vehicle.baler.knotingAnimation#name") |
209 | spec.knotingAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.knotingAnimation#speed"), 1) |
210 | |
211 | spec.compactingAnimation = getXMLString(self.xmlFile, "vehicle.baler.compactingAnimation#name") |
212 | spec.compactingAnimationInterval = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.compactingAnimation#interval"), 60) * 1000 |
213 | spec.compactingAnimationCompactTime = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.compactingAnimation#compactTime"), 5) * 1000 |
214 | spec.compactingAnimationCompactTimer = spec.compactingAnimationCompactTime |
215 | spec.compactingAnimationTime = spec.compactingAnimationInterval |
216 | spec.compactingAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.compactingAnimation#speed"), 1) |
217 | spec.compactingAnimationMinTime = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.compactingAnimation#minFillLevelTime"), 1) |
218 | spec.compactingAnimationMaxTime = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.compactingAnimation#maxFillLevelTime"), 0.1) |
219 | end |
220 | |
221 | spec.lastAreaBiggerZero = false |
222 | spec.lastAreaBiggerZeroSent = false |
223 | spec.lastAreaBiggerZeroTime = 0 |
224 | |
225 | spec.workAreaParameters = {} |
226 | spec.workAreaParameters.lastPickedUpLiters = 0 |
227 | spec.workAreaParameters.lastPickedUpFillType = FillType.UNKNOWN |
228 | |
229 | spec.fillUnitOverflowFillLevel = 0 |
230 | |
231 | spec.maxPickupLitersPerSecond = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#maxPickupLitersPerSecond"), 500) |
232 | spec.pickUpLitersBuffer = ValueBuffer:new(750) |
233 | |
234 | spec.unloadingState = Baler.UNLOADING_CLOSED |
235 | spec.pickupFillTypes = {} |
236 | |
237 | spec.bales = {} |
238 | |
239 | spec.dummyBale = {} |
240 | spec.dummyBale.scaleNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#scaleNode"), self.i3dMappings) |
241 | spec.dummyBale.baleNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#baleNode"), self.i3dMappings) |
242 | spec.dummyBale.currentBaleFillType = FillType.UNKNOWN |
243 | spec.dummyBale.currentBale = nil |
244 | |
245 | spec.allowsBaleUnloading = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.baler.baleUnloading#allowed"), false) |
246 | spec.baleUnloadingTime = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleUnloading#time"), 4) * 1000 |
247 | spec.baleFoldThreshold = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleUnloading#foldThreshold"), 0.25) * self:getFillUnitCapacity(spec.fillUnitIndex) |
248 | |
249 | spec.isBaleUnloading = false |
250 | |
251 | spec.dirtyFlag = self:getNextDirtyFlag() |
252 | end |
onLoadFinished
DescriptionDefinitiononLoadFinished()Code
289 | function Baler:onLoadFinished(savegame) |
290 | local spec = self.spec_baler |
291 | if self.isServer then |
292 | if spec.createBaleNextFrame ~= nil and spec.createBaleNextFrame then |
293 | self:finishBale() |
294 | spec.createBaleNextFrame = nil |
295 | end |
296 | end |
297 | |
298 | if spec.balesToLoad ~= nil then |
299 | for _, v in ipairs(spec.balesToLoad) do |
300 | spec.customCreateBaleTime = v.baleTime -- set it as separate variable instead of function argument, so we won't break any mods |
301 | self:createBale(v.fillType, v.fillLevel) |
302 | self:setBaleTime(table.getn(spec.bales), v.baleTime, true) |
303 | end |
304 | |
305 | spec.balesToLoad = nil |
306 | end |
307 | end |
onPostLoad
DescriptionDefinitiononPostLoad()Code
256 | function Baler:onPostLoad(savegame) |
257 | local spec = self.spec_baler |
258 | |
259 | for fillTypeIndex, enabled in pairs(self:getFillUnitSupportedFillTypes(spec.fillUnitIndex)) do |
260 | if enabled and fillTypeIndex ~= FillType.UNKNOWN then |
261 | if g_fruitTypeManager:isFillTypeWindrow(fillTypeIndex) then |
262 | table.insert(spec.pickupFillTypes, fillTypeIndex) |
263 | end |
264 | end |
265 | end |
266 | |
267 | if savegame ~= nil and not savegame.resetVehicles then |
268 | local numBales = getXMLInt(savegame.xmlFile, savegame.key..".baler#numBales") |
269 | if numBales ~= nil then |
270 | spec.balesToLoad = {} |
271 | for i=1, numBales do |
272 | local baleKey = string.format("%s.baler.bale(%d)", savegame.key, i-1) |
273 | local bale = {} |
274 | local fillTypeStr = getXMLString(savegame.xmlFile, baleKey.."#fillType") |
275 | local fillType = g_fillTypeManager:getFillTypeByName(fillTypeStr) |
276 | if fillType ~= nil then |
277 | bale.fillType = fillType.index |
278 | bale.fillLevel = getXMLFloat(savegame.xmlFile, baleKey.."#fillLevel") |
279 | bale.baleTime = getXMLFloat(savegame.xmlFile, baleKey.."#baleTime") |
280 | table.insert(spec.balesToLoad, bale) |
281 | end |
282 | end |
283 | end |
284 | end |
285 | end |
onReadStream
DescriptionDefinitiononReadStream()Code
361 | function Baler:onReadStream(streamId, connection) |
362 | local spec = self.spec_baler |
363 | |
364 | if spec.baleUnloadAnimationName ~= nil then |
365 | local state = streamReadUIntN(streamId, 7) |
366 | local animTime = streamReadFloat32(streamId) |
367 | if state == Baler.UNLOADING_CLOSED or state == Baler.UNLOADING_CLOSING then |
368 | self:setIsUnloadingBale(false, true) |
369 | self:setRealAnimationTime(spec.baleCloseAnimationName, animTime) |
370 | elseif state == Baler.UNLOADING_OPEN or state == Baler.UNLOADING_OPENING then |
371 | self:setIsUnloadingBale(true, true) |
372 | self:setRealAnimationTime(spec.baleUnloadAnimationName, animTime) |
373 | end |
374 | end |
375 | |
376 | local numBales = streamReadUInt8(streamId) |
377 | for i=1, numBales do |
378 | local fillType = streamReadInt8(streamId) |
379 | local fillLevel = streamReadFloat32(streamId) |
380 | self:createBale(fillType, fillLevel) |
381 | if spec.baleAnimCurve ~= nil then |
382 | local baleTime = streamReadFloat32(streamId) |
383 | self:setBaleTime(i, baleTime) |
384 | end |
385 | end |
386 | |
387 | spec.lastAreaBiggerZero = streamReadBool(streamId) |
388 | end |
onReadUpdateStream
DescriptionDefinitiononReadUpdateStream()Code
421 | function Baler:onReadUpdateStream(streamId, timestamp, connection) |
422 | local spec = self.spec_baler |
423 | |
424 | if connection:getIsServer() then |
425 | spec.lastAreaBiggerZero = streamReadBool(streamId) |
426 | spec.fillEffectType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
427 | end |
428 | end |
onRegisterActionEvents
DescriptionDefinitiononRegisterActionEvents()Code
1161 | function Baler:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection) |
1162 | if self.isClient then |
1163 | local spec = self.spec_baler |
1164 | self:clearActionEventsTable(spec.actionEvents) |
1165 | |
1166 | if isActiveForInputIgnoreSelection and not spec.automaticDrop then |
1167 | local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.IMPLEMENT_EXTRA3, self, Baler.actionEventUnloading, false, true, false, true, nil) |
1168 | g_inputBinding:setActionEventText(actionEventId, g_i18n:getText("action_closeCover")) |
1169 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH) |
1170 | end |
1171 | end |
1172 | end |
onStartWorkAreaProcessing
DescriptionDefinitiononStartWorkAreaProcessing()Code
1176 | function Baler:onStartWorkAreaProcessing(dt) |
1177 | local spec = self.spec_baler |
1178 | |
1179 | if self.isServer then |
1180 | spec.lastAreaBiggerZero = false |
1181 | spec.workAreaParameters.lastPickedUpLiters = 0 |
1182 | spec.workAreaParameters.lastPickedUpFillType = FillType.UNKNOWN |
1183 | end |
1184 | end |
onTurnedOff
DescriptionDefinitiononTurnedOff()Code
732 | function Baler:onTurnedOff() |
733 | if self.isClient then |
734 | local spec = self.spec_baler |
735 | g_effectManager:stopEffects(spec.fillEffects) |
736 | g_animationManager:stopAnimations(spec.animationNodes) |
737 | g_soundManager:stopSamples(spec.samples) |
738 | end |
739 | end |
onTurnedOn
DescriptionDefinitiononTurnedOn()Code
719 | function Baler:onTurnedOn() |
720 | if self.setFoldState ~= nil then |
721 | self:setFoldState(-1, false) |
722 | end |
723 | if self.isClient then |
724 | local spec = self.spec_baler |
725 | g_animationManager:startAnimations(spec.animationNodes) |
726 | g_soundManager:playSample(spec.samples.work) |
727 | end |
728 | end |
onUpdate
DescriptionDefinitiononUpdate()Code
443 | function Baler:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
444 | local spec = self.spec_baler |
445 | |
446 | if self.isServer then |
447 | if self.isAddedToPhysics then |
448 | if spec.createBaleNextFrame ~= nil and spec.createBaleNextFrame then |
449 | self:finishBale() |
450 | spec.createBaleNextFrame = nil |
451 | end |
452 | end |
453 | end |
454 | end |
onUpdateTick
DescriptionDefinitiononUpdateTick()Code
458 | function Baler:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
459 | local spec = self.spec_baler |
460 | |
461 | if self:getIsTurnedOn() then |
462 | if self.isClient then |
463 | |
464 | if spec.lastAreaBiggerZero and spec.fillEffectType ~= FillType.UNKNOWN then |
465 | spec.lastAreaBiggerZeroTime = 500 |
466 | elseif spec.lastAreaBiggerZeroTime > 0 then |
467 | spec.lastAreaBiggerZeroTime = math.max(spec.lastAreaBiggerZeroTime - dt, 0) |
468 | end |
469 | |
470 | if spec.lastAreaBiggerZeroTime > 0 then |
471 | g_effectManager:setFillType(spec.fillEffects, spec.fillEffectType) |
472 | g_effectManager:startEffects(spec.fillEffects) |
473 | else |
474 | g_effectManager:stopEffects(spec.fillEffects) |
475 | end |
476 | |
477 | if spec.knotCleaningTimer <= g_currentMission.time then |
478 | g_soundManager:playSample(spec.samples.knotCleaning) |
479 | spec.knotCleaningTimer = g_currentMission.time + spec.knotCleaningTime |
480 | end |
481 | |
482 | if spec.compactingAnimation ~= nil and spec.unloadingState == Baler.UNLOADING_CLOSED then |
483 | if spec.compactingAnimationTime <= g_currentMission.time then |
484 | local fillLevel = self:getFillUnitFillLevelPercentage(spec.fillUnitIndex) |
485 | local stopTime = MathUtil.lerp(spec.compactingAnimationMinTime, spec.compactingAnimationMaxTime, fillLevel) |
486 | if stopTime > 0 then |
487 | self:setAnimationStopTime(spec.compactingAnimation, MathUtil.clamp(stopTime, 0, 1)) |
488 | self:playAnimation(spec.compactingAnimation, spec.compactingAnimationSpeed, self:getAnimationTime(spec.compactingAnimation), false) |
489 | spec.compactingAnimationTime = math.huge |
490 | end |
491 | end |
492 | |
493 | if spec.compactingAnimationTime == math.huge then |
494 | if not self:getIsAnimationPlaying(spec.compactingAnimation) then |
495 | spec.compactingAnimationCompactTimer = spec.compactingAnimationCompactTimer - dt |
496 | if spec.compactingAnimationCompactTimer < 0 then |
497 | self:playAnimation(spec.compactingAnimation, -spec.compactingAnimationSpeed, self:getAnimationTime(spec.compactingAnimation), false) |
498 | spec.compactingAnimationCompactTimer = spec.compactingAnimationCompactTime |
499 | end |
500 | |
501 | if self:getAnimationTime(spec.compactingAnimation) == 0 then |
502 | spec.compactingAnimationTime = g_currentMission.time + spec.compactingAnimationInterval |
503 | end |
504 | end |
505 | end |
506 | end |
507 | end |
508 | else |
509 | if spec.isBaleUnloading and self.isServer then |
510 | local deltaTime = dt / spec.baleUnloadingTime |
511 | self:moveBales(deltaTime) |
512 | end |
513 | end |
514 | |
515 | if self.isClient then |
516 | --delete dummy bale on client after physical bale is displayed |
517 | if spec.unloadingState == Baler.UNLOADING_OPEN then |
518 | if getNumOfChildren(spec.baleAnimRoot) > 0 then |
519 | delete(getChildAt(spec.baleAnimRoot, 0)) |
520 | end |
521 | end |
522 | end |
523 | |
524 | if spec.unloadingState == Baler.UNLOADING_OPENING then |
525 | local isPlaying = self:getIsAnimationPlaying(spec.baleUnloadAnimationName) |
526 | local animTime = self:getRealAnimationTime(spec.baleUnloadAnimationName) |
527 | if not isPlaying or animTime >= spec.baleDropAnimTime then |
528 | if table.getn(spec.bales) > 0 then |
529 | self:dropBale(1) |
530 | if self.isServer then |
531 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -math.huge, self:getFillUnitFillType(spec.fillUnitIndex), ToolType.UNDEFINED) |
532 | end |
533 | end |
534 | if not isPlaying then |
535 | spec.unloadingState = Baler.UNLOADING_OPEN |
536 | |
537 | if self.isClient then |
538 | g_soundManager:stopSample(spec.samples.eject) |
539 | g_soundManager:stopSample(spec.samples.door) |
540 | g_animationManager:stopAnimations(spec.unloadAnimationNodes) |
541 | end |
542 | end |
543 | else |
544 | g_animationManager:startAnimations(spec.unloadAnimationNodes) |
545 | end |
546 | elseif spec.unloadingState == Baler.UNLOADING_CLOSING then |
547 | if not self:getIsAnimationPlaying(spec.baleCloseAnimationName) then |
548 | spec.unloadingState = Baler.UNLOADING_CLOSED |
549 | if self.isClient then |
550 | g_soundManager:stopSample(spec.samples.door) |
551 | end |
552 | end |
553 | end |
554 | |
555 | -- on client side it can happen that the baler is closed 1 frame before the animation is synced completelly |
556 | -- in this case we drop the bale here |
557 | if spec.unloadingState == Baler.UNLOADING_OPEN or spec.unloadingState == Baler.UNLOADING_CLOSING then |
558 | if not self.isServer then |
559 | if table.getn(spec.bales) > 0 then |
560 | self:dropBale(1) |
561 | end |
562 | end |
563 | end |
564 | |
565 | -- update action event visibility and text |
566 | local actionEvent = spec.actionEvents[InputAction.IMPLEMENT_EXTRA3] |
567 | if actionEvent ~= nil then |
568 | local showAction = false |
569 | |
570 | if self:isUnloadingAllowed() then |
571 | if spec.baleUnloadAnimationName ~= nil or spec.allowsBaleUnloading then |
572 | |
573 | if spec.unloadingState == Baler.UNLOADING_CLOSED then |
574 | if self:getCanUnloadUnfinishedBale() then |
575 | g_inputBinding:setActionEventText(actionEvent.actionEventId, g_i18n:getText("action_unloadUnfinishedBale")) |
576 | showAction = true |
577 | end |
578 | if table.getn(spec.bales) > 0 then |
579 | g_inputBinding:setActionEventText(actionEvent.actionEventId, g_i18n:getText("action_unloadBaler")) |
580 | showAction = true |
581 | end |
582 | elseif spec.unloadingState == Baler.UNLOADING_OPEN then |
583 | if spec.baleUnloadAnimationName ~= nil then |
584 | g_inputBinding:setActionEventText(actionEvent.actionEventId, g_i18n:getText("action_closeBack")) |
585 | showAction = true |
586 | end |
587 | end |
588 | end |
589 | end |
590 | |
591 | g_inputBinding:setActionEventActive(actionEvent.actionEventId, showAction) |
592 | end |
593 | |
594 | --automatically drop bale and close door afterwards |
595 | if self.isServer then |
596 | if (spec.automaticDrop ~= nil and spec.automaticDrop) or self:getIsAIActive() then |
597 | if self:isUnloadingAllowed() then |
598 | if spec.baleUnloadAnimationName ~= nil or spec.allowsBaleUnloading then |
599 | if spec.unloadingState == Baler.UNLOADING_CLOSED then |
600 | if table.getn(spec.bales) > 0 then |
601 | self:setIsUnloadingBale(true) |
602 | end |
603 | elseif spec.unloadingState == Baler.UNLOADING_OPEN then |
604 | if spec.baleUnloadAnimationName ~= nil then |
605 | self:setIsUnloadingBale(false) |
606 | end |
607 | end |
608 | end |
609 | end |
610 | end |
611 | |
612 | spec.pickUpLitersBuffer:add(spec.workAreaParameters.lastPickedUpLiters) |
613 | end |
614 | end |
onWriteStream
DescriptionDefinitiononWriteStream()Code
392 | function Baler:onWriteStream(streamId, connection) |
393 | local spec = self.spec_baler |
394 | |
395 | if spec.baleUnloadAnimationName ~= nil then |
396 | streamWriteUIntN(streamId, spec.unloadingState, 7) |
397 | local animTime = 0 |
398 | if spec.unloadingState == Baler.UNLOADING_CLOSED or spec.unloadingState == Baler.UNLOADING_CLOSING then |
399 | animTime = self:getRealAnimationTime(spec.baleCloseAnimationName) |
400 | elseif spec.unloadingState == Baler.UNLOADING_OPEN or spec.unloadingState == Baler.UNLOADING_OPENING then |
401 | animTime = self:getRealAnimationTime(spec.baleUnloadAnimationName) |
402 | end |
403 | streamWriteFloat32(streamId, animTime) |
404 | end |
405 | |
406 | streamWriteUInt8(streamId, table.getn(spec.bales)) |
407 | for i=1, table.getn(spec.bales) do |
408 | local bale = spec.bales[i] |
409 | streamWriteInt8(streamId, bale.fillType) |
410 | streamWriteFloat32(streamId, bale.fillLevel) |
411 | if spec.baleAnimCurve ~= nil then |
412 | streamWriteFloat32(streamId, bale.time) |
413 | end |
414 | end |
415 | |
416 | streamWriteBool(streamId, spec.lastAreaBiggerZero) |
417 | end |
onWriteUpdateStream
DescriptionDefinitiononWriteUpdateStream()Code
432 | function Baler:onWriteUpdateStream(streamId, connection, dirtyMask) |
433 | local spec = self.spec_baler |
434 | |
435 | if not connection:getIsServer() then |
436 | streamWriteBool(streamId, spec.lastAreaBiggerZero) |
437 | streamWriteUIntN(streamId, spec.fillEffectTypeSent, FillTypeManager.SEND_NUM_BITS) |
438 | end |
439 | end |
prerequisitesPresent
DescriptionDefinitionprerequisitesPresent()Code
30 | function Baler.prerequisitesPresent(specializations) |
31 | return SpecializationUtil.hasSpecialization(FillUnit, specializations) and |
32 | SpecializationUtil.hasSpecialization(WorkArea, specializations) and |
33 | SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) |
34 | end |
processBalerArea
DescriptionDefinitionprocessBalerArea()Code
1129 | function Baler:processBalerArea(workArea, dt) |
1130 | local spec = self.spec_baler |
1131 | |
1132 | local lsx, lsy, lsz, lex, ley, lez, lineRadius = DensityMapHeightUtil.getLineByArea(workArea.start, workArea.width, workArea.height) |
1133 | local currentFillType = self:getFillUnitFillType(spec.fillUnitIndex) |
1134 | if self.isServer then |
1135 | spec.fillEffectType = FillType.UNKNOWN |
1136 | end |
1137 | for _, fillTypeIndex in ipairs(spec.pickupFillTypes) do |
1138 | local pickedUpLiters = -DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, fillTypeIndex, lsx, lsy, lsz, lex, ley, lez, lineRadius, nil, nil, false, nil) |
1139 | if pickedUpLiters > 0 then |
1140 | if self.isServer then |
1141 | spec.fillEffectType = fillTypeIndex |
1142 | end |
1143 | |
1144 | if currentFillType == FillType.UNKNOWN then |
1145 | spec.workAreaParameters.lastPickedUpFillType = fillTypeIndex |
1146 | currentFillType = fillTypeIndex |
1147 | end |
1148 | |
1149 | spec.workAreaParameters.lastPickedUpFillType = currentFillType |
1150 | spec.workAreaParameters.lastPickedUpLiters = spec.workAreaParameters.lastPickedUpLiters + pickedUpLiters |
1151 | |
1152 | return pickedUpLiters, pickedUpLiters |
1153 | end |
1154 | end |
1155 | |
1156 | return 0, 0 |
1157 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
71 | function Baler.registerEventListeners(vehicleType) |
72 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", Baler) |
73 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Baler) |
74 | SpecializationUtil.registerEventListener(vehicleType, "onLoadFinished", Baler) |
75 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", Baler) |
76 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Baler) |
77 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Baler) |
78 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", Baler) |
79 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", Baler) |
80 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Baler) |
81 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Baler) |
82 | SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", Baler) |
83 | SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", Baler) |
84 | SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", Baler) |
85 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", Baler) |
86 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", Baler) |
87 | SpecializationUtil.registerEventListener(vehicleType, "onFillUnitFillLevelChanged", Baler) |
88 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
38 | function Baler.registerFunctions(vehicleType) |
39 | SpecializationUtil.registerFunction(vehicleType, "processBalerArea", Baler.processBalerArea) |
40 | |
41 | SpecializationUtil.registerFunction(vehicleType, "isUnloadingAllowed", Baler.isUnloadingAllowed) |
42 | SpecializationUtil.registerFunction(vehicleType, "getTimeFromLevel", Baler.getTimeFromLevel) |
43 | SpecializationUtil.registerFunction(vehicleType, "moveBales", Baler.moveBales) |
44 | SpecializationUtil.registerFunction(vehicleType, "moveBale", Baler.moveBale) |
45 | SpecializationUtil.registerFunction(vehicleType, "setIsUnloadingBale", Baler.setIsUnloadingBale) |
46 | SpecializationUtil.registerFunction(vehicleType, "dropBale", Baler.dropBale) |
47 | SpecializationUtil.registerFunction(vehicleType, "finishBale", Baler.finishBale) |
48 | SpecializationUtil.registerFunction(vehicleType, "createBale", Baler.createBale) |
49 | SpecializationUtil.registerFunction(vehicleType, "setBaleTime", Baler.setBaleTime) |
50 | SpecializationUtil.registerFunction(vehicleType, "getCanUnloadUnfinishedBale", Baler.getCanUnloadUnfinishedBale) |
51 | SpecializationUtil.registerFunction(vehicleType, "deleteDummyBale", Baler.deleteDummyBale) |
52 | SpecializationUtil.registerFunction(vehicleType, "createDummyBale", Baler.createDummyBale) |
53 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
57 | function Baler.registerOverwrittenFunctions(vehicleType) |
58 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSpeedRotatingPartFromXML", Baler.loadSpeedRotatingPartFromXML) |
59 | |
60 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", Baler.doCheckSpeedLimit) |
61 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsSpeedRotatingPartActive", Baler.getIsSpeedRotatingPartActive) |
62 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeTurnedOn", Baler.getCanBeTurnedOn) |
63 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsFoldAllowed", Baler.getIsFoldAllowed) |
64 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsWorkAreaActive", Baler.getIsWorkAreaActive) |
65 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getConsumingLoad", Baler.getConsumingLoad) |
66 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", Baler.getCanBeSelected) |
67 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
333 | function Baler:saveToXMLFile(xmlFile, key, usedModNames) |
334 | if self.isReconfigurating == nil or not self.isReconfigurating then |
335 | local spec = self.spec_baler |
336 | |
337 | -- never save bales on round balers since they can only have one bale and that is saved in the fillUnit |
338 | -- if the fill unit is not full we try to save the bale (maybe the user saves while unloading) |
339 | if spec.baleUnloadAnimationName == nil or self:getFillUnitFreeCapacity(spec.fillUnitIndex) > 0 then |
340 | setXMLInt(xmlFile, key.."#numBales", #spec.bales) |
341 | |
342 | for k, bale in ipairs(spec.bales) do |
343 | local baleKey = string.format("%s.bale(%d)", key, k-1) |
344 | local fillTypeStr = "UNKNOWN" |
345 | if bale.fillType ~= FillType.UNKNOWN then |
346 | fillTypeStr = g_fillTypeManager:getFillTypeNameByIndex(bale.fillType) |
347 | end |
348 | setXMLString(xmlFile, baleKey.."#fillType", fillTypeStr) |
349 | setXMLFloat(xmlFile, baleKey.."#fillLevel", bale.fillLevel) |
350 | |
351 | if spec.baleAnimCurve ~= nil then |
352 | setXMLFloat(xmlFile, baleKey.."#baleTime", bale.time) |
353 | end |
354 | end |
355 | end |
356 | end |
357 | end |
setBaleTime
DescriptionDefinitionsetBaleTime()Code
837 | function Baler:setBaleTime(i, baleTime, noEventSend) |
838 | local spec = self.spec_baler |
839 | |
840 | if spec.baleAnimCurve ~= nil then |
841 | local bale = spec.bales[i] |
842 | if bale ~= nil then |
843 | bale.time = baleTime |
844 | if self.isServer then |
845 | local v = spec.baleAnimCurve:get(bale.time) |
846 | setTranslation(bale.baleJointNode, v[1], v[2], v[3]) |
847 | setRotation(bale.baleJointNode, v[4], v[5], v[6]) |
848 | if bale.baleJointIndex ~= 0 then |
849 | setJointFrame(bale.baleJointIndex, 0, bale.baleJointNode) |
850 | end |
851 | end |
852 | if bale.time >= 1 then |
853 | self:dropBale(i) |
854 | end |
855 | if table.getn(spec.bales) == 0 then |
856 | spec.isBaleUnloading = false |
857 | end |
858 | if self.isServer then |
859 | if noEventSend == nil or not noEventSend then |
860 | g_server:broadcastEvent(BalerSetBaleTimeEvent:new(self, i, bale.time), nil, nil, self) |
861 | end |
862 | end |
863 | end |
864 | end |
865 | end |
setIsUnloadingBale
DescriptionDefinitionsetIsUnloadingBale()Code
761 | function Baler:setIsUnloadingBale(isUnloadingBale, noEventSend) |
762 | local spec = self.spec_baler |
763 | |
764 | if spec.baleUnloadAnimationName ~= nil then |
765 | if isUnloadingBale then |
766 | if spec.unloadingState ~= Baler.UNLOADING_OPENING then |
767 | |
768 | if table.getn(spec.bales) == 0 and spec.canUnloadUnfinishedBale and self:getFillUnitFillLevel(spec.fillUnitIndex) > spec.unfinishedBaleThreshold then |
769 | local fillTypeIndex = self:getFillUnitFillType(spec.fillUnitIndex) |
770 | local currentFillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex) |
771 | local delta = self:getFillUnitFreeCapacity(spec.fillUnitIndex) |
772 | spec.lastBaleFillLevel = currentFillLevel |
773 | self:setFillUnitFillLevelToDisplay(spec.fillUnitIndex, currentFillLevel) |
774 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, delta, fillTypeIndex, ToolType.UNDEFINED) |
775 | end |
776 | |
777 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
778 | spec.unloadingState = Baler.UNLOADING_OPENING |
779 | if self.isClient then |
780 | g_soundManager:playSample(spec.samples.eject) |
781 | g_soundManager:playSample(spec.samples.door) |
782 | end |
783 | self:playAnimation(spec.baleUnloadAnimationName, spec.baleUnloadAnimationSpeed, nil, true) |
784 | end |
785 | else |
786 | if spec.unloadingState ~= Baler.UNLOADING_CLOSING and spec.unloadingState ~= Baler.UNLOADING_CLOSED then |
787 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
788 | spec.unloadingState = Baler.UNLOADING_CLOSING |
789 | if self.isClient then |
790 | g_soundManager:playSample(spec.samples.door) |
791 | end |
792 | self:playAnimation(spec.baleCloseAnimationName, spec.baleCloseAnimationSpeed, nil, true) |
793 | end |
794 | end |
795 | elseif spec.allowsBaleUnloading then |
796 | if isUnloadingBale then |
797 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
798 | spec.isBaleUnloading = true |
799 | end |
800 | end |
801 | end |