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 _simdepot_h
9 #define _simdepot_h
10 
11 #include "tpl/slist_tpl.h"
12 #include "obj/gebaeude.h"
13 #include "convoihandle_t.h"
14 #include "simline.h"
15 
16 #define VEHICLE_FILTER_RELEVANT 1
17 #define VEHICLE_FILTER_GOODS_OFFSET 2
18 #define SORT_BY_DEFAULT 0
19 
20 
21 class karte_t;
22 class vehicle_t;
23 class depot_frame_t;
24 class vehicle_desc_t;
25 
26 
27 /**
28  * In Depots werden Fahrzeuge gekauft, gewartet, verkauft und gelagert.
29  * @author Hj. Malthaner
30  */
31 class depot_t : public gebaeude_t
32 {
33 protected:
34 	/**
35 	 * Reworked depot data!
36 	 *
37 	 * It can now contain any number of vehicles bought by the user (as before).
38 	 * And it can hold any number of convois (before only one).
39 	 * It is possible to have 0 convois in a depot, but an empty one shall be
40 	 * automatically created, when necessary.
41 	 * Convois are numbered 0...(n-1).
42 	 * Vehicles are accessed by type.
43 	 *
44 	 * @author Volker Meyer
45 	 * @date  30.05.2003
46 	 */
47 	slist_tpl<vehicle_t *> vehicles;
48 	slist_tpl<convoihandle_t> convois;
49 
50 	void rdwr_vehikel(slist_tpl<vehicle_t*> &list, loadsave_t *file);
51 
52 	static slist_tpl<depot_t *> all_depots;
53 
54 public:
55 	// Last selected vehicle filter
56 	int selected_filter;
57 
58 	// Last selected vehicle sort
59 	int selected_sort_by;
60 
61 	// finds the next/previous depot relative to the current position
62 	static depot_t *find_depot( koord3d start, const obj_t::typ depot_type, const player_t *player, bool next);
63 
get_depot_list()64 	static const slist_tpl<depot_t *>& get_depot_list() { return all_depots; }
65 
66 	depot_t(loadsave_t *file);
67 	depot_t(koord3d pos, player_t *player, const building_tile_desc_t *t);
68 	virtual ~depot_t();
69 
70 	void call_depot_tool( char tool, convoihandle_t cnv, const char *extra );
71 
72 	virtual simline_t::linetype get_line_type() const = 0;
73 
74 	void rdwr(loadsave_t *file) OVERRIDE;
75 
76 	// text for the tabs is defaulted to the train names
get_electrics_name()77 	virtual const char * get_electrics_name() { return "Electrics_tab"; };
get_passenger_name()78 	virtual const char * get_passenger_name() { return "Pas_tab"; }
get_zieher_name()79 	virtual const char * get_zieher_name() { return "Lokomotive_tab"; }
get_haenger_name()80 	virtual const char * get_haenger_name() { return "Waggon_tab"; }
81 
82 	vehicle_t* find_oldest_newest(const vehicle_desc_t* desc, bool old);
83 
84 	/**
85 	 * Access to convoi list.
86 	 * @author Volker Meyer
87 	 * @date  30.05.2003
88 	 */
convoi_count()89 	unsigned convoi_count() const { return convois.get_count(); }
90 
get_convoi(unsigned int icnv)91 	convoihandle_t get_convoi(unsigned int icnv) const { return icnv < convoi_count() ? convois.at(icnv) : convoihandle_t(); }
92 
93 	convoihandle_t add_convoi(bool local_execution);
94 
get_convoy_list()95 	slist_tpl<convoihandle_t> const& get_convoy_list() { return convois; }
96 
97 	// checks if cnv can be copied by using only stored vehicles and non-obsolete purchased vehicles
98 	bool check_obsolete_inventory(convoihandle_t cnv);
99 
100 	/**
101 	 * copies convoi and its schedule or line
102 	 * @author hsiegeln
103 	 */
104 	convoihandle_t copy_convoi(convoihandle_t old_cnv, bool local_execution);
105 
106 	/**
107 	 * Let convoi leave the depot.
108 	 * If not possible, a message is displayed and the function returns false.
109 	 * @param if local_execution is true, this method creates pop-ups in case of errors
110 	 * @author Volker Meyer, Dwachs
111 	 * @date  09.06.2003 / 27.04.2010
112 	 */
113 	bool start_convoi(convoihandle_t cnv, bool local_execution);
114 
115 	bool start_all_convoys();
116 
117 	/**
118 	 * Destroy the convoi and put the vehicles in the vehicles list (sell==false),
119 	 * or sell all immediately (sell==true).
120 	 * @author Volker Meyer
121 	 * @date  09.06.2003
122 	 */
123 	bool disassemble_convoi(convoihandle_t cnv, bool sell);
124 
125 	/**
126 	 * Remove the convoi from the depot lists
127 	 * updating depot gui frame as necessary
128 	 */
129 	void remove_convoi( convoihandle_t cnv );
130 
131 	/**
132 	 * Remove vehicle from vehicle list and add it to the convoi. Two positions
133 	 * are possible - in front or at the rear.
134 	 * @author Volker Meyer
135 	 * @date  09.06.2003
136 	 */
137 	void append_vehicle(convoihandle_t cnv, vehicle_t* veh, bool infront, bool local_execution);
138 
139 	/**
140 	 * Remove the vehicle at given position from the convoi and put it in the
141 	 * vehicle list.
142 	 * @author Volker Meyer
143 	 * @date  09.06.2003
144 	 */
145 	void remove_vehicle(convoihandle_t cnv, int ipos);
146 	void remove_vehicles_to_end(convoihandle_t cnv, int ipos);
147 
148 	/**
149 	 * Access to vehicles not bound to a convoi. They are not ordered
150 	 * in any way.
151 	 * @author Volker Meyer
152 	 * @date  30.05.2003
153 	 */
get_vehicle_list()154 	slist_tpl<vehicle_t*> const& get_vehicle_list() { return vehicles; }
155 
156 	/**
157 	 * A new vehicle is bought and added to the vehicle list.
158 	 * The new vehicle in the list is returned.
159 	 * @author Volker Meyer
160 	 * @date  09.06.2003
161 	 */
162 	vehicle_t* buy_vehicle(const vehicle_desc_t* info);
163 
164 	/**
165 	 * Sell a vehicle from the vehicle list.
166 	 * @author Volker Meyer
167 	 * @date  09.06.2003
168 	 */
169 	void sell_vehicle(vehicle_t* veh);
170 
171 	/**
172 	 * Access to vehicle types which can be bought in the depot.
173 	 * @author Volker Meyer
174 	 */
175 	slist_tpl<vehicle_desc_t const*> const& get_vehicle_type(uint8 sortkey = SORT_BY_DEFAULT) const;
176 
177 	/**
178 	 * A convoi arrived at the depot and is added to the convoi list.
179 	 * If schedule_adjust is true, the current depot is removed from schedule.
180 	 * @author Volker Meyer
181 	 * @date  09.06.2003
182 	 */
183 	void convoi_arrived(convoihandle_t cnv, bool schedule_adjust);
184 
185 	/**
186 	 * Parameters to determine layout and behaviour of the depot_frame_t.
187 	 * @author Volker Meyer
188 	 * @date  09.06.2003
189 	 */
190 	virtual int get_x_grid() const = 0;
191 	virtual int get_y_grid() const = 0;
192 	virtual int get_x_placement() const = 0;
193 	virtual int get_y_placement() const = 0;
194 	virtual unsigned get_max_convoi_length() const = 0;
195 
196 	/**
197 	 * Opens a new info window for that object.
198 	 *
199 	 * @author Hj. Malthaner
200 	 */
201 	void show_info() OVERRIDE;
202 
203 	/**
204 	 * Can object be removed?
205 	 * @return NULL when OK, otherwise an error message
206 	 * @author Hj. Malthaner
207 	 */
208 	const char * is_deletable(const player_t *player) OVERRIDE;
209 
210 	/**
211 	 * identifies the oldest vehicle of a certain type
212 	 * @return NULL if no vehicle is found
213 	 * @author hsiegeln (stolen from Hajo)
214 	 */
215 	vehicle_t* get_oldest_vehicle(const vehicle_desc_t* desc);
216 
217 	/**
218 	 * Sets/gets the line that was selected the last time in the depot dialog
219 	 */
set_last_selected_line(const linehandle_t last_line)220 	void set_last_selected_line(const linehandle_t last_line) { last_selected_line=last_line; }
get_last_selected_line()221 	linehandle_t get_last_selected_line() const { return last_selected_line; }
222 
223 	/**
224 	 * Will update all depot_frame_t (new vehicles!)
225 	 */
226 	static void update_all_win();
227 	static void new_month();
228 
229 	/**
230 	 * Update the depot_frame_t.
231 	 */
232 	void update_win();
233 
234 private:
235 	linehandle_t last_selected_line;
236 
237 	/**
238 	 * Used to block new actions from depot frame gui when convois are being added to the depot.
239 	 * Otherwise lag in multipler results in actions being performed on the wrong convoi.
240 	 * Only works for a single client making changes in a depot at once. Multiple clients can still result in wrong convois being changed.
241 	 */
242 	bool command_pending;
243 
244 public:
is_command_pending()245 	bool is_command_pending() const { return command_pending; }
clear_command_pending()246 	void clear_command_pending() { command_pending = false; }
set_command_pending()247 	void set_command_pending() { command_pending = true; }
248 };
249 
250 
251 /**
252  * Depots for train vehicles.
253  *
254  * @author Hj. Malthaner
255  * @see depot_t
256  * @see gebaeude_t
257  */
258 class bahndepot_t : public depot_t
259 {
260 public:
bahndepot_t(loadsave_t * file)261 	bahndepot_t(loadsave_t *file) : depot_t(file) {}
bahndepot_t(koord3d pos,player_t * player,const building_tile_desc_t * t)262 	bahndepot_t(koord3d pos,player_t *player, const building_tile_desc_t *t) : depot_t(pos,player,t) {}
263 
get_line_type()264 	simline_t::linetype get_line_type() const OVERRIDE { return simline_t::trainline; }
265 
rdwr_vehicles(loadsave_t * file)266 	void rdwr_vehicles(loadsave_t *file) { depot_t::rdwr_vehikel(vehicles,file); }
267 
268 	/**
269 	 * Parameters to determine layout and behaviour of the depot_frame_t.
270 	 * @author Volker Meyer
271 	 * @date  09.06.2003
272 	 */
get_x_placement()273 	int get_x_placement() const OVERRIDE {return -25; }
get_y_placement()274 	int get_y_placement() const OVERRIDE {return -28; }
get_x_grid()275 	int get_x_grid() const OVERRIDE { return 24; }
get_y_grid()276 	int get_y_grid() const OVERRIDE { return 24; }
277 	unsigned get_max_convoi_length() const OVERRIDE;
278 
get_typ()279 	obj_t::typ get_typ() const OVERRIDE { return bahndepot; }
get_name()280 	const char *get_name() const OVERRIDE {return "Bahndepot"; }
281 };
282 
283 
284 class tramdepot_t : public bahndepot_t
285 {
286 public:
tramdepot_t(loadsave_t * file)287 	tramdepot_t(loadsave_t *file):bahndepot_t(file) {}
tramdepot_t(koord3d pos,player_t * player,const building_tile_desc_t * t)288 	tramdepot_t(koord3d pos,player_t *player, const building_tile_desc_t *t): bahndepot_t(pos,player,t) {}
289 
get_line_type()290 	simline_t::linetype get_line_type() const OVERRIDE { return simline_t::tramline; }
291 
get_typ()292 	obj_t::typ get_typ() const OVERRIDE { return tramdepot; }
get_name()293 	const char *get_name() const OVERRIDE {return "Tramdepot"; }
294 };
295 
296 class monoraildepot_t : public bahndepot_t
297 {
298 public:
monoraildepot_t(loadsave_t * file)299 	monoraildepot_t(loadsave_t *file):bahndepot_t(file) {}
monoraildepot_t(koord3d pos,player_t * player,const building_tile_desc_t * t)300 	monoraildepot_t(koord3d pos,player_t *player, const building_tile_desc_t *t): bahndepot_t(pos,player,t) {}
301 
get_line_type()302 	simline_t::linetype get_line_type() const OVERRIDE { return simline_t::monorailline; }
303 
get_typ()304 	obj_t::typ get_typ() const OVERRIDE { return monoraildepot; }
get_name()305 	const char *get_name() const OVERRIDE {return "Monoraildepot"; }
306 };
307 
308 class maglevdepot_t : public bahndepot_t
309 {
310 public:
maglevdepot_t(loadsave_t * file)311 	maglevdepot_t(loadsave_t *file):bahndepot_t(file) {}
maglevdepot_t(koord3d pos,player_t * player,const building_tile_desc_t * t)312 	maglevdepot_t(koord3d pos,player_t *player, const building_tile_desc_t *t): bahndepot_t(pos,player,t) {}
313 
get_line_type()314 	simline_t::linetype get_line_type() const OVERRIDE { return simline_t::maglevline; }
315 
get_typ()316 	obj_t::typ get_typ() const OVERRIDE { return maglevdepot; }
get_name()317 	const char *get_name() const OVERRIDE {return "Maglevdepot"; }
318 };
319 
320 class narrowgaugedepot_t : public bahndepot_t
321 {
322 public:
narrowgaugedepot_t(loadsave_t * file)323 	narrowgaugedepot_t(loadsave_t *file):bahndepot_t(file) {}
narrowgaugedepot_t(koord3d pos,player_t * player,const building_tile_desc_t * t)324 	narrowgaugedepot_t(koord3d pos,player_t *player, const building_tile_desc_t *t): bahndepot_t(pos,player,t) {}
325 
get_line_type()326 	simline_t::linetype get_line_type() const OVERRIDE { return simline_t::narrowgaugeline; }
327 
get_typ()328 	obj_t::typ get_typ() const OVERRIDE { return narrowgaugedepot; }
get_name()329 	const char *get_name() const OVERRIDE {return "Narrowgaugedepot"; }
330 };
331 
332 /**
333  * Depots for street vehicles
334  *
335  * @author Hj. Malthaner
336  * @see depot_t
337  * @see gebaeude_t
338  */
339 class strassendepot_t : public depot_t
340 {
341 protected:
get_passenger_name()342 	const char * get_passenger_name() OVERRIDE { return "Bus_tab"; }
get_electrics_name()343 	const char * get_electrics_name() OVERRIDE { return "TrolleyBus_tab"; }
get_zieher_name()344 	const char * get_zieher_name() OVERRIDE { return "LKW_tab"; }
get_haenger_name()345 	const char * get_haenger_name() OVERRIDE { return "Anhaenger_tab"; }
346 
347 public:
strassendepot_t(loadsave_t * file)348 	strassendepot_t(loadsave_t *file) : depot_t(file) {}
strassendepot_t(koord3d pos,player_t * player,const building_tile_desc_t * t)349 	strassendepot_t(koord3d pos,player_t *player, const building_tile_desc_t *t) : depot_t(pos,player,t) {}
350 
get_line_type()351 	simline_t::linetype get_line_type() const OVERRIDE { return simline_t::truckline; }
352 
353 	/**
354 	 * Parameters to determine layout and behaviour of the depot_frame_t.
355 	 * @author Volker Meyer
356 	 * @date  09.06.2003
357 	 */
get_x_placement()358 	int get_x_placement() const OVERRIDE { return -20; }
get_y_placement()359 	int get_y_placement() const OVERRIDE { return -25; }
get_x_grid()360 	int get_x_grid() const OVERRIDE { return 24; }
get_y_grid()361 	int get_y_grid() const OVERRIDE { return 24; }
362 	unsigned get_max_convoi_length() const OVERRIDE;
363 
get_typ()364 	obj_t::typ get_typ() const OVERRIDE { return strassendepot; }
get_name()365 	const char *get_name() const OVERRIDE {return "Strassendepot";}
366 };
367 
368 
369 /**
370  * Depots for ships
371  *
372  * @author Hj. Malthaner
373  * @see depot_t
374  * @see gebaeude_t
375  */
376 class schiffdepot_t : public depot_t
377 {
378 protected:
get_passenger_name()379 	const char * get_passenger_name() OVERRIDE { return "Ferry_tab"; }
get_zieher_name()380 	const char * get_zieher_name() OVERRIDE { return "Schiff_tab"; }
get_haenger_name()381 	const char * get_haenger_name() OVERRIDE { return "Schleppkahn_tab"; }
382 
383 public:
schiffdepot_t(loadsave_t * file)384 	schiffdepot_t(loadsave_t *file) : depot_t(file) {}
schiffdepot_t(koord3d pos,player_t * player,const building_tile_desc_t * t)385 	schiffdepot_t(koord3d pos, player_t *player, const building_tile_desc_t *t) : depot_t(pos,player,t) {}
386 
get_line_type()387 	simline_t::linetype get_line_type() const OVERRIDE { return simline_t::shipline; }
388 
389 	/**
390 	 * Parameters to determine layout and behaviour of the depot_frame_t.
391 	 * @author Volker Meyer
392 	 * @date  09.06.2003
393 	 */
get_x_placement()394 	int get_x_placement() const OVERRIDE { return -1; }
get_y_placement()395 	int get_y_placement() const OVERRIDE { return -11; }
get_x_grid()396 	int get_x_grid() const OVERRIDE { return 60; }
get_y_grid()397 	int get_y_grid() const OVERRIDE { return 46; }
398 
399 	unsigned get_max_convoi_length() const OVERRIDE;
get_typ()400 	obj_t::typ get_typ() const OVERRIDE { return schiffdepot; }
get_name()401 	const char *get_name() const OVERRIDE {return "Schiffdepot";}
402 };
403 
404 
405 /**
406  * Depots for aircrafts
407  */
408 class airdepot_t : public depot_t
409 {
410 protected:
get_zieher_name()411 	const char * get_zieher_name() OVERRIDE { return "aircraft_tab"; }
get_passenger_name()412 	const char * get_passenger_name() OVERRIDE { return "Flug_tab"; }
413 
414 public:
airdepot_t(loadsave_t * file)415 	airdepot_t(loadsave_t *file) : depot_t(file) {}
airdepot_t(koord3d pos,player_t * player,const building_tile_desc_t * t)416 	airdepot_t(koord3d pos,player_t *player, const building_tile_desc_t *t) : depot_t(pos,player,t) {}
417 
get_line_type()418 	simline_t::linetype get_line_type() const OVERRIDE { return simline_t::airline; }
419 
420 	/**
421 	 * Parameters to determine layout and behaviour of the depot_frame_t.
422 	 * @author Volker Meyer
423 	 * @date  09.06.2003
424 	 */
get_x_placement()425 	int get_x_placement() const OVERRIDE {return -10; }
get_y_placement()426 	int get_y_placement() const OVERRIDE {return -23; }
get_x_grid()427 	int get_x_grid() const OVERRIDE { return 36; }
get_y_grid()428 	int get_y_grid() const OVERRIDE { return 36; }
429 	unsigned get_max_convoi_length() const OVERRIDE;
430 
get_typ()431 	obj_t::typ get_typ() const OVERRIDE { return airdepot; }
get_name()432 	const char *get_name() const OVERRIDE {return "Hangar";}
433 };
434 
435 #endif
436