From cbf7bac239871a3cf7176e3f82449ab0b6c86db6 Mon Sep 17 00:00:00 2001 From: Qi-huanye <2728290997@qq.com> Date: Sun, 26 Apr 2026 14:57:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=A4=9A=E9=80=89=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/Tetris.h | 2 + src/source/Tetris.cpp | 27 +++++++++- src/source/TetrisLogic.cpp | 4 +- src/source/TetrisRender.cpp | 46 +++++++++++++--- src/source/TetrisRogue.cpp | 103 ++++++++++++++++++++++++++++++++++++ 5 files changed, 173 insertions(+), 9 deletions(-) diff --git a/src/include/Tetris.h b/src/include/Tetris.h index f63a4f2..8410b98 100644 --- a/src/include/Tetris.h +++ b/src/include/Tetris.h @@ -140,6 +140,8 @@ struct UpgradeUiState int pendingCount; int totalChosenCount; int picksRemaining; + int markedCount; + bool marked[6]; UpgradeOption options[6]; }; diff --git a/src/source/Tetris.cpp b/src/source/Tetris.cpp index 63d34ba..5906dca 100644 --- a/src/source/Tetris.cpp +++ b/src/source/Tetris.cpp @@ -824,11 +824,36 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) InvalidateRect(hWnd, nullptr, FALSE); break; case VK_RETURN: - case VK_SPACE: ConfirmUpgradeSelection(); ResetGameTimer(hWnd); InvalidateRect(hWnd, nullptr, FALSE); break; + case VK_SPACE: + if (upgradeUiState.picksRemaining > 1 && upgradeUiState.optionCount > 0) + { + bool currentlyMarked = upgradeUiState.marked[upgradeUiState.selectedIndex]; + if (currentlyMarked) + { + upgradeUiState.marked[upgradeUiState.selectedIndex] = false; + if (upgradeUiState.markedCount > 0) + { + upgradeUiState.markedCount--; + } + } + else if (upgradeUiState.markedCount < upgradeUiState.picksRemaining) + { + upgradeUiState.marked[upgradeUiState.selectedIndex] = true; + upgradeUiState.markedCount++; + } + InvalidateRect(hWnd, nullptr, FALSE); + } + else + { + ConfirmUpgradeSelection(); + ResetGameTimer(hWnd); + InvalidateRect(hWnd, nullptr, FALSE); + } + break; default: break; } diff --git a/src/source/TetrisLogic.cpp b/src/source/TetrisLogic.cpp index 9e0c55d..50ff114 100644 --- a/src/source/TetrisLogic.cpp +++ b/src/source/TetrisLogic.cpp @@ -17,7 +17,7 @@ MenuState menuState = { 0, 2 }; HelpState helpState = { 0, 3, 0 }; PlayerStats classicStats = { 0, 1, 0, 0, 0 }; PlayerStats rogueStats = { 0, 1, 0, 30, 0, 100, 100, 0 }; -UpgradeUiState upgradeUiState = { 0, 0, 0, 0, {} }; +UpgradeUiState upgradeUiState = { 0, 0, 0, 0, 0, 0, {}, {} }; FeedbackState feedbackState = { 0, _T(""), _T("") }; ClearEffectState clearEffectState = { 0, 0, 0, {} }; FloatingTextEffect floatingTextEffects[8] = {}; @@ -1172,6 +1172,7 @@ void Restart() upgradeUiState.pendingCount = 0; upgradeUiState.totalChosenCount = 0; upgradeUiState.picksRemaining = 0; + upgradeUiState.markedCount = 0; feedbackState.visibleTicks = 0; feedbackState.title[0] = _T('\0'); feedbackState.detail[0] = _T('\0'); @@ -1258,6 +1259,7 @@ void ReturnToMainMenu() menuState.optionCount = 3; upgradeUiState.pendingCount = 0; upgradeUiState.picksRemaining = 0; + upgradeUiState.markedCount = 0; if (menuState.selectedIndex < 0 || menuState.selectedIndex >= menuState.optionCount) { diff --git a/src/source/TetrisRender.cpp b/src/source/TetrisRender.cpp index 494a6b0..6d3bcee 100644 --- a/src/source/TetrisRender.cpp +++ b/src/source/TetrisRender.cpp @@ -1844,11 +1844,23 @@ void TDrawScreen(HDC hdc, HWND hWnd) overlayRect.top + SS(106) }; TCHAR overlaySubtitle[128]; - _stprintf_s( - overlaySubtitle, - _T("出现 %d 个强化,还可选择 %d 个"), - upgradeUiState.optionCount, - upgradeUiState.picksRemaining); + if (upgradeUiState.picksRemaining > 1) + { + _stprintf_s( + overlaySubtitle, + _T("出现 %d 个强化,请标记 %d 个(已选 %d 个)"), + upgradeUiState.optionCount, + upgradeUiState.picksRemaining, + upgradeUiState.markedCount); + } + else + { + _stprintf_s( + overlaySubtitle, + _T("出现 %d 个强化,还可选择 %d 个"), + upgradeUiState.optionCount, + upgradeUiState.picksRemaining); + } DrawText(hdc, overlaySubtitle, -1, &overlaySubtitleRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); int gap = SS(18); @@ -1871,6 +1883,7 @@ void TDrawScreen(HDC hdc, HWND hWnd) for (int i = 0; i < upgradeUiState.optionCount; i++) { bool isSelected = (i == upgradeUiState.selectedIndex); + bool isMarked = upgradeUiState.marked[i]; int column = i % columnCount; int row = i / columnCount; int left = overlayRect.left + horizontalPadding + column * (cardWidth + gap); @@ -1920,6 +1933,11 @@ void TDrawScreen(HDC hdc, HWND hWnd) rarityText = _T("\u7a00\u6709\u5ea6\uff1a\u7f55\u89c1"); } + if (isMarked && !upgradeUiState.options[i].cursed) + { + cardFill = RGB(255, 226, 236); + } + if (isSelected && !upgradeUiState.options[i].cursed) { cardFill = RGB(255, 235, 242); @@ -1948,7 +1966,14 @@ void TDrawScreen(HDC hdc, HWND hWnd) }; SelectObject(hdc, smallFont); SetTextColor(hdc, footerColor); - DrawText(hdc, levelText, -1, &levelRect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE); + if (isMarked) + { + DrawText(hdc, _T("[已选]"), -1, &levelRect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE); + } + else + { + DrawText(hdc, levelText, -1, &levelRect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE); + } SelectObject(hdc, sectionFont); SetTextColor(hdc, upgradeUiState.options[i].cursed ? RGB(130, 54, 54) : (isSelected ? titleColor : textColor)); @@ -2011,7 +2036,14 @@ void TDrawScreen(HDC hdc, HWND hWnd) overlayRect.right - SS(30), overlayRect.bottom - SS(18) }; - DrawText(hdc, _T("W/A/S/D \u6216\u65b9\u5411\u952e\u5207\u6362\uff0cEnter \u6216 Space \u786e\u8ba4"), -1, &hintRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); + DrawText( + hdc, + upgradeUiState.picksRemaining > 1 + ? _T("W/A/S/D 或方向键切换,Space 标记,Enter 确认已选强化") + : _T("W/A/S/D 或方向键切换,Enter 或 Space 确认"), + -1, + &hintRect, + DT_CENTER | DT_VCENTER | DT_SINGLELINE); } DrawMusicButton(); diff --git a/src/source/TetrisRogue.cpp b/src/source/TetrisRogue.cpp index c05a705..979ceb6 100644 --- a/src/source/TetrisRogue.cpp +++ b/src/source/TetrisRogue.cpp @@ -1219,6 +1219,11 @@ static void FillUpgradeOptions() upgradeUiState.optionCount = optionCount; upgradeUiState.selectedIndex = 0; upgradeUiState.picksRemaining = (rogueStats.dualChoiceLevel > 0 || rogueStats.destinyWheelLevel > 0) ? 2 : 1; + upgradeUiState.markedCount = 0; + for (int i = 0; i < 6; i++) + { + upgradeUiState.marked[i] = false; + } for (int i = 0; i < optionCount; i++) { @@ -2003,6 +2008,103 @@ void ConfirmUpgradeSelection() return; } + if (upgradeUiState.picksRemaining > 1) + { + if (upgradeUiState.markedCount != upgradeUiState.picksRemaining) + { + SetFeedbackMessage(_T("选择未完成"), _T("请先标记足够的强化,再按 Enter 确认。"), 10); + return; + } + + TCHAR feedbackTitle[64] = _T("获得强化"); + TCHAR feedbackDetail[128] = _T(""); + int appliedSelections = 0; + + for (int optionIndex = 0; optionIndex < upgradeUiState.optionCount; optionIndex++) + { + if (!upgradeUiState.marked[optionIndex]) + { + continue; + } + + UpgradeOption selectedOption = upgradeUiState.options[optionIndex]; + int applyCount = 1; + TCHAR gamblerSuffix[64] = _T(""); + + if (currentMode == MODE_ROGUE && rogueStats.gamblerLevel > 0) + { + int gamblerChance = 20 + (rogueStats.gamblerLevel - 1) * 5; + if (gamblerChance > 40) + { + gamblerChance = 40; + } + + int roll = rand() % 100; + if (roll < gamblerChance) + { + applyCount = 2; + _stprintf_s(gamblerSuffix, _T("(翻倍)")); + } + else if (roll >= 100 - gamblerChance) + { + applyCount = 0; + _stprintf_s(gamblerSuffix, _T("(落空)")); + } + } + + ApplyUpgradeById(selectedOption.id, selectedOption.targetPieceType, applyCount); + upgradeUiState.totalChosenCount++; + + if (selectedOption.cursed) + { + ApplyDestinyCurse(); + } + + if (appliedSelections == 0) + { + _stprintf_s(feedbackTitle, _T("获得强化:%s"), selectedOption.name); + } + else + { + _stprintf_s(feedbackTitle, _T("获得强化 x%d"), appliedSelections + 1); + } + + if (lstrlen(feedbackDetail) > 0) + { + _stprintf_s(feedbackDetail + lstrlen(feedbackDetail), 128 - lstrlen(feedbackDetail), _T(";")); + } + _stprintf_s( + feedbackDetail + lstrlen(feedbackDetail), + 128 - lstrlen(feedbackDetail), + _T("%s%s%s"), + selectedOption.name, + gamblerSuffix, + selectedOption.cursed ? _T(" [诅咒]") : _T("")); + appliedSelections++; + } + + SetFeedbackMessage(feedbackTitle, feedbackDetail, 12); + if (upgradeUiState.pendingCount > 0) + { + upgradeUiState.pendingCount--; + } + + if (upgradeUiState.pendingCount > 0) + { + FillUpgradeOptions(); + currentScreen = SCREEN_UPGRADE; + return; + } + + upgradeUiState.optionCount = 0; + upgradeUiState.picksRemaining = 0; + upgradeUiState.markedCount = 0; + currentScreen = SCREEN_PLAYING; + ResolvePendingUpgradeShockwave(); + PlayPendingLineClearEffect(); + return; + } + UpgradeOption selectedOption = upgradeUiState.options[upgradeUiState.selectedIndex]; int applyCount = 1; TCHAR gamblerSuffix[64] = _T(""); @@ -2096,6 +2198,7 @@ void ConfirmUpgradeSelection() upgradeUiState.optionCount = 0; upgradeUiState.picksRemaining = 0; + upgradeUiState.markedCount = 0; currentScreen = SCREEN_PLAYING; ResolvePendingUpgradeShockwave();