Changeset - r13923:097b41840d11
[Not reviewed]
master
0 3 0
rubidium - 14 years ago 2009-12-11 22:04:57
rubidium@openttd.org
(svn r18465) -Codechange: simplify CheckTrainInDepot and remove some unneeded wrapper functions
3 files changed with 13 insertions and 26 deletions:
0 comments (0 inline, 0 general)
src/train.h
Show inline comments
 
@@ -41,25 +41,24 @@ enum VehicleRailFlags {
 
	VRF_TOGGLE_REVERSE = 7,
 

	
 
	/* used to mark a train that can't get a path reservation */
 
	VRF_TRAIN_STUCK    = 8,
 
};
 

	
 
void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2);
 
void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2);
 

	
 
byte FreightWagonMult(CargoID cargo);
 

	
 
int CheckTrainInDepot(const Train *v, bool needs_to_be_stopped);
 
int CheckTrainStoppedInDepot(const Train *v);
 
void UpdateTrainAcceleration(Train *v);
 
void CheckTrainsLengths();
 

	
 
void FreeTrainTrackReservation(const Train *v, TileIndex origin = INVALID_TILE, Trackdir orig_td = INVALID_TRACKDIR);
 
bool TryPathReserve(Train *v, bool mark_as_stuck = false, bool first_tile_okay = false);
 

	
 
int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, int *station_ahead, int *station_length);
 

	
 
void TrainConsistChanged(Train *v, bool same_length);
 
void TrainPowerChanged(Train *v);
 
int GetTrainCurveSpeedLimit(Train *v);
 
Money GetTrainRunningCost(const Train *v);
 
@@ -124,25 +123,25 @@ struct Train : public SpecializedVehicle
 
	const char *GetTypeString() const { return "train"; }
 
	void MarkDirty();
 
	void UpdateDeltaXY(Direction direction);
 
	ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_TRAIN_INC : EXPENSES_TRAIN_RUN; }
 
	void PlayLeaveStationSound() const;
 
	bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
 
	SpriteID GetImage(Direction direction) const;
 
	int GetDisplaySpeed() const { return this->tcache.last_speed; }
 
	int GetDisplayMaxSpeed() const { return this->tcache.cached_max_speed; }
 
	Money GetRunningCost() const;
 
	int GetDisplayImageWidth(Point *offset = NULL) const;
 
	bool IsInDepot() const { return CheckTrainInDepot(this, false) != -1; }
 
	bool IsStoppedInDepot() const { return CheckTrainStoppedInDepot(this) >= 0; }
 
	bool IsStoppedInDepot() const { return CheckTrainInDepot(this, true) != -1; }
 
	bool Tick();
 
	void OnNewDay();
 
	uint Crash(bool flooded = false);
 
	Trackdir GetVehicleTrackdir() const;
 
	TileIndex GetOrderStationLocation(StationID station);
 
	bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
 

	
 
	void ReserveTrackUnderConsist() const;
 

	
 
	/**
 
	 * enum to handle train subtypes
 
	 * Do not access it directly unless you have to. Use the access functions below
src/train_cmd.cpp
Show inline comments
 
@@ -957,55 +957,43 @@ CommandCost CmdBuildRailVehicle(TileInde
 

	
 
	return value;
 
}
 

	
 

	
 
/* Check if all the wagons of the given train are in a depot, returns the
 
 * number of cars (including loco) then. If not it returns -1 */
 
int CheckTrainInDepot(const Train *v, bool needs_to_be_stopped)
 
{
 
	TileIndex tile = v->tile;
 

	
 
	/* check if stopped in a depot */
 
	if (!IsRailDepotTile(tile) || v->cur_speed != 0) return -1;
 
	if (!IsRailDepotTile(tile) || v->cur_speed != 0 ||
 
			(needs_to_be_stopped && v->IsFrontEngine() && !(v->vehstatus & VS_STOPPED))) {
 
		return -1;
 
	}
 

	
 
	int count = 0;
 
	for (; v != NULL; v = v->Next()) {
 
		/* This count is used by the depot code to determine the number of engines
 
		 * in the consist. Exclude articulated parts so that autoreplacing to
 
		 * engines with more articulated parts than before works correctly.
 
		 *
 
		 * Also skip counting rear ends of multiheaded engines */
 
		if (!v->IsArticulatedPart() && !v->IsRearDualheaded()) count++;
 
		if (v->track != TRACK_BIT_DEPOT || v->tile != tile ||
 
				(v->IsFrontEngine() && needs_to_be_stopped && !(v->vehstatus & VS_STOPPED))) {
 
			return -1;
 
		}
 
		if (v->track != TRACK_BIT_DEPOT || v->tile != tile) return -1;
 
	}
 

	
 
	return count;
 
}
 

	
 
