forked from aburch/simutrans
-
Notifications
You must be signed in to change notification settings - Fork 53
/
Copy pathsimhalt.h
1069 lines (850 loc) · 33.7 KB
/
simhalt.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* This file is part of the Simutrans-Extended project under the Artistic License.
* (see LICENSE.txt)
*/
#ifndef SIMHALT_H
#define SIMHALT_H
#include "convoihandle_t.h"
#include "linehandle_t.h"
#include "halthandle_t.h"
#include "simware.h"
#include "obj/simobj.h"
#include "display/simgraph.h"
#include "simtypes.h"
#include "simconst.h"
#include "bauer/goods_manager.h"
#include "descriptor/goods_desc.h"
#include "dataobj/koord.h"
#include "tpl/inthashtable_tpl.h"
#include "tpl/slist_tpl.h"
#include "tpl/vector_tpl.h"
#include "tpl/binary_heap_tpl.h"
#include "tpl/quickstone_hashtable_tpl.h"
#include "tpl/koordhashtable_tpl.h"
#include "tpl/fixed_list_tpl.h"
#include "tpl/binary_heap_tpl.h"
#include "tpl/minivec_tpl.h"
#define MAX_HALT_COST 13 // Total number of cost items
#define MAX_MONTHS 12 // Max history
//#define MAX_HALT_NON_MONEY_TYPES 8 // number of non money types in HALT's financial statistic
#define HALT_VISITORS 0 // the amount of visitors that getting on and off
#define HALT_COMMUTERS 1 // the amount of commuters that getting on and off
#define HALT_WAITING 2 // the amount of ware waiting
#define HALT_HAPPY 3 // number of happy passengers
#define HALT_UNHAPPY 4 // number of unhappy passengers
#define HALT_NOROUTE 5 // number of no-route passengers
#define HALT_CONVOIS_ARRIVED 6 // number of convois arrived this month
#define HALT_TOO_SLOW 7 // The number of passengers whose estimated journey time exceeds their tolerance.
#define HALT_TOO_WAITING 8 // The number of passengers who waited so long at the station.
#define HALT_MAIL_DELIVERED 9 // amount of delivered mail from here
#define HALT_MAIL_NOROUTE 10 // amount of no-route mail
#define HALT_MAIL_HANDLING_VOLUME 11 // the handling volume of mail
#define HALT_GOODS_HANDLING_VOLUME 12 // the handling volume of goods
/* NOTE - Standard has HALT_WALKED here as no. 7. In Extended, this is in cities, not stops.*/
// This should be network safe multi-threadedly (this has been considered carefully and tested somewhat,
// although the test was run at a time (March 2017) when there was another known bug, hard to find, causing
// network desyncs when multiple clients connect to a server, so the test is not a perfect proof of being
// network safe)
// It is faster enabled than disabled.
#define ALWAYS_CACHE_SERVICE_INTERVAL
class cbuffer_t;
class grund_t;
class fabrik_t;
class karte_t;
class karte_ptr_t;
class koord3d;
class loadsave_t;
class schedule_t;
class player_t;
class ware_t;
class transferring_cargo_t;
// elements of the lines_loaded vector
struct lines_loaded_t
{
linehandle_t line;
bool reversed;
uint8 current_stop;
uint8 catg_index;
};
// -------------------------- Haltestelle ----------------------------
/**
* Haltestellen in Simutrans. Diese Klasse managed das Routing und Verladen
* von Waren. Eine Haltestelle ist somit auch ein Warenumschlagplatz.
* @see stadt_t
* @see fabrik_t
* @see convoi_t
*/
class haltestelle_t
{
public:
enum station_flags {
NOT_ENABLED = 0,
PAX = 1 << 0,
POST = 1 << 1,
WARE = 1 << 2,
};
// can be combined with or!
enum stationtyp {
invalid = 0,
loadingbay = 1 << 0,
railstation = 1 << 1,
dock = 1 << 2,
busstop = 1 << 3,
airstop = 1 << 4,
monorailstop = 1 << 5,
tramstop = 1 << 6,
maglevstop = 1 << 7,
narrowgaugestop = 1 << 8
};
private:
/// List of all halts in the game.
static vector_tpl<halthandle_t> alle_haltestellen;
/**
* finds a stop by its name
*/
static stringhashtable_tpl<halthandle_t, N_BAGS_LARGE> all_names;
/**
* Finds a stop by coordinate.
* only used during loading.
*/
static inthashtable_tpl<sint32,halthandle_t, N_BAGS_LARGE> *all_koords;
/**
* A list of lines and freight categories that have already been loaded with all available freight at the halt.
* Reset each step.
*/
static vector_tpl<lines_loaded_t> lines_loaded;
/*
* struct holds new financial history for line
*/
sint64 financial_history[MAX_MONTHS][MAX_HALT_COST];
/**
* initialize the financial history
*/
void init_financial_history();
PIXVAL status_color, last_status_color, status_color_freight;
sint16 last_bar_count;
vector_tpl<scr_coord_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
uint32 capacity[3]; // passenger, mail, goods
uint8 overcrowded[256/8]; ///< bit field for each goods type (max 256)
slist_tpl<convoihandle_t> loading_here;
sint32 last_loading_step;
// A list of halts within walking distance
// @author: jamespetts, July 2011
vector_tpl<halthandle_t> halts_within_walking_distance;
void add_halt_within_walking_distance(halthandle_t halt);
void remove_halt_within_walking_distance(halthandle_t halt);
void check_nearby_halts();
uint8 control_towers;
koord init_pos; // for halt without grounds, created during game initialisation
/**
* Handle for ourselves. Can be used like the 'this' pointer
*/
halthandle_t self;
/*
* The time (in 10ths of seconds)
* that it takes passengers to walk
* through this stop from one
* connexion to another. This is
* based on the size of the stop.
*/
uint32 transfer_time;
/**
* The time (in 10ths of seconds)
* that it takes goods to be trans-shipped
* inside this stop. This assumes a fixed
* rate of 1km/h and is based on the size
* of the stop.
*/
uint32 transshipment_time;
/* This is called by the path explorer
* when this halt needs to re-route goods.
* This cannot be done from within the
* path explorer when it is multi-threaded.
*/
vector_tpl<uint8> categories_to_refresh_next_step;
/**
* This is the list of passengers/mail/goods that
* have arrived at this stop but are in the process
* of transferring either to catch the next service,
* or walking/being carted to their ultimate
* destination.
*
* This is an array of these vectors: one per thread,
* indexed by thread number.
*/
vector_tpl<transferring_cargo_t> *transferring_cargoes;
public:
const slist_tpl<convoihandle_t> &get_loading_convois() const { return loading_here; }
// add convoi to loading queue
void request_loading( convoihandle_t cnv );
/* recalculates the station bar */
void recalc_status();
/**
* Handles changes of schedules and the resulting re-routing.
*/
static void step_all();
/**
* Resets reconnect_counter.
* The next call to step_all() will start complete reconnecting.
*/
static void reset_routing();
/**
* Returns an index to a halt at koord k
* optionally limit to that owned by player sp
* by default create a new halt if none found
* Only used during loading.
*/
static halthandle_t get_halt_koord_index(koord k);
/*
* this will only return something if this stop belongs to same player or is public, or is a dock (when on water)
*/
static halthandle_t get_halt(const koord3d pos, const player_t *player );
static halthandle_t get_halt_2D(const koord pos, const player_t *player );
// static slist_tpl<halthandle_t>& get_alle_haltestellen() { return alle_haltestellen; }
static const vector_tpl<halthandle_t>& get_alle_haltestellen() { return alle_haltestellen; }
static vector_tpl<lines_loaded_t>& access_lines_loaded() { return lines_loaded; }
/**
* Station factory method. Returns handles instead of pointers.
*/
static halthandle_t create(koord pos, player_t *player);
/**
* Station factory method. Returns handles instead of pointers.
*/
static halthandle_t create(loadsave_t *file);
/**
* removes a ground tile from a station, deletes the building and, if last tile, also the halthandle
*/
static bool remove(player_t *player, koord3d pos);
/**
* Station destruction method.
*/
static void destroy(halthandle_t);
/**
* destroys all stations
*/
static void destroy_all();
uint32 get_number_of_halts_within_walking_distance() const;
halthandle_t get_halt_within_walking_distance(uint32 index) const { return halts_within_walking_distance[index]; }
/**
* List of all tiles (grund_t) that belong to this halt.
*/
struct tile_t
{
tile_t() {}
tile_t(grund_t* grund_) : grund(grund_) {}
bool operator ==(const tile_t& o) { return grund == o.grund; }
bool operator !=(const tile_t& o) { return grund != o.grund; }
grund_t* grund;
convoihandle_t reservation[2];
};
// Data on direct connexions from one station to the next.
// @author: jamespetts
struct connexion
{
// Times in tenths of minutes
uint32 journey_time;
uint32 waiting_time;
uint32 transfer_time;
// Convoy only used if line not used
// (i.e., if the best route involves using a convoy without a line)
linehandle_t best_line;
convoihandle_t best_convoy;
// TODO: Consider whether to add comfort
uint16 alternative_seats; // used in overcrowd calculations in fetch_goods, updated by update_alternative_seats
// For the memory pool
void* operator new(size_t size);
void operator delete(void *p);
};
bool do_alternative_seats_calculation; //for optimisations purpose
const slist_tpl<tile_t> &get_tiles() const { return tiles; }
bool is_within_walking_distance_of(halthandle_t halt) const;
typedef quickstone_hashtable_tpl<haltestelle_t, connexion*, N_BAGS_MEDIUM> connexions_map;
struct waiting_time_set
{
fixed_list_tpl<uint32, 32> times;
uint8 month;
};
typedef inthashtable_tpl<uint32, waiting_time_set, N_BAGS_SMALL> waiting_time_map;
void add_control_tower() { control_towers ++; }
void remove_control_tower() { if(control_towers > 0) control_towers --; }
struct service_frequency_specifier
{
// Category
uint16 x;
// Halt ID
uint8 y;
service_frequency_specifier operator - (service_frequency_specifier s)
{
service_frequency_specifier result;
result.x = x - s.x;
result.y = y - s.y;
return result;
}
};
bool is_transfer(const uint8 catg, const uint8 g_class, uint8 max_classes) const { return non_identical_schedules[(catg * max_classes) + g_class] > 1u; }
// bool is_transfer(const uint8 catg) const { return all_links[catg].is_transfer; }
// Whether or not there are passengers/mail trying to use this station.
// demand_check = false : Confirm existence of transport history of corresponding category
bool has_pax_user(const uint8 months, bool demand_check) const;
bool has_mail_user(const uint8 months, bool demand_check) const;
bool is_using() const;
typedef inthashtable_tpl<uint16, sint64, N_BAGS_SMALL> arrival_times_map;
#ifdef MULTI_THREAD
uint32 get_transferring_cargoes_count() const;
#else
uint32 get_transferring_cargoes_count() const { return transferring_cargoes->get_count(); }
#endif
private:
slist_tpl<tile_t> tiles;
// Table of all direct connexions to this halt, with routing information.
// One entry per goods type and class.
// This stores pointers to connexions_map objects to enable quick swapping.
vector_tpl<vector_tpl<connexions_map*>> connexions;
/**
* For each line/lineless convoy which serves the current halt, this
* counter is incremented. Each ware category and class needs a separate counter.
* If this counter is more than 1, this halt is a transfer halt.
* @author Knightly
*/
//uint8 *non_identical_schedules;
// Note: this is an offset vector: a single dimensional vector
// functioning as a two dimensional vector (category, class)
// using offsets as described here:
// https://stackoverflow.com/questions/34077816/how-to-properly-work-with-dynamically-allocated-multi-dimensional-arrays-in-c
// This should be more reliable than an array of pointers and faster than a vector of vectors.
vector_tpl<uint8> non_identical_schedules;
// Array with different categories that contains all waiting goods at this stop
vector_tpl<ware_t> **cargo;
/**
* Liste der angeschlossenen Fabriken
*/
slist_tpl<fabrik_t *> fab_list;
player_t *owner;
static karte_ptr_t welt;
/**
* What is that for a station (for the image)
*/
stationtyp station_type;
// private helper function for recalc_station_type()
void add_to_station_type( grund_t *gr );
/**
* Reconnect and reroute if counter different from welt->get_schedule_counter()
*/
static uint8 reconnect_counter;
// since we do partial routing, we remember the last offset
uint8 last_catg_index;
uint32 last_goods_index;
/* station flags (most what enabled) */
uint16 enables;
/**
* 0 = North; 1 = South; 2 = East 3 = West
* Used for the time interval system
*/
sint64 train_last_departed[4];
/**
* Used for the time interval system
*/
vector_tpl<koord3d> station_signals;
#ifdef USE_QUOTE
// for station rating
//const char * quote_bezeichnung(int quote, convoihandle_t cnv) const;
const char * quote_bezeichnung(int quote) const;
#endif
// add the ware to the internal storage, called only internally
void add_ware_to_halt(ware_t ware, bool from_saved = false);
// Add cargoes to the waiting list
void add_to_waiting_list(ware_t ware, sint64 ready_time);
/**
* This calculates how long that it will take any given
* cargo packet to be ready to transfer onwards from
* this stop.
*/
sint64 calc_ready_time(ware_t ware, bool arriving_from_vehicle, koord origin_pos = koord::invalid) const;
/**
* transfers all goods to given station
*/
void transfer_goods(halthandle_t halt);
/**
* parameter to ease sorting
* sortierung is local and stores the sortorder for the individual station
*/
uint8 sortierung;
bool resort_freight_info;
haltestelle_t(loadsave_t *file);
haltestelle_t(koord pos, player_t *player);
~haltestelle_t();
// Record of waiting times. Takes a list of the last 16 waiting times per type of goods.
// Getter method will need to average the waiting times.
// @author: jamespetts
vector_tpl<vector_tpl<waiting_time_map*>> waiting_times;
// Store the service frequencies to all other halts so that this does not need to be
// recalculated frequently. These are used as proxies for waiting times when no
// recent (or any) waiting time data are available.
koordhashtable_tpl<service_frequency_specifier, uint32, N_BAGS_SMALL> service_frequencies;
static const sint64 waiting_multiplication_factor = 3ll;
static const sint64 waiting_tolerance_ratio = 50ll;
uint8 check_waiting;
// Added by : Knightly
// Purpose : To store the time at which this halt is created
// This is *not* saved in save games.
// When loading halts from save game, this is set to 0
sint64 inauguration_time;
/**
* Arrival times of convoys bound for this stop, estimated based on
* convoys' point to point timings, indexed by the convoy's ID
*/
arrival_times_map estimated_convoy_arrival_times;
arrival_times_map estimated_convoy_departure_times;
/**
* Calculates the earliest time in ticks that passengers/mail/goods can arrive
* at the given halt in light of the current estimated departure times.
*/
sint64 calc_earliest_arrival_time_at(halthandle_t halt, convoihandle_t &convoi, uint8 catg_index, uint8 g_class) const;
/**
* This will check the list of transferring cargoes
* and register at their destination those that
* are ready to go there.
*/
void check_transferring_cargoes();
public:
// Added by : Knightly
void swap_connexions(const uint8 category, const uint8 g_class, haltestelle_t::connexions_map* &cxns)
{
// swap the connexion hashtables
connexions_map *temp = connexions[category][g_class];
connexions[category][g_class] = cxns;
cxns = temp;
// since this swap is equivalent to having the connexions rebuilt
resort_freight_info = true;
}
// Added by : Knightly
uint8 get_schedule_count(const uint8 category, uint8 g_class, uint8 max_classes) const { return non_identical_schedules[(category * max_classes) + g_class]; }
void set_schedule_count(const uint8 category, uint8 g_class, uint8 max_classes, const uint8 schedule_count) { non_identical_schedules[(category * max_classes) + g_class] = schedule_count; }
void reset_connexions(uint8 category, uint8 g_class);
/**
* Called every 255 steps
* will distribute the goods to changed routes (if there are any)
* returns true upon completion
*/
//uint32 reroute_goods();
// Re-routing goods of a single ware category
uint32 reroute_goods(uint8 catg);
/**
* getter/setter for sortby
*/
uint8 get_sortby() { return sortierung; }
void set_sortby(uint8 sm) { resort_freight_info =true; sortierung = sm; }
/**
* Calculates a status color for status bars
*/
PIXVAL get_status_farbe() const { return status_color; }
PIXVAL get_status_color(uint8 typ) const;
/**
* Draws some nice colored bars giving some status information
*/
void display_status(sint16 xpos, sint16 ypos);
/**
* "Surrounding searches, achievable factories and builds the
* factory list." (Google)
*/
void verbinde_fabriken();
void add_factory(fabrik_t* fab);
void remove_fabriken(fabrik_t *fab);
void rotate90( const sint16 y_size );
player_t *get_owner() const {return owner;}
void set_owner(player_t* value) { owner = value; }
// just for info so far
sint64 calc_maintenance() const;
bool make_public_and_join( player_t *player );
/**
* Checks if there is connection for certain freight to the other halt.
* @param halt the other halt
* @param catg_index freight category index
* @return 0 - not connected, 1 - connected, -1 - undecided (call again later...)
*/
// TODO: Check whetehr this can be removed entirely
sint8 is_connected(halthandle_t halt, uint8 catg_index) const;
const slist_tpl<fabrik_t*>& get_fab_list() const { return fab_list; }
/**
* called regularly to update status and reroute stuff
*/
void step();
/**
* Called every month/every 24 game hours
*/
void new_month();
// @author: jamespetts, although much is borrowed from suche_route
// Returns the journey time of the best possible route from this halt. Time == UINT32_MAX_VALUE when there is no route.
uint32 find_route(ware_t &ware, const uint32 journey_time = UINT32_MAX_VALUE) const;
void get_destination_halts_of_ware(ware_t &ware, vector_tpl<halthandle_t>& destination_halts_list) const;
uint32 find_route(const vector_tpl<halthandle_t>& ziel_list, ware_t & ware, const uint32 journey_time = UINT32_MAX_VALUE, const koord destination_pos = koord::invalid) const;
inline bool get_pax_enabled() const { return enables & PAX; }
inline bool get_mail_enabled() const { return enables & POST; }
inline bool get_ware_enabled() const { return enables & WARE; }
// check, if we accepts this good
// often called, thus inline ...
inline bool is_enabled( const goods_desc_t *wtyp ) const {
return is_enabled(wtyp->get_catg_index());
}
// a separate version for checking with goods category index
inline bool is_enabled( const uint8 catg_index ) const
{
if (catg_index == goods_manager_t::INDEX_PAS) {
return enables&PAX;
}
else if(catg_index == goods_manager_t::INDEX_MAIL) {
return enables&POST;
}
return enables&WARE;
}
// The stop does not handle any goods. only possible to stop
bool is_not_enabled() const
{
return enables == NOT_ENABLED;
}
// for gui purpose
// Compare convoy/line and halt to determine if it has a matching attribute. If not, loading cannot be executed.
bool can_serve(linehandle_t line) const;
bool can_serve(convoihandle_t cnv) const;
/**
* Found route and station uncrowded
*/
void add_pax_happy(int n);
/**
* Station in walking distance
*/
void add_pax_walked(int n);
/**
* Found no route
*/
void add_pax_no_route(int n);
// count mail no route or delivered
void add_mail_delivered(int n);
void add_mail_no_route(int n);
/**
* Station crowded
*/
void add_pax_unhappy(int n);
// The number of passengers for whom the shortest
// route exceeds their time tolerance.
// @author: jamespetts
void add_pax_too_slow(int n);
// Waiting so long at the station. added 01/2019(EX14.3)
void add_pax_too_waiting(int n);
int get_pax_happy() const { return (int)financial_history[0][HALT_HAPPY]; }
int get_pax_no_route() const { return (int)financial_history[0][HALT_NOROUTE]; }
int get_pax_unhappy() const { return (int)financial_history[0][HALT_UNHAPPY]; }
int get_pax_too_slow() const { return (int)financial_history[0][HALT_TOO_SLOW]; }
int get_pax_too_waiting() const { return (int)financial_history[0][HALT_TOO_WAITING]; }
int get_mail_delivered() const { return (int)financial_history[0][HALT_MAIL_DELIVERED]; }
int get_mail_no_route() const { return (int)financial_history[0][HALT_MAIL_NOROUTE]; }
/**
* Add tile to list of station tiles.
* @param relink_factories if true call verbinde_fabriken, if not true take care of factory connections yourself
*/
bool add_grund(grund_t *gb, bool relink_factories = true, bool recalc_nearby_halts = true);
bool rem_grund(grund_t *gb);
uint32 get_capacity(uint8 typ) const { return capacity[typ]; }
bool existiert_in_welt() const;
koord get_init_pos() const { return init_pos; }
koord get_basis_pos() const;
koord3d get_basis_pos3d() const;
/**
* return the closest square that belongs to this halt
*/
koord get_next_pos( koord start, bool square = false ) const;
// true, if this station is overcrowded for this category
bool is_overcrowded( const uint8 idx ) const { return (overcrowded[idx/8] & (1<<(idx%8)))!=0; }
sint64 get_overcrowded_proporion(uint8 typ) const;
/// @returns total amount of the good waiting at this halt.
uint32 get_ware_summe(const goods_desc_t *warentyp) const;
uint32 get_ware_summe(const goods_desc_t *warentyp, uint8 wealth_class, bool chk_only_commuter = false) const;
uint32 get_ware_summe(const goods_desc_t *warentyp, linehandle_t line, uint8 wealth_class=255) const;
// Specify the section in the schedule entry to distinguish the direction heading out of the station
uint32 get_ware_summe_for(const goods_desc_t *warentyp, linehandle_t line, uint8 wealth_class = 255, uint8 entry_start=0, uint8 entry_end=255) const;
uint32 get_leaving_goods_sum(const goods_desc_t *warentyp, uint8 g_class = 255) const;
uint32 get_transferring_goods_sum(const goods_desc_t *warentyp, uint8 g_class = 255) const;
/**
* returns total number for a certain position (since more than one factory might connect to a stop)
*/
uint32 get_ware_fuer_zielpos(const goods_desc_t *warentyp, const koord zielpos) const;
/**
* True if we accept/deliver this kind of good
*/
bool gibt_ab(const goods_desc_t *warentyp) const { return cargo[warentyp->get_catg_index()] != NULL; }
bool accepts_goods_catg(uint8 goods_catg) const { return cargo[goods_catg] != NULL; }
/**
* retrieves a ware packet for any destination in the list
* needed, if the factory in question wants to remove something
*/
bool recall_ware( ware_t& w, uint32 menge );
/**
* Fetches goods from this halt. Returns true if other convois on the same line should try loading these goods because this convoi is awaiting spacing, if not preferred, or is overcrowded
* Fetches goods from this halt
* @param load Output parameter. Goods will be put into this list, the vehicle has to load them.
* @param good_category Specifies the kind of good (or compatible goods) we are requesting to fetch from this stop.
* @param requested_amount How many units of the cargo we can fetch.
*/
bool fetch_goods( slist_tpl<ware_t> &load, const goods_desc_t *good_category, sint32 requested_amount, const schedule_t *schedule, const player_t *player, convoi_t* cnv, bool overcrowd, const uint8 g_class, const bool use_lower_classes, bool& other_classes_available, const bool mixed_load_prohibition, uint8 goods_restriction);
/**
* Delivers goods (ware_t) to this halt.
* if no route is found, the good will be removed.
*
* The second version is like the first, but will not recalculate the route
* This is used for inital passenger, since they already know a route
*
* @returns amount of goods
*/
void liefere_an(ware_t ware, uint8 walked_between_stations = 0);
void starte_mit_route(ware_t ware, koord origin_pos);
const grund_t *find_matching_position(waytype_t wt) const;
/**
* checks, if there is an unoccupied loading bay for this kind of thing
*/
bool find_free_position(const waytype_t w ,convoihandle_t cnv,const obj_t::typ d) const;
/**
* reserves a position (caution: railblocks work differently!
*/
bool reserve_position(grund_t *gr,convoihandle_t cnv);
/**
* frees a reserved position (caution: railblocks work differently!
*/
bool unreserve_position(grund_t *gr, convoihandle_t cnv);
/** true, if this can be reserved
*/
bool is_reservable(const grund_t *gr, convoihandle_t cnv) const;
uint8 get_empty_lane(const grund_t *gr, convoihandle_t cnv) const;
/**
* return update flag of waiting cargo info.
*/
bool get_freight_info();
/**
* Opens an information window for this station.
*/
void show_info();
void show_detail();
/**
* @return the type of a station
* (combination of: railstation, loading bay, dock)
*/
stationtyp get_station_type() const { return station_type; }
void recalc_station_type();
/**
* fragt den namen der Haltestelle ab.
* Der Name ist der text des ersten Untergrundes der Haltestelle
* @return der Name der Haltestelle.
*/
const char *get_name() const;
void set_name(const char *name);
// create an unique name: better to be called with valid handle, although it will work without
char* create_name(koord k, char const* typ);
void rdwr(loadsave_t *file);
void finish_rd(bool need_recheck_for_walking_distance);
/**
* Called before savegame will be loaded.
* Creates all_koords table.
*/
static void start_load_game();
/**
* Called after loading of savegame almost finished,
* i.e. after finish_rd is finished.
* Deletes all_koords table.
*/
static void end_load_game();
/**
* called, if a line serves this stop
*/
void add_line(linehandle_t line);
/**
* called, if a line removes this stop from it's schedule
*/
void remove_line(linehandle_t line);
/**
* list of line ids that serve this stop
*/
vector_tpl<linehandle_t> registered_lines;
/**
* Register a lineless convoy which serves this stop
*/
void add_convoy(convoihandle_t convoy);
/**
* Unregister a lineless convoy
*/
void remove_convoy(convoihandle_t convoy);
/**
* A list of lineless convoys serving this stop
*/
vector_tpl<convoihandle_t> registered_convoys;
// Update and recalculate the cached service intervals
void update_service_intervals(schedule_t* sch);
#ifdef ALWAYS_CACHE_SERVICE_INTERVAL
// This is a selective clear of the service intervals:
// this will clear the service intervals to stops
// on this schedule only. To clear all service intervals,
// run service_intervals.clear().
void clear_service_intervals(schedule_t* sch);
#endif
/**
* It will calculate number of free seats in all other (not cnv) convoys at stop
* @author Inkelyad
*/
void update_alternative_seats(convoihandle_t cnv);
/**
* book a certain amount into the halt's financial history
*/
void book(sint64 amount, int cost_type);
/**
* return a pointer to the financial history
*/
sint64* get_finance_history() { return *financial_history; }
/**
* return a specified element from the financial history
*/
sint64 get_finance_history(int month, int cost_type) const { return financial_history[month][cost_type]; }
/* marks a coverage area */
void mark_unmark_coverage(const bool mark, const bool factories = false) const;
uint32 get_around_population(uint8 g_class = 255) const;
uint32 get_around_visitor_demand(uint8 g_class = 255) const;
uint32 get_around_job_demand(uint8 g_class = 255) const;
uint32 get_around_visitor_generated() const;
uint32 get_around_succeeded_visiting() const;
uint32 get_around_commuter_generated() const;
uint32 get_around_succeeded_commuting() const;
// Returns the current number of workers, but overflows are truncated per building.
uint32 get_around_employee_factor() const;
uint32 get_around_mail_demand() const;
uint32 get_around_mail_generated() const;
uint32 get_around_mail_delivery_succeeded() const;
// The number of passengers who have tried to use this station.
sint64 get_potential_passenger_number(uint8 month) const
{
sint64 sum=0;
sum += financial_history[month][HALT_HAPPY];
sum += financial_history[month][HALT_UNHAPPY];
sum += financial_history[month][HALT_NOROUTE];
sum += financial_history[month][HALT_TOO_SLOW];
sum += financial_history[month][HALT_TOO_WAITING];
return sum;
}
// Getting and setting average waiting times in minutes
// @author: jamespetts
uint32 get_average_waiting_time(halthandle_t halt, uint8 category, uint8 g_class);
void add_waiting_time(uint32 time, halthandle_t halt, uint8 category, uint8 g_class, bool do_not_reset_month = false);
connexions_map* get_connexions(uint8 catg, uint8 g_class) { return connexions[catg][g_class]; }
linehandle_t get_preferred_line(halthandle_t transfer, uint8 category, uint8 g_class) const;
convoihandle_t get_preferred_convoy(halthandle_t transfer, uint8 category, uint8 g_class) const;
// Added by : Knightly
// Adapted from : Jamespetts' code
// Purpose : To notify relevant halts to rebuild connexions and to notify all halts to recalculate paths
// @jamespetts: modified the code to combine with previous method and provide options about partially delayed refreshes for performance.
static void refresh_routing(const schedule_t *const sched, const minivec_tpl<uint8> &categories, const minivec_tpl<uint8> *passenger_classes, const minivec_tpl<uint8> *mail_classes, const player_t *const player);
// Added by : Knightly
// Adapted from : haltestelle_t::add_connexion()
// Purpose : Create goods list of specified goods category if it is not already present
void prepare_goods_list(uint8 category)
{
if (cargo[category] == NULL )
{
// indicates that this can route those goods
cargo[category] = new vector_tpl<ware_t>(0);
}
}
// Addedy by : Knightly
// Purpose : Return the time at which the halt was first created
sint64 get_inauguration_time() { return inauguration_time; }
/*
* deletes factory references so map rotation won't segfault
*/
void release_factory_links();
/**
* Get queue position for spacing. It is *not* same as index in 'loading_here'.
*/
int get_queue_pos(convoihandle_t cnv) const;
bool check_access(const player_t* player) const;
bool has_available_network(const player_t* player, uint8 catg_index=goods_manager_t::INDEX_NONE) const;
// Check if passed waytype's service is active
// This is not affected by dummy bus stops intended to increase capacity,
// so it's a more accurate judgment than checking facilities.
bool has_waytype_service(waytype_t wt) const;
bool has_no_control_tower() const;
/**
* Get the time that it takes for passengers to transfer within this stop
* in 1/10ths of minutes.
*/
inline uint32 get_transfer_time() const { return transfer_time; }
/**
* Get the time that it takes for goods to be transferred within this stop
* in 1/10ths of minutes.
*/
inline uint32 get_transshipment_time() const { return transshipment_time; }
void set_reroute_goods_next_step(uint8 catg) { categories_to_refresh_next_step.append(catg); }
/**
* Calculate the transfer and transshipment time values.
*/
void calc_transfer_time();
/**
* The average time in 10ths of minutes between convoys to this destination
*/
uint32 get_service_frequency(halthandle_t destination, uint8 category) const;
uint32 calc_service_frequency(halthandle_t destination, uint8 category) const;
void set_estimated_arrival_time(uint16 convoy_id, sint64 time);
void set_estimated_departure_time(uint16 convoy_id, sint64 time);
/**
* Removes a convoy from the time estimates.
* Used when deleting a convoy.