4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file script_bridge.cpp Implementation of ScriptBridge. */
12 #include "../../stdafx.h"
13 #include "script_bridge.hpp"
14 #include "script_rail.hpp"
15 #include "../script_instance.hpp"
16 #include "../../bridge_map.h"
17 #include "../../strings_func.h"
18 #include "../../date_func.h"
20 #include "../../safeguards.h"
22 /* static */ bool ScriptBridge::IsValidBridge(BridgeID bridge_id
)
24 return bridge_id
< MAX_BRIDGES
&& ::GetBridgeSpec(bridge_id
)->avail_year
<= _cur_year
;
27 /* static */ bool ScriptBridge::IsBridgeTile(TileIndex tile
)
29 if (!::IsValidTile(tile
)) return false;
30 return ::IsBridgeTile(tile
);
33 /* static */ BridgeID
ScriptBridge::GetBridgeID(TileIndex tile
)
35 if (!IsBridgeTile(tile
)) return (BridgeID
)-1;
36 return (BridgeID
)::GetBridgeType(tile
);
40 * Helper function to connect a just built bridge to nearby roads.
41 * @param instance The script instance we have to built the road for.
43 static void _DoCommandReturnBuildBridge2(class ScriptInstance
*instance
)
45 if (!ScriptBridge::_BuildBridgeRoad2()) {
46 ScriptInstance::DoCommandReturn(instance
);
50 /* This can never happen, as in test-mode this callback is never executed,
51 * and in execute-mode, the other callback is called. */
56 * Helper function to connect a just built bridge to nearby roads.
57 * @param instance The script instance we have to built the road for.
59 static void _DoCommandReturnBuildBridge1(class ScriptInstance
*instance
)
61 if (!ScriptBridge::_BuildBridgeRoad1()) {
62 ScriptInstance::DoCommandReturn(instance
);
66 /* This can never happen, as in test-mode this callback is never executed,
67 * and in execute-mode, the other callback is called. */
71 /* static */ bool ScriptBridge::BuildBridge(ScriptVehicle::VehicleType vehicle_type
, BridgeID bridge_id
, TileIndex start
, TileIndex end
)
73 EnforcePrecondition(false, start
!= end
);
74 EnforcePrecondition(false, ::IsValidTile(start
) && ::IsValidTile(end
));
75 EnforcePrecondition(false, TileX(start
) == TileX(end
) || TileY(start
) == TileY(end
));
76 EnforcePrecondition(false, vehicle_type
== ScriptVehicle::VT_ROAD
|| vehicle_type
== ScriptVehicle::VT_RAIL
|| vehicle_type
== ScriptVehicle::VT_WATER
);
77 EnforcePrecondition(false, vehicle_type
!= ScriptVehicle::VT_RAIL
|| ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType()));
78 EnforcePrecondition(false, vehicle_type
!= ScriptVehicle::VT_ROAD
|| ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType()));
79 EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY
|| vehicle_type
== ScriptVehicle::VT_ROAD
);
82 switch (vehicle_type
) {
83 case ScriptVehicle::VT_ROAD
:
84 type
|= (TRANSPORT_ROAD
<< 15);
85 type
|= (::RoadTypeToRoadTypes((::RoadType
)ScriptObject::GetRoadType()) << 8);
87 case ScriptVehicle::VT_RAIL
:
88 type
|= (TRANSPORT_RAIL
<< 15);
89 type
|= (ScriptRail::GetCurrentRailType() << 8);
91 case ScriptVehicle::VT_WATER
:
92 type
|= (TRANSPORT_WATER
<< 15);
94 default: NOT_REACHED();
97 /* For rail and water we do nothing special */
98 if (vehicle_type
== ScriptVehicle::VT_RAIL
|| vehicle_type
== ScriptVehicle::VT_WATER
) {
99 return ScriptObject::DoCommand(end
, start
, type
| bridge_id
, CMD_BUILD_BRIDGE
);
102 ScriptObject::SetCallbackVariable(0, start
);
103 ScriptObject::SetCallbackVariable(1, end
);
104 return ScriptObject::DoCommand(end
, start
, type
| bridge_id
, CMD_BUILD_BRIDGE
, NULL
, &::_DoCommandReturnBuildBridge1
);
107 /* static */ bool ScriptBridge::_BuildBridgeRoad1()
109 /* Build the piece of road on the 'start' side of the bridge */
110 TileIndex end
= ScriptObject::GetCallbackVariable(0);
111 TileIndex start
= ScriptObject::GetCallbackVariable(1);
113 DiagDirection dir_1
= ::DiagdirBetweenTiles(end
, start
);
114 DiagDirection dir_2
= ::ReverseDiagDir(dir_1
);
116 return ScriptObject::DoCommand(start
+ ::TileOffsByDiagDir(dir_1
), ::DiagDirToRoadBits(dir_2
) | (ScriptObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD
, NULL
, &::_DoCommandReturnBuildBridge2
);
119 /* static */ bool ScriptBridge::_BuildBridgeRoad2()
121 /* Build the piece of road on the 'end' side of the bridge */
122 TileIndex end
= ScriptObject::GetCallbackVariable(0);
123 TileIndex start
= ScriptObject::GetCallbackVariable(1);
125 DiagDirection dir_1
= ::DiagdirBetweenTiles(end
, start
);
126 DiagDirection dir_2
= ::ReverseDiagDir(dir_1
);
128 return ScriptObject::DoCommand(end
+ ::TileOffsByDiagDir(dir_2
), ::DiagDirToRoadBits(dir_1
) | (ScriptObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD
);
131 /* static */ bool ScriptBridge::RemoveBridge(TileIndex tile
)
133 EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY
);
134 EnforcePrecondition(false, IsBridgeTile(tile
));
135 return ScriptObject::DoCommand(tile
, 0, 0, CMD_LANDSCAPE_CLEAR
);
138 /* static */ char *ScriptBridge::GetName(BridgeID bridge_id
)
140 if (!IsValidBridge(bridge_id
)) return NULL
;
142 return GetString(::GetBridgeSpec(bridge_id
)->transport_name
[0]);
145 /* static */ int32
ScriptBridge::GetMaxSpeed(BridgeID bridge_id
)
147 if (!IsValidBridge(bridge_id
)) return -1;
149 return ::GetBridgeSpec(bridge_id
)->speed
; // km-ish/h
152 /* static */ Money
ScriptBridge::GetPrice(BridgeID bridge_id
, uint length
)
154 if (!IsValidBridge(bridge_id
)) return -1;
156 return ::CalcBridgeLenCostFactor(length
) * _price
[PR_BUILD_BRIDGE
] * ::GetBridgeSpec(bridge_id
)->price
>> 8;
159 /* static */ int32
ScriptBridge::GetMaxLength(BridgeID bridge_id
)
161 if (!IsValidBridge(bridge_id
)) return -1;
163 return min(::GetBridgeSpec(bridge_id
)->max_length
, _settings_game
.construction
.max_bridge_length
) + 2;
166 /* static */ int32
ScriptBridge::GetMinLength(BridgeID bridge_id
)
168 if (!IsValidBridge(bridge_id
)) return -1;
170 return ::GetBridgeSpec(bridge_id
)->min_length
+ 2;
173 /* static */ TileIndex
ScriptBridge::GetOtherBridgeEnd(TileIndex tile
)
175 if (!::IsValidTile(tile
)) return INVALID_TILE
;
176 if (!IsBridgeTile(tile
)) return INVALID_TILE
;
178 return ::GetOtherBridgeEnd(tile
);