1 /*
2  * Copyright (c) 1997 - 2001 Hansj�rg Malthaner
3  *
4  * This file is part of the Simutrans project under the artistic license.
5  * (see license.txt)
6  */
7 
8 #ifndef simplan_h
9 #define simplan_h
10 
11 #include "halthandle_t.h"
12 #include "boden/grund.h"
13 
14 
15 class karte_ptr_t;
16 class grund_t;
17 class obj_t;
18 
19 class planquadrat_t;
20 void swap(planquadrat_t& a, planquadrat_t& b);
21 
22 
23 /**
24  * Die Karte ist aus Planquadraten zusammengesetzt.
25  * Planquadrate speichern Untergr�nde (B�den) der Karte.
26  * @author Hj. Malthaner
27  */
28 class planquadrat_t
29 {
30 	static karte_ptr_t welt;
31 private:
32 	/* list of stations that are reaching to this tile (saves lots of time for lookup) */
33 	halthandle_t *halt_list;
34 
35 	uint8 ground_size, halt_list_count;
36 
37 	// stores climate related settings
38 	uint8 climate_data;
39 
40 	union DATA {
41 		grund_t ** some;    // valid if capacity > 1
42 		grund_t * one;      // valid if capacity == 1
43 	} data;
44 
45 public:
46 	/**
47 	 * Constructs a planquadrat (tile) with initial capacity of one ground
48 	 * @author Hansj�rg Malthaner
49 	 */
planquadrat_t()50 	planquadrat_t() { ground_size = 0; climate_data = 0; data.one = NULL; halt_list_count = 0;  halt_list = NULL; }
51 
52 	~planquadrat_t();
53 
54 private:
55 	planquadrat_t(planquadrat_t const&);
56 	planquadrat_t& operator=(planquadrat_t const&);
57 	friend void swap(planquadrat_t& a, planquadrat_t& b);
58 
59 public:
60 	/**
61 	* Setzen des "normalen" Bodens auf Kartenniveau
62 	* @author V. Meyer
63 	*/
64 	void kartenboden_setzen(grund_t *bd, bool startup = false);
65 
66 	/**
67 	* Ersetzt Boden alt durch neu, l�scht Boden alt.
68 	* @author Hansj�rg Malthaner
69 	*/
70 	void boden_ersetzen(grund_t *alt, grund_t *neu);
71 
72 	/**
73 	* Setzen einen Br�cken- oder Tunnelbodens
74 	* @author V. Meyer
75 	*/
76 	void boden_hinzufuegen(grund_t *bd);
77 
78 	/**
79 	* L�schen eines Br�cken- oder Tunnelbodens
80 	* @author V. Meyer
81 	*/
82 	bool boden_entfernen(grund_t *bd);
83 
84 	/**
85 	* Return either ground tile in this height or NULL if not existing
86 	* Inline, since called from karte_t::lookup() and thus extremely often
87 	* @return NULL if not ground in this height
88 	* @author Hj. Malthaner
89 	*/
get_boden_in_hoehe(const sint16 z)90 	inline grund_t *get_boden_in_hoehe(const sint16 z) const {
91 		if(ground_size==1) {
92 			// must be valid ground at this point!
93 			if(  data.one->get_hoehe() == z  ) {
94 				return data.one;
95 			}
96 		}
97 		else {
98 			for(  uint8 i = 0;  i < ground_size;  i++  ) {
99 				if(  data.some[i]->get_hoehe() == z  ) {
100 					return data.some[i];
101 				}
102 			}
103 		}
104 		return NULL;
105 	}
106 
107 	/**
108 	* returns normal ground (always first index)
109 	* @return not defined if no ground (must not happen!)
110 	* @author Hansj�rg Malthaner
111 	*/
get_kartenboden()112 	inline grund_t *get_kartenboden() const { return (ground_size<=1) ? data.one : data.some[0]; }
113 
114 	/**
115 	* find ground if thing is on this planquadrat (tile)
116 	* @return grund_t * with thing or NULL
117 	* @author V. Meyer
118 	*/
119 	grund_t *get_boden_von_obj(obj_t *obj) const;
120 
121 	/**
122 	* ground saved at index position idx (zero would be normal ground)
123 	* Since it is always called from loops or with other checks, no
124 	* range check is done => if only one ground, range is ignored!
125 	* @return ground at idx, undefined if ground_size==NULL
126 	* @author Hj. Malthaner
127 	*/
get_boden_bei(const unsigned idx)128 	inline grund_t *get_boden_bei(const unsigned idx) const { return (ground_size<=1 ? data.one : data.some[idx]); }
129 
130 	/**
131 	* @return Anzahl der B�den dieses Planquadrats
132 	* @author Hj. Malthaner
133 	*/
get_boden_count()134 	unsigned int get_boden_count() const { return ground_size; }
135 
136 	/**
137 	* returns climate of plan (lowest 3 bits of climate byte)
138 	* @author Kieron Green
139 	*/
get_climate()140 	inline climate get_climate() const { return (climate)(climate_data & 7); }
141 
142 	/**
143 	* sets plan climate
144 	* @author Kieron Green
145 	*/
set_climate(climate cl)146 	void set_climate(climate cl) {
147 		climate_data = (climate_data & 0xf8) + (cl & 7);
148 	}
149 
150 	/**
151 	* returns whether this is a transition to next climate (which will then use calculated image rather than overlay)
152 	* @author Kieron Green
153 	*/
get_climate_transition_flag()154 	inline bool get_climate_transition_flag() const { return (climate_data >> 3) & 1; }
155 
156 	/**
157 	* set whether this is a transition to next climate (which will then use calculated image rather than overlay)
158 	* @author Kieron Green
159 	*/
set_climate_transition_flag(bool flag)160 	void set_climate_transition_flag(bool flag) {
161 		climate_data = flag ? (climate_data | 0x08) : (climate_data & 0xf7);
162 	}
163 
164 	/**
165 	* returns corners which transition to another climate
166 	* this has no meaning if tile is a slope with transition to next climate as these corners are fixed
167 	* therefore for this case to allow double heights 0 = first level transition, 1 = second level transition
168 	* @author Kieron Green
169 	*/
get_climate_corners()170 	inline uint8 get_climate_corners() const { return (climate_data >> 4) & 15; }
171 
172 	/**
173 	* sets climate transition corners
174 	* this has no meaning if tile is a slope with transition to next climate as these corners are fixed
175 	* therefore for this case to allow double heights 0 = first level transition, 1 = second level transition
176 	* @author Kieron Green
177 	*/
set_climate_corners(uint8 corners)178 	void set_climate_corners(uint8 corners) {
179 		climate_data = (climate_data & 0x0f) + (corners << 4);
180 	}
181 
182 	/**
183 	* converts boden to correct type, land or water
184 	* @author Kieron Green
185 	*/
186 	void correct_water();
187 
188 	/**
189 	* konvertiert Land zu Water wenn unter Grundwasserniveau abgesenkt
190 	* @author Hj. Malthaner
191 	*/
192 	void abgesenkt();
193 
194 	/**
195 	* Converts water to land when raised above the ground water level
196 	* @author Hj. Malthaner
197 	*/
198 	void angehoben();
199 
200 	/**
201 	* returns halthandle belonging to player if present
202 	* @return NULL if no halt present
203 	* @author Kieron Green
204 	*/
205 	halthandle_t get_halt(player_t *player) const;
206 
207 private:
208 	// these functions are private helper functions for halt_list corrections
209 	void halt_list_remove( halthandle_t halt );
210 	void halt_list_insert_at( halthandle_t halt, uint8 pos );
211 
212 public:
213 	/**
214 	 * The following three functions takes about 4 bytes of memory per tile but speed up passenger generation
215 	 * @author prissi
216 	 * @param unsorted if true then halt list will be sorted later by call to sort_haltlist, see karte_t::plans_finish_rd.
217 	 */
218 	void add_to_haltlist(halthandle_t halt, bool unsorted = false);
219 
220 	/**
221 	* removes the halt from a ground
222 	* however this function check, whether there is really no other part still reachable
223 	* @author prissi
224 	*/
225 	void remove_from_haltlist(halthandle_t halt);
226 
227 	/**
228 	 * sort list of connected halts, ascending wrt distance to this tile
229 	 */
230 	void sort_haltlist();
231 
232 
233 	bool is_connected(halthandle_t halt) const;
234 
235 	/**
236 	* returns the internal array of halts
237 	* @author prissi
238 	*/
get_haltlist()239 	const halthandle_t *get_haltlist() const { return halt_list; }
get_haltlist_count()240 	uint8 get_haltlist_count() const { return halt_list_count; }
241 
242 	void rdwr(loadsave_t *file, koord pos );
243 
244 	/**
245 	* Updates season and/or snowline dependent graphics
246 	*/
247 	void check_season_snowline(const bool season_change, const bool snowline_change);
248 
249 	void display_obj(const sint16 xpos, const sint16 ypos, const sint16 raster_tile_width, const bool is_global, const sint8 hmin, const sint8 hmax  CLIP_NUM_DEF) const;
250 
251 	void display_overlay(sint16 xpos, sint16 ypos) const;
252 
253 	static void toggle_horizontal_clip(CLIP_NUM_DEF0);
254 
255 	/**
256 	 * @brief Update this square for underground view.
257 	 *
258 	 * Updates this square for underground view. This includes calculating
259 	 * calculating new back will images as well as water depth texture.
260 	 *
261 	 * This method does not modify this square object, but does modify the
262 	 * grounds it references.
263 	 */
264 	void update_underground() const;
265 };
266 
267 #endif
268