From 102c7ae60ea5339268a9bcf42b3c695c04d77afb Mon Sep 17 00:00:00 2001 From: truebrain Date: Mon, 19 Dec 2011 21:02:33 +0000 Subject: [PATCH] (svn r23629) -Add: allow ScriptRoad::BuildRoad, ScriptBridge::BuildBridge (for roads) and ScriptTunnel:BuildTunnel (for roads) to work for GameScript --- src/command.cpp | 8 ++-- src/road.cpp | 2 +- src/road_cmd.cpp | 30 +++++++++----- src/script/api/game/game_bridge.hpp.sq | 1 + src/script/api/game/game_road.hpp.sq | 2 + src/script/api/game/game_tile.hpp.sq | 1 + src/script/api/game/game_tunnel.hpp.sq | 1 + src/script/api/script_bridge.cpp | 2 + src/script/api/script_bridge.hpp | 3 +- src/script/api/script_road.hpp | 4 +- src/script/api/script_tile.hpp | 1 - src/script/api/script_tunnel.cpp | 2 + src/script/api/script_tunnel.hpp | 3 +- src/tunnelbridge_cmd.cpp | 54 +++++++++++++++++++------- 14 files changed, 81 insertions(+), 33 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 677b748644..b345382948 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -194,14 +194,14 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdBuildSingleRail, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SINGLE_RAIL DEF_CMD(CmdRemoveSingleRail, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SINGLE_RAIL DEF_CMD(CmdLandscapeClear, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_LANDSCAPE_CLEAR - DEF_CMD(CmdBuildBridge, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_BRIDGE + DEF_CMD(CmdBuildBridge, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_BRIDGE DEF_CMD(CmdBuildRailStation, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_RAIL_STATION DEF_CMD(CmdBuildTrainDepot, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_TRAIN_DEPOT DEF_CMD(CmdBuildSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SIGNALS DEF_CMD(CmdRemoveSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SIGNALS DEF_CMD(CmdTerraformLand, CMD_ALL_TILES | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_TERRAFORM_LAND DEF_CMD(CmdBuildObject, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_OBJECT - DEF_CMD(CmdBuildTunnel, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_TUNNEL + DEF_CMD(CmdBuildTunnel, CMD_DEITY | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_TUNNEL DEF_CMD(CmdRemoveFromRailStation, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_FROM_RAIL_STATION DEF_CMD(CmdConvertRail, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_CONVERT_RAILD DEF_CMD(CmdBuildRailWaypoint, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_RAIL_WAYPOINT @@ -210,9 +210,9 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdBuildRoadStop, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD_STOP DEF_CMD(CmdRemoveRoadStop, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_ROAD_STOP - DEF_CMD(CmdBuildLongRoad, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_LONG_ROAD + DEF_CMD(CmdBuildLongRoad,CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_LONG_ROAD DEF_CMD(CmdRemoveLongRoad, CMD_NO_TEST | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_LONG_ROAD; towns may disallow removing road bits (as they are connected) in test, but in exec they're removed and thus removing is allowed. - DEF_CMD(CmdBuildRoad, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD + DEF_CMD(CmdBuildRoad, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD DEF_CMD(CmdBuildRoadDepot, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD_DEPOT DEF_CMD(CmdBuildAirport, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_AIRPORT diff --git a/src/road.cpp b/src/road.cpp index 3b175d1092..fad4cbce15 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -106,7 +106,7 @@ bool HasRoadTypesAvail(const CompanyID company, const RoadTypes rts) { RoadTypes avail_roadtypes; - if (company == OWNER_TOWN || _game_mode == GM_EDITOR || _generating_world) { + if (company == OWNER_DEITY || company == OWNER_TOWN || _game_mode == GM_EDITOR || _generating_world) { avail_roadtypes = ROADTYPES_ROAD; } else { Company *c = Company::GetIfValid(company); diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 3df83c821c..5094808456 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -478,6 +478,7 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existi */ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { + CompanyID company = _current_company; CommandCost cost(EXPENSES_CONSTRUCTION); RoadBits existing = ROAD_NONE; @@ -485,10 +486,19 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero * if a non-company is building the road */ - if ((Company::IsValidID(_current_company) && p2 != 0) || (_current_company == OWNER_TOWN && !Town::IsValidID(p2))) return CMD_ERROR; - if (_current_company != OWNER_TOWN) { + if ((Company::IsValidID(company) && p2 != 0) || (company == OWNER_TOWN && !Town::IsValidID(p2)) || (company == OWNER_DEITY && p2 != 0)) return CMD_ERROR; + if (company != OWNER_TOWN) { const Town *town = CalcClosestTownFromTile(tile); p2 = (town != NULL) ? town->index : (TownID)INVALID_TOWN; + + if (company == OWNER_DEITY) { + company = OWNER_TOWN; + + /* If we are not within a town, we are not owned by the town */ + if (town == NULL || DistanceSquare(tile, town->xy) > town->squared_town_zone_radius[HZB_TOWN_EDGE]) { + company = OWNER_NONE; + } + } } RoadBits pieces = Extract(p1); @@ -608,11 +618,11 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 Track railtrack = AxisToTrack(OtherAxis(roaddir)); YapfNotifyTrackLayoutChange(tile, railtrack); /* Update company infrastructure counts. A level crossing has two road bits. */ - Company *c = Company::GetIfValid(_current_company); + Company *c = Company::GetIfValid(company); if (c != NULL) { c->infrastructure.road[rt] += 2; if (rt != ROADTYPE_ROAD) c->infrastructure.road[ROADTYPE_ROAD] += 2; - DirtyCompanyInfrastructureWindows(_current_company); + DirtyCompanyInfrastructureWindows(company); } /* Update rail count for level crossings. The plain track is already * counted, so only add the difference to the level crossing cost. */ @@ -621,7 +631,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Always add road to the roadtypes (can't draw without it) */ bool reserved = HasBit(GetRailReservationTrackBits(tile), railtrack); - MakeRoadCrossing(tile, _current_company, _current_company, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2); + MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2); SetCrossingReservation(tile, reserved); UpdateLevelCrossing(tile, false); MarkTileDirtyByTile(tile); @@ -717,7 +727,7 @@ do_clear:; RoadTileType rtt = GetRoadTileType(tile); if (existing == ROAD_NONE || rtt == ROAD_TILE_CROSSING) { SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); - SetRoadOwner(tile, rt, _current_company); + SetRoadOwner(tile, rt, company); if (rt == ROADTYPE_ROAD) SetTownIndex(tile, p2); } if (rtt != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rt); @@ -729,8 +739,8 @@ do_clear:; SetRoadTypes(other_end, GetRoadTypes(other_end) | RoadTypeToRoadTypes(rt)); SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); - SetRoadOwner(other_end, rt, _current_company); - SetRoadOwner(tile, rt, _current_company); + SetRoadOwner(other_end, rt, company); + SetRoadOwner(tile, rt, company); /* Mark tiles dirty that have been repaved */ MarkTileDirtyByTile(other_end); @@ -746,11 +756,11 @@ do_clear:; case MP_STATION: assert(IsDriveThroughStopTile(tile)); SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); - SetRoadOwner(tile, rt, _current_company); + SetRoadOwner(tile, rt, company); break; default: - MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, _current_company, _current_company); + MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, company, company); break; } diff --git a/src/script/api/game/game_bridge.hpp.sq b/src/script/api/game/game_bridge.hpp.sq index d4c2d05838..56b327471b 100644 --- a/src/script/api/game/game_bridge.hpp.sq +++ b/src/script/api/game/game_bridge.hpp.sq @@ -42,6 +42,7 @@ void SQGSBridge_Register(Squirrel *engine) SQGSBridge.DefSQStaticMethod(engine, &ScriptBridge::GetPrice, "GetPrice", 3, ".ii"); SQGSBridge.DefSQStaticMethod(engine, &ScriptBridge::GetMaxLength, "GetMaxLength", 2, ".i"); SQGSBridge.DefSQStaticMethod(engine, &ScriptBridge::GetMinLength, "GetMinLength", 2, ".i"); + SQGSBridge.DefSQStaticMethod(engine, &ScriptBridge::BuildBridge, "BuildBridge", 5, ".iiii"); SQGSBridge.DefSQStaticMethod(engine, &ScriptBridge::GetOtherBridgeEnd, "GetOtherBridgeEnd", 2, ".i"); SQGSBridge.PostRegister(engine); diff --git a/src/script/api/game/game_road.hpp.sq b/src/script/api/game/game_road.hpp.sq index 5dd857dedf..f398b6b003 100644 --- a/src/script/api/game/game_road.hpp.sq +++ b/src/script/api/game/game_road.hpp.sq @@ -59,6 +59,8 @@ void SQGSRoad_Register(Squirrel *engine) SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetRoadDepotFrontTile, "GetRoadDepotFrontTile", 2, ".i"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetRoadStationFrontTile, "GetRoadStationFrontTile", 2, ".i"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetDriveThroughBackTile, "GetDriveThroughBackTile", 2, ".i"); + SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::BuildRoad, "BuildRoad", 3, ".ii"); + SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::BuildRoadFull, "BuildRoadFull", 3, ".ii"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetBuildCost, "GetBuildCost", 3, ".ii"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetMaintenanceCostFactor, "GetMaintenanceCostFactor", 2, ".i"); diff --git a/src/script/api/game/game_tile.hpp.sq b/src/script/api/game/game_tile.hpp.sq index 53e02578b3..a25a175b52 100644 --- a/src/script/api/game/game_tile.hpp.sq +++ b/src/script/api/game/game_tile.hpp.sq @@ -77,6 +77,7 @@ void SQGSTile_Register(Squirrel *engine) ScriptError::RegisterErrorMapString(ScriptTile::ERR_AREA_ALREADY_FLAT, "ERR_AREA_ALREADY_FLAT"); ScriptError::RegisterErrorMapString(ScriptTile::ERR_EXCAVATION_WOULD_DAMAGE, "ERR_EXCAVATION_WOULD_DAMAGE"); + SQGSTile.DefSQStaticMethod(engine, &ScriptTile::IsBuildable, "IsBuildable", 2, ".i"); SQGSTile.DefSQStaticMethod(engine, &ScriptTile::IsBuildableRectangle, "IsBuildableRectangle", 4, ".iii"); SQGSTile.DefSQStaticMethod(engine, &ScriptTile::IsWaterTile, "IsWaterTile", 2, ".i"); SQGSTile.DefSQStaticMethod(engine, &ScriptTile::IsCoastTile, "IsCoastTile", 2, ".i"); diff --git a/src/script/api/game/game_tunnel.hpp.sq b/src/script/api/game/game_tunnel.hpp.sq index 49a6311def..e2d94bfcdd 100644 --- a/src/script/api/game/game_tunnel.hpp.sq +++ b/src/script/api/game/game_tunnel.hpp.sq @@ -39,6 +39,7 @@ void SQGSTunnel_Register(Squirrel *engine) SQGSTunnel.DefSQStaticMethod(engine, &ScriptTunnel::IsTunnelTile, "IsTunnelTile", 2, ".i"); SQGSTunnel.DefSQStaticMethod(engine, &ScriptTunnel::GetOtherTunnelEnd, "GetOtherTunnelEnd", 2, ".i"); + SQGSTunnel.DefSQStaticMethod(engine, &ScriptTunnel::BuildTunnel, "BuildTunnel", 3, ".ii"); SQGSTunnel.PostRegister(engine); } diff --git a/src/script/api/script_bridge.cpp b/src/script/api/script_bridge.cpp index da74712ccb..c2cbfcde0a 100644 --- a/src/script/api/script_bridge.cpp +++ b/src/script/api/script_bridge.cpp @@ -17,6 +17,7 @@ #include "../../strings_func.h" #include "../../economy_func.h" #include "../../date_func.h" +#include "../../company_func.h" /* static */ bool ScriptBridge::IsValidBridge(BridgeID bridge_id) { @@ -74,6 +75,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) EnforcePrecondition(false, TileX(start) == TileX(end) || TileY(start) == TileY(end)); EnforcePrecondition(false, vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER); EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_RAIL || ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType())); + EnforcePrecondition(false, _current_company != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD); uint type = 0; switch (vehicle_type) { diff --git a/src/script/api/script_bridge.hpp b/src/script/api/script_bridge.hpp index 16fe8d6b8f..2677826031 100644 --- a/src/script/api/script_bridge.hpp +++ b/src/script/api/script_bridge.hpp @@ -135,6 +135,7 @@ public: * ScriptMap::GetTileY(start) == ScriptMap::GetTileY(end). * @pre vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_WATER || * (vehicle_type == ScriptVehicle::VT_RAIL && ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType())). + * @game @pre Outside CompanyMode: vehicle_type == ScriptVehicle::VT_ROAD. * @exception ScriptError::ERR_ALREADY_BUILT * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_LAND_SLOPED_WRONG @@ -143,9 +144,9 @@ public: * @exception ScriptBridge::ERR_BRIDGE_CANNOT_END_IN_WATER * @exception ScriptBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT * @return Whether the bridge has been/can be build or not. + * @game @note Building a bridge (without CompanyMode) results in a bridge owned by towns. * @note No matter if the road pieces were build or not, if building the * bridge succeeded, this function returns true. - * @api -game */ static bool BuildBridge(ScriptVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end); diff --git a/src/script/api/script_road.hpp b/src/script/api/script_road.hpp index c655ca51e1..062a15ddf3 100644 --- a/src/script/api/script_road.hpp +++ b/src/script/api/script_road.hpp @@ -265,8 +265,8 @@ public: * @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS * @exception ScriptError::ERR_VEHICLE_IN_THE_WAY * @note Construction will fail if an obstacle is found between the start and end tiles. + * @game @note Building a piece of road (without CompanyMode) results in a piece of road owned by towns. * @return Whether the road has been/can be build or not. - * @api -game */ static bool BuildRoad(TileIndex start, TileIndex end); @@ -317,8 +317,8 @@ public: * @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS * @exception ScriptError::ERR_VEHICLE_IN_THE_WAY * @note Construction will fail if an obstacle is found between the start and end tiles. + * @game @note Building a piece of road (without CompanyMode) results in a piece of road owned by towns. * @return Whether the road has been/can be build or not. - * @api -game */ static bool BuildRoadFull(TileIndex start, TileIndex end); diff --git a/src/script/api/script_tile.hpp b/src/script/api/script_tile.hpp index f5fe509937..e9155f7459 100644 --- a/src/script/api/script_tile.hpp +++ b/src/script/api/script_tile.hpp @@ -130,7 +130,6 @@ public: * as you can build tram-rails on road-tiles. * @note For rail you also might want to check for ScriptRoad::IsRoad(), * as in some cases you can build rails on road-tiles. - * @api -game */ static bool IsBuildable(TileIndex tile); diff --git a/src/script/api/script_tunnel.cpp b/src/script/api/script_tunnel.cpp index 10b99d2f29..f851853c80 100644 --- a/src/script/api/script_tunnel.cpp +++ b/src/script/api/script_tunnel.cpp @@ -15,6 +15,7 @@ #include "../script_instance.hpp" #include "../../tunnel_map.h" #include "../../command_func.h" +#include "../../company_func.h" /* static */ bool ScriptTunnel::IsTunnelTile(TileIndex tile) { @@ -83,6 +84,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) EnforcePrecondition(false, ::IsValidTile(start)); EnforcePrecondition(false, vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_ROAD); EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_RAIL || ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType())); + EnforcePrecondition(false, _current_company != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD); uint type = 0; if (vehicle_type == ScriptVehicle::VT_ROAD) { diff --git a/src/script/api/script_tunnel.hpp b/src/script/api/script_tunnel.hpp index 1ae9c4d1b7..fbd30b19e6 100644 --- a/src/script/api/script_tunnel.hpp +++ b/src/script/api/script_tunnel.hpp @@ -87,6 +87,7 @@ public: * @pre ScriptMap::IsValidTile(start). * @pre vehicle_type == ScriptVehicle::VT_ROAD || (vehicle_type == ScriptVehicle::VT_RAIL && * ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType())). + * @game @pre Outside CompanyMode: vehicle_type == ScriptVehicle::VT_ROAD. * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptTunnel::ERR_TUNNEL_CANNOT_BUILD_ON_WATER * @exception ScriptTunnel::ERR_TUNNEL_START_SITE_UNSUITABLE @@ -96,7 +97,7 @@ public: * @note The slope of a tile can be determined by ScriptTile::GetSlope(TileIndex). * @note No matter if the road pieces were build or not, if building the * tunnel succeeded, this function returns true. - * @api -game + * @game @note Building a bridge (without CompanyMode) results in a bridge owned by towns. */ static bool BuildTunnel(ScriptVehicle::VehicleType vehicle_type, TileIndex start); diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 24dbcff6bb..6d6a1d78cf 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -212,6 +212,8 @@ CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoC */ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { + CompanyID company = _current_company; + RailType railtype = INVALID_RAILTYPE; RoadTypes roadtypes = ROADTYPES_NONE; @@ -226,7 +228,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u switch (transport_type) { case TRANSPORT_ROAD: roadtypes = Extract(p2); - if (!HasExactlyOneBit(roadtypes) || !HasRoadTypesAvail(_current_company, roadtypes)) return CMD_ERROR; + if (!HasExactlyOneBit(roadtypes) || !HasRoadTypesAvail(company, roadtypes)) return CMD_ERROR; break; case TRANSPORT_RAIL: @@ -244,6 +246,18 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u TileIndex tile_start = p1; TileIndex tile_end = end_tile; + if (company == OWNER_DEITY) { + if (transport_type != TRANSPORT_ROAD) return CMD_ERROR; + const Town *town = CalcClosestTownFromTile(tile_start); + + company = OWNER_TOWN; + + /* If we are not within a town, we are not owned by the town */ + if (town == NULL || DistanceSquare(tile_start, town->xy) > town->squared_town_zone_radius[HZB_TOWN_EDGE]) { + company = OWNER_NONE; + } + } + if (tile_start == tile_end) { return_cmd_error(STR_ERROR_CAN_T_START_AND_END_ON); } @@ -312,7 +326,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u } /* Do not allow replacing another company's bridges. */ - if (!IsTileOwner(tile_start, _current_company) && !IsTileOwner(tile_start, OWNER_TOWN)) { + if (!IsTileOwner(tile_start, company) && !IsTileOwner(tile_start, OWNER_TOWN)) { return_cmd_error(STR_ERROR_AREA_IS_OWNED_BY_ANOTHER); } @@ -424,7 +438,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u } } - owner = _current_company; + owner = company; } /* do the drill? */ @@ -475,7 +489,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u if ((flags & DC_EXEC) && transport_type == TRANSPORT_RAIL) { Track track = AxisToTrack(direction); - AddSideToSignalBuffer(tile_start, INVALID_DIAGDIR, _current_company); + AddSideToSignalBuffer(tile_start, INVALID_DIAGDIR, company); YapfNotifyTrackLayoutChange(tile_start, track); } @@ -483,7 +497,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u * It's unnecessary to execute this command every time for every bridge. So it is done only * and cost is computed in "bridge_gui.c". For AI, Towns this has to be of course calculated */ - Company *c = Company::GetIfValid(_current_company); + Company *c = Company::GetIfValid(company); if (!(flags & DC_QUERY_COST) || (c != NULL && c->is_ai)) { bridge_len += 2; // begin and end tiles/ramps @@ -520,6 +534,8 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u */ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { + CompanyID company = _current_company; + TransportType transport_type = Extract(p1); RailType railtype = INVALID_RAILTYPE; @@ -533,12 +549,24 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, case TRANSPORT_ROAD: rts = Extract(p1); - if (!HasExactlyOneBit(rts) || !HasRoadTypesAvail(_current_company, rts)) return CMD_ERROR; + if (!HasExactlyOneBit(rts) || !HasRoadTypesAvail(company, rts)) return CMD_ERROR; break; default: return CMD_ERROR; } + if (company == OWNER_DEITY) { + if (transport_type != TRANSPORT_ROAD) return CMD_ERROR; + const Town *town = CalcClosestTownFromTile(start_tile); + + company = OWNER_TOWN; + + /* If we are not within a town, we are not owned by the town */ + if (town == NULL || DistanceSquare(start_tile, town->xy) > town->squared_town_zone_radius[HZB_TOWN_EDGE]) { + company = OWNER_NONE; + } + } + int start_z; int end_z; Slope start_tileh = GetTileSlope(start_tile, &start_z); @@ -640,13 +668,13 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, } if (flags & DC_EXEC) { - Company *c = Company::GetIfValid(_current_company); + Company *c = Company::GetIfValid(company); uint num_pieces = (tiles + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; if (transport_type == TRANSPORT_RAIL) { if (!IsTunnelTile(start_tile) && c != NULL) c->infrastructure.rail[railtype] += num_pieces; - MakeRailTunnel(start_tile, _current_company, direction, railtype); - MakeRailTunnel(end_tile, _current_company, ReverseDiagDir(direction), railtype); - AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, _current_company); + MakeRailTunnel(start_tile, company, direction, railtype); + MakeRailTunnel(end_tile, company, ReverseDiagDir(direction), railtype); + AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, company); YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction)); } else { if (c != NULL) { @@ -655,10 +683,10 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, c->infrastructure.road[rt] += num_pieces * 2; // A full diagonal road has two road bits. } } - MakeRoadTunnel(start_tile, _current_company, direction, rts); - MakeRoadTunnel(end_tile, _current_company, ReverseDiagDir(direction), rts); + MakeRoadTunnel(start_tile, company, direction, rts); + MakeRoadTunnel(end_tile, company, ReverseDiagDir(direction), rts); } - DirtyCompanyInfrastructureWindows(_current_company); + DirtyCompanyInfrastructureWindows(company); } return cost;