Skip to content

Commit

Permalink
v1.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
RayDeeUx committed Dec 5, 2024
1 parent 9c0dc00 commit 8658a83
Show file tree
Hide file tree
Showing 10 changed files with 253 additions and 230 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ project(DeathScreenTweaks VERSION 1.0.0)

add_library(${PROJECT_NAME} SHARED
src/main.cpp
src/MenuLayer.cpp
src/PlayLayer.cpp
src/FLAlertLayer.cpp
src/PlayerObject.cpp
src/Manager.cpp
src/Manager.hpp
src/Settings.cpp
src/Settings.hpp
# Add your cpp files here
Expand Down
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# DeathScreenTweaks Changelog
## v1.5.0
- Refactor source code into multiple files.
## v1.4.3
- Port to 2.2074.
## v1.4.2
Expand Down
6 changes: 3 additions & 3 deletions mod.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"geode": "4.0.0-beta.1",
"geode": "4.0.1",
"gd": {
"mac": "2.2074",
"android": "2.2074",
"win": "2.2074"
},
"version": "v1.4.3",
"version": "v1.5.0",
"id": "raydeeux.deathscreentweaks",
"name": "DeathScreenTweaks",
"developers": ["RayDeeUx", "sofabeddd"],
Expand Down Expand Up @@ -79,7 +79,7 @@
},
"customFont": {
"name": "\"New Best\" Text Font #",
"description": "Sets the font of all \"New Best\" death messages. Default is 0 (falls back to <cl>goldFont</c>, as seen in vanilla Geometry Dash).\n\nNotes:\n- <cj>-1 for Pusab, -2 for chatFont, and -3 for Oxygene One (the font used to resemble the original \"New Best\" font,</c> <cl>suggested by Saritahh</c><cj>).</c>\n- <cy>To use font numbers greater than 0: refer to the level editor for the font each number corresponds to, subtract that number by 1, and then put it here.</c>\n<cl>- If using Oxygene One/-3, singular quotation marks/apostrophes (') will not be displayed. This is a problem from Jakob Fischer, the designer of the Oxygene One font.</c>",
"description": "Sets the font of all \"New Best\" death messages. Default is 0 (falls back to <cl>goldFont</c>, as seen in vanilla Geometry Dash).\n\nNotes:\n- <cj>-1 for Pusab, -2 for chatFont, and -3 for Oxygene One (the font used to resemble the original \"New Best\" font,</c> <cl>suggested by Saritahh</c><cj>).</c>\n- <cy>To use font numbers greater than 0: refer to the level editor for the font each number corresponds to, subtract that number by 1, and then put it here.</c>\n<cl>- If using Oxygene One/-3, double quotation marks (\") will not be displayed. This is a problem from Jakob Fischer, the designer of the Oxygene One font.</c>",
"type": "int",
"default": 0,
"min": -3,
Expand Down
18 changes: 18 additions & 0 deletions src/FLAlertLayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <Geode/modify/FLAlertLayer.hpp>

#define PREFERRED_HOOK_PRIO (-2123456789)

using namespace geode::prelude;class $modify(MyFLAlertLayer, FLAlertLayer) {
static void onModify(auto & self)
{
(void) self.setHookPriority("FLAlertLayer::init", PREFERRED_HOOK_PRIO);
}
bool init(FLAlertLayerProtocol* delegate, char const* title, gd::string desc, char const* btn1, char const* btn2, float width, bool scroll, float height, float textScale) {
const std::string& titleAsString = title;
const std::string& descAsString = desc;
if (titleAsString != "\"New Best\" Text Font #" && !utils::string::contains(descAsString, "To use font numbers greater than 0: refer to the level editor for the font each number corresponds to, subtract that number by 1, and then put it here.") && !utils::string::contains(descAsString, "suggested by Saritahh") && !utils::string::contains(descAsString, "If using Oxygene One")) {
return FLAlertLayer::init(delegate, title, desc, btn1, btn2, width, scroll, height, textScale);
}
return FLAlertLayer::init(delegate, title, desc, btn1, btn2, 420.f, true, 320.f, 1.0f);
}
};
3 changes: 3 additions & 0 deletions src/Manager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "Manager.hpp"

Manager* Manager::instance = nullptr;
33 changes: 33 additions & 0 deletions src/Manager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include <regex>

// Manager.hpp structure by acaruso
// reused with explicit permission and strong encouragement

using namespace geode::prelude;

class Manager {

protected:
static Manager* instance;
public:

bool calledAlready = false;

std::regex percentRegex = std::regex(R"(^(\d+)%$)");

std::vector<std::string> quotes;
std::vector<std::string> customQuotes;
std::vector<std::string> dNBMigration;

bool completedJDDNCheck = false;

static Manager* getSharedInstance() {
if (!instance) {
instance = new Manager();
}
return instance;
}

};
26 changes: 26 additions & 0 deletions src/MenuLayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <Geode/modify/MenuLayer.hpp>
#include "Manager.hpp"

#define getBool Mod::get()->getSettingValue<bool>
#define manager Manager::getSharedInstance()

using namespace geode::prelude;

class $modify(MyMenuLayer, MenuLayer) {
void forceEnableJustDont() {
auto gm = GameManager::sharedState();
if (!gm->getGameVariable("0095")) {
gm->setGameVariable("0095", true);
Mod::get()->setSettingValue("checkJustDont", false);
log::info("\"Just Dont\"/\"Do Not\" check complete.");
}
}
bool init() {
bool result = MenuLayer::init();
if (!manager->completedJDDNCheck && getBool("enabled") && getBool("checkJustDont")) {
MyMenuLayer::forceEnableJustDont();
}
manager->completedJDDNCheck = true;
return result;
}
};
90 changes: 90 additions & 0 deletions src/PlayLayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <Geode/modify/PlayLayer.hpp>
#include <iostream>
#include <algorithm>
#include <random>
#include "Manager.hpp"

#define getModBool Mod::get()->getSettingValue<bool>
#define getModString Mod::get()->getSettingValue<std::string>
#define getModInt Mod::get()->getSettingValue<int64_t>
#define manager Manager::getSharedInstance()

class $modify(MyPlayLayer, PlayLayer) {
static std::string grabRandomQuote(std::vector<std::string> vector = manager->quotes) {
std::mt19937 randomSeed(std::random_device{}());
std::shuffle(vector.begin(), vector.end(), randomSeed);
return vector.front();
}
static bool isNewBest(PlayLayer* pl) {
return pl->getCurrentPercentInt() > pl->m_level->m_normalPercent.value();
}
void updateProgressbar() {
PlayLayer::updateProgressbar();
if (!getModBool("enabled") || m_level->isPlatformer() || !m_player1->m_isDead || m_isPlatformer) return;
for (int i = getChildrenCount() - 1; i >= 0; i--) {
// NEW [good]: int i = getChildrenCount() - 1; i >= 0; i--
// ORIG [bad]: int i = getChildrenCount(); i-- > 0;
auto theLastCCNode = typeinfo_cast<CCNode*>(this->getChildren()->objectAtIndex(i));
if (typeinfo_cast<CurrencyRewardLayer*>(theLastCCNode) != nullptr) {
// hide CurrencyRewardLayer
theLastCCNode->setVisible(!getModBool("currencyLayer"));
continue;
}
if (theLastCCNode == nullptr || typeinfo_cast<UILayer*>(theLastCCNode) != nullptr) continue; // skip UILayer
if (theLastCCNode->getZOrder() != 100) continue;
if (theLastCCNode->getChildrenCount() < 2) continue;
if (getModBool("noVisibleNewBest")) return theLastCCNode->setVisible(false);
for (const auto child : CCArrayExt<CCNode*>(theLastCCNode->getChildren())) {
const auto node = typeinfo_cast<CCLabelBMFont*>(child);
if (!node) continue;
std::string nodeString = node->getString();
std::string fontFile = node->getFntFile();
if (nodeString.ends_with("%") && fontFile == "bigFont.fnt") {
if (MyPlayLayer::isNewBest(this) && getModBool("accuratePercent")) { return node->setString(fmt::format("{:.{}f}%", getCurrentPercent(), getModInt("accuracy")).c_str()); }
// i have to do all of this because robtop's wonderful technology shows percent from previous death if i dont include all of this
std::smatch match;
if (!std::regex_match(nodeString, match, manager->percentRegex)) { continue; }
auto percent = std::regex_replace(nodeString, std::regex("%"), "");
auto percentAsInt = utils::numFromString<int>(percent);
if (percentAsInt.isErr()) continue;
auto currPercent = this->getCurrentPercentInt();
if (getModBool("logging")) {
log::info("percentAsInt == currentPercentInt: {}", percentAsInt.unwrap() == currPercent);
log::info("percentAsInt: {}", percentAsInt.unwrap());
log::info("getCurrentPercentInt: {}", currPercent);
}
if (!getModBool("accuratePercent")) node->setString(fmt::format("{}%", currPercent).c_str());
else node->setString(fmt::format("{:.{}f}%", getCurrentPercent(), getModInt("accuracy")).c_str());
continue;
}
std::string randomString = grabRandomQuote();
if (!manager->customQuotes.empty() && getModBool("customTextsOnly")) randomString = grabRandomQuote(manager->customQuotes);
if (fontFile != "goldFont.fnt" || std::ranges::find(manager->quotes, nodeString) != manager->quotes.end() || randomString.empty()) continue; // avoid regenerating new quotes
if (getModBool("hideNewBestMessages")) {
node->setVisible(false);
continue;
}
auto fontID = getModInt("customFont");
if (fontID == -3) {
node->setFntFile("newBestFont.fnt"_spr);
node->setExtraKerning(4);
randomString = utils::string::toUpper(randomString); // oxygene one does not support lowercase chars
randomString = utils::string::replace(randomString, "\"", "\'\'"); // oxygene one does not support `"` char
}
if (getModBool("changeDeathText")) node->setString(randomString.c_str(), true);
if (getModBool("lineWrapping")) {
node->setAlignment(CCTextAlignment::kCCTextAlignmentCenter); // center text
float scale = .25f * (155.f / randomString.length());
if (scale > Mod::get()->getSettingValue<double>("maxScale")) scale = Mod::get()->getSettingValue<double>("maxScale");
node->setWidth(420.f); // width of end screen minus 20px, not marajuana referenec
node->setScale(scale);
} else { node->limitLabelWidth(420.f, 10.f, .25f); } // you never know how long these custom strings might get
if (fontID == -2) node->setFntFile("chatFont.fnt");
else if (fontID == -1) node->setFntFile("bigFont.fnt");
else if (fontID != 0 && fontID != -3) node->setFntFile(fmt::format("gjFont{:02d}.fnt", fontID).c_str());
node->setAlignment(kCCTextAlignmentCenter);
if (fontID != 0 && fontID != -3 && getModBool("customFontGoldColor")) node->setColor({254, 207, 6});
}
}
}
};
52 changes: 52 additions & 0 deletions src/PlayerObject.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <Geode/modify/PlayerObject.hpp>
#include <filesystem>

#define getBool Mod::get()->getSettingValue<bool>
#define getString Mod::get()->getSettingValue<std::string>
#define getInt Mod::get()->getSettingValue<int64_t>

using namespace geode::prelude;

class $modify(MyPlayerObject, PlayerObject) {
static bool isNewBest(PlayLayer* pl) {
return pl->getCurrentPercentInt() > pl->m_level->m_normalPercent.value();
}
void playerDestroyed(bool p0) {
PlayerObject::playerDestroyed(p0);
if (!getBool("enabled")) return;
const auto pl = PlayLayer::get();
if (!pl) return;
if (this != pl->m_player1) return;
const auto theLevel = pl->m_level;
if (!theLevel || theLevel->isPlatformer()) return;
if (this == pl->m_player2 && theLevel->m_twoPlayerMode) return;
bool qualifiedForAlwaysNewBest = false;
// splitting it into three if statements for readability
if (!pl->m_isTestMode && !pl->m_isPracticeMode && getBool("alwaysNewBest") && !isNewBest(pl)) qualifiedForAlwaysNewBest = true;
if (getBool("alwaysNewBestPlaytest") && pl->m_isTestMode) qualifiedForAlwaysNewBest = true;
if (getBool("alwaysNewBestPractice") && pl->m_isPracticeMode) qualifiedForAlwaysNewBest = true;
if (getBool("logging")) {
log::info("pl->getCurrentPercentInt() <= pl->m_level->m_normalPercent.value(): {}", pl->getCurrentPercentInt() <= pl->m_level->m_normalPercent.value());
log::info("pl->getCurrentPercentInt(): {}", pl->getCurrentPercentInt());
log::info("pl->m_level->m_normalPercent.value(): {}", pl->m_level->m_normalPercent.value());
}
if (qualifiedForAlwaysNewBest) pl->showNewBest(true, 0, 0, false, false, false);
if (!getBool("newBestSFX") || MyPlayerObject::isNewBest(pl) || pl->m_isTestMode || pl->m_isPracticeMode) return; // shouldnt play new best sfx in practice/testmode
const auto fmod = FMODAudioEngine::get();
if (!fmod) { return; }
if (const auto newBestSFXFile = Mod::get()->getConfigDir() / fmt::format("newBest.{}", getString("extension")); std::filesystem::exists(newBestSFXFile)) {
if (getBool("logging")) {
log::info("newBestSFXFile: {}", newBestSFXFile.string());
log::info("getString(\"extension\"): {}", getString("extension"));
}
auto system = fmod->m_system;
FMOD::Channel* channel;
FMOD::Sound* sound;
system->createSound(newBestSFXFile.string().c_str(), FMOD_DEFAULT, nullptr, &sound);
system->playSound(sound, nullptr, false, &channel);
channel->setVolume(getInt("newBestVolume") / 100.0f);
} else if (theLevel->m_stars.value() == 0) {
fmod->playEffect("magicExplosion.ogg");
}
}
};
Loading

0 comments on commit 8658a83

Please sign in to comment.