diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 047e27ba27..7340c0d42f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,7 +24,7 @@ jobs: build_type: RelWithDebInfo runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install GCC @@ -91,7 +91,7 @@ jobs: needs: clang-format runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install GCC @@ -129,7 +129,7 @@ jobs: run: shell: msys2 {0} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: msys2/setup-msys2@v2 @@ -177,7 +177,7 @@ jobs: build/Windows-x86_64/Freeciv21-*-Windows-x86_64.exe build/Windows-x86_64/Freeciv21-*-Windows-x86_64.exe.sha256 - name: Upload a build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Windows-exe path: build/Windows-x86_64/Freeciv21-*.exe @@ -191,13 +191,13 @@ jobs: VCPKG_ROOT: C:/vcpkg VCPKG_DEFAULT_BINARY_CACHE: ${{github.workspace}}/vcpkg/bincache steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: lukka/run-vcpkg@v10 + - uses: lukka/run-vcpkg@v11 name: Install dependencies with: - vcpkgGitCommitId: c8696863d371ab7f46e213d8f5ca923c4aef2a00 + vcpkgGitCommitId: 53bef8994c541b6561884a8395ea35715ece75db - name: Enable Developer Command Prompt uses: ilammy/msvc-dev-cmd@v1 - name: Configure @@ -217,7 +217,7 @@ jobs: env: VCPKG_BUILD_TYPE: release steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install build tools @@ -229,13 +229,13 @@ jobs: gettext \ create-dmg brew link gettext --force - - uses: actions/setup-python@v4 # Workaround for #2069 + - uses: actions/setup-python@v5 # Workaround for #2069 with: python-version: '3.11' - - uses: lukka/run-vcpkg@v10 + - uses: lukka/run-vcpkg@v11 name: Install dependencies with: - vcpkgGitCommitId: c8696863d371ab7f46e213d8f5ca923c4aef2a00 + vcpkgGitCommitId: 53bef8994c541b6561884a8395ea35715ece75db - name: Build uses: lukka/run-cmake@v10 with: @@ -286,7 +286,7 @@ jobs: Freeciv21-*.dmg Freeciv21-*.dmg.sha256 - name: Upload a build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: macOS-dmg path: Freeciv21-*.dmg @@ -314,7 +314,7 @@ jobs: zlib-devel \ libunwind-devel \ elfutils-libs - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Configure # Set ALWAYS_ROOT because the container user is root and creating an # unpriviledged user would be too much work. @@ -388,8 +388,8 @@ jobs: if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' steps: - name: checkout - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v19 + uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v22 - run: nix flake check # TODO: We can add the build to a cache for others (see cachix.org) # It's free for FOSS. @@ -403,10 +403,10 @@ jobs: env: QT_VERSION: v5.15.8-lts-lgpl steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache Qt build id: qtcache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/qt key: qt-wasm-${{ env.QT_VERSION }}-svg-socket-v2 @@ -419,7 +419,7 @@ jobs: clang \ python3 \ gettext - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Checkout emsdk with: repository: emscripten-core/emsdk @@ -442,7 +442,7 @@ jobs: cd lua-5.4.3 emcmake cmake . emmake make install - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 if: steps.qtcache.outputs.cache-hit != 'true' name: Checkout qtbase with: @@ -460,7 +460,7 @@ jobs: git cherry-pick 76d12eea2252c5e537dff15b103bdc1f925cf760 ./configure -xplatform wasm-emscripten -opensource -confirm-license -prefix ~/qt -nomake examples make install - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 if: steps.qtcache.outputs.cache-hit != 'true' name: Checkout qtsvg with: @@ -474,7 +474,7 @@ jobs: cd qtsvg ~/qt/bin/qmake make install - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Checkout zstd with: repository: facebook/zstd @@ -487,7 +487,7 @@ jobs: mkdir bld emcmake cmake build/cmake -DZSTD_BUILD_PROGRAMS=0 -DZSTD_BUILD_SHARED=0 emmake make install - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Checkout extra-cmake-modules with: repository: KDE/extra-cmake-modules @@ -498,7 +498,7 @@ jobs: cd ecm cmake . sudo make install - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Checkout karchive with: repository: KDE/karchive @@ -543,13 +543,13 @@ jobs: run: | cat common/networking/CMakeFiles/networking.dir/includes_CXX.rsp cat CMakeCache.txt - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: failure() with: name: cmakecache path: CMakeCache.txt - name: Archive production artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: wasm-client path: freeciv21-client.* @@ -558,7 +558,7 @@ jobs: name: clang-format Code Formatter runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Run clang-format style check for C/C++ diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 63f0473d74..4d5457100e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -10,8 +10,9 @@ jobs: update-autorevision: name: "Update AutoRevision" runs-on: ubuntu-22.04 + if: github.event_name == 'release' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - # Make sure there are no unstaged changes @@ -29,7 +30,7 @@ jobs: echo Target branch is $branch echo branch=$branch >> $GITHUB_OUTPUT - name: Create Pull Request - uses: peter-evans/create-pull-request@v4.0.4 + uses: peter-evans/create-pull-request@v6 with: base: ${{ steps.branch.outputs.branch }} commit-message: "Release update of AutoRevision.txt" @@ -44,8 +45,9 @@ jobs: update-archive: name: "Update Source Archive" runs-on: ubuntu-22.04 + if: github.event_name == 'release' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - run: git rev-parse --short=5 HEAD > cmake/AutoRevision.txt @@ -78,7 +80,7 @@ jobs: shell: msys2 {0} if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: msys2/setup-msys2@v2 diff --git a/AUTHORS b/AUTHORS index 2aa22e2c19..de631f00a7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,5 +1,6 @@ Freeciv21 contributors are listed below in alphabetical order: +- blabber (Tobias Rehbein) - DobbyK - ilkkachu (Ilkka Virta) - jwrober (James Robertson) diff --git a/CMakeLists.txt b/CMakeLists.txt index e8ac627aea..980af6a930 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,28 +39,22 @@ include(AutoRevision) # Set some variables from AutoRevision for use here and later list(LENGTH FC21_REV_TAG_LIST FC21_REV_TAG_LIST_LENGTH) -# When we tag a stable release we only get 2 of the 4 components populated -# So we manually set some of the variables we need for the full version. -if(${FC21_REV_TAG_LIST_LENGTH} EQUAL 2) +# When we tag a stable release we only get 3 of the 4 components populated, +# so we manually set some of the variables we need for the full version. +if (${FC21_REV_TAG_LIST_LENGTH} EQUAL 3) list(GET FC21_REV_TAG_LIST 0 FC21_MAJOR_VERSION) list(GET FC21_REV_TAG_LIST 1 FC21_MINOR_VERSION) - set(FC21_LABEL_VERSION "Stable") - set(FC21_EMER_VERSION "0") - set(FC21_PATCH_VERSION "0") + list(GET FC21_REV_TAG_LIST 2 FC21_PATCH_VERSION) + set(FC21_VERSION_LABEL "stable") set(IS_STABLE_VERSION true) - set(FREECIV21_VERSION "${FC21_MAJOR_VERSION}.${FC21_MINOR_VERSION}") + set(FREECIV21_VERSION "${FC21_MAJOR_VERSION}.${FC21_MINOR_VERSION}.${FC21_PATCH_VERSION}") else() list(GET FC21_REV_TAG_LIST 0 FC21_MAJOR_VERSION) list(GET FC21_REV_TAG_LIST 1 FC21_MINOR_VERSION) - list(GET FC21_REV_TAG_LIST 2 FC21_LABEL_VERSION) - if (${FC21_REV_TAG_LIST_LENGTH} GREATER 3) - list(GET FC21_REV_TAG_LIST 3 FC21_EMER_VERSION) - else() - set(FC21_EMER_VERSION 0) - endif() - set(FC21_PATCH_VERSION ${FC21_REV_HEAD_HASH_D}) + list(GET FC21_REV_TAG_LIST 2 FC21_VERSION_LABEL) + list(GET FC21_REV_TAG_LIST 3 FC21_PATCH_VERSION) set(IS_STABLE_VERSION false) - set(FREECIV21_VERSION "${FC21_MAJOR_VERSION}.${FC21_MINOR_VERSION}.${FC21_PATCH_VERSION}") + set(FREECIV21_VERSION "${FC21_MAJOR_VERSION}.${FC21_MINOR_VERSION}") endif() # Set project diff --git a/README.md b/README.md index 31f9d754ac..243e403583 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,9 @@ The documentation is found on our [documentation website](https://longturn.readt Installation ------------ -### Snap and Flathub Editions +### Snap, Flathub and AUR Editions -

Get Freeciv21 on Snapcraft Get Freeciv21 on Flathub

+

Get Freeciv21 on Snapcraft Get Freeciv21 on Flathub AUR version

