Script v1.7.1.0
- AI
- Animals
- Contracts
- Debug
- Economy
- Effects
- Events
- Farms
- GUI
- Handtools
- I3d
- Materials
- Misc
- Objects
- Placeables
- Player
- Shop
- Sounds
- Specializations
- AIConveyorBelt
- AIImplement
- AIVehicle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BunkerSiloCompacter
- BunkerSiloInteractor
- BuyableBale
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- JigglingParts
- Leveler
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- MixerWagon
- Motorized
- Mountable
- Mower
- Pickup
- Pipe
- Plow
- PowerConsumer
- PowerTakeOffs
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StrawBlower
- StumpCutter
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TipOccluder
- Trailer
- TreePlanter
- TreeSaw
- TurnOnVehicle
- Washable
- WaterTrailer
- Wearable
- Weeder
- Wheels
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- 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
Cultivator
DescriptionSpecialization for all cultivators, requires WorkArea specializationFunctions
- doCheckSpeedLimit
- getDefaultSpeedLimit
- getDirtMultiplier
- getDoGroundManipulation
- getIsWorkAreaActive
- getWearMultiplier
- initSpecialization
- loadWorkAreaFromXML
- onDeactivate
- onDelete
- onEndWorkAreaProcessing
- onLoad
- onPostAttach
- onPreDetach
- onStartWorkAreaProcessing
- prerequisitesPresent
- processCultivatorArea
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
doCheckSpeedLimit
DescriptionReturns if speed limit should be checkedDefinition
doCheckSpeedLimit()Return Values
boolean | checkSpeedlimit | check speed limit |
141 | function Cultivator:doCheckSpeedLimit(superFunc) |
142 | return superFunc(self) or self:getIsImplementChainLowered() |
143 | end |
getDefaultSpeedLimit
DescriptionReturns default speed limitDefinition
getDefaultSpeedLimit()Return Values
float | speedLimit | speed limit |
312 | function Cultivator.getDefaultSpeedLimit() |
313 | return 15 |
314 | end |
getDirtMultiplier
DescriptionReturns current dirt multiplierDefinition
getDirtMultiplier()Return Values
float | dirtMultiplier | current dirt multiplier |
161 | function Cultivator:getDirtMultiplier(superFunc) |
162 | local spec = self.spec_cultivator |
163 | |
164 | local multiplier = superFunc(self) |
165 | if spec.isWorking then |
166 | multiplier = multiplier + self:getWorkDirtMultiplier() * self:getLastSpeed() / spec.speedLimit |
167 | end |
168 | |
169 | return multiplier |
170 | end |
getDoGroundManipulation
DescriptionReturns if tool does ground manipulationDefinition
getDoGroundManipulation()Return Values
boolean | doGroundManipulation | do ground manipulation |
148 | function Cultivator:getDoGroundManipulation(superFunc) |
149 | local spec = self.spec_cultivator |
150 | |
151 | if not spec.isWorking then |
152 | return false |
153 | end |
154 | |
155 | return superFunc(self) |
156 | end |
getIsWorkAreaActive
DescriptionDefinitiongetIsWorkAreaActive()Code
204 | function Cultivator:getIsWorkAreaActive(superFunc, workArea) |
205 | if workArea.type == WorkAreaType.CULTIVATOR then |
206 | local spec = self.spec_cultivator |
207 | |
208 | if spec.startActivationTime > g_currentMission.time then |
209 | return false |
210 | end |
211 | |
212 | if spec.onlyActiveWhenLowered and self.getIsLowered ~= nil then |
213 | if not self:getIsLowered(false) then |
214 | return false |
215 | end |
216 | end |
217 | end |
218 | |
219 | return superFunc(self, workArea) |
220 | end |
getWearMultiplier
DescriptionReturns current wear multiplierDefinition
getWearMultiplier()Return Values
float | dirtMultiplier | current wear multiplier |
175 | function Cultivator:getWearMultiplier(superFunc) |
176 | local spec = self.spec_cultivator |
177 | local multiplier = superFunc(self) |
178 | |
179 | if spec.isWorking then |
180 | multiplier = multiplier + self:getWorkWearMultiplier() * self:getLastSpeed() / spec.speedLimit |
181 | end |
182 | |
183 | return multiplier |
184 | end |
initSpecialization
DescriptionCalled on specialization initializingDefinition
initSpecialization()Code
15 | function Cultivator.initSpecialization() |
16 | g_workAreaTypeManager:addWorkAreaType("cultivator", true) |
17 | 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 |
192 | function Cultivator:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
193 | local retValue = superFunc(self, workArea, xmlFile, key) |
194 | |
195 | if workArea.type == WorkAreaType.DEFAULT then |
196 | workArea.type = WorkAreaType.CULTIVATOR |
197 | end |
198 | |
199 | return retValue |
200 | end |
onDeactivate
DescriptionDefinitiononDeactivate()Code
243 | function Cultivator:onDeactivate() |
244 | if self.isClient then |
245 | local spec = self.spec_cultivator |
246 | g_soundManager:stopSamples(spec.samples) |
247 | spec.isWorkSamplePlaying = false |
248 | end |
249 | end |
onDelete
DescriptionCalled on deletingDefinition
onDelete()Code
104 | function Cultivator:onDelete() |
105 | if self.isClient then |
106 | local spec = self.spec_cultivator |
107 | g_soundManager:deleteSamples(spec.samples) |
108 | end |
109 | end |
onEndWorkAreaProcessing
DescriptionDefinitiononEndWorkAreaProcessing()Code
278 | function Cultivator:onEndWorkAreaProcessing(dt) |
279 | local spec = self.spec_cultivator |
280 | |
281 | if self.isServer then |
282 | local lastStatsArea = spec.workAreaParameters.lastStatsArea |
283 | if lastStatsArea > 0 then |
284 | local ha = MathUtil.areaToHa(lastStatsArea, g_currentMission:getFruitPixelsToSqm()) -- 4096px are mapped to 2048m |
285 | local stats = g_currentMission:farmStats(self:getLastTouchedFarmlandFarmId()) |
286 | stats:updateStats("workedHectares", ha) |
287 | stats:updateStats("cultivatedHectares", ha) |
288 | |
289 | stats:updateStats("workedTime", dt/(1000*60)) |
290 | stats:updateStats("cultivatedTime", dt/(1000*60)) |
291 | end |
292 | end |
293 | |
294 | if self.isClient then |
295 | if spec.isWorking then |
296 | if not spec.isWorkSamplePlaying then |
297 | g_soundManager:playSample(spec.samples.work) |
298 | spec.isWorkSamplePlaying = true |
299 | end |
300 | else |
301 | if spec.isWorkSamplePlaying then |
302 | g_soundManager:stopSample(spec.samples.work) |
303 | spec.isWorkSamplePlaying = false |
304 | end |
305 | end |
306 | end |
307 | end |
onLoad
DescriptionCalled on loadingDefinition
onLoad(table savegame)Arguments
table | savegame | savegame |
59 | function Cultivator:onLoad(savegame) |
60 | |
61 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.cultivator.directionNode#index", "vehicle.cultivator.directionNode#node") --FS17 to FS19 |
62 | |
63 | if self:getGroundReferenceNodeFromIndex(1) == nil then |
64 | print("Warning: No ground reference nodes in "..self.configFileName) |
65 | end |
66 | |
67 | local spec = self.spec_cultivator |
68 | |
69 | if self.isClient then |
70 | spec.samples = {} |
71 | spec.samples.work = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.cultivator.sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
72 | spec.isWorkSamplePlaying = false |
73 | end |
74 | |
75 | spec.directionNode = Utils.getNoNil(I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.cultivator.directionNode#node"), self.i3dMappings), self.components[1].node) |
76 | spec.onlyActiveWhenLowered = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.cultivator.onlyActiveWhenLowered#value"), true) |
77 | spec.isSubsoiler = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.cultivator#isSubsoiler"), false) |
78 | |
79 | if self.addAITerrainDetailRequiredRange ~= nil then |
80 | self:addAITerrainDetailRequiredRange(g_currentMission.plowValue, g_currentMission.plowValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels) |
81 | self:addAITerrainDetailRequiredRange(g_currentMission.sowingValue, g_currentMission.sowingValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels) |
82 | self:addAITerrainDetailRequiredRange(g_currentMission.sowingWidthValue, g_currentMission.sowingWidthValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels) |
83 | self:addAITerrainDetailRequiredRange(g_currentMission.grassValue, g_currentMission.grassValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels) |
84 | end |
85 | |
86 | spec.startActivationTimeout = 2000 |
87 | spec.startActivationTime = 0 |
88 | spec.hasGroundContact = false |
89 | spec.isWorking = false |
90 | spec.limitToField = false |
91 | spec.forceLimitToField = true |
92 | |
93 | spec.workAreaParameters = {} |
94 | spec.workAreaParameters.limitToField = spec.limitToField |
95 | spec.workAreaParameters.forceLimitToField = spec.forceLimitToField |
96 | spec.workAreaParameters.angle = 0 |
97 | spec.workAreaParameters.lastChangedArea = 0 |
98 | spec.workAreaParameters.lastStatsArea = 0 |
99 | spec.workAreaParameters.lastTotalArea = 0 |
100 | end |
onPostAttach
DescriptionCalled if vehicle gets attachedDefinition
onPostAttach(table attacherVehicle, integer inputJointDescIndex, integer jointDescIndex)Arguments
table | attacherVehicle | attacher vehicle |
integer | inputJointDescIndex | index of input attacher joint |
integer | jointDescIndex | index of attacher joint it gets attached to |
227 | function Cultivator:onPostAttach(attacherVehicle, inputJointDescIndex, jointDescIndex) |
228 | local spec = self.spec_cultivator |
229 | spec.startActivationTime = g_currentMission.time + spec.startActivationTimeout |
230 | end |
onPreDetach
DescriptionCalled if vehicle gets detachedDefinition
onPreDetach(table attacherVehicle, table implement)Arguments
table | attacherVehicle | attacher vehicle |
table | implement | implement |
236 | function Cultivator:onPreDetach(attacherVehicle, implement) |
237 | local spec = self.spec_cultivator |
238 | spec.limitToField = false |
239 | end |
onStartWorkAreaProcessing
DescriptionDefinitiononStartWorkAreaProcessing()Code
253 | function Cultivator:onStartWorkAreaProcessing(dt) |
254 | local spec = self.spec_cultivator |
255 | |
256 | spec.isWorking = false |
257 | |
258 | local limitToField = spec.limitToField or spec.forceLimitToField |
259 | local limitGrassDestructionToField = spec.limitToField or spec.forceLimitToField |
260 | if not g_currentMission:getHasPlayerPermission("createFields", self:getOwner()) then |
261 | limitToField = true |
262 | limitGrassDestructionToField = true |
263 | end |
264 | |
265 | local dx,_,dz = localDirectionToWorld(spec.directionNode, 0, 0, 1) |
266 | local angle = FSDensityMapUtil.convertToDensityMapAngle(MathUtil.getYRotationFromDirection(dx, dz), g_currentMission.terrainDetailAngleMaxValue) |
267 | |
268 | spec.workAreaParameters.limitToField = limitToField |
269 | spec.workAreaParameters.limitGrassDestructionToField = limitGrassDestructionToField |
270 | spec.workAreaParameters.angle = angle |
271 | spec.workAreaParameters.lastChangedArea = 0 |
272 | spec.workAreaParameters.lastStatsArea = 0 |
273 | spec.workAreaParameters.lastTotalArea = 0 |
274 | 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 |
23 | function Cultivator.prerequisitesPresent(specializations) |
24 | return SpecializationUtil.hasSpecialization(WorkArea, specializations) |
25 | end |
processCultivatorArea
DescriptionDefinitionprocessCultivatorArea()Code
113 | function Cultivator:processCultivatorArea(workArea, dt) |
114 | local spec = self.spec_cultivator |
115 | |
116 | local xs,_,zs = getWorldTranslation(workArea.start) |
117 | local xw,_,zw = getWorldTranslation(workArea.width) |
118 | local xh,_,zh = getWorldTranslation(workArea.height) |
119 | |
120 | local params = spec.workAreaParameters |
121 | |
122 | local realArea, area = FSDensityMapUtil.updateCultivatorArea(xs,zs, xw,zw, xh,zh, not params.limitToField, not params.limitGrassDestructionToField, params.angle, nil) |
123 | params.lastChangedArea = params.lastChangedArea + realArea |
124 | params.lastStatsArea = params.lastStatsArea + realArea |
125 | params.lastTotalArea = params.lastTotalArea + area |
126 | |
127 | if spec.isSubsoiler then |
128 | FSDensityMapUtil.updateSubsoilerArea(xs,zs, xw,zw, xh,zh) |
129 | end |
130 | |
131 | FSDensityMapUtil.eraseTireTrack(xs,zs, xw,zw, xh,zh) |
132 | |
133 | spec.isWorking = self:getLastSpeed() > 0.5 |
134 | |
135 | return realArea, area |
136 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
46 | function Cultivator.registerEventListeners(vehicleType) |
47 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", Cultivator) |
48 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", Cultivator) |
49 | SpecializationUtil.registerEventListener(vehicleType, "onPostAttach", Cultivator) |
50 | SpecializationUtil.registerEventListener(vehicleType, "onPreDetach", Cultivator) |
51 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", Cultivator) |
52 | SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", Cultivator) |
53 | SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", Cultivator) |
54 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
29 | function Cultivator.registerFunctions(vehicleType) |
30 | SpecializationUtil.registerFunction(vehicleType, "processCultivatorArea", Cultivator.processCultivatorArea) |
31 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
35 | function Cultivator.registerOverwrittenFunctions(vehicleType) |
36 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", Cultivator.doCheckSpeedLimit) |
37 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDoGroundManipulation", Cultivator.getDoGroundManipulation) |
38 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirtMultiplier", Cultivator.getDirtMultiplier) |
39 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getWearMultiplier", Cultivator.getWearMultiplier) |
40 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWorkAreaFromXML", Cultivator.loadWorkAreaFromXML) |
41 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsWorkAreaActive", Cultivator.getIsWorkAreaActive) |
42 | end |