Changeset - r13849:0178a6ac1660
[Not reviewed]
master
0 6 0
rubidium - 14 years ago 2009-12-02 23:53:15
rubidium@openttd.org
(svn r18388) -Codechange: move entering/leaving of road stops to functions of RoadStop
6 files changed with 89 insertions and 82 deletions:
0 comments (0 inline, 0 general)
src/pathfinder/yapf/yapf_road.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file yapf_road.cpp The road pathfinding. */
 

	
 
#include "../../stdafx.h"
 
#include "../../roadstop_base.h"
 

	
 
#include "yapf.hpp"
 
#include "yapf_node_road.hpp"
 
#include "../../roadstop_base.h"
 

	
 

	
 
template <class Types>
 
class CYapfCostRoadT
 
{
 
public:
 
	typedef typename Types::Tpf Tpf; ///< pathfinder (derived from THIS class)
 
	typedef typename Types::TrackFollower TrackFollower; ///< track follower helper
 
	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
 
	typedef typename Node::Key Key;    ///< key to hash tables
 

	
 
protected:
src/roadstop.cpp
Show inline comments
 
@@ -38,24 +38,81 @@ RoadStop *RoadStop::GetNextRoadStop(cons
 
		if ((GetRoadTypes(rs->xy) & v->compatible_roadtypes) == ROADTYPES_NONE) continue;
 
		/* The vehicle is articulated and can therefor not go the a standard road stop */
 
		if (IsStandardRoadStopTile(rs->xy) && v->HasArticulatedPart()) continue;
 

	
 
		/* The vehicle can actually go to this road stop. So, return it! */
 
		return rs;
 
	}
 

	
 
	return NULL;
 
}
 

	
 
/**
 
 * Leave the road stop
 
 * @param rv the vehicle that leaves the stop
 
 */
 
void RoadStop::Leave(RoadVehicle *rv)
 
{
 
	/* Vehicle is leaving a road stop tile, mark bay as free
 
		* For drive-through stops, only do it if the vehicle stopped here */
 
	if (IsStandardRoadStopTile(rv->tile) || HasBit(rv->state, RVS_IS_STOPPING)) {
 
		this->FreeBay(HasBit(rv->state, RVS_USING_SECOND_BAY));
 
		ClrBit(rv->state, RVS_IS_STOPPING);
 
	}
 
	if (IsStandardRoadStopTile(rv->tile)) this->SetEntranceBusy(false);
 
}
 

	
 
/**
 
 * Enter the road stop
 
 * @param rv   the vehicle that enters the stop
 
 * @return whether the road stop could actually be entered
 
 */
 
bool RoadStop::Enter(RoadVehicle *rv)
 
