Mercurial > hg > openttd
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 |