forked from aburch/simutrans
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathblockmanager.h
199 lines (141 loc) · 4.71 KB
/
blockmanager.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
/*
* blockmanager.h
*
* Copyright (c) 1997 - 2001 Hansjörg Malthaner
*
* This file is part of the Simutrans project and may not be used
* in other projects without written permission of the author.
*/
#ifndef blockmanager_h
#define blockmanager_h
#include "railblocks.h"
#include "tpl/array_tpl.h"
#include "dataobj/marker.h"
#include "ifc/koord_beobachter.h"
class vehikel_t;
class karte_t;
class schiene_t;
class spieler_t;
/**
* Der Blockmanager verwaltet die Blockstrecken.
* Als singleton implementiert.
* @see blockstrecke_t
* @author Hj. Malthaner
*/
class blockmanager
{
private:
class block_ersetzer : public koord_beobachter
{
private:
karte_t *welt;
blockhandle_t alt;
public:
block_ersetzer(karte_t *welt, blockhandle_t bs);
virtual ~block_ersetzer() {};
blockhandle_t neu;
bool neue_koord(koord3d k);
void wieder_koord(koord3d );
bool ist_uebergang_ok(koord3d pos1, koord3d pos2);
};
/**
* (Er)setzt den tracktyp eines blocks. Z.B. auf elektrifiziert.
* @author Hj. Malthaner
*/
class tracktyp_ersetzer : public koord_beobachter
{
private:
karte_t *welt;
blockhandle_t alt;
uint8 electric;
public:
tracktyp_ersetzer(karte_t *welt, blockhandle_t alt, uint8 el);
virtual ~tracktyp_ersetzer() {};
bool neue_koord(koord3d k);
void wieder_koord(koord3d );
bool ist_uebergang_ok(koord3d pos1, koord3d pos2);
};
/**
* normalerweise weiss eine blockstrecke, ob sie frei ist oder nicht
* aber neu angelegte blockstrecken besitzen diese information noch
* nicht. deshalb können objekte dieser Klasse prüfen, ob eine blockstrecke
* frei ist.
* @author Hj. Malthaner
*/
class pruefer_ob_strecke_frei : public koord_beobachter
{
private:
karte_t *welt;
blockhandle_t bs;
public:
pruefer_ob_strecke_frei(karte_t *welt, blockhandle_t bs);
virtual ~pruefer_ob_strecke_frei() {};
bool neue_koord(koord3d k);
void wieder_koord(koord3d );
bool ist_uebergang_ok(koord3d pos1, koord3d pos2);
int count;
};
static blockmanager * single_instance;
blockmanager();
slist_tpl< blockhandle_t > strecken;
marker_t marker;
int map_size;
const char * baue_neues_signal(karte_t *welt, spieler_t *sp,
koord3d pos, koord3d pos2, schiene_t *sch,
ribi_t::ribi dir);
const char * baue_andere_signale(koord3d pos1, koord3d pos2,
schiene_t *sch1, schiene_t *sch2,
ribi_t::ribi ribi);
/**
* vereinigt zwei blockstrecken zu einer einzigen und gibt
* diese zurück. Dabei wird bs2 zu bs1 zugeschlagen, bs2 geloescht.
* bs1 bleibt uebrig.
*/
void vereinige(karte_t *welt,
blockhandle_t bs1,
blockhandle_t bs2);
public:
void setze_welt_groesse(int w);
int gib_block_nr(blockhandle_t bs) {return strecken.index_of(bs);};
blockhandle_t gib_strecke_bei(int i) {return (blockhandle_t )strecken.at(i);};
const slist_tpl< blockhandle_t > * gib_strecken() {return &strecken;};
/**
* gibt den blockmanager zurück
*/
static blockmanager * gib_manager();
void neue_schiene(karte_t *welt, grund_t *gr, ding_t *sig = NULL);
void schiene_erweitern(karte_t *welt, grund_t *gr);
/**
* entfernt ein signal aus dem blockstreckennetz.
*/
bool entferne_signal(karte_t *welt, koord3d k);
/**
* entfernt eine koordinate aus dem blockstreckennetz.
*/
bool entferne_schiene(karte_t *welt, koord3d k);
/**
* @return NULL wenn ok, oder Fehlermeldung
*/
const char* neues_signal(karte_t *welt, spieler_t *sp,
koord3d pos, ribi_t::ribi dir);
bool entferne_signal(signal_t *sig, blockhandle_t bs);
/**
* findet blockstrecke zu einem beliebigen punkt auf der strecke
*/
blockhandle_t finde_blockstrecke(karte_t *welt, koord3d punkt);
/**
* Nur zum Debugging, setzt leere Blockstrecken auf leer
* wenn der Blockstreckenzustand inkonsistent geworden ist
*/
void pruefe_blockstrecke(karte_t *welt, koord3d k);
void setze_tracktyp(karte_t *welt, koord3d k, uint8 styp);
void rdwr(karte_t *welt, loadsave_t *file);
void laden_abschliessen();
void delete_all_blocks();
private:
array_tpl<koord3d> &finde_nachbarn(const karte_t *welt, const koord3d pos,
const ribi_t::ribi ribi, int &anzahl);
bool ist_markiert(grund_t *gr) const { return marker.ist_markiert(gr); }
void traversiere_netz(const karte_t * welt, const koord3d start, koord_beobachter *cmd);
};
#endif