summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNiels Martin Hansen <nielsm@indvikleren.dk>2018-07-28 23:28:24 +0200
committerNiels Martin Hansen <nielsm@indvikleren.dk>2019-01-21 16:06:25 +0100
commit48b334cf97cabee375bd8c96670754c736fbd2f8 (patch)
tree0044d76cdf3016b7ba39cf00aa60b616f8f28d05 /src
parent9ce92521c1f2c6bec862a4e09926c6cca750d9d2 (diff)
downloadopenttd-48b334cf97cabee375bd8c96670754c736fbd2f8.tar.xz
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.
Diffstat (limited to 'src')
-rw-r--r--src/house.h46
-rw-r--r--src/newgrf.cpp26
-rw-r--r--src/table/town_land.h7
-rw-r--r--src/town_cmd.cpp2
4 files changed, 56 insertions, 25 deletions
diff --git a/src/house.h b/src/house.h
index 94ef62ad5..c1cfe6104 100644
--- a/src/house.h
+++ b/src/house.h
@@ -31,6 +31,8 @@ static const HouseID NEW_HOUSE_OFFSET = 110; ///< Offset for new houses.
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;
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 57dcb41ca..3b0af5517 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -2294,6 +2294,10 @@ static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
break;
}
+ case 0x23:
+ buf->Skip(buf->ReadByte() * 2);
+ break;
+
default:
ret = CIR_UNKNOWN;
break;
@@ -2526,6 +2530,28 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt
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;
diff --git a/src/table/town_land.h b/src/table/town_land.h
index e4098334a..647601511 100644
--- a/src/table/town_land.h
+++ b/src/table/town_land.h
@@ -1812,8 +1812,11 @@ assert_compile(lengthof(_town_draw_tile_data) == (NEW_HOUSE_OFFSET) * 4 * 4);
* @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[] = {
/**
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index 986c52c4e..dacf59ddc 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -611,7 +611,7 @@ static inline void AddAcceptedCargoSetMask(CargoID cargo, uint amount, CargoArra
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++) {