src/town_cmd.cpp
branchnoai
changeset 9624 b71483f2330f
parent 9620 31e38d28a0af
child 9625 3301b1b3889c
--- a/src/town_cmd.cpp	Fri May 11 15:13:08 2007 +0000
+++ b/src/town_cmd.cpp	Fri May 25 00:25:08 2007 +0000
@@ -38,6 +38,7 @@
 #include "newgrf.h"
 #include "newgrf_callbacks.h"
 #include "newgrf_house.h"
+#include "newgrf_commons.h"
 
 /**
  * Called if a new block is added to the town-pool
@@ -343,7 +344,7 @@
 
 	/* Check and/or  */
 	if (HASBIT(GetHouseSpecs(GetHouseType(tile))->callback_mask, CBM_CONSTRUCTION_STATE_CHANGE)) {
-		uint16 callback_res = GetHouseCallback(CBID_CONSTRUCTION_STATE_CHANGE, 0, GetHouseType(tile), GetTownByTile(tile), tile);
+		uint16 callback_res = GetHouseCallback(CBID_CONSTRUCTION_STATE_CHANGE, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
 		if (callback_res != CALLBACK_FAILED) ChangeHouseAnimationFrame(tile, callback_res);
 	}
 
@@ -399,24 +400,55 @@
 
 	r = Random();
 
-	if (GB(r, 0, 8) < hs->population) {
-		uint amt = GB(r, 0, 8) / 8 + 1;
-		uint moved;
-
-		if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
-		t->new_max_pass += amt;
-		moved = MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt);
-		t->new_act_pass += moved;
-	}
-
-	if (GB(r, 8, 8) < hs->mail_generation) {
-		uint amt = GB(r, 8, 8) / 8 + 1;
-		uint moved;
-
-		if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
-		t->new_max_mail += amt;
-		moved = MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt);
-		t->new_act_mail += moved;
+	if (HASBIT(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) {
+		for (uint i = 0; i < 256; i++) {
+			uint16 callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
+
+			if (callback == CALLBACK_FAILED) break;
+			if (callback == 0x20FF) break;
+
+			CargoID cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grffile);
+			if (cargo == CT_INVALID) continue;
+
+			uint amt = GB(callback, 0, 8);
+			uint moved = MoveGoodsToStation(tile, 1, 1, cargo, amt);
+
+			const CargoSpec *cs = GetCargo(cargo);
+			switch (cs->town_effect) {
+				case TE_PASSENGERS:
+					t->new_max_pass += amt;
+					t->new_act_pass += moved;
+					break;
+
+				case TE_MAIL:
+					t->new_max_mail += amt;
+					t->new_act_mail += moved;
+					break;
+
+				default:
+					break;
+			}
+		}
+	} else {
+		if (GB(r, 0, 8) < hs->population) {
+			uint amt = GB(r, 0, 8) / 8 + 1;
+			uint moved;
+
+			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
+			t->new_max_pass += amt;
+			moved = MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt);
+			t->new_act_pass += moved;
+		}
+
+		if (GB(r, 8, 8) < hs->mail_generation) {
+			uint amt = GB(r, 8, 8) / 8 + 1;
+			uint moved;
+
+			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
+			t->new_max_mail += amt;
+			moved = MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt);
+			t->new_act_mail += moved;
+		}
 	}
 
 	_current_player = OWNER_TOWN;
