Changeset - r8919:cac9f783953d
[Not reviewed]
master
0 5 0
rubidium - 16 years ago 2008-04-13 16:54:19
rubidium@openttd.org
(svn r12689) -Feature: non-stop(or rather no non-stop) and via orders for road vehicles.
5 files changed with 29 insertions and 14 deletions:
0 comments (0 inline, 0 general)
src/openttd.cpp
Show inline comments
 
@@ -2442,25 +2442,30 @@ bool AfterLoadGame()
 
			if (IsTileType(t, MP_HOUSE) && GetHouseType(t) >= NEW_HOUSE_OFFSET) {
 
				SetHouseAnimationFrame(t, GB(_m[t].m6, 3, 5));
 
			}
 
		}
 
	}
 

	
 
	if (CheckSavegameVersion(93)) {
 
		/* Rework of orders. */
 
		Order *order;
 
		FOR_ALL_ORDERS(order) order->ConvertFromOldSavegame();
 

	
 
		Vehicle *v;
 
		FOR_ALL_VEHICLES(v) v->current_order.ConvertFromOldSavegame();
 
		FOR_ALL_VEHICLES(v) {
 
			v->current_order.ConvertFromOldSavegame();
 
			if (v->type == VEH_ROAD && v->IsPrimaryVehicle() && v->prev_shared == NULL) {
 
				FOR_VEHICLE_ORDERS(v, order) order->SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 
			}
 
		}
 
	} else if (CheckSavegameVersion(94)) {
 
		/* Unload and transfer are now mutual exclusive. */
 
		Order *order;
 
		FOR_ALL_ORDERS(order) {
 
			if ((order->GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) {
 
				order->SetUnloadType(OUFB_TRANSFER);
 
				order->SetLoadType(OLFB_NO_LOAD);
 
			}
 
		}
 

	
 
		Vehicle *v;
 
		FOR_ALL_VEHICLES(v) {
src/order_cmd.cpp
Show inline comments
 
@@ -349,25 +349,25 @@ CommandCost CmdInsertOrder(TileIndex til
 
					break;
 

	
 
				case VEH_AIRCRAFT:
 
					if (!(st->facilities & FACIL_AIRPORT) || !CanAircraftUseStation(v->engine_type, st)) {
 
						return CMD_ERROR;
 
					}
 
					break;
 

	
 
				default: return CMD_ERROR;
 
			}
 

	
 
			/* Non stop not allowed for non-trains. */
 
			if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN) return CMD_ERROR;
 
			if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN && v->type != VEH_ROAD) return CMD_ERROR;
 

	
 
			/* Full load and unload are mutual exclusive. */
 
			if ((new_order.GetLoadType() & OLFB_FULL_LOAD) && (new_order.GetUnloadType() & OUFB_UNLOAD)) return CMD_ERROR;
 

	
 
			/* Filter invalid load/unload types. */
 
			switch (new_order.GetLoadType()) {
 
				case OLF_LOAD_IF_POSSIBLE: case OLFB_FULL_LOAD: case OLF_FULL_LOAD_ANY: break;
 
				default: return CMD_ERROR;
 
			}
 
			if (new_order.GetUnloadType() & ~(OUFB_UNLOAD | OUFB_TRANSFER)) return CMD_ERROR;
 
			break;
 
		}
 
