196 return; |
196 return; |
197 } |
197 } |
198 |
198 |
199 if (_tick_counter & 3) return; |
199 if (_tick_counter & 3) return; |
200 |
200 |
201 // If the house is not one with a lift anymore, then stop this animating. |
201 /* If the house is not one with a lift anymore, then stop this animating. |
202 // Not exactly sure when this happens, but probably when a house changes. |
202 * Not exactly sure when this happens, but probably when a house changes. |
203 // Before this was just a return...so it'd leak animated tiles.. |
203 * Before this was just a return...so it'd leak animated tiles.. |
204 // That bug seems to have been here since day 1?? |
204 * That bug seems to have been here since day 1?? */ |
205 if (!(GetHouseSpecs(GetHouseType(tile))->building_flags & BUILDING_IS_ANIMATED)) { |
205 if (!(GetHouseSpecs(GetHouseType(tile))->building_flags & BUILDING_IS_ANIMATED)) { |
206 DeleteAnimatedTile(tile); |
206 DeleteAnimatedTile(tile); |
207 return; |
207 return; |
208 } |
208 } |
209 |
209 |
210 if (!LiftHasDestination(tile)) { |
210 if (!LiftHasDestination(tile)) { |
211 int i; |
211 int i; |
212 |
212 |
213 /** Building has 6 floors, number 0 .. 6, where 1 is illegal. |
213 /* Building has 6 floors, number 0 .. 6, where 1 is illegal. |
214 * This is due to the fact that the first floor is, in the graphics, |
214 * This is due to the fact that the first floor is, in the graphics, |
215 * the height of 2 'normal' floors. |
215 * the height of 2 'normal' floors. |
216 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */ |
216 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */ |
217 do { |
217 do { |
218 i = (Random() & 7) - 1; |
218 i = (Random() & 7) - 1; |
508 static bool IsRoadAllowedHere(TileIndex tile, int dir) |
508 static bool IsRoadAllowedHere(TileIndex tile, int dir) |
509 { |
509 { |
510 Slope k; |
510 Slope k; |
511 Slope slope; |
511 Slope slope; |
512 |
512 |
513 // If this assertion fails, it might be because the world contains |
513 /* If this assertion fails, it might be because the world contains |
514 // land at the edges. This is not ok. |
514 * land at the edges. This is not ok. */ |
515 TILE_ASSERT(tile); |
515 TILE_ASSERT(tile); |
516 |
516 |
517 for (;;) { |
517 for (;;) { |
518 // Check if there already is a road at this point? |
518 /* Check if there already is a road at this point? */ |
519 if (GetAnyRoadTrackBits(tile) == 0) { |
519 if (GetAnyRoadTrackBits(tile) == 0) { |
520 // No, try to build one in the direction. |
520 /* No, try to build one in the direction. |
521 // if that fails clear the land, and if that fails exit. |
521 * if that fails clear the land, and if that fails exit. |
522 // This is to make sure that we can build a road here later. |
522 * This is to make sure that we can build a road here later. */ |
523 if (CmdFailed(DoCommand(tile, (dir & 1 ? ROAD_X : ROAD_Y), 0, DC_AUTO, CMD_BUILD_ROAD)) && |
523 if (CmdFailed(DoCommand(tile, (dir & 1 ? ROAD_X : ROAD_Y), 0, DC_AUTO, CMD_BUILD_ROAD)) && |
524 CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) |
524 CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) |
525 return false; |
525 return false; |
526 } |
526 } |
527 |
527 |
528 slope = GetTileSlope(tile, NULL); |
528 slope = GetTileSlope(tile, NULL); |
529 if (slope == SLOPE_FLAT) { |
529 if (slope == SLOPE_FLAT) { |
530 no_slope: |
530 no_slope: |
531 // Tile has no slope |
531 /* Tile has no slope |
532 // Disallow the road if any neighboring tile has a road. |
532 * Disallow the road if any neighboring tile has a road. */ |
533 if (HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+1]))), dir^2) || |
533 if (HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+1]))), dir^2) || |
534 HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+3]))), dir^2) || |
534 HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+3]))), dir^2) || |
535 HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+1]) + ToTileIndexDiff(_roadblock_tileadd[dir+2]))), dir) || |
535 HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+1]) + ToTileIndexDiff(_roadblock_tileadd[dir+2]))), dir) || |
536 HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+3]) + ToTileIndexDiff(_roadblock_tileadd[dir+2]))), dir)) |
536 HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+3]) + ToTileIndexDiff(_roadblock_tileadd[dir+2]))), dir)) |
537 return false; |
537 return false; |
538 |
538 |
539 // Otherwise allow |
539 /* Otherwise allow */ |
540 return true; |
540 return true; |
541 } |
541 } |
542 |
542 |
543 // If the tile is not a slope in the right direction, then |
543 /* If the tile is not a slope in the right direction, then |
544 // maybe terraform some. |
544 * maybe terraform some. */ |
545 k = (dir & 1) ? SLOPE_NE : SLOPE_NW; |
545 k = (dir & 1) ? SLOPE_NE : SLOPE_NW; |
546 if (k != slope && ComplementSlope(k) != slope) { |
546 if (k != slope && ComplementSlope(k) != slope) { |
547 uint32 r = Random(); |
547 uint32 r = Random(); |
548 |
548 |
549 if (CHANCE16I(1, 8, r) && !_generating_world) { |
549 if (CHANCE16I(1, 8, r) && !_generating_world) { |
608 |
608 |
609 if (mask == 0) { |
609 if (mask == 0) { |
610 int a; |
610 int a; |
611 int b; |
611 int b; |
612 |
612 |
613 // Tile has no road. First reset the status counter |
613 /* Tile has no road. First reset the status counter |
614 // to say that this is the last iteration. |
614 * to say that this is the last iteration. */ |
615 _grow_town_result = 0; |
615 _grow_town_result = 0; |
616 |
616 |
617 // Remove hills etc |
617 /* Remove hills etc */ |
618 LevelTownLand(tile); |
618 LevelTownLand(tile); |
619 |
619 |
620 // Is a road allowed here? |
620 /* Is a road allowed here? */ |
621 if (!IsRoadAllowedHere(tile, block)) return; |
621 if (!IsRoadAllowedHere(tile, block)) return; |
622 |
622 |
623 // Randomize new road block numbers |
623 /* Randomize new road block numbers */ |
624 a = block; |
624 a = block; |
625 b = block ^ 2; |
625 b = block ^ 2; |
626 if (CHANCE16(1, 4)) { |
626 if (CHANCE16(1, 4)) { |
627 do { |
627 do { |
628 a = GB(Random(), 0, 2); |
628 a = GB(Random(), 0, 2); |
629 } while (a == b); |
629 } while (a == b); |
630 } |
630 } |
631 |
631 |
632 if (!IsRoadAllowedHere(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a])), a)) { |
632 if (!IsRoadAllowedHere(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a])), a)) { |
633 // A road is not allowed to continue the randomized road, |
633 /* A road is not allowed to continue the randomized road, |
634 // return if the road we're trying to build is curved. |
634 * return if the road we're trying to build is curved. */ |
635 if (a != (b ^ 2)) return; |
635 if (a != (b ^ 2)) return; |
636 |
636 |
637 // Return if neither side of the new road is a house |
637 /* Return if neither side of the new road is a house */ |
638 if (!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 1])), MP_HOUSE) && |
638 if (!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 1])), MP_HOUSE) && |
639 !IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 3])), MP_HOUSE)) |
639 !IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 3])), MP_HOUSE)) |
640 return; |
640 return; |
641 |
641 |
642 // That means that the road is only allowed if there is a house |
642 /* That means that the road is only allowed if there is a house |
643 // at any side of the new road. |
643 * at any side of the new road. */ |
644 } |
644 } |
645 rcmd = (RoadBits)((1 << a) + (1 << b)); |
645 rcmd = (RoadBits)((1 << a) + (1 << b)); |
646 |
646 |
647 } else if (block < 5 && !HASBIT(mask,block^2)) { |
647 } else if (block < 5 && !HASBIT(mask,block^2)) { |
648 // Continue building on a partial road. |
648 /* Continue building on a partial road. |
649 // Always OK. |
649 * Always OK. */ |
650 _grow_town_result = 0; |
650 _grow_town_result = 0; |
651 rcmd = (RoadBits)(1 << (block ^ 2)); |
651 rcmd = (RoadBits)(1 << (block ^ 2)); |
652 } else { |
652 } else { |
653 int i; |
653 int i; |
654 |
654 |
655 // Reached a tunnel/bridge? Then continue at the other side of it. |
655 /* Reached a tunnel/bridge? Then continue at the other side of it. */ |
656 if (IsTileType(tile, MP_TUNNELBRIDGE)) { |
656 if (IsTileType(tile, MP_TUNNELBRIDGE)) { |
657 if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) { |
657 if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) { |
658 *tile_ptr = GetOtherTunnelEnd(tile); |
658 *tile_ptr = GetOtherTunnelEnd(tile); |
659 } else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_ROAD) { |
659 } else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_ROAD) { |
660 *tile_ptr = GetOtherBridgeEnd(tile); |
660 *tile_ptr = GetOtherBridgeEnd(tile); |
661 } |
661 } |
662 return; |
662 return; |
663 } |
663 } |
664 |
664 |
665 // Possibly extend the road in a direction. |
665 /* Possibly extend the road in a direction. |
666 // Randomize a direction and if it has a road, bail out. |
666 * Randomize a direction and if it has a road, bail out. */ |
667 i = GB(Random(), 0, 2); |
667 i = GB(Random(), 0, 2); |
668 if (HASBIT(mask, i)) return; |
668 if (HASBIT(mask, i)) return; |
669 |
669 |
670 // This is the tile we will reach if we extend to this direction. |
670 /* This is the tile we will reach if we extend to this direction. */ |
671 tmptile = TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[i])); |
671 tmptile = TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[i])); |
672 |
672 |
673 // Don't do it if it reaches to water. |
673 /* Don't do it if it reaches to water. */ |
674 if (IsClearWaterTile(tmptile)) return; |
674 if (IsClearWaterTile(tmptile)) return; |
675 |
675 |
676 // Build a house at the edge. 60% chance or |
676 /* Build a house at the edge. 60% chance or |
677 // always ok if no road allowed. |
677 * always ok if no road allowed. */ |
678 if (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6, 10)) { |
678 if (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6, 10)) { |
679 // But not if there already is a house there. |
679 /* But not if there already is a house there. */ |
680 if (!IsTileType(tmptile, MP_HOUSE)) { |
680 if (!IsTileType(tmptile, MP_HOUSE)) { |
681 // Level the land if possible |
681 /* Level the land if possible */ |
682 LevelTownLand(tmptile); |
682 LevelTownLand(tmptile); |
683 |
683 |
684 // And build a house. |
684 /* And build a house. |
685 // Set result to -1 if we managed to build it. |
685 * Set result to -1 if we managed to build it. */ |
686 if (BuildTownHouse(t1, tmptile)) _grow_town_result = -1; |
686 if (BuildTownHouse(t1, tmptile)) _grow_town_result = -1; |
687 } |
687 } |
688 return; |
688 return; |
689 } |
689 } |
690 |
690 |
691 _grow_town_result = 0; |
691 _grow_town_result = 0; |
692 rcmd = (RoadBits)(1 << i); |
692 rcmd = (RoadBits)(1 << i); |
693 } |
693 } |
694 |
694 |
695 // Return if a water tile |
695 /* Return if a water tile */ |
696 if (IsClearWaterTile(tile)) return; |
696 if (IsClearWaterTile(tile)) return; |
697 |
697 |
698 // Determine direction of slope, |
698 /* Determine direction of slope, |
699 // and build a road if not a special slope. |
699 * and build a road if not a special slope. */ |
700 switch (GetTileSlope(tile, NULL)) { |
700 switch (GetTileSlope(tile, NULL)) { |
701 case SLOPE_SW: i = DIAGDIR_NE; break; |
701 case SLOPE_SW: i = DIAGDIR_NE; break; |
702 case SLOPE_SE: i = DIAGDIR_NW; break; |
702 case SLOPE_SE: i = DIAGDIR_NW; break; |
703 case SLOPE_NW: i = DIAGDIR_SE; break; |
703 case SLOPE_NW: i = DIAGDIR_SE; break; |
704 case SLOPE_NE: i = DIAGDIR_SW; break; |
704 case SLOPE_NE: i = DIAGDIR_SW; break; |
711 return; |
711 return; |
712 } |
712 } |
713 |
713 |
714 tmptile = tile; |
714 tmptile = tile; |
715 |
715 |
716 // Now it contains the direction of the slope |
716 /* Now it contains the direction of the slope */ |
717 j = -11; // max 11 tile long bridges |
717 j = -11; // max 11 tile long bridges |
718 do { |
718 do { |
719 if (++j == 0) |
719 if (++j == 0) |
720 goto build_road_and_exit; |
720 goto build_road_and_exit; |
721 tmptile = TILE_MASK(tmptile + TileOffsByDiagDir(i)); |
721 tmptile = TILE_MASK(tmptile + TileOffsByDiagDir(i)); |
722 } while (IsClearWaterTile(tmptile)); |
722 } while (IsClearWaterTile(tmptile)); |
723 |
723 |
724 // no water tiles in between? |
724 /* no water tiles in between? */ |
725 if (j == -10) |
725 if (j == -10) |
726 goto build_road_and_exit; |
726 goto build_road_and_exit; |
727 |
727 |
728 // Quit if it selecting an appropiate bridge type fails a large number of times. |
728 /* Quit if it selecting an appropiate bridge type fails a large number of times. */ |
729 j = 22; |
729 j = 22; |
730 { |
730 { |
731 int32 bridge_len = GetBridgeLength(tile, tmptile); |
731 int32 bridge_len = GetBridgeLength(tile, tmptile); |
732 do { |
732 do { |
733 byte bridge_type = RandomRange(MAX_BRIDGES - 1); |
733 byte bridge_type = RandomRange(MAX_BRIDGES - 1); |
734 if (CheckBridge_Stuff(bridge_type, bridge_len)) { |
734 if (CheckBridge_Stuff(bridge_type, bridge_len)) { |
735 if (!CmdFailed(DoCommand(tile, tmptile, 0x8000 + bridge_type, DC_EXEC | DC_AUTO, CMD_BUILD_BRIDGE))) |
735 if (!CmdFailed(DoCommand(tile, tmptile, 0x8000 + bridge_type, DC_EXEC | DC_AUTO, CMD_BUILD_BRIDGE))) |
736 _grow_town_result = -1; |
736 _grow_town_result = -1; |
737 |
737 |
738 // obviously, if building any bridge would fail, there is no need to try other bridge-types |
738 /* obviously, if building any bridge would fail, there is no need to try other bridge-types */ |
739 return; |
739 return; |
740 } |
740 } |
741 } while (--j != 0); |
741 } while (--j != 0); |
742 } |
742 } |
743 } |
743 } |
744 |
744 |
745 // Returns true if a house was built, or no if the build failed. |
745 /** Returns "growth" if a house was built, or no if the build failed. |
|
746 * @param t town to inquiry |
|
747 * @param tile to inquiry |
|
748 * @return something other than zero(0)if town expansion was possible |
|
749 */ |
746 static int GrowTownAtRoad(Town *t, TileIndex tile) |
750 static int GrowTownAtRoad(Town *t, TileIndex tile) |
747 { |
751 { |
748 int block = 5; // special case |
752 int block = 5; // special case |
749 |
753 |
750 TILE_ASSERT(tile); |
754 TILE_ASSERT(tile); |
751 |
755 |
752 // Number of times to search. |
756 /* Number of times to search. */ |
753 _grow_town_result = 10 + t->num_houses * 4 / 9; |
757 _grow_town_result = 10 + t->num_houses * 4 / 9; |
754 |
758 |
755 do { |
759 do { |
756 // Get a bitmask of the road blocks on a tile |
760 /* Get a bitmask of the road blocks on a tile */ |
757 RoadBits mask = GetTownRoadMask(tile); |
761 RoadBits mask = GetTownRoadMask(tile); |
758 |
762 |
759 // Try to grow the town from this point |
763 /* Try to grow the town from this point */ |
760 GrowTownInTile(&tile,mask,block,t); |
764 GrowTownInTile(&tile, mask, block, t); |
761 |
765 |
762 // Exclude the source position from the bitmask |
766 /* Exclude the source position from the bitmask |
763 // and return if no more road blocks available |
767 * and return if no more road blocks available */ |
764 ClrBitT(mask, (block ^ 2)); |
768 ClrBitT(mask, (block ^ 2)); |
765 if (mask == 0) |
769 if (mask == 0) |
766 return _grow_town_result; |
770 return _grow_town_result; |
767 |
771 |
768 // Select a random bit from the blockmask, walk a step |
772 /* Select a random bit from the blockmask, walk a step |
769 // and continue the search from there. |
773 * and continue the search from there. */ |
770 do block = Random() & 3; while (!HASBIT(mask,block)); |
774 do block = Random() & 3; while (!HASBIT(mask,block)); |
771 tile += ToTileIndexDiff(_roadblock_tileadd[block]); |
775 tile += ToTileIndexDiff(_roadblock_tileadd[block]); |
772 |
776 |
773 if (IsTileType(tile, MP_STREET)) { |
777 if (IsTileType(tile, MP_STREET)) { |
774 /* Don't allow building over roads of other cities */ |
778 /* Don't allow building over roads of other cities */ |
780 SetTileOwner(tile, OWNER_TOWN); |
784 SetTileOwner(tile, OWNER_TOWN); |
781 SetTownIndex(tile, t->index); |
785 SetTownIndex(tile, t->index); |
782 } |
786 } |
783 } |
787 } |
784 |
788 |
785 // Max number of times is checked. |
789 /* Max number of times is checked. */ |
786 } while (--_grow_town_result >= 0); |
790 } while (--_grow_town_result >= 0); |
787 |
791 |
788 return (_grow_town_result == -2); |
792 return (_grow_town_result == -2); |
789 } |
793 } |
790 |
794 |
791 // Generate a random road block |
795 /** Generate a random road block |
792 // The probability of a straight road |
796 * The probability of a straight road |
793 // is somewhat higher than a curved. |
797 * is somewhat higher than a curved. */ |
794 static RoadBits GenRandomRoadBits() |
798 static RoadBits GenRandomRoadBits() |
795 { |
799 { |
796 uint32 r = Random(); |
800 uint32 r = Random(); |
797 uint a = GB(r, 0, 2); |
801 uint a = GB(r, 0, 2); |
798 uint b = GB(r, 8, 2); |
802 uint b = GB(r, 8, 2); |
799 if (a == b) b ^= 2; |
803 if (a == b) b ^= 2; |
800 return (RoadBits)((1 << a) + (1 << b)); |
804 return (RoadBits)((1 << a) + (1 << b)); |
801 } |
805 } |
802 |
806 |
803 // Grow the town |
807 /** Grow the town |
804 // Returns true if a house was built, or no if the build failed. |
808 * @Return true if a house was built, or no if the build failed. */ |
805 static bool GrowTown(Town *t) |
809 static bool GrowTown(Town *t) |
806 { |
810 { |
807 TileIndex tile; |
811 TileIndex tile; |
808 const TileIndexDiffC *ptr; |
812 const TileIndexDiffC *ptr; |
809 PlayerID old_player; |
813 PlayerID old_player; |
822 { 2, 2}, |
826 { 2, 2}, |
823 { 2, -2}, |
827 { 2, -2}, |
824 { 0, 0} |
828 { 0, 0} |
825 }; |
829 }; |
826 |
830 |
827 // Current player is a town |
831 /* Current player is a town */ |
828 old_player = _current_player; |
832 old_player = _current_player; |
829 _current_player = OWNER_TOWN; |
833 _current_player = OWNER_TOWN; |
830 |
834 |
831 // Find a road that we can base the construction on. |
835 /* Find a road that we can base the construction on. */ |
832 tile = t->xy; |
836 tile = t->xy; |
833 for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { |
837 for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { |
834 if (GetAnyRoadTrackBits(tile) != 0) { |
838 if (GetAnyRoadTrackBits(tile) != 0) { |
835 int r = GrowTownAtRoad(t, tile); |
839 int r = GrowTownAtRoad(t, tile); |
836 _current_player = old_player; |
840 _current_player = old_player; |
837 return r != 0; |
841 return r != 0; |
838 } |
842 } |
839 tile = TILE_ADD(tile, ToTileIndexDiff(*ptr)); |
843 tile = TILE_ADD(tile, ToTileIndexDiff(*ptr)); |
840 } |
844 } |
841 |
845 |
842 // No road available, try to build a random road block by |
846 /* No road available, try to build a random road block by |
843 // clearing some land and then building a road there. |
847 * clearing some land and then building a road there. */ |
844 tile = t->xy; |
848 tile = t->xy; |
845 for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { |
849 for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { |
846 /* Only work with plain land that not already has a house */ |
850 /* Only work with plain land that not already has a house */ |
847 if (!IsTileType(tile, MP_HOUSE) && GetTileSlope(tile, NULL) == SLOPE_FLAT) { |
851 if (!IsTileType(tile, MP_HOUSE) && GetTileSlope(tile, NULL) == SLOPE_FLAT) { |
848 if (!CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) { |
852 if (!CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) { |
888 |
892 |
889 if (t->num_houses < 92) { |
893 if (t->num_houses < 92) { |
890 memcpy(t->radius, _town_radius_data[t->num_houses / 4], sizeof(t->radius)); |
894 memcpy(t->radius, _town_radius_data[t->num_houses / 4], sizeof(t->radius)); |
891 } else { |
895 } else { |
892 int mass = t->num_houses / 8; |
896 int mass = t->num_houses / 8; |
893 // At least very roughly extrapolate. Empirical numbers dancing between |
897 /* At least very roughly extrapolate. Empirical numbers dancing between |
894 // overwhelming by cottages and skyscrapers outskirts. |
898 * overwhelming by cottages and skyscrapers outskirts. */ |
895 t->radius[0] = mass * mass; |
899 t->radius[0] = mass * mass; |
896 // Actually we are proportional to sqrt() but that's right because |
900 /* Actually we are proportional to sqrt() but that's right because |
897 // we are covering an area. |
901 * we are covering an area. */ |
898 t->radius[1] = mass * 7; |
902 t->radius[1] = mass * 7; |
899 t->radius[2] = 0; |
903 t->radius[2] = 0; |
900 t->radius[3] = mass * 4; |
904 t->radius[3] = mass * 4; |
901 t->radius[4] = mass * 3; |
905 t->radius[4] = mass * 3; |
902 //debug("%d (->%d): %d %d %d %d\n", t->num_houses, mass, t->radius[0], t->radius[1], t->radius[3], t->radius[4]); |
906 //debug("%d (->%d): %d %d %d %d\n", t->num_houses, mass, t->radius[0], t->radius[1], t->radius[3], t->radius[4]); |
1057 /* Only in the scenario editor */ |
1062 /* Only in the scenario editor */ |
1058 if (_game_mode != GM_EDITOR) return CMD_ERROR; |
1063 if (_game_mode != GM_EDITOR) return CMD_ERROR; |
1059 |
1064 |
1060 SET_EXPENSES_TYPE(EXPENSES_OTHER); |
1065 SET_EXPENSES_TYPE(EXPENSES_OTHER); |
1061 |
1066 |
1062 // Check if too close to the edge of map |
1067 /* Check if too close to the edge of map */ |
1063 if (DistanceFromEdge(tile) < 12) |
1068 if (DistanceFromEdge(tile) < 12) |
1064 return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP); |
1069 return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP); |
1065 |
1070 |
1066 // Can only build on clear flat areas, possibly with trees. |
1071 /* Can only build on clear flat areas, possibly with trees. */ |
1067 if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || GetTileSlope(tile, NULL) != SLOPE_FLAT) { |
1072 if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || GetTileSlope(tile, NULL) != SLOPE_FLAT) { |
1068 return_cmd_error(STR_0239_SITE_UNSUITABLE); |
1073 return_cmd_error(STR_0239_SITE_UNSUITABLE); |
1069 } |
1074 } |
1070 |
1075 |
1071 // Check distance to all other towns. |
1076 /* Check distance to all other towns. */ |
1072 if (IsCloseToTown(tile, 20)) |
1077 if (IsCloseToTown(tile, 20)) |
1073 return_cmd_error(STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN); |
1078 return_cmd_error(STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN); |
1074 |
1079 |
1075 // Get a unique name for the town. |
1080 /* Get a unique name for the town. */ |
1076 if (!CreateTownName(&townnameparts)) |
1081 if (!CreateTownName(&townnameparts)) |
1077 return_cmd_error(STR_023A_TOO_MANY_TOWNS); |
1082 return_cmd_error(STR_023A_TOO_MANY_TOWNS); |
1078 |
1083 |
1079 // Allocate town struct |
1084 /* Allocate town struct */ |
1080 t = AllocateTown(); |
1085 t = AllocateTown(); |
1081 if (t == NULL) return_cmd_error(STR_023A_TOO_MANY_TOWNS); |
1086 if (t == NULL) return_cmd_error(STR_023A_TOO_MANY_TOWNS); |
1082 |
1087 |
1083 // Create the town |
1088 /* Create the town */ |
1084 if (flags & DC_EXEC) { |
1089 if (flags & DC_EXEC) { |
1085 _generating_world = true; |
1090 _generating_world = true; |
1086 DoCreateTown(t, tile, townnameparts, p1); |
1091 DoCreateTown(t, tile, townnameparts, p1); |
1087 _generating_world = false; |
1092 _generating_world = false; |
1088 } |
1093 } |
1094 TileIndex tile; |
1099 TileIndex tile; |
1095 Town *t; |
1100 Town *t; |
1096 uint32 townnameparts; |
1101 uint32 townnameparts; |
1097 |
1102 |
1098 do { |
1103 do { |
1099 // Generate a tile index not too close from the edge |
1104 /* Generate a tile index not too close from the edge */ |
1100 tile = RandomTile(); |
1105 tile = RandomTile(); |
1101 if (DistanceFromEdge(tile) < 20) continue; |
1106 if (DistanceFromEdge(tile) < 20) continue; |
1102 |
1107 |
1103 // Make sure the tile is plain |
1108 /* Make sure the tile is plain */ |
1104 if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != SLOPE_FLAT) continue; |
1109 if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != SLOPE_FLAT) continue; |
1105 |
1110 |
1106 // Check not too close to a town |
1111 /* Check not too close to a town */ |
1107 if (IsCloseToTown(tile, 20)) continue; |
1112 if (IsCloseToTown(tile, 20)) continue; |
1108 |
1113 |
1109 // Get a unique name for the town. |
1114 /* Get a unique name for the town. */ |
1110 if (!CreateTownName(&townnameparts)) break; |
1115 if (!CreateTownName(&townnameparts)) break; |
1111 |
1116 |
1112 // Allocate a town struct |
1117 /* Allocate a town struct */ |
1113 t = AllocateTown(); |
1118 t = AllocateTown(); |
1114 if (t == NULL) break; |
1119 if (t == NULL) break; |
1115 |
1120 |
1116 DoCreateTown(t, tile, townnameparts, size_mode); |
1121 DoCreateTown(t, tile, townnameparts, size_mode); |
1117 return t; |
1122 return t; |
1221 Slope slope; |
1226 Slope slope; |
1222 uint z; |
1227 uint z; |
1223 uint oneof = 0; |
1228 uint oneof = 0; |
1224 HouseSpec *hs; |
1229 HouseSpec *hs; |
1225 |
1230 |
1226 // Above snow? |
1231 /* Above snow? */ |
1227 slope = GetTileSlope(tile, &z); |
1232 slope = GetTileSlope(tile, &z); |
1228 |
1233 |
1229 // Get the town zone type |
1234 /* Get the town zone type */ |
1230 { |
1235 { |
1231 uint rad = GetTownRadiusGroup(t, tile); |
1236 uint rad = GetTownRadiusGroup(t, tile); |
1232 |
1237 |
1233 int land = _opt.landscape; |
1238 int land = _opt.landscape; |
1234 if (land == LT_ARCTIC && z >= _opt.snow_line) land = -1; |
1239 if (land == LT_ARCTIC && z >= _opt.snow_line) land = -1; |
1235 |
1240 |
1236 bitmask = (1 << rad) + (1 << (land + 12)); |
1241 bitmask = (1 << rad) + (1 << (land + 12)); |
1237 } |
1242 } |
1238 |
1243 |
1239 // bits 0-4 are used |
1244 /* bits 0-4 are used |
1240 // bits 11-15 are used |
1245 * bits 11-15 are used |
1241 // bits 5-10 are not used. |
1246 * bits 5-10 are not used. */ |
1242 { |
1247 { |
1243 HouseID houses[HOUSE_MAX]; |
1248 HouseID houses[HOUSE_MAX]; |
1244 int num = 0; |
1249 int num = 0; |
1245 uint cumulative_probs[HOUSE_MAX]; |
1250 uint cumulative_probs[HOUSE_MAX]; |
1246 uint probability_max = 0; |
1251 uint probability_max = 0; |
1247 |
1252 |
1248 // Generate a list of all possible houses that can be built. |
1253 /* Generate a list of all possible houses that can be built. */ |
1249 for (i = 0; i < HOUSE_MAX; i++) { |
1254 for (i = 0; i < HOUSE_MAX; i++) { |
1250 hs = GetHouseSpecs(i); |
1255 hs = GetHouseSpecs(i); |
1251 if ((~hs->building_availability & bitmask) == 0 && hs->enabled) { |
1256 if ((~hs->building_availability & bitmask) == 0 && hs->enabled) { |
1252 if (_have_newhouses) { |
1257 if (_have_newhouses) { |
1253 probability_max += hs->probability; |
1258 probability_max += hs->probability; |
1396 } |
1401 } |
1397 } |
1402 } |
1398 |
1403 |
1399 hs = GetHouseSpecs(house); |
1404 hs = GetHouseSpecs(house); |
1400 |
1405 |
1401 // Remove population from the town if the house is finished. |
1406 /* Remove population from the town if the house is finished. */ |
1402 if (IsHouseCompleted(tile)) { |
1407 if (IsHouseCompleted(tile)) { |
1403 ChangePopulation(t, -hs->population); |
1408 ChangePopulation(t, -hs->population); |
1404 } |
1409 } |
1405 |
1410 |
1406 t->num_houses--; |
1411 t->num_houses--; |
1407 DecreaseBuildingCount(t, house); |
1412 DecreaseBuildingCount(t, house); |
1408 |
1413 |
1409 // Clear flags for houses that only may exist once/town. |
1414 /* Clear flags for houses that only may exist once/town. */ |
1410 if (hs->building_flags & BUILDING_IS_CHURCH) { |
1415 if (hs->building_flags & BUILDING_IS_CHURCH) { |
1411 CLRBIT(t->flags12, TOWN_HAS_CHURCH); |
1416 CLRBIT(t->flags12, TOWN_HAS_CHURCH); |
1412 } else if (hs->building_flags & BUILDING_IS_STADIUM) { |
1417 } else if (hs->building_flags & BUILDING_IS_STADIUM) { |
1413 CLRBIT(t->flags12, TOWN_HAS_STADIUM); |
1418 CLRBIT(t->flags12, TOWN_HAS_STADIUM); |
1414 } |
1419 } |
1415 |
1420 |
1416 // Do the actual clearing of tiles |
1421 /* Do the actual clearing of tiles */ |
1417 eflags = hs->building_flags; |
1422 eflags = hs->building_flags; |
1418 DoClearTownHouseHelper(tile); |
1423 DoClearTownHouseHelper(tile); |
1419 if (eflags & BUILDING_2_TILES_X) DoClearTownHouseHelper(tile + TileDiffXY(1, 0)); |
1424 if (eflags & BUILDING_2_TILES_X) DoClearTownHouseHelper(tile + TileDiffXY(1, 0)); |
1420 if (eflags & BUILDING_2_TILES_Y) DoClearTownHouseHelper(tile + TileDiffXY(0, 1)); |
1425 if (eflags & BUILDING_2_TILES_Y) DoClearTownHouseHelper(tile + TileDiffXY(0, 1)); |
1421 if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1)); |
1426 if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1)); |
1422 } |
1427 } |
1423 |
1428 |
1424 /** Rename a town (server-only). |
1429 /** Rename a town (server-only). |
1425 * @param tile unused |
1430 * @param tile unused |
|
1431 * @param flags type of operation |
1426 * @param p1 town ID to rename |
1432 * @param p1 town ID to rename |
1427 * @param p2 unused |
1433 * @param p2 unused |
1428 */ |
1434 */ |
1429 int32 CmdRenameTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1435 int32 CmdRenameTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1430 { |
1436 { |
1579 static void TownActionBribe(Town* t) |
1585 static void TownActionBribe(Town* t) |
1580 { |
1586 { |
1581 if (!RandomRange(15)) { |
1587 if (!RandomRange(15)) { |
1582 Station *st; |
1588 Station *st; |
1583 |
1589 |
1584 // set as unwanted for 6 months |
1590 /* set as unwanted for 6 months */ |
1585 t->unwanted[_current_player] = 6; |
1591 t->unwanted[_current_player] = 6; |
1586 |
1592 |
1587 // set all close by station ratings to 0 |
1593 /* set all close by station ratings to 0 */ |
1588 FOR_ALL_STATIONS(st) { |
1594 FOR_ALL_STATIONS(st) { |
1589 if (st->town == t && st->owner == _current_player) { |
1595 if (st->town == t && st->owner == _current_player) { |
1590 for (CargoID i = 0; i < NUM_CARGO; i++) st->goods[i].rating = 0; |
1596 for (CargoID i = 0; i < NUM_CARGO; i++) st->goods[i].rating = 0; |
1591 } |
1597 } |
1592 } |
1598 } |
1593 |
1599 |
1594 // only show errormessage to the executing player. All errors are handled command.c |
1600 /* only show errormessage to the executing player. All errors are handled command.c |
1595 // but this is special, because it can only 'fail' on a DC_EXEC |
1601 * but this is special, because it can only 'fail' on a DC_EXEC */ |
1596 if (IsLocalPlayer()) ShowErrorMessage(STR_BRIBE_FAILED_2, STR_BRIBE_FAILED, 0, 0); |
1602 if (IsLocalPlayer()) ShowErrorMessage(STR_BRIBE_FAILED_2, STR_BRIBE_FAILED, 0, 0); |
1597 |
1603 |
1598 /* decrease by a lot! |
1604 /* decrease by a lot! |
1599 * ChangeTownRating is only for stuff in demolishing. Bribe failure should |
1605 * ChangeTownRating is only for stuff in demolishing. Bribe failure should |
1600 * be independent of any cheat settings |
1606 * be independent of any cheat settings |
1713 SETBIT(t->flags12, TOWN_IS_FUNDED); |
1720 SETBIT(t->flags12, TOWN_IS_FUNDED); |
1714 } |
1721 } |
1715 |
1722 |
1716 static void UpdateTownAmounts(Town *t) |
1723 static void UpdateTownAmounts(Town *t) |
1717 { |
1724 { |
1718 // Using +1 here to prevent overflow and division by zero |
1725 /* Using +1 here to prevent overflow and division by zero */ |
1719 t->pct_pass_transported = t->new_act_pass * 256 / (t->new_max_pass + 1); |
1726 t->pct_pass_transported = t->new_act_pass * 256 / (t->new_max_pass + 1); |
1720 |
1727 |
1721 t->max_pass = t->new_max_pass; t->new_max_pass = 0; |
1728 t->max_pass = t->new_max_pass; t->new_max_pass = 0; |
1722 t->act_pass = t->new_act_pass; t->new_act_pass = 0; |
1729 t->act_pass = t->new_act_pass; t->new_act_pass = 0; |
1723 t->act_food = t->new_act_food; t->new_act_food = 0; |
1730 t->act_food = t->new_act_food; t->new_act_food = 0; |
1724 t->act_water = t->new_act_water; t->new_act_water = 0; |
1731 t->act_water = t->new_act_water; t->new_act_water = 0; |
1725 |
1732 |
1726 // Using +1 here to prevent overflow and division by zero |
1733 /* Using +1 here to prevent overflow and division by zero */ |
1727 t->pct_mail_transported = t->new_act_mail * 256 / (t->new_max_mail + 1); |
1734 t->pct_mail_transported = t->new_act_mail * 256 / (t->new_max_mail + 1); |
1728 t->max_mail = t->new_max_mail; t->new_max_mail = 0; |
1735 t->max_mail = t->new_max_mail; t->new_max_mail = 0; |
1729 t->act_mail = t->new_act_mail; t->new_act_mail = 0; |
1736 t->act_mail = t->new_act_mail; t->new_act_mail = 0; |
1730 |
1737 |
1731 InvalidateWindow(WC_TOWN_VIEW, t->index); |
1738 InvalidateWindow(WC_TOWN_VIEW, t->index); |
1818 t->ratings[_current_player] = rating; |
1825 t->ratings[_current_player] = rating; |
1819 } |
1826 } |
1820 |
1827 |
1821 /* penalty for removing town-owned stuff */ |
1828 /* penalty for removing town-owned stuff */ |
1822 static const int _default_rating_settings [3][3] = { |
1829 static const int _default_rating_settings [3][3] = { |
1823 // ROAD_REMOVE, TUNNELBRIDGE_REMOVE, INDUSTRY_REMOVE |
1830 /* ROAD_REMOVE, TUNNELBRIDGE_REMOVE, INDUSTRY_REMOVE */ |
1824 { 0, 128, 384}, // Permissive |
1831 { 0, 128, 384}, ///< Permissive |
1825 { 48, 192, 480}, // Neutral |
1832 { 48, 192, 480}, ///< Neutral |
1826 { 96, 384, 768}, // Hostile |
1833 { 96, 384, 768}, ///< Hostile |
1827 }; |
1834 }; |
1828 |
1835 |
1829 bool CheckforTownRating(uint32 flags, Town *t, byte type) |
1836 bool CheckforTownRating(uint32 flags, Town *t, byte type) |
1830 { |
1837 { |
1831 int modemod; |
1838 int modemod; |
1832 |
1839 |
1833 // if magic_bulldozer cheat is active, town doesn't restrict your destructive actions |
1840 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */ |
1834 if (t == NULL || !IsValidPlayer(_current_player) || _cheats.magic_bulldozer.value) |
1841 if (t == NULL || !IsValidPlayer(_current_player) || _cheats.magic_bulldozer.value) |
1835 return true; |
1842 return true; |
1836 |
1843 |
1837 /* check if you're allowed to remove the street/bridge/tunnel/industry |
1844 /* check if you're allowed to remove the street/bridge/tunnel/industry |
1838 * owned by a town no removal if rating is lower than ... depends now on |
1845 * owned by a town no removal if rating is lower than ... depends now on |
1898 NULL, /* vehicle_enter_tile_proc */ |
1905 NULL, /* vehicle_enter_tile_proc */ |
1899 GetSlopeTileh_Town, /* get_slope_tileh_proc */ |
1906 GetSlopeTileh_Town, /* get_slope_tileh_proc */ |
1900 }; |
1907 }; |
1901 |
1908 |
1902 |
1909 |
1903 // Save and load of towns. |
1910 /** Save and load of towns. */ |
1904 static const SaveLoad _town_desc[] = { |
1911 static const SaveLoad _town_desc[] = { |
1905 SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5), |
1912 SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5), |
1906 SLE_CONDVAR(Town, xy, SLE_UINT32, 6, SL_MAX_VERSION), |
1913 SLE_CONDVAR(Town, xy, SLE_UINT32, 6, SL_MAX_VERSION), |
1907 |
1914 |
1908 SLE_CONDVAR(Town, population, SLE_FILE_U16 | SLE_VAR_U32, 0, 2), |
1915 SLE_CONDVAR(Town, population, SLE_FILE_U16 | SLE_VAR_U32, 0, 2), |
1914 SLE_VAR(Town, townnameparts, SLE_UINT32), |
1921 SLE_VAR(Town, townnameparts, SLE_UINT32), |
1915 |
1922 |
1916 SLE_VAR(Town, flags12, SLE_UINT8), |
1923 SLE_VAR(Town, flags12, SLE_UINT8), |
1917 SLE_VAR(Town, statues, SLE_UINT8), |
1924 SLE_VAR(Town, statues, SLE_UINT8), |
1918 |
1925 |
1919 // sort_index_obsolete was stored here in savegame format 0 - 1 |
1926 /* sort_index_obsolete was stored here in savegame format 0 - 1 */ |
1920 SLE_CONDNULL(1, 0, 1), |
1927 SLE_CONDNULL(1, 0, 1), |
1921 |
1928 |
1922 SLE_VAR(Town, have_ratings, SLE_UINT8), |
1929 SLE_VAR(Town, have_ratings, SLE_UINT8), |
1923 SLE_ARR(Town, ratings, SLE_INT16, 8), |
1930 SLE_ARR(Town, ratings, SLE_INT16, 8), |
1924 // failed bribe attempts are stored since savegame format 4 |
1931 /* failed bribe attempts are stored since savegame format 4 */ |
1925 SLE_CONDARR(Town, unwanted, SLE_INT8, 8, 4,SL_MAX_VERSION), |
1932 SLE_CONDARR(Town, unwanted, SLE_INT8, 8, 4,SL_MAX_VERSION), |
1926 |
1933 |
1927 SLE_CONDVAR(Town, max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), |
1934 SLE_CONDVAR(Town, max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), |
1928 SLE_CONDVAR(Town, max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), |
1935 SLE_CONDVAR(Town, max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), |
1929 SLE_CONDVAR(Town, new_max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), |
1936 SLE_CONDVAR(Town, new_max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), |