Update to 1.10.0-beta1

This commit is contained in:
dP
2019-10-31 22:24:28 +03:00
parent b84a475e14
commit 599ccf0c2b
1470 changed files with 354219 additions and 16795 deletions
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+6 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();
/**
+7 -3
View File
@@ -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();
+6 -6
View File
@@ -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 */
+8 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
/**
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+8 -8
View File
@@ -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();
}
+15 -15
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+2 -2
View File
@@ -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
View File
@@ -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);
}
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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--;
+9 -3
View File
@@ -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;
}
/**
+137
View File
@@ -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 */
+2 -2
View File
@@ -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
View File
@@ -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 */
+3 -3
View File
@@ -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 */
+5 -5
View File
@@ -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
View File
@@ -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.
+2 -2
View File
@@ -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) {
+4 -4
View File
@@ -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 */
+5 -5
View File
@@ -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 */
+4 -4
View File
@@ -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 */
+3 -3
View File
@@ -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 */
+3 -3
View File
@@ -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
View File
@@ -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 */
+4 -4
View File
@@ -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++;
+4 -4
View File
@@ -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 */
+4 -4
View File
@@ -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 */
+7 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -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
View File
@@ -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));
}
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+5 -5
View File
@@ -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__) */
+1 -1
View File
@@ -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>
-106
View File
@@ -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 */
+14 -5
View File
@@ -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 */
+486
View File
@@ -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
+9 -9
View File
@@ -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);
}
}
+2 -2
View File
@@ -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));
}
+3 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
};
+5 -5
View File
@@ -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);
+12 -12
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+3
View File
@@ -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 */
+3
View File
@@ -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
};
-8
View File
@@ -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