forked from AlbertBall/railway-dot-exe
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTrackUnit.h
1875 lines (1664 loc) · 115 KB
/
TrackUnit.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
// TrackUnit.h
/*
Comments in .h files are believed to be accurate and up to date
This is a source code file for "railway.exe", a railway operation
simulator, written originally in Borland C++ Builder 4 Professional with
later updates in Embarcadero C++Builder.
Copyright (C) 2010 Albert Ball [original development]
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// ---------------------------------------------------------------------------
#ifndef TrackUnitH
#define TrackUnitH
// ---------------------------------------------------------------------------
#include <vcl.h>
#include <vector>
#include <map>
#include <fstream>
#include <list>
#include <utility> //for pair
#include "DisplayUnit.h" //for UserGraphicVector
#include <windows.h> //needed for 64 bit compilation
#define FirstUnusedSpeedTagNumber 147 //defined value for use in array sizing etc
// ---------------------------------------------------------------------------
typedef std::pair<int, int> THVPair;
///< HLoc/VLoc position pair
class TDisplay;
///< type only declared here to allow access, full declaration in DisplayUnit
class TPrefDirElement;
///< forward declaration because needed in TTrack
typedef std::vector<TPrefDirElement> TPrefDirVector;
///< forward declaration because needed in TTrack
// ---------------------------------------------------------------------------
/// Map and multimap comparator based on horizontal & vertical position
class TMapComp
{
public:
/// HLoc VLoc
bool operator()(const THVPair& lower, const THVPair& higher) const;
};
// ---------------------------------------------------------------------------
enum TTrackType
///< describes the type of track element
{
Simple, Crossover, Points, Buffers, Bridge, SignalPost, Continuation, Platform, GapJump, FootCrossing, Unused,
Concourse, Parapet, NamedNonStationLocation, Erase, LevelCrossing
};
// FootCrossing covers footbridge & underpass/surface, 'unused' was marker the for old 'text' number, since disused
// Concourse, Parapet, NamedNonStationLocation, Platform & LevelCrossing are the 5 types of inactive element
// Erase was the default active element used for erasing, not used now (all data members unset)
enum TConfiguration
///< describes the type of track link. 'End' is used for both buffer stop and continuation entry/exit positions
{
NotSet, Connection, End, Gap, Lead, Trail, CrossConn, Under, Signal
};
// FIXED TRACK :-
// All basic track building blocks & methods
class TFixedTrackPiece
{
public: // everything uses these - should really have Gets & Sets but too many to change now
bool FixedNamedLocationElement;
///< true for an element that can be named (platforms, concourse, footcrossings & non-station named loactions)
int SpeedTag;
///< The element identification number - corresponds to the relevant SpeedButton->Tag
int Link[4];
///< Track connection link values, max. of 4, unused = -1, top lh diag = 1, top = 2, top rh diag = 3, left = 4, right = 6, bottom lh diag = 7, bottom = 8, bottom rh diag = 9
Graphics::TBitmap *GraphicPtr;
///< the track bitmap for display on the zoomed-in railway
Graphics::TBitmap *SmallGraphicPtr;
///< the track bitmap for display on the zoomed-out railway
TConfiguration Config[4];
///< the type of link - see TConfiguration above
TTrackType TrackType;
///< the type of track element
/// Plot the element on the railway display at position HLocInput & VLocInput
void PlotFixedTrackElement(int Caller, int HLocInput, int VLocInput) const;
/// Constructor for building TTrack.FixedTrackArray - see below
TFixedTrackPiece(int SpeedTagVal, TTrackType TrackTypeVal, int LkVal[4], TConfiguration ConfigVal[4], Graphics::TBitmap *GraphicPtrVal,
Graphics::TBitmap *SmallGraphicPtrVal);
/// Default constructor
TFixedTrackPiece();
};
// ---------------------------------------------------------------------------
// VARIABLE TRACK :-
// ---------------------------------------------------------------------------
/* Note: Should probably have used different derived classes for the different track types, to avoid all having
attributes & other specific data, but by the time this occurred to me as a good idea it seemed likely to be more difficult
to backtrack than to put up with the extra & unused data.
*/
/// Basic track elements as implemented in the overall railway layout
class TTrackElement : public TFixedTrackPiece
{
public: // everything uses these - should really have Gets & Sets but too many to change now
AnsiString ActiveTrackElementName;
///< Location name used either in the timetable or for a continuation (continuation names not used in timetable as trains can't stop there). Only active track elements where there are platforms or non-station named locations (not footcrossings) have ActiveTrackElementNames
AnsiString ElementID;
///< the element identifier based on position in the railway
AnsiString LocationName;
///< location name not used for timetabling, only for identification: platforms, non-station named locations, concourses (inactive) and footcrossings (active) have LocationNames
bool CallingOnSet;
///< Used for for signals only when a train is being called on - used to plot the position lights
bool LCPlotted;
///< Utility marker to avoid plotting every element of a multitrack LC during ClearandRebuildRailway
bool TempTrackMarker01, TempTrackMarker23;
///< Utility markers for program use, not used from v2.12.0
bool Failed;
///< New parameter added at v2.13.0 for failed points, signals & TSRs
int Attribute;
///< special variable used only for points, signals & level crossings, ignored otherwise; points 0=set to go straight, 1=set to diverge, where both legs diverge 0=set to left fork; signals: 0=red; 1=yellow; 2=double yellow; 3 = green; Level crossing: 0 = raised barriers = closed to trains; 1 = lowered barriers = open to trains; 2 = changing state = closed to trains
int Conn[4];
///< Connecting element position in TrackVector, set to -1 if no connecting link or if track not linked
int ConnLinkPos[4];
///< Connecting element link position (i.e. array positions of the connecting element links, in same order as Link[4])
int HLoc, VLoc;
///< The h & v locations in the railway (top lh corner of the first build screen = 0,0)
int Length01, Length23, SpeedLimit01, SpeedLimit23;
///< Element lengths and speed limits, ...01 is for the track with link positions [0] and [1], ...23 for [2] and [3], set to -1 if not used (lengths in m & speed limits in km/h)
int StationEntryStopLinkPos1, StationEntryStopLinkPos2, StationEntryStopLinkPos3, StationEntryStopLinkPos4;
///< Used for track at platforms ( 1 & 2) and non-station named locations (1 - 4) to mark the train front element stop position, 3 & 4 added at v2.18.0 to allow non-station names on 4-track elements
int TrainIDOnElement, TrainIDOnBridgeOrFailedPointOrigSpeedLimit01, TrainIDOnBridgeOrFailedPointOrigSpeedLimit23;
///< Set to the TrainID value for a bridge when a train is present on the element, bridges can have two trains present so the ...01 and ...23 values give the TrainIDs for track with link positions [0] & [1], and [2] & [3] respectively, set to -1 if no train present
///< For a failed point store the original speedlimits, names changed at v2.13.0 to cater for failed points (OK as these not used for points, only bridges)
enum
///< added at version 0.6
{
FourAspect, ThreeAspect, TwoAspect, GroundSignal
} SigAspect;
// inline functions
/// Constructor for non-specific default element. Use high neg numbers for 'unset' h & v as can go high negatively legitimately
TTrackElement() : TFixedTrackPiece(), HLoc(-2000000000), VLoc(-2000000000), LocationName(""), ActiveTrackElementName(""), Attribute(0), CallingOnSet(false),
Length01(-1), Length23(-1), SpeedLimit01(-1), SpeedLimit23(-1), TrainIDOnElement(-1), TrainIDOnBridgeOrFailedPointOrigSpeedLimit01(-1),
TrainIDOnBridgeOrFailedPointOrigSpeedLimit23(-1), StationEntryStopLinkPos1(-1), StationEntryStopLinkPos2(-1), StationEntryStopLinkPos3(-1),
StationEntryStopLinkPos4(-1), SigAspect(FourAspect)
{
Failed = false; //added at v2.13.1
for(int x = 0; x < 4; x++)
{
ConnLinkPos[x] = -1;
Conn[x] = -1;
}
}
// functions defined in .cpp file
bool operator == (TTrackElement RHElement);
///< equivalence operator
bool operator != (TTrackElement RHElement);
///< non-equivalence operator
AnsiString LogTrack(int Caller) const;
///< Used to log track parameters for call stack logging
void PlotVariableTrackElement(int Caller, TDisplay *Disp) const;
///< Plot the element on the display 'variable' indicates that the element may be named and if so may be plotted striped or solid depending on whether the name has been set
/// Constructor for specific type of element. Use very high neg. numbers as 'unset' values for HLoc & VLoc initially as can go high negatively legitimately, build from existing TTrackPiece with default values for extra members
TTrackElement(TFixedTrackPiece Input);
};
// ---------------------------------------------------------------------------
// PrefDir & Route elements
// ---------------------------------------------------------------------------
/// Basic preferred direction or route element - track element with additional members
class TPrefDirElement : public TTrackElement
{
protected:
int ELink, ELinkPos;
///< entry link number & array position
int XLink, XLinkPos;
///< exit link number & array position
int EXNumber;
///< used to facilitate identification of the appropriate preferred direction or route graphic
int TrackVectorPosition;
///< TrackVectorPosition of the corresponding track element
int CheckCount;
///< internal check value used when building preferred directions
Graphics::TBitmap *EXGraphicPtr, *EntryDirectionGraphicPtr;
///< pointers to the appropriate entry/exit graphic, or direction marker graphic, for preferred directions and routes
bool operator == (TPrefDirElement RHElement);
///< equivalence operator
bool operator != (TPrefDirElement RHElement);
///< non-equivalence operator
public:
friend class TOnePrefDir;
friend class TOneRoute;
friend class TAllRoutes;
bool IsARoute;
///< false for Pref Dir, true for route
bool AutoSignals;
///< marker within the route for an AutoSignal route element
bool PrefDirRoute;
///< marker within the route for preferred direction route element
// inline functions
/// Position check
bool IsPosition(int Position) const
{
if(TrackVectorPosition == Position)
{
return(true);
}
else
{
return(false);
}
}
/// Returns SpeedTag //added at v2.9.2 for clipboard storage
int GetSpeedTag() const
{
return(SpeedTag);
}
/// Returns HLoc //added at v2.9.0 for clipboard storage
int GetHLoc() const
{
return(HLoc);
}
/// Returns VLoc //added at v2.9.0 for clipboard storage
int GetVLoc() const
{
return(VLoc);
}
/// Returns ELink
int GetELink() const
{
return(ELink);
}
/// Returns the ELink array position
int GetELinkPos() const
{
return(ELinkPos);
}
/// Returns XLink
int GetXLink() const
{
return(XLink);
}
/// Returns the XLink array position
int GetXLinkPos() const
{
return(XLinkPos);
}
/// Returns EXNumber //added at v2.9.0 for clipboard storage
int GetEXNumber()
{
return(EXNumber);
}
/// Returns CheckCount
int GetCheckCount() //added at v2.9.1
{
return(CheckCount);
}
/// Returns TrackVectorPosition
unsigned int GetTrackVectorPosition() const
{
return(TrackVectorPosition);
}
/// Returns signed integer value of TrackVectorPosition (used in flip, mirror etc for pref dirs) added at v2.9.1
int GetSignedIntTrackVectorPosition() const
{
return(TrackVectorPosition);
}
/// Returns EXGraphicPtr for preferred directions
Graphics::TBitmap *GetEXGraphicPtr()
{
return(GetPrefDirGraphicPtr());
}
/// Returns route graphic
Graphics::TBitmap *GetRouteEXGraphicPtr()
{
return(GetRouteGraphicPtr(AutoSignals, PrefDirRoute));
}
/// Used in pasting pref dirs
void SetTrackVectorPosition(int TVPos) // added at v2.9.0
{
TrackVectorPosition = TVPos;
}
void SetCheckCount(int ChkCnt) //added at v2.9.1
{
CheckCount = ChkCnt;
}
/// Used in pasting pref dirs
void SetELink(int input) // added at v2.9.0
{
ELink = input;
}
/// Used in pasting pref dirs
void SetELinkPos(int input) // added at v2.9.0
{
ELinkPos = input;
}
/// Used in pasting pref dirs
void SetXLink(int input) // added at v2.9.0
{
XLink = input;
}
/// Used in pasting pref dirs
void SetXLinkPos(int input) // added at v2.9.0
{
XLinkPos = input;
}
/// Used in pasting pref dirs
void SetEXNumber(int input) // added at v2.9.0
{
EXNumber = input;
}
/// Used in pasting pref dirs
void SetEXGraphicPtr(Graphics::TBitmap *input) //added at v2.9.1
{
EXGraphicPtr = input;
}
/// Used in pasting pref dirs
void SetEntryDirectionGraphicPtr(Graphics::TBitmap *input) //added at v2.9.1
{
EntryDirectionGraphicPtr = input;
}
/// Default constructor, loads default values
TPrefDirElement() : TTrackElement(), ELink(-1), ELinkPos(-1), XLink(-1), XLinkPos(-1), EXNumber(-1), TrackVectorPosition(-1), CheckCount(0), EXGraphicPtr(0),
EntryDirectionGraphicPtr(0), IsARoute(false), AutoSignals(false), PrefDirRoute(false)
{
;
}
/// Constructs a PrefDirElement from a base TrackElement. Sets up the TrackElement values but leaves others as default values
TPrefDirElement(TTrackElement Input) : TTrackElement(Input), ELink(-1), ELinkPos(-1), XLink(-1), XLinkPos(-1), EXNumber(-1), TrackVectorPosition(-1),
CheckCount(0), EXGraphicPtr(0), EntryDirectionGraphicPtr(0), IsARoute(false), AutoSignals(false), PrefDirRoute(false)
{
;
}
// external functions
bool EntryExitNumber();
///< determines and loads EXNumber (see above)
AnsiString LogPrefDir() const;
///< Sends a list of PrefDirElement values to Utilities->CallLog file for debugging purposes
TPrefDirElement(TTrackElement InputElement, int ELink, int ELinkPos, int XLink, int XLinkPos, int TrackVectorPosition);
///< Constructs a PrefDirElement from supplied values
Graphics::TBitmap *GetDirectionPrefDirGraphicPtr() const;
///< picks up the EntryDirectionGraphicPtr for preferred directions
Graphics::TBitmap *GetDirectionRouteGraphicPtr(bool AutoSigsFlag, bool PrefDirRoute) const;
///< picks up the green or red route direction graphic
Graphics::TBitmap *GetOriginalGraphicPtr();
///< picks up the original (non-flashing) graphic for use during route flashing
Graphics::TBitmap *GetPrefDirGraphicPtr();
///< picks up the EXGraphicPtr for preferred directions
Graphics::TBitmap *GetRouteAutoSigsGraphicPtr();
///< picks up the blue route graphic (not used - superseded by GetRouteGraphicPtr)
Graphics::TBitmap *GetRouteGraphicPtr(bool AutoSigsFlag, bool PrefDirRoute);
///< picks up the appropriate route graphic
int GetRouteColour(Graphics::TBitmap *EXG);
///< finds the route colour for a specific prefdir element with EXGraphicPtr EXG
};
// ---------------------------------------------------------------------------
/// Allows a single Width x Height graphic to change and change back independently of the remaining display
/**
Used for the flashing green and red gap markers, flashing points and route start graphics. The code is mostly self-explanatory, but SetScreenHVSource (sets source
rectangle) must be called before the original graphic is loaded, whether or not the graphic is loaded from the screen (using
LoadOriginalScreenGraphic, for point flashing and route start markers) or an existing bitmap (using LoadOriginalExistingGraphic, for red
and green gap flashing), and OverlayGraphic and OriginalGraphic must be loaded before they are plotted. Checks are
built in for these conditions. SourceRect is the rectangle on the appropriate canvas where the original graphic is taken from. The
original graphic can be taken from the screen - LoadOriginalScreenGraphic(), or from a section from an existing bitmap -
LoadOriginalExistingGraphic. If an existing bitmap is selected then the loading function overrides the size that was set in the
constructor, and SourceRect & HPos & VPos that were set in SetScreenHVSource.
*/
class TGraphicElement
{
private:
bool OverlayPlotted, OverlayLoaded, OriginalLoaded, ScreenSourceSet, ScreenGraphicLoaded, ExistingGraphicLoaded;
///< state flags
int HPos, VPos;
///< horizontal and vertical positions
int Width, Height;
///< dimensions in pixels
Graphics::TBitmap *OriginalGraphic, *OverlayGraphic;
///< original and temporary overlay graphics
TRect SourceRect;
///< source rectangle of the original graphic
public:
// inline functions
int GetHPos()
{
return(HPos);
}
int GetVPos()
{
return(VPos);
}
/// Set SourceRect member values from those supplied and existing Width & Height - ensure this is only called after Width & Height are set
void SetSourceRect(int Left, int Top)
{
SourceRect.init(Left, Top, Left + Width, Top + Height);
}
// functions defined in .cpp file
void LoadOriginalExistingGraphic(int Caller, int HOffset, int VOffset, int WidthIn, int HeightIn, Graphics::TBitmap *Graphic);
///< Load red or green gap flashing graphic from the stored bitmaps
void LoadOriginalScreenGraphic(int Caller);
///< Load original graphic from the screen for point flashing or route start markers
void LoadOverlayGraphic(int Caller, Graphics::TBitmap *Overlay);
///< Load the temporary overlay graphic
void PlotOverlay(int Caller, TDisplay *Disp);
///< Plot the overlay graphic on screen
void PlotOriginal(int Caller, TDisplay *Disp);
///< Plot the original graphic on screen
void SetScreenHVSource(int Caller, int HPosIn, int VPosIn);
///< Set HPos, VPos & SourceRect member values from the supplied positions
TGraphicElement();
///< Default constructor (16 x 16 pixel element)
TGraphicElement(int WidthIn, int HeightIn);
///< Constructor for specified dimensions
~TGraphicElement();
///< Destructor
};
// ---------------------------------------------------------------------------
/** Identification Number:
This was introduced when it was decided to have a route identification number for each route rather than using the vector
position number for identifying existing routes that were being extended during route building. Using vector position numbers
meant that these identification numbers had to be changed when existing routes were erased by trains passing over them. IDInt is
used for StartSelectionRouteID and ReqPosRouteID (see TAllRoutes) and ensures that any confusion with the old vector position
numbers is picked up by the compiler. Note that the route's RouteID value is an 'int', not an 'IDInt', 'IDInt' is only used for
StartSelectionRouteID and ReqPosRouteID */
class IDInt
{
private:
int InternalInt;
///< the internal integer value represented by IDInt
public:
// all inline
/// get the internal integer
int GetInt() const
{
return(InternalInt);
}
/// Equality comparator
bool operator == (IDInt Comparator)
{
return (InternalInt == Comparator.InternalInt);
}
/// Greater than comparator
bool operator > (int Comparator)
{
return (InternalInt > Comparator);
}
/// Constructor that sets the internal integer to the input value. The 'explicit' prefix is used to force a compiler error if the input value is an IDInt, which would be a program error (otherwise it would be implicitly converted to an int)
explicit IDInt(int Int)
{
InternalInt = Int;
}
/// Default constructor, internal integer set to -1
IDInt()
{
InternalInt = -1;
}
};
// ---------------------------------------------------------------------------
// Track
// ---------------------------------------------------------------------------
/**All dynamic track data & methods. Only one object since only one operating railway
Note: The TrackMap & InactiveTrackMap were developed well after the TrackVector, to speed up track element
searches. It was realised at that time that the maps themselves could contain type TTrackElement rather than int
(for TrackVectorPosition), and that the track vectors could be dispensed with completely. However after an attempt
to remove them it was clear that they were far too embedded throughout the program for easy removal, so they were
left in. */
class TTrack
{
private:
/// Holds an array of TrackPieces, only accessible to TTrack
class TFixedTrackArray
{
public:
TFixedTrackPiece FixedTrackPiece[FirstUnusedSpeedTagNumber];
///< the array member
/// Array constructor
TFixedTrackArray();
};
TFixedTrackArray FixedTrackArray;
///< the FixedTrackPiece array object
TTrackElement DistanceStartElement, DistanceContinuingElement;
///< initially used for track element lengths but since disused
bool TrackFinished;
///< marker for all Conn & ConnLinkPos values set & track complete
int GapPos, GapHLoc, GapVLoc;
///< record gap setting info
int HLocMin, VLocMin, HLocMax, VLocMax;
///< give extent of railway for use in zoomed in and out displays and in saving railway images
int LinkCheckArray[9][2];
///< array of valid link connecting values, I don't think this is used now
int LinkHVArray[10][2];
///< array used to determine relative horizontal & vertical track element positions for specific link values
int Tag76Array[25][3];
///< these arrays give valid adjacent named element relative positions for each type of named element, the numbers - 76, 77 etc - relate to track element element SpeedTag values (76 - 79 = platforms, 96 = concourse, 129 & 130 = footbridges, 145 & 146 underpasses and 131 = non-station named location.
int Tag77Array[25][3];
int Tag78Array[25][3];
int Tag79Array[25][3];
int Tag96Array[28][3];
int Tag129Array[8][3];
int Tag130Array[8][3];
int Tag131Array[4][3];
int Tag145Array[8][3];
int Tag146Array[8][3];
Set<int, 1, 146>TopPlatAllowed, BotPlatAllowed, LeftPlatAllowed, RightPlatAllowed, NameAllowed, LevelCrossingAllowed;
///< sets of valid TrackElements for placement of platforms and non-station named locations
public:
/*
All LCs begin with barriers raised. i.e. closed to trains, that is the normal state. When a route is set through an LC an active LC object is created
by SetLCChangeValues (called by ConvertandAdd.... for lowering barriers) and added to the
ChangingLCVector. Once created 'FlashingGraphics' takes care of the flashing, until the duration is reached. While flashing no further routes
can be set through that LC and the first route can't be cancelled, hence the flashing only needs to cater for plotting the route on the one track that
started the barrier lowering. When the duration is reached, the object is transferred to a new vector BarriersDownVector, after the StartTime has been
reset (to time the period for which the barriers are down - penalties are given for > 3 minutes), BarrierState changed to Down, and the object erased
from ChangingLCVector. When there is no route through an LC and no train on the track then the barriers are raised - in ClockTimer2 - when the
BarriersDownVector object is copied back to ChangingLCVector with a new StartTime, BarrierState and ChangeDuration. Again FlashingGraphics takes care
of the flashing until the duration is reached, when the object is erased from the vector and the LC reverts to its normal (barriers raised) state.
At v2.6.0 LCs could be lowered and raised manually, manual LCs are shown lowering and down as green and indicated by TypeOfRoute being 2. A manual LC
can't have a route set while changing; can't be opened while a route is set; and must be opened manually.*/
enum TBarrierState
///< state of barriers, values for level crossings either changing state or with barriers up or down
{
Raising, Lowering, Up, Down
};
class TActiveLevelCrossing
{
public:
int TypeOfRoute;
///< route type - 0 = nonsignals, 1 = preferred direction (can't have autosigs), 2 no route, 2 added at v2.6.0 for manual operation
bool ReducedTimePenalty;
///< marker that is set when a train is present on one of the elements of the LC - used to provide a 3 minute penalty allowance
TBarrierState BarrierState;
///< state of barriers - Raising, Lowering, Up, Down (an enum - see above)
float ChangeDuration;
///< duration of the level crossing changing period
int BaseElementSpeedTag;
///< SpeedTag value for the base element of a level crossing
int HLoc;
///< HLoc value for found level crossing element
int VLoc;
///< VLoc value for found level crossing element
TDateTime StartTime;
///< stores the starting time for level crossing changing
TActiveLevelCrossing();
///< constructor, sets default values
};
typedef std::vector<TActiveLevelCrossing>TActiveLCVector;
///< vector of changing level crossing objects. Note that although a LC may contain several elements there will be only one in the vector when changing, and it might be any of the individual elements. This is because when an entry is made all linked elements have their attributes changed to 2 for changing, so no more are found. This applies both for closing & opening to trains
typedef std::vector<int>TLCVector;
///< vector of level crossing InactiveTrackVector positions - note that this contains all LC elements whether linked to others or not
typedef std::vector<TUserGraphicItem>TUserGraphicVector;
///< vector of UserGraphicItems
typedef std::vector<TTrackElement>TTrackVector;
///< vector of TrackElements
typedef std::vector<TTrackElement>::iterator TTrackVectorIterator;
///< iterator for TTrackVector
typedef std::map<AnsiString, TPicture*>TUserGraphicMap;
///< map of filenames as key and TPicture* as value. This holds all the TPicture pointers created when a user graphic is selected
typedef std::pair<AnsiString, TPicture*>TUserGraphicMapEntry;
///<an entry for TUserGraphicMap
typedef std::map<THVPair, unsigned int, TMapComp>TTrackMap;
///< map of TrackElement TrackVectorPositions, HLoc & VLoc pair is the key
typedef TTrackMap::iterator TTrackMapIterator;
typedef std::pair<THVPair, unsigned int>TTrackMapEntry;
typedef std::map<THVPair, THVPair, TMapComp>TGapMap;
///< map of matching gap positions as an HLoc/VLoc pair, with the key being
typedef TGapMap::iterator TGapMapIterator;
///< the first gap HLoc/VLoc pair, contains one entry for each pair of matched gaps
typedef std::pair<THVPair, THVPair>TGapMapEntry;
typedef std::multimap<THVPair, unsigned int, TMapComp>TInactiveTrack2MultiMap;
///< multimap of inactive TrackElements (platforms, concourses, non-station named locations, parapets & level crossings) '2' because can have 2 entries (platforms) at a single location
typedef TInactiveTrack2MultiMap::iterator TInactiveTrack2MultiMapIterator;
///< iterator for TInactiveTrack2MultiMap
typedef std::pair<TInactiveTrack2MultiMapIterator, TInactiveTrack2MultiMapIterator>TInactiveTrackRange;
///< range for TInactiveTrack2MultiMap
typedef std::pair<unsigned int, unsigned int>TIMPair;
///< TrackElement pair type used for inactive elements, values are vector positions
typedef std::list<int>TLNPendingList;
///< type list of location name vector positions (see note below) used during
typedef TLNPendingList::iterator TLNPendingListIterator;
///< naming of linked named location elements
typedef std::multimap<THVPair, int, TMapComp>TLNDone2MultiMap;
///< multimap of location name vector positions (see note below) used
typedef TLNDone2MultiMap::iterator TLNDone2MultiMapIterator;
///< during naming of linked named location elements, '2' because there
typedef std::pair<THVPair, int>TLNDone2MultiMapEntry;
///< can be up to 2 entries (platforms) at a single location
typedef std::multimap<AnsiString, int>TLocationNameMultiMap;
///< map of location name vector positions (see note below), one entry for every element that is a FixedNamedLocationElement i.e platforms, concourses, footcrossings & named non-station locations. Hence the only active track elements included are footcrossings
typedef TLocationNameMultiMap::iterator TLocationNameMultiMapIterator;
typedef std::pair<TLocationNameMultiMapIterator, TLocationNameMultiMapIterator> TLocationNameMultiMapRange;
typedef std::pair<AnsiString, int>TLocationNameMultiMapEntry;
typedef std::map<THVPair, bool> THVPairsLinkedMap;
///< added at v2.6.1 for use in PopulateHVPairsLinkedMapAndNoDuplicates
// NOTE: the above (TLNPendingList, TLNDone2MultiMap & TLocationNameMultiMap) store adjusted vector positions - adjusted because have
// a single int to represent both active and inactive vector positions. Use (-1 - Position) for active vector positions & (Position)
// for inactive vector positions (most location elements are in the inactive vector so these are positive). The '-1' bit is needed
// because the value '0' is used for the first position in the inactive vector
typedef std::map<AnsiString, int>TActiveTrackElementNameMap;
///< map of ActiveTrackElementNames compiled and used for populating the LocationNameComboBox during timetable creation or editing. Used in place of LocationNameMultiMap as that can contain concourses and non-station named locations that aren't associated with any track. The second 'int' entry is a dummy, only the list of AnsiString names is needed, and being a map it is automatically sorted and without duplicates.
typedef TActiveTrackElementNameMap::iterator TActiveTrackElementNameIterator;
typedef std::pair<AnsiString, int>TActiveTrackElementNameMapEntry;
typedef std::map<THVPair, Graphics::TBitmap*> TMultiplayerOverlayMap; //added for multiplayer
struct TInfrastructureFailureEntry //added at v2.13.0
{
int TVPos;
TDateTime FailureTime;
TDateTime RepairTime;
};
typedef std::vector<TInfrastructureFailureEntry>TFailedElementVector; //added at v2.13.0
typedef std::vector<int> TSimpleVector; //added at v2.13.0
/// Used as basic elements in a table of signals - see SigTable below
struct TSigElement
{
// NOTE: Don't alter the order of these members as they are loaded from an array of values in the constructor
int SpeedTag;
///< the TrackElement SpeedTag value - specifies the signal element
int Attribute;
///< the signal state - red, yellow, double yellow or green
Graphics::TBitmap* SigPtr;
///< pointer to the graphic
};
TSigElement SigTable[40];
///< original table of signals for four aspect
TSigElement SigTableThreeAspect[40];
///< new at version 0.6 for three aspect
TSigElement SigTableTwoAspect[40];
///< new at version 0.6 for two aspect
TSigElement SigTableGroundSignal[40];
///< new at version 0.6 for ground signals
TSigElement FailedSigTable[8], FailedGroundSigTable[8];
///< table of failed signals added at v2.13.0
AnsiString RouteFailMessage;
bool ActiveTrackElementNameMapCompiledFlag;
///< indicates that the ActiveTrackElementNameMap has been compiled
bool CopyFlag;
///< true only when copying a selection, used to prevent location names being copied
bool DuplicatedLocationName(int Caller, bool GiveMessage);
///< examines LocationNameMultiMap and returns true if there are two or more locations with the same name - added at v2.6.1 to cater for Bill78's new .dev file merge program and used when try to save as a .rly file.
bool GapFlashFlag;
///< true when a pair of connected gaps is flashing
bool LCChangeFlag;
///< true when LCs changing
bool LCFoundInAutoSigsRoute;
///< true if found an LC during an automatic route search
bool NoPlatsMessageSent;
///< used to send no platforms warning once only
bool SuppressRouteFailMessage;
///< true if a message has been given in the search routine, to avoid giving multiple times and to avoid other failure messages being given
// bool LCFoundInRouteBuildingFlag; {dropped at v2.17.0 as not used)
///< true if a route set through an LC that is closed to trains (& therefore needs to be opened)
bool PointFlashFlag;
///< true when points are flashing during manual change
bool RouteFlashFlag;
///< true while a route is flashing prior to being set
bool SkipLocationNameMultiMapCheck;
///<changed from PastingWithAttributes in v2.4.0 as all pastes are now with attributes - needed to suppress multimap checks while pasting
bool OverrideAndHideSignalBridgeMessage;
///<if false signals facing bridges are not permitted, but can be set to true using CTRL ALT 5
bool SignalFailedFlag;
///<indicates at least one signal has failed
bool TSRFlag;
///<indicates at least one element has a temporary speed restriction
float LevelCrossingBarrierUpFlashDuration;
///< duration of the flash period when level crossing closing to trains
float LevelCrossingBarrierDownFlashDuration;
///< duration of the flash period when level crossing opening
int FlipArray[FirstUnusedSpeedTagNumber];
///< holds TrackElement SpeedTag values for 'flipping' via menu items 'Edit' & 'Flip'
int GapFlashGreenPosition, GapFlashRedPosition;
///< TrackVectorPosition of the gap element that is flashing green or red
int MirrorArray[FirstUnusedSpeedTagNumber];
///< holds TrackElement SpeedTag values for 'mirroring' via menu items 'Edit' & 'Mirror'
int RotRightArray[FirstUnusedSpeedTagNumber];
///< holds TrackElement SpeedTag values for 'rotating right' via menu items 'Edit' & 'Rotate right'
int RotLeftArray[FirstUnusedSpeedTagNumber];
///< holds TrackElement SpeedTag values for 'rotating left' via menu items 'Edit' & 'Rotate left'
TFailedElementVector FailedPointsVector, FailedSignalsVector, TSRVector;
///< vector of failed points with track vector positions & repair times for use in failure handling (new at v2.13.0)
std::map<AnsiString, char>ContinuationNameMap;
///< map of all continuation names, char is a dummy
TMultiplayerOverlayMap MultiplayerOverlayMap; //added for multiplayer
///< map of coupled continuations
TActiveTrackElementNameMap ActiveTrackElementNameMap;
///< map of active track element names
TActiveLCVector ChangingLCVector;
///< vector of values for changing level crossings - i.e. barriers in course of being raised or lowered
TActiveLCVector BarriersDownVector;
///< vector of LCs with barriers down
TGapMap GapMap;
///< map of gaps (see type for more information above)
TGraphicElement *GapFlashGreen, *GapFlashRed;
///< the red & green circle graphics used to show where the gaps are
TInactiveTrack2MultiMap InactiveTrack2MultiMap;
///< multimap of inactive TrackElements (see type for more information above)
TLCVector LCVector;
///< vector of level crossing InactiveTrackVector positions
TLNDone2MultiMap LNDone2MultiMap;
///< multimap of processed location name elements (see type for more information above)
TLNPendingList LNPendingList;
///< list of location name elements awaiting processing (see type for more information above)
TLocationNameMultiMap LocationNameMultiMap;
///< multimap of location names (see type for more information above)
TSimpleVector SimpleVector;
///< vector of simple element track vector positions
TUserGraphicVector UserGraphicVector, SelectGraphicVector;
///< vectors of user graphics
TUserGraphicMap UserGraphicMap;
///<the map of graphic filenames as key and TPicture* as values
TTrackMap TrackMap;
///< map of track (see type for more information above)
TTrackVector TrackVector, InactiveTrackVector, NewVector, DistanceVector, DistanceSearchVector, SelectVector;
///< vectors of TrackElements
TTrackVectorIterator NextTrackElementPtr;
///< track vector iterator used during cycling through a track vector
TUserGraphicMapEntry UGME;
///<an entry for the UserGraphicMap
// inline functions
/// Return location name for a given inactive track vector position
AnsiString GetLocationName(unsigned int InactiveTrackVectorPosition)
{
return(InactiveTrackElementAt(24, InactiveTrackVectorPosition).LocationName);
}
/// Indicates whether or not the railway is ready for saving as a '.rly' file and for operation
bool IsReadyForOperation(bool GiveMessage)
{
return (IsTrackFinished() && !LocationsNotNamed(1) && !GapsUnset(8) && !DuplicatedLocationName(0, GiveMessage));
}
/// Indicates whether or not the track has been successfully linked together
bool IsTrackFinished()
{
return(TrackFinished);
}
/// checks if a user graphic present
bool UserGraphicPresentAtHV(int Caller, int HPos, int VPos, int& UGIVectorPos)
{
UGIVectorPos = 0;
for(int x = (UserGraphicVector.size() - 1); x >= 0; x--) // go downwards because may erase the element identified
{
if((HPos >= (UserGraphicVectorAt(18, x).HPos - (Display->DisplayOffsetH * 16))) && (HPos < (UserGraphicVectorAt(19, x).HPos +
UserGraphicVectorAt(20, x).Width - (Display->DisplayOffsetH * 16))) && (VPos >= (UserGraphicVectorAt(21, x).VPos -
(Display->DisplayOffsetV * 16))) && (VPos < (UserGraphicVectorAt(22, x).VPos + UserGraphicVectorAt(23, x).Height -
(Display->DisplayOffsetV * 16))))
{
UGIVectorPos = x;
return(true);
}
}
return(false);
}
enum
{
FourAspectBuild, ThreeAspectBuild, TwoAspectBuild, GroundSignalBuild
} SignalAspectBuildMode;
///< aspect mode for future signal additions
int GetGapHLoc()
{
return(GapHLoc);
} // return the respective values
int GetGapVLoc()
{
return(GapVLoc);
}
int GetHLocMax()
{
return(HLocMax);
}
int GetHLocMin()
{
return(HLocMin);
}
int GetVLocMax()
{
return(VLocMax);
}
int GetVLocMin()
{
return(VLocMin);
}
/// Return the corresponding link position (track always occupies either links 0 & 1 or 2 & 3)
int GetNonPointsOppositeLinkPos(int LinkPosIn)
{
if(LinkPosIn == 3)
{
return(2);
}
if(LinkPosIn == 2)
{
return(3);
}
if(LinkPosIn == 1)
{
return(0);
}
return(1);
}
/// Return the number of active track elements
int TrackVectorSize()
{
return(TrackVector.size());
}
/// Return a basic track element from the SpeedTag new at v2.2.0 - needed because Interface doesn't have direct access to FixedTrackArray
TTrackElement BuildBasicElementFromSpeedTag(int Caller, int SpeedTag)
{
return(FixedTrackArray.FixedTrackPiece[SpeedTag]);
}
/// Return the number of selected active and inactive track elements (via menu items 'Edit' and 'Select')
unsigned int SelectVectorSize()
{
return(SelectVector.size());
}
/// Store a TrackElement in the SelectVector
void SelectPush(TTrackElement TrackElement)
{
SelectVector.push_back(TrackElement);
}
void SelectVectorClear()
{
SelectVector.clear();
}
// set member values
void SetHLocMax(int HLoc)
{
HLocMax = HLoc;
}
void SetHLocMin(int HLoc)
{
HLocMin = HLoc;
}
void SetTrackFinished(bool Value)
{
TrackFinished = Value;
}
void SetVLocMax(int VLoc)
{
VLocMax = VLoc;
}
void SetVLocMin(int VLoc)
{
VLocMin = VLoc;
}
// externally defined functions
/// Used to check the validity of footcrossing links
bool ActiveMapCheck(int Caller, int HLoc, int VLoc, int SpeedTag);
/// Checks BarrierDownVector and returns true if there is one that is linked to the LC at H & V positions and is set to manual (TypeOfRoute == 2), and returns the vector position in BDVectorPos
bool AnyLinkedBarrierDownVectorManual(int Caller, int HLoc, int VLoc, int &BDVectorPos);
/// True if a route or train present on any linked level crossing element
bool AnyLinkedLevelCrossingElementsWithRoutesOrTrains(int Caller, int HLoc, int VLoc, TPrefDirVector SearchVector, bool &TrainPresent);
/// Used during location naming to check for adjacent named elements to a given element at HLoc & VLoc with a specific SpeedTag, and if found allow that element to be inserted into the LNPendingList for naming similarly
bool AdjElement(int Caller, int HLoc, int VLoc, int SpeedTag, int &FoundElement);
/// Used in SearchForAndUpdateLocationName to check for adjacent named elements to a given element at HLoc & VLoc with a specific SpeedTag, and if found allow that name to be used for this element and all other named elements that are linked to it
bool AdjNamedElement(int Caller, int HLoc, int VLoc, int SpeedTag, AnsiString &LocationName, int &FoundElement);
/// True for a blank (SpeedTag == 0) element at a specific Trackvector position, no longer used after TrackErase changed (now EraseTrackElement) so that blank elements aren't used
bool BlankElementAt(int Caller, int At) const;
// True if BarriersDownVector checks OK in SessionFile
bool CheckActiveLCVector(int Caller, std::ifstream &VecFile);
/// True if a footcrossing is linked properly at both ends
bool CheckFootCrossingLinks(int Caller, TTrackElement &TrackElement);
/// True if TrackElements in the file are all valid