Files
jminos/src/Core/GameParameters.cpp
2025-03-03 22:34:46 +01:00

245 lines
6.7 KiB
C++

#include "GameParameters.h"
#include "Gamemode.h"
#include "Player.h"
GameParameters::GameParameters(Gamemode gamemode, const Player& controls) :
gamemode(gamemode),
controls(controls) {
this->reset();
}
void GameParameters::reset() {
this->clearedLines = 0;
switch (this->gamemode) {
// lowest gravity
case SPRINT : {this->level = 1; break;}
// lowest gravity
case ULTRA : {this->level = 1; break;}
// goes from level 1 to 20
case MARATHON : {this->level = 1; break;}
// goes from level 20 to 39
case MASTER : {this->level = 20; break;}
default : this->level = 1;
}
this->updateStats();
}
void GameParameters::clearLines(int lineNumber) {
switch (this->gamemode) {
// modes where level increases
case MARATHON :
case MASTER : {
int previousLines = this->clearedLines;
this->clearedLines += lineNumber;
// level increments every 10 lines, stats only changes on level up
if (previousLines / 10 < this->clearedLines / 10) {
this->level = this->clearedLines / 10;
this->updateStats();
}
break;
}
// other modes
default : this->clearedLines += lineNumber;
}
}
bool GameParameters::hasWon(int framesPassed) const {
switch (this->gamemode) {
// win once 40 lines have been cleared
case SPRINT : return this->clearedLines >= 40;
// win once 2mn have passed
case ULTRA : return (framesPassed / 60) >= 120;
// win once 200 lines have been cleared
case MARATHON : return this->clearedLines >= 200;
// win once 200 lines have been cleared
case MASTER : return this->clearedLines >= 200;
default : return false;
}
}
void GameParameters::updateStats() {
/* NEXT QUEUE */
switch (this->gamemode) {
// 5 for rapidity gamemodes
case SPRINT :
case ULTRA : {
this->nextQueueLength = 5;
break;
}
// 3 for endurance gamemodes
case MARATHON :
case MASTER : {
this->nextQueueLength = 3;
break;
}
default : this->nextQueueLength = 1;
}
/* BONE BLOCKS */
switch (this->gamemode) {
// blocks turns into bone blocks at level 30
case MASTER : this->boneBlocks = (this->level >= 30);
default : this->boneBlocks = false;
}
/* GRAVITY */
// get gravity for an assumed 20-rows board
static const int gravityPerLevel[] = {
0, // lvl0 = no gravity
1, // 60f/line, 20s total
2, // 30f/line, 10s total
3, // 20f/line, 6.66s total
4, // 15f/line, 5s total
5, // 12f/line, 4s total
6, // 10f/line, 3.33 total
7, // 8.57f/line, 2.85s total
8, // 7.5f/line, 2.5s total
10, // 6f/line, 2s total
12, // 5f/line, 1.66s total
14, // 4.28f/line, 1.42s total
17, // 3.52f/line, 1.17s total
20, // 3f/line, 60f total
24, // 2.5f/line, 50f total
30, // 2f/line, 40f total
40, // 1.5f/line, 30f total
1 * 60, // 1line/f, 20f total
2 * 60, // 2line/f, 10f total
4 * 60, // 4line/f, 5f total
20 * 60 // lvl20 = instant gravity
};
if (this->level < 0) {
this->gravity = gravityPerLevel[0];
}
else if (this->level > 20) {
this->gravity = gravityPerLevel[20];
}
else {
this->gravity = gravityPerLevel[this->level];
}
/* LOCK DELAY */
switch (this->gamemode) {
// starts at 500ms (30f) at lvl 20 and ends at 183ms (11f) at lvl 39
case MASTER : {this->lockDelay = 30 - (this->level - 20); break;}
// 1s by default
default : this->lockDelay = 60;
}
/* FORCED LOCK DELAY */
this->forcedLockDelay = this->lockDelay * 10;
/* ARE */
switch (this->gamemode) {
// starts at 400ms (24f) at lvl 1 and ends at 083ms (5f) at lvl 20
case MARATHON : {this->ARE = 24 - (this->level - 1); break;}
// starts at 400ms (24f) at lvl 20 and ends at 083ms (5f) at lvl 39
case MASTER : {this->ARE = 24 - (this->level - 20); break;}
// no ARE by default
default : this->ARE = 0;
}
/* LINE ARE */
this->lineARE = this->ARE * 2;
/* DAS */
this->DAS = this->controls.getDAS();
switch (this->gamemode) {
// for modes with reduced lock delay, ensure DAS is lower than lock delay, but at least 1
case MASTER : {
if (this->lockDelay <= this->DAS) {
this->DAS = this->lockDelay - 6; // give 6f (100ms) to change directions
}
if (this->DAS < 1) {
this->DAS = 1;
}
break;
}
// modes with no reduced lock delay
default : break;
}
/* ARR */
this->ARR = this->controls.getARR();
switch (this->gamemode) {
// for modes with reduced lock delay, ensure ARR is lower than DAS, but not lower than 1
case MASTER : {
if (this->DAS <= this->ARR) {
this->ARR = this->DAS - 1;
}
if (this->ARR < 1) {
this->ARR = 1;
}
break;
}
// modes with no reduced lock delay
default : break;
}
/* SDR */
this->SDR = this->controls.getSDR();
switch (this->gamemode) {
// modes where we don't want instant soft drop to be possible
case MARATHON : {
if (this->SDR < 1) {
this->SDR = 1;
}
break;
}
// modes where we don't care
default : break;
}
}
int GameParameters::getClearedLines() const {
return this->clearedLines;
}
int GameParameters::getLevel() const {
return this->level;
}
int GameParameters::getNextQueueLength() const {
return this->nextQueueLength;
}
bool GameParameters::getBoneBlocks() const {
return this->boneBlocks;
}
int GameParameters::getGravity() const {
return this->gravity;
}
int GameParameters::getLockDelay() const {
return this->lockDelay;
}
int GameParameters::getForcedLockDelay() const {
return this->forcedLockDelay;
}
int GameParameters::getARE() const {
return this->ARE;
}
int GameParameters::getLineARE() const {
return this->lineARE;
}
int GameParameters::getDAS() const {
return this->DAS;
}
int GameParameters::getARR() const {
return this->ARR;
}
int GameParameters::getSDR() const {
return this->SDR;
}