进一步拆分与注释补强
This commit is contained in:
Submodule
+1
Submodule .worktrees/ack-syc-swj added at 58ab400949
+135
-55
@@ -382,40 +382,42 @@ void DropDown()
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将当前活动方块固定到工作区,并生成下一个活动方块。
|
||||
*
|
||||
* 遍历当前方块 4x4 形状矩阵,把其中所有非空单元写入工作区数组,
|
||||
* 表示该方块已经落地并转为固定状态。
|
||||
* 如果固定时仍有任意非空单元位于可视区域顶部之外,则判定游戏结束。
|
||||
* 此时当前方块在可视区域内的部分仍会保留在工作区中。
|
||||
* 若未超出顶部,再将“下一方块”切换为新的当前方块,重置旋转状态,
|
||||
* 并把新方块生成到工作区上方的初始位置,同时刷新预测落点。
|
||||
* @brief 收集当前方块将要固定到棋盘上的格子,并标记是否越过顶部。
|
||||
* @param overflowTop 返回是否有方块格位于可视区域顶部之外。
|
||||
* @param fixedCells 返回普通落地格,用于后续特殊效果定位。
|
||||
* @param fixedCellCount 返回普通落地格数量。
|
||||
* @param explosiveCells 返回爆破方块落地格。
|
||||
* @param explosiveCellCount 返回爆破方块落地格数量。
|
||||
*/
|
||||
void Fixing()
|
||||
static void CollectAndWriteFixedCells(
|
||||
bool& overflowTop,
|
||||
Point fixedCells[],
|
||||
int& fixedCellCount,
|
||||
Point explosiveCells[],
|
||||
int& explosiveCellCount)
|
||||
{
|
||||
bool overflowTop = false;
|
||||
Point fixedCells[4] = {};
|
||||
int fixedCellCount = 0;
|
||||
Point explosiveCells[4] = {};
|
||||
int explosiveCellCount = 0;
|
||||
pendingChainBombFollowup = false;
|
||||
overflowTop = false;
|
||||
fixedCellCount = 0;
|
||||
explosiveCellCount = 0;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (bricks[type][state][i][j] != 0)
|
||||
if (bricks[type][state][i][j] == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int fixY = point.y + i;
|
||||
int fixX = point.x + j;
|
||||
|
||||
// 只要当前方块任意非空单元仍超出顶部,就标记为结束
|
||||
// 顶部溢出只记录状态,真正的复活或结束逻辑在后续统一处理。
|
||||
if (fixY < 0)
|
||||
{
|
||||
overflowTop = true;
|
||||
}
|
||||
|
||||
// 将当前方块在可视区域内的部分写入工作区
|
||||
if (fixY >= 0 && fixY < GetRoguePlayableHeight() && fixX >= 0 && fixX < nGameWidth)
|
||||
{
|
||||
workRegion[fixY][fixX] = currentPieceIsRainbow ? 8 : bricks[type][state][i][j];
|
||||
@@ -434,12 +436,20 @@ void Fixing()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 处理方块固定时的顶部溢出、终末清场和最后一搏。
|
||||
* @param overflowTop 是否出现顶部溢出。
|
||||
* @return 溢出已被处理且游戏可以继续时返回 true;需要结束游戏时返回 false。
|
||||
*/
|
||||
static bool ResolveFixingOverflow(bool overflowTop)
|
||||
{
|
||||
if (!overflowTop)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ApplyRainbowLandingEffect(overflowTop, fixedCells, fixedCellCount);
|
||||
|
||||
if (overflowTop)
|
||||
{
|
||||
if (currentMode == MODE_ROGUE && rogueStats.terminalClearLevel > 0 && rogueStats.lastChanceCount > 0 && rogueStats.screenBombCount > 0)
|
||||
{
|
||||
rogueStats.lastChanceCount--;
|
||||
@@ -455,8 +465,10 @@ void Fixing()
|
||||
_T("终末清场启动,清除 %d 格,并进入 10 秒狂热。"),
|
||||
clearedByTerminal);
|
||||
SetFeedbackMessage(_T("终末清场"), terminalDetail, 14);
|
||||
return true;
|
||||
}
|
||||
else if (currentMode == MODE_ROGUE && rogueStats.lastChanceCount > 0)
|
||||
|
||||
if (currentMode == MODE_ROGUE && rogueStats.lastChanceCount > 0)
|
||||
{
|
||||
rogueStats.lastChanceCount--;
|
||||
|
||||
@@ -469,13 +481,56 @@ void Fixing()
|
||||
_T("最后一搏"),
|
||||
_T("底部 3 行被清除,战局得以延续。"),
|
||||
14);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
gameOverFlag = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 生成下一枚活动方块,并刷新 Hold、特殊方块和预测落点状态。
|
||||
*/
|
||||
static void SpawnNextFallingPiece()
|
||||
{
|
||||
// 消耗预览队列后重置本回合状态,确保 Hold 和特殊标记只影响新方块。
|
||||
type = ConsumeNextType();
|
||||
nType = nextTypes[0];
|
||||
state = 0;
|
||||
holdUsedThisTurn = false;
|
||||
RollCurrentPieceSpecialFlags(true);
|
||||
point = GetSpawnPoint(type);
|
||||
target = point;
|
||||
ComputeTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将当前活动方块固定到工作区,并生成下一个活动方块。
|
||||
*
|
||||
* 遍历当前方块 4x4 形状矩阵,把其中所有非空单元写入工作区数组,
|
||||
* 表示该方块已经落地并转为固定状态。
|
||||
* 如果固定时仍有任意非空单元位于可视区域顶部之外,则判定游戏结束。
|
||||
* 此时当前方块在可视区域内的部分仍会保留在工作区中。
|
||||
* 若未超出顶部,再将“下一方块”切换为新的当前方块,重置旋转状态,
|
||||
* 并把新方块生成到工作区上方的初始位置,同时刷新预测落点。
|
||||
*/
|
||||
void Fixing()
|
||||
{
|
||||
bool overflowTop = false;
|
||||
Point fixedCells[4] = {};
|
||||
int fixedCellCount = 0;
|
||||
Point explosiveCells[4] = {};
|
||||
int explosiveCellCount = 0;
|
||||
pendingChainBombFollowup = false;
|
||||
|
||||
CollectAndWriteFixedCells(overflowTop, fixedCells, fixedCellCount, explosiveCells, explosiveCellCount);
|
||||
|
||||
ApplyRainbowLandingEffect(overflowTop, fixedCells, fixedCellCount);
|
||||
|
||||
if (!ResolveFixingOverflow(overflowTop))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ApplySpecialLandingEffects(fixedCells, fixedCellCount, explosiveCells, explosiveCellCount);
|
||||
|
||||
@@ -484,15 +539,7 @@ void Fixing()
|
||||
currentFallInterval = GetRogueFallInterval();
|
||||
}
|
||||
|
||||
// 生成下一个活动方块
|
||||
type = ConsumeNextType();
|
||||
nType = nextTypes[0];
|
||||
state = 0;
|
||||
holdUsedThisTurn = false;
|
||||
RollCurrentPieceSpecialFlags(true);
|
||||
point = GetSpawnPoint(type);
|
||||
target = point;
|
||||
ComputeTarget();
|
||||
SpawnNextFallingPiece();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -521,20 +568,15 @@ void DeleteOneLine(int number)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 检查并删除所有已满的行,同时更新当前得分。
|
||||
*
|
||||
* 该函数会从底部向上遍历工作区,判断每一行是否被完全填满。
|
||||
* 如果某一行全部非 0,则调用 DeleteOneLine 删除该行,
|
||||
* 并将该行上方的内容整体下移。为了避免连续满行被漏检,
|
||||
* 删除后会继续检查当前行号。每成功消除 1 行,当前得分增加 100 分。
|
||||
*
|
||||
* @return 本次实际消除的行数。
|
||||
* @brief 从底向上扫描满行并删除,记录本次消除的原始行号。
|
||||
* @param clearedRows 返回最多 8 个被消除行号,用于播放消行动画。
|
||||
* @param clearedRowCount 返回记录的行号数量。
|
||||
* @return 本次标准消行数量。
|
||||
*/
|
||||
int DeleteLines()
|
||||
static int ScanAndDeleteFullLines(int clearedRows[], int& clearedRowCount)
|
||||
{
|
||||
int clearedLines = 0;
|
||||
int clearedRows[8] = {};
|
||||
int clearedRowCount = 0;
|
||||
clearedRowCount = 0;
|
||||
|
||||
int playableHeight = GetRoguePlayableHeight();
|
||||
for (int i = playableHeight - 1; i >= 0; i--)
|
||||
@@ -564,8 +606,17 @@ int DeleteLines()
|
||||
}
|
||||
}
|
||||
|
||||
// 消行数量先进入玩法结算,再根据是否正在升级决定动画立即播放还是暂存。
|
||||
ApplyLineClearResult(clearedLines);
|
||||
return clearedLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据当前界面状态立即播放或暂存消行动画。
|
||||
* @param clearedRows 已消除行号数组。
|
||||
* @param clearedRowCount 行号数量。
|
||||
* @param clearedLines 本次消行数量。
|
||||
*/
|
||||
static void DispatchLineClearEffect(const int clearedRows[], int clearedRowCount, int clearedLines)
|
||||
{
|
||||
if (currentScreen == SCREEN_UPGRADE)
|
||||
{
|
||||
QueueLineClearEffect(clearedRows, clearedRowCount, clearedLines);
|
||||
@@ -574,10 +625,20 @@ int DeleteLines()
|
||||
{
|
||||
TriggerLineClearEffect(clearedRows, clearedRowCount, clearedLines);
|
||||
}
|
||||
}
|
||||
|
||||
// 连环炸弹的追加爆破只在爆破方块导致后续消行时触发一次。
|
||||
if (pendingChainBombFollowup && clearedLines > 0)
|
||||
/**
|
||||
* @brief 处理连环炸弹因消行触发的一次追加 3x3 爆破。
|
||||
* @param clearedLines 本次标准消行数量。
|
||||
*/
|
||||
static void ResolveChainBombFollowup(int clearedLines)
|
||||
{
|
||||
if (!pendingChainBombFollowup || clearedLines <= 0)
|
||||
{
|
||||
pendingChainBombFollowup = false;
|
||||
return;
|
||||
}
|
||||
|
||||
pendingChainBombFollowup = false;
|
||||
|
||||
int followupCleared = 0;
|
||||
@@ -618,11 +679,30 @@ int DeleteLines()
|
||||
followupExp);
|
||||
SetFeedbackMessage(_T("连环炸弹"), followupDetail, 12);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pendingChainBombFollowup = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 检查并删除所有已满的行,同时更新当前得分。
|
||||
*
|
||||
* 该函数会从底部向上遍历工作区,判断每一行是否被完全填满。
|
||||
* 如果某一行全部非 0,则调用 DeleteOneLine 删除该行,
|
||||
* 并将该行上方的内容整体下移。为了避免连续满行被漏检,
|
||||
* 删除后会继续检查当前行号。每成功消除 1 行,当前得分增加 100 分。
|
||||
*
|
||||
* @return 本次实际消除的行数。
|
||||
*/
|
||||
int DeleteLines()
|
||||
{
|
||||
int clearedRows[8] = {};
|
||||
int clearedRowCount = 0;
|
||||
int clearedLines = ScanAndDeleteFullLines(clearedRows, clearedRowCount);
|
||||
|
||||
// 消行数量先进入玩法结算,再根据是否正在升级决定动画立即播放还是暂存。
|
||||
ApplyLineClearResult(clearedLines);
|
||||
DispatchLineClearEffect(clearedRows, clearedRowCount, clearedLines);
|
||||
|
||||
// 连环炸弹的追加爆破只在爆破方块导致后续消行时触发一次。
|
||||
ResolveChainBombFollowup(clearedLines);
|
||||
|
||||
return clearedLines;
|
||||
}
|
||||
|
||||
+290
-163
@@ -417,6 +417,88 @@ static bool HandleMenuKey(HWND hWnd, WPARAM key)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 在帮助首页选项之间循环移动。
|
||||
* @param direction 负数向前,正数向后。
|
||||
*/
|
||||
static void MoveHelpHomeSelection(int direction)
|
||||
{
|
||||
helpState.selectedIndex += direction;
|
||||
if (helpState.selectedIndex < 0)
|
||||
{
|
||||
helpState.selectedIndex = helpState.optionCount - 1;
|
||||
}
|
||||
if (helpState.selectedIndex >= helpState.optionCount)
|
||||
{
|
||||
helpState.selectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 在技能演示列表中移动选中项,并同步滚动偏移。
|
||||
* @param direction 负数向上,正数向下。
|
||||
*/
|
||||
static void MoveSkillDemoSelection(int direction)
|
||||
{
|
||||
helpState.selectedIndex += direction;
|
||||
if (helpState.selectedIndex < 0)
|
||||
{
|
||||
helpState.selectedIndex = GetRogueSkillDemoCount() - 1;
|
||||
}
|
||||
if (helpState.selectedIndex >= GetRogueSkillDemoCount())
|
||||
{
|
||||
helpState.selectedIndex = 0;
|
||||
helpScrollOffset = 0;
|
||||
}
|
||||
else if (direction < 0 && helpState.selectedIndex * 68 < helpScrollOffset)
|
||||
{
|
||||
helpScrollOffset = helpState.selectedIndex * 68;
|
||||
}
|
||||
else if (direction > 0 && helpState.selectedIndex * 68 > helpScrollOffset + 360)
|
||||
{
|
||||
helpScrollOffset = helpState.selectedIndex * 68 - 360;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 打开帮助首页当前选中的子页面。
|
||||
*/
|
||||
static void ActivateHelpSelection()
|
||||
{
|
||||
if (helpState.selectedIndex == 3)
|
||||
{
|
||||
helpState.currentPage = 5;
|
||||
helpState.selectedIndex = 0;
|
||||
helpScrollOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
helpState.currentPage = helpState.selectedIndex + 1;
|
||||
helpScrollOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从帮助子页返回帮助首页或主菜单。
|
||||
*/
|
||||
static void LeaveRulesPage()
|
||||
{
|
||||
int previousPage = helpState.currentPage;
|
||||
if (helpState.currentPage == 0)
|
||||
{
|
||||
ReturnToMainMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
helpState.currentPage = 0;
|
||||
if (previousPage == 4 || previousPage == 5)
|
||||
{
|
||||
helpState.selectedIndex = 3;
|
||||
}
|
||||
helpScrollOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 处理帮助和致谢页键盘导航。
|
||||
* @param hWnd 当前窗口句柄。
|
||||
@@ -438,11 +520,7 @@ static bool HandleRulesKey(HWND hWnd, WPARAM key)
|
||||
case 'A':
|
||||
if (helpState.currentPage == 0)
|
||||
{
|
||||
helpState.selectedIndex--;
|
||||
if (helpState.selectedIndex < 0)
|
||||
{
|
||||
helpState.selectedIndex = helpState.optionCount - 1;
|
||||
}
|
||||
MoveHelpHomeSelection(-1);
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
}
|
||||
else if (helpState.currentPage == 4)
|
||||
@@ -452,15 +530,7 @@ static bool HandleRulesKey(HWND hWnd, WPARAM key)
|
||||
}
|
||||
else if (helpState.currentPage == 5)
|
||||
{
|
||||
helpState.selectedIndex--;
|
||||
if (helpState.selectedIndex < 0)
|
||||
{
|
||||
helpState.selectedIndex = GetRogueSkillDemoCount() - 1;
|
||||
}
|
||||
if (helpState.selectedIndex * 68 < helpScrollOffset)
|
||||
{
|
||||
helpScrollOffset = helpState.selectedIndex * 68;
|
||||
}
|
||||
MoveSkillDemoSelection(-1);
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
}
|
||||
break;
|
||||
@@ -470,11 +540,7 @@ static bool HandleRulesKey(HWND hWnd, WPARAM key)
|
||||
case 'D':
|
||||
if (helpState.currentPage == 0)
|
||||
{
|
||||
helpState.selectedIndex++;
|
||||
if (helpState.selectedIndex >= helpState.optionCount)
|
||||
{
|
||||
helpState.selectedIndex = 0;
|
||||
}
|
||||
MoveHelpHomeSelection(1);
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
}
|
||||
else if (helpState.currentPage == 4)
|
||||
@@ -484,16 +550,7 @@ static bool HandleRulesKey(HWND hWnd, WPARAM key)
|
||||
}
|
||||
else if (helpState.currentPage == 5)
|
||||
{
|
||||
helpState.selectedIndex++;
|
||||
if (helpState.selectedIndex >= GetRogueSkillDemoCount())
|
||||
{
|
||||
helpState.selectedIndex = 0;
|
||||
helpScrollOffset = 0;
|
||||
}
|
||||
else if (helpState.selectedIndex * 68 > helpScrollOffset + 360)
|
||||
{
|
||||
helpScrollOffset = helpState.selectedIndex * 68 - 360;
|
||||
}
|
||||
MoveSkillDemoSelection(1);
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
}
|
||||
break;
|
||||
@@ -501,17 +558,7 @@ static bool HandleRulesKey(HWND hWnd, WPARAM key)
|
||||
case VK_SPACE:
|
||||
if (helpState.currentPage == 0)
|
||||
{
|
||||
if (helpState.selectedIndex == 3)
|
||||
{
|
||||
helpState.currentPage = 5;
|
||||
helpState.selectedIndex = 0;
|
||||
helpScrollOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
helpState.currentPage = helpState.selectedIndex + 1;
|
||||
helpScrollOffset = 0;
|
||||
}
|
||||
ActivateHelpSelection();
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
}
|
||||
else if (helpState.currentPage == 5)
|
||||
@@ -524,24 +571,9 @@ static bool HandleRulesKey(HWND hWnd, WPARAM key)
|
||||
case VK_ESCAPE:
|
||||
case VK_BACK:
|
||||
case 'M':
|
||||
{
|
||||
int previousPage = helpState.currentPage;
|
||||
if (helpState.currentPage == 0)
|
||||
{
|
||||
ReturnToMainMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
helpState.currentPage = 0;
|
||||
if (previousPage == 4 || previousPage == 5)
|
||||
{
|
||||
helpState.selectedIndex = 3;
|
||||
}
|
||||
helpScrollOffset = 0;
|
||||
}
|
||||
LeaveRulesPage();
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -549,6 +581,92 @@ static bool HandleRulesKey(HWND hWnd, WPARAM key)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 计算升级卡片网格列数。
|
||||
* @return 当前升级界面使用的列数,至少为 1。
|
||||
*/
|
||||
static int GetUpgradeColumnCount()
|
||||
{
|
||||
int upgradeColumnCount = upgradeUiState.optionCount <= 3 ? upgradeUiState.optionCount : 3;
|
||||
if (upgradeColumnCount < 1)
|
||||
{
|
||||
upgradeColumnCount = 1;
|
||||
}
|
||||
return upgradeColumnCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 在升级卡片网格中横向移动选中项。
|
||||
* @param direction 负数向左,正数向右。
|
||||
*/
|
||||
static void MoveUpgradeSelectionHorizontal(int direction)
|
||||
{
|
||||
if (upgradeUiState.optionCount <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int upgradeColumnCount = GetUpgradeColumnCount();
|
||||
int rowStart = upgradeUiState.selectedIndex - (upgradeUiState.selectedIndex % upgradeColumnCount);
|
||||
int rowEnd = rowStart + upgradeColumnCount - 1;
|
||||
if (rowEnd >= upgradeUiState.optionCount)
|
||||
{
|
||||
rowEnd = upgradeUiState.optionCount - 1;
|
||||
}
|
||||
|
||||
if (direction < 0)
|
||||
{
|
||||
upgradeUiState.selectedIndex = (upgradeUiState.selectedIndex > rowStart) ? upgradeUiState.selectedIndex - 1 : rowEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
upgradeUiState.selectedIndex = (upgradeUiState.selectedIndex < rowEnd) ? upgradeUiState.selectedIndex + 1 : rowStart;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 在升级卡片网格中纵向移动选中项。
|
||||
* @param direction 负数向上,正数向下。
|
||||
*/
|
||||
static void MoveUpgradeSelectionVertical(int direction)
|
||||
{
|
||||
int upgradeColumnCount = GetUpgradeColumnCount();
|
||||
if (direction < 0 && upgradeUiState.selectedIndex >= upgradeColumnCount)
|
||||
{
|
||||
upgradeUiState.selectedIndex -= upgradeColumnCount;
|
||||
}
|
||||
else if (direction > 0 && upgradeUiState.selectedIndex + upgradeColumnCount < upgradeUiState.optionCount)
|
||||
{
|
||||
upgradeUiState.selectedIndex += upgradeColumnCount;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 切换多选升级中的当前卡片标记状态。
|
||||
*/
|
||||
static void ToggleUpgradeMarkedSelection()
|
||||
{
|
||||
if (upgradeUiState.picksRemaining <= 1 || upgradeUiState.optionCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 处理升级选择界面键盘导航。
|
||||
* @param hWnd 当前窗口句柄。
|
||||
@@ -562,64 +680,26 @@ static bool HandleUpgradeKey(HWND hWnd, WPARAM key)
|
||||
return false;
|
||||
}
|
||||
|
||||
int upgradeColumnCount = upgradeUiState.optionCount <= 3 ? upgradeUiState.optionCount : 3;
|
||||
if (upgradeColumnCount < 1)
|
||||
{
|
||||
upgradeColumnCount = 1;
|
||||
}
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case VK_LEFT:
|
||||
case 'A':
|
||||
if (upgradeUiState.optionCount > 1)
|
||||
{
|
||||
int rowStart = upgradeUiState.selectedIndex - (upgradeUiState.selectedIndex % upgradeColumnCount);
|
||||
if (upgradeUiState.selectedIndex > rowStart)
|
||||
{
|
||||
upgradeUiState.selectedIndex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
int rowEnd = rowStart + upgradeColumnCount - 1;
|
||||
if (rowEnd >= upgradeUiState.optionCount)
|
||||
{
|
||||
rowEnd = upgradeUiState.optionCount - 1;
|
||||
}
|
||||
upgradeUiState.selectedIndex = rowEnd;
|
||||
}
|
||||
}
|
||||
MoveUpgradeSelectionHorizontal(-1);
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
break;
|
||||
case VK_RIGHT:
|
||||
case 'D':
|
||||
if (upgradeUiState.optionCount > 1)
|
||||
{
|
||||
int rowStart = upgradeUiState.selectedIndex - (upgradeUiState.selectedIndex % upgradeColumnCount);
|
||||
int rowEnd = rowStart + upgradeColumnCount - 1;
|
||||
if (rowEnd >= upgradeUiState.optionCount)
|
||||
{
|
||||
rowEnd = upgradeUiState.optionCount - 1;
|
||||
}
|
||||
|
||||
upgradeUiState.selectedIndex = (upgradeUiState.selectedIndex < rowEnd) ? upgradeUiState.selectedIndex + 1 : rowStart;
|
||||
}
|
||||
MoveUpgradeSelectionHorizontal(1);
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
break;
|
||||
case VK_UP:
|
||||
case 'W':
|
||||
if (upgradeUiState.selectedIndex >= upgradeColumnCount)
|
||||
{
|
||||
upgradeUiState.selectedIndex -= upgradeColumnCount;
|
||||
}
|
||||
MoveUpgradeSelectionVertical(-1);
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
break;
|
||||
case VK_DOWN:
|
||||
case 'S':
|
||||
if (upgradeUiState.selectedIndex + upgradeColumnCount < upgradeUiState.optionCount)
|
||||
{
|
||||
upgradeUiState.selectedIndex += upgradeColumnCount;
|
||||
}
|
||||
MoveUpgradeSelectionVertical(1);
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
break;
|
||||
case VK_RETURN:
|
||||
@@ -630,20 +710,7 @@ static bool HandleUpgradeKey(HWND hWnd, WPARAM key)
|
||||
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++;
|
||||
}
|
||||
ToggleUpgradeMarkedSelection();
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
}
|
||||
else
|
||||
@@ -665,40 +732,54 @@ static bool HandleUpgradeKey(HWND hWnd, WPARAM key)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 处理游戏过程中的按键。
|
||||
* @brief 处理 Rogue 技能演示模式的专用按键。
|
||||
* @param hWnd 当前窗口句柄。
|
||||
* @param key 按键虚拟键码。
|
||||
* @return 已处理返回 true。
|
||||
*/
|
||||
static void HandlePlayingKey(HWND hWnd, WPARAM key)
|
||||
static bool HandleDemoPlayingKey(HWND hWnd, WPARAM key)
|
||||
{
|
||||
if (IsRogueSkillDemoMode())
|
||||
if (!IsRogueSkillDemoMode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (key == 'N')
|
||||
{
|
||||
AdvanceRogueSkillDemo();
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (key == 'R')
|
||||
{
|
||||
RestartCurrentRogueSkillDemo();
|
||||
ResetGameTimer(hWnd);
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (key == VK_ESCAPE || key == VK_BACK || key == 'M')
|
||||
{
|
||||
OpenSkillDemoScreen();
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 处理正常战局控制键,如菜单、重开、暂停、目标提示和复活。
|
||||
* @param hWnd 当前窗口句柄。
|
||||
* @param key 按键虚拟键码。
|
||||
* @return 已处理返回 true。
|
||||
*/
|
||||
static bool HandleBattleControlKey(HWND hWnd, WPARAM key)
|
||||
{
|
||||
if (!IsRogueSkillDemoMode() && key == 'M')
|
||||
{
|
||||
ReturnToMainMenu();
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!IsRogueSkillDemoMode() && key == 'R')
|
||||
@@ -706,21 +787,21 @@ static void HandlePlayingKey(HWND hWnd, WPARAM key)
|
||||
StartGameWithMode(currentMode);
|
||||
ResetGameTimer(hWnd);
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!IsRogueSkillDemoMode() && key == 'P')
|
||||
{
|
||||
suspendFlag = !suspendFlag;
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == 'G')
|
||||
{
|
||||
targetFlag = !targetFlag;
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gameOverFlag && reviveAvailable && key == 'V')
|
||||
@@ -735,23 +816,70 @@ static void HandlePlayingKey(HWND hWnd, WPARAM key)
|
||||
SetFeedbackMessage(_T("视频播放失败"), _T("无法打开复活视频,复活机会未消耗。"), 14);
|
||||
}
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gameOverFlag || suspendFlag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 处理 Rogue 侧栏滚动和主动技能按键。
|
||||
* @param hWnd 当前窗口句柄。
|
||||
* @param key 按键虚拟键码。
|
||||
* @return 已处理返回 true。
|
||||
*/
|
||||
static bool HandleRogueSkillKey(HWND hWnd, WPARAM key)
|
||||
{
|
||||
if (currentMode == MODE_ROGUE && (key == 'J' || key == 'K'))
|
||||
{
|
||||
int direction = (key == 'J') ? 1 : -1;
|
||||
AdjustScrollOffset(upgradeListScrollOffset, direction * GetScrollStep(hWnd, 52));
|
||||
InvalidateRect(hWnd, nullptr, FALSE);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 正常游玩按键先改变方块或触发技能,再统一刷新预测落点和界面。
|
||||
switch (key)
|
||||
{
|
||||
case 'C':
|
||||
case VK_SHIFT:
|
||||
case VK_LSHIFT:
|
||||
case VK_RSHIFT:
|
||||
HoldCurrentPiece();
|
||||
return true;
|
||||
case 'Z':
|
||||
UseBlackHole();
|
||||
return true;
|
||||
case 'X':
|
||||
UseScreenBomb();
|
||||
return true;
|
||||
case 'V':
|
||||
UseAirReshape();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 固定当前方块后执行消行和 Rogue 升级检查。
|
||||
*/
|
||||
static void FixPieceAndResolveLines()
|
||||
{
|
||||
Fixing();
|
||||
if (!gameOverFlag)
|
||||
{
|
||||
DeleteLines();
|
||||
CheckRogueLevelProgress();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 处理移动、旋转、软降和硬降等方块操作键。
|
||||
* @param key 按键虚拟键码。
|
||||
* @return 已处理返回 true。
|
||||
*/
|
||||
static bool HandlePieceMovementKey(WPARAM key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case VK_LEFT:
|
||||
@@ -760,14 +888,14 @@ static void HandlePlayingKey(HWND hWnd, WPARAM key)
|
||||
{
|
||||
MoveLeft();
|
||||
}
|
||||
break;
|
||||
return true;
|
||||
case VK_RIGHT:
|
||||
case 'D':
|
||||
if (CanMoveRight())
|
||||
{
|
||||
MoveRight();
|
||||
}
|
||||
break;
|
||||
return true;
|
||||
case VK_DOWN:
|
||||
case 'S':
|
||||
if (CanMoveDown())
|
||||
@@ -776,44 +904,43 @@ static void HandlePlayingKey(HWND hWnd, WPARAM key)
|
||||
}
|
||||
else
|
||||
{
|
||||
Fixing();
|
||||
if (!gameOverFlag)
|
||||
{
|
||||
DeleteLines();
|
||||
CheckRogueLevelProgress();
|
||||
FixPieceAndResolveLines();
|
||||
}
|
||||
}
|
||||
break;
|
||||
return true;
|
||||
case VK_UP:
|
||||
case 'W':
|
||||
Rotate();
|
||||
break;
|
||||
return true;
|
||||
case VK_SPACE:
|
||||
DropDown();
|
||||
Fixing();
|
||||
if (!gameOverFlag)
|
||||
{
|
||||
DeleteLines();
|
||||
CheckRogueLevelProgress();
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
case VK_SHIFT:
|
||||
case VK_LSHIFT:
|
||||
case VK_RSHIFT:
|
||||
HoldCurrentPiece();
|
||||
break;
|
||||
case 'Z':
|
||||
UseBlackHole();
|
||||
break;
|
||||
case 'X':
|
||||
UseScreenBomb();
|
||||
break;
|
||||
case 'V':
|
||||
UseAirReshape();
|
||||
break;
|
||||
FixPieceAndResolveLines();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 处理游戏过程中的按键。
|
||||
* @param hWnd 当前窗口句柄。
|
||||
* @param key 按键虚拟键码。
|
||||
*/
|
||||
static void HandlePlayingKey(HWND hWnd, WPARAM key)
|
||||
{
|
||||
if (HandleDemoPlayingKey(hWnd, key) || HandleBattleControlKey(hWnd, key))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (gameOverFlag || suspendFlag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 正常游玩按键先改变方块或触发技能,再统一刷新预测落点和界面。
|
||||
if (!HandlePieceMovementKey(key))
|
||||
{
|
||||
HandleRogueSkillKey(hWnd, key);
|
||||
}
|
||||
|
||||
if (!gameOverFlag)
|
||||
|
||||
+429
-305
@@ -1555,18 +1555,15 @@ static int TriggerUpgradeShockwave(int rowsToClear)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按权重和当前局势生成升级菜单中的候选强化。
|
||||
*
|
||||
* 该函数只负责生成 UI 选项,不应用强化效果。候选池会先过滤前置、
|
||||
* 等级上限和互斥条件,再按动态权重不放回抽取,保证同一轮不会重复出现。
|
||||
* @brief 收集当前可进入升级池的强化下标和动态权重。
|
||||
* @param selectableIndexes 返回候选在强化池中的下标。
|
||||
* @param selectableWeights 返回候选动态权重。
|
||||
* @return 候选数量。
|
||||
*/
|
||||
static void FillUpgradeOptions()
|
||||
static int CollectSelectableUpgrades(int selectableIndexes[], int selectableWeights[])
|
||||
{
|
||||
int selectableIndexes[kUpgradePoolSize] = { 0 };
|
||||
int selectableWeights[kUpgradePoolSize] = { 0 };
|
||||
int selectableCount = 0;
|
||||
|
||||
// 第一段:筛出当前真正可选的强化,并记录它们的动态权重。
|
||||
for (int i = 0; i < kUpgradePoolSize; i++)
|
||||
{
|
||||
if (IsUpgradeSelectable(kUpgradePool[i]))
|
||||
@@ -1577,7 +1574,16 @@ static void FillUpgradeOptions()
|
||||
}
|
||||
}
|
||||
|
||||
// 命运轮盘把候选扩到 6 个;双重抉择和命运轮盘都会允许本轮选 2 个。
|
||||
return selectableCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化本轮升级界面的数量、选中项和多选状态。
|
||||
* @param selectableCount 当前可选候选数量。
|
||||
* @return 本轮实际展示的选项数量。
|
||||
*/
|
||||
static int PrepareUpgradeOptionState(int selectableCount)
|
||||
{
|
||||
int optionLimit = (rogueStats.destinyWheelLevel > 0) ? 6 : 3;
|
||||
int optionCount = selectableCount < optionLimit ? selectableCount : optionLimit;
|
||||
upgradeUiState.optionCount = optionCount;
|
||||
@@ -1589,9 +1595,17 @@ static void FillUpgradeOptions()
|
||||
upgradeUiState.marked[i] = false;
|
||||
}
|
||||
|
||||
// 第二段:按权重不放回抽取候选,抽中后用末尾元素覆盖当前槽位。
|
||||
for (int i = 0; i < optionCount; i++)
|
||||
{
|
||||
return optionCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按权重从候选数组中抽取一个槽位。
|
||||
* @param selectableWeights 候选权重数组。
|
||||
* @param selectableCount 候选数量。
|
||||
* @return 被抽中的候选槽位。
|
||||
*/
|
||||
static int PickUpgradeSlotByWeight(const int selectableWeights[], int selectableCount)
|
||||
{
|
||||
int totalWeight = 0;
|
||||
for (int weightIndex = 0; weightIndex < selectableCount; weightIndex++)
|
||||
{
|
||||
@@ -1615,45 +1629,80 @@ static void FillUpgradeOptions()
|
||||
}
|
||||
}
|
||||
|
||||
int pickedIndex = selectableIndexes[pickSlot];
|
||||
const UpgradeEntry& pickedEntry = kUpgradePool[pickedIndex];
|
||||
return pickSlot;
|
||||
}
|
||||
|
||||
upgradeUiState.options[i].id = pickedEntry.id;
|
||||
upgradeUiState.options[i].currentLevel = GetUpgradeCurrentLevel(pickedEntry.id);
|
||||
upgradeUiState.options[i].targetPieceType = -1;
|
||||
upgradeUiState.options[i].rarity = GetUpgradeBaseRarity(pickedEntry.id);
|
||||
upgradeUiState.options[i].cursed = false;
|
||||
upgradeUiState.options[i].name = pickedEntry.name;
|
||||
upgradeUiState.options[i].category = pickedEntry.category;
|
||||
upgradeUiState.options[i].description = pickedEntry.description;
|
||||
/**
|
||||
* @brief 将抽中的强化池条目写入升级 UI 选项。
|
||||
* @param optionIndex UI 选项下标。
|
||||
* @param pickedEntry 被抽中的强化池条目。
|
||||
*/
|
||||
static void FillUpgradeOptionFromEntry(int optionIndex, const UpgradeEntry& pickedEntry)
|
||||
{
|
||||
upgradeUiState.options[optionIndex].id = pickedEntry.id;
|
||||
upgradeUiState.options[optionIndex].currentLevel = GetUpgradeCurrentLevel(pickedEntry.id);
|
||||
upgradeUiState.options[optionIndex].targetPieceType = -1;
|
||||
upgradeUiState.options[optionIndex].rarity = GetUpgradeBaseRarity(pickedEntry.id);
|
||||
upgradeUiState.options[optionIndex].cursed = false;
|
||||
upgradeUiState.options[optionIndex].name = pickedEntry.name;
|
||||
upgradeUiState.options[optionIndex].category = pickedEntry.category;
|
||||
upgradeUiState.options[optionIndex].description = pickedEntry.description;
|
||||
|
||||
// 方块改造目前固定展示 I 块概率提升,说明文字需要运行时拼接。
|
||||
if (pickedEntry.id == UPGRADE_PIECE_TUNING)
|
||||
{
|
||||
int targetPieceType = 0;
|
||||
upgradeUiState.options[i].targetPieceType = targetPieceType;
|
||||
upgradeUiState.options[i].currentLevel = rogueStats.pieceTuningLevels[0];
|
||||
upgradeUiState.options[i].name = _T("方块改造");
|
||||
upgradeUiState.options[optionIndex].targetPieceType = targetPieceType;
|
||||
upgradeUiState.options[optionIndex].currentLevel = rogueStats.pieceTuningLevels[0];
|
||||
upgradeUiState.options[optionIndex].name = _T("方块改造");
|
||||
|
||||
static TCHAR tuningDescriptions[6][64];
|
||||
_stprintf_s(
|
||||
tuningDescriptions[i],
|
||||
tuningDescriptions[optionIndex],
|
||||
_T("%s 块的生成概率提高。"),
|
||||
GetPieceShortName(0));
|
||||
upgradeUiState.options[i].description = tuningDescriptions[i];
|
||||
upgradeUiState.options[optionIndex].description = tuningDescriptions[optionIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 命运轮盘生效时,为本轮候选随机附加一个诅咒标记。
|
||||
* @param optionCount 本轮展示选项数量。
|
||||
*/
|
||||
static void MarkDestinyCursedOption(int optionCount)
|
||||
{
|
||||
if (rogueStats.destinyWheelLevel > 0 && optionCount > 0)
|
||||
{
|
||||
int cursedIndex = rand() % optionCount;
|
||||
upgradeUiState.options[cursedIndex].cursed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按权重和当前局势生成升级菜单中的候选强化。
|
||||
*
|
||||
* 该函数只负责生成 UI 选项,不应用强化效果。候选池会先过滤前置、
|
||||
* 等级上限和互斥条件,再按动态权重不放回抽取,保证同一轮不会重复出现。
|
||||
*/
|
||||
static void FillUpgradeOptions()
|
||||
{
|
||||
int selectableIndexes[kUpgradePoolSize] = { 0 };
|
||||
int selectableWeights[kUpgradePoolSize] = { 0 };
|
||||
int selectableCount = CollectSelectableUpgrades(selectableIndexes, selectableWeights);
|
||||
int optionCount = PrepareUpgradeOptionState(selectableCount);
|
||||
|
||||
// 第二段:按权重不放回抽取候选,抽中后用末尾元素覆盖当前槽位。
|
||||
for (int i = 0; i < optionCount; i++)
|
||||
{
|
||||
int pickSlot = PickUpgradeSlotByWeight(selectableWeights, selectableCount);
|
||||
int pickedIndex = selectableIndexes[pickSlot];
|
||||
FillUpgradeOptionFromEntry(i, kUpgradePool[pickedIndex]);
|
||||
|
||||
selectableIndexes[pickSlot] = selectableIndexes[selectableCount - 1];
|
||||
selectableWeights[pickSlot] = selectableWeights[selectableCount - 1];
|
||||
selectableCount--;
|
||||
}
|
||||
|
||||
// 命运轮盘在候选中随机附加一个诅咒,确认时才提高下一次升级需求。
|
||||
if (rogueStats.destinyWheelLevel > 0 && optionCount > 0)
|
||||
{
|
||||
int cursedIndex = rand() % optionCount;
|
||||
upgradeUiState.options[cursedIndex].cursed = true;
|
||||
}
|
||||
MarkDestinyCursedOption(optionCount);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1708,6 +1757,241 @@ int GetRogueFallInterval()
|
||||
return baseInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 应用成长、保命和基础操作类强化。
|
||||
* @param upgradeId 强化编号。
|
||||
* @param applyCount 本次应用次数。
|
||||
* @return 当前强化已处理返回 true。
|
||||
*/
|
||||
static bool ApplyGrowthOrOperationUpgrade(int upgradeId, int applyCount)
|
||||
{
|
||||
switch (upgradeId)
|
||||
{
|
||||
case UPGRADE_SCORE_MULTIPLIER:
|
||||
rogueStats.scoreMultiplierPercent += 20 * applyCount;
|
||||
rogueStats.scoreUpgradeLevel += applyCount;
|
||||
return true;
|
||||
case UPGRADE_COMBO_BONUS:
|
||||
rogueStats.comboBonusStacks += applyCount;
|
||||
return true;
|
||||
case UPGRADE_EXP_MULTIPLIER:
|
||||
rogueStats.expMultiplierPercent += 25 * applyCount;
|
||||
rogueStats.expUpgradeLevel += applyCount;
|
||||
return true;
|
||||
case UPGRADE_SLOW_FALL:
|
||||
rogueStats.slowFallStacks += applyCount;
|
||||
if (rogueStats.slowFallStacks > 4)
|
||||
{
|
||||
rogueStats.slowFallStacks = 4;
|
||||
}
|
||||
currentFallInterval = GetRogueFallInterval();
|
||||
return true;
|
||||
case UPGRADE_PREVIEW_PLUS_ONE:
|
||||
if (rogueStats.previewCount < 2)
|
||||
{
|
||||
rogueStats.previewCount = 2;
|
||||
}
|
||||
rogueStats.previewUpgradeLevel = rogueStats.previewCount - 1;
|
||||
return true;
|
||||
case UPGRADE_LAST_CHANCE:
|
||||
rogueStats.lastChanceCount += applyCount;
|
||||
rogueStats.lastChanceUpgradeLevel += applyCount;
|
||||
return true;
|
||||
case UPGRADE_HOLD_UNLOCK:
|
||||
rogueStats.holdUnlocked = 1;
|
||||
holdUsedThisTurn = false;
|
||||
return true;
|
||||
case UPGRADE_PERFECT_ROTATE:
|
||||
rogueStats.perfectRotateLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_TIME_DILATION:
|
||||
rogueStats.timeDilationLevel = 1;
|
||||
currentFallInterval = GetRogueFallInterval();
|
||||
return true;
|
||||
case UPGRADE_CONTROL_MASTER:
|
||||
rogueStats.controlMasterLevel = 1;
|
||||
if (rogueStats.previewCount < 3)
|
||||
{
|
||||
rogueStats.previewCount++;
|
||||
}
|
||||
rogueStats.previewUpgradeLevel = rogueStats.previewCount - 1;
|
||||
return true;
|
||||
case UPGRADE_DOUBLE_GROWTH:
|
||||
rogueStats.doubleGrowthLevel = 1;
|
||||
rogueStats.scoreMultiplierPercent += 15;
|
||||
rogueStats.expMultiplierPercent += 15;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 应用特殊方块和落地派生类强化。
|
||||
* @param upgradeId 强化编号。
|
||||
* @param applyCount 本次应用次数。
|
||||
* @return 当前强化已处理返回 true。
|
||||
*/
|
||||
static bool ApplySpecialPieceUpgrade(int upgradeId, int applyCount)
|
||||
{
|
||||
switch (upgradeId)
|
||||
{
|
||||
case UPGRADE_PRESSURE_RELIEF:
|
||||
rogueStats.pressureReliefLevel += applyCount;
|
||||
for (int i = 0; i < applyCount; i++)
|
||||
{
|
||||
int topOccupiedRow = GetTopOccupiedRow();
|
||||
if (topOccupiedRow >= 0)
|
||||
{
|
||||
DeleteOneLine(topOccupiedRow);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case UPGRADE_SWEEPER:
|
||||
rogueStats.sweeperLevel += applyCount;
|
||||
if (rogueStats.sweeperLevel > 4)
|
||||
{
|
||||
rogueStats.sweeperLevel = 4;
|
||||
}
|
||||
return true;
|
||||
case UPGRADE_EXPLOSIVE_PIECE:
|
||||
rogueStats.explosiveLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_CHAIN_BLAST:
|
||||
rogueStats.chainBlastLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_CHAIN_BOMB:
|
||||
rogueStats.chainBombLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_LASER_PIECE:
|
||||
rogueStats.laserLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_THUNDER_TETRIS:
|
||||
rogueStats.thunderTetrisLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_THUNDER_LASER:
|
||||
rogueStats.thunderLaserLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_CROSS_PIECE:
|
||||
rogueStats.crossPieceLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_RAINBOW_PIECE:
|
||||
rogueStats.rainbowPieceLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_STABLE_STRUCTURE:
|
||||
rogueStats.stableStructureLevel += applyCount;
|
||||
return true;
|
||||
case UPGRADE_PIECE_TUNING:
|
||||
rogueStats.pieceTuningLevels[0] += applyCount;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 应用主动技能、爆发和资源次数类强化。
|
||||
* @param upgradeId 强化编号。
|
||||
* @param applyCount 本次应用次数。
|
||||
* @return 当前强化已处理返回 true。
|
||||
*/
|
||||
static bool ApplyActiveSkillUpgrade(int upgradeId, int applyCount)
|
||||
{
|
||||
switch (upgradeId)
|
||||
{
|
||||
case UPGRADE_FEVER_MODE:
|
||||
rogueStats.feverLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_RAGE_STACK:
|
||||
rogueStats.rageStackLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_INFINITE_FEVER:
|
||||
rogueStats.infiniteFeverLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_SCREEN_BOMB:
|
||||
rogueStats.screenBombLevel += applyCount;
|
||||
rogueStats.screenBombCount += applyCount;
|
||||
return true;
|
||||
case UPGRADE_TERMINAL_CLEAR:
|
||||
rogueStats.terminalClearLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_BLOCK_STORM:
|
||||
rogueStats.blockStormLevel = 1;
|
||||
rogueStats.blockStormPiecesRemaining = 5;
|
||||
nextTypes[0] = 0;
|
||||
nextTypes[1] = 0;
|
||||
nextTypes[2] = 0;
|
||||
return true;
|
||||
case UPGRADE_BLACK_HOLE:
|
||||
rogueStats.blackHoleLevel = 1;
|
||||
rogueStats.blackHoleCharges += 2 * applyCount;
|
||||
return true;
|
||||
case UPGRADE_AIR_RESHAPE:
|
||||
rogueStats.reshapeLevel += applyCount;
|
||||
rogueStats.reshapeCharges += 2 * applyCount;
|
||||
return true;
|
||||
case UPGRADE_VOID_CORE:
|
||||
rogueStats.voidCoreLevel = 1;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 应用风险、升级规则和进化类强化。
|
||||
* @param upgradeId 强化编号。
|
||||
* @param applyCount 本次应用次数。
|
||||
* @return 当前强化已处理返回 true。
|
||||
*/
|
||||
static bool ApplyRiskOrEvolutionUpgrade(int upgradeId, int applyCount)
|
||||
{
|
||||
switch (upgradeId)
|
||||
{
|
||||
case UPGRADE_DUAL_CHOICE:
|
||||
rogueStats.dualChoiceLevel = 1;
|
||||
rogueStats.requiredExp = rogueStats.requiredExp * 130 / 100;
|
||||
if (rogueStats.requiredExp < 10)
|
||||
{
|
||||
rogueStats.requiredExp = 10;
|
||||
}
|
||||
return true;
|
||||
case UPGRADE_DESTINY_WHEEL:
|
||||
rogueStats.destinyWheelLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_HIGH_PRESSURE:
|
||||
rogueStats.highPressureLevel = 1;
|
||||
rogueStats.scoreMultiplierPercent += 50;
|
||||
rogueStats.expMultiplierPercent += 50;
|
||||
currentFallInterval = GetRogueFallInterval();
|
||||
return true;
|
||||
case UPGRADE_TETRIS_GAMBLE:
|
||||
rogueStats.tetrisGambleLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_EXTREME_PLAYER:
|
||||
rogueStats.extremePlayerLevel = 1;
|
||||
rogueStats.extremeDangerTicks = 30;
|
||||
rogueStats.extremeDangerLevel = 0;
|
||||
currentFallInterval = GetRogueFallInterval();
|
||||
return true;
|
||||
case UPGRADE_UPGRADE_SHOCKWAVE:
|
||||
rogueStats.upgradeShockwaveLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_EVOLUTION_IMPACT:
|
||||
rogueStats.evolutionImpactLevel = 1;
|
||||
return true;
|
||||
case UPGRADE_GAMBLER:
|
||||
rogueStats.gamblerLevel += applyCount;
|
||||
if (rogueStats.gamblerLevel > 4)
|
||||
{
|
||||
rogueStats.gamblerLevel = 4;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据强化编号把对应效果写入 Rogue 属性。
|
||||
*
|
||||
@@ -1727,191 +2011,10 @@ static void ApplyUpgradeById(int upgradeId, int targetPieceType, int applyCount)
|
||||
return;
|
||||
}
|
||||
|
||||
// 基础成长类强化直接叠加倍率或层数。
|
||||
switch (upgradeId)
|
||||
{
|
||||
case UPGRADE_SCORE_MULTIPLIER:
|
||||
rogueStats.scoreMultiplierPercent += 20 * applyCount;
|
||||
rogueStats.scoreUpgradeLevel += applyCount;
|
||||
break;
|
||||
case UPGRADE_COMBO_BONUS:
|
||||
rogueStats.comboBonusStacks += applyCount;
|
||||
break;
|
||||
case UPGRADE_EXP_MULTIPLIER:
|
||||
rogueStats.expMultiplierPercent += 25 * applyCount;
|
||||
rogueStats.expUpgradeLevel += applyCount;
|
||||
break;
|
||||
case UPGRADE_SLOW_FALL:
|
||||
rogueStats.slowFallStacks += applyCount;
|
||||
if (rogueStats.slowFallStacks > 4)
|
||||
{
|
||||
rogueStats.slowFallStacks = 4;
|
||||
}
|
||||
currentFallInterval = GetRogueFallInterval();
|
||||
break;
|
||||
case UPGRADE_PREVIEW_PLUS_ONE:
|
||||
if (rogueStats.previewCount < 2)
|
||||
{
|
||||
rogueStats.previewCount = 2;
|
||||
}
|
||||
rogueStats.previewUpgradeLevel = rogueStats.previewCount - 1;
|
||||
break;
|
||||
case UPGRADE_LAST_CHANCE:
|
||||
rogueStats.lastChanceCount += applyCount;
|
||||
rogueStats.lastChanceUpgradeLevel += applyCount;
|
||||
break;
|
||||
case UPGRADE_HOLD_UNLOCK:
|
||||
rogueStats.holdUnlocked = 1;
|
||||
holdUsedThisTurn = false;
|
||||
break;
|
||||
case UPGRADE_PRESSURE_RELIEF:
|
||||
{
|
||||
// 卸压清场立即从最高占用行开始删除,直接改善当前局面。
|
||||
rogueStats.pressureReliefLevel += applyCount;
|
||||
for (int i = 0; i < applyCount; i++)
|
||||
{
|
||||
int topOccupiedRow = GetTopOccupiedRow();
|
||||
if (topOccupiedRow >= 0)
|
||||
{
|
||||
DeleteOneLine(topOccupiedRow);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UPGRADE_SWEEPER:
|
||||
rogueStats.sweeperLevel += applyCount;
|
||||
if (rogueStats.sweeperLevel > 4)
|
||||
{
|
||||
rogueStats.sweeperLevel = 4;
|
||||
}
|
||||
break;
|
||||
case UPGRADE_EXPLOSIVE_PIECE:
|
||||
rogueStats.explosiveLevel = 1;
|
||||
break;
|
||||
case UPGRADE_CHAIN_BLAST:
|
||||
rogueStats.chainBlastLevel = 1;
|
||||
break;
|
||||
case UPGRADE_CHAIN_BOMB:
|
||||
rogueStats.chainBombLevel = 1;
|
||||
break;
|
||||
case UPGRADE_LASER_PIECE:
|
||||
rogueStats.laserLevel = 1;
|
||||
break;
|
||||
case UPGRADE_THUNDER_TETRIS:
|
||||
rogueStats.thunderTetrisLevel = 1;
|
||||
break;
|
||||
case UPGRADE_THUNDER_LASER:
|
||||
rogueStats.thunderLaserLevel = 1;
|
||||
break;
|
||||
case UPGRADE_FEVER_MODE:
|
||||
rogueStats.feverLevel = 1;
|
||||
break;
|
||||
case UPGRADE_RAGE_STACK:
|
||||
rogueStats.rageStackLevel = 1;
|
||||
break;
|
||||
case UPGRADE_INFINITE_FEVER:
|
||||
rogueStats.infiniteFeverLevel = 1;
|
||||
break;
|
||||
case UPGRADE_SCREEN_BOMB:
|
||||
rogueStats.screenBombLevel += applyCount;
|
||||
rogueStats.screenBombCount += applyCount;
|
||||
break;
|
||||
case UPGRADE_TERMINAL_CLEAR:
|
||||
rogueStats.terminalClearLevel = 1;
|
||||
break;
|
||||
case UPGRADE_DUAL_CHOICE:
|
||||
rogueStats.dualChoiceLevel = 1;
|
||||
rogueStats.requiredExp = rogueStats.requiredExp * 130 / 100;
|
||||
if (rogueStats.requiredExp < 10)
|
||||
{
|
||||
rogueStats.requiredExp = 10;
|
||||
}
|
||||
break;
|
||||
case UPGRADE_DESTINY_WHEEL:
|
||||
rogueStats.destinyWheelLevel = 1;
|
||||
break;
|
||||
case UPGRADE_PERFECT_ROTATE:
|
||||
rogueStats.perfectRotateLevel = 1;
|
||||
break;
|
||||
case UPGRADE_TIME_DILATION:
|
||||
rogueStats.timeDilationLevel = 1;
|
||||
currentFallInterval = GetRogueFallInterval();
|
||||
break;
|
||||
case UPGRADE_HIGH_PRESSURE:
|
||||
rogueStats.highPressureLevel = 1;
|
||||
rogueStats.scoreMultiplierPercent += 50;
|
||||
rogueStats.expMultiplierPercent += 50;
|
||||
currentFallInterval = GetRogueFallInterval();
|
||||
break;
|
||||
case UPGRADE_TETRIS_GAMBLE:
|
||||
rogueStats.tetrisGambleLevel = 1;
|
||||
break;
|
||||
case UPGRADE_EXTREME_PLAYER:
|
||||
rogueStats.extremePlayerLevel = 1;
|
||||
rogueStats.extremeDangerTicks = 30;
|
||||
rogueStats.extremeDangerLevel = 0;
|
||||
currentFallInterval = GetRogueFallInterval();
|
||||
break;
|
||||
case UPGRADE_UPGRADE_SHOCKWAVE:
|
||||
rogueStats.upgradeShockwaveLevel = 1;
|
||||
break;
|
||||
case UPGRADE_EVOLUTION_IMPACT:
|
||||
rogueStats.evolutionImpactLevel = 1;
|
||||
break;
|
||||
case UPGRADE_CONTROL_MASTER:
|
||||
rogueStats.controlMasterLevel = 1;
|
||||
if (rogueStats.previewCount < 3)
|
||||
{
|
||||
rogueStats.previewCount++;
|
||||
}
|
||||
rogueStats.previewUpgradeLevel = rogueStats.previewCount - 1;
|
||||
break;
|
||||
case UPGRADE_BLOCK_STORM:
|
||||
// 方块风暴会同时改写预览队列,确保玩家马上看到连续 I 块。
|
||||
rogueStats.blockStormLevel = 1;
|
||||
rogueStats.blockStormPiecesRemaining = 5;
|
||||
nextTypes[0] = 0;
|
||||
nextTypes[1] = 0;
|
||||
nextTypes[2] = 0;
|
||||
break;
|
||||
case UPGRADE_CROSS_PIECE:
|
||||
rogueStats.crossPieceLevel = 1;
|
||||
break;
|
||||
case UPGRADE_BLACK_HOLE:
|
||||
rogueStats.blackHoleLevel = 1;
|
||||
rogueStats.blackHoleCharges += 2 * applyCount;
|
||||
break;
|
||||
case UPGRADE_AIR_RESHAPE:
|
||||
rogueStats.reshapeLevel += applyCount;
|
||||
rogueStats.reshapeCharges += 2 * applyCount;
|
||||
break;
|
||||
case UPGRADE_RAINBOW_PIECE:
|
||||
rogueStats.rainbowPieceLevel = 1;
|
||||
break;
|
||||
case UPGRADE_VOID_CORE:
|
||||
rogueStats.voidCoreLevel = 1;
|
||||
break;
|
||||
case UPGRADE_STABLE_STRUCTURE:
|
||||
rogueStats.stableStructureLevel += applyCount;
|
||||
break;
|
||||
case UPGRADE_DOUBLE_GROWTH:
|
||||
rogueStats.doubleGrowthLevel = 1;
|
||||
rogueStats.scoreMultiplierPercent += 15;
|
||||
rogueStats.expMultiplierPercent += 15;
|
||||
break;
|
||||
case UPGRADE_PIECE_TUNING:
|
||||
rogueStats.pieceTuningLevels[0] += applyCount;
|
||||
break;
|
||||
case UPGRADE_GAMBLER:
|
||||
rogueStats.gamblerLevel += applyCount;
|
||||
if (rogueStats.gamblerLevel > 4)
|
||||
{
|
||||
rogueStats.gamblerLevel = 4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ApplyGrowthOrOperationUpgrade(upgradeId, applyCount) ||
|
||||
ApplySpecialPieceUpgrade(upgradeId, applyCount) ||
|
||||
ApplyActiveSkillUpgrade(upgradeId, applyCount) ||
|
||||
ApplyRiskOrEvolutionUpgrade(upgradeId, applyCount);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2473,6 +2576,109 @@ void OpenUpgradeMenu()
|
||||
currentScreen = SCREEN_UPGRADE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 结束一轮升级选择,如果还有待处理升级则刷新下一轮选项。
|
||||
* @return 仍停留在升级界面返回 true;已回到游戏返回 false。
|
||||
*/
|
||||
static bool FinishUpgradeSelectionRound()
|
||||
{
|
||||
if (upgradeUiState.pendingCount > 0)
|
||||
{
|
||||
upgradeUiState.pendingCount--;
|
||||
}
|
||||
|
||||
if (upgradeUiState.pendingCount > 0)
|
||||
{
|
||||
FillUpgradeOptions();
|
||||
currentScreen = SCREEN_UPGRADE;
|
||||
return true;
|
||||
}
|
||||
|
||||
upgradeUiState.optionCount = 0;
|
||||
upgradeUiState.picksRemaining = 0;
|
||||
upgradeUiState.markedCount = 0;
|
||||
|
||||
currentScreen = SCREEN_PLAYING;
|
||||
ResolvePendingUpgradeShockwave();
|
||||
PlayPendingLineClearEffect();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 构造单选强化的反馈正文。
|
||||
* @param selectedOption 被选择的强化选项。
|
||||
* @param gamblerSuffix 赌徒契约附加说明。
|
||||
* @param feedbackDetail 返回反馈正文。
|
||||
* @param feedbackDetailCapacity 反馈正文缓冲区长度。
|
||||
*/
|
||||
static void BuildSingleUpgradeFeedback(const UpgradeOption& selectedOption, const TCHAR* gamblerSuffix, TCHAR feedbackDetail[], int feedbackDetailCapacity)
|
||||
{
|
||||
if (selectedOption.id == UPGRADE_PIECE_TUNING && selectedOption.targetPieceType >= 0)
|
||||
{
|
||||
_stprintf_s(
|
||||
feedbackDetail,
|
||||
feedbackDetailCapacity,
|
||||
_T("%s 块的生成概率提高%s"),
|
||||
GetPieceShortName(0),
|
||||
gamblerSuffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
_stprintf_s(feedbackDetail, feedbackDetailCapacity, _T("%s%s"), selectedOption.description, gamblerSuffix);
|
||||
}
|
||||
|
||||
if (selectedOption.cursed)
|
||||
{
|
||||
_stprintf_s(
|
||||
feedbackDetail + lstrlen(feedbackDetail),
|
||||
feedbackDetailCapacity - lstrlen(feedbackDetail),
|
||||
_T(" 诅咒缠身:下一次升级所需 EXP 提高 25%。"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 应用多选升级中一个已标记的选项并拼接反馈。
|
||||
* @param selectedOption 被应用的选项。
|
||||
* @param appliedSelections 已应用选项数量。
|
||||
* @param feedbackTitle 返回反馈标题。
|
||||
* @param feedbackDetail 返回反馈正文。
|
||||
*/
|
||||
static void ApplyMarkedUpgradeOption(const UpgradeOption& selectedOption, int& appliedSelections, TCHAR feedbackTitle[], TCHAR feedbackDetail[])
|
||||
{
|
||||
TCHAR gamblerSuffix[64] = _T("");
|
||||
int applyCount = RollGamblerApplyCount(gamblerSuffix, 64, true);
|
||||
|
||||
ApplyUpgradeById(selectedOption.id, selectedOption.targetPieceType, applyCount);
|
||||
upgradeUiState.totalChosenCount++;
|
||||
|
||||
if (selectedOption.cursed)
|
||||
{
|
||||
ApplyDestinyCurse();
|
||||
}
|
||||
|
||||
if (appliedSelections == 0)
|
||||
{
|
||||
_stprintf_s(feedbackTitle, 64, _T("获得强化:%s"), selectedOption.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
_stprintf_s(feedbackTitle, 64, _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++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 确认升级菜单中的选择并应用对应强化效果。
|
||||
*
|
||||
@@ -2507,59 +2713,11 @@ void ConfirmUpgradeSelection()
|
||||
}
|
||||
|
||||
UpgradeOption selectedOption = upgradeUiState.options[optionIndex];
|
||||
TCHAR gamblerSuffix[64] = _T("");
|
||||
int applyCount = RollGamblerApplyCount(gamblerSuffix, 64, true);
|
||||
|
||||
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++;
|
||||
ApplyMarkedUpgradeOption(selectedOption, appliedSelections, feedbackTitle, feedbackDetail);
|
||||
}
|
||||
|
||||
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();
|
||||
FinishUpgradeSelectionRound();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2573,26 +2731,11 @@ void ConfirmUpgradeSelection()
|
||||
TCHAR feedbackTitle[64];
|
||||
TCHAR feedbackDetail[128];
|
||||
_stprintf_s(feedbackTitle, _T("获得强化:%s"), selectedOption.name);
|
||||
if (selectedOption.id == UPGRADE_PIECE_TUNING && selectedOption.targetPieceType >= 0)
|
||||
{
|
||||
_stprintf_s(
|
||||
feedbackDetail,
|
||||
_T("%s 块的生成概率提高%s"),
|
||||
GetPieceShortName(0),
|
||||
gamblerSuffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
_stprintf_s(feedbackDetail, _T("%s%s"), selectedOption.description, gamblerSuffix);
|
||||
}
|
||||
BuildSingleUpgradeFeedback(selectedOption, gamblerSuffix, feedbackDetail, 128);
|
||||
|
||||
if (selectedOption.cursed)
|
||||
{
|
||||
ApplyDestinyCurse();
|
||||
_stprintf_s(
|
||||
feedbackDetail + lstrlen(feedbackDetail),
|
||||
128 - lstrlen(feedbackDetail),
|
||||
_T(" 诅咒缠身:下一次升级所需 EXP 提高 25%。"));
|
||||
}
|
||||
|
||||
SetFeedbackMessage(feedbackTitle, feedbackDetail, 12);
|
||||
@@ -2622,26 +2765,7 @@ void ConfirmUpgradeSelection()
|
||||
return;
|
||||
}
|
||||
|
||||
// 连续升级时重新生成下一轮强化;全部完成后回到游戏并播放延迟效果。
|
||||
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();
|
||||
FinishUpgradeSelectionRound();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user