411 } |
412 } |
412 |
413 |
413 |
414 |
414 static int32 ClearTile_Clear(TileIndex tile, byte flags) |
415 static int32 ClearTile_Clear(TileIndex tile, byte flags) |
415 { |
416 { |
416 static const int32 null = 0; |
|
417 static const int32* clear_price_table[] = { |
417 static const int32* clear_price_table[] = { |
418 &null, |
|
419 &_price.clear_1, |
|
420 &_price.clear_1, |
|
421 &_price.clear_1, |
418 &_price.clear_1, |
422 &_price.purchase_land, |
419 &_price.purchase_land, |
423 &_price.purchase_land, |
|
424 &_price.purchase_land, |
|
425 &_price.purchase_land, |
|
426 &_price.clear_2, |
420 &_price.clear_2, |
427 &_price.clear_2, |
|
428 &_price.clear_2, |
|
429 &_price.clear_2, |
|
430 &_price.clear_3, |
|
431 &_price.clear_3, |
|
432 &_price.clear_3, |
|
433 &_price.clear_3, |
421 &_price.clear_3, |
434 &_price.purchase_land, |
422 &_price.purchase_land, |
435 &_price.purchase_land, |
423 &_price.purchase_land, |
436 &_price.purchase_land, |
424 &_price.clear_2, // XXX unused? |
437 &_price.purchase_land, |
|
438 &_price.purchase_land, |
|
439 &_price.purchase_land, |
|
440 &_price.purchase_land, |
|
441 &_price.purchase_land, |
|
442 &_price.clear_2, |
|
443 &_price.clear_2, |
|
444 &_price.clear_2, |
|
445 &_price.clear_2, |
|
446 }; |
425 }; |
447 const int32 *price = clear_price_table[GB(_m[tile].m5, 0, 5)]; |
426 int32 price; |
|
427 |
|
428 if (IsClearGround(tile, CL_GRASS) && GetClearDensity(tile) == 0) { |
|
429 price = 0; |
|
430 } else { |
|
431 price = *clear_price_table[GetClearGround(tile)]; |
|
432 } |
448 |
433 |
449 if (flags & DC_EXEC) DoClearSquare(tile); |
434 if (flags & DC_EXEC) DoClearSquare(tile); |
450 |
435 |
451 return *price; |
436 return price; |
452 } |
437 } |
453 |
438 |
454 /** Sell a land area. Actually you only sell one tile, so |
439 /** Sell a land area. Actually you only sell one tile, so |
455 * the name is a bit confusing ;p |
440 * the name is a bit confusing ;p |
456 * @param x,y the tile the player is selling |
441 * @param x,y the tile the player is selling |
515 } |
500 } |
516 |
501 |
517 static void DrawTile_Clear(TileInfo *ti) |
502 static void DrawTile_Clear(TileInfo *ti) |
518 { |
503 { |
519 switch (GB(ti->map5, 2, 3)) { |
504 switch (GB(ti->map5, 2, 3)) { |
520 case 0: |
505 case CL_GRASS: |
521 DrawClearLandTile(ti, GB(ti->map5, 0, 2)); |
506 DrawClearLandTile(ti, GB(ti->map5, 0, 2)); |
522 break; |
507 break; |
523 |
508 |
524 case 1: |
509 case CL_ROUGH: |
525 DrawHillyLandTile(ti); |
510 DrawHillyLandTile(ti); |
526 break; |
511 break; |
527 |
512 |
528 case 2: |
513 case CL_ROCKS: |
529 DrawGroundSprite(SPR_FLAT_ROCKY_LAND_1 + _tileh_to_sprite[ti->tileh]); |
514 DrawGroundSprite(SPR_FLAT_ROCKY_LAND_1 + _tileh_to_sprite[ti->tileh]); |
530 break; |
515 break; |
531 |
516 |
532 case 3: |
517 case CL_FIELDS: |
533 DrawGroundSprite(_clear_land_sprites_1[GB(_m[ti->tile].m3, 0, 4)] + _tileh_to_sprite[ti->tileh]); |
518 DrawGroundSprite(_clear_land_sprites_1[GB(_m[ti->tile].m3, 0, 4)] + _tileh_to_sprite[ti->tileh]); |
534 break; |
519 break; |
535 |
520 |
536 case 4: |
521 case CL_SNOW: |
537 DrawGroundSprite(_clear_land_sprites_2[GB(ti->map5, 0, 2)] + _tileh_to_sprite[ti->tileh]); |
522 DrawGroundSprite(_clear_land_sprites_2[GB(ti->map5, 0, 2)] + _tileh_to_sprite[ti->tileh]); |
538 break; |
523 break; |
539 |
524 |
540 case 5: |
525 case CL_DESERT: |
541 DrawGroundSprite(_clear_land_sprites_3[GB(ti->map5, 0, 2)] + _tileh_to_sprite[ti->tileh]); |
526 DrawGroundSprite(_clear_land_sprites_3[GB(ti->map5, 0, 2)] + _tileh_to_sprite[ti->tileh]); |
542 break; |
527 break; |
543 } |
528 } |
544 |
529 |
545 DrawClearLandFence(ti); |
530 DrawClearLandFence(ti); |
546 } |
531 } |
547 |
532 |
569 { |
554 { |
570 byte self; |
555 byte self; |
571 byte neighbour; |
556 byte neighbour; |
572 TileIndex dirty = INVALID_TILE; |
557 TileIndex dirty = INVALID_TILE; |
573 |
558 |
574 switch (GetTileType(tile)) { |
559 self = (IsTileType(tile, MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 1, 0), CL_FIELDS)); |
575 case MP_CLEAR: |
560 |
576 self = (GB(_m[tile].m5, 0, 5) == 15); |
561 neighbour = (IsTileType(TILE_ADDXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 1, 0), CL_FIELDS)); |
577 break; |
|
578 |
|
579 default: |
|
580 self = 0; |
|
581 break; |
|
582 } |
|
583 |
|
584 switch (GetTileType(TILE_ADDXY(tile, 1, 0))) { |
|
585 case MP_CLEAR: |
|
586 neighbour = (GB(_m[TILE_ADDXY(tile, 1, 0)].m5, 0, 5) == 15); |
|
587 break; |
|
588 |
|
589 default: |
|
590 neighbour = 0; |
|
591 break; |
|
592 } |
|
593 |
|
594 if (GB(_m[tile].m4, 5, 3) == 0) { |
562 if (GB(_m[tile].m4, 5, 3) == 0) { |
595 if (self != neighbour) { |
563 if (self != neighbour) { |
596 SB(_m[tile].m4, 5, 3, 3); |
564 SB(_m[tile].m4, 5, 3, 3); |
597 dirty = tile; |
565 dirty = tile; |
598 } |
566 } |
601 SB(_m[tile].m4, 5, 3, 0); |
569 SB(_m[tile].m4, 5, 3, 0); |
602 dirty = tile; |
570 dirty = tile; |
603 } |
571 } |
604 } |
572 } |
605 |
573 |
606 switch (GetTileType(TILE_ADDXY(tile, 0, 1))) { |
574 neighbour = (IsTileType(TILE_ADDXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, 1), CL_FIELDS)); |
607 case MP_CLEAR: |
|
608 neighbour = (GB(_m[TILE_ADDXY(tile, 0, 1)].m5, 0, 5) == 15); |
|
609 break; |
|
610 |
|
611 default: |
|
612 neighbour = 0; |
|
613 break; |
|
614 } |
|
615 |
|
616 if (GB(_m[tile].m4, 2, 3) == 0) { |
575 if (GB(_m[tile].m4, 2, 3) == 0) { |
617 if (self != neighbour) { |
576 if (self != neighbour) { |
618 SB(_m[tile].m4, 2, 3, 3); |
577 SB(_m[tile].m4, 2, 3, 3); |
619 dirty = tile; |
578 dirty = tile; |
620 } |
579 } |
630 |
589 |
631 |
590 |
632 /* convert into snowy tiles */ |
591 /* convert into snowy tiles */ |
633 static void TileLoopClearAlps(TileIndex tile) |
592 static void TileLoopClearAlps(TileIndex tile) |
634 { |
593 { |
635 int k; |
|
636 byte m5,tmp; |
|
637 |
|
638 /* distance from snow line, in steps of 8 */ |
594 /* distance from snow line, in steps of 8 */ |
639 k = GetTileZ(tile) - _opt.snow_line; |
595 int k = GetTileZ(tile) - _opt.snow_line; |
640 |
596 |
641 m5 = _m[tile].m5 & 0x1C; |
597 if (k < -8) { // well below the snow line |
642 tmp = _m[tile].m5 & 3; |
598 if (!IsClearGround(tile, CL_SNOW)) return; |
643 |
599 if (GetClearDensity(tile) == 0) SetClearGroundDensity(tile, CL_GRASS, 3); |
644 if (k < -8) { |
|
645 /* snow_m2_down */ |
|
646 if (m5 != 0x10) |
|
647 return; |
|
648 if (tmp == 0) |
|
649 m5 = 3; |
|
650 } else if (k == -8) { |
|
651 /* snow_m1 */ |
|
652 if (m5 != 0x10) { |
|
653 m5 = 0x10; |
|
654 } else if (tmp != 0) { |
|
655 m5 = (tmp - 1) + 0x10; |
|
656 } else |
|
657 return; |
|
658 } else if (k < 8) { |
|
659 /* snow_0 */ |
|
660 if (m5 != 0x10) { |
|
661 m5 = 0x10; |
|
662 } else if (tmp != 1) { |
|
663 m5 = 1; |
|
664 if (tmp != 0) |
|
665 m5 = tmp - 1; |
|
666 m5 += 0x10; |
|
667 } else |
|
668 return; |
|
669 } else if (k == 8) { |
|
670 /* snow_p1 */ |
|
671 if (m5 != 0x10) { |
|
672 m5 = 0x10; |
|
673 } else if (tmp != 2) { |
|
674 m5 = 2; |
|
675 if (tmp <= 2) |
|
676 m5 = tmp + 1; |
|
677 m5 += 0x10; |
|
678 } else |
|
679 return; |
|
680 } else { |
600 } else { |
681 /* snow_p2_up */ |
601 if (!IsClearGround(tile, CL_SNOW)) { |
682 if (m5 != 0x10) { |
602 SetClearGroundDensity(tile, CL_SNOW, 0); |
683 m5 = 0x10; |
603 } else { |
684 } else if (tmp != 3) { |
604 uint density = min((uint)(k + 8) / 8, 3); |
685 m5 = tmp + 1 + 0x10; |
605 |
686 } else |
606 if (GetClearDensity(tile) < density) { |
687 return; |
607 AddClearDensity(tile, 1); |
688 } |
608 } else if (GetClearDensity(tile) > density) { |
689 |
609 AddClearDensity(tile, -1); |
690 _m[tile].m5 = m5; |
610 } else { |
|
611 return; |
|
612 } |
|
613 } |
|
614 } |
|
615 |
691 MarkTileDirtyByTile(tile); |
616 MarkTileDirtyByTile(tile); |
692 } |
617 } |
693 |
618 |
694 static void TileLoopClearDesert(TileIndex tile) |
619 static void TileLoopClearDesert(TileIndex tile) |
695 { |
620 { |
696 if ((_m[tile].m5 & 0x1C) == 0x14) return; |
621 if (IsClearGround(tile, CL_DESERT)) return; |
697 |
622 |
698 if (GetMapExtraBits(tile) == 1) { |
623 if (GetMapExtraBits(tile) == 1) { |
699 _m[tile].m5 = 0x17; |
624 SetClearGroundDensity(tile, CL_DESERT, 3); |
700 } else { |
625 } else { |
701 if (GetMapExtraBits(tile + TileDiffXY( 1, 0)) != 1 && |
626 if (GetMapExtraBits(tile + TileDiffXY( 1, 0)) != 1 && |
702 GetMapExtraBits(tile + TileDiffXY(-1, 0)) != 1 && |
627 GetMapExtraBits(tile + TileDiffXY(-1, 0)) != 1 && |
703 GetMapExtraBits(tile + TileDiffXY( 0, 1)) != 1 && |
628 GetMapExtraBits(tile + TileDiffXY( 0, 1)) != 1 && |
704 GetMapExtraBits(tile + TileDiffXY( 0, -1)) != 1) |
629 GetMapExtraBits(tile + TileDiffXY( 0, -1)) != 1) |
705 return; |
630 return; |
706 _m[tile].m5 = 0x15; |
631 SetClearGroundDensity(tile, CL_DESERT, 1); |
707 } |
632 } |
708 |
633 |
709 MarkTileDirtyByTile(tile); |
634 MarkTileDirtyByTile(tile); |
710 } |
635 } |
711 |
636 |
712 static void TileLoop_Clear(TileIndex tile) |
637 static void TileLoop_Clear(TileIndex tile) |
713 { |
638 { |
714 byte m5,m3; |
|
715 |
|
716 TileLoopClearHelper(tile); |
639 TileLoopClearHelper(tile); |
717 |
640 |
718 if (_opt.landscape == LT_DESERT) { |
641 if (_opt.landscape == LT_DESERT) { |
719 TileLoopClearDesert(tile); |
642 TileLoopClearDesert(tile); |
720 } else if (_opt.landscape == LT_HILLY) { |
643 } else if (_opt.landscape == LT_HILLY) { |
721 TileLoopClearAlps(tile); |
644 TileLoopClearAlps(tile); |
722 } |
645 } |
723 |
646 |
724 m5 = _m[tile].m5; |
647 switch (GetClearGround(tile)) { |
725 if ((m5 & 0x1C) == 0x10 || (m5 & 0x1C) == 0x14) return; |
648 case CL_GRASS: |
726 |
649 if (GetClearDensity(tile) == 3) return; |
727 if ((m5 & 0x1C) != 0xC) { |
650 |
728 if ((m5 & 3) == 3) return; |
651 if (_game_mode != GM_EDITOR) { |
729 |
652 if (GetClearCounter(tile) < 7) { |
730 if (_game_mode != GM_EDITOR) { |
653 AddClearCounter(tile, 1); |
731 m5 += 0x20; |
654 return; |
732 if (m5 >= 0x20) { |
655 } else { |
733 // Didn't overflow |
656 SetClearCounter(tile, 0); |
734 _m[tile].m5 = m5; |
657 AddClearDensity(tile, 1); |
|
658 } |
|
659 } else { |
|
660 SetClearGroundDensity(tile, GB(Random(), 0, 8) > 21 ? CL_GRASS : CL_ROUGH, 3); |
|
661 } |
|
662 break; |
|
663 |
|
664 case CL_FIELDS: { |
|
665 uint field_type; |
|
666 |
|
667 if (_game_mode == GM_EDITOR) return; |
|
668 |
|
669 if (GetClearCounter(tile) < 7) { |
|
670 AddClearCounter(tile, 1); |
735 return; |
671 return; |
736 } |
672 } else { |
737 /* did overflow, so continue */ |
673 SetClearCounter(tile, 0); |
738 } else { |
674 } |
739 m5 = (GB(Random(), 0, 8) > 21) ? 2 : 6; |
675 |
740 } |
676 field_type = GB(_m[tile].m3, 0, 4); |
741 m5++; |
677 field_type = (field_type < 8) ? field_type + 1 : 0; |
742 } else if (_game_mode != GM_EDITOR) { |
678 SB(_m[tile].m3, 0, 4, field_type); |
743 /* handle farm field */ |
679 break; |
744 m5 += 0x20; |
680 } |
745 if (m5 >= 0x20) { |
681 |
746 // Didn't overflow |
682 default: |
747 _m[tile].m5 = m5; |
|
748 return; |
683 return; |
749 } |
684 } |
750 /* overflowed */ |
685 |
751 m3 = _m[tile].m3 + 1; |
|
752 assert( (m3 & 0xF) != 0); |
|
753 if ( (m3 & 0xF) >= 9) /* NOTE: will not work properly if m3&0xF == 0xF */ |
|
754 m3 &= ~0xF; |
|
755 _m[tile].m3 = m3; |
|
756 } |
|
757 |
|
758 _m[tile].m5 = m5; |
|
759 MarkTileDirtyByTile(tile); |
686 MarkTileDirtyByTile(tile); |
760 } |
687 } |
761 |
688 |
762 void GenerateClearTile(void) |
689 void GenerateClearTile(void) |
763 { |
690 { |
802 { |
729 { |
803 return 0; |
730 return 0; |
804 } |
731 } |
805 |
732 |
806 static const StringID _clear_land_str[] = { |
733 static const StringID _clear_land_str[] = { |
|
734 STR_080D_GRASS, |
807 STR_080B_ROUGH_LAND, |
735 STR_080B_ROUGH_LAND, |
808 STR_080A_ROCKS, |
736 STR_080A_ROCKS, |
809 STR_080E_FIELDS, |
737 STR_080E_FIELDS, |
810 STR_080F_SNOW_COVERED_LAND, |
738 STR_080F_SNOW_COVERED_LAND, |
811 STR_0810_DESERT, |
739 STR_0810_DESERT |
812 0, |
|
813 0, |
|
814 STR_080C_BARE_LAND, |
|
815 STR_080D_GRASS, |
|
816 STR_080D_GRASS, |
|
817 STR_080D_GRASS, |
|
818 }; |
740 }; |
819 |
741 |
820 static void GetTileDesc_Clear(TileIndex tile, TileDesc *td) |
742 static void GetTileDesc_Clear(TileIndex tile, TileDesc *td) |
821 { |
743 { |
822 uint i = GB(_m[tile].m5, 2, 3); |
744 if (IsClearGround(tile, CL_GRASS) && GetClearDensity(tile) == 0) { |
823 if (i == 0) i = GB(_m[tile].m5, 0, 2) + 8; |
745 td->str = STR_080C_BARE_LAND; |
824 td->str = _clear_land_str[i - 1]; |
746 } else { |
|
747 td->str = _clear_land_str[GetClearGround(tile)]; |
|
748 } |
825 td->owner = GetTileOwner(tile); |
749 td->owner = GetTileOwner(tile); |
826 } |
750 } |
827 |
751 |
828 static void ChangeTileOwner_Clear(TileIndex tile, PlayerID old_player, PlayerID new_player) |
752 static void ChangeTileOwner_Clear(TileIndex tile, PlayerID old_player, PlayerID new_player) |
829 { |
753 { |