Skip to content

Commit d2510c7

Browse files
committed
v2.3.4
1 parent 3d76eb2 commit d2510c7

8 files changed

Lines changed: 168 additions & 4 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ else()
88
endif()
99
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
1010

11-
project(comboBurst VERSION 2.3.3)
11+
project(comboBurst VERSION 2.3.4)
1212

1313
file(GLOB_RECURSE SOURCES src/*.cpp)
1414
add_library(${PROJECT_NAME} SHARED ${SOURCES})

changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# v2.3.4
2+
* Added a button that opens the custom sprites folder (thanks ery)
3+
14
# v2.3.3
25
* Added an option for calculating percentage difference from 0%. ("Consistent Popups")
36
* Added support for other image formats, meaning that you may use ImagePlus to add gifs, webps, jxl, and qoi images.

mod.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"android": "2.2074",
77
"ios": "2.2074"
88
},
9-
"version": "v2.3.3",
9+
"version": "v2.3.4",
1010
"id": "crewly.comboburst",
1111
"name": "Combo Burst",
1212
"developer": "crewly",
@@ -90,6 +90,10 @@
9090
"default": "Anime",
9191
"one-of": ["Anime", "Meme", "Custom"]
9292
},
93+
"sprite-folder": {
94+
"type": "custom:sprite-folder",
95+
"name": "Custom Sprites Folder"
96+
},
9397
"popup-effect": {
9498
"name": "Popup Animation",
9599
"description": "The animation effect used for the Combo Burst",
File renamed without changes.

src/PauseLayer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <Geode/Geode.hpp>
2-
#include "ComboBurst.h"
2+
#include "ComboBurst.hpp"
33

44
using namespace geode::prelude;
55

src/PlayLayer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <Geode/Geode.hpp>
2-
#include "ComboBurst.h"
2+
#include "ComboBurst.hpp"
33

44
using namespace geode::prelude;
55

src/Settings.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "Settings.hpp"
2+
3+
SettingNodeV3* MyButtonSettingV3::createNode(float width) {
4+
return MyButtonSettingNodeV3::create(
5+
std::static_pointer_cast<MyButtonSettingV3>(shared_from_this()),
6+
width
7+
);
8+
}

src/Settings.hpp

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#pragma once
2+
3+
#include "ComboBurst.hpp"
4+
#include <Geode/loader/SettingV3.hpp>
5+
#include <Geode/loader/Mod.hpp>
6+
7+
// If you use PCH these are most likely not necessary
8+
#include <Geode/binding/ButtonSprite.hpp>
9+
#include <Geode/binding/CCMenuItemSpriteExtra.hpp>
10+
#include <Geode/binding/FLAlertLayer.hpp>
11+
12+
using namespace geode::prelude;
13+
14+
// Inherit from SettingV3 directly over SettingBaseValueV3, as our setting
15+
// doesn't actually control any value, but it just a simple button
16+
class MyButtonSettingV3 : public SettingV3 {
17+
public:
18+
// Once again implement the parse function
19+
static Result<std::shared_ptr<SettingV3>> parse(std::string const& key, std::string const& modID, matjson::Value const& json) {
20+
auto res = std::make_shared<MyButtonSettingV3>();
21+
auto root = checkJson(json, "MyButtonSettingV3");
22+
23+
// `parseBaseProperties` parses all base properties, including
24+
// `requires-restart` - which does not really make sense in our use case,
25+
// as there's nothing in this setting that could require a restart.
26+
// So, we instead parse the base properties that actually apply to this
27+
// setting manually:
28+
res->init(key, modID, root);
29+
res->parseNameAndDescription(root);
30+
res->parseEnableIf(root);
31+
32+
root.checkUnknownKeys();
33+
return root.ok(std::static_pointer_cast<SettingV3>(res));
34+
}
35+
36+
// Since there's no data to save or load, these can just return true
37+
// Although you could use these for example to store how many times the
38+
// button has been clicked
39+
bool load(matjson::Value const& json) override {
40+
return true;
41+
}
42+
bool save(matjson::Value& json) const override {
43+
return true;
44+
}
45+
46+
// This setting can't ever have anything but the default value, as it has
47+
// no value
48+
bool isDefaultValue() const override {
49+
return true;
50+
}
51+
void reset() override {}
52+
53+
// Once again defined out-of-line
54+
SettingNodeV3* createNode(float width) override;
55+
};
56+
57+
// We are inheriting from `SettingNodeV3` directly again, as we don't need the
58+
// boilerplate `SettingValueNodeV3` fills in for us because our setting has no
59+
// value!
60+
class MyButtonSettingNodeV3 : public SettingNodeV3 {
61+
protected:
62+
CCSprite* m_buttonSprite;
63+
CCMenuItemSpriteExtra* m_button;
64+
65+
bool init(std::shared_ptr<MyButtonSettingV3> setting, float width) {
66+
if (!SettingNodeV3::init(setting, width))
67+
return false;
68+
69+
// We just create the button and add it to the setting's menu
70+
m_buttonSprite = CCSprite::createWithSpriteFrameName("folderIcon_001.png");
71+
m_buttonSprite->setScale(0.75f);
72+
m_button = CCMenuItemSpriteExtra::create(
73+
m_buttonSprite, this, menu_selector(MyButtonSettingNodeV3::onButton)
74+
);
75+
this->getButtonMenu()->addChildAtPosition(m_button, Anchor::Center);
76+
this->getButtonMenu()->setContentWidth(60);
77+
this->getButtonMenu()->updateLayout();
78+
79+
this->updateState(nullptr);
80+
81+
return true;
82+
}
83+
84+
void updateState(CCNode* invoker) override {
85+
SettingNodeV3::updateState(invoker);
86+
87+
// In case there's an "enable-if" condition on this button, for example
88+
// if this played a test notification in a notification mod and you
89+
// want to disable the button if notifications are disabled entirely
90+
auto shouldEnable = this->getSetting()->shouldEnable();
91+
m_button->setEnabled(shouldEnable);
92+
m_buttonSprite->setCascadeColorEnabled(true);
93+
m_buttonSprite->setCascadeOpacityEnabled(true);
94+
m_buttonSprite->setOpacity(shouldEnable ? 255 : 155);
95+
m_buttonSprite->setColor(shouldEnable ? ccWHITE : ccGRAY);
96+
}
97+
void onButton(CCObject*) {
98+
auto path = getSpriteDir();
99+
if (!std::filesystem::exists(path)) {
100+
try {
101+
std::filesystem::create_directory(path);
102+
} catch (std::filesystem::filesystem_error& e) {
103+
log::error("Couldn't create custom sprite directory:"
104+
"{}", e.what());
105+
}
106+
}
107+
file::openFolder(
108+
path
109+
);
110+
}
111+
112+
// Both of these can just be no-ops, since they make no sense for our
113+
// setting as it's just a button
114+
void onCommit() override {}
115+
void onResetToDefault() override {}
116+
117+
public:
118+
static MyButtonSettingNodeV3* create(std::shared_ptr<MyButtonSettingV3> setting, float width) {
119+
auto ret = new MyButtonSettingNodeV3();
120+
if (ret && ret->init(setting, width)) {
121+
ret->autorelease();
122+
return ret;
123+
}
124+
CC_SAFE_DELETE(ret);
125+
return nullptr;
126+
}
127+
128+
// Both of these can just return false, since they make no sense for our
129+
// setting as it's just a button
130+
bool hasUncommittedChanges() const override {
131+
return false;
132+
}
133+
bool hasNonDefaultValue() const override {
134+
return false;
135+
}
136+
137+
// This is not necessary, but it makes it so you don't have to do the
138+
// pointer cast every time you want to access the properties of the button
139+
// setting
140+
std::shared_ptr<MyButtonSettingV3> getSetting() const {
141+
return std::static_pointer_cast<MyButtonSettingV3>(SettingNodeV3::getSetting());
142+
}
143+
};
144+
145+
146+
// Register as before
147+
$execute {
148+
(void)Mod::get()->registerCustomSettingType("sprite-folder", &MyButtonSettingV3::parse);
149+
}

0 commit comments

Comments
 (0)