src/town_cmd.cpp
branchNewGRF_ports
changeset 6720 35756db7e577
parent 6719 4cc327ad39d5
child 6743 cabfaa4a0295
--- a/src/town_cmd.cpp	Sat Jun 02 19:59:29 2007 +0000
+++ b/src/town_cmd.cpp	Sat Jul 14 19:42:58 2007 +0000
@@ -39,6 +39,7 @@
 #include "newgrf_callbacks.h"
 #include "newgrf_house.h"
 #include "newgrf_commons.h"
+#include "newgrf_townname.h"
 
 /**
  * Called if a new block is added to the town-pool
@@ -344,7 +345,7 @@
 
 	/* Check and/or  */
 	if (HASBIT(GetHouseSpecs(GetHouseType(tile))->callback_mask, CBM_CONSTRUCTION_STATE_CHANGE)) {
-		uint16 callback_res = GetHouseCallback(CBID_CONSTRUCTION_STATE_CHANGE, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
+		uint16 callback_res = GetHouseCallback(CBID_HOUSE_CONSTRUCTION_STATE_CHANGE, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
 		if (callback_res != CALLBACK_FAILED) ChangeHouseAnimationFrame(tile, callback_res);
 	}
 
@@ -478,17 +479,17 @@
 	/* not used */
 }
 
-static int32 ClearTile_Town(TileIndex tile, byte flags)
+static CommandCost ClearTile_Town(TileIndex tile, byte flags)
 {
 	int rating;
-	int32 cost;
+	CommandCost cost;
 	Town *t;
 	HouseSpec *hs = GetHouseSpecs(GetHouseType(tile));
 
 	if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
 	if (!CanDeleteHouse(tile)) return CMD_ERROR;
 
-	cost = _price.remove_house * hs->removal_cost >> 8;
+	cost.AddCost(_price.remove_house * hs->removal_cost >> 8);
 
 	rating = hs->remove_rating_decrease;
 	_cleared_town_rating += rating;
@@ -639,6 +640,7 @@
 	TrackBits b = GetAnyRoadTrackBits(tile, ROADTYPE_ROAD);
 	RoadBits r = ROAD_NONE;
 
+	if (b == TRACK_BIT_NONE) return r;
 	if (b & TRACK_BIT_X)     r |= ROAD_X;
 	if (b & TRACK_BIT_Y)     r |= ROAD_Y;
 	if (b & TRACK_BIT_UPPER) r |= ROAD_NE | ROAD_NW;
@@ -667,6 +669,8 @@
 
 static bool IsRoadAllowedHere(TileIndex tile, int dir)
 {
+	if (TileX(tile) < 2 || TileY(tile) < 2 || MapMaxX() <= TileX(tile) || MapMaxY() <= TileY(tile)) return false;
+
 	Slope k;
 	Slope slope;
 
@@ -708,7 +712,7 @@
 			uint32 r = Random();
 
 			if (CHANCE16I(1, 8, r) && !_generating_world) {
-				int32 res;
+				CommandCost res;
 
 				if (CHANCE16I(1, 16, r)) {
 					res = DoCommand(tile, slope, 0, DC_EXEC | DC_AUTO | DC_NO_WATER,
@@ -730,12 +734,12 @@
 
 static bool TerraformTownTile(TileIndex tile, int edges, int dir)
 {
-	int32 r;
+	CommandCost r;
 
 	TILE_ASSERT(tile);
 
 	r = DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
-	if (CmdFailed(r) || r >= 126 * 16) return false;
+	if (CmdFailed(r) || r.GetCost() >= 126 * 16) return false;
 	DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND);
 	return true;
 }
@@ -1063,7 +1067,7 @@
 
 		default:
 build_road_and_exit:
-			if (!CmdFailed(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) {
+			if (CmdSucceeded(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) {
 				_grow_town_result = -1;
 			}
 			return;
@@ -1096,7 +1100,7 @@
 		do {
 			byte bridge_type = RandomRange(MAX_BRIDGES - 1);
 			if (CheckBridge_Stuff(bridge_type, bridge_len)) {
-				if (!CmdFailed(DoCommand(tile, tmptile, 0x8000 + bridge_type, DC_EXEC | DC_AUTO, CMD_BUILD_BRIDGE)))
+				if (CmdSucceeded(DoCommand(tile, tmptile, bridge_type | ((0x80 | ROADTYPES_ROAD) << 8), DC_EXEC | DC_AUTO, CMD_BUILD_BRIDGE)))
 					_grow_town_result = -1;
 
 				/* obviously, if building any bridge would fail, there is no need to try other bridge-types */
@@ -1235,7 +1239,7 @@
 	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
 		/* Only work with plain land that not already has a house */
 		if (!IsTileType(tile, MP_HOUSE) && GetTileSlope(tile, NULL) == SLOPE_FLAT) {
-			if (!CmdFailed(DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR))) {
+			if (CmdSucceeded(DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR))) {
 				DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
 				_current_player = old_player;
 				return true;
@@ -1295,6 +1299,7 @@
 
 static bool CreateTownName(uint32 *townnameparts)
 {
+	extern int _nb_orig_names;
 	Town *t2;
 	char buf1[64];
 	char buf2[64];
@@ -1305,7 +1310,9 @@
 	 * the other towns may take considerable amount of time (10000 is
 	 * too much). */
 	int tries = 1000;
-	uint16 townnametype = SPECSTR_TOWNNAME_START + _opt.town_name;
+	bool grf = (_opt.town_name >= _nb_orig_names);
+	uint32 grfid = grf ? GetGRFTownNameId(_opt.town_name - _nb_orig_names) : 0;
+	uint16 townnametype = grf ? GetGRFTownNameType(_opt.town_name - _nb_orig_names) : SPECSTR_TOWNNAME_START + _opt.town_name;
 
 	assert(townnameparts);
 
@@ -1314,7 +1321,11 @@
 		r = Random();
 
 		SetDParam(0, r);
-		GetString(buf1, townnametype, lastof(buf1));
+		if (grf && grfid != 0) {
+			GRFTownNameGenerate(buf1, grfid, townnametype, r, lastof(buf1));
+		} else {
+			GetString(buf1, townnametype, lastof(buf1));
+		}
 
 		/* Check size and width */
 		if (strlen(buf1) >= 31 || GetStringBoundingBox(buf1).width > 130) continue;
@@ -1351,6 +1362,7 @@
  */
 static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSizeMode size_mode, uint size)
 {
+	extern int _nb_orig_names;
 	int x, i;
 
 	/* clear the town struct */
@@ -1392,7 +1404,15 @@
 	t->exclusive_counter = 0;
 	t->statues = 0;
 
-	t->townnametype = SPECSTR_TOWNNAME_START + _opt.town_name;
+	if (_opt.town_name < _nb_orig_names) {
+		/* Original town name */
+		t->townnamegrfid = 0;
+		t->townnametype = SPECSTR_TOWNNAME_START + _opt.town_name;
+	} else {
+		/* Newgrf town name */
+		t->townnamegrfid = GetGRFTownNameId(_opt.town_name  - _nb_orig_names);
+		t->townnametype  = GetGRFTownNameType(_opt.town_name - _nb_orig_names);
+	}
 	t->townnameparts = townnameparts;
 
 	UpdateTownVirtCoord(t);
@@ -1464,7 +1484,7 @@
  * @param p1 size of the town (0 = small, 1 = medium, 2 = large)
  * @param p2 size mode (@see TownSizeMode)
  */
-int32 CmdBuildTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Town *t;
 	uint32 townnameparts;
@@ -1502,7 +1522,7 @@
 		DoCreateTown(t, tile, townnameparts, (TownSizeMode)p2, p1);
 		_generating_world = false;
 	}
-	return 0;
+	return CommandCost();
 }
 
 Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size)
@@ -1587,7 +1607,7 @@
 	if (b)
 		return false;
 
-	return !CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR));
+	return CmdSucceeded(DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR));
 }
 
 
@@ -1668,7 +1688,7 @@
 		for (i = 0; i < HOUSE_MAX; i++) {
 			hs = GetHouseSpecs(i);
 			if ((~hs->building_availability & bitmask) == 0 && hs->enabled) {
-				if (HASBIT(_loaded_newgrf_features, GRFLOADED_NEWHOUSES)) {
+				if (_loaded_newgrf_features.has_newhouses) {
 					probability_max += hs->probability;
 					cumulative_probs[num] = probability_max;
 				}
@@ -1677,7 +1697,7 @@
 		}
 
 		for (;;) {
-			if (HASBIT(_loaded_newgrf_features, GRFLOADED_NEWHOUSES)) {
+			if (_loaded_newgrf_features.has_newhouses) {
 				uint r = RandomRange(probability_max);
 				for (i = 0; i < num; i++) if (cumulative_probs[i] >= r) break;
 
@@ -1688,7 +1708,7 @@
 
 			hs = GetHouseSpecs(house);
 
-			if (HASBIT(_loaded_newgrf_features, GRFLOADED_NEWHOUSES)) {
+			if (_loaded_newgrf_features.has_newhouses) {
 				if (hs->override != 0) hs = GetHouseSpecs(hs->override);
 
 				if ((hs->extra_flags & BUILDING_IS_HISTORICAL) && !_generating_world) continue;
@@ -1770,7 +1790,7 @@
 
 static bool BuildTownHouse(Town *t, TileIndex tile)
 {
-	int32 r;
+	CommandCost r;
 
 	if (IsSteepSlope(GetTileSlope(tile, NULL))) return false;
 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return false;
@@ -1840,27 +1860,44 @@
 	if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1));
 }
 
+static bool IsUniqueTownName(const char *name)
+{
+	const Town *t;
+	char buf[512];
+
+	FOR_ALL_TOWNS(t) {
+		SetDParam(0, t->index);
+		GetString(buf, STR_TOWN, lastof(buf));
+		if (strcmp(buf, name) == 0) return false;
+	}
+
+	return true;
+}
+
 /** Rename a town (server-only).
  * @param tile unused
  * @param flags type of operation
  * @param p1 town ID to rename
  * @param p2 unused
  */
-int32 CmdRenameTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdRenameTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	StringID str;
 	Town *t;
 
-	if (!IsValidTownID(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
+	if (!IsValidTownID(p1) || StrEmpty(_cmd_text)) return CMD_ERROR;
 
 	t = GetTown(p1);
 
-	str = AllocateNameUnique(_cmd_text, 4);
+	if (!IsUniqueTownName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
+
+	str = AllocateName(_cmd_text, 4);
 	if (str == 0) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
 		DeleteName(t->townnametype);
 		t->townnametype = str;
+		t->townnamegrfid = 0;
 
 		UpdateTownVirtCoord(t);
 		_town_sort_dirty = true;
@@ -1869,7 +1906,7 @@
 	} else {
 		DeleteName(str);
 	}
-	return 0;
+	return CommandCost();
 }
 
 /** Called from GUI */
@@ -1915,15 +1952,10 @@
 
 static void TownActionRoadRebuild(Town* t)
 {
-	const Player* p;
-
 	t->road_build_months = 6;
 
 	SetDParam(0, t->index);
-
-	p = GetPlayer(_current_player);
-	SetDParam(1, p->name_1);
-	SetDParam(2, p->name_2);
+	SetDParam(1, _current_player);
 
 	AddNewsItem(STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING,
 		NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_GENERAL, 0), t->xy, 0);
@@ -1932,7 +1964,7 @@
 static bool DoBuildStatueOfCompany(TileIndex tile, TownID town_id)
 {
 	PlayerID old;
-	int32 r;
+	CommandCost r;
 
 	if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return false;
 
@@ -2050,9 +2082,9 @@
  * @param p1 town to do the action at
  * @param p2 action to perform, @see _town_action_proc for the list of available actions
  */
-int32 CmdDoTownAction(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdDoTownAction(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	int32 cost;
+	CommandCost cost;
 	Town *t;
 
 	if (!IsValidTownID(p1) || p2 > lengthof(_town_action_proc)) return CMD_ERROR;
@@ -2063,7 +2095,7 @@
 
 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 
-	cost = (_price.build_industry >> 8) * _town_action_costs[p2];
+	cost.AddCost((_price.build_industry >> 8) * _town_action_costs[p2]);
 
 	if (flags & DC_EXEC) {
 		_town_action_proc[p2](t);
@@ -2338,6 +2370,7 @@
 
 
 	    SLE_VAR(Town, num_houses,            SLE_UINT16),
+	SLE_CONDVAR(Town, townnamegrfid,         SLE_UINT32, 66, SL_MAX_VERSION),
 	    SLE_VAR(Town, townnametype,          SLE_UINT16),
 	    SLE_VAR(Town, townnameparts,         SLE_UINT32),