| 807 | } |
| 808 | |
| 809 | void GenerateObjects() |
| 810 | { |
| 811 | /* Set a guestimate on how much we progress */ |
| 812 | SetGeneratingWorldProgress(GWP_OBJECT, (uint)ObjectSpec::Count()); |
| 813 | |
| 814 | /* Determine number of water tiles at map border needed for freeform_edges */ |
| 815 | uint num_water_tiles = 0; |
| 816 | if (_settings_game.construction.freeform_edges) { |
| 817 | for (uint x = 0; x < Map::MaxX(); x++) { |
| 818 | if (IsTileType(TileXY(x, 1), MP_WATER)) num_water_tiles++; |
| 819 | if (IsTileType(TileXY(x, Map::MaxY() - 1), MP_WATER)) num_water_tiles++; |
| 820 | } |
| 821 | for (uint y = 1; y < Map::MaxY() - 1; y++) { |
| 822 | if (IsTileType(TileXY(1, y), MP_WATER)) num_water_tiles++; |
| 823 | if (IsTileType(TileXY(Map::MaxX() - 1, y), MP_WATER)) num_water_tiles++; |
| 824 | } |
| 825 | } |
| 826 | |
| 827 | /* Iterate over all possible object types */ |
| 828 | for (const auto &spec : ObjectSpec::Specs()) { |
| 829 | |
| 830 | /* Continue, if the object was never available till now or shall not be placed */ |
| 831 | if (!spec.WasEverAvailable() || spec.generate_amount == 0) continue; |
| 832 | |
| 833 | uint16_t amount = spec.generate_amount; |
| 834 | |
| 835 | /* Scale by map size */ |
| 836 | if (spec.flags.Test(ObjectFlag::ScaleByWater) && _settings_game.construction.freeform_edges) { |
| 837 | /* Scale the amount of lighthouses with the amount of land at the borders. |
| 838 | * The -6 is because the top borders are MP_VOID (-2) and all corners |
| 839 | * are counted twice (-4). */ |
| 840 | amount = Map::ScaleBySize1D(amount * num_water_tiles) / (2 * Map::MaxY() + 2 * Map::MaxX() - 6); |
| 841 | } else if (spec.flags.Test(ObjectFlag::ScaleByWater)) { |
| 842 | amount = Map::ScaleBySize1D(amount); |
| 843 | } else { |
| 844 | amount = Map::ScaleBySize(amount); |
| 845 | } |
| 846 | |
| 847 | /* Now try to place the requested amount of this object */ |
| 848 | for (uint j = Map::ScaleBySize(1000); j != 0 && amount != 0 && Object::CanAllocateItem(); j--) { |
| 849 | switch (spec.Index()) { |
| 850 | case OBJECT_TRANSMITTER: |
| 851 | if (TryBuildTransmitter()) amount--; |
| 852 | break; |
| 853 | |
| 854 | case OBJECT_LIGHTHOUSE: |
| 855 | if (TryBuildLightHouse()) amount--; |
| 856 | break; |
| 857 | |
| 858 | default: |
| 859 | uint8_t view = RandomRange(spec.views); |
| 860 | if (CmdBuildObject({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoTestTownRating, DoCommandFlag::NoModifyTownRating}, RandomTile(), spec.Index(), view).Succeeded()) amount--; |
| 861 | break; |
| 862 | } |
| 863 | } |
| 864 | IncreaseGeneratingWorldProgress(GWP_OBJECT); |
| 865 | } |
| 866 | } |
no test coverage detected