补充十字方块、黑洞和空中换形强化
This commit is contained in:
@@ -57,6 +57,7 @@ struct PlayerStats
|
|||||||
int chainBlastLevel;
|
int chainBlastLevel;
|
||||||
int chainBombLevel;
|
int chainBombLevel;
|
||||||
int laserLevel;
|
int laserLevel;
|
||||||
|
int crossPieceLevel;
|
||||||
int thunderTetrisLevel;
|
int thunderTetrisLevel;
|
||||||
int thunderLaserLevel;
|
int thunderLaserLevel;
|
||||||
int feverLevel;
|
int feverLevel;
|
||||||
@@ -82,6 +83,10 @@ struct PlayerStats
|
|||||||
int holdSlowTicks;
|
int holdSlowTicks;
|
||||||
int blockStormLevel;
|
int blockStormLevel;
|
||||||
int blockStormPiecesRemaining;
|
int blockStormPiecesRemaining;
|
||||||
|
int blackHoleLevel;
|
||||||
|
int blackHoleCharges;
|
||||||
|
int reshapeLevel;
|
||||||
|
int reshapeCharges;
|
||||||
int stableStructureLevel;
|
int stableStructureLevel;
|
||||||
int doubleGrowthLevel;
|
int doubleGrowthLevel;
|
||||||
int gamblerLevel;
|
int gamblerLevel;
|
||||||
@@ -164,6 +169,7 @@ extern int holdType;
|
|||||||
extern bool holdUsedThisTurn;
|
extern bool holdUsedThisTurn;
|
||||||
extern bool currentPieceIsExplosive;
|
extern bool currentPieceIsExplosive;
|
||||||
extern bool currentPieceIsLaser;
|
extern bool currentPieceIsLaser;
|
||||||
|
extern bool currentPieceIsCross;
|
||||||
extern int bricks[7][4][4][4];
|
extern int bricks[7][4][4][4];
|
||||||
extern COLORREF BrickColor[7];
|
extern COLORREF BrickColor[7];
|
||||||
|
|
||||||
@@ -187,6 +193,8 @@ void OpenUpgradeMenu();
|
|||||||
void ConfirmUpgradeSelection();
|
void ConfirmUpgradeSelection();
|
||||||
void HoldCurrentPiece();
|
void HoldCurrentPiece();
|
||||||
void UseScreenBomb();
|
void UseScreenBomb();
|
||||||
|
void UseBlackHole();
|
||||||
|
void UseAirReshape();
|
||||||
int GetRogueFallInterval();
|
int GetRogueFallInterval();
|
||||||
|
|
||||||
void TDrawScreen(HDC hdc, HWND hWnd);
|
void TDrawScreen(HDC hdc, HWND hWnd);
|
||||||
|
|||||||
@@ -435,9 +435,15 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
case VK_SHIFT:
|
case VK_SHIFT:
|
||||||
HoldCurrentPiece();
|
HoldCurrentPiece();
|
||||||
break;
|
break;
|
||||||
|
case 'Z':
|
||||||
|
UseBlackHole();
|
||||||
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
UseScreenBomb();
|
UseScreenBomb();
|
||||||
break;
|
break;
|
||||||
|
case 'V':
|
||||||
|
UseAirReshape();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+284
-11
@@ -24,6 +24,7 @@ int holdType = -1;
|
|||||||
bool holdUsedThisTurn = false;
|
bool holdUsedThisTurn = false;
|
||||||
bool currentPieceIsExplosive = false;
|
bool currentPieceIsExplosive = false;
|
||||||
bool currentPieceIsLaser = false;
|
bool currentPieceIsLaser = false;
|
||||||
|
bool currentPieceIsCross = false;
|
||||||
Point pendingChainBombCenter = { 0, 0 };
|
Point pendingChainBombCenter = { 0, 0 };
|
||||||
bool pendingChainBombFollowup = false;
|
bool pendingChainBombFollowup = false;
|
||||||
|
|
||||||
@@ -63,7 +64,10 @@ enum UpgradeId
|
|||||||
UPGRADE_UPGRADE_SHOCKWAVE = 31,
|
UPGRADE_UPGRADE_SHOCKWAVE = 31,
|
||||||
UPGRADE_EVOLUTION_IMPACT = 32,
|
UPGRADE_EVOLUTION_IMPACT = 32,
|
||||||
UPGRADE_CONTROL_MASTER = 33,
|
UPGRADE_CONTROL_MASTER = 33,
|
||||||
UPGRADE_BLOCK_STORM = 34
|
UPGRADE_BLOCK_STORM = 34,
|
||||||
|
UPGRADE_CROSS_PIECE = 35,
|
||||||
|
UPGRADE_BLACK_HOLE = 36,
|
||||||
|
UPGRADE_AIR_RESHAPE = 37
|
||||||
};
|
};
|
||||||
|
|
||||||
static const UpgradeEntry kUpgradePool[] =
|
static const UpgradeEntry kUpgradePool[] =
|
||||||
@@ -99,6 +103,9 @@ static const UpgradeEntry kUpgradePool[] =
|
|||||||
{ UPGRADE_EVOLUTION_IMPACT, 1, 118, false, _T("\u8fdb\u5316\u51b2\u51fb"), _T("\u8fdb\u5316"), _T("\u5347\u7ea7\u65f6\u6e05\u9664\u5e95\u90e8 3 \u884c\uff0c\u5e76\u83b7\u5f97 10 \u79d2\u53cc\u500d EXP\u3002") },
|
{ UPGRADE_EVOLUTION_IMPACT, 1, 118, false, _T("\u8fdb\u5316\u51b2\u51fb"), _T("\u8fdb\u5316"), _T("\u5347\u7ea7\u65f6\u6e05\u9664\u5e95\u90e8 3 \u884c\uff0c\u5e76\u83b7\u5f97 10 \u79d2\u53cc\u500d EXP\u3002") },
|
||||||
{ UPGRADE_CONTROL_MASTER, 1, 112, false, _T("\u64cd\u63a7\u5927\u5e08"), _T("\u8fdb\u5316"), _T("Hold \u540e\u77ed\u6682\u964d\u4f4e\u4e0b\u843d\u901f\u5ea6\uff0c\u5e76\u989d\u5916\u589e\u52a0 1 \u4e2a\u9884\u89c8\u65b9\u5757\u3002") },
|
{ UPGRADE_CONTROL_MASTER, 1, 112, false, _T("\u64cd\u63a7\u5927\u5e08"), _T("\u8fdb\u5316"), _T("Hold \u540e\u77ed\u6682\u964d\u4f4e\u4e0b\u843d\u901f\u5ea6\uff0c\u5e76\u989d\u5916\u589e\u52a0 1 \u4e2a\u9884\u89c8\u65b9\u5757\u3002") },
|
||||||
{ UPGRADE_BLOCK_STORM, 1, 82, false, _T("\u65b9\u5757\u98ce\u66b4"), _T("\u723d\u611f"), _T("\u63a5\u4e0b\u6765 5 \u4e2a\u65b9\u5757\u5168\u90e8\u53d8\u6210 I \u5757\uff0c\u5feb\u901f\u5236\u9020\u56db\u6d88\u673a\u4f1a\u3002") },
|
{ UPGRADE_BLOCK_STORM, 1, 82, false, _T("\u65b9\u5757\u98ce\u66b4"), _T("\u723d\u611f"), _T("\u63a5\u4e0b\u6765 5 \u4e2a\u65b9\u5757\u5168\u90e8\u53d8\u6210 I \u5757\uff0c\u5feb\u901f\u5236\u9020\u56db\u6d88\u673a\u4f1a\u3002") },
|
||||||
|
{ 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_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_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_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") },
|
{ 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") },
|
||||||
@@ -287,6 +294,10 @@ static void ResetPlayerStats(PlayerStats& stats, bool useRogueRules)
|
|||||||
stats.holdSlowTicks = 0;
|
stats.holdSlowTicks = 0;
|
||||||
stats.blockStormLevel = 0;
|
stats.blockStormLevel = 0;
|
||||||
stats.blockStormPiecesRemaining = 0;
|
stats.blockStormPiecesRemaining = 0;
|
||||||
|
stats.blackHoleLevel = 0;
|
||||||
|
stats.blackHoleCharges = 0;
|
||||||
|
stats.reshapeLevel = 0;
|
||||||
|
stats.reshapeCharges = 0;
|
||||||
stats.stableStructureLevel = 0;
|
stats.stableStructureLevel = 0;
|
||||||
stats.doubleGrowthLevel = 0;
|
stats.doubleGrowthLevel = 0;
|
||||||
stats.gamblerLevel = 0;
|
stats.gamblerLevel = 0;
|
||||||
@@ -382,6 +393,12 @@ static int GetUpgradeCurrentLevel(int upgradeId)
|
|||||||
return rogueStats.controlMasterLevel;
|
return rogueStats.controlMasterLevel;
|
||||||
case UPGRADE_BLOCK_STORM:
|
case UPGRADE_BLOCK_STORM:
|
||||||
return rogueStats.blockStormLevel;
|
return rogueStats.blockStormLevel;
|
||||||
|
case UPGRADE_CROSS_PIECE:
|
||||||
|
return rogueStats.crossPieceLevel;
|
||||||
|
case UPGRADE_BLACK_HOLE:
|
||||||
|
return rogueStats.blackHoleLevel;
|
||||||
|
case UPGRADE_AIR_RESHAPE:
|
||||||
|
return rogueStats.reshapeLevel;
|
||||||
case UPGRADE_STABLE_STRUCTURE:
|
case UPGRADE_STABLE_STRUCTURE:
|
||||||
return rogueStats.stableStructureLevel;
|
return rogueStats.stableStructureLevel;
|
||||||
case UPGRADE_DOUBLE_GROWTH:
|
case UPGRADE_DOUBLE_GROWTH:
|
||||||
@@ -568,6 +585,24 @@ static int GetUpgradeDynamicWeight(const UpgradeEntry& entry)
|
|||||||
weight += 20;
|
weight += 20;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case UPGRADE_CROSS_PIECE:
|
||||||
|
if (rogueStats.laserLevel > 0 || rogueStats.feverLevel > 0)
|
||||||
|
{
|
||||||
|
weight += 14;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UPGRADE_BLACK_HOLE:
|
||||||
|
if (boardIsDangerous)
|
||||||
|
{
|
||||||
|
weight += 18;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UPGRADE_AIR_RESHAPE:
|
||||||
|
if (boardIsDangerous || rogueStats.tetrisGambleLevel > 0)
|
||||||
|
{
|
||||||
|
weight += 18;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case UPGRADE_STABLE_STRUCTURE:
|
case UPGRADE_STABLE_STRUCTURE:
|
||||||
if (boardIsDangerous)
|
if (boardIsDangerous)
|
||||||
{
|
{
|
||||||
@@ -813,6 +848,37 @@ static bool RollLaserPiece()
|
|||||||
return (rand() % 100) < chancePercent;
|
return (rand() % 100) < chancePercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool RollCrossPiece()
|
||||||
|
{
|
||||||
|
if (currentMode != MODE_ROGUE || rogueStats.crossPieceLevel <= 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int chancePercent = 8 + (rogueStats.crossPieceLevel - 1) * 6;
|
||||||
|
if (chancePercent > 28)
|
||||||
|
{
|
||||||
|
chancePercent = 28;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rand() % 100) < chancePercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RollCurrentPieceSpecialFlags(bool allowRandomSpecials)
|
||||||
|
{
|
||||||
|
if (!allowRandomSpecials)
|
||||||
|
{
|
||||||
|
currentPieceIsExplosive = false;
|
||||||
|
currentPieceIsLaser = false;
|
||||||
|
currentPieceIsCross = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPieceIsExplosive = RollExplosivePiece();
|
||||||
|
currentPieceIsLaser = !currentPieceIsExplosive && RollLaserPiece();
|
||||||
|
currentPieceIsCross = !currentPieceIsExplosive && !currentPieceIsLaser && RollCrossPiece();
|
||||||
|
}
|
||||||
|
|
||||||
static int ClearExplosiveAreaAt(int centerY, int centerX)
|
static int ClearExplosiveAreaAt(int centerY, int centerX)
|
||||||
{
|
{
|
||||||
int radius = (currentMode == MODE_ROGUE && rogueStats.chainBombLevel > 0) ? 2 : 1;
|
int radius = (currentMode == MODE_ROGUE && rogueStats.chainBombLevel > 0) ? 2 : 1;
|
||||||
@@ -857,6 +923,74 @@ static int ClearColumnAt(int column)
|
|||||||
return clearedCellCount;
|
return clearedCellCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ClearRowAt(int row)
|
||||||
|
{
|
||||||
|
int clearedCellCount = 0;
|
||||||
|
|
||||||
|
if (row < 0 || row >= nGameHeight)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = 0; x < nGameWidth; x++)
|
||||||
|
{
|
||||||
|
if (workRegion[row][x] != 0)
|
||||||
|
{
|
||||||
|
workRegion[row][x] = 0;
|
||||||
|
clearedCellCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return clearedCellCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TriggerBlackHole()
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clearedCellCount = 0;
|
||||||
|
for (int y = 0; y < nGameHeight; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < nGameWidth; x++)
|
||||||
|
{
|
||||||
|
if (workRegion[y][x] == targetBlock)
|
||||||
|
{
|
||||||
|
workRegion[y][x] = 0;
|
||||||
|
clearedCellCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return clearedCellCount;
|
||||||
|
}
|
||||||
|
|
||||||
static int TriggerScreenBomb()
|
static int TriggerScreenBomb()
|
||||||
{
|
{
|
||||||
int clearedCellCount = 0;
|
int clearedCellCount = 0;
|
||||||
@@ -1366,6 +1500,17 @@ static void ApplyUpgradeById(int upgradeId, int targetPieceType, int applyCount)
|
|||||||
nextTypes[1] = 0;
|
nextTypes[1] = 0;
|
||||||
nextTypes[2] = 0;
|
nextTypes[2] = 0;
|
||||||
break;
|
break;
|
||||||
|
case UPGRADE_CROSS_PIECE:
|
||||||
|
rogueStats.crossPieceLevel += applyCount;
|
||||||
|
break;
|
||||||
|
case UPGRADE_BLACK_HOLE:
|
||||||
|
rogueStats.blackHoleLevel = 1;
|
||||||
|
rogueStats.blackHoleCharges++;
|
||||||
|
break;
|
||||||
|
case UPGRADE_AIR_RESHAPE:
|
||||||
|
rogueStats.reshapeLevel = 1;
|
||||||
|
rogueStats.reshapeCharges++;
|
||||||
|
break;
|
||||||
case UPGRADE_STABLE_STRUCTURE:
|
case UPGRADE_STABLE_STRUCTURE:
|
||||||
rogueStats.stableStructureLevel += applyCount;
|
rogueStats.stableStructureLevel += applyCount;
|
||||||
break;
|
break;
|
||||||
@@ -2085,6 +2230,51 @@ void Fixing()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentPieceIsCross)
|
||||||
|
{
|
||||||
|
int crossRow = point.y + 1;
|
||||||
|
int crossColumn = point.x + 1;
|
||||||
|
if (crossRow < 0)
|
||||||
|
{
|
||||||
|
crossRow = 0;
|
||||||
|
}
|
||||||
|
if (crossRow >= nGameHeight)
|
||||||
|
{
|
||||||
|
crossRow = nGameHeight - 1;
|
||||||
|
}
|
||||||
|
if (crossColumn < 0)
|
||||||
|
{
|
||||||
|
crossColumn = 0;
|
||||||
|
}
|
||||||
|
if (crossColumn >= nGameWidth)
|
||||||
|
{
|
||||||
|
crossColumn = nGameWidth - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int crossCellsCleared = ClearRowAt(crossRow);
|
||||||
|
int columnCellsCleared = ClearColumnAt(crossColumn);
|
||||||
|
if (workRegion[crossRow][crossColumn] == 0 && columnCellsCleared > 0)
|
||||||
|
{
|
||||||
|
// center cell may already be counted by row clear
|
||||||
|
}
|
||||||
|
int totalCrossCleared = crossCellsCleared + columnCellsCleared;
|
||||||
|
|
||||||
|
if (currentMode == MODE_ROGUE && totalCrossCleared > 0)
|
||||||
|
{
|
||||||
|
int crossScore = totalCrossCleared * rogueStats.scoreMultiplierPercent / 100;
|
||||||
|
if (crossScore < totalCrossCleared)
|
||||||
|
{
|
||||||
|
crossScore = totalCrossCleared;
|
||||||
|
}
|
||||||
|
rogueStats.score += crossScore;
|
||||||
|
tScore = rogueStats.score;
|
||||||
|
|
||||||
|
TCHAR crossDetail[128];
|
||||||
|
_stprintf_s(crossDetail, _T("\u6e05\u9664 %d \u683c +%d Score"), totalCrossCleared, crossScore);
|
||||||
|
SetFeedbackMessage(_T("\u5341\u5b57\u65b9\u5757\u89e6\u53d1"), crossDetail, 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (TryStabilizeBoard() > 0)
|
if (TryStabilizeBoard() > 0)
|
||||||
{
|
{
|
||||||
SetFeedbackMessage(_T("\u7a33\u5b9a\u7ed3\u6784\u751f\u6548"), _T("\u81ea\u52a8\u586b\u8865\u4e86\u4e00\u4e2a\u90bb\u8fd1\u7a7a\u6d1e\u3002"), 10);
|
SetFeedbackMessage(_T("\u7a33\u5b9a\u7ed3\u6784\u751f\u6548"), _T("\u81ea\u52a8\u586b\u8865\u4e86\u4e00\u4e2a\u90bb\u8fd1\u7a7a\u6d1e\u3002"), 10);
|
||||||
@@ -2100,8 +2290,7 @@ void Fixing()
|
|||||||
nType = nextTypes[0];
|
nType = nextTypes[0];
|
||||||
state = 0;
|
state = 0;
|
||||||
holdUsedThisTurn = false;
|
holdUsedThisTurn = false;
|
||||||
currentPieceIsExplosive = RollExplosivePiece();
|
RollCurrentPieceSpecialFlags(true);
|
||||||
currentPieceIsLaser = !currentPieceIsExplosive && RollLaserPiece();
|
|
||||||
point = GetSpawnPoint(type);
|
point = GetSpawnPoint(type);
|
||||||
target = point;
|
target = point;
|
||||||
ComputeTarget();
|
ComputeTarget();
|
||||||
@@ -2274,8 +2463,7 @@ void Restart()
|
|||||||
feedbackState.detail[0] = _T('\0');
|
feedbackState.detail[0] = _T('\0');
|
||||||
holdType = -1;
|
holdType = -1;
|
||||||
holdUsedThisTurn = false;
|
holdUsedThisTurn = false;
|
||||||
currentPieceIsExplosive = false;
|
RollCurrentPieceSpecialFlags(false);
|
||||||
currentPieceIsLaser = false;
|
|
||||||
tScore = 0;
|
tScore = 0;
|
||||||
|
|
||||||
ResetNextQueue();
|
ResetNextQueue();
|
||||||
@@ -2283,8 +2471,7 @@ void Restart()
|
|||||||
nType = nextTypes[0];
|
nType = nextTypes[0];
|
||||||
state = 0;
|
state = 0;
|
||||||
holdUsedThisTurn = false;
|
holdUsedThisTurn = false;
|
||||||
currentPieceIsExplosive = RollExplosivePiece();
|
RollCurrentPieceSpecialFlags(true);
|
||||||
currentPieceIsLaser = !currentPieceIsExplosive && RollLaserPiece();
|
|
||||||
point = GetSpawnPoint(type);
|
point = GetSpawnPoint(type);
|
||||||
target = point;
|
target = point;
|
||||||
|
|
||||||
@@ -2452,14 +2639,12 @@ void HoldCurrentPiece()
|
|||||||
{
|
{
|
||||||
type = ConsumeNextType();
|
type = ConsumeNextType();
|
||||||
nType = nextTypes[0];
|
nType = nextTypes[0];
|
||||||
currentPieceIsExplosive = RollExplosivePiece();
|
RollCurrentPieceSpecialFlags(true);
|
||||||
currentPieceIsLaser = !currentPieceIsExplosive && RollLaserPiece();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
type = previousHoldType;
|
type = previousHoldType;
|
||||||
currentPieceIsExplosive = false;
|
RollCurrentPieceSpecialFlags(false);
|
||||||
currentPieceIsLaser = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
point = GetSpawnPoint(type);
|
point = GetSpawnPoint(type);
|
||||||
@@ -2518,3 +2703,91 @@ void UseScreenBomb()
|
|||||||
currentFallInterval = GetRogueFallInterval();
|
currentFallInterval = GetRogueFallInterval();
|
||||||
ComputeTarget();
|
ComputeTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UseBlackHole()
|
||||||
|
{
|
||||||
|
if (currentMode != MODE_ROGUE || rogueStats.blackHoleCharges <= 0 || currentScreen != SCREEN_PLAYING || suspendFlag || gameOverFlag)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clearedCells = TriggerBlackHole();
|
||||||
|
if (clearedCells <= 0)
|
||||||
|
{
|
||||||
|
SetFeedbackMessage(_T("黑洞未触发"), _T("当前棋盘上没有可被黑洞吞噬的固定方块。"), 10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rogueStats.blackHoleCharges--;
|
||||||
|
|
||||||
|
int scoreGain = clearedCells * rogueStats.scoreMultiplierPercent / 100;
|
||||||
|
if (scoreGain < clearedCells)
|
||||||
|
{
|
||||||
|
scoreGain = clearedCells;
|
||||||
|
}
|
||||||
|
|
||||||
|
rogueStats.score += scoreGain;
|
||||||
|
tScore = rogueStats.score;
|
||||||
|
|
||||||
|
TCHAR detail[128];
|
||||||
|
_stprintf_s(
|
||||||
|
detail,
|
||||||
|
_T("吞噬数量最多的一种方块,清除 %d 格 +%d Score"),
|
||||||
|
clearedCells,
|
||||||
|
scoreGain);
|
||||||
|
SetFeedbackMessage(_T("主动释放黑洞"), detail, 12);
|
||||||
|
|
||||||
|
currentFallInterval = GetRogueFallInterval();
|
||||||
|
ComputeTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UseAirReshape()
|
||||||
|
{
|
||||||
|
if (currentMode != MODE_ROGUE || rogueStats.reshapeCharges <= 0 || currentScreen != SCREEN_PLAYING || suspendFlag || gameOverFlag)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int targetType = 0;
|
||||||
|
const int candidateStates[2] = { 0, 1 };
|
||||||
|
const int candidateOffsets[5] = { 0, -1, 1, -2, 2 };
|
||||||
|
Point originalPoint = point;
|
||||||
|
int originalType = type;
|
||||||
|
int originalState = state;
|
||||||
|
bool transformed = false;
|
||||||
|
|
||||||
|
for (int stateIndex = 0; stateIndex < 2 && !transformed; stateIndex++)
|
||||||
|
{
|
||||||
|
int nextState = candidateStates[stateIndex];
|
||||||
|
for (int offsetIndex = 0; offsetIndex < 5; offsetIndex++)
|
||||||
|
{
|
||||||
|
Point candidatePoint = originalPoint;
|
||||||
|
candidatePoint.x += candidateOffsets[offsetIndex];
|
||||||
|
|
||||||
|
if (IsPiecePlacementValid(targetType, nextState, candidatePoint))
|
||||||
|
{
|
||||||
|
type = targetType;
|
||||||
|
state = nextState;
|
||||||
|
point = candidatePoint;
|
||||||
|
transformed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!transformed)
|
||||||
|
{
|
||||||
|
type = originalType;
|
||||||
|
state = originalState;
|
||||||
|
point = originalPoint;
|
||||||
|
SetFeedbackMessage(_T("空中换形失败"), _T("当前空间不足,无法将方块变为 I 方块。"), 10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rogueStats.reshapeCharges--;
|
||||||
|
|
||||||
|
TCHAR detail[128];
|
||||||
|
_stprintf_s(detail, _T("当前方块已变为 I 方块,剩余 %d 次。"), rogueStats.reshapeCharges);
|
||||||
|
SetFeedbackMessage(_T("空中换形"), detail, 12);
|
||||||
|
ComputeTarget();
|
||||||
|
}
|
||||||
|
|||||||
@@ -333,6 +333,9 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
_T("\u2193 / S\uff1a\u8f6f\u964d\r\n")
|
_T("\u2193 / S\uff1a\u8f6f\u964d\r\n")
|
||||||
_T("Space\uff1a\u786c\u964d\r\n")
|
_T("Space\uff1a\u786c\u964d\r\n")
|
||||||
_T("C / Shift\uff1aHold\uff08\u89e3\u9501\u540e\uff09\r\n")
|
_T("C / Shift\uff1aHold\uff08\u89e3\u9501\u540e\uff09\r\n")
|
||||||
|
_T("Z\uff1a\u91ca\u653e\u9ed1\u6d1e\uff08\u83b7\u5f97\u540e\uff09\r\n")
|
||||||
|
_T("X\uff1a\u91ca\u653e\u6e05\u5c4f\u70b8\u5f39\uff08\u83b7\u5f97\u540e\uff09\r\n")
|
||||||
|
_T("V\uff1a\u7a7a\u4e2d\u6362\u5f62\uff08\u83b7\u5f97\u540e\uff09\r\n")
|
||||||
_T("P\uff1a\u6682\u505c / \u7ee7\u7eed\r\n")
|
_T("P\uff1a\u6682\u505c / \u7ee7\u7eed\r\n")
|
||||||
_T("R\uff1a\u91cd\u5f00\u5f53\u524d\u5bf9\u5c40\r\n")
|
_T("R\uff1a\u91cd\u5f00\u5f53\u524d\u5bf9\u5c40\r\n")
|
||||||
_T("M\uff1a\u8fd4\u56de\u4e3b\u83dc\u5355"),
|
_T("M\uff1a\u8fd4\u56de\u4e3b\u83dc\u5355"),
|
||||||
@@ -541,6 +544,11 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
activeOutlineColor = RGB(120, 232, 255);
|
activeOutlineColor = RGB(120, 232, 255);
|
||||||
activeOutlineWidth = SS(3);
|
activeOutlineWidth = SS(3);
|
||||||
}
|
}
|
||||||
|
else if (currentPieceIsCross)
|
||||||
|
{
|
||||||
|
activeOutlineColor = RGB(196, 255, 132);
|
||||||
|
activeOutlineWidth = SS(3);
|
||||||
|
}
|
||||||
HPEN brickPen = CreatePen(PS_SOLID, activeOutlineWidth, activeOutlineColor);
|
HPEN brickPen = CreatePen(PS_SOLID, activeOutlineWidth, activeOutlineColor);
|
||||||
oldPen = (HPEN)SelectObject(hdc, brickPen);
|
oldPen = (HPEN)SelectObject(hdc, brickPen);
|
||||||
oldBrush = (HBRUSH)SelectObject(hdc, brickBrush);
|
oldBrush = (HBRUSH)SelectObject(hdc, brickBrush);
|
||||||
@@ -704,6 +712,18 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(146), explosiveText, lstrlen(explosiveText));
|
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(146), explosiveText, lstrlen(explosiveText));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rogueStats.crossPieceLevel > 0)
|
||||||
|
{
|
||||||
|
TCHAR crossText[96];
|
||||||
|
int crossChance = 8 + (rogueStats.crossPieceLevel - 1) * 6;
|
||||||
|
if (crossChance > 28)
|
||||||
|
{
|
||||||
|
crossChance = 28;
|
||||||
|
}
|
||||||
|
_stprintf_s(crossText, _T("\u5341\u5b57\u6982\u7387 %d%% %s"), crossChance, currentPieceIsCross ? _T("\u672c\u5757\u5df2\u5341\u5b57") : _T("\u672c\u5757\u666e\u901a"));
|
||||||
|
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(178), crossText, lstrlen(crossText));
|
||||||
|
}
|
||||||
|
|
||||||
if (rogueStats.laserLevel > 0)
|
if (rogueStats.laserLevel > 0)
|
||||||
{
|
{
|
||||||
TCHAR laserText[96];
|
TCHAR laserText[96];
|
||||||
@@ -752,6 +772,20 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(530), bombText, lstrlen(bombText));
|
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(530), bombText, lstrlen(bombText));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rogueStats.blackHoleLevel > 0)
|
||||||
|
{
|
||||||
|
TCHAR blackHoleText[96];
|
||||||
|
_stprintf_s(blackHoleText, _T("\u9ed1\u6d1e \u5e93\u5b58 %d Z \u4e3b\u52a8\u91ca\u653e"), rogueStats.blackHoleCharges);
|
||||||
|
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(818), blackHoleText, lstrlen(blackHoleText));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rogueStats.reshapeLevel > 0)
|
||||||
|
{
|
||||||
|
TCHAR reshapeText[96];
|
||||||
|
_stprintf_s(reshapeText, _T("\u7a7a\u4e2d\u6362\u5f62 \u5e93\u5b58 %d V \u53d8\u4e3a I \u5757"), rogueStats.reshapeCharges);
|
||||||
|
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(850), reshapeText, lstrlen(reshapeText));
|
||||||
|
}
|
||||||
|
|
||||||
if (rogueStats.terminalClearLevel > 0)
|
if (rogueStats.terminalClearLevel > 0)
|
||||||
{
|
{
|
||||||
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(562), _T("\u7ec8\u672b\u6e05\u573a \u6fc0\u6d3b\u6700\u540e\u4e00\u640f\u65f6\u81ea\u52a8\u89e6\u53d1"), lstrlen(_T("\u7ec8\u672b\u6e05\u573a \u6fc0\u6d3b\u6700\u540e\u4e00\u640f\u65f6\u81ea\u52a8\u89e6\u53d1")));
|
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(562), _T("\u7ec8\u672b\u6e05\u573a \u6fc0\u6d3b\u6700\u540e\u4e00\u640f\u65f6\u81ea\u52a8\u89e6\u53d1"), lstrlen(_T("\u7ec8\u672b\u6e05\u573a \u6fc0\u6d3b\u6700\u540e\u4e00\u640f\u65f6\u81ea\u52a8\u89e6\u53d1")));
|
||||||
@@ -980,6 +1014,18 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
{
|
{
|
||||||
_stprintf_s(upgradeSummary + lstrlen(upgradeSummary), 512 - lstrlen(upgradeSummary), _T("\u65b9\u5757\u98ce\u66b4 Lv.1\r\n"));
|
_stprintf_s(upgradeSummary + lstrlen(upgradeSummary), 512 - lstrlen(upgradeSummary), _T("\u65b9\u5757\u98ce\u66b4 Lv.1\r\n"));
|
||||||
}
|
}
|
||||||
|
if (rogueStats.crossPieceLevel > 0)
|
||||||
|
{
|
||||||
|
_stprintf_s(upgradeSummary + lstrlen(upgradeSummary), 512 - lstrlen(upgradeSummary), _T("\u5341\u5b57\u65b9\u5757 Lv.%d\r\n"), rogueStats.crossPieceLevel);
|
||||||
|
}
|
||||||
|
if (rogueStats.blackHoleLevel > 0)
|
||||||
|
{
|
||||||
|
_stprintf_s(upgradeSummary + lstrlen(upgradeSummary), 512 - lstrlen(upgradeSummary), _T("\u9ed1\u6d1e Lv.1\r\n"));
|
||||||
|
}
|
||||||
|
if (rogueStats.reshapeLevel > 0)
|
||||||
|
{
|
||||||
|
_stprintf_s(upgradeSummary + lstrlen(upgradeSummary), 512 - lstrlen(upgradeSummary), _T("\u7a7a\u4e2d\u6362\u5f62 Lv.1\r\n"));
|
||||||
|
}
|
||||||
if (rogueStats.stableStructureLevel > 0)
|
if (rogueStats.stableStructureLevel > 0)
|
||||||
{
|
{
|
||||||
_stprintf_s(upgradeSummary + lstrlen(upgradeSummary), 512 - lstrlen(upgradeSummary), _T("\u7a33\u5b9a\u7ed3\u6784 Lv.%d\r\n"), rogueStats.stableStructureLevel);
|
_stprintf_s(upgradeSummary + lstrlen(upgradeSummary), 512 - lstrlen(upgradeSummary), _T("\u7a33\u5b9a\u7ed3\u6784 Lv.%d\r\n"), rogueStats.stableStructureLevel);
|
||||||
@@ -1187,7 +1233,7 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
SelectObject(hdc, smallFont);
|
SelectObject(hdc, smallFont);
|
||||||
SetTextColor(hdc, RGB(128, 104, 118));
|
SetTextColor(hdc, RGB(128, 104, 118));
|
||||||
TextOut(hdc, panelRect.left + SS(24), hintTop, _T("M \uff1a\u8fd4\u56de\u83dc\u5355"), lstrlen(_T("M \uff1a\u8fd4\u56de\u83dc\u5355")));
|
TextOut(hdc, panelRect.left + SS(24), hintTop, _T("M \uff1a\u8fd4\u56de\u83dc\u5355"), lstrlen(_T("M \uff1a\u8fd4\u56de\u83dc\u5355")));
|
||||||
TextOut(hdc, panelRect.left + SS(24), hintTop + SS(32), _T("\u89c4\u5219\u8bf4\u660e\u8bf7\u5728\u4e3b\u83dc\u5355\u8fdb\u5165"), lstrlen(_T("\u89c4\u5219\u8bf4\u660e\u8bf7\u5728\u4e3b\u83dc\u5355\u8fdb\u5165")));
|
TextOut(hdc, panelRect.left + SS(24), hintTop + SS(32), _T("Z \u9ed1\u6d1e X \u6e05\u5c4f\u70b8\u5f39 V \u7a7a\u4e2d\u6362\u5f62"), lstrlen(_T("Z \u9ed1\u6d1e X \u6e05\u5c4f\u70b8\u5f39 V \u7a7a\u4e2d\u6362\u5f62")));
|
||||||
|
|
||||||
if (feedbackState.visibleTicks > 0)
|
if (feedbackState.visibleTicks > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
|
|
||||||
| 状态 | 数量 |
|
| 状态 | 数量 |
|
||||||
|---|---:|
|
|---|---:|
|
||||||
| 已完成 | 20 |
|
| 已完成 | 28 |
|
||||||
| 部分完成 | 5 |
|
| 部分完成 | 5 |
|
||||||
| 未完成 | 10 |
|
| 未完成 | 2 |
|
||||||
|
|
||||||
## 已完成
|
## 已完成
|
||||||
|
|
||||||
@@ -25,19 +25,27 @@
|
|||||||
| 额外预览 | 基础 | 预览数量增加,当前最多到 3 个 | 基础出现 |
|
| 额外预览 | 基础 | 预览数量增加,当前最多到 3 个 | 基础出现 |
|
||||||
| 暂存槽 | 基础 | 解锁 Hold | 基础出现 |
|
| 暂存槽 | 基础 | 解锁 Hold | 基础出现 |
|
||||||
| 最后一搏 | 基础 | 濒死时自动清除底部 3 行并续命一次 | 基础出现 |
|
| 最后一搏 | 基础 | 濒死时自动清除底部 3 行并续命一次 | 基础出现 |
|
||||||
|
| 成长核心 | 基础 | 选择后永久提高 15% 得分和 15% EXP 获取,只能选择一次 | 基础出现 |
|
||||||
| 激光方块 | 爽感 | 特殊激光块落地后清除整列 | 基础出现 |
|
| 激光方块 | 爽感 | 特殊激光块落地后清除整列 | 基础出现 |
|
||||||
|
| 十字方块 | 爽感 | 特殊方块落地后同时清除所在行与列 | 基础出现 |
|
||||||
| 连锁爆破 | 爽感 | 消行后额外清除附近若干格 | 炸弹方块 |
|
| 连锁爆破 | 爽感 | 消行后额外清除附近若干格 | 炸弹方块 |
|
||||||
| 雷霆四消 | 爽感 | 四消时额外清除随机 2 行 | 激光方块 |
|
| 雷霆四消 | 爽感 | 四消时额外清除随机 2 行 | 激光方块 |
|
||||||
| 暴走堆叠 | 爽感 | 连击越高得分倍率越高 | 基础出现 |
|
| 暴走堆叠 | 爽感 | 连击越高得分倍率越高 | 基础出现 |
|
||||||
| 清屏炸弹 | 爽感 | 累计消行充能,获得可主动释放的底部 5 行清屏 | 基础出现 |
|
| 清屏炸弹 | 爽感 | 累计消行充能,获得可主动释放的底部 5 行清屏 | 基础出现 |
|
||||||
|
| 升级冲击波 | 爽感 | 每次升级时自动清除底部 2 行 | 积分倍率 + 经验强化 + 减压 |
|
||||||
|
| 黑洞 | 爽感 | 获得有限次数主动技能,释放后清除棋盘中数量最多的一种方块 | 基础出现 |
|
||||||
|
| 方块风暴 | 爽感 | 接下来 5 个方块全部变成 I 方块 | 基础出现 |
|
||||||
| 完美旋转 | 操作 | 旋转失败时自动尝试左右各偏移 1 格修正 | 基础出现 |
|
| 完美旋转 | 操作 | 旋转失败时自动尝试左右各偏移 1 格修正 | 基础出现 |
|
||||||
|
| 空中换形 | 操作 | 获得有限次数主动技能,可将当前方块变为 I 方块 | 基础出现 |
|
||||||
| 赌徒 | 风险 | 选强化时概率双倍生效,也可能落空 | 基础出现 |
|
| 赌徒 | 风险 | 选强化时概率双倍生效,也可能落空 | 基础出现 |
|
||||||
| 双重选择 | 风险 | 升级时可额外再选 1 个强化,下次升级需求提高 30% | 基础出现 |
|
| 双重选择 | 风险 | 升级时可额外再选 1 个强化,下次升级需求提高 30% | 基础出现 |
|
||||||
| 高压奖励 | 风险 | 下落速度提高 15%,得分和 EXP 额外提高 50% | 基础出现 |
|
| 高压奖励 | 风险 | 下落速度提高 15%,得分和 EXP 额外提高 50% | 基础出现 |
|
||||||
| 连环炸弹 | 进化 | 爆炸范围提升到 5x5,触发消行时追加一次小爆炸 | 炸弹方块 + 连锁爆破 |
|
| 连环炸弹 | 进化 | 爆炸范围提升到 5x5,触发消行时追加一次小爆炸 | 炸弹方块 + 连锁爆破 |
|
||||||
| 雷霆激光 | 进化 | 四消时额外发射 2 道激光并获得额外 EXP | 激光方块 + 雷霆四消 |
|
| 雷霆激光 | 进化 | 四消时额外发射 2 道激光并获得额外 EXP | 激光方块 + 雷霆四消 |
|
||||||
|
| 进化冲击 | 进化 | 升级时清除底部 3 行并获得 10 秒双倍经验 | 升级冲击波 + 成长核心 |
|
||||||
| 无限狂热 | 进化 | 狂热期间消行延长时间,四消额外延长,连击加成更强 | 狂热模式 + 暴走堆叠 |
|
| 无限狂热 | 进化 | 狂热期间消行延长时间,四消额外延长,连击加成更强 | 狂热模式 + 暴走堆叠 |
|
||||||
| 终末清场 | 进化 | 触发最后一搏时自动释放一次清屏炸弹,并进入狂热 | 清屏炸弹 + 最后一搏 |
|
| 终末清场 | 进化 | 触发最后一搏时自动释放一次清屏炸弹,并进入狂热 | 清屏炸弹 + 最后一搏 |
|
||||||
|
| 操控大师 | 进化 | Hold 后短时间减速、旋转失败自动修正、增加一个预览 | 完美旋转 + 暂存槽 |
|
||||||
| 命运轮盘 | 进化 | 升级出现 5 个选项,可选 2 个,其中 1 个附带诅咒 | 赌徒 + 双重选择 |
|
| 命运轮盘 | 进化 | 升级出现 5 个选项,可选 2 个,其中 1 个附带诅咒 | 赌徒 + 双重选择 |
|
||||||
|
|
||||||
## 部分完成
|
## 部分完成
|
||||||
@@ -54,30 +62,20 @@
|
|||||||
|
|
||||||
| 强化 | 分类 | 目标效果 | 升级路径 |
|
| 强化 | 分类 | 目标效果 | 升级路径 |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| 成长核心 | 基础 | 选择后永久提高 15% 得分和 15% EXP 获取,只能选择一次 | 基础出现 |
|
|
||||||
| 十字方块 | 爽感 | 特殊方块落地后同时清除所在行与列 | 基础出现 |
|
|
||||||
| 彩虹方块 | 爽感 | 可替代任意方块格子,用于补齐消行 | 基础出现 |
|
| 彩虹方块 | 爽感 | 可替代任意方块格子,用于补齐消行 | 基础出现 |
|
||||||
| 升级冲击波 | 爽感 | 每次升级时自动清除底部 2 行 | 积分倍率 + 经验强化 + 减压 |
|
|
||||||
| 黑洞 | 爽感 | 清除棋盘中数量最多的一种方块 | 基础出现 |
|
|
||||||
| 方块风暴 | 爽感 | 进入短时模式,接下来 5 个方块全部变成 I 方块 | 基础出现 |
|
|
||||||
| 空中换形 | 操作 | 将当前方块变成指定方块,使用次数有限 | 基础出现 |
|
|
||||||
| 进化冲击 | 进化 | 升级时清除更多行并获得双倍经验 | 升级冲击波 + 成长核心 |
|
|
||||||
| 操控大师 | 进化 | Hold 后短时间减速、旋转失败自动修正、增加一个预览 | 完美旋转 + 暂存槽 |
|
|
||||||
| 虚空核心 | 进化 | 黑洞和彩虹方块互相触发,小型黑洞追加清除 | 黑洞 + 彩虹方块 |
|
| 虚空核心 | 进化 | 黑洞和彩虹方块互相触发,小型黑洞追加清除 | 黑洞 + 彩虹方块 |
|
||||||
|
|
||||||
## 备注
|
## 备注
|
||||||
|
|
||||||
| 强化 | 备注 |
|
| 强化 | 备注 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| 成长核心 | 当前代码里有 `双倍成长`,但它不是这里规划的“一次性 +15% 得分 / +15% EXP”版本,不能直接算作已完成 |
|
|
||||||
| 升级冲击波 | 现在按新规划处理为 `积分倍率 + 经验强化 + 减压` 的升级强化,不再作为基础强化单独出现 |
|
| 升级冲击波 | 现在按新规划处理为 `积分倍率 + 经验强化 + 减压` 的升级强化,不再作为基础强化单独出现 |
|
||||||
| 幽灵落点 | 常规功能已存在,后续不纳入 Rogue 强化池实现范围 |
|
| 幽灵落点 | 常规功能已存在,后续不纳入 Rogue 强化池实现范围 |
|
||||||
| 精准控制 | 因 `幽灵落点` 不纳入强化池,当前版本也不再作为后续必做强化 |
|
| 精准控制 | 因 `幽灵落点` 不纳入强化池,当前版本也不再作为后续必做强化 |
|
||||||
| 空中换形 | 当前代码里没有对应主动技能入口,也没有变形库存或使用次数系统 |
|
|
||||||
|
|
||||||
## 推荐下一批实现顺序
|
## 推荐下一批实现顺序
|
||||||
|
|
||||||
1. `成长核心 + 升级冲击波 + 进化冲击`
|
1. `彩虹方块 + 虚空核心`
|
||||||
2. `十字方块 / 方块风暴 / 空中换形`
|
2. `炸弹方块` 出现机制对齐为“每隔 10 个方块”
|
||||||
3. `彩虹方块 + 黑洞 + 虚空核心`
|
3. `狂热模式` 补上“特殊方块出现率提高”
|
||||||
4. `操控大师`
|
4. `极限玩家` 补上“30 秒未四消增加危险等级”
|
||||||
|
|||||||
Reference in New Issue
Block a user