2.2.0
This commit is contained in:
parent
e7a0847adb
commit
ec0ea91fc3
48
README.md
48
README.md
|
@ -8,50 +8,4 @@ An example for the frex/canvas integration can be found [here](https://gitlab.co
|
||||||
You will just need to install Respackopts. A menu button will appear besides all supported resourcepacks.\
|
You will just need to install Respackopts. A menu button will appear besides all supported resourcepacks.\
|
||||||
You can get the latest debug build [here](https://gitlab.com/jfmods/respackopts/-/jobs/artifacts/master/raw/latest.jar?job=build_test) and the latest stable build [here](https://modrinth.com/mod/respackopts)
|
You can get the latest debug build [here](https://gitlab.com/jfmods/respackopts/-/jobs/artifacts/master/raw/latest.jar?job=build_test) and the latest stable build [here](https://modrinth.com/mod/respackopts)
|
||||||
## Resource pack authors
|
## Resource pack authors
|
||||||
You will need to define a respackopts conf as seen [here](https://gitlab.com/jfmods/respackopts/-/blob/master/run/resourcepacks/lumi/assets/respackopts/conf.json)
|
You can head to the [wiki](https://gitlab.com/jfmods/respackopts/-/wikis/home) for details.
|
||||||
|
|
||||||
This config may include:
|
|
||||||
- boolean values, expressed as Json bools
|
|
||||||
- number values, expressed as Json numbers
|
|
||||||
- slider-based numeric values, expressed as a json object containing only the fields `default`, `min` and `max` and only whole numbers
|
|
||||||
- string values (not accessible from default integrations), expressed as Json strings
|
|
||||||
- enums, expressed as Json arrays containing simple strings
|
|
||||||
- subcategories expressed as json objects. These must meet the same constraints as the root config
|
|
||||||
|
|
||||||
You can also provide translations/more complex names for your resource pack's configs.\
|
|
||||||
The following things can be changed:
|
|
||||||
- Entry names: `respackopts.field.{packId}.{entryId}`
|
|
||||||
- Category titles: `respackopts.title.{packId}`
|
|
||||||
- Tooltips: `respackopts.tooltip.{packId}.{entryId}`
|
|
||||||
|
|
||||||
In subcategories, you can use `{packId}.{categoryId}` instead of `{packId}`
|
|
||||||
|
|
||||||
Please note that translations require your resource pack to be loaded.
|
|
||||||
|
|
||||||
The version property defines the format version. It will be incremented if changes to the layout of the config are made\
|
|
||||||
I will likely attempt to support older versions if I decide to make an incompatible change.\
|
|
||||||
To use the information from the config you will need to use and integration module/plugin.\
|
|
||||||
For the ones included by default:
|
|
||||||
### Canvas
|
|
||||||
Respackopts defines a config supplier, you can include it with `#include respackopts:config_supplier`\
|
|
||||||
You can always check whether it was properly loaded by checking if `respackopts_loaded` is defined.\
|
|
||||||
Values can be accessed with `{packId}_{entryId}` for basic elements.\
|
|
||||||
Enum values can be accessed as booleans expressing whether the specified entry is selected with `{packId}_{entryId}_{enumKey}`.\
|
|
||||||
Examples of using these are available [here](https://gitlab.com/jfmods/respackopts/-/tree/master/run/resourcepacks/lumi)
|
|
||||||
### Conditional resources
|
|
||||||
Respackopts allows creating conditional resources by creating a file named `{targetFile}.rpo`.\
|
|
||||||
This file is a json file that contains an array named "conditions". The resource will be ignored if any of the conditions are not met.\
|
|
||||||
This allows (for example) overrides for textures to only be loaded if the user enables them through the config.\
|
|
||||||
It also allows the following operations: `and`, `equal`, `nor`/`not`, `or`, `xor`.\
|
|
||||||
An example can be seen [here](https://gitlab.com/jfmods/respackopts/-/tree/master/run/resourcepacks/lumi/assets/minecraft/lang)
|
|
||||||
### Fallback resources
|
|
||||||
Respackopts allows creating fallbacks for resources if they are unavailable/disabled.\
|
|
||||||
To do this, create a "fallbacks" entry in a files .rpo containing every possible fallback file as a string in an array.\
|
|
||||||
Use this in conjunction with the conditional resources feature in order to create multiple options for a single texture.\
|
|
||||||
A simple example can be seen [here](https://gitlab.com/jfmods/respackopts/-/blob/master/run/resourcepacks/lumi/assets/minecraft/lang/de_de.json.rpo)
|
|
||||||
## Mod developers
|
|
||||||
All entry types extend the common ConfigEntry class and implement sevaral methods. The main config element can be found in Respackopts.CONFIG_BRANCH
|
|
||||||
and will always be a config branch (an element containing sub-elements).\
|
|
||||||
If you need code to be ran after changes are made to the state, add an action to `saveActions`.\
|
|
||||||
This is currently used for the Canvas/FREX integration, which uses it to generate shader code.\
|
|
||||||
The config GUI is currently generated using cloth config. The config icon ís loaded from ModMenu. It will not display if that is not loaded.
|
|
|
@ -15,9 +15,9 @@ dependencies {
|
||||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
|
|
||||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:0.34.9+1.17"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:0.36.1+1.17"
|
||||||
|
|
||||||
modImplementation "com.terraformersmc:modmenu:2.0.0-beta.7"
|
modImplementation "com.terraformersmc:modmenu:2.0.2"
|
||||||
|
|
||||||
modApi("me.shedaniel.cloth:cloth-config-fabric:5.0.34")
|
modApi("me.shedaniel.cloth:cloth-config-fabric:5.0.34")
|
||||||
modImplementation("grondag:canvas-mc117-1.17:+") {
|
modImplementation("grondag:canvas-mc117-1.17:+") {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
org.gradle.jvmargs=-Xmx1G
|
org.gradle.jvmargs=-Xmx1G
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check these on https://modmuss50.me/fabric.html
|
# check these on https://modmuss50.me/fabric.html
|
||||||
minecraft_version=1.17
|
minecraft_version=1.17.1
|
||||||
yarn_mappings=build.1
|
yarn_mappings=build.1
|
||||||
loader_version=0.11.3
|
loader_version=0.11.6
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=2.1.1
|
mod_version=2.2.0
|
||||||
maven_group=io.gitlab.jfronny
|
maven_group=io.gitlab.jfronny
|
||||||
archives_base_name=respackopts
|
archives_base_name=respackopts
|
||||||
|
|
||||||
modrinth_id=TiF5QWZY
|
modrinth_id=TiF5QWZY
|
||||||
modrinth_required_dependencies=wRE7Emzz
|
modrinth_required_dependencies=mzVbb1XI
|
||||||
modrinth_optional_dependencies=
|
modrinth_optional_dependencies=
|
||||||
curseforge_id=430090
|
curseforge_id=430090
|
||||||
curseforge_required_dependencies=cloth-config, modmenu
|
curseforge_required_dependencies=cloth-config, modmenu
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
"respackopts.tooltip.lumi.tonemap": "Tooltip test",
|
"respackopts.tooltip.lumi.tonemap": "Tooltip test",
|
||||||
"respackopts.field.lumi.pbr": "Enable PBR",
|
"respackopts.field.lumi.pbr": "Enable PBR",
|
||||||
"respackopts.field.lumi.debugMode": "Debug Mode",
|
"respackopts.field.lumi.debugMode": "Debug Mode",
|
||||||
|
"respackopts.field.lumi.debugMode.normal": "Normal Mode",
|
||||||
"respackopts.field.lumi.waterVertexWavy": "Wavy water model",
|
"respackopts.field.lumi.waterVertexWavy": "Wavy water model",
|
||||||
"respackopts.tooltip.lumi.subcategoryTest.sliderTest": "Yayyy"
|
"respackopts.tooltip.lumi.subcategoryTest.sliderTest": "Yayyy"
|
||||||
}
|
}
|
|
@ -21,12 +21,13 @@ public class GuiFactory {
|
||||||
public void buildCategory(ConfigBranch source, String screenId, Consumer<AbstractConfigListEntry<?>> config, ConfigEntryBuilder entryBuilder, String namePrefix) {
|
public void buildCategory(ConfigBranch source, String screenId, Consumer<AbstractConfigListEntry<?>> config, ConfigEntryBuilder entryBuilder, String namePrefix) {
|
||||||
for (Map.Entry<String, ConfigEntry<?>> in : source.getValue().entrySet()) {
|
for (Map.Entry<String, ConfigEntry<?>> in : source.getValue().entrySet()) {
|
||||||
ConfigEntry<?> entry = in.getValue();
|
ConfigEntry<?> entry = in.getValue();
|
||||||
String prefix = ("".equals(namePrefix) ? "" : namePrefix + ".") + in.getKey();
|
String entryName = ("".equals(namePrefix) ? "" : namePrefix + ".") + in.getKey();
|
||||||
String entryName = "respackopts." + entry.getEntryType() + "." + screenId;
|
Respackopts.LOGGER.info(entryName);
|
||||||
|
String translationPrefix = "respackopts." + entry.getEntryType() + "." + screenId;
|
||||||
config.accept(entry.buildEntry(entryBuilder,
|
config.accept(entry.buildEntry(entryBuilder,
|
||||||
getText(prefix, entryName),
|
getText(entryName, translationPrefix),
|
||||||
() -> {
|
() -> {
|
||||||
String k = "respackopts.tooltip." + screenId + "." + prefix;
|
String k = "respackopts.tooltip." + screenId + "." + entryName;
|
||||||
if (Language.getInstance().hasTranslation(k)) {
|
if (Language.getInstance().hasTranslation(k)) {
|
||||||
Text[] res = new Text[1];
|
Text[] res = new Text[1];
|
||||||
res[0] = new TranslatableText(k);
|
res[0] = new TranslatableText(k);
|
||||||
|
@ -36,15 +37,16 @@ public class GuiFactory {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
},
|
},
|
||||||
screenId,
|
screenId,
|
||||||
prefix));
|
entryName,
|
||||||
|
translationPrefix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Text getText(String prefix, String entryName) {
|
public static Text getText(String name, String translationPrefix) {
|
||||||
String translatableNameKey = entryName + "." + prefix;
|
String translatableNameKey = translationPrefix + "." + name;
|
||||||
return Language.getInstance().hasTranslation(translatableNameKey)
|
return Language.getInstance().hasTranslation(translatableNameKey)
|
||||||
? new TranslatableText(translatableNameKey)
|
? new TranslatableText(translatableNameKey)
|
||||||
: new LiteralText(prefix);
|
: new LiteralText(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Screen buildGui(ConfigBranch source, String resourcepackid, Screen parent, Runnable onSave) {
|
public Screen buildGui(ConfigBranch source, String resourcepackid, Screen parent, Runnable onSave) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class ConfigBooleanEntry extends ConfigEntry<Boolean> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractConfigListEntry<?> buildEntry(ConfigEntryBuilder entryBuilder, Text name, Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String namePrefix) {
|
public AbstractConfigListEntry<?> buildEntry(ConfigEntryBuilder entryBuilder, Text name, Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String entryName, String translationPrefix) {
|
||||||
return entryBuilder.startBooleanToggle(name, getValue())
|
return entryBuilder.startBooleanToggle(name, getValue())
|
||||||
.setDefaultValue(getDefault())
|
.setDefaultValue(getDefault())
|
||||||
.setSaveConsumer(this::setValue)
|
.setSaveConsumer(this::setValue)
|
||||||
|
|
|
@ -88,9 +88,9 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractConfigListEntry<?> buildEntry(ConfigEntryBuilder entryBuilder, Text name, Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String namePrefix) {
|
public AbstractConfigListEntry<?> buildEntry(ConfigEntryBuilder entryBuilder, Text name, Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String entryName, String translationPrefix) {
|
||||||
SubCategoryBuilder sc = entryBuilder.startSubCategory(name);
|
SubCategoryBuilder sc = entryBuilder.startSubCategory(name);
|
||||||
Respackopts.factory.buildCategory(this, screenId, sc::add, entryBuilder, namePrefix);
|
Respackopts.factory.buildCategory(this, screenId, sc::add, entryBuilder, entryName);
|
||||||
sc.setTooltipSupplier(tooltipSupplier);
|
sc.setTooltipSupplier(tooltipSupplier);
|
||||||
return sc.build();
|
return sc.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ public abstract class ConfigEntry<T> {
|
||||||
|
|
||||||
public abstract void buildShader(StringBuilder sb, String valueName);
|
public abstract void buildShader(StringBuilder sb, String valueName);
|
||||||
|
|
||||||
public abstract AbstractConfigListEntry<?> buildEntry(ConfigEntryBuilder entryBuilder, Text name, Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String namePrefix);
|
public abstract AbstractConfigListEntry<?> buildEntry(ConfigEntryBuilder entryBuilder, Text name, Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String entryName, String translationPrefix);
|
||||||
|
|
||||||
public String getEntryType() {
|
public String getEntryType() {
|
||||||
return "field";
|
return "field";
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.gitlab.jfronny.respackopts.data.entry;
|
package io.gitlab.jfronny.respackopts.data.entry;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.respackopts.GuiFactory;
|
||||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||||
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
|
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
|
||||||
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
||||||
|
@ -11,6 +12,7 @@ import net.minecraft.text.Text;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class ConfigEnumEntry extends ConfigEntry<String> {
|
public class ConfigEnumEntry extends ConfigEntry<String> {
|
||||||
|
@ -112,10 +114,11 @@ public class ConfigEnumEntry extends ConfigEntry<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractConfigListEntry<?> buildEntry(ConfigEntryBuilder entryBuilder, Text name, Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String namePrefix) {
|
public AbstractConfigListEntry<?> buildEntry(ConfigEntryBuilder entryBuilder, Text name, Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String entryName, String translationPrefix) {
|
||||||
|
Function<String, Text> entryText = s -> GuiFactory.getText(s, ("".equals(translationPrefix) ? "" : translationPrefix + ".") + entryName);
|
||||||
return entryBuilder.startDropdownMenu(name,
|
return entryBuilder.startDropdownMenu(name,
|
||||||
DropdownMenuBuilder.TopCellElementBuilder.of(getValue(), s -> s, LiteralText::new),
|
DropdownMenuBuilder.TopCellElementBuilder.of(getValue(), s -> s, entryText),
|
||||||
new DropdownBoxEntry.DefaultSelectionCellCreator<>())
|
DropdownMenuBuilder.CellCreatorBuilder.of(entryText))
|
||||||
.setSuggestionMode(false)
|
.setSuggestionMode(false)
|
||||||
.setDefaultValue(getDefault())
|
.setDefaultValue(getDefault())
|
||||||
.setSelections(() -> values.iterator())
|
.setSelections(() -> values.iterator())
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class ConfigNumericEntry extends ConfigEntry<Double> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractConfigListEntry<?> buildEntry(ConfigEntryBuilder entryBuilder, Text name, Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String namePrefix) {
|
public AbstractConfigListEntry<?> buildEntry(ConfigEntryBuilder entryBuilder, Text name, Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String entryName, String translationPrefix) {
|
||||||
if (min != null && max != null) {
|
if (min != null && max != null) {
|
||||||
return entryBuilder.startIntSlider(name,
|
return entryBuilder.startIntSlider(name,
|
||||||
getValue().intValue(), min.intValue(), max.intValue())
|
getValue().intValue(), min.intValue(), max.intValue())
|
||||||
|
|
|
@ -27,7 +27,6 @@ public class FallbackFilter {
|
||||||
return false;
|
return false;
|
||||||
String fbt = name + Respackopts.FILE_EXTENSION;
|
String fbt = name + Respackopts.FILE_EXTENSION;
|
||||||
if (containsFileBase.test(fbt)) {
|
if (containsFileBase.test(fbt)) {
|
||||||
System.out.println(fbt);
|
|
||||||
try (InputStream stream = openFileBase.open(fbt); Reader w = new InputStreamReader(stream)) {
|
try (InputStream stream = openFileBase.open(fbt); Reader w = new InputStreamReader(stream)) {
|
||||||
Rpo rpo = Respackopts.GSON.fromJson(w, Rpo.class);
|
Rpo rpo = Respackopts.GSON.fromJson(w, Rpo.class);
|
||||||
if (rpo.fallbacks != null) {
|
if (rpo.fallbacks != null) {
|
||||||
|
@ -68,10 +67,8 @@ public class FallbackFilter {
|
||||||
String path = identifier.getPath();
|
String path = identifier.getPath();
|
||||||
if (path.endsWith(Respackopts.FILE_EXTENSION)) {
|
if (path.endsWith(Respackopts.FILE_EXTENSION)) {
|
||||||
String expectedTarget = path.substring(0, path.length() - Respackopts.FILE_EXTENSION.length());
|
String expectedTarget = path.substring(0, path.length() - Respackopts.FILE_EXTENSION.length());
|
||||||
System.out.println(expectedTarget);
|
|
||||||
if (ret.stream().noneMatch(s -> s.getPath().equals(expectedTarget)) && fileVisible(expectedTarget)) {
|
if (ret.stream().noneMatch(s -> s.getPath().equals(expectedTarget)) && fileVisible(expectedTarget)) {
|
||||||
ret.add(new Identifier(namespace, expectedTarget));
|
ret.add(new Identifier(namespace, expectedTarget));
|
||||||
System.out.println("Added fallback");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user