Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- |
2 | -- TreePlanter |
3 | -- |
4 | -- @author Manuel Leithner |
5 | -- @date 05/05/14 |
6 | -- |
7 | -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved. |
8 | |
9 | source("dataS/scripts/vehicles/specializations/TreePlanterLoadPalletEvent.lua"); |
10 | source("dataS/scripts/vehicles/specializations/TreePlanterActivatable.lua"); |
11 | |
12 | TreePlanter = {}; |
13 | |
14 | function TreePlanter.prerequisitesPresent(specializations) |
15 | return SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations); |
16 | end; |
17 | |
18 | function TreePlanter:load(xmlFile) |
19 | self.getDoGroundManipulation = Utils.overwrittenFunction(self.getDoGroundManipulation, TreePlanter.getDoGroundManipulation); |
20 | self.getDirtMultiplier = Utils.overwrittenFunction(self.getDirtMultiplier, TreePlanter.getDirtMultiplier); |
21 | self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, TreePlanter.getIsSpeedRotatingPartActive); |
22 | self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, TreePlanter.doCheckSpeedLimit); |
23 | self.setFillLevel = Utils.appendedFunction(self.setFillLevel, TreePlanter.setFillLevel); |
24 | self.createTree = TreePlanter.createTree; |
25 | self.loadPallet = TreePlanter.loadPallet; |
26 | self.removeMountedObject = Utils.appendedFunction(self.removeMountedObject, TreePlanter.removeMountedObject); |
27 | |
28 | if self.isClient then |
29 | self.sampleTreePlanter = Utils.loadSample(xmlFile, {}, "vehicle.treePlanterSound", nil, self.baseDirectory); |
30 | self.treePlanterTurnedOnRotationNodes = Utils.loadRotationNodes(xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "treePlanter", self.components); |
31 | end; |
32 | |
33 | self.treePlanterNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.treePlanter#node")); |
34 | self.treePlanterMinDistance = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.treePlanter#minDistance"), 20); -- distance to next tree |
35 | local refNodeIndex = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.treePlanter#refNodeIndex"), 0) + 1; |
36 | self.treePlanterRefNode = self.groundReferenceNodes[refNodeIndex]; |
37 | if table.getn(self.groundReferenceNodes) == 0 or self.treePlanterRefNode == nil then |
38 | print("Warning: No groundReferenceNode specified or invalid groundReferenceNode index in '".. self.configFileName .. "'"); |
39 | end; |
40 | |
41 | self.treePlanterActivatable = TreePlanterActivatable:new(self); |
42 | |
43 | self.saplingPalletGrabNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.treePlanter#saplingPalletGrabNode")), self.rootNode); |
44 | self.saplingPalletMountNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.treePlanter#saplingPalletMountNode")), self.rootNode); |
45 | self.mountedSaplingPallet = nil; |
46 | |
47 | self.fillTypes[Fillable.FILLTYPE_TREESAPLINGS] = true; |
48 | self.currentTree = 1; |
49 | self.lastTreePos = nil; |
50 | self.synchronizeFullFillLevel = true; |
51 | |
52 | self.nearestPalletDistance = 6.0; |
53 | self.treePlantingRefNode = 1; |
54 | self.showFieldNotOwnedWarning = false; |
55 | |
56 | self.isTreePlanterSpeedLimitActive = false; |
57 | |
58 | self.treePlanterDirtyFlag = self:getNextDirtyFlag(); |
59 | end; |
60 | |
61 | function TreePlanter:delete() |
62 | if self.isClient then |
63 | Utils.deleteSample(self.sampleTreePlanter); |
64 | end; |
65 | if self.treePlanterActivatable ~= nil then |
66 | g_currentMission:removeActivatableObject(self.treePlanterActivatable); |
67 | end; |
68 | if self.mountedSaplingPallet ~= nil then |
69 | self.mountedSaplingPallet:unmount(); |
70 | self.mountedSaplingPallet = nil; |
71 | end; |
72 | end; |
73 | |
74 | function TreePlanter:removeMountedObject(object, isDeleting) |
75 | if self.mountedSaplingPallet == object then |
76 | self.mountedSaplingPallet = nil; |
77 | end |
78 | end |
79 | |
80 | function TreePlanter:readStream(streamId, connection) |
81 | local hasPallet = streamReadBool(streamId); |
82 | if hasPallet then |
83 | self.palletIdToMount = streamReadInt32(streamId); |
84 | end; |
85 | end; |
86 | |
87 | function TreePlanter:writeStream(streamId, connection) |
88 | streamWriteBool(streamId, self.mountedSaplingPallet ~= nil); |
89 | if self.mountedSaplingPallet ~= nil then |
90 | local palletId = networkGetObjectId(self.mountedSaplingPallet); |
91 | streamWriteInt32(streamId, palletId); |
92 | end; |
93 | end; |
94 | |
95 | |
96 | function TreePlanter:readUpdateStream(streamId, timestamp, connection) |
97 | if connection:getIsServer() then |
98 | self.treePlanterHasGroundContact = streamReadBool(streamId); |
99 | self.showFieldNotOwnedWarning = streamReadBool(streamId); |
100 | end; |
101 | end; |
102 | |
103 | function TreePlanter:writeUpdateStream(streamId, connection, dirtyMask) |
104 | if not connection:getIsServer() then |
105 | streamWriteBool(streamId, self.treePlanterHasGroundContact); |
106 | streamWriteBool(streamId, self.showFieldNotOwnedWarning); |
107 | end; |
108 | end; |
109 | |
110 | function TreePlanter:mouseEvent(posX, posY, isDown, isUp, button) |
111 | end; |
112 | |
113 | function TreePlanter:keyEvent(unicode, sym, modifier, isDown) |
114 | end; |
115 | |
116 | function TreePlanter:update(dt) |
117 | if self.firstTimeRun then |
118 | if self.palletIdToMount ~= nil then |
119 | local pallet = networkGetObject(self.palletIdToMount); |
120 | if pallet ~= nil then |
121 | pallet:mount(self, self.saplingPalletMountNode, 0,0,0, 0,0,0); |
122 | self:setFillLevel(pallet.fillLevel, pallet.fillType); |
123 | self.capacity = pallet.capacity; |
124 | self.mountedSaplingPallet = pallet; |
125 | g_currentMission:removeActivatableObject(self.treePlanterActivatable) |
126 | self.palletIdToMount = nil; |
127 | end; |
128 | end; |
129 | end; |
130 | |
131 | if self:getIsActive() then |
132 | if self.mountedSaplingPallet == nil then |
133 | self.nearestSaplingPallet = TreePlanter.getSaplingPalletInRange(self, self.saplingPalletGrabNode); |
134 | if self.nearestSaplingPallet ~= nil then |
135 | g_currentMission:addActivatableObject(self.treePlanterActivatable); |
136 | else |
137 | g_currentMission:removeActivatableObject(self.treePlanterActivatable); |
138 | end; |
139 | end; |
140 | end |
141 | |
142 | if self.isClient then |
143 | Utils.updateRotationNodes(self, self.treePlanterTurnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn()); |
144 | end; |
145 | end; |
146 | |
147 | function TreePlanter:updateTick(dt) |
148 | self.isTreePlanterSpeedLimitActive = false; |
149 | if self:getIsActive() then |
150 | local showFieldNotOwnedWarning = false; |
151 | |
152 | if self.isServer then |
153 | local hasGroundContact = false; |
154 | if self.treePlanterRefNode ~= nil then |
155 | hasGroundContact = self.treePlanterRefNode.isActive; |
156 | end; |
157 | if self.treePlanterHasGroundContact ~= hasGroundContact then |
158 | self:raiseDirtyFlags(self.treePlanterDirtyFlag); |
159 | end |
160 | self.treePlanterHasGroundContact = hasGroundContact; |
161 | end |
162 | local hasGroundContact = self.treePlanterHasGroundContact; |
163 | |
164 | if hasGroundContact and self.mountedSaplingPallet ~= nil then |
165 | if self:getIsTurnedOn() then |
166 | self.isTreePlanterSpeedLimitActive = true; |
167 | |
168 | if self.isServer then |
169 | if self:getLastSpeed() > 1 and self.fillLevel > 0 then |
170 | local x,y,z = getWorldTranslation(self.treePlanterNode); |
171 | if g_currentMission:getIsFieldOwnedAtWorldPos(x,z) then |
172 | showFieldNotOwnedWarning = false; |
173 | if self.lastTreePos ~= nil then |
174 | local distance = Utils.vector3Length(x-self.lastTreePos[1], y-self.lastTreePos[2], z-self.lastTreePos[3]); |
175 | if distance > self.treePlanterMinDistance then |
176 | self:createTree(); |
177 | end; |
178 | else |
179 | self:createTree(); |
180 | end; |
181 | else |
182 | showFieldNotOwnedWarning = true; |
183 | end; |
184 | end; |
185 | end; |
186 | end; |
187 | end; |
188 | |
189 | if self.isServer then |
190 | if showFieldNotOwnedWarning ~= self.showFieldNotOwnedWarning then |
191 | self.showFieldNotOwnedWarning = showFieldNotOwnedWarning; |
192 | self:raiseDirtyFlags(self.treePlanterDirtyFlag); |
193 | end |
194 | end |
195 | |
196 | if self.isClient then |
197 | if self:getIsTurnedOn() and self.treePlanterHasGroundContact and self:getIsActiveForSound() and self:getLastSpeed() > 1 then |
198 | Utils.playSample(self.sampleTreePlanter, 0, 0, nil); |
199 | else |
200 | Utils.stopSample(self.sampleTreePlanter, true); |
201 | end; |
202 | end; |
203 | end; |
204 | end; |
205 | |
206 | function TreePlanter:draw() |
207 | if self.isClient then |
208 | if self:getIsActiveForInput(true) then |
209 | if self.fillLevel <= 0 and self:getCapacity() ~= 0 then |
210 | g_currentMission:addExtraPrintText(g_i18n:getText("FirstFillTheTool")); |
211 | end; |
212 | end |
213 | |
214 | if self.fillLevel > 0 then |
215 | g_currentMission:setFillTypeOverlayFillType(Fillable.FILLTYPE_TREESAPLINGS); |
216 | end; |
217 | |
218 | if self.showFieldNotOwnedWarning then |
219 | g_currentMission:showBlinkingWarning(g_i18n:getText("You_dont_own_this_field")); |
220 | end |
221 | end; |
222 | end; |
223 | |
224 | function TreePlanter:onAttach(attacherVehicle, jointDescIndex) |
225 | end; |
226 | |
227 | function TreePlanter:onDeactivateSounds() |
228 | if self.isClient then |
229 | Utils.stopSample(self.sampleTreePlanter, true); |
230 | end; |
231 | end; |
232 | |
233 | function TreePlanter:onTurnedOff(noEventSend) |
234 | TreePlanter.onDeactivateSounds(self) |
235 | end; |
236 | |
237 | function TreePlanter:createTree() |
238 | if self.isServer and self.mountedSaplingPallet ~= nil then |
239 | local x,y,z = getWorldTranslation(self.treePlanterNode); |
240 | local yRot = math.random() * 2*math.pi; |
241 | TreePlantUtil.plantTree(g_currentMission.plantedTrees, self.mountedSaplingPallet.treeType, x,y,z, 0,yRot,0, 0); |
242 | self.lastTreePos = {x,y,z}; |
243 | self:setFillLevel(self.fillLevel - 1, Fillable.FILLTYPE_TREESAPLINGS); |
244 | end; |
245 | end; |
246 | |
247 | function TreePlanter:setFillLevel(fillLevel, fillType, force) |
248 | if self.mountedSaplingPallet ~= nil then |
249 | self.mountedSaplingPallet:setFillLevel(fillLevel); |
250 | if self.mountedSaplingPallet.fillLevel <= 0 then |
251 | self.mountedSaplingPallet:delete(); |
252 | self.mountedSaplingPallet = nil; |
253 | end; |
254 | end; |
255 | end; |
256 | |
257 | function TreePlanter:loadPallet(palletObjectId, noEventSend) |
258 | TreePlanterLoadPalletEvent.sendEvent(self, palletObjectId, noEventSend); |
259 | |
260 | self.palletIdToMount = palletObjectId; |
261 | end; |
262 | |
263 | function TreePlanter:getDirtMultiplier(superFunc) |
264 | local multiplier = 0; |
265 | if superFunc ~= nil then |
266 | multiplier = multiplier + superFunc(self); |
267 | end; |
268 | |
269 | if self.treePlanterHasGroundContact then |
270 | multiplier = multiplier + self.workMultiplier * self:getLastSpeed() / self.speedLimit; |
271 | end; |
272 | |
273 | return multiplier; |
274 | end; |
275 | |
276 | function TreePlanter:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart) |
277 | |
278 | if not self.treePlanterHasGroundContact then |
279 | return false; |
280 | end; |
281 | |
282 | if superFunc ~= nil then |
283 | return superFunc(self, speedRotatingPart); |
284 | end |
285 | return true; |
286 | end; |
287 | |
288 | function TreePlanter:doCheckSpeedLimit(superFunc) |
289 | local parent = true; |
290 | if superFunc ~= nil then |
291 | parent = superFunc(self); |
292 | end |
293 | |
294 | return parent and self.treePlanterHasGroundContact; --self.isTreePlanterSpeedLimitActive; |
295 | end; |
296 | |
297 | function TreePlanter:loadFromAttributesAndNodes(xmlFile, key, resetVehicles) |
298 | if not resetVehicles then |
299 | local lastTreePos = getXMLString(xmlFile, key.."#lastTreePos"); |
300 | if lastTreePos ~= nil then |
301 | self.lastTreePos = Utils.getVectorNFromString(lastTreePos, 3); |
302 | end |
303 | |
304 | local palletClassName = getXMLString(xmlFile, key..".pallet#className"); |
305 | if palletClassName ~= nil then |
306 | local modName = getXMLString(xmlFile, key..".pallet#modName"); |
307 | if modName == nil or g_modIsLoaded[modName] then |
308 | local itemClass = getClassObject(palletClassName); |
309 | if itemClass ~= nil and itemClass.new ~= nil then |
310 | local item = itemClass:new(self.isServer, self.isClient); |
311 | if item ~= nil and item.loadFromAttributesAndNodes ~= nil and item:loadFromAttributesAndNodes(xmlFile, key..".pallet") then |
312 | item:register(); |
313 | item:mount(self, self.saplingPalletMountNode, 0,0,0, 0,0,0); |
314 | self.mountedSaplingPallet = item; |
315 | end |
316 | end |
317 | end |
318 | end |
319 | end |
320 | |
321 | return BaseMission.VEHICLE_LOAD_OK; |
322 | end; |
323 | |
324 | function TreePlanter:getSaveAttributesAndNodes(nodeIdent, usedModNames) |
325 | local attributes = ''; |
326 | local nodes = ''; |
327 | if self.lastTreePos ~= nil then |
328 | attributes = 'lastTreePos="'..self.lastTreePos[1]..' ' .. self.lastTreePos[2] .. ' ' .. self.lastTreePos[3] ..'"'; |
329 | end; |
330 | if self.mountedSaplingPallet ~= nil then |
331 | local modExtra = ""; |
332 | local modName = self.mountedSaplingPallet.customEnvironment; |
333 | local classModName = getClassModName(self.mountedSaplingPallet.className); |
334 | if modName == nil then |
335 | modName = classModName; |
336 | end |
337 | if modName ~= nil then |
338 | if usedModNames ~= nil then |
339 | usedModNames[modName] = modName; |
340 | end |
341 | modExtra = ' modName="'..modName..'"'; |
342 | end |
343 | if classModName ~= nil then |
344 | if usedModNames ~= nil then |
345 | usedModNames[classModName] = classModName; |
346 | end |
347 | end |
348 | nodes = nodeIdent..'<pallet className="'..self.mountedSaplingPallet.className..'"'..modExtra; |
349 | local palletAttributes, palletNodes = self.mountedSaplingPallet:getSaveAttributesAndNodes(nodeIdent.." ", usedModNames); |
350 | if palletAttributes ~= nil and palletAttributes ~= "" then |
351 | nodes = nodes.." "..palletAttributes; |
352 | end |
353 | if palletNodes ~= nil and palletNodes ~= "" then |
354 | nodes = nodes..">\n"..palletNodes.."\n"..nodeIdent.."</pallet>\n"; |
355 | else |
356 | nodes = nodes..'/>'; |
357 | end |
358 | end |
359 | return attributes, nodes; |
360 | end; |
361 | |
362 | function TreePlanter:getDoGroundManipulation(supreFunc) |
363 | if not self:getIsTurnedOn() then |
364 | return false; |
365 | end |
366 | if superFunc ~= nil then |
367 | return superFunc(self); |
368 | end |
369 | return true; |
370 | end; |
371 | |
372 | function TreePlanter.getDefaultSpeedLimit() |
373 | return 5; |
374 | end; |
375 | |
376 | function TreePlanter.getSaplingPalletInRange(self, refNode) |
377 | local px, py, pz = getWorldTranslation(refNode); |
378 | local nearestDistance = self.nearestPalletDistance; |
379 | local nearestSaplingPallet = nil; |
380 | |
381 | for index, item in pairs(g_currentMission.itemsToSave) do |
382 | local saplingPallet = item.item; |
383 | if saplingPallet:isa(SaplingPallet) then |
384 | local vx, vy, vz = getWorldTranslation(saplingPallet.nodeId); |
385 | local distance = Utils.vector3Length(px-vx, py-vy, pz-vz); |
386 | if distance < nearestDistance then |
387 | nearestSaplingPallet = saplingPallet; |
388 | end |
389 | end; |
390 | end; |
391 | return nearestSaplingPallet; |
392 | end;
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de