equal
deleted
inserted
replaced
42 |
42 |
43 if (tree >= 0) { |
43 if (tree >= 0) { |
44 m5 = (byte)(r >> 16); |
44 m5 = (byte)(r >> 16); |
45 if ((m5 & 0x7) == 7) m5--; // there is no growth state 7 |
45 if ((m5 & 0x7) == 7) m5--; // there is no growth state 7 |
46 |
46 |
47 _map5[tile] = m5 & 0x07; // growth state; |
47 _m[tile].m5 = m5 & 0x07; // growth state; |
48 _map5[tile] |= m5 & 0xC0; // amount of trees |
48 _m[tile].m5 |= m5 & 0xC0; // amount of trees |
49 |
49 |
50 _map3_lo[tile] = tree; // set type of tree |
50 _m[tile].m3 = tree; // set type of tree |
51 _map3_hi[tile] = 0; // no hedge |
51 _m[tile].m4 = 0; // no hedge |
52 |
52 |
53 // above snowline? |
53 // above snowline? |
54 if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) { |
54 if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) { |
55 _map2[tile] = 0xE0; // set land type to snow |
55 _m[tile].m2 = 0xE0; // set land type to snow |
56 _map2[tile] |= (byte)(r >> 24)&0x07; // randomize counter |
56 _m[tile].m2 |= (byte)(r >> 24)&0x07; // randomize counter |
57 } |
57 } |
58 else |
58 else |
59 { |
59 { |
60 _map2[tile] = (byte)(r >> 24)&0x1F; // randomize counter and ground |
60 _m[tile].m2 = (byte)(r >> 24)&0x1F; // randomize counter and ground |
61 } |
61 } |
62 |
62 |
63 |
63 |
64 // make it tree class |
64 // make it tree class |
65 SetTileType(tile, MP_TREES); |
65 SetTileType(tile, MP_TREES); |
84 cur_tile = TILE_MASK(tile + TileDiffXY(x, y)); |
84 cur_tile = TILE_MASK(tile + TileDiffXY(x, y)); |
85 |
85 |
86 /* Only on tiles within 13 squares from tile, |
86 /* Only on tiles within 13 squares from tile, |
87 on clear tiles, and NOT on farm-tiles or rocks */ |
87 on clear tiles, and NOT on farm-tiles or rocks */ |
88 if (dist <= 13 && IsTileType(cur_tile, MP_CLEAR) && |
88 if (dist <= 13 && IsTileType(cur_tile, MP_CLEAR) && |
89 (_map5[cur_tile] & 0x1F) != 0x0F && (_map5[cur_tile] & 0x1C) != 8) { |
89 (_m[cur_tile].m5 & 0x1F) != 0x0F && (_m[cur_tile].m5 & 0x1C) != 8) { |
90 PlaceTree(cur_tile, r, dist <= 6 ? 0xC0 : 0); |
90 PlaceTree(cur_tile, r, dist <= 6 ? 0xC0 : 0); |
91 } |
91 } |
92 } while (--i); |
92 } while (--i); |
93 } |
93 } |
94 |
94 |
109 i = ScaleByMapSize(1000); |
109 i = ScaleByMapSize(1000); |
110 do { |
110 do { |
111 r = Random(); |
111 r = Random(); |
112 tile = TILE_MASK(r); |
112 tile = TILE_MASK(r); |
113 /* Only on clear tiles, and NOT on farm-tiles or rocks */ |
113 /* Only on clear tiles, and NOT on farm-tiles or rocks */ |
114 if (IsTileType(tile, MP_CLEAR) && (_map5[tile] & 0x1F) != 0x0F && (_map5[tile] & 0x1C) != 8) { |
114 if (IsTileType(tile, MP_CLEAR) && (_m[tile].m5 & 0x1F) != 0x0F && (_m[tile].m5 & 0x1C) != 8) { |
115 PlaceTree(tile, r, 0); |
115 PlaceTree(tile, r, 0); |
116 } |
116 } |
117 } while (--i); |
117 } while (--i); |
118 |
118 |
119 /* place extra trees at rainforest area */ |
119 /* place extra trees at rainforest area */ |
186 _error_message = STR_2803_TREE_ALREADY_HERE; |
186 _error_message = STR_2803_TREE_ALREADY_HERE; |
187 continue; |
187 continue; |
188 } |
188 } |
189 |
189 |
190 if (flags & DC_EXEC) { |
190 if (flags & DC_EXEC) { |
191 _map5[ti.tile] = ti.map5 + 0x40; |
191 _m[ti.tile].m5 = ti.map5 + 0x40; |
192 MarkTileDirtyByTile(ti.tile); |
192 MarkTileDirtyByTile(ti.tile); |
193 } |
193 } |
194 // 2x as expensive to add more trees to an existing tile |
194 // 2x as expensive to add more trees to an existing tile |
195 cost += _price.build_trees * 2; |
195 cost += _price.build_trees * 2; |
196 break; |
196 break; |
272 const uint32 *s; |
272 const uint32 *s; |
273 const byte *d; |
273 const byte *d; |
274 byte z; |
274 byte z; |
275 TreeListEnt te[4]; |
275 TreeListEnt te[4]; |
276 |
276 |
277 m2 = _map2[ti->tile]; |
277 m2 = _m[ti->tile].m2; |
278 |
278 |
279 if ( (m2&0x30) == 0) { |
279 if ( (m2&0x30) == 0) { |
280 DrawClearLandTile(ti, 3); |
280 DrawClearLandTile(ti, 3); |
281 } else if ((m2&0x30) == 0x20) { |
281 } else if ((m2&0x30) == 0x20) { |
282 DrawGroundSprite(_tree_sprites_1[m2 >> 6] + _tileh_to_sprite[ti->tileh]); |
282 DrawGroundSprite(_tree_sprites_1[m2 >> 6] + _tileh_to_sprite[ti->tileh]); |
283 } else { |
283 } else { |
284 DrawHillyLandTile(ti); |
284 DrawHillyLandTile(ti); |
285 } |
285 } |
286 |
286 |
287 DrawClearLandFence(ti, _map3_hi[ti->tile] >> 2); |
287 DrawClearLandFence(ti, _m[ti->tile].m4 >> 2); |
288 |
288 |
289 z = ti->z; |
289 z = ti->z; |
290 if (ti->tileh != 0) { |
290 if (ti->tileh != 0) { |
291 z += 4; |
291 z += 4; |
292 if (ti->tileh & 0x10) |
292 if (ti->tileh & 0x10) |
304 tmp = (tmp >> 1) | (tmp << 15); |
304 tmp = (tmp >> 1) | (tmp << 15); |
305 tmp += ti->y; |
305 tmp += ti->y; |
306 |
306 |
307 d = _tree_layout_xy[(tmp & 0x30) >> 4]; |
307 d = _tree_layout_xy[(tmp & 0x30) >> 4]; |
308 |
308 |
309 index = ((tmp>>6)&3) + (_map3_lo[ti->tile]<<2); |
309 index = ((tmp>>6)&3) + (_m[ti->tile].m3<<2); |
310 |
310 |
311 /* different tree styles above one of the grounds */ |
311 /* different tree styles above one of the grounds */ |
312 if ((m2 & 0xB0) == 0xA0 && index >= 48 && index < 80) |
312 if ((m2 & 0xB0) == 0xA0 && index >= 48 && index < 80) |
313 index += 164 - 48; |
313 index += 164 - 48; |
314 |
314 |
376 Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority); |
376 Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority); |
377 if (t != NULL) |
377 if (t != NULL) |
378 ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM); |
378 ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM); |
379 } |
379 } |
380 |
380 |
381 num = (_map5[tile] >> 6) + 1; |
381 num = (_m[tile].m5 >> 6) + 1; |
382 if ( (byte)(_map3_lo[tile]-0x14) <= (0x1A-0x14)) |
382 if ( (byte)(_m[tile].m3-0x14) <= (0x1A-0x14)) |
383 num <<= 2; |
383 num <<= 2; |
384 |
384 |
385 if (flags & DC_EXEC) |
385 if (flags & DC_EXEC) |
386 DoClearSquare(tile); |
386 DoClearSquare(tile); |
387 |
387 |
398 byte b; |
398 byte b; |
399 StringID str; |
399 StringID str; |
400 |
400 |
401 td->owner = GetTileOwner(tile); |
401 td->owner = GetTileOwner(tile); |
402 |
402 |
403 b = _map3_lo[tile]; |
403 b = _m[tile].m3; |
404 (str=STR_2810_CACTUS_PLANTS, b==0x1B) || |
404 (str=STR_2810_CACTUS_PLANTS, b==0x1B) || |
405 (str=STR_280F_RAINFOREST, IS_BYTE_INSIDE(b, 0x14, 0x1A+1)) || |
405 (str=STR_280F_RAINFOREST, IS_BYTE_INSIDE(b, 0x14, 0x1A+1)) || |
406 (str=STR_280E_TREES, true); |
406 (str=STR_280E_TREES, true); |
407 td->str = str; |
407 td->str = str; |
408 } |
408 } |
428 |
428 |
429 if (CHANCE16I(1,200,r=Random())) { |
429 if (CHANCE16I(1,200,r=Random())) { |
430 SndPlayTileFx(_desert_sounds[(r >> 16) & 3], tile); |
430 SndPlayTileFx(_desert_sounds[(r >> 16) & 3], tile); |
431 } |
431 } |
432 } else if (b == 1) { |
432 } else if (b == 1) { |
433 if ((_map2[tile] & 0x30) != 0x20) { |
433 if ((_m[tile].m2 & 0x30) != 0x20) { |
434 _map2[tile] &= 0xF; |
434 _m[tile].m2 &= 0xF; |
435 _map2[tile] |= 0xE0; |
435 _m[tile].m2 |= 0xE0; |
436 MarkTileDirtyByTile(tile); |
436 MarkTileDirtyByTile(tile); |
437 } |
437 } |
438 } |
438 } |
439 } |
439 } |
440 |
440 |
444 int k; |
444 int k; |
445 |
445 |
446 /* distance from snow line, in steps of 8 */ |
446 /* distance from snow line, in steps of 8 */ |
447 k = GetTileZ(tile) - _opt.snow_line; |
447 k = GetTileZ(tile) - _opt.snow_line; |
448 |
448 |
449 tmp = _map5[tile] & 0xF0; |
449 tmp = _m[tile].m5 & 0xF0; |
450 |
450 |
451 if (k < -8) { |
451 if (k < -8) { |
452 /* snow_m2_down */ |
452 /* snow_m2_down */ |
453 if ((tmp&0x30) != 0x20) |
453 if ((tmp&0x30) != 0x20) |
454 return; |
454 return; |
479 } else { |
479 } else { |
480 m2 = 0xE0; |
480 m2 = 0xE0; |
481 } |
481 } |
482 } |
482 } |
483 |
483 |
484 _map2[tile] &= 0xF; |
484 _m[tile].m2 &= 0xF; |
485 _map2[tile] |= m2; |
485 _m[tile].m2 |= m2; |
486 MarkTileDirtyByTile(tile); |
486 MarkTileDirtyByTile(tile); |
487 } |
487 } |
488 |
488 |
489 static void TileLoop_Trees(TileIndex tile) |
489 static void TileLoop_Trees(TileIndex tile) |
490 { |
490 { |
510 |
510 |
511 TileLoopClearHelper(tile); |
511 TileLoopClearHelper(tile); |
512 |
512 |
513 /* increase counter */ |
513 /* increase counter */ |
514 { |
514 { |
515 uint16 m2 = _map2[tile]; |
515 uint16 m2 = _m[tile].m2; |
516 _map2[tile] = m2 = (m2 & 0xF0) | ((m2+1)&0xF); |
516 _m[tile].m2 = m2 = (m2 & 0xF0) | ((m2+1)&0xF); |
517 if (m2 & 0xF) |
517 if (m2 & 0xF) |
518 return; |
518 return; |
519 } |
519 } |
520 |
520 |
521 m5 = _map5[tile]; |
521 m5 = _m[tile].m5; |
522 if ((m5&7) == 3) { |
522 if ((m5&7) == 3) { |
523 /* regular sized tree */ |
523 /* regular sized tree */ |
524 if (_opt.landscape == LT_DESERT && _map3_lo[tile]!=0x1B && GetMapExtraBits(tile)==1) { |
524 if (_opt.landscape == LT_DESERT && _m[tile].m3!=0x1B && GetMapExtraBits(tile)==1) { |
525 m5++; /* start destructing */ |
525 m5++; /* start destructing */ |
526 } else { |
526 } else { |
527 switch(Random() & 0x7) { |
527 switch(Random() & 0x7) { |
528 case 0: /* start destructing */ |
528 case 0: /* start destructing */ |
529 m5++; |
529 m5++; |
535 break; |
535 break; |
536 } |
536 } |
537 /* fall through */ |
537 /* fall through */ |
538 |
538 |
539 case 2: { /* add a neighbouring tree */ |
539 case 2: { /* add a neighbouring tree */ |
540 byte m3 = _map3_lo[tile]; |
540 byte m3 = _m[tile].m3; |
541 |
541 |
542 tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]); |
542 tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]); |
543 |
543 |
544 if (!IsTileType(tile, MP_CLEAR)) |
544 if (!IsTileType(tile, MP_CLEAR)) |
545 return; |
545 return; |
546 |
546 |
547 if ( (_map5[tile] & 0x1C) == 4) { |
547 if ( (_m[tile].m5 & 0x1C) == 4) { |
548 _map2[tile] = 0x10; |
548 _m[tile].m2 = 0x10; |
549 } else if ((_map5[tile] & 0x1C) == 16) { |
549 } else if ((_m[tile].m5 & 0x1C) == 16) { |
550 _map2[tile] = ((_map5[tile] & 3) << 6) | 0x20; |
550 _m[tile].m2 = ((_m[tile].m5 & 3) << 6) | 0x20; |
551 } else { |
551 } else { |
552 if ((_map5[tile] & 0x1F) != 3) |
552 if ((_m[tile].m5 & 0x1F) != 3) |
553 return; |
553 return; |
554 _map2[tile] = 0; |
554 _m[tile].m2 = 0; |
555 } |
555 } |
556 |
556 |
557 _map3_lo[tile] = m3; |
557 _m[tile].m3 = m3; |
558 _map3_hi[tile] = 0; |
558 _m[tile].m4 = 0; |
559 SetTileType(tile, MP_TREES); |
559 SetTileType(tile, MP_TREES); |
560 |
560 |
561 m5 = 0; |
561 m5 = 0; |
562 break; |
562 break; |
563 } |
563 } |
574 } else { |
574 } else { |
575 /* just one tree, change type into MP_CLEAR */ |
575 /* just one tree, change type into MP_CLEAR */ |
576 SetTileType(tile, MP_CLEAR); |
576 SetTileType(tile, MP_CLEAR); |
577 |
577 |
578 m5 = 3; |
578 m5 = 3; |
579 m2 = _map2[tile]; |
579 m2 = _m[tile].m2; |
580 if ((m2&0x30) != 0) { // on snow/desert or rough land |
580 if ((m2&0x30) != 0) { // on snow/desert or rough land |
581 m5 = (m2 >> 6) | 0x10; |
581 m5 = (m2 >> 6) | 0x10; |
582 if ((m2&0x30) != 0x20) // if not on snow/desert, then on rough land |
582 if ((m2&0x30) != 0x20) // if not on snow/desert, then on rough land |
583 m5 = 7; |
583 m5 = 7; |
584 } |
584 } |
587 } else { |
587 } else { |
588 /* in the middle of a transition, change to next */ |
588 /* in the middle of a transition, change to next */ |
589 m5++; |
589 m5++; |
590 } |
590 } |
591 |
591 |
592 _map5[tile] = m5; |
592 _m[tile].m5 = m5; |
593 MarkTileDirtyByTile(tile); |
593 MarkTileDirtyByTile(tile); |
594 } |
594 } |
595 |
595 |
596 void OnTick_Trees(void) |
596 void OnTick_Trees(void) |
597 { |
597 { |
602 |
602 |
603 /* place a tree at a random rainforest spot */ |
603 /* place a tree at a random rainforest spot */ |
604 if (_opt.landscape == LT_DESERT && |
604 if (_opt.landscape == LT_DESERT && |
605 (r=Random(),tile=TILE_MASK(r),GetMapExtraBits(tile)==2) && |
605 (r=Random(),tile=TILE_MASK(r),GetMapExtraBits(tile)==2) && |
606 IsTileType(tile, MP_CLEAR) && |
606 IsTileType(tile, MP_CLEAR) && |
607 (m=_map5[tile]&0x1C, m<=4) && |
607 (m=_m[tile].m5&0x1C, m<=4) && |
608 (tree=GetRandomTreeType(tile, r>>24)) >= 0) { |
608 (tree=GetRandomTreeType(tile, r>>24)) >= 0) { |
609 |
609 |
610 ModifyTile(tile, |
610 ModifyTile(tile, |
611 MP_SETTYPE(MP_TREES) | |
611 MP_SETTYPE(MP_TREES) | |
612 MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, |
612 MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, |
613 (m == 4 ? 0x10 : 0), |
613 (m == 4 ? 0x10 : 0), |
614 tree, |
614 tree, |
615 _map3_hi[tile] & ~3, |
615 _m[tile].m4 & ~3, |
616 0 |
616 0 |
617 ); |
617 ); |
618 } |
618 } |
619 |
619 |
620 // byte underflow |
620 // byte underflow |
623 |
623 |
624 /* place a tree at a random spot */ |
624 /* place a tree at a random spot */ |
625 r = Random(); |
625 r = Random(); |
626 tile = TILE_MASK(r); |
626 tile = TILE_MASK(r); |
627 if (IsTileType(tile, MP_CLEAR) && |
627 if (IsTileType(tile, MP_CLEAR) && |
628 (m=_map5[tile]&0x1C, m==0 || m==4 || m==0x10) && |
628 (m=_m[tile].m5&0x1C, m==0 || m==4 || m==0x10) && |
629 (tree=GetRandomTreeType(tile, r>>24)) >= 0) { |
629 (tree=GetRandomTreeType(tile, r>>24)) >= 0) { |
630 int m2; |
630 int m2; |
631 |
631 |
632 if (m == 0) { |
632 if (m == 0) { |
633 m2 = 0; |
633 m2 = 0; |
634 } else if (m == 4) { |
634 } else if (m == 4) { |
635 m2 = 0x10; |
635 m2 = 0x10; |
636 } else { |
636 } else { |
637 m2 = ((_map5[tile] & 3) << 6) | 0x20; |
637 m2 = ((_m[tile].m5 & 3) << 6) | 0x20; |
638 } |
638 } |
639 |
639 |
640 ModifyTile(tile, |
640 ModifyTile(tile, |
641 MP_SETTYPE(MP_TREES) | |
641 MP_SETTYPE(MP_TREES) | |
642 MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, |
642 MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, |
643 m2, |
643 m2, |
644 tree, |
644 tree, |
645 _map3_hi[tile] & ~3, |
645 _m[tile].m4 & ~3, |
646 0 |
646 0 |
647 ); |
647 ); |
648 } |
648 } |
649 } |
649 } |
650 |
650 |