Script v1_7_1_0
- AI
- Animals
- Collections
- Contracts
- Debug
- Economy
- Elements
- EnvironmentalScore
- Errors
- Events
- GUI
- Handtools
- Hud
- I3d
- Input
- Jobs
- Maps
- Materials
- Misc
- Objects
- Parameters
- Placeables
- Placement
- Player
- Shop
- Sounds
- Specialization
- Specializations
- AIConveyorBelt
- AIDrivable
- AIFieldWorker
- AIImplement
- AIJobVehicle
- AIVehicle
- AIVehicleObstacle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- AutoLoader
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BigBag
- BunkerSiloCompacter
- BunkerSiloInteractor
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- CropSensor
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- ExtendedAIVehicle
- ExtendedCombine
- ExtendedMotorized
- ExtendedMower
- ExtendedSowingMachine
- ExtendedSprayer
- ExtendedWearable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- HeadlandAnimation
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- InlineWrapper
- JigglingParts
- Leveler
- LicensePlates
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- ManureSensor
- MixerWagon
- Motorized
- Mountable
- Mower
- Mulcher
- MultipleItemPurchase
- Pallet
- Pickup
- Pipe
- PlaceableAI
- PlaceableAnimatedObjects
- PlaceableBeehive
- PlaceableBeehivePalletSpa...
- PlaceableBunkerSilo
- PlaceableBuyingStation
- PlaceableCartridgePlayer
- PlaceableChargingStation
- PlaceableClearAreas
- PlaceableColorable
- PlaceableDeletedNodes
- PlaceableDoghouse
- PlaceableDynamicallyLoade...
- PlaceableFarmhouse
- PlaceableFence
- PlaceableFoliageAreas
- PlaceableGreenhouse
- PlaceableHighPressureWash...
- PlaceableHotspots
- PlaceableHusbandry
- PlaceableHusbandryAnimals
- PlaceableHusbandryFeeding...
- PlaceableHusbandryFence
- PlaceableHusbandryFood
- PlaceableHusbandryLiquidM...
- PlaceableHusbandryMilk
- PlaceableHusbandryPallets
- PlaceableHusbandryStraw
- PlaceableHusbandryWater
- PlaceableIncomePerHour
- PlaceableIndoorAreas
- PlaceableInfoTrigger
- PlaceableLeveling
- PlaceableLights
- PlaceableManureHeap
- PlaceablePlacement
- PlaceableProductionPoint
- PlaceableSellingStation
- PlaceableSilo
- PlaceableSiloExtension
- PlaceableSolarPanels
- PlaceableTipOcclusionArea...
- PlaceableTrainSystem
- PlaceableTriggerMarkers
- PlaceableVine
- PlaceableWardrobe
- PlaceableWeatherStation
- PlaceableWeighingStation
- PlaceableWindTurbine
- PlaceableWorkshop
- Plow
- PlowPacker
- PowerConsumer
- PowerTakeOffs
- PrecisionFarmingStatistic
- PushHandTool
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- RTKStation
- SaltSpreader
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SoilSampler
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StonePicker
- StrawBlower
- StumpCutter
- SupportVehicle
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TestAreas
- TipOccluder
- Trailer
- TreePlanter
- TreeSaplingPallet
- TreeSaw
- TurnOnVehicle
- VariableWorkWidth
- VehicleSettings
- VineCutter
- VineDetector
- VinePrepruner
- Washable
- WaterTrailer
- Wearable
- Weeder
- WeedSpotSpray
- Wheels
- WindBending
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- StateMachine
- Statistics
- Tasks
- Triggers
- Utils
- Vehicles
Engine v1_7_1_0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- general
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- NoteNode
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- VoiceChat
- XML
Foundation Reference
TreeSaw
DescriptionSpecialization for vehicles with sawing functionality. Not to confuse with Chainsaw hand toolFunctions
- initSpecialization
- onDeactivate
- onDelete
- onDraw
- onLoad
- onReadUpdateStream
- onTurnedOff
- onTurnedOn
- onUpdate
- onUpdateTick
- onWriteUpdateStream
- prerequisitesPresent
- registerEventListeners
initSpecialization
DescriptionDefinitioninitSpecialization()Code
23 | function TreeSaw.initSpecialization() |
24 | local schema = Vehicle.xmlSchema |
25 | schema:setXMLSpecializationType("TreeSaw") |
26 | |
27 | SoundManager.registerSampleXMLPaths(schema, "vehicle.treeSaw.sounds", "cut") |
28 | SoundManager.registerSampleXMLPaths(schema, "vehicle.treeSaw.sounds", "saw") |
29 | |
30 | AnimationManager.registerAnimationNodesXMLPaths(schema, "vehicle.treeSaw.animationNodes") |
31 | EffectManager.registerEffectXMLPaths(schema, "vehicle.treeSaw.effects") |
32 | |
33 | schema:register(XMLValueType.NODE_INDEX, "vehicle.treeSaw.cutNode#node", "Cut node") |
34 | schema:register(XMLValueType.FLOAT, "vehicle.treeSaw.cutNode#sizeY", "Size Y", 1) |
35 | schema:register(XMLValueType.FLOAT, "vehicle.treeSaw.cutNode#sizeZ", "Size Z", 1) |
36 | schema:register(XMLValueType.FLOAT, "vehicle.treeSaw.cutNode#lengthAboveThreshold", "Min. tree length above cut node", 0.3) |
37 | schema:register(XMLValueType.FLOAT, "vehicle.treeSaw.cutNode#lengthBelowThreshold", "Min. tree length below cut node", 0.3) |
38 | schema:register(XMLValueType.FLOAT, "vehicle.treeSaw.cutNode#timer", "Cut delay (sec.)", 1) |
39 | |
40 | schema:setXMLSpecializationType() |
41 | end |
onDeactivate
DescriptionCalled on deactivateDefinition
onDeactivate()Code
262 | function TreeSaw:onDeactivate() |
263 | local spec = self.spec_treeSaw |
264 | |
265 | spec.curSplitShape = nil |
266 | spec.cutTimer = -1 |
267 | end |
onDelete
DescriptionCalled on deletingDefinition
onDelete()Code
95 | function TreeSaw:onDelete() |
96 | local spec = self.spec_treeSaw |
97 | g_effectManager:deleteEffects(spec.effects) |
98 | g_soundManager:deleteSamples(spec.samples) |
99 | g_animationManager:deleteAnimations(spec.animationNodes) |
100 | end |
onDraw
DescriptionCalled on drawDefinition
onDraw(boolean isActiveForInput, boolean isSelected)Arguments
boolean | isActiveForInput | true if vehicle is active for input |
boolean | isSelected | true if vehicle is selected |
248 | function TreeSaw:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
249 | local spec = self.spec_treeSaw |
250 | |
251 | if spec.isCutting then |
252 | g_currentMission:addExtraPrintText(g_i18n:getText("info_cutting")) |
253 | end |
254 | |
255 | if spec.warnTreeNotOwned then |
256 | g_currentMission:showBlinkingWarning(g_i18n:getText("warning_youDontHaveAccessToThisLand"), 1000) |
257 | end |
258 | end |
onLoad
DescriptionCalled on loadingDefinition
onLoad(table savegame)Arguments
table | savegame | savegame |
61 | function TreeSaw:onLoad(savegame) |
62 | local spec = self.spec_treeSaw |
63 | |
64 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "vehicle.treeSaw.animationNodes.animationNode", "stumbCutter") --FS17 to FS19 |
65 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.treeSaw.cutParticleSystems.emitterShape(0)", "vehicle.treeSaw.effects.effectNode") --FS17 to FS19 |
66 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.treeSaw.sawSound", "vehicle.treeSaw.sounds.saw") --FS17 to FS19 |
67 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.treeSaw.cutSound", "vehicle.treeSaw.sounds.cut") --FS17 to FS19 |
68 | |
69 | local baseKey = "vehicle.treeSaw" |
70 | |
71 | if self.isClient then |
72 | spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, baseKey..".animationNodes", self.components, self, self.i3dMappings) |
73 | spec.effects = g_effectManager:loadEffect(self.xmlFile, baseKey .. ".effects", self.components, self, self.i3dMappings) |
74 | |
75 | spec.samples = {} |
76 | spec.samples.cut = g_soundManager:loadSampleFromXML(self.xmlFile, baseKey .. ".sounds", "cut", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
77 | spec.samples.saw = g_soundManager:loadSampleFromXML(self.xmlFile, baseKey .. ".sounds", "saw", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
78 | end |
79 | |
80 | spec.cutNode = self.xmlFile:getValue(baseKey .. ".cutNode#node", nil, self.components, self.i3dMappings) |
81 | spec.cutSizeY = self.xmlFile:getValue(baseKey .. ".cutNode#sizeY", 1) |
82 | spec.cutSizeZ = self.xmlFile:getValue(baseKey .. ".cutNode#sizeZ", 1) |
83 | spec.lengthAboveThreshold = self.xmlFile:getValue(baseKey .. ".cutNode#lengthAboveThreshold", 0.3) |
84 | spec.lengthBelowThreshold = self.xmlFile:getValue(baseKey .. ".cutNode#lengthBelowThreshold", 0.3) |
85 | spec.cutTimerDuration = self.xmlFile:getValue(baseKey .. ".cutNode#timer", 1) * 1000 |
86 | |
87 | spec.curSplitShape = nil |
88 | spec.cutTimer = -1 |
89 | spec.isCutting = false |
90 | spec.warnTreeNotOwned = false |
91 | end |
onReadUpdateStream
DescriptionCalled on on updateDefinition
onReadUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
107 | function TreeSaw:onReadUpdateStream(streamId, timestamp, connection) |
108 | if connection:getIsServer() then |
109 | local spec = self.spec_treeSaw |
110 | spec.isCutting = streamReadBool(streamId) |
111 | end |
112 | end |
onTurnedOff
DescriptionCalled on turn offDefinition
onTurnedOff()Code
281 | function TreeSaw:onTurnedOff() |
282 | local spec = self.spec_treeSaw |
283 | |
284 | spec.curSplitShape = nil |
285 | spec.cutTimer = -1 |
286 | |
287 | if self.isClient then |
288 | g_animationManager:stopAnimations(spec.animationNodes) |
289 | g_effectManager:stopEffects(spec.effects) |
290 | g_soundManager:stopSamples(spec.samples) |
291 | end |
292 | end |
onTurnedOn
DescriptionCalled on turn onDefinition
onTurnedOn()Code
271 | function TreeSaw:onTurnedOn() |
272 | if self.isClient then |
273 | local spec = self.spec_treeSaw |
274 | g_animationManager:startAnimations(spec.animationNodes) |
275 | g_soundManager:playSample(spec.samples.saw) |
276 | end |
277 | end |
onUpdate
DescriptionCalled on updateDefinition
onUpdate(float dt, boolean isActiveForInput, boolean isSelected)Arguments
float | dt | time since last call in ms |
boolean | isActiveForInput | true if vehicle is active for input |
boolean | isSelected | true if vehicle is selected |
131 | function TreeSaw:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
132 | local spec = self.spec_treeSaw |
133 | |
134 | -- Verify that the split shapes still exist (possible that someone has cut them) |
135 | if self.isServer then |
136 | if spec.curSplitShape ~= nil then |
137 | if not entityExists(spec.curSplitShape) then |
138 | spec.curSplitShape = nil |
139 | if g_server ~= nil then |
140 | spec.cutTimer = -1 |
141 | end |
142 | end |
143 | end |
144 | |
145 | spec.isCutting = spec.curSplitShape ~= nil |
146 | if spec.curSplitShape ~= nil then |
147 | if spec.cutTimer > 0 then |
148 | spec.cutTimer = math.max(spec.cutTimer - dt, 0) |
149 | end |
150 | |
151 | -- cut |
152 | if spec.cutTimer == 0 then |
153 | spec.cutTimer = -1 |
154 | |
155 | local x,y,z = getWorldTranslation(spec.cutNode) |
156 | local nx,ny,nz = localDirectionToWorld(spec.cutNode, 1,0,0) |
157 | local yx,yy,yz = localDirectionToWorld(spec.cutNode, 0,1,0) |
158 | |
159 | ChainsawUtil.cutSplitShape(spec.curSplitShape, x,y,z, nx,ny,nz, yx,yy,yz, spec.cutSizeY, spec.cutSizeZ, self:getActiveFarm()) |
160 | spec.curSplitShape = nil |
161 | end |
162 | end |
163 | end |
164 | |
165 | -- effect and sound for cut |
166 | if self.isClient then |
167 | if spec.cutTimer > 0 then |
168 | g_effectManager:setFillType(spec.effects, FillType.WOODCHIPS) |
169 | g_effectManager:startEffects(spec.effects) |
170 | if not g_soundManager:getIsSamplePlaying(spec.samples.cut) then |
171 | g_soundManager:playSample(spec.samples.cut) |
172 | end |
173 | else |
174 | g_effectManager:stopEffects(spec.effects) |
175 | if g_soundManager:getIsSamplePlaying(spec.samples.cut) then |
176 | g_soundManager:stopSample(spec.samples.cut) |
177 | end |
178 | end |
179 | end |
180 | end |
onUpdateTick
DescriptionCalled on update tickDefinition
onUpdateTick(float dt, boolean isActiveForInput, boolean isSelected)Arguments
float | dt | time since last call in ms |
boolean | isActiveForInput | true if vehicle is active for input |
boolean | isSelected | true if vehicle is selected |
187 | function TreeSaw:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
188 | local spec = self.spec_treeSaw |
189 | spec.warnTreeNotOwned = false |
190 | |
191 | if self:getIsTurnedOn() then |
192 | if spec.cutNode ~= nil then |
193 | local x,y,z = getWorldTranslation(spec.cutNode) |
194 | local nx,ny,nz = localDirectionToWorld(spec.cutNode, 1,0,0) |
195 | local yx,yy,yz = localDirectionToWorld(spec.cutNode, 0,1,0) |
196 | |
197 | if spec.curSplitShape == nil then |
198 | local shape, _, _, _, _ = findSplitShape(x,y,z, nx,ny,nz, yx,yy,yz, spec.cutSizeY, spec.cutSizeZ) |
199 | if shape ~= 0 then |
200 | if g_currentMission.accessHandler:canFarmAccessLand(self:getActiveFarm(), x, z) then |
201 | spec.curSplitShape = shape |
202 | spec.cutTimer = spec.cutTimerDuration |
203 | else |
204 | spec.warnTreeNotOwned = true |
205 | end |
206 | end |
207 | end |
208 | |
209 | if spec.curSplitShape ~= nil then |
210 | local minY,maxY, minZ,maxZ = testSplitShape(spec.curSplitShape, x,y,z, nx,ny,nz, yx,yy,yz, spec.cutSizeY, spec.cutSizeZ) |
211 | if minY == nil then |
212 | spec.curSplitShape = nil |
213 | else |
214 | -- check if cut would be below y=0 (tree CoSy) |
215 | local cutTooLow = false |
216 | local _,ly,_ = localToLocal(spec.cutNode, spec.curSplitShape, 0,minY,minZ) |
217 | cutTooLow = cutTooLow or ly < 0.01 |
218 | _,ly,_ = localToLocal(spec.cutNode, spec.curSplitShape, 0,minY,maxZ) |
219 | cutTooLow = cutTooLow or ly < 0.01 |
220 | _,ly,_ = localToLocal(spec.cutNode, spec.curSplitShape, 0,maxY,minZ) |
221 | cutTooLow = cutTooLow or ly < 0.01 |
222 | _,ly,_ = localToLocal(spec.cutNode, spec.curSplitShape, 0,maxY,maxZ) |
223 | cutTooLow = cutTooLow or ly < 0.01 |
224 | if cutTooLow then |
225 | spec.curSplitShape = nil |
226 | end |
227 | end |
228 | end |
229 | |
230 | if spec.curSplitShape ~= nil then |
231 | local lenBelow, lenAbove = getSplitShapePlaneExtents(spec.curSplitShape, x,y,z, nx,ny,nz) |
232 | if lenAbove < spec.lengthAboveThreshold or lenBelow < spec.lengthBelowThreshold then |
233 | spec.curSplitShape = nil |
234 | end |
235 | end |
236 | |
237 | if spec.curSplitShape == nil and spec.cutTimer > -1 then |
238 | spec.cutTimer = -1 |
239 | end |
240 | end |
241 | end |
242 | end |
onWriteUpdateStream
DescriptionCalled on on updateDefinition
onWriteUpdateStream(integer streamId, table connection, integer dirtyMask)Arguments
integer | streamId | stream ID |
table | connection | connection |
integer | dirtyMask | dirty mask |
119 | function TreeSaw:onWriteUpdateStream(streamId, connection, dirtyMask) |
120 | if not connection:getIsServer() then |
121 | local spec = self.spec_treeSaw |
122 | streamWriteBool(streamId, spec.isCutting) |
123 | end |
124 | 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 |
17 | function TreeSaw.prerequisitesPresent(specializations) |
18 | return SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) |
19 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
45 | function TreeSaw.registerEventListeners(vehicleType) |
46 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", TreeSaw) |
47 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", TreeSaw) |
48 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", TreeSaw) |
49 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", TreeSaw) |
50 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", TreeSaw) |
51 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", TreeSaw) |
52 | SpecializationUtil.registerEventListener(vehicleType, "onDraw", TreeSaw) |
53 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", TreeSaw) |
54 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", TreeSaw) |
55 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", TreeSaw) |
56 | end |