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 | WindrowAreaEvent = {}; |
4 | WindrowAreaEvent_mt = Class(WindrowAreaEvent, Event); |
5 | |
6 | InitStaticEventClass(WindrowAreaEvent, "WindrowAreaEvent", EventIds.EVENT_WINDROW_AREA); |
7 | |
8 | function WindrowAreaEvent:emptyNew() |
9 | local self = Event:new(WindrowAreaEvent_mt); |
10 | return self; |
11 | end |
12 | |
13 | function WindrowAreaEvent:new(workAreas, fruitType, bitType) |
14 | local self = WindrowAreaEvent:emptyNew() |
15 | self.workAreas = workAreas; |
16 | self.fruitType = fruitType; |
17 | self.bitType = bitType; |
18 | assert(table.getn(self.workAreas) < 16); |
19 | assert(table.getn(self.workAreas) > 0 ); |
20 | assert(self.bitType >= 0 and self.bitType <= 3); |
21 | return self; |
22 | end |
23 | |
24 | function WindrowAreaEvent:readStream(streamId, connection) |
25 | local numAreas = streamReadUIntN(streamId, 4); |
26 | local fruitType = streamReadUIntN(streamId, FruitUtil.sendNumBits); |
27 | |
28 | local v = {}; |
29 | for i=1, numAreas do |
30 | v[i] = streamReadUIntN(streamId, g_currentMission.numWindrowChannels); |
31 | end |
32 | |
33 | local refX = streamReadFloat32(streamId); |
34 | local refY = streamReadFloat32(streamId); |
35 | local values = Utils.readCompressed2DVectors(streamId, refX, refY, (numAreas)*6-1, 0.01, true); |
36 | |
37 | for i=1, numAreas do |
38 | local vi = i-1; |
39 | local x = values[vi*6+1].x; |
40 | local z = values[vi*6+1].y; |
41 | local x1 = values[vi*6+2].x; |
42 | local z1 = values[vi*6+2].y; |
43 | local x2 = values[vi*6+3].x; |
44 | local z2 = values[vi*6+3].y; |
45 | local dx = values[vi*6+4].x; |
46 | local dz = values[vi*6+4].y; |
47 | local dx1 = values[vi*6+5].x; |
48 | local dz1 = values[vi*6+5].y; |
49 | local dx2 = values[vi*6+6].x; |
50 | local dz2 = values[vi*6+6].y; |
51 | |
52 | Utils.updateFruitWindrowArea(fruitType, x, z, x1, z1, x2, z2, 0); |
53 | |
54 | -- now that we removed the windrow, maybe there is some hidden drygrass to grow (set it to growth state 1 if there is some) |
55 | if fruitType == FruitUtil.FRUITTYPE_GRASS or fruitType == FruitUtil.FRUITTYPE_DRYGRASS then |
56 | Utils.switchFruitTypeArea(FruitUtil.FRUITTYPE_GRASS, FruitUtil.FRUITTYPE_DRYGRASS, x, z, x1, z1, x2, z2, 2); |
57 | end |
58 | |
59 | if fruitType == FruitUtil.FRUITTYPE_GRASS or FruitUtil.FRUITTYPE_DRYGRASS then |
60 | -- switch all dry grass to grass, and then destroy everything that is not grass |
61 | Utils.switchFruitTypeArea(FruitUtil.FRUITTYPE_GRASS, FruitUtil.FRUITTYPE_DRYGRASS, dx, dz, dx1, dz1, dx2, dz2); |
62 | Utils.destroyOtherFruit(FruitUtil.FRUITTYPE_GRASS, dx, dz, dx1, dz1, dx2, dz2); |
63 | |
64 | Utils.updateFruitWindrowArea(fruitType, dx, dz, dx1, dz1, dx2, dz2, v[i], true, false); |
65 | else |
66 | Utils.updateFruitWindrowArea(fruitType, dx, dz, dx1, dz1, dx2, dz2, v[i], true, true); |
67 | end |
68 | end |
69 | end |
70 | |
71 | function WindrowAreaEvent:writeStream(streamId, connection) |
72 | local numWorkAreas = table.getn(self.workAreas); |
73 | streamWriteUIntN(streamId, numWorkAreas, 4); |
74 | streamWriteUIntN(streamId, self.fruitType, FruitUtil.sendNumBits); |
75 | |
76 | for i=1, numWorkAreas do |
77 | streamWriteUIntN(streamId, self.workAreas[i][13], g_currentMission.numWindrowChannels); |
78 | end; |
79 | |
80 | local refX, refY; |
81 | local values = {}; |
82 | for i=1, numWorkAreas do |
83 | local d = self.workAreas[i]; |
84 | if refX == nil then |
85 | refX = d[1]; |
86 | refY = d[2]; |
87 | streamWriteFloat32(streamId, d[1]); |
88 | streamWriteFloat32(streamId, d[2]); |
89 | else |
90 | table.insert(values, {x=d[1], y=d[2]}); |
91 | end |
92 | table.insert(values, {x=d[3], y=d[4]}); |
93 | table.insert(values, {x=d[5], y=d[6]}); |
94 | table.insert(values, {x=d[7], y=d[8]}); |
95 | table.insert(values, {x=d[9], y=d[10]}); |
96 | table.insert(values, {x=d[11], y=d[12]}); |
97 | end |
98 | assert(table.getn(values) == (numWorkAreas)*6 - 1); |
99 | Utils.writeCompressed2DVectors(streamId, refX, refY, values, 0.01, self.bitType); |
100 | end |
101 | |
102 | function WindrowAreaEvent:run(connection) |
103 | print("Error: Do not run WindrowAreaEvent locally"); |
104 | end |
105 | |
106 | |
107 | function WindrowAreaEvent.runLocally(workAreas, accumulatedWorkAreaValues, accumulatedFruitType) |
108 | |
109 | local numAreas = table.getn(workAreas); |
110 | |
111 | local refX, refY; |
112 | local values = {}; |
113 | for i=1, numAreas do |
114 | local d = workAreas[i]; |
115 | if refX==nil then |
116 | refX = d[1]; |
117 | refY = d[2]; |
118 | else |
119 | table.insert(values, {x=d[1], y=d[2]}); |
120 | end |
121 | table.insert(values, {x=d[3], y=d[4]}); |
122 | table.insert(values, {x=d[5], y=d[6]}); |
123 | table.insert(values, {x=d[7], y=d[8]}); |
124 | table.insert(values, {x=d[9], y=d[10]}); |
125 | table.insert(values, {x=d[11], y=d[12]}); |
126 | end |
127 | |
128 | local values, bitType = Utils.simWriteCompressed2DVectors(refX, refY, values, 0.01, true); |
129 | |
130 | local restSum = 0; |
131 | local fruitType = FruitUtil.FRUITTYPE_GRASS; |
132 | local fruitTypeFix = false; |
133 | |
134 | local workAreasSend = {}; |
135 | for i=1, numAreas do |
136 | |
137 | local vi = i-1; |
138 | local x = values[vi*6+1].x; |
139 | local z = values[vi*6+1].y; |
140 | local x1 = values[vi*6+2].x; |
141 | local z1 = values[vi*6+2].y; |
142 | local x2 = values[vi*6+3].x; |
143 | local z2 = values[vi*6+3].y; |
144 | local dx = values[vi*6+4].x; |
145 | local dz = values[vi*6+4].y; |
146 | local dx1 = values[vi*6+5].x; |
147 | local dz1 = values[vi*6+5].y; |
148 | local dx2 = values[vi*6+6].x; |
149 | local dz2 = values[vi*6+6].y; |
150 | |
151 | local area = 0; |
152 | if fruitTypeFix then |
153 | area = Utils.updateFruitWindrowArea(fruitType, x, z, x1, z1, x2, z2, 0); |
154 | else |
155 | -- first try dry grass to avoid wet grass destroying dry grass |
156 | fruitType = FruitUtil.FRUITTYPE_DRYGRASS; |
157 | area = Utils.updateFruitWindrowArea(fruitType, x, z, x1, z1, x2, z2, 0); |
158 | |
159 | if area == 0 then |
160 | for fruitId=1, FruitUtil.NUM_FRUITTYPES do |
161 | if fruitId ~= FruitUtil.FRUITTYPE_DRYGRASS then |
162 | local ids = g_currentMission.fruits[fruitId]; |
163 | if ids ~= nil and ids.windrowId ~= 0 then |
164 | fruitType = fruitId; |
165 | area = Utils.updateFruitWindrowArea(fruitType, x, z, x1, z1, x2, z2, 0); |
166 | if area > 0 then |
167 | break; |
168 | end |
169 | end |
170 | end |
171 | end |
172 | end |
173 | end |
174 | if area > 0 then |
175 | fruitTypeFix = true; |
176 | |
177 | -- now that we removed the windrow, maybe there is some hidden drygrass to grow (set it to growth state 1 if there is some) |
178 | if fruitType == FruitUtil.FRUITTYPE_DRYGRASS then |
179 | Utils.switchFruitTypeArea(FruitUtil.FRUITTYPE_GRASS, FruitUtil.FRUITTYPE_DRYGRASS, x, z, x1, z1, x2, z2, 2); |
180 | end |
181 | |
182 | end |
183 | -- add the accumulated value |
184 | if not fruitTypeFix or accumulatedFruitType == fruitType then |
185 | area = area + accumulatedWorkAreaValues[i]; |
186 | fruitType = accumulatedFruitType; |
187 | end |
188 | accumulatedWorkAreaValues[i] = 0; |
189 | |
190 | if area > 0 then |
191 | |
192 | local old, total = Utils.getFruitWindrowArea(fruitType, dx, dz, dx1, dz1, dx2, dz2); |
193 | |
194 | local value = (area+old) / total; |
195 | |
196 | -- round to the lower value, so the error we make is always positive as we place not enough windrows |
197 | value = math.floor(value+0.001); |
198 | |
199 | |
200 | if value >= 1 then |
201 | -- calculate the error we make by the rounding and clamping, so we can add it the next time |
202 | |
203 | value = math.min(value, g_currentMission.maxWindrowValue); |
204 | accumulatedWorkAreaValues[i] = math.min(math.max(area+old - value*total, 0), 2*g_currentMission.maxWindrowValue); |
205 | |
206 | if fruitType == FruitUtil.FRUITTYPE_GRASS or fruitType == FruitUtil.FRUITTYPE_DRYGRASS then |
207 | -- switch all dry grass to grass, and then destroy everything that is not grass |
208 | Utils.switchFruitTypeArea(FruitUtil.FRUITTYPE_GRASS, FruitUtil.FRUITTYPE_DRYGRASS, dx, dz, dx1, dz1, dx2, dz2); |
209 | Utils.destroyOtherFruit(FruitUtil.FRUITTYPE_GRASS, dx, dz, dx1, dz1, dx2, dz2); |
210 | |
211 | Utils.updateFruitWindrowArea(fruitType, dx, dz, dx1, dz1, dx2, dz2, value, true, false); |
212 | else |
213 | Utils.updateFruitWindrowArea(fruitType, dx, dz, dx1, dz1, dx2, dz2, value, true, true); |
214 | end |
215 | |
216 | if value > 0 then |
217 | table.insert(workAreasSend, {x,z, x1,z1, x2,z2, dx,dz, dx1,dz1, dx2,dz2, value, workAreas[i][14] }); |
218 | end; |
219 | else |
220 | -- calculate the error we make by not changing the drop area |
221 | accumulatedWorkAreaValues[i] = area; |
222 | end |
223 | |
224 | end |
225 | end |
226 | |
227 | return workAreasSend, fruitType, bitType; |
228 | end
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de