2009-08-21 20:21:05 +00:00
|
|
|
/*
|
|
|
|
* This file is part of OpenTTD.
|
|
|
|
* 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.
|
|
|
|
* 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.
|
|
|
|
* 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/>.
|
|
|
|
*/
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/** @file script_bridge.cpp Implementation of ScriptBridge. */
|
2009-01-12 17:11:45 +00:00
|
|
|
|
2011-01-22 10:33:16 +00:00
|
|
|
#include "../../stdafx.h"
|
2011-11-29 23:07:38 +00:00
|
|
|
#include "script_bridge.hpp"
|
|
|
|
#include "script_rail.hpp"
|
2011-11-29 23:27:17 +00:00
|
|
|
#include "../script_instance.hpp"
|
2009-01-12 17:11:45 +00:00
|
|
|
#include "../../bridge_map.h"
|
|
|
|
#include "../../strings_func.h"
|
2009-02-14 21:17:35 +00:00
|
|
|
#include "../../date_func.h"
|
2019-01-31 23:08:03 +00:00
|
|
|
#include "table/strings.h"
|
2009-01-12 17:11:45 +00:00
|
|
|
|
2014-04-23 20:13:33 +00:00
|
|
|
#include "../../safeguards.h"
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ bool ScriptBridge::IsValidBridge(BridgeID bridge_id)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
2009-02-14 21:17:35 +00:00
|
|
|
return bridge_id < MAX_BRIDGES && ::GetBridgeSpec(bridge_id)->avail_year <= _cur_year;
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ bool ScriptBridge::IsBridgeTile(TileIndex tile)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
|
|
|
if (!::IsValidTile(tile)) return false;
|
|
|
|
return ::IsBridgeTile(tile);
|
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ BridgeID ScriptBridge::GetBridgeID(TileIndex tile)
|
2009-03-28 12:04:38 +00:00
|
|
|
{
|
2009-03-28 16:19:04 +00:00
|
|
|
if (!IsBridgeTile(tile)) return (BridgeID)-1;
|
2009-03-28 12:04:38 +00:00
|
|
|
return (BridgeID)::GetBridgeType(tile);
|
|
|
|
}
|
|
|
|
|
2011-05-01 09:24:19 +00:00
|
|
|
/**
|
|
|
|
* Helper function to connect a just built bridge to nearby roads.
|
2012-03-04 16:54:12 +00:00
|
|
|
* @param instance The script instance we have to built the road for.
|
2011-05-01 09:24:19 +00:00
|
|
|
*/
|
2011-11-29 23:21:33 +00:00
|
|
|
static void _DoCommandReturnBuildBridge2(class ScriptInstance *instance)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
2011-11-29 23:15:35 +00:00
|
|
|
if (!ScriptBridge::_BuildBridgeRoad2()) {
|
2011-11-29 23:21:33 +00:00
|
|
|
ScriptInstance::DoCommandReturn(instance);
|
2009-01-12 17:11:45 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This can never happen, as in test-mode this callback is never executed,
|
2009-03-14 18:16:29 +00:00
|
|
|
* and in execute-mode, the other callback is called. */
|
2009-01-12 17:11:45 +00:00
|
|
|
NOT_REACHED();
|
|
|
|
}
|
|
|
|
|
2011-05-01 09:24:19 +00:00
|
|
|
/**
|
|
|
|
* Helper function to connect a just built bridge to nearby roads.
|
2012-03-04 16:54:12 +00:00
|
|
|
* @param instance The script instance we have to built the road for.
|
2011-05-01 09:24:19 +00:00
|
|
|
*/
|
2011-11-29 23:21:33 +00:00
|
|
|
static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
2011-11-29 23:15:35 +00:00
|
|
|
if (!ScriptBridge::_BuildBridgeRoad1()) {
|
2011-11-29 23:21:33 +00:00
|
|
|
ScriptInstance::DoCommandReturn(instance);
|
2009-01-12 17:11:45 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This can never happen, as in test-mode this callback is never executed,
|
2009-03-14 18:16:29 +00:00
|
|
|
* and in execute-mode, the other callback is called. */
|
2009-01-12 17:11:45 +00:00
|
|
|
NOT_REACHED();
|
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ bool ScriptBridge::BuildBridge(ScriptVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
|
|
|
EnforcePrecondition(false, start != end);
|
|
|
|
EnforcePrecondition(false, ::IsValidTile(start) && ::IsValidTile(end));
|
|
|
|
EnforcePrecondition(false, TileX(start) == TileX(end) || TileY(start) == TileY(end));
|
2011-11-29 23:15:35 +00:00
|
|
|
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()));
|
2013-12-08 15:44:09 +00:00
|
|
|
EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_ROAD || ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType()));
|
2011-12-19 21:05:25 +00:00
|
|
|
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD);
|
2009-01-12 17:11:45 +00:00
|
|
|
|
|
|
|
uint type = 0;
|
|
|
|
switch (vehicle_type) {
|
2011-11-29 23:15:35 +00:00
|
|
|
case ScriptVehicle::VT_ROAD:
|
2009-01-12 17:11:45 +00:00
|
|
|
type |= (TRANSPORT_ROAD << 15);
|
2019-04-06 06:46:15 +00:00
|
|
|
type |= (ScriptRoad::GetCurrentRoadType() << 8);
|
2009-01-12 17:11:45 +00:00
|
|
|
break;
|
2011-11-29 23:15:35 +00:00
|
|
|
case ScriptVehicle::VT_RAIL:
|
2009-01-12 17:11:45 +00:00
|
|
|
type |= (TRANSPORT_RAIL << 15);
|
2011-11-29 23:15:35 +00:00
|
|
|
type |= (ScriptRail::GetCurrentRailType() << 8);
|
2009-01-12 17:11:45 +00:00
|
|
|
break;
|
2011-11-29 23:15:35 +00:00
|
|
|
case ScriptVehicle::VT_WATER:
|
2009-01-12 17:11:45 +00:00
|
|
|
type |= (TRANSPORT_WATER << 15);
|
|
|
|
break;
|
|
|
|
default: NOT_REACHED();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* For rail and water we do nothing special */
|
2011-11-29 23:15:35 +00:00
|
|
|
if (vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER) {
|
|
|
|
return ScriptObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE);
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
ScriptObject::SetCallbackVariable(0, start);
|
|
|
|
ScriptObject::SetCallbackVariable(1, end);
|
2019-04-10 21:07:06 +00:00
|
|
|
return ScriptObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE, nullptr, &::_DoCommandReturnBuildBridge1);
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ bool ScriptBridge::_BuildBridgeRoad1()
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
|
|
|
/* Build the piece of road on the 'start' side of the bridge */
|
2011-11-29 23:15:35 +00:00
|
|
|
TileIndex end = ScriptObject::GetCallbackVariable(0);
|
|
|
|
TileIndex start = ScriptObject::GetCallbackVariable(1);
|
2009-01-12 17:11:45 +00:00
|
|
|
|
2009-03-21 21:43:23 +00:00
|
|
|
DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
|
2009-01-12 17:11:45 +00:00
|
|
|
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
|
|
|
|
|
2019-04-06 06:46:15 +00:00
|
|
|
return ScriptObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptRoad::GetCurrentRoadType() << 4), 0, CMD_BUILD_ROAD, nullptr, &::_DoCommandReturnBuildBridge2);
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ bool ScriptBridge::_BuildBridgeRoad2()
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
|
|
|
/* Build the piece of road on the 'end' side of the bridge */
|
2011-11-29 23:15:35 +00:00
|
|
|
TileIndex end = ScriptObject::GetCallbackVariable(0);
|
|
|
|
TileIndex start = ScriptObject::GetCallbackVariable(1);
|
2009-01-12 17:11:45 +00:00
|
|
|
|
2009-03-21 21:43:23 +00:00
|
|
|
DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
|
2009-01-12 17:11:45 +00:00
|
|
|
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
|
|
|
|
|
2019-04-06 06:46:15 +00:00
|
|
|
return ScriptObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptRoad::GetCurrentRoadType() << 4), 0, CMD_BUILD_ROAD);
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ bool ScriptBridge::RemoveBridge(TileIndex tile)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
2011-12-19 21:05:36 +00:00
|
|
|
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
2009-01-12 17:11:45 +00:00
|
|
|
EnforcePrecondition(false, IsBridgeTile(tile));
|
2011-11-29 23:15:35 +00:00
|
|
|
return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2019-01-31 23:08:03 +00:00
|
|
|
/* static */ char *ScriptBridge::GetName(BridgeID bridge_id, ScriptVehicle::VehicleType vehicle_type)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
2019-04-10 21:07:06 +00:00
|
|
|
EnforcePrecondition(nullptr, vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER);
|
|
|
|
if (!IsValidBridge(bridge_id)) return nullptr;
|
2009-01-12 17:11:45 +00:00
|
|
|
|
2019-01-31 23:08:03 +00:00
|
|
|
return GetString(vehicle_type == ScriptVehicle::VT_WATER ? STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT : ::GetBridgeSpec(bridge_id)->transport_name[vehicle_type]);
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ int32 ScriptBridge::GetMaxSpeed(BridgeID bridge_id)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
|
|
|
if (!IsValidBridge(bridge_id)) return -1;
|
|
|
|
|
2009-02-01 17:14:39 +00:00
|
|
|
return ::GetBridgeSpec(bridge_id)->speed; // km-ish/h
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ Money ScriptBridge::GetPrice(BridgeID bridge_id, uint length)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
|
|
|
if (!IsValidBridge(bridge_id)) return -1;
|
|
|
|
|
2009-11-07 22:47:54 +00:00
|
|
|
return ::CalcBridgeLenCostFactor(length) * _price[PR_BUILD_BRIDGE] * ::GetBridgeSpec(bridge_id)->price >> 8;
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ int32 ScriptBridge::GetMaxLength(BridgeID bridge_id)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
|
|
|
if (!IsValidBridge(bridge_id)) return -1;
|
|
|
|
|
2011-02-04 15:37:23 +00:00
|
|
|
return min(::GetBridgeSpec(bridge_id)->max_length, _settings_game.construction.max_bridge_length) + 2;
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ int32 ScriptBridge::GetMinLength(BridgeID bridge_id)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
|
|
|
if (!IsValidBridge(bridge_id)) return -1;
|
|
|
|
|
|
|
|
return ::GetBridgeSpec(bridge_id)->min_length + 2;
|
|
|
|
}
|
|
|
|
|
2011-11-29 23:15:35 +00:00
|
|
|
/* static */ TileIndex ScriptBridge::GetOtherBridgeEnd(TileIndex tile)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
|
|
|
if (!::IsValidTile(tile)) return INVALID_TILE;
|
|
|
|
if (!IsBridgeTile(tile)) return INVALID_TILE;
|
|
|
|
|
|
|
|
return ::GetOtherBridgeEnd(tile);
|
|
|
|
}
|