Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved. |
2 | |
3 | local UPDATE_INDEX = 0; |
4 | local KEEP_INDEX = 1; |
5 | local SET_INDEX_TO_ZERO = 2; |
6 | |
7 | local TYPE_COMPARE_EQUAL = 0; |
8 | local TYPE_COMPARE_NOTEQUAL = 1; |
9 | local TYPE_COMPARE_NONE = 2; |
10 | |
11 | function Utils.cutFruitArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, destroySpray, destroySeedingWidth) |
12 | local ids = g_currentMission.fruits[fruitId]; |
13 | if ids == nil or ids.id == 0 then |
14 | return 0; |
15 | end |
16 | local id = ids.id; |
17 | local desc = FruitUtil.fruitIndexToDesc[fruitId]; |
18 | local value = desc.cutState+1; |
19 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
20 | |
21 | local detailId = g_currentMission.terrainDetailId; |
22 | local spraySum = 0; |
23 | if destroySpray then |
24 | setDensityMaskParams(detailId, "between", desc.minHarvestingGrowthState+1, desc.maxHarvestingGrowthState+1); -- add 1 since growth state 0 has density value 1 |
25 | spraySum = setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.sprayChannel, 1, id, 0, g_currentMission.numFruitStateChannels, 0); |
26 | setDensityMaskParams(detailId, "greater", 0); |
27 | end |
28 | if desc.useSeedingWidth and (destroySeedingWidth == nil or destroySeedingWidth) then |
29 | setDensityMaskParams(detailId, "between", desc.minHarvestingGrowthState+1, desc.maxHarvestingGrowthState+1); -- add 1 since growth state 0 has density value 1 |
30 | local detailTypeValue = 2^g_currentMission.sowingChannel; |
31 | setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, id, 0, g_currentMission.numFruitStateChannels, detailTypeValue); |
32 | setDensityMaskParams(detailId, "greater", 0); |
33 | end |
34 | |
35 | -- if no fruit is there, the value is 0 or 1, thus we need to shift by -1, to get values from 0-4, where 0 is no and 4 is full |
36 | setDensityReturnValueShift(id, -1); |
37 | setDensityCompareParams(id, "between", desc.minHarvestingGrowthState+1, desc.maxHarvestingGrowthState+1); -- add 1 since growth state 0 has density value 1 |
38 | local pixelsSum, numPixels = setDensityParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numFruitStateChannels, value); |
39 | setDensityCompareParams(id, "greater", -1); |
40 | setDensityReturnValueShift(id, 0); |
41 | if desc.allowsPartialGrowthState then |
42 | return pixelsSum / desc.maxHarvestingGrowthState, numPixels, spraySum; |
43 | else |
44 | return numPixels, numPixels, spraySum; |
45 | end |
46 | end |
47 | |
48 | function Utils.updateFruitWindrowArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, value, force, deleteFruit) |
49 | local ids = g_currentMission.fruits[fruitId]; |
50 | if ids == nil or ids.windrowId == 0 then |
51 | return 0; |
52 | end |
53 | local desc = FruitUtil.fruitIndexToDesc[fruitId]; |
54 | local windrowId = ids.windrowId; |
55 | local maskId = ids.id; |
56 | local numMaskChannels = g_currentMission.numFruitStateChannels; |
57 | if value < 0.1 then |
58 | maskId = windrowId; |
59 | numMaskChannels = g_currentMission.numWindrowChannels; |
60 | else |
61 | if maskId == 0 and not force then |
62 | return 0; |
63 | end |
64 | setDensityMaskParams(windrowId, "between", desc.minHarvestingGrowthState+1, desc.maxHarvestingGrowthState+1); -- add 1 since growth state 0 has density value 1 |
65 | end |
66 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(windrowId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
67 | local ret=0; |
68 | if force then |
69 | if deleteFruit == nil or deleteFruit then |
70 | Utils.destroyOtherFruit(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ) |
71 | end |
72 | ret = setDensityParallelogram(windrowId, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numWindrowChannels, value); |
73 | else |
74 | ret = setDensityMaskedParallelogram(windrowId, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numWindrowChannels, maskId, 0, numMaskChannels, value); |
75 | end |
76 | setDensityMaskParams(windrowId, "greater", 0); |
77 | return ret; |
78 | end |
79 | |
80 | function Utils.switchFruitTypeArea(newFruitId, maskFruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, newValue) |
81 | local newIds = g_currentMission.fruits[newFruitId]; |
82 | local ids = g_currentMission.fruits[maskFruitId]; |
83 | if newIds == nil or ids == nil or ids.id == 0 or newIds.id == 0 then |
84 | return; |
85 | end |
86 | local id = newIds.id; |
87 | local maskId = ids.id; |
88 | |
89 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
90 | if newValue ~= nil then |
91 | setDensityMaskedParallelogram(maskId, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numFruitStateChannels, maskId, 0, g_currentMission.numFruitStateChannels, newValue); |
92 | end |
93 | -- change from old to new fruit type wherever the growthstate is > 0 |
94 | setTypeIndexMaskedParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, maskId, 0, g_currentMission.numFruitStateChannels); |
95 | end |
96 | |
97 | function Utils.destroyOtherFruit(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ) |
98 | local ids = g_currentMission.fruits[fruitId]; |
99 | if ids == nil or ids.id == 0 then |
100 | return; |
101 | end |
102 | local id = ids.id; |
103 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
104 | setDensityTypeIndexCompareMode(id, TYPE_COMPARE_NOTEQUAL); |
105 | setDensityCompareParams(id, "greater", 0); |
106 | setDensityParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numFruitStateChannels, 0); |
107 | setDensityCompareParams(id, "greater", -1); |
108 | setDensityTypeIndexCompareMode(id, TYPE_COMPARE_EQUAL); |
109 | end |
110 | |
111 | function Utils.getFruitArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, allowPreparing) |
112 | if allowPreparing == nil then |
113 | allowPreparing = false; |
114 | end |
115 | local ids = g_currentMission.fruits[fruitId]; |
116 | if ids == nil or ids.id == 0 then |
117 | return 0, 0; |
118 | end |
119 | local id = ids.id; |
120 | local desc = FruitUtil.fruitIndexToDesc[fruitId]; |
121 | setDensityReturnValueShift(id, -1); |
122 | setDensityCompareParams(id, "between", desc.minHarvestingGrowthState+1, desc.maxHarvestingGrowthState+1); -- add 1 since growth state 0 has density value 1 |
123 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
124 | local ret, total = getDensityParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numFruitStateChannels); |
125 | if allowPreparing and desc.minPreparingGrowthState >= 0 and desc.maxPreparingGrowthState >= 0 then |
126 | setDensityCompareParams(id, "between", desc.minPreparingGrowthState+1, desc.maxPreparingGrowthState+1); -- add 1 since growth state 0 has density value 1 |
127 | local ret2, total2 = getDensityParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numFruitStateChannels); |
128 | ret = ret + ret2; |
129 | total = total + total2; |
130 | end |
131 | setDensityCompareParams(id, "greater", -1); |
132 | setDensityReturnValueShift(id, 0); |
133 | return ret, total; |
134 | end |
135 | |
136 | function Utils.getFruitWindrowArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ) |
137 | local ids = g_currentMission.fruits[fruitId]; |
138 | if ids == nil or ids.windrowId == 0 then |
139 | return 0, 0; |
140 | end |
141 | local id = ids.windrowId; |
142 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
143 | local ret, _, total = getDensityParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numWindrowChannels); |
144 | return ret, total; |
145 | end |
146 | |
147 | function Utils.updateCultivatorArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, forced, commonForced, angle) |
148 | forced = Utils.getNoNil(forced, true); |
149 | commonForced = Utils.getNoNil(commonForced, true); |
150 | local detailId = g_currentMission.terrainDetailId; |
151 | Utils.updateDestroyCommonArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, not commonForced); |
152 | |
153 | local value = 2^g_currentMission.cultivatorChannel; |
154 | |
155 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(detailId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
156 | |
157 | setDensityCompareParams(detailId, "greater", 0, 0, value, 0); |
158 | local _,areaBefore,_ = getDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels); |
159 | setDensityCompareParams(detailId, "greater", -1); |
160 | |
161 | local area = 0; |
162 | local realArea = 0; |
163 | if forced then |
164 | area = area + setDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, value); |
165 | if angle ~= nil then |
166 | setDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailAngleFirstChannel, g_currentMission.terrainDetailAngleNumChannels, angle); |
167 | end |
168 | else |
169 | area = area + setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, detailId, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, value); |
170 | if angle ~= nil then |
171 | setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailAngleFirstChannel, g_currentMission.terrainDetailAngleNumChannels, detailId, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, angle); |
172 | end |
173 | end |
174 | |
175 | setDensityCompareParams(detailId, "greater", 0, 0, value, 0); |
176 | local _,areaAfter,_ = getDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels); |
177 | setDensityCompareParams(detailId, "greater", -1); |
178 | |
179 | realArea = areaAfter - areaBefore; |
180 | |
181 | return realArea, area; |
182 | end |
183 | |
184 | function Utils.updatePloughArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, forced, commonForced, angle) |
185 | forced = Utils.getNoNil(forced, true); |
186 | commonForced = Utils.getNoNil(commonForced, true); |
187 | local detailId = g_currentMission.terrainDetailId; |
188 | Utils.updateDestroyCommonArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, not commonForced); |
189 | |
190 | local value = 2^g_currentMission.ploughChannel; |
191 | |
192 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(detailId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
193 | |
194 | setDensityCompareParams(detailId, "greater", 0, 0, value, 0); |
195 | local _,areaBefore,_ = getDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels); |
196 | setDensityCompareParams(detailId, "greater", -1); |
197 | |
198 | local area = 0; |
199 | if forced then |
200 | area = area + setDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, value); |
201 | if angle ~= nil then |
202 | setDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailAngleFirstChannel, g_currentMission.terrainDetailAngleNumChannels, angle); |
203 | end |
204 | else |
205 | area = area + setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, detailId, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, value); |
206 | if angle ~= nil then |
207 | setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailAngleFirstChannel, g_currentMission.terrainDetailAngleNumChannels, detailId, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, angle); |
208 | end |
209 | end |
210 | |
211 | setDensityCompareParams(detailId, "greater", 0, 0, value, 0); |
212 | local _,areaAfter,_ = getDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels); |
213 | setDensityCompareParams(detailId, "greater", -1); |
214 | |
215 | realArea = areaAfter - areaBefore; |
216 | |
217 | return realArea, area; |
218 | end |
219 | |
220 | function Utils.updateDestroyCommonArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, limitToField) |
221 | limitToField = Utils.getNoNil(limitToField, false); |
222 | local detailId = g_currentMission.terrainDetailId; |
223 | -- destroy all fruits |
224 | for index, entry in pairs(g_currentMission.fruits) do |
225 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(entry.id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
226 | setDensityNewTypeIndexMode(entry.id, SET_INDEX_TO_ZERO); |
227 | setDensityTypeIndexCompareMode(entry.id, TYPE_COMPARE_NONE); |
228 | |
229 | -- note: this asumes entry.id has the lowest channel offset |
230 | if limitToField then |
231 | setDensityMaskedParallelogram(entry.id, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numFruitDensityMapChannels, detailId, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, 0); |
232 | else |
233 | setDensityParallelogram(entry.id, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numFruitDensityMapChannels, 0); |
234 | end |
235 | |
236 | setDensityNewTypeIndexMode(entry.id, UPDATE_INDEX); |
237 | setDensityTypeIndexCompareMode(entry.id, TYPE_COMPARE_EQUAL); |
238 | break; |
239 | end |
240 | -- destroy tyre tracks |
241 | if g_currentMission.tyreTrackSystem ~= nil then |
242 | g_currentMission.tyreTrackSystem:eraseParallelogram(startWorldX,startWorldZ, widthWorldX,widthWorldZ, heightWorldX,heightWorldZ); |
243 | end |
244 | --Utils.updateDensity(wheatId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, -1, 0); |
245 | --Utils.updateDensity(wheatCuttedShortId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, 0, 0); |
246 | for i=1, table.getn(g_currentMission.dynamicFoliageLayers) do |
247 | local id = g_currentMission.dynamicFoliageLayers[i]; |
248 | local numChannels = getTerrainDetailNumChannels(id); |
249 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
250 | if limitToField then |
251 | setDensityMaskedParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, 0, numChannels, detailId, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, 0); |
252 | else |
253 | setDensityParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, 0, numChannels, 0); |
254 | end |
255 | end |
256 | end |
257 | |
258 | function Utils.updateSprayArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ) |
259 | local detailId = g_currentMission.terrainDetailId; |
260 | |
261 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(detailId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
262 | local _, numPixels = setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.sprayChannel, 1, detailId, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, 1.0); |
263 | return numPixels; |
264 | end |
265 | |
266 | function Utils.updateSowingArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, angle, useDirectPlanting) |
267 | |
268 | local ids = g_currentMission.fruits[fruitId]; |
269 | if ids == nil or ids.id == 0 then |
270 | return 0; |
271 | end |
272 | angle = Utils.getNoNil(angle, 0); |
273 | useDirectPlanting = Utils.getNoNil(useDirectPlanting, false); |
274 | |
275 | if g_currentMission.tyreTrackSystem ~= nil then |
276 | g_currentMission.tyreTrackSystem:eraseParallelogram(startWorldX,startWorldZ, widthWorldX,widthWorldZ, heightWorldX,heightWorldZ); |
277 | end |
278 | |
279 | local desc = FruitUtil.fruitIndexToDesc[fruitId]; |
280 | |
281 | local detailId = g_currentMission.terrainDetailId; |
282 | local sowingAddChannel; |
283 | if desc.useSeedingWidth then |
284 | sowingAddChannel = g_currentMission.sowingWidthChannel; |
285 | else |
286 | sowingAddChannel = g_currentMission.sowingChannel; |
287 | end |
288 | local excludeMask = 0; |
289 | if not useDirectPlanting then |
290 | excludeMask = 2^g_currentMission.sowingChannel + 2^g_currentMission.sowingWidthChannel; |
291 | end |
292 | local cultivatorChannel = g_currentMission.cultivatorChannel; |
293 | local ploughChannel = g_currentMission.ploughChannel; |
294 | |
295 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(ids.id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
296 | |
297 | local plantValue = 1; |
298 | |
299 | -- plant the fruit |
300 | setDensityMaskParams(ids.id, "greater", 0, 0, 0, excludeMask); |
301 | -- change fruit twice, once with values greater than the plant value and once with values smaller than the plant value (==0) |
302 | -- do not change (and count) the already planted areas |
303 | setDensityCompareParams(ids.id, "greater", plantValue); |
304 | -- Note: we plant numFruitDensityMapChannels, to destroy windrows etc. |
305 | local _,numPixels1 = setDensityMaskedParallelogram(ids.id, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numFruitDensityMapChannels, detailId, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, plantValue); |
306 | setDensityCompareParams(ids.id, "equals", 0); |
307 | local _,numPixels2, totalPixels = setDensityMaskedParallelogram(ids.id, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numFruitDensityMapChannels, detailId, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, plantValue); |
308 | setDensityCompareParams(ids.id, "greater", -1); |
309 | |
310 | local numPixels = numPixels1 + numPixels2; |
311 | setDensityMaskParams(ids.id, "greater", 0); |
312 | |
313 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(detailId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
314 | |
315 | -- add the sowing area and remove the other types |
316 | local value = 2^sowingAddChannel; |
317 | if fruitId == FruitUtil.FRUITTYPE_GRASS then |
318 | value = 0; |
319 | end |
320 | setDensityMaskParams(detailId, "greater", 0, 0, 0, excludeMask); |
321 | local _, numDetailPixels = setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, detailId, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels, value); |
322 | setDensityMaskParams(detailId, "greater", 0); |
323 | if value > 0 then |
324 | setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, g_currentMission.terrainDetailAngleFirstChannel, g_currentMission.terrainDetailAngleNumChannels, detailId, sowingAddChannel, 1, angle); |
325 | end |
326 | |
327 | return numPixels, numDetailPixels; |
328 | end |
329 | |
330 | function Utils.updateMeadowArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, dropWindrow) |
331 | if dropWindrow == nil or dropWindrow then |
332 | Utils.updateFruitWindrowArea(FruitUtil.FRUITTYPE_GRASS, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, 1) |
333 | end |
334 | return Utils.cutFruitArea(FruitUtil.FRUITTYPE_GRASS, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, true, true) |
335 | end |
336 | |
337 | function Utils.updateCuttedMeadowArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ) |
338 | -- regrow grass where we have windrows and cut long of type grass |
339 | --Utils.setGrowthStateAtWindrowArea(FruitUtil.FRUITTYPE_GRASS, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, FruitUtil.FRUITTYPE_GRASS, 1) |
340 | |
341 | local area = Utils.updateFruitWindrowArea(FruitUtil.FRUITTYPE_GRASS, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, 0); |
342 | |
343 | -- regrow grass where we have windrows and cut long of type dryGrass |
344 | --Utils.setGrowthStateAtWindrowArea(FruitUtil.FRUITTYPE_DRYGRASS, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, FruitUtil.FRUITTYPE_GRASS, 1) |
345 | |
346 | -- pick up the dryGrass, this now is of type grass, as the above two commands changed the fruit type to grass |
347 | area = area+ Utils.updateFruitWindrowArea(FruitUtil.FRUITTYPE_DRYGRASS, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, 0); |
348 | |
349 | -- now that we removed the cut long and windrow, maybe there is some hidden drygrass to grow (set it to growth state 1 if there is some) |
350 | Utils.switchFruitTypeArea(FruitUtil.FRUITTYPE_GRASS, FruitUtil.FRUITTYPE_DRYGRASS, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, 1); |
351 | |
352 | return area; |
353 | end |
354 | |
355 | function Utils.updateFruitPreparerArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, startDropWorldX, startDropWorldZ, widthDropWorldX, widthDropWorldZ, heightDropWorldX, heightDropWorldZ) |
356 | local ids = g_currentMission.fruits[fruitId]; |
357 | if ids == nil or ids.id == 0 then |
358 | return 0; |
359 | end |
360 | local desc = FruitUtil.fruitIndexToDesc[fruitId]; |
361 | |
362 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(ids.id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
363 | |
364 | setDensityCompareParams(ids.id, "between", desc.minPreparingGrowthState+1, desc.maxPreparingGrowthState+1); -- add 1 since growth state 0 has density value 1 |
365 | local _, numChangedPixels = setDensityParallelogram(ids.id, x, z, widthX, widthZ, heightX, heightZ, 0, g_currentMission.numFruitStateChannels, desc.preparedGrowthState+1); |
366 | setDensityCompareParams(ids.id, "greater", -1); |
367 | |
368 | if ids.preparingOutputId ~= 0 and numChangedPixels > 0 then |
369 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(ids.preparingOutputId, startDropWorldX, startDropWorldZ, widthDropWorldX, widthDropWorldZ, heightDropWorldX, heightDropWorldZ); |
370 | -- place preparing output only were we have any fruit |
371 | setDensityMaskedParallelogram(ids.preparingOutputId, x, z, widthX, widthZ, heightX, heightZ, 0, 1, ids.id, 0, g_currentMission.numFruitStateChannels, 1); |
372 | end |
373 | |
374 | return numChangedPixels; |
375 | end |
376 | |
377 | |
378 | function Utils.removeGroundValueArea(id, firstChannel, numChannels, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, valueToLeave) |
379 | |
380 | if id == 0 then |
381 | return 0; |
382 | end |
383 | |
384 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
385 | |
386 | --setDensityReturnValueShift(id, -1); |
387 | local valueRemoved, numPixels; |
388 | if valueToLeave <= 0 then |
389 | valueRemoved, numPixels = setDensityParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, firstChannel, numChannels, 0); |
390 | else |
391 | setDensityMaskParams(id, "greater", valueToLeave); |
392 | local oldSum, total = setDensityMaskedParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, firstChannel, numChannels, id, firstChannel, numChannels, valueToLeave); |
393 | setDensityMaskParams(id, "greater", 0); |
394 | valueRemoved = oldSum - valueToLeave*total; |
395 | numPixels = total; |
396 | end |
397 | --setDensityReturnValueShift(id, 0); |
398 | |
399 | return valueRemoved, numPixels; |
400 | end |
401 | |
402 | function Utils.addGroundValueArea(id, firstChannel, numChannels, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, totalAmount) |
403 | if totalAmount <= 0 or id == 0 then |
404 | return 0,0,0,0; |
405 | end |
406 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
407 | local numAdded = 0; |
408 | local roundingError = 0; |
409 | local amountPerPixel = 0; |
410 | local numPixels = getDensityParallelogramArea(id, x, z, widthX, widthZ, heightX, heightZ); |
411 | if numPixels > 0 then |
412 | amountPerPixel = math.floor(totalAmount/numPixels); |
413 | if amountPerPixel > 0 then |
414 | local _,_,totalDelta = addDensityParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, firstChannel, numChannels, amountPerPixel); |
415 | numAdded = totalDelta; |
416 | end |
417 | roundingError = totalAmount - amountPerPixel*numPixels; |
418 | end |
419 | return numAdded, numPixels, amountPerPixel, roundingError; |
420 | end |
421 | |
422 | function Utils.addGroundValueAreaPerPixel(id, firstChannel, numChannels, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, amountPerPixel) |
423 | if amountPerPixel <= 0 then |
424 | return 0; |
425 | end |
426 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
427 | local _,_,numAdded = addDensityParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, firstChannel, numChannels, amountPerPixel); |
428 | return numAdded; |
429 | end |
430 | |
431 | -- unused |
432 | |
433 | |
434 | function Utils.updateFruitCutShortArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, value) |
435 | --[[local ids = g_currentMission.fruits[fruitId]; |
436 | if ids == nil or ids.cutShortId == 0 then |
437 | return 0; |
438 | end |
439 | local desc = FruitUtil.fruitIndexToDesc[fruitId]; |
440 | local cutShortId = ids.cutShortId; |
441 | local maskId = ids.id; |
442 | local numMaskChannels = 3; |
443 | if value < 0.1 then |
444 | maskId = cutShortId; |
445 | numMaskChannels = 1; |
446 | else |
447 | if maskId == 0 then |
448 | return 0; |
449 | end |
450 | setDensityMaskParams(cutShortId, "greater", desc.minHarvestingGrowthState); |
451 | end |
452 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(cutShortId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
453 | setDensityMaskedParallelogram(cutShortId, x, z, widthX, widthZ, heightX, heightZ, 0, 1, maskId, 0, numMaskChannels, value); |
454 | setDensityMaskParams(cutShortId, "greater", 0);]] |
455 | end |
456 | |
457 | function Utils.updateFruitCutLongArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, value, force, deleteFruit) |
458 | --[[local ids = g_currentMission.fruits[fruitId]; |
459 | if ids == nil or ids.cutLongId == 0 then |
460 | return 0; |
461 | end |
462 | local cutLongId = ids.cutLongId; |
463 | local maskId = ids.id; |
464 | local numMaskChannels = 3; |
465 | if value < 0.1 then |
466 | maskId = cutLongId; |
467 | numMaskChannels = 2; |
468 | else |
469 | if maskId == 0 and not force then |
470 | return 0; |
471 | end |
472 | setDensityMaskParams(cutLongId, "greater", 1); |
473 | end |
474 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(cutLongId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
475 | local ret=0; |
476 | if force then |
477 | if deleteFruit == nil or deleteFruit then |
478 | if ids.id ~= 0 then |
479 | setDensityParallelogram(ids.id, x, z, widthX, widthZ, heightX, heightZ, 0, 3, 0); |
480 | end |
481 | end |
482 | if ids.windrowId ~= 0 then |
483 | setDensityParallelogram(ids.windrowId, x, z, widthX, widthZ, heightX, heightZ, 0, 2, 0); |
484 | end |
485 | ret = setDensityParallelogram(cutLongId, x, z, widthX, widthZ, heightX, heightZ, 0, 2, value); |
486 | else |
487 | ret = setDensityMaskedParallelogram(cutLongId, x, z, widthX, widthZ, heightX, heightZ, 0, 2, maskId, 0, numMaskChannels, value); |
488 | end |
489 | setDensityMaskParams(cutLongId, "greater", 0); |
490 | return ret;]] |
491 | return 0; |
492 | end |
493 | |
494 | function Utils.getFruitCutLongArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ) |
495 | --[[local ids = g_currentMission.fruits[fruitId]; |
496 | if ids == nil or ids.cutLongId == 0 then |
497 | return 0, 0; |
498 | end |
499 | local id = ids.cutLongId; |
500 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
501 | local ret, total = getDensityParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, 0, 2); |
502 | return ret, total;]] |
503 | return 0,0; |
504 | end |
505 | |
506 | |
507 | --[[function Utils.setGrowthStateAtCutLongArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, newFruitId, value) |
508 | local newIds = g_currentMission.fruits[newFruitId]; |
509 | local ids = g_currentMission.fruits[fruitId]; |
510 | if newIds == nil or ids == nil or ids.cutLongId == 0 or newIds.id == 0 then |
511 | return; |
512 | end |
513 | local id = newIds.id; |
514 | local maskId = ids.cutLongId; |
515 | |
516 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
517 | setDensityMaskedParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, 0, 3, maskId, 0, 2, value); |
518 | end |
519 | |
520 | function Utils.setGrowthStateAtWindrowArea(fruitId, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, newFruitId, value) |
521 | local newIds = g_currentMission.fruits[newFruitId]; |
522 | local ids = g_currentMission.fruits[fruitId]; |
523 | if newIds == nil or ids == nil or ids.windrowId == 0 or newIds.id == 0 then |
524 | return; |
525 | end |
526 | local id = newIds.id; |
527 | local maskId = ids.windrowId; |
528 | |
529 | local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ); |
530 | setDensityMaskedParallelogram(id, x, z, widthX, widthZ, heightX, heightZ, 0, 3, maskId, 0, 2, value); |
531 | end]] |
532 | |
533 | function Utils.getTyreTrackColorFromDensityBits(densityBits) |
534 | -- TODO: use densityBits and g_currentMission.cultivatorChannel, g_currentMission.ploughChannel etc. to determine color |
535 | -- should return r,g,b,a where a is softness (1.0 = make deep tyre tracks, 0.0 = make shallow tyre tracks) |
536 | -- current value is the same as the terrain dirt layer |
537 | return 0.247,0.191,0.145,1; |
538 | end
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de