Script v1.4.4.0
- Handtools
- Events
- Objects
- Placeables
- Triggers
- Utils
- Vehicles
- Specializations
- AIVehicle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BuiltInCutterTrailer
- BunkerSiloCompacter
- Combine
- ConveyorBelt
- Cover
- CrabSteering
- Crawler
- Cultivator
- Cutter
- Cylindered
- Drivable
- DynamicMountAttacher
- Fillable
- FillActivatable
- FillVolume
- Foldable
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- FuelTrailer
- Honk
- HookLiftContainer
- HookLiftTrailer
- Leveler
- Lights
- LivestockTrailer
- ManureBarrel
- ManureSpreader
- MixerWagon
- Motorized
- Mountable
- Mower
- NonTabbable
- Overloading
- Pickup
- Pipe
- Plough
- PowerConsumer
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- RidgeMarker
- Roller
- Ropes
- RotorSpreader
- SemiTrailerFront
- Shovel
- SowingMachine
- SpeedRotatingParts
- Sprayer
- Steerable
- StrawBlower
- StumpCutter
- Tedder
- TensionBelts
- Trailer
- TreePlanter
- TreePlanterActivatable
- TreeSaw
- TurnOnVehicle
- Washable
- WaterTrailer
- Weeder
- WheelRotations
- Windrower
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkParticles
Engine v7.0.0.2
- General
- Entity
- Node
- Scenegraph
- Lighting
- Camera
- Shape
- Particle System
- Physics
- Spline
- Animation
- Overlays
- Sound
- Input
- XML
- Network
- Callbacks
- Text Rendering
- Terrain Detail
- Tire Track
- Editor
- Rendering
- String
- Math
- I3D
- Fillplanes
Foundation Reference
Baler
DescriptionClass for all BalersFunctions
- initSpecialization
- prerequisitesPresent
- preLoad
- load
- postLoad
- delete
- readStream
- writeStream
- readUpdateStream
- writeUpdateStream
- getSaveAttributesAndNodes
- update
- updateTick
- draw
- getIsFoldAllowed
- onDeactivate
- onDeactivateSounds
- setUnitFillLevel
- onTurnedOn
- onTurnedOff
- doCheckSpeedLimit
- isUnloadingAllowed
- setIsUnloadingBale
- getTimeFromLevel
- moveBales
- moveBale
- setBaleTime
- allowFillType
- allowPickingUp
- createBale
- dropBale
- getIsTurnedOnAllowed
- loadWorkAreaFromXML
- loadSpeedRotatingPartFromXML
- getIsSpeedRotatingPartActive
- getDefaultSpeedLimit
- processBalerAreas
initSpecialization
DescriptionCalled on specialization initializingDefinition
initSpecialization()Code
25 | function Baler.initSpecialization() |
26 | WorkArea.registerAreaType("baler") |
27 | end |
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
33 | function Baler.prerequisitesPresent(specializations) |
34 | return SpecializationUtil.hasSpecialization(Fillable, specializations) and SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) and SpecializationUtil.hasSpecialization(Pickup, specializations) |
35 | end |
preLoad
DescriptionCalled before loadingDefinition
preLoad(table savegame)Arguments
table | savegame | savegame |
40 | function Baler:preLoad(savegame) |
41 | self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Baler.loadWorkAreaFromXML) |
42 | self.loadSpeedRotatingPartFromXML = Utils.overwrittenFunction(self.loadSpeedRotatingPartFromXML, Baler.loadSpeedRotatingPartFromXML) |
43 | end |
load
DescriptionCalled on loadingDefinition
load(table savegame)Arguments
table | savegame | savegame |
48 | function Baler:load(savegame) |
49 | |
50 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.fillScale#value", "vehicle.baler#fillScale") |
51 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleAnimation", "vehicle.baler.baleAnimation") |
52 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleAnimation", "vehicle.baler.baleAnimation") |
53 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.balerUVScrollParts.balerUVScrollPart", "vehicle.baler.uvScrollParts.uvScrollPart") |
54 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.knotingAnimation", "vehicle.baler.knotingAnimation") |
55 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.balingAnimation", "vehicle.baler.balingAnimation") |
56 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleUnloading#allowed", "vehicle.baler.baleUnloading#allowed") |
57 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleUnloading#time", "vehicle.baler.baleUnloading#time") |
58 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleUnloading#foldThreshold", "vehicle.baler.baleUnloading#foldThreshold") |
59 | |
60 | self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, Baler.doCheckSpeedLimit) |
61 | self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, Baler.getIsSpeedRotatingPartActive) |
62 | self.allowPickingUp = Utils.overwrittenFunction(self.allowPickingUp, Baler.allowPickingUp) |
63 | self.getIsTurnedOnAllowed = Utils.overwrittenFunction(self.getIsTurnedOnAllowed, Baler.getIsTurnedOnAllowed) |
64 | self.getIsFoldAllowed = Utils.overwrittenFunction(self.getIsFoldAllowed, Baler.getIsFoldAllowed) |
65 | self.setUnitFillLevel = Utils.appendedFunction(self.setUnitFillLevel, Baler.setUnitFillLevel) |
66 | self.isUnloadingAllowed = Baler.isUnloadingAllowed |
67 | self.getTimeFromLevel = Baler.getTimeFromLevel |
68 | self.moveBales = SpecializationUtil.callSpecializationsFunction("moveBales") |
69 | self.moveBale = SpecializationUtil.callSpecializationsFunction("moveBale") |
70 | self.allowFillType = Baler.allowFillType |
71 | self.setIsUnloadingBale = Baler.setIsUnloadingBale |
72 | self.dropBale = Baler.dropBale |
73 | self.createBale = Baler.createBale |
74 | self.setBaleTime = Baler.setBaleTime |
75 | self.processBalerAreas = Baler.processBalerAreas |
76 | |
77 | self.baler = {} |
78 | self.baler.fillScale = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.fillScale#value"), 1) |
79 | self.baler.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#fillUnitIndex"), 1) |
80 | self.baler.unloadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#unloadInfoIndex"), 1) |
81 | self.baler.loadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#loadInfoIndex"), 1) |
82 | self.baler.dischargeInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#dischargeInfoIndex"), 1) |
83 | |
84 | local firstBaleMarker = getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#firstBaleMarker") |
85 | if firstBaleMarker ~= nil then |
86 | local baleAnimCurve = AnimCurve:new(linearInterpolatorN) |
87 | local keyI = 0 |
88 | while true do |
89 | local key = string.format("vehicle.baler.baleAnimation.key(%d)", keyI) |
90 | local t = getXMLFloat(self.xmlFile, key.."#time") |
91 | local x,y,z = Utils.getVectorFromString(getXMLString(self.xmlFile, key.."#pos")) |
92 | if x == nil or y == nil or z == nil then |
93 | break |
94 | end |
95 | local rx, ry, rz = Utils.getVectorFromString(getXMLString(self.xmlFile, key.."#rot")) |
96 | rx = math.rad(Utils.getNoNil(rx, 0)) |
97 | ry = math.rad(Utils.getNoNil(ry, 0)) |
98 | rz = math.rad(Utils.getNoNil(rz, 0)) |
99 | baleAnimCurve:addKeyframe({ v={x, y, z, rx, ry, rz}, time = t}) |
100 | keyI = keyI +1 |
101 | end |
102 | if keyI > 0 then |
103 | self.baler.baleAnimCurve = baleAnimCurve |
104 | self.baler.firstBaleMarker = firstBaleMarker |
105 | end |
106 | end |
107 | self.baler.baleAnimRoot, self.baler.baleAnimRootComponent = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#node")) |
108 | if self.baler.baleAnimRoot == nil then |
109 | self.baler.baleAnimRoot = self.components[1].node |
110 | self.baler.baleAnimRootComponent = self.components[1].node |
111 | end |
112 | -- there is no standard bale animation, load the unload animation (for round baler) |
113 | if self.baler.firstBaleMarker == nil then |
114 | local unloadAnimationName = getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#unloadAnimationName") |
115 | local closeAnimationName = getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#closeAnimationName") |
116 | local unloadAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#unloadAnimationSpeed"), 1) |
117 | local closeAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#closeAnimationSpeed"), 1) |
118 | if unloadAnimationName ~= nil and closeAnimationName ~= nil then |
119 | if self.playAnimation ~= nil and self.animations ~= nil then |
120 | if self.animations[unloadAnimationName] ~= nil and self.animations[closeAnimationName] ~= nil then |
121 | --print("has unload animation") |
122 | self.baler.baleUnloadAnimationName = unloadAnimationName |
123 | self.baler.baleUnloadAnimationSpeed = unloadAnimationSpeed |
124 | |
125 | self.baler.baleCloseAnimationName = closeAnimationName |
126 | self.baler.baleCloseAnimationSpeed = closeAnimationSpeed |
127 | |
128 | self.baler.baleDropAnimTime = getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#baleDropAnimTime") |
129 | if self.baler.baleDropAnimTime == nil then |
130 | self.baler.baleDropAnimTime = self:getAnimationDuration(self.baler.baleUnloadAnimationName) |
131 | else |
132 | self.baler.baleDropAnimTime = self.baler.baleDropAnimTime * 1000 |
133 | end |
134 | else |
135 | print("Error: Failed to find unload animations '"..unloadAnimationName.."' and '"..closeAnimationName.."' in '"..self.configFileName.."'.") |
136 | end |
137 | else |
138 | print("Error: There is an unload animation in '"..self.configFileName.."' but it is not a AnimatedVehicle. Change to a vehicle type which has the AnimatedVehicle specialization.") |
139 | end |
140 | end |
141 | end |
142 | |
143 | self.baler.baleTypes = {} |
144 | local i = 0 |
145 | while true do |
146 | local key = string.format("vehicle.baler.baleTypes.baleType(%d)", i) |
147 | if not hasXMLProperty(self.xmlFile, key) then |
148 | break |
149 | end |
150 | local isRoundBale = Utils.getNoNil(getXMLBool(self.xmlFile, key.."#isRoundBale"), false) |
151 | local width = Utils.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#width"), 1.2), 2) |
152 | local height = Utils.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#height"), 0.9), 2) |
153 | local length = Utils.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#length"), 2.4), 2) |
154 | local diameter = Utils.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#diameter"), 1.8), 2) |
155 | table.insert(self.baler.baleTypes, {isRoundBale=isRoundBale, width=width, height=height, length=length, diameter=diameter}) |
156 | i = i + 1 |
157 | end |
158 | self.baler.currentBaleTypeId = 1 |
159 | |
160 | if table.getn(self.baler.baleTypes) == 0 then |
161 | self.baler.baleTypes = nil |
162 | end |
163 | |
164 | if self.isClient then |
165 | self.baler.sampleBaler = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.baler.balerSound", nil, self.baseDirectory) |
166 | self.baler.sampleBalerAlarm = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.baler.balerAlarm", nil, self.baseDirectory) |
167 | self.baler.sampleBalerEject = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.baler.balerBaleEject", nil, self.baseDirectory) |
168 | self.baler.sampleBalerDoor = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.baler.balerDoor", nil, self.baseDirectory) |
169 | self.baler.sampleBalerKnotCleaning = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.baler.balerKnotCleaning", nil, self.baseDirectory) |
170 | self.baler.knotCleaningTime = 10000 |
171 | |
172 | self.baler.uvScrollParts = Utils.loadScrollers(self.components, self.xmlFile, "vehicle.baler.uvScrollParts.uvScrollPart", {}, false) |
173 | self.baler.turnedOnRotationNodes = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "baler", self.components) |
174 | |
175 | self.baler.fillEffects = EffectManager:loadEffect(self.xmlFile, "vehicle.baler.fillEffect", self.components, self) |
176 | |
177 | self.baler.knotingAnimation = getXMLString(self.xmlFile, "vehicle.baler.knotingAnimation#name") |
178 | self.baler.knotingAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.knotingAnimation#speed"), 1) |
179 | end |
180 | |
181 | self.baler.balingAnimationName = Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.baler.balingAnimation#name"), "") |
182 | if self.playAnimation == nil or self.getIsAnimationPlaying == nil then |
183 | self.baler.balingAnimationName = "" |
184 | end |
185 | |
186 | self.baler.lastAreaBiggerZero = false |
187 | self.baler.lastAreaBiggerZeroSent = false |
188 | self.baler.lastAreaBiggerZeroTime = 0 |
189 | |
190 | self.baler.unloadingState = Baler.UNLOADING_CLOSED |
191 | self.baler.pickupFillTypes = {} |
192 | |
193 | self.baler.bales = {} |
194 | self.baler.hasBaler = true |
195 | |
196 | self.baler.dummyBale = {} |
197 | self.baler.dummyBale.scaleNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#scaleNode")) |
198 | self.baler.dummyBale.baleNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#baleNode")) |
199 | self.baler.dummyBale.currentBaleFillType = FillUtil.FILLTYPE_UNKNOWN |
200 | self.baler.dummyBale.currentBale = nil |
201 | |
202 | self.baler.allowsBaleUnloading = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.baler.baleUnloading#allowed"), false) |
203 | self.baler.baleUnloadingTime = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleUnloading#time"), 4) * 1000 |
204 | self.baler.baleFoldThreshold = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleUnloading#foldThreshold"), 0.25) * self:getCapacity() |
205 | |
206 | self.baler.isBaleUnloading = false |
207 | self.baler.isSpeedLimitActive = false |
208 | |
209 | self.baler.dirtyFlag = self:getNextDirtyFlag() |
210 | end |
postLoad
DescriptionCalled after loadingDefinition
postLoad(table savegame)Arguments
table | savegame | savegame |
215 | function Baler:postLoad(savegame) |
216 | |
217 | for fillType, enabled in pairs(self:getUnitFillTypes(self.baler.fillUnitIndex)) do |
218 | if enabled and fillType ~= FillUtil.FILLTYPE_UNKNOWN then |
219 | if FruitUtil.fillTypeIsWindrow[fillType] then |
220 | table.insert(self.baler.pickupFillTypes, fillType) |
221 | end |
222 | end |
223 | end |
224 | |
225 | if self.isClient then |
226 | self.baler.fillParticleSystems = {} |
227 | self.baler.currentFillParticleSystem = nil |
228 | local i = 0 |
229 | while true do |
230 | local key = string.format("vehicle.baler.fillParticleSystems.emitterShape(%d)", i) |
231 | if not hasXMLProperty(self.xmlFile, key) then |
232 | break |
233 | end |
234 | |
235 | local emitterShape = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key.."#node")) |
236 | local particleType = getXMLString(self.xmlFile, key.."#particleType") |
237 | if emitterShape ~= nil then |
238 | for _, fillType in pairs(self.baler.pickupFillTypes) do |
239 | local particleSystem = MaterialUtil.getParticleSystem(fillType, particleType) |
240 | if particleSystem ~= nil then |
241 | if self.baler.fillParticleSystems[fillType] == nil then |
242 | self.baler.fillParticleSystems[fillType] = {} |
243 | end |
244 | table.insert(self.baler.fillParticleSystems[fillType], ParticleUtil.copyParticleSystem(self.xmlFile, key, particleSystem, emitterShape)) |
245 | end |
246 | end |
247 | end |
248 | i = i + 1 |
249 | end |
250 | end |
251 | |
252 | if savegame ~= nil and not savegame.resetVehicles then |
253 | local numBales = getXMLInt(savegame.xmlFile, savegame.key.."#numBales") |
254 | if numBales ~= nil then |
255 | self.baler.balesToLoad = {} |
256 | for i=1, numBales do |
257 | local baleKey = savegame.key..string.format(".bale(%d)", i-1) |
258 | local bale = {} |
259 | local fillTypeStr = getXMLString(savegame.xmlFile, baleKey.."#fillType") |
260 | local fillType = FillUtil.fillTypeNameToInt[fillTypeStr] |
261 | bale.fillType = fillType |
262 | bale.fillLevel = getXMLFloat(savegame.xmlFile, baleKey.."#fillLevel") |
263 | bale.baleTime = getXMLFloat(savegame.xmlFile, baleKey.."#baleTime") |
264 | table.insert(self.baler.balesToLoad, bale) |
265 | end |
266 | end |
267 | end |
268 | |
269 | if self.baler.firstBaleMarker == nil then |
270 | if self:getUnitFillLevel(self.baler.fillUnitIndex) >= self:getUnitCapacity(self.baler.fillUnitIndex) then |
271 | self.baler.baleToCreate = true; |
272 | end; |
273 | end; |
274 | end |
delete
DescriptionCalled on deletingDefinition
delete()Code
278 | function Baler:delete() |
279 | for k, _ in pairs(self.baler.bales) do |
280 | self:dropBale(k) |
281 | end |
282 | |
283 | if self.baler.dummyBale.currentBale ~= nil then |
284 | delete(self.baler.dummyBale.currentBale) |
285 | self.baler.dummyBale.currentBale = nil |
286 | end |
287 | |
288 | if self.isClient then |
289 | SoundUtil.deleteSample(self.baler.sampleBaler) |
290 | SoundUtil.deleteSample(self.baler.sampleBalerAlarm) |
291 | SoundUtil.deleteSample(self.baler.sampleBalerDoor) |
292 | SoundUtil.deleteSample(self.baler.sampleBalerEject) |
293 | SoundUtil.deleteSample(self.baler.sampleBalerKnotCleaning) |
294 | |
295 | for _,v in pairs(self.baler.fillParticleSystems) do |
296 | ParticleUtil.deleteParticleSystems(v) |
297 | end |
298 | |
299 | EffectManager:deleteEffects(self.baler.fillEffects); |
300 | end |
301 | end |
readStream
DescriptionCalled on client side on joinDefinition
readStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
307 | function Baler:readStream(streamId, connection) |
308 | if self.baler.baleUnloadAnimationName ~= nil then |
309 | local state = streamReadUIntN(streamId, 7) |
310 | local animTime = streamReadFloat32(streamId) |
311 | if state == Baler.UNLOADING_CLOSED or state == Baler.UNLOADING_CLOSING then |
312 | self:setIsUnloadingBale(false, true) |
313 | self:setRealAnimationTime(self.baler.baleCloseAnimationName, animTime) |
314 | elseif state == Baler.UNLOADING_OPEN or state == Baler.UNLOADING_OPENING then |
315 | self:setIsUnloadingBale(true, true) |
316 | self:setRealAnimationTime(self.baler.baleUnloadAnimationName, animTime) |
317 | end |
318 | end |
319 | |
320 | local numBales = streamReadUInt8(streamId) |
321 | for i=1, numBales do |
322 | local fillType = streamReadInt8(streamId) |
323 | local fillLevel = streamReadFloat32(streamId) |
324 | self:createBale(fillType, fillLevel) |
325 | if self.baler.baleAnimCurve ~= nil then |
326 | local baleTime = streamReadFloat32(streamId) |
327 | self:setBaleTime(i, baleTime) |
328 | end |
329 | end |
330 | |
331 | self.baler.lastAreaBiggerZero = streamReadBool(streamId) |
332 | end |
writeStream
DescriptionCalled on server side on joinDefinition
writeStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
338 | function Baler:writeStream(streamId, connection) |
339 | |
340 | if self.baler.baleUnloadAnimationName ~= nil then |
341 | streamWriteUIntN(streamId, self.baler.unloadingState, 7) |
342 | local animTime = 0 |
343 | if self.baler.unloadingState == Baler.UNLOADING_CLOSED or self.baler.unloadingState == Baler.UNLOADING_CLOSING then |
344 | animTime = self:getRealAnimationTime(self.baler.baleCloseAnimationName) |
345 | elseif self.baler.unloadingState == Baler.UNLOADING_OPEN or self.baler.unloadingState == Baler.UNLOADING_OPENING then |
346 | animTime = self:getRealAnimationTime(self.baler.baleUnloadAnimationName) |
347 | end |
348 | streamWriteFloat32(streamId, animTime) |
349 | end |
350 | |
351 | streamWriteUInt8(streamId, table.getn(self.baler.bales)) |
352 | for i=1, table.getn(self.baler.bales) do |
353 | local bale = self.baler.bales[i] |
354 | streamWriteInt8(streamId, bale.fillType) |
355 | streamWriteFloat32(streamId, bale.fillLevel) |
356 | if self.baler.baleAnimCurve ~= nil then |
357 | streamWriteFloat32(streamId, bale.time) |
358 | end |
359 | end |
360 | |
361 | streamWriteBool(streamId, self.baler.lastAreaBiggerZero) |
362 | end |
readUpdateStream
DescriptionCalled on on updateDefinition
readUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
369 | function Baler:readUpdateStream(streamId, timestamp, connection) |
370 | if connection:getIsServer() then |
371 | self.baler.lastAreaBiggerZero = streamReadBool(streamId) |
372 | end |
373 | end |
writeUpdateStream
DescriptionCalled on on updateDefinition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)Arguments
integer | streamId | stream ID |
table | connection | connection |
integer | dirtyMask | dirty mask |
380 | function Baler:writeUpdateStream(streamId, connection, dirtyMask) |
381 | if not connection:getIsServer() then |
382 | streamWriteBool(streamId, self.baler.lastAreaBiggerZero) |
383 | end |
384 | end |
getSaveAttributesAndNodes
DescriptionReturns attributes and nodes to saveDefinition
getSaveAttributesAndNodes(table nodeIdent)Arguments
table | nodeIdent | node ident |
string | attributes | attributes |
string | nodes | nodes |
391 | function Baler:getSaveAttributesAndNodes(nodeIdent) |
392 | if self.baler.firstBaleMarker ~= nil then |
393 | local attributes = 'numBales="'..table.getn(self.baler.bales)..'"' |
394 | local nodes = "" |
395 | local baleNum = 0 |
396 | |
397 | for i=1, table.getn(self.baler.bales) do |
398 | local bale = self.baler.bales[i] |
399 | local fillTypeStr = "unknown" |
400 | if bale.fillType ~= FillUtil.FILLTYPE_UNKNOWN then |
401 | fillTypeStr = FillUtil.fillTypeIntToName[bale.fillType] |
402 | end |
403 | |
404 | if baleNum>0 then |
405 | nodes = nodes.."\n" |
406 | end |
407 | nodes = nodes..nodeIdent..'<bale fillType="'..fillTypeStr..'" fillLevel="'..bale.fillLevel..'"' |
408 | if self.baler.baleAnimCurve ~= nil then |
409 | nodes = nodes..' baleTime="'..bale.time..'"' |
410 | end |
411 | nodes = nodes..' />' |
412 | baleNum = baleNum+1 |
413 | end |
414 | return attributes,nodes |
415 | end; |
416 | |
417 | return "",""; |
418 | end |
update
DescriptionCalled on updateDefinition
update(float dt)Arguments
float | dt | time since last call in ms |
429 | function Baler:update(dt) |
430 | |
431 | if self.firstTimeRun and self.baler.balesToLoad ~= nil then |
432 | if table.getn(self.baler.balesToLoad) > 0 then |
433 | local v = self.baler.balesToLoad[1]; |
434 | |
435 | if v.targetBaleTime == nil then |
436 | self:createBale(v.fillType, v.fillLevel) |
437 | self:setBaleTime(table.getn(self.baler.bales), 0, true); |
438 | v.targetBaleTime = v.baleTime; |
439 | v.baleTime = 0; |
440 | else |
441 | v.baleTime = math.min(v.baleTime + dt / 1000, v.targetBaleTime); |
442 | self:setBaleTime(table.getn(self.baler.bales), v.baleTime, true); |
443 | |
444 | if v.baleTime == v.targetBaleTime then |
445 | |
446 | local index = table.getn(self.baler.balesToLoad); |
447 | if index == 1 then |
448 | self.baler.balesToLoad = nil; |
449 | else |
450 | table.remove(self.baler.balesToLoad, 1); |
451 | end; |
452 | end; |
453 | end; |
454 | end; |
455 | end |
456 | |
457 | if self.firstTimeRun and self.baler.baleToCreate ~= nil then |
458 | self:createBale(self:getUnitFillType(self.baler.fillUnitIndex), self:getUnitCapacity(self.baler.fillUnitIndex)) |
459 | g_server:broadcastEvent(BalerCreateBaleEvent:new(self, self:getUnitFillType(self.baler.fillUnitIndex), 0), nil, nil, self) |
460 | |
461 | self.baler.baleToCreate = nil; |
462 | end; |
463 | |
464 | if self:getIsActiveForInput() then |
465 | if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA3) then |
466 | if self:isUnloadingAllowed() then |
467 | if self.baler.baleUnloadAnimationName ~= nil or self.baler.allowsBaleUnloading then |
468 | if self.baler.unloadingState == Baler.UNLOADING_CLOSED then |
469 | if table.getn(self.baler.bales) > 0 then |
470 | self:setIsUnloadingBale(true) |
471 | end |
472 | elseif self.baler.unloadingState == Baler.UNLOADING_OPEN then |
473 | if self.baler.baleUnloadAnimationName ~= nil then |
474 | self:setIsUnloadingBale(false) |
475 | end |
476 | end |
477 | end |
478 | end |
479 | end |
480 | end |
481 | |
482 | if self.isClient then |
483 | Utils.updateRotationNodes(self, self.baler.turnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn() ) |
484 | Utils.updateScrollers(self.baler.uvScrollParts, dt, self:getIsActive() and self:getIsTurnedOn()) |
485 | end |
486 | end |
updateTick
DescriptionCalled on update tickDefinition
updateTick(float dt)Arguments
float | dt | time since last call in ms |
491 | function Baler:updateTick(dt) |
492 | self.baler.isSpeedLimitActive = false |
493 | |
494 | if self.isServer then |
495 | self.baler.lastAreaBiggerZero = false |
496 | end |
497 | |
498 | if self:getIsActive() then |
499 | if self:getIsTurnedOn() then |
500 | if self:allowPickingUp() then |
501 | if g_currentMission:getCanAddLimitedObject(FSBaseMission.LIMITED_OBJECT_TYPE_BALE) then |
502 | self.baler.isSpeedLimitActive = true |
503 | if self.isServer then |
504 | local workAreas, _, _ = self:getTypedNetworkAreas(WorkArea.AREATYPE_BALER, false) |
505 | local totalLiters = 0 |
506 | local usedFillType = FillUtil.FILLTYPE_UNKNOWN |
507 | if table.getn(workAreas) > 0 then |
508 | totalLiters, usedFillType = self:processBalerAreas(workAreas, self.baler.pickupFillTypes) |
509 | end |
510 | |
511 | if totalLiters > 0 then |
512 | self.baler.lastAreaBiggerZero = true |
513 | if self.baler.lastAreaBiggerZero ~= self.baler.lastAreaBiggerZeroSent then |
514 | self:raiseDirtyFlags(self.baler.dirtyFlag) |
515 | self.baler.lastAreaBiggerZeroSent = self.baler.lastAreaBiggerZero |
516 | end |
517 | |
518 | local deltaLevel = totalLiters * self.baler.fillScale |
519 | |
520 | if self.baler.baleUnloadAnimationName == nil then |
521 | -- move all bales |
522 | local deltaTime = self:getTimeFromLevel(deltaLevel) |
523 | self:moveBales(deltaTime) |
524 | end |
525 | |
526 | local oldFillLevel = self:getUnitFillLevel(self.baler.fillUnitIndex) |
527 | self:setUnitFillLevel(self.baler.fillUnitIndex, oldFillLevel+deltaLevel, usedFillType, true) |
528 | if self:getUnitFillLevel(self.baler.fillUnitIndex) >= self:getUnitCapacity(self.baler.fillUnitIndex) then |
529 | if self.baler.baleTypes ~= nil then |
530 | -- create bale |
531 | if self.baler.baleAnimCurve ~= nil then |
532 | local restDeltaFillLevel = deltaLevel - (self:getUnitFillLevel(self.baler.fillUnitIndex)-oldFillLevel) |
533 | self:setUnitFillLevel(self.baler.fillUnitIndex, restDeltaFillLevel, usedFillType, true) |
534 | |
535 | self:createBale(usedFillType, self:getUnitCapacity(self.baler.fillUnitIndex)) |
536 | |
537 | local numBales = table.getn(self.baler.bales) |
538 | local bale = self.baler.bales[numBales] |
539 | |
540 | self:moveBale(numBales, self:getTimeFromLevel(restDeltaFillLevel), true) |
541 | -- note: self.baler.bales[numBales] can not be accessed anymore since the bale might be dropped already |
542 | g_server:broadcastEvent(BalerCreateBaleEvent:new(self, usedFillType, bale.time), nil, nil, self) |
543 | elseif self.baler.baleUnloadAnimationName ~= nil then |
544 | self:createBale(usedFillType, self:getUnitCapacity(self.baler.fillUnitIndex)) |
545 | g_server:broadcastEvent(BalerCreateBaleEvent:new(self, usedFillType, 0), nil, nil, self) |
546 | end |
547 | end |
548 | end |
549 | end |
550 | end |
551 | else |
552 | g_currentMission:showBlinkingWarning(g_i18n:getText("warning_tooManyBales"), 500) |
553 | end |
554 | end |
555 | |
556 | |
557 | if self.baler.lastAreaBiggerZero and self.fillUnits[self.baler.fillUnitIndex].lastValidFillType ~= FillUtil.FILLTYPE_UNKNOWN then |
558 | self.baler.lastAreaBiggerZeroTime = 500 |
559 | else |
560 | if self.baler.lastAreaBiggerZeroTime > 0 then |
561 | self.baler.lastAreaBiggerZeroTime = self.baler.lastAreaBiggerZeroTime - dt |
562 | end |
563 | end |
564 | |
565 | if self.isClient then |
566 | if self.baler.fillEffects ~= nil then |
567 | if self.baler.lastAreaBiggerZeroTime > 0 then |
568 | EffectManager:setFillType(self.baler.fillEffects, self.fillUnits[self.baler.fillUnitIndex].lastValidFillType) |
569 | EffectManager:startEffects(self.baler.fillEffects) |
570 | else |
571 | EffectManager:stopEffects(self.baler.fillEffects) |
572 | end |
573 | end |
574 | |
575 | local currentFillParticleSystem = self.baler.fillParticleSystems[self.fillUnits[self.baler.fillUnitIndex].lastValidFillType] |
576 | if currentFillParticleSystem ~= self.baler.currentFillParticleSystem then |
577 | if self.baler.currentFillParticleSystem ~= nil then |
578 | for _, ps in pairs(self.baler.currentFillParticleSystem) do |
579 | ParticleUtil.setEmittingState(ps, false) |
580 | end |
581 | self.baler.currentFillParticleSystem = nil |
582 | end |
583 | self.baler.currentFillParticleSystem = currentFillParticleSystem |
584 | end |
585 | |
586 | if self.baler.currentFillParticleSystem ~= nil then |
587 | for _, ps in pairs(self.baler.currentFillParticleSystem) do |
588 | ParticleUtil.setEmittingState(ps, self.baler.lastAreaBiggerZeroTime > 0) |
589 | end |
590 | end |
591 | |
592 | if self:getIsActiveForSound() then |
593 | if self.baler.knotCleaningTime <= g_currentMission.time then |
594 | SoundUtil.playSample(self.baler.sampleBalerKnotCleaning, 1, 0, nil) |
595 | self.baler.knotCleaningTime = g_currentMission.time + 120000 |
596 | end |
597 | SoundUtil.playSample(self.baler.sampleBaler, 0, 0, nil) |
598 | end |
599 | end |
600 | else |
601 | if self.baler.isBaleUnloading and self.isServer then |
602 | local deltaTime = dt / self.baler.baleUnloadingTime |
603 | self:moveBales(deltaTime) |
604 | end |
605 | end |
606 | |
607 | if self.isClient then |
608 | if not self:getIsTurnedOn() then |
609 | SoundUtil.stopSample(self.baler.sampleBalerKnotCleaning) |
610 | SoundUtil.stopSample(self.baler.sampleBaler) |
611 | end |
612 | |
613 | if self:getIsTurnedOn() and self:getUnitFillLevel(self.baler.fillUnitIndex) > (self:getUnitCapacity(self.baler.fillUnitIndex) * 0.68) and self:getUnitFillLevel(self.baler.fillUnitIndex) < self:getUnitCapacity(self.baler.fillUnitIndex) then |
614 | -- start alarm sound |
615 | if self:getIsActiveForSound() then |
616 | SoundUtil.playSample(self.baler.sampleBalerAlarm, 0, 0, nil) |
617 | end |
618 | else |
619 | SoundUtil.stopSample(self.baler.sampleBalerAlarm) |
620 | end |
621 | |
622 | --delete dummy bale on client after physical bale is displayed |
623 | if self.baler.unloadingState == Baler.UNLOADING_OPEN then |
624 | if getNumOfChildren(self.baler.baleAnimRoot) > 0 then |
625 | delete(getChildAt(self.baler.baleAnimRoot, 0)); |
626 | end; |
627 | end; |
628 | end; |
629 | |
630 | if self.baler.unloadingState == Baler.UNLOADING_OPENING then |
631 | local isPlaying = self:getIsAnimationPlaying(self.baler.baleUnloadAnimationName) |
632 | local animTime = self:getRealAnimationTime(self.baler.baleUnloadAnimationName) |
633 | if not isPlaying or animTime >= self.baler.baleDropAnimTime then |
634 | if table.getn(self.baler.bales) > 0 then |
635 | self:dropBale(1) |
636 | if self.isServer then |
637 | self:setUnitFillLevel(self.baler.fillUnitIndex, 0, self:getUnitFillType(self.baler.fillUnitIndex), true) |
638 | end |
639 | end |
640 | if not isPlaying then |
641 | self.baler.unloadingState = Baler.UNLOADING_OPEN |
642 | |
643 | if self.isClient then |
644 | SoundUtil.stopSample(self.baler.sampleBalerEject) |
645 | SoundUtil.stopSample(self.baler.sampleBalerDoor) |
646 | end |
647 | end |
648 | end |
649 | elseif self.baler.unloadingState == Baler.UNLOADING_CLOSING then |
650 | if not self:getIsAnimationPlaying(self.baler.baleCloseAnimationName) then |
651 | self.baler.unloadingState = Baler.UNLOADING_CLOSED |
652 | if self.isClient then |
653 | SoundUtil.stopSample(self.baler.sampleBalerDoor) |
654 | end |
655 | end |
656 | end |
657 | end |
658 | end |
draw
DescriptionCalled on drawDefinition
draw()Code
662 | function Baler:draw() |
663 | if self.isClient then |
664 | if self:getIsActiveForInput(true) then |
665 | if self:isUnloadingAllowed() then |
666 | if self.baler.baleUnloadAnimationName ~= nil or self.baler.allowsBaleUnloading then |
667 | if self.baler.unloadingState == Baler.UNLOADING_CLOSED then |
668 | if table.getn(self.baler.bales) > 0 then |
669 | g_currentMission:addHelpButtonText(g_i18n:getText("action_unloadBaler"), InputBinding.IMPLEMENT_EXTRA3, nil, GS_PRIO_HIGH) |
670 | end |
671 | elseif self.baler.unloadingState == Baler.UNLOADING_OPEN then |
672 | if self.baler.baleUnloadAnimationName ~= nil then |
673 | g_currentMission:addHelpButtonText(g_i18n:getText("action_closeBack"), InputBinding.IMPLEMENT_EXTRA3, nil, GS_PRIO_HIGH) |
674 | end |
675 | end |
676 | end |
677 | end |
678 | end |
679 | end |
680 | end |
getIsFoldAllowed
DescriptionReturns if fold is allowedDefinition
getIsFoldAllowed(boolean onAiTurnOn)Arguments
boolean | onAiTurnOn | called on ai turn on |
boolean | allowsFold | allows folding |
686 | function Baler:getIsFoldAllowed(superFunc, onAiTurnOn) |
687 | if (table.getn(self.baler.bales) > 0 and self:getUnitFillLevel(self.baler.fillUnitIndex) > self.baler.baleFoldThreshold) or table.getn(self.baler.bales) > 1 or self:getIsTurnedOn() then |
688 | return false |
689 | end |
690 | |
691 | if superFunc ~= nil then |
692 | return superFunc(self, onAiTurnOn) |
693 | end |
694 | |
695 | return true |
696 | end |
onDeactivate
DescriptionCalled on deactivateDefinition
onDeactivate()Code
700 | function Baler:onDeactivate() |
701 | if self.baler.balingAnimationName ~= "" then |
702 | self:stopAnimation(self.baler.balingAnimationName, true) |
703 | end |
704 | if self.isClient then |
705 | if self.baler.fillEffects ~= nil then |
706 | EffectManager:stopEffects(self.baler.fillEffects) |
707 | end |
708 | if self.baler.currentFillParticleSystem ~= nil then |
709 | for _, ps in pairs(self.baler.currentFillParticleSystem) do |
710 | ParticleUtil.setEmittingState(ps, false) |
711 | end |
712 | end |
713 | end |
714 | end |
onDeactivateSounds
DescriptionCalled on deactivating soundsDefinition
onDeactivateSounds()Code
718 | function Baler:onDeactivateSounds() |
719 | if self.isClient then |
720 | SoundUtil.stopSample(self.baler.sampleBaler, true) |
721 | SoundUtil.stopSample(self.baler.sampleBalerAlarm, true) |
722 | SoundUtil.stopSample(self.baler.sampleBalerDoor, true) |
723 | SoundUtil.stopSample(self.baler.sampleBalerEject, true) |
724 | SoundUtil.stopSample(self.baler.sampleBalerKnotCleaning, true) |
725 | end |
726 | end |
setUnitFillLevel
DescriptionSet unit fill levelDefinition
setUnitFillLevel(integer fillUnitIndex, float fillLevel, integer fillType, boolean force, table fillInfo)Arguments
integer | fillUnitIndex | index of fill unit |
float | fillLevel | new fill level |
integer | fillType | fill type |
boolean | force | force action |
table | fillInfo | fill info for fill volume |
735 | function Baler:setUnitFillLevel(fillUnitIndex, fillLevel, fillType, force, fillInfo) |
736 | if fillUnitIndex == self.baler.fillUnitIndex then |
737 | if self.baler.dummyBale.baleNode ~= nil and fillLevel > 0 and fillLevel < self:getUnitCapacity(fillUnitIndex) and (self.baler.dummyBale.currentBale == nil or self.baler.dummyBale.currentBaleFillType ~= fillType) then |
738 | if self.baler.dummyBale.currentBale ~= nil then |
739 | delete(self.baler.dummyBale.currentBale) |
740 | self.baler.dummyBale.currentBale = nil |
741 | end |
742 | local t = self.baler.baleTypes[self.baler.currentBaleTypeId] |
743 | |
744 | local baleType = BaleUtil.getBale(fillType, t.width, t.height, t.length, t.diameter, t.isRoundBale) |
745 | |
746 | local baleRoot = Utils.loadSharedI3DFile(baleType.filename, self.baseDirectory, false, false) |
747 | local baleId = getChildAt(baleRoot, 0) |
748 | setRigidBodyType(baleId, "NoRigidBody") |
749 | link(self.baler.dummyBale.baleNode, baleId) |
750 | delete(baleRoot) |
751 | self.baler.dummyBale.currentBale = baleId |
752 | self.baler.dummyBale.currentBaleFillType = fillType |
753 | end |
754 | |
755 | if self.baler.dummyBale.currentBale ~= nil then |
756 | local percent = fillLevel / self:getUnitCapacity(fillUnitIndex) |
757 | local y = 1 |
758 | if getUserAttribute(self.baler.dummyBale.currentBale, "isRoundbale") then |
759 | y = percent |
760 | end |
761 | setScale(self.baler.dummyBale.scaleNode, 1, y, percent) |
762 | end |
763 | end |
764 | end |
onTurnedOn
DescriptionCalled on turn onDefinition
onTurnedOn(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
769 | function Baler:onTurnedOn(noEventSend) |
770 | if self.setFoldState ~= nil then |
771 | self:setFoldState(-1) |
772 | end |
773 | if self.baler.balingAnimationName ~= "" then |
774 | self:playAnimation(self.baler.balingAnimationName, 1, self:getAnimationTime(self.baler.balingAnimationName), true) |
775 | end |
776 | end |
onTurnedOff
DescriptionCalled on turn offDefinition
onTurnedOff(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
781 | function Baler:onTurnedOff(noEventSend) |
782 | if self.baler.balingAnimationName ~= "" then |
783 | self:stopAnimation(self.baler.balingAnimationName, true) |
784 | end |
785 | if self.isClient then |
786 | if self.baler.fillEffects ~= nil then |
787 | EffectManager:stopEffects(self.baler.fillEffects) |
788 | end |
789 | if self.baler.currentFillParticleSystem ~= nil then |
790 | for _, ps in pairs(self.baler.currentFillParticleSystem) do |
791 | ParticleUtil.setEmittingState(ps, false) |
792 | end |
793 | end |
794 | end |
795 | end |
doCheckSpeedLimit
DescriptionReturns if speed limit should be checkedDefinition
doCheckSpeedLimit()Return Values
boolean | checkSpeedlimit | check speed limit |
800 | function Baler:doCheckSpeedLimit(superFunc) |
801 | local parent = false |
802 | if superFunc ~= nil then |
803 | parent = superFunc(self) |
804 | end |
805 | |
806 | return parent or self.baler.isSpeedLimitActive |
807 | end |
isUnloadingAllowed
DescriptionReturns if unloading is allowedDefinition
isUnloadingAllowed()Return Values
boolean | isAllowed | unloading is allowed |
812 | function Baler:isUnloadingAllowed() |
813 | if self.hasBaleWrapper == nil or not self.hasBaleWrapper then |
814 | return not self.baler.allowsBaleUnloading or (self.baler.allowsBaleUnloading and not self:getIsTurnedOn() and not self.baler.isBaleUnloading) |
815 | end |
816 | |
817 | return self:allowsGrabbingBale() |
818 | end |
setIsUnloadingBale
DescriptionSet bale unloadingDefinition
setIsUnloadingBale(boolean isUnloadingBale, boolean noEventSend)Arguments
boolean | isUnloadingBale | is unloading bale |
boolean | noEventSend | no event send |
824 | function Baler:setIsUnloadingBale(isUnloadingBale, noEventSend) |
825 | if self.baler.baleUnloadAnimationName ~= nil then |
826 | if isUnloadingBale then |
827 | if self.baler.unloadingState ~= Baler.UNLOADING_OPENING then |
828 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
829 | self.baler.unloadingState = Baler.UNLOADING_OPENING |
830 | if self.isClient and self:getIsActiveForSound() then |
831 | SoundUtil.playSample(self.baler.sampleBalerEject, 1, 0, nil) |
832 | SoundUtil.playSample(self.baler.sampleBalerDoor, 1, 0, nil) |
833 | end |
834 | self:playAnimation(self.baler.baleUnloadAnimationName, self.baler.baleUnloadAnimationSpeed, nil, true) |
835 | end |
836 | else |
837 | if self.baler.unloadingState ~= Baler.UNLOADING_CLOSING then |
838 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
839 | self.baler.unloadingState = Baler.UNLOADING_CLOSING |
840 | if self.isClient and self:getIsActiveForSound() then |
841 | SoundUtil.playSample(self.baler.sampleBalerDoor, 1, 0, nil) |
842 | end |
843 | self:playAnimation(self.baler.baleCloseAnimationName, self.baler.baleCloseAnimationSpeed, nil, true) |
844 | end |
845 | end |
846 | elseif self.baler.allowsBaleUnloading then |
847 | if isUnloadingBale then |
848 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
849 | self.baler.isBaleUnloading = true |
850 | end |
851 | end |
852 | end |
getTimeFromLevel
DescriptionReturns time on animation depending on fill levelDefinition
getTimeFromLevel(float level)Arguments
float | level | current bale fill level |
858 | function Baler:getTimeFromLevel(level) |
859 | -- level = capacity -> time = firstBaleMarker |
860 | -- level = 0 -> time = 0 |
861 | if self.baler.firstBaleMarker ~= nil then |
862 | return level / self:getCapacity() * self.baler.firstBaleMarker |
863 | end |
864 | return 0 |
865 | end |
moveBales
DescriptionMove balesDefinition
moveBales(float dt)Arguments
float | dt | time since last call in ms |
870 | function Baler:moveBales(dt) |
871 | for i=table.getn(self.baler.bales), 1, -1 do |
872 | self:moveBale(i, dt) |
873 | end |
874 | end |
moveBale
DescriptionMove baleDefinition
moveBale(integer i, float dt, boolean noEventSend)Arguments
integer | i | index of bale to move |
float | dt | time since last call in ms |
boolean | noEventSend | no event send |
881 | function Baler:moveBale(i, dt, noEventSend) |
882 | local bale = self.baler.bales[i] |
883 | self:setBaleTime(i, bale.time + dt, noEventSend) |
884 | end |
setBaleTime
DescriptionSet bale animation timeDefinition
setBaleTime(integer i, float baleTime, boolean noEventSend)Arguments
integer | i | index of bale to move |
float | baleTime | new bale time |
boolean | noEventSend | no event send |
891 | function Baler:setBaleTime(i, baleTime, noEventSend) |
892 | if self.baler.baleAnimCurve ~= nil then |
893 | local bale = self.baler.bales[i] |
894 | bale.time = baleTime |
895 | if self.isServer then |
896 | local v = self.baler.baleAnimCurve:get(bale.time) |
897 | --setTranslation(bale.id, v[1], v[2], v[3]) |
898 | --setRotation(bale.id, v[4], v[5], v[6]) |
899 | setTranslation(bale.baleJointNode, v[1], v[2], v[3]) |
900 | setRotation(bale.baleJointNode, v[4], v[5], v[6]) |
901 | if bale.baleJointIndex ~= 0 then |
902 | setJointFrame(bale.baleJointIndex, 0, bale.baleJointNode) |
903 | end |
904 | end |
905 | if bale.time >= 1 then |
906 | self:dropBale(i) |
907 | end |
908 | if table.getn(self.baler.bales) == 0 then |
909 | self.baler.isBaleUnloading = false |
910 | end |
911 | if self.isServer then |
912 | if noEventSend == nil or not noEventSend then |
913 | g_server:broadcastEvent(BalerSetBaleTimeEvent:new(self, i, bale.time), nil, nil, self) |
914 | end |
915 | end |
916 | end |
917 | end |
allowFillType
DescriptionReturns if fill type is allowedDefinition
allowFillType(integer fillType)Arguments
integer | fillType | fill type |
boolean | isAllowed | fill type is allowed |
923 | function Baler:allowFillType(fillType) |
924 | return self.baler.pickupFillTypes[fillType] ~= nil |
925 | end |
allowPickingUp
DescriptionReturns if picking up is allowedDefinition
allowPickingUp()Return Values
boolean | isAllowed | picking up is allowed |
930 | function Baler:allowPickingUp(superFunc) |
931 | if self.baler.baleUnloadAnimationName ~= nil then |
932 | if table.getn(self.baler.bales) > 0 or self.baler.unloadingState ~= Baler.UNLOADING_CLOSED then |
933 | return false |
934 | end |
935 | end |
936 | |
937 | if superFunc ~= nil then |
938 | return superFunc(self) |
939 | end |
940 | return true |
941 | end |
createBale
DescriptionCreate new bale in balerDefinition
createBale(integer baleFillType, float fillLevel)Arguments
integer | baleFillType | fill type of bale to create |
float | fillLevel | fill level of bale |
947 | function Baler:createBale(baleFillType, fillLevel) |
948 | |
949 | if self.baler.knotingAnimation ~= nil then |
950 | self:playAnimation(self.baler.knotingAnimation, self.baler.knotingAnimationSpeed, nil, true) |
951 | end |
952 | |
953 | if self.baler.dummyBale.currentBale ~= nil then |
954 | delete(self.baler.dummyBale.currentBale) |
955 | self.baler.dummyBale.currentBale = nil |
956 | end |
957 | |
958 | local t = self.baler.baleTypes[self.baler.currentBaleTypeId] |
959 | local baleType = BaleUtil.getBale(baleFillType, t.width, t.height, t.length, t.diameter, t.isRoundBale) |
960 | |
961 | local bale = {} |
962 | bale.filename = Utils.getFilename(baleType.filename, self.baseDirectory) |
963 | bale.time = 0 |
964 | bale.fillType = baleFillType |
965 | bale.fillLevel = fillLevel |
966 | |
967 | if self.baler.baleUnloadAnimationName ~= nil then |
968 | local baleRoot = Utils.loadSharedI3DFile(baleType.filename, self.baseDirectory, false, false) |
969 | local baleId = getChildAt(baleRoot, 0) |
970 | link(self.baler.baleAnimRoot, baleId) |
971 | delete(baleRoot) |
972 | bale.id = baleId |
973 | end |
974 | |
975 | if self.isServer and self.baler.baleUnloadAnimationName == nil then |
976 | local x,y,z = getWorldTranslation(self.baler.baleAnimRoot) |
977 | local rx,ry,rz = getWorldRotation(self.baler.baleAnimRoot) |
978 | |
979 | local baleObject = Bale:new(self.isServer, self.isClient) |
980 | baleObject:load(bale.filename, x,y,z,rx,ry,rz, bale.fillLevel) |
981 | baleObject:register() |
982 | baleObject:setCanBeSold(false) |
983 | |
984 | local baleJointNode = createTransformGroup("BaleJointTG") |
985 | link(self.baler.baleAnimRoot, baleJointNode) |
986 | setTranslation(baleJointNode, 0,0,0) |
987 | setRotation(baleJointNode, 0,0,0) |
988 | |
989 | local constr = JointConstructor:new() |
990 | constr:setActors(self.baler.baleAnimRootComponent, baleObject.nodeId) |
991 | constr:setJointTransforms(baleJointNode, baleObject.nodeId) |
992 | for i=1, 3 do |
993 | constr:setRotationLimit(i-1, 0, 0) |
994 | constr:setTranslationLimit(i-1, true, 0, 0) |
995 | end |
996 | constr:setEnableCollision(false) |
997 | local baleJointIndex = constr:finalize() |
998 | |
999 | g_currentMission:removeItemToSave(baleObject) |
1000 | |
1001 | bale.baleJointNode = baleJointNode |
1002 | bale.baleJointIndex = baleJointIndex |
1003 | bale.baleObject = baleObject |
1004 | end |
1005 | |
1006 | table.insert(self.baler.bales, bale) |
1007 | end |
dropBale
DescriptionDrop baleDefinition
dropBale(integer baleIndex)Arguments
integer | baleIndex | index of bale |
1012 | function Baler:dropBale(baleIndex) |
1013 | local bale = self.baler.bales[baleIndex] |
1014 | |
1015 | if self.isServer then |
1016 | local baleObject |
1017 | |
1018 | if bale.baleJointIndex ~= nil then |
1019 | baleObject = bale.baleObject |
1020 | removeJoint(bale.baleJointIndex) |
1021 | delete(bale.baleJointNode) |
1022 | g_currentMission:addItemToSave(bale.baleObject) |
1023 | else |
1024 | baleObject = Bale:new(self.isServer, self.isClient) |
1025 | local x,y,z = getWorldTranslation(bale.id) |
1026 | local rx,ry,rz = getWorldRotation(bale.id) |
1027 | baleObject:load(bale.filename, x,y,z,rx,ry,rz, bale.fillLevel) |
1028 | baleObject:register() |
1029 | delete(bale.id) |
1030 | end |
1031 | |
1032 | baleObject:setCanBeSold(true) |
1033 | |
1034 | if (not self.hasBaleWrapper or self.moveBaleToWrapper == nil) and baleObject.nodeId ~= nil then |
1035 | -- release bale if there's no bale wrapper |
1036 | local x,y,z = getWorldTranslation(baleObject.nodeId) |
1037 | local vx,vy,vz = getVelocityAtWorldPos(self.baler.baleAnimRootComponent, x,y,z) |
1038 | setLinearVelocity(baleObject.nodeId, vx,vy,vz) |
1039 | elseif self.moveBaleToWrapper ~= nil then |
1040 | -- move bale to wrapper |
1041 | self:moveBaleToWrapper(baleObject) |
1042 | end |
1043 | end |
1044 | |
1045 | Utils.releaseSharedI3DFile(bale.filename, nil, true) |
1046 | table.remove(self.baler.bales, baleIndex) |
1047 | |
1048 | g_currentMission.missionStats:updateStats("baleCount", 1) |
1049 | end |
getIsTurnedOnAllowed
DescriptionReturns if turn on is allowedDefinition
getIsTurnedOnAllowed(boolean isTurnedOn)Arguments
boolean | isTurnedOn | is turned on |
boolean | allow | allow turn on |
1055 | function Baler:getIsTurnedOnAllowed(superFunc, isTurnedOn) |
1056 | if isTurnedOn and self.baler.isBaleUnloading then |
1057 | return false |
1058 | end |
1059 | |
1060 | if superFunc ~= nil then |
1061 | return superFunc(self, isTurnedOn) |
1062 | end |
1063 | |
1064 | return true |
1065 | end |
loadWorkAreaFromXML
DescriptionLoads work areas from xmlDefinition
loadWorkAreaFromXML(table workArea, integer xmlFile, string key)Arguments
table | workArea | workArea |
integer | xmlFile | id of xml object |
string | key | key |
boolean | success | success |
1073 | function Baler:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
1074 | local retValue = true |
1075 | if superFunc ~= nil then |
1076 | retValue = superFunc(self, workArea, xmlFile, key) |
1077 | end |
1078 | |
1079 | if workArea.type == WorkArea.AREATYPE_DEFAULT then |
1080 | workArea.type = WorkArea.AREATYPE_BALER |
1081 | end |
1082 | |
1083 | return retValue |
1084 | end |
loadSpeedRotatingPartFromXML
DescriptionLoads speed rotating parts from xmlDefinition
loadSpeedRotatingPartFromXML(table speedRotatingPart, integer xmlFile, string key)Arguments
table | speedRotatingPart | speedRotatingPart |
integer | xmlFile | id of xml object |
string | key | key |
boolean | success | success |
1092 | function Baler:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key) |
1093 | if superFunc ~= nil then |
1094 | if not superFunc(self, speedRotatingPart, xmlFile, key) then |
1095 | return false |
1096 | end |
1097 | end |
1098 | |
1099 | speedRotatingPart.rotateOnlyIfFillLevelIncreased = Utils.getNoNil(getXMLBool(xmlFile, key .. "#rotateOnlyIfFillLevelIncreased"), false) |
1100 | |
1101 | return true |
1102 | end |
getIsSpeedRotatingPartActive
DescriptionReturns true if speed rotating part is activeDefinition
getIsSpeedRotatingPartActive(table speedRotatingPart)Arguments
table | speedRotatingPart | speedRotatingPart |
boolean | isActive | speed rotating part is active |
1108 | function Baler:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart) |
1109 | if speedRotatingPart.rotateOnlyIfFillLevelIncreased ~= nil then |
1110 | if speedRotatingPart.rotateOnlyIfFillLevelIncreased and not self.baler.lastAreaBiggerZero then |
1111 | return false |
1112 | end |
1113 | end |
1114 | |
1115 | if superFunc ~= nil then |
1116 | return superFunc(self, speedRotatingPart) |
1117 | end |
1118 | return true |
1119 | end |
getDefaultSpeedLimit
DescriptionReturns default speed limitDefinition
getDefaultSpeedLimit()Return Values
float | speedLimit | speed limit |
1124 | function Baler.getDefaultSpeedLimit() |
1125 | return 25 |
1126 | end |
processBalerAreas
DescriptionProcess baler areasDefinition
processBalerAreas(table workAreas, table fillTypes)Arguments
table | workAreas | work areas to process |
table | fillTypes | fill types |
float | totalLiters | total liters picked up |
integer | usedFillType | fill type picked up |
1134 | function Baler:processBalerAreas(workAreas, fillTypes) |
1135 | |
1136 | local totalLiters = 0 |
1137 | local usedFillType = FillUtil.FILLTYPE_UNKNOWN |
1138 | |
1139 | local numAreas = table.getn(workAreas) |
1140 | for i=1, numAreas do |
1141 | local x0 = workAreas[i][1] |
1142 | local z0 = workAreas[i][2] |
1143 | local x1 = workAreas[i][3] |
1144 | local z1 = workAreas[i][4] |
1145 | local x2 = workAreas[i][5] |
1146 | local z2 = workAreas[i][6] |
1147 | |
1148 | local hx = x2 - x0 |
1149 | local hz = z2 - z0 |
1150 | local hLength = Utils.vector2Length(hx, hz) |
1151 | local hLength_2 = 0.5 * hLength |
1152 | |
1153 | local wx = x1 - x0 |
1154 | local wz = z1 - z0 |
1155 | local wLength = Utils.vector2Length(wx, wz) |
1156 | |
1157 | local sx = x0 + (hx * 0.5) + ((wx/wLength)*hLength_2) |
1158 | local sz = z0 + (hz * 0.5) + ((wz/wLength)*hLength_2) |
1159 | |
1160 | local ex = x1 + (hx * 0.5) - ((wx/wLength)*hLength_2) |
1161 | local ez = z1 + (hz * 0.5) - ((wz/wLength)*hLength_2) |
1162 | |
1163 | local sy = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, sx,0,sz) |
1164 | local ey = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, ex,0,ez) |
1165 | |
1166 | |
1167 | if usedFillType == FillUtil.FILLTYPE_UNKNOWN then |
1168 | for _, fillType in pairs(fillTypes) do |
1169 | local liters = -TipUtil.tipToGroundAroundLine(self, -math.huge, fillType, sx,sy,sz, ex,ey,ez, hLength_2, nil, nil, false, nil) |
1170 | if liters > 0 then |
1171 | usedFillType = fillType |
1172 | totalLiters = totalLiters + liters |
1173 | break |
1174 | end |
1175 | end |
1176 | else |
1177 | totalLiters = totalLiters - TipUtil.tipToGroundAroundLine(self, -math.huge, usedFillType, sx,sy,sz, ex,ey,ez, hLength_2, nil, nil, false, nil) |
1178 | end |
1179 | |
1180 | end |
1181 | |
1182 | return totalLiters, usedFillType |
1183 | end |