Changeset - r6012:6160fb57dc8a
[Not reviewed]
master
0 25 1
rubidium - 18 years ago 2007-02-14 16:37:16
rubidium@openttd.org
(svn r8735) -Feature: drive-through road stops made possible by the hard work of mart3p.
26 files changed with 373 insertions and 61 deletions:
0 comments (0 inline, 0 general)
bin/data/roadstops.grf
Show inline comments
 
new file 100644
 
binary diff not shown
src/command.cpp
Show inline comments
 
@@ -45,6 +45,7 @@ DEF_COMMAND(CmdRenameWaypoint);
 
DEF_COMMAND(CmdRemoveTrainWaypoint);
 

	
 
DEF_COMMAND(CmdBuildRoadStop);
 
DEF_COMMAND(CmdRemoveRoadStop);
 

	
 
DEF_COMMAND(CmdBuildLongRoad);
 
DEF_COMMAND(CmdRemoveLongRoad);
 
@@ -188,7 +189,7 @@ static const Command _command_proc_table
 
	{NULL,                                   0}, /*  19 */
 
	{NULL,                                   0}, /*  20 */
 
	{CmdBuildRoadStop,                       0}, /*  21 */
 
	{NULL,                                   0}, /*  22 */
 
	{CmdRemoveRoadStop,                      0}, /*  22 */
 
	{CmdBuildLongRoad,                       0}, /*  23 */
 
	{CmdRemoveLongRoad,                      0}, /*  24 */
 
	{CmdBuildRoad,                           0}, /*  25 */
src/command.h
Show inline comments
 
