补充彩虹方块与虚空核心强化链
This commit is contained in:
+215
-7
@@ -25,6 +25,7 @@ bool holdUsedThisTurn = false;
|
||||
bool currentPieceIsExplosive = false;
|
||||
bool currentPieceIsLaser = false;
|
||||
bool currentPieceIsCross = false;
|
||||
bool currentPieceIsRainbow = false;
|
||||
Point pendingChainBombCenter = { 0, 0 };
|
||||
bool pendingChainBombFollowup = false;
|
||||
|
||||
@@ -67,7 +68,9 @@ enum UpgradeId
|
||||
UPGRADE_BLOCK_STORM = 34,
|
||||
UPGRADE_CROSS_PIECE = 35,
|
||||
UPGRADE_BLACK_HOLE = 36,
|
||||
UPGRADE_AIR_RESHAPE = 37
|
||||
UPGRADE_AIR_RESHAPE = 37,
|
||||
UPGRADE_RAINBOW_PIECE = 38,
|
||||
UPGRADE_VOID_CORE = 39
|
||||
};
|
||||
|
||||
static const UpgradeEntry kUpgradePool[] =
|
||||
@@ -106,6 +109,8 @@ static const UpgradeEntry kUpgradePool[] =
|
||||
{ UPGRADE_CROSS_PIECE, -1, 76, true, _T("\u5341\u5b57\u65b9\u5757"), _T("\u723d\u611f"), _T("\u63d0\u9ad8\u5341\u5b57\u65b9\u5757\u51fa\u73b0\u6982\u7387\uff0c\u843d\u5730\u540e\u6e05\u9664\u6240\u5728\u884c\u4e0e\u6240\u5728\u5217\u3002") },
|
||||
{ UPGRADE_BLACK_HOLE, 1, 78, false, _T("\u9ed1\u6d1e"), _T("\u7279\u6b8a"), _T("\u83b7\u5f97 1 \u6b21\u4e3b\u52a8\u9ed1\u6d1e\uff0c\u91ca\u653e\u540e\u6e05\u9664\u68cb\u76d8\u4e0a\u6570\u91cf\u6700\u591a\u7684\u4e00\u79cd\u65b9\u5757\u3002") },
|
||||
{ UPGRADE_AIR_RESHAPE, 1, 74, false, _T("\u7a7a\u4e2d\u6362\u5f62"), _T("\u64cd\u4f5c"), _T("\u83b7\u5f97 1 \u6b21\u4e3b\u52a8\u6362\u5f62\uff0c\u53ef\u5c06\u5f53\u524d\u65b9\u5757\u53d8\u4e3a I \u5757\u3002") },
|
||||
{ UPGRADE_RAINBOW_PIECE, 1, 74, false, _T("\u5f69\u8679\u65b9\u5757"), _T("\u723d\u611f"), _T("\u6982\u7387\u751f\u6210\u5f69\u8679\u65b9\u5757\uff0c\u843d\u5730\u540e\u53ef\u81ea\u52a8\u8865\u5168\u884c\u5185\u7f3a\u53e3\uff0c\u66f4\u5bb9\u6613\u8865\u9f50\u6d88\u884c\u3002") },
|
||||
{ UPGRADE_VOID_CORE, 1, 112, false, _T("\u865a\u7a7a\u6838\u5fc3"), _T("\u8fdb\u5316"), _T("\u9ed1\u6d1e\u540e\u989d\u5916\u751f\u6210 1 \u4e2a\u5f69\u8679\u65b9\u5757\uff0c\u5f69\u8679\u6d88\u884c\u65f6\u89e6\u53d1\u5c0f\u578b\u9ed1\u6d1e\u3002") },
|
||||
{ UPGRADE_STABLE_STRUCTURE, -1, 72, true, _T("\u7a33\u5b9a\u7ed3\u6784"), _T("\u7279\u6b8a"), _T("\u843d\u5730\u540e\u5c0f\u6982\u7387\u81ea\u52a8\u586b\u8865\u90bb\u8fd1\u7a7a\u6d1e\uff0c\u63d0\u9ad8\u76d8\u9762\u7ed3\u6784\u7a33\u5b9a\u6027\u3002") },
|
||||
{ UPGRADE_DOUBLE_GROWTH, 1, 84, false, _T("\u6210\u957f\u6838\u5fc3"), _T("\u6210\u957f"), _T("\u6c38\u4e45\u83b7\u5f97 +15% \u5f97\u5206\u4e0e +15% EXP\uff0c\u53ea\u80fd\u9009\u62e9\u4e00\u6b21\u3002") },
|
||||
{ UPGRADE_PIECE_TUNING, -1, 64, true, _T("\u65b9\u5757\u6539\u9020"), _T("\u7279\u6b8a"), _T("\u9009\u62e9\u4e00\u79cd\u65b9\u5757\uff0c\u964d\u4f4e\u5176\u540e\u7eed\u51fa\u73b0\u6982\u7387\u3002") },
|
||||
@@ -298,6 +303,9 @@ static void ResetPlayerStats(PlayerStats& stats, bool useRogueRules)
|
||||
stats.blackHoleCharges = 0;
|
||||
stats.reshapeLevel = 0;
|
||||
stats.reshapeCharges = 0;
|
||||
stats.rainbowPieceLevel = 0;
|
||||
stats.voidCoreLevel = 0;
|
||||
stats.pendingRainbowPieceCount = 0;
|
||||
stats.stableStructureLevel = 0;
|
||||
stats.doubleGrowthLevel = 0;
|
||||
stats.gamblerLevel = 0;
|
||||
@@ -399,6 +407,10 @@ static int GetUpgradeCurrentLevel(int upgradeId)
|
||||
return rogueStats.blackHoleLevel;
|
||||
case UPGRADE_AIR_RESHAPE:
|
||||
return rogueStats.reshapeLevel;
|
||||
case UPGRADE_RAINBOW_PIECE:
|
||||
return rogueStats.rainbowPieceLevel;
|
||||
case UPGRADE_VOID_CORE:
|
||||
return rogueStats.voidCoreLevel;
|
||||
case UPGRADE_STABLE_STRUCTURE:
|
||||
return rogueStats.stableStructureLevel;
|
||||
case UPGRADE_DOUBLE_GROWTH:
|
||||
@@ -603,6 +615,15 @@ static int GetUpgradeDynamicWeight(const UpgradeEntry& entry)
|
||||
weight += 18;
|
||||
}
|
||||
break;
|
||||
case UPGRADE_RAINBOW_PIECE:
|
||||
if (boardIsDangerous || rogueStats.totalLinesCleared >= 8)
|
||||
{
|
||||
weight += 16;
|
||||
}
|
||||
break;
|
||||
case UPGRADE_VOID_CORE:
|
||||
weight += 30;
|
||||
break;
|
||||
case UPGRADE_STABLE_STRUCTURE:
|
||||
if (boardIsDangerous)
|
||||
{
|
||||
@@ -744,6 +765,13 @@ static bool IsUpgradeSelectable(const UpgradeEntry& entry)
|
||||
rogueStats.controlMasterLevel == 0;
|
||||
}
|
||||
|
||||
if (entry.id == UPGRADE_VOID_CORE)
|
||||
{
|
||||
return rogueStats.blackHoleLevel > 0 &&
|
||||
rogueStats.rainbowPieceLevel > 0 &&
|
||||
rogueStats.voidCoreLevel == 0;
|
||||
}
|
||||
|
||||
if (entry.repeatable)
|
||||
{
|
||||
return true;
|
||||
@@ -864,6 +892,70 @@ static bool RollCrossPiece()
|
||||
return (rand() % 100) < chancePercent;
|
||||
}
|
||||
|
||||
static bool RollRainbowPiece()
|
||||
{
|
||||
if (currentMode != MODE_ROGUE || rogueStats.rainbowPieceLevel <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int chancePercent = 12;
|
||||
return (rand() % 100) < chancePercent;
|
||||
}
|
||||
|
||||
static bool IsRainbowBoardCell(int cellValue)
|
||||
{
|
||||
return cellValue == 8;
|
||||
}
|
||||
|
||||
static int TriggerMiniBlackHole(int maxCellsToClear)
|
||||
{
|
||||
int blockCounts[8] = { 0 };
|
||||
|
||||
for (int y = 0; y < nGameHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < nGameWidth; x++)
|
||||
{
|
||||
int cell = workRegion[y][x];
|
||||
if (cell >= 1 && cell <= 7)
|
||||
{
|
||||
blockCounts[cell]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int targetBlock = 0;
|
||||
int maxCount = 0;
|
||||
for (int block = 1; block <= 7; block++)
|
||||
{
|
||||
if (blockCounts[block] > maxCount)
|
||||
{
|
||||
maxCount = blockCounts[block];
|
||||
targetBlock = block;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetBlock == 0 || maxCellsToClear <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int clearedCellCount = 0;
|
||||
for (int y = nGameHeight - 1; y >= 0 && clearedCellCount < maxCellsToClear; y--)
|
||||
{
|
||||
for (int x = 0; x < nGameWidth && clearedCellCount < maxCellsToClear; x++)
|
||||
{
|
||||
if (workRegion[y][x] == targetBlock)
|
||||
{
|
||||
workRegion[y][x] = 0;
|
||||
clearedCellCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return clearedCellCount;
|
||||
}
|
||||
|
||||
static void RollCurrentPieceSpecialFlags(bool allowRandomSpecials)
|
||||
{
|
||||
if (!allowRandomSpecials)
|
||||
@@ -871,12 +963,24 @@ static void RollCurrentPieceSpecialFlags(bool allowRandomSpecials)
|
||||
currentPieceIsExplosive = false;
|
||||
currentPieceIsLaser = false;
|
||||
currentPieceIsCross = false;
|
||||
currentPieceIsRainbow = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentMode == MODE_ROGUE && rogueStats.pendingRainbowPieceCount > 0)
|
||||
{
|
||||
rogueStats.pendingRainbowPieceCount--;
|
||||
currentPieceIsExplosive = false;
|
||||
currentPieceIsLaser = false;
|
||||
currentPieceIsCross = false;
|
||||
currentPieceIsRainbow = true;
|
||||
return;
|
||||
}
|
||||
|
||||
currentPieceIsExplosive = RollExplosivePiece();
|
||||
currentPieceIsLaser = !currentPieceIsExplosive && RollLaserPiece();
|
||||
currentPieceIsCross = !currentPieceIsExplosive && !currentPieceIsLaser && RollCrossPiece();
|
||||
currentPieceIsRainbow = !currentPieceIsExplosive && !currentPieceIsLaser && !currentPieceIsCross && RollRainbowPiece();
|
||||
}
|
||||
|
||||
static int ClearExplosiveAreaAt(int centerY, int centerX)
|
||||
@@ -944,6 +1048,48 @@ static int ClearRowAt(int row)
|
||||
return clearedCellCount;
|
||||
}
|
||||
|
||||
static int TriggerRainbowRowCompletion(int minRow, int maxRow)
|
||||
{
|
||||
int filledCellCount = 0;
|
||||
|
||||
if (minRow < 0)
|
||||
{
|
||||
minRow = 0;
|
||||
}
|
||||
if (maxRow >= nGameHeight)
|
||||
{
|
||||
maxRow = nGameHeight - 1;
|
||||
}
|
||||
|
||||
for (int row = minRow; row <= maxRow; row++)
|
||||
{
|
||||
int emptyCount = 0;
|
||||
int emptyColumn = -1;
|
||||
bool hasRainbowCell = false;
|
||||
|
||||
for (int x = 0; x < nGameWidth; x++)
|
||||
{
|
||||
if (workRegion[row][x] == 0)
|
||||
{
|
||||
emptyCount++;
|
||||
emptyColumn = x;
|
||||
}
|
||||
else if (IsRainbowBoardCell(workRegion[row][x]))
|
||||
{
|
||||
hasRainbowCell = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasRainbowCell && emptyCount == 1 && emptyColumn >= 0)
|
||||
{
|
||||
workRegion[row][emptyColumn] = 8;
|
||||
filledCellCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return filledCellCount;
|
||||
}
|
||||
|
||||
static int TriggerBlackHole()
|
||||
{
|
||||
int blockCounts[8] = { 0 };
|
||||
@@ -1511,6 +1657,12 @@ static void ApplyUpgradeById(int upgradeId, int targetPieceType, int applyCount)
|
||||
rogueStats.reshapeLevel = 1;
|
||||
rogueStats.reshapeCharges++;
|
||||
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;
|
||||
@@ -2099,6 +2251,7 @@ void Fixing()
|
||||
bool overflowTop = false;
|
||||
Point explosiveCells[4] = {};
|
||||
int explosiveCellCount = 0;
|
||||
int rainbowFilledCount = 0;
|
||||
pendingChainBombFollowup = false;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
@@ -2119,7 +2272,7 @@ void Fixing()
|
||||
// 将当前方块在可视区域内的部分写入工作区
|
||||
if (fixY >= 0 && fixY < nGameHeight && fixX >= 0 && fixX < nGameWidth)
|
||||
{
|
||||
workRegion[fixY][fixX] = bricks[type][state][i][j];
|
||||
workRegion[fixY][fixX] = currentPieceIsRainbow ? 8 : bricks[type][state][i][j];
|
||||
if (currentPieceIsExplosive && explosiveCellCount < 4)
|
||||
{
|
||||
explosiveCells[explosiveCellCount].x = fixX;
|
||||
@@ -2131,6 +2284,17 @@ void Fixing()
|
||||
}
|
||||
}
|
||||
|
||||
if (!overflowTop && currentPieceIsRainbow)
|
||||
{
|
||||
rainbowFilledCount = TriggerRainbowRowCompletion(point.y, point.y + 3);
|
||||
if (rainbowFilledCount > 0)
|
||||
{
|
||||
TCHAR rainbowDetail[128];
|
||||
_stprintf_s(rainbowDetail, _T("\u8865\u5168 %d \u4e2a\u884c\u5185\u7f3a\u53e3\uff0c\u66f4\u5bb9\u6613\u8fbe\u6210\u6d88\u884c\u3002"), rainbowFilledCount);
|
||||
SetFeedbackMessage(_T("\u5f69\u8679\u65b9\u5757\u751f\u6548"), rainbowDetail, 10);
|
||||
}
|
||||
}
|
||||
|
||||
if (overflowTop)
|
||||
{
|
||||
if (currentMode == MODE_ROGUE && rogueStats.terminalClearLevel > 0 && rogueStats.lastChanceCount > 0 && rogueStats.screenBombCount > 0)
|
||||
@@ -2332,6 +2496,7 @@ void DeleteOneLine(int number)
|
||||
int DeleteLines()
|
||||
{
|
||||
int clearedLines = 0;
|
||||
bool clearedWithRainbow = false;
|
||||
|
||||
for (int i = nGameHeight - 1; i >= 0; i--)
|
||||
{
|
||||
@@ -2348,6 +2513,14 @@ int DeleteLines()
|
||||
|
||||
if (fullLine)
|
||||
{
|
||||
for (int j = 0; j < nGameWidth; j++)
|
||||
{
|
||||
if (IsRainbowBoardCell(workRegion[i][j]))
|
||||
{
|
||||
clearedWithRainbow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DeleteOneLine(i);
|
||||
clearedLines++;
|
||||
i++;
|
||||
@@ -2400,6 +2573,25 @@ int DeleteLines()
|
||||
pendingChainBombFollowup = false;
|
||||
}
|
||||
|
||||
if (currentMode == MODE_ROGUE && clearedWithRainbow && rogueStats.voidCoreLevel > 0)
|
||||
{
|
||||
int miniBlackHoleCleared = TriggerMiniBlackHole(5);
|
||||
if (miniBlackHoleCleared > 0)
|
||||
{
|
||||
int miniScore = miniBlackHoleCleared * rogueStats.scoreMultiplierPercent / 100;
|
||||
if (miniScore < miniBlackHoleCleared)
|
||||
{
|
||||
miniScore = miniBlackHoleCleared;
|
||||
}
|
||||
rogueStats.score += miniScore;
|
||||
tScore = rogueStats.score;
|
||||
|
||||
TCHAR miniDetail[128];
|
||||
_stprintf_s(miniDetail, _T("\u5f69\u8679\u6d88\u884c\u89e6\u53d1\u5c0f\u578b\u9ed1\u6d1e\uff0c\u6e05\u9664 %d \u683c +%d Score"), miniBlackHoleCleared, miniScore);
|
||||
SetFeedbackMessage(_T("\u865a\u7a7a\u6838\u5fc3\u89e6\u53d1"), miniDetail, 12);
|
||||
}
|
||||
}
|
||||
|
||||
return clearedLines;
|
||||
}
|
||||
|
||||
@@ -2729,12 +2921,28 @@ void UseBlackHole()
|
||||
rogueStats.score += scoreGain;
|
||||
tScore = rogueStats.score;
|
||||
|
||||
if (rogueStats.voidCoreLevel > 0)
|
||||
{
|
||||
rogueStats.pendingRainbowPieceCount++;
|
||||
}
|
||||
|
||||
TCHAR detail[128];
|
||||
_stprintf_s(
|
||||
detail,
|
||||
_T("吞噬数量最多的一种方块,清除 %d 格 +%d Score"),
|
||||
clearedCells,
|
||||
scoreGain);
|
||||
if (rogueStats.voidCoreLevel > 0)
|
||||
{
|
||||
_stprintf_s(
|
||||
detail,
|
||||
_T("吞噬数量最多的一种方块,清除 %d 格 +%d Score 并生成 1 个彩虹方块"),
|
||||
clearedCells,
|
||||
scoreGain);
|
||||
}
|
||||
else
|
||||
{
|
||||
_stprintf_s(
|
||||
detail,
|
||||
_T("吞噬数量最多的一种方块,清除 %d 格 +%d Score"),
|
||||
clearedCells,
|
||||
scoreGain);
|
||||
}
|
||||
SetFeedbackMessage(_T("主动释放黑洞"), detail, 12);
|
||||
|
||||
currentFallInterval = GetRogueFallInterval();
|
||||
|
||||
Reference in New Issue
Block a user