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 /* 9 * Vehicle base type. 10 */ 11 12 #ifndef SIMVEHICLE_H 13 #define SIMVEHICLE_H 14 15 #include "../simtypes.h" 16 #include "../simobj.h" 17 #include "../halthandle_t.h" 18 #include "../convoihandle_t.h" 19 #include "../ifc/simtestdriver.h" 20 #include "../boden/grund.h" 21 #include "../descriptor/vehicle_desc.h" 22 #include "../vehicle/overtaker.h" 23 #include "../tpl/slist_tpl.h" 24 25 class convoi_t; 26 class schedule_t; 27 class signal_t; 28 class ware_t; 29 class route_t; 30 31 /*----------------------- Movables ------------------------------------*/ 32 33 /** 34 * Base class for all vehicles 35 * 36 * @author Hj. Malthaner 37 */ 38 class vehicle_base_t : public obj_t 39 { 40 protected: 41 // offsets for different directions 42 static sint8 dxdy[16]; 43 44 // to make the length on diagonals configurable 45 // Number of vehicle steps along a diagonal... 46 // remember to subtract one when stepping down to 0 47 static uint8 diagonal_vehicle_steps_per_tile; 48 static uint8 old_diagonal_vehicle_steps_per_tile; 49 static uint16 diagonal_multiplier; 50 51 // [0]=xoff [1]=yoff 52 static sint8 driveleft_base_offsets[8][2]; 53 static sint8 overtaking_base_offsets[8][2]; 54 55 /** 56 * Actual travel direction in screen coordinates 57 * @author Hj. Malthaner 58 */ 59 ribi_t::ribi direction; 60 61 // true on slope (make calc_height much faster) 62 uint8 use_calc_height:1; 63 64 /** 65 * Thing is moving on this lane. 66 * Possible values: 67 * (Back) 68 * 0 - sidewalk (going on the right side to w/sw/s) 69 * 1 - road (going on the right side to w/sw/s) 70 * 2 - middle (everything with waytype != road) 71 * 3 - road (going on the right side to se/e/../nw) 72 * 4 - sidewalk (going on the right side to se/e/../nw) 73 * (Front) 74 */ 75 uint8 disp_lane:3; 76 77 sint8 dx, dy; 78 79 // number of steps in this tile (255 per tile) 80 uint8 steps, steps_next; 81 82 /** 83 * Next position on our path 84 * @author Hj. Malthaner 85 */ 86 koord3d pos_next; 87 88 /** 89 * Offsets for uphill/downhill. 90 * Have to be multiplied with -TILE_HEIGHT_STEP/2. 91 * To obtain real z-offset, interpolate using steps, steps_next. 92 */ 93 uint8 zoff_start:4, zoff_end:4; 94 95 // cached image 96 image_id image; 97 98 /** 99 * Vehicle movement: check whether this vehicle can enter the next tile (pos_next). 100 * @returns NULL if check fails, otherwise pointer to the next tile 101 */ 102 virtual grund_t* hop_check() = 0; 103 104 /** 105 * Vehicle movement: change tiles, calls leave_tile and enter_tile. 106 * @param gr pointer to ground of new position (never NULL) 107 */ 108 virtual void hop(grund_t* gr) = 0; 109 110 void calc_image() OVERRIDE = 0; 111 112 // check for road vehicle, if next tile is free 113 vehicle_base_t *no_cars_blocking( const grund_t *gr, const convoi_t *cnv, const uint8 current_direction, const uint8 next_direction, const uint8 next_90direction ); 114 115 // only needed for old way of moving vehicles to determine position at loading time 116 bool is_about_to_hop( const sint8 neu_xoff, const sint8 neu_yoff ) const; 117 118 public: 119 // only called during load time: set some offsets 120 static void set_diagonal_multiplier( uint32 multiplier, uint32 old_multiplier ); get_diagonal_multiplier()121 static uint16 get_diagonal_multiplier() { return diagonal_multiplier; } get_diagonal_vehicle_steps_per_tile()122 static uint8 get_diagonal_vehicle_steps_per_tile() { return diagonal_vehicle_steps_per_tile; } 123 124 static void set_overtaking_offsets( bool driving_on_the_left ); 125 126 // if true, this convoi needs to restart for correct alignment 127 bool need_realignment() const; 128 129 uint32 do_drive(uint32 dist); // basis movement code 130 set_image(image_id b)131 inline void set_image( image_id b ) { image = b; } get_image()132 image_id get_image() const OVERRIDE {return image;} 133 134 sint16 get_hoff(const sint16 raster_width=1) const; get_steps()135 uint8 get_steps() const {return steps;} 136 get_disp_lane()137 uint8 get_disp_lane() const { return disp_lane; } 138 139 // to make smaller steps than the tile granularity, we have to calculate our offsets ourselves! 140 virtual void get_screen_offset( int &xoff, int &yoff, const sint16 raster_width ) const; 141 142 /** 143 * Vehicle movement: calculates z-offset of vehicles on slopes, 144 * handles vehicles that are invisible in tunnels. 145 * @param gr vehicle is on this ground 146 * @note has to be called after loading to initialize z-offsets 147 */ 148 void calc_height(grund_t *gr = NULL); 149 150 void rotate90() OVERRIDE; 151 152 template<class K1, class K2> calc_direction(const K1 & from,const K2 & to)153 static ribi_t::ribi calc_direction(const K1& from, const K2& to) 154 { 155 return ribi_type(from, to); 156 } 157 158 ribi_t::ribi calc_set_direction(const koord3d& start, const koord3d& ende); 159 get_direction()160 ribi_t::ribi get_direction() const {return direction;} 161 get_pos_next()162 koord3d get_pos_next() const {return pos_next;} 163 164 waytype_t get_waytype() const OVERRIDE = 0; 165 166 // true, if this vehicle did not moved for some time is_stuck()167 virtual bool is_stuck() { return true; } 168 169 /** 170 * Vehicle movement: enter tile, add this to the ground. 171 * @pre position (obj_t::pos) needs to be updated prior to calling this functions 172 * @return pointer to ground (never NULL) 173 */ 174 virtual void enter_tile(grund_t*); 175 176 /** 177 * Vehicle movement: leave tile, release reserved crossing, remove vehicle from the ground. 178 */ 179 virtual void leave_tile(); 180 get_overtaker()181 virtual overtaker_t *get_overtaker() { return NULL; } 182 183 vehicle_base_t(); 184 185 vehicle_base_t(koord3d pos); 186 is_flying()187 virtual bool is_flying() const { return false; } 188 }; 189 190 191 template<> inline vehicle_base_t* obj_cast<vehicle_base_t>(obj_t* const d) 192 { 193 return d->is_moving() ? static_cast<vehicle_base_t*>(d) : 0; 194 } 195 196 197 /** 198 * Class for all vehicles with route 199 * 200 * @author Hj. Malthaner 201 */ 202 203 class vehicle_t : public vehicle_base_t, public test_driver_t 204 { 205 private: 206 /** 207 * Date of purchase in months 208 * @author Hj. Malthaner 209 */ 210 sint32 purchase_time; 211 212 /* For the more physical acceleration model friction is introduced 213 * frictionforce = gamma*speed*weight 214 * since the total weight is needed a lot of times, we save it 215 * @author prissi 216 */ 217 uint32 sum_weight; 218 219 grund_t* hop_check() OVERRIDE; 220 221 /** 222 * Calculate friction caused by slopes and curves. 223 */ 224 virtual void calc_friction(const grund_t *gr); 225 226 protected: 227 void hop(grund_t*) OVERRIDE; 228 229 // current limit (due to track etc.) 230 sint32 speed_limit; 231 232 ribi_t::ribi previous_direction; 233 234 // for target reservation and search 235 halthandle_t target_halt; 236 237 /* The friction is calculated new every step, so we save it too 238 * @author prissi 239 */ 240 sint16 current_friction; 241 242 /** 243 * Current index on the route 244 * @author Hj. Malthaner 245 */ 246 uint16 route_index; 247 248 uint16 total_freight; // since the sum is needed quite often, it is cached 249 slist_tpl<ware_t> fracht; // list of goods being transported 250 251 const vehicle_desc_t *desc; 252 253 convoi_t *cnv; // != NULL if the vehicle is part of a Convoi 254 255 bool leading:1; // true, if vehicle is first vehicle of a convoi 256 bool last:1; // true, if vehicle is last vehicle of a convoi 257 bool smoke:1; 258 bool check_for_finish:1; // true, if on the last tile 259 bool has_driven:1; 260 check_next_tile(const grund_t *)261 bool check_next_tile(const grund_t* ) const OVERRIDE {return false;} 262 263 public: 264 void calc_image() OVERRIDE; 265 266 // the coordinates, where the vehicle was loaded the last time 267 koord3d last_stop_pos; 268 get_convoi()269 convoi_t *get_convoi() const { return cnv; } 270 271 void rotate90() OVERRIDE; 272 273 274 /** 275 * Method checks whether next tile is free to move on. 276 * Looks up next tile, and calls @ref can_enter_tile(const grund_t*, sint32&, uint8). 277 */ 278 bool can_enter_tile(sint32 &restart_speed, uint8 second_check_count); 279 280 /** 281 * Method checks whether next tile is free to move on. 282 * @param gr_next next tile, must not be NULL 283 */ 284 virtual bool can_enter_tile(const grund_t *gr_next, sint32 &restart_speed, uint8 second_check_count) = 0; 285 286 void enter_tile(grund_t*) OVERRIDE; 287 288 void leave_tile() OVERRIDE; 289 290 waytype_t get_waytype() const OVERRIDE = 0; 291 292 /** 293 * Determine the direction bits for this kind of vehicle. 294 * 295 * @author Hj. Malthaner, 04.01.01 296 */ get_ribi(const grund_t * gr)297 ribi_t::ribi get_ribi(const grund_t* gr) const OVERRIDE { return gr->get_weg_ribi(get_waytype()); } 298 get_purchase_time()299 sint32 get_purchase_time() const {return purchase_time;} 300 get_smoke(bool yesno)301 void get_smoke(bool yesno ) { smoke = yesno;} 302 303 virtual bool calc_route(koord3d start, koord3d ziel, sint32 max_speed, route_t* route); get_route_index()304 uint16 get_route_index() const {return route_index;} 305 306 /** 307 * Get the base image. 308 * @author Hj. Malthaner 309 */ get_base_image()310 image_id get_base_image() const { return desc->get_base_image(); } 311 312 /** 313 * @return image with base direction and freight image taken from loaded cargo 314 */ 315 image_id get_loaded_image() const; 316 317 /** 318 * @return vehicle description object 319 * @author Hj. Malthaner 320 */ get_desc()321 const vehicle_desc_t *get_desc() const {return desc; } 322 323 /** 324 * @return die running_cost in Cr/100Km 325 * @author Hj. Malthaner 326 */ get_operating_cost()327 int get_operating_cost() const { return desc->get_running_cost(); } 328 329 /** 330 * Play sound, when the vehicle is visible on screen 331 * @author Hj. Malthaner 332 */ 333 void play_sound() const; 334 335 /** 336 * Prepare vehicle for new ride. 337 * Sets route_index, pos_next, steps_next. 338 * If @p recalc is true this sets position and recalculates/resets movement parameters. 339 * @author Hj. Malthaner 340 */ 341 void initialise_journey( uint16 start_route_index, bool recalc ); 342 343 vehicle_t(); 344 vehicle_t(koord3d pos, const vehicle_desc_t* desc, player_t* player); 345 346 ~vehicle_t(); 347 348 void make_smoke() const; 349 350 void show_info() OVERRIDE; 351 352 void info(cbuffer_t & buf) const OVERRIDE; 353 354 /* return friction constant: changes in hill and curves; may even negative downhill * 355 * @author prissi 356 */ get_frictionfactor()357 inline sint16 get_frictionfactor() const { return current_friction; } 358 359 /* Return total weight including freight (in kg!) 360 * @author prissi 361 */ get_total_weight()362 inline uint32 get_total_weight() const { return sum_weight; } 363 364 // returns speedlimit of ways (and if convoi enters station etc) 365 // the convoi takes care of the max_speed of the vehicle get_speed_limit()366 sint32 get_speed_limit() const { return speed_limit; } 367 get_cargo()368 const slist_tpl<ware_t> & get_cargo() const { return fracht;} // list of goods being transported 369 370 /** 371 * Rotate freight target coordinates, has to be called after rotating factories. 372 */ 373 void rotate90_freight_destinations(const sint16 y_size); 374 375 /** 376 * Calculate the total quantity of goods moved 377 */ get_total_cargo()378 uint16 get_total_cargo() const { return total_freight; } 379 380 /** 381 * Calculate transported cargo total weight in KG 382 * @author Hj. Malthaner 383 */ 384 uint32 get_cargo_weight() const; 385 386 /** 387 * get the type of cargo this vehicle can transport 388 */ get_cargo_type()389 const goods_desc_t* get_cargo_type() const { return desc->get_freight_type(); } 390 391 /** 392 * Get the maximum capacity 393 */ get_cargo_max()394 uint16 get_cargo_max() const {return desc->get_capacity(); } 395 396 const char * get_cargo_mass() const; 397 398 /** 399 * create an info text for the freight 400 * e.g. to display in a info window 401 * @author Hj. Malthaner 402 */ 403 void get_cargo_info(cbuffer_t & buf) const; 404 405 /** 406 * Delete all vehicle load 407 * @author Hj. Malthaner 408 */ 409 void discard_cargo(); 410 411 /** 412 * Payment is done per hop. It iterates all goods and calculates 413 * the income for the last hop. This method must be called upon 414 * every stop. 415 * @return income total for last hop 416 * @author Hj. Malthaner 417 */ 418 sint64 calc_revenue(const koord3d& start, const koord3d& end) const; 419 420 // sets or query begin and end of convois set_leading(bool janein)421 void set_leading(bool janein) {leading = janein;} is_leading()422 bool is_leading() {return leading;} 423 set_last(bool janein)424 void set_last(bool janein) {last = janein;} is_last()425 bool is_last() {return last;} 426 427 // marks the vehicle as really used set_driven()428 void set_driven() { has_driven = true; } 429 430 virtual void set_convoi(convoi_t *c); 431 432 /** 433 * Unload freight to halt 434 * @return sum of unloaded goods 435 */ 436 uint16 unload_cargo(halthandle_t halt, bool all ); 437 438 /** 439 * Load freight from halt 440 * @return amount loaded 441 */ 442 uint16 load_cargo(halthandle_t halt, const vector_tpl<halthandle_t>& destination_halts); 443 444 /** 445 * Remove freight that no longer can reach it's destination 446 * i.e. because of a changed schedule 447 * @author Hj. Malthaner 448 */ 449 void remove_stale_cargo(); 450 451 /** 452 * Generate a matching schedule for the vehicle type 453 * @author Hj. Malthaner 454 */ 455 virtual schedule_t *generate_new_schedule() const = 0; 456 457 const char *is_deletable(const player_t *player) OVERRIDE; 458 459 void rdwr(loadsave_t *file) OVERRIDE; 460 virtual void rdwr_from_convoi(loadsave_t *file); 461 462 uint32 calc_sale_value() const; 463 464 // true, if this vehicle did not moved for some time 465 bool is_stuck() OVERRIDE; 466 467 // this routine will display a tooltip for lost, on depot order, and stuck vehicles 468 #ifdef MULTI_THREAD 469 void display_overlay(int xpos, int ypos) const OVERRIDE; 470 #else 471 void display_after(int xpos, int ypos, bool dirty) const OVERRIDE; 472 #endif 473 }; 474 475 476 template<> inline vehicle_t* obj_cast<vehicle_t>(obj_t* const d) 477 { 478 return dynamic_cast<vehicle_t*>(d); 479 } 480 481 482 /** 483 * A class for road vehicles. Manages the look of the vehicles 484 * and the navigability of tiles. 485 * 486 * @author Hj. Malthaner 487 * @see vehicle_t 488 */ 489 class road_vehicle_t : public vehicle_t 490 { 491 private: 492 // called internally only from ist_weg_frei() 493 // returns true on success 494 bool choose_route(sint32 &restart_speed, ribi_t::ribi start_direction, uint16 index); 495 496 protected: 497 bool check_next_tile(const grund_t *bd) const OVERRIDE; 498 499 public: 500 void enter_tile(grund_t*) OVERRIDE; 501 502 void rotate90() OVERRIDE; 503 504 void calc_disp_lane(); 505 get_waytype()506 waytype_t get_waytype() const OVERRIDE { return road_wt; } 507 508 road_vehicle_t(loadsave_t *file, bool first, bool last); 509 road_vehicle_t(koord3d pos, const vehicle_desc_t* desc, player_t* player, convoi_t* cnv); // start and schedule 510 511 void set_convoi(convoi_t *c) OVERRIDE; 512 513 // how expensive to go here (for way search) 514 int get_cost(const grund_t *gr, const weg_t *w, const sint32 max_speed, ribi_t::ribi from) const OVERRIDE; 515 get_cost_upslope()516 uint32 get_cost_upslope() const OVERRIDE { return 15; } 517 518 bool calc_route(koord3d start, koord3d ziel, sint32 max_speed, route_t* route) OVERRIDE; 519 520 bool can_enter_tile(const grund_t *gr_next, sint32 &restart_speed, uint8 second_check_count) OVERRIDE; 521 522 // returns true for the way search to an unknown target. 523 bool is_target(const grund_t *,const grund_t *) const OVERRIDE; 524 525 // since we must consider overtaking, we use this for offset calculation 526 void get_screen_offset( int &xoff, int &yoff, const sint16 raster_width ) const OVERRIDE; 527 get_typ()528 obj_t::typ get_typ() const OVERRIDE { return road_vehicle; } 529 530 schedule_t * generate_new_schedule() const OVERRIDE; 531 532 overtaker_t* get_overtaker() OVERRIDE; 533 }; 534 535 536 /** 537 * A class for rail vehicles (trains). Manages the look of the vehicles 538 * and the navigability of tiles. 539 * 540 * @author Hj. Malthaner 541 * @see vehicle_t 542 */ 543 class rail_vehicle_t : public vehicle_t 544 { 545 protected: 546 bool check_next_tile(const grund_t *bd) const OVERRIDE; 547 548 void enter_tile(grund_t*) OVERRIDE; 549 550 bool is_signal_clear(uint16 start_index, sint32 &restart_speed); 551 bool is_pre_signal_clear(signal_t *sig, uint16 start_index, sint32 &restart_speed); 552 bool is_priority_signal_clear(signal_t *sig, uint16 start_index, sint32 &restart_speed); 553 bool is_longblock_signal_clear(signal_t *sig, uint16 start_index, sint32 &restart_speed); 554 bool is_choose_signal_clear(signal_t *sig, uint16 start_index, sint32 &restart_speed); 555 556 public: get_waytype()557 waytype_t get_waytype() const OVERRIDE { return track_wt; } 558 559 // since we might need to un-reserve previously used blocks, we must do this before calculation a new route 560 bool calc_route(koord3d start, koord3d ziel, sint32 max_speed, route_t* route) OVERRIDE; 561 562 // how expensive to go here (for way search) 563 int get_cost(const grund_t *gr, const weg_t *w, const sint32 max_speed, ribi_t::ribi from) const OVERRIDE; 564 get_cost_upslope()565 uint32 get_cost_upslope() const OVERRIDE { return 25; } 566 567 // returns true for the way search to an unknown target. 568 bool is_target(const grund_t *,const grund_t *) const OVERRIDE; 569 570 // handles all block stuff and route choosing ... 571 bool can_enter_tile(const grund_t *gr_next, sint32 &restart_speed, uint8) OVERRIDE; 572 573 // reserves or un-reserves all blocks and returns the handle to the next block (if there) 574 // returns true on successful reservation 575 bool block_reserver(const route_t *route, uint16 start_index, uint16 &next_signal, uint16 &next_crossing, int signal_count, bool reserve, bool force_unreserve ) const; 576 577 void leave_tile() OVERRIDE; 578 get_typ()579 typ get_typ() const OVERRIDE { return rail_vehicle; } 580 581 rail_vehicle_t(loadsave_t *file, bool is_first, bool is_last); 582 rail_vehicle_t(koord3d pos, const vehicle_desc_t* desc, player_t* player, convoi_t *cnv); 583 ~rail_vehicle_t(); 584 585 void set_convoi(convoi_t *c) OVERRIDE; 586 587 schedule_t * generate_new_schedule() const OVERRIDE; 588 }; 589 590 591 592 /** 593 * very similar to normal railroad, so we can implement it here completely ... 594 * @author prissi 595 * @see vehicle_t 596 */ 597 class monorail_vehicle_t : public rail_vehicle_t 598 { 599 public: get_waytype()600 waytype_t get_waytype() const OVERRIDE { return monorail_wt; } 601 602 // all handled by rail_vehicle_t monorail_vehicle_t(loadsave_t * file,bool is_first,bool is_last)603 monorail_vehicle_t(loadsave_t *file, bool is_first, bool is_last) : rail_vehicle_t(file,is_first, is_last) {} monorail_vehicle_t(koord3d pos,const vehicle_desc_t * desc,player_t * player,convoi_t * cnv)604 monorail_vehicle_t(koord3d pos, const vehicle_desc_t* desc, player_t* player, convoi_t* cnv) : rail_vehicle_t(pos, desc, player, cnv) {} 605 get_typ()606 typ get_typ() const OVERRIDE { return monorail_vehicle; } 607 608 schedule_t * generate_new_schedule() const OVERRIDE; 609 }; 610 611 612 613 /** 614 * very similar to normal railroad, so we can implement it here completely ... 615 * @author prissi 616 * @see vehicle_t 617 */ 618 class maglev_vehicle_t : public rail_vehicle_t 619 { 620 public: get_waytype()621 waytype_t get_waytype() const OVERRIDE { return maglev_wt; } 622 623 // all handled by rail_vehicle_t maglev_vehicle_t(loadsave_t * file,bool is_first,bool is_last)624 maglev_vehicle_t(loadsave_t *file, bool is_first, bool is_last) : rail_vehicle_t(file, is_first, is_last) {} maglev_vehicle_t(koord3d pos,const vehicle_desc_t * desc,player_t * player,convoi_t * cnv)625 maglev_vehicle_t(koord3d pos, const vehicle_desc_t* desc, player_t* player, convoi_t* cnv) : rail_vehicle_t(pos, desc, player, cnv) {} 626 get_typ()627 typ get_typ() const OVERRIDE { return maglev_vehicle; } 628 629 schedule_t * generate_new_schedule() const OVERRIDE; 630 }; 631 632 633 634 /** 635 * very similar to normal railroad, so we can implement it here completely ... 636 * @author prissi 637 * @see vehicle_t 638 */ 639 class narrowgauge_vehicle_t : public rail_vehicle_t 640 { 641 public: get_waytype()642 waytype_t get_waytype() const OVERRIDE { return narrowgauge_wt; } 643 644 // all handled by rail_vehicle_t narrowgauge_vehicle_t(loadsave_t * file,bool is_first,bool is_last)645 narrowgauge_vehicle_t(loadsave_t *file, bool is_first, bool is_last) : rail_vehicle_t(file, is_first, is_last) {} narrowgauge_vehicle_t(koord3d pos,const vehicle_desc_t * desc,player_t * player,convoi_t * cnv)646 narrowgauge_vehicle_t(koord3d pos, const vehicle_desc_t* desc, player_t* player, convoi_t* cnv) : rail_vehicle_t(pos, desc, player, cnv) {} 647 get_typ()648 typ get_typ() const OVERRIDE { return narrowgauge_vehicle; } 649 650 schedule_t * generate_new_schedule() const OVERRIDE; 651 }; 652 653 654 655 /** 656 * A class for naval vehicles. Manages the look of the vehicles 657 * and the navigability of tiles. 658 * 659 * @author Hj. Malthaner 660 * @see vehicle_t 661 */ 662 class water_vehicle_t : public vehicle_t 663 { 664 protected: 665 // how expensive to go here (for way search) get_cost(const grund_t *,const weg_t *,const sint32,ribi_t::ribi)666 int get_cost(const grund_t *, const weg_t*, const sint32, ribi_t::ribi) const OVERRIDE { return 1; } 667 668 void calc_friction(const grund_t *gr) OVERRIDE; 669 670 bool check_next_tile(const grund_t *bd) const OVERRIDE; 671 672 void enter_tile(grund_t*) OVERRIDE; 673 674 public: get_waytype()675 waytype_t get_waytype() const OVERRIDE { return water_wt; } 676 677 bool can_enter_tile(const grund_t *gr_next, sint32 &restart_speed, uint8) OVERRIDE; 678 679 // returns true for the way search to an unknown target. is_target(const grund_t *,const grund_t *)680 bool is_target(const grund_t *,const grund_t *) const OVERRIDE {return 0;} 681 682 water_vehicle_t(loadsave_t *file, bool is_first, bool is_last); 683 water_vehicle_t(koord3d pos, const vehicle_desc_t* desc, player_t* player, convoi_t* cnv); 684 get_typ()685 obj_t::typ get_typ() const OVERRIDE { return water_vehicle; } 686 687 schedule_t * generate_new_schedule() const OVERRIDE; 688 }; 689 690 691 /** 692 * A class for aircrafts. Manages the look of the vehicles 693 * and the navigability of tiles. 694 * 695 * @author hsiegeln 696 * @see vehicle_t 697 */ 698 class air_vehicle_t : public vehicle_t 699 { 700 public: 701 enum flight_state { taxiing=0, departing=1, flying=2, landing=3, looking_for_parking=4, circling=5, taxiing_to_halt=6 }; 702 703 private: 704 // only used for is_target() (do not need saving) 705 ribi_t::ribi approach_dir; 706 #ifdef USE_DIFFERENT_WIND 707 static uint8 get_approach_ribi( koord3d start, koord3d ziel ); 708 #endif 709 // only used for route search and approach vectors of get_ribi() (do not need saving) 710 koord3d search_start; 711 koord3d search_end; 712 713 flight_state state; // functions needed for the search without destination from find_route 714 715 sint16 flying_height; 716 sint16 target_height; 717 uint32 search_for_stop, touchdown, takeoff; 718 719 protected: 720 // jumps to next tile and correct the height ... 721 void hop(grund_t*) OVERRIDE; 722 723 bool check_next_tile(const grund_t *bd) const OVERRIDE; 724 725 void enter_tile(grund_t*) OVERRIDE; 726 727 bool block_reserver( uint32 start, uint32 end, bool reserve ) const; 728 729 // find a route and reserve the stop position 730 bool find_route_to_stop_position(); 731 732 public: 733 air_vehicle_t(loadsave_t *file, bool is_first, bool is_last); 734 air_vehicle_t(koord3d pos, const vehicle_desc_t* desc, player_t* player, convoi_t* cnv); // start and schedule 735 736 // to shift the events around properly get_event_index(flight_state & state_,uint32 & takeoff_,uint32 & stopsearch_,uint32 & landing_)737 void get_event_index( flight_state &state_, uint32 &takeoff_, uint32 &stopsearch_, uint32 &landing_ ) { state_ = state; takeoff_ = takeoff; stopsearch_ = search_for_stop; landing_ = touchdown; } set_event_index(flight_state state_,uint32 takeoff_,uint32 stopsearch_,uint32 landing_)738 void set_event_index( flight_state state_, uint32 takeoff_, uint32 stopsearch_, uint32 landing_ ) { state = state_; takeoff = takeoff_; search_for_stop = stopsearch_; touchdown = landing_; } 739 740 // since we are drawing ourselves, we must mark ourselves dirty during deletion 741 ~air_vehicle_t(); 742 get_waytype()743 waytype_t get_waytype() const OVERRIDE { return air_wt; } 744 745 // returns true for the way search to an unknown target. 746 bool is_target(const grund_t *,const grund_t *) const OVERRIDE; 747 748 // return valid direction 749 ribi_t::ribi get_ribi(const grund_t* ) const OVERRIDE; 750 751 // how expensive to go here (for way search) 752 int get_cost(const grund_t *gr, const weg_t *w, const sint32 max_speed, ribi_t::ribi from) const OVERRIDE; 753 754 bool can_enter_tile(const grund_t *gr_next, sint32 &restart_speed, uint8) OVERRIDE; 755 756 void set_convoi(convoi_t *c) OVERRIDE; 757 758 bool calc_route(koord3d start, koord3d ziel, sint32 max_speed, route_t* route) OVERRIDE; 759 get_typ()760 typ get_typ() const OVERRIDE { return air_vehicle; } 761 762 schedule_t *generate_new_schedule() const OVERRIDE; 763 764 void rdwr_from_convoi(loadsave_t *file) OVERRIDE; 765 get_flyingheight()766 int get_flyingheight() const {return flying_height-get_hoff()-2;} 767 768 // image: when flying empty, on ground the plane get_image()769 image_id get_image() const OVERRIDE {return !is_on_ground() ? IMG_EMPTY : image;} 770 771 // image: when flying the shadow, on ground empty get_outline_image()772 image_id get_outline_image() const OVERRIDE {return !is_on_ground() ? image : IMG_EMPTY;} 773 774 // shadow has black color (when flying) get_outline_colour()775 FLAGGED_PIXVAL get_outline_colour() const OVERRIDE {return !is_on_ground() ? TRANSPARENT75_FLAG | OUTLINE_FLAG | color_idx_to_rgb(COL_BLACK) : 0;} 776 777 #ifdef MULTI_THREAD 778 // this draws the "real" aircrafts (when flying) 779 void display_after(int xpos, int ypos, const sint8 clip_num) const OVERRIDE; 780 781 // this routine will display a tooltip for lost, on depot order, and stuck vehicles 782 void display_overlay(int xpos, int ypos) const OVERRIDE; 783 #else 784 // this draws the "real" aircrafts (when flying) 785 void display_after(int xpos, int ypos, bool dirty) const OVERRIDE; 786 #endif 787 calc_friction(const grund_t *)788 void calc_friction(const grund_t*) OVERRIDE {} 789 is_on_ground()790 bool is_on_ground() const { return flying_height==0 && !(state==circling || state==flying); } 791 792 const char *is_deletable(const player_t *player) OVERRIDE; 793 is_flying()794 bool is_flying() const OVERRIDE { return !is_on_ground(); } 795 }; 796 797 #endif 798