Changeset - r23187:bba8b5b3c78d
[Not reviewed]
master
0 4 0
Niels Martin Hansen - 6 years ago 2018-07-28 21:28:24
nielsm@indvikleren.dk
Add: Houses can accept up to 16 different cargo types via NewGRF.

New Action0 property 23 for feature 07, variable length, format B n*(B B). Initial byte is number of structures following. First byte in structure is cargo id, second is acceptance level in 1/8 units.
4 files changed with 56 insertions and 25 deletions:
0 comments (0 inline, 0 general)
src/house.h
Show inline comments
 
@@ -31,6 +31,8 @@ static const HouseID NEW_HOUSE_OFFSET = 
 
static const HouseID NUM_HOUSES       = 512;    ///< Total number of houses.
 
static const HouseID INVALID_HOUSE_ID = 0xFFFF;
 

	
 
static const uint HOUSE_NUM_ACCEPTS = 16; ///< Max number of cargoes accepted by a tile
 

	
 
/**
 
 * There can only be as many classes as there are new houses, plus one for
 
 * NO_CLASS, as the original houses don't have classes.
 
@@ -97,30 +99,30 @@ DECLARE_ENUM_AS_BIT_SET(HouseExtraFlags)
 

	
 
struct HouseSpec {
 
	/* Standard properties */
 
	Year min_year;                     ///< introduction year of the house
 
	Year max_year;                     ///< last year it can be built
 
	byte population;                   ///< population (Zero on other tiles in multi tile house.)
 
	byte removal_cost;                 ///< cost multiplier for removing it
 
	StringID building_name;            ///< building name
 
	uint16 remove_rating_decrease;     ///< rating decrease if removed
 
	byte mail_generation;              ///< mail generation multiplier (tile based, as the acceptances below)
 
	byte cargo_acceptance[3];          ///< acceptance level for the cargo slots
 
	CargoID accepts_cargo[3];          ///< 3 input cargo slots
 
	BuildingFlags building_flags;      ///< some flags that describe the house (size, stadium etc...)
 
	HouseZones building_availability;  ///< where can it be built (climates, zones)
 
	bool enabled;                      ///< the house is available to build (true by default, but can be disabled by newgrf)
 
	Year min_year;                            ///< introduction year of the house
 
	Year max_year;                            ///< last year it can be built
 
	byte population;                          ///< population (Zero on other tiles in multi tile house.)
 
	byte removal_cost;                        ///< cost multiplier for removing it
 
	StringID building_name;                   ///< building name
 
	uint16 remove_rating_decrease;            ///< rating decrease if removed
 
	byte mail_generation;                     ///< mail generation multiplier (tile based, as the acceptances below)
 
	byte cargo_acceptance[HOUSE_NUM_ACCEPTS]; ///< acceptance level for the cargo slots
 
	CargoID accepts_cargo[HOUSE_NUM_ACCEPTS]; ///< input cargo slots
 
	BuildingFlags building_flags;             ///< some flags that describe the house (size, stadium etc...)
 
	HouseZones building_availability;         ///< where can it be built (climates, zones)
 
	bool enabled;                             ///< the house is available to build (true by default, but can be disabled by newgrf)
 

	
 
	/* NewHouses properties */
 
	GRFFileProps grf_prop;             ///< Properties related the the grf file
 
	uint16 callback_mask;              ///< Bitmask of house callbacks that have to be called
 
	byte random_colour[4];             ///< 4 "random" colours
 
	byte probability;                  ///< Relative probability of appearing (16 is the standard value)
 
	HouseExtraFlags extra_flags;       ///< some more flags
 
	HouseClassID class_id;             ///< defines the class this house has (not grf file based)
 
	AnimationInfo animation;           ///< information about the animation.
 
	byte processing_time;              ///< Periodic refresh multiplier
 
	byte minimum_life;                 ///< The minimum number of years this house will survive before the town rebuilds it
 
	CargoTypes watched_cargoes;        ///< Cargo types watched for acceptance.
 
	GRFFileProps grf_prop;                    ///< Properties related the the grf file
 
	uint16 callback_mask;                     ///< Bitmask of house callbacks that have to be called
 
	byte random_colour[4];                    ///< 4 "random" colours
 
	byte probability;                         ///< Relative probability of appearing (16 is the standard value)
 
	HouseExtraFlags extra_flags;              ///< some more flags
 
	HouseClassID class_id;                    ///< defines the class this house has (not grf file based)
 
	AnimationInfo animation;                  ///< information about the animation.
 
	byte processing_time;                     ///< Periodic refresh multiplier
 
	byte minimum_life;                        ///< The minimum number of years this house will survive before the town rebuilds it
 
	CargoTypes watched_cargoes;               ///< Cargo types watched for acceptance.
 

	
 
	Money GetRemovalCost() const;
 

	
