changeset 18781:ee6ce5148ede draft

(svn r23629) -Add: allow ScriptRoad::BuildRoad, ScriptBridge::BuildBridge (for roads) and ScriptTunnel:BuildTunnel (for roads) to work for GameScript
author truebrain <truebrain@openttd.org>
date Mon, 19 Dec 2011 21:02:33 +0000
parents f5ccc1e2ae55
children d14680ee0033
files src/command.cpp src/road.cpp src/road_cmd.cpp src/script/api/game/game_bridge.hpp.sq src/script/api/game/game_road.hpp.sq src/script/api/game/game_tile.hpp.sq src/script/api/game/game_tunnel.hpp.sq src/script/api/script_bridge.cpp src/script/api/script_bridge.hpp src/script/api/script_road.hpp src/script/api/script_tile.hpp src/script/api/script_tunnel.cpp src/script/api/script_tunnel.hpp src/tunnelbridge_cmd.cpp
diffstat 14 files changed, 81 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -194,14 +194,14 @@
 	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 @@
 
 	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
--- a/src/road.cpp
+++ b/src/road.cpp
@@ -106,7 +106,7 @@
 {
 	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);
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -478,6 +478,7 @@
  */
 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 @@
 
 	/* 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<RoadBits, 0, 4>(p1);
@@ -608,11 +618,11 @@
 				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 @@
 
 				/* 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 @@
 				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 @@
 
 				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 @@
 			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;
 		}
 
--- a/src/script/api/game/game_bridge.hpp.sq
+++ b/src/script/api/game/game_bridge.hpp.sq
@@ -42,6 +42,7 @@
 	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);
--- a/src/script/api/game/game_road.hpp.sq
+++ b/src/script/api/game/game_road.hpp.sq
@@ -59,6 +59,8 @@
 	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");
 
--- a/src/script/api/game/game_tile.hpp.sq
+++ b/src/script/api/game/game_tile.hpp.sq
@@ -77,6 +77,7 @@
 	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");
--- a/src/script/api/game/game_tunnel.hpp.sq
+++ b/src/script/api/game/game_tunnel.hpp.sq
@@ -39,6 +39,7 @@
 
 	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);
 }
--- 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 @@
 	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) {
--- a/src/script/api/script_bridge.hpp
+++ b/src/script/api/script_bridge.hpp
@@ -135,6 +135,7 @@
 	 *  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 @@
 	 * @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);
 
--- a/src/script/api/script_road.hpp
+++ b/src/script/api/script_road.hpp
@@ -265,8 +265,8 @@
 	 * @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 @@
 	 * @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);
 
--- a/src/script/api/script_tile.hpp
+++ b/src/script/api/script_tile.hpp
@@ -130,7 +130,6 @@
 	 *   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);
 
--- 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 @@
 	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) {
--- a/src/script/api/script_tunnel.hpp
+++ b/src/script/api/script_tunnel.hpp
@@ -87,6 +87,7 @@
 	 * @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 @@
 	 * @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);
 
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -212,6 +212,8 @@
  */
 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 @@
 	switch (transport_type) {
 		case TRANSPORT_ROAD:
 			roadtypes = Extract<RoadTypes, 8, 2>(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 @@
 	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 @@
 		}
 
 		/* 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 @@
 			}
 		}
 
-		owner = _current_company;
+		owner = company;
 	}
 
 	/* do the drill? */
@@ -475,7 +489,7 @@
 
 	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 @@
 	 * 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 CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 {
+	CompanyID company = _current_company;
+
 	TransportType transport_type = Extract<TransportType, 8, 2>(p1);
 
 	RailType railtype = INVALID_RAILTYPE;
@@ -533,12 +549,24 @@
 
 		case TRANSPORT_ROAD:
 			rts = Extract<RoadTypes, 0, 2>(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 @@
 	}
 
 	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 @@
 					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;