{
 
	if (IsStandardRoadStopTile(this->xy)) {
 
		/* For normal (non drive-through) road stops
 
			* Check if station is busy or if there are no free bays or whether it is a articulated vehicle. */
 
		if (this->IsEntranceBusy() || !this->HasFreeBay() || rv->HasArticulatedPart()) return false;
 

	
 
		SetBit(rv->state, RVS_IN_ROAD_STOP);
 

	
 
		/* Allocate a bay and update the road state */
 
		uint bay_nr = this->AllocateBay();
 
		SB(rv->state, RVS_USING_SECOND_BAY, 1, bay_nr);
 

	
 
		/* Mark the station entrace as busy */
 
		this->SetEntranceBusy(true);
 
		return true;
 
	}
 

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

	
 
	if (!this->IsFreeBay(side)) return false;
 

	
 
	/* Check if the vehicle is stopping at this road stop */
 
	if (GetRoadStopType(this->xy) == (rv->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
 
			rv->current_order.ShouldStopAtStation(rv, GetStationIndex(this->xy))) {
 
		SetBit(rv->state, RVS_IS_STOPPING);
 
		this->AllocateDriveThroughBay(side);
 
	}
 

	
 
	/* Indicate if vehicle is using second bay. */
 
	if (side == 1) SetBit(rv->state, RVS_USING_SECOND_BAY);
 
	/* Indicate a drive-through stop */
 
	SetBit(rv->state, RVS_IN_DT_ROAD_STOP);
 
	return true;
 
}
 

	
 
/**
 
 * Find a roadstop at given tile
 
 * @param tile tile with roadstop
 
 * @param type roadstop type
 
 * @return pointer to RoadStop
 
 * @pre there has to be roadstop of given type there!
 
 */
 
/* static */ RoadStop *RoadStop::GetByTile(TileIndex tile, RoadStopType type)
 
{
 
	const Station *st = Station::GetByTile(tile);
 

	
 
	for (RoadStop *rs = st->GetPrimaryRoadStop(type);; rs = rs->next) {
 
		if (rs->xy == tile) return rs;
src/roadstop_base.h
Show inline comments
 
@@ -54,24 +54,50 @@ struct RoadStop : RoadStopPool::PoolItem
 
	/**
 
	 * Checks whether the given bay is free in this road stop
 
	 * @param nr bay to check
 
	 * @return is given bay free?
 
	 */
 
	FORCEINLINE bool IsFreeBay(uint nr) const
 
	{
 
		assert(nr < RSSFB_BAY_COUNT);
 
		return HasBit(this->status, nr);
 
	}
 

	
 
	/**
 
	 * Checks whether the entrance of the road stop is occupied by a vehicle
 
	 * @return is entrance busy?
 
	 */
 
	FORCEINLINE bool IsEntranceBusy() const
 
	{
 
		return HasBit(this->status, RSSFB_ENTRY_BUSY);
 
	}
 

	
 
	/**
 
	 * Makes an entrance occupied or free
 
	 * @param busy if true, marks busy; free otherwise
 
	 */
 
	FORCEINLINE void SetEntranceBusy(bool busy)
 
	{
 
		SB(this->status, RSSFB_ENTRY_BUSY, 1, busy);
 
	}
 

	
 
	void Leave(RoadVehicle *rv);
 
	bool Enter(RoadVehicle *rv);
 

	
 
	RoadStop *GetNextRoadStop(const struct RoadVehicle *v) const;
 

	
 
	static RoadStop *GetByTile(TileIndex tile, RoadStopType type);
 

	
 
private:
 
	/**
 
	 * Allocates a bay
 
	 * @return the allocated bay number
 
	 * @pre this->HasFreeBay()
 
	 */
 
	FORCEINLINE uint AllocateBay()
 
	{
 
		assert(this->HasFreeBay());
 

	
 
		/* Find the first free bay. If the bit is set, the bay is free. */
 
		uint bay_nr = 0;
 
		while (!HasBit(this->status, bay_nr)) bay_nr++;
 

	
 
@@ -89,41 +115,18 @@ struct RoadStop : RoadStopPool::PoolItem
 
		ClrBit(this->status, nr);
 
	}
 

	
 
	/**
 
	 * Frees the given bay
 
	 * @param nr the number of the bay to free
 
	 */
 
	FORCEINLINE void FreeBay(uint nr)
 
	{
 
		assert(nr < RSSFB_BAY_COUNT);
 
		SetBit(this->status, nr);
 
	}
 

	
 

	
 
	/**
 
	 * Checks whether the entrance of the road stop is occupied by a vehicle
 
	 * @return is entrance busy?
 
	 */
 
	FORCEINLINE bool IsEntranceBusy() const
 
	{
 
		return HasBit(this->status, RSSFB_ENTRY_BUSY);
 
	}
 

	
 
	/**
 
	 * Makes an entrance occupied or free
 
	 * @param busy if true, marks busy; free otherwise
 
	 */
 
	FORCEINLINE void SetEntranceBusy(bool busy)
 
	{
 
		SB(this->status, RSSFB_ENTRY_BUSY, 1, busy);
 
	}
 

	
 
	RoadStop *GetNextRoadStop(const struct RoadVehicle *v) const;
 

	
 
	static RoadStop *GetByTile(TileIndex tile, RoadStopType type);
 
};
 

	
 
#define FOR_ALL_ROADSTOPS_FROM(var, start) FOR_ALL_ITEMS_FROM(RoadStop, roadstop_index, var, start)
 
#define FOR_ALL_ROADSTOPS(var) FOR_ALL_ROADSTOPS_FROM(var, 0)
 

	
 
#endif /* ROADSTOP_BASE_H */
src/roadveh_cmd.cpp
Show inline comments
 
@@ -456,31 +456,25 @@ void RoadVehicle::UpdateDeltaXY(Directio
 
#undef MKIT
 

	
 
	uint32 x = _delta_xy_table[direction];
 
	this->x_offs        = GB(x,  0, 8);
 
	this->y_offs        = GB(x,  8, 8);
 
	this->x_extent      = GB(x, 16, 8);
 
	this->y_extent      = GB(x, 24, 8);
 
	this->z_extent      = 6;
 
}
 

	
 
static void ClearCrashedStation(RoadVehicle *v)
 
{
 
	RoadStop *rs = RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile));
 

	
 
	/* Mark the station entrance as not busy */
 
	rs->SetEntranceBusy(false);
 

	
 
	/* Free the parking bay */
 
	rs->FreeBay(HasBit(v->state, RVS_USING_SECOND_BAY));
 
	RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
 
}
 

	
 
