diff --git a/image.png b/image.png new file mode 100644 index 0000000..161c336 Binary files /dev/null and b/image.png differ diff --git a/src/include/Tetris.h b/src/include/Tetris.h index 909b8d4..1557a5d 100644 --- a/src/include/Tetris.h +++ b/src/include/Tetris.h @@ -132,7 +132,7 @@ struct UpgradeUiState int pendingCount; int totalChosenCount; int picksRemaining; - UpgradeOption options[5]; + UpgradeOption options[6]; }; struct FeedbackState diff --git a/src/source/Tetris.cpp b/src/source/Tetris.cpp index bbe2b3c..157b636 100644 --- a/src/source/Tetris.cpp +++ b/src/source/Tetris.cpp @@ -366,21 +366,31 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) if (currentScreen == SCREEN_UPGRADE) { + int upgradeColumnCount = upgradeUiState.optionCount <= 3 ? upgradeUiState.optionCount : 3; + if (upgradeColumnCount < 1) + { + upgradeColumnCount = 1; + } + switch (wParam) { case VK_LEFT: case 'A': if (upgradeUiState.optionCount > 1) { - if ((upgradeUiState.selectedIndex % 2) == 1) + int rowStart = upgradeUiState.selectedIndex - (upgradeUiState.selectedIndex % upgradeColumnCount); + if (upgradeUiState.selectedIndex > rowStart) { upgradeUiState.selectedIndex--; } else { - upgradeUiState.selectedIndex = (upgradeUiState.selectedIndex + 1 < upgradeUiState.optionCount) - ? upgradeUiState.selectedIndex + 1 - : upgradeUiState.selectedIndex; + int rowEnd = rowStart + upgradeColumnCount - 1; + if (rowEnd >= upgradeUiState.optionCount) + { + rowEnd = upgradeUiState.optionCount - 1; + } + upgradeUiState.selectedIndex = rowEnd; } } InvalidateRect(hWnd, nullptr, FALSE); @@ -389,34 +399,37 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case 'D': if (upgradeUiState.optionCount > 1) { - if ((upgradeUiState.selectedIndex % 2) == 0 && upgradeUiState.selectedIndex + 1 < upgradeUiState.optionCount) + int rowStart = upgradeUiState.selectedIndex - (upgradeUiState.selectedIndex % upgradeColumnCount); + int rowEnd = rowStart + upgradeColumnCount - 1; + if (rowEnd >= upgradeUiState.optionCount) + { + rowEnd = upgradeUiState.optionCount - 1; + } + + if (upgradeUiState.selectedIndex < rowEnd) { upgradeUiState.selectedIndex++; } else { - upgradeUiState.selectedIndex--; - if (upgradeUiState.selectedIndex < 0) - { - upgradeUiState.selectedIndex = 0; - } + upgradeUiState.selectedIndex = rowStart; } } InvalidateRect(hWnd, nullptr, FALSE); break; case VK_UP: case 'W': - if (upgradeUiState.optionCount > 2 && upgradeUiState.selectedIndex >= 2) + if (upgradeUiState.selectedIndex >= upgradeColumnCount) { - upgradeUiState.selectedIndex -= 2; + upgradeUiState.selectedIndex -= upgradeColumnCount; } InvalidateRect(hWnd, nullptr, FALSE); break; case VK_DOWN: case 'S': - if (upgradeUiState.optionCount > 2 && upgradeUiState.selectedIndex + 2 < upgradeUiState.optionCount) + if (upgradeUiState.selectedIndex + upgradeColumnCount < upgradeUiState.optionCount) { - upgradeUiState.selectedIndex += 2; + upgradeUiState.selectedIndex += upgradeColumnCount; } InvalidateRect(hWnd, nullptr, FALSE); break; diff --git a/src/source/TetrisRogue.cpp b/src/source/TetrisRogue.cpp index ece5781..440efb2 100644 --- a/src/source/TetrisRogue.cpp +++ b/src/source/TetrisRogue.cpp @@ -68,7 +68,7 @@ static const UpgradeEntry kUpgradePool[] = { UPGRADE_SCREEN_BOMB, 1, 78, false, _T("\u6e05\u5c4f\u70b8\u5f39"), _T("\u8fdb\u9636"), _T("\u7d2f\u8ba1\u6d88\u884c 30 \u884c\u540e\u83b7\u5f97 1 \u6b21\u6e05\u5c4f\u70b8\u5f39\uff0c\u53ef\u81ea\u52a8\u6216\u4e3b\u52a8\u6e05\u9664\u5e95\u90e8 5 \u884c\u3002") }, { UPGRADE_TERMINAL_CLEAR, 1, 108, false, _T("\u7ec8\u672b\u6e05\u573a"), _T("\u8fdb\u5316"), _T("\u6fc0\u6d3b\u6700\u540e\u4e00\u640f\u65f6\u81ea\u52a8\u91ca\u653e\u4e00\u6b21\u6e05\u5c4f\u70b8\u5f39\uff0c\u5e76\u8fdb\u5165 10 \u79d2\u72c2\u70ed\u3002") }, { UPGRADE_DUAL_CHOICE, 1, 68, false, _T("\u53cc\u91cd\u9009\u62e9"), _T("\u8fdb\u9636"), _T("\u6bcf\u6b21\u5347\u7ea7\u53ef\u989d\u5916\u518d\u9009 1 \u4e2a\u5f3a\u5316\uff0c\u4f46\u4e0b\u4e00\u6b21\u5347\u7ea7\u9700\u6c42 +30%\u3002") }, - { UPGRADE_DESTINY_WHEEL, 1, 104, false, _T("\u547d\u8fd0\u8f6e\u76d8"), _T("\u8fdb\u5316"), _T("\u6bcf\u6b21\u5347\u7ea7\u51fa\u73b0 5 \u4e2a\u9009\u9879\uff0c\u53ef\u9009 2 \u4e2a\uff0c\u4f46\u5176\u4e2d 1 \u4e2a\u9644\u5e26\u8d1f\u9762\u6548\u679c\u3002") }, + { UPGRADE_DESTINY_WHEEL, 1, 104, false, _T("\u547d\u8fd0\u8f6e\u76d8"), _T("\u8fdb\u5316"), _T("\u6bcf\u6b21\u5347\u7ea7\u51fa\u73b0 6 \u4e2a\u9009\u9879\uff0c\u53ef\u9009 2 \u4e2a\uff0c\u4f46\u5176\u4e2d 1 \u4e2a\u9644\u5e26\u8d1f\u9762\u6548\u679c\u3002") }, { UPGRADE_PERFECT_ROTATE, 1, 82, false, _T("\u5b8c\u7f8e\u65cb\u8f6c"), _T("\u64cd\u4f5c"), _T("\u65cb\u8f6c\u5931\u8d25\u65f6\u81ea\u52a8\u5c1d\u8bd5\u5de6\u53f3\u5404\u504f\u79fb 1 \u683c\u8fdb\u884c\u4fee\u6b63\u3002") }, { UPGRADE_TIME_DILATION, 1, 80, false, _T("\u65f6\u95f4\u7f13\u6d41"), _T("\u4fdd\u547d"), _T("\u76d8\u9762\u63a5\u8fd1\u9876\u7aef\u65f6\u81ea\u52a8\u964d\u4f4e\u4e0b\u843d\u901f\u5ea6\uff0c\u4e3a\u8865\u6551\u7559\u51fa\u53cd\u5e94\u7a7a\u95f4\u3002") }, { UPGRADE_HIGH_PRESSURE, 1, 70, false, _T("\u9ad8\u538b\u5956\u52b1"), _T("\u98ce\u9669"), _T("\u4e0b\u843d\u901f\u5ea6\u63d0\u9ad8 15%\uff0c\u4f46\u5f97\u5206\u4e0e EXP \u989d\u5916\u63d0\u9ad8 50%\u3002") }, @@ -1026,7 +1026,7 @@ static void FillUpgradeOptions() } } - int optionLimit = (rogueStats.destinyWheelLevel > 0) ? 5 : 3; + int optionLimit = (rogueStats.destinyWheelLevel > 0) ? 6 : 3; int optionCount = selectableCount < optionLimit ? selectableCount : optionLimit; upgradeUiState.optionCount = optionCount; upgradeUiState.selectedIndex = 0; @@ -1094,7 +1094,7 @@ static void FillUpgradeOptions() upgradeUiState.options[i].currentLevel = rogueStats.pieceTuningLevels[targetPieceType]; upgradeUiState.options[i].name = _T("\u65b9\u5757\u6539\u9020"); - static TCHAR tuningDescriptions[4][64]; + static TCHAR tuningDescriptions[6][64]; _stprintf_s( tuningDescriptions[i], _T("\u964d\u4f4e %s \u65b9\u5757\u7684\u51fa\u73b0\u6982\u7387\u3002"), @@ -1774,10 +1774,20 @@ void ConfirmUpgradeSelection() void HoldCurrentPiece() { - if (currentMode != MODE_ROGUE || rogueStats.holdUnlocked == 0 || holdUsedThisTurn || gameOverFlag) + if (currentMode != MODE_ROGUE || currentScreen != SCREEN_PLAYING || suspendFlag || gameOverFlag) { return; } + if (rogueStats.holdUnlocked == 0) + { + SetFeedbackMessage(_T("Hold \u672a\u89e3\u9501"), _T("\u9700\u8981\u5148\u83b7\u5f97 Hold \u89e3\u9501\u5f3a\u5316\u3002"), 10); + return; + } + if (holdUsedThisTurn) + { + SetFeedbackMessage(_T("Hold \u6682\u4e0d\u53ef\u7528"), _T("\u6bcf\u4e2a\u65b9\u5757\u53ea\u80fd Hold \u4e00\u6b21\uff0c\u843d\u5730\u540e\u6062\u590d\u3002"), 10); + return; + } int previousHoldType = holdType; holdType = type; @@ -1825,10 +1835,20 @@ void HoldCurrentPiece() void UseScreenBomb() { - if (currentMode != MODE_ROGUE || rogueStats.screenBombCount <= 0 || currentScreen != SCREEN_PLAYING || suspendFlag || gameOverFlag) + if (currentMode != MODE_ROGUE || currentScreen != SCREEN_PLAYING || suspendFlag || gameOverFlag) { return; } + if (rogueStats.screenBombLevel <= 0) + { + SetFeedbackMessage(_T("\u6e05\u5c4f\u70b8\u5f39\u672a\u89e3\u9501"), _T("\u9700\u8981\u5148\u83b7\u5f97\u6e05\u5c4f\u70b8\u5f39\u5f3a\u5316\u3002"), 10); + return; + } + if (rogueStats.screenBombCount <= 0) + { + SetFeedbackMessage(_T("\u6e05\u5c4f\u70b8\u5f39\u672a\u5c31\u7eea"), _T("\u7d2f\u8ba1\u6d88\u884c\u5145\u80fd\u540e\u624d\u80fd\u4f7f\u7528\u3002"), 10); + return; + } rogueStats.screenBombCount--; int clearedCells = TriggerScreenBomb(); @@ -1855,10 +1875,20 @@ void UseScreenBomb() void UseBlackHole() { - if (currentMode != MODE_ROGUE || rogueStats.blackHoleCharges <= 0 || currentScreen != SCREEN_PLAYING || suspendFlag || gameOverFlag) + if (currentMode != MODE_ROGUE || currentScreen != SCREEN_PLAYING || suspendFlag || gameOverFlag) { return; } + if (rogueStats.blackHoleLevel <= 0) + { + SetFeedbackMessage(_T("\u9ed1\u6d1e\u672a\u89e3\u9501"), _T("\u9700\u8981\u5148\u83b7\u5f97\u9ed1\u6d1e\u5f3a\u5316\u3002"), 10); + return; + } + if (rogueStats.blackHoleCharges <= 0) + { + SetFeedbackMessage(_T("\u9ed1\u6d1e\u6b21\u6570\u4e0d\u8db3"), _T("\u5f53\u524d\u6ca1\u6709\u53ef\u7528\u7684\u9ed1\u6d1e\u6b21\u6570\u3002"), 10); + return; + } int clearedCells = TriggerBlackHole(); if (clearedCells <= 0) @@ -1908,10 +1938,20 @@ void UseBlackHole() void UseAirReshape() { - if (currentMode != MODE_ROGUE || rogueStats.reshapeCharges <= 0 || currentScreen != SCREEN_PLAYING || suspendFlag || gameOverFlag) + if (currentMode != MODE_ROGUE || currentScreen != SCREEN_PLAYING || suspendFlag || gameOverFlag) { return; } + if (rogueStats.reshapeLevel <= 0) + { + SetFeedbackMessage(_T("\u7a7a\u4e2d\u6362\u5f62\u672a\u89e3\u9501"), _T("\u9700\u8981\u5148\u83b7\u5f97\u7a7a\u4e2d\u6362\u5f62\u5f3a\u5316\u3002"), 10); + return; + } + if (rogueStats.reshapeCharges <= 0) + { + SetFeedbackMessage(_T("\u7a7a\u4e2d\u6362\u5f62\u6b21\u6570\u4e0d\u8db3"), _T("\u5f53\u524d\u6ca1\u6709\u53ef\u7528\u7684\u6362\u5f62\u6b21\u6570\u3002"), 10); + return; + } const int targetType = 0; const int candidateStates[2] = { 0, 1 };