From 8969938c33e23f7fd7d4049784be1a11af3427d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=B3=87=20=CF=BA=E2=9A=B8=D0=AF=E2=84=87=E2=9A=94=20?= =?UTF-8?q?=E1=B3=87?= Date: Wed, 11 Nov 2020 08:23:31 +0100 Subject: [PATCH] Fogging outside city tiles works but needs some maps flush --- client/gui-qt/canvas.cpp | 31 ++++++++++++++++++++++ client/gui-qt/citydlg.cpp | 49 +++++++++++++++++++++++++---------- client/gui-qt/citydlg.h | 1 + client/gui-qt/qtg_cxxside.cpp | 1 + client/gui-qt/qtg_cxxside.h | 3 +++ client/gui_cbsetter.cpp | 1 + client/gui_interface.cpp | 8 ++++++ client/gui_interface.h | 3 +++ client/include/canvas_g.h | 3 +++ client/include/citydlg_g.h | 1 + client/mapview_common.cpp | 30 ++++++++++++++++----- client/mapview_common.h | 2 +- 12 files changed, 111 insertions(+), 22 deletions(-) diff --git a/client/gui-qt/canvas.cpp b/client/gui-qt/canvas.cpp index 0bebf2789e..2548ea51d1 100644 --- a/client/gui-qt/canvas.cpp +++ b/client/gui-qt/canvas.cpp @@ -166,6 +166,37 @@ void qtg_canvas_put_sprite_fogged(struct canvas *pcanvas, int canvas_x, p.end(); } +void qtg_canvas_put_sprite_citymode(struct canvas *pcanvas, int canvas_x, + int canvas_y, struct sprite *psprite, + bool fog, int fog_x, int fog_y) +{ + QPainter p; + + p.begin(&pcanvas->map_pixmap); + p.setCompositionMode(QPainter::CompositionMode_Difference); + p.setOpacity(0.5); + p.drawPixmap(canvas_x, canvas_y, *psprite->pm); + p.end(); + // QPainter p, q; + // QPixmap pix(psprite->pm->width(), psprite->pm->height()); + // pix.fill(Qt::transparent); + // pix = psprite->pm->copy(); + + // q.begin(&pix); + // q.setCompositionMode(QPainter::RasterOp_NotSourceOrNotDestination); + // q.drawPixmap(canvas_x, canvas_y, *psprite->pm); + // q.end(); + + // p.begin(&pcanvas->map_pixmap); + // p.setOpacity(0.8); + // //p.setCompositionMode(QPainter::CompositionMode_SourceIn); + // p.drawPixmap(canvas_x, canvas_y, pix); + // p.setOpacity(0.5); + // p.setCompositionMode(QPainter::CompositionMode_Lighten); + // p.drawPixmap(canvas_x, canvas_y, *psprite->pm); + // p.end(); +} + /************************************************************************/ /** Draw a filled-in colored rectangle onto canvas. ****************************************************************************/ diff --git a/client/gui-qt/citydlg.cpp b/client/gui-qt/citydlg.cpp index 23e9bd5df1..896f3ea0b8 100644 --- a/client/gui-qt/citydlg.cpp +++ b/client/gui-qt/citydlg.cpp @@ -39,8 +39,9 @@ #include "climisc.h" #include "control.h" #include "global_worklist.h" -#include "mapview_common.h" #include "mapctrl_common.h" +#include "mapview_common.h" +#include "mapview_g.h" #include "sprite.h" #include "text.h" #include "tilespec.h" @@ -511,7 +512,7 @@ void impr_info::update_buildings() h = ui->height(); layout->addWidget(ui, 0, Qt::AlignVCenter); } - layout->setContentsMargins(0,0,0,0); + layout->setContentsMargins(0, 0, 0, 0); if (impr_list.count() > 0) { parentWidget()->parentWidget()->setFixedHeight(h + 12); } else { @@ -974,11 +975,10 @@ void unit_info::update_units() ui = unit_list[j]; layout->addWidget(ui, 0, Qt::AlignVCenter); } - layout->setContentsMargins(0,0,0,0); + layout->setContentsMargins(0, 0, 0, 0); if (unit_list.count() > 0) { - parentWidget()->parentWidget()->setFixedHeight( - ui->height() + 12); + parentWidget()->parentWidget()->setFixedHeight(ui->height() + 12); } else { parentWidget()->parentWidget()->setFixedHeight(0); } @@ -1022,10 +1022,7 @@ city_label::city_label(QWidget *parent) : QLabel(parent), pcity(nullptr) type = FEELING_FINAL; } -void city_label::set_type(int x) -{ - type = x; -} +void city_label::set_type(int x) { type = x; } /************************************************************************/ /** Mouse handler for city_label ****************************************************************************/ @@ -1035,7 +1032,8 @@ void city_label::mousePressEvent(QMouseEvent *event) int w = tileset_small_sprite_width(tileset) / king()->map_scale; int num_citizens; - if (!pcity) return; + if (!pcity) + return; if (cma_is_city_under_agent(pcity, NULL)) { return; } @@ -1721,7 +1719,6 @@ void city_dialog::city_rename() ask->show(); } - /************************************************************************/ /** Save cma dialog input ****************************************************************************/ @@ -1740,7 +1737,8 @@ void city_dialog::save_cma() param.allow_disorder = false; param.allow_specialists = true; param.require_happy = ui.qsliderbox->cma_celeb_checkbox->isChecked(); - param.happy_factor = ui.qsliderbox->slider_tab[2 * O_LAST + 1]->value(); + param.happy_factor = + ui.qsliderbox->slider_tab[2 * O_LAST + 1]->value(); for (int i = O_FOOD; i < O_LAST; i++) { param.minimal_surplus[i] = ui.qsliderbox->slider_tab[2 * i]->value(); @@ -1929,7 +1927,6 @@ void city_dialog::cma_remove() ask->show(); } - /************************************************************************/ /** Received signal about changed qcheckbox - allow disbanding city ****************************************************************************/ @@ -2338,6 +2335,8 @@ void city_dialog::drop() } } +bool city_dialog::exist() { return m_instance ? true : false; } + /************************************************************************/ /** Removes selected item from city worklist ****************************************************************************/ @@ -2894,6 +2893,8 @@ void qtg_real_city_dialog_popup(struct city *pcity) city_dialog::instance()->show(); city_dialog::instance()->activateWindow(); city_dialog::instance()->raise(); + dirty_all(); + flush_dirty(); } /************************************************************************/ /** @@ -2965,12 +2966,32 @@ void qtg_refresh_unit_city_dialogs(struct unit *punit) qtg_real_city_dialog_refresh(pcity_pre); } +struct city *is_any_city_dialog_open() +{ + // some checks not to iterate cities + if (!city_dialog::exist()) + return nullptr; + if (!city_dialog::instance()->isVisible()) + return nullptr; + if (client_is_global_observer() || client_is_observer()) + return nullptr; + + city_list_iterate(client.conn.playing->cities, pcity) + { + if (qtg_city_dialog_is_open(pcity)) + return pcity; + } + city_list_iterate_end; + return nullptr; +} + /************************************************************************/ /** Return whether the dialog for the given city is open. ****************************************************************************/ bool qtg_city_dialog_is_open(struct city *pcity) { - + if (!city_dialog::exist()) + return false; if (city_dialog::instance()->pcity == pcity && city_dialog::instance()->isVisible()) { return true; diff --git a/client/gui-qt/citydlg.h b/client/gui-qt/citydlg.h index da7b546bb8..dac91a0f46 100644 --- a/client/gui-qt/citydlg.h +++ b/client/gui-qt/citydlg.h @@ -367,6 +367,7 @@ class city_dialog : public qfc_dialog { void setup_ui(struct city *qcity); void refresh(); void cma_check_agent(); + static bool exist(); struct city *pcity; int scroll_height; diff --git a/client/gui-qt/qtg_cxxside.cpp b/client/gui-qt/qtg_cxxside.cpp index aad181a77a..5388584926 100644 --- a/client/gui-qt/qtg_cxxside.cpp +++ b/client/gui-qt/qtg_cxxside.cpp @@ -51,6 +51,7 @@ void setup_gui_funcs() funcs->canvas_put_sprite = qtg_canvas_put_sprite; funcs->canvas_put_sprite_full = qtg_canvas_put_sprite_full; funcs->canvas_put_sprite_fogged = qtg_canvas_put_sprite_fogged; + funcs->canvas_put_sprite_citymode = qtg_canvas_put_sprite_citymode; funcs->canvas_put_rectangle = qtg_canvas_put_rectangle; funcs->canvas_fill_sprite_area = qtg_canvas_fill_sprite_area; funcs->canvas_put_line = qtg_canvas_put_line; diff --git a/client/gui-qt/qtg_cxxside.h b/client/gui-qt/qtg_cxxside.h index 447439dfb6..211eded7d8 100644 --- a/client/gui-qt/qtg_cxxside.h +++ b/client/gui-qt/qtg_cxxside.h @@ -64,6 +64,9 @@ void qtg_canvas_put_sprite_full(struct canvas *pcanvas, int canvas_x, void qtg_canvas_put_sprite_fogged(struct canvas *pcanvas, int canvas_x, int canvas_y, struct sprite *psprite, bool fog, int fog_x, int fog_y); +void qtg_canvas_put_sprite_citymode(struct canvas *pcanvas, int canvas_x, + int canvas_y, struct sprite *psprite, + bool fog, int fog_x, int fog_y); void qtg_canvas_put_rectangle(struct canvas *pcanvas, struct color *pcolor, int canvas_x, int canvas_y, int width, int height); diff --git a/client/gui_cbsetter.cpp b/client/gui_cbsetter.cpp index edd9eff0e0..b7395a7139 100644 --- a/client/gui_cbsetter.cpp +++ b/client/gui_cbsetter.cpp @@ -71,6 +71,7 @@ void setup_gui_funcs(void) funcs->canvas_put_sprite = gui_canvas_put_sprite; funcs->canvas_put_sprite_full = gui_canvas_put_sprite_full; funcs->canvas_put_sprite_fogged = gui_canvas_put_sprite_fogged; + funcs->canvas_put_sprite_citymode = gui_canvas_put_sprite_citymode; funcs->canvas_put_rectangle = gui_canvas_put_rectangle; funcs->canvas_fill_sprite_area = gui_canvas_fill_sprite_area; funcs->canvas_put_line = gui_canvas_put_line; diff --git a/client/gui_interface.cpp b/client/gui_interface.cpp index 5e6386751c..421e9bda12 100644 --- a/client/gui_interface.cpp +++ b/client/gui_interface.cpp @@ -220,6 +220,14 @@ void canvas_put_sprite_fogged(struct canvas *pcanvas, int canvas_x, fog_x, fog_y); } +void canvas_put_sprite_citymode(struct canvas *pcanvas, int canvas_x, + int canvas_y, struct sprite *psprite, bool fog, + int fog_x, int fog_y) +{ + funcs.canvas_put_sprite_citymode(pcanvas, canvas_x, canvas_y, psprite, fog, + fog_x, fog_y); +} + /**********************************************************************/ /** Call canvas_put_rectangle callback **************************************************************************/ diff --git a/client/gui_interface.h b/client/gui_interface.h index 003da9b49f..353cc7087a 100644 --- a/client/gui_interface.h +++ b/client/gui_interface.h @@ -75,6 +75,9 @@ struct gui_funcs { void (*canvas_put_sprite_fogged)(struct canvas *pcanvas, int canvas_x, int canvas_y, struct sprite *psprite, bool fog, int fog_x, int fog_y); + void (*canvas_put_sprite_citymode)(struct canvas *pcanvas, int canvas_x, + int canvas_y, struct sprite *psprite, + bool fog, int fog_x, int fog_y); void (*canvas_put_rectangle)(struct canvas *pcanvas, struct color *pcolor, int canvas_x, int canvas_y, int width, int height); diff --git a/client/include/canvas_g.h b/client/include/canvas_g.h index ef225b46eb..5ac10858b5 100644 --- a/client/include/canvas_g.h +++ b/client/include/canvas_g.h @@ -43,6 +43,9 @@ GUI_FUNC_PROTO(void, canvas_put_sprite_full, struct canvas *pcanvas, GUI_FUNC_PROTO(void, canvas_put_sprite_fogged, struct canvas *pcanvas, int canvas_x, int canvas_y, struct sprite *psprite, bool fog, int fog_x, int fog_y) +GUI_FUNC_PROTO(void, canvas_put_sprite_citymode, struct canvas *pcanvas, + int canvas_x, int canvas_y, struct sprite *psprite, bool fog, + int fog_x, int fog_y) GUI_FUNC_PROTO(void, canvas_put_rectangle, struct canvas *pcanvas, struct color *pcolor, int canvas_x, int canvas_y, int width, int height) diff --git a/client/include/citydlg_g.h b/client/include/citydlg_g.h index 94408351f4..720fa30e78 100644 --- a/client/include/citydlg_g.h +++ b/client/include/citydlg_g.h @@ -29,5 +29,6 @@ GUI_FUNC_PROTO(bool, city_dialog_is_open, struct city *pcity) /* Actually defined in update_queue.c */ void popup_city_dialog(struct city *pcity); void refresh_city_dialog(struct city *pcity); +struct city * is_any_city_dialog_open(); #endif /* FC__CITYDLG_G_H */ diff --git a/client/mapview_common.cpp b/client/mapview_common.cpp index 81b16ba527..cb674f2855 100644 --- a/client/mapview_common.cpp +++ b/client/mapview_common.cpp @@ -35,6 +35,7 @@ #include "unitlist.h" /* client/include */ +#include "citydlg_g.h" #include "graphics_g.h" #include "gui_main_g.h" #include "mapctrl_g.h" @@ -1290,7 +1291,7 @@ bool tile_visible_and_not_on_border_mapcanvas(struct tile *ptile) ****************************************************************************/ void put_drawn_sprites(struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y, int count, struct drawn_sprite *pdrawn, - bool fog) + bool fog, bool city_dialog) { int i; @@ -1299,8 +1300,12 @@ void put_drawn_sprites(struct canvas *pcanvas, float zoom, int canvas_x, /* This can happen, although it should probably be avoided. */ continue; } - - if (fog && pdrawn[i].foggable) { + if (city_dialog) { + canvas_put_sprite_citymode(pcanvas, + canvas_x / zoom + pdrawn[i].offset_x, + canvas_y / zoom + pdrawn[i].offset_y, + pdrawn[i].sprite, TRUE, canvas_x, canvas_y); + } else if (fog && pdrawn[i].foggable) { canvas_put_sprite_fogged(pcanvas, canvas_x / zoom + pdrawn[i].offset_x, canvas_y / zoom + pdrawn[i].offset_y, pdrawn[i].sprite, TRUE, canvas_x, canvas_y); @@ -1314,7 +1319,7 @@ void put_drawn_sprites(struct canvas *pcanvas, float zoom, int canvas_x, } } } - +#include /************************************************************************/ /** Draw one layer of a tile, edge, corner, unit, and/or city onto the canvas at the given position. @@ -1328,14 +1333,25 @@ void put_one_element(struct canvas *pcanvas, float zoom, const struct unit_type *putype) { struct drawn_sprite tile_sprs[80]; + bool city_mode = false; int count = fill_sprite_array(tileset, tile_sprs, layer, ptile, pedge, pcorner, punit, pcity, citymode, putype); bool fog = (ptile && gui_options.draw_fog_of_war && TILE_KNOWN_UNSEEN == client_tile_get_known(ptile)); - + if (ptile) { + struct city *xcity = is_any_city_dialog_open(); + if (xcity) { + int dummy_x, dummy_y; + //struct city *xcity = find_city_near_tile(ptile); + if (xcity + && !city_base_to_city_map(&dummy_x, &dummy_y, xcity, ptile)) { + city_mode = true; + } + } + } /*** Draw terrain and specials ***/ - put_drawn_sprites(pcanvas, zoom, canvas_x, canvas_y, count, tile_sprs, - fog); + put_drawn_sprites(pcanvas, zoom, canvas_x, canvas_y, count, tile_sprs, fog, + city_mode); } /************************************************************************/ /** diff --git a/client/mapview_common.h b/client/mapview_common.h index 2bb34f0982..4518a472ec 100644 --- a/client/mapview_common.h +++ b/client/mapview_common.h @@ -292,7 +292,7 @@ void put_one_element(struct canvas *pcanvas, float zoom, void put_drawn_sprites(struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y, int count, struct drawn_sprite *pdrawn, - bool fog); + bool fog, bool citydialog = false); void update_map_canvas(int canvas_x, int canvas_y, int width, int height); void update_map_canvas_visible(void);