summaryrefslogtreecommitdiff
path: root/src/house.h
blob: b2253c711e94bb33a20190fceadb8b8d2cf829e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* $Id$ */

/** @file house.h definition of HouseSpec and accessors */

#ifndef HOUSE_H
#define HOUSE_H

#include "strings_type.h"
#include "cargo_type.h"
#include "economy_type.h"
#include "date_type.h"
#include "house_type.h"

/** Simple value that indicates the house has reached the final stage of
 * construction. */
static const byte TOWN_HOUSE_COMPLETED = 3;

enum {
	HOUSE_NO_CLASS   = 0,
	NEW_HOUSE_OFFSET = 110,
	HOUSE_MAX        = 512,
	INVALID_HOUSE_ID = 0xFFFF,

	/* 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. */
	HOUSE_CLASS_MAX  = HOUSE_MAX - NEW_HOUSE_OFFSET + 1,
};

enum BuildingFlags {
	TILE_NO_FLAG         =       0,
	TILE_SIZE_1x1        = 1U << 0,
	TILE_NOT_SLOPED      = 1U << 1,
	TILE_SIZE_2x1        = 1U << 2,
	TILE_SIZE_1x2        = 1U << 3,
	TILE_SIZE_2x2        = 1U << 4,
	BUILDING_IS_ANIMATED = 1U << 5,
	BUILDING_IS_CHURCH   = 1U << 6,
	BUILDING_IS_STADIUM  = 1U << 7,
	BUILDING_HAS_1_TILE  = TILE_SIZE_1x1 | TILE_SIZE_2x1 | TILE_SIZE_1x2 | TILE_SIZE_2x2,
	BUILDING_HAS_2_TILES = TILE_SIZE_2x1 | TILE_SIZE_1x2 | TILE_SIZE_2x2,
	BUILDING_2_TILES_X   = TILE_SIZE_2x1 | TILE_SIZE_2x2,
	BUILDING_2_TILES_Y   = TILE_SIZE_1x2 | TILE_SIZE_2x2,
	BUILDING_HAS_4_TILES = TILE_SIZE_2x2,
};
DECLARE_ENUM_AS_BIT_SET(BuildingFlags)

enum HouseZonesBits {
	HZB_BEGIN     = 0,
	HZB_TOWN_EDGE = 0,
	HZB_TOWN_OUTSKIRT,
	HZB_TOWN_OUTER_SUBURB,
	HZB_TOWN_INNER_SUBURB,
	HZB_TOWN_CENTRE,
	HZB_END,
};
assert_compile(HZB_END == 5);

DECLARE_POSTFIX_INCREMENT(HouseZonesBits)

enum HouseZones {                  ///< Bit  Value       Meaning
	HZ_NOZNS             = 0x0000,  ///<       0          This is just to get rid of zeros, meaning none
	HZ_ZON1              = 1U << HZB_TOWN_EDGE,    ///< 0..4 1,2,4,8,10  which town zones the building can be built in, Zone1 been the further suburb
	HZ_ZON2              = 1U << HZB_TOWN_OUTSKIRT,
	HZ_ZON3              = 1U << HZB_TOWN_OUTER_SUBURB,
	HZ_ZON4              = 1U << HZB_TOWN_INNER_SUBURB,
	HZ_ZON5              = 1U << HZB_TOWN_CENTRE,  ///<  center of town
	HZ_ZONALL            = 0x001F,  ///<       1F         This is just to englobe all above types at once
	HZ_SUBARTC_ABOVE     = 0x0800,  ///< 11    800        can appear in sub-arctic climate above the snow line
	HZ_TEMP              = 0x1000,  ///< 12   1000        can appear in temperate climate
	HZ_SUBARTC_BELOW     = 0x2000,  ///< 13   2000        can appear in sub-arctic climate below the snow line
	HZ_SUBTROPIC         = 0x4000,  ///< 14   4000        can appear in subtropical climate
	HZ_TOYLND            = 0x8000   ///< 15   8000        can appear in toyland climate
};
DECLARE_ENUM_AS_BIT_SET(HouseZones)

enum HouseExtraFlags {
	NO_EXTRA_FLAG            =       0,
	BUILDING_IS_HISTORICAL   = 1U << 0,  ///< this house will only appear during town generation in random games, thus the historical
	BUILDING_IS_PROTECTED    = 1U << 1,  ///< towns and AI will not remove this house, while human players will be able to
	SYNCHRONISED_CALLBACK_1B = 1U << 2,  ///< synchronized callback 1B will be performed, on multi tile houses
	CALLBACK_1A_RANDOM_BITS  = 1U << 3,  ///< callback 1A needs random bits
};

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)

	/* NewHouses properties */
	HouseID substitute_id;             ///< which original house this one is based on
	struct SpriteGroup *spritegroup;   ///< pointer to the different sprites of the house
	HouseID override;                  ///< which house this one replaces
	uint16 callback_mask;              ///< House callback flags
	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 (grf file based) @See HouseGetVariable, prop 0x44
	byte animation_frames;             ///< number of animation frames
	byte animation_speed;              ///< amount of time between each of those frames
	byte processing_time;              ///< Periodic refresh multiplier
	byte minimum_life;                 ///< The minimum number of years this house will survive before the town rebuilds it

	/* grf file related properties*/
	uint8 local_id;                    ///< id defined by the grf file for this house
	const struct GRFFile *grffile;     ///< grf file that introduced this house

	/**
	 * Get the cost for removing this house
	 * @return the cost (inflation corrected etc)
	 */
	Money GetRemovalCost() const;

	static FORCEINLINE HouseSpec *Get(size_t house_id)
	{
		assert(house_id < HOUSE_MAX);
		extern HouseSpec _house_specs[];
		return &_house_specs[house_id];
	}
};

#endif /* HOUSE_H */