Fix compilation errors after the merge

This commit is contained in:
dP
2025-06-27 18:03:03 +05:00
parent f0f93c68ca
commit 0fe7c3635c
85 changed files with 1926 additions and 1971 deletions

View File

@@ -5,7 +5,7 @@ from pathlib import Path
from pprint import pprint
RX_COMMAND = re.compile(r'(?P<returns>CommandCost|std::tuple<CommandCost, [^>]*>) (?P<name>Cmd\w*)\((?P<args>[^)]*)\);')
RX_DEF_TRAIT = re.compile(r'DEF_CMD_TRAIT\((?P<constant>\w+),\s+(?P<function>\w+),\s+(?P<flags>[^,]*),\s+(?P<category>\w+)\)')
RX_DEF_TRAIT = re.compile(r'DEF_CMD_TRAIT\((?P<constant>\w+),\s+(?P<function>\w+),\s+(?P<flags>[^,()]+(?:\([^)]+\))?),\s+(?P<category>\w+)\)')
RX_ARG = re.compile(r'(?P<type>(:?const |)[\w:]* &?)(?P<name>\w*)')
RX_CALLBACK = re.compile(r'void\s+(?P<name>Cc\w+)\(Commands')
RX_CALLBACK_REF = re.compile(r'CommandCallback(?:Data|)\s+(?P<name>Cc\w+);')
@@ -128,7 +128,7 @@ def parse_commands():
at = '::' + at
args[i] = (at, an)
do_args = args[:]
if 'CMD_LOCATION' in flags:
if 'Location' in flags:
args = [('TileIndex', 'location')] + args
print(cid, constant, category, args)
callback_args = 'CommandCost' if result_type is None else f'CommandCost, {result_type}'
@@ -139,9 +139,9 @@ def parse_commands():
area_code = cc
default_run_as = 'INVALID_COMPANY'
if 'CMD_DEITY' in flags:
if 'Deity' in flags:
default_run_as = 'OWNER_DEITY'
if 'CMD_SERVER' in flags or 'CMD_SPECTATOR' in flags:
if 'Server' in flags or 'CMD_SPECTATOR' in flags:
default_run_as = 'COMPANY_SPECTATOR' # same as INVALID though
res.append({
@@ -184,8 +184,8 @@ struct CallbackArgsHelper<void(*const)(Commands, const CommandCost &, Targs...)>
#endif
static size_t FindCallbackIndex(::CommandCallback *callback) {
if (auto it = std::find(std::cbegin(_callback_table), std::cend(_callback_table), callback); it != std::cend(_callback_table)) {
return static_cast<size_t>(std::distance(std::cbegin(_callback_table), it));
if (auto it = std::ranges::find(_callback_table, callback); it != std::end(_callback_table)) {
return static_cast<size_t>(std::distance(std::begin(_callback_table), it));
}
return std::numeric_limits<size_t>::max();
}
@@ -266,7 +266,7 @@ def run():
f' ~{name}() override {{}}\n'
f'\n'
f' bool _post(::CommandCallback * callback) override;\n'
f' CommandCost _do(DoCommandFlag flags) override;\n'
f' CommandCost _do(DoCommandFlags flags) override;\n'
f' Commands get_command() override;\n'
f'}};\n\n'
)
@@ -321,7 +321,7 @@ def run():
f'bool {name}::_post(::CommandCallback *callback) {{\n'
f' return _{name}_dispatch[FindCallbackIndex(callback)](this->error{sep_this_args_list});\n'
'}\n'
f'CommandCost {name}::_do(DoCommandFlag flags) {{\n'
f'CommandCost {name}::_do(DoCommandFlags flags) {{\n'
f' return {cost_getter}(::Command<{constant}>::Do(flags, {test_args_list}));\n'
'}\n'
)

View File

@@ -433,9 +433,7 @@ public:
return GetString(this->sel_roadtype == INVALID_ROADTYPE ? STR_REPLACE_ALL_ROADTYPE : GetRoadTypeInfo(this->sel_roadtype)->strings.replace_text);
case WID_RV_SHOW_HIDDEN_ENGINES:
SetDParam(0, this->cm_num_hidden_engines);
TODO
break;
return GetString(CM_STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN + this->vehicle_type, this->cm_num_hidden_engines);
default:
return this->Window::GetWidgetString(widget, stringid);
@@ -753,7 +751,7 @@ static constexpr NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetToolTip(STR_TOOLTIP_SORT_CRITERIA),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetStringTip(CM_STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetToolTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
EndContainer(),
EndContainer(),

View File

@@ -111,7 +111,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
} else {
uint r = remap[GB(m, 0, 8)];
*anim = r | (m & 0xFF00);
if (r != 0) *dst = this->AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
if (r != 0) *dst = AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
}
anim++;
dst++;
@@ -127,7 +127,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
} else {
uint r = remap[GB(m, 0, 8)];
*anim = 0;
if (r != 0) *dst = ComposeColourPANoCheck(this->AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8)), src_px->a, *dst);
if (r != 0) *dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8)), src_px->a, *dst);
}
anim++;
dst++;

View File

@@ -334,7 +334,7 @@ bmcr_alpha_blend_single:
}
break;
case CM_BM_TINT_REMAP:
case BlitterMode::CMTintRemap:
for (uint x = (uint) bp->width; x > 0; x--) {
if (src_mv->m == 0) {
if (src->a != 0) {
@@ -343,7 +343,7 @@ bmcr_alpha_blend_single:
}
} else {
uint r = remap[src_mv->m];
if (r != 0) *dst = ComposeColourPANoCheck(this->AdjustBrightness(this->LookupColourInPalette(r), src_mv->v), src->a, *dst);
if (r != 0) *dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(r), src_mv->v), src->a, *dst);
}
src_mv++;
dst++;
@@ -450,11 +450,11 @@ bm_normal:
break;
case BlitterMode::CMTintRemap:
if (bp->skip_left != 0 || bp->width <= MARGIN_REMAP_THRESHOLD) {
if (sprite_flags & SF_NO_ANIM) Draw<BlitterMode::CMTintRemap, RM_WITH_SKIP, BT_NONE, true, false>(bp, zoom);
else Draw<BlitterMode::CMTintRemap, RM_WITH_SKIP, BT_NONE, true, true>(bp, zoom);
if (sprite_flags.Test(SpriteFlag::NoAnim)) Draw<BlitterMode::CMTintRemap, RM_WITH_SKIP, BT_NONE, true, false>(bp, zoom);
else Draw<BlitterMode::CMTintRemap, RM_WITH_SKIP, BT_NONE, true, true>(bp, zoom);
} else {
if (sprite_flags & SF_NO_ANIM) Draw<BlitterMode::CMTintRemap, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
else Draw<BlitterMode::CMTintRemap, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
if (sprite_flags.Test(SpriteFlag::NoAnim)) Draw<BlitterMode::CMTintRemap, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
else Draw<BlitterMode::CMTintRemap, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
}
break;
case BlitterMode::Transparent: Draw<BlitterMode::Transparent, RM_NONE, BT_NONE, true, true>(bp, zoom); return;

View File

@@ -122,7 +122,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
*dst = citymania::Remap32RGB(src_px->r, src_px->g, src_px->b, remap);
} else {
uint r = remap[GB(m, 0, 8)];
if (r != 0) *dst = this->AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
if (r != 0) *dst = AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
}
dst++;
src_px++;
@@ -135,7 +135,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
*dst = citymania::Remap32RGBANoCheck(src_px->r, src_px->g, src_px->b, src_px->a, *dst, remap);
} else {
uint r = remap[GB(m, 0, 8)];
if (r != 0) *dst = ComposeColourPANoCheck(this->AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8)), src_px->a, *dst);
if (r != 0) *dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8)), src_px->a, *dst);
}
dst++;
src_px++;

View File

@@ -44,7 +44,7 @@ void Blitter_32bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoo
if (src->m == 0) {
if (src->a != 0) *dst = citymania::Remap32RGBA(src->r, src->g, src->b, src->a, *dst, bp->remap);
} else {
if (bp->remap[src->m] != 0) *dst = ComposeColourPA(this->AdjustBrightness(this->LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst);
if (bp->remap[src->m] != 0) *dst = ComposeColourPA(AdjustBrightness(this->LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst);
}
break;

View File

@@ -421,7 +421,7 @@ bmcr_alpha_blend_single:
}
} else {
uint r = remap[src_mv->m];
if (r != 0) *dst = ComposeColourPANoCheck(this->AdjustBrightness(this->LookupColourInPalette(r), src_mv->v), src->a, *dst);
if (r != 0) *dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(r), src_mv->v), src->a, *dst);
}
src_mv++;
dst++;
@@ -513,9 +513,9 @@ bm_normal:
case BlitterMode::BlackRemap: Draw<BlitterMode::BlackRemap, RM_NONE, BT_NONE, true>(bp, zoom); return;
case BlitterMode::CMTintRemap:
if (bp->skip_left != 0 || bp->width <= MARGIN_REMAP_THRESHOLD) {
Draw<CM_BM_TINT_REMAP, RM_WITH_SKIP, BT_NONE, true>(bp, zoom); return;
Draw<BlitterMode::CMTintRemap, RM_WITH_SKIP, BT_NONE, true>(bp, zoom); return;
} else {
Draw<CM_BM_TINT_REMAP, RM_WITH_MARGIN, BT_NONE, true>(bp, zoom); return;
Draw<BlitterMode::CMTintRemap, RM_WITH_MARGIN, BT_NONE, true>(bp, zoom); return;
}
}
}

View File

