summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskidd13 <skidd13@openttd.org>2008-04-01 16:27:01 +0000
committerskidd13 <skidd13@openttd.org>2008-04-01 16:27:01 +0000
commit1e7f2dbc10db498379d15c37c25b0b68f31d8ad0 (patch)
treefa7b7c551834401c339efb7adeb04a67e8ea18ed
parent15b2f075874d929fb4824e3389d52967d220b7f7 (diff)
downloadopenttd-1e7f2dbc10db498379d15c37c25b0b68f31d8ad0.tar.xz
(svn r12534) -Feature: Add a new type of town road layouts - random for each town
-rw-r--r--src/lang/english.txt1
-rw-r--r--src/town.h49
-rw-r--r--src/town_cmd.cpp66
-rw-r--r--src/town_type.h2
4 files changed, 87 insertions, 31 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt
index 5d08b9a81..ffe0ec08c 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -1173,6 +1173,7 @@ STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :default
STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :better roads
STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 grid
STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 grid
+STR_CONFIG_PATCHES_TOWN_LAYOUT_RANDOM :random
STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position of main toolbar: {ORANGE}{STRING1}
STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Left
diff --git a/src/town.h b/src/town.h
index cbbc76371..3f5f2bd84 100644
--- a/src/town.h
+++ b/src/town.h
@@ -6,6 +6,7 @@
#define TOWN_H
#include "oldpool.h"
+#include "core/bitmath_func.hpp"
#include "core/random_func.hpp"
#include "cargo_type.h"
#include "tile_type.h"
@@ -13,6 +14,7 @@
#include "town_type.h"
#include "player_type.h"
#include "newgrf_string_type.h"
+#include "settings_type.h"
enum {
HOUSE_NO_CLASS = 0,
@@ -161,6 +163,9 @@ struct Town : PoolItem<Town, TownID, &_Town_pool> {
/* NOSAVE: The number of each type of building in the town. */
BuildingCounts building_counts;
+ /* NOSAVE: The town specific road layout */
+ TownLayout layout;
+
/**
* Creates a new town
*/
@@ -170,8 +175,21 @@ struct Town : PoolItem<Town, TownID, &_Town_pool> {
~Town();
inline bool IsValid() const { return this->xy != 0; }
+
+ void InitializeLayout();
+
+ inline TownLayout GetActiveLayout() const;
};
+/**
+ * Get the current valid layout for the town
+ * @return the active layout for this town
+ */
+inline TownLayout Town::GetActiveLayout() const
+{
+ return (_patches.town_layout == TL_RANDOM) ? this->layout : _patches.town_layout;
+}
+
struct HouseSpec {
/* Standard properties */
Year min_date; ///< introduction year of the house
@@ -314,7 +332,6 @@ extern const Town **_town_sort;
extern Town *_cleared_town;
extern int _cleared_town_rating;
-uint TileHash2Bit(uint x, uint y);
void ResetHouses();
void ClearTownHouse(Town *t, TileIndex tile);
@@ -327,4 +344,34 @@ void ChangeTownRating(Town *t, int add, int max);
HouseZonesBits GetTownRadiusGroup(const Town* t, TileIndex tile);
void SetTownRatingTestMode(bool mode);
+/**
+ * Calculate a hash value from a tile position
+ *
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ * @return The hash of the tile
+ */
+static inline uint TileHash(uint x, uint y)
+{
+ uint hash = x >> 4;
+ hash ^= x >> 6;
+ hash ^= y >> 4;
+ hash -= y >> 6;
+ return hash;
+}
+
+/**
+ * Get the last two bits of the TileHash
+ * from a tile position.
+ *
+ * @see TileHash()
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ * @return The last two bits from hash of the tile
+ */
+static inline uint TileHash2Bit(uint x, uint y)
+{
+ return GB(TileHash(x, y), 0, 2);
+}
+
#endif /* TOWN_H */
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index 6d4c1bec3..041f9bddd 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -107,6 +107,23 @@ Town::~Town()
this->xy = 0;
}
+/**
+ * Generate a random town road layout.
+ *
+ * The layout is based on the TileHash.
+ */
+void Town::InitializeLayout()
+{
+ this->layout = (TownLayout)(TileHash(TileX(this->xy), TileY(this->xy)) % NUM_TLS);
+
+ /* Set invalid layouts to valid ones */
+ switch (this->layout) {
+ default: break;
+ case TL_RANDOM: this->layout = TL_ORIGINAL; break;
+ case TL_NO_ROADS: this->layout = TL_BETTER_ROADS; break;
+ }
+}
+
// Local
static int _grow_town_result;
@@ -130,23 +147,6 @@ static TownDrawTileProc * const _town_draw_tile_procs[1] = {
};
/**
- * Calculate a hash value from a tile position
- *
- * @param x The X coordinate
- * @param y The Y coordinate
- * @return The hash of the tile
- */
-uint TileHash2Bit(uint x, uint y)
-{
- uint hash = x >> 4;
- hash ^= x >> 6;
- hash ^= y >> 4;
- hash -= y >> 6;
- hash &= 3;
- return hash;
-}
-
-/**
* Return a random direction
*
* @return a random direction
@@ -708,11 +708,12 @@ static bool IsNeighborRoadTile(TileIndex tile, const DiagDirection dir, uint dis
/**
* Check if a Road is allowed on a given tile
*
+ * @param t The current town
* @param tile The target tile
* @param dir The direction in which we want to extend the town
* @return true if it is allowed else false
*/
-static bool IsRoadAllowedHere(TileIndex tile, DiagDirection dir)
+static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
{
if (TileX(tile) < 2 || TileX(tile) >= MapMaxX() || TileY(tile) < 2 || TileY(tile) >= MapMaxY()) return false;
@@ -733,7 +734,7 @@ static bool IsRoadAllowedHere(TileIndex tile, DiagDirection dir)
if (cur_slope == SLOPE_FLAT) {
no_slope:
/* Tile has no slope */
- switch (_patches.town_layout) {
+ switch (t->GetActiveLayout()) {
default: NOT_REACHED();
case TL_ORIGINAL: // Disallow the road if any neighboring tile has a road (distance: 1)
@@ -804,13 +805,13 @@ static void LevelTownLand(TileIndex tile)
* @return the RoadBit of the current tile regarding
* the selected town layout
*/
-static RoadBits GetTownRoadGridElement(Town* t, TileIndex tile, DiagDirection dir)
+static RoadBits GetTownRoadGridElement(Town *t, TileIndex tile, DiagDirection dir)
{
/* align the grid to the downtown */
TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
RoadBits rcmd = ROAD_NONE;
- switch (_patches.town_layout) {
+ switch (t->GetActiveLayout()) {
default: NOT_REACHED();
case TL_2X2_GRID:
@@ -993,7 +994,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
LevelTownLand(tile);
/* Is a road allowed here? */
- switch (_patches.town_layout) {
+ switch (t1->GetActiveLayout()) {
default: NOT_REACHED();
case TL_NO_ROADS: /* Disallow Roads */
@@ -1007,7 +1008,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
case TL_BETTER_ROADS:
case TL_ORIGINAL:
- if (!IsRoadAllowedHere(tile, target_dir)) return;
+ if (!IsRoadAllowedHere(t1, tile, target_dir)) return;
DiagDirection source_dir = ReverseDiagDir(target_dir);
@@ -1016,7 +1017,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
do target_dir = RandomDiagDir(); while (target_dir == source_dir);
}
- if (!IsRoadAllowedHere(TileAddByDiagDir(tile, target_dir), target_dir)) {
+ if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
/* A road is not allowed to continue the randomized road,
* return if the road we're trying to build is curved. */
if (target_dir != ReverseDiagDir(source_dir)) return;
@@ -1041,7 +1042,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
* the fitting RoadBits */
_grow_town_result = GROWTH_SEARCH_STOPPED;
- switch (_patches.town_layout) {
+ switch (t1->GetActiveLayout()) {
default: NOT_REACHED();
case TL_NO_ROADS: /* Disallow Roads */
@@ -1079,7 +1080,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
/* Don't walk into water. */
if (IsWaterTile(house_tile)) return;
- switch (_patches.town_layout) {
+ switch (t1->GetActiveLayout()) {
default: NOT_REACHED();
case TL_NO_ROADS:
@@ -1103,7 +1104,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
/* Allow a house at the edge. 60% chance or
* always ok if no road allowed. */
rcmd = DiagDirToRoadBits(target_dir);
- allow_house = (!IsRoadAllowedHere(house_tile, target_dir) || Chance16(6, 10));
+ allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
break;
}
@@ -1157,7 +1158,7 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
/* Number of times to search.
* Better roads, 2X2 and 3X3 grid grow quite fast so we give
* them a little handicap. */
- switch (_patches.town_layout) {
+ switch (t->GetActiveLayout()) {
case TL_BETTER_ROADS:
_grow_town_result = 10 + t->num_houses * 2 / 9;
break;
@@ -1447,6 +1448,8 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize
UpdateTownVirtCoord(t);
_town_sort_dirty = true;
+ t->InitializeLayout();
+
/* Random town size. */
x = (Random() & 0xF) + 8;
@@ -1736,7 +1739,7 @@ static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile)
{
TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
- switch (_patches.town_layout) {
+ switch (t->GetActiveLayout()) {
case TL_2X2_GRID:
if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
break;
@@ -1767,7 +1770,7 @@ static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile)
uint dx = MapSize() + TileX(t->xy) - TileX(tile);
uint dy = MapSize() + TileY(t->xy) - TileY(tile);
- switch (_patches.town_layout) {
+ switch (t->GetActiveLayout()) {
case TL_2X2_GRID:
if ((dx % 3) != 0 || (dy % 3) != 0) return false;
break;
@@ -2700,6 +2703,9 @@ static void Load_TOWN()
void AfterLoadTown()
{
_town_sort_dirty = true;
+
+ Town *t;
+ FOR_ALL_TOWNS(t) t->InitializeLayout();
}
extern const ChunkHandler _town_chunk_handlers[] = {
diff --git a/src/town_type.h b/src/town_type.h
index 3491b68d7..c800a5154 100644
--- a/src/town_type.h
+++ b/src/town_type.h
@@ -66,6 +66,8 @@ enum TownLayout {
TL_2X2_GRID, ///< Geometric 2x2 grid algorithm
TL_3X3_GRID, ///< Geometric 3x3 grid algorithm
+ TL_RANDOM, ///< Random town layout
+
NUM_TLS, ///< Number of town layouts
};