src/newgrf.cpp
Show inline comments
 
@@ -2294,6 +2294,10 @@ static ChangeInfoResult IgnoreTownHouseP
 
			break;
 
		}
 

	
 
		case 0x23:
 
			buf->Skip(buf->ReadByte() * 2);
 
			break;
 

	
 
		default:
 
			ret = CIR_UNKNOWN;
 
			break;
 
@@ -2526,6 +2530,28 @@ static ChangeInfoResult TownHouseChangeI
 
				housespec->max_year = buf->ReadWord();
 
				break;
 

	
 
			case 0x23: { // variable length cargo types accepted
 
				uint count = buf->ReadByte();
 
				if (count > lengthof(housespec->accepts_cargo)) {
 
					GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
 
					error->param_value[1] = prop;
 
					return CIR_DISABLED;
 
				}
 
				/* Always write the full accepts_cargo array, and check each index for being inside the
 
				 * provided data. This ensures all values are properly initialized, and also avoids
 
				 * any risks of array overrun. */
 
				for (uint i = 0; i < lengthof(housespec->accepts_cargo); i++) {
 
					if (i < count) {
 
						housespec->accepts_cargo[i] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
 
						housespec->cargo_acceptance[i] = buf->ReadByte();
 
					} else {
 
						housespec->accepts_cargo[i] = CT_INVALID;
 
						housespec->cargo_acceptance[i] = 0;
 
					}
 
				}
 
				break;
 
			}
 

	
 
			default:
 
				ret = CIR_UNKNOWN;
 
				break;
src/table/town_land.h
Show inline comments
 
@@ -1812,8 +1812,11 @@ assert_compile(lengthof(_town_draw_tile_
 
 * @see HouseSpec
 
 */
 
#define MS(mnd, mxd, p, rc, bn, rr, mg, ca1, ca2, ca3, bf, ba, cg1, cg2, cg3) \
 
	{mnd, mxd, p, rc, bn, rr, mg, {ca1, ca2, ca3}, {cg1, cg2, cg3}, bf, ba, true, \
 
	 GRFFileProps(INVALID_HOUSE_ID), 0, {0, 0, 0, 0}, 16, NO_EXTRA_FLAG, HOUSE_NO_CLASS, {0, 2, 0, 0}, 0, 0, 0}
 
	{mnd, mxd, p, rc, bn, rr, mg, \
 
	{ca1, ca2, ca3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
 
	{cg1, cg2, cg3, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \
 
	bf, ba, true, GRFFileProps(INVALID_HOUSE_ID), 0, {0, 0, 0, 0}, \
 
	16, NO_EXTRA_FLAG, HOUSE_NO_CLASS, {0, 2, 0, 0}, 0, 0, 0}
 
/** House specifications from original data */
 
static const HouseSpec _original_house_specs[] = {
 
	/**
src/town_cmd.cpp
Show inline comments
 
@@ -611,7 +611,7 @@ static inline void AddAcceptedCargoSetMa
 
static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes *always_accepted)
 
{
 
	const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
 
	CargoID accepts[3];
 
	CargoID accepts[lengthof(hs->accepts_cargo)];
 

	
 
	/* Set the initial accepted cargo types */
 
	for (uint8 i = 0; i < lengthof(accepts); i++) {
0 comments (0 inline, 0 general)