@@ -403,25 +403,25 @@ CommandCost CmdInsertOrder(TileIndex til
 

	
 
						case VEH_SHIP:
 
							if (!IsTileDepotType(dp->xy, TRANSPORT_WATER)) return CMD_ERROR;
 
							break;
 

	
 
						default: return CMD_ERROR;
 
					}
 
				}
 
			} else {
 
				if (!IsPlayerBuildableVehicleType(v)) return CMD_ERROR;
 
			}
 

	
 
			if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN) return CMD_ERROR;
 
			if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN && v->type != VEH_ROAD) return CMD_ERROR;
 
			if (new_order.GetDepotOrderType() & ~ODTFB_PART_OF_ORDERS) return CMD_ERROR;
 
			if (new_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT) return CMD_ERROR;
 
			break;
 
		}
 

	
 
		case OT_GOTO_WAYPOINT: {
 

	
 
			if (v->type != VEH_TRAIN) return CMD_ERROR;
 

	
 
			if (!IsValidWaypointID(new_order.GetDestination())) return CMD_ERROR;
 
			const Waypoint *wp = GetWaypoint(new_order.GetDestination());
 

	
 
@@ -860,24 +860,25 @@ CommandCost CmdModifyOrder(TileIndex til
 
		case OT_CONDITIONAL:
 
			if (mof != MOF_COND_VARIABLE && mof != MOF_COND_COMPARATOR && mof != MOF_COND_VALUE) return CMD_ERROR;
 
			break;
 

	
 
		default:
 
			return CMD_ERROR;
 
	}
 

	
 
	switch (mof) {
 
		default: NOT_REACHED();
 

	
 
		case MOF_NON_STOP:
 
			if (v->type != VEH_TRAIN && v->type != VEH_ROAD) return CMD_ERROR;
 
			if (data >= ONSF_END) return CMD_ERROR;
 
			if (data == order->GetNonStopType()) return CMD_ERROR;
 
			break;
 

	
 
		case MOF_UNLOAD:
 
			if ((data & ~(OUFB_UNLOAD | OUFB_TRANSFER | OUFB_NO_UNLOAD)) != 0) return CMD_ERROR;
 
			/* Unload and no-unload are mutual exclusive and so are transfer and no unload. */
 
			if (data != 0 && ((data & (OUFB_UNLOAD | OUFB_TRANSFER)) != 0) == ((data & OUFB_NO_UNLOAD) != 0)) return CMD_ERROR;
 
			if (data == order->GetUnloadType()) return CMD_ERROR;
 
			break;
 

	
 
		case MOF_LOAD:
src/order_gui.cpp
Show inline comments
 
@@ -228,25 +228,25 @@ static void DrawOrdersWindow(Window *w)
 
		w->widget[ORDER_WIDGET_UNLOAD].data          = _order_unload_drowdown[order == NULL ? 0 : order->GetUnloadType()];
 
		w->widget[ORDER_WIDGET_COND_VARIABLE].data   = _order_conditional_variable[order == NULL ? 0 : order->GetConditionVariable()];
 
		w->widget[ORDER_WIDGET_COND_COMPARATOR].data = _order_conditional_condition[order == NULL ? 0 : order->GetConditionComparator()];
 

	
 
		/* skip */
 
		w->SetWidgetDisabledState(ORDER_WIDGET_SKIP, v->num_orders <= 1);
 

	
 
		/* delete */
 
		w->SetWidgetDisabledState(ORDER_WIDGET_DELETE,
 
				(uint)v->num_orders + ((shared_orders || v->num_orders != 0) ? 1 : 0) <= (uint)WP(w, order_d).sel);
 

	
 
		/* non-stop only for trains */
 
		w->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP,  v->type != VEH_TRAIN || order == NULL);
 
		w->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP,  (v->type != VEH_TRAIN && v->type != VEH_ROAD) || order == NULL);
 
		w->SetWidgetDisabledState(ORDER_WIDGET_FULL_LOAD, order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // full load
 
		w->SetWidgetDisabledState(ORDER_WIDGET_UNLOAD,    order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // unload
 
		/* Disable list of vehicles with the same shared orders if there is no list */
 
		w->SetWidgetDisabledState(ORDER_WIDGET_SHARED_ORDER_LIST, !shared_orders || v->orders == NULL);
 
		w->SetWidgetDisabledState(ORDER_WIDGET_REFIT,     order == NULL); // Refit
 
		w->SetWidgetDisabledState(ORDER_WIDGET_SERVICE,   order == NULL); // Refit
 
		w->HideWidget(ORDER_WIDGET_REFIT); // Refit
 
		w->HideWidget(ORDER_WIDGET_SERVICE); // Service
 

	
 
		w->HideWidget(ORDER_WIDGET_COND_VARIABLE);
 
		w->HideWidget(ORDER_WIDGET_COND_COMPARATOR);
 
		w->HideWidget(ORDER_WIDGET_COND_VALUE);
 
@@ -316,25 +316,25 @@ static void DrawOrdersWindow(Window *w)
 
		if (i - w->vscroll.pos < w->vscroll.cap) {
 
			switch (order->GetType()) {
 
				case OT_DUMMY:
 
					SetDParam(1, STR_INVALID_ORDER);
 
					SetDParam(2, order->GetDestination());
 
					break;
 

	
 
				case OT_GOTO_STATION: {
 
					OrderLoadFlags load = order->GetLoadType();
 
					OrderUnloadFlags unload = order->GetUnloadType();
 

	
 
					SetDParam(1, STR_GO_TO_STATION);
 
					SetDParam(2, STR_ORDER_GO_TO + (v->type == VEH_TRAIN ? order->GetNonStopType() : 0));
 
					SetDParam(2, STR_ORDER_GO_TO + ((v->type == VEH_TRAIN || v->type == VEH_ROAD) ? order->GetNonStopType() : 0));
 
					SetDParam(3, order->GetDestination());
 
					SetDParam(4, (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) ? STR_EMPTY : _station_load_types[unload][load]);
 
				} break;
 

	
 
				case OT_GOTO_DEPOT:
 
					if (v->type == VEH_AIRCRAFT) {
 
						if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
 
							SetDParam(1, STR_GO_TO_NEAREST_DEPOT);
 
							SetDParam(3, STR_ORDER_NEAREST_HANGAR);
 
						} else {
 
							SetDParam(1, STR_GO_TO_HANGAR);
 
							SetDParam(3, order->GetDestination());
 
@@ -422,24 +422,25 @@ static Order GetOrderCmdFromTile(const V
 
				if (v->type == VEH_TRAIN && IsTileOwner(tile, _local_player)) {
 
					if (IsRailDepot(tile)) {
 
						order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS);
 
						if (_patches.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 
						return order;
 
					}
 
				}
 
				break;
 

	
 
			case MP_ROAD:
 
				if (IsRoadDepot(tile) && v->type == VEH_ROAD && IsTileOwner(tile, _local_player)) {
 
					order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS);
 
					if (_patches.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 
					return order;
 
				}
 
				break;
 

	
 
			case MP_STATION:
 
				if (v->type != VEH_AIRCRAFT) break;
 
				if (IsHangar(tile) && IsTileOwner(tile, _local_player)) {
 
					order.MakeGoToDepot(GetStationIndex(tile), ODTFB_PART_OF_ORDERS);
 
					return order;
 
				}
 
				break;
 

	
 
@@ -472,25 +473,25 @@ static Order GetOrderCmdFromTile(const V
 
		StationID st_index = GetStationIndex(tile);
 
		const Station *st = GetStation(st_index);
 

	
 
		if (st->owner == _current_player || st->owner == OWNER_NONE) {
 
			byte facil;
 
			(facil = FACIL_DOCK, v->type == VEH_SHIP) ||
 
			(facil = FACIL_TRAIN, v->type == VEH_TRAIN) ||
 
			(facil = FACIL_AIRPORT, v->type == VEH_AIRCRAFT) ||
 
			(facil = FACIL_BUS_STOP, v->type == VEH_ROAD && IsCargoInClass(v->cargo_type, CC_PASSENGERS)) ||
 
			(facil = FACIL_TRUCK_STOP, 1);
 
			if (st->facilities & facil) {
 
				order.MakeGoToStation(st_index);
 
				if (_patches.new_nonstop && v->type == VEH_TRAIN) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 
				if (_patches.new_nonstop && (v->type == VEH_TRAIN || v->type == VEH_ROAD)) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 
				return order;
 
			}
 
		}
 
	}
 

	
 
	/* not found */
 
	order.Free();
 
	return order;
 
}
 

	
 
static bool HandleOrderVehClick(const Vehicle *v, const Vehicle *u, Window *w)
 
{
 
@@ -1160,22 +1161,22 @@ static const WindowDesc _other_orders_de
 

	
 
void ShowOrdersWindow(const Vehicle *v)
 
{
 
	Window *w;
 
	VehicleID veh = v->index;
 

	
 
	DeleteWindowById(WC_VEHICLE_ORDERS, veh);
 
	DeleteWindowById(WC_VEHICLE_DETAILS, veh);
 

	
 
	if (v->owner != _local_player) {
 
		w = AllocateWindowDescFront(&_other_orders_desc, veh);
 
	} else {
 
		w = AllocateWindowDescFront((v->type == VEH_TRAIN) ? &_orders_train_desc : &_orders_desc, veh);
 
		w = AllocateWindowDescFront((v->type == VEH_TRAIN || v->type == VEH_ROAD) ? &_orders_train_desc : &_orders_desc, veh);
 
	}
 

	
 
	if (w != NULL) {
 
		w->caption_color = v->owner;
 
		w->vscroll.cap = 6;
 
		w->resize.step_height = 10;
 
		WP(w, order_d).sel = -1;
 
	}
 
}
src/roadveh_cmd.cpp
Show inline comments
 
@@ -1699,36 +1699,35 @@ again:
 
			return true;
 
		}
 
	}
 

	
 
	/* If the vehicle is in a normal road stop and the frame equals the stop frame OR
 
	 * if the vehicle is in a drive-through road stop and this is the destination station
 
	 * and it's the correct type of stop (bus or truck) and the frame equals the stop frame...
 
	 * (the station test and stop type test ensure that other vehicles, using the road stop as
 
	 * a through route, do not stop) */
 
	if (IsRoadVehFront(v) && ((IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
 
			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
 
			(IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
 
			v->current_order.GetDestination() == GetStationIndex(v->tile) &&
 
			v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
 
			GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
 
			v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) {
 

	
 
		RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
 
		Station* st = GetStationByTile(v->tile);
 

	
 
		/* Vehicle is at the stop position (at a bay) in a road stop.
 
		 * Note, if vehicle is loading/unloading it has already been handled,
 
		 * so if we get here the vehicle has just arrived or is just ready to leave. */
 
		if (!v->current_order.IsType(OT_LEAVESTATION) &&
 
				!v->current_order.IsType(OT_GOTO_DEPOT)) {
 
		if (!v->current_order.IsType(OT_LEAVESTATION)) {
 
			/* Vehicle has arrived at a bay in a road stop */
 

	
 
			if (IsDriveThroughStopTile(v->tile)) {
 
				TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction));
 
				RoadStopType type = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK;
 

	
 
				/* Check if next inline bay is free */
 
				if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) {
 
					RoadStop *rs_n = GetRoadStopByTile(next_tile, type);
 

	
 
					if (rs_n->IsFreeBay(HasBit(v->u.road.state, RVS_USING_SECOND_BAY))) {
 
						/* Bay in next stop along is free - use it */
 
@@ -1738,28 +1737,33 @@ again:
 
						v->dest_tile = rs_n->xy;
 
						v->u.road.slot_age = 14;
 

	
 
						v->u.road.frame++;
 
						RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
 
						return true;
 
					}
 
				}
 
			}
 

	
 
			rs->SetEntranceBusy(false);
 

	
 
			v->last_station_visited = GetStationIndex(v->tile);
 
			v->last_station_visited = st->index;
 

	
 
			RoadVehArrivesAt(v, st);
 
			v->BeginLoading();
 
			if (IsDriveThroughStopTile(v->tile) || v->current_order.GetDestination() == st->index) {
 
				RoadVehArrivesAt(v, st);
 
				v->BeginLoading();
 
			} else {
 
				v->current_order.MakeLeaveStation();
 
				InvalidateVehicleOrder(v);
 
			}
 

	
 
			return false;
 
		}
 

	
 
		/* Vehicle is ready to leave a bay in a road stop */
 
		if (!v->current_order.IsType(OT_GOTO_DEPOT)) {
 
			if (rs->IsEntranceBusy()) {
 
				/* Road stop entrance is busy, so wait as there is nowhere else to go */
 
				v->cur_speed = 0;
 
				return false;
 
			}
 
			v->current_order.Free();
 
@@ -1797,24 +1801,26 @@ again:
 
		StartRoadVehSound(v);
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 

	
 
	/* Check tile position conditions - i.e. stop position in depot,
 
	 * entry onto bridge or into tunnel */
 
	r = VehicleEnterTile(v, v->tile, x, y);
 
	if (HasBit(r, VETS_CANNOT_ENTER)) {
 
		v->cur_speed = 0;
 
		return false;
 
	}
 

	
 
	if (v->current_order.IsType(OT_LEAVESTATION) && IsDriveThroughStopTile(v->tile)) v->current_order.Free();
 

	
 
	/* Move to next frame unless vehicle arrived at a stop position
 
	 * in a depot or entered a tunnel/bridge */
 
	if (!HasBit(r, VETS_ENTERED_WORMHOLE)) v->u.road.frame++;
 

	
 
	v->cur_image = v->GetImage(v->direction);
 
	v->UpdateDeltaXY(v->direction);
 
	RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
 
	return true;
 
}
 

	
 
static void RoadVehController(Vehicle *v)
 
{
src/station_cmd.cpp
Show inline comments
 
@@ -2397,27 +2397,27 @@ static void ClickTile_Station(TileIndex 
 
	} else {
 
		ShowStationViewWindow(GetStationIndex(tile));
 
	}
 
}
 

	
 
static const byte _enter_station_speedtable[12] = {
 
	215, 195, 175, 155, 135, 115, 95, 75, 55, 35, 15, 0
 
};
 

	
 
static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y)
 
{
 
	StationID station_id = GetStationIndex(tile);
 
	if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE;
 

	
 
	if (v->type == VEH_TRAIN) {
 
		if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE;
 
		if (IsRailwayStation(tile) && IsFrontEngine(v) &&
 
				!IsCompatibleTrainStationTile(tile + TileOffsByDiagDir(DirToDiagDir(v->direction)), tile)) {
 
			DiagDirection dir = DirToDiagDir(v->direction);
 

	
 
			x &= 0xF;
 
			y &= 0xF;
 

	
 
			if (DiagDirToAxis(dir) != AXIS_X) Swap(x, y);
 
			if (y == TILE_SIZE / 2) {
 
				if (dir != DIAGDIR_SE && dir != DIAGDIR_SW) x = TILE_SIZE - 1 - x;
 
				if (x == 12) return VETSB_ENTERED_STATION | (VehicleEnterTileStatus)(station_id << VETS_STATION_ID_OFFSET); /* enter station */
 
				if (x < 12) {
 
@@ -2427,24 +2427,26 @@ static VehicleEnterTileStatus VehicleEnt
 
					spd = _enter_station_speedtable[x];
 
					if (spd < v->cur_speed) v->cur_speed = spd;
 
				}
 
			}
 
		}
 
	} else if (v->type == VEH_ROAD) {
 
		if (v->u.road.state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)v->u.road.state) && v->u.road.frame == 0) {
 
			if (IsRoadStop(tile) && IsRoadVehFront(v)) {
 
				/* Attempt to allocate a parking bay in a road stop */
 
				RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
 

	
 
				if (IsDriveThroughStopTile(tile)) {
 
					if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE;
 

	
 
					/* Vehicles entering a drive-through stop from the 'normal' side use first bay (bay 0). */
 
					byte side = ((DirToDiagDir(v->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (v->u.road.overtaking == 0)) ? 0 : 1;
 

	
 
					if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER;
 

	
 
					/* Check if the vehicle is stopping at this road stop */
 
					if (GetRoadStopType(tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
 
							v->current_order.GetDestination() == GetStationIndex(tile)) {
 
						SetBit(v->u.road.state, RVS_IS_STOPPING);
 
						rs->AllocateDriveThroughBay(side);
 
					}
 

	
0 comments (0 inline, 0 general)