### Windows and macOS @@ -86,3 +86,17 @@ Alternatively, Freeciv21 can be used with Nix. For this, enable Nix flakes and r ```sh nix run github:longturn/freeciv21#; ``` + +### FreeBSD + +Freeciv21 is available in the FreeBSD ports tree. You can install the binary +package using this command: +```sh +pkg install freeciv21 +``` + +Although it is recommended to use the binary package, you can also build +Freeciv21 using the ports tree: +```sh +make -C /usr/ports/games/freeciv21 install clean +``` diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index e3ef026725..a4406da9ed 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -157,8 +157,13 @@ target_link_libraries(freeciv21-client PRIVATE common) target_link_libraries(freeciv21-client PRIVATE cvercmp) target_link_libraries(freeciv21-client PRIVATE tolua) -target_link_libraries(freeciv21-client PRIVATE Qt5::Widgets) -target_link_libraries(freeciv21-client PRIVATE Qt5::Svg) +target_link_libraries(freeciv21-client PRIVATE Qt6::Widgets) +target_link_libraries(freeciv21-client PRIVATE Qt6::Svg) + +# Workaround for QTBUG-93413 +set_source_files_properties( + widgets/city/governor_widget.ui + PROPERTIES AUTOUIC_OPTIONS "--connections;string") if(NOT EMSCRIPTEN) target_sources(freeciv21-client PRIVATE servers.cpp) @@ -178,11 +183,11 @@ if (AUDIO_SDL) endif() if (APPLE) - qt5_import_plugins(freeciv21-client INCLUDE Qt5::QCocoaIntegrationPlugin Qt5::QSvgPlugin) + qt6_import_plugins(freeciv21-client INCLUDE Qt6::QCocoaIntegrationPlugin Qt6::QSvgPlugin) endif() if(EMSCRIPTEN) - qt5_import_plugins(freeciv21-client INCLUDE Qt5::QWasmIntegrationPlugin) + qt6_import_plugins(freeciv21-client INCLUDE Qt6::QWasmIntegrationPlugin) target_link_options(freeciv21-client PRIVATE -sASSERTIONS=1 -sWEBSOCKET_URL=wss:// @@ -200,8 +205,8 @@ if(EMSCRIPTEN) "--preload-file=${CMAKE_SOURCE_DIR}/data/hexemplio@data/hexemplio" "--preload-file=${CMAKE_SOURCE_DIR}/data/amplio2.tilespec@data/amplio2.tilespec" "--preload-file=${CMAKE_SOURCE_DIR}/data/amplio2@data/amplio2" - "--preload-file=${CMAKE_SOURCE_DIR}/data/themes/gui-qt/Classic@data/themes/gui-qt/Classic" - "--preload-file=${CMAKE_SOURCE_DIR}/data/themes/gui-qt/icons@data/themes/gui-qt/icons" + "--preload-file=${CMAKE_SOURCE_DIR}/data/themes/Classic@data/themes/Classic" + "--preload-file=${CMAKE_SOURCE_DIR}/data/themes/icons@data/themes/icons" "--preload-file=${CMAKE_SOURCE_DIR}/data/stdmusic.musicspec@data/stdmusic.musicspec" "--preload-file=${CMAKE_SOURCE_DIR}/data/stdmusic@data/stdmusic" "--preload-file=${CMAKE_SOURCE_DIR}/data/stdsounds@data/stdsounds" diff --git a/client/audio/audio.cpp b/client/audio/audio.cpp index 801337150e..f9c3eabf38 100644 --- a/client/audio/audio.cpp +++ b/client/audio/audio.cpp @@ -78,30 +78,16 @@ const QVector *get_soundplugin_list(const struct option *poption) return plugin_list; } -/** - Returns a static string vector of audiosets of given type available - on the system by searching all data directories for files matching - suffix. - The list is nullptr-terminated. - */ -static const QVector * -get_audio_speclist(const char *suffix, QVector **audio_list) -{ - if (nullptr == *audio_list) { - *audio_list = fileinfolist(get_data_dirs(), suffix); - } - - return *audio_list; -} - /** Returns a static string vector of soundsets available on the system. */ const QVector *get_soundset_list(const struct option *poption) { - static QVector *sound_list = nullptr; - - return get_audio_speclist(SNDSPEC_SUFFIX, &sound_list); + static QVector *sound_list = new QVector; + auto list = fileinfolist(get_data_dirs(), SNDSPEC_SUFFIX); + *sound_list = std::move(*list); + delete list; + return sound_list; } /** @@ -109,9 +95,11 @@ const QVector *get_soundset_list(const struct option *poption) */ const QVector *get_musicset_list(const struct option *poption) { - static QVector *music_list = nullptr; - - return get_audio_speclist(MUSICSPEC_SUFFIX, &music_list); + static QVector *music_list = new QVector; + auto list = fileinfolist(get_data_dirs(), MUSICSPEC_SUFFIX); + *music_list = std::move(*list); + delete list; + return music_list; } /** diff --git a/client/audio/audio_none.cpp b/client/audio/audio_none.cpp index 96f4f8f3ba..ed5b0c25c6 100644 --- a/client/audio/audio_none.cpp +++ b/client/audio/audio_none.cpp @@ -9,14 +9,10 @@ see https://www.gnu.org/licenses/. */ -#include "support.h" - -#include "audio.h" - #include "audio_none.h" - -// gui-qt +#include "audio.h" #include "qtg_cxxside.h" +#include "support.h" /** Clean up diff --git a/client/chatline.cpp b/client/chatline.cpp index 59a6531c6b..84e8cdafd1 100644 --- a/client/chatline.cpp +++ b/client/chatline.cpp @@ -26,6 +26,7 @@ // common #include "chat.h" #include "chatline_common.h" + // client #include "audio/audio.h" #include "client_main.h" @@ -33,21 +34,19 @@ #include "colors_common.h" #include "connectdlg_common.h" #include "control.h" -#include "featured_text.h" -#include "game.h" -#include "views/view_map_common.h" -// gui-qt #include "dialogs.h" #include "fc_client.h" +#include "featured_text.h" #include "fonts.h" +#include "game.h" #include "icons.h" #include "messagewin.h" #include "page_game.h" #include "views/view_map.h" +#include "views/view_map_common.h" static bool is_plain_public_message(const QString &s); -FC_CPP_DECLARE_LISTENER(chat_listener) QStringList chat_listener::history = QStringList(); namespace { @@ -607,7 +606,7 @@ void chat_widget::append(const QString &str) void chat_widget::paintEvent(QPaintEvent *event) { QStyleOption opt; - opt.init(this); + opt.initFrom(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } diff --git a/client/chatline.h b/client/chatline.h index b4cf8f2223..771764dd0e 100644 --- a/client/chatline.h +++ b/client/chatline.h @@ -16,7 +16,7 @@ #include #include #include -// gui-qt +// client #include "listener.h" #include "widgets/decorations.h" @@ -27,12 +27,10 @@ class QPaintEvent; class QPainter; class QPushButton; class QUrl; -class chat_listener; void set_chat_colors(const QHash &colors); QString apply_tags(QString str, const struct text_tag_list *tags, QColor bg_color); -template <> std::set listener::instances; /*************************************************************************** Listener for chat. See listener<> for information about how to use it ***************************************************************************/ diff --git a/client/chatline_common.cpp b/client/chatline_common.cpp index 08c884e7b4..907716d70e 100644 --- a/client/chatline_common.cpp +++ b/client/chatline_common.cpp @@ -22,13 +22,10 @@ #include "featured_text.h" #include "packets.h" -// gui-qt -#include "chatline.h" - // client -#include "client_main.h" - +#include "chatline.h" #include "chatline_common.h" +#include "client_main.h" Q_GLOBAL_STATIC(QMutex, ow_mutex); diff --git a/client/citybar.cpp b/client/citybar.cpp index d8aac9a9ce..a824fcd34e 100644 --- a/client/citybar.cpp +++ b/client/citybar.cpp @@ -23,10 +23,8 @@ // common #include "city.h" -// gui-qt -#include "canvas.h" - // client +#include "canvas.h" #include "client_main.h" #include "colors_common.h" #include "views/view_map_common.h" diff --git a/client/citydlg.cpp b/client/citydlg.cpp index 496aa7d932..8723a78508 100644 --- a/client/citydlg.cpp +++ b/client/citydlg.cpp @@ -33,24 +33,22 @@ #include "game.h" // client +#include "canvas.h" #include "citydlg_common.h" #include "client_main.h" #include "climisc.h" #include "control.h" -#include "global_worklist.h" -#include "governor.h" -#include "mapctrl_common.h" -#include "tileset/tilespec.h" -#include "views/view_map_common.h" -// gui-qt -#include "canvas.h" #include "fc_client.h" #include "fonts.h" +#include "global_worklist.h" +#include "governor.h" #include "hudwidget.h" #include "icons.h" +#include "mapctrl_common.h" #include "page_game.h" #include "qtg_cxxside.h" #include "text.h" +#include "tileset/tilespec.h" #include "tooltips.h" #include "top_bar.h" #include "unitlist.h" @@ -58,6 +56,7 @@ #include "utils/unit_quick_menu.h" #include "views/view_cities.h" // hIcon #include "views/view_map.h" +#include "views/view_map_common.h" #include "widgets/city/governor_widget.h" extern QString split_text(const QString &text, bool cut); @@ -581,28 +580,57 @@ void city_label::set_type(int x) { type = x; } */ void city_label::mousePressEvent(QMouseEvent *event) { - int citnum, i, num_citizens, nothing_width; - int w = tileset_small_sprite_width(tileset); - if (!pcity) { return; } + if (cma_is_city_under_agent(pcity, nullptr)) { return; } - num_citizens = pcity->size; - nothing_width = (this->width() - num_citizens * w) / 2; - i = 1 + (num_citizens * 5 / 200); - w = w / i; - citnum = (event->x() - nothing_width) / w; if (!can_client_issue_orders()) { return; } - city_rotate_specialist(pcity, citnum); + int sprite_width = tileset_small_sprite_width(tileset); + int sprite_height = tileset_small_sprite_height(tileset); + + int num_citizens = pcity->size; + + // if there's less than CITIZENS_PER_ROW citizens, we may have space on the + // sides, so account for that + int horizontal_spacing = + (this->width() - MIN(CITIZENS_PER_ROW, num_citizens) * sprite_width) + / 2; + + int citizen_x = (event->x() - horizontal_spacing) / sprite_width; + int citizen_y = event->y() / sprite_height; + + int citizen_index = citizen_y * CITIZENS_PER_ROW + citizen_x; + + // users can click in empty space beyond the citizen sprites if there are + // incomplete rows + if (citizen_index < 0 || citizen_index > num_citizens - 1) { + return; + } + + city_rotate_specialist(pcity, citizen_index); } +QSize city_label::get_pixmap_size() const +{ + auto pix = this->pixmap(Qt::ReturnByValue); + if (pix.isNull()) { + return {0, 0}; + } else { + return pix.size(); + } +} + +QSize city_label::minimumSizeHint() const { return this->get_pixmap_size(); } + +QSize city_label::sizeHint() const { return this->get_pixmap_size(); } + /** Just sets target city for city_label */ @@ -1422,87 +1450,88 @@ void city_dialog::update_buy_button() ui.buy_button->setText(str); } +/** + Fill a pixmap with citizen sprites + */ +void city_dialog::fill_citizens_pixmap(QPixmap *pixmap, QPainter *painter, + const citizen_category *categories, + int num_citizens) +{ + int sprite_width = tileset_small_sprite_width(tileset); + int sprite_height = tileset_small_sprite_height(tileset); + + QRect sprite_rectangle(0, 0, sprite_width, sprite_height); + QRect painting_area(0, 0, sprite_width, sprite_height); + + pixmap->fill(Qt::transparent); + for (int i = 0; i < num_citizens; i++) { + painting_area.moveTo((i % CITIZENS_PER_ROW) * sprite_width, + (i / CITIZENS_PER_ROW) * sprite_height); + auto pix = get_citizen_sprite(tileset, categories[i], i, pcity); + painter->begin(citizen_pixmap); + painter->drawPixmap(painting_area, *pix, sprite_rectangle); + painter->end(); + } +} + /** Redraws citizens for city_label (citizens_label) */ void city_dialog::update_citizens() { enum citizen_category categories[MAX_CITY_SIZE]; - int i, j, width, height; - QPainter p; int num_citizens = get_city_citizen_types(pcity, FEELING_FINAL, categories); - int w = tileset_small_sprite_width(tileset); - int h = tileset_small_sprite_height(tileset); - i = 1 + (num_citizens * 5 / 200); - w = w / i; - QRect source_rect(0, 0, w, h); - QRect dest_rect(0, 0, w, h); - width = w * num_citizens; - height = h; + int num_rows = num_citizens / CITIZENS_PER_ROW; + + // extra incomplete row for leftover citizens + if (num_citizens % CITIZENS_PER_ROW > 0) { + num_rows += 1; + } + + int sprite_width = tileset_small_sprite_width(tileset); + int sprite_height = tileset_small_sprite_height(tileset); + + int canvas_width = sprite_width * MIN(CITIZENS_PER_ROW, num_citizens); + int canvas_height = sprite_height * num_rows; if (citizen_pixmap) { citizen_pixmap->detach(); delete citizen_pixmap; } - citizen_pixmap = new QPixmap(width, height); + citizen_pixmap = new QPixmap(canvas_width, canvas_height); + QPainter painter; - for (j = 0, i = 0; i < num_citizens; i++, j++) { - dest_rect.moveTo(i * w, 0); - auto pix = get_citizen_sprite(tileset, categories[j], j, pcity); - p.begin(citizen_pixmap); - p.drawPixmap(dest_rect, *pix, source_rect); - p.end(); - } + this->fill_citizens_pixmap(citizen_pixmap, &painter, categories, + num_citizens); ui.citizens_label->set_city(pcity); ui.citizens_label->setPixmap(*citizen_pixmap); + ui.citizens_label->updateGeometry(); lab_table[FEELING_FINAL]->setPixmap(*citizen_pixmap); + lab_table[FEELING_FINAL]->updateGeometry(); lab_table[FEELING_FINAL]->setToolTip(text_happiness_wonders(pcity)); - for (int k = 0; k < FEELING_LAST - 1; k++) { - lab_table[k]->set_city(pcity); + for (int i = 0; i < FEELING_LAST - 1; i++) { + lab_table[i]->set_city(pcity); num_citizens = get_city_citizen_types( - pcity, static_cast(k), categories); - - for (j = 0, i = 0; i < num_citizens; i++, j++) { - dest_rect.moveTo(i * w, 0); - auto pix = get_citizen_sprite(tileset, categories[j], j, pcity); - p.begin(citizen_pixmap); - p.drawPixmap(dest_rect, *pix, source_rect); - p.end(); - } - - lab_table[k]->setPixmap(*citizen_pixmap); + pcity, static_cast(i), categories); + this->fill_citizens_pixmap(citizen_pixmap, &painter, categories, + num_citizens); - switch (k) { - case FEELING_BASE: - lab_table[k]->setToolTip(text_happiness_cities(pcity)); - break; - - case FEELING_LUXURY: - lab_table[k]->setToolTip(text_happiness_luxuries(pcity)); - break; - - case FEELING_EFFECT: - lab_table[k]->setToolTip(text_happiness_buildings(pcity)); - break; - - case FEELING_NATIONALITY: - lab_table[k]->setToolTip(text_happiness_nationality(pcity)); - break; - - case FEELING_MARTIAL: - lab_table[k]->setToolTip(text_happiness_units(pcity)); - break; - - default: - break; - } + lab_table[i]->setPixmap(*citizen_pixmap); + lab_table[i]->updateGeometry(); } + + lab_table[FEELING_BASE]->setToolTip(text_happiness_cities(pcity)); + lab_table[FEELING_LUXURY]->setToolTip(text_happiness_luxuries(pcity)); + lab_table[FEELING_EFFECT]->setToolTip(text_happiness_buildings(pcity)); + lab_table[FEELING_NATIONALITY]->setToolTip( + text_happiness_nationality(pcity)); + lab_table[FEELING_MARTIAL]->setToolTip(text_happiness_units(pcity)); } /** diff --git a/client/citydlg.h b/client/citydlg.h index 492aba002a..7796ec3c71 100644 --- a/client/citydlg.h +++ b/client/citydlg.h @@ -9,6 +9,7 @@ **************************************************************************/ #pragma once +#include "city.h" #include "fc_types.h" // Qt @@ -23,9 +24,11 @@ #include #include #include -// gui-qt +// client #include "dialogs.h" +#define CITIZENS_PER_ROW 20 + class QAction; class QCheckBox; class QCloseEvent; @@ -251,9 +254,12 @@ class city_label : public QLabel { private: struct city *pcity{nullptr}; int type; + QSize get_pixmap_size() const; protected: void mousePressEvent(QMouseEvent *event) override; + QSize minimumSizeHint() const override; + QSize sizeHint() const override; }; class city_info : public QWidget { @@ -298,6 +304,9 @@ class city_dialog : public QWidget { void update_building(); void update_info_label(); void update_buy_button(); + void fill_citizens_pixmap(QPixmap *pixmap, QPainter *painter, + const citizen_category *categories, + int num_citizens); void update_citizens(); void update_improvements(); void update_units(); diff --git a/client/citydlg.ui b/client/citydlg.ui index 9ed64953e0..1efbce18dd 100644 --- a/client/citydlg.ui +++ b/client/citydlg.ui @@ -64,11 +64,11 @@ - - - 200 - 0 - + + + 0 + 0 + citizens @@ -407,6 +407,12 @@ true + + + 0 + 0 + + 0 @@ -431,6 +437,12 @@ true + + + 0 + 0 + + Output @@ -596,6 +608,12 @@ true + + + 0 + 0 + + 0 @@ -617,6 +635,12 @@ + + + 0 + 0 + + TextLabel @@ -634,6 +658,12 @@ + + + 0 + 0 + + TextLabel @@ -651,6 +681,12 @@ + + + 0 + 0 + + lab_table3 @@ -668,6 +704,12 @@ + + + 0 + 0 + + TextLabel @@ -685,6 +727,12 @@ + + + 0 + 0 + + TextLabel @@ -702,6 +750,12 @@ + + + 0 + 0 + + TextLabel diff --git a/client/client_main.cpp b/client/client_main.cpp index de85673802..1aae8b86e0 100644 --- a/client/client_main.cpp +++ b/client/client_main.cpp @@ -74,12 +74,14 @@ #include "fonts.h" #include "global_worklist.h" #include "governor.h" +#include "helpdlg.h" #include "messagewin_common.h" #include "minimap_panel.h" #include "music.h" #include "options.h" #include "overview_common.h" #include "packhand.h" +#include "qtg_cxxside.h" #include "themes_common.h" #include "tileset/tilespec.h" #include "update_queue.h" @@ -88,10 +90,6 @@ #include "views/view_nations_data.h" #include "voteinfo.h" -// gui-qt -#include "helpdlg.h" -#include "qtg_cxxside.h" - /* client/luascript */ #include "script_client.h" @@ -303,7 +301,6 @@ static void client_game_reset() */ int client_main(int argc, char *argv[]) { - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setHighDpiScaleFactorRoundingPolicy( Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QApplication app(argc, argv); @@ -329,9 +326,9 @@ int client_main(int argc, char *argv[]) #ifdef ENABLE_NLS (void) bindtextdomain("freeciv21-nations", get_locale_dir()); #endif - init_character_encodings(gui_character_encoding, gui_use_transliteration); + init_character_encodings(); #ifdef ENABLE_NLS - bind_textdomain_codeset("freeciv21-nations", get_internal_encoding()); + bind_textdomain_codeset("freeciv21-nations", "UTF-8"); #endif QCommandLineParser parser; diff --git a/client/climisc.cpp b/client/climisc.cpp index 1131c4fe4f..d4130f0d61 100644 --- a/client/climisc.cpp +++ b/client/climisc.cpp @@ -57,13 +57,11 @@ #include "options.h" #include "packhand.h" #include "page_game.h" +#include "qtg_cxxside.h" #include "tileset/tilespec.h" #include "views/view_map.h" #include "views/view_map_common.h" -// gui-qt -#include "qtg_cxxside.h" - extern void flush_dirty_overview(); /** Remove unit, client end version diff --git a/client/clinet.cpp b/client/clinet.cpp index 3f7e01d420..2cc1815924 100644 --- a/client/clinet.cpp +++ b/client/clinet.cpp @@ -40,8 +40,6 @@ #include "governor.h" #include "options.h" #include "packhand.h" - -// gui-qt #include "qtg_cxxside.h" // In autoconnect mode, try to connect to once a second diff --git a/client/connectdlg.cpp b/client/connectdlg.cpp index 8a57d9c41b..88665cc37d 100644 --- a/client/connectdlg.cpp +++ b/client/connectdlg.cpp @@ -12,9 +12,8 @@ #include "game.h" // client #include "chatline_common.h" -#include "packhand_gen.h" -// gui-qt #include "fc_client.h" +#include "packhand_gen.h" #include "page_network.h" #include "pages_g.h" #include "qtg_cxxside.h" diff --git a/client/connectdlg_common.cpp b/client/connectdlg_common.cpp index 7515b6099e..38aa793e6d 100644 --- a/client/connectdlg_common.cpp +++ b/client/connectdlg_common.cpp @@ -21,6 +21,7 @@ #include #include +#include #ifdef FREECIV_MSWINDOWS #include @@ -41,8 +42,6 @@ #include "clinet.h" // connect_to_server() #include "connectdlg_common.h" #include "packhand_gen.h" - -// gui-qt #include "qtg_cxxside.h" #define WAIT_BETWEEN_TRIES 100000 // usecs @@ -50,7 +49,7 @@ bool server_quitting = false; -static char challenge_fullname[MAX_LEN_PATH]; +static QString challenge_fullname{}; static bool client_has_hack = false; int internal_server_port; @@ -318,9 +317,9 @@ static void randomize_string(char *str, size_t n) and then sends the string to the server. If the server can open and read the string, then the client is given hack access. */ -void send_client_wants_hack(const char *filename) +void send_client_wants_hack(const QString &filename) { - if (filename[0] != '\0') { + if (!filename.isEmpty()) { struct packet_single_want_hack_req req; struct section_file *file; auto sdir = freeciv_storage_dir(); @@ -334,9 +333,7 @@ void send_client_wants_hack(const char *filename) } QDir().mkpath(sdir); - - fc_snprintf(challenge_fullname, sizeof(challenge_fullname), "%s/%s", - qUtf8Printable(sdir), filename); + challenge_fullname = sdir + QStringLiteral("/") + filename; // generate an authentication token randomize_string(req.token, sizeof(req.token)); @@ -345,7 +342,7 @@ void send_client_wants_hack(const char *filename) secfile_insert_str(file, req.token, "challenge.token"); if (!secfile_save(file, challenge_fullname)) { qCritical("Couldn't write token to temporary file: %s", - challenge_fullname); + qUtf8Printable(challenge_fullname)); } secfile_destroy(file); @@ -360,11 +357,12 @@ void send_client_wants_hack(const char *filename) void handle_single_want_hack_reply(bool you_have_hack) { // remove challenge file - if (challenge_fullname[0] != '\0') { - if (fc_remove(challenge_fullname) == -1) { - qCritical("Couldn't remove temporary file: %s", challenge_fullname); + if (!challenge_fullname.isEmpty()) { + if (!QFile::remove(challenge_fullname)) { + qCritical("Couldn't remove temporary file: %s", + qUtf8Printable(challenge_fullname)); } - challenge_fullname[0] = '\0'; + challenge_fullname.clear(); } if (you_have_hack) { diff --git a/client/connectdlg_common.h b/client/connectdlg_common.h index 1b610e2dec..21a80efb56 100644 --- a/client/connectdlg_common.h +++ b/client/connectdlg_common.h @@ -19,7 +19,7 @@ void client_kill_server(bool force); bool is_server_running(); bool can_client_access_hack(); -void send_client_wants_hack(const char *filename); +void send_client_wants_hack(const QString &filename); void send_save_game(const char *filename); void set_ruleset(const char *ruleset); diff --git a/client/control.cpp b/client/control.cpp index 32efafe44b..933d1ad04b 100644 --- a/client/control.cpp +++ b/client/control.cpp @@ -37,23 +37,20 @@ // client #include "audio/audio.h" +#include "chatline.h" #include "client_main.h" #include "climap.h" #include "climisc.h" +#include "control.h" #include "editor.h" #include "goto.h" #include "governor.h" #include "options.h" #include "overview_common.h" -#include "tileset/tilespec.h" -#include "update_queue.h" - -#include "control.h" - -// gui-qt -#include "chatline.h" #include "page_game.h" #include "qtg_cxxside.h" +#include "tileset/tilespec.h" +#include "update_queue.h" #include "views/view_map.h" struct client_disband_unit_data { diff --git a/client/dialogs.cpp b/client/dialogs.cpp index 0a54bc1054..b0235e6953 100644 --- a/client/dialogs.cpp +++ b/client/dialogs.cpp @@ -39,22 +39,21 @@ #include "chatline_common.h" #include "client_main.h" #include "control.h" -#include "packhand.h" -#include "text.h" -#include "tileset/tilespec.h" -#include "views/view_map_common.h" -// gui-qt - awesome client #include "fc_client.h" #include "fonts.h" #include "helpdlg.h" #include "hudwidget.h" #include "icons.h" +#include "packhand.h" #include "page_game.h" #include "qtg_cxxside.h" +#include "text.h" #include "tileset/sprite.h" +#include "tileset/tilespec.h" #include "unithudselector.h" #include "unitselect.h" #include "views/view_map.h" +#include "views/view_map_common.h" #include "widgets/report_widget.h" // Locations for non action enabler controlled buttons. diff --git a/client/dialogs.h b/client/dialogs.h index 8f48999c1a..4d3250e421 100644 --- a/client/dialogs.h +++ b/client/dialogs.h @@ -17,7 +17,6 @@ #include "fc_types.h" // client #include "dialogs_g.h" -// gui-qt #include "hudwidget.h" #include "widgets/decorations.h" diff --git a/client/diplodlg.cpp b/client/diplodlg.cpp index e9e7fb2f14..e0e38afffc 100644 --- a/client/diplodlg.cpp +++ b/client/diplodlg.cpp @@ -34,7 +34,6 @@ // client #include "client_main.h" #include "colors_common.h" -// gui-qt #include "diplodlg_g.h" #include "fc_client.h" #include "icons.h" diff --git a/client/editor.cpp b/client/editor.cpp index 68290430ee..0576f54f88 100644 --- a/client/editor.cpp +++ b/client/editor.cpp @@ -30,14 +30,10 @@ #include "control.h" #include "editor.h" #include "mapctrl_common.h" -#include "tileset/tilespec.h" -#include "views/view_map_geometry.h" - -/* client/include */ #include "mapview_g.h" - -// gui-qt #include "qtg_cxxside.h" +#include "tileset/tilespec.h" +#include "views/view_map_geometry.h" enum selection_modes { SELECTION_MODE_NEW = 0, diff --git a/client/endgamereport.cpp b/client/endgamereport.cpp index b6b91bdf36..71724bbf89 100644 --- a/client/endgamereport.cpp +++ b/client/endgamereport.cpp @@ -16,10 +16,9 @@ // common #include "nation.h" // client -#include "tileset/sprite.h" -// gui-qt #include "fc_client.h" #include "page_game.h" +#include "tileset/sprite.h" /** Constructor for endgame report diff --git a/client/fc_client.cpp b/client/fc_client.cpp index 6ab6481e59..265b027610 100644 --- a/client/fc_client.cpp +++ b/client/fc_client.cpp @@ -12,13 +12,14 @@ // Qt #include #include +#include #include #include #include #include #include #include -#include + // utility #include "fcintl.h" // common @@ -29,8 +30,6 @@ #include "client_main.h" #include "clinet.h" #include "connectdlg_common.h" -#include "update_queue.h" -// gui-qt #include "fonts.h" #include "gui_main.h" #include "icons.h" @@ -45,6 +44,7 @@ #include "page_scenario.h" #include "tileset/sprite.h" #include "top_bar.h" +#include "update_queue.h" #include "views/view_map.h" #include "voteinfo_bar.h" @@ -60,7 +60,7 @@ fc_client::fc_client() : QMainWindow(), current_file(QLatin1String("")) setWindowFlags(Qt::FramelessWindowHint); setWindowState(Qt::WindowFullScreen); #endif - QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); + // QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); status_bar_queue.clear(); for (int i = 0; i <= PAGE_GAME; i++) { pages_layout[i] = nullptr; @@ -71,6 +71,8 @@ fc_client::fc_client() : QMainWindow(), current_file(QLatin1String("")) QApplication::setFont(fcFont::instance()->getFont(fonts::default_font)); QString path; + setWindowTitle(_("Freeciv21")); + central_wdg = new QWidget; central_layout = new QStackedLayout; @@ -134,7 +136,6 @@ fc_client::~fc_client() } /** - Main part of gui-qt. This is not called simply 'fc_client::main()', since SDL includes ould sometimes cause 'main' to be considered an macro that expands to 'SDL_main' @@ -152,7 +153,6 @@ void fc_client::fc_main(QApplication *qapp) startTimer(TIMER_INTERVAL); connect(qapp, &QCoreApplication::aboutToQuit, this, &fc_client::closing); - qapp->setAttribute(Qt::AA_UseHighDpiPixmaps); qapp->exec(); free_mapcanvas_and_overview(); @@ -687,6 +687,43 @@ void fc_client::start_new_game() } } +/** + * Load the modpack-installer from the start menu + */ +void fc_client::load_modpack() +{ + output_window_append(ftc_client, _("Starting the modpack installer...")); + + const QString storage = freeciv_storage_dir(); + if (storage == nullptr) { + output_window_append(ftc_client, + _("Cannot find Freeciv21 storage directory")); + output_window_append( + ftc_client, + _("You'll have to start the modpack installer manually. Sorry...")); + return; + } + + // Look for a modpack installer binary + const QString modpack_name = QStringLiteral("freeciv21-modpack-qt"); + + // First next to the client binary + // NOTE On Windows findExecutable adds the .exe automatically + QString location = QStandardPaths::findExecutable( + modpack_name, {QCoreApplication::applicationDirPath()}); + if (location.isEmpty()) { + // Then in PATH + location = QStandardPaths::findExecutable(modpack_name); + } + + // Start it + qInfo(_("Starting freeciv21-modpack-qt at %s"), qUtf8Printable(location)); + + QProcess *modProcess = new QProcess(this); + QStringList arguments; + modProcess->start(location, arguments); +} + /** Contructor for corner widget (used for menubar) */ diff --git a/client/fc_client.h b/client/fc_client.h index aacf4f102e..661912d752 100644 --- a/client/fc_client.h +++ b/client/fc_client.h @@ -17,12 +17,11 @@ // common #include "packets.h" // client +#include "chatline.h" +#include "menu.h" #include "pages_g.h" #include "servers.h" #include "tileset/tilespec.h" -// gui-qt -#include "chatline.h" -#include "menu.h" #include "tradecalculation.h" class QApplication; @@ -140,6 +139,7 @@ public slots: void start_from_file(const QString &file); void start_new_game(); void switch_page(int i); + void load_modpack(); private: void create_loading_page(); diff --git a/client/gotodlg.cpp b/client/gotodlg.cpp index 39620adc26..70f212a4f0 100644 --- a/client/gotodlg.cpp +++ b/client/gotodlg.cpp @@ -24,14 +24,13 @@ // client #include "client_main.h" #include "control.h" +#include "fc_client.h" #include "goto.h" +#include "page_game.h" #include "text.h" +#include "tileset/sprite.h" #include "views/view_map.h" #include "views/view_map_common.h" -// gui-qt -#include "fc_client.h" -#include "page_game.h" -#include "tileset/sprite.h" /** Constructor for goto_dialog diff --git a/client/gui_main.cpp b/client/gui_main.cpp index 6f6d48c06d..49d2031cfb 100644 --- a/client/gui_main.cpp +++ b/client/gui_main.cpp @@ -21,31 +21,28 @@ // client #include "client_main.h" #include "clinet.h" -#include "mapview_g.h" -#include "options.h" -#include "themes_common.h" -#include "tileset/sprite.h" -#include "tileset/tilespec.h" -#include "views/view_map_common.h" -// gui-qt #include "fc_client.h" #include "fonts.h" #include "helpdlg.h" #include "hudwidget.h" +#include "mapview_g.h" #include "messagewin.h" +#include "options.h" #include "page_game.h" #include "page_pregame.h" #include "qtg_cxxside.h" +#include "themes_common.h" +#include "tileset/sprite.h" +#include "tileset/tilespec.h" #include "unitselect.h" #include "views/view_map.h" +#include "views/view_map_common.h" #include "widgets/report_widget.h" void real_science_report_dialog_update(void *); extern void city_font_update(); -const bool gui_use_transliteration = false; -const char *const gui_character_encoding = "UTF-8"; const char *client_string = "gui-qt"; static fc_client *freeciv_qt; diff --git a/client/helpdlg.cpp b/client/helpdlg.cpp index 14bd95bd89..5cfa329d7b 100644 --- a/client/helpdlg.cpp +++ b/client/helpdlg.cpp @@ -31,13 +31,12 @@ #include "canvas.h" #include "client_main.h" #include "climisc.h" -#include "views/view_map_common.h" -// gui-qt #include "fc_client.h" #include "fonts.h" #include "helpdlg.h" #include "tileset/sprite.h" #include "tileset/tilespec.h" +#include "views/view_map_common.h" #define MAX_HELP_TEXT_SIZE 8192 #define REQ_LABEL_NEVER _("(Never)") diff --git a/client/helpdlg.h b/client/helpdlg.h index 5bc810de8b..e109579e3f 100644 --- a/client/helpdlg.h +++ b/client/helpdlg.h @@ -15,9 +15,8 @@ // common #include "extras.h" // client -#include "helpdata.h" -// gui-qt #include "dialogs.h" +#include "helpdata.h" class QCloseEvent; class QFrame; diff --git a/client/hudwidget.cpp b/client/hudwidget.cpp index 320f7cb56d..7cda8dab07 100644 --- a/client/hudwidget.cpp +++ b/client/hudwidget.cpp @@ -29,19 +29,18 @@ #include "unitlist.h" // client #include "calendar.h" -#include "client_main.h" -#include "goto.h" -#include "text.h" -#include "views/view_map_common.h" -// gui-qt #include "canvas.h" +#include "client_main.h" #include "fc_client.h" #include "fonts.h" +#include "goto.h" #include "icons.h" #include "page_game.h" +#include "text.h" #include "tileset/sprite.h" #include "top_bar.h" #include "views/view_map.h" +#include "views/view_map_common.h" #include "widgets/decorations.h" static QString popup_terrain_info(struct tile *ptile); @@ -867,7 +866,7 @@ void hud_action::leaveEvent(QEvent *event) /** Enter event for hud_action, used to get status of pixmap higlight */ -void hud_action::enterEvent(QEvent *event) +void hud_action::enterEvent(QEnterEvent *event) { focus = true; update(); @@ -1568,7 +1567,7 @@ void hud_unit_combat::leaveEvent(QEvent *event) /** Leave event for hud unit combat. Shows highlight. */ -void hud_unit_combat::enterEvent(QEvent *event) +void hud_unit_combat::enterEvent(QEnterEvent *event) { focus = true; update(); diff --git a/client/hudwidget.h b/client/hudwidget.h index c820ca45d8..fc3e85907c 100644 --- a/client/hudwidget.h +++ b/client/hudwidget.h @@ -19,7 +19,6 @@ #include // utility #include "fc_types.h" -// gui-qt #include "shortcuts.h" class QComboBox; @@ -173,7 +172,7 @@ class hud_action : public QWidget { void mousePressEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *event) override; void leaveEvent(QEvent *event) override; - void enterEvent(QEvent *event) override; + void enterEvent(QEnterEvent *event) override; private slots: void mouse_clicked(); void mouse_right_clicked(); @@ -261,7 +260,7 @@ class hud_unit_combat : public QWidget { void paintEvent(QPaintEvent *event) override; void mousePressEvent(QMouseEvent *e) override; void leaveEvent(QEvent *event) override; - void enterEvent(QEvent *event) override; + void enterEvent(QEnterEvent *event) override; private: void init_images(bool redraw = false); diff --git a/client/icons.cpp b/client/icons.cpp index c8f24cc81c..575c98cc2c 100644 --- a/client/icons.cpp +++ b/client/icons.cpp @@ -127,10 +127,10 @@ QIcon fcIcons::getIcon(const QString &id) QIcon icon; // Try custom icon from theme. - icon.addFile( - fileinfoname(get_data_dirs(), - qUtf8Printable(QStringLiteral("themes/gui-qt/%1/%2.svg") - .arg(current_theme, id)))); + icon.addFile(fileinfoname( + get_data_dirs(), + qUtf8Printable( + QStringLiteral("themes/%1/%2.svg").arg(current_theme, id)))); if (!icon.isNull()) { return icon; } @@ -138,24 +138,24 @@ QIcon fcIcons::getIcon(const QString &id) // Try SVG from icons dir. QString path = fileinfoname( get_data_dirs(), - qUtf8Printable(QStringLiteral("themes/gui-qt/icons/%1.svg").arg(id))); + qUtf8Printable(QStringLiteral("themes/icons/%1.svg").arg(id))); if (!path.isEmpty()) { // Special icon engine for theme colorization. return QIcon(new icon_engine(path)); } // Fall back to PNG. - icon.addFile( - fileinfoname(get_data_dirs(), - qUtf8Printable(QStringLiteral("themes/gui-qt/%1/%2.png") - .arg(current_theme, id)))); + icon.addFile(fileinfoname( + get_data_dirs(), + qUtf8Printable( + QStringLiteral("themes/%1/%2.png").arg(current_theme, id)))); if (!icon.isNull()) { return icon; } icon.addFile(fileinfoname( get_data_dirs(), - qUtf8Printable(QStringLiteral("themes/gui-qt/icons/%1.png").arg(id)))); + qUtf8Printable(QStringLiteral("themes/icons/%1.png").arg(id)))); return icon; } @@ -174,7 +174,7 @@ QPixmap *fcIcons::getPixmap(const QString &id) if (QPixmapCache::find(id, pm)) { return pm; } - str = QStringLiteral("themes/gui-qt/"); + str = QStringLiteral("themes/"); png_bytes = QString(str + current_theme + "/" + id + ".png").toLocal8Bit(); status = pm->load(fileinfoname(get_data_dirs(), png_bytes.data())); @@ -196,7 +196,7 @@ QString fcIcons::getPath(const QString &id) QString str; QByteArray png_bytes; - str = QStringLiteral("themes/gui-qt/icons/"); + str = QStringLiteral("themes/icons/"); png_bytes = QString(str + id + ".png").toLocal8Bit(); return fileinfoname(get_data_dirs(), png_bytes.data()); diff --git a/client/icons.h b/client/icons.h index 8572f7b336..8b27e490e5 100644 --- a/client/icons.h +++ b/client/icons.h @@ -9,10 +9,12 @@ **************************************************************************/ #pragma once +#include #include #include + /**************************************************************************** - Class helping reading icons/pixmaps from themes/gui-qt/icons folder + Class helping reading icons/pixmaps from themes/icons folder ****************************************************************************/ class fcIcons { Q_DISABLE_COPY(fcIcons); diff --git a/client/include/themes_g.h b/client/include/themes_g.h index 2099ab4eb5..45bf68d930 100644 --- a/client/include/themes_g.h +++ b/client/include/themes_g.h @@ -10,8 +10,9 @@ received a copy of the GNU General Public License along with Freeciv21. ***********************************************************************/ #pragma once +#include + class QString; -class QStringList; void gui_load_theme(const QString &directory, const QString &theme_name); QStringList get_useable_themes_in_directory(QString &directory); diff --git a/client/listener.h b/client/listener.h index 6bf5dccd80..a4dab190e8 100644 --- a/client/listener.h +++ b/client/listener.h @@ -10,6 +10,7 @@ #pragma once #include +#include /*************************************************************************** Helper template to connect C and C++ code. @@ -26,13 +27,6 @@ }; ~~~~~ - The listener needs some static data. Declaring it is as simple as putting - a macro in some source file: - - ~~~~~{.cpp} - FC_CPP_DECLARE_LISTENER(foo_listener) - ~~~~~ - Then, you call the listeners from the implementation of the C interface: ~~~~~{.cpp} @@ -103,7 +97,7 @@ template class listener { private: // All instances of type_t that have called listen(). - static std::set instances; + inline static std::set *> instances{}; protected: explicit listener(); @@ -112,22 +106,10 @@ template class listener { void listen(); public: - template static void invoke(_member_fct_ function); - - template - static void invoke(_member_fct_ function, _arg1_t_ arg); - - template - static void invoke(_member_fct_ function, _arg1_t_ arg1, _arg2_t_ arg2); + template + static void invoke(_member_fct_ function, _args_ &&...args); }; -/*************************************************************************** - Macro to declare the static data needed by listener<> classes -***************************************************************************/ -#define FC_CPP_DECLARE_LISTENER(_type_) \ - template <> \ - std::set<_type_ *> listener<_type_>::instances = std::set<_type_ *>(); - /*************************************************************************** Constructor ***************************************************************************/ @@ -140,7 +122,7 @@ template void listener<_type_>::listen() { // If you get an error here, your listener likely doesn't inherit from the // listener<> correctly. See the class documentation. - instances.insert(dynamic_cast(this)); + instances.insert(this); } /*************************************************************************** @@ -148,66 +130,22 @@ template void listener<_type_>::listen() ***************************************************************************/ template listener<_type_>::~listener() { - instances.erase(dynamic_cast(this)); -} - -/*************************************************************************** - Invokes a member function on all instances of an listener type. Template - parameters are meant to be automatically deduced. - - Zero-parameter overload. - - @param function The member function to call -***************************************************************************/ -template -template -void listener<_type_>::invoke(_member_fct_ function) -{ - typename std::set::iterator it = instances.begin(); - typename std::set::iterator end = instances.end(); - for (; it != end; ++it) { - ((*it)->*function)(); - } -} - -/*************************************************************************** - Invokes a member function on all instances of an listener type. Template - parameters are meant to be automatically deduced. - - One-parameter overload. - - @param function The member function to call - @param arg The argument to call the function with -***************************************************************************/ -template -template -void listener<_type_>::invoke(_member_fct_ function, _arg1_t_ arg) -{ - typename std::set::iterator it = instances.begin(); - typename std::set::iterator end = instances.end(); - for (; it != end; ++it) { - ((*it)->*function)(arg); - } + instances.erase(this); } /*************************************************************************** - Invokes a member function on all instances of an listener type. Template + Invokes a member function on all instances of a listener type. Template parameters are meant to be automatically deduced. - Two-parameters overload. - @param function The member function to call - @param arg1 The first argument to pass to the function - @param arg2 The second argument to pass to the function + @param args Arguments to pass ot the function. ***************************************************************************/ template -template -void listener<_type_>::invoke(_member_fct_ function, _arg1_t_ arg1, - _arg2_t_ arg2) +template +void listener<_type_>::invoke(_member_fct_ function, _args_ &&...args) { - typename std::set::iterator it = instances.begin(); - typename std::set::iterator end = instances.end(); - for (; it != end; ++it) { - ((*it)->*function)(arg1, arg2); + for (auto &instance : instances) { + (dynamic_cast(instance)->*function)( + std::forward<_args_>(args)...); } } diff --git a/client/luaconsole.cpp b/client/luaconsole.cpp index 285ba933d3..a91b2962c9 100644 --- a/client/luaconsole.cpp +++ b/client/luaconsole.cpp @@ -17,11 +17,10 @@ // common #include "featured_text.h" #include "luaconsole_g.h" -/* client/luascript */ -#include "script_client.h" -// gui-qt +// client #include "chatline.h" #include "fc_client.h" +#include "script_client.h" QString qlua_filename; diff --git a/client/map_updates_handler.cpp b/client/map_updates_handler.cpp index 81969cb92d..58d154b0ce 100644 --- a/client/map_updates_handler.cpp +++ b/client/map_updates_handler.cpp @@ -9,8 +9,6 @@ #include "options.h" #include "tileset/tilespec.h" -FC_CPP_DECLARE_LISTENER(freeciv::map_updates_handler) - namespace freeciv { /** diff --git a/client/mapctrl.cpp b/client/mapctrl.cpp index e25bd2912c..ac12497e1e 100644 --- a/client/mapctrl.cpp +++ b/client/mapctrl.cpp @@ -17,23 +17,22 @@ #include "map.h" // client #include "chatline_common.h" +#include "citydlg.h" #include "citydlg_common.h" #include "client_main.h" +#include "fc_client.h" #include "mapctrl.h" #include "mapctrl_common.h" +#include "messagewin.h" +#include "page_game.h" +#include "shortcuts.h" #include "themes_common.h" #include "tile.h" #include "tileset/tilespec.h" #include "unit.h" -#include "views/view_map_common.h" -// gui-qt -#include "citydlg.h" -#include "fc_client.h" -#include "messagewin.h" -#include "page_game.h" -#include "shortcuts.h" #include "unitselect.h" #include "views/view_map.h" +#include "views/view_map_common.h" extern void qload_lua_script(); extern void qreload_lua_script(); diff --git a/client/menu.cpp b/client/menu.cpp index c8992a38c2..e19daf50f0 100644 --- a/client/menu.cpp +++ b/client/menu.cpp @@ -31,6 +31,7 @@ #include "road.h" #include "unit.h" // client +#include "audio/audio.h" #include "citybar.h" #include "cityrep_g.h" #include "client_main.h" @@ -38,19 +39,13 @@ #include "clinet.h" #include "connectdlg_common.h" #include "control.h" -#include "helpdlg.h" -#include "mapctrl_g.h" -#include "ratesdlg_g.h" -#include "renderer.h" -#include "repodlgs_g.h" -#include "tileset/tilespec.h" -#include "views/view_map_common.h" -// gui-qt #include "dialogs.h" #include "fc_client.h" #include "gotodlg.h" #include "gui_main.h" +#include "helpdlg.h" #include "hudwidget.h" +#include "mapctrl_g.h" #include "messageoptions.h" #include "messagewin.h" #include "minimap.h" @@ -59,12 +54,17 @@ #include "page_pregame.h" #include "qtg_cxxside.h" #include "ratesdlg.h" +#include "ratesdlg_g.h" +#include "renderer.h" +#include "repodlgs_g.h" #include "shortcuts.h" #include "spaceshipdlg.h" #include "tileset/sprite.h" +#include "tileset/tilespec.h" #include "top_bar.h" #include "unithudselector.h" #include "views/view_map.h" +#include "views/view_map_common.h" #include "views/view_nations.h" #include "views/view_units.h" @@ -575,6 +575,8 @@ void mr_menu::setup_menus() connect(act, &QAction::triggered, this, &mr_menu::shortcut_options); act = menu->addAction(_("Load Another Tileset")); connect(act, &QAction::triggered, this, &mr_menu::tileset_custom_load); + act = menu->addAction(_("Add Modpacks")); + connect(act, &QAction::triggered, this, &mr_menu::add_modpacks); act = menu->addAction(_("Tileset Debugger")); connect(act, &QAction::triggered, queen()->mapview_wdg, &map_view::show_debugger); @@ -2660,6 +2662,11 @@ void mr_menu::tileset_custom_load() dialog->show(); } +/** + * Slot for loading modpack installer + */ +void mr_menu::add_modpacks() { king()->load_modpack(); } + /** Slot for loading new tileset */ diff --git a/client/menu.h b/client/menu.h index 70885f71da..69a6b51375 100644 --- a/client/menu.h +++ b/client/menu.h @@ -203,6 +203,7 @@ private slots: void save_image(); void tileset_custom_load(); void load_new_tileset(); + void add_modpacks(); void back_to_menu(); void quit_game(); diff --git a/client/messageoptions.cpp b/client/messageoptions.cpp index 64149ea2a2..4ac2ee9389 100644 --- a/client/messageoptions.cpp +++ b/client/messageoptions.cpp @@ -19,9 +19,8 @@ // utility #include "log.h" // client -#include "options.h" -// gui-qt #include "fc_client.h" +#include "options.h" #include "page_game.h" /** diff --git a/client/messagewin.cpp b/client/messagewin.cpp index 5889c50c65..92b40153b7 100644 --- a/client/messagewin.cpp +++ b/client/messagewin.cpp @@ -21,13 +21,11 @@ // client #include "client_main.h" -#include "messagewin_common.h" -#include "update_queue.h" - -// gui-qt #include "fc_client.h" +#include "messagewin_common.h" #include "page_game.h" #include "tileset/sprite.h" +#include "update_queue.h" #include "views/view_map.h" /** @@ -109,7 +107,7 @@ void message_widget::item_selected(const QItemSelection &sl, /** Mouse entered message_widget */ -void message_widget::enterEvent(QEvent *event) +void message_widget::enterEvent(QEnterEvent *event) { setCursor(Qt::ArrowCursor); } @@ -128,7 +126,7 @@ void message_widget::leaveEvent(QEvent *event) void message_widget::paintEvent(QPaintEvent *event) { QStyleOption opt; - opt.init(this); + opt.initFrom(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } diff --git a/client/messagewin.h b/client/messagewin.h index 27df0b0010..d6a4cea1a3 100644 --- a/client/messagewin.h +++ b/client/messagewin.h @@ -43,7 +43,7 @@ class message_widget : public resizable_widget { QGridLayout *layout; protected: - void enterEvent(QEvent *event) override; + void enterEvent(QEnterEvent *event) override; void leaveEvent(QEvent *event) override; void paintEvent(QPaintEvent *event) override; diff --git a/client/messagewin_common.cpp b/client/messagewin_common.cpp index 75556251ca..2b99487c08 100644 --- a/client/messagewin_common.cpp +++ b/client/messagewin_common.cpp @@ -23,15 +23,13 @@ // client #include "client_main.h" +#include "messagewin.h" #include "messagewin_common.h" #include "options.h" #include "page_game.h" #include "update_queue.h" #include "views/view_map.h" -// gui-qt -#include "messagewin.h" - static struct message **messages = nullptr; static int messages_total = 0; static int messages_alloc = 0; diff --git a/client/minimap.cpp b/client/minimap.cpp index 263b0430e3..e924f0a57f 100644 --- a/client/minimap.cpp +++ b/client/minimap.cpp @@ -18,11 +18,9 @@ // client #include "client_main.h" +#include "fc_client.h" #include "minimap_panel.h" #include "overview_common.h" - -// gui-qt -#include "fc_client.h" #include "page_game.h" #include "qtg_cxxside.h" #include "views/view_map.h" diff --git a/client/minimap.h b/client/minimap.h index deecff51ca..eaefe6e7a3 100644 --- a/client/minimap.h +++ b/client/minimap.h @@ -15,8 +15,9 @@ // Qt #include #include -// gui-qt is The One +// client #include "widgets/decorations.h" + class QImage; class QMouseEvent; class QMoveEvent; diff --git a/client/optiondlg.cpp b/client/optiondlg.cpp index f5b3a4806a..db39d71773 100644 --- a/client/optiondlg.cpp +++ b/client/optiondlg.cpp @@ -22,10 +22,9 @@ // utility #include "log.h" // client -#include "options.h" -// gui-qt #include "fc_client.h" #include "optiondlg.h" +#include "options.h" #include "page_pregame.h" enum { diff --git a/client/options.cpp b/client/options.cpp index 137e6586ac..8af9cebda7 100644 --- a/client/options.cpp +++ b/client/options.cpp @@ -55,19 +55,16 @@ #include "governor.h" #include "mapctrl_common.h" #include "music.h" +#include "options.h" #include "overview_common.h" #include "packhand_gen.h" +#include "qtg_cxxside.h" #include "themes_common.h" #include "tileset/tilespec.h" #include "views/view_cities_data.h" #include "views/view_map_common.h" #include "views/view_nations_data.h" -#include "options.h" - -// gui-qt -#include "qtg_cxxside.h" - typedef QHash optionsHash; typedef QHash dialOptionsHash; @@ -3788,7 +3785,6 @@ static const char *get_last_option_file_name(bool *allow_digital_boolean) fc_strlcpy(name_buffer, OPTION_FILE_NAME, sizeof(name_buffer)); #else int major, minor; - struct stat buf; name = freeciv_storage_dir(); if (name.isEmpty()) { @@ -3807,7 +3803,7 @@ static const char *get_last_option_file_name(bool *allow_digital_boolean) fc_snprintf(name_buffer, sizeof(name_buffer), "%s/freeciv-client-rc-%d.%d", qUtf8Printable(name), major, minor); - if (0 == fc_stat(name_buffer, &buf)) { + if (QFileInfo::exists(name_buffer)) { if (MAJOR_NEW_OPTION_FILE_NAME != major || MINOR_NEW_OPTION_FILE_NAME != minor) { qInfo(_("Didn't find '%s' option file, " @@ -3831,7 +3827,7 @@ static const char *get_last_option_file_name(bool *allow_digital_boolean) fc_snprintf(name_buffer, sizeof(name_buffer), "%s/.freeciv-client-rc-%d.%d", qUtf8Printable(QDir::homePath()), major, minor); - if (0 == fc_stat(name_buffer, &buf)) { + if (QFileInfo::exists(name_buffer)) { qInfo(_("Didn't find '%s' option file, " "loading from '%s' instead."), get_current_option_file_name() @@ -3848,7 +3844,7 @@ static const char *get_last_option_file_name(bool *allow_digital_boolean) // Try with the old one. fc_snprintf(name_buffer, sizeof(name_buffer), "%s/%s", qUtf8Printable(name), OLD_OPTION_FILE_NAME); - if (0 == fc_stat(name_buffer, &buf)) { + if (QFileInfo::exists(name_buffer)) { qInfo(_("Didn't find '%s' option file, " "loading from '%s' instead."), get_current_option_file_name(), OLD_OPTION_FILE_NAME); diff --git a/client/options.h b/client/options.h index 89dc98fbf7..ac79380398 100644 --- a/client/options.h +++ b/client/options.h @@ -160,7 +160,6 @@ struct client_options { }; char mapimg_filename[512] = "mapimage filename"; -// gui-qt client specific options. #define FC_QT_DEFAULT_THEME_NAME "NightStalker" bool gui_qt_fullscreen = true; bool gui_qt_show_preview = true; diff --git a/client/packhand.cpp b/client/packhand.cpp index 5e483a2d03..c36029a6a8 100644 --- a/client/packhand.cpp +++ b/client/packhand.cpp @@ -87,11 +87,13 @@ #include "editor.h" #include "goto.h" // client_goto_init() #include "governor.h" +#include "helpdlg.h" #include "messagewin_common.h" #include "music.h" #include "options.h" #include "overview_common.h" #include "page_game.h" +#include "qtg_cxxside.h" #include "tileset/tilespec.h" #include "update_queue.h" #include "views/view_map.h" @@ -99,10 +101,6 @@ #include "views/view_nations_data.h" #include "voteinfo.h" -// gui-qt -#include "helpdlg.h" -#include "qtg_cxxside.h" - /* client/luascript */ #include "script_client.h" @@ -353,7 +351,7 @@ void handle_server_join_reply(bool you_can_join, const char *message, } client_info._obsolete = 5; // Old value for gui_type(GUI_QT) - client_info.emerg_version = EMERGENCY_VERSION; + client_info._obsolete2 = 0; qstrncpy(client_info.distribution, FREECIV_DISTRIBUTOR, sizeof(client_info.distribution)); send_packet_client_info(&client.conn, &client_info); diff --git a/client/page_game.cpp b/client/page_game.cpp index 961bf10c72..af5c63334a 100644 --- a/client/page_game.cpp +++ b/client/page_game.cpp @@ -27,14 +27,9 @@ #include "government.h" #include "repodlgs_g.h" // client -#include "client_main.h" -#include "text.h" -#include "tileset/tilespec.h" -#include "views/view_map_common.h" - -// gui-qt - Eye of Storm #include "chatline.h" #include "citydlg.h" +#include "client_main.h" #include "fc_client.h" #include "gotodlg.h" #include "hudwidget.h" @@ -44,8 +39,11 @@ #include "minimap.h" #include "minimap_panel.h" #include "ratesdlg.h" +#include "text.h" +#include "tileset/tilespec.h" #include "top_bar.h" #include "views/view_map.h" +#include "views/view_map_common.h" #include "views/view_nations.h" #include "views/view_units.h" diff --git a/client/page_main.cpp b/client/page_main.cpp index 75f4295f35..bfe49339cb 100644 --- a/client/page_main.cpp +++ b/client/page_main.cpp @@ -13,13 +13,11 @@ #include "fcintl.h" // common #include "version.h" -// gui-qt +// client #include "fc_client.h" page_main::page_main(QWidget *parent, fc_client *gui) : QWidget(parent) { - QString msgbuf; - QString beta; ui.setupUi(this); ui.btut->setText(_("Tutorial")); ui.bstart->setText(_("Start new game")); @@ -28,11 +26,14 @@ page_main::page_main(QWidget *parent, fc_client *gui) : QWidget(parent) ui.bload->setText(_("Load saved game")); ui.bconnect->setText(_("Connect to network game")); ui.bquit->setText(_("Quit")); + ui.bmods->setText(_("Mods")); connect(ui.btut, &QAbstractButton::clicked, gui, &fc_client::start_tutorial); connect(ui.bstart, &QAbstractButton::clicked, gui, &fc_client::start_new_game); + connect(ui.bmods, &QAbstractButton::clicked, gui, + &fc_client::load_modpack); connect(ui.bscenario, &QPushButton::clicked, [gui]() { gui->switch_page(PAGE_SCENARIO); }); connect(ui.boptions, &QAbstractButton::clicked, @@ -43,11 +44,8 @@ page_main::page_main(QWidget *parent, fc_client *gui) : QWidget(parent) connect(ui.bload, &QPushButton::clicked, [gui]() { gui->switch_page(PAGE_LOAD); }); - // TRANS: "version 2.6.0, Qt client" - msgbuf = QString(_("%1%2, Qt client")) - .arg(word_version()) - .arg(freeciv21_version()); - ui.lversion->setText(QString(msgbuf) + beta); + // TRANS: "Version 2.6.0" + ui.lversion->setText(QString(_("Version %1")).arg(freeciv21_version())); setLayout(ui.gridLayout); } diff --git a/client/page_main.ui b/client/page_main.ui index e8e59b7c94..0d6ba061eb 100644 --- a/client/page_main.ui +++ b/client/page_main.ui @@ -6,14 +6,14 @@ 0 0 - 821 - 397 + 850 + 500 - 821 - 397 + 850 + 500 @@ -25,7 +25,7 @@ 50 40 651 - 321 + 421 @@ -44,30 +44,53 @@ 5 - - + + - Tutorial + Start true - - + + - Start + lversion + + + Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing + + + + + + + Quit true - - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - Connect + Options true @@ -94,31 +117,51 @@ - - + + - Options + Connect true - - + + + + Mods + + + true + + + + + + + Tutorial + + + true + + + + + - Qt::Horizontal + Qt::Vertical - 40 - 20 + 20 + 40 - + Qt::Vertical @@ -130,26 +173,6 @@ - - - - Quit - - - true - - - - - - - lversion - - - Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing - - - diff --git a/client/page_network.cpp b/client/page_network.cpp index ac3295f68a..6d0aad4ce3 100644 --- a/client/page_network.cpp +++ b/client/page_network.cpp @@ -20,7 +20,6 @@ #include "chatline_common.h" #include "client_main.h" #include "clinet.h" -// gui-qt #include "dialogs.h" #include "fc_client.h" diff --git a/client/page_pregame.cpp b/client/page_pregame.cpp index 88f35ebba9..bf80604ae5 100644 --- a/client/page_pregame.cpp +++ b/client/page_pregame.cpp @@ -23,9 +23,8 @@ #include "connectdlg_common.h" #include "game.h" // client -#include "client_main.h" -// gui-qt #include "chatline.h" +#include "client_main.h" #include "dialogs.h" #include "fc_client.h" #include "icons.h" diff --git a/client/pregameoptions.cpp b/client/pregameoptions.cpp index 08575ccf5b..3723138e22 100644 --- a/client/pregameoptions.cpp +++ b/client/pregameoptions.cpp @@ -22,10 +22,9 @@ #include "chatline_common.h" #include "colors_common.h" #include "connectdlg_common.h" -// clienchatlint +// client #include "client_main.h" #include "climisc.h" -// gui-qt #include "dialogs.h" #include "fc_client.h" #include "icons.h" diff --git a/client/qtg_cxxside.h b/client/qtg_cxxside.h index e8bc62277a..233a00468e 100644 --- a/client/qtg_cxxside.h +++ b/client/qtg_cxxside.h @@ -12,9 +12,8 @@ // common #include "fc_types.h" // client -#include "tileset/tilespec.h" -// gui-qt #include "pages_g.h" +#include "tileset/tilespec.h" class QTcpSocket; diff --git a/client/ratesdlg.cpp b/client/ratesdlg.cpp index a2be4877bb..d683bb1b77 100644 --- a/client/ratesdlg.cpp +++ b/client/ratesdlg.cpp @@ -24,11 +24,10 @@ #include "packets.h" // client #include "client_main.h" -#include "tileset/tilespec.h" -// gui-qt #include "dialogs.h" #include "fc_client.h" #include "icons.h" +#include "tileset/tilespec.h" #include "widgets/multi_slider.h" static int scale_to_mult(const struct multiplier *pmul, int scale); diff --git a/client/ratesdlg.h b/client/ratesdlg.h index 6b0fc897dd..030618249d 100644 --- a/client/ratesdlg.h +++ b/client/ratesdlg.h @@ -12,7 +12,7 @@ // Qt #include #include -// gui-qt +// client #include "dialogs.h" #include "widgets/multi_slider.h" diff --git a/client/repodlgs_common.cpp b/client/repodlgs_common.cpp index 0af2821c42..d4ba621fbb 100644 --- a/client/repodlgs_common.cpp +++ b/client/repodlgs_common.cpp @@ -37,6 +37,9 @@ void get_economy_report_data(struct improvement_entry *entries, *num_entries_used = 0; *total_cost = 0; *total_income = 0; + QStringList redundant_cities; + redundant_cities.clear(); + QString str; if (nullptr == client.conn.playing) { return; @@ -53,6 +56,7 @@ void get_economy_report_data(struct improvement_entry *entries, cost += city_improvement_upkeep(pcity, pimprove); if (is_improvement_redundant(pcity, pimprove)) { redundant++; + redundant_cities.append(pcity->name); } } } @@ -62,11 +66,19 @@ void get_economy_report_data(struct improvement_entry *entries, continue; } + if (redundant == 0) { + str = (_("None")); + } else { + // Convert the string list we built to a standard string for display. + str = redundant_cities.join(", "); + } + entries[*num_entries_used].type = pimprove; entries[*num_entries_used].count = count; entries[*num_entries_used].redundant = redundant; entries[*num_entries_used].total_cost = cost; entries[*num_entries_used].cost = cost / count; + entries[*num_entries_used].city_names = str; (*num_entries_used)++; /* Currently there is no building expense under anarchy. It's diff --git a/client/repodlgs_common.h b/client/repodlgs_common.h index 899375385e..edb54bb999 100644 --- a/client/repodlgs_common.h +++ b/client/repodlgs_common.h @@ -13,12 +13,15 @@ #pragma once +#include + /* * Structure of data for the Economics View. See get_economy_report_data() */ struct improvement_entry { struct impr_type *type; int count, redundant, cost, total_cost; + QString city_names; }; /* diff --git a/client/servers.cpp b/client/servers.cpp index 663d62e6a5..bc0336e7d0 100644 --- a/client/servers.cpp +++ b/client/servers.cpp @@ -38,10 +38,8 @@ #include "version.h" // client -#include "client_main.h" - -// gui-qt #include "chatline.h" +#include "client_main.h" struct server_scan { enum server_scan_type type; @@ -268,7 +266,7 @@ static struct server_list *parse_metaserver_data(QIODevice *f) "version_comments." FOLLOWTAG); if (latest_ver != nullptr) { - const char *my_comparable = fc_comparable_version(); + const char *my_comparable = freeciv21_version(); char vertext[2048]; qDebug("Metaserver says latest '" FOLLOWTAG diff --git a/client/shortcuts.cpp b/client/shortcuts.cpp index f65f364440..2718cada4c 100644 --- a/client/shortcuts.cpp +++ b/client/shortcuts.cpp @@ -25,10 +25,9 @@ #include #include // client -#include "options.h" -// gui-qt #include "fc_client.h" #include "hudwidget.h" +#include "options.h" #include "page_game.h" #include "views/view_map.h" diff --git a/client/spaceshipdlg.cpp b/client/spaceshipdlg.cpp index 05a6bdd029..865674a887 100644 --- a/client/spaceshipdlg.cpp +++ b/client/spaceshipdlg.cpp @@ -20,12 +20,11 @@ // client #include "client_main.h" #include "colors_common.h" -#include "spaceshipdlg_g.h" -// gui-qt #include "fc_client.h" #include "page_game.h" #include "qtg_cxxside.h" #include "spaceshipdlg.h" +#include "spaceshipdlg_g.h" class QGridLayout; diff --git a/client/text.cpp b/client/text.cpp index d199d35dbc..b43f9b201d 100644 --- a/client/text.cpp +++ b/client/text.cpp @@ -1635,7 +1635,10 @@ QString text_happiness_cities_apply_rules(int cities, int max_content) .arg(cities) .arg(max_content); } else if (max_content == 0) { - return _("You have %1 cities, thus all citizens are unhappy."); + return QString(PL_("You have %1 city, thus all citizens are unhappy.", + "You have %1 cities, thus all citizens are unhappy.", + cities)) + .arg(cities); } else { // TRANS: Pluralized in "%2 angry citizens" return QString(PL_("You have %1 cities, resulting in a maximum of " diff --git a/client/themes.cpp b/client/themes.cpp index 5f3b126a79..25ac6b8c91 100644 --- a/client/themes.cpp +++ b/client/themes.cpp @@ -201,7 +201,7 @@ QStringList get_gui_specific_themes_directories(int *count) *count = data_dirs.size(); for (const auto &data_dir : data_dirs) { - directories.append(QStringLiteral("%1/themes/gui-qt").arg(data_dir)); + directories.append(QStringLiteral("%1/themes").arg(data_dir)); } return directories; diff --git a/client/themes_common.cpp b/client/themes_common.cpp index 8df5f3d1db..61f700c7fb 100644 --- a/client/themes_common.cpp +++ b/client/themes_common.cpp @@ -18,10 +18,8 @@ _ ._ Copyright (c) 1996-2021 Freeciv21 and Freeciv contributors. // client #include "options.h" -#include "themes_common.h" - -// gui-qt #include "qtg_cxxside.h" +#include "themes_common.h" Q_GLOBAL_STATIC(QVector, themes_list) diff --git a/client/tileset/sprite.cpp b/client/tileset/sprite.cpp index 9a8a42b40a..d377e19fda 100644 --- a/client/tileset/sprite.cpp +++ b/client/tileset/sprite.cpp @@ -13,7 +13,7 @@ #include // utility #include "log.h" -// gui-qt +// client #include "fc_client.h" #include "sprite.h" diff --git a/client/tileset/tilespec.cpp b/client/tileset/tilespec.cpp index 7e0d4351db..5dc6081154 100644 --- a/client/tileset/tilespec.cpp +++ b/client/tileset/tilespec.cpp @@ -71,6 +71,7 @@ #include "control.h" // for fill_xxx #include "editor.h" #include "goto.h" +#include "helpdlg.h" #include "layer_background.h" #include "layer_base_flags.h" #include "layer_darkness.h" @@ -83,9 +84,6 @@ #include "utils/colorizer.h" #include "views/view_map.h" -// gui-qt -#include "helpdlg.h" - #define TILESPEC_CAPSTR \ "+Freeciv-tilespec-Devel-2019-Jul-03 duplicates_ok precise-hp-bars " \ "unlimited-unit-select-frames unlimited-upkeep-sprites hex_corner" @@ -774,7 +772,8 @@ QEvent::Type TilesetChanged; */ const QVector *get_tileset_list(const struct option *poption) { - static QVector *tilesets[3] = {nullptr, nullptr, nullptr}; + static QVector *tilesets[3] = { + new QVector, new QVector, new QVector}; int topo = option_get_cb_data(poption); int idx; @@ -782,49 +781,35 @@ const QVector *get_tileset_list(const struct option *poption) fc_assert_ret_val(idx < ARRAY_SIZE(tilesets), nullptr); - if (tilesets[idx] == nullptr) { - /* Note: this means you must restart the client after installing a new - tileset. */ - QVector *list = fileinfolist(get_data_dirs(), TILESPEC_SUFFIX); - - tilesets[idx] = new QVector; - for (const auto &file : qAsConst(*list)) { - struct tileset *t = - tileset_read_toplevel(qUtf8Printable(file), false, topo); - - if (t) { - tilesets[idx]->append(file); - tileset_free(t); - } + QVector *list = fileinfolist(get_data_dirs(), TILESPEC_SUFFIX); + tilesets[idx]->clear(); + for (const auto &file : qAsConst(*list)) { + struct tileset *t = tileset_read_toplevel(file, false, topo); + if (t) { + tilesets[idx]->append(file); + tileset_free(t); } - delete list; } + delete list; return tilesets[idx]; } /** - Gets full filename for tilespec file, based on input name. - Returned data is allocated, and freed by user as required. - Input name may be null, in which case uses default. - Falls back to default if can't find specified name; - dies if can't find default. + * Gets full filename for tilespec file, based on input name. */ -static char *tilespec_fullname(QString tileset_name) +static QString tilespec_fullname(QString tileset_name) { if (!tileset_name.isEmpty()) { - QString dname; - QString fname = - QStringLiteral("%1%2").arg(tileset_name, TILESPEC_SUFFIX); - - dname = fileinfoname(get_data_dirs(), qUtf8Printable(fname)); + auto fname = tileset_name + QStringLiteral(TILESPEC_SUFFIX); + auto dname = fileinfoname(get_data_dirs(), fname); if (!dname.isEmpty()) { - return fc_strdup(qUtf8Printable(dname)); + return dname; } } - return nullptr; + return QString(); } /** @@ -835,7 +820,8 @@ static char *tilespec_fullname(QString tileset_name) static bool check_tilespec_capabilities(struct section_file *file, const char *which, const char *us_capstr, - const char *filename, bool verbose) + const QString &filename, + bool verbose) { QtMsgType level = verbose ? LOG_ERROR : LOG_DEBUG; @@ -843,12 +829,12 @@ static bool check_tilespec_capabilities(struct section_file *file, if (nullptr == file_capstr) { log_base(level, "\"%s\": %s file doesn't have a capability string", - filename, which); + qUtf8Printable(filename), which); return false; } if (!has_capabilities(us_capstr, file_capstr)) { - log_base(level, "\"%s\": %s file appears incompatible:", filename, - which); + log_base(level, "\"%s\": %s file appears incompatible:", + qUtf8Printable(filename), which); log_base(level, " datafile options: %s", file_capstr); log_base(level, " supported options: %s", us_capstr); return false; @@ -857,7 +843,7 @@ static bool check_tilespec_capabilities(struct section_file *file, log_base(level, "\"%s\": %s file requires option(s) " "that client doesn't support:", - filename, which); + qUtf8Printable(filename), which); log_base(level, " datafile options: %s", file_capstr); log_base(level, " supported options: %s", us_capstr); return false; @@ -1493,11 +1479,10 @@ static void tileset_set_offsets(struct tileset *t, struct section_file *file) } static void tileset_stop_read(struct tileset *t, struct section_file *file, - char *fname, struct section_list *sections, + struct section_list *sections, const char **layer_order) { secfile_destroy(file); - delete[] fname; delete[] layer_order; delete[] t; if (nullptr != sections) { @@ -1576,7 +1561,6 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, bool verbose, int topology_id) { struct section_file *file; - char *fname; const char *c; int i; size_t num_spec_files; @@ -1593,25 +1577,24 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, const char *tstr; int topo; - fname = tilespec_fullname(tileset_name); - if (!fname) { + auto fname = tilespec_fullname(tileset_name); + if (fname.isEmpty()) { if (verbose) { qCritical("Can't find tileset \"%s\".", qUtf8Printable(tileset_name)); } return nullptr; } - qDebug("tilespec file is \"%s\".", fname); + qDebug("tilespec file is \"%s\".", qUtf8Printable(fname)); if (!(file = secfile_load(fname, true))) { - qCritical("Could not open '%s':\n%s", fname, secfile_error()); - delete[] fname; + qCritical("Could not open '%s':\n%s", qUtf8Printable(fname), + secfile_error()); return nullptr; } if (!check_tilespec_capabilities(file, "tilespec", TILESPEC_CAPSTR, fname, verbose)) { secfile_destroy(file); - delete[] fname; return nullptr; } @@ -1667,21 +1650,21 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, if (!secfile_lookup_int(file, &t->priority, "tilespec.priority") || !secfile_lookup_bool(file, &is_hex, "tilespec.is_hex")) { qCritical("Tileset \"%s\" invalid: %s", t->name, secfile_error()); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } tstr = secfile_lookup_str(file, "tilespec.type"); if (tstr == nullptr) { qCritical("Tileset \"%s\": no tileset type", t->name); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } t->type = ts_type_by_name(tstr, fc_strcasecmp); if (!ts_type_is_valid(t->type)) { qCritical("Tileset \"%s\": unknown tileset type \"%s\"", t->name, tstr); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } @@ -1697,7 +1680,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, if (!secfile_lookup_int(file, &hex_side, "tilespec.hex_side")) { qCritical("Tileset \"%s\" invalid: %s", t->name, secfile_error()); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } if (t->type == TS_ISOMETRIC) { @@ -1718,7 +1701,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, if (((topology_id & TF_HEX) && topology_id != (topo & (TF_ISO | TF_HEX))) || (!(topology_id & TF_HEX) && (topo & TF_HEX))) { // Not of requested topology - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } } @@ -1751,7 +1734,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, || !secfile_lookup_int(file, &t->normal_tile_height, "tilespec.normal_tile_height")) { qCritical("Tileset \"%s\" invalid: %s", t->name, secfile_error()); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } if (t->type == TS_ISOMETRIC) { @@ -1778,7 +1761,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, || !secfile_lookup_int(file, &t->small_sprite_height, "tilespec.small_tile_height")) { qCritical("Tileset \"%s\" invalid: %s", t->name, secfile_error()); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } qDebug("tile sizes %dx%d, %dx%d unit, %dx%d small", t->normal_tile_width, @@ -1788,14 +1771,14 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, tstr = secfile_lookup_str(file, "tilespec.fog_style"); if (tstr == nullptr) { qCritical("Tileset \"%s\": no fog_style", t->name); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } t->fogstyle = fog_style_by_name(tstr, fc_strcasecmp); if (!fog_style_is_valid(t->fogstyle)) { qCritical("Tileset \"%s\": unknown fog_style \"%s\"", t->name, tstr); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } @@ -1804,7 +1787,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, if (tileset_invalid_offsets(t, file)) { qCritical("Tileset \"%s\" invalid: %s", t->name, secfile_error()); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } tileset_set_offsets(t, file); @@ -1822,7 +1805,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, "Tileset \"%s\": unknown " "unit_default_orientation \"%s\"", t->name, c); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } else { /* Default orientation is allowed to not be a valid one for the @@ -1845,14 +1828,14 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, // Check for wrong layer names. if (!mapview_layer_is_valid(layer)) { qCritical("layer_order: Invalid layer \"%s\"", layer_order[i]); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } // Check for duplicates. for (j = 0; j < i; j++) { if (order[j] == layer) { qCritical("layer_order: Duplicate layer \"%s\"", layer_order[i]); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } } @@ -1874,7 +1857,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, if (!found) { qCritical("layer_order: Missing layer \"%s\"", mapview_layer_name(static_cast(i))); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } } @@ -1892,7 +1875,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, tstr = secfile_lookup_str(file, "tilespec.darkness_style"); if (tstr == nullptr) { qCritical("Tileset \"%s\": no darkness_style", t->name); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } @@ -1900,14 +1883,14 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, if (!darkness_style_is_valid(darkness_style)) { qCritical("Tileset \"%s\": unknown darkness_style \"%s\"", t->name, tstr); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } if (darkness_style == freeciv::DARKNESS_ISORECT && (t->type == TS_OVERHEAD || t->hex_width > 0 || t->hex_height > 0)) { qCritical("Invalid darkness style set in tileset \"%s\".", t->name); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } @@ -1920,7 +1903,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, secfile_lookup_str_vec(file, &count, "layer%d.match_types", i); for (int j = 0; j < count; j++) { if (!t->terrain_layers[i]->create_matching_group(match_types[j])) { - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } } @@ -1931,8 +1914,8 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, if (nullptr == sections || 0 == section_list_size(sections)) { tileset_error(t, LOG_ERROR, _("No [%s] sections supported by tileset \"%s\"."), - TILE_SECTION_PREFIX, fname); - tileset_stop_read(t, file, fname, sections, layer_order); + TILE_SECTION_PREFIX, qUtf8Printable(fname)); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } @@ -1948,7 +1931,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, } else { tileset_error(t, LOG_ERROR, _("No terrain tag given in section [%s]."), sec_name); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } } @@ -1961,7 +1944,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, for (int l = 0; l < num_layers; l++) { if (!t->terrain_layers[l]->add_tag( tag, QString(sec_name).mid(strlen(TILE_SECTION_PREFIX)))) { - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } @@ -1984,7 +1967,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, if (!t->terrain_layers[l]->set_tag_offsets(tag, offset_x, offset_y)) { - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } } @@ -1995,7 +1978,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, file, "whole", "%s.layer%d_sprite_type", sec_name, l); if (!t->terrain_layers[l]->set_tag_sprite_type( tag, check_sprite_type(type_str, sec_name))) { - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } } @@ -2008,7 +1991,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, if (matching_group) { if (!t->terrain_layers[l]->set_tag_matching_group( tag, matching_group)) { - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } } @@ -2020,7 +2003,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, for (std::size_t j = 0; j < count; ++j) { if (!t->terrain_layers[l]->set_tag_matches_with( tag, match_with[j])) { - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } } @@ -2059,7 +2042,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, if (t->estyle_hash->contains(extraname)) { qCritical("warning: duplicate extrastyle entry [%s].", extraname); - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } t->estyle_hash->insert(extraname, style); @@ -2068,8 +2051,9 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, spec_filenames = secfile_lookup_str_vec(file, &num_spec_files, "tilespec.files"); if (nullptr == spec_filenames || 0 == num_spec_files) { - qCritical("No tile graphics files specified in \"%s\"", fname); - tileset_stop_read(t, file, fname, sections, layer_order); + qCritical("No tile graphics files specified in \"%s\"", + qUtf8Printable(fname)); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } @@ -2088,7 +2072,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, qCritical("Can't find spec file \"%s\".", spec_filenames[i]); } delete sf; - tileset_stop_read(t, file, fname, sections, layer_order); + tileset_stop_read(t, file, sections, layer_order); return nullptr; } sf->file_name = fc_strdup(qUtf8Printable(dname)); @@ -2119,8 +2103,7 @@ static struct tileset *tileset_read_toplevel(const QString &tileset_name, secfile_check_unused(file); secfile_destroy(file); - qDebug("finished reading \"%s\".", fname); - delete[] fname; + qDebug("finished reading \"%s\".", qUtf8Printable(fname)); delete[] layer_order; return t; diff --git a/client/tooltips.cpp b/client/tooltips.cpp index 537b8ae617..df318efd5b 100644 --- a/client/tooltips.cpp +++ b/client/tooltips.cpp @@ -21,9 +21,8 @@ // client #include "client_main.h" #include "climisc.h" -#include "movement.h" -// gui-qt #include "fc_client.h" +#include "movement.h" #include "tooltips.h" extern QString split_text(const QString &text, bool cut); diff --git a/client/top_bar.cpp b/client/top_bar.cpp index 06db64e1bd..eb75177917 100644 --- a/client/top_bar.cpp +++ b/client/top_bar.cpp @@ -31,13 +31,11 @@ // client #include "client_main.h" #include "climisc.h" -#include "ratesdlg_g.h" - -// gui-qt #include "fc_client.h" #include "fonts.h" #include "page_game.h" #include "qtg_cxxside.h" +#include "ratesdlg_g.h" #include "tileset/sprite.h" #include "top_bar.h" #include "views/view_economics.h" diff --git a/client/unithudselector.h b/client/unithudselector.h index f567be140c..6008cf6513 100644 --- a/client/unithudselector.h +++ b/client/unithudselector.h @@ -19,7 +19,7 @@ #include // utility #include "fc_types.h" -// gui-qt +// client #include "dialogs.h" #include "shortcuts.h" diff --git a/client/unitselect.cpp b/client/unitselect.cpp index d73cee34c2..9ea6f5c0fe 100644 --- a/client/unitselect.cpp +++ b/client/unitselect.cpp @@ -20,15 +20,14 @@ // common #include "movement.h" // client +#include "canvas.h" #include "client_main.h" #include "control.h" -#include "tileset/tilespec.h" -#include "views/view_map_common.h" -// gui-qt -#include "canvas.h" #include "fonts.h" #include "page_game.h" +#include "tileset/tilespec.h" #include "views/view_map.h" +#include "views/view_map_common.h" /** Contructor for units_select diff --git a/client/update_queue.cpp b/client/update_queue.cpp index 13ef8a7e24..96c3a624c2 100644 --- a/client/update_queue.cpp +++ b/client/update_queue.cpp @@ -33,17 +33,15 @@ #include "repodlgs_g.h" // client +#include "canvas.h" #include "client_main.h" #include "connectdlg_common.h" +#include "qtg_cxxside.h" #include "tileset/tilespec.h" #include "update_queue.h" #include "views/view_nations_data.h" #include "views/view_units.h" -// gui-qt -#include "canvas.h" -#include "qtg_cxxside.h" - update_queue *update_queue::m_instance = nullptr; // returns instance of queue diff --git a/client/utils/colorizer.h b/client/utils/colorizer.h index f4484b0ee5..1e7c231236 100644 --- a/client/utils/colorizer.h +++ b/client/utils/colorizer.h @@ -8,6 +8,7 @@ #include #include +#include #include #include diff --git a/client/views/view_cities.cpp b/client/views/view_cities.cpp index 420cb068f4..d93319d0a4 100644 --- a/client/views/view_cities.cpp +++ b/client/views/view_cities.cpp @@ -26,9 +26,8 @@ // client #include "cityrep_g.h" #include "client_main.h" -#include "governor.h" -// gui-qt #include "fc_client.h" +#include "governor.h" #include "hudwidget.h" #include "icons.h" #include "page_game.h" diff --git a/client/views/view_economics.cpp b/client/views/view_economics.cpp index 93f3ca5cc5..0313c7bf28 100644 --- a/client/views/view_economics.cpp +++ b/client/views/view_economics.cpp @@ -15,11 +15,10 @@ #include "views/view_economics.h" // client -#include "tileset/sprite.h" -// gui-qt #include "fc_client.h" #include "hudwidget.h" #include "page_game.h" +#include "tileset/sprite.h" #include "top_bar.h" /** @@ -35,7 +34,8 @@ eco_report::eco_report() : QWidget() QStringList slist; slist << _("Type") << Q_("?Building or Unit type:Name") << _("Redundant") - << _("Count") << _("Cost") << _("Total Upkeep"); + << _("Count") << _("Cost") << _("Total Upkeep") + << _("Redundant Cities"); ui.eco_widget->setColumnCount(slist.count()); ui.eco_widget->setHorizontalHeaderLabels(slist); @@ -92,7 +92,7 @@ void eco_report::update_report() cid id = cid_encode_building(pimprove); ui.eco_widget->insertRow(i); - for (j = 0; j < 6; j++) { + for (j = 0; j < 7; j++) { item = new QTableWidgetItem; switch (j) { case 0: { @@ -124,6 +124,9 @@ void eco_report::update_report() item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); item->setData(Qt::DisplayRole, pentry->total_cost); break; + case 6: + item->setTextAlignment(Qt::AlignVCenter | Qt::AlignLeft); + item->setData(Qt::DisplayRole, pentry->city_names); } ui.eco_widget->setItem(i, j, item); } @@ -136,7 +139,7 @@ void eco_report::update_report() cid id = cid_encode_unit(putype); ui.eco_widget->insertRow(i + max_row); - for (j = 0; j < 6; j++) { + for (j = 0; j < 7; j++) { item = new QTableWidgetItem; switch (j) { case 0: { @@ -170,6 +173,9 @@ void eco_report::update_report() item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); item->setData(Qt::DisplayRole, pentry->total_cost); break; + case 6: + item->setTextAlignment(Qt::AlignVCenter | Qt::AlignLeft); + item->setText(_("Not Applicable")); } ui.eco_widget->setItem(max_row + i, j, item); } diff --git a/client/views/view_map.cpp b/client/views/view_map.cpp index 4e658e9cc4..4007eaaffa 100644 --- a/client/views/view_map.cpp +++ b/client/views/view_map.cpp @@ -29,23 +29,22 @@ #include "climap.h" #include "climisc.h" #include "colors_common.h" +#include "fc_client.h" +#include "fonts.h" +#include "hudwidget.h" #include "mapctrl_common.h" #include "mapview_g.h" +#include "messagewin.h" #include "minimap_panel.h" +#include "page_game.h" +#include "qtg_cxxside.h" #include "renderer.h" #include "text.h" #include "tileset/sprite.h" #include "tileset/tilespec.h" -#include "views/view_map_common.h" -// gui-qt -#include "fc_client.h" -#include "fonts.h" -#include "hudwidget.h" -#include "messagewin.h" -#include "page_game.h" -#include "qtg_cxxside.h" #include "top_bar.h" #include "views/view_map.h" +#include "views/view_map_common.h" #include "views/view_research.h" #include "widgets/decorations.h" diff --git a/client/views/view_map_common.cpp b/client/views/view_map_common.cpp index 1a3e0c8772..138feaea41 100644 --- a/client/views/view_map_common.cpp +++ b/client/views/view_map_common.cpp @@ -49,21 +49,19 @@ #include "mapview_g.h" // client +#include "canvas.h" #include "citydlg_common.h" +#include "client_main.h" #include "climap.h" #include "control.h" #include "editor.h" #include "map_updates_handler.h" #include "overview_common.h" +#include "qtg_cxxside.h" #include "tileset/tilespec.h" #include "views/view_map_common.h" #include "views/view_map_geometry.h" -// gui-qt -#include "canvas.h" -#include "client_main.h" -#include "qtg_cxxside.h" - Q_LOGGING_CATEGORY(graphics_category, "freeciv.graphics") Q_GLOBAL_STATIC(QSet, mapdeco_highlight_set) @@ -2357,7 +2355,7 @@ static struct link_mark *link_mark_new(enum text_link_type type, int id, /** Remove a link mark. */ -static void link_mark_destroy(struct link_mark *pmark) { free(pmark); } +static void link_mark_destroy(struct link_mark *pmark) { delete pmark; } /** Returns the location of the pointed mark. diff --git a/client/views/view_nations.cpp b/client/views/view_nations.cpp index 1914bed18b..81d97894e5 100644 --- a/client/views/view_nations.cpp +++ b/client/views/view_nations.cpp @@ -36,7 +36,6 @@ // client #include "chatline_common.h" #include "client_main.h" -// gui-qt #include "fc_client.h" #include "fonts.h" #include "page_game.h" diff --git a/client/views/view_research.cpp b/client/views/view_research.cpp index 5e15abd2bb..31d15da89f 100644 --- a/client/views/view_research.cpp +++ b/client/views/view_research.cpp @@ -27,19 +27,18 @@ #include "government.h" #include "research.h" // client +#include "citydlg.h" #include "client_main.h" #include "climisc.h" +#include "fc_client.h" #include "helpdlg.h" +#include "page_game.h" #include "text.h" #include "tileset/sprite.h" -#include "views/view_research_reqtree.h" -// gui-qt -#include "citydlg.h" -#include "fc_client.h" -#include "page_game.h" #include "tooltips.h" #include "top_bar.h" #include "views/view_research.h" +#include "views/view_research_reqtree.h" extern QString split_text(const QString &text, bool cut); extern QString cut_helptext(const QString &text); diff --git a/client/views/view_research_reqtree.h b/client/views/view_research_reqtree.h index f55051da7c..12939259e3 100644 --- a/client/views/view_research_reqtree.h +++ b/client/views/view_research_reqtree.h @@ -10,7 +10,7 @@ **************************************************************************/ #pragma once -// gui-qt +// client #include "canvas.h" #include diff --git a/client/views/view_units.cpp b/client/views/view_units.cpp index d5d36a75ef..cd61d69396 100644 --- a/client/views/view_units.cpp +++ b/client/views/view_units.cpp @@ -392,12 +392,12 @@ void units_view::selection_changed(const QItemSelection &sl, qvar = itm->data(Qt::UserRole); uid = qvar.toInt(); selected = cid_decode(uid); - counter = ui.units_widget->item(curr_row, 3)->text().toInt(); + counter = ui.units_widget->item(curr_row, 4)->text().toInt(); if (counter > 0) { ui.disband_but->setDisabled(false); ui.find_but->setDisabled(false); } - upg = ui.units_widget->item(curr_row, 1)->text(); + upg = ui.units_widget->item(curr_row, 2)->text(); if (upg != "-") { ui.upg_but->setDisabled(false); } diff --git a/client/voteinfo_bar.cpp b/client/voteinfo_bar.cpp index c25fe66045..fa04f5d871 100644 --- a/client/voteinfo_bar.cpp +++ b/client/voteinfo_bar.cpp @@ -15,11 +15,10 @@ #include #include // client +#include "fc_client.h" #include "page_game.h" #include "page_pregame.h" #include "voteinfo.h" -// gui-qt -#include "fc_client.h" /** Constructor for pregamevote diff --git a/client/widgets/decorations.cpp b/client/widgets/decorations.cpp index fe22f04ad1..6c278dcb44 100644 --- a/client/widgets/decorations.cpp +++ b/client/widgets/decorations.cpp @@ -24,12 +24,11 @@ #include "decorations.h" // Qt +#include "fc_client.h" +#include "icons.h" #include #include #include -// gui-qt -#include "fc_client.h" -#include "icons.h" /** Scale widget allowing scaling other widgets, shown in right top corner diff --git a/cmake/AutoRevision.txt b/cmake/AutoRevision.txt index 5ad47e959f..8ca49822ee 100644 --- a/cmake/AutoRevision.txt +++ b/cmake/AutoRevision.txt @@ -1,2 +1,2 @@ -859a7 -v3.1-alpha.4 +36ee8 +v3.1-alpha.5 diff --git a/cmake/FreecivBuildOptions.cmake b/cmake/FreecivBuildOptions.cmake index dd425ee6a0..6a4801587c 100644 --- a/cmake/FreecivBuildOptions.cmake +++ b/cmake/FreecivBuildOptions.cmake @@ -48,6 +48,14 @@ if (FREECIV_ENABLE_SERVER set(FREECIV_BUILD_LIBSERVER TRUE) endif() +# If we ask for the client, we have to have the Qt modpack installer from tools +if (FREECIV_ENABLE_CLIENT) + cmake_dependent_option( + FREECIV_ENABLE_FCMP_QT + "Build the modpack installer (Qt interface)" + ON FREECIV_ENABLE_TOOLS OFF) +endif() + # By default we do not enable VCPKG option(FREECIV_USE_VCPKG "Use VCPKG" OFF) diff --git a/cmake/FreecivDependencies.cmake b/cmake/FreecivDependencies.cmake index a8072182c1..8f828414a5 100644 --- a/cmake/FreecivDependencies.cmake +++ b/cmake/FreecivDependencies.cmake @@ -21,7 +21,7 @@ check_function_exists(at_quick_exit HAVE_AT_QUICK_EXIT) find_package(Python3 REQUIRED) # Required as the main networking and utility library -find_package(Qt5 5.15 COMPONENTS Core Network REQUIRED) +find_package(Qt6 6.6 COMPONENTS Core Network REQUIRED) # Required for utility if(FREECIV_ENABLE_SERVER) @@ -116,7 +116,7 @@ add_subdirectory(dependencies/sol2) include(FreecivBackward) # Compression -find_package(KF5Archive REQUIRED) +find_package(KF6Archive REQUIRED) set(FREECIV_HAVE_BZ2 ${KArchive_HAVE_BZIP2}) set(FREECIV_HAVE_LZMA ${KArchive_HAVE_LZMA}) set(FREECIV_HAVE_ZSTD ${KArchive_HAVE_ZSTD}) @@ -158,10 +158,10 @@ if (FREECIV_ENABLE_CLIENT OR FREECIV_ENABLE_FCMP_QT OR FREECIV_ENABLE_RULEDIT) # May want to relax the version later - find_package(Qt5 5.15 COMPONENTS Widgets REQUIRED) + find_package(Qt6 6.6 COMPONENTS Widgets REQUIRED) endif() if (FREECIV_ENABLE_CLIENT) - find_package(Qt5 5.15 COMPONENTS Svg REQUIRED) + find_package(Qt6 6.6 COMPONENTS Svg REQUIRED) endif() # FCMP-specific dependencies @@ -173,6 +173,6 @@ endif() if (NOT EMSCRIPTEN) include(CTest) if (BUILD_TESTING) - find_package(Qt5Test REQUIRED) + find_package(Qt6Test REQUIRED) endif() endif() diff --git a/cmake/FreecivInstall.cmake b/cmake/FreecivInstall.cmake index 3a4b81a319..05486cbdb8 100644 --- a/cmake/FreecivInstall.cmake +++ b/cmake/FreecivInstall.cmake @@ -41,10 +41,11 @@ if(WIN32 OR MSYS OR MINGW) # Custom command files to run the applications install( FILES - ${CMAKE_SOURCE_DIR}/dist/freeciv21-server.cmd ${CMAKE_SOURCE_DIR}/data/icons/128x128/freeciv21-client.ico ${CMAKE_SOURCE_DIR}/data/icons/128x128/freeciv21-modpack.ico ${CMAKE_SOURCE_DIR}/data/icons/128x128/freeciv21-server.ico + ${CMAKE_SOURCE_DIR}/dist/windows/freeciv21-server.cmd + ${CMAKE_SOURCE_DIR}/dist/windows/qt.conf DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT freeciv21) endif() diff --git a/cmake/NSIS.template.in b/cmake/NSIS.template.in index 9d6b8eab4f..e29b917ae5 100644 --- a/cmake/NSIS.template.in +++ b/cmake/NSIS.template.in @@ -199,7 +199,7 @@ FunctionEnd Function RunFreeciv21 - ExecShell "" "$SMPROGRAMS\${APPNAME}\${APPNAME} Client.lnk" + ExecShell "" "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" FunctionEnd Function UninstallExisting @@ -224,11 +224,11 @@ ; Create Desktop Icon - CreateShortCut "$DESKTOP\${APPNAME} Client.lnk" "$INSTDIR\freeciv21-client.exe" "" "$INSTDIR\freeciv21-client.ico" 0 + CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\freeciv21-client.exe" "" "$INSTDIR\freeciv21-client.ico" 0 ; Create Start Menu Entries CreateDirectory "$SMPROGRAMS\${APPNAME}" - CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME} Client.lnk" "$INSTDIR\freeciv21-client.exe" "" "$INSTDIR\freeciv21-client.ico" 0 + CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\freeciv21-client.exe" "" "$INSTDIR\freeciv21-client.ico" 0 CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME} Modpack Installer.lnk" "$INSTDIR\freeciv21-modpack-qt.exe" "" "$INSTDIR\freeciv21-modpack.ico" 0 CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME} Server.lnk" "$INSTDIR\freeciv21-server.exe" "" "$INSTDIR\freeciv21-server.ico" 0 diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 0d470a9e0f..8a5c08a98d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -31,7 +31,7 @@ target_include_directories(common_gen PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(common_gen PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/aicore) target_include_directories(common_gen PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/networking) -target_link_libraries(common_gen PUBLIC Qt5::Core) +target_link_libraries(common_gen PUBLIC Qt6::Core) target_link_libraries(common_gen PUBLIC utility) # Main library @@ -99,6 +99,6 @@ add_subdirectory(aicore) add_subdirectory(networking) add_subdirectory(scriptcore) -target_link_libraries(common PUBLIC Qt5::Core Qt5::Network) +target_link_libraries(common PUBLIC Qt6::Core Qt6::Network) target_link_libraries(common PRIVATE aicore networking) target_link_libraries(common PUBLIC common_gen scriptcore) diff --git a/common/helpdata.cpp b/common/helpdata.cpp index 60d5dfa38b..d5652b2ac5 100644 --- a/common/helpdata.cpp +++ b/common/helpdata.cpp @@ -2577,7 +2577,9 @@ char *helptext_unit(char *buf, size_t bufsz, struct player *pplayer, case ACTRES_BOMBARD: cat_snprintf(buf, bufsz, // TRANS: %d is bombard rate. - _(" * %d per turn.\n"), utype->bombard_rate); + PL_(" * %d round per action.\n", + " * %d rounds per action.\n", utype->bombard_rate), + utype->bombard_rate); cat_snprintf(buf, bufsz, // TRANS: talking about bombard _(" * These attacks will only damage (never kill)" diff --git a/common/networking/CMakeLists.txt b/common/networking/CMakeLists.txt index 907795a1d7..15fa20fe93 100644 --- a/common/networking/CMakeLists.txt +++ b/common/networking/CMakeLists.txt @@ -8,7 +8,7 @@ add_library( target_include_directories(networking PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(networking PUBLIC Qt5::Core) +target_link_libraries(networking PUBLIC Qt6::Core) target_link_libraries(networking PUBLIC common) if (NOT EMSCRIPTEN) target_link_libraries(networking PUBLIC ZLIB::ZLIB) diff --git a/common/networking/packets.def b/common/networking/packets.def index 214c214f30..d61cd62b4f 100644 --- a/common/networking/packets.def +++ b/common/networking/packets.def @@ -665,7 +665,8 @@ end PACKET_SERVER_INFO = 29; sc, dsend STRING version_label[48]; - UINT32 major_version, minor_version, patch_version, emerg_version; + UINT32 major_version, minor_version, patch_version; + UINT32 _obsolete; # Since 3.1 end /************** City packets **********************/ @@ -1291,7 +1292,7 @@ end PACKET_CLIENT_INFO = 119; cs, handle-per-conn UINT8 _obsolete; - UINT32 emerg_version; + UINT32 _obsolete2; # Since 3.1 STRING distribution[MAX_LEN_NAME]; end diff --git a/common/scriptcore/CMakeLists.txt b/common/scriptcore/CMakeLists.txt index 39c3ef8194..a3f238bcf5 100644 --- a/common/scriptcore/CMakeLists.txt +++ b/common/scriptcore/CMakeLists.txt @@ -48,6 +48,6 @@ target_include_directories(scriptcore PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(scriptcore PUBLIC common) target_link_libraries(scriptcore PUBLIC tolua) target_link_libraries(scriptcore PUBLIC sol2) -target_link_libraries(scriptcore PRIVATE Qt5::Core) +target_link_libraries(scriptcore PRIVATE Qt6::Core) add_compile_definitions(LUA_LIB) diff --git a/common/scriptcore/tolua_game.pkg b/common/scriptcore/tolua_game.pkg index 38062213f2..c00d5df4dc 100644 --- a/common/scriptcore/tolua_game.pkg +++ b/common/scriptcore/tolua_game.pkg @@ -79,6 +79,7 @@ struct Building_Type { struct Unit_Type { int build_cost; + int pop_cost; const int item_number @ id; }; diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 7c266e2ffb..773f7e0cee 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -152,8 +152,8 @@ if (FREECIV_ENABLE_CLIENT) COMPONENT freeciv21 FILES_MATCHING PATTERN *.png PATTERN *.spec) install( - DIRECTORY themes/gui-qt - DESTINATION "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/themes" + DIRECTORY themes + DESTINATION "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}" COMPONENT freeciv21 FILES_MATCHING PATTERN theme.conf PATTERN *.jpg diff --git a/data/civ1/units.ruleset b/data/civ1/units.ruleset index 4ca5f36796..d560188e2c 100644 --- a/data/civ1/units.ruleset +++ b/data/civ1/units.ruleset @@ -306,8 +306,8 @@ flags = "Missile", "Unreachable", "DoesntOccupyTile" ; "Explorer" = unit to use for exploring ; "Hut" = can be found in a hut ; "HutTech" = can be found in a hut, but its techs required -; "Partisan" = can be created as a partisan (only one unit can have this -; flag), see end of this file for its tech requirements option +; "Partisan" = can be created as a partisan if the +; Inspire_Partisans effect is enabled ; "DefendOk" = AI hint: ok for defending with ; "DefendGood" = AI hint: good for defending with ; "Ferryboat" = AI hint: useful for ferrying diff --git a/data/civ2/units.ruleset b/data/civ2/units.ruleset index af088d48ec..10647d99ae 100644 --- a/data/civ2/units.ruleset +++ b/data/civ2/units.ruleset @@ -323,8 +323,8 @@ flags = "Unreachable", "DoesntOccupyTile" ; "Explorer" = unit to use for exploring ; "Hut" = can be found in a hut ; "HutTech" = can be found in a hut, but its techs required -; "Partisan" = can be created as a partisan (only one unit can have this -; flag), see end of this file for its tech requirements option +; "Partisan" = can be created as a partisan if the +; Inspire_Partisans effect is enabled ; "DefendOk" = AI hint: ok for defending with ; "DefendGood" = AI hint: good for defending with ; "Ferryboat" = AI hint: useful for ferrying diff --git a/data/civ2civ3/units.ruleset b/data/civ2civ3/units.ruleset index e2d5b025fb..59e2a629ab 100644 --- a/data/civ2civ3/units.ruleset +++ b/data/civ2civ3/units.ruleset @@ -434,8 +434,8 @@ flags = "Unreachable", "DoesntOccupyTile", "CanPillage", "Airliftable" ; "Explorer" = unit to use for exploring ; "Hut" = can be found in a hut ; "HutTech" = can be found in a hut, but its techs required -; "Partisan" = can be created as a partisan (only one unit can have this -; flag), see end of this file for its tech requirements option +; "Partisan" = can be created as a partisan if the +; Inspire_Partisans effect is enabled ; "DefendOk" = AI hint: ok for defending with ; "DefendGood" = AI hint: good for defending with ; "Ferryboat" = AI hint: useful for ferrying diff --git a/data/classic/units.ruleset b/data/classic/units.ruleset index 2d4f73026a..d2fb8a3af2 100644 --- a/data/classic/units.ruleset +++ b/data/classic/units.ruleset @@ -410,8 +410,8 @@ flags = "Unreachable", "DoesntOccupyTile" ; "Explorer" = unit to use for exploring ; "Hut" = can be found in a hut ; "HutTech" = can be found in a hut, but its techs required -; "Partisan" = can be created as a partisan (only one unit can have this -; flag), see end of this file for its tech requirements option +; "Partisan" = can be created as a partisan if the +; Inspire_Partisans effect is enabled ; "DefendOk" = AI hint: ok for defending with ; "DefendGood" = AI hint: good for defending with ; "Ferryboat" = AI hint: useful for ferrying diff --git a/data/default/default.lua b/data/default/default.lua index 2cfa38a11b..f5cfc7f433 100644 --- a/data/default/default.lua +++ b/data/default/default.lua @@ -188,11 +188,26 @@ function _deflua_make_partisans_callback(city, loser, winner, reason) return end - local partisans = random(0, 1 + (city.size + 1) / 2) + 1 + local size = math.tointeger(city.size) + local partisans = random(0, 1 + (size + 1) / 2) + 1 if partisans > 8 then partisans = 8 end city.tile:place_partisans(loser, partisans, city:map_sq_radius()) + + -- In rulesets where partisans cost population, we reduce the city size + -- accordingly. This avoids an exploit where two players would keep conquering + -- a city back and forth to generate an unbounded number of partisans. + -- Get the generated unit type + local partisan_utype = find.role_unit_type("Partisan", loser) or + find.role_unit_type("Partisan", nil) + if partisan_utype then -- Better safe than sorry + local pop_cost = partisan_utype.pop_cost * partisans + if pop_cost > 0 then + edit.resize_city(city, math.max(1, size - pop_cost), 'partisans') + end + end + notify.event(loser, city.tile, E.CITY_LOST, _("The loss of %s has inspired partisans!"), city.name) notify.event(winner, city.tile, E.UNIT_WIN_ATT, diff --git a/data/experimental/units.ruleset b/data/experimental/units.ruleset index d1459d2606..ca31f54ba0 100644 --- a/data/experimental/units.ruleset +++ b/data/experimental/units.ruleset @@ -422,8 +422,8 @@ flags = "Unreachable", "DoesntOccupyTile" ; "Explorer" = unit to use for exploring ; "Hut" = can be found in a hut ; "HutTech" = can be found in a hut, but its techs required -; "Partisan" = can be created as a partisan (only one unit can have this -; flag), see end of this file for its tech requirements option +; "Partisan" = can be created as a partisan if the +; Inspire_Partisans effect is enabled ; "DefendOk" = AI hint: ok for defending with ; "DefendGood" = AI hint: good for defending with ; "Ferryboat" = AI hint: useful for ferrying diff --git a/data/granularity/units.ruleset b/data/granularity/units.ruleset index 7523df28ae..104fc4f914 100644 --- a/data/granularity/units.ruleset +++ b/data/granularity/units.ruleset @@ -340,8 +340,8 @@ flags = "TerrainSpeed" ; "Explorer" = unit to use for exploring ; "Hut" = can be found in a hut ; "HutTech" = can be found in a hut, but its techs required -; "Partisan" = can be created as a partisan (only one unit can have this -; flag), see end of this file for its tech requirements option +; "Partisan" = can be created as a partisan if the +; Inspire_Partisans effect is enabled ; "DefendOk" = AI hint: ok for defending with ; "DefendGood" = AI hint: good for defending with ; "Ferryboat" = AI hint: useful for ferrying diff --git a/data/graphics/logo+splash/freeciv21-modpack.svg b/data/graphics/logo+splash/freeciv21-modpack.svg new file mode 100644 index 0000000000..4958b4c6d7 --- /dev/null +++ b/data/graphics/logo+splash/freeciv21-modpack.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FREECIV21 + + + + + + + + diff --git a/data/graphics/logo+splash/freeciv21-modpack.svg.license b/data/graphics/logo+splash/freeciv21-modpack.svg.license new file mode 100644 index 0000000000..8a2b6d8d94 --- /dev/null +++ b/data/graphics/logo+splash/freeciv21-modpack.svg.license @@ -0,0 +1,4 @@ +SPDX-License-Identifier: GPL-3.0-or-later +SPDX-FileCopyrightText: James Blewitt +SPDX-FileCopyrightText: Hugo Flávio +SPDX-FileCopyrightText: Louis Moureaux diff --git a/data/graphics/logo+splash/freeciv21-ruledit.svg b/data/graphics/logo+splash/freeciv21-ruledit.svg new file mode 100644 index 0000000000..e010a91133 --- /dev/null +++ b/data/graphics/logo+splash/freeciv21-ruledit.svg @@ -0,0 +1,355 @@ + +image/svg+xmlFREECIV21 diff --git a/data/graphics/logo+splash/freeciv21-ruledit.svg.license b/data/graphics/logo+splash/freeciv21-ruledit.svg.license new file mode 100644 index 0000000000..8a2b6d8d94 --- /dev/null +++ b/data/graphics/logo+splash/freeciv21-ruledit.svg.license @@ -0,0 +1,4 @@ +SPDX-License-Identifier: GPL-3.0-or-later +SPDX-FileCopyrightText: James Blewitt +SPDX-FileCopyrightText: Hugo Flávio +SPDX-FileCopyrightText: Louis Moureaux diff --git a/data/icons/128x128/freeciv21-client.licence b/data/icons/128x128/freeciv21-client.license similarity index 100% rename from data/icons/128x128/freeciv21-client.licence rename to data/icons/128x128/freeciv21-client.license diff --git a/data/icons/128x128/freeciv21-modpack.ico b/data/icons/128x128/freeciv21-modpack.ico index cb02b3e6c5..2ebf4c617d 100644 Binary files a/data/icons/128x128/freeciv21-modpack.ico and b/data/icons/128x128/freeciv21-modpack.ico differ diff --git a/data/icons/128x128/freeciv21-modpack.license b/data/icons/128x128/freeciv21-modpack.license index 31d1312473..8a2b6d8d94 100644 --- a/data/icons/128x128/freeciv21-modpack.license +++ b/data/icons/128x128/freeciv21-modpack.license @@ -1,2 +1,4 @@ SPDX-License-Identifier: GPL-3.0-or-later -SPDX-FileCopyrightText: Freeciv21 and Freeciv Contributors +SPDX-FileCopyrightText: James Blewitt +SPDX-FileCopyrightText: Hugo Flávio +SPDX-FileCopyrightText: Louis Moureaux diff --git a/data/icons/128x128/freeciv21-modpack.png b/data/icons/128x128/freeciv21-modpack.png index e9d3bde093..e29e97da33 100644 Binary files a/data/icons/128x128/freeciv21-modpack.png and b/data/icons/128x128/freeciv21-modpack.png differ diff --git a/data/icons/128x128/freeciv21-ruledit.ico b/data/icons/128x128/freeciv21-ruledit.ico new file mode 100644 index 0000000000..b3112846ec Binary files /dev/null and b/data/icons/128x128/freeciv21-ruledit.ico differ diff --git a/data/icons/128x128/freeciv21-ruledit.license b/data/icons/128x128/freeciv21-ruledit.license new file mode 100644 index 0000000000..8a2b6d8d94 --- /dev/null +++ b/data/icons/128x128/freeciv21-ruledit.license @@ -0,0 +1,4 @@ +SPDX-License-Identifier: GPL-3.0-or-later +SPDX-FileCopyrightText: James Blewitt +SPDX-FileCopyrightText: Hugo Flávio +SPDX-FileCopyrightText: Louis Moureaux diff --git a/data/icons/128x128/freeciv21-ruledit.png b/data/icons/128x128/freeciv21-ruledit.png new file mode 100644 index 0000000000..2f68c1a847 Binary files /dev/null and b/data/icons/128x128/freeciv21-ruledit.png differ diff --git a/data/icons/16x16/freeciv21-client.png.license b/data/icons/16x16/freeciv21-client.png.license index 3b2c1f3699..80a0df00e0 120000 --- a/data/icons/16x16/freeciv21-client.png.license +++ b/data/icons/16x16/freeciv21-client.png.license @@ -1 +1 @@ -../128x128/freeciv21-client.licence \ No newline at end of file +../128x128/freeciv21-client.license \ No newline at end of file diff --git a/data/icons/16x16/freeciv21-modpack.png b/data/icons/16x16/freeciv21-modpack.png index 1f2abeacad..dd5b3f8672 100644 Binary files a/data/icons/16x16/freeciv21-modpack.png and b/data/icons/16x16/freeciv21-modpack.png differ diff --git a/data/icons/16x16/freeciv21-modpack.png.license b/data/icons/16x16/freeciv21-modpack.png.license index 6c6fecb94d..8812bca30c 120000 --- a/data/icons/16x16/freeciv21-modpack.png.license +++ b/data/icons/16x16/freeciv21-modpack.png.license @@ -1 +1 @@ -../128x128/freeciv21-modpack.licence \ No newline at end of file +../128x128/freeciv21-modpack.license \ No newline at end of file diff --git a/data/icons/16x16/freeciv21-ruledit.png b/data/icons/16x16/freeciv21-ruledit.png new file mode 100644 index 0000000000..88477b17ec Binary files /dev/null and b/data/icons/16x16/freeciv21-ruledit.png differ diff --git a/data/icons/16x16/freeciv21-ruledit.png.license b/data/icons/16x16/freeciv21-ruledit.png.license new file mode 120000 index 0000000000..74026026e6 --- /dev/null +++ b/data/icons/16x16/freeciv21-ruledit.png.license @@ -0,0 +1 @@ +../128x128/freeciv21-ruledit.license \ No newline at end of file diff --git a/data/icons/16x16/freeciv21-server.png.license b/data/icons/16x16/freeciv21-server.png.license index 4499e87224..316b36c86e 120000 --- a/data/icons/16x16/freeciv21-server.png.license +++ b/data/icons/16x16/freeciv21-server.png.license @@ -1 +1 @@ -../128x128/freeciv21-server.licence \ No newline at end of file +../128x128/freeciv21-server.license \ No newline at end of file diff --git a/data/icons/32x32/freeciv21-client.png.license b/data/icons/32x32/freeciv21-client.png.license index 3b2c1f3699..80a0df00e0 120000 --- a/data/icons/32x32/freeciv21-client.png.license +++ b/data/icons/32x32/freeciv21-client.png.license @@ -1 +1 @@ -../128x128/freeciv21-client.licence \ No newline at end of file +../128x128/freeciv21-client.license \ No newline at end of file diff --git a/data/icons/32x32/freeciv21-modpack.png b/data/icons/32x32/freeciv21-modpack.png index a6e453ca19..7638459343 100644 Binary files a/data/icons/32x32/freeciv21-modpack.png and b/data/icons/32x32/freeciv21-modpack.png differ diff --git a/data/icons/32x32/freeciv21-modpack.png.license b/data/icons/32x32/freeciv21-modpack.png.license index 6c6fecb94d..8812bca30c 120000 --- a/data/icons/32x32/freeciv21-modpack.png.license +++ b/data/icons/32x32/freeciv21-modpack.png.license @@ -1 +1 @@ -../128x128/freeciv21-modpack.licence \ No newline at end of file +../128x128/freeciv21-modpack.license \ No newline at end of file diff --git a/data/icons/32x32/freeciv21-ruledit.png b/data/icons/32x32/freeciv21-ruledit.png new file mode 100644 index 0000000000..ff7328dada Binary files /dev/null and b/data/icons/32x32/freeciv21-ruledit.png differ diff --git a/data/icons/32x32/freeciv21-ruledit.png.license b/data/icons/32x32/freeciv21-ruledit.png.license new file mode 120000 index 0000000000..74026026e6 --- /dev/null +++ b/data/icons/32x32/freeciv21-ruledit.png.license @@ -0,0 +1 @@ +../128x128/freeciv21-ruledit.license \ No newline at end of file diff --git a/data/icons/32x32/freeciv21-server.png.license b/data/icons/32x32/freeciv21-server.png.license index 4499e87224..316b36c86e 120000 --- a/data/icons/32x32/freeciv21-server.png.license +++ b/data/icons/32x32/freeciv21-server.png.license @@ -1 +1 @@ -../128x128/freeciv21-server.licence \ No newline at end of file +../128x128/freeciv21-server.license \ No newline at end of file diff --git a/data/icons/48x48/freeciv21-client.png.license b/data/icons/48x48/freeciv21-client.png.license index 3b2c1f3699..80a0df00e0 120000 --- a/data/icons/48x48/freeciv21-client.png.license +++ b/data/icons/48x48/freeciv21-client.png.license @@ -1 +1 @@ -../128x128/freeciv21-client.licence \ No newline at end of file +../128x128/freeciv21-client.license \ No newline at end of file diff --git a/data/icons/48x48/freeciv21-modpack.png b/data/icons/48x48/freeciv21-modpack.png index 302b92b6c3..14121732e6 100644 Binary files a/data/icons/48x48/freeciv21-modpack.png and b/data/icons/48x48/freeciv21-modpack.png differ diff --git a/data/icons/48x48/freeciv21-modpack.png.license b/data/icons/48x48/freeciv21-modpack.png.license index 6c6fecb94d..8812bca30c 120000 --- a/data/icons/48x48/freeciv21-modpack.png.license +++ b/data/icons/48x48/freeciv21-modpack.png.license @@ -1 +1 @@ -../128x128/freeciv21-modpack.licence \ No newline at end of file +../128x128/freeciv21-modpack.license \ No newline at end of file diff --git a/data/icons/48x48/freeciv21-ruledit.png b/data/icons/48x48/freeciv21-ruledit.png new file mode 100644 index 0000000000..f317d182f8 Binary files /dev/null and b/data/icons/48x48/freeciv21-ruledit.png differ diff --git a/data/icons/48x48/freeciv21-ruledit.png.license b/data/icons/48x48/freeciv21-ruledit.png.license new file mode 120000 index 0000000000..74026026e6 --- /dev/null +++ b/data/icons/48x48/freeciv21-ruledit.png.license @@ -0,0 +1 @@ +../128x128/freeciv21-ruledit.license \ No newline at end of file diff --git a/data/icons/48x48/freeciv21-server.png.license b/data/icons/48x48/freeciv21-server.png.license index 4499e87224..316b36c86e 120000 --- a/data/icons/48x48/freeciv21-server.png.license +++ b/data/icons/48x48/freeciv21-server.png.license @@ -1 +1 @@ -../128x128/freeciv21-server.licence \ No newline at end of file +../128x128/freeciv21-server.license \ No newline at end of file diff --git a/data/icons/64x64/freeciv21-client.png.license b/data/icons/64x64/freeciv21-client.png.license index 3b2c1f3699..80a0df00e0 120000 --- a/data/icons/64x64/freeciv21-client.png.license +++ b/data/icons/64x64/freeciv21-client.png.license @@ -1 +1 @@ -../128x128/freeciv21-client.licence \ No newline at end of file +../128x128/freeciv21-client.license \ No newline at end of file diff --git a/data/icons/64x64/freeciv21-modpack.png b/data/icons/64x64/freeciv21-modpack.png index d90bedab45..8b57d846f7 100644 Binary files a/data/icons/64x64/freeciv21-modpack.png and b/data/icons/64x64/freeciv21-modpack.png differ diff --git a/data/icons/64x64/freeciv21-modpack.png.license b/data/icons/64x64/freeciv21-modpack.png.license index 6c6fecb94d..8812bca30c 120000 --- a/data/icons/64x64/freeciv21-modpack.png.license +++ b/data/icons/64x64/freeciv21-modpack.png.license @@ -1 +1 @@ -../128x128/freeciv21-modpack.licence \ No newline at end of file +../128x128/freeciv21-modpack.license \ No newline at end of file diff --git a/data/icons/64x64/freeciv21-ruledit.png b/data/icons/64x64/freeciv21-ruledit.png new file mode 100644 index 0000000000..ddfeabb4b1 Binary files /dev/null and b/data/icons/64x64/freeciv21-ruledit.png differ diff --git a/data/icons/64x64/freeciv21-ruledit.png.license b/data/icons/64x64/freeciv21-ruledit.png.license new file mode 120000 index 0000000000..74026026e6 --- /dev/null +++ b/data/icons/64x64/freeciv21-ruledit.png.license @@ -0,0 +1 @@ +../128x128/freeciv21-ruledit.license \ No newline at end of file diff --git a/data/icons/64x64/freeciv21-server.png.license b/data/icons/64x64/freeciv21-server.png.license index 4499e87224..316b36c86e 120000 --- a/data/icons/64x64/freeciv21-server.png.license +++ b/data/icons/64x64/freeciv21-server.png.license @@ -1 +1 @@ -../128x128/freeciv21-server.licence \ No newline at end of file +../128x128/freeciv21-server.license \ No newline at end of file diff --git a/data/multiplayer/units.ruleset b/data/multiplayer/units.ruleset index 271874b364..27db888cdf 100644 --- a/data/multiplayer/units.ruleset +++ b/data/multiplayer/units.ruleset @@ -410,8 +410,8 @@ flags = "Unreachable", "DoesntOccupyTile" ; "Explorer" = unit to use for exploring ; "Hut" = can be found in a hut ; "HutTech" = can be found in a hut, but its techs required -; "Partisan" = can be created as a partisan (only one unit can have this -; flag), see end of this file for its tech requirements option +; "Partisan" = can be created as a partisan if the +; Inspire_Partisans effect is enabled ; "DefendOk" = AI hint: ok for defending with ; "DefendGood" = AI hint: good for defending with ; "Ferryboat" = AI hint: useful for ferrying diff --git a/data/royale/units.ruleset b/data/royale/units.ruleset index c9b8a4c967..d40776e0b1 100644 --- a/data/royale/units.ruleset +++ b/data/royale/units.ruleset @@ -446,8 +446,8 @@ flags = "Unreachable", "DoesntOccupyTile", "CanPillage", "Airliftable" ; "Explorer" = unit to use for exploring ; "Hut" = can be found in a hut ; "HutTech" = can be found in a hut, but its techs required -; "Partisan" = can be created as a partisan (only one unit can have this -; flag), see end of this file for its tech requirements option +; "Partisan" = can be created as a partisan if the +; Inspire_Partisans effect is enabled ; "DefendOk" = AI hint: ok for defending with ; "DefendGood" = AI hint: good for defending with ; "Ferryboat" = AI hint: useful for ferrying diff --git a/data/sandbox/units.ruleset b/data/sandbox/units.ruleset index df56485063..07ca84829a 100644 --- a/data/sandbox/units.ruleset +++ b/data/sandbox/units.ruleset @@ -438,8 +438,8 @@ flags = "Unreachable", "DoesntOccupyTile", "CanPillage", "MediumWeight" ; "Explorer" = unit to use for exploring ; "Hut" = can be found in a hut ; "HutTech" = can be found in a hut, but its techs required -; "Partisan" = can be created as a partisan (only one unit can have this -; flag), see end of this file for its tech requirements option +; "Partisan" = can be created as a partisan if the +; Inspire_Partisans effect is enabled ; "DefendOk" = AI hint: ok for defending with ; "DefendGood" = AI hint: good for defending with ; "Ferryboat" = AI hint: useful for ferrying diff --git a/data/stub/units.ruleset b/data/stub/units.ruleset index 4aac8a3670..1884e7a7ef 100644 --- a/data/stub/units.ruleset +++ b/data/stub/units.ruleset @@ -324,8 +324,8 @@ flags = "" ; "Explorer" = unit to use for exploring ; "Hut" = can be found in a hut ; "HutTech" = can be found in a hut, but its techs required -; "Partisan" = can be created as a partisan (only one unit can have this -; flag), see end of this file for its tech requirements option +; "Partisan" = can be created as a partisan if the +; Inspire_Partisans effect is enabled ; "DefendOk" = AI hint: ok for defending with ; "DefendGood" = AI hint: good for defending with ; "Ferryboat" = AI hint: useful for ferrying diff --git a/data/tests/CMakeLists.txt b/data/tests/CMakeLists.txt index d184c35eb0..c44f494940 100644 --- a/data/tests/CMakeLists.txt +++ b/data/tests/CMakeLists.txt @@ -15,7 +15,7 @@ file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/$/rulesets.cpp INPUT ${CMAKE_CURRENT_BINARY_DIR}/rulesets.cpp.in) add_executable(test_rulesets ${CMAKE_CURRENT_BINARY_DIR}/$/rulesets.cpp) -target_link_libraries(test_rulesets PRIVATE Qt5::Test) +target_link_libraries(test_rulesets PRIVATE Qt6::Test) add_test(NAME test_rulesets COMMAND test_rulesets WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}") diff --git a/data/themes/gui-qt/Classic/arrow-down.png b/data/themes/Classic/arrow-down.png similarity index 100% rename from data/themes/gui-qt/Classic/arrow-down.png rename to data/themes/Classic/arrow-down.png diff --git a/data/themes/gui-qt/Classic/arrow-left.png b/data/themes/Classic/arrow-left.png similarity index 100% rename from data/themes/gui-qt/Classic/arrow-left.png rename to data/themes/Classic/arrow-left.png diff --git a/data/themes/gui-qt/Classic/arrow-right.png b/data/themes/Classic/arrow-right.png similarity index 100% rename from data/themes/gui-qt/Classic/arrow-right.png rename to data/themes/Classic/arrow-right.png diff --git a/data/themes/gui-qt/Classic/arrow-up.png b/data/themes/Classic/arrow-up.png similarity index 100% rename from data/themes/gui-qt/Classic/arrow-up.png rename to data/themes/Classic/arrow-up.png diff --git a/data/themes/gui-qt/Classic/button-default.png b/data/themes/Classic/button-default.png similarity index 100% rename from data/themes/gui-qt/Classic/button-default.png rename to data/themes/Classic/button-default.png diff --git a/data/themes/gui-qt/Classic/button-insensitive.png b/data/themes/Classic/button-insensitive.png similarity index 100% rename from data/themes/gui-qt/Classic/button-insensitive.png rename to data/themes/Classic/button-insensitive.png diff --git a/data/themes/gui-qt/Classic/button-prelight.png b/data/themes/Classic/button-prelight.png similarity index 100% rename from data/themes/gui-qt/Classic/button-prelight.png rename to data/themes/Classic/button-prelight.png diff --git a/data/themes/gui-qt/Classic/button-pressed.png b/data/themes/Classic/button-pressed.png similarity index 100% rename from data/themes/gui-qt/Classic/button-pressed.png rename to data/themes/Classic/button-pressed.png diff --git a/data/themes/gui-qt/Classic/check4.png b/data/themes/Classic/check4.png similarity index 100% rename from data/themes/gui-qt/Classic/check4.png rename to data/themes/Classic/check4.png diff --git a/data/themes/gui-qt/Classic/checkbox-checked-pressed.png b/data/themes/Classic/checkbox-checked-pressed.png similarity index 100% rename from data/themes/gui-qt/Classic/checkbox-checked-pressed.png rename to data/themes/Classic/checkbox-checked-pressed.png diff --git a/data/themes/gui-qt/Classic/checkbox-checked.png b/data/themes/Classic/checkbox-checked.png similarity index 100% rename from data/themes/gui-qt/Classic/checkbox-checked.png rename to data/themes/Classic/checkbox-checked.png diff --git a/data/themes/gui-qt/Classic/checkbox-unchecked.png b/data/themes/Classic/checkbox-unchecked.png similarity index 100% rename from data/themes/gui-qt/Classic/checkbox-unchecked.png rename to data/themes/Classic/checkbox-unchecked.png diff --git a/data/themes/gui-qt/Classic/combo-arrow.png b/data/themes/Classic/combo-arrow.png similarity index 100% rename from data/themes/gui-qt/Classic/combo-arrow.png rename to data/themes/Classic/combo-arrow.png diff --git a/data/themes/gui-qt/Classic/combo-normal.png b/data/themes/Classic/combo-normal.png similarity index 100% rename from data/themes/gui-qt/Classic/combo-normal.png rename to data/themes/Classic/combo-normal.png diff --git a/data/themes/gui-qt/Classic/menu-overlay.png b/data/themes/Classic/menu-overlay.png similarity index 100% rename from data/themes/gui-qt/Classic/menu-overlay.png rename to data/themes/Classic/menu-overlay.png diff --git a/data/themes/gui-qt/Classic/menuline.png b/data/themes/Classic/menuline.png similarity index 100% rename from data/themes/gui-qt/Classic/menuline.png rename to data/themes/Classic/menuline.png diff --git a/data/themes/gui-qt/Classic/pattern.png b/data/themes/Classic/pattern.png similarity index 100% rename from data/themes/gui-qt/Classic/pattern.png rename to data/themes/Classic/pattern.png diff --git a/data/themes/gui-qt/Classic/radio-checked.png b/data/themes/Classic/radio-checked.png similarity index 100% rename from data/themes/gui-qt/Classic/radio-checked.png rename to data/themes/Classic/radio-checked.png diff --git a/data/themes/gui-qt/Classic/radio-unchecked.png b/data/themes/Classic/radio-unchecked.png similarity index 100% rename from data/themes/gui-qt/Classic/radio-unchecked.png rename to data/themes/Classic/radio-unchecked.png diff --git a/data/themes/gui-qt/Classic/resource.qss b/data/themes/Classic/resource.qss similarity index 97% rename from data/themes/gui-qt/Classic/resource.qss rename to data/themes/Classic/resource.qss index 6d0f6cb5c8..835082f1a6 100644 --- a/data/themes/gui-qt/Classic/resource.qss +++ b/data/themes/Classic/resource.qss @@ -82,6 +82,23 @@ resize_widget background: #ddca97; } +QPushButton[main_pagebt="true"] { + font-size: 1.5em; + padding: 0.2em 1em; + min-height: 32px; + min-width: 200px; +} + +QPushButton, QToolButton { + border-image: url(LittleFingerbutton-default.png) 3 3 3 3; + border-top: 4px e0d2b2; + border-bottom: 4px e0d2b2; + border-right: 4px e0d2b2; + border-left: 4px e0d2b2; + border-radius: 4px; + padding: 4px; +} + QPushButton, QToolButton { border-image: url(LittleFingerbutton-default.png) 3 3 3 3; border-top: 3px transparent; diff --git a/data/themes/gui-qt/Classic/splitter-horizontal.png b/data/themes/Classic/splitter-horizontal.png similarity index 100% rename from data/themes/gui-qt/Classic/splitter-horizontal.png rename to data/themes/Classic/splitter-horizontal.png diff --git a/data/themes/gui-qt/Classic/splitter-vertical.png b/data/themes/Classic/splitter-vertical.png similarity index 100% rename from data/themes/gui-qt/Classic/splitter-vertical.png rename to data/themes/Classic/splitter-vertical.png diff --git a/data/themes/gui-qt/Classic/theme.conf b/data/themes/Classic/theme.conf similarity index 100% rename from data/themes/gui-qt/Classic/theme.conf rename to data/themes/Classic/theme.conf diff --git a/data/themes/gui-qt/Classic/wheel.png b/data/themes/Classic/wheel.png similarity index 100% rename from data/themes/gui-qt/Classic/wheel.png rename to data/themes/Classic/wheel.png diff --git a/data/themes/gui-qt/NightStalker/ai.png b/data/themes/NightStalker/ai.png similarity index 100% rename from data/themes/gui-qt/NightStalker/ai.png rename to data/themes/NightStalker/ai.png diff --git a/data/themes/gui-qt/NightStalker/arrow-down.png b/data/themes/NightStalker/arrow-down.png similarity index 100% rename from data/themes/gui-qt/NightStalker/arrow-down.png rename to data/themes/NightStalker/arrow-down.png diff --git a/data/themes/gui-qt/NightStalker/arrow-left.png b/data/themes/NightStalker/arrow-left.png similarity index 100% rename from data/themes/gui-qt/NightStalker/arrow-left.png rename to data/themes/NightStalker/arrow-left.png diff --git a/data/themes/gui-qt/NightStalker/arrow-right.png b/data/themes/NightStalker/arrow-right.png similarity index 100% rename from data/themes/gui-qt/NightStalker/arrow-right.png rename to data/themes/NightStalker/arrow-right.png diff --git a/data/themes/gui-qt/NightStalker/arrow-up.png b/data/themes/NightStalker/arrow-up.png similarity index 100% rename from data/themes/gui-qt/NightStalker/arrow-up.png rename to data/themes/NightStalker/arrow-up.png diff --git a/data/themes/gui-qt/NightStalker/checkbox-checked-pressed.png b/data/themes/NightStalker/checkbox-checked-pressed.png similarity index 100% rename from data/themes/gui-qt/NightStalker/checkbox-checked-pressed.png rename to data/themes/NightStalker/checkbox-checked-pressed.png diff --git a/data/themes/gui-qt/NightStalker/checkbox-checked.png b/data/themes/NightStalker/checkbox-checked.png similarity index 100% rename from data/themes/gui-qt/NightStalker/checkbox-checked.png rename to data/themes/NightStalker/checkbox-checked.png diff --git a/data/themes/gui-qt/NightStalker/checkbox-unchecked-pressed.png b/data/themes/NightStalker/checkbox-unchecked-pressed.png similarity index 100% rename from data/themes/gui-qt/NightStalker/checkbox-unchecked-pressed.png rename to data/themes/NightStalker/checkbox-unchecked-pressed.png diff --git a/data/themes/gui-qt/NightStalker/checkbox-unchecked.png b/data/themes/NightStalker/checkbox-unchecked.png similarity index 100% rename from data/themes/gui-qt/NightStalker/checkbox-unchecked.png rename to data/themes/NightStalker/checkbox-unchecked.png diff --git a/data/themes/gui-qt/NightStalker/city-close.png b/data/themes/NightStalker/city-close.png similarity index 100% rename from data/themes/gui-qt/NightStalker/city-close.png rename to data/themes/NightStalker/city-close.png diff --git a/data/themes/gui-qt/NightStalker/city-left.png b/data/themes/NightStalker/city-left.png similarity index 100% rename from data/themes/gui-qt/NightStalker/city-left.png rename to data/themes/NightStalker/city-left.png diff --git a/data/themes/gui-qt/NightStalker/city-right.png b/data/themes/NightStalker/city-right.png similarity index 100% rename from data/themes/gui-qt/NightStalker/city-right.png rename to data/themes/NightStalker/city-right.png diff --git a/data/themes/gui-qt/NightStalker/combo-arrow.png b/data/themes/NightStalker/combo-arrow.png similarity index 100% rename from data/themes/gui-qt/NightStalker/combo-arrow.png rename to data/themes/NightStalker/combo-arrow.png diff --git a/data/themes/gui-qt/NightStalker/human.png b/data/themes/NightStalker/human.png similarity index 100% rename from data/themes/gui-qt/NightStalker/human.png rename to data/themes/NightStalker/human.png diff --git a/data/themes/gui-qt/NightStalker/pattern-game.png b/data/themes/NightStalker/pattern-game.png similarity index 100% rename from data/themes/gui-qt/NightStalker/pattern-game.png rename to data/themes/NightStalker/pattern-game.png diff --git a/data/themes/gui-qt/NightStalker/pattern.png b/data/themes/NightStalker/pattern.png similarity index 100% rename from data/themes/gui-qt/NightStalker/pattern.png rename to data/themes/NightStalker/pattern.png diff --git a/data/themes/gui-qt/NightStalker/radio-checked.png b/data/themes/NightStalker/radio-checked.png similarity index 100% rename from data/themes/gui-qt/NightStalker/radio-checked.png rename to data/themes/NightStalker/radio-checked.png diff --git a/data/themes/gui-qt/NightStalker/radio-unchecked.png b/data/themes/NightStalker/radio-unchecked.png similarity index 100% rename from data/themes/gui-qt/NightStalker/radio-unchecked.png rename to data/themes/NightStalker/radio-unchecked.png diff --git a/data/themes/gui-qt/NightStalker/resource.qss b/data/themes/NightStalker/resource.qss similarity index 99% rename from data/themes/gui-qt/NightStalker/resource.qss rename to data/themes/NightStalker/resource.qss index de642c2854..2e05706938 100644 --- a/data/themes/gui-qt/NightStalker/resource.qss +++ b/data/themes/NightStalker/resource.qss @@ -103,18 +103,20 @@ resize_widget QPushButton[main_pagebt="true"] { color: white; - min-height: 40px; + font-size: 1.5em; + padding: 0.2em 1em; + min-height: 32px; min-width: 200px; background: #000330; border: 2px solid #1237FF; - border-radius: 0px; - padding: 0px; + border-radius: 4px; + padding: 4px; } QPushButton:hover[main_pagebt="true"] { color: white; background: #000330; - border: 3px solid #3399FF; + border: 4px solid #3399FF; } QPushButton, QToolButton { diff --git a/data/themes/gui-qt/NightStalker/splitter-horizontal.png b/data/themes/NightStalker/splitter-horizontal.png similarity index 100% rename from data/themes/gui-qt/NightStalker/splitter-horizontal.png rename to data/themes/NightStalker/splitter-horizontal.png diff --git a/data/themes/gui-qt/NightStalker/splitter-vertical.png b/data/themes/NightStalker/splitter-vertical.png similarity index 100% rename from data/themes/gui-qt/NightStalker/splitter-vertical.png rename to data/themes/NightStalker/splitter-vertical.png diff --git a/data/themes/gui-qt/NightStalker/sun.png b/data/themes/NightStalker/sun.png similarity index 100% rename from data/themes/gui-qt/NightStalker/sun.png rename to data/themes/NightStalker/sun.png diff --git a/data/themes/gui-qt/NightStalker/theme.conf b/data/themes/NightStalker/theme.conf similarity index 100% rename from data/themes/gui-qt/NightStalker/theme.conf rename to data/themes/NightStalker/theme.conf diff --git a/data/themes/gui-qt/NightStalker/wheel.png b/data/themes/NightStalker/wheel.png similarity index 100% rename from data/themes/gui-qt/NightStalker/wheel.png rename to data/themes/NightStalker/wheel.png diff --git a/data/themes/gui-qt/icons/ai.png b/data/themes/icons/ai.png similarity index 100% rename from data/themes/gui-qt/icons/ai.png rename to data/themes/icons/ai.png diff --git a/data/themes/gui-qt/icons/automate.png b/data/themes/icons/automate.png similarity index 100% rename from data/themes/gui-qt/icons/automate.png rename to data/themes/icons/automate.png diff --git a/data/themes/gui-qt/icons/buildroad.png b/data/themes/icons/buildroad.png similarity index 100% rename from data/themes/gui-qt/icons/buildroad.png rename to data/themes/icons/buildroad.png diff --git a/data/themes/gui-qt/icons/buildroad.svg b/data/themes/icons/buildroad.svg similarity index 100% rename from data/themes/gui-qt/icons/buildroad.svg rename to data/themes/icons/buildroad.svg diff --git a/data/themes/gui-qt/icons/buildroad.svg.license b/data/themes/icons/buildroad.svg.license similarity index 100% rename from data/themes/gui-qt/icons/buildroad.svg.license rename to data/themes/icons/buildroad.svg.license diff --git a/data/themes/gui-qt/icons/cclose.png b/data/themes/icons/cclose.png similarity index 100% rename from data/themes/gui-qt/icons/cclose.png rename to data/themes/icons/cclose.png diff --git a/data/themes/gui-qt/icons/chopchop.png b/data/themes/icons/chopchop.png similarity index 100% rename from data/themes/gui-qt/icons/chopchop.png rename to data/themes/icons/chopchop.png diff --git a/data/themes/gui-qt/icons/chopchop.svg b/data/themes/icons/chopchop.svg similarity index 100% rename from data/themes/gui-qt/icons/chopchop.svg rename to data/themes/icons/chopchop.svg diff --git a/data/themes/gui-qt/icons/chopchop.svg.license b/data/themes/icons/chopchop.svg.license similarity index 100% rename from data/themes/gui-qt/icons/chopchop.svg.license rename to data/themes/icons/chopchop.svg.license diff --git a/data/themes/gui-qt/icons/cities.png b/data/themes/icons/cities.png similarity index 100% rename from data/themes/gui-qt/icons/cities.png rename to data/themes/icons/cities.png diff --git a/data/themes/gui-qt/icons/cities.svg b/data/themes/icons/cities.svg similarity index 100% rename from data/themes/gui-qt/icons/cities.svg rename to data/themes/icons/cities.svg diff --git a/data/themes/gui-qt/icons/cities.svg.license b/data/themes/icons/cities.svg.license similarity index 100% rename from data/themes/gui-qt/icons/cities.svg.license rename to data/themes/icons/cities.svg.license diff --git a/data/themes/gui-qt/icons/city-close.png b/data/themes/icons/city-close.png similarity index 100% rename from data/themes/gui-qt/icons/city-close.png rename to data/themes/icons/city-close.png diff --git a/data/themes/gui-qt/icons/city-left.png b/data/themes/icons/city-left.png similarity index 100% rename from data/themes/gui-qt/icons/city-left.png rename to data/themes/icons/city-left.png diff --git a/data/themes/gui-qt/icons/city-right.png b/data/themes/icons/city-right.png similarity index 100% rename from data/themes/gui-qt/icons/city-right.png rename to data/themes/icons/city-right.png diff --git a/data/themes/gui-qt/icons/close.png b/data/themes/icons/close.png similarity index 100% rename from data/themes/gui-qt/icons/close.png rename to data/themes/icons/close.png diff --git a/data/themes/gui-qt/icons/cmax.png b/data/themes/icons/cmax.png similarity index 100% rename from data/themes/gui-qt/icons/cmax.png rename to data/themes/icons/cmax.png diff --git a/data/themes/gui-qt/icons/cmin.png b/data/themes/icons/cmin.png similarity index 100% rename from data/themes/gui-qt/icons/cmin.png rename to data/themes/icons/cmin.png diff --git a/data/themes/gui-qt/icons/control.png b/data/themes/icons/control.png similarity index 100% rename from data/themes/gui-qt/icons/control.png rename to data/themes/icons/control.png diff --git a/data/themes/gui-qt/icons/done.png b/data/themes/icons/done.png similarity index 100% rename from data/themes/gui-qt/icons/done.png rename to data/themes/icons/done.png diff --git a/data/themes/gui-qt/icons/done.svg b/data/themes/icons/done.svg similarity index 100% rename from data/themes/gui-qt/icons/done.svg rename to data/themes/icons/done.svg diff --git a/data/themes/gui-qt/icons/done.svg.license b/data/themes/icons/done.svg.license similarity index 100% rename from data/themes/gui-qt/icons/done.svg.license rename to data/themes/icons/done.svg.license diff --git a/data/themes/gui-qt/icons/economy.png b/data/themes/icons/economy.png similarity index 100% rename from data/themes/gui-qt/icons/economy.png rename to data/themes/icons/economy.png diff --git a/data/themes/gui-qt/icons/economy.svg b/data/themes/icons/economy.svg similarity index 100% rename from data/themes/gui-qt/icons/economy.svg rename to data/themes/icons/economy.svg diff --git a/data/themes/gui-qt/icons/economy.svg.license b/data/themes/icons/economy.svg.license similarity index 100% rename from data/themes/gui-qt/icons/economy.svg.license rename to data/themes/icons/economy.svg.license diff --git a/data/themes/gui-qt/icons/erase.svg b/data/themes/icons/erase.svg similarity index 100% rename from data/themes/gui-qt/icons/erase.svg rename to data/themes/icons/erase.svg diff --git a/data/themes/gui-qt/icons/erase.svg.license b/data/themes/icons/erase.svg.license similarity index 100% rename from data/themes/gui-qt/icons/erase.svg.license rename to data/themes/icons/erase.svg.license diff --git a/data/themes/gui-qt/icons/expand-down.svg b/data/themes/icons/expand-down.svg similarity index 100% rename from data/themes/gui-qt/icons/expand-down.svg rename to data/themes/icons/expand-down.svg diff --git a/data/themes/gui-qt/icons/expand-down.svg.license b/data/themes/icons/expand-down.svg.license similarity index 100% rename from data/themes/gui-qt/icons/expand-down.svg.license rename to data/themes/icons/expand-down.svg.license diff --git a/data/themes/gui-qt/icons/expand-up.svg b/data/themes/icons/expand-up.svg similarity index 100% rename from data/themes/gui-qt/icons/expand-up.svg rename to data/themes/icons/expand-up.svg diff --git a/data/themes/gui-qt/icons/expand-up.svg.license b/data/themes/icons/expand-up.svg.license similarity index 100% rename from data/themes/gui-qt/icons/expand-up.svg.license rename to data/themes/icons/expand-up.svg.license diff --git a/data/themes/gui-qt/icons/flag-active.svg b/data/themes/icons/flag-active.svg similarity index 100% rename from data/themes/gui-qt/icons/flag-active.svg rename to data/themes/icons/flag-active.svg diff --git a/data/themes/gui-qt/icons/flag-active.svg.license b/data/themes/icons/flag-active.svg.license similarity index 100% rename from data/themes/gui-qt/icons/flag-active.svg.license rename to data/themes/icons/flag-active.svg.license diff --git a/data/themes/gui-qt/icons/flag.svg b/data/themes/icons/flag.svg similarity index 100% rename from data/themes/gui-qt/icons/flag.svg rename to data/themes/icons/flag.svg diff --git a/data/themes/gui-qt/icons/flag.svg.license b/data/themes/icons/flag.svg.license similarity index 100% rename from data/themes/gui-qt/icons/flag.svg.license rename to data/themes/icons/flag.svg.license diff --git a/data/themes/gui-qt/icons/fortify.png b/data/themes/icons/fortify.png similarity index 100% rename from data/themes/gui-qt/icons/fortify.png rename to data/themes/icons/fortify.png diff --git a/data/themes/gui-qt/icons/fortify.svg b/data/themes/icons/fortify.svg similarity index 100% rename from data/themes/gui-qt/icons/fortify.svg rename to data/themes/icons/fortify.svg diff --git a/data/themes/gui-qt/icons/fortify.svg.license b/data/themes/icons/fortify.svg.license similarity index 100% rename from data/themes/gui-qt/icons/fortify.svg.license rename to data/themes/icons/fortify.svg.license diff --git a/data/themes/gui-qt/icons/globe.svg b/data/themes/icons/globe.svg similarity index 100% rename from data/themes/gui-qt/icons/globe.svg rename to data/themes/icons/globe.svg diff --git a/data/themes/gui-qt/icons/globe.svg.license b/data/themes/icons/globe.svg.license similarity index 100% rename from data/themes/gui-qt/icons/globe.svg.license rename to data/themes/icons/globe.svg.license diff --git a/data/themes/gui-qt/icons/go-down.png b/data/themes/icons/go-down.png similarity index 100% rename from data/themes/gui-qt/icons/go-down.png rename to data/themes/icons/go-down.png diff --git a/data/themes/gui-qt/icons/go-up.png b/data/themes/icons/go-up.png similarity index 100% rename from data/themes/gui-qt/icons/go-up.png rename to data/themes/icons/go-up.png diff --git a/data/themes/gui-qt/icons/goto.png b/data/themes/icons/goto.png similarity index 100% rename from data/themes/gui-qt/icons/goto.png rename to data/themes/icons/goto.png diff --git a/data/themes/gui-qt/icons/goto.svg b/data/themes/icons/goto.svg similarity index 100% rename from data/themes/gui-qt/icons/goto.svg rename to data/themes/icons/goto.svg diff --git a/data/themes/gui-qt/icons/goto.svg.license b/data/themes/icons/goto.svg.license similarity index 100% rename from data/themes/gui-qt/icons/goto.svg.license rename to data/themes/icons/goto.svg.license diff --git a/data/themes/gui-qt/icons/help-donate.png b/data/themes/icons/help-donate.png similarity index 100% rename from data/themes/gui-qt/icons/help-donate.png rename to data/themes/icons/help-donate.png diff --git a/data/themes/gui-qt/icons/hfood.png b/data/themes/icons/hfood.png similarity index 100% rename from data/themes/gui-qt/icons/hfood.png rename to data/themes/icons/hfood.png diff --git a/data/themes/gui-qt/icons/hfood.svg b/data/themes/icons/hfood.svg similarity index 100% rename from data/themes/gui-qt/icons/hfood.svg rename to data/themes/icons/hfood.svg diff --git a/data/themes/gui-qt/icons/hfood.svg.license b/data/themes/icons/hfood.svg.license similarity index 100% rename from data/themes/gui-qt/icons/hfood.svg.license rename to data/themes/icons/hfood.svg.license diff --git a/data/themes/gui-qt/icons/hgold.png b/data/themes/icons/hgold.png similarity index 100% rename from data/themes/gui-qt/icons/hgold.png rename to data/themes/icons/hgold.png diff --git a/data/themes/gui-qt/icons/home.png b/data/themes/icons/home.png similarity index 100% rename from data/themes/gui-qt/icons/home.png rename to data/themes/icons/home.png diff --git a/data/themes/gui-qt/icons/hprod.png b/data/themes/icons/hprod.png similarity index 100% rename from data/themes/gui-qt/icons/hprod.png rename to data/themes/icons/hprod.png diff --git a/data/themes/gui-qt/icons/hprod.svg b/data/themes/icons/hprod.svg similarity index 100% rename from data/themes/gui-qt/icons/hprod.svg rename to data/themes/icons/hprod.svg diff --git a/data/themes/gui-qt/icons/hprod.svg.license b/data/themes/icons/hprod.svg.license similarity index 100% rename from data/themes/gui-qt/icons/hprod.svg.license rename to data/themes/icons/hprod.svg.license diff --git a/data/themes/gui-qt/icons/hsci.png b/data/themes/icons/hsci.png similarity index 100% rename from data/themes/gui-qt/icons/hsci.png rename to data/themes/icons/hsci.png diff --git a/data/themes/gui-qt/icons/hsci.svg b/data/themes/icons/hsci.svg similarity index 100% rename from data/themes/gui-qt/icons/hsci.svg rename to data/themes/icons/hsci.svg diff --git a/data/themes/gui-qt/icons/hsci.svg.license b/data/themes/icons/hsci.svg.license similarity index 100% rename from data/themes/gui-qt/icons/hsci.svg.license rename to data/themes/icons/hsci.svg.license diff --git a/data/themes/gui-qt/icons/htrade.png b/data/themes/icons/htrade.png similarity index 100% rename from data/themes/gui-qt/icons/htrade.png rename to data/themes/icons/htrade.png diff --git a/data/themes/gui-qt/icons/htrade.svg b/data/themes/icons/htrade.svg similarity index 100% rename from data/themes/gui-qt/icons/htrade.svg rename to data/themes/icons/htrade.svg diff --git a/data/themes/gui-qt/icons/htrade.svg.license b/data/themes/icons/htrade.svg.license similarity index 100% rename from data/themes/gui-qt/icons/htrade.svg.license rename to data/themes/icons/htrade.svg.license diff --git a/data/themes/gui-qt/icons/human.png b/data/themes/icons/human.png similarity index 100% rename from data/themes/gui-qt/icons/human.png rename to data/themes/icons/human.png diff --git a/data/themes/gui-qt/icons/irrigation.png b/data/themes/icons/irrigation.png similarity index 100% rename from data/themes/gui-qt/icons/irrigation.png rename to data/themes/icons/irrigation.png diff --git a/data/themes/gui-qt/icons/irrigation.svg b/data/themes/icons/irrigation.svg similarity index 100% rename from data/themes/gui-qt/icons/irrigation.svg rename to data/themes/icons/irrigation.svg diff --git a/data/themes/gui-qt/icons/irrigation.svg.license b/data/themes/icons/irrigation.svg.license similarity index 100% rename from data/themes/gui-qt/icons/irrigation.svg.license rename to data/themes/icons/irrigation.svg.license diff --git a/data/themes/gui-qt/icons/list-add.png b/data/themes/icons/list-add.png similarity index 100% rename from data/themes/gui-qt/icons/list-add.png rename to data/themes/icons/list-add.png diff --git a/data/themes/gui-qt/icons/load.png b/data/themes/icons/load.png similarity index 100% rename from data/themes/gui-qt/icons/load.png rename to data/themes/icons/load.png diff --git a/data/themes/gui-qt/icons/meeting-observer.png b/data/themes/icons/meeting-observer.png similarity index 100% rename from data/themes/gui-qt/icons/meeting-observer.png rename to data/themes/icons/meeting-observer.png diff --git a/data/themes/gui-qt/icons/messages.svg b/data/themes/icons/messages.svg similarity index 100% rename from data/themes/gui-qt/icons/messages.svg rename to data/themes/icons/messages.svg diff --git a/data/themes/gui-qt/icons/messages.svg.license b/data/themes/icons/messages.svg.license similarity index 100% rename from data/themes/gui-qt/icons/messages.svg.license rename to data/themes/icons/messages.svg.license diff --git a/data/themes/gui-qt/icons/mine.png b/data/themes/icons/mine.png similarity index 100% rename from data/themes/gui-qt/icons/mine.png rename to data/themes/icons/mine.png diff --git a/data/themes/gui-qt/icons/mine.svg b/data/themes/icons/mine.svg similarity index 100% rename from data/themes/gui-qt/icons/mine.svg rename to data/themes/icons/mine.svg diff --git a/data/themes/gui-qt/icons/mine.svg.license b/data/themes/icons/mine.svg.license similarity index 100% rename from data/themes/gui-qt/icons/mine.svg.license rename to data/themes/icons/mine.svg.license diff --git a/data/themes/gui-qt/icons/minus.png b/data/themes/icons/minus.png similarity index 100% rename from data/themes/gui-qt/icons/minus.png rename to data/themes/icons/minus.png diff --git a/data/themes/gui-qt/icons/move.png b/data/themes/icons/move.png similarity index 100% rename from data/themes/gui-qt/icons/move.png rename to data/themes/icons/move.png diff --git a/data/themes/gui-qt/icons/move.svg b/data/themes/icons/move.svg similarity index 100% rename from data/themes/gui-qt/icons/move.svg rename to data/themes/icons/move.svg diff --git a/data/themes/gui-qt/icons/move.svg.license b/data/themes/icons/move.svg.license similarity index 100% rename from data/themes/gui-qt/icons/move.svg.license rename to data/themes/icons/move.svg.license diff --git a/data/themes/gui-qt/icons/next.svg b/data/themes/icons/next.svg similarity index 100% rename from data/themes/gui-qt/icons/next.svg rename to data/themes/icons/next.svg diff --git a/data/themes/gui-qt/icons/next.svg.license b/data/themes/icons/next.svg.license similarity index 100% rename from data/themes/gui-qt/icons/next.svg.license rename to data/themes/icons/next.svg.license diff --git a/data/themes/gui-qt/icons/notify.svg b/data/themes/icons/notify.svg similarity index 100% rename from data/themes/gui-qt/icons/notify.svg rename to data/themes/icons/notify.svg diff --git a/data/themes/gui-qt/icons/notify.svg.license b/data/themes/icons/notify.svg.license similarity index 100% rename from data/themes/gui-qt/icons/notify.svg.license rename to data/themes/icons/notify.svg.license diff --git a/data/themes/gui-qt/icons/nuke.png b/data/themes/icons/nuke.png similarity index 100% rename from data/themes/gui-qt/icons/nuke.png rename to data/themes/icons/nuke.png diff --git a/data/themes/gui-qt/icons/nuke.svg b/data/themes/icons/nuke.svg similarity index 100% rename from data/themes/gui-qt/icons/nuke.svg rename to data/themes/icons/nuke.svg diff --git a/data/themes/gui-qt/icons/nuke.svg.license b/data/themes/icons/nuke.svg.license similarity index 100% rename from data/themes/gui-qt/icons/nuke.svg.license rename to data/themes/icons/nuke.svg.license diff --git a/data/themes/gui-qt/icons/paradrop.png b/data/themes/icons/paradrop.png similarity index 100% rename from data/themes/gui-qt/icons/paradrop.png rename to data/themes/icons/paradrop.png diff --git a/data/themes/gui-qt/icons/paradrop.svg b/data/themes/icons/paradrop.svg similarity index 100% rename from data/themes/gui-qt/icons/paradrop.svg rename to data/themes/icons/paradrop.svg diff --git a/data/themes/gui-qt/icons/paradrop.svg.license b/data/themes/icons/paradrop.svg.license similarity index 100% rename from data/themes/gui-qt/icons/paradrop.svg.license rename to data/themes/icons/paradrop.svg.license diff --git a/data/themes/gui-qt/icons/pillage.svg b/data/themes/icons/pillage.svg similarity index 100% rename from data/themes/gui-qt/icons/pillage.svg rename to data/themes/icons/pillage.svg diff --git a/data/themes/gui-qt/icons/pillage.svg.license b/data/themes/icons/pillage.svg.license similarity index 100% rename from data/themes/gui-qt/icons/pillage.svg.license rename to data/themes/icons/pillage.svg.license diff --git a/data/themes/gui-qt/icons/plantforest.png b/data/themes/icons/plantforest.png similarity index 100% rename from data/themes/gui-qt/icons/plantforest.png rename to data/themes/icons/plantforest.png diff --git a/data/themes/gui-qt/icons/plantforest.svg b/data/themes/icons/plantforest.svg similarity index 100% rename from data/themes/gui-qt/icons/plantforest.svg rename to data/themes/icons/plantforest.svg diff --git a/data/themes/gui-qt/icons/plantforest.svg.license b/data/themes/icons/plantforest.svg.license similarity index 100% rename from data/themes/gui-qt/icons/plantforest.svg.license rename to data/themes/icons/plantforest.svg.license diff --git a/data/themes/gui-qt/icons/plus.png b/data/themes/icons/plus.png similarity index 100% rename from data/themes/gui-qt/icons/plus.png rename to data/themes/icons/plus.png diff --git a/data/themes/gui-qt/icons/pollution.png b/data/themes/icons/pollution.png similarity index 100% rename from data/themes/gui-qt/icons/pollution.png rename to data/themes/icons/pollution.png diff --git a/data/themes/gui-qt/icons/preferences-other.png b/data/themes/icons/preferences-other.png similarity index 100% rename from data/themes/gui-qt/icons/preferences-other.png rename to data/themes/icons/preferences-other.png diff --git a/data/themes/gui-qt/icons/previous.svg b/data/themes/icons/previous.svg similarity index 100% rename from data/themes/gui-qt/icons/previous.svg rename to data/themes/icons/previous.svg diff --git a/data/themes/gui-qt/icons/previous.svg.license b/data/themes/icons/previous.svg.license similarity index 100% rename from data/themes/gui-qt/icons/previous.svg.license rename to data/themes/icons/previous.svg.license diff --git a/data/themes/gui-qt/icons/private.svg b/data/themes/icons/private.svg similarity index 100% rename from data/themes/gui-qt/icons/private.svg rename to data/themes/icons/private.svg diff --git a/data/themes/gui-qt/icons/private.svg.license b/data/themes/icons/private.svg.license similarity index 100% rename from data/themes/gui-qt/icons/private.svg.license rename to data/themes/icons/private.svg.license diff --git a/data/themes/gui-qt/icons/public.svg b/data/themes/icons/public.svg similarity index 100% rename from data/themes/gui-qt/icons/public.svg rename to data/themes/icons/public.svg diff --git a/data/themes/gui-qt/icons/public.svg.license b/data/themes/icons/public.svg.license similarity index 100% rename from data/themes/gui-qt/icons/public.svg.license rename to data/themes/icons/public.svg.license diff --git a/data/themes/gui-qt/icons/research.png b/data/themes/icons/research.png similarity index 100% rename from data/themes/gui-qt/icons/research.png rename to data/themes/icons/research.png diff --git a/data/themes/gui-qt/icons/research.svg b/data/themes/icons/research.svg similarity index 100% rename from data/themes/gui-qt/icons/research.svg rename to data/themes/icons/research.svg diff --git a/data/themes/gui-qt/icons/research.svg.license b/data/themes/icons/research.svg.license similarity index 100% rename from data/themes/gui-qt/icons/research.svg.license rename to data/themes/icons/research.svg.license diff --git a/data/themes/gui-qt/icons/resize.png b/data/themes/icons/resize.png similarity index 100% rename from data/themes/gui-qt/icons/resize.png rename to data/themes/icons/resize.png diff --git a/data/themes/gui-qt/icons/sentry.png b/data/themes/icons/sentry.png similarity index 100% rename from data/themes/gui-qt/icons/sentry.png rename to data/themes/icons/sentry.png diff --git a/data/themes/gui-qt/icons/set_homecity.png b/data/themes/icons/set_homecity.png similarity index 100% rename from data/themes/gui-qt/icons/set_homecity.png rename to data/themes/icons/set_homecity.png diff --git a/data/themes/gui-qt/icons/settings-minimap.svg b/data/themes/icons/settings-minimap.svg similarity index 100% rename from data/themes/gui-qt/icons/settings-minimap.svg rename to data/themes/icons/settings-minimap.svg diff --git a/data/themes/gui-qt/icons/settings-minimap.svg.license b/data/themes/icons/settings-minimap.svg.license similarity index 100% rename from data/themes/gui-qt/icons/settings-minimap.svg.license rename to data/themes/icons/settings-minimap.svg.license diff --git a/data/themes/gui-qt/icons/transform.png b/data/themes/icons/transform.png similarity index 100% rename from data/themes/gui-qt/icons/transform.png rename to data/themes/icons/transform.png diff --git a/data/themes/gui-qt/icons/units.png b/data/themes/icons/units.png similarity index 100% rename from data/themes/gui-qt/icons/units.png rename to data/themes/icons/units.png diff --git a/data/themes/gui-qt/icons/units.svg b/data/themes/icons/units.svg similarity index 100% rename from data/themes/gui-qt/icons/units.svg rename to data/themes/icons/units.svg diff --git a/data/themes/gui-qt/icons/units.svg.license b/data/themes/icons/units.svg.license similarity index 100% rename from data/themes/gui-qt/icons/units.svg.license rename to data/themes/icons/units.svg.license diff --git a/data/themes/gui-qt/icons/unload.png b/data/themes/icons/unload.png similarity index 100% rename from data/themes/gui-qt/icons/unload.png rename to data/themes/icons/unload.png diff --git a/data/themes/gui-qt/icons/upgrade.png b/data/themes/icons/upgrade.png similarity index 100% rename from data/themes/gui-qt/icons/upgrade.png rename to data/themes/icons/upgrade.png diff --git a/data/themes/gui-qt/icons/upgrade.svg b/data/themes/icons/upgrade.svg similarity index 100% rename from data/themes/gui-qt/icons/upgrade.svg rename to data/themes/icons/upgrade.svg diff --git a/data/themes/gui-qt/icons/upgrade.svg.license b/data/themes/icons/upgrade.svg.license similarity index 100% rename from data/themes/gui-qt/icons/upgrade.svg.license rename to data/themes/icons/upgrade.svg.license diff --git a/data/themes/gui-qt/icons/wait.png b/data/themes/icons/wait.png similarity index 100% rename from data/themes/gui-qt/icons/wait.png rename to data/themes/icons/wait.png diff --git a/data/themes/gui-qt/icons/wait.svg b/data/themes/icons/wait.svg similarity index 100% rename from data/themes/gui-qt/icons/wait.svg rename to data/themes/icons/wait.svg diff --git a/data/themes/gui-qt/icons/wait.svg.license b/data/themes/icons/wait.svg.license similarity index 100% rename from data/themes/gui-qt/icons/wait.svg.license rename to data/themes/icons/wait.svg.license diff --git a/data/themes/gui-qt/icons/zoom-in.svg b/data/themes/icons/zoom-in.svg similarity index 100% rename from data/themes/gui-qt/icons/zoom-in.svg rename to data/themes/icons/zoom-in.svg diff --git a/data/themes/gui-qt/icons/zoom-in.svg.license b/data/themes/icons/zoom-in.svg.license similarity index 100% rename from data/themes/gui-qt/icons/zoom-in.svg.license rename to data/themes/icons/zoom-in.svg.license diff --git a/data/themes/gui-qt/icons/zoom-original.svg b/data/themes/icons/zoom-original.svg similarity index 100% rename from data/themes/gui-qt/icons/zoom-original.svg rename to data/themes/icons/zoom-original.svg diff --git a/data/themes/gui-qt/icons/zoom-original.svg.license b/data/themes/icons/zoom-original.svg.license similarity index 100% rename from data/themes/gui-qt/icons/zoom-original.svg.license rename to data/themes/icons/zoom-original.svg.license diff --git a/data/themes/gui-qt/icons/zoom-out.svg b/data/themes/icons/zoom-out.svg similarity index 100% rename from data/themes/gui-qt/icons/zoom-out.svg rename to data/themes/icons/zoom-out.svg diff --git a/data/themes/gui-qt/icons/zoom-out.svg.license b/data/themes/icons/zoom-out.svg.license similarity index 100% rename from data/themes/gui-qt/icons/zoom-out.svg.license rename to data/themes/icons/zoom-out.svg.license diff --git a/dist/freeciv21-screenshot-2048x1112.png b/dist/freeciv21-screenshot-2048x1112.png deleted file mode 100644 index d928a2caa8..0000000000 Binary files a/dist/freeciv21-screenshot-2048x1112.png and /dev/null differ diff --git a/dist/freeciv21-screenshot.png b/dist/freeciv21-screenshot.png new file mode 100644 index 0000000000..bd0ddf589c Binary files /dev/null and b/dist/freeciv21-screenshot.png differ diff --git a/dist/net.longturn.freeciv21.metainfo.xml.in b/dist/net.longturn.freeciv21.metainfo.xml.in index b2b21a6573..c82cc59d50 100644 --- a/dist/net.longturn.freeciv21.metainfo.xml.in +++ b/dist/net.longturn.freeciv21.metainfo.xml.in @@ -3,8 +3,8 @@ net.longturn.freeciv21 CC0 GPL-3.0+ - Freeciv21 Client - Freeciv21 Game Client + Freeciv21 + Develop your civilization from humble roots to a global empire

