Skip to content

Commit

Permalink
Address issues #29, #28, #33,
Browse files Browse the repository at this point in the history
  • Loading branch information
Bawnorton committed Jan 20, 2024
1 parent 4191d9c commit b4680ec
Show file tree
Hide file tree
Showing 56 changed files with 1,012 additions and 665 deletions.
16 changes: 13 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id 'fabric-loom' version '1.4-SNAPSHOT'
id 'fabric-loom' version '1.5-SNAPSHOT'
id 'maven-publish'
id "me.modmuss50.mod-publish-plugin" version "0.3.3"
}
Expand Down Expand Up @@ -50,6 +50,17 @@ loom {
}
}

runs {
datagen {
inherit server
name "Data Generation"
vmArg "-Dfabric-api.datagen"
vmArg "-Dfabric-api.datagen.output-dir=${file("src/main/generated")}"
vmArg "-Dfabric-api.datagen.modid=${archivesBaseName}"

runDir "build/datagen"
}
}
}

dependencies {
Expand All @@ -61,9 +72,8 @@ dependencies {
// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"

// mixinextras
include(implementation(annotationProcessor("com.github.llamalad7.mixinextras:mixinextras-fabric:${project.mixin_extras_version}")))
include(implementation(annotationProcessor("com.github.bawnorton.mixinsquared:mixinsquared-fabric:0.1.1")))

// config
modImplementation("dev.isxander.yacl:yet-another-config-lib-fabric:${project.yacl_version}")
modImplementation("com.terraformersmc:modmenu:${project.modmenu_version}")
Expand Down
9 changes: 4 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@ org.gradle.parallel=true
# check these on https://fabricmc.net/develop
minecraft_version=1.20.1
yarn_mappings=1.20.1+build.10
loader_version=0.14.24
loader_version=0.15.3

# Mod Properties
mod_version=2.0.5
mod_version=2.1.0
maven_group=com.bawnorton
archives_base_name=bettertrims

# Dependencies
fabric_version=0.90.4+1.20.1
mixin_extras_version=0.2.0
fabric_version=0.91.0+1.20.1
illager_invasion_version=v8.0.0-1.20.1-Fabric
friends_and_foes_version=fabric-mc1.20.1-1.9.3
modmenu_version=7.2.1
yacl_version=3.1.1+1.20
yacl_version=3.2.1+1.20
172 changes: 82 additions & 90 deletions src/client/java/com/bawnorton/bettertrims/client/impl/YACLImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import com.bawnorton.bettertrims.client.config.ClientConfigManager;
import com.bawnorton.bettertrims.client.networking.ClientNetworking;
import com.bawnorton.bettertrims.config.ConfigManager;
import com.bawnorton.bettertrims.config.option.NestedConfigOption;
import com.bawnorton.bettertrims.config.option.OptionType;
import com.bawnorton.bettertrims.config.option.reference.ConfigOptionReference;
import com.bawnorton.bettertrims.config.option.reference.ParentedConfigOptionReference;
import com.bawnorton.bettertrims.config.annotation.Groups;
import com.bawnorton.bettertrims.config.option.ConfigOptionReference;
import com.bawnorton.bettertrims.config.option.ParentedConfigOptionReference;
import com.bawnorton.bettertrims.reflection.Reflection;
import dev.isxander.yacl3.api.*;
import dev.isxander.yacl3.api.controller.FloatSliderControllerBuilder;
Expand All @@ -18,68 +17,32 @@
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.*;

public abstract class YACLImpl {
private static boolean inScreen = false;
private static Screen screenParent = null;

public static Screen getScreen(Screen parent) {
YetAnotherConfigLib.Builder builder = YetAnotherConfigLib.createBuilder()
.title(yaclText("title", "main"))
.category(ConfigCategory.createBuilder()
.name(category("general"))
.tooltip(tooltip("general"))
.group(OptionGroup.createBuilder()
.name(group("game"))
.description(OptionDescription.of(description("game")))
.options(generateOptionsForType(OptionType.GAME))
.build())
.build())
.category(ConfigCategory.createBuilder()
.name(category("vanilla"))
.tooltip(tooltip("vanilla"))
.group(OptionGroup.createBuilder()
.name(group("vanilla"))
.description(OptionDescription.of(description("vanilla")))
.options(generateOptionsForType(OptionType.VANILLA))
.build())
.build())
.category(ConfigCategory.createBuilder()
.name(category("added_vanilla"))
.tooltip(tooltip("added_vanilla"))
.group(OptionGroup.createBuilder()
.name(group("added_vanilla"))
.description(OptionDescription.of(description("added_vanilla")))
.options(generateOptionsForType(OptionType.ADDED_VANILLA))
.build())
.build())
.category(ConfigCategory.createBuilder()
.name(category("modded"))
.tooltip(tooltip("modded"))
.group(OptionGroup.createBuilder()
.name(group("modded"))
.description(OptionDescription.of(description("modded")))
.options(generateOptionsForType(OptionType.MODDED))
.build())
.build());
Runnable saveCallback = () -> {
boolean inWorld = MinecraftClient.getInstance().world != null;
if (inWorld && ClientNetworking.isConnectedToDedicated()) {
ClientNetworking.trySendConfigToServer();
return;
}

inScreen = false;
ConfigManager.saveLocalConfig();
};
return builder.save(saveCallback).screenInit(yaclScreen -> {
inScreen = true;
screenParent = parent;
}).build().generateScreen(parent);
return YetAnotherConfigLib.createBuilder()
.title(yaclText("title", "main"))
.categories(generateCategories())
.save(() -> {
boolean inWorld = MinecraftClient.getInstance().world != null;
if (inWorld && ClientNetworking.isConnectedToDedicated()) {
ClientNetworking.trySendConfigToServer();
return;
}

inScreen = false;
ConfigManager.saveLocalConfig();
})
.screenInit(yaclScreen -> {
inScreen = true;
screenParent = parent;
})
.build()
.generateScreen(parent);
}

public static void refreshScreen() {
Expand All @@ -88,27 +51,54 @@ public static void refreshScreen() {
MinecraftClient.getInstance().setScreen(getScreen(screenParent));
}

private static Collection<? extends Option<?>> generateOptionsForType(OptionType type) {
private static Collection<ConfigCategory> generateCategories() {
Collection<ConfigCategory> categories = new ArrayList<>();
Groups groups = Reflection.getAnnotation(ClientConfigManager.getConfig(), Groups.class);
List<String> groupNames = new ArrayList<>(Arrays.asList(groups.value()));
Reflection.forEachAnnotatedField(ClientConfigManager.getConfig(), field -> ConfigOptionReference.readGroup(field).ifPresent(group -> {
if(!groupNames.contains(group)) {
throw new IllegalStateException("Group \"" + group + "\" does not exist. It is referenced by field \"" + field.getName() + "\".");
}
}));
for (String group : groupNames) {
categories.add(generateCategoryForGroup(group));
}
return categories;
}

private static ConfigCategory generateCategoryForGroup(String group) {
return ConfigCategory.createBuilder()
.name(category(group))
.tooltip(tooltip(group))
.group(OptionGroup.createBuilder()
.name(group(group))
.description(OptionDescription.of(description(group)))
.options(generateOptionsForGroup(group))
.build())
.build();
}

private static Collection<? extends Option<?>> generateOptionsForGroup(String group) {
Collection<Option<?>> options = new HashSet<>();
Reflection.forEachAnnotatedField(ClientConfigManager.getConfig(), field -> {
ConfigOptionReference reference = ConfigOptionReference.of(ClientConfigManager.getConfig(), field);
if (!reference.isOf(type)) return;
if (!reference.isOf(group)) return;

if (reference.isNested()) {
options.addAll(createNestedOptions(reference, type));
options.addAll(createNestedOptions(reference, group));
} else {
options.add(createOption(reference));
}
});
return options.stream().sorted(Comparator.comparing(option -> option.name().getString())).toList();
}

private static Collection<? extends Option<?>> createNestedOptions(ConfigOptionReference reference, OptionType type) {
private static Collection<? extends Option<?>> createNestedOptions(ConfigOptionReference reference, String type) {
if (!reference.isNested())
throw new IllegalArgumentException("Reference \"%s\" is not nested".formatted(reference.getFormattedName()));

Collection<Option<?>> options = new ArrayList<>();
NestedConfigOption instance = reference.nestedValue();
Object instance = reference.nestedValue();
Reflection.forEachAnnotatedField(instance, nestedField -> {
ParentedConfigOptionReference parentedReference = ParentedConfigOptionReference.of(reference, instance, nestedField);
if (!parentedReference.isOf(type)) return;
Expand All @@ -127,52 +117,54 @@ private static Option<?> createOption(ConfigOptionReference reference) {
case BOOLEAN -> booleanOption(reference);
case INTEGER -> integerOption(reference);
case FLOAT -> floatOption(reference);
case NESTED -> throw new IllegalArgumentException("Attempted to of non-nested option for nested reference \"%s\"".formatted(reference.getFormattedName()));
case NESTED ->
throw new IllegalArgumentException("Attempted to of non-nested option for nested reference \"%s\"".formatted(reference.getFormattedName()));
};
}

private static Option<Float> floatOption(ConfigOptionReference reference) {
return Option.<Float>createBuilder()
.name(option(reference.getFormattedName()))
.description(imagedDescription(reference))
.binding(Binding.generic(reference.floatValue(), reference::floatValue, reference::floatValue))
.controller(option -> FloatSliderControllerBuilder.create(option)
.valueFormatter(value -> Text.literal(String.format("%,.2f", value).replaceAll("[\u00a0\u202F]", " ")))
.range(reference.minFloatValue(), reference.maxFloatValue())
.step(reference.maxFloatValue() / 100f))
.build();
.name(option(reference.getFormattedName()))
.description(imagedDescription(reference))
.binding(Binding.generic(reference.floatValue(), reference::floatValue, reference::floatValue))
.controller(option -> FloatSliderControllerBuilder.create(option)
.formatValue(value -> Text.literal(String.format("%,.2f", value)
.replaceAll("[\u00a0\u202F]", " ")))
.range(reference.minFloatValue(), reference.maxFloatValue())
.step(reference.maxFloatValue() / 100f))
.build();
}

private static Option<Boolean> booleanOption(ConfigOptionReference reference) {
return Option.<Boolean>createBuilder()
.name(option(reference.getFormattedName()))
.description(imagedDescription(reference))
.binding(Binding.generic(reference.booleanValue(), reference::booleanValue, reference::booleanValue))
.controller(TickBoxControllerBuilder::create)
.build();
.name(option(reference.getFormattedName()))
.description(imagedDescription(reference))
.binding(Binding.generic(reference.booleanValue(), reference::booleanValue, reference::booleanValue))
.controller(TickBoxControllerBuilder::create)
.build();
}

private static Option<Integer> integerOption(ConfigOptionReference reference) {
return Option.<Integer>createBuilder()
.name(option(reference.getFormattedName()))
.description(imagedDescription(reference))
.binding(Binding.generic(reference.intValue(), reference::intValue, reference::intValue))
.controller(option -> IntegerSliderControllerBuilder.create(option)
.range(reference.minIntValue(), reference.maxIntValue())
.step(Math.max(1, reference.maxIntValue() / 100)))
.build();
.name(option(reference.getFormattedName()))
.description(imagedDescription(reference))
.binding(Binding.generic(reference.intValue(), reference::intValue, reference::intValue))
.controller(option -> IntegerSliderControllerBuilder.create(option)
.range(reference.minIntValue(), reference.maxIntValue())
.step(Math.max(1, reference.maxIntValue() / 100)))
.build();
}

private static OptionDescription imagedDescription(ConfigOptionReference reference) {
Identifier textureLocation = reference.findTexture();
if(textureLocation == null) {
if (textureLocation == null || MinecraftClient.getInstance().getResourceManager().getResource(textureLocation).isEmpty()) {
return OptionDescription.of(description(reference.getFormattedName()));
}

return OptionDescription.createBuilder()
.image(textureLocation, 16, 16)
.text(description(reference.getFormattedName()))
.build();
.image(textureLocation, 16, 16)
.text(description(reference.getFormattedName()))
.build();
}

private static MutableText category(String key) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.bawnorton.bettertrims.client.mixin;

import com.bawnorton.bettertrims.client.config.ClientConfigManager;
import com.bawnorton.bettertrims.effect.ArmorTrimEffects;
import com.bawnorton.bettertrims.extend.LivingEntityExtender;
import com.bawnorton.bettertrims.util.NumberWrapper;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;

@Mixin(GameRenderer.class)
public abstract class GameRendererMixin {
@WrapOperation(method = "getNightVisionStrength", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/effect/StatusEffectInstance;isDurationBelow(I)Z"))
private static boolean letsNotCrashThanks(StatusEffectInstance instance, int duration, Operation<Boolean> original) {
if(instance == null) return false;
return original.call(instance, duration);
}

@ModifyReturnValue(method = "getNightVisionStrength", at = @At("RETURN"))
private static float improveNightVisionWhenWearingSilver(float original, LivingEntity entity, float tickDelta) {
NumberWrapper increase = NumberWrapper.zero();
if (entity instanceof LivingEntityExtender extender && extender.betterTrims$shouldSilverApply()) {
ArmorTrimEffects.SILVER.apply(extender.betterTrims$getTrimmables(), () -> increase.increment(ClientConfigManager.getConfig().silverEffects.improveVision));
}
return Math.min(original + increase.getFloat(), 1.0F);
}
}
Loading

0 comments on commit b4680ec

Please sign in to comment.