Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- |
2 | -- RidgeMarker |
3 | -- This is the specialization for tools which have a ridge marker |
4 | -- |
5 | -- @author Stefan Geiger |
6 | -- @date 19/06/12 |
7 | -- |
8 | -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved. |
9 | |
10 | |
11 | source("dataS/scripts/vehicles/specializations/RidgeMarkerSetStateEvent.lua"); |
12 | |
13 | RidgeMarker = {}; |
14 | RidgeMarker.sendNumBits = 3; |
15 | RidgeMarker.numMaxStates = 2^RidgeMarker.sendNumBits; -- Include State 0 |
16 | |
17 | function RidgeMarker.initSpecialization() |
18 | WorkArea.registerAreaType("ridgemarker"); |
19 | end; |
20 | |
21 | function RidgeMarker.prerequisitesPresent(specializations) |
22 | return SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations) and SpecializationUtil.hasSpecialization(WorkArea, specializations); |
23 | end; |
24 | |
25 | function RidgeMarker:preLoad(xmlFile) |
26 | self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, RidgeMarker.loadWorkAreaFromXML); |
27 | self.loadSpeedRotatingPartFromXML = Utils.overwrittenFunction(self.loadSpeedRotatingPartFromXML, RidgeMarker.loadSpeedRotatingPartFromXML); |
28 | self.canFoldRidgeMarker = RidgeMarker.canFoldRidgeMarker; |
29 | end |
30 | |
31 | function RidgeMarker:load(xmlFile) |
32 | self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, RidgeMarker.getIsSpeedRotatingPartActive); |
33 | self.getIsWorkAreaActive = Utils.overwrittenFunction(self.getIsWorkAreaActive, RidgeMarker.getIsWorkAreaActive); |
34 | self.setRidgeMarkerState = RidgeMarker.setRidgeMarkerState; |
35 | |
36 | local inputButtonStr = getXMLString(xmlFile, "vehicle.ridgeMarker#inputButton"); |
37 | if inputButtonStr ~= nil then |
38 | self.ridgeMarkerInputButton = InputBinding[inputButtonStr]; |
39 | end; |
40 | self.ridgeMarkerInputButton = Utils.getNoNil(self.ridgeMarkerInputButton, InputBinding.IMPLEMENT_EXTRA4); |
41 | |
42 | self.ridgeMarkers = {}; |
43 | local i = 0; |
44 | while true do |
45 | local key = string.format("vehicle.ridgeMarkers.ridgeMarker(%d)", i); |
46 | if not hasXMLProperty(xmlFile, key) then |
47 | break; |
48 | end; |
49 | if table.getn(self.ridgeMarkers) >= RidgeMarker.numMaxStates-1 then |
50 | print("Error: RidgeMarker.load too many rigdeMarker states. Only "..(RidgeMarker.numMaxStates-1).." states are supported"); |
51 | break; |
52 | end; |
53 | local ridgeMarker = {}; |
54 | ridgeMarker.animName = getXMLString(xmlFile, key .. "#animName"); |
55 | table.insert(self.ridgeMarkers, ridgeMarker); |
56 | i = i + 1; |
57 | end; |
58 | self.numRigdeMarkers = table.getn(self.ridgeMarkers); |
59 | |
60 | self.ridgeMarkerMinFoldTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.ridgeMarkers#foldMinLimit"), 0); |
61 | self.ridgeMarkerMaxFoldTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.ridgeMarkers#foldMaxLimit"), 1); |
62 | self.foldDisableDirection = getXMLInt(xmlFile, "vehicle.ridgeMarkers#foldDisableDirection"); |
63 | self.ridgeMarkerOnlyActiveWhenLowered = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.ridgeMarkers#onlyActiveWhenLowered"), true); |
64 | self.ridgeMarkerState = 0; |
65 | end; |
66 | |
67 | function RidgeMarker:delete() |
68 | end; |
69 | |
70 | function RidgeMarker:readStream(streamId, connection) |
71 | local state = streamReadUIntN(streamId, RidgeMarker.sendNumBits); |
72 | self:setRidgeMarkerState(state, true); |
73 | end; |
74 | |
75 | function RidgeMarker:writeStream(streamId, connection) |
76 | streamWriteUIntN(streamId, self.ridgeMarkerState, RidgeMarker.sendNumBits); |
77 | end; |
78 | |
79 | function RidgeMarker:readUpdateStream(streamId, timestamp, connection) |
80 | end; |
81 | |
82 | function RidgeMarker:writeUpdateStream(streamId, connection, dirtyMask) |
83 | end; |
84 | |
85 | function RidgeMarker:loadFromAttributesAndNodes(xmlFile, key, resetVehicles) |
86 | return BaseMission.VEHICLE_LOAD_OK; |
87 | end; |
88 | |
89 | function RidgeMarker:setRelativePosition(positionX, offsetY, positionZ, yRot) |
90 | end; |
91 | |
92 | function RidgeMarker:mouseEvent(posX, posY, isDown, isUp, button) |
93 | end; |
94 | |
95 | function RidgeMarker:keyEvent(unicode, sym, modifier, isDown) |
96 | end; |
97 | |
98 | function RidgeMarker:update(dt) |
99 | if self.isClient and self:getIsActiveForInput(true) and self.numRigdeMarkers > 0 then |
100 | if InputBinding.hasEvent(self.ridgeMarkerInputButton) then |
101 | local newState = (self.ridgeMarkerState + 1) % (self.numRigdeMarkers+1); |
102 | if self:canFoldRidgeMarker(newState) then |
103 | self:setRidgeMarkerState(newState); |
104 | end; |
105 | end; |
106 | end; |
107 | end; |
108 | |
109 | function RidgeMarker:updateTick(dt) |
110 | if self:getIsActive() and self.numRigdeMarkers > 0 then |
111 | if self.isServer and (not self.ridgeMarkerOnlyActiveWhenLowered or self:isLowered(false)) then |
112 | local typedWorkAreas = self:getTypedWorkAreas(WorkArea.AREATYPE_RIDGEMARKER); |
113 | local ploughWorkAreasSend = {}; |
114 | local cultivatorWorkAreasSend = {}; |
115 | for _, workArea in pairs(typedWorkAreas) do |
116 | if self:getIsWorkAreaActive(workArea) then |
117 | local x,_,z = getWorldTranslation(workArea.startTest); |
118 | if g_currentMission:getIsFieldOwnedAtWorldPos(x,z) then |
119 | local x1,_,z1 = getWorldTranslation(workArea.widthTest); |
120 | local x2,_,z2 = getWorldTranslation(workArea.heightTest); |
121 | |
122 | local cultivatorArea = Utils.getDensity(g_currentMission.terrainDetailId, g_currentMission.cultivatorChannel, x, z, x1, z1, x2, z2); |
123 | local ploughArea = Utils.getDensity(g_currentMission.terrainDetailId, g_currentMission.ploughChannel, x, z, x1, z1, x2, z2); |
124 | |
125 | local x,_,z = getWorldTranslation(workArea.start); |
126 | local x1,_,z1 = getWorldTranslation(workArea.width); |
127 | local x2,_,z2 = getWorldTranslation(workArea.height); |
128 | local sowingArea = Utils.getDensity(g_currentMission.terrainDetailId, g_currentMission.sowingChannel, x, z, x1, z1, x2, z2); |
129 | |
130 | -- ignore non-field areas |
131 | if sowingArea > 0 or cultivatorArea > 0 or ploughArea > 0 then |
132 | local wx,wz = x1-x, z1-z; |
133 | local hx,hz = x2-x, z2-z; |
134 | |
135 | local worldToDensity = g_currentMission.terrainDetailMapSize / g_currentMission.terrainSize; |
136 | x = math.floor(x*worldToDensity+0.5)/worldToDensity; |
137 | z = math.floor(z*worldToDensity+0.5)/worldToDensity; |
138 | |
139 | x1, z1 = x+wx, z+wz; |
140 | x2, z2 = x+hx, z+hz; |
141 | |
142 | local workAreasSend = ploughWorkAreasSend; |
143 | if cultivatorArea < ploughArea then |
144 | workAreasSend = cultivatorWorkAreasSend; |
145 | end; |
146 | |
147 | table.insert(workAreasSend, {x,z,x1,z1,x2,z2}); |
148 | end; |
149 | end; |
150 | end; |
151 | end; |
152 | if table.getn(ploughWorkAreasSend) > 0 then |
153 | local dx,_,dz = localDirectionToWorld(self.sowingDirectionNode, 0, 0, 1); |
154 | local angle = Utils.convertToDensityMapAngle(Utils.getYRotationFromDirection(dx, dz), g_currentMission.terrainDetailAngleMaxValue); |
155 | PloughAreaEvent.runLocally(ploughWorkAreasSend, true, true, angle); |
156 | g_server:broadcastEvent(PloughAreaEvent:new(ploughWorkAreasSend, true, true, angle)); |
157 | end; |
158 | if table.getn(cultivatorWorkAreasSend) > 0 then |
159 | local dx,_,dz = localDirectionToWorld(self.sowingDirectionNode, 0, 0, 1); |
160 | local angle = Utils.convertToDensityMapAngle(Utils.getYRotationFromDirection(dx, dz), g_currentMission.terrainDetailAngleMaxValue); |
161 | CultivatorAreaEvent.runLocally(cultivatorWorkAreasSend, true, true, angle); |
162 | g_server:broadcastEvent(CultivatorAreaEvent:new(cultivatorWorkAreasSend, true, true, angle)); |
163 | end; |
164 | end; |
165 | end; |
166 | end; |
167 | |
168 | function RidgeMarker:draw() |
169 | if self.numRigdeMarkers > 0 and self:getIsActiveForInput(true) then |
170 | local newState = (self.ridgeMarkerState + 1) % (self.numRigdeMarkers+1); |
171 | if self:canFoldRidgeMarker(newState) then |
172 | g_currentMission:addHelpButtonText(g_i18n:getText("toggle_ridge_marker"), self.ridgeMarkerInputButton); |
173 | end |
174 | end; |
175 | end; |
176 | |
177 | function RidgeMarker:canFoldRidgeMarker(state) |
178 | if self.foldAnimTime ~= nil and (self.foldAnimTime < self.ridgeMarkerMinFoldTime or self.foldAnimTime > self.ridgeMarkerMaxFoldTime) then |
179 | return false; |
180 | end; |
181 | |
182 | if state ~= 0 and not self.moveToMiddle and self.foldDisableDirection ~= nil and (self.foldDisableDirection == self.foldMoveDirection or self.foldMoveDirection == 0) then |
183 | return false; |
184 | end; |
185 | |
186 | return true; |
187 | end; |
188 | |
189 | function RidgeMarker:setFoldState(direction, moveToMiddle, noEventSend) |
190 | if not moveToMiddle and direction > 0 then |
191 | self:setRidgeMarkerState(0, true); |
192 | end; |
193 | end; |
194 | |
195 | function RidgeMarker:aiTurnOn() |
196 | self:setRidgeMarkerState(0, true); |
197 | end; |
198 | |
199 | function RidgeMarker:onTurnedOff(noEventSend) |
200 | self:setRidgeMarkerState(0, true); |
201 | end; |
202 | |
203 | function RidgeMarker:setRidgeMarkerState(state, noEventSend) |
204 | if noEventSend == nil or noEventSend == false then |
205 | if g_server ~= nil then |
206 | g_server:broadcastEvent(RidgeMarkerSetStateEvent:new(self, state), nil, nil, self); |
207 | else |
208 | g_client:getServerConnection():sendEvent(RidgeMarkerSetStateEvent:new(self, state)); |
209 | end; |
210 | end |
211 | -- fold last state |
212 | if self.ridgeMarkerState ~= 0 then |
213 | local animTime = self:getAnimationTime(self.ridgeMarkers[self.ridgeMarkerState].animName); |
214 | self:playAnimation(self.ridgeMarkers[self.ridgeMarkerState].animName, -1, animTime, true); |
215 | end; |
216 | self.ridgeMarkerState = state; |
217 | |
218 | -- unfold new state |
219 | if self.ridgeMarkerState ~= 0 then |
220 | local animTime = self:getAnimationTime(self.ridgeMarkers[self.ridgeMarkerState].animName); |
221 | self:playAnimation(self.ridgeMarkers[self.ridgeMarkerState].animName, 1, animTime, true); |
222 | end; |
223 | end; |
224 | |
225 | function RidgeMarker:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key) |
226 | if superFunc ~= nil then |
227 | if not superFunc(self, speedRotatingPart, xmlFile, key) then |
228 | return false; |
229 | end |
230 | end |
231 | speedRotatingPart.ridgeMarkerAnim = getXMLString(xmlFile, key .. "#ridgeMarkerAnim"); |
232 | speedRotatingPart.ridgeMarkerAnimTimeMax = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#ridgeMarkerAnimTimeMax"), 0.99); |
233 | |
234 | return true; |
235 | end; |
236 | |
237 | function RidgeMarker:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart) |
238 | if speedRotatingPart.ridgeMarkerAnim ~= nil and self:getAnimationTime(speedRotatingPart.ridgeMarkerAnim) < speedRotatingPart.ridgeMarkerAnimTimeMax then |
239 | return false; |
240 | end; |
241 | |
242 | if superFunc ~= nil then |
243 | return superFunc(self, speedRotatingPart); |
244 | end |
245 | return true; |
246 | end; |
247 | |
248 | function RidgeMarker:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
249 | local retValue = true; |
250 | if superFunc ~= nil then |
251 | retValue = superFunc(self, workArea, xmlFile, key) |
252 | end |
253 | |
254 | local startTest = Utils.indexToObject(self.components, getXMLString(xmlFile, key .."#startIndexTest")); |
255 | local widthTest = Utils.indexToObject(self.components, getXMLString(xmlFile, key .."#widthIndexTest")); |
256 | local heightTest = Utils.indexToObject(self.components, getXMLString(xmlFile, key .."#heightIndexTest")); |
257 | if startTest ~= nil and widthTest ~= nil and heightTest ~= nil then |
258 | workArea.startTest = startTest; |
259 | workArea.widthTest = widthTest; |
260 | workArea.heightTest = heightTest; |
261 | workArea.animName = getXMLString(xmlFile, key .. "#animName"); |
262 | |
263 | if workArea.type == WorkArea.AREATYPE_DEFAULT then |
264 | workArea.type = WorkArea.AREATYPE_RIDGEMARKER; |
265 | end; |
266 | end; |
267 | |
268 | return retValue; |
269 | end; |
270 | |
271 | function RidgeMarker:getIsWorkAreaActive(superFunc, workArea) |
272 | if workArea.type == WorkArea.AREATYPE_RIDGEMARKER then |
273 | if self:getAnimationTime(workArea.animName) < 0.99 then |
274 | return false; |
275 | end; |
276 | end; |
277 | |
278 | if superFunc ~= nil then |
279 | return superFunc(self, workArea); |
280 | end |
281 | return true; |
282 | end;
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de