Freeciv21 is a free open source turn-based empire-building 4x strategy game, in which each player becomes the leader of a civilization. You compete against several opponents to build cities and use them to support a military and an economy. Players strive to complete an empire that survives all encounters with its neighbors to emerge victorious. Play begins at the dawn of history in 4,000 BCE.

@@ -19,7 +19,7 @@ Freeciv21 Screenshot - https://raw.githubusercontent.com/longturn/freeciv21/master/dist/freeciv21-screenshot-2048x1112.png + https://raw.githubusercontent.com/longturn/freeciv21/master/dist/freeciv21-screenshot.png longturn.net@gmail.com diff --git a/dist/net.longturn.freeciv21.modpack.metainfo.xml.in b/dist/net.longturn.freeciv21.modpack.metainfo.xml.in index f60876e3a9..3dbb55ae4a 100644 --- a/dist/net.longturn.freeciv21.modpack.metainfo.xml.in +++ b/dist/net.longturn.freeciv21.modpack.metainfo.xml.in @@ -19,7 +19,7 @@ Freeciv21 Screenshot - https://raw.githubusercontent.com/longturn/freeciv21/master/dist/freeciv21-screenshot-2048x1112.png + https://raw.githubusercontent.com/longturn/freeciv21/master/dist/freeciv21-screenshot.png longturn.net@gmail.com diff --git a/dist/net.longturn.freeciv21.ruledit.desktop.in b/dist/net.longturn.freeciv21.ruledit.desktop.in index 586d0344c4..4fb6286086 100644 --- a/dist/net.longturn.freeciv21.ruledit.desktop.in +++ b/dist/net.longturn.freeciv21.ruledit.desktop.in @@ -10,7 +10,7 @@ GenericName[ru]=Стратегическая игра Comment=Edit Freeciv21 game rules Comment[ru]=Меняйте любые правила Freeciv21 и создавайте новые Exec=@CMAKE_INSTALL_FULL_BINDIR@/freeciv21-ruledit -Icon=@CMAKE_INSTALL_FULL_DATAROOTDIR@/freeciv21/icons/128x128/freeciv21-client.png +Icon=@CMAKE_INSTALL_FULL_DATAROOTDIR@/freeciv21/icons/128x128/freeciv21-ruledit.png StartupNotify=true Terminal=false Type=Application diff --git a/dist/net.longturn.freeciv21.ruledit.metainfo.xml.in b/dist/net.longturn.freeciv21.ruledit.metainfo.xml.in index cb7d60d964..14d5e46f44 100644 --- a/dist/net.longturn.freeciv21.ruledit.metainfo.xml.in +++ b/dist/net.longturn.freeciv21.ruledit.metainfo.xml.in @@ -13,13 +13,13 @@

