7 #include "table/sprites.h" |
7 #include "table/sprites.h" |
8 #include "table/tree_land.h" |
8 #include "table/tree_land.h" |
9 #include "functions.h" |
9 #include "functions.h" |
10 #include "map.h" |
10 #include "map.h" |
11 #include "tile.h" |
11 #include "tile.h" |
|
12 #include "tree.h" |
12 #include "viewport.h" |
13 #include "viewport.h" |
13 #include "command.h" |
14 #include "command.h" |
14 #include "town.h" |
15 #include "town.h" |
15 #include "sound.h" |
16 #include "sound.h" |
16 #include "variables.h" |
17 #include "variables.h" |
17 |
18 |
18 static int GetRandomTreeType(TileIndex tile, uint seed) |
19 static TreeType GetRandomTreeType(TileIndex tile, uint seed) |
19 { |
20 { |
20 switch (_opt.landscape) { |
21 switch (_opt.landscape) { |
21 case LT_NORMAL: |
22 case LT_NORMAL: |
22 return seed * 12 >> 8; |
23 return seed * TR_COUNT_TEMPERATE / 256 + TR_TEMPERATE; |
23 |
24 |
24 case LT_HILLY: |
25 case LT_HILLY: |
25 return (seed >> 5) + 12; |
26 return seed * TR_COUNT_SUB_ARCTIC / 256 + TR_SUB_ARCTIC; |
26 |
27 |
27 case LT_DESERT: |
28 case LT_DESERT: |
28 switch (GetMapExtraBits(tile)) { |
29 switch (GetMapExtraBits(tile)) { |
29 case 0: return (seed >> 6) + 28; |
30 case 0: return seed * TR_COUNT_SUB_TROPICAL / 256 + TR_SUB_TROPICAL; |
30 case 1: return (seed > 12) ? -1 : 27; |
31 case 1: return (seed > 12) ? TR_INVALID : TR_CACTUS; |
31 default: return (seed * 7 >> 8) + 20; |
32 default: return seed * TR_COUNT_RAINFOREST / 256 + TR_RAINFOREST; |
32 } |
33 } |
33 |
34 |
34 default: |
35 default: |
35 return (seed * 9 >> 8) + 32; |
36 return seed * TR_COUNT_TOYLAND / 256 + TR_TOYLAND; |
36 } |
37 } |
37 } |
38 } |
38 |
39 |
39 static void PlaceTree(TileIndex tile, uint32 r) |
40 static void PlaceTree(TileIndex tile, uint32 r) |
40 { |
41 { |
41 int tree = GetRandomTreeType(tile, GB(r, 24, 8)); |
42 TreeType tree = GetRandomTreeType(tile, GB(r, 24, 8)); |
42 byte m5; |
43 |
43 |
44 if (tree != TR_INVALID) { |
44 if (tree >= 0) { |
|
45 SetTileType(tile, MP_TREES); |
45 SetTileType(tile, MP_TREES); |
46 |
46 SetTreeType(tile, tree); |
47 m5 = GB(r, 16, 8); |
47 SetFenceSE(tile, 0); |
48 if (GB(m5, 0, 3) == 7) m5--; // there is no growth state 7 |
48 SetFenceSW(tile, 0); |
49 |
49 SetTreeCount(tile, GB(r, 22, 2)); |
50 _m[tile].m5 = m5 & 0x07; // growth state; |
50 SetTreeGrowth(tile, min(GB(r, 16, 3), 6)); |
51 _m[tile].m5 |= m5 & 0xC0; // amount of trees |
|
52 |
|
53 _m[tile].m3 = tree; // set type of tree |
|
54 _m[tile].m4 = 0; // no hedge |
|
55 |
51 |
56 // above snowline? |
52 // above snowline? |
57 if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) { |
53 if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) { |
58 _m[tile].m2 = 0xE0; // set land type to snow |
54 SetTreeGroundDensity(tile, TR_SNOW_DESERT, 3); |
59 _m[tile].m2 |= GB(r, 24, 3); // randomize counter |
55 SetTreeCounter(tile, GB(r, 24, 3)); |
60 } else { |
56 } else { |
61 _m[tile].m2 = GB(r, 24, 5); // randomize counter and ground |
57 SetTreeGroundDensity(tile, GB(r, 28, 1), 0); |
|
58 SetTreeCounter(tile, GB(r, 24, 4)); |
62 } |
59 } |
63 } |
60 } |
64 } |
61 } |
65 |
62 |
66 static void DoPlaceMoreTrees(TileIndex tile) |
63 static void DoPlaceMoreTrees(TileIndex tile) |
189 case CL_ROCKS: cost += _price.clear_2; break; |
186 case CL_ROCKS: cost += _price.clear_2; break; |
190 default: break; |
187 default: break; |
191 } |
188 } |
192 |
189 |
193 if (flags & DC_EXEC) { |
190 if (flags & DC_EXEC) { |
194 int treetype; |
191 TreeType treetype; |
195 int m2; |
|
196 |
192 |
197 if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) { |
193 if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) { |
198 Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority); |
194 Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority); |
199 if (t != NULL) |
195 if (t != NULL) |
200 ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM); |
196 ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM); |
201 } |
197 } |
202 |
198 |
|
199 treetype = p1; |
|
200 if (treetype == TR_INVALID) { |
|
201 treetype = GetRandomTreeType(tile, GB(Random(), 24, 8)); |
|
202 if (treetype == TR_INVALID) treetype = TR_CACTUS; |
|
203 } |
|
204 |
203 switch (GetClearGround(tile)) { |
205 switch (GetClearGround(tile)) { |
204 case CL_ROUGH: m2 = 16; break; |
206 case CL_ROUGH: SetTreeGroundDensity(tile, TR_ROUGH, 0); break; |
205 case CL_SNOW: m2 = GetClearDensity(tile) << 6 | 0x20; break; |
207 case CL_SNOW: SetTreeGroundDensity(tile, TR_SNOW_DESERT, GetClearDensity(tile)); break; |
206 default: m2 = 0; break; |
208 default: SetTreeGroundDensity(tile, TR_GRASS, 0); break; |
207 } |
209 } |
208 |
210 SetTreeCounter(tile, 0); |
209 treetype = p1; |
211 |
210 if (treetype == -1) { |
212 SetTileType(tile, MP_TREES); |
211 treetype = GetRandomTreeType(tile, GB(Random(), 24, 8)); |
213 SetTreeType(tile, treetype); |
212 if (treetype == -1) treetype = 27; |
214 SetFenceSE(tile, 0); |
213 } |
215 SetFenceSW(tile, 0); |
214 |
216 SetTreeCount(tile, 0); |
215 ModifyTile(tile, |
217 SetTreeGrowth(tile, _game_mode == GM_EDITOR ? 3 : 0); |
216 MP_SETTYPE(MP_TREES) | |
218 |
217 MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5, |
219 if (_game_mode == GM_EDITOR && IS_INT_INSIDE(treetype, TR_RAINFOREST, TR_CACTUS)) |
218 m2, /* map2 */ |
|
219 treetype, /* map3lo */ |
|
220 _game_mode == GM_EDITOR ? 3 : 0 /* map5 */ |
|
221 ); |
|
222 |
|
223 if (_game_mode == GM_EDITOR && IS_BYTE_INSIDE(treetype, 0x14, 0x1B)) |
|
224 SetMapExtraBits(tile, 2); |
220 SetMapExtraBits(tile, 2); |
225 } |
221 } |
226 cost += _price.build_trees; |
222 cost += _price.build_trees; |
227 break; |
223 break; |
228 |
224 |
365 /* not used */ |
359 /* not used */ |
366 } |
360 } |
367 |
361 |
368 static void GetTileDesc_Trees(TileIndex tile, TileDesc *td) |
362 static void GetTileDesc_Trees(TileIndex tile, TileDesc *td) |
369 { |
363 { |
370 byte b; |
364 TreeType tt = GetTreeType(tile); |
371 StringID str; |
365 |
|
366 if (IS_INT_INSIDE(tt, TR_RAINFOREST, TR_CACTUS)) { |
|
367 td->str = STR_280F_RAINFOREST; |
|
368 } else if (tt == TR_CACTUS) { |
|
369 td->str = STR_2810_CACTUS_PLANTS; |
|
370 } else { |
|
371 td->str = STR_280E_TREES; |
|
372 } |
372 |
373 |
373 td->owner = GetTileOwner(tile); |
374 td->owner = GetTileOwner(tile); |
374 |
|
375 b = _m[tile].m3; |
|
376 (str=STR_2810_CACTUS_PLANTS, b==0x1B) || |
|
377 (str=STR_280F_RAINFOREST, IS_BYTE_INSIDE(b, 0x14, 0x1A+1)) || |
|
378 (str=STR_280E_TREES, true); |
|
379 td->str = str; |
|
380 } |
375 } |
381 |
376 |
382 static void AnimateTile_Trees(TileIndex tile) |
377 static void AnimateTile_Trees(TileIndex tile) |
383 { |
378 { |
384 /* not used */ |
379 /* not used */ |
385 } |
380 } |
386 |
381 |
387 static void TileLoopTreesDesert(TileIndex tile) |
382 static void TileLoopTreesDesert(TileIndex tile) |
388 { |
383 { |
389 static const SoundFx forest_sounds[] = { |
384 switch (GetMapExtraBits(tile)) { |
390 SND_42_LOON_BIRD, |
385 case 1: |
391 SND_43_LION, |
386 if (GetTreeGround(tile) != TR_SNOW_DESERT) { |
392 SND_44_MONKEYS, |
387 SetTreeGroundDensity(tile, TR_SNOW_DESERT, 3); |
393 SND_48_DISTANT_BIRD |
388 MarkTileDirtyByTile(tile); |
394 }; |
389 } |
395 |
390 break; |
396 byte b = GetMapExtraBits(tile); |
391 |
397 |
392 case 2: { |
398 if (b == 2) { |
393 static const SoundFx forest_sounds[] = { |
399 uint32 r = Random(); |
394 SND_42_LOON_BIRD, |
400 |
395 SND_43_LION, |
401 if (CHANCE16I(1, 200, r)) SndPlayTileFx(forest_sounds[GB(r, 16, 2)], tile); |
396 SND_44_MONKEYS, |
402 } else if (b == 1) { |
397 SND_48_DISTANT_BIRD |
403 if (GB(_m[tile].m2, 4, 2) != 2) { |
398 }; |
404 SB(_m[tile].m2, 4, 2, 2); |
399 uint32 r = Random(); |
405 SB(_m[tile].m2, 6, 2, 3); |
400 |
406 MarkTileDirtyByTile(tile); |
401 if (CHANCE16I(1, 200, r)) SndPlayTileFx(forest_sounds[GB(r, 16, 2)], tile); |
|
402 break; |
407 } |
403 } |
408 } |
404 } |
409 } |
405 } |
410 |
406 |
411 static void TileLoopTreesAlps(TileIndex tile) |
407 static void TileLoopTreesAlps(TileIndex tile) |
412 { |
408 { |
413 byte tmp, m2; |
409 int k = GetTileZ(tile) - _opt.snow_line; |
414 int k; |
|
415 |
|
416 /* distance from snow line, in steps of 8 */ |
|
417 k = GetTileZ(tile) - _opt.snow_line; |
|
418 |
|
419 tmp = _m[tile].m2 & 0xF0; |
|
420 |
410 |
421 if (k < -8) { |
411 if (k < -8) { |
422 if ((tmp & 0x30) != 0x20) return; |
412 if (GetTreeGround(tile) != TR_SNOW_DESERT) return; |
423 m2 = 0; // no snow |
413 SetTreeGroundDensity(tile, TR_GRASS, 0); |
424 } else if (k == -8) { |
|
425 m2 = 0x20; // 1/4 snow |
|
426 if (tmp == m2) return; |
|
427 } else if (k == 0) { |
|
428 m2 = 0x60;// 1/2 snow |
|
429 if (tmp == m2) return; |
|
430 } else if (k == 8) { |
|
431 m2 = 0xA0; // 3/4 snow |
|
432 if (tmp == m2) return; |
|
433 } else { |
414 } else { |
434 if (tmp == 0xE0) { |
415 uint density = min((uint)(k + 8) / 8, 3); |
435 uint32 r = Random(); |
416 |
436 if (CHANCE16I(1, 200, r)) { |
417 if (GetTreeGround(tile) != TR_SNOW_DESERT || GetTreeDensity(tile) != density) { |
437 SndPlayTileFx((r & 0x80000000) ? SND_39_HEAVY_WIND : SND_34_WIND, tile); |
418 SetTreeGroundDensity(tile, TR_SNOW_DESERT, density); |
|
419 } else { |
|
420 if (GetTreeDensity(tile) == 3) { |
|
421 uint32 r = Random(); |
|
422 if (CHANCE16I(1, 200, r)) { |
|
423 SndPlayTileFx((r & 0x80000000) ? SND_39_HEAVY_WIND : SND_34_WIND, tile); |
|
424 } |
438 } |
425 } |
439 return; |
426 return; |
440 } else { |
427 } |
441 m2 = 0xE0; // full snow |
428 } |
442 } |
|
443 } |
|
444 |
|
445 _m[tile].m2 &= 0xF; |
|
446 _m[tile].m2 |= m2; |
|
447 MarkTileDirtyByTile(tile); |
429 MarkTileDirtyByTile(tile); |
448 } |
430 } |
449 |
431 |
450 static void TileLoop_Trees(TileIndex tile) |
432 static void TileLoop_Trees(TileIndex tile) |
451 { |
433 { |
452 byte m5; |
|
453 |
|
454 static const TileIndexDiffC _tileloop_trees_dir[] = { |
434 static const TileIndexDiffC _tileloop_trees_dir[] = { |
455 {-1, -1}, |
435 {-1, -1}, |
456 { 0, -1}, |
436 { 0, -1}, |
457 { 1, -1}, |
437 { 1, -1}, |
458 {-1, 0}, |
438 {-1, 0}, |
460 {-1, 1}, |
440 {-1, 1}, |
461 { 0, 1}, |
441 { 0, 1}, |
462 { 1, 1} |
442 { 1, 1} |
463 }; |
443 }; |
464 |
444 |
465 if (_opt.landscape == LT_DESERT) { |
445 switch (_opt.landscape) { |
466 TileLoopTreesDesert(tile); |
446 case LT_DESERT: TileLoopTreesDesert(tile); break; |
467 } else if (_opt.landscape == LT_HILLY) { |
447 case LT_HILLY: TileLoopTreesAlps(tile); break; |
468 TileLoopTreesAlps(tile); |
|
469 } |
448 } |
470 |
449 |
471 TileLoopClearHelper(tile); |
450 TileLoopClearHelper(tile); |
472 |
451 |
473 /* increase counter */ |
452 if (GetTreeCounter(tile) < 15) { |
474 AB(_m[tile].m2, 0, 4, 1); |
453 AddTreeCounter(tile, 1); |
475 if (GB(_m[tile].m2, 0, 4) != 0) return; |
454 return; |
476 |
455 } |
477 m5 = _m[tile].m5; |
456 SetTreeCounter(tile, 0); |
478 if (GB(m5, 0, 3) == 3) { |
457 |
479 /* regular sized tree */ |
458 switch (GetTreeGrowth(tile)) { |
480 if (_opt.landscape == LT_DESERT && _m[tile].m3 != 0x1B && GetMapExtraBits(tile) == 1) { |
459 case 3: /* regular sized tree */ |
481 m5++; /* start destructing */ |
460 if (_opt.landscape == LT_DESERT && GetTreeType(tile) != TR_CACTUS && GetMapExtraBits(tile) == 1) { |
482 } else { |
461 AddTreeGrowth(tile, 1); |
483 switch (GB(Random(), 0, 3)) { |
462 } else { |
484 case 0: /* start destructing */ |
463 switch (GB(Random(), 0, 3)) { |
485 m5++; |
464 case 0: /* start destructing */ |
486 break; |
465 AddTreeGrowth(tile, 1); |
487 |
466 break; |
488 case 1: /* add a tree */ |
467 |
489 if (m5 < 0xC0) { |
468 case 1: /* add a tree */ |
490 m5 = (m5 + 0x40) & ~7; |
469 if (GetTreeCount(tile) < 3) { |
491 break; |
470 AddTreeCount(tile, 1); |
|
471 SetTreeGrowth(tile, 0); |
|
472 break; |
|
473 } |
|
474 /* FALL THROUGH */ |
|
475 |
|
476 case 2: { /* add a neighbouring tree */ |
|
477 TreeType treetype = GetTreeType(tile); |
|
478 |
|
479 tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]); |
|
480 |
|
481 if (!IsTileType(tile, MP_CLEAR)) return; |
|
482 |
|
483 switch (GetClearGround(tile)) { |
|
484 case CL_GRASS: |
|
485 if (GetClearDensity(tile) != 3) return; |
|
486 SetTreeGroundDensity(tile, TR_GRASS, 0); |
|
487 break; |
|
488 |
|
489 case CL_ROUGH: SetTreeGroundDensity(tile, TR_ROUGH, 0); break; |
|
490 case CL_SNOW: SetTreeGroundDensity(tile, TR_SNOW_DESERT, GetClearDensity(tile)); break; |
|
491 default: return; |
|
492 } |
|
493 SetTreeCounter(tile, 0); |
|
494 |
|
495 SetTileType(tile, MP_TREES); |
|
496 SetTreeType(tile, treetype); |
|
497 SetFenceSE(tile, 0); |
|
498 SetFenceSW(tile, 0); |
|
499 SetTreeCount(tile, 0); |
|
500 SetTreeGrowth(tile, 0); |
|
501 break; |
|
502 } |
|
503 |
|
504 default: |
|
505 return; |
492 } |
506 } |
493 /* fall through */ |
507 } |
494 |
508 break; |
495 case 2: { /* add a neighbouring tree */ |
509 |
496 byte m3 = _m[tile].m3; |
510 case 6: /* final stage of tree destruction */ |
497 |
511 if (GetTreeCount(tile) > 0) { |
498 tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]); |
512 /* more than one tree, delete it */ |
499 |
513 AddTreeCount(tile, -1); |
500 if (!IsTileType(tile, MP_CLEAR)) return; |
514 SetTreeGrowth(tile, 3); |
501 |
515 } else { |
502 switch (GetClearGround(tile)) { |
516 /* just one tree, change type into MP_CLEAR */ |
503 case CL_GRASS: |
517 SetTileType(tile, MP_CLEAR); |
504 if (GetClearDensity(tile) != 3) return; |
518 SetTileOwner(tile, OWNER_NONE); |
505 _m[tile].m2 = 0; |
519 switch (GetTreeGround(tile)) { |
506 break; |
520 case TR_GRASS: SetClearGroundDensity(tile, CL_GRASS, 3); break; |
507 |
521 case TR_ROUGH: SetClearGroundDensity(tile, CL_ROUGH, 3); break; |
508 case CL_ROUGH: _m[tile].m2 = 0x10; break; |
522 default: SetClearGroundDensity(tile, CL_SNOW, GetTreeDensity(tile)); break; |
509 case CL_SNOW: _m[tile].m2 = GetClearDensity(tile) << 6 | 0x20; break; |
|
510 default: return; |
|
511 } |
523 } |
512 |
|
513 _m[tile].m3 = m3; |
|
514 _m[tile].m4 = 0; |
|
515 SetTileType(tile, MP_TREES); |
|
516 |
|
517 m5 = 0; |
|
518 break; |
|
519 } |
524 } |
520 |
525 break; |
521 default: |
526 |
522 return; |
527 default: |
523 } |
528 AddTreeGrowth(tile, 1); |
524 } |
529 break; |
525 } else if (GB(m5, 0, 3) == 6) { |
530 } |
526 /* final stage of tree destruction */ |
531 |
527 if (GB(m5, 6, 2) != 0) { |
|
528 /* more than one tree, delete it? */ |
|
529 m5 = ((m5 - 6) - 0x40) + 3; |
|
530 } else { |
|
531 /* just one tree, change type into MP_CLEAR */ |
|
532 SetTileType(tile, MP_CLEAR); |
|
533 SetTileOwner(tile, OWNER_NONE); |
|
534 switch (_m[tile].m2 & 0x30) { |
|
535 case 0x00: SetClearGroundDensity(tile, CL_GRASS, 3); break; |
|
536 case 0x10: SetClearGroundDensity(tile, CL_ROUGH, 3); break; |
|
537 default: SetClearGroundDensity(tile, CL_SNOW, GB(_m[tile].m2, 6, 2)); break; |
|
538 } |
|
539 MarkTileDirtyByTile(tile); |
|
540 return; |
|
541 } |
|
542 } else { |
|
543 /* in the middle of a transition, change to next */ |
|
544 m5++; |
|
545 } |
|
546 |
|
547 _m[tile].m5 = m5; |
|
548 MarkTileDirtyByTile(tile); |
532 MarkTileDirtyByTile(tile); |
549 } |
533 } |
550 |
534 |
551 void OnTick_Trees(void) |
535 void OnTick_Trees(void) |
552 { |
536 { |
558 /* place a tree at a random rainforest spot */ |
542 /* place a tree at a random rainforest spot */ |
559 if (_opt.landscape == LT_DESERT && |
543 if (_opt.landscape == LT_DESERT && |
560 (r = Random(), tile = RandomTileSeed(r), GetMapExtraBits(tile) == 2) && |
544 (r = Random(), tile = RandomTileSeed(r), GetMapExtraBits(tile) == 2) && |
561 IsTileType(tile, MP_CLEAR) && |
545 IsTileType(tile, MP_CLEAR) && |
562 (ct = GetClearGround(tile), ct == CL_GRASS || ct == CL_ROUGH) && |
546 (ct = GetClearGround(tile), ct == CL_GRASS || ct == CL_ROUGH) && |
563 (tree = GetRandomTreeType(tile, GB(r, 24, 8))) >= 0) { |
547 (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TR_INVALID) { |
564 |
548 SetTileType(tile, MP_TREES); |
565 ModifyTile(tile, |
549 SetTreeGroundDensity(tile, ct == CL_ROUGH ? TR_ROUGH : TR_GRASS, 0); |
566 MP_SETTYPE(MP_TREES) | |
550 SetTreeCounter(tile, 0); |
567 MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, |
551 SetTreeType(tile, tree); |
568 (ct == CL_ROUGH ? 0x10 : 0), |
552 SetTreeCount(tile, 0); |
569 tree, |
553 SetTreeGrowth(tile, 0); |
570 _m[tile].m4 & ~3, |
|
571 0 |
|
572 ); |
|
573 } |
554 } |
574 |
555 |
575 // byte underflow |
556 // byte underflow |
576 if (--_trees_tick_ctr != 0) return; |
557 if (--_trees_tick_ctr != 0) return; |
577 |
558 |
578 /* place a tree at a random spot */ |
559 /* place a tree at a random spot */ |
579 r = Random(); |
560 r = Random(); |
580 tile = TILE_MASK(r); |
561 tile = TILE_MASK(r); |
581 if (IsTileType(tile, MP_CLEAR) && |
562 if (IsTileType(tile, MP_CLEAR) && |
582 (ct = GetClearGround(tile), ct == CL_GRASS || ct == CL_ROUGH || ct == CL_SNOW) && |
563 (ct = GetClearGround(tile), ct == CL_GRASS || ct == CL_ROUGH || ct == CL_SNOW) && |
583 (tree = GetRandomTreeType(tile, GB(r, 24, 8))) >= 0) { |
564 (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TR_INVALID) { |
584 int m2; |
|
585 |
|
586 switch (ct) { |
565 switch (ct) { |
587 case CL_GRASS: m2 = 0; break; |
566 case CL_GRASS: SetTreeGroundDensity(tile, TR_GRASS, 0); break; |
588 case CL_ROUGH: m2 = 0x10; break; |
567 case CL_ROUGH: SetTreeGroundDensity(tile, TR_ROUGH, 0); break; |
589 default: m2 = (GetClearDensity(tile) << 6) | 0x20; break; |
568 default: SetTreeGroundDensity(tile, TR_SNOW_DESERT, GetClearDensity(tile)); break; |
590 } |
569 } |
591 |
570 SetTreeCounter(tile, 0); |
592 ModifyTile(tile, |
571 SetTileType(tile, MP_TREES); |
593 MP_SETTYPE(MP_TREES) | |
572 SetTreeType(tile, tree); |
594 MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, |
573 SetTreeCount(tile, 0); |
595 m2, |
574 SetTreeGrowth(tile, 0); |
596 tree, |
|
597 _m[tile].m4 & ~3, |
|
598 0 |
|
599 ); |
|
600 } |
575 } |
601 } |
576 } |
602 |
577 |
603 static void ClickTile_Trees(TileIndex tile) |
578 static void ClickTile_Trees(TileIndex tile) |
604 { |
579 { |