220 |
220 |
221 /* type of bridge */ |
221 /* type of bridge */ |
222 switch (transport_type) { |
222 switch (transport_type) { |
223 case TRANSPORT_ROAD: |
223 case TRANSPORT_ROAD: |
224 roadtypes = (RoadTypes)GB(p2, 8, 3); |
224 roadtypes = (RoadTypes)GB(p2, 8, 3); |
225 if (!AreValidRoadTypes(roadtypes) || !HasRoadTypesAvail(_current_player, roadtypes)) return CMD_ERROR; |
225 if (!AreValidRoadTypes(roadtypes) || !HasRoadTypesAvail(_current_company, roadtypes)) return CMD_ERROR; |
226 break; |
226 break; |
227 |
227 |
228 case TRANSPORT_RAIL: |
228 case TRANSPORT_RAIL: |
229 railtype = (RailType)GB(p2, 8, 7); |
229 railtype = (RailType)GB(p2, 8, 7); |
230 if (!ValParamRailtype(railtype)) return CMD_ERROR; |
230 if (!ValParamRailtype(railtype)) return CMD_ERROR; |
302 /* Do not replace the bridge with the same bridge type. */ |
302 /* Do not replace the bridge with the same bridge type. */ |
303 if (!(flags & DC_QUERY_COST) && bridge_type == GetBridgeType(tile_start)) { |
303 if (!(flags & DC_QUERY_COST) && bridge_type == GetBridgeType(tile_start)) { |
304 return_cmd_error(STR_1007_ALREADY_BUILT); |
304 return_cmd_error(STR_1007_ALREADY_BUILT); |
305 } |
305 } |
306 |
306 |
307 /* Do not allow replacing another player's bridges. */ |
307 /* Do not allow replacing another company's bridges. */ |
308 if (!IsTileOwner(tile_start, _current_player) && !IsTileOwner(tile_start, OWNER_TOWN)) { |
308 if (!IsTileOwner(tile_start, _current_company) && !IsTileOwner(tile_start, OWNER_TOWN)) { |
309 return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER); |
309 return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER); |
310 } |
310 } |
311 |
311 |
312 cost.AddCost((bridge_len + 1) * _price.clear_bridge); // The cost of clearing the current bridge. |
312 cost.AddCost((bridge_len + 1) * _price.clear_bridge); // The cost of clearing the current bridge. |
313 replace_bridge = true; |
313 replace_bridge = true; |
316 /* Do not remove road types when upgrading a bridge */ |
316 /* Do not remove road types when upgrading a bridge */ |
317 roadtypes |= GetRoadTypes(tile_start); |
317 roadtypes |= GetRoadTypes(tile_start); |
318 } else { |
318 } else { |
319 /* Build a new bridge. */ |
319 /* Build a new bridge. */ |
320 |
320 |
321 bool allow_on_slopes = (!_is_old_ai_player && _settings_game.construction.build_on_slopes && transport_type != TRANSPORT_WATER); |
321 bool allow_on_slopes = (!_is_old_ai_company && _settings_game.construction.build_on_slopes && transport_type != TRANSPORT_WATER); |
322 |
322 |
323 /* Try and clear the start landscape */ |
323 /* Try and clear the start landscape */ |
324 ret = DoCommand(tile_start, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
324 ret = DoCommand(tile_start, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
325 if (CmdFailed(ret)) return ret; |
325 if (CmdFailed(ret)) return ret; |
326 cost = ret; |
326 cost = ret; |
362 } |
362 } |
363 |
363 |
364 /* do the drill? */ |
364 /* do the drill? */ |
365 if (flags & DC_EXEC) { |
365 if (flags & DC_EXEC) { |
366 DiagDirection dir = AxisToDiagDir(direction); |
366 DiagDirection dir = AxisToDiagDir(direction); |
367 Owner owner = (replace_bridge && IsTileOwner(tile_start, OWNER_TOWN)) ? OWNER_TOWN : _current_player; |
367 Owner owner = (replace_bridge && IsTileOwner(tile_start, OWNER_TOWN)) ? OWNER_TOWN : _current_company; |
368 |
368 |
369 switch (transport_type) { |
369 switch (transport_type) { |
370 case TRANSPORT_RAIL: |
370 case TRANSPORT_RAIL: |
371 MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype); |
371 MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype); |
372 MakeRailBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), railtype); |
372 MakeRailBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), railtype); |
441 } |
441 } |
442 } |
442 } |
443 |
443 |
444 if (flags & DC_EXEC && transport_type == TRANSPORT_RAIL) { |
444 if (flags & DC_EXEC && transport_type == TRANSPORT_RAIL) { |
445 Track track = AxisToTrack(direction); |
445 Track track = AxisToTrack(direction); |
446 AddSideToSignalBuffer(tile_start, INVALID_DIAGDIR, _current_player); |
446 AddSideToSignalBuffer(tile_start, INVALID_DIAGDIR, _current_company); |
447 YapfNotifyTrackLayoutChange(tile_start, track); |
447 YapfNotifyTrackLayoutChange(tile_start, track); |
448 } |
448 } |
449 |
449 |
450 /* for human player that builds the bridge he gets a selection to choose from bridges (DC_QUERY_COST) |
450 /* for human player that builds the bridge he gets a selection to choose from bridges (DC_QUERY_COST) |
451 * It's unnecessary to execute this command every time for every bridge. So it is done only |
451 * It's unnecessary to execute this command every time for every bridge. So it is done only |
452 * and cost is computed in "bridge_gui.c". For AI, Towns this has to be of course calculated |
452 * and cost is computed in "bridge_gui.c". For AI, Towns this has to be of course calculated |
453 */ |
453 */ |
454 if (!(flags & DC_QUERY_COST) || (IsValidPlayerID(_current_player) && GetPlayer(_current_player)->is_ai)) { |
454 if (!(flags & DC_QUERY_COST) || (IsValidCompanyID(_current_company) && GetCompany(_current_company)->is_ai)) { |
455 bridge_len += 2; // begin and end tiles/ramps |
455 bridge_len += 2; // begin and end tiles/ramps |
456 |
456 |
457 if (IsValidPlayerID(_current_player) && !_is_old_ai_player) |
457 if (IsValidCompanyID(_current_company) && !_is_old_ai_company) |
458 bridge_len = CalcBridgeLenCostFactor(bridge_len); |
458 bridge_len = CalcBridgeLenCostFactor(bridge_len); |
459 |
459 |
460 cost.AddCost((int64)bridge_len * _price.build_bridge * GetBridgeSpec(bridge_type)->price >> 8); |
460 cost.AddCost((int64)bridge_len * _price.build_bridge * GetBridgeSpec(bridge_type)->price >> 8); |
461 |
461 |
462 /* Aqueducts are a little more expensive. */ |
462 /* Aqueducts are a little more expensive. */ |
489 _build_tunnel_endtile = 0; |
489 _build_tunnel_endtile = 0; |
490 if (transport_type == TRANSPORT_RAIL) { |
490 if (transport_type == TRANSPORT_RAIL) { |
491 if (!ValParamRailtype((RailType)p1)) return CMD_ERROR; |
491 if (!ValParamRailtype((RailType)p1)) return CMD_ERROR; |
492 } else { |
492 } else { |
493 const RoadTypes rts = (RoadTypes)GB(p1, 0, 3); |
493 const RoadTypes rts = (RoadTypes)GB(p1, 0, 3); |
494 if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_player, rts)) return CMD_ERROR; |
494 if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_company, rts)) return CMD_ERROR; |
495 } |
495 } |
496 |
496 |
497 start_tileh = GetTileSlope(start_tile, &start_z); |
497 start_tileh = GetTileSlope(start_tile, &start_z); |
498 direction = GetInclinedSlopeDirection(start_tileh); |
498 direction = GetInclinedSlopeDirection(start_tileh); |
499 if (direction == INVALID_DIAGDIR) return_cmd_error(STR_500B_SITE_UNSUITABLE_FOR_TUNNEL); |
499 if (direction == INVALID_DIAGDIR) return_cmd_error(STR_500B_SITE_UNSUITABLE_FOR_TUNNEL); |
569 cost.AddCost(_price.build_tunnel); |
569 cost.AddCost(_price.build_tunnel); |
570 cost.AddCost(ret); |
570 cost.AddCost(ret); |
571 |
571 |
572 if (flags & DC_EXEC) { |
572 if (flags & DC_EXEC) { |
573 if (transport_type == TRANSPORT_RAIL) { |
573 if (transport_type == TRANSPORT_RAIL) { |
574 MakeRailTunnel(start_tile, _current_player, direction, (RailType)GB(p1, 0, 4)); |
574 MakeRailTunnel(start_tile, _current_company, direction, (RailType)GB(p1, 0, 4)); |
575 MakeRailTunnel(end_tile, _current_player, ReverseDiagDir(direction), (RailType)GB(p1, 0, 4)); |
575 MakeRailTunnel(end_tile, _current_company, ReverseDiagDir(direction), (RailType)GB(p1, 0, 4)); |
576 AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, _current_player); |
576 AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, _current_company); |
577 YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction)); |
577 YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction)); |
578 } else { |
578 } else { |
579 MakeRoadTunnel(start_tile, _current_player, direction, (RoadTypes)GB(p1, 0, 3)); |
579 MakeRoadTunnel(start_tile, _current_company, direction, (RoadTypes)GB(p1, 0, 3)); |
580 MakeRoadTunnel(end_tile, _current_player, ReverseDiagDir(direction), (RoadTypes)GB(p1, 0, 3)); |
580 MakeRoadTunnel(end_tile, _current_company, ReverseDiagDir(direction), (RoadTypes)GB(p1, 0, 3)); |
581 } |
581 } |
582 } |
582 } |
583 |
583 |
584 return cost; |
584 return cost; |
585 } |
585 } |
586 |
586 |
587 |
587 |
588 static inline bool CheckAllowRemoveTunnelBridge(TileIndex tile) |
588 static inline bool CheckAllowRemoveTunnelBridge(TileIndex tile) |
589 { |
589 { |
590 /* Floods can remove anything as well as the scenario editor */ |
590 /* Floods can remove anything as well as the scenario editor */ |
591 if (_current_player == OWNER_WATER || _game_mode == GM_EDITOR) return true; |
591 if (_current_company == OWNER_WATER || _game_mode == GM_EDITOR) return true; |
592 /* Obviously if the bridge/tunnel belongs to us, or no-one, we can remove it */ |
592 /* Obviously if the bridge/tunnel belongs to us, or no-one, we can remove it */ |
593 if (CheckTileOwnership(tile) || IsTileOwner(tile, OWNER_NONE)) return true; |
593 if (CheckTileOwnership(tile) || IsTileOwner(tile, OWNER_NONE)) return true; |
594 /* Otherwise we can only remove town-owned stuff with extra patch-settings, or cheat */ |
594 /* Otherwise we can only remove town-owned stuff with extra patch-settings, or cheat */ |
595 if (IsTileOwner(tile, OWNER_TOWN) && (_settings_game.construction.extra_dynamite || _cheats.magic_bulldozer.value)) return true; |
595 if (IsTileOwner(tile, OWNER_TOWN) && (_settings_game.construction.extra_dynamite || _cheats.magic_bulldozer.value)) return true; |
596 return false; |
596 return false; |
1293 DiagDirection dir = GetTunnelBridgeDirection(tile); |
1293 DiagDirection dir = GetTunnelBridgeDirection(tile); |
1294 if (side != INVALID_DIAGDIR && side != ReverseDiagDir(dir)) return 0; |
1294 if (side != INVALID_DIAGDIR && side != ReverseDiagDir(dir)) return 0; |
1295 return CombineTrackStatus(TrackBitsToTrackdirBits(DiagDirToDiagTrackBits(dir)), TRACKDIR_BIT_NONE); |
1295 return CombineTrackStatus(TrackBitsToTrackdirBits(DiagDirToDiagTrackBits(dir)), TRACKDIR_BIT_NONE); |
1296 } |
1296 } |
1297 |
1297 |
1298 static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, PlayerID new_player) |
1298 static void ChangeTileOwner_TunnelBridge(TileIndex tile, Owner old_owner, Owner new_owner) |
1299 { |
1299 { |
1300 if (!IsTileOwner(tile, old_player)) return; |
1300 if (!IsTileOwner(tile, old_owner)) return; |
1301 |
1301 |
1302 if (new_player != PLAYER_SPECTATOR) { |
1302 if (new_owner != INVALID_OWNER) { |
1303 SetTileOwner(tile, new_player); |
1303 SetTileOwner(tile, new_owner); |
1304 } else { |
1304 } else { |
1305 if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR))) { |
1305 if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR))) { |
1306 /* When clearing the bridge/tunnel failed there are still vehicles on/in |
1306 /* When clearing the bridge/tunnel failed there are still vehicles on/in |
1307 * the bridge/tunnel. As all *our* vehicles are already removed, they |
1307 * the bridge/tunnel. As all *our* vehicles are already removed, they |
1308 * must be of another owner. Therefore this can't be rail tunnel/bridge. |
1308 * must be of another owner. Therefore this can't be rail tunnel/bridge. |