Skip to content

Commit

Permalink
v1.1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
hiimjasmine00 committed Jul 18, 2024
1 parent 1ff4398 commit 2b7f74b
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 14 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
set(CMAKE_CXX_VISIBILITY_PRESET hidden)

project(DemonsInBetween VERSION 1.1.4)
project(DemonsInBetween VERSION 1.1.5)

add_library(${PROJECT_NAME} SHARED
src/DemonsInBetween.cpp
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ A mod that adds additional demon difficulties in between existing ones.
# Features
- Fifteen new demon difficulties in between the five existing ones, determined using the [Geometry Dash Demon Ladder](https://gdladder.com)
- A quick search popup in the level search menu for the new demon difficulties
- Difficulty reloading in the level info page, using the refresh button

# Credits
- [SufficientEbb](https://gdbrowser.com/u/20865884) - Idea for the mod
Expand Down
1 change: 1 addition & 0 deletions about.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ A mod that adds additional demon difficulties in between existing ones.
# Features
- Fifteen new demon difficulties in between the five existing ones, determined using the [Geometry Dash Demon Ladder](https://gdladder.com)
- A quick search popup in the level search menu for the new demon difficulties
- Difficulty reloading in the level info page, using the refresh button

# Credits
- [SufficientEbb](user:20865884) - Idea for the mod
Expand Down
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Demons In Between Changelog
## v1.1.5 (2024-07-18)
- Added cache refreshing for a level's demon difficulty under the refresh button in the level info page

## v1.1.4 (2024-07-11)
- Added some compatibility with the mod "GodlikeFaces" by adyagmd

Expand Down
2 changes: 1 addition & 1 deletion mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"win": "2.206",
"mac": "2.206"
},
"version": "v1.1.4",
"version": "v1.1.5",
"id": "hiimjustin000.demons_in_between",
"name": "Demons In Between",
"developer": "hiimjustin000",
Expand Down
55 changes: 48 additions & 7 deletions src/DemonsInBetween.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void DemonsInBetween::tryLoadCache() {
loadGDDL();
return;
}

std::stringstream bufferStream;
bufferStream << file.rdbuf();

Expand All @@ -27,7 +27,7 @@ void DemonsInBetween::tryLoadCache() {
loadGDDL();
return;
}

auto cache = json.value();
if (!cache.contains("cached") || !cache["cached"].is_number() || !cache.contains("list") || !cache["list"].is_array()) {
log::error("GDDL cache is corrupted, loading from spreadsheet");
Expand All @@ -42,6 +42,7 @@ void DemonsInBetween::tryLoadCache() {
return;
}

GDDL_CACHE = cache;
initGDDL(cache["list"].as_array());
}

Expand All @@ -64,10 +65,8 @@ void DemonsInBetween::loadGDDL() {

void DemonsInBetween::initGDDL(matjson::Array const& gddl, bool saveCache) {
if (saveCache) {
auto file = std::fstream(CACHE_PATH, std::ios::out);
file << matjson::Value(matjson::Object({ { "cached", time(0) }, { "list", gddl } })).dump(0);
file.close();
log::info("Successfully saved GDDL cache");
GDDL_CACHE = matjson::Object({ { "cached", time(0) }, { "list", gddl } });
saveGDDL();
}

for (auto const& demon : gddl) {
Expand All @@ -76,6 +75,13 @@ void DemonsInBetween::initGDDL(matjson::Array const& gddl, bool saveCache) {
}
}

void DemonsInBetween::saveGDDL() {
auto file = std::fstream(CACHE_PATH, std::ios::out);
file << GDDL_CACHE.dump(0);
file.close();
log::info("Successfully saved GDDL cache");
}

matjson::Array const& DemonsInBetween::parseGDDL(std::string const& data) {
// MAKE SURE WE ARE NOT SPLITTING THE COMMAS IN THE QUOTATION MARKS
auto lines = string::split(data, "\n");
Expand All @@ -88,7 +94,7 @@ matjson::Array const& DemonsInBetween::parseGDDL(std::string const& data) {
auto key = keys[j];
auto value = values[j];
if (key == "ID") demon[key] = std::stoi(value);
else if (key == "Tier" || key == "Enjoyment") demon[key] = value != "" ? std::stod(value) : matjson::Value(nullptr);
else if (key == "Tier" || key == "Enjoyment") demon[key] = value != "" ? round(std::stod(value) * 100) / 100 : matjson::Value(nullptr);
else demon[key] = value;
}
demons.push_back(demon);
Expand All @@ -105,6 +111,41 @@ LadderDemon const& DemonsInBetween::demonForLevel(GJGameLevel* level) {
return demon == GDDL.end() ? defaultDemon : *demon;
}

void DemonsInBetween::refreshDemonForLevel(EventListener<web::WebTask>&& listenerRef, GJGameLevel* level, MiniFunction<void(LadderDemon const&)> callback) {
auto levelID = level->m_levelID.value();
auto demon = std::find_if(GDDL.begin(), GDDL.end(), [levelID](auto const& d) {
return d.id == levelID;
});
if (demon == GDDL.end()) return;

auto&& listener = std::move(listenerRef);
listener.bind([callback, demon](web::WebTask::Event* e) {
if (auto res = e->getValue()) {
if (res->ok()) {
auto json = res->json().value();
if (json["Rating"].is_null()) return;

demon->difficulty = DIFFICULTY_INDICES[(int)round(json["Rating"].as_double())];

auto& cacheArray = GDDL_CACHE["list"].as_array();
auto cacheDemon = std::find_if(cacheArray.begin(), cacheArray.end(), [demon](matjson::Value const& d) {
return d["ID"].as_int() == demon->id;
});
if (cacheDemon != cacheArray.end()) {
cacheDemon->operator[]("Tier") = round(json["Rating"].as_double() * 100) / 100;
cacheDemon->operator[]("Enjoyment") = !json["Enjoyment"].is_null() ? round(json["Enjoyment"].as_double() * 100) / 100 : matjson::Value(nullptr);
GDDL_CACHE_CHANGED = true;
log::info("Updated demon with ID {}", demon->id);
} else log::error("Failed to update demon with ID {}", demon->id);

if (callback) callback(*demon);
}
}
});

listener.setFilter(web::WebRequest().get(fmt::format("https://gdladder.com/api/level/{}", demon->id).c_str()));
}

CCSprite* DemonsInBetween::spriteForDifficulty(GJDifficultySprite* difficultySprite, int difficulty, GJDifficultyName name, GJFeatureState state) {
auto glow = state == GJFeatureState::Legendary ? "_4" : "";
auto sprite = CCSprite::createWithSpriteFrameName((name == GJDifficultyName::Long ?
Expand Down
4 changes: 4 additions & 0 deletions src/DemonsInBetween.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class DemonsInBetween {
};
public:
inline static std::vector<LadderDemon> GDDL = {};
inline static matjson::Value GDDL_CACHE = {};
inline static bool GDDL_CACHE_CHANGED = false;
inline static bool TRIED_LOADING = false;
inline static int MAX_PAGE = 0;
inline static int DIFFICULTY = 0;
Expand All @@ -38,8 +40,10 @@ class DemonsInBetween {
static void tryLoadCache();
static void loadGDDL();
static void initGDDL(matjson::Array const&, bool saveCache = false);
static void saveGDDL();
static matjson::Array const& parseGDDL(std::string const&);
static LadderDemon const& demonForLevel(GJGameLevel*);
static void refreshDemonForLevel(EventListener<web::WebTask>&&, GJGameLevel*, MiniFunction<void(LadderDemon const&)>);
static CCSprite* spriteForDifficulty(GJDifficultySprite*, int, GJDifficultyName, GJFeatureState);
static GJFeatureState stateForLevel(GJGameLevel*);
static GJSearchObject* searchObjectForPage(int);
Expand Down
43 changes: 38 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "DIBSearchPopup.hpp"

$on_mod(DataSaved) {
if (DemonsInBetween::GDDL_CACHE_CHANGED) DemonsInBetween::saveGDDL();
}

#include <Geode/modify/MenuLayer.hpp>
class $modify(DIBMenuLayer, MenuLayer) {
bool init() {
Expand Down Expand Up @@ -44,24 +48,53 @@ class $modify(DIBLevelSearchLayer, LevelSearchLayer) {

#include <Geode/modify/LevelInfoLayer.hpp>
class $modify(DIBLevelInfoLayer, LevelInfoLayer) {
struct Fields {
EventListener<web::WebTask> m_listener;
bool m_disabled;
};

static void onModify(auto& self) {
(void)self.setHookPriority("LevelInfoLayer::init", -50);
(void)self.setHookPriority("LevelInfoLayer::init", -50); // gddp integration is -42 D:
}

bool init(GJGameLevel* level, bool challenge) {
if (!LevelInfoLayer::init(level, challenge)) return false;

if (getChildByID("grd-difficulty") || getChildByID("gddp-difficulty")) return true;
if (getChildByID("grd-difficulty") || getChildByID("gddp-difficulty")) {
m_fields->m_disabled = true;
return true;
}

auto& demon = DemonsInBetween::demonForLevel(level);
if (demon.id == 0) return true;

addChild(DemonsInBetween::spriteForDifficulty(m_difficultySprite, demon.difficulty,
GJDifficultyName::Long, DemonsInBetween::stateForLevel(level)), 3);
m_difficultySprite->setOpacity(0);
createDemonSprite(demon);

return true;
}

void createDemonSprite(LadderDemon const& demon) {
if (m_fields->m_disabled) return;

if (auto existingDifficulty = getChildByID("between-difficulty-sprite"_spr)) existingDifficulty->removeFromParentAndCleanup(true);
addChild(DemonsInBetween::spriteForDifficulty(m_difficultySprite, demon.difficulty, GJDifficultyName::Long, DemonsInBetween::stateForLevel(m_level)), 3);
m_difficultySprite->setOpacity(0);
}

void onUpdate(CCObject* sender) {
LevelInfoLayer::onUpdate(sender);
if (m_fields->m_disabled) return;

if (!m_isBusy && GameLevelManager::sharedState()->isTimeValid(std::to_string(m_level->m_levelID.value()).c_str(), 3600.0f))
DemonsInBetween::refreshDemonForLevel(std::move(m_fields->m_listener), m_level, [this](LadderDemon const& demon) { createDemonSprite(demon); });
}

void levelUpdateFinished(GJGameLevel* level, UpdateResponse response) override {
LevelInfoLayer::levelUpdateFinished(level, response);
if (m_fields->m_disabled) return;

DemonsInBetween::refreshDemonForLevel(std::move(m_fields->m_listener), level, [this](LadderDemon const& demon) { createDemonSprite(demon); });
}
};

#include <Geode/modify/LevelCell.hpp>
Expand Down

0 comments on commit 2b7f74b

Please sign in to comment.