Update to 1.10.0-beta1
This commit is contained in:
+1
-1
@@ -142,7 +142,7 @@ public:
|
||||
break;
|
||||
}
|
||||
Lex();
|
||||
return ret;
|
||||
return std::move(ret);
|
||||
}
|
||||
bool IsEndOfStatement() { return ((_lex._prevtoken == '\n') || (_token == SQUIRREL_EOB) || (_token == '}') || (_token == ';')); }
|
||||
void OptionalSemicolon()
|
||||
|
||||
-13
@@ -20,12 +20,6 @@ struct SQOuterVar
|
||||
_src=src;
|
||||
_type=t;
|
||||
}
|
||||
SQOuterVar(const SQOuterVar &ov)
|
||||
{
|
||||
_type=ov._type;
|
||||
_src=ov._src;
|
||||
_name=ov._name;
|
||||
}
|
||||
SQOuterType _type;
|
||||
SQObjectPtr _name;
|
||||
SQObjectPtr _src;
|
||||
@@ -34,13 +28,6 @@ struct SQOuterVar
|
||||
struct SQLocalVarInfo
|
||||
{
|
||||
SQLocalVarInfo():_start_op(0),_end_op(0), _pos(0){}
|
||||
SQLocalVarInfo(const SQLocalVarInfo &lvi)
|
||||
{
|
||||
_name=lvi._name;
|
||||
_start_op=lvi._start_op;
|
||||
_end_op=lvi._end_op;
|
||||
_pos=lvi._pos;
|
||||
}
|
||||
SQObjectPtr _name;
|
||||
SQUnsignedInteger _start_op;
|
||||
SQUnsignedInteger _end_op;
|
||||
|
||||
+2
-2
@@ -502,14 +502,14 @@ SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)
|
||||
{
|
||||
SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
|
||||
_table(_strings)->NewSlot(ns,(SQInteger)1);
|
||||
return ns;
|
||||
return std::move(ns);
|
||||
}
|
||||
|
||||
SQObject SQFuncState::CreateTable()
|
||||
{
|
||||
SQObjectPtr nt(SQTable::Create(_sharedstate,0));
|
||||
_table(_strings)->NewSlot(nt,(SQInteger)1);
|
||||
return nt;
|
||||
return std::move(nt);
|
||||
}
|
||||
|
||||
SQFunctionProto *SQFuncState::BuildProto()
|
||||
|
||||
+5
-3
@@ -9,8 +9,10 @@
|
||||
#include "../../../core/alloc_func.hpp"
|
||||
#include "../../../safeguards.h"
|
||||
|
||||
void *sq_vm_malloc(SQUnsignedInteger size){ return MallocT<char>((size_t)size); }
|
||||
#ifdef SQUIRREL_DEFAULT_ALLOCATOR
|
||||
void *sq_vm_malloc(SQUnsignedInteger size) { return MallocT<char>((size_t)size); }
|
||||
|
||||
void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return ReallocT<char>(static_cast<char*>(p), (size_t)size); }
|
||||
void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size) { return ReallocT<char>(static_cast<char*>(p), (size_t)size); }
|
||||
|
||||
void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); }
|
||||
void sq_vm_free(void *p, SQUnsignedInteger size) { free(p); }
|
||||
#endif
|
||||
|
||||
+2
-3
@@ -12,9 +12,8 @@
|
||||
void sq_base_register(HSQUIRRELVM v);
|
||||
|
||||
struct SQExceptionTrap{
|
||||
SQExceptionTrap() {}
|
||||
SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
|
||||
SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
|
||||
SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target)
|
||||
: _stackbase(stackbase), _stacksize(ss), _ip(ip), _extarget(ex_target) {}
|
||||
SQInteger _stackbase;
|
||||
SQInteger _stacksize;
|
||||
SQInstruction *_ip;
|
||||
|
||||
+1
-3
@@ -32,7 +32,7 @@ public:
|
||||
START_NEXT_EASY = DAYS_IN_YEAR * 2,
|
||||
START_NEXT_MEDIUM = DAYS_IN_YEAR,
|
||||
START_NEXT_HARD = DAYS_IN_YEAR / 2,
|
||||
START_NEXT_MIN = 1,
|
||||
START_NEXT_MIN = 0,
|
||||
START_NEXT_MAX = 3600,
|
||||
START_NEXT_DEVIATION = 60,
|
||||
};
|
||||
@@ -164,11 +164,9 @@ public:
|
||||
/** Gets the ScriptScanner instance that is used to find AI Libraries */
|
||||
static AIScannerLibrary *GetScannerLibrary();
|
||||
|
||||
#if defined(ENABLE_NETWORK)
|
||||
/** Wrapper function for AIScanner::HasAI */
|
||||
static bool HasAI(const struct ContentInfo *ci, bool md5sum);
|
||||
static bool HasAILibrary(const ContentInfo *ci, bool md5sum);
|
||||
#endif
|
||||
private:
|
||||
static uint frame_counter; ///< Tick counter for the AI code
|
||||
static class AIScannerInfo *scanner_info; ///< ScriptScanner instance that is used to find AIs
|
||||
|
||||
+16
-5
@@ -31,7 +31,7 @@ ScriptConfigItem _start_date_config = {
|
||||
AI::START_NEXT_DEVIATION,
|
||||
30,
|
||||
SCRIPTCONFIG_NONE,
|
||||
NULL,
|
||||
nullptr,
|
||||
false
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ AIConfig::AIConfig(const AIConfig *config) : ScriptConfig(config)
|
||||
} else {
|
||||
config = &_settings_game.ai_config[company];
|
||||
}
|
||||
if (*config == NULL) *config = new AIConfig();
|
||||
if (*config == nullptr) *config = new AIConfig();
|
||||
return *config;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ ScriptInfo *AIConfig::FindInfo(const char *name, int version, bool force_exact_m
|
||||
bool AIConfig::ResetInfo(bool force_exact_match)
|
||||
{
|
||||
this->info = (ScriptInfo *)AI::FindInfo(this->name, force_exact_match ? this->version : -1, force_exact_match);
|
||||
return this->info != NULL;
|
||||
return this->info != nullptr;
|
||||
}
|
||||
|
||||
void AIConfig::PushExtraConfigList()
|
||||
@@ -90,7 +90,7 @@ void AIConfig::ClearConfigList()
|
||||
|
||||
int AIConfig::GetSetting(const char *name) const
|
||||
{
|
||||
if (this->info == NULL) {
|
||||
if (this->info == nullptr) {
|
||||
SettingValueList::const_iterator it = this->settings.find(name);
|
||||
if (it == this->settings.end()) {
|
||||
assert(strcmp("start_date", name) == 0);
|
||||
@@ -111,7 +111,7 @@ int AIConfig::GetSetting(const char *name) const
|
||||
|
||||
void AIConfig::SetSetting(const char *name, int value)
|
||||
{
|
||||
if (this->info == NULL) {
|
||||
if (this->info == nullptr) {
|
||||
if (strcmp("start_date", name) != 0) return;
|
||||
value = Clamp(value, AI::START_NEXT_MIN, AI::START_NEXT_MAX);
|
||||
|
||||
@@ -127,3 +127,14 @@ void AIConfig::SetSetting(const char *name, int value)
|
||||
|
||||
ScriptConfig::SetSetting(name, value);
|
||||
}
|
||||
|
||||
void AIConfig::AddRandomDeviation()
|
||||
{
|
||||
int start_date = this->GetSetting("start_date");
|
||||
|
||||
ScriptConfig::AddRandomDeviation();
|
||||
|
||||
/* start_date = 0 is a special case, where random deviation does not occur.
|
||||
* If start_date was not already 0, then a minimum value of 1 must apply. */
|
||||
this->SetSetting("start_date", start_date != 0 ? max(1, this->GetSetting("start_date")) : 0);
|
||||
}
|
||||
|
||||
@@ -30,8 +30,9 @@ public:
|
||||
|
||||
class AIInfo *GetInfo() const;
|
||||
|
||||
/* virtual */ int GetSetting(const char *name) const;
|
||||
/* virtual */ void SetSetting(const char *name, int value);
|
||||
int GetSetting(const char *name) const override;
|
||||
void SetSetting(const char *name, int value) override;
|
||||
void AddRandomDeviation() override;
|
||||
|
||||
/**
|
||||
* When ever the AI Scanner is reloaded, all infos become invalid. This
|
||||
@@ -44,9 +45,9 @@ public:
|
||||
bool ResetInfo(bool force_exact_match);
|
||||
|
||||
protected:
|
||||
/* virtual */ void PushExtraConfigList();
|
||||
/* virtual */ void ClearConfigList();
|
||||
/* virtual */ ScriptInfo *FindInfo(const char *name, int version, bool force_exact_match);
|
||||
void PushExtraConfigList() override;
|
||||
void ClearConfigList() override;
|
||||
ScriptInfo *FindInfo(const char *name, int version, bool force_exact_match) override;
|
||||
};
|
||||
|
||||
#endif /* AI_CONFIG_HPP */
|
||||
|
||||
+30
-34
@@ -26,8 +26,8 @@
|
||||
#include "../safeguards.h"
|
||||
|
||||
/* static */ uint AI::frame_counter = 0;
|
||||
/* static */ AIScannerInfo *AI::scanner_info = NULL;
|
||||
/* static */ AIScannerLibrary *AI::scanner_library = NULL;
|
||||
/* static */ AIScannerInfo *AI::scanner_info = nullptr;
|
||||
/* static */ AIScannerLibrary *AI::scanner_library = nullptr;
|
||||
|
||||
/* static */ bool AI::CanStartNew()
|
||||
{
|
||||
@@ -44,19 +44,19 @@
|
||||
|
||||
AIConfig *config = AIConfig::GetConfig(company, AIConfig::SSS_FORCE_GAME);
|
||||
AIInfo *info = config->GetInfo();
|
||||
if (info == NULL || (rerandomise_ai && config->IsRandom())) {
|
||||
if (info == nullptr || (rerandomise_ai && config->IsRandom())) {
|
||||
info = AI::scanner_info->SelectRandomAI();
|
||||
assert(info != NULL);
|
||||
assert(info != nullptr);
|
||||
/* Load default data and store the name in the settings */
|
||||
config->Change(info->GetName(), -1, false, true);
|
||||
}
|
||||
config->AnchorUnchangeableSettings();
|
||||
|
||||
Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Company *c = Company::Get(company);
|
||||
|
||||
c->ai_info = info;
|
||||
assert(c->ai_instance == NULL);
|
||||
assert(c->ai_instance == nullptr);
|
||||
c->ai_instance = new AIInstance();
|
||||
c->ai_instance->Initialize(info);
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
assert(_settings_game.difficulty.competitor_speed <= 4);
|
||||
if ((AI::frame_counter & ((1 << (4 - _settings_game.difficulty.competitor_speed)) - 1)) != 0) return;
|
||||
|
||||
Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, FILE_LINE);
|
||||
const Company *c;
|
||||
FOR_ALL_COMPANIES(c) {
|
||||
if (c->is_ai) {
|
||||
@@ -107,12 +107,12 @@
|
||||
if (_networking && !_network_server) return;
|
||||
PerformanceMeasurer::SetInactive((PerformanceElement)(PFE_AI0 + company));
|
||||
|
||||
Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Company *c = Company::Get(company);
|
||||
|
||||
delete c->ai_instance;
|
||||
c->ai_instance = NULL;
|
||||
c->ai_info = NULL;
|
||||
c->ai_instance = nullptr;
|
||||
c->ai_info = nullptr;
|
||||
|
||||
cur_company.Restore();
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
* for the server owner to unpause the script again. */
|
||||
if (_network_dedicated) return;
|
||||
|
||||
Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Company::Get(company)->ai_instance->Pause();
|
||||
|
||||
cur_company.Restore();
|
||||
@@ -135,7 +135,7 @@
|
||||
|
||||
/* static */ void AI::Unpause(CompanyID company)
|
||||
{
|
||||
Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Company::Get(company)->ai_instance->Unpause();
|
||||
|
||||
cur_company.Restore();
|
||||
@@ -143,7 +143,7 @@
|
||||
|
||||
/* static */ bool AI::IsPaused(CompanyID company)
|
||||
{
|
||||
Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
bool paused = Company::Get(company)->ai_instance->IsPaused();
|
||||
|
||||
cur_company.Restore();
|
||||
@@ -164,10 +164,10 @@
|
||||
|
||||
/* static */ void AI::Initialize()
|
||||
{
|
||||
if (AI::scanner_info != NULL) AI::Uninitialize(true);
|
||||
if (AI::scanner_info != nullptr) AI::Uninitialize(true);
|
||||
|
||||
AI::frame_counter = 0;
|
||||
if (AI::scanner_info == NULL) {
|
||||
if (AI::scanner_info == nullptr) {
|
||||
TarScanner::DoScan(TarScanner::AI);
|
||||
AI::scanner_info = new AIScannerInfo();
|
||||
AI::scanner_info->Initialize();
|
||||
@@ -187,17 +187,17 @@
|
||||
} else {
|
||||
delete AI::scanner_info;
|
||||
delete AI::scanner_library;
|
||||
AI::scanner_info = NULL;
|
||||
AI::scanner_library = NULL;
|
||||
AI::scanner_info = nullptr;
|
||||
AI::scanner_library = nullptr;
|
||||
|
||||
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
|
||||
if (_settings_game.ai_config[c] != NULL) {
|
||||
if (_settings_game.ai_config[c] != nullptr) {
|
||||
delete _settings_game.ai_config[c];
|
||||
_settings_game.ai_config[c] = NULL;
|
||||
_settings_game.ai_config[c] = nullptr;
|
||||
}
|
||||
if (_settings_newgame.ai_config[c] != NULL) {
|
||||
if (_settings_newgame.ai_config[c] != nullptr) {
|
||||
delete _settings_newgame.ai_config[c];
|
||||
_settings_newgame.ai_config[c] = NULL;
|
||||
_settings_newgame.ai_config[c] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,10 +209,10 @@
|
||||
* the AIConfig. If not, remove the AI from the list (which will assign
|
||||
* a random new AI on reload). */
|
||||
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
|
||||
if (_settings_game.ai_config[c] != NULL && _settings_game.ai_config[c]->HasScript()) {
|
||||
if (_settings_game.ai_config[c] != nullptr && _settings_game.ai_config[c]->HasScript()) {
|
||||
if (!_settings_game.ai_config[c]->ResetInfo(true)) {
|
||||
DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
|
||||
_settings_game.ai_config[c]->Change(NULL);
|
||||
_settings_game.ai_config[c]->Change(nullptr);
|
||||
if (Company::IsValidAiID(c)) {
|
||||
/* The code belonging to an already running AI was deleted. We can only do
|
||||
* one thing here to keep everything sane and that is kill the AI. After
|
||||
@@ -226,10 +226,10 @@
|
||||
Company::Get(c)->ai_info = _settings_game.ai_config[c]->GetInfo();
|
||||
}
|
||||
}
|
||||
if (_settings_newgame.ai_config[c] != NULL && _settings_newgame.ai_config[c]->HasScript()) {
|
||||
if (_settings_newgame.ai_config[c] != nullptr && _settings_newgame.ai_config[c]->HasScript()) {
|
||||
if (!_settings_newgame.ai_config[c]->ResetInfo(false)) {
|
||||
DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
|
||||
_settings_newgame.ai_config[c]->Change(NULL);
|
||||
_settings_newgame.ai_config[c]->Change(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,7 +253,7 @@
|
||||
}
|
||||
|
||||
/* Queue the event */
|
||||
Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Company::Get(_current_company)->ai_instance->InsertEvent(event);
|
||||
cur_company.Restore();
|
||||
|
||||
@@ -283,9 +283,9 @@
|
||||
{
|
||||
if (!_networking || _network_server) {
|
||||
Company *c = Company::GetIfValid(company);
|
||||
assert(c != NULL && c->ai_instance != NULL);
|
||||
assert(c != nullptr && c->ai_instance != nullptr);
|
||||
|
||||
Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
c->ai_instance->Save();
|
||||
cur_company.Restore();
|
||||
} else {
|
||||
@@ -297,9 +297,9 @@
|
||||
{
|
||||
if (!_networking || _network_server) {
|
||||
Company *c = Company::GetIfValid(company);
|
||||
assert(c != NULL && c->ai_instance != NULL);
|
||||
assert(c != nullptr && c->ai_instance != nullptr);
|
||||
|
||||
Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
c->ai_instance->Load(version);
|
||||
cur_company.Restore();
|
||||
} else {
|
||||
@@ -362,8 +362,6 @@
|
||||
InvalidateWindowClassesData(WC_AI_SETTINGS);
|
||||
}
|
||||
|
||||
#if defined(ENABLE_NETWORK)
|
||||
|
||||
/**
|
||||
* Check whether we have an AI (library) with the exact characteristics as ci.
|
||||
* @param ci the characteristics to search on (shortname and md5sum)
|
||||
@@ -380,8 +378,6 @@
|
||||
return AI::scanner_library->HasScript(ci, md5sum);
|
||||
}
|
||||
|
||||
#endif /* defined(ENABLE_NETWORK) */
|
||||
|
||||
/* static */ AIScannerInfo *AI::GetScannerInfo()
|
||||
{
|
||||
return AI::scanner_info;
|
||||
|
||||
+65
-67
@@ -98,7 +98,7 @@ struct AIListWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AIL_CAPTION:
|
||||
@@ -107,7 +107,7 @@ struct AIListWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
if (widget == WID_AIL_LIST) {
|
||||
this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
|
||||
@@ -118,7 +118,7 @@ struct AIListWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AIL_LIST: {
|
||||
@@ -139,13 +139,13 @@ struct AIListWindow : public Window {
|
||||
break;
|
||||
}
|
||||
case WID_AIL_INFO_BG: {
|
||||
AIInfo *selected_info = NULL;
|
||||
AIInfo *selected_info = nullptr;
|
||||
ScriptInfoList::const_iterator it = this->info_list->begin();
|
||||
for (int i = 1; selected_info == NULL && it != this->info_list->end(); i++, it++) {
|
||||
for (int i = 1; selected_info == nullptr && it != this->info_list->end(); i++, it++) {
|
||||
if (this->selected == i - 1) selected_info = static_cast<AIInfo *>((*it).second);
|
||||
}
|
||||
/* Some info about the currently selected AI. */
|
||||
if (selected_info != NULL) {
|
||||
if (selected_info != nullptr) {
|
||||
int y = r.top + WD_FRAMERECT_TOP;
|
||||
SetDParamStr(0, selected_info->GetAuthor());
|
||||
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_AUTHOR);
|
||||
@@ -153,7 +153,7 @@ struct AIListWindow : public Window {
|
||||
SetDParam(0, selected_info->GetVersion());
|
||||
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_VERSION);
|
||||
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
|
||||
if (selected_info->GetURL() != NULL) {
|
||||
if (selected_info->GetURL() != nullptr) {
|
||||
SetDParamStr(0, selected_info->GetURL());
|
||||
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_URL);
|
||||
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
|
||||
@@ -172,7 +172,7 @@ struct AIListWindow : public Window {
|
||||
void ChangeAI()
|
||||
{
|
||||
if (this->selected == -1) {
|
||||
GetConfig(slot)->Change(NULL);
|
||||
GetConfig(slot)->Change(nullptr);
|
||||
} else {
|
||||
ScriptInfoList::const_iterator it = this->info_list->begin();
|
||||
for (int i = 0; i < this->selected; i++) it++;
|
||||
@@ -183,7 +183,7 @@ struct AIListWindow : public Window {
|
||||
DeleteWindowByClass(WC_QUERY_STRING);
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AIL_LIST: { // Select one of the AIs
|
||||
@@ -211,7 +211,7 @@ struct AIListWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnResize()
|
||||
void OnResize() override
|
||||
{
|
||||
this->vscroll->SetCapacityFromWidget(this, WID_AIL_LIST);
|
||||
}
|
||||
@@ -221,7 +221,7 @@ struct AIListWindow : public Window {
|
||||
* @param data Information about the changed data.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (_game_mode == GM_NORMAL && Company::IsValidID(this->slot)) {
|
||||
delete this;
|
||||
@@ -317,7 +317,7 @@ struct AISettingsWindow : public Window {
|
||||
this->RebuildVisibleSettings();
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AIS_CAPTION:
|
||||
@@ -346,7 +346,7 @@ struct AISettingsWindow : public Window {
|
||||
this->vscroll->SetCount((int)this->visible_settings.size());
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
if (widget == WID_AIS_BACKGROUND) {
|
||||
this->line_height = max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
|
||||
@@ -357,7 +357,7 @@ struct AISettingsWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
if (widget != WID_AIS_BACKGROUND) return;
|
||||
|
||||
@@ -407,7 +407,7 @@ struct AISettingsWindow : public Window {
|
||||
} else {
|
||||
DrawArrowButtons(buttons_left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value);
|
||||
}
|
||||
if (config_item.labels != NULL && config_item.labels->Contains(current_value)) {
|
||||
if (config_item.labels != nullptr && config_item.labels->Contains(current_value)) {
|
||||
SetDParam(idx++, STR_JUST_RAW_STRING);
|
||||
SetDParamStr(idx++, config_item.labels->Find(current_value)->second);
|
||||
} else {
|
||||
@@ -421,7 +421,7 @@ struct AISettingsWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPaint()
|
||||
void OnPaint() override
|
||||
{
|
||||
if (this->closing_dropdown) {
|
||||
this->closing_dropdown = false;
|
||||
@@ -430,7 +430,7 @@ struct AISettingsWindow : public Window {
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AIS_BACKGROUND: {
|
||||
@@ -479,12 +479,12 @@ struct AISettingsWindow : public Window {
|
||||
this->clicked_dropdown = true;
|
||||
this->closing_dropdown = false;
|
||||
|
||||
DropDownList *list = new DropDownList();
|
||||
DropDownList list;
|
||||
for (int i = config_item.min_value; i <= config_item.max_value; i++) {
|
||||
*list->Append() = new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false);
|
||||
list.emplace_back(new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false));
|
||||
}
|
||||
|
||||
ShowDropDownListAt(this, list, old_val, -1, wi_rect, COLOUR_ORANGE, true);
|
||||
ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE, true);
|
||||
}
|
||||
}
|
||||
} else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) {
|
||||
@@ -530,7 +530,7 @@ struct AISettingsWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnQueryTextFinished(char *str)
|
||||
void OnQueryTextFinished(char *str) override
|
||||
{
|
||||
if (StrEmpty(str)) return;
|
||||
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
|
||||
@@ -542,7 +542,7 @@ struct AISettingsWindow : public Window {
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
virtual void OnDropdownSelect(int widget, int index)
|
||||
void OnDropdownSelect(int widget, int index) override
|
||||
{
|
||||
assert(this->clicked_dropdown);
|
||||
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
|
||||
@@ -553,7 +553,7 @@ struct AISettingsWindow : public Window {
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
virtual void OnDropdownClose(Point pt, int widget, int index, bool instant_close)
|
||||
void OnDropdownClose(Point pt, int widget, int index, bool instant_close) override
|
||||
{
|
||||
/* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
|
||||
* the same dropdown button was clicked again, and then not open the dropdown again.
|
||||
@@ -564,12 +564,12 @@ struct AISettingsWindow : public Window {
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
virtual void OnResize()
|
||||
void OnResize() override
|
||||
{
|
||||
this->vscroll->SetCapacityFromWidget(this, WID_AIS_BACKGROUND);
|
||||
}
|
||||
|
||||
virtual void OnRealtimeTick(uint delta_ms)
|
||||
void OnRealtimeTick(uint delta_ms) override
|
||||
{
|
||||
if (this->timeout.Elapsed(delta_ms)) {
|
||||
this->clicked_button = -1;
|
||||
@@ -582,7 +582,7 @@ struct AISettingsWindow : public Window {
|
||||
* @param data Information about the changed data.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
this->RebuildVisibleSettings();
|
||||
HideDropDownMenu(this);
|
||||
@@ -646,7 +646,7 @@ struct ScriptTextfileWindow : public TextfileWindow {
|
||||
this->LoadTextfile(textfile, (slot == OWNER_DEITY) ? GAME_DIR : AI_DIR);
|
||||
}
|
||||
|
||||
/* virtual */ void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
if (widget == WID_TF_CAPTION) {
|
||||
SetDParam(0, (slot == OWNER_DEITY) ? STR_CONTENT_TYPE_GAME_SCRIPT : STR_CONTENT_TYPE_AI);
|
||||
@@ -743,7 +743,7 @@ struct AIConfigWindow : public Window {
|
||||
DeleteWindowByClass(WC_AI_SETTINGS);
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AIC_NUMBER:
|
||||
@@ -767,7 +767,7 @@ struct AIConfigWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AIC_GAMELIST:
|
||||
@@ -805,12 +805,12 @@ struct AIConfigWindow : public Window {
|
||||
*/
|
||||
static bool IsEditable(CompanyID slot)
|
||||
{
|
||||
if (slot == OWNER_DEITY) return _game_mode != GM_NORMAL || Game::GetInstance() != NULL;
|
||||
if (slot == OWNER_DEITY) return _game_mode != GM_NORMAL || Game::GetInstance() != nullptr;
|
||||
|
||||
if (_game_mode != GM_NORMAL) {
|
||||
return slot > 0 && slot <= GetGameSettings().difficulty.max_no_competitors;
|
||||
}
|
||||
if (Company::IsValidID(slot) || slot < 0) return false;
|
||||
if (Company::IsValidID(slot)) return false;
|
||||
|
||||
int max_slot = GetGameSettings().difficulty.max_no_competitors;
|
||||
for (CompanyID cid = COMPANY_FIRST; cid < (CompanyID)max_slot && cid < MAX_COMPANIES; cid++) {
|
||||
@@ -819,13 +819,13 @@ struct AIConfigWindow : public Window {
|
||||
return slot < max_slot;
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AIC_GAMELIST: {
|
||||
StringID text = STR_AI_CONFIG_NONE;
|
||||
|
||||
if (GameConfig::GetConfig()->GetInfo() != NULL) {
|
||||
if (GameConfig::GetConfig()->GetInfo() != nullptr) {
|
||||
SetDParamStr(0, GameConfig::GetConfig()->GetInfo()->GetName());
|
||||
text = STR_JUST_RAW_STRING;
|
||||
}
|
||||
@@ -843,7 +843,7 @@ struct AIConfigWindow : public Window {
|
||||
|
||||
if ((_game_mode != GM_NORMAL && i == 0) || (_game_mode == GM_NORMAL && Company::IsValidHumanID(i))) {
|
||||
text = STR_AI_CONFIG_HUMAN_PLAYER;
|
||||
} else if (AIConfig::GetConfig((CompanyID)i)->GetInfo() != NULL) {
|
||||
} else if (AIConfig::GetConfig((CompanyID)i)->GetInfo() != nullptr) {
|
||||
SetDParamStr(0, AIConfig::GetConfig((CompanyID)i)->GetInfo()->GetName());
|
||||
text = STR_JUST_RAW_STRING;
|
||||
} else {
|
||||
@@ -858,10 +858,10 @@ struct AIConfigWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
if (widget >= WID_AIC_TEXTFILE && widget < WID_AIC_TEXTFILE + TFT_END) {
|
||||
if (this->selected_slot == INVALID_COMPANY || GetConfig(this->selected_slot) == NULL) return;
|
||||
if (this->selected_slot == INVALID_COMPANY || GetConfig(this->selected_slot) == nullptr) return;
|
||||
|
||||
ShowScriptTextfileWindow((TextfileType)(widget - WID_AIC_TEXTFILE), this->selected_slot);
|
||||
return;
|
||||
@@ -928,9 +928,7 @@ struct AIConfigWindow : public Window {
|
||||
if (!_network_available) {
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
|
||||
} else {
|
||||
#if defined(ENABLE_NETWORK)
|
||||
ShowNetworkContentListWindow(NULL, CONTENT_TYPE_AI, CONTENT_TYPE_GAME);
|
||||
#endif
|
||||
ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_AI, CONTENT_TYPE_GAME);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -941,7 +939,7 @@ struct AIConfigWindow : public Window {
|
||||
* @param data Information about the changed data.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (!IsEditable(this->selected_slot)) {
|
||||
this->selected_slot = INVALID_COMPANY;
|
||||
@@ -957,7 +955,7 @@ struct AIConfigWindow : public Window {
|
||||
this->SetWidgetDisabledState(WID_AIC_MOVE_DOWN, this->selected_slot == OWNER_DEITY || this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot + 1)));
|
||||
|
||||
for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) {
|
||||
this->SetWidgetDisabledState(WID_AIC_TEXTFILE + tft, this->selected_slot == INVALID_COMPANY || (GetConfig(this->selected_slot)->GetTextfile(tft, this->selected_slot) == NULL));
|
||||
this->SetWidgetDisabledState(WID_AIC_TEXTFILE + tft, this->selected_slot == INVALID_COMPANY || (GetConfig(this->selected_slot)->GetTextfile(tft, this->selected_slot) == nullptr));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1026,7 +1024,7 @@ struct AIDebugWindow : public Window {
|
||||
{
|
||||
if (ai_debug_company == OWNER_DEITY) {
|
||||
GameInstance *game = Game::GetInstance();
|
||||
return game == NULL || game->IsDead();
|
||||
return game == nullptr || game->IsDead();
|
||||
}
|
||||
return !Company::IsValidAiID(ai_debug_company) || Company::Get(ai_debug_company)->ai_instance->IsDead();
|
||||
}
|
||||
@@ -1040,7 +1038,7 @@ struct AIDebugWindow : public Window {
|
||||
{
|
||||
switch (company) {
|
||||
case INVALID_COMPANY: return false;
|
||||
case OWNER_DEITY: return Game::GetInstance() != NULL;
|
||||
case OWNER_DEITY: return Game::GetInstance() != nullptr;
|
||||
default: return Company::IsValidAiID(company);
|
||||
}
|
||||
}
|
||||
@@ -1065,7 +1063,7 @@ struct AIDebugWindow : public Window {
|
||||
}
|
||||
|
||||
/* If no AI is available, see if there is a game script. */
|
||||
if (Game::GetInstance() != NULL) ChangeToAI(OWNER_DEITY);
|
||||
if (Game::GetInstance() != nullptr) ChangeToAI(OWNER_DEITY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1098,7 +1096,7 @@ struct AIDebugWindow : public Window {
|
||||
this->InvalidateData(-1);
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
if (widget == WID_AID_LOG_PANEL) {
|
||||
resize->height = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
|
||||
@@ -1106,7 +1104,7 @@ struct AIDebugWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPaint()
|
||||
void OnPaint() override
|
||||
{
|
||||
this->SelectValidDebugCompany();
|
||||
|
||||
@@ -1142,7 +1140,7 @@ struct AIDebugWindow : public Window {
|
||||
|
||||
/* Set button colour for Game Script. */
|
||||
GameInstance *game = Game::GetInstance();
|
||||
bool valid = game != NULL;
|
||||
bool valid = game != nullptr;
|
||||
bool dead = valid && game->IsDead();
|
||||
bool paused = valid && game->IsPaused();
|
||||
|
||||
@@ -1156,7 +1154,7 @@ struct AIDebugWindow : public Window {
|
||||
|
||||
ScriptLog::LogData *log = this->GetLogPointer();
|
||||
|
||||
int scroll_count = (log == NULL) ? 0 : log->used;
|
||||
int scroll_count = (log == nullptr) ? 0 : log->used;
|
||||
if (this->vscroll->GetCount() != scroll_count) {
|
||||
this->vscroll->SetCount(scroll_count);
|
||||
|
||||
@@ -1164,7 +1162,7 @@ struct AIDebugWindow : public Window {
|
||||
this->SetWidgetDirty(WID_AID_SCROLLBAR);
|
||||
}
|
||||
|
||||
if (log == NULL) return;
|
||||
if (log == nullptr) return;
|
||||
|
||||
/* Detect when the user scrolls the window. Enable autoscroll when the
|
||||
* bottom-most line becomes visible. */
|
||||
@@ -1184,13 +1182,13 @@ struct AIDebugWindow : public Window {
|
||||
this->last_vscroll_pos = this->vscroll->GetPosition();
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AID_NAME_TEXT:
|
||||
if (ai_debug_company == OWNER_DEITY) {
|
||||
const GameInfo *info = Game::GetInfo();
|
||||
assert(info != NULL);
|
||||
assert(info != nullptr);
|
||||
SetDParam(0, STR_AI_DEBUG_NAME_AND_VERSION);
|
||||
SetDParamStr(1, info->GetName());
|
||||
SetDParam(2, info->GetVersion());
|
||||
@@ -1198,7 +1196,7 @@ struct AIDebugWindow : public Window {
|
||||
SetDParam(0, STR_EMPTY);
|
||||
} else {
|
||||
const AIInfo *info = Company::Get(ai_debug_company)->ai_info;
|
||||
assert(info != NULL);
|
||||
assert(info != nullptr);
|
||||
SetDParam(0, STR_AI_DEBUG_NAME_AND_VERSION);
|
||||
SetDParamStr(1, info->GetName());
|
||||
SetDParam(2, info->GetVersion());
|
||||
@@ -1207,19 +1205,19 @@ struct AIDebugWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
if (ai_debug_company == INVALID_COMPANY) return;
|
||||
|
||||
switch (widget) {
|
||||
case WID_AID_LOG_PANEL: {
|
||||
ScriptLog::LogData *log = this->GetLogPointer();
|
||||
if (log == NULL) return;
|
||||
if (log == nullptr) return;
|
||||
|
||||
int y = this->top_offset;
|
||||
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < log->used; i++) {
|
||||
int pos = (i + log->pos + 1 - log->used + log->count) % log->count;
|
||||
if (log->lines[pos] == NULL) break;
|
||||
if (log->lines[pos] == nullptr) break;
|
||||
|
||||
TextColour colour;
|
||||
switch (log->type[pos]) {
|
||||
@@ -1266,7 +1264,7 @@ struct AIDebugWindow : public Window {
|
||||
this->last_vscroll_pos = this->vscroll->GetPosition();
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
/* Also called for hotkeys, so check for disabledness */
|
||||
if (this->IsWidgetDisabled(widget)) return;
|
||||
@@ -1336,7 +1334,7 @@ struct AIDebugWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnEditboxChanged(int wid)
|
||||
void OnEditboxChanged(int wid) override
|
||||
{
|
||||
if (wid == WID_AID_BREAK_STR_EDIT_BOX) {
|
||||
/* Save the current string to static member so it can be restored next time the window is opened. */
|
||||
@@ -1351,7 +1349,7 @@ struct AIDebugWindow : public Window {
|
||||
* This is the company ID of the AI/GS which wrote a new log message, or -1 in other cases.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
/* If the log message is related to the active company tab, check the break string.
|
||||
* This needs to be done in gameloop-scope, so the AI is suspended immediately. */
|
||||
@@ -1359,7 +1357,7 @@ struct AIDebugWindow : public Window {
|
||||
/* Get the log instance of the active company */
|
||||
ScriptLog::LogData *log = this->GetLogPointer();
|
||||
|
||||
if (log != NULL) {
|
||||
if (log != nullptr) {
|
||||
this->break_string_filter.ResetState();
|
||||
this->break_string_filter.AddLine(log->lines[log->pos]);
|
||||
if (this->break_string_filter.GetState()) {
|
||||
@@ -1387,8 +1385,8 @@ struct AIDebugWindow : public Window {
|
||||
|
||||
this->SelectValidDebugCompany();
|
||||
|
||||
ScriptLog::LogData *log = ai_debug_company != INVALID_COMPANY ? this->GetLogPointer() : NULL;
|
||||
this->vscroll->SetCount((log == NULL) ? 0 : log->used);
|
||||
ScriptLog::LogData *log = ai_debug_company != INVALID_COMPANY ? this->GetLogPointer() : nullptr;
|
||||
this->vscroll->SetCount((log == nullptr) ? 0 : log->used);
|
||||
|
||||
/* Update company buttons */
|
||||
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
|
||||
@@ -1396,7 +1394,7 @@ struct AIDebugWindow : public Window {
|
||||
this->SetWidgetLoweredState(i + WID_AID_COMPANY_BUTTON_START, ai_debug_company == i);
|
||||
}
|
||||
|
||||
this->SetWidgetDisabledState(WID_AID_SCRIPT_GAME, Game::GetGameInstance() == NULL);
|
||||
this->SetWidgetDisabledState(WID_AID_SCRIPT_GAME, Game::GetGameInstance() == nullptr);
|
||||
this->SetWidgetLoweredState(WID_AID_SCRIPT_GAME, ai_debug_company == OWNER_DEITY);
|
||||
|
||||
this->SetWidgetLoweredState(WID_AID_BREAK_STR_ON_OFF_BTN, this->break_check_enabled);
|
||||
@@ -1408,7 +1406,7 @@ struct AIDebugWindow : public Window {
|
||||
(ai_debug_company == OWNER_DEITY ? !Game::IsPaused() : !AI::IsPaused(ai_debug_company)));
|
||||
}
|
||||
|
||||
virtual void OnResize()
|
||||
void OnResize() override
|
||||
{
|
||||
this->vscroll->SetCapacityFromWidget(this, WID_AID_LOG_PANEL);
|
||||
}
|
||||
@@ -1439,7 +1437,7 @@ static EventState AIDebugGlobalHotkeys(int hotkey)
|
||||
{
|
||||
if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED;
|
||||
Window *w = ShowAIDebugWindow(INVALID_COMPANY);
|
||||
if (w == NULL) return ES_NOT_HANDLED;
|
||||
if (w == nullptr) return ES_NOT_HANDLED;
|
||||
return w->OnHotkey(hotkey);
|
||||
}
|
||||
|
||||
@@ -1532,14 +1530,14 @@ Window *ShowAIDebugWindow(CompanyID show_company)
|
||||
{
|
||||
if (!_networking || _network_server) {
|
||||
AIDebugWindow *w = (AIDebugWindow *)BringWindowToFrontById(WC_AI_DEBUG, 0);
|
||||
if (w == NULL) w = new AIDebugWindow(&_ai_debug_desc, 0);
|
||||
if (w == nullptr) w = new AIDebugWindow(&_ai_debug_desc, 0);
|
||||
if (show_company != INVALID_COMPANY) w->ChangeToAI(show_company);
|
||||
return w;
|
||||
} else {
|
||||
ShowErrorMessage(STR_ERROR_AI_DEBUG_SERVER_ONLY, INVALID_STRING_ID, WL_INFO);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1565,7 +1563,7 @@ void ShowAIDebugWindowIfAIError()
|
||||
}
|
||||
|
||||
GameInstance *g = Game::GetGameInstance();
|
||||
if (g != NULL && g->IsDead()) {
|
||||
if (g != nullptr && g->IsDead()) {
|
||||
ShowAIDebugWindow(OWNER_DEITY);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -29,7 +29,7 @@ static bool CheckAPIVersion(const char *api_version)
|
||||
return strcmp(api_version, "0.7") == 0 || strcmp(api_version, "1.0") == 0 || strcmp(api_version, "1.1") == 0 ||
|
||||
strcmp(api_version, "1.2") == 0 || strcmp(api_version, "1.3") == 0 || strcmp(api_version, "1.4") == 0 ||
|
||||
strcmp(api_version, "1.5") == 0 || strcmp(api_version, "1.6") == 0 || strcmp(api_version, "1.7") == 0 ||
|
||||
strcmp(api_version, "1.8") == 0 || strcmp(api_version, "1.9") == 0;
|
||||
strcmp(api_version, "1.8") == 0 || strcmp(api_version, "1.9") == 0 || strcmp(api_version, "1.10") == 0;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
@@ -65,8 +65,8 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
||||
/* static */ SQInteger AIInfo::Constructor(HSQUIRRELVM vm)
|
||||
{
|
||||
/* Get the AIInfo */
|
||||
SQUserPointer instance = NULL;
|
||||
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == NULL) return sq_throwerror(vm, "Pass an instance of a child class of AIInfo to RegisterAI");
|
||||
SQUserPointer instance = nullptr;
|
||||
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of AIInfo to RegisterAI");
|
||||
AIInfo *info = (AIInfo *)instance;
|
||||
|
||||
SQInteger res = ScriptInfo::Constructor(vm, info);
|
||||
@@ -100,7 +100,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
||||
}
|
||||
|
||||
/* Remove the link to the real instance, else it might get deleted by RegisterAI() */
|
||||
sq_setinstanceup(vm, 2, NULL);
|
||||
sq_setinstanceup(vm, 2, nullptr);
|
||||
/* Register the AI to the base system */
|
||||
info->GetScanner()->RegisterScript(info);
|
||||
return 0;
|
||||
@@ -112,7 +112,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
||||
SQUserPointer instance;
|
||||
sq_getinstanceup(vm, 2, &instance, 0);
|
||||
AIInfo *info = (AIInfo *)instance;
|
||||
info->api_version = NULL;
|
||||
info->api_version = nullptr;
|
||||
|
||||
SQInteger res = ScriptInfo::Constructor(vm, info);
|
||||
if (res != 0) return res;
|
||||
@@ -122,7 +122,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
||||
info->api_version = stredup(buf);
|
||||
|
||||
/* Remove the link to the real instance, else it might get deleted by RegisterAI() */
|
||||
sq_setinstanceup(vm, 2, NULL);
|
||||
sq_setinstanceup(vm, 2, nullptr);
|
||||
/* Register the AI to the base system */
|
||||
static_cast<AIScannerInfo *>(info->GetScanner())->SetDummyAI(info);
|
||||
return 0;
|
||||
@@ -131,7 +131,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
||||
AIInfo::AIInfo() :
|
||||
min_loadable_version(0),
|
||||
use_as_random(false),
|
||||
api_version(NULL)
|
||||
api_version(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ private:
|
||||
/** All static information from an AI library like name, version, etc. */
|
||||
class AILibrary : public ScriptInfo {
|
||||
public:
|
||||
AILibrary() : ScriptInfo(), category(NULL) {};
|
||||
AILibrary() : ScriptInfo(), category(nullptr) {};
|
||||
~AILibrary();
|
||||
|
||||
/**
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "../script/api/ai/ai_rail.hpp.sq"
|
||||
#include "../script/api/ai/ai_railtypelist.hpp.sq"
|
||||
#include "../script/api/ai/ai_road.hpp.sq"
|
||||
#include "../script/api/ai/ai_roadtypelist.hpp.sq"
|
||||
#include "../script/api/ai/ai_sign.hpp.sq"
|
||||
#include "../script/api/ai/ai_signlist.hpp.sq"
|
||||
#include "../script/api/ai/ai_station.hpp.sq"
|
||||
@@ -145,6 +146,7 @@ void AIInstance::RegisterAPI()
|
||||
SQAIEventSubsidyOffer_Register(this->engine);
|
||||
SQAIEventSubsidyOfferExpired_Register(this->engine);
|
||||
SQAIEventTownFounded_Register(this->engine);
|
||||
SQAIEventVehicleAutoReplaced_Register(this->engine);
|
||||
SQAIEventVehicleCrashed_Register(this->engine);
|
||||
SQAIEventVehicleLost_Register(this->engine);
|
||||
SQAIEventVehicleUnprofitable_Register(this->engine);
|
||||
@@ -167,6 +169,7 @@ void AIInstance::RegisterAPI()
|
||||
SQAIRail_Register(this->engine);
|
||||
SQAIRailTypeList_Register(this->engine);
|
||||
SQAIRoad_Register(this->engine);
|
||||
SQAIRoadTypeList_Register(this->engine);
|
||||
SQAISign_Register(this->engine);
|
||||
SQAISignList_Register(this->engine);
|
||||
SQAIStation_Register(this->engine);
|
||||
@@ -216,10 +219,10 @@ void AIInstance::Died()
|
||||
ShowAIDebugWindow(_current_company);
|
||||
|
||||
const AIInfo *info = AIConfig::GetConfig(_current_company, AIConfig::SSS_FORCE_GAME)->GetInfo();
|
||||
if (info != NULL) {
|
||||
if (info != nullptr) {
|
||||
ShowErrorMessage(STR_ERROR_AI_PLEASE_REPORT_CRASH, INVALID_STRING_ID, WL_WARNING);
|
||||
|
||||
if (info->GetURL() != NULL) {
|
||||
if (info->GetURL() != nullptr) {
|
||||
ScriptLog::Info("Please report the error to the following URL:");
|
||||
ScriptLog::Info(info->GetURL());
|
||||
}
|
||||
@@ -228,6 +231,7 @@ void AIInstance::Died()
|
||||
|
||||
void AIInstance::LoadDummyScript()
|
||||
{
|
||||
ScriptAllocatorScope alloc_scope(this->engine);
|
||||
extern void Script_CreateDummy(HSQUIRRELVM vm, StringID string, const char *type);
|
||||
Script_CreateDummy(this->engine->GetVM(), STR_ERROR_AI_NO_AI_FOUND, "AI");
|
||||
}
|
||||
@@ -259,7 +263,7 @@ void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint3
|
||||
* when the company does not exist anymore.
|
||||
*/
|
||||
const Company *c = Company::GetIfValid(_current_company);
|
||||
if (c == NULL || c->ai_instance == NULL) return;
|
||||
if (c == nullptr || c->ai_instance == nullptr) return;
|
||||
|
||||
if (c->ai_instance->DoCommandCallback(result, tile, p1, p2, cmd)) {
|
||||
c->ai_instance->Continue();
|
||||
|
||||
@@ -25,14 +25,14 @@ public:
|
||||
*/
|
||||
void Initialize(class AIInfo *info);
|
||||
|
||||
/* virtual */ int GetSetting(const char *name);
|
||||
/* virtual */ ScriptInfo *FindLibrary(const char *library, int version);
|
||||
int GetSetting(const char *name) override;
|
||||
ScriptInfo *FindLibrary(const char *library, int version) override;
|
||||
|
||||
private:
|
||||
/* virtual */ void RegisterAPI();
|
||||
/* virtual */ void Died();
|
||||
/* virtual */ CommandCallback *GetDoCommandCallback();
|
||||
/* virtual */ void LoadDummyScript();
|
||||
void RegisterAPI() override;
|
||||
void Died() override;
|
||||
CommandCallback *GetDoCommandCallback() override;
|
||||
void LoadDummyScript() override;
|
||||
};
|
||||
|
||||
#endif /* AI_INSTANCE_HPP */
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
AIScannerInfo::AIScannerInfo() :
|
||||
ScriptScanner(),
|
||||
info_dummy(NULL)
|
||||
info_dummy(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ void AIScannerInfo::Initialize()
|
||||
{
|
||||
ScriptScanner::Initialize("AIScanner");
|
||||
|
||||
ScriptAllocatorScope alloc_scope(this->engine);
|
||||
|
||||
/* Create the dummy AI */
|
||||
free(this->main_script);
|
||||
this->main_script = stredup("%_dummy");
|
||||
@@ -94,14 +96,14 @@ AIInfo *AIScannerInfo::SelectRandomAI() const
|
||||
|
||||
AIInfo *AIScannerInfo::FindInfo(const char *nameParam, int versionParam, bool force_exact_match)
|
||||
{
|
||||
if (this->info_list.size() == 0) return NULL;
|
||||
if (nameParam == NULL) return NULL;
|
||||
if (this->info_list.size() == 0) return nullptr;
|
||||
if (nameParam == nullptr) return nullptr;
|
||||
|
||||
char ai_name[1024];
|
||||
strecpy(ai_name, nameParam, lastof(ai_name));
|
||||
strtolower(ai_name);
|
||||
|
||||
AIInfo *info = NULL;
|
||||
AIInfo *info = nullptr;
|
||||
int version = -1;
|
||||
|
||||
if (versionParam == -1) {
|
||||
@@ -110,7 +112,7 @@ AIInfo *AIScannerInfo::FindInfo(const char *nameParam, int versionParam, bool fo
|
||||
|
||||
/* If we didn't find a match AI, maybe the user included a version */
|
||||
char *e = strrchr(ai_name, '.');
|
||||
if (e == NULL) return NULL;
|
||||
if (e == nullptr) return nullptr;
|
||||
*e = '\0';
|
||||
e++;
|
||||
versionParam = atoi(e);
|
||||
@@ -165,7 +167,7 @@ AILibrary *AIScannerLibrary::FindLibrary(const char *library, int version)
|
||||
|
||||
/* Check if the library + version exists */
|
||||
ScriptInfoList::iterator iter = this->info_list.find(library_name);
|
||||
if (iter == this->info_list.end()) return NULL;
|
||||
if (iter == this->info_list.end()) return nullptr;
|
||||
|
||||
return static_cast<AILibrary *>((*iter).second);
|
||||
}
|
||||
|
||||
+14
-14
@@ -19,7 +19,7 @@ public:
|
||||
AIScannerInfo();
|
||||
~AIScannerInfo();
|
||||
|
||||
/* virtual */ void Initialize();
|
||||
void Initialize() override;
|
||||
|
||||
/**
|
||||
* Select a random AI.
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
* @param nameParam The name of the AI.
|
||||
* @param versionParam The version of the AI, or -1 if you want the latest.
|
||||
* @param force_exact_match Only match name+version, never latest.
|
||||
* @return NULL if no match found, otherwise the AI that matched.
|
||||
* @return nullptr if no match found, otherwise the AI that matched.
|
||||
*/
|
||||
class AIInfo *FindInfo(const char *nameParam, int versionParam, bool force_exact_match);
|
||||
|
||||
@@ -42,11 +42,11 @@ public:
|
||||
void SetDummyAI(class AIInfo *info);
|
||||
|
||||
protected:
|
||||
/* virtual */ void GetScriptName(ScriptInfo *info, char *name, const char *last);
|
||||
/* virtual */ const char *GetFileName() const { return PATHSEP "info.nut"; }
|
||||
/* virtual */ Subdirectory GetDirectory() const { return AI_DIR; }
|
||||
/* virtual */ const char *GetScannerName() const { return "AIs"; }
|
||||
/* virtual */ void RegisterAPI(class Squirrel *engine);
|
||||
void GetScriptName(ScriptInfo *info, char *name, const char *last) override;
|
||||
const char *GetFileName() const override { return PATHSEP "info.nut"; }
|
||||
Subdirectory GetDirectory() const override { return AI_DIR; }
|
||||
const char *GetScannerName() const override { return "AIs"; }
|
||||
void RegisterAPI(class Squirrel *engine) override;
|
||||
|
||||
private:
|
||||
AIInfo *info_dummy; ///< The dummy AI.
|
||||
@@ -54,22 +54,22 @@ private:
|
||||
|
||||
class AIScannerLibrary : public ScriptScanner {
|
||||
public:
|
||||
/* virtual */ void Initialize();
|
||||
void Initialize() override;
|
||||
|
||||
/**
|
||||
* Find a library in the pool.
|
||||
* @param library The library name to find.
|
||||
* @param version The version the library should have.
|
||||
* @return The library if found, NULL otherwise.
|
||||
* @return The library if found, nullptr otherwise.
|
||||
*/
|
||||
class AILibrary *FindLibrary(const char *library, int version);
|
||||
|
||||
protected:
|
||||
/* virtual */ void GetScriptName(ScriptInfo *info, char *name, const char *last);
|
||||
/* virtual */ const char *GetFileName() const { return PATHSEP "library.nut"; }
|
||||
/* virtual */ Subdirectory GetDirectory() const { return AI_LIBRARY_DIR; }
|
||||
/* virtual */ const char *GetScannerName() const { return "AI Libraries"; }
|
||||
/* virtual */ void RegisterAPI(class Squirrel *engine);
|
||||
void GetScriptName(ScriptInfo *info, char *name, const char *last) override;
|
||||
const char *GetFileName() const override { return PATHSEP "library.nut"; }
|
||||
Subdirectory GetDirectory() const override { return AI_LIBRARY_DIR; }
|
||||
const char *GetScannerName() const override { return "AI Libraries"; }
|
||||
void RegisterAPI(class Squirrel *engine) override;
|
||||
};
|
||||
|
||||
#endif /* AI_SCANNER_HPP */
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ struct Aircraft FINAL : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
|
||||
byte previous_pos; ///< Previous desired position of the aircraft.
|
||||
StationID targetairport; ///< Airport to go to next.
|
||||
byte state; ///< State of the airport. @see AirportMovementStates
|
||||
DirectionByte last_direction;
|
||||
Direction last_direction;
|
||||
byte number_consecutive_turns; ///< Protection to prevent the aircraft of making a lot of turns in order to reach a specific point.
|
||||
byte turn_counter; ///< Ticks between each turn to prevent > 45 degree turns.
|
||||
byte flags; ///< Aircraft flags. @see AirVehicleFlags
|
||||
|
||||
+49
-50
@@ -143,7 +143,7 @@ static StationID FindNearestHangar(const Aircraft *v)
|
||||
if (v->acache.cached_max_range_sqr != 0) {
|
||||
/* Check if our current destination can be reached from the depot airport. */
|
||||
const Station *cur_dest = GetTargetAirportIfValid(v);
|
||||
if (cur_dest != NULL && DistanceSquare(st->airport.tile, cur_dest->airport.tile) > v->acache.cached_max_range_sqr) continue;
|
||||
if (cur_dest != nullptr && DistanceSquare(st->airport.tile, cur_dest->airport.tile) > v->acache.cached_max_range_sqr) continue;
|
||||
}
|
||||
if (distance < best || index == INVALID_STATION) {
|
||||
best = distance;
|
||||
@@ -295,7 +295,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *
|
||||
v->cargo_type = e->GetDefaultCargoType();
|
||||
u->cargo_type = CT_MAIL;
|
||||
|
||||
v->name = NULL;
|
||||
v->name = nullptr;
|
||||
v->last_station_visited = INVALID_STATION;
|
||||
v->last_loading_station = INVALID_STATION;
|
||||
|
||||
@@ -379,7 +379,7 @@ bool Aircraft::FindClosestDepot(TileIndex *location, DestinationID *destination,
|
||||
{
|
||||
const Station *st = GetTargetAirportIfValid(this);
|
||||
/* If the station is not a valid airport or if it has no hangars */
|
||||
if (st == NULL || !CanVehicleUseStation(this, st) || !st->airport.HasHangar()) {
|
||||
if (st == nullptr || !CanVehicleUseStation(this, st) || !st->airport.HasHangar()) {
|
||||
/* the aircraft has to search for a hangar on its own */
|
||||
StationID station = FindNearestHangar(this);
|
||||
|
||||
@@ -388,8 +388,8 @@ bool Aircraft::FindClosestDepot(TileIndex *location, DestinationID *destination,
|
||||
st = Station::Get(station);
|
||||
}
|
||||
|
||||
if (location != NULL) *location = st->xy;
|
||||
if (destination != NULL) *destination = st->index;
|
||||
if (location != nullptr) *location = st->xy;
|
||||
if (destination != nullptr) *destination = st->index;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -408,7 +408,7 @@ static void CheckIfAircraftNeedsService(Aircraft *v)
|
||||
|
||||
const Station *st = Station::Get(v->current_order.GetDestination());
|
||||
|
||||
assert(st != NULL);
|
||||
assert(st != nullptr);
|
||||
|
||||
/* only goto depot if the target airport has a depot */
|
||||
if (st->airport.HasHangar() && CanVehicleUseStation(v, st)) {
|
||||
@@ -531,7 +531,7 @@ void SetAircraftPosition(Aircraft *v, int x, int y, int z)
|
||||
u->UpdatePositionAndViewport();
|
||||
|
||||
u = u->Next();
|
||||
if (u != NULL) {
|
||||
if (u != nullptr) {
|
||||
u->x_pos = x;
|
||||
u->y_pos = y;
|
||||
u->z_pos = z + ROTOR_Z_OFFSET;
|
||||
@@ -552,7 +552,7 @@ void HandleAircraftEnterHangar(Aircraft *v)
|
||||
Aircraft *u = v->Next();
|
||||
u->vehstatus |= VS_HIDDEN;
|
||||
u = u->Next();
|
||||
if (u != NULL) {
|
||||
if (u != nullptr) {
|
||||
u->vehstatus |= VS_HIDDEN;
|
||||
u->cur_speed = 0;
|
||||
}
|
||||
@@ -725,8 +725,8 @@ void GetAircraftFlightLevelBounds(const Vehicle *v, int *min_level, int *max_lev
|
||||
/* Make faster planes fly higher so that they can overtake slower ones */
|
||||
base_altitude += min(20 * (v->vcache.cached_max_speed / 200) - 90, 0);
|
||||
|
||||
if (min_level != NULL) *min_level = base_altitude + AIRCRAFT_MIN_FLYING_ALTITUDE;
|
||||
if (max_level != NULL) *max_level = base_altitude + AIRCRAFT_MAX_FLYING_ALTITUDE;
|
||||
if (min_level != nullptr) *min_level = base_altitude + AIRCRAFT_MIN_FLYING_ALTITUDE;
|
||||
if (max_level != nullptr) *max_level = base_altitude + AIRCRAFT_MAX_FLYING_ALTITUDE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -801,8 +801,8 @@ template int GetAircraftFlightLevel(Aircraft *v, bool takeoff);
|
||||
*/
|
||||
static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, Direction rotation)
|
||||
{
|
||||
assert(v != NULL);
|
||||
assert(apc != NULL);
|
||||
assert(v != nullptr);
|
||||
assert(apc != nullptr);
|
||||
|
||||
/* In the case the station doesn't exit anymore, set target tile 0.
|
||||
* It doesn't hurt much, aircraft will go to next order, nearest hangar
|
||||
@@ -810,7 +810,7 @@ static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc,
|
||||
TileIndex tile = 0;
|
||||
|
||||
const Station *st = Station::GetIfValid(v->targetairport);
|
||||
if (st != NULL) {
|
||||
if (st != nullptr) {
|
||||
/* Make sure we don't go to INVALID_TILE if the airport has been removed. */
|
||||
tile = (st->airport.tile != INVALID_TILE) ? st->airport.tile : st->xy;
|
||||
}
|
||||
@@ -844,13 +844,13 @@ static bool AircraftController(Aircraft *v)
|
||||
{
|
||||
int count;
|
||||
|
||||
/* NULL if station is invalid */
|
||||
/* nullptr if station is invalid */
|
||||
const Station *st = Station::GetIfValid(v->targetairport);
|
||||
/* INVALID_TILE if there is no station */
|
||||
TileIndex tile = INVALID_TILE;
|
||||
Direction rotation = DIR_N;
|
||||
uint size_x = 1, size_y = 1;
|
||||
if (st != NULL) {
|
||||
if (st != nullptr) {
|
||||
if (st->airport.tile != INVALID_TILE) {
|
||||
tile = st->airport.tile;
|
||||
rotation = st->airport.rotation;
|
||||
@@ -864,7 +864,7 @@ static bool AircraftController(Aircraft *v)
|
||||
const AirportFTAClass *afc = tile == INVALID_TILE ? GetAirport(AT_DUMMY) : st->airport.GetFTA();
|
||||
|
||||
/* prevent going to INVALID_TILE if airport is deleted. */
|
||||
if (st == NULL || st->airport.tile == INVALID_TILE) {
|
||||
if (st == nullptr || st->airport.tile == INVALID_TILE) {
|
||||
/* Jump into our "holding pattern" state machine if possible */
|
||||
if (v->pos >= afc->nofelements) {
|
||||
v->pos = v->previous_pos = AircraftGetEntryPoint(v, afc, DIR_N);
|
||||
@@ -904,7 +904,7 @@ static bool AircraftController(Aircraft *v)
|
||||
v->tile = 0;
|
||||
|
||||
int z_dest;
|
||||
GetAircraftFlightLevelBounds(v, &z_dest, NULL);
|
||||
GetAircraftFlightLevelBounds(v, &z_dest, nullptr);
|
||||
|
||||
/* Reached altitude? */
|
||||
if (v->z_pos >= z_dest) {
|
||||
@@ -921,7 +921,7 @@ static bool AircraftController(Aircraft *v)
|
||||
if (amd.flag & AMED_HELI_LOWER) {
|
||||
SetBit(v->flags, VAF_HELI_DIRECT_DESCENT);
|
||||
|
||||
if (st == NULL) {
|
||||
if (st == nullptr) {
|
||||
/* FIXME - AircraftController -> if station no longer exists, do not land
|
||||
* helicopter will circle until sign disappears, then go to next order
|
||||
* what to do when it is the only order left, right now it just stays in 1 place */
|
||||
@@ -1127,7 +1127,7 @@ static bool HandleCrashedAircraft(Aircraft *v)
|
||||
Station *st = GetTargetAirportIfValid(v);
|
||||
|
||||
/* make aircraft crash down to the ground */
|
||||
if (v->crashed_counter < 500 && st == NULL && ((v->crashed_counter % 3) == 0) ) {
|
||||
if (v->crashed_counter < 500 && st == nullptr && ((v->crashed_counter % 3) == 0) ) {
|
||||
int z = GetSlopePixelZ(Clamp(v->x_pos, 0, MapMaxX() * TILE_SIZE), Clamp(v->y_pos, 0, MapMaxY() * TILE_SIZE));
|
||||
v->z_pos -= 1;
|
||||
if (v->z_pos == z) {
|
||||
@@ -1158,7 +1158,7 @@ static bool HandleCrashedAircraft(Aircraft *v)
|
||||
/* clear runway-in on all airports, set by crashing plane
|
||||
* small airports use AIRPORT_BUSY, city airports use RUNWAY_IN_OUT_block, etc.
|
||||
* but they all share the same number */
|
||||
if (st != NULL) {
|
||||
if (st != nullptr) {
|
||||
CLRBITS(st->airport.flags, RUNWAY_IN_block);
|
||||
CLRBITS(st->airport.flags, RUNWAY_IN_OUT_block); // commuter airport
|
||||
CLRBITS(st->airport.flags, RUNWAY_IN2_block); // intercontinental
|
||||
@@ -1232,8 +1232,8 @@ void HandleMissingAircraftOrders(Aircraft *v)
|
||||
* actually stops.
|
||||
*/
|
||||
const Station *st = GetTargetAirportIfValid(v);
|
||||
if (st == NULL) {
|
||||
Backup<CompanyByte> cur_company(_current_company, v->owner, FILE_LINE);
|
||||
if (st == nullptr) {
|
||||
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
|
||||
CommandCost ret = DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT);
|
||||
cur_company.Restore();
|
||||
|
||||
@@ -1288,17 +1288,17 @@ static void CrashAirplane(Aircraft *v)
|
||||
v->Next()->cargo.Truncate();
|
||||
const Station *st = GetTargetAirportIfValid(v);
|
||||
StringID newsitem;
|
||||
if (st == NULL) {
|
||||
if (st == nullptr) {
|
||||
newsitem = STR_NEWS_PLANE_CRASH_OUT_OF_FUEL;
|
||||
} else {
|
||||
SetDParam(1, st->index);
|
||||
newsitem = STR_NEWS_AIRCRAFT_CRASH;
|
||||
}
|
||||
|
||||
AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, st == NULL ? ScriptEventVehicleCrashed::CRASH_AIRCRAFT_NO_AIRPORT : ScriptEventVehicleCrashed::CRASH_PLANE_LANDING));
|
||||
Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, st == NULL ? ScriptEventVehicleCrashed::CRASH_AIRCRAFT_NO_AIRPORT : ScriptEventVehicleCrashed::CRASH_PLANE_LANDING));
|
||||
AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, st == nullptr ? ScriptEventVehicleCrashed::CRASH_AIRCRAFT_NO_AIRPORT : ScriptEventVehicleCrashed::CRASH_PLANE_LANDING));
|
||||
Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, st == nullptr ? ScriptEventVehicleCrashed::CRASH_AIRCRAFT_NO_AIRPORT : ScriptEventVehicleCrashed::CRASH_PLANE_LANDING));
|
||||
|
||||
AddVehicleNewsItem(newsitem, NT_ACCIDENT, v->index, st != NULL ? st->index : INVALID_STATION);
|
||||
AddVehicleNewsItem(newsitem, NT_ACCIDENT, v->index, st != nullptr ? st->index : INVALID_STATION);
|
||||
|
||||
ModifyStationRatingAround(v->tile, v->owner, -160, 30);
|
||||
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
|
||||
@@ -1310,18 +1310,17 @@ static void CrashAirplane(Aircraft *v)
|
||||
*/
|
||||
static void MaybeCrashAirplane(Aircraft *v)
|
||||
{
|
||||
if (_settings_game.vehicle.plane_crashes == 0) return;
|
||||
|
||||
Station *st = Station::Get(v->targetairport);
|
||||
|
||||
/* FIXME -- MaybeCrashAirplane -> increase crashing chances of very modern airplanes on smaller than AT_METROPOLITAN airports */
|
||||
uint32 prob = (0x4000 << _settings_game.vehicle.plane_crashes);
|
||||
uint32 prob;
|
||||
if ((st->airport.GetFTA()->flags & AirportFTAClass::SHORT_STRIP) &&
|
||||
(AircraftVehInfo(v->engine_type)->subtype & AIR_FAST) &&
|
||||
!_cheats.no_jetcrash.value) {
|
||||
prob /= 20;
|
||||
prob = 3276;
|
||||
} else {
|
||||
prob /= 1500;
|
||||
if (_settings_game.vehicle.plane_crashes == 0) return;
|
||||
prob = (0x4000 << _settings_game.vehicle.plane_crashes) / 1500;
|
||||
}
|
||||
|
||||
if (GB(Random(), 0, 22) > prob) return;
|
||||
@@ -1393,8 +1392,8 @@ void AircraftNextAirportPos_and_Order(Aircraft *v)
|
||||
}
|
||||
|
||||
const Station *st = GetTargetAirportIfValid(v);
|
||||
const AirportFTAClass *apc = st == NULL ? GetAirport(AT_DUMMY) : st->airport.GetFTA();
|
||||
Direction rotation = st == NULL ? DIR_N : st->airport.rotation;
|
||||
const AirportFTAClass *apc = st == nullptr ? GetAirport(AT_DUMMY) : st->airport.GetFTA();
|
||||
Direction rotation = st == nullptr ? DIR_N : st->airport.rotation;
|
||||
v->pos = v->previous_pos = AircraftGetEntryPoint(v, apc, rotation);
|
||||
}
|
||||
|
||||
@@ -1419,7 +1418,7 @@ void AircraftLeaveHangar(Aircraft *v, Direction exit_dir)
|
||||
|
||||
/* Rotor blades */
|
||||
u = u->Next();
|
||||
if (u != NULL) {
|
||||
if (u != nullptr) {
|
||||
u->vehstatus &= ~VS_HIDDEN;
|
||||
u->cur_speed = 80;
|
||||
}
|
||||
@@ -1589,7 +1588,7 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass
|
||||
|
||||
/* Send the helicopter to a hangar if needed for replacement */
|
||||
if (v->NeedsAutomaticServicing()) {
|
||||
Backup<CompanyByte> cur_company(_current_company, v->owner, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
|
||||
DoCommand(v->tile, v->index | DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, 0, DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT);
|
||||
cur_company.Restore();
|
||||
}
|
||||
@@ -1606,7 +1605,7 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc)
|
||||
* it is possible to choose from multiple landing runways, so loop until a free one is found */
|
||||
byte landingtype = (v->subtype == AIR_HELICOPTER) ? HELILANDING : LANDING;
|
||||
const AirportFTA *current = apc->layout[v->pos].next;
|
||||
while (current != NULL) {
|
||||
while (current != nullptr) {
|
||||
if (current->heading == landingtype) {
|
||||
/* save speed before, since if AirportHasBlock is false, it resets them to 0
|
||||
* we don't want that for plane in air
|
||||
@@ -1640,7 +1639,7 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc
|
||||
|
||||
/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */
|
||||
if (v->NeedsAutomaticServicing()) {
|
||||
Backup<CompanyByte> cur_company(_current_company, v->owner, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
|
||||
DoCommand(v->tile, v->index | DEPOT_SERVICE, 0, DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT);
|
||||
cur_company.Restore();
|
||||
}
|
||||
@@ -1762,7 +1761,7 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc)
|
||||
v->previous_pos = v->pos; // save previous location
|
||||
|
||||
/* there is only one choice to move to */
|
||||
if (current->next == NULL) {
|
||||
if (current->next == nullptr) {
|
||||
if (AirportSetBlocks(v, current, apc)) {
|
||||
v->pos = current->next_position;
|
||||
UpdateAircraftCache(v);
|
||||
@@ -1781,7 +1780,7 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc)
|
||||
return false;
|
||||
}
|
||||
current = current->next;
|
||||
} while (current != NULL);
|
||||
} while (current != nullptr);
|
||||
|
||||
DEBUG(misc, 0, "[Ap] cannot move further on Airport! (pos %d state %d) for vehicle %d", v->pos, v->state, v->index);
|
||||
NOT_REACHED();
|
||||
@@ -1816,7 +1815,7 @@ static bool AirportHasBlock(Aircraft *v, const AirportFTA *current_pos, const Ai
|
||||
* "reserve" a block for the plane
|
||||
* @param v airplane that requires the operation
|
||||
* @param current_pos of the vehicle in the list of blocks
|
||||
* @param apc airport on which block is requsted to be set
|
||||
* @param apc airport on which block is requested to be set
|
||||
* @returns true on success. Eg, next block was free and we have occupied it
|
||||
*/
|
||||
static bool AirportSetBlocks(Aircraft *v, const AirportFTA *current_pos, const AirportFTAClass *apc)
|
||||
@@ -1831,7 +1830,7 @@ static bool AirportSetBlocks(Aircraft *v, const AirportFTA *current_pos, const A
|
||||
* this means more blocks should be checked/set */
|
||||
const AirportFTA *current = current_pos;
|
||||
if (current == reference) current = current->next;
|
||||
while (current != NULL) {
|
||||
while (current != nullptr) {
|
||||
if (current->heading == current_pos->heading && current->block != 0) {
|
||||
airport_flags |= current->block;
|
||||
break;
|
||||
@@ -1926,8 +1925,8 @@ static uint GetNumTerminals(const AirportFTAClass *apc)
|
||||
static bool AirportFindFreeTerminal(Aircraft *v, const AirportFTAClass *apc)
|
||||
{
|
||||
/* example of more terminalgroups
|
||||
* {0,HANGAR,NOTHING_block,1}, {0,255,TERM_GROUP1_block,0}, {0,255,TERM_GROUP2_ENTER_block,1}, {0,0,N,1},
|
||||
* Heading 255 denotes a group. We see 2 groups here:
|
||||
* {0,HANGAR,NOTHING_block,1}, {0,TERMGROUP,TERM_GROUP1_block,0}, {0,TERMGROUP,TERM_GROUP2_ENTER_block,1}, {0,0,N,1},
|
||||
* Heading TERMGROUP denotes a group. We see 2 groups here:
|
||||
* 1. group 0 -- TERM_GROUP1_block (check block)
|
||||
* 2. group 1 -- TERM_GROUP2_ENTER_block (check block)
|
||||
* First in line is checked first, group 0. If the block (TERM_GROUP1_block) is free, it
|
||||
@@ -1939,8 +1938,8 @@ static bool AirportFindFreeTerminal(Aircraft *v, const AirportFTAClass *apc)
|
||||
const Station *st = Station::Get(v->targetairport);
|
||||
const AirportFTA *temp = apc->layout[v->pos].next;
|
||||
|
||||
while (temp != NULL) {
|
||||
if (temp->heading == 255) {
|
||||
while (temp != nullptr) {
|
||||
if (temp->heading == TERMGROUP) {
|
||||
if (!(st->airport.flags & temp->block)) {
|
||||
/* read which group do we want to go to?
|
||||
* (the first free group) */
|
||||
@@ -2038,9 +2037,9 @@ static bool AircraftEventHandler(Aircraft *v, int loop)
|
||||
/* Check the distance to the next destination. This code works because the target
|
||||
* airport is only updated after take off and not on the ground. */
|
||||
Station *cur_st = Station::GetIfValid(v->targetairport);
|
||||
Station *next_st = v->current_order.IsType(OT_GOTO_STATION) || v->current_order.IsType(OT_GOTO_DEPOT) ? Station::GetIfValid(v->current_order.GetDestination()) : NULL;
|
||||
Station *next_st = v->current_order.IsType(OT_GOTO_STATION) || v->current_order.IsType(OT_GOTO_DEPOT) ? Station::GetIfValid(v->current_order.GetDestination()) : nullptr;
|
||||
|
||||
if (cur_st != NULL && cur_st->airport.tile != INVALID_TILE && next_st != NULL && next_st->airport.tile != INVALID_TILE) {
|
||||
if (cur_st != nullptr && cur_st->airport.tile != INVALID_TILE && next_st != nullptr && next_st->airport.tile != INVALID_TILE) {
|
||||
uint dist = DistanceSquare(cur_st->airport.tile, next_st->airport.tile);
|
||||
AircraftHandleDestTooFar(v, dist > v->acache.cached_max_range_sqr);
|
||||
}
|
||||
@@ -2078,16 +2077,16 @@ bool Aircraft::Tick()
|
||||
* Returns aircraft's target station if v->target_airport
|
||||
* is a valid station with airport.
|
||||
* @param v vehicle to get target airport for
|
||||
* @return pointer to target station, NULL if invalid
|
||||
* @return pointer to target station, nullptr if invalid
|
||||
*/
|
||||
Station *GetTargetAirportIfValid(const Aircraft *v)
|
||||
{
|
||||
assert(v->type == VEH_AIRCRAFT);
|
||||
|
||||
Station *st = Station::GetIfValid(v->targetairport);
|
||||
if (st == NULL) return NULL;
|
||||
if (st == nullptr) return nullptr;
|
||||
|
||||
return st->airport.tile == INVALID_TILE ? NULL : st;
|
||||
return st->airport.tile == INVALID_TILE ? nullptr : st;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ void DrawAircraftDetails(const Aircraft *v, int left, int right, int y)
|
||||
int y_offset = (v->Next()->cargo_cap != 0) ? -(FONT_HEIGHT_NORMAL + 1): 0;
|
||||
Money feeder_share = 0;
|
||||
|
||||
for (const Aircraft *u = v; u != NULL; u = u->Next()) {
|
||||
for (const Aircraft *u = v; u != nullptr; u = u->Next()) {
|
||||
if (u->IsNormalAircraft()) {
|
||||
SetDParam(0, u->engine_type);
|
||||
SetDParam(1, u->build_year);
|
||||
|
||||
+4
-4
@@ -46,7 +46,7 @@
|
||||
* @param delta_z Height of the airport above the land.
|
||||
*/
|
||||
#define HELIPORT(name, num_helipads, delta_z) \
|
||||
AIRPORT_GENERIC(name, NULL, num_helipads, AirportFTAClass::HELICOPTERS, delta_z)
|
||||
AIRPORT_GENERIC(name, nullptr, num_helipads, AirportFTAClass::HELICOPTERS, delta_z)
|
||||
|
||||
AIRPORT(country, 0, true)
|
||||
AIRPORT(city, 0, false)
|
||||
@@ -58,7 +58,7 @@ HELIPORT(helidepot, 1, 0)
|
||||
AIRPORT(intercontinental, 2, false)
|
||||
HELIPORT(helistation, 3, 0)
|
||||
HELIPORT(oilrig, 1, 54)
|
||||
AIRPORT_GENERIC(dummy, NULL, 0, AirportFTAClass::ALL, 0)
|
||||
AIRPORT_GENERIC(dummy, nullptr, 0, AirportFTAClass::ALL, 0)
|
||||
|
||||
#undef HELIPORT
|
||||
#undef AIRPORT
|
||||
@@ -135,7 +135,7 @@ AirportFTAClass::~AirportFTAClass()
|
||||
{
|
||||
for (uint i = 0; i < nofelements; i++) {
|
||||
AirportFTA *current = layout[i].next;
|
||||
while (current != NULL) {
|
||||
while (current != nullptr) {
|
||||
AirportFTA *next = current->next;
|
||||
free(current);
|
||||
current = next;
|
||||
@@ -195,7 +195,7 @@ static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildu
|
||||
current = current->next;
|
||||
internalcounter++;
|
||||
}
|
||||
current->next = NULL;
|
||||
current->next = nullptr;
|
||||
internalcounter++;
|
||||
}
|
||||
return FAutomata;
|
||||
|
||||
+28
-27
@@ -60,29 +60,30 @@ enum AirportMovingDataFlags {
|
||||
|
||||
/** Movement States on Airports (headings target) */
|
||||
enum AirportMovementStates {
|
||||
TO_ALL = 0, ///< Go in this direction for every target.
|
||||
HANGAR = 1, ///< Heading for hangar.
|
||||
TERM1 = 2, ///< Heading for terminal 1.
|
||||
TERM2 = 3, ///< Heading for terminal 2.
|
||||
TERM3 = 4, ///< Heading for terminal 3.
|
||||
TERM4 = 5, ///< Heading for terminal 4.
|
||||
TERM5 = 6, ///< Heading for terminal 5.
|
||||
TERM6 = 7, ///< Heading for terminal 6.
|
||||
HELIPAD1 = 8, ///< Heading for helipad 1.
|
||||
HELIPAD2 = 9, ///< Heading for helipad 2.
|
||||
TAKEOFF = 10, ///< Airplane wants to leave the airport.
|
||||
STARTTAKEOFF = 11, ///< Airplane has arrived at a runway for take-off.
|
||||
ENDTAKEOFF = 12, ///< Airplane has reached end-point of the take-off runway.
|
||||
HELITAKEOFF = 13, ///< Helicopter wants to leave the airport.
|
||||
FLYING = 14, ///< %Vehicle is flying in the air.
|
||||
LANDING = 15, ///< Airplane wants to land.
|
||||
ENDLANDING = 16, ///< Airplane wants to finish landing.
|
||||
HELILANDING = 17, ///< Helicopter wants to land.
|
||||
HELIENDLANDING = 18, ///< Helicopter wants to finish landing.
|
||||
TERM7 = 19, ///< Heading for terminal 7.
|
||||
TERM8 = 20, ///< Heading for terminal 8.
|
||||
HELIPAD3 = 21, ///< Heading for helipad 3.
|
||||
MAX_HEADINGS = 21, ///< Last valid target to head for.
|
||||
TO_ALL = 0, ///< Go in this direction for every target.
|
||||
HANGAR = 1, ///< Heading for hangar.
|
||||
TERM1 = 2, ///< Heading for terminal 1.
|
||||
TERM2 = 3, ///< Heading for terminal 2.
|
||||
TERM3 = 4, ///< Heading for terminal 3.
|
||||
TERM4 = 5, ///< Heading for terminal 4.
|
||||
TERM5 = 6, ///< Heading for terminal 5.
|
||||
TERM6 = 7, ///< Heading for terminal 6.
|
||||
HELIPAD1 = 8, ///< Heading for helipad 1.
|
||||
HELIPAD2 = 9, ///< Heading for helipad 2.
|
||||
TAKEOFF = 10, ///< Airplane wants to leave the airport.
|
||||
STARTTAKEOFF = 11, ///< Airplane has arrived at a runway for take-off.
|
||||
ENDTAKEOFF = 12, ///< Airplane has reached end-point of the take-off runway.
|
||||
HELITAKEOFF = 13, ///< Helicopter wants to leave the airport.
|
||||
FLYING = 14, ///< %Vehicle is flying in the air.
|
||||
LANDING = 15, ///< Airplane wants to land.
|
||||
ENDLANDING = 16, ///< Airplane wants to finish landing.
|
||||
HELILANDING = 17, ///< Helicopter wants to land.
|
||||
HELIENDLANDING = 18, ///< Helicopter wants to finish landing.
|
||||
TERM7 = 19, ///< Heading for terminal 7.
|
||||
TERM8 = 20, ///< Heading for terminal 8.
|
||||
HELIPAD3 = 21, ///< Heading for helipad 3.
|
||||
MAX_HEADINGS = 21, ///< Last valid target to head for.
|
||||
TERMGROUP = 255, ///< Aircraft is looking for a free terminal in a terminalgroup.
|
||||
};
|
||||
|
||||
/** Movement Blocks on Airports blocks (eg_airport_flags). */
|
||||
@@ -130,10 +131,10 @@ static const uint64
|
||||
|
||||
/** A single location on an airport where aircraft can move to. */
|
||||
struct AirportMovingData {
|
||||
int16 x; ///< x-coordinate of the destination.
|
||||
int16 y; ///< y-coordinate of the destination.
|
||||
uint16 flag; ///< special flags when moving towards the destination.
|
||||
DirectionByte direction; ///< Direction to turn the aircraft after reaching the destination.
|
||||
int16 x; ///< x-coordinate of the destination.
|
||||
int16 y; ///< y-coordinate of the destination.
|
||||
uint16 flag; ///< special flags when moving towards the destination.
|
||||
Direction direction; ///< Direction to turn the aircraft after reaching the destination.
|
||||
};
|
||||
|
||||
AirportMovingData RotateAirportMovingData(const AirportMovingData *orig, Direction rotation, uint num_tiles_x, uint num_tiles_y);
|
||||
|
||||
+22
-19
@@ -79,6 +79,7 @@ struct BuildAirToolbarWindow : Window {
|
||||
|
||||
~BuildAirToolbarWindow()
|
||||
{
|
||||
if (this->IsWidgetLowered(WID_AT_AIRPORT)) SetViewportCatchmentStation(nullptr, true);
|
||||
if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
|
||||
}
|
||||
|
||||
@@ -87,14 +88,14 @@ struct BuildAirToolbarWindow : Window {
|
||||
* @param data Information about the changed data.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (!gui_scope) return;
|
||||
|
||||
if (!CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) delete this;
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AT_AIRPORT:
|
||||
@@ -114,7 +115,7 @@ struct BuildAirToolbarWindow : Window {
|
||||
}
|
||||
|
||||
|
||||
virtual void OnPlaceObject(Point pt, TileIndex tile)
|
||||
void OnPlaceObject(Point pt, TileIndex tile) override
|
||||
{
|
||||
switch (this->last_user_action) {
|
||||
case WID_AT_AIRPORT:
|
||||
@@ -129,20 +130,22 @@ struct BuildAirToolbarWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
|
||||
void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override
|
||||
{
|
||||
VpSelectTilesWithMethod(pt.x, pt.y, select_method);
|
||||
}
|
||||
|
||||
virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
|
||||
void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override
|
||||
{
|
||||
if (pt.x != -1 && select_proc == DDSP_DEMOLISH_AREA) {
|
||||
GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPlaceObjectAbort()
|
||||
void OnPlaceObjectAbort() override
|
||||
{
|
||||
if (this->IsWidgetLowered(WID_AT_AIRPORT)) SetViewportCatchmentStation(nullptr, true);
|
||||
|
||||
this->RaiseButtons();
|
||||
|
||||
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
|
||||
@@ -161,7 +164,7 @@ static EventState AirportToolbarGlobalHotkeys(int hotkey)
|
||||
{
|
||||
if (_game_mode != GM_NORMAL || !CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) return ES_NOT_HANDLED;
|
||||
Window *w = ShowBuildAirToolbar();
|
||||
if (w == NULL) return ES_NOT_HANDLED;
|
||||
if (w == nullptr) return ES_NOT_HANDLED;
|
||||
return w->OnHotkey(hotkey);
|
||||
}
|
||||
|
||||
@@ -198,11 +201,11 @@ static WindowDesc _air_toolbar_desc(
|
||||
*
|
||||
* If the terraform toolbar is linked to the toolbar, that window is also opened.
|
||||
*
|
||||
* @return newly opened airport toolbar, or NULL if the toolbar could not be opened.
|
||||
* @return newly opened airport toolbar, or nullptr if the toolbar could not be opened.
|
||||
*/
|
||||
Window *ShowBuildAirToolbar()
|
||||
{
|
||||
if (!Company::IsValidID(_local_company)) return NULL;
|
||||
if (!Company::IsValidID(_local_company)) return nullptr;
|
||||
|
||||
DeleteWindowByClass(WC_BUILD_TOOLBAR);
|
||||
return AllocateWindowDescFront<BuildAirToolbarWindow>(&_air_toolbar_desc, TRANSPORT_AIR);
|
||||
@@ -214,12 +217,12 @@ class BuildAirportWindow : public PickerWindowBase {
|
||||
Scrollbar *vscroll;
|
||||
|
||||
/** Build a dropdown list of available airport classes */
|
||||
static DropDownList *BuildAirportClassDropDown()
|
||||
static DropDownList BuildAirportClassDropDown()
|
||||
{
|
||||
DropDownList *list = new DropDownList();
|
||||
DropDownList list;
|
||||
|
||||
for (uint i = 0; i < AirportClass::GetClassCount(); i++) {
|
||||
*list->Append() = new DropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i, false);
|
||||
list.emplace_back(new DropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i, false));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -268,7 +271,7 @@ public:
|
||||
DeleteWindowById(WC_SELECT_STATION, 0);
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AP_CLASS_DROPDOWN:
|
||||
@@ -293,7 +296,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AP_CLASS_DROPDOWN: {
|
||||
@@ -357,7 +360,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AP_AIRPORT_LIST: {
|
||||
@@ -394,7 +397,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPaint()
|
||||
void OnPaint() override
|
||||
{
|
||||
this->DrawWidgets();
|
||||
|
||||
@@ -462,7 +465,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AP_CLASS_DROPDOWN:
|
||||
@@ -535,7 +538,7 @@ public:
|
||||
this->SelectOtherAirport(-1);
|
||||
}
|
||||
|
||||
virtual void OnDropdownSelect(int widget, int index)
|
||||
void OnDropdownSelect(int widget, int index) override
|
||||
{
|
||||
assert(widget == WID_AP_CLASS_DROPDOWN);
|
||||
_selected_airport_class = (AirportClassID)index;
|
||||
@@ -543,7 +546,7 @@ public:
|
||||
this->SelectFirstAvailableAirport(false);
|
||||
}
|
||||
|
||||
virtual void OnRealtimeTick(uint delta_ms)
|
||||
void OnRealtimeTick(uint delta_ms) override
|
||||
{
|
||||
CheckRedrawStationCoverage(this);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "safeguards.h"
|
||||
|
||||
/** The table/list with animated tiles. */
|
||||
SmallVector<TileIndex, 256> _animated_tiles;
|
||||
std::vector<TileIndex> _animated_tiles;
|
||||
|
||||
/**
|
||||
* Removes the given tile from the animated tile table.
|
||||
@@ -27,10 +27,10 @@ SmallVector<TileIndex, 256> _animated_tiles;
|
||||
*/
|
||||
void DeleteAnimatedTile(TileIndex tile)
|
||||
{
|
||||
TileIndex *to_remove = _animated_tiles.Find(tile);
|
||||
if (to_remove != _animated_tiles.End()) {
|
||||
auto to_remove = std::find(_animated_tiles.begin(), _animated_tiles.end(), tile);
|
||||
if (to_remove != _animated_tiles.end()) {
|
||||
/* The order of the remaining elements must stay the same, otherwise the animation loop may miss a tile. */
|
||||
_animated_tiles.ErasePreservingOrder(to_remove);
|
||||
_animated_tiles.erase(to_remove);
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ void DeleteAnimatedTile(TileIndex tile)
|
||||
void AddAnimatedTile(TileIndex tile)
|
||||
{
|
||||
MarkTileDirtyByTile(tile);
|
||||
_animated_tiles.Include(tile);
|
||||
include(_animated_tiles, tile);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,8 +53,8 @@ void AnimateAnimatedTiles()
|
||||
{
|
||||
PerformanceAccumulator framerate(PFE_GL_LANDSCAPE);
|
||||
|
||||
const TileIndex *ti = _animated_tiles.Begin();
|
||||
while (ti < _animated_tiles.End()) {
|
||||
const TileIndex *ti = _animated_tiles.data();
|
||||
while (ti < _animated_tiles.data() + _animated_tiles.size()) {
|
||||
const TileIndex curr = *ti;
|
||||
AnimateTile(curr);
|
||||
/* During the AnimateTile call, DeleteAnimatedTile could have been called,
|
||||
@@ -75,5 +75,5 @@ void AnimateAnimatedTiles()
|
||||
*/
|
||||
void InitializeAnimatedTiles()
|
||||
{
|
||||
_animated_tiles.Clear();
|
||||
_animated_tiles.clear();
|
||||
}
|
||||
|
||||
@@ -31,9 +31,9 @@ static const uint MAX_ARTICULATED_PARTS = 100; ///< Maximum of articulated parts
|
||||
* @param mirrored Returns whether the part shall be flipped.
|
||||
* @return engine to add or INVALID_ENGINE
|
||||
*/
|
||||
static EngineID GetNextArticulatedPart(uint index, EngineID front_type, Vehicle *front = NULL, bool *mirrored = NULL)
|
||||
static EngineID GetNextArticulatedPart(uint index, EngineID front_type, Vehicle *front = nullptr, bool *mirrored = nullptr)
|
||||
{
|
||||
assert(front == NULL || front->engine_type == front_type);
|
||||
assert(front == nullptr || front->engine_type == front_type);
|
||||
|
||||
const Engine *front_engine = Engine::Get(front_type);
|
||||
|
||||
@@ -44,12 +44,12 @@ static EngineID GetNextArticulatedPart(uint index, EngineID front_type, Vehicle
|
||||
/* 8 bits, bit 7 for mirroring */
|
||||
callback = GB(callback, 0, 8);
|
||||
if (callback == 0xFF) return INVALID_ENGINE;
|
||||
if (mirrored != NULL) *mirrored = HasBit(callback, 7);
|
||||
if (mirrored != nullptr) *mirrored = HasBit(callback, 7);
|
||||
callback = GB(callback, 0, 7);
|
||||
} else {
|
||||
/* 15 bits, bit 14 for mirroring */
|
||||
if (callback == 0x7FFF) return INVALID_ENGINE;
|
||||
if (mirrored != NULL) *mirrored = HasBit(callback, 14);
|
||||
if (mirrored != nullptr) *mirrored = HasBit(callback, 14);
|
||||
callback = GB(callback, 0, 14);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ uint CountArticulatedParts(EngineID engine_type, bool purchase_window)
|
||||
* either, so it doesn't matter how many articulated parts there are. */
|
||||
if (!Vehicle::CanAllocateItem()) return 0;
|
||||
|
||||
Vehicle *v = NULL;
|
||||
Vehicle *v = nullptr;
|
||||
if (!purchase_window) {
|
||||
v = new Vehicle();
|
||||
v->engine_type = engine_type;
|
||||
@@ -108,7 +108,7 @@ static inline uint16 GetVehicleDefaultCapacity(EngineID engine, CargoID *cargo_t
|
||||
{
|
||||
const Engine *e = Engine::Get(engine);
|
||||
CargoID cargo = (e->CanCarryCargo() ? e->GetDefaultCargoType() : (CargoID)CT_INVALID);
|
||||
if (cargo_type != NULL) *cargo_type = cargo;
|
||||
if (cargo_type != nullptr) *cargo_type = cargo;
|
||||
if (cargo == CT_INVALID) return 0;
|
||||
return e->GetDisplayDefaultCapacity();
|
||||
}
|
||||
@@ -168,16 +168,16 @@ CargoArray GetCapacityOfArticulatedParts(EngineID engine)
|
||||
* @param engine Model to investigate.
|
||||
* @param[out] cargoes Total amount of units that can be transported, summed by cargo.
|
||||
* @param[out] refits Whether a (possibly partial) refit for each cargo is possible.
|
||||
* @param cargo_type Selected refitted cargo type
|
||||
* @param cargo_capacity Capacity of selected refitted cargo type
|
||||
*/
|
||||
void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, CargoTypes *refits)
|
||||
void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, CargoTypes *refits, CargoID cargo_type, uint16 cargo_capacity)
|
||||
{
|
||||
cargoes->Clear();
|
||||
*refits = 0;
|
||||
|
||||
const Engine *e = Engine::Get(engine);
|
||||
|
||||
CargoID cargo_type;
|
||||
uint16 cargo_capacity = GetVehicleDefaultCapacity(engine, &cargo_type);
|
||||
if (cargo_type < NUM_CARGO && cargo_capacity > 0) {
|
||||
(*cargoes)[cargo_type] += cargo_capacity;
|
||||
if (IsEngineRefittable(engine)) SetBit(*refits, cargo_type);
|
||||
@@ -290,15 +290,15 @@ bool IsArticulatedVehicleCarryingDifferentCargoes(const Vehicle *v, CargoID *car
|
||||
if (v->cargo_type != CT_INVALID && v->GetEngine()->CanCarryCargo()) {
|
||||
if (first_cargo == CT_INVALID) first_cargo = v->cargo_type;
|
||||
if (first_cargo != v->cargo_type) {
|
||||
if (cargo_type != NULL) *cargo_type = CT_INVALID;
|
||||
if (cargo_type != nullptr) *cargo_type = CT_INVALID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL;
|
||||
} while (v != NULL);
|
||||
v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr;
|
||||
} while (v != nullptr);
|
||||
|
||||
if (cargo_type != NULL) *cargo_type = first_cargo;
|
||||
if (cargo_type != nullptr) *cargo_type = first_cargo;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -330,8 +330,8 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v)
|
||||
assert(v->cargo_type < NUM_CARGO);
|
||||
real_default_capacity[v->cargo_type] += v->cargo_cap;
|
||||
|
||||
v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL;
|
||||
} while (v != NULL);
|
||||
v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr;
|
||||
} while (v != nullptr);
|
||||
|
||||
/* Check whether the vehicle carries more cargoes than expected */
|
||||
bool carries_more = false;
|
||||
|
||||
+11
-11
@@ -29,11 +29,11 @@ static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine, G
|
||||
{
|
||||
EngineRenew *er = (EngineRenew *)erl;
|
||||
|
||||
while (er != NULL) {
|
||||
while (er != nullptr) {
|
||||
if (er->from == engine && GroupIsInGroup(group, er->group_id)) return er;
|
||||
er = er->next;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,12 +46,12 @@ void RemoveAllEngineReplacement(EngineRenewList *erl)
|
||||
EngineRenew *er = (EngineRenew *)(*erl);
|
||||
EngineRenew *next;
|
||||
|
||||
while (er != NULL) {
|
||||
while (er != nullptr) {
|
||||
next = er->next;
|
||||
delete er;
|
||||
er = next;
|
||||
}
|
||||
*erl = NULL; // Empty list
|
||||
*erl = nullptr; // Empty list
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,12 +66,12 @@ void RemoveAllEngineReplacement(EngineRenewList *erl)
|
||||
EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group, bool *replace_when_old)
|
||||
{
|
||||
const EngineRenew *er = GetEngineReplacement(erl, engine, group);
|
||||
if (er == NULL && (group == DEFAULT_GROUP || (Group::IsValidID(group) && !Group::Get(group)->replace_protection))) {
|
||||
if (er == nullptr && (group == DEFAULT_GROUP || (Group::IsValidID(group) && !Group::Get(group)->replace_protection))) {
|
||||
/* We didn't find anything useful in the vehicle's own group so we will try ALL_GROUP */
|
||||
er = GetEngineReplacement(erl, engine, ALL_GROUP);
|
||||
}
|
||||
if (replace_when_old != NULL) *replace_when_old = er == NULL ? false : er->replace_when_old;
|
||||
return er == NULL ? INVALID_ENGINE : er->to;
|
||||
if (replace_when_old != nullptr) *replace_when_old = er == nullptr ? false : er->replace_when_old;
|
||||
return er == nullptr ? INVALID_ENGINE : er->to;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +88,7 @@ CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, Engi
|
||||
{
|
||||
/* Check if the old vehicle is already in the list */
|
||||
EngineRenew *er = GetEngineReplacement(*erl, old_engine, group);
|
||||
if (er != NULL) {
|
||||
if (er != nullptr) {
|
||||
if (flags & DC_EXEC) {
|
||||
er->to = new_engine;
|
||||
er->replace_when_old = replace_when_old;
|
||||
@@ -122,12 +122,12 @@ CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, Engi
|
||||
CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, DoCommandFlag flags)
|
||||
{
|
||||
EngineRenew *er = (EngineRenew *)(*erl);
|
||||
EngineRenew *prev = NULL;
|
||||
EngineRenew *prev = nullptr;
|
||||
|
||||
while (er != NULL) {
|
||||
while (er != nullptr) {
|
||||
if (er->from == engine && er->group_id == group) {
|
||||
if (flags & DC_EXEC) {
|
||||
if (prev == NULL) { // First element
|
||||
if (prev == nullptr) { // First element
|
||||
/* The second becomes the new first element */
|
||||
*erl = (EngineRenewList)er->next;
|
||||
} else {
|
||||
|
||||
+56
-44
@@ -20,6 +20,8 @@
|
||||
#include "articulated_vehicles.h"
|
||||
#include "core/random_func.hpp"
|
||||
#include "vehiclelist.h"
|
||||
#include "road.h"
|
||||
#include "ai/ai.hpp"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
@@ -74,6 +76,9 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company)
|
||||
}
|
||||
|
||||
case VEH_ROAD:
|
||||
/* make sure the roadtypes are compatible */
|
||||
if ((GetRoadTypeInfo(e_from->u.road.roadtype)->powered_roadtypes & GetRoadTypeInfo(e_to->u.road.roadtype)->powered_roadtypes) == ROADTYPES_NONE) return false;
|
||||
|
||||
/* make sure that we do not replace a tram with a normal road vehicles or vice versa */
|
||||
if (HasBit(e_from->info.misc_flags, EF_ROAD_TRAM) != HasBit(e_to->info.misc_flags, EF_ROAD_TRAM)) return false;
|
||||
break;
|
||||
@@ -98,9 +103,9 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company)
|
||||
*/
|
||||
void CheckCargoCapacity(Vehicle *v)
|
||||
{
|
||||
assert(v == NULL || v->First() == v);
|
||||
assert(v == nullptr || v->First() == v);
|
||||
|
||||
for (Vehicle *src = v; src != NULL; src = src->Next()) {
|
||||
for (Vehicle *src = v; src != nullptr; src = src->Next()) {
|
||||
assert(src->cargo.TotalCount() == src->cargo.ActionCount(VehicleCargoList::MTA_KEEP));
|
||||
|
||||
/* Do we need to more cargo away? */
|
||||
@@ -108,7 +113,7 @@ void CheckCargoCapacity(Vehicle *v)
|
||||
|
||||
/* We need to move a particular amount. Try that on the other vehicles. */
|
||||
uint to_spread = src->cargo.TotalCount() - src->cargo_cap;
|
||||
for (Vehicle *dest = v; dest != NULL && to_spread != 0; dest = dest->Next()) {
|
||||
for (Vehicle *dest = v; dest != nullptr && to_spread != 0; dest = dest->Next()) {
|
||||
assert(dest->cargo.TotalCount() == dest->cargo.ActionCount(VehicleCargoList::MTA_KEEP));
|
||||
if (dest->cargo.TotalCount() >= dest->cargo_cap || dest->cargo_type != src->cargo_type) continue;
|
||||
|
||||
@@ -135,7 +140,7 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai
|
||||
{
|
||||
assert(!part_of_chain || new_head->IsPrimaryVehicle());
|
||||
/* Loop through source parts */
|
||||
for (Vehicle *src = old_veh; src != NULL; src = src->Next()) {
|
||||
for (Vehicle *src = old_veh; src != nullptr; src = src->Next()) {
|
||||
assert(src->cargo.TotalCount() == src->cargo.ActionCount(VehicleCargoList::MTA_KEEP));
|
||||
if (!part_of_chain && src->type == VEH_TRAIN && src != old_veh && src != Train::From(old_veh)->other_multiheaded_part && !src->IsArticulatedPart()) {
|
||||
/* Skip vehicles, which do not belong to old_veh */
|
||||
@@ -145,7 +150,7 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai
|
||||
if (src->cargo_type >= NUM_CARGO || src->cargo.TotalCount() == 0) continue;
|
||||
|
||||
/* Find free space in the new chain */
|
||||
for (Vehicle *dest = new_head; dest != NULL && src->cargo.TotalCount() > 0; dest = dest->Next()) {
|
||||
for (Vehicle *dest = new_head; dest != nullptr && src->cargo.TotalCount() > 0; dest = dest->Next()) {
|
||||
assert(dest->cargo.TotalCount() == dest->cargo.ActionCount(VehicleCargoList::MTA_KEEP));
|
||||
if (!part_of_chain && dest->type == VEH_TRAIN && dest != new_head && dest != Train::From(new_head)->other_multiheaded_part && !dest->IsArticulatedPart()) {
|
||||
/* Skip vehicles, which do not belong to new_head */
|
||||
@@ -216,7 +221,7 @@ static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool
|
||||
/* the old engine didn't have cargo capacity, but the new one does
|
||||
* now we will figure out what cargo the train is carrying and refit to fit this */
|
||||
|
||||
for (v = v->First(); v != NULL; v = v->Next()) {
|
||||
for (v = v->First(); v != nullptr; v = v->Next()) {
|
||||
if (!v->GetEngine()->CanCarryCargo()) continue;
|
||||
/* Now we found a cargo type being carried on the train and we will see if it is possible to carry to this one */
|
||||
if (HasBit(available_cargo_types, v->cargo_type)) return v->cargo_type;
|
||||
@@ -280,7 +285,7 @@ static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool alw
|
||||
*/
|
||||
static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain)
|
||||
{
|
||||
*new_vehicle = NULL;
|
||||
*new_vehicle = nullptr;
|
||||
|
||||
/* Shall the vehicle be replaced? */
|
||||
const Company *c = Company::Get(_current_company);
|
||||
@@ -294,7 +299,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
|
||||
if (refit_cargo == CT_INVALID) return CommandCost(); // incompatible cargoes
|
||||
|
||||
/* Build the new vehicle */
|
||||
cost = DoCommand(old_veh->tile, e, 0, DC_EXEC | DC_AUTOREPLACE, GetCmdBuildVeh(old_veh));
|
||||
cost = DoCommand(old_veh->tile, e | (CT_INVALID << 24), 0, DC_EXEC | DC_AUTOREPLACE, GetCmdBuildVeh(old_veh));
|
||||
if (cost.Failed()) return cost;
|
||||
|
||||
Vehicle *new_veh = Vehicle::Get(_new_vehicle_id);
|
||||
@@ -330,14 +335,14 @@ static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_ca
|
||||
/**
|
||||
* Issue a train vehicle move command
|
||||
* @param v The vehicle to move
|
||||
* @param after The vehicle to insert 'v' after, or NULL to start new chain
|
||||
* @param after The vehicle to insert 'v' after, or nullptr to start new chain
|
||||
* @param flags the command flags to use
|
||||
* @param whole_chain move all vehicles following 'v' (true), or only 'v' (false)
|
||||
* @return success or error
|
||||
*/
|
||||
static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after, DoCommandFlag flags, bool whole_chain)
|
||||
{
|
||||
return DoCommand(0, v->index | (whole_chain ? 1 : 0) << 20, after != NULL ? after->index : INVALID_VEHICLE, flags | DC_NO_CARGO_CAP_CHECK, CMD_MOVE_RAIL_VEHICLE);
|
||||
return DoCommand(0, v->index | (whole_chain ? 1 : 0) << 20, after != nullptr ? after->index : INVALID_VEHICLE, flags | DC_NO_CARGO_CAP_CHECK, CMD_MOVE_RAIL_VEHICLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,11 +400,11 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b
|
||||
CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0);
|
||||
|
||||
/* Build and refit replacement vehicle */
|
||||
Vehicle *new_v = NULL;
|
||||
Vehicle *new_v = nullptr;
|
||||
cost.AddCost(BuildReplacementVehicle(old_v, &new_v, false));
|
||||
|
||||
/* Was a new vehicle constructed? */
|
||||
if (cost.Succeeded() && new_v != NULL) {
|
||||
if (cost.Succeeded() && new_v != nullptr) {
|
||||
*nothing_to_do = false;
|
||||
|
||||
if ((flags & DC_EXEC) != 0) {
|
||||
@@ -415,6 +420,8 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b
|
||||
TransferCargo(old_v, new_v, false);
|
||||
|
||||
*single_unit = new_v;
|
||||
|
||||
AI::NewEvent(old_v->owner, new ScriptEventVehicleAutoReplaced(old_v->index, new_v->index));
|
||||
}
|
||||
|
||||
/* Sell the old vehicle */
|
||||
@@ -449,17 +456,17 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
uint16 old_total_length = CeilDiv(Train::From(old_head)->gcache.cached_total_length, TILE_SIZE) * TILE_SIZE;
|
||||
|
||||
int num_units = 0; ///< Number of units in the chain
|
||||
for (Train *w = Train::From(old_head); w != NULL; w = w->GetNextUnit()) num_units++;
|
||||
for (Train *w = Train::From(old_head); w != nullptr; w = w->GetNextUnit()) num_units++;
|
||||
|
||||
Train **old_vehs = CallocT<Train *>(num_units); ///< Will store vehicles of the old chain in their order
|
||||
Train **new_vehs = CallocT<Train *>(num_units); ///< New vehicles corresponding to old_vehs or NULL if no replacement
|
||||
Train **new_vehs = CallocT<Train *>(num_units); ///< New vehicles corresponding to old_vehs or nullptr if no replacement
|
||||
Money *new_costs = MallocT<Money>(num_units); ///< Costs for buying and refitting the new vehicles
|
||||
|
||||
/* Collect vehicles and build replacements
|
||||
* Note: The replacement vehicles can only successfully build as long as the old vehicles are still in their chain */
|
||||
int i;
|
||||
Train *w;
|
||||
for (w = Train::From(old_head), i = 0; w != NULL; w = w->GetNextUnit(), i++) {
|
||||
for (w = Train::From(old_head), i = 0; w != nullptr; w = w->GetNextUnit(), i++) {
|
||||
assert(i < num_units);
|
||||
old_vehs[i] = w;
|
||||
|
||||
@@ -468,41 +475,41 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
if (cost.Failed()) break;
|
||||
|
||||
new_costs[i] = ret.GetCost();
|
||||
if (new_vehs[i] != NULL) *nothing_to_do = false;
|
||||
if (new_vehs[i] != nullptr) *nothing_to_do = false;
|
||||
}
|
||||
Train *new_head = (new_vehs[0] != NULL ? new_vehs[0] : old_vehs[0]);
|
||||
Train *new_head = (new_vehs[0] != nullptr ? new_vehs[0] : old_vehs[0]);
|
||||
|
||||
/* Note: When autoreplace has already failed here, old_vehs[] is not completely initialized. But it is also not needed. */
|
||||
if (cost.Succeeded()) {
|
||||
/* Separate the head, so we can start constructing the new chain */
|
||||
Train *second = Train::From(old_head)->GetNextUnit();
|
||||
if (second != NULL) cost.AddCost(CmdMoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true));
|
||||
if (second != nullptr) cost.AddCost(CmdMoveVehicle(second, nullptr, DC_EXEC | DC_AUTOREPLACE, true));
|
||||
|
||||
assert(Train::From(new_head)->GetNextUnit() == NULL);
|
||||
assert(Train::From(new_head)->GetNextUnit() == nullptr);
|
||||
|
||||
/* Append engines to the new chain
|
||||
* We do this from back to front, so that the head of the temporary vehicle chain does not change all the time.
|
||||
* That way we also have less trouble when exceeding the unitnumber limit.
|
||||
* OTOH the vehicle attach callback is more expensive this way :s */
|
||||
Train *last_engine = NULL; ///< Shall store the last engine unit after this step
|
||||
Train *last_engine = nullptr; ///< Shall store the last engine unit after this step
|
||||
if (cost.Succeeded()) {
|
||||
for (int i = num_units - 1; i > 0; i--) {
|
||||
Train *append = (new_vehs[i] != NULL ? new_vehs[i] : old_vehs[i]);
|
||||
Train *append = (new_vehs[i] != nullptr ? new_vehs[i] : old_vehs[i]);
|
||||
|
||||
if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) continue;
|
||||
|
||||
if (new_vehs[i] != NULL) {
|
||||
if (new_vehs[i] != nullptr) {
|
||||
/* Move the old engine to a separate row with DC_AUTOREPLACE. Else
|
||||
* moving the wagon in front may fail later due to unitnumber limit.
|
||||
* (We have to attach wagons without DC_AUTOREPLACE.) */
|
||||
CmdMoveVehicle(old_vehs[i], NULL, DC_EXEC | DC_AUTOREPLACE, false);
|
||||
CmdMoveVehicle(old_vehs[i], nullptr, DC_EXEC | DC_AUTOREPLACE, false);
|
||||
}
|
||||
|
||||
if (last_engine == NULL) last_engine = append;
|
||||
if (last_engine == nullptr) last_engine = append;
|
||||
cost.AddCost(CmdMoveVehicle(append, new_head, DC_EXEC, false));
|
||||
if (cost.Failed()) break;
|
||||
}
|
||||
if (last_engine == NULL) last_engine = new_head;
|
||||
if (last_engine == nullptr) last_engine = new_head;
|
||||
}
|
||||
|
||||
/* When wagon removal is enabled and the new engines without any wagons are already longer than the old, we have to fail */
|
||||
@@ -513,8 +520,8 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
*/
|
||||
if (cost.Succeeded()) {
|
||||
for (int i = num_units - 1; i > 0; i--) {
|
||||
assert(last_engine != NULL);
|
||||
Vehicle *append = (new_vehs[i] != NULL ? new_vehs[i] : old_vehs[i]);
|
||||
assert(last_engine != nullptr);
|
||||
Vehicle *append = (new_vehs[i] != nullptr ? new_vehs[i] : old_vehs[i]);
|
||||
|
||||
if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) {
|
||||
/* Insert wagon after 'last_engine' */
|
||||
@@ -524,7 +531,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
* to the train becoming too long, or the train becoming longer
|
||||
* would move the vehicle to the empty vehicle chain. */
|
||||
if (wagon_removal && (res.Failed() ? res.GetErrorMessage() == STR_ERROR_TRAIN_TOO_LONG : new_head->gcache.cached_total_length > old_total_length)) {
|
||||
CmdMoveVehicle(append, NULL, DC_EXEC | DC_AUTOREPLACE, false);
|
||||
CmdMoveVehicle(append, nullptr, DC_EXEC | DC_AUTOREPLACE, false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -543,7 +550,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
assert(new_head->gcache.cached_total_length <= _settings_game.vehicle.max_train_length * TILE_SIZE);
|
||||
for (int i = 1; i < num_units; i++) {
|
||||
Vehicle *wagon = new_vehs[i];
|
||||
if (wagon == NULL) continue;
|
||||
if (wagon == nullptr) continue;
|
||||
if (wagon->First() == new_head) break;
|
||||
|
||||
assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON);
|
||||
@@ -551,7 +558,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
/* Sell wagon */
|
||||
CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon));
|
||||
assert(ret.Succeeded());
|
||||
new_vehs[i] = NULL;
|
||||
new_vehs[i] = nullptr;
|
||||
|
||||
/* Revert the money subtraction when the vehicle was built.
|
||||
* This value is different from the sell value, esp. because of refitting */
|
||||
@@ -572,18 +579,21 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
for (int i = 0; i < num_units; i++) {
|
||||
Vehicle *w = old_vehs[i];
|
||||
/* Is the vehicle again part of the new chain?
|
||||
* Note: We cannot test 'new_vehs[i] != NULL' as wagon removal might cause to remove both */
|
||||
* Note: We cannot test 'new_vehs[i] != nullptr' as wagon removal might cause to remove both */
|
||||
if (w->First() == new_head) continue;
|
||||
|
||||
if ((flags & DC_EXEC) != 0) TransferCargo(w, new_head, true);
|
||||
|
||||
/* Sell the vehicle.
|
||||
* Note: This might temporarly construct new trains, so use DC_AUTOREPLACE to prevent
|
||||
* Note: This might temporarily construct new trains, so use DC_AUTOREPLACE to prevent
|
||||
* it from failing due to engine limits. */
|
||||
cost.AddCost(DoCommand(0, w->index, 0, flags | DC_AUTOREPLACE, GetCmdSellVeh(w)));
|
||||
if ((flags & DC_EXEC) != 0) {
|
||||
old_vehs[i] = NULL;
|
||||
if (i == 0) old_head = NULL;
|
||||
old_vehs[i] = nullptr;
|
||||
if (i == 0) {
|
||||
AI::NewEvent(old_head->owner, new ScriptEventVehicleAutoReplaced(old_head->index, new_head->index));
|
||||
old_head = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,9 +606,9 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
if ((flags & DC_EXEC) == 0) {
|
||||
/* Separate the head, so we can reattach the old vehicles */
|
||||
Train *second = Train::From(old_head)->GetNextUnit();
|
||||
if (second != NULL) CmdMoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true);
|
||||
if (second != nullptr) CmdMoveVehicle(second, nullptr, DC_EXEC | DC_AUTOREPLACE, true);
|
||||
|
||||
assert(Train::From(old_head)->GetNextUnit() == NULL);
|
||||
assert(Train::From(old_head)->GetNextUnit() == nullptr);
|
||||
|
||||
for (int i = num_units - 1; i > 0; i--) {
|
||||
CommandCost ret = CmdMoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
|
||||
@@ -610,9 +620,9 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
/* Finally undo buying of new vehicles */
|
||||
if ((flags & DC_EXEC) == 0) {
|
||||
for (int i = num_units - 1; i >= 0; i--) {
|
||||
if (new_vehs[i] != NULL) {
|
||||
if (new_vehs[i] != nullptr) {
|
||||
DoCommand(0, new_vehs[i]->index, 0, DC_EXEC, GetCmdSellVeh(new_vehs[i]));
|
||||
new_vehs[i] = NULL;
|
||||
new_vehs[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -622,11 +632,11 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
free(new_costs);
|
||||
} else {
|
||||
/* Build and refit replacement vehicle */
|
||||
Vehicle *new_head = NULL;
|
||||
Vehicle *new_head = nullptr;
|
||||
cost.AddCost(BuildReplacementVehicle(old_head, &new_head, true));
|
||||
|
||||
/* Was a new vehicle constructed? */
|
||||
if (cost.Succeeded() && new_head != NULL) {
|
||||
if (cost.Succeeded() && new_head != nullptr) {
|
||||
*nothing_to_do = false;
|
||||
|
||||
/* The new vehicle is constructed, now take over orders and everything... */
|
||||
@@ -637,6 +647,8 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
if ((flags & DC_EXEC) != 0) {
|
||||
TransferCargo(old_head, new_head, true);
|
||||
*chain = new_head;
|
||||
|
||||
AI::NewEvent(old_head->owner, new ScriptEventVehicleAutoReplaced(old_head->index, new_head->index));
|
||||
}
|
||||
|
||||
/* Sell the old vehicle */
|
||||
@@ -666,7 +678,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
Vehicle *v = Vehicle::GetIfValid(p1);
|
||||
if (v == NULL) return CMD_ERROR;
|
||||
if (v == nullptr) return CMD_ERROR;
|
||||
|
||||
CommandCost ret = CheckOwnership(v->owner);
|
||||
if (ret.Failed()) return ret;
|
||||
@@ -690,12 +702,12 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1
|
||||
/* Test whether any replacement is set, before issuing a whole lot of commands that would end in nothing changed */
|
||||
Vehicle *w = v;
|
||||
bool any_replacements = false;
|
||||
while (w != NULL) {
|
||||
while (w != nullptr) {
|
||||
EngineID e;
|
||||
CommandCost cost = GetNewEngineType(w, c, false, e);
|
||||
if (cost.Failed()) return cost;
|
||||
any_replacements |= (e != INVALID_ENGINE);
|
||||
w = (!free_wagon && w->type == VEH_TRAIN ? Train::From(w)->GetNextUnit() : NULL);
|
||||
w = (!free_wagon && w->type == VEH_TRAIN ? Train::From(w)->GetNextUnit() : nullptr);
|
||||
}
|
||||
|
||||
CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0);
|
||||
@@ -756,7 +768,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1
|
||||
CommandCost CmdSetAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
Company *c = Company::GetIfValid(_current_company);
|
||||
if (c == NULL) return CMD_ERROR;
|
||||
if (c == nullptr) return CMD_ERROR;
|
||||
|
||||
EngineID old_engine_type = GB(p2, 0, 16);
|
||||
EngineID new_engine_type = GB(p2, 16, 16);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "company_base.h"
|
||||
|
||||
void RemoveAllEngineReplacement(EngineRenewList *erl);
|
||||
EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group, bool *replace_when_old = NULL);
|
||||
EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group, bool *replace_when_old = nullptr);
|
||||
CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, GroupID group, bool replace_when_old, DoCommandFlag flags);
|
||||
CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, DoCommandFlag flags);
|
||||
|
||||
@@ -38,7 +38,7 @@ static inline void RemoveAllEngineReplacementForCompany(Company *c)
|
||||
* @return The engine type to replace with, or INVALID_ENGINE if no
|
||||
* replacement is in the list.
|
||||
*/
|
||||
static inline EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group, bool *replace_when_old = NULL)
|
||||
static inline EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group, bool *replace_when_old = nullptr)
|
||||
{
|
||||
return EngineReplacement(c->engine_renew_list, engine, group, replace_when_old);
|
||||
}
|
||||
|
||||
+184
-46
@@ -14,6 +14,7 @@
|
||||
#include "vehicle_gui.h"
|
||||
#include "newgrf_engine.h"
|
||||
#include "rail.h"
|
||||
#include "road.h"
|
||||
#include "strings_func.h"
|
||||
#include "window_func.h"
|
||||
#include "autoreplace_func.h"
|
||||
@@ -24,6 +25,7 @@
|
||||
#include "settings_func.h"
|
||||
#include "core/geometry_func.hpp"
|
||||
#include "rail_gui.h"
|
||||
#include "road_gui.h"
|
||||
#include "widgets/dropdown_func.h"
|
||||
|
||||
#include "widgets/autoreplace_widget.h"
|
||||
@@ -32,11 +34,9 @@
|
||||
|
||||
void DrawEngineList(VehicleType type, int x, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group);
|
||||
|
||||
static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b)
|
||||
static bool EngineNumberSorter(const EngineID &a, const EngineID &b)
|
||||
{
|
||||
int r = Engine::Get(*a)->list_position - Engine::Get(*b)->list_position;
|
||||
|
||||
return r;
|
||||
return Engine::Get(a)->list_position < Engine::Get(b)->list_position;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,6 +88,7 @@ class ReplaceVehicleWindow : public Window {
|
||||
bool descending_sort_order; ///< Order of sorting vehicles.
|
||||
bool show_hidden_engines; ///< Whether to show the hidden engines.
|
||||
RailType sel_railtype; ///< Type of rail tracks selected. #INVALID_RAILTYPE to show all.
|
||||
RoadType sel_roadtype; ///< Type of road selected. #INVALID_ROADTYPE to show all.
|
||||
Scrollbar *vscroll[2];
|
||||
|
||||
/**
|
||||
@@ -123,13 +124,27 @@ class ReplaceVehicleWindow : public Window {
|
||||
byte side = draw_left ? 0 : 1;
|
||||
|
||||
GUIEngineList *list = &this->engines[side];
|
||||
list->Clear();
|
||||
list->clear();
|
||||
|
||||
const Engine *e;
|
||||
FOR_ALL_ENGINES_OF_TYPE(e, type) {
|
||||
if (!draw_left && !this->show_hidden_engines && e->IsHidden(_local_company)) continue;
|
||||
EngineID eid = e->index;
|
||||
if (type == VEH_TRAIN && !this->GenerateReplaceRailList(eid, draw_left, this->replace_engines)) continue; // special rules for trains
|
||||
switch (type) {
|
||||
case VEH_TRAIN:
|
||||
if (!this->GenerateReplaceRailList(eid, draw_left, this->replace_engines)) continue; // special rules for trains
|
||||
break;
|
||||
|
||||
case VEH_ROAD:
|
||||
if (draw_left && this->sel_roadtype != INVALID_ROADTYPE) {
|
||||
/* Ensure that the roadtype is specific to the selected one */
|
||||
if (e->u.road.roadtype != this->sel_roadtype) continue;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (draw_left) {
|
||||
const uint num_engines = GetGroupNumEngines(_local_company, this->sel_group, eid);
|
||||
@@ -140,7 +155,7 @@ class ReplaceVehicleWindow : public Window {
|
||||
if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_company)) continue;
|
||||
}
|
||||
|
||||
*list->Append() = eid;
|
||||
list->push_back(eid);
|
||||
if (eid == this->sel_engine[side]) selected_engine = eid; // The selected engine is still in the list
|
||||
}
|
||||
this->sel_engine[side] = selected_engine; // update which engine we selected (the same or none, if it's not in the list anymore)
|
||||
@@ -160,8 +175,8 @@ class ReplaceVehicleWindow : public Window {
|
||||
if (this->engines[0].NeedRebuild()) {
|
||||
/* We need to rebuild the left engines list */
|
||||
this->GenerateReplaceVehList(true);
|
||||
this->vscroll[0]->SetCount(this->engines[0].Length());
|
||||
if (this->reset_sel_engine && this->sel_engine[0] == INVALID_ENGINE && this->engines[0].Length() != 0) {
|
||||
this->vscroll[0]->SetCount((uint)this->engines[0].size());
|
||||
if (this->reset_sel_engine && this->sel_engine[0] == INVALID_ENGINE && this->engines[0].size() != 0) {
|
||||
this->sel_engine[0] = this->engines[0][0];
|
||||
}
|
||||
}
|
||||
@@ -170,7 +185,7 @@ class ReplaceVehicleWindow : public Window {
|
||||
/* Either we got a request to rebuild the right engines list, or the left engines list selected a different engine */
|
||||
if (this->sel_engine[0] == INVALID_ENGINE) {
|
||||
/* Always empty the right engines list when nothing is selected in the left engines list */
|
||||
this->engines[1].Clear();
|
||||
this->engines[1].clear();
|
||||
this->sel_engine[1] = INVALID_ENGINE;
|
||||
} else {
|
||||
if (this->reset_sel_engine && this->sel_engine[0] != INVALID_ENGINE) {
|
||||
@@ -180,11 +195,11 @@ class ReplaceVehicleWindow : public Window {
|
||||
}
|
||||
/* Regenerate the list on the right. Note: This resets sel_engine[1] to INVALID_ENGINE, if it is no longer available. */
|
||||
this->GenerateReplaceVehList(false);
|
||||
this->vscroll[1]->SetCount(this->engines[1].Length());
|
||||
this->vscroll[1]->SetCount((uint)this->engines[1].size());
|
||||
if (this->reset_sel_engine && this->sel_engine[1] != INVALID_ENGINE) {
|
||||
int position = 0;
|
||||
for (EngineID *it = this->engines[1].Begin(); it != this->engines[1].End(); ++it) {
|
||||
if (*it == this->sel_engine[1]) break;
|
||||
for (EngineID &eid : this->engines[1]) {
|
||||
if (eid == this->sel_engine[1]) break;
|
||||
++position;
|
||||
}
|
||||
this->vscroll[1]->ScrollTowards(position);
|
||||
@@ -212,6 +227,7 @@ public:
|
||||
ReplaceVehicleWindow(WindowDesc *desc, VehicleType vehicletype, GroupID id_g) : Window(desc)
|
||||
{
|
||||
this->sel_railtype = INVALID_RAILTYPE;
|
||||
this->sel_roadtype = INVALID_ROADTYPE;
|
||||
this->replace_engines = true; // start with locomotives (all other vehicles will not read this bool)
|
||||
this->engines[0].ForceRebuild();
|
||||
this->engines[1].ForceRebuild();
|
||||
@@ -231,13 +247,18 @@ public:
|
||||
widget->SetLowered(this->show_hidden_engines);
|
||||
this->FinishInitNested(vehicletype);
|
||||
|
||||
if (vehicletype == VEH_TRAIN || vehicletype == VEH_ROAD) {
|
||||
widget = this->GetWidget<NWidgetCore>(WID_RV_RAIL_ROAD_TYPE_DROPDOWN);
|
||||
widget->tool_tip = STR_REPLACE_HELP_RAILTYPE + vehicletype;
|
||||
}
|
||||
|
||||
this->sort_criteria = _engine_sort_last_criteria[vehicletype];
|
||||
this->descending_sort_order = _engine_sort_last_order[vehicletype];
|
||||
this->owner = _local_company;
|
||||
this->sel_group = id_g;
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_RV_SORT_ASCENDING_DESCENDING: {
|
||||
@@ -289,13 +310,28 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_RV_TRAIN_RAILTYPE_DROPDOWN: {
|
||||
case WID_RV_RAIL_ROAD_TYPE_DROPDOWN: {
|
||||
Dimension d = {0, 0};
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||
const RailtypeInfo *rti = GetRailTypeInfo(rt);
|
||||
/* Skip rail type if it has no label */
|
||||
if (rti->label == 0) continue;
|
||||
d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text));
|
||||
switch (this->window_number) {
|
||||
case VEH_TRAIN:
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||
const RailtypeInfo *rti = GetRailTypeInfo(rt);
|
||||
/* Skip rail type if it has no label */
|
||||
if (rti->label == 0) continue;
|
||||
d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text));
|
||||
}
|
||||
break;
|
||||
|
||||
case VEH_ROAD:
|
||||
for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) {
|
||||
const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
|
||||
/* Skip road type if it has no label */
|
||||
if (rti->label == 0) continue;
|
||||
d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text));
|
||||
}
|
||||
break;
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
d.width += padding.width;
|
||||
d.height += padding.height;
|
||||
@@ -316,7 +352,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_RV_CAPTION:
|
||||
@@ -353,7 +389,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_RV_SORT_ASCENDING_DESCENDING:
|
||||
@@ -384,7 +420,7 @@ public:
|
||||
case WID_RV_RIGHT_MATRIX: {
|
||||
int side = (widget == WID_RV_LEFT_MATRIX) ? 0 : 1;
|
||||
EngineID start = this->vscroll[side]->GetPosition(); // what is the offset for the start (scrolling)
|
||||
EngineID end = min(this->vscroll[side]->GetCapacity() + start, this->engines[side].Length());
|
||||
EngineID end = min(this->vscroll[side]->GetCapacity() + start, (uint)this->engines[side].size());
|
||||
|
||||
/* Do the actual drawing */
|
||||
DrawEngineList((VehicleType)this->window_number, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP,
|
||||
@@ -394,7 +430,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPaint()
|
||||
void OnPaint() override
|
||||
{
|
||||
if (this->engines[0].NeedRebuild() || this->engines[1].NeedRebuild()) this->GenerateLists();
|
||||
|
||||
@@ -411,9 +447,18 @@ public:
|
||||
* or The selected vehicle has no replacement set up */
|
||||
this->SetWidgetDisabledState(WID_RV_STOP_REPLACE, this->sel_engine[0] == INVALID_ENGINE || !EngineHasReplacementForCompany(c, this->sel_engine[0], this->sel_group));
|
||||
|
||||
if (this->window_number == VEH_TRAIN) {
|
||||
/* Show the selected railtype in the pulldown menu */
|
||||
this->GetWidget<NWidgetCore>(WID_RV_TRAIN_RAILTYPE_DROPDOWN)->widget_data = sel_railtype == INVALID_RAILTYPE ? STR_REPLACE_ALL_RAILTYPE : GetRailTypeInfo(sel_railtype)->strings.replace_text;
|
||||
switch (this->window_number) {
|
||||
case VEH_TRAIN:
|
||||
/* Show the selected railtype in the pulldown menu */
|
||||
this->GetWidget<NWidgetCore>(WID_RV_RAIL_ROAD_TYPE_DROPDOWN)->widget_data = sel_railtype == INVALID_RAILTYPE ? STR_REPLACE_ALL_RAILTYPE : GetRailTypeInfo(sel_railtype)->strings.replace_text;
|
||||
break;
|
||||
|
||||
case VEH_ROAD:
|
||||
/* Show the selected roadtype in the pulldown menu */
|
||||
this->GetWidget<NWidgetCore>(WID_RV_RAIL_ROAD_TYPE_DROPDOWN)->widget_data = sel_roadtype == INVALID_ROADTYPE ? STR_REPLACE_ALL_ROADTYPE : GetRoadTypeInfo(sel_roadtype)->strings.replace_text;
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
this->DrawWidgets();
|
||||
@@ -423,9 +468,16 @@ public:
|
||||
/* Draw details panels. */
|
||||
for (int side = 0; side < 2; side++) {
|
||||
if (this->sel_engine[side] != INVALID_ENGINE) {
|
||||
/* Use default engine details without refitting */
|
||||
const Engine *e = Engine::Get(this->sel_engine[side]);
|
||||
TestedEngineDetails ted;
|
||||
ted.cost = 0;
|
||||
ted.cargo = e->GetDefaultCargoType();
|
||||
ted.capacity = e->GetDisplayDefaultCapacity(&ted.mail_capacity);
|
||||
|
||||
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS);
|
||||
int text_end = DrawVehiclePurchaseInfo(nwi->pos_x + WD_FRAMETEXT_LEFT, nwi->pos_x + nwi->current_x - WD_FRAMETEXT_RIGHT,
|
||||
nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine[side]);
|
||||
nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine[side], ted);
|
||||
needed_height = max(needed_height, text_end - (int)nwi->pos_y + WD_FRAMERECT_BOTTOM);
|
||||
}
|
||||
}
|
||||
@@ -437,7 +489,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_RV_SORT_ASCENDING_DESCENDING:
|
||||
@@ -460,15 +512,23 @@ public:
|
||||
break;
|
||||
|
||||
case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: {
|
||||
DropDownList *list = new DropDownList();
|
||||
*list->Append() = new DropDownListStringItem(STR_REPLACE_ENGINES, 1, false);
|
||||
*list->Append() = new DropDownListStringItem(STR_REPLACE_WAGONS, 0, false);
|
||||
ShowDropDownList(this, list, this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN);
|
||||
DropDownList list;
|
||||
list.emplace_back(new DropDownListStringItem(STR_REPLACE_ENGINES, 1, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_REPLACE_WAGONS, 0, false));
|
||||
ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN);
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_RV_TRAIN_RAILTYPE_DROPDOWN: // Railtype selection dropdown menu
|
||||
ShowDropDownList(this, GetRailTypeDropDownList(true, true), sel_railtype, WID_RV_TRAIN_RAILTYPE_DROPDOWN);
|
||||
case WID_RV_RAIL_ROAD_TYPE_DROPDOWN: // Rail/roadtype selection dropdown menu
|
||||
switch (this->window_number) {
|
||||
case VEH_TRAIN:
|
||||
ShowDropDownList(this, GetRailTypeDropDownList(true, true), sel_railtype, WID_RV_RAIL_ROAD_TYPE_DROPDOWN);
|
||||
break;
|
||||
|
||||
case VEH_ROAD:
|
||||
ShowDropDownList(this, GetRoadTypeDropDownList(RTTB_ROAD | RTTB_TRAM, true, true), sel_roadtype, WID_RV_RAIL_ROAD_TYPE_DROPDOWN);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: // toggle renew_keep_length
|
||||
@@ -501,7 +561,7 @@ public:
|
||||
click_side = 1;
|
||||
}
|
||||
uint i = this->vscroll[click_side]->GetScrolledRowFromWidget(pt.y, this, widget);
|
||||
size_t engine_count = this->engines[click_side].Length();
|
||||
size_t engine_count = this->engines[click_side].size();
|
||||
|
||||
EngineID e = engine_count > i ? this->engines[click_side][i] : INVALID_ENGINE;
|
||||
if (e == this->sel_engine[click_side]) break; // we clicked the one we already selected
|
||||
@@ -516,7 +576,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnDropdownSelect(int widget, int index)
|
||||
void OnDropdownSelect(int widget, int index) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_RV_SORT_DROPDOWN:
|
||||
@@ -528,10 +588,25 @@ public:
|
||||
}
|
||||
break;
|
||||
|
||||
case WID_RV_TRAIN_RAILTYPE_DROPDOWN: {
|
||||
RailType temp = (RailType)index;
|
||||
if (temp == sel_railtype) return; // we didn't select a new one. No need to change anything
|
||||
sel_railtype = temp;
|
||||
case WID_RV_RAIL_ROAD_TYPE_DROPDOWN:
|
||||
switch (this->window_number) {
|
||||
case VEH_TRAIN: {
|
||||
RailType temp = (RailType)index;
|
||||
if (temp == sel_railtype) return; // we didn't select a new one. No need to change anything
|
||||
sel_railtype = temp;
|
||||
break;
|
||||
}
|
||||
|
||||
case VEH_ROAD: {
|
||||
RoadType temp = (RoadType)index;
|
||||
if (temp == sel_roadtype) return; // we didn't select a new one. No need to change anything
|
||||
sel_roadtype = temp;
|
||||
break;
|
||||
}
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
/* Reset scrollbar positions */
|
||||
this->vscroll[0]->SetPosition(0);
|
||||
this->vscroll[1]->SetPosition(0);
|
||||
@@ -541,7 +616,6 @@ public:
|
||||
this->reset_sel_engine = true;
|
||||
this->SetDirty();
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: {
|
||||
this->replace_engines = index != 0;
|
||||
@@ -557,7 +631,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnResize()
|
||||
void OnResize() override
|
||||
{
|
||||
this->vscroll[0]->SetCapacityFromWidget(this, WID_RV_LEFT_MATRIX);
|
||||
this->vscroll[1]->SetCapacityFromWidget(this, WID_RV_RIGHT_MATRIX);
|
||||
@@ -568,7 +642,7 @@ public:
|
||||
* @param data Information about the changed data.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (data != 0) {
|
||||
/* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
|
||||
@@ -598,7 +672,7 @@ static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_RAILTYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_RAIL_ROAD_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_REPLACE_ENGINE_WAGON_SELECT_HELP),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
|
||||
@@ -643,6 +717,64 @@ static WindowDesc _replace_rail_vehicle_desc(
|
||||
_nested_replace_rail_vehicle_widgets, lengthof(_nested_replace_rail_vehicle_widgets)
|
||||
);
|
||||
|
||||
static const NWidgetPart _nested_replace_road_vehicle_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION), SetDataTip(STR_REPLACE_VEHICLES_WHITE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
|
||||
NWidget(WWT_SHADEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||
NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_REPLACE_VEHICLE_VEHICLES_IN_USE, STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP), SetFill(1, 1), SetMinimalSize(0, 12), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||
NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES, STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP), SetFill(1, 1), SetMinimalSize(0, 12), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_RAIL_ROAD_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), SetFill(1, 1),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||
NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR),
|
||||
NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(NWID_PUSHBUTTON_DROPDOWN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetDataTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_INFO_TAB), SetMinimalSize(167, 12), SetDataTip(0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_STOP_REPLACE), SetMinimalSize(150, 12), SetDataTip(STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _replace_road_vehicle_desc(
|
||||
WDP_AUTO, "replace_vehicle_road", 500, 140,
|
||||
WC_REPLACE_VEHICLE, WC_NONE,
|
||||
WDF_CONSTRUCTION,
|
||||
_nested_replace_road_vehicle_widgets, lengthof(_nested_replace_road_vehicle_widgets)
|
||||
);
|
||||
|
||||
static const NWidgetPart _nested_replace_vehicle_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
||||
@@ -705,5 +837,11 @@ static WindowDesc _replace_vehicle_desc(
|
||||
void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype)
|
||||
{
|
||||
DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype);
|
||||
new ReplaceVehicleWindow(vehicletype == VEH_TRAIN ? &_replace_rail_vehicle_desc : &_replace_vehicle_desc, vehicletype, id_g);
|
||||
WindowDesc *desc;
|
||||
switch (vehicletype) {
|
||||
case VEH_TRAIN: desc = &_replace_rail_vehicle_desc; break;
|
||||
case VEH_ROAD: desc = &_replace_road_vehicle_desc; break;
|
||||
default: desc = &_replace_vehicle_desc; break;
|
||||
}
|
||||
new ReplaceVehicleWindow(desc, vehicletype, id_g);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ void BaseConsist::CopyConsistPropertiesFrom(const BaseConsist *src)
|
||||
if (this == src) return;
|
||||
|
||||
free(this->name);
|
||||
this->name = src->name != NULL ? stredup(src->name) : NULL;
|
||||
this->name = src->name != nullptr ? stredup(src->name) : nullptr;
|
||||
|
||||
this->current_order_time = src->current_order_time;
|
||||
this->lateness_counter = src->lateness_counter;
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ struct BaseConsist {
|
||||
|
||||
uint16 vehicle_flags; ///< Used for gradual loading and other miscellaneous things (@see VehicleFlags enum)
|
||||
|
||||
BaseConsist() : name(NULL) {}
|
||||
BaseConsist() : name(nullptr) {}
|
||||
virtual ~BaseConsist();
|
||||
|
||||
void CopyConsistPropertiesFrom(const BaseConsist *src);
|
||||
|
||||
+15
-15
@@ -76,9 +76,9 @@ struct BaseSet {
|
||||
{
|
||||
free(this->name);
|
||||
|
||||
for (TranslatedStrings::iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
|
||||
free(iter->first);
|
||||
free(iter->second);
|
||||
for (auto &pair : this->description) {
|
||||
free(pair.first);
|
||||
free(pair.second);
|
||||
}
|
||||
|
||||
for (uint i = 0; i < NUM_FILES; i++) {
|
||||
@@ -118,20 +118,20 @@ struct BaseSet {
|
||||
* @param isocode the isocode to search for
|
||||
* @return the description
|
||||
*/
|
||||
const char *GetDescription(const char *isocode = NULL) const
|
||||
const char *GetDescription(const char *isocode = nullptr) const
|
||||
{
|
||||
if (isocode != NULL) {
|
||||
if (isocode != nullptr) {
|
||||
/* First the full ISO code */
|
||||
for (TranslatedStrings::const_iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
|
||||
if (strcmp(iter->first, isocode) == 0) return iter->second;
|
||||
for (const auto &pair : this->description) {
|
||||
if (strcmp(pair.first, isocode) == 0) return pair.second;
|
||||
}
|
||||
/* Then the first two characters */
|
||||
for (TranslatedStrings::const_iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
|
||||
if (strncmp(iter->first, isocode, 2) == 0) return iter->second;
|
||||
for (const auto &pair : this->description) {
|
||||
if (strncmp(pair.first, isocode, 2) == 0) return pair.second;
|
||||
}
|
||||
}
|
||||
/* Then fall back */
|
||||
return this->description.Begin()->second;
|
||||
return this->description.front().second;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,17 +151,17 @@ struct BaseSet {
|
||||
/**
|
||||
* Search a textfile file next to this base media.
|
||||
* @param type The type of the textfile to search for.
|
||||
* @return The filename for the textfile, \c NULL otherwise.
|
||||
* @return The filename for the textfile, \c nullptr otherwise.
|
||||
*/
|
||||
const char *GetTextfile(TextfileType type) const
|
||||
{
|
||||
for (uint i = 0; i < NUM_FILES; i++) {
|
||||
const char *textfile = ::GetTextfile(type, BASESET_DIR, this->files[i].filename);
|
||||
if (textfile != NULL) {
|
||||
if (textfile != nullptr) {
|
||||
return textfile;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -176,7 +176,7 @@ protected:
|
||||
static Tbase_set *duplicate_sets; ///< All sets that aren't available, but needed for not downloading base sets when a newer version than the one on BaNaNaS is loaded.
|
||||
static const Tbase_set *used_set; ///< The currently used set
|
||||
|
||||
/* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename);
|
||||
bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override;
|
||||
|
||||
/**
|
||||
* Get the extension that is used to identify this set.
|
||||
@@ -231,7 +231,7 @@ template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::duplica
|
||||
* @param ci The content info to compare it to.
|
||||
* @param md5sum Should the MD5 checksum be tested as well?
|
||||
* @param s The list with sets.
|
||||
* @return The filename of the first file of the base set, or \c NULL if there is no match.
|
||||
* @return The filename of the first file of the base set, or \c nullptr if there is no match.
|
||||
*/
|
||||
template <class Tbase_set>
|
||||
const char *TryGetBaseSetFile(const ContentInfo *ci, bool md5sum, const Tbase_set *s);
|
||||
|
||||
+25
-42
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
#define fetch_metadata(name) \
|
||||
item = metadata->GetItem(name, false); \
|
||||
if (item == NULL || StrEmpty(item->value)) { \
|
||||
if (item == nullptr || StrEmpty(item->value)) { \
|
||||
DEBUG(grf, 0, "Base " SET_TYPE "set detail loading: %s field missing.", name); \
|
||||
DEBUG(grf, 0, " Is %s readable for the user running OpenTTD?", full_filename); \
|
||||
return false; \
|
||||
@@ -50,7 +50,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
||||
this->description[stredup("")] = stredup(item->value);
|
||||
|
||||
/* Add the translations of the descriptions too. */
|
||||
for (const IniItem *item = metadata->item; item != NULL; item = item->next) {
|
||||
for (const IniItem *item = metadata->item; item != nullptr; item = item->next) {
|
||||
if (strncmp("description.", item->name, 12) != 0) continue;
|
||||
|
||||
this->description[stredup(item->name + 12)] = stredup(item->value);
|
||||
@@ -65,7 +65,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
||||
this->version = atoi(item->value);
|
||||
|
||||
item = metadata->GetItem("fallback", false);
|
||||
this->fallback = (item != NULL && strcmp(item->value, "0") != 0 && strcmp(item->value, "false") != 0);
|
||||
this->fallback = (item != nullptr && strcmp(item->value, "0") != 0 && strcmp(item->value, "false") != 0);
|
||||
|
||||
/* For each of the file types we want to find the file, MD5 checksums and warning messages. */
|
||||
IniGroup *files = ini->GetGroup("files");
|
||||
@@ -75,14 +75,14 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
||||
MD5File *file = &this->files[i];
|
||||
/* Find the filename first. */
|
||||
item = files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], false);
|
||||
if (item == NULL || (item->value == NULL && !allow_empty_filename)) {
|
||||
if (item == nullptr || (item->value == nullptr && !allow_empty_filename)) {
|
||||
DEBUG(grf, 0, "No " SET_TYPE " file for: %s (in %s)", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *filename = item->value;
|
||||
if (filename == NULL) {
|
||||
file->filename = NULL;
|
||||
if (filename == nullptr) {
|
||||
file->filename = nullptr;
|
||||
/* If we list no file, that file must be valid */
|
||||
this->valid_files++;
|
||||
this->found_files++;
|
||||
@@ -93,7 +93,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
||||
|
||||
/* Then find the MD5 checksum */
|
||||
item = md5s->GetItem(filename, false);
|
||||
if (item == NULL || item->value == NULL) {
|
||||
if (item == nullptr || item->value == nullptr) {
|
||||
DEBUG(grf, 0, "No MD5 checksum specified for: %s (in %s)", filename, full_filename);
|
||||
return false;
|
||||
}
|
||||
@@ -119,8 +119,8 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
||||
|
||||
/* Then find the warning message when the file's missing */
|
||||
item = origin->GetItem(filename, false);
|
||||
if (item == NULL) item = origin->GetItem("default", false);
|
||||
if (item == NULL) {
|
||||
if (item == nullptr) item = origin->GetItem("default", false);
|
||||
if (item == nullptr) {
|
||||
DEBUG(grf, 1, "No origin warning message specified for: %s", filename);
|
||||
file->missing_warning = stredup("");
|
||||
} else {
|
||||
@@ -159,25 +159,25 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
|
||||
|
||||
Tbase_set *set = new Tbase_set();
|
||||
IniFile *ini = new IniFile();
|
||||
ini->LoadFromDisk(filename, BASESET_DIR);
|
||||
|
||||
char *path = stredup(filename + basepath_length);
|
||||
ini->LoadFromDisk(path, BASESET_DIR);
|
||||
|
||||
char *psep = strrchr(path, PATHSEPCHAR);
|
||||
if (psep != NULL) {
|
||||
if (psep != nullptr) {
|
||||
psep[1] = '\0';
|
||||
} else {
|
||||
*path = '\0';
|
||||
}
|
||||
|
||||
if (set->FillSetDetails(ini, path, filename)) {
|
||||
Tbase_set *duplicate = NULL;
|
||||
for (Tbase_set *c = BaseMedia<Tbase_set>::available_sets; c != NULL; c = c->next) {
|
||||
Tbase_set *duplicate = nullptr;
|
||||
for (Tbase_set *c = BaseMedia<Tbase_set>::available_sets; c != nullptr; c = c->next) {
|
||||
if (strcmp(c->name, set->name) == 0 || c->shortname == set->shortname) {
|
||||
duplicate = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (duplicate != NULL) {
|
||||
if (duplicate != nullptr) {
|
||||
/* The more complete set takes precedence over the version number. */
|
||||
if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) ||
|
||||
duplicate->valid_files > set->valid_files) {
|
||||
@@ -205,7 +205,7 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
|
||||
}
|
||||
} else {
|
||||
Tbase_set **last = &BaseMedia<Tbase_set>::available_sets;
|
||||
while (*last != NULL) last = &(*last)->next;
|
||||
while (*last != nullptr) last = &(*last)->next;
|
||||
|
||||
*last = set;
|
||||
ret = true;
|
||||
@@ -238,7 +238,7 @@ template <class Tbase_set>
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != NULL; s = s->next) {
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
|
||||
if (strcmp(name, s->name) == 0) {
|
||||
BaseMedia<Tbase_set>::used_set = s;
|
||||
CheckExternalFiles();
|
||||
@@ -258,7 +258,7 @@ template <class Tbase_set>
|
||||
/* static */ char *BaseMedia<Tbase_set>::GetSetsList(char *p, const char *last)
|
||||
{
|
||||
p += seprintf(p, last, "List of " SET_TYPE " sets:\n");
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != NULL; s = s->next) {
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
|
||||
p += seprintf(p, last, "%18s: %s", s->name, s->GetDescription());
|
||||
int invalid = s->GetNumInvalid();
|
||||
if (invalid != 0) {
|
||||
@@ -277,12 +277,11 @@ template <class Tbase_set>
|
||||
return p;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_NETWORK)
|
||||
#include "network/network_content.h"
|
||||
|
||||
template <class Tbase_set> const char *TryGetBaseSetFile(const ContentInfo *ci, bool md5sum, const Tbase_set *s)
|
||||
{
|
||||
for (; s != NULL; s = s->next) {
|
||||
for (; s != nullptr; s = s->next) {
|
||||
if (s->GetNumMissing() != 0) continue;
|
||||
|
||||
if (s->shortname != ci->unique_id) continue;
|
||||
@@ -297,32 +296,16 @@ template <class Tbase_set> const char *TryGetBaseSetFile(const ContentInfo *ci,
|
||||
}
|
||||
if (memcmp(md5, ci->md5sum, sizeof(md5)) == 0) return s->files[0].filename;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class Tbase_set>
|
||||
/* static */ bool BaseMedia<Tbase_set>::HasSet(const ContentInfo *ci, bool md5sum)
|
||||
{
|
||||
return (TryGetBaseSetFile(ci, md5sum, BaseMedia<Tbase_set>::available_sets) != NULL) ||
|
||||
(TryGetBaseSetFile(ci, md5sum, BaseMedia<Tbase_set>::duplicate_sets) != NULL);
|
||||
return (TryGetBaseSetFile(ci, md5sum, BaseMedia<Tbase_set>::available_sets) != nullptr) ||
|
||||
(TryGetBaseSetFile(ci, md5sum, BaseMedia<Tbase_set>::duplicate_sets) != nullptr);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class Tbase_set>
|
||||
const char *TryGetBaseSetFile(const ContentInfo *ci, bool md5sum, const Tbase_set *s)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template <class Tbase_set>
|
||||
/* static */ bool BaseMedia<Tbase_set>::HasSet(const ContentInfo *ci, bool md5sum)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
/**
|
||||
* Count the number of available graphics sets.
|
||||
* @return the number of sets
|
||||
@@ -331,7 +314,7 @@ template <class Tbase_set>
|
||||
/* static */ int BaseMedia<Tbase_set>::GetNumSets()
|
||||
{
|
||||
int n = 0;
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != NULL; s = s->next) {
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
|
||||
if (s != BaseMedia<Tbase_set>::used_set && s->GetNumMissing() != 0) continue;
|
||||
n++;
|
||||
}
|
||||
@@ -346,7 +329,7 @@ template <class Tbase_set>
|
||||
/* static */ int BaseMedia<Tbase_set>::GetIndexOfUsedSet()
|
||||
{
|
||||
int n = 0;
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != NULL; s = s->next) {
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
|
||||
if (s == BaseMedia<Tbase_set>::used_set) return n;
|
||||
if (s->GetNumMissing() != 0) continue;
|
||||
n++;
|
||||
@@ -361,7 +344,7 @@ template <class Tbase_set>
|
||||
template <class Tbase_set>
|
||||
/* static */ const Tbase_set *BaseMedia<Tbase_set>::GetSet(int index)
|
||||
{
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != NULL; s = s->next) {
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
|
||||
if (s != BaseMedia<Tbase_set>::used_set && s->GetNumMissing() != 0) continue;
|
||||
if (index == 0) return s;
|
||||
index--;
|
||||
|
||||
@@ -60,8 +60,8 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
||||
StringID string_id; ///< Default name (town area) of station
|
||||
|
||||
Town *town; ///< The town this station is associated with
|
||||
OwnerByte owner; ///< The owner of this station
|
||||
StationFacilityByte facilities; ///< The facilities that this station has
|
||||
Owner owner; ///< The owner of this station
|
||||
StationFacility facilities; ///< The facilities that this station has
|
||||
|
||||
uint8 num_specs; ///< Number of specs in the speclist
|
||||
StationSpecList *speclist; ///< List of station specs of this station
|
||||
@@ -110,6 +110,12 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
||||
*/
|
||||
virtual void UpdateVirtCoord() = 0;
|
||||
|
||||
virtual void MoveSign(TileIndex new_xy)
|
||||
{
|
||||
this->xy = new_xy;
|
||||
this->UpdateVirtCoord();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tile area for a given station type.
|
||||
* @param ta tile area to fill.
|
||||
@@ -214,7 +220,7 @@ struct SpecializedStation : public BaseStation {
|
||||
*/
|
||||
static inline T *GetIfValid(size_t index)
|
||||
{
|
||||
return IsValidID(index) ? Get(index) : NULL;
|
||||
return IsValidID(index) ? Get(index) : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* 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 bitmap_type.hpp Bitmap functions. */
|
||||
|
||||
#ifndef BITMAP_TYPE_HPP
|
||||
#define BITMAP_TYPE_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
/** Represents a tile area containing containing individually set tiles.
|
||||
* Each tile must be contained within the preallocated area.
|
||||
* A std::vector<bool> is used to mark which tiles are contained.
|
||||
*/
|
||||
class BitmapTileArea : public TileArea {
|
||||
protected:
|
||||
std::vector<bool> data;
|
||||
|
||||
inline uint Index(uint x, uint y) const { return y * this->w + x; }
|
||||
|
||||
inline uint Index(TileIndex tile) const { return Index(TileX(tile) - TileX(this->tile), TileY(tile) - TileY(this->tile)); }
|
||||
|
||||
public:
|
||||
BitmapTileArea()
|
||||
{
|
||||
this->tile = INVALID_TILE;
|
||||
this->w = 0;
|
||||
this->h = 0;
|
||||
}
|
||||
|
||||
BitmapTileArea(const TileArea &ta)
|
||||
{
|
||||
this->tile = ta.tile;
|
||||
this->w = ta.w;
|
||||
this->h = ta.h;
|
||||
this->data.resize(Index(this->w, this->h));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset and clear the BitmapTileArea.
|
||||
*/
|
||||
void Reset()
|
||||
{
|
||||
this->tile = INVALID_TILE;
|
||||
this->w = 0;
|
||||
this->h = 0;
|
||||
this->data.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the BitmapTileArea with the specified Rect.
|
||||
* @param rect Rect to use.
|
||||
*/
|
||||
void Initialize(const Rect &r)
|
||||
{
|
||||
this->tile = TileXY(r.left, r.top);
|
||||
this->w = r.right - r.left + 1;
|
||||
this->h = r.bottom - r.top + 1;
|
||||
this->data.clear();
|
||||
this->data.resize(Index(w, h));
|
||||
}
|
||||
|
||||
void Initialize(const TileArea &ta)
|
||||
{
|
||||
this->tile = ta.tile;
|
||||
this->w = ta.w;
|
||||
this->h = ta.h;
|
||||
this->data.clear();
|
||||
this->data.resize(Index(w, h));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tile as part of the tile area.
|
||||
* @param tile Tile to add.
|
||||
*/
|
||||
inline void SetTile(TileIndex tile)
|
||||
{
|
||||
assert(this->Contains(tile));
|
||||
this->data[Index(tile)] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a tile from the tile area.
|
||||
* @param tile Tile to clear
|
||||
*/
|
||||
inline void ClrTile(TileIndex tile)
|
||||
{
|
||||
assert(this->Contains(tile));
|
||||
this->data[Index(tile)] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a tile is part of the tile area.
|
||||
* @param tile Tile to check
|
||||
*/
|
||||
inline bool HasTile(TileIndex tile) const
|
||||
{
|
||||
return this->Contains(tile) && this->data[Index(tile)];
|
||||
}
|
||||
};
|
||||
|
||||
/** Iterator to iterate over all tiles belonging to a bitmaptilearea. */
|
||||
class BitmapTileIterator : public OrthogonalTileIterator {
|
||||
protected:
|
||||
const BitmapTileArea *bitmap;
|
||||
public:
|
||||
/**
|
||||
* Construct the iterator.
|
||||
* @param bitmap BitmapTileArea to iterate.
|
||||
*/
|
||||
BitmapTileIterator(const BitmapTileArea &bitmap) : OrthogonalTileIterator(bitmap), bitmap(&bitmap)
|
||||
{
|
||||
if (!this->bitmap->HasTile(TileIndex(this->tile))) ++(*this);
|
||||
}
|
||||
|
||||
inline TileIterator& operator ++()
|
||||
{
|
||||
(*this).OrthogonalTileIterator::operator++();
|
||||
while (this->tile != INVALID_TILE && !this->bitmap->HasTile(TileIndex(this->tile))) {
|
||||
(*this).OrthogonalTileIterator::operator++();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual TileIterator *Clone() const
|
||||
{
|
||||
return new BitmapTileIterator(*this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* BITMAP_TYPE_HPP */
|
||||
@@ -42,7 +42,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
||||
Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
|
||||
uint16 *anim = this->anim_buf + this->ScreenToAnimOffset((uint32 *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left;
|
||||
|
||||
const byte *remap = bp->remap; // store so we don't have to access it via bp everytime
|
||||
const byte *remap = bp->remap; // store so we don't have to access it via bp every time
|
||||
|
||||
for (int y = 0; y < bp->height; y++) {
|
||||
Colour *dst_ln = dst + bp->pitch;
|
||||
@@ -414,7 +414,7 @@ void Blitter_32bppAnim::CopyToBuffer(const void *video, void *dst, int width, in
|
||||
uint32 *udst = (uint32 *)dst;
|
||||
const uint32 *src = (const uint32 *)video;
|
||||
|
||||
if (this->anim_buf == NULL) return;
|
||||
if (this->anim_buf == nullptr) return;
|
||||
|
||||
const uint16 *anim_line = this->ScreenToAnimOffset((const uint32 *)video) + this->anim_buf;
|
||||
|
||||
|
||||
+17
-17
@@ -26,8 +26,8 @@ protected:
|
||||
|
||||
public:
|
||||
Blitter_32bppAnim() :
|
||||
anim_buf(NULL),
|
||||
anim_alloc(NULL),
|
||||
anim_buf(nullptr),
|
||||
anim_alloc(nullptr),
|
||||
anim_buf_width(0),
|
||||
anim_buf_height(0),
|
||||
anim_buf_pitch(0)
|
||||
@@ -37,21 +37,21 @@ public:
|
||||
|
||||
~Blitter_32bppAnim();
|
||||
|
||||
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
|
||||
/* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal);
|
||||
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
|
||||
/* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash);
|
||||
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
|
||||
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
|
||||
/* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);
|
||||
/* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y);
|
||||
/* virtual */ int BufferSize(int width, int height);
|
||||
/* virtual */ void PaletteAnimate(const Palette &palette);
|
||||
/* virtual */ Blitter::PaletteAnimation UsePaletteAnimation();
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
|
||||
void SetPixel(void *video, int x, int y, uint8 colour) override;
|
||||
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
|
||||
void DrawRect(void *video, int width, int height, uint8 colour) override;
|
||||
void CopyFromBuffer(void *video, const void *src, int width, int height) override;
|
||||
void CopyToBuffer(const void *video, void *dst, int width, int height) override;
|
||||
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
|
||||
int BufferSize(int width, int height) override;
|
||||
void PaletteAnimate(const Palette &palette) override;
|
||||
Blitter::PaletteAnimation UsePaletteAnimation() override;
|
||||
|
||||
/* virtual */ const char *GetName() { return "32bpp-anim"; }
|
||||
/* virtual */ int GetBytesPerPixel() { return 6; }
|
||||
/* virtual */ void PostResize();
|
||||
const char *GetName() override { return "32bpp-anim"; }
|
||||
int GetBytesPerPixel() override { return 6; }
|
||||
void PostResize() override;
|
||||
|
||||
/**
|
||||
* Look up the colour in the current palette.
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
class FBlitter_32bppAnim : public BlitterFactory {
|
||||
public:
|
||||
FBlitter_32bppAnim() : BlitterFactory("32bpp-anim", "32bpp Animation Blitter (palette animation)") {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_32bppAnim(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_32bppAnim(); }
|
||||
};
|
||||
|
||||
#endif /* BLITTER_32BPP_ANIM_HPP */
|
||||
|
||||
@@ -28,15 +28,15 @@
|
||||
/** A partially 32 bpp blitter with palette animation. */
|
||||
class Blitter_32bppSSE2_Anim : public Blitter_32bppAnim {
|
||||
public:
|
||||
/* virtual */ void PaletteAnimate(const Palette &palette);
|
||||
/* virtual */ const char *GetName() { return "32bpp-sse2-anim"; }
|
||||
void PaletteAnimate(const Palette &palette) override;
|
||||
const char *GetName() override { return "32bpp-sse2-anim"; }
|
||||
};
|
||||
|
||||
/** Factory for the partially 32bpp blitter with animation. */
|
||||
class FBlitter_32bppSSE2_Anim : public BlitterFactory {
|
||||
public:
|
||||
FBlitter_32bppSSE2_Anim() : BlitterFactory("32bpp-sse2-anim", "32bpp partially SSE2 Animation Blitter (palette animation)", HasCPUIDFlag(1, 3, 26)) {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSE2_Anim(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_32bppSSE2_Anim(); }
|
||||
};
|
||||
|
||||
#endif /* WITH_SSE */
|
||||
|
||||
@@ -35,19 +35,19 @@ private:
|
||||
|
||||
public:
|
||||
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent, bool animated>
|
||||
/* virtual */ void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
|
||||
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
|
||||
/* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) {
|
||||
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override {
|
||||
return Blitter_32bppSSE_Base::Encode(sprite, allocator);
|
||||
}
|
||||
/* virtual */ const char *GetName() { return "32bpp-sse4-anim"; }
|
||||
const char *GetName() override { return "32bpp-sse4-anim"; }
|
||||
};
|
||||
|
||||
/** Factory for the SSE4 32 bpp blitter (with palette animation). */
|
||||
class FBlitter_32bppSSE4_Anim: public BlitterFactory {
|
||||
public:
|
||||
FBlitter_32bppSSE4_Anim() : BlitterFactory("32bpp-sse4-anim", "32bpp SSE4 Blitter (palette animation)", HasCPUIDFlag(1, 2, 19)) {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSE4_Anim(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_32bppSSE4_Anim(); }
|
||||
};
|
||||
|
||||
#endif /* WITH_SSE */
|
||||
|
||||
+13
-13
@@ -20,19 +20,19 @@
|
||||
/** Base for all 32bpp blitters. */
|
||||
class Blitter_32bppBase : public Blitter {
|
||||
public:
|
||||
/* virtual */ uint8 GetScreenDepth() { return 32; }
|
||||
/* virtual */ void *MoveTo(void *video, int x, int y);
|
||||
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
|
||||
/* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash);
|
||||
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
|
||||
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
|
||||
/* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);
|
||||
/* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch);
|
||||
/* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y);
|
||||
/* virtual */ int BufferSize(int width, int height);
|
||||
/* virtual */ void PaletteAnimate(const Palette &palette);
|
||||
/* virtual */ Blitter::PaletteAnimation UsePaletteAnimation();
|
||||
/* virtual */ int GetBytesPerPixel() { return 4; }
|
||||
uint8 GetScreenDepth() override { return 32; }
|
||||
void *MoveTo(void *video, int x, int y) override;
|
||||
void SetPixel(void *video, int x, int y, uint8 colour) override;
|
||||
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
|
||||
void DrawRect(void *video, int width, int height, uint8 colour) override;
|
||||
void CopyFromBuffer(void *video, const void *src, int width, int height) override;
|
||||
void CopyToBuffer(const void *video, void *dst, int width, int height) override;
|
||||
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override;
|
||||
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
|
||||
int BufferSize(int width, int height) override;
|
||||
void PaletteAnimate(const Palette &palette) override;
|
||||
Blitter::PaletteAnimation UsePaletteAnimation() override;
|
||||
int GetBytesPerPixel() override { return 4; }
|
||||
|
||||
/**
|
||||
* Look up the colour in the current palette.
|
||||
|
||||
@@ -48,7 +48,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
|
||||
/* skip lines in dst */
|
||||
Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
|
||||
|
||||
/* store so we don't have to access it via bp everytime (compiler assumes pointer aliasing) */
|
||||
/* store so we don't have to access it via bp every time (compiler assumes pointer aliasing) */
|
||||
const byte *remap = bp->remap;
|
||||
|
||||
for (int y = 0; y < bp->height; y++) {
|
||||
@@ -66,7 +66,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
|
||||
/* we will end this line when we reach this point */
|
||||
Colour *dst_end = dst + bp->skip_left;
|
||||
|
||||
/* number of pixels with the same aplha channel class */
|
||||
/* number of pixels with the same alpha channel class */
|
||||
uint n;
|
||||
|
||||
while (dst < dst_end) {
|
||||
|
||||
@@ -23,10 +23,10 @@ public:
|
||||
byte data[]; ///< Data, all zoomlevels.
|
||||
};
|
||||
|
||||
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
|
||||
/* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
|
||||
|
||||
/* virtual */ const char *GetName() { return "32bpp-optimized"; }
|
||||
const char *GetName() override { return "32bpp-optimized"; }
|
||||
|
||||
template <BlitterMode mode> void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
|
||||
};
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
class FBlitter_32bppOptimized : public BlitterFactory {
|
||||
public:
|
||||
FBlitter_32bppOptimized() : BlitterFactory("32bpp-optimized", "32bpp Optimized Blitter (no palette animation)") {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_32bppOptimized(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_32bppOptimized(); }
|
||||
};
|
||||
|
||||
#endif /* BLITTER_32BPP_OPTIMIZED_HPP */
|
||||
|
||||
@@ -26,18 +26,18 @@ class Blitter_32bppSimple : public Blitter_32bppBase {
|
||||
uint8 v; ///< Brightness-channel
|
||||
};
|
||||
public:
|
||||
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
|
||||
/* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal);
|
||||
/* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
|
||||
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
|
||||
|
||||
/* virtual */ const char *GetName() { return "32bpp-simple"; }
|
||||
const char *GetName() override { return "32bpp-simple"; }
|
||||
};
|
||||
|
||||
/** Factory for the simple 32 bpp blitter. */
|
||||
class FBlitter_32bppSimple : public BlitterFactory {
|
||||
public:
|
||||
FBlitter_32bppSimple() : BlitterFactory("32bpp-simple", "32bpp Simple Blitter (no palette animation)") {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSimple(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_32bppSimple(); }
|
||||
};
|
||||
|
||||
#endif /* BLITTER_32BPP_SIMPLE_HPP */
|
||||
|
||||
@@ -82,22 +82,22 @@ DECLARE_ENUM_AS_BIT_SET(Blitter_32bppSSE_Base::SpriteFlags);
|
||||
/** The SSE2 32 bpp blitter (without palette animation). */
|
||||
class Blitter_32bppSSE2 : public Blitter_32bppSimple, public Blitter_32bppSSE_Base {
|
||||
public:
|
||||
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent>
|
||||
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
|
||||
|
||||
/* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) {
|
||||
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override {
|
||||
return Blitter_32bppSSE_Base::Encode(sprite, allocator);
|
||||
}
|
||||
|
||||
/* virtual */ const char *GetName() { return "32bpp-sse2"; }
|
||||
const char *GetName() override { return "32bpp-sse2"; }
|
||||
};
|
||||
|
||||
/** Factory for the SSE2 32 bpp blitter (without palette animation). */
|
||||
class FBlitter_32bppSSE2 : public BlitterFactory {
|
||||
public:
|
||||
FBlitter_32bppSSE2() : BlitterFactory("32bpp-sse2", "32bpp SSE2 Blitter (no palette animation)", HasCPUIDFlag(1, 3, 26)) {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSE2(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_32bppSSE2(); }
|
||||
};
|
||||
|
||||
#endif /* WITH_SSE */
|
||||
|
||||
@@ -27,17 +27,17 @@
|
||||
/** The SSE4 32 bpp blitter (without palette animation). */
|
||||
class Blitter_32bppSSE4 : public Blitter_32bppSSSE3 {
|
||||
public:
|
||||
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent>
|
||||
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
|
||||
/* virtual */ const char *GetName() { return "32bpp-sse4"; }
|
||||
const char *GetName() override { return "32bpp-sse4"; }
|
||||
};
|
||||
|
||||
/** Factory for the SSE4 32 bpp blitter (without palette animation). */
|
||||
class FBlitter_32bppSSE4: public BlitterFactory {
|
||||
public:
|
||||
FBlitter_32bppSSE4() : BlitterFactory("32bpp-sse4", "32bpp SSE4 Blitter (no palette animation)", HasCPUIDFlag(1, 2, 19)) {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSE4(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_32bppSSE4(); }
|
||||
};
|
||||
|
||||
#endif /* WITH_SSE */
|
||||
|
||||
@@ -27,17 +27,17 @@
|
||||
/** The SSSE3 32 bpp blitter (without palette animation). */
|
||||
class Blitter_32bppSSSE3 : public Blitter_32bppSSE2 {
|
||||
public:
|
||||
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent>
|
||||
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
|
||||
/* virtual */ const char *GetName() { return "32bpp-ssse3"; }
|
||||
const char *GetName() override { return "32bpp-ssse3"; }
|
||||
};
|
||||
|
||||
/** Factory for the SSSE3 32 bpp blitter (without palette animation). */
|
||||
class FBlitter_32bppSSSE3: public BlitterFactory {
|
||||
public:
|
||||
FBlitter_32bppSSSE3() : BlitterFactory("32bpp-ssse3", "32bpp SSSE3 Blitter (no palette animation)", HasCPUIDFlag(1, 2, 9)) {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSSE3(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_32bppSSSE3(); }
|
||||
};
|
||||
|
||||
#endif /* WITH_SSE */
|
||||
|
||||
+14
-14
@@ -17,20 +17,20 @@
|
||||
/** Base for all 8bpp blitters. */
|
||||
class Blitter_8bppBase : public Blitter {
|
||||
public:
|
||||
/* virtual */ uint8 GetScreenDepth() { return 8; }
|
||||
/* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal);
|
||||
/* virtual */ void *MoveTo(void *video, int x, int y);
|
||||
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
|
||||
/* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash);
|
||||
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
|
||||
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
|
||||
/* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);
|
||||
/* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch);
|
||||
/* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y);
|
||||
/* virtual */ int BufferSize(int width, int height);
|
||||
/* virtual */ void PaletteAnimate(const Palette &palette);
|
||||
/* virtual */ Blitter::PaletteAnimation UsePaletteAnimation();
|
||||
/* virtual */ int GetBytesPerPixel() { return 1; }
|
||||
uint8 GetScreenDepth() override { return 8; }
|
||||
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
|
||||
void *MoveTo(void *video, int x, int y) override;
|
||||
void SetPixel(void *video, int x, int y, uint8 colour) override;
|
||||
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
|
||||
void DrawRect(void *video, int width, int height, uint8 colour) override;
|
||||
void CopyFromBuffer(void *video, const void *src, int width, int height) override;
|
||||
void CopyToBuffer(const void *video, void *dst, int width, int height) override;
|
||||
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override;
|
||||
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
|
||||
int BufferSize(int width, int height) override;
|
||||
void PaletteAnimate(const Palette &palette) override;
|
||||
Blitter::PaletteAnimation UsePaletteAnimation() override;
|
||||
int GetBytesPerPixel() override { return 1; }
|
||||
};
|
||||
|
||||
#endif /* BLITTER_8BPP_BASE_HPP */
|
||||
|
||||
@@ -167,7 +167,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloca
|
||||
uint trans = 0;
|
||||
uint pixels = 0;
|
||||
uint last_colour = 0;
|
||||
byte *count_dst = NULL;
|
||||
byte *count_dst = nullptr;
|
||||
|
||||
/* Store the scaled image */
|
||||
const SpriteLoader::CommonPixel *src = &sprite[i].data[y * sprite[i].width];
|
||||
@@ -176,11 +176,11 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloca
|
||||
uint colour = src++->m;
|
||||
|
||||
if (last_colour == 0 || colour == 0 || pixels == 255) {
|
||||
if (count_dst != NULL) {
|
||||
if (count_dst != nullptr) {
|
||||
/* Write how many non-transparent bytes we get */
|
||||
*count_dst = pixels;
|
||||
pixels = 0;
|
||||
count_dst = NULL;
|
||||
count_dst = nullptr;
|
||||
}
|
||||
/* As long as we find transparency bytes, keep counting */
|
||||
if (colour == 0 && trans != 255) {
|
||||
@@ -206,7 +206,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloca
|
||||
}
|
||||
}
|
||||
|
||||
if (count_dst != NULL) *count_dst = pixels;
|
||||
if (count_dst != nullptr) *count_dst = pixels;
|
||||
|
||||
/* Write line-ending */
|
||||
*dst = 0; dst++;
|
||||
|
||||
@@ -24,17 +24,17 @@ public:
|
||||
byte data[]; ///< Data, all zoomlevels.
|
||||
};
|
||||
|
||||
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
|
||||
/* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
|
||||
|
||||
/* virtual */ const char *GetName() { return "8bpp-optimized"; }
|
||||
const char *GetName() override { return "8bpp-optimized"; }
|
||||
};
|
||||
|
||||
/** Factory for the 8bpp blitter optimised for speed. */
|
||||
class FBlitter_8bppOptimized : public BlitterFactory {
|
||||
public:
|
||||
FBlitter_8bppOptimized() : BlitterFactory("8bpp-optimized", "8bpp Optimized Blitter (compression + all-ZoomLevel cache)") {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_8bppOptimized(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_8bppOptimized(); }
|
||||
};
|
||||
|
||||
#endif /* BLITTER_8BPP_OPTIMIZED_HPP */
|
||||
|
||||
@@ -18,17 +18,17 @@
|
||||
/** Most trivial 8bpp blitter. */
|
||||
class Blitter_8bppSimple FINAL : public Blitter_8bppBase {
|
||||
public:
|
||||
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
|
||||
/* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
|
||||
|
||||
/* virtual */ const char *GetName() { return "8bpp-simple"; }
|
||||
const char *GetName() override { return "8bpp-simple"; }
|
||||
};
|
||||
|
||||
/** Factory for the most trivial 8bpp blitter. */
|
||||
class FBlitter_8bppSimple : public BlitterFactory {
|
||||
public:
|
||||
FBlitter_8bppSimple() : BlitterFactory("8bpp-simple", "8bpp Simple Blitter (relative slow, but never wrong)") {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_8bppSimple(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_8bppSimple(); }
|
||||
};
|
||||
|
||||
#endif /* BLITTER_8BPP_SIMPLE_HPP */
|
||||
|
||||
@@ -48,7 +48,7 @@ private:
|
||||
*/
|
||||
static Blitter **GetActiveBlitter()
|
||||
{
|
||||
static Blitter *s_blitter = NULL;
|
||||
static Blitter *s_blitter = nullptr;
|
||||
return &s_blitter;
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ protected:
|
||||
* @param name The name of the blitter.
|
||||
* @param description A longer description for the blitter.
|
||||
* @param usable Whether the blitter is usable (on the current computer). For example for disabling SSE blitters when the CPU can't handle them.
|
||||
* @pre name != NULL.
|
||||
* @pre description != NULL.
|
||||
* @pre name != nullptr.
|
||||
* @pre description != nullptr.
|
||||
* @pre There is no blitter registered with this name.
|
||||
*/
|
||||
BlitterFactory(const char *name, const char *description, bool usable = true) :
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
static Blitter *SelectBlitter(const char *name)
|
||||
{
|
||||
BlitterFactory *b = GetBlitterFactory(name);
|
||||
if (b == NULL) return NULL;
|
||||
if (b == nullptr) return nullptr;
|
||||
|
||||
Blitter *newb = b->CreateInstance();
|
||||
delete *GetActiveBlitter();
|
||||
@@ -109,7 +109,7 @@ public:
|
||||
/**
|
||||
* Get the blitter factory with the given name.
|
||||
* @param name the blitter factory to select.
|
||||
* @return The blitter factory, or NULL when there isn't one with the wanted name.
|
||||
* @return The blitter factory, or nullptr when there isn't one with the wanted name.
|
||||
*/
|
||||
static BlitterFactory *GetBlitterFactory(const char *name)
|
||||
{
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
}
|
||||
#endif /* defined(WITH_COCOA) */
|
||||
#endif /* defined(DEDICATED) */
|
||||
if (GetBlitters().size() == 0) return NULL;
|
||||
if (GetBlitters().size() == 0) return nullptr;
|
||||
const char *bname = (StrEmpty(name)) ? default_blitter : name;
|
||||
|
||||
Blitters::iterator it = GetBlitters().begin();
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+18
-18
@@ -17,31 +17,31 @@
|
||||
/** Blitter that does nothing. */
|
||||
class Blitter_Null : public Blitter {
|
||||
public:
|
||||
/* virtual */ uint8 GetScreenDepth() { return 0; }
|
||||
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) {};
|
||||
/* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) {};
|
||||
/* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
|
||||
/* virtual */ void *MoveTo(void *video, int x, int y) { return NULL; };
|
||||
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour) {};
|
||||
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour) {};
|
||||
/* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) {};
|
||||
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height) {};
|
||||
/* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height) {};
|
||||
/* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) {};
|
||||
/* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) {};
|
||||
/* virtual */ int BufferSize(int width, int height) { return 0; };
|
||||
/* virtual */ void PaletteAnimate(const Palette &palette) { };
|
||||
/* virtual */ Blitter::PaletteAnimation UsePaletteAnimation() { return Blitter::PALETTE_ANIMATION_NONE; };
|
||||
uint8 GetScreenDepth() override { return 0; }
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override {};
|
||||
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override {};
|
||||
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
|
||||
void *MoveTo(void *video, int x, int y) override { return nullptr; };
|
||||
void SetPixel(void *video, int x, int y, uint8 colour) override {};
|
||||
void DrawRect(void *video, int width, int height, uint8 colour) override {};
|
||||
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override {};
|
||||
void CopyFromBuffer(void *video, const void *src, int width, int height) override {};
|
||||
void CopyToBuffer(const void *video, void *dst, int width, int height) override {};
|
||||
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override {};
|
||||
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override {};
|
||||
int BufferSize(int width, int height) override { return 0; };
|
||||
void PaletteAnimate(const Palette &palette) override { };
|
||||
Blitter::PaletteAnimation UsePaletteAnimation() override { return Blitter::PALETTE_ANIMATION_NONE; };
|
||||
|
||||
/* virtual */ const char *GetName() { return "null"; }
|
||||
/* virtual */ int GetBytesPerPixel() { return 0; }
|
||||
const char *GetName() override { return "null"; }
|
||||
int GetBytesPerPixel() override { return 0; }
|
||||
};
|
||||
|
||||
/** Factory for the blitter that does nothing. */
|
||||
class FBlitter_Null : public BlitterFactory {
|
||||
public:
|
||||
FBlitter_Null() : BlitterFactory("null", "Null Blitter (does nothing)") {}
|
||||
/* virtual */ Blitter *CreateInstance() { return new Blitter_Null(); }
|
||||
Blitter *CreateInstance() override { return new Blitter_Null(); }
|
||||
};
|
||||
|
||||
#endif /* BLITTER_NULL_HPP */
|
||||
|
||||
+3
-3
@@ -319,7 +319,7 @@ static inline bool BmpRead24(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
bool BmpReadHeader(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
{
|
||||
uint32 header_size;
|
||||
assert(info != NULL);
|
||||
assert(info != nullptr);
|
||||
MemSetT(info, 0);
|
||||
|
||||
/* Reading BMP header */
|
||||
@@ -390,7 +390,7 @@ bool BmpReadHeader(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
*/
|
||||
bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
{
|
||||
assert(info != NULL && data != NULL);
|
||||
assert(info != nullptr && data != nullptr);
|
||||
|
||||
data->bitmap = CallocT<byte>(info->width * info->height * ((info->bpp == 24) ? 3 : 1));
|
||||
|
||||
@@ -413,7 +413,7 @@ bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
|
||||
void BmpDestroyData(BmpData *data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data != nullptr);
|
||||
free(data->palette);
|
||||
free(data->bitmap);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "gfx_type.h"
|
||||
|
||||
struct BmpInfo {
|
||||
uint32 offset; ///< offset of bitmap data from .bmp file begining
|
||||
uint32 offset; ///< offset of bitmap data from .bmp file beginning
|
||||
uint32 width; ///< bitmap width
|
||||
uint32 height; ///< bitmap height
|
||||
bool os2_bmp; ///< true if OS/2 1.x or windows 2.x bitmap
|
||||
|
||||
+15
-15
@@ -13,7 +13,7 @@
|
||||
#include "base_media_base.h"
|
||||
#include "blitter/factory.hpp"
|
||||
|
||||
#if defined(ENABLE_NETWORK) && defined(WITH_FREETYPE)
|
||||
#if defined(WITH_FREETYPE)
|
||||
|
||||
#include "core/geometry_func.hpp"
|
||||
#include "fontcache.h"
|
||||
@@ -40,7 +40,7 @@ static const struct NWidgetPart _background_widgets[] = {
|
||||
* Window description for the background window to prevent smearing.
|
||||
*/
|
||||
static WindowDesc _background_desc(
|
||||
WDP_MANUAL, NULL, 0, 0,
|
||||
WDP_MANUAL, nullptr, 0, 0,
|
||||
WC_BOOTSTRAP, WC_NONE,
|
||||
0,
|
||||
_background_widgets, lengthof(_background_widgets)
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
ResizeWindow(this, _screen.width, _screen.height);
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
GfxFillRect(r.left, r.top, r.right, r.bottom, 4, FILLRECT_OPAQUE);
|
||||
GfxFillRect(r.left, r.top, r.right, r.bottom, 0, FILLRECT_CHECKER);
|
||||
@@ -73,7 +73,7 @@ static const NWidgetPart _nested_boostrap_download_status_window_widgets[] = {
|
||||
|
||||
/** Window description for the download window */
|
||||
static WindowDesc _bootstrap_download_status_window_desc(
|
||||
WDP_CENTER, NULL, 0, 0,
|
||||
WDP_CENTER, nullptr, 0, 0,
|
||||
WC_NETWORK_STATUS_WINDOW, WC_NONE,
|
||||
WDF_MODAL,
|
||||
_nested_boostrap_download_status_window_widgets, lengthof(_nested_boostrap_download_status_window_widgets)
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual void OnDownloadComplete(ContentID cid)
|
||||
void OnDownloadComplete(ContentID cid) override
|
||||
{
|
||||
/* We have completed downloading. We can trigger finding the right set now. */
|
||||
BaseGraphics::FindSets();
|
||||
@@ -118,7 +118,7 @@ static const NWidgetPart _bootstrap_query_widgets[] = {
|
||||
|
||||
/** The window description for the query. */
|
||||
static WindowDesc _bootstrap_query_desc(
|
||||
WDP_CENTER, NULL, 0, 0,
|
||||
WDP_CENTER, nullptr, 0, 0,
|
||||
WC_CONFIRM_POPUP_QUERY, WC_NONE,
|
||||
0,
|
||||
_bootstrap_query_widgets, lengthof(_bootstrap_query_widgets)
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
_network_content_client.RemoveCallback(this);
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
/* We cache the button size. This is safe as no reinit can happen here. */
|
||||
if (this->button_size.width == 0) {
|
||||
@@ -165,14 +165,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
if (widget != 0) return;
|
||||
|
||||
DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMETEXT_BOTTOM, STR_MISSING_GRAPHICS_SET_MESSAGE, TC_FROMSTRING, SA_CENTER);
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_BAFD_YES:
|
||||
@@ -189,13 +189,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnConnect(bool success)
|
||||
void OnConnect(bool success) override
|
||||
{
|
||||
/* Once connected, request the metadata. */
|
||||
_network_content_client.RequestContentList(CONTENT_TYPE_BASE_GRAPHICS);
|
||||
}
|
||||
|
||||
virtual void OnReceiveContentInfo(const ContentInfo *ci)
|
||||
void OnReceiveContentInfo(const ContentInfo *ci) override
|
||||
{
|
||||
/* And once the meta data is received, start downloading it. */
|
||||
_network_content_client.Select(ci->id);
|
||||
@@ -204,7 +204,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) */
|
||||
#endif /* defined(WITH_FREETYPE) */
|
||||
|
||||
/**
|
||||
* Handle all procedures for bootstrapping OpenTTD without a base graphics set.
|
||||
@@ -214,13 +214,13 @@ public:
|
||||
*/
|
||||
bool HandleBootstrap()
|
||||
{
|
||||
if (BaseGraphics::GetUsedSet() != NULL) return true;
|
||||
if (BaseGraphics::GetUsedSet() != nullptr) return true;
|
||||
|
||||
/* No user interface, bail out with an error. */
|
||||
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) goto failure;
|
||||
|
||||
/* If there is no network or no freetype, then there is nothing we can do. Go straight to failure. */
|
||||
#if defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(_WIN32) || defined(__APPLE__))
|
||||
#if defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(_WIN32) || defined(__APPLE__))
|
||||
if (!_network_available) goto failure;
|
||||
|
||||
/* First tell the game we're bootstrapping. */
|
||||
@@ -255,7 +255,7 @@ bool HandleBootstrap()
|
||||
if (_exit_game) return false;
|
||||
|
||||
/* Try to probe the graphics. Should work this time. */
|
||||
if (!BaseGraphics::SetSet(NULL)) goto failure;
|
||||
if (!BaseGraphics::SetSet(nullptr)) goto failure;
|
||||
|
||||
/* Finally we can continue heading for the menu. */
|
||||
_game_mode = GM_MENU;
|
||||
|
||||
+50
-34
@@ -13,6 +13,7 @@
|
||||
#include "error.h"
|
||||
#include "command_func.h"
|
||||
#include "rail.h"
|
||||
#include "road.h"
|
||||
#include "strings_func.h"
|
||||
#include "window_func.h"
|
||||
#include "sound_func.h"
|
||||
@@ -94,31 +95,31 @@ private:
|
||||
Scrollbar *vscroll;
|
||||
|
||||
/** Sort the bridges by their index */
|
||||
static int CDECL BridgeIndexSorter(const BuildBridgeData *a, const BuildBridgeData *b)
|
||||
static bool BridgeIndexSorter(const BuildBridgeData &a, const BuildBridgeData &b)
|
||||
{
|
||||
return a->index - b->index;
|
||||
return a.index < b.index;
|
||||
}
|
||||
|
||||
/** Sort the bridges by their price */
|
||||
static int CDECL BridgePriceSorter(const BuildBridgeData *a, const BuildBridgeData *b)
|
||||
static bool BridgePriceSorter(const BuildBridgeData &a, const BuildBridgeData &b)
|
||||
{
|
||||
return a->cost - b->cost;
|
||||
return a.cost < b.cost;
|
||||
}
|
||||
|
||||
/** Sort the bridges by their maximum speed */
|
||||
static int CDECL BridgeSpeedSorter(const BuildBridgeData *a, const BuildBridgeData *b)
|
||||
static bool BridgeSpeedSorter(const BuildBridgeData &a, const BuildBridgeData &b)
|
||||
{
|
||||
return a->spec->speed - b->spec->speed;
|
||||
return a.spec->speed < b.spec->speed;
|
||||
}
|
||||
|
||||
void BuildBridge(uint8 i)
|
||||
{
|
||||
switch ((TransportType)(this->type >> 15)) {
|
||||
case TRANSPORT_RAIL: _last_railbridge_type = this->bridges->Get(i)->index; break;
|
||||
case TRANSPORT_ROAD: _last_roadbridge_type = this->bridges->Get(i)->index; break;
|
||||
case TRANSPORT_RAIL: _last_railbridge_type = this->bridges->at(i).index; break;
|
||||
case TRANSPORT_ROAD: _last_roadbridge_type = this->bridges->at(i).index; break;
|
||||
default: break;
|
||||
}
|
||||
DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->Get(i)->index,
|
||||
DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->at(i).index,
|
||||
CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), CcBuildBridge);
|
||||
}
|
||||
|
||||
@@ -154,7 +155,7 @@ public:
|
||||
this->bridges->NeedResort();
|
||||
this->SortBridgeList();
|
||||
|
||||
this->vscroll->SetCount(bl->Length());
|
||||
this->vscroll->SetCount((uint)bl->size());
|
||||
}
|
||||
|
||||
~BuildBridgeWindow()
|
||||
@@ -164,7 +165,7 @@ public:
|
||||
delete bridges;
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_BBS_DROPDOWN_ORDER: {
|
||||
@@ -187,11 +188,11 @@ public:
|
||||
case WID_BBS_BRIDGE_LIST: {
|
||||
Dimension sprite_dim = {0, 0}; // Biggest bridge sprite dimension
|
||||
Dimension text_dim = {0, 0}; // Biggest text dimension
|
||||
for (int i = 0; i < (int)this->bridges->Length(); i++) {
|
||||
const BridgeSpec *b = this->bridges->Get(i)->spec;
|
||||
for (int i = 0; i < (int)this->bridges->size(); i++) {
|
||||
const BridgeSpec *b = this->bridges->at(i).spec;
|
||||
sprite_dim = maxdim(sprite_dim, GetSpriteSize(b->sprite));
|
||||
|
||||
SetDParam(2, this->bridges->Get(i)->cost);
|
||||
SetDParam(2, this->bridges->at(i).cost);
|
||||
SetDParam(1, b->speed);
|
||||
SetDParam(0, b->material);
|
||||
text_dim = maxdim(text_dim, GetStringBoundingBox(_game_mode == GM_EDITOR ? STR_SELECT_BRIDGE_SCENEDIT_INFO : STR_SELECT_BRIDGE_INFO));
|
||||
@@ -208,7 +209,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
|
||||
Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override
|
||||
{
|
||||
/* Position the window so hopefully the first bridge from the list is under the mouse pointer. */
|
||||
NWidgetBase *list = this->GetWidget<NWidgetBase>(WID_BBS_BRIDGE_LIST);
|
||||
@@ -218,7 +219,7 @@ public:
|
||||
return corner;
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_BBS_DROPDOWN_ORDER:
|
||||
@@ -227,10 +228,10 @@ public:
|
||||
|
||||
case WID_BBS_BRIDGE_LIST: {
|
||||
uint y = r.top;
|
||||
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges->Length(); i++) {
|
||||
const BridgeSpec *b = this->bridges->Get(i)->spec;
|
||||
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges->size(); i++) {
|
||||
const BridgeSpec *b = this->bridges->at(i).spec;
|
||||
|
||||
SetDParam(2, this->bridges->Get(i)->cost);
|
||||
SetDParam(2, this->bridges->at(i).cost);
|
||||
SetDParam(1, b->speed);
|
||||
SetDParam(0, b->material);
|
||||
|
||||
@@ -244,10 +245,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
EventState OnKeyPress(WChar key, uint16 keycode) override
|
||||
{
|
||||
const uint8 i = keycode - '1';
|
||||
if (i < 9 && i < this->bridges->Length()) {
|
||||
if (i < 9 && i < this->bridges->size()) {
|
||||
/* Build the requested bridge */
|
||||
this->BuildBridge(i);
|
||||
delete this;
|
||||
@@ -256,13 +257,13 @@ public:
|
||||
return ES_NOT_HANDLED;
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
default: break;
|
||||
case WID_BBS_BRIDGE_LIST: {
|
||||
uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_BBS_BRIDGE_LIST);
|
||||
if (i < this->bridges->Length()) {
|
||||
if (i < this->bridges->size()) {
|
||||
this->BuildBridge(i);
|
||||
delete this;
|
||||
}
|
||||
@@ -280,7 +281,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnDropdownSelect(int widget, int index)
|
||||
void OnDropdownSelect(int widget, int index) override
|
||||
{
|
||||
if (widget == WID_BBS_DROPDOWN_CRITERIA && this->bridges->SortType() != index) {
|
||||
this->bridges->SetSortType(index);
|
||||
@@ -289,7 +290,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnResize()
|
||||
void OnResize() override
|
||||
{
|
||||
this->vscroll->SetCapacityFromWidget(this, WID_BBS_BRIDGE_LIST);
|
||||
}
|
||||
@@ -393,7 +394,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
|
||||
StringID errmsg = INVALID_STRING_ID;
|
||||
CommandCost ret = DoCommand(end, start, type, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)) | DC_QUERY_COST, CMD_BUILD_BRIDGE);
|
||||
|
||||
GUIBridgeList *bl = NULL;
|
||||
GUIBridgeList *bl = nullptr;
|
||||
if (ret.Failed()) {
|
||||
errmsg = ret.GetErrorMessage();
|
||||
} else {
|
||||
@@ -404,11 +405,25 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
|
||||
|
||||
Money infra_cost = 0;
|
||||
switch (transport_type) {
|
||||
case TRANSPORT_ROAD:
|
||||
infra_cost = (bridge_len + 2) * _price[PR_BUILD_ROAD] * 2;
|
||||
case TRANSPORT_ROAD: {
|
||||
/* In case we add a new road type as well, we must be aware of those costs. */
|
||||
if (IsBridgeTile(start)) infra_cost *= CountBits(GetRoadTypes(start) | (RoadTypes)road_rail_type);
|
||||
RoadType road_rt = INVALID_ROADTYPE;
|
||||
RoadType tram_rt = INVALID_ROADTYPE;
|
||||
if (IsBridgeTile(start)) {
|
||||
road_rt = GetRoadTypeRoad(start);
|
||||
tram_rt = GetRoadTypeTram(start);
|
||||
}
|
||||
if (RoadTypeIsRoad((RoadType)road_rail_type)) {
|
||||
road_rt = (RoadType)road_rail_type;
|
||||
} else {
|
||||
tram_rt = (RoadType)road_rail_type;
|
||||
}
|
||||
|
||||
if (road_rt != INVALID_ROADTYPE) infra_cost += (bridge_len + 2) * 2 * RoadBuildCost(road_rt);
|
||||
if (tram_rt != INVALID_ROADTYPE) infra_cost += (bridge_len + 2) * 2 * RoadBuildCost(tram_rt);
|
||||
|
||||
break;
|
||||
}
|
||||
case TRANSPORT_RAIL: infra_cost = (bridge_len + 2) * RailBuildCost((RailType)road_rail_type); break;
|
||||
default: break;
|
||||
}
|
||||
@@ -417,17 +432,18 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
|
||||
for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) {
|
||||
if (CheckBridgeAvailability(brd_type, bridge_len).Succeeded()) {
|
||||
/* bridge is accepted, add to list */
|
||||
BuildBridgeData *item = bl->Append();
|
||||
item->index = brd_type;
|
||||
item->spec = GetBridgeSpec(brd_type);
|
||||
/*C++17: BuildBridgeData &item = */ bl->emplace_back();
|
||||
BuildBridgeData &item = bl->back();
|
||||
item.index = brd_type;
|
||||
item.spec = GetBridgeSpec(brd_type);
|
||||
/* Add to terraforming & bulldozing costs the cost of the
|
||||
* bridge itself (not computed with DC_QUERY_COST) */
|
||||
item->cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price[PR_BUILD_BRIDGE] * item->spec->price) >> 8) + infra_cost;
|
||||
item.cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price[PR_BUILD_BRIDGE] * item.spec->price) >> 8) + infra_cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bl != NULL && bl->Length() != 0) {
|
||||
if (bl != nullptr && bl->size() != 0) {
|
||||
new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl);
|
||||
} else {
|
||||
delete bl;
|
||||
|
||||
+18
-14
@@ -12,8 +12,10 @@
|
||||
#ifndef BRIDGE_MAP_H
|
||||
#define BRIDGE_MAP_H
|
||||
|
||||
#include "rail_map.h"
|
||||
#include "road_map.h"
|
||||
#include "bridge.h"
|
||||
#include "water_map.h"
|
||||
|
||||
/**
|
||||
* Checks if this is a bridge, instead of a tunnel
|
||||
@@ -123,20 +125,20 @@ static inline void SetBridgeMiddle(TileIndex t, Axis a)
|
||||
* @param bridgetype the type of bridge this bridge ramp belongs to
|
||||
* @param d the direction this ramp must be facing
|
||||
* @param tt the transport type of the bridge
|
||||
* @param rt the road or rail type
|
||||
* @note this function should not be called directly.
|
||||
*/
|
||||
static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, DiagDirection d, TransportType tt, uint rt)
|
||||
static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, DiagDirection d, TransportType tt)
|
||||
{
|
||||
SetTileType(t, MP_TUNNELBRIDGE);
|
||||
SetTileOwner(t, o);
|
||||
SetDockingTile(t, false);
|
||||
_m[t].m2 = 0;
|
||||
_m[t].m3 = 0;
|
||||
_m[t].m4 = 0;
|
||||
_m[t].m4 = INVALID_ROADTYPE;
|
||||
_m[t].m5 = 1 << 7 | tt << 2 | d;
|
||||
SB(_me[t].m6, 2, 4, bridgetype);
|
||||
_me[t].m7 = 0;
|
||||
_me[t].m8 = rt;
|
||||
_me[t].m8 = INVALID_ROADTYPE << 6;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,14 +149,15 @@ static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, D
|
||||
* @param owner_tram the new owner of the tram on the bridge
|
||||
* @param bridgetype the type of bridge this bridge ramp belongs to
|
||||
* @param d the direction this ramp must be facing
|
||||
* @param r the road type of the bridge
|
||||
* @param road_rt the road type of the bridge
|
||||
* @param tram_rt the tram type of the bridge
|
||||
*/
|
||||
static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, Owner owner_road, Owner owner_tram, BridgeType bridgetype, DiagDirection d, RoadTypes r)
|
||||
static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, Owner owner_road, Owner owner_tram, BridgeType bridgetype, DiagDirection d, RoadType road_rt, RoadType tram_rt)
|
||||
{
|
||||
MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD, 0);
|
||||
SetRoadOwner(t, ROADTYPE_ROAD, owner_road);
|
||||
if (owner_tram != OWNER_TOWN) SetRoadOwner(t, ROADTYPE_TRAM, owner_tram);
|
||||
SetRoadTypes(t, r);
|
||||
MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD);
|
||||
SetRoadOwner(t, RTT_ROAD, owner_road);
|
||||
if (owner_tram != OWNER_TOWN) SetRoadOwner(t, RTT_TRAM, owner_tram);
|
||||
SetRoadTypes(t, road_rt, tram_rt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,11 +166,12 @@ static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, Owner owner_road, Ow
|
||||
* @param o the new owner of the bridge ramp
|
||||
* @param bridgetype the type of bridge this bridge ramp belongs to
|
||||
* @param d the direction this ramp must be facing
|
||||
* @param r the rail type of the bridge
|
||||
* @param rt the rail type of the bridge
|
||||
*/
|
||||
static inline void MakeRailBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, DiagDirection d, RailType r)
|
||||
static inline void MakeRailBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, DiagDirection d, RailType rt)
|
||||
{
|
||||
MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL, r);
|
||||
MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL);
|
||||
SetRailType(t, rt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +182,7 @@ static inline void MakeRailBridgeRamp(TileIndex t, Owner o, BridgeType bridgetyp
|
||||
*/
|
||||
static inline void MakeAqueductBridgeRamp(TileIndex t, Owner o, DiagDirection d)
|
||||
{
|
||||
MakeBridgeRamp(t, o, 0, d, TRANSPORT_WATER, 0);
|
||||
MakeBridgeRamp(t, o, 0, d, TRANSPORT_WATER);
|
||||
}
|
||||
|
||||
#endif /* BRIDGE_MAP_H */
|
||||
|
||||
+387
-245
File diff suppressed because it is too large
Load Diff
+1
-2
@@ -145,12 +145,11 @@ public:
|
||||
|
||||
|
||||
/** Types of cargo source and destination */
|
||||
enum SourceType {
|
||||
enum SourceType : byte {
|
||||
ST_INDUSTRY, ///< Source/destination is an industry
|
||||
ST_TOWN, ///< Source/destination is a town
|
||||
ST_HEADQUARTERS, ///< Source/destination are company headquarters
|
||||
};
|
||||
typedef SimpleTinyEnumT<SourceType, byte> SourceTypeByte; ///< The SourceType packed into a byte for savegame purposes.
|
||||
|
||||
typedef uint16 SourceID; ///< Contains either industry ID, town ID or company ID (or INVALID_SOURCE)
|
||||
static const SourceID INVALID_SOURCE = 0xFFFF; ///< Invalid/unknown index of source
|
||||
|
||||
+8
-8
@@ -121,7 +121,7 @@ bool CargoDelivery::operator()(CargoPacket *cp)
|
||||
bool CargoLoad::operator()(CargoPacket *cp)
|
||||
{
|
||||
CargoPacket *cp_new = this->Preprocess(cp);
|
||||
if (cp_new == NULL) return false;
|
||||
if (cp_new == nullptr) return false;
|
||||
cp_new->SetLoadPlace(this->load_place);
|
||||
this->source->RemoveFromCache(cp_new, cp_new->Count());
|
||||
this->destination->Append(cp_new, VehicleCargoList::MTA_KEEP);
|
||||
@@ -136,7 +136,7 @@ bool CargoLoad::operator()(CargoPacket *cp)
|
||||
bool CargoReservation::operator()(CargoPacket *cp)
|
||||
{
|
||||
CargoPacket *cp_new = this->Preprocess(cp);
|
||||
if (cp_new == NULL) return false;
|
||||
if (cp_new == nullptr) return false;
|
||||
cp_new->SetLoadPlace(this->load_place);
|
||||
this->source->reserved_count += cp_new->Count();
|
||||
this->source->RemoveFromCache(cp_new, cp_new->Count());
|
||||
@@ -152,7 +152,7 @@ bool CargoReservation::operator()(CargoPacket *cp)
|
||||
bool CargoReturn::operator()(CargoPacket *cp)
|
||||
{
|
||||
CargoPacket *cp_new = this->Preprocess(cp);
|
||||
if (cp_new == NULL) cp_new = cp;
|
||||
if (cp_new == nullptr) cp_new = cp;
|
||||
assert(cp_new->Count() <= this->destination->reserved_count);
|
||||
this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_LOAD, cp_new->Count());
|
||||
this->destination->reserved_count -= cp_new->Count();
|
||||
@@ -162,13 +162,13 @@ bool CargoReturn::operator()(CargoPacket *cp)
|
||||
|
||||
/**
|
||||
* Transfers some cargo from a vehicle to a station.
|
||||
* @param cp Packet to be transfered.
|
||||
* @param cp Packet to be transferred.
|
||||
* @return True if the packet was completely reserved, false if part of it was.
|
||||
*/
|
||||
bool CargoTransfer::operator()(CargoPacket *cp)
|
||||
{
|
||||
CargoPacket *cp_new = this->Preprocess(cp);
|
||||
if (cp_new == NULL) return false;
|
||||
if (cp_new == nullptr) return false;
|
||||
this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count());
|
||||
/* No transfer credits here as they were already granted during Stage(). */
|
||||
this->destination->Append(cp_new, cp_new->NextStation());
|
||||
@@ -183,7 +183,7 @@ bool CargoTransfer::operator()(CargoPacket *cp)
|
||||
bool CargoShift::operator()(CargoPacket *cp)
|
||||
{
|
||||
CargoPacket *cp_new = this->Preprocess(cp);
|
||||
if (cp_new == NULL) cp_new = cp;
|
||||
if (cp_new == nullptr) cp_new = cp;
|
||||
this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_KEEP, cp_new->Count());
|
||||
this->destination->Append(cp_new, VehicleCargoList::MTA_KEEP);
|
||||
return cp_new == cp;
|
||||
@@ -197,7 +197,7 @@ bool CargoShift::operator()(CargoPacket *cp)
|
||||
bool StationCargoReroute::operator()(CargoPacket *cp)
|
||||
{
|
||||
CargoPacket *cp_new = this->Preprocess(cp);
|
||||
if (cp_new == NULL) cp_new = cp;
|
||||
if (cp_new == nullptr) cp_new = cp;
|
||||
StationID next = this->ge->GetVia(cp_new->SourceStation(), this->avoid, this->avoid2);
|
||||
assert(next != this->avoid && next != this->avoid2);
|
||||
if (this->source != this->destination) {
|
||||
@@ -220,7 +220,7 @@ bool StationCargoReroute::operator()(CargoPacket *cp)
|
||||
bool VehicleCargoReroute::operator()(CargoPacket *cp)
|
||||
{
|
||||
CargoPacket *cp_new = this->Preprocess(cp);
|
||||
if (cp_new == NULL) cp_new = cp;
|
||||
if (cp_new == nullptr) cp_new = cp;
|
||||
if (cp_new->NextStation() == this->avoid || cp_new->NextStation() == this->avoid2) {
|
||||
cp->SetNextStation(this->ge->GetVia(cp_new->SourceStation(), this->avoid, this->avoid2));
|
||||
}
|
||||
|
||||
@@ -151,9 +151,9 @@ void AddCargoDelivery(CargoID cargo_type, CompanyID company, uint32 amount, Sour
|
||||
if (iter != _cargo_deliveries.end()) iter->second += amount;
|
||||
|
||||
/* Industry delivery. */
|
||||
for (const Industry * const *ip = st->industries_near.Begin(); ip != st->industries_near.End(); ip++) {
|
||||
if ((*ip)->index != dest) continue;
|
||||
CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, (*ip)->index);
|
||||
for (Industry *ind : st->industries_near) {
|
||||
if (ind->index != dest) continue;
|
||||
CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, ind->index);
|
||||
CargoMonitorMap::iterator iter = _cargo_deliveries.find(num);
|
||||
if (iter != _cargo_deliveries.end()) iter->second += amount;
|
||||
}
|
||||
|
||||
+8
-8
@@ -86,11 +86,11 @@ CargoPacket::CargoPacket(uint16 count, byte days_in_transit, StationID source, T
|
||||
/**
|
||||
* Split this packet in two and return the split off part.
|
||||
* @param new_size Size of the split part.
|
||||
* @return Split off part, or NULL if no packet could be allocated!
|
||||
* @return Split off part, or nullptr if no packet could be allocated!
|
||||
*/
|
||||
CargoPacket *CargoPacket::Split(uint new_size)
|
||||
{
|
||||
if (!CargoPacket::CanAllocateItem()) return NULL;
|
||||
if (!CargoPacket::CanAllocateItem()) return nullptr;
|
||||
|
||||
Money fs = this->FeederShare(new_size);
|
||||
CargoPacket *cp_new = new CargoPacket(new_size, this->days_in_transit, this->source, this->source_xy, this->loaded_at_xy, fs, this->source_type, this->source_id);
|
||||
@@ -248,12 +248,12 @@ template <class Tinst, class Tcont>
|
||||
* @param cp Cargo packet to add.
|
||||
* @param action Either MTA_KEEP if you want to add the packet directly or MTA_LOAD
|
||||
* if you want to reserve it first.
|
||||
* @pre cp != NULL
|
||||
* @pre cp != nullptr
|
||||
* @pre action == MTA_LOAD || (action == MTA_KEEP && this->designation_counts[MTA_LOAD] == 0)
|
||||
*/
|
||||
void VehicleCargoList::Append(CargoPacket *cp, MoveToAction action)
|
||||
{
|
||||
assert(cp != NULL);
|
||||
assert(cp != nullptr);
|
||||
assert(action == MTA_LOAD ||
|
||||
(action == MTA_KEEP && this->action_counts[MTA_LOAD] == 0));
|
||||
this->AddToMeta(cp, action);
|
||||
@@ -395,7 +395,7 @@ void VehicleCargoList::AgeCargo()
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets loaded_at_xy to the current station for all cargo to be transfered.
|
||||
* Sets loaded_at_xy to the current station for all cargo to be transferred.
|
||||
* This is done when stopping or skipping while the vehicle is unloading. In
|
||||
* that case the vehicle will get part of its transfer credits early and it may
|
||||
* get more transfer credits than it's entitled to.
|
||||
@@ -689,11 +689,11 @@ uint VehicleCargoList::Reroute(uint max_move, VehicleCargoList *dest, StationID
|
||||
* @note Do not use the cargo packet anymore after it has been appended to this CargoList!
|
||||
* @param next the next hop
|
||||
* @param cp the cargo packet to add
|
||||
* @pre cp != NULL
|
||||
* @pre cp != nullptr
|
||||
*/
|
||||
void StationCargoList::Append(CargoPacket *cp, StationID next)
|
||||
{
|
||||
assert(cp != NULL);
|
||||
assert(cp != nullptr);
|
||||
this->AddToCache(cp);
|
||||
|
||||
StationCargoPacketMap::List &list = this->packets[next];
|
||||
@@ -776,7 +776,7 @@ uint StationCargoList::Truncate(uint max_move, StationCargoAmountMap *cargo_per_
|
||||
uint prev_count = this->count;
|
||||
uint moved = 0;
|
||||
uint loop = 0;
|
||||
bool do_count = cargo_per_source != NULL;
|
||||
bool do_count = cargo_per_source != nullptr;
|
||||
while (max_move > moved) {
|
||||
for (Iterator it(this->packets.begin()); it != this->packets.end();) {
|
||||
CargoPacket *cp = *it;
|
||||
|
||||
+9
-9
@@ -43,13 +43,13 @@ typedef uint32 TileOrStationID;
|
||||
*/
|
||||
struct CargoPacket : CargoPacketPool::PoolItem<&_cargopacket_pool> {
|
||||
private:
|
||||
Money feeder_share; ///< Value of feeder pickup to be paid for on delivery of cargo.
|
||||
uint16 count; ///< The amount of cargo in this packet.
|
||||
byte days_in_transit; ///< Amount of days this packet has been in transit.
|
||||
SourceTypeByte source_type; ///< Type of \c source_id.
|
||||
SourceID source_id; ///< Index of source, INVALID_SOURCE if unknown/invalid.
|
||||
StationID source; ///< The station where the cargo came from first.
|
||||
TileIndex source_xy; ///< The origin of the cargo (first station in feeder chain).
|
||||
Money feeder_share; ///< Value of feeder pickup to be paid for on delivery of cargo.
|
||||
uint16 count; ///< The amount of cargo in this packet.
|
||||
byte days_in_transit; ///< Amount of days this packet has been in transit.
|
||||
SourceType source_type; ///< Type of \c source_id.
|
||||
SourceID source_id; ///< Index of source, INVALID_SOURCE if unknown/invalid.
|
||||
StationID source; ///< The station where the cargo came from first.
|
||||
TileIndex source_xy; ///< The origin of the cargo (first station in feeder chain).
|
||||
union {
|
||||
TileOrStationID loaded_at_xy; ///< Location where this cargo has been loaded into the vehicle.
|
||||
TileOrStationID next_station; ///< Station where the cargo wants to go next.
|
||||
@@ -286,7 +286,7 @@ protected:
|
||||
typedef CargoList<VehicleCargoList, CargoPacketList> Parent;
|
||||
|
||||
Money feeder_share; ///< Cache for the feeder share.
|
||||
uint action_counts[NUM_MOVE_TO_ACTION]; ///< Counts of cargo to be transfered, delivered, kept and loaded.
|
||||
uint action_counts[NUM_MOVE_TO_ACTION]; ///< Counts of cargo to be transferred, delivered, kept and loaded.
|
||||
|
||||
template<class Taction>
|
||||
void ShiftCargo(Taction action);
|
||||
@@ -549,7 +549,7 @@ public:
|
||||
|
||||
uint Reserve(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next);
|
||||
uint Load(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next);
|
||||
uint Truncate(uint max_move = UINT_MAX, StationCargoAmountMap *cargo_per_source = NULL);
|
||||
uint Truncate(uint max_move = UINT_MAX, StationCargoAmountMap *cargo_per_source = nullptr);
|
||||
uint Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge);
|
||||
|
||||
/**
|
||||
|
||||
+15
-17
@@ -14,7 +14,7 @@
|
||||
#include "newgrf_cargo.h"
|
||||
#include "string_func.h"
|
||||
#include "strings_func.h"
|
||||
#include "core/sort_func.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
#include "table/sprites.h"
|
||||
#include "table/strings.h"
|
||||
@@ -132,56 +132,54 @@ SpriteID CargoSpec::GetCargoIcon() const
|
||||
return sprite;
|
||||
}
|
||||
|
||||
const CargoSpec *_sorted_cargo_specs[NUM_CARGO]; ///< Cargo specifications sorted alphabetically by name.
|
||||
uint8 _sorted_cargo_specs_size; ///< Number of cargo specifications stored at the _sorted_cargo_specs array (including special cargoes).
|
||||
uint8 _sorted_standard_cargo_specs_size; ///< Number of standard cargo specifications stored at the _sorted_cargo_specs array.
|
||||
std::vector<const CargoSpec *> _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name.
|
||||
uint8 _sorted_standard_cargo_specs_size; ///< Number of standard cargo specifications stored in the _sorted_cargo_specs array.
|
||||
|
||||
|
||||
/** Sort cargo specifications by their name. */
|
||||
static int CDECL CargoSpecNameSorter(const CargoSpec * const *a, const CargoSpec * const *b)
|
||||
static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b)
|
||||
{
|
||||
static char a_name[64];
|
||||
static char b_name[64];
|
||||
|
||||
GetString(a_name, (*a)->name, lastof(a_name));
|
||||
GetString(b_name, (*b)->name, lastof(b_name));
|
||||
GetString(a_name, a->name, lastof(a_name));
|
||||
GetString(b_name, b->name, lastof(b_name));
|
||||
|
||||
int res = strnatcmp(a_name, b_name); // Sort by name (natural sorting).
|
||||
|
||||
/* If the names are equal, sort by cargo bitnum. */
|
||||
return (res != 0) ? res : ((*a)->bitnum - (*b)->bitnum);
|
||||
return (res != 0) ? res < 0 : (a->bitnum < b->bitnum);
|
||||
}
|
||||
|
||||
/** Sort cargo specifications by their cargo class. */
|
||||
static int CDECL CargoSpecClassSorter(const CargoSpec * const *a, const CargoSpec * const *b)
|
||||
static bool CargoSpecClassSorter(const CargoSpec * const &a, const CargoSpec * const &b)
|
||||
{
|
||||
int res = ((*b)->classes & CC_PASSENGERS) - ((*a)->classes & CC_PASSENGERS);
|
||||
int res = (b->classes & CC_PASSENGERS) - (a->classes & CC_PASSENGERS);
|
||||
if (res == 0) {
|
||||
res = ((*b)->classes & CC_MAIL) - ((*a)->classes & CC_MAIL);
|
||||
res = (b->classes & CC_MAIL) - (a->classes & CC_MAIL);
|
||||
if (res == 0) {
|
||||
res = ((*a)->classes & CC_SPECIAL) - ((*b)->classes & CC_SPECIAL);
|
||||
res = (a->classes & CC_SPECIAL) - (b->classes & CC_SPECIAL);
|
||||
if (res == 0) {
|
||||
return CargoSpecNameSorter(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return res < 0;
|
||||
}
|
||||
|
||||
/** Initialize the list of sorted cargo specifications. */
|
||||
void InitializeSortedCargoSpecs()
|
||||
{
|
||||
_sorted_cargo_specs_size = 0;
|
||||
_sorted_cargo_specs.clear();
|
||||
const CargoSpec *cargo;
|
||||
/* Add each cargo spec to the list. */
|
||||
FOR_ALL_CARGOSPECS(cargo) {
|
||||
_sorted_cargo_specs[_sorted_cargo_specs_size] = cargo;
|
||||
_sorted_cargo_specs_size++;
|
||||
_sorted_cargo_specs.push_back(cargo);
|
||||
}
|
||||
|
||||
/* Sort cargo specifications by cargo class and name. */
|
||||
QSortT(_sorted_cargo_specs, _sorted_cargo_specs_size, &CargoSpecClassSorter);
|
||||
std::sort(_sorted_cargo_specs.begin(), _sorted_cargo_specs.end(), &CargoSpecClassSorter);
|
||||
|
||||
_standard_cargo_mask = 0;
|
||||
|
||||
|
||||
+4
-4
@@ -17,6 +17,7 @@
|
||||
#include "gfx_type.h"
|
||||
#include "strings_type.h"
|
||||
#include "landscape_type.h"
|
||||
#include <vector>
|
||||
|
||||
/** Globally unique label of a cargo type. */
|
||||
typedef uint32 CargoLabel;
|
||||
@@ -137,8 +138,7 @@ CargoID GetCargoIDByLabel(CargoLabel cl);
|
||||
CargoID GetCargoIDByBitnum(uint8 bitnum);
|
||||
|
||||
void InitializeSortedCargoSpecs();
|
||||
extern const CargoSpec *_sorted_cargo_specs[NUM_CARGO];
|
||||
extern uint8 _sorted_cargo_specs_size;
|
||||
extern std::vector<const CargoSpec *> _sorted_cargo_specs;
|
||||
extern uint8 _sorted_standard_cargo_specs_size;
|
||||
|
||||
/**
|
||||
@@ -152,7 +152,7 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc)
|
||||
return (CargoSpec::Get(c)->classes & cc) != 0;
|
||||
}
|
||||
|
||||
#define FOR_ALL_CARGOSPECS_FROM(var, start) for (size_t cargospec_index = start; var = NULL, cargospec_index < CargoSpec::GetArraySize(); cargospec_index++) \
|
||||
#define FOR_ALL_CARGOSPECS_FROM(var, start) for (size_t cargospec_index = start; var = nullptr, cargospec_index < CargoSpec::GetArraySize(); cargospec_index++) \
|
||||
if ((var = CargoSpec::Get(cargospec_index))->IsValid())
|
||||
#define FOR_ALL_CARGOSPECS(var) FOR_ALL_CARGOSPECS_FROM(var, 0)
|
||||
|
||||
@@ -163,7 +163,7 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc)
|
||||
* @param var Reference getting the cargospec.
|
||||
* @see CargoSpec
|
||||
*/
|
||||
#define FOR_ALL_SORTED_CARGOSPECS(var) for (uint8 index = 0; index < _sorted_cargo_specs_size && (var = _sorted_cargo_specs[index], true) ; index++)
|
||||
#define FOR_ALL_SORTED_CARGOSPECS(var) for (uint8 index = 0; index < _sorted_cargo_specs.size() && (var = _sorted_cargo_specs[index], true) ; index++)
|
||||
|
||||
/**
|
||||
* Loop header for iterating over 'real' cargoes, sorted by name. Phony cargoes like regearing cargoes are skipped.
|
||||
|
||||
+10
-10
@@ -186,9 +186,9 @@ struct CheatEntry {
|
||||
static const CheatEntry _cheats_ui[] = {
|
||||
{SLE_INT32, STR_CHEAT_MONEY, &_money_cheat_amount, &_cheats.money.been_used, &ClickMoneyCheat },
|
||||
{SLE_UINT8, STR_CHEAT_CHANGE_COMPANY, &_local_company, &_cheats.switch_company.been_used, &ClickChangeCompanyCheat },
|
||||
{SLE_BOOL, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, NULL },
|
||||
{SLE_BOOL, STR_CHEAT_CROSSINGTUNNELS, &_cheats.crossing_tunnels.value, &_cheats.crossing_tunnels.been_used, NULL },
|
||||
{SLE_BOOL, STR_CHEAT_NO_JETCRASH, &_cheats.no_jetcrash.value, &_cheats.no_jetcrash.been_used, NULL },
|
||||
{SLE_BOOL, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, nullptr },
|
||||
{SLE_BOOL, STR_CHEAT_CROSSINGTUNNELS, &_cheats.crossing_tunnels.value, &_cheats.crossing_tunnels.been_used, nullptr },
|
||||
{SLE_BOOL, STR_CHEAT_NO_JETCRASH, &_cheats.no_jetcrash.value, &_cheats.no_jetcrash.been_used, nullptr },
|
||||
{SLE_BOOL, STR_CHEAT_SETUP_PROD, &_cheats.setup_prod.value, &_cheats.setup_prod.been_used, &ClickSetProdCheat },
|
||||
{SLE_UINT8, STR_CHEAT_EDIT_MAX_HL, &_settings_game.construction.max_heightlevel, &_cheats.edit_max_hl.been_used, &ClickChangeMaxHlCheat },
|
||||
{SLE_INT32, STR_CHEAT_CHANGE_DATE, &_cur_year, &_cheats.change_date.been_used, &ClickChangeDateCheat },
|
||||
@@ -221,7 +221,7 @@ struct CheatWindow : Window {
|
||||
this->InitNested();
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
if (widget != WID_C_PANEL) return;
|
||||
|
||||
@@ -283,7 +283,7 @@ struct CheatWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
if (widget != WID_C_PANEL) return;
|
||||
|
||||
@@ -330,7 +330,7 @@ struct CheatWindow : Window {
|
||||
size->height = this->header_height + WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_BOTTOM + this->line_height * lengthof(_cheats_ui);
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_C_PANEL);
|
||||
uint btn = (pt.y - wid->pos_y - WD_FRAMERECT_TOP - this->header_height) / this->line_height;
|
||||
@@ -365,7 +365,7 @@ struct CheatWindow : Window {
|
||||
switch (ce->type) {
|
||||
case SLE_BOOL:
|
||||
value ^= 1;
|
||||
if (ce->proc != NULL) ce->proc(value, 0);
|
||||
if (ce->proc != nullptr) ce->proc(value, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -384,16 +384,16 @@ struct CheatWindow : Window {
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
virtual void OnTimeout()
|
||||
void OnTimeout() override
|
||||
{
|
||||
this->clicked = 0;
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
virtual void OnQueryTextFinished(char *str)
|
||||
void OnQueryTextFinished(char *str) override
|
||||
{
|
||||
/* Was 'cancel' pressed or nothing entered? */
|
||||
if (str == NULL || StrEmpty(str)) return;
|
||||
if (str == nullptr || StrEmpty(str)) return;
|
||||
|
||||
const CheatEntry *ce = &_cheats_ui[clicked_widget];
|
||||
int oldvalue = (int32)ReadValue(ce->variable, ce->type);
|
||||
|
||||
+5
-5
@@ -389,15 +389,15 @@ extern const TileTypeProcs _tile_type_clear_procs = {
|
||||
DrawTile_Clear, ///< draw_tile_proc
|
||||
GetSlopePixelZ_Clear, ///< get_slope_z_proc
|
||||
ClearTile_Clear, ///< clear_tile_proc
|
||||
NULL, ///< add_accepted_cargo_proc
|
||||
nullptr, ///< add_accepted_cargo_proc
|
||||
GetTileDesc_Clear, ///< get_tile_desc_proc
|
||||
GetTileTrackStatus_Clear, ///< get_tile_track_status_proc
|
||||
NULL, ///< click_tile_proc
|
||||
NULL, ///< animate_tile_proc
|
||||
nullptr, ///< click_tile_proc
|
||||
nullptr, ///< animate_tile_proc
|
||||
TileLoop_Clear, ///< tile_loop_proc
|
||||
ChangeTileOwner_Clear, ///< change_tile_owner_proc
|
||||
NULL, ///< add_produced_cargo_proc
|
||||
NULL, ///< vehicle_enter_tile_proc
|
||||
nullptr, ///< add_produced_cargo_proc
|
||||
nullptr, ///< vehicle_enter_tile_proc
|
||||
GetFoundation_Clear, ///< get_foundation_proc
|
||||
TerraformTile_Clear, ///< terraform_tile_proc
|
||||
};
|
||||
|
||||
+18
-21
@@ -68,6 +68,8 @@ CommandProc CmdBuildRoad;
|
||||
|
||||
CommandProc CmdBuildRoadDepot;
|
||||
|
||||
CommandProc CmdConvertRoad;
|
||||
|
||||
CommandProc CmdBuildAirport;
|
||||
|
||||
CommandProc CmdBuildDock;
|
||||
@@ -214,7 +216,7 @@ static const Command _command_proc_table[] = {
|
||||
DEF_CMD(CmdRemoveRailroadTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_RAILROAD_TRACK
|
||||
DEF_CMD(CmdBuildSingleRail, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SINGLE_RAIL
|
||||
DEF_CMD(CmdRemoveSingleRail, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SINGLE_RAIL
|
||||
DEF_CMD(CmdLandscapeClear, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_LANDSCAPE_CLEAR
|
||||
DEF_CMD(CmdLandscapeClear, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_LANDSCAPE_CLEAR
|
||||
DEF_CMD(CmdBuildBridge, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_BRIDGE
|
||||
DEF_CMD(CmdBuildRailStation, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_RAIL_STATION
|
||||
DEF_CMD(CmdBuildTrainDepot, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_TRAIN_DEPOT
|
||||
@@ -235,6 +237,7 @@ static const Command _command_proc_table[] = {
|
||||
DEF_CMD(CmdRemoveLongRoad, CMD_NO_TEST | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_LONG_ROAD; towns may disallow removing road bits (as they are connected) in test, but in exec they're removed and thus removing is allowed.
|
||||
DEF_CMD(CmdBuildRoad, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD
|
||||
DEF_CMD(CmdBuildRoadDepot, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD_DEPOT
|
||||
DEF_CMD(CmdConvertRoad, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_CONVERT_ROAD
|
||||
|
||||
DEF_CMD(CmdBuildAirport, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_AIRPORT
|
||||
DEF_CMD(CmdBuildDock, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_DOCK
|
||||
@@ -283,7 +286,7 @@ static const Command _command_proc_table[] = {
|
||||
|
||||
DEF_CMD(CmdTurnRoadVeh, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_TURN_ROADVEH
|
||||
|
||||
DEF_CMD(CmdPause, CMD_SERVER, CMDT_SERVER_SETTING ), // CMD_PAUSE
|
||||
DEF_CMD(CmdPause, CMD_SERVER | CMD_NO_EST, CMDT_SERVER_SETTING ), // CMD_PAUSE
|
||||
|
||||
DEF_CMD(CmdBuyShareInCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_BUY_SHARE_IN_COMPANY
|
||||
DEF_CMD(CmdSellShareInCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_SELL_SHARE_IN_COMPANY
|
||||
@@ -307,7 +310,7 @@ static const Command _command_proc_table[] = {
|
||||
DEF_CMD(CmdChangeBankBalance, CMD_DEITY, CMDT_MONEY_MANAGEMENT ), // CMD_CHANGE_BANK_BALANCE
|
||||
DEF_CMD(CmdBuildCanal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_CANAL
|
||||
DEF_CMD(CmdCreateSubsidy, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_SUBSIDY
|
||||
DEF_CMD(CmdCompanyCtrl, CMD_SPECTATOR | CMD_CLIENT_ID, CMDT_SERVER_SETTING ), // CMD_COMPANY_CTRL
|
||||
DEF_CMD(CmdCompanyCtrl, CMD_SPECTATOR | CMD_CLIENT_ID | CMD_NO_EST, CMDT_SERVER_SETTING ), // CMD_COMPANY_CTRL
|
||||
DEF_CMD(CmdCustomNewsItem, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_CUSTOM_NEWS_ITEM
|
||||
DEF_CMD(CmdCreateGoal, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_GOAL
|
||||
DEF_CMD(CmdRemoveGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_REMOVE_GOAL
|
||||
@@ -361,7 +364,7 @@ static const Command _command_proc_table[] = {
|
||||
};
|
||||
|
||||
/*!
|
||||
* This function range-checks a cmd, and checks if the cmd is not NULL
|
||||
* This function range-checks a cmd, and checks if the cmd is not nullptr
|
||||
*
|
||||
* @param cmd The integer value of a command
|
||||
* @return true if the command is valid (and got a CommandProc function)
|
||||
@@ -370,7 +373,7 @@ bool IsValidCommand(uint32 cmd)
|
||||
{
|
||||
cmd &= CMD_ID_MASK;
|
||||
|
||||
return cmd < lengthof(_command_proc_table) && _command_proc_table[cmd].proc != NULL;
|
||||
return cmd < lengthof(_command_proc_table) && _command_proc_table[cmd].proc != nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -469,7 +472,7 @@ CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags,
|
||||
|
||||
/* only execute the test call if it's toplevel, or we're not execing. */
|
||||
if (_docommand_recursive == 1 || !(flags & DC_EXEC) ) {
|
||||
if (_docommand_recursive == 1) _cleared_object_areas.Clear();
|
||||
if (_docommand_recursive == 1) _cleared_object_areas.clear();
|
||||
SetTownRatingTestMode(true);
|
||||
res = proc(tile, flags & ~DC_EXEC, p1, p2, text);
|
||||
SetTownRatingTestMode(false);
|
||||
@@ -492,7 +495,7 @@ CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags,
|
||||
|
||||
/* Execute the command here. All cost-relevant functions set the expenses type
|
||||
* themselves to the cost object at some point */
|
||||
if (_docommand_recursive == 1) _cleared_object_areas.Clear();
|
||||
if (_docommand_recursive == 1) _cleared_object_areas.clear();
|
||||
res = proc(tile, flags, p1, p2, text);
|
||||
if (res.Failed()) {
|
||||
error:
|
||||
@@ -551,14 +554,14 @@ bool DoCommandP(const CommandContainer *container, bool my_cmd)
|
||||
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd)
|
||||
{
|
||||
/* Cost estimation is generally only done when the
|
||||
* local user presses shift while doing somthing.
|
||||
* local user presses shift while doing something.
|
||||
* However, in case of incoming network commands,
|
||||
* map generation or the pause button we do want
|
||||
* to execute. */
|
||||
bool estimate_only = _shift_pressed && IsLocalCompany() &&
|
||||
!_generating_world &&
|
||||
!(cmd & CMD_NETWORK_COMMAND) &&
|
||||
(cmd & CMD_ID_MASK) != CMD_PAUSE;
|
||||
!(GetCommandFlags(cmd) & CMD_NO_EST);
|
||||
|
||||
/* We're only sending the command, so don't do
|
||||
* fancy things for 'success'. */
|
||||
@@ -573,10 +576,8 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
/* Only set p2 when the command does not come from the network. */
|
||||
if (!(cmd & CMD_NETWORK_COMMAND) && GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = CLIENT_ID_SERVER;
|
||||
#endif
|
||||
|
||||
CommandCost res = DoCommandPInternal(tile, p1, p2, cmd, callback, text, my_cmd, estimate_only);
|
||||
if (res.Failed()) {
|
||||
@@ -596,7 +597,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac
|
||||
ShowCostOrIncomeAnimation(x, y, GetSlopePixelZ(x, y), res.GetCost());
|
||||
}
|
||||
|
||||
if (!estimate_only && !only_sending && callback != NULL) {
|
||||
if (!estimate_only && !only_sending && callback != nullptr) {
|
||||
callback(res, tile, p1, p2, cmd);
|
||||
}
|
||||
|
||||
@@ -639,17 +640,15 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
|
||||
CommandProc *proc = _command_proc_table[cmd_id].proc;
|
||||
/* Shouldn't happen, but you never know when someone adds
|
||||
* NULLs to the _command_proc_table. */
|
||||
assert(proc != NULL);
|
||||
assert(proc != nullptr);
|
||||
|
||||
/* Command flags are used internally */
|
||||
CommandFlags cmd_flags = GetCommandFlags(cmd);
|
||||
/* Flags get send to the DoCommand */
|
||||
DoCommandFlag flags = CommandFlagsToDCFlags(cmd_flags);
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
/* Make sure p2 is properly set to a ClientID. */
|
||||
assert(!(cmd_flags & CMD_CLIENT_ID) || p2 != 0);
|
||||
#endif
|
||||
|
||||
/* Do not even think about executing out-of-bounds tile-commands */
|
||||
if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (cmd_flags & CMD_ALL_TILES) == 0))) return_dcpi(CMD_ERROR);
|
||||
@@ -664,13 +663,13 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
|
||||
return_dcpi(CMD_ERROR);
|
||||
}
|
||||
|
||||
Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, FILE_LINE);
|
||||
if (exec_as_spectator) cur_company.Change(COMPANY_SPECTATOR);
|
||||
|
||||
bool test_and_exec_can_differ = (cmd_flags & CMD_NO_TEST) != 0;
|
||||
|
||||
/* Test the command. */
|
||||
_cleared_object_areas.Clear();
|
||||
_cleared_object_areas.clear();
|
||||
SetTownRatingTestMode(true);
|
||||
BasePersistentStorageArray::SwitchMode(PSM_ENTER_TESTMODE);
|
||||
CommandCost res = proc(tile, flags, p1, p2, text);
|
||||
@@ -696,7 +695,6 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
|
||||
return_dcpi(res);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
/*
|
||||
* If we are in network, and the command is not from the network
|
||||
* send it to the command-queue and abort execution
|
||||
@@ -711,12 +709,11 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
|
||||
* reset the storages as we've not executed the command. */
|
||||
return_dcpi(CommandCost());
|
||||
}
|
||||
#endif /* ENABLE_NETWORK */
|
||||
DEBUG(desync, 1, "cmd: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
|
||||
|
||||
/* Actually try and execute the command. If no cost-type is given
|
||||
* use the construction one */
|
||||
_cleared_object_areas.Clear();
|
||||
_cleared_object_areas.clear();
|
||||
BasePersistentStorageArray::SwitchMode(PSM_ENTER_COMMAND);
|
||||
CommandCost res2 = proc(tile, flags | DC_EXEC, p1, p2, text);
|
||||
BasePersistentStorageArray::SwitchMode(PSM_LEAVE_COMMAND);
|
||||
@@ -756,7 +753,7 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
|
||||
/* update last build coordinate of company. */
|
||||
if (tile != 0) {
|
||||
Company *c = Company::GetIfValid(_current_company);
|
||||
if (c != NULL) c->last_build_coordinate = tile;
|
||||
if (c != nullptr) c->last_build_coordinate = tile;
|
||||
}
|
||||
|
||||
SubtractMoneyFromCompany(res2);
|
||||
|
||||
+2
-4
@@ -34,17 +34,15 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID);
|
||||
*/
|
||||
#define return_cmd_error(errcode) return CommandCost(errcode);
|
||||
|
||||
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text = NULL);
|
||||
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text = nullptr);
|
||||
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags);
|
||||
|
||||
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = NULL, const char *text = NULL, bool my_cmd = true);
|
||||
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = nullptr, const char *text = nullptr, bool my_cmd = true);
|
||||
bool DoCommandP(const CommandContainer *container, bool my_cmd = true);
|
||||
|
||||
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only);
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company);
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
extern Money _additional_cash_required;
|
||||
|
||||
|
||||
+6
-4
@@ -36,25 +36,25 @@ public:
|
||||
/**
|
||||
* Creates a command cost return with no cost and no error
|
||||
*/
|
||||
CommandCost() : expense_type(INVALID_EXPENSES), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_grffile(NULL), textref_stack_size(0) {}
|
||||
CommandCost() : expense_type(INVALID_EXPENSES), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_grffile(nullptr), textref_stack_size(0) {}
|
||||
|
||||
/**
|
||||
* Creates a command return value the is failed with the given message
|
||||
*/
|
||||
explicit CommandCost(StringID msg) : expense_type(INVALID_EXPENSES), cost(0), message(msg), success(false), textref_stack_grffile(NULL), textref_stack_size(0) {}
|
||||
explicit CommandCost(StringID msg) : expense_type(INVALID_EXPENSES), cost(0), message(msg), success(false), textref_stack_grffile(nullptr), textref_stack_size(0) {}
|
||||
|
||||
/**
|
||||
* Creates a command cost with given expense type and start cost of 0
|
||||
* @param ex_t the expense type
|
||||
*/
|
||||
explicit CommandCost(ExpensesType ex_t) : expense_type(ex_t), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_grffile(NULL), textref_stack_size(0) {}
|
||||
explicit CommandCost(ExpensesType ex_t) : expense_type(ex_t), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_grffile(nullptr), textref_stack_size(0) {}
|
||||
|
||||
/**
|
||||
* Creates a command return value with the given start cost and expense type
|
||||
* @param ex_t the expense type
|
||||
* @param cst the initial cost of this command
|
||||
*/
|
||||
CommandCost(ExpensesType ex_t, const Money &cst) : expense_type(ex_t), cost(cst), message(INVALID_STRING_ID), success(true), textref_stack_grffile(NULL), textref_stack_size(0) {}
|
||||
CommandCost(ExpensesType ex_t, const Money &cst) : expense_type(ex_t), cost(cst), message(INVALID_STRING_ID), success(true), textref_stack_grffile(nullptr), textref_stack_size(0) {}
|
||||
|
||||
|
||||
/**
|
||||
@@ -202,6 +202,7 @@ enum Commands {
|
||||
CMD_REMOVE_LONG_ROAD, ///< remove a complete road (not a "half" one)
|
||||
CMD_BUILD_ROAD, ///< build a "half" road
|
||||
CMD_BUILD_ROAD_DEPOT, ///< build a road depot
|
||||
CMD_CONVERT_ROAD, ///< convert a road type
|
||||
|
||||
CMD_BUILD_AIRPORT, ///< build an airport
|
||||
|
||||
@@ -395,6 +396,7 @@ enum CommandFlags {
|
||||
CMD_CLIENT_ID = 0x080, ///< set p2 with the ClientID of the sending client.
|
||||
CMD_DEITY = 0x100, ///< the command may be executed by COMPANY_DEITY
|
||||
CMD_STR_CTRL = 0x200, ///< the command's string may contain control strings
|
||||
CMD_NO_EST = 0x400, ///< the command is never estimated.
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(CommandFlags)
|
||||
|
||||
|
||||
+7
-4
@@ -43,6 +43,9 @@ struct CompanyInfrastructure {
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) total += this->rail[rt];
|
||||
return total;
|
||||
}
|
||||
|
||||
uint32 GetRoadTotal() const;
|
||||
uint32 GetTramTotal() const;
|
||||
};
|
||||
|
||||
typedef Pool<Company, CompanyID, 1, MAX_COMPANIES> CompanyPool;
|
||||
@@ -72,7 +75,7 @@ struct CompanyProperties {
|
||||
TileIndex location_of_HQ; ///< Northern tile of HQ; #INVALID_TILE when there is none.
|
||||
TileIndex last_build_coordinate; ///< Coordinate of the last build thing by this company.
|
||||
|
||||
OwnerByte share_owners[4]; ///< Owners of the 4 shares of the company. #INVALID_OWNER if nobody has bought them yet.
|
||||
Owner share_owners[4]; ///< Owners of the 4 shares of the company. #INVALID_OWNER if nobody has bought them yet.
|
||||
|
||||
Year inaugurated_year; ///< Year of starting the company.
|
||||
|
||||
@@ -98,7 +101,7 @@ struct CompanyProperties {
|
||||
|
||||
// TODO: Change some of these member variables to use relevant INVALID_xxx constants
|
||||
CompanyProperties()
|
||||
: name_2(0), name_1(0), name(NULL), president_name_1(0), president_name_2(0), president_name(NULL),
|
||||
: name_2(0), name_1(0), name(nullptr), president_name_1(0), president_name_2(0), president_name(nullptr),
|
||||
face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0),
|
||||
location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0),
|
||||
months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0),
|
||||
@@ -137,7 +140,7 @@ struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {
|
||||
static inline bool IsValidAiID(size_t index)
|
||||
{
|
||||
const Company *c = Company::GetIfValid(index);
|
||||
return c != NULL && c->is_ai;
|
||||
return c != nullptr && c->is_ai;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,7 +152,7 @@ struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {
|
||||
static inline bool IsValidHumanID(size_t index)
|
||||
{
|
||||
const Company *c = Company::GetIfValid(index);
|
||||
return c != NULL && !c->is_ai;
|
||||
return c != nullptr && !c->is_ai;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+66
-42
@@ -43,8 +43,8 @@
|
||||
|
||||
void ClearEnginesHiddenFlagOfCompany(CompanyID cid);
|
||||
|
||||
CompanyByte _local_company; ///< Company controlled by the human player at this client. Can also be #COMPANY_SPECTATOR.
|
||||
CompanyByte _current_company; ///< Company currently doing an action.
|
||||
CompanyID _local_company; ///< Company controlled by the human player at this client. Can also be #COMPANY_SPECTATOR.
|
||||
CompanyID _current_company; ///< Company currently doing an action.
|
||||
Colours _company_colours[MAX_COMPANIES]; ///< NOSAVE: can be determined from company structs.
|
||||
CompanyManagerFace _company_manager_face; ///< for company manager face storage in openttd.cfg
|
||||
uint _next_competitor_start; ///< the number of ticks before the next AI is started
|
||||
@@ -107,10 +107,8 @@ void SetLocalCompany(CompanyID new_company)
|
||||
/* If actually changing to another company, several windows need closing */
|
||||
bool switching_company = _local_company != new_company;
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
/* Delete the chat window, if you were team chatting. */
|
||||
if (switching_company) InvalidateWindowData(WC_SEND_NETWORK_MSG, DESTTYPE_TEAM, _local_company);
|
||||
#endif
|
||||
|
||||
assert(IsLocalCompany());
|
||||
|
||||
@@ -198,7 +196,7 @@ bool CheckCompanyHasMoney(CommandCost &cost)
|
||||
{
|
||||
if (cost.GetCost() > 0) {
|
||||
const Company *c = Company::GetIfValid(_current_company);
|
||||
if (c != NULL && cost.GetCost() > c->money) {
|
||||
if (c != nullptr && cost.GetCost() > c->money) {
|
||||
SetDParam(0, cost.GetCost());
|
||||
cost.MakeError(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY);
|
||||
return false;
|
||||
@@ -244,7 +242,7 @@ static void SubtractMoneyFromAnyCompany(Company *c, CommandCost cost)
|
||||
void SubtractMoneyFromCompany(CommandCost cost)
|
||||
{
|
||||
Company *c = Company::GetIfValid(_current_company);
|
||||
if (c != NULL) SubtractMoneyFromAnyCompany(c, cost);
|
||||
if (c != nullptr) SubtractMoneyFromAnyCompany(c, cost);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,7 +356,7 @@ static void GenerateCompanyName(Company *c)
|
||||
|
||||
StringID str;
|
||||
uint32 strp;
|
||||
if (t->name == NULL && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) {
|
||||
if (t->name == nullptr && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) {
|
||||
str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_COMPANY_NAME_START;
|
||||
strp = t->townnameparts;
|
||||
|
||||
@@ -544,7 +542,7 @@ void ResetCompanyLivery(Company *c)
|
||||
*/
|
||||
Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
|
||||
{
|
||||
if (!Company::CanAllocateItem()) return NULL;
|
||||
if (!Company::CanAllocateItem()) return nullptr;
|
||||
|
||||
/* we have to generate colour before this company is valid */
|
||||
Colours colour = GenerateCompanyColour();
|
||||
@@ -553,7 +551,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
|
||||
if (company == INVALID_COMPANY) {
|
||||
c = new Company(STR_SV_UNNAMED, is_ai);
|
||||
} else {
|
||||
if (Company::IsValidID(company)) return NULL;
|
||||
if (Company::IsValidID(company)) return nullptr;
|
||||
c = new (company) Company(STR_SV_UNNAMED, is_ai);
|
||||
}
|
||||
|
||||
@@ -567,7 +565,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
|
||||
c->share_owners[0] = c->share_owners[1] = c->share_owners[2] = c->share_owners[3] = INVALID_OWNER;
|
||||
|
||||
c->avail_railtypes = GetCompanyRailtypes(c->index);
|
||||
c->avail_roadtypes = GetCompanyRoadtypes(c->index);
|
||||
c->avail_roadtypes = GetCompanyRoadTypes(c->index);
|
||||
c->inaugurated_year = _cur_year;
|
||||
RandomCompanyManagerFaceBits(c->face, (GenderEthnicity)Random(), false, false); // create a random company manager face
|
||||
|
||||
@@ -598,11 +596,9 @@ void StartupCompanies()
|
||||
}
|
||||
|
||||
/** Start a new competitor company if possible. */
|
||||
static void MaybeStartNewCompany()
|
||||
static bool MaybeStartNewCompany()
|
||||
{
|
||||
#ifdef ENABLE_NETWORK
|
||||
if (_networking && Company::GetNumItems() >= _settings_client.network.max_companies) return;
|
||||
#endif /* ENABLE_NETWORK */
|
||||
if (_networking && Company::GetNumItems() >= _settings_client.network.max_companies) return false;
|
||||
|
||||
Company *c;
|
||||
|
||||
@@ -615,8 +611,10 @@ static void MaybeStartNewCompany()
|
||||
if (n < (uint)_settings_game.difficulty.max_no_competitors) {
|
||||
/* Send a command to all clients to start up a new AI.
|
||||
* Works fine for Multiplayer and Singleplayer */
|
||||
DoCommandP(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, CMD_COMPANY_CTRL);
|
||||
return DoCommandP(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, CMD_COMPANY_CTRL);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Initialize the pool of companies. */
|
||||
@@ -675,7 +673,7 @@ static void HandleBankruptcyTakeover(Company *c)
|
||||
/* Did we ask everyone for bankruptcy? If so, bail out. */
|
||||
if (c->bankrupt_asked == MAX_UVALUE(CompanyMask)) return;
|
||||
|
||||
Company *c2, *best = NULL;
|
||||
Company *c2, *best = nullptr;
|
||||
int32 best_performance = -1;
|
||||
|
||||
/* Ask the company with the highest performance history first */
|
||||
@@ -711,17 +709,25 @@ void OnTick_Companies()
|
||||
if (_game_mode == GM_EDITOR) return;
|
||||
|
||||
Company *c = Company::GetIfValid(_cur_company_tick_index);
|
||||
if (c != NULL) {
|
||||
if (c != nullptr) {
|
||||
if (c->name_1 != 0) GenerateCompanyName(c);
|
||||
if (c->bankrupt_asked != 0) HandleBankruptcyTakeover(c);
|
||||
}
|
||||
|
||||
if (_next_competitor_start == 0) {
|
||||
_next_competitor_start = AI::GetStartNextTime() * DAY_TICKS;
|
||||
/* AI::GetStartNextTime() can return 0. */
|
||||
_next_competitor_start = max(1, AI::GetStartNextTime() * DAY_TICKS);
|
||||
}
|
||||
|
||||
if (AI::CanStartNew() && _game_mode != GM_MENU && --_next_competitor_start == 0) {
|
||||
MaybeStartNewCompany();
|
||||
if (_game_mode != GM_MENU && AI::CanStartNew() && --_next_competitor_start == 0) {
|
||||
/* Allow multiple AIs to possibly start in the same tick. */
|
||||
do {
|
||||
if (!MaybeStartNewCompany()) break;
|
||||
|
||||
/* In networking mode, we can only send a command to start but it
|
||||
* didn't execute yet, so we cannot loop. */
|
||||
if (_networking) break;
|
||||
} while (AI::GetStartNextTime() == 0);
|
||||
}
|
||||
|
||||
_cur_company_tick_index = (_cur_company_tick_index + 1) % MAX_COMPANIES;
|
||||
@@ -756,14 +762,14 @@ void CompaniesYearlyLoop()
|
||||
/**
|
||||
* Fill the CompanyNewsInformation struct with the required data.
|
||||
* @param c the current company.
|
||||
* @param other the other company (use \c NULL if not relevant).
|
||||
* @param other the other company (use \c nullptr if not relevant).
|
||||
*/
|
||||
void CompanyNewsInformation::FillData(const Company *c, const Company *other)
|
||||
{
|
||||
SetDParam(0, c->index);
|
||||
GetString(this->company_name, STR_COMPANY_NAME, lastof(this->company_name));
|
||||
|
||||
if (other == NULL) {
|
||||
if (other == nullptr) {
|
||||
*this->other_company_name = '\0';
|
||||
} else {
|
||||
SetDParam(0, other->index);
|
||||
@@ -785,9 +791,7 @@ void CompanyNewsInformation::FillData(const Company *c, const Company *other)
|
||||
*/
|
||||
void CompanyAdminUpdate(const Company *company)
|
||||
{
|
||||
#ifdef ENABLE_NETWORK
|
||||
if (_network_server) NetworkAdminCompanyUpdate(company);
|
||||
#endif /* ENABLE_NETWORK */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -797,9 +801,7 @@ void CompanyAdminUpdate(const Company *company)
|
||||
*/
|
||||
void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason)
|
||||
{
|
||||
#ifdef ENABLE_NETWORK
|
||||
if (_network_server) NetworkAdminCompanyRemove(company_id, (AdminCompanyRemoveReason)reason);
|
||||
#endif /* ENABLE_NETWORK */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -824,7 +826,6 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
/* This command is only executed in a multiplayer game */
|
||||
if (!_networking) return CMD_ERROR;
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
/* Has the network client a correct ClientIndex? */
|
||||
if (!(flags & DC_EXEC)) return CommandCost();
|
||||
|
||||
@@ -834,8 +835,8 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
/* When replaying the client ID is not a valid client; there
|
||||
* are actually no clients at all. However, the company has to
|
||||
* be created, otherwise we cannot rerun the game properly.
|
||||
* So only allow a NULL client info in that case. */
|
||||
if (ci == NULL) return CommandCost();
|
||||
* So only allow a nullptr client info in that case. */
|
||||
if (ci == nullptr) return CommandCost();
|
||||
#endif /* NOT DEBUG_DUMP_COMMANDS */
|
||||
|
||||
/* Delete multiplayer progress bar */
|
||||
@@ -844,7 +845,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
Company *c = DoStartupNewCompany(false);
|
||||
|
||||
/* A new company could not be created, revert to being a spectator */
|
||||
if (c == NULL) {
|
||||
if (c == nullptr) {
|
||||
if (_network_server) {
|
||||
ci->client_playas = COMPANY_SPECTATOR;
|
||||
NetworkUpdateClientInfo(ci->client_id);
|
||||
@@ -868,7 +869,6 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
}
|
||||
|
||||
NetworkServerNewCompany(c, ci);
|
||||
#endif /* ENABLE_NETWORK */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -877,9 +877,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
|
||||
if (company_id != INVALID_COMPANY && (company_id >= MAX_COMPANIES || Company::IsValidID(company_id))) return CMD_ERROR;
|
||||
Company *c = DoStartupNewCompany(true, company_id);
|
||||
#ifdef ENABLE_NETWORK
|
||||
if (c != NULL) NetworkServerNewCompany(c, NULL);
|
||||
#endif /* ENABLE_NETWORK */
|
||||
if (c != nullptr) NetworkServerNewCompany(c, nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -888,7 +886,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
if (reason >= CRR_END) return CMD_ERROR;
|
||||
|
||||
Company *c = Company::GetIfValid(company_id);
|
||||
if (c == NULL) return CMD_ERROR;
|
||||
if (c == nullptr) return CMD_ERROR;
|
||||
|
||||
if (!(flags & DC_EXEC)) return CommandCost();
|
||||
|
||||
@@ -1060,7 +1058,7 @@ static bool IsUniqueCompanyName(const char *name)
|
||||
const Company *c;
|
||||
|
||||
FOR_ALL_COMPANIES(c) {
|
||||
if (c->name != NULL && strcmp(c->name, name) == 0) return false;
|
||||
if (c->name != nullptr && strcmp(c->name, name) == 0) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1087,7 +1085,7 @@ CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
||||
if (flags & DC_EXEC) {
|
||||
Company *c = Company::Get(_current_company);
|
||||
free(c->name);
|
||||
c->name = reset ? NULL : stredup(text);
|
||||
c->name = reset ? nullptr : stredup(text);
|
||||
MarkWholeScreenDirty();
|
||||
CompanyAdminUpdate(c);
|
||||
}
|
||||
@@ -1105,7 +1103,7 @@ static bool IsUniquePresidentName(const char *name)
|
||||
const Company *c;
|
||||
|
||||
FOR_ALL_COMPANIES(c) {
|
||||
if (c->president_name != NULL && strcmp(c->president_name, name) == 0) return false;
|
||||
if (c->president_name != nullptr && strcmp(c->president_name, name) == 0) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1134,11 +1132,11 @@ CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
free(c->president_name);
|
||||
|
||||
if (reset) {
|
||||
c->president_name = NULL;
|
||||
c->president_name = nullptr;
|
||||
} else {
|
||||
c->president_name = stredup(text);
|
||||
|
||||
if (c->name_1 == STR_SV_UNNAMED && c->name == NULL) {
|
||||
if (c->name_1 == STR_SV_UNNAMED && c->name == nullptr) {
|
||||
char buf[80];
|
||||
|
||||
seprintf(buf, lastof(buf), "%s Transport", text);
|
||||
@@ -1155,13 +1153,13 @@ CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
|
||||
/**
|
||||
* Get the service interval for the given company and vehicle type.
|
||||
* @param c The company, or NULL for client-default settings.
|
||||
* @param c The company, or nullptr for client-default settings.
|
||||
* @param type The vehicle type to get the interval for.
|
||||
* @return The service interval.
|
||||
*/
|
||||
int CompanyServiceInterval(const Company *c, VehicleType type)
|
||||
{
|
||||
const VehicleDefaultSettings *vds = (c == NULL) ? &_settings_client.company.vehicle : &c->settings.vehicle;
|
||||
const VehicleDefaultSettings *vds = (c == nullptr) ? &_settings_client.company.vehicle : &c->settings.vehicle;
|
||||
switch (type) {
|
||||
default: NOT_REACHED();
|
||||
case VEH_TRAIN: return vds->servint_trains;
|
||||
@@ -1170,3 +1168,29 @@ int CompanyServiceInterval(const Company *c, VehicleType type)
|
||||
case VEH_SHIP: return vds->servint_ships;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total sum of all owned road bits.
|
||||
* @return Combined total road road bits.
|
||||
*/
|
||||
uint32 CompanyInfrastructure::GetRoadTotal() const
|
||||
{
|
||||
uint32 total = 0;
|
||||
for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
|
||||
if (RoadTypeIsRoad(rt)) total += this->road[rt];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total sum of all owned tram bits.
|
||||
* @return Combined total of tram road bits.
|
||||
*/
|
||||
uint32 CompanyInfrastructure::GetTramTotal() const
|
||||
{
|
||||
uint32 total = 0;
|
||||
for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
|
||||
if (RoadTypeIsTram(rt)) total += this->road[rt];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
+2
-2
@@ -32,8 +32,8 @@ void SubtractMoneyFromCompanyFract(CompanyID company, CommandCost cost);
|
||||
CommandCost CheckOwnership(Owner owner, TileIndex tile = 0);
|
||||
CommandCost CheckTileOwnership(TileIndex tile);
|
||||
|
||||
extern CompanyByte _local_company;
|
||||
extern CompanyByte _current_company;
|
||||
extern CompanyID _local_company;
|
||||
extern CompanyID _current_company;
|
||||
|
||||
extern Colours _company_colours[MAX_COMPANIES];
|
||||
extern CompanyManagerFace _company_manager_face;
|
||||
|
||||
+133
-121
@@ -30,6 +30,7 @@
|
||||
#include "core/geometry_func.hpp"
|
||||
#include "object_type.h"
|
||||
#include "rail.h"
|
||||
#include "road.h"
|
||||
#include "engine_base.h"
|
||||
#include "window_func.h"
|
||||
#include "road_func.h"
|
||||
@@ -284,7 +285,7 @@ struct CompanyFinancesWindow : Window {
|
||||
this->owner = (Owner)this->window_number;
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_CF_CAPTION:
|
||||
@@ -303,7 +304,7 @@ struct CompanyFinancesWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
int type = _settings_client.gui.expenses_layout;
|
||||
switch (widget) {
|
||||
@@ -331,7 +332,7 @@ struct CompanyFinancesWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_CF_EXPS_CATEGORY:
|
||||
@@ -392,7 +393,7 @@ struct CompanyFinancesWindow : Window {
|
||||
this->GetWidget<NWidgetStacked>(WID_CF_SEL_BUTTONS)->SetDisplayedPlane(plane);
|
||||
}
|
||||
|
||||
virtual void OnPaint()
|
||||
void OnPaint() override
|
||||
{
|
||||
if (!this->IsShaded()) {
|
||||
if (!this->small) {
|
||||
@@ -422,7 +423,7 @@ struct CompanyFinancesWindow : Window {
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_CF_TOGGLE_SIZE: // toggle size
|
||||
@@ -451,7 +452,7 @@ struct CompanyFinancesWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnHundredthTick()
|
||||
void OnHundredthTick() override
|
||||
{
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
if (c->money > CompanyFinancesWindow::max_money) {
|
||||
@@ -519,24 +520,22 @@ class DropDownListColourItem : public DropDownListItem {
|
||||
public:
|
||||
DropDownListColourItem(int result, bool masked) : DropDownListItem(result, masked) {}
|
||||
|
||||
virtual ~DropDownListColourItem() {}
|
||||
|
||||
StringID String() const
|
||||
{
|
||||
return this->result >= COLOUR_END ? STR_COLOUR_DEFAULT : _colour_dropdown[this->result];
|
||||
}
|
||||
|
||||
uint Height(uint width) const
|
||||
uint Height(uint width) const override
|
||||
{
|
||||
return max(FONT_HEIGHT_NORMAL, ScaleGUITrad(12) + 2);
|
||||
}
|
||||
|
||||
bool Selectable() const
|
||||
bool Selectable() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
|
||||
void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const override
|
||||
{
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
int height = bottom - top;
|
||||
@@ -564,14 +563,14 @@ private:
|
||||
uint rows;
|
||||
uint line_height;
|
||||
GUIGroupList groups;
|
||||
SmallVector<int, 32> indents;
|
||||
std::vector<int> indents;
|
||||
Scrollbar *vscroll;
|
||||
|
||||
void ShowColourDropDownMenu(uint32 widget)
|
||||
{
|
||||
uint32 used_colours = 0;
|
||||
const Company *c;
|
||||
const Livery *livery, *default_livery = NULL;
|
||||
const Livery *livery, *default_livery = nullptr;
|
||||
bool primary = widget == WID_SCL_PRI_COL_DROPDOWN;
|
||||
byte default_col;
|
||||
|
||||
@@ -604,49 +603,49 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
DropDownList *list = new DropDownList();
|
||||
if (default_livery != NULL) {
|
||||
DropDownList list;
|
||||
if (default_livery != nullptr) {
|
||||
/* Add COLOUR_END to put the colour out of range, but also allow us to show what the default is */
|
||||
default_col = (primary ? default_livery->colour1 : default_livery->colour2) + COLOUR_END;
|
||||
*list->Append() = new DropDownListColourItem(default_col, false);
|
||||
list.emplace_back(new DropDownListColourItem(default_col, false));
|
||||
}
|
||||
for (uint i = 0; i < lengthof(_colour_dropdown); i++) {
|
||||
*list->Append() = new DropDownListColourItem(i, HasBit(used_colours, i));
|
||||
list.emplace_back(new DropDownListColourItem(i, HasBit(used_colours, i)));
|
||||
}
|
||||
|
||||
byte sel = (default_livery == NULL || HasBit(livery->in_use, primary ? 0 : 1)) ? (primary ? livery->colour1 : livery->colour2) : default_col;
|
||||
ShowDropDownList(this, list, sel, widget);
|
||||
byte sel = (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) ? (primary ? livery->colour1 : livery->colour2) : default_col;
|
||||
ShowDropDownList(this, std::move(list), sel, widget);
|
||||
}
|
||||
|
||||
static int CDECL GroupNameSorter(const Group * const *a, const Group * const *b)
|
||||
static bool GroupNameSorter(const Group * const &a, const Group * const &b)
|
||||
{
|
||||
static const Group *last_group[2] = { NULL, NULL };
|
||||
static const Group *last_group[2] = { nullptr, nullptr };
|
||||
static char last_name[2][64] = { "", "" };
|
||||
|
||||
if (*a != last_group[0]) {
|
||||
last_group[0] = *a;
|
||||
SetDParam(0, (*a)->index);
|
||||
if (a != last_group[0]) {
|
||||
last_group[0] = a;
|
||||
SetDParam(0, a->index);
|
||||
GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
|
||||
}
|
||||
|
||||
if (*b != last_group[1]) {
|
||||
last_group[1] = *b;
|
||||
SetDParam(0, (*b)->index);
|
||||
if (b != last_group[1]) {
|
||||
last_group[1] = b;
|
||||
SetDParam(0, b->index);
|
||||
GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
|
||||
}
|
||||
|
||||
int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
if (r == 0) return (*a)->index - (*b)->index;
|
||||
return r;
|
||||
if (r == 0) return a->index < b->index;
|
||||
return r < 0;
|
||||
}
|
||||
|
||||
void AddChildren(GUIGroupList *source, GroupID parent, int indent)
|
||||
{
|
||||
for (const Group **g = source->Begin(); g != source->End(); g++) {
|
||||
if ((*g)->parent != parent) continue;
|
||||
*this->groups.Append() = *g;
|
||||
*this->indents.Append() = indent;
|
||||
AddChildren(source, (*g)->index, indent + 1);
|
||||
for (const Group *g : *source) {
|
||||
if (g->parent != parent) continue;
|
||||
this->groups.push_back(g);
|
||||
this->indents.push_back(indent);
|
||||
AddChildren(source, g->index, indent + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,8 +653,8 @@ private:
|
||||
{
|
||||
if (!this->groups.NeedRebuild()) return;
|
||||
|
||||
this->groups.Clear();
|
||||
this->indents.Clear();
|
||||
this->groups.clear();
|
||||
this->indents.clear();
|
||||
|
||||
if (this->livery_class >= LC_GROUP_RAIL) {
|
||||
GUIGroupList list;
|
||||
@@ -664,7 +663,7 @@ private:
|
||||
const Group *g;
|
||||
FOR_ALL_GROUPS(g) {
|
||||
if (g->owner == owner && g->vehicle_type == vtype) {
|
||||
*list.Append() = g;
|
||||
list.push_back(g);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,7 +673,7 @@ private:
|
||||
AddChildren(&list, INVALID_GROUP, 0);
|
||||
}
|
||||
|
||||
this->groups.Compact();
|
||||
this->groups.shrink_to_fit();
|
||||
this->groups.RebuildDone();
|
||||
}
|
||||
|
||||
@@ -688,7 +687,7 @@ private:
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->rows = this->groups.Length();
|
||||
this->rows = (uint)this->groups.size();
|
||||
}
|
||||
|
||||
this->vscroll->SetCount(this->rows);
|
||||
@@ -742,7 +741,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SCL_SPACER_DROPDOWN: {
|
||||
@@ -795,7 +794,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPaint()
|
||||
void OnPaint() override
|
||||
{
|
||||
bool local = (CompanyID)this->window_number == _local_company;
|
||||
|
||||
@@ -809,7 +808,7 @@ public:
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SCL_CAPTION:
|
||||
@@ -849,7 +848,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
if (widget != WID_SCL_MATRIX) return;
|
||||
|
||||
@@ -904,7 +903,7 @@ public:
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->groups.Length());
|
||||
uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)this->groups.size());
|
||||
for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
|
||||
const Group *g = this->groups[i];
|
||||
SetDParam(0, g->index);
|
||||
@@ -913,7 +912,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
/* Livery Class buttons */
|
||||
@@ -944,7 +943,7 @@ public:
|
||||
this->groups.ForceRebuild();
|
||||
this->BuildGroupList((CompanyID)this->window_number);
|
||||
|
||||
if (this->groups.Length() > 0) {
|
||||
if (this->groups.size() > 0) {
|
||||
this->sel = this->groups[0]->index;
|
||||
}
|
||||
}
|
||||
@@ -987,12 +986,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnResize()
|
||||
void OnResize() override
|
||||
{
|
||||
this->vscroll->SetCapacityFromWidget(this, WID_SCL_MATRIX);
|
||||
}
|
||||
|
||||
virtual void OnDropdownSelect(int widget, int index)
|
||||
void OnDropdownSelect(int widget, int index) override
|
||||
{
|
||||
bool local = (CompanyID)this->window_number == _local_company;
|
||||
if (!local) return;
|
||||
@@ -1018,7 +1017,7 @@ public:
|
||||
* @param data Information about the changed data.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (!gui_scope) return;
|
||||
|
||||
@@ -1031,7 +1030,7 @@ public:
|
||||
|
||||
if (!Group::IsValidID(this->sel)) {
|
||||
this->sel = INVALID_GROUP;
|
||||
if (this->groups.Length() > 0) this->sel = this->groups[0]->index;
|
||||
if (this->groups.size() > 0) this->sel = this->groups[0]->index;
|
||||
}
|
||||
|
||||
this->SetDirty();
|
||||
@@ -1102,7 +1101,7 @@ static WindowDesc _select_company_livery_desc(
|
||||
void ShowCompanyLiveryWindow(CompanyID company, GroupID group)
|
||||
{
|
||||
SelectCompanyLiveryWindow *w = (SelectCompanyLiveryWindow *)BringWindowToFrontById(WC_COMPANY_COLOUR, company);
|
||||
if (w == NULL) {
|
||||
if (w == nullptr) {
|
||||
new SelectCompanyLiveryWindow(&_select_company_livery_desc, company, group);
|
||||
} else if (group != INVALID_GROUP) {
|
||||
w->SetSelectedGroup(company, group);
|
||||
@@ -1370,7 +1369,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnInit()
|
||||
void OnInit() override
|
||||
{
|
||||
/* Size of the boolean yes/no button. */
|
||||
Dimension yesno_dim = maxdim(GetStringBoundingBox(STR_FACE_YES), GetStringBoundingBox(STR_FACE_NO));
|
||||
@@ -1393,7 +1392,7 @@ public:
|
||||
this->number_dim = number_dim;
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SCMF_FACE: {
|
||||
@@ -1452,7 +1451,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPaint()
|
||||
void OnPaint() override
|
||||
{
|
||||
/* lower the non-selected gender button */
|
||||
this->SetWidgetsLoweredState(!this->is_female, WID_SCMF_MALE, WID_SCMF_MALE2, WIDGET_LIST_END);
|
||||
@@ -1513,7 +1512,7 @@ public:
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT:
|
||||
@@ -1602,7 +1601,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
/* Toggle size, advanced/simple face selection */
|
||||
@@ -1711,12 +1710,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnQueryTextFinished(char *str)
|
||||
void OnQueryTextFinished(char *str) override
|
||||
{
|
||||
if (str == NULL) return;
|
||||
if (str == nullptr) return;
|
||||
/* Set a new company manager face number */
|
||||
if (!StrEmpty(str)) {
|
||||
this->face = strtoul(str, NULL, 10);
|
||||
this->face = strtoul(str, nullptr, 10);
|
||||
ScaleAllCompanyManagerFaceBits(this->face);
|
||||
ShowErrorMessage(STR_FACE_FACECODE_SET, INVALID_STRING_ID, WL_INFO);
|
||||
this->UpdateData();
|
||||
@@ -1784,6 +1783,10 @@ static const NWidgetPart _nested_company_infrastructure_widgets[] = {
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_ROAD_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_ROAD_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TRAM_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TRAM_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_WATER_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_WATER_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
|
||||
@@ -1821,7 +1824,7 @@ struct CompanyInfrastructureWindow : Window
|
||||
void UpdateRailRoadTypes()
|
||||
{
|
||||
this->railtypes = RAILTYPES_NONE;
|
||||
this->roadtypes = ROADTYPES_ROAD; // Road is always available.
|
||||
this->roadtypes = ROADTYPES_NONE;
|
||||
|
||||
/* Find the used railtypes. */
|
||||
Engine *e;
|
||||
@@ -1834,14 +1837,16 @@ struct CompanyInfrastructureWindow : Window
|
||||
/* Get the date introduced railtypes as well. */
|
||||
this->railtypes = AddDateIntroducedRailTypes(this->railtypes, MAX_DAY);
|
||||
|
||||
/* Tram is only visible when there will be a tram. */
|
||||
/* Find the used roadtypes. */
|
||||
FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
|
||||
if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue;
|
||||
if (!HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue;
|
||||
|
||||
this->roadtypes |= ROADTYPES_TRAM;
|
||||
break;
|
||||
this->roadtypes |= GetRoadTypeInfo(e->u.road.roadtype)->introduces_roadtypes;
|
||||
}
|
||||
|
||||
/* Get the date introduced roadtypes as well. */
|
||||
this->roadtypes = AddDateIntroducedRoadTypes(this->roadtypes, MAX_DAY);
|
||||
this->roadtypes &= ~_roadtypes_hidden_mask;
|
||||
}
|
||||
|
||||
/** Get total infrastructure maintenance cost. */
|
||||
@@ -1856,8 +1861,11 @@ struct CompanyInfrastructureWindow : Window
|
||||
}
|
||||
total += SignalMaintenanceCost(c->infrastructure.signal);
|
||||
|
||||
if (HasBit(this->roadtypes, ROADTYPE_ROAD)) total += RoadMaintenanceCost(ROADTYPE_ROAD, c->infrastructure.road[ROADTYPE_ROAD]);
|
||||
if (HasBit(this->roadtypes, ROADTYPE_TRAM)) total += RoadMaintenanceCost(ROADTYPE_TRAM, c->infrastructure.road[ROADTYPE_TRAM]);
|
||||
uint32 road_total = c->infrastructure.GetRoadTotal();
|
||||
uint32 tram_total = c->infrastructure.GetTramTotal();
|
||||
for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
|
||||
if (HasBit(this->roadtypes, rt)) total += RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total);
|
||||
}
|
||||
|
||||
total += CanalMaintenanceCost(c->infrastructure.water);
|
||||
total += StationMaintenanceCost(c->infrastructure.station);
|
||||
@@ -1866,7 +1874,7 @@ struct CompanyInfrastructureWindow : Window
|
||||
return total;
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_CI_CAPTION:
|
||||
@@ -1875,7 +1883,7 @@ struct CompanyInfrastructureWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
|
||||
@@ -1885,7 +1893,8 @@ struct CompanyInfrastructureWindow : Window
|
||||
|
||||
size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT).width);
|
||||
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) {
|
||||
RailType rt;
|
||||
FOR_ALL_SORTED_RAILTYPES(rt) {
|
||||
if (HasBit(this->railtypes, rt)) {
|
||||
lines++;
|
||||
SetDParam(0, GetRailTypeInfo(rt)->strings.name);
|
||||
@@ -1901,18 +1910,19 @@ struct CompanyInfrastructureWindow : Window
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_CI_ROAD_DESC: {
|
||||
uint lines = 1;
|
||||
case WID_CI_ROAD_DESC:
|
||||
case WID_CI_TRAM_DESC: {
|
||||
uint lines = 0;
|
||||
|
||||
size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT).width);
|
||||
size->width = max(size->width, GetStringBoundingBox(widget == WID_CI_ROAD_DESC ? STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT : STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT).width);
|
||||
|
||||
if (HasBit(this->roadtypes, ROADTYPE_ROAD)) {
|
||||
lines++;
|
||||
size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD).width + WD_FRAMERECT_LEFT);
|
||||
}
|
||||
if (HasBit(this->roadtypes, ROADTYPE_TRAM)) {
|
||||
lines++;
|
||||
size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY).width + WD_FRAMERECT_LEFT);
|
||||
RoadType rt;
|
||||
FOR_ALL_SORTED_ROADTYPES(rt) {
|
||||
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) {
|
||||
lines++;
|
||||
SetDParam(0, GetRoadTypeInfo(rt)->strings.name);
|
||||
size->width = max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WD_FRAMERECT_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
size->height = max(size->height, lines * FONT_HEIGHT_NORMAL);
|
||||
@@ -1932,6 +1942,7 @@ struct CompanyInfrastructureWindow : Window
|
||||
|
||||
case WID_CI_RAIL_COUNT:
|
||||
case WID_CI_ROAD_COUNT:
|
||||
case WID_CI_TRAM_COUNT:
|
||||
case WID_CI_WATER_COUNT:
|
||||
case WID_CI_STATION_COUNT:
|
||||
case WID_CI_TOTAL: {
|
||||
@@ -1945,9 +1956,12 @@ struct CompanyInfrastructureWindow : Window
|
||||
}
|
||||
max_val = max(max_val, c->infrastructure.signal);
|
||||
max_cost = max(max_cost, SignalMaintenanceCost(c->infrastructure.signal));
|
||||
uint32 road_total = c->infrastructure.GetRoadTotal();
|
||||
uint32 tram_total = c->infrastructure.GetTramTotal();
|
||||
for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) {
|
||||
max_val = max(max_val, c->infrastructure.road[rt]);
|
||||
max_cost = max(max_cost, RoadMaintenanceCost(rt, c->infrastructure.road[rt]));
|
||||
max_cost = max(max_cost, RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total));
|
||||
|
||||
}
|
||||
max_val = max(max_val, c->infrastructure.water);
|
||||
max_cost = max(max_cost, CanalMaintenanceCost(c->infrastructure.water));
|
||||
@@ -1998,7 +2012,7 @@ struct CompanyInfrastructureWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
int y = r.top;
|
||||
@@ -2043,26 +2057,32 @@ struct CompanyInfrastructureWindow : Window
|
||||
}
|
||||
|
||||
case WID_CI_ROAD_DESC:
|
||||
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT);
|
||||
case WID_CI_TRAM_DESC: {
|
||||
DrawString(r.left, r.right, y, widget == WID_CI_ROAD_DESC ? STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT : STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT);
|
||||
|
||||
if (this->roadtypes != ROADTYPES_NONE) {
|
||||
if (HasBit(this->roadtypes, ROADTYPE_ROAD)) DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD);
|
||||
if (HasBit(this->roadtypes, ROADTYPE_TRAM)) DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY);
|
||||
} else {
|
||||
/* No valid roadtypes. */
|
||||
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE);
|
||||
/* Draw name of each valid roadtype. */
|
||||
RoadType rt;
|
||||
FOR_ALL_SORTED_ROADTYPES(rt) {
|
||||
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) {
|
||||
SetDParam(0, GetRoadTypeInfo(rt)->strings.name);
|
||||
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_CI_ROAD_COUNT:
|
||||
if (HasBit(this->roadtypes, ROADTYPE_ROAD)) {
|
||||
this->DrawCountLine(r, y, c->infrastructure.road[ROADTYPE_ROAD], RoadMaintenanceCost(ROADTYPE_ROAD, c->infrastructure.road[ROADTYPE_ROAD]));
|
||||
}
|
||||
if (HasBit(this->roadtypes, ROADTYPE_TRAM)) {
|
||||
this->DrawCountLine(r, y, c->infrastructure.road[ROADTYPE_TRAM], RoadMaintenanceCost(ROADTYPE_TRAM, c->infrastructure.road[ROADTYPE_TRAM]));
|
||||
case WID_CI_TRAM_COUNT: {
|
||||
uint32 road_tram_total = widget == WID_CI_ROAD_COUNT ? c->infrastructure.GetRoadTotal() : c->infrastructure.GetTramTotal();
|
||||
RoadType rt;
|
||||
FOR_ALL_SORTED_ROADTYPES(rt) {
|
||||
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_COUNT)) {
|
||||
this->DrawCountLine(r, y, c->infrastructure.road[rt], RoadMaintenanceCost(rt, c->infrastructure.road[rt], road_tram_total));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_CI_WATER_DESC:
|
||||
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT);
|
||||
@@ -2101,7 +2121,7 @@ struct CompanyInfrastructureWindow : Window
|
||||
* @param data Information about the changed data.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (!gui_scope) return;
|
||||
|
||||
@@ -2267,7 +2287,7 @@ struct CompanyWindow : Window
|
||||
this->OnInvalidateData();
|
||||
}
|
||||
|
||||
virtual void OnPaint()
|
||||
void OnPaint() override
|
||||
{
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
bool local = this->window_number == _local_company;
|
||||
@@ -2336,7 +2356,7 @@ struct CompanyWindow : Window
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_C_FACE: {
|
||||
@@ -2389,15 +2409,13 @@ struct CompanyWindow : Window
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
case WID_C_HAS_PASSWORD:
|
||||
*size = maxdim(*size, GetSpriteSize(SPR_LOCK));
|
||||
break;
|
||||
#endif /* ENABLE_NETWORK */
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
switch (widget) {
|
||||
@@ -2500,17 +2518,15 @@ struct CompanyWindow : Window
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
case WID_C_HAS_PASSWORD:
|
||||
if (_networking && NetworkCompanyIsPassworded(c->index)) {
|
||||
DrawSprite(SPR_LOCK, PAL_NONE, r.left, r.top);
|
||||
}
|
||||
break;
|
||||
#endif /* ENABLE_NETWORK */
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_C_CAPTION:
|
||||
@@ -2528,7 +2544,7 @@ struct CompanyWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_C_NEW_FACE: DoSelectCompanyManagerFace(this); break;
|
||||
@@ -2596,7 +2612,6 @@ struct CompanyWindow : Window
|
||||
DoCommandP(0, this->window_number, 0, CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_SELL_25_SHARE_IN));
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
case WID_C_COMPANY_PASSWORD:
|
||||
if (this->window_number == _local_company) ShowNetworkCompanyPasswordWindow(this);
|
||||
break;
|
||||
@@ -2609,24 +2624,23 @@ struct CompanyWindow : Window
|
||||
MarkWholeScreenDirty();
|
||||
} else if (NetworkCompanyIsPassworded(company)) {
|
||||
/* ask for the password */
|
||||
ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION, NETWORK_PASSWORD_LENGTH, this, CS_ALPHANUMERAL, QSF_NONE);
|
||||
ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION, NETWORK_PASSWORD_LENGTH, this, CS_ALPHANUMERAL, QSF_PASSWORD);
|
||||
} else {
|
||||
/* just send the join command */
|
||||
NetworkClientRequestMove(company);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLE_NETWORK */
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnHundredthTick()
|
||||
void OnHundredthTick() override
|
||||
{
|
||||
/* redraw the window every now and then */
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
virtual void OnPlaceObject(Point pt, TileIndex tile)
|
||||
void OnPlaceObject(Point pt, TileIndex tile) override
|
||||
{
|
||||
if (DoCommandP(tile, OBJECT_HQ, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS)) && !_shift_pressed) {
|
||||
ResetObjectToPlace();
|
||||
@@ -2634,31 +2648,29 @@ struct CompanyWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPlaceObjectAbort()
|
||||
void OnPlaceObjectAbort() override
|
||||
{
|
||||
this->RaiseButtons();
|
||||
}
|
||||
|
||||
virtual void OnQueryTextFinished(char *str)
|
||||
void OnQueryTextFinished(char *str) override
|
||||
{
|
||||
if (str == NULL) return;
|
||||
if (str == nullptr) return;
|
||||
|
||||
switch (this->query_widget) {
|
||||
default: NOT_REACHED();
|
||||
|
||||
case WID_C_PRESIDENT_NAME:
|
||||
DoCommandP(0, 0, 0, CMD_RENAME_PRESIDENT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_PRESIDENT), NULL, str);
|
||||
DoCommandP(0, 0, 0, CMD_RENAME_PRESIDENT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_PRESIDENT), nullptr, str);
|
||||
break;
|
||||
|
||||
case WID_C_COMPANY_NAME:
|
||||
DoCommandP(0, 0, 0, CMD_RENAME_COMPANY | CMD_MSG(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME), NULL, str);
|
||||
DoCommandP(0, 0, 0, CMD_RENAME_COMPANY | CMD_MSG(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME), nullptr, str);
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
case WID_C_COMPANY_JOIN:
|
||||
NetworkClientRequestMove((CompanyID)this->window_number, str);
|
||||
break;
|
||||
#endif /* ENABLE_NETWORK */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2668,7 +2680,7 @@ struct CompanyWindow : Window
|
||||
* @param data Information about the changed data.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (this->window_number == _local_company) return;
|
||||
|
||||
@@ -2727,7 +2739,7 @@ struct BuyCompanyWindow : Window {
|
||||
this->InitNested(window_number);
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_BC_FACE:
|
||||
@@ -2743,7 +2755,7 @@ struct BuyCompanyWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_BC_CAPTION:
|
||||
@@ -2753,7 +2765,7 @@ struct BuyCompanyWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_BC_FACE: {
|
||||
@@ -2772,7 +2784,7 @@ struct BuyCompanyWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_BC_NO:
|
||||
@@ -2806,7 +2818,7 @@ static const NWidgetPart _nested_buy_company_widgets[] = {
|
||||
};
|
||||
|
||||
static WindowDesc _buy_company_desc(
|
||||
WDP_AUTO, NULL, 0, 0,
|
||||
WDP_AUTO, nullptr, 0, 0,
|
||||
WC_BUY_COMPANY, WC_NONE,
|
||||
WDF_CONSTRUCTION,
|
||||
_nested_buy_company_widgets, lengthof(_nested_buy_company_widgets)
|
||||
|
||||
+1
-3
@@ -17,7 +17,7 @@
|
||||
/**
|
||||
* Enum for all companies/owners.
|
||||
*/
|
||||
enum Owner {
|
||||
enum Owner : byte {
|
||||
/* All companies below MAX_COMPANIES are playable
|
||||
* companies, above, they are special, computer controlled 'companies' */
|
||||
OWNER_BEGIN = 0x00, ///< First owner
|
||||
@@ -45,10 +45,8 @@ static const uint MAX_HISTORY_QUARTERS = 24; ///< The maximum number
|
||||
|
||||
/** Define basic enum properties */
|
||||
template <> struct EnumPropsT<Owner> : MakeEnumPropsT<Owner, byte, OWNER_BEGIN, OWNER_END, INVALID_OWNER> {};
|
||||
typedef TinyEnumT<Owner> OwnerByte;
|
||||
|
||||
typedef Owner CompanyID;
|
||||
typedef OwnerByte CompanyByte;
|
||||
|
||||
typedef uint16 CompanyMask;
|
||||
|
||||
|
||||
+23
-29
@@ -32,11 +32,9 @@ FILE *_iconsole_output_file;
|
||||
|
||||
void IConsoleInit()
|
||||
{
|
||||
_iconsole_output_file = NULL;
|
||||
#ifdef ENABLE_NETWORK /* Initialize network only variables */
|
||||
_iconsole_output_file = nullptr;
|
||||
_redirect_console_to_client = INVALID_CLIENT_ID;
|
||||
_redirect_console_to_admin = INVALID_ADMIN_ID;
|
||||
#endif
|
||||
|
||||
IConsoleGUIInit();
|
||||
|
||||
@@ -45,14 +43,14 @@ void IConsoleInit()
|
||||
|
||||
static void IConsoleWriteToLogFile(const char *string)
|
||||
{
|
||||
if (_iconsole_output_file != NULL) {
|
||||
if (_iconsole_output_file != nullptr) {
|
||||
/* if there is an console output file ... also print it there */
|
||||
const char *header = GetLogPrefix();
|
||||
if ((strlen(header) != 0 && fwrite(header, strlen(header), 1, _iconsole_output_file) != 1) ||
|
||||
fwrite(string, strlen(string), 1, _iconsole_output_file) != 1 ||
|
||||
fwrite("\n", 1, 1, _iconsole_output_file) != 1) {
|
||||
fclose(_iconsole_output_file);
|
||||
_iconsole_output_file = NULL;
|
||||
_iconsole_output_file = nullptr;
|
||||
IConsolePrintF(CC_DEFAULT, "cannot write to log file");
|
||||
}
|
||||
}
|
||||
@@ -60,10 +58,10 @@ static void IConsoleWriteToLogFile(const char *string)
|
||||
|
||||
bool CloseConsoleLogIfActive()
|
||||
{
|
||||
if (_iconsole_output_file != NULL) {
|
||||
if (_iconsole_output_file != nullptr) {
|
||||
IConsolePrintF(CC_DEFAULT, "file output complete");
|
||||
fclose(_iconsole_output_file);
|
||||
_iconsole_output_file = NULL;
|
||||
_iconsole_output_file = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,7 +88,6 @@ void IConsolePrint(TextColour colour_code, const char *string)
|
||||
assert(IsValidConsoleColour(colour_code));
|
||||
|
||||
char *str;
|
||||
#ifdef ENABLE_NETWORK
|
||||
if (_redirect_console_to_client != INVALID_CLIENT_ID) {
|
||||
/* Redirect the string to the client */
|
||||
NetworkServerSendRcon(_redirect_console_to_client, colour_code, string);
|
||||
@@ -101,7 +98,6 @@ void IConsolePrint(TextColour colour_code, const char *string)
|
||||
NetworkServerSendAdminRcon(_redirect_console_to_admin, colour_code, string);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create a copy of the string, strip if of colours and invalid
|
||||
* characters and (when applicable) assign it to the console buffer */
|
||||
@@ -110,9 +106,7 @@ void IConsolePrint(TextColour colour_code, const char *string)
|
||||
str_validate(str, str + strlen(str));
|
||||
|
||||
if (_network_dedicated) {
|
||||
#ifdef ENABLE_NETWORK
|
||||
NetworkAdminConsole("console", str);
|
||||
#endif /* ENABLE_NETWORK */
|
||||
fprintf(stdout, "%s%s\n", GetLogPrefix(), str);
|
||||
fflush(stdout);
|
||||
IConsoleWriteToLogFile(str);
|
||||
@@ -209,22 +203,22 @@ bool GetArgumentInteger(uint32 *value, const char *arg)
|
||||
template<class T>
|
||||
void IConsoleAddSorted(T **base, T *item_new)
|
||||
{
|
||||
if (*base == NULL) {
|
||||
if (*base == nullptr) {
|
||||
*base = item_new;
|
||||
return;
|
||||
}
|
||||
|
||||
T *item_before = NULL;
|
||||
T *item_before = nullptr;
|
||||
T *item = *base;
|
||||
/* The list is alphabetically sorted, insert the new item at the correct location */
|
||||
while (item != NULL) {
|
||||
while (item != nullptr) {
|
||||
if (strcmp(item->name, item_new->name) > 0) break; // insert here
|
||||
|
||||
item_before = item;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
if (item_before == NULL) {
|
||||
if (item_before == nullptr) {
|
||||
*base = item_new;
|
||||
} else {
|
||||
item_before->next = item_new;
|
||||
@@ -257,7 +251,7 @@ void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *
|
||||
{
|
||||
IConsoleCmd *item_new = MallocT<IConsoleCmd>(1);
|
||||
item_new->name = RemoveUnderscores(stredup(name));
|
||||
item_new->next = NULL;
|
||||
item_new->next = nullptr;
|
||||
item_new->proc = proc;
|
||||
item_new->hook = hook;
|
||||
|
||||
@@ -267,16 +261,16 @@ void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *
|
||||
/**
|
||||
* Find the command pointed to by its string
|
||||
* @param name command to be found
|
||||
* @return return Cmdstruct of the found command, or NULL on failure
|
||||
* @return return Cmdstruct of the found command, or nullptr on failure
|
||||
*/
|
||||
IConsoleCmd *IConsoleCmdGet(const char *name)
|
||||
{
|
||||
IConsoleCmd *item;
|
||||
|
||||
for (item = _iconsole_cmds; item != NULL; item = item->next) {
|
||||
for (item = _iconsole_cmds; item != nullptr; item = item->next) {
|
||||
if (strcmp(item->name, name) == 0) return item;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -286,7 +280,7 @@ IConsoleCmd *IConsoleCmdGet(const char *name)
|
||||
*/
|
||||
void IConsoleAliasRegister(const char *name, const char *cmd)
|
||||
{
|
||||
if (IConsoleAliasGet(name) != NULL) {
|
||||
if (IConsoleAliasGet(name) != nullptr) {
|
||||
IConsoleError("an alias with this name already exists; insertion aborted");
|
||||
return;
|
||||
}
|
||||
@@ -295,7 +289,7 @@ void IConsoleAliasRegister(const char *name, const char *cmd)
|
||||
char *cmd_aliased = stredup(cmd);
|
||||
IConsoleAlias *item_new = MallocT<IConsoleAlias>(1);
|
||||
|
||||
item_new->next = NULL;
|
||||
item_new->next = nullptr;
|
||||
item_new->cmdline = cmd_aliased;
|
||||
item_new->name = new_alias;
|
||||
|
||||
@@ -305,17 +299,17 @@ void IConsoleAliasRegister(const char *name, const char *cmd)
|
||||
/**
|
||||
* Find the alias pointed to by its string
|
||||
* @param name alias to be found
|
||||
* @return return Aliasstruct of the found alias, or NULL on failure
|
||||
* @return return Aliasstruct of the found alias, or nullptr on failure
|
||||
*/
|
||||
IConsoleAlias *IConsoleAliasGet(const char *name)
|
||||
{
|
||||
IConsoleAlias *item;
|
||||
|
||||
for (item = _iconsole_aliases; item != NULL; item = item->next) {
|
||||
for (item = _iconsole_aliases; item != nullptr; item = item->next) {
|
||||
if (strcmp(item->name, name) == 0) return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
/**
|
||||
* An alias is just another name for a command, or for more commands
|
||||
@@ -484,7 +478,7 @@ void IConsoleCmdExec(const char *cmdstr)
|
||||
}
|
||||
}
|
||||
|
||||
for (uint i = 0; i < lengthof(tokens) && tokens[i] != NULL; i++) {
|
||||
for (uint i = 0; i < lengthof(tokens) && tokens[i] != nullptr; i++) {
|
||||
DEBUG(console, 8, "Token %d is: '%s'", i, tokens[i]);
|
||||
}
|
||||
|
||||
@@ -495,12 +489,12 @@ void IConsoleCmdExec(const char *cmdstr)
|
||||
*/
|
||||
RemoveUnderscores(tokens[0]);
|
||||
IConsoleCmd *cmd = IConsoleCmdGet(tokens[0]);
|
||||
if (cmd != NULL) {
|
||||
ConsoleHookResult chr = (cmd->hook == NULL ? CHR_ALLOW : cmd->hook(true));
|
||||
if (cmd != nullptr) {
|
||||
ConsoleHookResult chr = (cmd->hook == nullptr ? CHR_ALLOW : cmd->hook(true));
|
||||
switch (chr) {
|
||||
case CHR_ALLOW:
|
||||
if (!cmd->proc(t_index, tokens)) { // index started with 0
|
||||
cmd->proc(0, NULL); // if command failed, give help
|
||||
cmd->proc(0, nullptr); // if command failed, give help
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -511,7 +505,7 @@ void IConsoleCmdExec(const char *cmdstr)
|
||||
|
||||
t_index--;
|
||||
IConsoleAlias *alias = IConsoleAliasGet(tokens[0]);
|
||||
if (alias != NULL) {
|
||||
if (alias != nullptr) {
|
||||
IConsoleAliasExec(alias, t_index, &tokens[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
+65
-71
@@ -39,6 +39,7 @@
|
||||
#include "engine_base.h"
|
||||
#include "game/game.hpp"
|
||||
#include "table/strings.h"
|
||||
#include <time.h>
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
@@ -86,8 +87,6 @@ static ConsoleFileList _console_file_list; ///< File storage cache for the conso
|
||||
* command hooks
|
||||
****************/
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
|
||||
/**
|
||||
* Check network availability and inform in console about failure of detection.
|
||||
* @return Network availability.
|
||||
@@ -159,10 +158,6 @@ DEF_CONSOLE_HOOK(ConHookNoNetwork)
|
||||
return CHR_ALLOW;
|
||||
}
|
||||
|
||||
#else
|
||||
# define ConHookNoNetwork NULL
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
DEF_CONSOLE_HOOK(ConHookNewGRFDeveloperTool)
|
||||
{
|
||||
if (_settings_client.gui.newgrf_developer_tools) {
|
||||
@@ -170,11 +165,7 @@ DEF_CONSOLE_HOOK(ConHookNewGRFDeveloperTool)
|
||||
if (echo) IConsoleError("This command is only available in game and editor.");
|
||||
return CHR_DISALLOW;
|
||||
}
|
||||
#ifdef ENABLE_NETWORK
|
||||
return ConHookNoNetwork(echo);
|
||||
#else
|
||||
return CHR_ALLOW;
|
||||
#endif
|
||||
}
|
||||
return CHR_HIDE;
|
||||
}
|
||||
@@ -258,7 +249,7 @@ DEF_CONSOLE_CMD(ConResetTile)
|
||||
* Scroll to a tile on the map.
|
||||
* param x tile number or tile x coordinate.
|
||||
* param y optional y coordinate.
|
||||
* @note When only one argument is given it is intepreted as the tile number.
|
||||
* @note When only one argument is given it is interpreted as the tile number.
|
||||
* When two arguments are given, they are interpreted as the tile's x
|
||||
* and y coordinates.
|
||||
* @return True when either console help was shown or a proper amount of parameters given.
|
||||
@@ -359,7 +350,7 @@ DEF_CONSOLE_CMD(ConLoad)
|
||||
const char *file = argv[1];
|
||||
_console_file_list.ValidateFileList();
|
||||
const FiosItem *item = _console_file_list.FindItem(file);
|
||||
if (item != NULL) {
|
||||
if (item != nullptr) {
|
||||
if (GetAbstractFileType(item->type) == FT_SAVEGAME) {
|
||||
_switch_mode = SM_LOAD_GAME;
|
||||
_file_to_saveload.SetMode(item->type);
|
||||
@@ -388,7 +379,7 @@ DEF_CONSOLE_CMD(ConRemove)
|
||||
const char *file = argv[1];
|
||||
_console_file_list.ValidateFileList();
|
||||
const FiosItem *item = _console_file_list.FindItem(file);
|
||||
if (item != NULL) {
|
||||
if (item != nullptr) {
|
||||
if (!FiosDelete(item->name)) {
|
||||
IConsolePrintF(CC_ERROR, "%s: Failed to delete file", file);
|
||||
}
|
||||
@@ -430,7 +421,7 @@ DEF_CONSOLE_CMD(ConChangeDirectory)
|
||||
const char *file = argv[1];
|
||||
_console_file_list.ValidateFileList(true);
|
||||
const FiosItem *item = _console_file_list.FindItem(file);
|
||||
if (item != NULL) {
|
||||
if (item != nullptr) {
|
||||
switch (item->type) {
|
||||
case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT:
|
||||
FiosBrowseTo(item);
|
||||
@@ -458,7 +449,7 @@ DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
|
||||
_console_file_list.ValidateFileList(true);
|
||||
_console_file_list.InvalidateFileList();
|
||||
|
||||
FiosGetDescText(&path, NULL);
|
||||
FiosGetDescText(&path, nullptr);
|
||||
IConsolePrint(CC_DEFAULT, path);
|
||||
return true;
|
||||
}
|
||||
@@ -479,13 +470,12 @@ DEF_CONSOLE_CMD(ConClearBuffer)
|
||||
/**********************************
|
||||
* Network Core Console Commands
|
||||
**********************************/
|
||||
#ifdef ENABLE_NETWORK
|
||||
|
||||
static bool ConKickOrBan(const char *argv, bool ban)
|
||||
{
|
||||
uint n;
|
||||
|
||||
if (strchr(argv, '.') == NULL && strchr(argv, ':') == NULL) { // banning with ID
|
||||
if (strchr(argv, '.') == nullptr && strchr(argv, ':') == nullptr) { // banning with ID
|
||||
ClientID client_id = (ClientID)atoi(argv);
|
||||
|
||||
/* Don't kill the server, or the client doing the rcon. The latter can't be kicked because
|
||||
@@ -498,7 +488,7 @@ static bool ConKickOrBan(const char *argv, bool ban)
|
||||
}
|
||||
|
||||
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
|
||||
if (ci == NULL) {
|
||||
if (ci == nullptr) {
|
||||
IConsoleError("Invalid client");
|
||||
return true;
|
||||
}
|
||||
@@ -563,21 +553,20 @@ DEF_CONSOLE_CMD(ConUnBan)
|
||||
|
||||
/* Try by IP. */
|
||||
uint index;
|
||||
for (index = 0; index < _network_ban_list.Length(); index++) {
|
||||
if (strcmp(_network_ban_list[index], argv[1]) == 0) break;
|
||||
for (index = 0; index < _network_ban_list.size(); index++) {
|
||||
if (_network_ban_list[index] == argv[1]) break;
|
||||
}
|
||||
|
||||
/* Try by index. */
|
||||
if (index >= _network_ban_list.Length()) {
|
||||
if (index >= _network_ban_list.size()) {
|
||||
index = atoi(argv[1]) - 1U; // let it wrap
|
||||
}
|
||||
|
||||
if (index < _network_ban_list.Length()) {
|
||||
if (index < _network_ban_list.size()) {
|
||||
char msg[64];
|
||||
seprintf(msg, lastof(msg), "Unbanned %s", _network_ban_list[index]);
|
||||
seprintf(msg, lastof(msg), "Unbanned %s", _network_ban_list[index].c_str());
|
||||
IConsolePrint(CC_DEFAULT, msg);
|
||||
free(_network_ban_list[index]);
|
||||
_network_ban_list.Erase(_network_ban_list.Get(index));
|
||||
_network_ban_list.erase(_network_ban_list.begin() + index);
|
||||
} else {
|
||||
IConsolePrint(CC_DEFAULT, "Invalid list index or IP not in ban-list.");
|
||||
IConsolePrint(CC_DEFAULT, "For a list of banned IP's, see the command 'banlist'");
|
||||
@@ -596,8 +585,8 @@ DEF_CONSOLE_CMD(ConBanList)
|
||||
IConsolePrint(CC_DEFAULT, "Banlist: ");
|
||||
|
||||
uint i = 1;
|
||||
for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++, i++) {
|
||||
IConsolePrintF(CC_DEFAULT, " %d) %s", i, *iter);
|
||||
for (const auto &entry : _network_ban_list) {
|
||||
IConsolePrintF(CC_DEFAULT, " %d) %s", i, entry.c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -700,7 +689,7 @@ DEF_CONSOLE_CMD(ConClientNickChange)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NetworkClientInfo::GetByClientID(client_id) == NULL) {
|
||||
if (NetworkClientInfo::GetByClientID(client_id) == nullptr) {
|
||||
IConsoleError("Invalid client");
|
||||
return true;
|
||||
}
|
||||
@@ -771,7 +760,7 @@ DEF_CONSOLE_CMD(ConMoveClient)
|
||||
CompanyID company_id = (CompanyID)(atoi(argv[2]) <= MAX_COMPANIES ? atoi(argv[2]) - 1 : atoi(argv[2]));
|
||||
|
||||
/* check the client exists */
|
||||
if (ci == NULL) {
|
||||
if (ci == nullptr) {
|
||||
IConsoleError("Invalid client-id, check the command 'clients' for valid client-id's.");
|
||||
return true;
|
||||
}
|
||||
@@ -870,8 +859,7 @@ DEF_CONSOLE_CMD(ConNetworkReconnect)
|
||||
default:
|
||||
/* From a user pov 0 is a new company, internally it's different and all
|
||||
* companies are offset by one to ease up on users (eg companies 1-8 not 0-7) */
|
||||
playas--;
|
||||
if (playas < COMPANY_FIRST || playas >= MAX_COMPANIES) return false;
|
||||
if (playas < COMPANY_FIRST + 1 || playas > MAX_COMPANIES + 1) return false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -899,8 +887,8 @@ DEF_CONSOLE_CMD(ConNetworkConnect)
|
||||
if (argc < 2) return false;
|
||||
if (_networking) NetworkDisconnect(); // we are in network-mode, first close it!
|
||||
|
||||
const char *port = NULL;
|
||||
const char *company = NULL;
|
||||
const char *port = nullptr;
|
||||
const char *company = nullptr;
|
||||
char *ip = argv[1];
|
||||
/* Default settings: default port and new company */
|
||||
uint16 rport = NETWORK_DEFAULT_PORT;
|
||||
@@ -909,7 +897,7 @@ DEF_CONSOLE_CMD(ConNetworkConnect)
|
||||
ParseConnectionString(&company, &port, ip);
|
||||
|
||||
IConsolePrintF(CC_DEFAULT, "Connecting to %s...", ip);
|
||||
if (company != NULL) {
|
||||
if (company != nullptr) {
|
||||
join_as = (CompanyID)atoi(company);
|
||||
IConsolePrintF(CC_DEFAULT, " company-no: %d", join_as);
|
||||
|
||||
@@ -920,7 +908,7 @@ DEF_CONSOLE_CMD(ConNetworkConnect)
|
||||
join_as--;
|
||||
}
|
||||
}
|
||||
if (port != NULL) {
|
||||
if (port != nullptr) {
|
||||
rport = atoi(port);
|
||||
IConsolePrintF(CC_DEFAULT, " port: %s", port);
|
||||
}
|
||||
@@ -930,8 +918,6 @@ DEF_CONSOLE_CMD(ConNetworkConnect)
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
/*********************************
|
||||
* script file console commands
|
||||
*********************************/
|
||||
@@ -947,7 +933,7 @@ DEF_CONSOLE_CMD(ConExec)
|
||||
|
||||
FILE *script_file = FioFOpenFile(argv[1], "r", BASE_DIR);
|
||||
|
||||
if (script_file == NULL) {
|
||||
if (script_file == nullptr) {
|
||||
if (argc == 2 || atoi(argv[2]) != 0) IConsoleError("script file not found");
|
||||
return true;
|
||||
}
|
||||
@@ -955,7 +941,7 @@ DEF_CONSOLE_CMD(ConExec)
|
||||
_script_running = true;
|
||||
|
||||
char cmdline[ICON_CMDLN_SIZE];
|
||||
while (_script_running && fgets(cmdline, sizeof(cmdline), script_file) != NULL) {
|
||||
while (_script_running && fgets(cmdline, sizeof(cmdline), script_file) != nullptr) {
|
||||
/* Remove newline characters from the executing script */
|
||||
for (char *cmdptr = cmdline; *cmdptr != '\0'; cmdptr++) {
|
||||
if (*cmdptr == '\n' || *cmdptr == '\r') {
|
||||
@@ -1006,7 +992,7 @@ DEF_CONSOLE_CMD(ConScript)
|
||||
|
||||
IConsolePrintF(CC_DEFAULT, "file output started to: %s", argv[1]);
|
||||
_iconsole_output_file = fopen(argv[1], "ab");
|
||||
if (_iconsole_output_file == NULL) IConsoleError("could not open file");
|
||||
if (_iconsole_output_file == nullptr) IConsoleError("could not open file");
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1045,7 +1031,7 @@ DEF_CONSOLE_CMD(ConNewGame)
|
||||
return true;
|
||||
}
|
||||
|
||||
StartNewGameWithoutGUI((argc == 2) ? strtoul(argv[1], NULL, 10) : GENERATE_NEW_SEED);
|
||||
StartNewGameWithoutGUI((argc == 2) ? strtoul(argv[1], nullptr, 10) : GENERATE_NEW_SEED);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1297,7 +1283,7 @@ DEF_CONSOLE_CMD(ConRescanNewGRF)
|
||||
return true;
|
||||
}
|
||||
|
||||
ScanNewGRFFiles(NULL);
|
||||
ScanNewGRFFiles(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1317,13 +1303,27 @@ DEF_CONSOLE_CMD(ConGetSeed)
|
||||
DEF_CONSOLE_CMD(ConGetDate)
|
||||
{
|
||||
if (argc == 0) {
|
||||
IConsoleHelp("Returns the current date (day-month-year) of the game. Usage: 'getdate'");
|
||||
IConsoleHelp("Returns the current date (year-month-day) of the game. Usage: 'getdate'");
|
||||
return true;
|
||||
}
|
||||
|
||||
YearMonthDay ymd;
|
||||
ConvertDateToYMD(_date, &ymd);
|
||||
IConsolePrintF(CC_DEFAULT, "Date: %d-%d-%d", ymd.day, ymd.month + 1, ymd.year);
|
||||
IConsolePrintF(CC_DEFAULT, "Date: %04d-%02d-%02d", ymd.year, ymd.month + 1, ymd.day);
|
||||
return true;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConGetSysDate)
|
||||
{
|
||||
if (argc == 0) {
|
||||
IConsoleHelp("Returns the current date (year-month-day) of your system. Usage: 'getsysdate'");
|
||||
return true;
|
||||
}
|
||||
|
||||
time_t t;
|
||||
time(&t);
|
||||
auto timeinfo = localtime(&t);
|
||||
IConsolePrintF(CC_DEFAULT, "System Date: %04d-%02d-%02d %02d:%02d:%02d", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1340,7 +1340,7 @@ DEF_CONSOLE_CMD(ConAlias)
|
||||
if (argc < 3) return false;
|
||||
|
||||
alias = IConsoleAliasGet(argv[1]);
|
||||
if (alias == NULL) {
|
||||
if (alias == nullptr) {
|
||||
IConsoleAliasRegister(argv[1], argv[2]);
|
||||
} else {
|
||||
free(alias->cmdline);
|
||||
@@ -1362,7 +1362,7 @@ DEF_CONSOLE_CMD(ConScreenShot)
|
||||
if (argc > 3) return false;
|
||||
|
||||
ScreenshotType type = SC_VIEWPORT;
|
||||
const char *name = NULL;
|
||||
const char *name = nullptr;
|
||||
|
||||
if (argc > 1) {
|
||||
if (strcmp(argv[1], "big") == 0) {
|
||||
@@ -1400,7 +1400,7 @@ DEF_CONSOLE_CMD(ConInfoCmd)
|
||||
if (argc < 2) return false;
|
||||
|
||||
const IConsoleCmd *cmd = IConsoleCmdGet(argv[1]);
|
||||
if (cmd == NULL) {
|
||||
if (cmd == nullptr) {
|
||||
IConsoleError("the given command was not found");
|
||||
return true;
|
||||
}
|
||||
@@ -1408,7 +1408,7 @@ DEF_CONSOLE_CMD(ConInfoCmd)
|
||||
IConsolePrintF(CC_DEFAULT, "command name: %s", cmd->name);
|
||||
IConsolePrintF(CC_DEFAULT, "command proc: %p", cmd->proc);
|
||||
|
||||
if (cmd->hook != NULL) IConsoleWarning("command is hooked");
|
||||
if (cmd->hook != nullptr) IConsoleWarning("command is hooked");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1466,16 +1466,16 @@ DEF_CONSOLE_CMD(ConHelp)
|
||||
|
||||
RemoveUnderscores(argv[1]);
|
||||
cmd = IConsoleCmdGet(argv[1]);
|
||||
if (cmd != NULL) {
|
||||
cmd->proc(0, NULL);
|
||||
if (cmd != nullptr) {
|
||||
cmd->proc(0, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
alias = IConsoleAliasGet(argv[1]);
|
||||
if (alias != NULL) {
|
||||
if (alias != nullptr) {
|
||||
cmd = IConsoleCmdGet(alias->cmdline);
|
||||
if (cmd != NULL) {
|
||||
cmd->proc(0, NULL);
|
||||
if (cmd != nullptr) {
|
||||
cmd->proc(0, nullptr);
|
||||
return true;
|
||||
}
|
||||
IConsolePrintF(CC_ERROR, "ERROR: alias is of special type, please see its execution-line: '%s'", alias->cmdline);
|
||||
@@ -1505,9 +1505,9 @@ DEF_CONSOLE_CMD(ConListCommands)
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const IConsoleCmd *cmd = _iconsole_cmds; cmd != NULL; cmd = cmd->next) {
|
||||
if (argv[1] == NULL || strstr(cmd->name, argv[1]) != NULL) {
|
||||
if (cmd->hook == NULL || cmd->hook(false) != CHR_HIDE) IConsolePrintF(CC_DEFAULT, "%s", cmd->name);
|
||||
for (const IConsoleCmd *cmd = _iconsole_cmds; cmd != nullptr; cmd = cmd->next) {
|
||||
if (argv[1] == nullptr || strstr(cmd->name, argv[1]) != nullptr) {
|
||||
if (cmd->hook == nullptr || cmd->hook(false) != CHR_HIDE) IConsolePrintF(CC_DEFAULT, "%s", cmd->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1521,8 +1521,8 @@ DEF_CONSOLE_CMD(ConListAliases)
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const IConsoleAlias *alias = _iconsole_aliases; alias != NULL; alias = alias->next) {
|
||||
if (argv[1] == NULL || strstr(alias->name, argv[1]) != NULL) {
|
||||
for (const IConsoleAlias *alias = _iconsole_aliases; alias != nullptr; alias = alias->next) {
|
||||
if (argv[1] == nullptr || strstr(alias->name, argv[1]) != nullptr) {
|
||||
IConsolePrintF(CC_DEFAULT, "%s => %s", alias->name, alias->cmdline);
|
||||
}
|
||||
}
|
||||
@@ -1547,12 +1547,9 @@ DEF_CONSOLE_CMD(ConCompanies)
|
||||
const char *password_state = "";
|
||||
if (c->is_ai) {
|
||||
password_state = "AI";
|
||||
}
|
||||
#ifdef ENABLE_NETWORK
|
||||
else if (_network_server) {
|
||||
} else if (_network_server) {
|
||||
password_state = StrEmpty(_network_company_states[c->index].password) ? "unprotected" : "protected";
|
||||
}
|
||||
#endif
|
||||
|
||||
char colour[512];
|
||||
GetString(colour, STR_COLOUR_DARK_BLUE + _company_colours[c->index], lastof(colour));
|
||||
@@ -1569,8 +1566,6 @@ DEF_CONSOLE_CMD(ConCompanies)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
|
||||
DEF_CONSOLE_CMD(ConSay)
|
||||
{
|
||||
if (argc == 0) {
|
||||
@@ -1736,8 +1731,8 @@ static void OutputContentState(const ContentInfo *const ci)
|
||||
|
||||
DEF_CONSOLE_CMD(ConContent)
|
||||
{
|
||||
static ContentCallback *cb = NULL;
|
||||
if (cb == NULL) {
|
||||
static ContentCallback *cb = nullptr;
|
||||
if (cb == nullptr) {
|
||||
cb = new ConsoleContentCallback();
|
||||
_network_content_client.AddCallback(cb);
|
||||
}
|
||||
@@ -1795,7 +1790,7 @@ DEF_CONSOLE_CMD(ConContent)
|
||||
if (strcasecmp(argv[1], "state") == 0) {
|
||||
IConsolePrintF(CC_WHITE, "id, type, state, name");
|
||||
for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) {
|
||||
if (argc > 2 && strcasestr((*iter)->name, argv[2]) == NULL) continue;
|
||||
if (argc > 2 && strcasestr((*iter)->name, argv[2]) == nullptr) continue;
|
||||
OutputContentState(*iter);
|
||||
}
|
||||
return true;
|
||||
@@ -1812,7 +1807,6 @@ DEF_CONSOLE_CMD(ConContent)
|
||||
return false;
|
||||
}
|
||||
#endif /* defined(WITH_ZLIB) */
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
DEF_CONSOLE_CMD(ConSetting)
|
||||
{
|
||||
@@ -1861,7 +1855,7 @@ DEF_CONSOLE_CMD(ConListSettings)
|
||||
|
||||
if (argc > 2) return false;
|
||||
|
||||
IConsoleListSettings((argc == 2) ? argv[1] : NULL);
|
||||
IConsoleListSettings((argc == 2) ? argv[1] : nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1946,6 +1940,7 @@ void IConsoleStdLibRegister()
|
||||
IConsoleCmdRegister("restart", ConRestart);
|
||||
IConsoleCmdRegister("getseed", ConGetSeed);
|
||||
IConsoleCmdRegister("getdate", ConGetDate);
|
||||
IConsoleCmdRegister("getsysdate", ConGetSysDate);
|
||||
IConsoleCmdRegister("quit", ConExit);
|
||||
IConsoleCmdRegister("resetengines", ConResetEngines, ConHookNoNetwork);
|
||||
IConsoleCmdRegister("reset_enginepool", ConResetEnginePool, ConHookNoNetwork);
|
||||
@@ -1992,7 +1987,7 @@ void IConsoleStdLibRegister()
|
||||
IConsoleAliasRegister("players", "companies");
|
||||
|
||||
/* networking functions */
|
||||
#ifdef ENABLE_NETWORK
|
||||
|
||||
/* Content downloading is only available with ZLIB */
|
||||
#if defined(WITH_ZLIB)
|
||||
IConsoleCmdRegister("content", ConContent);
|
||||
@@ -2050,7 +2045,6 @@ void IConsoleStdLibRegister()
|
||||
IConsoleAliasRegister("restart_game_year", "setting restart_game_year %+");
|
||||
IConsoleAliasRegister("min_players", "setting min_active_clients %+");
|
||||
IConsoleAliasRegister("reload_cfg", "setting reload_cfg %+");
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
/* debugging stuff */
|
||||
#ifdef _DEBUG
|
||||
|
||||
+29
-29
@@ -78,7 +78,7 @@ struct IConsoleLine {
|
||||
static const IConsoleLine *Get(uint index)
|
||||
{
|
||||
const IConsoleLine *item = IConsoleLine::front;
|
||||
while (index != 0 && item != NULL) {
|
||||
while (index != 0 && item != nullptr) {
|
||||
index--;
|
||||
item = item->previous;
|
||||
}
|
||||
@@ -96,14 +96,14 @@ struct IConsoleLine {
|
||||
static bool Truncate()
|
||||
{
|
||||
IConsoleLine *cur = IConsoleLine::front;
|
||||
if (cur == NULL) return false;
|
||||
if (cur == nullptr) return false;
|
||||
|
||||
int count = 1;
|
||||
for (IConsoleLine *item = cur->previous; item != NULL; count++, cur = item, item = item->previous) {
|
||||
for (IConsoleLine *item = cur->previous; item != nullptr; count++, cur = item, item = item->previous) {
|
||||
if (item->time > _settings_client.gui.console_backlog_timeout &&
|
||||
count > _settings_client.gui.console_backlog_length) {
|
||||
delete item;
|
||||
cur->previous = NULL;
|
||||
cur->previous = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -119,12 +119,12 @@ struct IConsoleLine {
|
||||
static void Reset()
|
||||
{
|
||||
delete IConsoleLine::front;
|
||||
IConsoleLine::front = NULL;
|
||||
IConsoleLine::front = nullptr;
|
||||
IConsoleLine::size = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/* static */ IConsoleLine *IConsoleLine::front = NULL;
|
||||
/* static */ IConsoleLine *IConsoleLine::front = nullptr;
|
||||
/* static */ int IConsoleLine::size = 0;
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ static const struct NWidgetPart _nested_console_window_widgets[] = {
|
||||
};
|
||||
|
||||
static WindowDesc _console_window_desc(
|
||||
WDP_MANUAL, NULL, 0, 0,
|
||||
WDP_MANUAL, nullptr, 0, 0,
|
||||
WC_CONSOLE, WC_NONE,
|
||||
0,
|
||||
_nested_console_window_widgets, lengthof(_nested_console_window_widgets)
|
||||
@@ -201,13 +201,13 @@ struct IConsoleWindow : Window
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
virtual void OnPaint()
|
||||
void OnPaint() override
|
||||
{
|
||||
const int right = this->width - 5;
|
||||
|
||||
GfxFillRect(0, 0, this->width - 1, this->height - 1, PC_BLACK);
|
||||
int ypos = this->height - this->line_height;
|
||||
for (const IConsoleLine *print = IConsoleLine::Get(IConsoleWindow::scroll); print != NULL; print = print->previous) {
|
||||
for (const IConsoleLine *print = IConsoleLine::Get(IConsoleWindow::scroll); print != nullptr; print = print->previous) {
|
||||
SetDParamStr(0, print->buffer);
|
||||
ypos = DrawStringMultiLine(5, right, -this->line_height, ypos, STR_JUST_RAW_STRING, print->colour, SA_LEFT | SA_BOTTOM | SA_FORCE) - ICON_LINE_SPACING;
|
||||
if (ypos < 0) break;
|
||||
@@ -229,7 +229,7 @@ struct IConsoleWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnHundredthTick()
|
||||
void OnHundredthTick() override
|
||||
{
|
||||
if (IConsoleLine::Truncate() &&
|
||||
(IConsoleWindow::scroll > IConsoleLine::size)) {
|
||||
@@ -238,12 +238,12 @@ struct IConsoleWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnMouseLoop()
|
||||
void OnMouseLoop() override
|
||||
{
|
||||
if (_iconsole_cmdline.HandleCaret()) this->SetDirty();
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
EventState OnKeyPress(WChar key, uint16 keycode) override
|
||||
{
|
||||
if (_focused_window != this) return ES_NOT_HANDLED;
|
||||
|
||||
@@ -281,13 +281,13 @@ struct IConsoleWindow : Window
|
||||
|
||||
case WKC_RETURN: case WKC_NUM_ENTER: {
|
||||
/* We always want the ] at the left side; we always force these strings to be left
|
||||
* aligned anyway. So enforce this in all cases by addding a left-to-right marker,
|
||||
* aligned anyway. So enforce this in all cases by adding a left-to-right marker,
|
||||
* otherwise it will be drawn at the wrong side with right-to-left texts. */
|
||||
IConsolePrintF(CC_COMMAND, LRM "] %s", _iconsole_cmdline.buf);
|
||||
const char *cmd = IConsoleHistoryAdd(_iconsole_cmdline.buf);
|
||||
IConsoleClearCommand();
|
||||
|
||||
if (cmd != NULL) IConsoleCmdExec(cmd);
|
||||
if (cmd != nullptr) IConsoleCmdExec(cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ struct IConsoleWindow : Window
|
||||
return ES_HANDLED;
|
||||
}
|
||||
|
||||
virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
|
||||
void InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) override
|
||||
{
|
||||
if (_iconsole_cmdline.InsertString(str, marked, caret, insert_location, replacement_end)) {
|
||||
IConsoleWindow::scroll = 0;
|
||||
@@ -323,25 +323,25 @@ struct IConsoleWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char *GetFocusedText() const
|
||||
const char *GetFocusedText() const override
|
||||
{
|
||||
return _iconsole_cmdline.buf;
|
||||
}
|
||||
|
||||
virtual const char *GetCaret() const
|
||||
const char *GetCaret() const override
|
||||
{
|
||||
return _iconsole_cmdline.buf + _iconsole_cmdline.caretpos;
|
||||
}
|
||||
|
||||
virtual const char *GetMarkedText(size_t *length) const
|
||||
const char *GetMarkedText(size_t *length) const override
|
||||
{
|
||||
if (_iconsole_cmdline.markend == 0) return NULL;
|
||||
if (_iconsole_cmdline.markend == 0) return nullptr;
|
||||
|
||||
*length = _iconsole_cmdline.markend - _iconsole_cmdline.markpos;
|
||||
return _iconsole_cmdline.buf + _iconsole_cmdline.markpos;
|
||||
}
|
||||
|
||||
virtual Point GetCaretPosition() const
|
||||
Point GetCaretPosition() const override
|
||||
{
|
||||
int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);
|
||||
Point pt = {this->line_offset + delta + _iconsole_cmdline.caretxoffs, this->height - this->line_height};
|
||||
@@ -349,7 +349,7 @@ struct IConsoleWindow : Window
|
||||
return pt;
|
||||
}
|
||||
|
||||
virtual Rect GetTextBoundingRect(const char *from, const char *to) const
|
||||
Rect GetTextBoundingRect(const char *from, const char *to) const override
|
||||
{
|
||||
int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);
|
||||
|
||||
@@ -360,21 +360,21 @@ struct IConsoleWindow : Window
|
||||
return r;
|
||||
}
|
||||
|
||||
virtual const char *GetTextCharacterAtPosition(const Point &pt) const
|
||||
const char *GetTextCharacterAtPosition(const Point &pt) const override
|
||||
{
|
||||
int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);
|
||||
|
||||
if (!IsInsideMM(pt.y, this->height - this->line_height, this->height)) return NULL;
|
||||
if (!IsInsideMM(pt.y, this->height - this->line_height, this->height)) return nullptr;
|
||||
|
||||
return GetCharAtPosition(_iconsole_cmdline.buf, pt.x - delta);
|
||||
}
|
||||
|
||||
virtual void OnMouseWheel(int wheel)
|
||||
void OnMouseWheel(int wheel) override
|
||||
{
|
||||
this->Scroll(-wheel);
|
||||
}
|
||||
|
||||
virtual void OnFocusLost()
|
||||
void OnFocusLost() override
|
||||
{
|
||||
VideoDriver::GetInstance()->EditBoxLostFocus();
|
||||
}
|
||||
@@ -459,10 +459,10 @@ static const char *IConsoleHistoryAdd(const char *cmd)
|
||||
while (IsWhitespace(*cmd)) cmd++;
|
||||
|
||||
/* Do not put empty command in history */
|
||||
if (StrEmpty(cmd)) return NULL;
|
||||
if (StrEmpty(cmd)) return nullptr;
|
||||
|
||||
/* Do not put in history if command is same as previous */
|
||||
if (_iconsole_history[0] == NULL || strcmp(_iconsole_history[0], cmd) != 0) {
|
||||
if (_iconsole_history[0] == nullptr || strcmp(_iconsole_history[0], cmd) != 0) {
|
||||
free(_iconsole_history[ICON_HISTORY_SIZE - 1]);
|
||||
memmove(&_iconsole_history[1], &_iconsole_history[0], sizeof(_iconsole_history[0]) * (ICON_HISTORY_SIZE - 1));
|
||||
_iconsole_history[0] = stredup(cmd);
|
||||
@@ -479,10 +479,10 @@ static const char *IConsoleHistoryAdd(const char *cmd)
|
||||
*/
|
||||
static void IConsoleHistoryNavigate(int direction)
|
||||
{
|
||||
if (_iconsole_history[0] == NULL) return; // Empty history
|
||||
if (_iconsole_history[0] == nullptr) return; // Empty history
|
||||
_iconsole_historypos = Clamp(_iconsole_historypos + direction, -1, ICON_HISTORY_SIZE - 1);
|
||||
|
||||
if (direction > 0 && _iconsole_history[_iconsole_historypos] == NULL) _iconsole_historypos--;
|
||||
if (direction > 0 && _iconsole_history[_iconsole_historypos] == nullptr) _iconsole_historypos--;
|
||||
|
||||
if (_iconsole_historypos == -1) {
|
||||
_iconsole_cmdline.DeleteAll();
|
||||
|
||||
@@ -69,7 +69,7 @@ extern IConsoleAlias *_iconsole_aliases; ///< List of registered aliases.
|
||||
void IConsoleClearBuffer();
|
||||
|
||||
/* Commands */
|
||||
void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *hook = NULL);
|
||||
void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *hook = nullptr);
|
||||
void IConsoleAliasRegister(const char *name, const char *cmd);
|
||||
IConsoleCmd *IConsoleCmdGet(const char *name);
|
||||
IConsoleAlias *IConsoleAliasGet(const char *name);
|
||||
|
||||
+12
-12
@@ -53,23 +53,23 @@ static inline void CheckAllocationConstraints(size_t num_elements)
|
||||
* @note the memory contains garbage data (i.e. possibly non-zero values).
|
||||
* @tparam T the type of the variable(s) to allocation.
|
||||
* @param num_elements the number of elements to allocate of the given type.
|
||||
* @return NULL when num_elements == 0, non-NULL otherwise.
|
||||
* @return nullptr when num_elements == 0, non-nullptr otherwise.
|
||||
*/
|
||||
template <typename T>
|
||||
static inline T *MallocT(size_t num_elements)
|
||||
{
|
||||
/*
|
||||
* MorphOS cannot handle 0 elements allocations, or rather that always
|
||||
* returns NULL. So we do that for *all* allocations, thus causing it
|
||||
* returns nullptr. So we do that for *all* allocations, thus causing it
|
||||
* to behave the same on all OSes.
|
||||
*/
|
||||
if (num_elements == 0) return NULL;
|
||||
if (num_elements == 0) return nullptr;
|
||||
|
||||
/* Ensure the size does not overflow. */
|
||||
CheckAllocationConstraints<T>(num_elements);
|
||||
|
||||
T *t_ptr = (T*)malloc(num_elements * sizeof(T));
|
||||
if (t_ptr == NULL) MallocError(num_elements * sizeof(T));
|
||||
if (t_ptr == nullptr) MallocError(num_elements * sizeof(T));
|
||||
return t_ptr;
|
||||
}
|
||||
|
||||
@@ -81,20 +81,20 @@ static inline T *MallocT(size_t num_elements)
|
||||
* @note the memory contains all zero values.
|
||||
* @tparam T the type of the variable(s) to allocation.
|
||||
* @param num_elements the number of elements to allocate of the given type.
|
||||
* @return NULL when num_elements == 0, non-NULL otherwise.
|
||||
* @return nullptr when num_elements == 0, non-nullptr otherwise.
|
||||
*/
|
||||
template <typename T>
|
||||
static inline T *CallocT(size_t num_elements)
|
||||
{
|
||||
/*
|
||||
* MorphOS cannot handle 0 elements allocations, or rather that always
|
||||
* returns NULL. So we do that for *all* allocations, thus causing it
|
||||
* returns nullptr. So we do that for *all* allocations, thus causing it
|
||||
* to behave the same on all OSes.
|
||||
*/
|
||||
if (num_elements == 0) return NULL;
|
||||
if (num_elements == 0) return nullptr;
|
||||
|
||||
T *t_ptr = (T*)calloc(num_elements, sizeof(T));
|
||||
if (t_ptr == NULL) MallocError(num_elements * sizeof(T));
|
||||
if (t_ptr == nullptr) MallocError(num_elements * sizeof(T));
|
||||
return t_ptr;
|
||||
}
|
||||
|
||||
@@ -107,26 +107,26 @@ static inline T *CallocT(size_t num_elements)
|
||||
* @tparam T the type of the variable(s) to allocation.
|
||||
* @param t_ptr the previous allocation to extend/shrink.
|
||||
* @param num_elements the number of elements to allocate of the given type.
|
||||
* @return NULL when num_elements == 0, non-NULL otherwise.
|
||||
* @return nullptr when num_elements == 0, non-nullptr otherwise.
|
||||
*/
|
||||
template <typename T>
|
||||
static inline T *ReallocT(T *t_ptr, size_t num_elements)
|
||||
{
|
||||
/*
|
||||
* MorphOS cannot handle 0 elements allocations, or rather that always
|
||||
* returns NULL. So we do that for *all* allocations, thus causing it
|
||||
* returns nullptr. So we do that for *all* allocations, thus causing it
|
||||
* to behave the same on all OSes.
|
||||
*/
|
||||
if (num_elements == 0) {
|
||||
free(t_ptr);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Ensure the size does not overflow. */
|
||||
CheckAllocationConstraints<T>(num_elements);
|
||||
|
||||
t_ptr = (T*)realloc(static_cast<void *>(t_ptr), num_elements * sizeof(T));
|
||||
if (t_ptr == NULL) ReallocError(num_elements * sizeof(T));
|
||||
if (t_ptr == nullptr) ReallocError(num_elements * sizeof(T));
|
||||
return t_ptr;
|
||||
}
|
||||
|
||||
|
||||
+1
-98
@@ -14,69 +14,6 @@
|
||||
|
||||
#include "alloc_func.hpp"
|
||||
|
||||
/**
|
||||
* A small 'wrapper' for allocations that can be done on most OSes on the
|
||||
* stack, but are just too large to fit in the stack on devices with a small
|
||||
* stack such as the NDS.
|
||||
* So when it is possible a stack allocation is made, otherwise a heap
|
||||
* allocation is made and this is freed once the struct goes out of scope.
|
||||
* @param T the type to make the allocation for
|
||||
* @param length the amount of items to allocate
|
||||
*/
|
||||
template <typename T, size_t length>
|
||||
struct SmallStackSafeStackAlloc {
|
||||
#if !defined(__NDS__)
|
||||
/** Storing the data on the stack */
|
||||
T data[length];
|
||||
#else
|
||||
/** Storing it on the heap */
|
||||
T *data;
|
||||
/** The length (in elements) of data in this allocator. */
|
||||
size_t len;
|
||||
|
||||
/** Allocating the memory */
|
||||
SmallStackSafeStackAlloc() : data(MallocT<T>(length)), len(length) {}
|
||||
|
||||
/** And freeing when it goes out of scope */
|
||||
~SmallStackSafeStackAlloc()
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Gets a pointer to the data stored in this wrapper.
|
||||
* @return the pointer.
|
||||
*/
|
||||
inline operator T *()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pointer to the data stored in this wrapper.
|
||||
* @return the pointer.
|
||||
*/
|
||||
inline T *operator -> ()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pointer to the last data element stored in this wrapper.
|
||||
* @note needed because endof does not work properly for pointers.
|
||||
* @return the 'endof' pointer.
|
||||
*/
|
||||
inline T *EndOf()
|
||||
{
|
||||
#if !defined(__NDS__)
|
||||
return endof(data);
|
||||
#else
|
||||
return &data[len];
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A reusable buffer that can be used for places that temporary allocate
|
||||
* a bit of memory and do that very often, or for places where static
|
||||
@@ -93,7 +30,7 @@ private:
|
||||
|
||||
public:
|
||||
/** Create a new buffer */
|
||||
ReusableBuffer() : buffer(NULL), count(0) {}
|
||||
ReusableBuffer() : buffer(nullptr), count(0) {}
|
||||
/** Clear the buffer */
|
||||
~ReusableBuffer() { free(this->buffer); }
|
||||
|
||||
@@ -180,38 +117,4 @@ public:
|
||||
inline void operator delete[](void *ptr) { free(ptr); }
|
||||
};
|
||||
|
||||
/**
|
||||
* A smart pointer class that free()'s the pointer on destruction.
|
||||
* @tparam T Storage type.
|
||||
*/
|
||||
template <typename T>
|
||||
class AutoFreePtr
|
||||
{
|
||||
T *ptr; ///< Stored pointer.
|
||||
|
||||
public:
|
||||
AutoFreePtr(T *ptr) : ptr(ptr) {}
|
||||
~AutoFreePtr() { free(this->ptr); }
|
||||
|
||||
/**
|
||||
* Take ownership of a new pointer and free the old one if needed.
|
||||
* @param ptr NEw pointer.
|
||||
*/
|
||||
inline void Assign(T *ptr)
|
||||
{
|
||||
free(this->ptr);
|
||||
this->ptr = ptr;
|
||||
}
|
||||
|
||||
/** Dereference pointer. */
|
||||
inline T *operator ->() { return this->ptr; }
|
||||
/** Dereference pointer. */
|
||||
inline const T *operator ->() const { return this->ptr; }
|
||||
|
||||
/** Cast to underlaying regular pointer. */
|
||||
inline operator T *() { return this->ptr; }
|
||||
/** Cast to underlaying regular pointer. */
|
||||
inline operator const T *() const { return this->ptr; }
|
||||
};
|
||||
|
||||
#endif /* ALLOC_TYPE_HPP */
|
||||
|
||||
@@ -367,12 +367,12 @@ static inline T ROR(const T x, const uint8 n)
|
||||
* (since it will use hardware swapping if available).
|
||||
* Even though they should return uint16 and uint32, we get
|
||||
* warnings if we don't cast those (why?) */
|
||||
#define BSWAP32(x) ((uint32)CFSwapInt32(x))
|
||||
#define BSWAP16(x) ((uint16)CFSwapInt16(x))
|
||||
# define BSWAP32(x) (static_cast<uint32>(CFSwapInt32(x)))
|
||||
# define BSWAP16(x) (static_cast<uint16>(CFSwapInt16(x)))
|
||||
#elif defined(_MSC_VER)
|
||||
/* MSVC has intrinsics for swapping, resulting in faster code */
|
||||
#define BSWAP32(x) (_byteswap_ulong(x))
|
||||
#define BSWAP16(x) (_byteswap_ushort(x))
|
||||
# define BSWAP32(x) (_byteswap_ulong(x))
|
||||
# define BSWAP16(x) (_byteswap_ushort(x))
|
||||
#else
|
||||
/**
|
||||
* Perform a 32 bits endianness bitswap on x.
|
||||
@@ -383,7 +383,7 @@ static inline T ROR(const T x, const uint8 n)
|
||||
{
|
||||
#if !defined(__ICC) && defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ >= 3))
|
||||
/* GCC >= 4.3 provides a builtin, resulting in faster code */
|
||||
return (uint32)__builtin_bswap32((int32)x);
|
||||
return static_cast<uint32>(__builtin_bswap32(static_cast<int32>(x)));
|
||||
#else
|
||||
return ((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000) | ((x << 24) & 0xFF000000);
|
||||
#endif /* defined(__GNUC__) */
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#define TTD_BIG_ENDIAN 1
|
||||
|
||||
/* Windows has always LITTLE_ENDIAN */
|
||||
#if defined(_WIN32) || defined(__OS2__)
|
||||
#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
|
||||
# define TTD_ENDIAN TTD_LITTLE_ENDIAN
|
||||
#elif defined(OSX)
|
||||
# include <sys/types.h>
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#ifndef ENUM_TYPE_HPP
|
||||
#define ENUM_TYPE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
/** Some enums need to have allowed incrementing (i.e. StationClassID) */
|
||||
#define DECLARE_POSTFIX_INCREMENT(enum_type) \
|
||||
inline enum_type operator ++(enum_type& e, int) \
|
||||
@@ -48,8 +46,6 @@
|
||||
* we will create specialization derived from MakeEnumPropsT<>.
|
||||
* i.e.:
|
||||
* template <> struct EnumPropsT<Track> : MakeEnumPropsT<Track, byte, TRACK_BEGIN, TRACK_END, INVALID_TRACK> {};
|
||||
* followed by:
|
||||
* typedef TinyEnumT<Track> TrackByte;
|
||||
*/
|
||||
template <typename Tenum_t> struct EnumPropsT;
|
||||
|
||||
@@ -74,106 +70,4 @@ struct MakeEnumPropsT {
|
||||
static const uint num_bits = Tnum_bits; ///< Number of bits for storing the enum in command parameters
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* In some cases we use byte or uint16 to store values that are defined as enum. It is
|
||||
* necessary in order to control the sizeof() such values. Some compilers make enum
|
||||
* the same size as int (4 or 8 bytes instead of 1 or 2). As a consequence the strict
|
||||
* compiler type - checking causes errors like:
|
||||
* 'HasPowerOnRail' : cannot convert parameter 1 from 'byte' to 'RailType' when
|
||||
* u->u.rail.railtype is passed as argument or type RailType. In such cases it is better
|
||||
* to teach the compiler that u->u.rail.railtype is to be treated as RailType.
|
||||
*/
|
||||
template <typename Tenum_t> struct TinyEnumT;
|
||||
|
||||
/** The general declaration of TinyEnumT<> (above) */
|
||||
template <typename Tenum_t>
|
||||
struct TinyEnumT {
|
||||
typedef Tenum_t enum_type; ///< expose our enumeration type (i.e. Trackdir) to outside
|
||||
typedef EnumPropsT<Tenum_t> Props; ///< make easier access to our enumeration properties
|
||||
typedef typename Props::storage storage_type; ///< small storage type
|
||||
static const enum_type begin = Props::begin; ///< enum beginning (i.e. TRACKDIR_BEGIN)
|
||||
static const enum_type end = Props::end; ///< enum end (i.e. TRACKDIR_END)
|
||||
static const enum_type invalid = Props::invalid;///< invalid value (i.e. INVALID_TRACKDIR)
|
||||
|
||||
storage_type m_val; ///< here we hold the actual value in small (i.e. byte) form
|
||||
|
||||
/** Cast operator - invoked then the value is assigned to the Tenum_t type */
|
||||
inline operator enum_type () const
|
||||
{
|
||||
return (enum_type)m_val;
|
||||
}
|
||||
|
||||
/** Assignment operator (from Tenum_t type) */
|
||||
inline TinyEnumT& operator = (enum_type e)
|
||||
{
|
||||
m_val = (storage_type)e;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Assignment operator (from Tenum_t type) */
|
||||
inline TinyEnumT& operator = (uint u)
|
||||
{
|
||||
m_val = (storage_type)u;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** postfix ++ operator on tiny type */
|
||||
inline TinyEnumT operator ++ (int)
|
||||
{
|
||||
TinyEnumT org = *this;
|
||||
if (++m_val >= end) m_val -= (storage_type)(end - begin);
|
||||
return org;
|
||||
}
|
||||
|
||||
/** prefix ++ operator on tiny type */
|
||||
inline TinyEnumT& operator ++ ()
|
||||
{
|
||||
if (++m_val >= end) m_val -= (storage_type)(end - begin);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Template of struct holding enum types (on most archs, enums are stored in an int32). No math operators are provided. */
|
||||
template <typename enum_type, typename storage_type>
|
||||
struct SimpleTinyEnumT {
|
||||
storage_type m_val; ///< here we hold the actual value in small (i.e. byte) form
|
||||
|
||||
/** Cast operator - invoked then the value is assigned to the storage_type */
|
||||
inline operator enum_type () const
|
||||
{
|
||||
return (enum_type)this->m_val;
|
||||
}
|
||||
|
||||
/** Assignment operator (from enum_type) */
|
||||
inline SimpleTinyEnumT &operator = (enum_type e)
|
||||
{
|
||||
this->m_val = (storage_type)e;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Assignment operator (from general uint) */
|
||||
inline SimpleTinyEnumT &operator = (uint u)
|
||||
{
|
||||
this->m_val = (storage_type)u;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Bit math (or) assignment operator (from enum_type) */
|
||||
inline SimpleTinyEnumT &operator |= (enum_type e)
|
||||
{
|
||||
this->m_val = (storage_type)((enum_type)this->m_val | e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Bit math (and) assignment operator (from enum_type) */
|
||||
inline SimpleTinyEnumT &operator &= (enum_type e)
|
||||
{
|
||||
this->m_val = (storage_type)((enum_type)this->m_val & e);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* ENUM_TYPE_HPP */
|
||||
|
||||
@@ -12,11 +12,6 @@
|
||||
#ifndef GEOMETRY_TYPE_HPP
|
||||
#define GEOMETRY_TYPE_HPP
|
||||
|
||||
#if defined(__AMIGA__)
|
||||
/* AmigaOS already has a Point declared */
|
||||
#define Point OTTD_Point
|
||||
#endif /* __AMIGA__ */
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* Mac OS X already has both Rect and Point declared */
|
||||
#define Rect OTTD_Rect
|
||||
@@ -34,6 +29,20 @@ struct Point {
|
||||
struct Dimension {
|
||||
uint width;
|
||||
uint height;
|
||||
|
||||
Dimension(uint w = 0, uint h = 0) : width(w), height(h) {};
|
||||
|
||||
bool operator< (const Dimension &other) const
|
||||
{
|
||||
int x = (*this).width - other.width;
|
||||
if (x != 0) return x < 0;
|
||||
return (*this).height < other.height;
|
||||
}
|
||||
|
||||
bool operator== (const Dimension &other) const
|
||||
{
|
||||
return (*this).width == other.width && (*this).height == other.height;
|
||||
}
|
||||
};
|
||||
|
||||
/** Specification of a rectangle with absolute coordinates of all edges */
|
||||
|
||||
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* 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 kdtree.hpp K-d tree template specialised for 2-dimensional Manhattan geometry */
|
||||
|
||||
#ifndef KDTREE_HPP
|
||||
#define KDTREE_HPP
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
/**
|
||||
* K-dimensional tree, specialised for 2-dimensional space.
|
||||
* This is not intended as a primary storage of data, but as an index into existing data.
|
||||
* Usually the type stored by this tree should be an index into an existing array.
|
||||
*
|
||||
* This implementation assumes Manhattan distances are used.
|
||||
*
|
||||
* Be careful when using this in game code, depending on usage pattern, the tree shape may
|
||||
* end up different for different clients in multiplayer, causing iteration order to differ
|
||||
* and possibly having elements returned in different order. The using code should be designed
|
||||
* to produce the same result regardless of iteration order.
|
||||
*
|
||||
* The element type T must be less-than comparable for FindNearest to work.
|
||||
*
|
||||
* @tparam T Type stored in the tree, should be cheap to copy.
|
||||
* @tparam TxyFunc Functor type to extract coordinate from a T value and dimension index (0 or 1).
|
||||
* @tparam CoordT Type of coordinate values extracted via TxyFunc.
|
||||
* @tparam DistT Type to use for representing distance values.
|
||||
*/
|
||||
template <typename T, typename TxyFunc, typename CoordT, typename DistT>
|
||||
class Kdtree {
|
||||
/** Type of a node in the tree */
|
||||
struct node {
|
||||
T element; ///< Element stored at node
|
||||
size_t left; ///< Index of node to the left, INVALID_NODE if none
|
||||
size_t right; ///< Index of node to the right, INVALID_NODE if none
|
||||
|
||||
node(T element) : element(element), left(INVALID_NODE), right(INVALID_NODE) { }
|
||||
};
|
||||
|
||||
static const size_t INVALID_NODE = SIZE_MAX; ///< Index value indicating no-such-node
|
||||
|
||||
std::vector<node> nodes; ///< Pool of all nodes in the tree
|
||||
std::vector<size_t> free_list; ///< List of dead indices in the nodes vector
|
||||
size_t root; ///< Index of root node
|
||||
TxyFunc xyfunc; ///< Functor to extract a coordinate from an element
|
||||
size_t unbalanced; ///< Number approximating how unbalanced the tree might be
|
||||
|
||||
/** Create one new node in the tree, return its index in the pool */
|
||||
size_t AddNode(const T &element)
|
||||
{
|
||||
if (this->free_list.size() == 0) {
|
||||
this->nodes.emplace_back(element);
|
||||
return this->nodes.size() - 1;
|
||||
} else {
|
||||
size_t newidx = this->free_list.back();
|
||||
this->free_list.pop_back();
|
||||
this->nodes[newidx] = node{ element };
|
||||
return newidx;
|
||||
}
|
||||
}
|
||||
|
||||
/** Find a coordinate value to split a range of elements at */
|
||||
template <typename It>
|
||||
CoordT SelectSplitCoord(It begin, It end, int level)
|
||||
{
|
||||
It mid = begin + (end - begin) / 2;
|
||||
std::nth_element(begin, mid, end, [&](T a, T b) { return this->xyfunc(a, level % 2) < this->xyfunc(b, level % 2); });
|
||||
return this->xyfunc(*mid, level % 2);
|
||||
}
|
||||
|
||||
/** Construct a subtree from elements between begin and end iterators, return index of root */
|
||||
template <typename It>
|
||||
size_t BuildSubtree(It begin, It end, int level)
|
||||
{
|
||||
ptrdiff_t count = end - begin;
|
||||
|
||||
if (count == 0) {
|
||||
return INVALID_NODE;
|
||||
} else if (count == 1) {
|
||||
return this->AddNode(*begin);
|
||||
} else if (count > 1) {
|
||||
CoordT split_coord = SelectSplitCoord(begin, end, level);
|
||||
It split = std::partition(begin, end, [&](T v) { return this->xyfunc(v, level % 2) < split_coord; });
|
||||
size_t newidx = this->AddNode(*split);
|
||||
this->nodes[newidx].left = this->BuildSubtree(begin, split, level + 1);
|
||||
this->nodes[newidx].right = this->BuildSubtree(split + 1, end, level + 1);
|
||||
return newidx;
|
||||
} else {
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
/** Rebuild the tree with all existing elements, optionally adding or removing one more */
|
||||
bool Rebuild(const T *include_element, const T *exclude_element)
|
||||
{
|
||||
size_t initial_count = this->Count();
|
||||
if (initial_count < 8) return false; // arbitrary value for "not worth rebalancing"
|
||||
|
||||
T root_element = this->nodes[this->root].element;
|
||||
std::vector<T> elements = this->FreeSubtree(this->root);
|
||||
elements.push_back(root_element);
|
||||
|
||||
if (include_element != nullptr) {
|
||||
elements.push_back(*include_element);
|
||||
initial_count++;
|
||||
}
|
||||
if (exclude_element != nullptr) {
|
||||
typename std::vector<T>::iterator removed = std::remove(elements.begin(), elements.end(), *exclude_element);
|
||||
elements.erase(removed, elements.end());
|
||||
initial_count--;
|
||||
}
|
||||
|
||||
this->Build(elements.begin(), elements.end());
|
||||
assert(initial_count == this->Count());
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Insert one element in the tree somewhere below node_idx */
|
||||
void InsertRecursive(const T &element, size_t node_idx, int level)
|
||||
{
|
||||
/* Dimension index of current level */
|
||||
int dim = level % 2;
|
||||
/* Node reference */
|
||||
node &n = this->nodes[node_idx];
|
||||
|
||||
/* Coordinate of element splitting at this node */
|
||||
CoordT nc = this->xyfunc(n.element, dim);
|
||||
/* Coordinate of the new element */
|
||||
CoordT ec = this->xyfunc(element, dim);
|
||||
/* Which side to insert on */
|
||||
size_t &next = (ec < nc) ? n.left : n.right;
|
||||
|
||||
if (next == INVALID_NODE) {
|
||||
/* New leaf */
|
||||
size_t newidx = this->AddNode(element);
|
||||
/* Vector may have been reallocated at this point, n and next are invalid */
|
||||
node &nn = this->nodes[node_idx];
|
||||
if (ec < nc) nn.left = newidx; else nn.right = newidx;
|
||||
} else {
|
||||
this->InsertRecursive(element, next, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Free all children of the given node
|
||||
* @return Collection of elements that were removed from tree.
|
||||
*/
|
||||
std::vector<T> FreeSubtree(size_t node_idx)
|
||||
{
|
||||
std::vector<T> subtree_elements;
|
||||
node &n = this->nodes[node_idx];
|
||||
|
||||
/* We'll be appending items to the free_list, get index of our first item */
|
||||
size_t first_free = this->free_list.size();
|
||||
/* Prepare the descent with our children */
|
||||
if (n.left != INVALID_NODE) this->free_list.push_back(n.left);
|
||||
if (n.right != INVALID_NODE) this->free_list.push_back(n.right);
|
||||
n.left = n.right = INVALID_NODE;
|
||||
|
||||
/* Recursively free the nodes being collected */
|
||||
for (size_t i = first_free; i < this->free_list.size(); i++) {
|
||||
node &fn = this->nodes[this->free_list[i]];
|
||||
subtree_elements.push_back(fn.element);
|
||||
if (fn.left != INVALID_NODE) this->free_list.push_back(fn.left);
|
||||
if (fn.right != INVALID_NODE) this->free_list.push_back(fn.right);
|
||||
fn.left = fn.right = INVALID_NODE;
|
||||
}
|
||||
|
||||
return subtree_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and remove one element from the tree.
|
||||
* @param element The element to search for
|
||||
* @param node_idx Sub-tree to search in
|
||||
* @param level Current depth in the tree
|
||||
* @return New root node index of the sub-tree processed
|
||||
*/
|
||||
size_t RemoveRecursive(const T &element, size_t node_idx, int level)
|
||||
{
|
||||
/* Node reference */
|
||||
node &n = this->nodes[node_idx];
|
||||
|
||||
if (n.element == element) {
|
||||
/* Remove this one */
|
||||
this->free_list.push_back(node_idx);
|
||||
if (n.left == INVALID_NODE && n.right == INVALID_NODE) {
|
||||
/* Simple case, leaf, new child node for parent is "none" */
|
||||
return INVALID_NODE;
|
||||
} else {
|
||||
/* Complex case, rebuild the sub-tree */
|
||||
std::vector<T> subtree_elements = this->FreeSubtree(node_idx);
|
||||
return this->BuildSubtree(subtree_elements.begin(), subtree_elements.end(), level);;
|
||||
}
|
||||
} else {
|
||||
/* Search in a sub-tree */
|
||||
/* Dimension index of current level */
|
||||
int dim = level % 2;
|
||||
/* Coordinate of element splitting at this node */
|
||||
CoordT nc = this->xyfunc(n.element, dim);
|
||||
/* Coordinate of the element being removed */
|
||||
CoordT ec = this->xyfunc(element, dim);
|
||||
/* Which side to remove from */
|
||||
size_t next = (ec < nc) ? n.left : n.right;
|
||||
assert(next != INVALID_NODE); // node must exist somewhere and must be found before a leaf is reached
|
||||
/* Descend */
|
||||
size_t new_branch = this->RemoveRecursive(element, next, level + 1);
|
||||
if (new_branch != next) {
|
||||
/* Vector may have been reallocated at this point, n and next are invalid */
|
||||
node &nn = this->nodes[node_idx];
|
||||
if (ec < nc) nn.left = new_branch; else nn.right = new_branch;
|
||||
}
|
||||
return node_idx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DistT ManhattanDistance(const T &element, CoordT x, CoordT y) const
|
||||
{
|
||||
return abs((DistT)this->xyfunc(element, 0) - (DistT)x) + abs((DistT)this->xyfunc(element, 1) - (DistT)y);
|
||||
}
|
||||
|
||||
/** A data element and its distance to a searched-for point */
|
||||
using node_distance = std::pair<T, DistT>;
|
||||
/** Ordering function for node_distance objects, elements with equal distance are ordered by less-than comparison */
|
||||
static node_distance SelectNearestNodeDistance(const node_distance &a, const node_distance &b)
|
||||
{
|
||||
if (a.second < b.second) return a;
|
||||
if (b.second < a.second) return b;
|
||||
if (a.first < b.first) return a;
|
||||
if (b.first < a.first) return b;
|
||||
NOT_REACHED(); // a.first == b.first: same element must not be inserted twice
|
||||
}
|
||||
/** Search a sub-tree for the element nearest to a given point */
|
||||
node_distance FindNearestRecursive(CoordT xy[2], size_t node_idx, int level, DistT limit = std::numeric_limits<DistT>::max()) const
|
||||
{
|
||||
/* Dimension index of current level */
|
||||
int dim = level % 2;
|
||||
/* Node reference */
|
||||
const node &n = this->nodes[node_idx];
|
||||
|
||||
/* Coordinate of element splitting at this node */
|
||||
CoordT c = this->xyfunc(n.element, dim);
|
||||
/* This node's distance to target */
|
||||
DistT thisdist = ManhattanDistance(n.element, xy[0], xy[1]);
|
||||
/* Assume this node is the best choice for now */
|
||||
node_distance best = std::make_pair(n.element, thisdist);
|
||||
|
||||
/* Next node to visit */
|
||||
size_t next = (xy[dim] < c) ? n.left : n.right;
|
||||
if (next != INVALID_NODE) {
|
||||
/* Check if there is a better node down the tree */
|
||||
best = SelectNearestNodeDistance(best, this->FindNearestRecursive(xy, next, level + 1));
|
||||
}
|
||||
|
||||
limit = min(best.second, limit);
|
||||
|
||||
/* Check if the distance from current best is worse than distance from target to splitting line,
|
||||
* if it is we also need to check the other side of the split. */
|
||||
size_t opposite = (xy[dim] >= c) ? n.left : n.right; // reverse of above
|
||||
if (opposite != INVALID_NODE && limit >= abs((int)xy[dim] - (int)c)) {
|
||||
node_distance other_candidate = this->FindNearestRecursive(xy, opposite, level + 1, limit);
|
||||
best = SelectNearestNodeDistance(best, other_candidate);
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
template <typename Outputter>
|
||||
void FindContainedRecursive(CoordT p1[2], CoordT p2[2], size_t node_idx, int level, Outputter outputter) const
|
||||
{
|
||||
/* Dimension index of current level */
|
||||
int dim = level % 2;
|
||||
/* Node reference */
|
||||
const node &n = this->nodes[node_idx];
|
||||
|
||||
/* Coordinate of element splitting at this node */
|
||||
CoordT ec = this->xyfunc(n.element, dim);
|
||||
/* Opposite coordinate of element */
|
||||
CoordT oc = this->xyfunc(n.element, 1 - dim);
|
||||
|
||||
/* Test if this element is within rectangle */
|
||||
if (ec >= p1[dim] && ec < p2[dim] && oc >= p1[1 - dim] && oc < p2[1 - dim]) outputter(n.element);
|
||||
|
||||
/* Recurse left if part of rectangle is left of split */
|
||||
if (p1[dim] < ec && n.left != INVALID_NODE) this->FindContainedRecursive(p1, p2, n.left, level + 1, outputter);
|
||||
|
||||
/* Recurse right if part of rectangle is right of split */
|
||||
if (p2[dim] > ec && n.right != INVALID_NODE) this->FindContainedRecursive(p1, p2, n.right, level + 1, outputter);
|
||||
}
|
||||
|
||||
/** Debugging function, counts number of occurrences of an element regardless of its correct position in the tree */
|
||||
size_t CountValue(const T &element, size_t node_idx) const
|
||||
{
|
||||
if (node_idx == INVALID_NODE) return 0;
|
||||
const node &n = this->nodes[node_idx];
|
||||
return CountValue(element, n.left) + CountValue(element, n.right) + ((n.element == element) ? 1 : 0);
|
||||
}
|
||||
|
||||
void IncrementUnbalanced(size_t amount = 1)
|
||||
{
|
||||
this->unbalanced += amount;
|
||||
}
|
||||
|
||||
/** Check if the entire tree is in need of rebuilding */
|
||||
bool IsUnbalanced()
|
||||
{
|
||||
size_t count = this->Count();
|
||||
if (count < 8) return false;
|
||||
return this->unbalanced > this->Count() / 4;
|
||||
}
|
||||
|
||||
/** Verify that the invariant is true for a sub-tree, assert if not */
|
||||
void CheckInvariant(size_t node_idx, int level, CoordT min_x, CoordT max_x, CoordT min_y, CoordT max_y)
|
||||
{
|
||||
if (node_idx == INVALID_NODE) return;
|
||||
|
||||
const node &n = this->nodes[node_idx];
|
||||
CoordT cx = this->xyfunc(n.element, 0);
|
||||
CoordT cy = this->xyfunc(n.element, 1);
|
||||
|
||||
assert(cx >= min_x);
|
||||
assert(cx < max_x);
|
||||
assert(cy >= min_y);
|
||||
assert(cy < max_y);
|
||||
|
||||
if (level % 2 == 0) {
|
||||
// split in dimension 0 = x
|
||||
CheckInvariant(n.left, level + 1, min_x, cx, min_y, max_y);
|
||||
CheckInvariant(n.right, level + 1, cx, max_x, min_y, max_y);
|
||||
} else {
|
||||
// split in dimension 1 = y
|
||||
CheckInvariant(n.left, level + 1, min_x, max_x, min_y, cy);
|
||||
CheckInvariant(n.right, level + 1, min_x, max_x, cy, max_y);
|
||||
}
|
||||
}
|
||||
|
||||
/** Verify the invariant for the entire tree, does nothing unless KDTREE_DEBUG is defined */
|
||||
void CheckInvariant()
|
||||
{
|
||||
#ifdef KDTREE_DEBUG
|
||||
CheckInvariant(this->root, 0, std::numeric_limits<CoordT>::min(), std::numeric_limits<CoordT>::max(), std::numeric_limits<CoordT>::min(), std::numeric_limits<CoordT>::max());
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
/** Construct a new Kdtree with the given xyfunc */
|
||||
Kdtree(TxyFunc xyfunc) : root(INVALID_NODE), xyfunc(xyfunc), unbalanced(0) { }
|
||||
|
||||
/**
|
||||
* Clear and rebuild the tree from a new sequence of elements,
|
||||
* @tparam It Iterator type for element sequence.
|
||||
* @param begin First element in sequence.
|
||||
* @param end One past last element in sequence.
|
||||
*/
|
||||
template <typename It>
|
||||
void Build(It begin, It end)
|
||||
{
|
||||
this->nodes.clear();
|
||||
this->free_list.clear();
|
||||
this->unbalanced = 0;
|
||||
if (begin == end) return;
|
||||
this->nodes.reserve(end - begin);
|
||||
|
||||
this->root = this->BuildSubtree(begin, end, 0);
|
||||
CheckInvariant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the tree.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
this->nodes.clear();
|
||||
this->free_list.clear();
|
||||
this->unbalanced = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstruct the tree with the same elements, letting it be fully balanced.
|
||||
*/
|
||||
void Rebuild()
|
||||
{
|
||||
this->Rebuild(nullptr, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a single element in the tree.
|
||||
* Repeatedly inserting single elements may cause the tree to become unbalanced.
|
||||
* Undefined behaviour if the element already exists in the tree.
|
||||
*/
|
||||
void Insert(const T &element)
|
||||
{
|
||||
if (this->Count() == 0) {
|
||||
this->root = this->AddNode(element);
|
||||
} else {
|
||||
if (!this->IsUnbalanced() || !this->Rebuild(&element, nullptr)) {
|
||||
this->InsertRecursive(element, this->root, 0);
|
||||
this->IncrementUnbalanced();
|
||||
}
|
||||
CheckInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a single element from the tree, if it exists.
|
||||
* Since elements are stored in interior nodes as well as leaf nodes, removing one may
|
||||
* require a larger sub-tree to be re-built. Because of this, worst case run time is
|
||||
* as bad as a full tree rebuild.
|
||||
*/
|
||||
void Remove(const T &element)
|
||||
{
|
||||
size_t count = this->Count();
|
||||
if (count == 0) return;
|
||||
if (!this->IsUnbalanced() || !this->Rebuild(nullptr, &element)) {
|
||||
/* If the removed element is the root node, this modifies this->root */
|
||||
this->root = this->RemoveRecursive(element, this->root, 0);
|
||||
this->IncrementUnbalanced();
|
||||
}
|
||||
CheckInvariant();
|
||||
}
|
||||
|
||||
/** Get number of elements stored in tree */
|
||||
size_t Count() const
|
||||
{
|
||||
assert(this->free_list.size() <= this->nodes.size());
|
||||
return this->nodes.size() - this->free_list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the element closest to given coordinate, in Manhattan distance.
|
||||
* For multiple elements with the same distance, the one comparing smaller with
|
||||
* a less-than comparison is chosen.
|
||||
*/
|
||||
T FindNearest(CoordT x, CoordT y) const
|
||||
{
|
||||
assert(this->Count() > 0);
|
||||
|
||||
CoordT xy[2] = { x, y };
|
||||
return this->FindNearestRecursive(xy, this->root, 0).first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all items contained within the given rectangle.
|
||||
* @note Start coordinates are inclusive, end coordinates are exclusive. x1<x2 && y1<y2 is a precondition.
|
||||
* @param x1 Start first coordinate, points found are greater or equals to this.
|
||||
* @param y1 Start second coordinate, points found are greater or equals to this.
|
||||
* @param x2 End first coordinate, points found are less than this.
|
||||
* @param y2 End second coordinate, points found are less than this.
|
||||
* @param outputter Callback used to return values from the search.
|
||||
*/
|
||||
template <typename Outputter>
|
||||
void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, Outputter outputter) const
|
||||
{
|
||||
assert(x1 < x2);
|
||||
assert(y1 < y2);
|
||||
|
||||
if (this->Count() == 0) return;
|
||||
|
||||
CoordT p1[2] = { x1, y1 };
|
||||
CoordT p2[2] = { x2, y2 };
|
||||
this->FindContainedRecursive(p1, p2, this->root, 0, outputter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all items contained within the given rectangle.
|
||||
* @note End coordinates are exclusive, x1<x2 && y1<y2 is a precondition.
|
||||
*/
|
||||
std::vector<T> FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2) const
|
||||
{
|
||||
std::vector<T> result;
|
||||
this->FindContained(x1, y1, x2, y2, [&result](T e) {result.push_back(e); });
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -115,7 +115,7 @@ template <typename T>
|
||||
static inline T *AlignPtr(T *x, uint n)
|
||||
{
|
||||
assert_compile(sizeof(size_t) == sizeof(void *));
|
||||
return (T *)Align((size_t)x, n);
|
||||
return reinterpret_cast<T *>(Align((size_t)x, n));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,7 +202,7 @@ static inline uint ClampU(const uint a, const uint min, const uint max)
|
||||
*/
|
||||
static inline int32 ClampToI32(const int64 a)
|
||||
{
|
||||
return (int32)Clamp<int64>(a, INT32_MIN, INT32_MAX);
|
||||
return static_cast<int32>(Clamp<int64>(a, INT32_MIN, INT32_MAX));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,7 +218,7 @@ static inline uint16 ClampToU16(const uint64 a)
|
||||
* match for min(uint64, uint) than uint64 min(uint64, uint64). As such we
|
||||
* need to cast the UINT16_MAX to prevent MSVC from displaying its
|
||||
* infinite loads of warnings. */
|
||||
return (uint16)min<uint64>(a, (uint64)UINT16_MAX);
|
||||
return static_cast<uint16>(min<uint64>(a, static_cast<uint64>(UINT16_MAX)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,9 +247,9 @@ static inline T Delta(const T a, const T b)
|
||||
* @return True if the value is in the interval, false else.
|
||||
*/
|
||||
template <typename T>
|
||||
static inline bool IsInsideBS(const T x, const uint base, const uint size)
|
||||
static inline bool IsInsideBS(const T x, const size_t base, const size_t size)
|
||||
{
|
||||
return (uint)(x - base) < size;
|
||||
return (size_t)(x - base) < size;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,9 +263,9 @@ static inline bool IsInsideBS(const T x, const uint base, const uint size)
|
||||
* @see IsInsideBS()
|
||||
*/
|
||||
template <typename T>
|
||||
static inline bool IsInsideMM(const T x, const uint min, const uint max)
|
||||
static inline bool IsInsideMM(const T x, const size_t min, const size_t max)
|
||||
{
|
||||
return (uint)(x - min) < (max - min);
|
||||
return (size_t)(x - min) < (max - min);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,10 +339,10 @@ static inline int RoundDivSU(int a, uint b)
|
||||
{
|
||||
if (a > 0) {
|
||||
/* 0.5 is rounded to 1 */
|
||||
return (a + (int)b / 2) / (int)b;
|
||||
return (a + static_cast<int>(b) / 2) / static_cast<int>(b);
|
||||
} else {
|
||||
/* -0.5 is rounded to 0 */
|
||||
return (a - ((int)b - 1) / 2) / (int)b;
|
||||
return (a - (static_cast<int>(b) - 1) / 2) / static_cast<int>(b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ static inline int MemCmpT(const T *ptr1, const T *ptr2, size_t num = 1)
|
||||
template <typename T>
|
||||
static inline void MemReverseT(T *ptr1, T *ptr2)
|
||||
{
|
||||
assert(ptr1 != NULL && ptr2 != NULL);
|
||||
assert(ptr1 != nullptr && ptr2 != nullptr);
|
||||
assert(ptr1 < ptr2);
|
||||
|
||||
do {
|
||||
@@ -95,7 +95,7 @@ static inline void MemReverseT(T *ptr1, T *ptr2)
|
||||
template <typename T>
|
||||
static inline void MemReverseT(T *ptr, size_t num)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
assert(ptr != nullptr);
|
||||
|
||||
MemReverseT(ptr, ptr + (num - 1));
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
/* virtual */ PoolBase::~PoolBase()
|
||||
{
|
||||
PoolVector *pools = PoolBase::GetPools();
|
||||
pools->Erase(pools->Find(this));
|
||||
if (pools->Length() == 0) delete pools;
|
||||
pools->erase(std::find(pools->begin(), pools->end(), this));
|
||||
if (pools->size() == 0) delete pools;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,10 +31,7 @@
|
||||
*/
|
||||
/* static */ void PoolBase::Clean(PoolType pt)
|
||||
{
|
||||
PoolVector *pools = PoolBase::GetPools();
|
||||
PoolBase **end = pools->End();
|
||||
for (PoolBase **ppool = pools->Begin(); ppool != end; ppool++) {
|
||||
PoolBase *pool = *ppool;
|
||||
for (PoolBase *pool : *PoolBase::GetPools()) {
|
||||
if (pool->type & pt) pool->CleanPool();
|
||||
}
|
||||
}
|
||||
|
||||
+14
-14
@@ -39,8 +39,8 @@ DEFINE_POOL_METHOD(inline)::Pool(const char *name) :
|
||||
checked(0),
|
||||
#endif /* OTTD_ASSERT */
|
||||
cleaning(false),
|
||||
data(NULL),
|
||||
alloc_cache(NULL)
|
||||
data(nullptr),
|
||||
alloc_cache(nullptr)
|
||||
{ }
|
||||
|
||||
/**
|
||||
@@ -71,7 +71,7 @@ DEFINE_POOL_METHOD(inline size_t)::FindFirstFree()
|
||||
size_t index = this->first_free;
|
||||
|
||||
for (; index < this->first_unused; index++) {
|
||||
if (this->data[index] == NULL) return index;
|
||||
if (this->data[index] == nullptr) return index;
|
||||
}
|
||||
|
||||
if (index < this->size) {
|
||||
@@ -96,17 +96,17 @@ DEFINE_POOL_METHOD(inline size_t)::FindFirstFree()
|
||||
* @param size size of item
|
||||
* @param index index of item
|
||||
* @pre index < this->size
|
||||
* @pre this->Get(index) == NULL
|
||||
* @pre this->Get(index) == nullptr
|
||||
*/
|
||||
DEFINE_POOL_METHOD(inline void *)::AllocateItem(size_t size, size_t index)
|
||||
{
|
||||
assert(this->data[index] == NULL);
|
||||
assert(this->data[index] == nullptr);
|
||||
|
||||
this->first_unused = max(this->first_unused, index + 1);
|
||||
this->items++;
|
||||
|
||||
Titem *item;
|
||||
if (Tcache && this->alloc_cache != NULL) {
|
||||
if (Tcache && this->alloc_cache != nullptr) {
|
||||
assert(sizeof(Titem) == size);
|
||||
item = (Titem *)this->alloc_cache;
|
||||
this->alloc_cache = this->alloc_cache->next;
|
||||
@@ -164,7 +164,7 @@ DEFINE_POOL_METHOD(void *)::GetNew(size_t size, size_t index)
|
||||
|
||||
if (index >= this->size) this->ResizeFor(index);
|
||||
|
||||
if (this->data[index] != NULL) {
|
||||
if (this->data[index] != nullptr) {
|
||||
SlErrorCorruptFmt("%s index " PRINTF_SIZE " already in use", this->name, index);
|
||||
}
|
||||
|
||||
@@ -174,13 +174,13 @@ DEFINE_POOL_METHOD(void *)::GetNew(size_t size, size_t index)
|
||||
/**
|
||||
* Deallocates memory used by this index and marks item as free
|
||||
* @param index item to deallocate
|
||||
* @pre unit is allocated (non-NULL)
|
||||
* @note 'delete NULL' doesn't cause call of this function, so it is safe
|
||||
* @pre unit is allocated (non-nullptr)
|
||||
* @note 'delete nullptr' doesn't cause call of this function, so it is safe
|
||||
*/
|
||||
DEFINE_POOL_METHOD(void)::FreeItem(size_t index)
|
||||
{
|
||||
assert(index < this->size);
|
||||
assert(this->data[index] != NULL);
|
||||
assert(this->data[index] != nullptr);
|
||||
if (Tcache) {
|
||||
AllocCache *ac = (AllocCache *)this->data[index];
|
||||
ac->next = this->alloc_cache;
|
||||
@@ -188,7 +188,7 @@ DEFINE_POOL_METHOD(void)::FreeItem(size_t index)
|
||||
} else {
|
||||
free(this->data[index]);
|
||||
}
|
||||
this->data[index] = NULL;
|
||||
this->data[index] = nullptr;
|
||||
this->first_free = min(this->first_free, index);
|
||||
this->items--;
|
||||
if (!this->cleaning) Titem::PostDestructor(index);
|
||||
@@ -199,16 +199,16 @@ DEFINE_POOL_METHOD(void)::CleanPool()
|
||||
{
|
||||
this->cleaning = true;
|
||||
for (size_t i = 0; i < this->first_unused; i++) {
|
||||
delete this->Get(i); // 'delete NULL;' is very valid
|
||||
delete this->Get(i); // 'delete nullptr;' is very valid
|
||||
}
|
||||
assert(this->items == 0);
|
||||
free(this->data);
|
||||
this->first_unused = this->first_free = this->size = 0;
|
||||
this->data = NULL;
|
||||
this->data = nullptr;
|
||||
this->cleaning = false;
|
||||
|
||||
if (Tcache) {
|
||||
while (this->alloc_cache != NULL) {
|
||||
while (this->alloc_cache != nullptr) {
|
||||
AllocCache *ac = this->alloc_cache;
|
||||
this->alloc_cache = ac->next;
|
||||
free(ac);
|
||||
|
||||
+17
-17
@@ -7,7 +7,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/>.
|
||||
*/
|
||||
|
||||
/** @file pool_type.hpp Defintion of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle, Town, and other indexed items. */
|
||||
/** @file pool_type.hpp Definition of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle, Town, and other indexed items. */
|
||||
|
||||
#ifndef POOL_TYPE_HPP
|
||||
#define POOL_TYPE_HPP
|
||||
@@ -26,7 +26,7 @@ enum PoolType {
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(PoolType)
|
||||
|
||||
typedef SmallVector<struct PoolBase *, 4> PoolVector; ///< Vector of pointers to PoolBase
|
||||
typedef std::vector<struct PoolBase *> PoolVector; ///< Vector of pointers to PoolBase
|
||||
|
||||
/** Base class for base of all pools. */
|
||||
struct PoolBase {
|
||||
@@ -50,7 +50,7 @@ struct PoolBase {
|
||||
*/
|
||||
PoolBase(PoolType pt) : type(pt)
|
||||
{
|
||||
*PoolBase::GetPools()->Append() = this;
|
||||
PoolBase::GetPools()->push_back(this);
|
||||
}
|
||||
|
||||
virtual ~PoolBase();
|
||||
@@ -91,7 +91,7 @@ struct Pool : PoolBase {
|
||||
size_t size; ///< Current allocated size
|
||||
size_t first_free; ///< No item with index lower than this is free (doesn't say anything about this one!)
|
||||
size_t first_unused; ///< This and all higher indexes are free (doesn't say anything about first_unused-1 !)
|
||||
size_t items; ///< Number of used indexes (non-NULL)
|
||||
size_t items; ///< Number of used indexes (non-nullptr)
|
||||
#ifdef OTTD_ASSERT
|
||||
size_t checked; ///< Number of items we checked for
|
||||
#endif /* OTTD_ASSERT */
|
||||
@@ -115,13 +115,13 @@ struct Pool : PoolBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether given index can be used to get valid (non-NULL) Titem
|
||||
* Tests whether given index can be used to get valid (non-nullptr) Titem
|
||||
* @param index index to examine
|
||||
* @return true if PoolItem::Get(index) will return non-NULL pointer
|
||||
* @return true if PoolItem::Get(index) will return non-nullptr pointer
|
||||
*/
|
||||
inline bool IsValidID(size_t index)
|
||||
{
|
||||
return index < this->first_unused && this->Get(index) != NULL;
|
||||
return index < this->first_unused && this->Get(index) != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,7 +150,7 @@ struct Pool : PoolBase {
|
||||
* Allocates space for new Titem
|
||||
* @param size size of Titem
|
||||
* @return pointer to allocated memory
|
||||
* @note can never fail (return NULL), use CanAllocate() to check first!
|
||||
* @note can never fail (return nullptr), use CanAllocate() to check first!
|
||||
*/
|
||||
inline void *operator new(size_t size)
|
||||
{
|
||||
@@ -164,7 +164,7 @@ struct Pool : PoolBase {
|
||||
*/
|
||||
inline void operator delete(void *p)
|
||||
{
|
||||
if (p == NULL) return;
|
||||
if (p == nullptr) return;
|
||||
Titem *pn = (Titem *)p;
|
||||
assert(pn == Tpool->Get(pn->index));
|
||||
Tpool->FreeItem(pn->index);
|
||||
@@ -175,7 +175,7 @@ struct Pool : PoolBase {
|
||||
* @param size size of Titem
|
||||
* @param index index of item
|
||||
* @return pointer to allocated memory
|
||||
* @note can never fail (return NULL), use CanAllocate() to check first!
|
||||
* @note can never fail (return nullptr), use CanAllocate() to check first!
|
||||
* @pre index has to be unused! Else it will crash
|
||||
*/
|
||||
inline void *operator new(size_t size, size_t index)
|
||||
@@ -228,9 +228,9 @@ struct Pool : PoolBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether given index can be used to get valid (non-NULL) Titem
|
||||
* Tests whether given index can be used to get valid (non-nullptr) Titem
|
||||
* @param index index to examine
|
||||
* @return true if PoolItem::Get(index) will return non-NULL pointer
|
||||
* @return true if PoolItem::Get(index) will return non-nullptr pointer
|
||||
*/
|
||||
static inline bool IsValidID(size_t index)
|
||||
{
|
||||
@@ -252,11 +252,11 @@ struct Pool : PoolBase {
|
||||
* Returns Titem with given index
|
||||
* @param index of item to get
|
||||
* @return pointer to Titem
|
||||
* @note returns NULL for invalid index
|
||||
* @note returns nullptr for invalid index
|
||||
*/
|
||||
static inline Titem *GetIfValid(size_t index)
|
||||
{
|
||||
return index < Tpool->first_unused ? Tpool->Get(index) : NULL;
|
||||
return index < Tpool->first_unused ? Tpool->Get(index) : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,7 +282,7 @@ struct Pool : PoolBase {
|
||||
* Dummy function called after destructor of each member.
|
||||
* If you want to use it, override it in PoolItem's subclass.
|
||||
* @param index index of deleted item
|
||||
* @note when this function is called, PoolItem::Get(index) == NULL.
|
||||
* @note when this function is called, PoolItem::Get(index) == nullptr.
|
||||
* @note it's called only when !CleaningPool()
|
||||
*/
|
||||
static inline void PostDestructor(size_t index) { }
|
||||
@@ -314,8 +314,8 @@ private:
|
||||
};
|
||||
|
||||
#define FOR_ALL_ITEMS_FROM(type, iter, var, start) \
|
||||
for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \
|
||||
if ((var = type::Get(iter)) != NULL)
|
||||
for (size_t iter = start; var = nullptr, iter < type::GetPoolSize(); iter++) \
|
||||
if ((var = type::Get(iter)) != nullptr)
|
||||
|
||||
#define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0)
|
||||
|
||||
|
||||
+46
-36
@@ -13,7 +13,6 @@
|
||||
#define SMALLMAP_TYPE_HPP
|
||||
|
||||
#include "smallvec_type.hpp"
|
||||
#include "sort_func.hpp"
|
||||
|
||||
/**
|
||||
* Simple pair of data. Both types have to be POD ("Plain Old Data")!
|
||||
@@ -27,6 +26,7 @@ struct SmallPair {
|
||||
|
||||
/** Initializes this Pair with data */
|
||||
inline SmallPair(const T &first, const U &second) : first(first), second(second) { }
|
||||
SmallPair() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -38,8 +38,8 @@ struct SmallPair {
|
||||
*
|
||||
* @see SmallVector
|
||||
*/
|
||||
template <typename T, typename U, uint S = 16>
|
||||
struct SmallMap : SmallVector<SmallPair<T, U>, S> {
|
||||
template <typename T, typename U>
|
||||
struct SmallMap : std::vector<SmallPair<T, U> > {
|
||||
typedef ::SmallPair<T, U> Pair;
|
||||
typedef Pair *iterator;
|
||||
typedef const Pair *const_iterator;
|
||||
@@ -54,12 +54,13 @@ struct SmallMap : SmallVector<SmallPair<T, U>, S> {
|
||||
* @param key key to find
|
||||
* @return &Pair(key, data) if found, this->End() if not
|
||||
*/
|
||||
inline const Pair *Find(const T &key) const
|
||||
inline typename std::vector<Pair>::const_iterator Find(const T &key) const
|
||||
{
|
||||
for (uint i = 0; i < this->items; i++) {
|
||||
if (key == this->data[i].first) return &this->data[i];
|
||||
typename std::vector<Pair>::const_iterator it;
|
||||
for (it = std::vector<Pair>::begin(); it != std::vector<Pair>::end(); it++) {
|
||||
if (key == it->first) return it;
|
||||
}
|
||||
return this->End();
|
||||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,18 +70,39 @@ struct SmallMap : SmallVector<SmallPair<T, U>, S> {
|
||||
*/
|
||||
inline Pair *Find(const T &key)
|
||||
{
|
||||
for (uint i = 0; i < this->items; i++) {
|
||||
if (key == this->data[i].first) return &this->data[i];
|
||||
for (uint i = 0; i < std::vector<Pair>::size(); i++) {
|
||||
if (key == std::vector<Pair>::operator[](i).first) return &std::vector<Pair>::operator[](i);
|
||||
}
|
||||
return this->End();
|
||||
}
|
||||
|
||||
inline const Pair *End() const
|
||||
{
|
||||
return std::vector<Pair>::data() + std::vector<Pair>::size();
|
||||
}
|
||||
|
||||
inline Pair *End()
|
||||
{
|
||||
return std::vector<Pair>::data() + std::vector<Pair>::size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests whether a key is assigned in this map.
|
||||
* @param key key to test
|
||||
* @return true iff the item is present
|
||||
*/
|
||||
inline bool Contains(const T &key) const
|
||||
{
|
||||
return this->Find(key) != std::vector<Pair>::end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a key is assigned in this map.
|
||||
* @param key key to test
|
||||
* @return true iff the item is present
|
||||
*/
|
||||
inline bool Contains(const T &key)
|
||||
{
|
||||
return this->Find(key) != this->End();
|
||||
}
|
||||
@@ -92,8 +114,9 @@ struct SmallMap : SmallVector<SmallPair<T, U>, S> {
|
||||
*/
|
||||
inline void Erase(Pair *pair)
|
||||
{
|
||||
assert(pair >= this->Begin() && pair < this->End());
|
||||
*pair = this->data[--this->items];
|
||||
assert(pair >= std::vector<Pair>::data() && pair < this->End());
|
||||
auto distance = pair - std::vector<Pair>::data();
|
||||
std::vector<Pair>::erase(std::vector<Pair>::begin() + distance);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,13 +127,11 @@ struct SmallMap : SmallVector<SmallPair<T, U>, S> {
|
||||
*/
|
||||
inline bool Erase(const T &key)
|
||||
{
|
||||
for (uint i = 0; i < this->items; i++) {
|
||||
if (key == this->data[i].first) {
|
||||
this->data[i] = this->data[--this->items];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
auto *pair = this->Find(key);
|
||||
if (pair == this->End()) return false;
|
||||
|
||||
this->Erase(pair);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,9 +143,7 @@ struct SmallMap : SmallVector<SmallPair<T, U>, S> {
|
||||
inline bool Insert(const T &key, const U &data)
|
||||
{
|
||||
if (this->Contains(key)) return false;
|
||||
Pair *n = this->Append();
|
||||
n->first = key;
|
||||
n->second = data;
|
||||
std::vector<Pair>::emplace_back(key, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -136,22 +155,13 @@ struct SmallMap : SmallVector<SmallPair<T, U>, S> {
|
||||
*/
|
||||
inline U &operator[](const T &key)
|
||||
{
|
||||
for (uint i = 0; i < this->items; i++) {
|
||||
if (key == this->data[i].first) return this->data[i].second;
|
||||
for (uint i = 0; i < std::vector<Pair>::size(); i++) {
|
||||
if (key == std::vector<Pair>::operator[](i).first) return std::vector<Pair>::operator[](i).second;
|
||||
}
|
||||
Pair *n = this->Append();
|
||||
n->first = key;
|
||||
return n->second;
|
||||
}
|
||||
|
||||
inline void SortByKey()
|
||||
{
|
||||
QSortT(this->Begin(), this->items, KeySorter);
|
||||
}
|
||||
|
||||
static int CDECL KeySorter(const Pair *a, const Pair *b)
|
||||
{
|
||||
return a->first - b->first;
|
||||
/*C++17: Pair &n = */ std::vector<Pair>::emplace_back();
|
||||
Pair &n = std::vector<Pair>::back();
|
||||
n.first = key;
|
||||
return n.second;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -46,13 +46,13 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
SmallMatrix() : data(NULL), width(0), height(0), capacity(0) {}
|
||||
SmallMatrix() : data(nullptr), width(0), height(0), capacity(0) {}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
* @param other The other matrix to copy.
|
||||
*/
|
||||
SmallMatrix(const SmallMatrix &other) : data(NULL), width(0), height(0), capacity(0)
|
||||
SmallMatrix(const SmallMatrix &other) : data(nullptr), width(0), height(0), capacity(0)
|
||||
{
|
||||
this->Assign(other);
|
||||
}
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
this->width = 0;
|
||||
this->capacity = 0;
|
||||
free(this->data);
|
||||
this->data = NULL;
|
||||
this->data = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,8 +216,8 @@ public:
|
||||
inline void Resize(uint new_width, uint new_height)
|
||||
{
|
||||
uint new_capacity = new_width * new_height;
|
||||
T *new_data = NULL;
|
||||
void (*copy)(T *dest, const T *src, size_t count) = NULL;
|
||||
T *new_data = nullptr;
|
||||
void (*copy)(T *dest, const T *src, size_t count) = nullptr;
|
||||
if (new_capacity > this->capacity) {
|
||||
/* If the data doesn't fit into current capacity, resize and copy ... */
|
||||
new_data = MallocT<T>(new_capacity);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define SMALLSTACK_TYPE_HPP
|
||||
|
||||
#include "smallvec_type.hpp"
|
||||
#include "../thread/thread.h"
|
||||
#include <mutex>
|
||||
|
||||
/**
|
||||
* A simplified pool which stores values instead of pointers and doesn't
|
||||
@@ -23,15 +23,14 @@
|
||||
template<typename Titem, typename Tindex, Tindex Tgrowth_step, Tindex Tmax_size>
|
||||
class SimplePool {
|
||||
public:
|
||||
inline SimplePool() : first_unused(0), first_free(0), mutex(ThreadMutex::New()) {}
|
||||
inline ~SimplePool() { delete this->mutex; }
|
||||
inline SimplePool() : first_unused(0), first_free(0) {}
|
||||
|
||||
/**
|
||||
* Get the mutex. We don't lock the mutex in the pool methods as the
|
||||
* SmallStack isn't necessarily in a consistent state after each method.
|
||||
* @return Mutex.
|
||||
*/
|
||||
inline ThreadMutex *GetMutex() { return this->mutex; }
|
||||
inline std::mutex &GetMutex() { return this->mutex; }
|
||||
|
||||
/**
|
||||
* Get the item at position index.
|
||||
@@ -73,8 +72,8 @@ private:
|
||||
if (!this->data[index].valid) return index;
|
||||
}
|
||||
|
||||
if (index >= this->data.Length() && index < Tmax_size) {
|
||||
this->data.Resize(index + 1);
|
||||
if (index >= this->data.size() && index < Tmax_size) {
|
||||
this->data.resize(index + 1);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
@@ -86,8 +85,8 @@ private:
|
||||
Tindex first_unused;
|
||||
Tindex first_free;
|
||||
|
||||
ThreadMutex *mutex;
|
||||
SmallVector<SimplePoolPoolItem, Tgrowth_step> data;
|
||||
std::mutex mutex;
|
||||
std::vector<SimplePoolPoolItem> data;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -106,6 +105,7 @@ struct SmallStackItem {
|
||||
*/
|
||||
inline SmallStackItem(const Titem &value, Tindex next) :
|
||||
next(next), value(value) {}
|
||||
SmallStackItem() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -195,7 +195,7 @@ public:
|
||||
inline void Push(const Titem &item)
|
||||
{
|
||||
if (this->value != Tinvalid) {
|
||||
ThreadMutexLocker lock(SmallStack::GetPool().GetMutex());
|
||||
std::lock_guard<std::mutex> lock(SmallStack::GetPool().GetMutex());
|
||||
Tindex new_item = SmallStack::GetPool().Create();
|
||||
if (new_item != Tmax_size) {
|
||||
PooledSmallStack &pushed = SmallStack::GetPool().Get(new_item);
|
||||
@@ -218,7 +218,7 @@ public:
|
||||
if (this->next == Tmax_size) {
|
||||
this->value = Tinvalid;
|
||||
} else {
|
||||
ThreadMutexLocker lock(SmallStack::GetPool().GetMutex());
|
||||
std::lock_guard<std::mutex> lock(SmallStack::GetPool().GetMutex());
|
||||
PooledSmallStack &popped = SmallStack::GetPool().Get(this->next);
|
||||
this->value = popped.value;
|
||||
if (popped.branch_count == 0) {
|
||||
@@ -257,7 +257,7 @@ public:
|
||||
{
|
||||
if (item == Tinvalid || item == this->value) return true;
|
||||
if (this->next != Tmax_size) {
|
||||
ThreadMutexLocker lock(SmallStack::GetPool().GetMutex());
|
||||
std::lock_guard<std::mutex> lock(SmallStack::GetPool().GetMutex());
|
||||
const SmallStack *in_list = this;
|
||||
do {
|
||||
in_list = static_cast<const SmallStack *>(
|
||||
@@ -281,7 +281,7 @@ protected:
|
||||
inline void Branch()
|
||||
{
|
||||
if (this->next != Tmax_size) {
|
||||
ThreadMutexLocker lock(SmallStack::GetPool().GetMutex());
|
||||
std::lock_guard<std::mutex> lock(SmallStack::GetPool().GetMutex());
|
||||
++(SmallStack::GetPool().Get(this->next).branch_count);
|
||||
}
|
||||
}
|
||||
|
||||
+26
-422
@@ -14,438 +14,42 @@
|
||||
|
||||
#include "alloc_func.hpp"
|
||||
#include "mem_func.hpp"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
/**
|
||||
* Simple vector template class.
|
||||
* Helper function to append an item to a vector if it is not already contained
|
||||
* Consider using std::set, std::unordered_set or std::flat_set in new code
|
||||
*
|
||||
* @note There are no asserts in the class so you have
|
||||
* to care about that you grab an item which is
|
||||
* inside the list.
|
||||
* @param vec A reference to the vector to be extended
|
||||
* @param item Reference to the item to be copy-constructed if not found
|
||||
*
|
||||
* @tparam T The type of the items stored
|
||||
* @tparam S The steps of allocation
|
||||
* @return Whether the item was already present
|
||||
*/
|
||||
template <typename T, uint S>
|
||||
class SmallVector {
|
||||
protected:
|
||||
T *data; ///< The pointer to the first item
|
||||
uint items; ///< The number of items stored
|
||||
uint capacity; ///< The available space for storing items
|
||||
|
||||
public:
|
||||
SmallVector() : data(NULL), items(0), capacity(0) { }
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
* @param other The other vector to copy.
|
||||
*/
|
||||
SmallVector(const SmallVector &other) : data(NULL), items(0), capacity(0)
|
||||
{
|
||||
this->Assign(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic copy constructor.
|
||||
* @param other The other vector to copy.
|
||||
*/
|
||||
template <uint X>
|
||||
SmallVector(const SmallVector<T, X> &other) : data(NULL), items(0), capacity(0)
|
||||
{
|
||||
this->Assign(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assignment.
|
||||
* @param other The other vector to assign.
|
||||
*/
|
||||
SmallVector &operator=(const SmallVector &other)
|
||||
{
|
||||
this->Assign(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic assignment.
|
||||
* @param other The other vector to assign.
|
||||
*/
|
||||
template <uint X>
|
||||
SmallVector &operator=(const SmallVector<T, X> &other)
|
||||
{
|
||||
this->Assign(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~SmallVector()
|
||||
{
|
||||
free(this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign items from other vector.
|
||||
*/
|
||||
template <uint X>
|
||||
inline void Assign(const SmallVector<T, X> &other)
|
||||
{
|
||||
if ((const void *)&other == (void *)this) return;
|
||||
|
||||
this->Clear();
|
||||
if (other.Length() > 0) MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all items from the list.
|
||||
*/
|
||||
inline void Clear()
|
||||
{
|
||||
/* In fact we just reset the item counter avoiding the need to
|
||||
* probably reallocate the same amount of memory the list was
|
||||
* previously using. */
|
||||
this->items = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all items from the list and free allocated memory.
|
||||
*/
|
||||
inline void Reset()
|
||||
{
|
||||
this->items = 0;
|
||||
this->capacity = 0;
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compact the list down to the smallest block size boundary.
|
||||
*/
|
||||
inline void Compact()
|
||||
{
|
||||
uint capacity = Align(this->items, S);
|
||||
if (capacity >= this->capacity) return;
|
||||
|
||||
this->capacity = capacity;
|
||||
this->data = ReallocT(this->data, this->capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append an item and return it.
|
||||
* @param to_add the number of items to append
|
||||
* @return pointer to newly allocated item
|
||||
*/
|
||||
inline T *Append(uint to_add = 1)
|
||||
{
|
||||
uint begin = this->items;
|
||||
this->items += to_add;
|
||||
|
||||
if (this->items > this->capacity) {
|
||||
this->capacity = Align(this->items, S);
|
||||
this->data = ReallocT(this->data, this->capacity);
|
||||
}
|
||||
|
||||
return &this->data[begin];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of the vector, effectively truncating items from the end or appending uninitialised ones.
|
||||
* @param num_items Target size.
|
||||
*/
|
||||
inline void Resize(uint num_items)
|
||||
{
|
||||
this->items = num_items;
|
||||
|
||||
if (this->items > this->capacity) {
|
||||
this->capacity = Align(this->items, S);
|
||||
this->data = ReallocT(this->data, this->capacity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new item at a specific position into the vector, moving all following items.
|
||||
* @param item Position at which the new item should be inserted
|
||||
* @return pointer to the new item
|
||||
*/
|
||||
inline T *Insert(T *item)
|
||||
{
|
||||
assert(item >= this->Begin() && item <= this->End());
|
||||
|
||||
size_t to_move = this->End() - item;
|
||||
size_t start = item - this->Begin();
|
||||
|
||||
this->Append();
|
||||
if (to_move > 0) MemMoveT(this->Begin() + start + 1, this->Begin() + start, to_move);
|
||||
return this->Begin() + start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first occurrence of an item.
|
||||
* The '!=' operator of T is used for comparison.
|
||||
* @param item Item to search for
|
||||
* @return The position of the item, or End() when not present
|
||||
*/
|
||||
inline const T *Find(const T &item) const
|
||||
{
|
||||
const T *pos = this->Begin();
|
||||
const T *end = this->End();
|
||||
while (pos != end && *pos != item) pos++;
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first occurrence of an item.
|
||||
* The '!=' operator of T is used for comparison.
|
||||
* @param item Item to search for
|
||||
* @return The position of the item, or End() when not present
|
||||
*/
|
||||
inline T *Find(const T &item)
|
||||
{
|
||||
T *pos = this->Begin();
|
||||
const T *end = this->End();
|
||||
while (pos != end && *pos != item) pos++;
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first occurrence of an item.
|
||||
* The '!=' operator of T is used for comparison.
|
||||
* @param item Item to search for
|
||||
* @return The position of the item, or -1 when not present
|
||||
*/
|
||||
inline int FindIndex(const T &item) const
|
||||
{
|
||||
int index = 0;
|
||||
const T *pos = this->Begin();
|
||||
const T *end = this->End();
|
||||
while (pos != end && *pos != item) {
|
||||
pos++;
|
||||
index++;
|
||||
}
|
||||
return pos == end ? -1 : index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a item is present in the vector.
|
||||
* The '!=' operator of T is used for comparison.
|
||||
* @param item Item to test for
|
||||
* @return true iff the item is present
|
||||
*/
|
||||
inline bool Contains(const T &item) const
|
||||
{
|
||||
return this->Find(item) != this->End();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes given item from this vector
|
||||
* @param item item to remove
|
||||
* @note it has to be pointer to item in this map. It is overwritten by the last item.
|
||||
*/
|
||||
inline void Erase(T *item)
|
||||
{
|
||||
assert(item >= this->Begin() && item < this->End());
|
||||
*item = this->data[--this->items];
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove items from the vector while preserving the order of other items.
|
||||
* @param pos First item to remove.
|
||||
* @param count Number of consecutive items to remove.
|
||||
*/
|
||||
void ErasePreservingOrder(uint pos, uint count = 1)
|
||||
{
|
||||
ErasePreservingOrder(this->data + pos, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove items from the vector while preserving the order of other items.
|
||||
* @param item First item to remove.
|
||||
* @param count Number of consecutive items to remove.
|
||||
*/
|
||||
inline void ErasePreservingOrder(T *item, uint count = 1)
|
||||
{
|
||||
if (count == 0) return;
|
||||
assert(item >= this->Begin());
|
||||
assert(item + count <= this->End());
|
||||
|
||||
this->items -= count;
|
||||
ptrdiff_t to_move = this->End() - item;
|
||||
if (to_move > 0) MemMoveT(item, item + count, to_move);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a item is present in the vector, and appends it to the end if not.
|
||||
* The '!=' operator of T is used for comparison.
|
||||
* @param item Item to test for
|
||||
* @return true iff the item is was already present
|
||||
*/
|
||||
inline bool Include(const T &item)
|
||||
{
|
||||
bool is_member = this->Contains(item);
|
||||
if (!is_member) *this->Append() = item;
|
||||
return is_member;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of items in the list.
|
||||
*
|
||||
* @return The number of items in the list.
|
||||
*/
|
||||
inline uint Length() const
|
||||
{
|
||||
return this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pointer to the first item (const)
|
||||
*
|
||||
* @return the pointer to the first item
|
||||
*/
|
||||
inline const T *Begin() const
|
||||
{
|
||||
return this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pointer to the first item
|
||||
*
|
||||
* @return the pointer to the first item
|
||||
*/
|
||||
inline T *Begin()
|
||||
{
|
||||
return this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pointer behind the last valid item (const)
|
||||
*
|
||||
* @return the pointer behind the last valid item
|
||||
*/
|
||||
inline const T *End() const
|
||||
{
|
||||
return &this->data[this->items];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pointer behind the last valid item
|
||||
*
|
||||
* @return the pointer behind the last valid item
|
||||
*/
|
||||
inline T *End()
|
||||
{
|
||||
return &this->data[this->items];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pointer to item "number" (const)
|
||||
*
|
||||
* @param index the position of the item
|
||||
* @return the pointer to the item
|
||||
*/
|
||||
inline const T *Get(uint index) const
|
||||
{
|
||||
/* Allow access to the 'first invalid' item */
|
||||
assert(index <= this->items);
|
||||
return &this->data[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pointer to item "number"
|
||||
*
|
||||
* @param index the position of the item
|
||||
* @return the pointer to the item
|
||||
*/
|
||||
inline T *Get(uint index)
|
||||
{
|
||||
/* Allow access to the 'first invalid' item */
|
||||
assert(index <= this->items);
|
||||
return &this->data[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item "number" (const)
|
||||
*
|
||||
* @param index the position of the item
|
||||
* @return the item
|
||||
*/
|
||||
inline const T &operator[](uint index) const
|
||||
{
|
||||
assert(index < this->items);
|
||||
return this->data[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item "number"
|
||||
*
|
||||
* @param index the position of the item
|
||||
* @return the item
|
||||
*/
|
||||
inline T &operator[](uint index)
|
||||
{
|
||||
assert(index < this->items);
|
||||
return this->data[index];
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline bool include(std::vector<T>& vec, const T &item)
|
||||
{
|
||||
const bool is_member = std::find(vec.begin(), vec.end(), item) != vec.end();
|
||||
if (!is_member) vec.emplace_back(item);
|
||||
return is_member;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple vector template class, with automatic free.
|
||||
* Helper function to get the index of an item
|
||||
* Consider using std::set, std::unordered_set or std::flat_set in new code
|
||||
*
|
||||
* @note There are no asserts in the class so you have
|
||||
* to care about that you grab an item which is
|
||||
* inside the list.
|
||||
* @param vec A reference to the vector to be extended
|
||||
* @param item Reference to the item to be search for
|
||||
*
|
||||
* @param T The type of the items stored, must be a pointer
|
||||
* @param S The steps of allocation
|
||||
* @return Index of element if found, otherwise -1
|
||||
*/
|
||||
template <typename T, uint S>
|
||||
class AutoFreeSmallVector : public SmallVector<T, S> {
|
||||
public:
|
||||
~AutoFreeSmallVector()
|
||||
{
|
||||
this->Clear();
|
||||
}
|
||||
template <typename T>
|
||||
int find_index(std::vector<T> const& vec, T const& item)
|
||||
{
|
||||
auto const it = std::find(vec.begin(), vec.end(), item);
|
||||
if (it != vec.end()) return it - vec.begin();
|
||||
|
||||
/**
|
||||
* Remove all items from the list.
|
||||
*/
|
||||
inline void Clear()
|
||||
{
|
||||
for (uint i = 0; i < this->items; i++) {
|
||||
free(this->data[i]);
|
||||
}
|
||||
|
||||
this->items = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple vector template class, with automatic delete.
|
||||
*
|
||||
* @note There are no asserts in the class so you have
|
||||
* to care about that you grab an item which is
|
||||
* inside the list.
|
||||
*
|
||||
* @param T The type of the items stored, must be a pointer
|
||||
* @param S The steps of allocation
|
||||
*/
|
||||
template <typename T, uint S>
|
||||
class AutoDeleteSmallVector : public SmallVector<T, S> {
|
||||
public:
|
||||
~AutoDeleteSmallVector()
|
||||
{
|
||||
this->Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all items from the list.
|
||||
*/
|
||||
inline void Clear()
|
||||
{
|
||||
for (uint i = 0; i < this->items; i++) {
|
||||
delete this->data[i];
|
||||
}
|
||||
|
||||
this->items = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef AutoFreeSmallVector<char*, 4> StringList; ///< Type for a list of strings.
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* SMALLVEC_TYPE_HPP */
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ unsigned __int64 ottd_rdtsc();
|
||||
#endif
|
||||
|
||||
/* rdtsc for all other *nix-en (hopefully). Use GCC syntax */
|
||||
#if (defined(__i386__) || defined(__x86_64__)) && !defined(__DJGPP__) && !defined(RDTSC_AVAILABLE)
|
||||
#if (defined(__i386__) || defined(__x86_64__)) && !defined(RDTSC_AVAILABLE)
|
||||
uint64 ottd_rdtsc()
|
||||
{
|
||||
uint32 high, low;
|
||||
|
||||
+42
-38
@@ -52,27 +52,27 @@
|
||||
# include <ft2build.h>
|
||||
# include FT_FREETYPE_H
|
||||
#endif /* WITH_FREETYPE */
|
||||
#if defined(WITH_ICU_LAYOUT) || defined(WITH_ICU_SORT)
|
||||
#if defined(WITH_ICU_LX) || defined(WITH_ICU_I18N)
|
||||
# include <unicode/uversion.h>
|
||||
#endif /* WITH_ICU_SORT || WITH_ICU_LAYOUT */
|
||||
#ifdef WITH_LZMA
|
||||
#endif /* WITH_ICU_LX || WITH_ICU_I18N */
|
||||
#ifdef WITH_LIBLZMA
|
||||
# include <lzma.h>
|
||||
#endif
|
||||
#ifdef WITH_LZO
|
||||
#include <lzo/lzo1x.h>
|
||||
#endif
|
||||
#ifdef WITH_SDL
|
||||
#if defined(WITH_SDL) || defined(WITH_SDL2)
|
||||
# include <SDL.h>
|
||||
#endif /* WITH_SDL */
|
||||
#endif /* WITH_SDL || WITH_SDL2 */
|
||||
#ifdef WITH_ZLIB
|
||||
# include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
/* static */ const char *CrashLog::message = NULL;
|
||||
/* static */ char *CrashLog::gamelog_buffer = NULL;
|
||||
/* static */ const char *CrashLog::gamelog_last = NULL;
|
||||
/* static */ const char *CrashLog::message = nullptr;
|
||||
/* static */ char *CrashLog::gamelog_buffer = nullptr;
|
||||
/* static */ const char *CrashLog::gamelog_last = nullptr;
|
||||
|
||||
char *CrashLog::LogCompiler(char *buffer, const char *last) const
|
||||
{
|
||||
@@ -168,18 +168,18 @@ char *CrashLog::LogConfiguration(char *buffer, const char *last) const
|
||||
" Sound driver: %s\n"
|
||||
" Sound set: %s (%u)\n"
|
||||
" Video driver: %s\n\n",
|
||||
BlitterFactory::GetCurrentBlitter() == NULL ? "none" : BlitterFactory::GetCurrentBlitter()->GetName(),
|
||||
BaseGraphics::GetUsedSet() == NULL ? "none" : BaseGraphics::GetUsedSet()->name,
|
||||
BaseGraphics::GetUsedSet() == NULL ? UINT32_MAX : BaseGraphics::GetUsedSet()->version,
|
||||
_current_language == NULL ? "none" : _current_language->file,
|
||||
MusicDriver::GetInstance() == NULL ? "none" : MusicDriver::GetInstance()->GetName(),
|
||||
BaseMusic::GetUsedSet() == NULL ? "none" : BaseMusic::GetUsedSet()->name,
|
||||
BaseMusic::GetUsedSet() == NULL ? UINT32_MAX : BaseMusic::GetUsedSet()->version,
|
||||
BlitterFactory::GetCurrentBlitter() == nullptr ? "none" : BlitterFactory::GetCurrentBlitter()->GetName(),
|
||||
BaseGraphics::GetUsedSet() == nullptr ? "none" : BaseGraphics::GetUsedSet()->name,
|
||||
BaseGraphics::GetUsedSet() == nullptr ? UINT32_MAX : BaseGraphics::GetUsedSet()->version,
|
||||
_current_language == nullptr ? "none" : _current_language->file,
|
||||
MusicDriver::GetInstance() == nullptr ? "none" : MusicDriver::GetInstance()->GetName(),
|
||||
BaseMusic::GetUsedSet() == nullptr ? "none" : BaseMusic::GetUsedSet()->name,
|
||||
BaseMusic::GetUsedSet() == nullptr ? UINT32_MAX : BaseMusic::GetUsedSet()->version,
|
||||
_networking ? (_network_server ? "server" : "client") : "no",
|
||||
SoundDriver::GetInstance() == NULL ? "none" : SoundDriver::GetInstance()->GetName(),
|
||||
BaseSounds::GetUsedSet() == NULL ? "none" : BaseSounds::GetUsedSet()->name,
|
||||
BaseSounds::GetUsedSet() == NULL ? UINT32_MAX : BaseSounds::GetUsedSet()->version,
|
||||
VideoDriver::GetInstance() == NULL ? "none" : VideoDriver::GetInstance()->GetName()
|
||||
SoundDriver::GetInstance() == nullptr ? "none" : SoundDriver::GetInstance()->GetName(),
|
||||
BaseSounds::GetUsedSet() == nullptr ? "none" : BaseSounds::GetUsedSet()->name,
|
||||
BaseSounds::GetUsedSet() == nullptr ? UINT32_MAX : BaseSounds::GetUsedSet()->version,
|
||||
VideoDriver::GetInstance() == nullptr ? "none" : VideoDriver::GetInstance()->GetName()
|
||||
);
|
||||
|
||||
buffer += seprintf(buffer, last,
|
||||
@@ -197,14 +197,14 @@ char *CrashLog::LogConfiguration(char *buffer, const char *last) const
|
||||
buffer += seprintf(buffer, last, "AI Configuration (local: %i) (current: %i):\n", (int)_local_company, (int)_current_company);
|
||||
const Company *c;
|
||||
FOR_ALL_COMPANIES(c) {
|
||||
if (c->ai_info == NULL) {
|
||||
if (c->ai_info == nullptr) {
|
||||
buffer += seprintf(buffer, last, " %2i: Human\n", (int)c->index);
|
||||
} else {
|
||||
buffer += seprintf(buffer, last, " %2i: %s (v%d)\n", (int)c->index, c->ai_info->GetName(), c->ai_info->GetVersion());
|
||||
}
|
||||
}
|
||||
|
||||
if (Game::GetInfo() != NULL) {
|
||||
if (Game::GetInfo() != nullptr) {
|
||||
buffer += seprintf(buffer, last, " GS: %s (v%d)\n", Game::GetInfo()->GetName(), Game::GetInfo()->GetVersion());
|
||||
}
|
||||
buffer += seprintf(buffer, last, "\n");
|
||||
@@ -240,21 +240,21 @@ char *CrashLog::LogLibraries(char *buffer, const char *last) const
|
||||
buffer += seprintf(buffer, last, " FreeType: %d.%d.%d\n", major, minor, patch);
|
||||
#endif /* WITH_FREETYPE */
|
||||
|
||||
#if defined(WITH_ICU_LAYOUT) || defined(WITH_ICU_SORT)
|
||||
#if defined(WITH_ICU_LX) || defined(WITH_ICU_I18N)
|
||||
/* 4 times 0-255, separated by dots (.) and a trailing '\0' */
|
||||
char buf[4 * 3 + 3 + 1];
|
||||
UVersionInfo ver;
|
||||
u_getVersion(ver);
|
||||
u_versionToString(ver, buf);
|
||||
#ifdef WITH_ICU_SORT
|
||||
#ifdef WITH_ICU_I18N
|
||||
buffer += seprintf(buffer, last, " ICU i18n: %s\n", buf);
|
||||
#endif
|
||||
#ifdef WITH_ICU_LAYOUT
|
||||
#ifdef WITH_ICU_LX
|
||||
buffer += seprintf(buffer, last, " ICU lx: %s\n", buf);
|
||||
#endif
|
||||
#endif /* WITH_ICU_SORT || WITH_ICU_LAYOUT */
|
||||
#endif /* WITH_ICU_LX || WITH_ICU_I18N */
|
||||
|
||||
#ifdef WITH_LZMA
|
||||
#ifdef WITH_LIBLZMA
|
||||
buffer += seprintf(buffer, last, " LZMA: %s\n", lzma_version_string());
|
||||
#endif
|
||||
|
||||
@@ -263,13 +263,17 @@ char *CrashLog::LogLibraries(char *buffer, const char *last) const
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PNG
|
||||
buffer += seprintf(buffer, last, " PNG: %s\n", png_get_libpng_ver(NULL));
|
||||
buffer += seprintf(buffer, last, " PNG: %s\n", png_get_libpng_ver(nullptr));
|
||||
#endif /* WITH_PNG */
|
||||
|
||||
#ifdef WITH_SDL
|
||||
const SDL_version *v = SDL_Linked_Version();
|
||||
buffer += seprintf(buffer, last, " SDL: %d.%d.%d\n", v->major, v->minor, v->patch);
|
||||
#endif /* WITH_SDL */
|
||||
const SDL_version *sdl_v = SDL_Linked_Version();
|
||||
buffer += seprintf(buffer, last, " SDL1: %d.%d.%d\n", sdl_v->major, sdl_v->minor, sdl_v->patch);
|
||||
#elif defined(WITH_SDL2)
|
||||
SDL_version sdl2_v;
|
||||
SDL_GetVersion(&sdl2_v);
|
||||
buffer += seprintf(buffer, last, " SDL2: %d.%d.%d\n", sdl2_v.major, sdl2_v.minor, sdl2_v.patch);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ZLIB
|
||||
buffer += seprintf(buffer, last, " Zlib: %s\n", zlibVersion());
|
||||
@@ -313,7 +317,7 @@ char *CrashLog::LogRecentNews(char *buffer, const char *last) const
|
||||
buffer += seprintf(buffer, last, "Recent news messages:\n");
|
||||
|
||||
int i = 0;
|
||||
for (NewsItem *news = _latest_news; i < 32 && news != NULL; news = news->prev, i++) {
|
||||
for (NewsItem *news = _latest_news; i < 32 && news != nullptr; news = news->prev, i++) {
|
||||
YearMonthDay ymd;
|
||||
ConvertDateToYMD(news->date, &ymd);
|
||||
buffer += seprintf(buffer, last, "(%i-%02i-%02i) StringID: %u, Type: %u, Ref1: %u, %u, Ref2: %u, %u\n",
|
||||
@@ -332,7 +336,7 @@ char *CrashLog::LogRecentNews(char *buffer, const char *last) const
|
||||
*/
|
||||
char *CrashLog::FillCrashLog(char *buffer, const char *last) const
|
||||
{
|
||||
time_t cur_time = time(NULL);
|
||||
time_t cur_time = time(nullptr);
|
||||
buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n");
|
||||
buffer += seprintf(buffer, last, "Crash at: %s", asctime(gmtime(&cur_time)));
|
||||
|
||||
@@ -370,7 +374,7 @@ bool CrashLog::WriteCrashLog(const char *buffer, char *filename, const char *fil
|
||||
seprintf(filename, filename_last, "%scrash.log", _personal_dir);
|
||||
|
||||
FILE *file = FioFOpenFile(filename, "w", NO_DIRECTORY);
|
||||
if (file == NULL) return false;
|
||||
if (file == nullptr) return false;
|
||||
|
||||
size_t len = strlen(buffer);
|
||||
size_t written = fwrite(buffer, 1, len, file);
|
||||
@@ -397,7 +401,7 @@ bool CrashLog::WriteSavegame(char *filename, const char *filename_last) const
|
||||
{
|
||||
/* If the map array doesn't exist, saving will fail too. If the map got
|
||||
* initialised, there is a big chance the rest is initialised too. */
|
||||
if (_m == NULL) return false;
|
||||
if (_m == nullptr) return false;
|
||||
|
||||
try {
|
||||
GamelogEmergency();
|
||||
@@ -422,7 +426,7 @@ bool CrashLog::WriteSavegame(char *filename, const char *filename_last) const
|
||||
bool CrashLog::WriteScreenshot(char *filename, const char *filename_last) const
|
||||
{
|
||||
/* Don't draw when we have invalid screen size */
|
||||
if (_screen.width < 1 || _screen.height < 1 || _screen.dst_ptr == NULL) return false;
|
||||
if (_screen.width < 1 || _screen.height < 1 || _screen.dst_ptr == nullptr) return false;
|
||||
|
||||
bool res = MakeScreenshot(SC_CRASHLOG, "crash");
|
||||
if (res) strecpy(filename, _full_screenshot_name, filename_last);
|
||||
@@ -505,7 +509,7 @@ bool CrashLog::MakeCrashLog() const
|
||||
*/
|
||||
/* static */ void CrashLog::AfterCrashLogCleanup()
|
||||
{
|
||||
if (MusicDriver::GetInstance() != NULL) MusicDriver::GetInstance()->Stop();
|
||||
if (SoundDriver::GetInstance() != NULL) SoundDriver::GetInstance()->Stop();
|
||||
if (VideoDriver::GetInstance() != NULL) VideoDriver::GetInstance()->Stop();
|
||||
if (MusicDriver::GetInstance() != nullptr) MusicDriver::GetInstance()->Stop();
|
||||
if (SoundDriver::GetInstance() != nullptr) SoundDriver::GetInstance()->Stop();
|
||||
if (VideoDriver::GetInstance() != nullptr) VideoDriver::GetInstance()->Stop();
|
||||
}
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ protected:
|
||||
* Writes actually encountered error to the buffer.
|
||||
* @param buffer The begin where to write at.
|
||||
* @param last The last position in the buffer to write to.
|
||||
* @param message Message passed to use for possible errors. Can be NULL.
|
||||
* @param message Message passed to use for possible errors. Can be nullptr.
|
||||
* @return the position of the \c '\0' character after the buffer.
|
||||
*/
|
||||
virtual char *LogError(char *buffer, const char *last, const char *message) const = 0;
|
||||
|
||||
@@ -64,6 +64,9 @@ static const CurrencySpec origin_currency_specs[CURRENCY_END] = {
|
||||
{ 4901, "", CF_NOEURO, "", NBSP "Rls", 1, STR_GAME_OPTIONS_CURRENCY_IRR }, ///< Iranian Rial
|
||||
{ 80, "", CF_NOEURO, "", NBSP "rub", 1, STR_GAME_OPTIONS_CURRENCY_RUB }, ///< New Russian Ruble
|
||||
{ 24, "", CF_NOEURO, "$", "", 0, STR_GAME_OPTIONS_CURRENCY_MXN }, ///< Mexican peso
|
||||
{ 40, "", CF_NOEURO, "NTD" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_NTD }, ///< new taiwan dollar
|
||||
{ 8, "", CF_NOEURO, "\xC2\xA5", "", 0, STR_GAME_OPTIONS_CURRENCY_CNY }, ///< chinese renminbi
|
||||
{ 10, "", CF_NOEURO, "HKD" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_HKD }, ///< hong kong dollar
|
||||
};
|
||||
|
||||
/** Array of currencies used by the system */
|
||||
|
||||
@@ -60,6 +60,9 @@ enum Currencies {
|
||||
CURRENCY_IRR, ///< Iranian Rial
|
||||
CURRENCY_RUB, ///< New Russian Ruble
|
||||
CURRENCY_MXN, ///< Mexican Peso
|
||||
CURRENCY_NTD, ///< New Taiwan Dollar
|
||||
CURRENCY_CNY, ///< Chinese Renminbi
|
||||
CURRENCY_HKD, ///< Hong Kong Dollar
|
||||
CURRENCY_END, ///< always the last item
|
||||
};
|
||||
|
||||
|
||||
@@ -195,9 +195,7 @@ static void OnNewYear()
|
||||
VehiclesYearlyLoop();
|
||||
TownsYearlyLoop();
|
||||
InvalidateWindowClassesData(WC_BUILD_STATION);
|
||||
#ifdef ENABLE_NETWORK
|
||||
if (_network_server) NetworkServerYearlyLoop();
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
if (_cur_year == _settings_client.gui.semaphore_build_before) ResetSignalVariant();
|
||||
|
||||
@@ -217,11 +215,9 @@ static void OnNewYear()
|
||||
LinkGraph *lg;
|
||||
FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(-days_this_year);
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
/* Because the _date wraps here, and text-messages expire by game-days, we have to clean out
|
||||
* all of them if the date is set back, else those messages will hang for ever */
|
||||
NetworkInitChatMessage();
|
||||
#endif /* ENABLE_NETWORK */
|
||||
}
|
||||
|
||||
if (_settings_client.gui.auto_euro) CheckSwitchToEuro();
|
||||
@@ -244,9 +240,7 @@ static void OnNewMonth()
|
||||
IndustryMonthlyLoop();
|
||||
SubsidyMonthlyLoop();
|
||||
StationMonthlyLoop();
|
||||
#ifdef ENABLE_NETWORK
|
||||
if (_network_server) NetworkServerMonthlyLoop();
|
||||
#endif /* ENABLE_NETWORK */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,9 +248,7 @@ static void OnNewMonth()
|
||||
*/
|
||||
static void OnNewDay()
|
||||
{
|
||||
#ifdef ENABLE_NETWORK
|
||||
if (_network_server) NetworkServerDailyLoop();
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
DisasterDailyLoop();
|
||||
IndustryDailyLoop();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user