static void DeleteLastRoadVeh(RoadVehicle *v)
 
{
 
	Vehicle *u = v;
 
	for (; v->Next() != NULL; v = v->Next()) u = v;
 
	u->SetNext(NULL);
 

	
 
	if (IsTileType(v->tile, MP_STATION)) ClearCrashedStation(v);
 

	
 
	delete v;
 
}
 
@@ -1308,35 +1302,25 @@ again:
 
			/* Try an about turn to re-enter the previous tile */
 
			dir = _road_reverse_table[rd.x & 3];
 
			goto again;
 
		}
 

	
 
		if (IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
 
			if (IsReversingRoadTrackdir(dir) && IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
 
				/* New direction is trying to turn vehicle around.
 
				 * We can't turn at the exit of a road stop so wait.*/
 
				v->cur_speed = 0;
 
				return false;
 
			}
 
			if (IsRoadStop(v->tile)) {
 
				RoadStop *rs = RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile));
 

	
 
				/* Vehicle is leaving a road stop tile, mark bay as free
 
				 * For drive-through stops, only do it if the vehicle stopped here */
 
				if (IsStandardRoadStopTile(v->tile) || HasBit(v->state, RVS_IS_STOPPING)) {
 
					rs->FreeBay(HasBit(v->state, RVS_USING_SECOND_BAY));
 
					ClrBit(v->state, RVS_IS_STOPPING);
 
				}
 
				if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(false);
 
			}
 
			if (IsRoadStop(v->tile)) RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
 
		}
 

	
 
		if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
 
			v->tile = tile;
 
			v->state = (byte)dir;
 
			v->frame = start_frame;
 
		}
 
		if (new_dir != v->direction) {
 
			v->direction = new_dir;
 
			v->cur_speed -= v->cur_speed >> 2;
 
		}
 

	
src/saveload/afterload.cpp
Show inline comments
 
@@ -3,45 +3,45 @@
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file afterload.cpp Code updating data after game load */
 

	
 
#include "../stdafx.h"
 
#include "../void_map.h"
 
#include "../signs_base.h"
 
#include "../roadstop_base.h"
 
#include "../depot_base.h"
 
#include "../window_func.h"
 
#include "../fios.h"
 
#include "../gamelog.h"
 
#include "../gamelog_internal.h"
 
#include "../network/network.h"
 
#include "../gfxinit.h"
 
#include "../functions.h"
 
#include "../industry.h"
 
#include "../clear_map.h"
 
#include "../vehicle_func.h"
 
#include "../newgrf_station.h"
 
#include "../openttd.h"
 
#include "../debug.h"
 
#include "../string_func.h"
 
#include "../date_func.h"
 
#include "../roadveh.h"
 
#include "../train.h"
 
#include "../station_base.h"
 
#include "../waypoint_base.h"
 
#include "../roadstop_base.h"
 
#include "../tunnelbridge_map.h"
 
#include "../landscape.h"
 
#include "../pathfinder/yapf/yapf_cache.h"
 
#include "../elrail_func.h"
 
#include "../signs_func.h"
 
#include "../aircraft.h"
 
#include "../unmovable_map.h"
 
#include "../tree_map.h"
 
#include "../company_func.h"
 
#include "../road_cmd.h"
 
#include "../ai/ai.hpp"
 
