From e353f4968b6a091a76ffd84ecf8e2ce12d5243de Mon Sep 17 00:00:00 2001 From: tooomm Date: Sat, 6 Jun 2026 16:51:45 +0200 Subject: [PATCH 01/17] split sign+notarize into own script --- .ci/sign_macos_bundle.sh | 76 +++++++++++++++++++++++++++++ .github/workflows/desktop-build.yml | 47 +++--------------- 2 files changed, 83 insertions(+), 40 deletions(-) create mode 100755 .ci/sign_macos_bundle.sh diff --git a/.ci/sign_macos_bundle.sh b/.ci/sign_macos_bundle.sh new file mode 100755 index 000000000..cf673771c --- /dev/null +++ b/.ci/sign_macos_bundle.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +# This script is to be used by the ci environment. + +# Signs and notarizes a macOS app bundle +# Requires: $1 - path to the app bundle +# Environment variables: +# - MACOS_CERTIFICATE_NAME: Name of the certificate for signing (optional, skips signing if not set) +# - MACOS_CI_KEYCHAIN_PWD: Password for the CI keychain (required if MACOS_CERTIFICATE_NAME is set) +# - MACOS_NOTARIZATION_APPLE_ID: Apple ID for notarization (optional, skips notarization if not set) +# - MACOS_NOTARIZATION_PWD: Password for notarization (required if MACOS_NOTARIZATION_APPLE_ID is set) +# - MACOS_NOTARIZATION_TEAM_ID: Team ID for notarization (required if MACOS_NOTARIZATION_APPLE_ID is set) +# exitcode: 1 for failure, 2 for invalid arguments + +set -e + +# Check input arguments +if [[ $# -lt 1 ]]; then + echo "::error file=$0::No argument passed to the script - provide " + exit 2 +fi + +APP_BUNDLE_PATH="$1" + +# Verify that the app bundle exists +if [[ ! -e "$APP_BUNDLE_PATH" ]]; then + echo "::error file=$0::App bundle not found at: $APP_BUNDLE_PATH" +fi + +# Sign the app bundle +if [[ -n "$MACOS_CERTIFICATE_NAME" ]]; then + echo "::group::Sign app bundle" + security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + /usr/bin/codesign --sign="$MACOS_CERTIFICATE_NAME" --entitlements=".ci/macos.entitlements" --options=runtime --force --deep --timestamp --verbose "$APP_BUNDLE_PATH" + echo "::endgroup::" +else + echo "::error file=$0::MACOS_CERTIFICATE_NAME not set. Can not sign the app bundle." + exit 1 +fi + +# Notarize the app bundle +if [[ -n "$MACOS_NOTARIZATION_APPLE_ID" ]]; then + echo "::group::Notarize app bundle" + # Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI + xcrun notarytool store-credentials "notarytool-profile" --apple-id "$MACOS_NOTARIZATION_APPLE_ID" --team-id "$MACOS_NOTARIZATION_TEAM_ID" --password "$MACOS_NOTARIZATION_PWD" + + # We can't notarize an app bundle directly, but we need to compress it as an archive. + # Therefore, we create a zip file containing our app bundle, so that we can send it to the notarization service + echo "" + echo "Creating temp notarization archive" + ditto -c -k --keepParent "$APP_BUNDLE_PATH" "notarization.zip" + + # Here we send the notarization request to the Apple's Notarization service, waiting for the result. + # This typically takes a few seconds inside a CI environment, but it might take more depending on the App characteristics. + # Visit the Notarization docs for more information and strategies on how to optimize it if you're curious. + echo "" + xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait + echo "::endgroup::" + + echo "::group::Staple app" + # Finally, we need to "attach the staple" to our executable, which will allow our app to be + # validated by macOS even when an internet connection is not available. + echo "Attach staple" + xcrun stapler staple "$APP_BUNDLE_PATH" + echo "::endgroup::" + + echo "::group::Cleanup" + # Cleanup keychain and files to avoid leaking credentials + echo "Deleting keychain" + security delete-keychain build.keychain + rm -f certificate.p12 notarization.zip + echo "::endgroup::" +else + echo "::error file=$0::MACOS_NOTARIZATION_APPLE_ID not set. Can not notarize the app bundle." + exit 1 +fi diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index 62108b34a..c6557c54d 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -446,8 +446,8 @@ jobs: VCPKG_BINARY_SOURCES: 'clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite' # macOS-specific environment variables, will be ignored on Windows MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }} - MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} + MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} DEVELOPER_DIR: '/Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer' TARGET_MACOS_VERSION: ${{ matrix.override_target }} @@ -472,50 +472,17 @@ jobs: path: ${{env.CCACHE_DIR}} key: ${{ steps.ccache_restore.outputs.cache-primary-key }} - - name: Sign app bundle - if: matrix.os == 'macOS' && matrix.make_package && needs.configure.outputs.tag != null - id: sign_macos + - name: Sign & notarize app bundle + # if: matrix.os == 'macOS' && matrix.make_package && needs.configure.outputs.tag != null + if: matrix.os == 'macOS' + shell: bash env: MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} - run: | - if [[ -n "$MACOS_CERTIFICATE_NAME" ]] - then - security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain - /usr/bin/codesign --sign="$MACOS_CERTIFICATE_NAME" --entitlements=".ci/macos.entitlements" --options=runtime --force --deep --timestamp --verbose "${{steps.build.outputs.path}}" - fi - - - name: Notarize app bundle - if: steps.sign_macos.outcome == 'success' - env: MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }} - MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }} MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }} - run: | - if [[ -n "$MACOS_NOTARIZATION_APPLE_ID" ]] - then - # Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI - echo "Create keychain profile" - xcrun notarytool store-credentials "notarytool-profile" --apple-id "$MACOS_NOTARIZATION_APPLE_ID" --team-id "$MACOS_NOTARIZATION_TEAM_ID" --password "$MACOS_NOTARIZATION_PWD" - - # We can't notarize an app bundle directly, but we need to compress it as an archive. - # Therefore, we create a zip file containing our app bundle, so that we can send it to the - # notarization service - echo "Creating temp notarization archive" - ditto -c -k --keepParent "${{steps.build.outputs.path}}" "notarization.zip" - - # Here we send the notarization request to the Apple's Notarization service, waiting for the result. - # This typically takes a few seconds inside a CI environment, but it might take more depending on the App - # characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if - # you're curious - echo "Notarize app" - xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait - - # Finally, we need to "attach the staple" to our executable, which will allow our app to be - # validated by macOS even when an internet connection is not available. - echo "Attach staple" - xcrun stapler staple "${{steps.build.outputs.path}}" - fi + MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }} + run: .ci/sign_macos_bundle.sh "${{ steps.build.outputs.path }}" - name: Upload artifact if: matrix.make_package From 6f7c5d7788c1ef0eacf84fc12ea83bff31d23f04 Mon Sep 17 00:00:00 2001 From: tooomm Date: Sat, 6 Jun 2026 22:28:38 +0200 Subject: [PATCH 02/17] move cert import too --- .ci/compile.sh | 15 ---------- .ci/sign_macos_bundle.sh | 43 ++++++++++++++++++++--------- .github/workflows/desktop-build.yml | 6 ++-- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/.ci/compile.sh b/.ci/compile.sh index ee846897b..19777aa94 100755 --- a/.ci/compile.sh +++ b/.ci/compile.sh @@ -218,21 +218,6 @@ if [[ $RUNNER_OS == macOS ]]; then echo "::endgroup::" fi - echo "::group::Signing Certificate" - if [[ -n "$MACOS_CERTIFICATE_NAME" ]]; then - echo "$MACOS_CERTIFICATE" | base64 --decode >"certificate.p12" - security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain - security default-keychain -s build.keychain - security set-keychain-settings -t 3600 -l build.keychain - security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain - security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign - security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain - echo "macOS signing certificate successfully imported and keychain configured." - else - echo "No signing certificate configured. Skipping set up of keychain in macOS environment." - fi - echo "::endgroup::" - if [[ $MAKE_PACKAGE ]]; then # Workaround https://github.com/actions/runner-images/issues/7522 # have hdiutil repeat the command 10 times in hope of success diff --git a/.ci/sign_macos_bundle.sh b/.ci/sign_macos_bundle.sh index cf673771c..60ac7b3c7 100755 --- a/.ci/sign_macos_bundle.sh +++ b/.ci/sign_macos_bundle.sh @@ -22,23 +22,40 @@ fi APP_BUNDLE_PATH="$1" -# Verify that the app bundle exists +# Verify that app bundle exists if [[ ! -e "$APP_BUNDLE_PATH" ]]; then echo "::error file=$0::App bundle not found at: $APP_BUNDLE_PATH" + exit 1 fi -# Sign the app bundle +# Configure keychain +if [[ -n "$MACOS_CERTIFICATE" ]]; then + echo "::group::Import certificate" + echo "$MACOS_CERTIFICATE" | base64 --decode >"certificate.p12" + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + security default-keychain -s build.keychain + security set-keychain-settings -t 3600 -l build.keychain + security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain + echo "::endgroup::" +else + echo "::error file=$0::MACOS_CERTIFICATE not set. Can not configure keychain." + exit 1 +fi + +# Sign app bundle if [[ -n "$MACOS_CERTIFICATE_NAME" ]]; then echo "::group::Sign app bundle" security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain /usr/bin/codesign --sign="$MACOS_CERTIFICATE_NAME" --entitlements=".ci/macos.entitlements" --options=runtime --force --deep --timestamp --verbose "$APP_BUNDLE_PATH" echo "::endgroup::" else - echo "::error file=$0::MACOS_CERTIFICATE_NAME not set. Can not sign the app bundle." + echo "::error file=$0::MACOS_CERTIFICATE_NAME not set. Can not sign app bundle." exit 1 fi -# Notarize the app bundle +# Notarize app bundle if [[ -n "$MACOS_NOTARIZATION_APPLE_ID" ]]; then echo "::group::Notarize app bundle" # Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI @@ -47,7 +64,7 @@ if [[ -n "$MACOS_NOTARIZATION_APPLE_ID" ]]; then # We can't notarize an app bundle directly, but we need to compress it as an archive. # Therefore, we create a zip file containing our app bundle, so that we can send it to the notarization service echo "" - echo "Creating temp notarization archive" + echo "Creating temp notarization archive..." ditto -c -k --keepParent "$APP_BUNDLE_PATH" "notarization.zip" # Here we send the notarization request to the Apple's Notarization service, waiting for the result. @@ -63,14 +80,14 @@ if [[ -n "$MACOS_NOTARIZATION_APPLE_ID" ]]; then echo "Attach staple" xcrun stapler staple "$APP_BUNDLE_PATH" echo "::endgroup::" - - echo "::group::Cleanup" - # Cleanup keychain and files to avoid leaking credentials - echo "Deleting keychain" - security delete-keychain build.keychain - rm -f certificate.p12 notarization.zip - echo "::endgroup::" else - echo "::error file=$0::MACOS_NOTARIZATION_APPLE_ID not set. Can not notarize the app bundle." + echo "::error file=$0::MACOS_NOTARIZATION_APPLE_ID not set. Can not notarize app bundle." exit 1 fi + +echo "::group::Cleanup" +# Cleanup keychain and files to avoid leaking credentials +echo "Deleting keychain" +security delete-keychain build.keychain +rm -f certificate.p12 notarization.zip +echo "::endgroup::" diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index c6557c54d..acc8266dd 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -445,10 +445,6 @@ jobs: VCPKG_DISABLE_METRICS: 1 VCPKG_BINARY_SOURCES: 'clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite' # macOS-specific environment variables, will be ignored on Windows - MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }} - MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} - MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} - MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} DEVELOPER_DIR: '/Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer' TARGET_MACOS_VERSION: ${{ matrix.override_target }} CCACHE_EVICTION_AGE: ${{ matrix.ccache_eviction_age }} @@ -477,7 +473,9 @@ jobs: if: matrix.os == 'macOS' shell: bash env: + MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }} MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} + MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }} MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }} From e674a39b878d020275a5df6645336d271a4d7952 Mon Sep 17 00:00:00 2001 From: Christo Date: Tue, 9 Jun 2026 13:54:01 +0800 Subject: [PATCH 03/17] Fix #6952: prevent deck loss when saving to a full disk (#6978) * Fix #6952: prevent deck loss when saving to a full disk DeckLoader::saveToFile() opened the target with QFile in WriteOnly mode, which truncates the existing file to 0 bytes the moment it is opened. The serializers (DeckList::saveToFile_Native/_Plain) always return true and the result of flush() was ignored, so a write that failed part-way -- e.g. because the disk was full -- left a 0-byte file behind yet was still reported (and logged) as a successful save. The same truncate-then-write pattern in updateLastLoadedTimestamp() could destroy a deck on load. Switch both paths to QSaveFile, which writes to a temporary file and only atomically replaces the target if commit() succeeds. On any write or flush failure commit() returns false, the original deck is left untouched, and the failure is logged instead of being reported as success. * Use QSaveFile in convertToCockatriceFormat() too convertToCockatriceFormat() had the same data-loss pattern: QFile WriteOnly truncated the .cod, saveToFile_Native() always returns true, and the original file was then removed unconditionally -- so a full disk during conversion wrote a 0-byte .cod and then deleted the source deck. Switch to QSaveFile (write + atomic commit), remove the original only after a successful commit, and move the format check ahead of the file open so an already-Cockatrice or unsupported deck never truncates or deletes anything. Raised in review by ZeldaZach. --- .../src/interface/deck_loader/deck_loader.cpp | 137 ++++++++++-------- 1 file changed, 77 insertions(+), 60 deletions(-) diff --git a/cockatrice/src/interface/deck_loader/deck_loader.cpp b/cockatrice/src/interface/deck_loader/deck_loader.cpp index e616c5eb5..39a0c1071 100644 --- a/cockatrice/src/interface/deck_loader/deck_loader.cpp +++ b/cockatrice/src/interface/deck_loader/deck_loader.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -129,7 +130,10 @@ std::optional DeckLoader::loadFromRemote(const QString &nativeString std::optional DeckLoader::saveToFile(const DeckList &deck, const QString &fileName, DeckFileFormat::Format fmt) { - QFile file(fileName); + // Use QSaveFile so that a failed write (e.g. a full disk) leaves the existing deck untouched + // instead of truncating it to a 0-byte file. The target is only replaced once every byte has + // been flushed successfully in commit(). + QSaveFile file(fileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qCWarning(DeckLoaderLog) << "Could not create or open file:" << fileName; return std::nullopt; @@ -145,15 +149,19 @@ DeckLoader::saveToFile(const DeckList &deck, const QString &fileName, DeckFileFo break; } - file.flush(); - file.close(); - - qCInfo(DeckLoaderLog) << "Saved deck to " << fileName << "with format" << fmt << "-" << success; - if (!success) { + file.cancelWriting(); + qCWarning(DeckLoaderLog) << "Failed to serialize deck for file:" << fileName; return std::nullopt; } + if (!file.commit()) { + qCWarning(DeckLoaderLog) << "Failed to save deck to " << fileName << ":" << file.errorString(); + return std::nullopt; + } + + qCInfo(DeckLoaderLog) << "Saved deck to " << fileName << "with format" << fmt; + LoadedDeck::LoadInfo lastLoadInfo = {fileName, fmt}; return lastLoadInfo; } @@ -196,38 +204,44 @@ bool DeckLoader::updateLastLoadedTimestamp(LoadedDeck &deck) QDateTime originalTimestamp = fileInfo.lastModified(); - // Open the file for writing - QFile file(fileName); + // Use QSaveFile so that a failed write (e.g. a full disk) cannot truncate an existing deck to a + // 0-byte file while merely bumping its timestamp. + QSaveFile file(fileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qCWarning(DeckLoaderLog) << "Failed to open file for writing:" << fileName; return false; } - bool result = false; - // Perform file modifications deck.deckList.setLastLoadedTimestamp(QDateTime::currentDateTime().toString()); - result = deck.deckList.saveToFile_Native(&file); - file.close(); // Close the file to ensure changes are flushed - - if (result) { - // Re-open the file and set the original timestamp - if (!file.open(QIODevice::ReadWrite)) { - qCWarning(DeckLoaderLog) << "Failed to re-open file to set timestamp:" << fileName; - return false; - } - - if (!file.setFileTime(originalTimestamp, QFileDevice::FileModificationTime)) { - qCWarning(DeckLoaderLog) << "Failed to set modification time for file:" << fileName; - file.close(); - return false; - } - - file.close(); + if (!deck.deckList.saveToFile_Native(&file)) { + file.cancelWriting(); + qCWarning(DeckLoaderLog) << "Failed to serialize deck for file:" << fileName; + return false; } - return result; + if (!file.commit()) { + qCWarning(DeckLoaderLog) << "Failed to update timestamp for file:" << fileName << ":" << file.errorString(); + return false; + } + + // Re-open the file and restore the original timestamp, so that updating the lastLoadedTimestamp + // does not change the file's modification time. + QFile timestampFile(fileName); + if (!timestampFile.open(QIODevice::ReadWrite)) { + qCWarning(DeckLoaderLog) << "Failed to re-open file to set timestamp:" << fileName; + return false; + } + + if (!timestampFile.setFileTime(originalTimestamp, QFileDevice::FileModificationTime)) { + qCWarning(DeckLoaderLog) << "Failed to set modification time for file:" << fileName; + timestampFile.close(); + return false; + } + + timestampFile.close(); + return true; } static QString getDomainForWebsite(DeckLoader::DecklistWebsite website) @@ -444,51 +458,54 @@ bool DeckLoader::convertToCockatriceFormat(LoadedDeck &deck) return false; } + // Determine the format before touching any file, so an already-converted or + // unsupported deck never truncates or deletes anything. + switch (DeckFileFormat::getFormatFromName(fileName)) { + case DeckFileFormat::PlainText: + break; + case DeckFileFormat::Cockatrice: + qCInfo(DeckLoaderLog) << "File is already in Cockatrice format. No conversion needed."; + return true; + default: + qCWarning(DeckLoaderLog) << "Unsupported file format for conversion:" << fileName; + return false; + } + // Change the file extension to .cod QFileInfo fileInfo(fileName); QString newFileName = QDir::toNativeSeparators(fileInfo.path() + "/" + fileInfo.completeBaseName() + ".cod"); - // Open the new file for writing - QFile file(newFileName); + // Use QSaveFile so a failed write (e.g. a full disk) cannot leave a 0-byte .cod + // behind and then delete the original deck. + QSaveFile file(newFileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qCWarning(DeckLoaderLog) << "Failed to open file for writing:" << newFileName; return false; } - bool result = false; - - // Perform file modifications based on the detected format - switch (DeckFileFormat::getFormatFromName(fileName)) { - case DeckFileFormat::PlainText: - // Save in Cockatrice's native format - result = deck.deckList.saveToFile_Native(&file); - break; - case DeckFileFormat::Cockatrice: - qCInfo(DeckLoaderLog) << "File is already in Cockatrice format. No conversion needed."; - result = true; - break; - default: - qCWarning(DeckLoaderLog) << "Unsupported file format for conversion:" << fileName; - result = false; - break; + if (!deck.deckList.saveToFile_Native(&file)) { + file.cancelWriting(); + qCWarning(DeckLoaderLog) << "Failed to serialize deck for file:" << newFileName; + return false; } - file.close(); - - // Delete the old file if conversion was successful - if (result) { - if (!QFile::remove(fileName)) { - qCWarning(DeckLoaderLog) << "Failed to delete original file:" << fileName; - } else { - qCInfo(DeckLoaderLog) << "Original file deleted successfully:" << fileName; - } - deck.lastLoadInfo = { - .fileName = newFileName, - .fileFormat = DeckFileFormat::Cockatrice, - }; + if (!file.commit()) { + qCWarning(DeckLoaderLog) << "Failed to convert deck to " << newFileName << ":" << file.errorString(); + return false; } - return result; + // Conversion succeeded: delete the original file. + if (!QFile::remove(fileName)) { + qCWarning(DeckLoaderLog) << "Failed to delete original file:" << fileName; + } else { + qCInfo(DeckLoaderLog) << "Original file deleted successfully:" << fileName; + } + deck.lastLoadInfo = { + .fileName = newFileName, + .fileFormat = DeckFileFormat::Cockatrice, + }; + + return true; } void DeckLoader::printDeckListNode(QTextCursor *cursor, const InnerDecklistNode *node) From 9e03f826165604f89c033fc368c3412652ff92f0 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Tue, 9 Jun 2026 08:05:39 +0200 Subject: [PATCH 04/17] [Game][Player] Split Player into PlayerLogic/PlayerGraphicsItem (#6944) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Game][Player] Split Player into PlayerLogic/PlayerGraphicsItem Took 4 minutes Took 48 seconds * Drop early return. Took 1 hour 13 minutes Took 2 minutes Took 1 minute * Delete player view. Took 37 seconds * Restore card counter color in menu. Took 5 minutes --------- Co-authored-by: Lukas Brübach --- .../src/game/board/abstract_card_item.h | 5 + cockatrice/src/game/board/card_item.cpp | 39 ++-- cockatrice/src/game/game_scene.cpp | 101 ++++++++++- cockatrice/src/game/game_scene.h | 15 ++ cockatrice/src/game/player/menu/card_menu.cpp | 133 +++++++------- cockatrice/src/game/player/menu/card_menu.h | 9 +- .../src/game/player/menu/custom_zone_menu.cpp | 10 +- .../src/game/player/menu/custom_zone_menu.h | 6 +- cockatrice/src/game/player/menu/move_menu.cpp | 27 ++- cockatrice/src/game/player/menu/move_menu.h | 4 +- .../src/game/player/menu/player_menu.cpp | 50 +++--- cockatrice/src/game/player/menu/player_menu.h | 13 +- cockatrice/src/game/player/menu/pt_menu.cpp | 34 ++-- cockatrice/src/game/player/menu/pt_menu.h | 4 +- .../src/game/player/menu/utility_menu.cpp | 40 +++-- .../src/game/player/menu/utility_menu.h | 10 +- cockatrice/src/game/player/player_actions.cpp | 167 +++++++++--------- cockatrice/src/game/player/player_actions.h | 66 ++++--- .../src/game/player/player_event_handler.cpp | 13 +- .../src/game/player/player_event_handler.h | 1 + .../src/game/player/player_graphics_item.cpp | 31 ++-- .../src/game/player/player_graphics_item.h | 10 +- cockatrice/src/game/player/player_logic.cpp | 23 +-- cockatrice/src/game/player/player_logic.h | 18 +- .../src/game_graphics/zones/table_zone.cpp | 15 +- .../src/game_graphics/zones/table_zone.h | 4 +- .../src/interface/widgets/tabs/tab_game.cpp | 56 +++--- .../src/interface/widgets/tabs/tab_game.h | 2 +- 28 files changed, 538 insertions(+), 368 deletions(-) diff --git a/cockatrice/src/game/board/abstract_card_item.h b/cockatrice/src/game/board/abstract_card_item.h index ed545e1ab..863954b73 100644 --- a/cockatrice/src/game/board/abstract_card_item.h +++ b/cockatrice/src/game/board/abstract_card_item.h @@ -44,6 +44,11 @@ signals: void deleteCardInfoPopup(QString cardName); void sigPixmapUpdated(); void cardShiftClicked(QString cardName); + void rightClicked(AbstractCardItem *card, QPoint screenPos); + void playSelected(AbstractCardItem *card); + void playSelectedFaceDown(AbstractCardItem *card); + void hideSelected(AbstractCardItem *card); + void selectionChanged(AbstractCardItem *card, bool selected); public: enum diff --git a/cockatrice/src/game/board/card_item.cpp b/cockatrice/src/game/board/card_item.cpp index a08194540..16197ae16 100644 --- a/cockatrice/src/game/board/card_item.cpp +++ b/cockatrice/src/game/board/card_item.cpp @@ -40,7 +40,7 @@ void CardItem::prepareDelete() { if (owner != nullptr) { if (owner->getGame()->getActiveCard() == this) { - owner->getPlayerMenu()->updateCardMenu(nullptr); + emit owner->requestCardMenuUpdate(nullptr); owner->getGame()->setActiveCard(nullptr); } owner = nullptr; @@ -399,8 +399,11 @@ void CardItem::playCard(bool faceDown) emit tz->toggleTapped(); } else { if (SettingsCache::instance().getClickPlaysAllSelected()) { - faceDown ? state->getZone()->getPlayer()->getPlayerActions()->actPlayFacedown() - : state->getZone()->getPlayer()->getPlayerActions()->actPlay(); + if (faceDown) { + emit playSelectedFaceDown(this); + } else { + emit playSelected(this); + } } else { state->getZone()->getPlayer()->getPlayerActions()->playCard(this, faceDown); } @@ -460,7 +463,7 @@ void CardItem::handleClickedToPlay(bool shiftHeld) { if (isUnwritableRevealZone(state->getZone())) { if (SettingsCache::instance().getClickPlaysAllSelected()) { - state->getZone()->getPlayer()->getPlayerActions()->actHide(); + emit hideSelected(this); } else { state->getZone()->removeCard(this); } @@ -471,17 +474,11 @@ void CardItem::handleClickedToPlay(bool shiftHeld) void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { - if (event->button() == Qt::RightButton) { - - if (owner != nullptr) { - owner->getGame()->setActiveCard(this); - if (QMenu *cardMenu = owner->getPlayerMenu()->updateCardMenu(this)) { - cardMenu->popup(event->screenPos()); - return; - } - } - } else if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) && - (!SettingsCache::instance().getDoubleClickToPlay())) { + if (event->button() == Qt::RightButton && owner != nullptr) { + emit rightClicked(this, event->screenPos()); + } + if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) && + (!SettingsCache::instance().getDoubleClickToPlay())) { handleClickedToPlay(event->modifiers().testFlag(Qt::ShiftModifier)); } @@ -531,14 +528,14 @@ bool CardItem::animationEvent() QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value) { if ((change == ItemSelectedHasChanged) && owner != nullptr) { - if (value == true) { - owner->getGame()->setActiveCard(this); - owner->getPlayerMenu()->updateCardMenu(this); - } else if (owner->getGameScene()->selectedItems().isEmpty()) { + bool selected = value.toBool(); - owner->getGame()->setActiveCard(nullptr); - owner->getPlayerMenu()->updateCardMenu(nullptr); + if (selected) { + owner->getGame()->setActiveCard(this); } + + emit selectionChanged(this, selected); } + return AbstractCardItem::itemChange(change, value); } diff --git a/cockatrice/src/game/game_scene.cpp b/cockatrice/src/game/game_scene.cpp index 867869a3f..dc55ecfe9 100644 --- a/cockatrice/src/game/game_scene.cpp +++ b/cockatrice/src/game/game_scene.cpp @@ -4,8 +4,10 @@ #include "../game_graphics/zones/select_zone.h" #include "../game_graphics/zones/view_zone.h" #include "../game_graphics/zones/view_zone_widget.h" +#include "abstract_game.h" #include "board/card_item.h" #include "phases_toolbar.h" +#include "player/player_actions.h" #include "player/player_graphics_item.h" #include "player/player_logic.h" @@ -72,6 +74,80 @@ QList GameScene::selectedCards() const return selectedCards; } +void GameScene::onCardSelectionChanged(AbstractCardItem *abstractCard, bool selected) +{ + CardItem *card = qobject_cast(abstractCard); + if (!card || !card->getOwner()) { + return; + } + + auto *owner = card->getOwner(); + + if (selected) { + owner->requestCardMenuUpdate(card); + return; + } + + if (selectedItems().isEmpty()) { + owner->getGame()->setActiveCard(nullptr); + owner->requestCardMenuUpdate(nullptr); + } +} + +void GameScene::onCardRightClicked(AbstractCardItem *abstractCard, QPoint screenPos) +{ + auto *card = qobject_cast(abstractCard); + if (!card) { + return; + } + if (!card->getOwner()) { + return; + } + auto *view = playerViews.value(card->getOwner()->getPlayerInfo()->getId()); + if (!view) { + return; + } + + card->getOwner()->getGame()->setActiveCard(card); + + if (auto *menu = view->getPlayerMenu()->updateCardMenu(card)) { + menu->popup(screenPos); + } +} + +void GameScene::playSelected(AbstractCardItem *card) +{ + if (!card) { + return; + } + if (!card->getOwner()) { + return; + } + card->getOwner()->getPlayerActions()->actPlay(selectedCards()); +} + +void GameScene::playSelectedFaceDown(AbstractCardItem *card) +{ + if (!card) { + return; + } + if (!card->getOwner()) { + return; + } + card->getOwner()->getPlayerActions()->actPlayFacedown(selectedCards()); +} + +void GameScene::hideSelected(AbstractCardItem *card) +{ + if (!card) { + return; + } + if (!card->getOwner()) { + return; + } + card->getOwner()->getPlayerActions()->actHide(selectedCards()); +} + /** * @brief Adds a player to the scene and stores their graphics item. * @param player Player to add. @@ -82,9 +158,11 @@ void GameScene::addPlayer(PlayerLogic *player) { qCInfo(GameScenePlayerAdditionRemovalLog) << "GameScene::addPlayer name=" << player->getPlayerInfo()->getName(); - playerViews.insert(player->getPlayerInfo()->getId(), player->getGraphicsItem()); - addItem(player->getGraphicsItem()); - connect(player->getGraphicsItem(), &PlayerGraphicsItem::sizeChanged, this, &GameScene::rearrange); + auto *view = new PlayerGraphicsItem(player); + + playerViews.insert(player->getPlayerInfo()->getId(), view); + addItem(view); + connect(view, &PlayerGraphicsItem::sizeChanged, this, &GameScene::rearrange); connect(player, &PlayerLogic::concededChanged, this, [this](int id, bool conceded) { if (conceded) { @@ -93,6 +171,8 @@ void GameScene::addPlayer(PlayerLogic *player) rearrange(); }); + connect(player, &PlayerLogic::requestZoneViewToggle, this, &GameScene::toggleZoneView); + connect(player, &PlayerLogic::requestRevealedZoneView, this, &GameScene::addRevealedZoneView); connect(player, &PlayerLogic::arrowDeleted, this, &GameScene::deleteArrow); connect(player, &PlayerLogic::arrowCreateRequested, this, &GameScene::addArrow); connect(player, &PlayerLogic::arrowDeleteRequested, this, &GameScene::requestArrowDeletion); @@ -123,6 +203,7 @@ void GameScene::removePlayer(PlayerLogic *player) } auto *view = playerViews.take(player->getPlayerInfo()->getId()); removeItem(view); + view->deleteLater(); rearrange(); } @@ -204,7 +285,7 @@ QList GameScene::collectActivePlayers(int &firstPlayerIndex) cons bool firstPlayerFound = false; for (auto *pgItem : playerViews.values()) { - PlayerLogic *p = pgItem->getPlayer(); + PlayerLogic *p = pgItem->getLogic(); if (p && !p->getConceded()) { activePlayers.append(p); if (!firstPlayerFound && p->getPlayerInfo()->getLocal()) { @@ -275,12 +356,12 @@ QSizeF GameScene::computeSceneSizeAndPlayerLayout(const QList &pl for (int j = 0; j < rowsInColumn; ++j) { PlayerLogic *player = playersIter.next(); if (col == 0) { - playersByColumn[col].prepend(player->getGraphicsItem()); + playersByColumn[col].prepend(playerViews.value(player->getPlayerInfo()->getId())); } else { - playersByColumn[col].append(player->getGraphicsItem()); + playersByColumn[col].append(playerViews.value(player->getPlayerInfo()->getId())); } - auto *pgItem = player->getGraphicsItem(); + auto *pgItem = playerViews.value(player->getPlayerInfo()->getId()); thisColumnHeight += pgItem->boundingRect().height() + playerAreaSpacing; columnWidth[col] = std::max(columnWidth[col], (int)pgItem->boundingRect().width()); } @@ -375,7 +456,8 @@ void GameScene::addArrow(QSharedPointer data) return; } - auto *startZone = startView->getPlayer()->getZones().value(data->startZone); + PlayerLogic *startLogic = startView->getLogic(); + auto *startZone = startLogic->getZones().value(data->startZone); if (!startZone) { return; } @@ -389,7 +471,8 @@ void GameScene::addArrow(QSharedPointer data) if (data->isPlayerTargeted()) { targetItem = targetView->getPlayerTarget(); } else { - if (auto *zone = targetView->getPlayer()->getZones().value(data->targetZone)) { + auto *zone = targetView->getLogic()->getZones().value(data->targetZone); + if (zone) { targetItem = zone->getCard(data->targetCardId); } } diff --git a/cockatrice/src/game/game_scene.h b/cockatrice/src/game/game_scene.h index 567089fc0..0587566d0 100644 --- a/cockatrice/src/game/game_scene.h +++ b/cockatrice/src/game/game_scene.h @@ -97,6 +97,16 @@ public: */ void removePlayer(PlayerLogic *player); + QMap getPlayers() const + { + return playerViews; + } + + PlayerGraphicsItem *viewForPlayer(int playerId) + { + return playerViews.value(playerId); + } + /** * @brief Adjusts the global rotation offset for player layout. * @param rotationAdjustment Number of positions to rotate. @@ -182,6 +192,11 @@ public: void stopRubberBand(); public slots: + void onCardSelectionChanged(AbstractCardItem *card, bool selected); + void onCardRightClicked(AbstractCardItem *card, QPoint screenPos); + void playSelected(AbstractCardItem *card); + void playSelectedFaceDown(AbstractCardItem *card); + void hideSelected(AbstractCardItem *card); /** @brief Toggles a zone view for a player. */ void toggleZoneView(PlayerLogic *player, const QString &zoneName, int numberCards, bool isReversed = false); diff --git a/cockatrice/src/game/player/menu/card_menu.cpp b/cockatrice/src/game/player/menu/card_menu.cpp index 3b866d4e0..ba925afb0 100644 --- a/cockatrice/src/game/player/menu/card_menu.cpp +++ b/cockatrice/src/game/player/menu/card_menu.cpp @@ -31,93 +31,92 @@ static QIcon createCircleIcon(const QColor &color) return QIcon(pixmap); } -CardMenu::CardMenu(PlayerLogic *_player, const CardItem *_card, bool _shortcutsActive) +template +static QAction *makeAction(QObject *parent, Slot &&slot, bool checkable = false, bool checked = false) +{ + auto *a = new QAction(parent); + a->setCheckable(checkable); + if (checkable) { + a->setChecked(checked); + } + QObject::connect(a, &QAction::triggered, parent, std::forward(slot)); + return a; +} + +CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _shortcutsActive) : player(_player), card(_card), shortcutsActive(_shortcutsActive) { - auto playerActions = player->getPlayerActions(); - - const QList &players = player->getGame()->getPlayerManager()->getPlayers().values(); + const QList &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); for (auto playerToAdd : players) { - if (playerToAdd == player) { + if (playerToAdd == player->getLogic()) { continue; } playersInfo.append(qMakePair(playerToAdd->getPlayerInfo()->getName(), playerToAdd->getPlayerInfo()->getId())); } - connect(player->getGame()->getPlayerManager(), &PlayerManager::playerRemoved, this, &CardMenu::removePlayer); + connect(player->getLogic()->getGame()->getPlayerManager(), &PlayerManager::playerRemoved, this, + &CardMenu::removePlayer); - aTap = new QAction(this); - aTap->setData(cmTap); - connect(aTap, &QAction::triggered, playerActions, &PlayerActions::cardMenuAction); - aDoesntUntap = new QAction(this); - aDoesntUntap->setData(cmDoesntUntap); - aDoesntUntap->setCheckable(true); - aDoesntUntap->setChecked(card != nullptr && card->getDoesntUntap()); - connect(aDoesntUntap, &QAction::triggered, playerActions, &PlayerActions::cardMenuAction); + auto *actions = player->getLogic()->getPlayerActions(); + auto *gameScene = player->getGameScene(); + + // Single selection resolver used by all lambdas — called at trigger time + auto sel = [gameScene]() { return gameScene->selectedCards(); }; + + // Unified dispatcher for card menu actions + auto invoke = [actions, sel](CardMenuActionType type) { + return [actions, sel, type]() { actions->cardMenuAction(sel(), type); }; + }; + + // Actions using invoke (type dispatch, need selection) + aTap = makeAction(this, invoke(cmTap)); + aDoesntUntap = makeAction(this, invoke(cmDoesntUntap), /*checkable=*/true, card && card->getDoesntUntap()); + aFlip = makeAction(this, invoke(cmFlip)); + aPeek = makeAction(this, invoke(cmPeek)); + aClone = makeAction(this, invoke(cmClone)); + + // Actions using selection directly + aUnattach = makeAction(this, [actions, sel]() { actions->actUnattach(sel()); }); + aSetAnnotation = makeAction(this, [actions, sel]() { actions->actSetAnnotation(sel()); }); + aPlay = makeAction(this, [actions, sel]() { actions->actPlay(sel()); }); + aPlayFacedown = makeAction(this, [actions, sel]() { actions->actPlayFacedown(sel()); }); + aHide = makeAction(this, [actions, sel]() { actions->actHide(sel()); }); + aReduceLifeByPower = makeAction(this, [actions, sel]() { actions->actReduceLifeByPower(sel()); }); + + // Actions that use activeCard, not selection — direct connection aAttach = new QAction(this); - connect(aAttach, &QAction::triggered, playerActions, &PlayerActions::actAttach); - aUnattach = new QAction(this); - connect(aUnattach, &QAction::triggered, playerActions, &PlayerActions::actUnattach); aDrawArrow = new QAction(this); - connect(aDrawArrow, &QAction::triggered, playerActions, &PlayerActions::actDrawArrow); - aSetAnnotation = new QAction(this); - connect(aSetAnnotation, &QAction::triggered, playerActions, &PlayerActions::actSetAnnotation); - aFlip = new QAction(this); - aFlip->setData(cmFlip); - connect(aFlip, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); - aPeek = new QAction(this); - aPeek->setData(cmPeek); - connect(aPeek, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); - aClone = new QAction(this); - aClone->setData(cmClone); - connect(aClone, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); aSelectAll = new QAction(this); - connect(aSelectAll, &QAction::triggered, playerActions, &PlayerActions::actSelectAll); aSelectRow = new QAction(this); - connect(aSelectRow, &QAction::triggered, playerActions, &PlayerActions::actSelectRow); aSelectColumn = new QAction(this); - connect(aSelectColumn, &QAction::triggered, playerActions, &PlayerActions::actSelectColumn); - aReduceLifeByPower = new QAction(this); - connect(aReduceLifeByPower, &QAction::triggered, playerActions, &PlayerActions::actReduceLifeByPower); - - aPlay = new QAction(this); - connect(aPlay, &QAction::triggered, playerActions, &PlayerActions::actPlay); - aHide = new QAction(this); - connect(aHide, &QAction::triggered, playerActions, &PlayerActions::actHide); - aPlayFacedown = new QAction(this); - connect(aPlayFacedown, &QAction::triggered, playerActions, &PlayerActions::actPlayFacedown); + connect(aAttach, &QAction::triggered, actions, &PlayerActions::actAttach); + connect(aDrawArrow, &QAction::triggered, actions, &PlayerActions::actDrawArrow); + connect(aSelectAll, &QAction::triggered, actions, &PlayerActions::actSelectAll); + connect(aSelectRow, &QAction::triggered, actions, &PlayerActions::actSelectRow); + connect(aSelectColumn, &QAction::triggered, actions, &PlayerActions::actSelectColumn); aRevealToAll = new QAction(this); mCardCounters = new QMenu; + // Card counters for (int i = 0; i < 6; ++i) { QColor color = SettingsCache::instance().cardCounters().color(i); QIcon circleIcon = createCircleIcon(color); - auto *tempAddCounter = new QAction(this); - tempAddCounter->setIconVisibleInMenu(true); - tempAddCounter->setIcon(circleIcon); + auto *addAction = makeAction(this, [actions, sel, i]() { actions->actAddCardCounter(sel(), i); }); + addAction->setIcon(circleIcon); + aAddCounter.append(addAction); - auto *tempRemoveCounter = new QAction(this); - tempRemoveCounter->setIconVisibleInMenu(true); - tempRemoveCounter->setIcon(circleIcon); + auto *removeAction = makeAction(this, [actions, sel, i]() { actions->actRemoveCardCounter(sel(), i); }); + removeAction->setIcon(circleIcon); + aRemoveCounter.append(removeAction); - auto *tempSetCounter = new QAction(this); - tempSetCounter->setIconVisibleInMenu(true); - tempSetCounter->setIcon(circleIcon); - - aAddCounter.append(tempAddCounter); - aRemoveCounter.append(tempRemoveCounter); - aSetCounter.append(tempSetCounter); - connect(tempAddCounter, &QAction::triggered, playerActions, - [playerActions, i] { playerActions->actAddCardCounter(i); }); - connect(tempRemoveCounter, &QAction::triggered, playerActions, - [playerActions, i] { playerActions->actRemoveCardCounter(i); }); - connect(tempSetCounter, &QAction::triggered, playerActions, - [playerActions, i] { playerActions->actSetCardCounter(i); }); + auto *setAction = makeAction(this, [actions, sel, i]() { actions->actSetCardCounter(sel(), i); }); + setAction->setIcon(circleIcon); + aSetCounter.append(setAction); } setShortcutsActive(); @@ -129,7 +128,7 @@ CardMenu::CardMenu(PlayerLogic *_player, const CardItem *_card, bool _shortcutsA } bool revealedCard = false; - bool writeableCard = player->getPlayerInfo()->getLocalOrJudge(); + bool writeableCard = player->getLogic()->getPlayerInfo()->getLocalOrJudge(); if (auto *view = qobject_cast(card->getZone())) { if (view->getRevealZone()) { if (view->getWriteableRevealZone()) { @@ -313,7 +312,9 @@ void CardMenu::createHandOrCustomZoneMenu(bool canModifyCard) initContextualPlayersMenu(revealMenu, aRevealToAll); - connect(revealMenu, &QMenu::triggered, player->getPlayerActions(), &PlayerActions::actReveal); + connect(revealMenu, &QMenu::triggered, this, [this](QAction *action) { + player->getLogic()->getPlayerActions()->actReveal(player->getGameScene()->selectedCards(), action); + }); addSeparator(); addAction(aClone); @@ -398,8 +399,7 @@ void CardMenu::addRelatedCardView() QAction *viewCard = viewRelatedCards->addAction(relatedCardName); Q_UNUSED(viewCard); - connect(viewCard, &QAction::triggered, player->getGame(), - [this, cardRef] { player->getGame()->getTab()->viewCardInfo(cardRef); }); + connect(viewCard, &QAction::triggered, this, [this, cardRef] { emit cardInfoRequested(cardRef); }); } } @@ -461,7 +461,8 @@ void CardMenu::addRelatedCardActions() auto *createRelated = new QAction(text, this); createRelated->setData(QVariant(index++)); - connect(createRelated, &QAction::triggered, player->getPlayerActions(), &PlayerActions::actCreateRelatedCard); + connect(createRelated, &QAction::triggered, player->getLogic()->getPlayerActions(), + &PlayerActions::actCreateRelatedCard); addAction(createRelated); } @@ -470,7 +471,7 @@ void CardMenu::addRelatedCardActions() createRelatedCards->setShortcuts( SettingsCache::instance().shortcuts().getShortcut("Player/aCreateRelatedTokens")); } - connect(createRelatedCards, &QAction::triggered, player->getPlayerActions(), + connect(createRelatedCards, &QAction::triggered, player->getLogic()->getPlayerActions(), &PlayerActions::actCreateAllRelatedCards); addAction(createRelatedCards); } diff --git a/cockatrice/src/game/player/menu/card_menu.h b/cockatrice/src/game/player/menu/card_menu.h index ad3962caf..d67ef3876 100644 --- a/cockatrice/src/game/player/menu/card_menu.h +++ b/cockatrice/src/game/player/menu/card_menu.h @@ -8,15 +8,20 @@ #define COCKATRICE_CARD_MENU_H #include +#include class CardItem; +class PlayerGraphicsItem; class PlayerLogic; class CardMenu : public QMenu { Q_OBJECT +signals: + void cardInfoRequested(const CardRef &cardRef); + public: - explicit CardMenu(PlayerLogic *player, const CardItem *card, bool shortcutsActive); + explicit CardMenu(PlayerGraphicsItem *player, const CardItem *card, bool shortcutsActive); void removePlayer(PlayerLogic *playerToRemove); void createTableMenu(bool canModifyCard); void createStackMenu(bool canModifyCard); @@ -41,7 +46,7 @@ public: QList aAddCounter, aSetCounter, aRemoveCounter; private: - PlayerLogic *player; + PlayerGraphicsItem *player; const CardItem *card; QList> playersInfo; bool shortcutsActive; diff --git a/cockatrice/src/game/player/menu/custom_zone_menu.cpp b/cockatrice/src/game/player/menu/custom_zone_menu.cpp index 88b7f3710..106e646d9 100644 --- a/cockatrice/src/game/player/menu/custom_zone_menu.cpp +++ b/cockatrice/src/game/player/menu/custom_zone_menu.cpp @@ -2,12 +2,12 @@ #include "../player_logic.h" -CustomZoneMenu::CustomZoneMenu(PlayerLogic *_player) : player(_player) +CustomZoneMenu::CustomZoneMenu(PlayerGraphicsItem *_player) : player(_player) { menuAction()->setVisible(false); - connect(player, &PlayerLogic::clearCustomZonesMenu, this, &CustomZoneMenu::clearCustomZonesMenu); - connect(player, &PlayerLogic::addViewCustomZoneActionToCustomZoneMenu, this, + connect(player->getLogic(), &PlayerLogic::clearCustomZonesMenu, this, &CustomZoneMenu::clearCustomZonesMenu); + connect(player->getLogic(), &PlayerLogic::addViewCustomZoneActionToCustomZoneMenu, this, &CustomZoneMenu::addViewCustomZoneActionToCustomZoneMenu); retranslateUi(); @@ -17,7 +17,7 @@ void CustomZoneMenu::retranslateUi() { setTitle(tr("C&ustom Zones")); - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { for (auto aViewZone : actions()) { aViewZone->setText(tr("View custom zone '%1'").arg(aViewZone->data().toString())); @@ -37,5 +37,5 @@ void CustomZoneMenu::addViewCustomZoneActionToCustomZoneMenu(QString zoneName) QAction *aViewZone = addAction(tr("View custom zone '%1'").arg(zoneName)); aViewZone->setData(zoneName); connect(aViewZone, &QAction::triggered, this, - [zoneName, this]() { player->getGameScene()->toggleZoneView(player, zoneName, -1); }); + [zoneName, this]() { player->getGameScene()->toggleZoneView(player->getLogic(), zoneName, -1); }); } \ No newline at end of file diff --git a/cockatrice/src/game/player/menu/custom_zone_menu.h b/cockatrice/src/game/player/menu/custom_zone_menu.h index e10f6a4f0..46dd58db6 100644 --- a/cockatrice/src/game/player/menu/custom_zone_menu.h +++ b/cockatrice/src/game/player/menu/custom_zone_menu.h @@ -11,12 +11,12 @@ #include -class PlayerLogic; +class PlayerGraphicsItem; class CustomZoneMenu : public QMenu, public AbstractPlayerComponent { Q_OBJECT public: - explicit CustomZoneMenu(PlayerLogic *player); + explicit CustomZoneMenu(PlayerGraphicsItem *player); void retranslateUi() override; void setShortcutsActive() override { @@ -26,7 +26,7 @@ public: } private: - PlayerLogic *player; + PlayerGraphicsItem *player; private slots: void clearCustomZonesMenu(); void addViewCustomZoneActionToCustomZoneMenu(QString zoneName); diff --git a/cockatrice/src/game/player/menu/move_menu.cpp b/cockatrice/src/game/player/menu/move_menu.cpp index 3a5ad4da3..4dfdee432 100644 --- a/cockatrice/src/game/player/menu/move_menu.cpp +++ b/cockatrice/src/game/player/menu/move_menu.cpp @@ -4,7 +4,7 @@ #include "../player_actions.h" #include "../player_logic.h" -MoveMenu::MoveMenu(PlayerLogic *player) : QMenu(tr("Move to")) +MoveMenu::MoveMenu(PlayerGraphicsItem *player) : QMenu(tr("Move to")) { aMoveToTopLibrary = new QAction(this); aMoveToTopLibrary->setData(cmMoveToTopLibrary); @@ -20,14 +20,23 @@ MoveMenu::MoveMenu(PlayerLogic *player) : QMenu(tr("Move to")) aMoveToExile = new QAction(this); aMoveToExile->setData(cmMoveToExile); - connect(aMoveToTopLibrary, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); - connect(aMoveToBottomLibrary, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); - connect(aMoveToXfromTopOfLibrary, &QAction::triggered, player->getPlayerActions(), - &PlayerActions::actMoveCardXCardsFromTop); - connect(aMoveToTable, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); - connect(aMoveToHand, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); - connect(aMoveToGraveyard, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); - connect(aMoveToExile, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction); + auto *actions = player->getLogic()->getPlayerActions(); + + auto invoke = [player](CardMenuActionType type) { + return [type, player]() { + player->getLogic()->getPlayerActions()->cardMenuAction(player->getGameScene()->selectedCards(), type); + }; + }; + + connect(aMoveToTopLibrary, &QAction::triggered, actions, invoke(cmMoveToTopLibrary)); + connect(aMoveToBottomLibrary, &QAction::triggered, actions, invoke(cmMoveToBottomLibrary)); + connect(aMoveToXfromTopOfLibrary, &QAction::triggered, actions, [player]() { + player->getLogic()->getPlayerActions()->actMoveCardXCardsFromTop(player->getGameScene()->selectedCards()); + }); + connect(aMoveToTable, &QAction::triggered, actions, invoke(cmMoveToTable)); + connect(aMoveToHand, &QAction::triggered, actions, invoke(cmMoveToHand)); + connect(aMoveToGraveyard, &QAction::triggered, actions, invoke(cmMoveToGraveyard)); + connect(aMoveToExile, &QAction::triggered, actions, invoke(cmMoveToExile)); addAction(aMoveToTopLibrary); addAction(aMoveToXfromTopOfLibrary); diff --git a/cockatrice/src/game/player/menu/move_menu.h b/cockatrice/src/game/player/menu/move_menu.h index 4e257b7fb..150bdbd3c 100644 --- a/cockatrice/src/game/player/menu/move_menu.h +++ b/cockatrice/src/game/player/menu/move_menu.h @@ -8,13 +8,13 @@ #define COCKATRICE_MOVE_MENU_H #include -class PlayerLogic; +class PlayerGraphicsItem; class MoveMenu : public QMenu { Q_OBJECT public: - explicit MoveMenu(PlayerLogic *player); + explicit MoveMenu(PlayerGraphicsItem *player); void setShortcutsActive(); void retranslateUi(); diff --git a/cockatrice/src/game/player/menu/player_menu.cpp b/cockatrice/src/game/player/menu/player_menu.cpp index 9e7b91923..6687bbba8 100644 --- a/cockatrice/src/game/player/menu/player_menu.cpp +++ b/cockatrice/src/game/player/menu/player_menu.cpp @@ -10,23 +10,26 @@ #include -PlayerMenu::PlayerMenu(PlayerLogic *_player) : QObject(_player), player(_player) +PlayerMenu::PlayerMenu(PlayerGraphicsItem *_player) : QObject(_player), player(_player) { + connect(player->getLogic(), &PlayerLogic::requestCardMenuUpdate, this, &PlayerMenu::updateCardMenu); + connect(this, &PlayerMenu::cardInfoRequested, player, &PlayerGraphicsItem::cardInfoRequested); + playerMenu = new TearOffMenu(); - if (player->getPlayerInfo()->getLocalOrJudge()) { - handMenu = addManagedMenu(player, player->getPlayerActions(), playerMenu); - libraryMenu = addManagedMenu(player, playerMenu); + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { + handMenu = addManagedMenu(player->getLogic(), player->getLogic()->getPlayerActions(), playerMenu); + libraryMenu = addManagedMenu(player->getLogic(), playerMenu); } else { handMenu = nullptr; libraryMenu = nullptr; } - graveMenu = addManagedMenu(player, playerMenu); - rfgMenu = addManagedMenu(player, playerMenu); + graveMenu = addManagedMenu(player->getLogic(), playerMenu); + rfgMenu = addManagedMenu(player->getLogic(), playerMenu); - if (player->getPlayerInfo()->getLocalOrJudge()) { - sideboardMenu = addManagedMenu(player, playerMenu); + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { + sideboardMenu = addManagedMenu(player->getLogic(), playerMenu); customZonesMenu = addManagedMenu(player); playerMenu->addSeparator(); @@ -40,8 +43,8 @@ PlayerMenu::PlayerMenu(PlayerLogic *_player) : QObject(_player), player(_player) utilityMenu = nullptr; } - if (player->getPlayerInfo()->getLocal()) { - sayMenu = addManagedMenu(player); + if (player->getLogic()->getPlayerInfo()->getLocal()) { + sayMenu = addManagedMenu(player->getLogic()); } else { sayMenu = nullptr; } @@ -55,13 +58,13 @@ PlayerMenu::PlayerMenu(PlayerLogic *_player) : QObject(_player), player(_player) void PlayerMenu::setMenusForGraphicItems() { - player->getGraphicsItem()->getTableZoneGraphicsItem()->setMenu(playerMenu); - player->getGraphicsItem()->getGraveyardZoneGraphicsItem()->setMenu(graveMenu, graveMenu->aViewGraveyard); - player->getGraphicsItem()->getRfgZoneGraphicsItem()->setMenu(rfgMenu, rfgMenu->aViewRfg); - if (player->getPlayerInfo()->getLocalOrJudge()) { - player->getGraphicsItem()->getHandZoneGraphicsItem()->setMenu(handMenu); - player->getGraphicsItem()->getDeckZoneGraphicsItem()->setMenu(libraryMenu, libraryMenu->aDrawCard); - player->getGraphicsItem()->getSideboardZoneGraphicsItem()->setMenu(sideboardMenu); + player->getTableZoneGraphicsItem()->setMenu(playerMenu); + player->getGraveyardZoneGraphicsItem()->setMenu(graveMenu, graveMenu->aViewGraveyard); + player->getRfgZoneGraphicsItem()->setMenu(rfgMenu, rfgMenu->aViewRfg); + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { + player->getHandZoneGraphicsItem()->setMenu(handMenu); + player->getDeckZoneGraphicsItem()->setMenu(libraryMenu, libraryMenu->aDrawCard); + player->getSideboardZoneGraphicsItem()->setMenu(sideboardMenu); } } @@ -74,12 +77,14 @@ QMenu *PlayerMenu::updateCardMenu(const CardItem *card) // If is spectator (as spectators don't need card menus), return // only update the menu if the card is actually selected - if ((player->getGame()->getPlayerManager()->isSpectator() && !player->getGame()->getPlayerManager()->isJudge()) || - player->getGame()->getActiveCard() != card) { + if ((player->getLogic()->getGame()->getPlayerManager()->isSpectator() && + !player->getLogic()->getGame()->getPlayerManager()->isJudge()) || + player->getLogic()->getGame()->getActiveCard() != card) { return nullptr; } - QMenu *menu = new CardMenu(player, card, shortcutsActive); + CardMenu *menu = new CardMenu(player, card, shortcutsActive); + connect(menu, &CardMenu::cardInfoRequested, this, &PlayerMenu::cardInfoRequested); emit cardMenuUpdated(menu); return menu; @@ -87,7 +92,7 @@ QMenu *PlayerMenu::updateCardMenu(const CardItem *card) void PlayerMenu::retranslateUi() { - playerMenu->setTitle(tr("Player \"%1\"").arg(player->getPlayerInfo()->getName())); + playerMenu->setTitle(tr("Player \"%1\"").arg(player->getLogic()->getPlayerInfo()->getName())); for (auto *component : managedComponents) { component->retranslateUi(); @@ -104,7 +109,8 @@ void PlayerMenu::refreshShortcuts() { if (shortcutsActive) { // Judges get access to every player's menus but only want shortcuts to be set for their own. - if (player->getPlayerInfo()->getLocalOrJudge() && !player->getPlayerInfo()->getLocal()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge() && + !player->getLogic()->getPlayerInfo()->getLocal()) { setShortcutsInactive(); } else { setShortcutsActive(); diff --git a/cockatrice/src/game/player/menu/player_menu.h b/cockatrice/src/game/player/menu/player_menu.h index d5c19df58..62ba66df7 100644 --- a/cockatrice/src/game/player/menu/player_menu.h +++ b/cockatrice/src/game/player/menu/player_menu.h @@ -8,7 +8,6 @@ #define COCKATRICE_PLAYER_MENU_H #include "../../../interface/widgets/menus/tearoff_menu.h" -#include "../player_logic.h" #include "custom_zone_menu.h" #include "grave_menu.h" #include "hand_menu.h" @@ -23,29 +22,31 @@ #include class CardItem; +class CardMenu; +class PlayerGraphicsItem; class PlayerMenu : public QObject { Q_OBJECT signals: - void cardMenuUpdated(QMenu *cardMenu); + void cardMenuUpdated(CardMenu *cardMenu); + void cardInfoRequested(const CardRef &cardRef); void shortcutsActivated(); void shortcutsDeactivated(); void retranslateRequested(); public slots: void setMenusForGraphicItems(); + QMenu *updateCardMenu(const CardItem *card); private slots: void refreshShortcuts(); public: - explicit PlayerMenu(PlayerLogic *player); + explicit PlayerMenu(PlayerGraphicsItem *player); /** @brief Retranslate all user-visible strings. Called on language change. */ void retranslateUi(); - QMenu *updateCardMenu(const CardItem *card); - [[nodiscard]] QMenu *getPlayerMenu() const { return playerMenu; @@ -77,7 +78,7 @@ public: void setShortcutsInactive(); private: - PlayerLogic *player; + PlayerGraphicsItem *player; TearOffMenu *playerMenu; QMenu *countersMenu; HandMenu *handMenu; diff --git a/cockatrice/src/game/player/menu/pt_menu.cpp b/cockatrice/src/game/player/menu/pt_menu.cpp index 7dc3035c1..846256e24 100644 --- a/cockatrice/src/game/player/menu/pt_menu.cpp +++ b/cockatrice/src/game/player/menu/pt_menu.cpp @@ -3,30 +3,40 @@ #include "../player_actions.h" #include "../player_logic.h" -PtMenu::PtMenu(PlayerLogic *player) : QMenu(tr("Power / toughness")) +PtMenu::PtMenu(PlayerGraphicsItem *player) : QMenu(tr("Power / toughness")) { - PlayerActions *playerActions = player->getPlayerActions(); + PlayerActions *playerActions = player->getLogic()->getPlayerActions(); aIncP = new QAction(this); - connect(aIncP, &QAction::triggered, playerActions, &PlayerActions::actIncP); + connect(aIncP, &QAction::triggered, playerActions, + [player, playerActions] { playerActions->actIncP(player->getGameScene()->selectedCards()); }); aDecP = new QAction(this); - connect(aDecP, &QAction::triggered, playerActions, &PlayerActions::actDecP); + connect(aDecP, &QAction::triggered, playerActions, + [player, playerActions] { playerActions->actDecP(player->getGameScene()->selectedCards()); }); aIncT = new QAction(this); - connect(aIncT, &QAction::triggered, playerActions, &PlayerActions::actIncT); + connect(aIncT, &QAction::triggered, playerActions, + [player, playerActions] { playerActions->actIncT(player->getGameScene()->selectedCards()); }); aDecT = new QAction(this); - connect(aDecT, &QAction::triggered, playerActions, &PlayerActions::actDecT); + connect(aDecT, &QAction::triggered, playerActions, + [player, playerActions] { playerActions->actDecT(player->getGameScene()->selectedCards()); }); aIncPT = new QAction(this); - connect(aIncPT, &QAction::triggered, playerActions, [playerActions] { playerActions->actIncPT(); }); + connect(aIncPT, &QAction::triggered, playerActions, + [player, playerActions] { playerActions->actIncPT(player->getGameScene()->selectedCards()); }); aDecPT = new QAction(this); - connect(aDecPT, &QAction::triggered, playerActions, &PlayerActions::actDecPT); + connect(aDecPT, &QAction::triggered, playerActions, + [player, playerActions] { playerActions->actDecPT(player->getGameScene()->selectedCards()); }); aFlowP = new QAction(this); - connect(aFlowP, &QAction::triggered, playerActions, &PlayerActions::actFlowP); + connect(aFlowP, &QAction::triggered, playerActions, + [player, playerActions] { playerActions->actFlowP(player->getGameScene()->selectedCards()); }); aFlowT = new QAction(this); - connect(aFlowT, &QAction::triggered, playerActions, &PlayerActions::actFlowT); + connect(aFlowT, &QAction::triggered, playerActions, + [player, playerActions] { playerActions->actFlowT(player->getGameScene()->selectedCards()); }); aSetPT = new QAction(this); - connect(aSetPT, &QAction::triggered, playerActions, &PlayerActions::actSetPT); + connect(aSetPT, &QAction::triggered, playerActions, + [player, playerActions] { playerActions->actSetPT(player->getGameScene()->selectedCards()); }); aResetPT = new QAction(this); - connect(aResetPT, &QAction::triggered, playerActions, &PlayerActions::actResetPT); + connect(aResetPT, &QAction::triggered, playerActions, + [player, playerActions] { playerActions->actResetPT(player->getGameScene()->selectedCards()); }); addAction(aIncP); addAction(aDecP); diff --git a/cockatrice/src/game/player/menu/pt_menu.h b/cockatrice/src/game/player/menu/pt_menu.h index 645449586..72f828801 100644 --- a/cockatrice/src/game/player/menu/pt_menu.h +++ b/cockatrice/src/game/player/menu/pt_menu.h @@ -8,14 +8,14 @@ #define COCKATRICE_PT_MENU_H #include -class PlayerLogic; +class PlayerGraphicsItem; class PtMenu : public QMenu { Q_OBJECT public: - explicit PtMenu(PlayerLogic *player); + explicit PtMenu(PlayerGraphicsItem *player); void retranslateUi(); void setShortcutsActive(); diff --git a/cockatrice/src/game/player/menu/utility_menu.cpp b/cockatrice/src/game/player/menu/utility_menu.cpp index 6b33d7bde..005b38c3b 100644 --- a/cockatrice/src/game/player/menu/utility_menu.cpp +++ b/cockatrice/src/game/player/menu/utility_menu.cpp @@ -8,11 +8,14 @@ #include #include -UtilityMenu::UtilityMenu(PlayerLogic *_player, QMenu *playerMenu) : QMenu(playerMenu), player(_player) +UtilityMenu::UtilityMenu(PlayerGraphicsItem *_player, QMenu *playerMenu) : QMenu(playerMenu), player(_player) { - PlayerActions *playerActions = player->getPlayerActions(); + PlayerActions *playerActions = player->getLogic()->getPlayerActions(); + connect(playerActions, &PlayerActions::requestEnableAndSetCreateAnotherTokenAction, this, + &UtilityMenu::setAndEnableCreateAnotherTokenAction); + connect(playerActions, &PlayerActions::requestSetLastToken, this, &UtilityMenu::setLastToken); - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { aUntapAll = new QAction(this); connect(aUntapAll, &QAction::triggered, playerActions, &PlayerActions::actUntapAll); @@ -23,19 +26,22 @@ UtilityMenu::UtilityMenu(PlayerLogic *_player, QMenu *playerMenu) : QMenu(player connect(aFlipCoin, &QAction::triggered, playerActions, &PlayerActions::actFlipCoin); aCreateToken = new QAction(this); - connect(aCreateToken, &QAction::triggered, playerActions, &PlayerActions::actCreateToken); + connect(aCreateToken, &QAction::triggered, playerActions, + [this]() { player->getLogic()->getPlayerActions()->actCreateToken(getPredefinedTokens()); }); aCreateAnotherToken = new QAction(this); connect(aCreateAnotherToken, &QAction::triggered, playerActions, &PlayerActions::actCreateAnotherToken); aCreateAnotherToken->setEnabled(false); aIncrementAllCardCounters = new QAction(this); - connect(aIncrementAllCardCounters, &QAction::triggered, playerActions, - &PlayerActions::actIncrementAllCardCounters); + connect(aIncrementAllCardCounters, &QAction::triggered, playerActions, [this]() { + player->getLogic()->getPlayerActions()->actIncrementAllCardCounters( + player->getGameScene()->selectedCards()); + }); createPredefinedTokenMenu = new QMenu(QString()); createPredefinedTokenMenu->setEnabled(false); - connect(player, &PlayerLogic::deckChanged, this, &UtilityMenu::populatePredefinedTokensMenu); + connect(player->getLogic(), &PlayerLogic::deckChanged, this, &UtilityMenu::populatePredefinedTokensMenu); playerMenu->addAction(aIncrementAllCardCounters); playerMenu->addSeparator(); @@ -66,7 +72,7 @@ void UtilityMenu::populatePredefinedTokensMenu() clear(); setEnabled(false); predefinedTokens.clear(); - const DeckList &deckList = player->getDeck(); + const DeckList &deckList = player->getLogic()->getDeck(); if (deckList.isEmpty()) { return; @@ -84,14 +90,24 @@ void UtilityMenu::populatePredefinedTokensMenu() if (i < 10) { a->setShortcut(QKeySequence("Alt+" + QString::number((i + 1) % 10))); } - connect(a, &QAction::triggered, player->getPlayerActions(), &PlayerActions::actCreatePredefinedToken); + connect(a, &QAction::triggered, player->getLogic()->getPlayerActions(), + &PlayerActions::actCreatePredefinedToken); } } } +void UtilityMenu::setLastToken(CardInfoPtr lastToken) +{ + if (!createAnotherTokenActionExists()) { + return; + } + + player->getLogic()->getPlayerActions()->setLastTokenInfo(lastToken); +} + void UtilityMenu::retranslateUi() { - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { aIncrementAllCardCounters->setText(tr("Increment all card counters")); aUntapAll->setText(tr("&Untap all permanents")); aRollDie->setText(tr("R&oll die...")); @@ -106,7 +122,7 @@ void UtilityMenu::setShortcutsActive() { ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts(); - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { aIncrementAllCardCounters->setShortcuts(shortcuts.getShortcut("Player/aIncrementAllCardCounters")); aUntapAll->setShortcuts(shortcuts.getShortcut("Player/aUntapAll")); aRollDie->setShortcuts(shortcuts.getShortcut("Player/aRollDie")); @@ -118,7 +134,7 @@ void UtilityMenu::setShortcutsActive() void UtilityMenu::setShortcutsInactive() { - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { aUntapAll->setShortcut(QKeySequence()); aRollDie->setShortcut(QKeySequence()); aFlipCoin->setShortcut(QKeySequence()); diff --git a/cockatrice/src/game/player/menu/utility_menu.h b/cockatrice/src/game/player/menu/utility_menu.h index fab3211ca..bdc2a81a5 100644 --- a/cockatrice/src/game/player/menu/utility_menu.h +++ b/cockatrice/src/game/player/menu/utility_menu.h @@ -10,19 +10,21 @@ #include "abstract_player_component.h" #include +#include -class PlayerLogic; +class PlayerGraphicsItem; class UtilityMenu : public QMenu, public AbstractPlayerComponent { Q_OBJECT public slots: void populatePredefinedTokensMenu(); + void setLastToken(CardInfoPtr lastToken); void retranslateUi() override; void setShortcutsActive() override; void setShortcutsInactive() override; public: - explicit UtilityMenu(PlayerLogic *player, QMenu *playerMenu); + explicit UtilityMenu(PlayerGraphicsItem *player, QMenu *playerMenu); [[nodiscard]] bool createAnotherTokenActionExists() const { @@ -31,7 +33,7 @@ public: void setAndEnableCreateAnotherTokenAction(QString text) { - aCreateAnotherToken->setText(text); + aCreateAnotherToken->setText(tr("C&reate another %1 token").arg(text)); aCreateAnotherToken->setEnabled(true); } @@ -41,7 +43,7 @@ public: } private: - PlayerLogic *player; + PlayerGraphicsItem *player; QStringList predefinedTokens; QMenu *createPredefinedTokenMenu; diff --git a/cockatrice/src/game/player/player_actions.cpp b/cockatrice/src/game/player/player_actions.cpp index 1706c44dc..7d58be31a 100644 --- a/cockatrice/src/game/player/player_actions.cpp +++ b/cockatrice/src/game/player/player_actions.cpp @@ -39,6 +39,8 @@ static constexpr int MOVE_TOP_CARD_UNTIL_INTERVAL = 100; PlayerActions::PlayerActions(PlayerLogic *_player) : QObject(_player), player(_player), lastTokenTableRow(0), movingCardsUntil(false) { + connect(this, &PlayerActions::requestZoneViewToggle, player, &PlayerLogic::onRequestZoneViewToggle); + moveTopCardTimer = new QTimer(this); moveTopCardTimer->setInterval(MOVE_TOP_CARD_UNTIL_INTERVAL); moveTopCardTimer->setSingleShot(true); @@ -133,12 +135,12 @@ void PlayerActions::playCardToTable(const CardItem *card, bool faceDown) void PlayerActions::actViewLibrary() { - player->getGameScene()->toggleZoneView(player, ZoneNames::DECK, -1); + emit requestZoneViewToggle(ZoneNames::DECK, -1); } void PlayerActions::actViewHand() { - player->getGameScene()->toggleZoneView(player, ZoneNames::HAND, -1); + emit requestZoneViewToggle(ZoneNames::HAND, -1); } /** @@ -170,7 +172,7 @@ void PlayerActions::actSortHand() static QList defaultOptions = {CardList::SortByName, CardList::SortByPrinting}; - player->getGraphicsItem()->getHandZoneGraphicsItem()->sortHand(sortOptions + defaultOptions); + emit requestSortHand(sortOptions + defaultOptions); } void PlayerActions::actViewTopCards() @@ -182,7 +184,7 @@ void PlayerActions::actViewTopCards() deckSize, 1, &ok); if (ok) { defaultNumberTopCards = number; - player->getGameScene()->toggleZoneView(player, ZoneNames::DECK, number); + emit requestZoneViewToggle(ZoneNames::DECK, number); } } @@ -195,24 +197,24 @@ void PlayerActions::actViewBottomCards() deckSize, 1, &ok); if (ok) { defaultNumberBottomCards = number; - player->getGameScene()->toggleZoneView(player, ZoneNames::DECK, number, true); + emit requestZoneViewToggle(ZoneNames::DECK, number, true); } } -void PlayerActions::actAlwaysRevealTopCard() +void PlayerActions::actAlwaysRevealTopCard(bool alwaysRevealTopCard) { Command_ChangeZoneProperties cmd; cmd.set_zone_name(ZoneNames::DECK); - cmd.set_always_reveal_top_card(player->getPlayerMenu()->getLibraryMenu()->isAlwaysRevealTopCardChecked()); + cmd.set_always_reveal_top_card(alwaysRevealTopCard); sendGameCommand(cmd); } -void PlayerActions::actAlwaysLookAtTopCard() +void PlayerActions::actAlwaysLookAtTopCard(bool alwaysRevealTopCard) { Command_ChangeZoneProperties cmd; cmd.set_zone_name(ZoneNames::DECK); - cmd.set_always_look_at_top_card(player->getPlayerMenu()->getLibraryMenu()->isAlwaysLookAtTopCardChecked()); + cmd.set_always_look_at_top_card(alwaysRevealTopCard); sendGameCommand(cmd); } @@ -224,17 +226,17 @@ void PlayerActions::actOpenDeckInDeckEditor() void PlayerActions::actViewGraveyard() { - player->getGameScene()->toggleZoneView(player, ZoneNames::GRAVE, -1); + emit requestZoneViewToggle(ZoneNames::GRAVE, -1); } void PlayerActions::actViewRfg() { - player->getGameScene()->toggleZoneView(player, ZoneNames::EXILE, -1); + emit requestZoneViewToggle(ZoneNames::EXILE, -1); } void PlayerActions::actViewSideboard() { - player->getGameScene()->toggleZoneView(player, ZoneNames::SIDEBOARD, -1); + emit requestZoneViewToggle(ZoneNames::SIDEBOARD, -1); } void PlayerActions::actShuffle() @@ -862,9 +864,9 @@ void PlayerActions::actFlipCoin() sendGameCommand(cmd); } -void PlayerActions::actCreateToken() +void PlayerActions::actCreateToken(const QStringList &predefinedTokens) { - DlgCreateToken dlg(player->getPlayerMenu()->getUtilityMenu()->getPredefinedTokens(), player->getGame()->getTab()); + DlgCreateToken dlg(predefinedTokens, player->getGame()->getTab()); if (!dlg.exec()) { return; } @@ -880,8 +882,7 @@ void PlayerActions::actCreateToken() } } - player->getPlayerMenu()->getUtilityMenu()->setAndEnableCreateAnotherTokenAction( - tr("C&reate another %1 token").arg(lastTokenInfo.name)); + emit requestEnableAndSetCreateAnotherTokenAction(lastTokenInfo.name); actCreateAnotherToken(); } @@ -912,8 +913,12 @@ void PlayerActions::setLastToken(CardInfoPtr cardInfo) return; } - UtilityMenu *utilityMenu = player->getPlayerMenu()->getUtilityMenu(); - if (utilityMenu == nullptr || !utilityMenu->createAnotherTokenActionExists()) { + emit requestSetLastToken(cardInfo); +} + +void PlayerActions::setLastTokenInfo(CardInfoPtr cardInfo) +{ + if (cardInfo == nullptr) { return; } @@ -927,7 +932,7 @@ void PlayerActions::setLastToken(CardInfoPtr cardInfo) lastTokenTableRow = TableZone::tableRowToGridY(cardInfo->getUiAttributes().tableRow); - utilityMenu->setAndEnableCreateAnotherTokenAction(tr("C&reate another %1 token").arg(lastTokenInfo.name)); + emit requestEnableAndSetCreateAnotherTokenAction(lastTokenInfo.name); } void PlayerActions::actCreatePredefinedToken() @@ -1166,7 +1171,7 @@ void PlayerActions::actSayMessage() sendGameCommand(cmd); } -void PlayerActions::actMoveCardXCardsFromTop() +void PlayerActions::actMoveCardXCardsFromTop(QList selectedCards) { int deckSize = player->getDeckZone()->getCards().size() + 1; // add the card to move to the deck bool ok; @@ -1182,7 +1187,7 @@ void PlayerActions::actMoveCardXCardsFromTop() defaultNumberTopCardsToPlaceBelow = number; - QList cardList = player->getGameScene()->selectedCards(); + QList cardList = selectedCards; if (cardList.isEmpty()) { return; } @@ -1213,12 +1218,12 @@ void PlayerActions::actMoveCardXCardsFromTop() } } -void PlayerActions::actIncPT(int deltaP, int deltaT) +void PlayerActions::actIncPT(QList selectedCards, int deltaP, int deltaT) { int playerid = player->getPlayerInfo()->getId(); QList commandList; - for (auto card : player->getGameScene()->selectedCards()) { + for (auto card : selectedCards) { QString pt = card->getPT(); const auto ptList = CardItem::parsePT(pt); QString newpt; @@ -1246,11 +1251,11 @@ void PlayerActions::actIncPT(int deltaP, int deltaT) player->getGame()->getGameEventHandler()->sendGameCommand(prepareGameCommand(commandList), playerid); } -void PlayerActions::actResetPT() +void PlayerActions::actResetPT(QList selectedCards) { int playerid = player->getPlayerInfo()->getId(); QList commandList; - for (auto card : player->getGameScene()->selectedCards()) { + for (auto card : selectedCards) { QString ptString; if (!card->getFaceDown()) { // leave the pt empty if the card is face down ExactCard ec = card->getCard(); @@ -1279,13 +1284,12 @@ void PlayerActions::actResetPT() } } -void PlayerActions::actSetPT() +void PlayerActions::actSetPT(QList selectedCards) { QString oldPT; int playerid = player->getPlayerInfo()->getId(); - auto cards = player->getGameScene()->selectedCards(); - for (auto card : cards) { + for (auto card : selectedCards) { if (!card->getPT().isEmpty()) { oldPT = card->getPT(); } @@ -1303,7 +1307,7 @@ void PlayerActions::actSetPT() bool empty = ptList.isEmpty(); QList commandList; - for (auto card : cards) { + for (auto card : selectedCards) { auto *cmd = new Command_SetCardAttr; QString newpt = QString(); if (!empty) { @@ -1347,47 +1351,47 @@ void PlayerActions::actDrawArrow() } } -void PlayerActions::actIncP() +void PlayerActions::actIncP(QList selectedCards) { - actIncPT(1, 0); + actIncPT(selectedCards, 1, 0); } -void PlayerActions::actDecP() +void PlayerActions::actDecP(QList selectedCards) { - actIncPT(-1, 0); + actIncPT(selectedCards, -1, 0); } -void PlayerActions::actIncT() +void PlayerActions::actIncT(QList selectedCards) { - actIncPT(0, 1); + actIncPT(selectedCards, 0, 1); } -void PlayerActions::actDecT() +void PlayerActions::actDecT(QList selectedCards) { - actIncPT(0, -1); + actIncPT(selectedCards, 0, -1); } -void PlayerActions::actIncPT() +void PlayerActions::actIncPT(QList selectedCards) { - actIncPT(1, 1); + actIncPT(selectedCards, 1, 1); } -void PlayerActions::actDecPT() +void PlayerActions::actDecPT(QList selectedCards) { - actIncPT(-1, -1); + actIncPT(selectedCards, -1, -1); } -void PlayerActions::actFlowP() +void PlayerActions::actFlowP(QList selectedCards) { - actIncPT(1, -1); + actIncPT(selectedCards, 1, -1); } -void PlayerActions::actFlowT() +void PlayerActions::actFlowT(QList selectedCards) { - actIncPT(-1, 1); + actIncPT(selectedCards, -1, 1); } -void PlayerActions::actReduceLifeByPower() +void PlayerActions::actReduceLifeByPower(QList selectedCards) { // find life counter auto lifeCounter = player->getLifeCounter(); @@ -1395,10 +1399,9 @@ void PlayerActions::actReduceLifeByPower() return; } - // calculate total power - auto cards = player->getGameScene()->selectedCards(); + // calculate total power; int total = 0; - for (auto card : cards) { + for (auto card : selectedCards) { QVariantList parsed = CardItem::parsePT(card->getPT()); if (!parsed.isEmpty()) { int power = parsed.first().toInt(); // toInt will default to 0 if it's not an int @@ -1423,11 +1426,10 @@ void AnnotationDialog::keyPressEvent(QKeyEvent *event) QInputDialog::keyPressEvent(event); } -void PlayerActions::actSetAnnotation() +void PlayerActions::actSetAnnotation(QList selectedCards) { QString oldAnnotation; - auto cards = player->getGameScene()->selectedCards(); - for (auto card : cards) { + for (auto card : selectedCards) { if (!card->getAnnotation().isEmpty()) { oldAnnotation = card->getAnnotation(); } @@ -1447,7 +1449,7 @@ void PlayerActions::actSetAnnotation() QString annotation = dialog->textValue().left(MAX_NAME_LENGTH); QList commandList; - for (auto card : cards) { + for (auto card : selectedCards) { auto *cmd = new Command_SetCardAttr; cmd->set_zone(card->getZone()->getName().toStdString()); cmd->set_card_id(card->getId()); @@ -1468,10 +1470,10 @@ void PlayerActions::actAttach() card->drawAttachArrow(); } -void PlayerActions::actUnattach() +void PlayerActions::actUnattach(QList selectedCards) { QList commandList; - for (auto card : player->getGameScene()->selectedCards()) { + for (auto card : selectedCards) { if (!card->getAttachedTo()) { continue; } @@ -1484,20 +1486,20 @@ void PlayerActions::actUnattach() sendGameCommand(prepareGameCommand(commandList)); } -void PlayerActions::actAddCardCounter(int counterId) +void PlayerActions::actAddCardCounter(QList selectedCards, int counterId) { - offsetCardCounter(counterId, 1); + offsetCardCounter(selectedCards, counterId, 1); } -void PlayerActions::actRemoveCardCounter(int counterId) +void PlayerActions::actRemoveCardCounter(QList selectedCards, int counterId) { - offsetCardCounter(counterId, -1); + offsetCardCounter(selectedCards, counterId, -1); } -void PlayerActions::offsetCardCounter(int counterId, int offset) +void PlayerActions::offsetCardCounter(QList selectedCards, int counterId, int offset) { QList commandList; - for (auto card : player->getGameScene()->selectedCards()) { + for (auto card : selectedCards) { int oldValue = card->getCounters().value(counterId, 0); int newValue = oldValue + offset; @@ -1517,15 +1519,14 @@ void PlayerActions::offsetCardCounter(int counterId, int offset) sendGameCommand(prepareGameCommand(commandList)); } -void PlayerActions::actSetCardCounter(int counterId) +void PlayerActions::actSetCardCounter(QList selectedCards, int counterId) { player->setDialogSemaphore(true); // If a single card is selected, we show the old value in the dialog. Otherwise, we show "x" - QList sel = player->getGameScene()->selectedCards(); QString oldValueForDlg = "x"; - if (sel.size() == 1) { - auto *card = sel.first(); + if (selectedCards.size() == 1) { + auto *card = selectedCards.first(); oldValueForDlg = QString::number(card->getCounters().value(counterId, 0)); } @@ -1541,7 +1542,7 @@ void PlayerActions::actSetCardCounter(int counterId) } QList commandList; - for (auto card : sel) { + for (auto card : selectedCards) { int oldValue = card->getCounters().value(counterId, 0); Expression exp(oldValue); double parsed = exp.parse(dialog.textValue()); @@ -1559,9 +1560,8 @@ void PlayerActions::actSetCardCounter(int counterId) sendGameCommand(prepareGameCommand(commandList)); } -void PlayerActions::actIncrementAllCardCounters() +void PlayerActions::actIncrementAllCardCounters(QList cardsToUpdate) { - auto cardsToUpdate = player->getGameScene()->selectedCards(); if (cardsToUpdate.isEmpty()) { // If no cards selected, update all cards on table cardsToUpdate = static_cast>(player->getTableZone()->getCards()); @@ -1607,10 +1607,8 @@ static bool isUnwritableRevealZone(CardZoneLogic *zone) return false; } -void PlayerActions::playSelectedCards(const bool faceDown) +void PlayerActions::playSelectedCards(QList selectedCards, const bool faceDown) { - QList selectedCards = player->getGameScene()->selectedCards(); - // CardIds will get shuffled downwards when cards leave the deck. // We need to iterate through the cards in reverse order so cardIds don't get changed out from under us as we play // out the cards one-by-one. @@ -1624,19 +1622,19 @@ void PlayerActions::playSelectedCards(const bool faceDown) } } -void PlayerActions::actPlay() +void PlayerActions::actPlay(QList selectedCards) { - playSelectedCards(false); + playSelectedCards(selectedCards, false); } -void PlayerActions::actPlayFacedown() +void PlayerActions::actPlayFacedown(QList selectedCards) { - playSelectedCards(true); + playSelectedCards(selectedCards, true); } -void PlayerActions::actHide() +void PlayerActions::actHide(QList selectedCards) { - for (const auto &item : player->getGameScene()->selectedCards()) { + for (const auto &item : selectedCards) { auto *card = static_cast(item); if (card && isUnwritableRevealZone(card->getZone())) { card->getZone()->removeCard(card); @@ -1644,7 +1642,7 @@ void PlayerActions::actHide() } } -void PlayerActions::actReveal(QAction *action) +void PlayerActions::actReveal(QList selectedCards, QAction *action) { const int otherPlayerId = action->data().toInt(); @@ -1653,7 +1651,7 @@ void PlayerActions::actReveal(QAction *action) cmd.set_player_id(otherPlayerId); } - for (auto card : player->getGameScene()->selectedCards()) { + for (auto card : selectedCards) { if (!cmd.has_zone_name()) { cmd.set_zone_name(card->getZone()->getName().toStdString()); } @@ -1735,15 +1733,14 @@ void PlayerActions::actRevealRandomGraveyardCard(int revealToPlayerId) sendGameCommand(cmd); } -void PlayerActions::cardMenuAction() +void PlayerActions::cardMenuAction(QList selectedCards, CardMenuActionType type) { - auto *a = dynamic_cast(sender()); - QList cardList = player->getGameScene()->selectedCards(); + QList cardList = selectedCards; QList commandList; - if (a->data().toInt() <= (int)cmClone) { + if (type <= cmClone) { for (const auto &card : cardList) { - switch (static_cast(a->data().toInt())) { + switch (type) { // Leaving both for compatibility with server case cmUntap: // fallthrough @@ -1824,7 +1821,7 @@ void PlayerActions::cardMenuAction() idList.add_card()->set_card_id(i->getId()); } - switch (static_cast(a->data().toInt())) { + switch (type) { case cmMoveToTopLibrary: { auto *cmd = new Command_MoveCard; cmd->set_start_player_id(startPlayerId); diff --git a/cockatrice/src/game/player/player_actions.h b/cockatrice/src/game/player/player_actions.h index 3b822b61a..940de610f 100644 --- a/cockatrice/src/game/player/player_actions.h +++ b/cockatrice/src/game/player/player_actions.h @@ -9,6 +9,7 @@ #define COCKATRICE_PLAYER_ACTIONS_H #include "../dialogs/dlg_create_token.h" #include "../dialogs/dlg_move_top_cards_until.h" +#include "card_menu_action_type.h" #include "event_processing_options.h" #include "player_logic.h" @@ -56,15 +57,22 @@ public: return movingCardsUntil; } +signals: + void requestZoneViewToggle(const QString &zoneName, int numberCards, bool isReversed = false); + void requestSortHand(const QList &options); + void requestEnableAndSetCreateAnotherTokenAction(const QString &lastTokenName); + void requestSetLastToken(CardInfoPtr lastToken); + public slots: void setLastToken(CardInfoPtr cardInfo); + void setLastTokenInfo(CardInfoPtr cardInfo); void playCard(CardItem *c, bool faceDown); void playCardToTable(const CardItem *c, bool faceDown); void actUntapAll(); void actRollDie(); void actFlipCoin(); - void actCreateToken(); + void actCreateToken(const QStringList &predefinedTokens); void actCreateAnotherToken(); void actShuffle(); void actShuffleTop(); @@ -77,9 +85,9 @@ public slots: void actMulliganMinusOne(); void doMulligan(int number); - void actPlay(); - void actPlayFacedown(); - void actHide(); + void actPlay(QList selectedCards); + void actPlayFacedown(QList selectedCards); + void actHide(QList selectedCards); void actMoveTopCardToPlay(); void actMoveTopCardToPlayFaceDown(); @@ -111,8 +119,8 @@ public slots: void actViewHand(); void actViewTopCards(); void actViewBottomCards(); - void actAlwaysRevealTopCard(); - void actAlwaysLookAtTopCard(); + void actAlwaysRevealTopCard(bool alwaysRevealTopCard); + void actAlwaysLookAtTopCard(bool alwaysRevealTopCard); void actViewGraveyard(); void actLendLibrary(int lendToPlayerId); void actRevealTopCards(int revealToPlayerId, int amount); @@ -127,37 +135,37 @@ public slots: void actCreateRelatedCard(); void actCreateAllRelatedCards(); - void actMoveCardXCardsFromTop(); - void actRemoveCardCounter(int counterId); - void actAddCardCounter(int counterId); - void actSetCardCounter(int counterId); - void actIncrementAllCardCounters(); + void actMoveCardXCardsFromTop(QList selectedCards); + void actRemoveCardCounter(QList selectedCards, int counterId); + void actAddCardCounter(QList selectedCards, int counterId); + void actSetCardCounter(QList selectedCards, int counterId); + void actIncrementAllCardCounters(QList cardsToUpdate); void actAttach(); - void actUnattach(); + void actUnattach(QList selectedCards); void actDrawArrow(); - void actIncPT(int deltaP, int deltaT); - void actResetPT(); - void actSetPT(); - void actIncP(); - void actDecP(); - void actIncT(); - void actDecT(); - void actIncPT(); - void actDecPT(); - void actFlowP(); - void actFlowT(); + void actIncPT(QList selectedCards, int deltaP, int deltaT); + void actResetPT(QList selectedCards); + void actSetPT(QList selectedCards); + void actIncP(QList selectedCards); + void actDecP(QList selectedCards); + void actIncT(QList selectedCards); + void actDecT(QList selectedCards); + void actIncPT(QList selectedCards); + void actDecPT(QList selectedCards); + void actFlowP(QList selectedCards); + void actFlowT(QList selectedCards); - void actReduceLifeByPower(); + void actReduceLifeByPower(QList selectedCards); - void actSetAnnotation(); - void actReveal(QAction *action); + void actSetAnnotation(QList selectedCards); + void actReveal(QList selectedCards, QAction *action); void actRevealHand(int revealToPlayerId); void actRevealRandomHandCard(int revealToPlayerId); void actRevealLibrary(int revealToPlayerId); void actSortHand(); - void cardMenuAction(); + void cardMenuAction(QList selectedCards, CardMenuActionType type); private: PlayerLogic *player; @@ -185,12 +193,12 @@ private: bool persistent = false); bool createRelatedFromRelation(const CardItem *sourceCard, const CardRelation *cardRelation); - void playSelectedCards(bool faceDown = false); + void playSelectedCards(QList selectedCards, bool faceDown = false); void cmdSetTopCard(Command_MoveCard &cmd); void cmdSetBottomCard(Command_MoveCard &cmd); - void offsetCardCounter(int counterId, int offset); + void offsetCardCounter(QList selectedCards, int counterId, int offset); }; #endif // COCKATRICE_PLAYER_ACTIONS_H diff --git a/cockatrice/src/game/player/player_event_handler.cpp b/cockatrice/src/game/player/player_event_handler.cpp index debc6c8f7..aa751170b 100644 --- a/cockatrice/src/game/player/player_event_handler.cpp +++ b/cockatrice/src/game/player/player_event_handler.cpp @@ -6,7 +6,6 @@ #include "../board/arrow_item.h" #include "../board/card_item.h" #include "../board/card_list.h" -#include "libcockatrice/utility/color.h" #include "player_actions.h" #include "player_logic.h" @@ -33,10 +32,12 @@ #include #include #include +#include #include PlayerEventHandler::PlayerEventHandler(PlayerLogic *_player) : QObject(_player), player(_player) { + connect(this, &PlayerEventHandler::requestCardMenuUpdate, player, &PlayerLogic::requestCardMenuUpdate); } void PlayerEventHandler::eventGameSay(const Event_GameSay &event) @@ -252,7 +253,7 @@ void PlayerEventHandler::eventSetCardCounter(const Event_SetCardCounter &event) int oldValue = card->getCounters().value(event.counter_id(), 0); card->setCounter(event.counter_id(), event.counter_value()); - player->getPlayerMenu()->updateCardMenu(card); + emit requestCardMenuUpdate(card); emit logSetCardCounter(player, card->getName(), event.counter_id(), event.counter_value(), oldValue); } @@ -370,7 +371,7 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv targetZone->addCard(card, true, x, y); emit cardZoneChanged(card, startZone == targetZone); - player->getPlayerMenu()->updateCardMenu(card); + emit requestCardMenuUpdate(card); if (player->getPlayerActions()->isMovingCardsUntil() && startZoneString == ZoneNames::DECK && targetZone->getName() == ZoneNames::STACK) { @@ -397,7 +398,7 @@ void PlayerEventHandler::eventFlipCard(const Event_FlipCard &event) emit logFlipCard(player, card->getName(), event.face_down()); card->setFaceDown(event.face_down()); - player->getPlayerMenu()->updateCardMenu(card); + emit requestCardMenuUpdate(card); } void PlayerEventHandler::eventDestroyCard(const Event_DestroyCard &event) @@ -466,7 +467,7 @@ void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event) } else { emit logUnattachCard(player, startCard->getName()); } - player->getPlayerMenu()->updateCardMenu(startCard); + emit requestCardMenuUpdate(startCard); } void PlayerEventHandler::eventDrawCards(const Event_DrawCards &event) @@ -552,7 +553,7 @@ void PlayerEventHandler::eventRevealCards(const Event_RevealCards &event, EventP } if (!options.testFlag(SKIP_REVEAL_WINDOW) && showZoneView && !cardList.isEmpty()) { - player->getGameScene()->addRevealedZoneView(player, zone, cardList, event.grant_write_access()); + emit player->requestRevealedZoneView(player, zone, cardList, event.grant_write_access()); } emit logRevealCards(player, zone, cardId, cardName, otherPlayer, false, diff --git a/cockatrice/src/game/player/player_event_handler.h b/cockatrice/src/game/player/player_event_handler.h index 958dee16b..cfd82933f 100644 --- a/cockatrice/src/game/player/player_event_handler.h +++ b/cockatrice/src/game/player/player_event_handler.h @@ -83,6 +83,7 @@ signals: void logAlwaysRevealTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal); void logAlwaysLookAtTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal); void cardZoneChanged(CardItem *card, bool sameZone); + void requestCardMenuUpdate(const CardItem *card); public: PlayerEventHandler(PlayerLogic *player); diff --git a/cockatrice/src/game/player/player_graphics_item.cpp b/cockatrice/src/game/player/player_graphics_item.cpp index 0d4f8c3ed..d86fce86b 100644 --- a/cockatrice/src/game/player/player_graphics_item.cpp +++ b/cockatrice/src/game/player/player_graphics_item.cpp @@ -8,6 +8,9 @@ #include "../board/abstract_card_item.h" #include "../board/counter_general.h" #include "../hand_counter.h" +#include "player_actions.h" + +#include PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player) { @@ -16,23 +19,26 @@ PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player) connect(&SettingsCache::instance(), &SettingsCache::handJustificationChanged, this, &PlayerGraphicsItem::rearrangeZones); connect(player, &PlayerLogic::rearrangeCounters, this, &PlayerGraphicsItem::rearrangeCounters); + connect(player, &PlayerLogic::activeChanged, this, &PlayerGraphicsItem::onPlayerActiveChanged); connect(player, &PlayerLogic::concededChanged, this, [this](int, bool c) { setVisible(!c); }); connect(player, &PlayerLogic::zoneIdChanged, this, [this](int id) { playerArea->setPlayerZoneId(id); }); connect(player, &PlayerLogic::counterAdded, this, &PlayerGraphicsItem::onCounterAdded); connect(player, &PlayerLogic::counterRemoved, this, &PlayerGraphicsItem::onCounterRemoved); - connect(player->getPlayerMenu(), &PlayerMenu::shortcutsActivated, this, [this]() { + playerMenu = new PlayerMenu(this); + + connect(playerMenu, &PlayerMenu::shortcutsActivated, this, [this]() { for (auto *ctr : counterWidgets) { ctr->setShortcutsActive(); } }); - connect(player->getPlayerMenu(), &PlayerMenu::shortcutsDeactivated, this, [this]() { + connect(playerMenu, &PlayerMenu::shortcutsDeactivated, this, [this]() { for (auto *ctr : counterWidgets) { ctr->setShortcutsInactive(); } }); - connect(player->getPlayerMenu(), &PlayerMenu::retranslateRequested, this, [this]() { + connect(playerMenu, &PlayerMenu::retranslateRequested, this, [this]() { for (auto *ctr : counterWidgets) { ctr->retranslateUi(); } @@ -47,6 +53,8 @@ PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player) initializeZones(); + playerMenu->setMenusForGraphicItems(); + connect(tableZoneGraphicsItem, &TableZone::sizeChanged, this, &PlayerGraphicsItem::updateBoundingRect); updateBoundingRect(); @@ -57,7 +65,7 @@ PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player) void PlayerGraphicsItem::retranslateUi() { - player->getPlayerMenu()->retranslateUi(); + playerMenu->retranslateUi(); QMapIterator zoneIterator(player->getZones()); while (zoneIterator.hasNext()) { @@ -93,14 +101,16 @@ void PlayerGraphicsItem::initializeZones() rfgZoneGraphicsItem = new PileZone(player->getRfgZone(), this); rfgZoneGraphicsItem->setPos(base + QPointF(0, 2 * h + h2 + 10)); - tableZoneGraphicsItem = new TableZone(player->getTableZone(), this); + tableZoneGraphicsItem = new TableZone(player->getTableZone(), mirrored, this); connect(tableZoneGraphicsItem, &TableZone::sizeChanged, this, &PlayerGraphicsItem::updateBoundingRect); + connect(this, &PlayerGraphicsItem::mirroredChanged, tableZoneGraphicsItem, &TableZone::setMirrored); stackZoneGraphicsItem = new StackZone(player->getStackZone(), static_cast(tableZoneGraphicsItem->boundingRect().height()), this); handZoneGraphicsItem = new HandZone(player->getHandZone(), static_cast(tableZoneGraphicsItem->boundingRect().height()), this); + connect(player->getPlayerActions(), &PlayerActions::requestSortHand, handZoneGraphicsItem, &HandZone::sortHand); connect(handZoneGraphicsItem->getLogic(), &HandZoneLogic::cardCountChanged, handCounter, &HandCounter::updateNumber); @@ -145,6 +155,7 @@ void PlayerGraphicsItem::setMirrored(bool _mirrored) { if (mirrored != _mirrored) { mirrored = _mirrored; + emit mirroredChanged(mirrored); rearrangeZones(); } } @@ -159,11 +170,11 @@ void PlayerGraphicsItem::onCounterAdded(CounterState *state) } counterWidgets.insert(state->getId(), widget); - if (player->getPlayerMenu()->getCountersMenu() && widget->getMenu()) { - player->getPlayerMenu()->getCountersMenu()->addMenu(widget->getMenu()); + if (playerMenu->getCountersMenu() && widget->getMenu()) { + playerMenu->getCountersMenu()->addMenu(widget->getMenu()); } - if (player->getPlayerMenu()->getShortcutsActive()) { + if (playerMenu->getShortcutsActive()) { widget->setShortcutsActive(); } @@ -176,8 +187,8 @@ void PlayerGraphicsItem::onCounterRemoved(int counterId) if (!widget) { return; } - if (player->getPlayerMenu()->getCountersMenu() && widget->getMenu()) { - player->getPlayerMenu()->getCountersMenu()->removeAction(widget->getMenu()->menuAction()); + if (playerMenu->getCountersMenu() && widget->getMenu()) { + playerMenu->getCountersMenu()->removeAction(widget->getMenu()->menuAction()); } widget->delCounter(); rearrangeCounters(); diff --git a/cockatrice/src/game/player/player_graphics_item.h b/cockatrice/src/game/player/player_graphics_item.h index e37fe7290..1acb1520f 100644 --- a/cockatrice/src/game/player/player_graphics_item.h +++ b/cockatrice/src/game/player/player_graphics_item.h @@ -55,11 +55,16 @@ public: return static_cast(scene()); } - PlayerLogic *getPlayer() const + PlayerLogic *getLogic() const { return player; } + [[nodiscard]] PlayerMenu *getPlayerMenu() const + { + return playerMenu; + } + PlayerArea *getPlayerArea() const { return playerArea; @@ -111,9 +116,12 @@ public slots: signals: void sizeChanged(); void playerCountChanged(); + void mirroredChanged(bool isMirrored); + void cardInfoRequested(const CardRef &cardRef); private: PlayerLogic *player; + PlayerMenu *playerMenu; PlayerArea *playerArea; PlayerTarget *playerTarget; QMap counterWidgets; diff --git a/cockatrice/src/game/player/player_logic.cpp b/cockatrice/src/game/player/player_logic.cpp index 0210aa0c6..b748eb19a 100644 --- a/cockatrice/src/game/player/player_logic.cpp +++ b/cockatrice/src/game/player/player_logic.cpp @@ -35,14 +35,6 @@ PlayerLogic::PlayerLogic(const ServerInfo_User &info, int _id, bool _local, bool conceded(false), zoneId(0), dialogSemaphore(false) { initializeZones(); - - playerMenu = new PlayerMenu(this); - graphicsItem = new PlayerGraphicsItem(this); - playerMenu->setMenusForGraphicItems(); - - connect(this, &PlayerLogic::activeChanged, graphicsItem, &PlayerGraphicsItem::onPlayerActiveChanged); - - connect(this, &PlayerLogic::openDeckEditor, game->getTab(), &TabGame::openDeckEditor); } void PlayerLogic::initializeZones() @@ -68,7 +60,6 @@ PlayerLogic::~PlayerLogic() } zones.clear(); - delete playerMenu; delete getPlayerInfo()->userInfo; } @@ -326,22 +317,16 @@ void PlayerLogic::setActive(bool _active) active = _active; emit activeChanged(active); } +void PlayerLogic::onRequestZoneViewToggle(const QString &zoneName, int numberCards, bool isReversed) +{ + emit requestZoneViewToggle(this, zoneName, numberCards, isReversed); +} void PlayerLogic::updateZones() { getTableZone()->reorganizeCards(); } -PlayerGraphicsItem *PlayerLogic::getGraphicsItem() -{ - return graphicsItem; -} - -GameScene *PlayerLogic::getGameScene() -{ - return getGraphicsItem()->getGameScene(); -} - void PlayerLogic::setGameStarted() { if (playerInfo->local) { diff --git a/cockatrice/src/game/player/player_logic.h b/cockatrice/src/game/player/player_logic.h index c3508d069..c83892dea 100644 --- a/cockatrice/src/game/player/player_logic.h +++ b/cockatrice/src/game/player/player_logic.h @@ -67,8 +67,14 @@ class PlayerLogic : public QObject signals: void openDeckEditor(const LoadedDeck &deck); + void requestZoneViewToggle(PlayerLogic *player, const QString &zoneName, int numberCards, bool isReversed); + void requestRevealedZoneView(PlayerLogic *player, + CardZoneLogic *zone, + const QList &cardList, + bool withWritePermission); void deckChanged(); void newCardAdded(AbstractCardItem *card); + void requestCardMenuUpdate(const CardItem *card); void counterAdded(CounterState *state); void counterRemoved(int counterId); void rearrangeCounters(); @@ -85,6 +91,7 @@ signals: public slots: void setActive(bool _active); + void onRequestZoneViewToggle(const QString &zoneName, int numberCards, bool isReversed); public: PlayerLogic(const ServerInfo_User &info, int _id, bool _local, bool _judge, AbstractGame *_parent); @@ -112,10 +119,6 @@ public: return game; } - GameScene *getGameScene(); - - [[nodiscard]] PlayerGraphicsItem *getGraphicsItem(); - [[nodiscard]] PlayerActions *getPlayerActions() const { return playerActions; @@ -131,11 +134,6 @@ public: return playerInfo; } - [[nodiscard]] PlayerMenu *getPlayerMenu() const - { - return playerMenu; - } - void setDeck(const DeckList &_deck); [[nodiscard]] const DeckList &getDeck() const @@ -234,8 +232,6 @@ private: PlayerInfo *playerInfo; PlayerEventHandler *playerEventHandler; PlayerActions *playerActions; - PlayerMenu *playerMenu; - PlayerGraphicsItem *graphicsItem; bool active; bool conceded; diff --git a/cockatrice/src/game_graphics/zones/table_zone.cpp b/cockatrice/src/game_graphics/zones/table_zone.cpp index ffb4adf5c..245de8281 100644 --- a/cockatrice/src/game_graphics/zones/table_zone.cpp +++ b/cockatrice/src/game_graphics/zones/table_zone.cpp @@ -22,7 +22,8 @@ const QColor TableZone::FADE_MASK = QColor(0, 0, 0, 80); const QColor TableZone::GRADIENT_COLOR = QColor(255, 255, 255, 150); const QColor TableZone::GRADIENT_COLORLESS = QColor(255, 255, 255, 0); -TableZone::TableZone(TableZoneLogic *_logic, QGraphicsItem *parent) : SelectZone(_logic, parent), active(false) +TableZone::TableZone(TableZoneLogic *_logic, bool _mirrored, QGraphicsItem *parent) + : SelectZone(_logic, parent), active(false), mirrored(_mirrored) { connect(_logic, &TableZoneLogic::contentSizeChanged, this, &TableZone::resizeToContents); connect(_logic, &TableZoneLogic::toggleTapped, this, &TableZone::toggleTapped); @@ -50,12 +51,16 @@ QRectF TableZone::boundingRect() const return QRectF(0, 0, width, height); } +void TableZone::setMirrored(bool isMirrored) +{ + mirrored = isMirrored; + update(); +} + bool TableZone::isInverted() const { - return ((getLogic()->getPlayer()->getGraphicsItem()->getMirrored() && - !SettingsCache::instance().getInvertVerticalCoordinate()) || - (!getLogic()->getPlayer()->getGraphicsItem()->getMirrored() && - SettingsCache::instance().getInvertVerticalCoordinate())); + return ((mirrored && !SettingsCache::instance().getInvertVerticalCoordinate()) || + (!mirrored && SettingsCache::instance().getInvertVerticalCoordinate())); } void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) diff --git a/cockatrice/src/game_graphics/zones/table_zone.h b/cockatrice/src/game_graphics/zones/table_zone.h index f46531520..8a898173b 100644 --- a/cockatrice/src/game_graphics/zones/table_zone.h +++ b/cockatrice/src/game_graphics/zones/table_zone.h @@ -82,6 +82,7 @@ private: If this TableZone is currently active */ bool active = false; + bool mirrored = false; [[nodiscard]] bool isInverted() const; @@ -96,6 +97,7 @@ public slots: Reorganizes CardItems in the TableZone */ void reorganizeCards() override; + void setMirrored(bool isMirrored); public: /** @@ -104,7 +106,7 @@ public: @param _p the Player @param parent defaults to null */ - explicit TableZone(TableZoneLogic *_logic, QGraphicsItem *parent = nullptr); + explicit TableZone(TableZoneLogic *_logic, bool mirrored, QGraphicsItem *parent = nullptr); /** @return a QRectF of the TableZone bounding box. diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.cpp b/cockatrice/src/interface/widgets/tabs/tab_game.cpp index c52f73319..1e2bebd15 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_game.cpp @@ -1,6 +1,7 @@ #include "tab_game.h" #include "../../../client/settings/cache_settings.h" +#include "../../../game/player/menu/card_menu.h" #include "../game/board/arrow_item.h" #include "../game/board/card_item.h" #include "../game/deckview/deck_view_container.h" @@ -363,11 +364,10 @@ void TabGame::retranslateUi() cardInfoFrameWidget->retranslateUi(); - QMapIterator i(game->getPlayerManager()->getPlayers()); - - while (i.hasNext()) { - i.next().value()->getGraphicsItem()->retranslateUi(); + for (auto playerView : scene->getPlayers().values()) { + playerView->retranslateUi(); } + QMapIterator j(deckViewContainers); while (j.hasNext()) { j.next().value()->playerDeckView->retranslateUi(); @@ -654,8 +654,12 @@ PlayerLogic *TabGame::addPlayer(PlayerLogic *newPlayer) scene->addPlayer(newPlayer); + auto *view = scene->viewForPlayer(newPlayer->getPlayerInfo()->getId()); + connect(newPlayer, &PlayerLogic::newCardAdded, this, &TabGame::newCardAdded); - connect(newPlayer->getPlayerMenu(), &PlayerMenu::cardMenuUpdated, this, &TabGame::setCardMenu); + connect(newPlayer, &PlayerLogic::openDeckEditor, this, &TabGame::openDeckEditor); + connect(view->getPlayerMenu(), &PlayerMenu::cardMenuUpdated, this, &TabGame::setCardMenu); + connect(view, &PlayerGraphicsItem::cardInfoRequested, this, &TabGame::viewCardInfo); messageLog->connectToPlayerEventHandler(newPlayer->getPlayerEventHandler()); @@ -668,7 +672,7 @@ PlayerLogic *TabGame::addPlayer(PlayerLogic *newPlayer) addLocalPlayer(newPlayer, newPlayer->getPlayerInfo()->getId()); } - gameMenu->insertMenu(playersSeparator, newPlayer->getPlayerMenu()->getPlayerMenu()); + gameMenu->insertMenu(playersSeparator, view->getPlayerMenu()->getPlayerMenu()); createZoneForPlayer(newPlayer, newPlayer->getPlayerInfo()->getId()); @@ -678,7 +682,7 @@ PlayerLogic *TabGame::addPlayer(PlayerLogic *newPlayer) void TabGame::addLocalPlayer(PlayerLogic *newPlayer, int playerId) { if (game->getGameState()->getClients().size() == 1) { - newPlayer->getPlayerMenu()->setShortcutsActive(); + scene->viewForPlayer(playerId)->getPlayerMenu()->setShortcutsActive(); } auto *deckView = new TabbedDeckViewContainer(playerId, this); @@ -698,27 +702,24 @@ void TabGame::addLocalPlayer(PlayerLogic *newPlayer, int playerId) void TabGame::processPlayerLeave(PlayerLogic *leavingPlayer) { - QString playerName = "@" + leavingPlayer->getPlayerInfo()->getName(); - removePlayerFromAutoCompleteList(playerName); - - scene->removePlayer(leavingPlayer); + removePlayerFromAutoCompleteList("@" + leavingPlayer->getPlayerInfo()->getName()); // When we inserted the playerMenu into the gameMenu earlier, Qt wrapped the playerMenu into a QAction*, which lives // independently and does not get cleaned up when the source menu gets destroyed. We have to manually clean here. - if (leavingPlayer->getPlayerMenu()) { - QMenu *menu = leavingPlayer->getPlayerMenu()->getPlayerMenu(); - if (menu) { - // Find and remove the QAction pointing to this menu - QList actions = gameMenu->actions(); - for (QAction *act : actions) { - if (act->menu() == menu) { - gameMenu->removeAction(act); - delete act; // deletes the QAction wrapper around the submenu - break; - } + auto *view = scene->viewForPlayer(leavingPlayer->getPlayerInfo()->getId()); + if (view) { + // Find and remove the QAction pointing to this menu + QMenu *menu = view->getPlayerMenu()->getPlayerMenu(); + for (QAction *act : gameMenu->actions()) { + if (act->menu() == menu) { + gameMenu->removeAction(act); + delete act; + break; } } } + + scene->removePlayer(leavingPlayer); } void TabGame::processRemotePlayerDeckSelect(QString deckList, int playerId, QString playerName) @@ -869,12 +870,12 @@ PlayerLogic *TabGame::setActivePlayer(int id) if (i.value() == player) { i.value()->setActive(true); if (game->getGameState()->getClients().size() > 1) { - i.value()->getPlayerMenu()->setShortcutsActive(); + scene->viewForPlayer(i.value()->getPlayerInfo()->getId())->getPlayerMenu()->setShortcutsActive(); } } else { i.value()->setActive(false); if (game->getGameState()->getClients().size() > 1) { - i.value()->getPlayerMenu()->setShortcutsInactive(); + scene->viewForPlayer(i.value()->getPlayerInfo()->getId())->getPlayerMenu()->setShortcutsInactive(); } } } @@ -890,8 +891,13 @@ void TabGame::setActivePhase(int phase) void TabGame::newCardAdded(AbstractCardItem *card) { + connect(card, &AbstractCardItem::rightClicked, scene, &GameScene::onCardRightClicked); + connect(card, &AbstractCardItem::playSelected, scene, &GameScene::playSelected); + connect(card, &AbstractCardItem::playSelectedFaceDown, scene, &GameScene::playSelectedFaceDown); + connect(card, &AbstractCardItem::hideSelected, scene, &GameScene::hideSelected); connect(card, &AbstractCardItem::hovered, cardInfoFrameWidget, qOverload(&CardInfoFrameWidget::setCard)); + connect(card, &AbstractCardItem::selectionChanged, scene, &GameScene::onCardSelectionChanged); connect(card, &AbstractCardItem::showCardInfoPopup, this, &TabGame::showCardInfoPopup); connect(card, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString))); connect(card, &AbstractCardItem::cardShiftClicked, this, &TabGame::linkCardToChat); @@ -935,7 +941,7 @@ QString TabGame::getTabText() const /** * @param menu The menu to set. Pass in nullptr to set the menu to empty. */ -void TabGame::setCardMenu(QMenu *menu) +void TabGame::setCardMenu(CardMenu *menu) { if (!aCardMenu) { return; diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.h b/cockatrice/src/interface/widgets/tabs/tab_game.h index 7f9392034..ddda4d9b9 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.h +++ b/cockatrice/src/interface/widgets/tabs/tab_game.h @@ -141,7 +141,7 @@ signals: private slots: void adminLockChanged(bool lock); void newCardAdded(AbstractCardItem *card); - void setCardMenu(QMenu *menu); + void setCardMenu(CardMenu *menu); void actGameInfo(); void actConcede(); From 487bb84b6f4473f230871461f4a1bae0de5edc46 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Tue, 9 Jun 2026 08:07:06 +0200 Subject: [PATCH 05/17] [Game][Menus] Make Menus accept PlayerGraphicsItem instead of PlayerLogic (#6945) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Game][Player] Split Player into PlayerLogic/PlayerGraphicsItem Took 4 minutes Took 58 seconds Took 2 minutes * [Game][Menus] Make Menus accept PlayerGraphicsItem instead of PlayerLogic Took 7 minutes Took 4 minutes Took 9 seconds Took 2 minutes Took 5 minutes Took 58 seconds --------- Co-authored-by: Lukas Brübach --- cockatrice/src/game/board/card_item.cpp | 1 + cockatrice/src/game/player/menu/card_menu.cpp | 1 + .../src/game/player/menu/grave_menu.cpp | 18 +++--- cockatrice/src/game/player/menu/grave_menu.h | 6 +- cockatrice/src/game/player/menu/hand_menu.cpp | 26 +++++---- cockatrice/src/game/player/menu/hand_menu.h | 6 +- .../src/game/player/menu/library_menu.cpp | 55 +++++++++++-------- .../src/game/player/menu/library_menu.h | 5 +- .../src/game/player/menu/player_menu.cpp | 12 ++-- cockatrice/src/game/player/menu/rfg_menu.cpp | 12 ++-- cockatrice/src/game/player/menu/rfg_menu.h | 6 +- cockatrice/src/game/player/menu/say_menu.cpp | 4 +- cockatrice/src/game/player/menu/say_menu.h | 6 +- .../src/game/player/menu/sideboard_menu.cpp | 7 ++- .../src/game/player/menu/sideboard_menu.h | 6 +- 15 files changed, 93 insertions(+), 78 deletions(-) diff --git a/cockatrice/src/game/board/card_item.cpp b/cockatrice/src/game/board/card_item.cpp index 16197ae16..029822805 100644 --- a/cockatrice/src/game/board/card_item.cpp +++ b/cockatrice/src/game/board/card_item.cpp @@ -476,6 +476,7 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::RightButton && owner != nullptr) { emit rightClicked(this, event->screenPos()); + return; } if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) && (!SettingsCache::instance().getDoubleClickToPlay())) { diff --git a/cockatrice/src/game/player/menu/card_menu.cpp b/cockatrice/src/game/player/menu/card_menu.cpp index ba925afb0..150c1c587 100644 --- a/cockatrice/src/game/player/menu/card_menu.cpp +++ b/cockatrice/src/game/player/menu/card_menu.cpp @@ -6,6 +6,7 @@ #include "../../zones/view_zone_logic.h" #include "../card_menu_action_type.h" #include "../player_actions.h" +#include "../player_graphics_item.h" #include "../player_logic.h" #include "move_menu.h" #include "pt_menu.h" diff --git a/cockatrice/src/game/player/menu/grave_menu.cpp b/cockatrice/src/game/player/menu/grave_menu.cpp index 16a5858ca..45762e900 100644 --- a/cockatrice/src/game/player/menu/grave_menu.cpp +++ b/cockatrice/src/game/player/menu/grave_menu.cpp @@ -8,14 +8,14 @@ #include #include -GraveyardMenu::GraveyardMenu(PlayerLogic *_player, QWidget *parent) : TearOffMenu(parent), player(_player) +GraveyardMenu::GraveyardMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player) { createMoveActions(); createViewActions(); addAction(aViewGraveyard); - if (player->getPlayerInfo()->local || player->getPlayerInfo()->judge) { + if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) { mRevealRandomGraveyardCard = addMenu(QString()); connect(mRevealRandomGraveyardCard, &QMenu::aboutToShow, this, &GraveyardMenu::populateRevealRandomMenuWithActivePlayers); @@ -36,9 +36,9 @@ GraveyardMenu::GraveyardMenu(PlayerLogic *_player, QWidget *parent) : TearOffMen void GraveyardMenu::createMoveActions() { - auto grave = player->getGraveZone(); + auto grave = player->getLogic()->getGraveZone(); - if (player->getPlayerInfo()->local || player->getPlayerInfo()->judge) { + if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) { aMoveGraveToTopLibrary = new QAction(this); aMoveGraveToTopLibrary->setData(QList() << ZoneNames::DECK << 0); @@ -60,7 +60,7 @@ void GraveyardMenu::createMoveActions() void GraveyardMenu::createViewActions() { - PlayerActions *playerActions = player->getPlayerActions(); + PlayerActions *playerActions = player->getLogic()->getPlayerActions(); aViewGraveyard = new QAction(this); connect(aViewGraveyard, &QAction::triggered, playerActions, &PlayerActions::actViewGraveyard); @@ -76,9 +76,9 @@ void GraveyardMenu::populateRevealRandomMenuWithActivePlayers() mRevealRandomGraveyardCard->addSeparator(); - const auto &players = player->getGame()->getPlayerManager()->getPlayers().values(); + const auto &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); for (auto *other : players) { - if (other == player) { + if (other == player->getLogic()) { continue; } QAction *a = mRevealRandomGraveyardCard->addAction(other->getPlayerInfo()->getName()); @@ -90,7 +90,7 @@ void GraveyardMenu::populateRevealRandomMenuWithActivePlayers() void GraveyardMenu::onRevealRandomTriggered() { if (auto *a = qobject_cast(sender())) { - player->getPlayerActions()->actRevealRandomGraveyardCard(a->data().toInt()); + player->getLogic()->getPlayerActions()->actRevealRandomGraveyardCard(a->data().toInt()); } } @@ -100,7 +100,7 @@ void GraveyardMenu::retranslateUi() aViewGraveyard->setText(tr("&View graveyard")); - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { moveGraveMenu->setTitle(tr("&Move graveyard to...")); aMoveGraveToTopLibrary->setText(tr("&Top of library")); aMoveGraveToBottomLibrary->setText(tr("&Bottom of library")); diff --git a/cockatrice/src/game/player/menu/grave_menu.h b/cockatrice/src/game/player/menu/grave_menu.h index d3d98802d..116261e9b 100644 --- a/cockatrice/src/game/player/menu/grave_menu.h +++ b/cockatrice/src/game/player/menu/grave_menu.h @@ -13,7 +13,7 @@ #include #include -class PlayerLogic; +class PlayerGraphicsItem; class GraveyardMenu : public TearOffMenu, public AbstractPlayerComponent { Q_OBJECT @@ -21,7 +21,7 @@ signals: void newPlayerActionCreated(QAction *action); public: - explicit GraveyardMenu(PlayerLogic *player, QWidget *parent = nullptr); + explicit GraveyardMenu(PlayerGraphicsItem *player, QWidget *parent = nullptr); void createMoveActions(); void createViewActions(); void populateRevealRandomMenuWithActivePlayers(); @@ -40,7 +40,7 @@ public: QAction *aMoveGraveToRfg = nullptr; private: - PlayerLogic *player; + PlayerGraphicsItem *player; }; #endif // COCKATRICE_GRAVE_MENU_H diff --git a/cockatrice/src/game/player/menu/hand_menu.cpp b/cockatrice/src/game/player/menu/hand_menu.cpp index 6ff177655..60899a27a 100644 --- a/cockatrice/src/game/player/menu/hand_menu.cpp +++ b/cockatrice/src/game/player/menu/hand_menu.cpp @@ -5,16 +5,20 @@ #include "../../../game_graphics/zones/hand_zone.h" #include "../../abstract_game.h" #include "../player_actions.h" +#include "../player_graphics_item.h" #include "../player_logic.h" #include #include #include -HandMenu::HandMenu(PlayerLogic *_player, PlayerActions *actions, QWidget *parent) : TearOffMenu(parent), player(_player) +HandMenu::HandMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player) { - if (player->getPlayerInfo()->local || player->getPlayerInfo()->judge) { + auto *actions = player->getLogic()->getPlayerActions(); + + if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) { aViewHand = new QAction(this); + connect(aViewHand, &QAction::triggered, actions, &PlayerActions::actViewHand); addAction(aViewHand); @@ -75,7 +79,7 @@ HandMenu::HandMenu(PlayerLogic *_player, PlayerActions *actions, QWidget *parent mMoveHandMenu = addTearOffMenu(QString()); - if (player->getPlayerInfo()->local || player->getPlayerInfo()->judge) { + if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) { aMoveHandToTopLibrary = new QAction(this); aMoveHandToTopLibrary->setData(QList() << ZoneNames::DECK << 0); aMoveHandToBottomLibrary = new QAction(this); @@ -85,7 +89,7 @@ HandMenu::HandMenu(PlayerLogic *_player, PlayerActions *actions, QWidget *parent aMoveHandToRfg = new QAction(this); aMoveHandToRfg->setData(QList() << ZoneNames::EXILE << 0); - auto hand = player->getHandZone(); + auto hand = player->getLogic()->getHandZone(); connect(aMoveHandToTopLibrary, &QAction::triggered, hand, &HandZoneLogic::moveAllToZone); connect(aMoveHandToBottomLibrary, &QAction::triggered, hand, &HandZoneLogic::moveAllToZone); @@ -107,7 +111,7 @@ void HandMenu::retranslateUi() { setTitle(tr("&Hand")); - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { aViewHand->setText(tr("&View hand")); mSortHand->setTitle(tr("Sort hand by...")); @@ -166,9 +170,9 @@ void HandMenu::populateRevealHandMenuWithActivePlayers() mRevealHand->addSeparator(); - const auto &players = player->getGame()->getPlayerManager()->getPlayers().values(); + const auto &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); for (auto *other : players) { - if (other == player) { + if (other == player->getLogic()) { continue; } QAction *a = mRevealHand->addAction(other->getPlayerInfo()->getName()); @@ -185,9 +189,9 @@ void HandMenu::populateRevealRandomHandCardMenuWithActivePlayers() mRevealRandomHandCard->addSeparator(); - const auto &players = player->getGame()->getPlayerManager()->getPlayers().values(); + const auto &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); for (auto *other : players) { - if (other == player) { + if (other == player->getLogic()) { continue; } QAction *a = mRevealRandomHandCard->addAction(other->getPlayerInfo()->getName()); @@ -204,7 +208,7 @@ void HandMenu::onRevealHandTriggered() } const int targetId = action->data().toInt(); - player->getPlayerActions()->actRevealHand(targetId); + player->getLogic()->getPlayerActions()->actRevealHand(targetId); } void HandMenu::onRevealRandomHandCardTriggered() @@ -215,5 +219,5 @@ void HandMenu::onRevealRandomHandCardTriggered() } const int targetId = action->data().toInt(); - player->getPlayerActions()->actRevealRandomHandCard(targetId); + player->getLogic()->getPlayerActions()->actRevealRandomHandCard(targetId); } diff --git a/cockatrice/src/game/player/menu/hand_menu.h b/cockatrice/src/game/player/menu/hand_menu.h index 1e2ddd95a..d5204612b 100644 --- a/cockatrice/src/game/player/menu/hand_menu.h +++ b/cockatrice/src/game/player/menu/hand_menu.h @@ -13,7 +13,7 @@ #include #include -class PlayerLogic; +class PlayerGraphicsItem; class PlayerActions; class HandMenu : public TearOffMenu, public AbstractPlayerComponent @@ -21,7 +21,7 @@ class HandMenu : public TearOffMenu, public AbstractPlayerComponent Q_OBJECT public: - HandMenu(PlayerLogic *player, PlayerActions *actions, QWidget *parent = nullptr); + HandMenu(PlayerGraphicsItem *player, QWidget *parent = nullptr); QMenu *revealHandMenu() const { @@ -43,7 +43,7 @@ private slots: void onRevealRandomHandCardTriggered(); private: - PlayerLogic *player; + PlayerGraphicsItem *player; QAction *aViewHand = nullptr; QAction *aMulligan = nullptr; diff --git a/cockatrice/src/game/player/menu/library_menu.cpp b/cockatrice/src/game/player/menu/library_menu.cpp index 8449af05a..cdc45ed7c 100644 --- a/cockatrice/src/game/player/menu/library_menu.cpp +++ b/cockatrice/src/game/player/menu/library_menu.cpp @@ -8,9 +8,10 @@ #include "../player_logic.h" #include +#include #include -LibraryMenu::LibraryMenu(PlayerLogic *_player, QWidget *parent) : TearOffMenu(parent), player(_player) +LibraryMenu::LibraryMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player) { createDrawActions(); createShuffleActions(); @@ -75,8 +76,8 @@ LibraryMenu::LibraryMenu(PlayerLogic *_player, QWidget *parent) : TearOffMenu(pa bottomLibraryMenu->addSeparator(); bottomLibraryMenu->addAction(aShuffleBottomCards); - connect(player, &PlayerLogic::resetTopCardMenuActions, this, &LibraryMenu::resetTopCardMenuActions); - connect(player, &PlayerLogic::deckChanged, this, &LibraryMenu::enableOpenInDeckEditorAction); + connect(player->getLogic(), &PlayerLogic::resetTopCardMenuActions, this, &LibraryMenu::resetTopCardMenuActions); + connect(player->getLogic(), &PlayerLogic::deckChanged, this, &LibraryMenu::enableOpenInDeckEditorAction); retranslateUi(); } @@ -94,9 +95,9 @@ void LibraryMenu::resetTopCardMenuActions() void LibraryMenu::createDrawActions() { - PlayerActions *playerActions = player->getPlayerActions(); + PlayerActions *playerActions = player->getLogic()->getPlayerActions(); - if (player->getPlayerInfo()->local || player->getPlayerInfo()->judge) { + if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) { aDrawCard = new QAction(this); connect(aDrawCard, &QAction::triggered, playerActions, &PlayerActions::actDrawCard); aDrawCards = new QAction(this); @@ -112,9 +113,9 @@ void LibraryMenu::createDrawActions() void LibraryMenu::createShuffleActions() { - PlayerActions *playerActions = player->getPlayerActions(); + PlayerActions *playerActions = player->getLogic()->getPlayerActions(); - if (player->getPlayerInfo()->local || player->getPlayerInfo()->judge) { + if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) { aShuffle = new QAction(this); connect(aShuffle, &QAction::triggered, playerActions, &PlayerActions::actShuffle); aShuffleTopCards = new QAction(this); @@ -126,9 +127,9 @@ void LibraryMenu::createShuffleActions() void LibraryMenu::createMoveActions() { - PlayerActions *playerActions = player->getPlayerActions(); + PlayerActions *playerActions = player->getLogic()->getPlayerActions(); - if (player->getPlayerInfo()->local || player->getPlayerInfo()->judge) { + if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) { aMoveTopToPlay = new QAction(this); connect(aMoveTopToPlay, &QAction::triggered, playerActions, &PlayerActions::actMoveTopCardToPlay); aMoveTopToPlayFaceDown = new QAction(this); @@ -181,9 +182,9 @@ void LibraryMenu::createMoveActions() void LibraryMenu::createViewActions() { - PlayerActions *playerActions = player->getPlayerActions(); + PlayerActions *playerActions = player->getLogic()->getPlayerActions(); - if (player->getPlayerInfo()->local || player->getPlayerInfo()->judge) { + if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) { aViewLibrary = new QAction(this); connect(aViewLibrary, &QAction::triggered, playerActions, &PlayerActions::actViewLibrary); @@ -207,7 +208,7 @@ void LibraryMenu::retranslateUi() { setTitle(tr("&Library")); - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { aViewLibrary->setText(tr("&View library")); aViewTopCards->setText(tr("View &top cards of library...")); aViewBottomCards->setText(tr("View bottom cards of library...")); @@ -263,9 +264,9 @@ void LibraryMenu::populateRevealLibraryMenuWithActivePlayers() mRevealLibrary->addSeparator(); - const auto &players = player->getGame()->getPlayerManager()->getPlayers().values(); + const auto &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); for (auto *other : players) { - if (other == player) { + if (other == player->getLogic()) { continue; } QAction *a = mRevealLibrary->addAction(other->getPlayerInfo()->getName()); @@ -278,9 +279,9 @@ void LibraryMenu::populateLendLibraryMenuWithActivePlayers() { mLendLibrary->clear(); - const auto &players = player->getGame()->getPlayerManager()->getPlayers().values(); + const auto &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); for (auto *other : players) { - if (other == player) { + if (other == player->getLogic()) { continue; } QAction *a = mLendLibrary->addAction(other->getPlayerInfo()->getName()); @@ -299,9 +300,9 @@ void LibraryMenu::populateRevealTopCardMenuWithActivePlayers() mRevealTopCard->addSeparator(); - const auto &players = player->getGame()->getPlayerManager()->getPlayers().values(); + const auto &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); for (auto *other : players) { - if (other == player) { + if (other == player->getLogic()) { continue; } QAction *a = mRevealTopCard->addAction(other->getPlayerInfo()->getName()); @@ -313,27 +314,33 @@ void LibraryMenu::populateRevealTopCardMenuWithActivePlayers() void LibraryMenu::onRevealLibraryTriggered() { if (auto *a = qobject_cast(sender())) { - player->getPlayerActions()->actRevealLibrary(a->data().toInt()); + player->getLogic()->getPlayerActions()->actRevealLibrary(a->data().toInt()); } } void LibraryMenu::onLendLibraryTriggered() { if (auto *a = qobject_cast(sender())) { - player->getPlayerActions()->actLendLibrary(a->data().toInt()); + player->getLogic()->getPlayerActions()->actLendLibrary(a->data().toInt()); } } void LibraryMenu::onRevealTopCardTriggered() { + QWidget *parent = nullptr; + if (auto *view = player->scene() ? player->scene()->views().value(0) : nullptr) { + parent = view->window(); + } if (auto *a = qobject_cast(sender())) { - int deckSize = player->getDeckZone()->getCards().size(); - bool ok; - int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Reveal top cards of library"), + + int deckSize = player->getLogic()->getDeckZone()->getCards().size(); + bool ok = true; + int number = QInputDialog::getInt(parent, tr("Reveal top cards of library"), tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberTopCards, 1, deckSize, 1, &ok); + if (ok) { - player->getPlayerActions()->actRevealTopCards(a->data().toInt(), number); + player->getLogic()->getPlayerActions()->actRevealTopCards(a->data().toInt(), number); defaultNumberTopCards = number; } } diff --git a/cockatrice/src/game/player/menu/library_menu.h b/cockatrice/src/game/player/menu/library_menu.h index a941c54b1..bc0e6fb8e 100644 --- a/cockatrice/src/game/player/menu/library_menu.h +++ b/cockatrice/src/game/player/menu/library_menu.h @@ -13,6 +13,7 @@ #include #include +class PlayerGraphicsItem; class PlayerLogic; class PlayerActions; @@ -24,7 +25,7 @@ public slots: void resetTopCardMenuActions(); public: - LibraryMenu(PlayerLogic *player, QWidget *parent = nullptr); + LibraryMenu(PlayerGraphicsItem *player, QWidget *parent = nullptr); void createDrawActions(); void createShuffleActions(); void createMoveActions(); @@ -111,7 +112,7 @@ public: int defaultNumberTopCards = 1; private: - PlayerLogic *player; + PlayerGraphicsItem *player; }; #endif // COCKATRICE_LIBRARY_MENU_H diff --git a/cockatrice/src/game/player/menu/player_menu.cpp b/cockatrice/src/game/player/menu/player_menu.cpp index 6687bbba8..041b41052 100644 --- a/cockatrice/src/game/player/menu/player_menu.cpp +++ b/cockatrice/src/game/player/menu/player_menu.cpp @@ -18,18 +18,18 @@ PlayerMenu::PlayerMenu(PlayerGraphicsItem *_player) : QObject(_player), player(_ playerMenu = new TearOffMenu(); if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { - handMenu = addManagedMenu(player->getLogic(), player->getLogic()->getPlayerActions(), playerMenu); - libraryMenu = addManagedMenu(player->getLogic(), playerMenu); + handMenu = addManagedMenu(player, playerMenu); + libraryMenu = addManagedMenu(player, playerMenu); } else { handMenu = nullptr; libraryMenu = nullptr; } - graveMenu = addManagedMenu(player->getLogic(), playerMenu); - rfgMenu = addManagedMenu(player->getLogic(), playerMenu); + graveMenu = addManagedMenu(player, playerMenu); + rfgMenu = addManagedMenu(player, playerMenu); if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { - sideboardMenu = addManagedMenu(player->getLogic(), playerMenu); + sideboardMenu = addManagedMenu(player, playerMenu); customZonesMenu = addManagedMenu(player); playerMenu->addSeparator(); @@ -44,7 +44,7 @@ PlayerMenu::PlayerMenu(PlayerGraphicsItem *_player) : QObject(_player), player(_ } if (player->getLogic()->getPlayerInfo()->getLocal()) { - sayMenu = addManagedMenu(player->getLogic()); + sayMenu = addManagedMenu(player); } else { sayMenu = nullptr; } diff --git a/cockatrice/src/game/player/menu/rfg_menu.cpp b/cockatrice/src/game/player/menu/rfg_menu.cpp index e8aca00cb..79fdebf48 100644 --- a/cockatrice/src/game/player/menu/rfg_menu.cpp +++ b/cockatrice/src/game/player/menu/rfg_menu.cpp @@ -5,14 +5,14 @@ #include -RfgMenu::RfgMenu(PlayerLogic *_player, QWidget *parent) : TearOffMenu(parent), player(_player) +RfgMenu::RfgMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player) { createMoveActions(); createViewActions(); addAction(aViewRfg); - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { addSeparator(); moveRfgMenu = addTearOffMenu(QString()); moveRfgMenu->addAction(aMoveRfgToTopLibrary); @@ -28,8 +28,8 @@ RfgMenu::RfgMenu(PlayerLogic *_player, QWidget *parent) : TearOffMenu(parent), p void RfgMenu::createMoveActions() { - if (player->getPlayerInfo()->getLocalOrJudge()) { - auto rfg = player->getRfgZone(); + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { + auto rfg = player->getLogic()->getRfgZone(); aMoveRfgToTopLibrary = new QAction(this); aMoveRfgToTopLibrary->setData(QList() << ZoneNames::DECK << 0); @@ -49,7 +49,7 @@ void RfgMenu::createMoveActions() void RfgMenu::createViewActions() { - PlayerActions *playerActions = player->getPlayerActions(); + PlayerActions *playerActions = player->getLogic()->getPlayerActions(); aViewRfg = new QAction(this); connect(aViewRfg, &QAction::triggered, playerActions, &PlayerActions::actViewRfg); @@ -61,7 +61,7 @@ void RfgMenu::retranslateUi() aViewRfg->setText(tr("&View exile")); - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { moveRfgMenu->setTitle(tr("&Move exile to...")); aMoveRfgToTopLibrary->setText(tr("&Top of library")); aMoveRfgToBottomLibrary->setText(tr("&Bottom of library")); diff --git a/cockatrice/src/game/player/menu/rfg_menu.h b/cockatrice/src/game/player/menu/rfg_menu.h index 9e179f8fd..f5dd888e4 100644 --- a/cockatrice/src/game/player/menu/rfg_menu.h +++ b/cockatrice/src/game/player/menu/rfg_menu.h @@ -13,12 +13,12 @@ #include #include -class PlayerLogic; +class PlayerGraphicsItem; class RfgMenu : public TearOffMenu, public AbstractPlayerComponent { Q_OBJECT public: - explicit RfgMenu(PlayerLogic *player, QWidget *parent = nullptr); + explicit RfgMenu(PlayerGraphicsItem *player, QWidget *parent = nullptr); void createMoveActions(); void createViewActions(); void retranslateUi() override; @@ -38,7 +38,7 @@ public: QAction *aMoveRfgToGrave = nullptr; private: - PlayerLogic *player; + PlayerGraphicsItem *player; }; #endif // COCKATRICE_RFG_MENU_H diff --git a/cockatrice/src/game/player/menu/say_menu.cpp b/cockatrice/src/game/player/menu/say_menu.cpp index a2d5ab982..58bbd33aa 100644 --- a/cockatrice/src/game/player/menu/say_menu.cpp +++ b/cockatrice/src/game/player/menu/say_menu.cpp @@ -4,7 +4,7 @@ #include "../player_actions.h" #include "../player_logic.h" -SayMenu::SayMenu(PlayerLogic *_player) : player(_player) +SayMenu::SayMenu(PlayerGraphicsItem *_player) : player(_player) { connect(&SettingsCache::instance().messages(), &MessageSettings::messageMacrosChanged, this, &SayMenu::initSayMenu); initSayMenu(); @@ -44,7 +44,7 @@ void SayMenu::initSayMenu() for (int i = 0; i < count; ++i) { auto *newAction = new QAction(SettingsCache::instance().messages().getMessageAt(i), this); - connect(newAction, &QAction::triggered, player->getPlayerActions(), &PlayerActions::actSayMessage); + connect(newAction, &QAction::triggered, player->getLogic()->getPlayerActions(), &PlayerActions::actSayMessage); addAction(newAction); } diff --git a/cockatrice/src/game/player/menu/say_menu.h b/cockatrice/src/game/player/menu/say_menu.h index 3de70e85c..3ff160d05 100644 --- a/cockatrice/src/game/player/menu/say_menu.h +++ b/cockatrice/src/game/player/menu/say_menu.h @@ -11,12 +11,12 @@ #include -class PlayerLogic; +class PlayerGraphicsItem; class SayMenu : public QMenu, public AbstractPlayerComponent { Q_OBJECT public: - explicit SayMenu(PlayerLogic *player); + explicit SayMenu(PlayerGraphicsItem *player); void retranslateUi() override; void setShortcutsActive() override; @@ -26,7 +26,7 @@ private slots: void initSayMenu(); private: - PlayerLogic *player; + PlayerGraphicsItem *player; bool shortcutsActive = false; }; diff --git a/cockatrice/src/game/player/menu/sideboard_menu.cpp b/cockatrice/src/game/player/menu/sideboard_menu.cpp index f88625a1f..27b50b570 100644 --- a/cockatrice/src/game/player/menu/sideboard_menu.cpp +++ b/cockatrice/src/game/player/menu/sideboard_menu.cpp @@ -3,12 +3,13 @@ #include "../player_actions.h" #include "../player_logic.h" -SideboardMenu::SideboardMenu(PlayerLogic *player, QMenu *playerMenu) : QMenu(playerMenu) +SideboardMenu::SideboardMenu(PlayerGraphicsItem *player, QMenu *playerMenu) : QMenu(playerMenu) { aViewSideboard = new QAction(this); - connect(aViewSideboard, &QAction::triggered, player->getPlayerActions(), &PlayerActions::actViewSideboard); + connect(aViewSideboard, &QAction::triggered, player->getLogic()->getPlayerActions(), + &PlayerActions::actViewSideboard); - if (player->getPlayerInfo()->getLocalOrJudge()) { + if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { addAction(aViewSideboard); } diff --git a/cockatrice/src/game/player/menu/sideboard_menu.h b/cockatrice/src/game/player/menu/sideboard_menu.h index 20a206782..b3b547291 100644 --- a/cockatrice/src/game/player/menu/sideboard_menu.h +++ b/cockatrice/src/game/player/menu/sideboard_menu.h @@ -11,19 +11,19 @@ #include -class PlayerLogic; +class PlayerGraphicsItem; class SideboardMenu : public QMenu, public AbstractPlayerComponent { Q_OBJECT public: - explicit SideboardMenu(PlayerLogic *player, QMenu *playerMenu); + explicit SideboardMenu(PlayerGraphicsItem *player, QMenu *playerMenu); void retranslateUi() override; void setShortcutsActive() override; void setShortcutsInactive() override; private: - PlayerLogic *player; + PlayerGraphicsItem *player; QAction *aViewSideboard; }; From cbfd28690842eb4348a38889ac83ad3b07cc7c91 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Tue, 9 Jun 2026 08:22:59 +0200 Subject: [PATCH 06/17] [Game][Player] Move dialog creation out of player_actions and into player_dialogs (#6946) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Game][Player] Split Player into PlayerLogic/PlayerGraphicsItem Took 4 minutes Took 48 seconds Took 2 minutes * Drop early return. Took 1 hour 13 minutes Took 2 minutes Took 1 minute Took 24 seconds * [Game][Player] Split Player into PlayerLogic/PlayerGraphicsItem Took 4 minutes Took 58 seconds * [Game][Menus] Make Menus accept PlayerGraphicsItem instead of PlayerLogic Took 7 minutes Took 4 minutes Took 9 seconds Took 2 minutes Took 5 minutes Took 58 seconds * [Game][Player] Split Player into PlayerLogic/PlayerGraphicsItem Took 4 minutes Took 2 minutes * [Game][Menus] Make Menus accept PlayerGraphicsItem instead of PlayerLogic Took 7 minutes Took 1 minute Took 57 seconds * [Game][Player] Move dialog creation out of player_actions and into player_dialogs Took 3 minutes Took 1 second * Fix typo. Took 5 minutes * Addressed comments. Took 16 minutes Took 11 seconds * Reintroduce clearCardsToDelete check. Took 3 minutes * Capture cards before semaphore. Took 1 minute --------- Co-authored-by: Lukas Brübach --- cockatrice/CMakeLists.txt | 1 + cockatrice/src/game/player/menu/card_menu.cpp | 4 +- cockatrice/src/game/player/menu/hand_menu.cpp | 2 +- .../src/game/player/menu/library_menu.cpp | 15 +- cockatrice/src/game/player/menu/move_menu.cpp | 5 +- cockatrice/src/game/player/menu/pt_menu.cpp | 2 +- .../src/game/player/menu/utility_menu.cpp | 7 +- cockatrice/src/game/player/player_actions.cpp | 410 +++++++++--------- cockatrice/src/game/player/player_actions.h | 82 +++- cockatrice/src/game/player/player_dialogs.cpp | 298 +++++++++++++ cockatrice/src/game/player/player_dialogs.h | 62 +++ .../src/game/player/player_graphics_item.cpp | 5 + .../src/game/player/player_graphics_item.h | 2 + 13 files changed, 664 insertions(+), 231 deletions(-) create mode 100644 cockatrice/src/game/player/player_dialogs.cpp create mode 100644 cockatrice/src/game/player/player_dialogs.h diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 028161ee0..f0e363e18 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -100,6 +100,7 @@ set(cockatrice_SOURCES src/game/player/menu/utility_menu.cpp src/game/player/player_actions.cpp src/game/player/player_area.cpp + src/game/player/player_dialogs.cpp src/game/player/player_event_handler.cpp src/game/player/player_graphics_item.cpp src/game/player/player_info.cpp diff --git a/cockatrice/src/game/player/menu/card_menu.cpp b/cockatrice/src/game/player/menu/card_menu.cpp index 150c1c587..c1c33e37d 100644 --- a/cockatrice/src/game/player/menu/card_menu.cpp +++ b/cockatrice/src/game/player/menu/card_menu.cpp @@ -79,7 +79,7 @@ CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _sho // Actions using selection directly aUnattach = makeAction(this, [actions, sel]() { actions->actUnattach(sel()); }); - aSetAnnotation = makeAction(this, [actions, sel]() { actions->actSetAnnotation(sel()); }); + aSetAnnotation = makeAction(this, [actions, sel]() { actions->actRequestSetAnnotationDialog(sel()); }); aPlay = makeAction(this, [actions, sel]() { actions->actPlay(sel()); }); aPlayFacedown = makeAction(this, [actions, sel]() { actions->actPlayFacedown(sel()); }); aHide = makeAction(this, [actions, sel]() { actions->actHide(sel()); }); @@ -115,7 +115,7 @@ CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _sho removeAction->setIcon(circleIcon); aRemoveCounter.append(removeAction); - auto *setAction = makeAction(this, [actions, sel, i]() { actions->actSetCardCounter(sel(), i); }); + auto *setAction = makeAction(this, [actions, sel, i]() { actions->actRequestSetCardCounterDialog(sel(), i); }); setAction->setIcon(circleIcon); aSetCounter.append(setAction); } diff --git a/cockatrice/src/game/player/menu/hand_menu.cpp b/cockatrice/src/game/player/menu/hand_menu.cpp index 60899a27a..64a8c5754 100644 --- a/cockatrice/src/game/player/menu/hand_menu.cpp +++ b/cockatrice/src/game/player/menu/hand_menu.cpp @@ -62,7 +62,7 @@ HandMenu::HandMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(p addSeparator(); aMulligan = new QAction(this); - connect(aMulligan, &QAction::triggered, actions, &PlayerActions::actMulligan); + connect(aMulligan, &QAction::triggered, actions, &PlayerActions::actRequestMulliganDialog); addAction(aMulligan); // Mulligan same size diff --git a/cockatrice/src/game/player/menu/library_menu.cpp b/cockatrice/src/game/player/menu/library_menu.cpp index cdc45ed7c..00ab4592f 100644 --- a/cockatrice/src/game/player/menu/library_menu.cpp +++ b/cockatrice/src/game/player/menu/library_menu.cpp @@ -101,13 +101,13 @@ void LibraryMenu::createDrawActions() aDrawCard = new QAction(this); connect(aDrawCard, &QAction::triggered, playerActions, &PlayerActions::actDrawCard); aDrawCards = new QAction(this); - connect(aDrawCards, &QAction::triggered, playerActions, &PlayerActions::actDrawCards); + connect(aDrawCards, &QAction::triggered, playerActions, &PlayerActions::actRequestDrawCardsDialog); aUndoDraw = new QAction(this); connect(aUndoDraw, &QAction::triggered, playerActions, &PlayerActions::actUndoDraw); aDrawBottomCard = new QAction(this); connect(aDrawBottomCard, &QAction::triggered, playerActions, &PlayerActions::actDrawBottomCard); aDrawBottomCards = new QAction(this); - connect(aDrawBottomCards, &QAction::triggered, playerActions, &PlayerActions::actDrawBottomCards); + connect(aDrawBottomCards, &QAction::triggered, playerActions, &PlayerActions::actRequestDrawBottomCardsDialog); } } @@ -119,9 +119,9 @@ void LibraryMenu::createShuffleActions() aShuffle = new QAction(this); connect(aShuffle, &QAction::triggered, playerActions, &PlayerActions::actShuffle); aShuffleTopCards = new QAction(this); - connect(aShuffleTopCards, &QAction::triggered, playerActions, &PlayerActions::actShuffleTop); + connect(aShuffleTopCards, &QAction::triggered, playerActions, &PlayerActions::actRequestShuffleTopDialog); aShuffleBottomCards = new QAction(this); - connect(aShuffleBottomCards, &QAction::triggered, playerActions, &PlayerActions::actShuffleBottom); + connect(aShuffleBottomCards, &QAction::triggered, playerActions, &PlayerActions::actRequestShuffleBottomDialog); } } @@ -150,7 +150,8 @@ void LibraryMenu::createMoveActions() connect(aMoveTopCardsToExileFaceDown, &QAction::triggered, playerActions, &PlayerActions::actMoveTopCardsToExileFaceDown); aMoveTopCardsUntil = new QAction(this); - connect(aMoveTopCardsUntil, &QAction::triggered, playerActions, &PlayerActions::actMoveTopCardsUntil); + connect(aMoveTopCardsUntil, &QAction::triggered, playerActions, + &PlayerActions::actRequestMoveTopCardsUntilDialog); aMoveTopCardToBottom = new QAction(this); connect(aMoveTopCardToBottom, &QAction::triggered, playerActions, &PlayerActions::actMoveTopCardToBottom); @@ -189,9 +190,9 @@ void LibraryMenu::createViewActions() connect(aViewLibrary, &QAction::triggered, playerActions, &PlayerActions::actViewLibrary); aViewTopCards = new QAction(this); - connect(aViewTopCards, &QAction::triggered, playerActions, &PlayerActions::actViewTopCards); + connect(aViewTopCards, &QAction::triggered, playerActions, &PlayerActions::actRequestViewTopCardsDialog); aViewBottomCards = new QAction(this); - connect(aViewBottomCards, &QAction::triggered, playerActions, &PlayerActions::actViewBottomCards); + connect(aViewBottomCards, &QAction::triggered, playerActions, &PlayerActions::actRequestViewBottomCardsDialog); aAlwaysRevealTopCard = new QAction(this); aAlwaysRevealTopCard->setCheckable(true); connect(aAlwaysRevealTopCard, &QAction::triggered, playerActions, &PlayerActions::actAlwaysRevealTopCard); diff --git a/cockatrice/src/game/player/menu/move_menu.cpp b/cockatrice/src/game/player/menu/move_menu.cpp index 4dfdee432..9997aecf3 100644 --- a/cockatrice/src/game/player/menu/move_menu.cpp +++ b/cockatrice/src/game/player/menu/move_menu.cpp @@ -30,9 +30,8 @@ MoveMenu::MoveMenu(PlayerGraphicsItem *player) : QMenu(tr("Move to")) connect(aMoveToTopLibrary, &QAction::triggered, actions, invoke(cmMoveToTopLibrary)); connect(aMoveToBottomLibrary, &QAction::triggered, actions, invoke(cmMoveToBottomLibrary)); - connect(aMoveToXfromTopOfLibrary, &QAction::triggered, actions, [player]() { - player->getLogic()->getPlayerActions()->actMoveCardXCardsFromTop(player->getGameScene()->selectedCards()); - }); + connect(aMoveToXfromTopOfLibrary, &QAction::triggered, actions, + &PlayerActions::actRequestMoveCardXCardsFromTopDialog); connect(aMoveToTable, &QAction::triggered, actions, invoke(cmMoveToTable)); connect(aMoveToHand, &QAction::triggered, actions, invoke(cmMoveToHand)); connect(aMoveToGraveyard, &QAction::triggered, actions, invoke(cmMoveToGraveyard)); diff --git a/cockatrice/src/game/player/menu/pt_menu.cpp b/cockatrice/src/game/player/menu/pt_menu.cpp index 846256e24..011271385 100644 --- a/cockatrice/src/game/player/menu/pt_menu.cpp +++ b/cockatrice/src/game/player/menu/pt_menu.cpp @@ -33,7 +33,7 @@ PtMenu::PtMenu(PlayerGraphicsItem *player) : QMenu(tr("Power / toughness")) [player, playerActions] { playerActions->actFlowT(player->getGameScene()->selectedCards()); }); aSetPT = new QAction(this); connect(aSetPT, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actSetPT(player->getGameScene()->selectedCards()); }); + [player, playerActions] { playerActions->actRequestSetPTDialog(player->getGameScene()->selectedCards()); }); aResetPT = new QAction(this); connect(aResetPT, &QAction::triggered, playerActions, [player, playerActions] { playerActions->actResetPT(player->getGameScene()->selectedCards()); }); diff --git a/cockatrice/src/game/player/menu/utility_menu.cpp b/cockatrice/src/game/player/menu/utility_menu.cpp index 005b38c3b..9769a029e 100644 --- a/cockatrice/src/game/player/menu/utility_menu.cpp +++ b/cockatrice/src/game/player/menu/utility_menu.cpp @@ -20,14 +20,15 @@ UtilityMenu::UtilityMenu(PlayerGraphicsItem *_player, QMenu *playerMenu) : QMenu connect(aUntapAll, &QAction::triggered, playerActions, &PlayerActions::actUntapAll); aRollDie = new QAction(this); - connect(aRollDie, &QAction::triggered, playerActions, &PlayerActions::actRollDie); + connect(aRollDie, &QAction::triggered, playerActions, &PlayerActions::actRequestRollDieDialog); aFlipCoin = new QAction(this); connect(aFlipCoin, &QAction::triggered, playerActions, &PlayerActions::actFlipCoin); aCreateToken = new QAction(this); - connect(aCreateToken, &QAction::triggered, playerActions, - [this]() { player->getLogic()->getPlayerActions()->actCreateToken(getPredefinedTokens()); }); + connect(aCreateToken, &QAction::triggered, playerActions, [this]() { + player->getLogic()->getPlayerActions()->actRequestCreateTokenDialog(getPredefinedTokens()); + }); aCreateAnotherToken = new QAction(this); connect(aCreateAnotherToken, &QAction::triggered, playerActions, &PlayerActions::actCreateAnotherToken); diff --git a/cockatrice/src/game/player/player_actions.cpp b/cockatrice/src/game/player/player_actions.cpp index 7d58be31a..2b0428dd8 100644 --- a/cockatrice/src/game/player/player_actions.cpp +++ b/cockatrice/src/game/player/player_actions.cpp @@ -5,7 +5,6 @@ #include "../../interface/widgets/tabs/tab_game.h" #include "../../interface/widgets/utility/get_text_with_max.h" #include "../board/card_item.h" -#include "../client/settings/card_counter_settings.h" #include "../dialogs/dlg_move_top_cards_until.h" #include "../dialogs/dlg_roll_dice.h" #include "../zones/view_zone_logic.h" @@ -175,30 +174,26 @@ void PlayerActions::actSortHand() emit requestSortHand(sortOptions + defaultOptions); } -void PlayerActions::actViewTopCards() +void PlayerActions::actRequestViewTopCardsDialog() { - int deckSize = player->getDeckZone()->getCards().size(); - bool ok; - int number = QInputDialog::getInt(player->getGame()->getTab(), tr("View top cards of library"), - tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberTopCards, 1, - deckSize, 1, &ok); - if (ok) { - defaultNumberTopCards = number; - emit requestZoneViewToggle(ZoneNames::DECK, number); - } + emit requestViewTopCardsDialog(defaultNumberTopCards, player->getDeckZone()->getCards().size()); } -void PlayerActions::actViewBottomCards() +void PlayerActions::actViewTopCards(int number) { - int deckSize = player->getDeckZone()->getCards().size(); - bool ok; - int number = QInputDialog::getInt(player->getGame()->getTab(), tr("View bottom cards of library"), - tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberBottomCards, 1, - deckSize, 1, &ok); - if (ok) { - defaultNumberBottomCards = number; - emit requestZoneViewToggle(ZoneNames::DECK, number, true); - } + defaultNumberTopCards = number; + emit requestZoneViewToggle(ZoneNames::DECK, number); +} + +void PlayerActions::actRequestViewBottomCardsDialog() +{ + emit requestViewBottomCardsDialog(defaultNumberBottomCards, player->getDeckZone()->getCards().size()); +} + +void PlayerActions::actViewBottomCards(int number) +{ + defaultNumberBottomCards = number; + emit requestZoneViewToggle(ZoneNames::DECK, number, true); } void PlayerActions::actAlwaysRevealTopCard(bool alwaysRevealTopCard) @@ -244,18 +239,20 @@ void PlayerActions::actShuffle() sendGameCommand(Command_Shuffle()); } -void PlayerActions::actShuffleTop() +void PlayerActions::actRequestShuffleTopDialog() { const int maxCards = player->getDeckZone()->getCards().size(); if (maxCards == 0) { return; } - bool ok; - int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Shuffle top cards of library"), - tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1, - maxCards, 1, &ok); - if (!ok) { + emit requestShuffleTopDialog(defaultNumberTopCards, maxCards); +} + +void PlayerActions::actShuffleTop(int number) +{ + const int maxCards = player->getDeckZone()->getCards().size(); + if (maxCards == 0) { return; } @@ -273,18 +270,20 @@ void PlayerActions::actShuffleTop() sendGameCommand(cmd); } -void PlayerActions::actShuffleBottom() +void PlayerActions::actRequestShuffleBottomDialog() { const int maxCards = player->getDeckZone()->getCards().size(); if (maxCards == 0) { return; } - bool ok; - int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Shuffle bottom cards of library"), - tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1, - maxCards, 1, &ok); - if (!ok) { + emit requestShuffleBottomDialog(defaultNumberBottomCards, maxCards); +} + +void PlayerActions::actShuffleBottom(int number) +{ + const int maxCards = player->getDeckZone()->getCards().size(); + if (maxCards == 0) { return; } @@ -309,21 +308,18 @@ void PlayerActions::actDrawCard() sendGameCommand(cmd); } -void PlayerActions::actMulligan() +void PlayerActions::actRequestMulliganDialog() { int startSize = SettingsCache::instance().getStartingHandSize(); int handSize = player->getHandZone()->getCards().size(); int deckSize = player->getDeckZone()->getCards().size() + handSize; - bool ok; - int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Draw hand"), - tr("Number of cards: (max. %1)").arg(deckSize) + '\n' + - tr("0 and lower are in comparison to current hand size"), - startSize, -handSize, deckSize, 1, &ok); + emit requestMulliganDialog(startSize, handSize, deckSize); +} - if (!ok) { - return; - } +void PlayerActions::actMulligan(int number) +{ + int handSize = player->getHandZone()->getCards().size(); if (number < 1) { number = handSize + number; @@ -357,19 +353,19 @@ void PlayerActions::doMulligan(int number) sendGameCommand(cmd); } -void PlayerActions::actDrawCards() +void PlayerActions::actRequestDrawCardsDialog() { int deckSize = player->getDeckZone()->getCards().size(); - bool ok; - int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Draw cards"), - tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberTopCards, 1, - deckSize, 1, &ok); - if (ok) { - defaultNumberTopCards = number; - Command_DrawCards cmd; - cmd.set_number(static_cast(number)); - sendGameCommand(cmd); - } + + emit requestDrawCardsDialog(defaultNumberTopCards, deckSize); +} + +void PlayerActions::actDrawCards(int number) +{ + defaultNumberTopCards = number; + Command_DrawCards cmd; + cmd.set_number(static_cast(number)); + sendGameCommand(cmd); } void PlayerActions::actUndoDraw() @@ -427,36 +423,40 @@ void PlayerActions::actMoveTopCardToExile() void PlayerActions::actMoveTopCardsToGrave() { - moveTopCardsTo(ZoneNames::GRAVE, tr("grave"), false); + actRequestMoveTopCardsToDialog(ZoneNames::GRAVE, tr("grave"), false); } void PlayerActions::actMoveTopCardsToGraveFaceDown() { - moveTopCardsTo(ZoneNames::GRAVE, tr("grave"), true); + actRequestMoveTopCardsToDialog(ZoneNames::GRAVE, tr("grave"), true); } void PlayerActions::actMoveTopCardsToExile() { - moveTopCardsTo(ZoneNames::EXILE, tr("exile"), false); + actRequestMoveTopCardsToDialog(ZoneNames::EXILE, tr("exile"), false); } void PlayerActions::actMoveTopCardsToExileFaceDown() { - moveTopCardsTo(ZoneNames::EXILE, tr("exile"), true); + actRequestMoveTopCardsToDialog(ZoneNames::EXILE, tr("exile"), true); } -void PlayerActions::moveTopCardsTo(const QString &targetZone, const QString &zoneDisplayName, bool faceDown) +void PlayerActions::actRequestMoveTopCardsToDialog(const QString &targetZone, + const QString &zoneDisplayName, + bool faceDown) { const int maxCards = player->getDeckZone()->getCards().size(); if (maxCards == 0) { return; } - bool ok; - int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Move top cards to %1").arg(zoneDisplayName), - tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1, - maxCards, 1, &ok); - if (!ok) { + emit requestMoveTopCardsToDialog(defaultNumberTopCards, maxCards, targetZone, zoneDisplayName, faceDown); +} + +void PlayerActions::moveTopCardsTo(int number, const QString &targetZone, bool faceDown) +{ + const int maxCards = player->getDeckZone()->getCards().size(); + if (maxCards == 0) { return; } @@ -483,17 +483,16 @@ void PlayerActions::moveTopCardsTo(const QString &targetZone, const QString &zon sendGameCommand(cmd); } -void PlayerActions::actMoveTopCardsUntil() +void PlayerActions::actRequestMoveTopCardsUntilDialog() { stopMoveTopCardsUntil(); - DlgMoveTopCardsUntil dlg(player->getGame()->getTab(), movingCardsUntilOptions); - if (!dlg.exec()) { - return; - } + emit requestMoveTopCardsUntilDialog(movingCardsUntilOptions); +} - auto expr = dlg.getExpr(); - movingCardsUntilOptions = dlg.getOptions(); +void PlayerActions::moveTopCardsUntil(const QString &expr, MoveTopCardsUntilOptions options) +{ + movingCardsUntilOptions = options; if (player->getDeckZone()->getCards().empty()) { stopMoveTopCardsUntil(); @@ -622,36 +621,40 @@ void PlayerActions::actMoveBottomCardToExile() void PlayerActions::actMoveBottomCardsToGrave() { - moveBottomCardsTo(ZoneNames::GRAVE, tr("grave"), false); + actRequestMoveBottomCardsToDialog(ZoneNames::GRAVE, tr("grave"), false); } void PlayerActions::actMoveBottomCardsToGraveFaceDown() { - moveBottomCardsTo(ZoneNames::GRAVE, tr("grave"), true); + actRequestMoveBottomCardsToDialog(ZoneNames::GRAVE, tr("grave"), true); } void PlayerActions::actMoveBottomCardsToExile() { - moveBottomCardsTo(ZoneNames::EXILE, tr("exile"), false); + actRequestMoveBottomCardsToDialog(ZoneNames::EXILE, tr("exile"), false); } void PlayerActions::actMoveBottomCardsToExileFaceDown() { - moveBottomCardsTo(ZoneNames::EXILE, tr("exile"), true); + actRequestMoveBottomCardsToDialog(ZoneNames::EXILE, tr("exile"), true); } -void PlayerActions::moveBottomCardsTo(const QString &targetZone, const QString &zoneDisplayName, bool faceDown) +void PlayerActions::actRequestMoveBottomCardsToDialog(const QString &targetZone, + const QString &zoneDisplayName, + bool faceDown) { const int maxCards = player->getDeckZone()->getCards().size(); if (maxCards == 0) { return; } - bool ok; - int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Move bottom cards to %1").arg(zoneDisplayName), - tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1, - maxCards, 1, &ok); - if (!ok) { + emit requestMoveBottomCardsToDialog(defaultNumberBottomCards, maxCards, targetZone, zoneDisplayName, faceDown); +} + +void PlayerActions::moveBottomCardsTo(int number, const QString &targetZone, bool faceDown) +{ + const int maxCards = player->getDeckZone()->getCards().size(); + if (maxCards == 0) { return; } @@ -763,20 +766,24 @@ void PlayerActions::actDrawBottomCard() sendGameCommand(cmd); } -void PlayerActions::actDrawBottomCards() +void PlayerActions::actRequestDrawBottomCardsDialog() { const int maxCards = player->getDeckZone()->getCards().size(); if (maxCards == 0) { return; } - bool ok; - int number = QInputDialog::getInt(player->getGame()->getTab(), tr("Draw bottom cards"), - tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1, - maxCards, 1, &ok); - if (!ok) { + emit requestDrawBottomCardsDialog(defaultNumberBottomCards, maxCards); +} + +void PlayerActions::actDrawBottomCards(int number) +{ + const int maxCards = player->getDeckZone()->getCards().size(); + if (maxCards == 0) { return; - } else if (number > maxCards) { + } + + if (number > maxCards) { number = maxCards; } defaultNumberBottomCards = number; @@ -843,16 +850,16 @@ void PlayerActions::actUntapAll() sendGameCommand(cmd); } -void PlayerActions::actRollDie() +void PlayerActions::actRequestRollDieDialog() { - DlgRollDice dlg(player->getGame()->getTab()); - if (!dlg.exec()) { - return; - } + emit requestRollDieDialog(); +} +void PlayerActions::actRollDie(int sides, int count) +{ Command_RollDie cmd; - cmd.set_sides(dlg.getDieSideCount()); - cmd.set_count(dlg.getDiceToRollCount()); + cmd.set_sides(sides); + cmd.set_count(count); sendGameCommand(cmd); } @@ -864,14 +871,14 @@ void PlayerActions::actFlipCoin() sendGameCommand(cmd); } -void PlayerActions::actCreateToken(const QStringList &predefinedTokens) +void PlayerActions::actRequestCreateTokenDialog(const QStringList &predefinedTokens) { - DlgCreateToken dlg(predefinedTokens, player->getGame()->getTab()); - if (!dlg.exec()) { - return; - } + emit requestCreateTokenDialog(predefinedTokens); +} - lastTokenInfo = dlg.getTokenInfo(); +void PlayerActions::actCreateToken(TokenInfo tokenToCreate) +{ + lastTokenInfo = tokenToCreate; ExactCard correctedCard = CardDatabaseManager::query()->guessCard({lastTokenInfo.name, lastTokenInfo.providerId}); if (correctedCard) { @@ -951,23 +958,17 @@ void PlayerActions::actCreatePredefinedToken() void PlayerActions::actCreateRelatedCard() { const CardItem *sourceCard = player->getGame()->getActiveCard(); + if (!sourceCard) { return; } + auto *action = static_cast(sender()); // If there is a better way of passing a CardRelation through a QAction, please add it here. auto relatedCards = sourceCard->getCardInfo().getAllRelatedCards(); - CardRelation *cardRelation = relatedCards.at(action->data().toInt()); - /* - * If we make a token via "Token: TokenName" - * then let's allow it to be created via "create another token" - */ - if (createRelatedFromRelation(sourceCard, cardRelation) && cardRelation->getCanCreateAnother()) { - ExactCard relatedCard = CardDatabaseManager::query()->getCardFromSameSet(cardRelation->getName(), - sourceCard->getCard().getPrinting()); - setLastToken(relatedCard.getCardPtr()); - } + CardRelation *cardRelation = relatedCards.at(action->data().toInt()); + actRequestCreateRelatedFromRelationDialog(sourceCard, cardRelation); } void PlayerActions::actCreateAllRelatedCards() @@ -987,7 +988,9 @@ void PlayerActions::actCreateAllRelatedCards() if (relatedCards.length() == 1) { cardRelation = relatedCards.at(0); - if (createRelatedFromRelation(sourceCard, cardRelation)) { + lastRelatedCreationSucceeded = false; // reset before emit + actRequestCreateRelatedFromRelationDialog(sourceCard, cardRelation); + if (lastRelatedCreationSucceeded) { ++tokensTypesCreated; } } else { @@ -999,15 +1002,18 @@ void PlayerActions::actCreateAllRelatedCards() } } switch (nonExcludedRelatedCards.length()) { - case 1: // if nonExcludedRelatedCards == 1 + case 1: cardRelation = nonExcludedRelatedCards.at(0); - if (createRelatedFromRelation(sourceCard, cardRelation)) { + lastRelatedCreationSucceeded = false; // reset before emit + actRequestCreateRelatedFromRelationDialog(sourceCard, cardRelation); + if (lastRelatedCreationSucceeded) { ++tokensTypesCreated; } break; + // If all are marked "Exclude", then treat the situation as if none of them are. // We won't accept "garbage in, garbage out", here. - case 0: // else if nonExcludedRelatedCards == 0 + case 0: for (CardRelation *cardRelationAll : relatedCards) { if (!cardRelationAll->getDoesAttach() && !cardRelationAll->getIsVariable()) { dbName = cardRelationAll->getName(); @@ -1022,7 +1028,8 @@ void PlayerActions::actCreateAllRelatedCards() } } break; - default: // else + + default: for (CardRelation *cardRelationNotExcluded : nonExcludedRelatedCards) { if (!cardRelationNotExcluded->getDoesAttach() && !cardRelationNotExcluded->getIsVariable()) { dbName = cardRelationNotExcluded->getName(); @@ -1050,50 +1057,83 @@ void PlayerActions::actCreateAllRelatedCards() } } -bool PlayerActions::createRelatedFromRelation(const CardItem *sourceCard, const CardRelation *cardRelation) +void PlayerActions::actRequestCreateRelatedFromRelationDialog(const CardItem *sourceCard, + const CardRelation *cardRelation) +{ + emit requestCreateRelatedFromRelationDialog(sourceCard, cardRelation); +} + +bool PlayerActions::createRelatedFromRelation(const CardItem *sourceCard, + const CardRelation *cardRelation, + int variableCount) { if (sourceCard == nullptr || cardRelation == nullptr) { return false; } - QString dbName = cardRelation->getName(); - bool persistent = cardRelation->getIsPersistent(); + + const QString dbName = cardRelation->getName(); + const bool persistent = cardRelation->getIsPersistent(); + + // Variable relations always use DoesNotAttach, regardless of the count the user + // entered. if (cardRelation->getIsVariable()) { - bool ok; - player->setDialogSemaphore(true); - int count = QInputDialog::getInt(player->getGame()->getTab(), tr("Create tokens"), tr("Number:"), - cardRelation->getDefaultCount(), 1, MAX_TOKENS_PER_DIALOG, 1, &ok); - player->setDialogSemaphore(false); - if (!ok) { + if (variableCount <= 0) { return false; } + for (int i = 0; i < variableCount; ++i) { + createCard(sourceCard, dbName, CardRelationType::DoesNotAttach, persistent); + } + return true; + } + + const int count = cardRelation->getDefaultCount(); + + if (count > 1) { for (int i = 0; i < count; ++i) { createCard(sourceCard, dbName, CardRelationType::DoesNotAttach, persistent); } - } else if (cardRelation->getDefaultCount() > 1) { - for (int i = 0; i < cardRelation->getDefaultCount(); ++i) { - createCard(sourceCard, dbName, CardRelationType::DoesNotAttach, persistent); - } - } else { - CardRelationType attachType; - // do not attempt to attach to another player's cards, this causes the card to attempt to attach to the same - // cardid on the local player's field instead, which is an entirely different card! - if (player->getPlayerInfo()->getLocalOrJudge()) { - attachType = cardRelation->getAttachType(); - } else { - attachType = CardRelationType::DoesNotAttach; - } - - // move card onto table first if attaching from some other zone - // we only do this for AttachTo because cross-zone TransformInto is already handled server-side - if (attachType == CardRelationType::AttachTo && sourceCard->getZone()->getName() != ZoneNames::TABLE) { - playCardToTable(sourceCard, false); - } - - createCard(sourceCard, dbName, attachType, persistent); + return true; } + + CardRelationType attachType; + // do not attempt to attach to another player's cards, this causes the card to attempt to attach to the same + // cardid on the local player's field instead, which is an entirely different card! + if (player->getPlayerInfo()->getLocalOrJudge()) { + attachType = cardRelation->getAttachType(); + } else { + attachType = CardRelationType::DoesNotAttach; + } + + // move card onto table first if attaching from some other zone + // we only do this for AttachTo because cross-zone TransformInto is already handled server-side + if (attachType == CardRelationType::AttachTo && sourceCard->getZone()->getName() != ZoneNames::TABLE) { + playCardToTable(sourceCard, false); + } + + createCard(sourceCard, dbName, attachType, persistent); return true; } +void PlayerActions::onRelatedCardCreated(const CardItem *sourceCard, const CardRelation *cardRelation) +{ + if (sourceCard == nullptr || cardRelation == nullptr) { + return; + } + + /* + * If we make a token via "Token: TokenName" + * then let's allow it to be created via "create another token" + */ + if (!cardRelation->getCanCreateAnother()) { + return; + } + + ExactCard relatedCard = + CardDatabaseManager::query()->getCardFromSameSet(cardRelation->getName(), sourceCard->getCard().getPrinting()); + + setLastToken(relatedCard.getCardPtr()); +} + void PlayerActions::createCard(const CardItem *sourceCard, const QString &dbCardName, CardRelationType attachType, @@ -1171,35 +1211,29 @@ void PlayerActions::actSayMessage() sendGameCommand(cmd); } -void PlayerActions::actMoveCardXCardsFromTop(QList selectedCards) +void PlayerActions::actRequestMoveCardXCardsFromTopDialog() { int deckSize = player->getDeckZone()->getCards().size() + 1; // add the card to move to the deck - bool ok; - int number = - QInputDialog::getInt(player->getGame()->getTab(), tr("Place card X cards from top of library"), - tr("Which position should this card be placed:") + "\n" + tr("(max. %1)").arg(deckSize), - defaultNumberTopCardsToPlaceBelow, 1, deckSize, 1, &ok); - number -= 1; // indexes start at 0 - if (!ok) { - return; - } + emit requestMoveCardXCardsFromTopDialog(defaultNumberTopCardsToPlaceBelow, deckSize); +} +void PlayerActions::actMoveCardXCardsFromTop(QList selectedCards, int number) +{ defaultNumberTopCardsToPlaceBelow = number; - QList cardList = selectedCards; - if (cardList.isEmpty()) { + if (selectedCards.isEmpty()) { return; } QList commandList; ListOfCardsToMove idList; - for (const auto &i : cardList) { + for (const auto &i : selectedCards) { idList.add_card()->set_card_id(i->getId()); } - int startPlayerId = cardList[0]->getZone()->getPlayer()->getPlayerInfo()->getId(); - QString startZone = cardList[0]->getZone()->getName(); + int startPlayerId = selectedCards[0]->getZone()->getPlayer()->getPlayerInfo()->getId(); + QString startZone = selectedCards[0]->getZone()->getName(); auto *cmd = new Command_MoveCard; cmd->set_start_player_id(startPlayerId); @@ -1284,24 +1318,22 @@ void PlayerActions::actResetPT(QList selectedCards) } } -void PlayerActions::actSetPT(QList selectedCards) +void PlayerActions::actRequestSetPTDialog(QList selectedCards) { QString oldPT; - int playerid = player->getPlayerInfo()->getId(); for (auto card : selectedCards) { if (!card->getPT().isEmpty()) { oldPT = card->getPT(); } } - bool ok; - player->setDialogSemaphore(true); - QString pt = getTextWithMax(player->getGame()->getTab(), tr("Change power/toughness"), tr("Change stats to:"), - QLineEdit::Normal, oldPT, &ok); - player->setDialogSemaphore(false); - if (player->clearCardsToDelete() || !ok) { - return; - } + + emit requestSetPTDialog(oldPT); +} + +void PlayerActions::actSetPT(QList selectedCards, const QString &pt) +{ + int playerid = player->getPlayerInfo()->getId(); const auto ptList = CardItem::parsePT(pt); bool empty = ptList.isEmpty(); @@ -1426,7 +1458,7 @@ void AnnotationDialog::keyPressEvent(QKeyEvent *event) QInputDialog::keyPressEvent(event); } -void PlayerActions::actSetAnnotation(QList selectedCards) +void PlayerActions::actRequestSetAnnotationDialog(QList selectedCards) { QString oldAnnotation; for (auto card : selectedCards) { @@ -1435,19 +1467,11 @@ void PlayerActions::actSetAnnotation(QList selectedCards) } } - player->setDialogSemaphore(true); - AnnotationDialog *dialog = new AnnotationDialog(player->getGame()->getTab()); - dialog->setOptions(QInputDialog::UsePlainTextEditForTextInput); - dialog->setWindowTitle(tr("Set annotation")); - dialog->setLabelText(tr("Please enter the new annotation:")); - dialog->setTextValue(oldAnnotation); - bool ok = dialog->exec(); - player->setDialogSemaphore(false); - if (player->clearCardsToDelete() || !ok) { - return; - } - QString annotation = dialog->textValue().left(MAX_NAME_LENGTH); + emit requestSetAnnotationDialog(oldAnnotation); +} +void PlayerActions::actSetAnnotation(QList selectedCards, const QString &annotation) +{ QList commandList; for (auto card : selectedCards) { auto *cmd = new Command_SetCardAttr; @@ -1519,10 +1543,8 @@ void PlayerActions::offsetCardCounter(QList selectedCards, int count sendGameCommand(prepareGameCommand(commandList)); } -void PlayerActions::actSetCardCounter(QList selectedCards, int counterId) +void PlayerActions::actRequestSetCardCounterDialog(QList selectedCards, int counterId) { - player->setDialogSemaphore(true); - // If a single card is selected, we show the old value in the dialog. Otherwise, we show "x" QString oldValueForDlg = "x"; if (selectedCards.size() == 1) { @@ -1530,22 +1552,16 @@ void PlayerActions::actSetCardCounter(QList selectedCards, int count oldValueForDlg = QString::number(card->getCounters().value(counterId, 0)); } - auto &cardCounterSettings = SettingsCache::instance().cardCounters(); - QString counterName = cardCounterSettings.displayName(counterId); - - AbstractCounterDialog dialog(counterName, oldValueForDlg, player->getGame()->getTab()); - int ok = dialog.exec(); - - player->setDialogSemaphore(false); - if (player->clearCardsToDelete() || !ok) { - return; - } + emit requestSetCardCounterDialog(counterId, oldValueForDlg); +} +void PlayerActions::actSetCardCounter(QList selectedCards, int counterId, const QString &counterValue) +{ QList commandList; for (auto card : selectedCards) { int oldValue = card->getCounters().value(counterId, 0); Expression exp(oldValue); - double parsed = exp.parse(dialog.textValue()); + double parsed = exp.parse(counterValue); // Clamp in double precision first to avoid UB, then cast int number = static_cast(qBound(0.0, parsed, static_cast(MAX_COUNTERS_ON_CARD))); diff --git a/cockatrice/src/game/player/player_actions.h b/cockatrice/src/game/player/player_actions.h index 940de610f..2779fa5aa 100644 --- a/cockatrice/src/game/player/player_actions.h +++ b/cockatrice/src/game/player/player_actions.h @@ -58,6 +58,31 @@ public: } signals: + void requestViewTopCardsDialog(int defaultNumberTopCards, int deckSize); + void requestViewBottomCardsDialog(int defaultNumberBottomCards, int deckSize); + void requestShuffleTopDialog(int defaultNumberTopCards, int maxCards); + void requestShuffleBottomDialog(int defaultNumberBottomCards, int maxCards); + void requestMulliganDialog(int startSize, int handSize, int deckSize); + void requestDrawCardsDialog(int defaultNumberTopCards, int deckSize); + void requestMoveTopCardsToDialog(int defaultNumberTopCards, + int maxCards, + const QString &targetZone, + const QString &zoneDisplayName, + bool faceDown); + void requestMoveTopCardsUntilDialog(MoveTopCardsUntilOptions options); + void requestMoveBottomCardsToDialog(int defaultNumberBottomCards, + int maxCards, + const QString &targetZone, + const QString &zoneDisplayName, + bool faceDown); + void requestDrawBottomCardsDialog(int defaultNumberBottomCards, int maxCards); + void requestRollDieDialog(); + void requestCreateTokenDialog(const QStringList &predefinedTokens); + void requestCreateRelatedFromRelationDialog(const CardItem *sourceCard, const CardRelation *cardRelation); + void requestMoveCardXCardsFromTopDialog(int defaultNumberTopCardsToPlaceBelow, int deckSize); + void requestSetPTDialog(const QString &oldPT); + void requestSetAnnotationDialog(const QString &oldAnnotation); + void requestSetCardCounterDialog(int counterId, const QString &oldValueForDlg); void requestZoneViewToggle(const QString &zoneName, int numberCards, bool isReversed = false); void requestSortHand(const QList &options); void requestEnableAndSetCreateAnotherTokenAction(const QString &lastTokenName); @@ -70,17 +95,30 @@ public slots: void playCardToTable(const CardItem *c, bool faceDown); void actUntapAll(); - void actRollDie(); + void actRequestRollDieDialog(); + void actRollDie(int sides, int count); void actFlipCoin(); - void actCreateToken(const QStringList &predefinedTokens); + void actRequestCreateTokenDialog(const QStringList &predefinedTokens); + void actCreateToken(TokenInfo tokenToCreate); void actCreateAnotherToken(); + void actRequestCreateRelatedFromRelationDialog(const CardItem *sourceCard, const CardRelation *cardRelation); + bool createRelatedFromRelation(const CardItem *sourceCard, const CardRelation *cardRelation, int variableCount); + void onRelatedCardCreated(const CardItem *sourceCard, const CardRelation *cardRelation); + void setLastRelatedCreationSucceeded(bool succeeded) + { + lastRelatedCreationSucceeded = succeeded; + } void actShuffle(); - void actShuffleTop(); - void actShuffleBottom(); + void actRequestShuffleTopDialog(); + void actShuffleTop(int number); + void actRequestShuffleBottomDialog(); + void actShuffleBottom(int number); void actDrawCard(); - void actDrawCards(); + void actRequestDrawCardsDialog(); + void actDrawCards(int number); void actUndoDraw(); - void actMulligan(); + void actRequestMulliganDialog(); + void actMulligan(int number); void actMulliganSameSize(); void actMulliganMinusOne(); void doMulligan(int number); @@ -97,10 +135,14 @@ public slots: void actMoveTopCardsToGraveFaceDown(); void actMoveTopCardsToExile(); void actMoveTopCardsToExileFaceDown(); - void actMoveTopCardsUntil(); + void actRequestMoveTopCardsUntilDialog(); + void moveTopCardsUntil(const QString &expr, MoveTopCardsUntilOptions options); void actMoveTopCardToBottom(); + void actRequestMoveTopCardsToDialog(const QString &targetZone, const QString &zoneDisplayName, bool faceDown); + void moveTopCardsTo(int number, const QString &targetZone, bool faceDown); void actDrawBottomCard(); - void actDrawBottomCards(); + void actRequestDrawBottomCardsDialog(); + void actDrawBottomCards(int number); void actMoveBottomCardToPlay(); void actMoveBottomCardToPlayFaceDown(); void actMoveBottomCardToGrave(); @@ -110,6 +152,8 @@ public slots: void actMoveBottomCardsToExile(); void actMoveBottomCardsToExileFaceDown(); void actMoveBottomCardToTop(); + void actRequestMoveBottomCardsToDialog(const QString &targetZone, const QString &zoneDisplayName, bool faceDown); + void moveBottomCardsTo(int number, const QString &targetZone, bool faceDown); void actSelectAll(); void actSelectRow(); @@ -117,8 +161,10 @@ public slots: void actViewLibrary(); void actViewHand(); - void actViewTopCards(); - void actViewBottomCards(); + void actRequestViewTopCardsDialog(); + void actViewTopCards(int number); + void actRequestViewBottomCardsDialog(); + void actViewBottomCards(int number); void actAlwaysRevealTopCard(bool alwaysRevealTopCard); void actAlwaysLookAtTopCard(bool alwaysRevealTopCard); void actViewGraveyard(); @@ -135,17 +181,20 @@ public slots: void actCreateRelatedCard(); void actCreateAllRelatedCards(); - void actMoveCardXCardsFromTop(QList selectedCards); + void actRequestMoveCardXCardsFromTopDialog(); + void actMoveCardXCardsFromTop(QList selectedCards, int number); void actRemoveCardCounter(QList selectedCards, int counterId); void actAddCardCounter(QList selectedCards, int counterId); - void actSetCardCounter(QList selectedCards, int counterId); + void actRequestSetCardCounterDialog(QList selectedCards, int counterId); + void actSetCardCounter(QList selectedCards, int counterId, const QString &counterValue); void actIncrementAllCardCounters(QList cardsToUpdate); void actAttach(); void actUnattach(QList selectedCards); void actDrawArrow(); void actIncPT(QList selectedCards, int deltaP, int deltaT); void actResetPT(QList selectedCards); - void actSetPT(QList selectedCards); + void actRequestSetPTDialog(QList selectedCards); + void actSetPT(QList selectedCards, const QString &pt); void actIncP(QList selectedCards); void actDecP(QList selectedCards); void actIncT(QList selectedCards); @@ -157,7 +206,8 @@ public slots: void actReduceLifeByPower(QList selectedCards); - void actSetAnnotation(QList selectedCards); + void actRequestSetAnnotationDialog(QList selectedCards); + void actSetAnnotation(QList selectedCards, const QString &annotation); void actReveal(QList selectedCards, QAction *action); void actRevealHand(int revealToPlayerId); void actRevealRandomHandCard(int revealToPlayerId); @@ -184,14 +234,12 @@ private: int movingCardsUntilCounter = 0; MoveTopCardsUntilOptions movingCardsUntilOptions; - void moveTopCardsTo(const QString &targetZone, const QString &zoneDisplayName, bool faceDown); - void moveBottomCardsTo(const QString &targetZone, const QString &zoneDisplayName, bool faceDown); + bool lastRelatedCreationSucceeded = false; void createCard(const CardItem *sourceCard, const QString &dbCardName, CardRelationType attach = CardRelationType::DoesNotAttach, bool persistent = false); - bool createRelatedFromRelation(const CardItem *sourceCard, const CardRelation *cardRelation); void playSelectedCards(QList selectedCards, bool faceDown = false); diff --git a/cockatrice/src/game/player/player_dialogs.cpp b/cockatrice/src/game/player/player_dialogs.cpp new file mode 100644 index 000000000..3c26ae1fe --- /dev/null +++ b/cockatrice/src/game/player/player_dialogs.cpp @@ -0,0 +1,298 @@ +#include "player_dialogs.h" + +#include "../../client/settings/card_counter_settings.h" +#include "../../interface/widgets/utility/get_text_with_max.h" +#include "../board/card_item.h" +#include "../dialogs/dlg_roll_dice.h" +#include "../player/player_graphics_item.h" + +#include +#include + +PlayerDialogs::PlayerDialogs(PlayerGraphicsItem *_player, PlayerActions *_playerActions) + : QObject(_player), player(_player), playerActions(_playerActions) +{ + connect(playerActions, &PlayerActions::requestViewTopCardsDialog, this, + &PlayerDialogs::onViewTopCardsDialogRequested); + + connect(playerActions, &PlayerActions::requestViewBottomCardsDialog, this, + &PlayerDialogs::onViewBottomCardsDialogRequested); + + connect(playerActions, &PlayerActions::requestShuffleTopDialog, this, &PlayerDialogs::onShuffleTopDialogRequested); + + connect(playerActions, &PlayerActions::requestShuffleBottomDialog, this, + &PlayerDialogs::onShuffleBottomDialogRequested); + + connect(playerActions, &PlayerActions::requestMulliganDialog, this, &PlayerDialogs::onMulliganDialogRequested); + + connect(playerActions, &PlayerActions::requestDrawCardsDialog, this, &PlayerDialogs::onDrawCardsDialogRequested); + + connect(playerActions, &PlayerActions::requestMoveTopCardsToDialog, this, + &PlayerDialogs::onMoveTopCardsToDialogRequested); + + connect(playerActions, &PlayerActions::requestMoveTopCardsUntilDialog, this, + &PlayerDialogs::onMoveTopCardsUntilDialogRequested); + + connect(playerActions, &PlayerActions::requestMoveBottomCardsToDialog, this, + &PlayerDialogs::onMoveBottomCardsToDialogRequested); + + connect(playerActions, &PlayerActions::requestDrawBottomCardsDialog, this, + &PlayerDialogs::onDrawBottomCardsDialogRequested); + + connect(playerActions, &PlayerActions::requestRollDieDialog, this, &PlayerDialogs::onRollDieDialogRequested); + + connect(playerActions, &PlayerActions::requestCreateTokenDialog, this, + &PlayerDialogs::onCreateTokenDialogRequested); + + connect(playerActions, &PlayerActions::requestCreateRelatedFromRelationDialog, this, + &PlayerDialogs::onCreateRelatedFromRelationDialogRequested); + + connect(playerActions, &PlayerActions::requestMoveCardXCardsFromTopDialog, this, + &PlayerDialogs::onMoveCardXCardsFromTopDialogRequested); + + connect(playerActions, &PlayerActions::requestSetPTDialog, this, &PlayerDialogs::onSetPTDialogRequested); + + connect(playerActions, &PlayerActions::requestSetAnnotationDialog, this, + &PlayerDialogs::onSetAnnotationDialogRequested); + + connect(playerActions, &PlayerActions::requestSetCardCounterDialog, this, + &PlayerDialogs::onSetCardCounterDialogRequested); +} + +void PlayerDialogs::onViewTopCardsDialogRequested(int defaultNumberTopCards, int deckSize) +{ + bool ok; + int number = QInputDialog::getInt(dialogParent(), tr("View top cards of library"), + tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberTopCards, 1, + deckSize, 1, &ok); + if (ok) { + playerActions->actViewTopCards(number); + } +} + +void PlayerDialogs::onViewBottomCardsDialogRequested(int defaultNumberBottomCards, int deckSize) +{ + bool ok; + int number = QInputDialog::getInt(dialogParent(), tr("View bottom cards of library"), + tr("Number of cards: (max. %1)").arg(deckSize), defaultNumberBottomCards, 1, + deckSize, 1, &ok); + if (ok) { + playerActions->actViewBottomCards(number); + } +} + +void PlayerDialogs::onShuffleTopDialogRequested(int defaultNumberTopCards, int maxCards) +{ + bool ok; + int number = QInputDialog::getInt(dialogParent(), tr("Shuffle top cards of library"), + tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1, + maxCards, 1, &ok); + if (ok) { + playerActions->actShuffleTop(number); + } +} + +void PlayerDialogs::onShuffleBottomDialogRequested(int defaultNumberBottomCards, int maxCards) +{ + bool ok; + int number = QInputDialog::getInt(dialogParent(), tr("Shuffle bottom cards of library"), + tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1, + maxCards, 1, &ok); + if (ok) { + playerActions->actShuffleBottom(number); + } +} + +void PlayerDialogs::onMulliganDialogRequested(int startSize, int handSize, int deckSize) +{ + bool ok; + int number = QInputDialog::getInt(dialogParent(), tr("Draw hand"), + tr("Number of cards: (max. %1)").arg(deckSize) + '\n' + + tr("0 and lower are in comparison to current hand size"), + startSize, -handSize, deckSize, 1, &ok); + + if (ok) { + playerActions->actMulligan(number); + } +} + +void PlayerDialogs::onDrawCardsDialogRequested(int defaultNumberTopCards, int deckSize) +{ + bool ok; + int number = QInputDialog::getInt(dialogParent(), tr("Draw cards"), tr("Number of cards: (max. %1)").arg(deckSize), + defaultNumberTopCards, 1, deckSize, 1, &ok); + + if (ok) { + playerActions->actDrawCards(number); + } +} + +void PlayerDialogs::onMoveTopCardsToDialogRequested(int defaultNumberTopCards, + int maxCards, + const QString &targetZone, + const QString &zoneDisplayName, + bool faceDown) +{ + bool ok; + int number = QInputDialog::getInt(dialogParent(), tr("Move top cards to %1").arg(zoneDisplayName), + tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberTopCards, 1, + maxCards, 1, &ok); + if (ok) { + playerActions->moveTopCardsTo(number, targetZone, faceDown); + } +} + +void PlayerDialogs::onMoveTopCardsUntilDialogRequested(MoveTopCardsUntilOptions options) +{ + DlgMoveTopCardsUntil dlg(dialogParent(), options); + if (!dlg.exec()) { + return; + } + playerActions->moveTopCardsUntil(dlg.getExpr(), dlg.getOptions()); +} + +void PlayerDialogs::onMoveBottomCardsToDialogRequested(int defaultNumberBottomCards, + int maxCards, + const QString &targetZone, + const QString &zoneDisplayName, + bool faceDown) +{ + bool ok; + int number = QInputDialog::getInt(dialogParent(), tr("Move bottom cards to %1").arg(zoneDisplayName), + tr("Number of cards: (max. %1)").arg(maxCards), defaultNumberBottomCards, 1, + maxCards, 1, &ok); + if (ok) { + playerActions->moveBottomCardsTo(number, targetZone, faceDown); + } +} + +void PlayerDialogs::onDrawBottomCardsDialogRequested(int defaultNumberBottomCards, int maxCards) +{ + bool ok; + int number = + QInputDialog::getInt(dialogParent(), tr("Draw bottom cards"), tr("Number of cards: (max. %1)").arg(maxCards), + defaultNumberBottomCards, 1, maxCards, 1, &ok); + if (ok) { + playerActions->actDrawBottomCards(number); + } +} + +void PlayerDialogs::onRollDieDialogRequested() +{ + DlgRollDice dlg(dialogParent()); + if (!dlg.exec()) { + return; + } + playerActions->actRollDie(dlg.getDieSideCount(), dlg.getDiceToRollCount()); +} + +void PlayerDialogs::onCreateRelatedFromRelationDialogRequested(const CardItem *sourceCard, + const CardRelation *cardRelation) +{ + if (sourceCard == nullptr || cardRelation == nullptr) { + playerActions->setLastRelatedCreationSucceeded(false); + return; + } + + int variableCount = cardRelation->getDefaultCount(); + + if (cardRelation->getIsVariable()) { + bool ok; + + emit requestDialogSemaphore(true); + + variableCount = QInputDialog::getInt(dialogParent(), tr("Create tokens"), tr("Number:"), + cardRelation->getDefaultCount(), 1, MAX_TOKENS_PER_DIALOG, 1, &ok); + + emit requestDialogSemaphore(false); + + if (!ok) { + playerActions->setLastRelatedCreationSucceeded(false); // cancelled + return; + } + } + + const bool succeeded = playerActions->createRelatedFromRelation(sourceCard, cardRelation, variableCount); + + playerActions->setLastRelatedCreationSucceeded(succeeded); + + if (succeeded) { + playerActions->onRelatedCardCreated(sourceCard, cardRelation); // only on confirmed success + } +} + +void PlayerDialogs::onCreateTokenDialogRequested(const QStringList &predefinedTokens) +{ + DlgCreateToken dlg(predefinedTokens, dialogParent()); + if (!dlg.exec()) { + return; + } + + playerActions->actCreateToken(dlg.getTokenInfo()); +} + +void PlayerDialogs::onMoveCardXCardsFromTopDialogRequested(int defaultNumberTopCardsToPlaceBelow, int deckSize) +{ + bool ok; + int number = + QInputDialog::getInt(dialogParent(), tr("Place card X cards from top of library"), + tr("Which position should this card be placed:") + "\n" + tr("(max. %1)").arg(deckSize), + defaultNumberTopCardsToPlaceBelow, 1, deckSize, 1, &ok); + number -= 1; // indexes start at 0 + + if (ok) { + playerActions->actMoveCardXCardsFromTop(player->getGameScene()->selectedCards(), number); + } +} + +void PlayerDialogs::onSetPTDialogRequested(const QString &oldPT) +{ + bool ok; + auto cards = player->getGameScene()->selectedCards(); + emit requestDialogSemaphore(true); + QString pt = getTextWithMax(dialogParent(), tr("Change power/toughness"), tr("Change stats to:"), QLineEdit::Normal, + oldPT, &ok); + emit requestDialogSemaphore(false); + + if (!ok || player->getLogic()->clearCardsToDelete()) { + return; + } + + playerActions->actSetPT(cards, pt); +} + +void PlayerDialogs::onSetAnnotationDialogRequested(const QString &oldAnnotation) +{ + auto cards = player->getGameScene()->selectedCards(); + emit requestDialogSemaphore(true); + AnnotationDialog *dialog = new AnnotationDialog(dialogParent()); + dialog->setOptions(QInputDialog::UsePlainTextEditForTextInput); + dialog->setWindowTitle(tr("Set annotation")); + dialog->setLabelText(tr("Please enter the new annotation:")); + dialog->setTextValue(oldAnnotation); + bool ok = dialog->exec(); + emit requestDialogSemaphore(false); + if (!ok || player->getLogic()->clearCardsToDelete()) { + return; + } + QString annotation = dialog->textValue().left(MAX_NAME_LENGTH); + playerActions->actSetAnnotation(cards, annotation); +} + +void PlayerDialogs::onSetCardCounterDialogRequested(int counterId, const QString &oldValueForDlg) +{ + auto cards = player->getGameScene()->selectedCards(); + emit requestDialogSemaphore(true); + + auto &cardCounterSettings = SettingsCache::instance().cardCounters(); + QString counterName = cardCounterSettings.displayName(counterId); + + AbstractCounterDialog dialog(counterName, oldValueForDlg, dialogParent()); + int ok = dialog.exec(); + + emit requestDialogSemaphore(false); + if (!ok || player->getLogic()->clearCardsToDelete()) { + return; + } + playerActions->actSetCardCounter(cards, counterId, dialog.textValue()); +} \ No newline at end of file diff --git a/cockatrice/src/game/player/player_dialogs.h b/cockatrice/src/game/player/player_dialogs.h new file mode 100644 index 000000000..a15c5174f --- /dev/null +++ b/cockatrice/src/game/player/player_dialogs.h @@ -0,0 +1,62 @@ +#ifndef COCKATRICE_PLAYER_DIALOGS_H +#define COCKATRICE_PLAYER_DIALOGS_H +#include "player_actions.h" + +#include +#include + +class PlayerGraphicsItem; +class PlayerDialogs : public QObject +{ + + Q_OBJECT + +public: + explicit PlayerDialogs(PlayerGraphicsItem *player, PlayerActions *playerActions); + +signals: + void requestDialogSemaphore(bool active); + +public slots: + void onViewTopCardsDialogRequested(int defaultNumberTopCards, int deckSize); + void onViewBottomCardsDialogRequested(int defaultNumberBottomCards, int deckSize); + void onShuffleTopDialogRequested(int defaultNumberTopCards, int maxCards); + void onShuffleBottomDialogRequested(int defaultNumberBottomCards, int maxCards); + void onMulliganDialogRequested(int startSize, int handSize, int deckSize); + void onDrawCardsDialogRequested(int defaultNumberTopCards, int deckSize); + void onMoveTopCardsToDialogRequested(int defaultNumberTopCards, + int maxCards, + const QString &targetZone, + const QString &zoneDisplayName, + bool faceDown); + void onMoveTopCardsUntilDialogRequested(MoveTopCardsUntilOptions options); + void onMoveBottomCardsToDialogRequested(int defaultNumberBottomCards, + int maxCards, + const QString &targetZone, + const QString &zoneDisplayName, + bool faceDown); + void onDrawBottomCardsDialogRequested(int defaultNumberBottomCards, int maxCards); + void onRollDieDialogRequested(); + void onCreateRelatedFromRelationDialogRequested(const CardItem *sourceCard, const CardRelation *cardRelation); + void onCreateTokenDialogRequested(const QStringList &predefinedTokens); + void onMoveCardXCardsFromTopDialogRequested(int defaultNumberTopCardsToPlaceBelow, int deckSize); + void onSetPTDialogRequested(const QString &oldPT); + void onSetAnnotationDialogRequested(const QString &oldAnnotation); + void onSetCardCounterDialogRequested(int counterId, const QString &oldValueForDlg); + +private: + PlayerGraphicsItem *player; + PlayerActions *playerActions; + + QWidget *dialogParent() const + { + if (auto *s = player->scene()) { + if (auto *v = s->views().value(0)) { + return v->window(); + } + } + return nullptr; + } +}; + +#endif // COCKATRICE_PLAYER_DIALOGS_H diff --git a/cockatrice/src/game/player/player_graphics_item.cpp b/cockatrice/src/game/player/player_graphics_item.cpp index d86fce86b..b0a476d5a 100644 --- a/cockatrice/src/game/player/player_graphics_item.cpp +++ b/cockatrice/src/game/player/player_graphics_item.cpp @@ -9,6 +9,7 @@ #include "../board/counter_general.h" #include "../hand_counter.h" #include "player_actions.h" +#include "player_dialogs.h" #include @@ -44,6 +45,10 @@ PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player) } }); + playerDialogs = new PlayerDialogs(this, player->getPlayerActions()); + + connect(playerDialogs, &PlayerDialogs::requestDialogSemaphore, player, &PlayerLogic::setDialogSemaphore); + playerArea = new PlayerArea(this); playerTarget = new PlayerTarget(player, playerArea); diff --git a/cockatrice/src/game/player/player_graphics_item.h b/cockatrice/src/game/player/player_graphics_item.h index 1acb1520f..c1fcb4ed8 100644 --- a/cockatrice/src/game/player/player_graphics_item.h +++ b/cockatrice/src/game/player/player_graphics_item.h @@ -14,6 +14,7 @@ class HandZone; class PileZone; +class PlayerDialogs; class PlayerTarget; class StackZone; class TableZone; @@ -122,6 +123,7 @@ signals: private: PlayerLogic *player; PlayerMenu *playerMenu; + PlayerDialogs *playerDialogs; PlayerArea *playerArea; PlayerTarget *playerTarget; QMap counterWidgets; From da4ba222c0c9dabd1b70c96aac20bdd8721c6e13 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Tue, 9 Jun 2026 09:51:13 +0200 Subject: [PATCH 07/17] [Game] Move graphics out of game and into game_graphics (#6928) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Game][Player] Pull out graphics_items out of player_logic Took 25 seconds Took 9 minutes * [Game] Move graphics files into game_graphics Took 1 minute Took 2 minutes Took 23 seconds Took 1 minute Took 2 seconds * Include. Took 4 minutes Took 3 minutes Took 4 minutes Took 1 minute Took 3 minutes --------- Co-authored-by: Lukas Brübach --- cockatrice/CMakeLists.txt | 74 +++++++++---------- cockatrice/src/game/abstract_game.cpp | 2 +- cockatrice/src/game/abstract_game.h | 9 +-- cockatrice/src/game/arrow_registry.cpp | 2 +- cockatrice/src/game/board/card_list.cpp | 2 +- cockatrice/src/game/game.cpp | 8 +- cockatrice/src/game/game.h | 3 +- cockatrice/src/game/game_event_handler.cpp | 2 +- cockatrice/src/game/player/player_actions.cpp | 7 +- cockatrice/src/game/player/player_actions.h | 9 ++- .../src/game/player/player_event_handler.cpp | 4 +- cockatrice/src/game/player/player_info.h | 2 +- cockatrice/src/game/player/player_logic.cpp | 10 +-- cockatrice/src/game/player/player_logic.h | 5 +- cockatrice/src/game/replay.cpp | 4 +- cockatrice/src/game/replay.h | 2 +- cockatrice/src/game/zones/card_zone_logic.cpp | 2 +- cockatrice/src/game/zones/hand_zone_logic.cpp | 2 +- cockatrice/src/game/zones/pile_zone_logic.cpp | 2 +- .../src/game/zones/stack_zone_logic.cpp | 2 +- .../src/game/zones/table_zone_logic.cpp | 2 +- cockatrice/src/game/zones/view_zone_logic.cpp | 2 +- .../board/abstract_card_drag_item.cpp | 0 .../board/abstract_card_drag_item.h | 0 .../board/abstract_card_item.cpp | 0 .../board/abstract_card_item.h | 2 +- .../board/abstract_counter.cpp | 6 +- .../board/abstract_counter.h | 2 +- .../board/arrow_item.cpp | 6 +- .../board/arrow_item.h | 2 +- .../board/arrow_target.cpp | 2 +- .../board/arrow_target.h | 2 +- .../board/card_drag_item.cpp | 6 +- .../board/card_drag_item.h | 0 .../board/card_item.cpp | 17 ++--- .../{game => game_graphics}/board/card_item.h | 4 +- .../board/counter_general.cpp | 2 +- .../board/counter_general.h | 0 .../board/translate_counter_name.cpp | 0 .../board/translate_counter_name.h | 0 .../{game => game_graphics}/card_dimensions.h | 0 .../deckview/deck_view.cpp | 0 .../deckview/deck_view.h | 0 .../deckview/deck_view_container.cpp | 0 .../deckview/deck_view_container.h | 0 .../deckview/tabbed_deck_view_container.cpp | 0 .../deckview/tabbed_deck_view_container.h | 0 .../dialogs/dlg_create_token.cpp | 0 .../dialogs/dlg_create_token.h | 0 .../dialogs/dlg_move_top_cards_until.cpp | 0 .../dialogs/dlg_move_top_cards_until.h | 0 .../dialogs/dlg_roll_dice.cpp | 0 .../dialogs/dlg_roll_dice.h | 0 .../{game => game_graphics}/game_scene.cpp | 14 ++-- .../src/{game => game_graphics}/game_scene.h | 6 +- .../src/{game => game_graphics}/game_view.cpp | 0 .../src/{game => game_graphics}/game_view.h | 0 .../{game => game_graphics}/hand_counter.cpp | 2 +- .../{game => game_graphics}/hand_counter.h | 4 +- .../log/message_log_widget.cpp | 6 +- .../log/message_log_widget.h | 2 +- .../phases_toolbar.cpp | 0 .../{game => game_graphics}/phases_toolbar.h | 2 +- .../player/card_menu_action_type.h | 0 .../player/menu/abstract_player_component.h | 0 .../player/menu/card_menu.cpp | 6 +- .../player/menu/card_menu.h | 0 .../player/menu/custom_zone_menu.cpp | 3 +- .../player/menu/custom_zone_menu.h | 0 .../player/menu/grave_menu.cpp | 7 +- .../player/menu/grave_menu.h | 0 .../player/menu/hand_menu.cpp | 6 +- .../player/menu/hand_menu.h | 0 .../player/menu/library_menu.cpp | 7 +- .../player/menu/library_menu.h | 0 .../player/menu/move_menu.cpp | 5 +- .../player/menu/move_menu.h | 0 .../player/menu/player_menu.cpp | 1 + .../player/menu/player_menu.h | 0 .../player/menu/pt_menu.cpp | 5 +- .../player/menu/pt_menu.h | 0 .../player/menu/rfg_menu.cpp | 5 +- .../player/menu/rfg_menu.h | 0 .../player/menu/say_menu.cpp | 5 +- .../player/menu/say_menu.h | 0 .../player/menu/sideboard_menu.cpp | 5 +- .../player/menu/sideboard_menu.h | 0 .../player/menu/utility_menu.cpp | 5 +- .../player/menu/utility_menu.h | 0 .../player/player_area.cpp | 0 .../player/player_area.h | 2 +- .../player/player_dialogs.cpp | 0 .../player/player_dialogs.h | 3 +- .../player/player_graphics_item.cpp | 11 +-- .../player/player_graphics_item.h | 3 +- .../player/player_list_widget.cpp | 0 .../player/player_list_widget.h | 2 +- .../player/player_target.cpp | 2 +- .../player/player_target.h | 2 +- .../z_value_layer_manager.h | 0 .../src/{game => game_graphics}/z_values.h | 0 .../src/game_graphics/zones/card_zone.cpp | 2 +- .../src/game_graphics/zones/hand_zone.cpp | 4 +- .../src/game_graphics/zones/pile_zone.cpp | 4 +- .../src/game_graphics/zones/select_zone.cpp | 4 +- .../src/game_graphics/zones/stack_zone.cpp | 6 +- .../src/game_graphics/zones/table_zone.cpp | 8 +- .../src/game_graphics/zones/table_zone.h | 2 +- .../src/game_graphics/zones/view_zone.cpp | 4 +- .../game_graphics/zones/view_zone_widget.cpp | 6 +- .../cards/card_info_display_widget.cpp | 2 +- .../widgets/cards/card_info_frame_widget.cpp | 2 +- .../cards/card_info_picture_widget.cpp | 2 +- .../widgets/cards/card_info_text_widget.cpp | 2 +- .../src/interface/widgets/tabs/tab_game.cpp | 26 ++++--- .../src/interface/widgets/tabs/tab_game.h | 3 +- 116 files changed, 208 insertions(+), 198 deletions(-) rename cockatrice/src/{game => game_graphics}/board/abstract_card_drag_item.cpp (100%) rename cockatrice/src/{game => game_graphics}/board/abstract_card_drag_item.h (100%) rename cockatrice/src/{game => game_graphics}/board/abstract_card_item.cpp (100%) rename cockatrice/src/{game => game_graphics}/board/abstract_card_item.h (98%) rename cockatrice/src/{game => game_graphics}/board/abstract_counter.cpp (97%) rename cockatrice/src/{game => game_graphics}/board/abstract_counter.h (98%) rename cockatrice/src/{game => game_graphics}/board/arrow_item.cpp (99%) rename cockatrice/src/{game => game_graphics}/board/arrow_item.h (98%) rename cockatrice/src/{game => game_graphics}/board/arrow_target.cpp (92%) rename cockatrice/src/{game => game_graphics}/board/arrow_target.h (93%) rename cockatrice/src/{game => game_graphics}/board/card_drag_item.cpp (96%) rename cockatrice/src/{game => game_graphics}/board/card_drag_item.h (100%) rename cockatrice/src/{game => game_graphics}/board/card_item.cpp (98%) rename cockatrice/src/{game => game_graphics}/board/card_item.h (98%) rename cockatrice/src/{game => game_graphics}/board/counter_general.cpp (95%) rename cockatrice/src/{game => game_graphics}/board/counter_general.h (100%) rename cockatrice/src/{game => game_graphics}/board/translate_counter_name.cpp (100%) rename cockatrice/src/{game => game_graphics}/board/translate_counter_name.h (100%) rename cockatrice/src/{game => game_graphics}/card_dimensions.h (100%) rename cockatrice/src/{game => game_graphics}/deckview/deck_view.cpp (100%) rename cockatrice/src/{game => game_graphics}/deckview/deck_view.h (100%) rename cockatrice/src/{game => game_graphics}/deckview/deck_view_container.cpp (100%) rename cockatrice/src/{game => game_graphics}/deckview/deck_view_container.h (100%) rename cockatrice/src/{game => game_graphics}/deckview/tabbed_deck_view_container.cpp (100%) rename cockatrice/src/{game => game_graphics}/deckview/tabbed_deck_view_container.h (100%) rename cockatrice/src/{game => game_graphics}/dialogs/dlg_create_token.cpp (100%) rename cockatrice/src/{game => game_graphics}/dialogs/dlg_create_token.h (100%) rename cockatrice/src/{game => game_graphics}/dialogs/dlg_move_top_cards_until.cpp (100%) rename cockatrice/src/{game => game_graphics}/dialogs/dlg_move_top_cards_until.h (100%) rename cockatrice/src/{game => game_graphics}/dialogs/dlg_roll_dice.cpp (100%) rename cockatrice/src/{game => game_graphics}/dialogs/dlg_roll_dice.h (100%) rename cockatrice/src/{game => game_graphics}/game_scene.cpp (98%) rename cockatrice/src/{game => game_graphics}/game_scene.h (98%) rename cockatrice/src/{game => game_graphics}/game_view.cpp (100%) rename cockatrice/src/{game => game_graphics}/game_view.h (100%) rename cockatrice/src/{game => game_graphics}/hand_counter.cpp (96%) rename cockatrice/src/{game => game_graphics}/hand_counter.h (87%) rename cockatrice/src/{game => game_graphics}/log/message_log_widget.cpp (99%) rename cockatrice/src/{game => game_graphics}/log/message_log_widget.h (99%) rename cockatrice/src/{game => game_graphics}/phases_toolbar.cpp (100%) rename cockatrice/src/{game => game_graphics}/phases_toolbar.h (97%) rename cockatrice/src/{game => game_graphics}/player/card_menu_action_type.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/abstract_player_component.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/card_menu.cpp (99%) rename cockatrice/src/{game => game_graphics}/player/menu/card_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/custom_zone_menu.cpp (93%) rename cockatrice/src/{game => game_graphics}/player/menu/custom_zone_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/grave_menu.cpp (96%) rename cockatrice/src/{game => game_graphics}/player/menu/grave_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/hand_menu.cpp (98%) rename cockatrice/src/{game => game_graphics}/player/menu/hand_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/library_menu.cpp (99%) rename cockatrice/src/{game => game_graphics}/player/menu/library_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/move_menu.cpp (96%) rename cockatrice/src/{game => game_graphics}/player/menu/move_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/player_menu.cpp (99%) rename cockatrice/src/{game => game_graphics}/player/menu/player_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/pt_menu.cpp (96%) rename cockatrice/src/{game => game_graphics}/player/menu/pt_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/rfg_menu.cpp (95%) rename cockatrice/src/{game => game_graphics}/player/menu/rfg_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/say_menu.cpp (91%) rename cockatrice/src/{game => game_graphics}/player/menu/say_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/sideboard_menu.cpp (87%) rename cockatrice/src/{game => game_graphics}/player/menu/sideboard_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/menu/utility_menu.cpp (97%) rename cockatrice/src/{game => game_graphics}/player/menu/utility_menu.h (100%) rename cockatrice/src/{game => game_graphics}/player/player_area.cpp (100%) rename cockatrice/src/{game => game_graphics}/player/player_area.h (94%) rename cockatrice/src/{game => game_graphics}/player/player_dialogs.cpp (100%) rename cockatrice/src/{game => game_graphics}/player/player_dialogs.h (96%) rename cockatrice/src/{game => game_graphics}/player/player_graphics_item.cpp (97%) rename cockatrice/src/{game => game_graphics}/player/player_graphics_item.h (98%) rename cockatrice/src/{game => game_graphics}/player/player_list_widget.cpp (100%) rename cockatrice/src/{game => game_graphics}/player/player_list_widget.h (97%) rename cockatrice/src/{game => game_graphics}/player/player_target.cpp (99%) rename cockatrice/src/{game => game_graphics}/player/player_target.h (95%) rename cockatrice/src/{game => game_graphics}/z_value_layer_manager.h (100%) rename cockatrice/src/{game => game_graphics}/z_values.h (100%) diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index f0e363e18..bd99d08bf 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -57,57 +57,57 @@ set(cockatrice_SOURCES src/filters/syntax_help.cpp src/game/abstract_game.cpp src/game/arrow_registry.cpp - src/game/board/abstract_card_drag_item.cpp - src/game/board/abstract_card_item.cpp - src/game/board/abstract_counter.cpp + src/game_graphics/board/abstract_card_drag_item.cpp + src/game_graphics/board/abstract_card_item.cpp + src/game_graphics/board/abstract_counter.cpp src/game/board/arrow_data.cpp - src/game/board/arrow_item.cpp - src/game/board/arrow_target.cpp - src/game/board/card_drag_item.cpp - src/game/board/card_item.cpp + src/game_graphics/board/arrow_item.cpp + src/game_graphics/board/arrow_target.cpp + src/game_graphics/board/card_drag_item.cpp + src/game_graphics/board/card_item.cpp src/game/board/card_list.cpp src/game/board/card_state.cpp - src/game/board/counter_general.cpp + src/game_graphics/board/counter_general.cpp src/game/board/counter_state.cpp - src/game/board/translate_counter_name.cpp - src/game/deckview/deck_view.cpp - src/game/deckview/deck_view_container.cpp - src/game/deckview/tabbed_deck_view_container.cpp - src/game/dialogs/dlg_create_token.cpp - src/game/dialogs/dlg_move_top_cards_until.cpp - src/game/dialogs/dlg_roll_dice.cpp + src/game_graphics/board/translate_counter_name.cpp + src/game_graphics/deckview/deck_view.cpp + src/game_graphics/deckview/deck_view_container.cpp + src/game_graphics/deckview/tabbed_deck_view_container.cpp + src/game_graphics/dialogs/dlg_create_token.cpp + src/game_graphics/dialogs/dlg_move_top_cards_until.cpp + src/game_graphics/dialogs/dlg_roll_dice.cpp src/game/game.cpp src/game/game_event_handler.cpp src/game/game_meta_info.cpp - src/game/game_scene.cpp + src/game_graphics/game_scene.cpp src/game/game_state.cpp - src/game/game_view.cpp - src/game/hand_counter.cpp - src/game/log/message_log_widget.cpp + src/game_graphics/game_view.cpp + src/game_graphics/hand_counter.cpp + src/game_graphics/log/message_log_widget.cpp src/game/phase.cpp - src/game/phases_toolbar.cpp - src/game/player/menu/card_menu.cpp - src/game/player/menu/custom_zone_menu.cpp - src/game/player/menu/grave_menu.cpp - src/game/player/menu/hand_menu.cpp - src/game/player/menu/library_menu.cpp - src/game/player/menu/move_menu.cpp - src/game/player/menu/player_menu.cpp - src/game/player/menu/pt_menu.cpp - src/game/player/menu/rfg_menu.cpp - src/game/player/menu/say_menu.cpp - src/game/player/menu/sideboard_menu.cpp - src/game/player/menu/utility_menu.cpp + src/game_graphics/phases_toolbar.cpp + src/game_graphics/player/menu/card_menu.cpp + src/game_graphics/player/menu/custom_zone_menu.cpp + src/game_graphics/player/menu/grave_menu.cpp + src/game_graphics/player/menu/hand_menu.cpp + src/game_graphics/player/menu/library_menu.cpp + src/game_graphics/player/menu/move_menu.cpp + src/game_graphics/player/menu/player_menu.cpp + src/game_graphics/player/menu/pt_menu.cpp + src/game_graphics/player/menu/rfg_menu.cpp + src/game_graphics/player/menu/say_menu.cpp + src/game_graphics/player/menu/sideboard_menu.cpp + src/game_graphics/player/menu/utility_menu.cpp src/game/player/player_actions.cpp - src/game/player/player_area.cpp - src/game/player/player_dialogs.cpp + src/game_graphics/player/player_area.cpp + src/game_graphics/player/player_dialogs.cpp src/game/player/player_event_handler.cpp - src/game/player/player_graphics_item.cpp + src/game_graphics/player/player_graphics_item.cpp src/game/player/player_info.cpp - src/game/player/player_list_widget.cpp + src/game_graphics/player/player_list_widget.cpp src/game/player/player_logic.cpp src/game/player/player_manager.cpp - src/game/player/player_target.cpp + src/game_graphics/player/player_target.cpp src/game/replay.cpp src/game/zones/card_zone_logic.cpp src/game/zones/hand_zone_logic.cpp diff --git a/cockatrice/src/game/abstract_game.cpp b/cockatrice/src/game/abstract_game.cpp index 5b1b4bff2..c20003ece 100644 --- a/cockatrice/src/game/abstract_game.cpp +++ b/cockatrice/src/game/abstract_game.cpp @@ -3,7 +3,7 @@ #include "../interface/widgets/tabs/tab_game.h" #include "player/player_logic.h" -AbstractGame::AbstractGame(TabGame *_tab) : QObject(_tab), tab(_tab) +AbstractGame::AbstractGame(QObject *_parent) : QObject(_parent) { gameMetaInfo = new GameMetaInfo(this); gameEventHandler = new GameEventHandler(this); diff --git a/cockatrice/src/game/abstract_game.h b/cockatrice/src/game/abstract_game.h index 2441bac2d..5115ed5ca 100644 --- a/cockatrice/src/game/abstract_game.h +++ b/cockatrice/src/game/abstract_game.h @@ -16,26 +16,19 @@ #include class CardItem; -class TabGame; class AbstractGame : public QObject { Q_OBJECT public: - explicit AbstractGame(TabGame *tab); + explicit AbstractGame(QObject *parent); - TabGame *tab; GameMetaInfo *gameMetaInfo; GameState *gameState; GameEventHandler *gameEventHandler; PlayerManager *playerManager; CardItem *activeCard; - TabGame *getTab() const - { - return tab; - } - GameMetaInfo *getGameMetaInfo() { return gameMetaInfo; diff --git a/cockatrice/src/game/arrow_registry.cpp b/cockatrice/src/game/arrow_registry.cpp index e679d2972..286764b3b 100644 --- a/cockatrice/src/game/arrow_registry.cpp +++ b/cockatrice/src/game/arrow_registry.cpp @@ -1,6 +1,6 @@ #include "arrow_registry.h" -#include "board/arrow_item.h" +#include "../game_graphics/board/arrow_item.h" void ArrowRegistry::insert(QSharedPointer data, ArrowItem *arrow) { diff --git a/cockatrice/src/game/board/card_list.cpp b/cockatrice/src/game/board/card_list.cpp index c324ca10a..0080b5ae6 100644 --- a/cockatrice/src/game/board/card_list.cpp +++ b/cockatrice/src/game/board/card_list.cpp @@ -1,6 +1,6 @@ #include "card_list.h" -#include "card_item.h" +#include "../../game_graphics/board/card_item.h" #include #include diff --git a/cockatrice/src/game/game.cpp b/cockatrice/src/game/game.cpp index 38477f7f7..4c8b109c2 100644 --- a/cockatrice/src/game/game.cpp +++ b/cockatrice/src/game/game.cpp @@ -4,16 +4,16 @@ #include -Game::Game(TabGame *_tab, +Game::Game(QObject *_parent, + bool isLocalGame, QList &_clients, const Event_GameJoined &event, const QMap &_roomGameTypes) - : AbstractGame(_tab) + : AbstractGame(_parent) { gameMetaInfo->setFromProto(event.game_info()); gameMetaInfo->setRoomGameTypes(_roomGameTypes); - gameState = new GameState(this, 0, event.host_id(), tab->getTabSupervisor()->getIsLocalGame(), _clients, false, - event.resuming(), -1, false); + gameState = new GameState(this, 0, event.host_id(), isLocalGame, _clients, false, event.resuming(), -1, false); connect(gameMetaInfo, &GameMetaInfo::startedChanged, gameState, &GameState::onStartedChanged); playerManager = new PlayerManager(this, event.player_id(), event.judge(), event.spectator()); gameMetaInfo->setStarted(false); diff --git a/cockatrice/src/game/game.h b/cockatrice/src/game/game.h index ccdb679df..4f912664c 100644 --- a/cockatrice/src/game/game.h +++ b/cockatrice/src/game/game.h @@ -16,7 +16,8 @@ class Game : public AbstractGame Q_OBJECT public: - Game(TabGame *tab, + Game(QObject *parent, + bool isLocalGame, QList &_clients, const Event_GameJoined &event, const QMap &_roomGameTypes); diff --git a/cockatrice/src/game/game_event_handler.cpp b/cockatrice/src/game/game_event_handler.cpp index 629e2f6a1..4a96eebdb 100644 --- a/cockatrice/src/game/game_event_handler.cpp +++ b/cockatrice/src/game/game_event_handler.cpp @@ -1,8 +1,8 @@ #include "game_event_handler.h" +#include "../game_graphics/log/message_log_widget.h" #include "../interface/widgets/tabs/tab_game.h" #include "abstract_game.h" -#include "log/message_log_widget.h" #include #include diff --git a/cockatrice/src/game/player/player_actions.cpp b/cockatrice/src/game/player/player_actions.cpp index 2b0428dd8..de909ca5e 100644 --- a/cockatrice/src/game/player/player_actions.cpp +++ b/cockatrice/src/game/player/player_actions.cpp @@ -1,14 +1,13 @@ #include "player_actions.h" +#include "../../game_graphics/dialogs/dlg_move_top_cards_until.h" +#include "../../game_graphics/dialogs/dlg_roll_dice.h" +#include "../../game_graphics/player/card_menu_action_type.h" #include "../../game_graphics/zones/hand_zone.h" #include "../../game_graphics/zones/table_zone.h" #include "../../interface/widgets/tabs/tab_game.h" #include "../../interface/widgets/utility/get_text_with_max.h" -#include "../board/card_item.h" -#include "../dialogs/dlg_move_top_cards_until.h" -#include "../dialogs/dlg_roll_dice.h" #include "../zones/view_zone_logic.h" -#include "card_menu_action_type.h" #include #include diff --git a/cockatrice/src/game/player/player_actions.h b/cockatrice/src/game/player/player_actions.h index 2779fa5aa..3f1960892 100644 --- a/cockatrice/src/game/player/player_actions.h +++ b/cockatrice/src/game/player/player_actions.h @@ -7,9 +7,11 @@ #ifndef COCKATRICE_PLAYER_ACTIONS_H #define COCKATRICE_PLAYER_ACTIONS_H -#include "../dialogs/dlg_create_token.h" -#include "../dialogs/dlg_move_top_cards_until.h" -#include "card_menu_action_type.h" + +#include "../../game_graphics/board/card_item.h" +#include "../../game_graphics/dialogs/dlg_create_token.h" +#include "../../game_graphics/dialogs/dlg_move_top_cards_until.h" +#include "../../game_graphics/player/card_menu_action_type.h" #include "event_processing_options.h" #include "player_logic.h" @@ -26,7 +28,6 @@ class Message; } } // namespace google -class CardItem; class Command_MoveCard; class GameEventContext; class PendingCommand; diff --git a/cockatrice/src/game/player/player_event_handler.cpp b/cockatrice/src/game/player/player_event_handler.cpp index aa751170b..bc48298f7 100644 --- a/cockatrice/src/game/player/player_event_handler.cpp +++ b/cockatrice/src/game/player/player_event_handler.cpp @@ -1,10 +1,10 @@ #include "player_event_handler.h" +#include "../../game_graphics/board/arrow_item.h" +#include "../../game_graphics/board/card_item.h" #include "../../game_graphics/zones/view_zone.h" #include "../../interface/widgets/tabs/tab_game.h" #include "../board/arrow_data.h" -#include "../board/arrow_item.h" -#include "../board/card_item.h" #include "../board/card_list.h" #include "player_actions.h" #include "player_logic.h" diff --git a/cockatrice/src/game/player/player_info.h b/cockatrice/src/game/player/player_info.h index e67131ceb..4ec39edbd 100644 --- a/cockatrice/src/game/player/player_info.h +++ b/cockatrice/src/game/player/player_info.h @@ -7,7 +7,7 @@ #ifndef COCKATRICE_PLAYER_INFO_H #define COCKATRICE_PLAYER_INFO_H -#include "player_target.h" +#include "../../game_graphics/player/player_target.h" #include #include diff --git a/cockatrice/src/game/player/player_logic.cpp b/cockatrice/src/game/player/player_logic.cpp index b748eb19a..485e2fc5c 100644 --- a/cockatrice/src/game/player/player_logic.cpp +++ b/cockatrice/src/game/player/player_logic.cpp @@ -1,18 +1,18 @@ #include "player_logic.h" +#include "../../game_graphics/board/arrow_item.h" +#include "../../game_graphics/board/card_item.h" +#include "../../game_graphics/board/counter_general.h" +#include "../../game_graphics/game_scene.h" +#include "../../game_graphics/player/player_target.h" #include "../../game_graphics/zones/hand_zone.h" #include "../../game_graphics/zones/pile_zone.h" #include "../../game_graphics/zones/stack_zone.h" #include "../../game_graphics/zones/table_zone.h" #include "../../interface/theme_manager.h" #include "../../interface/widgets/tabs/tab_game.h" -#include "../board/arrow_item.h" -#include "../board/card_item.h" #include "../board/card_list.h" -#include "../board/counter_general.h" -#include "../game_scene.h" #include "player_actions.h" -#include "player_target.h" #include #include diff --git a/cockatrice/src/game/player/player_logic.h b/cockatrice/src/game/player/player_logic.h index c83892dea..a89cb6eed 100644 --- a/cockatrice/src/game/player/player_logic.h +++ b/cockatrice/src/game/player/player_logic.h @@ -7,6 +7,7 @@ #ifndef PLAYER_H #define PLAYER_H +#include "../../game_graphics/player/player_area.h" #include "../../interface/widgets/menus/tearoff_menu.h" #include "../board/arrow_data.h" #include "../interface/deck_loader/loaded_deck.h" @@ -14,10 +15,7 @@ #include "../zones/pile_zone_logic.h" #include "../zones/stack_zone_logic.h" #include "../zones/table_zone_logic.h" -#include "menu/player_menu.h" -#include "player_area.h" #include "player_event_handler.h" -#include "player_graphics_item.h" #include "player_info.h" #include @@ -54,6 +52,7 @@ class PlayerMenu; class QAction; class QMenu; class ServerInfo_Arrow; +class ServerInfo_Card; class ServerInfo_Counter; class ServerInfo_Player; class ServerInfo_User; diff --git a/cockatrice/src/game/replay.cpp b/cockatrice/src/game/replay.cpp index 6886f817a..69f9d8b20 100644 --- a/cockatrice/src/game/replay.cpp +++ b/cockatrice/src/game/replay.cpp @@ -2,9 +2,9 @@ #include "../interface/widgets/tabs/tab_game.h" -Replay::Replay(TabGame *_tab, GameReplay *_replay) : AbstractGame(_tab) +Replay::Replay(QObject *_parent, GameReplay *_replay, bool isLocalGame) : AbstractGame(_parent) { - gameState = new GameState(this, 0, -1, tab->getTabSupervisor()->getIsLocalGame(), {}, false, false, -1, false); + gameState = new GameState(this, 0, -1, isLocalGame, {}, false, false, -1, false); connect(gameMetaInfo, &GameMetaInfo::startedChanged, gameState, &GameState::onStartedChanged); playerManager = new PlayerManager(this, -1, false, true); loadReplay(_replay); diff --git a/cockatrice/src/game/replay.h b/cockatrice/src/game/replay.h index b837e4b8c..ecb3a10d0 100644 --- a/cockatrice/src/game/replay.h +++ b/cockatrice/src/game/replay.h @@ -15,7 +15,7 @@ class Replay : public AbstractGame Q_OBJECT public: - explicit Replay(TabGame *_tab, GameReplay *_replay); + explicit Replay(QObject *_parent, GameReplay *_replay, bool isLocalGame); }; #endif // COCKATRICE_REPLAY_H diff --git a/cockatrice/src/game/zones/card_zone_logic.cpp b/cockatrice/src/game/zones/card_zone_logic.cpp index aace7097e..7e0585f4e 100644 --- a/cockatrice/src/game/zones/card_zone_logic.cpp +++ b/cockatrice/src/game/zones/card_zone_logic.cpp @@ -1,7 +1,7 @@ #include "card_zone_logic.h" +#include "../../game_graphics/board/card_item.h" #include "../../game_graphics/zones/view_zone.h" -#include "../board/card_item.h" #include "../player/player_actions.h" #include "../player/player_logic.h" #include "view_zone_logic.h" diff --git a/cockatrice/src/game/zones/hand_zone_logic.cpp b/cockatrice/src/game/zones/hand_zone_logic.cpp index 36af11131..3bdd15902 100644 --- a/cockatrice/src/game/zones/hand_zone_logic.cpp +++ b/cockatrice/src/game/zones/hand_zone_logic.cpp @@ -1,6 +1,6 @@ #include "hand_zone_logic.h" -#include "../board/card_item.h" +#include "../../game_graphics/board/card_item.h" #include "card_zone_algorithms.h" HandZoneLogic::HandZoneLogic(PlayerLogic *_player, diff --git a/cockatrice/src/game/zones/pile_zone_logic.cpp b/cockatrice/src/game/zones/pile_zone_logic.cpp index 66edde4b7..0f374fb84 100644 --- a/cockatrice/src/game/zones/pile_zone_logic.cpp +++ b/cockatrice/src/game/zones/pile_zone_logic.cpp @@ -1,6 +1,6 @@ #include "pile_zone_logic.h" -#include "../board/card_item.h" +#include "../../game_graphics/board/card_item.h" PileZoneLogic::PileZoneLogic(PlayerLogic *_player, const QString &_name, diff --git a/cockatrice/src/game/zones/stack_zone_logic.cpp b/cockatrice/src/game/zones/stack_zone_logic.cpp index 2120b9a1d..341d4b0e4 100644 --- a/cockatrice/src/game/zones/stack_zone_logic.cpp +++ b/cockatrice/src/game/zones/stack_zone_logic.cpp @@ -1,6 +1,6 @@ #include "stack_zone_logic.h" -#include "../board/card_item.h" +#include "../../game_graphics/board/card_item.h" #include "card_zone_algorithms.h" StackZoneLogic::StackZoneLogic(PlayerLogic *_player, diff --git a/cockatrice/src/game/zones/table_zone_logic.cpp b/cockatrice/src/game/zones/table_zone_logic.cpp index 3d7ac4297..a4f033819 100644 --- a/cockatrice/src/game/zones/table_zone_logic.cpp +++ b/cockatrice/src/game/zones/table_zone_logic.cpp @@ -1,6 +1,6 @@ #include "table_zone_logic.h" -#include "../board/card_item.h" +#include "../../game_graphics/board/card_item.h" TableZoneLogic::TableZoneLogic(PlayerLogic *_player, const QString &_name, diff --git a/cockatrice/src/game/zones/view_zone_logic.cpp b/cockatrice/src/game/zones/view_zone_logic.cpp index fa4a73d38..8782a1762 100644 --- a/cockatrice/src/game/zones/view_zone_logic.cpp +++ b/cockatrice/src/game/zones/view_zone_logic.cpp @@ -1,7 +1,7 @@ #include "view_zone_logic.h" #include "../../client/settings/cache_settings.h" -#include "../board/card_item.h" +#include "../../game_graphics/board/card_item.h" /** * @param _player the player that the cards are revealed to. diff --git a/cockatrice/src/game/board/abstract_card_drag_item.cpp b/cockatrice/src/game_graphics/board/abstract_card_drag_item.cpp similarity index 100% rename from cockatrice/src/game/board/abstract_card_drag_item.cpp rename to cockatrice/src/game_graphics/board/abstract_card_drag_item.cpp diff --git a/cockatrice/src/game/board/abstract_card_drag_item.h b/cockatrice/src/game_graphics/board/abstract_card_drag_item.h similarity index 100% rename from cockatrice/src/game/board/abstract_card_drag_item.h rename to cockatrice/src/game_graphics/board/abstract_card_drag_item.h diff --git a/cockatrice/src/game/board/abstract_card_item.cpp b/cockatrice/src/game_graphics/board/abstract_card_item.cpp similarity index 100% rename from cockatrice/src/game/board/abstract_card_item.cpp rename to cockatrice/src/game_graphics/board/abstract_card_item.cpp diff --git a/cockatrice/src/game/board/abstract_card_item.h b/cockatrice/src/game_graphics/board/abstract_card_item.h similarity index 98% rename from cockatrice/src/game/board/abstract_card_item.h rename to cockatrice/src/game_graphics/board/abstract_card_item.h index 863954b73..bdb5f7cf1 100644 --- a/cockatrice/src/game/board/abstract_card_item.h +++ b/cockatrice/src/game_graphics/board/abstract_card_item.h @@ -7,9 +7,9 @@ #ifndef ABSTRACTCARDITEM_H #define ABSTRACTCARDITEM_H -#include "../../game_graphics/board/graphics_item_type.h" #include "../card_dimensions.h" #include "arrow_target.h" +#include "graphics_item_type.h" #include #include diff --git a/cockatrice/src/game/board/abstract_counter.cpp b/cockatrice/src/game_graphics/board/abstract_counter.cpp similarity index 97% rename from cockatrice/src/game/board/abstract_counter.cpp rename to cockatrice/src/game_graphics/board/abstract_counter.cpp index 18787a0bc..219dd456e 100644 --- a/cockatrice/src/game/board/abstract_counter.cpp +++ b/cockatrice/src/game_graphics/board/abstract_counter.cpp @@ -1,10 +1,10 @@ #include "abstract_counter.h" #include "../../client/settings/cache_settings.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" +#include "../../game_graphics/board/translate_counter_name.h" #include "../../interface/widgets/tabs/tab_game.h" -#include "../player/player_actions.h" -#include "../player/player_logic.h" -#include "translate_counter_name.h" #include #include diff --git a/cockatrice/src/game/board/abstract_counter.h b/cockatrice/src/game_graphics/board/abstract_counter.h similarity index 98% rename from cockatrice/src/game/board/abstract_counter.h rename to cockatrice/src/game_graphics/board/abstract_counter.h index b31bd1aa3..b319a722d 100644 --- a/cockatrice/src/game/board/abstract_counter.h +++ b/cockatrice/src/game_graphics/board/abstract_counter.h @@ -7,9 +7,9 @@ #ifndef COUNTER_H #define COUNTER_H +#include "../../game/board/counter_state.h" #include "../../interface/widgets/menus/tearoff_menu.h" #include "../player/menu/abstract_player_component.h" -#include "counter_state.h" #include #include diff --git a/cockatrice/src/game/board/arrow_item.cpp b/cockatrice/src/game_graphics/board/arrow_item.cpp similarity index 99% rename from cockatrice/src/game/board/arrow_item.cpp rename to cockatrice/src/game_graphics/board/arrow_item.cpp index 0b740bc70..af6a6bf36 100644 --- a/cockatrice/src/game/board/arrow_item.cpp +++ b/cockatrice/src/game_graphics/board/arrow_item.cpp @@ -2,11 +2,11 @@ #include "arrow_item.h" #include "../../client/settings/cache_settings.h" -#include "../../game_graphics/zones/card_zone.h" -#include "../player/player_actions.h" -#include "../player/player_logic.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" #include "../player/player_target.h" #include "../z_values.h" +#include "../zones/card_zone.h" #include "card_item.h" #include diff --git a/cockatrice/src/game/board/arrow_item.h b/cockatrice/src/game_graphics/board/arrow_item.h similarity index 98% rename from cockatrice/src/game/board/arrow_item.h rename to cockatrice/src/game_graphics/board/arrow_item.h index 0c04c27f8..1c306e065 100644 --- a/cockatrice/src/game/board/arrow_item.h +++ b/cockatrice/src/game_graphics/board/arrow_item.h @@ -1,7 +1,7 @@ #ifndef ARROWITEM_H #define ARROWITEM_H -#include "arrow_data.h" +#include "../../game/board/arrow_data.h" #include "arrow_target.h" #include diff --git a/cockatrice/src/game/board/arrow_target.cpp b/cockatrice/src/game_graphics/board/arrow_target.cpp similarity index 92% rename from cockatrice/src/game/board/arrow_target.cpp rename to cockatrice/src/game_graphics/board/arrow_target.cpp index edf526e4e..79b21d921 100644 --- a/cockatrice/src/game/board/arrow_target.cpp +++ b/cockatrice/src/game_graphics/board/arrow_target.cpp @@ -1,6 +1,6 @@ #include "arrow_target.h" -#include "../player/player_logic.h" +#include "../../game/player/player_logic.h" #include "arrow_item.h" ArrowTarget::ArrowTarget(PlayerLogic *_owner, QGraphicsItem *parent) : AbstractGraphicsItem(parent), owner(_owner) diff --git a/cockatrice/src/game/board/arrow_target.h b/cockatrice/src/game_graphics/board/arrow_target.h similarity index 93% rename from cockatrice/src/game/board/arrow_target.h rename to cockatrice/src/game_graphics/board/arrow_target.h index 664572705..bf89c5456 100644 --- a/cockatrice/src/game/board/arrow_target.h +++ b/cockatrice/src/game_graphics/board/arrow_target.h @@ -7,7 +7,7 @@ #ifndef ARROWTARGET_H #define ARROWTARGET_H -#include "../../game_graphics/board/abstract_graphics_item.h" +#include "abstract_graphics_item.h" #include diff --git a/cockatrice/src/game/board/card_drag_item.cpp b/cockatrice/src/game_graphics/board/card_drag_item.cpp similarity index 96% rename from cockatrice/src/game/board/card_drag_item.cpp rename to cockatrice/src/game_graphics/board/card_drag_item.cpp index 39fb9a390..49467c5c9 100644 --- a/cockatrice/src/game/board/card_drag_item.cpp +++ b/cockatrice/src/game_graphics/board/card_drag_item.cpp @@ -1,9 +1,9 @@ #include "card_drag_item.h" -#include "../../game_graphics/zones/card_zone.h" -#include "../../game_graphics/zones/table_zone.h" -#include "../../game_graphics/zones/view_zone.h" #include "../game_scene.h" +#include "../zones/card_zone.h" +#include "../zones/table_zone.h" +#include "../zones/view_zone.h" #include "card_item.h" #include diff --git a/cockatrice/src/game/board/card_drag_item.h b/cockatrice/src/game_graphics/board/card_drag_item.h similarity index 100% rename from cockatrice/src/game/board/card_drag_item.h rename to cockatrice/src/game_graphics/board/card_drag_item.h diff --git a/cockatrice/src/game/board/card_item.cpp b/cockatrice/src/game_graphics/board/card_item.cpp similarity index 98% rename from cockatrice/src/game/board/card_item.cpp rename to cockatrice/src/game_graphics/board/card_item.cpp index 029822805..cabe988c2 100644 --- a/cockatrice/src/game/board/card_item.cpp +++ b/cockatrice/src/game_graphics/board/card_item.cpp @@ -1,14 +1,14 @@ #include "card_item.h" #include "../../client/settings/cache_settings.h" -#include "../../game_graphics/zones/table_zone.h" -#include "../../game_graphics/zones/view_zone.h" +#include "../../game/phase.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" +#include "../../game/zones/view_zone_logic.h" #include "../../interface/widgets/tabs/tab_game.h" #include "../game_scene.h" -#include "../phase.h" -#include "../player/player_actions.h" -#include "../player/player_logic.h" -#include "../zones/view_zone_logic.h" +#include "../zones/table_zone.h" +#include "../zones/view_zone.h" #include "arrow_item.h" #include "card_drag_item.h" @@ -482,8 +482,7 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) (!SettingsCache::instance().getDoubleClickToPlay())) { handleClickedToPlay(event->modifiers().testFlag(Qt::ShiftModifier)); } - - if (owner != nullptr) { // cards without owner will be deleted + if (owner != nullptr) { setCursor(Qt::OpenHandCursor); } AbstractCardItem::mouseReleaseEvent(event); @@ -539,4 +538,4 @@ QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value) } return AbstractCardItem::itemChange(change, value); -} +} \ No newline at end of file diff --git a/cockatrice/src/game/board/card_item.h b/cockatrice/src/game_graphics/board/card_item.h similarity index 98% rename from cockatrice/src/game/board/card_item.h rename to cockatrice/src/game_graphics/board/card_item.h index 87f9667de..8efcd085d 100644 --- a/cockatrice/src/game/board/card_item.h +++ b/cockatrice/src/game_graphics/board/card_item.h @@ -7,9 +7,9 @@ #ifndef CARDITEM_H #define CARDITEM_H -#include "../zones/card_zone_logic.h" +#include "../../game/board/card_state.h" +#include "../../game/zones/card_zone_logic.h" #include "abstract_card_item.h" -#include "card_state.h" #include #include diff --git a/cockatrice/src/game/board/counter_general.cpp b/cockatrice/src/game_graphics/board/counter_general.cpp similarity index 95% rename from cockatrice/src/game/board/counter_general.cpp rename to cockatrice/src/game_graphics/board/counter_general.cpp index 5147ede6b..379c6f837 100644 --- a/cockatrice/src/game/board/counter_general.cpp +++ b/cockatrice/src/game_graphics/board/counter_general.cpp @@ -1,7 +1,7 @@ #include "counter_general.h" -#include "../../game_graphics/board/abstract_graphics_item.h" #include "../../interface/pixel_map_generator.h" +#include "abstract_graphics_item.h" #include diff --git a/cockatrice/src/game/board/counter_general.h b/cockatrice/src/game_graphics/board/counter_general.h similarity index 100% rename from cockatrice/src/game/board/counter_general.h rename to cockatrice/src/game_graphics/board/counter_general.h diff --git a/cockatrice/src/game/board/translate_counter_name.cpp b/cockatrice/src/game_graphics/board/translate_counter_name.cpp similarity index 100% rename from cockatrice/src/game/board/translate_counter_name.cpp rename to cockatrice/src/game_graphics/board/translate_counter_name.cpp diff --git a/cockatrice/src/game/board/translate_counter_name.h b/cockatrice/src/game_graphics/board/translate_counter_name.h similarity index 100% rename from cockatrice/src/game/board/translate_counter_name.h rename to cockatrice/src/game_graphics/board/translate_counter_name.h diff --git a/cockatrice/src/game/card_dimensions.h b/cockatrice/src/game_graphics/card_dimensions.h similarity index 100% rename from cockatrice/src/game/card_dimensions.h rename to cockatrice/src/game_graphics/card_dimensions.h diff --git a/cockatrice/src/game/deckview/deck_view.cpp b/cockatrice/src/game_graphics/deckview/deck_view.cpp similarity index 100% rename from cockatrice/src/game/deckview/deck_view.cpp rename to cockatrice/src/game_graphics/deckview/deck_view.cpp diff --git a/cockatrice/src/game/deckview/deck_view.h b/cockatrice/src/game_graphics/deckview/deck_view.h similarity index 100% rename from cockatrice/src/game/deckview/deck_view.h rename to cockatrice/src/game_graphics/deckview/deck_view.h diff --git a/cockatrice/src/game/deckview/deck_view_container.cpp b/cockatrice/src/game_graphics/deckview/deck_view_container.cpp similarity index 100% rename from cockatrice/src/game/deckview/deck_view_container.cpp rename to cockatrice/src/game_graphics/deckview/deck_view_container.cpp diff --git a/cockatrice/src/game/deckview/deck_view_container.h b/cockatrice/src/game_graphics/deckview/deck_view_container.h similarity index 100% rename from cockatrice/src/game/deckview/deck_view_container.h rename to cockatrice/src/game_graphics/deckview/deck_view_container.h diff --git a/cockatrice/src/game/deckview/tabbed_deck_view_container.cpp b/cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.cpp similarity index 100% rename from cockatrice/src/game/deckview/tabbed_deck_view_container.cpp rename to cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.cpp diff --git a/cockatrice/src/game/deckview/tabbed_deck_view_container.h b/cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.h similarity index 100% rename from cockatrice/src/game/deckview/tabbed_deck_view_container.h rename to cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.h diff --git a/cockatrice/src/game/dialogs/dlg_create_token.cpp b/cockatrice/src/game_graphics/dialogs/dlg_create_token.cpp similarity index 100% rename from cockatrice/src/game/dialogs/dlg_create_token.cpp rename to cockatrice/src/game_graphics/dialogs/dlg_create_token.cpp diff --git a/cockatrice/src/game/dialogs/dlg_create_token.h b/cockatrice/src/game_graphics/dialogs/dlg_create_token.h similarity index 100% rename from cockatrice/src/game/dialogs/dlg_create_token.h rename to cockatrice/src/game_graphics/dialogs/dlg_create_token.h diff --git a/cockatrice/src/game/dialogs/dlg_move_top_cards_until.cpp b/cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.cpp similarity index 100% rename from cockatrice/src/game/dialogs/dlg_move_top_cards_until.cpp rename to cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.cpp diff --git a/cockatrice/src/game/dialogs/dlg_move_top_cards_until.h b/cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.h similarity index 100% rename from cockatrice/src/game/dialogs/dlg_move_top_cards_until.h rename to cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.h diff --git a/cockatrice/src/game/dialogs/dlg_roll_dice.cpp b/cockatrice/src/game_graphics/dialogs/dlg_roll_dice.cpp similarity index 100% rename from cockatrice/src/game/dialogs/dlg_roll_dice.cpp rename to cockatrice/src/game_graphics/dialogs/dlg_roll_dice.cpp diff --git a/cockatrice/src/game/dialogs/dlg_roll_dice.h b/cockatrice/src/game_graphics/dialogs/dlg_roll_dice.h similarity index 100% rename from cockatrice/src/game/dialogs/dlg_roll_dice.h rename to cockatrice/src/game_graphics/dialogs/dlg_roll_dice.h diff --git a/cockatrice/src/game/game_scene.cpp b/cockatrice/src/game_graphics/game_scene.cpp similarity index 98% rename from cockatrice/src/game/game_scene.cpp rename to cockatrice/src/game_graphics/game_scene.cpp index dc55ecfe9..b9816a602 100644 --- a/cockatrice/src/game/game_scene.cpp +++ b/cockatrice/src/game_graphics/game_scene.cpp @@ -1,15 +1,17 @@ #include "game_scene.h" #include "../client/settings/cache_settings.h" -#include "../game_graphics/zones/select_zone.h" -#include "../game_graphics/zones/view_zone.h" -#include "../game_graphics/zones/view_zone_widget.h" -#include "abstract_game.h" +#include "../game/abstract_game.h" +#include "../game/player/player_actions.h" +#include "../game/player/player_logic.h" +#include "../game_graphics/player/player_graphics_item.h" #include "board/card_item.h" #include "phases_toolbar.h" -#include "player/player_actions.h" +#include "player/menu/player_menu.h" #include "player/player_graphics_item.h" -#include "player/player_logic.h" +#include "zones/select_zone.h" +#include "zones/view_zone.h" +#include "zones/view_zone_widget.h" #include #include diff --git a/cockatrice/src/game/game_scene.h b/cockatrice/src/game_graphics/game_scene.h similarity index 98% rename from cockatrice/src/game/game_scene.h rename to cockatrice/src/game_graphics/game_scene.h index 0587566d0..74e979556 100644 --- a/cockatrice/src/game/game_scene.h +++ b/cockatrice/src/game_graphics/game_scene.h @@ -1,10 +1,10 @@ #ifndef GAMESCENE_H #define GAMESCENE_H -#include "arrow_registry.h" -#include "board/arrow_data.h" +#include "../game/arrow_registry.h" +#include "../game/board/arrow_data.h" +#include "../game/zones/card_zone_logic.h" #include "board/arrow_item.h" -#include "zones/card_zone_logic.h" #include #include diff --git a/cockatrice/src/game/game_view.cpp b/cockatrice/src/game_graphics/game_view.cpp similarity index 100% rename from cockatrice/src/game/game_view.cpp rename to cockatrice/src/game_graphics/game_view.cpp diff --git a/cockatrice/src/game/game_view.h b/cockatrice/src/game_graphics/game_view.h similarity index 100% rename from cockatrice/src/game/game_view.h rename to cockatrice/src/game_graphics/game_view.h diff --git a/cockatrice/src/game/hand_counter.cpp b/cockatrice/src/game_graphics/hand_counter.cpp similarity index 96% rename from cockatrice/src/game/hand_counter.cpp rename to cockatrice/src/game_graphics/hand_counter.cpp index a853ae2de..35989ff38 100644 --- a/cockatrice/src/game/hand_counter.cpp +++ b/cockatrice/src/game_graphics/hand_counter.cpp @@ -1,6 +1,6 @@ #include "hand_counter.h" -#include "../game_graphics/zones/card_zone.h" +#include "zones/card_zone.h" #include #include diff --git a/cockatrice/src/game/hand_counter.h b/cockatrice/src/game_graphics/hand_counter.h similarity index 87% rename from cockatrice/src/game/hand_counter.h rename to cockatrice/src/game_graphics/hand_counter.h index 41ab3b5b2..9aa65d514 100644 --- a/cockatrice/src/game/hand_counter.h +++ b/cockatrice/src/game_graphics/hand_counter.h @@ -7,8 +7,8 @@ #ifndef HANDCOUNTER_H #define HANDCOUNTER_H -#include "../game_graphics/board/abstract_graphics_item.h" -#include "../game_graphics/board/graphics_item_type.h" +#include "board/abstract_graphics_item.h" +#include "board/graphics_item_type.h" #include diff --git a/cockatrice/src/game/log/message_log_widget.cpp b/cockatrice/src/game_graphics/log/message_log_widget.cpp similarity index 99% rename from cockatrice/src/game/log/message_log_widget.cpp rename to cockatrice/src/game_graphics/log/message_log_widget.cpp index 906f15c2e..ccd903b04 100644 --- a/cockatrice/src/game/log/message_log_widget.cpp +++ b/cockatrice/src/game_graphics/log/message_log_widget.cpp @@ -1,13 +1,13 @@ #include "message_log_widget.h" +#include "../../client/settings/card_counter_settings.h" #include "../../client/sound_engine.h" +#include "../../game/phase.h" +#include "../../game/player/player_logic.h" #include "../../interface/widgets/tabs/tab_game.h" #include "../board/card_item.h" #include "../board/translate_counter_name.h" -#include "../phase.h" -#include "../player/player_logic.h" -#include <../../client/settings/card_counter_settings.h> #include #include #include diff --git a/cockatrice/src/game/log/message_log_widget.h b/cockatrice/src/game_graphics/log/message_log_widget.h similarity index 99% rename from cockatrice/src/game/log/message_log_widget.h rename to cockatrice/src/game_graphics/log/message_log_widget.h index 9f1990ac4..a145d358d 100644 --- a/cockatrice/src/game/log/message_log_widget.h +++ b/cockatrice/src/game_graphics/log/message_log_widget.h @@ -7,8 +7,8 @@ #ifndef MESSAGELOGWIDGET_H #define MESSAGELOGWIDGET_H +#include "../../game/zones/card_zone_logic.h" #include "../../interface/widgets/server/chat_view/chat_view.h" -#include "../zones/card_zone_logic.h" class AbstractGame; class CardItem; diff --git a/cockatrice/src/game/phases_toolbar.cpp b/cockatrice/src/game_graphics/phases_toolbar.cpp similarity index 100% rename from cockatrice/src/game/phases_toolbar.cpp rename to cockatrice/src/game_graphics/phases_toolbar.cpp diff --git a/cockatrice/src/game/phases_toolbar.h b/cockatrice/src/game_graphics/phases_toolbar.h similarity index 97% rename from cockatrice/src/game/phases_toolbar.h rename to cockatrice/src/game_graphics/phases_toolbar.h index 6f0931d61..39884ef75 100644 --- a/cockatrice/src/game/phases_toolbar.h +++ b/cockatrice/src/game_graphics/phases_toolbar.h @@ -8,7 +8,7 @@ #ifndef PHASESTOOLBAR_H #define PHASESTOOLBAR_H -#include "../game_graphics/board/abstract_graphics_item.h" +#include "board/abstract_graphics_item.h" #include #include diff --git a/cockatrice/src/game/player/card_menu_action_type.h b/cockatrice/src/game_graphics/player/card_menu_action_type.h similarity index 100% rename from cockatrice/src/game/player/card_menu_action_type.h rename to cockatrice/src/game_graphics/player/card_menu_action_type.h diff --git a/cockatrice/src/game/player/menu/abstract_player_component.h b/cockatrice/src/game_graphics/player/menu/abstract_player_component.h similarity index 100% rename from cockatrice/src/game/player/menu/abstract_player_component.h rename to cockatrice/src/game_graphics/player/menu/abstract_player_component.h diff --git a/cockatrice/src/game/player/menu/card_menu.cpp b/cockatrice/src/game_graphics/player/menu/card_menu.cpp similarity index 99% rename from cockatrice/src/game/player/menu/card_menu.cpp rename to cockatrice/src/game_graphics/player/menu/card_menu.cpp index c1c33e37d..aa94c3be7 100644 --- a/cockatrice/src/game/player/menu/card_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/card_menu.cpp @@ -3,11 +3,11 @@ #include "../../../client/settings/card_counter_settings.h" #include "../../../interface/widgets/tabs/tab_game.h" #include "../../board/card_item.h" -#include "../../zones/view_zone_logic.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" +#include "../../game/zones/view_zone_logic.h" #include "../card_menu_action_type.h" -#include "../player_actions.h" #include "../player_graphics_item.h" -#include "../player_logic.h" #include "move_menu.h" #include "pt_menu.h" diff --git a/cockatrice/src/game/player/menu/card_menu.h b/cockatrice/src/game_graphics/player/menu/card_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/card_menu.h rename to cockatrice/src/game_graphics/player/menu/card_menu.h diff --git a/cockatrice/src/game/player/menu/custom_zone_menu.cpp b/cockatrice/src/game_graphics/player/menu/custom_zone_menu.cpp similarity index 93% rename from cockatrice/src/game/player/menu/custom_zone_menu.cpp rename to cockatrice/src/game_graphics/player/menu/custom_zone_menu.cpp index 106e646d9..743746cc8 100644 --- a/cockatrice/src/game/player/menu/custom_zone_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/custom_zone_menu.cpp @@ -1,6 +1,7 @@ #include "custom_zone_menu.h" -#include "../player_logic.h" +#include "../../game/player/player_logic.h" +#include "../player_graphics_item.h" CustomZoneMenu::CustomZoneMenu(PlayerGraphicsItem *_player) : player(_player) { diff --git a/cockatrice/src/game/player/menu/custom_zone_menu.h b/cockatrice/src/game_graphics/player/menu/custom_zone_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/custom_zone_menu.h rename to cockatrice/src/game_graphics/player/menu/custom_zone_menu.h diff --git a/cockatrice/src/game/player/menu/grave_menu.cpp b/cockatrice/src/game_graphics/player/menu/grave_menu.cpp similarity index 96% rename from cockatrice/src/game/player/menu/grave_menu.cpp rename to cockatrice/src/game_graphics/player/menu/grave_menu.cpp index 45762e900..698481f7a 100644 --- a/cockatrice/src/game/player/menu/grave_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/grave_menu.cpp @@ -1,8 +1,9 @@ #include "grave_menu.h" -#include "../../abstract_game.h" -#include "../player_actions.h" -#include "../player_logic.h" +#include "../../game/abstract_game.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" +#include "../player_graphics_item.h" #include #include diff --git a/cockatrice/src/game/player/menu/grave_menu.h b/cockatrice/src/game_graphics/player/menu/grave_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/grave_menu.h rename to cockatrice/src/game_graphics/player/menu/grave_menu.h diff --git a/cockatrice/src/game/player/menu/hand_menu.cpp b/cockatrice/src/game_graphics/player/menu/hand_menu.cpp similarity index 98% rename from cockatrice/src/game/player/menu/hand_menu.cpp rename to cockatrice/src/game_graphics/player/menu/hand_menu.cpp index 64a8c5754..ba0702f07 100644 --- a/cockatrice/src/game/player/menu/hand_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/hand_menu.cpp @@ -3,10 +3,10 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" #include "../../../game_graphics/zones/hand_zone.h" -#include "../../abstract_game.h" -#include "../player_actions.h" +#include "../../game/abstract_game.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" #include "../player_graphics_item.h" -#include "../player_logic.h" #include #include diff --git a/cockatrice/src/game/player/menu/hand_menu.h b/cockatrice/src/game_graphics/player/menu/hand_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/hand_menu.h rename to cockatrice/src/game_graphics/player/menu/hand_menu.h diff --git a/cockatrice/src/game/player/menu/library_menu.cpp b/cockatrice/src/game_graphics/player/menu/library_menu.cpp similarity index 99% rename from cockatrice/src/game/player/menu/library_menu.cpp rename to cockatrice/src/game_graphics/player/menu/library_menu.cpp index 00ab4592f..4c15e09ec 100644 --- a/cockatrice/src/game/player/menu/library_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/library_menu.cpp @@ -3,9 +3,10 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" #include "../../../interface/widgets/tabs/tab_game.h" -#include "../../abstract_game.h" -#include "../player_actions.h" -#include "../player_logic.h" +#include "../../game/abstract_game.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" +#include "../player_graphics_item.h" #include #include diff --git a/cockatrice/src/game/player/menu/library_menu.h b/cockatrice/src/game_graphics/player/menu/library_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/library_menu.h rename to cockatrice/src/game_graphics/player/menu/library_menu.h diff --git a/cockatrice/src/game/player/menu/move_menu.cpp b/cockatrice/src/game_graphics/player/menu/move_menu.cpp similarity index 96% rename from cockatrice/src/game/player/menu/move_menu.cpp rename to cockatrice/src/game_graphics/player/menu/move_menu.cpp index 9997aecf3..5b7209a9f 100644 --- a/cockatrice/src/game/player/menu/move_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/move_menu.cpp @@ -1,8 +1,9 @@ #include "move_menu.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" #include "../card_menu_action_type.h" -#include "../player_actions.h" -#include "../player_logic.h" +#include "../player_graphics_item.h" MoveMenu::MoveMenu(PlayerGraphicsItem *player) : QMenu(tr("Move to")) { diff --git a/cockatrice/src/game/player/menu/move_menu.h b/cockatrice/src/game_graphics/player/menu/move_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/move_menu.h rename to cockatrice/src/game_graphics/player/menu/move_menu.h diff --git a/cockatrice/src/game/player/menu/player_menu.cpp b/cockatrice/src/game_graphics/player/menu/player_menu.cpp similarity index 99% rename from cockatrice/src/game/player/menu/player_menu.cpp rename to cockatrice/src/game_graphics/player/menu/player_menu.cpp index 041b41052..17b791222 100644 --- a/cockatrice/src/game/player/menu/player_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/player_menu.cpp @@ -5,6 +5,7 @@ #include "../../../game_graphics/zones/table_zone.h" #include "../../../interface/widgets/tabs/tab_game.h" #include "../../board/card_item.h" +#include "../player_graphics_item.h" #include "card_menu.h" #include "hand_menu.h" diff --git a/cockatrice/src/game/player/menu/player_menu.h b/cockatrice/src/game_graphics/player/menu/player_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/player_menu.h rename to cockatrice/src/game_graphics/player/menu/player_menu.h diff --git a/cockatrice/src/game/player/menu/pt_menu.cpp b/cockatrice/src/game_graphics/player/menu/pt_menu.cpp similarity index 96% rename from cockatrice/src/game/player/menu/pt_menu.cpp rename to cockatrice/src/game_graphics/player/menu/pt_menu.cpp index 011271385..a01be9424 100644 --- a/cockatrice/src/game/player/menu/pt_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/pt_menu.cpp @@ -1,7 +1,8 @@ #include "pt_menu.h" -#include "../player_actions.h" -#include "../player_logic.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" +#include "../player_graphics_item.h" PtMenu::PtMenu(PlayerGraphicsItem *player) : QMenu(tr("Power / toughness")) { diff --git a/cockatrice/src/game/player/menu/pt_menu.h b/cockatrice/src/game_graphics/player/menu/pt_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/pt_menu.h rename to cockatrice/src/game_graphics/player/menu/pt_menu.h diff --git a/cockatrice/src/game/player/menu/rfg_menu.cpp b/cockatrice/src/game_graphics/player/menu/rfg_menu.cpp similarity index 95% rename from cockatrice/src/game/player/menu/rfg_menu.cpp rename to cockatrice/src/game_graphics/player/menu/rfg_menu.cpp index 79fdebf48..45abadbf7 100644 --- a/cockatrice/src/game/player/menu/rfg_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/rfg_menu.cpp @@ -1,7 +1,8 @@ #include "rfg_menu.h" -#include "../player_actions.h" -#include "../player_logic.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" +#include "../player_graphics_item.h" #include diff --git a/cockatrice/src/game/player/menu/rfg_menu.h b/cockatrice/src/game_graphics/player/menu/rfg_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/rfg_menu.h rename to cockatrice/src/game_graphics/player/menu/rfg_menu.h diff --git a/cockatrice/src/game/player/menu/say_menu.cpp b/cockatrice/src/game_graphics/player/menu/say_menu.cpp similarity index 91% rename from cockatrice/src/game/player/menu/say_menu.cpp rename to cockatrice/src/game_graphics/player/menu/say_menu.cpp index 58bbd33aa..336b70f0d 100644 --- a/cockatrice/src/game/player/menu/say_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/say_menu.cpp @@ -1,8 +1,9 @@ #include "say_menu.h" #include "../../../client/settings/cache_settings.h" -#include "../player_actions.h" -#include "../player_logic.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" +#include "../player_graphics_item.h" SayMenu::SayMenu(PlayerGraphicsItem *_player) : player(_player) { diff --git a/cockatrice/src/game/player/menu/say_menu.h b/cockatrice/src/game_graphics/player/menu/say_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/say_menu.h rename to cockatrice/src/game_graphics/player/menu/say_menu.h diff --git a/cockatrice/src/game/player/menu/sideboard_menu.cpp b/cockatrice/src/game_graphics/player/menu/sideboard_menu.cpp similarity index 87% rename from cockatrice/src/game/player/menu/sideboard_menu.cpp rename to cockatrice/src/game_graphics/player/menu/sideboard_menu.cpp index 27b50b570..0dd7894d2 100644 --- a/cockatrice/src/game/player/menu/sideboard_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/sideboard_menu.cpp @@ -1,7 +1,8 @@ #include "sideboard_menu.h" -#include "../player_actions.h" -#include "../player_logic.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" +#include "../player_graphics_item.h" SideboardMenu::SideboardMenu(PlayerGraphicsItem *player, QMenu *playerMenu) : QMenu(playerMenu) { diff --git a/cockatrice/src/game/player/menu/sideboard_menu.h b/cockatrice/src/game_graphics/player/menu/sideboard_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/sideboard_menu.h rename to cockatrice/src/game_graphics/player/menu/sideboard_menu.h diff --git a/cockatrice/src/game/player/menu/utility_menu.cpp b/cockatrice/src/game_graphics/player/menu/utility_menu.cpp similarity index 97% rename from cockatrice/src/game/player/menu/utility_menu.cpp rename to cockatrice/src/game_graphics/player/menu/utility_menu.cpp index 9769a029e..61a822b21 100644 --- a/cockatrice/src/game/player/menu/utility_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/utility_menu.cpp @@ -1,8 +1,9 @@ #include "utility_menu.h" #include "../../../interface/deck_loader/deck_loader.h" -#include "../player_actions.h" -#include "../player_logic.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" +#include "../player_graphics_item.h" #include "player_menu.h" #include diff --git a/cockatrice/src/game/player/menu/utility_menu.h b/cockatrice/src/game_graphics/player/menu/utility_menu.h similarity index 100% rename from cockatrice/src/game/player/menu/utility_menu.h rename to cockatrice/src/game_graphics/player/menu/utility_menu.h diff --git a/cockatrice/src/game/player/player_area.cpp b/cockatrice/src/game_graphics/player/player_area.cpp similarity index 100% rename from cockatrice/src/game/player/player_area.cpp rename to cockatrice/src/game_graphics/player/player_area.cpp diff --git a/cockatrice/src/game/player/player_area.h b/cockatrice/src/game_graphics/player/player_area.h similarity index 94% rename from cockatrice/src/game/player/player_area.h rename to cockatrice/src/game_graphics/player/player_area.h index 6ffaf4958..d73547f81 100644 --- a/cockatrice/src/game/player/player_area.h +++ b/cockatrice/src/game_graphics/player/player_area.h @@ -7,7 +7,7 @@ #ifndef COCKATRICE_PLAYER_AREA_H #define COCKATRICE_PLAYER_AREA_H -#include "../../game_graphics/board/graphics_item_type.h" +#include "../board/graphics_item_type.h" #include "QGraphicsItem" /** diff --git a/cockatrice/src/game/player/player_dialogs.cpp b/cockatrice/src/game_graphics/player/player_dialogs.cpp similarity index 100% rename from cockatrice/src/game/player/player_dialogs.cpp rename to cockatrice/src/game_graphics/player/player_dialogs.cpp diff --git a/cockatrice/src/game/player/player_dialogs.h b/cockatrice/src/game_graphics/player/player_dialogs.h similarity index 96% rename from cockatrice/src/game/player/player_dialogs.h rename to cockatrice/src/game_graphics/player/player_dialogs.h index a15c5174f..f87704f2d 100644 --- a/cockatrice/src/game/player/player_dialogs.h +++ b/cockatrice/src/game_graphics/player/player_dialogs.h @@ -1,6 +1,7 @@ #ifndef COCKATRICE_PLAYER_DIALOGS_H #define COCKATRICE_PLAYER_DIALOGS_H -#include "player_actions.h" +#include "../../game/player/player_actions.h" +#include "player_graphics_item.h" #include #include diff --git a/cockatrice/src/game/player/player_graphics_item.cpp b/cockatrice/src/game_graphics/player/player_graphics_item.cpp similarity index 97% rename from cockatrice/src/game/player/player_graphics_item.cpp rename to cockatrice/src/game_graphics/player/player_graphics_item.cpp index b0a476d5a..07975ed5e 100644 --- a/cockatrice/src/game/player/player_graphics_item.cpp +++ b/cockatrice/src/game_graphics/player/player_graphics_item.cpp @@ -1,14 +1,15 @@ #include "player_graphics_item.h" -#include "../../game_graphics/zones/hand_zone.h" -#include "../../game_graphics/zones/pile_zone.h" -#include "../../game_graphics/zones/stack_zone.h" -#include "../../game_graphics/zones/table_zone.h" +#include "../../game/player/player_actions.h" #include "../../interface/widgets/tabs/tab_game.h" #include "../board/abstract_card_item.h" #include "../board/counter_general.h" #include "../hand_counter.h" -#include "player_actions.h" +#include "../zones/hand_zone.h" +#include "../zones/pile_zone.h" +#include "../zones/stack_zone.h" +#include "../zones/table_zone.h" +#include "menu/player_menu.h" #include "player_dialogs.h" #include diff --git a/cockatrice/src/game/player/player_graphics_item.h b/cockatrice/src/game_graphics/player/player_graphics_item.h similarity index 98% rename from cockatrice/src/game/player/player_graphics_item.h rename to cockatrice/src/game_graphics/player/player_graphics_item.h index c1fcb4ed8..0dcc959bd 100644 --- a/cockatrice/src/game/player/player_graphics_item.h +++ b/cockatrice/src/game_graphics/player/player_graphics_item.h @@ -6,15 +6,16 @@ #ifndef COCKATRICE_PLAYER_GRAPHICS_ITEM_H #define COCKATRICE_PLAYER_GRAPHICS_ITEM_H +#include "../../game/player/player_logic.h" #include "../board/abstract_counter.h" #include "../game_scene.h" -#include "player_logic.h" #include class HandZone; class PileZone; class PlayerDialogs; +class PlayerMenu; class PlayerTarget; class StackZone; class TableZone; diff --git a/cockatrice/src/game/player/player_list_widget.cpp b/cockatrice/src/game_graphics/player/player_list_widget.cpp similarity index 100% rename from cockatrice/src/game/player/player_list_widget.cpp rename to cockatrice/src/game_graphics/player/player_list_widget.cpp diff --git a/cockatrice/src/game/player/player_list_widget.h b/cockatrice/src/game_graphics/player/player_list_widget.h similarity index 97% rename from cockatrice/src/game/player/player_list_widget.h rename to cockatrice/src/game_graphics/player/player_list_widget.h index 842c45873..a53cfa989 100644 --- a/cockatrice/src/game/player/player_list_widget.h +++ b/cockatrice/src/game_graphics/player/player_list_widget.h @@ -7,7 +7,7 @@ #ifndef PLAYERLISTWIDGET_H #define PLAYERLISTWIDGET_H -#include "player_logic.h" +#include "../../game/player/player_logic.h" #include #include diff --git a/cockatrice/src/game/player/player_target.cpp b/cockatrice/src/game_graphics/player/player_target.cpp similarity index 99% rename from cockatrice/src/game/player/player_target.cpp rename to cockatrice/src/game_graphics/player/player_target.cpp index 97fd51998..567f3d44d 100644 --- a/cockatrice/src/game/player/player_target.cpp +++ b/cockatrice/src/game_graphics/player/player_target.cpp @@ -1,7 +1,7 @@ #include "player_target.h" +#include "../../game/player/player_logic.h" #include "../../interface/pixel_map_generator.h" -#include "player_logic.h" #include #include diff --git a/cockatrice/src/game/player/player_target.h b/cockatrice/src/game_graphics/player/player_target.h similarity index 95% rename from cockatrice/src/game/player/player_target.h rename to cockatrice/src/game_graphics/player/player_target.h index d3facc60d..67e155660 100644 --- a/cockatrice/src/game/player/player_target.h +++ b/cockatrice/src/game_graphics/player/player_target.h @@ -7,9 +7,9 @@ #ifndef PLAYERTARGET_H #define PLAYERTARGET_H -#include "../../game_graphics/board/graphics_item_type.h" #include "../board/abstract_counter.h" #include "../board/arrow_target.h" +#include "../board/graphics_item_type.h" #include diff --git a/cockatrice/src/game/z_value_layer_manager.h b/cockatrice/src/game_graphics/z_value_layer_manager.h similarity index 100% rename from cockatrice/src/game/z_value_layer_manager.h rename to cockatrice/src/game_graphics/z_value_layer_manager.h diff --git a/cockatrice/src/game/z_values.h b/cockatrice/src/game_graphics/z_values.h similarity index 100% rename from cockatrice/src/game/z_values.h rename to cockatrice/src/game_graphics/z_values.h diff --git a/cockatrice/src/game_graphics/zones/card_zone.cpp b/cockatrice/src/game_graphics/zones/card_zone.cpp index 6ba8abe42..3457b681e 100644 --- a/cockatrice/src/game_graphics/zones/card_zone.cpp +++ b/cockatrice/src/game_graphics/zones/card_zone.cpp @@ -1,6 +1,6 @@ #include "card_zone.h" -#include "../../game/board/card_item.h" +#include "../board/card_item.h" #include "view_zone.h" #include diff --git a/cockatrice/src/game_graphics/zones/hand_zone.cpp b/cockatrice/src/game_graphics/zones/hand_zone.cpp index 09e9a5091..5885e3630 100644 --- a/cockatrice/src/game_graphics/zones/hand_zone.cpp +++ b/cockatrice/src/game_graphics/zones/hand_zone.cpp @@ -1,11 +1,11 @@ #include "hand_zone.h" #include "../../client/settings/cache_settings.h" -#include "../../game/board/card_drag_item.h" -#include "../../game/board/card_item.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" #include "../../interface/theme_manager.h" +#include "../board/card_drag_item.h" +#include "../board/card_item.h" #include #include diff --git a/cockatrice/src/game_graphics/zones/pile_zone.cpp b/cockatrice/src/game_graphics/zones/pile_zone.cpp index 302b983d8..7bb0e695a 100644 --- a/cockatrice/src/game_graphics/zones/pile_zone.cpp +++ b/cockatrice/src/game_graphics/zones/pile_zone.cpp @@ -1,10 +1,10 @@ #include "pile_zone.h" -#include "../../game/board/card_drag_item.h" -#include "../../game/board/card_item.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" #include "../../game/zones/pile_zone_logic.h" +#include "../board/card_drag_item.h" +#include "../board/card_item.h" #include "view_zone.h" #include diff --git a/cockatrice/src/game_graphics/zones/select_zone.cpp b/cockatrice/src/game_graphics/zones/select_zone.cpp index 90d53b464..f2e720686 100644 --- a/cockatrice/src/game_graphics/zones/select_zone.cpp +++ b/cockatrice/src/game_graphics/zones/select_zone.cpp @@ -1,8 +1,8 @@ #include "select_zone.h" #include "../../client/settings/cache_settings.h" -#include "../../game/board/card_item.h" -#include "../../game/game_scene.h" +#include "../board/card_item.h" +#include "../game_scene.h" #include #include diff --git a/cockatrice/src/game_graphics/zones/stack_zone.cpp b/cockatrice/src/game_graphics/zones/stack_zone.cpp index 9b0545b1d..46ff099ab 100644 --- a/cockatrice/src/game_graphics/zones/stack_zone.cpp +++ b/cockatrice/src/game_graphics/zones/stack_zone.cpp @@ -1,12 +1,12 @@ #include "stack_zone.h" -#include "../../game/board/card_drag_item.h" -#include "../../game/board/card_item.h" -#include "../../game/card_dimensions.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" #include "../../game/zones/stack_zone_logic.h" #include "../../interface/theme_manager.h" +#include "../board/card_drag_item.h" +#include "../board/card_item.h" +#include "../card_dimensions.h" #include #include diff --git a/cockatrice/src/game_graphics/zones/table_zone.cpp b/cockatrice/src/game_graphics/zones/table_zone.cpp index 245de8281..e886f62e9 100644 --- a/cockatrice/src/game_graphics/zones/table_zone.cpp +++ b/cockatrice/src/game_graphics/zones/table_zone.cpp @@ -1,14 +1,14 @@ #include "table_zone.h" #include "../../client/settings/cache_settings.h" -#include "../../game/board/arrow_item.h" -#include "../../game/board/card_drag_item.h" -#include "../../game/board/card_item.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" -#include "../../game/z_values.h" #include "../../game/zones/table_zone_logic.h" #include "../../interface/theme_manager.h" +#include "../board/arrow_item.h" +#include "../board/card_drag_item.h" +#include "../board/card_item.h" +#include "../z_values.h" #include #include diff --git a/cockatrice/src/game_graphics/zones/table_zone.h b/cockatrice/src/game_graphics/zones/table_zone.h index 8a898173b..0d7e58206 100644 --- a/cockatrice/src/game_graphics/zones/table_zone.h +++ b/cockatrice/src/game_graphics/zones/table_zone.h @@ -7,8 +7,8 @@ #ifndef TABLEZONE_H #define TABLEZONE_H -#include "../../game/board/abstract_card_item.h" #include "../../game/zones/table_zone_logic.h" +#include "../board/abstract_card_item.h" #include "select_zone.h" /** diff --git a/cockatrice/src/game_graphics/zones/view_zone.cpp b/cockatrice/src/game_graphics/zones/view_zone.cpp index 805c60638..baf7b8b30 100644 --- a/cockatrice/src/game_graphics/zones/view_zone.cpp +++ b/cockatrice/src/game_graphics/zones/view_zone.cpp @@ -1,10 +1,10 @@ #include "view_zone.h" -#include "../../game/board/card_drag_item.h" -#include "../../game/board/card_item.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" #include "../../game/zones/view_zone_logic.h" +#include "../board/card_drag_item.h" +#include "../board/card_item.h" #include #include diff --git a/cockatrice/src/game_graphics/zones/view_zone_widget.cpp b/cockatrice/src/game_graphics/zones/view_zone_widget.cpp index 03c6d8925..4a5d064d0 100644 --- a/cockatrice/src/game_graphics/zones/view_zone_widget.cpp +++ b/cockatrice/src/game_graphics/zones/view_zone_widget.cpp @@ -2,12 +2,12 @@ #include "../../client/settings/cache_settings.h" #include "../../filters/syntax_help.h" -#include "../../game/board/card_item.h" -#include "../../game/game_scene.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" -#include "../../game/z_values.h" #include "../../interface/pixel_map_generator.h" +#include "../board/card_item.h" +#include "../game_scene.h" +#include "../z_values.h" #include "view_zone.h" #include diff --git a/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp index 509a2d92f..577dafe0a 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp @@ -1,6 +1,6 @@ #include "card_info_display_widget.h" -#include "../../../game/board/card_item.h" +#include "../../../game_graphics/board/card_item.h" #include "card_info_picture_widget.h" #include "card_info_text_widget.h" diff --git a/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp index 21bee8f54..2e7c62461 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp @@ -1,7 +1,7 @@ #include "card_info_frame_widget.h" #include "../../../client/settings/cache_settings.h" -#include "../../../game/board/card_item.h" +#include "../../../game_graphics/board/card_item.h" #include "card_info_display_widget.h" #include "card_info_picture_widget.h" #include "card_info_text_widget.h" diff --git a/cockatrice/src/interface/widgets/cards/card_info_picture_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_picture_widget.cpp index 66ec1c197..3bfd9ce7d 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_picture_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_picture_widget.cpp @@ -1,7 +1,7 @@ #include "card_info_picture_widget.h" #include "../../../client/settings/cache_settings.h" -#include "../../../game/board/card_item.h" +#include "../../../game_graphics/board/card_item.h" #include "../../../interface/card_picture_loader/card_picture_loader.h" #include "../../../interface/widgets/tabs/tab_supervisor.h" #include "../../window_main.h" diff --git a/cockatrice/src/interface/widgets/cards/card_info_text_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_text_widget.cpp index 345eb9909..c6af5320b 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_text_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_text_widget.cpp @@ -1,6 +1,6 @@ #include "card_info_text_widget.h" -#include "../../../game/board/card_item.h" +#include "../../../game_graphics/board/card_item.h" #include #include diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.cpp b/cockatrice/src/interface/widgets/tabs/tab_game.cpp index 1e2bebd15..a81161e83 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_game.cpp @@ -1,19 +1,21 @@ #include "tab_game.h" #include "../../../client/settings/cache_settings.h" -#include "../../../game/player/menu/card_menu.h" -#include "../game/board/arrow_item.h" -#include "../game/board/card_item.h" -#include "../game/deckview/deck_view_container.h" -#include "../game/deckview/tabbed_deck_view_container.h" #include "../game/game.h" -#include "../game/game_scene.h" -#include "../game/game_view.h" -#include "../game/log/message_log_widget.h" -#include "../game/phases_toolbar.h" -#include "../game/player/player_list_widget.h" #include "../game/player/player_logic.h" #include "../game/replay.h" +#include "../game_graphics/board/arrow_item.h" +#include "../game_graphics/board/card_item.h" +#include "../game_graphics/deckview/deck_view_container.h" +#include "../game_graphics/deckview/tabbed_deck_view_container.h" +#include "../game_graphics/game_scene.h" +#include "../game_graphics/game_view.h" +#include "../game_graphics/log/message_log_widget.h" +#include "../game_graphics/phases_toolbar.h" +#include "../game_graphics/player/menu/card_menu.h" +#include "../game_graphics/player/menu/player_menu.h" +#include "../game_graphics/player/player_graphics_item.h" +#include "../game_graphics/player/player_list_widget.h" #include "../interface/card_picture_loader/card_picture_loader.h" #include "../interface/widgets/cards/card_info_frame_widget.h" #include "../interface/widgets/dialogs/dlg_create_game.h" @@ -48,7 +50,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay) : Tab(_tabSupervisor), sayLabel(nullptr), sayEdit(nullptr) { // THIS CTOR IS USED ON REPLAY - game = new Replay(this, _replay); + game = new Replay(this, _replay, tabSupervisor->getIsLocalGame()); createCardInfoDock(true); createPlayerListDock(true); @@ -92,7 +94,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, : Tab(_tabSupervisor), userListProxy(_tabSupervisor->getUserListManager()) { // THIS CTOR IS USED ON GAMES - game = new Game(this, _clients, event, _roomGameTypes); + game = new Game(this, tabSupervisor->getIsLocalGame(), _clients, event, _roomGameTypes); createCardInfoDock(); createPlayerListDock(); diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.h b/cockatrice/src/interface/widgets/tabs/tab_game.h index ddda4d9b9..b9289432d 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.h +++ b/cockatrice/src/interface/widgets/tabs/tab_game.h @@ -10,8 +10,8 @@ #define TAB_GAME_H #include "../game/abstract_game.h" -#include "../game/log/message_log_widget.h" #include "../game/player/player_logic.h" +#include "../game_graphics/log/message_log_widget.h" #include "../interface/widgets/menus/tearoff_menu.h" #include "../interface/widgets/replay/replay_manager.h" #include "tab.h" @@ -20,6 +20,7 @@ #include #include +class CardMenu; class ServerInfo_PlayerProperties; class TabbedDeckViewContainer; inline Q_LOGGING_CATEGORY(TabGameLog, "tab_game"); From f72c82d0f9a33828ad9bbaeeb0a91ed8ebe14ffc Mon Sep 17 00:00:00 2001 From: kongwu <167565490+kongwu666@users.noreply.github.com> Date: Wed, 10 Jun 2026 11:46:43 +0800 Subject: [PATCH 08/17] [DeckEditor] Replace mainboard/sideboard with tokensboard for tokens (#6971) * [DeckEditor] Replace mainboard/sideboard with tokensboard for token cards (#6546) * [PrintingSelector] Replace std::tuple with ZoneCounts struct for readability (#6546) --- .../deck_editor/deck_state_manager.cpp | 4 ++ .../all_zones_card_amount_widget.cpp | 37 ++++++++++++-- .../all_zones_card_amount_widget.h | 5 +- .../printing_selector/card_amount_widget.cpp | 48 ++++++++++++++++--- .../printing_selector/card_amount_widget.h | 2 + .../printing_selector/printing_selector.cpp | 17 +++++-- .../printing_selector/printing_selector.h | 11 ++++- .../printing_selector_card_display_widget.cpp | 6 +-- .../printing_selector_card_display_widget.h | 2 +- .../printing_selector_card_overlay_widget.cpp | 10 ++-- .../printing_selector_card_overlay_widget.h | 2 +- 11 files changed, 115 insertions(+), 29 deletions(-) diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp index 6db8e5623..f8fb450ce 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp @@ -255,6 +255,10 @@ bool DeckStateManager::swapCardAtIndex(const QModelIndex &idx) } QString zoneName = gparent.siblingAtColumn(DeckListModelColumns::CARD_NAME).data(Qt::EditRole).toString(); + // tokens have no swap target + if (zoneName == DECK_ZONE_TOKENS) { + return false; + } QString otherZoneName = zoneName == DECK_ZONE_MAIN ? DECK_ZONE_SIDE : DECK_ZONE_MAIN; QString reason = tr("Moved to %1 1 × \"%2\" (%3)") // diff --git a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp index 36bccbcc3..05e269174 100644 --- a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp @@ -8,7 +8,7 @@ * @brief Constructor for the AllZonesCardAmountWidget class. * * Initializes the widget with its layout and sets up the connections and necessary - * UI elements for managing card counts in both the mainboard and sideboard zones. + * UI elements for managing card counts in all the mainboard, tokensboard and sideboard zones. * * @param parent The parent widget. * @param deckStateManager Pointer to the DeckStateManager @@ -31,13 +31,28 @@ AllZonesCardAmountWidget::AllZonesCardAmountWidget(QWidget *parent, buttonBoxMainboard = new CardAmountWidget(this, deckStateManager, cardSizeSlider, rootCard, DECK_ZONE_MAIN); zoneLabelSideboard = new ShadowBackgroundLabel(this, tr("Sideboard")); buttonBoxSideboard = new CardAmountWidget(this, deckStateManager, cardSizeSlider, rootCard, DECK_ZONE_SIDE); + zoneLabelTokensboard = new ShadowBackgroundLabel(this, tr("Tokens")); + buttonBoxTokensboard = new CardAmountWidget(this, deckStateManager, cardSizeSlider, rootCard, DECK_ZONE_TOKENS); layout->addWidget(zoneLabelMainboard, 0, Qt::AlignHCenter | Qt::AlignBottom); layout->addWidget(buttonBoxMainboard, 0, Qt::AlignHCenter | Qt::AlignTop); - layout->addSpacing(25); + layout->addSpacing(12); + layout->addWidget(zoneLabelTokensboard, 0, Qt::AlignHCenter | Qt::AlignBottom); + layout->addWidget(buttonBoxTokensboard, 0, Qt::AlignHCenter | Qt::AlignTop); + layout->addSpacing(13); layout->addWidget(zoneLabelSideboard, 0, Qt::AlignHCenter | Qt::AlignBottom); layout->addWidget(buttonBoxSideboard, 0, Qt::AlignHCenter | Qt::AlignTop); + // Show Tokens buttons for token cards, Mainboard/Sideboard for non-token cards + bool isToken = rootCard.getInfo().getIsToken(); + + zoneLabelMainboard->setVisible(!isToken); + buttonBoxMainboard->setVisible(!isToken); + zoneLabelTokensboard->setVisible(isToken); + buttonBoxTokensboard->setVisible(isToken); + zoneLabelSideboard->setVisible(!isToken); + buttonBoxSideboard->setVisible(!isToken); + connect(cardSizeSlider, &QSlider::valueChanged, this, &AllZonesCardAmountWidget::adjustFontSize); QTimer::singleShot(10, this, [this]() { adjustFontSize(this->cardSizeSlider->value()); }); @@ -67,15 +82,17 @@ void AllZonesCardAmountWidget::adjustFontSize(int scalePercentage) zoneLabelFont.setPointSize(newFontSize); zoneLabelMainboard->setFont(zoneLabelFont); zoneLabelSideboard->setFont(zoneLabelFont); + zoneLabelTokensboard->setFont(zoneLabelFont); // Repaint the widget (if necessary) repaint(); } -void AllZonesCardAmountWidget::setAmounts(int mainboardAmount, int sideboardAmount) +void AllZonesCardAmountWidget::setAmounts(int mainboardAmount, int sideboardAmount, int tokensboardAmount) { buttonBoxMainboard->setAmount(mainboardAmount); buttonBoxSideboard->setAmount(sideboardAmount); + buttonBoxTokensboard->setAmount(tokensboardAmount); } /** @@ -99,11 +116,21 @@ int AllZonesCardAmountWidget::getSideboardAmount() } /** - * @brief Checks if the amount is at least one in either the mainboard or sideboard. + * @brief Gets the card count in the tokensboard zone. + * + * @return The number of cards in the tokensboard. + */ +int AllZonesCardAmountWidget::getTokensboardAmount() +{ + return buttonBoxTokensboard->getAmount(); +} + +/** + * @brief Checks if the amount is at least one in either the mainboard or sideboard or tokensboard. */ bool AllZonesCardAmountWidget::isNonZero() { - return getMainboardAmount() > 0 || getSideboardAmount() > 0; + return getMainboardAmount() > 0 || getSideboardAmount() > 0 || getTokensboardAmount() > 0; } /** diff --git a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h index 05047d94f..de4a984be 100644 --- a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h @@ -23,6 +23,7 @@ public: const ExactCard &rootCard); int getMainboardAmount(); int getSideboardAmount(); + int getTokensboardAmount(); bool isNonZero(); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) @@ -33,7 +34,7 @@ public: public slots: void adjustFontSize(int scalePercentage); - void setAmounts(int mainboardAmount, int sideboardAmount); + void setAmounts(int mainboardAmount, int sideboardAmount, int tokensboardAmount); private: QVBoxLayout *layout; @@ -42,6 +43,8 @@ private: CardAmountWidget *buttonBoxMainboard; QLabel *zoneLabelSideboard; CardAmountWidget *buttonBoxSideboard; + QLabel *zoneLabelTokensboard; + CardAmountWidget *buttonBoxTokensboard; }; #endif // ALL_ZONES_CARD_AMOUNT_WIDGET_H diff --git a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp index 25222f437..ff47e7b9c 100644 --- a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp @@ -11,7 +11,7 @@ * @param parent The parent widget. * @param cardSizeSlider Pointer to the QSlider for adjusting font size. * @param rootCard The root card to manage within the widget. - * @param zoneName The zone name (e.g., DECK_ZONE_MAIN or DECK_ZONE_SIDE). + * @param zoneName The zone name (e.g., DECK_ZONE_MAIN , DECK_ZONE_SIDE, or DECK_ZONE_TOKENS). */ CardAmountWidget::CardAmountWidget(QWidget *parent, DeckStateManager *deckStateManager, @@ -36,13 +36,16 @@ CardAmountWidget::CardAmountWidget(QWidget *parent, incrementButton->setFixedSize(parentWidget()->size().width() / 3, parentWidget()->size().height() / 9); decrementButton->setFixedSize(parentWidget()->size().width() / 3, parentWidget()->size().height() / 9); - // Set up connections based on the zone (Mainboard or Sideboard) + // Set up connections based on the zone (Mainboard, Sideboard, or Tokensboard) if (zoneName == DECK_ZONE_MAIN) { connect(incrementButton, &QPushButton::clicked, this, &CardAmountWidget::addPrintingMainboard); connect(decrementButton, &QPushButton::clicked, this, &CardAmountWidget::removePrintingMainboard); } else if (zoneName == DECK_ZONE_SIDE) { connect(incrementButton, &QPushButton::clicked, this, &CardAmountWidget::addPrintingSideboard); connect(decrementButton, &QPushButton::clicked, this, &CardAmountWidget::removePrintingSideboard); + } else if (zoneName == DECK_ZONE_TOKENS) { + connect(incrementButton, &QPushButton::clicked, this, &CardAmountWidget::addPrintingTokensboard); + connect(decrementButton, &QPushButton::clicked, this, &CardAmountWidget::removePrintingTokensboard); } cardCountInZone = new QLabel(QString::number(amount), this); @@ -137,6 +140,19 @@ void CardAmountWidget::updateCardCount() layout->activate(); } +static QString zoneLogName(const QString &zone) +{ + if (zone == DECK_ZONE_MAIN) { + return "mainboard"; + } else if (zone == DECK_ZONE_SIDE) { + return "sideboard"; + } else if (zone == DECK_ZONE_TOKENS) { + return "tokens"; + } else { + return "unknown"; + } +} + static QModelIndex addAndReplacePrintings(DeckListModel *model, const QModelIndex &existing, const ExactCard &rootCard, @@ -161,9 +177,9 @@ static QModelIndex addAndReplacePrintings(DeckListModel *model, } /** - * @brief Adds a printing of the card to the specified zone (Mainboard or Sideboard). + * @brief Adds a printing of the card to the specified zone (Mainboard, Sideboard, or Tokensboard). * - * @param zone The zone to add the card to (DECK_ZONE_MAIN or DECK_ZONE_SIDE). + * @param zone The zone to add the card to (DECK_ZONE_MAIN, DECK_ZONE_SIDE, or DECK_ZONE_TOKENS). */ void CardAmountWidget::addPrinting(const QString &zone) { @@ -183,12 +199,13 @@ void CardAmountWidget::addPrinting(const QString &zone) } } + QString zoneName = zoneLogName(zone); QString reason = QString("Added %1 copies of '%2 (%3) %4' to %5 [ProviderID: %6]%7") .arg(1 + extraCopies) .arg(rootCard.getName()) .arg(rootCard.getPrinting().getSet()->getShortName()) .arg(rootCard.getPrinting().getProperty("num")) - .arg(zone == DECK_ZONE_MAIN ? "mainboard" : "sideboard") + .arg(zoneName) .arg(rootCard.getPrinting().getUuid()) .arg(replacingProviderless ? " (replaced providerless printings)" : ""); @@ -218,6 +235,14 @@ void CardAmountWidget::addPrintingSideboard() addPrinting(DECK_ZONE_SIDE); } +/** + * @brief Adds a printing to the tokens zone. + */ +void CardAmountWidget::addPrintingTokensboard() +{ + addPrinting(DECK_ZONE_TOKENS); +} + /** * @brief Removes a printing from the mainboard zone. */ @@ -234,18 +259,27 @@ void CardAmountWidget::removePrintingSideboard() decrementCardHelper(DECK_ZONE_SIDE); } +/** + * @brief Removes a printing from the tokens zone. + */ +void CardAmountWidget::removePrintingTokensboard() +{ + decrementCardHelper(DECK_ZONE_TOKENS); +} + /** * @brief Helper function to decrement the card count for a given zone. * - * @param zone The zone from which to remove the card (DECK_ZONE_MAIN or DECK_ZONE_SIDE). + * @param zone The zone from which to remove the card (DECK_ZONE_MAIN, DECK_ZONE_SIDE, or DECK_ZONE_TOKENS). */ void CardAmountWidget::decrementCardHelper(const QString &zone) { + QString zoneName = zoneLogName(zone); QString reason = QString("Removed 1 copy of '%1 (%2) %3' from %4 [ProviderID: %5]") .arg(rootCard.getName()) .arg(rootCard.getPrinting().getSet()->getShortName()) .arg(rootCard.getPrinting().getProperty("num")) - .arg(zone == DECK_ZONE_MAIN ? "mainboard" : "sideboard") + .arg(zoneName) .arg(rootCard.getPrinting().getUuid()); deckStateManager->modifyDeck(reason, [this, &zone](auto model) { diff --git a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h index f0f2128f0..2780e3ad2 100644 --- a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h @@ -60,8 +60,10 @@ private: private slots: void addPrintingMainboard(); void addPrintingSideboard(); + void addPrintingTokensboard(); void removePrintingMainboard(); void removePrintingSideboard(); + void removePrintingTokensboard(); void adjustFontSize(int scalePercentage); }; diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp index 71b93b297..76a416587 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp @@ -105,23 +105,30 @@ void PrintingSelector::printingsInDeckChanged() } /** - * @return A map of uuid to amounts (main, side). + * @return A map of uuid to amounts (main, side, tokens). */ -static QMap> tallyUuidCounts(const DeckListModel *model, const QString &cardName) +static QMap tallyUuidCounts(const DeckListModel *model, const QString &cardName) { - QMap> map; + QMap map; auto mainNodes = model->getCardNodesForZone(DECK_ZONE_MAIN); for (auto &node : mainNodes) { if (node->getName() == cardName) { - map[node->getCardProviderId()].first += node->getNumber(); + map[node->getCardProviderId()].mainboard += node->getNumber(); } } auto sideNodes = model->getCardNodesForZone(DECK_ZONE_SIDE); for (auto &node : sideNodes) { if (node->getName() == cardName) { - map[node->getCardProviderId()].second += node->getNumber(); + map[node->getCardProviderId()].sideboard += node->getNumber(); + } + } + + auto tokensNodes = model->getCardNodesForZone(DECK_ZONE_TOKENS); + for (auto &node : tokensNodes) { + if (node->getName() == cardName) { + map[node->getCardProviderId()].tokensboard += node->getNumber(); } } diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector.h index b9e6723f2..14d73f836 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector.h @@ -22,6 +22,13 @@ #define BATCH_SIZE 10 +struct ZoneCounts +{ + int mainboard = 0; + int sideboard = 0; + int tokensboard = 0; +}; + class DeckStateManager; class PrintingSelectorCardSearchWidget; class PrintingSelectorCardSelectionWidget; @@ -59,9 +66,9 @@ signals: /** * The amounts of the printings in the deck has changed - * @param uuidToAmounts Map of uuids to the amounts (maindeck, sideboard) in the deck + * @param uuidToAmounts Map of uuids to the amounts (maindeck, sideboard, tokensboard) in the deck */ - void cardAmountsChanged(const QMap> &uuidToAmounts); + void cardAmountsChanged(const QMap &uuidToAmounts); private: QVBoxLayout *layout; diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp index 7d0b4882f..edeba86d1 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp @@ -67,10 +67,10 @@ void PrintingSelectorCardDisplayWidget::clampSetNameToPicture() update(); } -void PrintingSelectorCardDisplayWidget::updateCardAmounts(const QMap> &uuidToAmounts) +void PrintingSelectorCardDisplayWidget::updateCardAmounts(const QMap &uuidToAmounts) { - auto [main, side] = uuidToAmounts.value(rootCard.getPrinting().getUuid()); - overlayWidget->updateCardAmounts(main, side); + auto counts = uuidToAmounts.value(rootCard.getPrinting().getUuid()); + overlayWidget->updateCardAmounts(counts.mainboard, counts.sideboard, counts.tokensboard); } void PrintingSelectorCardDisplayWidget::resizeEvent(QResizeEvent *event) diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h index b708bd973..4de561f4f 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h @@ -27,7 +27,7 @@ public: public slots: void clampSetNameToPicture(); - void updateCardAmounts(const QMap> &uuidToAmounts); + void updateCardAmounts(const QMap &uuidToAmounts); void resizeEvent(QResizeEvent *event) override; diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp index 69334d6f3..dd5f6dd7f 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp @@ -116,9 +116,11 @@ void PrintingSelectorCardOverlayWidget::enterEvent(QEvent *event) updateVisibility(); } -void PrintingSelectorCardOverlayWidget::updateCardAmounts(int mainboardAmount, int sideboardAmount) +void PrintingSelectorCardOverlayWidget::updateCardAmounts(int mainboardAmount, + int sideboardAmount, + int tokensboardAmount) { - allZonesCardAmountWidget->setAmounts(mainboardAmount, sideboardAmount); + allZonesCardAmountWidget->setAmounts(mainboardAmount, sideboardAmount, tokensboardAmount); updateVisibility(); } @@ -173,8 +175,8 @@ void PrintingSelectorCardOverlayWidget::updatePinBadgeVisibility() /** * @brief Handles the mouse leave event when the cursor leaves the overlay widget area. * - * When the cursor leaves the widget, the card amount widget is hidden if both the mainboard and sideboard - * amounts are zero. + * When the cursor leaves the widget, the card amount widget is hidden if all of the mainboard, sideboard, and + * tokensboard amounts are zero. * * @param event The event triggered when the mouse leaves the widget. */ diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h index 2fdf5ab74..52a43d220 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h @@ -39,7 +39,7 @@ signals: void cardPreferenceChanged(); public slots: - void updateCardAmounts(int mainboardAmount, int sideboardAmount); + void updateCardAmounts(int mainboardAmount, int sideboardAmount, int tokensboardAmount); private slots: void updateVisibility(); From 6d0a423dcfa842c14463848879f74dfac8280edf Mon Sep 17 00:00:00 2001 From: kongwu <167565490+kongwu666@users.noreply.github.com> Date: Wed, 10 Jun 2026 11:49:29 +0800 Subject: [PATCH 09/17] [Messages] Add option to ignore private messages from non-buddy users (#6966) * [Messages] Add option to ignore private messages from non-buddy users * [Messages] Exclude Moderator/Admin from non-buddy ignore filter Moderator and Admin messages should not be filtered out when the 'Ignore private messages from non-buddies' setting is enabled, to ensure that important warnings from server staff reach users. --- cockatrice/src/client/settings/cache_settings.cpp | 7 +++++++ cockatrice/src/client/settings/cache_settings.h | 7 +++++++ .../widgets/settings_page/messages_settings_page.cpp | 12 +++++++++--- .../widgets/settings_page/messages_settings_page.h | 1 + .../src/interface/widgets/tabs/tab_supervisor.cpp | 6 ++++++ 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/cockatrice/src/client/settings/cache_settings.cpp b/cockatrice/src/client/settings/cache_settings.cpp index 64416e5ee..73e5a98a1 100644 --- a/cockatrice/src/client/settings/cache_settings.cpp +++ b/cockatrice/src/client/settings/cache_settings.cpp @@ -388,6 +388,7 @@ SettingsCache::SettingsCache() ignoreUnregisteredUsers = settings->value("chat/ignore_unregistered", false).toBool(); ignoreUnregisteredUserMessages = settings->value("chat/ignore_unregistered_messages", false).toBool(); + ignoreNonBuddyUserMessages = settings->value("chat/ignore_nonbuddy_messages", false).toBool(); scaleCards = settings->value("cards/scaleCards", true).toBool(); verticalCardOverlapPercent = settings->value("cards/verticalCardOverlapPercent", 33).toInt(); @@ -1117,6 +1118,12 @@ void SettingsCache::setIgnoreUnregisteredUserMessages(QT_STATE_CHANGED_T _ignore settings->setValue("chat/ignore_unregistered_messages", ignoreUnregisteredUserMessages); } +void SettingsCache::setIgnoreNonBuddyUserMessages(QT_STATE_CHANGED_T _ignoreNonBuddyUserMessages) +{ + ignoreNonBuddyUserMessages = static_cast(_ignoreNonBuddyUserMessages); + settings->setValue("chat/ignore_nonbuddy_messages", ignoreNonBuddyUserMessages); +} + void SettingsCache::setPixmapCacheSize(const int _pixmapCacheSize) { pixmapCacheSize = _pixmapCacheSize; diff --git a/cockatrice/src/client/settings/cache_settings.h b/cockatrice/src/client/settings/cache_settings.h index b1197e267..8ee372766 100644 --- a/cockatrice/src/client/settings/cache_settings.h +++ b/cockatrice/src/client/settings/cache_settings.h @@ -183,6 +183,7 @@ signals: void soundThemeChanged(); void ignoreUnregisteredUsersChanged(); void ignoreUnregisteredUserMessagesChanged(); + void ignoreNonBuddyUserMessagesChanged(); void pixmapCacheSizeChanged(int newSizeInMBs); void networkCacheSizeChanged(int newSizeInMBs); void redirectCacheTtlChanged(int newTtl); @@ -294,6 +295,7 @@ private: QString soundThemeName; bool ignoreUnregisteredUsers; bool ignoreUnregisteredUserMessages; + bool ignoreNonBuddyUserMessages; QString picUrl; QString picUrlFallback; QString clientID; @@ -788,6 +790,10 @@ public: { return ignoreUnregisteredUserMessages; } + [[nodiscard]] bool getIgnoreNonBuddyUserMessages() const + { + return ignoreNonBuddyUserMessages; + } [[nodiscard]] int getPixmapCacheSize() const { return pixmapCacheSize; @@ -1111,6 +1117,7 @@ public slots: void setSoundThemeName(const QString &_soundThemeName); void setIgnoreUnregisteredUsers(QT_STATE_CHANGED_T _ignoreUnregisteredUsers); void setIgnoreUnregisteredUserMessages(QT_STATE_CHANGED_T _ignoreUnregisteredUserMessages); + void setIgnoreNonBuddyUserMessages(QT_STATE_CHANGED_T _ignoreNonBuddyUserMessages); void setPixmapCacheSize(const int _pixmapCacheSize); void setCardImageCacheMethod(CardPictureLoaderCacheMethod::CacheMethod _cardImageCachingMethod); void setNetworkCacheSizeInMB(const int _networkCacheSize); diff --git a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp index f64398fe5..1e6f99245 100644 --- a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp @@ -22,10 +22,14 @@ MessagesSettingsPage::MessagesSettingsPage() ignoreUnregUsersMainChat.setChecked(SettingsCache::instance().getIgnoreUnregisteredUsers()); ignoreUnregUserMessages.setChecked(SettingsCache::instance().getIgnoreUnregisteredUserMessages()); + ignoreNonBuddyUserMessages.setChecked(SettingsCache::instance().getIgnoreNonBuddyUserMessages()); + connect(&ignoreUnregUsersMainChat, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(), &SettingsCache::setIgnoreUnregisteredUsers); connect(&ignoreUnregUserMessages, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(), &SettingsCache::setIgnoreUnregisteredUserMessages); + connect(&ignoreNonBuddyUserMessages, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(), + &SettingsCache::setIgnoreNonBuddyUserMessages); invertMentionForeground.setChecked(SettingsCache::instance().getChatMentionForeground()); connect(&invertMentionForeground, &QCheckBox::QT_STATE_CHANGED, this, &MessagesSettingsPage::updateTextColor); @@ -62,9 +66,10 @@ MessagesSettingsPage::MessagesSettingsPage() chatGrid->addWidget(&ignoreUnregUsersMainChat, 2, 0); chatGrid->addWidget(&hexLabel, 1, 2); chatGrid->addWidget(&ignoreUnregUserMessages, 3, 0); - chatGrid->addWidget(&messagePopups, 4, 0); - chatGrid->addWidget(&mentionPopups, 5, 0); - chatGrid->addWidget(&roomHistory, 6, 0); + chatGrid->addWidget(&ignoreNonBuddyUserMessages, 4, 0); + chatGrid->addWidget(&messagePopups, 5, 0); + chatGrid->addWidget(&mentionPopups, 6, 0); + chatGrid->addWidget(&roomHistory, 7, 0); chatGroupBox = new QGroupBox; chatGroupBox->setLayout(chatGrid); @@ -237,6 +242,7 @@ void MessagesSettingsPage::retranslateUi() QString("%2").arg(WIKI_CUSTOM_SHORTCUTS).arg(tr("How to use in-game message macros"))); ignoreUnregUsersMainChat.setText(tr("Ignore chat room messages sent by unregistered users")); ignoreUnregUserMessages.setText(tr("Ignore private messages sent by unregistered users")); + ignoreNonBuddyUserMessages.setText(tr("Ignore private messages sent by non-buddy users")); invertMentionForeground.setText(tr("Invert text color")); invertHighlightForeground.setText(tr("Invert text color")); messagePopups.setText(tr("Enable desktop notifications for private messages")); diff --git a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h index e8a4a8aa4..e98ae0592 100644 --- a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h @@ -36,6 +36,7 @@ private: QCheckBox invertHighlightForeground; QCheckBox ignoreUnregUsersMainChat; QCheckBox ignoreUnregUserMessages; + QCheckBox ignoreNonBuddyUserMessages; QCheckBox messagePopups; QCheckBox mentionPopups; QCheckBox roomHistory; diff --git a/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp b/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp index 3566d6939..e7075f78f 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp @@ -1019,6 +1019,12 @@ void TabSupervisor::processUserMessageEvent(const Event_UserMessage &event) !userLevel.testFlag(ServerInfo_User::IsRegistered)) { // Flags are additive, so reg/mod/admin are all IsRegistered return; + } else if (SettingsCache::instance().getIgnoreNonBuddyUserMessages() && + !userListManager->isUserBuddy(senderName) && !userLevel.testFlag(ServerInfo_User::IsModerator) && + !userLevel.testFlag(ServerInfo_User::IsAdmin)) { + // Ignore private messages from non-buddies + // Moderator/Admin messages are exempt to ensure warnings reach users + return; } } tab = addMessageTab(QString::fromStdString(event.sender_name()), false); From 6be9cec6e20eb5928c2f8888ee968579d4a6edab Mon Sep 17 00:00:00 2001 From: ebbit1q Date: Wed, 10 Jun 2026 08:35:00 +0200 Subject: [PATCH 10/17] do not save a const reference to the user data in the info dialog (#6974) * do not save a const reference to the user data in the info dialog * cmake format --- .../widgets/server/user/user_info_box.cpp | 24 ++++++------------- .../widgets/server/user/user_info_box.h | 14 ++++------- .../utility/days_years_between.h | 8 +++++++ tests/CMakeLists.txt | 4 +++- tests/test_age_formatting.cpp | 13 +++++----- 5 files changed, 29 insertions(+), 34 deletions(-) create mode 100644 libcockatrice_utility/libcockatrice/utility/days_years_between.h diff --git a/cockatrice/src/interface/widgets/server/user/user_info_box.cpp b/cockatrice/src/interface/widgets/server/user/user_info_box.cpp index a9955ff3d..e41ae6e75 100644 --- a/cockatrice/src/interface/widgets/server/user/user_info_box.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_info_box.cpp @@ -85,24 +85,15 @@ void UserInfoBox::retranslateUi() avatarButton.setText(tr("Change avatar")); } -/** - * Creates the default profile pic that is used when the user doesn't have a custom pic - */ -static QPixmap createDefaultAvatar(int height, const ServerInfo_User &user) -{ - return UserLevelPixmapGenerator::generatePixmap(height, UserLevelFlags(user.user_level()), user.pawn_colors(), - false, QString::fromStdString(user.privlevel())); -} - void UserInfoBox::updateInfo(const ServerInfo_User &user) { - currentUserInfo = &user; - - const UserLevelFlags userLevel(user.user_level()); + userLevel = UserLevelFlags(user.user_level()); + pawnColors = user.pawn_colors(); + privLevel = QString::fromStdString(user.privlevel()); const std::string &bmp = user.avatar_bmp(); if (!avatarPixmap.loadFromData((const uchar *)bmp.data(), static_cast(bmp.size()))) { - avatarPixmap = createDefaultAvatar(64, user); + avatarPixmap = UserLevelPixmapGenerator::generatePixmap(64, userLevel, pawnColors, false, privLevel); hasAvatar = false; } else { hasAvatar = true; @@ -120,8 +111,7 @@ void UserInfoBox::updateInfo(const ServerInfo_User &user) countryLabel3.setText(""); } - userLevelIcon.setPixmap(UserLevelPixmapGenerator::generatePixmap(15, userLevel, user.pawn_colors(), false, - QString::fromStdString(user.privlevel()))); + userLevelIcon.setPixmap(UserLevelPixmapGenerator::generatePixmap(15, userLevel, pawnColors, false, privLevel)); QString userLevelText; if (userLevel.testFlag(ServerInfo_User::IsAdmin)) { userLevelText = tr("Administrator"); @@ -373,7 +363,7 @@ void UserInfoBox::processAvatarResponse(const Response &r) break; case Response::RespInternalError: default: - QMessageBox::critical(this, tr("Error"), tr("An error occured while trying to updater your avatar.")); + QMessageBox::critical(this, tr("Error"), tr("An error occured while trying to update your avatar.")); break; } } @@ -385,7 +375,7 @@ void UserInfoBox::resizeEvent(QResizeEvent *event) resizedPixmap = avatarPixmap.scaled(avatarPic.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); } else { int height = qMin(avatarPic.size().width(), avatarPic.size().height()); - resizedPixmap = createDefaultAvatar(height, *currentUserInfo); + resizedPixmap = UserLevelPixmapGenerator::generatePixmap(height, userLevel, pawnColors, false, privLevel); } avatarPic.setPixmap(resizedPixmap); diff --git a/cockatrice/src/interface/widgets/server/user/user_info_box.h b/cockatrice/src/interface/widgets/server/user/user_info_box.h index 299deed2f..055ac0096 100644 --- a/cockatrice/src/interface/widgets/server/user/user_info_box.h +++ b/cockatrice/src/interface/widgets/server/user/user_info_box.h @@ -11,8 +11,9 @@ #include #include #include +#include +#include -class ServerInfo_User; class AbstractClient; class Response; @@ -27,20 +28,15 @@ private: QPushButton editButton, passwordButton, avatarButton; QPixmap avatarPixmap; bool hasAvatar; - const ServerInfo_User *currentUserInfo; + UserLevelFlags userLevel; + ServerInfo_User::PawnColorsOverride pawnColors; + QString privLevel; static QString getAgeString(int ageSeconds); public: UserInfoBox(AbstractClient *_client, bool editable, QWidget *parent = nullptr, Qt::WindowFlags flags = {}); void retranslateUi(); - - inline static QPair getDaysAndYearsBetween(const QDate &then, const QDate &now) - { - int years = now.addDays(1 - then.dayOfYear()).year() - then.year(); // there is no yearsTo - int days = then.addYears(years).daysTo(now); - return {days, years}; - } private slots: void processResponse(const Response &r); void processEditResponse(const Response &r); diff --git a/libcockatrice_utility/libcockatrice/utility/days_years_between.h b/libcockatrice_utility/libcockatrice/utility/days_years_between.h new file mode 100644 index 000000000..c0f5da23a --- /dev/null +++ b/libcockatrice_utility/libcockatrice/utility/days_years_between.h @@ -0,0 +1,8 @@ +#include + +inline static QPair getDaysAndYearsBetween(const QDate &then, const QDate &now) +{ + int years = now.addDays(1 - then.dayOfYear()).year() - then.year(); // there is no yearsTo + int days = then.addYears(years).daysTo(now); + return {days, years}; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 00eba288e..04ac7fcee 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -59,7 +59,9 @@ endif() include_directories(${GTEST_INCLUDE_DIRS}) target_link_libraries(dummy_test Threads::Threads ${GTEST_BOTH_LIBRARIES}) target_link_libraries(expression_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}) -target_link_libraries(test_age_formatting Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}) +target_link_libraries( + test_age_formatting libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} +) target_link_libraries( password_hash_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} ) diff --git a/tests/test_age_formatting.cpp b/tests/test_age_formatting.cpp index e4fc64cf9..6a9d5d4af 100644 --- a/tests/test_age_formatting.cpp +++ b/tests/test_age_formatting.cpp @@ -1,6 +1,5 @@ -#include "../cockatrice/src/interface/widgets/server/user/user_info_box.h" - #include "gtest/gtest.h" +#include namespace { @@ -8,31 +7,31 @@ using dayyear = QPair; TEST(AgeFormatting, Zero) { - auto got = UserInfoBox::getDaysAndYearsBetween(QDate(2000, 1, 1), QDate(2000, 1, 1)); + auto got = getDaysAndYearsBetween(QDate(2000, 1, 1), QDate(2000, 1, 1)); ASSERT_EQ(got, dayyear(0, 0)) << "these are the same day"; } TEST(AgeFormatting, LeapDay) { - auto got = UserInfoBox::getDaysAndYearsBetween(QDate(2000, 2, 28), QDate(2000, 3, 1)); + auto got = getDaysAndYearsBetween(QDate(2000, 2, 28), QDate(2000, 3, 1)); ASSERT_EQ(got, dayyear(2, 0)) << "there is a leap day in between these days"; } TEST(AgeFormatting, LeapYear) { - auto got = UserInfoBox::getDaysAndYearsBetween(QDate(2000, 1, 1), QDate(2001, 1, 1)); + auto got = getDaysAndYearsBetween(QDate(2000, 1, 1), QDate(2001, 1, 1)); ASSERT_EQ(got, dayyear(0, 1)) << "there is a leap day in between these dates, but that's fine"; } TEST(AgeFormatting, LeapDayWithYear) { - auto got = UserInfoBox::getDaysAndYearsBetween(QDate(2000, 2, 28), QDate(2001, 3, 1)); + auto got = getDaysAndYearsBetween(QDate(2000, 2, 28), QDate(2001, 3, 1)); ASSERT_EQ(got, dayyear(1, 1)) << "there is a leap day in between these days but not in the last year"; } TEST(AgeFormatting, LeapDayThisYear) { - auto got = UserInfoBox::getDaysAndYearsBetween(QDate(2003, 2, 28), QDate(2004, 3, 1)); + auto got = getDaysAndYearsBetween(QDate(2003, 2, 28), QDate(2004, 3, 1)); ASSERT_EQ(got, dayyear(2, 1)) << "there is a leap day in between these days this year"; } } // namespace From b17d879da88f537cd83609f5a4cb42715ef9eb4c Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Wed, 10 Jun 2026 10:58:28 +0200 Subject: [PATCH 11/17] [Game][Graphics][Player] Add named zone lookup-map to player graphics. (#6984) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Took 16 minutes Co-authored-by: Lukas Brübach --- .../player/player_graphics_item.cpp | 16 ++++++++++++++++ .../game_graphics/player/player_graphics_item.h | 7 +++++++ 2 files changed, 23 insertions(+) diff --git a/cockatrice/src/game_graphics/player/player_graphics_item.cpp b/cockatrice/src/game_graphics/player/player_graphics_item.cpp index 07975ed5e..e0194abda 100644 --- a/cockatrice/src/game_graphics/player/player_graphics_item.cpp +++ b/cockatrice/src/game_graphics/player/player_graphics_item.cpp @@ -59,6 +59,9 @@ PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player) initializeZones(); + connect(player, &PlayerLogic::addViewCustomZoneActionToCustomZoneMenu, this, + &PlayerGraphicsItem::onCustomZoneAdded); + playerMenu->setMenusForGraphicItems(); connect(tableZoneGraphicsItem, &TableZone::sizeChanged, this, &PlayerGraphicsItem::updateBoundingRect); @@ -121,6 +124,19 @@ void PlayerGraphicsItem::initializeZones() connect(handZoneGraphicsItem->getLogic(), &HandZoneLogic::cardCountChanged, handCounter, &HandCounter::updateNumber); connect(handCounter, &HandCounter::showContextMenu, handZoneGraphicsItem, &HandZone::showContextMenu); + + zoneGraphicsItems.insert(player->getDeckZone()->getName(), deckZoneGraphicsItem); + zoneGraphicsItems.insert(player->getGraveZone()->getName(), graveyardZoneGraphicsItem); + zoneGraphicsItems.insert(player->getRfgZone()->getName(), rfgZoneGraphicsItem); + zoneGraphicsItems.insert(player->getSideboardZone()->getName(), sideboardGraphicsItem); + zoneGraphicsItems.insert(player->getTableZone()->getName(), tableZoneGraphicsItem); + zoneGraphicsItems.insert(player->getStackZone()->getName(), stackZoneGraphicsItem); + zoneGraphicsItems.insert(player->getHandZone()->getName(), handZoneGraphicsItem); +} + +void PlayerGraphicsItem::onCustomZoneAdded(QString customZoneName) +{ + zoneGraphicsItems.insert(customZoneName, nullptr); // Custom zone view goes here, if we ever implement it. } QRectF PlayerGraphicsItem::boundingRect() const diff --git a/cockatrice/src/game_graphics/player/player_graphics_item.h b/cockatrice/src/game_graphics/player/player_graphics_item.h index 0dcc959bd..d02234ded 100644 --- a/cockatrice/src/game_graphics/player/player_graphics_item.h +++ b/cockatrice/src/game_graphics/player/player_graphics_item.h @@ -77,6 +77,11 @@ public: return playerTarget; } + CardZone *getZoneGraphicsItem(const QString &name) const + { + return zoneGraphicsItems.value(name, nullptr); + } + [[nodiscard]] PileZone *getDeckZoneGraphicsItem() const { return deckZoneGraphicsItem; @@ -110,6 +115,7 @@ public: public slots: void onPlayerActiveChanged(bool _active); + void onCustomZoneAdded(QString customZoneName); void onCounterAdded(CounterState *state); void onCounterRemoved(int counterId); void rearrangeCounters(); @@ -128,6 +134,7 @@ private: PlayerArea *playerArea; PlayerTarget *playerTarget; QMap counterWidgets; + QMap zoneGraphicsItems; PileZone *deckZoneGraphicsItem; PileZone *sideboardGraphicsItem; PileZone *graveyardZoneGraphicsItem; From 694adc9e64729e3fb5bf9f0d1940a896f5594f0d Mon Sep 17 00:00:00 2001 From: tooomm Date: Thu, 11 Jun 2026 10:45:17 +0200 Subject: [PATCH 12/17] Use Visual Studio 2026 (#6985) --- .github/workflows/desktop-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index 19c9a15e3..179fd824f 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -331,7 +331,7 @@ jobs: target: 10 runner: windows-2025 - cmake_generator: "Visual Studio 17 2022" + cmake_generator: "Visual Studio 18 2026" cmake_generator_platform: x64 make_package: 1 package_suffix: "-Win10" From 7aaacbf34701f0c051fe30b3e57ecc24515457b8 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Thu, 11 Jun 2026 21:17:28 +0200 Subject: [PATCH 13/17] [Update][NSIS] Use single string shell invocation (#6986) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Took 18 minutes Took 2 minutes Co-authored-by: Lukas Brübach --- cockatrice/src/interface/widgets/dialogs/dlg_update.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp index 15735168f..f12550fa8 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp @@ -220,9 +220,8 @@ void DlgUpdate::downloadSuccessful(const QUrl &filepath) { setLabel(tr("Installing...")); // Try to open the installer. If it opens, quit Cockatrice - if (QProcess::startDetached(filepath.toLocalFile(), - QStringList() - << "/R" << QString("/D=%1").arg(QCoreApplication::applicationDirPath()))) { + if (QProcess::startDetached( + QString("\"%1\" /R /D=\"%2\"").arg(filepath.toLocalFile(), QCoreApplication::applicationDirPath()))) { QMetaObject::invokeMethod(static_cast(parent()), "close", Qt::QueuedConnection); qCInfo(DlgUpdateLog) << "Opened downloaded update file successfully - closing Cockatrice"; close(); From f28ede7ae36916bf2bc5248fc46eed9ca44c5edb Mon Sep 17 00:00:00 2001 From: kongwu <167565490+kongwu666@users.noreply.github.com> Date: Sat, 13 Jun 2026 17:42:55 +0800 Subject: [PATCH 14/17] [UserContextMenu] Add confirmation dialog before kicking a player (#6987) --- .../widgets/server/user/user_context_menu.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cockatrice/src/interface/widgets/server/user/user_context_menu.cpp b/cockatrice/src/interface/widgets/server/user/user_context_menu.cpp index 195b1cc8d..faa96fa1f 100644 --- a/cockatrice/src/interface/widgets/server/user/user_context_menu.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_context_menu.cpp @@ -476,10 +476,15 @@ void UserContextMenu::showContextMenu(const QPoint &pos, client->sendCommand(client->prepareSessionCommand(cmd)); } else if (actionClicked == aKick) { - Command_KickFromGame cmd; - cmd.set_player_id(playerId); + auto result = QMessageBox::question(static_cast(parent()), tr("Kick Player"), + tr("Are you sure you want to kick this player from the game?"), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + if (result == QMessageBox::Yes) { + Command_KickFromGame cmd; + cmd.set_player_id(playerId); - game->getGameEventHandler()->sendGameCommand(cmd); + game->getGameEventHandler()->sendGameCommand(cmd); + } } else if (actionClicked == aBan) { Command_GetUserInfo cmd; cmd.set_user_name(userName.toStdString()); From 80705afafe6c3b3e427b073eaef54b4882a65d63 Mon Sep 17 00:00:00 2001 From: tooomm Date: Sat, 13 Jun 2026 22:30:57 +0200 Subject: [PATCH 15/17] Update desktop-build.yml --- .github/workflows/desktop-build.yml | 67 +++++++++++++---------------- 1 file changed, 30 insertions(+), 37 deletions(-) diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index f3536c9e2..b6c7b9fe4 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -7,6 +7,17 @@ permissions: id-token: write # needed for signing certificate in attestation on: + pull_request: + paths: + - '*/**' # matches all files not in root + - '!**.md' + - '!.github/**' + - '!.tx/**' + - '!doc/**' + - '.github/workflows/desktop-build.yml' + - 'CMakeLists.txt' + - 'vcpkg.json' + - 'vcpkg' # needed to match submodule bumps (gitlink) push: branches: - master @@ -22,30 +33,19 @@ on: - 'vcpkg' # needed to match submodule bumps (gitlink) tags: - '*' - pull_request: - paths: - - '*/**' # matches all files not in root - - '!**.md' - - '!.github/**' - - '!.tx/**' - - '!doc/**' - - '.github/workflows/desktop-build.yml' - - 'CMakeLists.txt' - - 'vcpkg.json' - - 'vcpkg' # needed to match submodule bumps (gitlink) # Cancel earlier, unfinished runs of this workflow on the same branch (unless on release) concurrency: - group: "${{ github.workflow }} @ ${{ github.ref_name }}" cancel-in-progress: ${{ github.ref_type != 'tag' }} + group: "${{ github.workflow }} @ ${{ github.ref_name }}" jobs: configure: name: Configure runs-on: ubuntu-slim outputs: - tag: ${{ steps.configure.outputs.tag }} sha: ${{ steps.configure.outputs.sha }} + tag: ${{ steps.configure.outputs.tag }} steps: - name: "Configure" @@ -54,7 +54,7 @@ jobs: run: | tag_regex='^refs/tags/' if [[ $GITHUB_EVENT_NAME == pull-request ]]; then # pull request - sha="${{github.event.pull_request.head.sha}}" + sha="${{ github.event.pull_request.head.sha }}" elif [[ $GITHUB_REF =~ $tag_regex ]]; then # release sha="$GITHUB_SHA" tag="${GITHUB_REF/refs\/tags\//}" @@ -71,8 +71,8 @@ jobs: fetch-depth: 0 # fetch all history for all branches and tags - name: "Prepare release parameters" - id: prepare if: steps.configure.outputs.tag != null + id: prepare shell: bash env: TAG: ${{ steps.configure.outputs.tag }} @@ -83,12 +83,12 @@ jobs: id: create_release shell: bash env: + body_path: ${{ steps.prepare.outputs.body_path }} GH_TOKEN: ${{ github.token }} + prerelease: ${{ steps.prepare.outputs.is_beta }} + release_name: ${{ steps.prepare.outputs.title }} tag_name: ${{ steps.configure.outputs.tag }} target: ${{ steps.configure.outputs.sha }} - release_name: ${{ steps.prepare.outputs.title }} - body_path: ${{ steps.prepare.outputs.body_path }} - prerelease: ${{ steps.prepare.outputs.is_beta }} run: | args=() [[ $prerelease == yes ]] && args+=(--prerelease) @@ -188,13 +188,13 @@ jobs: --cmake-generator "$CMAKE_GENERATOR" - name: "Build release package" - id: build if: matrix.package != 'skip' + id: build shell: bash env: - SUFFIX: '-${{ matrix.distro }}${{ matrix.version }}' package: '${{ matrix.package }}' server_only: '${{ matrix.server_only }}' + SUFFIX: '-${{ matrix.distro }}${{ matrix.version }}' run: | source .ci/docker.sh args=() @@ -225,8 +225,8 @@ jobs: path: ${{ env.CACHE }} - name: "Upload artifact" - id: upload_artifact if: matrix.package != 'skip' + id: upload_artifact uses: actions/upload-artifact@v7 with: archive: false @@ -234,8 +234,8 @@ jobs: path: ${{ steps.build.outputs.path }} - name: "Upload to release" - id: upload_release if: matrix.package != 'skip' && needs.configure.outputs.tag != null + id: upload_release shell: bash env: asset_name: ${{ steps.build.outputs.fullname }} @@ -245,8 +245,8 @@ jobs: run: gh release upload "$tag_name" "$asset_path#$asset_name" - name: "Attest binary provenance" - id: attestation if: steps.upload_release.outcome == 'success' + id: attestation uses: actions/attest@v4 with: show-summary: false @@ -268,7 +268,6 @@ jobs: target: 13 runner: macos-15-intel - ccache_eviction_age: 7d cmake_generator: Ninja make_package: 1 override_target: 13 @@ -285,7 +284,6 @@ jobs: target: 14 runner: macos-14 - ccache_eviction_age: 7d cmake_generator: Ninja make_package: 1 package_suffix: "-macOS14" @@ -301,7 +299,6 @@ jobs: target: 15 runner: macos-15 - ccache_eviction_age: 7d cmake_generator: Ninja make_package: 1 package_suffix: "-macOS15" @@ -317,7 +314,6 @@ jobs: target: 15 runner: macos-15 - ccache_eviction_age: 7d cmake_generator: Ninja qt_version: 6.11.0 qt_arch: clang_64 @@ -346,6 +342,7 @@ jobs: timeout-minutes: 100 env: CCACHE_DIR: ${{ github.workspace }}/.cache/ + CCACHE_EVICTION_AGE: 7d CCACHE_SIZE: 550M # space of all repo is 10Gi: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy steps: @@ -443,16 +440,12 @@ jobs: id: build shell: bash env: - BUILDTYPE: '${{matrix.type}}' - MAKE_PACKAGE: '${{matrix.make_package}}' - PACKAGE_SUFFIX: '${{matrix.package_suffix}}' - CMAKE_GENERATOR: ${{matrix.cmake_generator}} - CMAKE_GENERATOR_PLATFORM: ${{matrix.cmake_generator_platform}} - USE_CCACHE: ${{matrix.use_ccache}} - VCPKG_DISABLE_METRICS: 1 - VCPKG_BINARY_SOURCES: 'clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite' - # macOS-specific environment variables, will be ignored on Windows - DEVELOPER_DIR: '/Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer' + BUILDTYPE: ${{ matrix.type }} + CMAKE_GENERATOR: ${{ matrix.cmake_generator }} + CMAKE_GENERATOR_PLATFORM: ${{ matrix.cmake_generator_platform }} + DEVELOPER_DIR: '/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer' + MAKE_PACKAGE: ${{ matrix.make_package }} + PACKAGE_SUFFIX: ${{ matrix.package_suffix }} TARGET_MACOS_VERSION: ${{ matrix.override_target }} USE_CCACHE: ${{ matrix.use_ccache }} VCPKG_BINARY_SOURCES: 'clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite' From 3978c7e642d2d2d2c716db084de69d248c7a3645 Mon Sep 17 00:00:00 2001 From: tooomm Date: Sun, 14 Jun 2026 00:22:29 +0200 Subject: [PATCH 16/17] move keychain setup and cert import back into build step --- .ci/compile.sh | 15 +++++++++++++++ .ci/sign_macos_bundle.sh | 16 ---------------- .github/workflows/desktop-build.yml | 6 ++++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.ci/compile.sh b/.ci/compile.sh index 19777aa94..ee846897b 100755 --- a/.ci/compile.sh +++ b/.ci/compile.sh @@ -218,6 +218,21 @@ if [[ $RUNNER_OS == macOS ]]; then echo "::endgroup::" fi + echo "::group::Signing Certificate" + if [[ -n "$MACOS_CERTIFICATE_NAME" ]]; then + echo "$MACOS_CERTIFICATE" | base64 --decode >"certificate.p12" + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + security default-keychain -s build.keychain + security set-keychain-settings -t 3600 -l build.keychain + security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain + echo "macOS signing certificate successfully imported and keychain configured." + else + echo "No signing certificate configured. Skipping set up of keychain in macOS environment." + fi + echo "::endgroup::" + if [[ $MAKE_PACKAGE ]]; then # Workaround https://github.com/actions/runner-images/issues/7522 # have hdiutil repeat the command 10 times in hope of success diff --git a/.ci/sign_macos_bundle.sh b/.ci/sign_macos_bundle.sh index 60ac7b3c7..e645d6119 100755 --- a/.ci/sign_macos_bundle.sh +++ b/.ci/sign_macos_bundle.sh @@ -28,22 +28,6 @@ if [[ ! -e "$APP_BUNDLE_PATH" ]]; then exit 1 fi -# Configure keychain -if [[ -n "$MACOS_CERTIFICATE" ]]; then - echo "::group::Import certificate" - echo "$MACOS_CERTIFICATE" | base64 --decode >"certificate.p12" - security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain - security default-keychain -s build.keychain - security set-keychain-settings -t 3600 -l build.keychain - security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain - security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign - security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain - echo "::endgroup::" -else - echo "::error file=$0::MACOS_CERTIFICATE not set. Can not configure keychain." - exit 1 -fi - # Sign app bundle if [[ -n "$MACOS_CERTIFICATE_NAME" ]]; then echo "::group::Sign app bundle" diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index b6c7b9fe4..17a85529f 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -444,6 +444,10 @@ jobs: CMAKE_GENERATOR: ${{ matrix.cmake_generator }} CMAKE_GENERATOR_PLATFORM: ${{ matrix.cmake_generator_platform }} DEVELOPER_DIR: '/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer' + MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} + MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} + MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} MAKE_PACKAGE: ${{ matrix.make_package }} PACKAGE_SUFFIX: ${{ matrix.package_suffix }} TARGET_MACOS_VERSION: ${{ matrix.override_target }} @@ -475,9 +479,7 @@ jobs: if: matrix.os == 'macOS' shell: bash env: - MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }} MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} - MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }} MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }} From cc4f21b369666e95eb3ac65cfe22b85342ca34f2 Mon Sep 17 00:00:00 2001 From: tooomm Date: Sun, 14 Jun 2026 00:54:33 +0200 Subject: [PATCH 17/17] stricter check for file in app bundle path --- .ci/sign_macos_bundle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/sign_macos_bundle.sh b/.ci/sign_macos_bundle.sh index e645d6119..344f27cb7 100755 --- a/.ci/sign_macos_bundle.sh +++ b/.ci/sign_macos_bundle.sh @@ -23,7 +23,7 @@ fi APP_BUNDLE_PATH="$1" # Verify that app bundle exists -if [[ ! -e "$APP_BUNDLE_PATH" ]]; then +if [[ ! -f "$APP_BUNDLE_PATH" ]]; then echo "::error file=$0::App bundle not found at: $APP_BUNDLE_PATH" exit 1 fi