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