roadveh_cmd.c
changeset 2951 2de6d3a59743
parent 2933 df6248fd77a7
child 2952 58522ed8f0f1
equal deleted inserted replaced
2950:30eee9c93028 2951:2de6d3a59743
   497 {
   497 {
   498 	v->u.road.crashed_ctr++;
   498 	v->u.road.crashed_ctr++;
   499 	if (v->u.road.crashed_ctr == 2) {
   499 	if (v->u.road.crashed_ctr == 2) {
   500 		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
   500 		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
   501 	} else if (v->u.road.crashed_ctr <= 45) {
   501 	} else if (v->u.road.crashed_ctr <= 45) {
   502 		if ((v->tick_counter&7)==0)
   502 		if ((v->tick_counter & 7) == 0)
   503 			RoadVehSetRandomDirection(v);
   503 			RoadVehSetRandomDirection(v);
   504 	} else if (v->u.road.crashed_ctr >= 2220) {
   504 	} else if (v->u.road.crashed_ctr >= 2220) {
   505 		RoadVehDelete(v);
   505 		RoadVehDelete(v);
   506 	}
   506 	}
   507 }
   507 }
   524 	v->vehstatus |= VS_CRASHED;
   524 	v->vehstatus |= VS_CRASHED;
   525 
   525 
   526 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   526 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   527 
   527 
   528 	pass = 1;
   528 	pass = 1;
   529 	if (v->cargo_type == 0)
   529 	if (v->cargo_type == 0) pass += v->cargo_count;
   530 		pass += v->cargo_count;
       
   531 	v->cargo_count = 0;
   530 	v->cargo_count = 0;
       
   531 
   532 	SetDParam(0, pass);
   532 	SetDParam(0, pass);
   533 
       
   534 	AddNewsItem(
   533 	AddNewsItem(
   535 		(pass == 1) ?
   534 		(pass == 1) ?
   536 			STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE,
   535 			STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE,
   537 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
   536 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
   538 		v->index,
   537 		v->index,
   544 
   543 
   545 static void RoadVehCheckTrainCrash(Vehicle *v)
   544 static void RoadVehCheckTrainCrash(Vehicle *v)
   546 {
   545 {
   547 	TileIndex tile;
   546 	TileIndex tile;
   548 
   547 
   549 	if (v->u.road.state == 255)
   548 	if (v->u.road.state == 255) return;
   550 		return;
       
   551 
   549 
   552 	tile = v->tile;
   550 	tile = v->tile;
   553 
   551 
   554 	// Make sure it's a road/rail crossing
   552 	if (!IsTileType(tile, MP_STREET) || !IsLevelCrossing(tile)) return;
   555 	if (!IsTileType(tile, MP_STREET) || !IsLevelCrossing(tile))
       
   556 		return;
       
   557 
   553 
   558 	if (VehicleFromPos(tile, v, (VehicleFromPosProc*)EnumCheckRoadVehCrashTrain) != NULL)
   554 	if (VehicleFromPos(tile, v, (VehicleFromPosProc*)EnumCheckRoadVehCrashTrain) != NULL)
   559 		RoadVehCrash(v);
   555 		RoadVehCrash(v);
   560 }
   556 }
   561 
   557 
   619 		return;
   615 		return;
   620 	}
   616 	}
   621 
   617 
   622 	if (order->type    == v->current_order.type &&
   618 	if (order->type    == v->current_order.type &&
   623 			order->flags   == v->current_order.flags &&
   619 			order->flags   == v->current_order.flags &&
   624 			order->station == v->current_order.station)
   620 			order->station == v->current_order.station) {
   625 		return;
   621 		return;
       
   622 	}
   626 
   623 
   627 	v->current_order = *order;
   624 	v->current_order = *order;
   628 
       
   629 	v->dest_tile = 0;
   625 	v->dest_tile = 0;
   630 
   626 
   631 	if (order->type == OT_GOTO_STATION) {
   627 	if (order->type == OT_GOTO_STATION) {
   632 		if (order->station == v->last_station_visited)
   628 		if (order->station == v->last_station_visited)
   633 			v->last_station_visited = INVALID_STATION;
   629 			v->last_station_visited = INVALID_STATION;
   797 	}
   793 	}
   798 }
   794 }
   799 
   795 
   800 static bool RoadVehAccelerate(Vehicle *v)
   796 static bool RoadVehAccelerate(Vehicle *v)
   801 {
   797 {
   802 	uint spd = v->cur_speed + 1 + ((v->u.road.overtaking != 0)?1:0);
   798 	uint spd = v->cur_speed + 1 + (v->u.road.overtaking != 0 ? 1 : 0);
   803 	byte t;
   799 	byte t;
   804 
   800 
   805 	// Clamp
   801 	// Clamp
   806 	spd = min(spd, v->max_speed);
   802 	spd = min(spd, v->max_speed);
   807 
   803 
   808 	//updates statusbar only if speed have changed to save CPU time
   804 	//updates statusbar only if speed have changed to save CPU time
   809 	if (spd != v->cur_speed) {
   805 	if (spd != v->cur_speed) {
   810 		v->cur_speed = spd;
   806 		v->cur_speed = spd;
   811 		if (_patches.vehicle_speed)
   807 		if (_patches.vehicle_speed) {
   812 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   808 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
   809 		}
   813 	}
   810 	}
   814 
   811 
   815 	// Decrease somewhat when turning
   812 	// Decrease somewhat when turning
   816 	if (!(v->direction&1))
   813 	if (!(v->direction & 1)) spd = spd * 3 >> 2;
   817 		spd = spd * 3 >> 2;
   814 
   818 
   815 	if (spd == 0) return false;
   819 	if (spd == 0)
   816 
   820 		return false;
   817 	if ((byte)++spd == 0) return true;
   821 
       
   822 	if ((byte)++spd == 0)
       
   823 		return true;
       
   824 
   818 
   825 	v->progress = (t = v->progress) - (byte)spd;
   819 	v->progress = (t = v->progress) - (byte)spd;
   826 
   820 
   827 	return (t < v->progress);
   821 	return (t < v->progress);
   828 }
   822 }
   888 
   882 
   889 	od.v = v;
   883 	od.v = v;
   890 	od.u = u;
   884 	od.u = u;
   891 
   885 
   892 	if (u->max_speed >= v->max_speed &&
   886 	if (u->max_speed >= v->max_speed &&
   893 			!(u->vehstatus&VS_STOPPED) &&
   887 			!(u->vehstatus & VS_STOPPED) &&
   894 			u->cur_speed != 0)
   888 			u->cur_speed != 0) {
   895 				return;
   889 		return;
       
   890 	}
   896 
   891 
   897 	if (v->direction != u->direction || !(v->direction&1))
   892 	if (v->direction != u->direction || !(v->direction&1))
   898 		return;
   893 		return;
   899 
   894 
   900 	if (v->u.road.state >= 32 || (v->u.road.state&7) > 1 )
   895 	if (v->u.road.state >= 32 || (v->u.road.state&7) > 1 )
   901 		return;
   896 		return;
   902 
   897 
   903 	tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD) & 0x3F;
   898 	tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD) & 0x3F;
   904 	if ((tt & 3) == 0)
   899 	if ((tt & 3) == 0) return;
   905 		return;
   900 	if ((tt & 0x3C) != 0) return;
   906 	if ((tt & 0x3C) != 0)
   901 
   907 		return;
   902 	if (tt == 3) tt = (v->direction & 2) ? 2 : 1;
   908 
       
   909 	if (tt == 3) {
       
   910 		tt = (v->direction&2)?2:1;
       
   911 	}
       
   912 	od.tilebits = tt;
   903 	od.tilebits = tt;
   913 
   904 
   914 	od.tile = v->tile;
   905 	od.tile = v->tile;
   915 	if (FindRoadVehToOvertake(&od))
   906 	if (FindRoadVehToOvertake(&od)) return;
   916 		return;
       
   917 
   907 
   918 	od.tile = v->tile + TileOffsByDir(v->direction >> 1);
   908 	od.tile = v->tile + TileOffsByDir(v->direction >> 1);
   919 	if (FindRoadVehToOvertake(&od))
   909 	if (FindRoadVehToOvertake(&od)) return;
   920 		return;
       
   921 
   910 
   922 	if (od.u->cur_speed == 0 || od.u->vehstatus&VS_STOPPED) {
   911 	if (od.u->cur_speed == 0 || od.u->vehstatus&VS_STOPPED) {
   923 		v->u.road.overtaking_ctr = 0x11;
   912 		v->u.road.overtaking_ctr = 0x11;
   924 		v->u.road.overtaking = 0x10;
   913 		v->u.road.overtaking = 0x10;
   925 	} else {
   914 	} else {
   926 //		if (FindRoadVehToOvertake(&od))
   915 //		if (FindRoadVehToOvertake(&od)) return;
   927 //			return;
       
   928 		v->u.road.overtaking_ctr = 0;
   916 		v->u.road.overtaking_ctr = 0;
   929 		v->u.road.overtaking = 0x10;
   917 		v->u.road.overtaking = 0x10;
   930 	}
   918 	}
   931 }
   919 }
   932 
   920 
   949 	uint num = 0;
   937 	uint num = 0;
   950 	uint b = bits;
   938 	uint b = bits;
   951 	uint i;
   939 	uint i;
   952 
   940 
   953 	do {
   941 	do {
   954 		if (b & 1)
   942 		if (b & 1) num++;
   955 			num++;
       
   956 	} while (b >>= 1);
   943 	} while (b >>= 1);
   957 
   944 
   958 	num = RandomRange(num);
   945 	num = RandomRange(num);
   959 
   946 
   960 	for(i=0; !((bits & 1) && ((int)--num) < 0); bits>>=1,i++);
   947 	for(i=0; !((bits & 1) && ((int)--num) < 0); bits>>=1,i++);
  1187 			return;
  1174 			return;
  1188 		}
  1175 		}
  1189 		v->breakdown_ctr--;
  1176 		v->breakdown_ctr--;
  1190 	}
  1177 	}
  1191 
  1178 
  1192 	// exit if vehicle is stopped
  1179 	if (v->vehstatus & VS_STOPPED) return;
  1193 	if (v->vehstatus & VS_STOPPED)
       
  1194 		return;
       
  1195 
  1180 
  1196 	ProcessRoadVehOrder(v);
  1181 	ProcessRoadVehOrder(v);
  1197 	HandleRoadVehLoading(v);
  1182 	HandleRoadVehLoading(v);
  1198 
  1183 
  1199 	if (v->current_order.type == OT_LOADING)
  1184 	if (v->current_order.type == OT_LOADING) return;
  1200 		return;
       
  1201 
  1185 
  1202 	if (v->u.road.state == 254) {
  1186 	if (v->u.road.state == 254) {
  1203 		int dir;
  1187 		int dir;
  1204 		const RoadDriveEntry*rdp;
  1188 		const RoadDriveEntry*rdp;
  1205 		byte rd2;
  1189 		byte rd2;
  1213 		rdp = _road_drive_data[(_opt.road_side<<4) + rd2];
  1197 		rdp = _road_drive_data[(_opt.road_side<<4) + rd2];
  1214 
  1198 
  1215 		x = TileX(v->tile) * 16 + (rdp[6].x & 0xF);
  1199 		x = TileX(v->tile) * 16 + (rdp[6].x & 0xF);
  1216 		y = TileY(v->tile) * 16 + (rdp[6].y & 0xF);
  1200 		y = TileY(v->tile) * 16 + (rdp[6].y & 0xF);
  1217 
  1201 
  1218 		if (RoadVehFindCloseTo(v,x,y,v->direction))
  1202 		if (RoadVehFindCloseTo(v,x,y,v->direction)) return;
  1219 			return;
       
  1220 
  1203 
  1221 		VehicleServiceInDepot(v);
  1204 		VehicleServiceInDepot(v);
  1222 
  1205 
  1223 		StartRoadVehSound(v);
  1206 		StartRoadVehSound(v);
  1224 
  1207 
  1234 
  1217 
  1235 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1218 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1236 		return;
  1219 		return;
  1237 	}
  1220 	}
  1238 
  1221 
  1239 	if (!RoadVehAccelerate(v))
  1222 	if (!RoadVehAccelerate(v)) return;
  1240 		return;
       
  1241 
  1223 
  1242 	if (v->u.road.overtaking != 0)  {
  1224 	if (v->u.road.overtaking != 0)  {
  1243 		if (++v->u.road.overtaking_ctr >= 35)
  1225 		if (++v->u.road.overtaking_ctr >= 35)
  1244 			/* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
  1226 			/* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
  1245 			 *  if the vehicle started a corner. To protect that, only allow an abort of
  1227 			 *  if the vehicle started a corner. To protect that, only allow an abort of
  1610 		RoadStopType type = (v->cargo_type == CT_PASSENGERS) ? RS_BUS : RS_TRUCK;
  1592 		RoadStopType type = (v->cargo_type == CT_PASSENGERS) ? RS_BUS : RS_TRUCK;
  1611 
  1593 
  1612 		st = GetStation(v->current_order.station);
  1594 		st = GetStation(v->current_order.station);
  1613 
  1595 
  1614 		//Current slot has expired
  1596 		//Current slot has expired
  1615 		if ( (v->u.road.slot_age++ <= 0) && (v->u.road.slot != NULL))
  1597 		if (v->u.road.slot_age++ <= 0 && v->u.road.slot != NULL) {
  1616 			ClearSlot(v, v->u.road.slot);
  1598 			ClearSlot(v, v->u.road.slot);
       
  1599 		}
  1617 
  1600 
  1618 		//We do not have a slot, so make one
  1601 		//We do not have a slot, so make one
  1619 		if (v->u.road.slot == NULL) {
  1602 		if (v->u.road.slot == NULL) {
  1620 			RoadStop *rs = GetPrimaryRoadStop(st, type);
  1603 			RoadStop *rs = GetPrimaryRoadStop(st, type);
  1621 			RoadStop *first_stop = rs;
  1604 			RoadStop *first_stop = rs;
  1622 			RoadStop *best_stop = NULL;
  1605 			RoadStop *best_stop = NULL;
  1623 			uint32 mindist = 12, dist; // 12 is threshold distance.
  1606 			uint32 mindist = 12, dist; // 12 is threshold distance.
  1624 
  1607 
  1625 		//first we need to find out how far our stations are away.
  1608 		//first we need to find out how far our stations are away.
  1626 			DEBUG(ms, 2) ("Multistop: Attempting to obtain a slot for vehicle %d at station %d (0x%x)", v->unitnumber, st->index, st->xy);
  1609 			DEBUG(ms, 2) ("Multistop: Attempting to obtain a slot for vehicle %d at station %d (0x%x)", v->unitnumber, st->index, st->xy);
  1627 			for(; rs != NULL; rs = rs->next) {
  1610 			for (; rs != NULL; rs = rs->next) {
  1628 				// Only consider those with at least a free slot.
  1611 				// Only consider those with at least a free slot.
  1629 				if (!(rs->slot[0] == INVALID_SLOT || rs->slot[1] == INVALID_SLOT))
  1612 				if (!(rs->slot[0] == INVALID_SLOT || rs->slot[1] == INVALID_SLOT))
  1630 					continue;
  1613 					continue;
  1631 
  1614 
  1632 				// Previously the NPF pathfinder was used here even if NPF is OFF.. WTF?
  1615 				// Previously the NPF pathfinder was used here even if NPF is OFF.. WTF?
  1633 				assert(NUM_SLOTS == 2);
  1616 				assert(NUM_SLOTS == 2);
  1634 				dist = DistanceManhattan(v->tile, rs->xy);
  1617 				dist = DistanceManhattan(v->tile, rs->xy);
  1635 
  1618 
  1636 				// Check if the station is located BEHIND the vehicle..
  1619 				// Check if the station is located BEHIND the vehicle..
  1637 				// In that case, add penalty.
  1620 				// In that case, add penalty.
  1638 				switch(v->direction) {
  1621 				switch (v->direction) {
  1639 				case 1: // going north east,x position decreasing
  1622 					case 1: // going north east,x position decreasing
  1640 					if (v->x_pos <= (int32)TileX(rs->xy) * 16 + 15)
  1623 						if (v->x_pos <= (int32)TileX(rs->xy) * 16 + 15) dist += 6;
  1641 						dist += 6;
  1624 						break;
  1642 					break;
  1625 					case 3: // Going south east, y position increasing
  1643 				case 3: // Going south east, y position increasing
  1626 						if (v->y_pos >= (int32)TileY(rs->xy) * 16) dist += 6;
  1644 					if (v->y_pos >= (int32)TileY(rs->xy) * 16)
  1627 						break;
  1645 						dist += 6;
  1628 					case 5: // Going south west, x position increasing
  1646 					break;
  1629 						if (v->x_pos >= (int32)TileX(rs->xy) * 16) dist += 6;
  1647 				case 5: // Going south west, x position increasing
  1630 						break;
  1648 					if (v->x_pos >= (int32)TileX(rs->xy) * 16)
  1631 					case 7: // Going north west, y position decrasing.
  1649 						dist += 6;
  1632 						if (v->y_pos <= (int32)TileY(rs->xy) * 16 + 15) dist += 6;
  1650 					break;
  1633 						break;
  1651 				case 7: // Going north west, y position decrasing.
       
  1652 					if (v->y_pos <= (int32)TileY(rs->xy) * 16 + 15)
       
  1653 						dist += 6;
       
  1654 					break;
       
  1655 				}
  1634 				}
  1656 
  1635 
  1657 				// Remember the one with the shortest distance
  1636 				// Remember the one with the shortest distance
  1658 				if (dist < mindist) {
  1637 				if (dist < mindist) {
  1659 					mindist = dist;
  1638 					mindist = dist;