39 | function TreeSaw:onLoad(savegame) |
40 | local spec = self.spec_treeSaw |
41 | |
42 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "vehicle.treeSaw.animationNodes.animationNode", "stumbCutter") --FS17 to FS19 |
43 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.treeSaw.cutParticleSystems.emitterShape(0)", "vehicle.treeSaw.effects.effectNode") --FS17 to FS19 |
44 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.treeSaw.sawSound", "vehicle.treeSaw.sounds.saw") --FS17 to FS19 |
45 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.treeSaw.cutSound", "vehicle.treeSaw.sounds.cut") --FS17 to FS19 |
46 | |
47 | local baseKey = "vehicle.treeSaw" |
48 | |
49 | if self.isClient then |
50 | spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, baseKey..".animationNodes", self.components, self, self.i3dMappings) |
51 | spec.effects = g_effectManager:loadEffect(self.xmlFile, baseKey .. ".effects", self.components, self, self.i3dMappings) |
52 | |
53 | spec.samples = {} |
54 | spec.samples.cut = g_soundManager:loadSampleFromXML(self.xmlFile, baseKey .. ".sounds", "cut", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
55 | spec.samples.saw = g_soundManager:loadSampleFromXML(self.xmlFile, baseKey .. ".sounds", "saw", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
56 | end |
57 | |
58 | spec.cutNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, baseKey .. ".cutNode#node"), self.i3dMappings) |
59 | spec.cutSizeY = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey .. ".cutNode#sizeY"), 1) |
60 | spec.cutSizeZ = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey .. ".cutNode#sizeZ"), 1) |
61 | spec.lengthAboveThreshold = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey .. ".cutNode#lengthAboveThreshold"), 0.3) |
62 | spec.lengthBelowThreshold = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey .. ".cutNode#lengthBelowThreshold"), 0.3) |
63 | spec.cutTimerDuration = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey .. ".cutNode#timer"), 1)*1000 |
64 | |
65 | spec.curSplitShape = nil |
66 | spec.cutTimer = -1 |
67 | spec.isCutting = false |
68 | spec.warnTreeNotOwned = false |
69 | end |
111 | function TreeSaw:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
112 | local spec = self.spec_treeSaw |
113 | |
114 | -- Verify that the split shapes still exist (possible that someone has cut them) |
115 | if self.isServer then |
116 | if spec.curSplitShape ~= nil then |
117 | if not entityExists(spec.curSplitShape) then |
118 | spec.curSplitShape = nil |
119 | if g_server ~= nil then |
120 | spec.cutTimer = -1 |
121 | end |
122 | end |
123 | end |
124 | |
125 | spec.isCutting = spec.curSplitShape ~= nil |
126 | if spec.curSplitShape ~= nil then |
127 | if spec.cutTimer > 0 then |
128 | spec.cutTimer = math.max(spec.cutTimer - dt, 0) |
129 | end |
130 | |
131 | -- cut |
132 | if spec.cutTimer == 0 then |
133 | spec.cutTimer = -1 |
134 | |
135 | local x,y,z = getWorldTranslation(spec.cutNode) |
136 | local nx,ny,nz = localDirectionToWorld(spec.cutNode, 1,0,0) |
137 | local yx,yy,yz = localDirectionToWorld(spec.cutNode, 0,1,0) |
138 | |
139 | ChainsawUtil.cutSplitShape(spec.curSplitShape, x,y,z, nx,ny,nz, yx,yy,yz, spec.cutSizeY, spec.cutSizeZ, self:getActiveFarm()) |
140 | spec.curSplitShape = nil |
141 | end |
142 | end |
143 | end |
144 | |
145 | -- effect and sound for cut |
146 | if self.isClient then |
147 | if spec.cutTimer > 0 then |
148 | g_effectManager:setFillType(spec.effects, FillType.WOODCHIPS) |
149 | g_effectManager:startEffects(spec.effects) |
150 | if not g_soundManager:getIsSamplePlaying(spec.samples.cut) then |
151 | g_soundManager:playSample(spec.samples.cut) |
152 | end |
153 | else |
154 | g_effectManager:stopEffects(spec.effects) |
155 | if g_soundManager:getIsSamplePlaying(spec.samples.cut) then |
156 | g_soundManager:stopSample(spec.samples.cut) |
157 | end |
158 | end |
159 | end |
160 | end |
167 | function TreeSaw:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
168 | local spec = self.spec_treeSaw |
169 | spec.warnTreeNotOwned = false |
170 | |
171 | if self:getIsTurnedOn() then |
172 | if spec.cutNode ~= nil then |
173 | local x,y,z = getWorldTranslation(spec.cutNode) |
174 | local nx,ny,nz = localDirectionToWorld(spec.cutNode, 1,0,0) |
175 | local yx,yy,yz = localDirectionToWorld(spec.cutNode, 0,1,0) |
176 | |
177 | if spec.curSplitShape == nil then |
178 | local shape, _, _, _, _ = findSplitShape(x,y,z, nx,ny,nz, yx,yy,yz, spec.cutSizeY, spec.cutSizeZ) |
179 | if shape ~= 0 then |
180 | if g_currentMission.accessHandler:canFarmAccessLand(self:getActiveFarm(), x, z) then |
181 | spec.curSplitShape = shape |
182 | spec.cutTimer = spec.cutTimerDuration |
183 | else |
184 | spec.warnTreeNotOwned = true |
185 | end |
186 | end |
187 | end |
188 | |
189 | if spec.curSplitShape ~= nil then |
190 | local minY,maxY, minZ,maxZ = testSplitShape(spec.curSplitShape, x,y,z, nx,ny,nz, yx,yy,yz, spec.cutSizeY, spec.cutSizeZ) |
191 | if minY == nil then |
192 | spec.curSplitShape = nil |
193 | else |
194 | -- check if cut would be below y=0 (tree CoSy) |
195 | local cutTooLow = false |
196 | local _,y,_ = localToLocal(spec.cutNode, spec.curSplitShape, 0,minY,minZ) |
197 | cutTooLow = cutTooLow or y < 0.01 |
198 | local _,y,_ = localToLocal(spec.cutNode, spec.curSplitShape, 0,minY,maxZ) |
199 | cutTooLow = cutTooLow or y < 0.01 |
200 | local _,y,_ = localToLocal(spec.cutNode, spec.curSplitShape, 0,maxY,minZ) |
201 | cutTooLow = cutTooLow or y < 0.01 |
202 | local _,y,_ = localToLocal(spec.cutNode, spec.curSplitShape, 0,maxY,maxZ) |
203 | cutTooLow = cutTooLow or y < 0.01 |
204 | if cutTooLow then |
205 | spec.curSplitShape = nil |
206 | end |
207 | end |
208 | end |
209 | |
210 | if spec.curSplitShape ~= nil then |
211 | local lenBelow, lenAbove = getSplitShapePlaneExtents(spec.curSplitShape, x,y,z, nx,ny,nz) |
212 | if lenAbove < spec.lengthAboveThreshold or lenBelow < spec.lengthBelowThreshold then |
213 | spec.curSplitShape = nil |
214 | end |
215 | end |
216 | |
217 | if spec.curSplitShape == nil and spec.cutTimer > -1 then |
218 | spec.cutTimer = -1 |
219 | end |
220 | end |
221 | end |
222 | end |
23 | function TreeSaw.registerEventListeners(vehicleType) |
24 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", TreeSaw) |
25 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", TreeSaw) |
26 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", TreeSaw) |
27 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", TreeSaw) |
28 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", TreeSaw) |
29 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", TreeSaw) |
30 | SpecializationUtil.registerEventListener(vehicleType, "onDraw", TreeSaw) |
31 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", TreeSaw) |
32 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", TreeSaw) |
33 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", TreeSaw) |
34 | end |