Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix selling improvements for multiple cities at once #2484

Merged
merged 7 commits into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 41 additions & 9 deletions client/repodlgs_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

// utility
#include "fcintl.h"
#include "log.h"
#include "support.h" // fc_snprintf()

// common
Expand Down Expand Up @@ -167,6 +166,34 @@ void get_economy_report_units_data(struct unit_entry *entries,
void sell_all_improvements(const struct impr_type *pimprove,
bool redundant_only, char *message,
size_t message_sz)
{
if (nullptr == client.conn.playing) {
return;
}

QList<struct city *> cities;
city_list_iterate(client.conn.playing->cities, pcity)
{
cities.append(pcity);
}
city_list_iterate_end;

sell_all_improvements_for_cities(cities, pimprove, redundant_only, message,
message_sz);
}

/**
Sell all improvements of the given type in cities. If
"redundant_only" is specified then only those improvements that are replaced
will be sold.

The "message" string will be filled with a GUI-friendly message about
what was sold.
*/
void sell_all_improvements_for_cities(QList<struct city *> cities,
const struct impr_type *pimprove,
bool redundant_only, char *message,
size_t message_sz)
{
int count = 0, gold = 0;

Expand All @@ -175,16 +202,21 @@ void sell_all_improvements(const struct impr_type *pimprove,
return;
}

city_list_iterate(client.conn.playing->cities, pcity)
{
if (!pcity->did_sell && city_has_building(pcity, pimprove)
&& (!redundant_only || is_improvement_redundant(pcity, pimprove))) {
count++;
gold += impr_sell_gold(pimprove);
city_sell_improvement(pcity, improvement_number(pimprove));
for (auto pcity : cities) {
int city_id = pcity->id;
if (nullptr == game_city_by_number(city_id)) {
continue;
}

if (pcity->did_sell || !city_has_building(pcity, pimprove)
|| (redundant_only && !is_improvement_redundant(pcity, pimprove))) {
continue;
}

count++;
gold += impr_sell_gold(pimprove);
city_sell_improvement(pcity, improvement_number(pimprove));
}
city_list_iterate_end;

if (count > 0) {
// FIXME: plurality of count is ignored!
Expand Down
4 changes: 4 additions & 0 deletions client/repodlgs_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ void get_economy_report_units_data(struct unit_entry *entries,
void sell_all_improvements(const struct impr_type *pimprove,
bool redundant_only, char *message,
size_t message_sz);
void sell_all_improvements_for_cities(QList<struct city *> cities,
const struct impr_type *pimprove,
bool redundant_only, char *message,
size_t message_sz);
void disband_all_units(const struct unit_type *punittype,
bool in_cities_only, char *message,
size_t message_sz);
81 changes: 48 additions & 33 deletions client/views/view_cities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include "fcintl.h"
// common
#include "citydlg_common.h"
#include "game.h"
#include "global_worklist.h"
// client
#include "cityrep_g.h"
Expand All @@ -32,6 +31,7 @@
#include "icons.h"
#include "page_game.h"
#include "qtg_cxxside.h"
#include "repodlgs_common.h"
#include "top_bar.h"
#include "views/view_cities.h"
#include "views/view_map.h"
Expand Down Expand Up @@ -566,11 +566,7 @@ void city_widget::display_list_menu(const QPoint)
cid id;
struct universal target;
QString imprname;
const struct impr_type *building;
Impr_type_id impr_id;
int city_id;
bool need_clear = true;
bool sell_ask = true;

if (!act) {
return;
Expand All @@ -582,6 +578,11 @@ void city_widget::display_list_menu(const QPoint)
id = qvar.toInt();
target = cid_decode(id);

if (m_state == SELL) {
sell(target.value.building);
return;
}

city_list_iterate(client_player()->cities, iter_city)
{
if (nullptr != iter_city) {
Expand Down Expand Up @@ -674,34 +675,6 @@ void city_widget::display_list_menu(const QPoint)
case CHANGE_PROD_LAST:
city_queue_insert(pcity, -1, &target);
break;
case SELL:
building = target.value.building;
if (sell_ask) {
hud_message_box *ask = new hud_message_box(king()->central_wdg);
imprname = improvement_name_translation(building);
QString buf = QString(_("Are you sure you want to sell the %1?"))
.arg(imprname);
sell_ask = false;
ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes);
ask->setDefaultButton(QMessageBox::No);
ask->button(QMessageBox::Yes)->setText(_("Yes Sell"));
ask->set_text_title(buf, _("Sell?"));
ask->setAttribute(Qt::WA_DeleteOnClose);
city_id = pcity->id;
impr_id = improvement_number(building);
connect(ask, &hud_message_box::accepted, this, [=]() {
struct city *pcity = game_city_by_number(city_id);
struct impr_type *building = improvement_by_number(impr_id);
if (!pcity || !building) {
return;
}
if (!pcity->did_sell && city_has_building(pcity, building)) {
city_sell_improvement(pcity, impr_id);
}
});
ask->show();
}
break;
case CMA:
if (CMA_NONE == id) {
cma_release_city(pcity);
Expand Down Expand Up @@ -732,6 +705,48 @@ void city_widget::display_list_menu(const QPoint)
list_menu->popup(QCursor::pos());
}

/**
Sell building for all selected cities after asking for
confirmation.
*/
void city_widget::sell(const struct impr_type *building)
{
fc_assert_ret(building != nullptr);

Impr_type_id impr_id = improvement_number(building);
if (nullptr == improvement_by_number(impr_id)) {
return;
}

hud_message_box *ask = new hud_message_box(king()->central_wdg);
QString imprname = improvement_name_translation(building);
QString buf;
if (selected_cities.size() == 1) {
buf = QString(_("Are you sure you want to sell the %1?")).arg(imprname);
} else {
buf = QString(_("Do you really wish to sell every %1?")).arg(imprname);
lmoureaux marked this conversation as resolved.
Show resolved Hide resolved
}

ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes);
ask->setDefaultButton(QMessageBox::No);
ask->button(QMessageBox::Yes)->setText(_("Yes Sell"));
ask->set_text_title(buf, _("Sell?"));
ask->setAttribute(Qt::WA_DeleteOnClose);
connect(ask, &hud_message_box::accepted, this, [=]() {
char buf[1024];
sell_all_improvements_for_cities(selected_cities, building, false, buf,
sizeof(buf));

hud_message_box *result = new hud_message_box(king()->central_wdg);
result->set_text_title(buf, _("Sell Results"));
result->setStandardButtons(QMessageBox::Ok);
result->setAttribute(Qt::WA_DeleteOnClose);
result->show();
});

ask->show();
}

/**
Fills menu items that can be produced or sold
*/
Expand Down
1 change: 1 addition & 0 deletions client/views/view_cities.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ public slots:
void fill_production_menus(city_widget::menu_labels what,
QMap<QString, cid> &custom_labels,
TestCityFunc test_func, QMenu *menu);
void sell(const struct impr_type *building);
};

/***************************************************************************
Expand Down
Loading