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 simhalt_h 9 #define simhalt_h 10 11 #include "convoihandle_t.h" 12 #include "linehandle_t.h" 13 #include "halthandle_t.h" 14 15 #include "simobj.h" 16 #include "display/simgraph.h" 17 #include "simtypes.h" 18 19 #include "bauer/goods_manager.h" 20 21 #include "descriptor/goods_desc.h" 22 23 #include "dataobj/koord.h" 24 25 #include "tpl/inthashtable_tpl.h" 26 27 #include "tpl/slist_tpl.h" 28 #include "tpl/vector_tpl.h" 29 #include "tpl/binary_heap_tpl.h" 30 31 32 #define RECONNECTING (1) 33 #define REROUTING (2) 34 35 #define MAX_HALT_COST 8 // Total number of cost items 36 #define MAX_MONTHS 12 // Max history 37 #define MAX_HALT_NON_MONEY_TYPES 7 // number of non money types in HALT's financial statistic 38 #define HALT_ARRIVED 0 // the amount of ware that arrived here 39 #define HALT_DEPARTED 1 // the amount of ware that has departed from here 40 #define HALT_WAITING 2 // the amount of ware waiting 41 #define HALT_HAPPY 3 // number of happy passengers 42 #define HALT_UNHAPPY 4 // number of unhappy passengers 43 #define HALT_NOROUTE 5 // number of no-route passengers 44 #define HALT_CONVOIS_ARRIVED 6 // number of convois arrived this month 45 #define HALT_WALKED 7 // could walk to destination 46 47 class cbuffer_t; 48 class grund_t; 49 class fabrik_t; 50 class karte_t; 51 class karte_ptr_t; 52 class koord3d; 53 class loadsave_t; 54 class schedule_t; 55 class player_t; 56 class ware_t; 57 58 // -------------------------- Haltestelle ---------------------------- 59 60 /** 61 * Haltestellen in Simutrans. Diese Klasse managed das Routing und Verladen 62 * von Waren. Eine Haltestelle ist somit auch ein Warenumschlagplatz. 63 * 64 * @author Hj. Malthaner 65 * @see stadt_t 66 * @see fabrik_t 67 * @see convoi_t 68 */ 69 class haltestelle_t 70 { 71 public: 72 enum station_flags { NOT_ENABLED=0, PAX=1, POST=2, WARE=4, CROWDED=8 }; 73 74 //13-Jan-02 Markus Weber Added 75 enum stationtyp {invalid=0, loadingbay=1, railstation = 2, dock = 4, busstop = 8, airstop = 16, monorailstop = 32, tramstop = 64, maglevstop=128, narrowgaugestop=256 }; //could be combined with or! 76 77 private: 78 /** 79 * Manche Methoden m�ssen auf alle Haltestellen angewandt werden 80 * deshalb verwaltet die Klasse eine Liste aller Haltestellen 81 * @author Hj. Malthaner 82 */ 83 static vector_tpl<halthandle_t> alle_haltestellen; 84 85 /** 86 * finds a stop by its name 87 * @author prissi 88 */ 89 static stringhashtable_tpl<halthandle_t> all_names; 90 91 /** 92 * Finds a stop by coordinate. 93 * only used during loading. 94 * @author prissi 95 */ 96 static inthashtable_tpl<sint32,halthandle_t> *all_koords; 97 98 /* 99 * struct holds new financial history for line 100 * @author hsiegeln 101 */ 102 sint64 financial_history[MAX_MONTHS][MAX_HALT_COST]; 103 104 /** 105 * initialize the financial history 106 * @author hsiegeln 107 */ 108 void init_financial_history(); 109 110 PIXVAL status_color, last_status_color; 111 sint16 last_bar_count; 112 vector_tpl<KOORD_VAL> last_bar_height; // caches the last height of the station bar for each good type drawn in display_status(). used for dirty tile management 113 uint32 capacity[3]; // passenger, mail, goods 114 uint8 overcrowded[256/8]; ///< bit field for each goods type (max 256) 115 116 static uint8 status_step; // NONE or SCHEDULING or REROUTING 117 118 slist_tpl<convoihandle_t> loading_here; 119 sint32 last_loading_step; 120 121 koord init_pos; // for halt without grounds, created during game initialisation 122 123 /** 124 * Handle for ourselves. Can be used like the 'this' pointer 125 * @author Hj. Malthaner 126 */ 127 halthandle_t self; 128 129 public: get_loading_convois()130 const slist_tpl<convoihandle_t> &get_loading_convois() const { return loading_here; } 131 132 // add convoi to loading queue 133 void request_loading( convoihandle_t cnv ); 134 135 /* recalculates the station bar */ 136 void recalc_status(); 137 138 /** 139 * Handles changes of schedules and the resulting re-routing. 140 */ 141 static void step_all(); 142 get_rerouting_status()143 static uint8 get_rerouting_status() { return status_step; } 144 145 /** 146 * Resets reconnect_counter. 147 * The next call to step_all() will start complete reconnecting. 148 */ 149 static void reset_routing(); 150 151 /** 152 * Tries to generate some pedestrians on the square and the 153 * adjacent squares. Return actual number of generated 154 * pedestrians. 155 * 156 * @author Hj. Malthaner 157 */ 158 static int generate_pedestrians(const koord3d pos, int count); 159 160 /** 161 * Returns an index to a halt at koord k 162 * optionally limit to that owned by player sp 163 * by default create a new halt if none found 164 * Only used during loading. 165 */ 166 static halthandle_t get_halt_koord_index(koord k); 167 168 /* 169 * this will only return something if this stop belongs to same player or is public, or is a dock (when on water) 170 */ 171 static halthandle_t get_halt(const koord3d pos, const player_t *player ); 172 get_alle_haltestellen()173 static const vector_tpl<halthandle_t>& get_alle_haltestellen() { return alle_haltestellen; } 174 175 /** 176 * Station factory method. Returns handles instead of pointers. 177 * @author Hj. Malthaner 178 */ 179 static halthandle_t create(koord pos, player_t *player); 180 181 /** 182 * Station factory method. Returns handles instead of pointers. 183 * @author Hj. Malthaner 184 */ 185 static halthandle_t create(loadsave_t *file); 186 187 /* 188 * removes a ground tile from a station, deletes the building and, if last tile, also the halthandle 189 * @author prissi 190 */ 191 static bool remove(player_t *player, koord3d pos); 192 193 /** 194 * Station destruction method. 195 * @author Hj. Malthaner 196 */ 197 static void destroy(halthandle_t); 198 199 /** 200 * destroys all stations 201 * @author Hj. Malthaner 202 */ 203 static void destroy_all(); 204 205 /** 206 * Liste aller felder (Grund-Objekte) die zu dieser Haltestelle geh�ren 207 * @author Hj. Malthaner 208 */ 209 struct tile_t 210 { tile_ttile_t211 tile_t(grund_t* grund_) : grund(grund_) {} 212 213 bool operator ==(const tile_t& o) { return grund == o.grund; } 214 bool operator !=(const tile_t& o) { return grund != o.grund; } 215 216 grund_t* grund; 217 convoihandle_t reservation; 218 }; 219 get_tiles()220 const slist_tpl<tile_t> &get_tiles() const { return tiles; }; 221 222 /** 223 * directly reachable halt with its connection weight 224 * @author Knightly 225 */ 226 struct connection_t 227 { 228 /// directly reachable halt 229 halthandle_t halt; 230 /// best connection weight to reach this destination 231 uint16 weight:15; 232 /// is halt a transfer halt 233 bool is_transfer:1; 234 connection_tconnection_t235 connection_t() : weight(0), is_transfer(false) { } haltconnection_t236 connection_t(halthandle_t _halt, uint16 _weight=0) : halt(_halt), weight(_weight), is_transfer(false) { } 237 238 bool operator == (const connection_t &other) const { return halt == other.halt; } 239 bool operator != (const connection_t &other) const { return halt != other.halt; } compareconnection_t240 static bool compare(const connection_t &a, const connection_t &b) { return a.halt.get_id() < b.halt.get_id(); } 241 }; 242 is_transfer(const uint8 catg)243 bool is_transfer(const uint8 catg) const { return all_links[catg].is_transfer; } 244 245 private: 246 slist_tpl<tile_t> tiles; 247 248 249 /** 250 * Stores information about link to cargo network of a certain category 251 */ 252 struct link_t { 253 /// List of all directly reachable halts with their respective connection weights 254 vector_tpl<connection_t> connections; 255 256 /** 257 * A transfer/interchange is a halt whereby ware can change line or lineless convoy. 258 * Thus, if a halt is served by 2 or more schedules (of lines or lineless convoys) 259 * for a particular ware type, it is a transfer/interchange for that ware type. 260 * Route searching is accelerated by differentiating transfer and non-transfer halts. 261 * @author Knightly 262 */ 263 bool is_transfer; 264 265 /** 266 * Id of connected component in link graph. 267 * Two halts are connected if and only if they belong to the same connected component. 268 * Exception: if value == UNDECIDED_CONNECTED_COMPONENT, then we are in the middle of 269 * recalculating the link graph. 270 * 271 * The id of the component has to be equal to the halt-id of one of its halts. 272 * This ensures that we always have unique component ids. 273 */ 274 uint16 catg_connected_component; 275 276 # define UNDECIDED_CONNECTED_COMPONENT (0xffff) 277 link_tlink_t278 link_t() { clear(); } 279 clearlink_t280 void clear() 281 { 282 connections.clear(); 283 is_transfer = false; 284 catg_connected_component = UNDECIDED_CONNECTED_COMPONENT; 285 } 286 }; 287 288 /// All links to networks of all freight categories, filled by rebuild_connected_components. 289 link_t* all_links; 290 291 /** 292 * Fills in catg_connected_component values for all halts and all categories. 293 * Uses depth-first search. 294 */ 295 static void rebuild_connected_components(); 296 297 /** 298 * Helper method: This halt (and all its connected neighbors) belong 299 * to the same component. 300 * Also sets connection_t::is_transfer. 301 * @param catg category of cargo network 302 * @param comp number of component 303 */ 304 void fill_connected_component(uint8 catg, uint16 comp); 305 306 307 // Array with different categories that contains all waiting goods at this stop 308 vector_tpl<ware_t> **cargo; 309 310 /** 311 * Liste der angeschlossenen Fabriken 312 * @author Hj. Malthaner 313 */ 314 slist_tpl<fabrik_t *> fab_list; 315 316 player_t *owner; 317 static karte_ptr_t welt; 318 319 /** 320 * What is that for a station (for the image) 321 * @author prissi 322 */ 323 stationtyp station_type; 324 325 // private helper function for recalc_station_type() 326 void add_to_station_type( grund_t *gr ); 327 328 /** 329 * Reconnect and reroute if counter different from welt->get_schedule_counter() 330 */ 331 static uint8 reconnect_counter; 332 // since we do partial routing, we remember the last offset 333 uint8 last_catg_index; 334 335 /* station flags (most what enabled) */ 336 uint8 enables; 337 338 /** 339 * versucht die ware mit beriets wartender ware zusammenzufassen 340 * @author Hj. Malthaner 341 */ 342 bool vereinige_waren(const ware_t &ware); 343 344 // add the ware to the internal storage, called only internally 345 void add_ware_to_halt(ware_t ware); 346 347 /** 348 * liefert wartende ware an eine Fabrik 349 * @author Hj. Malthaner 350 */ 351 void liefere_an_fabrik(const ware_t& ware) const; 352 353 /* 354 * transfers all goods to given station 355 * 356 * @author Dwachs 357 */ 358 void transfer_goods(halthandle_t halt); 359 360 /* 361 * parameter to ease sorting 362 * sortierung is local and stores the sortorder for the individual station 363 * @author hsiegeln 364 */ 365 uint8 sortierung; 366 bool resort_freight_info; 367 368 haltestelle_t(loadsave_t *file); 369 haltestelle_t(koord pos, player_t *player); 370 ~haltestelle_t(); 371 372 public: 373 /** 374 * Called after schedule calculation of all stations is finished 375 * will distribute the goods to changed routes (if there are any) 376 * returns true upon completion 377 * @author Hj. Malthaner 378 */ 379 bool reroute_goods(sint16 &units_remaining); 380 381 /** 382 * getter/setter for sortby 383 * @author hsiegeln 384 */ get_sortby()385 uint8 get_sortby() { return sortierung; } set_sortby(uint8 sm)386 void set_sortby(uint8 sm) { resort_freight_info =true; sortierung = sm; } 387 388 /** 389 * Calculates a status color for status bars 390 * @author Hj. Malthaner 391 */ get_status_farbe()392 PIXVAL get_status_farbe() const { return status_color; } 393 394 /** 395 * Draws some nice colored bars giving some status information 396 * @author Hj. Malthaner 397 */ 398 void display_status(KOORD_VAL xpos, KOORD_VAL ypos); 399 400 /** 401 * sucht umliegende, erreichbare fabriken und baut daraus die 402 * Fabrikliste auf. 403 * @author Hj. Malthaner 404 */ 405 void verbinde_fabriken(); 406 void remove_fabriken(fabrik_t *fab); 407 408 /** 409 * Rebuilds the list of connections to reachable halts 410 * returns the search number of connections 411 * @author Hj. Malthaner 412 */ 413 sint32 rebuild_connections(); 414 415 /** 416 * Rebuilds connections of all halts connected to this halt. 417 * Prepares deletion of this halt without losing connections and routed freight. 418 */ 419 void rebuild_linked_connections(); 420 get_reconnect_counter()421 uint8 get_reconnect_counter() const { return reconnect_counter; } 422 423 void rotate90( const sint16 y_size ); 424 get_owner()425 player_t *get_owner() const {return owner;} 426 427 // just for info so far 428 sint64 calc_maintenance() const; 429 430 void merge_halt( halthandle_t halt_to_join ); 431 432 void change_owner( player_t *player ); 433 get_pax_connections()434 vector_tpl<connection_t> const& get_pax_connections() const { return all_links[goods_manager_t::INDEX_PAS].connections; } get_mail_connections()435 vector_tpl<connection_t> const& get_mail_connections() const { return all_links[goods_manager_t::INDEX_MAIL].connections; } 436 437 // returns the matching warenziele (goods objectives/destinations) get_connections(uint8 const catg_index)438 vector_tpl<connection_t> const& get_connections(uint8 const catg_index) const { return all_links[catg_index].connections; } 439 440 /** 441 * Checks if there is connection for certain freight to the other halt. 442 * @param halt the other halt 443 * @param catg_index freight category index 444 * @return 0 - not connected, 1 - connected, -1 - undecided (call again later...) 445 */ 446 sint8 is_connected(halthandle_t halt, uint8 catg_index) const; 447 get_fab_list()448 const slist_tpl<fabrik_t*>& get_fab_list() const { return fab_list; } 449 450 /** 451 * called regularly to update status and reroute stuff 452 * @author Hj. Malthaner 453 */ 454 bool step(uint8 what, sint16 &units_remaining); 455 456 /** 457 * Called every month/every 24 game hours 458 * @author Hj. Malthaner 459 */ 460 void new_month(); 461 462 private: 463 /* Node used during route search */ 464 struct route_node_t 465 { 466 halthandle_t halt; 467 uint16 aggregate_weight; 468 route_node_troute_node_t469 route_node_t() : aggregate_weight(0) {} route_node_troute_node_t470 route_node_t(halthandle_t h, uint16 w) : halt(h), aggregate_weight(w) {} 471 472 // dereferencing to be used in binary_heap_tpl 473 inline uint16 operator * () const { return aggregate_weight; } 474 }; 475 476 /* Extra data for route search */ 477 struct halt_data_t 478 { 479 // transfer halt: 480 // in static function search_route(): previous transfer halt (to track back route) 481 // in member function search_route_resumable(): first transfer halt to get there 482 halthandle_t transfer; 483 uint16 best_weight; 484 uint16 depth:14; 485 bool destination:1; 486 bool overcrowded:1; 487 }; 488 489 // store the best weight so far for a halt, and indicate whether it is a destination 490 static halt_data_t halt_data[65536]; 491 492 // for efficient retrieval of the node with the smallest weight 493 static binary_heap_tpl<route_node_t> open_list; 494 495 /** 496 * Markers used in route searching to avoid processing the same halt more than once 497 * @author Knightly 498 */ 499 static uint8 markers[65536]; 500 static uint8 current_marker; 501 502 /** 503 * Remember last route search start and catg to resume search 504 * @author dwachs 505 */ 506 static halthandle_t last_search_origin; 507 static uint8 last_search_ware_catg_idx; 508 public: 509 enum routing_result_flags { NO_ROUTE=0, ROUTE_OK=1, ROUTE_WALK=2, ROUTE_OVERCROWDED=8 }; 510 511 /** 512 * Kann die Ware nicht zum Ziel geroutet werden (keine Route), dann werden 513 * Ziel und Zwischenziel auf koord::invalid gesetzt. 514 * 515 * @param ware die zu routende Ware 516 * @author Hj. Malthaner 517 * 518 * for reverse routing, also the next to last stop can be added, if next_to_ziel!=NULL 519 * 520 * if avoid_overcrowding is set, a valid route in only found when there is no overflowing stop in between 521 * 522 * @author prissi 523 */ 524 static int search_route( const halthandle_t *const start_halts, const uint16 start_halt_count, const bool no_routing_over_overcrowding, ware_t &ware, ware_t *const return_ware=NULL ); 525 526 /** 527 * A separate version of route searching code for re-calculating routes 528 * Search is resumable, that is if called for the same halt and same goods category 529 * it reuses search history from last search 530 * It is faster than calling the above version on each packet, and is used for re-routing packets from the same halt. 531 */ 532 void search_route_resumable( ware_t &ware ); 533 get_pax_enabled()534 bool get_pax_enabled() const { return enables & PAX; } get_mail_enabled()535 bool get_mail_enabled() const { return enables & POST; } get_ware_enabled()536 bool get_ware_enabled() const { return enables & WARE; } 537 538 // check, if we accepts this good 539 // often called, thus inline ... is_enabled(const goods_desc_t * wtyp)540 bool is_enabled( const goods_desc_t *wtyp ) const { 541 return is_enabled(wtyp->get_catg_index()); 542 } 543 544 // a separate version for checking with goods category index is_enabled(const uint8 catg_index)545 bool is_enabled( const uint8 catg_index ) const 546 { 547 if (catg_index == goods_manager_t::INDEX_PAS) { 548 return enables&PAX; 549 } 550 else if(catg_index == goods_manager_t::INDEX_MAIL) { 551 return enables&POST; 552 } 553 return enables&WARE; 554 } 555 556 /** 557 * Found route and station uncrowded 558 * @author Hj. Malthaner 559 */ 560 void add_pax_happy(int n); 561 562 /** 563 * Station in walking distance 564 * @author prissi 565 */ 566 void add_pax_walked(int n); 567 568 /** 569 * Found no route 570 * @author Hj. Malthaner 571 */ 572 void add_pax_no_route(int n); 573 574 /** 575 * Station crowded 576 * @author Hj. Malthaner 577 */ 578 void add_pax_unhappy(int n); 579 get_pax_happy()580 int get_pax_happy() const { return (int)financial_history[0][HALT_HAPPY]; } get_pax_no_route()581 int get_pax_no_route() const { return (int)financial_history[0][HALT_NOROUTE]; } get_pax_unhappy()582 int get_pax_unhappy() const { return (int)financial_history[0][HALT_UNHAPPY]; } 583 584 585 /** 586 * Add tile to list of station tiles. 587 * @param relink_factories if true call verbinde_fabriken, if not true take care of factory connections yourself 588 */ 589 bool add_grund(grund_t *gb, bool relink_factories = true); 590 bool rem_grund(grund_t *gb); 591 get_capacity(uint8 typ)592 uint32 get_capacity(uint8 typ) const { return capacity[typ]; } 593 594 bool existiert_in_welt() const; 595 get_init_pos()596 koord get_init_pos() const { return init_pos; } 597 koord get_basis_pos() const; 598 koord3d get_basis_pos3d() const; 599 600 public: 601 void recalc_basis_pos(); 602 603 // returns ground closest to this coordinate 604 grund_t *get_ground_closest_to( const koord here ) const; 605 606 /* return the closest square that belongs to this halt 607 * @author prissi 608 */ 609 koord get_next_pos( koord start ) const; 610 611 // true, if this station is overcrowded for this ware is_overcrowded(const uint8 idx)612 bool is_overcrowded( const uint8 idx ) const { return (overcrowded[idx/8] & (1<<(idx%8)))!=0; } 613 614 /** 615 * gibt Gesamtmenge derware vom typ typ zur�ck 616 * @author Hj. Malthaner 617 */ 618 uint32 get_ware_summe(const goods_desc_t *warentyp) const; 619 620 /** 621 * returns total number for a certain position (since more than one factory might connect to a stop) 622 * @author Hj. Malthaner 623 */ 624 uint32 get_ware_fuer_zielpos(const goods_desc_t *warentyp, const koord zielpos) const; 625 626 /** 627 * total amount of freight with specified next hop 628 * @author prissi 629 */ 630 uint32 get_ware_fuer_zwischenziel(const goods_desc_t *warentyp, const halthandle_t zwischenziel) const; 631 632 // true, if we accept/deliver this kind of good gibt_ab(const goods_desc_t * warentyp)633 bool gibt_ab(const goods_desc_t *warentyp) const { return cargo[warentyp->get_catg_index()] != NULL; } 634 635 /* retrieves a ware packet for any destination in the list 636 * needed, if the factory in question wants to remove something 637 */ 638 bool recall_ware( ware_t& w, uint32 menge ); 639 640 /** 641 * Fetches goods from this halt 642 * @param load Output parameter. Goods will be put into this list, the vehicle has to load them. 643 * @param good_category Specifies the kind of good (or compatible goods) we are requesting to fetch from this stop. 644 * @param amount How many units of the cargo we can fetch. 645 * @param schedule Schedule of the vehicle requesting the fetch. 646 * @param sp Company that's requesting the fetch. 647 * @author Dwachs 648 */ 649 void fetch_goods( slist_tpl<ware_t> &load, const goods_desc_t *good_category, uint32 requested_amount, const vector_tpl<halthandle_t>& destination_halts); 650 651 /* liefert ware an. Falls die Ware zu wartender Ware dazugenommen 652 * werden kann, kann ware_t gel�scht werden! D.h. man darf ware nach 653 * aufruf dieser Methode nicht mehr referenzieren! 654 * 655 * The second version is like the first, but will not recalculate the route 656 * This is used for inital passenger, since they already know a route 657 * 658 * @return angenommene menge 659 * @author Hj. Malthaner/prissi 660 */ 661 uint32 liefere_an(ware_t ware); 662 uint32 starte_mit_route(ware_t ware); 663 664 const grund_t *find_matching_position(waytype_t wt) const; 665 666 /* checks, if there is an unoccupied loading bay for this kind of thing 667 * @author prissi 668 */ 669 bool find_free_position(const waytype_t w ,convoihandle_t cnv,const obj_t::typ d) const; 670 671 /* reserves a position (caution: railblocks work differently! 672 * @author prissi 673 */ 674 bool reserve_position(grund_t *gr,convoihandle_t cnv); 675 676 /* frees a reserved position (caution: railblocks work differently! 677 * @author prissi 678 */ 679 bool unreserve_position(grund_t *gr, convoihandle_t cnv); 680 681 /* true, if this can be reserved 682 * @author prissi 683 */ 684 bool is_reservable(const grund_t *gr, convoihandle_t cnv) const; 685 686 /** 687 * @param buf the buffer to fill 688 * @return Goods description text (buf) 689 * @author Hj. Malthaner 690 */ 691 void get_freight_info(cbuffer_t & buf); 692 693 /** 694 * @param buf the buffer to fill 695 * @return short list of the waiting goods (i.e. 110 Wood, 15 Coal) 696 * @author Hj. Malthaner 697 */ 698 void get_short_freight_info(cbuffer_t & buf) const; 699 700 /** 701 * Opens an information window for this station. 702 * @author Hj. Malthaner 703 */ 704 void open_info_window(); 705 706 /** 707 * @return the type of a station 708 * (combination of: railstation, loading bay, dock) 709 * @author Markus Weber 710 */ get_station_type()711 stationtyp get_station_type() const { return station_type; } 712 void recalc_station_type(); 713 714 /** 715 * fragt den namen der Haltestelle ab. 716 * Der Name ist der text des ersten Untergrundes der Haltestelle 717 * @return der Name der Haltestelle. 718 * @author Hj. Malthaner 719 */ 720 const char *get_name() const; 721 722 void set_name(const char *name); 723 724 // create an unique name: better to be called with valid handle, although it will work without 725 char* create_name(koord k, char const* typ); 726 727 void rdwr(loadsave_t *file); 728 729 void finish_rd(); 730 731 /** 732 * Called before savegame will be loaded. 733 * Creates all_koords table. 734 */ 735 static void start_load_game(); 736 737 /** 738 * Called after loading of savegame almost finished, 739 * i.e. after finish_rd is finished. 740 * Deletes all_koords table. 741 */ 742 static void end_load_game(); 743 744 745 /* 746 * called, if a line serves this stop 747 * @author hsiegeln 748 */ add_line(linehandle_t line)749 void add_line(linehandle_t line) { registered_lines.append_unique(line); } 750 751 /* 752 * called, if a line removes this stop from it's schedule 753 * @author hsiegeln 754 */ remove_line(linehandle_t line)755 void remove_line(linehandle_t line) { registered_lines.remove(line); } 756 757 /* 758 * list of line ids that serve this stop 759 * @author hsiegeln 760 */ 761 vector_tpl<linehandle_t> registered_lines; 762 763 /** 764 * Register a lineless convoy which serves this stop 765 * @author Knightly 766 */ add_convoy(convoihandle_t convoy)767 void add_convoy(convoihandle_t convoy) { registered_convoys.append_unique(convoy); } 768 769 /** 770 * Unregister a lineless convoy 771 * @author Knightly 772 */ remove_convoy(convoihandle_t convoy)773 void remove_convoy(convoihandle_t convoy) { registered_convoys.remove(convoy); } 774 775 /** 776 * A list of lineless convoys serving this stop 777 * @author Knightly 778 */ 779 vector_tpl<convoihandle_t> registered_convoys; 780 781 /** 782 * book a certain amount into the halt's financial history 783 * @author hsiegeln 784 */ 785 void book(sint64 amount, int cost_type); 786 787 /** 788 * return a pointer to the financial history 789 * @author hsiegeln 790 */ get_finance_history()791 sint64* get_finance_history() { return *financial_history; } 792 793 /** 794 * return a specified element from the financial history 795 * @author hsiegeln 796 */ get_finance_history(int month,int cost_type)797 sint64 get_finance_history(int month, int cost_type) const { return financial_history[month][cost_type]; } 798 799 // flags station for a crowded message at the beginning of next month 800 // void bescheid_station_voll() { enables |= CROWDED; status_color = color_idx_to_rgb(COL_RED); } // for now report only serious overcrowding on transfer stops 801 802 /* marks a coverage area 803 * @author prissi 804 */ 805 void mark_unmark_coverage(const bool mark) const; 806 807 /* 808 * deletes factory references so map rotation won't segfault 809 */ 810 void release_factory_links(); 811 812 /** 813 * Initialise the markers to zero 814 * @author Knightly 815 */ 816 static void init_markers(); 817 818 /* 819 * check if it is in the station coverage 820 */ 821 bool is_halt_covered (const halthandle_t &halt) const; 822 }; 823 824 ENUM_BITSET(haltestelle_t::stationtyp) 825 826 #endif 827