1 #ifndef schedule_h 2 #define schedule_h 3 4 #include "schedule_entry.h" 5 6 #include "../halthandle_t.h" 7 8 #include "../tpl/minivec_tpl.h" 9 10 11 class cbuffer_t; 12 class grund_t; 13 class player_t; 14 class karte_t; 15 16 17 /** 18 * Class to hold schedule of vehicles in Simutrans. 19 * 20 * @author Hj. Malthaner 21 */ 22 class schedule_t 23 { 24 bool editing_finished; 25 uint8 current_stop; 26 27 static schedule_entry_t dummy_entry; 28 29 /** 30 * Fix up current_stop value, which we may have made out of range 31 * @author neroden 32 */ make_current_stop_valid()33 void make_current_stop_valid() { 34 uint8 count = entries.get_count(); 35 if( count == 0 ) { 36 current_stop = 0; 37 } 38 else if( current_stop >= count ) { 39 current_stop = count-1; 40 } 41 } 42 43 protected: schedule_t()44 schedule_t() : editing_finished(false), current_stop(0) {} 45 46 public: 47 enum schedule_type { 48 schedule = 0, truck_schedule = 1, train_schedule = 2, ship_schedule = 3, airplane_schedule = 4, monorail_schedule = 5, tram_schedule = 6, maglev_schedule = 7, narrowgauge_schedule = 8, 49 }; 50 51 minivec_tpl<schedule_entry_t> entries; 52 53 /** 54 * Returns error message if stops are not allowed 55 * @author Hj. Malthaner 56 */ 57 virtual char const* get_error_msg() const = 0; 58 59 /** 60 * Returns true if this schedule allows stop at the 61 * given tile. 62 * @author Hj. Malthaner 63 */ 64 bool is_stop_allowed(const grund_t *gr) const; 65 empty()66 bool empty() const { return entries.empty(); } 67 get_count()68 uint8 get_count() const { return entries.get_count(); } 69 70 virtual schedule_type get_type() const = 0; 71 72 virtual waytype_t get_waytype() const = 0; 73 74 /** 75 * Get current stop of the schedule. 76 * @author hsiegeln 77 */ get_current_stop()78 uint8 get_current_stop() const { return current_stop; } 79 80 /// returns the current stop, always a valid entry get_current_entry()81 schedule_entry_t const& get_current_entry() const { return current_stop >= entries.get_count() ? dummy_entry : entries[current_stop]; } 82 83 /** 84 * Set the current stop of the schedule . 85 * If new value is bigger than stops available, the max stop will be used. 86 * @author hsiegeln 87 */ set_current_stop(uint8 new_current_stop)88 void set_current_stop(uint8 new_current_stop) { 89 current_stop = new_current_stop; 90 make_current_stop_valid(); 91 } 92 93 /// advance current_stop by one advance()94 void advance() { 95 if( !entries.empty() ) { 96 current_stop = (current_stop+1)%entries.get_count(); 97 } 98 } 99 is_editing_finished()100 inline bool is_editing_finished() const { return editing_finished; } finish_editing()101 void finish_editing() { editing_finished = true; } start_editing()102 void start_editing() { editing_finished = false; } 103 ~schedule_t()104 virtual ~schedule_t() {} 105 106 /** 107 * returns a halthandle for the next halt in the schedule (or unbound) 108 */ 109 halthandle_t get_next_halt( player_t *player, halthandle_t halt ) const; 110 111 /** 112 * returns a halthandle for the previous halt in the schedule (or unbound) 113 */ 114 halthandle_t get_prev_halt( player_t *player ) const; 115 116 /** 117 * Inserts a coordinate at current_stop into the schedule. 118 */ 119 bool insert(const grund_t* gr, uint8 minimum_loading = 0, uint8 waiting_time_shift = 0); 120 121 /** 122 * Appends a coordinate to the schedule. 123 */ 124 bool append(const grund_t* gr, uint8 minimum_loading = 0, uint8 waiting_time_shift = 0); 125 126 /** 127 * Cleanup a schedule, removes double entries. 128 */ 129 void cleanup(); 130 131 /** 132 * Remove current_stop entry from the schedule. 133 */ 134 bool remove(); 135 136 void rdwr(loadsave_t *file); 137 138 void rotate90( sint16 y_size ); 139 140 /** 141 * if the passed in schedule matches "this", then return true 142 * @author hsiegeln 143 */ 144 bool matches(karte_t *welt, const schedule_t *schedule); 145 146 /** 147 * Compare this schedule with another, ignoring order and exact positions and waypoints. 148 * @author prissi 149 */ 150 bool similar( const schedule_t *schedule, const player_t *player ); 151 152 /** 153 * Calculates a return way for this schedule. 154 * Will add elements 1 to end in reverse order to schedule. 155 * @author hsiegeln 156 */ 157 void add_return_way(); 158 159 virtual schedule_t* copy() = 0;//{ return new schedule_t(this); } 160 161 // copy all entries from schedule src to this and adjusts current_stop 162 void copy_from(const schedule_t *src); 163 164 // fills the given buffer with a schedule 165 void sprintf_schedule( cbuffer_t &buf ) const; 166 167 // converts this string into a schedule 168 bool sscanf_schedule( const char * ); 169 170 /** 171 * Append description of entry to buf. 172 * If @p max_chars > 0 then append short version, without loading level and position. 173 */ 174 static void gimme_stop_name(cbuffer_t& buf, karte_t* welt, player_t const* player_, schedule_entry_t const& entry, int max_chars); 175 }; 176 177 178 /** 179 * Schedules with stops on tracks. 180 * 181 * @author Hj. Malthaner 182 */ 183 class train_schedule_t : public schedule_t 184 { 185 public: train_schedule_t()186 train_schedule_t() {} copy()187 schedule_t* copy() OVERRIDE { schedule_t *s = new train_schedule_t(); s->copy_from(this); return s; } get_error_msg()188 const char *get_error_msg() const OVERRIDE { return "Zughalt muss auf\nSchiene liegen!\n"; } 189 get_type()190 schedule_type get_type() const OVERRIDE { return train_schedule; } 191 get_waytype()192 waytype_t get_waytype() const OVERRIDE { return track_wt; } 193 }; 194 195 /** 196 * Schedules with stops on tram tracks. 197 * @author Hj. Malthaner 198 */ 199 class tram_schedule_t : public train_schedule_t 200 { 201 public: tram_schedule_t()202 tram_schedule_t() {} copy()203 schedule_t* copy() OVERRIDE { schedule_t *s = new tram_schedule_t(); s->copy_from(this); return s; } 204 get_type()205 schedule_type get_type() const OVERRIDE { return tram_schedule; } 206 get_waytype()207 waytype_t get_waytype() const OVERRIDE { return tram_wt; } 208 }; 209 210 211 /** 212 * Schedules with stops on roads. 213 * 214 * @author Hj. Malthaner 215 */ 216 class truck_schedule_t : public schedule_t 217 { 218 public: truck_schedule_t()219 truck_schedule_t() {} copy()220 schedule_t* copy() OVERRIDE { schedule_t *s = new truck_schedule_t(); s->copy_from(this); return s; } get_error_msg()221 const char *get_error_msg() const OVERRIDE { return "Autohalt muss auf\nStrasse liegen!\n"; } 222 get_type()223 schedule_type get_type() const OVERRIDE { return truck_schedule; } 224 get_waytype()225 waytype_t get_waytype() const OVERRIDE { return road_wt; } 226 }; 227 228 229 /** 230 * Schedules with stops on water. 231 * 232 * @author Hj. Malthaner 233 */ 234 class ship_schedule_t : public schedule_t 235 { 236 public: ship_schedule_t()237 ship_schedule_t() {} copy()238 schedule_t* copy() OVERRIDE { schedule_t *s = new ship_schedule_t(); s->copy_from(this); return s; } get_error_msg()239 const char *get_error_msg() const OVERRIDE { return "Schiffhalt muss im\nWasser liegen!\n"; } 240 get_type()241 schedule_type get_type() const OVERRIDE { return ship_schedule; } 242 get_waytype()243 waytype_t get_waytype() const OVERRIDE { return water_wt; } 244 }; 245 246 247 /** 248 * Schedules for airplanes. 249 * 250 * @author Hj. Malthaner 251 */ 252 class airplane_schedule_t : public schedule_t 253 { 254 public: airplane_schedule_t()255 airplane_schedule_t() {} copy()256 schedule_t* copy() OVERRIDE { schedule_t *s = new airplane_schedule_t(); s->copy_from(this); return s; } get_error_msg()257 const char *get_error_msg() const OVERRIDE { return "Flugzeughalt muss auf\nRunway liegen!\n"; } 258 get_type()259 schedule_type get_type() const OVERRIDE { return airplane_schedule; } 260 get_waytype()261 waytype_t get_waytype() const OVERRIDE { return air_wt; } 262 }; 263 264 /** 265 * Schedules with stops on mono-rails. 266 * @author Hj. Malthaner 267 */ 268 class monorail_schedule_t : public schedule_t 269 { 270 public: monorail_schedule_t()271 monorail_schedule_t() {} copy()272 schedule_t* copy() OVERRIDE { schedule_t *s = new monorail_schedule_t(); s->copy_from(this); return s; } get_error_msg()273 const char *get_error_msg() const OVERRIDE { return "Monorailhalt muss auf\nMonorail liegen!\n"; } 274 get_type()275 schedule_type get_type() const OVERRIDE { return monorail_schedule; } 276 get_waytype()277 waytype_t get_waytype() const OVERRIDE { return monorail_wt; } 278 }; 279 280 /** 281 * Schedules with stops on maglev tracks. 282 * @author Hj. Malthaner 283 */ 284 class maglev_schedule_t : public schedule_t 285 { 286 public: maglev_schedule_t()287 maglev_schedule_t() {} copy()288 schedule_t* copy() OVERRIDE { schedule_t *s = new maglev_schedule_t(); s->copy_from(this); return s; } get_error_msg()289 const char *get_error_msg() const OVERRIDE { return "Maglevhalt muss auf\nMaglevschiene liegen!\n"; } 290 get_type()291 schedule_type get_type() const OVERRIDE { return maglev_schedule; } 292 get_waytype()293 waytype_t get_waytype() const OVERRIDE { return maglev_wt; } 294 }; 295 296 /** 297 * Schedules with stops on narrowgauge tracks. 298 * 299 * @author Hj. Malthaner 300 */ 301 class narrowgauge_schedule_t : public schedule_t 302 { 303 public: narrowgauge_schedule_t()304 narrowgauge_schedule_t() {} copy()305 schedule_t* copy() OVERRIDE { schedule_t *s = new narrowgauge_schedule_t(); s->copy_from(this); return s; } get_error_msg()306 const char *get_error_msg() const OVERRIDE { return "On narrowgauge track only!\n"; } 307 get_type()308 schedule_type get_type() const OVERRIDE { return narrowgauge_schedule; } 309 get_waytype()310 waytype_t get_waytype() const OVERRIDE { return narrowgauge_wt; } 311 }; 312 313 314 #endif 315