2009-08-21 22:21:05 +02: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-30 00:15:35 +01:00
|
|
|
/** @file script_group.cpp Implementation of ScriptGroup. */
|
2009-01-12 18:11:45 +01:00
|
|
|
|
2011-01-22 11:33:16 +01:00
|
|
|
#include "../../stdafx.h"
|
2011-11-30 00:07:38 +01:00
|
|
|
#include "script_group.hpp"
|
|
|
|
#include "script_engine.hpp"
|
2011-11-30 00:27:17 +01:00
|
|
|
#include "../script_instance.hpp"
|
2009-01-12 18:11:45 +01:00
|
|
|
#include "../../string_func.h"
|
|
|
|
#include "../../strings_func.h"
|
|
|
|
#include "../../autoreplace_func.h"
|
2009-05-26 15:29:01 +02:00
|
|
|
#include "../../settings_func.h"
|
2019-02-13 23:18:33 +01:00
|
|
|
#include "../../vehicle_base.h"
|
2009-01-12 18:11:45 +01:00
|
|
|
#include "table/strings.h"
|
|
|
|
|
2014-04-23 22:13:33 +02:00
|
|
|
#include "../../safeguards.h"
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ bool ScriptGroup::IsValidGroup(GroupID group_id)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2009-05-18 18:21:28 +02:00
|
|
|
const Group *g = ::Group::GetIfValid(group_id);
|
2019-04-10 23:07:06 +02:00
|
|
|
return g != nullptr && g->owner == ScriptObject::GetCompany();
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2019-02-15 21:14:50 +01:00
|
|
|
/* static */ ScriptGroup::GroupID ScriptGroup::CreateGroup(ScriptVehicle::VehicleType vehicle_type, GroupID parent_group_id)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2019-04-10 23:07:06 +02:00
|
|
|
if (!ScriptObject::DoCommand(0, (::VehicleType)vehicle_type, parent_group_id, CMD_CREATE_GROUP, nullptr, &ScriptInstance::DoCommandReturnGroupID)) return GROUP_INVALID;
|
2009-01-12 18:11:45 +01:00
|
|
|
|
|
|
|
/* In case of test-mode, we return GroupID 0 */
|
2011-11-30 00:15:35 +01:00
|
|
|
return (ScriptGroup::GroupID)0;
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ bool ScriptGroup::DeleteGroup(GroupID group_id)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
|
|
|
EnforcePrecondition(false, IsValidGroup(group_id));
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
return ScriptObject::DoCommand(0, group_id, 0, CMD_DELETE_GROUP);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ ScriptVehicle::VehicleType ScriptGroup::GetVehicleType(GroupID group_id)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2011-11-30 00:15:35 +01:00
|
|
|
if (!IsValidGroup(group_id)) return ScriptVehicle::VT_INVALID;
|
2009-01-12 18:11:45 +01:00
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
return (ScriptVehicle::VehicleType)((::VehicleType)::Group::Get(group_id)->vehicle_type);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-12-19 22:06:06 +01:00
|
|
|
/* static */ bool ScriptGroup::SetName(GroupID group_id, Text *name)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2011-12-19 22:06:06 +01:00
|
|
|
CCountedPtr<Text> counter(name);
|
|
|
|
|
2009-01-12 18:11:45 +01:00
|
|
|
EnforcePrecondition(false, IsValidGroup(group_id));
|
2019-04-10 23:07:06 +02:00
|
|
|
EnforcePrecondition(false, name != nullptr);
|
2013-06-27 21:57:41 +02:00
|
|
|
const char *text = name->GetDecodedText();
|
2013-02-08 21:34:27 +01:00
|
|
|
EnforcePreconditionEncodedText(false, text);
|
2011-12-19 22:06:06 +01:00
|
|
|
EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_GROUP_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
|
2009-01-12 18:11:45 +01:00
|
|
|
|
2014-04-08 23:09:06 +02:00
|
|
|
return ScriptObject::DoCommand(0, group_id, 0, CMD_ALTER_GROUP, text);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ char *ScriptGroup::GetName(GroupID group_id)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2019-04-10 23:07:06 +02:00
|
|
|
if (!IsValidGroup(group_id)) return nullptr;
|
2009-01-12 18:11:45 +01:00
|
|
|
|
|
|
|
::SetDParam(0, group_id);
|
2012-01-08 22:48:05 +01:00
|
|
|
return GetString(STR_GROUP_NAME);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2019-02-13 22:18:44 +01:00
|
|
|
/* static */ bool ScriptGroup::SetParent(GroupID group_id, GroupID parent_group_id)
|
|
|
|
{
|
|
|
|
EnforcePrecondition(false, IsValidGroup(group_id));
|
|
|
|
EnforcePrecondition(false, IsValidGroup(parent_group_id));
|
|
|
|
|
|
|
|
return ScriptObject::DoCommand(0, group_id | 1 << 16, parent_group_id, CMD_ALTER_GROUP);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ ScriptGroup::GroupID ScriptGroup::GetParent(GroupID group_id)
|
|
|
|
{
|
|
|
|
EnforcePrecondition((ScriptGroup::GroupID)INVALID_GROUP, IsValidGroup(group_id));
|
|
|
|
|
|
|
|
const Group *g = ::Group::GetIfValid(group_id);
|
|
|
|
return (ScriptGroup::GroupID)g->parent;
|
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ bool ScriptGroup::EnableAutoReplaceProtection(GroupID group_id, bool enable)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
|
|
|
EnforcePrecondition(false, IsValidGroup(group_id));
|
|
|
|
|
2019-03-30 00:44:28 +01:00
|
|
|
return ScriptObject::DoCommand(0, group_id | GroupFlags::GF_REPLACE_PROTECTION, enable ? 1 : 0, CMD_SET_GROUP_FLAG);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ bool ScriptGroup::GetAutoReplaceProtection(GroupID group_id)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
|
|
|
if (!IsValidGroup(group_id)) return false;
|
|
|
|
|
2019-03-30 00:24:40 +01:00
|
|
|
return HasBit(::Group::Get(group_id)->flags, GroupFlags::GF_REPLACE_PROTECTION);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ int32 ScriptGroup::GetNumEngines(GroupID group_id, EngineID engine_id)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2009-01-16 01:05:26 +01:00
|
|
|
if (!IsValidGroup(group_id) && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return -1;
|
2009-01-12 18:11:45 +01:00
|
|
|
|
2011-12-19 22:05:25 +01:00
|
|
|
return GetGroupNumEngines(ScriptObject::GetCompany(), group_id, engine_id);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2021-08-12 21:29:03 +02:00
|
|
|
/* static */ int32 ScriptGroup::GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type)
|
|
|
|
{
|
|
|
|
bool valid_group = IsValidGroup(group_id);
|
|
|
|
if (!valid_group && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return -1;
|
|
|
|
if (!valid_group && (vehicle_type < ScriptVehicle::VT_RAIL || vehicle_type > ScriptVehicle::VT_AIR)) return -1;
|
|
|
|
|
|
|
|
return GetGroupNumVehicle(ScriptObject::GetCompany(), group_id, valid_group ? ::Group::Get(group_id)->vehicle_type : (::VehicleType)vehicle_type);
|
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ bool ScriptGroup::MoveVehicle(GroupID group_id, VehicleID vehicle_id)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2009-01-16 01:05:26 +01:00
|
|
|
EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT);
|
2011-11-30 00:15:35 +01:00
|
|
|
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id));
|
2009-01-12 18:11:45 +01:00
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
return ScriptObject::DoCommand(0, group_id, vehicle_id, CMD_ADD_VEHICLE_GROUP);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ bool ScriptGroup::EnableWagonRemoval(bool enable_removal)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
|
|
|
if (HasWagonRemoval() == enable_removal) return true;
|
|
|
|
|
2021-05-29 23:27:01 +02:00
|
|
|
return ScriptObject::DoCommand(0, 0, enable_removal ? 1 : 0, CMD_CHANGE_COMPANY_SETTING, "company.renew_keep_length");
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ bool ScriptGroup::HasWagonRemoval()
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2011-12-19 22:05:25 +01:00
|
|
|
return ::Company::Get(ScriptObject::GetCompany())->settings.renew_keep_length;
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ bool ScriptGroup::SetAutoReplace(GroupID group_id, EngineID engine_id_old, EngineID engine_id_new)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2010-01-27 21:51:11 +01:00
|
|
|
EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL);
|
2011-11-30 00:15:35 +01:00
|
|
|
EnforcePrecondition(false, ScriptEngine::IsBuildable(engine_id_new));
|
2009-01-12 18:11:45 +01:00
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
return ScriptObject::DoCommand(0, group_id << 16, (engine_id_new << 16) | engine_id_old, CMD_SET_AUTOREPLACE);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ EngineID ScriptGroup::GetEngineReplacement(GroupID group_id, EngineID engine_id)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2010-01-27 21:51:11 +01:00
|
|
|
if (!IsValidGroup(group_id) && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return ::INVALID_ENGINE;
|
2009-01-12 18:11:45 +01:00
|
|
|
|
2011-12-19 22:05:25 +01:00
|
|
|
return ::EngineReplacementForCompany(Company::Get(ScriptObject::GetCompany()), engine_id, group_id);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
/* static */ bool ScriptGroup::StopAutoReplace(GroupID group_id, EngineID engine_id)
|
2009-01-12 18:11:45 +01:00
|
|
|
{
|
2010-01-27 21:51:11 +01:00
|
|
|
EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL);
|
2009-01-12 18:11:45 +01:00
|
|
|
|
2011-11-30 00:15:35 +01:00
|
|
|
return ScriptObject::DoCommand(0, group_id << 16, (::INVALID_ENGINE << 16) | engine_id, CMD_SET_AUTOREPLACE);
|
2009-01-12 18:11:45 +01:00
|
|
|
}
|
2019-02-13 23:18:33 +01:00
|
|
|
|
|
|
|
/* static */ Money ScriptGroup::GetProfitThisYear(GroupID group_id)
|
|
|
|
{
|
|
|
|
if (!IsValidGroup(group_id)) return -1;
|
|
|
|
|
|
|
|
Money profit = 0;
|
|
|
|
|
2019-12-17 03:37:43 +01:00
|
|
|
for (const Vehicle *v : Vehicle::Iterate()) {
|
2019-02-13 23:18:33 +01:00
|
|
|
if (v->group_id != group_id) continue;
|
|
|
|
if (!v->IsPrimaryVehicle()) continue;
|
|
|
|
|
|
|
|
profit += v->GetDisplayProfitThisYear();
|
|
|
|
}
|
|
|
|
|
|
|
|
return profit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ Money ScriptGroup::GetProfitLastYear(GroupID group_id)
|
|
|
|
{
|
|
|
|
if (!IsValidGroup(group_id)) return -1;
|
|
|
|
|
|
|
|
return ::Group::Get(group_id)->statistics.profit_last_year;
|
|
|
|
}
|
2019-02-13 23:48:46 +01:00
|
|
|
|
|
|
|
/* static */ uint32 ScriptGroup::GetCurrentUsage(GroupID group_id)
|
|
|
|
{
|
|
|
|
if (!IsValidGroup(group_id)) return -1;
|
|
|
|
|
|
|
|
uint32 occupancy = 0;
|
|
|
|
uint32 vehicle_count = 0;
|
|
|
|
|
2019-12-17 03:37:43 +01:00
|
|
|
for (const Vehicle *v : Vehicle::Iterate()) {
|
2019-02-13 23:48:46 +01:00
|
|
|
if (v->group_id != group_id) continue;
|
|
|
|
if (!v->IsPrimaryVehicle()) continue;
|
|
|
|
|
|
|
|
occupancy += v->trip_occupancy;
|
|
|
|
vehicle_count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle_count == 0) return -1;
|
|
|
|
|
|
|
|
return occupancy / vehicle_count;
|
|
|
|
}
|
2019-03-08 19:13:33 +01:00
|
|
|
|
|
|
|
/* static */ bool ScriptGroup::SetPrimaryColour(GroupID group_id, ScriptCompany::Colours colour)
|
|
|
|
{
|
|
|
|
EnforcePrecondition(false, IsValidGroup(group_id));
|
|
|
|
|
|
|
|
return ScriptObject::DoCommand(0, group_id, colour << 16, CMD_SET_GROUP_LIVERY);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ bool ScriptGroup::SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour)
|
|
|
|
{
|
|
|
|
EnforcePrecondition(false, IsValidGroup(group_id));
|
|
|
|
|
|
|
|
return ScriptObject::DoCommand(0, group_id, (1 << 8) | (colour << 16), CMD_SET_GROUP_LIVERY);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ ScriptCompany::Colours ScriptGroup::GetPrimaryColour(GroupID group_id)
|
|
|
|
{
|
|
|
|
EnforcePrecondition(ScriptCompany::Colours::COLOUR_INVALID, IsValidGroup(group_id));
|
|
|
|
|
|
|
|
const Group *g = ::Group::GetIfValid(group_id);
|
|
|
|
if (!HasBit(g->livery.in_use, 0)) return ScriptCompany::Colours::COLOUR_INVALID;
|
|
|
|
return (ScriptCompany::Colours)g->livery.colour1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ ScriptCompany::Colours ScriptGroup::GetSecondaryColour(GroupID group_id)
|
|
|
|
{
|
|
|
|
EnforcePrecondition(ScriptCompany::Colours::COLOUR_INVALID, IsValidGroup(group_id));
|
|
|
|
|
|
|
|
const Group *g = ::Group::GetIfValid(group_id);
|
|
|
|
if (!HasBit(g->livery.in_use, 1)) return ScriptCompany::Colours::COLOUR_INVALID;
|
|
|
|
return (ScriptCompany::Colours)g->livery.colour2;
|
|
|
|
}
|