/* Used to check if the train is inside the depot and verifying that the VS_STOPPED flag is set */
 
int CheckTrainStoppedInDepot(const Train *v)
 
{
 
	return CheckTrainInDepot(v, true);
 
}
 

	
 
/* Used to check if the train is inside the depot, but not checking the VS_STOPPED flag */
 
inline bool CheckTrainIsInsideDepot(const Train *v)
 
{
 
	return CheckTrainInDepot(v, false) > 0;
 
}
 

	
 
/**
 
 * Unlink a rail wagon from the consist.
 
 * @param v Vehicle to remove.
 
 * @param first The first vehicle of the consist.
 
 * @return The first vehicle of the consist.
 
 */
 
static Train *UnlinkWagon(Train *v, Train *first)
 
{
 
	/* unlinking the first vehicle of the chain? */
 
	if (v == first) {
 
		v = v->GetNextVehicle();
 
		if (v == NULL) return NULL;
 
@@ -1083,29 +1071,29 @@ static void NormaliseTrainConsist(Train 
 

	
 
/**
 
 * Check/validate the new train length
 
 * @param dst_head   The destination chain of the to be moved vehicle
 
 * @param src_head   The source chain of the to be moved vehicle
 
 * @param src        The to be moved vehicle
 
 * @param move_chain Whether to move all vehicles after src or not
 
 * @return possible error of this command.
 
 */
 
static CommandCost CheckNewTrainLength(const Train *dst_head, const Train *src_head, const Train *src, bool move_chain)
 
{
 
	/* Check if all vehicles in the source train are stopped inside a depot. */
 
	int src_len = CheckTrainStoppedInDepot(src_head);
 
	int src_len = CheckTrainInDepot(src_head, true);
 
	if (src_len < 0) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
 

	
 
	/* Check if all vehicles in the destination train are stopped inside a depot. */
 
	int dst_len = dst_head != NULL ? CheckTrainStoppedInDepot(dst_head) : 0;
 
	int dst_len = dst_head != NULL ? CheckTrainInDepot(dst_head, true) : 0;
 
	if (dst_len < 0) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
 

	
 
	/* Determine the maximum length of trains. */
 
	int max_len = _settings_game.vehicle.mammoth_trains ? 100 : 10;
 

	
 
	/* If the length of both the source and destination combined is
 
	 * within the maximum length for trains there is no need for any
 
	 * complex calculations. All and any combination of vehicles
 
	 * will be within the required lengths. */
 
	if (src_len + dst_len <= max_len) return CommandCost();
 

	
 
	if (!move_chain && !src_head->IsFrontEngine() && src_head == src &&
 
@@ -1128,25 +1116,25 @@ static CommandCost CheckNewTrainLength(c
 
	 * chain or we are going to add vehicles to a free wagon chain.
 
	 * That chain does not have a limitation on its length.
 
	 * NOTE that this cannot be done earlier in case the first vehicle
 
	 * is removed from a free wagon chain and the second is an engine;
 
	 * the new train in the source chain needs to be checked. */
 
	if (dst_head == NULL ? !src->IsEngine() : !dst_head->IsFrontEngine()) {
 
		return CommandCost();
 
	}
 

	
 
	/* We are moving between rows, so only count the wagons from the source
 
	 * row that are being moved. */
 
	if (move_chain) {
 
		/* CheckTrainStoppedInDepot() counts units. */
 
		/* CheckTrainInDepot() counts units. */
 
		for (const Train *u = src_head; u != src && u != NULL; u = u->GetNextUnit()) src_len--;
 
	} else {
 
		/* If moving only one vehicle, just count that. */
 
		src_len = 1;
 
	}
 

	
 
	if (src_len + dst_len > max_len) return_cmd_error(STR_ERROR_TRAIN_TOO_LONG);
 
	return CommandCost();
 
}
 

	
 
/**
 
 * Check/validate whether we may actually build a new train
 
@@ -1535,25 +1523,25 @@ CommandCost CmdSellRailWagon(TileIndex t
 
	Window *w = NULL;
 

	
 
	Train *v = Train::GetIfValid(p1);
 
	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
 
	if (p2 > 1) return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_CAN_T_SELL_DESTROYED_VEHICLE);
 

	
 
	v = v->GetFirstEnginePart();
 
	Train *first = v->First();
 

	
 
	/* make sure the vehicle is stopped in the depot */
 
	if (CheckTrainStoppedInDepot(first) < 0) {
 
	if (!first->IsStoppedInDepot()) {
 
		return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
 
	}
 

	
 
	if (v->IsRearDualheaded()) return_cmd_error(STR_ERROR_REAR_ENGINE_FOLLOW_FRONT);
 

	
 
	if (flags & DC_EXEC) {
 
		if (v == first && first->IsFrontEngine()) {
 
			DeleteWindowById(WC_VEHICLE_VIEW, first->index);
 
			DeleteWindowById(WC_VEHICLE_ORDERS, first->index);
 
			DeleteWindowById(WC_VEHICLE_REFIT, first->index);
 
			DeleteWindowById(WC_VEHICLE_DETAILS, first->index);
 
			DeleteWindowById(WC_VEHICLE_TIMETABLE, first->index);
 
@@ -2093,25 +2081,25 @@ CommandCost CmdReverseTrainDirection(Til
 
	Train *v = Train::GetIfValid(p1);
 
	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (p2 != 0) {
 
		/* turn a single unit around */
 

	
 
		if (v->IsMultiheaded() || HasBit(EngInfo(v->engine_type)->callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) {
 
			return_cmd_error(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE_MULTIPLE_UNITS);
 
		}
 

	
 
		Train *front = v->First();
 
		/* make sure the vehicle is stopped in the depot */
 
		if (CheckTrainStoppedInDepot(front) < 0) {
 
		if (!front->IsStoppedInDepot()) {
 
			return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
 
		}
 

	
 
		if (flags & DC_EXEC) {
 
			ToggleBit(v->flags, VRF_REVERSE_DIRECTION);
 
			SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
			SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
		}
 
	} else {
 
		/* turn the whole train around */
 
		if ((v->vehstatus & VS_CRASHED) || v->breakdown_ctr != 0) return CMD_ERROR;
 

	
 
@@ -2169,25 +2157,25 @@ CommandCost CmdForceTrainProceed(TileInd
 
 * @param text unused
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdRefitRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	CargoID new_cid = GB(p2, 0, 8);
 
	byte new_subtype = GB(p2, 8, 8);
 
	bool only_this = HasBit(p2, 16);
 

	
 
	Train *v = Train::GetIfValid(p1);
 
	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
 
	if (!v->IsStoppedInDepot()) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
 
	if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_CAN_T_REFIT_DESTROYED_VEHICLE);
 

	
 
	/* Check cargo */
 
	if (new_cid >= NUM_CARGO) return CMD_ERROR;
 

	
 
	CommandCost cost = RefitVehicle(v, only_this, new_cid, new_subtype, flags);
 

	
 
	/* Update the train's cached variables */
 
	if (flags & DC_EXEC) {
 
		Train *front = v->First();
 
		TrainConsistChanged(front, false);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, front->index);
src/vehicle_cmd.cpp
Show inline comments
 
@@ -143,25 +143,25 @@ CommandCost CmdMassStartStopVehicle(Tile
 
	} else {
 
		/* Get the list of vehicles in the depot */
 
		BuildDepotVehicleList(vehicle_type, tile, &list, NULL);
 
	}
 

	
 
	for (uint i = 0; i < list.Length(); i++) {
 
		const Vehicle *v = list[i];
 

	
 
		if (!!(v->vehstatus & VS_STOPPED) != start_stop) continue;
 

	
 
		if (!vehicle_list_window) {
 
			if (vehicle_type == VEH_TRAIN) {
 
				if (CheckTrainInDepot(Train::From(v), false) == -1) continue;
 
				if (!Train::From(v)->IsInDepot()) continue;
 
			} else {
 
				if (!(v->vehstatus & VS_HIDDEN)) continue;
 
			}
 
		}
 

	
 
		CommandCost ret = DoCommand(tile, v->index, 0, flags, CMD_START_STOP_VEHICLE);
 

	
 
		if (CmdSucceeded(ret)) {
 
			return_value = CommandCost();
 
			/* We know that the command is valid for at least one vehicle.
 
			 * If we haven't set DC_EXEC, then there is no point in continueing because it will be valid */
 
			if (!(flags & DC_EXEC)) break;
0 comments (0 inline, 0 general)