1 /**
2  * Moving objects for Simutrans.
3  * Transport vehicles are defined in simvehicle.h, because they greatly
4  * differ from the vehicles defined herein for the individual traffic
5  * (pedestrians, citycars, movingobj aka flock of sheep).
6  *
7  * Hj. Malthaner
8  *
9  * April 2000
10  */
11 
12 #include "../simdebug.h"
13 #include "../display/simgraph.h"
14 #include "../simmesg.h"
15 #include "../simworld.h"
16 #include "../utils/simrandom.h"
17 #include "../display/simimg.h"
18 #include "../simunits.h"
19 #include "../simtypes.h"
20 #include "../simconvoi.h"
21 
22 #include "simroadtraffic.h"
23 #ifdef DESTINATION_CITYCARS
24 // for final citycar destinations
25 #include "simpeople.h"
26 #endif
27 
28 #include "../dataobj/translator.h"
29 #include "../dataobj/loadsave.h"
30 #include "../dataobj/environment.h"
31 
32 #include "../obj/crossing.h"
33 #include "../obj/roadsign.h"
34 
35 #include "../boden/grund.h"
36 #include "../boden/wege/weg.h"
37 
38 #include "../descriptor/citycar_desc.h"
39 #include "../descriptor/roadsign_desc.h"
40 
41 
42 #include "../utils/cbuffer_t.h"
43 
44 /**********************************************************************************************************************/
45 /* Road users (private cars and pedestrians) basis class from here on */
46 
47 
road_user_t()48 road_user_t::road_user_t() :
49 	vehicle_base_t()
50 {
51 	set_owner( welt->get_public_player() );
52 	time_to_life = 0;
53 	weg_next = 0;
54 }
55 
56 
57 /**
58  * Ensures that this object is removed correctly from the list
59  * of sync step-able things!
60  * @author Hj. Malthaner
61  */
~road_user_t()62 road_user_t::~road_user_t()
63 {
64 	mark_image_dirty( get_image(), 0 );
65 }
66 
67 
road_user_t(grund_t * bd,uint16 random)68 road_user_t::road_user_t(grund_t* bd, uint16 random) :
69 	vehicle_base_t(bd ? bd->get_pos() : koord3d::invalid)
70 {
71 	ribi_t::ribi road_ribi = bd->get_weg_ribi(road_wt);
72 
73 	weg_next = random;
74 
75 	// randomized offset
76 	uint8 offset = random & 3;
77 	direction = ribi_t::nsew[offset];
78 
79 	grund_t *to = NULL;
80 	for(uint8 r = 0; r < 4; r++) {
81 		ribi_t::ribi ribi = ribi_t::nsew[ (r + offset) &3];
82 		if( (ribi & road_ribi)!=0  &&  bd->get_neighbour(to, road_wt, ribi)) {
83 			direction = ribi;
84 			break;
85 		}
86 	}
87 
88 	switch(direction) {
89 		case ribi_t::north:
90 			dx = 2;
91 			dy = -1;
92 			break;
93 		case ribi_t::south:
94 			dx = -2;
95 			dy = 1;
96 			break;
97 		case ribi_t::east:
98 			dx = 2;
99 			dy = 1;
100 			break;
101 		case ribi_t::west:
102 			dx = -2;
103 			dy = -1;
104 			break;
105 	}
106 
107 	set_xoff( (dx<0) ? OBJECT_OFFSET_STEPS : -OBJECT_OFFSET_STEPS );
108 	set_yoff( (dy<0) ? OBJECT_OFFSET_STEPS/2 : -OBJECT_OFFSET_STEPS/2 );
109 
110 	if(to) {
111 		pos_next = to->get_pos();
112 	}
113 	else {
114 		pos_next = welt->lookup_kartenboden(get_pos().get_2d() + koord(direction))->get_pos();
115 	}
116 	set_owner( welt->get_public_player() );
117 }
118 
119 
120 /**
121  * Open a new observation window for the object.
122  * @author Hj. Malthaner
123  */
show_info()124 void road_user_t::show_info()
125 {
126 	if(env_t::road_user_info) {
127 		obj_t::show_info();
128 	}
129 }
130 
131 
rdwr(loadsave_t * file)132 void road_user_t::rdwr(loadsave_t *file)
133 {
134 	xml_tag_t t( file, "verkehrsteilnehmer_t" );
135 
136 	sint8 hoff = file->is_saving() ? get_hoff() : 0;
137 
138 	// correct old offsets ... REMOVE after savegame increase ...
139 	if(file->is_version_less(99, 18)  &&  file->is_saving()) {
140 		dx = dxdy[ ribi_t::get_dir(direction)*2 ];
141 		dy = dxdy[ ribi_t::get_dir(direction)*2+1 ];
142 		sint8 i = steps/16;
143 		set_xoff( get_xoff() + i*dx );
144 		set_yoff( get_yoff() + i*dy + hoff );
145 	}
146 
147 	vehicle_base_t::rdwr(file);
148 
149 	if(file->is_version_less(86, 6)) {
150 		sint32 l;
151 		file->rdwr_long(l);
152 		file->rdwr_long(l);
153 		file->rdwr_long(weg_next);
154 		file->rdwr_long(l);
155 		dx = (sint8)l;
156 		file->rdwr_long(l);
157 		dy = (sint8)l;
158 		file->rdwr_enum(direction);
159 		file->rdwr_long(l);
160 		hoff = (sint8)l;
161 	}
162 	else {
163 		if(file->is_version_less(99, 5)) {
164 			sint32 dummy32;
165 			file->rdwr_long(dummy32);
166 		}
167 		file->rdwr_long(weg_next);
168 		if(file->is_version_less(99, 18)) {
169 			file->rdwr_byte(dx);
170 			file->rdwr_byte(dy);
171 		}
172 		else {
173 			file->rdwr_byte(steps);
174 			file->rdwr_byte(steps_next);
175 		}
176 		file->rdwr_enum(direction);
177 		dx = dxdy[ ribi_t::get_dir(direction)*2];
178 		dy = dxdy[ ribi_t::get_dir(direction)*2+1];
179 		if(file->is_version_less(99, 5)  ||  file->is_version_atleast(99, 17)) {
180 			sint16 dummy16 = ((16*(sint16)hoff)/OBJECT_OFFSET_STEPS);
181 			file->rdwr_short(dummy16);
182 			hoff = (sint8)((OBJECT_OFFSET_STEPS*(sint16)dummy16)/16);
183 		}
184 		else {
185 			file->rdwr_byte(hoff);
186 		}
187 	}
188 	pos_next.rdwr(file);
189 
190 	// convert steps to position
191 	if(file->is_version_less(99, 18)) {
192 		sint8 ddx=get_xoff(), ddy=get_yoff()-hoff;
193 		sint8 i=0;
194 
195 		while(  !is_about_to_hop(ddx+dx*i,ddy+dy*i )  &&  i<16 ) {
196 			i++;
197 		}
198 		set_xoff( ddx-(16-i)*dx );
199 		set_yoff( ddy-(16-i)*dy );
200 		if(file->is_loading()) {
201 			if(dx && dy) {
202 				steps = min( VEHICLE_STEPS_PER_TILE - 1, VEHICLE_STEPS_PER_TILE - 1 - (i*16) );
203 				steps_next = VEHICLE_STEPS_PER_TILE - 1;
204 			}
205 			else {
206 				steps = min( VEHICLE_STEPS_PER_TILE/2 - 1, VEHICLE_STEPS_PER_TILE / 2 -(i*16) );
207 				steps_next = VEHICLE_STEPS_PER_TILE/2 ;
208 			}
209 		}
210 	}
211 
212 	// the lifetime in ms
213 	if(file->is_version_atleast(89, 5)) {
214 		file->rdwr_long(time_to_life);
215 	}
216 	// there might be crashes if world is destroyed after loading
217 	// without a sync-step being performed
218 	if(file->is_loading()  &&  time_to_life<=0) {
219 		time_to_life = 1;
220 	}
221 
222 	// Hajo: avoid endless growth of the values
223 	// this causes lockups near 2**32
224 	weg_next &= 65535;
225 }
226 
finish_rd()227 void road_user_t::finish_rd()
228 {
229 	calc_height(NULL);
230 	calc_image();
231 }
232 
233 
234 /**********************************************************************************************************************/
235 /* statsauto_t (city cars) from here on */
236 
237 
238 static weighted_vector_tpl<const citycar_desc_t*> liste_timeline;
239 stringhashtable_tpl<const citycar_desc_t *> private_car_t::table;
240 
register_desc(const citycar_desc_t * desc)241 bool private_car_t::register_desc(const citycar_desc_t *desc)
242 {
243 	if(  table.remove(desc->get_name())  ) {
244 		dbg->doubled( "citycar", desc->get_name() );
245 	}
246 	table.put(desc->get_name(), desc);
247 	return true;
248 }
249 
250 
251 
successfully_loaded()252 bool private_car_t::successfully_loaded()
253 {
254 	if(table.empty()) {
255 		DBG_MESSAGE("private_car_t", "No citycars found - feature disabled");
256 	}
257 	return true;
258 }
259 
260 
compare_stadtauto_desc(const citycar_desc_t * a,const citycar_desc_t * b)261 static bool compare_stadtauto_desc(const citycar_desc_t* a, const citycar_desc_t* b)
262 {
263 	int diff = a->get_intro_year_month() - b->get_intro_year_month();
264 	if (diff == 0) {
265 		diff = a->get_topspeed() - b->get_topspeed();
266 	}
267 	if (diff == 0) {
268 		/* same Level - we introduce an artificial, but unique resort
269 		 * on the induced name. */
270 		diff = strcmp(a->get_name(), b->get_name());
271 	}
272 	return diff < 0;
273 }
274 
275 
build_timeline_list(karte_t * welt)276 void private_car_t::build_timeline_list(karte_t *welt)
277 {
278 	// this list will contain all citycars
279 	liste_timeline.clear();
280 	vector_tpl<const citycar_desc_t*> temp_liste(0);
281 	if(  !table.empty()  ) {
282 		const int month_now = welt->get_current_month();
283 //DBG_DEBUG("private_car_t::built_timeline_liste()","year=%i, month=%i", month_now/12, month_now%12+1);
284 
285 		// check for every citycar, if still ok ...
286 		FOR(stringhashtable_tpl<citycar_desc_t const*>, const& i, table) {
287 			citycar_desc_t const* const info = i.value;
288 			const int intro_month = info->get_intro_year_month();
289 			const int retire_month = info->get_retire_year_month();
290 
291 			if (!welt->use_timeline() || (intro_month <= month_now && month_now < retire_month)) {
292 				temp_liste.insert_ordered( info, compare_stadtauto_desc );
293 			}
294 		}
295 	}
296 	liste_timeline.resize( temp_liste.get_count() );
297 	FOR(vector_tpl<citycar_desc_t const*>, const i, temp_liste) {
298 		liste_timeline.append(i, i->get_distribution_weight());
299 	}
300 }
301 
302 
303 
list_empty()304 bool private_car_t::list_empty()
305 {
306 	return liste_timeline.empty();
307 }
308 
309 
310 
~private_car_t()311 private_car_t::~private_car_t()
312 {
313 	// first: release crossing
314 	grund_t *gr = welt->lookup(get_pos());
315 	if(gr  &&  gr->ist_uebergang()) {
316 		gr->find<crossing_t>(2)->release_crossing(this);
317 	}
318 
319 	// just to be sure we are removed from this list!
320 	if(time_to_life>0) {
321 		welt->sync.remove(this);
322 	}
323 	welt->buche( -1, karte_t::WORLD_CITYCARS );
324 }
325 
326 
private_car_t(loadsave_t * file)327 private_car_t::private_car_t(loadsave_t *file) :
328 	road_user_t()
329 {
330 	rdwr(file);
331 	ms_traffic_jam = 0;
332 	calc_disp_lane();
333 	if(desc) {
334 		welt->sync.add(this);
335 	}
336 	welt->buche( +1, karte_t::WORLD_CITYCARS );
337 }
338 
339 
private_car_t(grund_t * gr,koord const target)340 private_car_t::private_car_t(grund_t* gr, koord const target) :
341 	road_user_t(gr, simrand(65535)),
342 	desc(liste_timeline.empty() ? 0 : pick_any_weighted(liste_timeline))
343 {
344 	pos_next_next = koord3d::invalid;
345 	time_to_life = welt->get_settings().get_stadtauto_duration() << 20;  // ignore welt->ticks_per_world_month_shift;
346 	current_speed = 48;
347 	ms_traffic_jam = 0;
348 #ifdef DESTINATION_CITYCARS
349 	this->target = target;
350 #else
351 	(void)target;
352 #endif
353 	calc_image();
354 	calc_disp_lane();
355 	welt->buche( +1, karte_t::WORLD_CITYCARS );
356 }
357 
358 
sync_step(uint32 delta_t)359 sync_result private_car_t::sync_step(uint32 delta_t)
360 {
361 	time_to_life -= delta_t;
362 	if(  time_to_life<=0  ) {
363 		return SYNC_DELETE;
364 	}
365 
366 	if(  current_speed==0  ) {
367 		// stuck in traffic jam
368 		uint32 old_ms_traffic_jam = ms_traffic_jam;
369 		ms_traffic_jam += delta_t;
370 		// check only every 1.024 s if stopped
371 		if(  (ms_traffic_jam>>10) != (old_ms_traffic_jam>>10)  ) {
372 			pos_next_next = koord3d::invalid;
373 			if(  hop_check()  ) {
374 				ms_traffic_jam = 0;
375 				current_speed = 48;
376 			}
377 			else {
378 				if(  ms_traffic_jam > welt->ticks_per_world_month  &&  old_ms_traffic_jam<=welt->ticks_per_world_month  ) {
379 					// message after two month, reset waiting timer
380 					welt->get_message()->add_message( translator::translate("To heavy traffic\nresults in traffic jam.\n"), get_pos().get_2d(), message_t::traffic_jams, color_idx_to_rgb(COL_ORANGE) );
381 				}
382 			}
383 		}
384 		weg_next = 0;
385 	}
386 	else {
387 		weg_next += current_speed*delta_t;
388 		const uint32 distance = do_drive( weg_next );
389 		// hop_check could have set weg_next to zero, check for possible underflow here
390 		if (weg_next > distance) {
391 			weg_next -= distance;
392 		}
393 		else {
394 			weg_next = 0;
395 		}
396 	}
397 
398 	return time_to_life>0 ? SYNC_OK : SYNC_DELETE;
399 }
400 
401 
rdwr(loadsave_t * file)402 void private_car_t::rdwr(loadsave_t *file)
403 {
404 	xml_tag_t s( file, "stadtauto_t" );
405 
406 	road_user_t::rdwr(file);
407 
408 	if(file->is_saving()) {
409 		const char *s = desc->get_name();
410 		file->rdwr_str(s);
411 	}
412 	else {
413 		char s[256];
414 		file->rdwr_str(s, lengthof(s));
415 		desc = table.get(s);
416 
417 		if(  desc == 0  &&  !liste_timeline.empty()  ) {
418 			dbg->warning("private_car_t::rdwr()", "Object '%s' not found in table, trying random stadtauto object type",s);
419 			desc = pick_any_weighted(liste_timeline);
420 		}
421 
422 		if(desc == 0) {
423 			dbg->warning("private_car_t::rdwr()", "loading game with private cars, but no private car objects found in PAK files.");
424 		}
425 		else {
426 			set_image(desc->get_image_id(ribi_t::get_dir(get_direction())));
427 		}
428 	}
429 
430 	if(file->is_version_less(86, 2)) {
431 		time_to_life = simrand(1000000)+10000;
432 	}
433 	else if(file->is_version_less(89, 5)) {
434 		file->rdwr_long(time_to_life);
435 		time_to_life *= 10000;	// converting from hops left to ms since start
436 	}
437 
438 	if(file->is_version_less(86, 5)) {
439 		// default starting speed for old games
440 		if(file->is_loading()) {
441 			current_speed = 48;
442 		}
443 	}
444 	else {
445 		sint32 dummy32=current_speed;
446 		file->rdwr_long(dummy32);
447 		current_speed = dummy32;
448 	}
449 
450 	if(file->is_version_less(99, 10)) {
451 		pos_next_next = koord3d::invalid;
452 	}
453 	else {
454 		pos_next_next.rdwr(file);
455 	}
456 
457 	// overtaking status
458 	if(file->is_version_less(100, 1)) {
459 		set_tiles_overtaking( 0 );
460 	}
461 	else {
462 		file->rdwr_byte(tiles_overtaking);
463 		set_tiles_overtaking( tiles_overtaking );
464 	}
465 	// do not start with zero speed!
466 	current_speed ++;
467 }
468 
469 
ist_weg_frei(grund_t * gr)470 bool private_car_t::ist_weg_frei(grund_t *gr)
471 {
472 	if(gr->get_top()>200) {
473 		// already too many things here
474 		return false;
475 	}
476 
477 	// road still there?
478 	weg_t * str = gr->get_weg(road_wt);
479 	if(str==NULL) {
480 		time_to_life = 0;
481 		return false;
482 	}
483 
484 	// calculate new direction
485 	// are we just turning around?
486 	const uint8 this_direction = get_direction();
487 	bool frei = false;
488 	if(  get_pos()==pos_next_next  ) {
489 		// turning around => single check
490 		const uint8 next_direction = ribi_t::backward(this_direction);
491 		frei = (NULL == no_cars_blocking( gr, NULL, next_direction, next_direction, next_direction ));
492 
493 		// do not block railroad crossing
494 		if(frei  &&  str->is_crossing()) {
495 			const grund_t *gr = welt->lookup(get_pos());
496 			frei = (NULL == no_cars_blocking( gr, NULL, next_direction, next_direction, next_direction ));
497 		}
498 	}
499 	else {
500 		// driving on: check for crossings etc. too
501 		const uint8 next_direction = this->calc_direction(get_pos(), pos_next_next);
502 
503 		// do not block this crossing (if possible)
504 		if(ribi_t::is_threeway(str->get_ribi_unmasked())) {
505 			// but leaving from railroad crossing is more important
506 			grund_t *gr_here = welt->lookup(get_pos());
507 			if(  gr_here  &&  gr_here->ist_uebergang()  ) {
508 				return true;
509 			}
510 			grund_t *test = welt->lookup(pos_next_next);
511 			if(  test  ) {
512 				uint8 next_90direction = this->calc_direction(pos_next, pos_next_next);
513 				frei = (NULL == no_cars_blocking( gr, NULL, this_direction, next_direction, next_90direction ));
514 				if(  frei  ) {
515 					// check, if it can leave this crossings
516 					frei = (NULL == no_cars_blocking( test, NULL, next_direction, next_90direction, next_90direction ));
517 				}
518 			}
519 			// this fails with two crossings together; however, I see no easy way out here ...
520 		}
521 		else {
522 			// not a crossing => skip 90� check!
523 			frei = true;
524 			// Overtaking vehicles shouldn't have anything blocking them
525 			if(  !is_overtaking()  ) {
526 				// not a crossing => skip 90� check!
527 				vehicle_base_t *dt = no_cars_blocking( gr, NULL, this_direction, next_direction, next_direction );
528 				if(  dt  ) {
529 					if(dt->is_stuck()) {
530 						// previous vehicle is stuck => end of traffic jam ...
531 						frei = false;
532 					}
533 					else {
534 						overtaker_t *over = dt->get_overtaker();
535 						if(over) {
536 							if(!over->is_overtaking()) {
537 								// otherwise the overtaken car would stop for us ...
538 								if(  road_vehicle_t const* const car = obj_cast<road_vehicle_t>(dt)  ) {
539 									convoi_t* const ocnv = car->get_convoi();
540 									if(  ocnv==NULL  ||  !can_overtake( ocnv, (ocnv->get_state()==convoi_t::LOADING ? 0 : over->get_max_power_speed()), ocnv->get_length_in_steps()+ocnv->get_vehikel(0)->get_steps())  ) {
541 										frei = false;
542 									}
543 								} else if(  private_car_t* const caut = obj_cast<private_car_t>(dt)  ) {
544 									if(  !can_overtake(caut, caut->get_desc()->get_topspeed(), VEHICLE_STEPS_PER_TILE)  ) {
545 										frei = false;
546 									}
547 								}
548 							}
549 						}
550 						else {
551 							// movingobj ... block road totally
552 							frei = false;
553 						}
554 					}
555 				}
556 			}
557 		}
558 
559 		// do not block railroad crossing
560 		if(  frei  &&  str->is_crossing()  ) {
561 			// can we cross?
562 			crossing_t* cr = gr->find<crossing_t>(2);
563 			if(  cr && !cr->request_crossing(this)) {
564 				// approaching railway crossing: check if empty
565 				return false;
566 			}
567 			// no further check, when already entered a crossing (to allow leaving it)
568 			grund_t *gr_here = welt->lookup(get_pos());
569 			if(gr_here  &&  gr_here->ist_uebergang()) {
570 				return true;
571 			}
572 			// ok, now check for free exit
573 			koord dir = pos_next.get_2d()-get_pos().get_2d();
574 			koord3d checkpos = pos_next+dir;
575 			uint8 number_reversed = 0;
576 			while(  number_reversed<2  ) {
577 				const grund_t *test = welt->lookup(checkpos);
578 				if(!test) {
579 					// should not reach here ! (z9999)
580 					break;
581 				}
582 				const uint8 next_direction = ribi_type(dir);
583 				const uint8 nextnext_direction = ribi_type(dir);
584 				// test next field after way crossing
585 				if(no_cars_blocking( test, NULL, next_direction, nextnext_direction, nextnext_direction )) {
586 					return false;
587 				}
588 				// ok, left the crossing
589 				if(!test->find<crossing_t>(2)) {
590 					// approaching railway crossing: check if empty
591 					crossing_t* cr = gr->find<crossing_t>(2);
592 					return cr->request_crossing( this );
593 				}
594 				else {
595 					// seems to be a dead-end.
596 					if(  (test->get_weg_ribi(road_wt)&next_direction) == 0  ) {
597 						// will be going back
598 						pos_next_next=get_pos();
599 						// check also opposite direction are free
600 						dir = -dir;
601 						number_reversed ++;
602 					}
603 				}
604 				checkpos += dir;
605 			}
606 		}
607 	}
608 
609 	if(frei  &&  current_speed==0) {
610 		ms_traffic_jam = 0;
611 		current_speed = 48;
612 	}
613 
614 	if(!frei) {
615 		// not free => stop overtaking
616 		this->set_tiles_overtaking(0);
617 	}
618 
619 	return frei;
620 }
621 
622 
enter_tile(grund_t * gr)623 void private_car_t::enter_tile(grund_t* gr)
624 {
625 #ifdef DESTINATION_CITYCARS
626 	if(  target!=koord::invalid  &&  koord_distance(pos_next.get_2d(),target)<10  ) {
627 		// delete it ...
628 		time_to_life = 0;
629 		// was generating pedestrians gere, but not possible with new sync system
630 	}
631 #endif
632 	vehicle_base_t::enter_tile(gr);
633 	calc_disp_lane();
634 	gr->get_weg(road_wt)->book(1, WAY_STAT_CONVOIS);
635 }
636 
637 
hop_check()638 grund_t* private_car_t::hop_check()
639 {
640 	// V.Meyer: weg_position_t changed to grund_t::get_neighbour()
641 	grund_t *const from = welt->lookup(pos_next);
642 	if(from==NULL) {
643 		// nothing to go? => destroy ...
644 		time_to_life = 0;
645 		return NULL;
646 	}
647 
648 	// find the allowed directions
649 	const weg_t *weg = from->get_weg(road_wt);
650 	if(weg==NULL) {
651 		// nothing to go? => destroy ...
652 		time_to_life = 0;
653 		return NULL;
654 	}
655 
656 	// traffic light phase check (since this is on next tile, it will always be necessary!)
657 	const ribi_t::ribi direction90 = ribi_type(get_pos(), pos_next);
658 
659 	if(  weg->has_sign(  )) {
660 		const roadsign_t* rs = from->find<roadsign_t>();
661 		const roadsign_desc_t* rs_desc = rs->get_desc();
662 		if(rs_desc->is_traffic_light()  &&  (rs->get_dir()&direction90)==0) {
663 			direction = direction90;
664 			calc_image();
665 			// wait here
666 			current_speed = 48;
667 			weg_next = 0;
668 			return NULL;
669 		}
670 	}
671 
672 	// next tile unknown => find next tile
673 	if(pos_next_next==koord3d::invalid) {
674 
675 		// ok, nobody did delete the road in front of us
676 		// so we can check for valid directions
677 		ribi_t::ribi ribi = weg->get_ribi() & (~ribi_t::backward(direction90));
678 
679 		// cul de sac: return
680 		if(ribi==0) {
681 			pos_next_next = get_pos();
682 			return ist_weg_frei(from) ? from : NULL;
683 		}
684 
685 #ifdef DESTINATION_CITYCARS
686 		static weighted_vector_tpl<koord3d> posliste(4);
687 		posliste.clear();
688 		const uint8 offset = ribi_t::is_single(ribi) ? 0 : simrand(4);
689 		for(uint8 r = 0; r < 4; r++) {
690 			if(  get_pos().get_2d()==koord::nsew[r]+pos_next.get_2d()  ) {
691 				continue;
692 			}
693 #else
694 		const uint8 offset = ribi_t::is_single(ribi) ? 0 : simrand(4);
695 		for(uint8 i = 0; i < 4; i++) {
696 			const uint8 r = (i+offset)&3;
697 #endif
698 			if(  (ribi&ribi_t::nsew[r])!=0  ) {
699 				grund_t *to;
700 				if(  from->get_neighbour(to, road_wt, ribi_t::nsew[r])  ) {
701 					// check, if this is just a single tile deep after a crossing
702 					weg_t *w = to->get_weg(road_wt);
703 					if(  ribi_t::is_single(w->get_ribi())  &&  (w->get_ribi()&ribi_t::nsew[r])==0  &&  !ribi_t::is_single(ribi)  ) {
704 						ribi &= ~ribi_t::nsew[r];
705 						continue;
706 					}
707 					// check, if roadsign forbid next step ...
708 					if(w->has_sign()) {
709 						const roadsign_t* rs = to->find<roadsign_t>();
710 						const roadsign_desc_t* rs_desc = rs->get_desc();
711 						if(rs_desc->get_min_speed()>desc->get_topspeed()  ||  (rs_desc->is_private_way()  &&  (rs->get_player_mask()&2)==0)  ) {
712 							// not allowed to go here
713 							ribi &= ~ribi_t::nsew[r];
714 							continue;
715 						}
716 					}
717 #ifdef DESTINATION_CITYCARS
718 					uint32 dist=koord_distance( to->get_pos().get_2d(), target );
719 					posliste.append( to->get_pos(), dist*dist );
720 #else
721 					// ok, now check if we are allowed to go here (i.e. no cars blocking)
722 					pos_next_next = to->get_pos();
723 					if(ist_weg_frei(from)) {
724 						// ok, this direction is fine!
725 						ms_traffic_jam = 0;
726 						if(current_speed<48) {
727 							current_speed = 48;
728 						}
729 						return from;
730 					}
731 					else {
732 						pos_next_next = koord3d::invalid;
733 					}
734 #endif
735 				}
736 				else {
737 					// not connected?!? => ribi likely wrong
738 					ribi &= ~ribi_t::nsew[r];
739 				}
740 			}
741 		}
742 #ifdef DESTINATION_CITYCARS
743 		if (!posliste.empty()) {
744 			pos_next_next = pick_any_weighted(posliste);
745 		}
746 		else {
747 			pos_next_next = get_pos();
748 		}
749 		if(ist_weg_frei(from)) {
750 			// ok, this direction is fine!
751 			ms_traffic_jam = 0;
752 			if(current_speed<48) {
753 				current_speed = 48;
754 			}
755 			return from;
756 		}
757 #else
758 		// only stumps at single way crossing, all other blocked => turn around
759 		if(ribi==0) {
760 			pos_next_next = get_pos();
761 			return ist_weg_frei(from) ? from : NULL;
762 		}
763 #endif
764 	}
765 	else {
766 		if(from  &&  ist_weg_frei(from)) {
767 			// ok, this direction is fine!
768 			ms_traffic_jam = 0;
769 			if(current_speed<48) {
770 				current_speed = 48;
771 			}
772 			return from;
773 		}
774 	}
775 	// no free tiles => assume traffic jam ...
776 	pos_next_next = koord3d::invalid;
777 	current_speed = 0;
778 	set_tiles_overtaking( 0 );
779 	return NULL;
780 }
781 
782 
783 
784 void private_car_t::hop(grund_t* to)
785 {
786 	leave_tile();
787 
788 	if(pos_next_next==get_pos()) {
789 		direction = calc_set_direction( pos_next, pos_next_next );
790 		steps_next = 0;	// mark for starting at end of tile!
791 	}
792 	else {
793 		direction = calc_set_direction( get_pos(), pos_next_next );
794 	}
795 	calc_image();
796 
797 	// and add to next tile
798 	set_pos(pos_next);
799 	enter_tile(to);
800 
801 	calc_current_speed(to);
802 
803 	update_tiles_overtaking();
804 	if(to->ist_uebergang()) {
805 		to->find<crossing_t>(2)->add_to_crossing(this);
806 	}
807 	pos_next = pos_next_next;
808 	pos_next_next = koord3d::invalid;
809 }
810 
811 
812 void private_car_t::calc_image()
813 {
814 	set_image(desc->get_image_id(ribi_t::get_dir(get_direction())));
815 }
816 
817 
818 void private_car_t::calc_current_speed(grund_t* gr)
819 {
820 	const weg_t * weg = gr->get_weg(road_wt);
821 	const sint32 max_speed = desc->get_topspeed();
822 	const sint32 speed_limit = weg ? kmh_to_speed(weg->get_max_speed()) : max_speed;
823 	current_speed += max_speed>>2;
824 	if(current_speed > max_speed) {
825 		current_speed = max_speed;
826 	}
827 	if(current_speed > speed_limit) {
828 		current_speed = speed_limit;
829 	}
830 }
831 
832 
833 void private_car_t::info(cbuffer_t & buf) const
834 {
835 	buf.printf(translator::translate("%s\nspeed %i\nmax_speed %i\ndx:%i dy:%i"), translator::translate(desc->get_name()), speed_to_kmh(current_speed), speed_to_kmh(desc->get_topspeed()), dx, dy);
836 
837 	if (char const* const maker = desc->get_copyright()) {
838 		buf.printf(translator::translate("Constructed by %s"), maker);
839 	}
840 }
841 
842 
843 // to make smaller steps than the tile granularity, we have to use this trick
844 void private_car_t::get_screen_offset( int &xoff, int &yoff, const sint16 raster_width ) const
845 {
846 	vehicle_base_t::get_screen_offset( xoff, yoff, raster_width );
847 
848 	if(  welt->get_settings().is_drive_left()  ) {
849 		const int drive_left_dir = ribi_t::get_dir(get_direction());
850 		xoff += tile_raster_scale_x( driveleft_base_offsets[drive_left_dir][0], raster_width );
851 		yoff += tile_raster_scale_y( driveleft_base_offsets[drive_left_dir][1], raster_width );
852 	}
853 
854 	// eventually shift position to take care of overtaking
855 	if(  is_overtaking()  ) {
856 		xoff += tile_raster_scale_x(overtaking_base_offsets[ribi_t::get_dir(get_direction())][0], raster_width);
857 		yoff += tile_raster_scale_x(overtaking_base_offsets[ribi_t::get_dir(get_direction())][1], raster_width);
858 	}
859 	else if(  is_overtaken()  ) {
860 		xoff -= tile_raster_scale_x(overtaking_base_offsets[ribi_t::get_dir(get_direction())][0], raster_width)/5;
861 		yoff -= tile_raster_scale_x(overtaking_base_offsets[ribi_t::get_dir(get_direction())][1], raster_width)/5;
862 	}
863 }
864 
865 
866 void private_car_t::calc_disp_lane()
867 {
868 	// driving in the back or the front
869 	ribi_t::ribi test_dir = welt->get_settings().is_drive_left() ? ribi_t::northeast : ribi_t::southwest;
870 	disp_lane = get_direction() & test_dir ? 1 : 3;
871 }
872 
873 void private_car_t::rotate90()
874 {
875 	road_user_t::rotate90();
876 	calc_disp_lane();
877 }
878 
879 /**
880  * conditions for a city car to overtake another overtaker.
881  * The city car is not overtaking/being overtaken.
882  * @author isidoro
883  */
884 bool private_car_t::can_overtake( overtaker_t *other_overtaker, sint32 other_speed, sint16 steps_other)
885 {
886 	if(  !other_overtaker->can_be_overtaken()  ) {
887 		return false;
888 	}
889 
890 	if(  other_speed == 0  ) {
891 		/* overtaking a loading convoi
892 		 * => we can do a lazy check, since halts are always straight
893 		 */
894 		grund_t *gr = welt->lookup(get_pos());
895 		if(  gr==NULL  ) {
896 			// should never happen, since there is a vehicle in front of us ...
897 			return false;
898 		}
899 		weg_t *str = gr->get_weg(road_wt);
900 		if(  str==0  ) {
901 			// also this is not possible, since a car loads in front of is!?!
902 			return false;
903 		}
904 
905 		const ribi_t::ribi direction = get_direction() & str->get_ribi();
906 		koord3d check_pos = get_pos()+koord((ribi_t::ribi)(str->get_ribi()&direction));
907 		for(  int tiles=1+(steps_other-1)/(CARUNITS_PER_TILE*VEHICLE_STEPS_PER_CARUNIT);  tiles>=0;  tiles--  ) {
908 			grund_t *gr = welt->lookup(check_pos);
909 			if(  gr==NULL  ) {
910 				return false;
911 			}
912 			weg_t *str = gr->get_weg(road_wt);
913 			if(  str==0  ) {
914 				return false;
915 			}
916 			// not overtaking on railroad crossings ...
917 			if(  str->is_crossing() ) {
918 				return false;
919 			}
920 			if(  ribi_t::is_threeway(str->get_ribi())  ) {
921 				return false;
922 			}
923 			// Check for other vehicles on the next tile
924 			const uint8 top = gr->get_top();
925 			for(  uint8 j=1;  j<top;  j++  ) {
926 				if(  vehicle_base_t* const v = obj_cast<vehicle_base_t>(gr->obj_bei(j))  ) {
927 					// check for other traffic on the road
928 					const overtaker_t *ov = v->get_overtaker();
929 					if(ov) {
930 						if(this!=ov  &&  other_overtaker!=ov) {
931 							return false;
932 						}
933 					}
934 					else if(  v->get_waytype()==road_wt  &&  v->get_typ()!=obj_t::pedestrian  ) {
935 						return false;
936 					}
937 				}
938 			}
939 			check_pos += koord(direction);
940 		}
941 		set_tiles_overtaking( 3+(steps_other-1)/(CARUNITS_PER_TILE*VEHICLE_STEPS_PER_CARUNIT) );
942 		return true;
943 	}
944 
945 	sint32 diff_speed = (sint32)current_speed - other_speed;
946 	if(  diff_speed < kmh_to_speed(5)  ) {
947 		// not fast enough to overtake
948 		return false;
949 	}
950 
951 	// Number of tiles overtaking will take
952 	int n_tiles = 0;
953 
954 	/* Distance it takes overtaking (unit: vehicle steps) = my_speed * time_overtaking
955 	 * time_overtaking = tiles_to_overtake/diff_speed
956 	 * tiles_to_overtake = convoi_length + pos_other_convoi
957 	 * convoi_length for city cars? ==> a bit over half a tile (10)
958 	 */
959 	sint32 time_overtaking = 0;
960 	sint32 distance = current_speed*((10<<4)+steps_other)/max(desc->get_topspeed()-other_speed,diff_speed);
961 
962 	// Conditions for overtaking:
963 	// Flat tiles, with no stops, no crossings, no signs, no change of road speed limit
964 	koord3d check_pos = get_pos();
965 	koord pos_prev = check_pos.get_2d();
966 
967 	grund_t *gr = welt->lookup(check_pos);
968 	if(  gr==NULL  ) {
969 		return false;
970 	}
971 
972 	weg_t *str = gr->get_weg(road_wt);
973 	if(  str==0  ) {
974 		return false;
975 	}
976 
977 	// we need 90 degree ribi
978 	ribi_t::ribi direction = get_direction();
979 	direction = str->get_ribi() & direction;
980 
981 	while(  distance > 0  ) {
982 
983 		// we allow stops and slopes, since empty stops and slopes cannot affect us
984 		// (citycars do not slow down on slopes!)
985 
986 		// start of bridge is one level deeper
987 		if(gr->get_weg_yoff()>0)  {
988 			check_pos.z ++;
989 		}
990 
991 		// special signs
992 		if(  str->has_sign()  &&  str->get_ribi()==str->get_ribi_unmasked()  ) {
993 			const roadsign_t *rs = gr->find<roadsign_t>(1);
994 			if(rs) {
995 				const roadsign_desc_t *rb = rs->get_desc();
996 				if(rb->get_min_speed()>desc->get_topspeed()  ||  rb->is_private_way()  ||  rb->is_traffic_light()  ) {
997 					// do not overtake when road is closed for cars, there is a traffic light or a too high min speed limit
998 					return false;
999 				}
1000 			}
1001 		}
1002 
1003 		// not overtaking on railroad crossings ...
1004 		if(  str->is_crossing() ) {
1005 			return false;
1006 		}
1007 
1008 		// street gets too slow (TODO: should be able to be correctly accounted for)
1009 		if(  desc->get_topspeed() > kmh_to_speed(str->get_max_speed())  ) {
1010 			return false;
1011 		}
1012 
1013 		int d = ribi_t::is_straight(str->get_ribi()) ? VEHICLE_STEPS_PER_TILE : diagonal_vehicle_steps_per_tile;
1014 		distance -= d;
1015 		time_overtaking += d;
1016 
1017 		n_tiles++;
1018 
1019 		/* Now we must check for next position:
1020 		 * crossings are ok, as long as we cannot exit there due to one way signs
1021 		 * much cheaper calculation: only go on in the direction of before (since no slopes allowed anyway ... )
1022 		 */
1023 		grund_t *to = welt->lookup( check_pos + koord((ribi_t::ribi)(str->get_ribi()&direction)) );
1024 		if(  ribi_t::is_threeway(str->get_ribi())  ||  to==NULL) {
1025 			// check for entries/exits/bridges, if necessary
1026 			ribi_t::ribi rib = str->get_ribi();
1027 			bool found_one = false;
1028 			for(  int r=0;  r<4;  r++  ) {
1029 				if(  (rib&ribi_t::nsew[r])==0  ||  check_pos.get_2d()+koord::nsew[r]==pos_prev) {
1030 					continue;
1031 				}
1032 				if(gr->get_neighbour(to, road_wt, ribi_t::nsew[r])) {
1033 					if(found_one) {
1034 						// two directions to go: unexpected cars may occurs => abort
1035 						return false;
1036 					}
1037 					found_one = true;
1038 				}
1039 			}
1040 		}
1041 		pos_prev = check_pos.get_2d();
1042 
1043 		// nowhere to go => nobody can come against us ...
1044 		if(to==NULL  ||  (str=to->get_weg(road_wt))==NULL) {
1045 			return false;
1046 		}
1047 
1048 		// Check for other vehicles on the next tile
1049 		const uint8 top = gr->get_top();
1050 		for(  uint8 j=1;  j<top;  j++  ) {
1051 			if(  vehicle_base_t* const v = obj_cast<vehicle_base_t>(gr->obj_bei(j))  ) {
1052 				// check for other traffic on the road
1053 				const overtaker_t *ov = v->get_overtaker();
1054 				if(ov) {
1055 					if(this!=ov  &&  other_overtaker!=ov) {
1056 						return false;
1057 					}
1058 				}
1059 				else if(  v->get_waytype()==road_wt  &&  v->get_typ()!=obj_t::pedestrian  ) {
1060 					return false;
1061 				}
1062 			}
1063 		}
1064 
1065 		gr = to;
1066 		check_pos = to->get_pos();
1067 
1068 		direction = ~ribi_type( check_pos, pos_prev ) & str->get_ribi();
1069 	}
1070 
1071 	// Second phase: only facing traffic is forbidden
1072 	//   Since street speed can change, we do the calculation with time.
1073 	//   Each empty tile will subtract tile_dimension/max_street_speed.
1074 	//   If time is exhausted, we are guaranteed that no facing traffic will
1075 	//   invade the dangerous zone.
1076 	time_overtaking = (time_overtaking << 16)/(sint32)current_speed;
1077 	do {
1078 		// we can allow crossings or traffic lights here, since they will stop also oncoming traffic
1079 		if(  ribi_t::is_straight(str->get_ribi())  ) {
1080 			time_overtaking -= (VEHICLE_STEPS_PER_TILE<<16) / kmh_to_speed(str->get_max_speed());
1081 		}
1082 		else {
1083 			time_overtaking -= (diagonal_vehicle_steps_per_tile<<16) / kmh_to_speed(str->get_max_speed());
1084 		}
1085 
1086 		// start of bridge is one level deeper
1087 		if(gr->get_weg_yoff()>0)  {
1088 			check_pos.z ++;
1089 		}
1090 
1091 		// much cheaper calculation: only go on in the direction of before ...
1092 		grund_t *to = welt->lookup( check_pos + koord((ribi_t::ribi)(str->get_ribi()&direction)) );
1093 		if(  ribi_t::is_threeway(str->get_ribi())  ||  to==NULL  ) {
1094 			// check for crossings/bridges, if necessary
1095 			bool found_one = false;
1096 			for(  int r=0;  r<4;  r++  ) {
1097 				if(check_pos.get_2d()+koord::nsew[r]==pos_prev) {
1098 					continue;
1099 				}
1100 				if(gr->get_neighbour(to, road_wt, ribi_t::nsew[r])) {
1101 					if(found_one) {
1102 						return false;
1103 					}
1104 					found_one = true;
1105 				}
1106 			}
1107 		}
1108 
1109 		koord pos_prev_prev = pos_prev;
1110 		pos_prev = check_pos.get_2d();
1111 
1112 		// nowhere to go => nobody can come against us ...
1113 		if(to==NULL  ||  (str=to->get_weg(road_wt))==NULL) {
1114 			break;
1115 		}
1116 
1117 		// Check for other vehicles in facing direction
1118 		// now only I know direction on this tile ...
1119 		ribi_t::ribi their_direction = ribi_t::backward(calc_direction( pos_prev_prev, to->get_pos()));
1120 		const uint8 top = gr->get_top();
1121 		for(  uint8 j=1;  j<top;  j++ ) {
1122 			vehicle_base_t* const v = obj_cast<vehicle_base_t>(gr->obj_bei(j));
1123 			if(  v  &&  v->get_direction() == their_direction  ) {
1124 				// check for car
1125 				if(v->get_overtaker()) {
1126 					return false;
1127 				}
1128 			}
1129 		}
1130 
1131 		gr = to;
1132 		check_pos = to->get_pos();
1133 
1134 		direction = ~ribi_type( check_pos, pos_prev ) & str->get_ribi();
1135 	} while( time_overtaking > 0 );
1136 
1137 	set_tiles_overtaking( 1+n_tiles );
1138 	other_overtaker->set_tiles_overtaking( -1-(n_tiles/2) );
1139 
1140 	return true;
1141 }
1142