#include "../town.h"
src/station_cmd.cpp
Show inline comments
 
@@ -2639,27 +2639,26 @@ static bool ClickTile_Station(TileIndex 
 
	if (st->facilities & FACIL_WAYPOINT) {
 
		ShowWaypointWindow(Waypoint::From(st));
 
	} else if (IsHangar(tile)) {
 
		ShowDepotWindow(tile, VEH_AIRCRAFT);
 
	} else {
 
		ShowStationViewWindow(st->index);
 
	}
 
	return true;
 
}
 

	
 
static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y)
 
{
 
	StationID station_id = GetStationIndex(tile);
 

	
 
	if (v->type == VEH_TRAIN) {
 
		StationID station_id = GetStationIndex(tile);
 
		if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE;
 
		if (!IsRailStation(tile) || !Train::From(v)->IsFrontEngine()) return VETSB_CONTINUE;
 

	
 
		int station_ahead;
 
		int station_length;
 
		int stop = GetTrainStopLocation(station_id, tile, Train::From(v), &station_ahead, &station_length);
 

	
 
		/* Stop whenever that amount of station ahead + the distance from the
 
		 * begin of the platform to the stop location is longer than the length
 
		 * of the platform. Station ahead 'includes' the current tile where the
 
		 * vehicle is on, so we need to substract that. */
 
		if (!IsInsideBS(stop + station_ahead, station_length, TILE_SIZE)) return VETSB_CONTINUE;
 
@@ -2679,60 +2678,25 @@ static VehicleEnterTileStatus VehicleEnt
 
				uint16 spd;
 

	
 
				v->vehstatus |= VS_TRAIN_SLOWING;
 
				spd = max(0, (stop - x) * 20 - 15);
 
				if (spd < v->cur_speed) v->cur_speed = spd;
 
			}
 
		}
 
	} else if (v->type == VEH_ROAD) {
 
		RoadVehicle *rv = RoadVehicle::From(v);
 
		if (rv->state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)rv->state) && rv->frame == 0) {
 
			if (IsRoadStop(tile) && rv->IsRoadVehFront()) {
 
				/* Attempt to allocate a parking bay in a road stop */
 
				RoadStop *rs = RoadStop::GetByTile(tile, GetRoadStopType(tile));
 

	
 
				if (IsDriveThroughStopTile(tile)) {
 
					if (!rv->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(rv->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (rv->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) == (rv->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
 
							rv->current_order.GetDestination() == GetStationIndex(tile)) {
 
						SetBit(rv->state, RVS_IS_STOPPING);
 
						rs->AllocateDriveThroughBay(side);
 
					}
 

	
 
					/* Indicate if vehicle is using second bay. */
 
					if (side == 1) SetBit(rv->state, RVS_USING_SECOND_BAY);
 
					/* Indicate a drive-through stop */
 
					SetBit(rv->state, RVS_IN_DT_ROAD_STOP);
 
					return VETSB_CONTINUE;
 
				}
 

	
 
				/* For normal (non drive-through) road stops
 
				 * Check if station is busy or if there are no free bays or whether it is a articulated vehicle. */
 
				if (rs->IsEntranceBusy() || !rs->HasFreeBay() || rv->HasArticulatedPart()) return VETSB_CANNOT_ENTER;
 

	
 
				SetBit(rv->state, RVS_IN_ROAD_STOP);
 

	
 
				/* Allocate a bay and update the road state */
 
				uint bay_nr = rs->AllocateBay();
 
				SB(rv->state, RVS_USING_SECOND_BAY, 1, bay_nr);
 

	
 
				/* Mark the station entrace as busy */
 
				rs->SetEntranceBusy(true);
 
				return RoadStop::GetByTile(tile, GetRoadStopType(tile))->Enter(rv) ? VETSB_CONTINUE : VETSB_CANNOT_ENTER;
 
			}
 
		}
 
	}
 

	
 
	return VETSB_CONTINUE;
 
}
 

	
 
/**
 
 * This function is called for each station once every 250 ticks.
 
 * Not all stations will get the tick at the same time.
 
 * @param st the station receiving the tick.
 
 * @return true if the station is still valid (wasn't deleted)
0 comments (0 inline, 0 general)