comparison src/station_cmd.cpp @ 6012:542153c1c803 draft

(svn r8735) -Feature: drive-through road stops made possible by the hard work of mart3p.
author rubidium <rubidium@openttd.org>
date Wed, 14 Feb 2007 16:37:16 +0000
parents 2f43f0d4d589
children 0b8944c960b5
comparison
equal deleted inserted replaced
6011:21d301b3bd81 6012:542153c1c803
33 #include "newgrf_station.h" 33 #include "newgrf_station.h"
34 #include "yapf/yapf.h" 34 #include "yapf/yapf.h"
35 #include "date.h" 35 #include "date.h"
36 #include "helpers.hpp" 36 #include "helpers.hpp"
37 #include "misc/autoptr.hpp" 37 #include "misc/autoptr.hpp"
38 #include "road.h"
38 39
39 /** 40 /**
40 * Called if a new block is added to the station-pool 41 * Called if a new block is added to the station-pool
41 */ 42 */
42 static void StationPoolNewBlock(uint start_item) 43 static void StationPoolNewBlock(uint start_item)
1245 } 1246 }
1246 1247
1247 /** Build a bus or truck stop 1248 /** Build a bus or truck stop
1248 * @param tile tile to build the stop at 1249 * @param tile tile to build the stop at
1249 * @param p1 entrance direction (DiagDirection) 1250 * @param p1 entrance direction (DiagDirection)
1250 * @param p2 0 for Bus stops, 1 for truck stops 1251 * @param p2 bit 0: 0 for Bus stops, 1 for truck stops
1252 * bit 1: 0 for normal, 1 for drive-through
1253 * bit 2: 0 for normal, 1 for build over road
1254 * bit 3: 0 for player owned road, 1 for town owned road
1251 */ 1255 */
1252 int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) 1256 int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
1253 { 1257 {
1254 Station *st; 1258 Station *st;
1255 RoadStop *road_stop; 1259 RoadStop *road_stop;
1256 int32 cost; 1260 int32 cost;
1257 int32 ret; 1261 int32 ret;
1258 bool type = !!p2; 1262 bool type = HASBIT(p2, 0);
1263 bool is_drive_through = HASBIT(p2, 1);
1264 Owner cur_owner = _current_player;
1259 1265
1260 /* Saveguard the parameters */ 1266 /* Saveguard the parameters */
1261 if (!IsValidDiagDirection((DiagDirection)p1)) return CMD_ERROR; 1267 if (!IsValidDiagDirection((DiagDirection)p1)) return CMD_ERROR;
1268 /* If it is a drive-through stop check for valid axis */
1269 if (is_drive_through && !IsValidAxis((Axis)p1)) return CMD_ERROR;
1270 /* If overbuilding a road check tile is a valid road tile */
1271 if (HASBIT(p2, 2) && !(IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_NORMAL)) return CMD_ERROR;
1272 /* If overbuilding a town road,check tile is town owned and patch setting is enabled */
1273 if (HASBIT(p2, 3) && !(_patches.road_stop_on_town_road && IsTileOwner(tile, OWNER_TOWN))) return CMD_ERROR;
1262 1274
1263 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); 1275 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
1264 1276
1265 if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) 1277 if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
1266 return CMD_ERROR; 1278 return CMD_ERROR;
1267 1279
1268 ret = CheckFlatLandBelow(tile, 1, 1, flags, 1 << p1, NULL); 1280 if (is_drive_through & HASBIT(p2, 3)) _current_player = OWNER_TOWN;
1281 ret = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL);
1282 _current_player = cur_owner;
1269 if (CmdFailed(ret)) return ret; 1283 if (CmdFailed(ret)) return ret;
1270 cost = ret; 1284 cost = HASBIT(p2, 2) ? 0 : ret; // Don't add cost of clearing road when overbuilding
1271 1285
1272 st = GetStationAround(tile, 1, 1, INVALID_STATION); 1286 st = GetStationAround(tile, 1, 1, INVALID_STATION);
1273 if (st == CHECK_STATIONS_ERR) return CMD_ERROR; 1287 if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
1274 1288
1275 /* Find a station close to us */ 1289 /* Find a station close to us */
1331 //initialize an empty station 1345 //initialize an empty station
1332 st->AddFacility((type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, tile); 1346 st->AddFacility((type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, tile);
1333 1347
1334 st->rect.BeforeAddTile(tile, StationRect::ADD_TRY); 1348 st->rect.BeforeAddTile(tile, StationRect::ADD_TRY);
1335 1349
1336 MakeRoadStop(tile, st->owner, st->index, type ? RoadStop::TRUCK : RoadStop::BUS, (DiagDirection)p1); 1350 MakeRoadStop(tile, st->owner, st->index, type ? RoadStop::TRUCK : RoadStop::BUS, is_drive_through, (DiagDirection)p1);
1351 if (is_drive_through & HASBIT(p2, 3)) SetStopBuiltOnTownRoad(tile);
1337 1352
1338 UpdateStationVirtCoordDirty(st); 1353 UpdateStationVirtCoordDirty(st);
1339 UpdateStationAcceptance(st, false); 1354 UpdateStationAcceptance(st, false);
1340 RebuildStationLists(); 1355 RebuildStationLists();
1341 InvalidateWindow(WC_STATION_LIST, st->owner); 1356 InvalidateWindow(WC_STATION_LIST, st->owner);
1393 } 1408 }
1394 1409
1395 return (is_truck) ? _price.remove_truck_station : _price.remove_bus_station; 1410 return (is_truck) ? _price.remove_truck_station : _price.remove_bus_station;
1396 } 1411 }
1397 1412
1398 1413 /** Remove a bus or truck stop
1414 * @param tile tile to remove the stop from
1415 * @param p1 not used
1416 * @param p2 bit 0: 0 for Bus stops, 1 for truck stops
1417 */
1418 int32 CmdRemoveRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
1419 {
1420 Station* st;
1421 bool is_drive_through;
1422 bool is_towns_road = false;
1423 RoadBits road_bits;
1424 int32 ret;
1425
1426 /* Make sure the specified tile is a road stop of the correct type */
1427 if (!IsTileType(tile, MP_STATION) || !IsRoadStop(tile) || (uint32)GetRoadStopType(tile) != p2) return CMD_ERROR;
1428 st = GetStationByTile(tile);
1429 /* Save the stop info before it is removed */
1430 is_drive_through = IsDriveThroughStopTile(tile);
1431 road_bits = GetAnyRoadBits(tile);
1432 if (is_drive_through) is_towns_road = GetStopBuiltOnTownRoad(tile);
1433
1434 ret = RemoveRoadStop(st, flags, tile);
1435
1436 /* If the stop was a drive-through stop replace the road */
1437 if ((flags & DC_EXEC) && !CmdFailed(ret) && is_drive_through) {
1438 uint index = 0;
1439 Owner cur_owner = _current_player;
1440
1441 if (is_towns_road) {
1442 index = ClosestTownFromTile(tile, _patches.dist_local_authority)->index;
1443 _current_player = OWNER_TOWN;
1444 }
1445 DoCommand(tile, road_bits, index, DC_EXEC, CMD_BUILD_ROAD);
1446 _current_player = cur_owner;
1447 }
1448
1449 return ret;
1450 }
1399 1451
1400 // FIXME -- need to move to its corresponding Airport variable 1452 // FIXME -- need to move to its corresponding Airport variable
1401 // Country Airfield (small) 1453 // Country Airfield (small)
1402 static const byte _airport_sections_country[] = { 1454 static const byte _airport_sections_country[] = {
1403 54, 53, 52, 65, 1455 54, 53, 52, 65,
2225 if (v->u.road.state < RVSB_IN_ROAD_STOP && v->u.road.frame == 0) { 2277 if (v->u.road.state < RVSB_IN_ROAD_STOP && v->u.road.frame == 0) {
2226 if (IsRoadStop(tile)) { 2278 if (IsRoadStop(tile)) {
2227 /* Attempt to allocate a parking bay in a road stop */ 2279 /* Attempt to allocate a parking bay in a road stop */
2228 RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile)); 2280 RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
2229 2281
2282 if (IsDriveThroughStopTile(tile)) {
2283 /* Vehicles entering a drive-through stop from the 'normal' side use first bay (bay 0). */
2284 byte side = ((DirToDiagDir(v->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (v->u.road.overtaking == 0)) ? 0 : 1;
2285
2286 if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER;
2287
2288 /* Check if the vehicle is stopping at this road stop */
2289 if (GetRoadStopType(tile) == ((v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) &&
2290 v->current_order.dest == GetStationIndex(tile)) {
2291 SETBIT(v->u.road.state, RVS_IS_STOPPING);
2292 rs->AllocateDriveThroughBay(side);
2293 }
2294
2295 /* Indicate if vehicle is using second bay. */
2296 if (side == 1) SETBIT(v->u.road.state, RVS_USING_SECOND_BAY);
2297 /* Indicate a drive-through stop */
2298 SETBIT(v->u.road.state, RVS_IN_DT_ROAD_STOP);
2299 return VETSB_CONTINUE;
2300 }
2301
2302 /* For normal (non drive-through) road stops */
2230 /* Check if station is busy or if there are no free bays. */ 2303 /* Check if station is busy or if there are no free bays. */
2231 if (rs->IsEntranceBusy() || !rs->HasFreeBay()) return VETSB_CANNOT_ENTER; 2304 if (rs->IsEntranceBusy() || !rs->HasFreeBay()) return VETSB_CANNOT_ENTER;
2232 2305
2233 SETBIT(v->u.road.state, RVS_IN_ROAD_STOP); 2306 SETBIT(v->u.road.state, RVS_IN_ROAD_STOP);
2234 2307
2691 2764
2692 switch (GetStationType(tile)) { 2765 switch (GetStationType(tile)) {
2693 case STATION_RAIL: return RemoveRailroadStation(st, tile, flags); 2766 case STATION_RAIL: return RemoveRailroadStation(st, tile, flags);
2694 case STATION_AIRPORT: return RemoveAirport(st, flags); 2767 case STATION_AIRPORT: return RemoveAirport(st, flags);
2695 case STATION_TRUCK: 2768 case STATION_TRUCK:
2696 case STATION_BUS: return RemoveRoadStop(st, flags, tile); 2769 if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile))
2770 return_cmd_error(STR_3047_MUST_DEMOLISH_TRUCK_STATION);
2771 return RemoveRoadStop(st, flags, tile);
2772 case STATION_BUS:
2773 if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile))
2774 return_cmd_error(STR_3046_MUST_DEMOLISH_BUS_STATION);
2775 return RemoveRoadStop(st, flags, tile);
2697 case STATION_BUOY: return RemoveBuoy(st, flags); 2776 case STATION_BUOY: return RemoveBuoy(st, flags);
2698 case STATION_DOCK: return RemoveDock(st, flags); 2777 case STATION_DOCK: return RemoveDock(st, flags);
2699 default: break; 2778 default: break;
2700 } 2779 }
2701 2780