@@ -27,6 +27,7 @@ enum {
 
	CMD_REMOVE_TRAIN_WAYPOINT        =  18,
 

	
 
	CMD_BUILD_ROAD_STOP              =  21,
 
	CMD_REMOVE_ROAD_STOP             =  22,
 
	CMD_BUILD_LONG_ROAD              =  23,
 
	CMD_REMOVE_LONG_ROAD             =  24,
 
	CMD_BUILD_ROAD                   =  25,
src/gfxinit.cpp
Show inline comments
 
@@ -387,6 +387,9 @@ static void LoadSpriteTables(void)
 
	assert(load_index == SPR_AIRPORTX_BASE);
 
	load_index += LoadGrfFile("airports.grf", load_index, i++);
 

	
 
	assert(load_index == SPR_ROADSTOP_BASE);
 
	load_index += LoadGrfFile("roadstops.grf", load_index, i++);
 

	
 
	/* Initialize the unicode to sprite mapping table */
 
	InitializeUnicodeGlyphMap();
 

	
src/lang/english.txt
Show inline comments
 
@@ -1041,6 +1041,7 @@ STR_CONFIG_PATCHES_BRIBE                
 
STR_CONFIG_PATCHES_NONUNIFORM_STATIONS                          :{LTBLUE}Nonuniform stations: {ORANGE}{STRING1}
 
STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL                          :{LTBLUE}New global pathfinding (NPF, overrides NTP): {ORANGE}{STRING1}
 
STR_CONFIG_PATCHES_FREIGHT_TRAINS                               :{LTBLUE}Weight multiplier for freight to simulate heavy trains: {ORANGE}{STRING}
 
STR_CONFIG_PATCHES_STOP_ON_TOWN_ROAD                            :{LTBLUE}Allow drive-through road stops on town owned roads: {ORANGE}{STRING}
 

	
 
STR_CONFIG_PATCHES_SMALL_AIRPORTS                               :{LTBLUE}Always allow small airports: {ORANGE}{STRING1}
 

	
 
@@ -1584,6 +1585,8 @@ STR_1815_ROAD_WITH_STREETLIGHTS         
 
STR_1816_TREE_LINED_ROAD                                        :Tree-lined road
 
STR_1817_ROAD_VEHICLE_DEPOT                                     :Road vehicle depot
 
STR_1818_ROAD_RAIL_LEVEL_CROSSING                               :Road/rail level crossing
 
STR_CAN_T_REMOVE_BUS_STATION                                    :{WHITE}Can't remove bus station...
 
STR_CAN_T_REMOVE_TRUCK_STATION                                  :{WHITE}Can't remove lorry station...
 

	
 
##id 0x2000
 
STR_2000_TOWNS                                                  :{WHITE}Towns
src/lang/hungarian.txt
Show inline comments
 
@@ -1107,6 +1107,7 @@ STR_CONFIG_PATCHES_BRIBE                                        :{LTBLUE}Önkormányzatok lefizethetősége: {ORANGE}{STRING}
 
STR_CONFIG_PATCHES_NONUNIFORM_STATIONS                          :{LTBLUE}Különböző vágánytípusok engedélyezése egy állomáson: {ORANGE}{STRING}
 
STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL                          :{LTBLUE}Új útvonalkereső (NPF, felülbírálja az NTP-t): {ORANGE}{STRING}
 
STR_CONFIG_PATCHES_FREIGHT_TRAINS                               :{LTBLUE}Tömegszorzó tehervonatoknak (szimulációs célból): {ORANGE}{STRING}
 
STR_CONFIG_PATCHES_STOP_ON_TOWN_ROAD                            :{LTBLUE}Áthajtható állomások engedélyezése városi utakra: {ORANGE}{STRING}
 

	
 
STR_CONFIG_PATCHES_SMALL_AIRPORTS                               :{LTBLUE}Mindig engedélyezze a kis repülőtereket: {ORANGE}{STRING}
 

	
 
@@ -1650,6 +1651,8 @@ STR_1815_ROAD_WITH_STREETLIGHTS                                 :Út lámpákkal
 
STR_1816_TREE_LINED_ROAD                                        :Fával szegélyezett út
 
STR_1817_ROAD_VEHICLE_DEPOT                                     :Garázs
 
STR_1818_ROAD_RAIL_LEVEL_CROSSING                               :Út/vasút kereszteződés
 
STR_CAN_T_REMOVE_BUS_STATION                                    :{WHITE}Nem távolíthatod el ezt a buszmegállót...
 
STR_CAN_T_REMOVE_TRUCK_STATION                                  :{WHITE}Nem távolíthatod el ezt a teherautó megállót...
 

	
 
##id 0x2000
 
STR_2000_TOWNS                                                  :{WHITE}Városok
src/npf.cpp
Show inline comments
 
@@ -279,6 +279,12 @@ static int32 NPFRoadPathCost(AyStar* as,
 
			if (IsLevelCrossing(tile)) cost += _patches.npf_crossing_penalty;
 
			break;
 

	
 
		case MP_STATION:
 
			cost = NPF_TILE_LENGTH;
 
			/* Increase the cost for drive-through road stops */
 
			if (IsDriveThroughStopTile(tile)) cost += _patches.npf_road_drive_through_penalty;
 
			break;
 

	
 
		default:
 
			break;
 
	}
 
@@ -453,7 +459,7 @@ static bool VehicleMayEnterTile(Owner ow
 
	if (IsTileType(tile, MP_RAILWAY) ||           /* Rail tile (also rail depot) */
 
			IsRailwayStationTile(tile) ||               /* Rail station tile */
 
			IsTileDepotType(tile, TRANSPORT_ROAD) ||  /* Road depot tile */
 
			IsRoadStopTile(tile) ||                /* Road station tile */
 
			IsStandardRoadStopTile(tile) || /* Road station tile (but not drive-through stops) */
 
			IsTileDepotType(tile, TRANSPORT_WATER)) { /* Water depot tile */
 
		return IsTileOwner(tile, owner); /* You need to own these tiles entirely to use them */
 
	}
 
@@ -529,8 +535,8 @@ static void NPFFollowTrack(AyStar* aysta
 
	} else if (IsBridgeTile(src_tile) && GetBridgeRampDirection(src_tile) == src_exitdir) {
 
		dst_tile = GetOtherBridgeEnd(src_tile);
 
		override_dst_check = true;
 
	} else if (type != TRANSPORT_WATER && (IsRoadStopTile(src_tile) || IsTileDepotType(src_tile, type))) {
 
		/* This is a road station or a train or road depot. We can enter and exit
 
	} else if (type != TRANSPORT_WATER && (IsStandardRoadStopTile(src_tile) || IsTileDepotType(src_tile, type))) {
 
		/* This is a road station (non drive-through) or a train or road depot. We can enter and exit
 
		 * those from one side only. Trackdirs don't support that (yet), so we'll
 
		 * do this here. */
 

	
 
@@ -599,7 +605,7 @@ static void NPFFollowTrack(AyStar* aysta
 
	}
 

	
 
	/* Determine available tracks */
 
	if (type != TRANSPORT_WATER && (IsRoadStopTile(dst_tile) || IsTileDepotType(dst_tile, type))){
 
	if (type != TRANSPORT_WATER && (IsStandardRoadStopTile(dst_tile) || IsTileDepotType(dst_tile, type))){
 
		/* Road stations and road and train depots return 0 on GTTS, so we have to do this by hand... */
 
		DiagDirection exitdir;
 
		if (IsRoadStopTile(dst_tile)) {
src/pathfind.cpp
Show inline comments
 
@@ -296,7 +296,7 @@ static void TPFMode1(TrackPathFinder* tp
 
	if (tpf->tracktype == TRANSPORT_ROAD) {
 
		// road stops and depots now have a track (r4419)
 
		// don't enter road stop from the back
 
		if (IsRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return;
 
		if (IsStandardRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return;
 
		// don't enter road depot from the back
 
		if (IsTileDepotType(tile, TRANSPORT_ROAD) && ReverseDiagDir(GetRoadDepotDirection(tile)) != direction) return;
 
	}
src/road_gui.cpp
Show inline comments
 
@@ -16,6 +16,7 @@
 
#include "sound.h"
 
#include "command.h"
 
#include "variables.h"
 
#include "station_map.h"
 
//needed for catchments
 
#include "station.h"
 

	
 
@@ -83,7 +84,7 @@ void CcRoadDepot(bool success, TileIndex
 
	if (success) {
 
		SndPlayTileFx(SND_1F_SPLAT, tile);
 
		ResetObjectToPlace();
 
		BuildRoadOutsideStation(tile, (DiagDirection)p1);
 
		if (!HASBIT(p2, 1)) BuildRoadOutsideStation(tile, (DiagDirection)p1);
 
	}
 
}
 

	
 
@@ -92,14 +93,45 @@ static void PlaceRoad_Depot(TileIndex ti
 
	DoCommandP(tile, _road_depot_orientation, 0, CcRoadDepot, CMD_BUILD_ROAD_DEPOT | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1807_CAN_T_BUILD_ROAD_VEHICLE));
 
}
 

	
 
static void PlaceRoadStop(TileIndex tile, uint32 p2, uint32 cmd)
 
{
 
	uint32 p1 = _road_station_picker_orientation;
 

	
 
	if (p1 >= DIAGDIR_END) {
 
		SETBIT(p2, 1); // It's a drive-through stop
 
		p1 -= DIAGDIR_END; // Adjust picker result to actual direction
 

	
 
		/* Only allow building over a road if its a straight road,
 
		 * facing the right direction and it belongs to the player */
 
		if ((IsTileType(tile, MP_STREET) &&
 
				GetRoadTileType(tile) == ROAD_TILE_NORMAL &&
 
				(IsTileOwner(tile, _current_player) || (_patches.road_stop_on_town_road && IsTileOwner(tile, OWNER_TOWN))) &&
 
				!(GetRoadBits(tile) & ((DiagDirection)p1 == DIAGDIR_NE ? ROAD_Y : ROAD_X)))) {
 

	
 
			cmd ^= CMD_AUTO;
 
			SETBIT(p2, 2); // We're building over an existing road
 
			if (IsTileOwner(tile, OWNER_TOWN)) SETBIT(p2, 3); // It's a town owned road
 
		}
 
	}
 
	DoCommandP(tile, p1, p2, CcRoadDepot, cmd);
 
}
 

	
 
static void PlaceRoad_BusStation(TileIndex tile)
 
{
 
	DoCommandP(tile, _road_station_picker_orientation, RoadStop::BUS, CcRoadDepot, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1808_CAN_T_BUILD_BUS_STATION));
 
	if (_remove_button_clicked) {
 
		DoCommandP(tile, 0, RoadStop::BUS, CcPlaySound1D, CMD_REMOVE_ROAD_STOP | CMD_MSG(STR_CAN_T_REMOVE_BUS_STATION));
 
	} else {
 
		PlaceRoadStop(tile, RoadStop::BUS, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1808_CAN_T_BUILD_BUS_STATION));
 
	}
 
}
 

	
 
static void PlaceRoad_TruckStation(TileIndex tile)
 
{
 
	DoCommandP(tile, _road_station_picker_orientation, RoadStop::TRUCK, CcRoadDepot, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1809_CAN_T_BUILD_TRUCK_STATION));
 
	if (_remove_button_clicked) {
 
		DoCommandP(tile, 0, RoadStop::TRUCK, CcPlaySound1D, CMD_REMOVE_ROAD_STOP | CMD_MSG(STR_CAN_T_REMOVE_TRUCK_STATION));
 
	} else {
 
		PlaceRoadStop(tile, RoadStop::TRUCK, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1809_CAN_T_BUILD_TRUCK_STATION));
 
	}
 
}
 

	
 
static void PlaceRoad_DemolishArea(TileIndex tile)
 
@@ -195,7 +227,7 @@ static void BuildRoadToolbWndProc(Window
 
	case WE_CREATE: DisableWindowWidget(w, RTW_REMOVE); break;
 

	
 
	case WE_PAINT:
 
		if (IsWindowWidgetLowered(w, RTW_ROAD_X) || IsWindowWidgetLowered(w, RTW_ROAD_Y)) {
 
		if (IsWindowWidgetLowered(w, RTW_ROAD_X) || IsWindowWidgetLowered(w, RTW_ROAD_Y) || IsWindowWidgetLowered(w, RTW_BUS_STATION) || IsWindowWidgetLowered(w, RTW_TRUCK_STATION)) {
 
			EnableWindowWidget(w, RTW_REMOVE);
 
		}
 
		DrawWindowWidgets(w);
 
@@ -428,7 +460,7 @@ static void RoadStationPickerWndProc(Win
 
	switch (e->event) {
 
	case WE_CREATE:
 
		LowerWindowWidget(w, _road_station_picker_orientation + 3);
 
		LowerWindowWidget(w, _station_show_coverage + 7);
 
		LowerWindowWidget(w, _station_show_coverage + 9);
 
		break;
 

	
 
	case WE_PAINT: {
 
@@ -445,13 +477,18 @@ static void RoadStationPickerWndProc(Win
 
			SetTileSelectSize(1, 1);
 
		}
 

	
 
		image = (w->window_class == WC_BUS_STATION) ? 0x47 : 0x43;
 
		image = (w->window_class == WC_BUS_STATION) ? GFX_BUS_BASE : GFX_TRUCK_BASE;
 

	
 
		StationPickerDrawSprite(103, 35, RAILTYPE_BEGIN, image);
 
		StationPickerDrawSprite(103, 85, RAILTYPE_BEGIN, image+1);
 
		StationPickerDrawSprite(35, 85, RAILTYPE_BEGIN, image+2);
 
		StationPickerDrawSprite(35, 35, RAILTYPE_BEGIN, image+3);
 

	
 
		image = (w->window_class == WC_BUS_STATION) ? GFX_BUS_BASE_EXT : GFX_TRUCK_BASE_EXT;
 

	
 
		StationPickerDrawSprite(171, 35, RAILTYPE_BEGIN, image);
 
		StationPickerDrawSprite(171, 85, RAILTYPE_BEGIN, image + 1);
 

	
 
		DrawStationCoverageAreaText(2, 146,
 
			((w->window_class == WC_BUS_STATION) ? (1<<CT_PASSENGERS) : ~(1<<CT_PASSENGERS)),
 
			3);
 
@@ -460,17 +497,17 @@ static void RoadStationPickerWndProc(Win
 

	
 
	case WE_CLICK: {
 
		switch (e->we.click.widget) {
 
		case 3: case 4: case 5: case 6:
 
		case 3: case 4: case 5: case 6: case 7: case 8:
 
			RaiseWindowWidget(w, _road_station_picker_orientation + 3);
 
			_road_station_picker_orientation = (DiagDirection)(e->we.click.widget - 3);
 
			LowerWindowWidget(w, _road_station_picker_orientation + 3);
 
			SndPlayFx(SND_15_BEEP);
 
			SetWindowDirty(w);
 
			break;
 
		case 7: case 8:
 
			RaiseWindowWidget(w, _station_show_coverage + 7);
 
			_station_show_coverage = (e->we.click.widget != 7);
 
			LowerWindowWidget(w, _station_show_coverage + 7);
 
		case 9: case 10:
 
			RaiseWindowWidget(w, _station_show_coverage + 9);
 
			_station_show_coverage = (e->we.click.widget != 9);
 
			LowerWindowWidget(w, _station_show_coverage + 9);
 
			SndPlayFx(SND_15_BEEP);
 
			SetWindowDirty(w);
 
			break;
 
@@ -494,12 +531,14 @@ static void RoadStationPickerWndProc(Win
 

	
 
static const Widget _bus_station_picker_widgets[] = {
 
{   WWT_CLOSEBOX,   RESIZE_NONE,     7,     0,    10,     0,    13, STR_00C5,                         STR_018B_CLOSE_WINDOW},
 
{    WWT_CAPTION,   RESIZE_NONE,     7,    11,   139,     0,    13, STR_3042_BUS_STATION_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{      WWT_PANEL,   RESIZE_NONE,     7,     0,   139,    14,   176, 0x0,                              STR_NULL},
 
{    WWT_CAPTION,   RESIZE_NONE,     7,    11,   206,     0,    13, STR_3042_BUS_STATION_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{      WWT_PANEL,   RESIZE_NONE,     7,     0,   206,    14,   176, 0x0,                              STR_NULL},
 
{      WWT_PANEL,   RESIZE_NONE,    14,    71,   136,    17,    66, 0x0,                              STR_3051_SELECT_BUS_STATION_ORIENTATION},
 
{      WWT_PANEL,   RESIZE_NONE,    14,    71,   136,    69,   118, 0x0,                              STR_3051_SELECT_BUS_STATION_ORIENTATION},
 
{      WWT_PANEL,   RESIZE_NONE,    14,     3,    68,    69,   118, 0x0,                              STR_3051_SELECT_BUS_STATION_ORIENTATION},
 
{      WWT_PANEL,   RESIZE_NONE,    14,     3,    68,    17,    66, 0x0,                              STR_3051_SELECT_BUS_STATION_ORIENTATION},
 
{      WWT_PANEL,   RESIZE_NONE,    14,   139,   204,    17,    66, 0x0,                              STR_3051_SELECT_BUS_STATION_ORIENTATION},
 
{      WWT_PANEL,   RESIZE_NONE,    14,   139,   204,    69,   118, 0x0,                              STR_3051_SELECT_BUS_STATION_ORIENTATION},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,    10,    69,   133,   144, STR_02DB_OFF,                     STR_3065_DON_T_HIGHLIGHT_COVERAGE},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,    70,   129,   133,   144, STR_02DA_ON,                      STR_3064_HIGHLIGHT_COVERAGE_AREA},
 
{      WWT_LABEL,   RESIZE_NONE,     7,     0,   139,   120,   133, STR_3066_COVERAGE_AREA_HIGHLIGHT, STR_NULL},
 
@@ -507,7 +546,7 @@ static const Widget _bus_station_picker_
 
};
 

	
 
static const WindowDesc _bus_station_picker_desc = {
 
	WDP_AUTO, WDP_AUTO, 140, 177,
 
	WDP_AUTO, WDP_AUTO, 207, 177,
 
	WC_BUS_STATION, WC_BUILD_TOOLBAR,
 
	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
 
	_bus_station_picker_widgets,
 
@@ -521,12 +560,14 @@ static void ShowBusStationPicker(void)
 

	
 
static const Widget _truck_station_picker_widgets[] = {
 
{   WWT_CLOSEBOX,   RESIZE_NONE,     7,     0,    10,     0,    13, STR_00C5,                         STR_018B_CLOSE_WINDOW},
 
{    WWT_CAPTION,   RESIZE_NONE,     7,    11,   139,     0,    13, STR_3043_TRUCK_STATION_ORIENT,    STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{      WWT_PANEL,   RESIZE_NONE,     7,     0,   139,    14,   176, 0x0,                              STR_NULL},
 
{    WWT_CAPTION,   RESIZE_NONE,     7,    11,   206,     0,    13, STR_3043_TRUCK_STATION_ORIENT,    STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{      WWT_PANEL,   RESIZE_NONE,     7,     0,   206,    14,   176, 0x0,                              STR_NULL},
 
{      WWT_PANEL,   RESIZE_NONE,    14,    71,   136,    17,    66, 0x0,                              STR_3052_SELECT_TRUCK_LOADING_BAY},
 
{      WWT_PANEL,   RESIZE_NONE,    14,    71,   136,    69,   118, 0x0,                              STR_3052_SELECT_TRUCK_LOADING_BAY},
 
{      WWT_PANEL,   RESIZE_NONE,    14,     3,    68,    69,   118, 0x0,                              STR_3052_SELECT_TRUCK_LOADING_BAY},
 
{      WWT_PANEL,   RESIZE_NONE,    14,     3,    68,    17,    66, 0x0,                              STR_3052_SELECT_TRUCK_LOADING_BAY},
 
{      WWT_PANEL,   RESIZE_NONE,    14,   139,   204,    17,    66, 0x0,                              STR_3052_SELECT_TRUCK_LOADING_BAY},
 
{      WWT_PANEL,   RESIZE_NONE,    14,   139,   204,    69,   118, 0x0,                              STR_3052_SELECT_TRUCK_LOADING_BAY},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,    10,    69,   133,   144, STR_02DB_OFF,                     STR_3065_DON_T_HIGHLIGHT_COVERAGE},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,    70,   129,   133,   144, STR_02DA_ON,                      STR_3064_HIGHLIGHT_COVERAGE_AREA},
 
{      WWT_LABEL,   RESIZE_NONE,     7,     0,   139,   120,   133, STR_3066_COVERAGE_AREA_HIGHLIGHT, STR_NULL},
 
@@ -534,7 +575,7 @@ static const Widget _truck_station_picke
 
};
 

	
 
static const WindowDesc _truck_station_picker_desc = {
 
	WDP_AUTO, WDP_AUTO, 140, 177,
 
	WDP_AUTO, WDP_AUTO, 207, 177,
 
	WC_TRUCK_STATION, WC_BUILD_TOOLBAR,
 
	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
 
	_truck_station_picker_widgets,
src/road_map.cpp
Show inline comments
 
@@ -24,6 +24,7 @@ RoadBits GetAnyRoadBits(TileIndex tile)
 

	
 
		case MP_STATION:
 
			if (!IsRoadStopTile(tile)) return ROAD_NONE;
 
			if (IsDriveThroughStopTile(tile)) return (GetRoadStopDir(tile) == DIAGDIR_NE) ? ROAD_X : ROAD_Y;
 
			return DiagDirToRoadBits(GetRoadStopDir(tile));
 

	
 
		case MP_TUNNELBRIDGE:
 
@@ -45,7 +46,7 @@ TrackBits GetAnyRoadTrackBits(TileIndex 
 
	uint32 r;
 

	
 
	// Don't allow local authorities to build roads through road depots or road stops.
 
	if ((IsTileType(tile, MP_STREET) && IsTileDepotType(tile, TRANSPORT_ROAD)) || IsTileType(tile, MP_STATION)) {
 
	if ((IsTileType(tile, MP_STREET) && IsTileDepotType(tile, TRANSPORT_ROAD)) || (IsTileType(tile, MP_STATION) && !IsDriveThroughStopTile(tile))) {
 
		return TRACK_BIT_NONE;
 
	}
 

	
src/roadveh_cmd.cpp
Show inline comments
 
@@ -1080,7 +1080,8 @@ static Trackdir RoadFindPathToDest(Vehic
 
			/* Road depot owned by another player or with the wrong orientation */
 
			trackdirs = TRACKDIR_BIT_NONE;
 
		}
 
	} else if (IsTileType(tile, MP_STATION) && IsRoadStopTile(tile)) {
 
	} else if (IsTileType(tile, MP_STATION) && IsStandardRoadStopTile(tile)) {
 
		/* Standard road stop (drive-through stops are treated as normal road) */
 
		if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir) {
 
			/* different station owner or wrong orientation */
 
			trackdirs = TRACKDIR_BIT_NONE;
 
@@ -1093,7 +1094,7 @@ static Trackdir RoadFindPathToDest(Vehic
 
				trackdirs = TRACKDIR_BIT_NONE;
 
			} else {
 
				/* Proper station type, check if there is free loading bay */
 
				if (!_patches.roadveh_queue &&
 
				if (!_patches.roadveh_queue &&  IsStandardRoadStopTile(tile) &&
 
						!GetRoadStopByTile(tile, rstype)->HasFreeBay()) {
 
					/* Station is full and RV queuing is off */
 
					trackdirs = TRACKDIR_BIT_NONE;
 
@@ -1167,7 +1168,8 @@ static Trackdir RoadFindPathToDest(Vehic
 
				goto do_it;
 
			}
 
		} else if (IsTileType(desttile, MP_STATION)) {
 
			if (IsRoadStop(desttile)) {
 
			/* For drive-through stops we can head for the actual station tile */
 
			if (IsStandardRoadStopTile(desttile)) {
 
				dir = GetRoadStopDir(desttile);
 
do_it:;
 
				/* When we are heading for a depot or station, we just
 
@@ -1242,9 +1244,11 @@ enum {
 
	/* Start frames for when a vehicle enters a tile/changes its state.
 
	 * The start frame is different for vehicles that turned around or
 
	 * are leaving the depot as the do not start at the edge of the tile */
 
	RVC_DEFAULT_START_FRAME     = 0,
 
	RVC_TURN_AROUND_START_FRAME = 1,
 
	RVC_DEPOT_START_FRAME       = 6
 
	RVC_DEFAULT_START_FRAME      = 0,
 
	RVC_TURN_AROUND_START_FRAME  = 1,
 
	RVC_DEPOT_START_FRAME        = 6,
 
	/* Stop frame for a vehicle in a drive-through stop */
 
	RVC_DRIVE_THROUGH_STOP_FRAME = 7
 
};
 

	
 
typedef struct RoadDriveEntry {
 
@@ -1376,8 +1380,12 @@ static void RoadVehController(Vehicle *v
 
		return;
 
	}
 

	
 
	/* Get move position data for next frame */
 
	rd = _road_drive_data[(v->u.road.state + (_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
 
	/* Get move position data for next frame.
 
	 * For a drive-through road stop use 'straight road' move data.
 
	 * In this case v->u.road.state is masked to give the road stop entry direction. */
 
	rd = _road_drive_data[(
 
		(HASBIT(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) +
 
		(_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
 

	
 
	if (rd.x & RDE_NEXT_TILE) {
 
		TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3);
 
@@ -1417,8 +1425,8 @@ again:
 
			goto again;
 
		}
 

	
 
		if (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
 
			if (IsReversingRoadTrackdir(dir)) {
 
		if (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
 
			if (IsReversingRoadTrackdir(dir) && IS_BYTE_INSIDE(v->u.road.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;
 
@@ -1427,9 +1435,13 @@ again:
 
			if (IsRoadStop(v->tile)) {
 
				RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
 

	
 
				/* Vehicle is leaving a road stop tile, mark bay as free */
 
				rs->FreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY));
 
				rs->SetEntranceBusy(false);
 
				/* 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->u.road.state, RVS_IS_STOPPING)) {
 
					rs->FreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY));
 
					CLRBIT(v->u.road.state, RVS_IS_STOPPING);
 
				}
 
				if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(false);
 
			}
 
		}
 

	
 
@@ -1523,8 +1535,18 @@ again:
 
		}
 
	}
 

	
 
	if (v->u.road.state >= RVSB_IN_ROAD_STOP &&
 
			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) {
 
	/* 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 ((IS_BYTE_INSIDE(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) ||
 
			(IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
 
			v->current_order.dest == GetStationIndex(v->tile) &&
 
			GetRoadStopType(v->tile) == ((v->cargo_type == CT_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);
 

	
 
@@ -1536,6 +1558,31 @@ again:
 
			/* Vehicle has arrived at a bay in a road stop */
 
			Order old_order;
 

	
 
			if (IsDriveThroughStopTile(v->tile)) {
 
				TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction));
 
				RoadStop::Type type = (v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK;
 

	
 
				assert(HASBIT(v->u.road.state, RVS_IS_STOPPING));
 

	
 
				/* 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 */
 
						ClearSlot(v);
 
						rs_n->num_vehicles++;
 
						v->u.road.slot = rs_n;
 
						v->dest_tile = rs_n->xy;
 
						v->u.road.slot_age = 14;
 

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

	
 
			rs->SetEntranceBusy(false);
 

	
 
			v->last_station_visited = GetStationIndex(v->tile);
 
@@ -1573,7 +1620,7 @@ again:
 
			ClearSlot(v);
 
		}
 

	
 
		rs->SetEntranceBusy(true);
 
		if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true);
 

	
 
		if (rs == v->u.road.slot) {
 
			/* We are leaving the correct station */
src/saveload.cpp
Show inline comments
 
@@ -30,7 +30,7 @@
 
#include "variables.h"
 
#include <setjmp.h>
 

	
 
extern const uint16 SAVEGAME_VERSION = 46;
 
extern const uint16 SAVEGAME_VERSION = 47;
 
uint16 _sl_version;       /// the major savegame version identifier
 
byte   _sl_minor_version; /// the minor savegame version, DO NOT USE!
 

	
src/settings.cpp
Show inline comments
 
@@ -1340,6 +1340,7 @@ const SettingDesc _patch_settings[] = {
 
	SDT_BOOL(Patches, serviceathelipad,        0, 0,  true,        STR_CONFIG_PATCHES_SERVICEATHELIPAD,   NULL),
 
	SDT_BOOL(Patches, modified_catchment,      0, 0,  true,        STR_CONFIG_PATCHES_CATCHMENT,          NULL),
 
	SDT_CONDBOOL(Patches, gradual_loading, 40, SL_MAX_VERSION, 0, 0,  true, STR_CONFIG_PATCHES_GRADUAL_LOADING,    NULL),
 
	SDT_CONDBOOL(Patches, road_stop_on_town_road, 47, SL_MAX_VERSION, 0, 0, false, STR_CONFIG_PATCHES_STOP_ON_TOWN_ROAD, NULL),
 

	
 
	/***************************************************************************/
 
	/* Economy section of the GUI-configure patches window */
 
@@ -1431,6 +1432,8 @@ const SettingDesc _patch_settings[] = {
 
	SDT_VAR(Patches, npf_road_curve_penalty,        SLE_UINT, 0, 0, 1,                      0, 100000, 0, STR_NULL, NULL),
 
	/* This is the penalty for level crossings, for both road and rail vehicles */
 
	SDT_VAR(Patches, npf_crossing_penalty,          SLE_UINT, 0, 0, (3 * NPF_TILE_LENGTH),  0, 100000, 0, STR_NULL, NULL),
 
	/* This is the penalty for drive-through road, stops. */
 
	SDT_CONDVAR (Patches, npf_road_drive_through_penalty, SLE_UINT, 47, SL_MAX_VERSION, 0, 0,  8 * NPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
 

	
 

	
 
	// The maximum number of nodes to search
 
@@ -1464,6 +1467,7 @@ const SettingDesc _patch_settings[] = {
 
	SDT_CONDVAR (Patches, yapf.road_slope_penalty                    , SLE_UINT, 33, SL_MAX_VERSION, 0, 0,  2 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
 
	SDT_CONDVAR (Patches, yapf.road_curve_penalty                    , SLE_UINT, 33, SL_MAX_VERSION, 0, 0,  1 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
 
	SDT_CONDVAR (Patches, yapf.road_crossing_penalty                 , SLE_UINT, 33, SL_MAX_VERSION, 0, 0,  3 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
 
	SDT_CONDVAR (Patches, yapf.road_stop_penalty                     , SLE_UINT, 47, SL_MAX_VERSION, 0, 0,  8 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
 

	
 
	/***************************************************************************/
 
	/* Terrain genation related patch options */
src/settings_gui.cpp
Show inline comments
 
@@ -599,6 +599,7 @@ static const char *_patches_stations[] =
 
	"serviceathelipad",
 
	"modified_catchment",
 
	"gradual_loading",
 
	"road_stop_on_town_road",
 
};
 

	
 
static const char *_patches_economy[] = {
src/station.cpp
Show inline comments
 
@@ -502,6 +502,13 @@ bool RoadStop::HasFreeBay() const
 
	return GB(status, 0, MAX_BAY_COUNT) != 0;
 
}
 

	
 
/** Checks whether the given bay is free in this road stop */
 
bool RoadStop::IsFreeBay(uint nr) const
 
{
 
	assert(nr < MAX_BAY_COUNT);
 
	return HASBIT(status, nr);
 
}
 

	
 
/**
 
 * Allocates a bay
 
 * @return the allocated bay number
 
@@ -520,6 +527,16 @@ uint RoadStop::AllocateBay()
 
}
 

	
 
/**
 
 * Allocates a bay in a drive-through road stop
 
 * @param nr the number of the bay to allocate
 
 */
 
void RoadStop::AllocateDriveThroughBay(uint nr)
 
{
 
	assert(nr < MAX_BAY_COUNT);
 
	CLRBIT(status, nr);
 
}
 

	
 
/**
 
 * Frees the given bay
 
 * @param nr the number of the bay to free
 
 */
src/station.h
Show inline comments
 
@@ -66,7 +66,9 @@ struct RoadStop {
 

	
 
	/* For accessing status */
 
	bool HasFreeBay() const;
 
	bool IsFreeBay(uint nr) const;
 
	uint AllocateBay();
 
	void AllocateDriveThroughBay(uint nr);
 
	void FreeBay(uint nr);
 
	bool IsEntranceBusy() const;
 
	void SetEntranceBusy(bool busy);
src/station_cmd.cpp
Show inline comments
 
@@ -35,6 +35,7 @@
 
#include "date.h"
 
#include "helpers.hpp"
 
#include "misc/autoptr.hpp"
 
#include "road.h"
 

	
 
/**
 
 * Called if a new block is added to the station-pool
 
@@ -1247,7 +1248,10 @@ static RoadStop **FindRoadStopSpot(bool 
 
/** Build a bus or truck stop
 
 * @param tile tile to build the stop at
 
 * @param p1 entrance direction (DiagDirection)
 
 * @param p2 0 for Bus stops, 1 for truck stops
 
 * @param p2 bit 0: 0 for Bus stops, 1 for truck stops
 
 *           bit 1: 0 for normal, 1 for drive-through
 
 *           bit 2: 0 for normal, 1 for build over road
 
 *           bit 3: 0 for player owned road, 1 for town owned road
 
 */
 
int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
@@ -1255,19 +1259,29 @@ int32 CmdBuildRoadStop(TileIndex tile, u
 
	RoadStop *road_stop;
 
	int32 cost;
 
	int32 ret;
 
	bool type = !!p2;
 
	bool type = HASBIT(p2, 0);
 
	bool is_drive_through = HASBIT(p2, 1);
 
	Owner cur_owner = _current_player;
 

	
 
	/* Saveguard the parameters */
 
	if (!IsValidDiagDirection((DiagDirection)p1)) return CMD_ERROR;
 
	/* If it is a drive-through stop check for valid axis */
 
	if (is_drive_through && !IsValidAxis((Axis)p1)) return CMD_ERROR;
 
	/* If overbuilding a road check tile is a valid road tile */
 
	if (HASBIT(p2, 2) && !(IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_NORMAL)) return CMD_ERROR;
 
	/* If overbuilding a town road,check tile is town owned and patch setting is enabled */
 
	if (HASBIT(p2, 3) && !(_patches.road_stop_on_town_road && IsTileOwner(tile, OWNER_TOWN))) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
 
		return CMD_ERROR;
 

	
 
	ret = CheckFlatLandBelow(tile, 1, 1, flags, 1 << p1, NULL);
 
	if (is_drive_through & HASBIT(p2, 3)) _current_player = OWNER_TOWN;
 
	ret = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL);
 
	_current_player = cur_owner;
 
	if (CmdFailed(ret)) return ret;
 
	cost = ret;
 
	cost = HASBIT(p2, 2) ? 0 : ret; // Don't add cost of clearing road when overbuilding
 

	
 
	st = GetStationAround(tile, 1, 1, INVALID_STATION);
 
	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
@@ -1333,7 +1347,8 @@ int32 CmdBuildRoadStop(TileIndex tile, u
 

	
 
		st->rect.BeforeAddTile(tile, StationRect::ADD_TRY);
 

	
 
		MakeRoadStop(tile, st->owner, st->index, type ? RoadStop::TRUCK : RoadStop::BUS, (DiagDirection)p1);
 
		MakeRoadStop(tile, st->owner, st->index, type ? RoadStop::TRUCK : RoadStop::BUS, is_drive_through, (DiagDirection)p1);
 
		if (is_drive_through & HASBIT(p2, 3)) SetStopBuiltOnTownRoad(tile);
 

	
 
		UpdateStationVirtCoordDirty(st);
 
		UpdateStationAcceptance(st, false);
 
@@ -1395,7 +1410,44 @@ static int32 RemoveRoadStop(Station *st,
 
	return (is_truck) ? _price.remove_truck_station : _price.remove_bus_station;
 
}
 

	
 

	
 
/** Remove a bus or truck stop
 
 * @param tile tile to remove the stop from
 
 * @param p1 not used
 
 * @param p2 bit 0: 0 for Bus stops, 1 for truck stops
 
 */
 
int32 CmdRemoveRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Station* st;
 
	bool is_drive_through;
 
	bool is_towns_road = false;
 
	RoadBits road_bits;
 
	int32 ret;
 

	
 
	/* Make sure the specified tile is a road stop of the correct type */
 
	if (!IsTileType(tile, MP_STATION) || !IsRoadStop(tile) || (uint32)GetRoadStopType(tile) != p2) return CMD_ERROR;
 
	st = GetStationByTile(tile);
 
	/* Save the stop info before it is removed */
 
	is_drive_through = IsDriveThroughStopTile(tile);
 
	road_bits = GetAnyRoadBits(tile);
 
	if (is_drive_through) is_towns_road = GetStopBuiltOnTownRoad(tile);
 

	
 
	ret = RemoveRoadStop(st, flags, tile);
 

	
 
	/* If the stop was a drive-through stop replace the road */
 
	if ((flags & DC_EXEC) && !CmdFailed(ret) && is_drive_through) {
 
		uint index = 0;
 
		Owner cur_owner = _current_player;
 

	
 
		if (is_towns_road) {
 
			index = ClosestTownFromTile(tile, _patches.dist_local_authority)->index;
 
			_current_player = OWNER_TOWN;
 
		}
 
		DoCommand(tile, road_bits, index, DC_EXEC, CMD_BUILD_ROAD);
 
		_current_player = cur_owner;
 
	}
 

	
 
	return ret;
 
}
 

	
 
// FIXME -- need to move to its corresponding Airport variable
 
// Country Airfield (small)
 
@@ -2227,6 +2279,27 @@ static uint32 VehicleEnter_Station(Vehic
 
				/* Attempt to allocate a parking bay in a road stop */
 
				RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
 

	
 
				if (IsDriveThroughStopTile(tile)) {
 
					/* 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) == ((v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) &&
 
							v->current_order.dest == GetStationIndex(tile)) {
 
						SETBIT(v->u.road.state, RVS_IS_STOPPING);
 
						rs->AllocateDriveThroughBay(side);
 
					}
 

	
 
					/* Indicate if vehicle is using second bay. */
 
					if (side == 1) SETBIT(v->u.road.state, RVS_USING_SECOND_BAY);
 
					/* Indicate a drive-through stop */
 
					SETBIT(v->u.road.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. */
 
				if (rs->IsEntranceBusy() || !rs->HasFreeBay()) return VETSB_CANNOT_ENTER;
 

	
 
@@ -2693,7 +2766,13 @@ static int32 ClearTile_Station(TileIndex
 
		case STATION_RAIL:    return RemoveRailroadStation(st, tile, flags);
 
		case STATION_AIRPORT: return RemoveAirport(st, flags);
 
		case STATION_TRUCK:
 
		case STATION_BUS:     return RemoveRoadStop(st, flags, tile);
 
			if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile))
 
				return_cmd_error(STR_3047_MUST_DEMOLISH_TRUCK_STATION);
 
			return RemoveRoadStop(st, flags, tile);
 
		case STATION_BUS:
 
			if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile))
 
				return_cmd_error(STR_3046_MUST_DEMOLISH_BUS_STATION);
 
			return RemoveRoadStop(st, flags, tile);
 
		case STATION_BUOY:    return RemoveBuoy(st, flags);
 
		case STATION_DOCK:    return RemoveDock(st, flags);
 
		default: break;
src/station_map.h
Show inline comments
 
@@ -42,7 +42,9 @@ enum {
 
	GFX_RADAR_DISTRICTWE_LAST     = 156,
 
	GFX_WINDSACK_INTERCON_FIRST   = 164,
 
	GFX_WINDSACK_INTERCON_LAST    = 167,
 
	GFX_BASE_END                  = 168
 
	GFX_TRUCK_BASE_EXT            = 168,
 
	GFX_BUS_BASE_EXT              = 170,
 
	GFX_BASE_END                  = 172
 
};
 

	
 
enum {
 
@@ -51,7 +53,9 @@ enum {
 
	TRUCK_SIZE = GFX_BUS_BASE - GFX_TRUCK_BASE,
 
	BUS_SIZE = GFX_OILRIG_BASE - GFX_BUS_BASE,
 
	DOCK_SIZE_TOTAL = GFX_BUOY_BASE - GFX_DOCK_BASE,
 
	AIRPORT_SIZE_EXTENDED = GFX_BASE_END - GFX_AIRPORT_BASE_EXTENDED
 
	AIRPORT_SIZE_EXTENDED = GFX_TRUCK_BASE_EXT - GFX_AIRPORT_BASE_EXTENDED,
 
	TRUCK_SIZE_EXT = GFX_BUS_BASE_EXT - GFX_TRUCK_BASE_EXT,
 
	BUS_SIZE_EXT = GFX_BASE_END - GFX_BUS_BASE_EXT,
 
};
 

	
 
typedef enum HangarTiles {
 
@@ -125,12 +129,14 @@ static inline bool IsAirport(TileIndex t
 

	
 
static inline bool IsTruckStop(TileIndex t)
 
{
 
	return IS_BYTE_INSIDE(GetStationGfx(t), GFX_TRUCK_BASE, GFX_TRUCK_BASE + TRUCK_SIZE);
 
	return (IS_BYTE_INSIDE(GetStationGfx(t), GFX_TRUCK_BASE, GFX_TRUCK_BASE + TRUCK_SIZE)) ||
 
		(IS_BYTE_INSIDE(GetStationGfx(t), GFX_TRUCK_BASE_EXT, GFX_TRUCK_BASE_EXT + TRUCK_SIZE_EXT));
 
}
 

	
 
static inline bool IsBusStop(TileIndex t)
 
{
 
	return IS_BYTE_INSIDE(GetStationGfx(t), GFX_BUS_BASE, GFX_BUS_BASE + BUS_SIZE);
 
	return (IS_BYTE_INSIDE(GetStationGfx(t), GFX_BUS_BASE, GFX_BUS_BASE + BUS_SIZE)) ||
 
		(IS_BYTE_INSIDE(GetStationGfx(t), GFX_BUS_BASE_EXT, GFX_BUS_BASE_EXT + BUS_SIZE_EXT));
 
}
 

	
 
static inline bool IsRoadStop(TileIndex t)
 
@@ -143,13 +149,44 @@ static inline bool IsRoadStopTile(TileIn
 
	return IsTileType(t, MP_STATION) && IsRoadStop(t);
 
}
 

	
 
static inline bool IsStandardRoadStopTile(TileIndex t)
 
{
 
	return IsTileType(t, MP_STATION) &&
 
		(IS_BYTE_INSIDE(GetStationGfx(t), GFX_TRUCK_BASE, GFX_TRUCK_BASE + TRUCK_SIZE) ||
 
		IS_BYTE_INSIDE(GetStationGfx(t), GFX_BUS_BASE, GFX_BUS_BASE + BUS_SIZE));
 
}
 

	
 
static inline bool IsDriveThroughStopTile(TileIndex t)
 
{
 
	return IsTileType(t, MP_STATION) &&
 
		(IS_BYTE_INSIDE(GetStationGfx(t), GFX_TRUCK_BASE_EXT, GFX_TRUCK_BASE_EXT + TRUCK_SIZE_EXT) ||
 
		IS_BYTE_INSIDE(GetStationGfx(t), GFX_BUS_BASE_EXT, GFX_BUS_BASE_EXT + BUS_SIZE_EXT));
 
}
 

	
 
static inline bool GetStopBuiltOnTownRoad(TileIndex t)
 
{
 
	assert(IsDriveThroughStopTile(t));
 
	return HASBIT(_m[t].m6, 3);
 
}
 

	
 
static inline void SetStopBuiltOnTownRoad(TileIndex t)
 
{
 
	assert(IsDriveThroughStopTile(t));
 
	SETBIT(_m[t].m6, 3);
 
}
 

	
 
/**
 
 * Gets the direction the road stop entrance points towards.
 
 */
 
static inline DiagDirection GetRoadStopDir(TileIndex t)
 
{
 
	StationGfx gfx = GetStationGfx(t);
 
	assert(IsRoadStopTile(t));
 
	return (DiagDirection)((GetStationGfx(t) - GFX_TRUCK_BASE) & 3);
 
	if (gfx < GFX_TRUCK_BASE_EXT) {
 
		return (DiagDirection)((gfx - GFX_TRUCK_BASE) & 3);
 
	} else {
 
		return (DiagDirection)((gfx - GFX_TRUCK_BASE_EXT) & 1);
 
	}
 
}
 

	
 
static inline bool IsOilRig(TileIndex t)
 
@@ -275,9 +312,13 @@ static inline void MakeRailStation(TileI
 
	SetRailType(t, rt);
 
}
 

	
 
static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStop::Type rst, DiagDirection d)
 
static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStop::Type rst, bool is_drive_through, DiagDirection d)
 
{
 
	MakeStation(t, o, sid, (rst == RoadStop::BUS ? GFX_BUS_BASE : GFX_TRUCK_BASE) + d);
 
	if (is_drive_through) {
 
		MakeStation(t, o, sid, (rst == RoadStop::BUS ? GFX_BUS_BASE_EXT : GFX_TRUCK_BASE_EXT) + d);
 
	} else {
 
		MakeStation(t, o, sid, (rst == RoadStop::BUS ? GFX_BUS_BASE : GFX_TRUCK_BASE) + d);
 
	}
 
}
 

	
 
static inline void MakeAirport(TileIndex t, Owner o, StationID sid, byte section)
src/table/sprites.h
Show inline comments
 
@@ -117,6 +117,16 @@ enum Sprites {
 
	SPR_GRASS_RIGHT = SPR_AIRPORTX_BASE + 13,
 
	SPR_GRASS_LEFT = SPR_AIRPORTX_BASE + 14,
 

	
 
	SPR_ROADSTOP_BASE = SPR_AIRPORTX_BASE + 15, // The sprites used for drive-through road stops
 
	SPR_BUS_STOP_DT_Y_W = SPR_ROADSTOP_BASE,
 
	SPR_BUS_STOP_DT_Y_E = SPR_ROADSTOP_BASE + 1,
 
	SPR_BUS_STOP_DT_X_W = SPR_ROADSTOP_BASE + 2,
 
	SPR_BUS_STOP_DT_X_E = SPR_ROADSTOP_BASE + 3,
 
	SPR_TRUCK_STOP_DT_Y_W = SPR_ROADSTOP_BASE + 4,
 
	SPR_TRUCK_STOP_DT_Y_E = SPR_ROADSTOP_BASE + 5,
 
	SPR_TRUCK_STOP_DT_X_W = SPR_ROADSTOP_BASE + 6,
 
	SPR_TRUCK_STOP_DT_X_E = SPR_ROADSTOP_BASE + 7,
 

	
 
	/* Manager face sprites */
 
	SPR_GRADIENT = 874, // background gradient behind manager face
 

	
 
@@ -295,6 +305,10 @@ enum Sprites {
 
	SPR_PYLON_NS_W = SPR_ELRAIL_BASE + 37,
 
	SPR_PYLON_NS_E = SPR_ELRAIL_BASE + 38,
 

	
 
	/* sprites for roads */
 
	SPR_ROAD_PAVED_STRAIGHT_Y       = 1313,
 
	SPR_ROAD_PAVED_STRAIGHT_X       = 1314,
 

	
 
	/* sprites for airports and airfields*/
 
	/* Small airports are AIRFIELD, everything else is AIRPORT */
 
	SPR_HELIPORT                    = 2633,
src/table/station_land.h
Show inline comments
 
@@ -959,6 +959,34 @@ static const DrawTileSeqStruct _station_
 
	TILE_SEQ_END()
 
};
 

	
 
// drive-through truck stop X
 
static const DrawTileSeqStruct _station_display_datas_0168[] = {
 
	{  1,  0,  0,  14,  3, 10, SPR_TRUCK_STOP_DT_X_W | (1 << PALETTE_MODIFIER_COLOR), PAL_NONE },
 
	{  1, 13,  0,  14,  1, 10, SPR_TRUCK_STOP_DT_X_E | (1 << PALETTE_MODIFIER_COLOR), PAL_NONE },
 
	TILE_SEQ_END()
 
};
 

	
 
// drive-through truck stop Y
 
static const DrawTileSeqStruct _station_display_datas_0169[] = {
 
	{ 13,  1,  0,  1, 14, 10, SPR_TRUCK_STOP_DT_Y_W | (1 << PALETTE_MODIFIER_COLOR), PAL_NONE },
 
	{  0,  1,  0,  3, 14, 10, SPR_TRUCK_STOP_DT_Y_E | (1 << PALETTE_MODIFIER_COLOR), PAL_NONE },
 
	TILE_SEQ_END()
 
};
 

	
 
// drive-through bus stop X
 
static const DrawTileSeqStruct _station_display_datas_0170[] = {
 
	{  5,  0,  0,  8,  3, 10, SPR_BUS_STOP_DT_X_W | (1 << PALETTE_MODIFIER_COLOR), PAL_NONE },
 
	{  5, 14,  0,  8,  1, 10, SPR_BUS_STOP_DT_X_E | (1 << PALETTE_MODIFIER_COLOR), PAL_NONE },
 
	TILE_SEQ_END()
 
};
 

	
 
// drive-through bus stop Y
 
static const DrawTileSeqStruct _station_display_datas_0171[] = {
 
	{ 13,  5,  0,  1,  8, 10, SPR_BUS_STOP_DT_Y_W | (1 << PALETTE_MODIFIER_COLOR), PAL_NONE },
 
	{  0,  5,  0,  3,  8, 10, SPR_BUS_STOP_DT_Y_E | (1 << PALETTE_MODIFIER_COLOR), PAL_NONE },
 
	TILE_SEQ_END()
 
};
 

	
 
static const DrawTileSprites _station_display_datas[] = {
 
	{ SPR_RAIL_TRACK_X,               PAL_NONE, _station_display_datas_0 },
 
	{ SPR_RAIL_TRACK_Y,               PAL_NONE, _station_display_datas_1 },
 
@@ -1128,4 +1156,8 @@ static const DrawTileSprites _station_di
 
	{ SPR_FLAT_GRASS_TILE,            PAL_NONE, _station_display_datas_59 },
 
	{ SPR_FLAT_GRASS_TILE,            PAL_NONE, _station_display_datas_60 },
 
	{ SPR_FLAT_GRASS_TILE,            PAL_NONE, _station_display_datas_61 },
 
	{ SPR_ROAD_PAVED_STRAIGHT_X,      PAL_NONE, _station_display_datas_0168 },
 
	{ SPR_ROAD_PAVED_STRAIGHT_Y,      PAL_NONE, _station_display_datas_0169 },
 
	{ SPR_ROAD_PAVED_STRAIGHT_X,      PAL_NONE, _station_display_datas_0170 },
 
	{ SPR_ROAD_PAVED_STRAIGHT_Y,      PAL_NONE, _station_display_datas_0171 }
 
};
src/variables.h
Show inline comments
 
@@ -166,6 +166,7 @@ typedef struct Patches {
 
	bool autosave_on_exit;              // save an autosave when you quit the game, but do not ask "Do you really want to quit?"
 
	byte max_num_autosaves;             // controls how many autosavegames are made before the game starts to overwrite (names them 0 to max_num_autosaves - 1)
 
	bool extra_dynamite;                // extra dynamite
 
	bool road_stop_on_town_road;        // allow building of drive-through road stops on town owned roads
 

	
 
	bool never_expire_vehicles;         // never expire vehicles
 
	byte extend_vehicle_life;           // extend vehicle life by this many years
 
@@ -211,6 +212,7 @@ typedef struct Patches {
 
	uint32 npf_water_curve_penalty;        /* The penalty for curves */
 
	uint32 npf_road_curve_penalty;         /* The penalty for curves */
 
	uint32 npf_crossing_penalty;           /* The penalty for level crossings */
 
	uint32 npf_road_drive_through_penalty; /* The penalty for going through a drive-through road stop */
 

	
 
	bool population_in_label; // Show the population of a town in his label?
 

	
src/vehicle.cpp
Show inline comments
 
@@ -2756,9 +2756,11 @@ Trackdir GetVehicleTrackdir(const Vehicl
 
			if (IsRoadVehInDepot(v)) /* We'll assume the road vehicle is facing outwards */
 
				return DiagdirToDiagTrackdir(GetRoadDepotDirection(v->tile));
 

	
 
			if (IsRoadStopTile(v->tile)) /* We'll assume the road vehicle is facing outwards */
 
			if (IsStandardRoadStopTile(v->tile)) /* We'll assume the road vehicle is facing outwards */
 
				return DiagdirToDiagTrackdir(GetRoadStopDir(v->tile)); /* Road vehicle in a station */
 

	
 
			if (IsDriveThroughStopTile(v->tile)) return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
 

	
 
			/* If vehicle's state is a valid track direction (vehicle is not turning around) return it */
 
			if (!IsReversingRoadTrackdir((Trackdir)v->u.road.state)) return (Trackdir)v->u.road.state;
 

	
src/vehicle.h
Show inline comments
 
@@ -45,14 +45,18 @@ enum RoadVehicleStates {
 

	
 
	/* Bit numbers */
 
	RVS_USING_SECOND_BAY         =    1,                      ///< Only used while in a road stop
 
	RVS_IS_STOPPING              =    2,                      ///< Only used for drive-through stops. Vehicle will stop here
 
	RVS_DRIVE_SIDE               =    4,                      ///< Only used when retrieving move data and for turning vehicles
 
	RVS_IN_ROAD_STOP             =    5,                      ///< The vehicle is in a road stop
 
	RVS_IN_DT_ROAD_STOP          =    6,                      ///< The vehicle is in a drive-through road stop
 

	
 
	/* Bit sets of the above specified bits */
 
	RVSB_USING_SECOND_BAY        = 1 << RVS_USING_SECOND_BAY, ///< Only used while in a road stop
 
	RVSB_DRIVE_SIDE              = 1 << RVS_DRIVE_SIDE,       ///< Only used when retrieving move data and for turning vehicles
 
	RVSB_IN_ROAD_STOP            = 1 << RVS_IN_ROAD_STOP,     ///< The vehicle is in a road stop
 
	RVSB_IN_ROAD_STOP_END        = RVSB_IN_ROAD_STOP + TRACKDIR_END,
 
	RVSB_IN_DT_ROAD_STOP         = 1 << RVS_IN_DT_ROAD_STOP,  ///< The vehicle is in a drive-through road stop
 
	RVSB_IN_DT_ROAD_STOP_END     = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END,
 

	
 
	RVSB_TRACKDIR_MASK           = 0x0F,                      ///< The mask used to extract track dirs
 
	RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09                       ///< Only bits 0 and 3 are used to encode the trackdir for road stops
src/yapf/follow_track.hpp
Show inline comments
 
@@ -121,8 +121,8 @@ protected:
 
	/** return true if we can leave m_old_tile in m_exitdir */
 
	FORCEINLINE bool CanExitOldTile()
 
	{
 
		// road stop can be left at one direction only
 
		if (IsRoadTT() && IsRoadStopTile(m_old_tile)) {
 
		// road stop can be left at one direction only unless it's a drive-through stop
 
		if (IsRoadTT() && IsStandardRoadStopTile(m_old_tile)) {
 
			DiagDirection exitdir = GetRoadStopDir(m_old_tile);
 
			if (exitdir != m_exitdir)
 
				return false;
 
@@ -140,8 +140,8 @@ protected:
 
	/** return true if we can enter m_new_tile from m_exitdir */
 
	FORCEINLINE bool CanEnterNewTile()
 
	{
 
		if (IsRoadTT() && IsRoadStopTile(m_new_tile)) {
 
			// road stop can be entered from one direction only
 
		if (IsRoadTT() && IsStandardRoadStopTile(m_new_tile)) {
 
			// road stop can be entered from one direction only unless it's a drive-through stop
 
			DiagDirection exitdir = GetRoadStopDir(m_new_tile);
 
			if (ReverseDiagDir(exitdir) != m_exitdir)
 
				return false;
src/yapf/yapf_road.cpp
Show inline comments
 
@@ -51,6 +51,10 @@ protected:
 
					if (IsLevelCrossing(tile))
 
						cost += Yapf().PfGetSettings().road_crossing_penalty;
 
					break;
 
				case MP_STATION:
 
					if (IsDriveThroughStopTile(tile))
 
						cost += Yapf().PfGetSettings().road_stop_penalty;
 
					break;
 

	
 
				default:
 
					break;
 
@@ -76,6 +80,10 @@ public:
 
			// base tile cost depending on distance between edges
 
			segment_cost += Yapf().OneTileCost(tile, trackdir);
 

	
 
			const Vehicle* v = Yapf().GetVehicle();
 
			// we have reached the vehicle's destination - segment should end here to avoid target skipping
 
			if (v->current_order.type == OT_GOTO_STATION && tile == v->dest_tile) break;
 

	
 
			// stop if we have just entered the depot
 
			if (IsTileDepotType(tile, TRANSPORT_ROAD) && trackdir == DiagdirToDiagTrackdir(ReverseDiagDir(GetRoadDepotDirection(tile)))) {
 
				// next time we will reverse and leave the depot
 
@@ -103,7 +111,6 @@ public:
 
			// add min/max speed penalties
 
			int min_speed = 0;
 
			int max_speed = F.GetSpeedLimit(&min_speed);
 
			const Vehicle* v = Yapf().GetVehicle();
 
			if (max_speed < v->max_speed) segment_cost += 1 * (v->max_speed - max_speed);
 
			if (min_speed > v->max_speed) segment_cost += 10 * (min_speed - v->max_speed);
 

	
src/yapf/yapf_settings.h
Show inline comments
 
@@ -39,6 +39,7 @@ YS_DEF_BEGIN
 
	YS_DEF(uint32, road_slope_penalty)         ///< penalty for up-hill slope
 
	YS_DEF(uint32, road_curve_penalty)         ///< penalty for curves
 
	YS_DEF(uint32, road_crossing_penalty)      ///< penalty for level crossing
 
	YS_DEF(uint32, road_stop_penalty)          ///< penalty for going through a drive-through road stop
 
	YS_DEF(bool  , rail_firstred_twoway_eol)   ///< treat first red two-way signal as dead end
 
	YS_DEF(uint32, rail_firstred_penalty)      ///< penalty for first red signal
 
	YS_DEF(uint32, rail_firstred_exit_penalty) ///< penalty for first red exit signal
0 comments (0 inline, 0 general)