(svn r27985) -Codechange: Convert VA2 switches into ones with non-overlapping ranges...
[openttd.git] / src / script / api / script_engine.cpp
blob1fe16321b50d1ce339b9bdc9c0b43bd3742b269e
1 /* $Id$ */
3 /*
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/>.
8 */
10 /** @file script_engine.cpp Implementation of ScriptEngine. */
12 #include "../../stdafx.h"
13 #include "script_engine.hpp"
14 #include "script_cargo.hpp"
15 #include "../../company_base.h"
16 #include "../../strings_func.h"
17 #include "../../rail.h"
18 #include "../../engine_base.h"
19 #include "../../engine_func.h"
20 #include "../../articulated_vehicles.h"
21 #include "table/strings.h"
23 #include "../../safeguards.h"
25 /* static */ bool ScriptEngine::IsValidEngine(EngineID engine_id)
27 const Engine *e = ::Engine::GetIfValid(engine_id);
28 if (e == NULL || !e->IsEnabled()) return false;
30 /* AIs have only access to engines they can purchase or still have in use.
31 * Deity has access to all engined that will be or were available ever. */
32 CompanyID company = ScriptObject::GetCompany();
33 return company == OWNER_DEITY || ::IsEngineBuildable(engine_id, e->type, company) || ::Company::Get(company)->group_all[e->type].num_engines[engine_id] > 0;
36 /* static */ bool ScriptEngine::IsBuildable(EngineID engine_id)
38 const Engine *e = ::Engine::GetIfValid(engine_id);
39 return e != NULL && ::IsEngineBuildable(engine_id, e->type, ScriptObject::GetCompany());
42 /* static */ char *ScriptEngine::GetName(EngineID engine_id)
44 if (!IsValidEngine(engine_id)) return NULL;
46 ::SetDParam(0, engine_id);
47 return GetString(STR_ENGINE_NAME);
50 /* static */ CargoID ScriptEngine::GetCargoType(EngineID engine_id)
52 if (!IsValidEngine(engine_id)) return CT_INVALID;
54 CargoArray cap = ::GetCapacityOfArticulatedParts(engine_id);
56 CargoID most_cargo = CT_INVALID;
57 uint amount = 0;
58 for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
59 if (cap[cid] > amount) {
60 amount = cap[cid];
61 most_cargo = cid;
65 return most_cargo;
68 /* static */ bool ScriptEngine::CanRefitCargo(EngineID engine_id, CargoID cargo_id)
70 if (!IsValidEngine(engine_id)) return false;
71 if (!ScriptCargo::IsValidCargo(cargo_id)) return false;
73 return HasBit(::GetUnionOfArticulatedRefitMasks(engine_id, true), cargo_id);
76 /* static */ bool ScriptEngine::CanPullCargo(EngineID engine_id, CargoID cargo_id)
78 if (!IsValidEngine(engine_id)) return false;
79 if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL) return false;
80 if (!ScriptCargo::IsValidCargo(cargo_id)) return false;
82 return (::RailVehInfo(engine_id)->ai_passenger_only != 1) || ScriptCargo::HasCargoClass(cargo_id, ScriptCargo::CC_PASSENGERS);
86 /* static */ int32 ScriptEngine::GetCapacity(EngineID engine_id)
88 if (!IsValidEngine(engine_id)) return -1;
90 const Engine *e = ::Engine::Get(engine_id);
91 switch (e->type) {
92 case VEH_ROAD:
93 case VEH_TRAIN: {
94 CargoArray capacities = GetCapacityOfArticulatedParts(engine_id);
95 for (CargoID c = 0; c < NUM_CARGO; c++) {
96 if (capacities[c] == 0) continue;
97 return capacities[c];
99 return -1;
102 case VEH_SHIP:
103 case VEH_AIRCRAFT:
104 return e->GetDisplayDefaultCapacity();
106 default: NOT_REACHED();
110 /* static */ int32 ScriptEngine::GetReliability(EngineID engine_id)
112 if (!IsValidEngine(engine_id)) return -1;
113 if (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL && IsWagon(engine_id)) return -1;
115 return ::ToPercent16(::Engine::Get(engine_id)->reliability);
118 /* static */ int32 ScriptEngine::GetMaxSpeed(EngineID engine_id)
120 if (!IsValidEngine(engine_id)) return -1;
122 const Engine *e = ::Engine::Get(engine_id);
123 int32 max_speed = e->GetDisplayMaxSpeed(); // km-ish/h
124 if (e->type == VEH_AIRCRAFT) max_speed /= _settings_game.vehicle.plane_speed;
125 return max_speed;
128 /* static */ Money ScriptEngine::GetPrice(EngineID engine_id)
130 if (!IsValidEngine(engine_id)) return -1;
132 return ::Engine::Get(engine_id)->GetCost();
135 /* static */ int32 ScriptEngine::GetMaxAge(EngineID engine_id)
137 if (!IsValidEngine(engine_id)) return -1;
138 if (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL && IsWagon(engine_id)) return -1;
140 return ::Engine::Get(engine_id)->GetLifeLengthInDays();
143 /* static */ Money ScriptEngine::GetRunningCost(EngineID engine_id)
145 if (!IsValidEngine(engine_id)) return -1;
147 return ::Engine::Get(engine_id)->GetRunningCost();
150 /* static */ int32 ScriptEngine::GetPower(EngineID engine_id)
152 if (!IsValidEngine(engine_id)) return -1;
153 if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL && GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return -1;
154 if (IsWagon(engine_id)) return -1;
156 return ::Engine::Get(engine_id)->GetPower();
159 /* static */ int32 ScriptEngine::GetWeight(EngineID engine_id)
161 if (!IsValidEngine(engine_id)) return -1;
162 if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL && GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return -1;
164 return ::Engine::Get(engine_id)->GetDisplayWeight();
167 /* static */ int32 ScriptEngine::GetMaxTractiveEffort(EngineID engine_id)
169 if (!IsValidEngine(engine_id)) return -1;
170 if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL && GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return -1;
171 if (IsWagon(engine_id)) return -1;
173 return ::Engine::Get(engine_id)->GetDisplayMaxTractiveEffort();
176 /* static */ ScriptDate::Date ScriptEngine::GetDesignDate(EngineID engine_id)
178 if (!IsValidEngine(engine_id)) return ScriptDate::DATE_INVALID;
180 return (ScriptDate::Date)::Engine::Get(engine_id)->intro_date;
183 /* static */ ScriptVehicle::VehicleType ScriptEngine::GetVehicleType(EngineID engine_id)
185 if (!IsValidEngine(engine_id)) return ScriptVehicle::VT_INVALID;
187 switch (::Engine::Get(engine_id)->type) {
188 case VEH_ROAD: return ScriptVehicle::VT_ROAD;
189 case VEH_TRAIN: return ScriptVehicle::VT_RAIL;
190 case VEH_SHIP: return ScriptVehicle::VT_WATER;
191 case VEH_AIRCRAFT: return ScriptVehicle::VT_AIR;
192 default: NOT_REACHED();
196 /* static */ bool ScriptEngine::IsWagon(EngineID engine_id)
198 if (!IsValidEngine(engine_id)) return false;
199 if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL) return false;
201 return ::RailVehInfo(engine_id)->power == 0;
204 /* static */ bool ScriptEngine::CanRunOnRail(EngineID engine_id, ScriptRail::RailType track_rail_type)
206 if (!IsValidEngine(engine_id)) return false;
207 if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL) return false;
208 if (!ScriptRail::IsRailTypeAvailable(track_rail_type)) return false;
210 return ::IsCompatibleRail((::RailType)::RailVehInfo(engine_id)->railtype, (::RailType)track_rail_type);
213 /* static */ bool ScriptEngine::HasPowerOnRail(EngineID engine_id, ScriptRail::RailType track_rail_type)
215 if (!IsValidEngine(engine_id)) return false;
216 if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL) return false;
217 if (!ScriptRail::IsRailTypeAvailable(track_rail_type)) return false;
219 return ::HasPowerOnRail((::RailType)::RailVehInfo(engine_id)->railtype, (::RailType)track_rail_type);
222 /* static */ ScriptRoad::RoadType ScriptEngine::GetRoadType(EngineID engine_id)
224 if (!IsValidEngine(engine_id)) return ScriptRoad::ROADTYPE_INVALID;
225 if (GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return ScriptRoad::ROADTYPE_INVALID;
227 return HasBit(::EngInfo(engine_id)->misc_flags, EF_ROAD_TRAM) ? ScriptRoad::ROADTYPE_TRAM : ScriptRoad::ROADTYPE_ROAD;
230 /* static */ ScriptRail::RailType ScriptEngine::GetRailType(EngineID engine_id)
232 if (!IsValidEngine(engine_id)) return ScriptRail::RAILTYPE_INVALID;
233 if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL) return ScriptRail::RAILTYPE_INVALID;
235 return (ScriptRail::RailType)(uint)::RailVehInfo(engine_id)->railtype;
238 /* static */ bool ScriptEngine::IsArticulated(EngineID engine_id)
240 if (!IsValidEngine(engine_id)) return false;
241 if (GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD && GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL) return false;
243 return IsArticulatedEngine(engine_id);
246 /* static */ ScriptAirport::PlaneType ScriptEngine::GetPlaneType(EngineID engine_id)
248 if (!IsValidEngine(engine_id)) return ScriptAirport::PT_INVALID;
249 if (GetVehicleType(engine_id) != ScriptVehicle::VT_AIR) return ScriptAirport::PT_INVALID;
251 return (ScriptAirport::PlaneType)::AircraftVehInfo(engine_id)->subtype;
254 /* static */ uint ScriptEngine::GetMaximumOrderDistance(EngineID engine_id)
256 if (!IsValidEngine(engine_id)) return 0;
258 switch (GetVehicleType(engine_id)) {
259 case ScriptVehicle::VT_WATER:
260 return _settings_game.pf.pathfinder_for_ships != VPF_NPF ? 129 : 0;
262 case ScriptVehicle::VT_AIR:
263 return ::Engine::Get(engine_id)->GetRange() * ::Engine::Get(engine_id)->GetRange();
265 default:
266 return 0;