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