Skip to content

Commit 1c106f2

Browse files
committed
mock thumbnail idek if this works
1 parent a3b4280 commit 1c106f2

4 files changed

Lines changed: 201 additions & 28 deletions

File tree

src/main.cpp

Lines changed: 115 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,103 @@
11
#include "popup/HorribleMenuPopup.hpp"
22

3+
#include <fmt/core.h>
4+
35
#include <Geode/Geode.hpp>
46

5-
#include <Geode/modify/CCMenuItem.hpp>
67
#include <Geode/modify/MenuLayer.hpp>
8+
#include <Geode/modify/CCLayer.hpp>
9+
#include <Geode/modify/CCMenuItem.hpp>
710

811
#include <Geode/binding/FMODAudioEngine.hpp>
912

1013
using namespace geode::prelude;
14+
using namespace geode::utils;
15+
using namespace matjson;
1116

1217
auto horribleMod = getMod();
1318

19+
class $modify(HorribleCCLayer, CCLayer) {
20+
bool init() {
21+
if (!CCLayer::init()) return false;
22+
23+
log::debug("Hooked Cocos layer {}", getID());
24+
25+
if (horribleMod && horribleMod->getSavedValue<bool>("mock", false)) {
26+
if (auto b = true) { // change to random chance
27+
auto mockConfigPath = fmt::format("{}\\mock.json", horribleMod->getSaveDir());
28+
auto mockConfig = file::readJson(std::filesystem::path(mockConfigPath));
29+
30+
if (mockConfig.isOk()) {
31+
auto mockConfigUnwr = mockConfig.unwrapOr(Value());
32+
33+
std::srand(static_cast<unsigned int>(std::time(nullptr)));
34+
int randInd = std::rand() % mockConfigUnwr.size(); // random index of the matjson
35+
36+
auto lvl = mockConfigUnwr.get(as<size_t>(randInd));
37+
38+
if (lvl.isOk()) {
39+
auto lvlUnwr = lvl.unwrap();
40+
41+
auto id = lvlUnwr.getKey().value_or("");
42+
auto percent = lvlUnwr.asInt().unwrapOr(99);
43+
44+
if (!id.empty()) {
45+
std::string path = fmt::format("{}\\{}.png", horribleMod->getSaveDir(), id);
46+
47+
// screenshot sprite
48+
auto ss = LazySprite::create({ 192.f, 108.f });
49+
ss->setID("mock"_spr);
50+
ss->setAnchorPoint({ 0.5, 0.5 });
51+
ss->setPosition({ -192.f, -108.f });
52+
53+
ss->setLoadCallback([this, ss, percent](Result<> res) {
54+
if (res.isOk()) {
55+
// Success: scale and position the sprite
56+
log::info("Sprite loaded successfully");
57+
58+
float yA = as<float>(std::rand()) / RAND_MAX; // first y pos %
59+
float yB = as<float>(std::rand()) / RAND_MAX; // last y pos %
60+
61+
auto percLabelText = fmt::format("{}%", std::to_string(percent));
62+
63+
auto percLabel = CCLabelBMFont::create(percLabelText.c_str(), "bigFont.fnt");
64+
percLabel->setPosition({ ss->getScaledContentWidth() / 2.f, ss->getScaledContentHeight() / 2.f });
65+
66+
ss->setPositionY(getScaledContentHeight() * yA);
67+
ss->setRotation(360.f * (yA * yB));
68+
69+
auto move = CCEaseIn::create(CCMoveTo::create(7.5f, { getScaledContentWidth() + 192.f, getScaledContentHeight() * yB }), 1.f);
70+
auto rotate = CCEaseOut::create(CCRotateBy::create(12.5f, 45.f), 1.f);
71+
72+
auto action = CCSpawn::createWithTwoActions(move, rotate);
73+
ss->runAction(action);
74+
75+
log::info("Animated sprite successfully");
76+
} else {
77+
log::error("Sprite failed to load: {}", res.unwrapErr());
78+
ss->removeMeAndCleanup();
79+
};
80+
});
81+
82+
ss->loadFromFile(std::filesystem::path(path));
83+
addChild(ss);
84+
};
85+
};
86+
};
87+
};
88+
};
89+
90+
return true;
91+
};
92+
};
93+
1494
// modify CCMenuItem so it plays the sound whenever a button is clicked regardless of the layer
15-
class $modify(HorribleMenuItem, CCMenuItem) {
95+
class $modify(HorribleCCMenuItem, CCMenuItem) {
1696
void activate() override {
1797
if (horribleMod && horribleMod->getSavedValue<bool>("achieve", true)) {
1898
if (auto fmod = FMODAudioEngine::sharedEngine()) {
1999
// @geode-ignore(unknown-resource)
20-
if ((rand() % 50) == 0) fmod->playEffect("achievement_01.ogg"); // 50/50 chance of playing
100+
if ((rand() % 75) == 0) fmod->playEffect("achievement_01.ogg"); // 75% chance of playing
21101
};
22102
};
23103

@@ -35,12 +115,14 @@ class $modify(MyMenuLayer, MenuLayer) {
35115
"GJ_moonsIcon_001.png",
36116
0.875f,
37117
CircleBaseColor::Green,
38-
CircleBaseSize::MediumAlt);
118+
CircleBaseSize::MediumAlt
119+
);
39120

40121
auto btn = CCMenuItemSpriteExtra::create(
41122
btnSprite,
42123
this,
43-
menu_selector(MyMenuLayer::onHorribleButton));
124+
menu_selector(MyMenuLayer::onHorribleButton)
125+
);
44126
btn->setID("horribleBtn");
45127

46128
if (auto menu = typeinfo_cast<CCMenu*>(bottomMenu)) {
@@ -49,6 +131,34 @@ class $modify(MyMenuLayer, MenuLayer) {
49131
};
50132
};
51133

134+
// TESTING
135+
136+
// DELETE LATER
137+
138+
auto ss = CCSprite::createWithSpriteFrameName("GJLargeLock_001.png");
139+
ss->setPosition({ -192.f, 108.f });
140+
ss->setZOrder(501);
141+
142+
addChild(ss);
143+
144+
float yA = as<float>(std::rand()) / RAND_MAX; // first y pos %
145+
float yB = as<float>(std::rand()) / RAND_MAX; // last y pos %
146+
147+
ss->setPositionY(getScaledContentHeight() * yA);
148+
ss->setRotation(360.f * (yA * yB));
149+
150+
auto move = CCEaseIn::create(CCMoveTo::create(7.5f, { getScaledContentWidth() + 192.f, getScaledContentHeight() * yB }), 1.f);
151+
auto rotate = CCEaseOut::create(CCRotateBy::create(12.5f, 45.f), 1.f);
152+
153+
auto action = CCSpawn::createWithTwoActions(move, rotate);
154+
ss->runAction(action);
155+
156+
log::info("Animated sprite successfully");
157+
158+
// DELETE LATER
159+
160+
// TESTING
161+
52162
return true;
53163
};
54164