The Freeciv21 Ruleset Editor can be used to create your own game rules, or the change existing ones.

net.longturn.freeciv21.ruledit.desktop - https://raw.githubusercontent.com/longturn/freeciv21/master/data/icons/128x128/freeciv21-client.png + https://raw.githubusercontent.com/longturn/freeciv21/master/data/icons/128x128/freeciv21-ruledit.png https://longturn.net/ https://github.com/longturn/freeciv21/issues Freeciv21 Screenshot - https://raw.githubusercontent.com/longturn/freeciv21/master/dist/freeciv21-screenshot-2048x1112.png + https://raw.githubusercontent.com/longturn/freeciv21/master/dist/freeciv21-screenshot.png longturn.net@gmail.com diff --git a/dist/net.longturn.freeciv21.server.metainfo.xml.in b/dist/net.longturn.freeciv21.server.metainfo.xml.in index c3ba812efb..f1a08a297a 100644 --- a/dist/net.longturn.freeciv21.server.metainfo.xml.in +++ b/dist/net.longturn.freeciv21.server.metainfo.xml.in @@ -19,7 +19,7 @@ Freeciv21 Screenshot - https://raw.githubusercontent.com/longturn/freeciv21/master/dist/freeciv21-screenshot-2048x1112.png + https://raw.githubusercontent.com/longturn/freeciv21/master/dist/freeciv21-screenshot.png longturn.net@gmail.com diff --git a/dist/snapcraft.yaml b/dist/snapcraft.yaml index 2d2b4117c8..aba2c31d8f 100644 --- a/dist/snapcraft.yaml +++ b/dist/snapcraft.yaml @@ -13,19 +13,20 @@ # - cd build # - snapcraft # - sudo snap install --devmode ./freeciv21_*.snap +# - snapcraft upload --release=latest/edge ./freeciv21_*.snap # ########## name: freeciv21 title: Freeciv21 -summary: Freeciv21 - Freeciv for the 21st Century +summary: Freeciv21 - Develop your civilization from humble roots to a global empire description: | Freeciv21 is a free open source turn-based empire-building 4x strategy game, in which each player becomes the leader of a civilization. You compete against several opponents to build cities and use them to support a military and an economy. Players strive to complete an empire that survives all encounters with its neighbors to emerge victorious. Play begins at the dawn of history in 4,000 BCE. Freeciv21 takes its roots in the well-known FOSS game Freeciv and extends it for more fun, with a revived focus on competitive multiplayer environments. Players can choose from over 500 nations and can play against the computer or other people in an active online community. The code is maintained by the team over at Longturn.net and is based on the QT framework. The game supports both hex and square tiles and is easily modified to create custom rules. # TODO: At some point, will want to integrate into cmake process and configure_file() -version: '3.1.alpha4' +version: '3.1-alpha.5' grade: devel license: GPL-3.0-or-later @@ -50,7 +51,7 @@ parts: source-type: git # TODO: integrate into cmake process and configure_file() #source-branch: master - source-commit: a82c58f1d40307aaa88a8fd2d0e0e3e9a3dfe1fd + source-commit: baf62126f40b5b19115bba122189ca05ff46ef25 cmake-generator: Ninja cmake-parameters: - "-DCMAKE_INSTALL_PREFIX=/usr" diff --git a/dist/freeciv21-server.cmd b/dist/windows/freeciv21-server.cmd similarity index 97% rename from dist/freeciv21-server.cmd rename to dist/windows/freeciv21-server.cmd index 1ccc238913..5863fba92f 100644 --- a/dist/freeciv21-server.cmd +++ b/dist/windows/freeciv21-server.cmd @@ -1,3 +1,3 @@ -@echo off -if not "%1" == "auto" set LANG=%1 -start "%~n0" /D . "%~dp0\freeciv21-server.exe" %2 %3 %4 %5 %6 %7 %8 %9 +@echo off +if not "%1" == "auto" set LANG=%1 +start "%~n0" /D . "%~dp0\freeciv21-server.exe" %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/dist/windows/qt.conf b/dist/windows/qt.conf new file mode 100644 index 0000000000..b842593d71 --- /dev/null +++ b/dist/windows/qt.conf @@ -0,0 +1,5 @@ +[Platforms] +# We force FreeType on Windows because rendering Libertinus with DirectWrite +# looks terrible. +# Dark mode controls window title bars. 1 means follow the system default. +WindowsArguments = fontengine=freetype,darkmode=1 diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 975975cadc..b74113b1b0 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,10 +1,13 @@ # CMakeLists for Freeciv21 Docs -find_package(Sphinx QUIET) +if(FREECIV_ENABLE_MANPAGES) + find_package(Sphinx REQUIRED) +else() + find_package(Sphinx QUIET) +endif() if(SPHINX_FOUND) message(STATUS "Sphinx Found, configuring.") - option(FREECIV_ENABLE_MANPAGES "Enable manpages" ON) set(SPHINX_SOURCE ${CMAKE_SOURCE_DIR}/docs) set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}) set(SPHINX_MAN ${CMAKE_CURRENT_BINARY_DIR}/man) @@ -15,15 +18,21 @@ if(SPHINX_FOUND) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating documentation with Sphinx") - # We only create man pages on Unix - if(UNIX AND NOT APPLE) + # We only create man pages on Unix by default or if the user explicitly + # requested it. + if(UNIX AND NOT APPLE AND NOT DEFINED FREECIV_ENABLE_MANPAGES) + option(FREECIV_ENABLE_MANPAGES "Enable manpages" ON) + else() + option(FREECIV_ENABLE_MANPAGES "Enable manpages" OFF) + endif() + + if(FREECIV_ENABLE_MANPAGES) add_custom_target(man-pages ALL - COMMAND - ${SPHINX_EXECUTABLE} -b man ${SPHINX_SOURCE} ${SPHINX_MAN} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Generating manual pages with Sphinx") + COMMAND + ${SPHINX_EXECUTABLE} -b man ${SPHINX_SOURCE} ${SPHINX_MAN} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating manual pages with Sphinx") endif() else() message(STATUS "Sphinx NOT Found.") - option(FREECIV_ENABLE_MANPAGES "Enable manpages" OFF) endif() diff --git a/docs/Coding/guidelines.rst b/docs/Coding/guidelines.rst index 9a92735701..122f4836fb 100644 --- a/docs/Coding/guidelines.rst +++ b/docs/Coding/guidelines.rst @@ -12,7 +12,7 @@ different standards and should not be modified for the sole purpose of making it In a nutshell, new or refactored Freeciv21 code is written in modern C++ (the standard version evolves depending on what the targeted compilers support). This coding style strives to achieve a balance between old code originally written in C and the new possibilities brought by C++, so that new and old code do not look -too different. At this time we are targetting C++17. +too different. At this time we are targeting C++17. The rules listed on this page are guidelines. They represent the preferred way of writing code for Freeciv21, but good code that does not follow the guidelines will not be rejected directly. However, you should expect diff --git a/docs/Coding/hacking.rst b/docs/Coding/hacking.rst index b9243cccfa..3a0a99862b 100644 --- a/docs/Coding/hacking.rst +++ b/docs/Coding/hacking.rst @@ -575,7 +575,7 @@ the sight range of one of your units or cities. We keep track of Fog of War by counting the number of units and cities of each client that can see the tile. This requires a number per player, per tile, so each :code:`player_tile` has a :code:`short[]`. Every time a -unit, city, or somthing else can observe a tile 1 is added to its player's number at the tile, and when it +unit, city, or something else can observe a tile 1 is added to its player's number at the tile, and when it cannot observe any more (killed/moved/pillaged) 1 is subtracted. In addition to the initialization/loading of a game this array is manipulated with the :code:`void unfog_area(struct player *pplayer, int x, int y, int len)` and :code:`void fog_area(struct player *pplayer, int x, int y, int len)` functions. The :code:`int len` @@ -607,7 +607,7 @@ gets fogged the date is updated. There is a Shared Vision feature, meaning that if ``p1`` gives Shared Vision to ``p2``, every time a function like :code:`show_area()`, :code:`fog_area()`, :code:`unfog_area()`, or :code:`give_tile_info_from_player_to_player()` is called on ``p1``, ``p2`` also gets the information. Note -that if ``p2`` gives Shared Vision to ``p3``, ``p3`` also gets the informtion for ``p1``. This is controlled +that if ``p2`` gives Shared Vision to ``p3``, ``p3`` also gets the information for ``p1``. This is controlled by ``p1's`` really_gives_vision bitvector, where the dependencies will be kept. National Borders diff --git a/docs/Coding/network-protocol.rst b/docs/Coding/network-protocol.rst index 3134631a4a..a32df8e114 100644 --- a/docs/Coding/network-protocol.rst +++ b/docs/Coding/network-protocol.rst @@ -161,9 +161,9 @@ exists the unchanged fields will be assumed to be zero. For a ``bool`` field, another optimization called ``bool-header-folding`` is applied. Instead of sending an indicator in the bitvector if the given ``bool`` value has changed, and so using 1 byte for the real value, -the actual value of the ``bool`` is transfered in the bitvector bit of this ``bool`` field. +the actual value of the ``bool`` is transferred in the bitvector bit of this ``bool`` field. -Another optimization called ``array-diff`` is used to reduce the amount of elements transfered if an array is +Another optimization called ``array-diff`` is used to reduce the amount of elements transferred if an array is changed. This is independent of the ``delta-header`` bit, i.e. it will only be used if the array has changed its value and the bit indicates this. Instead of transferring the whole array only a list of ``index`` and ``new value of this index`` pairs are transferred. The ``index`` is 8 bit and the end of this pair list is @@ -185,7 +185,7 @@ Compression To further reduce the network traffic between the client and the server, the (delta) packets are compressed using the DEFLATE compression algorithm. To get better compression results, multiple packets are grouped -together and compressed into a chunk. This chunk is then transfered as a normal packet. A chunk packet starts +together and compressed into a chunk. This chunk is then transferred as a normal packet. A chunk packet starts with the 2 byte ``length`` field, which every packet has. A chunk packet has no type. A chunk packet is identified by having a too large ``length`` field. If the length of the packet is over ``COMPRESSION_BORDER``, it is a chunk packet. It will be uncompressed at the receiving side and re-fed into the receiving queue. @@ -285,5 +285,5 @@ will find the set of used capabilities for a given packet. Let us say there are Each of these combinations is called a variant. If ``n`` is the number of capabilities used by the packet the number of variants is :math:`2^n`. -For each of these variants a seperate send and receive function will be generated. The variant for a packet and +For each of these variants a separate send and receive function will be generated. The variant for a packet and a connection is calculated once and then saved in the connection struct. diff --git a/docs/Coding/scorelog.rst b/docs/Coding/scorelog.rst index 4c17e40598..35af01380b 100644 --- a/docs/Coding/scorelog.rst +++ b/docs/Coding/scorelog.rst @@ -6,7 +6,7 @@ Format Description of the Scorelog ********************************** Empty lines and lines starting with ``#`` are comments. Each non-comment line starts with a command. The -parameter are supplied on that line and are seperated by a space. Strings which may contain whitespaces +parameter are supplied on that line and are separated by a space. Strings which may contain whitespaces are always the last parameter and so extend until the end of line. The following commands exists: diff --git a/docs/Contributing/dev-env.rst b/docs/Contributing/dev-env.rst index 4ba1bfb5a1..70c052a6cc 100644 --- a/docs/Contributing/dev-env.rst +++ b/docs/Contributing/dev-env.rst @@ -30,7 +30,7 @@ All platforms can use `KDevelop `_. However, For the best results, especially if you are editing game code and not just Longturn game rulesets or documentation, you will want :strong:`Linux` to be your workstation OS. Many of the current developers use a -Debain variant such as Ubuntu. Instructions for getting all of the tools needed for Debian Linux can be found +Debian variant such as Ubuntu. Instructions for getting all of the tools needed for Debian Linux can be found in :doc:`/Getting/compile`. Do not follow the steps to clone the repository (e.g. the :code:`git clone` command), that will happen in a bit. diff --git a/docs/Contributing/eval-pull-request.rst b/docs/Contributing/eval-pull-request.rst index 0f3115a76d..433f6e5561 100644 --- a/docs/Contributing/eval-pull-request.rst +++ b/docs/Contributing/eval-pull-request.rst @@ -60,7 +60,7 @@ This page assumes the user knows how to use :file:`git`, compile Freeciv21 and u :strong:`Run tests` -..code-block:: sh +.. code-block:: sh $ cmake --build build --target test diff --git a/docs/Contributing/msys2.rst b/docs/Contributing/msys2.rst index 31a4a83476..680103820c 100644 --- a/docs/Contributing/msys2.rst +++ b/docs/Contributing/msys2.rst @@ -101,4 +101,4 @@ Build ===== Now that you have the environment setup. You can follow the steps in :doc:`/Getting/install`. MSYS2 in a -Linux emulation evironment on Windows, so the commands for :file:`git`, :file:`cmake`, etc. work the same. +Linux emulation environment on Windows, so the commands for :file:`git`, :file:`cmake`, etc. work the same. diff --git a/docs/Contributing/pull-request.rst b/docs/Contributing/pull-request.rst index a12f9907ee..511ab5dc69 100644 --- a/docs/Contributing/pull-request.rst +++ b/docs/Contributing/pull-request.rst @@ -73,7 +73,7 @@ from Upstream to Local. 2. Create a Branch from Upstream ================================ -Now that things are all up to date with the lastest code, let's create a branch to do your work in. +Now that things are all up to date with the latest code, let's create a branch to do your work in. .. code-block:: sh @@ -151,8 +151,8 @@ one commit into a Pull Request then you can read about `git add ` command. This is also shown on the :file:`git status` command output. diff --git a/docs/Contributing/release.rst b/docs/Contributing/release.rst index b5c5ec22f6..8b42266ee2 100644 --- a/docs/Contributing/release.rst +++ b/docs/Contributing/release.rst @@ -21,7 +21,7 @@ These are the general steps to prepare and finalize a release: The easiest way to do this is to copy the contents of the last release, delete the bullet points, and add a single bullet of ``* Nothing for this release`` to each section. :strong:`DO NOT` add a tag at this time. This prevents an accidental release. -#. A release manager will update the draft as PR's are commited to the repository to help keep track of +#. A release manager will update the draft as PR's are committed to the repository to help keep track of the release cadence progress. As PR's are added to sections the ``* Nothing for this release`` is removed. #. Multiple PR's can be combined on a single bullet line. Documentation updates are often done this way. #. When we are getting close to crossing one of the release candidate thresholds, the release manager will @@ -41,15 +41,16 @@ These are the general steps to prepare and finalize a release: `branches page `_. #. From the same page, create a new ``stable`` branch from ``master``. #. Update ``cmake/AutoRevision.txt`` with the hash of the last commit in ``master`` and - ``v[major version].[minor version]-dev`` with the version of the :strong:`next stable release`, then + ``v[major version].[minor version]-dev.0`` with the version of the :strong:`next stable release`, then open a PR for this change to ``master``. This way, development builds from ``master`` will immediately use the version number of the next stable. #. If the release is a :strong:`release candidate` for a :strong:`stable release`, the release manager will make sure that the :guilabel:`Target` branch in the release draft is set to ``stable``. #. The release manager will add a tag to the release notes page and then click :guilabel:`Publish Release`. - The format of the tag is ``v[major version].[minor version]-[pre-release name].[number]``. For example: - ``v3.0-beta.6``. :strong:`The format is very important` to the build configuration process. + The format of the tag is ``v[major version].[minor version]-[pre-release name].[number]`` for pre-releases + and ``v[major version].[minor version].[patch version]`` for stable versions. For example: + ``v3.0-beta.6`` or ``v3.1.0``. :strong:`The format is very important` to the build configuration process. #. After a few minutes the continuous integration (CI) will open a PR titled ``Release Update of AutoRevision.txt``. The release manager will open the PR, click on the :guilabel:`Close pull request` button, and then click :guilabel:`Open pull request` button. This is a diff --git a/docs/Getting/about.rst b/docs/Getting/about.rst index fda19c599c..ff0ad07fc6 100644 --- a/docs/Getting/about.rst +++ b/docs/Getting/about.rst @@ -13,7 +13,7 @@ About Freeciv21 *************** .. _Freeciv21 Overview: -.. figure:: ../../dist/freeciv21-screenshot-2048x1112.png +.. figure:: ../../dist/freeciv21-screenshot.png :width: 800px :align: center :alt: Freeciv21 Overview diff --git a/docs/Getting/compile.rst b/docs/Getting/compile.rst index ddd2b25d10..67d183a663 100644 --- a/docs/Getting/compile.rst +++ b/docs/Getting/compile.rst @@ -2,6 +2,7 @@ .. SPDX-FileCopyrightText: Freeciv21 and Freeciv Contributors .. SPDX-FileCopyrightText: James Robertson .. SPDX-FileCopyrightText: Louis Moureaux +.. SPDX-FileCopyrightText: Tobias Rehbein Compiling Freeciv21 @@ -93,7 +94,7 @@ GNU Gettext https://www.gnu.org/software/gettext/ Lua - Lua is a powerful, efficient, lightweight, embedable scripting language. It supports procedural + Lua is a powerful, efficient, lightweight, embeddable scripting language. It supports procedural programming, object-oriented programming, functional programming, data-driven programming, and data description. Exact version 5.3 is preferred. @@ -397,6 +398,8 @@ them directives and they start with :literal:`-D`. The defaults are marked with (recommended) FREECIV_ENABLE_RULEDIT={ON/OFF} Enables the Ruleset Editor FREECIV_ENABLE_RULEUP={ON/OFF} Enables the Ruleset upgrade tool + FREECIV_ENABLE_MANPAGES={ON/OFF} Enables the generation of manpages. This is primarily + relevant for Unix-like operating systems FREECIV_USE_VCPKG={ON/:strong:`OFF`} Enables the use of VCPKG FREECIV_DOWNLOAD_FONTS{:strong:`ON`/OFF} Enables the downloading of Libertinus Fonts CMAKE_BUILD_TYPE={:strong:`Release`/Debug} Changes the Build Type. Most people will pick Release diff --git a/docs/Getting/windows-install.rst b/docs/Getting/windows-install.rst index 82b5cb4eb1..1322fc9a2d 100644 --- a/docs/Getting/windows-install.rst +++ b/docs/Getting/windows-install.rst @@ -68,7 +68,7 @@ Select the installation type and then click :guilabel:`Next` to continue... :alt: Admin Installation Panel :figclass: align-center - Admin Install - Mult-User Selection + Admin Install - Multi-User Selection By default, the Admin installer will place the files in the :file:`C:\\Program Files` folder. Change if @@ -78,7 +78,7 @@ you want and click :guilabel:`Next` to continue... .. figure:: /_static/images/windows-installer/05a-Admin-Folder.png :align: center :height: 400 - :alt: Admin Instalation Folder Panel + :alt: Admin Installation Folder Panel :figclass: align-center Admin Install - Installation Folder @@ -114,7 +114,7 @@ You will find an icon for the client on the Desktop or in the Start Menu at .. _non-admin: -Non-Local Admin (Unpriviledged User) Instalation +Non-Local Admin (Unprivileged User) Installation ================================================ If you :emphasis:`are not` logged on as a local Administrator there is no UAC prompt and the following panel @@ -152,7 +152,7 @@ The Non-Admin Installer places the files in your User Directory by default. Chan .. figure:: /_static/images/windows-installer/05b-User-Folder.png :align: center :height: 400 - :alt: User Instalation Folder Panel + :alt: User Installation Folder Panel :figclass: align-center User Install - Installation Folder diff --git a/docs/Manuals/Advanced/index.rst b/docs/Manuals/Advanced/index.rst index bc268fd7f2..a678a74896 100644 --- a/docs/Manuals/Advanced/index.rst +++ b/docs/Manuals/Advanced/index.rst @@ -12,4 +12,5 @@ looking for more general or generic gameplay information, it would be best to s .. toctree:: players.rst fc21-uri.rst + map-generator :maxdepth: 2 diff --git a/docs/Manuals/Advanced/map-generator.rst b/docs/Manuals/Advanced/map-generator.rst new file mode 100644 index 0000000000..de3c887539 --- /dev/null +++ b/docs/Manuals/Advanced/map-generator.rst @@ -0,0 +1,234 @@ +.. SPDX-License-Identifier: GPL-3.0-or-later +.. SPDX-FileCopyrightText: James Robertson + +Controlling the Map Generator +***************************** + +The generated map and player placement for a game can be manipulated by changing varying +:doc:`/Manuals/Server/options`. This page aims to give the reader some recipes or options on how to manipulate +the varying options to create the map you want to play. It is assumed that the game master is using a +:doc:`/Manuals/Server/settings-file`. + +The server options that impact what kind of map the generator creates are: + +* ``alltemperate`` +* ``flatpoles`` +* ``generator`` +* ``huts`` +* ``landmass`` +* ``mapseed`` +* ``mapsize`` +* ``revealmap`` +* ``separatepoles`` +* ``singlepole`` +* ``size`` +* ``specials`` +* ``startpos`` +* ``steepness`` +* ``teamplacement`` +* ``temperature`` +* ``tilesperplayer`` +* ``tinyisles`` +* ``topology`` +* ``wetness`` +* ``xsize`` +* ``ysize`` + +Some server options are more impacting than others to the makeup of the map. Let us start with talking about +the options that are least impacting to the overall map. + +These options change the makeup of tiles and not the map itself: + +* ``alltemperate`` -- When ``enabled``, all tiles have a similar temperature. Players will all have similar + tiles to work. Set to ``disabled`` if you want to control with the ``temperature`` and ``wetness`` options. +* ``huts`` -- How many huts you want on the map. Longturn games typically have ``0`` huts. +* ``specials`` -- How many specials (tile resources) you want on the map. +* ``steepness`` -- Bigger numbers produce hilly and mountainous terrain, lower numbers do not. +* ``temperature`` -- You can create a hot or cold world with this option. +* ``tinyisles`` -- Set to ``enabled`` if you want small single-tile (1x1) islands on the map. +* ``wetness`` -- This option allows you to create a dry or wet map. Lower numbers are dry, higher numbers are + wet. +* ``revealmap`` -- This setting is used to reveal the whole map at game start. Good to use for testing, but + not for real games. + + +Poles and Base Topology +======================= + +The concept of poles and overall topology is important in how you want to create your world map. There are +some options that when toggled will create a pole at the top and bottom, no poles whatsoever, or poles in the +map that you can work and navigate around. + +The settings that define the poles and base topology are: + +* ``flatpoles`` -- A low setting (``0``) will give poles with water and a high (``100``) will fill in with + mostly glacier tiles on the poles. +* ``separatepoles`` -- When ``enabled`` will break poles up and when ``disabled`` will keep them together. +* ``singlepole`` -- When ``enabled`` will allow for a single pole and when ``disabled`` will give two poles. +* ``topology`` -- Sets the wrap (``X``, ``Y``), the orientation (isometric or overhead) and the tile type + (squares vs hexes). + +:strong:`Recipe: Blocking poles on the map` + +Set ``topology "WRAPX|ISO"``, ``separatepoles enabled``, and ``singlepole disabled``. This gives you a map +with a blocking (cannot navigate around it) pole at the top and bottom of the map. You navigate East and +West. If you set ``singlepole enabled`` here, you will get a really thick blocking border. + +You can create blocking poles on the left and right by changing ``WRAPX`` to ``WRAPY``. You would then +navigate North and South. + +Lastly, you can create a map that is like a game board. If you remove both ``WRAPX`` and ``WRAPY`` on +``topology``, you will get regular poles at the top and bottom and "black" on the left and right. You can only +navigate inside the box. + +:strong:`Recipe: A set of navigable poles on the map` + +Set ``topology "WRAPX|WRAPY|ISO"``, ``separatepoles enabled``, and ``singlepole disabled``. This gives you two +poles on the map, which looks and acts like Earth where you can navigate around them. + +If you set ``singlepole enabled`` instead of ``disabled`` you will get a single pole on the map instead of +two. + +Lastly, if you set ``flatpoles 0`` you will get navigable poles with passages of water inside of them. + +:strong:`Recipe: No poles on the map` + +Set ``topology "WRAPX|WRAPY|ISO"``, ``separatepoles disabled``, and ``singlepole disabled``. This eliminates +all poles on the map. You get a world with continents and islands, but no poles. There is no edge to the map +as you can navigate in all directions indefinitely. + +:strong:`Recipe: Overhead square tiles` + +Set ``topology "WRAPX|WRAPY"`` + +:strong:`Recipe: Hex tiles` + +Set ``topology "WRAPX|WRAPY|ISO|HEX"`` will give isometric hex tiles. Removing the ``ISO`` will give overhead +hex tiles. + + +Sizing Your Map +=============== + +The overall size of the map (total number of X and Y tiles) is driven by a collection of settings. They are: + +* ``mapsize`` +* ``size`` +* ``tilesperplayer`` +* ``xsize`` +* ``ysize`` + +The ``mapsize`` option is the driver and has three possible configurations: + +#. ``FULLSIZE`` -- When used, you must also have the ``size`` option set. The value is simply a number (in + thousands) of tiles. +#. ``PLAYER`` -- When used, you must also have the ``tilesperplayer`` option set. The map generator will take + this into account and try its best to give each player a similar number of tiles to settle. +#. ``XYSIZE`` -- When used, you must also have the ``xsize`` and ``ysize`` options set. These values are + similar to the ``size`` option. Give the map generator very specific number of tiles on the two axis. + +No recipes here. As a game master, you can figure out how big or small you want your map. Longturn games use +the ``tilesperplayer`` option for their games as a reference. + + +Finalizing the Map and Player Placement +======================================= + +This is probably one of the hardest aspects of map generation. Actually getting the map you want as a game +master, but also ensuring that player placement (or even team placement) is done the way you want is not +exactly directly mapped. There is a bit of randomness involved. + +These options are the last piece to defining a game map: + +* ``generator`` +* ``landmass`` +* ``mapseed`` +* ``startpos`` +* ``teamplacement`` + +As with the ``revealmap`` option, discussed earlier, the ``mapseed`` option is used during testing to keep +randomness from creeping into your testing. By setting a value, you eliminate the RNG in the server from +impacting the game map you want to create. If a game master is also playing the game, it is recommended to +disable (remove or comment out) this option when the game starts so even the game master does not have +knowledge of the map at game start. + +We will get to some recipes in a bit, but before we do that, let us talk about the ``generator`` and +``startpos`` options. They work in tandem with each other. + +First up, ``generator`` has the following configurations: + +* ``SCENARIO`` -- This configuration is for Scenario games only. This is a special use case. +* ``RANDOM`` -- The default. As the name implies, there is a dependency on the built-in Random Number + Generator (RNG) in the server. The generator will attempt to create equally spaced, relatively small + islands. Player placement will be impacted by the ``landmass`` option. The larger the value the bigger the + continents/islands. This option is also impacted by the ``mapsize`` option. Best to use the ``FULLSIZE`` or + the ``XYSIZE`` configuration. +* ``FRACTAL`` -- This is the setting most Longturn games use. This configuration will create earth-like maps. + By default, all players are placed on the same continent. The ``landmass`` option can also impact placement. +* ``ISLAND`` -- Each player is placed on their own island. Each island is similar in size, but not shape. +* ``FAIR`` -- Every player gets the exact same island. +* ``FRACTURE`` -- Similar to ``FRACTAL``, however this configuration often places mountains on the coasts. + +Now let us discuss ``startpos``, which has the following configurations: + +* ``DEFAULT`` -- The default. This configuration uses the ``generator`` configuration to place players. +* ``SINGLE`` -- One player per island/continent. +* ``2or3`` -- As the configuration name implies, the ``startpos`` will place 2 or 3 players together on an + island/continent. +* ``ALL`` -- Everyone is placed on the same continent. Make sure you give enough tiles when using this + configuration. The ``landmass`` and ``tilesperplayer`` will come in handy. +* ``VARIABLE`` -- The server will use the RNG to give a bit of randomness to player placement. The size of the + continents will be taken into account. + +:strong:`Recipe: Large Pangea-like world` + +To create a gigantic single continent and have every player start there, begin with the no poles recipe above. +Then set ``generator`` to ``RANDOM``, or ``FRACTAL``, or ``FRACTURE`` and set ``landmass 85`` (the max). +Finally set ``startpos "ALL"``. + +If you want more ocean or poles, you can reduce the ``landmass`` setting and add poles with the recipe above. +Longturn games use a ``landmass`` setting of ``40`` with poles for many games. + +:strong:`Recipe: An archipelago with players on their own island` + +To create an archipelago and start each player on their own island, begin with the navigable poles on the map +recipe above. This is recommended from a realism perspective. If you do not want poles, you can skip it. Set +``generator`` to ``ISLAND`` or ``FAIR`` (``ISLAND`` is recommended) and then set ``startpos "SINGLE"``. +Finally set ``landmass`` to 15 or 20 (minimum is 15). This will allow for some small random non-populated +islands on the map. + +This recipe introduces a great use of the ``tilesperplayer`` option. Each player will get a similar sized +island of the number of tiles you define. Do not forget to change the ``mapsize`` option to ``PLAYER`` if you +go this route. + +By playing around with the varying values, you can create many different kinds of maps. Let us move to +discussing team games and team placement. + +Team games are a special use case. Most games are what the Longturn community calls Free For All (FFA). The +idea of an FFA game is there are no preset alliances at game start. Those form in game. Team games are the +opposite of FFA games. Alliances (e.g. teams) are defined before the game starts. Getting player placement +correct when teams are involved is quite important! + +The ``teamplacement`` option has the following configurations: + +* ``DISABLED`` -- If set, then the option configuration is ignored. +* ``CLOSEST`` -- The default. The name implies what happens. +* ``CONTINENT`` -- Everyone on the same continent. This requires tuning ``landmass``, ``generator``, and + ``startpos`` to fit how you want the teams to get placed on the same continent. +* ``HORIZONTAL`` -- Place team players in a East-West alignment. +* ``VERTICAL`` -- Place team players in a North-South alignment. + +:strong:`Recipe: Two team game with each team on their own continent` + +Follow the :doc:`steps ` to create a :file:`players.serv` file. + +Add a ``read players.serv`` entry to your :doc:`/Manuals/Server/settings-file`. + +Set ``generator "FRACTURE"``, ``landmass`` to 30 or 40, ``mapsize "PLAYER"``, ``tilesperplayer`` to something +between 1 and 1000 (Longturn uses 500), ``teamplacement "CONTINENT"``, and ``startpos "ALL"``. + +You can add poles to the map with the recipe above. + +.. note:: Do not be surprised if you need to play around with some of the other settings to get the map you + are looking for. Every Longturn game goes through a process of generating test maps for players to evaluate + and vote for. Play around with the settings and you will get the map you eventually want! diff --git a/docs/Manuals/Game/intro.rst b/docs/Manuals/Game/intro.rst index 6ee2af5a10..e70152090c 100644 --- a/docs/Manuals/Game/intro.rst +++ b/docs/Manuals/Game/intro.rst @@ -15,7 +15,7 @@ Regardless the method you used to get into a game, eventually you will make it t shown in :numref:`Game Overview` below. This is known as the :ref:`Map View `. .. _Game Overview: -.. figure:: ../../../dist/freeciv21-screenshot-2048x1112.png +.. figure:: ../../../dist/freeciv21-screenshot.png :scale: 25% :align: center :alt: Freeciv21 game overview diff --git a/docs/Manuals/Game/menu.rst b/docs/Manuals/Game/menu.rst index 9b56db8a9c..5cf0f430a3 100644 --- a/docs/Manuals/Game/menu.rst +++ b/docs/Manuals/Game/menu.rst @@ -110,6 +110,10 @@ Load Another Tileset Available Tilesets Dialog +Add Modpacks + Launches the modpack installer. This utility allows the Longturn community to create third-party content + and offer it for enhanced gameplay. For more information refer to :doc:`/Manuals/modpack-installer`. + Tileset Debugger Opens the :guilabel:`Tileset Debugger` dialog. This option is documented in :doc:`/Modding/Tilesets/debugger` @@ -192,19 +196,19 @@ Scale Fonts City Bar Style This menu has a sub-menu of three options: :guilabel:`Simple`, :guilabel:`Traditional`, and - :guilabel:`Polished` as shown in :numref:`Citybar Style Simple`, :numref:`Citybar Sytle Traditional`, + :guilabel:`Polished` as shown in :numref:`Citybar Style Simple`, :numref:`Citybar Style Traditional`, and, :numref:`Citybar Style Polished`, respectively. .. _Citybar Style Simple: .. figure:: /_static/images/gui-elements/citybar-simple.png :align: center - :alt: City Bar Syle - Simple + :alt: City Bar Style - Simple :figclass: align-center City Bar Style - Simple -.. _Citybar Sytle Traditional: +.. _Citybar Style Traditional: .. figure:: /_static/images/gui-elements/citybar-traditional.png :align: center :alt: City Bar Style - Traditional @@ -531,8 +535,7 @@ Clear Orders Clear any delayed orders from the above two menu items. Add All Cities to Trade Planning - All all current cities in your into an advanced trade planning array. This is used by the WarCiv - ruleset. + Add all current cities into an advanced trade planning array. This is used by the WarCiv ruleset. Calculate Trade Planning Run a trade effectiveness algorithm across all of the cities in the trade plan to determine the best diff --git a/docs/Manuals/Game/shortcut-options.rst b/docs/Manuals/Game/shortcut-options.rst index 6ccc7a4b69..122fde200c 100644 --- a/docs/Manuals/Game/shortcut-options.rst +++ b/docs/Manuals/Game/shortcut-options.rst @@ -150,7 +150,7 @@ City Traderoutes Default: ``Ctrl+D`` City Production Levels - Toggles the disply of city production in the city bar. + Toggles the display of city production in the city bar. Default: ``Ctrl+P`` diff --git a/docs/Manuals/Game/start-screen.rst b/docs/Manuals/Game/start-screen.rst index 9420b6f40d..e41c4eec28 100644 --- a/docs/Manuals/Game/start-screen.rst +++ b/docs/Manuals/Game/start-screen.rst @@ -44,6 +44,7 @@ The following buttons are available on the :guilabel:`Start Screen`: * :guilabel:`Load Saved Game` -- Load a previously saved single player game. See `Load Saved Game`_ below. * :guilabel:`Start Scenario Game` -- Start a single player scenario game. See `Start Scenario Game`_ below. * :guilabel:`Options` -- Set client options. See `Options`_ below. +* :guilabel:`Mods` -- Launch the modpack installer. See :doc:`/Manuals/modpack-installer`. * :guilabel:`Quit` -- Quit Freeciv21 .. Note:: diff --git a/docs/Manuals/Game/top-bar.rst b/docs/Manuals/Game/top-bar.rst index d6e5479f5e..ca5af9c7dd 100644 --- a/docs/Manuals/Game/top-bar.rst +++ b/docs/Manuals/Game/top-bar.rst @@ -194,7 +194,7 @@ The :guilabel:`Nations and Diplomacy View` has a few buttons at the upper left. :guilabel:`Nations and Diplomacy View`. Let us talk about the buttons from right to left as :guilabel:`Meet` takes the longest to describe. If you -have any active treaty negotiations ocurring, you can click on the :guilabel:`Active Diplomacy` button to +have any active treaty negotiations occurring, you can click on the :guilabel:`Active Diplomacy` button to switch to that page. The :numref:`Nations and Diplomacy View Button` on the top function bar will change to a flag icon with a red dot to give you a visual reminder that there are open meetings to attend to. diff --git a/docs/Manuals/Program/freeciv21-server.rst b/docs/Manuals/Program/freeciv21-server.rst index 413572060c..f18faa3ceb 100644 --- a/docs/Manuals/Program/freeciv21-server.rst +++ b/docs/Manuals/Program/freeciv21-server.rst @@ -90,7 +90,7 @@ The freeciv21-server requires the default ruleset files to be readable at start. * default/nationlist.ruleset These files are for the default ruleset for the game (civ2civ3), which are loaded if you do not use the -`--ruleset` arguement. Alternate rules can be loaded with the ``rulesetdir`` directive in a start up script. +`--ruleset` argument. Alternate rules can be loaded with the ``rulesetdir`` directive in a start up script. Type ``help rulesetdir`` at the server command prompt for more information. If you are going to enable user authentication, you will need the `database.lua` file. The file is diff --git a/docs/Manuals/Rulesets/Common/unit_type_roles.rst b/docs/Manuals/Rulesets/Common/unit_type_roles.rst index 8b054da950..82c3e32978 100644 --- a/docs/Manuals/Rulesets/Common/unit_type_roles.rst +++ b/docs/Manuals/Rulesets/Common/unit_type_roles.rst @@ -44,7 +44,7 @@ directory. The following roles are used in all of the rulesets shipped by the Fr Can be created as a :unit:`Barbarian` that disembarks from a barbarian boat. :strong:`BarbarianSeaTech` - Can be created as a :unit:`Barbarian` that disembarks from a barbarian boatif someone has researched its + Can be created as a :unit:`Barbarian` that disembarks from a barbarian boat if someone has researched its technology requirements. :strong:`BorderPolice` diff --git a/docs/Manuals/Server/command-line.rst b/docs/Manuals/Server/command-line.rst index 1e608c681c..1593d7ebe9 100644 --- a/docs/Manuals/Server/command-line.rst +++ b/docs/Manuals/Server/command-line.rst @@ -81,7 +81,7 @@ such as: Sets the server id to ID. ``-s, --saves `` - Save games to directory DIR. Generally a ver good idea to save games at least every turn and depending on + Save games to directory DIR. Generally a very good idea to save games at least every turn and depending on how long the turns are set to, to save within a turn. In the case of a server crash, restarting from a save comes in very handy. diff --git a/docs/Manuals/Server/commands.rst b/docs/Manuals/Server/commands.rst index 7b48a69cb4..832b3ff120 100644 --- a/docs/Manuals/Server/commands.rst +++ b/docs/Manuals/Server/commands.rst @@ -201,7 +201,7 @@ server's own command-line. This server command-line is separate from the OS term .. note:: The term *minimal changes* is not well understood at this time. The server help does not provide more details. An enterprising enthusiast could read the :term:`AI` code to determine what the term means and - provide more details. Any real player is not going to want the AI to run thier nation and will + provide more details. Any real player is not going to want the AI to run their nation and will :ref:`delegate ` instead. ``/handicapped `` diff --git a/docs/Manuals/Server/index.rst b/docs/Manuals/Server/index.rst index f7f681f064..644136800b 100644 --- a/docs/Manuals/Server/index.rst +++ b/docs/Manuals/Server/index.rst @@ -12,7 +12,7 @@ bottom of this page in the footer. .. note:: This manual is for advanced users of Freeciv21. Most players simply install the game and either play local single-player games or join online Longturn multi-player games and do not really worry at all about the - server. If you are good at Linux administration, interesting in hosting your own server, or better + server. If you are good at Linux administration, interested in hosting your own server, or better understand how the Longturn team goes about creating the online games, then read on! If you are having trouble, come find the Longturn Community on Discord at https://discord.gg/98krqGm. A good diff --git a/docs/Manuals/modpack-installer.rst b/docs/Manuals/modpack-installer.rst index 4b2b7b131d..c6fa0352f2 100644 --- a/docs/Manuals/modpack-installer.rst +++ b/docs/Manuals/modpack-installer.rst @@ -21,6 +21,10 @@ They can be installed using the modpack installer tool :file:`freeciv21-modpack- standard installation. There is also a command-line-only tool called :file:`freeciv21-modpack`, which is mainly useful for headless game servers. +The easiest way to open the modpack installer is by clicking the :guilabel:`Mods` button on the +:doc:`Start Screen ` or the :guilabel:`Add Modpacks` option from the +:guilabel:`Game` menu. + In standard Freeciv21 builds, when you start the graphical modpack installer, it will show a list of modpacks curated by the Freeciv21 developers and Longturn community. You can select one and click :guilabel:`Install modpack`. The tool will download the files for the selected modpack, any other modpacks it @@ -89,7 +93,7 @@ modpacks by hand, the standard rulesets, tilesets, etc. supplied with Freeciv21 The precise location where files are downloaded to depends on your build and platform. For Unix systems, it is likely to be under the hidden :file:`~/.local/share/freeciv21` directory in your home directory. For -Windows based sytems it will be in your user profile directory in a hidden :file:`AppData` folder, typically, +Windows based systems it will be in your user profile directory in a hidden :file:`AppData` folder, typically, :file:`C:\\Users\\[MyUserName]\\AppData\\Roaming\\freeciv21` It is likely to be near where the Freeciv21 interface stores its saved games. diff --git a/docs/Modding/Rulesets/Effects/Nation_Intelligence.rst b/docs/Modding/Rulesets/Effects/Nation_Intelligence.rst index 749a4d6ecb..2d372f5846 100644 --- a/docs/Modding/Rulesets/Effects/Nation_Intelligence.rst +++ b/docs/Modding/Rulesets/Effects/Nation_Intelligence.rst @@ -17,7 +17,7 @@ Nation_Intelligence The ``Nation_Intelligence`` effect controls what kind of information about a foreign nation is visible in the :ref:`Nations View `. A value of ``0`` or lower hides the information, while it becomes visible when the effect evaluates to ``1`` or bigger. For instance, the following effect -repurposes the :wonder:`United Nations` to reveal everyone's secrets to everone else: +repurposes the :wonder:`United Nations` to reveal everyone's secrets to everyone else: .. code-block:: ini diff --git a/docs/Modding/Rulesets/actions.rst b/docs/Modding/Rulesets/actions.rst index 75c5f3d29f..19bff99184 100644 --- a/docs/Modding/Rulesets/actions.rst +++ b/docs/Modding/Rulesets/actions.rst @@ -284,7 +284,7 @@ Targeted Sabotage City Escape .. _action-sabotage-city-production: Sabotage City Production - Sabotage the city's produciton. + Sabotage the city's production. Rules: @@ -296,7 +296,7 @@ Sabotage City Production .. _action-sabotage-city-production-escape: Sabotage City Production Escape - Sabotage the city's produciton and escape. + Sabotage the city's production and escape. Rules: @@ -541,7 +541,7 @@ Establish Trade Route .. _action-enter-marketplace: Enter Marketplace - Get a one time bounus without creating a trade route. + Get a one time bonus without creating a trade route. Rules: @@ -904,7 +904,7 @@ Bombard * if ``force_capture_units`` is TRUE, "Capture Units" must be impossible. * actor must have a ``bombard_rate`` > 0. * actor must have an ``attack`` > 0. - * actor must be on a tile next to the target or, if :code:`bombard_max_range` allows it, futher away. + * actor must be on a tile next to the target or, if :code:`bombard_max_range` allows it, further away. * target cannot be in a city the actor player is not at war with. * target owner must be at war with actor. (!) @@ -916,7 +916,7 @@ Bombard 2 Rules: * UI name can be set using :code:`ui_name_bombard_2`. - * actor must be on a tile next to the target or, if :code:`bombard_2_max_range` allows it, futher away. + * actor must be on a tile next to the target or, if :code:`bombard_2_max_range` allows it, further away. * A copy of "Bombard". * See "Bombard" for everything else. @@ -928,7 +928,7 @@ Bombard 3 Rules: * UI name can be set using :code:`ui_name_bombard_3`. - * actor must be on a tile next to the target or, if :code:`bombard_3_max_range` allows it, futher away. + * actor must be on a tile next to the target or, if :code:`bombard_3_max_range` allows it, further away. * A copy of "Bombard". * See "Bombard" for everything else. diff --git a/docs/Modding/Rulesets/effects.rst b/docs/Modding/Rulesets/effects.rst index d0d6c63312..f809cec897 100644 --- a/docs/Modding/Rulesets/effects.rst +++ b/docs/Modding/Rulesets/effects.rst @@ -809,6 +809,15 @@ Has_Senate Inspire_Partisans Partisan units (defined in :file:`units.ruleset`) may spring up when this player's cities are taken. + The number of partisans created is a function of the city size. + When multiple unit types have the Partisan flag, the game tries to choose one the player can build. If + the player cannot build any, the first Partisan unit type is used. If the created partisans units have a + non-zero ``pop_cost``, the city will lose citizens accordingly. + + .. note:: + This effect can create units that the player could normally not build (because the tech hasn't + been researched or the ``NoBuild`` flag is set). It is your responsibility to set the appropriate + requirements to avoid creating advanced units if a city is conquered in the early game. .. _effect-happiness-to-gold: diff --git a/docs/Modding/Rulesets/nations.rst b/docs/Modding/Rulesets/nations.rst index 4e672b594f..d30de7e20e 100644 --- a/docs/Modding/Rulesets/nations.rst +++ b/docs/Modding/Rulesets/nations.rst @@ -25,7 +25,7 @@ The following information is required to add a new nation: Napoléon Bonaparte (https://en.wikipedia.org/wiki/Napoleon), but not Jean Casimir-Perier (https://en.wikipedia.org/wiki/Jean_Casimir-Perier). * Special names for the ruler in certain governments, if applicable. For instance, when in Despotism the - Egypian leader is called *Pharaoh*. + Egyptian leader is called *Pharaoh*. * A flag, preferably something official (if your nation does not have an official flag, think twice before including it). Wikipedia has many of those under free licenses. * A few nations that will be preferred by the server when there is a civil war. For instance, the @@ -195,7 +195,7 @@ Contents and Style What Nations Can Be Added ------------------------- -A nation in Freeciv21 should preferrably be a current independent country or a historical kingdom or realm. A +A nation in Freeciv21 should preferably be a current independent country or a historical kingdom or realm. A nation that is currently governed by or the part of a greater political entity, or in other ways lacks complete independence could in most cases be made a Freeciv21 nation as well, but must never be listed as *modern* (see `Nation grouping`_ below.) diff --git a/docs/Modding/Tilesets/graphics.rst b/docs/Modding/Tilesets/graphics.rst index d8051db0f8..fc40904cbf 100644 --- a/docs/Modding/Tilesets/graphics.rst +++ b/docs/Modding/Tilesets/graphics.rst @@ -178,7 +178,7 @@ the :code:`[tilespec]` section. Currently options include: :strong:`String Lists` - String lists are aa comma-separated list of strings. + String lists are a comma-separated list of strings. * :code:`files` : A list of :file:`.spec` files to scan for sprites. See "individual spec files", below. @@ -225,7 +225,7 @@ Multiple grids would be useful to have different size tiles in the same file. Ea left) and spacing, both in terms of pixels, and then refers to individual tiles of the grid by row and column. The origin, and rows and columns, are counted as (0,0) = top left. -* :code:`x_top_left` : X-coordinate of the leftmost pixel of the leftomost cell. +* :code:`x_top_left` : X-coordinate of the leftmost pixel of the leftmost cell. * :code:`y_top_left` : Y-coordinate of the topmost pixel of the topmost cell. * :code:`dx` : Cell width. * :code:`dy` : Cell height. diff --git a/docs/Modding/Tilesets/ts-breaking-changes.rst b/docs/Modding/Tilesets/ts-breaking-changes.rst index 41fa50eac2..51a53926a7 100644 --- a/docs/Modding/Tilesets/ts-breaking-changes.rst +++ b/docs/Modding/Tilesets/ts-breaking-changes.rst @@ -4,8 +4,8 @@ Tileset Breaking Changes ************************ -This page lists in reverse chronilogical order breaking changes merged into the ``master`` branch of the -GitHub repository to aid Tileset modders keep thier tilesets up to date. +This page lists in reverse chronological order breaking changes merged into the ``master`` branch of the +GitHub repository to aid Tileset modders keep their tilesets up to date. Post Beta.4 before Beta.5 ========================= diff --git a/docs/Modding/index.rst b/docs/Modding/index.rst index 30342e0e21..a74d7d3395 100644 --- a/docs/Modding/index.rst +++ b/docs/Modding/index.rst @@ -8,7 +8,7 @@ Modding The Modding category is an area for documentation editors to provide tips and other details on modifying aspects of Freeciv21 such as Rulesets, Musicsets, Soundsets and Tilesets. All of these areas allow for a -large amount of varyability in game play that is not hardcoded in the software. This is one of the +large amount of variability in game play that is not hardcoded in the software. This is one of the strengths of Freeciv21. There are five major areas of Modding that are often called "Modpacks" and are written by "Modders". The @@ -102,7 +102,7 @@ Soundsets Soundsets are a collection of :literal:`spec` files that allow a Modder to add sound files to varying events that happen inside the game. Events such as founding a city, or attacking a unit can have a sound associated with them. There is a huge number of events in Freeciv21 that a Modder can attach a sound file to. Soundsets -will start with a top-lvel :literal:`.soundset` file and with a directory of the same name will have +will start with a top-level :literal:`.soundset` file and with a directory of the same name will have :literal:`.ogg` sound files to play in the client. Have a look at :file:`stdsounds.soundspec` and associated files in :file:`/stdsounds` for an example. @@ -116,7 +116,7 @@ Musicsets Musicsets are a collection of :literal:`spec` files that allow a Modder to add Music files to play as a soundtrack inside the game. Game music follows the game based on the nation selected and the mood. The mood is -essentially binary: peace or war. Musicsets will start with a top-lvel :literal:`.musicspec` file and with a +essentially binary: peace or war. Musicsets will start with a top-level :literal:`.musicspec` file and with a directory of the same name will have :literal:`.ogg` sound files to play in the client. Have a look at :file:`stdmusic.musicspec` and associated files in :file:`/stdmusic` for an example. diff --git a/docs/Modding/musicsets.rst b/docs/Modding/musicsets.rst index f53ddc5102..8231587906 100644 --- a/docs/Modding/musicsets.rst +++ b/docs/Modding/musicsets.rst @@ -17,7 +17,7 @@ references to the media files in a separate sub-directory. The soundtrack is broken up into time periods following the technology tree and is split by two moods: peace and combat. Peace is generally defined when you are "farming" and growing your civilization with no fighting -going on at all. Any kind of fighting, inlcuding defense of your cities will trigger combat and the music mood +going on at all. Any kind of fighting, including defense of your cities will trigger combat and the music mood will change. After 16 turns of no combat the music will return to peace. At the beginning of the game, you select the style of music you want to hear by picking the city style of your @@ -33,7 +33,7 @@ civilization. The current choices are: The city style is automatically selected for you when you pick your nation, but you can change it if you like. The discovery of :advance:`University` changes the music for all city styles for the Renaissance Age. All -further disoveries noted below will change the music for all city styles/nations. +further discoveries noted below will change the music for all city styles/nations. The discovery of :advance:`Railroad` brings in the Industrial Age. diff --git a/docs/Playing/cma.rst b/docs/Playing/cma.rst index b348be7dac..3638165a5a 100644 --- a/docs/Playing/cma.rst +++ b/docs/Playing/cma.rst @@ -22,7 +22,7 @@ mining, or are occupied by an enemy, the Governor becomes active. Second, it sup like production (shields), gold, science, or luxury goods. Third, it gives the player a fine-grained control over this, with the possibility of setting constraints for any kind of city output. The latter includes the constraint of celebration, which makes it very easy to let your cities grow, even in harder times. The forth, -and probably most valuable thing in war times, is that is keeps your cities content, preventing them from +and probably most valuable thing in war times, is that it keeps your cities content, preventing them from revolt. The legacy Freeciv Wiki also contains some other useful information related to the CMA: @@ -125,7 +125,7 @@ The game allows the user to load and save preset parameters for the agent. Choos it will save any changes you made to you Governor presets as well. The format for the options file (usually :file:`~/.local/share/freeciv21/freeciv-client-rc-X.Y` , where X.Y -is the version of freeciv21 in use) is as follows (in case you which to change these presets manually, i.e. +is the version of Freeciv21 in use) is as follows (in case you which to change these presets manually, i.e. with a text editor). Under the heading :literal:`[cma]`, is a :literal:`number_of_presets`. This should be set to the number of diff --git a/docs/Playing/faq.rst b/docs/Playing/faq.rst index bbbe02730e..e52273554b 100644 --- a/docs/Playing/faq.rst +++ b/docs/Playing/faq.rst @@ -13,12 +13,12 @@ Frequently Asked Questions (FAQ) ******************************** -The following page has a listing of frequenty asked questions with answers about Freeciv21. +The following page has a listing of frequently asked questions with answers about Freeciv21. Gameplay ======== -This section of the FAQ is broken into a collection of sub-sections all surrounding general GamePlay aspects +This section of the FAQ is broken into a collection of sub-sections all surrounding general Gameplay aspects of Freeciv21: * `Gameplay General`_ @@ -188,7 +188,7 @@ Other than as noted here, the :term:`AI` players are not known to cheat. Does the game have a combat calculator, like other Civ games have? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -There is no integrated combat calculator. You can use the one on the longturn.net website here: +There is no integrated combat calculator. You can use the one on the Longturn.net website here: https://longturn.net/warcalc/. You can also select an attacking unit and then middle-click over a defending unit and in the pop-up window you will see the odds of win/loss. @@ -851,10 +851,10 @@ If all players are on the same local area network (LAN), they should launch thei the existing server listed. Double-click on it to join. To play over the Internet, players will need to enter the hostname and port into their game interfaces. The -game admin will need to tell the other players those details. To join a longturn.net server you start by +game admin will need to tell the other players those details. To join a Longturn.net server you start by clicking :guilabel:`Connect to Network Game` and then in the bottom-left of the dialog fill in the :guilabel:`Connect`, :guilabel:`Port`, and :guilabel:`Username` fields provided by the game admin. Once ready, -click the :guilabel:`Connect` button at the bottom-right, fill in your longturn.net password in the +click the :guilabel:`Connect` button at the bottom-right, fill in your Longturn.net password in the :guilabel:`Password` box and you will be added to the game. .. note:: diff --git a/docs/Playing/how-to-play.rst b/docs/Playing/how-to-play.rst index b34c493a50..5709782104 100644 --- a/docs/Playing/how-to-play.rst +++ b/docs/Playing/how-to-play.rst @@ -165,7 +165,7 @@ good to discuss here in the early game. :menuselection:`Game --> Load Another Tileset` and picking ``Hexemplio`` from the list. Let us first talk about two concepts: *Vision Radius* and *Working Radius*. Each city has a vision radius and -a working radius. The vision radius is the tiles that the citizens of a city can see on the map. If an emeny +a working radius. The vision radius is the tiles that the citizens of a city can see on the map. If an enemy unit comes within the vision radius of a city, a sentried unit inside of the city will wake up and alert you. Within the vision radius is the smaller working radius. When thinking of city planning, you should be most concerned with the working radius of a city. These are the tiles that the citizens of your cities manage to @@ -223,7 +223,7 @@ but at the beginning of the game you will have a lot of land that is not being u takes more moves for your :unit:`Settlers` to reach the planned city center of the city. In Smallpoxing you only have to move a few tiles. With Largepoxing you have to move twice the distance and time (in turns). -There is a third stragey. It is not called “Midpoxing” per se, but the strategy is similar to a middle ground +There is a third strategy. It is not called “Midpoxing” per se, but the strategy is similar to a middle ground between the Smallpoxing and Largepoxing strategies. Here is an example of a Midpoxing strategy: .. _Midpoxing: diff --git a/docs/Playing/index.rst b/docs/Playing/index.rst index 2285c4eca3..e1b7b30db3 100644 --- a/docs/Playing/index.rst +++ b/docs/Playing/index.rst @@ -2,7 +2,7 @@ Playing ======= The Playing category is an area for documentation editors to provide tips and tricks on ways to play -Freeciv21 and any of the varying rulesets that the longurn.net community likes to play. +Freeciv21 and any of the varying rulesets that the Longturn.net community likes to play. .. toctree:: diff --git a/docs/Playing/turn-change.rst b/docs/Playing/turn-change.rst index 9c939b4aaf..bcc7b69dbb 100644 --- a/docs/Playing/turn-change.rst +++ b/docs/Playing/turn-change.rst @@ -18,7 +18,7 @@ This page has been adapted from the legacy Freeciv `Wiki `_ community. The documentation is organized in six categories: +`Longturn.net `_ community. The documentation is organized in six categories: :doc:`Getting ` The Getting category is where you to go learn about Freeciv21 and how to get it installed on your system. :doc:`Playing ` The Playing category is an area for documentation editors to provide tips and tricks on ways to play - Freeciv21 and any of they varying rulesets that the longurn.net community likes to play. You will also find + Freeciv21 and any of they varying rulesets that the Longturn.net community likes to play. You will also find the FAQ here. :doc:`Manuals ` @@ -31,7 +31,7 @@ Welcome to the documentation of the Freeciv21 project brought to you by the :doc:`Modding ` The Modding category is an area for documentation editors to provide tips and other details on modifying aspects of Freeciv21 such as Rulesets, Musicsets, Soundsets and Tilesets. All of these areas allow for a - large amount of varyability in game play that is not hardcoded in the software. This is one of the + large amount of variability in game play that is not hardcoded in the software. This is one of the strengths of Freeciv21. :doc:`Contributing ` diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 92ed9faf5d..1bacb74964 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -87,7 +87,7 @@ target_include_directories(server PUBLIC ${CMAKE_SOURCE_DIR}/ai) target_include_directories(server PUBLIC ${CMAKE_SOURCE_DIR}/ai/default) target_include_directories(server PUBLIC ${CMAKE_SOURCE_DIR}/ai/classic) -target_link_libraries(server PUBLIC Qt5::Core Qt5::Network server_gen) +target_link_libraries(server PUBLIC Qt6::Core Qt6::Network server_gen) target_link_libraries(server PRIVATE Readline::readline) add_subdirectory(advisors) diff --git a/server/connecthand.cpp b/server/connecthand.cpp index e6e5bfbc27..9b7daef6ac 100644 --- a/server/connecthand.cpp +++ b/server/connecthand.cpp @@ -399,7 +399,7 @@ bool handle_login_request(struct connection *pconn, info.major_version = MAJOR_VERSION; info.minor_version = MINOR_VERSION; info.patch_version = PATCH_VERSION; - info.emerg_version = EMERGENCY_VERSION; + info._obsolete = 0; sz_strlcpy(info.version_label, VERSION_LABEL); send_packet_server_info(pconn, &info); } diff --git a/server/savegame/savegame3.cpp b/server/savegame/savegame3.cpp index c315d65afe..e5b7396b00 100644 --- a/server/savegame/savegame3.cpp +++ b/server/savegame/savegame3.cpp @@ -1574,8 +1574,7 @@ static void sg_save_savefile(struct savedata *saving) secfile_insert_str(saving->file, saving->save_reason, "savefile.reason"); // Save as accurate freeciv revision information as possible - secfile_insert_str(saving->file, freeciv_datafile_version(), - "savefile.revision"); + secfile_insert_str(saving->file, freeciv21_version(), "savefile.revision"); /* Save rulesetdir at this point as this ruleset is required by this * savefile. */ @@ -2376,7 +2375,6 @@ static void sg_save_scenario(struct savedata *saving) game_version = MAJOR_VERSION * 1000000 + MINOR_VERSION * 10000 + PATCH_VERSION * 100; - game_version += EMERGENCY_VERSION; secfile_insert_int(saving->file, game_version, "scenario.game_version"); if (!saving->scenario || !game.scenario.is_scenario) { diff --git a/server/scripting/api_server_edit.cpp b/server/scripting/api_server_edit.cpp index 4f6733c383..0672cca4d5 100644 --- a/server/scripting/api_server_edit.cpp +++ b/server/scripting/api_server_edit.cpp @@ -9,6 +9,8 @@ */ // utility +#include "city.h" +#include "cityturn.h" #include "fcintl.h" #include "rand.h" @@ -279,6 +281,20 @@ void api_edit_create_city(lua_State *L, Player *pplayer, Tile *ptile, create_city(pplayer, ptile, name, pplayer); } +/** + * Resizes a city. + */ +void api_edit_resize_city(lua_State *L, City *pcity, int size, + const char *reason) +{ + LUASCRIPT_CHECK_STATE(L); + LUASCRIPT_CHECK_ARG_NIL(L, pcity, 2, City); + + LUASCRIPT_CHECK(L, size > 0 && size < MAX_CITY_SIZE, "Invalid city size"); + + city_change_size(pcity, size, city_owner(pcity), reason); +} + /** Create a new player. */ diff --git a/server/scripting/api_server_edit.h b/server/scripting/api_server_edit.h index 9fd06b6f27..ef7066cea0 100644 --- a/server/scripting/api_server_edit.h +++ b/server/scripting/api_server_edit.h @@ -42,6 +42,8 @@ bool api_edit_change_terrain(lua_State *L, Tile *ptile, Terrain *pterr); void api_edit_create_city(lua_State *L, Player *pplayer, Tile *ptile, const char *name); +void api_edit_resize_city(lua_State *L, City *pcity, int size, + const char *reason); Player *api_edit_create_player(lua_State *L, const char *username, Nation_Type *pnation, const char *ai); void api_edit_change_gold(lua_State *L, Player *pplayer, int amount); diff --git a/server/scripting/script_server.cpp b/server/scripting/script_server.cpp index a2fd38182a..a4a502220f 100644 --- a/server/scripting/script_server.cpp +++ b/server/scripting/script_server.cpp @@ -118,19 +118,18 @@ bool script_server_unsafe_do_string(struct connection *caller, bool script_server_load_file(const char *filename, char **buf) { FILE *ffile; - struct stat stats; char *buffer; - fc_stat(filename, &stats); + QFileInfo stats(filename); ffile = fc_fopen(filename, "r"); if (ffile != nullptr) { int len; - buffer = new char[stats.st_size + 1]; - len = fread(buffer, 1, stats.st_size, ffile); + buffer = new char[stats.size() + 1]; + len = fread(buffer, 1, stats.size(), ffile); - if (len == stats.st_size) { + if (len == stats.size()) { buffer[len] = '\0'; *buf = buffer; diff --git a/server/scripting/tolua_server.pkg b/server/scripting/tolua_server.pkg index 3a0cc277b6..edfb148213 100644 --- a/server/scripting/tolua_server.pkg +++ b/server/scripting/tolua_server.pkg @@ -121,6 +121,8 @@ module edit { void api_edit_create_city @ create_city (lua_State *L, Player *pplayer, Tile *ptile, const char *name); + void api_edit_resize_city + @ resize_city (lua_State *L, City *pcity, int size, const char *reason); void api_edit_create_owned_extra @ create_owned_extra (lua_State *L, Tile *ptile, const char *name, Player *pplayer); diff --git a/server/sernet.cpp b/server/sernet.cpp index a21308a36b..ab059f7297 100644 --- a/server/sernet.cpp +++ b/server/sernet.cpp @@ -528,7 +528,7 @@ void connection_ping(struct connection *pconn) { civtimer *timer = timer_new(TIMER_USER, TIMER_ACTIVE); - log_debug("sending ping to %s (open=%d)", conn_description(pconn), + log_debug("sending ping to %s (open=%lld)", conn_description(pconn), pconn->server.ping_timers->size()); timer_start(timer); pconn->server.ping_timers->append(timer); diff --git a/server/srv_main.cpp b/server/srv_main.cpp index 57a9126ddd..70e0cf4c97 100644 --- a/server/srv_main.cpp +++ b/server/srv_main.cpp @@ -204,9 +204,9 @@ void srv_init() has_been_srv_init = true; // init character encodings. - init_character_encodings(FC_DEFAULT_DATA_ENCODING, false); + init_character_encodings(); #ifdef ENABLE_NLS - bind_textdomain_codeset("freeciv21-nations", get_internal_encoding()); + bind_textdomain_codeset("freeciv21-nations", "UTF-8"); #endif // Initialize callbacks. diff --git a/server/tests/CMakeLists.txt b/server/tests/CMakeLists.txt index eed9ea2c4e..211a020b95 100644 --- a/server/tests/CMakeLists.txt +++ b/server/tests/CMakeLists.txt @@ -7,7 +7,7 @@ file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/$/cli.cpp INPUT ${CMAKE_CURRENT_BINARY_DIR}/cli.cpp.in) add_executable(test_server_cli ${CMAKE_CURRENT_BINARY_DIR}/$/cli.cpp) -target_link_libraries(test_server_cli PRIVATE Qt5::Test) +target_link_libraries(test_server_cli PRIVATE Qt6::Test) add_test(NAME test_server_cli COMMAND test_server_cli WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}") diff --git a/server/unithand.cpp b/server/unithand.cpp index c4eddd9ecf..808281dc05 100644 --- a/server/unithand.cpp +++ b/server/unithand.cpp @@ -4134,8 +4134,7 @@ static bool do_attack(struct unit *punit, struct tile *def_tile, /* Now that dead defender is certainly no longer listed as unit * supported by the city, we may even remove the city * (if it shrinks from size 1) */ - auto pcity = tile_city(def_tile); - if (pdefender->hp <= 0) { + if (auto pcity = tile_city(def_tile); pcity != nullptr) { unit_attack_civilian_casualties(punit, pcity, paction, "attack"); } if (unit_is_alive(winner_id)) { diff --git a/server/unittools.cpp b/server/unittools.cpp index 476f18981b..6178118326 100644 --- a/server/unittools.cpp +++ b/server/unittools.cpp @@ -1176,7 +1176,15 @@ void place_partisans(struct tile *pcenter, struct player *powner, int count, int sq_radius) { struct tile *ptile = nullptr; - struct unit_type *u_type = get_role_unit(L_PARTISAN, 0); + struct unit_type *u_type = best_role_unit_for_player(powner, L_PARTISAN); + if (!u_type) { + // If the player cannot build any partisan, pick the first one + u_type = get_role_unit(L_PARTISAN, 0); + } + if (!u_type) { + // Cannot do anything. + return; + } while (count-- > 0 && find_a_good_partisan_spot(pcenter, powner, u_type, sq_radius, diff --git a/tools/civmanual.cpp b/tools/civmanual.cpp index 8b157c6801..c78756952f 100644 --- a/tools/civmanual.cpp +++ b/tools/civmanual.cpp @@ -72,8 +72,6 @@ struct tag_types { const char *title_end; const char *sect_title_begin; const char *sect_title_end; - const char *image_begin; - const char *image_end; const char *item_begin; const char *item_end; const char *subitem_begin; @@ -102,12 +100,6 @@ struct tag_types html_tags = { // section title end "", - // image begin - "", - // item begin "
\n", @@ -142,12 +134,6 @@ struct tag_types wiki_tags = { // section title end "===", - // image begin - "[[Image:", - - // image end - ".png]]", - // item begin "----\n\n", @@ -202,7 +188,7 @@ static bool manual_command(struct tag_types *tag_info) fprintf(doc, "%s", tag_info->header); fprintf(doc, "\n\n", - freeciv_datafile_version()); + freeciv21_version()); switch (manuals) { case MANUAL_SETTINGS: @@ -332,8 +318,7 @@ static bool manual_command(struct tag_types *tag_info) fprintf(doc, _("%sFreeciv21 %s terrain help (%s)%s\n\n"), tag_info->title_begin, freeciv21_version(), game.control.name, tag_info->title_end); - fprintf(doc, "", - _("Terrain")); + fprintf(doc, "
%s
", _("Terrain")); fprintf(doc, "", _("Resources")); fprintf(doc, "", _("Move cost"), _("Defense bonus")); fprintf(doc, "", @@ -367,19 +352,15 @@ static bool manual_command(struct tag_types *tag_info) continue; } - fprintf(doc, "", tag_info->image_begin, - pterrain->graphic_str, tag_info->image_end, - terrain_name_translation(pterrain)); + fprintf(doc, "", terrain_name_translation(pterrain)); fprintf(doc, "\n", pterrain->output[O_FOOD], pterrain->output[O_SHIELD], pterrain->output[O_TRADE]); fprintf(doc, "
%sF/P/T%s%s
%s
%s
%s
%s
%s
%s
%s
(%s)
%s%s%s%s
%s%d/%d/%d\n"); for (r = pterrain->resources; *r; r++) { fprintf(doc, - "" - "\n", - tag_info->image_begin, (*r)->graphic_str, - tag_info->image_end, extra_name_translation(*r), + "\n", + extra_name_translation(*r), (*r)->data.resource->output[O_FOOD], (*r)->data.resource->output[O_SHIELD], (*r)->data.resource->output[O_TRADE]); @@ -477,7 +458,7 @@ static bool manual_command(struct tag_types *tag_info) } fprintf(doc, - "
%s%s%s%s%d/%d/%d
%s%d/%d/%d
\n" + "
%s
\n" "\n\n", _("Name"), _("Cost"), _("Upkeep"), _("Requirement"), _("Obsolete by"), _("More info")); @@ -496,11 +477,10 @@ static bool manual_command(struct tag_types *tag_info) nullptr); fprintf(doc, - "\n" + "\n" "\n
%s%s
%s
%s
%s
%s
%s%s%s%s
%s%d
%d
", - tag_info->image_begin, pimprove->graphic_str, - tag_info->image_end, improvement_name_translation(pimprove), - pimprove->build_cost, pimprove->upkeep); + improvement_name_translation(pimprove), pimprove->build_cost, + pimprove->upkeep); requirement_vector_iterate(&pimprove->reqs, req) { @@ -667,7 +647,7 @@ int main(int argc, char **argv) QCoreApplication::setApplicationVersion(freeciv21_version()); init_nls(); - init_character_encodings(FC_DEFAULT_DATA_ENCODING, false); + init_character_encodings(); QCommandLineParser parser; parser.addHelpOption(); diff --git a/tools/fcmp/CMakeLists.txt b/tools/fcmp/CMakeLists.txt index 6b4ce120af..0cb659f2c8 100644 --- a/tools/fcmp/CMakeLists.txt +++ b/tools/fcmp/CMakeLists.txt @@ -28,7 +28,7 @@ if (FREECIV_ENABLE_FCMP_QT) mpgui_qt.cpp ) target_link_libraries(freeciv21-modpack-qt PRIVATE freeciv_modpack) - target_link_libraries(freeciv21-modpack-qt PRIVATE Qt5::Widgets) + target_link_libraries(freeciv21-modpack-qt PRIVATE Qt6::Widgets) install(TARGETS freeciv21-modpack-qt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT freeciv21) diff --git a/tools/fcmp/download.cpp b/tools/fcmp/download.cpp index a577773dc7..f259b25939 100644 --- a/tools/fcmp/download.cpp +++ b/tools/fcmp/download.cpp @@ -318,6 +318,7 @@ const char *download_modpack(const QUrl &url, const struct fcmp_params *fcmp, return msg; } } + delete[] inst_ver; } } diff --git a/tools/fcmp/modinst.cpp b/tools/fcmp/modinst.cpp index 80525a1029..ddfb84a07c 100644 --- a/tools/fcmp/modinst.cpp +++ b/tools/fcmp/modinst.cpp @@ -40,7 +40,6 @@ void load_install_info_lists(struct fcmp_params *fcmp) { char main_db_filename[500]; char scenario_db_filename[500]; - struct stat buf; fc_snprintf(main_db_filename, sizeof(main_db_filename), "%s/" DATASUBDIR "/" FCMP_CONTROLD "/mp.db", @@ -56,14 +55,14 @@ void load_install_info_lists(struct fcmp_params *fcmp) "%s/scenarios/" FCMP_CONTROLD "/modpacks.db", qUtf8Printable(fcmp->inst_prefix)); - if (fc_stat(main_db_filename, &buf)) { + if (QFileInfo::exists(main_db_filename)) { create_mpdb(main_db_filename, false); load_install_info_list(main_ii_filename); } else { open_mpdb(main_db_filename, false); } - if (fc_stat(scenario_db_filename, &buf)) { + if (QFileInfo::exists(scenario_db_filename)) { create_mpdb(scenario_db_filename, true); load_install_info_list(scenario_ii_filename); } else { @@ -77,10 +76,9 @@ void load_install_info_lists(struct fcmp_params *fcmp) void fcmp_init() { init_nls(); - init_character_encodings(FC_DEFAULT_DATA_ENCODING, false); - + init_character_encodings(); fc_srand(time(nullptr)); /* Needed at least for Windows version of - netfile_get_section_file() */ + netfile_get_section_file() */ } /** diff --git a/tools/fcmp/mpcli.cpp b/tools/fcmp/mpcli.cpp index 66aa2ae017..7d1576ff25 100644 --- a/tools/fcmp/mpcli.cpp +++ b/tools/fcmp/mpcli.cpp @@ -73,6 +73,8 @@ static void setup_modpack_list(const QString &name, const QUrl &url, if (!notes.isEmpty()) { qInfo() << _("Comment=") << notes; } + + delete[] tmp; } /** @@ -91,10 +93,7 @@ int main(int argc, char *argv[]) load_install_info_lists(&fcmp); qInfo(_("Freeciv21 modpack installer (command line version)")); - - qInfo("%s%s", word_version(), freeciv21_version()); - - qInfo("%s", ""); + qInfo(_("Version %s"), freeciv21_version()); if (fcmp.autoinstall.isEmpty()) { if (auto msg = diff --git a/tools/fcmp/mpdb.cpp b/tools/fcmp/mpdb.cpp index ac9496bb6e..da5e746062 100644 --- a/tools/fcmp/mpdb.cpp +++ b/tools/fcmp/mpdb.cpp @@ -111,12 +111,13 @@ static int mpdb_query(sqlite3 *handle, const char *query) ret = sqlite3_step(stmt); } - if (ret == SQLITE_DONE) { - ret = sqlite3_finalize(stmt); + if (ret != SQLITE_DONE && ret != SQLITE_ROW) { + qCritical("Query \"%s\" failed. (%d)", query, ret); } - if (ret != SQLITE_OK) { - qCritical("Query \"%s\" failed. (%d)", query, ret); + if (int errcode = sqlite3_finalize(stmt); errcode != SQLITE_OK) { + qCritical("Finalizing query \"%s\" returned error. (%d)", query, + errcode); } return ret; @@ -160,13 +161,13 @@ void create_mpdb(const char *filename, bool scenario_db) ");"); } - if (ret == SQLITE_OK) { + if (ret == SQLITE_DONE) { ret = mpdb_query(*handle, "create table modpacks (name VARCHAR(60) NOT null, " "type VARCHAR(32), version VARCHAR(32) NOT null);"); } - if (ret == SQLITE_OK) { + if (ret == SQLITE_DONE) { log_debug("Created %s", filename); } else { qCritical(_("Creating \"%s\" failed: %s"), filename, @@ -240,21 +241,23 @@ bool mpdb_update_modpack(const char *name, enum modpack_type type, ret = mpdb_query(*handle, qbuf); } - if (ret != SQLITE_OK) { + if (ret != SQLITE_DONE) { qCritical(_("Failed to insert modpack '%s' information"), name); } - return ret != SQLITE_OK; + return ret != SQLITE_DONE; } /** - Return version of modpack. + Return version of modpack. The caller is responsible to free the returned + string. */ const char *mpdb_installed_version(const char *name, enum modpack_type type) { sqlite3 **handle; int ret; char qbuf[2048]; + const char *version = nullptr; sqlite3_stmt *stmt; if (type == MPT_SCENARIO) { @@ -271,13 +274,20 @@ const char *mpdb_installed_version(const char *name, enum modpack_type type) ret = sqlite3_step(stmt); } - if (ret == SQLITE_DONE) { - ret = sqlite3_finalize(stmt); + if (ret == SQLITE_ROW) { + version = qstrdup((const char *) sqlite3_column_text(stmt, 2)); } - if (ret == SQLITE_ROW) { - return (const char *) sqlite3_column_text(stmt, 2); + if (ret != SQLITE_DONE && ret != SQLITE_ROW) { + qCritical("Query to get installed version for \"%s\" failed. (%d)", name, + ret); + } + + if (int errcode = sqlite3_finalize(stmt); errcode != SQLITE_OK) { + qCritical( + "Finalizing query to get installed version for \"%s\" failed. (%d)", + name, errcode); } - return nullptr; + return version; } diff --git a/tools/fcmp/mpgui_qt.cpp b/tools/fcmp/mpgui_qt.cpp index 28f0d6f180..197056308a 100644 --- a/tools/fcmp/mpgui_qt.cpp +++ b/tools/fcmp/mpgui_qt.cpp @@ -104,7 +104,7 @@ int main(int argc, char **argv) central = new QWidget; main_window = new mpgui_main(&app, central); - main_window->setGeometry(0, 30, 640, 60); + main_window->resize(820, 140); main_window->setWindowTitle( QString::fromUtf8(_("Freeciv21 modpack installer (Qt)"))); @@ -171,13 +171,9 @@ void mpgui::setup(QWidget *central, struct fcmp_params *params) new QPushButton(QString::fromUtf8(_("Install modpack"))); QStringList headers; QLabel *URL_label; - QLabel *version_label; - char verbuf[2048]; - fc_snprintf(verbuf, sizeof(verbuf), "%s%s", word_version(), - freeciv21_version()); - - version_label = new QLabel(QString::fromUtf8(verbuf)); + auto version_label = + new QLabel(QString(_("Version %1")).arg(freeciv21_version())); version_label->setAlignment(Qt::AlignHCenter); version_label->setParent(central); version_label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); @@ -311,7 +307,6 @@ void mpgui::refresh_list_versions() for (int i = 0; i < mpcount; i++) { QString name_str; int type_int; - const char *new_inst; enum modpack_type type; QByteArray name_bytes; @@ -319,13 +314,12 @@ void mpgui::refresh_list_versions() type_int = mplist_table->item(i, ML_TYPE)->text().toInt(); type = (enum modpack_type) type_int; name_bytes = name_str.toUtf8(); - new_inst = mpdb_installed_version(name_bytes.data(), type); - if (new_inst == nullptr) { - new_inst = _("Not installed"); - } + auto tmp = mpdb_installed_version(qUtf8Printable(name_bytes), type); + QString new_inst = tmp ? tmp : _("Not installed"); + delete[] tmp; - mplist_table->item(i, ML_COL_INST)->setText(QString::fromUtf8(new_inst)); + mplist_table->item(i, ML_COL_INST)->setText(new_inst); } mplist_table->resizeColumnsToContents(); @@ -356,6 +350,7 @@ void mpgui::setup_list(const QString &name, const QUrl &url, const char *tmp = mpdb_installed_version(qUtf8Printable(name), type); QString inst_str = tmp ? tmp : _("Not installed"); + delete[] tmp; QString type_nbr; QTableWidgetItem *item; diff --git a/tools/ruledit/CMakeLists.txt b/tools/ruledit/CMakeLists.txt index 8ff8267097..068bf3b065 100644 --- a/tools/ruledit/CMakeLists.txt +++ b/tools/ruledit/CMakeLists.txt @@ -28,7 +28,7 @@ add_executable( target_link_libraries(freeciv21-ruledit server) target_link_libraries(freeciv21-ruledit tools_ruleutil) target_link_libraries(freeciv21-ruledit tools_shared) -target_link_libraries(freeciv21-ruledit Qt5::Widgets) +target_link_libraries(freeciv21-ruledit Qt6::Widgets) add_dependencies(freeciv21-ruledit freeciv_translations) install(TARGETS freeciv21-ruledit diff --git a/tools/ruledit/ruledit.cpp b/tools/ruledit/ruledit.cpp index 6d7c01cad8..e77f26feaa 100644 --- a/tools/ruledit/ruledit.cpp +++ b/tools/ruledit/ruledit.cpp @@ -65,7 +65,7 @@ int main(int argc, char **argv) QIcon::setFallbackThemeName(QIcon::themeName()); QIcon::setThemeName(QStringLiteral("icons")); - qApp->setWindowIcon(QIcon::fromTheme(QStringLiteral("freeciv21-client"))); + qApp->setWindowIcon(QIcon::fromTheme(QStringLiteral("freeciv21-ruledit"))); log_init(); @@ -75,9 +75,9 @@ int main(int argc, char **argv) (void) bindtextdomain("freeciv21-ruledit", get_locale_dir()); #endif - init_character_encodings(FC_DEFAULT_DATA_ENCODING, false); + init_character_encodings(); #ifdef ENABLE_NLS - bind_textdomain_codeset("freeciv21-ruledit", get_internal_encoding()); + bind_textdomain_codeset("freeciv21-ruledit", "UTF-8"); #endif // Initialize command line arguments. diff --git a/tools/ruledit/ruledit_qt.cpp b/tools/ruledit/ruledit_qt.cpp index 5eed6e98b2..86b23b0dec 100644 --- a/tools/ruledit/ruledit_qt.cpp +++ b/tools/ruledit/ruledit_qt.cpp @@ -83,8 +83,6 @@ ruledit_gui::ruledit_gui(ruledit_main *main) : QObject(main) QWidget *edit_widget = new QWidget(); QPushButton *ruleset_accept; QLabel *rs_label; - QLabel *version_label; - char verbuf[2048]; data.nationlist = nullptr; data.nationlist_saved = nullptr; @@ -92,13 +90,12 @@ ruledit_gui::ruledit_gui(ruledit_main *main) : QObject(main) auto *central = new QWidget; main->setCentralWidget(central); - fc_snprintf(verbuf, sizeof(verbuf), "%s%s", word_version(), - freeciv21_version()); - main_layout = new QStackedLayout(); preload_layout->setSizeConstraint(QLayout::SetMaximumSize); - version_label = new QLabel(verbuf); + + auto version_label = + new QLabel(QString(_("Version %1")).arg(freeciv21_version())); version_label->setAlignment(Qt::AlignHCenter); version_label->setParent(central); preload_layout->addWidget(version_label); diff --git a/tools/ruleup.cpp b/tools/ruleup.cpp index 15fab41290..e3b2b37b03 100644 --- a/tools/ruleup.cpp +++ b/tools/ruleup.cpp @@ -109,8 +109,7 @@ int main(int argc, char **argv) log_init(); init_nls(); - - init_character_encodings(FC_DEFAULT_DATA_ENCODING, false); + init_character_encodings(); rup_parse_cmdline(app); diff --git a/tools/ruleutil/rulesave.cpp b/tools/ruleutil/rulesave.cpp index 52fdfaaa07..5d8b53b329 100644 --- a/tools/ruleutil/rulesave.cpp +++ b/tools/ruleutil/rulesave.cpp @@ -64,7 +64,7 @@ static struct section_file *create_ruleset_file(const char *rsname, } secfile_insert_str(sfile, buf, "datafile.description"); - secfile_insert_str(sfile, freeciv_datafile_version(), "datafile.ruledit"); + secfile_insert_str(sfile, freeciv21_version(), "datafile.ruledit"); secfile_insert_str(sfile, RULESET_CAPABILITIES, "datafile.options"); secfile_insert_int(sfile, FORMAT_VERSION, "datafile.format_version"); diff --git a/utility/CMakeLists.txt b/utility/CMakeLists.txt index 8c4b29e57a..80b9fe5afe 100644 --- a/utility/CMakeLists.txt +++ b/utility/CMakeLists.txt @@ -65,8 +65,8 @@ target_include_directories(utility PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(utility PRIVATE ${STACK_UNWINDING_LIBRARY}) target_link_libraries(utility PRIVATE ${STACK_SYMBOLS_LIBRARY}) -target_link_libraries(utility PUBLIC Qt5::Core Qt5::Network) -target_link_libraries(utility PRIVATE KF5::Archive) +target_link_libraries(utility PUBLIC Qt6::Core Qt6::Network) +target_link_libraries(utility PRIVATE KF6::Archive) if (WIN32 OR MSYS OR MINGW) target_link_libraries(utility PRIVATE ws2_32 wsock32) endif() diff --git a/utility/fc_version.h.in b/utility/fc_version.h.in index 04673e0ce7..734bad4149 100644 --- a/utility/fc_version.h.in +++ b/utility/fc_version.h.in @@ -3,17 +3,13 @@ #define MAJOR_VERSION @FC21_MAJOR_VERSION@ #define MINOR_VERSION @FC21_MINOR_VERSION@ #define PATCH_VERSION @FC21_PATCH_VERSION@ -#define EMERGENCY_VERSION @FC21_EMER_VERSION@ -#ifndef VERSION_LABEL -#define VERSION_LABEL "-@FC21_LABEL_VERSION@" -#endif +#define VERSION_LABEL "-@FC21_VERSION_LABEL@" + #cmakedefine01 IS_STABLE_VERSION -#ifndef VERSION_STRING -# if IS_STABLE_VERSION -# define VERSION_STRING "@FC21_MAJOR_VERSION@.@FC21_MINOR_VERSION@" -# else // IS_STABLE_VERSION -# define VERSION_STRING "@FC21_MAJOR_VERSION@.@FC21_MINOR_VERSION@.@FC21_PATCH_VERSION@.@FC21_EMER_VERSION@-@FC21_LABEL_VERSION@" -# endif +#if IS_STABLE_VERSION +# define VERSION_STRING "@FC21_MAJOR_VERSION@.@FC21_MINOR_VERSION@.@FC21_PATCH_VERSION@" +#else // IS_STABLE_VERSION +# define VERSION_STRING "@FC21_MAJOR_VERSION@.@FC21_MINOR_VERSION@-@FC21_VERSION_LABEL@.@FC21_PATCH_VERSION@" #endif #define NETWORK_CAPSTRING \ diff --git a/utility/fciconv.cpp b/utility/fciconv.cpp index e940733d4f..61b576e52b 100644 --- a/utility/fciconv.cpp +++ b/utility/fciconv.cpp @@ -20,110 +20,45 @@ #include #include -#include #include -static QTextCodec *localCodec; -static QTextCodec *dataCodec; -static QTextCodec *internalCodec; - -static const char *transliteration_string; -static const char *local_encoding, *data_encoding, *internal_encoding; - /** Must be called during the initialization phase of server and client to initialize the character encodings to be used. Pass an internal encoding of nullptr to use the local encoding internally. */ -void init_character_encodings(const char *my_internal_encoding, - bool my_use_transliteration) +void init_character_encodings() { - transliteration_string = ""; - if (my_use_transliteration) { - transliteration_string = "//TRANSLIT"; - } - - /* Set the data encoding - first check $FREECIV_DATA_ENCODING, - * then fall back to the default. */ - data_encoding = getenv("FREECIV_DATA_ENCODING"); - if (!data_encoding) { - data_encoding = FC_DEFAULT_DATA_ENCODING; - } - - /* Set the local encoding - first check $FREECIV_LOCAL_ENCODING, - * then ask the system. */ - local_encoding = getenv("FREECIV_LOCAL_ENCODING"); - if (!local_encoding) { - local_encoding = - qstrdup(QLocale::system().name().toLocal8Bit().constData()); - } - - /* Set the internal encoding - first check $FREECIV_INTERNAL_ENCODING, - * then check the passed-in default value, then fall back to the local - * encoding. */ - internal_encoding = getenv("FREECIV_INTERNAL_ENCODING"); - if (!internal_encoding) { - internal_encoding = my_internal_encoding; - - if (!internal_encoding) { - internal_encoding = local_encoding; - } - } - localCodec = QTextCodec::codecForLocale(); - dataCodec = QTextCodec::codecForName(data_encoding); - internalCodec = QTextCodec::codecForName(internal_encoding); #ifdef FREECIV_ENABLE_NLS - bind_textdomain_codeset("freeciv21-core", internal_encoding); + bind_textdomain_codeset("freeciv21-core", "UTF-8"); #endif - -#ifdef FREECIV_DEBUG - fprintf(stderr, "Encodings: Data=%s, Local=%s, Internal=%s\n", - data_encoding, local_encoding, internal_encoding); -#endif // FREECIV_DEBUG } -/** - Return the internal encoding. This depends on the server or GUI being - used. - */ -const char *get_internal_encoding() { return internal_encoding; } - char *data_to_internal_string_malloc(const char *text) { - QString s; - s = dataCodec->toUnicode(text); - s = internalCodec->fromUnicode(s); - return qstrdup(s.toLocal8Bit().data()); + return qstrdup(text); } + char *internal_to_data_string_malloc(const char *text) { - QString s; - s = internalCodec->toUnicode(text); - s = dataCodec->fromUnicode(s); - return qstrdup(s.toLocal8Bit().data()); + return qstrdup(text); } + char *internal_to_local_string_malloc(const char *text) { - QString s; - s = internalCodec->toUnicode(text); - s = localCodec->fromUnicode(s); - return qstrdup(s.toLocal8Bit().data()); + return qstrdup(QString(text).toLocal8Bit()); } + char *local_to_internal_string_malloc(const char *text) { - QString s; - s = localCodec->toUnicode(text); - s = internalCodec->fromUnicode(s); - return qstrdup(s.toLocal8Bit().data()); + return qstrdup(QString::fromLocal8Bit(text).toUtf8()); } + char *local_to_internal_string_buffer(const char *text, char *buf, size_t bufsz) { - QString s; - s = localCodec->toUnicode(text); - s = internalCodec->fromUnicode(s); - return qstrncpy(buf, s.toLocal8Bit().data(), bufsz); + return qstrncpy(buf, QString::fromLocal8Bit(text).toUtf8(), bufsz); } /** diff --git a/utility/fciconv.h b/utility/fciconv.h index 2de9b8d701..f96b46d41b 100644 --- a/utility/fciconv.h +++ b/utility/fciconv.h @@ -66,20 +66,15 @@ encoding. */ -#define FC_DEFAULT_DATA_ENCODING "UTF-8" +void init_character_encodings(); -void init_character_encodings(const char *internal_encoding, - bool use_transliteration); +[[deprecated]] char *data_to_internal_string_malloc(const char *text); +[[deprecated]] char *internal_to_data_string_malloc(const char *text); +[[deprecated]] char *internal_to_local_string_malloc(const char *text); +[[deprecated]] char *local_to_internal_string_malloc(const char *text); -const char *get_internal_encoding(); - -char *data_to_internal_string_malloc(const char *text); -char *internal_to_data_string_malloc(const char *text); -char *internal_to_local_string_malloc(const char *text); -char *local_to_internal_string_malloc(const char *text); - -char *local_to_internal_string_buffer(const char *text, char *buf, - size_t bufsz); +[[deprecated]] char * +local_to_internal_string_buffer(const char *text, char *buf, size_t bufsz); #define fc_printf(...) fc_fprintf(stdout, __VA_ARGS__) void fc_fprintf(FILE *stream, const char *format, ...) diff --git a/utility/inputfile.cpp b/utility/inputfile.cpp index 3508be98f2..f4b5e3eae6 100644 --- a/utility/inputfile.cpp +++ b/utility/inputfile.cpp @@ -68,7 +68,7 @@ #include // KArchive -#include +#include // utility #include "fcintl.h" @@ -206,7 +206,7 @@ struct inputfile *inf_from_file(const QString &filename, fc_assert_ret_val(!filename.isEmpty(), nullptr); fc_assert_ret_val(0 < filename.length(), nullptr); - auto *fp = new KFilterDev(filename); + auto *fp = new KCompressionDevice(filename); fp->open(QIODevice::ReadOnly); if (!fp->isOpen()) { delete fp; @@ -234,7 +234,7 @@ struct inputfile *inf_from_stream(QIODevice *stream, inf->filename.clear(); inf->fp = stream; inf->stream = new QTextStream(stream); - inf->stream->setCodec("UTF-8"); + inf->stream->setEncoding(QStringConverter::Utf8); inf->stream->setAutoDetectUnicode(true); // Allow UTF-16 and UTF-32 inf->datafn = datafn; @@ -256,8 +256,8 @@ static void inf_close_partial(struct inputfile *inf) // No way to determine whether a generic QIODevice has error'ed :( bool error = false; - if (dynamic_cast(inf->fp)) { - error = dynamic_cast(inf->fp)->error() != 0; + if (dynamic_cast(inf->fp)) { + error = dynamic_cast(inf->fp)->error() != 0; } if (error) { qCCritical(inf_category) << "Error before closing" << inf_filename(inf) @@ -635,7 +635,7 @@ static QString get_token_entry_name(struct inputfile *inf) } // Check that we didn't eat a comment in the middle - auto ref = inf->cur_line.midRef(inf->cur_line_pos, eq - inf->cur_line_pos); + auto ref = inf->cur_line.mid(inf->cur_line_pos, eq - inf->cur_line_pos); if (ref.contains(';') || ref.contains('#')) { return ""; } @@ -802,7 +802,7 @@ static QString get_token_value(struct inputfile *inf) qUtf8Printable(name)); return ""; } - auto fp = new KFilterDev(rfname); + auto fp = new KCompressionDevice(rfname); fp->open(QIODevice::ReadOnly); if (!fp->isOpen()) { qCCritical(inf_category, _("Cannot open stringfile \"%s\"."), diff --git a/utility/registry_ini.cpp b/utility/registry_ini.cpp index b55cd9914e..d660adb446 100644 --- a/utility/registry_ini.cpp +++ b/utility/registry_ini.cpp @@ -149,7 +149,8 @@ - Now uses hash.c */ // KArchive -#include +#include +#include // utility #include "bugs.h" @@ -620,7 +621,7 @@ bool secfile_save(const struct section_file *secfile, QString filename) } auto real_filename = interpret_tilde(filename); - auto fs = std::make_unique(real_filename); + auto fs = std::make_unique(real_filename); fs->open(QIODevice::WriteOnly); if (!fs->isOpen()) { diff --git a/utility/shared.cpp b/utility/shared.cpp index d7debef602..ede808f030 100644 --- a/utility/shared.cpp +++ b/utility/shared.cpp @@ -56,7 +56,7 @@ static QStringList default_data_path() QStringList{QStringLiteral("."), QStringLiteral("data"), freeciv_storage_dir() + QStringLiteral("/" DATASUBDIR), QStringLiteral(FREECIV_INSTALL_DATADIR)} - + QStandardPaths::standardLocations(QStandardPaths::DataLocation); + + QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); QCoreApplication::setApplicationName(app_name); return paths; } @@ -92,8 +92,6 @@ static QStringList scenario_dir_names = {}; static char *mc_group = nullptr; -Q_GLOBAL_STATIC(QString, realfile); - /** An AND function for fc_tristate. */ @@ -645,7 +643,7 @@ QVector *fileinfolist(const QStringList &dirs, const char *suffix) dir.setNameFilters({QStringLiteral("*") + QString::fromUtf8(suffix)}); for (auto name : dir.entryList()) { name.truncate(name.length() - qstrlen(suffix)); - files->append(name.toUtf8().data()); + files->append(name); } } std::sort(files->begin(), files->end()); @@ -657,48 +655,22 @@ QVector *fileinfolist(const QStringList &dirs, const char *suffix) Returns a filename to access the specified file from a directory by searching all specified directories for the file. - If the specified 'filename' is empty, the returned string contains - the effective path. (But this should probably only be used for - debug output.) - Returns an empty string if the specified filename cannot be found in any of the data directories. */ QString fileinfoname(const QStringList &dirs, const QString &filename) { - if (dirs.isEmpty()) { - return QString(); - } - - if (filename.isEmpty()) { - bool first = true; - - realfile->clear(); - for (const auto &dirname : dirs) { - if (first) { - *realfile += QStringLiteral("/%1").arg(dirname); - first = false; - } else { - *realfile += QStringLiteral("%1").arg(dirname); - } - } - - return *realfile; - } - for (const auto &dirname : dirs) { - struct stat buf; // see if we can open the file or directory - - *realfile = QStringLiteral("%1/%2").arg(dirname, filename); - if (fc_stat(qUtf8Printable(*realfile), &buf) == 0) { - return *realfile; + QString path = dirname + QLatin1String("/") + filename; + if (QFileInfo::exists(path)) { + return path; } } qDebug("Could not find readable file \"%s\" in data path.", qUtf8Printable(filename)); - return nullptr; + return QString(); } /** @@ -1130,7 +1102,7 @@ QString interpret_tilde(const QString &filename) if (filename == QLatin1String("~")) { return QDir::homePath(); } else if (filename.startsWith(QLatin1String("~/"))) { - return QDir::homePath() + filename.midRef(1); + return QDir::homePath() + filename.mid(1); } else { return filename; } diff --git a/utility/shared.h b/utility/shared.h index 63c35cd13c..63e37066a5 100644 --- a/utility/shared.h +++ b/utility/shared.h @@ -21,8 +21,6 @@ #include -template class QVector; - // Changing these will break network compatability! #define MAX_LEN_ADDR 256 // see also MAXHOSTNAMELEN and RFC 1123 2.1 #define MAX_LEN_PATH 4095 diff --git a/utility/support.cpp b/utility/support.cpp index 736d4c7825..e12aabf70b 100644 --- a/utility/support.cpp +++ b/utility/support.cpp @@ -101,7 +101,7 @@ int fc_strncasecmp(const char *str0, const char *str1, size_t n) { auto left = QString::fromUtf8(str0); auto right = QString::fromUtf8(str1); - return left.leftRef(n).compare(right.leftRef(n), Qt::CaseInsensitive); + return left.left(n).compare(right.left(n), Qt::CaseInsensitive); } /** @@ -218,7 +218,7 @@ int fc_strncasequotecmp(const char *str0, const char *str1, size_t n) && right.endsWith(QLatin1String("\""))) { right = right.mid(1, right.length() - 2); } - return left.leftRef(n).compare(right.leftRef(n), Qt::CaseInsensitive); + return left.left(n).compare(right.left(n), Qt::CaseInsensitive); } /** @@ -267,44 +267,6 @@ FILE *fc_fopen(const char *filename, const char *opentype) #endif // FREECIV_MSWINDOWS } -/** - Wrapper function for remove() with filename conversion to local - encoding on Windows. - */ -int fc_remove(const char *filename) -{ -#ifdef FREECIV_MSWINDOWS - int result; - char *filename_in_local_encoding = - internal_to_local_string_malloc(filename); - - result = remove(filename_in_local_encoding); - free(filename_in_local_encoding); - return result; -#else // FREECIV_MSWINDOWS - return remove(filename); -#endif // FREECIV_MSWINDOWS -} - -/** - Wrapper function for stat() with filename conversion to local - encoding on Windows. - */ -int fc_stat(const char *filename, struct stat *buf) -{ -#ifdef FREECIV_MSWINDOWS - int result; - char *filename_in_local_encoding = - internal_to_local_string_malloc(filename); - - result = stat(filename_in_local_encoding, buf); - free(filename_in_local_encoding); - return result; -#else // FREECIV_MSWINDOWS - return stat(filename, buf); -#endif // FREECIV_MSWINDOWS -} - /** Returns last error code. */ @@ -423,7 +385,7 @@ size_t fc_strlcpy(char *dest, const char *src, size_t n) size_t cut_at = n - 1; QByteArray encoded; do { - encoded = source.leftRef(cut_at--).toUtf8(); + encoded = source.left(cut_at--).toUtf8(); } while (cut_at > 0 && encoded.size() + 1 > n); if (cut_at == 0) { diff --git a/utility/support.h b/utility/support.h index 445b428544..4b222ef541 100644 --- a/utility/support.h +++ b/utility/support.h @@ -123,8 +123,6 @@ int fc_strcoll(const char *str0, const char *str1); int fc_stricoll(const char *str0, const char *str1); FILE *fc_fopen(const char *filename, const char *opentype); -int fc_remove(const char *filename); -int fc_stat(const char *filename, struct stat *buf); fc_errno fc_get_errno(); const char *fc_strerror(fc_errno err); diff --git a/utility/tests/CMakeLists.txt b/utility/tests/CMakeLists.txt index 2a25ad5537..1ef52e7e9e 100644 --- a/utility/tests/CMakeLists.txt +++ b/utility/tests/CMakeLists.txt @@ -1,5 +1,5 @@ set(CMAKE_AUTOMOC ON) add_executable(test_utility_paths test_paths.cpp) -target_link_libraries(test_utility_paths PRIVATE Qt5::Test utility) +target_link_libraries(test_utility_paths PRIVATE Qt6::Test utility) add_test(NAME test_utility_paths COMMAND test_utility_paths) diff --git a/utility/version.cpp b/utility/version.cpp index e815e6414d..f72c3d3c9c 100644 --- a/utility/version.cpp +++ b/utility/version.cpp @@ -40,30 +40,3 @@ const char *freeciv_name_version() return msgbuf; } - -/** - Return string describing version type. - */ -const char *word_version() { return _("version "); } - -/** - Returns version string that can be used to compare two freeciv builds. - This does not handle git revisions, as there's no way to compare - which of the two commits is "higher". - */ -const char *fc_comparable_version() { return freeciv21_version(); } - -/** - Return version string in a format suitable to be written to created - datafiles as human readable information. - */ -const char *freeciv_datafile_version() -{ - static char buf[500] = {'\0'}; - - if (buf[0] == '\0') { - fc_snprintf(buf, sizeof(buf), "%s", freeciv21_version()); - } - - return buf; -} diff --git a/utility/version.h b/utility/version.h index b34df2157e..17db52af7e 100644 --- a/utility/version.h +++ b/utility/version.h @@ -15,6 +15,3 @@ // version informational strings const char *freeciv21_version(); const char *freeciv_name_version(); -const char *word_version(); -const char *fc_comparable_version(); -const char *freeciv_datafile_version();