@@ -424,6 +456,7 @@
 	if (hs->building_flags & BUILDING_HAS_1_TILE &&
 			HASBIT(t->flags12, TOWN_IS_FUNDED) &&
 			CanDeleteHouse(tile) &&
+			max(_cur_year - GetHouseConstructionYear(tile), 0) >= hs->minimum_life &&
 			--t->time_until_rebuild == 0) {
 		t->time_until_rebuild = GB(r, 16, 8) + 192;
 
@@ -488,7 +521,7 @@
 
 	/* Check for custom accepted cargo types */
 	if (HASBIT(hs->callback_mask, CBM_HOUSE_ACCEPT_CARGO)) {
-		uint16 callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, GetHouseType(tile), GetTownByTile(tile), tile);
+		uint16 callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
 		if (callback != CALLBACK_FAILED) {
 			/* Replace accepted cargo types with translated values from callback */
 			accepts[0] = GetCargoTranslation(GB(callback,  0, 5), hs->grffile);
@@ -499,7 +532,7 @@
 
 	/* Check for custom cargo acceptance */
 	if (HASBIT(hs->callback_mask, CBM_CARGO_ACCEPTANCE)) {
-		uint16 callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, GetHouseType(tile), GetTownByTile(tile), tile);
+		uint16 callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
 		if (callback != CALLBACK_FAILED) {
 			if (accepts[0] != CT_INVALID) ac[accepts[0]] = GB(callback, 0, 4);
 			if (accepts[1] != CT_INVALID) ac[accepts[1]] = GB(callback, 4, 4);
@@ -530,7 +563,7 @@
 	td->owner = OWNER_TOWN;
 }
 
-static uint32 GetTileTrackStatus_Town(TileIndex tile, TransportType mode)
+static uint32 GetTileTrackStatus_Town(TileIndex tile, TransportType mode, uint sub_mode)
 {
 	/* not used */
 	return 0;
@@ -603,7 +636,7 @@
 
 static RoadBits GetTownRoadMask(TileIndex tile)
 {
-	TrackBits b = GetAnyRoadTrackBits(tile);
+	TrackBits b = GetAnyRoadTrackBits(tile, ROADTYPE_ROAD);
 	RoadBits r = ROAD_NONE;
 
 	if (b & TRACK_BIT_X)     r |= ROAD_X;
@@ -643,7 +676,7 @@
 
 	for (;;) {
 		/* Check if there already is a road at this point? */
-		if (GetAnyRoadTrackBits(tile) == 0) {
+		if (GetAnyRoadTrackBits(tile, ROADTYPE_ROAD) == 0) {
 			/* No, try to build one in the direction.
 			 * if that fails clear the land, and if that fails exit.
 			 * This is to make sure that we can build a road here later. */
@@ -1177,7 +1210,7 @@
 	/* Let the town be a ghost town
 	 * The player wanted it in such a way. Thus there he has it. ;)
 	 * Never reached in editor mode. */
-	if (_patches.town_layout == TL_NO_ROADS) {
+	if (_patches.town_layout == TL_NO_ROADS && _generating_world) {
 		return false;
 	}
 
@@ -1188,7 +1221,7 @@
 	/* Find a road that we can base the construction on. */
 	tile = t->xy;
 	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
-		if (GetAnyRoadTrackBits(tile) != 0) {
+		if (GetAnyRoadTrackBits(tile, ROADTYPE_ROAD) != 0) {
 			int r = GrowTownAtRoad(t, tile);
 			_current_player = old_player;
 			return r != 0;
@@ -1661,7 +1694,7 @@
 				if ((hs->extra_flags & BUILDING_IS_HISTORICAL) && !_generating_world) continue;
 
 				if (HASBIT(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) {
-					uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, house, t, tile);
+					uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile);
 					if (callback_res != CALLBACK_FAILED && callback_res == 0) continue;
 				}
 			}
@@ -2175,7 +2208,7 @@
 {
 	if (IsTileType(tile, MP_HOUSE) || (
 				IsTileType(tile, MP_STREET) &&
-				(IsLevelCrossing(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile)) == OWNER_TOWN
+				GetRoadOwner(tile, ROADTYPE_ROAD) == OWNER_TOWN
 			)) {
 		return GetTownByTile(tile);
 	} else {
@@ -2370,19 +2403,19 @@
 /* Save and load the mapping between the house id on the map, and the grf file
  * it came from. */
 static const SaveLoad _house_id_mapping_desc[] = {
-	SLE_VAR(HouseIDMapping, grfid,         SLE_UINT32),
-	SLE_VAR(HouseIDMapping, house_id,      SLE_UINT8),
-	SLE_VAR(HouseIDMapping, substitute_id, SLE_UINT8),
+	SLE_VAR(EntityIDMapping, grfid,         SLE_UINT32),
+	SLE_VAR(EntityIDMapping, entity_id,     SLE_UINT8),
+	SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
 	SLE_END()
 };
 
 static void Save_HOUSEIDS()
 {
-	uint i;
-
-	for (i = 0; i != lengthof(_house_id_mapping); i++) {
+	uint j = _house_mngr.GetMaxMapping();
+
+	for (uint i = 0; i < j; i++) {
 		SlSetArrayIndex(i);
-		SlObject(&_house_id_mapping[i], _house_id_mapping_desc);
+		SlObject(&_house_mngr.mapping_ID[i], _house_id_mapping_desc);
 	}
 }
 
@@ -2390,11 +2423,12 @@
 {
 	int index;
 
-	ResetHouseIDMapping();
+	_house_mngr.ResetMapping();
+	uint max_id = _house_mngr.GetMaxMapping();
 
 	while ((index = SlIterateArray()) != -1) {
-		if ((uint)index >= lengthof(_house_id_mapping)) break;
-		SlObject(&_house_id_mapping[index], _house_id_mapping_desc);
+		if ((uint)index >= max_id) break;
+		SlObject(&_house_mngr.mapping_ID[index], _house_id_mapping_desc);
 	}
 }