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 |