@@ -184,7 +184,7 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
switch (mode) {
case BlitterMode::ColourRemap:
case BlitterMode::CMTintRemap;
case BlitterMode::CMTintRemap:
case BlitterMode::CrashRemap:
if (src_px->a == 255) {
do {

View File

@@ -858,9 +858,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number,
bool articulated_cargo = false;
if (_settings_client.gui.newgrf_developer_tools) {
SetDParam(0, e->index);
SetDParam(1, e->grf_prop.local_id);
DrawString(left, right, y, CM_STR_PURCHASE_ENGINE_ID);
DrawString(left, right, y, GetString(CM_STR_PURCHASE_ENGINE_ID, e->index, e->grf_prop.local_id));
y += GetCharacterHeight(FS_NORMAL);
}
@@ -1209,7 +1207,7 @@ struct BuildVehicleWindow : Window {
widget->SetStringTip(STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON + type, STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP + type);
widget = this->GetWidget<NWidgetCore>(WID_BV_SHOW_HIDDEN_ENGINES);
widget->SetStringTip(CM_STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN + type, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP + type);
widget->SetToolTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP + type);
widget->SetLowered(this->show_hidden_engines);
this->details_height = ((this->vehicle_type == VEH_TRAIN) ? 10 : 9);
@@ -1334,7 +1332,7 @@ struct BuildVehicleWindow : Window {
// CM this->SelectEngine(this->eng_list[0].engine_id);
return this->eng_list[0].engine_id;
}
return INVALID_ENGINE;
return EngineID::Invalid();
}
/** Filter a single engine */
@@ -1556,7 +1554,7 @@ struct BuildVehicleWindow : Window {
this->eng_list.clear();
GUIEngineList list;
EngineID sel_id = INVALID_ENGINE; // CM
EngineID sel_id = EngineID::Invalid(); // CM
switch (this->vehicle_type) {
default: NOT_REACHED();
@@ -1782,10 +1780,7 @@ struct BuildVehicleWindow : Window {
}
case WID_BV_SHOW_HIDDEN_ENGINES:
TODO
return GetString()
SetDParam(0, this->cm_num_hidden_engines);
break;
return GetString(CM_STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN + this->vehicle_type, this->cm_num_hidden_engines);
default:
return this->Window::GetWidgetString(widget, stringid);

View File

@@ -56,6 +56,8 @@ add_files(
cm_survey.cpp
cm_tooltips.hpp
cm_tooltips.cpp
cm_town_gui.hpp
cm_town_gui.cpp
cm_newgrf_revisions.hpp
cm_watch_gui.hpp
cm_watch_gui.cpp

View File

@@ -629,7 +629,7 @@ void BuildBlueprint(sp<Blueprint> &blueprint, TileIndex start) {
scmd.station_to_join = station_id;
scmd.post();
}
if (!sign_part) ::Command<CMD_REMOVE_FROM_RAIL_STATION>::Post(tile, 0, false);
if (!sign_part) ::Command<CMD_REMOVE_FROM_RAIL_STATION>::Post(tile, (TileIndex)0, false);
return true;
}
).post();
@@ -672,8 +672,7 @@ bool LoadBlueprint(uint slot) {
if (slot >= MAX_BLUEPRINT_SLOTS) return false;
_active_blueprint = {INVALID_TILE, _blueprint_slots[slot]};
if (_active_blueprint.second == nullptr) {
SetDParam(0, slot);
ShowErrorMessage(CM_STR_NO_BLUEPRINT_IN_SLOT, INVALID_STRING_ID, WL_ERROR);
ShowErrorMessage(GetEncodedString(CM_STR_NO_BLUEPRINT_IN_SLOT, slot), {}, WL_ERROR);
}
return _active_blueprint.second != nullptr;
}

View File

@@ -28,8 +28,7 @@ enum CargoOption {
static void DrawPrice(Money amount, int left, int right, int top)
{
SetDParam(0, amount);
DrawString(left, right, top, STR_FINANCES_POSITIVE_INCOME, TC_FROMSTRING, SA_RIGHT);
DrawString(left, right, top, GetString(STR_FINANCES_POSITIVE_INCOME, amount), TC_FROMSTRING, SA_RIGHT);
}
void InvalidateCargosWindows(CompanyID cid)
@@ -48,10 +47,9 @@ struct CargosWindow : Window {
this->cargoPeriod = WID_CT_OPTION_CARGO_TOTAL;
}
void SetStringParameters(int widget) const override {
if(widget != WID_CT_CAPTION) return;
SetDParam(0, (CompanyID)this->window_number);
SetDParam(1, (CompanyID)this->window_number);
std::string GetWidgetString(WidgetID widget, StringID stringid) const override {
if(widget != WID_CT_CAPTION) return this->Window::GetWidgetString(widget, stringid);
return GetString(CM_STR_TOOLBAR_CARGOS_CAPTION, (CompanyID)this->window_number, (CompanyID)this->window_number);
}
void OnClick([[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count) override {
@@ -133,8 +131,7 @@ struct CargosWindow : Window {
r.left + max_icon_size.width - icon_size.width,
y + (line_height - (int)icon_size.height) / 2);
SetDParam(0, cs->name);
DrawString(rect_x + icon_space, r.right, y + text_y_ofs, CM_STR_TOOLBAR_CARGOS_NAME);
DrawString(rect_x + icon_space, r.right, y + text_y_ofs, GetString(CM_STR_TOOLBAR_CARGOS_NAME, cs->name));
y += line_height;
}
@@ -151,16 +148,14 @@ struct CargosWindow : Window {
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
auto &economy = (this->cargoPeriod == WID_CT_OPTION_CARGO_MONTH ? c->old_economy[0] : c->cur_economy);
sum_cargo_amount += economy.delivered_cargo[cs->Index()];
SetDParam(0, economy.delivered_cargo[cs->Index()]);
DrawString(r.left, r.right, y + text_y_ofs, CM_STR_TOOLBAR_CARGOS_UNITS, TC_FROMSTRING, SA_RIGHT); //cargo amount in pcs
DrawString(r.left, r.right, y + text_y_ofs, GetString(CM_STR_TOOLBAR_CARGOS_UNITS, economy.delivered_cargo[cs->Index()]), TC_FROMSTRING, SA_RIGHT); //cargo amount in pcs
y += line_height;
}
GfxFillRect(r.left, y + 1, r.right, y + 1, PC_BLACK);
y += CT_LINESPACE;
SetDParam(0, sum_cargo_amount);
DrawString(r.left, r.right, y, CM_STR_TOOLBAR_CARGOS_UNITS_TOTAL, TC_FROMSTRING, SA_RIGHT);
DrawString(r.left, r.right, y, GetString(CM_STR_TOOLBAR_CARGOS_UNITS_TOTAL, sum_cargo_amount), TC_FROMSTRING, SA_RIGHT);
break;
case WID_CT_INCOME:
@@ -184,15 +179,15 @@ struct CargosWindow : Window {
static const NWidgetPart _nested_cargos_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_CT_CAPTION), SetDataTip(CM_STR_TOOLBAR_CARGOS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_CT_CAPTION),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 1),
NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::scaled.framerect.top, WidgetDimensions::scaled.framerect.right, WidgetDimensions::scaled.framerect.bottom, WidgetDimensions::scaled.framerect.left), SetPIP(0, 9, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CT_HEADER_CARGO), SetFill(1, 0), SetPadding(2,2,2,2), SetDataTip(CM_STR_TOOLBAR_CARGOS_HEADER_CARGO, CM_STR_TOOLBAR_CARGOS_HEADER_CARGO),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CT_HEADER_AMOUNT), SetMinimalSize(108, 16), SetFill(1, 0), SetPadding(2,2,2,2), SetDataTip(STR_NULL, STR_NULL),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CT_HEADER_INCOME), SetMinimalSize(108, 16), SetFill(1, 0), SetPadding(2,2,2,2), SetDataTip(STR_NULL, STR_NULL),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CT_HEADER_CARGO), SetFill(1, 0), SetPadding(2,2,2,2), SetStringTip(CM_STR_TOOLBAR_CARGOS_HEADER_CARGO, CM_STR_TOOLBAR_CARGOS_HEADER_CARGO),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CT_HEADER_AMOUNT), SetMinimalSize(108, 16), SetFill(1, 0), SetPadding(2,2,2,2),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CT_HEADER_INCOME), SetMinimalSize(108, 16), SetFill(1, 0), SetPadding(2,2,2,2),
EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 1),
@@ -207,7 +202,7 @@ static const NWidgetPart _nested_cargos_widgets[] = {
static WindowDesc _cargos_desc(
WDP_AUTO, "cm_cargo_table", 0, 0,
WC_CARGOS, WC_NONE,
WDF_CONSTRUCTION,
WindowDefaultFlag::Construction,
_nested_cargos_widgets
);

View File

@@ -1,9 +1,9 @@
/** @file cargo_table_gui.h GUI Functions related to cargos. */
/** @file cm_cargo_table_gui.hpp CityMania cargo table GUI. */
#ifndef CM_CARGO_TABLE_HPP
#define CM_CARGO_TABLE_HPP
#ifndef CM_CARGO_TABLE_GUI_HPP
#define CM_CARGO_TABLE_GUI_HPP
#include "company_type.h"
#include "../company_type.h"
namespace citymania {
@@ -12,4 +12,4 @@ void InvalidateCargosWindows(CompanyID cid);
} // namespace citymania
#endif /* CARGO_TABLE_H */
#endif /* CM_CARGO_TABLE_GUI_HPP */

View File

@@ -70,8 +70,7 @@ public:
this->box.height = this->padding;
this->box.width = 0;
for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
SetDParamStr(0, ci->client_name);
this->box.width = std::max<int>(this->box.width, GetStringBoundingBox(STR_JUST_RAW_STRING).width);
this->box.width = std::max<int>(this->box.width, GetStringBoundingBox(ci->client_name).width);
this->box.height += this->line_height;
}
this->box.width += this->padding * 3 + icon_size.width;
@@ -176,11 +175,10 @@ public:
std::sort(clients.begin(), clients.end());
for (const auto &[playas, name, style] : clients) {
auto [colour, icon] = STYLES[style];
SetDParamStr(0, name);
// auto colour = TC_SILVER;
// if (ci->client_id == _network_own_client_id) colour = TC_WHITE;
// if (ci->client_id == CLIENT_ID_SERVER) colour = TC_ORANGE;
DrawString(text_left, text_right, y + this->text_offset_y, STR_JUST_RAW_STRING, colour);
DrawString(text_left, text_right, y + this->text_offset_y, name, colour);
if (icon != PAL_NONE) DrawSprite(icon, COMPANY_SPRITE_COLOUR(playas), x, y + this->icon_offset_y);
// DrawCompanyIcon(playas, x, y + this->icon_offset_y);

View File

@@ -33,7 +33,7 @@ extern CommandCallback _current_callback;
class Command {
public:
bool no_estimate_flag = false;
CompanyID company = INVALID_COMPANY;
CompanyID company = CompanyID::Invalid();
StringID error = (StringID)0;
CommandCallback callback = nullptr;
@@ -41,13 +41,13 @@ public:
virtual ~Command() {}
virtual bool _post(::CommandCallback *callback)=0;
virtual CommandCost _do(DoCommandFlag flags)=0;
virtual CommandCost _do(DoCommandFlags flags)=0;
virtual Commands get_command()=0;
template <typename Tcallback>
bool post(Tcallback callback) {
CompanyID company_backup = _current_company;
if (this->company != INVALID_COMPANY)
if (this->company != CompanyID::Invalid())
_current_company = company;
_no_estimate_command = this->no_estimate_flag;
_current_callback = this->callback;
@@ -61,9 +61,9 @@ public:
return this->post<::CommandCallback *>(nullptr);
}
CommandCost call(DoCommandFlag flags) {
CommandCost call(DoCommandFlags flags) {
CompanyID old = _current_company;
if (this->company != INVALID_COMPANY)
if (this->company != CompanyID::Invalid())
_current_company = company;
auto res = this->_do(flags);
_current_company = old;
@@ -71,7 +71,7 @@ public:
}
CommandCost test() {
return this->call(DC_NONE);
return this->call({});
}
Command &with_error(StringID error) {

View File

@@ -91,7 +91,7 @@ namespace citymania {
size_t GetCommandHash(Commands cmd, CompanyID company_id, StringID err_msg, ::CommandCallback callback, const CommandDataBuffer &data) {
size_t res = 0;
hash_combine(res, cmd, (uint16)company_id, err_msg, callback, data);
hash_combine(res, cmd, company_id.base(), err_msg, callback, data);
return res;
}

View File

@@ -6,21 +6,21 @@
#include "cm_main.hpp"
#include "../network/core/http.h" //HttpCallback
#include "core/geometry_func.hpp" //maxdim
#include "settings_type.h"
#include "settings_func.h" //saveconfig
#include "3rdparty/md5/md5.h" //pass crypt
#include "network/network_func.h" //network chat
#include "strings_func.h"
#include "textbuf_gui.h" //show query
#include "network/network.h" //networking
#include "ini_type.h" //ini file
#include "fileio_func.h" //personal dir
#include "error.h" //error message
#include "debug.h"
#include "window_func.h"
#include "window_gui.h"
#include "querystring_gui.h" // QueryString definition
#include "../core/geometry_func.hpp" //maxdim
#include "../settings_type.h"
#include "../settings_func.h" //saveconfig
#include "../3rdparty/md5/md5.h" //pass crypt
#include "../network/network_func.h" //network chat
#include "../strings_func.h"
#include "../textbuf_gui.h" //show query
#include "../network/network.h" //networking
#include "../ini_type.h" //ini file
#include "../fileio_func.h" //personal dir
#include "../error.h" //error message
#include "../debug.h"
#include "../window_func.h"
#include "../window_gui.h"
#include "../querystring_gui.h" // QueryString definition
#include <sstream>
@@ -463,79 +463,79 @@ static const NWidgetPart _nested_commands_toolbar_widgets[] = {
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_GOAL), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_GOAL_CAPTION, STR_TOOLBAR_COMMANDS_GOAL_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_QUEST), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_QUEST_CAPTION, STR_TOOLBAR_COMMANDS_QUEST_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_SCORE), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_SCORE_CAPTION, STR_TOOLBAR_COMMANDS_SCORE_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_TOWN), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_TOWN_CAPTION, STR_TOOLBAR_COMMANDS_TOWN_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_TOWN_ID), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_TOWN_ID_CAPTION, STR_TOOLBAR_COMMANDS_TOWN_ID_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_HINT), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_HINT_CAPTION, STR_TOOLBAR_COMMANDS_HINT_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_LOGIN), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_LOGIN_CAPTION, STR_TOOLBAR_COMMANDS_LOGIN_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_NAME), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NAME_CAPTION, STR_TOOLBAR_COMMANDS_NAME_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_TIMELEFT), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_TIMELEFT_CAPTION, STR_TOOLBAR_COMMANDS_TIMELEFT_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_INFO), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_INFO_CAPTION, STR_TOOLBAR_COMMANDS_INFO_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NS0), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NS1), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NS2), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NS3), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NS4), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NS5), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NS6), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NS7), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NS9), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NS10), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NSX1), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NSX2), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NSX3), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NSX4), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, CTW_NSX5), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_NS_CAPTION, STR_TOOLBAR_COMMANDS_NS_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_RESETME), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_RESETME_CAPTION, STR_TOOLBAR_COMMANDS_RESETME_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_SAVEME), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_SAVEME_CAPTION, STR_TOOLBAR_COMMANDS_SAVEME_TOOLTIP),
EndContainer(),
//more
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_TOPICS), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_TOPICS_CAPTION, STR_TOOLBAR_COMMANDS_TOPICS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_HELP), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_HELP_CAPTION, STR_TOOLBAR_COMMANDS_HELP_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_TOPIC1), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_TOPIC1_CAPTION, STR_TOOLBAR_COMMANDS_TOPIC1_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_RULES), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_RULES_CAPTION, STR_TOOLBAR_COMMANDS_RULES_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_TOPIC2), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_TOPIC2_CAPTION, STR_TOOLBAR_COMMANDS_TOPIC2_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_CBHINT), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_CBHINT_CAPTION, STR_TOOLBAR_COMMANDS_CBHINT_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_TOPIC3), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_TOPIC3_CAPTION, STR_TOOLBAR_COMMANDS_TOPIC3_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_BEST), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_BEST_CAPTION, STR_TOOLBAR_COMMANDS_BEST_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_TOPIC4), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_TOPIC4_CAPTION, STR_TOOLBAR_COMMANDS_TOPIC4_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_RANK), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_RANK_CAPTION, STR_TOOLBAR_COMMANDS_RANK_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_TOPIC5), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_TOPIC5_CAPTION, STR_TOOLBAR_COMMANDS_TOPIC5_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_ME), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_ME_CAPTION, STR_TOOLBAR_COMMANDS_ME_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CTW_TOPIC6), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(STR_TOOLBAR_COMMANDS_TOPIC6_CAPTION, STR_TOOLBAR_COMMANDS_TOPIC6_TOOLTIP),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(0, 1), EndContainer(),
EndContainer(),
@@ -593,7 +593,7 @@ public:
}
void OnFailure() override {
ShowErrorMessage(CM_STR_LOGIN_ERROR_SIGN_IN_FAILED, INVALID_STRING_ID, WL_ERROR);
ShowErrorMessage(GetEncodedString(CM_STR_LOGIN_ERROR_SIGN_IN_FAILED), {}, WL_ERROR);
}
bool IsCancelled() const override {
@@ -604,7 +604,7 @@ public:
if(strlen(this->buf) == 4 && _networking){
NetworkClientSendChatToServer(fmt::format("!login {}", this->buf));
} else{
ShowErrorMessage(CM_STR_LOGIN_ERROR_BAD_INPUT, INVALID_STRING_ID, WL_ERROR);
ShowErrorMessage(GetEncodedString(CM_STR_LOGIN_ERROR_BAD_INPUT), {}, WL_ERROR);
}
this->proccessing = false;
}
@@ -669,6 +669,20 @@ void AccountLogin(CommunityName community){
login.InitiateLoginSequence();
}
template <typename Container>
std::string hex_join(const Container& data, bool uppercase = false) {
std::string result;
result.reserve(data.size() * 2);
const char* fmt_str = uppercase ? "{:02X}" : "{:02x}";
for (const auto& byte : data) {
result += fmt::format(fmt::runtime(fmt_str), static_cast<unsigned char>(byte));
}
return result;
}
//login window
class LoginWindow : public Window {
public:
@@ -681,27 +695,23 @@ public:
// if(!_novahost || !_networking) this->DisableWidget(LWW_NOVAPOLIS);
}
void SetStringParameters(int widget) const override
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
{
switch(widget){
case LWW_NOVAPOLIS_LOGIN:
SetDParamStr(0, _inilogindata[NOVAPOLISUSER]);
break;
return GetString(CM_STR_LOGIN_WINDOW_USERNAME_DISPLAY, _inilogindata[NOVAPOLISUSER]);
case LWW_NOVAPOLIS_PW:
SetDParam(0, (GetLoginItem(NOVAPOLIS_PW).empty() ? CM_STR_LOGIN_WINDOW_NOT_SET : CM_STR_LOGIN_WINDOW_SET));
break;
return GetString(CM_STR_LOGIN_WINDOW_PASSWORD_DISPLAY, (GetLoginItem(NOVAPOLIS_PW).empty() ? CM_STR_LOGIN_WINDOW_NOT_SET : CM_STR_LOGIN_WINDOW_SET));
case LWW_NICE_LOGIN:
SetDParamStr(0, _inilogindata[NICEUSER]);
break;
return GetString(CM_STR_LOGIN_WINDOW_USERNAME_DISPLAY, _inilogindata[NICEUSER]);
case LWW_NICE_PW:
SetDParam(0, (GetLoginItem(NICE_PW).empty() ? CM_STR_LOGIN_WINDOW_NOT_SET : CM_STR_LOGIN_WINDOW_SET));
break;
return GetString(CM_STR_LOGIN_WINDOW_PASSWORD_DISPLAY, (GetLoginItem(NICE_PW).empty() ? CM_STR_LOGIN_WINDOW_NOT_SET : CM_STR_LOGIN_WINDOW_SET));
case LWW_BTPRO_LOGIN:
SetDParamStr(0, _inilogindata[BTPROUSER]);
break;
return GetString(CM_STR_LOGIN_WINDOW_USERNAME_DISPLAY, _inilogindata[BTPROUSER]);
case LWW_BTPRO_PW:
SetDParam(0, (GetLoginItem(BTPRO_PW).empty() ? CM_STR_LOGIN_WINDOW_NOT_SET : CM_STR_LOGIN_WINDOW_SET));
break;
return GetString(CM_STR_LOGIN_WINDOW_PASSWORD_DISPLAY, (GetLoginItem(BTPRO_PW).empty() ? CM_STR_LOGIN_WINDOW_NOT_SET : CM_STR_LOGIN_WINDOW_SET));
default:
return this->Window::GetWidgetString(widget, stringid);
}
}
@@ -721,13 +731,13 @@ public:
case LWW_NICE_LOGIN:
case LWW_BTPRO_LOGIN:
this->query_widget = (LoginWindowQueryWidgets)widget;
ShowQueryString(STR_EMPTY, CM_STR_LOGIN_WINDOW_CHANGE_USERNAME, MAX_COMMUNITY_STRING_LEN, this, CS_ALPHANUMERAL, QSF_NONE);
ShowQueryString("", CM_STR_LOGIN_WINDOW_CHANGE_USERNAME, MAX_COMMUNITY_STRING_LEN, this, CS_ALPHANUMERAL, {});
break;
case LWW_NOVAPOLIS_PW:
case LWW_NICE_PW:
case LWW_BTPRO_PW:
this->query_widget = (LoginWindowQueryWidgets)widget;
ShowQueryString(STR_EMPTY, CM_STR_LOGIN_WINDOW_CHANGE_PASSWORD, MAX_COMMUNITY_STRING_LEN, this, CS_ALPHANUMERAL, QSF_NONE);
ShowQueryString("", CM_STR_LOGIN_WINDOW_CHANGE_PASSWORD, MAX_COMMUNITY_STRING_LEN, this, CS_ALPHANUMERAL, {});
break;
}
}
@@ -757,15 +767,11 @@ public:
password.Append(str.value().c_str(), str.value().length());
password.Finish(digest);
auto first_pass = fmt::format("{:02x}", fmt::join(digest, ""));
auto tobe_salted = fmt::format("nice{}client", first_pass);
auto tobe_salted = fmt::format("nice{}client", hex_join(digest));
salted_password.Append(tobe_salted.c_str(),tobe_salted.length());
salted_password.Finish(digest);
auto second_pass = fmt::format("{:02x}", fmt::join(digest, ""));
// Save the result to citymania.cfg
SetLoginItem(NICE_PW, second_pass);
SetLoginItem(NICE_PW, hex_join(digest));
break;
}
default: return;
@@ -779,55 +785,55 @@ private:
static const NWidgetPart _nested_login_window_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(CM_STR_LOGIN_WINDOW_CAPTION, 0),
NWidget(WWT_CAPTION, COLOUR_GREY), SetToolTip(CM_STR_LOGIN_WINDOW_CAPTION),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0),
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPadding(10),
NWidget(NWID_VERTICAL, NWidContainerFlag::EqualSize), SetPadding(10),
//novapolis
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_USERNAME), SetDataTip(CM_STR_LOGIN_WINDOW_USERNAME, 0),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_USERNAME), SetToolTip(CM_STR_LOGIN_WINDOW_USERNAME),
NWidget(NWID_SPACER), SetMinimalSize(20, 0),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_PASSWORD), SetDataTip(CM_STR_LOGIN_WINDOW_PASSWORD, 0),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_PASSWORD), SetToolTip(CM_STR_LOGIN_WINDOW_PASSWORD),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 5),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_NOVAPOLIS_LOGIN), SetMinimalSize(60, 20), SetFill(1, 0), SetDataTip(CM_STR_LOGIN_WINDOW_USERNAME_DISPLAY, CM_STR_LOGIN_WINDOW_CHANGE_USERNAME_HELPTEXT),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_NOVAPOLIS_LOGIN), SetMinimalSize(60, 20), SetFill(1, 0),
NWidget(NWID_SPACER), SetMinimalSize(20, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_NOVAPOLIS_PW), SetMinimalSize(30, 20), SetFill(1, 0), SetDataTip(CM_STR_LOGIN_WINDOW_PASSWORD_DISPLAY, CM_STR_LOGIN_WINDOW_CHANGE_PASSWORD_HELPTEXT),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_NOVAPOLIS_PW), SetMinimalSize(30, 20), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 10),
NWidget(WWT_PUSHTXTBTN, COLOUR_PURPLE, LWW_NOVAPOLIS), SetMinimalSize(100, 30), SetFill(1, 0), SetDataTip(CM_STR_LOGIN_WINDOW_CITYMANIA, CM_STR_LOGIN_WINDOW_SIGN_IN_HELPTEXT),
NWidget(WWT_PUSHTXTBTN, COLOUR_PURPLE, LWW_NOVAPOLIS), SetMinimalSize(100, 30), SetFill(1, 0), SetStringTip(CM_STR_LOGIN_WINDOW_CITYMANIA, CM_STR_LOGIN_WINDOW_SIGN_IN_HELPTEXT),
NWidget(NWID_SPACER), SetMinimalSize(0, 10),
//n-ice
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_USERNAME), SetDataTip(CM_STR_LOGIN_WINDOW_USERNAME, 0),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_USERNAME), SetToolTip(CM_STR_LOGIN_WINDOW_USERNAME),
NWidget(NWID_SPACER), SetMinimalSize(20, 0),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_PASSWORD), SetDataTip(CM_STR_LOGIN_WINDOW_PASSWORD, 0),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_PASSWORD), SetToolTip(CM_STR_LOGIN_WINDOW_PASSWORD),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 5),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_NICE_LOGIN), SetMinimalSize(60, 20), SetFill(1, 0), SetDataTip(CM_STR_LOGIN_WINDOW_USERNAME_DISPLAY, CM_STR_LOGIN_WINDOW_CHANGE_USERNAME_HELPTEXT),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_NICE_LOGIN), SetMinimalSize(60, 20), SetFill(1, 0),
NWidget(NWID_SPACER), SetMinimalSize(20, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_NICE_PW), SetMinimalSize(30, 20), SetFill(1, 0), SetDataTip(CM_STR_LOGIN_WINDOW_PASSWORD_DISPLAY, CM_STR_LOGIN_WINDOW_CHANGE_PASSWORD_HELPTEXT),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_NICE_PW), SetMinimalSize(30, 20), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 10),
NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, LWW_NICE), SetMinimalSize(100, 30), SetFill(1, 0), SetDataTip(CM_STR_LOGIN_WINDOW_NICE, CM_STR_LOGIN_WINDOW_SIGN_IN_HELPTEXT),
NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, LWW_NICE), SetMinimalSize(100, 30), SetFill(1, 0), SetStringTip(CM_STR_LOGIN_WINDOW_NICE, CM_STR_LOGIN_WINDOW_SIGN_IN_HELPTEXT),
NWidget(NWID_SPACER), SetMinimalSize(0, 10),
//btpro
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_USERNAME), SetDataTip(CM_STR_LOGIN_WINDOW_USERNAME, 0),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_USERNAME), SetToolTip(CM_STR_LOGIN_WINDOW_USERNAME),
NWidget(NWID_SPACER), SetMinimalSize(20, 0),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_PASSWORD), SetDataTip(CM_STR_LOGIN_WINDOW_PASSWORD, 0),
NWidget(WWT_TEXT, COLOUR_BROWN, LWW_PASSWORD), SetToolTip(CM_STR_LOGIN_WINDOW_PASSWORD),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 5),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_BTPRO_LOGIN), SetMinimalSize(60, 20), SetFill(1, 0), SetDataTip(CM_STR_LOGIN_WINDOW_USERNAME_DISPLAY, CM_STR_LOGIN_WINDOW_CHANGE_USERNAME_HELPTEXT),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_BTPRO_LOGIN), SetMinimalSize(60, 20), SetFill(1, 0),
NWidget(NWID_SPACER), SetMinimalSize(20, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_BTPRO_PW), SetMinimalSize(30, 20), SetFill(1, 0), SetDataTip(CM_STR_LOGIN_WINDOW_PASSWORD_DISPLAY, CM_STR_LOGIN_WINDOW_CHANGE_PASSWORD_HELPTEXT),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, LWW_BTPRO_PW), SetMinimalSize(30, 20), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 10),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, LWW_BTPRO), SetMinimalSize(100, 30), SetFill(1, 0), SetDataTip(CM_STR_LOGIN_WINDOW_BTPRO, CM_STR_LOGIN_WINDOW_SIGN_IN_HELPTEXT),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, LWW_BTPRO), SetMinimalSize(100, 30), SetFill(1, 0), SetStringTip(CM_STR_LOGIN_WINDOW_BTPRO, CM_STR_LOGIN_WINDOW_SIGN_IN_HELPTEXT),
EndContainer(),
EndContainer(),
};
@@ -835,7 +841,7 @@ static const NWidgetPart _nested_login_window_widgets[] = {
static WindowDesc _login_window_desc(
WDP_CENTER, nullptr, 0, 0,
CM_WC_LOGIN_WINDOW, WC_NONE,
WDF_CONSTRUCTION,
WindowDefaultFlag::Construction,
std::span<const NWidgetPart>(_nested_login_window_widgets)
);

View File

@@ -58,7 +58,7 @@ bool ConStep([[maybe_unused]] uint8_t argc, [[maybe_unused]] char *argv[]) {
auto n = (argc > 1 ? atoi(argv[1]) : 1);
_pause_countdown = n;
cmd::Pause(PM_PAUSED_NORMAL, 0).post();
cmd::Pause(PauseMode::Normal, 0).post();
return true;
}
@@ -120,7 +120,7 @@ bool ConTreeMap([[maybe_unused]] uint8_t argc, [[maybe_unused]] char *argv[]) {
return true;
}
for (TileIndex tile = 0; tile < Map::Size(); tile++) {
for (auto tile : Map::Iterate()) {
auto mx = x - x * TileX(tile) / Map::SizeX() - 1;
auto my = y * TileY(tile) / Map::SizeY();
auto t = map[mx + my * x];
@@ -163,7 +163,7 @@ void MakeReplaySave() {
}
void CheckIntervalSave() {
if (_pause_mode == PM_UNPAUSED) {
if (_pause_mode.None()) {
_replay_ticks++;
if (_replay_save_interval && _replay_ticks - _replay_last_save >= _replay_save_interval) {
MakeReplaySave();

View File

@@ -80,25 +80,24 @@ struct CompanyEvent {
struct CargoDeliveredToIndustry {
Industry *industry;
CargoID cargo_type;
CargoType cargo_type;
uint amount;
const Station *station;
};
struct CargoDeliveredToUnknown {
CargoID cargo_type;
CargoType cargo_type;
uint amount;
const Station *station;
};
struct CargoAccepted {
Company *company;
CargoID cargo_type;
CargoType cargo_type;
uint amount;
const Station *station;
Money profit;
SourceType src_type;
SourceID src;
Source src;
};
struct CompanyMoneyChanged {

View File

@@ -65,7 +65,7 @@ typedef std::vector<ParentSpriteToDraw> ParentSpriteToDrawVector;
typedef std::vector<ChildScreenSpriteToDraw> ChildScreenSpriteToDrawVector;
extern const DrawBuildingsTileStruct _town_draw_tile_data[(NEW_HOUSE_OFFSET) * 4 * 4];
Viewport SetupScreenshotViewport(ScreenshotType t, uint32_t width = 0, uint32_t height = 0);
namespace citymania {
@@ -197,7 +197,7 @@ void WriteHouseSpecInfo(JsonWriter &j) {
j.kv("removal_cost", hs->removal_cost);
j.kv("name", hs->building_name);
j.kv("mail_generation", hs->mail_generation);
j.kv("flags", hs->building_flags);
j.kv("flags", hs->building_flags.base());
j.kv("availability", hs->building_availability);
j.kv("enabled", hs->enabled);
j.end_dict();
@@ -224,7 +224,6 @@ void WriteHouseSpecInfo(JsonWriter &j) {
void WriteCargoSpecInfo(JsonWriter &j) {
j.begin_list_with_key("cargo_specs");
char cargo_label[16];
SetDParam(0, 123);
for (const CargoSpec *cs : CargoSpec::Iterate()) {
j.begin_dict();
JKV(j, cs->initial_payment);
@@ -292,7 +291,7 @@ void WriteEngineInfo(JsonWriter &j) {
for (const Engine *e : Engine::Iterate()) {
if (e->type != VEH_TRAIN) continue;
j.begin_dict();
JKV(j, e->index);
JKV(j, e->index.base());
j.kv("name", e->name);
j.kv("cost", e->GetCost());
j.kv("running_cost", e->GetRunningCost());
@@ -300,7 +299,7 @@ void WriteEngineInfo(JsonWriter &j) {
j.begin_dict_with_key("info");
JKV(j, e->info.cargo_type);
JKV(j, e->info.cargo_age_period);
JKV(j, e->info.climates);
JKV(j, e->info.climates.base());
JKV(j, e->info.base_intro.base());
JKV(j, e->info.lifelength.base());
JKV(j, e->info.base_life.base());
@@ -351,14 +350,14 @@ void ExportOpenttdData(const std::string &filename) {
data_export::WriteEngineInfo(j);
}
extern void ViewportExportDrawBegin(const Viewport *vp, int left, int top, int right, int bottom);
extern void ViewportExportDrawBegin(const Viewport &vp, int left, int top, int right, int bottom);
extern void ViewportExportDrawEnd();
extern TileSpriteToDrawVector &ViewportExportGetTileSprites();
extern ParentSpriteToSortVector &ViewportExportGetSortedParentSprites();
extern ChildScreenSpriteToDrawVector &ViewportExportGetChildSprites();
void ViewportExportJson(const Viewport *vp, int left, int top, int right, int bottom) {
void ViewportExportJson(const Viewport &vp, int left, int top, int right, int bottom) {
ViewportExportDrawBegin(vp, left, top, right, bottom);
auto fname = fmt::format("snaps/tick_{}.json", TimerGameTick::counter);
@@ -441,11 +440,10 @@ void ViewportExportJson(const Viewport *vp, int left, int top, int right, int bo
}
void ExportFrameSpritesJson() {
Viewport vp;
SetupScreenshotViewport(SC_VIEWPORT, &vp);
Viewport vp = SetupScreenshotViewport(SC_VIEWPORT);
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
vp.zoom = w->viewport->zoom;
ViewportExportJson(&vp,
ViewportExportJson(vp,
vp.virtual_left,
vp.virtual_top,
vp.virtual_left + vp.virtual_width,
@@ -483,7 +481,7 @@ void ExportSpriteAndPal(SpriteID img, SpriteID pal) {
}
}
void ViewportExport(const Viewport *vp, int left, int top, int right, int bottom) {
void ViewportExport(const Viewport &vp, int left, int top, int right, int bottom) {
ViewportExportDrawBegin(vp, left, top, right, bottom);
auto fname = fmt::format("snaps/tick_{}.bin", TimerGameTick::counter);
@@ -516,11 +514,10 @@ bool _is_recording = false;
void ExportFrameSprites() {
if (!_is_recording) return;
Viewport vp;
SetupScreenshotViewport(SC_VIEWPORT, &vp);
Viewport vp = SetupScreenshotViewport(SC_VIEWPORT);
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
vp.zoom = w->viewport->zoom;
ViewportExport(&vp,
ViewportExport(vp,
vp.virtual_left,
vp.virtual_top,
vp.virtual_left + vp.virtual_width,

View File

@@ -10,6 +10,7 @@
#include "cm_station_gui.hpp"
#include "cm_type.hpp"
#include "cm_zoning.hpp"
#include "generated/cm_gen_commands.hpp"
#include "../core/math_func.hpp"
#include "../table/bridge_land.h"
@@ -41,18 +42,18 @@
#include "../table/autorail.h"
#include "../table/industry_land.h"
#include "../debug.h"
#include "generated/cm_gen_commands.hpp"
#include "station_gui.h"
#include "station_type.h"
#include "table/sprites.h"
#include "table/strings.h"
#include "tile_type.h"
#include "../station_gui.h"
#include "../station_type.h"
#include "../table/sprites.h"
#include "../table/strings.h"
#include "../tile_type.h"
#include <algorithm>
#include <cstdint>
#include <optional>
#include <set>
/** Enumeration of multi-part foundations */
enum FoundationPart {
FOUNDATION_PART_NONE = 0xFF, ///< Neither foundation nor groundsprite drawn yet.
@@ -180,8 +181,8 @@ struct TileZoning {
uint8 industry_fund_update;
};
static TileZoning *_mz = nullptr;
static IndustryType _industry_forbidden_tiles = INVALID_INDUSTRYTYPE;
static std::unique_ptr<TileZoning[]> _mz = nullptr;
static IndustryType _industry_forbidden_tiles = IT_INVALID;
extern StationBuildingStatus _station_building_status;
extern const Station *_station_to_join;
@@ -543,12 +544,12 @@ void ObjectHighlight::AddStationOverlayData(int w, int h, int rad, StationCovera
if (!_settings_game.station.modified_catchment) rad = CA_UNMODIFIED;
auto production = citymania::GetProductionAroundTiles(this->tile, w, h, rad);
bool has_header = false;
for (CargoID i = 0; i < NUM_CARGO; i++) {
for (CargoType i = 0; i < NUM_CARGO; i++) {
if (production[i] == 0) continue;
switch (sct) {
case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(i, CC_PASSENGERS)) continue; break;
case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(i, CC_PASSENGERS)) continue; break;
case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(i, CargoClass::Passengers)) continue; break;
case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(i, CargoClass::Passengers)) continue; break;
case SCT_ALL: break;
default: NOT_REACHED();
}
@@ -560,9 +561,7 @@ void ObjectHighlight::AddStationOverlayData(int w, int h, int rad, StationCovera
this->overlay_data.emplace_back(PAL_NONE, GetString(CM_STR_BUILD_INFO_OVERLAY_STATION_SUPPLIES));
has_header = true;
}
SetDParam(0, i);
SetDParam(1, production[i] >> 8);
this->overlay_data.emplace_back(cs->GetCargoIcon(), GetString(CM_STR_BUILD_INFO_OVERLAY_STATION_CARGO));
this->overlay_data.emplace_back(cs->GetCargoIcon(), GetString(CM_STR_BUILD_INFO_OVERLAY_STATION_CARGO, i, production[i] >> 8));
}
}
@@ -597,7 +596,7 @@ void ObjectHighlight::UpdateTiles() {
auto ta = OrthogonalTileArea(this->tile, this->end_tile);
auto numtracks = ta.w;
auto plat_len = ta.h;
if (this->axis == AXIS_X) Swap(numtracks, plat_len);
if (this->axis == AXIS_X) std::swap(numtracks, plat_len);
this->cost = cmd::BuildRailStation(
this->tile,
@@ -638,7 +637,7 @@ void ObjectHighlight::UpdateTiles() {
this->tile,
ta.w,
ta.h,
(this->is_truck ? ROADSTOP_TRUCK : ROADSTOP_BUS),
(this->is_truck ? RoadStopType::Truck : RoadStopType::Bus),
(this->ddir >= DIAGDIR_END), // is_drive_through
(DiagDirection)(this->ddir % 4),
this->roadtype,
@@ -768,7 +767,7 @@ void ObjectHighlight::UpdateTiles() {
break;
}
case Type::INDUSTRY: {
this->cost = cmd::BuildIndustry{this->tile, this->ind_type, this->ind_layout, true, 0}.call(DC_NONE);
this->cost = cmd::BuildIndustry{this->tile, this->ind_type, this->ind_layout, true, 0}.call({});
if (this->cost.Succeeded()) {
const IndustrySpec *indspec = GetIndustrySpec(this->ind_type);
if (indspec == nullptr) break;
@@ -815,8 +814,7 @@ void ObjectHighlight::UpdateOverlay() {
auto err = this->cost.GetErrorMessage();
// auto extra_err = this->cost.GetExtraErrorMessage();
bool no_money = (err == STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY);
SetDParam(0, this->cost.GetCost());
this->overlay_data.emplace_back(PAL_NONE, GetString(no_money ? CM_STR_BUILD_INFO_OVERLAY_COST_NO_MONEY : CM_STR_BUILD_INFO_OVERLAY_COST_OK));
this->overlay_data.emplace_back(PAL_NONE, GetString(no_money ? CM_STR_BUILD_INFO_OVERLAY_COST_NO_MONEY : CM_STR_BUILD_INFO_OVERLAY_COST_OK, this->cost.GetCost()));
// if (this->cost.Failed() && err != STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY) {
// if (err == INVALID_STRING_ID) {
// this->overlay_data.emplace_back(PAL_NONE, GetString(CM_STR_BUILD_INFO_OVERLAY_ERROR_UNKNOWN));
@@ -933,7 +931,7 @@ void DrawTrainDepotSprite(SpriteID palette, const TileInfo *ti, RailType railtyp
void DrawTrainStationSprite(SpriteID palette, const TileInfo *ti, RailType railtype, Axis axis, uint8_t section) {
int32 total_offset = 0;
const DrawTileSprites *t = GetStationTileLayout(STATION_RAIL, section + (axis == AXIS_X ? 0 : 1));
const DrawTileSprites *t = GetStationTileLayout(StationType::Rail, section + (axis == AXIS_X ? 0 : 1));
const RailTypeInfo *rti = nullptr;
if (railtype != INVALID_RAILTYPE) {
@@ -1003,7 +1001,7 @@ void DrawRoadStop(SpriteID palette, const TileInfo *ti, RoadType roadtype, DiagD
}
}
const DrawTileSprites *t = GetStationTileLayout(is_truck ? STATION_TRUCK : STATION_BUS, image);
const DrawTileSprites *t = GetStationTileLayout(is_truck ? StationType::Truck : StationType::Bus, image);
AddSortableSpriteToDraw(t->ground.sprite, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z);
DrawRailTileSeq(ti, t, TO_INVALID, total_offset, 0, palette);
/* Draw road, tram catenary */
@@ -1012,13 +1010,13 @@ void DrawRoadStop(SpriteID palette, const TileInfo *ti, RoadType roadtype, DiagD
void DrawDockSlope(SpriteID palette, const TileInfo *ti, DiagDirection ddir) {
uint image = (uint)ddir;
const DrawTileSprites *t = GetStationTileLayout(STATION_DOCK, image);
const DrawTileSprites *t = GetStationTileLayout(StationType::Dock, image);
DrawRailTileSeq(ti, t, TO_INVALID, 0, 0, palette);
}
void DrawDockFlat(SpriteID palette, const TileInfo *ti, Axis axis) {
uint image = GFX_DOCK_BASE_WATER_PART + (uint)axis;
const DrawTileSprites *t = GetStationTileLayout(STATION_DOCK, image);
const DrawTileSprites *t = GetStationTileLayout(StationType::Dock, image);
DrawRailTileSeq(ti, t, TO_INVALID, 0, 0, palette);
}
@@ -1059,7 +1057,7 @@ void DrawRoadDepot(SpriteID palette, const TileInfo *ti, RoadType roadtype, Diag
int relocation = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_DEPOT);
bool default_gfx = relocation == 0;
if (default_gfx) {
if (HasBit(rti->flags, ROTF_CATENARY)) {
if (rti->flags.Test(RoadTypeFlag::Catenary)) {
if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK && RoadTypeIsTram(roadtype) && !rti->UsesOverlay()) {
/* Sprites with track only work for default tram */
relocation = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_ROAD_DEPOT;
@@ -1097,7 +1095,7 @@ void DrawAirportTile(SpriteID palette, const TileInfo *ti, StationGfx gfx) {
gfx = GetTranslatedAirportTileID(gfx);
if (gfx >= NEW_AIRPORTTILE_OFFSET) {
const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
if (ats->grf_prop.spritegroup[0] != nullptr /* && DrawNewAirportTile(ti, Station::GetByTile(ti->tile), gfx, ats) */) {
if (ats->grf_prop.spritegroups[0] != nullptr /* && DrawNewAirportTile(ti, Station::GetByTile(ti->tile), gfx, ats) */) {
return;
}
/* No sprite group (or no valid one) found, meaning no graphics associated.
@@ -1122,7 +1120,7 @@ void DrawAirportTile(SpriteID palette, const TileInfo *ti, StationGfx gfx) {
t = &_station_display_datas_airport_flag_grass_fence_ne_2[0];
break;
}
if (t == nullptr || t->seq == nullptr) t = GetStationTileLayout(STATION_AIRPORT, gfx);
if (t == nullptr || t->GetSequence().empty()) t = GetStationTileLayout(StationType::Airport, gfx);
if (t) {
AddSortableSpriteToDraw(t->ground.sprite, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z);
DrawRailTileSeq(ti, t, TO_INVALID, total_offset, 0, palette);
@@ -1224,7 +1222,7 @@ struct IndustryTilePreviewResolverObject : public ResolverObject {
ind_scope(*this, tile, indus, indus->type),
gfx(gfx)
{
this->root_spritegroup = GetIndustryTileSpec(gfx)->grf_prop.spritegroup[0];
this->root_spritegroup = GetIndustryTileSpec(gfx)->grf_prop.spritegroups[0];
}
ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, uint8_t relative = 0) override {
@@ -1244,7 +1242,7 @@ bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const Indus
{
if (ti->tileh != SLOPE_FLAT) {
bool draw_old_one = true;
if (HasBit(inds->callback_mask, CBM_INDT_DRAW_FOUNDATIONS)) {
if (inds->callback_mask.Test(IndustryTileCallbackMask::DrawFoundations)) {
/* Called to determine the type (if any) of foundation to draw for industry tile */
uint32 callback_res = GetIndustryTileCallback(CBID_INDTILE_DRAW_FOUNDATIONS, 0, 0, gfx, i, ti->tile);
if (callback_res != CALLBACK_FAILED) draw_old_one = ConvertBooleanCallback(inds->grf_prop.grffile, CBID_INDTILE_DRAW_FOUNDATIONS, callback_res);
@@ -1273,14 +1271,14 @@ void DrawIndustryTile(SpriteID palette, const TileInfo *ti, IndustryType ind_typ
TileInfo nti = *ti;
ind.type = ind_type;
ind.selected_layout = ind_layout + 1;
ind.index = INVALID_INDUSTRY;
ind.index = IndustryID::Invalid();
ind.location.tile = ti->tile - tile_diff;
/* Draw the tile using the specialized method of newgrf industrytile.
* DrawNewIndustry will return false if ever the resolver could not
* find any sprite to display. So in this case, we will jump on the
* substitute gfx instead. */
if (indts->grf_prop.spritegroup[0] != nullptr && citymania::DrawNewIndustryTile(&nti, &ind, gfx, indts)) {
if (indts->grf_prop.spritegroups[0] != nullptr && citymania::DrawNewIndustryTile(&nti, &ind, gfx, indts)) {
return;
} else {
/* No sprite group (or no valid one) found, meaning no graphics associated.
@@ -1406,15 +1404,13 @@ void DrawSignal(SpriteID palette, const TileInfo *ti, RailType railtype, uint po
}
// copied from tunnelbridge_cmd.cpp
static inline const PalSpriteID *GetBridgeSpriteTable(int index, BridgePieces table)
static inline std::span<const PalSpriteID> GetBridgeSpriteTable(int index, BridgePieces table)
{
const BridgeSpec *bridge = GetBridgeSpec(index);
assert(table < BRIDGE_PIECE_INVALID);
if (bridge->sprite_table == nullptr || bridge->sprite_table[table] == nullptr) {
return _bridge_sprite_table[index][table];
} else {
return bridge->sprite_table[table];
}
assert(table < NUM_BRIDGE_PIECES);
if (table < bridge->sprite_table.size() && !bridge->sprite_table[table].empty()) return bridge->sprite_table[table];
return _bridge_sprite_table[index][table];
}
void DrawBridgeHead(SpriteID palette, const TileInfo *ti, RailType railtype, DiagDirection ddir, BridgeType type) {
@@ -1917,7 +1913,7 @@ TileHighlight GetTileHighlight(const TileInfo *ti, TileType tile_type) {
}
if (_settings_client.gui.cm_show_industry_forbidden_tiles &&
_industry_forbidden_tiles != INVALID_INDUSTRYTYPE) {
_industry_forbidden_tiles != IT_INVALID) {
auto b = CalcTileBorders(ti->tile, [](TileIndex t) { return !CanBuildIndustryOnTileCached(_industry_forbidden_tiles, t); });
th.add_border(b.first, CM_SPR_PALETTE_ZONING_RED);
if (!CanBuildIndustryOnTileCached(_industry_forbidden_tiles, ti->tile))
@@ -2107,8 +2103,7 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
}
void AllocateZoningMap(uint map_size) {
free(_mz);
_mz = CallocT<TileZoning>(map_size);
_mz = std::make_unique<TileZoning[]>(map_size);
}
uint8 GetTownZone(Town *town, TileIndex tile) {

View File

@@ -341,7 +341,7 @@ public:
int airport_type = 0;
uint8_t airport_layout = 0;
sp<Blueprint> blueprint = nullptr;
IndustryType ind_type = INVALID_INDUSTRYTYPE;
IndustryType ind_type = IT_INVALID;
uint32 ind_layout = 0;
CommandCost cost;
Dimension overlay_dim;

View File

@@ -151,7 +151,7 @@ void RailToolbar_UpdateRemoveWidgetStatus(Window *w, int widget, bool remove_act
if (!_settings_client.gui.station_dragdrop) {
int x = _settings_client.gui.station_numtracks;
int y = _settings_client.gui.station_platlength;
if (_station_gui.axis == 0) Swap(x, y);
if (_station_gui.axis == 0) std::swap(x, y);
SetTileSelectSize(x, y);
} else {
VpSetPlaceSizingLimit(_settings_game.station.station_spread);

View File

@@ -26,7 +26,7 @@ void SaveLocation(uint slot) {
auto &loc = _locations[slot];
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
auto vp = w->viewport;
auto &vp = w->viewport;
loc.zoom = vp->zoom;
loc.scrollpos_x = vp->scrollpos_x;
@@ -39,10 +39,10 @@ void LoadLocation(uint slot) {
if (!loc.scrollpos_y && !loc.scrollpos_x) return;
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
auto vp = w->viewport;
auto &vp = w->viewport;
vp->zoom = loc.zoom;
vp->follow_vehicle = INVALID_VEHICLE;
vp->follow_vehicle = VehicleID::Invalid();
vp->dest_scrollpos_x = loc.scrollpos_x;
vp->dest_scrollpos_y = loc.scrollpos_y;
vp->virtual_width = ScaleByZoom(vp->width, vp->zoom);

View File

@@ -58,25 +58,25 @@ static uint8 _linkstat_colours_in_legenda[] = {0, 1, 3, 5, 7, 9, 11};
static const int NUM_NO_COMPANY_ENTRIES = 4; ///< Number of entries in the owner legend that are not companies.
/** Macro for ordinary entry of LegendAndColour */
#define MK(a, b) {a, b, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, false, false}
#define MK(a, b) {a, b, IT_INVALID, 0, CompanyID::Invalid(), true, false, false}
/** Macro for a height legend entry with configurable colour. */
#define MC(col_break) {0, STR_TINY_BLACK_HEIGHT, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, false, col_break}
#define MC(col_break) {0, STR_TINY_BLACK_HEIGHT, IT_INVALID, 0, CompanyID::Invalid(), true, false, col_break}
/** Macro for non-company owned property entry of LegendAndColour */
#define MO(a, b) {a, b, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, false, false}
#define MO(a, b) {a, b, IT_INVALID, 0, CompanyID::Invalid(), true, false, false}
/** Macro used for forcing a rebuild of the owner legend the first time it is used. */
#define MOEND() {0, 0, INVALID_INDUSTRYTYPE, 0, OWNER_NONE, true, true, false}
#define MOEND() {0, 0, IT_INVALID, 0, OWNER_NONE, true, true, false}
/** Macro for end of list marker in arrays of LegendAndColour */
#define MKEND() {0, STR_NULL, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, true, false}
#define MKEND() {0, STR_NULL, IT_INVALID, 0, CompanyID::Invalid(), true, true, false}
/**
* Macro for break marker in arrays of LegendAndColour.
* It will have valid data, though
*/
#define MS(a, b) {a, b, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, false, true}
#define MS(a, b) {a, b, IT_INVALID, 0, CompanyID::Invalid(), true, false, true}
/** Legend text giving the colours to look for on the minimap */
static LegendAndColour _legend_land_contours[] = {
@@ -173,14 +173,15 @@ static uint _industry_to_list_pos[NUM_INDUSTRYTYPES];
/** Show heightmap in industry and owner mode of smallmap window. */
static bool _smallmap_show_heightmap = false;
/** Highlight a specific industry type */
static IndustryType _smallmap_industry_highlight = INVALID_INDUSTRYTYPE;
static IndustryType _smallmap_industry_highlight = IT_INVALID;
/** State of highlight blinking */
static bool _smallmap_industry_highlight_state;
/** For connecting company ID to position in owner list (small map legend) */
static uint _company_to_list_pos[MAX_COMPANIES];
static ReferenceThroughBaseContainer<std::array<uint32_t, MAX_COMPANIES>> _company_to_list_pos;
// TODO may have similar class in bulid overlays
struct IconTextSizeHelper {
protected:
RectPadding padding;
@@ -200,8 +201,8 @@ public:
this->text_ofs_x = this->icon_dim.width + WidgetDimensions::scaled.hsep_normal;
}
void add(StringID string_id, FontSize font_size) {
this->text_dim = maxdim(this->text_dim, GetStringBoundingBox(string_id, font_size));
void add(std::string_view str, FontSize font_size) {
this->text_dim = maxdim(this->text_dim, GetStringBoundingBox(str, font_size));
num_lines++;
};
@@ -350,7 +351,7 @@ static const LegendAndColour * const _legend_table[] = {
_legend_from_industries,
};
#define MKCOLOUR(x) TO_LE32X(x)
#define MKCOLOUR(x) TO_LE32(x)
#define MKCOLOUR_XXXX(x) (MKCOLOUR(0x01010101) * (uint)(x))
#define MKCOLOUR_X0X0(x) (MKCOLOUR(0x01000100) * (uint)(x))
@@ -370,18 +371,17 @@ static const LegendAndColour * const _legend_table[] = {
/** Colour scheme of the smallmap. */
struct SmallMapColourScheme {
uint32 *height_colours; ///< Cached colours for each level in a map.
const uint32 *height_colours_base; ///< Base table for determining the colours
size_t colour_count; ///< The number of colours.
uint32 default_colour; ///< Default colour of the land.
std::vector<uint32_t> height_colours; ///< Cached colours for each level in a map.
std::span<const uint32_t> height_colours_base; ///< Base table for determining the colours
uint32_t default_colour; ///< Default colour of the land.
};
/** Available colour schemes for height maps. */
static SmallMapColourScheme _heightmap_schemes[] = {
{nullptr, _green_map_heights, lengthof(_green_map_heights), MKCOLOUR_XXXX(0x54)}, ///< Green colour scheme.
{nullptr, _dark_green_map_heights, lengthof(_dark_green_map_heights), MKCOLOUR_XXXX(0x62)}, ///< Dark green colour scheme.
{nullptr, _violet_map_heights, lengthof(_violet_map_heights), MKCOLOUR_XXXX(0x81)}, ///< Violet colour scheme.
{nullptr, citymania::_yellow_map_heights, lengthof(citymania::_yellow_map_heights), MKCOLOUR_XXXX(0xC1)},
{{}, _green_map_heights, MKCOLOUR_XXXX(0x54)}, ///< Green colour scheme.
{{}, _dark_green_map_heights, MKCOLOUR_XXXX(0x62)}, ///< Dark green colour scheme.
{{}, _violet_map_heights, MKCOLOUR_XXXX(0x81)}, ///< Violet colour scheme.
{{}, citymania::_yellow_map_heights, MKCOLOUR_XXXX(0xC1)},
};
/**
@@ -390,7 +390,7 @@ static SmallMapColourScheme _heightmap_schemes[] = {
void BuildLandLegend()
{
/* The smallmap window has never been initialized, so no need to change the legend. */
if (_heightmap_schemes[0].height_colours == nullptr) return;
if (_heightmap_schemes[0].height_colours.empty()) return;
/*
* The general idea of this function is to fill the legend with an appropriate evenly spaced
@@ -570,11 +570,11 @@ static inline uint32 GetSmallMapRoutesPixels(TileIndex tile, TileType t)
switch (t) {
case MP_STATION:
switch (GetStationType(tile)) {
case STATION_RAIL: return MKCOLOUR_XXXX(PC_VERY_DARK_BROWN);
case STATION_AIRPORT: return MKCOLOUR_XXXX(PC_RED);
case STATION_TRUCK: return MKCOLOUR_XXXX(PC_ORANGE);
case STATION_BUS: return MKCOLOUR_XXXX(PC_YELLOW);
case STATION_DOCK: return MKCOLOUR_XXXX(PC_LIGHT_BLUE);
case StationType::Rail: return MKCOLOUR_XXXX(PC_VERY_DARK_BROWN);
case StationType::Airport: return MKCOLOUR_XXXX(PC_RED);
case StationType::Truck: return MKCOLOUR_XXXX(PC_ORANGE);
case StationType::Bus: return MKCOLOUR_XXXX(PC_YELLOW);
case StationType::Dock: return MKCOLOUR_XXXX(PC_LIGHT_BLUE);
default: return MKCOLOUR_FFFF;
}
@@ -604,7 +604,7 @@ static inline uint32 GetSmallMapRoutesPixels(TileIndex tile, TileType t)
const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour];
return ApplyMask(cs->default_colour, &andor);
}
[[ fallthrough ]];
[[fallthrough]];
}
default:
@@ -659,7 +659,7 @@ static inline uint32 GetSmallMapVegetationPixels(TileIndex tile, TileType t)
case MP_TREES:
if (GetTreeGround(tile) == TREE_GROUND_SNOW_DESERT || GetTreeGround(tile) == TREE_GROUND_ROUGH_SNOW) {
return (_settings_game.game_creation.landscape == LT_ARCTIC) ? MKCOLOUR_XYYX(PC_LIGHT_BLUE, PC_TREES) : MKCOLOUR_XYYX(PC_ORANGE, PC_TREES);
return (_settings_game.game_creation.landscape == LandscapeType::Arctic) ? MKCOLOUR_XYYX(PC_LIGHT_BLUE, PC_TREES) : MKCOLOUR_XYYX(PC_ORANGE, PC_TREES);
}
return (GetTropicZone(tile) == TROPICZONE_RAINFOREST) ? MKCOLOUR_XYYX(PC_RAINFOREST, PC_TREES) : MKCOLOUR_XYYX(PC_GRASS_LAND, PC_TREES);
@@ -989,7 +989,7 @@ void SmallMapWindow::DrawVehicles(const DrawPixelInfo *dpi, Blitter *blitter) co
{
for (const Vehicle *v : Vehicle::Iterate()) {
if (v->type == VEH_EFFECT) continue;
if (v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) continue;
if (v->vehstatus.Any({VehState::Hidden, VehState::Unclickable})) continue;
/* Remap into flat coordinates. */
Point pt = this->TileToPixel(v->x_pos & ~TILE_UNIT_MASK, v->y_pos & ~TILE_UNIT_MASK);
@@ -1036,8 +1036,7 @@ void SmallMapWindow::DrawIndustryProduction(const DrawPixelInfo *dpi) const
IconTextSizeHelper its{SPR_CARGO_COAL, WidgetDimensions::scaled.framerect};
for (auto i = 0; i < INDUSTRY_NUM_OUTPUTS; i++) {
if (ind->produced[i].cargo == INVALID_CARGO) continue;
SetDParam(0, ind->produced[i].history[LAST_MONTH].production);
its.add(STR_JUST_INT, FS_SMALL);
its.add(GetString(STR_JUST_INT, ind->produced[i].history[LAST_MONTH].production), FS_SMALL);
}
its.calculate();
this->industry_max_sign = maxdim(this->industry_max_sign, its.size);
@@ -1046,8 +1045,8 @@ void SmallMapWindow::DrawIndustryProduction(const DrawPixelInfo *dpi) const
for (auto i = 0; i < INDUSTRY_NUM_OUTPUTS; i++) {
if (ind->produced[i].cargo == INVALID_CARGO) continue;
DrawSprite(CargoSpec::Get(ind->produced[i].cargo)->GetCargoIcon(), PAL_NONE, ir.left, ir.top + its.icon_ofs_y);
SetDParam(0, ind->produced[i].history[LAST_MONTH].production);
DrawString(ir.left + its.text_ofs_x, ir.right, ir.top + its.text_ofs_y, STR_JUST_INT, TC_WHITE, SA_LEFT, false, FS_SMALL);
auto str = GetString(STR_JUST_INT, ind->produced[i].history[LAST_MONTH].production);
DrawString(ir.left + its.text_ofs_x, ir.right, ir.top + its.text_ofs_y, str, TC_WHITE, SA_LEFT, false, FS_SMALL);
ir.top += its.line_height;
}
}
@@ -1072,11 +1071,9 @@ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const
y < dpi->top + dpi->height) {
if (this->map_type == CM_SMT_IMBA) {
/* And draw it. */
SetDParam(0, population);
DrawString(x, x + width, y, t->larger_town ? CM_STR_SMALLMAP_POPULATION_LARGE : CM_STR_SMALLMAP_POPULATION);
DrawString(x, x + width, y, GetString(t->larger_town ? CM_STR_SMALLMAP_POPULATION_LARGE : CM_STR_SMALLMAP_POPULATION, population));
} else {
SetDParam(0, t->index);
DrawString(x, x + t->cache.sign.width_small, y, t->larger_town ? CM_STR_SMALLMAP_TOWN_LARGE : STR_SMALLMAP_TOWN);
DrawString(x, x + t->cache.sign.width_small, y, GetString(t->larger_town ? CM_STR_SMALLMAP_TOWN_LARGE : STR_SMALLMAP_TOWN, t->index));
}
}
}
@@ -1088,10 +1085,10 @@ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const
void SmallMapWindow::DrawMapIndicators() const
{
/* Find main viewport. */
const Viewport *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
const Viewport &vp = *GetMainWindow()->viewport;
Point upper_left_smallmap_coord = InverseRemapCoords2(vp->virtual_left, vp->virtual_top);
Point lower_right_smallmap_coord = InverseRemapCoords2(vp->virtual_left + vp->virtual_width - 1, vp->virtual_top + vp->virtual_height - 1);
Point upper_left_smallmap_coord = InverseRemapCoords2(vp.virtual_left, vp.virtual_top);
Point lower_right_smallmap_coord = InverseRemapCoords2(vp.virtual_left + vp.virtual_width - 1, vp.virtual_top + vp.virtual_height - 1);
Point upper_left = this->TileToPixel(upper_left_smallmap_coord.x, upper_left_smallmap_coord.y);
Point lower_right = this->TileToPixel(lower_right_smallmap_coord.x, lower_right_smallmap_coord.y);
@@ -1190,49 +1187,55 @@ void SmallMapWindow::SetupWidgetData()
StringID legend_tooltip;
StringID enable_all_tooltip;
StringID disable_all_tooltip;
int plane;
int industry_names_select_plane;
int select_buttons_plane;
switch (this->map_type) {
case SMT_INDUSTRY:
case CM_SMT_IMBA:
legend_tooltip = STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION;
enable_all_tooltip = STR_SMALLMAP_TOOLTIP_ENABLE_ALL_INDUSTRIES;
disable_all_tooltip = STR_SMALLMAP_TOOLTIP_DISABLE_ALL_INDUSTRIES;
plane = 0;
industry_names_select_plane = 0;
select_buttons_plane = 0;
break;
case SMT_OWNER:
legend_tooltip = STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION;
enable_all_tooltip = STR_SMALLMAP_TOOLTIP_ENABLE_ALL_COMPANIES;
disable_all_tooltip = STR_SMALLMAP_TOOLTIP_DISABLE_ALL_COMPANIES;
plane = 0;
industry_names_select_plane = SZSP_NONE;
select_buttons_plane = 0;
break;
case SMT_LINKSTATS:
legend_tooltip = STR_SMALLMAP_TOOLTIP_CARGO_SELECTION;
enable_all_tooltip = STR_SMALLMAP_TOOLTIP_ENABLE_ALL_CARGOS;
disable_all_tooltip = STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS;
plane = 0;
industry_names_select_plane = SZSP_NONE;
select_buttons_plane = 0;
break;
default:
legend_tooltip = STR_NULL;
enable_all_tooltip = STR_NULL;
disable_all_tooltip = STR_NULL;
plane = 1;
industry_names_select_plane = SZSP_NONE;
select_buttons_plane = 1;
break;
}
this->GetWidget<NWidgetCore>(WID_SM_LEGEND)->SetDataTip(STR_NULL, legend_tooltip);
this->GetWidget<NWidgetCore>(WID_SM_ENABLE_ALL)->SetDataTip(STR_SMALLMAP_ENABLE_ALL, enable_all_tooltip);
this->GetWidget<NWidgetCore>(WID_SM_DISABLE_ALL)->SetDataTip(STR_SMALLMAP_DISABLE_ALL, disable_all_tooltip);
this->GetWidget<NWidgetStacked>(WID_SM_SELECT_BUTTONS)->SetDisplayedPlane(plane);
this->GetWidget<NWidgetCore>(WID_SM_LEGEND)->SetToolTip(legend_tooltip);
this->GetWidget<NWidgetCore>(WID_SM_ENABLE_ALL)->SetStringTip(STR_SMALLMAP_ENABLE_ALL, enable_all_tooltip);
this->GetWidget<NWidgetCore>(WID_SM_DISABLE_ALL)->SetStringTip(STR_SMALLMAP_DISABLE_ALL, disable_all_tooltip);
// TODO this->GetWidget<NWidgetStacked>(WID_SM_SHOW_IND_NAMES_SEL)->SetDisplayedPlane(industry_names_select_plane);
this->GetWidget<NWidgetStacked>(WID_SM_SELECT_BUTTONS)->SetDisplayedPlane(select_buttons_plane);
this->SetWidgetDisabledState(WID_SM_SHOW_HEIGHT, this->map_type == CM_SMT_IMBA);
}
SmallMapWindow::SmallMapWindow(WindowDesc &desc, int window_number) : Window(desc)
{
_smallmap_industry_highlight = INVALID_INDUSTRYTYPE;
_smallmap_industry_highlight = IT_INVALID;
this->overlay = new LinkGraphOverlay(this, WID_SM_MAP, 0, this->GetOverlayCompanyMask(), 1);
this->InitNested(window_number);
this->LowerWidget(WID_SM_CONTOUR + this->map_type);
@@ -1264,16 +1267,16 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
/* Rebuild colour indices if necessary. */
if (SmallMapWindow::map_height_limit == _settings_game.construction.map_height_limit) return;
for (uint n = 0; n < lengthof(_heightmap_schemes); n++) {
for (auto &heightmap_scheme : _heightmap_schemes) {
/* The heights go from 0 up to and including maximum. */
int heights = _settings_game.construction.map_height_limit + 1;
_heightmap_schemes[n].height_colours = ReallocT<uint32>(_heightmap_schemes[n].height_colours, heights);
size_t heights = _settings_game.construction.map_height_limit + 1;
heightmap_scheme.height_colours.resize(heights);
for (int z = 0; z < heights; z++) {
size_t access_index = (_heightmap_schemes[n].colour_count * z) / heights;
for (size_t z = 0; z < heights; z++) {
size_t access_index = (heightmap_scheme.height_colours_base.size() * z) / heights;
/* Choose colour by mapping the range (0..max heightlevel) on the complete colour table. */
_heightmap_schemes[n].height_colours[z] = _heightmap_schemes[n].height_colours_base[access_index];
heightmap_scheme.height_colours[z] = heightmap_scheme.height_colours_base[access_index];
}
}
@@ -1281,12 +1284,14 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
BuildLandLegend();
}
/* virtual */ void SmallMapWindow::SetStringParameters(int widget) const
std::string SmallMapWindow::GetWidgetString(WidgetID widget, StringID stringid) const
{
switch (widget) {
case WID_SM_CAPTION:
SetDParam(0, STR_SMALLMAP_TYPE_CONTOURS + this->map_type);
break;
return GetString(STR_SMALLMAP_CAPTION, STR_SMALLMAP_TYPE_CONTOURS + this->map_type);
default:
return this->Window::GetWidgetString(widget, stringid);
}
}
@@ -1299,16 +1304,13 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
uint height = 0;
uint num_columns = 1;
for (const LegendAndColour *tbl = _legend_table[i]; !tbl->end; ++tbl) {
StringID str;
std::string str;
if (i == SMT_INDUSTRY || i == CM_SMT_IMBA) {
SetDParam(0, tbl->legend);
SetDParam(1, IndustryPool::MAX_SIZE);
str = STR_SMALLMAP_INDUSTRY;
str = GetString(STR_SMALLMAP_INDUSTRY, tbl->legend, IndustryPool::MAX_SIZE);
} else if (i == SMT_LINKSTATS) {
SetDParam(0, tbl->legend);
str = STR_SMALLMAP_LINKSTATS;
str = GetString(STR_SMALLMAP_LINKSTATS, tbl->legend);
} else if (i == SMT_OWNER) {
if (tbl->company != INVALID_COMPANY) {
if (tbl->company != CompanyID::Invalid()) {
if (!Company::IsValidID(tbl->company)) {
/* Rebuild the owner legend. */
BuildOwnerLegend();
@@ -1316,10 +1318,9 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
return;
}
/* Non-fixed legend entries for the owner view. */
SetDParam(0, tbl->company);
str = STR_SMALLMAP_COMPANY;
str = GetString(STR_SMALLMAP_COMPANY, tbl->company);
} else {
str = tbl->legend;
str = GetString(tbl->legend);
}
} else {
if (tbl->col_break) {
@@ -1328,7 +1329,12 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
num_columns++;
}
height++;
str = tbl->legend;
// TODO
// if (i == SMT_CONTOUR) {
// str = GetString(tbl->legend, tbl->height * TILE_HEIGHT_STEP);
// } else {
str = GetString(tbl->legend);
// }
}
min_width = std::max(GetStringBoundingBox(str).width, min_width);
}
@@ -1342,11 +1348,14 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
/* The width of a column is the minimum width of all texts + the size of the blob + some spacing */
this->column_width = min_width + this->legend_width + WidgetDimensions::scaled.framerect.Horizontal();
SetDParam(0, 9999999); // max reasonable population
this->town_cache.max_sign = GetStringBoundingBox(CM_STR_SMALLMAP_POPULATION);
/* Cached string widths of industry names in the smallmap. Calculation is deferred to DrawIndustryNames(). */
// TODO
// std::fill(std::begin(_industry_to_name_string_width), std::end(_industry_to_name_string_width), 0);
SetDParam(0, 9999);
auto text_dim = GetStringBoundingBox(STR_JUST_INT, FS_SMALL);
// max reasonable population is 9999999
this->town_cache.max_sign = GetStringBoundingBox(GetString(CM_STR_SMALLMAP_POPULATION, 9999999));
auto text_dim = GetStringBoundingBox(GetString(STR_JUST_INT, 9999), FS_SMALL);
this->industry_max_sign = {
text_dim.width + WidgetDimensions::scaled.framerect.Horizontal(),
text_dim.height * _max_industry_outputs + WidgetDimensions::scaled.framerect.Vertical(),
@@ -1357,7 +1366,7 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
{
if (this->map_type == SMT_OWNER) {
for (const LegendAndColour *tbl = _legend_table[this->map_type]; !tbl->end; ++tbl) {
if (tbl->company != INVALID_COMPANY && !Company::IsValidID(tbl->company)) {
if (tbl->company != CompanyID::Invalid() && !Company::IsValidID(tbl->company)) {
/* Rebuild the owner legend. */
BuildOwnerLegend();
this->InvalidateData(1);
@@ -1423,42 +1432,45 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
uint8 legend_colour = tbl->colour;
std::array<StringParameter, 2> params{};
switch (this->map_type) {
case SMT_INDUSTRY:
case CM_SMT_IMBA:
/* Industry name must be formatted, since it's not in tiny font in the specs.
* So, draw with a parameter and use the STR_SMALLMAP_INDUSTRY string, which is tiny font */
SetDParam(0, tbl->legend);
SetDParam(1, Industry::GetIndustryTypeCount(tbl->type));
params[0] = tbl->legend;
params[1] = Industry::GetIndustryTypeCount(tbl->type);
if (tbl->show_on_map && tbl->type == _smallmap_industry_highlight) {
legend_colour = _smallmap_industry_highlight_state ? PC_WHITE : PC_BLACK;
}
[[ fallthrough ]];
[[fallthrough]];
case SMT_LINKSTATS:
SetDParam(0, tbl->legend);
[[ fallthrough ]];
params[0] = tbl->legend;
[[fallthrough]];
case SMT_OWNER:
if (this->map_type != SMT_OWNER || tbl->company != INVALID_COMPANY) {
if (this->map_type == SMT_OWNER) SetDParam(0, tbl->company);
if (this->map_type != SMT_OWNER || tbl->company != CompanyID::Invalid()) {
if (this->map_type == SMT_OWNER) params[0] = tbl->company;
if (!tbl->show_on_map) {
/* Simply draw the string, not the black border of the legend colour.
* This will enforce the idea of the disabled item */
DrawString(text, string, TC_GREY);
DrawString(text, GetStringWithArgs(string, params), TC_GREY);
} else {
DrawString(text, string, TC_BLACK);
DrawString(text, GetStringWithArgs(string, params), TC_BLACK);
GfxFillRect(icon, PC_BLACK); // Outer border of the legend colour
}
break;
}
[[ fallthrough ]];
[[fallthrough]];
default:
if (this->map_type == SMT_CONTOUR) SetDParam(0, tbl->height * TILE_HEIGHT_STEP);
/* Anything that is not an industry or a company is using normal process */
GfxFillRect(icon, PC_BLACK);
DrawString(text, tbl->legend);
if (this->map_type == SMT_CONTOUR) {
DrawString(text, GetString(tbl->legend, tbl->height * TILE_HEIGHT_STEP));
} else {
DrawString(text, tbl->legend);
}
break;
}
GfxFillRect(icon.Shrink(WidgetDimensions::scaled.bevel), legend_colour); // Legend colour
@@ -1582,7 +1594,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
/* virtual */ void SmallMapWindow::OnMouseOver(Point pt, int widget)
{
IndustryType new_highlight = INVALID_INDUSTRYTYPE;
IndustryType new_highlight = IT_INVALID;
if (widget == WID_SM_LEGEND && (this->map_type == SMT_INDUSTRY || this->map_type == CM_SMT_IMBA)) {
int industry_pos = GetPositionOnLegend(pt);
if (industry_pos >= 0 && industry_pos < _smallmap_industry_count) {
@@ -1765,7 +1777,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
{
/* Update the window every now and then */
if (this->map_type == SMT_LINKSTATS) {
uint32 company_mask = this->GetOverlayCompanyMask();
CompanyMask company_mask = this->GetOverlayCompanyMask();
if (this->overlay->GetCompanyMask() != company_mask) {
this->overlay->SetCompanyMask(company_mask);
} else {
@@ -1801,7 +1813,7 @@ void SmallMapWindow::UpdateLinks()
/** Blink the industries (if hover over an industry). */
void SmallMapWindow::Blink()
{
if (_smallmap_industry_highlight == INVALID_INDUSTRYTYPE) return;
if (_smallmap_industry_highlight == IT_INVALID) return;
_smallmap_industry_highlight_state = !_smallmap_industry_highlight_state;
@@ -1812,7 +1824,7 @@ void SmallMapWindow::Blink()
/** Force a full refresh of the map. */
void SmallMapWindow::ForceRefresh()
{
if (_smallmap_industry_highlight != INVALID_INDUSTRYTYPE) return;
if (_smallmap_industry_highlight != IT_INVALID) return;
this->UpdateLinks();
this->SetDirty();
@@ -1834,7 +1846,7 @@ void SmallMapWindow::ForceRefresh()
*/
void SmallMapWindow::SmallMapCenterOnCurrentPos()
{
const Viewport *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
auto &vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
Point viewport_center = InverseRemapCoords2(vp->virtual_left + vp->virtual_width / 2, vp->virtual_top + vp->virtual_height / 2);
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);
@@ -1906,8 +1918,7 @@ void SmallMapWindow::UpdateTownCache(bool force) {
if (this->map_type == CM_SMT_IMBA) {
if (!IsSignVisible(rect, pt, this->town_cache.max_sign.width, this->town_cache.max_sign.height)) continue;
SetDParam(0, t->cache.population);
auto dim = GetStringBoundingBox(CM_STR_SMALLMAP_POPULATION);
auto dim = GetStringBoundingBox(GetString(CM_STR_SMALLMAP_POPULATION, t->cache.population));
if (!IsSignVisible(rect, pt, dim.width, dim.height)) continue;
@@ -2022,34 +2033,34 @@ static const NWidgetPart _nested_smallmap_bar[] = {
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SM_LEGEND), SetResize(1, 1),
NWidget(NWID_VERTICAL),
/* Top button row. */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_ZOOM_IN),
SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN), SetFill(1, 1),
SetSpriteTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN), SetFill(1, 1),
NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_CENTERMAP),
SetDataTip(SPR_IMG_SMALLMAP, STR_SMALLMAP_CENTER), SetFill(1, 1),
SetSpriteTip(SPR_IMG_SMALLMAP, STR_SMALLMAP_CENTER_TOOLTIP), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, CM_WID_SM_IMBA),
SetDataTip(SPR_IMG_SHOW_COUNTOURS, CM_STR_SMALLMAP_TOOLTIP_SHOW_IMBA_ON_MAP), SetFill(1, 1),
SetSpriteTip(SPR_IMG_SHOW_COUNTOURS, CM_STR_SMALLMAP_TOOLTIP_SHOW_IMBA_ON_MAP), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_CONTOUR),
SetDataTip(SPR_IMG_SHOW_COUNTOURS, STR_SMALLMAP_TOOLTIP_SHOW_LAND_CONTOURS_ON_MAP), SetFill(1, 1),
SetSpriteTip(SPR_IMG_SHOW_COUNTOURS, STR_SMALLMAP_TOOLTIP_SHOW_LAND_CONTOURS_ON_MAP), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_VEHICLES),
SetDataTip(SPR_IMG_SHOW_VEHICLES, STR_SMALLMAP_TOOLTIP_SHOW_VEHICLES_ON_MAP), SetFill(1, 1),
SetSpriteTip(SPR_IMG_SHOW_VEHICLES, STR_SMALLMAP_TOOLTIP_SHOW_VEHICLES_ON_MAP), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_INDUSTRIES),
SetDataTip(SPR_IMG_INDUSTRY, STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP), SetFill(1, 1),
SetSpriteTip(SPR_IMG_INDUSTRY, STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP), SetFill(1, 1),
EndContainer(),
/* Bottom button row. */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_ZOOM_OUT),
SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT), SetFill(1, 1),
SetSpriteTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_TOGGLETOWNNAME),
SetDataTip(SPR_IMG_TOWN, STR_SMALLMAP_TOOLTIP_TOGGLE_TOWN_NAMES_ON_OFF), SetFill(1, 1),
SetSpriteTip(SPR_IMG_TOWN, STR_SMALLMAP_TOOLTIP_TOGGLE_TOWN_NAMES_ON_OFF), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_LINKSTATS),
SetDataTip(SPR_IMG_CARGOFLOW, STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP), SetFill(1, 1),
SetSpriteTip(SPR_IMG_CARGOFLOW, STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_ROUTES),
SetDataTip(SPR_IMG_SHOW_ROUTES, STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON), SetFill(1, 1),
SetSpriteTip(SPR_IMG_SHOW_ROUTES, STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_VEGETATION),
SetDataTip(SPR_IMG_PLANTTREES, STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP), SetFill(1, 1),
SetSpriteTip(SPR_IMG_PLANTTREES, STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_OWNERS),
SetDataTip(SPR_IMG_COMPANY_GENERAL, STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP), SetFill(1, 1),
SetSpriteTip(SPR_IMG_COMPANY_GENERAL, STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP), SetFill(1, 1),
EndContainer(),
NWidget(NWID_SPACER), SetResize(0, 1),
EndContainer(),
@@ -2070,7 +2081,7 @@ static std::unique_ptr<NWidgetBase> SmallMapDisplay()
static const NWidgetPart _nested_smallmap_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SM_CAPTION), SetDataTip(STR_SMALLMAP_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SM_CAPTION),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
@@ -2079,10 +2090,10 @@ static const NWidgetPart _nested_smallmap_widgets[] = {
/* Bottom button row and resize box. */
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SM_SELECT_BUTTONS),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SM_ENABLE_ALL), SetDataTip(STR_SMALLMAP_ENABLE_ALL, STR_NULL),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SM_DISABLE_ALL), SetDataTip(STR_SMALLMAP_DISABLE_ALL, STR_NULL),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SM_SHOW_HEIGHT), SetDataTip(STR_SMALLMAP_SHOW_HEIGHT, STR_SMALLMAP_TOOLTIP_SHOW_HEIGHT),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SM_ENABLE_ALL), SetStringTip(STR_SMALLMAP_ENABLE_ALL),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SM_DISABLE_ALL), SetStringTip(STR_SMALLMAP_DISABLE_ALL),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SM_SHOW_HEIGHT), SetStringTip(STR_SMALLMAP_SHOW_HEIGHT, STR_SMALLMAP_TOOLTIP_SHOW_HEIGHT),
NWidget(WWT_PANEL, COLOUR_BROWN), SetFill(1, 0), SetResize(1, 0),
EndContainer(),
EndContainer(),
@@ -2096,7 +2107,7 @@ static const NWidgetPart _nested_smallmap_widgets[] = {
static WindowDesc _smallmap_desc(
WDP_AUTO, "cm_minimap", 484, 314,
WC_SMALLMAP, WC_NONE,
0,
{},
_nested_smallmap_widgets
);

View File

@@ -12,7 +12,7 @@ extern CompanyID _local_company;
namespace citymania {
#define MKCOLOUR(x) TO_LE32X(x)
#define MKCOLOUR(x) TO_LE32(x)
#define MKCOLOURGROUP(x, y) \
MKCOLOUR(((uint32)(x) << 24) | ((uint32)(x) << 16) | ((uint32)(x) << 8) | (uint32)(x)), \
MKCOLOUR(((uint32)(x) << 24) | ((uint32)(y) << 16) | ((uint32)(y) << 8) | (uint32)(x)), \
@@ -186,9 +186,9 @@ protected:
* the _local_company. Spectators get to see all companies' links.
* @return Company mask.
*/
inline uint32 GetOverlayCompanyMask() const
inline CompanyMask GetOverlayCompanyMask() const
{
return Company::IsValidID(_local_company) ? 1U << _local_company : 0xffffffff;
return Company::IsValidID(_local_company) ? CompanyMask{}.Set(_local_company) : CompanyMask{}.Set();
}
/** Blink the industries (if selected) on a regular interval. */
@@ -237,7 +237,6 @@ public:
void SmallMapCenterOnCurrentPos();
Point GetStationMiddle(const Station *st) const;
void SetStringParameters(int widget) const override;
void OnInit() override;
void OnPaint() override;
void DrawWidget(const Rect &r, int widget) const override;
@@ -249,6 +248,7 @@ public:
// void OnHundredthTick() override;
void OnScroll(Point delta) override;
void OnMouseOver(Point pt, int widget) override;
std::string GetWidgetString(WidgetID widget, StringID stringid) const override;
};
} // namespace citymania

View File

@@ -29,7 +29,7 @@ static const NWidgetPart _nested_land_info_widgets[] = {
static WindowDesc _land_info_desc(
WDP_MANUAL, nullptr, 0, 0,
WC_LAND_INFO, WC_NONE,
0,
{},
_nested_land_info_widgets
);
@@ -43,8 +43,8 @@ class LandInfoWindow : public Window {
static const uint LAND_INFO_LINE_BUFF_SIZE = 512;
public:
StringList landinfo_data; ///< Info lines to show.
std::string cargo_acceptance; ///< Centered multi-line string for cargo acceptance.
StringList landinfo_data{}; ///< Info lines to show.
std::string cargo_acceptance{}; ///< Centered multi-line string for cargo acceptance.
TileIndex tile;
TileIndex end_tile; ///< For use in ruler(dragdrop) mode
@@ -75,8 +75,7 @@ public:
}
if (!this->cargo_acceptance.empty()) {
SetDParamStr(0, this->cargo_acceptance);
DrawStringMultiLine(ir, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER);
DrawStringMultiLine(ir, this->cargo_acceptance, TC_FROMSTRING, SA_CENTER);
}
}
@@ -95,15 +94,14 @@ public:
if (!this->cargo_acceptance.empty()) {
uint width = GetStringBoundingBox(this->cargo_acceptance).width + WidgetDimensions::scaled.frametext.Horizontal();
size.width = std::max(size.width, std::min(static_cast<uint>(ScaleGUITrad(300)), width));
SetDParamStr(0, cargo_acceptance);
size.height += GetStringHeight(STR_JUST_RAW_STRING, size.width - WidgetDimensions::scaled.frametext.Horizontal());
size.height += GetStringHeight(cargo_acceptance, size.width - WidgetDimensions::scaled.frametext.Horizontal());
}
}
LandInfoWindow(Tile tile, Tile end_tile) : Window(_land_info_desc), tile(tile), end_tile(end_tile)
{
this->InitNested();
CLRBITS(this->flags, WF_WHITE_BORDER);
this->flags.Reset(WindowFlag::WhiteBorder);
#if defined(_DEBUG)
# define LANDINFOD_LEVEL 0
@@ -126,206 +124,150 @@ public:
void OnInit() override
{
Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
/* Because build_date is not set yet in every TileDesc, we make sure it is empty */
TileDesc td;
TileDesc td{};
td.build_date = CalendarTime::INVALID_DATE;
/* Most tiles have only one owner, but
* - drivethrough roadstops can be build on town owned roads (up to 2 owners) and
* - roads can have up to four owners (railroad, road, tram, 3rd-roadtype "highway").
*/
td.owner_type[0] = STR_LAND_AREA_INFORMATION_OWNER; // At least one owner is displayed, though it might be "N/A".
td.owner_type[1] = STR_NULL; // STR_NULL results in skipping the owner
td.owner_type[2] = STR_NULL;
td.owner_type[3] = STR_NULL;
td.owner[0] = OWNER_NONE;
td.owner[1] = OWNER_NONE;
td.owner[2] = OWNER_NONE;
td.owner[3] = OWNER_NONE;
td.station_class = STR_NULL;
td.station_name = STR_NULL;
td.airport_class = STR_NULL;
td.airport_name = STR_NULL;
td.airport_tile_name = STR_NULL;
td.railtype = STR_NULL;
td.rail_speed = 0;
td.roadtype = STR_NULL;
td.road_speed = 0;
td.tramtype = STR_NULL;
td.tram_speed = 0;
td.cm_population = 0;
td.grf = nullptr;
CargoArray acceptance{};
AddAcceptedCargo(tile, acceptance, nullptr);
GetTileDesc(tile, &td);
GetTileDesc(tile, td);
this->landinfo_data.clear();
/* Tiletype */
SetDParam(0, td.dparam);
this->landinfo_data.push_back(GetString(td.str));
this->landinfo_data.push_back(GetString(td.str, td.dparam));
/* Up to four owners */
for (uint i = 0; i < 4; i++) {
if (td.owner_type[i] == STR_NULL) continue;
SetDParam(0, STR_LAND_AREA_INFORMATION_OWNER_N_A);
if (td.owner[i] != OWNER_NONE && td.owner[i] != OWNER_WATER) SetDParamsForOwnedBy(td.owner[i], tile);
this->landinfo_data.push_back(GetString(td.owner_type[i]));
if (td.owner[i] == OWNER_NONE || td.owner[i] == OWNER_WATER) {
this->landinfo_data.push_back(GetString(td.owner_type[i], STR_LAND_AREA_INFORMATION_OWNER_N_A, std::monostate{}));
} else {
auto params = GetParamsForOwnedBy(td.owner[i], tile);
this->landinfo_data.push_back(GetStringWithArgs(td.owner_type[i], params));
}
}
/* Cost to clear/revenue when cleared */
StringID str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A;
Company *c = Company::GetIfValid(_local_company);
if (c != nullptr) {
assert(_current_company == _local_company);
CommandCost costclear = Command<CMD_LANDSCAPE_CLEAR>::Do(DC_QUERY_COST, tile);
CommandCost costclear = Command<CMD_LANDSCAPE_CLEAR>::Do(DoCommandFlag::QueryCost, tile);
if (costclear.Succeeded()) {
Money cost = costclear.GetCost();
StringID str;
if (cost < 0) {
cost = -cost; // Negate negative cost to a positive revenue
str = STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED;
} else {
str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR;
}
SetDParam(0, cost);
this->landinfo_data.push_back(GetString(str, cost));
} else {
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A));
}
} else {
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A));
}
this->landinfo_data.push_back(GetString(str));
/* Location */
std::stringstream tile_ss;
tile_ss << "0x" << std::setfill('0') << std::setw(4) << std::hex << std::uppercase << tile.base(); // 0x%.4X
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LANDINFO_COORDS, TileX(tile), TileY(tile), GetTileZ(tile)));
SetDParam(0, TileX(tile));
SetDParam(1, TileY(tile));
SetDParam(2, GetTileZ(tile));
SetDParamStr(3, tile_ss.str());
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LANDINFO_COORDS));
/* Tile index */
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LANDINFO_INDEX, tile, tile));
/* Local authority */
SetDParam(0, STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE);
if (t != nullptr) {
SetDParam(0, STR_TOWN_NAME);
SetDParam(1, t->index);
if (t == nullptr) {
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY, STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE, std::monostate{}));
} else {
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY, STR_TOWN_NAME, t->index));
}
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY));
/* Build date */
if (td.build_date != CalendarTime::INVALID_DATE) {
SetDParam(0, td.build_date);
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_BUILD_DATE));
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_BUILD_DATE, td.build_date));
}
/* Station class */
if (td.station_class != STR_NULL) {
SetDParam(0, td.station_class);
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_STATION_CLASS));
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_STATION_CLASS, td.station_class));
}
/* Station type name */
if (td.station_name != STR_NULL) {
SetDParam(0, td.station_name);
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_STATION_TYPE));
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_STATION_TYPE, td.station_name));
}
/* Airport class */
if (td.airport_class != STR_NULL) {
SetDParam(0, td.airport_class);
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_AIRPORT_CLASS));
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_AIRPORT_CLASS, td.airport_class));
}
/* Airport name */
if (td.airport_name != STR_NULL) {
SetDParam(0, td.airport_name);
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_AIRPORT_NAME));
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_AIRPORT_NAME, td.airport_name));
}
/* Airport tile name */
if (td.airport_tile_name != STR_NULL) {
SetDParam(0, td.airport_tile_name);
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME));
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME, td.airport_tile_name));
}
/* Rail type name */
if (td.railtype != STR_NULL) {
SetDParam(0, td.railtype);
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_RAIL_TYPE));
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_RAIL_TYPE, td.railtype));
}
/* Rail speed limit */
if (td.rail_speed != 0) {
SetDParam(0, PackVelocity(td.rail_speed, VEH_TRAIN));
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT));
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT, PackVelocity(td.rail_speed, VEH_TRAIN)));
}
/* Road type name */
if (td.roadtype != STR_NULL) {
SetDParam(0, td.roadtype);
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_ROAD_TYPE));
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_ROAD_TYPE, td.roadtype));
}
/* Road speed limit */
if (td.road_speed != 0) {
SetDParam(0, PackVelocity(td.road_speed, VEH_ROAD));
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT));
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT, PackVelocity(td.road_speed, VEH_ROAD)));
}
/* Tram type name */
if (td.tramtype != STR_NULL) {
SetDParam(0, td.tramtype);
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_TRAM_TYPE));
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_TRAM_TYPE, td.tramtype));
}
/* Tram speed limit */
if (td.tram_speed != 0) {
SetDParam(0, PackVelocity(td.tram_speed, VEH_ROAD));
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT));
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT, PackVelocity(td.tram_speed, VEH_ROAD)));
}
/* Tile protection status */
if (td.town_can_upgrade.has_value()) {
this->landinfo_data.push_back(GetString(td.town_can_upgrade.value() ? STR_LAND_AREA_INFORMATION_TOWN_CAN_UPGRADE : STR_LAND_AREA_INFORMATION_TOWN_CANNOT_UPGRADE));
}
/* NewGRF name */
if (td.grf != nullptr) {
SetDParamStr(0, td.grf);
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_NEWGRF_NAME));
if (td.grf.has_value()) {
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_NEWGRF_NAME, std::move(*td.grf)));
}
/* CityMania code start (House pop) */
if (td.cm_population != 0) {
SetDParam(0, td.cm_population);
this->landinfo_data.push_back(GetString(CM_STR_LAND_AREA_INFORMATION_POP));
this->landinfo_data.push_back(GetString(CM_STR_LAND_AREA_INFORMATION_POP, td.cm_population));
}
/* CityMania code end */
/* Cargo acceptance is displayed in a extra multiline */
std::stringstream line;
line << GetString(STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED);
bool found = false;
for (const CargoSpec *cs : _sorted_cargo_specs) {
CargoID cid = cs->Index();
if (acceptance[cid] > 0) {
/* Add a comma between each item. */
if (found) line << ", ";
found = true;
/* If the accepted value is less than 8, show it in 1/8:ths */
if (acceptance[cid] < 8) {
SetDParam(0, acceptance[cid]);
SetDParam(1, cs->name);
line << GetString(STR_LAND_AREA_INFORMATION_CARGO_EIGHTS);
} else {
line << GetString(cs->name);
}
}
}
if (found) {
this->cargo_acceptance = line.str();
auto line = BuildCargoAcceptanceString(acceptance, STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED);
if (line.has_value()) {
this->cargo_acceptance = std::move(*line);
} else {
this->cargo_acceptance.clear();
}

View File

@@ -2,7 +2,6 @@
#include "cm_overlays.hpp"
#include "3rdparty/fmt/core.h"
#include "cm_client_list_gui.hpp"
#include "../blitter/factory.hpp" // Blitter BlitterFactory
@@ -18,8 +17,8 @@
#include "../zoom_func.h"
#include "../safeguards.h"
#include "gfx_type.h"
#include "table/sprites.h"
#include "../gfx_type.h"
#include "../table/sprites.h"
namespace citymania {

View File

@@ -11,7 +11,7 @@
#include "../safeguards.h"
extern TileIndex _rail_track_endtile; // rail_cmd.cpp
extern TileIndex _cm_rail_track_endtile; // rail_cmd.cpp
namespace citymania {
@@ -44,12 +44,12 @@ static sp<Command> DoRailroadTrack(TileIndex start_tile, TileIndex end_tile, Rai
static bool DoAutodirTerraform(bool diagonal, TileIndex start_tile, TileIndex /* end_tile */, Track track, sp<Command> rail_cmd, TileIndex s1, TileIndex e1, TileIndex s2, TileIndex e2, bool /* remove_mode */) {
auto rail_callback = [rail_cmd, start_tile, track, estimate=citymania::_estimate_mod](bool res) -> bool{
if (rail_cmd->call(DC_AUTO | DC_NO_WATER).GetErrorMessage() != STR_ERROR_ALREADY_BUILT ||
_rail_track_endtile == INVALID_TILE) {
if (rail_cmd->call({DoCommandFlag::Auto, DoCommandFlag::NoWater}).GetErrorMessage() != STR_ERROR_ALREADY_BUILT ||
_cm_rail_track_endtile == INVALID_TILE) {
if (!rail_cmd->post()) return false;
}
if (!estimate && _rail_track_endtile != INVALID_TILE)
StoreRailPlacementEndpoints(start_tile, _rail_track_endtile, track, true);
if (!estimate && _cm_rail_track_endtile != INVALID_TILE)
StoreRailPlacementEndpoints(start_tile, _cm_rail_track_endtile, track, true);
return res;
};
@@ -57,8 +57,8 @@ static bool DoAutodirTerraform(bool diagonal, TileIndex start_tile, TileIndex /*
auto h2 = TileHeight(s2);
auto cmd1 = cmd::LevelLand(e1, s1, diagonal, h1 < h2 ? LM_RAISE : LM_LEVEL);
auto cmd2 = cmd::LevelLand(e2, s2, diagonal, h2 < h1 ? LM_RAISE : LM_LEVEL);
auto c1_fail = cmd1.call(DC_AUTO | DC_NO_WATER).Failed();
auto c2_fail = cmd2.call(DC_AUTO | DC_NO_WATER).Failed();
auto c1_fail = cmd1.call({DoCommandFlag::Auto, DoCommandFlag::NoWater}).Failed();
auto c2_fail = cmd2.call({DoCommandFlag::Auto, DoCommandFlag::NoWater}).Failed();
if (c1_fail && c2_fail) return rail_callback(true);
if (c2_fail) return cmd1.with_callback(rail_callback).post();
if (!c1_fail) cmd1.post();
@@ -163,14 +163,14 @@ void HandleAutodirPlacement(RailType railtype, bool remove_mode) {
Track trackstat = static_cast<Track>( _thd.drawstyle & HT_DIR_MASK); // 0..5
citymania::HandleAutodirTerraform(start_tile, end_tile, trackstat, std::move(cmd), remove_mode);
return;
} else if (cmd->call(DC_AUTO | DC_NO_WATER).GetErrorMessage() != STR_ERROR_ALREADY_BUILT ||
_rail_track_endtile == INVALID_TILE) {
} else if (cmd->call({DoCommandFlag::Auto, DoCommandFlag::NoWater}).GetErrorMessage() != STR_ERROR_ALREADY_BUILT ||
_cm_rail_track_endtile == INVALID_TILE) {
if (!cmd->post(CcPlaySound_CONSTRUCTION_RAIL)) return;
}
/* Save new snap points for the polyline tool, no matter if the command
* succeeded, the snapping will be extended over overbuilt track pieces. */
if (!citymania::_estimate_mod && _rail_track_endtile != INVALID_TILE) {
StoreRailPlacementEndpoints(start_tile, _rail_track_endtile, trackstat, true);
if (!citymania::_estimate_mod && _cm_rail_track_endtile != INVALID_TILE) {
StoreRailPlacementEndpoints(start_tile, _cm_rail_track_endtile, trackstat, true);
}
}

View File

@@ -35,7 +35,7 @@ struct LimitsSettings {
class CBRequirement {
public:
CargoID cargo_id;
CargoType cargo_type;
uint32_t from;
uint32_t amount;
uint8_t decay;
@@ -45,9 +45,9 @@ public:
static CBRequirement Parse(const char *name, const char *value, uint8_t index);
CBRequirement(CargoID cargo_id, uint32_t from, uint32_t amount, uint8_t decay,
CBRequirement(CargoType cargo_type, uint32_t from, uint32_t amount, uint8_t decay,
uint8_t index, std::string name)
:cargo_id{cargo_id}, from{from}, amount{amount}, decay{decay},
:cargo_type{cargo_type}, from{from}, amount{amount}, decay{decay},
index{index}, name{name}, has_storage{decay < 100} {}
};

View File

@@ -41,7 +41,7 @@ bool _remove_button_clicked; // replace vanilla static vars
extern const Station *_viewport_highlight_station;
extern TileHighlightData _thd;
extern bool CheckClickOnViewportSign(const Viewport *vp, int x, int y, const ViewportSign *sign);
extern bool CheckClickOnViewportSign(const Viewport &vp, int x, int y, const ViewportSign *sign);
extern Rect ExpandRectWithViewportSignMargins(Rect r, ZoomLevel zoom);
extern RoadBits FindRailsToConnect(TileIndex tile);
extern ViewportSignKdtree _viewport_sign_kdtree;
@@ -185,10 +185,10 @@ const Station *CheckClickOnDeadStationSign() {
const Station *last_st = nullptr;
_viewport_sign_kdtree.FindContained(search_rect.left, search_rect.top, search_rect.right, search_rect.bottom, [&](const ViewportSignKdtreeItem & item) {
if (item.type != ViewportSignKdtreeItem::VKI_STATION) return;
auto st = Station::Get(item.id.station);
auto st = Station::Get(std::get<StationID>(item.id));
if (st->IsInUse()) return;
if (_local_company != st->owner) return;
if (CheckClickOnViewportSign(vp, x, y, &st->sign)) last_st = st;
if (CheckClickOnViewportSign(*vp, x, y, &st->sign)) last_st = st;
});
return last_st;
}
@@ -212,7 +212,7 @@ template <typename Tcommand, typename Tcallback>
void JoinAndBuild(Tcommand command, Tcallback *callback) {
auto join_to = _highlight_station_to_join;
command.adjacent = (citymania::_fn_mod || join_to);
command.station_to_join = INVALID_STATION;
command.station_to_join = StationID::Invalid();
if (citymania::_fn_mod) command.station_to_join = NEW_STATION;
else if (join_to) command.station_to_join = join_to->index;
@@ -370,7 +370,7 @@ void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, RoadStopType stop_t
rt,
spec_class,
spec_index,
INVALID_STATION,
StationID::Invalid(),
adjacent
);
c.with_error(err_msg);
@@ -385,7 +385,7 @@ void HandleStationPlacement(TileIndex start, TileIndex end)
uint numtracks = ta.w;
uint platlength = ta.h;
if (_station_gui.axis == AXIS_X) Swap(numtracks, platlength);
if (_station_gui.axis == AXIS_X) std::swap(numtracks, platlength);
auto c = cmd::BuildRailStation(
ta.tile,
@@ -395,7 +395,7 @@ void HandleStationPlacement(TileIndex start, TileIndex end)
platlength,
_station_gui.sel_class,
_station_gui.sel_type,
INVALID_STATION,
StationID::Invalid(),
false
);
c.with_error(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION);
@@ -412,7 +412,7 @@ void PlaceRail_Station(TileIndex tile) {
_settings_client.gui.station_platlength,
_station_gui.sel_class,
_station_gui.sel_type,
INVALID_STATION,
StationID::Invalid(),
false
);
c.with_error(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION);
@@ -424,7 +424,7 @@ void PlaceDock(TileIndex tile, TileIndex tile_to) {
auto c = cmd::BuildDock(
tile,
INVALID_STATION,
StationID::Invalid(),
false
);
c.with_error(STR_ERROR_CAN_T_BUILD_DOCK_HERE);
@@ -443,7 +443,7 @@ void PlaceAirport(TileIndex tile) {
tile,
airport_type,
layout,
INVALID_STATION,
StationID::Invalid(),
false
);
c.with_error(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE);
@@ -532,13 +532,13 @@ static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
const HouseSpec *hs = HouseSpec::Get(house_id);
Town *t = Town::GetByTile(tile);
if (HasBit(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) {
if (hs->callback_mask.Test(HouseCallbackMask::ProduceCargo)) {
for (uint i = 0; i < 256; i++) {
uint16 callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
CargoID cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
if (cargo == CT_INVALID) continue;
produced[cargo] += GetMonthlyFrom256Tick((uint)GB(callback, 0, 8)) ;
@@ -607,7 +607,7 @@ CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad)
if (i->neutral_station != nullptr && !_settings_game.station.serve_neutral_industries) continue;
for (const auto &p : i->produced) {
if (IsValidCargoID(p.cargo)) produced[p.cargo] += ((uint)p.history[LAST_MONTH].production) << 8;
if (IsValidCargoType(p.cargo)) produced[p.cargo] += ((uint)p.history[LAST_MONTH].production) << 8;
}
}
@@ -620,19 +620,17 @@ std::string GetStationCoverageProductionText(TileIndex tile, int w, int h, int r
std::ostringstream s;
s << GetString(CM_STR_STATION_BUILD_SUPPLIES);
bool first = true;
for (CargoID i = 0; i < NUM_CARGO; i++) {
for (CargoType i = 0; i < NUM_CARGO; i++) {
if (production[i] == 0) continue;
switch (sct) {
case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(i, CC_PASSENGERS)) continue; break;
case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(i, CC_PASSENGERS)) continue; break;
case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(i, CargoClass::Passengers)) continue; break;
case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(i, CargoClass::Passengers)) continue; break;
case SCT_ALL: break;
default: NOT_REACHED();
}
if (!first) s << ", ";
first = false;
SetDParam(0, i);
SetDParam(1, production[i] >> 8);
s << GetString(STR_JUST_CARGO);
s << GetString(STR_JUST_CARGO, i, production[i] >> 8);
}
return s.str();
}
@@ -640,13 +638,13 @@ std::string GetStationCoverageProductionText(TileIndex tile, int w, int h, int r
// ---- NEw code
StationID _station_to_join = INVALID_STATION;
StationID _station_to_join = StationID::Invalid();
std::chrono::time_point<std::chrono::system_clock> _station_to_join_selected;
void OnStationRemoved(const Station *station) {
if (_last_built_station == station) _last_built_station = nullptr;
if (_station_to_join == station->index) {
_station_to_join = INVALID_STATION;
_station_to_join = StationID::Invalid();
}
if (_ap.preview != nullptr) _ap.preview->OnStationRemoved(station);
}
@@ -731,7 +729,7 @@ up<Command> RailStationPreview::GetCommand(bool adjacent, StationID join_to) con
auto start_tile = ta.tile;
auto numtracks = ta.w;
auto platlength = ta.h;
if (_station_gui.axis == AXIS_X) Swap(numtracks, platlength);
if (_station_gui.axis == AXIS_X) std::swap(numtracks, platlength);
auto res = make_up<cmd::BuildRailStation>(
start_tile,
@@ -857,7 +855,7 @@ up<Command> RoadStationPreview::GetRemoveCommand() const {
citymania::_fn_mod
);
auto rti = GetRoadTypeInfo(_cur_roadtype);
res->with_error(rti->strings.err_remove_station[this->stop_type]);
// res->with_error(rti->strings.err_remove_station[this->stop_type]);
return res;
}
@@ -880,7 +878,7 @@ void RoadStationPreview::AddPreviewTiles(Preview::TileMap &tiles, SpriteID palet
palette,
cmdt->rt,
ddir,
cmdt->stop_type == ROADSTOP_TRUCK,
cmdt->stop_type == RoadStopType::Truck,
cmdt->spec_class,
cmdt->spec_index
));
@@ -890,8 +888,8 @@ void RoadStationPreview::AddPreviewTiles(Preview::TileMap &tiles, SpriteID palet
OverlayParams RoadStationPreview::GetOverlayParams() const {
return {
this->GetArea(false),
this->stop_type == ROADSTOP_TRUCK ? CA_TRUCK : CA_BUS,
this->stop_type == ROADSTOP_TRUCK ? SCT_NON_PASSENGERS_ONLY : SCT_PASSENGERS_ONLY
this->stop_type == RoadStopType::Truck ? CA_TRUCK : CA_BUS,
this->stop_type == RoadStopType::Truck ? SCT_NON_PASSENGERS_ONLY : SCT_PASSENGERS_ONLY
};
}
@@ -1050,12 +1048,12 @@ std::vector<std::pair<SpriteID, std::string>> StationPreviewBase::GetOverlayData
if (!_settings_game.station.modified_catchment) params.radius = CA_UNMODIFIED;
auto production = citymania::GetProductionAroundTiles(params.area.tile, params.area.w, params.area.h, params.radius);
bool has_header = false;
for (CargoID i = 0; i < NUM_CARGO; i++) {
for (CargoType i = 0; i < NUM_CARGO; i++) {
if (production[i] == 0) continue;
switch (params.coverage_type) {
case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(i, CC_PASSENGERS)) continue; break;
case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(i, CC_PASSENGERS)) continue; break;
case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(i, CargoClass::Passengers)) continue; break;
case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(i, CargoClass::Passengers)) continue; break;
case SCT_ALL: break;
default: NOT_REACHED();
}
@@ -1067,9 +1065,8 @@ std::vector<std::pair<SpriteID, std::string>> StationPreviewBase::GetOverlayData
res.emplace_back(PAL_NONE, GetString(CM_STR_BUILD_INFO_OVERLAY_STATION_SUPPLIES));
has_header = true;
}
SetDParam(0, i);
SetDParam(1, production[i] >> 8);
res.emplace_back(cs->GetCargoIcon(), GetString(CM_STR_BUILD_INFO_OVERLAY_STATION_CARGO));
res.emplace_back(cs->GetCargoIcon(),
GetString(CM_STR_BUILD_INFO_OVERLAY_STATION_CARGO, i, production[i] >> 8));
}
return res;
}
@@ -1100,13 +1097,13 @@ void VanillaStationPreview::Update(Point pt, TileIndex tile) {
this->palette = CM_PALETTE_TINT_WHITE;
if (this->remove_mode) return;
if (this->selected_station_to_join != INVALID_STATION) {
if (this->selected_station_to_join != StationID::Invalid()) {
this->station_to_join = this->selected_station_to_join;
return;
}
if (!IsValidTile(this->type->cur_tile)) return;
this->station_to_join = INVALID_STATION;
this->station_to_join = StationID::Invalid();
auto area = this->type->GetArea(false);
area.Expand(1);
area.ClampToMap();
@@ -1114,8 +1111,8 @@ void VanillaStationPreview::Update(Point pt, TileIndex tile) {
if (IsTileType(tile, MP_STATION) && GetTileOwner(tile) == _local_company) {
Station *st = Station::GetByTile(tile);
if (st == nullptr || st->index == this->station_to_join) continue;
if (this->station_to_join != INVALID_STATION) {
this->station_to_join = INVALID_STATION;
if (this->station_to_join != StationID::Invalid()) {
this->station_to_join = StationID::Invalid();
this->palette = CM_PALETTE_TINT_YELLOW;
break;
}
@@ -1123,15 +1120,15 @@ void VanillaStationPreview::Update(Point pt, TileIndex tile) {
// TODO check for command to return multiple? but also check each to
// see if they can be built
// if (this->GetCommand(true, st->index)->test().Succeeded()) {
// if (this->station_to_join != INVALID_STATION) {
// this->station_to_join = INVALID_STATION;
// if (this->station_to_join != StationID::Invalid()) {
// this->station_to_join = StationID::Invalid();
// this->palette = CM_PALETTE_TINT_YELLOW;
// break;
// } else this->station_to_join = st->index;
// }
}
}
if (this->station_to_join == INVALID_STATION && !this->GetCommand(true, NEW_STATION)->test().Succeeded())
if (this->station_to_join == StationID::Invalid() && !this->GetCommand(true, NEW_STATION)->test().Succeeded())
this->palette = CM_PALETTE_TINT_RED_DEEP;
}
@@ -1149,8 +1146,8 @@ void VanillaStationPreview::Execute() {
}
void VanillaStationPreview::OnStationRemoved(const Station *station) {
if (this->station_to_join == station->index) this->station_to_join = INVALID_STATION;
if (this->selected_station_to_join == station->index) this->station_to_join = INVALID_STATION;
if (this->station_to_join == station->index) this->station_to_join = StationID::Invalid();
if (this->selected_station_to_join == station->index) this->station_to_join = StationID::Invalid();
}
StationPreview::StationPreview(sp<PreviewStationType> type)
@@ -1158,7 +1155,7 @@ StationPreview::StationPreview(sp<PreviewStationType> type)
{
auto seconds_since_selected = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - _station_to_join_selected).count();
if (seconds_since_selected < 30) this->station_to_join = _station_to_join;
else this->station_to_join = INVALID_STATION;
else this->station_to_join = StationID::Invalid();
}
StationPreview::~StationPreview() {
@@ -1225,8 +1222,8 @@ bool StationPreview::HandleMousePress() {
_station_to_join = this->station_to_join;
_station_to_join_selected = std::chrono::system_clock::now();
} else {
this->station_to_join = INVALID_STATION;
_station_to_join = INVALID_STATION;
this->station_to_join = StationID::Invalid();
_station_to_join = StationID::Invalid();
}
return true;
}
@@ -1239,7 +1236,7 @@ void StationPreview::Execute() {
}
void StationPreview::OnStationRemoved(const Station *station) {
if (this->station_to_join == station->index) this->station_to_join = INVALID_STATION;
if (this->station_to_join == station->index) this->station_to_join = StationID::Invalid();
}
void SetSelectedStationToJoin(StationID station_id) {

View File

@@ -145,7 +145,7 @@ protected:
sp<PreviewStationType> type;
bool remove_mode = false;
bool keep_rail = true; // whether to keep rail in remove mode
StationID station_to_join = INVALID_STATION;
StationID station_to_join = StationID::Invalid();
bool show_coverage = true;
void AddAreaTiles(Preview::TileMap &tiles, bool add_current, bool show_join_area);
@@ -170,7 +170,7 @@ protected:
void Execute() override;
public:
StationID selected_station_to_join = INVALID_STATION;
StationID selected_station_to_join = StationID::Invalid();
VanillaStationPreview(sp<PreviewStationType> type) :StationPreviewBase{type} {};
virtual ~VanillaStationPreview() {};

View File

@@ -1,7 +1,7 @@
#ifndef CMEXT_SURVEY_HPP
#define CMEXT_SURVEY_HPP
#include "3rdparty/nlohmann/json.hpp"
#include "../3rdparty/nlohmann/json.hpp"
namespace citymania {

View File

@@ -32,7 +32,7 @@ static const NWidgetPart _nested_land_tooltips_widgets[] = {
static WindowDesc _land_tooltips_desc(
WDP_MANUAL, nullptr, 0, 0,
CM_WC_LAND_TOOLTIPS, WC_NONE,
0,
{},
_nested_land_tooltips_widgets
);
@@ -48,7 +48,8 @@ struct LandTooltipsWindow : public Window
this->tiletype = (TileType)(param & 0xFFFF);
this->objIndex = (uint16)((param >> 16) & 0xFFFF);
this->InitNested();
CLRBITS(this->flags, WF_WHITE_BORDER);
this->flags.Reset(WindowFlag::WhiteBorder);
}
virtual ~LandTooltipsWindow() {}
@@ -78,30 +79,29 @@ struct LandTooltipsWindow : public Window
case MP_HOUSE: {
const HouseSpec *hs = HouseSpec::Get((HouseID)this->objIndex);
if(hs == NULL) break;
SetDParam(0, hs->building_name);
size.width = std::max(GetStringBoundingBox(CM_STR_LAND_TOOLTIPS_HOUSE_NAME).width, size.width);
size.width = std::max(GetStringBoundingBox(GetString(CM_STR_LAND_TOOLTIPS_HOUSE_NAME, hs->building_name)).width, size.width);
size.height += text_height;
SetDParam(0, hs->population);
size.width = std::max(size.width, GetStringBoundingBox(CM_STR_LAND_TOOLTIPS_HOUSE_POPULATION).width);
size.width = std::max(size.width, GetStringBoundingBox(GetString(CM_STR_LAND_TOOLTIPS_HOUSE_POPULATION, hs->population)).width);
break;
}
case MP_INDUSTRY: {
const Industry *ind = Industry::GetIfValid((IndustryID)this->objIndex);
if(ind == NULL) break;
SetDParam(0, ind->index);
size.width = std::max(GetStringBoundingBox(CM_STR_LAND_TOOLTIPS_INDUSTRY_NAME).width, size.width);
size.width = std::max(GetStringBoundingBox(GetString(CM_STR_LAND_TOOLTIPS_INDUSTRY_NAME, ind->index)).width, size.width);
for (auto &p : ind->produced) {
if (!IsValidCargoID(p.cargo)) continue;
const CargoSpec *cs = CargoSpec::Get(p.cargo);
if(cs == NULL) continue;
size.height += line_height;
SetDParam(0, cs->name);
SetDParam(1, cs->Index());
SetDParam(2, p.history[LAST_MONTH].production);
SetDParam(3, ToPercent8(p.history[LAST_MONTH].PctTransported()));
size.width = std::max(GetStringBoundingBox(CM_STR_LAND_TOOLTIPS_INDUSTRY_CARGO).width + icons_width, size.width);
auto str = GetString(
CM_STR_LAND_TOOLTIPS_INDUSTRY_CARGO,
cs->name,
cs->Index(),
p.history[LAST_MONTH].production,
ToPercent8(p.history[LAST_MONTH].PctTransported())
);
size.width = std::max(GetStringBoundingBox(str).width + icons_width, size.width);
}
break;
}
@@ -109,17 +109,20 @@ struct LandTooltipsWindow : public Window
const Station *st = Station::GetIfValid((StationID)this->objIndex);
if(st == NULL) break;
SetDParam(0, st->index);
size.width = std::max(GetStringBoundingBox(CM_STR_LAND_TOOLTIPS_STATION_NAME).width, size.width);
size.width = std::max(GetStringBoundingBox(GetString(CM_STR_LAND_TOOLTIPS_STATION_NAME, st->index)).width, size.width);
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
int cargoid = cs->Index();
if (HasBit(st->goods[cargoid].status, GoodsEntry::GES_RATING)) {
auto cargoid = cs->Index();
auto &ge = st->goods[cargoid];
if (ge.HasRating() && ge.HasData()) {
size.height += line_height;
SetDParam(0, cs->name);
SetDParam(1, cargoid);
SetDParam(2, st->goods[cargoid].cargo.TotalCount());
SetDParam(3, ToPercent8(st->goods[cargoid].rating));
auto str = GetString(
CM_STR_LAND_TOOLTIPS_STATION_CARGO,
cs->name,
cargoid,
ge.GetData().cargo.TotalCount(),
ToPercent8(ge.rating)
);
size.width = std::max(GetStringBoundingBox(CM_STR_LAND_TOOLTIPS_STATION_CARGO).width + icons_width, size.width);
}
}
@@ -150,56 +153,57 @@ struct LandTooltipsWindow : public Window
switch(this->tiletype) {
case MP_HOUSE: {
const HouseSpec *hs = HouseSpec::Get((HouseID)this->objIndex);
if(hs == NULL) break;
if(hs == nullptr) break;
SetDParam(0, hs->building_name);
DrawString(ir, CM_STR_LAND_TOOLTIPS_HOUSE_NAME, TC_BLACK, SA_CENTER);
DrawString(ir, GetString(CM_STR_LAND_TOOLTIPS_HOUSE_NAME, hs->building_name), TC_BLACK, SA_CENTER);
ir.top += text_height;
SetDParam(0, hs->population);
DrawString(ir, CM_STR_LAND_TOOLTIPS_HOUSE_POPULATION, TC_BLACK, SA_CENTER);
DrawString(ir, GetString(CM_STR_LAND_TOOLTIPS_HOUSE_POPULATION, hs->population), TC_BLACK, SA_CENTER);
break;
}
case MP_INDUSTRY: {
const Industry *ind = Industry::GetIfValid((IndustryID)this->objIndex);
if(ind == NULL) break;
if(ind == nullptr) break;
SetDParam(0, ind->index);
DrawString(ir, CM_STR_LAND_TOOLTIPS_INDUSTRY_NAME, TC_BLACK, SA_CENTER);
DrawString(ir, GetString(CM_STR_LAND_TOOLTIPS_INDUSTRY_NAME, ind->index), TC_BLACK, SA_CENTER);
ir.top += text_height;
for (auto &p : ind->produced) {
if (!IsValidCargoID(p.cargo)) continue;
const CargoSpec *cs = CargoSpec::Get(p.cargo);
if(cs == NULL) continue;
SetDParam(0, cs->name);
SetDParam(1, cs->Index());
SetDParam(2, p.history[LAST_MONTH].production);
SetDParam(3, ToPercent8(p.history[LAST_MONTH].PctTransported()));
if(cs == nullptr) continue;
auto str = GetString(
CM_STR_LAND_TOOLTIPS_INDUSTRY_CARGO,
cs->name,
cs->Index(),
p.history[LAST_MONTH].production,
ToPercent8(p.history[LAST_MONTH].PctTransported())
);
this->DrawSpriteIcons(cs->GetCargoIcon(), ir.left, ir.top + icon_ofs);
DrawString(ir.left + icons_width, ir.right, ir.top + text_ofs, CM_STR_LAND_TOOLTIPS_INDUSTRY_CARGO);
DrawString(ir.left + icons_width, ir.right, ir.top + text_ofs, str);
ir.top += line_height;
}
break;
}
case MP_STATION: {
const Station *st = Station::GetIfValid((StationID)this->objIndex);
if(st == NULL) break;
if(st == nullptr) break;
SetDParam(0, st->index);
DrawString(ir, CM_STR_LAND_TOOLTIPS_STATION_NAME, TC_BLACK, SA_CENTER);
DrawString(ir, GetString(CM_STR_LAND_TOOLTIPS_STATION_NAME, st->index), TC_BLACK, SA_CENTER);
ir.top += text_height;
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
int cargoid = cs->Index();
if (HasBit(st->goods[cargoid].status, GoodsEntry::GES_RATING)) {
SetDParam(0, cs->name);
SetDParam(1, cargoid);
SetDParam(2, st->goods[cargoid].cargo.TotalCount());
SetDParam(3, ToPercent8(st->goods[cargoid].rating));
auto cargoid = cs->Index();
auto &ge = st->goods[cargoid];
if (ge.HasRating() && ge.HasData()) {
auto str = GetString(
CM_STR_LAND_TOOLTIPS_STATION_CARGO,
cs->name,
cargoid,
ge.GetData().cargo.TotalCount(),
ToPercent8(ge.rating)
);
this->DrawSpriteIcons(cs->GetCargoIcon(), ir.left, ir.top + icon_ofs);
DrawString(ir.left + icons_width, ir.right, ir.top + text_ofs, CM_STR_LAND_TOOLTIPS_STATION_CARGO);
DrawString(ir.left + icons_width, ir.right, ir.top + text_ofs, str);
ir.top += line_height;
}
}
@@ -242,7 +246,7 @@ void ShowLandTooltips(TileIndex tile, Window *parent) {
if (_settings_client.gui.cm_land_tooltips_for_industries) {
const Industry *ind = Industry::GetByTile(tile);
// if(ind->produced_cargo[0] == CT_INVALID && ind->produced_cargo[1] == CT_INVALID) return;
param = ((ind->index & 0xFFFF) << 16) | MP_INDUSTRY;
param = ((ind->index.base() & 0xFFFF) << 16) | MP_INDUSTRY;
}
break;
}
@@ -250,7 +254,7 @@ void ShowLandTooltips(TileIndex tile, Window *parent) {
if (_settings_client.gui.cm_land_tooltips_for_stations) {
if (IsRailWaypoint(tile) || HasTileWaterGround(tile)) break;
const Station *st = Station::GetByTile(tile);
param |= ((st->index & 0xFFFF) << 16) | MP_STATION;
param |= ((st->index.base() & 0xFFFF) << 16) | MP_STATION;
break;
}
}
@@ -270,7 +274,7 @@ static const NWidgetPart _nested_station_rating_tooltip_widgets[] = {
static WindowDesc _station_rating_tooltip_desc(
WDP_MANUAL, nullptr, 0, 0,
WC_STATION_RATING_TOOLTIP, WC_NONE,
0,
{},
_nested_station_rating_tooltip_widgets
);
@@ -300,7 +304,7 @@ public:
this->cs = cs;
this->close_cond = close_cond;
this->InitNested();
CLRBITS(this->flags, WF_WHITE_BORDER);
this->flags.Reset(WindowFlag::WhiteBorder);
}
Point OnInitialPosition(int16 sm_width, int16 sm_height, int /* window_number */) override
@@ -322,13 +326,12 @@ public:
this->data.clear();
const GoodsEntry *ge = &this->st->goods[this->cs->Index()];
SetDParam(0, this->cs->name);
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_RATING_DETAILS));
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_RATING_DETAILS, this->cs->name));
if (!ge->HasRating()) { return; }
int total_rating = 0;
if (HasBit(cs->callback_mask, CBM_CARGO_STATION_RATING_CALC)) {
if (cs->callback_mask.Test(CargoCallbackMask::StationRatingCalc)) {
uint last_speed = ge->HasVehicleEverTriedLoading() ? ge->last_speed : 0xFF;
uint32 var18 = std::min<uint32>(ge->time_since_pickup, 0xFF) | (std::min<uint32>(ge->max_waiting_cargo, 0xFFFF) << 8) | (std::min<uint32>(last_speed, 0xFF) << 24);
@@ -345,18 +348,24 @@ public:
total_rating += newgrf_rating;
newgrf_rating = this->RoundRating(newgrf_rating);
SetDParam(0, CM_STR_STATION_RATING_TOOLTIP_NEWGRF_RATING_0 + (newgrf_rating <= 0 ? 0 : 1));
SetDParam(1, newgrf_rating);
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_NEWGRF_RATING));
this->data.push_back(GetString(
CM_STR_STATION_RATING_TOOLTIP_NEWGRF_RATING,
CM_STR_STATION_RATING_TOOLTIP_NEWGRF_RATING_0 + (newgrf_rating <= 0 ? 0 : 1),
newgrf_rating
));
SetDParam(0, std::min<uint>(last_speed, 0xFF));
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_NEWGRF_SPEED));
SetDParam(0, std::min<uint>(ge->max_waiting_cargo, 0xFFFF));
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_NEWGRF_WAITUNITS));
SetDParam(0, (std::min<uint>(ge->time_since_pickup, 0xFF) * 5 + 1) / 2);
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_NEWGRF_WAITTIME));
this->data.push_back(GetString(
CM_STR_STATION_RATING_TOOLTIP_NEWGRF_SPEED,
std::min<uint>(last_speed, 0xFF)
));
this->data.push_back(GetString(
CM_STR_STATION_RATING_TOOLTIP_NEWGRF_WAITUNITS,
std::min<uint>(ge->max_waiting_cargo, 0xFFFF)
));
this->data.push_back(GetString(
CM_STR_STATION_RATING_TOOLTIP_NEWGRF_WAITTIME,
(std::min<uint>(ge->time_since_pickup, 0xFF) * 5 + 1) / 2
));
}
}
@@ -371,10 +380,12 @@ public:
if (waittime <= 3) waittime_stage = 4;
total_rating += STATION_RATING_WAITTIME[waittime_stage];
SetDParam(0, CM_STR_STATION_RATING_TOOLTIP_WAITTIME_0 + waittime_stage);
SetDParam(1, (ge->time_since_pickup * 5 + 1) / 2);
SetDParam(2, this->RoundRating(STATION_RATING_WAITTIME[waittime_stage]));
this->data.push_back(GetString(this->st->last_vehicle_type == VEH_SHIP ? CM_STR_STATION_RATING_TOOLTIP_WAITTIME_SHIP : CM_STR_STATION_RATING_TOOLTIP_WAITTIME));
this->data.push_back(GetString(
this->st->last_vehicle_type == VEH_SHIP ? CM_STR_STATION_RATING_TOOLTIP_WAITTIME_SHIP : CM_STR_STATION_RATING_TOOLTIP_WAITTIME,
CM_STR_STATION_RATING_TOOLTIP_WAITTIME_0 + waittime_stage,
(ge->time_since_pickup * 5 + 1) / 2,
this->RoundRating(STATION_RATING_WAITTIME[waittime_stage])
));
int waitunits_stage = 0;
if (ge->max_waiting_cargo <= 1500) waitunits_stage = 1;
@@ -384,45 +395,52 @@ public:
if (ge->max_waiting_cargo <= 100) waitunits_stage = 5;
total_rating += STATION_RATING_WAITUNITS[waitunits_stage];
SetDParam(0, CM_STR_STATION_RATING_TOOLTIP_WAITUNITS_0 + waitunits_stage);
SetDParam(1, ge->max_waiting_cargo);
SetDParam(2, this->RoundRating(STATION_RATING_WAITUNITS[waitunits_stage]));
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_WAITUNITS));
this->data.push_back(GetString(
CM_STR_STATION_RATING_TOOLTIP_WAITUNITS,
CM_STR_STATION_RATING_TOOLTIP_WAITUNITS_0 + waitunits_stage,
ge->max_waiting_cargo,
this->RoundRating(STATION_RATING_WAITUNITS[waitunits_stage])
));
int b = ge->last_speed - 85;
int r_speed = b >= 0 ? b >> 2 : 0;
int r_speed_round = this->RoundRating(r_speed);
total_rating += r_speed;
StringID speed_str;
if (ge->last_speed == 255) {
SetDParam(0, CM_STR_STATION_RATING_TOOLTIP_SPEED_MAX);
speed_str = CM_STR_STATION_RATING_TOOLTIP_SPEED_MAX;
} else if (r_speed_round == 0) {
SetDParam(0, CM_STR_STATION_RATING_TOOLTIP_SPEED_ZERO);
speed_str = CM_STR_STATION_RATING_TOOLTIP_SPEED_ZERO;
} else {
SetDParam(0, CM_STR_STATION_RATING_TOOLTIP_SPEED_0 + r_speed / 11);
speed_str = CM_STR_STATION_RATING_TOOLTIP_SPEED_0 + r_speed / 11;
}
SetDParam(0, ge->last_speed == 255 ? CM_STR_STATION_RATING_TOOLTIP_SPEED_MAX : CM_STR_STATION_RATING_TOOLTIP_SPEED_0 + r_speed / 11);
SetDParam(1, ge->last_speed);
SetDParam(2, r_speed_round);
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_SPEED));
this->data.push_back(GetString(
CM_STR_STATION_RATING_TOOLTIP_SPEED,
speed_str,
ge->last_speed,
r_speed_round
));
}
int age_stage = (ge->last_age >= 3 ? 0 : 3 - ge->last_age);
total_rating += STATION_RATING_AGE[age_stage];
SetDParam(0, CM_STR_STATION_RATING_TOOLTIP_AGE_0 + age_stage);
SetDParam(1, ge->last_age);
SetDParam(2, this->RoundRating(STATION_RATING_AGE[age_stage]));
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_AGE));
this->data.push_back(GetString(
CM_STR_STATION_RATING_TOOLTIP_AGE,
CM_STR_STATION_RATING_TOOLTIP_AGE_0 + age_stage,
ge->last_age,
this->RoundRating(STATION_RATING_AGE[age_stage])
));
if (Company::IsValidID(st->owner) && HasBit(st->town->statues, st->owner)) {
SetDParam(0, CM_STR_STATION_RATING_TOOLTIP_STATUE_YES);
StringID statue_str;
if (Company::IsValidID(st->owner) && st->town->statues.Test(st->owner)) {
statue_str = CM_STR_STATION_RATING_TOOLTIP_STATUE_YES;
total_rating += 26;
} else {
SetDParam(0, CM_STR_STATION_RATING_TOOLTIP_STATUE_NO);
statue_str = CM_STR_STATION_RATING_TOOLTIP_STATUE_NO;
}
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_STATUE));
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_STATUE, statue_str));
SetDParam(0, ToPercent8(Clamp(total_rating, 0, 255)));
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_TOTAL_RATING));
this->data.push_back(GetString(CM_STR_STATION_RATING_TOOLTIP_TOTAL_RATING, ToPercent8(Clamp(total_rating, 0, 255))));
}
void UpdateWidgetSize(WidgetID /* widget */, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override

View File

@@ -0,0 +1,493 @@
#include "../stdafx.h"
#include "cm_town_gui.hpp"
#include "../gui.h" // ShowExtraViewportWindow
#include "../hotkeys.h" // Hotkey
#include "../goal_base.h" // Goal::Iterate
#include "../strings_type.h" // StringID
#include "../strings_func.h" // GetString
#include "../textbuf_gui.h" // QueryStringFlag
#include "../viewport_func.h" // ScrollMainWindowToTile
#include "../zoom_func.h" // ScaleGUITrad
#include "../widgets/town_widget.h"
#include "../table/strings.h"
#include "cm_commands.hpp"
#include "cm_hotkeys.hpp"
#include <optional>
void ShowTownAuthorityWindow(uint town); // town_gui.cpp
namespace citymania {
// TODO replace with pair or remove
struct CargoX {
int id;
int from;
};
bool TownExecuteAction(const Town *town, TownAction action) {
if(!(action == TownAction::BuildStatue && town->statues.Test(_current_company))) { //don't built statue when there is one
return cmd::DoTownAction(town->xy, town->index, action)
.with_error(STR_ERROR_CAN_T_DO_THIS)
.post();
}
return false;
}
void DrawExtraTownInfo (Rect &r, const Town *town, uint line, bool show_house_states_info) {
//real pop and rating
DrawString(r, GetString(
CM_STR_TOWN_VIEW_REALPOP_RATE,
town->cm.real_population,
town->ratings[_current_company]
));
r.top += line;
//town stats
// int grow_rate = 0;
// if(town->growth_rate == TOWN_GROW_RATE_CUSTOM_NONE) grow_rate = 0;
// else grow_rate = TownTicksToDays((town->growth_rate & ~TOWN_GROW_RATE_CUSTOM) + 1);
// SetDParam(2, town->grow_counter < 16000 ? TownTicksToDays(town->grow_counter + 1) : -1);
DrawString(r, GetString(
CM_STR_TOWN_VIEW_GROWTH,
town->growth_rate,
HasBit(town->flags, TOWN_CUSTOM_GROWTH) ? CM_STR_TOWN_VIEW_GROWTH_RATE_CUSTOM : STR_EMPTY,
town->grow_counter,
town->time_until_rebuild,
HasBit(town->flags, TOWN_IS_GROWING) ? 1 : 0,
town->fund_buildings_months
));
r.top += line;
if (show_house_states_info) {
DrawString(r, GetString(
CM_STR_TOWN_VIEW_HOUSE_STATE,
town->cm.houses_constructing,
town->cm.houses_reconstructed_last_month,
town->cm.houses_demolished_last_month
));
r.top += line;
}
///houses stats
DrawString(r, GetString(
CM_STR_TOWN_VIEW_GROWTH_TILES,
town->cm.hs_total,
town->cm.hs_last_month,
town->cm.cs_total,
town->cm.cs_last_month,
town->cm.hr_total,
town->cm.hr_last_month
));
r.top += line;
}
bool CB_sortCargoesByFrom(CargoX first, CargoX second){
return (first.from < second.from) ? true : false;
}
struct CBTownWindow : Window {
private:
Town *town;
std::list<CargoX> cargoes;
enum CBTownWindowPlanes {
CBTWP_MP_GOALS = 0,
CBTWP_MP_CB,
};
public:
CBTownWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
{
for (uint i = 0; i < NUM_CARGO ; i++) {
CargoX c;
c.id = i;
c.from = CB_GetFrom(i);
this->cargoes.push_back(c);
}
cargoes.sort(CB_sortCargoesByFrom);
this->town = Town::Get(window_number);
this->InitNested(window_number);
if(this->town->cm.fund_regularly.Test(_local_company)) this->LowerWidget(WID_CB_FUND_REGULAR);
if(this->town->cm.do_powerfund.Test(_local_company)) this->LowerWidget(WID_CB_POWERFUND);
if(this->town->cm.advertise_regularly.Test(_local_company)) this->LowerWidget(WID_CB_ADVERT_REGULAR);
}
void OnClick([[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count) override
{
switch (widget) {
case WID_CB_CENTER_VIEW:
if (citymania::_fn_mod) {
ShowExtraViewportWindow(this->town->xy);
} else {
ScrollMainWindowToTile(this->town->xy);
}
break;
case WID_CB_ADVERT:
TownExecuteAction(this->town, TownAction::AdvertiseLarge);
break;
case WID_CB_FUND:
TownExecuteAction(this->town, TownAction::FundBuildings);
break;
case WID_CB_FUND_REGULAR:
this->town->cm.fund_regularly.Flip(_local_company);
this->SetWidgetLoweredState(widget, this->town->cm.fund_regularly.Test(_local_company));
this->SetWidgetDirty(widget);
break;
case WID_CB_POWERFUND:
this->town->cm.do_powerfund.Flip(_local_company);
this->SetWidgetLoweredState(widget, this->town->cm.do_powerfund.Test(_local_company));
this->SetWidgetDirty(widget);
break;
case WID_CB_ADVERT_REGULAR:
if (this->town->cm.advertise_regularly.None()) {
auto str = GetString(STR_JUST_INT, ToPercent8(this->town->cm.ad_rating_goal));
ShowQueryString(str, CM_STR_CB_ADVERT_REGULAR_RATING_TO_KEEP,
4, this, CS_NUMERAL, QueryStringFlag::AcceptUnchanged);
} else this->OnQueryTextFinished(std::nullopt);
break;
case WID_CB_TOWN_VIEW: // Town view window
ShowTownViewWindow(this->window_number);
break;
case WID_CB_SHOW_AUTHORITY: // town authority
ShowTownAuthorityWindow(this->window_number);
break;
}
}
void OnQueryTextFinished(std::optional<std::string> str) override
{
if (!str.has_value()) this->town->cm.advertise_regularly.Set(_local_company);
else this->town->cm.advertise_regularly.Reset(_local_company);
this->town->cm.ad_ref_goods_entry = std::nullopt;
this->SetWidgetLoweredState(WID_CB_ADVERT_REGULAR, this->town->cm.advertise_regularly.Test(_local_company));
this->SetWidgetDirty(WID_CB_ADVERT_REGULAR);
if (!str.has_value()) return;
uint val = Clamp(str->empty()? 0 : strtol(str->c_str(), NULL, 10), 1, 100);
this->town->cm.ad_rating_goal = ((val << 8) + 255) / 101;
}
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
{
if (widget != WID_CB_CAPTION) return this->Window::GetWidgetString(widget, stringid);
return GetString(CM_STR_TOWN_VIEW_CB_CAPTION, this->town->index);
}
const Company *GetCompany() const {
for (Company *c : Company::Iterate()) {
if (c->location_of_HQ != INVALID_TILE
&& DistanceMax(c->location_of_HQ, this->town->xy) < 11)
return c;
}
return nullptr;
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override {
static const uint EXP_TOPPADDING = 5;
static const uint EXP_LINESPACE = 2; // Amount of vertical space for a horizontal (sub-)total line.
switch(widget){
case WID_CB_DETAILS:
size.height = (GetCharacterHeight(FS_NORMAL) + EXP_LINESPACE) * 5;
break;
case WID_CB_GOALS: {
uint desired_height = 0;
auto company = GetCompany();
if (company) {
for(const Goal *g : Goal::Iterate()) {
if (g->company == company->index) {
desired_height++;
}
}
}
if (desired_height > 0)
size.height = desired_height * (GetCharacterHeight(FS_NORMAL) + EXP_LINESPACE) + EXP_TOPPADDING - EXP_LINESPACE;
break;
}
case WID_CB_CARGO_NAME:
case WID_CB_CARGO_AMOUNT:
case WID_CB_CARGO_REQ:
case WID_CB_CARGO_STORE:
case WID_CB_CARGO_STORE_PCT:
case WID_CB_CARGO_FROM:
case WID_CB_CARGO_PREVIOUS: {
uint desired_height = 0;
for(CargoType cargo = 0; cargo < NUM_CARGO; cargo++){
if(CB_GetReq(cargo) > 0) desired_height++;
}
if (desired_height > 0)
size.height = desired_height * (GetCharacterHeight(FS_NORMAL) + EXP_LINESPACE) + EXP_TOPPADDING - EXP_LINESPACE;
break;
}
}
}
void DrawWidget(const Rect &r, int widget) const override
{
static const uint EXP_LINESPACE = GetCharacterHeight(FS_NORMAL) + 2;
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
switch(widget){
case WID_CB_DETAILS:{
// growing
if(this->town->cm.cb.growth_state == TownGrowthState::GROWING)
DrawString(tr, CM_STR_TOWN_CB_GROWING);
else DrawString(tr, CM_STR_TOWN_CB_NOT_GROWING);
tr.top += GetCharacterHeight(FS_NORMAL);
// population
DrawString(tr, GetString(
STR_TOWN_VIEW_POPULATION_HOUSES,
this->town->cache.population,
this->town->cache.num_houses
));
tr.top += GetCharacterHeight(FS_NORMAL);
DrawExtraTownInfo(tr, this->town, EXP_LINESPACE, false);
// regular funding
if (this->town->cm.fund_regularly.Any()) {
DrawString(tr, CM_STR_CB_FUNDED_REGULARLY);
tr.top += EXP_LINESPACE;
}
break;
}
case WID_CB_GOALS: {
auto company = GetCompany();
if (!company) break;
for(const Goal *g : Goal::Iterate()) {
if (g->company != company->index)
continue;
DrawString(tr, GetString(STR_GOALS_TEXT, g->text.GetDecodedString()));
tr.top += EXP_LINESPACE;
}
break;
}
/* Citybuilder things*/
case WID_CB_CARGO_NAME:
case WID_CB_CARGO_AMOUNT:
case WID_CB_CARGO_REQ:
case WID_CB_CARGO_STORE:
case WID_CB_CARGO_STORE_PCT:
case WID_CB_CARGO_FROM:
case WID_CB_CARGO_PREVIOUS: {
if (this->town->larger_town) break;
uint delivered;
uint requirements;
uint from;
StringID string_to_draw;
//for cycle
std::list<CargoX> cargoes2 = this->cargoes;
std::list<CargoX>::iterator it2;
for (it2 = cargoes2.begin(); it2 != cargoes2.end(); ++it2) {
CargoX cargox;
cargox = *it2;
if (it2 == cargoes2.begin()) { // header
// FIXME rtl support
DrawString(tr.Shrink(ScaleGUITrad(14), 0, 0, 0),
(CM_STR_TOWN_GROWTH_HEADER_CARGO + widget - WID_CB_CARGO_NAME), TC_FROMSTRING,
(widget == WID_CB_CARGO_NAME) ? SA_LEFT : SA_RIGHT);
tr.top += EXP_LINESPACE;
}
const CargoSpec *cargos = CargoSpec::Get(cargox.id);
//cargo needed?
if (!cargos->IsValid() || CB_GetReq(cargos->Index()) == 0) continue;
from = CB_GetFrom(cargos->Index());
switch(widget) {
case WID_CB_CARGO_NAME: {
// FIXME scaling
GfxFillRect(tr.left, tr.top + 1, tr.left + 8, tr.top + 6, 0);
GfxFillRect(tr.left + 1, tr.top + 2, tr.left + 7, tr.top + 5, cargos->legend_colour);
DrawString(tr.Shrink(ScaleGUITrad(14), 0, 0, 0), GetString(CM_STR_TOWN_CB_CARGO_NAME, cargos->name));
break;
}
case WID_CB_CARGO_AMOUNT: {
delivered = this->town->cm.cb.delivered[cargos->Index()];
requirements = CB_GetTownReq(this->town->cache.population, CB_GetReq(cargos->Index()), from, true);
//when required
if (this->town->cache.population >= from) {
if((delivered + (uint)this->town->cm.cb.stored[cargos->Index()]) >= requirements) string_to_draw = CM_STR_TOWN_CB_CARGO_AMOUNT_GOOD;
else string_to_draw = CM_STR_TOWN_CB_CARGO_AMOUNT_BAD;
}
//when not required -> all faded
else string_to_draw = CM_STR_TOWN_CB_CARGO_AMOUNT_NOT;
DrawString(tr, GetString(string_to_draw, delivered), TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CB_CARGO_REQ: {
requirements = CB_GetTownReq(this->town->cache.population, CB_GetReq(cargos->Index()), from, true);
//when required
string_to_draw = (this->town->cache.population >= from) ? CM_STR_TOWN_CB_CARGO_REQ_YES : CM_STR_TOWN_CB_CARGO_REQ_NOT;
DrawString(tr, GetString(string_to_draw, requirements), TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CB_CARGO_PREVIOUS: {
requirements = CB_GetTownReq(this->town->cache.population, CB_GetReq(cargos->Index()), from, true);
if (this->town->cache.population >= from){
// if (this->town->delivered_enough[cargos->Index()]) {
string_to_draw = (this->town->cm.cb.delivered_last_month[cargos->Index()] >= requirements) ? CM_STR_TOWN_CB_CARGO_PREVIOUS_YES : CM_STR_TOWN_CB_CARGO_PREVIOUS_EDGE;
// }
// else string_to_draw = STR_TOWN_CB_CARGO_PREVIOUS_BAD;
}
else string_to_draw = CM_STR_TOWN_CB_CARGO_PREVIOUS_NOT;
DrawString(tr, GetString(string_to_draw, this->town->cm.cb.delivered_last_month[cargos->Index()]), TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CB_CARGO_STORE: {
if (CB_GetDecay(cargos->Index()) == 100) string_to_draw = CM_STR_TOWN_CB_CARGO_STORE_DECAY; //when 100% decay
else {
if (this->town->cache.population >= from) string_to_draw = CM_STR_TOWN_CB_CARGO_STORE_YES; //when required
else string_to_draw = CM_STR_TOWN_CB_CARGO_STORE_NOT;
}
DrawString(tr, GetString(string_to_draw, this->town->cm.cb.stored[cargos->Index()]), TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CB_CARGO_STORE_PCT: {
uint max_storage = CB_GetMaxTownStorage(this->town, cargos->Index());
std::string str;
if (CB_GetDecay(cargos->Index()) == 100 || !max_storage) str = GetString(CM_STR_TOWN_CB_CARGO_STORE_DECAY); //when 100% decay
else {
str = GetString(
this->town->cache.population >= from ? CM_STR_TOWN_CB_CARGO_STORE_PCT_YES : CM_STR_TOWN_CB_CARGO_STORE_PCT_NOT,
100 * this->town->cm.cb.stored[cargos->Index()] / max_storage
);
}
DrawString(tr, str, TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CB_CARGO_FROM: {
string_to_draw = (this->town->cache.population >= from) ? CM_STR_TOWN_CB_CARGO_FROM_YES : CM_STR_TOWN_CB_CARGO_FROM_NOT; //when required
DrawString(tr, GetString(string_to_draw, from), TC_FROMSTRING, SA_RIGHT);
break;
}
//last case
}
//switch
tr.top += EXP_LINESPACE;
//cargo needed?
}
//for cycle
}
break;
}
/* Citybuilder things enabled*/
}
void OnPaint() override {
if (!this->IsShaded()) {
int plane = CB_Enabled() ? CBTWP_MP_CB : CBTWP_MP_GOALS;
NWidgetStacked *wi = this->GetWidget<NWidgetStacked>(WID_CB_SELECT_REQUIREMENTS);
if (plane != wi->shown_plane) {
wi->SetDisplayedPlane(plane);
this->InvalidateData();
return;
}
}
this->DrawWidgets();
}
EventState OnHotkey(int hotkey) override
{
// TODO fix to proper hotkey
TownExecuteAction(this->town, TownAction::BuildStatue);
return ES_HANDLED;
}
static inline HotkeyList hotkeys{"cm_town_cb_view", {
Hotkey((uint16)0, "location", WID_TV_CENTER_VIEW),
Hotkey((uint16)0, "local_authority", WID_TV_SHOW_AUTHORITY),
Hotkey((uint16)0, "cb_window", WID_TV_CB),
Hotkey(WKC_CTRL | 'S', "build_statue", HK_STATUE + 0x80),
}};
};
static const NWidgetPart _nested_cb_town_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN, WID_CB_CAPTION), SetStringTip(CM_STR_TOWN_VIEW_CB_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_CB_CENTER_VIEW), SetMinimalSize(12, 14), SetStringTip(SPR_GOTO_LOCATION, STR_TOWN_VIEW_CENTER_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_BROWN),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetMinimalSize(0, 5), SetResize(1, 0), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_DETAILS), SetMinimalSize(66, 0), SetResize(1, 0), SetFill(1, 0),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_ADVERT),SetMinimalSize(33, 12),SetFill(1, 0), SetStringTip(CM_STR_CB_LARGE_ADVERTISING_CAMPAIGN),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_FUND),SetMinimalSize(33, 12),SetFill(1, 0), SetStringTip(CM_STR_CB_NEW_BUILDINGS),
NWidget(NWID_SPACER), SetMinimalSize(4, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_CB_ADVERT_REGULAR),SetMinimalSize(33, 12),SetFill(1, 0), SetStringTip(CM_STR_CB_ADVERT_REGULAR, CM_STR_CB_ADVERT_REGULAR_TT),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_CB_FUND_REGULAR),SetMinimalSize(33, 12),SetFill(1, 0), SetStringTip(CM_STR_CB_FUND_REGULAR, CM_STR_CB_FUND_REGULAR_TT),
NWidget(NWID_SPACER), SetMinimalSize(4, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
NWidget(NWID_SPACER), SetMinimalSize(33, 0), SetFill(1, 0),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_CB_POWERFUND),SetMinimalSize(33, 12),SetFill(1, 0), SetStringTip(CM_STR_CB_POWERFUND, CM_STR_CB_POWERFUND_TT),
NWidget(NWID_SPACER), SetMinimalSize(4, 0),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 5), SetResize(1, 0), SetFill(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_CB_SELECT_REQUIREMENTS),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_GOALS),SetMinimalSize(50 + 35 + 35 + 40 + 35 + 30, 0), SetResize(1, 0), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_NAME),SetMinimalSize(50, 0), SetResize(0, 0), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_AMOUNT),SetMinimalSize(35, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_REQ),SetMinimalSize(35, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_PREVIOUS),SetMinimalSize(40, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_STORE),SetMinimalSize(35, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_STORE_PCT),SetMinimalSize(30, 0), SetResize(1, 0), SetFill(0, 0),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 0), SetResize(1, 0), SetFill(1, 1),
EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_TOWN_VIEW), SetMinimalSize(40, 12), SetFill(1, 1), SetResize(1, 0), SetStringTip(CM_STR_CB_GUI_TOWN_VIEW_BUTTON, CM_STR_CB_GUI_TOWN_VIEW_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_SHOW_AUTHORITY), SetMinimalSize(40, 12), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON, STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP),
EndContainer(),
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
EndContainer(),
};
static WindowDesc _cb_town_desc(
WDP_AUTO, "cm_town_cb", 160, 30,
CM_WC_CB_TOWN, WC_NONE,
{},
_nested_cb_town_widgets,
&CBTownWindow::hotkeys
);
void ShowCBTownWindow(TownID town) {
AllocateWindowDescFront<CBTownWindow>(_cb_town_desc, town);
}
} // namespace citymania

View File

@@ -0,0 +1,17 @@
/** @file cm_town_gui.hpp CityMania town GUI. */
#ifndef CM_TOWN_GUI_HPP
#define CM_TOWN_GUI_HPP
#include "../town_type.h" // Town
#include "../town.h" // TownAction
namespace citymania {
bool TownExecuteAction(const Town *town, TownAction action);
void DrawExtraTownInfo(Rect &r, const Town *town, uint line, bool show_house_states_info);
void ShowCBTownWindow(TownID town);
} // namespace citymania
#endif /* CM_TOWN_GUI_HPP */

View File

@@ -100,7 +100,7 @@ static std::unique_ptr<NWidgetBase> MakeCompanyButtons2() {
company_panel->SetMinimalSizeAbsolute(company_sprite_size.width, company_sprite_size.height);
company_panel->SetResize(1, 0);
company_panel->SetFill(1, 1);
company_panel->SetDataTip(0, CM_STR_WATCH_CLICK_TO_WATCH_COMPANY);
company_panel->SetToolTip(CM_STR_WATCH_CLICK_TO_WATCH_COMPANY);
widget_container_horiz->Add(std::move(company_panel));
}
@@ -124,8 +124,8 @@ static const NWidgetPart _nested_watch_company_widgets[] = {
/* Title Bar with close box, title, shade and stick boxes */
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, EWW_CAPTION ), SetDataTip(CM_STR_WATCH_WINDOW_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_LOCATION), SetMinimalSize(12, 14), SetDataTip(SPR_GOTO_LOCATION, CM_STR_WATCH_LOCATION_TOOLTIP),
NWidget(WWT_CAPTION, COLOUR_GREY, EWW_CAPTION),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_LOCATION), SetMinimalSize(12, 14), SetStringTip(SPR_GOTO_LOCATION, CM_STR_WATCH_LOCATION_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -162,7 +162,7 @@ static const NWidgetPart _nested_watch_company_widgets[] = {
static WindowDesc _watch_company_desc(
WDP_AUTO, "cm_watch_gui", 300, 257,
WC_WATCH_COMPANY, WC_NONE,
WDF_NO_FOCUS,
WindowDefaultFlag::NoFocus,
_nested_watch_company_widgets
);
@@ -171,8 +171,8 @@ static const NWidgetPart _nested_watch_company_widgetsA[] = {
/* Title Bar with close box, title, shade and stick boxes */
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, EWW_CAPTION ), SetDataTip(CM_STR_WATCH_WINDOW_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_LOCATION), SetMinimalSize(12, 14), SetDataTip(SPR_GOTO_LOCATION, CM_STR_WATCH_LOCATION_TOOLTIP),
NWidget(WWT_CAPTION, COLOUR_GREY, EWW_CAPTION ), SetStringTip(CM_STR_WATCH_WINDOW_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_LOCATION), SetMinimalSize(12, 14), SetStringTip(SPR_GOTO_LOCATION, CM_STR_WATCH_LOCATION_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -181,29 +181,29 @@ static const NWidgetPart _nested_watch_company_widgetsA[] = {
NWidget( NWID_VERTICAL ),
/* Buton Zoom Out, In, Scrollto */
NWidget(NWID_SELECTION, INVALID_COLOUR, EWW_ENABLE_SELECT),
NWidget(NWID_VERTICAL ),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_KICK), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(CM_STR_XI_KICK, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_BAN), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(CM_STR_XI_BAN, 0 ),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_LOCK), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(CM_STR_XI_LOCK, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_UNLOCK), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(CM_STR_XI_UNLOCK, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_JOIN), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(CM_STR_XI_JOIN, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_KICKC), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(CM_STR_XI_KICKC, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_RESET), SetMinimalSize(40, 20), SetFill(1, 0), SetDataTip(CM_STR_XI_RESET, 0),
NWidget(NWID_VERTICAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_KICK), SetMinimalSize(40, 20), SetFill(1, 0), SetStringTip(CM_STR_XI_KICK),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_BAN), SetMinimalSize(40, 20), SetFill(1, 0), SetStringTip(CM_STR_XI_BAN),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_LOCK), SetMinimalSize(40, 20), SetFill(1, 0), SetStringTip(CM_STR_XI_LOCK),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_UNLOCK), SetMinimalSize(40, 20), SetFill(1, 0), SetStringTip(CM_STR_XI_UNLOCK),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_JOIN), SetMinimalSize(40, 20), SetFill(1, 0), SetStringTip(CM_STR_XI_JOIN),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_KICKC), SetMinimalSize(40, 20), SetFill(1, 0), SetStringTip(CM_STR_XI_KICKC),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_RESET), SetMinimalSize(40, 20), SetFill(1, 0), SetStringTip(CM_STR_XI_RESET),
EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_ZOOMOUT), SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_ZOOMIN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_CENTER), SetDataTip(SPR_CENTRE_VIEW_VEHICLE, STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT),
NWidget(WWT_PANEL, COLOUR_GREY, EWW_NEW_WINDOW), SetDataTip(0, 0), EndContainer(),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_ZOOMOUT), SetSpriteTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_ZOOMIN), SetSpriteTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_CENTER), SetSpriteTip(SPR_CENTRE_VIEW_VEHICLE, STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TOOLTIP),
NWidget(WWT_PANEL, COLOUR_GREY, EWW_NEW_WINDOW), EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_CLIENTS), SetMinimalSize(23, 10), SetDataTip(SPR_IMG_COMPANY_GENERAL, CM_STR_XI_PLAYERS_TOOLTIP),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_COMPANYW), SetMinimalSize(23, 10), SetDataTip(SPR_IMG_COMPANY_LIST, CM_STR_XI_COMPANYW_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_COMPANYHQ), SetMinimalSize(23, 10), SetDataTip(CM_STR_XI_COMPANYHQ, CM_STR_XI_COMPANYHQ_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_PRIVATEP_MESSAGE), SetMinimalSize(23, 10), SetDataTip(CM_STR_XI_PRIVATE_PLAYER_MESSAGE, CM_STR_XI_PRIVATE_PLAYER_MESSAGE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_PRIVATEC_MESSAGE), SetMinimalSize(23, 10), SetDataTip(CM_STR_XI_PRIVATE_COMPANY_MESSAGE, CM_STR_XI_PRIVATE_COMPANY_MESSAGE_TOOLTIP),
NWidget(WWT_PANEL, COLOUR_GREY, EWW_NEW_WINDOW), SetDataTip(0, 0), EndContainer(),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_CLIENTS), SetMinimalSize(23, 10), SetStringTip(SPR_IMG_COMPANY_GENERAL, CM_STR_XI_PLAYERS_TOOLTIP),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, EWW_COMPANYW), SetMinimalSize(23, 10), SetStringTip(SPR_IMG_COMPANY_LIST, CM_STR_XI_COMPANYW_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_COMPANYHQ), SetMinimalSize(23, 10), SetStringTip(CM_STR_XI_COMPANYHQ, CM_STR_XI_COMPANYHQ_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_PRIVATEP_MESSAGE), SetMinimalSize(23, 10), SetStringTip(CM_STR_XI_PRIVATE_PLAYER_MESSAGE, CM_STR_XI_PRIVATE_PLAYER_MESSAGE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, EWW_PRIVATEC_MESSAGE), SetMinimalSize(23, 10), SetStringTip(CM_STR_XI_PRIVATE_COMPANY_MESSAGE, CM_STR_XI_PRIVATE_COMPANY_MESSAGE_TOOLTIP),
NWidget(WWT_PANEL, COLOUR_GREY, EWW_NEW_WINDOW), EndContainer(),
EndContainer(),
/* Background panel for resize purpose */
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(0, 1), EndContainer(),
@@ -226,7 +226,7 @@ static const NWidgetPart _nested_watch_company_widgetsA[] = {
static WindowDesc _watch_company_descA(
WDP_AUTO, "watch_gui_client", 448, 256,
WC_WATCH_COMPANYA, WC_NONE,
WDF_CONSTRUCTION,
WindowDefaultFlag::Construction,
_nested_watch_company_widgetsA
);
@@ -234,7 +234,7 @@ static void ResetCallback(Window *w, bool confirmed)
{
if (confirmed) {
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID((ClientID)w->window_number);
if (ci && ci->client_playas != INVALID_COMPANY) {
if (ci && Company::IsValidID(ci->client_playas)) {
NetworkClientSendChatToServer(fmt::format("!reset {}", ci->client_playas + 1));
}
}
@@ -245,14 +245,14 @@ static void ResetCallback(Window *w, bool confirmed)
* @param window_number The window number for the class
* @param company_to_watch Company ID for watching a particular company
*/
WatchCompany::WatchCompany(WindowDesc &desc, int window_number, CompanyID company_to_watch = INVALID_COMPANY, int Wtype = EWT_COMPANY) : Window(desc)
WatchCompany::WatchCompany(WindowDesc &desc, int window_number, CompanyID company_to_watch = CompanyID::Invalid(), int Wtype=EWT_COMPANY) : Window(desc)
{
this->Wtype = Wtype;
if(this->Wtype == EWT_CLIENT){
this->watched_client = window_number;
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID((ClientID)this->watched_client);
this->watched_company = (ci != NULL) ? ci->client_playas : INVALID_COMPANY;
this->watched_company = (ci != NULL) ? ci->client_playas : CompanyID::Invalid();
this->InitNested(window_number);
this->owner = (Owner)this->watched_company;
}
@@ -264,16 +264,16 @@ WatchCompany::WatchCompany(WindowDesc &desc, int window_number, CompanyID compan
this->owner = this->watched_company;
/* Reset activity and client count for all companies */
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
this->company_activity[i] = 0;
this->company_count_client[i] = 0;
for (CompanyID c = CompanyID::Begin(); c < MAX_COMPANIES; ++c) {
this->company_activity[c] = 0;
this->company_count_client[c] = 0;
}
this->company_name = GetString(STR_JUST_NOTHING);
}
/* Init the viewport area */
NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(EWW_WATCH);
nvp->InitializeViewport(this, 0, ZOOM_LVL_NORMAL);
nvp->InitializeViewport(this, (TileIndex)0, ScaleZoomGUI(ZOOM_LVL_NORMAL));
Point pt;
/* the main window with the main view */
@@ -288,50 +288,26 @@ WatchCompany::WatchCompany(WindowDesc &desc, int window_number, CompanyID compan
this->viewport->dest_scrollpos_x = this->viewport->scrollpos_x;
this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y;
if ( this->watched_company != INVALID_COMPANY ) {
Company *c = Company::Get( this->watched_company );
this->ScrollToTile( c->last_build_coordinate );
if (auto c = Company::GetIfValid(this->watched_company); c != nullptr) {
this->ScrollToTile(c->last_build_coordinate);
}
this->InvalidateData( );
}
void WatchCompany::SetStringParameters(int widget) const
{
if(widget != EWW_CAPTION) return;
if(this->Wtype == EWT_COMPANY){
SetDParamStr(0, this->company_name);
return;
std::string WatchCompany::GetWidgetString(WidgetID widget, StringID stringid) const {
if(widget != EWW_CAPTION) return this->Window::GetWidgetString(widget, stringid);
if(this->Wtype == EWT_COMPANY) {
return GetString(CM_STR_WATCH_WINDOW_TITLE, this->company_name);
}
//EWT_CLIENT
if (!Company::IsValidHumanID(this->watched_company)){
// GetString((char *)this->company_name, STR_JUST_NOTHING, lastof(this->company_name));
}
else {
const Company *c = Company::Get(this->watched_company);
SetDParam(0, c->index);
// GetString((char *)this->company_name, STR_COMPANY_NAME, lastof(this->company_name));
}
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID((ClientID)this->watched_client);
if(ci){
// strecpy((char *)this->client_name, ci->client_name, lastof(this->client_name));
}
else{
// GetString((char *)this->client_name, STR_JUST_NOTHING, lastof(this->client_name));
}
SetDParamStr(0, this->client_name);
SetDParamStr(1, this->company_name);
if (Company::IsValidHumanID(this->watched_company)){
SetDParam(2, this->watched_company + 1);
}
else {
SetDParam(2, COMPANY_SPECTATOR);
}
return GetString(CM_STR_WATCH_WINDOW_TITLE_CLIENT, this->client_name, this->company_name, this->watched_company);
}
void WatchCompany::OnPaint()
{
if(this->Wtype == EWT_CLIENT){
bool wstate = this->watched_company == INVALID_COMPANY ? true : false;
bool wstate = Company::IsValidID(this->watched_company);
for(int i = EWW_LOCK; i <= EWW_COMPANYW; i++){
this->SetWidgetDisabledState(i, wstate);
}
@@ -410,16 +386,15 @@ void WatchCompany::OnClick(Point /* pt */, int widget, int /* click_count */)
if (IsInsideMM(widget, EWW_COMPANY_BEGIN, EWW_COMPANY_END)) {
/* Is it no on disable? */
if (!this->IsWidgetDisabled(widget)) {
if (this->watched_company != INVALID_COMPANY)
if (Company::IsValidID(this->watched_company))
this->RaiseWidget(EWW_COMPANY_BEGIN + this->watched_company);
auto c = Company::GetIfValid((CompanyID)(widget - EWW_COMPANY_BEGIN));
if (c == nullptr || this->watched_company == c->index) {
this->watched_company = INVALID_COMPANY;
this->watched_company = CompanyID::Invalid();
} else {
this->watched_company = c->index;
this->LowerWidget(widget);
SetDParam(0, c->index);
this->company_name = GetString(STR_COMPANY_NAME);
this->company_name = GetString(STR_COMPANY_NAME, c->index);
this->ScrollToTile(c->last_build_coordinate);
}
this->owner = this->watched_company;
@@ -434,21 +409,20 @@ void WatchCompany::OnClick(Point /* pt */, int widget, int /* click_count */)
} else if (IsInsideMM(widget, EWW_PB_COMPANY_FIRST, EWW_PB_COMPANY_LAST + 1)) {
/* Click on Company Button */
if (!this->IsWidgetDisabled(widget)) {
if (this->watched_company != INVALID_COMPANY) {
if (Company::IsValidID(this->watched_company)) {
/* Raise the watched company button */
this->RaiseWidget(EWW_PB_COMPANY_FIRST + this->watched_company);
}
if (this->watched_company == (CompanyID)(widget - EWW_PB_COMPANY_FIRST)) {
/* Stop watching watched_company */
this->watched_company = INVALID_COMPANY;
this->watched_company = CompanyID::Invalid();
this->company_name = GetString(STR_JUST_NOTHING);
} else {
/* Lower the new watched company button */
this->watched_company = (CompanyID)(widget - EWW_PB_COMPANY_FIRST);
this->LowerWidget( EWW_PB_COMPANY_FIRST + this->watched_company);
Company *c = Company::Get( this->watched_company );
SetDParam( 0, c->index );
this->company_name = GetString(STR_COMPANY_NAME);
this->company_name = GetString(STR_COMPANY_NAME, c->index);
this->ScrollToTile( c->last_build_coordinate );
}
@@ -498,10 +472,10 @@ void WatchCompany::OnClick(Point /* pt */, int widget, int /* click_count */)
break;
case EWW_BAN:
this->query_widget = EWQ_BAN;
ShowQueryString(CM_STR_XI_BAN_DAYSDEFAULT, CM_STR_XI_BAN_QUERY, 128, this, CS_ALPHANUMERAL, QSF_NONE);
ShowQueryString(GetString(CM_STR_XI_BAN_DAYSDEFAULT), CM_STR_XI_BAN_QUERY, 128, this, CS_ALPHANUMERAL, {});
break;
case EWW_RESET:
ShowQuery(CM_STR_XI_RESET_CAPTION, CM_STR_XI_REALY_RESET, this, ResetCallback);
ShowQuery(GetEncodedString(CM_STR_XI_RESET_CAPTION), GetEncodedString(CM_STR_XI_REALY_RESET), this, ResetCallback);
break;
case EWW_PRIVATEP_MESSAGE:{
const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID((ClientID)this->watched_client);
@@ -509,17 +483,17 @@ void WatchCompany::OnClick(Point /* pt */, int widget, int /* click_count */)
break;
}
case EWW_PRIVATEC_MESSAGE:
ShowNetworkChatQueryWindow(DESTTYPE_TEAM, this->watched_company);
ShowNetworkChatQueryWindow(DESTTYPE_TEAM, this->watched_company.base());
break;
case EWW_CLIENTS:
NetworkClientSendChatToServer("!clients");
break;
case EWW_COMPANYW:
if(this->watched_company != INVALID_COMPANY) ShowCompany(this->watched_company);
if (Company::IsValidID(this->watched_company)) ShowCompany(this->watched_company);
break;
case EWW_COMPANYHQ:
if(this->watched_company != INVALID_COMPANY){
TileIndex tile = Company::Get((CompanyID)this->watched_company)->location_of_HQ;
if (auto c = Company::GetIfValid(this->watched_company); c != nullptr) {
TileIndex tile = c->location_of_HQ;
ScrollMainWindowToTile(tile);
}
break;
@@ -548,14 +522,14 @@ void WatchCompany::OnInvalidateData(int data, bool /* gui_scope */)
// this->SetWidgetDisabledState(EWW_PB_ACTION1_FIRST + i , !Company::IsValidID(i) );
// }
// /* Check if the currently selected company is still active. */
// if (this->watched_company != INVALID_COMPANY) {
// if (this->watched_company != CompanyID::Invalid()) {
// /* Make sure the widget is lowered */
// this->LowerWidget(EWW_PB_COMPANY_FIRST + this->watched_company);
// /* Check if the watched Company is still a valid one */
// if (!Company::IsValidID(this->watched_company)) {
// /* Invalid Company Raise the associated widget. */
// this->RaiseWidget(this->watched_company + EWW_PB_COMPANY_FIRST );
// this->watched_company = INVALID_COMPANY;
// this->watched_company = CompanyID::Invalid();
// GetString( this->company_name, STR_JUST_NOTHING, lastof(this->company_name) );
// } else {
// Company *c = Company::Get( this->watched_company );
@@ -580,29 +554,21 @@ void WatchCompany::OnInvalidateData(int data, bool /* gui_scope */)
// }
/* Disable the companies who are not active */
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
this->SetWidgetDisabledState(EWW_COMPANY_BEGIN + i, !Company::IsValidID(i));
for (CompanyID i = CompanyID::Begin(); i < MAX_COMPANIES; ++i) {
this->SetWidgetDisabledState(EWW_COMPANY_BEGIN + i.base(), !Company::IsValidID(i));
}
/* Check if the currently selected company is still active. */
if (this->watched_company != INVALID_COMPANY && !Company::IsValidID(this->watched_company)) {
if (this->watched_company != CompanyID::Invalid() && !Company::IsValidID(this->watched_company)) {
/* Raise the widget for the previous selection. */
this->RaiseWidget(EWW_COMPANY_BEGIN + this->watched_company);
this->watched_company = INVALID_COMPANY;
this->RaiseWidget(EWW_COMPANY_BEGIN + this->watched_company.base());
this->watched_company = CompanyID::Invalid();
}
// if (this->company == INVALID_COMPANY) {
// for (const Company *c : Company::Iterate()) {
// this->company = c->index;
// break;
// }
// }
/* Make sure the widget is lowered */
if (this->watched_company != INVALID_COMPANY)
this->LowerWidget(EWW_COMPANY_BEGIN + this->watched_company);
}
else if(this->Wtype == EWT_CLIENT){
if (Company::IsValidID(this->watched_company))
this->LowerWidget(EWW_COMPANY_BEGIN + this->watched_company.base());
} else if(this->Wtype == EWT_CLIENT) {
if (data == 2) {
this->Close();
return;
@@ -611,11 +577,10 @@ void WatchCompany::OnInvalidateData(int data, bool /* gui_scope */)
if (!ci) {
this->Close();
return;
}
else {
} else {
this->watched_company = ci->client_playas;
this->owner = (Owner)this->watched_company;
bool wstate = this->watched_company == INVALID_COMPANY ? true : false;
bool wstate = Company::IsValidID(this->watched_company);
for(int i = EWW_LOCK; i <= EWW_COMPANYW; i++){
this->SetWidgetDisabledState(i, wstate);
}
@@ -660,7 +625,7 @@ void WatchCompany::OnDoCommand(CompanyID company, TileIndex tile )
void WatchCompany::OnRealtimeTick([[maybe_unused]] uint delta_ms)
{
bool set_dirty = false;
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
for (CompanyID i = CompanyID::Begin(); i < MAX_COMPANIES; ++i) {
if (this->company_activity[i] > 0) {
this->company_activity[i]--;
if (this->company_activity[i] == 0) {
@@ -674,16 +639,16 @@ void WatchCompany::OnRealtimeTick([[maybe_unused]] uint delta_ms)
}
}
void ShowWatchWindow(CompanyID company_to_watch = INVALID_COMPANY, int type = EWT_COMPANY)
void ShowWatchWindow(CompanyID company_to_watch=CompanyID::Invalid(), int type=EWT_COMPANY)
{
if(type == EWT_COMPANY) {
if (type == EWT_COMPANY) {
int i = 0;
/* find next free window number for watch viewport */
while (FindWindowById(WC_WATCH_COMPANY, i) != NULL) i++;
new WatchCompany(_watch_company_desc, i, company_to_watch, type);
} else if(type == EWT_CLIENT) {
} else if (type == EWT_CLIENT) {
if (BringWindowToFrontById(WC_WATCH_COMPANYA, company_to_watch)) return;
new WatchCompany(_watch_company_descA, company_to_watch, company_to_watch, type);
new WatchCompany(_watch_company_descA, company_to_watch.base(), company_to_watch, type);
}
}

View File

@@ -61,8 +61,8 @@ class WatchCompany : public Window
{
protected:
CompanyID watched_company; // Company ID beeing watched.
int company_activity[MAX_COMPANIES]; // int array for activity blot.
int company_count_client[MAX_COMPANIES]; // company client count.
ReferenceThroughBaseContainer<std::array<uint32_t, MAX_COMPANIES>> company_activity; // int array for activity blot.
ReferenceThroughBaseContainer<std::array<uint32_t, MAX_COMPANIES>> company_count_client; // company client count.
std::string company_name; // company name for title display
std::string client_name;
@@ -82,7 +82,7 @@ public:
void OnScroll(Point delta) override;
void OnMouseWheel(int wheel) override;
void OnInvalidateData(int data, bool gui_scope) override;
void SetStringParameters(int widget) const override;
std::string GetWidgetString(WidgetID widget, StringID stringid) const override;
void OnRealtimeTick([[maybe_unused]] uint delta_ms) override;
void OnPaint() override;
void OnQueryTextFinished(std::optional<std::string> str) override;

View File

@@ -83,22 +83,20 @@ Town *CMClosestTownFromTile(TileIndex tile, uint threshold)
if (!HasTownOwnedRoad(tile)) {
TownID tid = GetTownIndex(tile);
Town *town = Town::GetIfValid(tid);
if (tid == (TownID)INVALID_TOWN) {
if (town == nullptr) {
/* in the case we are generating "many random towns", this value may be INVALID_TOWN */
if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
assert(Town::GetNumItems() == 0);
return NULL;
return nullptr;
}
assert(Town::IsValidID(tid));
Town *town = Town::Get(tid);
if (DistanceManhattan(tile, town->xy) >= threshold) town = NULL;
if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
return town;
}
[[ fallthrough ]];
[[fallthrough]];
case MP_HOUSE:
return Town::GetByTile(tile);
@@ -168,7 +166,7 @@ SpriteID TileZoneCheckOpinionEvaluation(TileIndex tile, Owner owner) {
Town *town = CMClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
if (town == NULL) return INVALID_SPRITE_ID; // no town
else if (HasBit(town->have_ratings, owner)) { // good : bad
else if (town->have_ratings.Test(owner)) { // good : bad
int16 rating = town->ratings[owner];
if(rating <= RATING_APPALLING) return CM_SPR_PALETTE_ZONING_RED;
if(rating <= RATING_POOR) return CM_SPR_PALETTE_ZONING_ORANGE;

View File

@@ -157,7 +157,7 @@ struct ZoningWindow : public Window {
/** Construct the row containing the digit keys. */
static std::unique_ptr<NWidgetBase> MakeZoningButtons()
{
auto hor = std::make_unique<NWidgetHorizontal>(NC_EQUALSIZE);
auto hor = std::make_unique<NWidgetHorizontal>(NWidContainerFlag::EqualSize);
int zone_types_size = lengthof(_zone_types);
hor->SetPadding(1, 1, 1, 1);
@@ -180,7 +180,7 @@ static std::unique_ptr<NWidgetBase> MakeZoningButtons()
static const NWidgetPart _nested_zoning_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, ZTW_CAPTION), SetDataTip(CM_STR_ZONING_TOOLBAR, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_CAPTION, COLOUR_GREY, ZTW_CAPTION), SetStringTip(CM_STR_ZONING_TOOLBAR, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
@@ -192,7 +192,7 @@ static const NWidgetPart _nested_zoning_widgets[] = {
static WindowDesc _zoning_desc (
WDP_AUTO, "cm_zoning", 0, 0,
CM_WC_ZONING_TOOLBAR, WC_NONE,
0,
{},
_nested_zoning_widgets,
&ZoningWindow::hotkeys
);

View File

@@ -17,8 +17,30 @@ enum class TownGrowthTileState : uint8_t {
typedef std::map<TileIndex, TownGrowthTileState> TownsGrowthTilesIndex;
enum class TownGrowthState: uint8 {
NOT_GROWING = 0,
GROWING = 1,
SHRINKING = 2,
};
namespace ext {
struct CBTownInfo {
uint32_t pax_delivered;
uint32_t mail_delivered;
uint32_t pax_delivered_last_month;
uint32_t mail_delivered_last_month;
TownGrowthState growth_state;
uint8_t shrink_effeciency;
uint16_t shrink_rate;
uint16_t shrink_counter;
uint32_t stored[NUM_CARGO];
uint32_t delivered[NUM_CARGO];
uint32_t required[NUM_CARGO];
uint32_t delivered_last_month[NUM_CARGO];
uint32_t required_last_month[NUM_CARGO];
};
class Town {
public:
bool growing_by_chance = false; ///< whether town is growing due to 1/12 chance
@@ -40,6 +62,16 @@ public:
TownsGrowthTilesIndex growth_tiles_last_month;
TownsGrowthTilesIndex growth_tiles;
CBTownInfo cb;
std::optional<std::pair<StationID, CargoType>> ad_ref_goods_entry; ///< poiter to goods entry of some station, used to check rating for regular advertisement
int town_label; ///< Label dependent on _local_company rating.
CompanyMask fund_regularly; ///< funds buildings regularly when previous fund ends
CompanyMask do_powerfund; ///< funds buildings when grow counter is maximal (results in fastest funding possible)
uint32 last_funding = 0; ///< when town was funded the last time
CompanyMask advertise_regularly; ///< advertised regularly to keep stations rating on desired value
uint32 last_advertisement = 0;
uint8 ad_rating_goal; ///< value to keep rating at (for regular advertisement) (0..255)
};
} // namespace ext

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2542,7 +2542,7 @@ struct CompanyWindow : Window
case WID_C_MOD_COMPANY_RESET: {
if (!_networking) return;
this->query_widget = WID_C_MOD_COMPANY_RESET;
ShowQuery(CM_STR_XI_RESET_CAPTION, CM_STR_XI_REALY_RESET, this, ResetCallback);
ShowQuery(GetEncodedString(CM_STR_XI_RESET_CAPTION), GetEncodedString(CM_STR_XI_REALY_RESET), this, ResetCallback);
MarkWholeScreenDirty();
break;
}

View File

@@ -50,6 +50,11 @@ std::unique_ptr<DropDownListItem> MakeDropDownListIconItem(const Dimension &dim,
return std::make_unique<DropDownListIconItem>(dim, sprite, palette, GetString(str), value, masked, shaded);
}
std::unique_ptr<DropDownListItem> CMMakeDropDownListIconItem(const Dimension &dim, SpriteID sprite, PaletteID palette, std::string &&str, int value, bool masked, bool shaded)
{
return std::make_unique<DropDownListIconItem>(dim, sprite, palette, std::move(str), value, masked, shaded);
}
std::unique_ptr<DropDownListItem> MakeDropDownListCheckedItem(bool checked, StringID str, int value, bool masked, bool shaded, uint indent)
{
return std::make_unique<DropDownListCheckedItem>(indent, checked, GetString(str), value, masked, shaded);

View File

@@ -23,4 +23,6 @@ std::unique_ptr<DropDownListItem> MakeDropDownListIconItem(SpriteID sprite, Pale
std::unique_ptr<DropDownListItem> MakeDropDownListIconItem(const Dimension &dim, SpriteID sprite, PaletteID palette, StringID str, int value, bool masked = false, bool shaded = false);
std::unique_ptr<DropDownListItem> MakeDropDownListCheckedItem(bool checked, StringID str, int value, bool masked = false, bool shaded = false, uint indent = 0);
std::unique_ptr<DropDownListItem> CMMakeDropDownListIconItem(const Dimension &dim, SpriteID sprite, PaletteID palette, std::string &&str, int value, bool masked = false, bool shaded = false);
#endif /* DROPDOWN_FUNC_H */

View File

@@ -383,8 +383,8 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
/* Reset the ratings for the old owner */
t->ratings[old_owner] = RATING_INITIAL;
t->have_ratings.Reset(old_owner);
t->cm_advertise_regularly.Reset(old_owner);
t->cm_do_powerfund.Reset(old_owner);
t->cm.advertise_regularly.Reset(old_owner);
t->cm.do_powerfund.Reset(old_owner);
/* Transfer exclusive rights */
if (t->exclusive_counter > 0 && t->exclusivity == old_owner) {
@@ -1128,7 +1128,7 @@ static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest,
/* Increase town's counter for all goods types only if delivered near town*/
if(CB_Enabled()){
if (_settings_game.citymania.cb.acceptance_range == 0 || (DistanceManhattan(st->town->xy, st->xy) <= _settings_game.citymania.cb.acceptance_range)) {
st->town->cb.delivered[cargo_type] += accepted_total;
st->town->cm.cb.delivered[cargo_type] += accepted_total;
InvalidateWindowData(CM_WC_CB_TOWN, st->town->index);
}
}
@@ -1152,7 +1152,7 @@ static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest,
if (accepted_total > 0) {
if (accepted_ind != accepted_total)
citymania::Emit(citymania::event::CargoDeliveredToUnknown{cargo_type, accepted_total - accepted_ind, st});
citymania::Emit(citymania::event::CargoAccepted{company, cargo_type, accepted_total, st, profit, src_type, src});
citymania::Emit(citymania::event::CargoAccepted{company, cargo_type, accepted_total, st, profit, src});
}
return profit;

View File

@@ -1436,7 +1436,7 @@ void RedrawScreenRect(int left, int top, int right, int bottom)
static std::vector<Rect> _dirty_viewport_occlusions;
static const Viewport *_dirty_viewport;
static NWidgetDisplay _dirty_viewport_disp_flags;
static NWidgetDisplayFlags _dirty_viewport_disp_flags;
static void DrawDirtyViewport(uint occlusion, int left, int top, int right, int bottom)
{
@@ -1480,12 +1480,12 @@ static void DrawDirtyViewport(uint occlusion, int left, int top, int right, int
if (_game_mode == GM_MENU) {
RedrawScreenRect(left, top, right, bottom);
} else {
extern void ViewportDrawChk(const Viewport *vp, int left, int top, int right, int bottom);
ViewportDrawChk(_dirty_viewport, left, top, right, bottom);
extern void ViewportDrawChk(const Viewport &vp, int left, int top, int right, int bottom);
ViewportDrawChk(*_dirty_viewport, left, top, right, bottom);
if (_dirty_viewport_disp_flags & (ND_SHADE_GREY | ND_SHADE_DIMMED)) {
if (_dirty_viewport_disp_flags.Any({NWidgetDisplayFlag::ShadeGrey, NWidgetDisplayFlag::ShadeDimmed})) {
GfxFillRect(left, top, right - 1, bottom - 1,
(_dirty_viewport_disp_flags & ND_SHADE_DIMMED) ? PALETTE_TO_TRANSPARENT : PALETTE_NEWSPAPER, FILLRECT_RECOLOUR);
(_dirty_viewport_disp_flags.Test(NWidgetDisplayFlag::ShadeDimmed)) ? PALETTE_TO_TRANSPARENT : PALETTE_NEWSPAPER, FILLRECT_RECOLOUR);
}
VideoDriver::GetInstance()->MakeDirty(left, top, right - left, bottom - top);
}
@@ -1516,7 +1516,7 @@ void DrawDirtyBlocks()
if (_whole_screen_dirty) {
RedrawScreenRect(0, 0, _screen.width, _screen.height);
for (Window *w : Window::IterateFromBack()) {
w->flags &= ~(WF_DIRTY | WF_WIDGETS_DIRTY | WF_DRAG_DIRTIED);
w->flags.Reset({WindowFlag::CMDirty, WindowFlag::CMWidgetsDirty, WindowFlag::CMDragDirtied});
}
_whole_screen_dirty = false;
} else {
@@ -1533,20 +1533,20 @@ void DrawDirtyBlocks()
Backup dpi_backup(_cur_dpi, &bk);
for (Window *w : Window::IterateFromBack()) {
w->flags &= ~WF_DRAG_DIRTIED;
w->flags.Reset(WindowFlag::CMDragDirtied);
if (!MayBeShown(w)) continue;
if (w->viewport != nullptr) w->viewport->is_drawn = false;
if (w->flags & WF_DIRTY) {
if (w->flags.Test(WindowFlag::CMDirty)) {
clear_overlays();
DrawOverlappedWindowFlags flags = DOWF_MARK_DIRTY;
if (HasBit(_gfx_debug_flags, GDF_SHOW_WINDOW_DIRTY)) [[ unlikely ]] {
flags |= DOWF_SHOW_DEBUG;
}
DrawOverlappedWindowWithClipping(w, w->left, w->top, w->left + w->width, w->top + w->height, flags);
w->flags &= ~(WF_DIRTY | WF_WIDGETS_DIRTY);
} else if (w->flags & WF_WIDGETS_DIRTY) {
w->flags.Reset({WindowFlag::CMDirty, WindowFlag::CMWidgetsDirty});
} else if (w->flags.Test(WindowFlag::CMWidgetsDirty)) {
if (w->nested_root != nullptr) {
clear_overlays();
w->nested_root->FillDirtyWidgets(dirty_widgets);
@@ -1559,11 +1559,11 @@ void DrawDirtyBlocks()
}
dirty_widgets.clear();
}
w->flags &= ~WF_WIDGETS_DIRTY;
w->flags.Reset(WindowFlag::CMWidgetsDirty);
}
if (w->viewport != nullptr && !w->IsShaded()) {
Viewport *vp = w->viewport;
auto &vp = w->viewport;
if (vp->is_drawn) {
vp->ClearDirty();
} else if (vp->is_dirty) {
@@ -1577,10 +1577,10 @@ void DrawDirtyBlocks()
_cur_dpi->dst_ptr = _screen.dst_ptr;
_cur_dpi->zoom = ZOOM_LVL_NORMAL;
_dirty_viewport = vp;
_dirty_viewport_disp_flags = w->viewport_widget->disp_flags;
_dirty_viewport = vp.get();
_dirty_viewport_disp_flags = w->cm_viewport_widget->disp_flags;
TransparencyOptionBits to_backup = _transparency_opt;
if (_dirty_viewport_disp_flags & ND_NO_TRANSPARENCY) {
if (_dirty_viewport_disp_flags.Test(NWidgetDisplayFlag::NoTransparency)) {
_transparency_opt &= (1 << TO_SIGNS) | (1 << TO_TEXT); // Disable all transparency, except textual stuff
}

View File

@@ -216,9 +216,9 @@ struct BaseGraphWindow : Window {
protected:
static const int GRAPH_MAX_DATASETS = 64;
static const int GRAPH_NUM_MONTHS = 24; ///< Number of months displayed in the graph.
static const int GRAPH_PAYMENT_RATE_STEPS = 20; ///< Number of steps on Payment rate graph.
static const int PAYMENT_GRAPH_X_STEP_DAYS = 10; ///< X-axis step label for cargo payment rates "Days in transit".
static const int PAYMENT_GRAPH_X_STEP_SECONDS = 20; ///< X-axis step label for cargo payment rates "Seconds in transit".
static const int GRAPH_PAYMENT_RATE_STEPS = 24; ///< Number of steps on Payment rate graph.
static const int PAYMENT_GRAPH_X_STEP_DAYS = 20; ///< X-axis step label for cargo payment rates "Days in transit".
static const int PAYMENT_GRAPH_X_STEP_SECONDS = 40; ///< X-axis step label for cargo payment rates "Seconds in transit".
static const int ECONOMY_QUARTER_MINUTES = 3; ///< Minutes per economic quarter.
static const int ECONOMY_MONTH_MINUTES = 1; ///< Minutes per economic month.
@@ -977,8 +977,8 @@ static /* CM const */ NWidgetPart _nested_income_graph_widgets[] = {
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GRAPH_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetMinimalSize(0, 4),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_ENABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_DISABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_ENABLE_CARGOES), SetStringTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_DISABLE_CARGOES), SetStringTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0),
NWidget(NWID_SPACER), SetMinimalSize(0, 4),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_MATRIX, COLOUR_BROWN, WID_GRAPH_MATRIX), SetFill(0, 2), SetResize(0, 2), SetMatrixDataTip(1, 0, STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO), SetScrollbar(WID_GRAPH_MATRIX_SCROLLBAR),
@@ -1064,8 +1064,8 @@ static NWidgetPart _nested_delivered_cargo_graph_widgets[] = {
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GRAPH_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetMinimalSize(0, 4), SetFill(0, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_ENABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_DISABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_ENABLE_CARGOES), SetStringTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_DISABLE_CARGOES), SetStringTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0),
NWidget(NWID_SPACER), SetMinimalSize(0, 4),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_MATRIX, COLOUR_BROWN, WID_GRAPH_MATRIX), SetFill(0, 2), SetResize(0, 2), SetMatrixDataTip(1, 0, STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO), SetScrollbar(WID_GRAPH_MATRIX_SCROLLBAR),
@@ -1227,13 +1227,13 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
PaymentRatesGraphWindow(WindowDesc &desc, WindowNumber window_number) :
BaseGraphWindow(desc, STR_JUST_CURRENCY_SHORT)
{
this->num_on_x_axis = GRAPH_PAYMENT_RATE_STEPS; TODO set 24
this->num_on_x_axis = GRAPH_PAYMENT_RATE_STEPS;
this->num_vert_lines = GRAPH_PAYMENT_RATE_STEPS;
this->draw_dates = false;
this->x_values_reversed = false;
/* The x-axis is labeled in either seconds or days. A day is two seconds, so we adjust the label if needed. */
this->x_values_increment = 2 * (TimerGameEconomy::UsingWallclockUnits() ? PAYMENT_GRAPH_X_STEP_SECONDS : PAYMENT_GRAPH_X_STEP_DAYS);
this->x_values_increment = TimerGameEconomy::UsingWallclockUnits() ? PAYMENT_GRAPH_X_STEP_SECONDS : PAYMENT_GRAPH_X_STEP_DAYS;
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_GRAPH_MATRIX_SCROLLBAR);

View File

@@ -2055,7 +2055,7 @@ bool CanBuildIndustryOnTile(IndustryType type, TileIndex tile) {
const IndustrySpec *indspec = GetIndustrySpec(type);
CommandCost ret;
if (HasBit(indspec->callback_mask, CBM_IND_LOCATION)) {
if (indspec->callback_mask.Test(IndustryCallbackMask::Location)) {
ret = CheckIfCallBackAllowsCreation(
tile, type, 0, 0, 0, _current_company,
_current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION);

View File

@@ -39,6 +39,7 @@
#include "smallmap_gui.h"
#include "dropdown_type.h"
#include "clear_map.h"
#include "window_gui.h"
#include "zoom_func.h"
#include "industry_cmd.h"
#include "graph_gui.h"
@@ -65,7 +66,7 @@ static const int CM_HOTKEY_SWITCH_LAYOUT = 0x1001;
uint32 _cm_funding_layout;
IndustryType _cm_funding_type;
bool _ignore_restrictions;
bool _ignore_industry_restrictions;
std::bitset<NUM_INDUSTRYTYPES> _displayed_industries; ///< Communication from the industry chain window to the smallmap window about what industries to display.
/** Cargo suffix type (for which window is it requested) */
@@ -294,15 +295,15 @@ static constexpr NWidgetPart _nested_build_industry_widgets[] = {
EndContainer(),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetResize(1, 0),
NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(140, 14), SetDataTip(CM_STR_FUND_INDUSTRY_FORBIDDEN_TILES_TITLE, STR_NULL),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(140, 14), SetStringTip(CM_STR_FUND_INDUSTRY_FORBIDDEN_TILES_TITLE),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_DPI_FT_OFF), SetMinimalSize(60, 12),
SetDataTip(CM_STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF, CM_STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF_TOOLTIP),
SetStringTip(CM_STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF, CM_STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_DPI_FT_ON), SetMinimalSize(60, 12),
SetDataTip(CM_STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON, CM_STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON_TOOLTIP),
SetStringTip(CM_STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON, CM_STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON_TOOLTIP),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
@@ -378,7 +379,7 @@ class BuildIndustryWindow : public Window {
this->vscroll->SetCount(this->list.size());
this->funding_enabled = (_game_mode == GM_EDITOR || Company::IsValidID(_local_company)); // CM
this->cm_funding_enabled = (_game_mode == GM_EDITOR || Company::IsValidID(_local_company)); // CM
}
/** Update status of the fund and display-chain widgets. */
@@ -432,9 +433,9 @@ class BuildIndustryWindow : public Window {
public:
BuildIndustryWindow(WindowDesc &desc) : Window(desc)
{
FIXME move to constructor?
_cm_funding_type = IT_INVALID;
_cm_funding_layout = 0;
_cm_funding_layout = 0;
this->cm_funding_enabled = false;
this->CreateNestedTree();
@@ -450,7 +451,7 @@ public:
~BuildIndustryWindow()
{
citymania::SetIndustryForbiddenTilesHighlight(INVALID_INDUSTRYTYPE);
citymania::SetIndustryForbiddenTilesHighlight(IT_INVALID);
}
void OnInit() override
@@ -834,7 +835,7 @@ public:
{
switch (hotkey) {
case CM_HOTKEY_SWITCH_LAYOUT:
if (this->selected_type != INVALID_INDUSTRYTYPE && _thd.select_proc == CM_DDSP_FUND_INDUSTRY) {
if (this->selected_type != IT_INVALID && _thd.select_proc == CM_DDSP_FUND_INDUSTRY) {
const IndustrySpec *indspec = GetIndustrySpec(this->selected_type);
size_t num_layouts = indspec->layouts.size();
MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection
@@ -858,7 +859,7 @@ public:
static WindowDesc _build_industry_desc(
WDP_AUTO, "build_industry", 170, 212,
WC_BUILD_INDUSTRY, WC_NONE,
WDF_CONSTRUCTION,
WindowDefaultFlag::Construction,
_nested_build_industry_widgets,
&BuildIndustryWindow::hotkeys // CM
);
@@ -3199,14 +3200,13 @@ struct IndustryCargoesWindow : public Window {
DropDownList lst;
Dimension d = GetLargestCargoIconSize();
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
if (_settings_client.gui.developer < 1) {
lst.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index()));
continue;
}
std::string cargo_str;
if (_settings_client.gui.developer >= 1)
cargo_str = GetString(CM_STR_CARGO_WITH_ID, cs->name, cs->Index());
else
cargo_str = GetString(cs->name);
SetDParam(0, cs->name);
SetDParam(1, cs->Index());
lst.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, CM_STR_CARGO_WITH_ID, cs->Index()));
lst.push_back(CMMakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, std::move(cargo_str), cs->Index()));
}
if (!lst.empty()) {
int selected = (this->ind_cargo >= NUM_INDUSTRYTYPES) ? (int)(this->ind_cargo - NUM_INDUSTRYTYPES) : -1;
@@ -3220,15 +3220,14 @@ struct IndustryCargoesWindow : public Window {
for (IndustryType ind : _sorted_industry_types) {
const IndustrySpec *indsp = GetIndustrySpec(ind);
if (!indsp->enabled) continue;
if (_settings_client.gui.developer < 1) {
lst.push_back(MakeDropDownListStringItem(indsp->name, ind, false));
continue;
}
SetDParam(0, indsp->name);
SetDParam(1, ind);
auto s = GetString(CM_STR_INDUSTRY_TYPE_WITH_ID);
lst.push_back(MakeDropDownListStringItem(s, ind, false));
std::string indsp_str;
if (_settings_client.gui.developer >= 1)
indsp_str = GetString(CM_STR_INDUSTRY_TYPE_WITH_ID, indsp->name, ind);
else
indsp_str = GetString(indsp->name);
lst.push_back(MakeDropDownListStringItem(std::move(indsp_str), ind, false));
}
if (!lst.empty()) {
int selected = (this->ind_cargo < NUM_INDUSTRYTYPES) ? (int)this->ind_cargo : -1;

View File

@@ -6313,8 +6313,8 @@ CM_STR_CONFIG_SETTING_INVERT_FN_FOR_SIGNAL_DRAG_HELPTEXT :When enabled bu
CM_STR_TOGGLE_CLIENTS_OVERLAY :{BLACK}Toggle client list overlay.
CM_STR_SMALLMAP_TOWN_LARGE :{TINY_FONT}{YELLOW}{TOWN}
CM_STR_SMALLMAP_POPULATION_LARGE :{TINY_FONT}{YELLOW}({NUM})
CM_STR_SMALLMAP_POPULATION :{TINY_FONT}{WHITE}({NUM})
CM_STR_SMALLMAP_POPULATION_LARGE :{TINY_FONT}{YELLOW}{NUM}
CM_STR_SMALLMAP_POPULATION :{TINY_FONT}{WHITE}{NUM}
# Network server list filters
CM_STR_NETWORK_SERVER_LIST_FILTER_CITYMANIA :{BLACK}CityMania

View File

@@ -147,7 +147,7 @@ bool DoZoomInOutWindow(ZoomStateChange how, Window *w)
if (w->viewport != nullptr) { // the viewport can be null when how == ZOOM_NONE
w->viewport->virtual_left = w->viewport->scrollpos_x;
w->viewport->virtual_top = w->viewport->scrollpos_y;
UpdateViewportSizeZoom(vp);
UpdateViewportSizeZoom(*w->viewport);
}
/* Update the windows that have zoom-buttons to perhaps disable their buttons */
@@ -191,7 +191,7 @@ void FixTitleGameZoom(int zoom_adjust)
vp.virtual_width = ScaleByZoom(vp.width, vp.zoom);
vp.virtual_height = ScaleByZoom(vp.height, vp.zoom);
UpdateViewportSizeZoom(vp);
UpdateViewportSizeZoom(vp);
}
static constexpr NWidgetPart _nested_main_window_widgets[] = {

View File

@@ -133,7 +133,7 @@ public:
LandInfoWindow(Tile tile, Tile end_tile) : Window(_land_info_desc), tile(tile), end_tile(end_tile)
{
this->InitNested();
CLRBITS(this->flags, WF_WHITE_BORDER);
this->flags.Reset(WindowFlag::WhiteBorder);
#if defined(_DEBUG)
# define LANDINFOD_LEVEL 0
@@ -291,8 +291,7 @@ public:
/* CityMania code start (House pop) */
if (td.cm_population != 0) {
SetDParam(0, td.cm_population);
this->landinfo_data.push_back(GetString(CM_STR_LAND_AREA_INFORMATION_POP));
this->landinfo_data.push_back(GetString(CM_STR_LAND_AREA_INFORMATION_POP, td.cm_population));
}
/* CityMania code end */

View File

@@ -1253,7 +1253,7 @@ void NetworkGameLoop()
}
NetworkExecuteLocalCommandQueue();
if (citymania::_pause_countdown > 0 && --citymania::_pause_countdown == 0) Command<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, 1);
if (citymania::_pause_countdown > 0 && --citymania::_pause_countdown == 0) Command<CMD_PAUSE>::Post(PauseMode::Normal, 1);
citymania::ExecuteFakeCommands(TimerGameTick::counter);

View File

@@ -914,7 +914,7 @@ static constexpr NWidgetPart _nested_network_game_widgets[] = {
EndContainer(),
/* end CityMania code */
NWidget(NWID_HORIZONTAL), SetPIP(0, 7, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_NG_FILTER_LABEL), SetDataTip(STR_LIST_FILTER_TITLE, STR_NULL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_NG_FILTER_LABEL), SetStringTip(STR_LIST_FILTER_TITLE),
NWidget(WWT_EDITBOX, COLOUR_LIGHT_BLUE, WID_NG_FILTER), SetMinimalSize(251, 0), SetFill(1, 0), SetResize(1, 0),
SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
EndContainer(),
@@ -2027,15 +2027,13 @@ public:
}
if (company_id == COMPANY_SPECTATOR) {
DrawSprite(SPR_COMPANY_ICON, PALETTE_TO_GREY, icon_left, y + offset);
DrawSprite(CM_SPR_COMPANY_ICON, PALETTE_TO_GREY, icon_left, y + offset);
DrawString(tr.left, tr.right, y + text_y_offset, STR_NETWORK_CLIENT_LIST_SPECTATORS, TC_SILVER);
} else if (company_id == COMPANY_NEW_COMPANY) {
DrawSprite(SPR_COMPANY_ICON, PALETTE_TO_GREY, icon_left, y + offset);
DrawSprite(CM_SPR_COMPANY_ICON, PALETTE_TO_GREY, icon_left, y + offset);
DrawString(tr.left, tr.right, y + text_y_offset, STR_NETWORK_CLIENT_LIST_NEW_COMPANY, TC_WHITE);
} else {
DrawCompanyIcon(company_id, icon_left, y + offset);
FIXME DrawSprite(CM_SPR_COMPANY_ICON_LOCKED, COMPANY_SPRITE_COLOUR(company_id), icon_left, y + offset);
DrawSprite(CM_SPR_COMPANY_ICON, COMPANY_SPRITE_COLOUR(company_id), icon_left, y + offset);
DrawString(tr.left, tr.right, y + text_y_offset, GetString(STR_COMPANY_NAME, company_id, company_id), TC_SILVER);
}
}

View File

@@ -448,7 +448,7 @@ struct NewGRFInspectWindow : Window {
uint i = 0;
this->DrawString(r, i++, fmt::format("Industry type: {}", (int)((const Industry *)base)->type));
if (nif->variables.empty() {
if (nif->variables.empty()) {
this->DrawString(r, i++, "Variables:");
for (const NIVariable &niv : nif->variables) {
bool avail = true;

View File

@@ -7,6 +7,7 @@
/** @file openttd.cpp Functions related to starting OpenTTD. */
#include "openttd.h"
#include "stdafx.h"
#include "blitter/factory.hpp"
@@ -1304,7 +1305,7 @@ void StateGameLoop()
}
if (citymania::_pause_countdown > 0 && --citymania::_pause_countdown == 0) {
_pause_mode = PM_PAUSED_NORMAL;
_pause_mode = PauseMode::Normal;
SetWindowDirty(WC_MAIN_TOOLBAR, 0);
}

View File

@@ -427,7 +427,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlags flags, TileIndex tile, RailType ra
{
CommandCost cost(EXPENSES_CONSTRUCTION);
_rail_track_endtile = INVALID_TILE; // CM
_cm_rail_track_endtile = INVALID_TILE; // CM
if (!ValParamRailType(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
@@ -446,7 +446,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlags flags, TileIndex tile, RailType ra
ret = CheckTrackCombination(tile, trackbit);
if (ret.Succeeded()) ret = EnsureNoTrainOnTrack(tile, track);
if (ret.Failed()) {
if (ret.GetErrorMessage() == STR_ERROR_ALREADY_BUILT) _rail_track_endtile = tile;
if (ret.GetErrorMessage() == STR_ERROR_ALREADY_BUILT) _cm_rail_track_endtile = tile;
return ret;
}
@@ -565,7 +565,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlags flags, TileIndex tile, RailType ra
}
if (IsLevelCrossing(tile) && GetCrossingRailBits(tile) == trackbit) {
_rail_track_endtile = tile;
_cm_rail_track_endtile = tile;
return CommandCost(STR_ERROR_ALREADY_BUILT);
}
[[fallthrough]];
@@ -608,7 +608,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlags flags, TileIndex tile, RailType ra
}
cost.AddCost(RailBuildCost(railtype));
_rail_track_endtile = tile;
_cm_rail_track_endtile = tile;
return cost;
}
@@ -624,7 +624,7 @@ CommandCost CmdRemoveSingleRail(DoCommandFlags flags, TileIndex tile, Track trac
CommandCost cost(EXPENSES_CONSTRUCTION);
bool crossing = false;
_rail_track_endtile = INVALID_TILE;
_cm_rail_track_endtile = INVALID_TILE;
if (!ValParamTrackOrientation(track)) return CMD_ERROR;
TrackBits trackbit = TrackToTrackBits(track);
@@ -757,7 +757,7 @@ CommandCost CmdRemoveSingleRail(DoCommandFlags flags, TileIndex tile, Track trac
if (v != nullptr) TryPathReserve(v, true);
}
_rail_track_endtile = tile;
_cm_rail_track_endtile = tile;
return cost;
}
@@ -906,7 +906,7 @@ static CommandCost CmdRailTrackHelper(DoCommandFlags flags, TileIndex tile, Tile
if (ret.Failed()) {
last_error = std::move(ret);
if (_rail_track_endtile == INVALID_TILE) _cm_rail_track_endtile = last_endtile; // CM
if (_cm_rail_track_endtile == INVALID_TILE) _cm_rail_track_endtile = last_endtile; // CM
if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !remove) {
if (fail_on_obstacle) return last_error;
if (had_success) break; // Keep going if we haven't constructed any rail yet, skipping the start of the drag

View File

@@ -2045,7 +2045,7 @@ static WindowDesc _build_depot_desc(
WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
WindowDefaultFlag::Construction,
_nested_build_depot_widgets,
BuildRailDepotWindow::hotkeys
&BuildRailDepotWindow::hotkeys
);
static void ShowBuildTrainDepotPicker(Window *parent)

View File

@@ -7,6 +7,7 @@
/** @file road_gui.cpp GUI for building roads. */
#include "station_type.h"
#include "stdafx.h"
#include "gui.h"
#include "window_gui.h"
@@ -562,14 +563,14 @@ struct BuildRoadToolbarWindow : Window {
break;
case WID_ROT_BUS_STATION:
if (citymania::HandleStationPlacePushButton(this, WID_ROT_BUS_STATION, std::make_shared<citymania::RoadStationPreview>(ROADSTOP_BUS))) {
if (citymania::HandleStationPlacePushButton(this, WID_ROT_BUS_STATION, std::make_shared<citymania::RoadStationPreview>(RoadStopType::Bus))) {
ShowRVStationPicker(this, RoadStopType::Bus);
this->last_started_action = widget;
}
break;
case WID_ROT_TRUCK_STATION:
if (citymania::HandleStationPlacePushButton(this, WID_ROT_TRUCK_STATION, std::make_shared<citymania::RoadStationPreview>(ROADSTOP_TRUCK))) {
if (citymania::HandleStationPlacePushButton(this, WID_ROT_TRUCK_STATION, std::make_shared<citymania::RoadStationPreview>(RoadStopType::Truck))) {
ShowRVStationPicker(this, RoadStopType::Truck);
this->last_started_action = widget;
}
@@ -1241,9 +1242,9 @@ static constexpr NWidgetPart _nested_build_road_depot_widgets[] = {
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_SE), SetFill(0, 0), SetToolTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
EndContainer(),
EndContainer(),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CM_WID_BROD_DEPOT_AUTO), SetDataTip(CM_STR_STATION_BUILD_ORIENTATION_AUTO, CM_STR_BUILD_DEPOT_ROAD_ORIENTATION_AUTO_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CM_WID_BROD_DEPOT_AUTO), SetStringTip(CM_STR_STATION_BUILD_ORIENTATION_AUTO, CM_STR_BUILD_DEPOT_ROAD_ORIENTATION_AUTO_TOOLTIP),
EndContainer(),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CM_WID_BROD_DEPOT_AUTO), SetToolTip(CM_STR_STATION_BUILD_ORIENTATION_AUTO, CM_STR_BUILD_DEPOT_ROAD_ORIENTATION_AUTO_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CM_WID_BROD_DEPOT_AUTO), SetStringTip(CM_STR_STATION_BUILD_ORIENTATION_AUTO, CM_STR_BUILD_DEPOT_ROAD_ORIENTATION_AUTO_TOOLTIP),
EndContainer(),
};
@@ -1252,7 +1253,7 @@ static WindowDesc _build_road_depot_desc(
WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
WindowDefaultFlag::Construction,
_nested_build_road_depot_widgets,
BuildRoadDepotWindow::hotkeys
&BuildRoadDepotWindow::hotkeys
);
static void ShowRoadDepotPicker(Window *parent)
@@ -1418,13 +1419,15 @@ public:
for (WidgetID i = RoadTypeIsTram(_cur_roadtype) ? WID_BROS_STATION_X : WID_BROS_STATION_NE; i < WID_BROS_LT_OFF; i++) {
this->GetWidget<NWidgetCore>(i)->SetToolTip(rti->strings.picker_tooltip[to_underlying(rs)]);
}
if (RoadTypeIsTram(_cur_roadtype)) {
this->GetWidget<NWidgetCore>(WID_BROS_STATION_X).SetToolTip(rti->strings.picker_tooltip[rs]);
this->GetWidget<NWidgetCore>(WID_BROS_STATION_Y).SetToolTip(rti->strings.picker_tooltip[rs]);
this->GetWidget<NWidgetCore>(CM_WID_BROS_STATION_XY_AUTO).SetToolTip(rti->strings.picker_tooltip[rs]);
this->GetWidget<NWidgetCore>(WID_BROS_STATION_X)->SetToolTip(rti->strings.picker_tooltip[to_underlying(rs)]);
this->GetWidget<NWidgetCore>(WID_BROS_STATION_Y)->SetToolTip(rti->strings.picker_tooltip[to_underlying(rs)]);
this->GetWidget<NWidgetCore>(CM_WID_BROS_STATION_XY_AUTO)->SetToolTip(rti->strings.picker_tooltip[to_underlying(rs)]);
} else {
for (WidgetID i = WID_BROS_STATION_NE; i < WID_BROS_LT_OFF; i++) {
this->GetWidget<NWidgetCore>(i).SetToolTip(rti->strings.picker_tooltip[rs]);
this->GetWidget<NWidgetCore>(i)->SetToolTip(rti->strings.picker_tooltip[to_underlying(rs)]);
}
}
@@ -1664,8 +1667,8 @@ static constexpr NWidgetPart _nested_road_station_picker_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CM_WID_BROS_STATION_AUTO), SetMinimalSize(134, 12), SetDataTip(CM_STR_STATION_BUILD_ORIENTATION_AUTO, CM_STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CM_WID_BROS_STATION_XY_AUTO), SetMinimalSize(66, 12), SetDataTip(CM_STR_STATION_BUILD_ORIENTATION_AUTO, CM_STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CM_WID_BROS_STATION_AUTO), SetMinimalSize(134, 12), SetStringTip(CM_STR_STATION_BUILD_ORIENTATION_AUTO, CM_STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CM_WID_BROS_STATION_XY_AUTO), SetMinimalSize(66, 12), SetStringTip(CM_STR_STATION_BUILD_ORIENTATION_AUTO, CM_STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP),
EndContainer(),
EndContainer(),
/* 2-orientation plane. */

View File

@@ -33,11 +33,11 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r)
std::string line;
if (_settings_client.gui.newgrf_developer_tools) {
line = GetString(CM_STR_VEHICLE_INFO_BUILT_VALUE_WITH_ID, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->index);
line = GetString(CM_STR_VEHICLE_INFO_BUILT_VALUE_WITH_ID, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->index, v->build_year, v->value);
} else {
line = GetString(STR_VEHICLE_INFO_BUILT_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails));
line = GetString(STR_VEHICLE_INFO_BUILT_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->build_year, v->value);
}
DrawString(r.left, r.right, y, line, v->build_year, v->value);
DrawString(r.left, r.right, y, line);
y += GetCharacterHeight(FS_NORMAL);
if (v->HasArticulatedPart()) {

View File

@@ -540,34 +540,34 @@ static inline bool MayHaveBridgeAbove(Tile t)
IsTileType(t, MP_WATER) || IsTileType(t, MP_TUNNELBRIDGE) || IsTileType(t, MP_OBJECT);
}
extern GameStrings *_current_data;
extern std::shared_ptr<GameStrings> _current_gamestrings_data;
void AfterLoadFindBTProCBInfo() {
if (_current_data == NULL) return;
if (_current_gamestrings_data == nullptr) return;
char buf[15];
char *p = buf;
int pn;
p += Utf8Encode(p, SCC_ENCODED);
for (const auto &ls : _current_data->raw_strings) {
std::string encoded_prefix;
StringBuilder builder(encoded_prefix);
builder.PutUtf8(SCC_ENCODED);
for (const auto &ls : _current_gamestrings_data->raw_strings) {
int string_id = 0;
for (const auto &s : ls.lines) {
if (s.empty() || s[0] == ';' || s[0] == '#' || s[0] == ' ' || s[0] == '\0') continue;
if (strncmp(s.c_str(), "STR_TOWN_CLAIMED_CARGOS", strlen("STR_TOWN_CLAIMED_CARGOS")) == 0 ||
strncmp(s.c_str(), "STR_TOWN_CARGOS_NEEDED_CB", strlen("STR_TOWN_CARGOS_NEEDED_CB")) == 0) {
pn = p - buf + fmt::format("{:X}:", string_id).length();
bool with_decay = (strncmp(s.c_str(), "STR_TOWN_CLAIMED_CARGOS_DECAY",
strlen("STR_TOWN_CLAIMED_CARGOS_DECAY")) == 0);
auto str_prefix = encoded_prefix + fmt::format("{:X}:", string_id);
auto pn = str_prefix.size();
for (StoryPageElement *se : StoryPageElement::Iterate()) {
if (strncmp(se->text.c_str(), buf, pn) != 0) continue;
if (se->text.string.compare(0, pn, str_prefix, 0, pn) != 0) continue;
uint req, cargomask, from, decay=0;
if (with_decay) {
sscanf(se->text.c_str() + pn, "%X:%X:%X:%X", &req, &cargomask, &from, &decay);
sscanf(se->text.string.c_str() + pn, "%X:%X:%X:%X", &req, &cargomask, &from, &decay);
} else {
sscanf(se->text.c_str() + pn, "%X:%X:%X", &req, &cargomask, &from);
sscanf(se->text.string.c_str() + pn, "%X:%X:%X", &req, &cargomask, &from);
}
uint cargo_id = FindFirstBit(cargomask);
if (!CB_Enabled()) CB_SetCB(true);
CB_SetCB(true);
CB_SetRequirements(cargo_id, req, from, decay);
}
}
@@ -3415,7 +3415,7 @@ bool AfterLoadGame()
citymania::InitializeZoningMap();
citymania::minimap_init_industries();
if ((!_networking || _network_server ) && _settings_client.gui.cm_pause_after_load) _pause_mode = PM_PAUSED_NORMAL;
if ((!_networking || _network_server ) && _settings_client.gui.cm_pause_after_load) _pause_mode = PauseMode::Normal;
CheckGroundVehiclesAtCorrectZ();

View File

@@ -2946,16 +2946,14 @@ static std::optional<SavePreset> ParseSavePreset(const std::string &str)
if (level != Clamp<int>(level, slf.min_compression, slf.max_compression)) {
/* Invalid compression level, show the error and use default level */
SetDParamStr(0, level_str.c_str());
ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL, WL_CRITICAL);
ShowErrorMessage(GetEncodedString(STR_CONFIG_ERROR), GetEncodedString(STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL, level_str), WL_CRITICAL);
return SavePreset{&slf, slf.default_compression};
}
return SavePreset{&slf, (uint8_t)level};
}
}
SetDParamStr(0, str.c_str());
ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM, WL_CRITICAL);
ShowErrorMessage(GetEncodedString(STR_CONFIG_ERROR), GetEncodedString(STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM, str), WL_CRITICAL);
return {};
}

View File

@@ -191,7 +191,7 @@ static bool MakeSmallScreenshot(bool crashlog)
* @param height the height of the screenshot, or 0 for current viewport height (needs to be 0 with SC_VIEWPORT, SC_CRASHLOG, and SC_WORLD).
* @return Viewport
*/
static Viewport SetupScreenshotViewport(ScreenshotType t, uint32_t width = 0, uint32_t height = 0)
/* CM static */ Viewport SetupScreenshotViewport(ScreenshotType t, uint32_t width = 0, uint32_t height = 0)
{
Viewport vp{};

View File

@@ -64,15 +64,15 @@ void DrawShipDetails(const Vehicle *v, const Rect &r)
{
int y = r.top;
FIXME
SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails));
SetDParam(1, v->build_year);
SetDParam(2, v->value);
if (_settings_client.gui.newgrf_developer_tools) SetDParam(3, v->index); // CM
DrawString(r.left, r.right, y, _settings_client.gui.newgrf_developer_tools ? CM_STR_VEHICLE_INFO_BUILT_VALUE_WITH_ID : STR_VEHICLE_INFO_BUILT_VALUE);
std::string str;
auto engine_param = PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_BUILT_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->build_year, v->value));
if (_settings_client.gui.developer >= 1) {
str = GetString(CM_STR_VEHICLE_INFO_BUILT_VALUE_WITH_ID, engine_param, v->build_year, v->value, v->index);
} else {
str = GetString(STR_VEHICLE_INFO_BUILT_VALUE, engine_param, v->build_year, v->value);
}
DrawString(r.left, r.right, y, str);
y += GetCharacterHeight(FS_NORMAL);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_CAPACITY, v->cargo_type, v->cargo_cap, GetCargoSubtypeText(v)));

View File

@@ -33,6 +33,7 @@
#include "citymania/cm_station_gui.hpp"
#include "safeguards.h"
#include <optional>
/** The pool of stations. */
StationPool _station_pool("Station");
@@ -88,11 +89,9 @@ Station::~Station()
citymania::OnStationRemoved(this);
for (Town *t : Town::Iterate()) {
// Using poiter comparison instead of cycling cargos
if (t->ad_ref_goods_entry >= this->goods &&
t->ad_ref_goods_entry < this->goods + NUM_CARGO) {
t->ad_ref_goods_entry = NULL;
}
if (!t->cm.ad_ref_goods_entry.has_value()) continue;
auto [station_id, cargo_type] = t->cm.ad_ref_goods_entry.value();
if (station_id == this->index) t->cm.ad_ref_goods_entry = std::nullopt;
}
if (CleaningPool()) {

View File

@@ -87,7 +87,7 @@ int DrawStationCoverageAreaText(const Rect &r, StationCoverageType sct, int rad,
/* CityMania code begin */
if (supplies) {
auto s = citymania::GetStationCoverageProductionText(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE, rad, sct);
return DrawStringMultiLine(left, right, top, INT32_MAX, s.c_str());
return DrawStringMultiLine(r, s);
}
/* CityMania code end */
@@ -117,16 +117,18 @@ int DrawStationAuthorityText(int left, int right, int top) {
Town *town = ClosestTownFromTile(tile, UINT_MAX);
auto dist = DistanceManhattan(town->xy, tile);
SetDParam(0, town ? town->index : INVALID_TOWN);
auto tid = (town ? town->index : TownID::Invalid());
std::string str;
if (dist <= 10) {
return DrawStringMultiLine(left, right, top, INT32_MAX, CM_STR_STATION_BUILD_TOWN_SMALL);
str = GetString(CM_STR_STATION_BUILD_TOWN_SMALL, tid);
} else if (dist <= 15) {
return DrawStringMultiLine(left, right, top, INT32_MAX, CM_STR_STATION_BUILD_TOWN_MEDIUM);
str = GetString(CM_STR_STATION_BUILD_TOWN_MEDIUM, tid);
} else if (dist <= 20) {
return DrawStringMultiLine(left, right, top, INT32_MAX, CM_STR_STATION_BUILD_TOWN_LARGE);
str = GetString(CM_STR_STATION_BUILD_TOWN_LARGE, tid);
} else {
return DrawStringMultiLine(left, right, top, INT32_MAX, CM_STR_STATION_BUILD_TOWN);
str = GetString(CM_STR_STATION_BUILD_TOWN, tid);
}
return DrawStringMultiLine(left, right, top, INT32_MAX, str);
}
/**
@@ -1940,7 +1942,7 @@ struct StationViewWindow : public Window {
DrawString(tr, TimerGameEconomy::UsingWallclockUnits() ? STR_STATION_VIEW_SUPPLY_RATINGS_TITLE_MINUTE : STR_STATION_VIEW_SUPPLY_RATINGS_TITLE_MONTH);
tr.top += GetCharacterHeight(FS_NORMAL);
this->ratings_list_y = tr.top;
this->cm_ratings_list_y = tr.top;
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
const GoodsEntry *ge = &st->goods[cs->Index()];
if (!ge->HasRating()) continue;
@@ -2180,10 +2182,10 @@ struct StationViewWindow : public Window {
bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) override
{
if (widget != WID_SV_ACCEPT_RATING_LIST ||
this->GetWidget<NWidgetCore>(WID_SV_ACCEPTS_RATINGS)->widget_data == STR_STATION_VIEW_RATINGS_BUTTON)
this->GetWidget<NWidgetCore>(WID_SV_ACCEPTS_RATINGS)->GetString() == STR_STATION_VIEW_RATINGS_BUTTON)
return false;
int ofs_y = pt.y - this->ratings_list_y;
int ofs_y = pt.y - this->cm_ratings_list_y;
if (ofs_y < 0) return false;
const Station *st = Station::Get(this->window_number);
@@ -2358,11 +2360,10 @@ struct SelectStationWindow : Window {
Scrollbar *vscroll = nullptr;
SelectStationWindow(WindowDesc &desc, TileArea ta, StationPickerCmdProc&& proc) :
Window(desc, WPUT_WIDGET_RELATIVE),
Window(desc),
select_station_proc(std::move(proc)),
area(ta)
{
this->wpu_widget = WID_JS_PANEL;
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_JS_SCROLLBAR);
this->GetWidget<NWidgetCore>(WID_JS_CAPTION)->SetString(T::IsWaypoint() ? STR_JOIN_WAYPOINT_CAPTION : STR_JOIN_STATION_CAPTION);
@@ -2375,7 +2376,7 @@ struct SelectStationWindow : Window {
void Close([[maybe_unused]] int data = 0) override
{
if constexpr (std::is_same_v<T, Waypoint *>) SetViewportCatchmentSpecializedStation<typename T::StationType>(nullptr, true);
else citymania::SetSelectedStationToJoin(Station::Invalid());
else citymania::SetSelectedStationToJoin(StationID::Invalid());
_thd.freeze = false;
this->Window::Close();
@@ -2465,7 +2466,7 @@ struct SelectStationWindow : Window {
{
if (widget != WID_JS_PANEL) {
if constexpr (std::is_same_v<typename T::StationType, Waypoint>) SetViewportCatchmentSpecializedStation<typename T::StationType>(nullptr, true);
else citymania::SetSelectedStationToJoin(INVALID_STATION);
else citymania::SetSelectedStationToJoin(StationID::Invalid());
return;
}

View File

@@ -102,10 +102,7 @@ struct StatusBarWindow : Window {
size = Dimension(0, 0);
return;
}
SetDParam(0, 999);
SetDParam(1, 999);
SetDParam(2, 9999);
d = GetStringBoundingBox(CM_STR_STATUSBAR_APM);
d = GetStringBoundingBox(GetString(CM_STR_STATUSBAR_APM, 999, 999, 9999));
break;
default:
@@ -176,10 +173,13 @@ struct StatusBarWindow : Window {
case CM_WID_S_APM:
if (_settings_client.gui.cm_show_apm) {
auto epm = citymania::GetEPM();
SetDParam(0, epm.second);
SetDParam(1, epm.first);
SetDParam(2, std::min(citymania::get_average_command_lag(), 9999));
DrawString(tr, CM_STR_STATUSBAR_APM, TC_FROMSTRING, SA_HOR_CENTER);
auto str = GetString(
CM_STR_STATUSBAR_APM,
epm.second,
epm.first,
std::min(citymania::get_average_command_lag(), 9999)
);
DrawString(tr, str, TC_FROMSTRING, SA_HOR_CENTER);
}
break;
}

View File

@@ -107,8 +107,8 @@ public:
inline void clear() { this->string.clear(); }
inline bool empty() const { return this->string.empty(); }
std::string string; ///< The encoded string. CM: make public
private:
std::string string; ///< The encoded string.
/* An EncodedString can only be created by GetEncodedStringWithArgs(). */
explicit EncodedString(std::string &&string) : string(std::move(string)) {}

View File

@@ -3,12 +3,12 @@ static const SettingVariant _citymania_settings_table[] = {
[post-amble]
};
[templates]
SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $from, $to, $cat, $extra, $startup),
SDT_VAR = SDT_VAR(GameSettings, $var, $type, SettingFlags({$flags}), $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $range_cb, $from, $to, $cat, $extra, $startup),
[validation]
SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size");
[defaults]
flags = SF_NONE
flags = SettingFlag::CityMania
interval = 0
str = STR_NULL
strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT
@@ -19,6 +19,7 @@ str_cb = nullptr
help_cb = nullptr
val_cb = nullptr
def_cb = nullptr
range_cb = nullptr
load = nullptr
from = SL_MIN_VERSION
to = SL_MAX_VERSION

View File

@@ -11,16 +11,16 @@ static const SettingVariant _cmclient_settings_table[] = {
[post-amble]
};
[templates]
SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $from, $to, $cat, $extra, $startup),
SDTC_VAR = SDTC_VAR( $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $from, $to, $cat, $extra, $startup),
SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $from, $to, $cat, $extra, $startup),
SDTC_BOOL = SDTC_BOOL( $var, SettingFlags({$flags}), $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $from, $to, $cat, $extra, $startup),
SDTC_OMANY = SDTC_OMANY( $var, $type, SettingFlags({$flags}), $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $from, $to, $cat, $extra, $startup),
SDTC_VAR = SDTC_VAR( $var, $type, SettingFlags({$flags}), $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $range_cb, $from, $to, $cat, $extra, $startup),
[validation]
SDTC_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size");
SDTC_OMANY = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size");
SDTC_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size");
[defaults]
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::CityMania
interval = 0
str = STR_NULL
strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT
@@ -31,6 +31,7 @@ str_cb = nullptr
help_cb = nullptr
val_cb = nullptr
def_cb = nullptr
range_cb = nullptr
load = nullptr
from = SL_MIN_VERSION
to = SL_MAX_VERSION
@@ -65,7 +66,7 @@ str = CM_STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_UNLOAD
[SDTC_OMANY]
var = gui.cm_ctrl_order_mod
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
def = 1
max = 6
full = _order_mod_actions
@@ -76,7 +77,7 @@ cat = SC_BASIC
[SDTC_OMANY]
var = gui.cm_shift_order_mod
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
def = 0
max = 6
full = _order_mod_actions
@@ -87,7 +88,7 @@ cat = SC_BASIC
[SDTC_OMANY]
var = gui.cm_ctrl_shift_order_mod
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
def = 2
max = 6
full = _order_mod_actions
@@ -98,7 +99,7 @@ cat = SC_BASIC
[SDTC_OMANY]
var = gui.cm_alt_order_mod
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
def = 4
max = 6
full = _order_mod_actions
@@ -109,7 +110,7 @@ cat = SC_BASIC
[SDTC_OMANY]
var = gui.cm_alt_shift_order_mod
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
def = 3
max = 6
full = _order_mod_actions
@@ -120,7 +121,7 @@ cat = SC_BASIC
[SDTC_OMANY]
var = gui.cm_alt_ctrl_order_mod
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
def = 5
max = 6
full = _order_mod_actions
@@ -141,7 +142,7 @@ str = CM_STR_CONFIG_SETTING_WARN_IF_RUNWAY_IS_TOO_SHORT
[SDTC_VAR]
var = gui.cm_powerfund_money
type = SLE_UINT
guiflags = SGF_CURRENCY
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiCurrency, SettingFlag::CityMania
def = 200000
min = 0
max = 2000000
@@ -179,7 +180,7 @@ strhelp = CM_STR_CONFIG_SETTING_LAND_TOOLTIPS_FOR_HOUSES_HELPTEXT
[SDTC_OMANY]
var = gui.cm_fn_mod
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
full = _mod_keys
def = 2
min = 0
@@ -192,7 +193,7 @@ cat = SC_ADVANCED
[SDTC_OMANY]
var = gui.cm_remove_mod
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
full = _mod_keys
def = 2
min = 0
@@ -205,7 +206,7 @@ cat = SC_ADVANCED
[SDTC_OMANY]
var = gui.cm_estimate_mod
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
full = _mod_keys
def = 1
min = 0
@@ -218,7 +219,7 @@ cat = SC_ADVANCED
[SDTC_OMANY]
var = gui.cm_shaded_trees
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
full = _shaded_tree_options
def = 2
min = 0
@@ -240,7 +241,7 @@ post_cb = cm_v_RedrawStatusBar
[SDTC_OMANY]
var = gui.cm_graph_background
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_CITYMANIA
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania
full = _graph_background_options
def = 0
min = 0

View File

@@ -14,6 +14,7 @@
#include "company_base.h"
#include "house.h"
#include "gui.h"
#include "tile_type.h"
#include "window_gui.h"
#include "window_func.h"
#include "viewport_func.h"
@@ -128,21 +129,21 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t
// loop through every tile and send a demolish command for each tree
// orthogonal area
TileIndex tree_start_tile, tree_recent_tile, prev_tile;
tree_start_tile = tree_recent_tile = prev_tile = 0;
tree_start_tile = tree_recent_tile = prev_tile = INVALID_TILE;
if (!citymania::_fn_mod) {
OrthogonalTileArea square_area = OrthogonalTileArea(start_tile, end_tile);
for (auto cur_tile : square_area) {
// if we're on a non-consecutive tile or we've hit a black-marked tile
// safe tiles are: TREES or non-FIELD clear tiles (because they're expensive to demolish)
if (tree_start_tile != 0 &&
if (tree_start_tile != INVALID_TILE &&
(cur_tile != prev_tile + 1 ||
(!IsTileType(cur_tile, MP_TREES) && (!IsTileType(cur_tile, MP_CLEAR) || IsClearGround(cur_tile, CLEAR_FIELDS))))) {
Command<CMD_CLEAR_AREA>::Post(STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, tree_start_tile, tree_recent_tile, 0);
tree_start_tile = tree_recent_tile = 0;
tree_start_tile = tree_recent_tile = INVALID_TILE;
}
// if current tile is a tree
if (IsTileType(cur_tile, MP_TREES)) {
if (tree_start_tile == 0) {
if (tree_start_tile == INVALID_TILE) {
tree_start_tile = cur_tile;
}
tree_recent_tile = cur_tile;
@@ -150,7 +151,7 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t
prev_tile = cur_tile;
}
// one last ride to flavortown
if (tree_start_tile != 0) {
if (tree_start_tile != INVALID_TILE) {
Command<CMD_CLEAR_AREA>::Post(STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, tree_start_tile, tree_recent_tile, 0);
}
} else { // diagonal area
@@ -160,15 +161,15 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t
TileIndexDiffC tile_diff = TileIndexToTileIndexDiffC(cur_tile, prev_tile);
// if we're on a non-consecutive tile or we've hit a black-marked tile
// safe tiles are: TREES or non-FIELD clear tiles (because they're expensive to demolish)
if (tree_start_tile != 0 &&
if (tree_start_tile != INVALID_TILE &&
(!((tile_diff.x == 1 && tile_diff.y == 1) || (tile_diff.x == -1 && tile_diff.y == -1)) ||
(!IsTileType(cur_tile, MP_TREES) && (!IsTileType(cur_tile, MP_CLEAR) || IsClearGround(cur_tile, CLEAR_FIELDS))))) {
Command<CMD_CLEAR_AREA>::Post(STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, tree_start_tile, tree_recent_tile, 1);
tree_start_tile = tree_recent_tile = 0;
tree_start_tile = tree_recent_tile = INVALID_TILE;
}
// if current tile is a tree
if (IsTileType(cur_tile, MP_TREES)) {
if (tree_start_tile == 0) {
if (tree_start_tile == INVALID_TILE) {
tree_start_tile = cur_tile;
}
tree_recent_tile = cur_tile;
@@ -176,7 +177,7 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t
prev_tile = cur_tile;
}
// one last ride to flavortown
if (tree_start_tile != 0) {
if (tree_start_tile != INVALID_TILE) {
Command<CMD_CLEAR_AREA>::Post(STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, tree_start_tile, tree_recent_tile, 1);
}
}
@@ -226,8 +227,8 @@ struct TerraformToolbarWindow : Window {
void DrawWidget(const Rect &r, int widget) const override
{
if (widget == WID_TT_DEMOLISH_TREES) {
uint offset = this->IsWidgetLowered(WID_TT_DEMOLISH_TREES) ? 1 : 0;
if (widget == CM_WID_TT_DEMOLISH_TREES) {
uint offset = this->IsWidgetLowered(CM_WID_TT_DEMOLISH_TREES) ? 1 : 0;
ZoomLevel temp_zoom;
switch (_gui_zoom) {
case ZOOM_LVL_NORMAL:
@@ -280,8 +281,8 @@ struct TerraformToolbarWindow : Window {
this->last_user_action = widget;
break;
case WID_TT_DEMOLISH_TREES: // Demolish aka dynamite button
HandlePlacePushButton(this, WID_TT_DEMOLISH_TREES, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL, CM_DDSP_DEMOLISH_TREES);
case CM_WID_TT_DEMOLISH_TREES: // Demolish aka dynamite button
HandlePlacePushButton(this, CM_WID_TT_DEMOLISH_TREES, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL, CM_DDSP_DEMOLISH_TREES);
this->last_user_action = widget;
break;
@@ -326,7 +327,7 @@ struct TerraformToolbarWindow : Window {
PlaceProc_DemolishArea(tile);
break;
case WID_TT_DEMOLISH_TREES: // Demolish trees only
case CM_WID_TT_DEMOLISH_TREES: // Demolish trees only
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_DEMOLISH_TREES);
break;
@@ -407,7 +408,7 @@ struct TerraformToolbarWindow : Window {
Hotkey('I', "trees", WID_TT_PLANT_TREES),
Hotkey('O', "placesign", WID_TT_PLACE_SIGN),
Hotkey('P', "placeobject", WID_TT_PLACE_OBJECT),
Hotkey('D' | WKC_CTRL | WKC_GLOBAL_HOTKEY, "cm_treedozer", WID_TT_DEMOLISH_TREES),
Hotkey('D' | WKC_CTRL | WKC_GLOBAL_HOTKEY, "cm_treedozer", CM_WID_TT_DEMOLISH_TREES),
}, TerraformToolbarGlobalHotkeys};
};

View File

@@ -620,10 +620,8 @@ static CallBackFunction ToolbarWatchClick(Window *w)
static CallBackFunction MenuClickWatch(int index)
{
if(Company::IsValidID((CompanyID)index)){
citymania::ShowWatchWindow((CompanyID)index, 0);
}
else citymania::ShowWatchWindow(INVALID_COMPANY, 0);
if (Company::IsValidID((CompanyID)index)) citymania::ShowWatchWindow((CompanyID)index, 0);
else citymania::ShowWatchWindow(CompanyID::Invalid(), 0);
return CBF_NONE;
}
@@ -651,9 +649,9 @@ static CallBackFunction MenuClickCompany(int index)
case CTMN_NEW_COMPANY:
if (_network_server) {
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW, INVALID_COMPANY, CRR_NONE, _network_own_client_id);
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW, CompanyID::Invalid(), CRR_NONE, _network_own_client_id);
} else {
Command<CMD_COMPANY_CTRL>::SendNet(STR_NULL, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);
Command<CMD_COMPANY_CTRL>::SendNet(STR_NULL, _local_company, CCA_NEW, CompanyID::Invalid(), CRR_NONE, INVALID_CLIENT_ID);
}
return CBF_NONE;
@@ -2176,7 +2174,7 @@ struct MainToolbarWindow : Window {
case CM_MTHK_ZONING: citymania::ShowZoningToolbar(); break;
case CM_MTHK_LOGINWINDOW: citymania::ShowLoginWindow(); break;
case CM_MTHK_SETTINGS_ADV: ShowGameSettings(); break;
case CM_MTHK_NEWGRF: ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, &_grfconfig); break;
case CM_MTHK_NEWGRF: ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, _grfconfig); break;
case CM_MTHK_SMALLMAP_TOGGLE: citymania::ToggleSmallMap(); break;
default: return citymania::HandleToolbarHotkey(hotkey);
}

View File

@@ -54,28 +54,6 @@ struct TownCache {
auto operator<=>(const TownCache &) const = default;
};
enum class TownGrowthState: uint8 {
NOT_GROWING = 0,
GROWING = 1,
SHRINKING = 2,
};
struct CBTownInfo {
uint32 pax_delivered;
uint32 mail_delivered;
uint32 pax_delivered_last_month;
uint32 mail_delivered_last_month;
TownGrowthState growth_state;
uint8 shrink_effeciency;
uint16 shrink_rate;
uint16 shrink_counter;
uint32 stored[NUM_CARGO];
uint32 delivered[NUM_CARGO];
uint32 required[NUM_CARGO];
uint32 delivered_last_month[NUM_CARGO];
uint32 required_last_month[NUM_CARGO];
};
/** Town data structure. */
struct Town : TownPool::PoolItem<&_town_pool> {
TileIndex xy = INVALID_TILE; ///< town center tile
@@ -108,16 +86,6 @@ struct Town : TownPool::PoolItem<&_town_pool> {
EncodedString text{}; ///< General text with additional information.
StringID cm_town_label; ///< Label dependent on _local_company rating.
CBTownInfo cm_cb;
CompanyMask cm_fund_regularly; ///< funds buildings regularly when previous fund ends
CompanyMask cm_do_powerfund; ///< funds buildings when grow counter is maximal (results in fastest funding possible)
uint32 cm_last_funding = 0; ///< when town was funded the last time
CompanyMask cm_advertise_regularly; ///< advertised regularly to keep stations rating on desired value
uint32 cm_last_advertisement = 0;
uint8 cm_ad_rating_goal; ///< value to keep rating at (for regular advertisement) (0..255)
const GoodsEntry *cm_ad_ref_goods_entry; ///< poiter to goods entry of some station, used to check rating for regular advertisement
inline uint8_t GetPercentTransported(CargoType cargo_type) const
{
if (!IsValidCargoType(cargo_type)) return 0;
@@ -160,27 +128,16 @@ struct Town : TownPool::PoolItem<&_town_pool> {
//FORCEINLINE StringID Label() const{
StringID Label() const{
if (!_settings_client.gui.population_in_label)
return STR_VIEWPORT_TOWN;
return STR_TOWN_NAME;
if (!(_game_mode == GM_EDITOR) && (_local_company < MAX_COMPANIES)) {
// FIXME rating colour
return CM_STR_VIEWPORT_TOWN_POP_VERY_POOR_RATING + this->town_label;
return CM_STR_VIEWPORT_TOWN_POP_VERY_POOR_RATING + this->cm.town_label;
}
else {
return STR_VIEWPORT_TOWN_POP;
}
}
/* Returns the correct town small label, based on rating. */
//FORCEINLINE StringID SmallLabel() const{
StringID SmallLabel() const{
if (!(_game_mode == GM_EDITOR) && (_local_company < MAX_COMPANIES)) {
return CM_STR_VIEWPORT_TOWN_TINY_VERY_POOR_RATING + this->town_label;
}
else {
return STR_VIEWPORT_TOWN_TINY_WHITE;
}
}
/**
* Calculate the max town noise.
* The value is counted using the population divided by the content of the
@@ -277,14 +234,13 @@ bool CB_Enabled();
void CB_SetCB(bool cb);
uint CB_GetStorage();
void CB_SetStorage(uint storage);
void CB_SetRequirements(CargoID cargo, uint req, uint from, uint decay);
void CB_SetRequirements(CargoType cargo_type, uint req, uint from, uint decay);
void CB_ResetRequirements();
uint CB_GetReq(CargoID cargo);
uint CB_GetFrom(CargoID cargo);
uint CB_GetDecay(CargoID cargo);
uint CB_GetReq(CargoType cargo_type);
uint CB_GetFrom(CargoType cargo_type);
uint CB_GetDecay(CargoType cargo_type);
int CB_GetTownReq(uint population, uint req, uint from, bool from_non_important, bool prev_month = false);
uint CB_GetMaxTownStorage(Town *town, uint cargo);
bool TownExecuteAction(const Town *town, uint action);
/** Town actions of a company. */
enum class TownAction : uint8_t {

View File

@@ -66,6 +66,7 @@
#include "citymania/cm_main.hpp"
#include "safeguards.h"
#include <optional>
bool _cb_enabled = false;
uint _cb_storage = 0;
@@ -243,11 +244,11 @@ void Town::UpdateLabel()
{
if (!(_game_mode == GM_EDITOR) && (_local_company < MAX_COMPANIES)) {
int r = this->ratings[_local_company];
if (r < RATING_VERYPOOR) this->town_label = 0; // Appalling and Very Poor, RED
else if(r < RATING_MEDIOCRE) this->town_label = 1; // Poor and Mediocre, ORANGE
else if(r < RATING_GOOD) this->town_label = 2; // Good, YELLOW
else if(r < RATING_VERYGOOD) this->town_label = 3; // Very Good, WHITE
else this->town_label = 4; // Excellent and Outstanding, GREEN
if (r < RATING_VERYPOOR) this->cm.town_label = 0; // Appalling and Very Poor, RED
else if(r < RATING_MEDIOCRE) this->cm.town_label = 1; // Poor and Mediocre, ORANGE
else if(r < RATING_GOOD) this->cm.town_label = 2; // Good, YELLOW
else if(r < RATING_VERYGOOD) this->cm.town_label = 3; // Very Good, WHITE
else this->cm.town_label = 4; // Excellent and Outstanding, GREEN
}
}
@@ -553,7 +554,7 @@ static void AdvanceSingleHouseConstruction(TileIndex tile)
ChangePopulation(Town::GetByTile(tile), hs->population);
ResetHouseAge(tile);
if (hs->building_flags & BUILDING_HAS_1_TILE)
if (hs->building_flags.Any(BUILDING_HAS_1_TILE))
citymania::Emit(citymania::event::HouseCompleted{town, tile, house_id, hs});
}
MarkTileDirtyByTile(tile);
@@ -960,8 +961,8 @@ static void ChangeTileOwner_Town(TileIndex, Owner, Owner)
static bool GrowTown(Town *t);
bool TownNeedsFunding(Town *t) {
bool fund_regularly = HasBit(t->fund_regularly, _local_company);
bool do_powerfund = HasBit(t->do_powerfund, _local_company);
bool fund_regularly = t->cm.fund_regularly.Test(_local_company);
bool do_powerfund = t->cm.do_powerfund.Test(_local_company);
if (do_powerfund && (_settings_client.gui.cm_powerfund_money > Company::Get(_local_company)->money ||
_settings_client.gui.cm_powerfund_houses < t->cache.num_houses)) {
@@ -1011,53 +1012,66 @@ static void DoRegularFunding(Town *t)
return;
/* never fund faster than every Ticks::TOWN_GROWTH_TICKS */
if (TimerGameTick::counter < t->last_funding) {
if (UINT32_MAX - t->last_funding + TimerGameTick::counter < Ticks::TOWN_GROWTH_TICKS) return;
} else if (TimerGameTick::counter - t->last_funding < Ticks::TOWN_GROWTH_TICKS) return;
if (TimerGameTick::counter < t->cm.last_funding) {
if (UINT32_MAX - t->cm.last_funding + TimerGameTick::counter < Ticks::TOWN_GROWTH_TICKS) return;
} else if (TimerGameTick::counter - t->cm.last_funding < Ticks::TOWN_GROWTH_TICKS) return;
citymania::cmd::DoTownAction(t->xy, t->index, HK_FUND)
citymania::cmd::DoTownAction(t->xy, t->index, TownAction::FundBuildings)
.no_estimate()
.as_company(_local_company)
.post();
t->last_funding = TimerGameTick::counter;
t->cm.last_funding = TimerGameTick::counter;
}
static void DoRegularAdvertising(Town *t) {
if (!HasBit(t->advertise_regularly, _local_company))
if (t->cm.advertise_regularly.Test(_local_company))
return;
if (t->ad_ref_goods_entry == nullptr) {
if (!t->cm.ad_ref_goods_entry.has_value()) {
// Pick as ref station and cargo with min rating
uint8_t rating = 0;
for (Station *st : Station::Iterate()) {
if (st->owner == _local_company && DistanceManhattan(t->xy, st->xy) <= 20) {
for (CargoID i = 0; i < NUM_CARGO; i++)
if (st->goods[i].HasRating() && (t->ad_ref_goods_entry == nullptr ||
t->ad_ref_goods_entry->rating < st->goods[i].rating)) {
t->ad_ref_goods_entry = &st->goods[i];
for (CargoType i = 0; i < NUM_CARGO; i++)
if (st->goods[i].HasRating() && (t->cm.ad_ref_goods_entry == std::nullopt ||
rating < st->goods[i].rating)) {
t->cm.ad_ref_goods_entry = {st->index, i};
rating = st->goods[i].rating;
}
}
}
if (t->ad_ref_goods_entry == nullptr)
if (!t->cm.ad_ref_goods_entry.has_value())
return;
}
if (t->ad_ref_goods_entry->rating >= t->ad_rating_goal)
auto [station_id, cargo_type] = t->cm.ad_ref_goods_entry.value();
auto st = Station::GetIfValid(station_id);
if (st == nullptr) {
t->cm.ad_ref_goods_entry = std::nullopt;
return;
}
auto rating = st->goods[cargo_type].rating;
if (rating >= t->cm.ad_rating_goal)
return;
// don't advertise faster that once per 30 ticks
if (TimerGameTick::counter < t->last_advertisement) {
if (UINT32_MAX - t->last_advertisement + TimerGameTick::counter < 30) return;
} else if (TimerGameTick::counter - t->last_advertisement < 30) return;
t->last_advertisement = TimerGameTick::counter;
if (TimerGameTick::counter < t->cm.last_advertisement) {
if (UINT32_MAX - t->cm.last_advertisement + TimerGameTick::counter < 30) return;
} else if (TimerGameTick::counter - t->cm.last_advertisement < 30) return;
t->cm.last_advertisement = TimerGameTick::counter;
auto prev_rating = t->ad_ref_goods_entry->rating;
citymania::cmd::DoTownAction(t->xy, t->index, HK_LADVERT)
citymania::cmd::DoTownAction(t->xy, t->index, TownAction::AdvertiseLarge)
.no_estimate()
.as_company(_local_company)
.with_callback([=] (bool res) -> bool {
if (res && prev_rating == t->ad_ref_goods_entry->rating) {
t->ad_ref_goods_entry = nullptr;
if (!res) return true;
if (!t->cm.ad_ref_goods_entry.has_value()) return true;
auto [station_id, cargo_type] = t->cm.ad_ref_goods_entry.value();
auto st = Station::GetIfValid(station_id);
if (st == nullptr) return true;
if (rating == st->goods[cargo_type].rating) {
t->cm.ad_ref_goods_entry = std::nullopt;
}
return true;
}).post();
@@ -2205,24 +2219,24 @@ void CB_SetStorage(uint storage){
_cb_storage = storage;
}
void CB_SetRequirements(CargoID cargo, uint req, uint from, uint decay){
CBREQ[cargo] = req;
CBFROM[cargo] = from;
CBDECAY[cargo] = decay;
void CB_SetRequirements(CargoType cargo_type, uint req, uint from, uint decay){
CBREQ[cargo_type] = req;
CBFROM[cargo_type] = from;
CBDECAY[cargo_type] = decay;
}
void CB_ResetRequirements() {
for(CargoID cargo = 0; cargo < NUM_CARGO; cargo++){
for(CargoType cargo = 0; cargo < NUM_CARGO; cargo++){
CB_SetRequirements(cargo, 0, 0, 0);
}
}
uint CB_GetReq(CargoID cargo){
return CBREQ[cargo];
uint CB_GetReq(CargoType cargo_type) {
return CBREQ[cargo_type];
}
uint CB_GetFrom(CargoID cargo){
return CBFROM[cargo];
uint CB_GetFrom(CargoType cargo_type) {
return CBFROM[cargo_type];
}
uint CB_GetDecay(CargoID cargo){
return CBDECAY[cargo];
uint CB_GetDecay(CargoType cargo_type) {
return CBDECAY[cargo_type];
}
int CB_GetTownReq(uint population, uint req, uint from, bool from_non_important, bool prev_month)
@@ -2341,19 +2355,19 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSi
t->fund_buildings_months = 0;
//CB
t->cb.growth_state = TownGrowthState::NOT_GROWING;
t->cm.cb.growth_state = citymania::TownGrowthState::NOT_GROWING;
for (uint i = 0; i < NUM_CARGO ; i++) {
t->cb.stored[i] = 0;
t->cb.delivered[i] = 0;
t->cb.required[i] = 0;
t->cb.delivered_last_month[i] = 0;
t->cb.required_last_month[i] = 0;
t->cm.cb.stored[i] = 0;
t->cm.cb.delivered[i] = 0;
t->cm.cb.required[i] = 0;
t->cm.cb.delivered_last_month[i] = 0;
t->cm.cb.required_last_month[i] = 0;
}
t->fund_regularly = 0;
t->do_powerfund = 0;
t->advertise_regularly = 0;
t->ad_rating_goal = 95;
t->ad_ref_goods_entry = NULL;
t->cm.fund_regularly = {};
t->cm.do_powerfund = {};
t->cm.advertise_regularly = {};
t->cm.ad_rating_goal = 95;
t->cm.ad_ref_goods_entry = std::nullopt;
//CB
for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
@@ -2370,7 +2384,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSi
}
t->townnameparts = townnameparts;
t->town_label = 3; // CM
t->cm.town_label = 3; // CM
t->InitializeLayout(layout);

View File

@@ -56,28 +56,12 @@
#include <list>
#include "console_func.h"
#include "citymania/cm_commands.hpp"
#include "citymania/cm_hotkeys.hpp"
#include "citymania/cm_town_gui.hpp"
/* CityMania end */
#include "safeguards.h"
struct CargoX {
int id;
int from;
};
void ShowCBTownWindow(uint town);
static void DrawExtraTownInfo (Rect &r, Town *town, uint line, bool show_house_states_info=false);
bool TownExecuteAction(const Town *town, uint action){
if(!(action == HK_STATUE && HasBit(town->statues, _current_company))){ //don't built statue when there is one
return citymania::cmd::DoTownAction(town->xy, town->index, action)
.with_error(STR_ERROR_CAN_T_DO_THIS)
.post();
}
return false;
}
TownKdtree _town_local_authority_kdtree{};
typedef GUIList<const Town*, const bool &> GUITownList;
@@ -231,7 +215,7 @@ public:
}
int rating = this->town->ratings[c->index];
DrawString(text.left, text.right, text.top + text_y_offset, GetString(CM_STR_LOCAL_AUTHORITY_COMPANY_RATING, c->index, c->index, GetRatingString(rating), this->town->ratings[c->index]));
DrawString(text.left, text.right, text.top + text_y_offset, GetString(CM_STR_LOCAL_AUTHORITY_COMPANY_RATING_NUM, c->index, c->index, GetRatingString(rating), this->town->ratings[c->index]));
text.top += this->resize.step_height;
}
}
@@ -373,7 +357,14 @@ public:
EventState OnHotkey(int hotkey) override
{
TownExecuteAction(this->town, hotkey);
switch(hotkey) {
case HK_SADVERT: citymania::TownExecuteAction(this->town, TownAction::AdvertiseSmall); break;
case HK_MADVERT: citymania::TownExecuteAction(this->town, TownAction::AdvertiseMedium); break;
case HK_LADVERT: citymania::TownExecuteAction(this->town, TownAction::AdvertiseLarge); break;
case HK_STATUE: citymania::TownExecuteAction(this->town, TownAction::BuildStatue); break;
case HK_FUND: citymania::TownExecuteAction(this->town, TownAction::FundBuildings); break;
default: NOT_REACHED();
}
return ES_HANDLED;
}
@@ -391,10 +382,10 @@ static WindowDesc _town_authority_desc(
WC_TOWN_AUTHORITY, WC_NONE,
{},
_nested_town_authority_widgets,
TownAuthorityWindow::hotkeys
&TownAuthorityWindow::hotkeys
);
static void ShowTownAuthorityWindow(uint town)
/* CM static */ void ShowTownAuthorityWindow(uint town)
{
AllocateWindowDescFront<TownAuthorityWindow>(_town_authority_desc, town);
}
@@ -471,7 +462,7 @@ public:
}
}
DrawExtraTownInfo(tr, this->town, GetCharacterHeight(FS_NORMAL), true); // CM (CB)
citymania::DrawExtraTownInfo(tr, this->town, GetCharacterHeight(FS_NORMAL), true); // CM (CB)
bool first = true;
for (int i = TAE_BEGIN; i < TAE_END; i++) {
@@ -563,7 +554,7 @@ public:
case WID_TV_CB:
// if(_networking)
ShowCBTownWindow(this->window_number);
citymania::ShowCBTownWindow((TownID)this->window_number);
break;
case WID_TV_DELETE: // delete town - only available on Scenario editor
@@ -661,9 +652,9 @@ public:
EventState OnHotkey(int hotkey) override
{
if(hotkey == WID_TV_CB) ShowCBTownWindow(this->window_number);
else if (hotkey == HK_STATUE + 0x80){
TownExecuteAction(this->town, HK_STATUE);
if(hotkey == WID_TV_CB) citymania::ShowCBTownWindow(this->window_number);
else if (hotkey == HK_STATUE + 0x80) { // TODO fix to proper hotkey
citymania::TownExecuteAction(this->town, TownAction::BuildStatue);
return ES_NOT_HANDLED;
}
return Window::OnHotkey(hotkey);
@@ -678,7 +669,7 @@ public:
Hotkey((uint16)0, "location", WID_TV_CENTER_VIEW),
Hotkey((uint16)0, "local_authority", WID_TV_SHOW_AUTHORITY),
Hotkey((uint16)0, "cb_window", WID_TV_CB),
Hotkey(WKC_CTRL | 'S', "build_statue", HK_STATUE + 0x80),
Hotkey(WKC_CTRL | 'S', "build_statue", HK_STATUE + 0x80), // TODO make a proper hotkey
}};
};
@@ -909,28 +900,23 @@ public:
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
{
switch (widget) {
case WID_TD_CAPTION:
return GetString(STR_TOWN_DIRECTORY_CAPTION, this->vscroll->GetCount(), Town::GetNumItems());
case WID_TD_WORLD_POPULATION:
return GetString(STR_TOWN_POPULATION, GetWorldPopulation());
case WID_TD_SORT_CRITERIA:
return GetString(TownDirectoryWindow::sorter_names[this->towns.SortType()]);
case TDW_CAPTION_TEXT: {
FIXME
case WID_TD_CAPTION: {
// return GetString(STR_TOWN_DIRECTORY_CAPTION, this->vscroll->GetCount(), Town::GetNumItems());
uint16 town_number = 0;
uint16 city_number = 0;
for (Town *t : Town::Iterate()) {
if(t->larger_town) city_number++;
town_number++;
}
SetDParam(0, city_number);
SetDParam(1, town_number);
break;
return GetString(CM_STR_TOWN_DIRECTORY_CAPTION_EXTRA, city_number, town_number);
}
case WID_TD_WORLD_POPULATION:
return GetString(STR_TOWN_POPULATION, GetWorldPopulation());
case WID_TD_SORT_CRITERIA:
return GetString(TownDirectoryWindow::sorter_names[this->towns.SortType()]);
default:
return this->Window::GetWidgetString(widget, stringid);
}
@@ -941,9 +927,15 @@ public:
* @param t Town to draw.
* @return The string to use.
*/
static std::string GetTownString(const Town *t, uint64_t population)
static std::string GetTownString(const Town *t, uint64_t population, uint64_t cm_real_population, uint64_t cm_num_houses)
{
return GetString(t->larger_town ? STR_TOWN_DIRECTORY_CITY : STR_TOWN_DIRECTORY_TOWN, t->index, population);
return GetString(
t->larger_town ? CM_STR_TOWN_DIRECTORY_CITY_COLOUR : CM_STR_TOWN_DIRECTORY_TOWN_COLOUR,
t->index,
population,
cm_real_population,
cm_num_houses
);
}
void DrawWidget(const Rect &r, WidgetID widget) const override
@@ -980,9 +972,7 @@ public:
if (t->ratings[_local_company] > RATING_GOOD) icon = SPR_TOWN_RATING_GOOD;
DrawSprite(icon, PAL_NONE, icon_x, tr.top + (this->resize.step_height - icon_size.height) / 2);
}
FIXME different colours
DrawString(tr.left, tr.right, tr.top + (this->resize.step_height - GetCharacterHeight(FS_NORMAL)) / 2, t->larger_town ? CM_STR_TOWN_DIRECTORY_CITY_COLOUR : CM_STR_TOWN_DIRECTORY_TOWN_COLOUR);
DrawString(tr.left, tr.right, tr.top + (this->resize.step_height - GetCharacterHeight(FS_NORMAL)) / 2, GetTownString(t, t->cache.population));
DrawString(tr.left, tr.right, tr.top + (this->resize.step_height - GetCharacterHeight(FS_NORMAL)) / 2, GetTownString(t, t->cache.population, t->cm.real_population, t->cache.num_houses));
tr.top += this->resize.step_height;
}
@@ -1010,14 +1000,14 @@ public:
}
case WID_TD_LIST: {
Dimension d = GetStringBoundingBox(STR_TOWN_DIRECTORY_NONE);
uint64_t max_value = GetParamMaxDigits(8);
uint64_t max_pop_value = GetParamMaxDigits(8);
uint64_t max_houses_value = GetParamMaxDigits(5);
for (uint i = 0; i < this->towns.size(); i++) {
const Town *t = this->towns[i];
assert(t != nullptr);
FIXME (CM_STR_TOWN_DIRECTORY_TOWN_COLOUR)
d = maxdim(d, GetStringBoundingBox(GetTownString(t, max_value, GetParamMaxDigits(5))));
d = maxdim(d, GetStringBoundingBox(GetTownString(t, max_pop_value, max_pop_value, max_houses_value)));
}
Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD);
d.width += icon_size.width + 2;
@@ -1970,454 +1960,3 @@ void ShowBuildHousePicker(Window *parent)
if (BringWindowToFrontById(WC_BUILD_HOUSE, 0)) return;
new BuildHouseWindow(_build_house_desc, parent);
}
//CB
static void DrawExtraTownInfo (Rect &r, Town *town, uint line, bool show_house_states_info) {
//real pop and rating
SetDParam(0, town->cm.real_population);
SetDParam(1, town->ratings[_current_company]);
DrawString(r, CM_STR_TOWN_VIEW_REALPOP_RATE);
r.top += line;
//town stats
// int grow_rate = 0;
// if(town->growth_rate == TOWN_GROW_RATE_CUSTOM_NONE) grow_rate = 0;
// else grow_rate = TownTicksToDays((town->growth_rate & ~TOWN_GROW_RATE_CUSTOM) + 1);
SetDParam(0, town->growth_rate);
SetDParam(1, HasBit(town->flags, TOWN_CUSTOM_GROWTH) ? CM_STR_TOWN_VIEW_GROWTH_RATE_CUSTOM : STR_EMPTY);
// SetDParam(2, town->grow_counter < 16000 ? TownTicksToDays(town->grow_counter + 1) : -1);
SetDParam(2, town->grow_counter);
SetDParam(3, town->time_until_rebuild);
SetDParam(4, HasBit(town->flags, TOWN_IS_GROWING) ? 1 : 0);
SetDParam(5, town->fund_buildings_months);
DrawString(r, CM_STR_TOWN_VIEW_GROWTH);
r.top += line;
if (show_house_states_info) {
SetDParam(0, town->cm.houses_constructing);
SetDParam(1, town->cm.houses_reconstructed_last_month);
SetDParam(2, town->cm.houses_demolished_last_month);
DrawString(r, CM_STR_TOWN_VIEW_HOUSE_STATE);
r.top += line;
}
///houses stats
SetDParam(0, town->cm.hs_total);
SetDParam(1, town->cm.hs_last_month);
SetDParam(2, town->cm.cs_total);
SetDParam(3, town->cm.cs_last_month);
SetDParam(4, town->cm.hr_total);
SetDParam(5, town->cm.hr_last_month);
DrawString(r, CM_STR_TOWN_VIEW_GROWTH_TILES);
r.top += line;
}
bool CB_sortCargoesByFrom(CargoX first, CargoX second){
return (first.from < second.from) ? true : false;
}
struct CBTownWindow : Window {
private:
Town *town;
std::list<CargoX> cargoes;
enum CBTownWindowPlanes {
CBTWP_MP_GOALS = 0,
CBTWP_MP_CB,
};
public:
CBTownWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
{
for (uint i = 0; i < NUM_CARGO ; i++) {
CargoX c;
c.id = i;
c.from = CB_GetFrom(i);
this->cargoes.push_back(c);
}
cargoes.sort(CB_sortCargoesByFrom);
this->town = Town::Get(window_number);
this->InitNested(window_number);
if(HasBit(this->town->fund_regularly, _local_company)) this->LowerWidget(WID_CB_FUND_REGULAR);
if(HasBit(this->town->do_powerfund, _local_company)) this->LowerWidget(WID_CB_POWERFUND);
if(HasBit(this->town->advertise_regularly, _local_company)) this->LowerWidget(WID_CB_ADVERT_REGULAR);
}
void OnClick([[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count) override
{
switch (widget) {
case WID_CB_CENTER_VIEW:
if (citymania::_fn_mod) {
ShowExtraViewportWindow(this->town->xy);
} else {
ScrollMainWindowToTile(this->town->xy);
}
break;
case WID_CB_ADVERT:
TownExecuteAction(this->town, HK_LADVERT);
break;
case WID_CB_FUND:
TownExecuteAction(this->town, HK_FUND);
break;
case WID_CB_FUND_REGULAR:
ToggleBit(this->town->fund_regularly, _local_company);
this->SetWidgetLoweredState(widget, HasBit(this->town->fund_regularly, _local_company));
this->SetWidgetDirty(widget);
break;
case WID_CB_POWERFUND:
ToggleBit(this->town->do_powerfund, _local_company);
this->SetWidgetLoweredState(widget, HasBit(this->town->do_powerfund, _local_company));
this->SetWidgetDirty(widget);
break;
case WID_CB_ADVERT_REGULAR:
if (!this->town->advertise_regularly) {
SetDParam(0, ToPercent8(this->town->ad_rating_goal));
ShowQueryString(STR_JUST_INT, CM_STR_CB_ADVERT_REGULAR_RATING_TO_KEEP,
4, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
} else this->OnQueryTextFinished(std::nullopt);
break;
case WID_CB_TOWN_VIEW: // Town view window
ShowTownViewWindow(this->window_number);
break;
case WID_CB_SHOW_AUTHORITY: // town authority
ShowTownAuthorityWindow(this->window_number);
break;
}
}
void OnQueryTextFinished(std::optional<std::string> str) override
{
if (!str.has_value()) SetBit(this->town->advertise_regularly, _local_company);
else ClrBit(this->town->advertise_regularly, _local_company);
this->town->ad_ref_goods_entry = NULL;
this->SetWidgetLoweredState(WID_CB_ADVERT_REGULAR, HasBit(this->town->advertise_regularly, _local_company));
this->SetWidgetDirty(WID_CB_ADVERT_REGULAR);
if (!str.has_value()) return;
uint val = Clamp(str->empty()? 0 : strtol(str->c_str(), NULL, 10), 1, 100);
this->town->ad_rating_goal = ((val << 8) + 255) / 101;
}
void SetStringParameters(int widget) const override
{
if (widget == WID_CB_CAPTION){
SetDParam(0, this->town->index);
}
}
const Company *GetCompany() const {
for (Company *c : Company::Iterate()) {
if (c->location_of_HQ != INVALID_TILE
&& DistanceMax(c->location_of_HQ, this->town->xy) < 11)
return c;
}
return nullptr;
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override {
static const uint EXP_TOPPADDING = 5;
static const uint EXP_LINESPACE = 2; // Amount of vertical space for a horizontal (sub-)total line.
switch(widget){
case WID_CB_DETAILS:
size.height = (GetCharacterHeight(FS_NORMAL) + EXP_LINESPACE) * 5;
break;
case WID_CB_GOALS: {
uint desired_height = 0;
auto company = GetCompany();
if (company) {
for(const Goal *g : Goal::Iterate()) {
if (g->company == company->index) {
desired_height++;
}
}
}
if (desired_height > 0)
size.height = desired_height * (GetCharacterHeight(FS_NORMAL) + EXP_LINESPACE) + EXP_TOPPADDING - EXP_LINESPACE;
break;
}
case WID_CB_CARGO_NAME:
case WID_CB_CARGO_AMOUNT:
case WID_CB_CARGO_REQ:
case WID_CB_CARGO_STORE:
case WID_CB_CARGO_STORE_PCT:
case WID_CB_CARGO_FROM:
case WID_CB_CARGO_PREVIOUS: {
uint desired_height = 0;
for(CargoID cargo = 0; cargo < NUM_CARGO; cargo++){
if(CB_GetReq(cargo) > 0) desired_height++;
}
if (desired_height > 0)
size.height = desired_height * (GetCharacterHeight(FS_NORMAL) + EXP_LINESPACE) + EXP_TOPPADDING - EXP_LINESPACE;
break;
}
}
}
void DrawWidget(const Rect &r, int widget) const override
{
static const uint EXP_LINESPACE = GetCharacterHeight(FS_NORMAL) + 2;
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
switch(widget){
case WID_CB_DETAILS:{
// growing
if(this->town->cb.growth_state == TownGrowthState::GROWING)
DrawString(tr, CM_STR_TOWN_CB_GROWING);
else DrawString(tr, CM_STR_TOWN_CB_NOT_GROWING);
tr.top += GetCharacterHeight(FS_NORMAL);
// population
SetDParam(0, this->town->cache.population);
SetDParam(1, this->town->cache.num_houses);
DrawString(tr, STR_TOWN_VIEW_POPULATION_HOUSES);
tr.top += GetCharacterHeight(FS_NORMAL);
DrawExtraTownInfo(tr, this->town, EXP_LINESPACE, false);
// regular funding
if(this->town->fund_regularly != 0){
DrawString(tr, CM_STR_CB_FUNDED_REGULARLY);
tr.top += EXP_LINESPACE;
}
break;
}
case WID_CB_GOALS: {
auto company = GetCompany();
if (!company) break;
for(const Goal *g : Goal::Iterate()) {
if (g->company != company->index)
continue;
SetDParamStr(0, g->text);
DrawString(tr, STR_GOALS_TEXT);
tr.top += EXP_LINESPACE;
}
break;
}
/* Citybuilder things*/
case WID_CB_CARGO_NAME:
case WID_CB_CARGO_AMOUNT:
case WID_CB_CARGO_REQ:
case WID_CB_CARGO_STORE:
case WID_CB_CARGO_STORE_PCT:
case WID_CB_CARGO_FROM:
case WID_CB_CARGO_PREVIOUS: {
if (this->town->larger_town) break;
uint delivered;
uint requirements;
uint from;
StringID string_to_draw;
//for cycle
std::list<CargoX> cargoes2 = this->cargoes;
std::list<CargoX>::iterator it2;
for (it2 = cargoes2.begin(); it2 != cargoes2.end(); ++it2) {
CargoX cargox;
cargox = *it2;
if (it2 == cargoes2.begin()) { // header
// FIXME rtl support
DrawString(tr.Shrink(ScaleGUITrad(14), 0, 0, 0),
(CM_STR_TOWN_GROWTH_HEADER_CARGO + widget - WID_CB_CARGO_NAME), TC_FROMSTRING,
(widget == WID_CB_CARGO_NAME) ? SA_LEFT : SA_RIGHT);
tr.top += EXP_LINESPACE;
}
const CargoSpec *cargos = CargoSpec::Get(cargox.id);
//cargo needed?
if (!cargos->IsValid() || CB_GetReq(cargos->Index()) == 0) continue;
from = CB_GetFrom(cargos->Index());
switch(widget) {
case WID_CB_CARGO_NAME: {
// FIXME scaling
GfxFillRect(tr.left, tr.top + 1, tr.left + 8, tr.top + 6, 0);
GfxFillRect(tr.left + 1, tr.top + 2, tr.left + 7, tr.top + 5, cargos->legend_colour);
SetDParam(0, cargos->name);
DrawString(tr.Shrink(ScaleGUITrad(14), 0, 0, 0), CM_STR_TOWN_CB_CARGO_NAME);
break;
}
case WID_CB_CARGO_AMOUNT: {
delivered = this->town->cb.delivered[cargos->Index()];
requirements = CB_GetTownReq(this->town->cache.population, CB_GetReq(cargos->Index()), from, true);
SetDParam(0, delivered);
//when required
if (this->town->cache.population >= from) {
if((delivered + (uint)this->town->cb.stored[cargos->Index()]) >= requirements) string_to_draw = CM_STR_TOWN_CB_CARGO_AMOUNT_GOOD;
else string_to_draw = CM_STR_TOWN_CB_CARGO_AMOUNT_BAD;
}
//when not required -> all faded
else string_to_draw = CM_STR_TOWN_CB_CARGO_AMOUNT_NOT;
DrawString(tr, string_to_draw, TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CB_CARGO_REQ: {
requirements = CB_GetTownReq(this->town->cache.population, CB_GetReq(cargos->Index()), from, true);
SetDParam(0, requirements);
//when required
string_to_draw = (this->town->cache.population >= from) ? CM_STR_TOWN_CB_CARGO_REQ_YES : CM_STR_TOWN_CB_CARGO_REQ_NOT;
DrawString(tr, string_to_draw, TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CB_CARGO_PREVIOUS: {
requirements = CB_GetTownReq(this->town->cache.population, CB_GetReq(cargos->Index()), from, true);
SetDParam(0, this->town->cb.delivered_last_month[cargos->Index()]);
if (this->town->cache.population >= from){
// if (this->town->delivered_enough[cargos->Index()]) {
string_to_draw = (this->town->cb.delivered_last_month[cargos->Index()] >= requirements) ? CM_STR_TOWN_CB_CARGO_PREVIOUS_YES : CM_STR_TOWN_CB_CARGO_PREVIOUS_EDGE;
// }
// else string_to_draw = STR_TOWN_CB_CARGO_PREVIOUS_BAD;
}
else string_to_draw = CM_STR_TOWN_CB_CARGO_PREVIOUS_NOT;
DrawString(tr, string_to_draw, TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CB_CARGO_STORE: {
SetDParam(0, this->town->cb.stored[cargos->Index()]);
if (CB_GetDecay(cargos->Index()) == 100) string_to_draw = CM_STR_TOWN_CB_CARGO_STORE_DECAY; //when 100% decay
else {
if (this->town->cache.population >= from) string_to_draw = CM_STR_TOWN_CB_CARGO_STORE_YES; //when required
else string_to_draw = CM_STR_TOWN_CB_CARGO_STORE_NOT;
}
DrawString(tr, string_to_draw, TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CB_CARGO_STORE_PCT: {
uint max_storage = CB_GetMaxTownStorage(this->town, cargos->Index());
if (CB_GetDecay(cargos->Index()) == 100 || !max_storage) string_to_draw = CM_STR_TOWN_CB_CARGO_STORE_DECAY; //when 100% decay
else {
SetDParam(0, 100 * this->town->cb.stored[cargos->Index()] / max_storage);
if (this->town->cache.population >= from) string_to_draw = CM_STR_TOWN_CB_CARGO_STORE_PCT_YES; //when required
else string_to_draw = CM_STR_TOWN_CB_CARGO_STORE_PCT_NOT;
}
DrawString(tr, string_to_draw, TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CB_CARGO_FROM: {
SetDParam(0, from);
string_to_draw = (this->town->cache.population >= from) ? CM_STR_TOWN_CB_CARGO_FROM_YES : CM_STR_TOWN_CB_CARGO_FROM_NOT; //when required
DrawString(tr, string_to_draw, TC_FROMSTRING, SA_RIGHT);
break;
}
//last case
}
//switch
tr.top += EXP_LINESPACE;
//cargo needed?
}
//for cycle
}
break;
}
/* Citybuilder things enabled*/
}
void OnPaint() override {
if (!this->IsShaded()) {
int plane = CB_Enabled() ? CBTWP_MP_CB : CBTWP_MP_GOALS;
NWidgetStacked *wi = this->GetWidget<NWidgetStacked>(WID_CB_SELECT_REQUIREMENTS);
if (plane != wi->shown_plane) {
wi->SetDisplayedPlane(plane);
this->InvalidateData();
return;
}
}
this->DrawWidgets();
}
EventState OnHotkey(int hotkey) override
{
TownExecuteAction(this->town, hotkey);
return ES_HANDLED;
}
static inline HotkeyList hotkeys{"cm_town_cb_view", {
Hotkey((uint16)0, "location", WID_TV_CENTER_VIEW),
Hotkey((uint16)0, "local_authority", WID_TV_SHOW_AUTHORITY),
Hotkey((uint16)0, "cb_window", WID_TV_CB),
Hotkey(WKC_CTRL | 'S', "build_statue", HK_STATUE + 0x80),
}};
};
static const NWidgetPart _nested_cb_town_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN, WID_CB_CAPTION), SetDataTip(CM_STR_TOWN_VIEW_CB_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_CB_CENTER_VIEW), SetMinimalSize(12, 14), SetDataTip(SPR_GOTO_LOCATION, STR_TOWN_VIEW_CENTER_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_BROWN),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetMinimalSize(0, 5), SetResize(1, 0), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_DETAILS), SetMinimalSize(66, 0), SetResize(1, 0), SetFill(1, 0),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_ADVERT),SetMinimalSize(33, 12),SetFill(1, 0), SetDataTip(CM_STR_CB_LARGE_ADVERTISING_CAMPAIGN, 0),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_FUND),SetMinimalSize(33, 12),SetFill(1, 0), SetDataTip(CM_STR_CB_NEW_BUILDINGS, 0),
NWidget(NWID_SPACER), SetMinimalSize(4, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_CB_ADVERT_REGULAR),SetMinimalSize(33, 12),SetFill(1, 0), SetDataTip(CM_STR_CB_ADVERT_REGULAR, CM_STR_CB_ADVERT_REGULAR_TT),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_CB_FUND_REGULAR),SetMinimalSize(33, 12),SetFill(1, 0), SetDataTip(CM_STR_CB_FUND_REGULAR, CM_STR_CB_FUND_REGULAR_TT),
NWidget(NWID_SPACER), SetMinimalSize(4, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_SPACER), SetMinimalSize(33, 0), SetFill(1, 0),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_CB_POWERFUND),SetMinimalSize(33, 12),SetFill(1, 0), SetDataTip(CM_STR_CB_POWERFUND, CM_STR_CB_POWERFUND_TT),
NWidget(NWID_SPACER), SetMinimalSize(4, 0),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 5), SetResize(1, 0), SetFill(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_CB_SELECT_REQUIREMENTS),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_GOALS),SetMinimalSize(50 + 35 + 35 + 40 + 35 + 30, 0), SetResize(1, 0), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_NAME),SetMinimalSize(50, 0), SetResize(0, 0), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_AMOUNT),SetMinimalSize(35, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_REQ),SetMinimalSize(35, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_PREVIOUS),SetMinimalSize(40, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_STORE),SetMinimalSize(35, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_STORE_PCT),SetMinimalSize(30, 0), SetResize(1, 0), SetFill(0, 0),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 0), SetResize(1, 0), SetFill(1, 1),
EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_TOWN_VIEW), SetMinimalSize(40, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(CM_STR_CB_GUI_TOWN_VIEW_BUTTON, CM_STR_CB_GUI_TOWN_VIEW_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_SHOW_AUTHORITY), SetMinimalSize(40, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON, STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP),
EndContainer(),
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
EndContainer(),
};
static WindowDesc _cb_town_desc(
WDP_AUTO, "cm_town_cb", 160, 30,
CM_WC_CB_TOWN, WC_NONE,
0,
_nested_cb_town_widgets,
&CBTownWindow::hotkeys
);
void ShowCBTownWindow(uint town) {
AllocateWindowDescFront<CBTownWindow>(_cb_town_desc, town);
}

View File

@@ -229,11 +229,11 @@ static void TrainDetailsInfoTab(const Vehicle *v, int left, int right, int y)
{
std::string str;
if (RailVehInfo(v->engine_type)->railveh_type == RAILVEH_WAGON) {
str = GetString(STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->value);
FIXME if (_settings_client.gui.newgrf_developer_tools) SetDParam(2, v->index); // CM
if (_settings_client.gui.developer < 1) str = GetString(STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->value);
else str = GetString(CM_STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE_WITH_ID, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->value, v->index);
} else {
FIXME if (_settings_client.gui.newgrf_developer_tools) SetDParam(3, v->index); // CM
str = GetString(STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->build_year, v->value);
if (_settings_client.gui.developer < 1) str = GetString(STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->build_year, v->value);
else str = GetString(CM_STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE_WITH_ID, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->build_year, v->value, v->index);
}
DrawString(left, right, y, str);
}

View File

@@ -61,7 +61,7 @@ void VideoDriver_Null::MainLoop()
::InputLoop();
::UpdateWindows();
if (old_tick != TimerGameTick::counter) i++;
else _pause_mode = PM_UNPAUSED;
else _pause_mode = {};
}
IConsolePrint(CC_DEFAULT, "Null driver ran for {} tics, save: {}", this->ticks, this->savefile);
if (!this->savefile.empty()) {

View File

@@ -106,6 +106,7 @@
#include "core/math_func.hpp"
#include "citymania/cm_highlight.hpp"
#include "citymania/cm_hotkeys.hpp"
#include "citymania/cm_town_gui.hpp"
#include "citymania/cm_zoning.hpp"
/* CityMania code end */
@@ -248,8 +249,7 @@ static Point MapXYZToViewport(const Viewport &vp, int x, int y, int z)
}
void DeleteWindowViewport(Window *w)
{
delete w->viewport;
{
w->viewport = nullptr;
}
@@ -283,7 +283,7 @@ void InitializeWindowViewport(Window *w, int x, int y,
vp->virtual_width = ScaleByZoom(width, vp->zoom);
vp->virtual_height = ScaleByZoom(height, vp->zoom);
UpdateViewportSizeZoom(vp);
UpdateViewportSizeZoom(*vp);
Point pt;
@@ -394,12 +394,12 @@ static void DoSetViewportPosition(Window::IteratorToFront it, int left, int top,
}
}
inline void UpdateViewportDirtyBlockLeftMargin(Viewport *vp)
inline void UpdateViewportDirtyBlockLeftMargin(Viewport &vp)
{
// if (vp->zoom >= ZOOM_LVL_DRAW_MAP) {
// vp->dirty_block_left_margin = 0;
// } else {
vp->dirty_block_left_margin = UnScaleByZoomLower((-vp->virtual_left) & 127, vp->zoom);
vp.dirty_block_left_margin = UnScaleByZoomLower((-vp.virtual_left) & 127, vp.zoom);
// }
}
@@ -1926,10 +1926,10 @@ void ViewportDoDraw(const Viewport &vp, int left, int top, int right, int bottom
void ViewportDrawChk(const Viewport &vp, int left, int top, int right, int bottom) {
ViewportDoDraw(vp,
ScaleByZoom(left - vp->left, vp->zoom) + vp->virtual_left,
ScaleByZoom(top - vp->top, vp->zoom) + vp->virtual_top,
ScaleByZoom(right - vp->left, vp->zoom) + vp->virtual_left,
ScaleByZoom(bottom - vp->top, vp->zoom) + vp->virtual_top
ScaleByZoom(left - vp.left, vp.zoom) + vp.virtual_left,
ScaleByZoom(top - vp.top, vp.zoom) + vp.virtual_top,
ScaleByZoom(right - vp.left, vp.zoom) + vp.virtual_left,
ScaleByZoom(bottom - vp.top, vp.zoom) + vp.virtual_top
);
}
@@ -1947,7 +1947,7 @@ static inline void ViewportDraw(Viewport &vp, int left, int top, int right, int
if (top < vp.top) top = vp.top;
if (bottom > vp.top + vp.height) bottom = vp.top + vp.height;
vp->is_drawn = true;
vp.is_drawn = true;
ViewportDoDraw(vp,
ScaleByZoom(left - vp.left, vp.zoom) + vp.virtual_left,
@@ -2102,12 +2102,12 @@ void UpdateViewportPosition(Window *w, uint32_t delta_ms)
}
}
void UpdateViewportSizeZoom(Viewport *vp)
void UpdateViewportSizeZoom(Viewport &vp)
{
vp->dirty_blocks_per_column = CeilDiv(vp->height, vp->GetDirtyBlockHeight());
vp->dirty_blocks_per_row = CeilDiv(vp->width, vp->GetDirtyBlockWidth());
uint size = vp->dirty_blocks_per_row * vp->dirty_blocks_per_column;
vp->dirty_blocks.assign(size, false);
vp.dirty_blocks_per_column = CeilDiv(vp.height, vp.GetDirtyBlockHeight());
vp.dirty_blocks_per_row = CeilDiv(vp.width, vp.GetDirtyBlockWidth());
uint size = vp.dirty_blocks_per_row * vp.dirty_blocks_per_column;
vp.dirty_blocks.assign(size, false);
UpdateViewportDirtyBlockLeftMargin(vp);
// if (vp->zoom >= ZOOM_LVL_DRAW_MAP) {
@@ -2158,29 +2158,29 @@ static bool MarkViewportDirty(Viewport &vp, int left, int top, int right, int bo
if (top >= vp.virtual_height) return false;
int x = std::max<int>(0, UnScaleByZoomLower(left, vp->zoom) - vp->dirty_block_left_margin) >> vp->GetDirtyBlockWidthShift();
int y = UnScaleByZoomLower(top, vp->zoom) >> vp->GetDirtyBlockHeightShift();
int w = (std::max<int>(0, UnScaleByZoomLower(right, vp->zoom) - 1 - vp->dirty_block_left_margin) >> vp->GetDirtyBlockWidthShift()) + 1 - x;
int h = ((UnScaleByZoom(bottom, vp->zoom) - 1) >> vp->GetDirtyBlockHeightShift()) + 1 - y;
int x = std::max<int>(0, UnScaleByZoomLower(left, vp.zoom) - vp.dirty_block_left_margin) >> vp.GetDirtyBlockWidthShift();
int y = UnScaleByZoomLower(top, vp.zoom) >> vp.GetDirtyBlockHeightShift();
int w = (std::max<int>(0, UnScaleByZoomLower(right, vp.zoom) - 1 - vp.dirty_block_left_margin) >> vp.GetDirtyBlockWidthShift()) + 1 - x;
int h = ((UnScaleByZoom(bottom, vp.zoom) - 1) >> vp.GetDirtyBlockHeightShift()) + 1 - y;
// TODO somehow JGRPP avoids these checks
if (w < 0 || h < 0) return false;
if (x >= (int)vp->dirty_blocks_per_row) return false;
if (y >= (int)vp->dirty_blocks_per_column) return false;
h -= std::max((int)y + (int)h - (int)vp->dirty_blocks_per_column, 0);
w -= std::max((int)x + (int)w - (int)vp->dirty_blocks_per_row, 0);
if (x >= (int)vp.dirty_blocks_per_row) return false;
if (y >= (int)vp.dirty_blocks_per_column) return false;
h -= std::max((int)y + (int)h - (int)vp.dirty_blocks_per_column, 0);
w -= std::max((int)x + (int)w - (int)vp.dirty_blocks_per_row, 0);
uint column_skip = vp->dirty_blocks_per_column - h;
uint pos = (x * vp->dirty_blocks_per_column) + y;
uint column_skip = vp.dirty_blocks_per_column - h;
uint pos = (x * vp.dirty_blocks_per_column) + y;
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
vp->dirty_blocks[pos] = true;
vp.dirty_blocks[pos] = true;
pos++;
}
pos += column_skip;
}
vp->is_dirty = true;
vp.is_dirty = true;
/*if (unlikely(vp->zoom >= ZOOM_LVL_DRAW_MAP && !(flags & VMDF_NOT_LANDSCAPE))) {
uint l = UnScaleByZoomLower(left, vp->zoom);
@@ -2212,7 +2212,7 @@ bool MarkAllViewportsDirty(int left, int top, int right, int bottom)
bool dirty = false;
for (Window *w : Window::Iterate()) {
Viewport *vp = w->viewport;
auto &vp = w->viewport;
if (vp != nullptr) {
assert(vp->width != 0);
if (MarkViewportDirty(*vp, left, top, right, bottom)) dirty = true;
@@ -2467,7 +2467,7 @@ static bool CheckClickOnViewportSign(const Viewport &vp, int x, int y)
}
return true;
} else if (last_t != nullptr) {
if (citymania::_fn_mod) TownExecuteAction(last_t, 4); //CM build statue
if (citymania::_fn_mod) citymania::TownExecuteAction(last_t, TownAction::BuildStatue); // CM
else ShowTownViewWindow(last_t->index);
return true;
} else if (last_si != nullptr) {
@@ -2803,8 +2803,8 @@ static inline void CalcNewPolylineOutersize()
int outer_y1 = _thd.selstart2.y & ~TILE_UNIT_MASK;
int outer_x2 = _thd.selend2.x & ~TILE_UNIT_MASK;
int outer_y2 = _thd.selend2.y & ~TILE_UNIT_MASK;
if (outer_x1 > outer_x2) Swap(outer_x1, outer_x2);
if (outer_y1 > outer_y2) Swap(outer_y1, outer_y2);
if (outer_x1 > outer_x2) std::swap(outer_x1, outer_x2);
if (outer_y1 > outer_y2) std::swap(outer_y1, outer_y2);
/* include the first part */
outer_x1 = std::min<int>(outer_x1, _thd.new_pos.x);
outer_y1 = std::min<int>(outer_y1, _thd.new_pos.y);
@@ -2899,8 +2899,8 @@ void UpdateTileSelection()
y1 = _thd.selstart.y & ~TILE_UNIT_MASK;
int x2 = _thd.selend.x & ~TILE_UNIT_MASK;
int y2 = _thd.selend.y & ~TILE_UNIT_MASK;
if (x1 > x2) Swap(x1, x2);
if (y1 > y2) Swap(y1, y2);
if (x1 > x2) std::swap(x1, x2);
if (y1 > y2) std::swap(y1, y2);
_thd.new_pos.x = x1;
_thd.new_pos.y = y1;
_thd.new_size.x = x2 - x1 + TILE_SIZE;
@@ -2982,7 +2982,7 @@ void UpdateTileSelection()
* Displays the measurement tooltips when selecting multiple tiles
* @param text String to be displayed
*/
static inline void ShowMeasurementTooltips(EncodedString &&text, TooltipCloseCondition close_cond = TCC_EXIT_VIEWPOR)
static inline void ShowMeasurementTooltips(EncodedString &&text, TooltipCloseCondition close_cond = TCC_EXIT_VIEWPORT)
{
if (!_settings_client.gui.measure_tooltip) return;
GuiShowTooltips(_thd.GetCallbackWnd(), std::move(text), close_cond);
@@ -3251,11 +3251,9 @@ static int CalcHeightdiff(HighLightStyle style, uint distance, TileIndex start_t
*/
static void ShowLengthMeasurement(HighLightStyle style, TileIndex start_tile, TileIndex end_tile, TooltipCloseCondition close_cond = TCC_NONE, bool show_single_tile_length = false)
{
static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
EncodedString str;
if (_settings_client.gui.measure_tooltip) {
uint distance = DistanceManhattan(start_tile, end_tile) + 1;
uint8_t index = 0;
if (show_single_tile_length || distance != 1) {
int heightdiff = CalcHeightdiff(style, distance, start_tile, end_tile);
@@ -3266,11 +3264,10 @@ static void ShowLengthMeasurement(HighLightStyle style, TileIndex start_tile, Ti
distance = CeilDiv(distance, 2);
}
SetDParam(index++, distance);
if (heightdiff != 0) SetDParam(index++, heightdiff);
if (heightdiff != 0) str = GetEncodedString(STR_MEASURE_LENGTH_HEIGHTDIFF, distance, heightdiff);
else str = GetEncodedString(STR_MEASURE_LENGTH, distance);
}
ShowMeasurementTooltips(measure_strings_length[index], index, close_cond);
if (!str.empty()) ShowMeasurementTooltips(std::move(str), close_cond);
}
}
@@ -3713,7 +3710,7 @@ static void CalcRaildirsDrawstyle(int x, int y, int method)
/* CityMania code start */
_thd.dir2 = HT_DIR_END;
ShowLengthMeasurement(b, TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y));
ShowLengthMeasurement(b, TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y));
/* CityMania code end */
}
@@ -3896,7 +3893,7 @@ calc_heightdiff_single_direction:;
}
}
}
#endif
#endif
/* With current code passing a HT_LINE style to calculate the height
* difference is enough. However if/when a point-tool is created
* with this method, function should be called with new_style (below)
@@ -3914,12 +3911,6 @@ calc_heightdiff_single_direction:;
case VPM_X_AND_Y: // drag an X by Y area
FIXME why this if?
if (_settings_client.gui.measure_tooltip || _thd.select_proc == CM_DDSP_MEASURE) {
static const StringID measure_strings_area[] = {
STR_NULL, STR_NULL, STR_MEASURE_AREA, STR_MEASURE_AREA_HEIGHTDIFF,
CM_STR_MEASURE_DIST_HEIGHTDIFF,
};
if (_settings_client.gui.measure_tooltip) {
TileIndex t0 = TileVirtXY(sx, sy);
@@ -3973,14 +3964,6 @@ calc_heightdiff_single_direction:;
dx -= (style & HT_POINT ? 1 : 0);
dy -= (style & HT_POINT ? 1 : 0);
FIXME
? if (_thd.select_proc == CM_DDSP_MEASURE) {
? SetDParam(index++, sqrtl(dx * dx + dy * dy));
? }
?
? if (heightdiff != 0 || index == 3) SetDParam(index++, heightdiff);
? }
if (heightdiff == 0) {
ShowMeasurementTooltips(GetEncodedString(STR_MEASURE_AREA, dx, dy));
} else {
@@ -4388,7 +4371,7 @@ void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track
/* determine proper direction (pointing outside of the track) */
uint distance = DistanceManhattan(start_tile, end_tile);
if (distance > DistanceManhattan(TileAddByDiagDir(start_tile, TrackdirToExitdir(exit_trackdir_at_start)), end_tile)) {
Swap(exit_trackdir_at_start, exit_trackdir_at_end);
std::swap(exit_trackdir_at_start, exit_trackdir_at_end);
}
/* determine proper track on the end tile - switch between upper/lower or left/right based on the length */
if (distance % 2 != 0) exit_trackdir_at_end = NextTrackdir(exit_trackdir_at_end);
@@ -4530,12 +4513,12 @@ namespace citymania {
DrawPixelInfo *old_dpi;
void ViewportExportDrawBegin(const Viewport *vp, int left, int top, int right, int bottom) {
void ViewportExportDrawBegin(const Viewport &vp, int left, int top, int right, int bottom) {
old_dpi = _cur_dpi;
_cur_dpi = &_vd.dpi;
_vd.dpi.zoom = vp->zoom;
int mask = ScaleByZoom(-1, vp->zoom);
_vd.dpi.zoom = vp.zoom;
int mask = ScaleByZoom(-1, vp.zoom);
_vd.combine_sprites = SPRITE_COMBINE_NONE;

View File

@@ -26,7 +26,7 @@ Viewport *IsPtInWindowViewport(const Window *w, int x, int y);
Point TranslateXYToTileCoord(const Viewport &vp, int x, int y, bool clamp_to_map = true);
Point GetTileBelowCursor();
void UpdateViewportPosition(Window *w, uint32_t delta_ms);
void UpdateViewportSizeZoom(Viewport *vp);
void UpdateViewportSizeZoom(Viewport &vp);
bool MarkAllViewportsDirty(int left, int top, int right, int bottom);

View File

@@ -11,6 +11,7 @@
#include "core/backup_type.hpp"
#include "company_func.h"
#include "strings_type.h"
#include "widget_type.h"
#include "window_gui.h"
#include "viewport_func.h"
#include "zoom_func.h"
@@ -906,7 +907,7 @@ static void DrawOutline(const Window *, const NWidgetBase *wid)
void NWidgetBase::SetDirty(Window *w)
{
this->base_flags |= WBF_DIRTY;
w->flags |= WF_WIDGETS_DIRTY;
w->flags.Set(WindowFlag::CMWidgetsDirty);
}
/**
@@ -2496,7 +2497,7 @@ void NWidgetViewport::Draw(const Window *w)
void NWidgetViewport::InitializeViewport(Window *w, std::variant<TileIndex, VehicleID> focus, ZoomLevel zoom)
{
InitializeWindowViewport(w, this->pos_x, this->pos_y, this->current_x, this->current_y, focus, zoom);
w->viewport_widget = this;
w->cm_viewport_widget = this;
}
/**

View File

@@ -18,7 +18,7 @@ enum TerraformToolbarWidgets : WidgetID {
WID_TT_RAISE_LAND, ///< Raise land button.
WID_TT_LEVEL_LAND, ///< Level land button.
WID_TT_DEMOLISH, ///< Demolish aka dynamite button.
WID_TT_DEMOLISH_TREES, ///< Demolish trees only
CM_WID_TT_DEMOLISH_TREES, ///< Demolish trees only
WID_TT_BUY_LAND, ///< Buy land button.
WID_TT_PLANT_TREES, ///< Plant trees button (note: opens separate window, no place-push-button).
WID_TT_PLACE_SIGN, ///< Place sign button.

View File

@@ -78,6 +78,7 @@ enum BuildHouseWidgets : WidgetID {
WID_BH_PROTECT_ON, ///< Button to not protect the next house built.
};
// TODO move to cm folder
enum TownHK {
HK_SADVERT,
HK_MADVERT,

View File

@@ -942,7 +942,7 @@ void DrawOverlappedWindowForAll(int left, int top, int right, int bottom)
*/
void Window::SetDirty()
{
this->flags |= WF_DIRTY;
this->flags.Set(WindowFlag::CMDirty);
}
/**
@@ -2077,7 +2077,7 @@ void ResizeWindow(Window *w, int delta_x, int delta_y, bool clamp_to_screen, boo
AddPendingDirtyBlocks(w->left, w->top, w->left + w->width, w->top + w->height);
} else {
w->SetDirty();
}
}
}
/**
@@ -2125,8 +2125,8 @@ static EventState HandleWindowDragging()
break;
}
if (!(w->flags & WF_DRAG_DIRTIED)) {
w->flags |= WF_DRAG_DIRTIED;
if (w->flags.Test(WindowFlag::CMDragDirtied)) {
w->flags.Set(WindowFlag::CMDragDirtied);
w->SetDirtyAsBlocks();
}
@@ -2866,7 +2866,7 @@ static void MouseLoop(MouseClick click, int mousewheel)
switch (click) {
case MC_DOUBLE_LEFT:
case MC_LEFT:
if (citymania::HandleMouseClick(vp, click == MC_DOUBLE_LEFT)) return;
if (citymania::HandleMouseClick(vp, click == MC_DOUBLE_LEFT)) return;
if (HandleViewportClicked(*vp, x, y, click == MC_DOUBLE_LEFT)) return;
if (!w->flags.Test(WindowFlag::DisableVpScroll) &&
_settings_client.gui.scroll_mode == VSM_MAP_LMB) {