1 /*
2  * Copyright (c) 1997 - 2001 Hansj�rg Malthaner
3  *
4  * This file is part of the Simutrans project under the artistic licence.
5  * (see licence.txt)
6  */
7 
8 #ifndef boden_wege_weg_h
9 #define boden_wege_weg_h
10 
11 #include "../../display/simimg.h"
12 #include "../../simtypes.h"
13 #include "../../simobj.h"
14 #include "../../descriptor/way_desc.h"
15 #include "../../dataobj/koord3d.h"
16 
17 
18 class karte_t;
19 class way_desc_t;
20 class cbuffer_t;
21 template <class T> class slist_tpl;
22 
23 
24 // maximum number of months to store information
25 #define MAX_WAY_STAT_MONTHS 2
26 
27 // number of different statistics collected
28 #define MAX_WAY_STATISTICS 2
29 
30 enum way_statistics {
31 	WAY_STAT_GOODS   = 0, ///< number of goods transported over this way
32 	WAY_STAT_CONVOIS = 1  ///< number of convois that passed this way
33 };
34 
35 
36 /**
37  * <p>Der Weg ist die Basisklasse fuer alle Verkehrswege in Simutrans.
38  * Wege "geh�ren" immer zu einem Grund. Sie besitzen Richtungsbits sowie
39  * eine Maske fuer Richtungsbits.</p>
40  *
41  * <p>Ein Weg geh�rt immer zu genau einer Wegsorte</p>
42  *
43  * <p>Kreuzungen werden dadurch unterst�tzt, da� ein Grund zwei Wege
44  * enthalten kann (prinzipiell auch mehrere m�glich.</p>
45  *
46  * <p>Wegtyp -1 ist reserviert und kann nicht f�r Wege benutzt werden<p>
47  *
48  * @author Hj. Malthaner
49  */
50 class weg_t : public obj_no_info_t
51 {
52 public:
53 	/**
54 	* Get list of all ways
55 	* @author Hj. Malthaner
56 	*/
57 	static const slist_tpl <weg_t *> & get_alle_wege();
58 
59 	enum {
60 		HAS_SIDEWALK   = 0x01,
61 		IS_ELECTRIFIED = 0x02,
62 		HAS_SIGN       = 0x04,
63 		HAS_SIGNAL     = 0x08,
64 		HAS_WAYOBJ     = 0x10,
65 		HAS_CROSSING   = 0x20,
66 		IS_DIAGONAL    = 0x40, // marker for diagonal image
67 		IS_SNOW = 0x80	// marker, if above snowline currently
68 	};
69 
70 private:
71 	/**
72 	* array for statistical values
73 	* MAX_WAY_STAT_MONTHS: [0] = actual value; [1] = last month value
74 	* MAX_WAY_STATISTICS: see #define at top of file
75 	* @author hsiegeln
76 	*/
77 	sint16 statistics[MAX_WAY_STAT_MONTHS][MAX_WAY_STATISTICS];
78 
79 	/**
80 	* Way type description
81 	* @author Hj. Malthaner
82 	*/
83 	const way_desc_t * desc;
84 
85 	/**
86 	* Richtungsbits f�r den Weg. Norden ist oben rechts auf dem Monitor.
87 	* 1=Nord, 2=Ost, 4=Sued, 8=West
88 	* @author Hj. Malthaner
89 	*/
90 	uint8 ribi:4;
91 
92 	/**
93 	* Mask for ribi (Richtungsbits => Direction Bits)
94 	* @author Hj. Malthaner
95 	*/
96 	uint8 ribi_maske:4;
97 
98 	/**
99 	* flags like walkway, electrification, road sings
100 	* @author Hj. Malthaner
101 	*/
102 	uint8 flags;
103 
104 	/**
105 	* max speed; could not be taken for desc, since other object may modify the speed
106 	* @author Hj. Malthaner
107 	*/
108 	uint16 max_speed;
109 
110 	image_id image;
111 	image_id foreground_image;
112 
113 	/**
114 	* Initializes all member variables
115 	* @author Hj. Malthaner
116 	*/
117 	void init();
118 
119 	/**
120 	* initializes statistic array
121 	* @author hsiegeln
122 	*/
123 	void init_statistics();
124 
125 protected:
126 
127 	enum image_type { image_flat, image_slope, image_diagonal, image_switch };
128 
129 	/**
130 	 * initializes both front and back images
131 	 * switch images are set in schiene_t::reserve
132 	 */
133 	void set_images(image_type typ, uint8 ribi, bool snow, bool switch_nw=false);
134 
135 public:
weg_t(loadsave_t *)136 	weg_t(loadsave_t*) : obj_no_info_t() { init(); }
weg_t()137 	weg_t() : obj_no_info_t() { init(); }
138 
139 	virtual ~weg_t();
140 
141 #ifdef MULTI_THREAD
142 	void lock_mutex();
143 	void unlock_mutex();
144 #endif
145 
146 	/**
147 	 * Actual image recalculation
148 	 */
149 	void calc_image() OVERRIDE;
150 
151 	/**
152 	 * Called whenever the season or snowline height changes
153 	 * return false and the obj_t will be deleted
154 	 */
155 	bool check_season(const bool calc_only_season_change) OVERRIDE;
156 
157 	/**
158 	* Setzt die erlaubte H�chstgeschwindigkeit
159 	* @author Hj. Malthaner
160 	*/
set_max_speed(sint32 s)161 	void set_max_speed(sint32 s) { max_speed = s; }
162 
163 	/**
164 	* Ermittelt die erlaubte H�chstgeschwindigkeit
165 	* @author Hj. Malthaner
166 	*/
get_max_speed()167 	sint32 get_max_speed() const { return max_speed; }
168 
169 	/**
170 	* Setzt neue Description. Ersetzt alte H�chstgeschwindigkeit
171 	* mit wert aus Description.
172 	* @author Hj. Malthaner
173 	*/
174 	void set_desc(const way_desc_t *b);
get_desc()175 	const way_desc_t *get_desc() const { return desc; }
176 
177 	// returns a way with the matching type
178 	static weg_t *alloc(waytype_t wt);
179 
180 	// returns a string with the "official name of the waytype"
181 	static const char *waytype_to_string(waytype_t wt);
182 
183 	void rdwr(loadsave_t *file) OVERRIDE;
184 
185 	/**
186 	* Info-text for this way
187 	* @author Hj. Malthaner
188 	*/
189 	void info(cbuffer_t & buf) const OVERRIDE;
190 
191 	/**
192 	 * @return NULL if OK, otherwise an error message
193 	 * @author Hj. Malthaner
194 	 */
195 	const char *is_deletable(const player_t *player) OVERRIDE;
196 
197 	/**
198 	* Wegtyp zur�ckliefern
199 	*/
200 	waytype_t get_waytype() const OVERRIDE = 0;
201 
202 	/**
203 	* 'Jedes Ding braucht einen Typ.'
204 	* @return Gibt den typ des Objekts zur�ck.
205 	* @author Hj. Malthaner
206 	*/
get_typ()207 	typ get_typ() const OVERRIDE { return obj_t::way; }
208 
209 	/**
210 	* Die Bezeichnung des Wegs
211 	* @author Hj. Malthaner
212 	*/
get_name()213 	const char *get_name() const OVERRIDE { return desc->get_name(); }
214 
215 	/**
216 	* Add direction bits (ribi) for a way.
217 	*
218 	* Nachdem die ribis ge�ndert werden, ist das weg_image des
219 	* zugeh�rigen Grundes falsch (Ein Aufruf von grund_t::calc_image()
220 	* zur Reparatur mu� folgen).
221 	* @param ribi Richtungsbits
222 	*/
ribi_add(ribi_t::ribi ribi)223 	void ribi_add(ribi_t::ribi ribi) { this->ribi |= (uint8)ribi;}
224 
225 	/**
226 	* Remove direction bits (ribi) on a way.
227 	*
228 	* Nachdem die ribis ge�ndert werden, ist das weg_image des
229 	* zugeh�rigen Grundes falsch (Ein Aufruf von grund_t::calc_image()
230 	* zur Reparatur mu� folgen).
231 	* @param ribi Richtungsbits
232 	*/
ribi_rem(ribi_t::ribi ribi)233 	void ribi_rem(ribi_t::ribi ribi) { this->ribi &= (uint8)~ribi;}
234 
235 	/**
236 	* Set direction bits (ribi) for the way.
237 	*
238 	* Nachdem die ribis ge�ndert werden, ist das weg_image des
239 	* zugeh�rigen Grundes falsch (Ein Aufruf von grund_t::calc_image()
240 	* zur Reparatur mu� folgen).
241 	* @param ribi Richtungsbits
242 	*/
set_ribi(ribi_t::ribi ribi)243 	void set_ribi(ribi_t::ribi ribi) { this->ribi = (uint8)ribi;}
244 
245 	/**
246 	* Get the unmasked direction bits (ribi) for the way (without signals or other ribi changer).
247 	*/
get_ribi_unmasked()248 	ribi_t::ribi get_ribi_unmasked() const { return (ribi_t::ribi)ribi; }
249 
250 	/**
251 	* Get the masked direction bits (ribi) for the way (with signals or other ribi changer).
252 	*/
get_ribi()253 	ribi_t::ribi get_ribi() const { return (ribi_t::ribi)(ribi & ~ribi_maske); }
254 
255 	/**
256 	* f�r Signale ist es notwendig, bestimmte Richtungsbits auszumaskieren
257 	* damit Fahrzeuge nicht "von hinten" �ber Ampeln fahren k�nnen.
258 	* @param ribi Richtungsbits
259 	*/
set_ribi_maske(ribi_t::ribi ribi)260 	void set_ribi_maske(ribi_t::ribi ribi) { ribi_maske = (uint8)ribi; }
get_ribi_maske()261 	ribi_t::ribi get_ribi_maske() const { return (ribi_t::ribi)ribi_maske; }
262 
263 	/**
264 	 * called during map rotation
265 	 * @author priss
266 	 */
267 	void rotate90() OVERRIDE;
268 
269 	/**
270 	* book statistics - is called very often and therefore inline
271 	* @author hsiegeln
272 	*/
book(int amount,way_statistics type)273 	void book(int amount, way_statistics type) { statistics[0][type] += amount; }
274 
275 	/**
276 	* return statistics value
277 	* always returns last month's value
278 	* @author hsiegeln
279 	*/
get_statistics(int type)280 	int get_statistics(int type) const { return statistics[1][type]; }
281 
282 	/**
283 	* new month
284 	* @author hsiegeln
285 	*/
286 	void new_month();
287 
288 	void check_diagonal();
289 
290 	void count_sign();
291 
292 	/* flag query routines */
set_gehweg(const bool yesno)293 	void set_gehweg(const bool yesno) { flags = (yesno ? flags | HAS_SIDEWALK : flags & ~HAS_SIDEWALK); }
hat_gehweg()294 	inline bool hat_gehweg() const { return flags & HAS_SIDEWALK; }
295 
set_electrify(bool janein)296 	void set_electrify(bool janein) {janein ? flags |= IS_ELECTRIFIED : flags &= ~IS_ELECTRIFIED;}
is_electrified()297 	inline bool is_electrified() const {return flags&IS_ELECTRIFIED; }
298 
has_sign()299 	inline bool has_sign() const {return flags&HAS_SIGN; }
has_signal()300 	inline bool has_signal() const {return flags&HAS_SIGNAL; }
has_wayobj()301 	inline bool has_wayobj() const {return flags&HAS_WAYOBJ; }
is_crossing()302 	inline bool is_crossing() const {return flags&HAS_CROSSING; }
is_diagonal()303 	inline bool is_diagonal() const {return flags&IS_DIAGONAL; }
is_snow()304 	inline bool is_snow() const {return flags&IS_SNOW; }
305 
306 	// this is needed during a change from crossing to tram track
clear_crossing()307 	void clear_crossing() { flags &= ~HAS_CROSSING; }
308 
309 	/**
310 	 * Clear the has-sign flag when roadsign or signal got deleted.
311 	 * As there is only one of signal or roadsign on the way we can safely clear both flags.
312 	 */
clear_sign_flag()313 	void clear_sign_flag() { flags &= ~(HAS_SIGN | HAS_SIGNAL); }
314 
set_image(image_id b)315 	inline void set_image( image_id b ) { image = b; }
get_image()316 	image_id get_image() const OVERRIDE {return image;}
317 
set_foreground_image(image_id b)318 	inline void set_foreground_image( image_id b ) { foreground_image = b; }
get_front_image()319 	image_id get_front_image() const OVERRIDE {return foreground_image;}
320 
321 
322 	// correct maintenance
323 	void finish_rd() OVERRIDE;
324 } GCC_PACKED;
325 
326 #endif
327