1 /* 2 * Copyright (c) 1997 - 2002 by Volker Meyer & Hansj�rg Malthaner 3 * 4 * This file is part of the Simutrans project under the artistic licence. 5 */ 6 7 #ifndef __BUILDING_DESC_H 8 #define __BUILDING_DESC_H 9 10 #include <assert.h> 11 #include "image_array.h" 12 #include "obj_base_desc.h" 13 #include "skin_desc.h" 14 #include "../dataobj/koord.h" 15 16 class building_desc_t; 17 class tool_t; 18 class karte_t; 19 class checksum_t; 20 21 /* 22 * Author: 23 * Volker Meyer 24 * 25 * Description: 26 * Data for one tile of a potentially multi-tile building. 27 * 28 * Child nodes: 29 * 0 Imagelist2D season 0 back 30 * 1 Imagelist2D season 0 front 31 * 2 Imagelist2D season 1 back 32 * 3 Imagelist2D season 1 front 33 * ... ... 34 */ 35 class building_tile_desc_t : public obj_desc_t { 36 friend class tile_reader_t; 37 38 const building_desc_t *building; 39 40 uint8 seasons; 41 uint8 phases; ///< number of animation phases 42 uint16 index; 43 44 public: set_desc(const building_desc_t * building_desc)45 void set_desc(const building_desc_t *building_desc) { building = building_desc; } 46 get_desc()47 const building_desc_t *get_desc() const { return building; } 48 get_index()49 uint16 get_index() const { return index; } get_seasons()50 uint8 get_seasons() const { return seasons; } get_phases()51 uint8 get_phases() const { return phases; } 52 has_image()53 bool has_image() const { 54 return get_background(0,0,0)!=IMG_EMPTY || get_foreground(0,0)!=IMG_EMPTY; 55 } 56 get_background(uint16 phase,uint16 height,uint8 season)57 image_id get_background(uint16 phase, uint16 height, uint8 season) const 58 { 59 image_array_t const* const imglist = get_child<image_array_t>(0 + 2 * season); 60 if(phase>0 && phase<phases) { 61 if (image_t const* const image = imglist->get_image(height, phase)) { 62 return image->get_id(); 63 } 64 } 65 // here if this phase does not exists ... 66 image_t const* const image = imglist->get_image(height, 0); 67 return image != NULL ? image->get_id() : IMG_EMPTY; 68 } 69 70 // returns true, if the background is animated is_background_animated(uint8 season)71 bool is_background_animated(uint8 season) const 72 { 73 image_array_t const* const imglist = get_child<image_array_t>(0 + 2 * season); 74 const uint16 max_h = imglist->get_count(); 75 for( uint16 phase=1; phase<phases; phase++ ) { 76 for( uint16 h=0; h<max_h; h++ ) { 77 if( imglist->get_image( h, phase ) ) { 78 return true; 79 } 80 } 81 } 82 return false; 83 } 84 get_foreground(uint16 phase,uint8 season)85 image_id get_foreground(uint16 phase, uint8 season) const 86 { 87 image_array_t const* const imglist = get_child<image_array_t>(1 + 2 * season); 88 if(phase>0 && phase<phases) { 89 if (image_t const* const image = imglist->get_image(0, phase)) { 90 return image->get_id(); 91 } 92 } 93 // here if this phase does not exists ... 94 image_t const* const image = imglist->get_image(0, 0); 95 return image != NULL ? image->get_id() : IMG_EMPTY; 96 } 97 98 koord get_offset() const; 99 100 uint8 get_layout() const; 101 }; 102 103 /* 104 * Author: 105 * Volker Meyer 106 * 107 * Description: 108 * Data for one building, consists of potentially more than one tile. 109 * 110 * Child nodes: 111 * 0 Name 112 * 1 Copyright 113 * 2 Tile 1 114 * 3 Tile 2 115 * ... ... 116 */ 117 class building_desc_t : public obj_desc_timelined_t { 118 friend class building_reader_t; 119 120 public: 121 /** 122 * Building types 123 */ 124 enum btype 125 { 126 unknown = 0, 127 attraction_city = 1, 128 attraction_land = 2, 129 monument = 3, 130 factory = 4, 131 townhall = 5, 132 others = 6, ///< monorail foundation 133 headquarters = 7, 134 dock = 11, ///< dock, build on sloped coast 135 // in these, the extra data points to a waytype 136 depot = 33, 137 generic_stop = 34, 138 generic_extension = 35, 139 flat_dock = 36, ///< dock, but can start on a flat coast line 140 // city buildings 141 city_res = 37, ///< residential city buildings 142 city_com = 38, ///< commercial city buildings 143 city_ind = 39, ///< industrial city buildings 144 }; 145 146 147 enum flag_t { 148 FLAG_NULL = 0, 149 FLAG_NO_INFO = 1, ///< do not show info window 150 FLAG_NO_PIT = 2, ///< do not show construction pit 151 FLAG_NEED_GROUND = 4, ///< needs ground drawn below 152 FLAG_HAS_CURSOR = 8 ///< there is cursor/icon for this 153 }; 154 private: 155 /** 156 * Old named constants, only used for compatibility to load very old paks. 157 * These will be converted in building_reader_t::register_obj to a valid btype. 158 */ 159 enum old_building_types_t { 160 bahnhof = 8, 161 bushalt = 9, 162 ladebucht = 10, 163 binnenhafen = 12, 164 airport = 13, 165 monorailstop = 14, 166 bahnhof_geb = 16, 167 bushalt_geb = 17, 168 ladebucht_geb = 18, 169 hafen_geb = 19, 170 binnenhafen_geb = 20, 171 airport_geb = 21, 172 monorail_geb = 22, 173 wartehalle = 30, 174 mail = 31, 175 lagerhalle = 32, 176 }; 177 178 building_desc_t::btype type; 179 uint16 animation_time; // in ms 180 uint32 extra_data; 181 // extra data: 182 // minimum population to build for city attractions, 183 // waytype for depots 184 // player level for headquarters 185 // cluster number for city buildings (0 means no clustering) 186 koord size; 187 flag_t flags; 188 uint16 level; // or passengers; 189 uint8 layouts; // 1 2, 4, 8 or 16 190 uint8 enables; // if it is a stop, what is enabled ... 191 uint8 distribution_weight; // Hajo: chance to build, special buildings, only other is weight factor 192 193 194 /** @author: jamespetts. 195 * Additional fields for separate capacity/maintenance 196 * If these are not specified in the .dat file, they are set to 197 * PRICE_MAGIC then calculated from the "level" in the old way. 198 */ 199 200 sint32 price; 201 sint32 maintenance; 202 uint16 capacity; 203 204 #define PRICE_MAGIC (2147483647) 205 206 207 climate_bits allowed_climates; 208 209 /** 210 * Whether this building can or must be built underground. 211 * Only relevant for stations (generic_stop). 212 * 0 = cannot be built underground 213 * 1 = can only be built underground 214 * 2 = can be built either underground or above ground. 215 */ 216 uint8 allow_underground; 217 is_type(building_desc_t::btype u)218 bool is_type(building_desc_t::btype u) const { 219 return type == u; 220 } 221 222 tool_t *builder; 223 224 public: 225 226 koord get_size(uint8 layout = 0) const { 227 return (layout & 1) ? koord(size.y, size.x) : size; 228 } 229 230 // size of the building 231 sint16 get_y(uint8 layout = 0) const { 232 return (layout & 1) ? size.x: size.y; 233 } 234 235 sint16 get_x(uint8 layout = 0) const { 236 return (layout & 1) ? size.y : size.x; 237 } 238 get_all_layouts()239 uint8 get_all_layouts() const { return layouts; } 240 get_extra()241 uint32 get_extra() const { return extra_data; } 242 243 /** Returns waytype used for finance stats (distinguishes between tram track and train track) */ 244 waytype_t get_finance_waytype() const; 245 246 // ground is transparent needs_ground()247 bool needs_ground() const { return (flags & FLAG_NEED_GROUND) != 0; } 248 249 // no construction stage no_construction_pit()250 bool no_construction_pit() const { return (flags & FLAG_NO_PIT) != 0; } 251 252 // do not open info for this no_info_window()253 bool no_info_window() const { return (flags & FLAG_NO_INFO) != 0; } 254 get_type()255 building_desc_t::btype get_type() const { return type; } 256 is_townhall()257 bool is_townhall() const { return is_type(townhall); } is_headquarters()258 bool is_headquarters() const { return is_type(headquarters); } is_attraction()259 bool is_attraction() const { return is_type(attraction_land) || is_type(attraction_city); } is_factory()260 bool is_factory() const { return is_type(factory); } is_city_building()261 bool is_city_building() const { return is_type(city_res) || is_type(city_com) || is_type(city_ind); } is_transport_building()262 bool is_transport_building() const { return type > headquarters && type <= flat_dock; } is_depot()263 bool is_depot() const { return is_type(depot); } 264 265 bool is_connected_with_town() const; 266 267 /// @returns headquarters level (or -1 if building is not headquarters) get_headquarters_level()268 sint32 get_headquarters_level() const { return (is_headquarters() ? get_extra() : -1) ; } 269 270 /** 271 * the level is used in many places: for price, for capacity, ... 272 * @author Hj. Malthaner 273 */ get_level()274 uint16 get_level() const { return level; } 275 276 /** 277 * Mail generation level 278 * @author Hj. Malthaner 279 */ 280 uint16 get_mail_level() const; 281 282 // how often will this appear get_distribution_weight()283 uint8 get_distribution_weight() const { return distribution_weight; } 284 get_tile(uint16 index)285 const building_tile_desc_t *get_tile(uint16 index) const { 286 assert(index < layouts * size.x * size.y); 287 return get_child<building_tile_desc_t>(index + 2); 288 } 289 290 const building_tile_desc_t *get_tile(uint8 layout, sint16 x, sint16 y) const; 291 292 // returns true,if building can be rotated can_rotate()293 bool can_rotate() const { 294 if(size.x!=size.y && layouts==1) { 295 return false; 296 } 297 // check for missing tiles after rotation 298 for( sint16 x=0; x<size.x; x++ ) { 299 for( sint16 y=0; y<size.y; y++ ) { 300 // only true, if one is missing 301 if(get_tile( 0, x, y )->has_image() ^ get_tile( 1, get_x(1)-y-1, x )->has_image()) { 302 return false; 303 } 304 } 305 } 306 return true; 307 } 308 309 uint8 adjust_layout(uint8 layout) const; 310 311 /** 312 * Skin: cursor (index 0) and icon (index 1) 313 * @author Hj. Malthaner 314 */ get_cursor()315 const skin_desc_t * get_cursor() const { 316 return flags & FLAG_HAS_CURSOR ? get_child<skin_desc_t>(2 + size.x * size.y * layouts) : 0; 317 } 318 319 // the right house for this area? is_allowed_climate(climate cl)320 bool is_allowed_climate( climate cl ) const { return ((1<<cl)&allowed_climates)!=0; } 321 322 // the right house for this area? is_allowed_climate_bits(climate_bits cl)323 bool is_allowed_climate_bits( climate_bits cl ) const { return (cl&allowed_climates)!=0; } 324 325 // needed by place_finder get_allowed_climate_bits()326 climate_bits get_allowed_climate_bits() const { return allowed_climates; } 327 328 /** 329 * @return station flags (only used for station buildings and oil rigs) 330 * @author prissi 331 */ get_enabled()332 uint8 get_enabled() const { return enables; } 333 334 /** 335 * @return time for doing one step 336 * @author prissi 337 */ get_animation_time()338 uint16 get_animation_time() const { return animation_time; } 339 340 /** 341 * @see above for maintenance/price/capacity variable information 342 * @author Kieron Green/jamespetts 343 */ 344 sint32 get_maintenance(karte_t *world) const; 345 sint32 get_price(karte_t *world) const; get_capacity()346 uint16 get_capacity() const { return capacity; } 347 348 349 // default tool for building get_builder()350 tool_t *get_builder() const { 351 return builder; 352 } set_builder(tool_t * tool)353 void set_builder( tool_t *tool ) { 354 builder = tool; 355 } 356 357 void calc_checksum(checksum_t *chk) const; 358 can_be_built_underground()359 bool can_be_built_underground() const { return allow_underground > 0; } can_be_built_aboveground()360 bool can_be_built_aboveground() const { return allow_underground != 1; } 361 get_clusters()362 uint32 get_clusters() const { 363 // Only meaningful for res, com, ind 364 return is_city_building() ? extra_data : 0; 365 } 366 }; 367 368 ENUM_BITSET(building_desc_t::flag_t) 369 370 #endif 371