This commit is contained in:
JFronny 2021-07-08 17:49:15 +02:00
parent e7a0847adb
commit ec0ea91fc3
No known key found for this signature in database
GPG Key ID: BEC5ACBBD4EE17E5
11 changed files with 29 additions and 72 deletions

View File

@ -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 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
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)
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.
You can head to the [wiki](https://gitlab.com/jfmods/respackopts/-/wikis/home) for details.

View File

@ -15,9 +15,9 @@ dependencies {
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// 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")
modImplementation("grondag:canvas-mc117-1.17:+") {

View File

@ -2,16 +2,16 @@
org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://modmuss50.me/fabric.html
minecraft_version=1.17
minecraft_version=1.17.1
yarn_mappings=build.1
loader_version=0.11.3
loader_version=0.11.6
# Mod Properties
mod_version=2.1.1
mod_version=2.2.0
maven_group=io.gitlab.jfronny
archives_base_name=respackopts
modrinth_id=TiF5QWZY
modrinth_required_dependencies=wRE7Emzz
modrinth_required_dependencies=mzVbb1XI
modrinth_optional_dependencies=
curseforge_id=430090
curseforge_required_dependencies=cloth-config, modmenu

View File

@ -4,6 +4,7 @@
"respackopts.tooltip.lumi.tonemap": "Tooltip test",
"respackopts.field.lumi.pbr": "Enable PBR",
"respackopts.field.lumi.debugMode": "Debug Mode",
"respackopts.field.lumi.debugMode.normal": "Normal Mode",
"respackopts.field.lumi.waterVertexWavy": "Wavy water model",
"respackopts.tooltip.lumi.subcategoryTest.sliderTest": "Yayyy"
}

View File

@ -21,12 +21,13 @@ public class GuiFactory {
public void buildCategory(ConfigBranch source, String screenId, Consumer<AbstractConfigListEntry<?>> config, ConfigEntryBuilder entryBuilder, String namePrefix) {
for (Map.Entry<String, ConfigEntry<?>> in : source.getValue().entrySet()) {
ConfigEntry<?> entry = in.getValue();
String prefix = ("".equals(namePrefix) ? "" : namePrefix + ".") + in.getKey();
String entryName = "respackopts." + entry.getEntryType() + "." + screenId;
String entryName = ("".equals(namePrefix) ? "" : namePrefix + ".") + in.getKey();
Respackopts.LOGGER.info(entryName);
String translationPrefix = "respackopts." + entry.getEntryType() + "." + screenId;
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)) {
Text[] res = new Text[1];
res[0] = new TranslatableText(k);
@ -36,15 +37,16 @@ public class GuiFactory {
return Optional.empty();
},
screenId,
prefix));
entryName,
translationPrefix));
}
}
private Text getText(String prefix, String entryName) {
String translatableNameKey = entryName + "." + prefix;
public static Text getText(String name, String translationPrefix) {
String translatableNameKey = translationPrefix + "." + name;
return Language.getInstance().hasTranslation(translatableNameKey)
? new TranslatableText(translatableNameKey)
: new LiteralText(prefix);
: new LiteralText(name);
}
public Screen buildGui(ConfigBranch source, String resourcepackid, Screen parent, Runnable onSave) {

View File

@ -28,7 +28,7 @@ public class ConfigBooleanEntry extends ConfigEntry<Boolean> {
}
@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())
.setDefaultValue(getDefault())
.setSaveConsumer(this::setValue)

View File

@ -88,9 +88,9 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
}
@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);
Respackopts.factory.buildCategory(this, screenId, sc::add, entryBuilder, namePrefix);
Respackopts.factory.buildCategory(this, screenId, sc::add, entryBuilder, entryName);
sc.setTooltipSupplier(tooltipSupplier);
return sc.build();
}

View File

@ -68,7 +68,7 @@ public abstract class ConfigEntry<T> {
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() {
return "field";

View File

@ -1,5 +1,6 @@
package io.gitlab.jfronny.respackopts.data.entry;
import io.gitlab.jfronny.respackopts.GuiFactory;
import io.gitlab.jfronny.respackopts.Respackopts;
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
@ -11,6 +12,7 @@ import net.minecraft.text.Text;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
public class ConfigEnumEntry extends ConfigEntry<String> {
@ -112,10 +114,11 @@ public class ConfigEnumEntry extends ConfigEntry<String> {
}
@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,
DropdownMenuBuilder.TopCellElementBuilder.of(getValue(), s -> s, LiteralText::new),
new DropdownBoxEntry.DefaultSelectionCellCreator<>())
DropdownMenuBuilder.TopCellElementBuilder.of(getValue(), s -> s, entryText),
DropdownMenuBuilder.CellCreatorBuilder.of(entryText))
.setSuggestionMode(false)
.setDefaultValue(getDefault())
.setSelections(() -> values.iterator())

View File

@ -58,7 +58,7 @@ public class ConfigNumericEntry extends ConfigEntry<Double> {
}
@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) {
return entryBuilder.startIntSlider(name,
getValue().intValue(), min.intValue(), max.intValue())

View File

@ -27,7 +27,6 @@ public class FallbackFilter {
return false;
String fbt = name + Respackopts.FILE_EXTENSION;
if (containsFileBase.test(fbt)) {
System.out.println(fbt);
try (InputStream stream = openFileBase.open(fbt); Reader w = new InputStreamReader(stream)) {
Rpo rpo = Respackopts.GSON.fromJson(w, Rpo.class);
if (rpo.fallbacks != null) {
@ -68,10 +67,8 @@ public class FallbackFilter {
String path = identifier.getPath();
if (path.endsWith(Respackopts.FILE_EXTENSION)) {
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)) {
ret.add(new Identifier(namespace, expectedTarget));
System.out.println("Added fallback");
}
}
}