6 #include "viewport.h" |
6 #include "viewport.h" |
7 #include "command.h" |
7 #include "command.h" |
8 #include "town.h" |
8 #include "town.h" |
9 #include "sound.h" |
9 #include "sound.h" |
10 |
10 |
11 static int GetRandomTreeType(uint tile, uint seed) |
11 static int GetRandomTreeType(TileIndex tile, uint seed) |
12 { |
12 { |
13 byte i; |
13 switch (_opt.landscape) { |
14 |
14 case LT_NORMAL: |
15 if (_opt.landscape == LT_NORMAL) { |
15 return seed * 12 >> 8; |
16 return seed * 12 >> 8; |
16 |
17 } else if (_opt.landscape == LT_HILLY) { |
17 case LT_HILLY: |
18 return (seed >> 5) + 12; |
18 return (seed >> 5) + 12; |
19 } else if (_opt.landscape == LT_DESERT) { |
19 |
20 i = GetMapExtraBits(tile); |
20 case LT_DESERT: |
21 if (i == 0) { |
21 switch (GetMapExtraBits(tile)) { |
22 return (seed >> 6) + 28; |
22 case 0: |
23 } else if (i == 1) { |
23 return (seed >> 6) + 28; |
24 if (seed > 12) |
24 |
25 return -1; |
25 case 1: |
26 return 27; |
26 return (seed > 12) ? -1 : 27; |
27 } else { |
27 |
28 return (seed * 7 >> 8) + 20; |
28 default: |
29 } |
29 return (seed * 7 >> 8) + 20; |
30 } else { |
30 } |
31 return (seed * 9 >> 8) + 32; |
31 |
|
32 default: |
|
33 return (seed * 9 >> 8) + 32; |
32 } |
34 } |
33 } |
35 } |
34 |
36 |
35 static void PlaceTree(uint tile, uint32 r, byte m5_or) |
37 static void PlaceTree(uint tile, uint32 r, byte m5_or) |
36 { |
38 { |
161 if (ex < sx) intswap(ex, sx); |
166 if (ex < sx) intswap(ex, sx); |
162 if (ey < sy) intswap(ey, sy); |
167 if (ey < sy) intswap(ey, sy); |
163 |
168 |
164 cost = 0; // total cost |
169 cost = 0; // total cost |
165 |
170 |
166 for(x=sx; x<=ex; x+=16) { |
171 for (x = sx; x <= ex; x += 16) { |
167 for(y=sy; y<=ey; y+=16) { |
172 for (y = sy; y <= ey; y += 16) { |
|
173 TileInfo ti; |
|
174 |
168 FindLandscapeHeight(&ti, x, y); |
175 FindLandscapeHeight(&ti, x, y); |
169 if (!EnsureNoVehicle(ti.tile)) |
176 if (!EnsureNoVehicle(ti.tile)) |
170 continue; |
177 continue; |
171 |
178 |
172 if (ti.type == MP_TREES) { |
179 switch (ti.type) { |
173 // no more space for trees? |
180 case MP_TREES: |
174 if (_game_mode != GM_EDITOR && (ti.map5 & 0xC0) == 0xC0) { |
181 // no more space for trees? |
175 _error_message = STR_2803_TREE_ALREADY_HERE; |
182 if (_game_mode != GM_EDITOR && (ti.map5 & 0xC0) == 0xC0) { |
176 continue; |
183 _error_message = STR_2803_TREE_ALREADY_HERE; |
177 } |
184 continue; |
178 |
185 } |
179 if (flags & DC_EXEC) { |
186 |
180 _map5[ti.tile] = ti.map5 + 0x40; |
187 if (flags & DC_EXEC) { |
181 MarkTileDirtyByTile(ti.tile); |
188 _map5[ti.tile] = ti.map5 + 0x40; |
182 } |
189 MarkTileDirtyByTile(ti.tile); |
183 // 2x as expensive to add more trees to an existing tile |
190 } |
184 cost += _price.build_trees * 2; |
191 // 2x as expensive to add more trees to an existing tile |
185 } else { |
192 cost += _price.build_trees * 2; |
186 if (ti.type != MP_CLEAR || _map_owner[ti.tile] != OWNER_NONE) { |
193 break; |
|
194 |
|
195 case MP_CLEAR: |
|
196 if (_map_owner[ti.tile] != OWNER_NONE) { |
|
197 _error_message = STR_2804_SITE_UNSUITABLE; |
|
198 continue; |
|
199 } |
|
200 |
|
201 // it's expensive to clear farmland |
|
202 if ((ti.map5 & 0x1F) == 0xF) |
|
203 cost += _price.clear_3; |
|
204 else if ((ti.map5 & 0x1C) == 8) |
|
205 cost += _price.clear_2; |
|
206 |
|
207 if (flags & DC_EXEC) { |
|
208 int treetype; |
|
209 int m2; |
|
210 |
|
211 if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) { |
|
212 Town *t = ClosestTownFromTile(ti.tile, _patches.dist_local_authority); |
|
213 if (t != NULL) |
|
214 ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM); |
|
215 } |
|
216 |
|
217 switch (ti.map5 & 0x1C) { |
|
218 case 0x04: |
|
219 m2 = 16; |
|
220 break; |
|
221 |
|
222 case 0x10: |
|
223 m2 = ((ti.map5 & 3) << 6) | 0x20; |
|
224 break; |
|
225 |
|
226 default: |
|
227 m2 = 0; |
|
228 break; |
|
229 } |
|
230 |
|
231 treetype = p1; |
|
232 if (treetype == -1) { |
|
233 treetype = GetRandomTreeType(ti.tile, Random() >> 24); |
|
234 if (treetype == -1) treetype = 27; |
|
235 } |
|
236 |
|
237 ModifyTile(ti.tile, |
|
238 MP_SETTYPE(MP_TREES) | |
|
239 MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5, |
|
240 m2, /* map2 */ |
|
241 treetype, /* map3lo */ |
|
242 _game_mode == GM_EDITOR ? 3 : 0 /* map5 */ |
|
243 ); |
|
244 |
|
245 if (_game_mode == GM_EDITOR && IS_BYTE_INSIDE(treetype, 0x14, 0x1B)) |
|
246 SetMapExtraBits(ti.tile, 2); |
|
247 } |
|
248 cost += _price.build_trees; |
|
249 break; |
|
250 |
|
251 default: |
187 _error_message = STR_2804_SITE_UNSUITABLE; |
252 _error_message = STR_2804_SITE_UNSUITABLE; |
188 continue; |
253 break; |
189 } |
|
190 |
|
191 // it's expensive to clear farmland |
|
192 if ((ti.map5 & 0x1F) == 0xF) cost += _price.clear_3; |
|
193 else if ((ti.map5 & 0x1C) == 8) cost += _price.clear_2; |
|
194 |
|
195 if (flags & DC_EXEC) { |
|
196 int m2; |
|
197 |
|
198 if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) { |
|
199 Town *t = ClosestTownFromTile(ti.tile, _patches.dist_local_authority); |
|
200 if (t != NULL) |
|
201 ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM); |
|
202 } |
|
203 m2 = 0; |
|
204 if ( (ti.map5 & 0x1C) == 4 ) { |
|
205 m2 = 16; |
|
206 } else if ( (ti.map5 & 0x1C) == 16 ) { |
|
207 m2 = ((ti.map5 & 3) << 6) | 0x20; |
|
208 } |
|
209 |
|
210 treetype = p1; |
|
211 if (treetype == -1) { |
|
212 treetype = GetRandomTreeType(ti.tile, Random()>>24); |
|
213 if (treetype==-1) treetype=27; |
|
214 } |
|
215 |
|
216 ModifyTile(ti.tile, |
|
217 MP_SETTYPE(MP_TREES) | |
|
218 MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5, |
|
219 m2, /* map2 */ |
|
220 treetype, /* map3lo */ |
|
221 _game_mode == GM_EDITOR ? 3 : 0 /* map5 */ |
|
222 ); |
|
223 |
|
224 if (_game_mode == GM_EDITOR && IS_BYTE_INSIDE(treetype, 0x14, 0x1B)) { |
|
225 SetMapExtraBits(ti.tile, 2); |
|
226 } |
|
227 } |
|
228 cost += _price.build_trees; |
|
229 } |
254 } |
230 } |
255 } |
231 } |
256 } |
232 |
257 |
233 if (cost == 0) return CMD_ERROR; |
258 if (cost == 0) return CMD_ERROR; |