src/modified/LevelManager.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ using namespace geode::prelude;
66
namespace LevelManager {
77
void DownloadGriefLevel() {
88
auto horribleMod = getMod();
9+
910
if (horribleMod->getSavedValue<bool>("grief", false)) {
1011
auto glm = GameLevelManager::get();
1112
auto mdm = MusicDownloadManager::sharedState();
@@ -25,9 +26,11 @@ namespace LevelManager {
2526

2627
void DownloadCongregLevel() {
2728
auto horribleMod = getMod();
29+
2830
if (horribleMod->getSavedValue<bool>("congregation", false)) {
2931
auto glm = GameLevelManager::get();
3032
auto mdm = MusicDownloadManager::sharedState();
33+
3134
auto level = glm->getSavedLevel(93437568);
3235

3336
if (glm->hasDownloadedLevel(93437568)) {

src/modified/PlayLayer.cpp

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <fmt/core.h>
2+
13
#include <Geode/Geode.hpp>
24

35
#include <Geode/utils/terminate.hpp>
@@ -8,6 +10,8 @@
810
#include "LevelManager.hpp"
911

1012
using namespace geode::prelude;
13+
using namespace geode::utils;
14+
using namespace matjson;
1115

1216
class $modify(HorriblePlayLayer, PlayLayer) {
1317
struct Fields {
@@ -175,9 +179,12 @@ class $modify(HorriblePlayLayer, PlayLayer) {
175179

176180
if (congregLevel && !congregLevel->m_levelNotDownloaded && (!m_level || m_level->m_levelID.value() != 93437568)) {
177181
PlayLayer::destroyPlayer(player, game);
182+
178183
onExit();
184+
179185
auto scene = PlayLayer::scene(congregLevel, false, false);
180186
CCDirector::get()->replaceScene(scene);
187+
181188
log::info("Switching to Congregation level (93437568) by 10% chance");
182189
return;
183190
} else if (congregLevel && !congregLevel->m_levelNotDownloaded) {
@@ -216,11 +223,40 @@ class $modify(HorriblePlayLayer, PlayLayer) {
216223
renderTexture->begin();
217224
scene->visit();
218225
renderTexture->end();
219-
auto image = renderTexture->newCCImage();
220226

221-
if (image) {
222-
std::string path = fmt::format("{}\\{}.png", Mod::get()->getSaveDir(), id);
227+
if (auto image = renderTexture->newCCImage()) {
228+
std::string path = fmt::format("{}\\{}.png", horribleMod->getSaveDir(), id);
229+
223230
if (image->saveToFile(path.c_str(), false)) {
231+
auto mockConfigPath = fmt::format("{}\\mock.json", horribleMod->getSaveDir());
232+
auto mockConfig = file::readJson(std::filesystem::path(mockConfigPath)); // get the saved fails to mock the player with :)
233+
234+
auto toWrite = Value(); // what we're gonna write in the mock.json file
235+
236+
if (mockConfig.isOk()) {
237+
// unwrap the whole thing
238+
auto mockConfigUnwr = mockConfig.unwrapOr(Value());
239+
240+
// overwrite this field (or add it) with the percent
241+
mockConfigUnwr[std::to_string(id)] = percentage;
242+
243+
toWrite = mockConfigUnwr;
244+
} else {
245+
toWrite = makeObject({
246+
{ std::to_string(id), percentage }
247+
});
248+
};
249+
250+
if (!toWrite.isNull()) {
251+
auto mockJson = file::writeToJson(mockConfigPath, toWrite);
252+
253+
if (mockJson.isOk()) {
254+
log::info("Saved highly mockable percentage of {} to data", percentage);
255+
} else {
256+
log::error("Aw man, failed to save mockable percentage of {} to data", percentage);
257+
};
258+
};
259+
224260
log::info("Saved screenshot to {}", path);
225261
} else {
226262
log::error("Failed to save screenshot to {}", path);
@@ -232,4 +268,33 @@ class $modify(HorriblePlayLayer, PlayLayer) {
232268
};
233269
};
234270
};
271+
272+
void levelComplete() {
273+
auto horribleMod = getMod();
274+
275+
if (horribleMod->getSavedValue<bool>("mock", false)) {
276+
int id = m_level->m_levelID;
277+
int percentage = m_level->m_normalPercent;
278+
279+
auto mockConfigPath = fmt::format("{}\\mock.json", horribleMod->getSaveDir());
280+
auto mockConfig = file::readJson(std::filesystem::path(mockConfigPath)); // get the saved levels to mock the player :)
281+
282+
if (mockConfig.isOk()) {
283+
log::debug("Clearing mock record for {}", id);
284+
auto mockConfigUnwr = mockConfig.unwrapOr(Value());
285+
286+
mockConfigUnwr[std::to_string(id)].clear();
287+
288+
auto mockJson = file::writeToJson(mockConfigPath, mockConfigUnwr);
289+
290+
if (mockJson.isOk()) {
291+
log::info("Saved highly mockable percentage of {} to data", percentage);
292+
} else {
293+
log::error("Aw man, failed to save mockable percentage of {} to data", percentage);
294+
};
295+
};
296+
};
297+
298+
PlayLayer::levelComplete();
299+
};
235300
};

src/popup/HorribleMenuPopup.cpp

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
using namespace geode::prelude;
99

1010
// add yo mods here :D
11-
std::vector<std::tuple<std::string, std::string, std::string, SillyTier, bool>> HorribleMenuPopup::getAllOptions()
12-
{
11+
std::vector<std::tuple<std::string, std::string, std::string, SillyTier, bool>> HorribleMenuPopup::getAllOptions() {
1312
// for simple minded: [modID, modName, modDescription, sillyTier, restartRequired]
1413
return {
1514
{
@@ -53,21 +52,21 @@ std::vector<std::tuple<std::string, std::string, std::string, SillyTier, bool>>
5352
"Play the achievement sound when doing random things.\n<cy>Credit: Cheeseworks</c>",
5453
SillyTier::Low,
5554
false
56-
} };
55+
}
56+
};
5757
};
5858

59-
bool HorribleMenuPopup::setup()
60-
{
59+
bool HorribleMenuPopup::setup() {
6160
setID("options"_spr);
6261
setTitle("Horrible Options");
6362

6463
auto mainLayerSize = m_mainLayer->getContentSize();
6564

6665
// Add a background sprite to the popup
6766
auto optionScrollBg = CCScale9Sprite::create("square02_001.png");
68-
optionScrollBg->setAnchorPoint({0.5, 0.5});
69-
optionScrollBg->setPosition({mainLayerSize.width / 2.f, mainLayerSize.height / 2.f - 10.f});
70-
optionScrollBg->setContentSize({mainLayerSize.width - 25.f, mainLayerSize.height - 45.f});
67+
optionScrollBg->setAnchorPoint({ 0.5, 0.5 });
68+
optionScrollBg->setPosition({ mainLayerSize.width / 2.f, mainLayerSize.height / 2.f - 10.f });
69+
optionScrollBg->setContentSize({ mainLayerSize.width - 25.f, mainLayerSize.height - 45.f });
7170
optionScrollBg->setOpacity(50);
7271

7372
m_mainLayer->addChild(optionScrollBg);
@@ -78,9 +77,9 @@ bool HorribleMenuPopup::setup()
7877
columnLayout->setAxisAlignment(AxisAlignment::End);
7978

8079
// scroll layer
81-
auto optionsScrollLayer = ScrollLayer::create({optionScrollBg->getContentSize().width - 10.f, optionScrollBg->getContentSize().height - 10.f});
80+
auto optionsScrollLayer = ScrollLayer::create({ optionScrollBg->getContentSize().width - 10.f, optionScrollBg->getContentSize().height - 10.f });
8281
optionsScrollLayer->setID("scrollLayer");
83-
optionsScrollLayer->setAnchorPoint({0.5, 0.5});
82+
optionsScrollLayer->setAnchorPoint({ 0.5, 0.5 });
8483
optionsScrollLayer->ignoreAnchorPointForPosition(false);
8584
optionsScrollLayer->setPosition(optionScrollBg->getPosition());
8685

@@ -90,14 +89,12 @@ bool HorribleMenuPopup::setup()
9089
auto modOptions = getAllOptions();
9190

9291
// Sort mod options alphabetically by name
93-
std::sort(modOptions.begin(), modOptions.end(), [](const auto &a, const auto &b)
94-
{ return std::get<4>(a) < std::get<4>(b); });
92+
std::sort(modOptions.begin(), modOptions.end(), [](const auto& a, const auto& b) { return std::get<4>(a) < std::get<4>(b); });
9593

96-
for (const auto &option : modOptions)
97-
{
98-
const auto &[id, name, desc, silly, restart] = option;
94+
for (const auto& option : modOptions) {
95+
const auto& [id, name, desc, silly, restart] = option;
9996

100-
if (auto modOption = ModOption::create({optionsScrollLayer->m_contentLayer->getScaledContentWidth(), 32.f}, id, name, desc, silly, restart))
97+
if (auto modOption = ModOption::create({ optionsScrollLayer->m_contentLayer->getScaledContentWidth(), 32.f }, id, name, desc, silly, restart))
10198
optionsScrollLayer->m_contentLayer->addChild(modOption);
10299
};
103100

@@ -108,12 +105,10 @@ bool HorribleMenuPopup::setup()
108105
return true;
109106
};
110107

111-
HorribleMenuPopup *HorribleMenuPopup::create()
112-
{
108+
HorribleMenuPopup* HorribleMenuPopup::create() {
113109
auto ret = new HorribleMenuPopup();
114110

115-
if (ret && ret->initAnchored(300.f, 280.f))
116-
{
111+
if (ret && ret->initAnchored(300.f, 280.f)) {
117112
ret->autorelease();
118113
return ret;
119114
};

0 commit comments

Comments
 (0)