Feature: [GS] Scriptable league tables (#10001)
(cherry picked from commit 5e14a20b3b
)
This commit is contained in:
@@ -178,6 +178,7 @@ add_files(
|
||||
script_inflation.hpp
|
||||
script_info_docs.hpp
|
||||
script_infrastructure.hpp
|
||||
script_league.hpp
|
||||
script_list.hpp
|
||||
script_log.hpp
|
||||
script_map.hpp
|
||||
@@ -249,6 +250,7 @@ add_files(
|
||||
script_industrytypelist.cpp
|
||||
script_inflation.cpp
|
||||
script_infrastructure.cpp
|
||||
script_league.cpp
|
||||
script_list.cpp
|
||||
script_log.cpp
|
||||
script_map.cpp
|
||||
|
@@ -21,6 +21,7 @@
|
||||
* \li GSCargo::GetWeight
|
||||
* \li GSIndustryType::ResolveNewGRFID
|
||||
* \li GSObjectType::ResolveNewGRFID
|
||||
* \li GSLeagueTable
|
||||
*
|
||||
* Other changes:
|
||||
* \li GSRoad::HasRoadType now correctly checks RoadType against RoadType
|
||||
|
128
src/script/api/script_league.cpp
Normal file
128
src/script/api/script_league.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/** @file script_league.cpp Implementation of ScriptLeagueTable. */
|
||||
|
||||
#include "../../stdafx.h"
|
||||
|
||||
#include "script_league.hpp"
|
||||
|
||||
#include "../script_instance.hpp"
|
||||
#include "script_error.hpp"
|
||||
#include "../../league_base.h"
|
||||
#include "../../string_func.h"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
|
||||
/* static */ bool ScriptLeagueTable::IsValidLeagueTable(LeagueTableID table_id)
|
||||
{
|
||||
return ::LeagueTable::IsValidID(table_id);
|
||||
}
|
||||
|
||||
/* static */ ScriptLeagueTable::LeagueTableID ScriptLeagueTable::New(Text *title, Text *header, Text *footer)
|
||||
{
|
||||
CCountedPtr<Text> title_counter(title);
|
||||
CCountedPtr<Text> header_counter(header);
|
||||
CCountedPtr<Text> footer_counter(footer);
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_INVALID, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforcePrecondition(LEAGUE_TABLE_INVALID, title != nullptr);
|
||||
const char *encoded_title = title->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(LEAGUE_TABLE_INVALID, encoded_title);
|
||||
|
||||
std::string cmd_text = encoded_title;
|
||||
cmd_text.push_back(0x1F);
|
||||
if (header != nullptr) cmd_text += header->GetEncodedText();
|
||||
cmd_text.push_back(0x1F);
|
||||
if (footer != nullptr) cmd_text += footer->GetEncodedText();
|
||||
|
||||
if (!ScriptObject::DoCommand(0, 0, 0, CMD_CREATE_LEAGUE_TABLE, cmd_text.c_str(), &ScriptInstance::DoCommandReturnLeagueTableID)) return LEAGUE_TABLE_INVALID;
|
||||
|
||||
/* In case of test-mode, we return LeagueTableID 0 */
|
||||
return (ScriptLeagueTable::LeagueTableID)0;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptLeagueTable::IsValidLeagueTableElement(LeagueTableElementID element_id)
|
||||
{
|
||||
return ::LeagueTableElement::IsValidID(element_id);
|
||||
}
|
||||
|
||||
/* static */ ScriptLeagueTable::LeagueTableElementID ScriptLeagueTable::NewElement(ScriptLeagueTable::LeagueTableID table, int64 rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, uint32 link_target)
|
||||
{
|
||||
CCountedPtr<Text> text_counter(text);
|
||||
CCountedPtr<Text> score_counter(score);
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, IsValidLeagueTable(table));
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
|
||||
CompanyID c = (::CompanyID)company;
|
||||
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, text != nullptr);
|
||||
const char *encoded_text_ptr = text->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_text_ptr);
|
||||
std::string encoded_text = encoded_text_ptr; // save into string so GetEncodedText can reuse the internal buffer
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, score != nullptr);
|
||||
const char *encoded_score = score->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_score);
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, IsValidLink(Link((::LinkType)link_type, link_target)));
|
||||
|
||||
std::string cmd_text = std::move(encoded_text);
|
||||
cmd_text.push_back(0x1F);
|
||||
cmd_text += encoded_score;
|
||||
if (!ScriptObject::DoCommandEx(0, table | (c << 8) | (link_type << 16), link_target, rating, CMD_CREATE_LEAGUE_TABLE_ELEMENT, cmd_text.c_str(), 0, &ScriptInstance::DoCommandReturnLeagueTableElementID)) return LEAGUE_TABLE_ELEMENT_INVALID;
|
||||
|
||||
/* In case of test-mode, we return LeagueTableElementID 0 */
|
||||
return (ScriptLeagueTable::LeagueTableElementID)0;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptLeagueTable::UpdateElementData(LeagueTableElementID element, ScriptCompany::CompanyID company, Text *text, LinkType link_type, LinkTargetID link_target)
|
||||
{
|
||||
CCountedPtr<Text> text_counter(text);
|
||||
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforcePrecondition(false, IsValidLeagueTableElement(element));
|
||||
|
||||
EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
|
||||
CompanyID c = (::CompanyID)company;
|
||||
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
|
||||
|
||||
EnforcePrecondition(false, text != nullptr);
|
||||
const char *encoded_text = text->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(false, encoded_text);
|
||||
|
||||
EnforcePrecondition(false, IsValidLink(Link((::LinkType)link_type, link_target)));
|
||||
|
||||
return ScriptObject::DoCommand(0, element | (c << 16) | (link_type << 24), link_target, CMD_UPDATE_LEAGUE_TABLE_ELEMENT_DATA, encoded_text);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptLeagueTable::UpdateElementScore(LeagueTableElementID element, int64 rating, Text *score)
|
||||
{
|
||||
CCountedPtr<Text> score_counter(score);
|
||||
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforcePrecondition(false, IsValidLeagueTableElement(element));
|
||||
|
||||
EnforcePrecondition(false, score != nullptr);
|
||||
const char *encoded_score = score->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(false, encoded_score);
|
||||
|
||||
return ScriptObject::DoCommandEx(0, element, 0, rating, CMD_UPDATE_LEAGUE_TABLE_ELEMENT_SCORE, encoded_score);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptLeagueTable::RemoveElement(LeagueTableElementID element)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforcePrecondition(false, IsValidLeagueTableElement(element));
|
||||
|
||||
return ScriptObject::DoCommand(0, element, 0, CMD_REMOVE_LEAGUE_TABLE_ELEMENT);
|
||||
}
|
134
src/script/api/script_league.hpp
Normal file
134
src/script/api/script_league.hpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/** @file script_league.hpp Everything to manipulate league tables. */
|
||||
|
||||
#ifndef SCRIPT_LEAGUE_HPP
|
||||
#define SCRIPT_LEAGUE_HPP
|
||||
|
||||
#include "script_company.hpp"
|
||||
#include "script_text.hpp"
|
||||
#include "../../league_type.h"
|
||||
|
||||
/**
|
||||
* Class that handles league table related functions.
|
||||
*
|
||||
* To create a league table:
|
||||
* 1. Create the league table
|
||||
* 2. Create league table elements that will be shown in the table in the order of their rating (higher=better).
|
||||
*
|
||||
* @api game
|
||||
*/
|
||||
class ScriptLeagueTable : public ScriptObject {
|
||||
public:
|
||||
/**
|
||||
* The league table IDs.
|
||||
*/
|
||||
enum LeagueTableID {
|
||||
LEAGUE_TABLE_INVALID = ::INVALID_LEAGUE_TABLE, ///< An invalid league table id.
|
||||
};
|
||||
|
||||
/**
|
||||
* The league table element IDs.
|
||||
*/
|
||||
enum LeagueTableElementID {
|
||||
LEAGUE_TABLE_ELEMENT_INVALID = ::INVALID_LEAGUE_TABLE_ELEMENT, ///< An invalid league table element id.
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of a link.
|
||||
*/
|
||||
enum LinkType : byte {
|
||||
LINK_NONE = ::LT_NONE, ///< No link
|
||||
LINK_TILE = ::LT_TILE, ///< Link a tile
|
||||
LINK_INDUSTRY = ::LT_INDUSTRY, ///< Link an industry
|
||||
LINK_TOWN = ::LT_TOWN, ///< Link a town
|
||||
LINK_COMPANY = ::LT_COMPANY, ///< Link a company
|
||||
LINK_STORY_PAGE = ::LT_STORY_PAGE, ///< Link a story page
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether this is a valid league table ID.
|
||||
* @param table_id The LeagueTableID to check.
|
||||
* @return true iff this league table is valid.
|
||||
*/
|
||||
static bool IsValidLeagueTable(LeagueTableID table_id);
|
||||
|
||||
/**
|
||||
* Check whether this is a valid league table element ID.
|
||||
* @param element_id The LeagueTableElementID to check.
|
||||
* @return true iff this league table element is valid.
|
||||
*/
|
||||
static bool IsValidLeagueTableElement(LeagueTableElementID element_id);
|
||||
|
||||
/**
|
||||
* Create a new league table.
|
||||
* @param title League table title (can be either a raw string, or ScriptText object).
|
||||
* @return The new LeagueTableID, or LEAGUE_TABLE_INVALID if it failed.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre title != nullptr && len(title) != 0.
|
||||
*/
|
||||
static LeagueTableID New(Text *title, Text *header, Text *footer);
|
||||
|
||||
/**
|
||||
* Create a new league table element.
|
||||
* @param table Id of the league table this element belongs to.
|
||||
* @param rating Value that elements are ordered by.
|
||||
* @param company Company to show the color blob for or INVALID_COMPANY.
|
||||
* @param text Text of the element (can be either a raw string, or ScriptText object).
|
||||
* @param score String representation of the score associated with the element (can be either a raw string, or ScriptText object).
|
||||
* @param link_type Type of the referenced object.
|
||||
* @param link_target Id of the referenced object.
|
||||
* @return The new LeagueTableElementID, or LEAGUE_TABLE_ELEMENT_INVALID if it failed.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre IsValidLeagueTable(table).
|
||||
* @pre text != nullptr && len(text) != 0.
|
||||
* @pre score != nullptr && len(score) != 0.
|
||||
* @pre IsValidLink(Link(link_type, link_target)).
|
||||
*/
|
||||
static LeagueTableElementID NewElement(LeagueTableID table, int64 rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, LinkTargetID link_target);
|
||||
|
||||
/**
|
||||
* Update the attributes of a league table element.
|
||||
* @param element Id of the element to update
|
||||
* @param company Company to show the color blob for or INVALID_COMPANY.
|
||||
* @param text Text of the element (can be either a raw string, or ScriptText object).
|
||||
* @param link_type Type of the referenced object.
|
||||
* @param link_target Id of the referenced object.
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre IsValidLeagueTableElement(element).
|
||||
* @pre text != nullptr && len(text) != 0.
|
||||
* @pre IsValidLink(Link(link_type, link_target)).
|
||||
*/
|
||||
static bool UpdateElementData(LeagueTableElementID element, ScriptCompany::CompanyID company, Text *text, LinkType link_type, LinkTargetID link_target);
|
||||
|
||||
/**
|
||||
* Create a new league table element.
|
||||
* @param element Id of the element to update
|
||||
* @param rating Value that elements are ordered by.
|
||||
* @param score String representation of the score associated with the element (can be either a raw string, or ScriptText object).
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre IsValidLeagueTableElement(element).
|
||||
* @pre score != nullptr && len(score) != 0.
|
||||
*/
|
||||
static bool UpdateElementScore(LeagueTableElementID element, int64 rating, Text *score);
|
||||
|
||||
|
||||
/**
|
||||
* Remove a league table element.
|
||||
* @param element Id of the element to update
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre IsValidLeagueTableElement(element).
|
||||
*/
|
||||
static bool RemoveElement(LeagueTableElementID element);
|
||||
};
|
||||
|
||||
|
||||
#endif /* SCRIPT_LEAGUE_HPP */
|
@@ -26,6 +26,7 @@
|
||||
#include "../company_base.h"
|
||||
#include "../company_func.h"
|
||||
#include "../fileio_func.h"
|
||||
#include "../league_type.h"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
@@ -321,6 +322,17 @@ void ScriptInstance::CollectGarbage()
|
||||
instance->engine->InsertResult(ScriptObject::GetNewStoryPageElementID());
|
||||
}
|
||||
|
||||
/* static */ void ScriptInstance::DoCommandReturnLeagueTableElementID(ScriptInstance *instance)
|
||||
{
|
||||
instance->engine->InsertResult(static_cast<LeagueTableElementID>(ScriptObject::GetLastCommandResultData()));
|
||||
}
|
||||
|
||||
/* static */ void ScriptInstance::DoCommandReturnLeagueTableID(ScriptInstance *instance)
|
||||
{
|
||||
instance->engine->InsertResult(static_cast<LeagueTableID>(ScriptObject::GetLastCommandResultData()));
|
||||
}
|
||||
|
||||
|
||||
ScriptStorage *ScriptInstance::GetStorage()
|
||||
{
|
||||
return this->storage;
|
||||
|
@@ -115,6 +115,16 @@ public:
|
||||
*/
|
||||
static void DoCommandReturnStoryPageElementID(ScriptInstance *instance);
|
||||
|
||||
/**
|
||||
* Return a LeagueTableID reply for a DoCommand.
|
||||
*/
|
||||
static void DoCommandReturnLeagueTableID(ScriptInstance *instance);
|
||||
|
||||
/**
|
||||
* Return a LeagueTableElementID reply for a DoCommand.
|
||||
*/
|
||||
static void DoCommandReturnLeagueTableElementID(ScriptInstance *instance);
|
||||
|
||||
/**
|
||||
* Get the controller attached to the instance.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user